diff --git a/beeline/src/java/org/apache/hive/beeline/HiveSchemaTool.java b/beeline/src/java/org/apache/hive/beeline/HiveSchemaTool.java index ed58fe0..79ecad3 100644 --- a/beeline/src/java/org/apache/hive/beeline/HiveSchemaTool.java +++ b/beeline/src/java/org/apache/hive/beeline/HiveSchemaTool.java @@ -129,7 +129,7 @@ public void showInfo() throws HiveMetaException { String dbVersion = getMetaStoreSchemaVersion(metastoreConn); System.out.println("Hive distribution version:\t " + hiveVersion); System.out.println("Metastore schema version:\t " + dbVersion); - assertSameVersion(hiveVersion, dbVersion); + assertCompatibleVersion(hiveVersion, dbVersion); } @@ -179,15 +179,15 @@ public void verifySchemaVersion() throws HiveMetaException { String newSchemaVersion = getMetaStoreSchemaVersion( getConnectionToMetastore(false)); // verify that the new version is added to schema - assertSameVersion(MetaStoreSchemaInfo.getHiveSchemaVersion(), newSchemaVersion); + assertCompatibleVersion(MetaStoreSchemaInfo.getHiveSchemaVersion(), newSchemaVersion); } - private void assertSameVersion(String hiveSchemaVersion, String dbSchemaVersion) + private void assertCompatibleVersion(String hiveSchemaVersion, String dbSchemaVersion) throws HiveMetaException { - if (!hiveSchemaVersion.equalsIgnoreCase(dbSchemaVersion)) { - throw new HiveMetaException("Expected schema version " + hiveSchemaVersion - + ", found version " + dbSchemaVersion); - } + if (!MetaStoreSchemaInfo.isVersionCompatible(hiveSchemaVersion, dbSchemaVersion)) { + throw new HiveMetaException("Metastore schema version is not compatible. Hive Version: " + + hiveSchemaVersion + ", Database Schema Version: " + dbSchemaVersion); + } } /** diff --git a/metastore/src/java/org/apache/hadoop/hive/metastore/MetaStoreSchemaInfo.java b/metastore/src/java/org/apache/hadoop/hive/metastore/MetaStoreSchemaInfo.java index d72267d..98798e8 100644 --- a/metastore/src/java/org/apache/hadoop/hive/metastore/MetaStoreSchemaInfo.java +++ b/metastore/src/java/org/apache/hadoop/hive/metastore/MetaStoreSchemaInfo.java @@ -151,6 +151,10 @@ public static String getPreUpgradeScriptName(int index, String upgradeScriptName public static String getHiveSchemaVersion() { String hiveVersion = HiveVersionInfo.getShortVersion(); + return getEquivalentVersion(hiveVersion); + } + + private static String getEquivalentVersion(String hiveVersion) { // if there is an equivalent version, return that, else return this version String equivalentVersion = EQUIVALENT_VERSIONS.get(hiveVersion); if (equivalentVersion != null) { @@ -160,4 +164,44 @@ public static String getHiveSchemaVersion() { } } + /** + * A dbVersion is compatible with hive version if it is greater or equal to + * the hive version. This is result of the db schema upgrade design principles + * followed in hive project. + * + * @param hiveVersion + * version of hive software + * @param dbVersion + * version of metastore rdbms schema + * @return true if versions are compatible + */ + public static boolean isVersionCompatible(String hiveVersion, String dbVersion) { + hiveVersion = getEquivalentVersion(hiveVersion); + dbVersion = getEquivalentVersion(dbVersion); + if (hiveVersion.equals(dbVersion)) { + return true; + } + String[] hiveVerParts = hiveVersion.split("\\."); + String[] dbVerParts = dbVersion.split("\\."); + if (hiveVerParts.length != 3 || dbVerParts.length != 3) { + // these are non standard version numbers. can't perform the + // comparison on these, so assume that they are incompatible + return false; + } + + for (int i = 0; i < dbVerParts.length; i++) { + Integer dbVerPart = Integer.valueOf(dbVerParts[i]); + Integer hiveVerPart = Integer.valueOf(hiveVerParts[i]); + if (dbVerPart > hiveVerPart) { + return true; + } else if (dbVerPart < hiveVerPart) { + return false; + } else { + continue; // compare next part + } + } + + return true; + } + } diff --git a/metastore/src/test/org/apache/hadoop/hive/metastore/TestMetaStoreSchemaInfo.java b/metastore/src/test/org/apache/hadoop/hive/metastore/TestMetaStoreSchemaInfo.java new file mode 100644 index 0000000..7142001 --- /dev/null +++ b/metastore/src/test/org/apache/hadoop/hive/metastore/TestMetaStoreSchemaInfo.java @@ -0,0 +1,49 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hadoop.hive.metastore; + +import org.junit.Assert; +import org.junit.Test; + +/** + * Test MetaStoreSchemaInfo + */ +public class TestMetaStoreSchemaInfo { + + @Test + public void testIsVersionCompatible() throws Exception { + // first argument is hiveVersion, it is compatible if 2nd argument - dbVersion is + // greater than or equal to it + // check the compatible case + Assert.assertTrue(MetaStoreSchemaInfo.isVersionCompatible("0.0.1", "0.0.1")); + Assert.assertTrue(MetaStoreSchemaInfo.isVersionCompatible("0.0.1", "0.0.2")); + Assert.assertTrue(MetaStoreSchemaInfo.isVersionCompatible("1.0.2", "2.0.1")); + Assert.assertTrue(MetaStoreSchemaInfo.isVersionCompatible("0.0.9", "9.0.0")); + + // check equivalent versions, should be compatible + Assert.assertTrue(MetaStoreSchemaInfo.isVersionCompatible("0.13.0", "0.13.1")); + Assert.assertTrue(MetaStoreSchemaInfo.isVersionCompatible("0.13.1", "0.13.0")); + + // check incompatible versions + Assert.assertFalse(MetaStoreSchemaInfo.isVersionCompatible("0.1.1", "0.1.0")); + Assert.assertFalse(MetaStoreSchemaInfo.isVersionCompatible("4.0.1", "0.1.0")); + + } + +}