1
0
Эх сурвалжийг харах

SQL: Concat should be always not nullable (#36601)

Andrei Stefan 6 жил өмнө
parent
commit
2ed6ab9648

+ 27 - 0
x-pack/plugin/sql/qa/src/main/resources/functions.csv-spec

@@ -68,6 +68,33 @@ cct:s
 AlejandroMcAlpine
 ;
 
+selectConcatWithNullValues
+SELECT first_name, CONCAT(first_name,null),last_name, CONCAT(null,null), LENGTH(CONCAT(null,null)) FROM test_emp ORDER BY first_name DESC LIMIT 20;
+
+ first_name:s  |CONCAT(first_name,null):s|  last_name:s   |CONCAT(null,null):s|LENGTH(CONCAT(null,null)):i
+---------------+-------------------------+----------------+-------------------+-------------------------
+null           |                         |Demeyer         |                   |0
+null           |                         |Joslin          |                   |0
+null           |                         |Reistad         |                   |0
+null           |                         |Merlo           |                   |0
+null           |                         |Swan            |                   |0
+null           |                         |Chappelet       |                   |0
+null           |                         |Portugali       |                   |0
+null           |                         |Makrucki        |                   |0
+null           |                         |Lortz           |                   |0
+null           |                         |Brender         |                   |0
+Zvonko         |Zvonko                   |Nyanchama       |                   |0
+Zhongwei       |Zhongwei                 |Rosen           |                   |0
+Yongqiao       |Yongqiao                 |Berztiss        |                   |0
+Yishay         |Yishay                   |Tzvieli         |                   |0
+Yinghua        |Yinghua                  |Dredge          |                   |0
+Xinglin        |Xinglin                  |Eugenio         |                   |0
+Weiyi          |Weiyi                    |Meriste         |                   |0
+Vishv          |Vishv                    |Zockler         |                   |0
+Valter         |Valter                   |Sullins         |                   |0
+Valdiodio      |Valdiodio                |Niizuma         |                   |0
+;
+
 selectAsciiOfConcatWithGroupByOrderByCount
 SELECT ASCII(CONCAT("first_name","last_name")) ascii, COUNT(*) count FROM "test_emp" GROUP BY ASCII(CONCAT("first_name","last_name")) ORDER BY ASCII(CONCAT("first_name","last_name")) DESC LIMIT 10;
 

+ 1 - 1
x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/string/Concat.java

@@ -51,7 +51,7 @@ public class Concat extends BinaryScalarFunction {
     
     @Override
     public boolean nullable() {
-        return left().nullable() && right().nullable();
+        return false;
     }
 
     @Override

+ 9 - 0
x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/optimizer/OptimizerTests.java

@@ -34,6 +34,7 @@ import org.elasticsearch.xpack.sql.expression.function.scalar.math.Cos;
 import org.elasticsearch.xpack.sql.expression.function.scalar.math.E;
 import org.elasticsearch.xpack.sql.expression.function.scalar.math.Floor;
 import org.elasticsearch.xpack.sql.expression.function.scalar.string.Ascii;
+import org.elasticsearch.xpack.sql.expression.function.scalar.string.Concat;
 import org.elasticsearch.xpack.sql.expression.function.scalar.string.Repeat;
 import org.elasticsearch.xpack.sql.expression.predicate.BinaryOperator;
 import org.elasticsearch.xpack.sql.expression.predicate.Range;
@@ -87,6 +88,7 @@ import org.elasticsearch.xpack.sql.tree.NodeInfo;
 import org.elasticsearch.xpack.sql.type.DataType;
 import org.elasticsearch.xpack.sql.type.EsField;
 import org.elasticsearch.xpack.sql.util.CollectionUtils;
+import org.elasticsearch.xpack.sql.util.StringUtils;
 
 import java.util.Arrays;
 import java.util.Collections;
@@ -519,6 +521,13 @@ public class OptimizerTests extends ESTestCase {
         assertEquals(ONE, e.children().get(0));
         assertEquals(TWO, e.children().get(1));
     }
+    
+    public void testConcatFoldingIsNotNull() {
+        FoldNull foldNull = new FoldNull();
+        assertEquals(1, foldNull.rule(new Concat(EMPTY, Literal.NULL, ONE)).fold());
+        assertEquals(1, foldNull.rule(new Concat(EMPTY, ONE, Literal.NULL)).fold());
+        assertEquals(StringUtils.EMPTY, foldNull.rule(new Concat(EMPTY, Literal.NULL, Literal.NULL)).fold());
+    }
 
     //
     // Logical simplifications

+ 10 - 0
x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/planner/QueryFolderTests.java

@@ -263,4 +263,14 @@ public class QueryFolderTests extends ESTestCase {
         assertThat(ee.output().get(0).toString(), startsWith("COUNT(1){a->"));
         assertThat(ee.output().get(1).toString(), startsWith("a{s->"));
     }
+
+    public void testConcatIsNotFoldedForNull() {
+        PhysicalPlan p = plan("SELECT keyword FROM test WHERE CONCAT(keyword, null) IS NULL");
+        assertEquals(LocalExec.class, p.getClass());
+        LocalExec le = (LocalExec) p;
+        assertEquals(EmptyExecutable.class, le.executable().getClass());
+        EmptyExecutable ee = (EmptyExecutable) le.executable();
+        assertEquals(1, ee.output().size());
+        assertThat(ee.output().get(0).toString(), startsWith("keyword{f}#"));
+    }
 }