Changeset: fd16ecb2cf0a for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/fd16ecb2cf0a Modified Files: clients/Tests/MAL-signatures-hge.test clients/Tests/MAL-signatures.test sql/backends/monet5/rel_bin.c sql/backends/monet5/sql.c sql/scripts/76_dump.sql sql/server/rel_dump.c sql/server/rel_dump.h sql/server/rel_schema.c Branch: label Log Message:
only dump check expression added v1 of exp2sql to be used via select check_constraint('schema', 'constraint name'); diffs (truncated from 388 to 300 lines): diff --git a/clients/Tests/MAL-signatures-hge.test b/clients/Tests/MAL-signatures-hge.test --- a/clients/Tests/MAL-signatures-hge.test +++ b/clients/Tests/MAL-signatures-hge.test @@ -48969,6 +48969,11 @@ pattern sql.bind_idxbat(X_0:int, X_1:str mvc_bind_idxbat_wrap; Bind the 'schema.table.index' BAT with access kind:@0 - base table@1 - inserts@2 - updates sql +check +pattern sql.check(X_0:str, X_1:str):str +SQLcheck; +Return sql string of check constraint. +sql claim unsafe pattern sql.claim(X_0:int, X_1:str, X_2:str, X_3:lng) (X_4:oid, X_5:bat[:oid]) mvc_claim_wrap; diff --git a/clients/Tests/MAL-signatures.test b/clients/Tests/MAL-signatures.test --- a/clients/Tests/MAL-signatures.test +++ b/clients/Tests/MAL-signatures.test @@ -37429,6 +37429,11 @@ pattern sql.bind_idxbat(X_0:int, X_1:str mvc_bind_idxbat_wrap; Bind the 'schema.table.index' BAT with access kind:@0 - base table@1 - inserts@2 - updates sql +check +pattern sql.check(X_0:str, X_1:str):str +SQLcheck; +Return sql string of check constraint. +sql claim unsafe pattern sql.claim(X_0:int, X_1:str, X_2:str, X_3:lng) (X_4:oid, X_5:bat[:oid]) mvc_claim_wrap; diff --git a/sql/backends/monet5/rel_bin.c b/sql/backends/monet5/rel_bin.c --- a/sql/backends/monet5/rel_bin.c +++ b/sql/backends/monet5/rel_bin.c @@ -5143,25 +5143,22 @@ sql_insert_check(backend *be, sql_key *k { mvc *sql = be->mvc; int pos = 0; - sql_rel* rel = rel_read(sql, sa_strdup(sql->sa, key->check), &pos, sa_list(sql->sa)), *br = rel->l; - - assert(is_basetable(br->op)); + sql_rel *rel = rel_basetable(sql, key->t, key->t->base.name); + sql_exp *exp = exp_read(sql, rel, NULL, NULL, sa_strdup(sql->sa, key->check), &pos, 0); + rel->exps = rel_base_projection(sql, rel, 0); + /* create new sub stmt with needed inserts */ list *ins = sa_list(sql->sa); for(node *n = key->columns->h; n; n = n->next) { sql_kc *kc = n->data; stmt *in = list_fetch(inserts, kc->c->colnr); - sql_exp *e = rel_base_bind_column2(sql, br, kc->c->t->base.name, kc->c->base.name); + sql_exp *e = rel_base_bind_column2(sql, rel, kc->c->t->base.name, kc->c->base.name); in = stmt_alias(be, in, e->alias.label, kc->c->t->base.name, kc->c->base.name); append(ins, in); } stmt *sub = stmt_list(be, ins); - /* TODO: need exp here */ - assert(list_length(rel->exps) == 1); - sql_exp *e = rel->exps->h->data; - stmt *s = exp_bin(be, e, sub, NULL, NULL, NULL, NULL, NULL, 0, 0, 0); - + stmt *s = exp_bin(be, exp, sub, NULL, NULL, NULL, NULL, NULL, 0, 0, 0); sql_subfunc *cnt = sql_bind_func(sql, "sys", "count", sql_bind_localtype("void"), NULL, F_AGGR, true, true); s = stmt_uselect(be, column(be, s), stmt_bool(be, 0), cmp_equal, NULL, 0, 1); s = stmt_aggr(be, s, NULL, NULL, cnt, 1, 0, 1); @@ -6159,22 +6156,9 @@ sql_update_check(backend *be, stmt **upd { mvc *sql = be->mvc; int pos = 0; - sql_rel *rel = NULL; - - if (key->t->persistence == SQL_DECLARED_TABLE) { - stack_push_frame(be->mvc, "ALTER TABLE ADD CONSTRAINT CHECK"); - sql_schema* ss = key->t->s; - frame_push_table(sql, key->t); - key->t->s = ss; // recover the schema because frame_push_table removes it - - rel = rel_read(sql, sa_strdup(sql->sa, key->check), &pos, sa_list(sql->sa)); - stack_pop_frame(sql); - } else { - rel = rel_read(sql, sa_strdup(sql->sa, key->check), &pos, sa_list(sql->sa)); - } - - sql_rel *br = rel->l; - assert(is_basetable(br->op)); + sql_rel *rel = rel_basetable(sql, key->t, key->t->base.name); + sql_exp *exp = exp_read(sql, rel, NULL, NULL, sa_strdup(sql->sa, key->check), &pos, 0); + rel->exps = rel_base_projection(sql, rel, 0); /* create sub stmt with needed updates (or projected col from to be updated table) */ list *ups = sa_list(sql->sa); @@ -6187,16 +6171,13 @@ sql_update_check(backend *be, stmt **upd } else { upd = stmt_col(be, kc->c, u_tids, u_tids->partition); } - sql_exp *e = rel_base_bind_column2(sql, br, kc->c->t->base.name, kc->c->base.name); + sql_exp *e = rel_base_bind_column2(sql, rel, kc->c->t->base.name, kc->c->base.name); upd = stmt_alias(be, upd, e->alias.label, kc->c->t->base.name, kc->c->base.name); append(ups, upd); } stmt *sub = stmt_list(be, ups); - /* TODO: need exp here */ - assert(list_length(rel->exps) == 1); - sql_exp *e = rel->exps->h->data; - stmt *s = exp_bin(be, e, sub, NULL, NULL, NULL, NULL, NULL, 0, 0, 0); + stmt *s = exp_bin(be, exp, sub, NULL, NULL, NULL, NULL, NULL, 0, 0, 0); sql_subfunc *cnt = sql_bind_func(sql, "sys", "count", sql_bind_localtype("void"), NULL, F_AGGR, true, true); s = stmt_uselect(be, column(be, s), stmt_bool(be, 0), cmp_equal, NULL, 0, 1); diff --git a/sql/backends/monet5/sql.c b/sql/backends/monet5/sql.c --- a/sql/backends/monet5/sql.c +++ b/sql/backends/monet5/sql.c @@ -26,8 +26,10 @@ #include "store_sequence.h" #include "sql_partition.h" #include "rel_partition.h" +#include "rel_basetable.h" #include "rel_rel.h" #include "rel_exp.h" +#include "rel_dump.h" #include "rel_physical.h" #include "mal.h" #include "mal_client.h" @@ -5241,6 +5243,33 @@ SQLdecypher(Client cntxt, MalBlkPtr mb, return AUTHdecypherValue(pwhash, cypher); } +static str +SQLcheck(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) +{ + mvc *m = NULL; + str msg = NULL; + str *r = getArgReference_str(stk, pci, 0); + const char *sname = *getArgReference_str(stk, pci, 1); + const char *cname = *getArgReference_str(stk, pci, 2); + + if ((msg = getSQLContext(cntxt, mb, &m, NULL)) != NULL) + return msg; + if ((msg = checkSQLContext(cntxt)) != NULL) + return msg; + (void)sname; + sql_schema *s = mvc_bind_schema(m, sname); + if (s) { + sql_key *k = mvc_bind_key(m, s, cname); + if (k->check) { + int pos = 0; + sql_rel *rel = rel_basetable(m, k->t, k->t->base.name); + sql_exp *exp = exp_read(m, rel, NULL, NULL, sa_strdup(m->sa, k->check), &pos, 0); + *r = GDKstrdup(exp2sql(m, exp)); + } + } + return MAL_SUCCEED; +} + static mel_func sql_init_funcs[] = { pattern("sql", "shutdown", SQLshutdown_wrap, true, "", args(1,3, arg("",str),arg("delay",bte),arg("force",bit))), pattern("sql", "shutdown", SQLshutdown_wrap, true, "", args(1,3, arg("",str),arg("delay",sht),arg("force",bit))), @@ -6168,6 +6197,7 @@ static mel_func sql_init_funcs[] = { pattern("sql", "vacuum", SQLstr_column_vacuum, true, "vacuum a string column", args(0,3, arg("sname",str),arg("tname",str),arg("cname",str))), pattern("sql", "vacuum", SQLstr_column_auto_vacuum, true, "auto vacuum string column with interval(sec)", args(0,4, arg("sname",str),arg("tname",str),arg("cname",str),arg("interval", int))), pattern("sql", "stop_vacuum", SQLstr_column_stop_vacuum, true, "stop auto vacuum", args(0,3, arg("sname",str),arg("tname",str),arg("cname",str))), + pattern("sql", "check", SQLcheck, false, "Return sql string of check constraint.", args(1,3, arg("sql",str), arg("sname", str), arg("name", str))), { .imp=NULL } }; #include "mal_import.h" diff --git a/sql/scripts/76_dump.sql b/sql/scripts/76_dump.sql --- a/sql/scripts/76_dump.sql +++ b/sql/scripts/76_dump.sql @@ -361,3 +361,6 @@ BEGIN RETURN sys.dump_statements; END; + +CREATE FUNCTION check_constraint(sname STRING, cname STRING) RETURNS STRING EXTERNAL NAME sql."check"; +grant execute on function check_constraint to public; 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 @@ -923,8 +923,6 @@ readAtomString(int localtype, char *r, i return res; } -static sql_exp* exp_read(mvc *sql, sql_rel *lrel, sql_rel *rrel, list *top_exps, char *r, int *pos, int grp); - static sql_exp* read_prop(mvc *sql, sql_exp *exp, char *r, int *pos, bool *found) { @@ -1168,7 +1166,7 @@ try_update_label_count(mvc *sql, const c return 0; } -static sql_exp* +sql_exp* exp_read(mvc *sql, sql_rel *lrel, sql_rel *rrel, list *top_exps, char *r, int *pos, int grp) { int old, d=0, s=0, unique = 0, no_nils = 0, quote = 0, zero_if_empty = 0; @@ -1856,7 +1854,7 @@ read_rel_properties(mvc *sql, sql_rel *r sql_rel* rel_read(mvc *sql, char *r, int *pos, list *refs) { - sql_rel *rel = NULL, *nrel, *lrel, *rrel; + sql_rel *rel = NULL, *nrel, *lrel, *rrel = NULL; list *exps, *gexps, *rels = NULL; int distinct = 0, dependent = 0, single = 0; operator_type j = op_basetable; @@ -2508,3 +2506,92 @@ rel_read(mvc *sql, char *r, int *pos, li return NULL; return rel; } + +static bool +is_infix(sql_func *f) +{ + if (strlen(f->base.name) == 1) { + return true; + } else if (strlen(f->base.name) == 2) { + if (f->base.name[0] == '<' && f->base.name[1] == '>') + return true; + if (f->base.name[0] == '<' && f->base.name[1] == '=') + return true; + if (f->base.name[0] == '>' && f->base.name[1] == '=') + return true; + if (f->base.name[0] == '|' && f->base.name[1] == '|') + return true; + } + return false; +} + +/* only simple expressions, ie recursive no psm */ +static void +exp2sql_print(mvc *sql, stream *fout, sql_exp *e) +{ + switch (e->type) { + case e_func: { + sql_subfunc *sf = e->f; + list *args = e->l; + if (list_length(args) == 2 && is_infix(sf->func)) { + exp2sql_print(sql, fout, args->h->data); + mnstr_printf(fout, " %s ", sf->func->base.name); + exp2sql_print(sql, fout, args->h->next->data); + } else { + mnstr_printf(fout, "%s(", sf->func->base.name); + if (args) + for (node *n = args->h; n; n = n->next) { + exp2sql_print(sql, fout, n->data); + if (n->next) + mnstr_printf(fout, ", "); + } + mnstr_printf(fout, ")"); + } + } break; + case e_column: + mnstr_printf(fout, "%s", exp_name(e)); + break; + case e_convert: + mnstr_printf(fout, "CAST (" ); + exp2sql_print(sql, fout, e->l); + mnstr_printf(fout, "AS %s)", sql_subtype_string(sql->sa, exp_subtype(e))); + break; + case e_atom: + mnstr_printf(fout, "%s", atom2sql(sql->sa, e->l, 0)); + break; + case e_aggr: /* fall-through */ + case e_cmp: /* fall-through */ + case e_psm: + assert(0); + break; + } +} + +char * +exp2sql( mvc *sql, sql_exp *exp) +{ + buffer *b = NULL; + stream *s = NULL; + char *res = NULL; + + b = buffer_create(1024); + if(b == NULL) + goto cleanup; + s = buffer_wastream(b, "exp_dump"); + if(s == NULL) + goto cleanup; + + exp2sql_print(sql, s, exp); + + res = buffer_get_buf(b); + +cleanup: + if(b) + buffer_destroy(b); + if(s) + close_stream(s); + + char* fres = SA_STRDUP(sql->sa, res); + free (res); + return fres; +} diff --git a/sql/server/rel_dump.h b/sql/server/rel_dump.h _______________________________________________ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org