diff --git ql/src/java/org/apache/hadoop/hive/ql/parse/AcidExportSemanticAnalyzer.java ql/src/java/org/apache/hadoop/hive/ql/parse/AcidExportSemanticAnalyzer.java index 8ab39433ec..3f338a500d 100644 --- ql/src/java/org/apache/hadoop/hive/ql/parse/AcidExportSemanticAnalyzer.java +++ ql/src/java/org/apache/hadoop/hive/ql/parse/AcidExportSemanticAnalyzer.java @@ -121,6 +121,11 @@ private void analyzeAcidExport(ASTNode ast) throws SemanticException { assert tableTree != null && tableTree.getType() == HiveParser.TOK_TAB; ASTNode tokRefOrNameExportTable = (ASTNode) tableTree.getChild(0); Table exportTable = getTargetTable(tokRefOrNameExportTable); + + if (exportTable.getTableType() == org.apache.hadoop.hive.metastore.TableType.VIRTUAL_VIEW || + exportTable.getTableType() == org.apache.hadoop.hive.metastore.TableType.MATERIALIZED_VIEW) { + throw new SemanticException("Views and Materialized Views can not be exported."); + } assert AcidUtils.isFullAcidTable(exportTable); //need to create the table "manually" rather than creating a task since it has to exist to diff --git ql/src/java/org/apache/hadoop/hive/ql/parse/ExportSemanticAnalyzer.java ql/src/java/org/apache/hadoop/hive/ql/parse/ExportSemanticAnalyzer.java index 8c82379343..c0a3966983 100644 --- ql/src/java/org/apache/hadoop/hive/ql/parse/ExportSemanticAnalyzer.java +++ ql/src/java/org/apache/hadoop/hive/ql/parse/ExportSemanticAnalyzer.java @@ -33,6 +33,7 @@ import org.apache.hadoop.hive.ql.hooks.ReadEntity; import org.apache.hadoop.hive.ql.hooks.WriteEntity; import org.apache.hadoop.hive.ql.metadata.Hive; +import org.apache.hadoop.hive.ql.metadata.HiveException; import org.apache.hadoop.hive.ql.metadata.InvalidTableException; import org.apache.hadoop.hive.ql.metadata.Table; import org.apache.hadoop.hive.ql.parse.repl.dump.TableExport; @@ -100,6 +101,17 @@ public void analyzeInternal(ASTNode ast) throws SemanticException { } } + Table exportTable; + try { + exportTable = db.getTable(ts.getTableName()); + } catch (HiveException e) { + throw new SemanticException(e.getMessage(), e); + } + if (exportTable.getTableType() == org.apache.hadoop.hive.metastore.TableType.VIRTUAL_VIEW || + exportTable.getTableType() == org.apache.hadoop.hive.metastore.TableType.MATERIALIZED_VIEW) { + throw new SemanticException("Views and Materialized Views can not be exported."); + } + // initialize export path String tmpPath = stripQuotes(toTree.getText()); // All parsing is done, we're now good to start the export process diff --git ql/src/java/org/apache/hadoop/hive/ql/plan/ImportTableDesc.java ql/src/java/org/apache/hadoop/hive/ql/plan/ImportTableDesc.java index dc7040e388..c242ab13ef 100644 --- ql/src/java/org/apache/hadoop/hive/ql/plan/ImportTableDesc.java +++ ql/src/java/org/apache/hadoop/hive/ql/plan/ImportTableDesc.java @@ -22,7 +22,6 @@ import java.util.Map; import java.util.Set; -import com.google.common.collect.ImmutableSet; import org.apache.hadoop.hive.common.TableName; import org.apache.hadoop.hive.conf.HiveConf; import org.apache.hadoop.hive.metastore.TableType; @@ -30,12 +29,10 @@ import org.apache.hadoop.hive.metastore.api.Order; import org.apache.hadoop.hive.ql.ddl.DDLWork; import org.apache.hadoop.hive.ql.ddl.table.create.CreateTableDesc; -import org.apache.hadoop.hive.ql.ddl.view.create.CreateViewDesc; import org.apache.hadoop.hive.ql.exec.Task; import org.apache.hadoop.hive.ql.exec.TaskFactory; import org.apache.hadoop.hive.ql.hooks.ReadEntity; import org.apache.hadoop.hive.ql.hooks.WriteEntity; -import org.apache.hadoop.hive.ql.metadata.HiveException; import org.apache.hadoop.hive.ql.metadata.Table; import org.apache.hadoop.hive.ql.parse.HiveTableName; import org.apache.hadoop.hive.ql.parse.ReplicationSpec; @@ -49,341 +46,138 @@ private String dbName = null; private Table table = null; private CreateTableDesc createTblDesc = null; - private CreateViewDesc createViewDesc = null; - - public enum TYPE { TABLE, VIEW }; public ImportTableDesc(String dbName, Table table) throws Exception { this.dbName = dbName; this.table = table; final TableName tableName = HiveTableName.ofNullable(table.getTableName(), dbName); - switch (getDescType()) { - case TABLE: - this.createTblDesc = new CreateTableDesc(tableName, - false, // isExternal: set to false here, can be overwritten by the IMPORT stmt - false, - table.getSd().getCols(), - table.getPartitionKeys(), - table.getSd().getBucketCols(), - table.getSd().getSortCols(), - table.getSd().getNumBuckets(), - null, null, null, null, null, // these 5 delims passed as serde params - null, // comment passed as table params - table.getSd().getInputFormat(), - table.getSd().getOutputFormat(), - null, // location: set to null here, can be overwritten by the IMPORT stmt - table.getSd().getSerdeInfo().getSerializationLib(), - null, // storagehandler passed as table params - table.getSd().getSerdeInfo().getParameters(), - table.getParameters(), false, - (null == table.getSd().getSkewedInfo()) ? null : table.getSd().getSkewedInfo() - .getSkewedColNames(), - (null == table.getSd().getSkewedInfo()) ? null : table.getSd().getSkewedInfo() - .getSkewedColValues(), - null, - null, - null, - null, - null, - null, - table.getColStats(), - table.getTTable().getWriteId()); - this.createTblDesc.setStoredAsSubDirectories(table.getSd().isStoredAsSubDirectories()); - break; - case VIEW: - final String dbDotView = tableName.getNotEmptyDbTable(); - if (table.isMaterializedView()) { - this.createViewDesc = new CreateViewDesc(dbDotView, - table.getAllCols(), - null, // comment passed as table params - table.getParameters(), - table.getPartColNames(), - null, // sort columns passed as table params (if present) - null, // distribute columns passed as table params (if present) - false,false,false,false, - table.getSd().getInputFormat(), - table.getSd().getOutputFormat(), - null, // location: set to null here, can be overwritten by the IMPORT stmt - table.getSd().getSerdeInfo().getSerializationLib(), - null, // storagehandler passed as table params - table.getSd().getSerdeInfo().getParameters()); - // TODO: If the DB name from the creation metadata for any of the tables has changed, - // we should update it. Currently it refers to the source database name. - this.createViewDesc.setTablesUsed(table.getCreationMetadata() != null ? - table.getCreationMetadata().getTablesUsed() : ImmutableSet.of()); - } else { - this.createViewDesc = new CreateViewDesc(dbDotView, - table.getAllCols(), - null, // comment passed as table params - table.getParameters(), - table.getPartColNames(), - false,false,false, - table.getSd().getInputFormat(), - table.getSd().getOutputFormat(), - table.getSd().getSerdeInfo().getSerializationLib()); - } - - this.setViewAsReferenceText(dbName, table); - this.createViewDesc.setPartCols(table.getPartCols()); - break; - default: - throw new HiveException("Invalid table type"); - } - } - - public TYPE getDescType() { - if (table.isView() || table.isMaterializedView()) { - return TYPE.VIEW; - } - return TYPE.TABLE; - } - - public void setViewAsReferenceText(String dbName, Table table) { - String originalText = table.getViewOriginalText(); - String expandedText = table.getViewExpandedText(); - - if (!dbName.equals(table.getDbName())) { - // TODO: If the DB name doesn't match with the metadata from dump, then need to rewrite the original and expanded - // texts using new DB name. Currently it refers to the source database name. - } - - this.createViewDesc.setViewOriginalText(originalText); - this.createViewDesc.setViewExpandedText(expandedText); + this.createTblDesc = new CreateTableDesc(tableName, + false, // isExternal: set to false here, can be overwritten by the IMPORT stmt + false, + table.getSd().getCols(), + table.getPartitionKeys(), + table.getSd().getBucketCols(), + table.getSd().getSortCols(), + table.getSd().getNumBuckets(), + null, null, null, null, null, // these 5 delims passed as serde params + null, // comment passed as table params + table.getSd().getInputFormat(), + table.getSd().getOutputFormat(), + null, // location: set to null here, can be overwritten by the IMPORT stmt + table.getSd().getSerdeInfo().getSerializationLib(), + null, // storagehandler passed as table params + table.getSd().getSerdeInfo().getParameters(), + table.getParameters(), false, + (null == table.getSd().getSkewedInfo()) ? null : table.getSd().getSkewedInfo().getSkewedColNames(), + (null == table.getSd().getSkewedInfo()) ? null : table.getSd().getSkewedInfo().getSkewedColValues(), + null, + null, + null, + null, + null, + null, + table.getColStats(), + table.getTTable().getWriteId()); + this.createTblDesc.setStoredAsSubDirectories(table.getSd().isStoredAsSubDirectories()); } public void setReplicationSpec(ReplicationSpec replSpec) { - switch (getDescType()) { - case TABLE: - createTblDesc.setReplicationSpec(replSpec); - break; - case VIEW: - createViewDesc.setReplicationSpec(replSpec); - break; - } + createTblDesc.setReplicationSpec(replSpec); } public void setExternal(boolean isExternal) { - if (TYPE.TABLE.equals(getDescType())) { - createTblDesc.setExternal(isExternal); - } + createTblDesc.setExternal(isExternal); } public boolean isExternal() { - if (TYPE.TABLE.equals(getDescType())) { - return createTblDesc.isExternal(); - } - return false; + return createTblDesc.isExternal(); } public void setLocation(String location) { - switch (getDescType()) { - case TABLE: - createTblDesc.setLocation(location); - break; - case VIEW: - createViewDesc.setLocation(location); - break; - } + createTblDesc.setLocation(location); } public String getLocation() { - switch (getDescType()) { - case TABLE: - return createTblDesc.getLocation(); - case VIEW: - return createViewDesc.getLocation(); - } - return null; + return createTblDesc.getLocation(); } public void setTableName(TableName tableName) throws SemanticException { - switch (getDescType()) { - case TABLE: - createTblDesc.setTableName(tableName); - break; - case VIEW: - createViewDesc.setViewName(tableName.getNotEmptyDbTable()); - break; - } + createTblDesc.setTableName(tableName); } public String getTableName() throws SemanticException { - switch (getDescType()) { - case TABLE: - return createTblDesc.getTableName().getTable(); - case VIEW: - return TableName.fromString(createViewDesc.getViewName(), null, null).getTable(); - } - return null; + return createTblDesc.getTableName().getTable(); } public List getPartCols() { - switch (getDescType()) { - case TABLE: - return createTblDesc.getPartCols(); - case VIEW: - return createViewDesc.getPartCols(); - } - return null; + return createTblDesc.getPartCols(); } public List getCols() { - switch (getDescType()) { - case TABLE: - return createTblDesc.getCols(); - case VIEW: - return createViewDesc.getSchema(); - } - return null; + return createTblDesc.getCols(); } public Map getTblProps() { - switch (getDescType()) { - case TABLE: - return createTblDesc.getTblProps(); - case VIEW: - return createViewDesc.getTblProps(); - } - return null; + return createTblDesc.getTblProps(); } public String getInputFormat() { - switch (getDescType()) { - case TABLE: - return createTblDesc.getInputFormat(); - case VIEW: - return createViewDesc.getInputFormat(); - } - return null; + return createTblDesc.getInputFormat(); } public String getOutputFormat() { - switch (getDescType()) { - case TABLE: - return createTblDesc.getOutputFormat(); - case VIEW: - return createViewDesc.getOutputFormat(); - } - return null; + return createTblDesc.getOutputFormat(); } public String getSerName() { - switch (getDescType()) { - case TABLE: - return createTblDesc.getSerName(); - case VIEW: - return createViewDesc.getSerde(); - } - return null; + return createTblDesc.getSerName(); } public Map getSerdeProps() { - switch (getDescType()) { - case TABLE: - return createTblDesc.getSerdeProps(); - case VIEW: - return createViewDesc.getSerdeProps(); - } - return null; + return createTblDesc.getSerdeProps(); } public List getBucketCols() { - if (TYPE.TABLE.equals(getDescType())) { - return createTblDesc.getBucketCols(); - } - return null; + return createTblDesc.getBucketCols(); } public List getSortCols() { - if (TYPE.TABLE.equals(getDescType())) { - return createTblDesc.getSortCols(); - } - return null; + return createTblDesc.getSortCols(); } /** * @param replaceMode Determine if this CreateTable should behave like a replace-into alter instead */ public void setReplaceMode(boolean replaceMode) { - switch (getDescType()) { - case TABLE: - createTblDesc.setReplaceMode(replaceMode); - break; - case VIEW: - createViewDesc.setReplace(replaceMode); - } + createTblDesc.setReplaceMode(replaceMode); } public String getDatabaseName() { return dbName; } - public Task getCreateTableTask(Set inputs, Set outputs, - HiveConf conf) { - switch (getDescType()) { - case TABLE: - return TaskFactory.get(new DDLWork(inputs, outputs, createTblDesc), conf); - case VIEW: - return TaskFactory.get(new DDLWork(inputs, outputs, createViewDesc), conf); - } - return null; - } - - /** - * @return whether this table is actually a view - */ - public boolean isView() { - return table.isView(); - } - - public boolean isMaterializedView() { - return table.isMaterializedView(); + public Task getCreateTableTask(Set inputs, Set outputs, HiveConf conf) { + return TaskFactory.get(new DDLWork(inputs, outputs, createTblDesc), conf); } public TableType tableType() { - if (isView()) { - return TableType.VIRTUAL_VIEW; - } else if (isMaterializedView()) { - return TableType.MATERIALIZED_VIEW; - } return TableType.MANAGED_TABLE; } public Table toTable(HiveConf conf) throws Exception { - switch (getDescType()) { - case TABLE: - return createTblDesc.toTable(conf); - case VIEW: - return createViewDesc.toTable(conf); - default: - return null; - } + return createTblDesc.toTable(conf); } public void setReplWriteId(Long replWriteId) { - if (this.createTblDesc != null) { - this.createTblDesc.setReplWriteId(replWriteId); - } + this.createTblDesc.setReplWriteId(replWriteId); } public void setOwnerName(String ownerName) { - switch (getDescType()) { - case TABLE: - createTblDesc.setOwnerName(ownerName); - break; - case VIEW: - createViewDesc.setOwnerName(ownerName); - break; - default: - throw new RuntimeException("Invalid table type : " + getDescType()); - } + createTblDesc.setOwnerName(ownerName); } public Long getReplWriteId() { - if (this.createTblDesc != null) { - return this.createTblDesc.getReplWriteId(); - } - return -1L; + return this.createTblDesc.getReplWriteId(); } } diff --git ql/src/test/queries/clientnegative/export_materialized_view.q ql/src/test/queries/clientnegative/export_materialized_view.q new file mode 100644 index 0000000000..81ce8416db --- /dev/null +++ ql/src/test/queries/clientnegative/export_materialized_view.q @@ -0,0 +1,5 @@ +create table t ( a int ); + +create materialized view export_materialized_view disable rewrite as select * from t; + +export table export_materialized_view to 'ql/test/data/exports/export_materialized_view'; diff --git ql/src/test/queries/clientnegative/export_view.q ql/src/test/queries/clientnegative/export_view.q new file mode 100644 index 0000000000..086e8d9fdb --- /dev/null +++ ql/src/test/queries/clientnegative/export_view.q @@ -0,0 +1,5 @@ +create table t ( a int ); + +create view export_view as select * from t; + +export table export_view to 'ql/test/data/exports/export_view'; diff --git ql/src/test/results/clientnegative/export_materialized_view.q.out ql/src/test/results/clientnegative/export_materialized_view.q.out new file mode 100644 index 0000000000..239e41ef5f --- /dev/null +++ ql/src/test/results/clientnegative/export_materialized_view.q.out @@ -0,0 +1,19 @@ +PREHOOK: query: create table t ( a int ) +PREHOOK: type: CREATETABLE +PREHOOK: Output: database:default +PREHOOK: Output: default@t +POSTHOOK: query: create table t ( a int ) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: database:default +POSTHOOK: Output: default@t +PREHOOK: query: create materialized view export_materialized_view disable rewrite as select * from t +PREHOOK: type: CREATE_MATERIALIZED_VIEW +PREHOOK: Input: default@t +PREHOOK: Output: database:default +PREHOOK: Output: default@export_materialized_view +POSTHOOK: query: create materialized view export_materialized_view disable rewrite as select * from t +POSTHOOK: type: CREATE_MATERIALIZED_VIEW +POSTHOOK: Input: default@t +POSTHOOK: Output: database:default +POSTHOOK: Output: default@export_materialized_view +FAILED: SemanticException Views and Materialized Views can not be exported. diff --git ql/src/test/results/clientnegative/export_view.q.out ql/src/test/results/clientnegative/export_view.q.out new file mode 100644 index 0000000000..32a5c8c611 --- /dev/null +++ ql/src/test/results/clientnegative/export_view.q.out @@ -0,0 +1,20 @@ +PREHOOK: query: create table t ( a int ) +PREHOOK: type: CREATETABLE +PREHOOK: Output: database:default +PREHOOK: Output: default@t +POSTHOOK: query: create table t ( a int ) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: database:default +POSTHOOK: Output: default@t +PREHOOK: query: create view export_view as select * from t +PREHOOK: type: CREATEVIEW +PREHOOK: Input: default@t +PREHOOK: Output: database:default +PREHOOK: Output: default@export_view +POSTHOOK: query: create view export_view as select * from t +POSTHOOK: type: CREATEVIEW +POSTHOOK: Input: default@t +POSTHOOK: Output: database:default +POSTHOOK: Output: default@export_view +POSTHOOK: Lineage: export_view.a SIMPLE [(t)t.FieldSchema(name:a, type:int, comment:null), ] +FAILED: SemanticException Views and Materialized Views can not be exported.