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 "res_table.h"
15 : #include "bat_utils.h"
16 : #include "sql_types.h"
17 :
18 : static void
19 277508 : bat_incref(bat bid)
20 : {
21 277508 : BBPretain(bid);
22 277514 : }
23 :
24 : static void
25 277513 : bat_decref(bat bid)
26 : {
27 277513 : BBPrelease(bid);
28 277515 : }
29 :
30 : res_table *
31 126164 : res_table_create(sql_trans *tr, int res_id, oid query_id, int nr_cols, mapi_query_t type, res_table *next)
32 : {
33 126164 : res_table *t = MNEW(res_table);
34 126164 : res_col *tcols = ZNEW_ARRAY(res_col, nr_cols);
35 :
36 126164 : (void) tr;
37 126164 : if (!t || !tcols) {
38 0 : _DELETE(t);
39 0 : _DELETE(tcols);
40 0 : return NULL;
41 : }
42 :
43 126164 : *t = (res_table) {
44 : .id = res_id,
45 : .query_id = query_id,
46 : .query_type = type,
47 : .cols = tcols,
48 : .nr_cols = nr_cols,
49 : .next = next,
50 : };
51 :
52 126164 : return t;
53 : }
54 :
55 : res_col *
56 346440 : res_col_create(sql_trans *tr, res_table *t, const char *tn, const char *name, const char *typename, int digits, int scale, bool isbat, char mtype, void *val, bool cached)
57 : {
58 346440 : res_col *c = t->cols + t->cur_col;
59 346440 : BAT *b;
60 :
61 346440 : if (!sql_find_subtype(&c->type, typename, digits, scale))
62 343 : sql_init_subtype(&c->type, sql_trans_bind_type(tr, NULL, typename), digits, scale);
63 346444 : c->tn = _STRDUP(tn);
64 346451 : c->name = _STRDUP(name);
65 346450 : if (c->tn == NULL || c->name == NULL) {
66 0 : _DELETE(c->tn);
67 0 : _DELETE(c->name);
68 0 : return NULL;
69 : }
70 346450 : c->b = 0;
71 346450 : c->p = NULL;
72 346450 : c->mtype = mtype;
73 346450 : if (isbat) {
74 285034 : b = (BAT*)val;
75 285034 : if (b && t->cur_col == 0)
76 65438 : t->nr_rows = BATcount(b);
77 : } else { // wrap scalar values in BATs for result consistency
78 61416 : b = COLnew(0, mtype, 1, TRANSIENT);
79 61416 : if (b == NULL) {
80 0 : _DELETE(c->tn);
81 0 : _DELETE(c->name);
82 0 : return NULL;
83 : }
84 61416 : 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 61416 : if (t->cur_col == 0)
91 60726 : t->nr_rows = 1;
92 : cached = true; /* simply keep memory pointer for this small bat */
93 : }
94 346450 : c->b = b->batCacheid;
95 346450 : c->cached = cached;
96 346450 : if (cached)
97 68942 : c->p = (void*)b;
98 : else
99 277508 : bat_incref(c->b);
100 346456 : t->cur_col++;
101 346456 : assert(t->cur_col <= t->nr_cols);
102 : return c;
103 : }
104 :
105 : static void
106 346455 : res_col_destroy(res_col *c)
107 : {
108 346455 : if (c->b && !c->cached) {
109 277513 : bat_decref(c->b);
110 68942 : } else if (c->b) {
111 68942 : bat_destroy((BAT*)c->p);
112 : } else {
113 0 : _DELETE(c->p);
114 : }
115 346457 : _DELETE(c->name);
116 346457 : _DELETE(c->tn);
117 346457 : }
118 :
119 : void
120 126164 : res_table_destroy(res_table *t)
121 : {
122 126164 : int i;
123 :
124 472621 : for (i = 0; i < t->nr_cols; i++) {
125 346457 : res_col *c = t->cols + i;
126 :
127 346457 : if (c)
128 346457 : res_col_destroy(c);
129 : }
130 126164 : _DELETE(t->cols);
131 126164 : _DELETE(t);
132 126164 : }
133 :
134 : res_table *
135 123521 : res_tables_remove(res_table *results, res_table *t)
136 : {
137 123521 : res_table *r = results;
138 :
139 123521 : if (r == t) {
140 123521 : results = t->next;
141 : } else {
142 0 : for (; r; r = r->next) {
143 0 : if (r->next == t) {
144 0 : r->next = t->next;
145 0 : break;
146 : }
147 : }
148 : }
149 123521 : res_table_destroy(t);
150 123521 : return results;
151 : }
152 :
153 : void
154 37545 : res_tables_destroy(res_table *tab)
155 : {
156 37545 : if (tab) {
157 178 : res_table *r = tab, *t;
158 :
159 178 : for (t = r; t; t = r) {
160 145 : r = t->next;
161 145 : res_table_destroy(t);
162 : }
163 : }
164 37545 : }
165 :
166 : res_table *
167 253762 : res_tables_find(res_table *results, int res_id)
168 : {
169 253762 : res_table *r = results;
170 :
171 267441 : for (; r; r = r->next) {
172 263466 : if (r->id == res_id)
173 249787 : return r;
174 : }
175 : return NULL;
176 : }
|