Changeset: adf3902d0382 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=adf3902d0382
Modified Files:
        sql/common/sql_types.c
        sql/server/rel_select.c
Branch: default
Log Message:

handle the projection case of filter functions properly.


diffs (truncated from 412 to 300 lines):

diff --git a/sql/common/sql_types.c b/sql/common/sql_types.c
--- a/sql/common/sql_types.c
+++ b/sql/common/sql_types.c
@@ -35,6 +35,7 @@ list *types = NULL;
 list *aggrs = NULL;
 list *funcs = NULL;
 
+static sql_type *BIT = NULL;
 static list *localtypes = NULL;
 
 int digits2bits(int digits) 
@@ -636,7 +637,10 @@ sql_dup_subfunc(sql_allocator *sa, sql_f
        sql_subfunc *fres = SA_ZNEW(sa, sql_subfunc);
 
        fres->func = f;
-       if (IS_FUNC(f) || IS_UNION(f) || IS_ANALYTIC(f)) { /* not needed for 
PROC/FILT */
+       if (IS_FILT(f)) {
+               fres->res = sa_list(sa);
+               list_append(fres->res, sql_bind_localtype("bit"));
+       } else if (IS_FUNC(f) || IS_UNION(f) || IS_ANALYTIC(f)) { /* not needed 
for PROC */
                unsigned int mscale = 0, mdigits = 0;
 
                if (ops) for (tn = ops->h; tn; tn = tn->next) {
@@ -710,6 +714,7 @@ sql_find_func(sql_allocator *sa, sql_sch
        int key = hash_key(sqlfname);
        sql_hash_e *he;
        int found = 0;
+       int filt = (type == F_FUNC)?F_FILT:type;
 
        assert(nrargs);
        MT_lock_set(&funcs->ht_lock);
@@ -724,7 +729,7 @@ sql_find_func(sql_allocator *sa, sql_sch
        for (; he; he = he->chain) {
                sql_func *f = he->value;
 
-               if (f->type != type) 
+               if (f->type != type && f->type != filt) 
                        continue;
                if ((fres = func_cmp(sa, f, sqlfname, nrargs )) != NULL) {
                        MT_lock_unset(&funcs->ht_lock);
@@ -754,7 +759,7 @@ sql_find_func(sql_allocator *sa, sql_sch
                                for (; he; he = he->chain) {
                                        sql_func *f = he->value;
 
-                                       if (f->type != type)
+                                       if (f->type != type && f->type != filt) 
                                                continue;
                                        if ((fres = func_cmp(sa, f, sqlfname, 
nrargs )) != NULL) {
                                                
MT_lock_unset(&s->funcs.set->ht_lock);
@@ -775,7 +780,7 @@ sql_find_func(sql_allocator *sa, sql_sch
                                for (; n; n = n->next) {
                                        sql_func *f = n->data;
 
-                                       if (f->type != type)
+                                       if (f->type != type && f->type != filt) 
                                                continue;
                                        if ((fres = func_cmp(sa, f, sqlfname, 
nrargs )) != NULL)
                                                return fres;
@@ -806,7 +811,7 @@ sql_bind_member(sql_allocator *sa, sql_s
        for (; n; n = n->next) {
                sql_func *f = n->data;
 
-               if (!f->res)
+               if (!f->res && !IS_FILT(f))
                        continue;
                if (strcmp(f->base.name, sqlfname) == 0) {
                        if (list_length(f->ops) == nrargs && is_subtypeof(tp, 
&((sql_arg *) f->ops->h->data)->type)) 
@@ -829,7 +834,7 @@ sql_bind_member(sql_allocator *sa, sql_s
                for (; n; n = n->next) {
                        sql_func *f = n->data;
 
-                       if (!f->res)
+                       if (!f->res && !IS_FILT(f))
                                continue;
                        if (strcmp(f->base.name, sqlfname) == 0) {
                                if (list_length(f->ops) == nrargs && 
is_subtypeof(tp, &((sql_arg *) f->ops->h->data)->type)) 
@@ -876,12 +881,13 @@ sql_subfunc *
 sql_bind_func_(sql_allocator *sa, sql_schema *s, const char *sqlfname, list 
*ops, int type)
 {
        node *n = funcs->h;
+       int filt = (type == F_FUNC)?F_FILT:type;
 
        (void)s;
        for (; n; n = n->next) {
                sql_func *f = n->data;
 
-               if (f->type != type) 
+               if (f->type != type && f->type != filt) 
                        continue;
                if (strcmp(f->base.name, sqlfname) == 0) {
                        if (list_cmp(f->ops, ops, (fcmp) &arg_subtype_cmp) == 
0) 
@@ -894,7 +900,7 @@ sql_bind_func_(sql_allocator *sa, sql_sc
                if (s->funcs.set) for (n=s->funcs.set->h; n; n = n->next) {
                        sql_func *f = n->data;
 
-                       if (f->type != type) 
+                       if (f->type != type && f->type != filt) 
                                continue;
                        if (strcmp(f->base.name, sqlfname) == 0) {
                                if (list_cmp(f->ops, ops, (fcmp) 
&arg_subtype_cmp) == 0) 
@@ -947,9 +953,9 @@ sql_bind_func_result_(sql_allocator *sa,
                sql_func *f = n->data;
                sql_arg *firstres = NULL;
 
-               if (!f->res)
+               if (!f->res && !IS_FILT(f))
                        continue;
-               firstres = f->res->h->data;
+               firstres = IS_FILT(f)?BIT:f->res->h->data;
                if (strcmp(f->base.name, sqlfname) == 0 && 
(is_subtype(&firstres->type, res) || firstres->type.type->eclass == EC_ANY) && 
list_cmp(f->ops, ops, (fcmp) &arg_subtype_cmp) == 0) 
                        return sql_dup_subfunc(sa, f, ops, NULL);
        }
@@ -959,9 +965,9 @@ sql_bind_func_result_(sql_allocator *sa,
                sql_func *f = n->data;
                sql_arg *firstres = NULL;
 
-               if (!f->res)
+               if (!f->res && !IS_FILT(f))
                        continue;
-               firstres = f->res->h->data;
+               firstres = IS_FILT(f)?BIT:f->res->h->data;
                if (strcmp(f->base.name, sqlfname) == 0 && 
(is_subtype(&firstres->type, res) || firstres->type.type->eclass == EC_ANY) && 
list_cmp(f->ops, ops, (fcmp) &arg_subtype_cmp) == 0) 
                        return sql_dup_subfunc(sa, f, ops, NULL);
        }
@@ -1235,7 +1241,7 @@ sqltypeinit( sql_allocator *sa)
        sql_type *ts[100];
        sql_type **strings, **numerical;
        sql_type **decimals, **floats, **dates, **end, **t;
-       sql_type *STR, *BTE, *SHT, *INT, *LNG, *OID, *BIT, *FLT, *DBL, *DEC;
+       sql_type *STR, *BTE, *SHT, *INT, *LNG, *OID, *FLT, *DBL, *DEC;
        sql_type *WRD;
 #ifdef HAVE_HGE
        sql_type *HGE = NULL;
@@ -1707,14 +1713,17 @@ sqltypeinit( sql_allocator *sa)
                sql_create_func3(sa, "substring", "str", "substring", *t, INT, 
INT, *t, INOUT);
                sql_create_func(sa, "substr", "str", "substring", *t, INT, *t, 
INOUT);
                sql_create_func3(sa, "substr", "str", "substring", *t, INT, 
INT, *t, INOUT);
+               /*
                sql_create_func(sa, "like", "algebra", "like", *t, *t, BIT, 
SCALE_NONE);
                sql_create_func3(sa, "like", "algebra", "like", *t, *t, *t, 
BIT, SCALE_NONE);
                sql_create_func(sa, "ilike", "algebra", "ilike", *t, *t, BIT, 
SCALE_NONE);
                sql_create_func3(sa, "ilike", "algebra", "ilike", *t, *t, *t, 
BIT, SCALE_NONE);
+               */
                sql_create_func(sa, "not_like", "algebra", "not_like", *t, *t, 
BIT, SCALE_NONE);
                sql_create_func3(sa, "not_like", "algebra", "not_like", *t, *t, 
*t, BIT, SCALE_NONE);
                sql_create_func(sa, "not_ilike", "algebra", "not_ilike", *t, 
*t, BIT, SCALE_NONE);
                sql_create_func3(sa, "not_ilike", "algebra", "not_ilike", *t, 
*t, *t, BIT, SCALE_NONE);
+
                sql_create_func(sa, "patindex", "pcre", "patindex", *t, *t, 
INT, SCALE_NONE);
                sql_create_func(sa, "truncate", "str", "stringleft", *t, INT, 
*t, SCALE_NONE);
                sql_create_func(sa, "concat", "calc", "+", *t, *t, *t, 
DIGITS_ADD);
diff --git a/sql/server/rel_select.c b/sql/server/rel_select.c
--- a/sql/server/rel_select.c
+++ b/sql/server/rel_select.c
@@ -25,7 +25,7 @@
 #include "mal.h"               /* for have_hge */
 #endif
 
-#define check_card(card,f) ((card == card_none && !f->res) || (card != 
card_none && f->res) || card == card_loader)
+#define check_card(card,f) ((card == card_none && !f->res) || (card != 
card_none && (f->res || f->func->type == F_FILT)) || card == card_loader)
 
 static void
 rel_setsubquery(sql_rel*r)
@@ -1739,6 +1739,94 @@ rel_compare(mvc *sql, sql_rel *rel, symb
        return rel_compare_exp(sql, rel, ls, rs, compare_op, rs2, k.reduce);
 }
 
+static sql_exp*
+_rel_nop( mvc *sql, sql_schema *s, char *fname, list *tl, list *exps, 
sql_subtype *obj_type, int nr_args, exp_kind ek)
+{
+       sql_subfunc *f = NULL;
+       int table_func = (ek.card == card_relation);
+       int type = (ek.card == card_loader)?F_LOADER:((ek.card == 
card_none)?F_PROC:
+                  ((ek.card == card_relation)?F_UNION:F_FUNC));
+       int filt = (type == F_FUNC)?F_FILT:type;
+
+       f = bind_func_(sql, s, fname, tl, type);
+       if (f) {
+               return exp_op(sql->sa, exps, f);
+       } else if (obj_type && (f = bind_member_func(sql, s, fname, obj_type, 
nr_args, NULL)) != NULL) { 
+               sql_subfunc *prev = NULL;
+               node *n, *m;
+               list *nexps;
+
+               while((f = bind_member_func(sql, s, fname, obj_type, nr_args, 
prev)) != NULL) { 
+                       prev = f;
+                       if (f->func->type != type && f->func->type != filt)
+                               continue;
+                       if (f->func->vararg) 
+                               return exp_op(sql->sa, exps, f);
+                       nexps = new_exp_list(sql->sa);
+                       for (n = exps->h, m = f->func->ops->h; n && m;
+                                       n = n->next, m = m->next) {
+                               sql_arg *a = m->data;
+                               sql_exp *e = n->data;
+
+                               if (a->type.type->eclass == EC_ANY) {
+                                       sql_subtype *st = &e->tpe;
+                                       sql_init_subtype(&a->type, st->type, 
st->digits, st->scale);
+                               }
+                               e = rel_check_type(sql, &a->type, e, 
type_equal);
+                               if (!e) {
+                                       nexps = NULL;
+                                       break;
+                               }
+                               if (table_func && e->card > CARD_ATOM) {
+                                       sql_subaggr *zero_or_one = 
sql_bind_aggr(sql->sa, sql->session->schema, "zero_or_one", exp_subtype(e));
+
+                                       e = exp_aggr1(sql->sa, e, zero_or_one, 
0, 0, CARD_ATOM, 0);
+                               }
+                               append(nexps, e);
+                       }
+                       if (nexps) 
+                               return exp_op(sql->sa, nexps, f);
+               }
+       } else if ((f = find_func(sql, s, fname, nr_args, type, NULL)) != NULL) 
{
+               sql_subfunc *prev = NULL;
+               node *n, *m;
+               list *nexps;
+
+               while((f = find_func(sql, s, fname, nr_args, type, prev)) != 
NULL) { 
+                       prev = f;
+                       if (f->func->type != type && f->func->type != filt)
+                               continue;
+                       if (f->func->vararg) 
+                               return exp_op(sql->sa, exps, f);
+                       nexps = new_exp_list(sql->sa);
+                       for (n = exps->h, m = f->func->ops->h; n && m;
+                               n = n->next, m = m->next) {
+                               sql_arg *a = m->data;
+                               sql_exp *e = n->data;
+
+                               if (a->type.type->eclass == EC_ANY) {
+                                       sql_subtype *st = &e->tpe;
+                                       sql_init_subtype(&a->type, st->type, 
st->digits, st->scale);
+                               }
+                               e = rel_check_type(sql, &a->type, e, 
type_equal);
+                               if (!e) {
+                                       nexps = NULL;
+                                       break;
+                               }
+                               if (table_func && e->card > CARD_ATOM) {
+                                       sql_subaggr *zero_or_one = 
sql_bind_aggr(sql->sa, sql->session->schema, "zero_or_one", exp_subtype(e));
+       
+                                       e = exp_aggr1(sql->sa, e, zero_or_one, 
0, 0, CARD_ATOM, 0);
+                               }
+                               append(nexps, e);
+                       }
+                       if (nexps) 
+                               return exp_op(sql->sa, nexps, f);
+               }
+       }
+       return sql_error(sql, 02, "SELECT: no such operator '%s'", fname);
+}
+
 sql_exp *
 rel_logical_value_exp(mvc *sql, sql_rel **rel, symbol *sc, int f)
 {
@@ -1767,6 +1855,48 @@ rel_logical_value_exp(mvc *sql, sql_rel 
                else
                        return rel_binop_(sql, ls, rs, NULL, "and", card_value);
        }
+       case SQL_FILTER:
+               /* [ x,..] filter [ y,..] */
+               /* todo add anti, [ x,..] not filter [ y,...] */
+               /* no correlation */
+       {
+               dnode *ln = sc->data.lval->h->data.lval->h;
+               dnode *rn = sc->data.lval->h->next->next->data.lval->h;
+               dlist *filter_op = sc->data.lval->h->next->data.lval;
+               char *fname = qname_fname(filter_op);
+               char *sname = qname_schema(filter_op);
+               list *exps, *tl;
+               sql_schema *s = sql->session->schema;
+               sql_subtype *obj_type = NULL;
+
+               if (sname)
+                       s = mvc_bind_schema(sql, sname);
+
+               exps = sa_list(sql->sa);
+               tl = sa_list(sql->sa);
+               for (; ln; ln = ln->next) {
+                       symbol *sym = ln->data.sym;
+
+                       sql_exp *e = rel_value_exp(sql, rel, sym, f, ek);
+                       if (!e)
+                               return NULL;
+                       if (!obj_type)
+                               obj_type = exp_subtype(e);
+                       list_append(exps, e);
+                       append(tl, exp_subtype(e));
+               }
+               for (; rn; rn = rn->next) {
+                       symbol *sym = rn->data.sym;
+
+                       sql_exp *e = rel_value_exp(sql, rel, sym, f, ek);
+                       if (!e)
+                               return NULL;
+                       list_append(exps, e);
+                       append(tl, exp_subtype(e));
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to