This is an automated email from the ASF dual-hosted git repository. panjuan pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/shardingsphere.git
The following commit(s) were added to refs/heads/master by this push: new cc353e8 support postgresql pattern matching operator parse (#10270) cc353e8 is described below commit cc353e87f4e88124b3272ba1a0ae6c89c82797f3 Author: Zhengqiang Duan <strongdua...@gmail.com> AuthorDate: Fri May 7 19:37:41 2021 +0800 support postgresql pattern matching operator parse (#10270) * support postgresql pattern matching operator parse * fix test case exception --- .../statement/impl/OracleStatementSQLVisitor.java | 3 +- .../src/main/antlr4/imports/postgresql/BaseRule.g4 | 32 +++--- .../src/main/antlr4/imports/postgresql/Symbol.g4 | 2 + .../impl/PostgreSQLStatementSQLVisitor.java | 74 ++++++++++---- .../impl/SQLServerStatementSQLVisitor.java | 3 +- .../src/main/resources/case/dml/select.xml | 109 +++++---------------- .../main/resources/sql/supported/dml/select.xml | 5 +- 7 files changed, 103 insertions(+), 125 deletions(-) diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/impl/OracleStatementSQLVisitor.java b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/impl/OracleStatementSQLVisitor.java index 9095244..f86cfdd 100644 --- a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/impl/OracleStatementSQLVisitor.java +++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/impl/OracleStatementSQLVisitor.java @@ -466,7 +466,8 @@ public abstract class OracleStatementSQLVisitor extends OracleStatementBaseVisit @Override public final ASTNode visitRegularFunction(final RegularFunctionContext ctx) { calculateParameterCount(ctx.expr()); - return new ExpressionProjectionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.getText()); + String text = ctx.start.getInputStream().getText(new Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex())); + return new ExpressionProjectionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), text); } @Override diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-postgresql/src/main/antlr4/imports/postgresql/BaseRule.g4 b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-postgresql/src/main/antlr4/imports/postgresql/BaseRule.g4 index 681d561..2bf7428 100644 --- a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-postgresql/src/main/antlr4/imports/postgresql/BaseRule.g4 +++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-postgresql/src/main/antlr4/imports/postgresql/BaseRule.g4 @@ -504,6 +504,22 @@ comparisonOperator : EQ_ | GTE_ | GT_ | LTE_ | LT_ | NEQ_ ; +patternMatchingOperator + : LIKE + | TILDE_TILDE_ + | NOT LIKE + | NOT_TILDE_TILDE_ + | ILIKE + | ILIKE_ + | NOT ILIKE + | NOT_ILIKE_ + | SIMILAR TO + | NOT SIMILAR TO + | TILDE_ + | NOT_ TILDE_ + | TILDE_ ASTERISK_ + | NOT_ TILDE_ ASTERISK_ + ; cursorName : name @@ -527,18 +543,8 @@ aExpr | aExpr qualOp | aExpr comparisonOperator aExpr | NOT aExpr - | aExpr LIKE aExpr - | aExpr LIKE aExpr ESCAPE aExpr - | aExpr NOT LIKE aExpr - | aExpr NOT LIKE aExpr ESCAPE aExpr - | aExpr TILDE_ aExpr - | aExpr TILDE_ aExpr ESCAPE aExpr - | aExpr NOT_ TILDE_ aExpr - | aExpr NOT_ TILDE_ aExpr ESCAPE aExpr - | aExpr SIMILAR TO aExpr - | aExpr SIMILAR TO aExpr ESCAPE aExpr - | aExpr NOT SIMILAR TO aExpr - | aExpr NOT SIMILAR TO aExpr ESCAPE aExpr + | aExpr patternMatchingOperator aExpr + | aExpr patternMatchingOperator aExpr ESCAPE aExpr | aExpr IS NULL | aExpr ISNULL | aExpr IS NOT NULL @@ -658,8 +664,6 @@ columnref qualOp : jsonOperator - | TILDE_TILDE_ - | NOT_TILDE_TILDE_ | OPERATOR LP_ anyOperator RP_ ; diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-postgresql/src/main/antlr4/imports/postgresql/Symbol.g4 b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-postgresql/src/main/antlr4/imports/postgresql/Symbol.g4 index 7935e13..6d03f5e 100644 --- a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-postgresql/src/main/antlr4/imports/postgresql/Symbol.g4 +++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-postgresql/src/main/antlr4/imports/postgresql/Symbol.g4 @@ -61,6 +61,8 @@ SEMI_: ';'; TILDE_TILDE_: '~~'; NOT_TILDE_TILDE_: '!~~'; TYPE_CAST_: '::'; +ILIKE_: '~~*'; +NOT_ILIKE_: '!~~*'; JSON_EXTRACT_: '->'; JSON_EXTRACT_TEXT_: '->>'; JSON_PATH_EXTRACT_: '#>'; diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-postgresql/src/main/java/org/apache/shardingsphere/sql/parser/postgresql/visitor/statement/impl/PostgreSQLStatementSQLVisitor.java b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-postgresql/src/main/java/org/apache/shardingsphere/sql/parser/postgresql/visitor/statement/impl/PostgreSQLStatementSQLVisitor.java index 701d4b8..4b69acd 100644 --- a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-postgresql/src/main/java/org/apache/shardingsphere/sql/parser/postgresql/visitor/statement/impl/PostgreSQLStatementSQLVisitor.java +++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-postgresql/src/main/java/org/apache/shardingsphere/sql/parser/postgresql/visitor/statement/impl/PostgreSQLStatementSQLVisitor.java @@ -22,6 +22,7 @@ import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; import org.antlr.v4.runtime.misc.Interval; +import org.antlr.v4.runtime.tree.ParseTree; import org.antlr.v4.runtime.tree.TerminalNode; import org.apache.shardingsphere.sql.parser.api.visitor.ASTNode; import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementBaseVisitor; @@ -188,34 +189,37 @@ public abstract class PostgreSQLStatementSQLVisitor extends PostgreSQLStatementB if (null != ctx.IN()) { return createInSegment(ctx); } - if (null != ctx.TILDE_()) { - String operator = "~"; - if (null != ctx.NOT_()) { - operator = "!~"; - } - ExpressionSegment left = (ExpressionSegment) visit(ctx.aExpr(0)); - ExpressionSegment right = (ExpressionSegment) visit(ctx.aExpr(1)); - String text = ctx.start.getInputStream().getText(new Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex())); - return new BinaryOperationExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), left, right, operator, text); + if (null != ctx.patternMatchingOperator()) { + return createPatternMatchingOperationSegment(ctx); } if (null != ctx.comparisonOperator()) { - ExpressionSegment left = (ExpressionSegment) visit(ctx.aExpr(0)); - ExpressionSegment right = (ExpressionSegment) visit(ctx.aExpr(1)); - String operator = ctx.comparisonOperator().getText(); - String text = ctx.start.getInputStream().getText(new Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex())); - return new BinaryOperationExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), left, right, operator, text); + return createCommonBinaryOperationSegment(ctx, ctx.comparisonOperator().getText()); } if (null != ctx.logicalOperator()) { - ExpressionSegment left = (ExpressionSegment) visit(ctx.aExpr(0)); - ExpressionSegment right = (ExpressionSegment) visit(ctx.aExpr(1)); - String operator = ctx.logicalOperator().getText(); - String text = ctx.start.getInputStream().getText(new Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex())); - return new BinaryOperationExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), left, right, operator, text); + return createCommonBinaryOperationSegment(ctx, ctx.logicalOperator().getText()); } super.visitAExpr(ctx); String text = ctx.start.getInputStream().getText(new Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex())); return new CommonExpressionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), text); } + + private BinaryOperationExpression createPatternMatchingOperationSegment(final AExprContext ctx) { + String operator = ctx.patternMatchingOperator().getText(); + ExpressionSegment left = (ExpressionSegment) visit(ctx.aExpr(0)); + ListExpression right = new ListExpression(ctx.aExpr(1).start.getStartIndex(), ctx.aExpr().get(ctx.aExpr().size() - 1).stop.getStopIndex()); + for (int i = 1; i < ctx.aExpr().size(); i++) { + right.getItems().add((ExpressionSegment) visit(ctx.aExpr().get(i))); + } + String text = ctx.start.getInputStream().getText(new Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex())); + return new BinaryOperationExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), left, right, operator, text); + } + + private BinaryOperationExpression createCommonBinaryOperationSegment(final AExprContext ctx, final String operator) { + ExpressionSegment left = (ExpressionSegment) visit(ctx.aExpr(0)); + ExpressionSegment right = (ExpressionSegment) visit(ctx.aExpr(1)); + String text = ctx.start.getInputStream().getText(new Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex())); + return new BinaryOperationExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), left, right, operator, text); + } @Override public ASTNode visitCExpr(final CExprContext ctx) { @@ -235,8 +239,38 @@ public abstract class PostgreSQLStatementSQLVisitor extends PostgreSQLStatementB if (null != ctx.aExpr()) { return visit(ctx.aExpr()); } + if (null != ctx.funcExpr()) { + return visit(ctx.funcExpr()); + } super.visitCExpr(ctx); - return new CommonExpressionSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), ctx.getText()); + String text = ctx.start.getInputStream().getText(new Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex())); + return new CommonExpressionSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), text); + } + + @Override + public ASTNode visitFuncExpr(final FuncExprContext ctx) { + calculateParameterCount(getTargetRuleContextFromParseTree(ctx, CExprContext.class)); + String text = ctx.start.getInputStream().getText(new Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex())); + return new ExpressionProjectionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), text); + } + + private <T extends ParseTree> Collection<T> getTargetRuleContextFromParseTree(final ParseTree parseTree, final Class<? extends T> clazz) { + Collection<T> result = new LinkedList<>(); + for (int index = 0; index < parseTree.getChildCount(); index++) { + ParseTree child = parseTree.getChild(index); + if (clazz.isInstance(child)) { + result.add(clazz.cast(child)); + } else { + result.addAll(getTargetRuleContextFromParseTree(child, clazz)); + } + } + return result; + } + + private void calculateParameterCount(final Collection<CExprContext> cexprContexts) { + for (CExprContext each : cexprContexts) { + visit(each); + } } @Override diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-sqlserver/src/main/java/org/apache/shardingsphere/sql/parser/sqlserver/visitor/statement/impl/SQLServerStatementSQLVisitor.java b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-sqlserver/src/main/java/org/apache/shardingsphere/sql/parser/sqlserver/visitor/statement/impl/SQLServerStatementSQLVisitor.java index dd3f0be..1b628d4 100644 --- a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-sqlserver/src/main/java/org/apache/shardingsphere/sql/parser/sqlserver/visitor/statement/impl/SQLServerStatementSQLVisitor.java +++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-sqlserver/src/main/java/org/apache/shardingsphere/sql/parser/sqlserver/visitor/statement/impl/SQLServerStatementSQLVisitor.java @@ -471,7 +471,8 @@ public abstract class SQLServerStatementSQLVisitor extends SQLServerStatementBas @Override public final ASTNode visitRegularFunction(final RegularFunctionContext ctx) { calculateParameterCount(ctx.expr()); - return new ExpressionProjectionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.getText()); + String text = ctx.start.getInputStream().getText(new Interval(ctx.start.getStartIndex(), ctx.stop.getStopIndex())); + return new ExpressionProjectionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), text); } @Override diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/resources/case/dml/select.xml b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/resources/case/dml/select.xml index 3c7cda5..fb3fc7b 100644 --- a/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/resources/case/dml/select.xml +++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/resources/case/dml/select.xml @@ -37,7 +37,11 @@ <column name="name" start-index="29" stop-index="32"/> </left> <right> - <literal-expression value="^pg_toast" start-index="37" stop-index="47"/> + <list-expression> + <items> + <literal-expression value="^pg_toast" start-index="37" stop-index="47"/> + </items> + </list-expression> </right> <operator>!~</operator> </binary-operation-expression> @@ -744,7 +748,6 @@ <left> <binary-operation-expression start-index="53" stop-index="111" literal-stop-index="116"> <left> - <common-expression text="o.status LIKE CONCAT('%%', ?, '%%')" literal-text="o.status LIKE CONCAT('%%', 'init', '%%')" start-index="53" stop-index="87" literal-stop-index="92"/> <binary-operation-expression start-index="53" stop-index="87" literal-stop-index="92"> <left> <column name="status" start-index="53" stop-index="60"> @@ -810,86 +813,6 @@ </where> </select> - <select sql-case-id="select_count_like_concat_oracle_sqlserver" parameters="'init', 1, 2, 9, 10"> - <from> - <simple-table name="t_order" alias="o" start-index="37" stop-index="45" /> - </from> - <projections start-index="7" stop-index="30"> - <aggregation-projection type="COUNT" inner-expression="(0)" alias="orders_count" start-index="7" stop-index="14" /> - </projections> - <where start-index="47" stop-index="142" literal-stop-index="148"> - <expr> - <binary-operation-expression start-index="53" stop-index="142" literal-stop-index="148"> - <left> - <binary-operation-expression start-index="53" stop-index="111" literal-stop-index="116"> - <left> - <common-expression text="o.status LIKE CONCAT('%%', ?, '%%')" literal-text="o.status LIKE CONCAT('%%', 'init', '%%')" start-index="53" stop-index="87" literal-stop-index="92"/> - <binary-operation-expression start-index="53" stop-index="87" literal-stop-index="92"> - <left> - <column name="status" start-index="53" stop-index="60"> - <owner name="o" start-index="53" stop-index="53" /> - </column> - </left> - <operator>LIKE</operator> - <right> - <list-expression start-index="67" stop-index="87"> - <items> - <!-- 'text' is different from other database --> - <expression-projection text="CONCAT('%%',?,'%%')" literal-text="CONCAT('%%','init','%%')" start-index="67" stop-index="87" literal-stop-index="92" /> - </items> - </list-expression> - </right> - </binary-operation-expression> - </left> - <operator>AND</operator> - <right> - <in-expression start-index="93" stop-index="111" literal-start-index="98" literal-stop-index="116"> - <not>false</not> - <left> - <column name="user_id" start-index="93" stop-index="101" literal-start-index="98" literal-stop-index="106"> - <owner name="o" start-index="93" stop-index="93" literal-start-index="98" literal-stop-index="98"/> - </column> - </left> - <right> - <list-expression start-index="107" stop-index="110" literal-stop-index="115"> - <items> - <literal-expression value="1" start-index="112" stop-index="112" /> - <parameter-marker-expression value="1" start-index="107" stop-index="107" /> - </items> - <items> - <literal-expression value="2" start-index="115" stop-index="115" /> - <parameter-marker-expression value="2" start-index="110" stop-index="110" /> - </items> - </list-expression> - </right> - </in-expression> - </right> - </binary-operation-expression> - </left> - <operator>AND</operator> - <right> - <between-expression start-index="117" stop-index="142" literal-start-index="122" literal-stop-index="148"> - <not>false</not> - <left> - <column name="order_id" start-index="117" stop-index="126" literal-start-index="122" literal-stop-index="131"> - <owner name="o" start-index="117" stop-index="117" literal-start-index="122" literal-stop-index="122" /> - </column> - </left> - <between-expr> - <literal-expression value="9" start-index="141" stop-index="141" /> - <parameter-marker-expression value="3" start-index="136" stop-index="136" /> - </between-expr> - <and-expr> - <literal-expression value="10" start-index="147" stop-index="148" /> - <parameter-marker-expression value="4" start-index="142" stop-index="142" /> - </and-expr> - </between-expression> - </right> - </binary-operation-expression> - </expr> - </where> - </select> - <select sql-case-id="select_like_with_single_quotes" > <from> <simple-table name="admin" start-index="15" stop-index="19" /> @@ -929,7 +852,21 @@ <left> <binary-operation-expression start-index="53" stop-index="109" literal-stop-index="114"> <left> - <common-expression text="o.status ~~ CONCAT('%%', ?, '%%')" literal-text="o.status ~~ CONCAT('%%', 'init', '%%')" start-index="53" stop-index="85" literal-stop-index="90"/> + <binary-operation-expression start-index="53" stop-index="85" literal-stop-index="90"> + <left> + <column name="status" start-index="53" stop-index="60"> + <owner name="o" start-index="53" stop-index="53" /> + </column> + </left> + <operator>~~</operator> + <right> + <list-expression> + <items> + <expression-projection text="CONCAT('%%', ?, '%%')" literal-text="CONCAT('%%', 'init', '%%')" start-index="65" stop-index="85" literal-stop-index="90"/> + </items> + </list-expression> + </right> + </binary-operation-expression> </left> <operator>AND</operator> <right> @@ -1837,7 +1774,7 @@ </left> <operator>=</operator> <right> - <common-expression text="ST_GeographyFromText('SRID=4326;POINT('||?||' '||?||')')" literal-text="ST_GeographyFromText('SRID=4326;POINT('||100||' '||200||')')" start-index="60" stop-index="115" literal-start-index="78" literal-stop-index="137" /> + <expression-projection text="ST_GeographyFromText('SRID=4326;POINT('||?||' '||?||')')" literal-text="ST_GeographyFromText('SRID=4326;POINT('||100||' '||200||')')" start-index="60" stop-index="115" literal-start-index="78" literal-stop-index="137" /> </right> </binary-operation-expression> </right> @@ -1918,7 +1855,7 @@ </left> <operator>=</operator> <right> - <common-expression text="ST_GeographyFromText('SRID=4326;POINT('||?||' '||?||')')" literal-text="ST_GeographyFromText('SRID=4326;POINT('||100||' '||200||')')" start-index="73" stop-index="128" literal-start-index="109" literal-stop-index="168" /> + <expression-projection text="ST_GeographyFromText('SRID=4326;POINT('||?||' '||?||')')" literal-text="ST_GeographyFromText('SRID=4326;POINT('||100||' '||200||')')" start-index="73" stop-index="128" literal-start-index="109" literal-stop-index="168" /> </right> </binary-operation-expression> </right> @@ -2001,7 +1938,7 @@ </left> <operator>=</operator> <right> - <common-expression text="ST_GeographyFromText('SRID=4326;POINT('||?||' '||?||')')" literal-text="ST_GeographyFromText('SRID=4326;POINT('||100||' '||200||')')" start-index="79" stop-index="134" literal-start-index="115" literal-stop-index="174" /> + <expression-projection text="ST_GeographyFromText('SRID=4326;POINT('||?||' '||?||')')" literal-text="ST_GeographyFromText('SRID=4326;POINT('||100||' '||200||')')" start-index="79" stop-index="134" literal-start-index="115" literal-stop-index="174" /> </right> </binary-operation-expression> </right> diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/resources/sql/supported/dml/select.xml b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/resources/sql/supported/dml/select.xml index 4cb09bf..05c9128 100644 --- a/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/resources/sql/supported/dml/select.xml +++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/resources/sql/supported/dml/select.xml @@ -37,9 +37,8 @@ <sql-case id="select_equal_with_same_sharding_column" value="SELECT * FROM t_order WHERE order_id = ? AND order_id = ?" /> <sql-case id="select_in_with_same_sharding_column" value="SELECT * FROM t_order WHERE order_id IN (?, ?) AND order_id IN (?, ?) ORDER BY order_id" /> <sql-case id="select_with_N_string_in_expression" value="SELECT * FROM t_order WHERE is_deleted = 'N'" /> - <sql-case id="select_count_like" value="SELECT COUNT(*) FROM t_order WHERE (user_id = ? AND status LIKE ?)" db-types="MySQL, Oracle, SQL92, SQLServer" /> - <sql-case id="select_count_like_concat" value="SELECT count(0) as orders_count FROM t_order o WHERE o.status LIKE CONCAT('%%', ?, '%%') AND o.user_id IN (?, ?) AND o.order_id BETWEEN ? AND ?" db-types="MySQL, H2, PostgreSQL, SQL92" /> - <sql-case id="select_count_like_concat_oracle_sqlserver" value="SELECT count(0) as orders_count FROM t_order o WHERE o.status LIKE CONCAT('%%', ?, '%%') AND o.user_id IN (?, ?) AND o.order_id BETWEEN ? AND ?" db-types="Oracle, SQLServer" /> + <sql-case id="select_count_like" value="SELECT COUNT(*) FROM t_order WHERE (user_id = ? AND status LIKE ?)" /> + <sql-case id="select_count_like_concat" value="SELECT count(0) as orders_count FROM t_order o WHERE o.status LIKE CONCAT('%%', ?, '%%') AND o.user_id IN (?, ?) AND o.order_id BETWEEN ? AND ?" /> <sql-case id="select_like_with_single_quotes" value="select id from admin where fullname like 'a%'" db-types="MySQL"/> <sql-case id="select_count_tilde_concat" value="SELECT count(0) as orders_count FROM t_order o WHERE o.status ~~ CONCAT('%%', ?, '%%') AND o.user_id IN (?, ?) AND o.order_id BETWEEN ? AND ?" db-types="PostgreSQL" /> <sql-case id="select_sharding_route_with_binding_tables" value="SELECT i.* FROM t_order o JOIN t_order_item i ON o.user_id = i.user_id AND o.order_id = i.order_id WHERE o.user_id IN (?, ?) AND o.order_id BETWEEN ? AND ? ORDER BY i.item_id" />