2525public class ColumnsTransformer extends ASTNodeAccessImpl {
2626
2727 public enum ColumnsTransformerType {
28- APPLY , EXCEPT , EXCLUDE , REPLACE
28+ APPLY , EXCEPT , EXCLUDE , REPLACE , RENAME
2929 }
3030
3131 private ColumnsTransformerType type ;
3232 private Expression applyExpression ;
3333 private ParenthesedExpressionList <Column > exceptColumns ;
3434 private StringValue exceptPattern ;
3535 private List <SelectItem <?>> replaceItems ;
36+ private List <SelectItem <?>> renameItems ;
37+ private boolean parenthesized = true ;
3638 private boolean strict ;
3739
3840 public ColumnsTransformer (ColumnsTransformerType type ) {
@@ -108,6 +110,30 @@ public ColumnsTransformer setReplaceItems(List<SelectItem<?>> replaceItems) {
108110 return this ;
109111 }
110112
113+ /** DuckDB's {@code RENAME (column AS name, ...)}: each item is a column with its new name. */
114+ public List <SelectItem <?>> getRenameItems () {
115+ return renameItems ;
116+ }
117+
118+ public ColumnsTransformer setRenameItems (List <SelectItem <?>> renameItems ) {
119+ this .renameItems = renameItems ;
120+ return this ;
121+ }
122+
123+ /**
124+ * Whether the columns or items of an {@code EXCLUDE}, {@code REPLACE} or {@code RENAME} are
125+ * parenthesized; DuckDB also accepts a single one without parentheses, e.g.
126+ * {@code * EXCLUDE i}.
127+ */
128+ public boolean isParenthesized () {
129+ return parenthesized ;
130+ }
131+
132+ public ColumnsTransformer setParenthesized (boolean parenthesized ) {
133+ this .parenthesized = parenthesized ;
134+ return this ;
135+ }
136+
111137 void collectExpressions (List <Expression > expressions ) {
112138 switch (type ) {
113139 case APPLY :
@@ -135,6 +161,13 @@ void collectExpressions(List<Expression> expressions) {
135161 }
136162 }
137163 break ;
164+ case RENAME :
165+ if (renameItems != null ) {
166+ for (SelectItem <?> item : renameItems ) {
167+ expressions .add (item .getExpression ());
168+ }
169+ }
170+ break ;
138171 default :
139172 throw new IllegalStateException ("Unhandled ColumnsTransformerType: " + type );
140173 }
@@ -150,11 +183,22 @@ public StringBuilder appendTo(StringBuilder builder) {
150183 .append (exceptPattern != null ? exceptPattern : exceptColumns );
151184 break ;
152185 case EXCLUDE :
153- builder .append ("EXCLUDE " ).append (exceptColumns );
186+ builder .append ("EXCLUDE " ).append (parenthesized || exceptColumns .size () != 1
187+ ? exceptColumns
188+ : exceptColumns .get (0 ));
154189 break ;
155190 case REPLACE :
156- builder .append ("REPLACE" ).append (strict ? " STRICT" : "" ).append ("(" )
157- .append (Select .getStringList (replaceItems )).append (")" );
191+ boolean replaceParenthesized = parenthesized || replaceItems .size () != 1 ;
192+ builder .append ("REPLACE" ).append (strict ? " STRICT" : "" )
193+ .append (replaceParenthesized ? "(" : " " )
194+ .append (Select .getStringList (replaceItems ))
195+ .append (replaceParenthesized ? ")" : "" );
196+ break ;
197+ case RENAME :
198+ boolean renameParenthesized = parenthesized || renameItems .size () != 1 ;
199+ builder .append ("RENAME " ).append (renameParenthesized ? "(" : "" )
200+ .append (Select .getStringList (renameItems ))
201+ .append (renameParenthesized ? ")" : "" );
158202 break ;
159203 default :
160204 throw new IllegalStateException ("Unhandled ColumnsTransformerType: " + type );
0 commit comments