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 :
15 : #include "sql_qc.h"
16 : #include "sql_mvc.h"
17 : #include "sql_atom.h"
18 : #include "rel_exp.h"
19 : #include "gdk_time.h"
20 :
21 : qc *
22 38815 : qc_create(allocator *sa, int clientid, int seqnr)
23 : {
24 38815 : qc *r = SA_NEW(sa, qc);
25 38815 : if (!r)
26 : return NULL;
27 38815 : *r = (qc) {
28 : .clientid = clientid,
29 : .id = seqnr,
30 : };
31 38815 : return r;
32 : }
33 :
34 : static void
35 336 : cq_delete(int clientid, cq *q)
36 : {
37 336 : if (q->name)
38 335 : backend_freecode(NULL, clientid, q->name);
39 : /* q, params and name are allocated using sa, ie need to be delete last */
40 336 : if (q->sa)
41 336 : sa_destroy(q->sa);
42 336 : }
43 :
44 : static void
45 165 : cq_restart(int clientid, cq *q)
46 : {
47 165 : if (q->f->imp)
48 165 : backend_freecode(NULL, clientid, q->f->imp);
49 165 : q->f->instantiated = false;
50 165 : }
51 :
52 : void
53 207 : qc_delete(qc *cache, cq *q)
54 : {
55 207 : cq *n, *p = NULL;
56 :
57 207 : if (cache) {
58 208 : for (n = cache->q; n; p = n, n = n->next) {
59 208 : if (n == q) {
60 207 : if (p) {
61 1 : p->next = q->next;
62 : } else {
63 206 : cache->q = q->next;
64 : }
65 207 : cq_delete(cache->clientid, q);
66 207 : cache->nr--;
67 207 : break;
68 : }
69 : }
70 : }
71 207 : }
72 :
73 : void
74 16566 : qc_clean(qc *cache)
75 : {
76 16566 : cq *n, *p = NULL;
77 :
78 16566 : if (cache) {
79 16662 : for (n = cache->q; n; ) {
80 96 : p = n->next;
81 96 : cq_delete(cache->clientid, n);
82 96 : cache->nr--;
83 96 : n = p;
84 : }
85 16566 : cache->q = NULL;
86 : }
87 16566 : }
88 :
89 : void
90 28959 : qc_restart(qc *cache)
91 : {
92 28959 : if (cache) {
93 29124 : for (cq *q = cache->q; q; q = q->next)
94 165 : cq_restart(cache->clientid, q);
95 : }
96 28959 : }
97 :
98 :
99 : void
100 38815 : qc_destroy(qc *cache)
101 : {
102 38815 : cq *q, *n;
103 :
104 38815 : if (cache) {
105 38848 : for (q = cache->q; q; q = n) {
106 33 : n = q->next;
107 :
108 33 : cq_delete(cache->clientid, q);
109 33 : cache->nr--;
110 : }
111 : }
112 38815 : }
113 :
114 : cq *
115 6120 : qc_find(qc *cache, int id)
116 : {
117 6120 : cq *q;
118 :
119 6120 : if (cache) {
120 6121 : for (q = cache->q; q; q = q->next) {
121 6110 : if (q->id == id) {
122 6109 : q->count++;
123 6109 : return q;
124 : }
125 : }
126 : }
127 : return NULL;
128 : }
129 :
130 : cq *
131 336 : qc_insert(qc *cache, allocator *sa, sql_rel *r, symbol *s, list *params, mapi_query_t type, char *cmd, int no_mitosis)
132 : {
133 336 : int namelen;
134 336 : sql_func *f = SA_NEW(sa, sql_func);
135 336 : cq *n = SA_ZNEW(sa, cq);
136 336 : list *res = NULL;
137 :
138 336 : if (!n || !f || !cache)
139 : return NULL;
140 336 : n->id = cache->id++;
141 336 : cache->nr++;
142 :
143 336 : n->sa = sa;
144 336 : n->rel = r;
145 336 : n->s = s;
146 :
147 336 : n->next = cache->q;
148 336 : n->type = type;
149 336 : n->count = 1;
150 336 : namelen = 5 + ((n->id+7)>>3) + ((cache->clientid+7)>>3);
151 336 : char *name = sa_alloc(sa, namelen);
152 336 : n->no_mitosis = no_mitosis;
153 336 : n->created = timestamp_current();
154 336 : if (!name)
155 : return NULL;
156 336 : (void) snprintf(name, namelen, "p%d_%d", n->id, cache->clientid);
157 336 : n->name = name;
158 336 : cache->q = n;
159 :
160 336 : if (r && is_project(r->op) && !list_empty(r->exps)) {
161 287 : sql_arg *a;
162 287 : node *m;
163 :
164 287 : res = sa_list(sa);
165 1802 : for(m = r->exps->h; m; m = m->next) {
166 1515 : sql_exp *e = m->data;
167 1515 : sql_subtype *t = exp_subtype(e);
168 :
169 1515 : a = NULL;
170 1515 : if (t)
171 1510 : a = sql_create_arg(sa, NULL, t, ARG_OUT);
172 1515 : append(res, a);
173 : }
174 : }
175 :
176 336 : *f = (sql_func) {
177 : .mod = sql_private_module_name,
178 : .type = F_PROC,
179 : .lang = FUNC_LANG_SQL,
180 : .query = cmd,
181 : .ops = params,
182 : .res = res,
183 : };
184 336 : base_init(sa, &f->base, 0, true, NULL);
185 336 : f->base.new = 1;
186 336 : f->base.id = n->id;
187 336 : f->base.name = f->imp = name;
188 336 : f->instantiated = true;
189 336 : n->f = f;
190 336 : return n;
191 : }
192 :
193 : int
194 0 : qc_size(qc *cache)
195 : {
196 0 : return cache ? cache->nr : 0;
197 : }
|