You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by GitBox <gi...@apache.org> on 2020/02/07 14:58:25 UTC

[GitHub] [calcite] dhirenda-gautam commented on a change in pull request #1785: [CALCITE-3771] TRIM Support for HIVE/SPARK Dialect

dhirenda-gautam commented on a change in pull request #1785: [CALCITE-3771] TRIM Support for HIVE/SPARK Dialect
URL: https://github.com/apache/calcite/pull/1785#discussion_r376434164
 
 

 ##########
 File path: core/src/main/java/org/apache/calcite/sql/dialect/SparkSqlDialect.java
 ##########
 @@ -102,10 +108,121 @@ public SparkSqlDialect(SqlDialect.Context context) {
             timeUnitNode.getParserPosition());
         SqlFloorFunction.unparseDatetimeFunction(writer, call2, "DATE_TRUNC", false);
         break;
-
+      case TRIM:
+        unparseTrim(writer, call, leftPrec, rightPrec);
+        break;
       default:
         super.unparseCall(writer, call, leftPrec, rightPrec);
       }
     }
   }
+
+  /**
+   * For usage of TRIM, LTRIM and RTRIM in Spark
+   */
+  private void unparseTrim(
+      SqlWriter writer, SqlCall call, int leftPrec,
+      int rightPrec) {
+    SqlLiteral valueToBeTrim = call.operand(1);
+    if (valueToBeTrim.toValue().matches("\\s+")) {
+      handleTrimWithSpace(writer, call, leftPrec, rightPrec);
+    } else {
+      handleTrimWithChar(writer, call, leftPrec, rightPrec);
+    }
+  }
+
+  /**
+   * This method will handle the TRIM function if the value to be trimmed is space
+   * Below is an example :
+   * INPUT : SELECT TRIM(both ' ' from "ABC")
+   * OUPUT : SELECT TRIM(ABC)
+   * @param writer Target SqlWriter to write the call
+   * @param call SqlCall
+   * @param leftPrec Indicate left precision
+   * @param rightPrec Indicate Right precision
+   */
+  private void handleTrimWithSpace(
+      SqlWriter writer, SqlCall call, int leftPrec, int rightPrec) {
+    final String operatorName;
+    SqlLiteral trimFlag = call.operand(0);
+    switch (trimFlag.getValueAs(SqlTrimFunction.Flag.class)) {
+    case LEADING:
+      operatorName = "LTRIM";
+      break;
+    case TRAILING:
+      operatorName = "RTRIM";
+      break;
+    default:
+      operatorName = call.getOperator().getName();
+      break;
+    }
+    final SqlWriter.Frame trimFrame = writer.startFunCall(operatorName);
+    call.operand(2).unparse(writer, leftPrec, rightPrec);
+    writer.endFunCall(trimFrame);
+  }
+
+  /**
+   * This method will handle the TRIM function if the value to be trimmed is not space
+   * Below is an example :
+   * INPUT : SELECT TRIM(both 'A' from "ABC")
+   * OUPUT : SELECT REGEXP_REPLACE("ABC", '^(A)*', '')
+   * @param writer Target SqlWriter to write the call
+   * @param call SqlCall
+   * @param leftPrec Indicate left precision
+   * @param rightPrec Indicate Right precision
+   */
+  private void handleTrimWithChar(
+      SqlWriter writer, SqlCall call, int leftPrec, int rightPrec) {
+    SqlLiteral trimFlag = call.operand(0);
+    SqlCharStringLiteral regexNode = makeRegexNodeFromCall(call.operand(1), trimFlag);
+    SqlCharStringLiteral blankLiteral = SqlLiteral.createCharString("",
+        call.getParserPosition());
+    SqlNode[] trimOperands = new SqlNode[]{call.operand(2), regexNode, blankLiteral};
+    SqlCall regexReplaceCall = new SqlBasicCall(REGEXP_REPLACE, trimOperands, SqlParserPos.ZERO);
+    REGEXP_REPLACE.unparse(writer, regexReplaceCall, leftPrec, rightPrec);
+  }
+
+  /**
+   * This method will make regex pattern based on the TRIM flag
+   *
+   * @param call SqlCall contains the values that needs to be trimmed
+   * @param trimFlag It will contain the trimFlag either BOTH,LEADING or TRAILING
+   * @return It will return the regex pattern of the character to be trimmed.
+   */
+  private SqlCharStringLiteral makeRegexNodeFromCall(SqlNode call, SqlLiteral trimFlag) {
+    String regexPattern = ((SqlCharStringLiteral) call).toValue();
+    regexPattern = escapeSpecialChar(regexPattern);
+    switch (trimFlag.getValueAs(SqlTrimFunction.Flag.class)) {
+    case LEADING:
+      regexPattern = "^(".concat(regexPattern).concat(")*");
+      break;
+    case TRAILING:
+      regexPattern = "(".concat(regexPattern).concat(")*$");
+      break;
+    default:
 
 Review comment:
   Hi @danny0405 please suggest shall I create a new class to handle this or is there any existing class to handle the dialects common unparse logic.

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services