Skip to content

Commit

Permalink
优化解析union后的括号逻辑 alibaba#5241
Browse files Browse the repository at this point in the history
优化解析union后的括号逻辑 alibaba#5241  单测还没改完
  • Loading branch information
lizongbo committed May 6, 2024
1 parent c4ffc36 commit 3e9796e
Show file tree
Hide file tree
Showing 13 changed files with 126 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ public SQLSelectQuery query(SQLObject parent, boolean acceptUnion) {

SQLSelectQuery select = query();
accept(Token.RPAREN);
select.setParenthesized(true);

return queryRest(select, acceptUnion);
}
Expand Down Expand Up @@ -636,6 +637,7 @@ public SQLTableSource parseTableSourcePrimary() {

if ((lexer.token() == Token.UNION || lexer.token() == Token.MINUS || lexer.token() == Token.EXCEPT)
&& tableSource instanceof OracleSelectSubqueryTableSource) {
((OracleSelectSubqueryTableSource) tableSource).getSelect().getQueryBlock().setParenthesized(true);
OracleSelectSubqueryTableSource selectSubqueryTableSource = (OracleSelectSubqueryTableSource) tableSource;
SQLSelect select = selectSubqueryTableSource.getSelect();
SQLSelectQuery selectQuery = this.queryRest(select.getQuery(), true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,9 @@ public boolean visit(OracleSelectQueryBlock x) {
if (isPrettyFormat() && x.hasBeforeComment()) {
printlnComments(x.getBeforeCommentsDirect());
}

if (x.isParenthesized()) {
print('(');
}
print0(ucase ? "SELECT " : "select ");

if (x.getHintsSize() > 0) {
Expand Down Expand Up @@ -424,6 +426,9 @@ public boolean visit(OracleSelectQueryBlock x) {
}
}

if (x.isParenthesized()) {
print(')');
}
return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public SQLSelectQuery query(SQLObject parent, boolean acceptUnion) {
((SQLSelectQueryBlock) select).setParenthesized(true);
}
accept(Token.RPAREN);
select.setParenthesized(true);

return queryRest(select, acceptUnion);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1222,7 +1222,9 @@ public boolean visit(OracleSelectQueryBlock x) {
if (isPrettyFormat() && x.hasBeforeComment()) {
printlnComments(x.getBeforeCommentsDirect());
}

if (x.isParenthesized()) {
print('(');
}
print0(ucase ? "SELECT " : "select ");

if (x.getHintsSize() > 0) {
Expand Down Expand Up @@ -1298,7 +1300,9 @@ public boolean visit(OracleSelectQueryBlock x) {
x.getWaitTime().accept(this);
}
}

if (x.isParenthesized()) {
print(')');
}
return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ public SQLSelectQuery queryRest(SQLSelectQuery selectQuery, boolean acceptUnion)

paren = lexer.token == Token.LPAREN;
SQLSelectQuery r = this.query(paren ? null : union, false);
r.setParenthesized(paren);
union.addRelation(r);
right = r;
}
Expand Down Expand Up @@ -411,6 +412,7 @@ public SQLSelectQuery query(SQLObject parent, boolean acceptUnion) {

SQLSelectQuery select = query();
accept(Token.RPAREN);
select.setParenthesized(true);

return queryRest(select, acceptUnion);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2488,7 +2488,9 @@ public boolean visit(SQLSelectQueryBlock x) {
if (isPrettyFormat() && x.hasBeforeComment()) {
printlnComments(x.getBeforeCommentsDirect());
}

if (x.isParenthesized()) {
print('(');
}
print0(ucase ? "SELECT " : "select ");

if (x.getHintsSize() > 0) {
Expand Down Expand Up @@ -2590,7 +2592,9 @@ public boolean visit(SQLSelectQueryBlock x) {
println();
print0(ucase ? "FOR UPDATE" : "for update");
}

if (x.isParenthesized()) {
print(')');
}
return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ public void test_0() throws Exception {
"\t\tSELECT t1.cust_no, t1.organ_key\n" +
"\t\tFROM t08_cust_result_c_mid t1\n" +
"\t\tUNION\n" +
"\t\tSELECT t2.cust_no, t2.organ_key\n" +
"\t\tFROM t08_cust_result_i_mid t2\n" +
"\t\t(SELECT t2.cust_no, t2.organ_key\n" +
"\t\tFROM t08_cust_result_i_mid t2)\n" +
"\t)\n" +
") t3 ON (t3.cust_no = t.cust_no) \n" +
"WHEN MATCHED THEN UPDATE SET t.organ_key = t3.organ_key",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ public void test_0() throws Exception {
Assert.assertEquals(1, statementList.size());

Assert.assertEquals("INSERT INTO TB_DUOBAO_PARTICIPATE_NUMBER (PARTICIPATE_NUMBER, PERIOD_ID, PRODUCT_ID, number_index)"
+ "\nSELECT ?, ?, ?, ?"
+ "\nFROM DUAL"
+ "\n(SELECT ?, ?, ?, ?"
+ "\nFROM DUAL)"
+ "\nUNION ALL"
+ "\nSELECT ?, ?, ?, ?"
+ "\nFROM DUAL",//
+ "\n(SELECT ?, ?, ?, ?"
+ "\nFROM DUAL)",//
SQLUtils.toSQLString(stmt, JdbcConstants.ORACLE));

OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.alibaba.druid.bvt.sql.oracle.issues;

import com.alibaba.druid.DbType;
import com.alibaba.druid.sql.SQLParseAssertUtil;

import org.junit.Test;

import static org.junit.Assert.assertTrue;

/**
* 验证 Oracle union sql的问题
*
* @author lizongbo
* @see <a href="https://github.com/alibaba/druid/issues/5241">Issue来源</a>
*/
public class Issue5241 {

@Test
public void test_parse_union() throws Exception {
for (DbType dbType : new DbType[]{
//DbType.mysql,
//DbType.oracle,
DbType.oscar,
}) {
for (String sql : new String[]{
"select count(*)" +
"from (" +
" (select id1111 from tb_user111 where id in(1,2) order by id)" +
" union" +
" (select id2222 from tb_user222 where id=4 )" +
" union" +
" (select id3333 from tb_user333 where id=5 )" +
"" +
") t",
"select *\n" +
"from (\n" +
" (select * from tb_user6666 where id in(1,2) order by id )\n" +
" union (select id from tb_user7777 where id=5 order by id)\n" +
" \n" +
" union\n" +
" select * from tb_user8888 where id=4 order by id desc\n" +
"\n" +
") t;",
}) {
SQLParseAssertUtil.assertParseSql(sql, dbType);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,49 +73,49 @@ public void test_0() throws Exception {

SQLSelectStatement stmt = (SQLSelectStatement) statementList.get(0);

assertEquals("SELECT *\n" +
"FROM (\n" +
"\tSELECT C.FLEX_VALUE, c.PARENT_FLEX_VALUE, c.CN_DESCRIPTION, c.En_Description\n" +
"\tFROM (\n" +
"\t\tSELECT a.PARENT_FLEX_VALUE, a.FLEX_VALUE, a.CN_DESCRIPTION, a.EN_DESCRIPTION, a.SUMMARY_FLAG\n" +
"\t\tFROM bpm_department_t4 a\n" +
"\t\tWHERE 1 = 1\n" +
"\t\t\tAND a.ENABLED_FLAG = 'Y'\n" +
"\t\tMINUS\n" +
"\t\tSELECT DISTINCT b.PARENT_FLEX_VALUE, b.FLEX_VALUE, b.CN_DESCRIPTION, b.EN_DESCRIPTION, b.SUMMARY_FLAG\n" +
"\t\tFROM bpm_department_t4 b\n" +
"\t\tWHERE 1 = 1\n" +
"\t\t\tAND b.ENABLED_FLAG = 'Y'\n" +
"\t\tSTART WITH (b.flex_value = 'C019998'\n" +
"\t\t\tOR b.flex_value LIKE 'ZF%')\n" +
"\t\tCONNECT BY PRIOR b.flex_value = b.parent_flex_value\n" +
"\t) c\n" +
"\tWHERE 1 = 1\n" +
"\t\tAND UPPER(c.FLEX_VALUE) LIKE concat(concat('%', '334518102833'), '%')\n" +
"\t\tOR c.CN_DESCRIPTION LIKE concat(concat('%', '334518102833'), '%')\n" +
")", stmt.toString());
assertEquals("SELECT *\n"
+ "FROM (\n"
+ "\tSELECT C.FLEX_VALUE, c.PARENT_FLEX_VALUE, c.CN_DESCRIPTION, c.En_Description\n"
+ "\tFROM (\n"
+ "\t\t(SELECT a.PARENT_FLEX_VALUE, a.FLEX_VALUE, a.CN_DESCRIPTION, a.EN_DESCRIPTION, a.SUMMARY_FLAG\n"
+ "\t\tFROM bpm_department_t4 a\n"
+ "\t\tWHERE 1 = 1\n"
+ "\t\t\tAND a.ENABLED_FLAG = 'Y')\n"
+ "\t\tMINUS\n"
+ "\t\t(SELECT DISTINCT b.PARENT_FLEX_VALUE, b.FLEX_VALUE, b.CN_DESCRIPTION, b.EN_DESCRIPTION, b.SUMMARY_FLAG\n"
+ "\t\tFROM bpm_department_t4 b\n"
+ "\t\tWHERE 1 = 1\n"
+ "\t\t\tAND b.ENABLED_FLAG = 'Y'\n"
+ "\t\tSTART WITH (b.flex_value = 'C019998'\n"
+ "\t\t\tOR b.flex_value LIKE 'ZF%')\n"
+ "\t\tCONNECT BY PRIOR b.flex_value = b.parent_flex_value)\n"
+ "\t) c\n"
+ "\tWHERE 1 = 1\n"
+ "\t\tAND UPPER(c.FLEX_VALUE) LIKE concat(concat('%', '334518102833'), '%')\n"
+ "\t\tOR c.CN_DESCRIPTION LIKE concat(concat('%', '334518102833'), '%')\n"
+ ")", stmt.toString());

assertEquals("select *\n" +
"from (\n" +
"\tselect C.FLEX_VALUE, c.PARENT_FLEX_VALUE, c.CN_DESCRIPTION, c.En_Description\n" +
"\tfrom (\n" +
"\t\tselect a.PARENT_FLEX_VALUE, a.FLEX_VALUE, a.CN_DESCRIPTION, a.EN_DESCRIPTION, a.SUMMARY_FLAG\n" +
"\t\tfrom bpm_department_t4 a\n" +
"\t\twhere 1 = 1\n" +
"\t\t\tand a.ENABLED_FLAG = 'Y'\n" +
"\t\tminus\n" +
"\t\tselect distinct b.PARENT_FLEX_VALUE, b.FLEX_VALUE, b.CN_DESCRIPTION, b.EN_DESCRIPTION, b.SUMMARY_FLAG\n" +
"\t\tfrom bpm_department_t4 b\n" +
"\t\twhere 1 = 1\n" +
"\t\t\tand b.ENABLED_FLAG = 'Y'\n" +
"\t\tstart with (b.flex_value = 'C019998'\n" +
"\t\t\tor b.flex_value like 'ZF%')\n" +
"\t\tconnect by prior b.flex_value = b.parent_flex_value\n" +
"\t) c\n" +
"\twhere 1 = 1\n" +
"\t\tand UPPER(c.FLEX_VALUE) like concat(concat('%', '334518102833'), '%')\n" +
"\t\tor c.CN_DESCRIPTION like concat(concat('%', '334518102833'), '%')\n" +
")", stmt.toLowerCaseString());
assertEquals("select *\n"
+ "from (\n"
+ "\tselect C.FLEX_VALUE, c.PARENT_FLEX_VALUE, c.CN_DESCRIPTION, c.En_Description\n"
+ "\tfrom (\n"
+ "\t\t(select a.PARENT_FLEX_VALUE, a.FLEX_VALUE, a.CN_DESCRIPTION, a.EN_DESCRIPTION, a.SUMMARY_FLAG\n"
+ "\t\tfrom bpm_department_t4 a\n"
+ "\t\twhere 1 = 1\n"
+ "\t\t\tand a.ENABLED_FLAG = 'Y')\n"
+ "\t\tminus\n"
+ "\t\t(select distinct b.PARENT_FLEX_VALUE, b.FLEX_VALUE, b.CN_DESCRIPTION, b.EN_DESCRIPTION, b.SUMMARY_FLAG\n"
+ "\t\tfrom bpm_department_t4 b\n"
+ "\t\twhere 1 = 1\n"
+ "\t\t\tand b.ENABLED_FLAG = 'Y'\n"
+ "\t\tstart with (b.flex_value = 'C019998'\n"
+ "\t\t\tor b.flex_value like 'ZF%')\n"
+ "\t\tconnect by prior b.flex_value = b.parent_flex_value)\n"
+ "\t) c\n"
+ "\twhere 1 = 1\n"
+ "\t\tand UPPER(c.FLEX_VALUE) like concat(concat('%', '334518102833'), '%')\n"
+ "\t\tor c.CN_DESCRIPTION like concat(concat('%', '334518102833'), '%')\n"
+ ")", stmt.toLowerCaseString());

OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor();
stmt.accept(visitor);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ public void test_0() throws Exception {
{
String text = SQLUtils.toOracleString(stmt);

assertEquals("SELECT *\n" +
assertEquals("(SELECT *\n" +
"FROM emp\n" +
"WHERE empno = 111;", text);
"WHERE empno = 111);", text);
}
// Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("acduser.vw_acd_info", "xzqh")));

Expand Down
4 changes: 2 additions & 2 deletions core/src/test/resources/bvt/parser/postgresql-10.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ CREATE TABLE live_measures_copy (
updated_at
)
AS
SELECT uuid, project_uuid, component_uuid, CAST(metric_id AS VARCHAR(40)) AS metric_uuid, value
(SELECT uuid, project_uuid, component_uuid, CAST(metric_id AS VARCHAR(40)) AS metric_uuid, value
, text_value, variation, measure_data, update_marker, created_at
, updated_at
FROM live_measures
FROM live_measures)
4 changes: 2 additions & 2 deletions core/src/test/resources/bvt/parser/postgresql-3.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ create table s_2c3e24b36890b0d31aeca286e84c6471 as (
---------------------------
CREATE TABLE s_2c3e24b36890b0d31aeca286e84c6471
AS
SELECT DISTINCT ON(sn) AS sn, num01
FROM "s_f73e29e1c9830041f1bdfa8_2c3e24b36890b0d31aeca286e84c6471";
(SELECT DISTINCT ON(sn) AS sn, num01
FROM "s_f73e29e1c9830041f1bdfa8_2c3e24b36890b0d31aeca286e84c6471");

0 comments on commit 3e9796e

Please sign in to comment.