mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
improved hive sql parser support.
This commit is contained in:
@@ -60,6 +60,7 @@ public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLS
|
||||
protected boolean onCommitDeleteRows;
|
||||
|
||||
// for hive & odps
|
||||
protected SQLExternalRecordFormat rowFormat;
|
||||
protected final List<SQLColumnDefinition> partitionColumns = new ArrayList<SQLColumnDefinition>(2);
|
||||
protected final List<SQLName> clusteredBy = new ArrayList<SQLName>();
|
||||
protected final List<SQLSelectOrderByItem> sortedBy = new ArrayList<SQLSelectOrderByItem>();
|
||||
@@ -1094,4 +1095,15 @@ public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLS
|
||||
}
|
||||
this.partitionColumns.add(column);
|
||||
}
|
||||
|
||||
public SQLExternalRecordFormat getRowFormat() {
|
||||
return rowFormat;
|
||||
}
|
||||
|
||||
public void setRowFormat(SQLExternalRecordFormat x) {
|
||||
if (x != null) {
|
||||
x.setParent(this);
|
||||
}
|
||||
this.rowFormat = x;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.dialect.hive.parser;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.statement.*;
|
||||
import com.alibaba.druid.sql.dialect.hive.stmt.HiveCreateTableStatement;
|
||||
@@ -120,6 +121,11 @@ public class HiveCreateTableParser extends SQLCreateTableParser {
|
||||
}
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.COMMENT) {
|
||||
lexer.nextToken();
|
||||
SQLExpr comment = this.exprParser.expr();
|
||||
stmt.setComment(comment);
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.PARTITIONED) {
|
||||
lexer.nextToken();
|
||||
@@ -159,6 +165,23 @@ public class HiveCreateTableParser extends SQLCreateTableParser {
|
||||
accept(Token.RPAREN);
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.ROW) {
|
||||
lexer.nextToken();
|
||||
acceptIdentifier("FORMAT");
|
||||
|
||||
if (lexer.identifierEquals(FnvHash.Constants.DELIMITED)) {
|
||||
lexer.nextToken();
|
||||
acceptIdentifier("FIELDS");
|
||||
acceptIdentifier("TERMINATED");
|
||||
accept(Token.BY);
|
||||
SQLExternalRecordFormat format = new SQLExternalRecordFormat();
|
||||
format.setTerminatedBy(this.exprParser.expr());
|
||||
stmt.setRowFormat(format);
|
||||
} else {
|
||||
throw new ParserException("TODO " + lexer.info());
|
||||
}
|
||||
}
|
||||
|
||||
if (lexer.identifierEquals(FnvHash.Constants.SORTED)) {
|
||||
lexer.nextToken();
|
||||
accept(Token.BY);
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.dialect.hive.visitor;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.statement.*;
|
||||
import com.alibaba.druid.sql.dialect.hive.stmt.HiveCreateTableStatement;
|
||||
@@ -69,6 +70,13 @@ public class HiveOutputVisitor extends SQLASTOutputVisitor implements HiveASTVis
|
||||
print(')');
|
||||
}
|
||||
|
||||
SQLExpr comment = x.getComment();
|
||||
if (comment != null) {
|
||||
println();
|
||||
print0(ucase ? "COMMENT " : "comment ");
|
||||
comment.accept(this);
|
||||
}
|
||||
|
||||
int partitionSize = x.getPartitionColumns().size();
|
||||
if (partitionSize > 0) {
|
||||
println();
|
||||
@@ -104,6 +112,13 @@ public class HiveOutputVisitor extends SQLASTOutputVisitor implements HiveASTVis
|
||||
print(')');
|
||||
}
|
||||
|
||||
SQLExternalRecordFormat format = x.getRowFormat();
|
||||
if (format != null) {
|
||||
println();
|
||||
print0(ucase ? "ROW FORMAT DELIMITED " : "row format delimited ");
|
||||
visit(format);
|
||||
}
|
||||
|
||||
List<SQLSelectOrderByItem> sortedBy = x.getSortedBy();
|
||||
if (sortedBy.size() > 0) {
|
||||
println();
|
||||
@@ -141,4 +156,20 @@ public class HiveOutputVisitor extends SQLASTOutputVisitor implements HiveASTVis
|
||||
public void endVisit(HiveCreateTableStatement x) {
|
||||
|
||||
}
|
||||
|
||||
public boolean visit(SQLExternalRecordFormat x) {
|
||||
if (x.getDelimitedBy() != null) {
|
||||
println();
|
||||
print0(ucase ? "LINES TERMINATED BY " : "lines terminated by ");
|
||||
x.getDelimitedBy().accept(this);
|
||||
}
|
||||
|
||||
if (x.getTerminatedBy() != null) {
|
||||
println();
|
||||
print0(ucase ? "FIELDS TERMINATED BY " : "fields terminated by ");
|
||||
x.getTerminatedBy().accept(this);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
-11
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.dialect.mysql.visitor;
|
||||
|
||||
import com.alibaba.druid.sql.ast.statement.SQLAlterProcedureStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalDay;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeIntervalYear;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.*;
|
||||
@@ -926,16 +925,6 @@ public class OracleToMySqlOutputVisitor extends MySqlOutputVisitor implements Or
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleCreateTableStatement.OracleExternalRecordFormat x) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OracleCreateTableStatement.OracleExternalRecordFormat x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleCreateTableStatement.OIDIndex x) {
|
||||
return false;
|
||||
|
||||
+4
-42
@@ -18,11 +18,9 @@ package com.alibaba.druid.sql.dialect.oracle.ast.stmt;
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.SQLObject;
|
||||
import com.alibaba.druid.sql.ast.SQLPartitionBy;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLNumericLiteralExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExternalRecordFormat;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObject;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObjectImpl;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleSegmentAttributes;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleSegmentAttributesImpl;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleLobStorageClause;
|
||||
@@ -310,7 +308,7 @@ public class OracleCreateTableStatement extends SQLCreateTableStatement implemen
|
||||
|
||||
private SQLName externalType;
|
||||
private SQLExpr externalDirectory;
|
||||
private OracleExternalRecordFormat externalDirectoryRecordFormat;
|
||||
private SQLExternalRecordFormat externalDirectoryRecordFormat;
|
||||
private List<SQLExpr> externalDirectoryLocation = new ArrayList<SQLExpr>();
|
||||
private SQLExpr externalRejectLimit;
|
||||
|
||||
@@ -350,11 +348,11 @@ public class OracleCreateTableStatement extends SQLCreateTableStatement implemen
|
||||
this.externalDirectory = externalDirectory;
|
||||
}
|
||||
|
||||
public OracleExternalRecordFormat getExternalDirectoryRecordFormat() {
|
||||
public SQLExternalRecordFormat getExternalDirectoryRecordFormat() {
|
||||
return externalDirectoryRecordFormat;
|
||||
}
|
||||
|
||||
public void setExternalDirectoryRecordFormat(OracleExternalRecordFormat recordFormat) {
|
||||
public void setExternalDirectoryRecordFormat(SQLExternalRecordFormat recordFormat) {
|
||||
if (recordFormat != null) {
|
||||
recordFormat.setParent(this);
|
||||
}
|
||||
@@ -377,42 +375,6 @@ public class OracleCreateTableStatement extends SQLCreateTableStatement implemen
|
||||
}
|
||||
}
|
||||
|
||||
public static class OracleExternalRecordFormat extends OracleSQLObjectImpl {
|
||||
private SQLExpr delimitedBy;
|
||||
private SQLExpr terminatedBy;
|
||||
|
||||
@Override
|
||||
public void accept0(OracleASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
acceptChild(visitor, delimitedBy);
|
||||
acceptChild(visitor, terminatedBy);
|
||||
}
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
|
||||
public SQLExpr getDelimitedBy() {
|
||||
return delimitedBy;
|
||||
}
|
||||
|
||||
public void setDelimitedBy(SQLExpr delimitedBy) {
|
||||
if (delimitedBy != null) {
|
||||
delimitedBy.setParent(this);
|
||||
}
|
||||
this.delimitedBy = delimitedBy;
|
||||
}
|
||||
|
||||
public SQLExpr getTerminatedBy() {
|
||||
return terminatedBy;
|
||||
}
|
||||
|
||||
public void setTerminatedBy(SQLExpr terminatedBy) {
|
||||
if (terminatedBy != null) {
|
||||
terminatedBy.setParent(this);
|
||||
}
|
||||
this.terminatedBy = terminatedBy;
|
||||
}
|
||||
}
|
||||
|
||||
public static class OIDIndex extends OracleSegmentAttributesImpl implements OracleSQLObject{
|
||||
private SQLName name;
|
||||
|
||||
|
||||
+2
-1
@@ -22,6 +22,7 @@ import com.alibaba.druid.sql.ast.SQLPartitionByList;
|
||||
import com.alibaba.druid.sql.ast.SQLPartitionByRange;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLNumericLiteralExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExternalRecordFormat;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelect;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleLobStorageClause;
|
||||
@@ -266,7 +267,7 @@ public class OracleCreateTableParser extends SQLCreateTableParser {
|
||||
if (lexer.token() == Token.LPAREN) {
|
||||
lexer.nextToken();
|
||||
|
||||
OracleCreateTableStatement.OracleExternalRecordFormat recordFormat = new OracleCreateTableStatement.OracleExternalRecordFormat();
|
||||
SQLExternalRecordFormat recordFormat = new SQLExternalRecordFormat();
|
||||
|
||||
if (lexer.identifierEquals("RECORDS")) {
|
||||
lexer.nextToken();
|
||||
|
||||
@@ -398,10 +398,6 @@ public interface OracleASTVisitor extends SQLASTVisitor {
|
||||
|
||||
void endVisit(OracleCreateTableStatement.Organization x);
|
||||
|
||||
boolean visit(OracleCreateTableStatement.OracleExternalRecordFormat x);
|
||||
|
||||
void endVisit(OracleCreateTableStatement.OracleExternalRecordFormat x);
|
||||
|
||||
boolean visit(OracleCreateTableStatement.OIDIndex x);
|
||||
|
||||
void endVisit(OracleCreateTableStatement.OIDIndex x);
|
||||
|
||||
-7
@@ -990,13 +990,6 @@ public class OracleASTVisitorAdapter extends SQLASTVisitorAdapter implements Ora
|
||||
|
||||
}
|
||||
|
||||
public boolean visit(OracleCreateTableStatement.OracleExternalRecordFormat x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void endVisit(OracleCreateTableStatement.OracleExternalRecordFormat x) {
|
||||
|
||||
}
|
||||
public boolean visit(OracleCreateTableStatement.OIDIndex x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -3020,26 +3020,6 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
|
||||
|
||||
}
|
||||
|
||||
public boolean visit(OracleCreateTableStatement.OracleExternalRecordFormat x) {
|
||||
if (x.getDelimitedBy() != null) {
|
||||
println();
|
||||
print0(ucase ? "RECORDS DELIMITED BY " : "records delimited by ");
|
||||
x.getDelimitedBy().accept(this);
|
||||
}
|
||||
|
||||
if (x.getTerminatedBy() != null) {
|
||||
println();
|
||||
print0(ucase ? "FIELDS TERMINATED BY " : "fields terminated by ");
|
||||
x.getTerminatedBy().accept(this);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void endVisit(OracleCreateTableStatement.OracleExternalRecordFormat x) {
|
||||
|
||||
}
|
||||
|
||||
public boolean visit(OracleCreateTableStatement.OIDIndex x) {
|
||||
print0(ucase ? "OIDINDEX" : "oidindex");
|
||||
|
||||
|
||||
-10
@@ -1223,16 +1223,6 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleCreateTableStatement.OracleExternalRecordFormat x) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OracleCreateTableStatement.OracleExternalRecordFormat x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleCreateTableStatement.OIDIndex x) {
|
||||
return false;
|
||||
|
||||
@@ -46,7 +46,6 @@ import com.alibaba.druid.util.JdbcConstants;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class PGOutputVisitor extends SQLASTOutputVisitor implements PGASTVisitor, OracleASTVisitor {
|
||||
@@ -1890,28 +1889,6 @@ public class PGOutputVisitor extends SQLASTOutputVisitor implements PGASTVisitor
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleCreateTableStatement.OracleExternalRecordFormat x) {
|
||||
if (x.getDelimitedBy() != null) {
|
||||
println();
|
||||
print0(ucase ? "RECORDS DELIMITED BY " : "records delimited by ");
|
||||
x.getDelimitedBy().accept(this);
|
||||
}
|
||||
|
||||
if (x.getTerminatedBy() != null) {
|
||||
println();
|
||||
print0(ucase ? "FIELDS TERMINATED BY " : "fields terminated by ");
|
||||
x.getTerminatedBy().accept(this);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OracleCreateTableStatement.OracleExternalRecordFormat x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleCreateTableStatement.OIDIndex x) {
|
||||
print0(ucase ? "OIDINDEX" : "oidindex");
|
||||
|
||||
@@ -6025,4 +6025,20 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLExternalRecordFormat x) {
|
||||
if (x.getDelimitedBy() != null) {
|
||||
println();
|
||||
print0(ucase ? "RECORDS DELIMITED BY " : "records delimited by ");
|
||||
x.getDelimitedBy().accept(this);
|
||||
}
|
||||
|
||||
if (x.getTerminatedBy() != null) {
|
||||
println();
|
||||
print0(ucase ? "FIELDS TERMINATED BY " : "fields terminated by ");
|
||||
x.getTerminatedBy().accept(this);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -799,4 +799,7 @@ public interface SQLASTVisitor {
|
||||
|
||||
boolean visit(SQLDropTypeStatement x);
|
||||
void endVisit(SQLDropTypeStatement x);
|
||||
|
||||
boolean visit(SQLExternalRecordFormat x);
|
||||
void endVisit(SQLExternalRecordFormat x);
|
||||
}
|
||||
|
||||
@@ -1866,6 +1866,14 @@ public class SQLASTVisitorAdapter implements SQLASTVisitor {
|
||||
|
||||
}
|
||||
|
||||
public boolean visit(SQLExternalRecordFormat x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void endVisit(SQLExternalRecordFormat x) {
|
||||
|
||||
}
|
||||
|
||||
public final boolean isEnabled(VisitorFeature feature) {
|
||||
return VisitorFeature.isEnabled(this.features, feature);
|
||||
}
|
||||
|
||||
@@ -2416,4 +2416,9 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
|
||||
public boolean visit(SQLDropTypeStatement x) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLExternalRecordFormat x) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -621,5 +621,6 @@ public final class FnvHash {
|
||||
long RELEASE = fnv1a_64_lower("RELEASE");
|
||||
long MERGE = fnv1a_64_lower("MERGE");
|
||||
long INHERITS = fnv1a_64_lower("INHERITS");
|
||||
long DELIMITED = fnv1a_64_lower("DELIMITED");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user