| 1 | /* |
| 2 | * This Source Code Form is subject to the terms of the Mozilla Public |
| 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
| 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
| 5 | * |
| 6 | * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V. |
| 7 | */ |
| 8 | |
| 9 | #ifndef SQL_RELATION_H |
| 10 | #define SQL_RELATION_H |
| 11 | |
| 12 | #include "sql_catalog.h" |
| 13 | |
| 14 | typedef enum expression_type { |
| 15 | e_atom, |
| 16 | e_column, |
| 17 | e_cmp, |
| 18 | e_func, |
| 19 | e_aggr, |
| 20 | e_convert, |
| 21 | e_psm |
| 22 | } expression_type; |
| 23 | |
| 24 | #define CARD_ATOM 1 |
| 25 | #define CARD_AGGR 2 |
| 26 | #define CARD_MULTI 3 |
| 27 | |
| 28 | typedef struct sql_exp_name { |
| 29 | unsigned int label; |
| 30 | const char *name; |
| 31 | const char *rname; |
| 32 | } sql_exp_name; |
| 33 | |
| 34 | typedef struct expression { |
| 35 | expression_type type; /* atom, cmp, func/aggr */ |
| 36 | sql_exp_name alias; |
| 37 | void *l; |
| 38 | void *r; |
| 39 | void *f; /* func's and aggr's, also e_cmp may have have 2 arguments */ |
| 40 | unsigned int |
| 41 | flag:18, /* EXP_DISTINCT, NO_NIL, ASCENDING, NULLS_LAST, cmp types */ |
| 42 | card:2, /* card (0 truth value!) (1 atoms) (2 aggr) (3 multi value) */ |
| 43 | freevar:4, /* free variable, ie binds to the upper dependent join */ |
| 44 | intern:1, |
| 45 | anti:1, |
| 46 | base:1, |
| 47 | used:1; /* used for quick dead code removal */ |
| 48 | sql_subtype tpe; |
| 49 | void *p; /* properties for the optimizer */ |
| 50 | } sql_exp; |
| 51 | |
| 52 | #define EXP_DISTINCT 1 |
| 53 | #define NO_NIL 2 |
| 54 | #define TOPN_INCLUDING 4 |
| 55 | #define ZERO_IF_EMPTY 8 |
| 56 | |
| 57 | #define LEFT_JOIN 4 |
| 58 | |
| 59 | /* ASCENDING > 15 else we have problems with cmp types */ |
| 60 | #define ASCENDING 16 |
| 61 | #define CMPMASK (ASCENDING-1) |
| 62 | #define get_cmp(e) (e->flag&CMPMASK) |
| 63 | #define HAS_NO_NIL 32 |
| 64 | #define NULLS_LAST 64 |
| 65 | |
| 66 | #define UPD_COMP 1 |
| 67 | #define UPD_LOCKED 2 |
| 68 | #define UPD_NO_CONSTRAINT 4 |
| 69 | |
| 70 | #define REL_PARTITION 8 |
| 71 | |
| 72 | /* We need bit wise exclusive numbers as we merge the level also in the flag */ |
| 73 | #define PSM_SET 1 |
| 74 | #define PSM_VAR 2 |
| 75 | #define PSM_RETURN 4 |
| 76 | #define PSM_WHILE 8 |
| 77 | #define PSM_IF 16 |
| 78 | #define PSM_REL 32 |
| 79 | #define PSM_EXCEPTION 64 |
| 80 | |
| 81 | #define SET_PSM_LEVEL(level) (level<<8) |
| 82 | #define GET_PSM_LEVEL(level) (level>>8) |
| 83 | |
| 84 | typedef enum ddl_statement { |
| 85 | ddl_output, |
| 86 | ddl_list, |
| 87 | ddl_psm, |
| 88 | ddl_exception, |
| 89 | ddl_create_seq, |
| 90 | ddl_alter_seq, |
| 91 | ddl_drop_seq, |
| 92 | ddl_alter_table_add_range_partition, |
| 93 | ddl_alter_table_add_list_partition, |
| 94 | ddl_release, |
| 95 | ddl_commit, |
| 96 | ddl_rollback, |
| 97 | ddl_trans, |
| 98 | ddl_create_schema, |
| 99 | ddl_drop_schema, |
| 100 | ddl_create_table, |
| 101 | ddl_drop_table, |
| 102 | ddl_create_view, |
| 103 | ddl_drop_view, |
| 104 | ddl_drop_constraint, |
| 105 | ddl_alter_table, |
| 106 | ddl_create_type, |
| 107 | ddl_drop_type, |
| 108 | ddl_drop_index, |
| 109 | ddl_create_function, |
| 110 | ddl_drop_function, |
| 111 | ddl_create_trigger, |
| 112 | ddl_drop_trigger, |
| 113 | ddl_grant_roles, |
| 114 | ddl_revoke_roles, |
| 115 | ddl_grant, |
| 116 | ddl_revoke, |
| 117 | ddl_grant_func, |
| 118 | ddl_revoke_func, |
| 119 | ddl_create_user, |
| 120 | ddl_drop_user, |
| 121 | ddl_alter_user, |
| 122 | ddl_rename_user, |
| 123 | ddl_create_role, |
| 124 | ddl_drop_role, |
| 125 | ddl_alter_table_add_table, |
| 126 | ddl_alter_table_del_table, |
| 127 | ddl_alter_table_set_access, |
| 128 | , |
| 129 | ddl_rename_schema, |
| 130 | ddl_rename_table, |
| 131 | ddl_rename_column, |
| 132 | ddl_maxops /* evaluated to the max value, should be always kept at the bottom */ |
| 133 | } ddl_statement; |
| 134 | |
| 135 | typedef enum operator_type { |
| 136 | op_basetable = 0, |
| 137 | op_table, |
| 138 | op_ddl, |
| 139 | op_project, /* includes order by */ |
| 140 | op_select, |
| 141 | op_join, |
| 142 | op_left, |
| 143 | op_right, |
| 144 | op_full, |
| 145 | op_semi, |
| 146 | op_anti, |
| 147 | op_union, |
| 148 | op_inter, |
| 149 | op_except, |
| 150 | op_groupby, |
| 151 | op_topn, |
| 152 | op_sample, |
| 153 | op_insert, /* insert(l=table, r insert expressions) */ |
| 154 | op_update, /* update(l=table, r update expressions) */ |
| 155 | op_delete, /* delete(l=table, r delete expression) */ |
| 156 | op_truncate /* truncate(l=table) */ |
| 157 | } operator_type; |
| 158 | |
| 159 | #define is_atom(et) \ |
| 160 | (et == e_atom) |
| 161 | /* a simple atom is a literal or on the query stack */ |
| 162 | #define is_simple_atom(e) \ |
| 163 | (is_atom(e->type) && !e->r && !e->f) |
| 164 | #define is_values(e) \ |
| 165 | ((e)->type == e_atom && (e)->f) |
| 166 | #define is_func(et) \ |
| 167 | (et == e_func) |
| 168 | #define is_aggr(et) \ |
| 169 | (et == e_aggr) |
| 170 | #define is_convert(et) \ |
| 171 | (et == e_convert) |
| 172 | #define is_map_op(et) \ |
| 173 | (et == e_func || et == e_convert) |
| 174 | #define is_compare(et) \ |
| 175 | (et == e_cmp) |
| 176 | #define is_column(et) \ |
| 177 | (et != e_cmp) |
| 178 | #define is_alias(et) \ |
| 179 | (et == e_column) |
| 180 | #define is_analytic(e) \ |
| 181 | (e->type == e_func && ((sql_subfunc*)e->f)->func->type == F_ANALYTIC) |
| 182 | #define is_base(op) \ |
| 183 | (op == op_basetable || op == op_table) |
| 184 | #define is_basetable(op) \ |
| 185 | (op == op_basetable) |
| 186 | #define is_ddl(op) \ |
| 187 | (op == op_ddl) |
| 188 | #define is_outerjoin(op) \ |
| 189 | (op == op_left || op == op_right || op == op_full) |
| 190 | #define is_left(op) \ |
| 191 | (op == op_left) |
| 192 | #define is_right(op) \ |
| 193 | (op == op_right) |
| 194 | #define is_full(op) \ |
| 195 | (op == op_full) |
| 196 | #define is_join(op) \ |
| 197 | (op == op_join || is_outerjoin(op)) |
| 198 | #define is_semi(op) \ |
| 199 | (op == op_semi || op == op_anti) |
| 200 | #define is_joinop(op) \ |
| 201 | (is_join(op) || is_semi(op)) |
| 202 | #define is_select(op) \ |
| 203 | (op == op_select) |
| 204 | #define is_set(op) \ |
| 205 | (op == op_union || op == op_inter || op == op_except) |
| 206 | #define is_union(op) \ |
| 207 | (op == op_union) |
| 208 | #define is_inter(rel) \ |
| 209 | (op == op_inter) |
| 210 | #define is_except(rel) \ |
| 211 | (op == op_except) |
| 212 | #define is_simple_project(op) \ |
| 213 | (op == op_project) |
| 214 | #define is_project(op) \ |
| 215 | (op == op_project || op == op_groupby || is_set(op)) |
| 216 | #define is_groupby(op) \ |
| 217 | (op == op_groupby) |
| 218 | #define is_sort(rel) \ |
| 219 | ((rel->op == op_project && rel->r) || rel->op == op_topn) |
| 220 | #define is_topn(op) \ |
| 221 | (op == op_topn) |
| 222 | #define is_modify(op) \ |
| 223 | (op == op_insert || op == op_update || op == op_delete || op == op_truncate) |
| 224 | #define is_sample(op) \ |
| 225 | (op == op_sample) |
| 226 | #define is_insert(op) \ |
| 227 | (op == op_insert) |
| 228 | #define is_update(op) \ |
| 229 | (op == op_update) |
| 230 | #define is_delete(op) \ |
| 231 | (op == op_delete) |
| 232 | #define is_truncate(op) \ |
| 233 | (op == op_truncate) |
| 234 | |
| 235 | /* NO NIL semantics of aggr operations */ |
| 236 | #define need_no_nil(e) \ |
| 237 | ((e->flag&NO_NIL)==NO_NIL) |
| 238 | #define set_no_nil(e) \ |
| 239 | e->flag |= NO_NIL |
| 240 | |
| 241 | /* ZERO on empty sets, needed for sum (of counts)). */ |
| 242 | #define zero_if_empty(e) \ |
| 243 | ((e->flag&ZERO_IF_EMPTY)==ZERO_IF_EMPTY) |
| 244 | #define set_zero_if_empty(e) \ |
| 245 | e->flag |= ZERO_IF_EMPTY |
| 246 | |
| 247 | /* does the expression (possibly) have nils */ |
| 248 | #define has_nil(e) \ |
| 249 | (((e)->flag&HAS_NO_NIL) == 0) |
| 250 | #define set_has_no_nil(e) \ |
| 251 | (e)->flag |= HAS_NO_NIL |
| 252 | #define set_has_nil(e) \ |
| 253 | (e)->flag &= (~HAS_NO_NIL) |
| 254 | |
| 255 | #define is_ascending(e) \ |
| 256 | (((e)->flag&ASCENDING)==ASCENDING) |
| 257 | #define nulls_last(e) \ |
| 258 | (((e)->flag&NULLS_LAST)==NULLS_LAST) |
| 259 | #define set_direction(e, dir) \ |
| 260 | (e)->flag |= ((dir&1)?ASCENDING:0) | ((dir&2)?NULLS_LAST:0) |
| 261 | |
| 262 | #define is_anti(e) \ |
| 263 | ((e)->anti) |
| 264 | #define set_anti(e) \ |
| 265 | (e)->anti = 1 |
| 266 | #define is_intern(e) \ |
| 267 | ((e)->intern) |
| 268 | #define set_intern(e) \ |
| 269 | (e)->intern = 1 |
| 270 | #define is_basecol(e) \ |
| 271 | ((e)->base) |
| 272 | #define set_basecol(e) \ |
| 273 | (e)->base = 1 |
| 274 | |
| 275 | #define has_label(e) \ |
| 276 | ((e)->alias.label > 0) |
| 277 | |
| 278 | /* used for expressions and relations */ |
| 279 | #define need_distinct(e) \ |
| 280 | ((e->flag&EXP_DISTINCT)==EXP_DISTINCT) |
| 281 | #define set_distinct(e) \ |
| 282 | e->flag |= EXP_DISTINCT |
| 283 | #define set_nodistinct(e) \ |
| 284 | e->flag &= (~EXP_DISTINCT) |
| 285 | |
| 286 | #define is_processed(rel) \ |
| 287 | ((rel)->processed) |
| 288 | #define set_processed(rel) \ |
| 289 | (rel)->processed = 1 |
| 290 | #define reset_processed(rel) \ |
| 291 | (rel)->processed = 0 |
| 292 | #define is_subquery(rel) \ |
| 293 | ((rel)->subquery) |
| 294 | #define set_subquery(rel) \ |
| 295 | (rel)->subquery = 1 |
| 296 | #define reset_subquery(rel) \ |
| 297 | (rel)->subquery = 0 |
| 298 | #define is_dependent(rel) \ |
| 299 | ((rel)->dependent) |
| 300 | #define set_dependent(rel) \ |
| 301 | (rel)->dependent = 1 |
| 302 | #define reset_dependent(rel) \ |
| 303 | (rel)->dependent = 0 |
| 304 | |
| 305 | #define is_freevar(e) \ |
| 306 | ((e)->freevar) |
| 307 | #define set_freevar(e,level) \ |
| 308 | (e)->freevar = level+1 |
| 309 | #define reset_freevar(e) \ |
| 310 | (e)->freevar = 0 |
| 311 | |
| 312 | #define rel_is_ref(rel) (((sql_rel*)rel)->ref.refcnt > 1) |
| 313 | |
| 314 | typedef struct relation { |
| 315 | sql_ref ref; |
| 316 | |
| 317 | operator_type op; |
| 318 | void *l; |
| 319 | void *r; |
| 320 | list *exps; |
| 321 | int nrcols; /* nr of cols */ |
| 322 | unsigned int |
| 323 | flag:8, /* EXP_DISTINCT */ |
| 324 | card:4, /* 0, 1 (row), 2 aggr, 3 */ |
| 325 | dependent:1, /* dependent join */ |
| 326 | single:1, /* single join operator */ |
| 327 | processed:1, /* fully processed or still in the process of building */ |
| 328 | subquery:1; /* is this part a subquery, this is needed for proper name binding */ |
| 329 | void *p; /* properties for the optimizer, distribution */ |
| 330 | } sql_rel; |
| 331 | |
| 332 | #endif /* SQL_RELATION_H */ |
| 333 | |