2020import org .apache .calcite .rel .RelNode ;
2121import org .apache .calcite .rel .core .Aggregate ;
2222import org .apache .calcite .rel .core .Calc ;
23+ import org .apache .calcite .rel .core .Collect ;
24+ import org .apache .calcite .rel .core .Combine ;
25+ import org .apache .calcite .rel .core .Correlate ;
2326import org .apache .calcite .rel .core .Exchange ;
2427import org .apache .calcite .rel .core .Filter ;
2528import org .apache .calcite .rel .core .Join ;
29+ import org .apache .calcite .rel .core .Match ;
2630import org .apache .calcite .rel .core .Project ;
31+ import org .apache .calcite .rel .core .RepeatUnion ;
2732import org .apache .calcite .rel .core .Sample ;
2833import org .apache .calcite .rel .core .SetOp ;
34+ import org .apache .calcite .rel .core .Snapshot ;
2935import org .apache .calcite .rel .core .Sort ;
36+ import org .apache .calcite .rel .core .Spool ;
3037import org .apache .calcite .rel .core .TableFunctionScan ;
3138import org .apache .calcite .rel .core .TableModify ;
3239import org .apache .calcite .rel .core .TableScan ;
40+ import org .apache .calcite .rel .core .Uncollect ;
41+ import org .apache .calcite .rel .core .Values ;
3342import org .apache .calcite .rel .core .Window ;
43+ import org .apache .calcite .rex .RexNode ;
44+ import org .apache .calcite .rex .RexSubQuery ;
3445import org .apache .calcite .rex .RexTableInputRef .RelTableRef ;
46+ import org .apache .calcite .rex .RexUtil ;
3547import org .apache .calcite .util .Util ;
3648
3749import com .google .common .collect .HashMultimap ;
50+ import com .google .common .collect .ImmutableList ;
3851import com .google .common .collect .ImmutableSet ;
3952import com .google .common .collect .Multimap ;
4053
4154import org .checkerframework .checker .nullness .qual .Nullable ;
4255
56+ import java .util .ArrayList ;
4357import java .util .Collection ;
4458import java .util .HashMap ;
4559import java .util .HashSet ;
@@ -101,6 +115,11 @@ public Set<RelTableRef> getTableReferences(TableScan rel, RelMetadataQuery mq) {
101115 return ImmutableSet .of (RelTableRef .of (rel .getTable (), 0 ));
102116 }
103117
118+ /** Table references from Values. */
119+ public Set <RelTableRef > getTableReferences (Values rel , RelMetadataQuery mq ) {
120+ return ImmutableSet .of ();
121+ }
122+
104123 /**
105124 * Table references from Aggregate.
106125 */
@@ -112,45 +131,23 @@ public Set<RelTableRef> getTableReferences(TableScan rel, RelMetadataQuery mq) {
112131 * Table references from Join.
113132 */
114133 public @ Nullable Set <RelTableRef > getTableReferences (Join rel , RelMetadataQuery mq ) {
115- final RelNode leftInput = rel .getLeft ();
116- final RelNode rightInput = rel .getRight ( );
117- final Set < RelTableRef > result = new HashSet <>();
134+ return getTableReferences ( ImmutableList . of ( rel .getLeft (), rel . getRight ()),
135+ ImmutableList . of ( rel .getCondition ()), mq );
136+ }
118137
119- // Gather table references, left input references remain unchanged
120- final Multimap <List <String >, RelTableRef > leftQualifiedNamesToRefs = HashMultimap .create ();
121- final Set <RelTableRef > leftTableRefs = mq .getTableReferences (leftInput );
122- if (leftTableRefs == null ) {
123- // We could not infer the table refs from left input
124- return null ;
125- }
126- for (RelTableRef leftRef : leftTableRefs ) {
127- assert !result .contains (leftRef );
128- result .add (leftRef );
129- leftQualifiedNamesToRefs .put (leftRef .getQualifiedName (), leftRef );
130- }
138+ /** Table references from both inputs of Correlate. */
139+ public @ Nullable Set <RelTableRef > getTableReferences (Correlate rel , RelMetadataQuery mq ) {
140+ return getTableReferences (rel .getInputs (), ImmutableList .of (), mq );
141+ }
131142
132- // Gather table references, right input references might need to be
133- // updated if there are table names clashes with left input
134- final Set <RelTableRef > rightTableRefs = mq .getTableReferences (rightInput );
135- if (rightTableRefs == null ) {
136- // We could not infer the table refs from right input
137- return null ;
138- }
139- for (RelTableRef rightRef : rightTableRefs ) {
140- int shift = 0 ;
141- Collection <RelTableRef > lRefs =
142- leftQualifiedNamesToRefs .get (rightRef .getQualifiedName ());
143- if (lRefs != null ) {
144- shift = lRefs .size ();
145- }
146- RelTableRef shiftTableRef =
147- RelTableRef .of (rightRef .getTable (), shift + rightRef .getEntityNumber ());
148- assert !result .contains (shiftTableRef );
149- result .add (shiftTableRef );
150- }
143+ /** Table references from RepeatUnion. */
144+ public @ Nullable Set <RelTableRef > getTableReferences (RepeatUnion rel , RelMetadataQuery mq ) {
145+ return getTableReferences (rel .getInputs (), ImmutableList .of (), mq );
146+ }
151147
152- // Return result
153- return result ;
148+ /** Table references from Combine. */
149+ public @ Nullable Set <RelTableRef > getTableReferences (Combine rel , RelMetadataQuery mq ) {
150+ return getTableReferences (rel .getInputs (), ImmutableList .of (), mq );
154151 }
155152
156153 /**
@@ -160,31 +157,38 @@ public Set<RelTableRef> getTableReferences(TableScan rel, RelMetadataQuery mq) {
160157 * references.
161158 */
162159 public @ Nullable Set <RelTableRef > getTableReferences (SetOp rel , RelMetadataQuery mq ) {
163- return getTableReferences (rel .getInputs (), mq );
160+ return getTableReferences (rel .getInputs (), ImmutableList . of (), mq );
164161 }
165162
166163 /**
167- * Table references from the relational inputs of a TableFunctionScan.
164+ * Table references from TableFunctionScan.
168165 *
169- * <p>Returns an empty set if there are no inputs, and {@code null} if the table
170- * references of any input cannot be determined. Tables accessed internally
171- * by the table function are not included.
166+ * <p>Returns an empty set when its inputs and call reference no tables.
172167 */
173168 public @ Nullable Set <RelTableRef > getTableReferences (TableFunctionScan rel ,
174169 RelMetadataQuery mq ) {
175- return getTableReferences (rel .getInputs (), mq );
170+ return getTableReferences (rel .getInputs (), ImmutableList . of ( rel . getCall ()), mq );
176171 }
177172
178- /** Returns the union of the table references of {@code inputs}, assigning
179- * distinct entity numbers to repeated references to the same table, or {@code null}
180- * if the references of any input cannot be determined. */
173+ /** Returns the union of the table references of {@code inputs} and expression
174+ * sub-queries, assigning distinct entity numbers to repeated references to
175+ * the same table, or {@code null} if the references of any input or sub-query
176+ * cannot be determined. */
181177 private static @ Nullable Set <RelTableRef > getTableReferences (
182- List <RelNode > inputs , RelMetadataQuery mq ) {
178+ List <RelNode > inputs , List <? extends RexNode > expressions , RelMetadataQuery mq ) {
179+ final List <RelNode > rels = new ArrayList <>(inputs );
180+ final RexUtil .SubQueryCollector collector = new RexUtil .SubQueryCollector (true );
181+ for (RexNode expression : expressions ) {
182+ expression .accept (collector );
183+ }
184+ for (RexSubQuery subQuery : collector .getSubQueries ()) {
185+ rels .add (subQuery .rel );
186+ }
183187 final Set <RelTableRef > result = new HashSet <>();
184188
185189 // Infer column origin expressions for given references
186190 final Multimap <List <String >, RelTableRef > qualifiedNamesToRefs = HashMultimap .create ();
187- for (RelNode input : inputs ) {
191+ for (RelNode input : rels ) {
188192 final Map <RelTableRef , RelTableRef > currentTablesMapping = new HashMap <>();
189193 final Set <RelTableRef > inputTableRefs = mq .getTableReferences (input );
190194 if (inputTableRefs == null ) {
@@ -218,35 +222,45 @@ public Set<RelTableRef> getTableReferences(TableScan rel, RelMetadataQuery mq) {
218222 * Table references from Project.
219223 */
220224 public @ Nullable Set <RelTableRef > getTableReferences (Project rel , final RelMetadataQuery mq ) {
221- return mq . getTableReferences (rel .getInput ());
225+ return getTableReferences (ImmutableList . of ( rel .getInput ()), rel . getProjects (), mq );
222226 }
223227
224228 /**
225229 * Table references from Filter.
226230 */
227231 public @ Nullable Set <RelTableRef > getTableReferences (Filter rel , RelMetadataQuery mq ) {
228- return mq .getTableReferences (rel .getInput ());
232+ return getTableReferences (ImmutableList .of (rel .getInput ()),
233+ ImmutableList .of (rel .getCondition ()), mq );
229234 }
230235
231236 /**
232237 * Table references from Calc.
233238 */
234239 public @ Nullable Set <RelTableRef > getTableReferences (Calc rel , RelMetadataQuery mq ) {
235- return mq . getTableReferences (rel .getInput ());
240+ return getTableReferences (ImmutableList . of ( rel .getInput ()), rel . getProgram (). getExprList (), mq );
236241 }
237242
238243 /**
239244 * Table references from Sort.
240245 */
241246 public @ Nullable Set <RelTableRef > getTableReferences (Sort rel , RelMetadataQuery mq ) {
242- return mq .getTableReferences (rel .getInput ());
247+ final ImmutableList .Builder <RexNode > expressions = ImmutableList .builder ();
248+ if (rel .offset != null ) {
249+ expressions .add (rel .offset );
250+ }
251+ if (rel .fetch != null ) {
252+ expressions .add (rel .fetch );
253+ }
254+ return getTableReferences (ImmutableList .of (rel .getInput ()), expressions .build (), mq );
243255 }
244256
245257 /**
246258 * Table references from TableModify.
247259 */
248260 public @ Nullable Set <RelTableRef > getTableReferences (TableModify rel , RelMetadataQuery mq ) {
249- return mq .getTableReferences (rel .getInput ());
261+ final List <RexNode > expressions = rel .getSourceExpressionList ();
262+ return getTableReferences (ImmutableList .of (rel .getInput ()),
263+ expressions == null ? ImmutableList .of () : expressions , mq );
250264 }
251265
252266 /**
@@ -260,7 +274,19 @@ public Set<RelTableRef> getTableReferences(TableScan rel, RelMetadataQuery mq) {
260274 * Table references from Window.
261275 */
262276 public @ Nullable Set <RelTableRef > getTableReferences (Window rel , RelMetadataQuery mq ) {
263- return mq .getTableReferences (rel .getInput ());
277+ final ImmutableList .Builder <RexNode > expressions = ImmutableList .builder ();
278+ for (Window .Group group : rel .groups ) {
279+ expressions .addAll (group .aggCalls );
280+ final @ Nullable RexNode lowerOffset = group .lowerBound .getOffset ();
281+ if (lowerOffset != null ) {
282+ expressions .add (lowerOffset );
283+ }
284+ final @ Nullable RexNode upperOffset = group .upperBound .getOffset ();
285+ if (upperOffset != null ) {
286+ expressions .add (upperOffset );
287+ }
288+ }
289+ return getTableReferences (ImmutableList .of (rel .getInput ()), expressions .build (), mq );
264290 }
265291
266292 /**
@@ -270,4 +296,38 @@ public Set<RelTableRef> getTableReferences(TableScan rel, RelMetadataQuery mq) {
270296 return mq .getTableReferences (rel .getInput ());
271297 }
272298
299+ /** Table references from Snapshot. */
300+ public @ Nullable Set <RelTableRef > getTableReferences (Snapshot rel , RelMetadataQuery mq ) {
301+ return getTableReferences (ImmutableList .of (rel .getInput ()),
302+ ImmutableList .of (rel .getPeriod ()), mq );
303+ }
304+
305+ /** Table references from Match. */
306+ public @ Nullable Set <RelTableRef > getTableReferences (Match rel , RelMetadataQuery mq ) {
307+ final ImmutableList .Builder <RexNode > expressions = ImmutableList .builder ();
308+ expressions .add (rel .getPattern (), rel .getAfter ());
309+ expressions .addAll (rel .getMeasures ().values ());
310+ expressions .addAll (rel .getPatternDefinitions ().values ());
311+ final @ Nullable RexNode interval = rel .getInterval ();
312+ if (interval != null ) {
313+ expressions .add (interval );
314+ }
315+ return getTableReferences (ImmutableList .of (rel .getInput ()), expressions .build (), mq );
316+ }
317+
318+ /** Table references from Uncollect. */
319+ public @ Nullable Set <RelTableRef > getTableReferences (Uncollect rel , RelMetadataQuery mq ) {
320+ return mq .getTableReferences (rel .getInput ());
321+ }
322+
323+ /** Table references from Collect. */
324+ public @ Nullable Set <RelTableRef > getTableReferences (Collect rel , RelMetadataQuery mq ) {
325+ return mq .getTableReferences (rel .getInput ());
326+ }
327+
328+ /** Table references from Spool. */
329+ public @ Nullable Set <RelTableRef > getTableReferences (Spool rel , RelMetadataQuery mq ) {
330+ return mq .getTableReferences (rel .getInput ());
331+ }
332+
273333}
0 commit comments