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/05 13:56:17 UTC

[GitHub] [calcite] dhirenda-gautam opened a new pull request #1785: [CALCITE-3771] TRIM Support for HIVE/SPARK Dialect

dhirenda-gautam opened a new pull request #1785: [CALCITE-3771] TRIM Support for HIVE/SPARK Dialect
URL: https://github.com/apache/calcite/pull/1785
 
 
   In current Calcite implementation for query : SELECT TRIM('ABC') for SPARK Dialect it gets translated into SELECT TRIM(BOTH ' ' FROM 'ABC') .
   
   But the proper query for SPARK is :: SELECT TRIM('ABC')
   
   Unparse logic for the trim has been handled in Spark dialect to convert the source Trim query into valid SPARK query.
   
   
   
   Also,In HIVE/SPARK dialect TRIM with two operand is not supported
   
   Eg: SELECT TRIM(BOTH 'a' from 'ABC') So its equivalent is REGEXP_REPLACE which is handle in unparseTrim function.

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

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

Posted by GitBox <gi...@apache.org>.
danny0405 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_r381056146
 
 

 ##########
 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:
   Some check-style, no worries, i would fix that.

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

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

Posted by GitBox <gi...@apache.org>.
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_r380432190
 
 

 ##########
 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:
   @danny0405 what rework is required in this PR?

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

[GitHub] [calcite] XuQianJin-Stars commented on issue #1785: [CALCITE-3771] TRIM Support for HIVE/SPARK Dialect

Posted by GitBox <gi...@apache.org>.
XuQianJin-Stars commented on issue #1785: [CALCITE-3771] TRIM Support for HIVE/SPARK Dialect
URL: https://github.com/apache/calcite/pull/1785#issuecomment-583216663
 
 
   +1 LGTM

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

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

Posted by GitBox <gi...@apache.org>.
danny0405 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_r376683732
 
 

 ##########
 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:
   There is no common tool class now, maybe we can add a new one named `RelToSqlConverterUtil`

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

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

Posted by GitBox <gi...@apache.org>.
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

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

Posted by GitBox <gi...@apache.org>.
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_r378260941
 
 

 ##########
 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:
   @danny0405 I have moved the common code to a new class RelToSqlConverterUtil

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

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

Posted by GitBox <gi...@apache.org>.
danny0405 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_r376203556
 
 

 ##########
 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:
   Can we try to reuse these codes ? i.e. move to a tool class

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

[GitHub] [calcite] danny0405 closed pull request #1785: [CALCITE-3771] TRIM Support for HIVE/SPARK Dialect

Posted by GitBox <gi...@apache.org>.
danny0405 closed pull request #1785: [CALCITE-3771] TRIM Support for HIVE/SPARK Dialect
URL: https://github.com/apache/calcite/pull/1785
 
 
   

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