Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gaussdb parser support insert overwrite. #6195

Merged
merged 1 commit into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.alibaba.druid.sql.dialect.gaussdb.ast.stmt;

import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGInsertStatement;

import java.util.ArrayList;
import java.util.List;

public class GaussDbInsertStatement extends PGInsertStatement {
private final List<SQLExpr> partition = new ArrayList<SQLExpr>(4);
private boolean hasTableIdentifier;

public List<SQLExpr> getPartition() {
return partition;
}

public void setHasTableIdentifier(boolean hasTableIdentifier) {
this.hasTableIdentifier = hasTableIdentifier;
}

public boolean isHasTableIdentifier() {
return hasTableIdentifier;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ protected Keywords loadKeywords() {
map.put("START", Token.START);
map.put("PARTIAL", Token.PARTIAL);
map.put("KEY", Token.KEY);
map.put("OVERWRITE", Token.OVERWRITE);
map.putAll(super.loadKeywords().getKeywords());
return new Keywords(map);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
package com.alibaba.druid.sql.dialect.gaussdb.parser;

import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.expr.SQLListExpr;
import com.alibaba.druid.sql.ast.expr.SQLQueryExpr;
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem;
import com.alibaba.druid.sql.dialect.gaussdb.ast.stmt.GaussDbInsertStatement;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGInsertStatement;
import com.alibaba.druid.sql.dialect.postgresql.parser.PGSQLStatementParser;
import com.alibaba.druid.sql.parser.SQLParserFeature;
import com.alibaba.druid.sql.parser.Token;
import com.alibaba.druid.util.FnvHash;

import java.util.ArrayList;
import java.util.List;

public class GaussDbStatementParser extends PGSQLStatementParser {
public GaussDbStatementParser(String sql) {
Expand All @@ -21,4 +34,148 @@ public GaussDbCreateTableParser getSQLCreateTableParser() {
public SQLCreateTableStatement parseCreateTable() {
return getSQLCreateTableParser().parseCreateTable();
}

@Override
public PGInsertStatement parseInsert() {
GaussDbInsertStatement stmt = new GaussDbInsertStatement();

if (lexer.token() == Token.INSERT) {
lexer.nextToken();
if (lexer.token() == Token.INTO) {
lexer.nextToken();
} else {
accept(Token.OVERWRITE);
stmt.setOverwrite(true);
}

if (lexer.token() == Token.TABLE) {
lexer.nextToken();
stmt.setHasTableIdentifier(true);
}
stmt.setTableSource(this.exprParser.name());
if (lexer.token() == Token.AS) {
lexer.nextToken();
stmt.setAlias(lexer.stringVal());
lexer.nextToken();
} else if (lexer.token() == Token.IDENTIFIER) {
stmt.setAlias(lexer.stringVal());
lexer.nextToken();
}

}

if (lexer.token() == Token.PARTITION) {
lexer.nextToken();
accept(Token.LPAREN);
this.exprParser.exprList(stmt.getPartition(), stmt);
accept(Token.RPAREN);
}

if (lexer.token() == Token.DEFAULT) {
lexer.nextToken();
accept(Token.VALUES);
stmt.setDefaultValues(true);
}

if (lexer.token() == (Token.LPAREN)) {
lexer.nextToken();
this.exprParser.exprList(stmt.getColumns(), stmt);
accept(Token.RPAREN);
}

if (lexer.token() == (Token.VALUES)) {
lexer.nextToken();

for (; ; ) {
accept(Token.LPAREN);
SQLInsertStatement.ValuesClause valuesCaluse = new SQLInsertStatement.ValuesClause();
this.exprParser.exprList(valuesCaluse.getValues(), valuesCaluse);
stmt.addValueCause(valuesCaluse);

accept(Token.RPAREN);
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
break;
}
} else if (lexer.token() == (Token.SELECT)) {
SQLQueryExpr queryExpr = (SQLQueryExpr) this.exprParser.expr();
stmt.setQuery(queryExpr.getSubQuery());
}

if (lexer.token() == Token.ON) {
lexer.nextToken();
if (lexer.identifierEquals(FnvHash.Constants.CONFLICT)) {
lexer.nextToken();

if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
List<SQLExpr> onConflictTarget = new ArrayList<SQLExpr>();
this.exprParser.exprList(onConflictTarget, stmt);
stmt.setOnConflictTarget(onConflictTarget);
accept(Token.RPAREN);
}

if (lexer.token() == Token.ON) {
lexer.nextToken();
accept(Token.CONSTRAINT);
SQLName constraintName = this.exprParser.name();
stmt.setOnConflictConstraint(constraintName);
}

if (lexer.token() == Token.WHERE) {
lexer.nextToken();
SQLExpr where = this.exprParser.expr();
stmt.setOnConflictWhere(where);
}

if (lexer.token() == Token.DO) {
lexer.nextToken();

if (lexer.identifierEquals(FnvHash.Constants.NOTHING)) {
lexer.nextToken();
stmt.setOnConflictDoNothing(true);
} else {
accept(Token.UPDATE);
accept(Token.SET);

for (; ; ) {
SQLUpdateSetItem item = this.exprParser.parseUpdateSetItem();
stmt.addConflicUpdateItem(item);

if (lexer.token() != Token.COMMA) {
break;
}

lexer.nextToken();
}
if (lexer.token() == Token.WHERE) {
lexer.nextToken();
SQLExpr where = this.exprParser.expr();
stmt.setOnConflictUpdateWhere(where);
}
}
}
}
}

if (lexer.token() == Token.RETURNING) {
lexer.nextToken();
SQLExpr returning = this.exprParser.expr();

if (lexer.token() == Token.COMMA) {
lexer.nextToken();
SQLListExpr list = new SQLListExpr();
list.addItem(returning);

this.exprParser.exprList(list.getItems(), list);

returning = list;
}

stmt.setReturning(returning);
}
return stmt;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.alibaba.druid.sql.dialect.gaussdb.ast.GaussDbCreateTableStatement;
import com.alibaba.druid.sql.dialect.gaussdb.ast.GaussDbDistributeBy;
import com.alibaba.druid.sql.dialect.gaussdb.ast.stmt.GaussDbInsertStatement;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;

public interface GaussDbASTVisitor extends SQLASTVisitor {
Expand All @@ -15,4 +16,11 @@ default boolean visit(GaussDbDistributeBy x) {
}
default void endVisit(GaussDbDistributeBy x) {
}

default boolean visit(GaussDbInsertStatement x) {
return true;
}

default void endVisit(GaussDbInsertStatement x) {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@
import com.alibaba.druid.sql.ast.*;
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
import com.alibaba.druid.sql.ast.statement.SQLWithSubqueryClause;
import com.alibaba.druid.sql.dialect.gaussdb.ast.GaussDbCreateTableStatement;
import com.alibaba.druid.sql.dialect.gaussdb.ast.GaussDbDistributeBy;
import com.alibaba.druid.sql.dialect.gaussdb.ast.GaussDbPartitionValue;
import com.alibaba.druid.sql.dialect.gaussdb.ast.stmt.GaussDbInsertStatement;
import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor;

import java.util.List;
Expand Down Expand Up @@ -309,4 +312,70 @@ public boolean visit(GaussDbDistributeBy x) {
}
return false;
}

@Override
public boolean visit(SQLInsertStatement x) {
if (x instanceof GaussDbInsertStatement) {
return visit((GaussDbInsertStatement) x);
}
return super.visit(x);
}

@Override
public boolean visit(GaussDbInsertStatement x) {
List<SQLCommentHint> headHints = x.getHeadHintsDirect();
if (headHints != null) {
for (SQLCommentHint hint : headHints) {
hint.accept(this);
println();
}
}

if (x.getInsertBeforeCommentsDirect() != null) {
printlnComments(x.getInsertBeforeCommentsDirect());
}

SQLWithSubqueryClause with = x.getWith();
if (with != null) {
visit(with);
println();
}

if (x.isOverwrite()) {
print0(ucase ? "INSERT OVERWRITE " : "insert overwrite ");
} else {
print0(ucase ? "INSERT INTO " : "insert into ");
}

if (x.isHasTableIdentifier()) {
print0(ucase ? "TABLE " : "table ");
}
x.getTableSource().accept(this);

if (!x.getPartition().isEmpty()) {
print(" PARTITION (");
printAndAccept(x.getPartition(), ",");
print(")");
}

String columnsString = x.getColumnsString();
if (columnsString != null) {
print0(columnsString);
} else {
printInsertColumns(x.getColumns());
}

if (!x.getValuesList().isEmpty()) {
println();
print0(ucase ? "VALUES " : "values ");
printAndAccept(x.getValuesList(), ", ");
} else {
if (x.getQuery() != null) {
println();
x.getQuery().accept(this);
}
}

return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
import com.alibaba.druid.DbType;
import com.alibaba.druid.bvt.sql.SQLResourceTest;
import org.junit.Test;
public class GaussDbCreateTest extends SQLResourceTest {
public GaussDbCreateTest() {
public class GaussDbResourceTest extends SQLResourceTest {
public GaussDbResourceTest() {
super(DbType.gaussdb);
}
@Test
Expand Down
16 changes: 16 additions & 0 deletions core/src/test/resources/bvt/parser/gaussdb/1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
insert overwrite table edw_dwi.dwi_pub_eps_itsm_work_order_history_da partition (dt = '${deal_date}')
select
historyid as history_id ,
workorderid as work_order_id ,
operationownerid as operation_owner_id ,
operationtime as operation_time ,
description as description ,
operation as operation
from smart_sdi.sdi_itsm_public_workorderhistory_da
where dt = '${deal_date}'
--------------------
INSERT OVERWRITE TABLE edw_dwi.dwi_pub_eps_itsm_work_order_history_da PARTITION (dt = '${deal_date}')
SELECT historyid AS history_id, workorderid AS work_order_id, operationownerid AS operation_owner_id, operationtime AS operation_time, description AS description
, operation AS operation
FROM smart_sdi.sdi_itsm_public_workorderhistory_da
WHERE dt = '${deal_date}'
Loading