Changeset: c7f95c571a1b for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=c7f95c571a1b
Modified Files:
sql/include/sql_catalog.h
sql/include/sql_relation.h
sql/server/rel_dump.c
sql/server/rel_exp.c
sql/server/rel_optimizer.c
sql/server/rel_rel.c
sql/server/rel_select.c
sql/server/rel_unnest.c
sql/server/sql_semantic.c
Branch: default
Log Message:
use 2 more bit field fields for ascending and nulls_last
diffs (truncated from 502 to 300 lines):
diff --git a/sql/include/sql_catalog.h b/sql/include/sql_catalog.h
--- a/sql/include/sql_catalog.h
+++ b/sql/include/sql_catalog.h
@@ -184,7 +184,7 @@ typedef enum comp_type {
#define is_theta_exp(e) ((e) == cmp_gt || (e) == cmp_gte || (e) == cmp_lte ||\
(e) == cmp_lt || (e) == cmp_equal || (e) ==
cmp_notequal)
-#define is_complex_exp(e) ((e&CMPMASK) == cmp_or || (e) == cmp_in || (e) ==
cmp_notin || (e&CMPMASK) == cmp_filter)
+#define is_complex_exp(et) ((et) == cmp_or || (et) == cmp_in || (et) ==
cmp_notin || (et) == cmp_filter)
typedef enum commit_action_t {
CA_COMMIT, /* commit rows, only for persistent tables */
diff --git a/sql/include/sql_relation.h b/sql/include/sql_relation.h
--- a/sql/include/sql_relation.h
+++ b/sql/include/sql_relation.h
@@ -38,31 +38,30 @@ typedef struct expression {
void *r;
void *f; /* func's and aggr's, also e_cmp may have have 2
arguments */
unsigned int
- flag:18, /* EXP_DISTINCT, NO_NIL, ASCENDING, NULLS_LAST, cmp
types */
+ flag:20, /* EXP_DISTINCT, NO_NIL, cmp types */
card:2, /* card (0 truth value!) (1 atoms) (2 aggr) (3 multi
value) */
freevar:4, /* free variable, ie binds to the upper dependent join
*/
intern:1,
anti:1,
+ ascending:1, /* order direction */
+ nulls_last:1, /* return null after all other rows */
base:1,
used:1; /* used for quick dead code removal */
sql_subtype tpe;
void *p; /* properties for the optimizer */
} sql_exp;
-#define EXP_DISTINCT 1
-#define NO_NIL 2
-#define LEFT_JOIN 4
-#define ZERO_IF_EMPTY 8
+/* cannot be combined with cmp_* or PSM flags */
+#define EXP_DISTINCT 1 /* used for both expressions and
relations */
+#define NO_NIL 2
+#define LEFT_JOIN 4 /* relational flag */
+#define ZERO_IF_EMPTY 8 /* in case of partial aggregator
computation, some aggregators need to return 0 instead of NULL */
+#define HAS_NO_NIL 16
-/* ASCENDING > 15 else we have problems with cmp types */
-#define ASCENDING 16
-#define CMPMASK (ASCENDING-1)
-#define get_cmp(e) (e->flag&CMPMASK)
-#define HAS_NO_NIL 32
-#define NULLS_LAST 64
+#define get_cmp(e) (e->flag)
-#define UPD_COMP 1
-#define UPD_LOCKED 2
+#define UPD_COMP 1
+#define UPD_LOCKED 2
#define UPD_NO_CONSTRAINT 4
#define REL_PARTITION 8
@@ -153,81 +152,45 @@ typedef enum operator_type {
op_truncate /* truncate(l=table) */
} operator_type;
-#define is_atom(et) \
- (et == e_atom)
+#define is_atom(et) (et == e_atom)
/* a simple atom is a literal or on the query stack */
-#define is_simple_atom(e) \
- (is_atom(e->type) && !e->r && !e->f)
-#define is_values(e) \
- ((e)->type == e_atom && (e)->f)
-#define is_func(et) \
- (et == e_func)
-#define is_aggr(et) \
- (et == e_aggr)
-#define is_convert(et) \
- (et == e_convert)
-#define is_map_op(et) \
- (et == e_func || et == e_convert)
-#define is_compare(et) \
- (et == e_cmp)
-#define is_column(et) \
- (et != e_cmp)
-#define is_alias(et) \
- (et == e_column)
-#define is_analytic(e) \
- (e->type == e_func && ((sql_subfunc*)e->f)->func->type == F_ANALYTIC)
-#define is_base(op) \
- (op == op_basetable || op == op_table)
-#define is_basetable(op) \
- (op == op_basetable)
-#define is_ddl(op) \
- (op == op_ddl)
-#define is_outerjoin(op) \
- (op == op_left || op == op_right || op == op_full)
-#define is_left(op) \
- (op == op_left)
-#define is_right(op) \
- (op == op_right)
-#define is_full(op) \
- (op == op_full)
-#define is_join(op) \
- (op == op_join || is_outerjoin(op))
-#define is_semi(op) \
- (op == op_semi || op == op_anti)
-#define is_joinop(op) \
- (is_join(op) || is_semi(op))
-#define is_select(op) \
- (op == op_select)
-#define is_set(op) \
- (op == op_union || op == op_inter || op == op_except)
-#define is_union(op) \
- (op == op_union)
-#define is_inter(rel) \
- (op == op_inter)
-#define is_except(rel) \
- (op == op_except)
-#define is_simple_project(op) \
- (op == op_project)
-#define is_project(op) \
- (op == op_project || op == op_groupby || is_set(op))
-#define is_groupby(op) \
- (op == op_groupby)
-#define is_sort(rel) \
- ((rel->op == op_project && rel->r) || rel->op == op_topn)
-#define is_topn(op) \
- (op == op_topn)
-#define is_modify(op) \
- (op == op_insert || op == op_update || op == op_delete || op ==
op_truncate)
-#define is_sample(op) \
- (op == op_sample)
-#define is_insert(op) \
- (op == op_insert)
-#define is_update(op) \
- (op == op_update)
-#define is_delete(op) \
- (op == op_delete)
-#define is_truncate(op) \
- (op == op_truncate)
+#define is_simple_atom(e) (is_atom(e->type) && !e->r && !e->f)
+#define is_values(e) ((e)->type == e_atom && (e)->f)
+#define is_func(et) (et == e_func)
+#define is_aggr(et) (et == e_aggr)
+#define is_convert(et) (et == e_convert)
+#define is_map_op(et) (et == e_func || et == e_convert)
+#define is_compare(et) (et == e_cmp)
+#define is_column(et) (et != e_cmp)
+#define is_alias(et) (et == e_column)
+#define is_analytic(e) (e->type == e_func &&
((sql_subfunc*)e->f)->func->type == F_ANALYTIC)
+
+#define is_base(op) (op == op_basetable || op == op_table)
+#define is_basetable(op) (op == op_basetable)
+#define is_ddl(op) (op == op_ddl)
+#define is_outerjoin(op) (op == op_left || op == op_right || op ==
op_full)
+#define is_left(op) (op == op_left)
+#define is_right(op) (op == op_right)
+#define is_full(op) (op == op_full)
+#define is_join(op) (op == op_join || is_outerjoin(op))
+#define is_semi(op) (op == op_semi || op == op_anti)
+#define is_joinop(op) (is_join(op) || is_semi(op))
+#define is_select(op) (op == op_select)
+#define is_set(op) (op == op_union || op == op_inter || op ==
op_except)
+#define is_union(op) (op == op_union)
+#define is_inter(rel) (op == op_inter)
+#define is_except(rel) (op == op_except)
+#define is_simple_project(op) (op == op_project)
+#define is_project(op) (op == op_project || op == op_groupby
|| is_set(op))
+#define is_groupby(op) (op == op_groupby)
+#define is_sort(rel) ((rel->op == op_project && rel->r) || rel->op
== op_topn)
+#define is_topn(op) (op == op_topn)
+#define is_modify(op) (op == op_insert || op == op_update || op ==
op_delete || op == op_truncate)
+#define is_sample(op) (op == op_sample)
+#define is_insert(op) (op == op_insert)
+#define is_update(op) (op == op_update)
+#define is_delete(op) (op == op_delete)
+#define is_truncate(op) (op == op_truncate)
/* NO NIL semantics of aggr operations */
#define need_no_nil(e) \
@@ -249,28 +212,22 @@ typedef enum operator_type {
#define set_has_nil(e) \
(e)->flag &= (~HAS_NO_NIL)
-#define is_ascending(e) \
- (((e)->flag&ASCENDING)==ASCENDING)
-#define nulls_last(e) \
- (((e)->flag&NULLS_LAST)==NULLS_LAST)
-#define set_direction(e, dir) \
- (e)->flag |= ((dir&1)?ASCENDING:0) | ((dir&2)?NULLS_LAST:0)
+#define is_ascending(e) ((e)->ascending)
+#define set_ascending(e) ((e)->ascending = 1)
+#define set_descending(e) ((e)->ascending = 0)
+#define nulls_last(e) ((e)->nulls_last)
+#define set_nulls_last(e) ((e)->nulls_last=1)
+#define set_nulls_first(e) ((e)->nulls_last=0)
+#define set_direction(e, dir) ((e)->ascending = (dir&1), (e)->nulls_last =
(dir&2)?1:0)
-#define is_anti(e) \
- ((e)->anti)
-#define set_anti(e) \
- (e)->anti = 1
-#define is_intern(e) \
- ((e)->intern)
-#define set_intern(e) \
- (e)->intern = 1
-#define is_basecol(e) \
- ((e)->base)
-#define set_basecol(e) \
- (e)->base = 1
+#define is_anti(e) ((e)->anti)
+#define set_anti(e) (e)->anti = 1
+#define is_intern(e) ((e)->intern)
+#define set_intern(e) (e)->intern = 1
+#define is_basecol(e) ((e)->base)
+#define set_basecol(e) (e)->base = 1
-#define has_label(e) \
- ((e)->alias.label > 0)
+#define has_label(e) ((e)->alias.label > 0)
/* used for expressions and relations */
#define need_distinct(e) \
@@ -280,31 +237,19 @@ typedef enum operator_type {
#define set_nodistinct(e) \
e->flag &= (~EXP_DISTINCT)
-#define is_processed(rel) \
- ((rel)->processed)
-#define set_processed(rel) \
- (rel)->processed = 1
-#define reset_processed(rel) \
- (rel)->processed = 0
-#define is_subquery(rel) \
- ((rel)->subquery)
-#define set_subquery(rel) \
- (rel)->subquery = 1
-#define reset_subquery(rel) \
- (rel)->subquery = 0
-#define is_dependent(rel) \
- ((rel)->dependent)
-#define set_dependent(rel) \
- (rel)->dependent = 1
-#define reset_dependent(rel) \
- (rel)->dependent = 0
+#define is_processed(rel) ((rel)->processed)
+#define set_processed(rel) (rel)->processed = 1
+#define reset_processed(rel) (rel)->processed = 0
+#define is_subquery(rel) ((rel)->subquery)
+#define set_subquery(rel) (rel)->subquery = 1
+#define reset_subquery(rel) (rel)->subquery = 0
+#define is_dependent(rel) ((rel)->dependent)
+#define set_dependent(rel) (rel)->dependent = 1
+#define reset_dependent(rel) (rel)->dependent = 0
-#define is_freevar(e) \
- ((e)->freevar)
-#define set_freevar(e,level) \
- (e)->freevar = level+1
-#define reset_freevar(e) \
- (e)->freevar = 0
+#define is_freevar(e) ((e)->freevar)
+#define set_freevar(e,level) (e)->freevar = level+1
+#define reset_freevar(e) (e)->freevar = 0
#define rel_is_ref(rel) (((sql_rel*)rel)->ref.refcnt > 1)
diff --git a/sql/server/rel_dump.c b/sql/server/rel_dump.c
--- a/sql/server/rel_dump.c
+++ b/sql/server/rel_dump.c
@@ -253,6 +253,8 @@ exp_print(mvc *sql, stream *fout, sql_ex
}
if (e->type != e_atom && e->type != e_cmp && is_ascending(e))
mnstr_printf(fout, " ASC");
+ if (e->type != e_atom && e->type != e_cmp && nulls_last(e))
+ mnstr_printf(fout, " NULLS LAST");
if (e->type != e_atom && e->type != e_cmp && !has_nil(e))
mnstr_printf(fout, " NOT NULL");
/*
@@ -1084,7 +1086,13 @@ exp_read(mvc *sql, sql_rel *lrel, sql_re
if (strncmp(r+*pos, "ASC", strlen("ASC")) == 0) {
(*pos)+= (int) strlen("ASC");
skipWS(r, pos);
- set_direction(exp, 1);
+ set_ascending(exp);
+ }
+ /* [ NULLS LAST ] */
+ if (strncmp(r+*pos, "NULLS LAST", strlen("NULLS LAST")) == 0) {
+ (*pos)+= (int) strlen("NULLS LAST");
+ skipWS(r, pos);
+ set_nulls_last(exp);
}
/* [ ANY|ALL ] */
if (strncmp(r+*pos, "ANY", strlen("ANY")) == 0) {
diff --git a/sql/server/rel_exp.c b/sql/server/rel_exp.c
--- a/sql/server/rel_exp.c
+++ b/sql/server/rel_exp.c
@@ -120,6 +120,8 @@ exp_create(sql_allocator *sa, int type )
e->freevar = 0;
e->intern = 0;
e->anti = 0;
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list