LCOV - code coverage report
Current view: top level - sql/backends/monet5 - sql_subquery.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 365 838 43.6 %
Date: 2024-04-25 20:03:45 Functions: 12 21 57.1 %

          Line data    Source code
       1             : /*
       2             :  * SPDX-License-Identifier: MPL-2.0
       3             :  *
       4             :  * This Source Code Form is subject to the terms of the Mozilla Public
       5             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       6             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       7             :  *
       8             :  * Copyright 2024 MonetDB Foundation;
       9             :  * Copyright August 2008 - 2023 MonetDB B.V.;
      10             :  * Copyright 1997 - July 2008 CWI.
      11             :  */
      12             : 
      13             : #include "monetdb_config.h"
      14             : #include "sql_subquery.h"
      15             : #include "gdk_subquery.h"
      16             : 
      17             : str
      18         445 : zero_or_one_error(ptr ret, const bat *bid, const bit *err)
      19             : {
      20         445 :         BAT *b;
      21         445 :         BUN c;
      22         445 :         size_t _s;
      23         445 :         BATiter bi;
      24         445 :         const void *p = NULL;
      25             : 
      26         445 :         if ((b = BATdescriptor(*bid)) == NULL)
      27           0 :                 throw(SQL, "sql.zero_or_one", SQLSTATE(HY005) "Cannot access column descriptor");
      28         445 :         c = BATcount(b);
      29         445 :         if (c == 0) {
      30          37 :                 bi = bat_iterator(NULL);
      31          37 :                 p = ATOMnilptr(b->ttype);
      32         408 :         } else if (c == 1 || (c > 1 && *err == false)) {
      33         388 :                 bi = bat_iterator(b);
      34         388 :                 p = BUNtail(bi, 0);
      35             :         } else {
      36          20 :                 BBPunfix(b->batCacheid);
      37          20 :                 throw(SQL, "sql.zero_or_one", SQLSTATE(21000) "Cardinality violation, scalar value expected");
      38             :         }
      39         425 :         _s = ATOMsize(ATOMtype(b->ttype));
      40         425 :         if (b->ttype == TYPE_void)
      41           0 :                 p = &oid_nil;
      42         425 :         if (ATOMextern(b->ttype)) {
      43         312 :                 _s = ATOMlen(ATOMtype(b->ttype), p);
      44         312 :                 *(ptr *) ret = GDKmalloc(_s);
      45         312 :                 if (*(ptr *) ret == NULL) {
      46           0 :                         bat_iterator_end(&bi);
      47           0 :                         BBPunfix(b->batCacheid);
      48           0 :                         throw(SQL, "sql.zero_or_one", SQLSTATE(HY013) MAL_MALLOC_FAIL);
      49             :                 }
      50         312 :                 memcpy(*(ptr *) ret, p, _s);
      51         113 :         } else if (b->ttype == TYPE_bat) {
      52           0 :                 bat bid = *(bat *) p;
      53           0 :                 if ((*(BAT **) ret = BATdescriptor(bid)) == NULL){
      54           0 :                         bat_iterator_end(&bi);
      55           0 :                         BBPunfix(b->batCacheid);
      56           0 :                         throw(SQL, "sql.zero_or_one", SQLSTATE(HY005) "Cannot access column descriptor");
      57             :                 }
      58         113 :         } else if (_s == 4) {
      59          43 :                 *(int *) ret = *(int *) p;
      60             :         } else if (_s == 1) {
      61           2 :                 *(bte *) ret = *(bte *) p;
      62             :         } else if (_s == 2) {
      63           0 :                 *(sht *) ret = *(sht *) p;
      64             :         } else if (_s == 8) {
      65          60 :                 *(lng *) ret = *(lng *) p;
      66             : #ifdef HAVE_HGE
      67             :         } else if (_s == 16) {
      68           8 :                 *(hge *) ret = *(hge *) p;
      69             : #endif
      70             :         } else {
      71           0 :                 memcpy(ret, p, _s);
      72             :         }
      73         425 :         bat_iterator_end(&bi);
      74         425 :         BBPunfix(b->batCacheid);
      75         425 :         return MAL_SUCCEED;
      76             : }
      77             : 
      78             : str
      79           0 : zero_or_one_error_bat(ptr ret, const bat *bid, const bat *err)
      80             : {
      81           0 :         bit t = FALSE;
      82           0 :         (void)err;
      83           0 :         return zero_or_one_error(ret, bid, &t);
      84             : }
      85             : 
      86             : str
      87         445 : zero_or_one(ptr ret, const bat *bid)
      88             : {
      89         445 :         bit t = TRUE;
      90         445 :         return zero_or_one_error(ret, bid, &t);
      91             : }
      92             : 
      93             : str
      94           0 : SQLsubzero_or_one(bat *ret, const bat *bid, const bat *gid, const bat *eid, bit *no_nil)
      95             : {
      96           0 :         gdk_return r;
      97           0 :         BAT *ng = NULL, *h = NULL, *g = NULL;
      98           0 :         lng max = 0;
      99             : 
     100           0 :         (void)no_nil;
     101           0 :         (void)eid;
     102             : 
     103           0 :         if (!(g = BATdescriptor(*gid)))
     104           0 :                 throw(MAL, "sql.subzero_or_one", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     105           0 :         r = BATgroup(&ng, NULL, &h, g, NULL, NULL, NULL, NULL);
     106           0 :         BBPunfix(g->batCacheid);
     107           0 :         if (r != GDK_SUCCEED)
     108           0 :                 throw(MAL, "sql.subzero_or_one", GDK_EXCEPTION);
     109             : 
     110           0 :         BBPreclaim(ng);
     111           0 :         BATmax(h, &max);
     112           0 :         BBPunfix(h->batCacheid);
     113             : 
     114           0 :         if (max != lng_nil && max > 1)
     115           0 :                 throw(SQL, "sql.subzero_or_one", SQLSTATE(M0M29) "zero_or_one: cardinality violation, scalar expression expected");
     116           0 :         BBPretain(*ret = *bid);
     117           0 :         return MAL_SUCCEED;
     118             : }
     119             : 
     120             : #define SQLall_imp(TPE) \
     121             :         do {            \
     122             :                 TPE val = TPE##_nil;    \
     123             :                 if (c > 0) { \
     124             :                         TPE *restrict bp = (TPE*)bi.base; \
     125             :                         if (c == 1 || (bi.sorted && bi.revsorted)) { \
     126             :                                 val = bp[0]; \
     127             :                         } else { \
     128             :                                 for (; q < c; q++) { /* find first non nil */ \
     129             :                                         val = bp[q]; \
     130             :                                         if (!is_##TPE##_nil(val)) \
     131             :                                                 break; \
     132             :                                 } \
     133             :                                 for (; q < c; q++) { \
     134             :                                         TPE pp = bp[q]; \
     135             :                                         if (val != pp && !is_##TPE##_nil(pp)) { /* values != and not nil */ \
     136             :                                                 val = TPE##_nil; \
     137             :                                                 break; \
     138             :                                         } \
     139             :                                 } \
     140             :                         } \
     141             :                 } \
     142             :                 *(TPE *) ret = val; \
     143             :         } while (0)
     144             : 
     145             : str
     146          34 : SQLall(ptr ret, const bat *bid)
     147             : {
     148          34 :         BAT *b;
     149          34 :         BUN c, q = 0;
     150             : 
     151          34 :         if ((b = BATdescriptor(*bid)) == NULL)
     152           0 :                 throw(SQL, "sql.all", SQLSTATE(HY005) "Cannot access column descriptor");
     153             : 
     154          34 :         c = BATcount(b);
     155          34 :         if (b->ttype == TYPE_void) {
     156           0 :                 oid p = oid_nil;
     157           0 :                 memcpy(ret, &p, sizeof(oid));
     158             :         } else {
     159          34 :                 BATiter bi = bat_iterator(b);
     160          57 :                 switch (ATOMbasetype(bi.type)) {
     161          13 :                 case TYPE_bte:
     162          13 :                         SQLall_imp(bte);
     163          13 :                         break;
     164           1 :                 case TYPE_sht:
     165           4 :                         SQLall_imp(sht);
     166           1 :                         break;
     167           5 :                 case TYPE_int:
     168          10 :                         SQLall_imp(int);
     169           5 :                         break;
     170           9 :                 case TYPE_lng:
     171           9 :                         SQLall_imp(lng);
     172           9 :                         break;
     173             : #ifdef HAVE_HGE
     174           0 :                 case TYPE_hge:
     175           0 :                         SQLall_imp(hge);
     176           0 :                         break;
     177             : #endif
     178           0 :                 case TYPE_flt:
     179           0 :                         SQLall_imp(flt);
     180           0 :                         break;
     181           0 :                 case TYPE_dbl:
     182           0 :                         SQLall_imp(dbl);
     183           0 :                         break;
     184           6 :                 default: {
     185           6 :                         int (*ocmp) (const void *, const void *) = ATOMcompare(bi.type);
     186           6 :                         const void *n = ATOMnilptr(bi.type), *p = n;
     187           6 :                         size_t s;
     188             : 
     189           6 :                         if (c > 0) {
     190           6 :                                 if (c == 1 || (bi.sorted && bi.revsorted)) {
     191           5 :                                         p = BUNtail(bi, 0);
     192             :                                 } else {
     193           1 :                                         for (; q < c; q++) { /* find first non nil */
     194           1 :                                                 p = BUNtail(bi, q);
     195           1 :                                                 if (ocmp(n, p) != 0)
     196             :                                                         break;
     197             :                                         }
     198           2 :                                         for (; q < c; q++) {
     199           2 :                                                 const void *pp = BUNtail(bi, q);
     200           2 :                                                 if (ocmp(p, pp) != 0 && ocmp(n, pp) != 0) { /* values != and not nil */
     201             :                                                         p = n;
     202             :                                                         break;
     203             :                                                 }
     204             :                                         }
     205             :                                 }
     206             :                         }
     207          12 :                         s = ATOMlen(ATOMtype(bi.type), p);
     208           6 :                         if (ATOMextern(bi.type)) {
     209           5 :                                 *(ptr *) ret = GDKmalloc(s);
     210           5 :                                 if (*(ptr *) ret == NULL) {
     211           0 :                                         bat_iterator_end(&bi);
     212           0 :                                         BBPunfix(b->batCacheid);
     213           0 :                                         throw(SQL, "sql.all", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     214             :                                 }
     215           5 :                                 memcpy(*(ptr *)ret, p, s);
     216             :                         } else
     217           1 :                                 memcpy(ret, p, s);
     218             :                 }
     219             :                 }
     220          34 :                 bat_iterator_end(&bi);
     221             :         }
     222          34 :         BBPunfix(b->batCacheid);
     223          34 :         return MAL_SUCCEED;
     224             : }
     225             : 
     226             : str
     227          38 : SQLall_grp(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     228             : {
     229          38 :         bat *ret = getArgReference_bat(stk, pci, 0);
     230          38 :         bat *lp = getArgReference_bat(stk, pci, 1);
     231          38 :         bat *gp = getArgReference_bat(stk, pci, 2);
     232          38 :         bat *gpe = getArgReference_bat(stk, pci, 3);
     233          38 :         bat *sp = pci->argc == 6 ? getArgReference_bat(stk, pci, 4) : NULL;
     234             :         //bit *no_nil = getArgReference_bit(stk, pci, pci->argc == 6 ? 5 : 4); no_nil argument is ignored
     235          38 :         BAT *l = NULL, *g = NULL, *e = NULL, *s = NULL, *res = NULL;
     236             : 
     237          38 :         (void)cntxt;
     238          38 :         (void)mb;
     239          38 :         l = BATdescriptor(*lp);
     240          38 :         g = BATdescriptor(*gp);
     241          38 :         e = BATdescriptor(*gpe);
     242          38 :         if (sp)
     243           0 :                 s = BATdescriptor(*sp);
     244             : 
     245          38 :         if (!l || !g || !e || (sp && !s)) {
     246           0 :                 BBPreclaim(l);
     247           0 :                 BBPreclaim(g);
     248           0 :                 BBPreclaim(e);
     249           0 :                 BBPreclaim(s);
     250           0 :                 throw(MAL, "sql.all =", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     251             :         }
     252             : 
     253          38 :         res = BATall_grp(l, g, e, s);
     254             : 
     255          38 :         BBPunfix(l->batCacheid);
     256          38 :         BBPunfix(g->batCacheid);
     257          38 :         BBPunfix(e->batCacheid);
     258          38 :         BBPreclaim(s);
     259          38 :         if (res == NULL)
     260           0 :                 throw(MAL, "sql.all =", GDK_EXCEPTION);
     261          38 :         *ret = res->batCacheid;
     262          38 :         BBPkeepref(res);
     263          38 :         return MAL_SUCCEED;
     264             : }
     265             : 
     266             : #define SQLnil_imp(TPE) \
     267             :         do {            \
     268             :                 TPE *restrict bp = (TPE*)bi.base;       \
     269             :                 for (BUN q = 0; q < o; q++) {        \
     270             :                         if (is_##TPE##_nil(bp[q])) { \
     271             :                                 *ret = TRUE; \
     272             :                                 break; \
     273             :                         } \
     274             :                 } \
     275             :         } while (0)
     276             : 
     277             : str
     278          93 : SQLnil(bit *ret, const bat *bid)
     279             : {
     280          93 :         BAT *b;
     281             : 
     282          93 :         if ((b = BATdescriptor(*bid)) == NULL) {
     283           0 :                 throw(SQL, "sql.nil", SQLSTATE(HY005) "Cannot access column descriptor");
     284             :         }
     285          93 :         *ret = FALSE;
     286          93 :         if (BATcount(b) == 0)
     287          18 :                 *ret = bit_nil;
     288          93 :         if (BATcount(b) > 0) {
     289          75 :                 BUN o = BATcount(b);
     290             : 
     291          75 :                 BATiter bi = bat_iterator(b);
     292         144 :                 switch (ATOMbasetype(bi.type)) {
     293          19 :                 case TYPE_bte:
     294          49 :                         SQLnil_imp(bte);
     295             :                         break;
     296           1 :                 case TYPE_sht:
     297           2 :                         SQLnil_imp(sht);
     298             :                         break;
     299          41 :                 case TYPE_int:
     300        3215 :                         SQLnil_imp(int);
     301             :                         break;
     302           6 :                 case TYPE_lng:
     303          11 :                         SQLnil_imp(lng);
     304             :                         break;
     305             : #ifdef HAVE_HGE
     306           2 :                 case TYPE_hge:
     307           4 :                         SQLnil_imp(hge);
     308             :                         break;
     309             : #endif
     310           0 :                 case TYPE_flt:
     311           0 :                         SQLnil_imp(flt);
     312             :                         break;
     313           0 :                 case TYPE_dbl:
     314           0 :                         SQLnil_imp(dbl);
     315             :                         break;
     316           6 :                 default: {
     317           6 :                         int (*ocmp) (const void *, const void *) = ATOMcompare(bi.type);
     318           6 :                         const void *restrict nilp = ATOMnilptr(bi.type);
     319             : 
     320          13 :                         for (BUN q = 0; q < o; q++) {
     321           8 :                                 const void *restrict c = BUNtail(bi, q);
     322           8 :                                 if (ocmp(nilp, c) == 0) {
     323           1 :                                         *ret = TRUE;
     324           1 :                                         break;
     325             :                                 }
     326             :                         }
     327             :                 }
     328             :                 }
     329          75 :                 bat_iterator_end(&bi);
     330             :         }
     331          93 :         BBPunfix(b->batCacheid);
     332          93 :         return MAL_SUCCEED;
     333             : }
     334             : 
     335             : str
     336          74 : SQLnil_grp(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     337             : {
     338          74 :         bat *ret = getArgReference_bat(stk, pci, 0);
     339          74 :         bat *lp = getArgReference_bat(stk, pci, 1);
     340          74 :         bat *gp = getArgReference_bat(stk, pci, 2);
     341          74 :         bat *gpe = getArgReference_bat(stk, pci, 3);
     342          74 :         bat *sp = pci->argc == 6 ? getArgReference_bat(stk, pci, 4) : NULL;
     343             :         //bit *no_nil = getArgReference_bit(stk, pci, pci->argc == 6 ? 5 : 4); no_nil argument is ignored
     344          74 :         BAT *l = NULL, *g = NULL, *e = NULL, *s = NULL, *res = NULL;
     345             : 
     346          74 :         (void)cntxt;
     347          74 :         (void)mb;
     348          74 :         l = BATdescriptor(*lp);
     349          74 :         g = BATdescriptor(*gp);
     350          74 :         e = BATdescriptor(*gpe);
     351          74 :         if (sp)
     352           0 :                 s = BATdescriptor(*sp);
     353             : 
     354          74 :         if (!l || !g || !e || (sp && !s)) {
     355           0 :                 BBPreclaim(l);
     356           0 :                 BBPreclaim(g);
     357           0 :                 BBPreclaim(e);
     358           0 :                 BBPreclaim(s);
     359           0 :                 throw(MAL, "sql.nil", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     360             :         }
     361             : 
     362          74 :         res = BATnil_grp(l, g, e, s);
     363             : 
     364          74 :         BBPunfix(l->batCacheid);
     365          74 :         BBPunfix(g->batCacheid);
     366          74 :         BBPunfix(e->batCacheid);
     367          74 :         BBPreclaim(s);
     368          74 :         if (res == NULL)
     369           0 :                 throw(MAL, "sql.nil", GDK_EXCEPTION);
     370          74 :         *ret = res->batCacheid;
     371          74 :         BBPkeepref(res);
     372          74 :         return MAL_SUCCEED;
     373             : }
     374             : 
     375             : static inline bit
     376         184 : any_cmp(const bit cmp, const bit nl, const bit nr)
     377             : {
     378         184 :         if (nr == bit_nil) /* empty -> FALSE */
     379             :                 return FALSE;
     380         155 :         else if (cmp == TRUE)
     381             :                 return TRUE;
     382          90 :         else if (nl == TRUE || nr == TRUE)
     383             :                 return bit_nil;
     384             :         return FALSE;
     385             : }
     386             : 
     387             : #define ANY_ALL_CMP_BULK(FUNC, CMP, NL, NR) \
     388             :         do { \
     389             :                 for (BUN i = 0 ; i < q ; i++) { \
     390             :                         res_l[i] = FUNC(CMP, NL, NR); \
     391             :                         has_nil |= is_bit_nil(res_l[i]); \
     392             :                 } \
     393             :         } while (0);
     394             : 
     395             : str
     396          47 : SQLany_cmp(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     397             : {
     398          47 :         bat *ret = isaBatType(getArgType(mb, pci, 0)) ? getArgReference_bat(stk, pci, 0) : NULL;
     399          47 :         bat *cid = isaBatType(getArgType(mb, pci, 1)) ? getArgReference_bat(stk, pci, 1) : NULL;
     400          47 :         bat *nlid = isaBatType(getArgType(mb, pci, 2)) ? getArgReference_bat(stk, pci, 2) : NULL;
     401          47 :         bat *nrid = isaBatType(getArgType(mb, pci, 3)) ? getArgReference_bat(stk, pci, 3) : NULL;
     402          47 :         BAT *cmp = NULL, *nl = NULL, *nr = NULL, *res = NULL;
     403          47 :         str msg = MAL_SUCCEED;
     404          47 :         BUN q = 0;
     405          47 :         bit *restrict res_l = NULL, *cmp_l = NULL, *nl_l = NULL, *nr_l = NULL, cmp_at = FALSE, nl_at = FALSE, nr_at = FALSE, has_nil = 0;
     406          47 :         BATiter cmpi, nli, nri;
     407             : 
     408          47 :         (void) cntxt;
     409          47 :         if (cid && (cmp = BATdescriptor(*cid)) == NULL) {
     410           0 :                 msg = createException(SQL, "sql.any_cmp", SQLSTATE(HY005) "Cannot access column descriptor");
     411           0 :                 goto bailout;
     412             :         }
     413          47 :         if (nlid && (nl = BATdescriptor(*nlid)) == NULL) {
     414           0 :                 msg = createException(SQL, "sql.any_cmp", SQLSTATE(HY005) "Cannot access column descriptor");
     415           0 :                 goto bailout;
     416             :         }
     417          47 :         if (nrid && (nr = BATdescriptor(*nrid)) == NULL) {
     418           0 :                 msg = createException(SQL, "sql.any_cmp", SQLSTATE(HY005) "Cannot access column descriptor");
     419           0 :                 goto bailout;
     420             :         }
     421          47 :         cmpi = bat_iterator(cmp);
     422          47 :         nli = bat_iterator(nl);
     423          47 :         nri = bat_iterator(nr);
     424          47 :         if (cmp)
     425          47 :                 cmp_l = (bit *) cmpi.base;
     426             :         else
     427           0 :                 cmp_at = *getArgReference_bit(stk, pci, 1);
     428          47 :         if (nl)
     429          32 :                 nl_l = (bit *) nli.base;
     430             :         else
     431          15 :                 nl_at = *getArgReference_bit(stk, pci, 2);
     432          47 :         if (nr)
     433          47 :                 nr_l = (bit *) nri.base;
     434             :         else
     435           0 :                 nr_at = *getArgReference_bit(stk, pci, 3);
     436             : 
     437          47 :         if (cmp || nl || nr) {
     438          47 :                 q = cmp ? cmpi.count : nl ? nli.count : nri.count;
     439          47 :                 if (!(res = COLnew(cmp ? cmp->hseqbase : nl ? nl->hseqbase : nr->hseqbase, TYPE_bit, q, TRANSIENT))) {
     440           0 :                         msg = createException(SQL, "sql.any_cmp", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     441           0 :                         goto bailout1;
     442             :                 }
     443          47 :                 res_l = (bit *) Tloc(res, 0);
     444             :         }
     445             : 
     446          47 :         if (!cmp && !nl && !nr) {
     447           0 :                 bit *b = getArgReference_bit(stk, pci, 0);
     448           0 :                 *b = any_cmp(cmp_at, nl_at, nr_at);
     449          47 :         } else if (cmp && !nl && !nr) {
     450           0 :                 ANY_ALL_CMP_BULK(any_cmp, cmp_l[i], nl_at, nr_at);
     451          47 :         } else if (!cmp && nl && !nr) {
     452           0 :                 ANY_ALL_CMP_BULK(any_cmp, cmp_at, nl_l[i], nr_at);
     453          47 :         } else if (!cmp && !nl && nr) {
     454           0 :                 ANY_ALL_CMP_BULK(any_cmp, cmp_at, nl_at, nr_l[i]);
     455          47 :         } else if (!cmp && nl && nr) {
     456           0 :                 ANY_ALL_CMP_BULK(any_cmp, cmp_at, nl_l[i], nr_l[i]);
     457          47 :         } else if (cmp && !nl && nr) {
     458          35 :                 ANY_ALL_CMP_BULK(any_cmp, cmp_l[i], nl_at, nr_l[i]);
     459          32 :         } else if (cmp && nl && !nr) {
     460           0 :                 ANY_ALL_CMP_BULK(any_cmp, cmp_l[i], nl_l[i], nr_at);
     461             :         } else {
     462         196 :                 ANY_ALL_CMP_BULK(any_cmp, cmp_l[i], nl_l[i], nr_l[i]);
     463             :         }
     464             : 
     465          47 :         if (res) {
     466          47 :                 BATsetcount(res, q);
     467          47 :                 res->tkey = BATcount(res) <= 1;
     468          47 :                 res->tsorted = BATcount(res) <= 1;
     469          47 :                 res->trevsorted = BATcount(res) <= 1;
     470          47 :                 res->tnil = has_nil;
     471          47 :                 res->tnonil = !has_nil;
     472             :         }
     473           0 : bailout1:
     474          47 :         bat_iterator_end(&cmpi);
     475          47 :         bat_iterator_end(&nli);
     476          47 :         bat_iterator_end(&nri);
     477             : 
     478          47 : bailout:
     479          47 :         if (res && !msg) {
     480          47 :                 *ret = res->batCacheid;
     481          47 :                 BBPkeepref(res);
     482           0 :         } else if (res)
     483           0 :                 BBPreclaim(res);
     484          47 :         BBPreclaim(cmp);
     485          47 :         BBPreclaim(nl);
     486          47 :         BBPreclaim(nr);
     487          47 :         return msg;
     488             : }
     489             : 
     490             : static inline bit
     491         802 : all_cmp(const bit cmp, const bit nl, const bit nr)
     492             : {
     493         802 :         if (nr == bit_nil) /* empty -> TRUE */
     494             :                 return TRUE;
     495         481 :         else if (cmp == FALSE || (cmp == bit_nil && !nl && !nr))
     496             :                 return FALSE;
     497         182 :         else if (nl == TRUE || nr == TRUE)
     498             :                 return bit_nil;
     499             :         else
     500          75 :                 return cmp;
     501             :         return TRUE;
     502             : }
     503             : 
     504             : str
     505         116 : SQLall_cmp(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     506             : {
     507         116 :         bat *ret = isaBatType(getArgType(mb, pci, 0)) ? getArgReference_bat(stk, pci, 0) : NULL;
     508         116 :         bat *cid = isaBatType(getArgType(mb, pci, 1)) ? getArgReference_bat(stk, pci, 1) : NULL;
     509         116 :         bat *nlid = isaBatType(getArgType(mb, pci, 2)) ? getArgReference_bat(stk, pci, 2) : NULL;
     510         116 :         bat *nrid = isaBatType(getArgType(mb, pci, 3)) ? getArgReference_bat(stk, pci, 3) : NULL;
     511         116 :         BAT *cmp = NULL, *nl = NULL, *nr = NULL, *res = NULL;
     512         116 :         str msg = MAL_SUCCEED;
     513         116 :         BUN q = 0;
     514         116 :         bit *restrict res_l = NULL, *cmp_l = NULL, *nl_l = NULL, *nr_l = NULL, cmp_at = FALSE, nl_at = FALSE, nr_at = FALSE, has_nil = 0;
     515         116 :         BATiter cmpi, nli, nri;
     516             : 
     517         116 :         (void) cntxt;
     518         116 :         if (cid && (cmp = BATdescriptor(*cid)) == NULL) {
     519           0 :                 msg = createException(SQL, "sql.all_cmp", SQLSTATE(HY005) "Cannot access column descriptor");
     520           0 :                 goto bailout;
     521             :         }
     522         116 :         if (nlid && (nl = BATdescriptor(*nlid)) == NULL) {
     523           0 :                 msg = createException(SQL, "sql.all_cmp", SQLSTATE(HY005) "Cannot access column descriptor");
     524           0 :                 goto bailout;
     525             :         }
     526         116 :         if (nrid && (nr = BATdescriptor(*nrid)) == NULL) {
     527           0 :                 msg = createException(SQL, "sql.all_cmp", SQLSTATE(HY005) "Cannot access column descriptor");
     528           0 :                 goto bailout;
     529             :         }
     530         116 :         cmpi = bat_iterator(cmp);
     531         116 :         nli = bat_iterator(nl);
     532         116 :         nri = bat_iterator(nr);
     533         116 :         if (cmp)
     534         116 :                 cmp_l = (bit *) cmpi.base;
     535             :         else
     536           0 :                 cmp_at = *getArgReference_bit(stk, pci, 1);
     537         116 :         if (nl)
     538          79 :                 nl_l = (bit *) nli.base;
     539             :         else
     540          37 :                 nl_at = *getArgReference_bit(stk, pci, 2);
     541         116 :         if (nr)
     542         116 :                 nr_l = (bit *) nri.base;
     543             :         else
     544           0 :                 nr_at = *getArgReference_bit(stk, pci, 3);
     545             : 
     546         116 :         if (cmp || nl || nr) {
     547         116 :                 q = cmp ? cmpi.count : nl ? nli.count : nri.count;
     548         116 :                 if (!(res = COLnew(cmp ? cmp->hseqbase : nl ? nl->hseqbase : nr->hseqbase, TYPE_bit, q, TRANSIENT))) {
     549           0 :                         msg = createException(SQL, "sql.all_cmp", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     550           0 :                         goto bailout1;
     551             :                 }
     552         116 :                 res_l = (bit *) Tloc(res, 0);
     553             :         }
     554             : 
     555         116 :         if (!cmp && !nl && !nr) {
     556           0 :                 bit *b = getArgReference_bit(stk, pci, 0);
     557           0 :                 *b = all_cmp(cmp_at, nl_at, nr_at);
     558         116 :         } else if (cmp && !nl && !nr) {
     559           0 :                 ANY_ALL_CMP_BULK(all_cmp, cmp_l[i], nl_at, nr_at);
     560         116 :         } else if (!cmp && nl && !nr) {
     561           0 :                 ANY_ALL_CMP_BULK(all_cmp, cmp_at, nl_l[i], nr_at);
     562         116 :         } else if (!cmp && !nl && nr) {
     563           0 :                 ANY_ALL_CMP_BULK(all_cmp, cmp_at, nl_at, nr_l[i]);
     564         116 :         } else if (!cmp && nl && nr) {
     565           0 :                 ANY_ALL_CMP_BULK(all_cmp, cmp_at, nl_l[i], nr_l[i]);
     566         116 :         } else if (cmp && !nl && nr) {
     567          88 :                 ANY_ALL_CMP_BULK(all_cmp, cmp_l[i], nl_at, nr_l[i]);
     568          79 :         } else if (cmp && nl && !nr) {
     569           0 :                 ANY_ALL_CMP_BULK(all_cmp, cmp_l[i], nl_l[i], nr_at);
     570             :         } else {
     571         830 :                 ANY_ALL_CMP_BULK(all_cmp, cmp_l[i], nl_l[i], nr_l[i]);
     572             :         }
     573             : 
     574         116 :         if (res) {
     575         116 :                 BATsetcount(res, q);
     576         116 :                 res->tkey = BATcount(res) <= 1;
     577         116 :                 res->tsorted = BATcount(res) <= 1;
     578         116 :                 res->trevsorted = BATcount(res) <= 1;
     579         116 :                 res->tnil = has_nil;
     580         116 :                 res->tnonil = !has_nil;
     581             :         }
     582           0 : bailout1:
     583         116 :         bat_iterator_end(&cmpi);
     584         116 :         bat_iterator_end(&nli);
     585         116 :         bat_iterator_end(&nri);
     586             : 
     587         116 : bailout:
     588         116 :         if (res && !msg) {
     589         116 :                 *ret = res->batCacheid;
     590         116 :                 BBPkeepref(res);
     591           0 :         } else if (res)
     592           0 :                 BBPreclaim(res);
     593         116 :         BBPreclaim(cmp);
     594         116 :         BBPreclaim(nl);
     595         116 :         BBPreclaim(nr);
     596         116 :         return msg;
     597             : }
     598             : 
     599             : #define SQLanyequal_or_not_imp_single(TPE, OUTPUT) \
     600             :         do {                                                    \
     601             :                 TPE *rp = (TPE*)ri.base, *lp = (TPE*)li.base, p = lp[0];        \
     602             :                 for (BUN q = 0; q < o; q++) {        \
     603             :                         TPE c = rp[q]; \
     604             :                         if (is_##TPE##_nil(c)) { \
     605             :                                 *ret = bit_nil; \
     606             :                         } else if (p == c) { \
     607             :                                 *ret = OUTPUT; \
     608             :                                 break; \
     609             :                         } \
     610             :                 } \
     611             :         } while (0)
     612             : 
     613             : #define SQLanyequal_or_not_imp_multi(TPE, CMP) \
     614             :         do {                                                    \
     615             :                 TPE *rp = (TPE*)ri.base, *lp = (TPE*)li.base;   \
     616             :                 for (BUN q = 0; q < o; q++) {        \
     617             :                         TPE c = rp[q], d = lp[q]; \
     618             :                         res_l[q] = (is_##TPE##_nil(c) || is_##TPE##_nil(d)) ? bit_nil : c CMP d; \
     619             :                 } \
     620             :         } while (0)
     621             : 
     622             : str
     623          18 : SQLanyequal(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     624             : {
     625          18 :         bat *bret = isaBatType(getArgType(mb, pci, 0)) ? getArgReference_bat(stk, pci, 0) : NULL;
     626          18 :         bat *bid1 = getArgReference_bat(stk, pci, 1);
     627          18 :         bat *bid2 = getArgReference_bat(stk, pci, 2);
     628          18 :         BAT *res = NULL, *l = NULL, *r = NULL;
     629          18 :         str msg = MAL_SUCCEED;
     630          18 :         BUN o = 0;
     631          18 :         BATiter li, ri;
     632             : 
     633          18 :         (void) cntxt;
     634          18 :         if ((l = BATdescriptor(*bid1)) == NULL) {
     635           0 :                 msg = createException(SQL, "sql.any =", SQLSTATE(HY005) "Cannot access column descriptor");
     636           0 :                 goto bailout;
     637             :         }
     638          18 :         if ((r = BATdescriptor(*bid2)) == NULL) {
     639           0 :                 msg = createException(SQL, "sql.any =", SQLSTATE(HY005) "Cannot access column descriptor");
     640           0 :                 goto bailout;
     641             :         }
     642          18 :         if (l->ttype != r->ttype) {
     643           0 :                 msg = createException(SQL, "sql.any =", SQLSTATE(42000) "sql.any = requires both arguments of the same type");
     644           0 :                 goto bailout;
     645             :         }
     646             : 
     647          18 :         o = BATcount(r);
     648          18 :         ri = bat_iterator(r);
     649          18 :         li = bat_iterator(l);
     650          18 :         if (bret) {
     651           0 :                 if (!(res = COLnew(r->hseqbase, TYPE_bit, o, TRANSIENT))) {
     652           0 :                         msg = createException(SQL, "sql.any =", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     653           0 :                         goto bailout1;
     654             :                 }
     655           0 :                 bit *restrict res_l = (bit*) Tloc(res, 0);
     656             : 
     657           0 :                 switch (ATOMbasetype(li.type)) {
     658           0 :                 case TYPE_bte:
     659           0 :                         SQLanyequal_or_not_imp_multi(bte, ==);
     660             :                         break;
     661           0 :                 case TYPE_sht:
     662           0 :                         SQLanyequal_or_not_imp_multi(sht, ==);
     663             :                         break;
     664           0 :                 case TYPE_int:
     665           0 :                         SQLanyequal_or_not_imp_multi(int, ==);
     666             :                         break;
     667           0 :                 case TYPE_lng:
     668           0 :                         SQLanyequal_or_not_imp_multi(lng, ==);
     669             :                         break;
     670             : #ifdef HAVE_HGE
     671           0 :                 case TYPE_hge:
     672           0 :                         SQLanyequal_or_not_imp_multi(hge, ==);
     673             :                         break;
     674             : #endif
     675           0 :                 case TYPE_flt:
     676           0 :                         SQLanyequal_or_not_imp_multi(flt, ==);
     677             :                         break;
     678           0 :                 case TYPE_dbl:
     679           0 :                         SQLanyequal_or_not_imp_multi(dbl, ==);
     680             :                         break;
     681           0 :                 default: {
     682           0 :                         int (*ocmp) (const void *, const void *) = ATOMcompare(li.type);
     683           0 :                         const void *nilp = ATOMnilptr(li.type);
     684             : 
     685           0 :                         for (BUN q = 0; q < o; q++) {
     686           0 :                                 const void *c = BUNtail(ri, q), *d = BUNtail(li, q);
     687           0 :                                 res_l[q] = ocmp(nilp, c) == 0 || ocmp(nilp, d) == 0 ? bit_nil : ocmp(c, d) == 0;
     688             :                         }
     689             :                 }
     690             :                 }
     691             : 
     692           0 :                 BATsetcount(res, o);
     693           0 :                 res->tkey = BATcount(res) <= 1;
     694           0 :                 res->tsorted = BATcount(res) <= 1;
     695           0 :                 res->trevsorted = BATcount(res) <= 1;
     696           0 :                 res->tnil = li.nil || ri.nil;
     697           0 :                 res->tnonil = li.nonil && ri.nonil;
     698             :         } else {
     699          18 :                 bit *ret = getArgReference_bit(stk, pci, 0);
     700             : 
     701          18 :                 *ret = FALSE;
     702          18 :                 if (o > 0) {
     703          36 :                         switch (ATOMbasetype(li.type)) {
     704           2 :                         case TYPE_bte:
     705           3 :                                 SQLanyequal_or_not_imp_single(bte, TRUE);
     706             :                                 break;
     707           0 :                         case TYPE_sht:
     708           0 :                                 SQLanyequal_or_not_imp_single(sht, TRUE);
     709             :                                 break;
     710           1 :                         case TYPE_int:
     711           1 :                                 SQLanyequal_or_not_imp_single(int, TRUE);
     712             :                                 break;
     713           0 :                         case TYPE_lng:
     714           0 :                                 SQLanyequal_or_not_imp_single(lng, TRUE);
     715             :                                 break;
     716             : #ifdef HAVE_HGE
     717           0 :                         case TYPE_hge:
     718           0 :                                 SQLanyequal_or_not_imp_single(hge, TRUE);
     719             :                                 break;
     720             : #endif
     721           0 :                         case TYPE_flt:
     722           0 :                                 SQLanyequal_or_not_imp_single(flt, TRUE);
     723             :                                 break;
     724           1 :                         case TYPE_dbl:
     725           2 :                                 SQLanyequal_or_not_imp_single(dbl, TRUE);
     726             :                                 break;
     727          14 :                         default: {
     728          14 :                                 int (*ocmp) (const void *, const void *) = ATOMcompare(li.type);
     729          14 :                                 const void *nilp = ATOMnilptr(li.type);
     730          14 :                                 const void *p = BUNtail(li, 0);
     731             : 
     732          40 :                                 for (BUN q = 0; q < o; q++) {
     733          30 :                                         const void *c = BUNtail(ri, q);
     734          30 :                                         if (ocmp(nilp, c) == 0)
     735           0 :                                                 *ret = bit_nil;
     736          30 :                                         else if (ocmp(p, c) == 0) {
     737           4 :                                                 *ret = TRUE;
     738           4 :                                                 break;
     739             :                                         }
     740             :                                 }
     741             :                         }
     742             :                         }
     743             :                 }
     744             :         }
     745          10 : bailout1:
     746          18 :         bat_iterator_end(&li);
     747          18 :         bat_iterator_end(&ri);
     748             : 
     749          18 : bailout:
     750          18 :         if (res && !msg) {
     751           0 :                 *bret = res->batCacheid;
     752           0 :                 BBPkeepref(res);
     753          18 :         } else if (res)
     754           0 :                 BBPreclaim(res);
     755          18 :         BBPreclaim(l);
     756          18 :         BBPreclaim(r);
     757          18 :         return msg;
     758             : }
     759             : 
     760             : str
     761           0 : SQLanyequal_grp(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     762             : {
     763           0 :         bat *ret = getArgReference_bat(stk, pci, 0);
     764           0 :         bat *lp = getArgReference_bat(stk, pci, 1);
     765           0 :         bat *rp = getArgReference_bat(stk, pci, 2);
     766           0 :         bat *gp = getArgReference_bat(stk, pci, 3);
     767           0 :         bat *gpe = getArgReference_bat(stk, pci, 4);
     768           0 :         bat *sp = pci->argc == 7 ? getArgReference_bat(stk, pci, 5) : NULL;
     769             :         //bit *no_nil = getArgReference_bit(stk, pci, pci->argc - 1); no_nil argument is ignored
     770           0 :         BAT *l = NULL, *r = NULL, *g = NULL, *e = NULL, *s = NULL, *res = NULL;
     771             : 
     772           0 :         (void)cntxt;
     773           0 :         (void)mb;
     774           0 :         l = BATdescriptor(*lp);
     775           0 :         r = BATdescriptor(*rp);
     776           0 :         g = BATdescriptor(*gp);
     777           0 :         e = BATdescriptor(*gpe);
     778           0 :         if (sp)
     779           0 :                 s = BATdescriptor(*sp);
     780             : 
     781           0 :         if (!l || !r || !g || !e || (sp && !s)) {
     782           0 :                 BBPreclaim(l);
     783           0 :                 BBPreclaim(r);
     784           0 :                 BBPreclaim(g);
     785           0 :                 BBPreclaim(e);
     786           0 :                 BBPreclaim(s);
     787           0 :                 throw(MAL, "sql.any =", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     788             :         }
     789           0 :         if (l->ttype != r->ttype) {
     790           0 :                 BBPunfix(l->batCacheid);
     791           0 :                 BBPunfix(r->batCacheid);
     792           0 :                 BBPunfix(g->batCacheid);
     793           0 :                 BBPunfix(e->batCacheid);
     794           0 :                 BBPreclaim(s);
     795           0 :                 throw(MAL, "sql.any =", SQLSTATE(42000) "sql.any = requires both arguments of the same type");
     796             :         }
     797             : 
     798           0 :         res = BATanyequal_grp(l, r, g, e, s);
     799             : 
     800           0 :         BBPunfix(l->batCacheid);
     801           0 :         BBPunfix(r->batCacheid);
     802           0 :         BBPunfix(g->batCacheid);
     803           0 :         BBPunfix(e->batCacheid);
     804           0 :         BBPreclaim(s);
     805           0 :         if (res == NULL)
     806           0 :                 throw(MAL, "sql.any =", GDK_EXCEPTION);
     807           0 :         *ret = res->batCacheid;
     808           0 :         BBPkeepref(res);
     809           0 :         return MAL_SUCCEED;
     810             : }
     811             : 
     812             : str
     813           0 : SQLanyequal_grp2(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     814             : {
     815           0 :         bat *ret = getArgReference_bat(stk, pci, 0);
     816           0 :         bat *lp = getArgReference_bat(stk, pci, 1);
     817           0 :         bat *rp = getArgReference_bat(stk, pci, 2);
     818           0 :         bat *ip = getArgReference_bat(stk, pci, 3);
     819           0 :         bat *gp = getArgReference_bat(stk, pci, 4);
     820           0 :         bat *gpe = getArgReference_bat(stk, pci, 5);
     821           0 :         bat *sp = pci->argc == 8 ? getArgReference_bat(stk, pci, 6) : NULL;
     822             :         //bit *no_nil = getArgReference_bit(stk, pci, pci->argc == 8 ? 7 : 6); no_nil argument is ignored
     823           0 :         BAT *l = NULL, *r = NULL, *rid = NULL, *g = NULL, *e = NULL, *s = NULL, *res = NULL;
     824           0 :         (void)cntxt;
     825           0 :         (void)mb;
     826             : 
     827           0 :         l = BATdescriptor(*lp);
     828           0 :         r = BATdescriptor(*rp);
     829           0 :         rid = BATdescriptor(*ip);
     830           0 :         g = BATdescriptor(*gp);
     831           0 :         e = BATdescriptor(*gpe);
     832           0 :         if (sp)
     833           0 :                 s = BATdescriptor(*sp);
     834             : 
     835           0 :         if (!l || !r || !rid || !g || !e || (sp && !s)) {
     836           0 :                 BBPreclaim(l);
     837           0 :                 BBPreclaim(r);
     838           0 :                 BBPreclaim(rid);
     839           0 :                 BBPreclaim(g);
     840           0 :                 BBPreclaim(e);
     841           0 :                 BBPreclaim(s);
     842           0 :                 throw(MAL, "sql.any =", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     843             :         }
     844           0 :         if (l->ttype != r->ttype) {
     845           0 :                 BBPunfix(l->batCacheid);
     846           0 :                 BBPunfix(r->batCacheid);
     847           0 :                 BBPunfix(rid->batCacheid);
     848           0 :                 BBPunfix(g->batCacheid);
     849           0 :                 BBPunfix(e->batCacheid);
     850           0 :                 BBPreclaim(s);
     851           0 :                 throw(MAL, "sql.any =", SQLSTATE(42000) "sql.any = requires both arguments of the same type");
     852             :         }
     853             : 
     854           0 :         res = BATanyequal_grp2(l, r, rid, g, e, s);
     855             : 
     856           0 :         BBPunfix(l->batCacheid);
     857           0 :         BBPunfix(r->batCacheid);
     858           0 :         BBPunfix(rid->batCacheid);
     859           0 :         BBPunfix(g->batCacheid);
     860           0 :         BBPunfix(e->batCacheid);
     861           0 :         BBPreclaim(s);
     862           0 :         if (res == NULL)
     863           0 :                 throw(MAL, "sql.any =", GDK_EXCEPTION);
     864           0 :         *ret = res->batCacheid;
     865           0 :         BBPkeepref(res);
     866           0 :         return MAL_SUCCEED;
     867             : }
     868             : 
     869             : str
     870           5 : SQLallnotequal(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     871             : {
     872           5 :         bat *bret = isaBatType(getArgType(mb, pci, 0)) ? getArgReference_bat(stk, pci, 0) : NULL;
     873           5 :         bat *bid1 = getArgReference_bat(stk, pci, 1);
     874           5 :         bat *bid2 = getArgReference_bat(stk, pci, 2);
     875           5 :         BAT *res = NULL, *l = NULL, *r = NULL;
     876           5 :         str msg = MAL_SUCCEED;
     877           5 :         BUN o = 0;
     878           5 :         BATiter li, ri;
     879             : 
     880           5 :         (void) cntxt;
     881           5 :         if ((l = BATdescriptor(*bid1)) == NULL) {
     882           0 :                 msg = createException(SQL, "sql.all <>", SQLSTATE(HY005) "Cannot access column descriptor");
     883           0 :                 goto bailout;
     884             :         }
     885           5 :         if ((r = BATdescriptor(*bid2)) == NULL) {
     886           0 :                 msg = createException(SQL, "sql.all <>", SQLSTATE(HY005) "Cannot access column descriptor");
     887           0 :                 goto bailout;
     888             :         }
     889           5 :         if (l->ttype != r->ttype) {
     890           0 :                 msg = createException(SQL, "sql.all <>", SQLSTATE(42000) "sql.all <> requires both arguments of the same type");
     891           0 :                 goto bailout;
     892             :         }
     893             : 
     894           5 :         o = BATcount(r);
     895           5 :         ri = bat_iterator(r);
     896           5 :         li = bat_iterator(l);
     897           5 :         if (bret) {
     898           0 :                 if (!(res = COLnew(r->hseqbase, TYPE_bit, o, TRANSIENT))) {
     899           0 :                         msg = createException(SQL, "sql.all <>", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     900           0 :                         goto bailout1;
     901             :                 }
     902           0 :                 bit *restrict res_l = (bit*) Tloc(res, 0);
     903             : 
     904           0 :                 switch (ATOMbasetype(li.type)) {
     905           0 :                 case TYPE_bte:
     906           0 :                         SQLanyequal_or_not_imp_multi(bte, !=);
     907             :                         break;
     908           0 :                 case TYPE_sht:
     909           0 :                         SQLanyequal_or_not_imp_multi(sht, !=);
     910             :                         break;
     911           0 :                 case TYPE_int:
     912           0 :                         SQLanyequal_or_not_imp_multi(int, !=);
     913             :                         break;
     914           0 :                 case TYPE_lng:
     915           0 :                         SQLanyequal_or_not_imp_multi(lng, !=);
     916             :                         break;
     917             : #ifdef HAVE_HGE
     918           0 :                 case TYPE_hge:
     919           0 :                         SQLanyequal_or_not_imp_multi(hge, !=);
     920             :                         break;
     921             : #endif
     922           0 :                 case TYPE_flt:
     923           0 :                         SQLanyequal_or_not_imp_multi(flt, !=);
     924             :                         break;
     925           0 :                 case TYPE_dbl:
     926           0 :                         SQLanyequal_or_not_imp_multi(dbl, !=);
     927             :                         break;
     928           0 :                 default: {
     929           0 :                         int (*ocmp) (const void *, const void *) = ATOMcompare(li.type);
     930           0 :                         const void *nilp = ATOMnilptr(li.type);
     931             : 
     932           0 :                         for (BUN q = 0; q < o; q++) {
     933           0 :                                 const void *c = BUNtail(ri, q), *d = BUNtail(li, q);
     934           0 :                                 res_l[q] = ocmp(nilp, c) == 0 || ocmp(nilp, d) == 0 ? bit_nil : ocmp(c, d) != 0;
     935             :                         }
     936             :                 }
     937             :                 }
     938             : 
     939           0 :                 BATsetcount(res, o);
     940           0 :                 res->tkey = BATcount(res) <= 1;
     941           0 :                 res->tsorted = BATcount(res) <= 1;
     942           0 :                 res->trevsorted = BATcount(res) <= 1;
     943           0 :                 res->tnil = li.nil || ri.nil;
     944           0 :                 res->tnonil = li.nonil && ri.nonil;
     945             :         } else {
     946           5 :                 bit *ret = getArgReference_bit(stk, pci, 0);
     947             : 
     948           5 :                 *ret = TRUE;
     949           5 :                 if (o > 0) {
     950          10 :                         switch (ATOMbasetype(li.type)) {
     951           1 :                         case TYPE_bte:
     952           3 :                                 SQLanyequal_or_not_imp_single(bte, FALSE);
     953             :                                 break;
     954           1 :                         case TYPE_sht:
     955           2 :                                 SQLanyequal_or_not_imp_single(sht, FALSE);
     956             :                                 break;
     957           2 :                         case TYPE_int:
     958           5 :                                 SQLanyequal_or_not_imp_single(int, FALSE);
     959             :                                 break;
     960           0 :                         case TYPE_lng:
     961           0 :                                 SQLanyequal_or_not_imp_single(lng, FALSE);
     962             :                                 break;
     963             : #ifdef HAVE_HGE
     964           0 :                         case TYPE_hge:
     965           0 :                                 SQLanyequal_or_not_imp_single(hge, FALSE);
     966             :                                 break;
     967             : #endif
     968           0 :                         case TYPE_flt:
     969           0 :                                 SQLanyequal_or_not_imp_single(flt, FALSE);
     970             :                                 break;
     971           1 :                         case TYPE_dbl:
     972           2 :                                 SQLanyequal_or_not_imp_single(dbl, FALSE);
     973             :                                 break;
     974           0 :                         default: {
     975           0 :                                 int (*ocmp) (const void *, const void *) = ATOMcompare(li.type);
     976           0 :                                 const void *nilp = ATOMnilptr(li.type);
     977           0 :                                 const void *p = BUNtail(li, 0);
     978             : 
     979           0 :                                 for (BUN q = 0; q < o; q++) {
     980           0 :                                         const void *c = BUNtail(ri, q);
     981           0 :                                         if (ocmp(nilp, c) == 0)
     982           0 :                                                 *ret = bit_nil;
     983           0 :                                         else if (ocmp(p, c) == 0) {
     984           0 :                                                 *ret = FALSE;
     985           0 :                                                 break;
     986             :                                         }
     987             :                                 }
     988             :                         }
     989             :                         }
     990             :                 }
     991             :         }
     992           0 :   bailout1:
     993           5 :         bat_iterator_end(&li);
     994           5 :         bat_iterator_end(&ri);
     995             : 
     996           5 : bailout:
     997           5 :         if (res && !msg) {
     998           0 :                 *bret = res->batCacheid;
     999           0 :                 BBPkeepref(res);
    1000           5 :         } else if (res)
    1001           0 :                 BBPreclaim(res);
    1002           5 :         BBPreclaim(l);
    1003           5 :         BBPreclaim(r);
    1004           5 :         return msg;
    1005             : }
    1006             : 
    1007             : str
    1008           0 : SQLallnotequal_grp(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1009             : {
    1010           0 :         bat *ret = getArgReference_bat(stk, pci, 0);
    1011           0 :         bat *lp = getArgReference_bat(stk, pci, 1);
    1012           0 :         bat *rp = getArgReference_bat(stk, pci, 2);
    1013           0 :         bat *gp = getArgReference_bat(stk, pci, 3);
    1014           0 :         bat *gpe = getArgReference_bat(stk, pci, 4);
    1015           0 :         bat *sp = pci->argc == 7 ? getArgReference_bat(stk, pci, 5) : NULL;
    1016             :         //bit *no_nil = getArgReference_bit(stk, pci, pci->argc == 7 ? 6 : 5); no_nil argument is ignored
    1017           0 :         BAT *l = NULL, *r = NULL, *g = NULL, *e = NULL, *s = NULL, *res = NULL;
    1018             : 
    1019           0 :         (void)cntxt;
    1020           0 :         (void)mb;
    1021           0 :         l = BATdescriptor(*lp);
    1022           0 :         r = BATdescriptor(*rp);
    1023           0 :         g = BATdescriptor(*gp);
    1024           0 :         e = BATdescriptor(*gpe);
    1025           0 :         if (sp)
    1026           0 :                 s = BATdescriptor(*sp);
    1027             : 
    1028           0 :         if (!l || !r || !g || !e || (sp && !s)) {
    1029           0 :                 BBPreclaim(l);
    1030           0 :                 BBPreclaim(r);
    1031           0 :                 BBPreclaim(g);
    1032           0 :                 BBPreclaim(e);
    1033           0 :                 BBPreclaim(s);
    1034           0 :                 throw(MAL, "sql.all <>", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
    1035             :         }
    1036           0 :         if (l->ttype != r->ttype) {
    1037           0 :                 BBPunfix(l->batCacheid);
    1038           0 :                 BBPunfix(r->batCacheid);
    1039           0 :                 BBPunfix(g->batCacheid);
    1040           0 :                 BBPunfix(e->batCacheid);
    1041           0 :                 BBPreclaim(s);
    1042           0 :                 throw(MAL, "sql.all <>", SQLSTATE(42000) "sql.all <> requires both arguments of the same type");
    1043             :         }
    1044             : 
    1045           0 :         res = BATallnotequal_grp(l, r, g, e, s);
    1046             : 
    1047           0 :         BBPunfix(l->batCacheid);
    1048           0 :         BBPunfix(r->batCacheid);
    1049           0 :         BBPunfix(g->batCacheid);
    1050           0 :         BBPunfix(e->batCacheid);
    1051           0 :         BBPreclaim(s);
    1052           0 :         if (res == NULL)
    1053           0 :                 throw(MAL, "sql.all <>", GDK_EXCEPTION);
    1054           0 :         *ret = res->batCacheid;
    1055           0 :         BBPkeepref(res);
    1056           0 :         return MAL_SUCCEED;
    1057             : }
    1058             : 
    1059             : str
    1060           0 : SQLallnotequal_grp2(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1061             : {
    1062           0 :         bat *ret = getArgReference_bat(stk, pci, 0);
    1063           0 :         bat *lp = getArgReference_bat(stk, pci, 1);
    1064           0 :         bat *rp = getArgReference_bat(stk, pci, 2);
    1065           0 :         bat *ip = getArgReference_bat(stk, pci, 3);
    1066           0 :         bat *gp = getArgReference_bat(stk, pci, 4);
    1067           0 :         bat *gpe = getArgReference_bat(stk, pci, 5);
    1068           0 :         bat *sp = pci->argc == 8 ? getArgReference_bat(stk, pci, 6) : NULL;
    1069             :         //bit *no_nil = getArgReference_bit(stk, pci, pci->argc == 8 ? 7 : 6); no_nil argument is ignored
    1070           0 :         BAT *l = NULL, *r = NULL, *rid = NULL, *g = NULL, *e = NULL, *s = NULL, *res = NULL;
    1071             : 
    1072           0 :         (void)cntxt;
    1073           0 :         (void)mb;
    1074             : 
    1075           0 :         l = BATdescriptor(*lp);
    1076           0 :         r = BATdescriptor(*rp);
    1077           0 :         rid = BATdescriptor(*ip);
    1078           0 :         g = BATdescriptor(*gp);
    1079           0 :         e = BATdescriptor(*gpe);
    1080           0 :         if (sp)
    1081           0 :                 s = BATdescriptor(*sp);
    1082             : 
    1083           0 :         if (!l || !r || !rid || !g || !e || (sp && !s)) {
    1084           0 :                 BBPreclaim(l);
    1085           0 :                 BBPreclaim(r);
    1086           0 :                 BBPreclaim(rid);
    1087           0 :                 BBPreclaim(g);
    1088           0 :                 BBPreclaim(e);
    1089           0 :                 BBPreclaim(s);
    1090           0 :                 throw(MAL, "sql.all <>", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
    1091             :         }
    1092           0 :         if (l->ttype != r->ttype) {
    1093           0 :                 BBPunfix(l->batCacheid);
    1094           0 :                 BBPunfix(r->batCacheid);
    1095           0 :                 BBPunfix(rid->batCacheid);
    1096           0 :                 BBPunfix(g->batCacheid);
    1097           0 :                 BBPunfix(e->batCacheid);
    1098           0 :                 BBPreclaim(s);
    1099           0 :                 throw(MAL, "sql.all <>", SQLSTATE(42000) "sql.all <> requires both arguments of the same type");
    1100             :         }
    1101             : 
    1102           0 :         res = BATallnotequal_grp2(l, r, rid, g, e, s);
    1103             : 
    1104           0 :         BBPunfix(l->batCacheid);
    1105           0 :         BBPunfix(r->batCacheid);
    1106           0 :         BBPunfix(rid->batCacheid);
    1107           0 :         BBPunfix(g->batCacheid);
    1108           0 :         BBPunfix(e->batCacheid);
    1109           0 :         BBPreclaim(s);
    1110           0 :         if (res == NULL)
    1111           0 :                 throw(MAL, "sql.all <>", GDK_EXCEPTION);
    1112           0 :         *ret = res->batCacheid;
    1113           0 :         BBPkeepref(res);
    1114           0 :         return MAL_SUCCEED;
    1115             : }
    1116             : 
    1117             : str
    1118           5 : SQLexist(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1119             : {
    1120           5 :         BAT *b = NULL, *r = NULL;
    1121           5 :         bit count = TRUE;
    1122             : 
    1123           5 :         (void)cntxt;
    1124           5 :         if (isaBatType(getArgType(mb, pci, 1))) {
    1125           5 :                 bat *bid = getArgReference_bat(stk, pci, 1);
    1126           5 :                 if (!(b = BBPquickdesc(*bid)))
    1127           0 :                         throw(SQL, "aggr.exist", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
    1128           5 :                 count = BATcount(b) != 0;
    1129             :         }
    1130           5 :         if (isaBatType(getArgType(mb, pci, 0))) {
    1131           0 :                 bat *res = getArgReference_bat(stk, pci, 0);
    1132           0 :                 if (!(r = BATconstant(b ? b->hseqbase : 0, TYPE_bit, &count, b ? BATcount(b) : 1, TRANSIENT)))
    1133           0 :                         throw(SQL, "aggr.exist", SQLSTATE(HY013) MAL_MALLOC_FAIL);
    1134           0 :                 *res = r->batCacheid;
    1135           0 :                 BBPkeepref(r);
    1136             :         } else {
    1137           5 :                 bit *res = getArgReference_bit(stk, pci, 0);
    1138           5 :                 *res = count;
    1139             :         }
    1140             : 
    1141             :         return MAL_SUCCEED;
    1142             : }
    1143             : 
    1144             : str
    1145           0 : SQLsubexist(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1146             : {
    1147           0 :         bat *ret = getArgReference_bat(stk, pci, 0);
    1148           0 :         bat *bp = getArgReference_bat(stk, pci, 1);
    1149           0 :         bat *gp = getArgReference_bat(stk, pci, 2);
    1150           0 :         bat *gpe = getArgReference_bat(stk, pci, 3);
    1151           0 :         bat *sp = pci->argc == 6 ? getArgReference_bat(stk, pci, 4) : NULL;
    1152             :         //bit *no_nil = getArgReference_bit(stk, pci, pci->argc == 6 ? 5 : 4); no_nil argument is ignored
    1153           0 :         BAT *b = NULL, *g = NULL, *e = NULL, *s = NULL, *res = NULL;
    1154             : 
    1155           0 :         (void)cntxt;
    1156           0 :         (void)mb;
    1157           0 :         b = BATdescriptor(*bp);
    1158           0 :         g = BATdescriptor(*gp);
    1159           0 :         e = BATdescriptor(*gpe);
    1160           0 :         if (sp)
    1161           0 :                 s = BATdescriptor(*sp);
    1162             : 
    1163           0 :         if (!b || !g || !e || (sp && !s)) {
    1164           0 :                 BBPreclaim(b);
    1165           0 :                 BBPreclaim(g);
    1166           0 :                 BBPreclaim(e);
    1167           0 :                 BBPreclaim(s);
    1168           0 :                 throw(MAL, "sql.subexist", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
    1169             :         }
    1170             : 
    1171           0 :         res = BATsubexist(b, g, e, s);
    1172             : 
    1173           0 :         BBPunfix(b->batCacheid);
    1174           0 :         BBPunfix(g->batCacheid);
    1175           0 :         BBPunfix(e->batCacheid);
    1176           0 :         BBPreclaim(s);
    1177           0 :         if (res == NULL)
    1178           0 :                 throw(MAL, "sql.subexist", GDK_EXCEPTION);
    1179           0 :         *ret = res->batCacheid;
    1180           0 :         BBPkeepref(res);
    1181           0 :         return MAL_SUCCEED;
    1182             : }
    1183             : 
    1184             : str
    1185           0 : SQLnot_exist(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1186             : {
    1187           0 :         BAT *b = NULL, *r = NULL;
    1188           0 :         bit count = FALSE;
    1189             : 
    1190           0 :         (void)cntxt;
    1191           0 :         if (isaBatType(getArgType(mb, pci, 1))) {
    1192           0 :                 bat *bid = getArgReference_bat(stk, pci, 1);
    1193           0 :                 if (!(b = BBPquickdesc(*bid)))
    1194           0 :                         throw(SQL, "aggr.not_exist", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
    1195           0 :                 count = BATcount(b) == 0;
    1196             :         }
    1197           0 :         if (isaBatType(getArgType(mb, pci, 0))) {
    1198           0 :                 bat *res = getArgReference_bat(stk, pci, 0);
    1199           0 :                 if (!(r = BATconstant(b ? b->hseqbase : 0, TYPE_bit, &count, b ? BATcount(b) : 1, TRANSIENT)))
    1200           0 :                         throw(SQL, "aggr.not_exist", SQLSTATE(HY013) MAL_MALLOC_FAIL);
    1201           0 :                 *res = r->batCacheid;
    1202           0 :                 BBPkeepref(r);
    1203             :         } else {
    1204           0 :                 bit *res = getArgReference_bit(stk, pci, 0);
    1205           0 :                 *res = count;
    1206             :         }
    1207             : 
    1208             :         return MAL_SUCCEED;
    1209             : }
    1210             : 
    1211             : str
    1212           0 : SQLsubnot_exist(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1213             : {
    1214           0 :         bat *ret = getArgReference_bat(stk, pci, 0);
    1215           0 :         bat *bp = getArgReference_bat(stk, pci, 1);
    1216           0 :         bat *gp = getArgReference_bat(stk, pci, 2);
    1217           0 :         bat *gpe = getArgReference_bat(stk, pci, 3);
    1218           0 :         bat *sp = pci->argc == 6 ? getArgReference_bat(stk, pci, 4) : NULL;
    1219             :         //bit *no_nil = getArgReference_bit(stk, pci, pci->argc == 6 ? 5 : 4); no_nil argument is ignored
    1220           0 :         BAT *b = NULL, *g = NULL, *e = NULL, *s = NULL, *res = NULL;
    1221             : 
    1222           0 :         (void)cntxt;
    1223           0 :         (void)mb;
    1224           0 :         b = BATdescriptor(*bp);
    1225           0 :         g = BATdescriptor(*gp);
    1226           0 :         e = BATdescriptor(*gpe);
    1227           0 :         if (sp)
    1228           0 :                 s = BATdescriptor(*sp);
    1229             : 
    1230           0 :         if (!b || !g || !e || (sp && !s)) {
    1231           0 :                 BBPreclaim(b);
    1232           0 :                 BBPreclaim(g);
    1233           0 :                 BBPreclaim(e);
    1234           0 :                 BBPreclaim(s);
    1235           0 :                 throw(MAL, "sql.subnot_exist", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
    1236             :         }
    1237             : 
    1238           0 :         res = BATsubnot_exist(b, g, e, s);
    1239             : 
    1240           0 :         BBPunfix(b->batCacheid);
    1241           0 :         BBPunfix(g->batCacheid);
    1242           0 :         BBPunfix(e->batCacheid);
    1243           0 :         BBPreclaim(s);
    1244           0 :         if (res == NULL)
    1245           0 :                 throw(MAL, "sql.subnot_exist", GDK_EXCEPTION);
    1246           0 :         *ret = res->batCacheid;
    1247           0 :         BBPkeepref(res);
    1248           0 :         return MAL_SUCCEED;
    1249             : }

Generated by: LCOV version 1.14