You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by ma...@apache.org on 2016/10/18 22:44:25 UTC
calcite git commit: [CALCITE-1426] Support customized star expansion
in Table
Repository: calcite
Updated Branches:
refs/heads/master 105bba1f8 -> 5be0f0b04
[CALCITE-1426] Support customized star expansion in Table
Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/5be0f0b0
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/5be0f0b0
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/5be0f0b0
Branch: refs/heads/master
Commit: 5be0f0b046e36ea2ca3c052626599534dd8b0f71
Parents: 105bba1
Author: maryannxue <ma...@gmail.com>
Authored: Tue Oct 18 15:44:02 2016 -0700
Committer: maryannxue <ma...@gmail.com>
Committed: Tue Oct 18 15:44:02 2016 -0700
----------------------------------------------------------------------
.../calcite/schema/CustomExpansionTable.java | 42 ++++++
.../org/apache/calcite/sql/SqlIdentifier.java | 10 --
.../java/org/apache/calcite/sql/SqlInsert.java | 4 +
.../calcite/sql/advise/SqlAdvisorValidator.java | 7 +
.../calcite/sql/validate/SqlValidator.java | 7 +
.../calcite/sql/validate/SqlValidatorImpl.java | 127 +++++++++++--------
.../apache/calcite/test/MockCatalogReader.java | 75 +++++++++--
.../calcite/test/SqlToRelConverterTest.java | 6 +
.../apache/calcite/test/SqlValidatorTest.java | 6 +
.../org/apache/calcite/test/RelOptRulesTest.xml | 12 +-
.../calcite/test/SqlToRelConverterTest.xml | 18 ++-
11 files changed, 236 insertions(+), 78 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/calcite/blob/5be0f0b0/core/src/main/java/org/apache/calcite/schema/CustomExpansionTable.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/schema/CustomExpansionTable.java b/core/src/main/java/org/apache/calcite/schema/CustomExpansionTable.java
new file mode 100644
index 0000000..21ac696
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/schema/CustomExpansionTable.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.schema;
+
+import java.util.List;
+
+/**
+ * Extension to {@link Table} that specifies a list of column names for
+ * custom star expansion. The columns specified in the list can be any
+ * top-level column from the Table or any field or nested field under a
+ * top-level column, thus each column name is returned as a list of String
+ * objects representing the full name of the column or field. This expansion
+ * list will also be used as target columns in INSERT if the original target
+ * column list is not present.
+ *
+ * <p>It is optional for a Table to implement this interface. If Table does
+ * not implement this interface, star expansion will be performed in the
+ * default way according to the Table's row type.</p>
+ *
+ * <p><strong>NOTE: This class is experimental and subject to
+ * change/removal without notice</strong>.</p>
+ */
+public interface CustomExpansionTable extends Table {
+ /** Returns a list of column names for custom star expansion. */
+ List<List<String>> getCustomStarExpansion();
+}
+
+// End CustomExpansionTable.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/5be0f0b0/core/src/main/java/org/apache/calcite/sql/SqlIdentifier.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlIdentifier.java b/core/src/main/java/org/apache/calcite/sql/SqlIdentifier.java
index 7e2294c..d070150 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlIdentifier.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlIdentifier.java
@@ -258,16 +258,6 @@ public class SqlIdentifier extends SqlNode {
return new SqlIdentifier(names, collation, pos2, componentPositions);
}
- /**
- * Creates an identifier that consists of this identifier plus a wildcard star.
- * Does not modify this identifier.
- */
- public SqlIdentifier plusStar() {
- final SqlIdentifier id = this.plus("*", SqlParserPos.ZERO);
- return new SqlIdentifier(Lists.transform(id.names, STAR_TO_EMPTY), null, id.pos,
- id.componentPositions);
- }
-
/** Creates an identifier that consists of all but the last {@code n}
* name segments of this one. */
public SqlIdentifier skipLast(int n) {
http://git-wip-us.apache.org/repos/asf/calcite/blob/5be0f0b0/core/src/main/java/org/apache/calcite/sql/SqlInsert.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlInsert.java b/core/src/main/java/org/apache/calcite/sql/SqlInsert.java
index 19472a7..1c9030e 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlInsert.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlInsert.java
@@ -120,6 +120,10 @@ public class SqlInsert extends SqlCall {
return columnList;
}
+ public void setTargetColumnList(SqlNodeList columnList) {
+ this.columnList = columnList;
+ }
+
public final SqlNode getModifierNode(SqlInsertKeyword modifier) {
for (SqlNode keyword : keywords) {
SqlInsertKeyword keyword2 =
http://git-wip-us.apache.org/repos/asf/calcite/blob/5be0f0b0/core/src/main/java/org/apache/calcite/sql/advise/SqlAdvisorValidator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/advise/SqlAdvisorValidator.java b/core/src/main/java/org/apache/calcite/sql/advise/SqlAdvisorValidator.java
index 4d07e79..90f68cc 100644
--- a/core/src/main/java/org/apache/calcite/sql/advise/SqlAdvisorValidator.java
+++ b/core/src/main/java/org/apache/calcite/sql/advise/SqlAdvisorValidator.java
@@ -201,6 +201,13 @@ public class SqlAdvisorValidator extends SqlValidatorImpl {
return true;
}
+ public boolean shouldUseCustomStarExpansion() {
+ // Disable custom star expansion otherwise SqlValidatorNamespace.getTable()
+ // could be called on a SqlValidatorNamespace that was not successfully
+ // validated.
+ return false;
+ }
+
protected boolean shouldAllowOverRelation() {
return true; // no reason not to be lenient
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/5be0f0b0/core/src/main/java/org/apache/calcite/sql/validate/SqlValidator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/validate/SqlValidator.java b/core/src/main/java/org/apache/calcite/sql/validate/SqlValidator.java
index 215b96c..cc14c36 100644
--- a/core/src/main/java/org/apache/calcite/sql/validate/SqlValidator.java
+++ b/core/src/main/java/org/apache/calcite/sql/validate/SqlValidator.java
@@ -617,6 +617,13 @@ public interface SqlValidator {
boolean shouldExpandIdentifiers();
/**
+ * Returns whether to use a Table's custom star expansion.
+ *
+ * @return true if custom star expansion should be used; false otherwise.
+ */
+ boolean shouldUseCustomStarExpansion();
+
+ /**
* Enables or disables rewrite of "macro-like" calls such as COALESCE.
*
* @param rewriteCalls new setting
http://git-wip-us.apache.org/repos/asf/calcite/blob/5be0f0b0/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java b/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java
index bc630a9..b2dada1 100644
--- a/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java
+++ b/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java
@@ -19,6 +19,7 @@ package org.apache.calcite.sql.validate;
import org.apache.calcite.config.NullCollation;
import org.apache.calcite.linq4j.Ord;
import org.apache.calcite.plan.RelOptTable;
+import org.apache.calcite.prepare.Prepare;
import org.apache.calcite.rel.type.DynamicRecordType;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rel.type.RelDataTypeFactory;
@@ -29,6 +30,7 @@ import org.apache.calcite.runtime.CalciteContextException;
import org.apache.calcite.runtime.CalciteException;
import org.apache.calcite.runtime.Feature;
import org.apache.calcite.runtime.Resources;
+import org.apache.calcite.schema.CustomExpansionTable;
import org.apache.calcite.schema.Table;
import org.apache.calcite.sql.JoinConditionType;
import org.apache.calcite.sql.JoinType;
@@ -460,26 +462,42 @@ public class SqlValidatorImpl implements SqlValidatorWithHints {
scope,
includeSystemVars);
} else {
- final SqlNode from = p.right.getNode();
- final SqlValidatorNamespace fromNs = getNamespace(from, scope);
- assert fromNs != null;
- final RelDataType rowType = fromNs.getRowType();
- for (RelDataTypeField field : rowType.getFieldList()) {
- String columnName = field.getName();
-
- // TODO: do real implicit collation here
- final SqlIdentifier exp =
- new SqlIdentifier(
- ImmutableList.of(p.left, columnName),
- startPosition);
- addOrExpandField(
- selectItems,
- aliases,
- types,
- includeSystemVars,
- scope,
- exp,
- field);
+ final List<List<String>> customStarExpansion =
+ getCustomStarExpansion(p.right);
+ if (customStarExpansion != null) {
+ for (List<String> names : customStarExpansion) {
+ SqlIdentifier exp = new SqlIdentifier(
+ Lists.asList(p.left, names.toArray(new String[names.size()])),
+ startPosition);
+ addToSelectList(
+ selectItems,
+ aliases,
+ types,
+ exp,
+ scope,
+ includeSystemVars);
+ }
+ } else {
+ final SqlNode from = p.right.getNode();
+ final SqlValidatorNamespace fromNs = getNamespace(from, scope);
+ assert fromNs != null;
+ final RelDataType rowType = fromNs.getRowType();
+ for (RelDataTypeField field : rowType.getFieldList()) {
+ String columnName = field.getName();
+
+ // TODO: do real implicit collation here
+ final SqlNode exp =
+ new SqlIdentifier(
+ ImmutableList.of(p.left, columnName),
+ startPosition);
+ addToSelectList(
+ selectItems,
+ aliases,
+ types,
+ exp,
+ scope,
+ includeSystemVars);
+ }
}
}
}
@@ -512,14 +530,13 @@ public class SqlValidatorImpl implements SqlValidatorWithHints {
String columnName = field.getName();
// TODO: do real implicit collation here
- addOrExpandField(
+ addToSelectList(
selectItems,
aliases,
types,
- includeSystemVars,
- scope,
prefixId.plus(columnName, startPosition),
- field);
+ scope,
+ includeSystemVars);
}
} else {
throw newValidationError(prefixId, RESOURCE.starRequiresRecordType());
@@ -528,33 +545,18 @@ public class SqlValidatorImpl implements SqlValidatorWithHints {
}
}
- private boolean addOrExpandField(List<SqlNode> selectItems, Set<String> aliases,
- List<Map.Entry<String, RelDataType>> types, boolean includeSystemVars,
- SelectScope scope, SqlIdentifier id, RelDataTypeField field) {
- switch (field.getType().getStructKind()) {
- case PEEK_FIELDS:
- case PEEK_FIELDS_DEFAULT:
- final SqlNode starExp = id.plusStar();
- expandStar(
- selectItems,
- aliases,
- types,
- includeSystemVars,
- scope,
- starExp);
- return true;
-
- default:
- addToSelectList(
- selectItems,
- aliases,
- types,
- id,
- scope,
- includeSystemVars);
+ private List<List<String>> getCustomStarExpansion(SqlValidatorNamespace ns) {
+ if (!shouldUseCustomStarExpansion()) {
+ return null;
}
-
- return false;
+ final SqlValidatorTable table = ns.getTable();
+ if (table instanceof Prepare.PreparingTable) {
+ Table t = ((Prepare.PreparingTable) table).unwrap(Table.class);
+ if (t instanceof CustomExpansionTable) {
+ return ((CustomExpansionTable) t).getCustomStarExpansion();
+ }
+ }
+ return null;
}
public SqlNode validate(SqlNode topNode) {
@@ -1759,6 +1761,10 @@ public class SqlValidatorImpl implements SqlValidatorWithHints {
return expandIdentifiers;
}
+ public boolean shouldUseCustomStarExpansion() {
+ return true;
+ }
+
protected boolean shouldAllowIntermediateOrderBy() {
return true;
}
@@ -3734,6 +3740,11 @@ public class SqlValidatorImpl implements SqlValidatorWithHints {
validateNamespace(targetNamespace, unknownType);
SqlValidatorTable table = targetNamespace.getTable();
+ // If the INSERT does not have a target column list and the target
+ // table specifies a custom star expansion list, we will set the new
+ // target column list as the star expansion list.
+ rewriteTargetColumnList(insert, targetNamespace);
+
// INSERT has an optional column name list. If present then
// reduce the rowtype to the columns specified. If not present
// then the entire target rowtype is used.
@@ -3771,6 +3782,22 @@ public class SqlValidatorImpl implements SqlValidatorWithHints {
validateAccess(insert.getTargetTable(), table, SqlAccessEnum.INSERT);
}
+ private void rewriteTargetColumnList(
+ SqlInsert insert, SqlValidatorNamespace ns) {
+ final List<List<String>> customStarExpansion = getCustomStarExpansion(ns);
+ if (customStarExpansion == null) {
+ return;
+ }
+
+ final List<SqlNode> targetColumnList = new ArrayList<>();
+ final SqlParserPos startPosition = insert.getParserPosition();
+ for (List<String> names : customStarExpansion) {
+ targetColumnList.add(new SqlIdentifier(names, startPosition));
+ }
+ insert.setTargetColumnList(
+ new SqlNodeList(targetColumnList, startPosition));
+ }
+
private void checkFieldCount(
SqlNode node,
RelDataType logicalSourceRowType,
http://git-wip-us.apache.org/repos/asf/calcite/blob/5be0f0b0/core/src/test/java/org/apache/calcite/test/MockCatalogReader.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/MockCatalogReader.java b/core/src/test/java/org/apache/calcite/test/MockCatalogReader.java
index 3912880..3e5246a 100644
--- a/core/src/test/java/org/apache/calcite/test/MockCatalogReader.java
+++ b/core/src/test/java/org/apache/calcite/test/MockCatalogReader.java
@@ -48,6 +48,7 @@ import org.apache.calcite.rex.RexBuilder;
import org.apache.calcite.rex.RexInputRef;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.rex.RexUtil;
+import org.apache.calcite.schema.CustomExpansionTable;
import org.apache.calcite.schema.ModifiableView;
import org.apache.calcite.schema.Path;
import org.apache.calcite.schema.Schema;
@@ -356,7 +357,7 @@ public class MockCatalogReader implements Prepare.CatalogReader {
// FROM EMP
// WHERE DEPTNO = 20 AND SAL > 1000
MockTable emp20View = new MockViewTable(this, salesSchema.getCatalogName(),
- salesSchema.name, "EMP_20", false, 600, empTable,
+ salesSchema.name, "EMP_20", false, 600, empTable, null,
ImmutableIntList.of(0, 1, 2, 3, 4, 5, 6, 8)) {
@Override public RexNode getConstraint(RexBuilder rexBuilder,
@@ -392,8 +393,19 @@ public class MockCatalogReader implements Prepare.CatalogReader {
MockSchema structTypeSchema = new MockSchema("STRUCT");
registerSchema(structTypeSchema);
- final MockTable structTypeTable = MockTable.create(this, structTypeSchema,
- "T", false, 100);
+ MockTable structTypeTable = new MockTable(this,
+ structTypeSchema.getCatalogName(), structTypeSchema.name,
+ "T", false, 100,
+ ImmutableList.<List<String>>of(
+ ImmutableList.of("K0"),
+ ImmutableList.of("C1"),
+ ImmutableList.of("F1", "A0"),
+ ImmutableList.of("F2", "A0"),
+ ImmutableList.of("F0", "C0"),
+ ImmutableList.of("F1", "C0"),
+ ImmutableList.of("F0", "C1"),
+ ImmutableList.of("F1", "C2"),
+ ImmutableList.of("F2", "C3")));
structTypeTable.addColumn("K0", varchar20Type);
structTypeTable.addColumn("C1", varchar20Type);
final RelDataType f0Type = typeFactory.builder()
@@ -427,7 +439,7 @@ public class MockCatalogReader implements Prepare.CatalogReader {
MockTable struct10View = new MockViewTable(this,
structTypeSchema.getCatalogName(),
structTypeSchema.name, "T_10", false, 20,
- structTypeTable, ImmutableIntList.of(0, 1, 2, 3, 4)) {
+ structTypeTable, null, ImmutableIntList.of(0, 1, 2, 3, 4)) {
@Override public RexNode getConstraint(RexBuilder rexBuilder,
RelDataType tableRowType) {
@@ -451,6 +463,19 @@ public class MockCatalogReader implements Prepare.CatalogReader {
struct10View.addColumn("F1", f1Type);
struct10View.addColumn("F2", f2Type);
registerTable(struct10View);
+
+ // TODO Remove this table and use STRUCT.T instead after
+ // CALCITE-1425 is done.
+ MockTable simpleTable = new MockTable(this,
+ structTypeSchema.getCatalogName(), structTypeSchema.name,
+ "SIMPLE", false, 100,
+ ImmutableList.<List<String>>of(
+ ImmutableList.of("K2"),
+ ImmutableList.of("K0")));
+ simpleTable.addColumn("K0", varchar20Type);
+ simpleTable.addColumn("K1", intTypeNull);
+ simpleTable.addColumn("K2", timestampType);
+ registerTable(simpleTable);
return this;
}
@@ -636,20 +661,42 @@ public class MockCatalogReader implements Prepare.CatalogReader {
protected final List<String> names;
private final Set<String> monotonicColumnSet = Sets.newHashSet();
private StructKind kind = StructKind.FULLY_QUALIFIED;
+ protected final List<List<String>> customExpansionList;
public MockTable(MockCatalogReader catalogReader, String catalogName,
- String schemaName, String name, boolean stream, double rowCount) {
+ String schemaName, String name, boolean stream, double rowCount,
+ List<List<String>> customExpansionList) {
this.catalogReader = catalogReader;
this.stream = stream;
this.rowCount = rowCount;
this.names = ImmutableList.of(catalogName, schemaName, name);
+ this.customExpansionList = customExpansionList;
+ }
+
+ /**
+ * Subclass of AbstractModifiableTable that also implements
+ * CustomExpansionTable.
+ */
+ private abstract class AbstractModifiableTableWithCustomExpansion
+ extends JdbcTest.AbstractModifiableTable
+ implements CustomExpansionTable {
+
+ protected AbstractModifiableTableWithCustomExpansion(String tableName) {
+ super(tableName);
+ }
}
public static MockTable create(MockCatalogReader catalogReader,
MockSchema schema, String name, boolean stream, double rowCount) {
+ return create(catalogReader, schema, name, stream, rowCount, null);
+ }
+
+ public static MockTable create(MockCatalogReader catalogReader,
+ MockSchema schema, String name, boolean stream, double rowCount,
+ List<List<String>> customExpansionList) {
MockTable table =
new MockTable(catalogReader, schema.getCatalogName(), schema.name,
- name, stream, rowCount);
+ name, stream, rowCount, customExpansionList);
schema.addTable(name);
return table;
}
@@ -660,7 +707,7 @@ public class MockCatalogReader implements Prepare.CatalogReader {
}
if (clazz.isAssignableFrom(Table.class)) {
return clazz.cast(
- new JdbcTest.AbstractModifiableTable(Util.last(names)) {
+ new AbstractModifiableTableWithCustomExpansion(Util.last(names)) {
@Override public RelDataType
getRowType(RelDataTypeFactory typeFactory) {
return typeFactory.createStructType(rowType.getFieldList());
@@ -684,6 +731,10 @@ public class MockCatalogReader implements Prepare.CatalogReader {
String tableName, Class clazz) {
return null;
}
+
+ @Override public List<List<String>> getCustomStarExpansion() {
+ return customExpansionList;
+ }
});
}
return null;
@@ -756,7 +807,7 @@ public class MockCatalogReader implements Prepare.CatalogReader {
public RelOptTable extend(List<RelDataTypeField> extendedFields) {
final MockTable table = new MockTable(catalogReader, names.get(0),
- names.get(1), names.get(2), stream, rowCount);
+ names.get(1), names.get(2), stream, rowCount, customExpansionList);
table.columnList.addAll(columnList);
table.columnList.addAll(extendedFields);
table.onRegister(catalogReader.typeFactory);
@@ -783,8 +834,10 @@ public class MockCatalogReader implements Prepare.CatalogReader {
MockViewTable(MockCatalogReader catalogReader, String catalogName,
String schemaName, String name, boolean stream, double rowCount,
- MockTable fromTable, ImmutableIntList mapping) {
- super(catalogReader, catalogName, schemaName, name, stream, rowCount);
+ MockTable fromTable, List<List<String>> customExpansionList,
+ ImmutableIntList mapping) {
+ super(catalogReader, catalogName, schemaName, name, stream, rowCount,
+ customExpansionList);
this.fromTable = fromTable;
this.table = fromTable.unwrap(Table.class);
this.mapping = mapping;
@@ -875,7 +928,7 @@ public class MockCatalogReader implements Prepare.CatalogReader {
public static class MockDynamicTable extends MockTable {
MockDynamicTable(MockCatalogReader catalogReader, String catalogName,
String schemaName, String name, boolean stream, double rowCount) {
- super(catalogReader, catalogName, schemaName, name, stream, rowCount);
+ super(catalogReader, catalogName, schemaName, name, stream, rowCount, null);
}
public void onRegister(RelDataTypeFactory typeFactory) {
http://git-wip-us.apache.org/repos/asf/calcite/blob/5be0f0b0/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java
----------------------------------------------------------------------
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 c32e751..c50b301 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java
@@ -1745,6 +1745,12 @@ public class SqlToRelConverterTest extends SqlToRelTestBase {
sql(sql).ok();
}
+ @Test public void testStructTypeWithSelectStar2() {
+ final String sql = "select * from struct.t t1 join struct.t t2\n"
+ + "on t1.k0 = t2.k0";
+ sql(sql).ok();
+ }
+
@Test public void testStructTypeWithSelectFieldNameDotStar() {
final String sql = "select f1.* from struct.t";
sql(sql).ok();
http://git-wip-us.apache.org/repos/asf/calcite/blob/5be0f0b0/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
----------------------------------------------------------------------
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 caee32f..83125ba 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
@@ -7972,6 +7972,12 @@ public class SqlValidatorTest extends SqlValidatorTestCase {
sql(sql2).ok().bindType(expected2);
}
+ @Test public void testInsertBindWithCustomStarExpansion() {
+ sql("insert into struct.simple values (?, ?)")
+ .ok()
+ .bindType("RecordType(TIMESTAMP(0) ?0, VARCHAR(20) ?1)");
+ }
+
@Test public void testUpdateBind() {
final String sql = "update emp\n"
+ "set ename = ?\n"
http://git-wip-us.apache.org/repos/asf/calcite/blob/5be0f0b0/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
----------------------------------------------------------------------
diff --git a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
index d830b95..e773160 100644
--- a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
@@ -1134,7 +1134,7 @@ where c0 in (
</Resource>
<Resource name="planBefore">
<![CDATA[
-LogicalProject(K0=[$0], C1=[$1], C0=[$2], C10=[$3], C00=[$4], C2=[$5], A0=[$6], C3=[$7], A00=[$8])
+LogicalProject(K0=[$0], C1=[$1], A0=[$6], A00=[$8], C0=[$2], C00=[$4], C10=[$3], C2=[$5], C3=[$7])
LogicalFilter(condition=[IN($2, {
LogicalProject(C0=[$4])
LogicalProject(K0=[$0], C1=[$1], C0=[$2.C0], C13=[$2.C1], C04=[$3.C0], C2=[$3.C2], A0=[$3.A0], C3=[$4.C3], A08=[$4.A0])
@@ -1146,7 +1146,7 @@ LogicalProject(C0=[$4])
</Resource>
<Resource name="planAfter">
<![CDATA[
-LogicalProject(K0=[$0], C1=[$1], C0=[$2], C10=[$3], C00=[$4], C2=[$5], A0=[$6], C3=[$7], A00=[$8])
+LogicalProject(K0=[$0], C1=[$1], A0=[$6], A00=[$8], C0=[$2], C00=[$4], C10=[$3], C2=[$5], C3=[$7])
LogicalProject(K0=[$0], C1=[$1], C0=[$2], C13=[$3], C04=[$4], C2=[$5], A0=[$6], C3=[$7], A08=[$8])
LogicalJoin(condition=[=($2, $9)], joinType=[inner])
LogicalProject(K0=[$0], C1=[$1], C0=[$2.C0], C13=[$2.C1], C04=[$3.C0], C2=[$3.C2], A0=[$3.A0], C3=[$4.C3], A08=[$4.A0])
@@ -1167,7 +1167,7 @@ where c0 = (
</Resource>
<Resource name="planBefore">
<![CDATA[
-LogicalProject(K0=[$0], C1=[$1], C0=[$2], C10=[$3], C00=[$4], C2=[$5], A0=[$6], C3=[$7], A00=[$8])
+LogicalProject(K0=[$0], C1=[$1], A0=[$6], A00=[$8], C0=[$2], C00=[$4], C10=[$3], C2=[$5], C3=[$7])
LogicalFilter(condition=[=($2, $SCALAR_QUERY({
LogicalAggregate(group=[{}], EXPR$0=[MAX($0)])
LogicalProject($f0=[$4])
@@ -1181,7 +1181,7 @@ LogicalAggregate(group=[{}], EXPR$0=[MAX($0)])
</Resource>
<Resource name="planAfter">
<![CDATA[
-LogicalProject(K0=[$0], C1=[$1], C0=[$2], C10=[$3], C00=[$4], C2=[$5], A0=[$6], C3=[$7], A00=[$8])
+LogicalProject(K0=[$0], C1=[$1], A0=[$6], A00=[$8], C0=[$2], C00=[$4], C10=[$3], C2=[$5], C3=[$7])
LogicalProject(K0=[$0], C1=[$1], C0=[$2], C13=[$3], C04=[$4], C2=[$5], A0=[$6], C3=[$7], A08=[$8])
LogicalFilter(condition=[=($2, $9)])
LogicalCorrelate(correlation=[$cor0], joinType=[LEFT], requiredColumns=[{0}])
@@ -1204,7 +1204,7 @@ where c0 in (
</Resource>
<Resource name="planBefore">
<![CDATA[
-LogicalProject(K0=[$0], C1=[$1], C0=[$2], C10=[$3], C00=[$4], C2=[$5], A0=[$6], C3=[$7], A00=[$8])
+LogicalProject(K0=[$0], C1=[$1], A0=[$6], A00=[$8], C0=[$2], C00=[$4], C10=[$3], C2=[$5], C3=[$7])
LogicalFilter(condition=[IN($2, {
LogicalProject(C0=[$4])
LogicalFilter(condition=[=($cor0.C2_5, $5)])
@@ -1217,7 +1217,7 @@ LogicalProject(C0=[$4])
</Resource>
<Resource name="planAfter">
<![CDATA[
-LogicalProject(K0=[$0], C1=[$1], C0=[$2], C10=[$3], C00=[$4], C2=[$5], A0=[$6], C3=[$7], A00=[$8])
+LogicalProject(K0=[$0], C1=[$1], A0=[$6], A00=[$8], C0=[$2], C00=[$4], C10=[$3], C2=[$5], C3=[$7])
LogicalProject(K0=[$0], C1=[$1], C0=[$2], C13=[$3], C04=[$4], C2=[$5], A0=[$6], C3=[$7], A08=[$8])
LogicalFilter(condition=[=($2, $9)])
LogicalCorrelate(correlation=[$cor0], joinType=[INNER], requiredColumns=[{5}])
http://git-wip-us.apache.org/repos/asf/calcite/blob/5be0f0b0/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
----------------------------------------------------------------------
diff --git a/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml b/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
index 371c20c..500ee91 100644
--- a/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
@@ -2584,12 +2584,28 @@ LogicalProject(F1=[$0])
</Resource>
<Resource name="plan">
<![CDATA[
-LogicalProject(K0=[$0], C1=[$1], C0=[$2], C10=[$3], C00=[$4], C2=[$5], A0=[$6], C3=[$7], A00=[$8])
+LogicalProject(K0=[$0], C1=[$1], A0=[$6], A00=[$8], C0=[$2], C00=[$4], C10=[$3], C2=[$5], C3=[$7])
LogicalProject(K0=[$0], C1=[$1], C0=[$2.C0], C13=[$2.C1], C04=[$3.C0], C2=[$3.C2], A0=[$3.A0], C3=[$4.C3], A08=[$4.A0])
LogicalTableScan(table=[[CATALOG, STRUCT, T]])
]]>
</Resource>
</TestCase>
+ <TestCase name="testStructTypeWithSelectStar2">
+ <Resource name="sql">
+ <![CDATA[select * from struct.t t1 join struct.t t2
+on t1.k0 = t2.k0]]>
+ </Resource>
+ <Resource name="plan">
+ <![CDATA[
+LogicalProject(K0=[$0], C1=[$1], A0=[$6], A00=[$8], C0=[$2], C00=[$4], C10=[$3], C2=[$5], C3=[$7], K00=[$9], C11=[$10], A01=[$15], A02=[$17], C01=[$11], C02=[$13], C12=[$12], C20=[$14], C30=[$16])
+ LogicalJoin(condition=[=($0, $9)], joinType=[inner])
+ LogicalProject(K0=[$0], C1=[$1], C0=[$2.C0], C13=[$2.C1], C04=[$3.C0], C2=[$3.C2], A0=[$3.A0], C3=[$4.C3], A08=[$4.A0])
+ LogicalTableScan(table=[[CATALOG, STRUCT, T]])
+ LogicalProject(K0=[$0], C1=[$1], C0=[$2.C0], C13=[$2.C1], C04=[$3.C0], C2=[$3.C2], A0=[$3.A0], C3=[$4.C3], A08=[$4.A0])
+ LogicalTableScan(table=[[CATALOG, STRUCT, T]])
+]]>
+ </Resource>
+ </TestCase>
<TestCase name="testStructTypeWithSelectFieldNameDotStar">
<Resource name="sql">
<![CDATA[select f1.* from struct.t]]>