Changeset: 63dcb5a3792b for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=63dcb5a3792b
Modified Files:
sql/server/rel_select.c
Branch: default
Log Message:
Merged with Oct2020
diffs (225 lines):
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
@@ -497,8 +497,15 @@ find_table_function(mvc *sql, sql_schema
if (!f && list_length(tl)) {
int len, match = 0;
list *funcs = sql_find_funcs(sql->sa, s, fname,
list_length(tl), type);
- if (!funcs)
- return sql_error(sql, 02, SQLSTATE(HY013)
MAL_MALLOC_FAIL);
+
+ for (node *n = funcs->h; n ; ) { /* Reduce on privileges */
+ sql_subfunc *sf = n->data;
+ node *nn = n->next;
+
+ if (!execute_priv(sql, sf->func))
+ list_remove_node(funcs, n);
+ n = nn;
+ }
len = list_length(funcs);
if (len > 1) {
int i, score = 0;
@@ -647,8 +654,7 @@ rel_op_(mvc *sql, sql_schema *s, char *f
sql_ftype type = (ek.card == card_loader)?F_LOADER:((ek.card ==
card_none)?F_PROC:
((ek.card == card_relation)?F_UNION:F_FUNC));
- f = sql_bind_func(sql->sa, s, fname, NULL, NULL, type);
- if (f && check_card(ek.card, f)) {
+ if ((f = bind_func_(sql, s, fname, NULL, type)) && check_card(ek.card,
f)) {
return exp_op(sql->sa, NULL, f);
} else {
return sql_error(sql, 02, SQLSTATE(42000) "SELECT: no such
operator '%s'", fname);
@@ -1454,9 +1460,7 @@ rel_filter(mvc *sql, sql_rel *rel, list
if (sname && !(s = mvc_bind_schema(sql, sname)))
return sql_error(sql, 02, SQLSTATE(3F000) "SELECT: no such
schema '%s'", sname);
/* find filter function */
- f = sql_bind_func_(sql->sa, s, filter_op, tl, F_FILT);
-
- if (!f)
+ if (!(f = bind_func_(sql, s, filter_op, tl, F_FILT)))
f = find_func(sql, s, filter_op, list_length(tl), F_FILT, NULL);
if (f) {
node *n,*m = f->func->ops->h;
@@ -1724,8 +1728,15 @@ static sql_exp*
if (!f && list_length(tl)) {
int len, match = 0;
list *funcs = sql_find_funcs(sql->sa, s, fname,
list_length(tl), type);
- if (!funcs)
- return sql_error(sql, 02, SQLSTATE(HY013)
MAL_MALLOC_FAIL);
+
+ for (node *n = funcs->h; n ; ) { /* Reduce on privileges */
+ sql_subfunc *sf = n->data;
+ node *nn = n->next;
+
+ if (!execute_priv(sql, sf->func))
+ list_remove_node(funcs, n);
+ n = nn;
+ }
len = list_length(funcs);
if (len > 1) {
int i, score = 0;
@@ -2809,6 +2820,8 @@ rel_binop_(mvc *sql, sql_rel *rel, sql_e
/* handle param's early */
if (!t1 || !t2) {
f = sql_resolve_function_with_undefined_parameters(sql->sa, s,
fname, list_append(list_append(sa_list(sql->sa), t1), t2), type);
+ if (f && !execute_priv(sql, f->func))
+ f = NULL;
if (f) { /* add types using f */
if (!t1) {
sql_subtype *t =
arg_type(f->func->ops->h->data);
@@ -3630,6 +3643,8 @@ static sql_exp *
a = (sql_subfunc *) m->data;
op = a->func->ops->h;
+ if (!execute_priv(sql, a->func))
+ a = NULL;
for (n = exps->h ; a && op && n; op = op->next,
n = n->next ) {
sql_arg *arg = op->data;
sql_exp *e = n->data;
diff --git a/sql/test/Users/Tests/All b/sql/test/Users/Tests/All
--- a/sql/test/Users/Tests/All
+++ b/sql/test/Users/Tests/All
@@ -29,3 +29,4 @@ schemaRights
metadataConsistency
sessioncontrol
createUserRollback
+HAVE_PYMONETDB?userCallFunction
diff --git a/sql/test/Users/Tests/grantRole.Bug-3772.SQL.py
b/sql/test/Users/Tests/grantRole.Bug-3772.SQL.py
--- a/sql/test/Users/Tests/grantRole.Bug-3772.SQL.py
+++ b/sql/test/Users/Tests/grantRole.Bug-3772.SQL.py
@@ -2,7 +2,7 @@
# Let any user grant any role (not possible).
###
-import os, sys
+import os
try:
from MonetDBtesting import process
except ImportError:
@@ -22,9 +22,14 @@ CREATE ROLE role1;
GRANT ALL ON s1.test to role1;
""")
-
sql_test_client('bruce', 'bruce', input="""\
GRANT role1 to bruce;
SET role role1;
select * from test;
""")
+
+sql_test_client('monetdb', 'monetdb', input="""\
+DROP USER bruce;
+DROP ROLE role1;
+DROP SCHEMA s1 CASCADE;
+""")
diff --git a/sql/test/Users/Tests/userCallFunction.SQL.py
b/sql/test/Users/Tests/userCallFunction.SQL.py
new file mode 100644
--- /dev/null
+++ b/sql/test/Users/Tests/userCallFunction.SQL.py
@@ -0,0 +1,72 @@
+import os, sys, pymonetdb
+
+
+port = int(os.environ['MAPIPORT'])
+db = os.environ['TSTDB']
+
+conn1 =
pymonetdb.connect(port=port,database=db,autocommit=True,username='monetdb',password='monetdb')
+cur1 = conn1.cursor()
+cur1.execute("""
+start transaction;
+create schema s1;
+CREATE USER u1 WITH PASSWORD '1' NAME 'u1' SCHEMA s1;
+CREATE FUNCTION s1.f1() RETURNS INT BEGIN RETURN 10; END;
+CREATE FUNCTION s1.f1(a int) RETURNS INT BEGIN RETURN 10 + a; END;
+commit;
+""")
+cur1.close()
+conn1.close()
+
+conn1 =
pymonetdb.connect(port=port,database=db,autocommit=True,username='u1',password='1')
+cur1 = conn1.cursor()
+try:
+ cur1.execute('SELECT s1.f1();') # error, not allowed
+ sys.stderr.write("Exception expected")
+except pymonetdb.DatabaseError as e:
+ if "SELECT: no such operator 'f1'" not in str(e):
+ sys.stderr.write('Wrong error %s, expected SELECT: no such operator
\'f1\'' % (str(e)))
+try:
+ cur1.execute('SELECT s1.f1(1);') # error, not allowed
+ sys.stderr.write("Exception expected")
+except pymonetdb.DatabaseError as e:
+ if "SELECT: no such unary operator 'f1(tinyint)'" not in str(e):
+ sys.stderr.write('Wrong error %s, expected SELECT: no such unary
operator \'f1(tinyint)\'' % (str(e)))
+try:
+ cur1.execute('CALL sys.flush_log();') # error, not allowed
+ sys.stderr.write("Exception expected")
+except pymonetdb.DatabaseError as e:
+ if "SELECT: no such operator 'flush_log'" not in str(e):
+ sys.stderr.write('Wrong error %s, expected SELECT: no such operator
\'flush_log\'' % (str(e)))
+cur1.close()
+conn1.close()
+
+conn1 =
pymonetdb.connect(port=port,database=db,autocommit=True,username='monetdb',password='monetdb')
+cur1 = conn1.cursor()
+cur1.execute('GRANT EXECUTE ON FUNCTION s1.f1() TO u1;')
+cur1.close()
+conn1.close()
+
+conn1 =
pymonetdb.connect(port=port,database=db,autocommit=True,username='u1',password='1')
+cur1 = conn1.cursor()
+cur1.execute('SELECT s1.f1();')
+if cur1.fetchall() != [(10,)]:
+ sys.stderr.write("[(10,)] expected")
+try:
+ cur1.execute('SELECT s1.f1(1);') # error, not allowed
+ sys.stderr.write("Exception expected")
+except pymonetdb.DatabaseError as e:
+ if "SELECT: no such unary operator 'f1(tinyint)'" not in str(e):
+ sys.stderr.write('Wrong error %s, expected SELECT: no such unary
operator \'f1(tinyint)\'' % (str(e)))
+cur1.close()
+conn1.close()
+
+conn1 =
pymonetdb.connect(port=port,database=db,autocommit=True,username='monetdb',password='monetdb')
+cur1 = conn1.cursor()
+cur1.execute("""
+start transaction;
+drop user u1;
+drop schema s1 cascade;
+commit;
+""")
+cur1.close()
+conn1.close()
diff --git a/sql/test/Users/Tests/userCallFunction.stable.err
b/sql/test/Users/Tests/userCallFunction.stable.err
new file mode 100644
--- /dev/null
+++ b/sql/test/Users/Tests/userCallFunction.stable.err
@@ -0,0 +1,12 @@
+stderr of test 'userCallFunction` in directory 'sql/test/Users` itself:
+
+
+# 12:59:01 >
+# 12:59:01 > "/usr/bin/python3.9" "userCallFunction.SQL.py" "userCallFunction"
+# 12:59:01 >
+
+
+# 12:59:02 >
+# 12:59:02 > "Done."
+# 12:59:02 >
+
diff --git a/sql/test/Users/Tests/userCallFunction.stable.out
b/sql/test/Users/Tests/userCallFunction.stable.out
new file mode 100644
--- /dev/null
+++ b/sql/test/Users/Tests/userCallFunction.stable.out
@@ -0,0 +1,12 @@
+stdout of test 'userCallFunction` in directory 'sql/test/Users` itself:
+
+
+# 12:59:01 >
+# 12:59:01 > "/usr/bin/python3.9" "userCallFunction.SQL.py" "userCallFunction"
+# 12:59:01 >
+
+
+# 12:59:02 >
+# 12:59:02 > "Done."
+# 12:59:02 >
+
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list