diff --git itests/hive-unit/src/test/java/org/apache/hadoop/hive/metastore/TestHiveMetaStore.java itests/hive-unit/src/test/java/org/apache/hadoop/hive/metastore/TestHiveMetaStore.java index f344c47443..0aa1d4e16a 100644 --- itests/hive-unit/src/test/java/org/apache/hadoop/hive/metastore/TestHiveMetaStore.java +++ itests/hive-unit/src/test/java/org/apache/hadoop/hive/metastore/TestHiveMetaStore.java @@ -2999,7 +2999,7 @@ public void testTransactionalValidation() throws Throwable { Table t = createTable(dbName, tblName, owner, params, null, sd, 0); Assert.assertTrue("Expected exception", false); } catch (MetaException e) { - Assert.assertEquals("'transactional' property of TBLPROPERTIES may only have value 'true'", e.getMessage()); + Assert.assertEquals("'transactional' property of TBLPROPERTIES may only have value 'true': acidDb.acidTable", e.getMessage()); } // Fail - "transactional" property is set to an invalid value @@ -3009,7 +3009,7 @@ public void testTransactionalValidation() throws Throwable { Table t = createTable(dbName, tblName, owner, params, null, sd, 0); Assert.assertTrue("Expected exception", false); } catch (MetaException e) { - Assert.assertEquals("'transactional' property of TBLPROPERTIES may only have value 'true'", e.getMessage()); + Assert.assertEquals("'transactional' property of TBLPROPERTIES may only have value 'true': acidDb.acidTable", e.getMessage()); } // Fail - "transactional" is set to true, but the table is not bucketed @@ -3019,7 +3019,7 @@ public void testTransactionalValidation() throws Throwable { Table t = createTable(dbName, tblName, owner, params, null, sd, 0); Assert.assertTrue("Expected exception", false); } catch (MetaException e) { - Assert.assertEquals("The table must be stored using an ACID compliant format (such as ORC)", e.getMessage()); + Assert.assertEquals("The table must be stored using an ACID compliant format (such as ORC): acidDb.acidTable", e.getMessage()); } // Fail - "transactional" is set to true, and the table is bucketed, but doesn't use ORC @@ -3032,7 +3032,7 @@ public void testTransactionalValidation() throws Throwable { Table t = createTable(dbName, tblName, owner, params, null, sd, 0); Assert.assertTrue("Expected exception", false); } catch (MetaException e) { - Assert.assertEquals("The table must be stored using an ACID compliant format (such as ORC)", e.getMessage()); + Assert.assertEquals("The table must be stored using an ACID compliant format (such as ORC): acidDb.acidTable", e.getMessage()); } // Succeed - "transactional" is set to true, and the table is bucketed, and uses ORC @@ -3052,12 +3052,11 @@ public void testTransactionalValidation() throws Throwable { try { params.clear(); params.put("transactional", "false"); - t = new Table(); t.setParameters(params); client.alter_table(dbName, tblName, t); Assert.assertTrue("Expected exception", false); } catch (MetaException e) { - Assert.assertEquals("TBLPROPERTIES with 'transactional'='true' cannot be unset", e.getMessage()); + Assert.assertEquals("TBLPROPERTIES with 'transactional'='true' cannot be unset: aciddb.acidtable", e.getMessage()); } // Fail - trying to set "transactional" to "true" but doesn't satisfy bucketing and Input/OutputFormat requirement @@ -3072,7 +3071,7 @@ public void testTransactionalValidation() throws Throwable { client.alter_table(dbName, tblName, t); Assert.assertTrue("Expected exception", false); } catch (MetaException e) { - Assert.assertEquals("The table must be stored using an ACID compliant format (such as ORC)", e.getMessage()); + Assert.assertEquals("The table must be stored using an ACID compliant format (such as ORC): aciddb.acidtable1", e.getMessage()); } // Succeed - trying to set "transactional" to "true", and satisfies bucketing and Input/OutputFormat requirement 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 c9ee68891e..59d8489918 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 @@ -138,7 +138,8 @@ private void handleAlterTableTransactionalProp(PreAlterTableEvent context) throw 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)"); + throw new MetaException("The table must be stored using an ACID compliant format (such as ORC): " + + Warehouse.getQualifiedName(newTable)); } } @@ -161,7 +162,8 @@ private void handleAlterTableTransactionalProp(PreAlterTableEvent context) throw if (!hasValidTransactionalValue && !MetaStoreUtils.isInsertOnlyTableParam(oldTable.getParameters())) { // if here, there is attempt to set transactional to something other than 'true' // and NOT the same value it was before - throw new MetaException("TBLPROPERTIES with 'transactional'='true' cannot be unset"); + throw new MetaException("TBLPROPERTIES with 'transactional'='true' cannot be unset: " + + Warehouse.getQualifiedName(newTable)); } if (isTransactionalPropertiesPresent) { @@ -230,7 +232,8 @@ private void handleCreateTableTransactionalProp(PreCreateTableEvent context) thr if ("false".equalsIgnoreCase(transactional)) { // just drop transactional=false. For backward compatibility in case someone has scripts // with transactional=false - LOG.info("'transactional'='false' is no longer a valid property and will be ignored"); + LOG.info("'transactional'='false' is no longer a valid property and will be ignored: " + + Warehouse.getQualifiedName(newTable)); return; } @@ -257,7 +260,8 @@ private void handleCreateTableTransactionalProp(PreCreateTableEvent context) thr return; } // transactional is found, but the value is not in expected range - throw new MetaException("'transactional' property of TBLPROPERTIES may only have value 'true'"); + throw new MetaException("'transactional' property of TBLPROPERTIES may only have value 'true': " + + Warehouse.getQualifiedName(newTable)); } /** @@ -274,11 +278,13 @@ private void normazlieTransactionalPropertyDefault(Table table) { * Check that InputFormatClass/OutputFormatClass should implement * AcidInputFormat/AcidOutputFormat */ - private boolean conformToAcid(Table table) throws MetaException { + public static boolean conformToAcid(Table table) throws MetaException { StorageDescriptor sd = table.getSd(); try { - Class inputFormatClass = Class.forName(sd.getInputFormat()); - Class outputFormatClass = Class.forName(sd.getOutputFormat()); + Class inputFormatClass = sd.getInputFormat() == null ? null : + Class.forName(sd.getInputFormat()); + Class outputFormatClass = sd.getOutputFormat() == null ? null : + Class.forName(sd.getOutputFormat()); if (inputFormatClass == null || outputFormatClass == null || !Class.forName("org.apache.hadoop.hive.ql.io.AcidInputFormat").isAssignableFrom(inputFormatClass) || @@ -286,7 +292,9 @@ private boolean conformToAcid(Table table) throws MetaException { return false; } } catch (ClassNotFoundException e) { - throw new MetaException("Invalid input/output format for table"); + LOG.warn("Could not verify InputFormat=" + sd.getInputFormat() + " or OutputFormat=" + + sd.getOutputFormat() + " for " + Warehouse.getQualifiedName(table)); + return false; } return true; @@ -311,8 +319,8 @@ private void initializeTransactionalProperties(Table table) throws MetaException parameters.remove(key); String validationError = validateTransactionalProperties(tableTransactionalProperties); if (validationError != null) { - throw new MetaException("Invalid transactional properties specified for the " - + "table with the error " + validationError); + throw new MetaException("Invalid transactional properties specified for " + + Warehouse.getQualifiedName(table) + " with the error " + validationError); } break; }