You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hive.apache.org by pa...@apache.org on 2011/05/10 08:52:35 UTC
svn commit: r1101340 - in /hive/trunk/ql/src/java/org/apache/hadoop/hive/ql:
exec/Utilities.java stats/jdbc/JDBCStatsAggregator.java
Author: pauly
Date: Tue May 10 06:52:35 2011
New Revision: 1101340
URL: http://svn.apache.org/viewvc?rev=1101340&view=rev
Log:
HIVE-2153. Stats JDBC LIKE queries should escape '_' and '%' (Ning Zhang via pauly)
Modified:
hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/Utilities.java
hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/stats/jdbc/JDBCStatsAggregator.java
Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/Utilities.java
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/Utilities.java?rev=1101340&r1=1101339&r2=1101340&view=diff
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/Utilities.java (original)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/Utilities.java Tue May 10 06:52:35 2011
@@ -2014,12 +2014,12 @@ public final class Utilities {
* all input formats, and choose the ones that extend ReworkMapredInputFormat
* to a set. And finally go through the ReworkMapredInputFormat set, and call
* rework for each one.
- *
+ *
* Technically all these can be avoided if all Hive's input formats can share
* a same interface. As in today's hive and Hadoop, it is not possible because
* a lot of Hive's input formats are in Hadoop's code. And most of Hadoop's
* input formats just extend InputFormat interface.
- *
+ *
* @param task
* @param reworkMapredWork
* @param conf
@@ -2203,4 +2203,28 @@ public final class Utilities {
baseWindow * failures + // grace period for the last round of attempt
baseWindow * (failures + 1) * r.nextDouble()); // expanding time window for each failure
}
+
+ /**
+ * Escape the '_', '%', as well as the escape characters inside the string key.
+ * @param key the string that will be used for the SQL LIKE operator.
+ * @param escape the escape character
+ * @return a string with escaped '_' and '%'.
+ */
+ public static final char sqlEscapeChar = '\\';
+ public static String escapeSqlLike(String key) {
+ StringBuffer sb = new StringBuffer(key.length());
+ for (char c: key.toCharArray()) {
+ switch(c) {
+ case '_':
+ case '%':
+ case sqlEscapeChar:
+ sb.append(sqlEscapeChar);
+ // fall through
+ default:
+ sb.append(c);
+ break;
+ }
+ }
+ return sb.toString();
+ }
}
Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/stats/jdbc/JDBCStatsAggregator.java
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/stats/jdbc/JDBCStatsAggregator.java?rev=1101340&r1=1101339&r2=1101340&view=diff
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/stats/jdbc/JDBCStatsAggregator.java (original)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/stats/jdbc/JDBCStatsAggregator.java Tue May 10 06:52:35 2011
@@ -72,7 +72,8 @@ public class JDBCStatsAggregator impleme
"SELECT /* " + comment + " */ " +
" SUM(" + JDBCStatsSetupConstants.PART_STAT_ROW_COUNT_COLUMN_NAME + ")" +
" FROM " + JDBCStatsSetupConstants.PART_STAT_TABLE_NAME +
- " WHERE " + JDBCStatsSetupConstants.PART_STAT_ID_COLUMN_NAME + " LIKE ?";
+ " WHERE " + JDBCStatsSetupConstants.PART_STAT_ID_COLUMN_NAME +
+ " LIKE ? ESCAPE ?";
/* Automatic Cleaning:
IMPORTANT: Since we publish and aggregate only 1 value (1 column) which is the row count, it
@@ -85,7 +86,8 @@ public class JDBCStatsAggregator impleme
String delete =
"DELETE /* " + comment + " */ " +
" FROM " + JDBCStatsSetupConstants.PART_STAT_TABLE_NAME +
- " WHERE " + JDBCStatsSetupConstants.PART_STAT_ID_COLUMN_NAME + " LIKE ?";
+ " WHERE " + JDBCStatsSetupConstants.PART_STAT_ID_COLUMN_NAME +
+ " LIKE ? ESCAPE ?";
// stats is non-blocking -- throw an exception when timeout
DriverManager.setLoginTimeout(timeout);
@@ -156,12 +158,13 @@ public class JDBCStatsAggregator impleme
}
};
+ String keyPrefix = Utilities.escapeSqlLike(fileID) + "%";
for (int failures = 0; ; failures++) {
try {
long retval = 0;
- String keyPrefix = fileID + "%";
selStmt.setString(1, keyPrefix);
+ selStmt.setString(2, Character.toString(Utilities.sqlEscapeChar));
ResultSet result = Utilities.executeWithRetry(execQuery, selStmt, waitWindow, maxRetries);
if (result.next()) {
retval = result.getLong(1);
@@ -179,6 +182,7 @@ public class JDBCStatsAggregator impleme
through a separate method which the developer has to call it manually in the code.
*/
delStmt.setString(1, keyPrefix);
+ delStmt.setString(2, Character.toString(Utilities.sqlEscapeChar));
Utilities.executeWithRetry(execUpdate, delStmt, waitWindow, maxRetries);
LOG.info("Stats aggregator got " + retval);