From 228658f87d4ad725b4c082cf8c55f27a659581ae Mon Sep 17 00:00:00 2001 From: dengliming Date: Sat, 22 Aug 2026 12:49:59 +0800 Subject: [PATCH] fix(parser): support IF EXISTS in ALTER TABLE MODIFY COLUMN - accept both IF EXISTS and IF NOT EXISTS with optional COLUMN - preserve existence clauses when deparsing - add round-trip and AST regression tests --- .../statement/alter/AlterExpression.java | 5 +++-- .../net/sf/jsqlparser/parser/JSqlParserCC.jjt | 9 ++++++++- .../jsqlparser/statement/alter/AlterTest.java | 19 +++++++++++++++++++ 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/sf/jsqlparser/statement/alter/AlterExpression.java b/src/main/java/net/sf/jsqlparser/statement/alter/AlterExpression.java index 43615abdb..dd4e07f52 100644 --- a/src/main/java/net/sf/jsqlparser/statement/alter/AlterExpression.java +++ b/src/main/java/net/sf/jsqlparser/statement/alter/AlterExpression.java @@ -1118,8 +1118,9 @@ protected void toStringGeneral(StringBuilder b) { } else if (hasColumns) { b.append("COLUMNS "); } - if (useIfNotExists - && operation == AlterOperation.ADD) { + if (usingIfExists) { + b.append("IF EXISTS "); + } else if (useIfNotExists) { b.append("IF NOT EXISTS "); } } diff --git a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt index 974c93baf..db125a614 100644 --- a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt +++ b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt @@ -12633,7 +12633,14 @@ AlterExpression AlterExpressionAddAlterModify(): { alterExp.hasColumns(true); } ) )? - [ LOOKAHEAD(2) { alterExp.setUseIfNotExists(true); } ] + [ + LOOKAHEAD(2) + ( + { alterExp.setUseIfNotExists(true); } + | + { alterExp.setUsingIfExists(true); } + ) + ] ( LOOKAHEAD(3) AlterExpressionColumnChanges(alterExp) | diff --git a/src/test/java/net/sf/jsqlparser/statement/alter/AlterTest.java b/src/test/java/net/sf/jsqlparser/statement/alter/AlterTest.java index 5ba1a8762..35481fb7e 100644 --- a/src/test/java/net/sf/jsqlparser/statement/alter/AlterTest.java +++ b/src/test/java/net/sf/jsqlparser/statement/alter/AlterTest.java @@ -1109,6 +1109,25 @@ public void testIssue1875() throws JSQLParserException { assertSqlCanBeParsedAndDeparsed(stmt); } + @ParameterizedTest + @MethodSource("provideModifyColumnExistenceClauses") + public void testModifyColumnExistenceClauses(String sql, boolean usingIfExists, + boolean useIfNotExists) throws JSQLParserException { + Alter alter = (Alter) assertSqlCanBeParsedAndDeparsed(sql); + AlterExpression expression = alter.getAlterExpressions().get(0); + + assertEquals(usingIfExists, expression.isUsingIfExists()); + assertEquals(useIfNotExists, expression.isUseIfNotExists()); + } + + private static Stream provideModifyColumnExistenceClauses() { + return Stream.of( + Arguments.of("ALTER TABLE t MODIFY COLUMN IF EXISTS c INT", true, false), + Arguments.of("ALTER TABLE t MODIFY IF EXISTS c INT", true, false), + Arguments.of("ALTER TABLE t MODIFY COLUMN IF NOT EXISTS c INT", false, true), + Arguments.of("ALTER TABLE t MODIFY IF NOT EXISTS c INT", false, true)); + } + @Test public void testIssue2027() throws JSQLParserException { String sql = "ALTER TABLE `foo_bar` ADD COLUMN `baz` text";