diff --git a/presto-main/src/main/java/com/facebook/presto/sql/analyzer/MetadataExtractor.java b/presto-main/src/main/java/com/facebook/presto/sql/analyzer/MetadataExtractor.java index deb6806dc0c8..17f7a314eb89 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/analyzer/MetadataExtractor.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/analyzer/MetadataExtractor.java @@ -24,9 +24,11 @@ import com.facebook.presto.sql.tree.Analyze; import com.facebook.presto.sql.tree.DefaultTraversalVisitor; import com.facebook.presto.sql.tree.Delete; +import com.facebook.presto.sql.tree.Identifier; import com.facebook.presto.sql.tree.Insert; import com.facebook.presto.sql.tree.Statement; import com.facebook.presto.sql.tree.Table; +import com.facebook.presto.sql.tree.With; import java.util.HashSet; import java.util.Optional; @@ -125,17 +127,21 @@ private class MetadataExtractorContext { private final Optional parent; private final Set tableNames; + // avoid sending requests for metadata information for table names that we don't need, such as those involved in a query with a CTE + private final Set tableNamesToSkipProcessing; public MetadataExtractorContext() { this.parent = Optional.empty(); this.tableNames = new HashSet<>(); + this.tableNamesToSkipProcessing = new HashSet<>(); } public MetadataExtractorContext(Optional parent) { this.parent = parent; this.tableNames = new HashSet<>(); + this.tableNamesToSkipProcessing = new HashSet<>(); } public void addTable(QualifiedObjectName tableName) @@ -147,21 +153,27 @@ public void addTable(QualifiedObjectName tableName) private boolean tableExists(QualifiedObjectName tableName) { - if (tableNames.contains(tableName)) { - return true; - } - - if (parent.isPresent()) { - return parent.get().tableExists(tableName); - } - - return false; + return tableNames.contains((tableName)) || + parent.map(metadataExtractorContext -> metadataExtractorContext.tableExists(tableName)).orElse(false); } public Set getTableNames() { return tableNames; } + + public void addTableNameToSkipProcessing(Identifier commonTableExpressionName) + { + if (!shouldSkipProcessing(commonTableExpressionName)) { + tableNamesToSkipProcessing.add(commonTableExpressionName); + } + } + + public boolean shouldSkipProcessing(Identifier tableName) + { + return tableNamesToSkipProcessing.contains(tableName) || + parent.map(metadataExtractorContext -> metadataExtractorContext.shouldSkipProcessing(tableName)).orElse(false); + } } private class Visitor @@ -185,8 +197,10 @@ protected Void visitTable(Table table, MetadataExtractorContext context) throw new SemanticException(MISSING_SCHEMA, table, "Schema name is empty"); } + if (!context.shouldSkipProcessing(new Identifier(tableName.getObjectName()))) { + context.addTable(tableName); + } // This could be either tableName, view, or MView - context.addTable(tableName); return super.visitTable(table, context); } @@ -236,5 +250,15 @@ protected Void visitAnalyze(Analyze node, MetadataExtractorContext context) context.addTable(tableName); return super.visitAnalyze(node, context); } + + @Override + protected Void visitWith(With node, MetadataExtractorContext context) + { + node.getQueries().forEach(query -> { + context.addTableNameToSkipProcessing(query.getName()); + process(query, context); + }); + return null; + } } } diff --git a/presto-tests/src/main/java/com/facebook/presto/tests/AbstractTestQueries.java b/presto-tests/src/main/java/com/facebook/presto/tests/AbstractTestQueries.java index bc2377b1e371..d8982f814b65 100644 --- a/presto-tests/src/main/java/com/facebook/presto/tests/AbstractTestQueries.java +++ b/presto-tests/src/main/java/com/facebook/presto/tests/AbstractTestQueries.java @@ -6887,6 +6887,12 @@ public void testPreProcessMetastoreCalls() "WHERE\n" + " c.nationkey = 1\n"; assertEqualsIgnoreOrder(computeActual(enablePreProcessMetadataCalls, query), computeActual(getSession(), query)); + + query = "WITH temp_cte AS ( \n" + + " SELECT name from nation \n" + + " ) \n" + + " SELECT * FROM temp_cte"; + assertEqualsIgnoreOrder(computeActual(enablePreProcessMetadataCalls, query), computeActual(getSession(), query)); } @Test