diff --git a/beeline/src/java/org/apache/hive/beeline/HiveSchemaTool.java b/beeline/src/java/org/apache/hive/beeline/HiveSchemaTool.java index 36d2b9f..06929c6 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,16 +179,16 @@ 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 50d03a8..7f79921 100644 --- a/metastore/src/java/org/apache/hadoop/hive/metastore/MetaStoreSchemaInfo.java +++ b/metastore/src/java/org/apache/hadoop/hive/metastore/MetaStoreSchemaInfo.java @@ -145,6 +145,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) { @@ -154,4 +158,45 @@ 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; + } + + } \ No newline at end of file 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")); + + } + +} diff --git a/ql/src/test/queries/clientnegative/authorization_import.q b/ql/src/test/queries/clientnegative/authorization_import.q new file mode 100644 index 0000000..9d7cda1 --- /dev/null +++ b/ql/src/test/queries/clientnegative/authorization_import.q @@ -0,0 +1,40 @@ +set hive.test.authz.sstd.hs2.mode=true; +set hive.security.authorization.manager=org.apache.hadoop.hive.ql.security.authorization.plugin.sqlstd.SQLStdHiveAuthorizerFactoryForTest; +set hive.security.authenticator.manager=org.apache.hadoop.hive.ql.security.SessionStateConfigUserAuthenticator; +set hive.security.authorization.enabled=true; + +set hive.test.mode=true; +set hive.test.mode.prefix=; +set hive.test.mode.nosamplelist=import_auth_t1,import_auth_t2,import_auth_t3; + +drop table if exists import_auth_t1; +create table import_auth_t1 ( dep_id int comment "department id") stored as textfile; +dfs ${system:test.dfs.mkdir} target/tmp/ql/test/data/exports/import_auth_t1/temp; +dfs -rmr target/tmp/ql/test/data/exports/import_auth_t1; + +export table import_auth_t1 to 'ql/test/data/exports/import_auth_t1'; + +dfs -touchz target/tmp/ql/test/data/exports/import_auth_t1/1.txt; +dfs -chmod 777 target/tmp/ql/test/data/exports/import_auth_t1/1.txt; +dfs -chmod 777 target/tmp/ql/test/data/exports/import_auth_t1; + +dfs ${system:test.dfs.mkdir} target/tmp/ql/test/data/exports/import_auth_t2/temp; + +set user.name=hive_admin_user; +set role admin; +-- revoke insert on database importer from user hive_test_user; + + +create database importer; +use importer; + +show roles; + +set user.name=hive_test_user; +set role public; + +explain create table import_auth_t3 (dep_id int comment "department id") stored as textfile; +import table import_auth_t2 from 'ql/test/data/exports/import_auth_t1'; + +set user.name=hive_admin_user; +set role admin;