LCOV - code coverage report
Current view: top level - sql/storage - sql_catalog.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 287 329 87.2 %
Date: 2025-03-25 21:27:32 Functions: 37 40 92.5 %

          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     1360094 : base_key( sql_base *b )
      21             : {
      22     1360094 :         return hash_key(b->name);
      23             : }
      24             : 
      25             : void
      26      582177 : trans_add(sql_trans *tr, sql_base *b, void *data, tc_cleanup_fptr cleanup, tc_commit_fptr commit, tc_log_fptr log)
      27             : {
      28      582177 :         sql_change *change = MNEW(sql_change);
      29             : 
      30      582146 :         *change = (sql_change) {
      31             :                 .obj = b,
      32             :                 .data = data,
      33             :                 .cleanup = cleanup,
      34             :                 .commit = commit,
      35             :                 .log = log,
      36             :         };
      37      582146 :         MT_lock_set(&tr->lock);
      38      582155 :         tr->changes = list_add(tr->changes, change);
      39      582067 :         if (log)
      40      263360 :                 tr->logchanges++;
      41      582067 :         MT_lock_unset(&tr->lock);
      42      582157 : }
      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        6071 : tr_version_of_parent(sql_trans *tr, ulng ts)
      62             : {
      63       11220 :         for( tr = tr->parent; tr; tr = tr->parent)
      64        7820 :                 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         883 : list_find_id(list *l, sqlid id)
     106             : {
     107         883 :         if (l) {
     108         881 :                 node *n;
     109       10518 :                 for (n = l->h; n; n = n->next) {
     110             : 
     111             :                         /* check if ids match */
     112        9644 :                         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        7419 : schema_find_key(sql_trans *tr, sql_schema *s, const char *name)
     160             : {
     161        7419 :         sql_base *b = os_find_name(s->keys, tr, name);
     162             : 
     163        7419 :         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       11082 : find_sql_idx(sql_table *t, const char *iname)
     178             : {
     179       11082 :         node *n = ol_find_name(t->idxs, iname);
     180       11082 :         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       21085 : schema_find_idx(sql_trans *tr, sql_schema *s, const char *name)
     201             : {
     202       21085 :         sql_base *b = os_find_name(s->idxs, tr, name);
     203             : 
     204       21177 :         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    10973758 : find_sql_column(sql_table *t, const char *cname)
     238             : {
     239    10973758 :         node *n = ol_find_name(t->columns, cname);
     240    11030248 :         if (n)
     241    10758714 :                 return n->data;
     242             :         return NULL;
     243             : }
     244             : 
     245             : sql_column *
     246         241 : find_sql_column_id(sql_table *t, sqlid col_id)
     247             : {
     248         241 :         node *n = ol_find_id(t->columns, col_id);
     249         241 :         if (n)
     250         241 :                 return n->data;
     251             :         return NULL;
     252             : }
     253             : 
     254             : sql_table *
     255     8216980 : find_sql_table(sql_trans *tr, sql_schema *s, const char *tname)
     256             : {
     257     8216980 :         sql_table *t = (sql_table*)os_find_name(s->tables, tr, tname);
     258             : 
     259     8281408 :         if (!t && tr->tmp == s) {
     260      213724 :                 t = (sql_table*) os_find_name(tr->localtmps, tr, tname);
     261      213724 :                 return t;
     262             :         }
     263             : 
     264     8000899 :         if (t && isTempTable(t) && tr->tmp == s) {
     265       67992 :                 sqlstore *store = tr->store;
     266       67992 :                 assert(isGlobal(t));
     267             : 
     268       67992 :                 sql_table* lt = (sql_table*) os_find_name(tr->localtmps, tr, tname);
     269       68070 :                 if (lt)
     270             :                         return lt;
     271        4624 :                 MT_lock_set(&store->table_locks[t->base.id&(NR_TABLE_LOCKS-1)]);
     272             : 
     273        4624 :                 lt = (sql_table*) os_find_name(tr->localtmps, tr, tname);
     274        4624 :                 if (!lt)
     275        4618 :                         t = globaltmp_instantiate(tr, t);
     276             :                 else
     277             :                         t = lt;
     278        4624 :                 MT_lock_unset(&store->table_locks[t->base.id&(NR_TABLE_LOCKS-1)]);
     279        4624 :                 return t;
     280             :         }
     281             : 
     282             :         return t;
     283             : }
     284             : 
     285             : sql_table *
     286       38313 : find_sql_table_id(sql_trans *tr, sql_schema *s, sqlid id)
     287             : {
     288       38313 :         sql_table *t = (sql_table*)os_find_id(s->tables, tr, id);
     289       38313 :         if (!t && tr->tmp == s) {
     290          59 :                 t = (sql_table*) os_find_id(tr->localtmps, tr, id);
     291          59 :                 return t;
     292             :         }
     293             : 
     294       38254 :         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        3696 : find_sql_sequence(sql_trans *tr, sql_schema *s, const char *sname)
     329             : {
     330        3696 :         return (sql_sequence*)os_find_name(s->seqs, tr, sname);
     331             : }
     332             : 
     333             : sql_schema *
     334    11603555 : find_sql_schema(sql_trans *tr, const char *sname)
     335             : {
     336    11603555 :         if (tr->tmp && strcmp(sname, "tmp")==0)
     337             :                 return tr->tmp;
     338    10965333 :         return (sql_schema*)os_find_name(tr->cat->schemas, tr, sname);
     339             : }
     340             : 
     341             : sql_schema *
     342        1852 : find_sql_schema_id(sql_trans *tr, sqlid id)
     343             : {
     344        1852 :         if (tr->tmp && tr->tmp->base.id == id)
     345             :                 return tr->tmp;
     346        1495 :         return (sql_schema*)os_find_id(tr->cat->schemas, tr, id);
     347             : }
     348             : 
     349             : sql_type *
     350       64857 : find_sql_type(sql_trans *tr, sql_schema *s, const char *tname)
     351             : {
     352       64857 :         return (sql_type*)os_find_name(s->types, tr, tname);
     353             : }
     354             : 
     355             : sql_type *
     356       52259 : sql_trans_bind_type(sql_trans *tr, sql_schema *c, const char *name)
     357             : {
     358       52259 :         struct os_iter oi;
     359       52259 :         os_iterator(&oi, tr->cat->schemas, tr, NULL);
     360       53806 :         for (sql_base *b = oi_next(&oi); b; b = oi_next(&oi)) {
     361       53585 :                 sql_schema *s = (sql_schema*)b;
     362       53585 :                 sql_type *t = find_sql_type(tr, s, name);
     363       53585 :                 if (t)
     364       52038 :                         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          39 : sql_trans_find_type(sql_trans *tr, sql_schema *s, sqlid id)
     373             : {
     374          39 :         if (s) {
     375          39 :                 sql_base *b = os_find_id(s->types, tr, id);
     376          39 :                 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         960 : schema_find_trigger(sql_trans *tr, sql_schema *s, const char *name)
     430             : {
     431         960 :         sql_base *b = os_find_name(s->triggers, tr, name);
     432             : 
     433         960 :         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      573096 : partition_find_part(sql_trans *tr, sql_table *pt, sql_part *pp)
     551             : {
     552      573096 :         struct os_iter oi;
     553             : 
     554      573096 :         if (!pt->s) /* declared table */
     555             :                 return NULL;
     556      573087 :         os_iterator(&oi, pt->s->parts, tr, NULL);
     557      599015 :         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        3322 :                         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     4222847 : is_column_unique(sql_column *c)
     601             : {
     602             :         /* is it a primary key column itself? */
     603     4222847 :         if (c->t->pkey && list_length(c->t->pkey->k.columns) == 1 &&
     604      410285 :                 ((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     4076632 :         return c->unique == 2;
     608             : }
     609             : 
     610             : ValPtr
     611     6747513 : SA_VALcopy(allocator *sa, ValPtr d, const ValRecord *s)
     612             : {
     613     6747513 :         if (sa == NULL)
     614        2029 :                 return VALcopy(d, s);
     615     6745484 :         if (!ATOMextern(s->vtype)) {
     616     4848429 :                 *d = *s;
     617     1897055 :         } 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     1897055 :         } else if (s->vtype == TYPE_str) {
     626     1896753 :                 const char *p = s->val.sval;
     627     1896753 :                 d->vtype = TYPE_str;
     628     1896753 :                 d->len = strLen(p);
     629     1896753 :                 d->val.sval = sa_alloc(sa, d->len);
     630     1896753 :                 if (d->val.sval == NULL)
     631             :                         return NULL;
     632     1896753 :                 memcpy(d->val.sval, p, d->len);
     633             :         } else {
     634         302 :                 const void *p = s->val.pval;
     635         302 :                 d->vtype = s->vtype;
     636         302 :                 d->len = ATOMlen(d->vtype, p);
     637         302 :                 d->val.pval = sa_alloc(sa, d->len);
     638         302 :                 if (d->val.pval == NULL)
     639             :                         return NULL;
     640         302 :                 memcpy(d->val.pval, p, d->len);
     641             :         }
     642             :         return d;
     643             : }
     644             : 
     645             : atom *
     646      268162 : atom_copy(allocator *sa, atom *a)
     647             : {
     648      268162 :         atom *r = sa ?SA_NEW(sa, atom):MNEW(atom);
     649      268162 :         if (!r)
     650             :                 return NULL;
     651             : 
     652      268162 :         *r = (atom) {
     653      268162 :                 .isnull = a->isnull,
     654      268162 :                 .tpe = a->tpe,
     655             :                 .data = (ValRecord) {.vtype = TYPE_void,},
     656             :         };
     657      268162 :         if (!a->isnull)
     658      267131 :                 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             : }

Generated by: LCOV version 1.14