Changeset: 9f1b4b119dd3 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/9f1b4b119dd3 Modified Files: clients/Tests/MAL-signatures-hge.test clients/Tests/MAL-signatures.test clients/odbc/driver/SQLStatistics.c monetdb5/modules/mal/calc.c sql/backends/monet5/Tests/persist_unlogged.SQL.py sql/common/sql_types.c sql/scripts/13_date.sql sql/server/CMakeLists.txt sql/server/rel_select.c sql/server/rel_updates.c sql/server/sql_mvc.h sql/server/sql_parser.y sql/server/sql_scan.c sql/server/sql_semantic.c sql/server/sql_semantic.h sql/server/sql_symbol.h sql/server/sql_tokens.h sql/test/BugTracker-2015/Tests/reserved_keywords.Bug-3613.test Branch: clean_parser Log Message:
cleanup of the sql parser: no more reduce/reduce and shift/reduce warnings (enabled warnings==errors) cleanup fixes include better union + with handling more order by's allowed Keywords Table, Column, Distinct, Exec and Execute are now 'reserved' Same for 'as', ie. to use an alias with those use 'as alias'. diffs (truncated from 5402 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 @@ -43710,12 +43710,12 @@ str_2dec_lng; cast to dec(lng) and check for overflow calc max -pattern calc.max(X_0:any_1, X_1:any_1):any_1 +pattern calc.max(X_0:any_1, X_1:any_1...):any_1 CALCmax; Return max of V1 and V2 calc max_no_nil -pattern calc.max_no_nil(X_0:any_1, X_1:any_1):any_1 +pattern calc.max_no_nil(X_0:any_1, X_1:any_1...):any_1 CALCmax_no_nil; Return max of V1 and V2, ignoring nil values calc @@ -43730,12 +43730,12 @@ mbrFromString; (empty) calc min -pattern calc.min(X_0:any_1, X_1:any_1):any_1 +pattern calc.min(X_0:any_1, X_1:any_1...):any_1 CALCmin; Return min of V1 and V2 calc min_no_nil -pattern calc.min_no_nil(X_0:any_1, X_1:any_1):any_1 +pattern calc.min_no_nil(X_0:any_1, X_1:any_1...):any_1 CALCmin_no_nil; Return min of V1 and V2, ignoring nil values calc 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 @@ -32325,12 +32325,12 @@ str_2dec_lng; cast to dec(lng) and check for overflow calc max -pattern calc.max(X_0:any_1, X_1:any_1):any_1 +pattern calc.max(X_0:any_1, X_1:any_1...):any_1 CALCmax; Return max of V1 and V2 calc max_no_nil -pattern calc.max_no_nil(X_0:any_1, X_1:any_1):any_1 +pattern calc.max_no_nil(X_0:any_1, X_1:any_1...):any_1 CALCmax_no_nil; Return max of V1 and V2, ignoring nil values calc @@ -32345,12 +32345,12 @@ mbrFromString; (empty) calc min -pattern calc.min(X_0:any_1, X_1:any_1):any_1 +pattern calc.min(X_0:any_1, X_1:any_1...):any_1 CALCmin; Return min of V1 and V2 calc min_no_nil -pattern calc.min_no_nil(X_0:any_1, X_1:any_1):any_1 +pattern calc.min_no_nil(X_0:any_1, X_1:any_1...):any_1 CALCmin_no_nil; Return min of V1 and V2, ignoring nil values calc diff --git a/clients/odbc/driver/SQLStatistics.c b/clients/odbc/driver/SQLStatistics.c --- a/clients/odbc/driver/SQLStatistics.c +++ b/clients/odbc/driver/SQLStatistics.c @@ -213,7 +213,7 @@ MNDBStatistics(ODBCStmt *stmt, "join sys.objects kc on i.id = kc.id " "join sys._columns c on (t.id = c.table_id and kc.name = c.name) " "%sjoin sys.keys k on (k.name = i.name and i.table_id = k.table_id and k.type in (0, 1, 3)) " - "join sys.storage() st on (st.schema = s.name and st.table = t.name and st.column = c.name) " + "join sys.storage() st on (st.schema = s.name and st.\"table\" = t.name and st.\"column\" = c.name) " "where 1=1", SQL_INDEX_HASHED, SQL_INDEX_OTHER, (Unique == SQL_INDEX_UNIQUE) ? "" : "left outer "); @@ -262,7 +262,7 @@ MNDBStatistics(ODBCStmt *stmt, "join tmp.objects kc on i.id = kc.id " "join tmp._columns c on (t.id = c.table_id and kc.name = c.name) " "%sjoin tmp.keys k on (k.name = i.name and i.table_id = k.table_id and k.type in (0, 1, 3))" - "left outer join sys.storage() st on (st.schema = s.name and st.table = t.name and st.column = c.name) " + "left outer join sys.storage() st on (st.schema = s.name and st.\"table\" = t.name and st.\"column\" = c.name) " "where 1=1", SQL_INDEX_HASHED, SQL_INDEX_OTHER, (Unique == SQL_INDEX_UNIQUE) ? "" : "left outer "); diff --git a/monetdb5/modules/mal/calc.c b/monetdb5/modules/mal/calc.c --- a/monetdb5/modules/mal/calc.c +++ b/monetdb5/modules/mal/calc.c @@ -604,6 +604,18 @@ CALCmin_no_nil(Client cntxt, MalBlkPtr m if (ATOMcmp(t, p1, nil) == 0 || (ATOMcmp(t, p2, nil) != 0 && ATOMcmp(t, p1, p2) > 0)) p1 = p2; + if (pci->argc > 3) { + for(int i = 3; i < pci->argc; i++) { + if (t != getArgType(mb, pci, i)) + return mythrow(MAL, "calc.min", SEMANTIC_TYPE_MISMATCH); + ptr p2 = getArgReference(stk, pci, i); + if (t >= TYPE_str && ATOMstorage(t) >= TYPE_str) + p2 = *(ptr *) p2; + if (ATOMcmp(t, p1, nil) == 0 || + (ATOMcmp(t, p2, nil) != 0 && ATOMcmp(t, p1, p2) > 0)) + p1 = p2; + } + } if (VALinit(&stk->stk[getArg(pci, 0)], t, p1) == NULL) return mythrow(MAL, "calc.min", SQLSTATE(HY013) MAL_MALLOC_FAIL); return MAL_SUCCEED; @@ -655,6 +667,18 @@ CALCmax_no_nil(Client cntxt, MalBlkPtr m if (ATOMcmp(t, p1, nil) == 0 || (ATOMcmp(t, p2, nil) != 0 && ATOMcmp(t, p1, p2) < 0)) p1 = p2; + if (pci->argc > 3) { + for(int i = 3; i < pci->argc; i++) { + if (t != getArgType(mb, pci, i)) + return mythrow(MAL, "calc.max", SEMANTIC_TYPE_MISMATCH); + ptr p2 = getArgReference(stk, pci, i); + if (t >= TYPE_str && ATOMstorage(t) >= TYPE_str) + p2 = *(ptr *) p2; + if (ATOMcmp(t, p1, nil) == 0 || + (ATOMcmp(t, p2, nil) != 0 && ATOMcmp(t, p1, p2) < 0)) + p1 = p2; + } + } if (VALinit(&stk->stk[getArg(pci, 0)], t, p1) == NULL) return mythrow(MAL, "calc.max", SQLSTATE(HY013) MAL_MALLOC_FAIL); return MAL_SUCCEED; @@ -2583,10 +2607,10 @@ mel_func calc_init_funcs[] = { pattern("calc", "oid", CMDvarCONVERT, false, "Cast VALUE to oid", args(1,2, arg("",oid),arg("v",oid))), pattern("calc", "oid", CMDvarCONVERT, false, "Cast VALUE to oid", args(1,2, arg("",oid),arg("v",str))), pattern("calc", "str", CMDvarCONVERT, false, "Cast VALUE to str", args(1,2, arg("",str),argany("v",0))), - pattern("calc", "min", CALCmin, false, "Return min of V1 and V2", args(1,3, argany("",1),argany("v1",1),argany("v2",1))), - pattern("calc", "min_no_nil", CALCmin_no_nil, false, "Return min of V1 and V2, ignoring nil values", args(1,3, argany("",1),argany("v1",1),argany("v2",1))), - pattern("calc", "max", CALCmax, false, "Return max of V1 and V2", args(1,3, argany("",1),argany("v1",1),argany("v2",1))), - pattern("calc", "max_no_nil", CALCmax_no_nil, false, "Return max of V1 and V2, ignoring nil values", args(1,3, argany("",1),argany("v1",1),argany("v2",1))), + pattern("calc", "min", CALCmin, false, "Return min of V1 and V2", args(1,3, argany("",1),argany("v1",1),varargany("v2",1))), + pattern("calc", "min_no_nil", CALCmin_no_nil, false, "Return min of V1 and V2, ignoring nil values", args(1,3, argany("",1),argany("v1",1),varargany("v2",1))), + pattern("calc", "max", CALCmax, false, "Return max of V1 and V2", args(1,3, argany("",1),argany("v1",1),varargany("v2",1))), + pattern("calc", "max_no_nil", CALCmax_no_nil, false, "Return max of V1 and V2, ignoring nil values", args(1,3, argany("",1),argany("v1",1),varargany("v2",1))), command("calc", "ptr", CMDvarCONVERTptr, false, "Cast VALUE to ptr", args(1,2, arg("",ptr),arg("v",ptr))), pattern("calc", "ifthenelse", CALCswitchbit, false, "If VALUE is true return MIDDLE else RIGHT", args(1,4, argany("",1),arg("b",bit),argany("t",1),argany("f",1))), command("calc", "length", CMDstrlength, false, "Length of STRING", args(1,2, arg("",int),arg("s",str))), diff --git a/sql/backends/monet5/Tests/persist_unlogged.SQL.py b/sql/backends/monet5/Tests/persist_unlogged.SQL.py --- a/sql/backends/monet5/Tests/persist_unlogged.SQL.py +++ b/sql/backends/monet5/Tests/persist_unlogged.SQL.py @@ -18,13 +18,13 @@ with tempfile.TemporaryDirectory() as fa tc.execute("ALTER TABLE foo SET INSERT ONLY").assertSucceeded() tc.execute("INSERT INTO foo SELECT * FROM generate_series(0,500)") tc.execute("SELECT count(*) FROM foo").assertSucceeded().assertDataResultMatch([(500,)]) - tc.execute("SELECT table, rowcount FROM persist_unlogged(\'put\', \'foo\')").assertSucceeded().assertDataResultMatch([('foo', 0)]) + tc.execute("SELECT \"table\", rowcount FROM persist_unlogged(\'put\', \'foo\')").assertSucceeded().assertDataResultMatch([('foo', 0)]) # Simulate some work in order to trigger WAL flush(note that Mtests runs with --forcemito) tc.execute("CREATE TABLE bar (x INT)").assertSucceeded() tc.execute("INSERT INTO bar SELECT * FROM generate_series(0,100000)").assertSucceeded() - tc.execute("SELECT table, rowcount FROM persist_unlogged(\'put\', \'foo\')").assertSucceeded().assertDataResultMatch([('foo', 500)]) + tc.execute("SELECT \"table\", rowcount FROM persist_unlogged(\'put\', \'foo\')").assertSucceeded().assertDataResultMatch([('foo', 500)]) s.communicate() with process.server(mapiport='0', dbname='db1', dbfarm=os.path.join(farm_dir, 'db1'), stdin=process.PIPE, stdout=process.PIPE, stderr=process.PIPE) as s: diff --git a/sql/common/sql_types.c b/sql/common/sql_types.c --- a/sql/common/sql_types.c +++ b/sql/common/sql_types.c @@ -1109,8 +1109,10 @@ sqltypeinit( allocator *sa) sql_create_aggr(sa, "max", "aggr", "max", FALSE, FALSE, ANY, 1, ANY); sql_create_func(sa, "sql_min", "calc", "min", FALSE, FALSE, SCALE_FIX, 0, ANY, 2, ANY, ANY); sql_create_func(sa, "sql_max", "calc", "max", FALSE, FALSE, SCALE_FIX, 0, ANY, 2, ANY, ANY); - sql_create_func(sa, "least", "calc", "min_no_nil", TRUE, FALSE, SCALE_FIX, 0, ANY, 2, ANY, ANY); - sql_create_func(sa, "greatest", "calc", "max_no_nil", TRUE, FALSE, SCALE_FIX, 0, ANY, 2, ANY, ANY); + f = sql_create_func(sa, "least", "calc", "min_no_nil", TRUE, FALSE, SCALE_FIX, 0, ANY, 2, ANY, ANY); + f->vararg = 1; + f = sql_create_func(sa, "greatest", "calc", "max_no_nil", TRUE, FALSE, SCALE_FIX, 0, ANY, 2, ANY, ANY); + f->vararg = 1; sql_create_func(sa, "ifthenelse", "calc", "ifthenelse", TRUE, FALSE, SCALE_FIX, 0, ANY, 3, BIT, ANY, ANY); /* nullif, coalesce, casewhen and case don't have a backend implementation */ sql_create_func(sa, "nullif", "", "", TRUE, TRUE, SCALE_FIX, 0, ANY, 2, ANY, ANY); diff --git a/sql/scripts/13_date.sql b/sql/scripts/13_date.sql --- a/sql/scripts/13_date.sql +++ b/sql/scripts/13_date.sql @@ -32,6 +32,9 @@ create function timestamp_to_str(d times create function timestamp_to_str(d timestamp with time zone, format string) returns string external name mtime."timestamptz_to_str"; +create function dayname(d date) returns varchar(10) return date_to_str(d, '%A'); +create function monthname(d date) returns varchar(10) return date_to_str(d, '%B'); + grant execute on function str_to_date to public; grant execute on function date_to_str to public; grant execute on function str_to_time to public; @@ -40,3 +43,5 @@ grant execute on function time_to_str(ti grant execute on function str_to_timestamp to public; grant execute on function timestamp_to_str(timestamp, string) to public; grant execute on function timestamp_to_str(timestamp with time zone, string) to public; +grant execute on function dayname(date) to public; +grant execute on function monthname(date) to public; diff --git a/sql/server/CMakeLists.txt b/sql/server/CMakeLists.txt --- a/sql/server/CMakeLists.txt +++ b/sql/server/CMakeLists.txt @@ -13,7 +13,8 @@ BISON_TARGET(sqlparser sql_parser.y ${CMAKE_CURRENT_BINARY_DIR}/sql_parser.tab.c - COMPILE_FLAGS "-d -p sql -Wno-conflicts-sr -Wno-conflicts-rr" + #COMPILE_FLAGS "-t -rstates,itemsets,lookaheads -ffixit,caret -d -p sql -Wno-conflicts-sr -Wno-conflicts-rr -o sql_parser.output" + COMPILE_FLAGS "-p sql -Werror" DEFINES_FILE ${CMAKE_CURRENT_BINARY_DIR}/sql_parser.tab.h) add_library(sqlserver STATIC) 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 @@ -572,11 +572,13 @@ check_arguments_and_find_largest_any_typ atp = sql_bind_localtype("str"); node *n, *m; - for (n = exps->h, m = sf->func->ops->h; n && m; n = n->next, m = m->next) { - sql_arg *a = m->data; + sql_arg *last = NULL; + for (n = exps->h, m = sf->func->ops->h; n && ((sf->func->vararg && last) || m); n = n->next, m = m?m->next:NULL) { + sql_arg *a = m?m->data:last; sql_exp *e = n->data; sql_subtype *ntp = &a->type, *t = exp_subtype(e); + last = a; if (!t) { if (a->type.type->eclass == EC_ANY && atp) ntp = sql_create_subtype(sql->sa, atp->type, atp->digits, atp->scale); @@ -1075,8 +1077,13 @@ rel_values(sql_query *query, symbol *tab { mvc *sql = query->sql; sql_rel *r = NULL; - dlist *rowlist = tableref->data.lval->h->data.lval; - symbol *optname = tableref->data.lval->t->type == type_symbol ? tableref->data.lval->t->data.sym : NULL; + symbol *values = tableref; + symbol *optname = NULL; + if (tableref->token == SQL_TABLE) { + values = tableref->data.lval->h->data.sym; + optname = tableref->data.lval->t->type == type_symbol ? tableref->data.lval->t->data.sym : NULL; + } + dlist *rowlist = values->data.lval; node *m; list *exps = sa_list(sql->sa); exp_kind ek = {type_value, card_value, TRUE}; @@ -1292,7 +1299,7 @@ table_ref(sql_query *query, symbol *tabl list_append(refs, tname); } return res; - } else if (tableref->token == SQL_VALUES) { + } else if (tableref->token == SQL_VALUES || (tableref->token == SQL_TABLE && tableref->data.lval->h->data.sym->token == SQL_VALUES)) { return rel_values(query, tableref, refs); } else if (tableref->token == SQL_TABLE) { return rel_named_table_function(query, NULL, tableref, lateral, refs); @@ -1464,6 +1471,8 @@ rel_column_ref(sql_query *query, sql_rel if (dlist_length(l) == 1) { const char *name = l->h->data.sval; + if (!name) + return NULL; if (!exp && inner) if (!(exp = rel_bind_column(sql, inner, name, f, 0)) && sql->session->status == -ERR_AMBIGUOUS) @@ -1565,6 +1574,8 @@ rel_column_ref(sql_query *query, sql_rel tname = l->h->next->data.sval; cname = l->h->next->next->data.sval; } + if (!cname) + return NULL; if (!exp && rel && inner) if (!(exp = rel_bind_column3(sql, inner, sname, tname, cname, f)) && sql->session->status == -ERR_AMBIGUOUS) @@ -2181,8 +2192,11 @@ rel_in_value_exp(sql_query *query, sql_r int is_tuple = 0, add_select = 0; /* complex case */ - if (dl->h->type == type_list) { /* (a,b..) in (.. ) */ - dn = dl->h->data.lval->h; + //if (dl->h->type == type_list) { /* (a,b..) in (.. ) */ + if (dl->h->type == type_symbol && dl->h->data.sym->token == SQL_VALUES) { + lo = dl->h->data.sym; + dn = lo->data.lval->h->data.lval->h; + //dn = dl->h->data.lval->h; lo = dn->data.sym; dn = dn->next; } else { @@ -3145,8 +3159,9 @@ rel_op(sql_query *query, sql_rel **rel, char *fname = qname_schema_object(l->data.lval); char *sname = qname_schema(l->data.lval); - if (find_func(sql, sname, fname, 0, F_AGGR, false, NULL, NULL)) + if (find_func(sql, sname, fname, 1, F_AGGR, false, NULL, NULL)) return _rel_aggr(query, rel, 0, sname, fname, NULL, f); + sql->session->status = 0; /* if the function was not found clean the error */ sql->errstr[0] = '\0'; return rel_op_(sql, sname, fname, ek); @@ -3193,26 +3208,6 @@ rel_unop_(mvc *sql, sql_rel *rel, sql_ex found ? "insufficient privileges for" : "no such", sname ? "'":"", sname ? sname : "", sname ? "'.":"", fname, t ? t->type->base.name : "?"); } _______________________________________________ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org