diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/predicate/PredicatePushIntoMetadataChecker.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/predicate/PredicatePushIntoMetadataChecker.java index bd8afc2f415d..ff89746f7182 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/predicate/PredicatePushIntoMetadataChecker.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/predicate/PredicatePushIntoMetadataChecker.java @@ -196,7 +196,10 @@ public Boolean visitIsNotNullPredicate(final IsNotNullPredicate node, final Void @Override public Boolean visitLikePredicate(final LikePredicate node, final Void context) { - return node.getValue().accept(this, context); + return node.getValue() instanceof SymbolReference + && node.getValue().accept(this, context) + && node.getPattern() instanceof StringLiteral + && (!node.getEscape().isPresent() || node.getEscape().get() instanceof StringLiteral); } @Override diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/predicate/schema/ConvertSchemaPredicateToFilterVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/predicate/schema/ConvertSchemaPredicateToFilterVisitor.java index 510c748aceea..b4f810a8dfb0 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/predicate/schema/ConvertSchemaPredicateToFilterVisitor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/predicate/schema/ConvertSchemaPredicateToFilterVisitor.java @@ -114,7 +114,8 @@ public SchemaFilter visitIsNotNullPredicate( final LikePredicate node, final Context context) { // TODO: Support stringLiteral like tag/attr? if (!(node.getValue() instanceof SymbolReference) - || !(node.getPattern() instanceof StringLiteral)) { + || !(node.getPattern() instanceof StringLiteral) + || (node.getEscape().isPresent() && !(node.getEscape().get() instanceof StringLiteral))) { return null; } return wrapTagOrAttributeFilter( diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AnalyzerTest.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AnalyzerTest.java index 107070425e58..6487429edf2a 100644 --- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AnalyzerTest.java +++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AnalyzerTest.java @@ -671,6 +671,43 @@ public void expressionTest() { assertNull(deviceTableScanNode.getPushDownPredicate()); assertFalse(deviceTableScanNode.getTimePredicate().isPresent()); + sql = "SELECT * FROM table1 WHERE tag1 like 'A' || '%'"; + context = new MPPQueryContext(sql, queryId, sessionInfo, null, null); + analysis = analyzeSQL(sql, metadata, context); + symbolAllocator = new SymbolAllocator(); + logicalQueryPlan = + new TableLogicalPlanner( + context, metadata, sessionInfo, symbolAllocator, WarningCollector.NOOP) + .plan(analysis); + rootNode = logicalQueryPlan.getRootNode(); + + // Like with a non-literal pattern is evaluated by the filter operator. + assertTrue(rootNode.getChildren().get(0) instanceof FilterNode); + filterNode = (FilterNode) rootNode.getChildren().get(0); + assertTrue(filterNode.getPredicate().toString().contains("LIKE")); + assertTrue(rootNode.getChildren().get(0).getChildren().get(0) instanceof DeviceTableScanNode); + deviceTableScanNode = (DeviceTableScanNode) rootNode.getChildren().get(0).getChildren().get(0); + assertNull(deviceTableScanNode.getPushDownPredicate()); + assertFalse(deviceTableScanNode.getTimePredicate().isPresent()); + + sql = "SELECT * FROM table1 WHERE tag1 like concat('A', '%')"; + context = new MPPQueryContext(sql, queryId, sessionInfo, null, null); + analysis = analyzeSQL(sql, metadata, context); + symbolAllocator = new SymbolAllocator(); + logicalQueryPlan = + new TableLogicalPlanner( + context, metadata, sessionInfo, symbolAllocator, WarningCollector.NOOP) + .plan(analysis); + rootNode = logicalQueryPlan.getRootNode(); + + assertTrue(rootNode.getChildren().get(0) instanceof FilterNode); + filterNode = (FilterNode) rootNode.getChildren().get(0); + assertTrue(filterNode.getPredicate().toString().contains("LIKE")); + assertTrue(rootNode.getChildren().get(0).getChildren().get(0) instanceof DeviceTableScanNode); + deviceTableScanNode = (DeviceTableScanNode) rootNode.getChildren().get(0).getChildren().get(0); + assertNull(deviceTableScanNode.getPushDownPredicate()); + assertFalse(deviceTableScanNode.getTimePredicate().isPresent()); + // 3. in / not in sql = "SELECT *, s1/2, s2+1, s2*3, s1+s2, s2%1 FROM table1 WHERE tag1 in ('A', 'B') and tag2 not in ('A', 'C')";