commit b8d7c152f5c133a0715bb7a8169482e4dbb302e0 Author: Vihang Karajgaonkar Date: Mon Mar 13 13:26:28 2017 -0700 HIVE-16205 : Improving type safety in Objectstore 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..afcb940f7ebf15c05637a3a4a0f8cf3e4dd3cd3e 100644 --- a/metastore/src/java/org/apache/hadoop/hive/metastore/ObjectStore.java +++ b/metastore/src/java/org/apache/hadoop/hive/metastore/ObjectStore.java @@ -837,21 +837,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 +1202,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 && !pattern.isEmpty()) { + 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 +1281,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 +1313,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 +1340,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(":param").append(parameters.size()).append(")"); } else { - builder.append(" == \"").append(element).append("\""); + builder.append(" == ").append(":param").append(parameters.size()); } } builder.append(" )"); @@ -8227,25 +8219,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 && !pattern.isEmpty()) { + 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());