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 MAX_BITS 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 (of first input) */
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 following 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 :
194 : typedef struct sql_ref {
195 : int refcnt;
196 : } sql_ref;
197 :
198 : extern sql_ref *sql_ref_init(sql_ref *r);
199 : extern int sql_ref_inc(sql_ref *r);
200 : extern int sql_ref_dec(sql_ref *r);
201 :
202 : typedef void *sql_store;
203 :
204 : typedef struct sql_base {
205 : unsigned int
206 : new:1,
207 : deleted:1;
208 : ATOMIC_TYPE refcnt;
209 : sqlid id;
210 : char *name;
211 : } sql_base;
212 :
213 : #define isNew(x) ((x)->base.new)
214 : #define isDeleted(x) ((x)->base.deleted)
215 :
216 : extern void base_init(allocator *sa, sql_base * b, sqlid id, bool isnew, const char *name);
217 :
218 : typedef struct changeset {
219 : allocator *sa;
220 : fdestroy destroy;
221 : fkeyvalue fkeyvalue;
222 : struct list *set;
223 : struct list *dset;
224 : node *nelm;
225 : } changeset;
226 :
227 : typedef struct objlist {
228 : list *l;
229 : sql_hash *h;
230 : sql_store store;
231 : } objlist;
232 :
233 : struct sql_trans;
234 : struct sql_change;
235 : struct objectset;
236 : struct versionhead;
237 : struct os_iter {
238 : struct objectset *os;
239 : struct sql_trans *tr;
240 : struct versionhead *n;
241 : struct sql_hash_e *e;
242 : const char *name;
243 : };
244 :
245 : /* transaction changes */
246 : typedef int (*tc_valid_fptr) (struct sql_trans *tr, struct sql_change *c/*, ulng commit_ts, ulng oldest*/);
247 : typedef int (*tc_log_fptr) (struct sql_trans *tr, struct sql_change *c); /* write changes to the log */
248 : typedef int (*tc_commit_fptr) (struct sql_trans *tr, struct sql_change *c, ulng commit_ts, ulng oldest);/* commit/rollback changes */
249 : typedef int (*tc_cleanup_fptr) (sql_store store, struct sql_change *c, ulng oldest); /* garbage collection, ie cleanup structures when possible */
250 : typedef void (*destroy_fptr)(sql_store store, sql_base *b);
251 : typedef int (*validate_fptr)(struct sql_trans *tr, sql_base *b, int delete);
252 :
253 : extern struct objectset *os_new(allocator *sa, destroy_fptr destroy, bool temporary, bool unique, bool concurrent, bool nested, sql_store store);
254 : extern struct objectset *os_dup(struct objectset *os);
255 : extern void os_destroy(struct objectset *os, sql_store store);
256 : 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);
257 : extern int os_del(struct objectset *os, struct sql_trans *tr, const char *name, sql_base *b);
258 : extern int os_size(struct objectset *os, struct sql_trans *tr);
259 : extern int os_empty(struct objectset *os, struct sql_trans *tr);
260 : extern int os_remove(struct objectset *os, struct sql_trans *tr, const char *name);
261 : extern sql_base *os_find_name(struct objectset *os, struct sql_trans *tr, const char *name);
262 : extern sql_base *os_find_id(struct objectset *os, struct sql_trans *tr, sqlid id);
263 : /* iterating (for example for location functions) */
264 : extern void os_iterator(struct os_iter *oi, struct objectset *os, struct sql_trans *tr, const char *name /*optional*/);
265 : extern sql_base *oi_next(struct os_iter *oi);
266 : extern bool os_obj_intransaction(struct objectset *os, struct sql_trans *tr, sql_base *b);
267 : extern bool os_has_changes(struct objectset *os, struct sql_trans *tr);
268 :
269 : extern objlist *ol_new(allocator *sa, destroy_fptr destroy, sql_store store);
270 : extern void ol_destroy(objlist *ol, sql_store store);
271 : extern int ol_add(objlist *ol, sql_base *data);
272 : extern void ol_del(objlist *ol, sql_store store, node *data);
273 : extern node *ol_find_name(objlist *ol, const char *name);
274 : extern node *ol_find_id(objlist *ol, sqlid id);
275 : extern node *ol_rehash(objlist *ol, const char *oldname, node *n);
276 : #define ol_length(ol) (list_length(ol->l))
277 : #define ol_first_node(ol) (ol->l->h)
278 : #define ol_last_node(ol) (ol->l->t)
279 : #define ol_fetch(ol,nr) (list_fetch(ol->l, nr))
280 :
281 : extern void cs_new(changeset * cs, allocator *sa, fdestroy destroy, fkeyvalue hfunc);
282 : extern void cs_destroy(changeset * cs, void *data);
283 : extern changeset *cs_add(changeset * cs, void *elm, bool isnew);
284 : extern changeset *cs_del(changeset * cs, void *gdata, node *n, bool force);
285 : extern int cs_size(changeset * cs);
286 : extern node *cs_find_id(changeset * cs, sqlid id);
287 :
288 : typedef void *backend_code;
289 : typedef size_t backend_stack;
290 :
291 : typedef struct sql_schema {
292 : sql_base base;
293 : sqlid auth_id;
294 : sqlid owner;
295 : bit system; /* system or user schema */
296 : // TODO? int type; /* persistent, session local, transaction local */
297 :
298 : struct objectset *tables;
299 : struct objectset *types;
300 : struct objectset *funcs;
301 : struct objectset *seqs;
302 : struct objectset *keys; /* Names for keys, idxs, and triggers and parts are */
303 : struct objectset *idxs; /* global, but these objects are only */
304 : struct objectset *triggers; /* useful within a table */
305 : struct objectset *parts;
306 :
307 : char *internal; /* optional internal module name */
308 : sql_store store;
309 : } sql_schema;
310 :
311 : typedef struct sql_catalog {
312 : ATOMIC_TYPE schema_version;
313 :
314 : struct objectset *schemas;
315 : struct objectset *objects;
316 : } sql_catalog;
317 :
318 : typedef struct sql_trans {
319 : char *name;
320 :
321 : ulng ts; /* transaction start timestamp */
322 : ulng tid; /* transaction id */
323 :
324 : sql_store store; /* keep link into the global store */
325 : MT_Lock lock; /* lock protecting concurrent writes to the changes list */
326 : list *changes; /* list of changes */
327 :
328 : list *dropped; /* protection against recursive cascade action*/
329 : list *predicates; /* list of read predicates logged during update transactions */
330 : list *dependencies; /* list of dependencies created (list of sqlids from the objects) */
331 : list *depchanges; /* list of dependencies changed (it would be tested for conflicts at the end of the transaction) */
332 :
333 : lng logchanges; /* count number of changes to be applied to the wal */
334 : int active; /* is active transaction */
335 : int status; /* status of the last query */
336 :
337 : sql_catalog *cat;
338 : sql_schema *tmp; /* each session has its own tmp schema */
339 : struct objectset* localtmps;
340 :
341 : struct sql_trans *parent; /* multilevel transaction support */
342 : } sql_trans;
343 :
344 : typedef enum sql_class {
345 : EC_ANY,
346 : EC_TABLE,
347 : EC_BIT,
348 : EC_CHAR,
349 : EC_STRING,
350 : EC_BLOB,
351 : EC_POS,
352 : EC_NUM,
353 : EC_MONTH,
354 : EC_SEC,
355 : EC_DEC,
356 : EC_FLT,
357 : EC_TIME,
358 : EC_TIME_TZ,
359 : EC_DATE,
360 : EC_TIMESTAMP,
361 : EC_TIMESTAMP_TZ,
362 : EC_GEOM,
363 : EC_EXTERNAL,
364 : EC_MAX /* evaluated to the max value, should be always kept at the bottom */
365 : } sql_class;
366 :
367 : #define has_tz(e) (EC_TEMP_TZ(e))
368 : #define type_has_tz(t) has_tz((t)->type->eclass)
369 : #define EC_VARCHAR(e) ((e)==EC_CHAR||(e)==EC_STRING)
370 : #define EC_INTERVAL(e) ((e)==EC_MONTH||(e)==EC_SEC)
371 : #define EC_NUMBER(e) ((e)==EC_POS||(e)==EC_NUM||EC_INTERVAL(e)||(e)==EC_DEC||(e)==EC_FLT)
372 : #define EC_EXACTNUM(e) ((e)==EC_NUM||(e)==EC_DEC)
373 : #define EC_APPNUM(e) ((e)==EC_FLT)
374 : #define EC_COMPUTE(e) ((e)==EC_NUM||(e)==EC_FLT)
375 : #define EC_TEMP_TZ(e) ((e)==EC_TIME_TZ||(e)==EC_TIMESTAMP_TZ)
376 : #define EC_TEMP(e) ((e)==EC_TIME||(e)==EC_DATE||(e)==EC_TIMESTAMP||EC_TEMP_TZ(e))
377 : #define EC_TEMP_FRAC(e) ((e)==EC_TIME||(e)==EC_TIMESTAMP||EC_TEMP_TZ(e))
378 : #define EC_TEMP_NOFRAC(e) ((e)==EC_TIME||(e)==EC_TIMESTAMP)
379 : #define EC_SCALE(e) ((e)==EC_DEC||EC_TEMP_FRAC(e)||(e)==EC_SEC)
380 :
381 : typedef struct sql_type {
382 : sql_base base;
383 :
384 : char *impl; /* backend correspondent type */
385 : unsigned int digits;
386 : unsigned int scale; /* indicates how scale is used in functions */
387 : int localtype; /* localtype, need for coersions */
388 : unsigned char radix;
389 : sql_class eclass; /* types are grouped into equivalence classes */
390 : sql_schema *s;
391 : } sql_type;
392 :
393 : typedef struct sql_alias {
394 : char *name;
395 : char *alias;
396 : } sql_alias;
397 :
398 : #define ARG_IN 1
399 : #define ARG_OUT 0
400 :
401 : typedef struct sql_subtype {
402 : sql_type *type;
403 : unsigned int digits;
404 : unsigned int scale;
405 : } sql_subtype;
406 :
407 : /* sql_func need type transform rules types are equal if underlying
408 : * types are equal + scale is equal if types do not mach we try type
409 : * conversions which means for simple 1 arg functions
410 : */
411 :
412 : typedef struct sql_arg {
413 : char *name;
414 : bte inout;
415 : sql_subtype type;
416 : } sql_arg;
417 :
418 : typedef enum sql_ftype {
419 : F_FUNC = 1,
420 : F_PROC = 2,
421 : F_AGGR = 3,
422 : F_FILT = 4,
423 : F_UNION = 5,
424 : F_ANALYTIC = 6,
425 : F_LOADER = 7
426 : } sql_ftype;
427 :
428 : #define IS_FUNC(f) ((f)->type == F_FUNC)
429 : #define IS_PROC(f) ((f)->type == F_PROC)
430 : #define IS_AGGR(f) ((f)->type == F_AGGR)
431 : #define IS_FILT(f) ((f)->type == F_FILT)
432 : #define IS_UNION(f) ((f)->type == F_UNION)
433 : #define IS_ANALYTIC(f) ((f)->type == F_ANALYTIC)
434 : #define IS_LOADER(f) ((f)->type == F_LOADER)
435 :
436 : #define FUNC_TYPE_STR(type, F, fn) \
437 : switch (type) { \
438 : case F_FUNC: \
439 : F = "FUNCTION"; \
440 : fn = "function"; \
441 : break; \
442 : case F_PROC: \
443 : F = "PROCEDURE"; \
444 : fn = "procedure"; \
445 : break; \
446 : case F_AGGR: \
447 : F = "AGGREGATE"; \
448 : fn = "aggregate"; \
449 : break; \
450 : case F_FILT: \
451 : F = "FILTER FUNCTION"; \
452 : fn = "filter function"; \
453 : break; \
454 : case F_UNION: \
455 : F = "UNION FUNCTION"; \
456 : fn = "table returning function"; \
457 : break; \
458 : case F_ANALYTIC: \
459 : F = "WINDOW FUNCTION"; \
460 : fn = "window function"; \
461 : break; \
462 : case F_LOADER: \
463 : F = "LOADER FUNCTION"; \
464 : fn = "loader function"; \
465 : break; \
466 : default: \
467 : assert(0); \
468 : }
469 :
470 : typedef enum sql_flang {
471 : FUNC_LANG_INT = 0, /* internal */
472 : FUNC_LANG_MAL = 1, /* create sql external mod.func */
473 : FUNC_LANG_SQL = 2, /* create ... sql function/procedure */
474 : FUNC_LANG_R = 3, /* create .. language R */
475 : FUNC_LANG_C = 4, /* create .. language C */
476 : FUNC_LANG_J = 5, /* create .. language JAVASCRIPT (not implemented) */
477 : /* this should probably be done in a better way */
478 : FUNC_LANG_PY = 6, /* create .. language PYTHON */
479 : /* values 8 and 9 were for Python 2 */
480 : FUNC_LANG_PY3 = 10, /* create .. language PYTHON3 */
481 : /* values 7 and 11 where old map python code */
482 : FUNC_LANG_CPP = 12 /* create .. language CPP */
483 : } sql_flang;
484 :
485 : #define LANG_EXT(l) ((l)>FUNC_LANG_SQL)
486 : #define UDF_LANG(l) ((l)!=FUNC_LANG_INT)
487 :
488 : typedef struct sql_func {
489 : sql_base base;
490 :
491 : char *mod;
492 : char *imp;
493 : /*
494 : Backend implementation function after it gets instantiated.
495 : During instantiation 'imp' will be set, but look for the 'instantiated' value to check if it's done or not.
496 : Note that functions other than SQL and MAL, don't require instantiation and 'imp' is always set.
497 : */
498 : sql_ftype type;
499 : list *ops; /* param list */
500 : list *res; /* list of results */
501 : sql_flang lang;
502 : char *query; /* sql code */
503 : bool
504 : semantics:1, /* When set to true, function incorporates some kind of null semantics */
505 : side_effect:1, /* if the function has side-effects */
506 : varres:1, /* variable output result */
507 : vararg:1, /* variable input arguments */
508 : system:1, /* system function */
509 : instantiated:1, /* if the function is instantiated */
510 : private:1; /* certain functions cannot be bound from user queries */
511 : int fix_scale;
512 : /*
513 : SCALE_NONE => nothing
514 : SCALE_FIX => input scale fixing,
515 : SCALE_ADD => leave inputs as is and do add scales
516 : example numerical multiplication
517 : SCALE_SUB => first input scale, fix with second scale
518 : result scale is equal to first input
519 : example numerical division
520 : DIGITS_ADD => result digits, sum of args
521 : example string concat
522 : */
523 : sql_schema *s;
524 : allocator *sa;
525 : } sql_func;
526 :
527 : typedef struct sql_subfunc {
528 : sql_func *func;
529 : list *res;
530 : list *coltypes; /* we need this for copy into from loader */
531 : list *colnames; /* we need this for copy into from loader */
532 : char *sname, *tname; /* we need this for create table from loader */
533 : } sql_subfunc;
534 :
535 : typedef enum key_type {
536 : pkey,
537 : ukey, /* default behavior is that NULLS are distinct, e.g. there can be multiple null values in a column with regular UNIQUE constraint */
538 : fkey,
539 : unndkey, /* NULLS are not distinct, i.e. NULLS act as regular values for uniqueness checks */
540 : ckey /* CHECK constraint behaves as a key type*/
541 : } key_type;
542 :
543 : typedef struct sql_kc {
544 : struct sql_column *c;
545 : int trunc; /* 0 not truncated, >0 column is truncated */
546 : } sql_kc;
547 :
548 : typedef enum idx_type {
549 : hash_idx,
550 : join_idx,
551 : oph_idx, /* order preserving hash */
552 : no_idx, /* no idx, ie no storage */
553 : imprints_idx,
554 : ordered_idx,
555 : new_idx_types
556 : } idx_type;
557 :
558 : #define hash_index(t) ((t) == hash_idx || (t) == oph_idx)
559 : #define idx_has_column(t) (hash_index(t) || (t) == join_idx)
560 : #define oid_index(t) ((t) == join_idx)
561 : #define non_updatable_index(t) ((t) == ordered_idx || (t) == no_idx || !idx_has_column(t))
562 :
563 : typedef struct sql_idx {
564 : sql_base base;
565 : idx_type type; /* unique */
566 : struct list *columns; /* list of sql_kc */
567 : struct sql_table *t;
568 : struct sql_key *key; /* key */
569 : ATOMIC_PTR_TYPE data;
570 : } sql_idx;
571 :
572 : /* fkey consists of two of these */
573 : typedef struct sql_key { /* pkey, ukey, fkey */
574 : sql_base base;
575 : key_type type; /* pkey, ukey, fkey */
576 : sql_idx *idx; /* idx to accelerate key check */
577 : char *check; /* check condition*/
578 :
579 : struct list *columns; /* list of sql_kc */
580 : struct sql_table *t;
581 : int drop_action; /* only needed for alter drop key */
582 : } sql_key;
583 :
584 : typedef struct sql_ukey { /* pkey, ukey */
585 : sql_key k;
586 : //list *keys;
587 : } sql_ukey;
588 :
589 : typedef struct sql_fkey { /* fkey */
590 : sql_key k;
591 : /* 0=no action, 1=cascade, 2=restrict (default setting), 3=set null, 4=set default */
592 : int on_delete;
593 : int on_update;
594 : sqlid rkey;
595 : } sql_fkey;
596 :
597 : typedef struct sql_trigger {
598 : sql_base base;
599 : sht time; /* before or after */
600 : sht orientation; /* row or statement */
601 : sht event; /* insert, delete, update, truncate */
602 : /* int action_order; TODO, order within the set of triggers */
603 : struct list *columns; /* update trigger on list of (sql_kc) columns */
604 :
605 : struct sql_table *t;
606 : char *old_name; /* name referencing the old values */
607 : char *new_name; /* name referencing the new values */
608 :
609 : char *condition; /* when search condition, ie query */
610 : char *statement; /* action, ie list of sql statements */
611 : } sql_trigger;
612 :
613 : typedef struct sql_sequence {
614 : sql_base base;
615 : lng start;
616 : lng minvalue;
617 : lng maxvalue;
618 : lng increment;
619 : lng cacheinc;
620 : bit cycle;
621 : bit bedropped; /*Drop the SEQUENCE if you are dropping the column, e.g., SERIAL COLUMN".*/
622 : sql_schema *s;
623 : } sql_sequence;
624 :
625 : typedef struct sql_column {
626 : sql_base base;
627 : sql_subtype type;
628 : int colnr;
629 : bit null;
630 : char *def;
631 : char unique; /* 0 NOT UNIQUE, 1 SUB_UNIQUE, 2 UNIQUE */
632 : int drop_action; /* only used for alter statements */
633 : char *storage_type;
634 : size_t dcount;
635 : void *min;
636 : void *max;
637 :
638 : struct sql_table *t;
639 : ATOMIC_PTR_TYPE data;
640 : } sql_column;
641 :
642 : typedef enum table_types {
643 : tt_table = 0, /* table */
644 : tt_view = 1, /* view */
645 : tt_merge_table = 3, /* multiple tables form one table */
646 : /* tt_stream = 4, stream tables are not used anymore */
647 : tt_remote = 5, /* stored on a remote server */
648 : tt_replica_table = 6, /* multiple replica of the same table */
649 : tt_unlogged_table = 7
650 : } table_types;
651 :
652 : #define TABLE_TYPE_DESCRIPTION(tt, properties) \
653 : ((tt) == tt_table) ? "TABLE" : ((tt) == tt_view) ? "VIEW" \
654 : : ((tt) == tt_merge_table && !(properties)) ? "MERGE TABLE" \
655 : : ((tt) == tt_remote) ? "REMOTE TABLE" \
656 : : ((tt) == tt_merge_table && ((properties)&PARTITION_LIST) == PARTITION_LIST) ? "LIST PARTITION TABLE" \
657 : : ((tt) == tt_merge_table && ((properties)&PARTITION_RANGE) == PARTITION_RANGE) ? "RANGE PARTITION TABLE" \
658 : : ((tt) == tt_unlogged_table) ? "UNLOGGED TABLE" \
659 : : "REPLICA TABLE"
660 :
661 : #define isTable(x) ((x)->type==tt_table || (x)->type==tt_unlogged_table)
662 : #define isView(x) ((x)->type==tt_view)
663 : #define isNonPartitionedTable(x) ((x)->type==tt_merge_table && !(x)->properties)
664 : #define isRangePartitionTable(x) ((x)->type==tt_merge_table && ((x)->properties & PARTITION_RANGE) == PARTITION_RANGE)
665 : #define isListPartitionTable(x) ((x)->type==tt_merge_table && ((x)->properties & PARTITION_LIST) == PARTITION_LIST)
666 : #define isPartitionedByColumnTable(x) ((x)->type==tt_merge_table && ((x)->properties & PARTITION_COLUMN) == PARTITION_COLUMN)
667 : #define isPartitionedByExpressionTable(x) ((x)->type==tt_merge_table && ((x)->properties & PARTITION_EXPRESSION) == PARTITION_EXPRESSION)
668 : #define isMergeTable(x) ((x)->type==tt_merge_table)
669 : #define isRemote(x) ((x)->type==tt_remote)
670 : #define isReplicaTable(x) ((x)->type==tt_replica_table)
671 : #define isUnloggedTable(x) ((x)->type==tt_unlogged_table)
672 : #define isKindOfTable(x) (isTable(x) || isMergeTable(x) || isRemote(x) || isReplicaTable(x) || isUnloggedTable(x))
673 :
674 : #define TABLE_WRITABLE 0
675 : #define TABLE_READONLY 1
676 : #define TABLE_APPENDONLY 2
677 :
678 : typedef struct sql_part_value {
679 : ptr value;
680 : size_t length;
681 : } sql_part_value;
682 :
683 : typedef struct sql_part {
684 : sql_base base;
685 : struct sql_table *t; /* the merge table */
686 : sqlid member; /* the member of the merge table */
687 : bit with_nills; /* 0 no nills, 1 holds nills, NULL holds all values -> range FROM MINVALUE TO MAXVALUE WITH NULL */
688 : union {
689 : list *values; /* partition by values/list */
690 : struct sql_range { /* partition by range */
691 : ptr minvalue;
692 : ptr maxvalue;
693 : size_t minlength;
694 : size_t maxlength;
695 : } range;
696 : } part;
697 : } sql_part;
698 :
699 : typedef struct sql_expression {
700 : sql_subtype type; /* the returning sql_subtype of the expression */
701 : char *exp; /* the expression itself */
702 : list *cols; /* list of colnr of the columns of the table used in the expression */
703 : } sql_expression;
704 :
705 : typedef struct sql_table {
706 : sql_base base;
707 : sht type; /* table, view, etc */
708 : sht access; /* writable, readonly, appendonly */
709 : bit system; /* system or user table */
710 : bit bootstrap; /* system table created during bootstrap */
711 : bte properties; /* used for merge_tables */
712 : temp_t persistence; /* persistent, global or local temporary */
713 : ca_t commit_action; /* on commit action */
714 : char *query; /* views may require some query */
715 : int sz;
716 :
717 : sql_ukey *pkey;
718 : objlist *columns;
719 : objlist *idxs;
720 : objlist *keys;
721 : objlist *triggers;
722 : list *members; /* member tables of merge/replica tables */
723 : int drop_action; /* only needed for alter drop table */
724 :
725 : ATOMIC_PTR_TYPE data;
726 : sql_schema *s;
727 :
728 : union {
729 : struct sql_column *pcol; /* If it is partitioned on a column */
730 : struct sql_expression *pexp; /* If it is partitioned by an expression */
731 : } part;
732 : } sql_table;
733 :
734 : typedef struct res_col {
735 : char *tn;
736 : char *name;
737 : sql_subtype type;
738 : bat b;
739 : char mtype;
740 : bool cached;
741 : ptr *p;
742 : } res_col;
743 :
744 : typedef struct res_table {
745 : int id;
746 : oid query_id;
747 : mapi_query_t query_type;
748 : int nr_cols;
749 : BUN nr_rows;
750 : BUN cur_row;
751 : int cur_col;
752 : const char *tsep;
753 : const char *rsep;
754 : const char *ssep;
755 : const char *ns;
756 : res_col *cols;
757 : struct res_table *next;
758 : } res_table;
759 :
760 : typedef struct sql_session {
761 : allocator *sa;
762 : sql_trans *tr; /* active transaction */
763 :
764 : char *def_schema_name; /* users default schema name */
765 : char *schema_name; /* transaction's schema name */
766 : sql_schema *schema;
767 : ATOMIC_TYPE schema_version;
768 :
769 : char ac_on_commit; /* if 1, auto_commit should be enabled on
770 : commit, rollback, etc. */
771 : char auto_commit;
772 : int level; /* TRANSACTION isolation level */
773 : int status; /* status, ok/error */
774 : backend_stack stk;
775 : } sql_session;
776 :
777 : #define sql_base_loop(l, n) for (n=l->h; n; n=n->next)
778 :
779 : extern int base_key(sql_base *b);
780 : extern node *list_find_name(list *l, const char *name);
781 : extern node *list_find_id(list *l, sqlid id);
782 : extern node *list_find_base_id(list *l, sqlid id);
783 :
784 : extern sql_key *find_sql_key(sql_table *t, const char *kname);
785 : extern sql_key *sql_trans_find_key(sql_trans *tr, sqlid id);
786 : extern sql_key *schema_find_key(sql_trans *tr, sql_schema *s, const char *name);
787 :
788 : extern sql_idx *find_sql_idx(sql_table *t, const char *kname);
789 : extern sql_idx *sql_trans_find_idx(sql_trans *tr, sqlid id);
790 : extern sql_idx *schema_find_idx(sql_trans *tr, sql_schema *s, const char *name);
791 : extern sql_idx *schema_find_idx_id(sql_trans *tr, sql_schema *s, sqlid id);
792 :
793 : extern sql_column *find_sql_column(sql_table *t, const char *cname);
794 :
795 : extern sql_table *find_sys_table(sql_trans *tr, const char *tname);
796 : extern sql_table *find_sql_table(sql_trans *tr, sql_schema *s, const char *tname);
797 : extern sql_table *find_sql_table_id(sql_trans *tr, sql_schema *s, sqlid id);
798 : extern sql_table *sql_trans_find_table(sql_trans *tr, sqlid id);
799 :
800 : extern sql_sequence *find_sql_sequence(sql_trans *tr, sql_schema *s, const char *sname);
801 :
802 : extern sql_schema *find_sql_schema(sql_trans *t, const char *sname);
803 : extern sql_schema *find_sql_schema_id(sql_trans *t, sqlid id);
804 :
805 : extern sql_type *find_sql_type(sql_trans *tr, sql_schema * s, const char *tname);
806 : extern sql_type *sql_trans_bind_type(sql_trans *tr, sql_schema *s, const char *name);
807 : extern sql_type *sql_trans_find_type(sql_trans *tr, sql_schema *s /*optional */, sqlid id);
808 : extern sql_func *sql_trans_find_func(sql_trans *tr, sqlid id);
809 : extern sql_trigger *sql_trans_find_trigger(sql_trans *tr, sqlid id);
810 : extern sql_trigger *schema_find_trigger(sql_trans *tr, sql_schema *s, const char *name);
811 :
812 : extern void find_partition_type(sql_subtype *tpe, sql_table *mt);
813 : extern void *sql_values_list_element_validate_and_insert(void *v1, void *v2, void *tpe, int* res);
814 : extern void *sql_range_part_validate_and_insert(void *v1, void *v2, void *tpe);
815 : extern void *sql_values_part_validate_and_insert(void *v1, void *v2, void *tpe);
816 :
817 : typedef struct {
818 : BAT *b;
819 : char* name;
820 : void* def;
821 : } sql_emit_col;
822 :
823 : extern int nested_mergetable(sql_trans *tr, sql_table *t, const char *sname, const char *tname);
824 : extern bool is_column_unique(sql_column *c);
825 : sql_export sql_part *partition_find_part(sql_trans *tr, sql_table *pt, sql_part *pp);
826 : extern node *members_find_child_id(list *l, sqlid id);
827 :
828 : #define outside_str 1
829 : #define inside_str 2
830 :
831 : #define extracting_schema 1
832 : #define extracting_sequence 2
833 :
834 : static inline void
835 169 : extract_schema_and_sequence_name(allocator *sa, char *default_value, char **schema, char **sequence)
836 : {
837 169 : int status = outside_str, identifier = extracting_schema;
838 169 : char next_identifier[1024]; /* needs one extra character for null terminator */
839 169 : size_t bp = 0;
840 :
841 2691 : for (size_t i = 0; default_value[i]; i++) {
842 2691 : char next = default_value[i];
843 :
844 2691 : if (next == '"') {
845 508 : if (status == inside_str && default_value[i + 1] == '"') {
846 1 : next_identifier[bp++] = '"';
847 1 : i++; /* has to advance two positions */
848 338 : } else if (status == inside_str) {
849 338 : next_identifier[bp++] = '\0';
850 338 : if (identifier == extracting_schema) {
851 169 : *schema = SA_STRDUP(sa, next_identifier);
852 169 : identifier = extracting_sequence;
853 169 : } else if (identifier == extracting_sequence) {
854 169 : *sequence = SA_STRDUP(sa, next_identifier);
855 169 : break; /* done extracting */
856 : }
857 : bp = 0;
858 : status = outside_str;
859 : } else {
860 : assert(status == outside_str);
861 : status = inside_str;
862 : }
863 2183 : } else if (next == '.') {
864 169 : if (status == outside_str && default_value[i + 1] == '"') {
865 : status = inside_str;
866 : i++; /* has to advance two positions */
867 : } else {
868 0 : assert(status == inside_str);
869 0 : next_identifier[bp++] = '.'; /* used inside an identifier name */
870 : }
871 2014 : } else if (status == inside_str) {
872 2014 : next_identifier[bp++] = next;
873 : } else {
874 : assert(status == outside_str);
875 : }
876 : }
877 169 : }
878 :
879 : extern void arg_destroy(sql_store store, sql_arg *a);
880 : extern void part_value_destroy(sql_store store, sql_part_value *pv);
881 :
882 : typedef struct atom {
883 : int isnull;
884 : sql_subtype tpe;
885 : ValRecord data;
886 : } atom;
887 :
888 : /* duplicate atom */
889 : extern ValPtr SA_VALcopy(allocator *sa, ValPtr d, const ValRecord *s);
890 : extern atom *atom_copy(allocator *sa, atom *a);
891 :
892 : typedef struct pl {
893 : sql_column *c;
894 : unsigned int cmp;
895 : atom *r; /* if r is NULL then a full match is required */
896 : atom *f; /* make it match range expressions */
897 : uint8_t
898 : anti:1,
899 : semantics:1;
900 : } pl;
901 :
902 : #endif /* SQL_CATALOG_H */
|