improved h2 support, fix #3923

This commit is contained in:
高铁
2020-10-23 21:38:34 +08:00
parent aea896c35b
commit 243dc1a5c5
6 changed files with 100 additions and 5 deletions
@@ -15,9 +15,14 @@
*/
package com.alibaba.druid.sql.dialect.h2.parser;
import com.alibaba.druid.sql.ast.expr.SQLDefaultExpr;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr;
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
import com.alibaba.druid.sql.parser.Lexer;
import com.alibaba.druid.sql.parser.SQLExprParser;
import com.alibaba.druid.sql.parser.SQLParserFeature;
import com.alibaba.druid.sql.parser.Token;
import com.alibaba.druid.util.FnvHash;
import java.util.Arrays;
@@ -50,7 +55,42 @@ public class H2ExprParser extends SQLExprParser {
public H2ExprParser(Lexer lexer){
super(lexer);
dbType = lexer.getDbType();
this.aggregateFunctions = AGGREGATE_FUNCTIONS;
this.aggregateFunctionHashCodes = AGGREGATE_FUNCTIONS_CODES;
}
public SQLColumnDefinition parseColumnRest(SQLColumnDefinition column) {
column = super.parseColumnRest(column);
if (lexer.identifierEquals(FnvHash.Constants.GENERATED)) {
lexer.nextToken();
if (lexer.token() == Token.BY) {
lexer.nextToken();
accept(Token.DEFAULT);
column.setGeneratedAlawsAs(new SQLDefaultExpr());
} else {
acceptIdentifier("ALWAYS");
column.setGeneratedAlawsAs(new SQLIdentifierExpr("ALWAYS"));
}
accept(Token.AS);
acceptIdentifier("IDENTITY");
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 column;
}
}
@@ -15,6 +15,7 @@
*/
package com.alibaba.druid.sql.dialect.h2.parser;
import com.alibaba.druid.DbType;
import com.alibaba.druid.sql.parser.Keywords;
import com.alibaba.druid.sql.parser.Lexer;
import com.alibaba.druid.sql.parser.SQLParserFeature;
@@ -45,12 +46,12 @@ public class H2Lexer extends Lexer {
}
public H2Lexer(String input){
super(input);
super(input, null, DbType.h2);
super.keywods = DEFAULT_H2_KEYWORDS;
}
public H2Lexer(String input, SQLParserFeature... features){
super(input);
super(input, null, DbType.h2);
super.keywods = DEFAULT_H2_KEYWORDS;
for (SQLParserFeature feature : features) {
config(feature, true);
@@ -26,7 +26,7 @@ import java.util.List;
public class H2OutputVisitor extends SQLASTOutputVisitor implements H2ASTVisitor {
public H2OutputVisitor(Appendable appender) {
super(appender);
super(appender, DbType.h2);
}
public H2OutputVisitor(Appendable appender, DbType dbType) {
@@ -35,6 +35,7 @@ public class H2OutputVisitor extends SQLASTOutputVisitor implements H2ASTVisitor
public H2OutputVisitor(Appendable appender, boolean parameterized) {
super(appender, parameterized);
dbType = DbType.h2;
}
public boolean visit(SQLReplaceStatement x) {
@@ -33,6 +33,7 @@ public class SQLCreateTableParser extends SQLDDLParser {
public SQLCreateTableParser(SQLExprParser exprParser) {
super(exprParser);
dbType = exprParser.dbType;
}
public SQLCreateTableStatement parseCreateTable() {
@@ -51,6 +52,7 @@ public class SQLCreateTableParser extends SQLDDLParser {
public SQLCreateTableStatement parseCreateTable(boolean acceptCreate) {
SQLCreateTableStatement createTable = newCreateStatement();
createTable.setDbType(getDbType());
if (acceptCreate) {
if (lexer.hasComment() && lexer.isKeepComments()) {
@@ -108,7 +110,7 @@ public class SQLCreateTableParser extends SQLDDLParser {
createTable.getTableElementList().add(element);
} else if (token == Token.IDENTIFIER //
|| token == Token.LITERAL_ALIAS) {
SQLColumnDefinition column = this.exprParser.parseColumn();
SQLColumnDefinition column = this.exprParser.parseColumn(createTable);
column.setParent(createTable);
createTable.getTableElementList().add(column);
} else if (token == Token.PRIMARY //
@@ -3229,7 +3229,11 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
SQLColumnDefinition.Identity identity = x.getIdentity();
if (identity != null) {
print(' ');
if (dbType == DbType.h2) {
print0(ucase ? " AS " : " as ");
} else {
print(' ');
}
identity.accept(this);
}
@@ -0,0 +1,47 @@
/*
* 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.h2;
import com.alibaba.druid.DbType;
import com.alibaba.druid.sql.OracleTest;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor;
import com.alibaba.druid.util.JdbcConstants;
import org.junit.Assert;
import java.util.List;
public class H2_CreateTableTest_1 extends OracleTest {
public void test_0() throws Exception {
String sql = //
"CREATE TABLE tutorials_tbl ( \n" +
" id bigint generated by default as identity, \n" +
" title VARCHAR(50) NOT NULL, \n" +
" author VARCHAR(20) NOT NULL, \n" +
" submission_date DATE \n" +
");"; //
SQLStatement stmt = SQLUtils.parseSingleStatement(sql, DbType.h2);
assertEquals("CREATE TABLE tutorials_tbl (\n" +
"\tid bigint GENERATED ALWAYS AS DEFAULT AS IDENTITY,\n" +
"\ttitle VARCHAR(50) NOT NULL,\n" +
"\tauthor VARCHAR(20) NOT NULL,\n" +
"\tsubmission_date DATE\n" +
");", stmt.toString());
}
}