commit 0dc967613ab5f0e240606d7d3bfc8684b88a9eac Author: Vihang Karajgaonkar Date: Mon Mar 13 13:26:28 2017 -0700 HIVE-16205 : Improving type safety in Objectstore diff --git a/itests/hive-unit/src/test/java/org/apache/hive/jdbc/TestJdbcDriver2.java b/itests/hive-unit/src/test/java/org/apache/hive/jdbc/TestJdbcDriver2.java index 4a82aa5fbdc588c74b82b05774f866b0cc52ec02..35aad6da1e97f1070bb23c843874fbfdc91f37d9 100644 --- a/itests/hive-unit/src/test/java/org/apache/hive/jdbc/TestJdbcDriver2.java +++ b/itests/hive-unit/src/test/java/org/apache/hive/jdbc/TestJdbcDriver2.java @@ -1083,6 +1083,45 @@ public void testShowTables() throws SQLException { } @Test + public void testShowTablesInDb() throws SQLException { + Statement stmt = con.createStatement(); + assertNotNull("Statement is null", stmt); + + String tableNameInDbUnique = tableName + "_unique"; + // create a table with a unique name in testDb + stmt.execute("drop table if exists " + testDbName + "." + tableNameInDbUnique); + stmt.execute("create table " + testDbName + "." + tableNameInDbUnique + + " (under_col int comment 'the under column', value string) comment '" + tableComment + + "'"); + + ResultSet res = stmt.executeQuery("show tables in " + testDbName); + + boolean testTableExists = false; + while (res.next()) { + assertNotNull("table name is null in result set", res.getString(1)); + if (tableNameInDbUnique.equalsIgnoreCase(res.getString(1))) { + testTableExists = true; + } + } + assertTrue("table name " + tableNameInDbUnique + + " not found in SHOW TABLES result set", testTableExists); + stmt.execute("drop table if exists " + testDbName + "." + tableNameInDbUnique); + stmt.close(); + } + + @Test + public void testInvalidShowTables() throws SQLException { + Statement stmt = con.createStatement(); + assertNotNull("Statement is null", stmt); + + //show tables is in invalid show tables syntax. Hive does not return + //any tables in this case + ResultSet res = stmt.executeQuery("show tables " + testDbName); + assertFalse(res.next()); + stmt.close(); + } + + @Test public void testMetaDataGetTables() throws SQLException { getTablesTest(ImmutableSet.of(ClassicTableTypes.TABLE.toString()), ClassicTableTypes.VIEW.toString()); diff --git a/metastore/src/java/org/apache/hadoop/hive/metastore/ObjectStore.java b/metastore/src/java/org/apache/hadoop/hive/metastore/ObjectStore.java index c3f2e997d923b7e2610c62072cc95f10d0e44ca0..aa0fdbbbe19868bbf6acbd9b323f3e2608849520 100644 --- a/metastore/src/java/org/apache/hadoop/hive/metastore/ObjectStore.java +++ b/metastore/src/java/org/apache/hadoop/hive/metastore/ObjectStore.java @@ -191,6 +191,7 @@ private static final Map PINCLASSMAP; private static final String HOSTNAME; private static final String USER; + private static final String JDO_PARAM = ":param"; static { Map map = new HashMap(); map.put("table", MTable.class); @@ -837,21 +838,13 @@ public boolean dropDatabase(String dbname) throws NoSuchObjectException, MetaExc // Take the pattern and split it on the | to get all the composing // patterns String[] subpatterns = pattern.trim().split("\\|"); - String queryStr = "select name from org.apache.hadoop.hive.metastore.model.MDatabase where ("; - boolean first = true; - for (String subpattern : subpatterns) { - subpattern = "(?i)" + subpattern.replaceAll("\\*", ".*"); - if (!first) { - queryStr = queryStr + " || "; - } - queryStr = queryStr + " name.matches(\"" + subpattern + "\")"; - first = false; - } - queryStr = queryStr + ")"; - query = pm.newQuery(queryStr); + StringBuilder filterBuilder = new StringBuilder(); + List parameterVals = new ArrayList<>(subpatterns.length); + appendPatternCondition(filterBuilder, "name", subpatterns, parameterVals); + query = pm.newQuery(MDatabase.class, filterBuilder.toString()); query.setResult("name"); query.setOrdering("name ascending"); - Collection names = (Collection) query.execute(); + Collection names = (Collection) query.executeWithArray(parameterVals.toArray(new String[parameterVals.size()])); databases = new ArrayList(); for (Iterator i = names.iterator(); i.hasNext();) { databases.add((String) i.next()); @@ -1210,28 +1203,21 @@ public Table getTable(String dbName, String tableName) throws MetaException { dbName = HiveStringUtils.normalizeIdentifier(dbName); // Take the pattern and split it on the | to get all the composing // patterns - String[] subpatterns = pattern.trim().split("\\|"); - String queryStr = - "select tableName from org.apache.hadoop.hive.metastore.model.MTable " - + "where database.name == dbName && ("; - boolean first = true; - for (String subpattern : subpatterns) { - subpattern = "(?i)" + subpattern.replaceAll("\\*", ".*"); - if (!first) { - queryStr = queryStr + " || "; - } - queryStr = queryStr + " tableName.matches(\"" + subpattern + "\")"; - first = false; + List parameterVals = new ArrayList<>(); + StringBuilder filterBuilder = new StringBuilder(); + //adds database.name == dbName to the filter + appendSimpleCondition(filterBuilder, "database.name", new String[] {dbName}, parameterVals); + if(pattern != null) { + appendPatternCondition(filterBuilder, "tableName", pattern, parameterVals); } - queryStr = queryStr + ")"; - if (tableType != null) { - queryStr = queryStr + " && tableType.matches(\"" + tableType.toString() + "\")"; + if(tableType != null) { + appendPatternCondition(filterBuilder, "tableType", new String[] {tableType.toString()}, parameterVals); } - query = pm.newQuery(queryStr); - query.declareParameters("java.lang.String dbName"); + + query = pm.newQuery(MTable.class, filterBuilder.toString()); query.setResult("tableName"); query.setOrdering("tableName ascending"); - Collection names = (Collection) query.execute(dbName); + Collection names = (Collection) query.executeWithArray(parameterVals.toArray(new String[parameterVals.size()])); tbls = new ArrayList(); for (Iterator i = names.iterator(); i.hasNext();) { tbls.add((String) i.next()); @@ -1296,19 +1282,20 @@ private int getObjectCount(String fieldName, String objName) { openTransaction(); // Take the pattern and split it on the | to get all the composing // patterns - StringBuilder builder = new StringBuilder(); + StringBuilder filterBuilder = new StringBuilder(); + List parameterVals = new ArrayList<>(); if (dbNames != null && !dbNames.equals("*")) { - appendPatternCondition(builder, "database.name", dbNames); + appendPatternCondition(filterBuilder, "database.name", dbNames, parameterVals); } if (tableNames != null && !tableNames.equals("*")) { - appendPatternCondition(builder, "tableName", tableNames); + appendPatternCondition(filterBuilder, "tableName", tableNames, parameterVals); } if (tableTypes != null && !tableTypes.isEmpty()) { - appendSimpleCondition(builder, "tableType", tableTypes.toArray(new String[0])); + appendSimpleCondition(filterBuilder, "tableType", tableTypes.toArray(new String[0]), parameterVals); } - query = pm.newQuery(MTable.class, builder.toString()); - Collection tables = (Collection) query.execute(); + query = pm.newQuery(MTable.class, filterBuilder.toString()); + Collection tables = (Collection) query.executeWithArray(parameterVals.toArray(new String[parameterVals.size()])); for (MTable table : tables) { TableMeta metaData = new TableMeta( table.getDatabase().getName(), table.getTableName(), table.getTableType()); @@ -1327,19 +1314,24 @@ private int getObjectCount(String fieldName, String objName) { return metas; } + private StringBuilder appendPatternCondition(StringBuilder filterBuilder, String fieldName, + String[] elements, List parameterVals) { + return appendCondition(filterBuilder, fieldName, elements, true, parameterVals); + } + private StringBuilder appendPatternCondition(StringBuilder builder, - String fieldName, String elements) { + String fieldName, String elements, List parameters) { elements = HiveStringUtils.normalizeIdentifier(elements); - return appendCondition(builder, fieldName, elements.split("\\|"), true); + return appendCondition(builder, fieldName, elements.split("\\|"), true, parameters); } private StringBuilder appendSimpleCondition(StringBuilder builder, - String fieldName, String[] elements) { - return appendCondition(builder, fieldName, elements, false); + String fieldName, String[] elements, List parameters) { + return appendCondition(builder, fieldName, elements, false, parameters); } private StringBuilder appendCondition(StringBuilder builder, - String fieldName, String[] elements, boolean pattern) { + String fieldName, String[] elements, boolean pattern, List parameters) { if (builder.length() > 0) { builder.append(" && "); } @@ -1349,14 +1341,15 @@ private StringBuilder appendCondition(StringBuilder builder, if (pattern) { element = "(?i)" + element.replaceAll("\\*", ".*"); } + parameters.add(element); if (builder.length() > length) { builder.append(" || "); } builder.append(fieldName); if (pattern) { - builder.append(".matches(\"").append(element).append("\")"); + builder.append(".matches(").append(JDO_PARAM).append(parameters.size()).append(")"); } else { - builder.append(" == \"").append(element).append("\""); + builder.append(" == ").append(JDO_PARAM).append(parameters.size()); } } builder.append(" )"); @@ -8227,25 +8220,16 @@ public Function getFunction(String dbName, String funcName) throws MetaException dbName = HiveStringUtils.normalizeIdentifier(dbName); // Take the pattern and split it on the | to get all the composing // patterns - String[] subpatterns = pattern.trim().split("\\|"); - String queryStr = - "select functionName from org.apache.hadoop.hive.metastore.model.MFunction " - + "where database.name == dbName && ("; - boolean first = true; - for (String subpattern : subpatterns) { - subpattern = "(?i)" + subpattern.replaceAll("\\*", ".*"); - if (!first) { - queryStr = queryStr + " || "; - } - queryStr = queryStr + " functionName.matches(\"" + subpattern + "\")"; - first = false; + List parameterVals = new ArrayList<>(); + StringBuilder filterBuilder = new StringBuilder(); + appendSimpleCondition(filterBuilder, "database.name", new String[] { dbName }, parameterVals); + if(pattern != null) { + appendPatternCondition(filterBuilder, "functionName", pattern, parameterVals); } - queryStr = queryStr + ")"; - query = pm.newQuery(queryStr); - query.declareParameters("java.lang.String dbName"); + query = pm.newQuery(MFunction.class, filterBuilder.toString()); query.setResult("functionName"); query.setOrdering("functionName ascending"); - Collection names = (Collection) query.execute(dbName); + Collection names = (Collection) query.executeWithArray(parameterVals.toArray(new String[parameterVals.size()])); funcs = new ArrayList(); for (Iterator i = names.iterator(); i.hasNext();) { funcs.add((String) i.next());