From 443e91a5459e8d7f23e0fa6e48e2b5673d77c76a Mon Sep 17 00:00:00 2001 From: wenshao Date: Mon, 29 Oct 2018 09:53:29 +0800 Subject: [PATCH] bug fixed for issue #2876 --- .../dialect/odps/parser/OdpsExprParser.java | 3 +- .../com/alibaba/druid/sql/parser/Lexer.java | 41 +++++++++---------- .../com/alibaba/druid/bvt/bug/Issue2876.java | 31 ++++++++++++++ 3 files changed, 53 insertions(+), 22 deletions(-) create mode 100644 src/test/java/com/alibaba/druid/bvt/bug/Issue2876.java diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsExprParser.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsExprParser.java index 9838758c39..87fe12eb3d 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsExprParser.java @@ -73,7 +73,8 @@ public class OdpsExprParser extends SQLExprParser { } protected SQLExpr parseAliasExpr(String alias) { - return new SQLCharExpr(alias); + String chars = alias.substring(1, alias.length() - 1); + return new SQLCharExpr(chars); } @Override diff --git a/src/main/java/com/alibaba/druid/sql/parser/Lexer.java b/src/main/java/com/alibaba/druid/sql/parser/Lexer.java index 0d3ccdbc0b..263df3ec6a 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/Lexer.java +++ b/src/main/java/com/alibaba/druid/sql/parser/Lexer.java @@ -1358,8 +1358,9 @@ public class Lexer { stringVal = new String(buf, 0, bufPos); } } - + protected final void scanAlias() { + final char quote = ch; { boolean hasSpecial = false; int startIndex = pos + 1; @@ -1370,22 +1371,16 @@ public class Lexer { hasSpecial = true; continue; } - if (ch == '"') { + if (ch == quote) { if (i + 1 < text.length()) { char ch_next = charAt(i + 1); - if (ch_next == '"' || ch_next == '\'') { + if (ch_next == quote) { hasSpecial = true; i++; continue; } } - if (i > 0) { - char ch_last = charAt(i - 1); - if (ch_last == '\'') { - hasSpecial = true; - continue; - } - } + endIndex = i; break; } @@ -1415,6 +1410,7 @@ public class Lexer { initBuff(bufPos); //putChar(ch); + putChar(ch); for (;;) { if (isEOF()) { lexError("unclosed.str.lit"); @@ -1431,9 +1427,15 @@ public class Lexer { putChar('\0'); break; case '\'': + if (ch == quote) { + putChar('\\'); + } putChar('\''); break; case '"': + if (ch == quote) { + putChar('\\'); + } putChar('"'); break; case 'b': @@ -1449,6 +1451,7 @@ public class Lexer { putChar('\t'); break; case '\\': + putChar('\\'); putChar('\\'); break; case 'Z': @@ -1462,23 +1465,19 @@ public class Lexer { continue; } -// if (ch == '\'') { -// char ch_next = charAt(pos + 1); -// if (ch_next == '"') { -// scanChar(); -// continue; -// } -// } else - if (ch == '\"') { + if (ch == quote) { char ch_next = charAt(pos + 1); - if (ch_next == '"' || ch_next == '\'') { + + if (ch_next == quote) { + putChar('\\'); + putChar(ch); scanChar(); continue; } - //putChar(ch); + putChar(ch); scanChar(); - token = LITERAL_CHARS; + token = LITERAL_ALIAS; break; } diff --git a/src/test/java/com/alibaba/druid/bvt/bug/Issue2876.java b/src/test/java/com/alibaba/druid/bvt/bug/Issue2876.java new file mode 100644 index 0000000000..e1a391e791 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/bug/Issue2876.java @@ -0,0 +1,31 @@ +package com.alibaba.druid.bvt.bug; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource; +import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; +import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; + +import java.util.List; + +public class Issue2876 extends TestCase { + public void test_0() throws Exception { + String sql = "SELECT CONCAT(\"'\",b.PRIMARY_ID,\"'\") \n" + + "FROM s_user_session_attributes a \n" + + "LEFT JOIN s_user_session b ON a.SESSION_PRIMARY_ID=b.PRIMARY_ID \n" + + "WHERE a.ATTRIBUTE_NAME='KAPTCHA_SESSION_KEY' AND b.LAST_ACCESS_TIME <= 1540429945459"; + + System.out.println(sql); + + List stmtList = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL); + + SQLSelectStatement stmt = (SQLSelectStatement) stmtList.get(0); + SQLSelectQueryBlock queryBlock = stmt.getSelect().getQueryBlock(); + SQLJoinTableSource joinTableSource = (SQLJoinTableSource) queryBlock.getFrom(); + + assertEquals("a", joinTableSource.getLeft().getAlias()); + assertEquals("b", joinTableSource.getRight().getAlias()); + } +}