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 "sql_catalog.h"
15 : #include "sql_storage.h"
16 :
17 : const char *TID = "%TID%";
18 :
19 : inline int
20 1358801 : base_key( sql_base *b )
21 : {
22 1358801 : return hash_key(b->name);
23 : }
24 :
25 : void
26 581042 : trans_add(sql_trans *tr, sql_base *b, void *data, tc_cleanup_fptr cleanup, tc_commit_fptr commit, tc_log_fptr log)
27 : {
28 581042 : sql_change *change = MNEW(sql_change);
29 :
30 581019 : *change = (sql_change) {
31 : .obj = b,
32 : .data = data,
33 : .cleanup = cleanup,
34 : .commit = commit,
35 : .log = log,
36 : };
37 581019 : MT_lock_set(&tr->lock);
38 581027 : tr->changes = list_add(tr->changes, change);
39 580949 : if (log)
40 262310 : tr->logchanges++;
41 580949 : MT_lock_unset(&tr->lock);
42 581035 : }
43 :
44 : void
45 7 : trans_del(sql_trans *tr, sql_base *b)
46 : {
47 7 : MT_lock_set(&tr->lock);
48 68 : for(node *n= tr->changes->h; n; n = n->next) {
49 61 : sql_change *c = n->data;
50 61 : if (c->obj == b) {
51 1 : if (c->log)
52 1 : tr->logchanges--;
53 1 : _DELETE(c);
54 1 : n = list_remove_node(tr->changes, NULL, n);
55 : }
56 : }
57 7 : MT_lock_unset(&tr->lock);
58 7 : }
59 :
60 : int
61 6060 : tr_version_of_parent(sql_trans *tr, ulng ts)
62 : {
63 11200 : for( tr = tr->parent; tr; tr = tr->parent)
64 7811 : if (tr->tid == ts)
65 : return 1;
66 : return 0;
67 : }
68 :
69 : node *
70 105 : list_find_name(list *l, const char *name)
71 : {
72 105 : node *n;
73 :
74 105 : if (l)
75 320 : for (n = l->h; n; n = n->next) {
76 314 : sql_base *b = n->data;
77 :
78 : /* check if names match */
79 314 : if (name[0] == b->name[0] && strcmp(name, b->name) == 0) {
80 99 : return n;
81 : }
82 : }
83 : return NULL;
84 : }
85 :
86 : node *
87 0 : cs_find_id(changeset * cs, sqlid id)
88 : {
89 0 : node *n;
90 0 : list *l = cs->set;
91 :
92 0 : if (l)
93 0 : for (n = l->h; n; n = n->next) {
94 0 : sql_base *b = n->data;
95 :
96 : /* check if names match */
97 0 : if (b->id == id) {
98 0 : return n;
99 : }
100 : }
101 : return NULL;
102 : }
103 :
104 : node *
105 877 : list_find_id(list *l, sqlid id)
106 : {
107 877 : if (l) {
108 875 : node *n;
109 10507 : for (n = l->h; n; n = n->next) {
110 :
111 : /* check if ids match */
112 9639 : if (id == *(sqlid *) n->data) {
113 7 : return n;
114 : }
115 : }
116 : }
117 : return NULL;
118 : }
119 :
120 : node *
121 0 : list_find_base_id(list *l, sqlid id)
122 : {
123 0 : if (l) {
124 0 : node *n;
125 0 : for (n = l->h; n; n = n->next) {
126 0 : sql_base *b = n->data;
127 :
128 0 : if (id == b->id)
129 0 : return n;
130 : }
131 : }
132 : return NULL;
133 : }
134 :
135 : sql_key *
136 483 : find_sql_key(sql_table *t, const char *kname)
137 : {
138 483 : node *n = ol_find_name(t->keys, kname);
139 483 : if (n)
140 0 : return n->data;
141 : return NULL;
142 : }
143 :
144 : sql_key *
145 278 : sql_trans_find_key(sql_trans *tr, sqlid id)
146 : {
147 278 : struct os_iter oi;
148 278 : os_iterator(&oi, tr->cat->schemas, tr, NULL);
149 278 : for (sql_base *b = oi_next(&oi); b; b = oi_next(&oi)) {
150 278 : sql_schema *s = (sql_schema*)b;
151 278 : sql_base *bk = os_find_id(s->keys, tr, id);
152 278 : if (bk)
153 278 : return (sql_key*)bk;
154 : }
155 : return NULL;
156 : }
157 :
158 : sql_key *
159 7402 : schema_find_key(sql_trans *tr, sql_schema *s, const char *name)
160 : {
161 7402 : sql_base *b = os_find_name(s->keys, tr, name);
162 :
163 7402 : if (!b && tr->tmp == s) {
164 92 : struct os_iter oi;
165 92 : os_iterator(&oi, tr->localtmps, tr, NULL);
166 575 : for(sql_base *b = oi_next(&oi); b; b = oi_next(&oi)) {
167 483 : sql_table *t = (sql_table *) b;
168 483 : sql_key *o = find_sql_key(t, name);
169 483 : if (o)
170 0 : return o;
171 : }
172 : }
173 : return (sql_key*)b;
174 : }
175 :
176 : sql_idx *
177 11072 : find_sql_idx(sql_table *t, const char *iname)
178 : {
179 11072 : node *n = ol_find_name(t->idxs, iname);
180 11072 : if (n)
181 4028 : return n->data;
182 : return NULL;
183 : }
184 :
185 : sql_idx *
186 8 : sql_trans_find_idx(sql_trans *tr, sqlid id)
187 : {
188 8 : struct os_iter oi;
189 8 : os_iterator(&oi, tr->cat->schemas, tr, NULL);
190 8 : for (sql_base *b = oi_next(&oi); b; b = oi_next(&oi)) {
191 8 : sql_schema *s = (sql_schema*)b;
192 8 : sql_base *bi = os_find_id(s->idxs, tr, id);
193 8 : if (bi)
194 8 : return (sql_idx*)bi;
195 : }
196 : return NULL;
197 : }
198 :
199 : sql_idx *
200 21058 : schema_find_idx(sql_trans *tr, sql_schema *s, const char *name)
201 : {
202 21058 : sql_base *b = os_find_name(s->idxs, tr, name);
203 :
204 21164 : if (!b && tr->tmp == s) {
205 306 : struct os_iter oi;
206 306 : os_iterator(&oi, tr->localtmps, tr, NULL);
207 1080 : for(sql_base *b = oi_next(&oi); b; b = oi_next(&oi)) {
208 809 : sql_table *t = (sql_table *) b;
209 809 : sql_idx *o = find_sql_idx(t, name);
210 809 : if (o)
211 35 : return o;
212 : }
213 : }
214 : return (sql_idx*)b;
215 : }
216 :
217 : sql_idx *
218 1168 : schema_find_idx_id(sql_trans *tr, sql_schema *s, sqlid id)
219 : {
220 1168 : sql_base *b = os_find_id(s->idxs, tr, id);
221 :
222 1168 : if (!b && tr->tmp == s) {
223 24 : struct os_iter oi;
224 24 : os_iterator(&oi, tr->localtmps, tr, NULL);
225 122 : for(sql_base *b = oi_next(&oi); b; b = oi_next(&oi)) {
226 122 : sql_table *t = (sql_table *) b;
227 122 : node *o = ol_find_id(t->idxs, id);
228 122 : if (o)
229 24 : return (sql_idx*)o->data;
230 : }
231 : }
232 : return (sql_idx*)b;
233 : }
234 :
235 :
236 : sql_column *
237 11007362 : find_sql_column(sql_table *t, const char *cname)
238 : {
239 11007362 : node *n = ol_find_name(t->columns, cname);
240 11057577 : if (n)
241 10786984 : return n->data;
242 : return NULL;
243 : }
244 :
245 : sql_column *
246 185 : find_sql_column_id(sql_table *t, sqlid col_id)
247 : {
248 185 : node *n = ol_find_id(t->columns, col_id);
249 185 : if (n)
250 185 : return n->data;
251 : return NULL;
252 : }
253 :
254 : sql_table *
255 8241236 : find_sql_table(sql_trans *tr, sql_schema *s, const char *tname)
256 : {
257 8241236 : sql_table *t = (sql_table*)os_find_name(s->tables, tr, tname);
258 :
259 8291618 : if (!t && tr->tmp == s) {
260 213703 : t = (sql_table*) os_find_name(tr->localtmps, tr, tname);
261 213703 : return t;
262 : }
263 :
264 8011359 : if (t && isTempTable(t) && tr->tmp == s) {
265 67937 : sqlstore *store = tr->store;
266 67937 : assert(isGlobal(t));
267 :
268 67937 : sql_table* lt = (sql_table*) os_find_name(tr->localtmps, tr, tname);
269 67818 : if (lt)
270 : return lt;
271 4615 : MT_lock_set(&store->table_locks[t->base.id&(NR_TABLE_LOCKS-1)]);
272 :
273 4615 : lt = (sql_table*) os_find_name(tr->localtmps, tr, tname);
274 4615 : if (!lt)
275 4608 : t = globaltmp_instantiate(tr, t);
276 : else
277 : t = lt;
278 4615 : MT_lock_unset(&store->table_locks[t->base.id&(NR_TABLE_LOCKS-1)]);
279 4615 : return t;
280 : }
281 :
282 : return t;
283 : }
284 :
285 : sql_table *
286 38315 : find_sql_table_id(sql_trans *tr, sql_schema *s, sqlid id)
287 : {
288 38315 : sql_table *t = (sql_table*)os_find_id(s->tables, tr, id);
289 38315 : if (!t && tr->tmp == s) {
290 59 : t = (sql_table*) os_find_id(tr->localtmps, tr, id);
291 59 : return t;
292 : }
293 :
294 38256 : if (t && isTempTable(t) && tr->tmp == s) {
295 52 : sqlstore *store = tr->store;
296 52 : assert(isGlobal(t));
297 :
298 52 : sql_table* lt = (sql_table*) os_find_id(tr->localtmps, tr, id);
299 52 : if (lt)
300 : return lt;
301 0 : MT_lock_set(&store->table_locks[id&(NR_TABLE_LOCKS-1)]);
302 0 : lt = (sql_table*) os_find_id(tr->localtmps, tr, id);
303 0 : if (!lt)
304 0 : t = globaltmp_instantiate(tr, t);
305 : else
306 : t = lt;
307 0 : MT_lock_unset(&store->table_locks[id&(NR_TABLE_LOCKS-1)]);
308 0 : return t;
309 : }
310 : return t;
311 : }
312 :
313 : sql_table *
314 249 : sql_trans_find_table(sql_trans *tr, sqlid id)
315 : {
316 249 : struct os_iter oi;
317 249 : os_iterator(&oi, tr->cat->schemas, tr, NULL);
318 425 : for (sql_base *b = oi_next(&oi); b; b = oi_next(&oi)) {
319 423 : sql_schema *s = (sql_schema*)b;
320 423 : sql_base *bt = os_find_id(s->tables, tr, id);
321 423 : if (bt)
322 247 : return (sql_table*)bt;
323 : }
324 : return NULL;
325 : }
326 :
327 : sql_sequence *
328 3678 : find_sql_sequence(sql_trans *tr, sql_schema *s, const char *sname)
329 : {
330 3678 : return (sql_sequence*)os_find_name(s->seqs, tr, sname);
331 : }
332 :
333 : sql_schema *
334 11606472 : find_sql_schema(sql_trans *tr, const char *sname)
335 : {
336 11606472 : if (tr->tmp && strcmp(sname, "tmp")==0)
337 : return tr->tmp;
338 10969852 : return (sql_schema*)os_find_name(tr->cat->schemas, tr, sname);
339 : }
340 :
341 : sql_schema *
342 1848 : find_sql_schema_id(sql_trans *tr, sqlid id)
343 : {
344 1848 : if (tr->tmp && tr->tmp->base.id == id)
345 : return tr->tmp;
346 1491 : return (sql_schema*)os_find_id(tr->cat->schemas, tr, id);
347 : }
348 :
349 : sql_type *
350 64572 : find_sql_type(sql_trans *tr, sql_schema *s, const char *tname)
351 : {
352 64572 : return (sql_type*)os_find_name(s->types, tr, tname);
353 : }
354 :
355 : sql_type *
356 52093 : sql_trans_bind_type(sql_trans *tr, sql_schema *c, const char *name)
357 : {
358 52093 : struct os_iter oi;
359 52093 : os_iterator(&oi, tr->cat->schemas, tr, NULL);
360 53640 : for (sql_base *b = oi_next(&oi); b; b = oi_next(&oi)) {
361 53419 : sql_schema *s = (sql_schema*)b;
362 53419 : sql_type *t = find_sql_type(tr, s, name);
363 53419 : if (t)
364 51872 : return t;
365 : }
366 221 : if (c)
367 0 : return find_sql_type(tr, c, name);
368 : return NULL;
369 : }
370 :
371 : sql_type *
372 35 : sql_trans_find_type(sql_trans *tr, sql_schema *s, sqlid id)
373 : {
374 35 : if (s) {
375 35 : sql_base *b = os_find_id(s->types, tr, id);
376 35 : if (b)
377 : return (sql_type*)b;
378 : } else {
379 0 : struct os_iter oi;
380 0 : os_iterator(&oi, tr->cat->schemas, tr, NULL);
381 0 : for (sql_base *b = oi_next(&oi); b; b = oi_next(&oi)) {
382 0 : sql_schema *s = (sql_schema*)b;
383 0 : sql_base *bt = os_find_id(s->types, tr, id);
384 0 : if (bt)
385 0 : return (sql_type*)bt;
386 : }
387 : }
388 : return NULL;
389 : }
390 :
391 : sql_func *
392 389 : sql_trans_find_func(sql_trans *tr, sqlid id)
393 : {
394 389 : struct os_iter oi;
395 389 : os_iterator(&oi, tr->cat->schemas, tr, NULL);
396 601 : for (sql_base *b = oi_next(&oi); b; b = oi_next(&oi)) {
397 596 : sql_schema *s = (sql_schema*)b;
398 596 : sql_base *bf = os_find_id(s->funcs, tr, id);
399 596 : if (bf)
400 384 : return (sql_func*)bf;
401 : }
402 : return NULL;
403 : }
404 :
405 : static sql_trigger *
406 93 : find_sql_trigger(sql_table *t, const char *tname)
407 : {
408 93 : node *n = ol_find_name(t->triggers, tname);
409 93 : if (n)
410 0 : return n->data;
411 : return NULL;
412 : }
413 :
414 : sql_trigger *
415 2 : sql_trans_find_trigger(sql_trans *tr, sqlid id)
416 : {
417 2 : struct os_iter oi;
418 2 : os_iterator(&oi, tr->cat->schemas, tr, NULL);
419 2 : for (sql_base *b = oi_next(&oi); b; b = oi_next(&oi)) {
420 2 : sql_schema *s = (sql_schema*)b;
421 2 : sql_base *bt = os_find_id(s->triggers, tr, id);
422 2 : if (bt)
423 2 : return (sql_trigger*)bt;
424 : }
425 : return NULL;
426 : }
427 :
428 : sql_trigger *
429 958 : schema_find_trigger(sql_trans *tr, sql_schema *s, const char *name)
430 : {
431 958 : sql_base *b = os_find_name(s->triggers, tr, name);
432 :
433 958 : if (!b && tr->tmp == s) {
434 95 : struct os_iter oi;
435 95 : os_iterator(&oi, tr->localtmps, tr, NULL);
436 188 : for(sql_base *b = oi_next(&oi); b; b = oi_next(&oi)) {
437 93 : sql_table *t = (sql_table *) b;
438 93 : sql_trigger *o = find_sql_trigger(t, name);
439 93 : if (o)
440 0 : return o;
441 : }
442 : }
443 : return (sql_trigger*)b;
444 : }
445 :
446 : void*
447 197 : sql_values_list_element_validate_and_insert(void *v1, void *v2, void *tpe, int* res)
448 : {
449 197 : sql_part_value* pt = (sql_part_value*) v1, *newp = (sql_part_value*) v2;
450 197 : sql_subtype *tp = (sql_subtype *) tpe;
451 :
452 197 : *res = ATOMcmp(tp->type->localtype, newp->value, pt->value);
453 197 : return *res == 0 ? pt : NULL;
454 : }
455 :
456 : void*
457 136 : sql_range_part_validate_and_insert(void *v1, void *v2, void *type)
458 : {
459 136 : sql_part* pt = (sql_part*) v1, *newp = (sql_part*) v2;
460 136 : int res1, res2, tpe = *(int*)type;
461 136 : const void *nil = ATOMnilptr(tpe);
462 136 : bool pt_down_all = false, pt_upper_all = false, newp_down_all = false, newp_upper_all = false, pt_min_max_same = false, newp_min_max_same = false;
463 :
464 136 : if (pt == newp) /* same pointer, skip (used in updates) */
465 : return NULL;
466 :
467 133 : if (is_bit_nil(pt->with_nills) || is_bit_nil(newp->with_nills)) /* if one partition holds all including nills, then conflicts */
468 : return pt;
469 129 : if (newp->with_nills && pt->with_nills) /* only one partition at most has null values */
470 : return pt;
471 :
472 123 : pt_down_all = !ATOMcmp(tpe, nil, pt->part.range.minvalue);
473 123 : pt_upper_all = !ATOMcmp(tpe, nil, pt->part.range.maxvalue);
474 123 : newp_down_all = !ATOMcmp(tpe, nil, newp->part.range.minvalue);
475 123 : newp_upper_all = !ATOMcmp(tpe, nil, newp->part.range.maxvalue);
476 :
477 : /* if one partition just holds NULL values, then there's no conflict */
478 123 : if ((newp_down_all && newp_upper_all && newp->with_nills) || (pt_down_all && pt_upper_all && pt->with_nills))
479 : return NULL;
480 : /* holds all range, will always conflict */
481 107 : if ((pt_down_all && pt_upper_all && !pt->with_nills) || (newp_down_all && newp_upper_all && !newp->with_nills))
482 : return pt;
483 :
484 103 : pt_min_max_same = !ATOMcmp(tpe, pt->part.range.maxvalue, pt->part.range.minvalue);
485 103 : newp_min_max_same = !ATOMcmp(tpe, newp->part.range.maxvalue, newp->part.range.minvalue);
486 :
487 103 : if (pt_down_all) { /* from range min value until a value */
488 23 : res1 = ATOMcmp(tpe, pt->part.range.maxvalue, newp->part.range.minvalue);
489 23 : if (newp_down_all || (!newp_min_max_same && res1 > 0) || (newp_min_max_same && res1 >= 0))
490 : return pt;
491 : return NULL;
492 : }
493 80 : if (pt_upper_all) { /* from value until range max value */
494 9 : res1 = ATOMcmp(tpe, newp->part.range.maxvalue, pt->part.range.minvalue);
495 9 : if (newp_upper_all || (!newp_min_max_same && res1 > 0) || (newp_min_max_same && res1 >= 0))
496 : return pt;
497 : return NULL;
498 : }
499 71 : if (newp_down_all) { /* from range min value until a value */
500 2 : res1 = ATOMcmp(tpe, newp->part.range.maxvalue, pt->part.range.minvalue);
501 2 : if (pt_down_all || (!newp_min_max_same && res1 > 0) || (newp_min_max_same && res1 >= 0))
502 : return pt;
503 : return NULL;
504 : }
505 69 : if (newp_upper_all) { /* from value until range max value */
506 15 : res1 = ATOMcmp(tpe, pt->part.range.maxvalue, newp->part.range.minvalue);
507 15 : if (pt_upper_all || (!pt_min_max_same && res1 > 0) || (pt_min_max_same && res1 >= 0))
508 : return pt;
509 : return NULL;
510 : }
511 :
512 : /* Fallback into normal cases */
513 54 : res1 = ATOMcmp(tpe, newp->part.range.maxvalue, pt->part.range.minvalue);
514 54 : res2 = ATOMcmp(tpe, pt->part.range.maxvalue, newp->part.range.minvalue);
515 : /* overlap: y2 > x1 && x2 > y1 */
516 54 : if (((!newp_min_max_same && res1 > 0) || (newp_min_max_same && res1 >= 0)) && ((!pt_min_max_same && res2 > 0) || (pt_min_max_same && res2 >= 0)))
517 : return pt;
518 : return NULL;
519 : }
520 :
521 : void*
522 44 : sql_values_part_validate_and_insert(void *v1, void *v2, void *type)
523 : {
524 44 : sql_part* pt = (sql_part*) v1, *newp = (sql_part*) v2;
525 44 : list* b1 = pt->part.values, *b2 = newp->part.values;
526 44 : node *n1 = b1->h, *n2 = b2->h;
527 44 : int res, tpe = *(int*)type;
528 :
529 44 : if (pt == newp) /* same pointer, skip (used in updates) */
530 : return NULL;
531 :
532 42 : if (newp->with_nills && pt->with_nills)
533 : return pt; /* check for nulls first */
534 :
535 145 : while (n1 && n2) {
536 108 : sql_part_value *p1 = (sql_part_value *) n1->data, *p2 = (sql_part_value *) n2->data;
537 108 : res = ATOMcmp(tpe, p1->value, p2->value);
538 108 : if (!res) { /* overlap -> same value in both partitions */
539 : return pt;
540 104 : } else if (res < 0) {
541 101 : n1 = n1->next;
542 : } else {
543 3 : n2 = n2->next;
544 : }
545 : }
546 : return NULL;
547 : }
548 :
549 : sql_part *
550 573183 : partition_find_part(sql_trans *tr, sql_table *pt, sql_part *pp)
551 : {
552 573183 : struct os_iter oi;
553 :
554 573183 : if (!pt->s) /* declared table */
555 : return NULL;
556 573174 : os_iterator(&oi, pt->s->parts, tr, NULL);
557 599046 : for (sql_base *b = oi_next(&oi); b; b = oi_next(&oi)) {
558 28280 : sql_part *p = (sql_part*)b;
559 :
560 28280 : if (pp) {
561 150 : if (p == pp)
562 18 : pp = NULL;
563 150 : continue;
564 : }
565 28130 : if (p->member == pt->base.id)
566 3324 : return p;
567 : }
568 : return NULL;
569 : }
570 :
571 : node *
572 969 : members_find_child_id(list *l, sqlid id)
573 : {
574 969 : if (l) {
575 969 : node *n;
576 1376 : for (n = l->h; n; n = n->next) {
577 788 : sql_part *p = n->data;
578 :
579 788 : if (id == p->member)
580 381 : return n;
581 : }
582 : }
583 : return NULL;
584 : }
585 :
586 : int
587 593 : nested_mergetable(sql_trans *tr, sql_table *mt, const char *sname, const char *tname)
588 : {
589 593 : if (strcmp(mt->s->base.name, sname) == 0 && strcmp(mt->base.name, tname) == 0)
590 : return 1;
591 : /* try if this is also a partition */
592 609 : for( sql_part *parent = partition_find_part(tr, mt, NULL); parent; parent = partition_find_part(tr, mt, parent)) {
593 21 : if (nested_mergetable(tr, parent->t, sname, tname))
594 : return 1;
595 : }
596 : return 0;
597 : }
598 :
599 : bool
600 4215639 : is_column_unique(sql_column *c)
601 : {
602 : /* is it a primary key column itself? */
603 4215639 : if (c->t->pkey && list_length(c->t->pkey->k.columns) == 1 &&
604 409816 : ((sql_kc*)c->t->pkey->k.columns->h->data)->c->base.id == c->base.id)
605 : return true;
606 : /* is it a unique key itself */
607 4069666 : return c->unique == 2;
608 : }
609 :
610 : ValPtr
611 6736442 : SA_VALcopy(allocator *sa, ValPtr d, const ValRecord *s)
612 : {
613 6736442 : if (sa == NULL)
614 2025 : return VALcopy(d, s);
615 6734417 : if (!ATOMextern(s->vtype)) {
616 4842464 : *d = *s;
617 1891953 : } else if (s->val.pval == 0) {
618 0 : const void *p = ATOMnilptr(s->vtype);
619 0 : d->vtype = s->vtype;
620 0 : d->len = ATOMlen(d->vtype, p);
621 0 : d->val.pval = sa_alloc(sa, d->len);
622 0 : if (d->val.pval == NULL)
623 : return NULL;
624 0 : memcpy(d->val.pval, p, d->len);
625 1891953 : } else if (s->vtype == TYPE_str) {
626 1891666 : const char *p = s->val.sval;
627 1891666 : d->vtype = TYPE_str;
628 1891666 : d->len = strLen(p);
629 1891666 : d->val.sval = sa_alloc(sa, d->len);
630 1891666 : if (d->val.sval == NULL)
631 : return NULL;
632 1891666 : memcpy(d->val.sval, p, d->len);
633 : } else {
634 287 : const void *p = s->val.pval;
635 287 : d->vtype = s->vtype;
636 287 : d->len = ATOMlen(d->vtype, p);
637 287 : d->val.pval = sa_alloc(sa, d->len);
638 287 : if (d->val.pval == NULL)
639 : return NULL;
640 287 : memcpy(d->val.pval, p, d->len);
641 : }
642 : return d;
643 : }
644 :
645 : atom *
646 267821 : atom_copy(allocator *sa, atom *a)
647 : {
648 267821 : atom *r = sa ?SA_NEW(sa, atom):MNEW(atom);
649 267822 : if (!r)
650 : return NULL;
651 :
652 267822 : *r = (atom) {
653 267822 : .isnull = a->isnull,
654 267822 : .tpe = a->tpe,
655 : .data = (ValRecord) {.vtype = TYPE_void,},
656 : };
657 267822 : if (!a->isnull)
658 266791 : SA_VALcopy(sa, &r->data, &a->data);
659 : return r;
660 : }
661 :
662 :
663 : sql_table*
664 0 : find_sys_table(sql_trans *tr, const char* tbl_name)
665 : {
666 0 : sql_schema *sys = find_sql_schema(tr, "sys");
667 0 : return find_sql_table(tr, sys, tbl_name);
668 : }
|