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, 2025 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 283607 : bat_incref(bat bid)
20 : {
21 283607 : BBPretain(bid);
22 283612 : }
23 :
24 : static void
25 283603 : bat_decref(bat bid)
26 : {
27 283603 : BBPrelease(bid);
28 283611 : }
29 :
30 : res_table *
31 129952 : res_table_create(sql_trans *tr, int res_id, oid query_id, int nr_cols, mapi_query_t type, res_table *next)
32 : {
33 129952 : res_table *t = MNEW(res_table);
34 129959 : res_col *tcols = ZNEW_ARRAY(res_col, nr_cols);
35 :
36 129959 : (void) tr;
37 129959 : if (!t || !tcols) {
38 0 : _DELETE(t);
39 0 : _DELETE(tcols);
40 0 : return NULL;
41 : }
42 :
43 129959 : *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 : .nr_rows = BUN_NONE,
51 : .output_col = 0,
52 : };
53 :
54 129959 : return t;
55 : }
56 :
57 : res_col *
58 355976 : res_col_create(sql_trans *tr, res_table *t, const char *tn, const char *name, const char *typename, int digits, int scale, int multiset, bool isbat, char mtype, void *val, bool cached)
59 : {
60 355976 : res_col *c = t->cols + t->cur_col;
61 355976 : BAT *b;
62 :
63 355976 : if (!sql_find_subtype(&c->type, typename, digits, scale))
64 394 : sql_init_subtype(&c->type, sql_trans_bind_type(tr, NULL, typename), digits, scale);
65 355973 : c->nrfields = 1;
66 355973 : c->virt = (multiset&4)?true:false;
67 355973 : c->type.multiset = multiset&3;
68 355973 : c->multiset = c->type.multiset;
69 355973 : c->composite = c->type.type->composite;
70 355973 : t->complex_type = (t->complex_type || c->virt || c->composite || (c->multiset != MS_VALUE));
71 :
72 355973 : c->tn = _STRDUP(tn);
73 355974 : c->name = _STRDUP(name);
74 355979 : if (c->tn == NULL || c->name == NULL) {
75 0 : _DELETE(c->tn);
76 0 : _DELETE(c->name);
77 0 : return NULL;
78 : }
79 355979 : c->b = 0;
80 355979 : c->p = NULL;
81 355979 : c->mtype = mtype;
82 355979 : if (isbat) {
83 292880 : b = (BAT*)val;
84 292880 : if (b && t->nr_rows == BUN_NONE && !c->virt && t->cur_col == t->output_col)
85 67619 : t->nr_rows = BATcount(b);
86 : /*
87 : else if (c->virt) {
88 : if (c->multiset && c->type.type->composite)
89 : t->output_col = c->multiset + c->type.type->composite + 1;
90 : else if (c->multiset)
91 : t->output_col = c->multiset + 2;
92 : else
93 : t->output_col++;
94 : }
95 : */
96 : } else { // wrap scalar values in BATs for result consistency
97 63099 : b = COLnew(0, mtype, 1, TRANSIENT);
98 63100 : if (b == NULL) {
99 0 : _DELETE(c->tn);
100 0 : _DELETE(c->name);
101 0 : return NULL;
102 : }
103 63100 : if (BUNappend(b, val, false) != GDK_SUCCEED) {
104 0 : BBPreclaim(b);
105 0 : _DELETE(c->tn);
106 0 : _DELETE(c->name);
107 0 : return NULL;
108 : }
109 63098 : if (t->nr_rows == BUN_NONE && !c->virt)
110 60921 : t->nr_rows = 1;
111 : cached = true; /* simply keep memory pointer for this small bat */
112 : }
113 355978 : c->b = b->batCacheid;
114 355978 : c->cached = cached;
115 355978 : if (cached)
116 72371 : c->p = (void*)b;
117 : else
118 283607 : bat_incref(c->b);
119 355983 : t->cur_col++;
120 355983 : assert(t->cur_col <= t->nr_cols);
121 355983 : t->nr_output_cols = t->nr_cols;
122 355983 : return c;
123 : }
124 :
125 : static void
126 355970 : res_col_destroy(res_col *c)
127 : {
128 355970 : if (c->b && !c->cached) {
129 283603 : bat_decref(c->b);
130 72367 : } else if (c->b) {
131 72367 : bat_destroy((BAT*)c->p);
132 : } else {
133 0 : _DELETE(c->p);
134 : }
135 355965 : _DELETE(c->name);
136 355985 : _DELETE(c->tn);
137 355988 : }
138 :
139 : void
140 129888 : res_table_destroy(res_table *t)
141 : {
142 129888 : int i;
143 :
144 485918 : for (i = 0; i < t->nr_cols; i++) {
145 355961 : res_col *c = t->cols + i;
146 :
147 355961 : if (c)
148 355961 : res_col_destroy(c);
149 : }
150 129957 : _DELETE(t->cols);
151 129951 : _DELETE(t);
152 129959 : }
153 :
154 : res_table *
155 126504 : res_tables_remove(res_table *results, res_table *t)
156 : {
157 126504 : res_table *r = results;
158 :
159 126504 : if (r == t) {
160 126504 : results = t->next;
161 : } else {
162 0 : for (; r; r = r->next) {
163 0 : if (r->next == t) {
164 0 : r->next = t->next;
165 0 : break;
166 : }
167 : }
168 : }
169 126504 : res_table_destroy(t);
170 126567 : return results;
171 : }
172 :
173 : void
174 37638 : res_tables_destroy(res_table *tab)
175 : {
176 37638 : if (tab) {
177 183 : res_table *r = tab, *t;
178 :
179 183 : for (t = r; t; t = r) {
180 149 : r = t->next;
181 149 : res_table_destroy(t);
182 : }
183 : }
184 37638 : }
185 :
186 : res_table *
187 260438 : res_tables_find(res_table *results, int res_id)
188 : {
189 260438 : res_table *r = results;
190 :
191 274124 : for (; r; r = r->next) {
192 270070 : if (r->id == res_id)
193 256384 : return r;
194 : }
195 : return NULL;
196 : }
|