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 1112 : _free(void *dummy, void *data)
18 : {
19 1112 : (void)dummy;
20 1112 : GDKfree(data);
21 1112 : }
22 :
23 : static sqlid
24 3 : list_find_func_id(list *ids, sqlid id)
25 : {
26 3 : node *n = ids->h;
27 6 : while (n) {
28 6 : sql_func * f = n->data;
29 6 : if (f->base.id == id)
30 : return id;
31 : else
32 3 : n = n->next;
33 : }
34 : return 0;
35 : }
36 :
37 : /*Function to create a dependency*/
38 : int
39 382546 : sql_trans_create_dependency(sql_trans* tr, sqlid id, sqlid depend_id, sql_dependency depend_type)
40 : {
41 382546 : assert(id && depend_id);
42 382546 : sqlstore *store = tr->store;
43 382546 : sql_schema * s = find_sql_schema(tr, "sys");
44 382546 : sql_table *t = find_sql_table(tr, s, "dependencies");
45 382546 : sql_column *c_id = find_sql_column(t, "id");
46 382546 : sql_column *c_dep_id = find_sql_column(t, "depend_id");
47 382546 : sql_column *c_dep_type = find_sql_column(t, "depend_type");
48 382546 : sht dtype = (sht) depend_type;
49 382546 : int log_res = LOG_OK;
50 :
51 382546 : 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 378961 : log_res = store->table_api.table_insert(tr, t, &id, &depend_id, &dtype);
53 :
54 382546 : return log_res;
55 : }
56 :
57 : /*Function to drop the dependencies on depend_id*/
58 : int
59 36878 : sql_trans_drop_dependencies(sql_trans* tr, sqlid depend_id)
60 : {
61 36878 : sqlstore *store = tr->store;
62 36878 : oid rid;
63 36878 : sql_schema * s = find_sql_schema(tr, "sys");
64 36878 : sql_table* deps = find_sql_table(tr, s, "dependencies");
65 36878 : sql_column * dep_dep_id = find_sql_column(deps, "depend_id");
66 36878 : rids *rs;
67 36878 : int log_res = LOG_OK;
68 :
69 36878 : rs = store->table_api.rids_select(tr, dep_dep_id, &depend_id, &depend_id, NULL);
70 36878 : if (rs == NULL)
71 : return LOG_ERR;
72 56006 : for (rid = store->table_api.rids_next(rs); !is_oid_nil(rid) && log_res == LOG_OK; rid = store->table_api.rids_next(rs))
73 19128 : log_res = store->table_api.table_delete(tr, deps, rid);
74 36878 : store->table_api.rids_destroy(rs);
75 36878 : return log_res;
76 : }
77 :
78 : /*Function to drop the dependency between object and target, ie obj_id/depend_id*/
79 : int
80 400 : sql_trans_drop_dependency(sql_trans* tr, sqlid obj_id, sqlid depend_id, sql_dependency depend_type)
81 : {
82 400 : sqlstore *store = tr->store;
83 400 : oid rid;
84 400 : sql_schema * s = find_sql_schema(tr, "sys");
85 400 : sql_table* deps = find_sql_table(tr, s, "dependencies");
86 400 : sql_column *dep_obj_id = find_sql_column(deps, "id");
87 400 : sql_column *dep_dep_id = find_sql_column(deps, "depend_id");
88 400 : sql_column *dep_dep_type = find_sql_column(deps, "depend_type");
89 400 : sht dtype = (sht) depend_type;
90 400 : rids *rs;
91 400 : int log_res = LOG_OK;
92 :
93 400 : 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 400 : if (rs == NULL)
95 : return LOG_ERR;
96 666 : for (rid = store->table_api.rids_next(rs); !is_oid_nil(rid) && log_res == LOG_OK; rid = store->table_api.rids_next(rs))
97 266 : log_res = store->table_api.table_delete(tr, deps, rid);
98 400 : store->table_api.rids_destroy(rs);
99 400 : return log_res;
100 : }
101 :
102 : /*It returns a list with depend_id_1, depend_type_1, depend_id_2, depend_type_2, ....*/
103 : list*
104 9141 : sql_trans_get_dependencies(sql_trans* tr, sqlid id, sql_dependency depend_type, list * ignore_ids)
105 : {
106 9141 : sqlstore *store = tr->store;
107 9141 : void *v;
108 9141 : sql_schema *s = find_sql_schema(tr, "sys");
109 9141 : sql_table *deps = find_sql_table(tr, s, "dependencies");
110 9141 : sql_column *dep_id, *dep_dep_id, *dep_dep_type, *tri_id, *table_id;
111 9141 : list *dep_list = list_create((fdestroy) _free);
112 9141 : oid rid;
113 9141 : rids *rs;
114 :
115 9141 : if (!dep_list)
116 : return NULL;
117 :
118 9141 : dep_id = find_sql_column(deps, "id");
119 9141 : dep_dep_id = find_sql_column(deps, "depend_id");
120 9141 : dep_dep_type = find_sql_column(deps, "depend_type");
121 :
122 9141 : rs = store->table_api.rids_select(tr, dep_id, &id, &id, NULL);
123 9141 : if (rs == NULL) {
124 0 : list_destroy(dep_list);
125 0 : return NULL;
126 : }
127 9682 : for (rid = store->table_api.rids_next(rs); !is_oid_nil(rid); rid = store->table_api.rids_next(rs)){
128 541 : if (!(v = store->table_api.column_find_value(tr, dep_dep_id, rid))) {
129 0 : list_destroy(dep_list);
130 0 : store->table_api.rids_destroy(rs);
131 0 : return NULL;
132 : }
133 541 : id = *(sqlid*)v;
134 544 : if (!(ignore_ids && list_find_func_id(ignore_ids, id))) {
135 538 : if (list_append(dep_list, v) == NULL) {
136 0 : _DELETE(v);
137 0 : list_destroy(dep_list);
138 0 : store->table_api.rids_destroy(rs);
139 0 : return NULL;
140 : }
141 538 : if (!(v = store->table_api.column_find_value(tr, dep_dep_type, rid))) {
142 0 : list_destroy(dep_list);
143 0 : store->table_api.rids_destroy(rs);
144 0 : return NULL;
145 : }
146 538 : if (list_append(dep_list, v) == NULL) {
147 0 : _DELETE(v);
148 0 : list_destroy(dep_list);
149 0 : store->table_api.rids_destroy(rs);
150 0 : return NULL;
151 : }
152 : } else {
153 541 : _DELETE(v);
154 : }
155 : }
156 9141 : store->table_api.rids_destroy(rs);
157 :
158 9141 : if (depend_type == TABLE_DEPENDENCY) {
159 3904 : sql_table *triggers = find_sql_table(tr, s, "triggers");
160 3904 : table_id = find_sql_column(triggers, "table_id");
161 3904 : tri_id = find_sql_column(triggers, "id");
162 3904 : depend_type = TRIGGER_DEPENDENCY;
163 :
164 3904 : rs = store->table_api.rids_select(tr, table_id, &id, &id, NULL);
165 3904 : if (rs == NULL) {
166 0 : list_destroy(dep_list);
167 0 : return NULL;
168 : }
169 3905 : for (rid = store->table_api.rids_next(rs); !is_oid_nil(rid); rid = store->table_api.rids_next(rs)) {
170 1 : if (!(v = store->table_api.column_find_value(tr, tri_id, rid))) {
171 0 : list_destroy(dep_list);
172 0 : store->table_api.rids_destroy(rs);
173 0 : return NULL;
174 : }
175 1 : if (list_append(dep_list, v) == NULL) {
176 0 : _DELETE(v);
177 0 : list_destroy(dep_list);
178 0 : store->table_api.rids_destroy(rs);
179 0 : return NULL;
180 : }
181 1 : if (!(v = MNEW(sht))) {
182 0 : list_destroy(dep_list);
183 0 : store->table_api.rids_destroy(rs);
184 0 : return NULL;
185 : }
186 1 : *(sht *) v = (sht) depend_type;
187 1 : if (list_append(dep_list, v) == NULL) {
188 0 : _DELETE(v);
189 0 : list_destroy(dep_list);
190 0 : store->table_api.rids_destroy(rs);
191 0 : return NULL;
192 : }
193 : }
194 3904 : store->table_api.rids_destroy(rs);
195 : }
196 : return dep_list;
197 : }
198 :
199 : /*It checks if there are dependency between two ID's */
200 : sqlid
201 163 : sql_trans_get_dependency_type(sql_trans *tr, sqlid id, sql_dependency depend_type)
202 : {
203 163 : sqlstore *store = tr->store;
204 163 : oid rid;
205 163 : sql_schema *s;
206 163 : sql_table *dep;
207 163 : sql_column *dep_id, *dep_dep_id, *dep_dep_type;
208 163 : sht dtype = (sht) depend_type;
209 :
210 163 : s = find_sql_schema(tr, "sys");
211 163 : dep = find_sql_table(tr, s, "dependencies");
212 163 : dep_id = find_sql_column(dep, "id");
213 163 : dep_dep_id = find_sql_column(dep, "depend_id");
214 163 : dep_dep_type = find_sql_column(dep, "depend_type");
215 :
216 163 : rid = store->table_api.column_find_row(tr, dep_id, &id, dep_dep_type, &dtype, NULL);
217 163 : if (!is_oid_nil(rid)) {
218 142 : return store->table_api.column_find_sqlid(tr, dep_dep_id, rid);
219 : } else {
220 : return -1;
221 : }
222 : }
223 :
224 : /*It checks if there are dependency between two ID's */
225 : int
226 0 : sql_trans_check_dependency(sql_trans *tr, sqlid id, sqlid depend_id, sql_dependency depend_type)
227 : {
228 0 : sqlstore *store = tr->store;
229 0 : oid rid;
230 0 : sql_schema *s;
231 0 : sql_table *dep;
232 0 : sql_column *dep_id, *dep_dep_id, *dep_dep_type;
233 0 : sht dtype = (sht) depend_type;
234 :
235 0 : s = find_sql_schema(tr, "sys");
236 0 : dep = find_sql_table(tr, s, "dependencies");
237 0 : dep_id = find_sql_column(dep, "id");
238 0 : dep_dep_id = find_sql_column(dep, "depend_id");
239 0 : dep_dep_type = find_sql_column(dep, "depend_type");
240 :
241 0 : rid = store->table_api.column_find_row(tr, dep_id, &id, dep_dep_id, &depend_id, dep_dep_type, &dtype, NULL);
242 0 : if (!is_oid_nil(rid))
243 : return 1;
244 0 : else return 0;
245 : }
246 :
247 : /*Schema on users*/
248 :
249 : list *
250 0 : sql_trans_schema_user_dependencies(sql_trans *tr, sqlid schema_id)
251 : {
252 0 : sqlstore *store = tr->store;
253 0 : void *v;
254 0 : sql_schema * s = find_sql_schema(tr, "sys");
255 0 : sql_table *auths = find_sql_table(tr, s, "auths");
256 0 : sql_column *auth_id = find_sql_column(auths, "id");
257 0 : sql_dependency type = USER_DEPENDENCY;
258 0 : list *l = list_create((fdestroy) _free);
259 0 : rids *users;
260 0 : oid rid;
261 :
262 0 : if (!l || !(users = backend_schema_user_dependencies(tr, schema_id))) {
263 0 : list_destroy(l);
264 0 : return NULL;
265 : }
266 :
267 0 : for (rid = store->table_api.rids_next(users); !is_oid_nil(rid); rid = store->table_api.rids_next(users)) {
268 0 : if (!(v = store->table_api.column_find_value(tr, auth_id, rid))) {
269 0 : list_destroy(l);
270 0 : store->table_api.rids_destroy(users);
271 0 : return NULL;
272 : }
273 0 : list_append(l,v);
274 0 : if (!(v = MNEW(sht))) {
275 0 : list_destroy(l);
276 0 : store->table_api.rids_destroy(users);
277 0 : return NULL;
278 : }
279 0 : *(sht*)v = (sht) type;
280 0 : list_append(l,v);
281 : }
282 0 : store->table_api.rids_destroy(users);
283 0 : return l;
284 : }
285 :
286 : /*owner on schemas*/
287 : list *
288 104 : sql_trans_owner_schema_dependencies(sql_trans *tr, sqlid owner_id)
289 : {
290 104 : sqlstore *store = tr->store;
291 104 : void *v;
292 104 : sql_schema * s = find_sql_schema(tr, "sys");
293 104 : sql_table *schemas = find_sql_table(tr, s, "schemas");
294 104 : sql_column *schema_owner = find_sql_column(schemas, "authorization");
295 104 : sql_column *schema_id = find_sql_column(schemas, "id");
296 104 : sql_dependency type = SCHEMA_DEPENDENCY;
297 104 : list *l = list_create((fdestroy) _free);
298 104 : rids *rs;
299 104 : oid rid;
300 :
301 104 : if (!l)
302 : return NULL;
303 :
304 104 : rs = store->table_api.rids_select(tr, schema_owner, &owner_id, &owner_id, NULL);
305 104 : if (rs == NULL)
306 : return NULL;
307 :
308 121 : for (rid = store->table_api.rids_next(rs); !is_oid_nil(rid); rid = store->table_api.rids_next(rs)) {
309 17 : if (!(v = store->table_api.column_find_value(tr, schema_id, rid))) {
310 0 : list_destroy(l);
311 0 : store->table_api.rids_destroy(rs);
312 0 : return NULL;
313 : }
314 17 : list_append(l, v);
315 17 : if (!(v = MNEW(sht))) {
316 0 : list_destroy(l);
317 0 : store->table_api.rids_destroy(rs);
318 0 : return NULL;
319 : }
320 17 : *(sht*)v = (sht) type;
321 17 : list_append(l,v);
322 : }
323 104 : store->table_api.rids_destroy(rs);
324 104 : return l;
325 : }
326 :
327 : /*Function on Functions*/
|