mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
improved db2 sql parser, support db2 interval expr. for issue #2037
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid</artifactId>
|
||||
<version>1.1.5-SNAPSHOT</version>
|
||||
<version>1.1.5-preview_05</version>
|
||||
|
||||
<packaging>jar</packaging>
|
||||
<name>druid</name>
|
||||
@@ -279,6 +279,7 @@
|
||||
<version>1.6.0</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${java.home}/../Classes/jconsole.jar</systemPath>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
@@ -298,6 +299,7 @@
|
||||
<version>1.8.0</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${java.home}/../lib/jconsole.jar</systemPath>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -306,6 +308,7 @@
|
||||
<version>1.8.0</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${java.home}/../lib/tools.jar</systemPath>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
@@ -540,7 +543,7 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.calcite</groupId>
|
||||
<artifactId>calcite-core</artifactId>
|
||||
<version>1.13.0</version>
|
||||
<version>1.14.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -706,6 +709,12 @@
|
||||
<version>1.2.36</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.antlr</groupId>
|
||||
<artifactId>antlr4</artifactId>
|
||||
<version>4.7</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
@@ -248,7 +248,7 @@ public class SQLAggregateExpr extends SQLExprImpl implements Serializable, SQLRe
|
||||
}
|
||||
}
|
||||
|
||||
if (hash == FnvHash.Constants.WM_CONAT
|
||||
if (hash == FnvHash.Constants.WM_CONCAT
|
||||
|| hash == FnvHash.Constants.GROUP_CONCAT) {
|
||||
return SQLCharExpr.DEFAULT_DATA_TYPE;
|
||||
}
|
||||
|
||||
@@ -25,11 +25,16 @@ import java.util.List;
|
||||
public class SQLIntervalExpr extends SQLExprImpl {
|
||||
|
||||
private SQLExpr value;
|
||||
private SQLIntervalUnit unit;
|
||||
private SQLIntervalUnit unit;
|
||||
|
||||
public SQLIntervalExpr(){
|
||||
}
|
||||
|
||||
public SQLIntervalExpr(SQLExpr value, SQLIntervalUnit unit){
|
||||
setValue(value);
|
||||
this.unit = unit;
|
||||
}
|
||||
|
||||
public SQLIntervalExpr clone() {
|
||||
SQLIntervalExpr x = new SQLIntervalExpr();
|
||||
if (value != null) {
|
||||
|
||||
@@ -15,9 +15,11 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.ast.statement;
|
||||
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.SQLLimit;
|
||||
import com.alibaba.druid.sql.ast.SQLObjectImpl;
|
||||
import com.alibaba.druid.sql.ast.SQLOrderBy;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public class SQLUnionQuery extends SQLObjectImpl implements SQLSelectQuery {
|
||||
@@ -29,7 +31,8 @@ public class SQLUnionQuery extends SQLObjectImpl implements SQLSelectQuery {
|
||||
private SQLUnionOperator operator = SQLUnionOperator.UNION;
|
||||
private SQLOrderBy orderBy;
|
||||
|
||||
private SQLLimit limit;
|
||||
private SQLLimit limit;
|
||||
private String dbType;
|
||||
|
||||
public SQLUnionOperator getOperator() {
|
||||
return operator;
|
||||
@@ -133,6 +136,8 @@ public class SQLUnionQuery extends SQLObjectImpl implements SQLSelectQuery {
|
||||
x.setLimit(limit.clone());
|
||||
}
|
||||
|
||||
x.dbType = dbType;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
@@ -147,4 +152,17 @@ public class SQLUnionQuery extends SQLObjectImpl implements SQLSelectQuery {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getDbType() {
|
||||
return dbType;
|
||||
}
|
||||
|
||||
public void setDbType(String dbType) {
|
||||
this.dbType = dbType;
|
||||
}
|
||||
|
||||
public void output(StringBuffer buf) {
|
||||
SQLASTOutputVisitor visitor = SQLUtils.createOutputVisitor(buf, dbType);
|
||||
this.accept(visitor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,8 +17,14 @@ package com.alibaba.druid.sql.dialect.db2.ast;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLObject;
|
||||
import com.alibaba.druid.sql.dialect.db2.visitor.DB2ASTVisitor;
|
||||
import com.alibaba.druid.util.FnvHash;
|
||||
|
||||
|
||||
public interface DB2Object extends SQLObject {
|
||||
void accept0(DB2ASTVisitor visitor);
|
||||
|
||||
interface Constants {
|
||||
long CURRENT_DATE = FnvHash.fnv1a_64_lower("CURRENT DATE");
|
||||
long CURRENT_TIME = FnvHash.fnv1a_64_lower("CURRENT TIME");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ package com.alibaba.druid.sql.dialect.db2.parser;
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIntervalExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIntervalUnit;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLSequenceExpr;
|
||||
import com.alibaba.druid.sql.parser.Lexer;
|
||||
import com.alibaba.druid.sql.parser.SQLExprParser;
|
||||
@@ -93,9 +95,42 @@ public class DB2ExprParser extends SQLExprParser {
|
||||
if (identExpr.hashCode64() == FnvHash.Constants.CURRENT) {
|
||||
lexer.nextToken();
|
||||
|
||||
expr = new SQLIdentifierExpr("CURRENT DATE");
|
||||
expr = new SQLIdentifierExpr("CURRENT TIMESTAMP");
|
||||
}
|
||||
}
|
||||
} else if (lexer.identifierEquals(FnvHash.Constants.TIME)) {
|
||||
if (expr instanceof SQLIdentifierExpr) {
|
||||
SQLIdentifierExpr identExpr = (SQLIdentifierExpr) expr;
|
||||
if (identExpr.hashCode64() == FnvHash.Constants.CURRENT) {
|
||||
lexer.nextToken();
|
||||
|
||||
expr = new SQLIdentifierExpr("CURRENT TIME");
|
||||
}
|
||||
}
|
||||
} else if (lexer.identifierEquals(FnvHash.Constants.MONTHS)) {
|
||||
SQLIntervalExpr intervalExpr = new SQLIntervalExpr(expr, SQLIntervalUnit.MONTH);
|
||||
lexer.nextToken();
|
||||
expr = intervalExpr;
|
||||
} else if (lexer.identifierEquals(FnvHash.Constants.YEARS)) {
|
||||
SQLIntervalExpr intervalExpr = new SQLIntervalExpr(expr, SQLIntervalUnit.YEAR);
|
||||
lexer.nextToken();
|
||||
expr = intervalExpr;
|
||||
} else if (lexer.identifierEquals(FnvHash.Constants.DAYS)) {
|
||||
SQLIntervalExpr intervalExpr = new SQLIntervalExpr(expr, SQLIntervalUnit.DAY);
|
||||
lexer.nextToken();
|
||||
expr = intervalExpr;
|
||||
} else if (lexer.identifierEquals(FnvHash.Constants.HOURS)) {
|
||||
SQLIntervalExpr intervalExpr = new SQLIntervalExpr(expr, SQLIntervalUnit.HOUR);
|
||||
lexer.nextToken();
|
||||
expr = intervalExpr;
|
||||
} else if (lexer.identifierEquals(FnvHash.Constants.MINUTES)) {
|
||||
SQLIntervalExpr intervalExpr = new SQLIntervalExpr(expr, SQLIntervalUnit.MINUTE);
|
||||
lexer.nextToken();
|
||||
expr = intervalExpr;
|
||||
} else if (lexer.identifierEquals(FnvHash.Constants.SECONDS)) {
|
||||
SQLIntervalExpr intervalExpr = new SQLIntervalExpr(expr, SQLIntervalUnit.SECOND);
|
||||
lexer.nextToken();
|
||||
expr = intervalExpr;
|
||||
}
|
||||
|
||||
return super.primaryRest(expr);
|
||||
|
||||
@@ -22,15 +22,18 @@ import com.alibaba.druid.sql.ast.statement.SQLSelectQuery;
|
||||
import com.alibaba.druid.sql.dialect.db2.ast.stmt.DB2SelectQueryBlock;
|
||||
import com.alibaba.druid.sql.dialect.db2.ast.stmt.DB2SelectQueryBlock.Isolation;
|
||||
import com.alibaba.druid.sql.parser.*;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
|
||||
public class DB2SelectParser extends SQLSelectParser {
|
||||
|
||||
public DB2SelectParser(SQLExprParser exprParser){
|
||||
super(exprParser);
|
||||
dbType = JdbcConstants.DB2;
|
||||
}
|
||||
|
||||
public DB2SelectParser(SQLExprParser exprParser, SQLSelectListCache selectListCache){
|
||||
super(exprParser, selectListCache);
|
||||
dbType = JdbcConstants.DB2;
|
||||
}
|
||||
|
||||
public DB2SelectParser(String sql){
|
||||
|
||||
@@ -15,9 +15,12 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.dialect.db2.visitor;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.SQLPartitionBy;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIntervalExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIntervalUnit;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
|
||||
import com.alibaba.druid.sql.dialect.db2.ast.stmt.DB2CreateTableStatement;
|
||||
@@ -143,4 +146,17 @@ public class DB2OutputVisitor extends SQLASTOutputVisitor implements DB2ASTVisit
|
||||
print0(ucase ? operator.name : operator.name_lcase);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean visit(SQLIntervalExpr x) {
|
||||
SQLExpr value = x.getValue();
|
||||
value.accept(this);
|
||||
|
||||
SQLIntervalUnit unit = x.getUnit();
|
||||
if (unit != null) {
|
||||
print(' ');
|
||||
print0(ucase ? unit.name() : unit.name_lcase);
|
||||
print(ucase ? 'S' : 's');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.alibaba.druid.sql.dialect.db2.visitor;
|
||||
|
||||
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
|
||||
import com.alibaba.druid.sql.dialect.db2.ast.DB2Object;
|
||||
import com.alibaba.druid.sql.dialect.db2.ast.stmt.DB2CreateTableStatement;
|
||||
import com.alibaba.druid.sql.dialect.db2.ast.stmt.DB2SelectQueryBlock;
|
||||
import com.alibaba.druid.sql.dialect.db2.ast.stmt.DB2ValuesStatement;
|
||||
@@ -57,4 +58,8 @@ public class DB2SchemaStatVisitor extends SchemaStatVisitor implements DB2ASTVis
|
||||
public void endVisit(DB2CreateTableStatement x) {
|
||||
|
||||
}
|
||||
|
||||
protected boolean isPseudoColumn(long hash64) {
|
||||
return hash64 == DB2Object.Constants.CURRENT_DATE || hash64 == DB2Object.Constants.CURRENT_TIME;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1035,7 +1035,7 @@ public class SQLExprParser extends SQLParser {
|
||||
}
|
||||
|
||||
if (lexer.token == Token.LPAREN) {
|
||||
expr = methodRest(expr, name);
|
||||
expr = methodRest(expr, name, false);
|
||||
} else {
|
||||
expr = new SQLPropertyExpr(expr, name, hash_lower);
|
||||
}
|
||||
@@ -1045,7 +1045,7 @@ public class SQLExprParser extends SQLParser {
|
||||
return expr;
|
||||
}
|
||||
|
||||
private SQLExpr methodRest(SQLExpr expr, String name) {
|
||||
private SQLExpr methodRest(SQLExpr expr, String name, boolean aggregate) {
|
||||
lexer.nextToken();
|
||||
|
||||
if (lexer.token == Token.DISTINCT) {
|
||||
@@ -1066,6 +1066,21 @@ public class SQLExprParser extends SQLParser {
|
||||
accept(Token.RPAREN);
|
||||
}
|
||||
expr = aggregateExpr;
|
||||
} else if (aggregate) {
|
||||
SQLAggregateExpr methodInvokeExpr = new SQLAggregateExpr(name);
|
||||
methodInvokeExpr.setMethodName(expr.toString() + "." + name);
|
||||
if (lexer.token == Token.RPAREN) {
|
||||
lexer.nextToken();
|
||||
} else {
|
||||
if (lexer.token == Token.PLUS) {
|
||||
methodInvokeExpr.addArgument(new SQLIdentifierExpr("+"));
|
||||
lexer.nextToken();
|
||||
} else {
|
||||
exprList(methodInvokeExpr.getArguments(), methodInvokeExpr);
|
||||
}
|
||||
accept(Token.RPAREN);
|
||||
}
|
||||
expr = methodInvokeExpr;
|
||||
} else {
|
||||
SQLMethodInvokeExpr methodInvokeExpr = new SQLMethodInvokeExpr(name);
|
||||
methodInvokeExpr.setOwner(expr);
|
||||
@@ -2657,7 +2672,8 @@ public class SQLExprParser extends SQLParser {
|
||||
|
||||
token = lexer.token;
|
||||
if (token == Token.LPAREN) {
|
||||
expr = methodRest(expr, name);
|
||||
boolean aggregate = hash_lower == FnvHash.Constants.WMSYS && name_hash_lower == FnvHash.Constants.WM_CONCAT;
|
||||
expr = methodRest(expr, name, aggregate);
|
||||
token = lexer.token;
|
||||
} else {
|
||||
if (name_hash_lower == FnvHash.Constants.NEXTVAL) {
|
||||
|
||||
@@ -84,7 +84,9 @@ public class SQLSelectParser extends SQLParser {
|
||||
}
|
||||
|
||||
protected SQLUnionQuery createSQLUnionQuery() {
|
||||
return new SQLUnionQuery();
|
||||
SQLUnionQuery union = new SQLUnionQuery();
|
||||
union.setDbType(getDbType());
|
||||
return union;
|
||||
}
|
||||
|
||||
public SQLUnionQuery unionRest(SQLUnionQuery union) {
|
||||
|
||||
@@ -19,6 +19,7 @@ import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.*;
|
||||
import com.alibaba.druid.sql.ast.expr.*;
|
||||
import com.alibaba.druid.sql.ast.statement.*;
|
||||
import com.alibaba.druid.sql.dialect.db2.ast.DB2Object;
|
||||
import com.alibaba.druid.sql.dialect.db2.ast.stmt.DB2SelectQueryBlock;
|
||||
import com.alibaba.druid.sql.dialect.db2.visitor.DB2ASTVisitorAdapter;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.MysqlForeignKey;
|
||||
@@ -230,8 +231,6 @@ class SchemaResolveVisitorFactory {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static class DB2ResolveVisitor extends DB2ASTVisitorAdapter implements SchemaResolveVisitor {
|
||||
private SchemaRepository repository;
|
||||
private int options;
|
||||
@@ -283,6 +282,11 @@ class SchemaResolveVisitorFactory {
|
||||
}
|
||||
|
||||
public boolean visit(SQLIdentifierExpr x) {
|
||||
long hash64 = x.hashCode64();
|
||||
if (hash64 == DB2Object.Constants.CURRENT_DATE || hash64 == DB2Object.Constants.CURRENT_TIME) {
|
||||
return false;
|
||||
}
|
||||
|
||||
resolve(this, x);
|
||||
return true;
|
||||
}
|
||||
@@ -1684,7 +1688,7 @@ class SchemaResolveVisitorFactory {
|
||||
|
||||
if (ctxTable instanceof SQLJoinTableSource) {
|
||||
String alias = tableSource.computeAlias();
|
||||
if (alias == null) {
|
||||
if (alias == null || tableSource instanceof SQLWithSubqueryClause.Entry) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -350,6 +350,7 @@ public final class FnvHash {
|
||||
|
||||
long DATE = fnv1a_64_lower("DATE");
|
||||
long DATETIME = fnv1a_64_lower("DATETIME");
|
||||
long TIME = fnv1a_64_lower("TIME");
|
||||
long TIMESTAMP = fnv1a_64_lower("TIMESTAMP");
|
||||
long CLOB = fnv1a_64_lower("CLOB");
|
||||
long NCLOB = fnv1a_64_lower("NCLOB");
|
||||
@@ -371,7 +372,7 @@ public final class FnvHash {
|
||||
long CURRENT = fnv1a_64_lower("CURRENT");
|
||||
long COUNT = fnv1a_64_lower("COUNT");
|
||||
long ROW_NUMBER = fnv1a_64_lower("ROW_NUMBER");
|
||||
long WM_CONAT = fnv1a_64_lower("WM_CONAT");
|
||||
long WM_CONCAT = fnv1a_64_lower("WM_CONCAT");
|
||||
long AVG = fnv1a_64_lower("AVG");
|
||||
long MAX = fnv1a_64_lower("MAX");
|
||||
long MIN = fnv1a_64_lower("MIN");
|
||||
@@ -472,6 +473,13 @@ public final class FnvHash {
|
||||
long MINUTE = fnv1a_64_lower("MINUTE");
|
||||
long SECOND = fnv1a_64_lower("SECOND");
|
||||
|
||||
long SECONDS = fnv1a_64_lower("SECONDS");
|
||||
long MINUTES = fnv1a_64_lower("MINUTES");
|
||||
long HOURS = fnv1a_64_lower("HOURS");
|
||||
long DAYS = fnv1a_64_lower("DAYS");
|
||||
long MONTHS = fnv1a_64_lower("MONTHS");
|
||||
long YEARS = fnv1a_64_lower("YEARS");
|
||||
|
||||
long BEFORE = fnv1a_64_lower("BEFORE");
|
||||
long AFTER = fnv1a_64_lower("AFTER");
|
||||
long INSTEAD = fnv1a_64_lower("INSTEAD");
|
||||
@@ -515,5 +523,6 @@ public final class FnvHash {
|
||||
long VALIDPROC = fnv1a_64_lower("VALIDPROC");
|
||||
long COMPRESS = fnv1a_64_lower("COMPRESS");
|
||||
long YES = fnv1a_64_lower("YES");
|
||||
long WMSYS = fnv1a_64_lower("WMSYS");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Copyright 1999-2017 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.bvt.sql.db2;
|
||||
|
||||
import com.alibaba.druid.sql.DB2Test;
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
|
||||
import com.alibaba.druid.sql.dialect.db2.parser.DB2StatementParser;
|
||||
import com.alibaba.druid.sql.dialect.db2.visitor.DB2SchemaStatVisitor;
|
||||
import com.alibaba.druid.stat.TableStat;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
import org.junit.Assert;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class DB2SelectTest_26 extends DB2Test {
|
||||
|
||||
public void test_0() throws Exception {
|
||||
String sql = "SELECT LATN_ID,\n" +
|
||||
"CASE WHEN BUREAU_KEY = 116 THEN 46 ELSE BUREAU_KEY END BUREAU_KEY,\n" +
|
||||
"SUM(COALESCE(ADD_USER_CNT, 0)) ADD_SUM,\n" +
|
||||
"0 USER_ACCT,\n" +
|
||||
"0 USER_ACCT_LY\n" +
|
||||
"FROM MK.M_BROAD_BAND_USER_FACT\n" +
|
||||
"WHERE THE_DATE BETWEEN SUBSTR('{THISMONTH}', 1, 4) || '-01-01' AND '{THISMONTH}'\n" +
|
||||
"GROUP BY LATN_ID,\n" +
|
||||
"CASE WHEN BUREAU_KEY = 116 THEN 46 ELSE BUREAU_KEY END\n" +
|
||||
"UNION ALL\n" +
|
||||
"SELECT LATN_ID,\n" +
|
||||
"CASE WHEN BUREAU_KEY = 116 THEN 46 ELSE BUREAU_KEY END BUREAU_KEY,\n" +
|
||||
"0 ADD_SUM,\n" +
|
||||
"SUM(COALESCE(BILL_USER_CNT, 0)) USER_ACCT,\n" +
|
||||
"0 USER_ACCT_LY\n" +
|
||||
"FROM MK.M_BROAD_BAND_USER_FACT\n" +
|
||||
"WHERE THE_DATE = '{THISMONTH}'\n" +
|
||||
"GROUP BY LATN_ID,\n" +
|
||||
"CASE WHEN BUREAU_KEY = 116 THEN 46 ELSE BUREAU_KEY END\n" +
|
||||
"UNION ALL\n" +
|
||||
"SELECT LATN_ID,\n" +
|
||||
"CASE WHEN BUREAU_KEY = 116 THEN 46 ELSE BUREAU_KEY END BUREAU_KEY,\n" +
|
||||
"0 ADD_SUM,\n" +
|
||||
"0 USER_ACCT,\n" +
|
||||
"SUM(COALESCE(BILL_USER_CNT, 0)) USER_ACCT_LY\n" +
|
||||
"FROM MK.M_BROAD_BAND_USER_FACT\n" +
|
||||
"WHERE THE_DATE = DATE(SUBSTR('{THISMONTH}', 1, 4) || '-01-01') - 1 MONTHS\n" +
|
||||
"GROUP BY LATN_ID,\n" +
|
||||
"CASE WHEN BUREAU_KEY = 116 THEN 46 ELSE BUREAU_KEY END";
|
||||
|
||||
DB2StatementParser parser = new DB2StatementParser(sql);
|
||||
List<SQLStatement> statementList = parser.parseStatementList();
|
||||
SQLSelectStatement stmt = (SQLSelectStatement) statementList.get(0);
|
||||
System.out.println(stmt.getSelect().getQuery());
|
||||
|
||||
Assert.assertEquals(1, statementList.size());
|
||||
|
||||
DB2SchemaStatVisitor visitor = new DB2SchemaStatVisitor();
|
||||
stmt.accept(visitor);
|
||||
|
||||
System.out.println("Tables : " + visitor.getTables());
|
||||
// System.out.println("fields : " + visitor.getColumns());
|
||||
// System.out.println("coditions : " + visitor.getConditions());
|
||||
// System.out.println("orderBy : " + visitor.getOrderByColumns());
|
||||
|
||||
Assert.assertEquals(1, visitor.getTables().size());
|
||||
Assert.assertEquals(5, visitor.getColumns().size());
|
||||
Assert.assertEquals(2, visitor.getConditions().size());
|
||||
|
||||
Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("MK.M_BROAD_BAND_USER_FACT")));
|
||||
|
||||
// Assert.assertTrue(visitor.getColumns().contains(new Column("DSN8B10.EMP", "WORKDEPT")));
|
||||
// Assert.assertTrue(visitor.getColumns().contains(new Column("mytable", "first_name")));
|
||||
// Assert.assertTrue(visitor.getColumns().contains(new Column("mytable", "full_name")));
|
||||
|
||||
Assert.assertEquals("SELECT LATN_ID\n" +
|
||||
"\t, CASE \n" +
|
||||
"\t\tWHEN BUREAU_KEY = 116 THEN 46\n" +
|
||||
"\t\tELSE BUREAU_KEY\n" +
|
||||
"\tEND AS BUREAU_KEY, SUM(COALESCE(ADD_USER_CNT, 0)) AS ADD_SUM\n" +
|
||||
"\t, 0 AS USER_ACCT, 0 AS USER_ACCT_LY\n" +
|
||||
"FROM MK.M_BROAD_BAND_USER_FACT\n" +
|
||||
"WHERE THE_DATE BETWEEN SUBSTR('{THISMONTH}', 1, 4) CONCAT '-01-01' AND '{THISMONTH}'\n" +
|
||||
"GROUP BY LATN_ID, CASE \n" +
|
||||
"\t\tWHEN BUREAU_KEY = 116 THEN 46\n" +
|
||||
"\t\tELSE BUREAU_KEY\n" +
|
||||
"\tEND\n" +
|
||||
"UNION ALL\n" +
|
||||
"SELECT LATN_ID\n" +
|
||||
"\t, CASE \n" +
|
||||
"\t\tWHEN BUREAU_KEY = 116 THEN 46\n" +
|
||||
"\t\tELSE BUREAU_KEY\n" +
|
||||
"\tEND AS BUREAU_KEY, 0 AS ADD_SUM\n" +
|
||||
"\t, SUM(COALESCE(BILL_USER_CNT, 0)) AS USER_ACCT\n" +
|
||||
"\t, 0 AS USER_ACCT_LY\n" +
|
||||
"FROM MK.M_BROAD_BAND_USER_FACT\n" +
|
||||
"WHERE THE_DATE = '{THISMONTH}'\n" +
|
||||
"GROUP BY LATN_ID, CASE \n" +
|
||||
"\t\tWHEN BUREAU_KEY = 116 THEN 46\n" +
|
||||
"\t\tELSE BUREAU_KEY\n" +
|
||||
"\tEND\n" +
|
||||
"UNION ALL\n" +
|
||||
"SELECT LATN_ID\n" +
|
||||
"\t, CASE \n" +
|
||||
"\t\tWHEN BUREAU_KEY = 116 THEN 46\n" +
|
||||
"\t\tELSE BUREAU_KEY\n" +
|
||||
"\tEND AS BUREAU_KEY, 0 AS ADD_SUM, 0 AS USER_ACCT\n" +
|
||||
"\t, SUM(COALESCE(BILL_USER_CNT, 0)) AS USER_ACCT_LY\n" +
|
||||
"FROM MK.M_BROAD_BAND_USER_FACT\n" +
|
||||
"WHERE THE_DATE = DATE(SUBSTR('{THISMONTH}', 1, 4) CONCAT '-01-01') - 1 MONTHS\n" +
|
||||
"GROUP BY LATN_ID, CASE \n" +
|
||||
"\t\tWHEN BUREAU_KEY = 116 THEN 46\n" +
|
||||
"\t\tELSE BUREAU_KEY\n" +
|
||||
"\tEND", //
|
||||
SQLUtils.toSQLString(stmt, JdbcConstants.DB2));
|
||||
|
||||
Assert.assertEquals("select LATN_ID\n" +
|
||||
"\t, case \n" +
|
||||
"\t\twhen BUREAU_KEY = 116 then 46\n" +
|
||||
"\t\telse BUREAU_KEY\n" +
|
||||
"\tend as BUREAU_KEY, sum(COALESCE(ADD_USER_CNT, 0)) as ADD_SUM\n" +
|
||||
"\t, 0 as USER_ACCT, 0 as USER_ACCT_LY\n" +
|
||||
"from MK.M_BROAD_BAND_USER_FACT\n" +
|
||||
"where THE_DATE between SUBSTR('{THISMONTH}', 1, 4) concat '-01-01' and '{THISMONTH}'\n" +
|
||||
"group by LATN_ID, case \n" +
|
||||
"\t\twhen BUREAU_KEY = 116 then 46\n" +
|
||||
"\t\telse BUREAU_KEY\n" +
|
||||
"\tend\n" +
|
||||
"union all\n" +
|
||||
"select LATN_ID\n" +
|
||||
"\t, case \n" +
|
||||
"\t\twhen BUREAU_KEY = 116 then 46\n" +
|
||||
"\t\telse BUREAU_KEY\n" +
|
||||
"\tend as BUREAU_KEY, 0 as ADD_SUM\n" +
|
||||
"\t, sum(COALESCE(BILL_USER_CNT, 0)) as USER_ACCT\n" +
|
||||
"\t, 0 as USER_ACCT_LY\n" +
|
||||
"from MK.M_BROAD_BAND_USER_FACT\n" +
|
||||
"where THE_DATE = '{THISMONTH}'\n" +
|
||||
"group by LATN_ID, case \n" +
|
||||
"\t\twhen BUREAU_KEY = 116 then 46\n" +
|
||||
"\t\telse BUREAU_KEY\n" +
|
||||
"\tend\n" +
|
||||
"union all\n" +
|
||||
"select LATN_ID\n" +
|
||||
"\t, case \n" +
|
||||
"\t\twhen BUREAU_KEY = 116 then 46\n" +
|
||||
"\t\telse BUREAU_KEY\n" +
|
||||
"\tend as BUREAU_KEY, 0 as ADD_SUM, 0 as USER_ACCT\n" +
|
||||
"\t, sum(COALESCE(BILL_USER_CNT, 0)) as USER_ACCT_LY\n" +
|
||||
"from MK.M_BROAD_BAND_USER_FACT\n" +
|
||||
"where THE_DATE = DATE(SUBSTR('{THISMONTH}', 1, 4) concat '-01-01') - 1 months\n" +
|
||||
"group by LATN_ID, case \n" +
|
||||
"\t\twhen BUREAU_KEY = 116 then 46\n" +
|
||||
"\t\telse BUREAU_KEY\n" +
|
||||
"\tend", //
|
||||
SQLUtils.toSQLString(stmt, JdbcConstants.DB2, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 1999-2017 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.bvt.sql.db2;
|
||||
|
||||
import com.alibaba.druid.sql.DB2Test;
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
|
||||
import com.alibaba.druid.sql.dialect.db2.parser.DB2StatementParser;
|
||||
import com.alibaba.druid.sql.dialect.db2.visitor.DB2SchemaStatVisitor;
|
||||
import com.alibaba.druid.stat.TableStat;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
import org.junit.Assert;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class DB2SelectTest_27_interval extends DB2Test {
|
||||
|
||||
public void test_0() throws Exception {
|
||||
String sql = "SELECT current date + 1 YEAR, current date + 3 YEARS + 2 MONTHS + 15 DAYS, current time + 5 HOURS - 3 MINUTES + 10 SECONDS from sysibm.sysdummy1";
|
||||
|
||||
DB2StatementParser parser = new DB2StatementParser(sql);
|
||||
List<SQLStatement> statementList = parser.parseStatementList();
|
||||
SQLSelectStatement stmt = (SQLSelectStatement) statementList.get(0);
|
||||
System.out.println(stmt.getSelect().getQuery());
|
||||
|
||||
Assert.assertEquals(1, statementList.size());
|
||||
|
||||
DB2SchemaStatVisitor visitor = new DB2SchemaStatVisitor();
|
||||
stmt.accept(visitor);
|
||||
|
||||
System.out.println("Tables : " + visitor.getTables());
|
||||
System.out.println("fields : " + visitor.getColumns());
|
||||
// System.out.println("coditions : " + visitor.getConditions());
|
||||
// System.out.println("orderBy : " + visitor.getOrderByColumns());
|
||||
|
||||
Assert.assertEquals(1, visitor.getTables().size());
|
||||
Assert.assertEquals(0, visitor.getColumns().size());
|
||||
Assert.assertEquals(0, visitor.getConditions().size());
|
||||
|
||||
Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("sysibm.sysdummy1")));
|
||||
|
||||
// Assert.assertTrue(visitor.getColumns().contains(new Column("DSN8B10.EMP", "WORKDEPT")));
|
||||
// Assert.assertTrue(visitor.getColumns().contains(new Column("mytable", "first_name")));
|
||||
// Assert.assertTrue(visitor.getColumns().contains(new Column("mytable", "full_name")));
|
||||
|
||||
Assert.assertEquals("SELECT CURRENT DATE + 1 AS YEAR\n" +
|
||||
"\t, CURRENT DATE + 3 YEARS + 2 MONTHS + 15 DAYS\n" +
|
||||
"\t, CURRENT TIME + 5 HOURS - 3 MINUTES + 10 SECONDS\n" +
|
||||
"FROM sysibm.sysdummy1", //
|
||||
SQLUtils.toSQLString(stmt, JdbcConstants.DB2));
|
||||
|
||||
Assert.assertEquals("select CURRENT DATE + 1 as YEAR\n" +
|
||||
"\t, CURRENT DATE + 3 years + 2 months + 15 days\n" +
|
||||
"\t, CURRENT TIME + 5 hours - 3 minutes + 10 seconds\n" +
|
||||
"from sysibm.sysdummy1", //
|
||||
SQLUtils.toSQLString(stmt, JdbcConstants.DB2, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user