提交 748d092e 编写于 作者: T terrymanu

refactor insert statement 3rd version

上级 79be3771
......@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.druid.sql.ast.statement;
import com.alibaba.druid.sql.ast.SQLStatementImpl;
......@@ -24,7 +25,7 @@ public class SQLSelectStatement extends SQLStatementImpl {
private final SQLSelect select;
public SQLSelectStatement(final SQLSelect select){
public SQLSelectStatement(final SQLSelect select) {
this(select, null);
}
......
......@@ -16,10 +16,8 @@
package com.alibaba.druid.sql.dialect.mysql.parser;
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
import com.alibaba.druid.sql.parser.SQLSelectParser;
import com.alibaba.druid.sql.parser.SQLStatementParser;
import com.alibaba.druid.util.JdbcConstants;
import com.dangdang.ddframe.rdb.sharding.api.rule.ShardingRule;
import java.util.List;
......@@ -30,11 +28,6 @@ public class MySqlStatementParser extends SQLStatementParser {
super(shardingRule, parameters, new MySqlExprParser(sql));
}
@Override
protected SQLSelectStatement parseSelect() {
return new SQLSelectStatement(new MySqlSelectParser(getExprParser()).select(), JdbcConstants.MYSQL);
}
@Override
protected SQLSelectParser createSQLSelectParser() {
return new MySqlSelectParser(getExprParser());
......
/*
* Copyright 1999-2101 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.sql.dialect.postgresql.ast.stmt;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGSQLObject;
public interface PGSQLStatement extends SQLStatement, PGSQLObject {
}
/*
* Copyright 1999-2101 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.sql.dialect.postgresql.ast.stmt;
import com.alibaba.druid.sql.ast.statement.SQLSelect;
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithClause;
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
import com.alibaba.druid.util.JdbcConstants;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class PGSelectStatement extends SQLSelectStatement implements PGSQLStatement {
private PGWithClause with;
public PGSelectStatement(SQLSelect select){
super(select, JdbcConstants.POSTGRESQL);
}
@Override
protected void acceptInternal(final SQLASTVisitor visitor) {
accept0((PGASTVisitor) visitor);
}
@Override
public void accept0(final PGASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, with);
acceptChild(visitor, getSelect());
}
visitor.endVisit(this);
}
}
......@@ -16,17 +16,7 @@
package com.alibaba.druid.sql.dialect.postgresql.parser;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithClause;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithQuery;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectStatement;
import com.alibaba.druid.sql.lexer.Token;
import com.alibaba.druid.sql.parser.ParserUnsupportedException;
import com.alibaba.druid.sql.parser.SQLDeleteParserFactory;
import com.alibaba.druid.sql.parser.SQLStatementParser;
import com.alibaba.druid.sql.parser.SQLUpdateParserFactory;
import com.alibaba.druid.util.JdbcConstants;
import com.dangdang.ddframe.rdb.sharding.api.rule.ShardingRule;
import java.util.List;
......@@ -41,108 +31,4 @@ public class PGSQLStatementParser extends SQLStatementParser {
protected PGSelectParser createSQLSelectParser() {
return new PGSelectParser(getExprParser());
}
public PGWithClause parseWithClause() {
getLexer().nextToken();
PGWithClause withClause = new PGWithClause();
if (getLexer().equalToken(Token.RECURSIVE)) {
getLexer().nextToken();
withClause.setRecursive(true);
}
while (true) {
PGWithQuery withQuery = withQuery();
withClause.getWithQuery().add(withQuery);
if (getLexer().equalToken(Token.COMMA)) {
getLexer().nextToken();
} else {
break;
}
}
return withClause;
}
private PGWithQuery withQuery() {
PGWithQuery withQuery = new PGWithQuery();
if (getLexer().equalToken(Token.LITERAL_ALIAS)) {
withQuery.setName(new SQLIdentifierExpr("\"" + getLexer().getLiterals()
+ "\""));
} else {
withQuery.setName(new SQLIdentifierExpr(getLexer().getLiterals()));
}
getLexer().nextToken();
if (getLexer().equalToken(Token.LEFT_PAREN)) {
getLexer().nextToken();
while (true) {
withQuery.getColumns().add(getExprParser().expr());
if (getLexer().equalToken(Token.COMMA)) {
getLexer().nextToken();
} else {
break;
}
}
accept(Token.RIGHT_PAREN);
}
accept(Token.AS);
if (getLexer().equalToken(Token.LEFT_PAREN)) {
getLexer().nextToken();
SQLStatement query;
if (getLexer().equalToken(Token.SELECT)) {
query = parseSelect();
} else if (getLexer().equalToken(Token.INSERT)) {
query = new PostgreSQLInsertParser(getShardingRule(), getParameters(), getExprParser()).parse();
} else if (getLexer().equalToken(Token.UPDATE)) {
query = SQLUpdateParserFactory.newInstance(getShardingRule(), getParameters(), getExprParser(), JdbcConstants.POSTGRESQL).parse();
} else if (getLexer().equalToken(Token.DELETE)) {
query = SQLDeleteParserFactory.newInstance(getShardingRule(), getParameters(), getExprParser(), JdbcConstants.POSTGRESQL).parse();
} else if (getLexer().equalToken(Token.VALUES)) {
query = parseSelect();
} else {
throw new ParserUnsupportedException(getLexer().getToken());
}
withQuery.setQuery(query);
accept(Token.RIGHT_PAREN);
}
return withQuery;
}
@Override
protected PGSelectStatement parseSelect() {
return new PGSelectStatement(createSQLSelectParser().select());
}
@Override
public SQLStatement parseWith() {
PGWithClause with = parseWithClause();
if (getLexer().equalToken(Token.INSERT)) {
// PGInsertStatement stmt = (PGInsertStatement) new PostgreSQLInsertParser(getExprParser()).parse();
// stmt.setWith(with);
// return stmt;
// TODO call AbstractDeleteParser, need sharding rule
return null;
}
if (getLexer().equalToken(Token.SELECT)) {
PGSelectStatement stmt = parseSelect();
stmt.setWith(with);
return stmt;
}
if (getLexer().equalToken(Token.DELETE)) {
// TODO call AbstractDeleteParser, need sharding rule
return null;
}
throw new ParserUnsupportedException(getLexer().getToken());
}
}
......@@ -32,7 +32,6 @@ import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGPolygonExpr;
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGTypeCastExpr;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGFunctionTableSource;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectStatement;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGValuesQuery;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
......@@ -66,10 +65,6 @@ public interface PGASTVisitor extends SQLASTVisitor {
boolean visit(PGWithClause x);
void endVisit(PGSelectStatement x);
boolean visit(PGSelectStatement x);
void endVisit(PGParameter x);
boolean visit(PGParameter x);
......
......@@ -36,7 +36,6 @@ import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock.Fetc
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock.ForClause;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock.PGLimit;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock.WindowClause;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectStatement;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGValuesQuery;
import com.alibaba.druid.sql.visitor.SQLASTVisitorAdapter;
......@@ -87,15 +86,6 @@ public class PGASTVisitorAdapter extends SQLASTVisitorAdapter implements PGASTVi
return true;
}
@Override
public void endVisit(final PGSelectStatement x) {
}
@Override
public boolean visit(final PGSelectStatement x) {
return true;
}
@Override
public void endVisit(final PGSelectQueryBlock x) {
}
......
......@@ -18,7 +18,6 @@ package com.alibaba.druid.sql.dialect.postgresql.visitor;
import com.alibaba.druid.sql.ast.SQLSetQuantifier;
import com.alibaba.druid.sql.ast.expr.SQLBinaryExpr;
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithClause;
import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithQuery;
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGBoxExpr;
......@@ -39,7 +38,6 @@ import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock.Fetc
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock.ForClause;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock.PGLimit;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectQueryBlock.WindowClause;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectStatement;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGValuesQuery;
import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor;
......@@ -241,21 +239,6 @@ public class PGOutputVisitor extends SQLASTOutputVisitor implements PGASTVisitor
return false;
}
@Override
public void endVisit(PGSelectStatement x) {
}
@Override
public boolean visit(PGSelectStatement x) {
if (x.getWith() != null) {
x.getWith().accept(this);
println();
}
return visit((SQLSelectStatement) x);
}
@Override
public void endVisit(PGSelectQueryBlock x) {
......
......@@ -16,7 +16,6 @@
package com.alibaba.druid.sql.dialect.sqlserver.parser;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.parser.SQLSelectParser;
import com.alibaba.druid.sql.parser.SQLStatementParser;
import com.dangdang.ddframe.rdb.sharding.api.rule.ShardingRule;
......@@ -33,9 +32,4 @@ public class SQLServerStatementParser extends SQLStatementParser {
protected SQLSelectParser createSQLSelectParser() {
return new SQLServerSelectParser(getExprParser());
}
@Override
public SQLStatement parseWith() {
return parseSelect();
}
}
......@@ -57,7 +57,6 @@ public class SQLStatementParser extends SQLParser {
getLexer().nextToken();
}
if (getLexer().equalToken(Token.WITH)) {
// TODO 目前丢弃With的SQL
parseWith();
}
if (getLexer().equalToken(Token.SELECT)) {
......@@ -94,19 +93,43 @@ public class SQLStatementParser extends SQLParser {
throw new ParserException(getLexer());
}
protected SQLStatement parseWith() {
return null;
private void parseWith() {
getLexer().nextToken();
do {
parseWithQuery();
if (getLexer().equalToken(Token.EOF)) {
return;
}
} while (getLexer().equalToken(Token.COMMA));
}
private void parseWithQuery() {
while (!getLexer().equalToken(Token.AS)) {
getLexer().nextToken();
if (getLexer().equalToken(Token.EOF)) {
return;
}
}
accept(Token.AS);
accept(Token.LEFT_PAREN);
while (!getLexer().equalToken(Token.RIGHT_PAREN)) {
getLexer().nextToken();
if (getLexer().equalToken(Token.EOF)) {
return;
}
}
accept(Token.RIGHT_PAREN);
}
protected SQLSelectStatement parseSelect() {
return new SQLSelectStatement(createSQLSelectParser().select());
protected final SQLSelectStatement parseSelect() {
return new SQLSelectStatement(createSQLSelectParser().select(), getDbType());
}
protected SQLSelectParser createSQLSelectParser() {
return new SQLSelectParser(exprParser);
}
public SQLCommentStatement parseComment() {
protected final SQLCommentStatement parseComment() {
accept(Token.COMMENT);
SQLCommentStatement result = new SQLCommentStatement();
accept(Token.ON);
......@@ -119,7 +142,7 @@ public class SQLStatementParser extends SQLParser {
}
result.setOn(exprParser.name());
accept(Token.IS);
result.setComment(this.exprParser.expr());
result.setComment(exprParser.expr());
return result;
}
}
......@@ -86,17 +86,27 @@ public final class DeleteStatementParserTest extends AbstractStatementParserTest
@Test
public void parseWithSpecialSyntax() throws SQLException {
parseWithSpecialSyntax(JdbcConstants.MYSQL, "DELETE `TABLE_XXX` WHERE `field1`=1");
parseWithSpecialSyntax(JdbcConstants.MYSQL, "DELETE LOW_PRIORITY QUICK IGNORE TABLE_XXX PARTITION (partition_1) WHERE field1=1 ORDER BY field1 LIMIT 10");
parseWithSpecialSyntax(JdbcConstants.MYSQL, "DELETE FROM TABLE_XXX PARTITION (partition_1, partition_2,partition_3) WHERE field1=1");
parseWithSpecialSyntax(JdbcConstants.ORACLE, "DELETE /*+ index(field1) */ ONLY (TABLE_XXX) WHERE field1=1 RETURN * LOG ERRORS INTO TABLE_LOG");
parseWithSpecialSyntax(JdbcConstants.ORACLE, "DELETE /*+ index(field1) */ ONLY (TABLE_XXX) WHERE field1=1 RETURNING *");
parseWithSpecialSyntax(JdbcConstants.SQL_SERVER, "DELETE TOP(10) OUTPUT (inserted.field1) FROM TABLE_XXX WHERE field1=1");
parseWithSpecialSyntax(JdbcConstants.POSTGRESQL, "DELETE FROM ONLY TABLE_XXX USING producers WHERE field1=1 RETURNING *");
parseWithSpecialSyntax(JdbcConstants.POSTGRESQL, "DELETE FROM ONLY TABLE_XXX USING producers WHERE field1=1 OUTPUT *");
parseWithSpecialSyntax(JdbcConstants.MYSQL, "DELETE `TABLE_XXX` WHERE `field1`=1", "DELETE [Token(TABLE_XXX)] WHERE `field1`=1");
parseWithSpecialSyntax(JdbcConstants.MYSQL, "DELETE LOW_PRIORITY QUICK IGNORE TABLE_XXX PARTITION (partition_1) WHERE field1=1 ORDER BY field1 LIMIT 10",
"DELETE LOW_PRIORITY QUICK IGNORE [Token(TABLE_XXX)] PARTITION (partition_1) WHERE field1=1 ORDER BY field1 LIMIT 10");
parseWithSpecialSyntax(JdbcConstants.MYSQL, "DELETE FROM TABLE_XXX PARTITION (partition_1, partition_2,partition_3) WHERE field1=1",
"DELETE FROM [Token(TABLE_XXX)] PARTITION (partition_1, partition_2,partition_3) WHERE field1=1");
parseWithSpecialSyntax(JdbcConstants.ORACLE, "DELETE /*+ index(field1) */ ONLY (TABLE_XXX) WHERE field1=1 RETURN * LOG ERRORS INTO TABLE_LOG",
"DELETE /*+ index(field1) */ ONLY ([Token(TABLE_XXX)]) WHERE field1=1 RETURN * LOG ERRORS INTO TABLE_LOG");
parseWithSpecialSyntax(JdbcConstants.ORACLE, "DELETE /*+ index(field1) */ ONLY (TABLE_XXX) WHERE field1=1 RETURNING *",
"DELETE /*+ index(field1) */ ONLY ([Token(TABLE_XXX)]) WHERE field1=1 RETURNING *");
parseWithSpecialSyntax(JdbcConstants.SQL_SERVER,
"WITH field_query (field1, field2) AS (SELECT field1, field2 FROM TABLE_XXX AS xxx GROUP BY field1) DELETE TOP(10) OUTPUT (inserted.field1) FROM TABLE_XXX WHERE field1=1",
"WITH field_query (field1, field2) AS (SELECT field1, field2 FROM TABLE_XXX AS xxx GROUP BY field1) DELETE TOP(10) OUTPUT (inserted.field1) FROM [Token(TABLE_XXX)] WHERE field1=1");
parseWithSpecialSyntax(JdbcConstants.POSTGRESQL,
"WITH RECURSIVE field_query (field1) AS (SELECT field1 FROM TABLE_XXX AS xxx ORDER BY field1 DESC) DELETE FROM ONLY TABLE_XXX USING producers WHERE field1=1 RETURNING *",
"WITH RECURSIVE field_query (field1) AS (SELECT field1 FROM TABLE_XXX AS xxx ORDER BY field1 DESC) DELETE FROM ONLY [Token(TABLE_XXX)] USING producers WHERE field1=1 RETURNING *");
parseWithSpecialSyntax(JdbcConstants.POSTGRESQL,
"WITH field1_query AS (SELECT field1 FROM TABLE_XXX), field2_query AS (SELECT field2 FROM TABLE_XXX) DELETE FROM ONLY TABLE_XXX USING producers WHERE field1=1 OUTPUT *",
"WITH field1_query AS (SELECT field1 FROM TABLE_XXX), field2_query AS (SELECT field2 FROM TABLE_XXX) DELETE FROM ONLY [Token(TABLE_XXX)] USING producers WHERE field1=1 OUTPUT *");
}
private void parseWithSpecialSyntax(final String dbType, final String actualSQL) throws SQLException {
private void parseWithSpecialSyntax(final String dbType, final String actualSQL, final String expectedSQL) throws SQLException {
SQLDeleteStatement deleteStatement = (SQLDeleteStatement) getSqlStatementParser(dbType, actualSQL).parseStatement();
assertThat(deleteStatement.getSqlContext().getTable().getName(), is("TABLE_XXX"));
assertFalse(deleteStatement.getSqlContext().getTable().getAlias().isPresent());
......@@ -108,7 +118,6 @@ public final class DeleteStatementParserTest extends AbstractStatementParserTest
assertThat(condition.getValues().size(), is(1));
assertThat(condition.getValues().get(0), is((Comparable) 1));
assertFalse(conditions.hasNext());
String expectedSQL = actualSQL.contains("`TABLE_XXX`") ? actualSQL.replace("`TABLE_XXX`", "[Token(TABLE_XXX)]") : actualSQL.replace("TABLE_XXX", "[Token(TABLE_XXX)]");
assertThat(deleteStatement.getSqlContext().toSqlBuilder().toString().replace("([Token(TABLE_XXX)] )", "([Token(TABLE_XXX)])"), is(expectedSQL));
}
}
......@@ -105,16 +105,26 @@ public final class InsertStatementParserTest extends AbstractStatementParserTest
@Test
public void parseWithSpecialSyntax() {
parseWithSpecialSyntax(JdbcConstants.MYSQL, "INSERT LOW_PRIORITY IGNORE INTO `TABLE_XXX` PARTITION (partition1,partition2) (`field1`) VALUE (1)");
parseWithSpecialSyntax(JdbcConstants.MYSQL, "INSERT INTO TABLE_XXX SET field1=1");
parseWithSpecialSyntax(JdbcConstants.MYSQL, "INSERT LOW_PRIORITY IGNORE INTO `TABLE_XXX` PARTITION (partition1,partition2) (`field1`) VALUE (1)",
"INSERT LOW_PRIORITY IGNORE INTO [Token(TABLE_XXX)] PARTITION (partition1,partition2) (`field1`) VALUE (1)");
parseWithSpecialSyntax(JdbcConstants.MYSQL, "INSERT INTO TABLE_XXX SET field1=1", "INSERT INTO [Token(TABLE_XXX)] SET field1=1");
// TODO
// parseWithSpecialSyntax(JdbcConstants.MYSQL, "INSERT INTO TABLE_XXX (field1) SELECT field1 FROM TABLE_XXX2 ON DUPLICATE KEY UPDATE field1=field1+1");
parseWithSpecialSyntax(JdbcConstants.ORACLE, "INSERT /*+ index(field1) */ INTO TABLE_XXX (`field1`) VALUES (1) RETURNING field1*2 LOG ERRORS INTO TABLE_LOG");
parseWithSpecialSyntax(JdbcConstants.SQL_SERVER, "INSERT TOP(10) INTO OUTPUT TABLE_XXX (`field1`) VALUES (1)");
parseWithSpecialSyntax(JdbcConstants.POSTGRESQL, "INSERT INTO TABLE_XXX (field1) VALUES (1) RETURNING id");
// parseWithSpecialSyntax(JdbcConstants.MYSQL, "INSERT INTO TABLE_XXX (field1) SELECT field1 FROM TABLE_XXX2 ON DUPLICATE KEY UPDATE field1=field1+1",
// "INSERT INTO [Token(TABLE_XXX)] (field1) SELECT field1 FROM TABLE_XXX2 ON DUPLICATE KEY UPDATE field1=field1+1");
parseWithSpecialSyntax(JdbcConstants.ORACLE, "INSERT /*+ index(field1) */ INTO TABLE_XXX (`field1`) VALUES (1) RETURNING field1*2 LOG ERRORS INTO TABLE_LOG",
"INSERT /*+ index(field1) */ INTO [Token(TABLE_XXX)] (`field1`) VALUES (1) RETURNING field1*2 LOG ERRORS INTO TABLE_LOG");
parseWithSpecialSyntax(JdbcConstants.SQL_SERVER,
"WITH field_query (field1, field2) AS (SELECT field1, field2 FROM TABLE_XXX AS xxx GROUP BY field1) INSERT TOP(10) INTO OUTPUT TABLE_XXX (`field1`) VALUES (1)",
"WITH field_query (field1, field2) AS (SELECT field1, field2 FROM TABLE_XXX AS xxx GROUP BY field1) INSERT TOP(10) INTO OUTPUT [Token(TABLE_XXX)] (`field1`) VALUES (1)");
parseWithSpecialSyntax(JdbcConstants.POSTGRESQL,
"WITH RECURSIVE field_query (field1, field2) AS (SELECT field1, field2 FROM TABLE_XXX AS xxx ORDER BY field1 DESC) INSERT INTO TABLE_XXX (field1) VALUES (1) RETURNING id",
"WITH RECURSIVE field_query (field1, field2) AS (SELECT field1, field2 FROM TABLE_XXX AS xxx ORDER BY field1 DESC) INSERT INTO [Token(TABLE_XXX)] (field1) VALUES (1) RETURNING id");
parseWithSpecialSyntax(JdbcConstants.POSTGRESQL,
"WITH field1_query AS (SELECT field1 FROM TABLE_XXX), field2_query AS (SELECT field2 FROM TABLE_XXX) INSERT INTO TABLE_XXX (field1) VALUES (1) RETURNING *",
"WITH field1_query AS (SELECT field1 FROM TABLE_XXX), field2_query AS (SELECT field2 FROM TABLE_XXX) INSERT INTO [Token(TABLE_XXX)] (field1) VALUES (1) RETURNING *");
}
private void parseWithSpecialSyntax(final String dbType, final String actualSQL) {
private void parseWithSpecialSyntax(final String dbType, final String actualSQL, final String expectedSQL) {
SQLInsertStatement insertStatement = (SQLInsertStatement) getSqlStatementParser(dbType, actualSQL).parseStatement();
assertThat(insertStatement.getSqlContext().getTable().getName(), is("TABLE_XXX"));
assertFalse(insertStatement.getSqlContext().getTable().getAlias().isPresent());
......@@ -126,7 +136,6 @@ public final class InsertStatementParserTest extends AbstractStatementParserTest
assertThat(condition.getValues().size(), is(1));
assertThat(condition.getValues().get(0), is((Comparable) 1));
assertFalse(conditions.hasNext());
String expectedSQL = actualSQL.contains("`TABLE_XXX`") ? actualSQL.replace("`TABLE_XXX`", "[Token(TABLE_XXX)]") : actualSQL.replace("TABLE_XXX", "[Token(TABLE_XXX)]");
assertThat(insertStatement.getSqlContext().toSqlBuilder().toString(), is(expectedSQL));
}
......
......@@ -81,17 +81,27 @@ public final class UpdateStatementParserTest extends AbstractStatementParserTest
@Test
public void parseWithSpecialSyntax() {
parseWithSpecialSyntax(JdbcConstants.MYSQL, "UPDATE `TABLE_XXX` SET `field1`=1 WHERE `field1`=1");
parseWithSpecialSyntax(JdbcConstants.MYSQL, "UPDATE LOW_PRIORITY IGNORE TABLE_XXX SET field1=1 WHERE field1=1 ORDER BY field1 LIMIT 10");
parseWithSpecialSyntax(JdbcConstants.ORACLE, "UPDATE /*+ index(field1) */ ONLY TABLE_XXX SET field1=1 WHERE field1=1 RETURN * LOG ERRORS INTO TABLE_LOG");
parseWithSpecialSyntax(JdbcConstants.ORACLE, "UPDATE /*+ index(field1) */ ONLY TABLE_XXX SET field1=1 WHERE field1=1 RETURNING *");
parseWithSpecialSyntax(JdbcConstants.ORACLE, "UPDATE /*+ index(field1) */ ONLY TABLE_XXX SET field1=1 WHERE field1=1 LOG ERRORS INTO TABLE_LOG");
parseWithSpecialSyntax(JdbcConstants.SQL_SERVER, "UPDATE TOP(10) TABLE_XXX SET field1=1 OUTPUT (inserted.field1) WHERE field1=1");
parseWithSpecialSyntax(JdbcConstants.POSTGRESQL, "UPDATE ONLY TABLE_XXX SET field1=1 WHERE field1=1 RETURNING *");
parseWithSpecialSyntax(JdbcConstants.POSTGRESQL, "UPDATE ONLY TABLE_XXX SET (field1,field2)=(1,?) WHERE field1=1");
parseWithSpecialSyntax(JdbcConstants.MYSQL, "UPDATE `TABLE_XXX` SET `field1`=1 WHERE `field1`=1", "UPDATE [Token(TABLE_XXX)] SET `field1`=1 WHERE `field1`=1");
parseWithSpecialSyntax(JdbcConstants.MYSQL, "UPDATE LOW_PRIORITY IGNORE TABLE_XXX SET field1=1 WHERE field1=1 ORDER BY field1 LIMIT 10",
"UPDATE LOW_PRIORITY IGNORE [Token(TABLE_XXX)] SET field1=1 WHERE field1=1 ORDER BY field1 LIMIT 10");
parseWithSpecialSyntax(JdbcConstants.ORACLE, "UPDATE /*+ index(field1) */ ONLY TABLE_XXX SET field1=1 WHERE field1=1 RETURN * LOG ERRORS INTO TABLE_LOG",
"UPDATE /*+ index(field1) */ ONLY [Token(TABLE_XXX)] SET field1=1 WHERE field1=1 RETURN * LOG ERRORS INTO TABLE_LOG");
parseWithSpecialSyntax(JdbcConstants.ORACLE, "UPDATE /*+ index(field1) */ ONLY TABLE_XXX SET field1=1 WHERE field1=1 RETURNING *",
"UPDATE /*+ index(field1) */ ONLY [Token(TABLE_XXX)] SET field1=1 WHERE field1=1 RETURNING *");
parseWithSpecialSyntax(JdbcConstants.ORACLE, "UPDATE /*+ index(field1) */ ONLY TABLE_XXX SET field1=1 WHERE field1=1 LOG ERRORS INTO TABLE_LOG",
"UPDATE /*+ index(field1) */ ONLY [Token(TABLE_XXX)] SET field1=1 WHERE field1=1 LOG ERRORS INTO TABLE_LOG");
parseWithSpecialSyntax(JdbcConstants.SQL_SERVER,
"WITH field_query (field1) AS (SELECT field1 FROM TABLE_XXX AS xxx GROUP BY field1) UPDATE TOP(10) TABLE_XXX SET field1=1 OUTPUT (inserted.field1) WHERE field1=1",
"WITH field_query (field1) AS (SELECT field1 FROM TABLE_XXX AS xxx GROUP BY field1) UPDATE TOP(10) [Token(TABLE_XXX)] SET field1=1 OUTPUT (inserted.field1) WHERE field1=1");
parseWithSpecialSyntax(JdbcConstants.POSTGRESQL,
"WITH RECURSIVE field_query (field1) AS (SELECT field1 FROM TABLE_XXX AS xxx ORDER BY field1 DESC) UPDATE ONLY TABLE_XXX SET field1=1 WHERE field1=1 RETURNING *",
"WITH RECURSIVE field_query (field1) AS (SELECT field1 FROM TABLE_XXX AS xxx ORDER BY field1 DESC) UPDATE ONLY [Token(TABLE_XXX)] SET field1=1 WHERE field1=1 RETURNING *");
parseWithSpecialSyntax(JdbcConstants.POSTGRESQL,
"WITH field1_query AS (SELECT field1 FROM TABLE_XXX), field2_query AS (SELECT field2 FROM TABLE_XXX) UPDATE ONLY TABLE_XXX SET (field1,field2)=(1,?) WHERE field1=1",
"WITH field1_query AS (SELECT field1 FROM TABLE_XXX), field2_query AS (SELECT field2 FROM TABLE_XXX) UPDATE ONLY [Token(TABLE_XXX)] SET (field1,field2)=(1,?) WHERE field1=1");
}
private void parseWithSpecialSyntax(final String dbType, final String actualSQL) {
private void parseWithSpecialSyntax(final String dbType, final String actualSQL, final String expectedSQL) {
SQLUpdateStatement updateStatement = (SQLUpdateStatement) getSqlStatementParser(dbType, actualSQL).parseStatement();
assertThat(updateStatement.getSqlContext().getTable().getName(), is("TABLE_XXX"));
assertFalse(updateStatement.getSqlContext().getTable().getAlias().isPresent());
......@@ -103,7 +113,6 @@ public final class UpdateStatementParserTest extends AbstractStatementParserTest
assertThat(condition.getValues().size(), is(1));
assertThat(condition.getValues().get(0), is((Comparable) 1));
assertFalse(conditions.hasNext());
String expectedSQL = actualSQL.contains("`TABLE_XXX`") ? actualSQL.replace("`TABLE_XXX`", "[Token(TABLE_XXX)]") : actualSQL.replace("TABLE_XXX", "[Token(TABLE_XXX)]");
assertThat(updateStatement.getSqlContext().toSqlBuilder().toString(), is(expectedSQL));
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册