LCOV - code coverage report
Current view: top level - sql/storage - store_dependency.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 172 257 66.9 %
Date: 2024-11-15 19:37:45 Functions: 8 9 88.9 %

          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 "store_dependency.h"
      15             : 
      16             : static void
      17        1127 : _free(void *dummy, void *data)
      18             : {
      19        1127 :         (void)dummy;
      20        1127 :         GDKfree(data);
      21        1127 : }
      22             : 
      23             : static sqlid
      24           3 : list_find_func_id(list *ids, sqlid id)
      25             : {
      26           3 :         node *n = ids->h;
      27           3 :         while (n) {
      28           3 :                 sql_func * f = n->data;
      29           3 :                 if (f->base.id == id)
      30             :                         return id;
      31             :                 else
      32           0 :                         n = n->next;
      33             :         }
      34             :         return 0;
      35             : }
      36             : 
      37             : /*Function to create a dependency*/
      38             : int
      39      382296 : sql_trans_create_dependency(sql_trans* tr, sqlid id, sqlid depend_id, sql_dependency depend_type)
      40             : {
      41      382296 :         assert(id && depend_id);
      42      382296 :         sqlstore *store = tr->store;
      43      382296 :         sql_schema * s = find_sql_schema(tr, "sys");
      44      382296 :         sql_table *t = find_sql_table(tr, s, "dependencies");
      45      382296 :         sql_column *c_id = find_sql_column(t, "id");
      46      382296 :         sql_column *c_dep_id = find_sql_column(t, "depend_id");
      47      382296 :         sql_column *c_dep_type = find_sql_column(t, "depend_type");
      48      382296 :         sht dtype = (sht) depend_type;
      49      382296 :         int log_res = LOG_OK;
      50             : 
      51      382296 :         if (is_oid_nil(store->table_api.column_find_row(tr, c_id, &id, c_dep_id, &depend_id, c_dep_type, &dtype, NULL)))
      52      378687 :                 log_res = store->table_api.table_insert(tr, t, &id, &depend_id, &dtype);
      53             : 
      54      382296 :         return log_res;
      55             : }
      56             : 
      57             : /*Function to drop the dependencies on depend_id*/
      58             : int
      59       37695 : sql_trans_drop_dependencies(sql_trans* tr, sqlid depend_id)
      60             : {
      61       37695 :         sqlstore *store = tr->store;
      62       37695 :         oid rid;
      63       37695 :         sql_schema * s = find_sql_schema(tr, "sys");
      64       37695 :         sql_table* deps = find_sql_table(tr, s, "dependencies");
      65       37695 :         sql_column * dep_dep_id = find_sql_column(deps, "depend_id");
      66       37695 :         rids *rs;
      67       37695 :         int log_res = LOG_OK;
      68             : 
      69       37695 :         rs = store->table_api.rids_select(tr, dep_dep_id, &depend_id, &depend_id, NULL);
      70       37695 :         if (rs == NULL)
      71             :                 return LOG_ERR;
      72       56267 :         for (rid = store->table_api.rids_next(rs); !is_oid_nil(rid) && log_res == LOG_OK; rid = store->table_api.rids_next(rs))
      73       18572 :                 log_res = store->table_api.table_delete(tr, deps, rid);
      74       37695 :         store->table_api.rids_destroy(rs);
      75       37695 :         return log_res;
      76             : }
      77             : 
      78             : /*Function to drop the dependency between object and target, ie obj_id/depend_id*/
      79             : int
      80         422 : sql_trans_drop_dependency(sql_trans* tr, sqlid obj_id, sqlid depend_id, sql_dependency depend_type)
      81             : {
      82         422 :         sqlstore *store = tr->store;
      83         422 :         oid rid;
      84         422 :         sql_schema * s = find_sql_schema(tr, "sys");
      85         422 :         sql_table* deps = find_sql_table(tr, s, "dependencies");
      86         422 :         sql_column *dep_obj_id = find_sql_column(deps, "id");
      87         422 :         sql_column *dep_dep_id = find_sql_column(deps, "depend_id");
      88         422 :         sql_column *dep_dep_type = find_sql_column(deps, "depend_type");
      89         422 :         sht dtype = (sht) depend_type;
      90         422 :         rids *rs;
      91         422 :         int log_res = LOG_OK;
      92             : 
      93         422 :         rs = store->table_api.rids_select(tr, dep_obj_id, &obj_id, &obj_id, dep_dep_id, &depend_id, &depend_id, dep_dep_type, &dtype, &dtype, NULL);
      94         422 :         if (rs == NULL)
      95             :                 return LOG_ERR;
      96         714 :         for (rid = store->table_api.rids_next(rs); !is_oid_nil(rid) && log_res == LOG_OK; rid = store->table_api.rids_next(rs))
      97         292 :                 log_res = store->table_api.table_delete(tr, deps, rid);
      98         422 :         store->table_api.rids_destroy(rs);
      99         422 :         return log_res;
     100             : }
     101             : 
     102             : /*It returns a list with depend_id_1, depend_type_1,
     103             :                          depend_id_2, depend_type_2, ....*/
     104             : list*
     105        9532 : sql_trans_get_dependents(sql_trans* tr, sqlid id,
     106             :                                                  sql_dependency dependent_type,
     107             :                                                  list * ignore_ids)
     108             : {
     109        9532 :         sqlstore *store = tr->store;
     110        9532 :         table_functions table_api = store->table_api;
     111        9532 :         sql_schema *s = find_sql_schema(tr, "sys");
     112        9532 :         sql_table *deps = find_sql_table(tr, s, "dependencies");
     113        9532 :         sql_column *dep_id, *dep_dep_id, *dep_dep_type, *tri_id, *table_id;
     114        9532 :         list *dep_list = list_create((fdestroy)_free),
     115        9532 :                 *schema_tables = NULL;
     116        9532 :         void *v;
     117        9532 :         oid rid;
     118        9532 :         rids *rs;
     119        9532 :         sqlid low_id = id, high_id = -1;
     120             : 
     121        9532 :         if (!dep_list)
     122             :                 return NULL;
     123             : 
     124        9532 :         dep_id = find_sql_column(deps, "id");
     125        9532 :         dep_dep_id = find_sql_column(deps, "depend_id");
     126        9532 :         dep_dep_type = find_sql_column(deps, "depend_type");
     127             : 
     128        9532 :         if (dependent_type == SCHEMA_DEPENDENCY) {
     129          17 :                 sql_schema *s = find_sql_schema_id(tr, id);
     130          17 :                 assert(s);
     131          17 :                 schema_tables = list_create((fdestroy)_free);
     132          17 :                 if (schema_tables == NULL) {
     133           0 :                         list_destroy(dep_list);
     134           0 :                         return NULL;
     135             :                 }
     136          17 :                 struct os_iter oi;
     137          17 :                 os_iterator(&oi, s->tables, tr, NULL);
     138          17 :                 bool first = true;
     139          20 :                 for (sql_base *b = oi_next(&oi); b; b = oi_next(&oi)) {
     140           3 :                         sqlid* local_id = MNEW(sqlid);
     141           3 :                         if (local_id == NULL) {
     142           0 :                                 list_destroy(dep_list);
     143           0 :                                 return NULL;
     144             :                         }
     145           3 :                         *local_id = b->id;
     146           3 :                         if (list_append(schema_tables, local_id) == NULL) {
     147           0 :                                 list_destroy(dep_list);
     148           0 :                                 list_destroy(schema_tables);
     149           0 :                                 return NULL;
     150             :                         }
     151           3 :                         if (first) {
     152           3 :                                 low_id = b->id;
     153           3 :                                 first = false;
     154             :                         }
     155           3 :                         high_id = b->id;
     156             :                 }
     157             :         }
     158             : 
     159        9532 :         rs = table_api.rids_select(tr, dep_id, &low_id,
     160        9532 :                                                            high_id == -1 ? &low_id :
     161           3 :                                                            low_id == high_id ? &low_id : &high_id,
     162             :                                                            NULL);
     163        9532 :         if (rs == NULL) {
     164           0 :                 list_destroy(dep_list);
     165           0 :                 list_destroy(schema_tables);
     166           0 :                 return NULL;
     167             :         }
     168             : 
     169       10079 :         for (rid = table_api.rids_next(rs); !is_oid_nil(rid); rid = table_api.rids_next(rs)){
     170         547 :                 if (dependent_type == SCHEMA_DEPENDENCY) {
     171           1 :                         if (!(v = table_api.column_find_value(tr, dep_id, rid))) {
     172           0 :                                 list_destroy(dep_list);
     173           0 :                                 list_destroy(schema_tables);
     174           0 :                                 table_api.rids_destroy(rs);
     175           0 :                                 return NULL;
     176             :                         }
     177           1 :                         if (list_find_id(schema_tables, *(sqlid*)v) == NULL) {
     178           0 :                                 _DELETE(v);
     179           0 :                                 continue;
     180             :                         }
     181           1 :                         _DELETE(v);
     182             :                 }
     183         547 :                 if (!(v = table_api.column_find_value(tr, dep_dep_id, rid))) {
     184           0 :                         list_destroy(dep_list);
     185           0 :                         list_destroy(schema_tables);
     186           0 :                         table_api.rids_destroy(rs);
     187           0 :                         return NULL;
     188             :                 }
     189         547 :                 id = *(sqlid*)v;
     190         550 :                 if (!(ignore_ids && list_find_func_id(ignore_ids, id))) {
     191         544 :                         if (list_append(dep_list, v) == NULL) {
     192           0 :                                 _DELETE(v);
     193           0 :                                 list_destroy(dep_list);
     194           0 :                                 list_destroy(schema_tables);
     195           0 :                                 table_api.rids_destroy(rs);
     196           0 :                                 return NULL;
     197             :                         }
     198         544 :                         if (!(v = table_api.column_find_value(tr, dep_dep_type, rid))) {
     199           0 :                                 list_destroy(dep_list);
     200           0 :                                 list_destroy(schema_tables);
     201           0 :                                 table_api.rids_destroy(rs);
     202           0 :                                 return NULL;
     203             :                         }
     204         544 :                         if (list_append(dep_list, v) == NULL) {
     205           0 :                                 _DELETE(v);
     206           0 :                                 list_destroy(dep_list);
     207           0 :                                 list_destroy(schema_tables);
     208           0 :                                 table_api.rids_destroy(rs);
     209           0 :                                 return NULL;
     210             :                         }
     211             :                 } else {
     212         547 :                         _DELETE(v);
     213             :                 }
     214             :         }
     215        9532 :         table_api.rids_destroy(rs);
     216             : 
     217        9532 :         if (dependent_type == SCHEMA_DEPENDENCY)
     218          17 :                 list_destroy(schema_tables);
     219             : 
     220        9532 :         if (dependent_type == TABLE_DEPENDENCY) {
     221        4056 :                 sql_table *triggers = find_sql_table(tr, s, "triggers");
     222        4056 :                 table_id = find_sql_column(triggers, "table_id");
     223        4056 :                 tri_id = find_sql_column(triggers, "id");
     224        4056 :                 dependent_type = TRIGGER_DEPENDENCY;
     225             : 
     226        4056 :                 rs = table_api.rids_select(tr, table_id, &id, &id, NULL);
     227        4056 :                 if (rs == NULL) {
     228           0 :                         list_destroy(dep_list);
     229           0 :                         return NULL;
     230             :                 }
     231        4057 :                 for (rid = table_api.rids_next(rs); !is_oid_nil(rid); rid = table_api.rids_next(rs)) {
     232           1 :                         if (!(v = table_api.column_find_value(tr, tri_id, rid))) {
     233           0 :                                 list_destroy(dep_list);
     234           0 :                                 table_api.rids_destroy(rs);
     235           0 :                                 return NULL;
     236             :                         }
     237           1 :                         if (list_append(dep_list, v) == NULL) {
     238           0 :                                 _DELETE(v);
     239           0 :                                 list_destroy(dep_list);
     240           0 :                                 table_api.rids_destroy(rs);
     241           0 :                                 return NULL;
     242             :                         }
     243           1 :                         if (!(v = MNEW(sht))) {
     244           0 :                                 list_destroy(dep_list);
     245           0 :                                 table_api.rids_destroy(rs);
     246           0 :                                 return NULL;
     247             :                         }
     248           1 :                         *(sht *) v = (sht) dependent_type;
     249           1 :                         if (list_append(dep_list, v) == NULL) {
     250           0 :                                 _DELETE(v);
     251           0 :                                 list_destroy(dep_list);
     252           0 :                                 table_api.rids_destroy(rs);
     253           0 :                                 return NULL;
     254             :                         }
     255             :                 }
     256        4056 :                 table_api.rids_destroy(rs);
     257             :         }
     258             : 
     259             :         return dep_list;
     260             : }
     261             : 
     262             : /*It checks if there are dependency between two ID's */
     263             : sqlid
     264         164 : sql_trans_get_dependency_type(sql_trans *tr, sqlid id, sql_dependency depend_type)
     265             : {
     266         164 :         sqlstore *store = tr->store;
     267         164 :         oid rid;
     268         164 :         sql_schema *s;
     269         164 :         sql_table *dep;
     270         164 :         sql_column *dep_id, *dep_dep_id, *dep_dep_type;
     271         164 :         sht dtype = (sht) depend_type;
     272             : 
     273         164 :         s = find_sql_schema(tr, "sys");
     274         164 :         dep = find_sql_table(tr, s, "dependencies");
     275         164 :         dep_id = find_sql_column(dep, "id");
     276         164 :         dep_dep_id = find_sql_column(dep, "depend_id");
     277         164 :         dep_dep_type = find_sql_column(dep, "depend_type");
     278             : 
     279         164 :         rid = store->table_api.column_find_row(tr, dep_id, &id, dep_dep_type, &dtype, NULL);
     280         164 :         if (!is_oid_nil(rid)) {
     281         143 :                 return store->table_api.column_find_sqlid(tr, dep_dep_id, rid);
     282             :         } else {
     283             :                 return -1;
     284             :         }
     285             : }
     286             : 
     287             : /*It checks if there are dependency between two ID's */
     288             : int
     289           0 : sql_trans_check_dependency(sql_trans *tr, sqlid id, sqlid depend_id, sql_dependency depend_type)
     290             : {
     291           0 :         sqlstore *store = tr->store;
     292           0 :         oid rid;
     293           0 :         sql_schema *s;
     294           0 :         sql_table *dep;
     295           0 :         sql_column *dep_id, *dep_dep_id, *dep_dep_type;
     296           0 :         sht dtype = (sht) depend_type;
     297             : 
     298           0 :         s = find_sql_schema(tr, "sys");
     299           0 :         dep = find_sql_table(tr, s, "dependencies");
     300           0 :         dep_id = find_sql_column(dep, "id");
     301           0 :         dep_dep_id = find_sql_column(dep, "depend_id");
     302           0 :         dep_dep_type = find_sql_column(dep, "depend_type");
     303             : 
     304           0 :         rid = store->table_api.column_find_row(tr, dep_id, &id, dep_dep_id, &depend_id, dep_dep_type, &dtype, NULL);
     305           0 :         if (!is_oid_nil(rid))
     306             :                 return 1;
     307           0 :         else return 0;
     308             : }
     309             : 
     310             : /*Schema on users*/
     311             : 
     312             : list *
     313          17 : sql_trans_schema_user_dependencies(sql_trans *tr, sqlid schema_id)
     314             : {
     315          17 :         sqlstore *store = tr->store;
     316          17 :         void *v;
     317          17 :         sql_schema * s = find_sql_schema(tr, "sys");
     318          17 :         sql_table *auths = find_sql_table(tr, s, "auths");
     319          17 :         sql_column *auth_id = find_sql_column(auths, "id");
     320          17 :         sql_dependency type = USER_DEPENDENCY;
     321          17 :         list *l = list_create((fdestroy) _free);
     322          17 :         rids *users;
     323          17 :         oid rid;
     324             : 
     325          17 :         if (!l || !(users = backend_schema_user_dependencies(tr, schema_id))) {
     326           0 :                 list_destroy(l);
     327           0 :                 return NULL;
     328             :         }
     329             : 
     330          17 :         for (rid = store->table_api.rids_next(users); !is_oid_nil(rid); rid = store->table_api.rids_next(users)) {
     331           0 :                 if (!(v = store->table_api.column_find_value(tr, auth_id, rid))) {
     332           0 :                         list_destroy(l);
     333           0 :                         store->table_api.rids_destroy(users);
     334           0 :                         return NULL;
     335             :                 }
     336           0 :                 list_append(l,v);
     337           0 :                 if (!(v = MNEW(sht))) {
     338           0 :                         list_destroy(l);
     339           0 :                         store->table_api.rids_destroy(users);
     340           0 :                         return NULL;
     341             :                 }
     342           0 :                 *(sht*)v = (sht) type;
     343           0 :                 list_append(l,v);
     344             :         }
     345          17 :         store->table_api.rids_destroy(users);
     346             : 
     347          17 :         if (list_length(l) == 0) {
     348          17 :                 list_destroy(l);
     349          17 :                 l = NULL;
     350             :         }
     351             : 
     352             :         return l;
     353             : }
     354             : 
     355             : /*owner on schemas*/
     356             : list *
     357         107 : sql_trans_owner_schema_dependencies(sql_trans *tr, sqlid owner_id)
     358             : {
     359         107 :         sqlstore *store = tr->store;
     360         107 :         void *v;
     361         107 :         sql_schema * s = find_sql_schema(tr, "sys");
     362         107 :         sql_table *schemas = find_sql_table(tr, s, "schemas");
     363         107 :         sql_column *schema_owner = find_sql_column(schemas, "authorization");
     364         107 :         sql_column *schema_id = find_sql_column(schemas, "id");
     365         107 :         sql_dependency type = SCHEMA_DEPENDENCY;
     366         107 :         list *l = list_create((fdestroy) _free);
     367         107 :         rids *rs;
     368         107 :         oid rid;
     369             : 
     370         107 :         if (!l)
     371             :                 return NULL;
     372             : 
     373         107 :         rs = store->table_api.rids_select(tr, schema_owner, &owner_id, &owner_id, NULL);
     374         107 :         if (rs == NULL)
     375             :                 return NULL;
     376             : 
     377         124 :         for (rid = store->table_api.rids_next(rs); !is_oid_nil(rid); rid = store->table_api.rids_next(rs)) {
     378          17 :                 if (!(v = store->table_api.column_find_value(tr, schema_id, rid))) {
     379           0 :                         list_destroy(l);
     380           0 :                         store->table_api.rids_destroy(rs);
     381           0 :                         return NULL;
     382             :                 }
     383          17 :                 list_append(l, v);
     384          17 :                 if (!(v = MNEW(sht))) {
     385           0 :                         list_destroy(l);
     386           0 :                         store->table_api.rids_destroy(rs);
     387           0 :                         return NULL;
     388             :                 }
     389          17 :                 *(sht*)v = (sht) type;
     390          17 :                 list_append(l,v);
     391             :         }
     392         107 :         store->table_api.rids_destroy(rs);
     393         107 :         return l;
     394             : }
     395             : 
     396             : /*Function on Functions*/

Generated by: LCOV version 1.14