Changeset: 088ceba1e8e8 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/088ceba1e8e8
Modified Files:
sql/backends/monet5/sql_execute.c
sql/backends/monet5/sql_gencode.c
sql/server/rel_dump.c
sql/test/SQLancer/Tests/sqlancer19.SQL.py
Branch: Jul2021
Log Message:
Variables are still sent to the remote server. At the moment parse global ones
corretly (later I will check local ones, ie inside UDFs)
diffs (254 lines):
diff --git a/sql/backends/monet5/sql_execute.c
b/sql/backends/monet5/sql_execute.c
--- a/sql/backends/monet5/sql_execute.c
+++ b/sql/backends/monet5/sql_execute.c
@@ -809,6 +809,21 @@ is_a_number(char *v)
return 1;
}
+static char *
+parseIdent(char *in, char *out)
+{
+ while (*in && *in != '"') {
+ if (*in == '\\' && (*(in + 1) == '\\' || *(in + 1) == '"')) {
+ *out++ = *(in + 1);
+ in+=2;
+ } else {
+ *out++ = *in++;
+ }
+ }
+ *out++ = '\0';
+ return in;
+}
+
str
RAstatement2(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
{
@@ -823,7 +838,6 @@ RAstatement2(Client cntxt, MalBlkPtr mb,
str msg = MAL_SUCCEED;
sql_rel *rel;
list *refs, *ops;
- char buf[BUFSIZ];
if ((msg = getSQLContext(cntxt, mb, &m, &be)) != NULL)
return msg;
@@ -836,20 +850,15 @@ RAstatement2(Client cntxt, MalBlkPtr mb,
if (!m->sa)
return RAcommit_statement(be,
createException(SQL,"RAstatement2",SQLSTATE(HY013) MAL_MALLOC_FAIL));
- /* keep copy of signature and relational expression */
- snprintf(buf, BUFSIZ, "%s %s", sig, expr);
-
if (!stack_push_frame(m, NULL))
return RAcommit_statement(be,
createException(SQL,"RAstatement2",SQLSTATE(HY013) MAL_MALLOC_FAIL));
ops = sa_list(m->sa);
while (sig && *sig && !isspace((unsigned char) *sig)) {
- char *vnme = sig, *tnme;
+ char *vnme = sig, *tnme, *nbuf, *sch, *var;
char *p = strchr(++sig, (int)' ');
int d,s,nr = -1;
- sql_subtype t;
- //atom *a;
-
- assert(0);
+ sql_type *t = NULL;
+ sql_subtype tpe;
*p++ = 0;
/* vnme can be name or number */
@@ -859,29 +868,43 @@ RAstatement2(Client cntxt, MalBlkPtr mb,
p = strchr(p, (int)'(');
*p++ = 0;
tnme = sa_strdup(m->sa, tnme);
- if (!tnme)
- return RAcommit_statement(be,
createException(SQL,"RAstatement2",SQLSTATE(HY013) MAL_MALLOC_FAIL));
d = strtol(p, &p, 10);
p++; /* skip , */
s = strtol(p, &p, 10);
- sql_find_subtype(&t, tnme, d, s);
- //a = atom_general(m->sa, &t, NULL);
- //a->isnull = 0; // disable NULL value optimizations ugh
- /* the argument list may have holes and maybe out of order, ie
- * don't use sql_add_arg, but special numbered version
- * sql_set_arg(m, a, nr);
- * */
+ if (!sql_find_subtype(&tpe, tnme, d, s)) {
+ if (!(t = mvc_bind_type(m, tnme))) { /* try an external
type */
+ stack_pop_frame(m);
+ return RAcommit_statement(be,
createException(SQL,"RAstatement2",SQLSTATE(42000) "SQL type %s(%d, %d) not
found\n", tnme, d, s));
+ }
+ sql_init_subtype(&tpe, t, d, s);
+ }
+
if (nr >= 0) {
- append(ops, exp_atom_ref(m->sa, nr, &t));
- //if (!sql_set_arg(m, nr, a)) {
- // sqlcleanup(be, 0);
- // return
createException(SQL,"RAstatement2",SQLSTATE(HY013) MAL_MALLOC_FAIL);
- //}
+ list_append(ops, exp_atom_ref(m->sa, nr, &tpe));
} else {
- if (!push_global_var(m, "sys", vnme+1, &t))
+ sql_schema *s;
+
+ while (*vnme && isdigit(*vnme)) /* skip digit
characters */
+ vnme++;
+
+ nbuf = vnme;
+ sch = nbuf+1;
+ assert(*nbuf == '"');
+ nbuf = parseIdent(nbuf+1, sch);
+ assert(*nbuf == '\0');
+ var = nbuf+2;
+ nbuf = parseIdent(nbuf+2, var);
+
+ if (!(s = mvc_bind_schema(m, sch))) {
+ stack_pop_frame(m);
+ return RAcommit_statement(be,
createException(SQL,"RAstatement2",SQLSTATE(3F000) "No such schema '%s'", sch));
+ }
+ if (!find_global_var(m, s, var) && !push_global_var(m,
sch, var, &tpe)) {
+ stack_pop_frame(m);
return RAcommit_statement(be,
createException(SQL,"RAstatement2",SQLSTATE(HY013) MAL_MALLOC_FAIL));
- append(ops, exp_var(m->sa, NULL, sa_strdup(m->sa,
vnme+1), &t, 0));
+ }
+ list_append(ops, exp_param_or_declared(m->sa,
sa_strdup(m->sa, sch), sa_strdup(m->sa, var), &tpe, 0));
}
sig = strchr(p, (int)',');
if (sig)
@@ -889,7 +912,6 @@ RAstatement2(Client cntxt, MalBlkPtr mb,
}
refs = sa_list(m->sa);
rel = rel_read(m, expr, &pos, refs);
- stack_pop_frame(m);
if (rel)
rel = sql_processrelation(m, rel, 1, 1);
if (!rel) {
@@ -925,6 +947,7 @@ RAstatement2(Client cntxt, MalBlkPtr mb,
if (!msg && monet5_create_relational_function(m, mod, nme, rel, NULL,
ops, 0) < 0)
msg = createException(SQL, "RAstatement2", "%s", m->errstr);
rel_destroy(rel);
+ stack_pop_frame(m);
return RAcommit_statement(be, msg);
}
diff --git a/sql/backends/monet5/sql_gencode.c
b/sql/backends/monet5/sql_gencode.c
--- a/sql/backends/monet5/sql_gencode.c
+++ b/sql/backends/monet5/sql_gencode.c
@@ -393,15 +393,22 @@ static int
int type = t->type->localtype;
int varid = 0;
const char *nme =
(op->op3)?op->op3->op4.aval->data.val.sval:op->cname;
- char *buf = SA_NEW_ARRAY(m->sa, char, strlen(nme) + 2);
+ char *buf = SA_NEW_ARRAY(m->sa, char, strlen(nme) + 2),
*dst = buf, *in = (char*) nme;
if (!buf) {
GDKfree(lname);
sql_error(m, 001, SQLSTATE(HY013)
MAL_MALLOC_FAIL);
return -1;
}
- stpcpy(stpcpy(buf, "A"), nme);
- if ((varid = newVariable(curBlk, buf,strlen(buf),
type)) < 0) {
+ *dst++ = 'A';
+ while (*in) {
+ /* TODO double quotes shouldn't be striped */
+ if (*in != '"')
+ *dst++ = *in;
+ in++;
+ }
+ *dst = '\0';
+ if ((varid = newVariable(curBlk, buf, strlen(buf),
type)) < 0) {
GDKfree(lname);
sql_error(m, 003, SQLSTATE(42000) "Internal
error while compiling statement: variable id too long");
return -1;
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
@@ -1309,40 +1309,41 @@ exp_read(mvc *sql, sql_rel *lrel, sql_re
}
}
- if (!exp && b != e) { /* simple ident */
- /*
- if (!exp) {
- old = *e;
- *e = 0;
- if (stack_find_var(sql, b)) {
- sql_subtype *tpe = stack_find_type(sql, b);
- int frame = stack_find_frame(sql, b);
- exp = exp_param(sql->sa, sa_strdup(sql->sa, b),
tpe, frame);
- }
- *e = old;
- }
- */
- if (!exp && lrel) {
- int amb = 0, mul = 0;
+ if (!exp && lrel && b != e) { /* simple ident */
+ int amb = 0, mul = 0;
- old = *e;
- *e = 0;
- convertIdent(b);
- var_cname = sa_strdup(sql->sa, b);
- if (top_exps) {
- exp = exps_bind_column(top_exps, var_cname,
&amb, &mul, 1);
- if (exp)
- exp = exp_alias_or_copy(sql,
exp_relname(exp), var_cname, lrel, exp);
- }
- (void)amb;
- (void)mul;
- assert(amb == 0 && mul == 0);
- if (!exp && lrel)
- exp = rel_bind_column(sql, lrel, var_cname, 0,
1);
- if (!exp && rrel)
- exp = rel_bind_column(sql, rrel, var_cname, 0,
1);
- *e = old;
- skipWS(r,pos);
+ old = *e;
+ *e = 0;
+ convertIdent(b);
+ var_cname = sa_strdup(sql->sa, b);
+ if (top_exps) {
+ exp = exps_bind_column(top_exps, var_cname, &amb, &mul,
1);
+ if (exp)
+ exp = exp_alias_or_copy(sql, exp_relname(exp),
var_cname, lrel, exp);
+ }
+ (void)amb;
+ (void)mul;
+ assert(amb == 0 && mul == 0);
+ if (!exp && lrel)
+ exp = rel_bind_column(sql, lrel, var_cname, 0, 1);
+ if (!exp && rrel)
+ exp = rel_bind_column(sql, rrel, var_cname, 0, 1);
+ *e = old;
+ skipWS(r,pos);
+ }
+
+ if (!exp && (cname || var_cname)) { /* Try a variable */
+ sql_var *var = NULL;
+ sql_subtype *tpe = NULL;
+ int level = 0;
+ sql_arg *a = NULL;
+ bool has_tname = cname && tname && strcmp(tname, cname) != 0;
+
+ if (find_variable_on_scope(sql, has_tname ? tname : NULL, cname
? cname : var_cname, &var, &a, &tpe, &level, "SELECT")) {
+ if (var) /* if variable is known from the stack or a
global var */
+ exp = exp_param_or_declared(sql->sa, var->sname
? sa_strdup(sql->sa, var->sname) : NULL, sa_strdup(sql->sa, var->name),
&(var->var.tpe), level);
+ if (a) /* if variable is a parameter */
+ exp = exp_param_or_declared(sql->sa, NULL,
sa_strdup(sql->sa, cname), &(a->type), level);
}
}
diff --git a/sql/test/SQLancer/Tests/sqlancer19.SQL.py
b/sql/test/SQLancer/Tests/sqlancer19.SQL.py
--- a/sql/test/SQLancer/Tests/sqlancer19.SQL.py
+++ b/sql/test/SQLancer/Tests/sqlancer19.SQL.py
@@ -76,6 +76,10 @@ with SQLTestCase() as cli:
.assertSucceeded().assertDataResultMatch([(1,2,3,4,5)])
cli.execute("SELECT 1 as \"ups\\\", 2 as \"\\\", 3 as \"\"\"\", 4 as
\"\"\"\\\", 5 as \"\\\"\"\" from rt3 where rt3.c0 = 1;") \
.assertSucceeded().assertDataResultMatch([(1,2,3,4,5)])
+ cli.execute("SELECT \"current_schema\", current_user from t3 where t3.c0 =
1;") \
+ .assertSucceeded().assertDataResultMatch([("sys","monetdb")])
+ cli.execute("SELECT \"current_schema\", current_user from rt3 where rt3.c0
= 1;") \
+ .assertSucceeded().assertDataResultMatch([("sys","monetdb")])
cli.execute("SELECT sql_min(t3.c0 || t3.c0, 3) as x from t3 ORDER BY x;") \
.assertSucceeded().assertDataResultMatch([("11",),("22",),("22",),("3",),("3",),("3",)])
cli.execute("SELECT sql_min(rt3.c0 || rt3.c0, 3) as x from rt3 ORDER BY
x;") \
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list