Changeset: 6b817deadb3a for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=6b817deadb3a
Modified Files:
        clients/Tests/MAL-signatures.stable.out
        clients/Tests/MAL-signatures.stable.out.int128
        sql/backends/monet5/sql.c
        sql/backends/monet5/sql_subquery.c
        sql/backends/monet5/sql_subquery.h
        sql/backends/monet5/sql_subquery.mal
Branch: default
Log Message:

Implemented SQLall_grp with candidate list


diffs (truncated from 370 to 300 lines):

diff --git a/clients/Tests/MAL-signatures.stable.out 
b/clients/Tests/MAL-signatures.stable.out
--- a/clients/Tests/MAL-signatures.stable.out
+++ b/clients/Tests/MAL-signatures.stable.out
@@ -10188,7 +10188,8 @@ stdout of test 'MAL-signatures` in direc
 [ "sql",       "storage",      "pattern sql.storage(X_17:str, X_18:str, 
X_19:str) (X_0:bat[:str], X_1:bat[:str], X_2:bat[:str], X_3:bat[:str], 
X_4:bat[:str], X_5:bat[:str], X_6:bat[:lng], X_7:bat[:int], X_8:bat[:lng], 
X_9:bat[:lng], X_10:bat[:lng], X_11:bat[:bit], X_12:bat[:lng], X_13:bat[:bit], 
X_14:bat[:bit], X_15:bat[:bit], X_16:bat[:lng]) ",    "sql_storage;", ""      ]
 [ "sql",       "str_group_concat",     "pattern sql.str_group_concat(X_1:str, 
X_2:lng, X_3:lng):str ", "SQLstrgroup_concat;",  ""      ]
 [ "sql",       "str_group_concat",     "pattern sql.str_group_concat(X_1:str, 
X_2:str, X_3:lng, X_4:lng):str ",        "SQLstrgroup_concat;",  ""      ]
-[ "sql",       "suball",       "command sql.suball(X_1:bat[:any_1], 
X_2:bat[:oid], X_3:bat[:oid], X_4:bit):bat[:any_1] ",      "SQLall_grp;",  ""   
   ]
+[ "sql",       "suball",       "pattern sql.suball(X_1:bat[:any_1], 
X_2:bat[:oid], X_3:bat[:oid], X_4:bat[:oid], X_5:bit):bat[:any_1] ",       
"SQLall_grp;",  ""      ]
+[ "sql",       "suball",       "pattern sql.suball(X_1:bat[:any_1], 
X_2:bat[:oid], X_3:bat[:oid], X_4:bit):bat[:any_1] ",      "SQLall_grp;",  ""   
   ]
 [ "sql",       "subdelta",     "command sql.subdelta(X_1:bat[:oid], 
X_2:bat[:oid], X_3:bat[:oid], X_4:bat[:oid]):bat[:oid] ",  "DELTAsub2;",   ""   
   ]
 [ "sql",       "subdelta",     "command sql.subdelta(X_1:bat[:oid], 
X_2:bat[:oid], X_3:bat[:oid], X_4:bat[:oid], X_5:bat[:oid]):bat[:oid] ",   
"DELTAsub;",    ""      ]
 [ "sql",       "subnull",      "pattern sql.subnull(X_1:bat[:any_1], 
X_2:bat[:oid], X_3:bat[:oid], X_4:bat[:oid], X_5:bit):bat[:bit] ",        
"SQLnil_grp;",  ""      ]
diff --git a/clients/Tests/MAL-signatures.stable.out.int128 
b/clients/Tests/MAL-signatures.stable.out.int128
--- a/clients/Tests/MAL-signatures.stable.out.int128
+++ b/clients/Tests/MAL-signatures.stable.out.int128
@@ -13554,7 +13554,8 @@ stdout of test 'MAL-signatures` in direc
 [ "sql",       "storage",      "pattern sql.storage(X_17:str, X_18:str, 
X_19:str) (X_0:bat[:str], X_1:bat[:str], X_2:bat[:str], X_3:bat[:str], 
X_4:bat[:str], X_5:bat[:str], X_6:bat[:lng], X_7:bat[:int], X_8:bat[:lng], 
X_9:bat[:lng], X_10:bat[:lng], X_11:bat[:bit], X_12:bat[:lng], X_13:bat[:bit], 
X_14:bat[:bit], X_15:bat[:bit], X_16:bat[:lng]) ",    "sql_storage;", ""      ]
 [ "sql",       "str_group_concat",     "pattern sql.str_group_concat(X_1:str, 
X_2:lng, X_3:lng):str ", "SQLstrgroup_concat;",  ""      ]
 [ "sql",       "str_group_concat",     "pattern sql.str_group_concat(X_1:str, 
X_2:str, X_3:lng, X_4:lng):str ",        "SQLstrgroup_concat;",  ""      ]
-[ "sql",       "suball",       "command sql.suball(X_1:bat[:any_1], 
X_2:bat[:oid], X_3:bat[:oid], X_4:bit):bat[:any_1] ",      "SQLall_grp;",  ""   
   ]
+[ "sql",       "suball",       "pattern sql.suball(X_1:bat[:any_1], 
X_2:bat[:oid], X_3:bat[:oid], X_4:bat[:oid], X_5:bit):bat[:any_1] ",       
"SQLall_grp;",  ""      ]
+[ "sql",       "suball",       "pattern sql.suball(X_1:bat[:any_1], 
X_2:bat[:oid], X_3:bat[:oid], X_4:bit):bat[:any_1] ",      "SQLall_grp;",  ""   
   ]
 [ "sql",       "subdelta",     "command sql.subdelta(X_1:bat[:oid], 
X_2:bat[:oid], X_3:bat[:oid], X_4:bat[:oid]):bat[:oid] ",  "DELTAsub2;",   ""   
   ]
 [ "sql",       "subdelta",     "command sql.subdelta(X_1:bat[:oid], 
X_2:bat[:oid], X_3:bat[:oid], X_4:bat[:oid], X_5:bat[:oid]):bat[:oid] ",   
"DELTAsub;",    ""      ]
 [ "sql",       "subnull",      "pattern sql.subnull(X_1:bat[:any_1], 
X_2:bat[:oid], X_3:bat[:oid], X_4:bat[:oid], X_5:bit):bat[:bit] ",        
"SQLnil_grp;",  ""      ]
diff --git a/sql/backends/monet5/sql.c b/sql/backends/monet5/sql.c
--- a/sql/backends/monet5/sql.c
+++ b/sql/backends/monet5/sql.c
@@ -6627,7 +6627,8 @@ static mel_func sql_init_funcs[] = {
  command("sql", "zero_or_one", zero_or_one_error_bat, false, "if col contains 
exactly one value return this. Incase of more raise an exception if err is true 
else return nil", args(1,3, argany("",1),batargany("col",1),batarg("err",bit))),
  command("sql", "subzero_or_one", SQLsubzero_or_one, false, "", args(1,5, 
batargany("",1),batargany("b",1),batarg("g",oid),batarg("e",oid),arg("no_nil",bit))),
  command("sql", "all", SQLall, false, "if all values in col are equal return 
this, else nil", args(1,2, argany("",1),batargany("col",1))),
- command("sql", "suball", SQLall_grp, false, "if all values in l are equal 
(per group) return the value, else nil", args(1,5, 
batargany("",1),batargany("l",1),batarg("g",oid),batarg("e",oid),arg("no_nil",bit))),
+ pattern("sql", "suball", SQLall_grp, false, "if all values in l are equal 
(per group) return the value, else nil", args(1,5, 
batargany("",1),batargany("l",1),batarg("g",oid),batarg("e",oid),arg("no_nil",bit))),
+ pattern("sql", "suball", SQLall_grp, false, "if all values in l are equal 
(per group) return the value, else nil", args(1,6, 
batargany("",1),batargany("l",1),batarg("g",oid),batarg("e",oid),batarg("s",oid),arg("no_nil",bit))),
  command("sql", "null", SQLnil, false, "if b has a nil return true, else 
false", args(1,2, arg("",bit),batargany("b",1))),
  pattern("sql", "subnull", SQLnil_grp, false, "if any value in l is nil with 
in a group return true for that group, else false", args(1,5, 
batarg("",bit),batargany("l",1),batarg("g",oid),batarg("e",oid),arg("no_nil",bit))),
  pattern("sql", "subnull", SQLnil_grp, false, "if any value in l is nil with 
in a group return true for that group, else false; with candidate list", 
args(1,6, 
batarg("",bit),batargany("l",1),batarg("g",oid),batarg("e",oid),batarg("s",oid),arg("no_nil",bit))),
diff --git a/sql/backends/monet5/sql_subquery.c 
b/sql/backends/monet5/sql_subquery.c
--- a/sql/backends/monet5/sql_subquery.c
+++ b/sql/backends/monet5/sql_subquery.c
@@ -118,7 +118,7 @@ SQLsubzero_or_one(bat *ret, const bat *b
 
 #define SQLall_imp(TPE) \
        do {            \
-               TPE *restrict bp = (TPE*)Tloc(b, 0), val;       \
+               TPE *restrict bp = (TPE*)Tloc(b, 0), val = TPE##_nil;   \
                for (; q < c; q++) { /* find first non nil */ \
                        val = bp[q]; \
                        if (!is_##TPE##_nil(val)) \
@@ -183,6 +183,7 @@ SQLall(ptr ret, const bat *bid)
                        int (*ocmp) (const void *, const void *) = 
ATOMcompare(b->ttype);
                        const void *restrict n = ATOMnilptr(b->ttype);
                        BATiter bi = bat_iterator(b);
+                       p = n;
 
                        for (; q < c; q++) { /* find first non nil */
                                p = BUNtail(bi, q);
@@ -235,99 +236,201 @@ SQLall(ptr ret, const bat *bid)
        return MAL_SUCCEED;
 }
 
+#define SQLall_grp_imp(TYPE)   \
+       do {                    \
+               const TYPE *restrict vals = (const TYPE *) Tloc(l, 0); \
+               TYPE *restrict rp = (TYPE *) Tloc(res, 0); \
+               while (ncand > 0) {                                     \
+                       ncand--;                                        \
+                       i = canditer_next(&ci) - l->hseqbase;           \
+                       if (gids == NULL ||                             \
+                           (gids[i] >= min && gids[i] <= max)) {       \
+                               if (gids)                               \
+                                       gid = gids[i] - min;            \
+                               else                                    \
+                                       gid = (oid) i;                  \
+                               if (oids[gid] != (BUN_NONE - 1)) { \
+                                       if (oids[gid] == BUN_NONE) { \
+                                               if (!is_##TYPE##_nil(vals[i])) \
+                                                       oids[gid] = i; \
+                                       } else { \
+                                               if (vals[oids[gid]] != vals[i] 
&& !is_##TYPE##_nil(vals[i])) \
+                                                       oids[gid] = BUN_NONE - 
1; \
+                                       } \
+                               } \
+                       } \
+               } \
+               for (i = 0; i < ngrp; i++) { /* convert the found oids in 
values */ \
+                       BUN noid = oids[i]; \
+                       if (noid >= (BUN_NONE - 1)) { \
+                               rp[i] = TYPE##_nil; \
+                               hasnil = 1; \
+                       } else { \
+                               rp[i] = vals[noid]; \
+                       } \
+               } \
+       } while (0)
+
 str
-SQLall_grp(bat *ret, const bat *bid, const bat *gp, const bat *gpe, bit 
*no_nil)
+SQLall_grp(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
 {
-       BAT *l, *g, *e, *res;
-       BATiter li;
-       ssize_t p, *pos = NULL;
-       int error = 0, has_nil = 0;
-       int (*ocmp) (const void *, const void *);
-       const void *nilp;
+       bat *ret = getArgReference_bat(stk, pci, 0);
+       bat *lp = getArgReference_bat(stk, pci, 1);
+       bat *gp = getArgReference_bat(stk, pci, 2);
+       bat *gpe = getArgReference_bat(stk, pci, 3);
+       bat *sp = pci->argc == 6 ? getArgReference_bat(stk, pci, 4) : NULL;
+       //bit *no_nil = getArgReference_bit(stk, pci, pci->argc == 6 ? 5 : 4); 
no_nil argument is ignored
+       BAT *l = NULL, *g = NULL, *e = NULL, *s = NULL, *res = NULL;
+       const oid *restrict gids;
+       oid gid, min, max, *restrict oids = NULL; /* The oids variable controls 
if we have found a nil in the group so far */
+       BUN i, ngrp, ncand;
+       bit hasnil = 0;
+       struct canditer ci;
+       str msg = MAL_SUCCEED;
 
-       (void)no_nil;
-       if ((l = BATdescriptor(*bid)) == NULL) {
-               throw(SQL, "sql.all =", SQLSTATE(HY005) "Cannot access column 
descriptor");
+       (void)cntxt;
+       (void)mb;
+       if ((l = BATdescriptor(*lp)) == NULL) {
+               msg = createException(SQL, "sql.all =", SQLSTATE(HY005) "Cannot 
access column descriptor");
+               goto bailout;
        }
        if ((g = BATdescriptor(*gp)) == NULL) {
-               BBPunfix(l->batCacheid);
-               throw(SQL, "sql.all =", SQLSTATE(HY005) "Cannot access column 
descriptor");
+               msg = createException(SQL, "sql.all =", SQLSTATE(HY005) "Cannot 
access column descriptor");
+               goto bailout;
        }
        if ((e = BATdescriptor(*gpe)) == NULL) {
-               BBPunfix(l->batCacheid);
-               BBPunfix(g->batCacheid);
-               throw(SQL, "sql.all =", SQLSTATE(HY005) "Cannot access column 
descriptor");
+               msg = createException(SQL, "sql.all =", SQLSTATE(HY005) "Cannot 
access column descriptor");
+               goto bailout;
+       }
+       if (sp && (s = BATdescriptor(*sp)) == NULL) {
+               msg = createException(SQL, "sql.all =", SQLSTATE(HY005) "Cannot 
access column descriptor");
+               goto bailout;
+       }
+
+       if ((msg = (str)BATgroupaggrinit(l, g, e, s, &min, &max, &ngrp, &ci, 
&ncand)) != NULL)
+               goto bailout;
+       if (g == NULL) {
+               msg = createException(SQL, "sql.all =", SQLSTATE(HY005) "l and 
g must be aligned");
+               goto bailout;
        }
-       li = bat_iterator(l);
-               nilp = ATOMnilptr(l->ttype);
-       ocmp = ATOMcompare(l->ttype);
-       if (BATcount(g) > 0) {
-               BUN q, o, s, offset = 0;
-               BATiter gi = bat_iterator(g);
-
-               if ((pos = GDKmalloc(sizeof(BUN)*BATcount(e))) == NULL) {
-                       BBPunfix(l->batCacheid);
-                       BBPunfix(g->batCacheid);
-                       BBPunfix(e->batCacheid);
-                       throw(SQL, "sql.all =", SQLSTATE(HY013) 
MAL_MALLOC_FAIL);
+       if (BATcount(l) == 0 || ngrp == 0) {
+               const void *nilp = ATOMnilptr(l->ttype);
+               if ((res = BATconstant(ngrp == 0 ? 0 : min, l->ttype, nilp, 
ngrp, TRANSIENT)) == NULL) {
+                       msg = createException(SQL, "sql.all =", SQLSTATE(HY005) 
"Cannot access column descriptor");
+                       goto bailout;
+               }
+       } else {
+               if ((res = COLnew(min, l->ttype, ngrp, TRANSIENT)) == NULL) {
+                       msg = createException(SQL, "sql.all =", SQLSTATE(HY005) 
"Cannot access column descriptor");
+                       goto bailout;
+               }
+               if ((oids = GDKmalloc(ngrp * sizeof(oid))) == NULL) {
+                       msg = createException(SQL, "sql.all =", SQLSTATE(HY001) 
MAL_MALLOC_FAIL);
+                       goto bailout;
                }
-               for (s = 0; s < BATcount(e); s++) 
-                       pos[s] = -1;
+               for (i = 0; i < ngrp; i++)
+                       oids[i] = BUN_NONE;
+
+               if (!g || BATtdense(g))
+                       gids = NULL;
+               else
+                       gids = (const oid *) Tloc(g, 0);
 
-               offset = g->hseqbase - l->hseqbase;
-               o = BUNlast(g);
-               for (q = offset, s = 0; s < o; q++, s++) {
-                       oid id = *(oid*)BUNtail(gi, s);
-                       if (pos[id] == -2)
-                               continue;
-                       else if (pos[id] == -1) {
-                               const void *lv = BUNtail(li, q);
-                               if (ocmp(nilp, lv) != 0) /* not nil */
-                                       pos[id] = q;
-                       } else {
-                               const void *lv = BUNtail(li, q);
-                               const void *rv = BUNtail(li, pos[id]);
+               switch (l->ttype) {
+               case TYPE_bit:
+                       SQLall_grp_imp(bit);
+                       break;
+               case TYPE_bte:
+                       SQLall_grp_imp(bte);
+                       break;
+               case TYPE_sht:
+                       SQLall_grp_imp(sht);
+                       break;
+               case TYPE_int:
+                       SQLall_grp_imp(int);
+                       break;
+               case TYPE_lng:
+                       SQLall_grp_imp(lng);
+                       break;
+#ifdef HAVE_HGE
+               case TYPE_hge:
+                       SQLall_grp_imp(hge);
+                       break;
+#endif
+               case TYPE_flt:
+                       SQLall_grp_imp(flt);
+                       break;
+               case TYPE_dbl:
+                       SQLall_grp_imp(dbl);
+                       break;
+               default: {
+                       int (*ocmp) (const void *, const void *) = 
ATOMcompare(l->ttype);
+                       const void *restrict nilp = ATOMnilptr(l->ttype);
+                       BATiter li = bat_iterator(l);
 
-                               if (ocmp(lv, rv) != 0) /* values are different 
*/
-                                       if (ocmp(nilp, rv) != 0) /* and not nil 
*/
-                                               pos[id] = -2;
+                       while (ncand > 0) {
+                               ncand--;
+                               i = canditer_next(&ci) - l->hseqbase;
+                               if (gids == NULL ||
+                                       (gids[i] >= min && gids[i] <= max)) {
+                                       if (gids)
+                                               gid = gids[i] - min;
+                                       else
+                                               gid = (oid) i;
+                                       if (oids[gid] != (BUN_NONE - 1)) {
+                                               if (oids[gid] == BUN_NONE) {
+                                                       if (ocmp(BUNtail(li, 
i), nilp) != 0)
+                                                               oids[gid] = i;
+                                               } else {
+                                                       const void *pi = 
BUNtail(li, oids[gid]);
+                                                       const void *pp = 
BUNtail(li, i);
+                                                       if (ocmp(pi, pp) != 0 
&& ocmp(pp, nilp) != 0)
+                                                               oids[gid] = 
BUN_NONE - 1;
+                                               }
+                                       }
+                               }
+                       }
+
+                       for (i = 0; i < ngrp; i++) { /* convert the found oids 
in values */
+                               BUN noid = oids[i];
+                               void *next;
+                               if (noid == BUN_NONE) {
+                                       next = (void*) nilp;
+                                       hasnil = 1;
+                               } else {
+                                       next = BUNtail(li, noid);
+                               }
+                               if (BUNappend(res, next, false) != GDK_SUCCEED) 
{
+                                       msg = createException(SQL, "sql.all =", 
SQLSTATE(HY001) MAL_MALLOC_FAIL);
+                                       goto bailout;
+                               }
                        }
                }
-       }
-
-       if ((res = COLnew(e->hseqbase, l->ttype, BATcount(e), TRANSIENT)) == 
NULL) {
-               BBPunfix(l->batCacheid);
-               BBPunfix(g->batCacheid);
-               BBPunfix(e->batCacheid);
-               GDKfree(pos);
-               throw(SQL, "sql.all =", SQLSTATE(HY013) MAL_MALLOC_FAIL);
+               }
+               BATsetcount(res, ngrp);
+               res->tnil = hasnil != 0;
+               res->tnonil = hasnil == 0;
+               res->tkey = BATcount(res) <= 1;
+               res->tsorted = BATcount(res) <= 1;
+               res->trevsorted = BATcount(res) <= 1;
        }
 
-       for (p = 0; p < (ssize_t)BATcount(e) && !error; p++) {
-               const void *v = nilp;
-               if (pos[p] >= 0) {
-                       v = BUNtail(li, pos[p]);
-                       if (ocmp(v, nilp) == 0)
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to