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
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to