1/*
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5 *
6 * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
7 */
8
9#include "monetdb_config.h"
10#include "store_dependency.h"
11
12static sqlid
13list_find_func_id(list *ids, sqlid id)
14{
15 node *n = ids->h;
16 while (n) {
17 sql_func * f = n->data;
18 if (f->base.id == id)
19 return id;
20 else
21 n = n->next;
22 }
23 return 0;
24}
25
26/*Function to create a dependency*/
27void
28sql_trans_create_dependency(sql_trans* tr, sqlid id, sqlid depend_id, sql_dependency depend_type)
29{
30 sql_schema * s = find_sql_schema(tr, "sys");
31 sql_table *t = find_sql_table(s, "dependencies");
32 sql_column *c_id = find_sql_column(t, "id");
33 sql_column *c_dep_id = find_sql_column(t, "depend_id");
34 sql_column *c_dep_type = find_sql_column(t, "depend_type");
35 sht dtype = (sht) depend_type;
36
37 if (is_oid_nil(table_funcs.column_find_row(tr, c_id, &id, c_dep_id, &depend_id, c_dep_type, &dtype, NULL)))
38 table_funcs.table_insert(tr, t, &id, &depend_id, &dtype);
39}
40
41/*Function to drop the dependencies on depend_id*/
42void
43sql_trans_drop_dependencies(sql_trans* tr, sqlid depend_id)
44{
45 oid rid;
46 sql_schema * s = find_sql_schema(tr, "sys");
47 sql_table* deps = find_sql_table(s, "dependencies");
48 sql_column * dep_dep_id = find_sql_column(deps, "depend_id");
49 rids *rs;
50
51 rs = table_funcs.rids_select(tr, dep_dep_id, &depend_id, &depend_id, NULL);
52 for (rid = table_funcs.rids_next(rs); !is_oid_nil(rid); rid = table_funcs.rids_next(rs))
53 table_funcs.table_delete(tr, deps, rid);
54 table_funcs.rids_destroy(rs);
55}
56
57/*Function to drop the dependency between object and target, ie obj_id/depend_id*/
58void
59sql_trans_drop_dependency(sql_trans* tr, sqlid obj_id, sqlid depend_id, sql_dependency depend_type)
60{
61 oid rid;
62 sql_schema * s = find_sql_schema(tr, "sys");
63 sql_table* deps = find_sql_table(s, "dependencies");
64 sql_column *dep_obj_id = find_sql_column(deps, "id");
65 sql_column *dep_dep_id = find_sql_column(deps, "depend_id");
66 sql_column *dep_dep_type = find_sql_column(deps, "depend_type");
67 sht dtype = (sht) depend_type;
68 rids *rs;
69
70 rs = table_funcs.rids_select(tr, dep_obj_id, &obj_id, &obj_id, dep_dep_id, &depend_id, &depend_id, dep_dep_type, &dtype, &dtype, NULL);
71 for (rid = table_funcs.rids_next(rs); !is_oid_nil(rid); rid = table_funcs.rids_next(rs))
72 table_funcs.table_delete(tr, deps, rid);
73 table_funcs.rids_destroy(rs);
74}
75
76/*It returns a list with depend_id_1, depend_type_1, depend_id_2, depend_type_2, ....*/
77list*
78sql_trans_get_dependencies(sql_trans* tr, sqlid id, sql_dependency depend_type, list * ignore_ids)
79{
80 void *v;
81 sql_schema *s = find_sql_schema(tr, "sys");
82 sql_table *deps = find_sql_table(s, "dependencies");
83 sql_column *dep_id, *dep_dep_id, *dep_dep_type, *tri_id, *table_id;
84 list *dep_list = list_create((fdestroy) GDKfree);
85 oid rid;
86 rids *rs;
87
88 if (!dep_list)
89 return NULL;
90
91 dep_id = find_sql_column(deps, "id");
92 dep_dep_id = find_sql_column(deps, "depend_id");
93 dep_dep_type = find_sql_column(deps, "depend_type");
94
95 rs = table_funcs.rids_select(tr, dep_id, &id, &id, NULL);
96 for (rid = table_funcs.rids_next(rs); !is_oid_nil(rid); rid = table_funcs.rids_next(rs)){
97 v = table_funcs.column_find_value(tr, dep_dep_id, rid);
98 id = *(sqlid*)v;
99 if (!(ignore_ids && list_find_func_id(ignore_ids, id))) {
100 list_append(dep_list, v);
101 v = table_funcs.column_find_value(tr, dep_dep_type, rid);
102 list_append(dep_list, v);
103 } else {
104 _DELETE(v);
105 }
106 }
107 table_funcs.rids_destroy(rs);
108
109 if (depend_type == TABLE_DEPENDENCY) {
110 sql_table *triggers = find_sql_table(s, "triggers");
111 table_id = find_sql_column(triggers, "table_id");
112 tri_id = find_sql_column(triggers, "id");
113 depend_type = TRIGGER_DEPENDENCY;
114
115 rs = table_funcs.rids_select(tr, table_id, &id, &id, NULL);
116 for (rid = table_funcs.rids_next(rs); !is_oid_nil(rid); rid = table_funcs.rids_next(rs)) {
117 v = table_funcs.column_find_value(tr, tri_id, rid);
118 list_append(dep_list, v);
119 v = MNEW(sht);
120 if (v) {
121 *(sht *) v = (sht) depend_type;
122 } else {
123 list_destroy(dep_list);
124 return NULL;
125 }
126 list_append(dep_list, v);
127 }
128 table_funcs.rids_destroy(rs);
129 }
130 return dep_list;
131}
132
133/*It checks if there are dependency between two ID's */
134sqlid
135sql_trans_get_dependency_type(sql_trans *tr, sqlid id, sql_dependency depend_type)
136{
137 oid rid;
138 sql_schema *s;
139 sql_table *dep;
140 sql_column *dep_id, *dep_dep_id, *dep_dep_type;
141 sht dtype = (sht) depend_type;
142
143 s = find_sql_schema(tr, "sys");
144 dep = find_sql_table(s, "dependencies");
145 dep_id = find_sql_column(dep, "id");
146 dep_dep_id = find_sql_column(dep, "depend_id");
147 dep_dep_type = find_sql_column(dep, "depend_type");
148
149 rid = table_funcs.column_find_row(tr, dep_id, &id, dep_dep_type, &dtype, NULL);
150 if (!is_oid_nil(rid)) {
151 int r, *v = table_funcs.column_find_value(tr, dep_dep_id, rid);
152
153 r = *v;
154 _DELETE(v);
155 return r;
156 } else {
157 return -1;
158 }
159}
160
161/*It checks if there are dependency between two ID's */
162int
163sql_trans_check_dependency(sql_trans *tr, sqlid id, sqlid depend_id, sql_dependency depend_type)
164{
165 oid rid;
166 sql_schema *s;
167 sql_table *dep;
168 sql_column *dep_id, *dep_dep_id, *dep_dep_type;
169 sht dtype = (sht) depend_type;
170
171 s = find_sql_schema(tr, "sys");
172 dep = find_sql_table(s, "dependencies");
173 dep_id = find_sql_column(dep, "id");
174 dep_dep_id = find_sql_column(dep, "depend_id");
175 dep_dep_type = find_sql_column(dep, "depend_type");
176
177 rid = table_funcs.column_find_row(tr, dep_id, &id, dep_dep_id, &depend_id, dep_dep_type, &dtype, NULL);
178 if (!is_oid_nil(rid))
179 return 1;
180 else return 0;
181}
182
183/*Schema on users*/
184
185list *
186sql_trans_schema_user_dependencies(sql_trans *tr, sqlid schema_id)
187{
188 void *v;
189 sql_schema * s = find_sql_schema(tr, "sys");
190 sql_table *auths = find_sql_table(s, "auths");
191 sql_column *auth_id = find_sql_column(auths, "id");
192 sql_dependency type = USER_DEPENDENCY;
193 list *l = list_create((fdestroy) GDKfree);
194 rids *users;
195 oid rid;
196
197 if (!l)
198 return NULL;
199
200 users = backend_schema_user_dependencies(tr, schema_id);
201
202 for (rid = table_funcs.rids_next(users); !is_oid_nil(rid); rid = table_funcs.rids_next(users)) {
203 v = table_funcs.column_find_value(tr, auth_id, rid);
204 list_append(l,v);
205 v = MNEW(sht);
206 if (v) {
207 *(sht*)v = (sht) type;
208 } else {
209 list_destroy(l);
210 table_funcs.rids_destroy(users);
211 return NULL;
212 }
213 list_append(l,v);
214 }
215 table_funcs.rids_destroy(users);
216 return l;
217}
218
219/*owner on schemas*/
220list *
221sql_trans_owner_schema_dependencies(sql_trans *tr, sqlid owner_id)
222{
223 void *v;
224 sql_schema * s = find_sql_schema(tr, "sys");
225 sql_table *schemas = find_sql_table(s, "schemas");
226 sql_column *schema_owner = find_sql_column(schemas, "authorization");
227 sql_column *schema_id = find_sql_column(schemas, "id");
228 sql_dependency type = SCHEMA_DEPENDENCY;
229 list *l = list_create((fdestroy) GDKfree);
230 rids *rs;
231 oid rid;
232
233 if (!l)
234 return NULL;
235
236 rs = table_funcs.rids_select(tr, schema_owner, &owner_id, &owner_id, NULL);
237
238 for (rid = table_funcs.rids_next(rs); !is_oid_nil(rid); rid = table_funcs.rids_next(rs)) {
239 v = table_funcs.column_find_value(tr, schema_id, rid);
240 list_append(l, v);
241 v = MNEW(sht);
242 if (v) {
243 *(sht*)v = (sht) type;
244 } else {
245 list_destroy(l);
246 table_funcs.rids_destroy(rs);
247 return NULL;
248 }
249 list_append(l,v);
250 }
251 table_funcs.rids_destroy(rs);
252 return l;
253}
254
255/*Function on Functions*/
256