LCOV - code coverage report
Current view: top level - sql/storage - sql_catalog.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 277 315 87.9 %
Date: 2024-04-26 00:35:57 Functions: 36 39 92.3 %

          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 "sql_catalog.h"
      15             : #include "sql_storage.h"
      16             : 
      17             : const char *TID = "%TID%";
      18             : 
      19             : inline int
      20     1273368 : base_key( sql_base *b )
      21             : {
      22     1273368 :         return hash_key(b->name);
      23             : }
      24             : 
      25             : void
      26      533253 : trans_add(sql_trans *tr, sql_base *b, void *data, tc_cleanup_fptr cleanup, tc_commit_fptr commit, tc_log_fptr log)
      27             : {
      28      533253 :         sql_change *change = MNEW(sql_change);
      29             : 
      30      533250 :         *change = (sql_change) {
      31             :                 .obj = b,
      32             :                 .data = data,
      33             :                 .cleanup = cleanup,
      34             :                 .commit = commit,
      35             :                 .log = log,
      36             :         };
      37      533250 :         MT_lock_set(&tr->lock);
      38      533249 :         tr->changes = list_add(tr->changes, change);
      39      533166 :         if (log)
      40      236393 :                 tr->logchanges++;
      41      533166 :         MT_lock_unset(&tr->lock);
      42      533235 : }
      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        5964 : tr_version_of_parent(sql_trans *tr, ulng ts)
      62             : {
      63       11087 :         for( tr = tr->parent; tr; tr = tr->parent)
      64        7713 :                 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         823 : list_find_id(list *l, sqlid id)
     106             : {
     107         823 :         if (l) {
     108         821 :                 node *n;
     109       10397 :                 for (n = l->h; n; n = n->next) {
     110             : 
     111             :                         /* check if ids match */
     112        9583 :                         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        6953 : schema_find_key(sql_trans *tr, sql_schema *s, const char *name)
     160             : {
     161        6953 :         sql_base *b = os_find_name(s->keys, tr, name);
     162             : 
     163        6953 :         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       11263 : find_sql_idx(sql_table *t, const char *iname)
     178             : {
     179       11263 :         node *n = ol_find_name(t->idxs, iname);
     180       11263 :         if (n)
     181        4101 :                 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       20697 : schema_find_idx(sql_trans *tr, sql_schema *s, const char *name)
     201             : {
     202       20697 :         sql_base *b = os_find_name(s->idxs, tr, name);
     203             : 
     204       20805 :         if (!b && tr->tmp == s) {
     205         303 :                 struct os_iter oi;
     206         303 :                 os_iterator(&oi, tr->localtmps, tr, NULL);
     207        1074 :                 for(sql_base *b = oi_next(&oi); b; b = oi_next(&oi)) {
     208         806 :                         sql_table *t = (sql_table *) b;
     209         806 :                         sql_idx *o = find_sql_idx(t, name);
     210         806 :                         if (o)
     211          35 :                                 return o;
     212             :                 }
     213             :         }
     214             :         return (sql_idx*)b;
     215             : }
     216             : 
     217             : sql_idx *
     218        1162 : schema_find_idx_id(sql_trans *tr, sql_schema *s, sqlid id)
     219             : {
     220        1162 :         sql_base *b = os_find_id(s->idxs, tr, id);
     221             : 
     222        1162 :         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    10163101 : find_sql_column(sql_table *t, const char *cname)
     238             : {
     239    10163101 :         node *n = ol_find_name(t->columns, cname);
     240    10213289 :         if (n)
     241     9953591 :                 return n->data;
     242             :         return NULL;
     243             : }
     244             : 
     245             : sql_table *
     246     7558445 : find_sql_table(sql_trans *tr, sql_schema *s, const char *tname)
     247             : {
     248     7558445 :         sql_table *t = (sql_table*)os_find_name(s->tables, tr, tname);
     249             : 
     250     7616538 :         if (!t && tr->tmp == s) {
     251      208020 :                 t = (sql_table*) os_find_name(tr->localtmps, tr, tname);
     252      208020 :                 return t;
     253             :         }
     254             : 
     255     7345501 :         if (t && isTempTable(t) && tr->tmp == s) {
     256       52346 :                 assert(isGlobal(t));
     257             : 
     258       52346 :                 sql_table* lt = (sql_table*) os_find_name(tr->localtmps, tr, tname);
     259       52394 :                 if (lt)
     260             :                         return lt;
     261             : 
     262        4150 :                 t = globaltmp_instantiate(tr, t);
     263        4150 :                 return t;
     264             :         }
     265             : 
     266             :         return t;
     267             : }
     268             : 
     269             : sql_table *
     270       37894 : find_sql_table_id(sql_trans *tr, sql_schema *s, sqlid id)
     271             : {
     272       37894 :         sql_table *t = (sql_table*)os_find_id(s->tables, tr, id);
     273       37894 :         if (!t && tr->tmp == s) {
     274          59 :                 t = (sql_table*) os_find_id(tr->localtmps, tr, id);
     275          59 :                 return t;
     276             :         }
     277             : 
     278       37835 :         if (t && isTempTable(t) && tr->tmp == s) {
     279          52 :                 assert(isGlobal(t));
     280             : 
     281          52 :                 sql_table* lt = (sql_table*) os_find_id(tr->localtmps, tr, id);
     282          52 :                 if (lt)
     283             :                         return lt;
     284             : 
     285           0 :                 t = globaltmp_instantiate(tr, t);
     286           0 :                 return t;
     287             :         }
     288             :         return t;
     289             : }
     290             : 
     291             : sql_table *
     292         223 : sql_trans_find_table(sql_trans *tr, sqlid id)
     293             : {
     294         223 :         struct os_iter oi;
     295         223 :         os_iterator(&oi, tr->cat->schemas, tr, NULL);
     296         371 :         for (sql_base *b = oi_next(&oi); b; b = oi_next(&oi)) {
     297         371 :                 sql_schema *s = (sql_schema*)b;
     298         371 :                 sql_base *bt = os_find_id(s->tables, tr, id);
     299         371 :                 if (bt)
     300         223 :                         return (sql_table*)bt;
     301             :         }
     302             :         return NULL;
     303             : }
     304             : 
     305             : sql_sequence *
     306        3630 : find_sql_sequence(sql_trans *tr, sql_schema *s, const char *sname)
     307             : {
     308        3630 :         return (sql_sequence*)os_find_name(s->seqs, tr, sname);
     309             : }
     310             : 
     311             : sql_schema *
     312    10385913 : find_sql_schema(sql_trans *tr, const char *sname)
     313             : {
     314    10385913 :         if (tr->tmp && strcmp(sname, "tmp")==0)
     315             :                 return tr->tmp;
     316     9791950 :         return (sql_schema*)os_find_name(tr->cat->schemas, tr, sname);
     317             : }
     318             : 
     319             : sql_schema *
     320        1743 : find_sql_schema_id(sql_trans *tr, sqlid id)
     321             : {
     322        1743 :         if (tr->tmp && tr->tmp->base.id == id)
     323             :                 return tr->tmp;
     324        1403 :         return (sql_schema*)os_find_id(tr->cat->schemas, tr, id);
     325             : }
     326             : 
     327             : sql_type *
     328       61121 : find_sql_type(sql_trans *tr, sql_schema *s, const char *tname)
     329             : {
     330       61121 :         return (sql_type*)os_find_name(s->types, tr, tname);
     331             : }
     332             : 
     333             : sql_type *
     334       49422 : sql_trans_bind_type(sql_trans *tr, sql_schema *c, const char *name)
     335             : {
     336       49422 :         struct os_iter oi;
     337       49422 :         os_iterator(&oi, tr->cat->schemas, tr, NULL);
     338       50969 :         for (sql_base *b = oi_next(&oi); b; b = oi_next(&oi)) {
     339       50748 :                 sql_schema *s = (sql_schema*)b;
     340       50748 :                 sql_type *t = find_sql_type(tr, s, name);
     341       50748 :                 if (t)
     342       49201 :                         return t;
     343             :         }
     344         221 :         if (c)
     345           0 :                 return find_sql_type(tr, c, name);
     346             :         return NULL;
     347             : }
     348             : 
     349             : sql_type *
     350           3 : sql_trans_find_type(sql_trans *tr, sql_schema *s, sqlid id)
     351             : {
     352           3 :         if (s) {
     353           3 :                 sql_base *b = os_find_id(s->types, tr, id);
     354           3 :                 if (b)
     355             :                         return (sql_type*)b;
     356             :         } else {
     357           0 :                 struct os_iter oi;
     358           0 :                 os_iterator(&oi, tr->cat->schemas, tr, NULL);
     359           0 :                 for (sql_base *b = oi_next(&oi); b; b = oi_next(&oi)) {
     360           0 :                         sql_schema *s = (sql_schema*)b;
     361           0 :                         sql_base *bt = os_find_id(s->types, tr, id);
     362           0 :                         if (bt)
     363           0 :                                 return (sql_type*)bt;
     364             :                 }
     365             :         }
     366             :         return NULL;
     367             : }
     368             : 
     369             : sql_func *
     370         399 : sql_trans_find_func(sql_trans *tr, sqlid id)
     371             : {
     372         399 :         struct os_iter oi;
     373         399 :         os_iterator(&oi, tr->cat->schemas, tr, NULL);
     374         611 :         for (sql_base *b = oi_next(&oi); b; b = oi_next(&oi)) {
     375         606 :                 sql_schema *s = (sql_schema*)b;
     376         606 :                 sql_base *bf = os_find_id(s->funcs, tr, id);
     377         606 :                 if (bf)
     378         394 :                         return (sql_func*)bf;
     379             :         }
     380             :         return NULL;
     381             : }
     382             : 
     383             : static sql_trigger *
     384          89 : find_sql_trigger(sql_table *t, const char *tname)
     385             : {
     386          89 :         node *n = ol_find_name(t->triggers, tname);
     387          89 :         if (n)
     388           0 :                 return n->data;
     389             :         return NULL;
     390             : }
     391             : 
     392             : sql_trigger *
     393           2 : sql_trans_find_trigger(sql_trans *tr, sqlid id)
     394             : {
     395           2 :         struct os_iter oi;
     396           2 :         os_iterator(&oi, tr->cat->schemas, tr, NULL);
     397           2 :         for (sql_base *b = oi_next(&oi); b; b = oi_next(&oi)) {
     398           2 :                 sql_schema *s = (sql_schema*)b;
     399           2 :                 sql_base *bt = os_find_id(s->triggers, tr, id);
     400           2 :                 if (bt)
     401           2 :                         return (sql_trigger*)bt;
     402             :         }
     403             :         return NULL;
     404             : }
     405             : 
     406             : sql_trigger *
     407         918 : schema_find_trigger(sql_trans *tr, sql_schema *s, const char *name)
     408             : {
     409         918 :         sql_base *b = os_find_name(s->triggers, tr, name);
     410             : 
     411         918 :         if (!b && tr->tmp == s) {
     412          91 :                 struct os_iter oi;
     413          91 :                 os_iterator(&oi, tr->localtmps, tr, NULL);
     414         180 :                 for(sql_base *b = oi_next(&oi); b; b = oi_next(&oi)) {
     415          89 :                         sql_table *t = (sql_table *) b;
     416          89 :                         sql_trigger *o = find_sql_trigger(t, name);
     417          89 :                         if (o)
     418           0 :                                 return o;
     419             :                 }
     420             :         }
     421             :         return (sql_trigger*)b;
     422             : }
     423             : 
     424             : void*
     425         194 : sql_values_list_element_validate_and_insert(void *v1, void *v2, void *tpe, int* res)
     426             : {
     427         194 :         sql_part_value* pt = (sql_part_value*) v1, *newp = (sql_part_value*) v2;
     428         194 :         sql_subtype *tp = (sql_subtype *) tpe;
     429             : 
     430         194 :         *res = ATOMcmp(tp->type->localtype, newp->value, pt->value);
     431         194 :         return *res == 0 ? pt : NULL;
     432             : }
     433             : 
     434             : void*
     435         131 : sql_range_part_validate_and_insert(void *v1, void *v2, void *type)
     436             : {
     437         131 :         sql_part* pt = (sql_part*) v1, *newp = (sql_part*) v2;
     438         131 :         int res1, res2, tpe = *(int*)type;
     439         131 :         const void *nil = ATOMnilptr(tpe);
     440         131 :         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;
     441             : 
     442         131 :         if (pt == newp) /* same pointer, skip (used in updates) */
     443             :                 return NULL;
     444             : 
     445         128 :         if (is_bit_nil(pt->with_nills) || is_bit_nil(newp->with_nills)) /* if one partition holds all including nills, then conflicts */
     446             :                 return pt;
     447         124 :         if (newp->with_nills && pt->with_nills) /* only one partition at most has null values */
     448             :                 return pt;
     449             : 
     450         118 :         pt_down_all = !ATOMcmp(tpe, nil, pt->part.range.minvalue);
     451         118 :         pt_upper_all = !ATOMcmp(tpe, nil, pt->part.range.maxvalue);
     452         118 :         newp_down_all = !ATOMcmp(tpe, nil, newp->part.range.minvalue);
     453         118 :         newp_upper_all = !ATOMcmp(tpe, nil, newp->part.range.maxvalue);
     454             : 
     455             :         /* if one partition just holds NULL values, then there's no conflict */
     456         118 :         if ((newp_down_all && newp_upper_all && newp->with_nills) || (pt_down_all && pt_upper_all && pt->with_nills))
     457             :                 return NULL;
     458             :          /* holds all range, will always conflict */
     459         102 :         if ((pt_down_all && pt_upper_all && !pt->with_nills) || (newp_down_all && newp_upper_all && !newp->with_nills))
     460             :                 return pt;
     461             : 
     462          98 :         pt_min_max_same = !ATOMcmp(tpe, pt->part.range.maxvalue, pt->part.range.minvalue);
     463          98 :         newp_min_max_same = !ATOMcmp(tpe, newp->part.range.maxvalue, newp->part.range.minvalue);
     464             : 
     465          98 :         if (pt_down_all) { /* from range min value until a value */
     466          23 :                 res1 = ATOMcmp(tpe, pt->part.range.maxvalue, newp->part.range.minvalue);
     467          23 :                 if (newp_down_all || (!newp_min_max_same && res1 > 0) || (newp_min_max_same && res1 >= 0))
     468             :                         return pt;
     469             :                 return NULL;
     470             :         }
     471          75 :         if (pt_upper_all) { /* from value until range max value */
     472           9 :                 res1 = ATOMcmp(tpe, newp->part.range.maxvalue, pt->part.range.minvalue);
     473           9 :                 if (newp_upper_all || (!newp_min_max_same && res1 > 0) || (newp_min_max_same && res1 >= 0))
     474             :                         return pt;
     475             :                 return NULL;
     476             :         }
     477          66 :         if (newp_down_all) { /* from range min value until a value */
     478           2 :                 res1 = ATOMcmp(tpe, newp->part.range.maxvalue, pt->part.range.minvalue);
     479           2 :                 if (pt_down_all || (!newp_min_max_same && res1 > 0) || (newp_min_max_same && res1 >= 0))
     480             :                         return pt;
     481             :                 return NULL;
     482             :         }
     483          64 :         if (newp_upper_all) { /* from value until range max value */
     484          15 :                 res1 = ATOMcmp(tpe, pt->part.range.maxvalue, newp->part.range.minvalue);
     485          15 :                 if (pt_upper_all || (!pt_min_max_same && res1 > 0) || (pt_min_max_same && res1 >= 0))
     486             :                         return pt;
     487             :                 return NULL;
     488             :         }
     489             : 
     490             :         /* Fallback into normal cases */
     491          49 :         res1 = ATOMcmp(tpe, newp->part.range.maxvalue, pt->part.range.minvalue);
     492          49 :         res2 = ATOMcmp(tpe, pt->part.range.maxvalue, newp->part.range.minvalue);
     493             :         /* overlap: y2 > x1 && x2 > y1 */
     494          49 :         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)))
     495             :                 return pt;
     496             :         return NULL;
     497             : }
     498             : 
     499             : void*
     500          44 : sql_values_part_validate_and_insert(void *v1, void *v2, void *type)
     501             : {
     502          44 :         sql_part* pt = (sql_part*) v1, *newp = (sql_part*) v2;
     503          44 :         list* b1 = pt->part.values, *b2 = newp->part.values;
     504          44 :         node *n1 = b1->h, *n2 = b2->h;
     505          44 :         int res, tpe = *(int*)type;
     506             : 
     507          44 :         if (pt == newp) /* same pointer, skip (used in updates) */
     508             :                 return NULL;
     509             : 
     510          42 :         if (newp->with_nills && pt->with_nills)
     511             :                 return pt; /* check for nulls first */
     512             : 
     513         145 :         while (n1 && n2) {
     514         108 :                 sql_part_value *p1 = (sql_part_value *) n1->data, *p2 = (sql_part_value *) n2->data;
     515         108 :                 res = ATOMcmp(tpe, p1->value, p2->value);
     516         108 :                 if (!res) { /* overlap -> same value in both partitions */
     517             :                         return pt;
     518         104 :                 } else if (res < 0) {
     519         101 :                         n1 = n1->next;
     520             :                 } else {
     521           3 :                         n2 = n2->next;
     522             :                 }
     523             :         }
     524             :         return NULL;
     525             : }
     526             : 
     527             : sql_part *
     528      681192 : partition_find_part(sql_trans *tr, sql_table *pt, sql_part *pp)
     529             : {
     530      681192 :         struct os_iter oi;
     531             : 
     532      681192 :         if (!pt->s) /* declared table */
     533             :                 return NULL;
     534      681183 :         os_iterator(&oi, pt->s->parts, tr, NULL);
     535      727750 :         for (sql_base *b = oi_next(&oi); b; b = oi_next(&oi)) {
     536       48404 :                 sql_part *p = (sql_part*)b;
     537             : 
     538       48404 :                 if (pp) {
     539          78 :                         if (p == pp)
     540          17 :                                 pp = NULL;
     541          78 :                         continue;
     542             :                 }
     543       48326 :                 if (p->member == pt->base.id)
     544        2898 :                         return p;
     545             :         }
     546             :         return NULL;
     547             : }
     548             : 
     549             : node *
     550         857 : members_find_child_id(list *l, sqlid id)
     551             : {
     552         857 :         if (l) {
     553         857 :                 node *n;
     554        1222 :                 for (n = l->h; n; n = n->next) {
     555         709 :                         sql_part *p = n->data;
     556             : 
     557         709 :                         if (id == p->member)
     558         344 :                                 return n;
     559             :                 }
     560             :         }
     561             :         return NULL;
     562             : }
     563             : 
     564             : int
     565         522 : nested_mergetable(sql_trans *tr, sql_table *mt, const char *sname, const char *tname)
     566             : {
     567         522 :         if (strcmp(mt->s->base.name, sname) == 0 && strcmp(mt->base.name, tname) == 0)
     568             :                 return 1;
     569             :         /* try if this is also a partition */
     570         537 :         for( sql_part *parent = partition_find_part(tr, mt, NULL); parent; parent = partition_find_part(tr, mt, parent)) {
     571          20 :                 if (nested_mergetable(tr, parent->t, sname, tname))
     572             :                         return 1;
     573             :         }
     574             :         return 0;
     575             : }
     576             : 
     577             : bool
     578     3881496 : is_column_unique(sql_column *c)
     579             : {
     580             :         /* is it a primary key column itself? */
     581     3881496 :         if (c->t->pkey && list_length(c->t->pkey->k.columns) == 1 &&
     582      392419 :                 ((sql_kc*)c->t->pkey->k.columns->h->data)->c->base.id == c->base.id)
     583             :                 return true;
     584             :         /* is it a unique key itself */
     585     3743631 :         return c->unique == 2;
     586             : }
     587             : 
     588             : ValPtr
     589     6070502 : SA_VALcopy(allocator *sa, ValPtr d, const ValRecord *s)
     590             : {
     591     6070502 :         if (sa == NULL)
     592        1800 :                 return VALcopy(d, s);
     593     6068702 :         if (!ATOMextern(s->vtype)) {
     594     4381660 :                 *d = *s;
     595     1687042 :         } else if (s->val.pval == 0) {
     596           0 :                 const void *p = ATOMnilptr(s->vtype);
     597           0 :                 d->vtype = s->vtype;
     598           0 :                 d->len = ATOMlen(d->vtype, p);
     599           0 :                 d->val.pval = sa_alloc(sa, d->len);
     600           0 :                 if (d->val.pval == NULL)
     601             :                         return NULL;
     602           0 :                 memcpy(d->val.pval, p, d->len);
     603     1687042 :         } else if (s->vtype == TYPE_str) {
     604     1686748 :                 const char *p = s->val.sval;
     605     1686748 :                 d->vtype = TYPE_str;
     606     1686748 :                 d->len = strLen(p);
     607     1686748 :                 d->val.sval = sa_alloc(sa, d->len);
     608     1686748 :                 if (d->val.sval == NULL)
     609             :                         return NULL;
     610     1686748 :                 memcpy(d->val.sval, p, d->len);
     611             :         } else {
     612         294 :                 const void *p = s->val.pval;
     613         294 :                 d->vtype = s->vtype;
     614         294 :                 d->len = ATOMlen(d->vtype, p);
     615         294 :                 d->val.pval = sa_alloc(sa, d->len);
     616         294 :                 if (d->val.pval == NULL)
     617             :                         return NULL;
     618         294 :                 memcpy(d->val.pval, p, d->len);
     619             :         }
     620             :         return d;
     621             : }
     622             : 
     623             : atom *
     624      229032 : atom_copy(allocator *sa, atom *a)
     625             : {
     626      229032 :         atom *r = sa ?SA_NEW(sa, atom):MNEW(atom);
     627      229032 :         if (!r)
     628             :                 return NULL;
     629             : 
     630      229032 :         *r = (atom) {
     631      229032 :                 .isnull = a->isnull,
     632      229032 :                 .tpe = a->tpe,
     633             :                 .data = (ValRecord) {.vtype = TYPE_void,},
     634             :         };
     635      229032 :         if (!a->isnull)
     636      228295 :                 SA_VALcopy(sa, &r->data, &a->data);
     637             :         return r;
     638             : }
     639             : 
     640             : 
     641             : sql_table*
     642           0 : find_sys_table(sql_trans *tr, const char* tbl_name)
     643             : {
     644           0 :         sql_schema *sys = find_sql_schema(tr, "sys");
     645           0 :         return find_sql_table(tr, sys, tbl_name);
     646             : }

Generated by: LCOV version 1.14