diff --git ql/src/test/queries/clientpositive/mm_conversions.q ql/src/test/queries/clientpositive/mm_conversions.q index e933582927..6b221f68fb 100644 --- ql/src/test/queries/clientpositive/mm_conversions.q +++ ql/src/test/queries/clientpositive/mm_conversions.q @@ -61,6 +61,17 @@ insert into table part_to_mm partition(key_mm='457') select key from intermediat select * from part_to_mm s3 order by key, key_mm; drop table part_to_mm; + +drop table load_to_mm; +create table load_to_mm (key string, value string) tblproperties("transactional"="false"); +load data local inpath '../../data/files/kv1.txt' into table load_to_mm; +load data local inpath '../../data/files/kv1.txt' into table load_to_mm; +select count(*) from load_to_mm s1; +alter table load_to_mm set tblproperties("transactional"="true", "transactional_properties"="insert_only"); +select count(*) from load_to_mm s2; +drop table load_to_mm; + + set hive.mm.allow.originals=false; drop table simple_to_mm_text; diff --git ql/src/test/results/clientpositive/llap/mm_conversions.q.out ql/src/test/results/clientpositive/llap/mm_conversions.q.out index 8a9036a7bc..618aa3ce29 100644 --- ql/src/test/results/clientpositive/llap/mm_conversions.q.out +++ ql/src/test/results/clientpositive/llap/mm_conversions.q.out @@ -460,6 +460,68 @@ POSTHOOK: query: drop table part_to_mm POSTHOOK: type: DROPTABLE POSTHOOK: Input: default@part_to_mm POSTHOOK: Output: default@part_to_mm +PREHOOK: query: drop table load_to_mm +PREHOOK: type: DROPTABLE +POSTHOOK: query: drop table load_to_mm +POSTHOOK: type: DROPTABLE +PREHOOK: query: create table load_to_mm (key string, value string) tblproperties("transactional"="false") +PREHOOK: type: CREATETABLE +PREHOOK: Output: database:default +PREHOOK: Output: default@load_to_mm +POSTHOOK: query: create table load_to_mm (key string, value string) tblproperties("transactional"="false") +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: database:default +POSTHOOK: Output: default@load_to_mm +PREHOOK: query: load data local inpath '../../data/files/kv1.txt' into table load_to_mm +PREHOOK: type: LOAD +#### A masked pattern was here #### +PREHOOK: Output: default@load_to_mm +POSTHOOK: query: load data local inpath '../../data/files/kv1.txt' into table load_to_mm +POSTHOOK: type: LOAD +#### A masked pattern was here #### +POSTHOOK: Output: default@load_to_mm +PREHOOK: query: load data local inpath '../../data/files/kv1.txt' into table load_to_mm +PREHOOK: type: LOAD +#### A masked pattern was here #### +PREHOOK: Output: default@load_to_mm +POSTHOOK: query: load data local inpath '../../data/files/kv1.txt' into table load_to_mm +POSTHOOK: type: LOAD +#### A masked pattern was here #### +POSTHOOK: Output: default@load_to_mm +PREHOOK: query: select count(*) from load_to_mm s1 +PREHOOK: type: QUERY +PREHOOK: Input: default@load_to_mm +#### A masked pattern was here #### +POSTHOOK: query: select count(*) from load_to_mm s1 +POSTHOOK: type: QUERY +POSTHOOK: Input: default@load_to_mm +#### A masked pattern was here #### +1000 +PREHOOK: query: alter table load_to_mm set tblproperties("transactional"="true", "transactional_properties"="insert_only") +PREHOOK: type: ALTERTABLE_PROPERTIES +PREHOOK: Input: default@load_to_mm +PREHOOK: Output: default@load_to_mm +POSTHOOK: query: alter table load_to_mm set tblproperties("transactional"="true", "transactional_properties"="insert_only") +POSTHOOK: type: ALTERTABLE_PROPERTIES +POSTHOOK: Input: default@load_to_mm +POSTHOOK: Output: default@load_to_mm +PREHOOK: query: select count(*) from load_to_mm s2 +PREHOOK: type: QUERY +PREHOOK: Input: default@load_to_mm +#### A masked pattern was here #### +POSTHOOK: query: select count(*) from load_to_mm s2 +POSTHOOK: type: QUERY +POSTHOOK: Input: default@load_to_mm +#### A masked pattern was here #### +1000 +PREHOOK: query: drop table load_to_mm +PREHOOK: type: DROPTABLE +PREHOOK: Input: default@load_to_mm +PREHOOK: Output: default@load_to_mm +POSTHOOK: query: drop table load_to_mm +POSTHOOK: type: DROPTABLE +POSTHOOK: Input: default@load_to_mm +POSTHOOK: Output: default@load_to_mm PREHOOK: query: drop table simple_to_mm_text PREHOOK: type: DROPTABLE POSTHOOK: query: drop table simple_to_mm_text diff --git standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/TransactionalValidationListener.java standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/TransactionalValidationListener.java index 42d02489b4..c3d99c3926 100644 --- standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/TransactionalValidationListener.java +++ standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/TransactionalValidationListener.java @@ -132,24 +132,26 @@ private void handleAlterTableTransactionalProp(PreAlterTableEvent context) throw } if ("true".equalsIgnoreCase(transactionalValue) && !"true".equalsIgnoreCase(oldTransactionalValue)) { if(!isTransactionalPropertiesPresent) { - normazlieTransactionalPropertyDefault(newTable); + normalizeTransactionalPropertyDefault(newTable); isTransactionalPropertiesPresent = true; transactionalPropertiesValue = DEFAULT_TRANSACTIONAL_PROPERTY; } - //only need to check conformance if alter table enabled acid - if (!conformToAcid(newTable)) { - // INSERT_ONLY tables don't have to conform to ACID requirement like ORC or bucketing - if (transactionalPropertiesValue == null || !"insert_only".equalsIgnoreCase(transactionalPropertiesValue)) { - throw new MetaException("The table must be stored using an ACID compliant format (such as ORC): " - + Warehouse.getQualifiedName(newTable)); - } + // We only need to check conformance if alter table enabled acid. + // INSERT_ONLY tables don't have to conform to ACID requirement like ORC or bucketing. + boolean isFullAcid = transactionalPropertiesValue == null + || !"insert_only".equalsIgnoreCase(transactionalPropertiesValue); + if (isFullAcid && !conformToAcid(newTable)) { + throw new MetaException("The table must be stored using an ACID compliant " + + "format (such as ORC): " + Warehouse.getQualifiedName(newTable)); } if (newTable.getTableType().equals(TableType.EXTERNAL_TABLE.toString())) { throw new MetaException(Warehouse.getQualifiedName(newTable) + " cannot be declared transactional because it's an external table"); } - validateTableStructure(context.getHandler(), newTable); + if (isFullAcid) { + validateTableStructure(context.getHandler(), newTable); + } hasValidTransactionalValue = true; } @@ -189,6 +191,7 @@ private void handleAlterTableTransactionalProp(PreAlterTableEvent context) throw } checkSorted(newTable); } + private void checkSorted(Table newTable) throws MetaException { if(!TxnUtils.isAcidTable(newTable)) { return; @@ -309,7 +312,7 @@ private void handleCreateTableTransactionalProp(PreCreateTableEvent context) thr // normalize prop name parameters.put(hive_metastoreConstants.TABLE_IS_TRANSACTIONAL, Boolean.TRUE.toString()); if(transactionalProperties == null) { - normazlieTransactionalPropertyDefault(newTable); + normalizeTransactionalPropertyDefault(newTable); } initializeTransactionalProperties(newTable); checkSorted(newTable); @@ -325,7 +328,7 @@ private void handleCreateTableTransactionalProp(PreCreateTableEvent context) thr * transactional_properties should take on the default value. Easier to make this explicit in * table definition than keep checking everywhere if it's set or not. */ - private void normazlieTransactionalPropertyDefault(Table table) { + private void normalizeTransactionalPropertyDefault(Table table) { table.getParameters().put(hive_metastoreConstants.TABLE_TRANSACTIONAL_PROPERTIES, DEFAULT_TRANSACTIONAL_PROPERTY);