diff --git a/beeline/src/java/org/apache/hive/beeline/HiveSchemaTool.java b/beeline/src/java/org/apache/hive/beeline/HiveSchemaTool.java index 3402470..33561fe 100644 --- a/beeline/src/java/org/apache/hive/beeline/HiveSchemaTool.java +++ b/beeline/src/java/org/apache/hive/beeline/HiveSchemaTool.java @@ -148,9 +148,14 @@ public void showInfo() throws HiveMetaException { } - // read schema version from metastore private String getMetaStoreSchemaVersion(Connection metastoreConn) throws HiveMetaException { + return getMetaStoreSchemaVersion(metastoreConn, false); + } + + // read schema version from metastore + private String getMetaStoreSchemaVersion(Connection metastoreConn, + boolean checkDuplicatedVersion) throws HiveMetaException { String versionQuery; if (getDbCommandParser(dbType).needsQuotedIdentifier()) { versionQuery = "select t.\"SCHEMA_VERSION\" from \"VERSION\" t"; @@ -163,6 +168,9 @@ private String getMetaStoreSchemaVersion(Connection metastoreConn) throw new HiveMetaException("Didn't find version data in metastore"); } String currentSchemaVersion = res.getString(1); + if (checkDuplicatedVersion && res.next()) { + throw new HiveMetaException("Multiple versions were found in metastore."); + } return currentSchemaVersion; } catch (SQLException e) { throw new HiveMetaException("Failed to get schema version.", e); @@ -303,6 +311,7 @@ public void doInit(String toVersion) throws HiveMetaException { public void doValidate() throws HiveMetaException { System.out.print("Starting metastore validation"); + validateSchemaVersions(); validateSequences(); validateSchemaTables(); @@ -370,6 +379,26 @@ boolean validateSequences() throws HiveMetaException { } } + boolean validateSchemaVersions() throws HiveMetaException { + System.out.println("Validating schema version"); + try { + String newSchemaVersion = getMetaStoreSchemaVersion( + getConnectionToMetastore(false), true); + assertCompatibleVersion(MetaStoreSchemaInfo.getHiveSchemaVersion(), newSchemaVersion); + } catch (HiveMetaException hme) { + if (hme.getMessage().contains("Metastore schema version is not compatible") + || hme.getMessage().contains("Multiple versions were found in metastore") + || hme.getMessage().contains("Didn't find version data in metastore")) { + System.out.println("Failed in schema version validation: " + hme.getMessage()); + return false; + } else { + throw hme; + } + } + System.out.println("Succeeded in schema version validation."); + return true; + } + boolean validateSchemaTables() throws HiveMetaException { ResultSet rs = null; DatabaseMetaData metadata = null; diff --git a/itests/hive-unit/src/test/java/org/apache/hive/beeline/TestSchemaTool.java b/itests/hive-unit/src/test/java/org/apache/hive/beeline/TestSchemaTool.java index 2209c83..96878ed 100644 --- a/itests/hive-unit/src/test/java/org/apache/hive/beeline/TestSchemaTool.java +++ b/itests/hive-unit/src/test/java/org/apache/hive/beeline/TestSchemaTool.java @@ -187,6 +187,40 @@ public void testSchemaInit() throws Exception { } /** + * Test validation for schema versions + * @throws Exception + */ + public void testValidateSchemaVersions() throws Exception { + schemaTool.doInit(); + boolean isValid = schemaTool.validateSchemaVersions(); + // Test an invalid case with multiple versions + String[] scripts = new String[] { + "insert into VERSION values(100, '2.2.0', 'Hive release version 2.2.0')" + }; + File scriptFile = generateTestScript(scripts); + schemaTool.runBeeLine(scriptFile.getPath()); + isValid = schemaTool.validateSchemaVersions(); + assertFalse(isValid); + + scripts = new String[] { + "delete from VERSION where VER_ID = 100" + }; + scriptFile = generateTestScript(scripts); + schemaTool.runBeeLine(scriptFile.getPath()); + isValid = schemaTool.validateSchemaVersions(); + assertTrue(isValid); + + // Test an invalid case without version + scripts = new String[] { + "delete from VERSION" + }; + scriptFile = generateTestScript(scripts); + schemaTool.runBeeLine(scriptFile.getPath()); + isValid = schemaTool.validateSchemaVersions(); + assertFalse(isValid); + } + + /** * Test schema upgrade * @throws Exception */