LCOV - code coverage report
Current view: top level - sql/storage - sql_catalog.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 283 325 87.1 %
Date: 2024-11-13 19:37:10 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     1270279 : base_key( sql_base *b )
      21             : {
      22     1270279 :         return hash_key(b->name);
      23             : }
      24             : 
      25             : void
      26      550872 : trans_add(sql_trans *tr, sql_base *b, void *data, tc_cleanup_fptr cleanup, tc_commit_fptr commit, tc_log_fptr log)
      27             : {
      28      550872 :         sql_change *change = MNEW(sql_change);
      29             : 
      30      550864 :         *change = (sql_change) {
      31             :                 .obj = b,
      32             :                 .data = data,
      33             :                 .cleanup = cleanup,
      34             :                 .commit = commit,
      35             :                 .log = log,
      36             :         };
      37      550864 :         MT_lock_set(&tr->lock);
      38      550867 :         tr->changes = list_add(tr->changes, change);
      39      550805 :         if (log)
      40      259686 :                 tr->logchanges++;
      41      550805 :         MT_lock_unset(&tr->lock);
      42      550863 : }
      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        6048 : tr_version_of_parent(sql_trans *tr, ulng ts)
      62             : {
      63       11164 :         for( tr = tr->parent; tr; tr = tr->parent)
      64        7798 :                 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         838 : list_find_id(list *l, sqlid id)
     106             : {
     107         838 :         if (l) {
     108         836 :                 node *n;
     109       10426 :                 for (n = l->h; n; n = n->next) {
     110             : 
     111             :                         /* check if ids match */
     112        9597 :                         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        7308 : schema_find_key(sql_trans *tr, sql_schema *s, const char *name)
     160             : {
     161        7308 :         sql_base *b = os_find_name(s->keys, tr, name);
     162             : 
     163        7308 :         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       10544 : find_sql_idx(sql_table *t, const char *iname)
     178             : {
     179       10544 :         node *n = ol_find_name(t->idxs, iname);
     180       10544 :         if (n)
     181        4021 :                 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       21053 : schema_find_idx(sql_trans *tr, sql_schema *s, const char *name)
     201             : {
     202       21053 :         sql_base *b = os_find_name(s->idxs, tr, name);
     203             : 
     204       21136 :         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    10023768 : find_sql_column(sql_table *t, const char *cname)
     238             : {
     239    10023768 :         node *n = ol_find_name(t->columns, cname);
     240    10069912 :         if (n)
     241     9805116 :                 return n->data;
     242             :         return NULL;
     243             : }
     244             : 
     245             : sql_table *
     246     7815623 : find_sql_table(sql_trans *tr, sql_schema *s, const char *tname)
     247             : {
     248     7815623 :         sql_table *t = (sql_table*)os_find_name(s->tables, tr, tname);
     249             : 
     250     7847624 :         if (!t && tr->tmp == s) {
     251      212899 :                 t = (sql_table*) os_find_name(tr->localtmps, tr, tname);
     252      212899 :                 return t;
     253             :         }
     254             : 
     255     7569604 :         if (t && isTempTable(t) && tr->tmp == s) {
     256       65001 :                 sqlstore *store = tr->store;
     257       65001 :                 assert(isGlobal(t));
     258             : 
     259       65001 :                 sql_table* lt = (sql_table*) os_find_name(tr->localtmps, tr, tname);
     260       64926 :                 if (lt)
     261             :                         return lt;
     262        4445 :                 MT_lock_set(&store->table_locks[t->base.id&(NR_TABLE_LOCKS-1)]);
     263             : 
     264        4445 :                 lt = (sql_table*) os_find_name(tr->localtmps, tr, tname);
     265        4445 :                 if (!lt)
     266        4438 :                         t = globaltmp_instantiate(tr, t);
     267             :                 else
     268             :                         t = lt;
     269        4445 :                 MT_lock_unset(&store->table_locks[t->base.id&(NR_TABLE_LOCKS-1)]);
     270        4445 :                 return t;
     271             :         }
     272             : 
     273             :         return t;
     274             : }
     275             : 
     276             : sql_table *
     277       38301 : find_sql_table_id(sql_trans *tr, sql_schema *s, sqlid id)
     278             : {
     279       38301 :         sql_table *t = (sql_table*)os_find_id(s->tables, tr, id);
     280       38301 :         if (!t && tr->tmp == s) {
     281          59 :                 t = (sql_table*) os_find_id(tr->localtmps, tr, id);
     282          59 :                 return t;
     283             :         }
     284             : 
     285       38242 :         if (t && isTempTable(t) && tr->tmp == s) {
     286          52 :                 sqlstore *store = tr->store;
     287          52 :                 assert(isGlobal(t));
     288             : 
     289          52 :                 sql_table* lt = (sql_table*) os_find_id(tr->localtmps, tr, id);
     290          52 :                 if (lt)
     291             :                         return lt;
     292           0 :                 MT_lock_set(&store->table_locks[id&(NR_TABLE_LOCKS-1)]);
     293           0 :                 lt = (sql_table*) os_find_id(tr->localtmps, tr, id);
     294           0 :                 if (!lt)
     295           0 :                         t = globaltmp_instantiate(tr, t);
     296             :                 else
     297             :                         t = lt;
     298           0 :                 MT_lock_unset(&store->table_locks[id&(NR_TABLE_LOCKS-1)]);
     299           0 :                 return t;
     300             :         }
     301             :         return t;
     302             : }
     303             : 
     304             : sql_table *
     305         238 : sql_trans_find_table(sql_trans *tr, sqlid id)
     306             : {
     307         238 :         struct os_iter oi;
     308         238 :         os_iterator(&oi, tr->cat->schemas, tr, NULL);
     309         400 :         for (sql_base *b = oi_next(&oi); b; b = oi_next(&oi)) {
     310         400 :                 sql_schema *s = (sql_schema*)b;
     311         400 :                 sql_base *bt = os_find_id(s->tables, tr, id);
     312         400 :                 if (bt)
     313         238 :                         return (sql_table*)bt;
     314             :         }
     315             :         return NULL;
     316             : }
     317             : 
     318             : sql_sequence *
     319        3655 : find_sql_sequence(sql_trans *tr, sql_schema *s, const char *sname)
     320             : {
     321        3655 :         return (sql_sequence*)os_find_name(s->seqs, tr, sname);
     322             : }
     323             : 
     324             : sql_schema *
     325    10849279 : find_sql_schema(sql_trans *tr, const char *sname)
     326             : {
     327    10849279 :         if (tr->tmp && strcmp(sname, "tmp")==0)
     328             :                 return tr->tmp;
     329    10237497 :         return (sql_schema*)os_find_name(tr->cat->schemas, tr, sname);
     330             : }
     331             : 
     332             : sql_schema *
     333        1770 : find_sql_schema_id(sql_trans *tr, sqlid id)
     334             : {
     335        1770 :         if (tr->tmp && tr->tmp->base.id == id)
     336             :                 return tr->tmp;
     337        1443 :         return (sql_schema*)os_find_id(tr->cat->schemas, tr, id);
     338             : }
     339             : 
     340             : sql_type *
     341       61041 : find_sql_type(sql_trans *tr, sql_schema *s, const char *tname)
     342             : {
     343       61041 :         return (sql_type*)os_find_name(s->types, tr, tname);
     344             : }
     345             : 
     346             : sql_type *
     347       49148 : sql_trans_bind_type(sql_trans *tr, sql_schema *c, const char *name)
     348             : {
     349       49148 :         struct os_iter oi;
     350       49148 :         os_iterator(&oi, tr->cat->schemas, tr, NULL);
     351       50695 :         for (sql_base *b = oi_next(&oi); b; b = oi_next(&oi)) {
     352       50474 :                 sql_schema *s = (sql_schema*)b;
     353       50474 :                 sql_type *t = find_sql_type(tr, s, name);
     354       50474 :                 if (t)
     355       48927 :                         return t;
     356             :         }
     357         221 :         if (c)
     358           0 :                 return find_sql_type(tr, c, name);
     359             :         return NULL;
     360             : }
     361             : 
     362             : sql_type *
     363           3 : sql_trans_find_type(sql_trans *tr, sql_schema *s, sqlid id)
     364             : {
     365           3 :         if (s) {
     366           3 :                 sql_base *b = os_find_id(s->types, tr, id);
     367           3 :                 if (b)
     368             :                         return (sql_type*)b;
     369             :         } else {
     370           0 :                 struct os_iter oi;
     371           0 :                 os_iterator(&oi, tr->cat->schemas, tr, NULL);
     372           0 :                 for (sql_base *b = oi_next(&oi); b; b = oi_next(&oi)) {
     373           0 :                         sql_schema *s = (sql_schema*)b;
     374           0 :                         sql_base *bt = os_find_id(s->types, tr, id);
     375           0 :                         if (bt)
     376           0 :                                 return (sql_type*)bt;
     377             :                 }
     378             :         }
     379             :         return NULL;
     380             : }
     381             : 
     382             : sql_func *
     383         389 : sql_trans_find_func(sql_trans *tr, sqlid id)
     384             : {
     385         389 :         struct os_iter oi;
     386         389 :         os_iterator(&oi, tr->cat->schemas, tr, NULL);
     387         601 :         for (sql_base *b = oi_next(&oi); b; b = oi_next(&oi)) {
     388         596 :                 sql_schema *s = (sql_schema*)b;
     389         596 :                 sql_base *bf = os_find_id(s->funcs, tr, id);
     390         596 :                 if (bf)
     391         384 :                         return (sql_func*)bf;
     392             :         }
     393             :         return NULL;
     394             : }
     395             : 
     396             : static sql_trigger *
     397          93 : find_sql_trigger(sql_table *t, const char *tname)
     398             : {
     399          93 :         node *n = ol_find_name(t->triggers, tname);
     400          93 :         if (n)
     401           0 :                 return n->data;
     402             :         return NULL;
     403             : }
     404             : 
     405             : sql_trigger *
     406           2 : sql_trans_find_trigger(sql_trans *tr, sqlid id)
     407             : {
     408           2 :         struct os_iter oi;
     409           2 :         os_iterator(&oi, tr->cat->schemas, tr, NULL);
     410           2 :         for (sql_base *b = oi_next(&oi); b; b = oi_next(&oi)) {
     411           2 :                 sql_schema *s = (sql_schema*)b;
     412           2 :                 sql_base *bt = os_find_id(s->triggers, tr, id);
     413           2 :                 if (bt)
     414           2 :                         return (sql_trigger*)bt;
     415             :         }
     416             :         return NULL;
     417             : }
     418             : 
     419             : sql_trigger *
     420         950 : schema_find_trigger(sql_trans *tr, sql_schema *s, const char *name)
     421             : {
     422         950 :         sql_base *b = os_find_name(s->triggers, tr, name);
     423             : 
     424         950 :         if (!b && tr->tmp == s) {
     425          95 :                 struct os_iter oi;
     426          95 :                 os_iterator(&oi, tr->localtmps, tr, NULL);
     427         188 :                 for(sql_base *b = oi_next(&oi); b; b = oi_next(&oi)) {
     428          93 :                         sql_table *t = (sql_table *) b;
     429          93 :                         sql_trigger *o = find_sql_trigger(t, name);
     430          93 :                         if (o)
     431           0 :                                 return o;
     432             :                 }
     433             :         }
     434             :         return (sql_trigger*)b;
     435             : }
     436             : 
     437             : void*
     438         197 : sql_values_list_element_validate_and_insert(void *v1, void *v2, void *tpe, int* res)
     439             : {
     440         197 :         sql_part_value* pt = (sql_part_value*) v1, *newp = (sql_part_value*) v2;
     441         197 :         sql_subtype *tp = (sql_subtype *) tpe;
     442             : 
     443         197 :         *res = ATOMcmp(tp->type->localtype, newp->value, pt->value);
     444         197 :         return *res == 0 ? pt : NULL;
     445             : }
     446             : 
     447             : void*
     448         136 : sql_range_part_validate_and_insert(void *v1, void *v2, void *type)
     449             : {
     450         136 :         sql_part* pt = (sql_part*) v1, *newp = (sql_part*) v2;
     451         136 :         int res1, res2, tpe = *(int*)type;
     452         136 :         const void *nil = ATOMnilptr(tpe);
     453         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;
     454             : 
     455         136 :         if (pt == newp) /* same pointer, skip (used in updates) */
     456             :                 return NULL;
     457             : 
     458         133 :         if (is_bit_nil(pt->with_nills) || is_bit_nil(newp->with_nills)) /* if one partition holds all including nills, then conflicts */
     459             :                 return pt;
     460         129 :         if (newp->with_nills && pt->with_nills) /* only one partition at most has null values */
     461             :                 return pt;
     462             : 
     463         123 :         pt_down_all = !ATOMcmp(tpe, nil, pt->part.range.minvalue);
     464         123 :         pt_upper_all = !ATOMcmp(tpe, nil, pt->part.range.maxvalue);
     465         123 :         newp_down_all = !ATOMcmp(tpe, nil, newp->part.range.minvalue);
     466         123 :         newp_upper_all = !ATOMcmp(tpe, nil, newp->part.range.maxvalue);
     467             : 
     468             :         /* if one partition just holds NULL values, then there's no conflict */
     469         123 :         if ((newp_down_all && newp_upper_all && newp->with_nills) || (pt_down_all && pt_upper_all && pt->with_nills))
     470             :                 return NULL;
     471             :          /* holds all range, will always conflict */
     472         107 :         if ((pt_down_all && pt_upper_all && !pt->with_nills) || (newp_down_all && newp_upper_all && !newp->with_nills))
     473             :                 return pt;
     474             : 
     475         103 :         pt_min_max_same = !ATOMcmp(tpe, pt->part.range.maxvalue, pt->part.range.minvalue);
     476         103 :         newp_min_max_same = !ATOMcmp(tpe, newp->part.range.maxvalue, newp->part.range.minvalue);
     477             : 
     478         103 :         if (pt_down_all) { /* from range min value until a value */
     479          23 :                 res1 = ATOMcmp(tpe, pt->part.range.maxvalue, newp->part.range.minvalue);
     480          23 :                 if (newp_down_all || (!newp_min_max_same && res1 > 0) || (newp_min_max_same && res1 >= 0))
     481             :                         return pt;
     482             :                 return NULL;
     483             :         }
     484          80 :         if (pt_upper_all) { /* from value until range max value */
     485           9 :                 res1 = ATOMcmp(tpe, newp->part.range.maxvalue, pt->part.range.minvalue);
     486           9 :                 if (newp_upper_all || (!newp_min_max_same && res1 > 0) || (newp_min_max_same && res1 >= 0))
     487             :                         return pt;
     488             :                 return NULL;
     489             :         }
     490          71 :         if (newp_down_all) { /* from range min value until a value */
     491           2 :                 res1 = ATOMcmp(tpe, newp->part.range.maxvalue, pt->part.range.minvalue);
     492           2 :                 if (pt_down_all || (!newp_min_max_same && res1 > 0) || (newp_min_max_same && res1 >= 0))
     493             :                         return pt;
     494             :                 return NULL;
     495             :         }
     496          69 :         if (newp_upper_all) { /* from value until range max value */
     497          15 :                 res1 = ATOMcmp(tpe, pt->part.range.maxvalue, newp->part.range.minvalue);
     498          15 :                 if (pt_upper_all || (!pt_min_max_same && res1 > 0) || (pt_min_max_same && res1 >= 0))
     499             :                         return pt;
     500             :                 return NULL;
     501             :         }
     502             : 
     503             :         /* Fallback into normal cases */
     504          54 :         res1 = ATOMcmp(tpe, newp->part.range.maxvalue, pt->part.range.minvalue);
     505          54 :         res2 = ATOMcmp(tpe, pt->part.range.maxvalue, newp->part.range.minvalue);
     506             :         /* overlap: y2 > x1 && x2 > y1 */
     507          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)))
     508             :                 return pt;
     509             :         return NULL;
     510             : }
     511             : 
     512             : void*
     513          44 : sql_values_part_validate_and_insert(void *v1, void *v2, void *type)
     514             : {
     515          44 :         sql_part* pt = (sql_part*) v1, *newp = (sql_part*) v2;
     516          44 :         list* b1 = pt->part.values, *b2 = newp->part.values;
     517          44 :         node *n1 = b1->h, *n2 = b2->h;
     518          44 :         int res, tpe = *(int*)type;
     519             : 
     520          44 :         if (pt == newp) /* same pointer, skip (used in updates) */
     521             :                 return NULL;
     522             : 
     523          42 :         if (newp->with_nills && pt->with_nills)
     524             :                 return pt; /* check for nulls first */
     525             : 
     526         145 :         while (n1 && n2) {
     527         108 :                 sql_part_value *p1 = (sql_part_value *) n1->data, *p2 = (sql_part_value *) n2->data;
     528         108 :                 res = ATOMcmp(tpe, p1->value, p2->value);
     529         108 :                 if (!res) { /* overlap -> same value in both partitions */
     530             :                         return pt;
     531         104 :                 } else if (res < 0) {
     532         101 :                         n1 = n1->next;
     533             :                 } else {
     534           3 :                         n2 = n2->next;
     535             :                 }
     536             :         }
     537             :         return NULL;
     538             : }
     539             : 
     540             : sql_part *
     541      787364 : partition_find_part(sql_trans *tr, sql_table *pt, sql_part *pp)
     542             : {
     543      787364 :         struct os_iter oi;
     544             : 
     545      787364 :         if (!pt->s) /* declared table */
     546             :                 return NULL;
     547      787355 :         os_iterator(&oi, pt->s->parts, tr, NULL);
     548      821108 :         for (sql_base *b = oi_next(&oi); b; b = oi_next(&oi)) {
     549       36022 :                 sql_part *p = (sql_part*)b;
     550             : 
     551       36022 :                 if (pp) {
     552         131 :                         if (p == pp)
     553          18 :                                 pp = NULL;
     554         131 :                         continue;
     555             :                 }
     556       35891 :                 if (p->member == pt->base.id)
     557        3344 :                         return p;
     558             :         }
     559             :         return NULL;
     560             : }
     561             : 
     562             : node *
     563         963 : members_find_child_id(list *l, sqlid id)
     564             : {
     565         963 :         if (l) {
     566         963 :                 node *n;
     567        1370 :                 for (n = l->h; n; n = n->next) {
     568         782 :                         sql_part *p = n->data;
     569             : 
     570         782 :                         if (id == p->member)
     571         375 :                                 return n;
     572             :                 }
     573             :         }
     574             :         return NULL;
     575             : }
     576             : 
     577             : int
     578         593 : nested_mergetable(sql_trans *tr, sql_table *mt, const char *sname, const char *tname)
     579             : {
     580         593 :         if (strcmp(mt->s->base.name, sname) == 0 && strcmp(mt->base.name, tname) == 0)
     581             :                 return 1;
     582             :         /* try if this is also a partition */
     583         609 :         for( sql_part *parent = partition_find_part(tr, mt, NULL); parent; parent = partition_find_part(tr, mt, parent)) {
     584          21 :                 if (nested_mergetable(tr, parent->t, sname, tname))
     585             :                         return 1;
     586             :         }
     587             :         return 0;
     588             : }
     589             : 
     590             : bool
     591     3904309 : is_column_unique(sql_column *c)
     592             : {
     593             :         /* is it a primary key column itself? */
     594     3904309 :         if (c->t->pkey && list_length(c->t->pkey->k.columns) == 1 &&
     595      401219 :                 ((sql_kc*)c->t->pkey->k.columns->h->data)->c->base.id == c->base.id)
     596             :                 return true;
     597             :         /* is it a unique key itself */
     598     3762952 :         return c->unique == 2;
     599             : }
     600             : 
     601             : ValPtr
     602     6281690 : SA_VALcopy(allocator *sa, ValPtr d, const ValRecord *s)
     603             : {
     604     6281690 :         if (sa == NULL)
     605        1819 :                 return VALcopy(d, s);
     606     6279871 :         if (!ATOMextern(s->vtype)) {
     607     4506302 :                 *d = *s;
     608     1773569 :         } else if (s->val.pval == 0) {
     609           0 :                 const void *p = ATOMnilptr(s->vtype);
     610           0 :                 d->vtype = s->vtype;
     611           0 :                 d->len = ATOMlen(d->vtype, p);
     612           0 :                 d->val.pval = sa_alloc(sa, d->len);
     613           0 :                 if (d->val.pval == NULL)
     614             :                         return NULL;
     615           0 :                 memcpy(d->val.pval, p, d->len);
     616     1773569 :         } else if (s->vtype == TYPE_str) {
     617     1773283 :                 const char *p = s->val.sval;
     618     1773283 :                 d->vtype = TYPE_str;
     619     1773283 :                 d->len = strLen(p);
     620     1773283 :                 d->val.sval = sa_alloc(sa, d->len);
     621     1773283 :                 if (d->val.sval == NULL)
     622             :                         return NULL;
     623     1773283 :                 memcpy(d->val.sval, p, d->len);
     624             :         } else {
     625         286 :                 const void *p = s->val.pval;
     626         286 :                 d->vtype = s->vtype;
     627         286 :                 d->len = ATOMlen(d->vtype, p);
     628         286 :                 d->val.pval = sa_alloc(sa, d->len);
     629         286 :                 if (d->val.pval == NULL)
     630             :                         return NULL;
     631         286 :                 memcpy(d->val.pval, p, d->len);
     632             :         }
     633             :         return d;
     634             : }
     635             : 
     636             : atom *
     637      261753 : atom_copy(allocator *sa, atom *a)
     638             : {
     639      261753 :         atom *r = sa ?SA_NEW(sa, atom):MNEW(atom);
     640      261753 :         if (!r)
     641             :                 return NULL;
     642             : 
     643      261753 :         *r = (atom) {
     644      261753 :                 .isnull = a->isnull,
     645      261753 :                 .tpe = a->tpe,
     646             :                 .data = (ValRecord) {.vtype = TYPE_void,},
     647             :         };
     648      261753 :         if (!a->isnull)
     649      260650 :                 SA_VALcopy(sa, &r->data, &a->data);
     650             :         return r;
     651             : }
     652             : 
     653             : 
     654             : sql_table*
     655           0 : find_sys_table(sql_trans *tr, const char* tbl_name)
     656             : {
     657           0 :         sql_schema *sys = find_sql_schema(tr, "sys");
     658           0 :         return find_sql_table(tr, sys, tbl_name);
     659             : }

Generated by: LCOV version 1.14