LCOV - code coverage report
Current view: top level - sql/storage/bat - bat_table.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 421 560 75.2 %
Date: 2024-12-20 21:24:02 Functions: 29 30 96.7 %

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

Generated by: LCOV version 1.14