[Fix](Nereids) fix nereids failed to parse set operation with query in parenthesis (#18062)

sql like the format (q1, q2, q3 is a query): 

``` sql
(q1) 
UNION ALL (q2)
UNION ALL (q3)
ORDER BY keys
```
cannot be parsed by nereids, because order will be recognized as an alias of query, we add queryOrganization to avoid it.
This commit is contained in:
mch_ucchi
2023-03-31 15:55:52 +08:00
committed by GitHub
parent 22a705543b
commit 3ea98b65df
6 changed files with 35 additions and 17 deletions

View File

@ -68,9 +68,11 @@ planType
;
// -----------------Query-----------------
// add queryOrganization for parse (q1) union (q2) union (q3) order by keys, otherwise 'order' will be recognized to be
// identifier.
query
: {!doris_legacy_SQL_syntax}? cte? queryTerm queryOrganization
| {doris_legacy_SQL_syntax}? queryTerm
| {doris_legacy_SQL_syntax}? queryTerm queryOrganization
;
queryTerm
@ -186,7 +188,7 @@ queryOrganization
;
sortClause
: (ORDER BY sortItem (COMMA sortItem)*)
: ORDER BY sortItem (COMMA sortItem)*
;
sortItem

View File

@ -422,14 +422,17 @@ public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> {
.add(rightQuery)
.build();
LogicalPlan plan;
if (ctx.UNION() != null) {
return new LogicalUnion(qualifier, newChildren);
plan = new LogicalUnion(qualifier, newChildren);
} else if (ctx.EXCEPT() != null) {
return new LogicalExcept(qualifier, newChildren);
plan = new LogicalExcept(qualifier, newChildren);
} else if (ctx.INTERSECT() != null) {
return new LogicalIntersect(qualifier, newChildren);
plan = new LogicalIntersect(qualifier, newChildren);
} else {
throw new ParseException("not support", ctx);
}
throw new ParseException("not support", ctx);
return plan;
});
}

View File

@ -114,12 +114,13 @@ public abstract class LogicalSetOperation extends AbstractLogicalPlan implements
ImmutableList.Builder<NamedExpression> newOutputs = new Builder<>();
for (Expression expression : leftCastExpressions) {
if (expression instanceof Cast) {
Cast cast = ((Cast) expression);
newOutputs.add(new SlotReference(
((Cast) expression).child().toSql(), expression.getDataType(),
((Cast) expression).child().nullable()));
cast.child().toSql(), expression.getDataType(),
cast.child().nullable()));
} else if (expression instanceof Slot) {
newOutputs.add(new SlotReference(
expression.toSql(), expression.getDataType(), expression.nullable()));
Slot slot = ((Slot) expression);
newOutputs.add(new SlotReference(slot.toSql(), slot.getDataType(), slot.nullable()));
}
}
return newOutputs.build();

View File

@ -267,9 +267,22 @@ public class NereidsParserTest extends ParserTestBase {
System.out.println(logicalPlan.treeString());
String union1 = "select * from t1 union (select * from t2 union all select * from t3)";
NereidsParser nereidsParser1 = new NereidsParser();
LogicalPlan logicalPlan1 = nereidsParser1.parseSingle(union1);
LogicalPlan logicalPlan1 = nereidsParser.parseSingle(union1);
System.out.println(logicalPlan1.treeString());
String union2 = "(SELECT K1, K2, K3, K4, K5, K6, K7, K8, K9, K10, K11 FROM test WHERE K1 > 0)"
+ " UNION ALL (SELECT 1, 2, 3, 4, 3.14, 'HELLO', 'WORLD', 0.0, 1.1, CAST('1989-03-21' AS DATE), CAST('1989-03-21 13:00:00' AS DATETIME))"
+ " UNION ALL (SELECT K1, K2, K3, K4, K5, K6, K7, K8, K9, K10, K11 FROM baseall WHERE K3 > 0)"
+ " ORDER BY K1, K2, K3, K4";
LogicalPlan logicalPlan2 = nereidsParser.parseSingle(union2);
System.out.println(logicalPlan2.treeString());
String union3 = "select a.k1, a.k2, a.k3, b.k1, b.k2, b.k3 from test a left outer join baseall b"
+ " on a.k1 = b.k1 and a.k2 > b.k2 union (select a.k1, a.k2, a.k3, b.k1, b.k2, b.k3"
+ " from test a right outer join baseall b on a.k1 = b.k1 and a.k2 > b.k2)"
+ " order by isnull(a.k1), 1, 2, 3, 4, 5 limit 65535";
LogicalPlan logicalPlan3 = nereidsParser.parseSingle(union3);
System.out.println(logicalPlan3.treeString());
}
@Test