Skip to content

Commit

Permalink
Support RLIKE parse for MySQL (apache#26731)
Browse files Browse the repository at this point in the history
Co-authored-by: devinzhang <[email protected]>
  • Loading branch information
FakeKotaro and FakeKotaro authored Jul 3, 2023
1 parent 2f801b0 commit 7665b7a
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -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
;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,9 @@ public final ASTNode visitPredicate(final PredicateContext ctx) {
if (null != ctx.REGEXP()) {
return createBinaryOperationExpressionFromRegexp(ctx);
}
if (null != ctx.RLIKE()) {
return createBinaryOperationExpressionFromRlike(ctx);
}
return visit(ctx.bitExpr(0));
}

Expand Down Expand Up @@ -552,6 +555,14 @@ private BinaryOperationExpression createBinaryOperationExpressionFromRegexp(fina
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));
Expand Down
76 changes: 76 additions & 0 deletions test/it/parser/src/main/resources/case/dml/select-expression.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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">
Expand Down Expand Up @@ -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" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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" />
Expand All @@ -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 &amp; ?" 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 &lt;&lt; ?" db-types="MySQL" />
Expand Down

0 comments on commit 7665b7a

Please sign in to comment.