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
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list