This is an automated email from the ASF dual-hosted git repository.
duanzhengqiang 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 7665b7a36ad Support RLIKE parse for MySQL (#26731)
7665b7a36ad is described below
commit 7665b7a36ada62da118a06a69f6444045cacc280
Author: devin_411 <[email protected]>
AuthorDate: Mon Jul 3 12:01:00 2023 +0800
Support RLIKE parse for MySQL (#26731)
Co-authored-by: devinzhang <[email protected]>
---
.../src/main/antlr4/imports/mysql/BaseRule.g4 | 2 +-
.../visitor/statement/MySQLStatementVisitor.java | 11 ++++
.../main/resources/case/dml/select-expression.xml | 76 ++++++++++++++++++++++
.../sql/supported/dml/select-expression.xml | 2 +
4 files changed, 90 insertions(+), 1 deletion(-)
diff --git a/parser/sql/dialect/mysql/src/main/antlr4/imports/mysql/BaseRule.g4
b/parser/sql/dialect/mysql/src/main/antlr4/imports/mysql/BaseRule.g4
index 141bf47e1af..9b4f96af45c 100644
--- a/parser/sql/dialect/mysql/src/main/antlr4/imports/mysql/BaseRule.g4
+++ b/parser/sql/dialect/mysql/src/main/antlr4/imports/mysql/BaseRule.g4
@@ -872,7 +872,7 @@ predicate
| bitExpr NOT? BETWEEN bitExpr AND predicate
| bitExpr SOUNDS LIKE bitExpr
| bitExpr NOT? LIKE simpleExpr (ESCAPE simpleExpr)?
- | bitExpr NOT? REGEXP bitExpr
+ | bitExpr NOT? (REGEXP | RLIKE) bitExpr
| bitExpr
;
diff --git
a/parser/sql/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/MySQLStatementVisitor.java
b/parser/sql/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/MySQLStatementVisitor.java
index eb79f9afa77..4926b71acb4 100644
---
a/parser/sql/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/MySQLStatementVisitor.java
+++
b/parser/sql/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/MySQLStatementVisitor.java
@@ -508,6 +508,9 @@ public abstract class MySQLStatementVisitor extends
MySQLStatementBaseVisitor<AS
if (null != ctx.REGEXP()) {
return createBinaryOperationExpressionFromRegexp(ctx);
}
+ if (null != ctx.RLIKE()) {
+ return createBinaryOperationExpressionFromRlike(ctx);
+ }
return visit(ctx.bitExpr(0));
}
@@ -552,6 +555,14 @@ public abstract class MySQLStatementVisitor extends
MySQLStatementBaseVisitor<AS
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
createBinaryOperationExpressionFromRlike(final PredicateContext ctx) {
+ ExpressionSegment left = (ExpressionSegment) visit(ctx.bitExpr(0));
+ ExpressionSegment right = (ExpressionSegment) visit(ctx.bitExpr(1));
+ String operator = null != ctx.NOT() ? "NOT RLIKE" : "RLIKE";
+ 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 BetweenExpression createBetweenSegment(final PredicateContext ctx)
{
ExpressionSegment left = (ExpressionSegment) visit(ctx.bitExpr(0));
diff --git a/test/it/parser/src/main/resources/case/dml/select-expression.xml
b/test/it/parser/src/main/resources/case/dml/select-expression.xml
index e0006fbad88..17eb90c718a 100644
--- a/test/it/parser/src/main/resources/case/dml/select-expression.xml
+++ b/test/it/parser/src/main/resources/case/dml/select-expression.xml
@@ -121,6 +121,58 @@
</where>
</select>
+ <select sql-case-id="select_with_rlike" parameters="'init', 1, 2">
+ <from>
+ <simple-table name="t_order_item" alias="t" start-index="14"
stop-index="27" />
+ </from>
+ <projections start-index="7" stop-index="7">
+ <shorthand-projection start-index="7" stop-index="7" />
+ </projections>
+ <where start-index="29" stop-index="74" literal-stop-index="79">
+ <expr>
+ <binary-operation-expression start-index="35" stop-index="74"
literal-stop-index="79">
+ <left>
+ <binary-operation-expression start-index="35"
stop-index="50" literal-stop-index="55">
+ <left>
+ <column name="status" start-index="35"
stop-index="42">
+ <owner name="t" start-index="35"
stop-index="35" />
+ </column>
+ </left>
+ <operator>RLIKE</operator>
+ <right>
+ <literal-expression value="init"
start-index="50" stop-index="55" />
+ <parameter-marker-expression
parameter-index="0" start-index="50" stop-index="50" />
+ </right>
+ </binary-operation-expression>
+ </left>
+ <operator>AND</operator>
+ <right>
+ <in-expression start-index="56" stop-index="74"
literal-start-index="61" literal-stop-index="79">
+ <not>false</not>
+ <left>
+ <column name="item_id" start-index="56"
stop-index="64" literal-start-index="61" literal-stop-index="69">
+ <owner name="t" start-index="56"
stop-index="56" literal-start-index="61" literal-stop-index="61" />
+ </column>
+ </left>
+ <right>
+ <list-expression start-index="69"
stop-index="74" literal-start-index="74" literal-stop-index="79">
+ <items>
+ <literal-expression value="1"
start-index="75" stop-index="75" />
+ <parameter-marker-expression
parameter-index="1" start-index="70" stop-index="70" />
+ </items>
+ <items>
+ <literal-expression value="2"
start-index="78" stop-index="78" />
+ <parameter-marker-expression
parameter-index="2" start-index="73" stop-index="73" />
+ </items>
+ </list-expression>
+ </right>
+ </in-expression>
+ </right>
+ </binary-operation-expression>
+ </expr>
+ </where>
+ </select>
+
<select sql-case-id="select_with_case_expression">
<projections start-index="7" stop-index="124">
<shorthand-projection start-index="7" stop-index="9">
@@ -1005,6 +1057,30 @@
</where>
</select>
+ <select sql-case-id="select_where_with_predicate_with_rlike">
+ <from start-index="14" stop-index="20">
+ <simple-table name="t_order" start-index="14" stop-index="20" />
+ </from>
+ <projections distinct-row="false" start-index="7" stop-index="7">
+ <shorthand-projection start-index="7" stop-index="7" />
+ </projections>
+ <where start-index="22" stop-index="61">
+ <expr>
+ <binary-operation-expression start-index="28" stop-index="61">
+ <left>
+ <column name="order_id" start-index="28"
stop-index="43">
+ <owner name="t_order" start-index="28"
stop-index="34" />
+ </column>
+ </left>
+ <operator>NOT RLIKE</operator>
+ <right>
+ <literal-expression value="[123]" start-index="55"
stop-index="61" />
+ </right>
+ </binary-operation-expression>
+ </expr>
+ </where>
+ </select>
+
<select sql-case-id="select_where_with_bit_expr_with_vertical_bar"
parameters="1">
<from start-index="14" stop-index="20">
<simple-table name="t_order" start-index="14" stop-index="20" />
diff --git
a/test/it/parser/src/main/resources/sql/supported/dml/select-expression.xml
b/test/it/parser/src/main/resources/sql/supported/dml/select-expression.xml
index fa450ef0870..0fa6f800fa2 100644
--- a/test/it/parser/src/main/resources/sql/supported/dml/select-expression.xml
+++ b/test/it/parser/src/main/resources/sql/supported/dml/select-expression.xml
@@ -21,6 +21,7 @@
<sql-case id="select_with_expression_for_postgresql" value="SELECT
o.order_id + 1 * 2 as exp FROM t_order AS o ORDER BY o.order_id"
db-types="PostgreSQL,openGauss" />
<sql-case id="select_with_date_function" value="SELECT
DATE(i.creation_date) AS creation_date FROM `t_order_item` AS i ORDER BY
DATE(i.creation_date) DESC" db-types="MySQL" />
<sql-case id="select_with_regexp" value="SELECT * FROM t_order_item t
WHERE t.status REGEXP ? AND t.item_id IN (?, ?)" db-types="MySQL" />
+ <sql-case id="select_with_rlike" value="SELECT * FROM t_order_item t WHERE
t.status RLIKE ? AND t.item_id IN (?, ?)" db-types="MySQL" />
<sql-case id="select_with_case_expression" value="select t.*,o.item_id as
item_id,(case when t.status = 'init' then '已启用' when t.status = 'failed' then
'已停用' end) as stateName from t_order t left join t_order_item as o on
o.order_id =t.order_id where t.order_id=1000 limit 1" db-types="MySQL,H2" />
<sql-case id="select_where_with_expr_with_or" value="SELECT * FROM t_order
WHERE t_order.order_id = ? OR ? = t_order.order_id" db-types="MySQL" />
<sql-case id="select_where_with_expr_with_or_sign" value="SELECT * FROM
t_order WHERE t_order.order_id = ? || ? = t_order.order_id" db-types="MySQL" />
@@ -44,6 +45,7 @@
<sql-case id="select_where_with_predicate_with_like" value="SELECT * FROM
t_order WHERE t_order.order_id NOT LIKE '1%' ESCAPE '$'" db-types="MySQL" />
<sql-case id="select_where_with_predicate_with_not_like" value="SELECT *
FROM t_order WHERE t_order.status NOT LIKE '1%'"
db-types="MySQL,PostgreSQL,openGauss" />
<sql-case id="select_where_with_predicate_with_regexp" value="SELECT *
FROM t_order WHERE t_order.order_id NOT REGEXP '[123]'" db-types="MySQL" />
+ <sql-case id="select_where_with_predicate_with_rlike" value="SELECT * FROM
t_order WHERE t_order.order_id NOT RLIKE '[123]'" db-types="MySQL" />
<sql-case id="select_where_with_bit_expr_with_vertical_bar" value="SELECT
* FROM t_order WHERE t_order.order_id | ?" db-types="MySQL" />
<sql-case id="select_where_with_bit_expr_with_ampersand" value="SELECT *
FROM t_order WHERE t_order.order_id & ?" db-types="MySQL" />
<sql-case id="select_where_with_bit_expr_with_signed_left_shift"
value="SELECT * FROM t_order WHERE t_order.order_id << ?"
db-types="MySQL" />