Changeset: 90572cb38f04 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=90572cb38f04
Modified Files:
        monetdb5/optimizer/opt_pushselect.c
        sql/test/SQLancer/Tests/sqlancer09.stable.out
Branch: Oct2020
Log Message:

rewrite batalgebra.like + [theta]select -> likeselect cannot be done if the 
select statement was generated from an expression with NULL semantics. Later we 
can generate OR statements on this case


diffs (95 lines):

diff --git a/monetdb5/optimizer/opt_pushselect.c 
b/monetdb5/optimizer/opt_pushselect.c
--- a/monetdb5/optimizer/opt_pushselect.c
+++ b/monetdb5/optimizer/opt_pushselect.c
@@ -323,30 +323,45 @@ OPTpushselectImplementation(Client cntxt
                                                !isaBatType(getArgType(mb, q, 
2)) && /* pattern is a value */
                                                (q->argc != 4 || 
!isaBatType(getArgType(mb, q, 3))) /* escape is a value */
                                                ) {
-                                       InstrPtr r = newInstruction(mb, 
algebraRef, likeselectRef);
+                                       bool has_null_semantics = false;
                                        int has_cand = (getArgType(mb, p, 2) == 
newBatType(TYPE_oid)), offset = 0;
                                        int a, anti = (getFunctionId(q)[0] == 
'n'), ignore_case = (getFunctionId(q)[anti?4:0] == 'i');
 
-                                       getArg(r,0) = getArg(p,0);
-                                       r = addArgument(mb, r, getArg(q, 1));
-                                       if (has_cand) {
-                                               r = addArgument(mb, r, 
getArg(p, 2));
-                                               offset = 1;
-                                       } else if (isaBatType(getArgType(mb, q, 
1))) { /* likeselect calls have a candidate parameter */
-                                               r = pushNil(mb, r, TYPE_bat);
-                                               offset = 1;
+                                       /* TODO at the moment we cannot convert 
if the select statement has NULL semantics
+                                               we can convert it into VAL is 
NULL or PATERN is NULL or ESCAPE is NULL
+                                       */
+                                       if (getFunctionId(p) == selectRef && 
isVarConstant(mb,getArg(p, 2 + has_cand)) && isVarConstant(mb,getArg(p, 3 + 
has_cand))
+                                               && isVarConstant(mb,getArg(p, 4 
+ has_cand)) && isVarConstant(mb,getArg(p, 5 + has_cand))) {
+                                               ValRecord low = 
getVarConstant(mb, getArg(p, 2 + has_cand)), high = getVarConstant(mb, 
getArg(p, 3 + has_cand));
+                                               bit li = *(bit*)getVarValue(mb, 
getArg(p, 4 + has_cand)), hi = *(bit*)getVarValue(mb, getArg(p, 5 + has_cand));
+
+                                               if (li && hi && VALisnil(&low) 
&& VALisnil(&high))
+                                                       has_null_semantics = 
true;
                                        }
-                                       for(a = 2; a<q->argc; a++)
-                                               r = addArgument(mb, r, 
getArg(q, a));
-                                       if (r->argc < (4+offset))
-                                               r = pushStr(mb, r, ""); /* 
default esc */
-                                       if (r->argc < (5+offset))
-                                               r = pushBit(mb, r, ignore_case);
-                                       if (r->argc < (6+offset))
-                                               r = pushBit(mb, r, anti);
-                                       freeInstruction(p);
-                                       p = r;
-                                       actions++;
+
+                                       if (!has_null_semantics) {
+                                               InstrPtr r = newInstruction(mb, 
algebraRef, likeselectRef);
+                                               getArg(r,0) = getArg(p,0);
+                                               r = addArgument(mb, r, 
getArg(q, 1));
+                                               if (has_cand) {
+                                                       r = addArgument(mb, r, 
getArg(p, 2));
+                                                       offset = 1;
+                                               } else if 
(isaBatType(getArgType(mb, q, 1))) { /* likeselect calls have a candidate 
parameter */
+                                                       r = pushNil(mb, r, 
TYPE_bat);
+                                                       offset = 1;
+                                               }
+                                               for(a = 2; a<q->argc; a++)
+                                                       r = addArgument(mb, r, 
getArg(q, a));
+                                               if (r->argc < (4+offset))
+                                                       r = pushStr(mb, r, ""); 
/* default esc */
+                                               if (r->argc < (5+offset))
+                                                       r = pushBit(mb, r, 
ignore_case);
+                                               if (r->argc < (6+offset))
+                                                       r = pushBit(mb, r, 
anti);
+                                               freeInstruction(p);
+                                               p = r;
+                                               actions++;
+                                       }
                                }
                        }
 
diff --git a/sql/test/SQLancer/Tests/sqlancer09.stable.out 
b/sql/test/SQLancer/Tests/sqlancer09.stable.out
--- a/sql/test/SQLancer/Tests/sqlancer09.stable.out
+++ b/sql/test/SQLancer/Tests/sqlancer09.stable.out
@@ -377,8 +377,8 @@ stdout of test 'sqlancer09` in directory
 % .%145 # table_name
 % %145 # name
 % bigint # type
-% 2 # length
-[ 12   ]
+% 1 # length
+[ 6    ]
 #create or replace view v11(vc0) as (values ('<'), ('a'));
 #SELECT 1 FROM v11 WHERE v11.vc0 LIKE '' IS NULL;
 % .%4 # table_name
@@ -386,6 +386,11 @@ stdout of test 'sqlancer09` in directory
 % tinyint # type
 % 1 # length
 #ROLLBACK;
+#SELECT 1 HAVING group_concat('') NOT LIKE '3' IS NULL;
+% .%3 # table_name
+% %3 # name
+% tinyint # type
+% 1 # length
 
 # 14:35:03 >  
 # 14:35:03 >  "Done."
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to