diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index bb5a784deda..5b7eac5e2c6 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -285,6 +285,8 @@ Other Changes * SOLR-10155: For numeric types facet.contains= and facet.prefix= are now rejected. (Gus Heck, Christine Poerschke) +* SOLR-10171 Add Constant Reduction Rules to Calcite Planner (Kevin Risden) + ================== 6.4.2 ================== Consult the LUCENE_CHANGES.txt file for additional, low level, changes in this release. diff --git a/solr/core/src/java/org/apache/solr/handler/sql/SolrRules.java b/solr/core/src/java/org/apache/solr/handler/sql/SolrRules.java index 4cbadda5494..bbc4eb7ac58 100644 --- a/solr/core/src/java/org/apache/solr/handler/sql/SolrRules.java +++ b/solr/core/src/java/org/apache/solr/handler/sql/SolrRules.java @@ -26,6 +26,9 @@ import org.apache.calcite.rel.logical.LogicalAggregate; import org.apache.calcite.rel.logical.LogicalFilter; import org.apache.calcite.rel.logical.LogicalProject; import org.apache.calcite.rel.logical.LogicalSort; +import org.apache.calcite.rel.rules.AggregateValuesRule; +import org.apache.calcite.rel.rules.ReduceExpressionsRule; +import org.apache.calcite.rel.rules.ValuesReduceRule; import org.apache.calcite.rel.type.RelDataType; import org.apache.calcite.rex.RexCall; import org.apache.calcite.rex.RexInputRef; @@ -52,6 +55,17 @@ class SolrRules { SolrAggregateRule.AGGREGATE_RULE, }; + static final RelOptRule[] CONSTANT_REDUCTION_RULES = { + ReduceExpressionsRule.PROJECT_INSTANCE, + ReduceExpressionsRule.FILTER_INSTANCE, + ReduceExpressionsRule.CALC_INSTANCE, + ReduceExpressionsRule.JOIN_INSTANCE, + ValuesReduceRule.FILTER_INSTANCE, + ValuesReduceRule.PROJECT_FILTER_INSTANCE, + ValuesReduceRule.PROJECT_INSTANCE, + AggregateValuesRule.INSTANCE + }; + static List solrFieldNames(final RelDataType rowType) { return SqlValidatorUtil.uniquify( new AbstractList() { diff --git a/solr/core/src/java/org/apache/solr/handler/sql/SolrTableScan.java b/solr/core/src/java/org/apache/solr/handler/sql/SolrTableScan.java index 88c53ac0968..5363d59bbf3 100644 --- a/solr/core/src/java/org/apache/solr/handler/sql/SolrTableScan.java +++ b/solr/core/src/java/org/apache/solr/handler/sql/SolrTableScan.java @@ -72,6 +72,10 @@ class SolrTableScan extends TableScan implements SolrRel { for (RelOptRule rule : SolrRules.RULES) { planner.addRule(rule); } + + for (RelOptRule rule : SolrRules.CONSTANT_REDUCTION_RULES) { + planner.addRule(rule); + } } public void implement(Implementor implementor) { diff --git a/solr/core/src/test/org/apache/solr/handler/TestSQLHandler.java b/solr/core/src/test/org/apache/solr/handler/TestSQLHandler.java index 35f7ad05b9e..d724fbd485b 100644 --- a/solr/core/src/test/org/apache/solr/handler/TestSQLHandler.java +++ b/solr/core/src/test/org/apache/solr/handler/TestSQLHandler.java @@ -317,6 +317,14 @@ public class TestSQLHandler extends AbstractFullDistribZkTestBase { assert(tuple.getLong("myInt") == 7); assert(tuple.get("myString").equals("a")); + // SOLR-8845 - Test to make sure that 1 = 0 works for things like Spark SQL + sParams = mapParams(CommonParams.QT, "/sql", + "stmt", "select id, field_i, str_s from collection1 where 1 = 0"); + + solrStream = new SolrStream(jetty.url, sParams); + tuples = getTuples(solrStream); + + assertEquals(0, tuples.size()); } finally { delete(); } diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/sql/JdbcTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/sql/JdbcTest.java index 927856aed5b..ce14907eb9d 100644 --- a/solr/solrj/src/test/org/apache/solr/client/solrj/io/sql/JdbcTest.java +++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/sql/JdbcTest.java @@ -449,6 +449,25 @@ public class JdbcTest extends SolrCloudTestCase { } } + @Test + public void testOneEqualZeroMetadata() throws Exception { + // SOLR-8845 - Make sure that 1 = 1 (literal comparison literal) works + try (Connection con = DriverManager.getConnection("jdbc:solr://" + zkHost + + "?collection=" + COLLECTIONORALIAS)) { + + try (Statement stmt = con.createStatement()) { + try (ResultSet rs = stmt.executeQuery("select a_s from " + COLLECTIONORALIAS + " where 1 = 0")) { + assertFalse(rs.next()); + + ResultSetMetaData resultSetMetaData = rs.getMetaData(); + assertNotNull(resultSetMetaData); + assertEquals(1, resultSetMetaData.getColumnCount()); + assertEquals("a_s", resultSetMetaData.getColumnName(1)); + } + } + } + } + @Test public void testDriverMetadata() throws Exception { String collection = COLLECTIONORALIAS;