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 : #ifndef SQL_CATALOG_H
14 : #define SQL_CATALOG_H
15 :
16 : #include "sql_mem.h"
17 : #include "sql_list.h"
18 : #include "sql_hash.h"
19 : #include "mapi_querytype.h"
20 : #include "stream.h"
21 : #include "matomic.h"
22 :
23 : #define sql_shared_module_name "sql"
24 : #define sql_private_module_name "user"
25 :
26 : #define tr_none 1
27 : #define tr_readonly 2
28 : #define tr_writable 4
29 : #define tr_append 8
30 : #define tr_snapshot 16
31 : #define tr_serializable 32
32 :
33 : #define ACT_NO_ACTION 0
34 : #define ACT_CASCADE 1
35 : #define ACT_RESTRICT 2
36 : #define ACT_SET_NULL 3
37 : #define ACT_SET_DEFAULT 4
38 :
39 : #define DROP_RESTRICT 0
40 : #define DROP_CASCADE 1
41 : #define DROP_CASCADE_START 2
42 :
43 : #define PRIV_SELECT 1
44 : #define PRIV_UPDATE 2
45 : #define PRIV_INSERT 4
46 : #define PRIV_DELETE 8
47 : #define PRIV_EXECUTE 16
48 : #define PRIV_GRANT 32
49 : #define PRIV_TRUNCATE 64
50 : /* global privs */
51 : #define PRIV_COPYFROMFILE 1
52 : #define PRIV_COPYINTOFILE 2
53 :
54 : typedef enum sql_dependency {
55 : SCHEMA_DEPENDENCY = 1,
56 : TABLE_DEPENDENCY = 2,
57 : COLUMN_DEPENDENCY = 3,
58 : KEY_DEPENDENCY = 4,
59 : VIEW_DEPENDENCY = 5,
60 : USER_DEPENDENCY = 6,
61 : FUNC_DEPENDENCY = 7,
62 : TRIGGER_DEPENDENCY = 8,
63 : OWNER_DEPENDENCY = 9,
64 : INDEX_DEPENDENCY = 10,
65 : FKEY_DEPENDENCY = 11,
66 : SEQ_DEPENDENCY = 12,
67 : PROC_DEPENDENCY = 13,
68 : BEDROPPED_DEPENDENCY = 14, /*The object must be dropped when the dependent object is dropped independently of the DROP type.*/
69 : TYPE_DEPENDENCY = 15
70 : } sql_dependency;
71 :
72 : #define NO_DEPENDENCY 0
73 : #define HAS_DEPENDENCY 1
74 : #define CICLE_DEPENDENCY 2
75 : #define DEPENDENCY_CHECK_ERROR 3
76 : #define DEPENDENCY_CHECK_OK 0
77 :
78 : #define ROLE_PUBLIC 1
79 : #define ROLE_SYSADMIN 2
80 : #define USER_MONETDB 3
81 :
82 : #define SCALE_NONE 0
83 : #define SCALE_FIX 1 /* many numerical functions require equal
84 : scales/precision for all their inputs */
85 : #define SCALE_NOFIX 2
86 : #define SCALE_MUL 3 /* multiplication gives the sum of scales */
87 : #define SCALE_DIV 4 /* div on the other hand reduces the scales */
88 : #define DIGITS_ADD 5 /* some types grow under functions (concat) */
89 : #define INOUT 6 /* output type equals input type */
90 : #define SCALE_EQ 7 /* user defined functions need equal scales */
91 :
92 : #define RDONLY 0
93 : #define RD_INS 1
94 : #define RD_UPD_ID 2
95 : #define RD_UPD_VAL 3
96 : #define QUICK 4
97 : #define RD_EXT 5
98 :
99 : /* the following list of macros are used by rel_rankop function */
100 : #define UNBOUNDED_PRECEDING_BOUND 0
101 : #define UNBOUNDED_FOLLOWING_BOUND 1
102 : #define CURRENT_ROW_BOUND 2
103 :
104 : #define FRAME_ROWS 0 /* number of rows (preceding/following) */
105 : #define FRAME_RANGE 1 /* logical range (based on the ordering column).
106 : Example:
107 : RANGE BETWEEN INTERVAL '1' MONTH PRECEDING
108 : AND INTERVAL '1' MONTH FOLLOWING */
109 : #define FRAME_GROUPS 2
110 : #define FRAME_UNBOUNDED_TILL_CURRENT_ROW 3
111 : #define FRAME_CURRENT_ROW_TILL_UNBOUNDED 4
112 : #define FRAME_ALL 5
113 : #define FRAME_CURRENT_ROW 6
114 :
115 : /* the following list of macros are used by SQLwindow_bound function */
116 : #define BOUND_FIRST_HALF_PRECEDING 0
117 : #define BOUND_FIRST_HALF_FOLLOWING 1
118 : #define BOUND_SECOND_HALF_PRECEDING 2
119 : #define BOUND_SECOND_HALF_FOLLOWING 3
120 : #define CURRENT_ROW_PRECEDING 4
121 : #define CURRENT_ROW_FOLLOWING 5
122 :
123 : #define EXCLUDE_NONE 0 /* nothing excluded (also the default) */
124 : #define EXCLUDE_CURRENT_ROW 1 /* exclude the current row */
125 : #define EXCLUDE_GROUP 2 /* exclude group */
126 : #define EXCLUDE_TIES 3 /* exclude group but not the current row */
127 :
128 : /* The following macros are used in properties field of sql_table */
129 : #define PARTITION_RANGE 1
130 : #define PARTITION_LIST 2
131 : #define PARTITION_COLUMN 4
132 : #define PARTITION_EXPRESSION 8
133 :
134 : #define STORAGE_MAX_VALUE_LENGTH 2048
135 :
136 : #define cur_user 1
137 : #define cur_role 2
138 :
139 : #define sql_max(i1,i2) ((i1)<(i2))?(i2):(i1)
140 :
141 : #define dt_schema "%dt%"
142 : #define isDeclaredSchema(s) (strcmp(s->base.name, dt_schema) == 0)
143 :
144 : extern const char *TID;
145 :
146 : typedef enum temp_t {
147 : SQL_PERSIST = 0,
148 : SQL_LOCAL_TEMP = 1,
149 : SQL_GLOBAL_TEMP = 2,
150 : SQL_DECLARED_TABLE = 3, /* variable inside a stored procedure */
151 : SQL_MERGE_TABLE = 4,
152 : /* SQL_STREAM = 5, stream tables are not used anymore */
153 : SQL_REMOTE = 6,
154 : SQL_REPLICA_TABLE = 7,
155 : SQL_UNLOGGED_TABLE = 8
156 : } temp_t;
157 :
158 : typedef enum comp_type {
159 : cmp_gt = 0,
160 : cmp_gte = 1,
161 : cmp_lte = 2,
162 : cmp_lt = 3,
163 : cmp_equal = 4,
164 : cmp_notequal = 5,
165 :
166 : cmp_filter = 6,
167 : cmp_or = 7,
168 : cmp_in = 8, /* in value list */
169 : cmp_notin = 9, /* not in value list */
170 :
171 : /* The followin cmp_* are only used within stmt (not sql_exp) */
172 : cmp_all = 12, /* special case for crossproducts */
173 : cmp_project = 13, /* special case for projection joins */
174 : cmp_joined = 14, /* special case already joined */
175 : cmp_left_project = 15 /* last step of outer join */
176 : } comp_type;
177 :
178 : #define is_theta_exp(e) ((e) == cmp_gt || (e) == cmp_gte || (e) == cmp_lte ||\
179 : (e) == cmp_lt || (e) == cmp_equal || (e) == cmp_notequal)
180 :
181 : #define is_complex_exp(et) ((et) == cmp_or || (et) == cmp_in || (et) == cmp_notin || (et) == cmp_filter)
182 :
183 : #define is_equality_or_inequality_exp(et) ((et) == cmp_equal || (et) == cmp_notequal || (et) == cmp_in || (et) == cmp_notin)
184 :
185 : typedef enum commit_action_t {
186 : CA_COMMIT, /* commit rows, only for persistent tables */
187 : CA_DELETE, /* delete rows */
188 : CA_PRESERVE, /* preserve rows */
189 : CA_DROP /* drop table */
190 : } ca_t;
191 :
192 : typedef int sqlid;
193 : typedef void *sql_store;
194 :
195 : typedef struct sql_base {
196 : unsigned int
197 : new:1,
198 : deleted:1;
199 : ATOMIC_TYPE refcnt;
200 : sqlid id;
201 : char *name;
202 : } sql_base;
203 :
204 : #define isNew(x) ((x)->base.new)
205 : #define isDeleted(x) ((x)->base.deleted)
206 :
207 : extern void base_init(sql_allocator *sa, sql_base * b, sqlid id, bool isnew, const char *name);
208 :
209 : typedef struct changeset {
210 : sql_allocator *sa;
211 : fdestroy destroy;
212 : fkeyvalue fkeyvalue;
213 : struct list *set;
214 : struct list *dset;
215 : node *nelm;
216 : } changeset;
217 :
218 : typedef struct objlist {
219 : list *l;
220 : sql_hash *h;
221 : sql_store store;
222 : } objlist;
223 :
224 : struct sql_trans;
225 : struct sql_change;
226 : struct objectset;
227 : struct versionhead;
228 : struct os_iter {
229 : struct objectset *os;
230 : struct sql_trans *tr;
231 : struct versionhead *n;
232 : struct sql_hash_e *e;
233 : const char *name;
234 : };
235 :
236 : /* transaction changes */
237 : typedef int (*tc_valid_fptr) (struct sql_trans *tr, struct sql_change *c/*, ulng commit_ts, ulng oldest*/);
238 : typedef int (*tc_log_fptr) (struct sql_trans *tr, struct sql_change *c); /* write changes to the log */
239 : typedef int (*tc_commit_fptr) (struct sql_trans *tr, struct sql_change *c, ulng commit_ts, ulng oldest);/* commit/rollback changes */
240 : typedef int (*tc_cleanup_fptr) (sql_store store, struct sql_change *c, ulng oldest); /* garbage collection, ie cleanup structures when possible */
241 : typedef void (*destroy_fptr)(sql_store store, sql_base *b);
242 : typedef int (*validate_fptr)(struct sql_trans *tr, sql_base *b, int delete);
243 :
244 : extern struct objectset *os_new(sql_allocator *sa, destroy_fptr destroy, bool temporary, bool unique, bool concurrent, bool nested, sql_store store);
245 : extern struct objectset *os_dup(struct objectset *os);
246 : extern void os_destroy(struct objectset *os, sql_store store);
247 : extern int /*ok, error (name existed) and conflict (added before) */ os_add(struct objectset *os, struct sql_trans *tr, const char *name, sql_base *b);
248 : extern int os_del(struct objectset *os, struct sql_trans *tr, const char *name, sql_base *b);
249 : extern int os_size(struct objectset *os, struct sql_trans *tr);
250 : extern int os_empty(struct objectset *os, struct sql_trans *tr);
251 : extern int os_remove(struct objectset *os, struct sql_trans *tr, const char *name);
252 : extern sql_base *os_find_name(struct objectset *os, struct sql_trans *tr, const char *name);
253 : extern sql_base *os_find_id(struct objectset *os, struct sql_trans *tr, sqlid id);
254 : /* iterating (for example for location functinos) */
255 : extern void os_iterator(struct os_iter *oi, struct objectset *os, struct sql_trans *tr, const char *name /*optional*/);
256 : extern sql_base *oi_next(struct os_iter *oi);
257 : extern bool os_obj_intransaction(struct objectset *os, struct sql_trans *tr, sql_base *b);
258 : extern bool os_has_changes(struct objectset *os, struct sql_trans *tr);
259 :
260 : extern objlist *ol_new(sql_allocator *sa, destroy_fptr destroy, sql_store store);
261 : extern void ol_destroy(objlist *ol, sql_store store);
262 : extern int ol_add(objlist *ol, sql_base *data);
263 : extern void ol_del(objlist *ol, sql_store store, node *data);
264 : extern node *ol_find_name(objlist *ol, const char *name);
265 : extern node *ol_find_id(objlist *ol, sqlid id);
266 : extern node *ol_rehash(objlist *ol, const char *oldname, node *n);
267 : #define ol_length(ol) (list_length(ol->l))
268 : #define ol_first_node(ol) (ol->l->h)
269 : #define ol_last_node(ol) (ol->l->t)
270 : #define ol_fetch(ol,nr) (list_fetch(ol->l, nr))
271 :
272 : extern void cs_new(changeset * cs, sql_allocator *sa, fdestroy destroy, fkeyvalue hfunc);
273 : extern void cs_destroy(changeset * cs, void *data);
274 : extern changeset *cs_add(changeset * cs, void *elm, bool isnew);
275 : extern changeset *cs_del(changeset * cs, void *gdata, node *n, bool force);
276 : extern int cs_size(changeset * cs);
277 : extern node *cs_find_id(changeset * cs, sqlid id);
278 :
279 : typedef void *backend_code;
280 : typedef size_t backend_stack;
281 :
282 : typedef struct sql_schema {
283 : sql_base base;
284 : sqlid auth_id;
285 : sqlid owner;
286 : bit system; /* system or user schema */
287 : // TODO? int type; /* persistent, session local, transaction local */
288 :
289 : struct objectset *tables;
290 : struct objectset *types;
291 : struct objectset *funcs;
292 : struct objectset *seqs;
293 : struct objectset *keys; /* Names for keys, idxs, and triggers and parts are */
294 : struct objectset *idxs; /* global, but these objects are only */
295 : struct objectset *triggers; /* useful within a table */
296 : struct objectset *parts;
297 :
298 : char *internal; /* optional internal module name */
299 : sql_store store;
300 : } sql_schema;
301 :
302 : typedef struct sql_catalog {
303 : struct objectset *schemas;
304 : struct objectset *objects;
305 : } sql_catalog;
306 :
307 : typedef struct sql_trans {
308 : char *name;
309 :
310 : ulng ts; /* transaction start timestamp */
311 : ulng tid; /* transaction id */
312 :
313 : sql_store store; /* keep link into the global store */
314 : MT_Lock lock; /* lock protecting concurrent writes to the changes list */
315 : list *changes; /* list of changes */
316 :
317 : list *dropped; /* protection against recursive cascade action*/
318 : list *predicates; /* list of read predicates logged during update transactions */
319 : list *dependencies; /* list of dependencies created (list of sqlids from the objects) */
320 : list *depchanges; /* list of dependencies changed (it would be tested for conflicts at the end of the transaction) */
321 :
322 : lng logchanges; /* count number of changes to be applied to the wal */
323 : int active; /* is active transaction */
324 : int status; /* status of the last query */
325 :
326 : sql_catalog *cat;
327 : sql_schema *tmp; /* each session has its own tmp schema */
328 : struct objectset* localtmps;
329 :
330 : struct sql_trans *parent; /* multilevel transaction support */
331 : } sql_trans;
332 :
333 : typedef enum sql_class {
334 : EC_ANY,
335 : EC_TABLE,
336 : EC_BIT,
337 : EC_CHAR,
338 : EC_STRING,
339 : EC_BLOB,
340 : EC_POS,
341 : EC_NUM,
342 : EC_MONTH,
343 : EC_SEC,
344 : EC_DEC,
345 : EC_FLT,
346 : EC_TIME,
347 : EC_TIME_TZ,
348 : EC_DATE,
349 : EC_TIMESTAMP,
350 : EC_TIMESTAMP_TZ,
351 : EC_GEOM,
352 : EC_EXTERNAL,
353 : EC_MAX /* evaluated to the max value, should be always kept at the bottom */
354 : } sql_class;
355 :
356 : #define has_tz(e) (EC_TEMP_TZ(e))
357 : #define type_has_tz(t) has_tz((t)->type->eclass)
358 : #define EC_VARCHAR(e) ((e)==EC_CHAR||(e)==EC_STRING)
359 : #define EC_INTERVAL(e) ((e)==EC_MONTH||(e)==EC_SEC)
360 : #define EC_NUMBER(e) ((e)==EC_POS||(e)==EC_NUM||EC_INTERVAL(e)||(e)==EC_DEC||(e)==EC_FLT)
361 : #define EC_EXACTNUM(e) ((e)==EC_NUM||(e)==EC_DEC)
362 : #define EC_APPNUM(e) ((e)==EC_FLT)
363 : #define EC_COMPUTE(e) ((e)==EC_NUM||(e)==EC_FLT)
364 : #define EC_BOOLEAN(e) ((e)==EC_BIT||(e)==EC_NUM||(e)==EC_FLT)
365 : #define EC_TEMP_TZ(e) ((e)==EC_TIME_TZ||(e)==EC_TIMESTAMP_TZ)
366 : #define EC_TEMP(e) ((e)==EC_TIME||(e)==EC_DATE||(e)==EC_TIMESTAMP||EC_TEMP_TZ(e))
367 : #define EC_TEMP_FRAC(e) ((e)==EC_TIME||(e)==EC_TIMESTAMP||EC_TEMP_TZ(e))
368 : #define EC_TEMP_NOFRAC(e) ((e)==EC_TIME||(e)==EC_TIMESTAMP)
369 : #define EC_SCALE(e) ((e)==EC_DEC||EC_TEMP_FRAC(e)||(e)==EC_SEC)
370 : #define EC_BACKEND_FIXED(e) (EC_NUMBER(e)||(e)==EC_BIT||EC_TEMP(e))
371 :
372 : typedef struct sql_type {
373 : sql_base base;
374 :
375 : char *impl; /* backend correspondent type */
376 : unsigned int digits;
377 : unsigned int scale; /* indicates how scale is used in functions */
378 : int localtype; /* localtype, need for coersions */
379 : unsigned char radix;
380 : unsigned int bits;
381 : sql_class eclass; /* types are grouped into equivalence classes */
382 : sql_schema *s;
383 : } sql_type;
384 :
385 : typedef struct sql_alias {
386 : char *name;
387 : char *alias;
388 : } sql_alias;
389 :
390 : #define ARG_IN 1
391 : #define ARG_OUT 0
392 :
393 : typedef struct sql_subtype {
394 : sql_type *type;
395 : unsigned int digits;
396 : unsigned int scale;
397 : } sql_subtype;
398 :
399 : /* sql_func need type transform rules types are equal if underlying
400 : * types are equal + scale is equal if types do not mach we try type
401 : * conversions which means for simple 1 arg functions
402 : */
403 :
404 : typedef struct sql_arg {
405 : char *name;
406 : bte inout;
407 : sql_subtype type;
408 : } sql_arg;
409 :
410 : typedef enum sql_ftype {
411 : F_FUNC = 1,
412 : F_PROC = 2,
413 : F_AGGR = 3,
414 : F_FILT = 4,
415 : F_UNION = 5,
416 : F_ANALYTIC = 6,
417 : F_LOADER = 7
418 : } sql_ftype;
419 :
420 : #define IS_FUNC(f) ((f)->type == F_FUNC)
421 : #define IS_PROC(f) ((f)->type == F_PROC)
422 : #define IS_AGGR(f) ((f)->type == F_AGGR)
423 : #define IS_FILT(f) ((f)->type == F_FILT)
424 : #define IS_UNION(f) ((f)->type == F_UNION)
425 : #define IS_ANALYTIC(f) ((f)->type == F_ANALYTIC)
426 : #define IS_LOADER(f) ((f)->type == F_LOADER)
427 :
428 : #define FUNC_TYPE_STR(type, F, fn) \
429 : switch (type) { \
430 : case F_FUNC: \
431 : F = "FUNCTION"; \
432 : fn = "function"; \
433 : break; \
434 : case F_PROC: \
435 : F = "PROCEDURE"; \
436 : fn = "procedure"; \
437 : break; \
438 : case F_AGGR: \
439 : F = "AGGREGATE"; \
440 : fn = "aggregate"; \
441 : break; \
442 : case F_FILT: \
443 : F = "FILTER FUNCTION"; \
444 : fn = "filter function"; \
445 : break; \
446 : case F_UNION: \
447 : F = "UNION FUNCTION"; \
448 : fn = "table returning function"; \
449 : break; \
450 : case F_ANALYTIC: \
451 : F = "WINDOW FUNCTION"; \
452 : fn = "window function"; \
453 : break; \
454 : case F_LOADER: \
455 : F = "LOADER FUNCTION"; \
456 : fn = "loader function"; \
457 : break; \
458 : default: \
459 : assert(0); \
460 : }
461 :
462 : typedef enum sql_flang {
463 : FUNC_LANG_INT = 0, /* internal */
464 : FUNC_LANG_MAL = 1, /* create sql external mod.func */
465 : FUNC_LANG_SQL = 2, /* create ... sql function/procedure */
466 : FUNC_LANG_R = 3, /* create .. language R */
467 : FUNC_LANG_C = 4, /* create .. language C */
468 : FUNC_LANG_J = 5, /* create .. language JAVASCRIPT (not implemented) */
469 : /* this should probably be done in a better way */
470 : FUNC_LANG_PY = 6, /* create .. language PYTHON */
471 : /* values 8 and 9 were for Python 2 */
472 : FUNC_LANG_PY3 = 10, /* create .. language PYTHON3 */
473 : /* values 7 and 11 where old map python code */
474 : FUNC_LANG_CPP = 12 /* create .. language CPP */
475 : } sql_flang;
476 :
477 : #define LANG_EXT(l) ((l)>FUNC_LANG_SQL)
478 : #define UDF_LANG(l) ((l)!=FUNC_LANG_INT)
479 :
480 : typedef struct sql_func {
481 : sql_base base;
482 :
483 : char *mod;
484 : char *imp;
485 : /*
486 : Backend implementation function after it gets instantiated.
487 : During instantiation 'imp' will be set, but look for the 'instantiated' value to check if it's done or not.
488 : Note that functions other than SQL and MAL, don't require instantiation and 'imp' is always set.
489 : */
490 : sql_ftype type;
491 : list *ops; /* param list */
492 : list *res; /* list of results */
493 : sql_flang lang;
494 : char *query; /* sql code */
495 : bool
496 : semantics:1, /* When set to true, function incorporates some kind of null semantics */
497 : side_effect:1, /* if the function has side-effects */
498 : varres:1, /* variable output result */
499 : vararg:1, /* variable input arguments */
500 : system:1, /* system function */
501 : instantiated:1, /* if the function is instantiated */
502 : private:1; /* certain functions cannot be bound from user queries */
503 : int fix_scale;
504 : /*
505 : SCALE_NOFIX/SCALE_NONE => nothing
506 : SCALE_FIX => input scale fixing,
507 : SCALE_ADD => leave inputs as is and do add scales
508 : example numerical multiplication
509 : SCALE_SUB => first input scale, fix with second scale
510 : result scale is equal to first input
511 : example numerical division
512 : DIGITS_ADD => result digits, sum of args
513 : example string concat
514 : */
515 : sql_schema *s;
516 : sql_allocator *sa;
517 : } sql_func;
518 :
519 : typedef struct sql_subfunc {
520 : sql_func *func;
521 : list *res;
522 : list *coltypes; /* we need this for copy into from loader */
523 : list *colnames; /* we need this for copy into from loader */
524 : char *sname, *tname; /* we need this for create table from loader */
525 : } sql_subfunc;
526 :
527 : typedef enum key_type {
528 : pkey,
529 : ukey,
530 : fkey
531 : } key_type;
532 :
533 : typedef struct sql_kc {
534 : struct sql_column *c;
535 : int trunc; /* 0 not truncated, >0 colum is truncated */
536 : } sql_kc;
537 :
538 : typedef enum idx_type {
539 : hash_idx,
540 : join_idx,
541 : oph_idx, /* order preserving hash */
542 : no_idx, /* no idx, ie no storage */
543 : imprints_idx,
544 : ordered_idx,
545 : new_idx_types
546 : } idx_type;
547 :
548 : #define hash_index(t) ((t) == hash_idx || (t) == oph_idx)
549 : #define idx_has_column(t) (hash_index(t) || (t) == join_idx)
550 : #define oid_index(t) ((t) == join_idx)
551 : #define non_updatable_index(t) ((t) == ordered_idx || (t) == no_idx || !idx_has_column(t))
552 :
553 : typedef struct sql_idx {
554 : sql_base base;
555 : idx_type type; /* unique */
556 : struct list *columns; /* list of sql_kc */
557 : struct sql_table *t;
558 : struct sql_key *key; /* key */
559 : ATOMIC_PTR_TYPE data;
560 : } sql_idx;
561 :
562 : /* fkey consists of two of these */
563 : typedef struct sql_key { /* pkey, ukey, fkey */
564 : sql_base base;
565 : key_type type; /* pkey, ukey, fkey */
566 : sql_idx *idx; /* idx to accelerate key check */
567 :
568 : struct list *columns; /* list of sql_kc */
569 : struct sql_table *t;
570 : int drop_action; /* only needed for alter drop key */
571 : } sql_key;
572 :
573 : typedef struct sql_ukey { /* pkey, ukey */
574 : sql_key k;
575 : //list *keys;
576 : } sql_ukey;
577 :
578 : typedef struct sql_fkey { /* fkey */
579 : sql_key k;
580 : /* 0=no action, 1=cascade, 2=restrict (default setting), 3=set null, 4=set default */
581 : int on_delete;
582 : int on_update;
583 : sqlid rkey;
584 : } sql_fkey;
585 :
586 : typedef struct sql_trigger {
587 : sql_base base;
588 : sht time; /* before or after */
589 : sht orientation; /* row or statement */
590 : sht event; /* insert, delete, update, truncate */
591 : /* int action_order; TODO, order within the set of triggers */
592 : struct list *columns; /* update trigger on list of (sql_kc) columns */
593 :
594 : struct sql_table *t;
595 : char *old_name; /* name referencing the old values */
596 : char *new_name; /* name referencing the new values */
597 :
598 : char *condition; /* when search condition, ie query */
599 : char *statement; /* action, ie list of sql statements */
600 : } sql_trigger;
601 :
602 : typedef struct sql_sequence {
603 : sql_base base;
604 : lng start;
605 : lng minvalue;
606 : lng maxvalue;
607 : lng increment;
608 : lng cacheinc;
609 : bit cycle;
610 : bit bedropped; /*Drop the SEQUENCE if you are dropping the column, e.g., SERIAL COLUMN".*/
611 : sql_schema *s;
612 : } sql_sequence;
613 :
614 : typedef struct sql_column {
615 : sql_base base;
616 : sql_subtype type;
617 : int colnr;
618 : bit null;
619 : char *def;
620 : char unique; /* 0 NOT UNIQUE, 1 SUB_UNIQUE, 2 UNIQUE */
621 : int drop_action; /* only used for alter statements */
622 : char *storage_type;
623 : size_t dcount;
624 : void *min;
625 : void *max;
626 :
627 : struct sql_table *t;
628 : ATOMIC_PTR_TYPE data;
629 : } sql_column;
630 :
631 : typedef enum table_types {
632 : tt_table = 0, /* table */
633 : tt_view = 1, /* view */
634 : tt_merge_table = 3, /* multiple tables form one table */
635 : /* tt_stream = 4, stream tables are not used anymore */
636 : tt_remote = 5, /* stored on a remote server */
637 : tt_replica_table = 6, /* multiple replica of the same table */
638 : tt_unlogged_table = 7
639 : } table_types;
640 :
641 : #define TABLE_TYPE_DESCRIPTION(tt, properties) \
642 : ((tt) == tt_table) ? "TABLE" : ((tt) == tt_view) ? "VIEW" \
643 : : ((tt) == tt_merge_table && !(properties)) ? "MERGE TABLE" \
644 : : ((tt) == tt_remote) ? "REMOTE TABLE" \
645 : : ((tt) == tt_merge_table && ((properties)&PARTITION_LIST) == PARTITION_LIST) ? "LIST PARTITION TABLE" \
646 : : ((tt) == tt_merge_table && ((properties)&PARTITION_RANGE) == PARTITION_RANGE) ? "RANGE PARTITION TABLE" \
647 : : ((tt) == tt_unlogged_table) ? "UNLOGGED TABLE" \
648 : : "REPLICA TABLE"
649 :
650 : #define isTable(x) ((x)->type==tt_table || (x)->type==tt_unlogged_table)
651 : #define isView(x) ((x)->type==tt_view)
652 : #define isNonPartitionedTable(x) ((x)->type==tt_merge_table && !(x)->properties)
653 : #define isRangePartitionTable(x) ((x)->type==tt_merge_table && ((x)->properties & PARTITION_RANGE) == PARTITION_RANGE)
654 : #define isListPartitionTable(x) ((x)->type==tt_merge_table && ((x)->properties & PARTITION_LIST) == PARTITION_LIST)
655 : #define isPartitionedByColumnTable(x) ((x)->type==tt_merge_table && ((x)->properties & PARTITION_COLUMN) == PARTITION_COLUMN)
656 : #define isPartitionedByExpressionTable(x) ((x)->type==tt_merge_table && ((x)->properties & PARTITION_EXPRESSION) == PARTITION_EXPRESSION)
657 : #define isMergeTable(x) ((x)->type==tt_merge_table)
658 : #define isRemote(x) ((x)->type==tt_remote)
659 : #define isReplicaTable(x) ((x)->type==tt_replica_table)
660 : #define isUnloggedTable(x) ((x)->type==tt_unlogged_table)
661 : #define isKindOfTable(x) (isTable(x) || isMergeTable(x) || isRemote(x) || isReplicaTable(x) || isUnloggedTable(x))
662 :
663 : #define TABLE_WRITABLE 0
664 : #define TABLE_READONLY 1
665 : #define TABLE_APPENDONLY 2
666 :
667 : typedef struct sql_part_value {
668 : ptr value;
669 : size_t length;
670 : } sql_part_value;
671 :
672 : typedef struct sql_part {
673 : sql_base base;
674 : struct sql_table *t; /* the merge table */
675 : sqlid member; /* the member of the merge table */
676 : bit with_nills; /* 0 no nills, 1 holds nills, NULL holds all values -> range FROM MINVALUE TO MAXVALUE WITH NULL */
677 : union {
678 : list *values; /* partition by values/list */
679 : struct sql_range { /* partition by range */
680 : ptr minvalue;
681 : ptr maxvalue;
682 : size_t minlength;
683 : size_t maxlength;
684 : } range;
685 : } part;
686 : } sql_part;
687 :
688 : typedef struct sql_expression {
689 : sql_subtype type; /* the returning sql_subtype of the expression */
690 : char *exp; /* the expression itself */
691 : list *cols; /* list of colnr of the columns of the table used in the expression */
692 : } sql_expression;
693 :
694 : typedef struct sql_table {
695 : sql_base base;
696 : sht type; /* table, view, etc */
697 : sht access; /* writable, readonly, appendonly */
698 : bit system; /* system or user table */
699 : bit bootstrap; /* system table created during bootstrap */
700 : bte properties; /* used for merge_tables */
701 : temp_t persistence; /* persistent, global or local temporary */
702 : ca_t commit_action; /* on commit action */
703 : char *query; /* views may require some query */
704 : int sz;
705 :
706 : sql_ukey *pkey;
707 : objlist *columns;
708 : objlist *idxs;
709 : objlist *keys;
710 : objlist *triggers;
711 : list *members; /* member tables of merge/replica tables */
712 : int drop_action; /* only needed for alter drop table */
713 :
714 : ATOMIC_PTR_TYPE data;
715 : struct sql_schema *s;
716 :
717 : union {
718 : struct sql_column *pcol; /* If it is partitioned on a column */
719 : struct sql_expression *pexp; /* If it is partitioned by an expression */
720 : } part;
721 : } sql_table;
722 :
723 : typedef struct res_col {
724 : char *tn;
725 : char *name;
726 : sql_subtype type;
727 : bat b;
728 : char mtype;
729 : bool cached;
730 : ptr *p;
731 : } res_col;
732 :
733 : typedef struct res_table {
734 : int id;
735 : oid query_id;
736 : mapi_query_t query_type;
737 : int nr_cols;
738 : BUN nr_rows;
739 : BUN cur_row;
740 : int cur_col;
741 : const char *tsep;
742 : const char *rsep;
743 : const char *ssep;
744 : const char *ns;
745 : res_col *cols;
746 : struct res_table *next;
747 : } res_table;
748 :
749 : typedef struct sql_session {
750 : sql_allocator *sa;
751 : sql_trans *tr; /* active transaction */
752 :
753 : char *schema_name; /* transaction's schema name */
754 : sql_schema *schema;
755 :
756 : char ac_on_commit; /* if 1, auto_commit should be enabled on
757 : commit, rollback, etc. */
758 : char auto_commit;
759 : int level; /* TRANSACTION isolation level */
760 : int status; /* status, ok/error */
761 : backend_stack stk;
762 : } sql_session;
763 :
764 : #define sql_base_loop(l, n) for (n=l->h; n; n=n->next)
765 :
766 : extern int base_key(sql_base *b);
767 : extern node *list_find_name(list *l, const char *name);
768 : extern node *list_find_id(list *l, sqlid id);
769 : extern node *list_find_base_id(list *l, sqlid id);
770 :
771 : extern sql_key *find_sql_key(sql_table *t, const char *kname);
772 : extern sql_key *sql_trans_find_key(sql_trans *tr, sqlid id);
773 : extern sql_key *schema_find_key(sql_trans *tr, sql_schema *s, const char *name);
774 :
775 : extern sql_idx *find_sql_idx(sql_table *t, const char *kname);
776 : extern sql_idx *sql_trans_find_idx(sql_trans *tr, sqlid id);
777 : extern sql_idx *schema_find_idx(sql_trans *tr, sql_schema *s, const char *name);
778 : extern sql_idx *schema_find_idx_id(sql_trans *tr, sql_schema *s, sqlid id);
779 :
780 : extern sql_column *find_sql_column(sql_table *t, const char *cname);
781 :
782 : extern sql_table *find_sys_table(sql_trans *tr, const char *tname);
783 : extern sql_table *find_sql_table(sql_trans *tr, sql_schema *s, const char *tname);
784 : extern sql_table *find_sql_table_id(sql_trans *tr, sql_schema *s, sqlid id);
785 : extern sql_table *sql_trans_find_table(sql_trans *tr, sqlid id);
786 :
787 : extern sql_sequence *find_sql_sequence(sql_trans *tr, sql_schema *s, const char *sname);
788 :
789 : extern sql_schema *find_sql_schema(sql_trans *t, const char *sname);
790 : extern sql_schema *find_sql_schema_id(sql_trans *t, sqlid id);
791 :
792 : extern sql_type *find_sql_type(sql_trans *tr, sql_schema * s, const char *tname);
793 : extern sql_type *sql_trans_bind_type(sql_trans *tr, sql_schema *s, const char *name);
794 : extern sql_type *sql_trans_find_type(sql_trans *tr, sql_schema *s /*optional */, sqlid id);
795 : extern sql_func *sql_trans_find_func(sql_trans *tr, sqlid id);
796 : extern sql_trigger *sql_trans_find_trigger(sql_trans *tr, sqlid id);
797 : extern sql_trigger *schema_find_trigger(sql_trans *tr, sql_schema *s, const char *name);
798 :
799 : extern void find_partition_type(sql_subtype *tpe, sql_table *mt);
800 : extern void *sql_values_list_element_validate_and_insert(void *v1, void *v2, void *tpe, int* res);
801 : extern void *sql_range_part_validate_and_insert(void *v1, void *v2, void *tpe);
802 : extern void *sql_values_part_validate_and_insert(void *v1, void *v2, void *tpe);
803 :
804 : typedef struct {
805 : BAT *b;
806 : char* name;
807 : void* def;
808 : } sql_emit_col;
809 :
810 : extern int nested_mergetable(sql_trans *tr, sql_table *t, const char *sname, const char *tname);
811 : extern bool is_column_unique(sql_column *c);
812 : sql_export sql_part *partition_find_part(sql_trans *tr, sql_table *pt, sql_part *pp);
813 : extern node *members_find_child_id(list *l, sqlid id);
814 :
815 : #define outside_str 1
816 : #define inside_str 2
817 :
818 : #define extracting_schema 1
819 : #define extracting_sequence 2
820 :
821 : static inline void
822 165 : extract_schema_and_sequence_name(sql_allocator *sa, char *default_value, char **schema, char **sequence)
823 : {
824 165 : int status = outside_str, identifier = extracting_schema;
825 165 : char next_identifier[1024]; /* needs one extra character for null terminator */
826 165 : size_t bp = 0;
827 :
828 2625 : for (size_t i = 0; default_value[i]; i++) {
829 2625 : char next = default_value[i];
830 :
831 2625 : if (next == '"') {
832 496 : if (status == inside_str && default_value[i + 1] == '"') {
833 1 : next_identifier[bp++] = '"';
834 1 : i++; /* has to advance two positions */
835 330 : } else if (status == inside_str) {
836 330 : next_identifier[bp++] = '\0';
837 330 : if (identifier == extracting_schema) {
838 165 : *schema = SA_STRDUP(sa, next_identifier);
839 165 : identifier = extracting_sequence;
840 165 : } else if (identifier == extracting_sequence) {
841 165 : *sequence = SA_STRDUP(sa, next_identifier);
842 165 : break; /* done extracting */
843 : }
844 : bp = 0;
845 : status = outside_str;
846 : } else {
847 : assert(status == outside_str);
848 : status = inside_str;
849 : }
850 2129 : } else if (next == '.') {
851 165 : if (status == outside_str && default_value[i + 1] == '"') {
852 : status = inside_str;
853 : i++; /* has to advance two positions */
854 : } else {
855 0 : assert(status == inside_str);
856 0 : next_identifier[bp++] = '.'; /* used inside an identifier name */
857 : }
858 1964 : } else if (status == inside_str) {
859 1964 : next_identifier[bp++] = next;
860 : } else {
861 : assert(status == outside_str);
862 : }
863 : }
864 165 : }
865 :
866 : extern void arg_destroy(sql_store store, sql_arg *a);
867 : extern void part_value_destroy(sql_store store, sql_part_value *pv);
868 :
869 : typedef struct atom {
870 : int isnull;
871 : sql_subtype tpe;
872 : ValRecord data;
873 : } atom;
874 :
875 : /* duplicate atom */
876 : extern ValPtr SA_VALcopy(sql_allocator *sa, ValPtr d, const ValRecord *s);
877 : extern atom *atom_copy(sql_allocator *sa, atom *a);
878 :
879 : typedef struct pl {
880 : sql_column *c;
881 : unsigned int cmp;
882 : atom *r; /* if r is NULL then a full match is required */
883 : atom *f; /* make it match range expressions */
884 : uint8_t
885 : anti:1,
886 : semantics:1;
887 : } pl;
888 :
889 : #endif /* SQL_CATALOG_H */
|