LCOV - code coverage report
Current view: top level - gdk - gdk_subquery.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 242 489 49.5 %
Date: 2021-09-14 19:48:19 Functions: 6 8 75.0 %

          Line data    Source code
       1             : /*
       2             :  * This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       5             :  *
       6             :  * Copyright 1997 - July 2008 CWI, August 2008 - 2021 MonetDB B.V.
       7             :  */
       8             : 
       9             : #include "monetdb_config.h"
      10             : #include "gdk.h"
      11             : #include "gdk_subquery.h"
      12             : #include "gdk_private.h"
      13             : #include "gdk_calc_private.h"
      14             : 
      15             : #define SQLall_grp_imp(TYPE)                                            \
      16             :         do {                                                            \
      17             :                 const TYPE *restrict vals = (const TYPE *) li.base;     \
      18             :                 TYPE *restrict rp = (TYPE *) Tloc(res, 0);              \
      19             :                 while (ncand > 0) {                                  \
      20             :                         ncand--;                                        \
      21             :                         i = canditer_next(&ci) - l->hseqbase;            \
      22             :                         if (gids == NULL ||                             \
      23             :                             (gids[i] >= min && gids[i] <= max)) { \
      24             :                                 if (gids)                               \
      25             :                                         gid = gids[i] - min;            \
      26             :                                 else                                    \
      27             :                                         gid = (oid) i;                  \
      28             :                                 if (oids[gid] != (BUN_NONE - 1)) {      \
      29             :                                         if (oids[gid] == BUN_NONE) {    \
      30             :                                                 if (!is_##TYPE##_nil(vals[i])) \
      31             :                                                         oids[gid] = i;  \
      32             :                                         } else {                        \
      33             :                                                 if (vals[oids[gid]] != vals[i] && !is_##TYPE##_nil(vals[i])) \
      34             :                                                         oids[gid] = BUN_NONE - 1; \
      35             :                                         }                               \
      36             :                                 }                                       \
      37             :                         }                                               \
      38             :                 }                                                       \
      39             :                 for (i = 0; i < ngrp; i++) { /* convert the found oids in values */ \
      40             :                         BUN noid = oids[i];                             \
      41             :                         if (noid >= (BUN_NONE - 1)) {                        \
      42             :                                 rp[i] = TYPE##_nil;                     \
      43             :                                 hasnil = 1;                             \
      44             :                         } else {                                        \
      45             :                                 rp[i] = vals[noid];                     \
      46             :                         }                                               \
      47             :                 }                                                       \
      48             :         } while (0)
      49             : 
      50             : BAT *
      51          37 : BATall_grp(BAT *l, BAT *g, BAT *e, BAT *s)
      52             : {
      53             :         BAT *res = NULL;
      54             :         const oid *restrict gids;
      55             :         oid gid, min, max, *restrict oids = NULL; /* The oids variable controls if we have found a nil in the group so far */
      56             :         BUN i, ngrp, ncand;
      57             :         bit hasnil = 0;
      58             :         struct canditer ci;
      59             :         const char *err;
      60             :         lng t0 = 0;
      61             : 
      62          37 :         TRC_DEBUG_IF(ALGO) t0 = GDKusec();
      63             : 
      64          37 :         if ((err = BATgroupaggrinit(l, g, e, s, &min, &max, &ngrp, &ci, &ncand)) != NULL) {
      65           0 :                 GDKerror("%s\n", err);
      66           0 :                 return NULL;
      67             :         }
      68          37 :         if (g == NULL) {
      69           0 :                 GDKerror("l and g must be aligned\n");
      70           0 :                 return NULL;
      71             :         }
      72             : 
      73          37 :         if (BATcount(l) == 0 || ngrp == 0) {
      74          13 :                 const void *nilp = ATOMnilptr(l->ttype);
      75          13 :                 if ((res = BATconstant(ngrp == 0 ? 0 : min, l->ttype, nilp, ngrp, TRANSIENT)) == NULL)
      76           0 :                         goto alloc_fail;
      77             :         } else {
      78             :                 BATiter li;
      79             : 
      80          24 :                 if ((res = COLnew(min, l->ttype, ngrp, TRANSIENT)) == NULL)
      81           0 :                         goto alloc_fail;
      82          24 :                 if ((oids = GDKmalloc(ngrp * sizeof(oid))) == NULL)
      83           0 :                         goto alloc_fail;
      84             : 
      85         102 :                 for (i = 0; i < ngrp; i++)
      86          78 :                         oids[i] = BUN_NONE;
      87             : 
      88          24 :                 if (!g || BATtdense(g))
      89             :                         gids = NULL;
      90             :                 else
      91          11 :                         gids = (const oid *) Tloc(g, 0);
      92             : 
      93          24 :                 li = bat_iterator(l);
      94          48 :                 switch (ATOMbasetype(l->ttype)) {
      95           4 :                 case TYPE_bte:
      96          32 :                         SQLall_grp_imp(bte);
      97             :                         break;
      98           0 :                 case TYPE_sht:
      99           0 :                         SQLall_grp_imp(sht);
     100             :                         break;
     101           7 :                 case TYPE_int:
     102          55 :                         SQLall_grp_imp(int);
     103             :                         break;
     104           2 :                 case TYPE_lng:
     105          34 :                         SQLall_grp_imp(lng);
     106             :                         break;
     107             : #ifdef HAVE_HGE
     108          10 :                 case TYPE_hge:
     109          76 :                         SQLall_grp_imp(hge);
     110             :                         break;
     111             : #endif
     112           0 :                 case TYPE_flt:
     113           0 :                         SQLall_grp_imp(flt);
     114             :                         break;
     115           1 :                 case TYPE_dbl:
     116           9 :                         SQLall_grp_imp(dbl);
     117             :                         break;
     118           0 :                 default: {
     119           0 :                         int (*ocmp) (const void *, const void *) = ATOMcompare(l->ttype);
     120           0 :                         const void *restrict nilp = ATOMnilptr(l->ttype);
     121             : 
     122           0 :                         while (ncand > 0) {
     123           0 :                                 ncand--;
     124           0 :                                 i = canditer_next(&ci) - l->hseqbase;
     125           0 :                                 if (gids == NULL ||
     126           0 :                                         (gids[i] >= min && gids[i] <= max)) {
     127           0 :                                         if (gids)
     128           0 :                                                 gid = gids[i] - min;
     129             :                                         else
     130             :                                                 gid = (oid) i;
     131           0 :                                         if (oids[gid] != (BUN_NONE - 1)) {
     132           0 :                                                 if (oids[gid] == BUN_NONE) {
     133           0 :                                                         if (ocmp(BUNtail(li, i), nilp) != 0)
     134           0 :                                                                 oids[gid] = i;
     135             :                                                 } else {
     136           0 :                                                         const void *pi = BUNtail(li, oids[gid]);
     137           0 :                                                         const void *pp = BUNtail(li, i);
     138           0 :                                                         if (ocmp(pi, pp) != 0 && ocmp(pp, nilp) != 0)
     139           0 :                                                                 oids[gid] = BUN_NONE - 1;
     140             :                                                 }
     141             :                                         }
     142             :                                 }
     143             :                         }
     144             : 
     145           0 :                         if (ATOMvarsized(l->ttype)) {
     146           0 :                                 for (i = 0; i < ngrp; i++) { /* convert the found oids in values */
     147           0 :                                         BUN noid = oids[i];
     148             :                                         void *next;
     149           0 :                                         if (noid == BUN_NONE) {
     150             :                                                 next = (void*) nilp;
     151             :                                                 hasnil = 1;
     152             :                                         } else {
     153           0 :                                                 next = BUNtvar(li, noid);
     154             :                                         }
     155           0 :                                         if (tfastins_nocheckVAR(res, i, next) != GDK_SUCCEED) {
     156           0 :                                                 bat_iterator_end(&li);
     157           0 :                                                 goto alloc_fail;
     158             :                                         }
     159             :                                 }
     160             :                         } else {
     161           0 :                                 uint8_t *restrict rcast = (uint8_t *) Tloc(res, 0);
     162           0 :                                 uint16_t width = res->twidth;
     163           0 :                                 for (i = 0; i < ngrp; i++) { /* convert the found oids in values */
     164           0 :                                         BUN noid = oids[i];
     165             :                                         void *next;
     166           0 :                                         if (noid == BUN_NONE) {
     167             :                                                 next = (void*) nilp;
     168             :                                                 hasnil = 1;
     169             :                                         } else {
     170           0 :                                                 next = BUNtloc(li, noid);
     171             :                                         }
     172           0 :                                         memcpy(rcast, next, width);
     173           0 :                                         rcast += width;
     174             :                                 }
     175             :                         }
     176             :                 }
     177             :                 }
     178          24 :                 bat_iterator_end(&li);
     179          24 :                 BATsetcount(res, ngrp);
     180          24 :                 res->tnil = hasnil != 0;
     181          24 :                 res->tnonil = hasnil == 0;
     182          24 :                 res->tkey = BATcount(res) <= 1;
     183          24 :                 res->tsorted = BATcount(res) <= 1;
     184          24 :                 res->trevsorted = BATcount(res) <= 1;
     185             :         }
     186             : 
     187          37 :         GDKfree(oids);
     188             : 
     189          37 :         TRC_DEBUG(ALGO, "l=" ALGOBATFMT ",g=" ALGOBATFMT
     190             :                   ",e=" ALGOOPTBATFMT ",s=" ALGOOPTBATFMT
     191             :                   " -> " ALGOOPTBATFMT
     192             :                   " (%s -- " LLFMT " usec)\n",
     193             :                   ALGOBATPAR(l), ALGOBATPAR(g),
     194             :                   ALGOOPTBATPAR(e), ALGOOPTBATPAR(s),
     195             :                   ALGOOPTBATPAR(res),
     196             :                   __func__, GDKusec() - t0);
     197             :         return res;
     198           0 : alloc_fail:
     199           0 :         BBPreclaim(res);
     200           0 :         GDKfree(oids);
     201           0 :         return NULL;
     202             : }
     203             : 
     204             : #define SQLnil_grp_imp(TYPE)                                            \
     205             :         do {                                                            \
     206             :                 const TYPE *restrict vals = (const TYPE *) li.base;     \
     207             :                 while (ncand > 0) {                                  \
     208             :                         ncand--;                                        \
     209             :                         i = canditer_next(&ci) - l->hseqbase;            \
     210             :                         if (gids == NULL ||                             \
     211             :                             (gids[i] >= min && gids[i] <= max)) { \
     212             :                                 if (gids)                               \
     213             :                                         gid = gids[i] - min;            \
     214             :                                 else                                    \
     215             :                                         gid = (oid) i;                  \
     216             :                                 if (ret[gid] != TRUE && is_##TYPE##_nil(vals[i])) \
     217             :                                         ret[gid] = TRUE;                \
     218             :                         }                                               \
     219             :                 }                                                       \
     220             :         } while (0)
     221             : 
     222             : BAT *
     223          61 : BATnil_grp(BAT *l, BAT *g, BAT *e, BAT *s)
     224             : {
     225             :         BAT *res = NULL;
     226             :         const oid *restrict gids;
     227             :         oid gid, min, max;
     228             :         BUN i, ngrp, ncand;
     229             :         struct canditer ci;
     230             :         const char *err;
     231             :         lng t0 = 0;
     232             : 
     233          61 :         TRC_DEBUG_IF(ALGO) t0 = GDKusec();
     234             : 
     235          61 :         if ((err = BATgroupaggrinit(l, g, e, s, &min, &max, &ngrp, &ci, &ncand)) != NULL) {
     236           0 :                 GDKerror("%s\n", err);
     237           0 :                 return NULL;
     238             :         }
     239          61 :         if (g == NULL) {
     240           0 :                 GDKerror("l and g must be aligned\n");
     241           0 :                 return NULL;
     242             :         }
     243             : 
     244          74 :         if (BATcount(l) == 0 || ngrp == 0) {
     245          13 :                 bit F = FALSE;
     246          13 :                 if ((res = BATconstant(ngrp == 0 ? 0 : min, TYPE_bit, &F, ngrp, TRANSIENT)) == NULL)
     247           0 :                         goto alloc_fail;
     248             : 
     249             :         } else {
     250             :                 bit *restrict ret;
     251             :                 BATiter li;
     252             : 
     253          48 :                 if ((res = COLnew(min, TYPE_bit, ngrp, TRANSIENT)) == NULL)
     254           0 :                         goto alloc_fail;
     255          48 :                 ret = (bit *) Tloc(res, 0);
     256          48 :                 memset(ret, FALSE, ngrp * sizeof(bit));
     257             : 
     258          48 :                 if (!g || BATtdense(g))
     259             :                         gids = NULL;
     260             :                 else
     261          32 :                         gids = (const oid *) Tloc(g, 0);
     262             : 
     263          48 :                 li = bat_iterator(l);
     264          96 :                 switch (ATOMbasetype(l->ttype)) {
     265           4 :                 case TYPE_bte:
     266          24 :                         SQLnil_grp_imp(bte);
     267             :                         break;
     268           0 :                 case TYPE_sht:
     269           0 :                         SQLnil_grp_imp(sht);
     270             :                         break;
     271          22 :                 case TYPE_int:
     272         125 :                         SQLnil_grp_imp(int);
     273             :                         break;
     274           4 :                 case TYPE_lng:
     275          45 :                         SQLnil_grp_imp(lng);
     276             :                         break;
     277             : #ifdef HAVE_HGE
     278          17 :                 case TYPE_hge:
     279         108 :                         SQLnil_grp_imp(hge);
     280             :                         break;
     281             : #endif
     282           0 :                 case TYPE_flt:
     283           0 :                         SQLnil_grp_imp(flt);
     284             :                         break;
     285           1 :                 case TYPE_dbl:
     286           5 :                         SQLnil_grp_imp(dbl);
     287             :                         break;
     288           0 :                 default: {
     289           0 :                         int (*ocmp) (const void *, const void *) = ATOMcompare(l->ttype);
     290           0 :                         const void *restrict nilp = ATOMnilptr(l->ttype);
     291             : 
     292           0 :                         while (ncand > 0) {
     293           0 :                                 ncand--;
     294           0 :                                 i = canditer_next(&ci) - l->hseqbase;
     295           0 :                                 if (gids == NULL ||
     296           0 :                                         (gids[i] >= min && gids[i] <= max)) {
     297           0 :                                         if (gids)
     298           0 :                                                 gid = gids[i] - min;
     299             :                                         else
     300             :                                                 gid = (oid) i;
     301           0 :                                         const void *restrict lv = BUNtail(li, i);
     302           0 :                                         if (ret[gid] != TRUE && ocmp(lv, nilp) == 0)
     303           0 :                                                 ret[gid] = TRUE;
     304             :                                 }
     305             :                         }
     306             :                 }
     307             :                 }
     308          48 :                 bat_iterator_end(&li);
     309          48 :                 BATsetcount(res, ngrp);
     310          48 :                 res->tkey = BATcount(res) <= 1;
     311          48 :                 res->tsorted = BATcount(res) <= 1;
     312          48 :                 res->trevsorted = BATcount(res) <= 1;
     313          48 :                 res->tnil = false;
     314          48 :                 res->tnonil = true;
     315             :         }
     316             : 
     317          61 :         TRC_DEBUG(ALGO, "l=" ALGOBATFMT ",g=" ALGOBATFMT
     318             :                   ",e=" ALGOOPTBATFMT ",s=" ALGOOPTBATFMT
     319             :                   " -> " ALGOOPTBATFMT
     320             :                   " (%s -- " LLFMT " usec)\n",
     321             :                   ALGOBATPAR(l), ALGOBATPAR(g),
     322             :                   ALGOOPTBATPAR(e), ALGOOPTBATPAR(s),
     323             :                   ALGOOPTBATPAR(res),
     324             :                   __func__, GDKusec() - t0);
     325             :         return res;
     326           0 : alloc_fail:
     327           0 :         BBPreclaim(res);
     328           0 :         return NULL;
     329             : }
     330             : 
     331             : #define SQLanyequal_or_not_grp_imp(TYPE, TEST)                          \
     332             :         do {                                                            \
     333             :                 const TYPE *vals1 = (const TYPE *) li.base;             \
     334             :                 const TYPE *vals2 = (const TYPE *) ri.base;             \
     335             :                 while (ncand > 0) {                                  \
     336             :                         ncand--;                                        \
     337             :                         i = canditer_next(&ci) - l->hseqbase;            \
     338             :                         if (gids == NULL ||                             \
     339             :                             (gids[i] >= min && gids[i] <= max)) { \
     340             :                                 if (gids)                               \
     341             :                                         gid = gids[i] - min;            \
     342             :                                 else                                    \
     343             :                                         gid = (oid) i;                  \
     344             :                                 if (ret[gid] != TEST) {                 \
     345             :                                         if (is_##TYPE##_nil(vals1[i]) || is_##TYPE##_nil(vals2[i])) { \
     346             :                                                 ret[gid] = bit_nil;     \
     347             :                                                 hasnil = 1;             \
     348             :                                         } else if (vals1[i] == vals2[i]) { \
     349             :                                                 ret[gid] = TEST;        \
     350             :                                         }                               \
     351             :                                 }                                       \
     352             :                         }                                               \
     353             :                 }                                                       \
     354             :         } while (0)
     355             : 
     356             : BAT *
     357           0 : BATanyequal_grp(BAT *l, BAT *r, BAT *g, BAT *e, BAT *s)
     358             : {
     359             :         BAT *res = NULL;
     360             :         const oid *restrict gids;
     361             :         oid gid, min, max;
     362             :         BUN i, ngrp, ncand;
     363             :         bit hasnil = 0;
     364             :         struct canditer ci;
     365             :         const char *err;
     366             :         lng t0 = 0;
     367             : 
     368           0 :         TRC_DEBUG_IF(ALGO) t0 = GDKusec();
     369             : 
     370           0 :         if ((err = BATgroupaggrinit(l, g, e, s, &min, &max, &ngrp, &ci, &ncand)) != NULL) {
     371           0 :                 GDKerror("%s\n", err);
     372           0 :                 return NULL;
     373             :         }
     374           0 :         if (g == NULL) {
     375           0 :                 GDKerror("l, r and g must be aligned\n");
     376           0 :                 return NULL;
     377             :         }
     378             : 
     379           0 :         if (BATcount(l) == 0 || ngrp == 0) {
     380           0 :                 bit F = FALSE;
     381           0 :                 if ((res = BATconstant(ngrp == 0 ? 0 : min, TYPE_bit, &F, ngrp, TRANSIENT)) == NULL)
     382           0 :                         goto alloc_fail;
     383             :         } else {
     384             :                 bit *restrict ret;
     385             :                 BATiter li, ri;
     386             : 
     387           0 :                 if ((res = COLnew(min, TYPE_bit, ngrp, TRANSIENT)) == NULL)
     388           0 :                         goto alloc_fail;
     389           0 :                 ret = (bit *) Tloc(res, 0);
     390           0 :                 memset(ret, FALSE, ngrp * sizeof(bit));
     391             : 
     392           0 :                 if (!g || BATtdense(g))
     393             :                         gids = NULL;
     394             :                 else
     395           0 :                         gids = (const oid *) Tloc(g, 0);
     396             : 
     397           0 :                 li = bat_iterator(l);
     398           0 :                 ri = bat_iterator(r);
     399           0 :                 switch (ATOMbasetype(l->ttype)) {
     400           0 :                 case TYPE_bte:
     401           0 :                         SQLanyequal_or_not_grp_imp(bte, TRUE);
     402             :                         break;
     403           0 :                 case TYPE_sht:
     404           0 :                         SQLanyequal_or_not_grp_imp(sht, TRUE);
     405             :                         break;
     406           0 :                 case TYPE_int:
     407           0 :                         SQLanyequal_or_not_grp_imp(int, TRUE);
     408             :                         break;
     409           0 :                 case TYPE_lng:
     410           0 :                         SQLanyequal_or_not_grp_imp(lng, TRUE);
     411             :                         break;
     412             : #ifdef HAVE_HGE
     413           0 :                 case TYPE_hge:
     414           0 :                         SQLanyequal_or_not_grp_imp(hge, TRUE);
     415             :                         break;
     416             : #endif
     417           0 :                 case TYPE_flt:
     418           0 :                         SQLanyequal_or_not_grp_imp(flt, TRUE);
     419             :                         break;
     420           0 :                 case TYPE_dbl:
     421           0 :                         SQLanyequal_or_not_grp_imp(dbl, TRUE);
     422             :                         break;
     423           0 :                 default: {
     424           0 :                         int (*ocmp) (const void *, const void *) = ATOMcompare(l->ttype);
     425           0 :                         const void *nilp = ATOMnilptr(l->ttype);
     426             : 
     427           0 :                         while (ncand > 0) {
     428           0 :                                 ncand--;
     429           0 :                                 i = canditer_next(&ci) - l->hseqbase;
     430           0 :                                 if (gids == NULL ||
     431           0 :                                         (gids[i] >= min && gids[i] <= max)) {
     432           0 :                                         if (gids)
     433           0 :                                                 gid = gids[i] - min;
     434             :                                         else
     435             :                                                 gid = (oid) i;
     436           0 :                                         if (ret[gid] != TRUE) {
     437           0 :                                                 const void *lv = BUNtail(li, i);
     438           0 :                                                 const void *rv = BUNtail(ri, i);
     439           0 :                                                 if (ocmp(lv, nilp) == 0 || ocmp(rv, nilp) == 0) {
     440           0 :                                                         ret[gid] = bit_nil;
     441           0 :                                                         hasnil = 1;
     442           0 :                                                 } else if (ocmp(lv, rv) == 0)
     443           0 :                                                         ret[gid] = TRUE;
     444             :                                         }
     445             :                                 }
     446             :                         }
     447             :                 }
     448             :                 }
     449           0 :                 bat_iterator_end(&li);
     450           0 :                 bat_iterator_end(&ri);
     451           0 :                 BATsetcount(res, ngrp);
     452           0 :                 res->tkey = BATcount(res) <= 1;
     453           0 :                 res->tsorted = BATcount(res) <= 1;
     454           0 :                 res->trevsorted = BATcount(res) <= 1;
     455           0 :                 res->tnil = hasnil != 0;
     456           0 :                 res->tnonil = hasnil == 0;
     457             :         }
     458             : 
     459           0 :         TRC_DEBUG(ALGO, "l=" ALGOBATFMT ",r=" ALGOBATFMT ",g=" ALGOBATFMT
     460             :                   ",e=" ALGOOPTBATFMT ",s=" ALGOOPTBATFMT
     461             :                   " -> " ALGOOPTBATFMT
     462             :                   " (%s -- " LLFMT " usec)\n",
     463             :                   ALGOBATPAR(l), ALGOBATPAR(r), ALGOBATPAR(g),
     464             :                   ALGOOPTBATPAR(e), ALGOOPTBATPAR(s),
     465             :                   ALGOOPTBATPAR(res),
     466             :                   __func__, GDKusec() - t0);
     467             :         return res;
     468           0 : alloc_fail:
     469           0 :         BBPreclaim(res);
     470           0 :         return NULL;
     471             : }
     472             : 
     473             : BAT *
     474           0 : BATallnotequal_grp(BAT *l, BAT *r, BAT *g, BAT *e, BAT *s)
     475             : {
     476             :         BAT *res = NULL;
     477             :         const oid *restrict gids;
     478             :         oid gid, min, max;
     479             :         BUN i, ngrp, ncand;
     480             :         bit hasnil = 0;
     481             :         struct canditer ci;
     482             :         const char *err;
     483             :         lng t0 = 0;
     484             : 
     485           0 :         TRC_DEBUG_IF(ALGO) t0 = GDKusec();
     486             : 
     487           0 :         if ((err = BATgroupaggrinit(l, g, e, s, &min, &max, &ngrp, &ci, &ncand)) != NULL) {
     488           0 :                 GDKerror("%s\n", err);
     489           0 :                 return NULL;
     490             :         }
     491           0 :         if (g == NULL) {
     492           0 :                 GDKerror("l, r and g must be aligned\n");
     493           0 :                 return NULL;
     494             :         }
     495             : 
     496           0 :         if (BATcount(l) == 0 || ngrp == 0) {
     497           0 :                 bit T = TRUE;
     498           0 :                 if ((res = BATconstant(ngrp == 0 ? 0 : min, TYPE_bit, &T, ngrp, TRANSIENT)) == NULL)
     499           0 :                         goto alloc_fail;
     500             :         } else {
     501             :                 bit *restrict ret;
     502             :                 BATiter li, ri;
     503             : 
     504           0 :                 if ((res = COLnew(min, TYPE_bit, ngrp, TRANSIENT)) == NULL)
     505           0 :                         goto alloc_fail;
     506           0 :                 ret = (bit *) Tloc(res, 0);
     507           0 :                 memset(ret, FALSE, ngrp * sizeof(bit));
     508             : 
     509           0 :                 if (!g || BATtdense(g))
     510             :                         gids = NULL;
     511             :                 else
     512           0 :                         gids = (const oid *) Tloc(g, 0);
     513             : 
     514           0 :                 li = bat_iterator(l);
     515           0 :                 ri = bat_iterator(r);
     516           0 :                 switch (ATOMbasetype(l->ttype)) {
     517           0 :                 case TYPE_bte:
     518           0 :                         SQLanyequal_or_not_grp_imp(bte, FALSE);
     519             :                         break;
     520           0 :                 case TYPE_sht:
     521           0 :                         SQLanyequal_or_not_grp_imp(sht, FALSE);
     522             :                         break;
     523           0 :                 case TYPE_int:
     524           0 :                         SQLanyequal_or_not_grp_imp(int, FALSE);
     525             :                         break;
     526           0 :                 case TYPE_lng:
     527           0 :                         SQLanyequal_or_not_grp_imp(lng, FALSE);
     528             :                         break;
     529             : #ifdef HAVE_HGE
     530           0 :                 case TYPE_hge:
     531           0 :                         SQLanyequal_or_not_grp_imp(hge, FALSE);
     532             :                         break;
     533             : #endif
     534           0 :                 case TYPE_flt:
     535           0 :                         SQLanyequal_or_not_grp_imp(flt, FALSE);
     536             :                         break;
     537           0 :                 case TYPE_dbl:
     538           0 :                         SQLanyequal_or_not_grp_imp(dbl, FALSE);
     539             :                         break;
     540           0 :                 default: {
     541           0 :                         int (*ocmp) (const void *, const void *) = ATOMcompare(l->ttype);
     542           0 :                         const void *nilp = ATOMnilptr(l->ttype);
     543             : 
     544           0 :                         while (ncand > 0) {
     545           0 :                                 ncand--;
     546           0 :                                 i = canditer_next(&ci) - l->hseqbase;
     547           0 :                                 if (gids == NULL ||
     548           0 :                                         (gids[i] >= min && gids[i] <= max)) {
     549           0 :                                         if (gids)
     550           0 :                                                 gid = gids[i] - min;
     551             :                                         else
     552             :                                                 gid = (oid) i;
     553           0 :                                         if (ret[gid] != FALSE) {
     554           0 :                                                 const void *lv = BUNtail(li, i);
     555           0 :                                                 const void *rv = BUNtail(ri, i);
     556           0 :                                                 if (ocmp(lv, nilp) == 0 || ocmp(rv, nilp) == 0) {
     557           0 :                                                         ret[gid] = bit_nil;
     558           0 :                                                         hasnil = 1;
     559           0 :                                                 } else if (ocmp(lv, rv) == 0)
     560           0 :                                                         ret[gid] = FALSE;
     561             :                                         }
     562             :                                 }
     563             :                         }
     564             :                 }
     565             :                 }
     566           0 :                 bat_iterator_end(&li);
     567           0 :                 bat_iterator_end(&ri);
     568           0 :                 BATsetcount(res, ngrp);
     569           0 :                 res->tkey = BATcount(res) <= 1;
     570           0 :                 res->tsorted = BATcount(res) <= 1;
     571           0 :                 res->trevsorted = BATcount(res) <= 1;
     572           0 :                 res->tnil = hasnil != 0;
     573           0 :                 res->tnonil = hasnil == 0;
     574             :         }
     575             : 
     576           0 :         TRC_DEBUG(ALGO, "l=" ALGOBATFMT ",r=" ALGOBATFMT ",g=" ALGOBATFMT
     577             :                   ",e=" ALGOOPTBATFMT ",s=" ALGOOPTBATFMT
     578             :                   " -> " ALGOOPTBATFMT
     579             :                   " (%s -- " LLFMT " usec)\n",
     580             :                   ALGOBATPAR(l), ALGOBATPAR(r), ALGOBATPAR(g),
     581             :                   ALGOOPTBATPAR(e), ALGOOPTBATPAR(s),
     582             :                   ALGOOPTBATPAR(res),
     583             :                   __func__, GDKusec() - t0);
     584             :         return res;
     585           0 : alloc_fail:
     586           0 :         BBPreclaim(res);
     587           0 :         return NULL;
     588             : }
     589             : 
     590             : #define SQLanyequal_or_not_grp2_imp(TYPE, VAL1, VAL2)                   \
     591             :         do {                                                            \
     592             :                 const TYPE *vals1 = (const TYPE *) li.base;             \
     593             :                 const TYPE *vals2 = (const TYPE *) ri.base;             \
     594             :                 while (ncand > 0) {                                  \
     595             :                         ncand--;                                        \
     596             :                         i = canditer_next(&ci) - l->hseqbase;            \
     597             :                         if (gids == NULL ||                             \
     598             :                             (gids[i] >= min && gids[i] <= max)) { \
     599             :                                 if (gids)                               \
     600             :                                         gid = gids[i] - min;            \
     601             :                                 else                                    \
     602             :                                         gid = (oid) i;                  \
     603             :                                 if (ret[gid] != VAL1) {                 \
     604             :                                         const oid id = *(oid*)BUNtail(ii, i); \
     605             :                                         if (is_oid_nil(id)) {           \
     606             :                                                 ret[gid] = VAL2;        \
     607             :                                         } else if (is_##TYPE##_nil(vals1[i]) || is_##TYPE##_nil(vals2[i])) { \
     608             :                                                 ret[gid] = bit_nil;     \
     609             :                                         } else if (vals1[i] == vals2[i]) { \
     610             :                                                 ret[gid] = VAL1;        \
     611             :                                         }                               \
     612             :                                 }                                       \
     613             :                         }                                               \
     614             :                 }                                                       \
     615             :         } while (0)
     616             : 
     617             : BAT *
     618         132 : BATanyequal_grp2(BAT *l, BAT *r, BAT *rid, BAT *g, BAT *e, BAT *s)
     619             : {
     620             :         BAT *res = NULL;
     621             :         const oid *restrict gids;
     622             :         oid gid, min, max;
     623             :         BUN i, ngrp, ncand;
     624             :         bit hasnil = 0;
     625             :         struct canditer ci;
     626             :         const char *err;
     627             :         lng t0 = 0;
     628             : 
     629         132 :         TRC_DEBUG_IF(ALGO) t0 = GDKusec();
     630             : 
     631         132 :         if ((err = BATgroupaggrinit(l, g, e, s, &min, &max, &ngrp, &ci, &ncand)) != NULL) {
     632           0 :                 GDKerror("%s\n", err);
     633           0 :                 return NULL;
     634             :         }
     635         132 :         if (g == NULL) {
     636           0 :                 GDKerror("l, r, rid and g must be aligned\n");
     637           0 :                 return NULL;
     638             :         }
     639             : 
     640         138 :         if (BATcount(l) == 0 || ngrp == 0) {
     641           6 :                 bit F = FALSE;
     642           6 :                 if ((res = BATconstant(ngrp == 0 ? 0 : min, TYPE_bit, &F, ngrp, TRANSIENT)) == NULL)
     643           0 :                         goto alloc_fail;
     644             :         } else {
     645             :                 bit *restrict ret;
     646             :                 BATiter ii, li, ri;
     647             : 
     648         126 :                 if ((res = COLnew(min, TYPE_bit, ngrp, TRANSIENT)) == NULL)
     649           0 :                         goto alloc_fail;
     650         126 :                 ret = (bit *) Tloc(res, 0);
     651         126 :                 memset(ret, FALSE, ngrp * sizeof(bit));
     652             : 
     653         126 :                 if (!g || BATtdense(g))
     654             :                         gids = NULL;
     655             :                 else
     656          80 :                         gids = (const oid *) Tloc(g, 0);
     657             : 
     658         126 :                 ii = bat_iterator(rid);
     659         126 :                 li = bat_iterator(l);
     660         126 :                 ri = bat_iterator(r);
     661         249 :                 switch (ATOMbasetype(l->ttype)) {
     662           9 :                 case TYPE_bte:
     663          46 :                         SQLanyequal_or_not_grp2_imp(bte, TRUE, FALSE);
     664             :                         break;
     665           1 :                 case TYPE_sht:
     666           4 :                         SQLanyequal_or_not_grp2_imp(sht, TRUE, FALSE);
     667             :                         break;
     668          68 :                 case TYPE_int:
     669       27220 :                         SQLanyequal_or_not_grp2_imp(int, TRUE, FALSE);
     670             :                         break;
     671          17 :                 case TYPE_lng:
     672       22426 :                         SQLanyequal_or_not_grp2_imp(lng, TRUE, FALSE);
     673             :                         break;
     674             : #ifdef HAVE_HGE
     675          14 :                 case TYPE_hge:
     676         247 :                         SQLanyequal_or_not_grp2_imp(hge, TRUE, FALSE);
     677             :                         break;
     678             : #endif
     679           1 :                 case TYPE_flt:
     680        4865 :                         SQLanyequal_or_not_grp2_imp(flt, TRUE, FALSE);
     681             :                         break;
     682           3 :                 case TYPE_dbl:
     683          25 :                         SQLanyequal_or_not_grp2_imp(dbl, TRUE, FALSE);
     684             :                         break;
     685          13 :                 default: {
     686          13 :                         int (*ocmp) (const void *, const void *) = ATOMcompare(l->ttype);
     687          13 :                         const void *nilp = ATOMnilptr(l->ttype);
     688             : 
     689          66 :                         while (ncand > 0) {
     690          53 :                                 ncand--;
     691          53 :                                 i = canditer_next(&ci) - l->hseqbase;
     692          53 :                                 if (gids == NULL ||
     693          45 :                                         (gids[i] >= min && gids[i] <= max)) {
     694          53 :                                         if (gids)
     695          45 :                                                 gid = gids[i] - min;
     696             :                                         else
     697             :                                                 gid = (oid) i;
     698          53 :                                         if (ret[gid] != TRUE) {
     699          44 :                                                 const oid id = *(oid*)BUNtail(ii, i);
     700          44 :                                                 if (is_oid_nil(id)) {
     701           2 :                                                         ret[gid] = FALSE;
     702             :                                                 } else {
     703          42 :                                                         const void *lv = BUNtail(li, i);
     704          42 :                                                         const void *rv = BUNtail(ri, i);
     705          42 :                                                         if (ocmp(lv, nilp) == 0 || ocmp(rv, nilp) == 0) {
     706          13 :                                                                 ret[gid] = bit_nil;
     707          29 :                                                         } else if (ocmp(lv, rv) == 0)
     708           9 :                                                                 ret[gid] = TRUE;
     709             :                                                 }
     710             :                                         }
     711             :                                 }
     712             :                         }
     713             :                 }
     714             :                 }
     715         126 :                 bat_iterator_end(&li);
     716         126 :                 bat_iterator_end(&ri);
     717         126 :                 bat_iterator_end(&ii);
     718       12520 :                 for (BUN i = 0 ; i < ngrp ; i++)
     719       12394 :                         hasnil |= ret[i] == bit_nil;
     720         126 :                 BATsetcount(res, ngrp);
     721         126 :                 res->tkey = BATcount(res) <= 1;
     722         126 :                 res->tsorted = BATcount(res) <= 1;
     723         126 :                 res->trevsorted = BATcount(res) <= 1;
     724         126 :                 res->tnil = hasnil != 0;
     725         126 :                 res->tnonil = hasnil == 0;
     726             :         }
     727             : 
     728         132 :         TRC_DEBUG(ALGO, "l=" ALGOBATFMT ",r=" ALGOBATFMT ",rid=" ALGOBATFMT
     729             :                   ",g=" ALGOBATFMT ",e=" ALGOOPTBATFMT ",s=" ALGOOPTBATFMT
     730             :                   " -> " ALGOOPTBATFMT
     731             :                   " (%s -- " LLFMT " usec)\n",
     732             :                   ALGOBATPAR(l), ALGOBATPAR(r), ALGOBATPAR(rid),
     733             :                   ALGOBATPAR(g), ALGOOPTBATPAR(e), ALGOOPTBATPAR(s),
     734             :                   ALGOOPTBATPAR(res),
     735             :                   __func__, GDKusec() - t0);
     736             :         return res;
     737           0 : alloc_fail:
     738           0 :         BBPreclaim(res);
     739           0 :         return NULL;
     740             : }
     741             : 
     742             : BAT *
     743          36 : BATallnotequal_grp2(BAT *l, BAT *r, BAT *rid, BAT *g, BAT *e, BAT *s)
     744             : {
     745             :         BAT *res = NULL;
     746             :         const oid *restrict gids;
     747             :         oid gid, min, max;
     748             :         BUN i, ngrp, ncand;
     749             :         bit hasnil = 0;
     750             :         struct canditer ci;
     751             :         const char *err;
     752             :         lng t0 = 0;
     753             : 
     754          36 :         TRC_DEBUG_IF(ALGO) t0 = GDKusec();
     755             : 
     756          36 :         if ((err = BATgroupaggrinit(l, g, e, s, &min, &max, &ngrp, &ci, &ncand)) != NULL) {
     757           0 :                 GDKerror("%s\n", err);
     758           0 :                 return NULL;
     759             :         }
     760          36 :         if (g == NULL) {
     761           0 :                 GDKerror("l, r, rid and g must be aligned\n");
     762           0 :                 return NULL;
     763             :         }
     764             : 
     765          36 :         if (BATcount(l) == 0 || ngrp == 0) {
     766           0 :                 bit T = TRUE;
     767           0 :                 if ((res = BATconstant(ngrp == 0 ? 0 : min, TYPE_bit, &T, ngrp, TRANSIENT)) == NULL)
     768           0 :                         goto alloc_fail;
     769             :         } else {
     770             :                 bit *restrict ret;
     771             :                 BATiter ii, li, ri;
     772             : 
     773          36 :                 if ((res = COLnew(min, TYPE_bit, ngrp, TRANSIENT)) == NULL)
     774           0 :                         goto alloc_fail;
     775          36 :                 ret = (bit *) Tloc(res, 0);
     776          36 :                 memset(ret, TRUE, ngrp * sizeof(bit));
     777             : 
     778          36 :                 if (!g || BATtdense(g))
     779             :                         gids = NULL;
     780             :                 else
     781          21 :                         gids = (const oid *) Tloc(g, 0);
     782             : 
     783          36 :                 ii = bat_iterator(rid);
     784          36 :                 li = bat_iterator(l);
     785          36 :                 ri = bat_iterator(r);
     786          67 :                 switch (ATOMbasetype(l->ttype)) {
     787           8 :                 case TYPE_bte:
     788          76 :                         SQLanyequal_or_not_grp2_imp(bte, FALSE, TRUE);
     789             :                         break;
     790           0 :                 case TYPE_sht:
     791           0 :                         SQLanyequal_or_not_grp2_imp(sht, FALSE, TRUE);
     792             :                         break;
     793          15 :                 case TYPE_int:
     794     6744473 :                         SQLanyequal_or_not_grp2_imp(int, FALSE, TRUE);
     795             :                         break;
     796           2 :                 case TYPE_lng:
     797           5 :                         SQLanyequal_or_not_grp2_imp(lng, FALSE, TRUE);
     798             :                         break;
     799             : #ifdef HAVE_HGE
     800           3 :                 case TYPE_hge:
     801          33 :                         SQLanyequal_or_not_grp2_imp(hge, FALSE, TRUE);
     802             :                         break;
     803             : #endif
     804           0 :                 case TYPE_flt:
     805           0 :                         SQLanyequal_or_not_grp2_imp(flt, FALSE, TRUE);
     806             :                         break;
     807           2 :                 case TYPE_dbl:
     808          30 :                         SQLanyequal_or_not_grp2_imp(dbl, FALSE, TRUE);
     809             :                         break;
     810           6 :                 default: {
     811           6 :                         int (*ocmp) (const void *, const void *) = ATOMcompare(l->ttype);
     812           6 :                         const void *nilp = ATOMnilptr(l->ttype);
     813             : 
     814         229 :                         while (ncand > 0) {
     815         223 :                                 ncand--;
     816         223 :                                 i = canditer_next(&ci) - l->hseqbase;
     817         223 :                                 if (gids == NULL ||
     818           8 :                                         (gids[i] >= min && gids[i] <= max)) {
     819         223 :                                         if (gids)
     820           8 :                                                 gid = gids[i] - min;
     821             :                                         else
     822             :                                                 gid = (oid) i;
     823         223 :                                         if (ret[gid] != FALSE) {
     824         221 :                                                 const oid id = *(oid*)BUNtail(ii, i);
     825         221 :                                                 if (is_oid_nil(id)) {
     826          71 :                                                         ret[gid] = TRUE;
     827             :                                                 } else {
     828         150 :                                                         const void *lv = BUNtail(li, i);
     829         150 :                                                         const void *rv = BUNtail(ri, i);
     830         150 :                                                         if (ocmp(lv, nilp) == 0 || ocmp(rv, nilp) == 0) {
     831         144 :                                                                 ret[gid] = bit_nil;
     832           6 :                                                         } else if (ocmp(lv, rv) == 0)
     833           2 :                                                                 ret[gid] = FALSE;
     834             :                                                 }
     835             :                                         }
     836             :                                 }
     837             :                         }
     838             :                 }
     839             :                 }
     840          36 :                 bat_iterator_end(&ii);
     841          36 :                 bat_iterator_end(&li);
     842          36 :                 bat_iterator_end(&ri);
     843        4877 :                 for (BUN i = 0 ; i < ngrp ; i++)
     844        4841 :                         hasnil |= ret[i] == bit_nil;
     845          36 :                 BATsetcount(res, ngrp);
     846          36 :                 res->tkey = BATcount(res) <= 1;
     847          36 :                 res->tsorted = BATcount(res) <= 1;
     848          36 :                 res->trevsorted = BATcount(res) <= 1;
     849          36 :                 res->tnil = hasnil != 0;
     850          36 :                 res->tnonil = hasnil == 0;
     851             :         }
     852             : 
     853          36 :         TRC_DEBUG(ALGO, "l=" ALGOBATFMT ",r=" ALGOBATFMT ",rid=" ALGOBATFMT
     854             :                   ",g=" ALGOBATFMT ",e=" ALGOOPTBATFMT ",s=" ALGOOPTBATFMT
     855             :                   " -> " ALGOOPTBATFMT
     856             :                   " (%s -- " LLFMT " usec)\n",
     857             :                   ALGOBATPAR(l), ALGOBATPAR(r), ALGOBATPAR(rid),
     858             :                   ALGOBATPAR(g), ALGOOPTBATPAR(e), ALGOOPTBATPAR(s),
     859             :                   ALGOOPTBATPAR(res),
     860             :                   __func__, GDKusec() - t0);
     861             :         return res;
     862           0 : alloc_fail:
     863           0 :         BBPreclaim(res);
     864           0 :         return NULL;
     865             : }
     866             : 
     867             : BAT *
     868          48 : BATsubexist(BAT *b, BAT *g, BAT *e, BAT *s)
     869             : {
     870             :         BAT *res = NULL;
     871             :         const oid *restrict gids;
     872             :         oid min, max;
     873             :         BUN i, ngrp, ncand;
     874             :         struct canditer ci;
     875             :         const char *err;
     876             :         lng t0 = 0;
     877             : 
     878          48 :         TRC_DEBUG_IF(ALGO) t0 = GDKusec();
     879             : 
     880          48 :         if ((err = BATgroupaggrinit(b, g, e, s, &min, &max, &ngrp, &ci, &ncand)) != NULL) {
     881           0 :                 GDKerror("%s\n", err);
     882           0 :                 return NULL;
     883             :         }
     884          48 :         if (g == NULL) {
     885           0 :                 GDKerror("b and g must be aligned\n");
     886           0 :                 return NULL;
     887             :         }
     888             : 
     889          80 :         if (BATcount(b) == 0 || ngrp == 0) {
     890          32 :                 bit F = FALSE;
     891          32 :                 if ((res = BATconstant(ngrp == 0 ? 0 : min, TYPE_bit, &F, ngrp, TRANSIENT)) == NULL)
     892           0 :                         goto alloc_fail;
     893             :         } else {
     894             :                 bit *restrict exists;
     895             : 
     896          16 :                 if ((res = COLnew(min, TYPE_bit, ngrp, TRANSIENT)) == NULL)
     897           0 :                         goto alloc_fail;
     898          16 :                 exists = (bit *) Tloc(res, 0);
     899          16 :                 memset(exists, FALSE, ngrp * sizeof(bit));
     900             : 
     901          16 :                 if (!g || BATtdense(g))
     902             :                         gids = NULL;
     903             :                 else
     904           5 :                         gids = (const oid *) Tloc(g, 0);
     905             : 
     906           5 :                 if (gids) {
     907          26 :                         while (ncand > 0) {
     908          21 :                                 ncand--;
     909          21 :                                 i = canditer_next(&ci) - b->hseqbase;
     910          21 :                                 if (gids[i] >= min && gids[i] <= max)
     911          21 :                                         exists[gids[i] - min] = TRUE;
     912             :                         }
     913             :                 } else {
     914          30 :                         while (ncand > 0) {
     915          19 :                                 ncand--;
     916          19 :                                 i = canditer_next(&ci) - b->hseqbase;
     917          19 :                                 exists[i] = TRUE;
     918             :                         }
     919             :                 }
     920          16 :                 BATsetcount(res, ngrp);
     921          16 :                 res->tkey = BATcount(res) <= 1;
     922          16 :                 res->tsorted = BATcount(res) <= 1;
     923          16 :                 res->trevsorted = BATcount(res) <= 1;
     924          16 :                 res->tnil = false;
     925          16 :                 res->tnonil = true;
     926             :         }
     927             : 
     928          48 :         TRC_DEBUG(ALGO, "b=" ALGOBATFMT ",g=" ALGOBATFMT
     929             :                   ",e=" ALGOOPTBATFMT ",s=" ALGOOPTBATFMT
     930             :                   " -> " ALGOOPTBATFMT
     931             :                   " (%s -- " LLFMT " usec)\n",
     932             :                   ALGOBATPAR(b), ALGOBATPAR(g),
     933             :                   ALGOOPTBATPAR(e), ALGOOPTBATPAR(s),
     934             :                   ALGOOPTBATPAR(res),
     935             :                   __func__, GDKusec() - t0);
     936             :         return res;
     937           0 : alloc_fail:
     938           0 :         BBPreclaim(res);
     939           0 :         return NULL;
     940             : }
     941             : 
     942             : BAT *
     943          17 : BATsubnot_exist(BAT *b, BAT *g, BAT *e, BAT *s)
     944             : {
     945             :         BAT *res = NULL;
     946             :         const oid *restrict gids;
     947             :         oid min, max;
     948             :         BUN i, ngrp, ncand;
     949             :         struct canditer ci;
     950             :         const char *err;
     951             :         lng t0 = 0;
     952             : 
     953          17 :         TRC_DEBUG_IF(ALGO) t0 = GDKusec();
     954             : 
     955          17 :         if ((err = BATgroupaggrinit(b, g, e, s, &min, &max, &ngrp, &ci, &ncand)) != NULL) {
     956           0 :                 GDKerror("%s\n", err);
     957           0 :                 return NULL;
     958             :         }
     959          17 :         if (g == NULL) {
     960           0 :                 GDKerror("b and g must be aligned\n");
     961           0 :                 return NULL;
     962             :         }
     963             : 
     964          22 :         if (BATcount(b) == 0 || ngrp == 0) {
     965           5 :                 bit T = TRUE;
     966           5 :                 if ((res = BATconstant(ngrp == 0 ? 0 : min, TYPE_bit, &T, ngrp, TRANSIENT)) == NULL)
     967           0 :                         goto alloc_fail;
     968             :         } else {
     969             :                 bit *restrict exists;
     970             : 
     971          12 :                 if ((res = COLnew(min, TYPE_bit, ngrp, TRANSIENT)) == NULL)
     972           0 :                         goto alloc_fail;
     973          12 :                 exists = (bit *) Tloc(res, 0);
     974          12 :                 memset(exists, TRUE, ngrp * sizeof(bit));
     975             : 
     976          12 :                 if (!g || BATtdense(g))
     977             :                         gids = NULL;
     978             :                 else
     979           4 :                         gids = (const oid *) Tloc(g, 0);
     980             : 
     981           4 :                 if (gids) {
     982          84 :                         while (ncand > 0) {
     983          80 :                                 ncand--;
     984          80 :                                 i = canditer_next(&ci) - b->hseqbase;
     985          80 :                                 if (gids[i] >= min && gids[i] <= max)
     986          80 :                                         exists[gids[i] - min] = FALSE;
     987             :                         }
     988             :                 } else {
     989          29 :                         while (ncand > 0) {
     990          21 :                                 ncand--;
     991          21 :                                 i = canditer_next(&ci) - b->hseqbase;
     992          21 :                                 exists[i] = FALSE;
     993             :                         }
     994             :                 }
     995          12 :                 BATsetcount(res, ngrp);
     996          12 :                 res->tkey = BATcount(res) <= 1;
     997          12 :                 res->tsorted = BATcount(res) <= 1;
     998          12 :                 res->trevsorted = BATcount(res) <= 1;
     999          12 :                 res->tnil = false;
    1000          12 :                 res->tnonil = true;
    1001             :         }
    1002             : 
    1003          17 :         TRC_DEBUG(ALGO, "b=" ALGOBATFMT ",g=" ALGOBATFMT
    1004             :                   ",e=" ALGOOPTBATFMT ",s=" ALGOOPTBATFMT
    1005             :                   " -> " ALGOOPTBATFMT
    1006             :                   " (%s -- " LLFMT " usec)\n",
    1007             :                   ALGOBATPAR(b), ALGOBATPAR(g),
    1008             :                   ALGOOPTBATPAR(e), ALGOOPTBATPAR(s),
    1009             :                   ALGOOPTBATPAR(res),
    1010             :                   __func__, GDKusec() - t0);
    1011             :         return res;
    1012           0 : alloc_fail:
    1013           0 :         BBPreclaim(res);
    1014           0 :         return NULL;
    1015             : }

Generated by: LCOV version 1.14