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