PageRenderTime 42ms CodeModel.GetById 31ms RepoModel.GetById 0ms app.codeStats 1ms

/tags/release-0.0.0-rc0/hive/external/ql/src/java/org/apache/hadoop/hive/ql/exec/DDLTask.java

#
Java | 3258 lines | 2454 code | 332 blank | 472 comment | 676 complexity | 834d1c5310bbb8a1f599a85916c3cad4 MD5 | raw file
Possible License(s): Apache-2.0, BSD-3-Clause, JSON, CPL-1.0

Large files files are truncated, but you can click here to view the full file

  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. package org.apache.hadoop.hive.ql.exec;
  19. import static org.apache.commons.lang.StringUtils.join;
  20. import static org.apache.hadoop.util.StringUtils.stringifyException;
  21. import java.io.BufferedWriter;
  22. import java.io.DataOutput;
  23. import java.io.FileNotFoundException;
  24. import java.io.IOException;
  25. import java.io.OutputStreamWriter;
  26. import java.io.Serializable;
  27. import java.io.Writer;
  28. import java.net.URI;
  29. import java.net.URISyntaxException;
  30. import java.util.ArrayList;
  31. import java.util.Collections;
  32. import java.util.Comparator;
  33. import java.util.HashSet;
  34. import java.util.Iterator;
  35. import java.util.List;
  36. import java.util.Map;
  37. import java.util.Set;
  38. import java.util.SortedSet;
  39. import java.util.TreeSet;
  40. import java.util.Map.Entry;
  41. import org.apache.commons.logging.Log;
  42. import org.apache.commons.logging.LogFactory;
  43. import org.apache.hadoop.fs.FSDataOutputStream;
  44. import org.apache.hadoop.fs.FileStatus;
  45. import org.apache.hadoop.fs.FileSystem;
  46. import org.apache.hadoop.fs.FsShell;
  47. import org.apache.hadoop.fs.Path;
  48. import org.apache.hadoop.hive.conf.HiveConf;
  49. import org.apache.hadoop.hive.conf.HiveConf.ConfVars;
  50. import org.apache.hadoop.hive.metastore.MetaStoreUtils;
  51. import org.apache.hadoop.hive.metastore.ProtectMode;
  52. import org.apache.hadoop.hive.metastore.TableType;
  53. import org.apache.hadoop.hive.metastore.Warehouse;
  54. import org.apache.hadoop.hive.metastore.api.AlreadyExistsException;
  55. import org.apache.hadoop.hive.metastore.api.Database;
  56. import org.apache.hadoop.hive.metastore.api.FieldSchema;
  57. import org.apache.hadoop.hive.metastore.api.HiveObjectPrivilege;
  58. import org.apache.hadoop.hive.metastore.api.HiveObjectRef;
  59. import org.apache.hadoop.hive.metastore.api.HiveObjectType;
  60. import org.apache.hadoop.hive.metastore.api.Index;
  61. import org.apache.hadoop.hive.metastore.api.InvalidOperationException;
  62. import org.apache.hadoop.hive.metastore.api.MetaException;
  63. import org.apache.hadoop.hive.metastore.api.NoSuchObjectException;
  64. import org.apache.hadoop.hive.metastore.api.Order;
  65. import org.apache.hadoop.hive.metastore.api.PrincipalType;
  66. import org.apache.hadoop.hive.metastore.api.PrivilegeBag;
  67. import org.apache.hadoop.hive.metastore.api.PrivilegeGrantInfo;
  68. import org.apache.hadoop.hive.metastore.api.Role;
  69. import org.apache.hadoop.hive.ql.Context;
  70. import org.apache.hadoop.hive.ql.DriverContext;
  71. import org.apache.hadoop.hive.ql.QueryPlan;
  72. import org.apache.hadoop.hive.ql.hooks.ReadEntity;
  73. import org.apache.hadoop.hive.ql.hooks.WriteEntity;
  74. import org.apache.hadoop.hive.ql.lockmgr.HiveLock;
  75. import org.apache.hadoop.hive.ql.lockmgr.HiveLockManager;
  76. import org.apache.hadoop.hive.ql.lockmgr.HiveLockMode;
  77. import org.apache.hadoop.hive.ql.lockmgr.HiveLockObject;
  78. import org.apache.hadoop.hive.ql.lockmgr.HiveLockObject.HiveLockObjectData;
  79. import org.apache.hadoop.hive.ql.metadata.CheckResult;
  80. import org.apache.hadoop.hive.ql.metadata.Hive;
  81. import org.apache.hadoop.hive.ql.metadata.HiveException;
  82. import org.apache.hadoop.hive.ql.metadata.HiveMetaStoreChecker;
  83. import org.apache.hadoop.hive.ql.metadata.HiveStorageHandler;
  84. import org.apache.hadoop.hive.ql.metadata.InvalidTableException;
  85. import org.apache.hadoop.hive.ql.metadata.MetaDataFormatUtils;
  86. import org.apache.hadoop.hive.ql.metadata.Partition;
  87. import org.apache.hadoop.hive.ql.metadata.Table;
  88. import org.apache.hadoop.hive.ql.plan.AddPartitionDesc;
  89. import org.apache.hadoop.hive.ql.plan.AlterDatabaseDesc;
  90. import org.apache.hadoop.hive.ql.plan.AlterIndexDesc;
  91. import org.apache.hadoop.hive.ql.plan.AlterTableDesc;
  92. import org.apache.hadoop.hive.ql.plan.AlterTableSimpleDesc;
  93. import org.apache.hadoop.hive.ql.plan.CreateDatabaseDesc;
  94. import org.apache.hadoop.hive.ql.plan.CreateIndexDesc;
  95. import org.apache.hadoop.hive.ql.plan.CreateTableDesc;
  96. import org.apache.hadoop.hive.ql.plan.CreateTableLikeDesc;
  97. import org.apache.hadoop.hive.ql.plan.CreateViewDesc;
  98. import org.apache.hadoop.hive.ql.plan.DDLWork;
  99. import org.apache.hadoop.hive.ql.plan.DescDatabaseDesc;
  100. import org.apache.hadoop.hive.ql.plan.DescFunctionDesc;
  101. import org.apache.hadoop.hive.ql.plan.DescTableDesc;
  102. import org.apache.hadoop.hive.ql.plan.DropDatabaseDesc;
  103. import org.apache.hadoop.hive.ql.plan.DropIndexDesc;
  104. import org.apache.hadoop.hive.ql.plan.DropTableDesc;
  105. import org.apache.hadoop.hive.ql.plan.GrantDesc;
  106. import org.apache.hadoop.hive.ql.plan.GrantRevokeRoleDDL;
  107. import org.apache.hadoop.hive.ql.plan.LockTableDesc;
  108. import org.apache.hadoop.hive.ql.plan.MsckDesc;
  109. import org.apache.hadoop.hive.ql.plan.PrincipalDesc;
  110. import org.apache.hadoop.hive.ql.plan.PrivilegeDesc;
  111. import org.apache.hadoop.hive.ql.plan.PrivilegeObjectDesc;
  112. import org.apache.hadoop.hive.ql.plan.RevokeDesc;
  113. import org.apache.hadoop.hive.ql.plan.RoleDDLDesc;
  114. import org.apache.hadoop.hive.ql.plan.ShowDatabasesDesc;
  115. import org.apache.hadoop.hive.ql.plan.ShowFunctionsDesc;
  116. import org.apache.hadoop.hive.ql.plan.ShowGrantDesc;
  117. import org.apache.hadoop.hive.ql.plan.ShowIndexesDesc;
  118. import org.apache.hadoop.hive.ql.plan.ShowLocksDesc;
  119. import org.apache.hadoop.hive.ql.plan.ShowPartitionsDesc;
  120. import org.apache.hadoop.hive.ql.plan.ShowTableStatusDesc;
  121. import org.apache.hadoop.hive.ql.plan.ShowTablesDesc;
  122. import org.apache.hadoop.hive.ql.plan.SwitchDatabaseDesc;
  123. import org.apache.hadoop.hive.ql.plan.UnlockTableDesc;
  124. import org.apache.hadoop.hive.ql.plan.AlterTableDesc.AlterTableTypes;
  125. import org.apache.hadoop.hive.ql.plan.api.StageType;
  126. import org.apache.hadoop.hive.ql.security.authorization.Privilege;
  127. import org.apache.hadoop.hive.serde.Constants;
  128. import org.apache.hadoop.hive.serde2.Deserializer;
  129. import org.apache.hadoop.hive.serde2.MetadataTypedColumnsetSerDe;
  130. import org.apache.hadoop.hive.serde2.SerDeException;
  131. import org.apache.hadoop.hive.serde2.SerDeUtils;
  132. import org.apache.hadoop.hive.serde2.columnar.ColumnarSerDe;
  133. import org.apache.hadoop.hive.serde2.dynamic_type.DynamicSerDe;
  134. import org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe;
  135. import org.apache.hadoop.hive.shims.HadoopShims;
  136. import org.apache.hadoop.hive.shims.ShimLoader;
  137. import org.apache.hadoop.util.ToolRunner;
  138. /**
  139. * DDLTask implementation.
  140. *
  141. **/
  142. public class DDLTask extends Task<DDLWork> implements Serializable {
  143. private static final long serialVersionUID = 1L;
  144. private static final Log LOG = LogFactory.getLog("hive.ql.exec.DDLTask");
  145. transient HiveConf conf;
  146. private static final int separator = Utilities.tabCode;
  147. private static final int terminator = Utilities.newLineCode;
  148. // These are suffixes attached to intermediate directory names used in the
  149. // archiving / un-archiving process.
  150. private static String INTERMEDIATE_ARCHIVED_DIR_SUFFIX;
  151. private static String INTERMEDIATE_ORIGINAL_DIR_SUFFIX;
  152. private static String INTERMEDIATE_EXTRACTED_DIR_SUFFIX;
  153. public DDLTask() {
  154. super();
  155. }
  156. @Override
  157. public void initialize(HiveConf conf, QueryPlan queryPlan, DriverContext ctx) {
  158. super.initialize(conf, queryPlan, ctx);
  159. this.conf = conf;
  160. INTERMEDIATE_ARCHIVED_DIR_SUFFIX =
  161. HiveConf.getVar(conf, ConfVars.METASTORE_INT_ARCHIVED);
  162. INTERMEDIATE_ORIGINAL_DIR_SUFFIX =
  163. HiveConf.getVar(conf, ConfVars.METASTORE_INT_ORIGINAL);
  164. INTERMEDIATE_EXTRACTED_DIR_SUFFIX =
  165. HiveConf.getVar(conf, ConfVars.METASTORE_INT_EXTRACTED);
  166. }
  167. @Override
  168. public int execute(DriverContext driverContext) {
  169. // Create the db
  170. Hive db;
  171. try {
  172. db = Hive.get(conf);
  173. CreateDatabaseDesc createDatabaseDesc = work.getCreateDatabaseDesc();
  174. if (null != createDatabaseDesc) {
  175. return createDatabase(db, createDatabaseDesc);
  176. }
  177. DropDatabaseDesc dropDatabaseDesc = work.getDropDatabaseDesc();
  178. if (dropDatabaseDesc != null) {
  179. return dropDatabase(db, dropDatabaseDesc);
  180. }
  181. SwitchDatabaseDesc switchDatabaseDesc = work.getSwitchDatabaseDesc();
  182. if (switchDatabaseDesc != null) {
  183. return switchDatabase(db, switchDatabaseDesc);
  184. }
  185. DescDatabaseDesc descDatabaseDesc = work.getDescDatabaseDesc();
  186. if (descDatabaseDesc != null) {
  187. return descDatabase(descDatabaseDesc);
  188. }
  189. AlterDatabaseDesc alterDatabaseDesc = work.getAlterDatabaseDesc();
  190. if (alterDatabaseDesc != null) {
  191. return alterDatabase(alterDatabaseDesc);
  192. }
  193. CreateTableDesc crtTbl = work.getCreateTblDesc();
  194. if (crtTbl != null) {
  195. return createTable(db, crtTbl);
  196. }
  197. CreateIndexDesc crtIndex = work.getCreateIndexDesc();
  198. if (crtIndex != null) {
  199. return createIndex(db, crtIndex);
  200. }
  201. AlterIndexDesc alterIndex = work.getAlterIndexDesc();
  202. if (alterIndex != null) {
  203. return alterIndex(db, alterIndex);
  204. }
  205. DropIndexDesc dropIdx = work.getDropIdxDesc();
  206. if (dropIdx != null) {
  207. return dropIndex(db, dropIdx);
  208. }
  209. CreateTableLikeDesc crtTblLike = work.getCreateTblLikeDesc();
  210. if (crtTblLike != null) {
  211. return createTableLike(db, crtTblLike);
  212. }
  213. DropTableDesc dropTbl = work.getDropTblDesc();
  214. if (dropTbl != null) {
  215. return dropTable(db, dropTbl);
  216. }
  217. AlterTableDesc alterTbl = work.getAlterTblDesc();
  218. if (alterTbl != null) {
  219. return alterTable(db, alterTbl);
  220. }
  221. CreateViewDesc crtView = work.getCreateViewDesc();
  222. if (crtView != null) {
  223. return createView(db, crtView);
  224. }
  225. AddPartitionDesc addPartitionDesc = work.getAddPartitionDesc();
  226. if (addPartitionDesc != null) {
  227. return addPartition(db, addPartitionDesc);
  228. }
  229. AlterTableSimpleDesc simpleDesc = work.getAlterTblSimpleDesc();
  230. if (simpleDesc != null) {
  231. if (simpleDesc.getType() == AlterTableTypes.TOUCH) {
  232. return touch(db, simpleDesc);
  233. } else if (simpleDesc.getType() == AlterTableTypes.ARCHIVE) {
  234. return archive(db, simpleDesc, driverContext);
  235. } else if (simpleDesc.getType() == AlterTableTypes.UNARCHIVE) {
  236. return unarchive(db, simpleDesc);
  237. }
  238. }
  239. MsckDesc msckDesc = work.getMsckDesc();
  240. if (msckDesc != null) {
  241. return msck(db, msckDesc);
  242. }
  243. DescTableDesc descTbl = work.getDescTblDesc();
  244. if (descTbl != null) {
  245. return describeTable(db, descTbl);
  246. }
  247. DescFunctionDesc descFunc = work.getDescFunctionDesc();
  248. if (descFunc != null) {
  249. return describeFunction(descFunc);
  250. }
  251. ShowDatabasesDesc showDatabases = work.getShowDatabasesDesc();
  252. if (showDatabases != null) {
  253. return showDatabases(db, showDatabases);
  254. }
  255. ShowTablesDesc showTbls = work.getShowTblsDesc();
  256. if (showTbls != null) {
  257. return showTables(db, showTbls);
  258. }
  259. ShowTableStatusDesc showTblStatus = work.getShowTblStatusDesc();
  260. if (showTblStatus != null) {
  261. return showTableStatus(db, showTblStatus);
  262. }
  263. ShowFunctionsDesc showFuncs = work.getShowFuncsDesc();
  264. if (showFuncs != null) {
  265. return showFunctions(showFuncs);
  266. }
  267. ShowLocksDesc showLocks = work.getShowLocksDesc();
  268. if (showLocks != null) {
  269. return showLocks(showLocks);
  270. }
  271. LockTableDesc lockTbl = work.getLockTblDesc();
  272. if (lockTbl != null) {
  273. return lockTable(lockTbl);
  274. }
  275. UnlockTableDesc unlockTbl = work.getUnlockTblDesc();
  276. if (unlockTbl != null) {
  277. return unlockTable(unlockTbl);
  278. }
  279. ShowPartitionsDesc showParts = work.getShowPartsDesc();
  280. if (showParts != null) {
  281. return showPartitions(db, showParts);
  282. }
  283. RoleDDLDesc roleDDLDesc = work.getRoleDDLDesc();
  284. if (roleDDLDesc != null) {
  285. return roleDDL(roleDDLDesc);
  286. }
  287. GrantDesc grantDesc = work.getGrantDesc();
  288. if (grantDesc != null) {
  289. return grantOrRevokePrivileges(grantDesc.getPrincipals(), grantDesc
  290. .getPrivileges(), grantDesc.getPrivilegeSubjectDesc(), grantDesc.getGrantor(), grantDesc.getGrantorType(), grantDesc.isGrantOption(), true);
  291. }
  292. RevokeDesc revokeDesc = work.getRevokeDesc();
  293. if (revokeDesc != null) {
  294. return grantOrRevokePrivileges(revokeDesc.getPrincipals(), revokeDesc
  295. .getPrivileges(), revokeDesc.getPrivilegeSubjectDesc(), null, null, false, false);
  296. }
  297. ShowGrantDesc showGrantDesc = work.getShowGrantDesc();
  298. if (showGrantDesc != null) {
  299. return showGrants(showGrantDesc);
  300. }
  301. GrantRevokeRoleDDL grantOrRevokeRoleDDL = work.getGrantRevokeRoleDDL();
  302. if (grantOrRevokeRoleDDL != null) {
  303. return grantOrRevokeRole(grantOrRevokeRoleDDL);
  304. }
  305. ShowIndexesDesc showIndexes = work.getShowIndexesDesc();
  306. if (showIndexes != null) {
  307. return showIndexes(db, showIndexes);
  308. }
  309. } catch (InvalidTableException e) {
  310. console.printError("Table " + e.getTableName() + " does not exist");
  311. LOG.debug(stringifyException(e));
  312. return 1;
  313. } catch (HiveException e) {
  314. console.printError("FAILED: Error in metadata: " + e.getMessage(), "\n"
  315. + stringifyException(e));
  316. LOG.debug(stringifyException(e));
  317. return 1;
  318. } catch (Exception e) {
  319. console.printError("Failed with exception " + e.getMessage(), "\n"
  320. + stringifyException(e));
  321. return (1);
  322. }
  323. assert false;
  324. return 0;
  325. }
  326. private int grantOrRevokeRole(GrantRevokeRoleDDL grantOrRevokeRoleDDL)
  327. throws HiveException {
  328. try {
  329. boolean grantRole = grantOrRevokeRoleDDL.getGrant();
  330. List<PrincipalDesc> principals = grantOrRevokeRoleDDL.getPrincipalDesc();
  331. List<String> roles = grantOrRevokeRoleDDL.getRoles();
  332. for (PrincipalDesc principal : principals) {
  333. String userName = principal.getName();
  334. for (String roleName : roles) {
  335. if (grantRole) {
  336. db.grantRole(roleName, userName, principal.getType(),
  337. grantOrRevokeRoleDDL.getGrantor(), grantOrRevokeRoleDDL
  338. .getGrantorType(), grantOrRevokeRoleDDL.isGrantOption());
  339. } else {
  340. db.revokeRole(roleName, userName, principal.getType());
  341. }
  342. }
  343. }
  344. } catch (Exception e) {
  345. throw new HiveException(e);
  346. }
  347. return 0;
  348. }
  349. private int showGrants(ShowGrantDesc showGrantDesc) throws HiveException {
  350. try {
  351. Path resFile = new Path(showGrantDesc.getResFile());
  352. FileSystem fs = resFile.getFileSystem(conf);
  353. DataOutput outStream = fs.create(resFile);
  354. PrincipalDesc principalDesc = showGrantDesc.getPrincipalDesc();
  355. PrivilegeObjectDesc hiveObjectDesc = showGrantDesc.getHiveObj();
  356. String principalName = principalDesc.getName();
  357. if (hiveObjectDesc == null) {
  358. List<HiveObjectPrivilege> users = db.showPrivilegeGrant(
  359. HiveObjectType.GLOBAL, principalName, principalDesc.getType(),
  360. null, null, null, null);
  361. if (users != null && users.size() > 0) {
  362. boolean first = true;
  363. for (HiveObjectPrivilege usr : users) {
  364. if (!first) {
  365. outStream.write(terminator);
  366. } else {
  367. first = false;
  368. }
  369. writeGrantInfo(outStream, principalDesc.getType(), principalName,
  370. null, null, null, null, usr.getGrantInfo());
  371. }
  372. }
  373. } else {
  374. String obj = hiveObjectDesc.getObject();
  375. boolean notFound = true;
  376. String dbName = null;
  377. String tableName = null;
  378. Table tableObj = null;
  379. Database dbObj = null;
  380. if (hiveObjectDesc.getTable()) {
  381. String[] dbTab = obj.split("\\.");
  382. if (dbTab.length == 2) {
  383. dbName = dbTab[0];
  384. tableName = dbTab[1];
  385. } else {
  386. dbName = db.getCurrentDatabase();
  387. tableName = obj;
  388. }
  389. dbObj = db.getDatabase(dbName);
  390. tableObj = db.getTable(dbName, tableName);
  391. notFound = (dbObj == null || tableObj == null);
  392. } else {
  393. dbName = hiveObjectDesc.getObject();
  394. dbObj = db.getDatabase(dbName);
  395. notFound = (dbObj == null);
  396. }
  397. if (notFound) {
  398. throw new HiveException(obj + " can not be found");
  399. }
  400. String partName = null;
  401. List<String> partValues = null;
  402. if (hiveObjectDesc.getPartSpec() != null) {
  403. partName = Warehouse
  404. .makePartName(hiveObjectDesc.getPartSpec(), false);
  405. partValues = Warehouse.getPartValuesFromPartName(partName);
  406. }
  407. if (!hiveObjectDesc.getTable()) {
  408. // show database level privileges
  409. List<HiveObjectPrivilege> dbs = db.showPrivilegeGrant(HiveObjectType.DATABASE, principalName,
  410. principalDesc.getType(), dbName, null, null, null);
  411. if (dbs != null && dbs.size() > 0) {
  412. boolean first = true;
  413. for (HiveObjectPrivilege db : dbs) {
  414. if (!first) {
  415. outStream.write(terminator);
  416. } else {
  417. first = false;
  418. }
  419. writeGrantInfo(outStream, principalDesc.getType(), principalName,
  420. dbName, null, null, null, db.getGrantInfo());
  421. }
  422. }
  423. } else {
  424. if (showGrantDesc.getColumns() != null) {
  425. // show column level privileges
  426. for (String columnName : showGrantDesc.getColumns()) {
  427. List<HiveObjectPrivilege> columnss = db.showPrivilegeGrant(
  428. HiveObjectType.COLUMN, principalName,
  429. principalDesc.getType(), dbName, tableName, partValues,
  430. columnName);
  431. if (columnss != null && columnss.size() > 0) {
  432. boolean first = true;
  433. for (HiveObjectPrivilege col : columnss) {
  434. if (!first) {
  435. outStream.write(terminator);
  436. } else {
  437. first = false;
  438. }
  439. writeGrantInfo(outStream, principalDesc.getType(),
  440. principalName, dbName, tableName, partName, columnName,
  441. col.getGrantInfo());
  442. }
  443. }
  444. }
  445. } else if (hiveObjectDesc.getPartSpec() != null) {
  446. // show partition level privileges
  447. List<HiveObjectPrivilege> parts = db.showPrivilegeGrant(
  448. HiveObjectType.PARTITION, principalName, principalDesc
  449. .getType(), dbName, tableName, partValues, null);
  450. if (parts != null && parts.size() > 0) {
  451. boolean first = true;
  452. for (HiveObjectPrivilege part : parts) {
  453. if (!first) {
  454. outStream.write(terminator);
  455. } else {
  456. first = false;
  457. }
  458. writeGrantInfo(outStream, principalDesc.getType(),
  459. principalName, dbName, tableName, partName, null, part.getGrantInfo());
  460. }
  461. }
  462. } else {
  463. // show table level privileges
  464. List<HiveObjectPrivilege> tbls = db.showPrivilegeGrant(
  465. HiveObjectType.TABLE, principalName, principalDesc.getType(),
  466. dbName, tableName, null, null);
  467. if (tbls != null && tbls.size() > 0) {
  468. boolean first = true;
  469. for (HiveObjectPrivilege tbl : tbls) {
  470. if (!first) {
  471. outStream.write(terminator);
  472. } else {
  473. first = false;
  474. }
  475. writeGrantInfo(outStream, principalDesc.getType(),
  476. principalName, dbName, tableName, null, null, tbl.getGrantInfo());
  477. }
  478. }
  479. }
  480. }
  481. }
  482. ((FSDataOutputStream) outStream).close();
  483. } catch (FileNotFoundException e) {
  484. LOG.info("show table status: " + stringifyException(e));
  485. return 1;
  486. } catch (IOException e) {
  487. LOG.info("show table status: " + stringifyException(e));
  488. return 1;
  489. } catch (Exception e) {
  490. e.printStackTrace();
  491. throw new HiveException(e);
  492. }
  493. return 0;
  494. }
  495. private int grantOrRevokePrivileges(List<PrincipalDesc> principals,
  496. List<PrivilegeDesc> privileges, PrivilegeObjectDesc privSubjectDesc,
  497. String grantor, PrincipalType grantorType, boolean grantOption, boolean isGrant) {
  498. if (privileges == null || privileges.size() == 0) {
  499. console.printError("No privilege found.");
  500. return 1;
  501. }
  502. String dbName = null;
  503. String tableName = null;
  504. Table tableObj = null;
  505. Database dbObj = null;
  506. try {
  507. if (privSubjectDesc != null) {
  508. if (privSubjectDesc.getPartSpec() != null && isGrant) {
  509. throw new HiveException("Grant does not support partition level.");
  510. }
  511. String obj = privSubjectDesc.getObject();
  512. boolean notFound = true;
  513. if (privSubjectDesc.getTable()) {
  514. String[] dbTab = obj.split("\\.");
  515. if (dbTab.length == 2) {
  516. dbName = dbTab[0];
  517. tableName = dbTab[1];
  518. } else {
  519. dbName = db.getCurrentDatabase();
  520. tableName = obj;
  521. }
  522. dbObj = db.getDatabase(dbName);
  523. tableObj = db.getTable(dbName, tableName);
  524. notFound = (dbObj == null || tableObj == null);
  525. } else {
  526. dbName = privSubjectDesc.getObject();
  527. dbObj = db.getDatabase(dbName);
  528. notFound = (dbObj == null);
  529. }
  530. if (notFound) {
  531. throw new HiveException(obj + " can not be found");
  532. }
  533. }
  534. PrivilegeBag privBag = new PrivilegeBag();
  535. if (privSubjectDesc == null) {
  536. for (int idx = 0; idx < privileges.size(); idx++) {
  537. Privilege priv = privileges.get(idx).getPrivilege();
  538. if (privileges.get(idx).getColumns() != null
  539. && privileges.get(idx).getColumns().size() > 0) {
  540. throw new HiveException(
  541. "For user-level privileges, column sets should be null. columns="
  542. + privileges.get(idx).getColumns().toString());
  543. }
  544. privBag.addToPrivileges(new HiveObjectPrivilege(new HiveObjectRef(
  545. HiveObjectType.GLOBAL, null, null, null, null), null, null,
  546. new PrivilegeGrantInfo(priv.toString(), 0, grantor, grantorType,
  547. grantOption)));
  548. }
  549. } else {
  550. org.apache.hadoop.hive.metastore.api.Partition partObj = null;
  551. List<String> partValues = null;
  552. if (tableObj != null) {
  553. if ((!tableObj.isPartitioned())
  554. && privSubjectDesc.getPartSpec() != null) {
  555. throw new HiveException(
  556. "Table is not partitioned, but partition name is present: partSpec="
  557. + privSubjectDesc.getPartSpec().toString());
  558. }
  559. if (privSubjectDesc.getPartSpec() != null) {
  560. partObj = db.getPartition(tableObj, privSubjectDesc.getPartSpec(),
  561. false).getTPartition();
  562. partValues = partObj.getValues();
  563. }
  564. }
  565. for (PrivilegeDesc privDesc : privileges) {
  566. List<String> columns = privDesc.getColumns();
  567. Privilege priv = privDesc.getPrivilege();
  568. if (columns != null && columns.size() > 0) {
  569. if (!priv.supportColumnLevel()) {
  570. throw new HiveException(priv.toString()
  571. + " does not support column level.");
  572. }
  573. if (privSubjectDesc == null || tableName == null) {
  574. throw new HiveException(
  575. "For user-level/database-level privileges, column sets should be null. columns="
  576. + columns);
  577. }
  578. for (int i = 0; i < columns.size(); i++) {
  579. privBag.addToPrivileges(new HiveObjectPrivilege(
  580. new HiveObjectRef(HiveObjectType.COLUMN, dbName, tableName,
  581. partValues, columns.get(i)), null, null, new PrivilegeGrantInfo(priv.toString(), 0, grantor, grantorType, grantOption)));
  582. }
  583. } else {
  584. if (privSubjectDesc.getTable()) {
  585. if (privSubjectDesc.getPartSpec() != null) {
  586. privBag.addToPrivileges(new HiveObjectPrivilege(
  587. new HiveObjectRef(HiveObjectType.PARTITION, dbName,
  588. tableName, partValues, null), null, null, new PrivilegeGrantInfo(priv.toString(), 0, grantor, grantorType, grantOption)));
  589. } else {
  590. privBag
  591. .addToPrivileges(new HiveObjectPrivilege(
  592. new HiveObjectRef(HiveObjectType.TABLE, dbName,
  593. tableName, null, null), null, null, new PrivilegeGrantInfo(priv.toString(), 0, grantor, grantorType, grantOption)));
  594. }
  595. } else {
  596. privBag.addToPrivileges(new HiveObjectPrivilege(
  597. new HiveObjectRef(HiveObjectType.DATABASE, dbName, null,
  598. null, null), null, null, new PrivilegeGrantInfo(priv.toString(), 0, grantor, grantorType, grantOption)));
  599. }
  600. }
  601. }
  602. }
  603. for (PrincipalDesc principal : principals) {
  604. for (int i = 0; i < privBag.getPrivileges().size(); i++) {
  605. HiveObjectPrivilege objPrivs = privBag.getPrivileges().get(i);
  606. objPrivs.setPrincipalName(principal.getName());
  607. objPrivs.setPrincipalType(principal.getType());
  608. }
  609. if (isGrant) {
  610. db.grantPrivileges(privBag);
  611. } else {
  612. db.revokePrivileges(privBag);
  613. }
  614. }
  615. } catch (Exception e) {
  616. console.printError("Error: " + e.getMessage());
  617. return 1;
  618. }
  619. return 0;
  620. }
  621. private int roleDDL(RoleDDLDesc roleDDLDesc) {
  622. RoleDDLDesc.RoleOperation operation = roleDDLDesc.getOperation();
  623. try {
  624. if (operation.equals(RoleDDLDesc.RoleOperation.CREATE_ROLE)) {
  625. db.createRole(roleDDLDesc.getName(), roleDDLDesc.getRoleOwnerName());
  626. } else if (operation.equals(RoleDDLDesc.RoleOperation.DROP_ROLE)) {
  627. db.dropRole(roleDDLDesc.getName());
  628. } else if (operation.equals(RoleDDLDesc.RoleOperation.SHOW_ROLE_GRANT)) {
  629. List<Role> roles = db.showRoleGrant(roleDDLDesc.getName(), roleDDLDesc
  630. .getPrincipalType());
  631. if (roles != null && roles.size() > 0) {
  632. Path resFile = new Path(roleDDLDesc.getResFile());
  633. FileSystem fs = resFile.getFileSystem(conf);
  634. DataOutput outStream = fs.create(resFile);
  635. for (Role role : roles) {
  636. outStream.writeBytes("role name:" + role.getRoleName());
  637. outStream.write(terminator);
  638. }
  639. ((FSDataOutputStream) outStream).close();
  640. }
  641. } else {
  642. throw new HiveException("Unkown role operation "
  643. + operation.getOperationName());
  644. }
  645. } catch (HiveException e) {
  646. console.printError("Error in role operation "
  647. + operation.getOperationName() + " on role name "
  648. + roleDDLDesc.getName() + ", error message " + e.getMessage());
  649. return 1;
  650. } catch (IOException e) {
  651. LOG.info("role ddl exception: " + stringifyException(e));
  652. return 1;
  653. }
  654. return 0;
  655. }
  656. private int alterDatabase(AlterDatabaseDesc alterDbDesc) throws HiveException {
  657. String dbName = alterDbDesc.getDatabaseName();
  658. Database database = db.getDatabase(dbName);
  659. Map<String, String> newParams = alterDbDesc.getDatabaseProperties();
  660. if (database != null) {
  661. Map<String, String> params = database.getParameters();
  662. // if both old and new params are not null, merge them
  663. if (params != null && newParams != null) {
  664. params.putAll(newParams);
  665. database.setParameters(params);
  666. } else { // if one of them is null, replace the old params with the new one
  667. database.setParameters(newParams);
  668. }
  669. db.alterDatabase(database.getName(), database);
  670. } else {
  671. throw new HiveException("ERROR: The database " + dbName + " does not exist.");
  672. }
  673. return 0;
  674. }
  675. private int dropIndex(Hive db, DropIndexDesc dropIdx) throws HiveException {
  676. db.dropIndex(db.getCurrentDatabase(), dropIdx.getTableName(),
  677. dropIdx.getIndexName(), true);
  678. return 0;
  679. }
  680. private int createIndex(Hive db, CreateIndexDesc crtIndex) throws HiveException {
  681. if( crtIndex.getSerde() != null) {
  682. validateSerDe(crtIndex.getSerde());
  683. }
  684. db
  685. .createIndex(
  686. crtIndex.getTableName(), crtIndex.getIndexName(), crtIndex.getIndexTypeHandlerClass(),
  687. crtIndex.getIndexedCols(), crtIndex.getIndexTableName(), crtIndex.getDeferredRebuild(),
  688. crtIndex.getInputFormat(), crtIndex.getOutputFormat(), crtIndex.getSerde(),
  689. crtIndex.getStorageHandler(), crtIndex.getLocation(), crtIndex.getIdxProps(), crtIndex.getTblProps(),
  690. crtIndex.getSerdeProps(), crtIndex.getCollItemDelim(), crtIndex.getFieldDelim(), crtIndex.getFieldEscape(),
  691. crtIndex.getLineDelim(), crtIndex.getMapKeyDelim(), crtIndex.getIndexComment()
  692. );
  693. return 0;
  694. }
  695. private int alterIndex(Hive db, AlterIndexDesc alterIndex) throws HiveException {
  696. String dbName = alterIndex.getDbName();
  697. String baseTableName = alterIndex.getBaseTableName();
  698. String indexName = alterIndex.getIndexName();
  699. Index idx = db.getIndex(dbName, baseTableName, indexName);
  700. if (alterIndex.getOp() == AlterIndexDesc.AlterIndexTypes.ADDPROPS) {
  701. idx.getParameters().putAll(alterIndex.getProps());
  702. } else {
  703. console.printError("Unsupported Alter commnad");
  704. return 1;
  705. }
  706. // set last modified by properties
  707. if (!updateModifiedParameters(idx.getParameters(), conf)) {
  708. return 1;
  709. }
  710. try {
  711. db.alterIndex(dbName, baseTableName, indexName, idx);
  712. } catch (InvalidOperationException e) {
  713. console.printError("Invalid alter operation: " + e.getMessage());
  714. LOG.info("alter index: " + stringifyException(e));
  715. return 1;
  716. } catch (HiveException e) {
  717. console.printError("Invalid alter operation: " + e.getMessage());
  718. return 1;
  719. }
  720. return 0;
  721. }
  722. /**
  723. * Add a partition to a table.
  724. *
  725. * @param db
  726. * Database to add the partition to.
  727. * @param addPartitionDesc
  728. * Add this partition.
  729. * @return Returns 0 when execution succeeds and above 0 if it fails.
  730. * @throws HiveException
  731. */
  732. /**
  733. * Add a partition to a table.
  734. *
  735. * @param db
  736. * Database to add the partition to.
  737. * @param addPartitionDesc
  738. * Add this partition.
  739. * @return Returns 0 when execution succeeds and above 0 if it fails.
  740. * @throws HiveException
  741. */
  742. private int addPartition(Hive db, AddPartitionDesc addPartitionDesc) throws HiveException {
  743. Table tbl = db.getTable(addPartitionDesc.getDbName(), addPartitionDesc.getTableName());
  744. validateAlterTableType(tbl, AlterTableDesc.AlterTableTypes.ADDPARTITION);
  745. // If the add partition was created with IF NOT EXISTS, then we should
  746. // not throw an error if the specified part does exist.
  747. Partition checkPart = db.getPartition(tbl, addPartitionDesc.getPartSpec(), false);
  748. if (checkPart != null && addPartitionDesc.getIfNotExists()) {
  749. return 0;
  750. }
  751. if (addPartitionDesc.getLocation() == null) {
  752. db.createPartition(tbl, addPartitionDesc.getPartSpec());
  753. } else {
  754. // set partition path relative to table
  755. db.createPartition(tbl, addPartitionDesc.getPartSpec(), new Path(tbl
  756. .getPath(), addPartitionDesc.getLocation()));
  757. }
  758. Partition part = db
  759. .getPartition(tbl, addPartitionDesc.getPartSpec(), false);
  760. work.getOutputs().add(new WriteEntity(part));
  761. return 0;
  762. }
  763. /**
  764. * Rewrite the partition's metadata and force the pre/post execute hooks to
  765. * be fired.
  766. *
  767. * @param db
  768. * @param touchDesc
  769. * @return
  770. * @throws HiveException
  771. */
  772. private int touch(Hive db, AlterTableSimpleDesc touchDesc)
  773. throws HiveException {
  774. String dbName = touchDesc.getDbName();
  775. String tblName = touchDesc.getTableName();
  776. Table tbl = db.getTable(dbName, tblName);
  777. validateAlterTableType(tbl, AlterTableDesc.AlterTableTypes.TOUCH);
  778. if (touchDesc.getPartSpec() == null) {
  779. try {
  780. db.alterTable(tblName, tbl);
  781. } catch (InvalidOperationException e) {
  782. throw new HiveException("Uable to update table");
  783. }
  784. work.getInputs().add(new ReadEntity(tbl));
  785. work.getOutputs().add(new WriteEntity(tbl));
  786. } else {
  787. Partition part = db.getPartition(tbl, touchDesc.getPartSpec(), false);
  788. if (part == null) {
  789. throw new HiveException("Specified partition does not exist");
  790. }
  791. try {
  792. db.alterPartition(tblName, part);
  793. } catch (InvalidOperationException e) {
  794. throw new HiveException(e);
  795. }
  796. work.getInputs().add(new ReadEntity(part));
  797. work.getOutputs().add(new WriteEntity(part));
  798. }
  799. return 0;
  800. }
  801. /**
  802. * Determines whether a partition has been archived
  803. *
  804. * @param p
  805. * @return
  806. */
  807. private boolean isArchived(Partition p) {
  808. Map<String, String> params = p.getParameters();
  809. if ("true".equalsIgnoreCase(params.get(
  810. org.apache.hadoop.hive.metastore.api.Constants.IS_ARCHIVED))) {
  811. return true;
  812. } else {
  813. return false;
  814. }
  815. }
  816. private void setIsArchived(Partition p, boolean state) {
  817. Map<String, String> params = p.getParameters();
  818. if (state) {
  819. params.put(org.apache.hadoop.hive.metastore.api.Constants.IS_ARCHIVED,
  820. "true");
  821. } else {
  822. params.remove(org.apache.hadoop.hive.metastore.api.Constants.IS_ARCHIVED);
  823. }
  824. }
  825. private String getOriginalLocation(Partition p) {
  826. Map<String, String> params = p.getParameters();
  827. return params.get(
  828. org.apache.hadoop.hive.metastore.api.Constants.ORIGINAL_LOCATION);
  829. }
  830. private void setOriginalLocation(Partition p, String loc) {
  831. Map<String, String> params = p.getParameters();
  832. if (loc == null) {
  833. params.remove(org.apache.hadoop.hive.metastore.api.Constants.ORIGINAL_LOCATION);
  834. } else {
  835. params.put(org.apache.hadoop.hive.metastore.api.Constants.ORIGINAL_LOCATION, loc);
  836. }
  837. }
  838. // Returns only the path component of the URI
  839. private String getArchiveDirOnly(Path parentDir, String archiveName) {
  840. URI parentUri = parentDir.toUri();
  841. Path harDir = new Path(parentUri.getPath(), archiveName);
  842. return harDir.toString();
  843. }
  844. /**
  845. * Sets the appropriate attributes in the supplied Partition object to mark
  846. * it as archived. Note that the metastore is not touched - a separate
  847. * call to alter_partition is needed.
  848. *
  849. * @param p - the partition object to modify
  850. * @param parentDir - the parent directory of the archive, which is the
  851. * original directory that the partition's files resided in
  852. * @param dirInArchive - the directory within the archive file that contains
  853. * the partitions files
  854. * @param archiveName - the name of the archive
  855. * @throws URISyntaxException
  856. */
  857. private void setArchived(Partition p, Path parentDir, String dirInArchive, String archiveName)
  858. throws URISyntaxException {
  859. assert(isArchived(p) == false);
  860. Map<String, String> params = p.getParameters();
  861. URI parentUri = parentDir.toUri();
  862. String parentHost = parentUri.getHost();
  863. String harHost = null;
  864. if (parentHost == null) {
  865. harHost = "";
  866. } else {
  867. harHost = parentUri.getScheme() + "-" + parentHost;
  868. }
  869. // harUri is used to access the partition's files, which are in the archive
  870. // The format of the RI is something like:
  871. // har://underlyingfsscheme-host:port/archivepath
  872. URI harUri = null;
  873. if (dirInArchive.length() == 0) {
  874. harUri = new URI("har", parentUri.getUserInfo(), harHost, parentUri.getPort(),
  875. getArchiveDirOnly(parentDir, archiveName),
  876. parentUri.getQuery(), parentUri.getFragment());
  877. } else {
  878. harUri = new URI("har", parentUri.getUserInfo(), harHost, parentUri.getPort(),
  879. new Path(getArchiveDirOnly(parentDir, archiveName), dirInArchive).toUri().getPath(),
  880. parentUri.getQuery(), parentUri.getFragment());
  881. }
  882. setIsArchived(p, true);
  883. setOriginalLocation(p, parentDir.toString());
  884. p.setLocation(harUri.toString());
  885. }
  886. /**
  887. * Sets the appropriate attributes in the supplied Partition object to mark
  888. * it as not archived. Note that the metastore is not touched - a separate
  889. * call to alter_partition is needed.
  890. *
  891. * @param p - the partition to modify
  892. */
  893. private void setUnArchived(Partition p) {
  894. assert(isArchived(p) == true);
  895. String parentDir = getOriginalLocation(p);
  896. setIsArchived(p, false);
  897. setOriginalLocation(p, null);
  898. assert(parentDir != null);
  899. p.setLocation(parentDir);
  900. }
  901. private boolean pathExists(Path p) throws HiveException {
  902. try {
  903. FileSystem fs = p.getFileSystem(conf);
  904. return fs.exists(p);
  905. } catch (IOException e) {
  906. throw new HiveException(e);
  907. }
  908. }
  909. private void moveDir(FileSystem fs, Path from, Path to) throws HiveException {
  910. try {
  911. if (!fs.rename(from, to)) {
  912. throw new HiveException("Moving " + from + " to " + to + " failed!");
  913. }
  914. } catch (IOException e) {
  915. throw new HiveException(e);
  916. }
  917. }
  918. private void deleteDir(Path dir) throws HiveException {
  919. try {
  920. Warehouse wh = new Warehouse(conf);
  921. wh.deleteDir(dir, true);
  922. } catch (MetaException e) {
  923. throw new HiveException(e);
  924. }
  925. }
  926. private int archive(Hive db, AlterTableSimpleDesc simpleDesc, DriverContext driverContext)
  927. throws HiveException {
  928. String dbName = simpleDesc.getDbName();
  929. String tblName = simpleDesc.getTableName();
  930. Table tbl = db.getTable(dbName, tblName);
  931. validateAlterTableType(tbl, AlterTableDesc.AlterTableTypes.ARCHIVE);
  932. Map<String, String> partSpec = simpleDesc.getPartSpec();
  933. Partition p = db.getPartition(tbl, partSpec, false);
  934. if (tbl.getTableType() != TableType.MANAGED_TABLE) {
  935. throw new HiveException("ARCHIVE can only be performed on managed tables");
  936. }
  937. if (p == null) {
  938. throw new HiveException("Specified partition does not exist");
  939. }
  940. if (isArchived(p)) {
  941. // If there were a failure right after the metadata was updated in an
  942. // archiving operation, it's possible that the original, unarchived files
  943. // weren't deleted.
  944. Path originalDir = new Path(getOriginalLocation(p));
  945. Path leftOverIntermediateOriginal = new Path(originalDir.getParent(),
  946. originalDir.getName() + INTERMEDIATE_ORIGINAL_DIR_SUFFIX);
  947. if (pathExists(leftOverIntermediateOriginal)) {
  948. console.printInfo("Deleting " + leftOverIntermediateOriginal +
  949. " left over from a previous archiving operation");
  950. deleteDir(leftOverIntermediateOriginal);
  951. }
  952. throw new HiveException("Specified partition is already archived");
  953. }
  954. Path originalDir = p.getPartitionPath();
  955. Path intermediateArchivedDir = new Path(originalDir.getParent(),
  956. originalDir.getName() + INTERMEDIATE_ARCHIVED_DIR_SUFFIX);
  957. Path intermediateOriginalDir = new Path(originalDir.getParent(),
  958. originalDir.getName() + INTERMEDIATE_ORIGINAL_DIR_SUFFIX);
  959. String archiveName = "data.har";
  960. FileSystem fs = null;
  961. try {
  962. fs = originalDir.getFileSystem(conf);
  963. } catch (IOException e) {
  964. throw new HiveException(e);
  965. }
  966. // The following steps seem roundabout, but they are meant to aid in
  967. // recovery if a failure occurs and to keep a consistent state in the FS
  968. // Steps:
  969. // 1. Create the archive in a temporary folder
  970. // 2. Move the archive dir to an intermediate dir that is in at the same
  971. // dir as the original partition dir. Call the new dir
  972. // intermediate-archive.
  973. // 3. Rename the original partition dir to an intermediate dir. Call the
  974. // renamed dir intermediate-original
  975. // 4. Rename intermediate-archive to the original partition dir
  976. // 5. Change the metadata
  977. // 6. Delete the original partition files in intermediate-original
  978. // The original partition files are deleted after the metadata change
  979. // because the presence of those files are used to indicate whether
  980. // the original partition directory contains archived or unarchived files.
  981. // Create an archived version of the partition in a directory ending in
  982. // ARCHIVE_INTERMEDIATE_DIR_SUFFIX that's the same level as the partition,
  983. // if it does not already exist. If it does exist, we assume the dir is good
  984. // to use as the move operation that created it is atomic.
  985. if (!pathExists(intermediateArchivedDir) &&
  986. !pathExists(intermediateOriginalDir)) {
  987. // First create the archive in a tmp dir so that if the job fails, the
  988. // bad files don't pollute the filesystem
  989. Path tmpDir = new Path(driverContext.getCtx().getExternalTmpFileURI(originalDir.toUri()), "partlevel");
  990. console.printInfo("Creating " + archiveName + " for " + originalDir.toString());
  991. console.printInfo("in " + tmpDir);
  992. console.printInfo("Please wait... (this may take a while)");
  993. // Create the Hadoop archive
  994. HadoopShims shim = ShimLoader.getHadoopShims();
  995. int ret=0;
  996. try {
  997. ret = shim.createHadoopArchive(conf, originalDir, tmpDir, archiveName);
  998. } catch (Exception e) {
  999. throw new HiveException(e);
  1000. }
  1001. if (ret != 0) {
  1002. throw new HiveException("Error while creating HAR");
  1003. }
  1004. // Move from the tmp dir to an intermediate directory, in the same level as
  1005. // the partition directory. e.g. .../hr=12-intermediate-archived
  1006. try {
  1007. console.printInfo("Moving " + tmpDir + " to " + intermediateArchivedDir);
  1008. if (pathExists(intermediateArchivedDir)) {
  1009. throw new HiveException("The intermediate archive directory already exists.");
  1010. }
  1011. fs.rename(tmpDir, intermediateArchivedDir);
  1012. } catch (IOException e) {
  1013. throw new HiveException("Error while moving tmp directory");
  1014. }
  1015. } else {
  1016. if (pathExists(intermediateArchivedDir)) {
  1017. console.printInfo("Intermediate archive directory " + intermediateArchivedDir +
  1018. " already exists. Assuming it contains an archived version of the partition");
  1019. }
  1020. }
  1021. // If we get to here, we know that we've archived the partition files, but
  1022. // they may be in the original partition location, or in the intermediate
  1023. // original dir.
  1024. // Move the original parent directory to the intermediate original directory
  1025. // if the move hasn't been made already
  1026. if (!pathExists(intermediateOriginalDir)) {
  1027. console.printInfo("Moving " + originalDir + " to " +
  1028. intermediateOriginalDir);
  1029. moveDir(fs, originalDir, intermediateOriginalDir);
  1030. } else {
  1031. console.printInfo(intermediateOriginalDir + " already exists. " +
  1032. "Assuming it contains the original files in the partition");
  1033. }
  1034. // If there's a failure from here to when the metadata is updated,
  1035. // there will be no data in the partition, or an error while trying to read
  1036. // the partition (if the archive files have been moved to the original
  1037. // partition directory.) But re-running the archive command will allow
  1038. // recovery
  1039. // Move the intermediate archived directory to the original parent directory
  1040. if (!pathExists(originalDir)) {
  1041. console.printInfo("Moving " + intermediateArchivedDir + " to " +
  1042. originalDir);
  1043. moveDir(fs, intermediateArchivedDir, originalDir);
  1044. } else {
  1045. console.printInfo(originalDir + " already exists. " +
  1046. "Assuming it contains the archived version of the partition");
  1047. }
  1048. // Record this change in the metastore
  1049. try {
  1050. boolean parentSettable =
  1051. conf.getBoolVar(HiveConf.ConfVars.HIVEHARPARENTDIRSETTABLE);
  1052. // dirInArchive is the directory within the archive that has all the files
  1053. // for this partition. With older versions of Hadoop, archiving a
  1054. // a directory would produce the same directory structure
  1055. // in the archive. So if you created myArchive.har of /tmp/myDir, the
  1056. // files in /tmp/myDir would be located under myArchive.har/tmp/myDir/*
  1057. // In this case, dirInArchive should be tmp/myDir
  1058. // With newer versions of Hadoop, the parent directory could be specified.
  1059. // Assuming the parent directory was set to /tmp/myDir when creating the
  1060. // archive, the files can be found under myArchive.har/*
  1061. // In this case, dirInArchive should be empty
  1062. String dirInArchive = "";
  1063. if (!parentSettable) {
  1064. dirInArchive = originalDir.toUri().getPath();
  1065. if(dirInArchive.length() > 1 && dirInArchive.charAt(0)=='/') {
  1066. dirInArchive = dirInArchive.substring(1);
  1067. }
  1068. }
  1069. setArchived(p, originalDir, dirInArchive, archiveName);
  1070. db.alterPartition(tblName, p);
  1071. } catch (Exception e) {
  1072. throw new HiveException("Unable to change the partition info for HAR", e);
  1073. }
  1074. // If a failure occurs here, the directory containing the original files
  1075. // will not be deleted. The user will run ARCHIVE again to clear this up
  1076. deleteDir(intermediateOriginalDir);
  1077. return 0;
  1078. }
  1079. private int unarchive(Hive db, AlterTableSimpleDesc simpleDesc)
  1080. throws HiveException {
  1081. String dbName = simpleDesc.getDbName();
  1082. String tblName = simpleDesc.getTableName();
  1083. Table tbl = db.getTable(dbName, tblName);
  1084. validateAlterTableType(tbl, AlterTableDesc.AlterTableTypes.UNARCHIVE);
  1085. // Means user specified a table, not a partition
  1086. if (simpleDesc.getPartSpec() == null) {
  1087. throw new HiveException("ARCHIVE is for partitions only");
  1088. }
  1089. Map<String, String> partSpec = simpleDesc.getPartSpec();
  1090. Partition p = db.getPartition(tbl, partSpec, false);
  1091. if (tbl.getTableType() != TableType.MANAGED_TABLE) {
  1092. throw new HiveException("UNARCHIVE can only be performed on managed tables");
  1093. }
  1094. if (p == null) {
  1095. throw new HiveException("Specified partition does not exist");
  1096. }
  1097. if (!isArchived(p)) {
  1098. Path location = new Path(p.getLocation());
  1099. Path leftOverArchiveDir = new Path(location.getParent(),
  1100. location.getName() + INTERMEDIATE_ARCHIVED_DIR_SUFFIX);
  1101. if (pathExists(leftOverArchiveDir)) {
  1102. console.printInfo("Deleting " + leftOverArchiveDir + " left over " +
  1103. "from a previous unarchiving operation");
  1104. deleteDir(leftOverArchiveDir);
  1105. }
  1106. throw new HiveException("Specified partition is not archived");
  1107. }
  1108. Path originalLocation = new Path(getOriginalLocation(p));
  1109. Path sourceDir = new Path(p.getLocation());
  1110. Path intermediateArchiveDir = new Path(originalLocation.getParent(),
  1111. originalLocation.getName() + INTERMEDIATE_ARCHIVED_DIR_SUFFIX);
  1112. Path intermediateExtractedDir = new Path(originalLocation.getParent(),
  1113. originalLocation.getName() + INTERMEDIATE_EXTRACTED_DIR_SUFFIX);
  1114. Path tmpDir = new Path(driverContext
  1115. .getCtx()
  1116. .getExternalTmpFileURI(originalLocation.toUri()));
  1117. FileSystem fs = null;
  1118. try {
  1119. fs = tmpDir.getFileSystem(conf);
  1120. // Verify that there are no files in the tmp dir, because if there are, it
  1121. // would be copied to the partition
  1122. FileStatus [] filesInTmpDir = fs.listStatus(tmpDir);
  1123. if (filesInTmpDir != null && filesInTmpDir.length != 0) {
  1124. for (FileStatus file : filesInTmpDir) {
  1125. console.printInfo(file.getPath().toString());
  1126. }
  1127. throw new HiveException("Temporary directory " + tmpDir + " is not empty");
  1128. }
  1129. } catch (IOException e) {
  1130. throw new HiveException(e);
  1131. }
  1132. // Some sanity checks
  1133. if (originalLocation == null) {
  1134. throw new HiveException("Missing archive data in the partition");
  1135. }
  1136. if (!"har".equals(sourceDir.toUri().getScheme())) {
  1137. throw new HiveException("Location should refer to a HAR");
  1138. }
  1139. // Clarification of terms:
  1140. // - The originalLocation directory represents the original directory of the
  1141. // partition's files. They now contain an archived version of those files
  1142. // eg. hdfs:/warehouse/myTable/ds=1/
  1143. // - The source directory is the directory containing all the files that
  1144. // should be in the partition. e.g. har:/warehouse/myTable/ds=1/myTable.har/
  1145. // Note the har:/ scheme
  1146. // Steps:
  1147. // 1. Extract the archive in a temporary folder
  1148. // 2. Move the archive dir to an intermediate dir that is in at the same
  1149. // dir as originalLocation. Call the new dir intermediate-extracted.
  1150. // 3. Rename the original partition dir to an intermediate dir. Call the
  1151. // renamed dir intermediate-archive
  1152. // 4. Rename intermediate-extracted to the original partition dir
  1153. // 5. Change the metadata
  1154. // 6. Delete the archived partition files in intermediate-archive
  1155. if (!pathExists(intermediateExtractedDir) &&
  1156. !pathExists(intermediateArchiveDir)) {
  1157. try {
  1158. // Copy the files out of …

Large files files are truncated, but you can click here to view the full file