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);