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