Changeset: 41911d3ea79a for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/41911d3ea79a
Modified Files:
        sql/backends/monet5/rel_bin.c
        sql/backends/monet5/sql_scenario.c
        sql/server/rel_select.c
        sql/server/rel_semantic.c
        sql/server/sql_parser.y
Branch: default
Log Message:

add after a query an optional parameter list via : (p0, ... pn)


diffs (261 lines):

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
@@ -826,6 +826,41 @@ exp2bin_case(backend *be, sql_exp *fe, s
 }
 
 static stmt *
+exp2bin_named_placeholders(backend *be, sql_exp *fe)
+{
+       int argc = 0;
+       char arg[IDLENGTH];
+       list *args = fe->l;
+
+       if (list_empty(args))
+               return NULL;
+       for (node *n = args->h; n; n = n->next, argc++) {
+               sql_exp *a = n->data;
+               sql_subtype *t = exp_subtype(a);
+               stmt *s = exp_bin(be, a, NULL, NULL, NULL, NULL, NULL, NULL, 1, 
0, 1);
+               InstrPtr q = newAssignment(be->mb);
+
+               if (!q || !t || !s) {
+            sql_error(be->mvc, 10, SQLSTATE(42000) MAL_MALLOC_FAIL);
+                       return NULL;
+               }
+        int type = t->type->localtype, varid = 0;
+
+        snprintf(arg, IDLENGTH, "A%d", argc);
+        if ((varid = newVariable(be->mb, arg, strlen(arg), type)) < 0) {
+            sql_error(be->mvc, 10, SQLSTATE(42000) "Internal error while 
compiling statement: variable id too long");
+                       return NULL;
+        }
+               if (q)
+                       getDestVar(q) = varid;
+        q = pushArgument(be->mb, q, s->nr);
+               pushInstruction(be->mb, q);
+        //setVarType(be->mb, varid, type);
+       }
+       return NULL;
+}
+
+static stmt *
 exp2bin_casewhen(backend *be, sql_exp *fe, stmt *left, stmt *right, stmt 
*isel, int depth)
 {
        stmt *res = NULL, *ires = NULL, *rsel = NULL, *osel = NULL, *ncond = 
NULL, *ocond = NULL, *cond = NULL;
@@ -1483,6 +1518,8 @@ exp_bin(backend *be, sql_exp *e, stmt *l
                                return exp2bin_copyfrombinary(be, e, left, 
right, sel);
                        if (strcmp(fname, "file_loader") == 0)
                                return exp2bin_file_loader(be, e, left, right, 
sel);
+                       if (strcmp(fname, "-1") == 0) /* map arguments to A0 .. 
An */
+                               return exp2bin_named_placeholders(be, e);
                }
                if (!list_empty(exps)) {
                        unsigned nrcols = 0;
diff --git a/sql/backends/monet5/sql_scenario.c 
b/sql/backends/monet5/sql_scenario.c
--- a/sql/backends/monet5/sql_scenario.c
+++ b/sql/backends/monet5/sql_scenario.c
@@ -1318,12 +1318,12 @@ SQLparser(Client c, backend *be)
                be->vtop = oldvtop;
                be->vid = oldvid;
                (void)runtimeProfileSetTag(c); /* generate and set the tag in 
the mal block of the clients current program. */
-               if (m->emode != m_prepare) {
+               if (m->emode != m_prepare || (m->emode == m_prepare && (m->emod 
& mod_exec) && is_ddl(r->op)) /* direct execution prepare */) {
                        scanner_query_processed(&(m->scanner));
 
                        err = 0;
                        setVarType(c->curprg->def, 0, 0);
-                       if (be->subbackend && 
be->subbackend->check(be->subbackend, r)) {
+                       if (m->emode != m_prepare && be->subbackend && 
be->subbackend->check(be->subbackend, r)) {
                                res_table *rt = NULL;
                                if (be->subbackend->exec(be->subbackend, r, 
be->result_id++, &rt) == NULL) { /* on error fall back */
                                        if (rt) {
@@ -1337,7 +1337,19 @@ SQLparser(Client c, backend *be)
                        Tbegin = GDKusec();
 
                        int opt = 0;
-                       if (backend_dumpstmt(be, c->curprg->def, r, !(m->emod & 
mod_exec), 0, c->query) < 0) {
+                       if (m->emode == m_prepare && (m->emod & mod_exec)) {
+                               /* generated the named parameters for the 
placeholders */
+                               if (backend_dumpstmt(be, c->curprg->def, r->r, 
!(m->emod & mod_exec), 0, c->query) < 0) {
+                                       msg = handle_error(m, 0, msg);
+                                       err = 1;
+                                       MSresetInstructions(c->curprg->def, 
oldstop);
+                                       freeVariables(c, c->curprg->def, NULL, 
oldvtop, oldvid);
+                               }
+                               r = r->l;
+                               m->emode = m_normal;
+                               m->emod &= ~mod_exec;
+                       }
+                       if (!err && backend_dumpstmt(be, c->curprg->def, r, 
!(m->emod & mod_exec), 0, c->query) < 0) {
                                msg = handle_error(m, 0, msg);
                                err = 1;
                                MSresetInstructions(c->curprg->def, oldstop);
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
@@ -3370,6 +3370,45 @@ rel_nop_(mvc *sql, sql_rel *rel, sql_exp
        return exp_op4(sql->sa, a1,a2,a3,a4,f);
 }
 
+static sql_func *
+inplace_func(mvc *sql, sql_rel *r)
+{
+       sql_func *f = SA_NEW(sql->sa, sql_func);
+       list *res = NULL;
+
+       if (r && is_project(r->op) && !list_empty(r->exps)) {
+        sql_arg *a;
+        node *m;
+
+        res = sa_list(sql->sa);
+        for(m = r->exps->h; m; m = m->next) {
+            sql_exp *e = m->data;
+            sql_subtype *t = exp_subtype(e);
+
+            a = NULL;
+            if (t)
+                a = sql_create_arg(sql->sa, NULL, t, ARG_OUT);
+            append(res, a);
+        }
+    }
+
+    *f = (sql_func) {
+        .mod = "",
+        .imp = "",
+        .type = F_PROC,
+        .lang = FUNC_LANG_INT,
+        .query = NULL,
+        .ops = sql->params,
+        .res = res,
+    };
+    base_init(sql->sa, &f->base, 0, true, NULL);
+    f->base.new = 1;
+    f->base.id = -1;
+    f->base.name = "-1";
+    f->instantiated = TRUE;
+       return f;
+}
+
 static sql_exp *
 rel_nop(sql_query *query, sql_rel **rel, symbol *se, int fs, exp_kind ek)
 {
@@ -3400,15 +3439,16 @@ rel_nop(sql_query *query, sql_rel **rel,
 
                if (err)
                        return NULL;
-               if ((q = qc_find(sql->qc, nr))) {
+               if (nr == -1 || (q = qc_find(sql->qc, nr))) {
                        list *nexps = new_exp_list(sql->sa);
-                       sql_func *f = q->f;
+                       sql_func *f = q?q->f:inplace_func(sql, query->last_rel);
+                       list *ops = q?f->ops:sql->params;
 
                        tl = sa_list(sql->sa);
-                       if (list_length(f->ops) != list_length(exps))
-                               return sql_error(sql, 02, SQLSTATE(42000) "EXEC 
called with wrong number of arguments: expected %d, got %d", 
list_length(f->ops), list_length(exps));
-                       if (exps->h && f->ops) {
-                               for (node *n = exps->h, *m = f->ops->h; n && m; 
n = n->next, m = m->next) {
+                       if (list_length(ops) != list_length(exps))
+                               return sql_error(sql, 02, SQLSTATE(42000) "EXEC 
called with wrong number of arguments: expected %d, got %d", list_length(ops), 
list_length(exps));
+                       if (exps->h && ops) {
+                               for (node *n = exps->h, *m = ops->h; n && m; n 
= n->next, m = m->next) {
                                        sql_arg *a = m->data;
                                        sql_exp *e = n->data;
                                        sql_subtype *ntp = &a->type;
@@ -3425,7 +3465,8 @@ rel_nop(sql_query *query, sql_rel **rel,
                        }
                        if (err)
                                return NULL;
-                       sql->type = q->type;
+                       if (q)
+                               sql->type = q->type;
                        return exp_op(sql->sa, list_empty(nexps) ? NULL : 
nexps, sql_dup_subfunc(sql->sa, f, tl, NULL));
                } else {
                        return sql_error(sql, 02, SQLSTATE(42000) "EXEC: 
PREPARED Statement missing '%d'", nr);
diff --git a/sql/server/rel_semantic.c b/sql/server/rel_semantic.c
--- a/sql/server/rel_semantic.c
+++ b/sql/server/rel_semantic.c
@@ -207,6 +207,8 @@ rel_semantic(sql_query *query, symbol *s
                                r = rel_list(sql->sa, r, nr);
                        else
                                r = nr;
+                       if (sql->emode == m_prepare)
+                               query->last_rel = r;
                }
                stack_pop_frame(sql);
                return r;
diff --git a/sql/server/sql_parser.y b/sql/server/sql_parser.y
--- a/sql/server/sql_parser.y
+++ b/sql/server/sql_parser.y
@@ -235,6 +235,7 @@ int yydebug=1;
        drop_table_element
        exec
        exec_ref
+       arg_list_ref
        existence_test
        filter_exp
        forest_element_value
@@ -814,7 +815,7 @@ sqlstmt:
        {
                (void)yynerrs;
                if (m->sym) {
-                       append_symbol(m->sym->data.lval, $$);
+                       append_symbol(m->sym->data.lval, $1);
                        $$ = m->sym;
                } else {
                        m->sym = $$ = $1;
@@ -822,6 +823,26 @@ sqlstmt:
                YYACCEPT;
        }
 
+ | sql ':' arg_list_ref SCOLON
+       {
+               (void)yynerrs;
+                if (!m->emode) /* don't replace m_deps/instantiate */
+                       m->emode = m_prepare;
+               if (m->sym) {
+                       append_symbol(m->sym->data.lval, $1);
+                       $$ = m->sym;
+               } else {
+                       dlist* stmts = L();
+                       append_symbol(stmts, $$ = $1);
+                       m->sym = _symbol_create_list(SQL_MULSTMT, stmts);
+               }
+               if (m->sym->data.lval) {
+                       m->emod |= mod_exec;
+                       append_symbol(m->sym->data.lval, 
_symbol_create_symbol(SQL_CALL, $3)); 
+               }
+               YYACCEPT;
+       }
+
  | prepare             {
                          if (!m->emode) /* don't replace m_deps/instantiate */
                                m->emode = m_prepare;
@@ -5854,17 +5875,21 @@ dealloc:
  ;
 
 exec_ref:
-    posint '(' ')'
+    posint arg_list_ref { $$ = $2; $$->data.lval->h->data.i_val = $1; }
+ ;
+
+arg_list_ref:
+    '(' ')'
        { dlist *l = L();
-         append_int(l, $1);
+         append_int(l, -1);
          append_int(l, FALSE); /* ignore distinct */
          append_list(l, NULL);
          $$ = _symbol_create_list( SQL_NOP, l ); }
-|   posint '(' value_commalist ')'
+ |  '(' value_commalist ')'
        { dlist *l = L();
-         append_int(l, $1);
+         append_int(l, -1);
          append_int(l, FALSE); /* ignore distinct */
-         append_list(l, $3);
+         append_list(l, $2);
          $$ = _symbol_create_list( SQL_NOP, l ); }
  ;
 
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to