Changeset: c3987e3f4c33 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=c3987e3f4c33
Added Files:
sql/test/miscellaneous/Tests/create_func_temp.sql
sql/test/miscellaneous/Tests/create_func_temp.stable.err
sql/test/miscellaneous/Tests/create_func_temp.stable.out
Modified Files:
clients/examples/perl/sqlsample.pl
clients/odbc/driver/ODBCConvert.c
clients/odbc/driver/ODBCUtil.c
clients/odbc/driver/SQLPrepare.c
gdk/gdk_utils.c
sql/server/rel_psm.c
sql/server/rel_rel.c
sql/server/rel_select.c
sql/server/rel_unnest.c
sql/server/rel_unnest.h
sql/server/sql_scan.c
sql/server/sql_scan.h
sql/storage/store.c
sql/test/BugTracker-2014/Tests/copy-into.Bug-3481.SQL.py
sql/test/BugTracker-2014/Tests/utf8bom.Bug-3436.SQL.py
sql/test/BugTracker-2016/Tests/convert-function-test.Bug-3460.sql
sql/test/BugTracker-2016/Tests/convert-function-test.Bug-3460.stable.out
sql/test/BugTracker-2016/Tests/convert-function-test.Bug-3460.stable.out.int128
sql/test/BugTracker-2019/Tests/copy-into-from-stdin-empty-line.Bug-6669.sql
sql/test/BugTracker-2019/Tests/insert-into-select.Bug-6718.sql
sql/test/BugTracker-2019/Tests/python-loader-string.Bug-6759.py
sql/test/Tests/unicode.sql
sql/test/Tests/unicode.stable.out
sql/test/Users/Tests/copyinto.SQL.py
sql/test/Users/Tests/copyinto.stable.err
sql/test/mapi/Tests/perl_dbi.stable.out
sql/test/miscellaneous/Tests/All
sql/test/subquery/Tests/subquery5.sql
sql/test/subquery/Tests/subquery5.stable.err
sql/test/subquery/Tests/subquery5.stable.out
tools/merovingian/utils/utils.c
Branch: scoping
Log Message:
Merged with default
diffs (truncated from 1715 to 300 lines):
diff --git a/clients/examples/perl/sqlsample.pl
b/clients/examples/perl/sqlsample.pl
--- a/clients/examples/perl/sqlsample.pl
+++ b/clients/examples/perl/sqlsample.pl
@@ -48,6 +48,9 @@ my $dbh = DBI->connect( $dsn,
$sth->bind_param( 1, 7 , DBI::SQL_INTEGER() );
$sth->bind_param( 2,'seven' );
$sth->execute;
+ $sth->bind_param( 1, 42 , DBI::SQL_INTEGER() );
+ $sth->bind_param( 2, '\\n' );
+ $sth->execute;
}
{
my $sth = $dbh->prepare('select * from perl_table;');
diff --git a/clients/odbc/driver/ODBCConvert.c
b/clients/odbc/driver/ODBCConvert.c
--- a/clients/odbc/driver/ODBCConvert.c
+++ b/clients/odbc/driver/ODBCConvert.c
@@ -3197,6 +3197,7 @@ ODBCStore(ODBCStmt *stmt,
case SQL_WCHAR:
case SQL_WVARCHAR:
case SQL_WLONGVARCHAR:
+ assign(buf, bufpos, buflen, 'r', stmt); /* RAW string */
assign(buf, bufpos, buflen, '\'', stmt);
switch (ctype) {
case SQL_C_CHAR:
@@ -3205,22 +3206,11 @@ ODBCStore(ODBCStmt *stmt,
for (i = 0; i < slen; i++) {
unsigned char c = (unsigned char) sval[i];
- if (c == 0) {
+ if (c == 0)
break;
- } else if (c < 0x20 /* || c >= 0x7F */) {
- assign(buf, bufpos, buflen, '\\', stmt);
- assign(buf, bufpos, buflen, '0' + (c >>
6), stmt);
- assign(buf, bufpos, buflen, '0' + ((c
>> 3) & 0x7), stmt);
- assign(buf, bufpos, buflen, '0' + (c &
0x7), stmt);
- } else if (c == '\\') {
- assign(buf, bufpos, buflen, '\\', stmt);
- assign(buf, bufpos, buflen, '\\', stmt);
- } else if (c == '\'') {
- assign(buf, bufpos, buflen, '\\', stmt);
+ if (c == '\'')
assign(buf, bufpos, buflen, '\'', stmt);
- } else {
- assign(buf, bufpos, buflen, c, stmt);
- }
+ assign(buf, bufpos, buflen, c, stmt);
}
break;
case SQL_C_BIT:
diff --git a/clients/odbc/driver/ODBCUtil.c b/clients/odbc/driver/ODBCUtil.c
--- a/clients/odbc/driver/ODBCUtil.c
+++ b/clients/odbc/driver/ODBCUtil.c
@@ -679,7 +679,7 @@ ODBCTranslateSQL(ODBCDbc *dbc, const SQL
length = (size_t) sprintf(q, "%.*s ESCAPE ''''
%s", n, nquery, p);
break;
case '\\':
- length = (size_t) sprintf(q, "%.*s ESCAPE
'\\\\' %s", n, nquery, p);
+ length = (size_t) sprintf(q, "%.*s ESCAPE r'\\'
%s", n, nquery, p);
break;
default:
length = (size_t) sprintf(q, "%.*s ESCAPE '%c'
%s", n, nquery, esc, p);
@@ -784,9 +784,7 @@ ODBCTranslateSQL(ODBCDbc *dbc, const SQL
p++;
} else if (*p == '\'') {
while (*++p && *p != '\'')
- if (*p == '\\' &&
- *++p == 0)
- break;
+ ;
if (*p)
p++;
} else {
@@ -820,7 +818,7 @@ ODBCTranslateSQL(ODBCDbc *dbc, const SQL
if (strncasecmp(func->name, scalarfunc,
scalarfunclen) == 0 && func->name[scalarfunclen] == 0 && func->nargs == nargs) {
if (func->repl) {
const char *r;
- q = malloc(length - pr +
strlen(func->repl) - nargs + (nargs > 0 ? args[0].arglen : 0) + (nargs > 1 ?
args[1].arglen : 0) + (nargs > 2 ? args[2].arglen : 0) + 1);
+ q = malloc(length - pr +
strlen(func->repl) - nargs + (nargs > 0 ? args[0].arglen + 1 : 0) + (nargs > 1
? args[1].arglen + 1 : 0) + (nargs > 2 ? args[2].arglen + 1 : 0) + 1);
if (q == NULL) {
free(nquery);
return NULL;
@@ -829,6 +827,8 @@ ODBCTranslateSQL(ODBCDbc *dbc, const SQL
strncpy(q, nquery, pr);
for (r = func->repl; *r; r++) {
if (*r == '\1' || *r ==
'\2' || *r == '\3' || *r == '\4') {
+ if (args[*r -
1].argstart[0] == '\'')
+ q[pr++]
= 'r';
strncpy(q + pr,
args[*r - 1].argstart, args[*r - 1].arglen);
pr += (int)
args[*r - 1].arglen;
} else {
@@ -865,12 +865,17 @@ ODBCTranslateSQL(ODBCDbc *dbc, const SQL
for (c = convert; c->odbc; c++)
{
if
(strncasecmp(c->odbc, args[1].argstart, args[1].arglen) == 0 &&
c->odbc[args[1].arglen] == 0) {
- q =
malloc(length - pr + 11 + args[0].arglen + strlen(c->server));
+ const char *raw;
+ q =
malloc(length - pr + 11 + args[0].arglen + 1 + strlen(c->server));
if (q == NULL) {
free(nquery);
return
NULL;
}
- length =
(size_t) sprintf(q, "%.*scast(%.*s as %s)%s", n, nquery, (int) args[0].arglen,
args[0].argstart, c->server, p);
+ if
(args[0].argstart[0] == '\'')
+ raw =
"r";
+ else
+ raw =
"";
+ length =
(size_t) sprintf(q, "%.*scast(%s%.*s as %s)%s", n, nquery, raw, (int)
args[0].arglen, args[0].argstart, c->server, p);
free(nquery);
nquery = q;
break;
@@ -924,7 +929,7 @@ ODBCParsePV(const char *tab, const char
if (*s == '\'' || *s == '\\')
i++;
}
- i += strlen(tab) + strlen(col) + 25; /* ""."" like '' escape '\\' */
+ i += strlen(tab) + strlen(col) + 25; /* ""."" like '' escape r'\' */
res = malloc(i + 1);
if (res == NULL)
return NULL;
@@ -934,7 +939,7 @@ ODBCParsePV(const char *tab, const char
res[i++] = *s;
res[i++] = *s;
}
- for (s = "' escape '\\\\'"; *s; s++)
+ for (s = "' escape r'\\'"; *s; s++)
res[i++] = *s;
res[i] = 0;
return res;
diff --git a/clients/odbc/driver/SQLPrepare.c b/clients/odbc/driver/SQLPrepare.c
--- a/clients/odbc/driver/SQLPrepare.c
+++ b/clients/odbc/driver/SQLPrepare.c
@@ -74,10 +74,6 @@ MNDBPrepare(ODBCStmt *stmt,
}
fixODBCstring(StatementText, TextLength, SQLINTEGER, addStmtError,
stmt, return SQL_ERROR);
- /* TODO: convert ODBC escape sequences ( {d 'value'} or {t
- * 'value'} or {ts 'value'} or {escape 'e-char'} or {oj
- * outer-join} or {fn scalar-function} etc. ) to MonetDB SQL
- * syntax */
query = ODBCTranslateSQL(stmt->Dbc, StatementText, (size_t) TextLength,
stmt->noScan);
if (query == NULL) {
diff --git a/gdk/gdk_utils.c b/gdk/gdk_utils.c
--- a/gdk/gdk_utils.c
+++ b/gdk/gdk_utils.c
@@ -573,8 +573,8 @@ MT_init(void)
struct rlimit l;
/* address space (virtual memory) limit */
if (getrlimit(RLIMIT_AS, &l) == 0
- && l.rlim_cur != RLIM_INFINITY
- && l.rlim_cur < GDK_vm_maxsize) {
+ && (size_t)l.rlim_cur != RLIM_INFINITY
+ && (size_t)l.rlim_cur < GDK_vm_maxsize) {
GDK_vm_maxsize = l.rlim_cur;
}
#endif
diff --git a/sql/server/rel_rel.c b/sql/server/rel_rel.c
--- a/sql/server/rel_rel.c
+++ b/sql/server/rel_rel.c
@@ -122,17 +122,10 @@ rel_create( sql_allocator *sa )
if(!r)
return NULL;
+ *r = (sql_rel) {
+ .card = CARD_ATOM,
+ };
sql_ref_init(&r->ref);
- r->l = r->r = NULL;
- r->exps = NULL;
- r->nrcols = 0;
- r->flag = 0;
- r->card = CARD_ATOM;
- r->distinct = 0;
- r->processed = 0;
- r->dependent = 0;
- r->subquery = 0;
- r->p = NULL;
return r;
}
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
@@ -3365,6 +3365,7 @@ static sql_exp *
if (args && args->data.sym) {
int ungrouped_col = -1, i, all_aggr = query_has_outer(query);
all_freevar = 1;
+ bool found_nested_aggr = false;
for (i = 0; args && args->data.sym; args = args->next, i++) {
int base = (!groupby || !is_project(groupby->op) ||
is_base(groupby->op) || is_processed(groupby));
bool found_one = false;
@@ -3373,7 +3374,7 @@ static sql_exp *
has_args = true;
if (gl && gl != ogl) {
- if (groupby->grouped) {
+ if (gl->grouped) {
char *uaname = GDKmalloc(strlen(aname)
+ 1);
sql_exp *e = sql_error(sql, 02,
SQLSTATE(42000) "%s: aggregate functions cannot be nested",
uaname ? toUpperCopy(uaname,
aname) : aname);
@@ -3415,10 +3416,10 @@ static sql_exp *
} else {
all_aggr &= (exp_card(e) <= CARD_AGGR &&
!exp_is_atom(e) && is_aggr(e->type) && !is_func(e->type) && (!groupby ||
!is_groupby(groupby->op) || !groupby->r || !exps_find_exp(groupby->r, e)));
}
- all_freevar &= (exp_only_freevar(sql, e, &found_one) &&
found_one);
+ all_freevar &= (exp_only_freevar(query, e, &found_one,
&found_nested_aggr) && found_one);
list_append(exps, e);
}
- if (all_freevar && all_aggr)
+ if (all_freevar && (all_aggr || found_nested_aggr))
return sql_error(sql, 05, SQLSTATE(42000) "SELECT:
aggregate function calls cannot be nested");
if (!all_freevar) {
if (all_aggr) {
diff --git a/sql/server/rel_unnest.c b/sql/server/rel_unnest.c
--- a/sql/server/rel_unnest.c
+++ b/sql/server/rel_unnest.c
@@ -16,6 +16,7 @@
#include "rel_exp.h"
#include "rel_select.h"
#include "rel_rewriter.h"
+#include "sql_query.h"
#include "mal_errors.h" /* for SQLSTATE() */
static void
@@ -170,41 +171,50 @@ rel_has_freevar(mvc *sql, sql_rel *rel)
return 0;
}
-static int exps_only_freevar(mvc *sql, list *exps, bool *found_one);
-static int rel_only_freevar(mvc *sql, sql_rel *rel, bool *found_one);
+static int exps_only_freevar(sql_query *query, list *exps, bool *found_one,
bool *found_aggr);
+static int rel_only_freevar(sql_query *query, sql_rel *rel, bool *found_one,
bool *found_aggr);
int /* look for expressions with either only freevars or atoms */
-exp_only_freevar(mvc *sql, sql_exp *e, bool *found_one)
+exp_only_freevar(sql_query *query, sql_exp *e, bool *found_one, bool
*found_aggr)
{
if (THRhighwater()) {
- (void) sql_error(sql, 10, SQLSTATE(42000) "Query too complex:
running out of stack space");
+ (void) sql_error(query->sql, 10, SQLSTATE(42000) "Query too
complex: running out of stack space");
return 0;
}
if (is_freevar(e)) {
+ sql_rel *outer;
+ sql_exp *a;
+
*found_one = true;
+ if (e->type == e_column) {
+ if ((outer = query_fetch_outer(query,
is_freevar(e)-1))) {
+ if ((a = rel_find_exp(outer, e)) &&
is_aggr(a->type))
+ *found_aggr = true;
+ }
+ }
return 1;
}
switch(e->type) {
case e_cmp:
if (e->flag == cmp_or || e->flag == cmp_filter) {
- return (exps_only_freevar(sql, e->l, found_one) &&
exps_only_freevar(sql, e->r, found_one));
+ return (exps_only_freevar(query, e->l, found_one,
found_aggr) && exps_only_freevar(query, e->r, found_one, found_aggr));
} else if (e->flag == cmp_in || e->flag == cmp_notin) {
- return (exp_only_freevar(sql, e->l, found_one) &&
exps_only_freevar(sql, e->r, found_one));
+ return (exp_only_freevar(query, e->l, found_one,
found_aggr) && exps_only_freevar(query, e->r, found_one, found_aggr));
} else {
- return (exp_only_freevar(sql, e->l, found_one) &&
exp_only_freevar(sql, e->r, found_one) &&
- (!e->f || (e->f &&
exp_only_freevar(sql, e->f, found_one))));
+ return (exp_only_freevar(query, e->l, found_one,
found_aggr) && exp_only_freevar(query, e->r, found_one, found_aggr) &&
+ (!e->f || (e->f &&
exp_only_freevar(query, e->f, found_one, found_aggr))));
}
case e_convert:
- return exp_only_freevar(sql, e->l, found_one);
+ return exp_only_freevar(query, e->l, found_one, found_aggr);
case e_func:
case e_aggr:
if (e->l)
- return exps_only_freevar(sql, e->l, found_one);
+ return exps_only_freevar(query, e->l, found_one,
found_aggr);
return 1;
case e_psm:
if (exp_is_rel(e))
- return rel_only_freevar(sql, e->l, found_one);
+ return rel_only_freevar(query, e->l, found_one,
found_aggr);
return 1;
case e_atom:
return 1;
@@ -215,41 +225,41 @@ exp_only_freevar(mvc *sql, sql_exp *e, b
}
int
-exps_only_freevar(mvc *sql, list *exps, bool *found_one)
+exps_only_freevar(sql_query *query, list *exps, bool *found_one, bool
*found_aggr)
{
int all_freevar = 1;
if (THRhighwater()) {
- (void) sql_error(sql, 10, SQLSTATE(42000) "Query too complex:
running out of stack space");
+ (void) sql_error(query->sql, 10, SQLSTATE(42000) "Query too
complex: running out of stack space");
return 0;
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list