LCOV - code coverage report
Current view: top level - sql/storage/bat - bat_table.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 353 493 71.6 %
Date: 2021-10-13 02:24:04 Functions: 27 28 96.4 %

          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 "bat_table.h"
      11             : #include "bat_utils.h"
      12             : #include "bat_storage.h"
      13             : 
      14             : static BAT *
      15      691157 : delta_cands(sql_trans *tr, sql_table *t)
      16             : {
      17      691157 :         sqlstore *store = tr->store;
      18      691157 :         BAT *cands = store->storage_api.bind_cands(tr, t, 1, 0);
      19             : 
      20      691157 :         if (cands && (cands->ttype == TYPE_msk || mask_cand(cands))) {
      21       95320 :                 BAT *ncands = BATunmask(cands);
      22       95320 :                 BBPreclaim(cands);
      23             :                 cands = ncands;
      24             :         }
      25      691157 :         return cands;
      26             : }
      27             : 
      28             : static BAT *
      29     2402045 : full_column(sql_trans *tr, sql_column *c)
      30             : {
      31             :         /* return full normalized column bat
      32             :          *      b := b.copy()
      33             :                 b := b.replace(u);
      34             :         */
      35     2402045 :         sqlstore *store = tr->store;
      36     2402045 :         BAT *b = store->storage_api.bind_col(tr, c, RDONLY);
      37     2402045 :         BAT *ui = store->storage_api.bind_col(tr, c, RD_UPD_ID);
      38             : 
      39     2402045 :         if (!b || !ui) {
      40           0 :                 bat_destroy(b);
      41           0 :                 bat_destroy(ui);
      42           0 :                 return NULL;
      43             :         }
      44     2402045 :         if (BATcount(ui)) {
      45        1645 :                 BAT *uv = store->storage_api.bind_col(tr, c, RD_UPD_VAL), *r;
      46             : 
      47        1645 :                 if (!uv) {
      48           0 :                         bat_destroy(b);
      49           0 :                         bat_destroy(ui);
      50           0 :                         return NULL;
      51             :                 }
      52             : 
      53        1645 :                 r = COLcopy(b, b->ttype, true, TRANSIENT);
      54        1645 :                 bat_destroy(b);
      55             :                 b = r;
      56        1645 :                 if (!b || BATreplace(b, ui, uv, true) != GDK_SUCCEED) {
      57           0 :                         bat_destroy(b);
      58           0 :                         bat_destroy(ui);
      59           0 :                         bat_destroy(uv);
      60           0 :                         return NULL;
      61             :                 }
      62        1645 :                 bat_destroy(uv);
      63             :         }
      64     2402045 :         bat_destroy(ui);
      65     2402045 :         return b;
      66             : }
      67             : 
      68             : static oid
      69      601485 : column_find_row(sql_trans *tr, sql_column *c, const void *value, ...)
      70             : {
      71             :         va_list va;
      72             :         BAT *b = NULL, *s = NULL, *r = NULL;
      73      601485 :         oid rid = oid_nil;
      74             :         sql_column *n = NULL;
      75             : 
      76      601485 :         va_start(va, value);
      77      601485 :         s = delta_cands(tr, c->t);
      78      601485 :         if (!s)
      79           0 :                 goto return_nil;
      80      601485 :         b = full_column(tr, c);
      81      601485 :         if (!b) {
      82           0 :                 bat_destroy(s);
      83           0 :                 goto return_nil;
      84             :         }
      85      601485 :         r = BATselect(b, s, value, NULL, true, false, false);
      86      601485 :         bat_destroy(s);
      87      601485 :         bat_destroy(b);
      88      601485 :         if (!r)
      89           0 :                 goto return_nil;
      90             :         s = r;
      91     1335079 :         while ((n = va_arg(va, sql_column *)) != NULL) {
      92      733594 :                 value = va_arg(va, void *);
      93             :                 c = n;
      94             : 
      95      733594 :                 b = full_column(tr, c);
      96      733594 :                 if (!b) {
      97           0 :                         bat_destroy(s);
      98           0 :                         goto return_nil;
      99             :                 }
     100      733594 :                 r = BATselect(b, s, value, NULL, true, false, false);
     101      733594 :                 bat_destroy(s);
     102      733594 :                 bat_destroy(b);
     103      733594 :                 if (!r)
     104           0 :                         goto return_nil;
     105             :                 s = r;
     106             :         }
     107      601485 :         va_end(va);
     108      601485 :         if (BATcount(s) == 1) {
     109      175968 :                 rid = BUNtoid(s, 0);
     110             :         }
     111      601485 :         bat_destroy(s);
     112      601485 :         return rid;
     113           0 :   return_nil:
     114           0 :         va_end(va);
     115           0 :         return oid_nil;
     116             : }
     117             : 
     118             : static void *
     119       12430 : column_find_value(sql_trans *tr, sql_column *c, oid rid)
     120             : {
     121             :         BUN q = BUN_NONE;
     122             :         BAT *b;
     123             :         void *res = NULL;
     124             : 
     125       12430 :         b = full_column(tr, c);
     126       12430 :         if (b) {
     127       12430 :                 if (rid < b->hseqbase || rid >= b->hseqbase + BATcount(b))
     128             :                         q = BUN_NONE;
     129             :                 else
     130       12430 :                         q = rid - b->hseqbase;
     131             :         }
     132       12430 :         if (q != BUN_NONE) {
     133       12430 :                 BATiter bi = bat_iterator(b);
     134             :                 const void *r;
     135             :                 size_t sz;
     136             : 
     137       12430 :                 r = BUNtail(bi, q);
     138       12430 :                 sz = ATOMlen(b->ttype, r);
     139       12430 :                 res = GDKmalloc(sz);
     140       12430 :                 if (res)
     141       12430 :                         memcpy(res, r, sz);
     142       12430 :                 bat_iterator_end(&bi);
     143             :         }
     144       12430 :         bat_destroy(b);
     145       12430 :         return res;
     146             : }
     147             : 
     148             : #define column_find_tpe(TPE) \
     149             : static TPE \
     150             : column_find_##TPE(sql_trans *tr, sql_column *c, oid rid) \
     151             : { \
     152             :         BUN q = BUN_NONE; \
     153             :         BAT *b; \
     154             :         TPE res = -1; \
     155             :  \
     156             :         b = full_column(tr, c); \
     157             :         if (b) { \
     158             :                 if (rid < b->hseqbase || rid >= b->hseqbase + BATcount(b)) \
     159             :                         q = BUN_NONE; \
     160             :                 else \
     161             :                         q = rid - b->hseqbase; \
     162             :         } \
     163             :         if (q != BUN_NONE) { \
     164             :                 BATiter bi = bat_iterator(b); \
     165             :                 res = *(TPE*)BUNtail(bi, q); \
     166             :                 bat_iterator_end(&bi); \
     167             :         } \
     168             :         bat_destroy(b); \
     169             :         return res; \
     170             : }
     171             : 
     172      184468 : column_find_tpe(sqlid)
     173      566944 : column_find_tpe(bte)
     174      540792 : column_find_tpe(int)
     175         360 : column_find_tpe(lng)
     176             : 
     177             : static str
     178      307058 : column_find_string_start(sql_trans *tr, sql_column *c, oid rid, ptr *cbat)
     179             : {
     180             :         BUN q = BUN_NONE;
     181             :         BAT **b = (BAT**) cbat;
     182             :         str res = NULL;
     183             : 
     184      307058 :         *b = full_column(tr, c);
     185      307058 :         if (*b) {
     186      307058 :                 if (rid < (*b)->hseqbase || rid >= (*b)->hseqbase + BATcount(*b))
     187             :                         q = BUN_NONE;
     188             :                 else
     189      307058 :                         q = rid - (*b)->hseqbase;
     190             :         }
     191      307058 :         if (q != BUN_NONE) {
     192      307058 :                 BATiter bi = bat_iterator(*b);
     193      307058 :                 res = (str) BUNtvar(bi, q);
     194      307058 :                 bat_iterator_end(&bi);
     195             :         }
     196      307058 :         return res;
     197             : }
     198             : 
     199             : static void
     200      307058 : column_find_string_end(ptr cbat)
     201             : {
     202             :         BAT *b = (BAT*) cbat;
     203      307058 :         bat_destroy(b);
     204      307058 : }
     205             : 
     206             : static int
     207        3400 : column_update_value(sql_trans *tr, sql_column *c, oid rid, void *value)
     208             : {
     209        3400 :         sqlstore *store = tr->store;
     210        3400 :         assert(!is_oid_nil(rid));
     211             : 
     212        3400 :         return store->storage_api.update_col(tr, c, &rid, value, c->type.type->localtype);
     213             : }
     214             : 
     215             : static int
     216     1718539 : table_insert(sql_trans *tr, sql_table *t, ...)
     217             : {
     218     1718539 :         sqlstore *store = tr->store;
     219             :         va_list va;
     220     1718539 :         node *n = ol_first_node(t->columns);
     221             :         void *val = NULL;
     222             :         int cnt = 0;
     223             :         int ok = LOG_OK;
     224     1718539 :         BUN offset = 0;
     225             : 
     226     1718539 :         va_start(va, t);
     227     1718539 :         ok = t->bootstrap?
     228     1718539 :                 store->storage_api.claim_tab(tr, t, 1, &offset, NULL):
     229       81642 :                 store->storage_api.key_claim_tab(tr, t, 1, &offset, NULL);
     230     1718539 :         if (ok != LOG_OK) {
     231           4 :                 va_end(va);
     232           4 :                 return ok;
     233             :         }
     234    15249164 :         for (; n; n = n->next) {
     235    13530629 :                 sql_column *c = n->data;
     236    13530629 :                 val = va_arg(va, void *);
     237    13530629 :                 if (!val)
     238             :                         break;
     239    13530629 :                 ok = store->storage_api.append_col(tr, c, offset, NULL, val, 1, c->type.type->localtype);
     240    13530629 :                 if (ok != LOG_OK) {
     241           0 :                         va_end(va);
     242           0 :                         return ok;
     243             :                 }
     244    13530629 :                 cnt++;
     245             :         }
     246     1718535 :         va_end(va);
     247     1718535 :         if (n) {
     248             :                 // This part of the code should never get reached
     249           0 :                 TRC_ERROR(SQL_STORE, "Called table_insert(%s) with wrong number of args (%d,%d)\n", t->base.name, ol_length(t->columns), cnt);
     250           0 :                 assert(0);
     251             :                 return LOG_ERR;
     252             :         }
     253             :         return LOG_OK;
     254             : }
     255             : 
     256             : static int
     257       71577 : table_delete(sql_trans *tr, sql_table *t, oid rid)
     258             : {
     259       71577 :         sqlstore *store = tr->store;
     260       71577 :         assert(!is_oid_nil(rid));
     261             : 
     262       71577 :         return store->storage_api.delete_tab(tr, t, &rid, TYPE_oid);
     263             : }
     264             : 
     265             : static res_table *
     266         790 : table_orderby(sql_trans *tr, sql_table *t, sql_column *jl, sql_column *jr, sql_column *jl2, sql_column *jr2, sql_column *o, ...)
     267             : {
     268             :         /* jl/jr are columns on which we first join */
     269             :         /* if also jl2,jr2, we need to do another join, where both tables differ from 't' */
     270             : 
     271             :         va_list va;
     272             :         BAT *b = NULL, *r = NULL, *cl, *cr = NULL, *cr2 = NULL, *id = NULL, *grp = NULL;
     273             :         /* if pointers are equal, make it an inclusive select */
     274             : 
     275         790 :         cl = delta_cands(tr, t);
     276         790 :         if (cl == NULL)
     277             :                 return NULL;
     278             : 
     279         790 :         if (jl && jr) {
     280         632 :                 BAT *lcb, *rcb, *r = NULL, *l = NULL;
     281             :                 gdk_return ret;
     282             : 
     283         632 :                 cr = delta_cands(tr, jr->t);
     284         632 :                 lcb = full_column(tr, jl);
     285         632 :                 rcb = full_column(tr, jr);
     286         632 :                 if (!cr || !lcb || !rcb) {
     287           0 :                         bat_destroy(cl);
     288           0 :                         bat_destroy(cr);
     289           0 :                         bat_destroy(lcb);
     290           0 :                         bat_destroy(rcb);
     291           0 :                         return NULL;
     292             :                 }
     293             : 
     294         632 :                 ret = BATjoin(&l, &r, lcb, rcb, cl, cr, false, BATcount(lcb));
     295         632 :                 bat_destroy(cl);
     296         632 :                 bat_destroy(cr);
     297         632 :                 bat_destroy(lcb);
     298         632 :                 bat_destroy(rcb);
     299         632 :                 if (ret != GDK_SUCCEED)
     300             :                         return NULL;
     301         632 :                 cl = l;
     302         632 :                 cr = r;
     303             :         }
     304             :         /* we assume 1->n joins, therefore first join between jl2/jr2 */
     305         790 :         if (jl2 && jr2) {
     306         237 :                 assert(jr->t == jl2->t);
     307         237 :                 BAT *lcb, *rcb, *r = NULL, *l = NULL;
     308             :                 gdk_return ret;
     309             : 
     310         237 :                 cr2 = delta_cands(tr, jr2->t);
     311         237 :                 lcb = full_column(tr, jl2);
     312         237 :                 rcb = full_column(tr, jr2);
     313         237 :                 if (!cr2 || !lcb || !rcb) {
     314           0 :                         bat_destroy(cl);
     315           0 :                         bat_destroy(cr);
     316           0 :                         bat_destroy(cr2);
     317           0 :                         bat_destroy(lcb);
     318           0 :                         bat_destroy(rcb);
     319           0 :                         return NULL;
     320             :                 }
     321             : 
     322         237 :                 l = BATproject(cr, lcb); /* project because cr is join result */
     323         237 :                 bat_destroy(lcb);
     324         237 :                 lcb = l;
     325         237 :                 ret = BATjoin(&l, &r, lcb, rcb, NULL, cr2, false, BATcount(lcb));
     326         237 :                 bat_destroy(cr2);
     327         237 :                 bat_destroy(lcb);
     328         237 :                 bat_destroy(rcb);
     329         237 :                 if (ret != GDK_SUCCEED) {
     330           0 :                         bat_destroy(cl);
     331           0 :                         bat_destroy(cr);
     332           0 :                         return NULL;
     333             :                 }
     334         237 :                 lcb = BATproject(l, cl);
     335         237 :                 rcb = BATproject(l, cr);
     336         237 :                 bat_destroy(l);
     337         237 :                 bat_destroy(cl);
     338         237 :                 bat_destroy(cr);
     339         237 :                 if (!lcb || !rcb) {
     340           0 :                         bat_destroy(lcb);
     341           0 :                         bat_destroy(rcb);
     342           0 :                         bat_destroy(r);
     343           0 :                         return NULL;
     344             :                 }
     345             :                 cl = lcb;
     346             :                 cr = rcb;
     347         237 :                 cr2 = r;
     348             :         }
     349             : 
     350         790 :         va_start(va, o);
     351             :         do {
     352        2291 :                 BAT *nid = NULL, *ngrp = NULL;
     353        2291 :                 sql_column *next = va_arg(va, sql_column *);
     354             : 
     355        2291 :                 b = full_column(tr, o);
     356        2291 :                 if (b)
     357        2923 :                         r = BATproject( (o->t==t) ? cl : (cr2 && o->t==jr2->t) ? cr2 : cr, b);
     358        2291 :                 bat_destroy(b);
     359        2291 :                 if (!b || !r) {
     360           0 :                         bat_destroy(cl);
     361           0 :                         bat_destroy(cr);
     362           0 :                         bat_destroy(cr2);
     363           0 :                         va_end(va);
     364           0 :                         return NULL;
     365             :                 }
     366             :                 /* (sub)order b */
     367        3081 :                 if (BATsort(NULL, &nid, next?&ngrp:NULL, r, id, grp, false, false, false) != GDK_SUCCEED) {
     368           0 :                         bat_destroy(r);
     369           0 :                         bat_destroy(id);
     370           0 :                         bat_destroy(grp);
     371           0 :                         bat_destroy(cl);
     372           0 :                         bat_destroy(cr);
     373           0 :                         bat_destroy(cr2);
     374           0 :                         va_end(va);
     375           0 :                         return NULL;
     376             :                 }
     377        2291 :                 bat_destroy(r);
     378        2291 :                 bat_destroy(id);
     379        2291 :                 bat_destroy(grp);
     380        2291 :                 id = nid;
     381        2291 :                 grp = ngrp;
     382             :                 o = next;
     383        2291 :         } while (o);
     384         790 :         bat_destroy(grp);
     385         790 :         va_end(va);
     386             : 
     387         790 :         r = BATproject(id, cl);
     388         790 :         bat_destroy(id);
     389         790 :         bat_destroy(cl);
     390         790 :         bat_destroy(cr);
     391         790 :         bat_destroy(cr2);
     392             :         cl = r;
     393             :         /* project all in the new order */
     394         790 :         res_table *rt = res_table_create(tr, 1/*result_id*/, 1/*query_id*/, ol_length(t->columns), Q_TABLE, NULL, NULL);
     395         790 :         if (!rt) {
     396           0 :                 bat_destroy(cl);
     397           0 :                 return NULL;
     398             :         }
     399         790 :         rt->nr_rows = BATcount(cl);
     400        5530 :         for (node *n = ol_first_node(t->columns); n; n = n->next) {
     401             :                 BAT *rc = NULL;
     402             : 
     403        4740 :                 o = n->data;
     404        4740 :                 b = full_column(tr, o);
     405        4740 :                 if (b)
     406        4740 :                         rc = BATproject(cl, b);
     407        4740 :                 bat_destroy(b);
     408        4740 :                 if (!b || !rc) {
     409           0 :                         bat_destroy(cl);
     410           0 :                         bat_destroy(b);
     411           0 :                         res_table_destroy(rt);
     412           0 :                         return NULL;
     413             :                 }
     414        4740 :                 if (!res_col_create(tr, rt, t->base.name, o->base.name, o->type.type->base.name, o->type.type->digits, o->type.type->scale, TYPE_bat, rc, true)) {
     415           0 :                         bat_destroy(cl);
     416           0 :                         res_table_destroy(rt);
     417           0 :                         return NULL;
     418             :                 }
     419             :         }
     420         790 :         bat_destroy(cl);
     421         790 :         return rt;
     422             : }
     423             : 
     424             : static void *
     425      601663 : table_fetch_value(res_table *rt, sql_column *c)
     426             : {
     427             :         /* this function is only ever called during startup, and therefore
     428             :          * there are no other threads that may be modifying the BAT under
     429             :          * our hands, so returning a pointer into the heap is fine */
     430      601663 :         BAT *b = (BAT*)rt->cols[c->colnr].p;
     431      601663 :         BATiter bi = bat_iterator_nolock(b);
     432      601663 :         assert(b->ttype && b->ttype != TYPE_msk);
     433      601663 :         if (b->tvarsized)
     434      212002 :                 return BUNtvar(bi, rt->cur_row);
     435      389661 :         return Tloc(b, rt->cur_row);
     436             :         //return (void*)BUNtail(bi, rt->cur_row);
     437             : }
     438             : 
     439             : static void
     440         790 : table_result_destroy(res_table *rt)
     441             : {
     442         790 :         if (rt)
     443         790 :                 res_table_destroy(rt);
     444         790 : }
     445             : 
     446             : /* returns table rids, for the given select ranges */
     447             : static rids *
     448       87520 : rids_select( sql_trans *tr, sql_column *key, const void *key_value_low, const void *key_value_high, ...)
     449             : {
     450             :         va_list va;
     451             :         BAT *b = NULL, *r = NULL, *s = NULL;
     452       87520 :         rids *rs = MNEW(rids);
     453             :         const void *kvl = key_value_low, *kvh = key_value_high;
     454             :         /* if pointers are equal, make it an inclusive select */
     455       87520 :         bool hi = key_value_low == key_value_high;
     456             : 
     457       87520 :         if(!rs)
     458             :                 return NULL;
     459       87520 :         s = delta_cands(tr, key->t);
     460       87520 :         if (s == NULL) {
     461           0 :                 GDKfree(rs);
     462           0 :                 return NULL;
     463             :         }
     464       87520 :         b = full_column(tr, key);
     465       87520 :         if (b == NULL) {
     466           0 :                 bat_destroy(s);
     467           0 :                 GDKfree(rs);
     468           0 :                 return NULL;
     469             :         }
     470       87520 :         if (!kvl)
     471         186 :                 kvl = ATOMnilptr(b->ttype);
     472       87520 :         if (!kvh && kvl != ATOMnilptr(b->ttype))
     473             :                 kvh = ATOMnilptr(b->ttype);
     474       87520 :         if (key_value_low) {
     475       87334 :                 BAThash(b);
     476       87334 :                 r = BATselect(b, s, kvl, kvh, true, hi, false);
     477       87334 :                 bat_destroy(s);
     478             :                 s = r;
     479             :         }
     480       87520 :         bat_destroy(b);
     481       87520 :         if (s == NULL) {
     482           0 :                 GDKfree(rs);
     483           0 :                 return NULL;
     484             :         }
     485       87520 :         if (key_value_low || key_value_high) {
     486       87334 :                 va_start(va, key_value_high);
     487       89701 :                 while ((key = va_arg(va, sql_column *)) != NULL) {
     488        2367 :                         kvl = va_arg(va, void *);
     489        2367 :                         kvh = va_arg(va, void *);
     490             : 
     491        2367 :                         b = full_column(tr, key);
     492        2367 :                         if (b == NULL) {
     493           0 :                                 bat_destroy(s);
     494           0 :                                 GDKfree(rs);
     495           0 :                                 va_end(va);
     496           0 :                                 return NULL;
     497             :                         }
     498        2367 :                         if (!kvl)
     499           0 :                                 kvl = ATOMnilptr(b->ttype);
     500        2367 :                         if (!kvh && kvl != ATOMnilptr(b->ttype))
     501             :                                 kvh = ATOMnilptr(b->ttype);
     502        2367 :                         assert(kvh);
     503        2367 :                         r = BATselect(b, s, kvl, kvh, true, hi, false);
     504        2367 :                         bat_destroy(s);
     505             :                         s = r;
     506        2367 :                         bat_destroy(b);
     507        2367 :                         if (s == NULL) {
     508           0 :                                 GDKfree(rs);
     509           0 :                                 va_end(va);
     510           0 :                                 return NULL;
     511             :                         }
     512             :                 }
     513       87334 :                 va_end(va);
     514             :         }
     515       87520 :         *rs = (rids) {
     516             :                 .data = s,
     517             :         };
     518       87520 :         return rs;
     519             : }
     520             : 
     521             : /* order rids by orderby_column values */
     522             : static rids *
     523          75 : rids_orderby(sql_trans *tr, rids *r, sql_column *orderby_col)
     524             : {
     525             :         BAT *b, *s, *o;
     526             : 
     527          75 :         b = full_column(tr, orderby_col);
     528          75 :         if (!b)
     529             :                 return NULL;
     530          75 :         s = BATproject(r->data, b);
     531          75 :         bat_destroy(b);
     532          75 :         if (s == NULL)
     533             :                 return NULL;
     534          75 :         if (BATsort(NULL, &o, NULL, s, NULL, NULL, false, false, false) != GDK_SUCCEED) {
     535           0 :                 bat_destroy(s);
     536           0 :                 return NULL;
     537             :         }
     538          75 :         bat_destroy(s);
     539          75 :         s = BATproject(o, r->data);
     540          75 :         bat_destroy(o);
     541          75 :         if (s == NULL)
     542             :                 return NULL;
     543          75 :         bat_destroy(r->data);
     544          75 :         r->data = s;
     545          75 :         return r;
     546             : }
     547             : 
     548             : 
     549             : /* return table rids from result of rids_select, return (oid_nil) when done */
     550             : static oid
     551      122043 : rids_next(rids *r)
     552             : {
     553      122043 :         if (r->cur < BATcount((BAT *) r->data)) {
     554             :                 BAT *t = r->data;
     555             : 
     556       34744 :                 if (t && (t->ttype == TYPE_msk || mask_cand(t))) {
     557           0 :                         r->data = BATunmask(t);
     558           0 :                         if (!r->data) {
     559           0 :                                 r->data = t;
     560           0 :                                 return oid_nil;
     561             :                         }
     562           0 :                         bat_destroy(t);
     563             :                 }
     564       34744 :                 return BUNtoid((BAT *) r->data, r->cur++);
     565             :         }
     566       87299 :         return oid_nil;
     567             : }
     568             : 
     569             : /* clean up the resources taken by the result of rids_select */
     570             : static void
     571       87520 : rids_destroy(rids *r)
     572             : {
     573       87520 :         bat_destroy(r->data);
     574       87520 :         _DELETE(r);
     575       87520 : }
     576             : 
     577             : static int
     578         575 : rids_empty(rids *r )
     579             : {
     580         575 :         BAT *b = r->data;
     581         575 :         return BATcount(b) <= 0;
     582             : }
     583             : 
     584             : static rids *
     585           0 : rids_join(sql_trans *tr, rids *l, sql_column *lc, rids *r, sql_column *rc)
     586             : {
     587           0 :         BAT *lcb, *rcb, *s = NULL;
     588             :         gdk_return ret;
     589             : 
     590           0 :         lcb = full_column(tr, lc);
     591           0 :         rcb = full_column(tr, rc);
     592           0 :         if (!lcb || !rcb) {
     593           0 :                 bat_destroy(l->data);
     594           0 :                 l->data = NULL;
     595           0 :                 bat_destroy(lcb);
     596           0 :                 bat_destroy(rcb);
     597           0 :                 return NULL;
     598             :         }
     599           0 :         ret = BATjoin(&s, NULL, lcb, rcb, l->data, r->data, false, BATcount(lcb));
     600           0 :         bat_destroy(l->data);
     601           0 :         if (ret != GDK_SUCCEED) {
     602           0 :                 l->data = NULL;
     603             :         } else {
     604           0 :                 l->data = s;
     605             :         }
     606           0 :         bat_destroy(lcb);
     607           0 :         bat_destroy(rcb);
     608           0 :         return l;
     609             : }
     610             : 
     611             : static subrids *
     612         493 : subrids_create(sql_trans *tr, rids *t1, sql_column *rc, sql_column *lc, sql_column *obc)
     613             : {
     614             :         /* join t1.rc with lc order by obc */
     615             :         subrids *r;
     616         493 :         BAT *lcb, *rcb, *s, *obb, *o, *g, *ids, *rids = NULL;
     617             :         gdk_return ret;
     618             : 
     619         493 :         lcb = full_column(tr, lc);
     620         493 :         rcb = full_column(tr, rc);
     621         493 :         s = delta_cands(tr, lc->t);
     622         493 :         if (lcb == NULL || rcb == NULL || s == NULL) {
     623           0 :                 bat_destroy(lcb);
     624           0 :                 bat_destroy(rcb);
     625           0 :                 bat_destroy(s);
     626           0 :                 return NULL;
     627             :         }
     628             : 
     629         493 :         ret = BATjoin(&rids, NULL, lcb, rcb, s, t1->data, false, BATcount(lcb));
     630         493 :         bat_destroy(s);
     631         493 :         bat_destroy(rcb);
     632         493 :         if (ret != GDK_SUCCEED) {
     633           0 :                 bat_destroy(lcb);
     634           0 :                 return NULL;
     635             :         }
     636             : 
     637         493 :         s = BATproject(rids, lcb);
     638         493 :         bat_destroy(lcb);
     639         493 :         if (s == NULL) {
     640           0 :                 bat_destroy(rids);
     641           0 :                 return NULL;
     642             :         }
     643             :         lcb = s;
     644             : 
     645         493 :         if ((obb = full_column(tr, obc)) == NULL) {
     646           0 :                 bat_destroy(lcb);
     647           0 :                 bat_destroy(rids);
     648           0 :                 return NULL;
     649             :         }
     650         493 :         s = BATproject(rids, obb);
     651         493 :         bat_destroy(obb);
     652         493 :         if (s == NULL) {
     653           0 :                 bat_destroy(lcb);
     654           0 :                 bat_destroy(rids);
     655           0 :                 return NULL;
     656             :         }
     657             :         obb = s;
     658             : 
     659             :         /* need id, obc */
     660         493 :         ids = o = g = NULL;
     661         493 :         ret = BATsort(&ids, &o, &g, lcb, NULL, NULL, false, false, false);
     662         493 :         bat_destroy(lcb);
     663         493 :         if (ret != GDK_SUCCEED) {
     664           0 :                 bat_destroy(obb);
     665           0 :                 bat_destroy(rids);
     666           0 :                 return NULL;
     667             :         }
     668             : 
     669         493 :         s = NULL;
     670         493 :         ret = BATsort(NULL, &s, NULL, obb, o, g, false, false, false);
     671         493 :         bat_destroy(obb);
     672         493 :         bat_destroy(o);
     673         493 :         bat_destroy(g);
     674         493 :         if (ret != GDK_SUCCEED) {
     675           0 :                 bat_destroy(ids);
     676           0 :                 bat_destroy(rids);
     677           0 :                 return NULL;
     678             :         }
     679             : 
     680         493 :         o = BATproject(s, rids);
     681         493 :         bat_destroy(rids);
     682         493 :         bat_destroy(s);
     683         493 :         if (o == NULL) {
     684           0 :                 bat_destroy(ids);
     685           0 :                 return NULL;
     686             :         }
     687         493 :         rids = o;
     688             : 
     689         493 :         assert(ids->ttype == TYPE_int && ATOMtype(rids->ttype) == TYPE_oid);
     690         493 :         r = MNEW(subrids);
     691         493 :         if (r == NULL) {
     692           0 :                 bat_destroy(ids);
     693           0 :                 bat_destroy(rids);
     694           0 :                 return NULL;
     695             :         }
     696         493 :         *r = (subrids) {
     697             :                 .ids = ids,
     698             :                 .rids = rids,
     699             :         };
     700         493 :         return r;
     701             : }
     702             : 
     703             : static oid
     704      133039 : subrids_next(subrids *r)
     705             : {
     706      133039 :         if (r->pos < BATcount((BAT *) r->ids)) {
     707      132546 :                 BATiter ii = bat_iterator((BAT *) r->ids);
     708      132546 :                 sqlid id = *(sqlid*)BUNtloc(ii, r->pos);
     709      132546 :                 bat_iterator_end(&ii);
     710      132546 :                 if (id == r->id)
     711       97668 :                         return BUNtoid((BAT *) r->rids, r->pos++);
     712             :         }
     713       35371 :         return oid_nil;
     714             : }
     715             : 
     716             : static sqlid
     717       35864 : subrids_nextid(subrids *r)
     718             : {
     719       35864 :         if (r->pos < BATcount((BAT *) r->ids)) {
     720       35371 :                 BATiter ii = bat_iterator((BAT *) r->ids);
     721       35371 :                 r->id = *(sqlid*)BUNtloc(ii, r->pos);
     722       35371 :                 bat_iterator_end(&ii);
     723       35371 :                 return r->id;
     724             :         }
     725             :         return -1;
     726             : }
     727             : 
     728             : static void
     729         493 : subrids_destroy(subrids *r )
     730             : {
     731         493 :         bat_destroy(r->ids);
     732         493 :         bat_destroy(r->rids);
     733         493 :         _DELETE(r);
     734         493 : }
     735             : 
     736             : /* get the non - join results */
     737             : static rids *
     738         493 : rids_diff(sql_trans *tr, rids *l, sql_column *lc, subrids *r, sql_column *rc )
     739             : {
     740         493 :         BAT *lcb = full_column(tr, lc), *s, *rids, *diff;
     741         493 :         BAT *rcb = full_column(tr, rc);
     742             :         gdk_return ret;
     743             : 
     744         493 :         if (lcb == NULL || rcb == NULL) {
     745           0 :                 bat_destroy(lcb);
     746           0 :                 bat_destroy(rcb);
     747           0 :                 return NULL;
     748             :         }
     749         493 :         s = BATproject(r->rids, rcb);
     750         493 :         bat_destroy(rcb);
     751         493 :         if (s == NULL) {
     752           0 :                 bat_destroy(lcb);
     753           0 :                 return NULL;
     754             :         }
     755             :         rcb = s;
     756             : 
     757         493 :         s = BATproject(l->data, lcb);
     758         493 :         if (s == NULL) {
     759           0 :                 bat_destroy(lcb);
     760           0 :                 bat_destroy(rcb);
     761           0 :                 return NULL;
     762             :         }
     763             : 
     764         493 :         diff = BATdiff(s, rcb, NULL, NULL, false, false, BUN_NONE);
     765         493 :         bat_destroy(rcb);
     766         493 :         if (diff == NULL) {
     767           0 :                 bat_destroy(lcb);
     768           0 :                 bat_destroy(s);
     769           0 :                 return NULL;
     770             :         }
     771             : 
     772         493 :         ret = BATjoin(&rids, NULL, lcb, s, NULL, diff, false, BATcount(s));
     773         493 :         bat_destroy(diff);
     774         493 :         bat_destroy(lcb);
     775         493 :         bat_destroy(s);
     776         493 :         if (ret != GDK_SUCCEED)
     777             :                 return NULL;
     778             : 
     779         493 :         bat_destroy(l->data);
     780         493 :         l->data = rids;
     781         493 :         return l;
     782             : }
     783             : 
     784             : void
     785         266 : bat_table_init( table_functions *tf )
     786             : {
     787         266 :         tf->column_find_row = column_find_row;
     788         266 :         tf->column_find_value = column_find_value;
     789         266 :         tf->column_find_sqlid = column_find_sqlid;
     790         266 :         tf->column_find_bte = column_find_bte;
     791         266 :         tf->column_find_int = column_find_int;
     792         266 :         tf->column_find_lng = column_find_lng;
     793         266 :         tf->column_find_string_start = column_find_string_start; /* this function returns a pointer to the heap, use it with care! */
     794         266 :         tf->column_find_string_end = column_find_string_end; /* don't forget to call this function to unfix the bat descriptor! */
     795         266 :         tf->column_update_value = column_update_value;
     796         266 :         tf->table_insert = table_insert;
     797         266 :         tf->table_delete = table_delete;
     798         266 :         tf->table_orderby = table_orderby;
     799         266 :         tf->table_fetch_value = table_fetch_value;
     800         266 :         tf->table_result_destroy = table_result_destroy;
     801             : 
     802         266 :         tf->rids_select = rids_select;
     803         266 :         tf->rids_orderby = rids_orderby;
     804         266 :         tf->rids_join = rids_join;
     805         266 :         tf->rids_next = rids_next;
     806         266 :         tf->rids_destroy = rids_destroy;
     807         266 :         tf->rids_empty = rids_empty;
     808             : 
     809         266 :         tf->subrids_create = subrids_create;
     810         266 :         tf->subrids_next = subrids_next;
     811         266 :         tf->subrids_nextid = subrids_nextid;
     812         266 :         tf->subrids_destroy = subrids_destroy;
     813         266 :         tf->rids_diff = rids_diff;
     814         266 : }

Generated by: LCOV version 1.14