Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>com.alibaba</groupId>
<artifactId>druid-parent</artifactId>
<version>1.2.25-SNAPSHOT</version>
<version>1.2.28-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>druid</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,12 @@ public void addArgument(SQLExpr arg) {
this.arguments.add(arg);
}

public void addArguments(List<SQLExpr> args) {
for (SQLExpr arg : args) {
addArgument(arg);
}
}

public SQLExpr getOwner() {
return this.owner;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ public class BigQueryExprParser extends SQLExprParser {
"FIRST_VALUE",
"GROUPING",
"LAST_VALUE",
"LAG",
"LEAD",
"LOGICAL_AND",
"LOGICAL_OR",
"MAX",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,24 @@ public SQLExpr primaryRest(SQLExpr expr) {
castExpr.setExpr(expr);
castExpr.setDataType(dataType);

// If parseDataType consumed a COLLATE clause (e.g., ::text COLLATE "zh-Hans-x-icu"),
// extract it and wrap the cast in a COLLATE binary expression
if (dataType instanceof com.alibaba.druid.sql.ast.statement.SQLCharacterDataType) {
com.alibaba.druid.sql.ast.statement.SQLCharacterDataType charType =
(com.alibaba.druid.sql.ast.statement.SQLCharacterDataType) dataType;
String collate = charType.getCollate();
if (collate != null) {
charType.setCollate(null);
SQLBinaryOpExpr collateExpr = new SQLBinaryOpExpr(
castExpr,
SQLBinaryOperator.COLLATE,
new SQLIdentifierExpr(collate),
dbType
);
return primaryRest(collateExpr);
}
}

return primaryRest(castExpr);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1027,6 +1027,13 @@ public PGAnalyzeStatement parseAnalyzeTable() {
Lexer.SavePoint mark = lexer.mark();
String strVal = lexer.stringVal();
for (; ; ) {
if (Token.SEMI.equals(lexer.token())) {
stmt.setAfterSemi(true);
return stmt;
}
if (Token.EOF == lexer.token()) {
return stmt;
}
if (strVal.equalsIgnoreCase("VERBOSE")) {
stmt.setVerbose(true);
lexer.nextToken();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -371,23 +371,25 @@ public boolean visit(SQLSelect x) {
print0(ucase ? "FOR BROWSE" : "for browse");
}

if (x.getForXmlOptionsSize() > 0) {
if (x.getForXmlOptionsSize() > 0 || x.getXmlPath() != null) {
println();
print0(ucase ? "FOR XML " : "for xml ");

boolean first = true;
if (x.getXmlPath() != null) {
x.getXmlPath().accept(this);
first = false;
}

for (int i = 0; i < x.getForXmlOptions().size(); ++i) {
if (i != 0) {
if (!first) {
print0(", ");
print0(x.getForXmlOptions().get(i));
}
print0(x.getForXmlOptions().get(i));
first = false;
}
}

if (x.getXmlPath() != null) {
println();
print0(ucase ? "FOR XML " : "for xml ");
x.getXmlPath().accept(this);
}

if (x.getOffset() != null) {
println();
print0(ucase ? "OFFSET " : "offset ");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ public class Keywords {
sqlitemap.put("MERGE", Token.MERGE);
sqlitemap.put("MATCHED", Token.MATCHED);
sqlitemap.put("USING", Token.USING);
sqlitemap.put("IDENTITY", Token.IDENTITY);
DM_KEYWORDS = new Keywords(sqlitemap);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1984,7 +1984,7 @@ protected SQLExpr methodRest(SQLExpr expr, boolean acceptLPAREN) {
if (lexer.token == Token.OVER) {
if (aggregateExpr == null) {
aggregateExpr = new SQLAggregateExpr(methodName);
aggregateExpr.getArguments().addAll(methodInvokeExpr.getArguments());
aggregateExpr.addArguments(methodInvokeExpr.getArguments());
}
over(aggregateExpr);
}
Expand Down Expand Up @@ -4878,6 +4878,21 @@ public SQLColumnDefinition parseColumnRest(SQLColumnDefinition column) {
SQLColumnCheck check = parseColumnCheck();
column.addConstraint(check);
return parseColumnRest(column);
case IDENTITY: {
lexer.nextToken();
SQLColumnDefinition.Identity identity = new SQLColumnDefinition.Identity();
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
SQLIntegerExpr seed = (SQLIntegerExpr) this.primary();
accept(Token.COMMA);
SQLIntegerExpr increment = (SQLIntegerExpr) this.primary();
accept(Token.RPAREN);
identity.setSeed((Integer) seed.getNumber());
identity.setIncrement((Integer) increment.getNumber());
}
column.setIdentity(identity);
return parseColumnRest(column);
}
case IDENTIFIER:
long hash = lexer.hashLCase();
if (hash == FnvHash.Constants.AUTO_INCREMENT) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1237,6 +1237,13 @@ public SQLTableSource parseTableSource(boolean forFrom) {
this.exprParser.names(values.getColumns(), values);
accept(Token.RPAREN);
}
} else if (tableSource instanceof SQLUnionQueryTableSource) {
SQLUnionQueryTableSource union = (SQLUnionQueryTableSource) tableSource;
if (lexer.token == Token.LPAREN) {
lexer.nextToken();
this.exprParser.names(union.getColumns(), union);
accept(Token.RPAREN);
}
}
}

Expand Down Expand Up @@ -1820,6 +1827,7 @@ public SQLTableSource parseTableSourceRest(SQLTableSource tableSource) {
SQLTableSource unnestTableSource = parseUnnestTableSource();
if (unnestTableSource != null) {
if (lexer.identifierEquals(FnvHash.Constants.CROSS)
|| lexer.token == Token.CROSS
|| lexer.token == Token.LEFT
|| lexer.token == Token.RIGHT
|| lexer.token == Token.COMMA
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.alibaba.druid.bvt.sql.bigquery;

import com.alibaba.druid.DbType;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.expr.SQLAggregateExpr;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
import org.junit.Test;

import static org.junit.Assert.assertSame;

public class AggregateTest {
@Test
public void test_agg() {
String sql = "SELECT lag(date(d,'Asia/Jakarta')) over(partition by id order by n) FROM t1";
SQLSelectStatement stmt = (SQLSelectStatement) SQLUtils.parseSingleStatement(sql, DbType.bigquery);
SQLSelectQueryBlock queryBlock = stmt.getSelect().getQueryBlock();
SQLAggregateExpr expr = (SQLAggregateExpr) queryBlock.getSelectList().get(0).getExpr();
assertSame(expr, expr.getArgument(0).getParent());
}

@Test
public void test_agg_1() {
String sql = "SELECT xx(date(d,'Asia/Jakarta')) over(partition by id order by n) FROM t1";
SQLSelectStatement stmt = (SQLSelectStatement) SQLUtils.parseSingleStatement(sql, DbType.bigquery);
SQLSelectQueryBlock queryBlock = stmt.getSelect().getQueryBlock();
SQLAggregateExpr expr = (SQLAggregateExpr) queryBlock.getSelectList().get(0).getExpr();
assertSame(expr, expr.getArgument(0).getParent());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.alibaba.druid.bvt.sql.dm;

import java.util.List;

import com.alibaba.druid.DbType;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.parser.SQLParserUtils;
import com.alibaba.druid.sql.parser.SQLStatementParser;

import org.junit.Test;

import static org.junit.Assert.assertEquals;

/**
* @see <a href="https://github.com/alibaba/druid/issues/6583">Issue来源</a>
*/
public class DM_IdentityTest {

@Test
public void test_identity() {
String sql = "CREATE TABLE TEST.TEST_CREATE (\n"
+ " id INT IDENTITY(1,1),\n"
+ " name VARCHAR(64) NOT NULL,\n"
+ " PRIMARY KEY (id)\n"
+ ")";
SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, DbType.dm);
List<SQLStatement> stmtList = parser.parseStatementList();
assertEquals(1, stmtList.size());
}

@Test
public void test_identity_with_not_null() {
String sql = "CREATE TABLE t (id INT IDENTITY(1,1) NOT NULL PRIMARY KEY, val VARCHAR(100))";
SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, DbType.dm);
List<SQLStatement> stmtList = parser.parseStatementList();
assertEquals(1, stmtList.size());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.alibaba.druid.bvt.sql.postgresql.issues;

import java.util.List;

import com.alibaba.druid.DbType;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.parser.SQLParserUtils;
import com.alibaba.druid.sql.parser.SQLStatementParser;

import org.junit.Test;

import static org.junit.Assert.assertEquals;

/**
* @see <a href="https://github.com/alibaba/druid/issues/6572">Issue来源</a>
*/
public class Issue6572 {

@Test
public void test_union_column_alias() {
String sql = "select * from (select 1 union all select 2) AS serise_table(time)";
SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, DbType.postgresql);
List<SQLStatement> stmtList = parser.parseStatementList();
assertEquals(1, stmtList.size());
String output = stmtList.get(0).toString();
// Verify column alias is preserved
assert output.contains("serise_table");
}

@Test
public void test_union_multiple_column_aliases() {
String sql = "select * from (select 1, 'a' union all select 2, 'b') AS t(id, name)";
SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, DbType.postgresql);
List<SQLStatement> stmtList = parser.parseStatementList();
assertEquals(1, stmtList.size());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.alibaba.druid.bvt.sql.postgresql.issues;

import java.util.List;

import com.alibaba.druid.DbType;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.parser.SQLParserUtils;
import com.alibaba.druid.sql.parser.SQLStatementParser;

import org.junit.Test;

import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertEquals;

/**
* @see <a href="https://github.com/alibaba/druid/issues/6573">Issue来源</a>
*/
public class Issue6573 {

@Test
public void test_order_by_collate() {
String sql = "SELECT * FROM t ORDER BY col COLLATE \"zh-Hans-x-icu\" DESC";
SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, DbType.postgresql);
List<SQLStatement> stmtList = parser.parseStatementList();
assertEquals(1, stmtList.size());
String output = stmtList.get(0).toString();
System.out.println("OUTPUT1: " + output.replace("\n", " | "));
assertTrue("COLLATE clause should be preserved, got: " + output, output.contains("COLLATE"));
}

@Test
public void test_order_by_cast_collate() {
// From the original issue - cast with COLLATE
String sql = "SELECT * FROM t ORDER BY col::text COLLATE \"zh-Hans-x-icu\" DESC LIMIT 10";
SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, DbType.postgresql);
List<SQLStatement> stmtList = parser.parseStatementList();
assertEquals(1, stmtList.size());
String output = stmtList.get(0).toString();
System.out.println("OUTPUT3: " + output.replace("\n", " | "));
assertTrue("COLLATE clause should be preserved in cast expr, got: " + output, output.contains("COLLATE"));
}

@Test
public void test_order_by_collate_simple() {
String sql = "SELECT * FROM t ORDER BY col COLLATE \"C\" DESC";
SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, DbType.postgresql);
List<SQLStatement> stmtList = parser.parseStatementList();
assertEquals(1, stmtList.size());
String output = stmtList.get(0).toString();
System.out.println("OUTPUT2: " + output.replace("\n", " | "));
assertTrue("COLLATE clause should be preserved, got: " + output, output.contains("COLLATE"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.alibaba.druid.bvt.sql.postgresql.issues;

import java.util.List;

import com.alibaba.druid.DbType;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.parser.SQLParserUtils;
import com.alibaba.druid.sql.parser.SQLStatementParser;

import org.junit.Test;

import static org.junit.Assert.assertEquals;

/**
* @see <a href="https://github.com/alibaba/druid/issues/6595">Issue来源</a>
*/
public class Issue6595 {

@Test
public void test_analyze_skip_locked() {
String sql = "ANALYZE SKIP_LOCKED";
SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, DbType.postgresql);
List<SQLStatement> stmtList = parser.parseStatementList();
assertEquals(1, stmtList.size());
}

@Test
public void test_analyze_verbose() {
String sql = "ANALYZE VERBOSE";
SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, DbType.postgresql);
List<SQLStatement> stmtList = parser.parseStatementList();
assertEquals(1, stmtList.size());
}

@Test
public void test_analyze_verbose_skip_locked() {
String sql = "ANALYZE VERBOSE SKIP_LOCKED";
SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, DbType.postgresql);
List<SQLStatement> stmtList = parser.parseStatementList();
assertEquals(1, stmtList.size());
}

@Test
public void test_analyze_verbose_table() {
String sql = "ANALYZE VERBOSE my_table";
SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, DbType.postgresql);
List<SQLStatement> stmtList = parser.parseStatementList();
assertEquals(1, stmtList.size());
}

@Test
public void test_analyze_bare() {
String sql = "ANALYZE";
SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, DbType.postgresql);
List<SQLStatement> stmtList = parser.parseStatementList();
assertEquals(1, stmtList.size());
}
}
Loading
Loading