mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
Add implementation and testcase for Teradata Insert
This commit is contained in:
+56
@@ -0,0 +1,56 @@
|
||||
package com.alibaba.druid.sql.dialect.teradata.ast.stmt;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
|
||||
import com.alibaba.druid.sql.dialect.teradata.visitor.TeradataASTVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public class TeradataInsertStatement extends SQLInsertStatement {
|
||||
private List<ValuesClause> valuesList = new ArrayList<ValuesClause>();
|
||||
|
||||
public ValuesClause getValues() {
|
||||
if (valuesList.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
return valuesList.get(0);
|
||||
}
|
||||
|
||||
public void setValues(ValuesClause values) {
|
||||
if (valuesList.size() == 0) {
|
||||
valuesList.add(values);
|
||||
} else {
|
||||
valuesList.set(0, values);
|
||||
}
|
||||
}
|
||||
|
||||
public List<ValuesClause> getValuesList() {
|
||||
return valuesList;
|
||||
}
|
||||
|
||||
public void addValueCause(ValuesClause valueClause) {
|
||||
valueClause.setParent(this);
|
||||
valuesList.add(valueClause);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void accept0(SQLASTVisitor visitor) {
|
||||
if (visitor instanceof TeradataASTVisitor) {
|
||||
accept0((TeradataASTVisitor) visitor);
|
||||
} else {
|
||||
throw new IllegalArgumentException("not support visitor type : " + visitor.getClass().getName());
|
||||
}
|
||||
}
|
||||
|
||||
protected void accept0(TeradataASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
this.acceptChild(visitor, getTableSource());
|
||||
this.acceptChild(visitor, getColumns());
|
||||
this.acceptChild(visitor, getValuesList());
|
||||
this.acceptChild(visitor, getQuery());
|
||||
}
|
||||
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,7 @@ import com.alibaba.druid.sql.dialect.teradata.ast.expr.TeradataIntervalUnit;
|
||||
import com.alibaba.druid.sql.parser.Lexer;
|
||||
import com.alibaba.druid.sql.parser.ParserException;
|
||||
import com.alibaba.druid.sql.parser.SQLExprParser;
|
||||
import com.alibaba.druid.sql.parser.SQLSelectParser;
|
||||
import com.alibaba.druid.sql.parser.Token;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
|
||||
@@ -82,6 +83,10 @@ public class TeradataExprParser extends SQLExprParser {
|
||||
}
|
||||
}
|
||||
|
||||
public SQLSelectParser createSelectParser() {
|
||||
return new TeradataSelectParser(this);
|
||||
}
|
||||
|
||||
protected SQLExpr methodRest(SQLExpr expr, boolean acceptLPAREN) {
|
||||
if (acceptLPAREN) {
|
||||
accept(Token.LPAREN);
|
||||
|
||||
+165
-1
@@ -15,12 +15,22 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.dialect.teradata.parser;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLNCharExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelect;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.parser.OracleSelectParser;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement.ValuesClause;
|
||||
import com.alibaba.druid.sql.dialect.teradata.ast.stmt.TeradataInsertStatement;
|
||||
import com.alibaba.druid.sql.parser.Lexer;
|
||||
import com.alibaba.druid.sql.parser.ParserException;
|
||||
import com.alibaba.druid.sql.parser.SQLStatementParser;
|
||||
import com.alibaba.druid.sql.parser.Token;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
@@ -48,6 +58,160 @@ public class TeradataStatementParser extends SQLStatementParser {
|
||||
return new SQLSelectStatement(selectParser.select(), JdbcConstants.TERADATA);
|
||||
}
|
||||
|
||||
public SQLInsertStatement parseInsert() {
|
||||
TeradataInsertStatement insertStatement = new TeradataInsertStatement();
|
||||
|
||||
if (lexer.token() == Token.INSERT) {
|
||||
lexer.nextToken();
|
||||
|
||||
if (lexer.token() == Token.INTO) {
|
||||
lexer.nextToken();
|
||||
}
|
||||
|
||||
SQLName tableName = this.exprParser.name();
|
||||
insertStatement.setTableName(tableName);
|
||||
|
||||
if (lexer.token() == Token.IDENTIFIER && !identifierEquals("VALUE")) {
|
||||
insertStatement.setAlias(lexer.stringVal());
|
||||
lexer.nextToken();
|
||||
}
|
||||
}
|
||||
|
||||
int columnSize = 0;
|
||||
if (lexer.token() == (Token.LPAREN)) {
|
||||
lexer.nextToken();
|
||||
if (lexer.token() == (Token.SELECT)) {
|
||||
SQLSelect select = this.exprParser.createSelectParser().select();
|
||||
select.setParent(insertStatement);
|
||||
insertStatement.setQuery(select);
|
||||
} else {
|
||||
this.exprParser.exprList(insertStatement.getColumns(), insertStatement);
|
||||
columnSize = insertStatement.getColumns().size();
|
||||
}
|
||||
accept(Token.RPAREN);
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.VALUES || identifierEquals("VALUE")) {
|
||||
lexer.nextTokenLParen();
|
||||
parseValueClause(insertStatement.getValuesList(), columnSize);
|
||||
} else if (lexer.token() == Token.SET) {
|
||||
lexer.nextToken();
|
||||
|
||||
SQLInsertStatement.ValuesClause values = new SQLInsertStatement.ValuesClause();
|
||||
insertStatement.getValuesList().add(values);
|
||||
|
||||
for (;;) {
|
||||
SQLName name = this.exprParser.name();
|
||||
insertStatement.addColumn(name);
|
||||
if (lexer.token() == Token.EQ) {
|
||||
lexer.nextToken();
|
||||
} else {
|
||||
accept(Token.COLONEQ);
|
||||
}
|
||||
values.addValue(this.exprParser.expr());
|
||||
|
||||
if (lexer.token() == Token.COMMA) {
|
||||
lexer.nextToken();
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
} else if (lexer.token() == (Token.SELECT)) {
|
||||
SQLSelect select = this.exprParser.createSelectParser().select();
|
||||
select.setParent(insertStatement);
|
||||
insertStatement.setQuery(select);
|
||||
} else if (lexer.token() == (Token.LPAREN)) {
|
||||
lexer.nextToken();
|
||||
SQLSelect select = this.exprParser.createSelectParser().select();
|
||||
select.setParent(insertStatement);
|
||||
insertStatement.setQuery(select);
|
||||
accept(Token.RPAREN);
|
||||
}
|
||||
|
||||
return insertStatement;
|
||||
}
|
||||
|
||||
private void parseValueClause(List<ValuesClause> valueClauseList, int columnSize) {
|
||||
for (;;) {
|
||||
if (lexer.token() != Token.LPAREN) {
|
||||
throw new ParserException("syntax error, expect ')'");
|
||||
}
|
||||
lexer.nextTokenValue();
|
||||
|
||||
if (lexer.token() != Token.RPAREN) {
|
||||
List<SQLExpr> valueExprList;
|
||||
if (columnSize > 0) {
|
||||
valueExprList = new ArrayList<SQLExpr>(columnSize);
|
||||
} else {
|
||||
valueExprList = new ArrayList<SQLExpr>();
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
SQLExpr expr;
|
||||
if (lexer.token() == Token.LITERAL_INT) {
|
||||
expr = new SQLIntegerExpr(lexer.integerValue());
|
||||
lexer.nextTokenComma();
|
||||
} else if (lexer.token() == Token.LITERAL_CHARS) {
|
||||
expr = new SQLCharExpr(lexer.stringVal());
|
||||
lexer.nextTokenComma();
|
||||
} else if (lexer.token() == Token.LITERAL_NCHARS) {
|
||||
expr = new SQLNCharExpr(lexer.stringVal());
|
||||
lexer.nextTokenComma();
|
||||
} else {
|
||||
expr = exprParser.expr();
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.COMMA) {
|
||||
valueExprList.add(expr);
|
||||
lexer.nextTokenValue();
|
||||
continue;
|
||||
} else if (lexer.token() == Token.RPAREN) {
|
||||
valueExprList.add(expr);
|
||||
break;
|
||||
} else {
|
||||
expr = this.exprParser.primaryRest(expr);
|
||||
if (lexer.token() != Token.COMMA && lexer.token() != Token.RPAREN) {
|
||||
expr = this.exprParser.exprRest(expr);
|
||||
}
|
||||
|
||||
valueExprList.add(expr);
|
||||
if (lexer.token() == Token.COMMA) {
|
||||
lexer.nextToken();
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SQLInsertStatement.ValuesClause values = new SQLInsertStatement.ValuesClause(valueExprList);
|
||||
valueClauseList.add(values);
|
||||
} else {
|
||||
SQLInsertStatement.ValuesClause values = new SQLInsertStatement.ValuesClause(new ArrayList<SQLExpr>(0));
|
||||
valueClauseList.add(values);
|
||||
}
|
||||
|
||||
if (lexer.token() != Token.RPAREN) {
|
||||
throw new ParserException("syntax error");
|
||||
}
|
||||
|
||||
if (!parseCompleteValues && valueClauseList.size() >= parseValuesSize) {
|
||||
lexer.skipToEOF();
|
||||
break;
|
||||
}
|
||||
|
||||
lexer.nextTokenComma();
|
||||
if (lexer.token() == Token.COMMA) {
|
||||
lexer.nextTokenLParen();
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void parseStatementList(List<SQLStatement> statementList, int max) {
|
||||
for (;;) {
|
||||
if (max != -1) {
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
package com.alibaba.druid.bvt.sql.teradata;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Assert;
|
||||
|
||||
import com.alibaba.druid.sql.TeradataTest;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelect;
|
||||
import com.alibaba.druid.sql.dialect.teradata.ast.stmt.TeradataInsertStatement;
|
||||
import com.alibaba.druid.sql.dialect.teradata.ast.stmt.TeradataSelectQueryBlock;
|
||||
import com.alibaba.druid.sql.dialect.teradata.parser.TeradataStatementParser;
|
||||
import com.alibaba.druid.sql.dialect.teradata.visitor.TeradataSchemaStatVisitor;
|
||||
import com.alibaba.druid.stat.TableStat.Column;
|
||||
|
||||
|
||||
public class TeradataInsertTest_1 extends TeradataTest {
|
||||
public void test_values() throws Exception {
|
||||
String ins_sql = "INSERT INTO t1(c1, c2) VALUES "
|
||||
+ "('a', 'b'),"
|
||||
+ "('c', 'd'),"
|
||||
+ "('e', 'f')";
|
||||
|
||||
TeradataStatementParser parser = new TeradataStatementParser(ins_sql);
|
||||
List<SQLStatement> statementList = parser.parseStatementList();
|
||||
SQLStatement stmt = statementList.get(0);
|
||||
|
||||
Assert.assertTrue(stmt instanceof SQLInsertStatement);
|
||||
|
||||
TeradataInsertStatement insertStmt = (TeradataInsertStatement) stmt;
|
||||
Assert.assertEquals("t1", insertStmt.getTableSource().toString());
|
||||
Assert.assertEquals("c1", insertStmt.getColumns().get(0).toString());
|
||||
Assert.assertEquals("c2", insertStmt.getColumns().get(1).toString());
|
||||
Assert.assertEquals(3, insertStmt.getValuesList().size());
|
||||
Assert.assertEquals(2, insertStmt.getValuesList().get(0).getValues().size());
|
||||
|
||||
SQLSelect insertQuery = insertStmt.getQuery();
|
||||
Assert.assertNull(insertQuery);
|
||||
|
||||
TeradataSchemaStatVisitor visitor = new TeradataSchemaStatVisitor();
|
||||
insertStmt.accept(visitor);
|
||||
System.out.println(visitor.getColumns());
|
||||
System.out.println(visitor.getTables());
|
||||
System.out.println("------ end of " + new Object(){}.getClass().getEnclosingMethod().getName() + " ------");
|
||||
}
|
||||
|
||||
public void test_select() throws Exception {
|
||||
String ins_sql = "INSERT INTO d1.t1(col1, col2) "
|
||||
+ "SELECT c1, c2 "
|
||||
+ "FROM d2.t2 "
|
||||
+ "WHERE c1=0;";
|
||||
TeradataStatementParser parser = new TeradataStatementParser(ins_sql);
|
||||
List<SQLStatement> statementList = parser.parseStatementList();
|
||||
SQLStatement stmt = statementList.get(0);
|
||||
|
||||
Assert.assertTrue(stmt instanceof SQLInsertStatement);
|
||||
|
||||
TeradataInsertStatement insertStmt = (TeradataInsertStatement) stmt;
|
||||
SQLSelect insertQuery = insertStmt.getQuery();
|
||||
Assert.assertNotNull(insertQuery);
|
||||
|
||||
// retrieve SELECT sub-clause from INSERT query
|
||||
TeradataSelectQueryBlock insertBlock = (TeradataSelectQueryBlock) insertQuery.getQuery();
|
||||
Assert.assertNotNull(insertBlock);
|
||||
|
||||
// target table
|
||||
Assert.assertEquals("d1.t1", insertStmt.getTableSource().toString());
|
||||
Assert.assertEquals(2, insertStmt.getColumns().size());
|
||||
Assert.assertEquals("col1", insertStmt.getColumns().get(0).toString());
|
||||
Assert.assertEquals("col2", insertStmt.getColumns().get(1).toString());
|
||||
// source table
|
||||
Assert.assertEquals("d2.t2", insertBlock.getFrom().toString());
|
||||
Assert.assertEquals(2, insertBlock.getSelectList().size());
|
||||
Assert.assertEquals("c1", insertBlock.getSelectList().get(0).toString());
|
||||
Assert.assertEquals("c2", insertBlock.getSelectList().get(1).toString());
|
||||
|
||||
System.out.println("***********below is useful info **********");
|
||||
System.out.println("target table: " + insertStmt.getTableSource());
|
||||
System.out.println("target columns: " + insertStmt.getColumns());
|
||||
System.out.println("source from: " + insertBlock.getFrom());
|
||||
System.out.println("source columns : " + insertBlock.getSelectList());
|
||||
System.out.println("source condition: " + insertBlock.getWhere());
|
||||
System.out.println("********");
|
||||
|
||||
TeradataSchemaStatVisitor visitor = new TeradataSchemaStatVisitor();
|
||||
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());
|
||||
|
||||
System.out.println("------ end of " + new Object(){}.getClass().getEnclosingMethod().getName() + " ------");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user