LCOV - code coverage report
Current view: top level - sql/storage/bat - res_table.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 70 92 76.1 %
Date: 2021-10-13 02:24:04 Functions: 7 7 100.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 "res_table.h"
      11             : #include "bat_utils.h"
      12             : #include "sql_types.h"
      13             : 
      14             : static void
      15             : bat_incref(bat bid)
      16             : {
      17      222135 :         BBPretain(bid);
      18      222135 : }
      19             : 
      20             : static void
      21             : bat_decref(bat bid)
      22             : {
      23      300110 :         BBPrelease(bid);
      24      300110 : }
      25             : 
      26             : res_table *
      27       78765 : res_table_create(sql_trans *tr, int res_id, oid query_id, int nr_cols, mapi_query_t type, res_table *next, void *O)
      28             : {
      29             :         BAT *order = (BAT*)O;
      30       78765 :         res_table *t = MNEW(res_table);
      31       78765 :         res_col *tcols = ZNEW_ARRAY(res_col, nr_cols);
      32             : 
      33             :         (void) tr;
      34       78765 :         if (!t || !tcols) {
      35           0 :                 _DELETE(t);
      36           0 :                 _DELETE(tcols);
      37           0 :                 return NULL;
      38             :         }
      39             : 
      40       78765 :         *t = (res_table) {
      41             :                 .id = res_id,
      42             :                 .query_id = query_id,
      43             :                 .query_type = type,
      44             :                 .cols = tcols,
      45             :                 .nr_cols = nr_cols,
      46             :                 .next = next,
      47             :         };
      48             : 
      49       78765 :         if (order) {
      50       49659 :                 t->order = order->batCacheid;
      51             :                 bat_incref(t->order);
      52       49659 :                 t->nr_rows = BATcount(order);
      53             :         }
      54             :         return t;
      55             : }
      56             : 
      57             : res_col *
      58      255741 : res_col_create(sql_trans *tr, res_table *t, const char *tn, const char *name, const char *typename, int digits, int scale, char mtype, void *val, bool cached)
      59             : {
      60      255741 :         res_col *c = t->cols + t->cur_col;
      61             :         BAT *b;
      62             : 
      63      255741 :         if (!sql_find_subtype(&c->type, typename, digits, scale))
      64         321 :                 sql_init_subtype(&c->type, sql_trans_bind_type(tr, NULL, typename), digits, scale);
      65      255741 :         c->tn = _STRDUP(tn);
      66      255741 :         c->name = _STRDUP(name);
      67      255741 :         if (c->tn == NULL || c->name == NULL) {
      68           0 :                 _DELETE(c->tn);
      69           0 :                 _DELETE(c->name);
      70           0 :                 return NULL;
      71             :         }
      72      255741 :         c->b = 0;
      73      255741 :         c->p = NULL;
      74      255741 :         c->mtype = mtype;
      75      255741 :         if (mtype == TYPE_bat) {
      76             :                 b = (BAT*)val;
      77             :         } else { // wrap scalar values in BATs for result consistency
      78       28866 :                 b = COLnew(0, mtype, 1, TRANSIENT);
      79       28866 :                 if (b == NULL) {
      80           0 :                         _DELETE(c->tn);
      81           0 :                         _DELETE(c->name);
      82           0 :                         return NULL;
      83             :                 }
      84       28866 :                 if (BUNappend(b, val, false) != GDK_SUCCEED) {
      85           0 :                         BBPreclaim(b);
      86           0 :                         _DELETE(c->tn);
      87           0 :                         _DELETE(c->name);
      88           0 :                         return NULL;
      89             :                 }
      90             :                 /* we need to set the order bat otherwise mvc_export_result won't work with single-row result sets containing BATs */
      91       28866 :                 if (!t->order) {
      92       28316 :                         oid zero = 0;
      93       28316 :                         BAT *o = BATconstant(0, TYPE_oid, &zero, 1, TRANSIENT);
      94       28316 :                         if (o == NULL) {
      95           0 :                                 BBPreclaim(b);
      96           0 :                                 _DELETE(c->tn);
      97           0 :                                 _DELETE(c->name);
      98           0 :                                 return NULL;
      99             :                         }
     100       28316 :                         t->order = o->batCacheid;
     101       28316 :                         t->nr_rows = 1;
     102       28316 :                         BBPkeepref(t->order);
     103             :                 }
     104             :                 cached = true; /* simply keep memory pointer for this small bat */
     105             :         }
     106      255741 :         c->b = b->batCacheid;
     107      255741 :         c->cached = cached;
     108      255741 :         if (cached)
     109       33606 :                 c->p = (void*)b;
     110             :         else
     111             :                 bat_incref(c->b);
     112      255741 :         t->cur_col++;
     113      255741 :         assert(t->cur_col <= t->nr_cols);
     114             :         return c;
     115             : }
     116             : 
     117             : static void
     118      255741 : res_col_destroy(res_col *c)
     119             : {
     120      255741 :         if (c->b && !c->cached) {
     121             :                 bat_decref(c->b);
     122       33606 :         } else if (c->b) {
     123       33606 :                 bat_destroy((BAT*)c->p);
     124             :         } else {
     125           0 :                 _DELETE(c->p);
     126             :         }
     127      255741 :         _DELETE(c->name);
     128      255741 :         _DELETE(c->tn);
     129      255741 : }
     130             : 
     131             : void
     132       78765 : res_table_destroy(res_table *t)
     133             : {
     134             :         int i;
     135             : 
     136      334506 :         for (i = 0; i < t->nr_cols; i++) {
     137      255741 :                 res_col *c = t->cols + i;
     138             : 
     139      255741 :                 if (c)
     140      255741 :                         res_col_destroy(c);
     141             :         }
     142       78765 :         if (t->order)
     143             :                 bat_decref(t->order);
     144       78765 :         _DELETE(t->cols);
     145       78765 :         _DELETE(t);
     146       78765 : }
     147             : 
     148             : res_table *
     149       76947 : res_tables_remove(res_table *results, res_table *t)
     150             : {
     151             :         res_table *r = results;
     152             : 
     153       76947 :         if (r == t) {
     154       76947 :                 results = t->next;
     155             :         } else {
     156           0 :                 for (; r; r = r->next) {
     157           0 :                         if (r->next == t) {
     158           0 :                                 r->next = t->next;
     159           0 :                                 break;
     160             :                         }
     161             :                 }
     162             :         }
     163       76947 :         res_table_destroy(t);
     164       76947 :         return results;
     165             : }
     166             : 
     167             : void
     168        5388 : res_tables_destroy(res_table *tab)
     169             : {
     170        5388 :         if (tab) {
     171             :                 res_table *r = tab, *t;
     172             : 
     173         758 :                 for (t = r; t; t = r) {
     174         663 :                         r = t->next;
     175         663 :                         res_table_destroy(t);
     176             :                 }
     177             :         }
     178        5388 : }
     179             : 
     180             : res_table *
     181      163012 : res_tables_find(res_table *results, int res_id)
     182             : {
     183             :         res_table *r = results;
     184             : 
     185      163012 :         for (; r; r = r->next) {
     186      163000 :                 if (r->id == res_id)
     187      163000 :                         return r;
     188             :         }
     189             :         return NULL;
     190             : }

Generated by: LCOV version 1.14