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

Reply via email to