mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
improved hive sql parser. for issue #2051
This commit is contained in:
@@ -27,6 +27,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.MySqlUnique;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlTableIndex;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
import com.alibaba.druid.util.FnvHash;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
import com.alibaba.druid.util.ListDG;
|
||||
import com.alibaba.druid.util.lang.Consumer;
|
||||
|
||||
@@ -52,6 +53,7 @@ public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLS
|
||||
|
||||
protected SQLName tablespace;
|
||||
protected SQLPartitionBy partitioning;
|
||||
protected SQLName storedAs;
|
||||
|
||||
public SQLCreateTableStatement(){
|
||||
|
||||
@@ -978,6 +980,17 @@ public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLS
|
||||
}
|
||||
}
|
||||
|
||||
public SQLName getStoredAs() {
|
||||
return storedAs;
|
||||
}
|
||||
|
||||
public void setStoredAs(SQLName x) {
|
||||
if (x != null) {
|
||||
x.setParent(this);
|
||||
}
|
||||
this.storedAs = x;
|
||||
}
|
||||
|
||||
public SQLCreateTableStatement clone() {
|
||||
SQLCreateTableStatement x = new SQLCreateTableStatement(dbType);
|
||||
cloneTo(x);
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
package com.alibaba.druid.sql.dialect.hive.parser;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.statement.*;
|
||||
import com.alibaba.druid.sql.dialect.hive.stmt.HiveCreateTableStatement;
|
||||
import com.alibaba.druid.sql.parser.*;
|
||||
import com.alibaba.druid.util.FnvHash;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
|
||||
public class HiveCreateTableParser extends SQLCreateTableParser {
|
||||
public HiveCreateTableParser(SQLExprParser exprParser) {
|
||||
super(exprParser);
|
||||
}
|
||||
|
||||
public SQLCreateTableStatement parseCreateTable(boolean acceptCreate) {
|
||||
HiveCreateTableStatement stmt = newCreateStatement();
|
||||
|
||||
if (acceptCreate) {
|
||||
if (lexer.hasComment() && lexer.isKeepComments()) {
|
||||
stmt.addBeforeComment(lexer.readAndResetComments());
|
||||
}
|
||||
|
||||
accept(Token.CREATE);
|
||||
}
|
||||
|
||||
if (lexer.identifierEquals("GLOBAL")) {
|
||||
lexer.nextToken();
|
||||
|
||||
if (lexer.identifierEquals("TEMPORARY")) {
|
||||
lexer.nextToken();
|
||||
stmt.setType(SQLCreateTableStatement.Type.GLOBAL_TEMPORARY);
|
||||
} else {
|
||||
throw new ParserException("syntax error " + lexer.info());
|
||||
}
|
||||
} else if (lexer.token() == Token.IDENTIFIER && lexer.stringVal().equalsIgnoreCase("LOCAL")) {
|
||||
lexer.nextToken();
|
||||
if (lexer.token() == Token.IDENTIFIER && lexer.stringVal().equalsIgnoreCase("TEMPORAY")) {
|
||||
lexer.nextToken();
|
||||
stmt.setType(SQLCreateTableStatement.Type.LOCAL_TEMPORARY);
|
||||
} else {
|
||||
throw new ParserException("syntax error. " + lexer.info());
|
||||
}
|
||||
}
|
||||
|
||||
accept(Token.TABLE);
|
||||
|
||||
if (lexer.token() == Token.IF || lexer.identifierEquals("IF")) {
|
||||
lexer.nextToken();
|
||||
accept(Token.NOT);
|
||||
accept(Token.EXISTS);
|
||||
|
||||
stmt.setIfNotExiists(true);
|
||||
}
|
||||
|
||||
stmt.setName(this.exprParser.name());
|
||||
|
||||
if (lexer.token() == Token.LPAREN) {
|
||||
lexer.nextToken();
|
||||
|
||||
for (; ; ) {
|
||||
Token token = lexer.token();
|
||||
if (token == Token.IDENTIFIER
|
||||
&& lexer.stringVal().equalsIgnoreCase("SUPPLEMENTAL")
|
||||
&& JdbcConstants.ORACLE.equals(dbType)) {
|
||||
this.parseCreateTableSupplementalLogingProps(stmt);
|
||||
} else if (token == Token.IDENTIFIER //
|
||||
|| token == Token.LITERAL_ALIAS) {
|
||||
SQLColumnDefinition column = this.exprParser.parseColumn();
|
||||
stmt.getTableElementList().add(column);
|
||||
} else if (token == Token.PRIMARY //
|
||||
|| token == Token.UNIQUE //
|
||||
|| token == Token.CHECK //
|
||||
|| token == Token.CONSTRAINT
|
||||
|| token == Token.FOREIGN) {
|
||||
SQLConstraint constraint = this.exprParser.parseConstaint();
|
||||
constraint.setParent(stmt);
|
||||
stmt.getTableElementList().add((SQLTableElement) constraint);
|
||||
} else if (token == Token.TABLESPACE) {
|
||||
throw new ParserException("TODO " + lexer.info());
|
||||
} else {
|
||||
SQLColumnDefinition column = this.exprParser.parseColumn();
|
||||
stmt.getTableElementList().add(column);
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.COMMA) {
|
||||
lexer.nextToken();
|
||||
|
||||
if (lexer.token() == Token.RPAREN) { // compatible for sql server
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
accept(Token.RPAREN);
|
||||
|
||||
if (lexer.identifierEquals("INHERITS")) {
|
||||
lexer.nextToken();
|
||||
accept(Token.LPAREN);
|
||||
SQLName inherits = this.exprParser.name();
|
||||
stmt.setInherits(new SQLExprTableSource(inherits));
|
||||
accept(Token.RPAREN);
|
||||
}
|
||||
}
|
||||
|
||||
if (lexer.identifierEquals(FnvHash.Constants.STORED)) {
|
||||
lexer.nextToken();
|
||||
accept(Token.AS);
|
||||
SQLName name = this.exprParser.name();
|
||||
stmt.setStoredAs(name);
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.AS) {
|
||||
lexer.nextToken();
|
||||
SQLSelect select = this.createSQLSelectParser().select();
|
||||
stmt.setSelect(select);
|
||||
}
|
||||
|
||||
return stmt;
|
||||
}
|
||||
|
||||
protected HiveCreateTableStatement newCreateStatement() {
|
||||
return new HiveCreateTableStatement();
|
||||
}
|
||||
}
|
||||
@@ -20,10 +20,7 @@ import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLQueryExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLReplaceStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelect;
|
||||
import com.alibaba.druid.sql.parser.Lexer;
|
||||
import com.alibaba.druid.sql.parser.SQLParserFeature;
|
||||
import com.alibaba.druid.sql.parser.SQLStatementParser;
|
||||
import com.alibaba.druid.sql.parser.Token;
|
||||
import com.alibaba.druid.sql.parser.*;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
|
||||
public class HiveStatementParser extends SQLStatementParser {
|
||||
@@ -75,4 +72,8 @@ public class HiveStatementParser extends SQLStatementParser {
|
||||
|
||||
return stmt;
|
||||
}
|
||||
|
||||
public SQLCreateTableParser getSQLCreateTableParser() {
|
||||
return new HiveCreateTableParser(this.exprParser);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.alibaba.druid.sql.dialect.hive.stmt;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
|
||||
public class HiveCreateTableStatement extends SQLCreateTableStatement {
|
||||
public HiveCreateTableStatement() {
|
||||
this.dbType = JdbcConstants.HIVE;
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,9 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.dialect.hive.visitor;
|
||||
|
||||
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelect;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor;
|
||||
|
||||
import java.util.List;
|
||||
@@ -31,5 +34,4 @@ public class HiveOutputVisitor extends SQLASTOutputVisitor implements HiveASTVis
|
||||
public HiveOutputVisitor(Appendable appender, boolean parameterized) {
|
||||
super(appender, parameterized);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.parser;
|
||||
|
||||
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
|
||||
import com.alibaba.druid.sql.dialect.hive.stmt.HiveCreateTableStatement;
|
||||
|
||||
public class SQLParser {
|
||||
protected final Lexer lexer;
|
||||
protected String dbType;
|
||||
@@ -323,4 +326,8 @@ public class SQLParser {
|
||||
public final boolean isEnabled(SQLParserFeature feature) {
|
||||
return lexer.isEnabled(feature);
|
||||
}
|
||||
|
||||
protected SQLCreateTableStatement newCreateStatement() {
|
||||
return new SQLCreateTableStatement(getDbType());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2537,6 +2537,12 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
print(')');
|
||||
}
|
||||
|
||||
SQLName storedAs = x.getStoredAs();
|
||||
if (storedAs != null) {
|
||||
print0(ucase ? " STORE AS " : " store as ");
|
||||
printExpr(storedAs);
|
||||
}
|
||||
|
||||
SQLSelect select = x.getSelect();
|
||||
if (printSelect && select != null) {
|
||||
println();
|
||||
|
||||
Reference in New Issue
Block a user