From 00cb56cd9b403eb39adfe7c7aaf05190b8c80461 Mon Sep 17 00:00:00 2001 From: AdolphLv Date: Wed, 3 Jul 2024 18:17:50 +0800 Subject: [PATCH 1/5] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8Dmysql=E8=AF=AD?= =?UTF-8?q?=E5=8F=A5=E8=A7=A3=E6=9E=90=E5=BC=82=E5=B8=B8=E9=97=AE=E9=A2=98?= =?UTF-8?q?,mysql=E5=AE=9E=E9=99=85=E6=89=A7=E8=A1=8C=E6=AD=A3=E5=B8=B8=20?= =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=86=85=E5=AE=B9=E4=B8=AD=E5=90=AB?= =?UTF-8?q?=E8=BD=AC=E4=B9=89=E7=AC=A6=E5=8F=B7\\'XXX\\'=E4=BB=A5=E5=8F=8A?= =?UTF-8?q?=E6=9B=BF=E6=8D=A2=E6=97=B6=E5=BF=BD=E7=95=A5=E5=B7=B2=E7=BB=8F?= =?UTF-8?q?=E8=BD=AC=E4=B9=89=E7=9A=84'',=E4=BB=85=E8=BD=AC=E4=B9=89?= =?UTF-8?q?=E5=8D=95'=E5=92=8C\\'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mysql/parser/MySqlSelectParser.java | 24 +++++++++++++++++++ .../sql/visitor/SQLASTOutputVisitor.java | 3 ++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectParser.java b/core/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectParser.java index ee74fc94d3..06319eecef 100644 --- a/core/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectParser.java +++ b/core/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectParser.java @@ -115,6 +115,16 @@ public SQLSelectQuery query(SQLObject parent, boolean acceptUnion) { SQLSelectQuery select = query(); select.setParenthesized(true); + // 修复特殊sql语句解析错误问题 + // 解析异常语句: ((select * from b where 1=1) limit 0,123) + if (lexer.token() == Token.ORDER) { + parseSortBy((SQLSelectQueryBlock) select); + lexer.nextToken(); + } + if (lexer.token() == Token.LIMIT) { + SQLLimit limit = this.exprParser.parseLimit(); + ((SQLSelectQueryBlock) select).setLimit(limit); + } accept(Token.RPAREN); return queryRest(select, acceptUnion); @@ -429,6 +439,20 @@ public SQLTableSource parseTableSource(SQLObject parent) { tableSource.getHints().addAll(hints); } } + // 修复特殊sql语句解析错误问题 + // 解析异常语句: select * from (((select * from tb1 a where (a.cc IN('I') ) and 1=1 and (1=2) )) limit 0,1234) as a where (((a.cc IN('I') ) AND (a.cc IN('I') ))) order by a.cc + if (lexer.token() == Token.ORDER) { + SQLOrderBy orderBy = this.exprParser.parseOrderBy(); + if (tableSource instanceof SQLSubqueryTableSource) { + ((SQLSubqueryTableSource) tableSource).getSelect().setOrderBy(orderBy); + } + } + if (lexer.token() == Token.LIMIT) { + SQLLimit limit = this.exprParser.parseLimit(); + if (tableSource instanceof SQLSubqueryTableSource) { + ((SQLSubqueryTableSource) tableSource).getSelect().setLimit(limit); + } + } accept(Token.RPAREN); } else { tableSource = parseTableSource(); diff --git a/core/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java b/core/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java index a7d4f92602..354ca70d64 100644 --- a/core/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/core/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -1339,7 +1339,8 @@ protected void printChars(String text) { print('\''); int index = text.indexOf('\''); if (index >= 0) { - text = text.replaceAll("'", "''"); + //修复内容中含转义符号\\'XXX\\'以及替换时忽略已经转义的'',仅转义单'和\\' + text = text.replaceAll("(\\\\')|(? Date: Wed, 3 Jul 2024 20:15:28 +0800 Subject: [PATCH 2/5] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E9=80=9A=E8=BF=87?= =?UTF-8?q?MySqlInsertStatement.ValuesClause=E5=8A=A8=E6=80=81addValue?= =?UTF-8?q?=E5=AD=97=E7=AC=A6=E4=B8=B2=E6=95=B0=E5=80=BC=E6=97=B6,=20value?= =?UTF-8?q?=E5=80=BC=E4=B8=BA\\=20=E4=BC=9A=E5=AF=BC=E8=87=B4=E6=9C=80?= =?UTF-8?q?=E7=BB=88=E6=8B=BC=E6=8E=A5=E7=BB=93=E6=9E=9C=E4=B8=BA'\'?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java b/core/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java index 354ca70d64..c495128986 100644 --- a/core/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/core/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -1337,7 +1337,12 @@ protected void printChars(String text) { print0(ucase ? "NULL" : "null"); } else { print('\''); - int index = text.indexOf('\''); + int index = text.indexOf('\\'); + if (index >= 0) { + //修复内容中含特殊符号\时, 直接拼接会导致sql错误,但是又要忽略已经转义的 + text = text.replaceAll("(?= 0) { //修复内容中含转义符号\\'XXX\\'以及替换时忽略已经转义的'',仅转义单'和\\' text = text.replaceAll("(\\\\')|(? Date: Fri, 5 Jul 2024 13:36:52 +0800 Subject: [PATCH 3/5] =?UTF-8?q?fix:=20=E5=B7=B2=E7=BB=8F=E6=9C=89=E8=BD=AC?= =?UTF-8?q?=E4=B9=89=E7=AC=A6=E5=8F=B7=E7=9A=84=E4=B8=8D=E5=B8=8C=E6=9C=9B?= =?UTF-8?q?=E8=BF=9B=E8=A1=8C=E4=BA=8C=E6=AC=A1=E8=BD=AC=E4=B9=89,=20?= =?UTF-8?q?=E5=A6=82=E6=9E=9C=E6=98=AF=E4=BB=85=E5=8D=95'=E7=9A=84?= =?UTF-8?q?=E4=BB=8D=E9=9C=80=E8=A6=81=E8=BF=9B=E8=A1=8C=E8=BD=AC=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../druid/sql/visitor/SQLASTOutputVisitor.java | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/core/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java b/core/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java index c495128986..653cbde28a 100644 --- a/core/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/core/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -1337,17 +1337,12 @@ protected void printChars(String text) { print0(ucase ? "NULL" : "null"); } else { print('\''); - int index = text.indexOf('\\'); + int index = text.indexOf('\''); if (index >= 0) { - //修复内容中含特殊符号\时, 直接拼接会导致sql错误,但是又要忽略已经转义的 - text = text.replaceAll("(?= 0) { - //修复内容中含转义符号\\'XXX\\'以及替换时忽略已经转义的'',仅转义单'和\\' - text = text.replaceAll("(\\\\')|(? Date: Mon, 15 Jul 2024 19:06:26 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E8=BF=98=E5=8E=9F=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sql/visitor/SQLASTOutputVisitor.java | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/core/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java b/core/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java index 12f4f9ad43..568e6c8782 100644 --- a/core/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/core/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -1336,17 +1336,16 @@ public boolean visit(SQLCharExpr x, boolean parameterized) { } protected void printChars(String text) { - if (text == null) { - print0(ucase ? "NULL" : "null"); - } else { - print('\''); - int index = text.indexOf('\''); - if (index >= 0) { - //修复内容中含转义符号仅转义单' - text = text.replaceAll("(?= 0) { + text = text.replaceAll("'", "''"); + } + print0(text); + print('\''); } } From 83cd360f709d90f3b206f9247eccd298fca0b87f Mon Sep 17 00:00:00 2001 From: AdolphLv <35337924+AdolphLv@users.noreply.github.com> Date: Mon, 15 Jul 2024 19:08:36 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=E8=BF=98=E5=8E=9F=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sql/visitor/SQLASTOutputVisitor.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/core/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java b/core/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java index 568e6c8782..b010d18bf8 100644 --- a/core/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/core/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -1336,16 +1336,16 @@ public boolean visit(SQLCharExpr x, boolean parameterized) { } protected void printChars(String text) { - if (text == null) { - print0(ucase ? "NULL" : "null"); - } else { - print('\''); - int index = text.indexOf('\''); - if (index >= 0) { - text = text.replaceAll("'", "''"); - } - print0(text); - print('\''); + if (text == null) { + print0(ucase ? "NULL" : "null"); + } else { + print('\''); + int index = text.indexOf('\''); + if (index >= 0) { + text = text.replaceAll("'", "''"); + } + print0(text); + print('\''); } }