diff --git a/src/main/java/net/sf/jsqlparser/statement/select/AllColumns.java b/src/main/java/net/sf/jsqlparser/statement/select/AllColumns.java index 08b8532e3..749cdbf99 100644 --- a/src/main/java/net/sf/jsqlparser/statement/select/AllColumns.java +++ b/src/main/java/net/sf/jsqlparser/statement/select/AllColumns.java @@ -9,15 +9,14 @@ */ package net.sf.jsqlparser.statement.select; +import java.util.ArrayList; +import java.util.List; import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.ExpressionVisitor; import net.sf.jsqlparser.expression.operators.relational.ExpressionList; import net.sf.jsqlparser.parser.ASTNodeAccessImpl; import net.sf.jsqlparser.schema.Column; -import java.util.ArrayList; -import java.util.List; - public class AllColumns extends ASTNodeAccessImpl implements Expression { protected ExpressionList exceptColumns; protected List> replaceExpressions; @@ -87,7 +86,8 @@ public AllColumns setExceptKeyword(String exceptKeyword) { public StringBuilder appendTo(StringBuilder builder) { builder.append("*"); if (exceptColumns != null && !exceptColumns.isEmpty()) { - builder.append(" ").append(exceptKeyword).append("( "); + builder.append(" ").append(exceptKeyword == null ? "EXCEPT" : exceptKeyword) + .append("( "); exceptColumns.appendTo(builder); builder.append(" )"); } diff --git a/src/test/java/net/sf/jsqlparser/statement/select/AllColumnsTest.java b/src/test/java/net/sf/jsqlparser/statement/select/AllColumnsTest.java index 7f5aaba4c..2feeb33b3 100644 --- a/src/test/java/net/sf/jsqlparser/statement/select/AllColumnsTest.java +++ b/src/test/java/net/sf/jsqlparser/statement/select/AllColumnsTest.java @@ -9,7 +9,15 @@ */ package net.sf.jsqlparser.statement.select; +import static net.sf.jsqlparser.test.TestUtils.assertDeparse; +import static net.sf.jsqlparser.test.TestUtils.assertSqlCanBeParsedAndDeparsed; +import static org.junit.jupiter.api.Assertions.assertEquals; + import net.sf.jsqlparser.JSQLParserException; +import net.sf.jsqlparser.expression.operators.relational.ExpressionList; +import net.sf.jsqlparser.parser.CCJSqlParserUtil; +import net.sf.jsqlparser.schema.Column; +import net.sf.jsqlparser.schema.Table; import net.sf.jsqlparser.test.TestUtils; import org.junit.jupiter.api.Test; @@ -31,4 +39,52 @@ void testDuckDBQuerySyntax() throws JSQLParserException { + "FROM orders"; TestUtils.assertSqlCanBeParsedAndDeparsed(sqlStr, true); } + + @Test + void addExceptColumnToNewWildcard() throws JSQLParserException { + AllColumns columns = new AllColumns(); + columns.addExceptColumn(new Column("hidden")); + PlainSelect select = new PlainSelect().addSelectItem(columns).withFromItem(new Table("t")); + + String expected = "SELECT * EXCEPT( hidden ) FROM t"; + assertEquals(expected, select.toString()); + assertDeparse(select, expected); + assertSqlCanBeParsedAndDeparsed(expected); + } + + @Test + void setExceptColumnsOnParsedWildcard() throws JSQLParserException { + PlainSelect select = (PlainSelect) CCJSqlParserUtil.parse("SELECT * FROM t"); + AllColumns columns = select.getSelectItem(0).getExpression(AllColumns.class); + columns.setExceptColumns(new ExpressionList<>(new Column("hidden"))); + + String expected = "SELECT * EXCEPT( hidden ) FROM t"; + assertEquals(expected, select.toString()); + assertDeparse(select, expected); + assertSqlCanBeParsedAndDeparsed(expected); + } + + @Test + void addExceptColumnToParsedTableWildcard() throws JSQLParserException { + PlainSelect select = (PlainSelect) CCJSqlParserUtil.parse("SELECT t.* FROM t"); + AllTableColumns columns = select.getSelectItem(0).getExpression(AllTableColumns.class); + columns.addExceptColumn(new Column("hidden")); + + String expected = "SELECT t.* EXCEPT( hidden ) FROM t"; + assertEquals(expected, select.toString()); + assertDeparse(select, expected); + assertSqlCanBeParsedAndDeparsed(expected); + } + + @Test + void preserveExplicitExceptKeywordAndEmptyColumns() { + AllColumns columns = new AllColumns().setExceptKeyword("EXCLUDE"); + columns.addExceptColumn(new Column("hidden")); + assertEquals("* EXCLUDE( hidden )", columns.toString()); + + columns.setExceptColumns(new ExpressionList<>()); + assertEquals("*", columns.toString()); + columns.setExceptColumns(null); + assertEquals("*", columns.toString()); + } }