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 : order_required:1, /* some aggregate functions require an order */
512 : opt_order:1; /* some aggregate functions could have the inputs sorted */
513 :
514 : short fix_scale;
515 : /*
516 : SCALE_NONE => nothing
517 : SCALE_FIX => input scale fixing,
518 : SCALE_ADD => leave inputs as is and do add scales
519 : example numerical multiplication
520 : SCALE_SUB => first input scale, fix with second scale
521 : result scale is equal to first input
522 : example numerical division
523 : DIGITS_ADD => result digits, sum of args
524 : example string concat
525 : */
526 : sql_schema *s;
527 : allocator *sa;
528 : } sql_func;
529 :
530 : typedef struct sql_subfunc {
531 : sql_func *func;
532 : list *res;
533 : list *coltypes; /* we need this for copy into from loader */
534 : list *colnames; /* we need this for copy into from loader */
535 : char *sname, *tname; /* we need this for create table from loader */
536 : } sql_subfunc;
537 :
538 : typedef enum key_type {
539 : pkey,
540 : ukey, /* default behavior is that NULLS are distinct, e.g. there can be multiple null values in a column with regular UNIQUE constraint */
541 : fkey,
542 : unndkey, /* NULLS are not distinct, i.e. NULLS act as regular values for uniqueness checks */
543 : ckey /* CHECK constraint behaves as a key type*/
544 : } key_type;
545 :
546 : typedef struct sql_kc {
547 : struct sql_column *c;
548 : int trunc; /* 0 not truncated, >0 column is truncated */
549 : } sql_kc;
550 :
551 : typedef enum idx_type {
552 : hash_idx,
553 : join_idx,
554 : oph_idx, /* order preserving hash */
555 : no_idx, /* no idx, ie no storage */
556 : imprints_idx,
557 : ordered_idx,
558 : new_idx_types
559 : } idx_type;
560 :
561 : #define hash_index(t) ((t) == hash_idx || (t) == oph_idx)
562 : #define idx_has_column(t) (hash_index(t) || (t) == join_idx)
563 : #define oid_index(t) ((t) == join_idx)
564 : #define non_updatable_index(t) ((t) == ordered_idx || (t) == no_idx || !idx_has_column(t))
565 :
566 : typedef struct sql_idx {
567 : sql_base base;
568 : idx_type type; /* unique */
569 : struct list *columns; /* list of sql_kc */
570 : struct sql_table *t;
571 : struct sql_key *key; /* key */
572 : ATOMIC_PTR_TYPE data;
573 : } sql_idx;
574 :
575 : /* fkey consists of two of these */
576 : typedef struct sql_key { /* pkey, ukey, fkey */
577 : sql_base base;
578 : key_type type; /* pkey, ukey, fkey */
579 : sql_idx *idx; /* idx to accelerate key check */
580 : char *check; /* check condition*/
581 :
582 : struct list *columns; /* list of sql_kc */
583 : struct sql_table *t;
584 : int drop_action; /* only needed for alter drop key */
585 : } sql_key;
586 :
587 : typedef struct sql_ukey { /* pkey, ukey */
588 : sql_key k;
589 : //list *keys;
590 : } sql_ukey;
591 :
592 : typedef struct sql_fkey { /* fkey */
593 : sql_key k;
594 : /* 0=no action, 1=cascade, 2=restrict (default setting), 3=set null, 4=set default */
595 : int on_delete;
596 : int on_update;
597 : sqlid rkey;
598 : } sql_fkey;
599 :
600 : typedef struct sql_trigger {
601 : sql_base base;
602 : sht time; /* before or after */
603 : sht orientation; /* row or statement */
604 : sht event; /* insert, delete, update, truncate */
605 : /* int action_order; TODO, order within the set of triggers */
606 : struct list *columns; /* update trigger on list of (sql_kc) columns */
607 :
608 : struct sql_table *t;
609 : char *old_name; /* name referencing the old values */
610 : char *new_name; /* name referencing the new values */
611 :
612 : char *condition; /* when search condition, ie query */
613 : char *statement; /* action, ie list of sql statements */
614 : } sql_trigger;
615 :
616 : typedef struct sql_sequence {
617 : sql_base base;
618 : lng start;
619 : lng minvalue;
620 : lng maxvalue;
621 : lng increment;
622 : lng cacheinc;
623 : bit cycle;
624 : bit bedropped; /*Drop the SEQUENCE if you are dropping the column, e.g., SERIAL COLUMN".*/
625 : sql_schema *s;
626 : } sql_sequence;
627 :
628 : typedef struct sql_column {
629 : sql_base base;
630 : sql_subtype type;
631 : int colnr;
632 : bit null;
633 : char *def;
634 : char unique; /* 0 NOT UNIQUE, 1 SUB_UNIQUE, 2 UNIQUE */
635 : int drop_action; /* only used for alter statements */
636 : char *storage_type;
637 : size_t dcount;
638 : void *min;
639 : void *max;
640 :
641 : struct sql_table *t;
642 : ATOMIC_PTR_TYPE data;
643 : } sql_column;
644 :
645 : typedef enum table_types {
646 : tt_table = 0, /* table */
647 : tt_view = 1, /* view */
648 : tt_merge_table = 3, /* multiple tables form one table */
649 : /* tt_stream = 4, stream tables are not used anymore */
650 : tt_remote = 5, /* stored on a remote server */
651 : tt_replica_table = 6, /* multiple replica of the same table */
652 : tt_unlogged_table = 7
653 : } table_types;
654 :
655 : #define TABLE_TYPE_DESCRIPTION(tt, properties) \
656 : ((tt) == tt_table) ? "TABLE" : ((tt) == tt_view) ? "VIEW" \
657 : : ((tt) == tt_merge_table && !(properties)) ? "MERGE TABLE" \
658 : : ((tt) == tt_remote) ? "REMOTE TABLE" \
659 : : ((tt) == tt_merge_table && ((properties)&PARTITION_LIST) == PARTITION_LIST) ? "LIST PARTITION TABLE" \
660 : : ((tt) == tt_merge_table && ((properties)&PARTITION_RANGE) == PARTITION_RANGE) ? "RANGE PARTITION TABLE" \
661 : : ((tt) == tt_unlogged_table) ? "UNLOGGED TABLE" \
662 : : "REPLICA TABLE"
663 :
664 : #define isTable(x) ((x)->type==tt_table || (x)->type==tt_unlogged_table)
665 : #define isView(x) ((x)->type==tt_view)
666 : #define isNonPartitionedTable(x) ((x)->type==tt_merge_table && !(x)->properties)
667 : #define isRangePartitionTable(x) ((x)->type==tt_merge_table && ((x)->properties & PARTITION_RANGE) == PARTITION_RANGE)
668 : #define isListPartitionTable(x) ((x)->type==tt_merge_table && ((x)->properties & PARTITION_LIST) == PARTITION_LIST)
669 : #define isPartitionedByColumnTable(x) ((x)->type==tt_merge_table && ((x)->properties & PARTITION_COLUMN) == PARTITION_COLUMN)
670 : #define isPartitionedByExpressionTable(x) ((x)->type==tt_merge_table && ((x)->properties & PARTITION_EXPRESSION) == PARTITION_EXPRESSION)
671 : #define isMergeTable(x) ((x)->type==tt_merge_table)
672 : #define isRemote(x) ((x)->type==tt_remote)
673 : #define isReplicaTable(x) ((x)->type==tt_replica_table)
674 : #define isUnloggedTable(x) ((x)->type==tt_unlogged_table)
675 : #define isKindOfTable(x) (isTable(x) || isMergeTable(x) || isRemote(x) || isReplicaTable(x) || isUnloggedTable(x))
676 :
677 : #define TABLE_WRITABLE 0
678 : #define TABLE_READONLY 1
679 : #define TABLE_APPENDONLY 2
680 :
681 : typedef struct sql_part_value {
682 : ptr value;
683 : size_t length;
684 : } sql_part_value;
685 :
686 : typedef struct sql_part {
687 : sql_base base;
688 : struct sql_table *t; /* the merge table */
689 : sqlid member; /* the member of the merge table */
690 : bit with_nills; /* 0 no nills, 1 holds nills, NULL holds all values -> range FROM MINVALUE TO MAXVALUE WITH NULL */
691 : union {
692 : list *values; /* partition by values/list */
693 : struct sql_range { /* partition by range */
694 : ptr minvalue;
695 : ptr maxvalue;
696 : size_t minlength;
697 : size_t maxlength;
698 : } range;
699 : } part;
700 : } sql_part;
701 :
702 : typedef struct sql_expression {
703 : sql_subtype type; /* the returning sql_subtype of the expression */
704 : char *exp; /* the expression itself */
705 : list *cols; /* list of colnr of the columns of the table used in the expression */
706 : } sql_expression;
707 :
708 : typedef struct sql_table {
709 : sql_base base;
710 : sht type; /* table, view, etc */
711 : sht access; /* writable, readonly, appendonly */
712 : bit system; /* system or user table */
713 : bit bootstrap; /* system table created during bootstrap */
714 : bte properties; /* used for merge_tables */
715 : temp_t persistence; /* persistent, global or local temporary */
716 : ca_t commit_action; /* on commit action */
717 : char *query; /* views may require some query */
718 : int sz;
719 :
720 : sql_ukey *pkey;
721 : objlist *columns;
722 : objlist *idxs;
723 : objlist *keys;
724 : objlist *triggers;
725 : list *members; /* member tables of merge/replica tables */
726 : int drop_action; /* only needed for alter drop table */
727 :
728 : ATOMIC_PTR_TYPE data;
729 : sql_schema *s;
730 :
731 : union {
732 : struct sql_column *pcol; /* If it is partitioned on a column */
733 : struct sql_expression *pexp; /* If it is partitioned by an expression */
734 : } part;
735 : } sql_table;
736 :
737 : typedef struct res_col {
738 : char *tn;
739 : char *name;
740 : sql_subtype type;
741 : bat b;
742 : char mtype;
743 : bool cached;
744 : ptr *p;
745 : } res_col;
746 :
747 : typedef struct res_table {
748 : int id;
749 : oid query_id;
750 : mapi_query_t query_type;
751 : int nr_cols;
752 : BUN nr_rows;
753 : BUN cur_row;
754 : int cur_col;
755 : const char *tsep;
756 : const char *rsep;
757 : const char *ssep;
758 : const char *ns;
759 : res_col *cols;
760 : struct res_table *next;
761 : } res_table;
762 :
763 : typedef struct sql_session {
764 : allocator *sa;
765 : sql_trans *tr; /* active transaction */
766 :
767 : char *def_schema_name; /* users default schema name */
768 : char *schema_name; /* transaction's schema name */
769 : sql_schema *schema;
770 : ATOMIC_TYPE schema_version;
771 :
772 : char ac_on_commit; /* if 1, auto_commit should be enabled on
773 : commit, rollback, etc. */
774 : char auto_commit;
775 : int level; /* TRANSACTION isolation level */
776 : int status; /* status, ok/error */
777 : backend_stack stk;
778 : } sql_session;
779 :
780 : #define sql_base_loop(l, n) for (n=l->h; n; n=n->next)
781 :
782 : extern int base_key(sql_base *b);
783 : extern node *list_find_name(list *l, const char *name);
784 : extern node *list_find_id(list *l, sqlid id);
785 : extern node *list_find_base_id(list *l, sqlid id);
786 :
787 : extern sql_key *find_sql_key(sql_table *t, const char *kname);
788 : extern sql_key *sql_trans_find_key(sql_trans *tr, sqlid id);
789 : extern sql_key *schema_find_key(sql_trans *tr, sql_schema *s, const char *name);
790 :
791 : extern sql_idx *find_sql_idx(sql_table *t, const char *kname);
792 : extern sql_idx *sql_trans_find_idx(sql_trans *tr, sqlid id);
793 : extern sql_idx *schema_find_idx(sql_trans *tr, sql_schema *s, const char *name);
794 : extern sql_idx *schema_find_idx_id(sql_trans *tr, sql_schema *s, sqlid id);
795 :
796 : extern sql_column *find_sql_column(sql_table *t, const char *cname);
797 :
798 : extern sql_table *find_sys_table(sql_trans *tr, const char *tname);
799 : extern sql_table *find_sql_table(sql_trans *tr, sql_schema *s, const char *tname);
800 : extern sql_table *find_sql_table_id(sql_trans *tr, sql_schema *s, sqlid id);
801 : extern sql_table *sql_trans_find_table(sql_trans *tr, sqlid id);
802 :
803 : extern sql_sequence *find_sql_sequence(sql_trans *tr, sql_schema *s, const char *sname);
804 :
805 : extern sql_schema *find_sql_schema(sql_trans *t, const char *sname);
806 : extern sql_schema *find_sql_schema_id(sql_trans *t, sqlid id);
807 :
808 : extern sql_type *find_sql_type(sql_trans *tr, sql_schema * s, const char *tname);
809 : extern sql_type *sql_trans_bind_type(sql_trans *tr, sql_schema *s, const char *name);
810 : extern sql_type *sql_trans_find_type(sql_trans *tr, sql_schema *s /*optional */, sqlid id);
811 : extern sql_func *sql_trans_find_func(sql_trans *tr, sqlid id);
812 : extern sql_trigger *sql_trans_find_trigger(sql_trans *tr, sqlid id);
813 : extern sql_trigger *schema_find_trigger(sql_trans *tr, sql_schema *s, const char *name);
814 :
815 : extern void find_partition_type(sql_subtype *tpe, sql_table *mt);
816 : extern void *sql_values_list_element_validate_and_insert(void *v1, void *v2, void *tpe, int* res);
817 : extern void *sql_range_part_validate_and_insert(void *v1, void *v2, void *tpe);
818 : extern void *sql_values_part_validate_and_insert(void *v1, void *v2, void *tpe);
819 :
820 : typedef struct {
821 : BAT *b;
822 : char* name;
823 : void* def;
824 : } sql_emit_col;
825 :
826 : extern int nested_mergetable(sql_trans *tr, sql_table *t, const char *sname, const char *tname);
827 : extern bool is_column_unique(sql_column *c);
828 : sql_export sql_part *partition_find_part(sql_trans *tr, sql_table *pt, sql_part *pp);
829 : extern node *members_find_child_id(list *l, sqlid id);
830 :
831 : #define outside_str 1
832 : #define inside_str 2
833 :
834 : #define extracting_schema 1
835 : #define extracting_sequence 2
836 :
837 : static inline void
838 166 : extract_schema_and_sequence_name(allocator *sa, char *default_value, char **schema, char **sequence)
839 : {
840 166 : int status = outside_str, identifier = extracting_schema;
841 166 : char next_identifier[1024]; /* needs one extra character for null terminator */
842 166 : size_t bp = 0;
843 :
844 2640 : for (size_t i = 0; default_value[i]; i++) {
845 2640 : char next = default_value[i];
846 :
847 2640 : if (next == '"') {
848 499 : if (status == inside_str && default_value[i + 1] == '"') {
849 1 : next_identifier[bp++] = '"';
850 1 : i++; /* has to advance two positions */
851 332 : } else if (status == inside_str) {
852 332 : next_identifier[bp++] = '\0';
853 332 : if (identifier == extracting_schema) {
854 166 : *schema = SA_STRDUP(sa, next_identifier);
855 166 : identifier = extracting_sequence;
856 166 : } else if (identifier == extracting_sequence) {
857 166 : *sequence = SA_STRDUP(sa, next_identifier);
858 166 : break; /* done extracting */
859 : }
860 : bp = 0;
861 : status = outside_str;
862 : } else {
863 : assert(status == outside_str);
864 : status = inside_str;
865 : }
866 2141 : } else if (next == '.') {
867 166 : if (status == outside_str && default_value[i + 1] == '"') {
868 : status = inside_str;
869 : i++; /* has to advance two positions */
870 : } else {
871 0 : assert(status == inside_str);
872 0 : next_identifier[bp++] = '.'; /* used inside an identifier name */
873 : }
874 1975 : } else if (status == inside_str) {
875 1975 : next_identifier[bp++] = next;
876 : } else {
877 : assert(status == outside_str);
878 : }
879 : }
880 166 : }
881 :
882 : extern void arg_destroy(sql_store store, sql_arg *a);
883 : extern void part_value_destroy(sql_store store, sql_part_value *pv);
884 :
885 : typedef struct atom {
886 : int isnull;
887 : sql_subtype tpe;
888 : ValRecord data;
889 : } atom;
890 :
891 : /* duplicate atom */
892 : extern ValPtr SA_VALcopy(allocator *sa, ValPtr d, const ValRecord *s);
893 : extern atom *atom_copy(allocator *sa, atom *a);
894 :
895 : typedef struct pl {
896 : sql_column *c;
897 : unsigned int cmp;
898 : atom *r; /* if r is NULL then a full match is required */
899 : atom *f; /* make it match range expressions */
900 : uint8_t
901 : anti:1,
902 : semantics:1;
903 : } pl;
904 :
905 : #endif /* SQL_CATALOG_H */
|