LCOV - code coverage report
Current view: top level - sql/backends/monet5 - sql_subquery.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 346 832 41.6 %
Date: 2024-10-07 21:21:43 Functions: 11 21 52.4 %

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

Generated by: LCOV version 1.14