Skip to content

Commit

Permalink
Support SQLServer trim function parse (apache#29162)
Browse files Browse the repository at this point in the history
  • Loading branch information
venkatdatta0 committed Dec 25, 2023
1 parent a36b614 commit 0da92cd
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ distinct
;

specialFunction
: castFunction | charFunction | convertFunction
: castFunction | charFunction | convertFunction | trimFunction
;

castFunction
Expand All @@ -317,6 +317,11 @@ convertFunction
: CONVERT LP_ dataType COMMA_ expr (COMMA_ NUMBER_)? RP_
;

trimFunction
: TRIM LP_ ((LEADING | BOTH | TRAILING) expr? FROM)? expr RP_
| TRIM LP_ (expr FROM)? expr RP_
;

charFunction
: CHAR LP_ expr (COMMA_ expr)* (USING ignoredIdentifier)? RP_
;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -692,3 +692,15 @@ WITHOUT
: W I T H O U T
;

LEADING
: L E A D I N G
;

BOTH
: B O T H
;

TRAILING
: T R A I L I N G
;

Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.antlr.v4.runtime.tree.TerminalNode;
import org.apache.shardingsphere.sql.parser.api.ASTNode;
import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementBaseVisitor;
import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser;
import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.AggregationClauseContext;
import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.AggregationFunctionContext;
import org.apache.shardingsphere.sql.parser.autogen.SQLServerStatementParser.AliasContext;
Expand Down Expand Up @@ -632,6 +633,9 @@ public final ASTNode visitSpecialFunction(final SpecialFunctionContext ctx) {
if (null != ctx.charFunction()) {
return visit(ctx.charFunction());
}
if (null != ctx.trimFunction()) {
return visit(ctx.trimFunction());
}
return new FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.getChild(0).getChild(0).getText(), getOriginalText(ctx));
}

Expand Down Expand Up @@ -659,7 +663,28 @@ public ASTNode visitConvertFunction(final ConvertFunctionContext ctx) {
}
return result;
}


@Override
public ASTNode visitTrimFunction(SQLServerStatementParser.TrimFunctionContext ctx) {
FunctionSegment result = new FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.TRIM().getText(), getOriginalText(ctx));
if (null != ctx.BOTH()) {
result.getParameters().add(new LiteralExpressionSegment(ctx.BOTH().getSymbol().getStartIndex(), ctx.BOTH().getSymbol().getStopIndex(),
new OtherLiteralValue(ctx.BOTH().getSymbol().getText()).getValue()));
}
if (null != ctx.TRAILING()) {
result.getParameters().add(new LiteralExpressionSegment(ctx.TRAILING().getSymbol().getStartIndex(), ctx.TRAILING().getSymbol().getStopIndex(),
new OtherLiteralValue(ctx.TRAILING().getSymbol().getText()).getValue()));
}
if (null != ctx.LEADING()) {
result.getParameters().add(new LiteralExpressionSegment(ctx.LEADING().getSymbol().getStartIndex(), ctx.LEADING().getSymbol().getStopIndex(),
new OtherLiteralValue(ctx.LEADING().getSymbol().getText()).getValue()));
}
for (ExprContext each : ctx.expr()) {
result.getParameters().add((ExpressionSegment) visit(each));
}
return result;
}

@Override
public final ASTNode visitCharFunction(final CharFunctionContext ctx) {
calculateParameterCount(ctx.expr());
Expand Down
79 changes: 78 additions & 1 deletion test/it/parser/src/main/resources/case/dml/select.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6410,7 +6410,7 @@
</order-by>
</select>

<select sql-case-id="select_with_trim_function">
<select sql-case-id="select_with_trim_function1">
<projections start-index="7" stop-index="203" literal-start-index="7" literal-stop-index="203">
<expression-projection text="TRIM(' derby ')" start-index="7" stop-index="22" literal-start-index="7" literal-stop-index="22">
<literalText>TRIM(' derby ')</literalText>
Expand Down Expand Up @@ -6492,6 +6492,83 @@
</from>
</select>

<select sql-case-id="select_with_trim_function2">
<projections start-index="7" stop-index="56">
<expression-projection text="TRIM('.,! ' FROM ' # test .')" start-index="7" stop-index="56" alias="Result">
<expr>
<function function-name="TRIM" start-index="7" stop-index="46" text="TRIM('.,! ' FROM ' # test .')">
<parameter>
<literal-expression value=".,! " start-index="12" stop-index="17" />
</parameter>
<parameter>
<literal-expression value=" # test ." start-index="24" stop-index="45" />
</parameter>
</function>
</expr>
</expression-projection>
</projections>
</select>

<select sql-case-id="select_with_trim_function3">
<projections start-index="7" stop-index="66">
<expression-projection text="TRIM(LEADING '.,! ' FROM ' .# test .')" start-index="7" stop-index="66" alias="Result">
<expr>
<function function-name="TRIM" start-index="7" stop-index="56" text="TRIM(LEADING '.,! ' FROM ' .# test .')">
<parameter>
<literal-expression value="LEADING" start-index="12" stop-index="18" />
</parameter>
<parameter>
<literal-expression value=".,! " start-index="20" stop-index="25" />
</parameter>
<parameter>
<literal-expression value=" .# test ." start-index="33" stop-index="55" />
</parameter>
</function>
</expr>
</expression-projection>
</projections>
</select>

<select sql-case-id="select_with_trim_function4">
<projections start-index="7" stop-index="66">
<expression-projection text="TRIM(TRAILING '.,! ' FROM ' .# test .')" start-index="7" stop-index="66" alias="Result">
<expr>
<function function-name="TRIM" start-index="7" stop-index="56" text="TRIM(TRAILING '.,! ' FROM ' .# test .')">
<parameter>
<literal-expression value="TRAILING" start-index="12" stop-index="19" />
</parameter>
<parameter>
<literal-expression value=".,! " start-index="21" stop-index="26" />
</parameter>
<parameter>
<literal-expression value=" .# test ." start-index="33" stop-index="55" />
</parameter>
</function>
</expr>
</expression-projection>
</projections>
</select>

<select sql-case-id="select_with_trim_function5">
<projections start-index="7" stop-index="49">
<expression-projection text="TRIM(BOTH '123' FROM '123abc123')" start-index="7" stop-index="49" alias="Result">
<expr>
<function function-name="TRIM" start-index="7" stop-index="39" text="TRIM(BOTH '123' FROM '123abc123')">
<parameter>
<literal-expression value="BOTH" start-index="12" stop-index="15" />
</parameter>
<parameter>
<literal-expression value="123" start-index="17" stop-index="21" />
</parameter>
<parameter>
<literal-expression value="123abc123" start-index="28" stop-index="38" />
</parameter>
</function>
</expr>
</expression-projection>
</projections>
</select>

<select sql-case-id="select_with_ratio_to_report_function">
<projections start-index="7" stop-index="79" literal-start-index="7" literal-stop-index="79">
<expression-projection text="TO_CHAR(RATIO_TO_REPORT(amount_sold) OVER (), '9.999')" alias="RATIO_TO_REPORT" start-index="7" stop-index="79" literal-start-index="7" literal-stop-index="79">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,11 @@
<sql-case id="select_with_percentile_functions" value="SELECT department_id, PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY salary DESC) 'Median cont', PERCENTILE_DISC(0.5) WITHIN GROUP (ORDER BY salary DESC) 'Median disc' FROM employees GROUP BY department_id" db-types="Oracle" />
<sql-case id="select_with_keep_clause" value="SELECT salary,MIN(salary) KEEP (DENSE_RANK FIRST ORDER BY commission_pct) OVER (PARTITION BY department_id) 'Worst', MAX(salary) KEEP (DENSE_RANK LAST ORDER BY commission_pct) OVER (PARTITION BY department_id) 'Best' FROM employees ORDER BY department_id" db-types="Oracle" />
<sql-case id="select_with_corr_function" value="SELECT employee_id, CORR(SYSDATE - hire_date, salary) FROM employees WHERE department_id in (50, 80) ORDER BY employee_id" db-types="Oracle" />
<sql-case id="select_with_trim_function" value="select TRIM(' derby '), TRIM(BOTH ' ' FROM ' derby '), TRIM(TRAILING ' ' FROM ' derby '), TRIM(cast (null as char(1)) FROM ' derby '), TRIM(' ' FROM cast(null as varchar(30))), TRIM('y' FROM ' derby') FROM employees" db-types="Oracle" />
<sql-case id="select_with_trim_function1" value="select TRIM(' derby '), TRIM(BOTH ' ' FROM ' derby '), TRIM(TRAILING ' ' FROM ' derby '), TRIM(cast (null as char(1)) FROM ' derby '), TRIM(' ' FROM cast(null as varchar(30))), TRIM('y' FROM ' derby') FROM employees" db-types="Oracle" />
<sql-case id="select_with_trim_function2" value="SELECT TRIM('.,! ' FROM ' # test .') AS Result" db-types="SQLServer" />
<sql-case id="select_with_trim_function3" value="SELECT TRIM(LEADING '.,! ' FROM ' .# test .') AS Result" db-types="SQLServer" />
<sql-case id="select_with_trim_function4" value="SELECT TRIM(TRAILING '.,! ' FROM ' .# test .') AS Result" db-types="SQLServer" />
<sql-case id="select_with_trim_function5" value="SELECT TRIM(BOTH '123' FROM '123abc123') AS Result" db-types="SQLServer" />
<sql-case id="select_with_ratio_to_report_function" value="SELECT TO_CHAR(RATIO_TO_REPORT(amount_sold) OVER (), '9.999') AS RATIO_TO_REPORT FROM sales s GROUP BY s.channel_desc" db-types="Oracle" />
<sql-case id="select_with_sys_xmlagg_and_xmlgen" value="SELECT SYS_XMLAGG(last_name) a, SYS_XMLGEN(last_name) b FROM employees WHERE last_name LIKE 'R%' ORDER BY xmlagg;" db-types="Oracle" />
<sql-case id="select_with_cover_pop_and_covar_samp" value="SELECT product_id, supplier_id, COVAR_POP(list_price, min_price) OVER (ORDER BY product_id, supplier_id) AS CUM_COVP, COVAR_SAMP(list_price, min_price) OVER (ORDER BY product_id, supplier_id) AS CUM_COVS FROM product_information p WHERE category_id = 29 ORDER BY product_id, supplier_id" db-types="Oracle" />
Expand Down

0 comments on commit 0da92cd

Please sign in to comment.