You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by hy...@apache.org on 2019/04/12 23:07:54 UTC
[calcite] branch master updated: [CALCITE-2977] Exception is not
thrown when there are ambiguous field in select list
This is an automated email from the ASF dual-hosted git repository.
hyuan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/calcite.git
The following commit(s) were added to refs/heads/master by this push:
new 38e3c30 [CALCITE-2977] Exception is not thrown when there are ambiguous field in select list
38e3c30 is described below
commit 38e3c3015b661f8f9dc61d8d0ef4be6186a4bc7a
Author: pengzhiwei <pe...@icloud.com>
AuthorDate: Thu Apr 4 16:32:21 2019 +0800
[CALCITE-2977] Exception is not thrown when there are ambiguous field in select list
Close #1147
---
.../calcite/sql/validate/DelegatingScope.java | 24 +++++++----
.../apache/calcite/test/SqlToRelConverterTest.java | 2 +-
.../org/apache/calcite/test/SqlValidatorTest.java | 47 +++++++++++++++-------
3 files changed, 50 insertions(+), 23 deletions(-)
diff --git a/core/src/main/java/org/apache/calcite/sql/validate/DelegatingScope.java b/core/src/main/java/org/apache/calcite/sql/validate/DelegatingScope.java
index cf5d9d2..ee9e112 100644
--- a/core/src/main/java/org/apache/calcite/sql/validate/DelegatingScope.java
+++ b/core/src/main/java/org/apache/calcite/sql/validate/DelegatingScope.java
@@ -273,8 +273,8 @@ public abstract class DelegatingScope implements SqlValidatorScope {
final RelDataTypeField field =
nameMatcher.field(namespace.getRowType(), columnName);
if (field != null) {
- if (hasAmbiguousUnresolvedStar(namespace.getRowType(), field,
- columnName)) {
+ if (hasAmbiguousField(namespace.getRowType(), field,
+ columnName, nameMatcher)) {
throw validator.newValidationError(identifier,
RESOURCE.columnAmbiguous(columnName));
}
@@ -492,7 +492,7 @@ public abstract class DelegatingScope implements SqlValidatorScope {
if (!fieldName.equals(name)) {
identifier = identifier.setName(k, fieldName);
}
- if (hasAmbiguousUnresolvedStar(step.rowType, field0, name)) {
+ if (hasAmbiguousField(step.rowType, field0, name, nameMatcher)) {
throw validator.newValidationError(identifier,
RESOURCE.columnAmbiguous(name));
}
@@ -542,10 +542,10 @@ public abstract class DelegatingScope implements SqlValidatorScope {
return parent.getOrderList();
}
- /** Returns whether {@code rowType} contains more than one star column.
- * Having more than one star columns implies ambiguous column. */
- private boolean hasAmbiguousUnresolvedStar(RelDataType rowType,
- RelDataTypeField field, String columnName) {
+ /** Returns whether {@code rowType} contains more than one star column or
+ * fields with the same name, which implies ambiguous column. */
+ private boolean hasAmbiguousField(RelDataType rowType,
+ RelDataTypeField field, String columnName, SqlNameMatcher nameMatcher) {
if (field.isDynamicStar()
&& !DynamicRecordType.isDynamicStarColName(columnName)) {
int count = 0;
@@ -556,6 +556,16 @@ public abstract class DelegatingScope implements SqlValidatorScope {
}
}
}
+ } else { // check if there are fields with the same name
+ int count = 0;
+ for (RelDataTypeField f : rowType.getFieldList()) {
+ if (Util.matches(nameMatcher.isCaseSensitive(), f.getName(), columnName)) {
+ count++;
+ }
+ }
+ if (count > 1) {
+ return true;
+ }
}
return false;
}
diff --git a/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java b/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java
index d4e2c9b..35b8841 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java
@@ -596,7 +596,7 @@ public class SqlToRelConverterTest extends SqlToRelTestBase {
* and rename the second column to "e0". */
@Test public void testDuplicateColumnsInSubQuery() {
String sql = "select \"e\" from (\n"
- + "select empno as \"e\", deptno as d, 1 as \"e\" from EMP)";
+ + "select empno as \"e\", deptno as d, 1 as \"e0\" from EMP)";
sql(sql).ok();
}
diff --git a/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java b/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
index b12bbca..4238a9c 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
@@ -5743,7 +5743,7 @@ public class SqlValidatorTest extends SqlValidatorTestCase {
// make sal occur more than once on rhs, it is ignored and therefore
// there is no error about incompatible types
sql("select * from emp natural join\n"
- + " (select deptno, name as sal, 'foo' as sal from dept)").ok();
+ + " (select deptno, name as sal, 'foo' as sal2 from dept)").ok();
}
@Test public void testJoinUsingIncompatibleDatatype() {
@@ -6390,7 +6390,7 @@ public class SqlValidatorTest extends SqlValidatorTestCase {
// empno is not an alias in the first select in the union
checkFails(
- "select deptno, deptno from dept "
+ "select deptno, deptno as no2 from dept "
+ "union all "
+ "select empno, sal from emp "
+ "order by deptno asc, ^empno^",
@@ -7934,6 +7934,21 @@ public class SqlValidatorTest extends SqlValidatorTestCase {
.fails("SELECT must have a FROM clause");
}
+ @Test public void testSelectAmbiguousField() {
+ tester = tester.withCaseSensitive(false)
+ .withUnquotedCasing(Casing.UNCHANGED);
+ sql("select ^t0^ from (select 1 as t0, 2 as T0 from dept)")
+ .fails("Column 't0' is ambiguous");
+ sql("select ^t0^ from (select 1 as t0, 2 as t0,3 as t1,4 as t1, 5 as t2 from dept)")
+ .fails("Column 't0' is ambiguous");
+ // t0 is not referenced,so this case is allowed
+ sql("select 1 as t0, 2 as t0 from dept").ok();
+
+ tester = tester.withCaseSensitive(true)
+ .withUnquotedCasing(Casing.UNCHANGED);
+ sql("select t0 from (select 1 as t0, 2 as T0 from DEPT)").ok();
+ }
+
@Test public void testTableExtend() {
checkResultType("select * from dept extend (x int not null)",
"RecordType(INTEGER NOT NULL DEPTNO, VARCHAR(10) NOT NULL NAME, INTEGER NOT NULL X) NOT NULL");
@@ -8576,19 +8591,20 @@ public class SqlValidatorTest extends SqlValidatorTestCase {
@Test public void testCaseSensitiveBuiltinFunction() {
final SqlTester tester1 = tester
.withCaseSensitive(true)
+ .withUnquotedCasing(Casing.UNCHANGED)
.withQuoting(Quoting.BRACKET);
tester1.withOperatorTable(SqlStdOperatorTable.instance());
- tester1.checkQuery("select sum(empno) from EMP group by ename, empno");
- tester1.checkQuery("select [sum](empno) from EMP group by ename, empno");
- tester1.checkQuery("select [SUM](empno) from EMP group by ename, empno");
- tester1.checkQuery("select SUM(empno) from EMP group by ename, empno");
- tester1.checkQuery("select Sum(empno) from EMP group by ename, empno");
- tester1.checkQuery("select count(empno) from EMP group by ename, empno");
- tester1.checkQuery("select [count](empno) from EMP group by ename, empno");
- tester1.checkQuery("select [COUNT](empno) from EMP group by ename, empno");
- tester1.checkQuery("select COUNT(empno) from EMP group by ename, empno");
- tester1.checkQuery("select Count(empno) from EMP group by ename, empno");
+ tester1.checkQuery("select sum(EMPNO) from EMP group by ENAME, EMPNO");
+ tester1.checkQuery("select [sum](EMPNO) from EMP group by ENAME, EMPNO");
+ tester1.checkQuery("select [SUM](EMPNO) from EMP group by ENAME, EMPNO");
+ tester1.checkQuery("select SUM(EMPNO) from EMP group by ENAME, EMPNO");
+ tester1.checkQuery("select Sum(EMPNO) from EMP group by ENAME, EMPNO");
+ tester1.checkQuery("select count(EMPNO) from EMP group by ENAME, EMPNO");
+ tester1.checkQuery("select [count](EMPNO) from EMP group by ENAME, EMPNO");
+ tester1.checkQuery("select [COUNT](EMPNO) from EMP group by ENAME, EMPNO");
+ tester1.checkQuery("select COUNT(EMPNO) from EMP group by ENAME, EMPNO");
+ tester1.checkQuery("select Count(EMPNO) from EMP group by ENAME, EMPNO");
}
/** Test case for
@@ -9022,13 +9038,14 @@ public class SqlValidatorTest extends SqlValidatorTestCase {
.withQuoting(Quoting.BRACKET);
final SqlTester sensitive = tester
.withCaseSensitive(true)
+ .withUnquotedCasing(Casing.UNCHANGED)
.withQuoting(Quoting.BRACKET);
String sql = "select [e] from (\n"
- + "select empno as [e], deptno as d, 1 as [e] from EMP)";
+ + "select EMPNO as [e], DEPTNO as d, 1 as [e2] from EMP)";
sensitive.checkQuery(sql);
insensitive.checkQuery(sql);
- String sql1 = "select e from (\n"
- + "select empno as [e], deptno as d, 1 as [E] from EMP)";
+ String sql1 = "select e2 from (\n"
+ + "select EMPNO as [e2], DEPTNO as d, 1 as [E] from EMP)";
insensitive.checkQuery(sql1);
sensitive.checkQuery(sql1);
}