Skip to content

Commit 3b6bfba

Browse files
committed
[CALCITE-7331] Support the alias form SELECT * EXCEPT() for SELECT * EXCLUDE()
1 parent ca7be00 commit 3b6bfba

File tree

5 files changed

+36
-5
lines changed

5 files changed

+36
-5
lines changed

babel/src/test/java/org/apache/calcite/test/BabelTest.java

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,21 @@ names, is(
181181
});
182182

183183
fixture.withSql("select * exclude (empno, ^foo^) from emp")
184-
.fails("SELECT \\* EXCLUDE list contains unknown column\\(s\\): FOO");
184+
.fails("SELECT \\* EXCLUDE/EXCEPT list contains unknown column\\(s\\): FOO");
185+
186+
// Alias form: EXCEPT behaves the same as EXCLUDE
187+
fixture.withSql("select * except(empno, deptno) from emp")
188+
.type(type -> {
189+
final List<String> names = type.getFieldList().stream()
190+
.map(RelDataTypeField::getName)
191+
.collect(Collectors.toList());
192+
assertThat(
193+
names, is(
194+
ImmutableList.of("ENAME", "JOB", "MGR", "HIREDATE", "SAL", "COMM", "SLACKER")));
195+
});
196+
197+
fixture.withSql("select * except (empno, ^foo^) from emp")
198+
.fails("SELECT \\* EXCLUDE/EXCEPT list contains unknown column\\(s\\): FOO");
185199

186200
fixture.withSql("select e.* exclude(e.empno, e.ename, e.job, e.mgr)"
187201
+ " from emp e join dept d on e.deptno = d.deptno")
@@ -196,7 +210,23 @@ names, is(
196210

197211
fixture.withSql("select e.* exclude(e.empno, e.ename, e.job, e.mgr, ^d.deptno^)"
198212
+ " from emp e join dept d on e.deptno = d.deptno")
199-
.fails("SELECT \\* EXCLUDE list contains unknown column\\(s\\): D.DEPTNO");
213+
.fails("SELECT \\* EXCLUDE/EXCEPT list contains unknown column\\(s\\): D.DEPTNO");
214+
215+
// Alias form: EXCEPT for table-qualified star
216+
fixture.withSql("select e.* except(e.empno, e.ename, e.job, e.mgr)"
217+
+ " from emp e join dept d on e.deptno = d.deptno")
218+
.type(type -> {
219+
final List<String> names = type.getFieldList().stream()
220+
.map(RelDataTypeField::getName)
221+
.collect(Collectors.toList());
222+
assertThat(
223+
names, is(
224+
ImmutableList.of("HIREDATE", "SAL", "COMM", "DEPTNO", "SLACKER")));
225+
});
226+
227+
fixture.withSql("select e.* except(e.empno, e.ename, e.job, e.mgr, ^d.deptno^)"
228+
+ " from emp e join dept d on e.deptno = d.deptno")
229+
.fails("SELECT \\* EXCLUDE/EXCEPT list contains unknown column\\(s\\): D.DEPTNO");
200230

201231
fixture.withSql("select e.* exclude(e.empno, e.ename, e.job, e.mgr), d.* exclude(d.name)"
202232
+ " from emp e join dept d on e.deptno = d.deptno")

core/src/main/codegen/templates/Parser.jj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2020,7 +2020,7 @@ SqlNodeList StarExcludeList() :
20202020
SqlIdentifier id;
20212021
}
20222022
{
2023-
<EXCLUDE> <LPAREN> { s = span(); }
2023+
( <EXCLUDE> | <EXCEPT> ) <LPAREN> { s = span(); }
20242024
id = CompoundIdentifier() {
20252025
list.add(id);
20262026
}

core/src/main/java/org/apache/calcite/runtime/CalciteResource.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -810,7 +810,7 @@ ExInst<CalciteException> illegalArgumentForTableFunctionCall(String a0,
810810
@BaseMessage("EXCLUDE clause must follow a STAR expression")
811811
ExInst<CalciteException> selectExcludeRequiresStar();
812812

813-
@BaseMessage("SELECT * EXCLUDE list contains unknown column(s): {0}")
813+
@BaseMessage("SELECT * EXCLUDE/EXCEPT list contains unknown column(s): {0}")
814814
ExInst<SqlValidatorException> selectStarExcludeListContainsUnknownColumns(String columns);
815815

816816
@BaseMessage("SELECT * EXCLUDE list cannot exclude all columns")

core/src/main/resources/org/apache/calcite/runtime/CalciteResource.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ SelectStarRequiresFrom=SELECT * requires a FROM clause
269269
SelectExcludeRequiresStar=EXCLUDE clause must follow a STAR expression
270270
SelectStarExcludeListContainsUnknownColumns=SELECT * EXCLUDE list contains unknown column(s): {0}
271271
SelectStarExcludeCannotExcludeAllColumns=SELECT * EXCLUDE list cannot exclude all columns
272+
SelectStarExcludeListContainsUnknownColumns=SELECT * EXCLUDE/EXCEPT list contains unknown column(s): {0}
272273
GroupFunctionMustAppearInGroupByClause=Group function ''{0}'' can only appear in GROUP BY clause
273274
AuxiliaryWithoutMatchingGroupCall=Call to auxiliary group function ''{0}'' must have matching call to group function ''{1}'' in GROUP BY clause
274275
PivotAggMalformed=Measure expression in PIVOT must use aggregate function

site/_docs/reference.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ starWithExclude:
224224

225225
Note:
226226

227-
* `SELECT * EXCLUDE (...)` is recognized only when the Babel parser is enabled. It sets the generated parser configuration flag `includeStarExclude` to `true` (the standard parser leaves that flag `false`), which allows a `STAR` token followed by `EXCLUDE` and a parenthesized identifier list to be parsed into a `SqlStarExclude` node and ensures validators respect the exclusion list when expanding the projection. Reusing the same parser configuration elsewhere enables the same syntax for other components that need it.
227+
* `SELECT * EXCLUDE (...)` is recognized only when the Babel parser is enabled. It sets the generated parser configuration flag `includeStarExclude` to `true` (the standard parser leaves that flag `false`), which allows a `STAR` token followed by `EXCLUDE` (or the alias `EXCEPT`) and a parenthesized identifier list to be parsed into a `SqlStarExclude` node and ensures validators respect the exclusion list when expanding the projection. Reusing the same parser configuration elsewhere enables the same syntax for other components that need it.
228228

229229
projectItem:
230230
expression [ [ AS ] columnAlias ]

0 commit comments

Comments
 (0)