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

Reply via email to