From 3dd61cd9860e681444782f792e063a890340d0b8 Mon Sep 17 00:00:00 2001 From: LiZongbo Date: Sun, 24 Mar 2024 19:08:05 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=20drop=20column=20if=20exist?= =?UTF-8?q?s=E7=9A=84=E8=A7=A3=E6=9E=90=E6=94=AF=E6=8C=81=20#5797?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 优化 drop column if exists的解析支持 #5797 --- .../mysql/parser/MySqlStatementParser.java | 6 +- .../oracle/parser/OracleStatementParser.java | 5 ++ .../parser/SQLServerStatementParser.java | 6 +- .../druid/bvt/sql/mysql/issues/Issue5797.java | 62 +++++++++++++++++++ 4 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 core/src/test/java/com/alibaba/druid/bvt/sql/mysql/issues/Issue5797.java diff --git a/core/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java b/core/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java index 4821a42da6..4ebc130323 100644 --- a/core/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java +++ b/core/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java @@ -8002,7 +8002,11 @@ public void parseAlterDrop(SQLAlterTableStatement stmt) { } else if (lexer.token() == Token.COLUMN) { lexer.nextToken(); SQLAlterTableDropColumnItem item = new SQLAlterTableDropColumnItem(); - + if (lexer.token() == Token.IF) { + lexer.nextToken(); + accept(Token.EXISTS); + item.setIfExists(true); + } SQLName name = exprParser.name(); name.setParent(item); item.addColumn(name); diff --git a/core/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java b/core/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java index 0763cce6ca..3c03d16783 100644 --- a/core/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java +++ b/core/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java @@ -1746,6 +1746,11 @@ public void parseAlterDrop(SQLAlterTableStatement stmt) { } else if (lexer.token() == Token.COLUMN) { lexer.nextToken(); SQLAlterTableDropColumnItem item = new SQLAlterTableDropColumnItem(); + if (lexer.token() == Token.IF) { + lexer.nextToken(); + accept(Token.EXISTS); + item.setIfExists(true); + } this.exprParser.names(item.getColumns()); stmt.addItem(item); } else if (lexer.token() == Token.PARTITION) { diff --git a/core/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerStatementParser.java b/core/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerStatementParser.java index 4cf0f9f36e..426718edfd 100644 --- a/core/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerStatementParser.java +++ b/core/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerStatementParser.java @@ -590,7 +590,11 @@ public void parseAlterDrop(SQLAlterTableStatement stmt) { } else if (lexer.token() == Token.COLUMN) { lexer.nextToken(); SQLAlterTableDropColumnItem item = new SQLAlterTableDropColumnItem(); - + if (lexer.token() == Token.IF) { + lexer.nextToken(); + accept(Token.EXISTS); + item.setIfExists(true); + } SQLName name = exprParser.name(); name.setParent(item); item.addColumn(name); diff --git a/core/src/test/java/com/alibaba/druid/bvt/sql/mysql/issues/Issue5797.java b/core/src/test/java/com/alibaba/druid/bvt/sql/mysql/issues/Issue5797.java new file mode 100644 index 0000000000..0ce16d9cb4 --- /dev/null +++ b/core/src/test/java/com/alibaba/druid/bvt/sql/mysql/issues/Issue5797.java @@ -0,0 +1,62 @@ +package com.alibaba.druid.bvt.sql.mysql.issues; + +import java.util.List; + +import com.alibaba.druid.DbType; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.parser.SQLParserUtils; +import com.alibaba.druid.sql.parser.SQLStatementParser; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * @author lizongbo + * @see Issue来源 + */ +public class Issue5797 { + + @Test + public void test_parse_create_table() { + for (DbType dbType : new DbType[]{ + DbType.mysql, + DbType.postgresql, + DbType.oracle, + DbType.mariadb, + DbType.sqlserver, + DbType.h2, + DbType.hive, + //DbType.gaussdb, + //DbType.oscar, +// DbType.db2, +// DbType.dm, DbType.kingbase, + + }) { + + for (String sql : new String[]{ + "-- 给课程表增加类型字段\n" + + "alter table info_course drop column if exists course_type_id", + + }) { + System.out.println(dbType + "原始的sql===" + sql); + SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType); + List statementList = parser.parseStatementList(); + com.alibaba.druid.sql.ast.statement.SQLJoinTableSource ggg; + String sqlGen = statementList.toString(); + System.out.println(dbType + "生成的sql===" + sqlGen); + StringBuilder sb = new StringBuilder(); + for (SQLStatement statement : statementList) { + sb.append(statement.toString()).append(";"); + } + sb.deleteCharAt(sb.length() - 1); + parser = SQLParserUtils.createSQLStatementParser(sb.toString(), dbType); + List statementListNew = parser.parseStatementList(); + String sqlGenNew = statementList.toString(); + System.out.println(dbType + "重新解析再生成的sql===" + sqlGenNew); + assertEquals(statementList.toString(), statementListNew.toString()); + } + } + } +}