Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.apache.calcite.rel.core.Sample;
import org.apache.calcite.rel.core.SetOp;
import org.apache.calcite.rel.core.Sort;
import org.apache.calcite.rel.core.TableFunctionScan;
import org.apache.calcite.rel.core.TableModify;
import org.apache.calcite.rel.core.TableScan;
import org.apache.calcite.rel.core.Window;
Expand Down Expand Up @@ -159,11 +160,31 @@ public Set<RelTableRef> getTableReferences(TableScan rel, RelMetadataQuery mq) {
* references.
*/
public @Nullable Set<RelTableRef> getTableReferences(SetOp rel, RelMetadataQuery mq) {
return getTableReferences(rel.getInputs(), mq);
}

/**
* Table references from the relational inputs of a TableFunctionScan.
*
* <p>Returns an empty set if there are no inputs, and {@code null} if the table
* references of any input cannot be determined. Tables accessed internally
* by the table function are not included.
*/
public @Nullable Set<RelTableRef> getTableReferences(TableFunctionScan rel,
RelMetadataQuery mq) {
return getTableReferences(rel.getInputs(), mq);
}

/** Returns the union of the table references of {@code inputs}, assigning
* distinct entity numbers to repeated references to the same table, or {@code null}
* if the references of any input cannot be determined. */
private static @Nullable Set<RelTableRef> getTableReferences(
List<RelNode> inputs, RelMetadataQuery mq) {
final Set<RelTableRef> result = new HashSet<>();

// Infer column origin expressions for given references
final Multimap<List<String>, RelTableRef> qualifiedNamesToRefs = HashMultimap.create();
for (RelNode input : rel.getInputs()) {
for (RelNode input : inputs) {
final Map<RelTableRef, RelTableRef> currentTablesMapping = new HashMap<>();
final Set<RelTableRef> inputTableRefs = mq.getTableReferences(input);
if (inputTableRefs == null) {
Expand Down
51 changes: 51 additions & 0 deletions core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@
import static org.hamcrest.CoreMatchers.startsWith;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.closeTo;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.hasToString;
import static org.junit.jupiter.api.Assertions.assertNotNull;
Expand Down Expand Up @@ -4928,6 +4929,56 @@ public void checkAllPredicatesAndTableSetOp(String sql) {
assertNull(tableReferences);
}

@Test void testTableReferencesTableFunctionScanSameTableInputs() {
final RelNode rel = fixture()
.withRelFn(builder ->
builder.scan("EMP")
.scan("EMP")
.functionScan(new MockSqlOperatorTable.DedupFunction(), 2,
builder.cursor(2, 0), builder.cursor(2, 1))
.build())
.toRel();
final RelMetadataQuery mq = rel.getCluster().getMetadataQuery();
assertThat(mq.getTableReferences(rel),
sortsAs("[[scott, EMP].#0, [scott, EMP].#1]"));
}

@Test void testTableReferencesTumbleTableFunction() {
final RelNode rel = sql("select * from table(tumble(table emp, "
+ "descriptor(hiredate), interval '1' hour))").toRel();
final RelMetadataQuery mq = rel.getCluster().getMetadataQuery();
assertThat(mq.getTableReferences(rel),
sortsAs("[[CATALOG, SALES, EMP].#0]"));
}

@Test void testTableReferencesTableFunctionScanZeroInputs() {
final RelNode rel = fixture()
.withRelFn(builder ->
builder.functionScan(new MockSqlOperatorTable.RampFunction(), 0,
builder.literal(3))
.build())
.toRel();
final RelMetadataQuery mq = rel.getCluster().getMetadataQuery();
assertThat(mq.getTableReferences(rel), empty());
}

@Test void testTableReferencesTableFunctionScanUnknownInput() {
final RelNode rel = fixture()
.withRelFn(builder -> {
final RelNode scan = builder.scan("EMP").build();
final RelNode unknown =
new DummyRelNode(scan.getCluster(), scan.getTraitSet(), scan);
return builder.push(unknown)
.push(scan)
.functionScan(new MockSqlOperatorTable.DedupFunction(), 2,
builder.cursor(2, 0), builder.cursor(2, 1))
.build();
})
.toRel();
final RelMetadataQuery mq = rel.getCluster().getMetadataQuery();
assertNull(mq.getTableReferences(rel));
}

@Test void testNodeTypeCountEmp() {
final String sql = "select * from emp";
sql(sql)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ private java.util.Set getTableReferences_(
return provider0.getTableReferences((org.apache.calcite.rel.core.SetOp) r, mq);
} else if (r instanceof org.apache.calcite.rel.core.Sort) {
return provider0.getTableReferences((org.apache.calcite.rel.core.Sort) r, mq);
} else if (r instanceof org.apache.calcite.rel.core.TableFunctionScan) {
return provider0.getTableReferences((org.apache.calcite.rel.core.TableFunctionScan) r, mq);
} else if (r instanceof org.apache.calcite.rel.core.TableModify) {
return provider0.getTableReferences((org.apache.calcite.rel.core.TableModify) r, mq);
} else if (r instanceof org.apache.calcite.rel.core.TableScan) {
Expand Down
Loading