Changeset: cba5fe23a059 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/cba5fe23a059
Modified Files:
sql/backends/monet5/sql.c
sql/backends/monet5/sql_cat.c
sql/backends/monet5/sql_statistics.c
sql/backends/monet5/sql_user.c
sql/server/sql_privileges.c
sql/storage/bat/bat_table.c
Branch: Jul2021
Log Message:
Adding missing transaction conflict checks
diffs (truncated from 361 to 300 lines):
diff --git a/sql/backends/monet5/sql.c b/sql/backends/monet5/sql.c
--- a/sql/backends/monet5/sql.c
+++ b/sql/backends/monet5/sql.c
@@ -1669,8 +1669,8 @@ mvc_append_column(sql_trans *t, sql_colu
{
sqlstore *store = t->store;
int res = store->storage_api.append_col(t, c, pos, ins, TYPE_bat, 0);
- if (res != LOG_OK)
- throw(SQL, "sql.append", SQLSTATE(42000) "Cannot append
values");
+ if (res != LOG_OK) /* the conflict case should never happen, but leave
it here */
+ throw(SQL, "sql.append", SQLSTATE(42000) "Append failed%s", res
== LOG_CONFLICT ? " due to conflict with another transaction" : "");
return MAL_SUCCEED;
}
diff --git a/sql/backends/monet5/sql_cat.c b/sql/backends/monet5/sql_cat.c
--- a/sql/backends/monet5/sql_cat.c
+++ b/sql/backends/monet5/sql_cat.c
@@ -1644,7 +1644,7 @@ SQLcomment_on(Client cntxt, MalBlkPtr mb
}
}
if (ok != LOG_OK)
- throw(SQL, "sql.comment_on", SQLSTATE(3F000) "operation
failed");
+ throw(SQL, "sql.comment_on", SQLSTATE(42000) "Comment on
failed%s", ok == LOG_CONFLICT ? " due to conflict with another transaction" :
"");
return MAL_SUCCEED;
}
diff --git a/sql/backends/monet5/sql_statistics.c
b/sql/backends/monet5/sql_statistics.c
--- a/sql/backends/monet5/sql_statistics.c
+++ b/sql/backends/monet5/sql_statistics.c
@@ -30,6 +30,7 @@ sql_drop_statistics(mvc *m, sql_table *t
sql_table *sysstats;
sql_column *statsid;
oid rid;
+ int log_res = LOG_OK;
tr = m->session->tr;
sys = mvc_bind_schema(m, "sys");
@@ -64,9 +65,8 @@ sql_drop_statistics(mvc *m, sql_table *t
sql_column *c = ncol->data;
rid = store->table_api.column_find_row(tr, statsid,
&c->base.id, NULL);
- if (!is_oid_nil(rid) &&
- store->table_api.table_delete(tr, sysstats, rid) !=
LOG_OK)
- throw(SQL, "sql_drop_statistics", "delete
failed");
+ if (!is_oid_nil(rid) && (log_res =
store->table_api.table_delete(tr, sysstats, rid)) != LOG_OK)
+ throw(SQL, "sql.sql_drop_statistics",
SQLSTATE(42000) "DROP STATISTICS: failed%s", log_res == LOG_CONFLICT ? " due to
conflict with another transaction" : "");
}
}
return MAL_SUCCEED;
@@ -89,7 +89,7 @@ sql_analyze(Client cntxt, MalBlkPtr mb,
int argc = pci->argc;
int width = 0;
int minmax = *getArgReference_int(stk, pci, 1);
- int sfnd = 0, tfnd = 0, cfnd = 0;
+ int sfnd = 0, tfnd = 0, cfnd = 0, log_res = LOG_OK;
sql_schema *sys;
sql_table *sysstats;
sql_column *statsid;
@@ -302,15 +302,15 @@ sql_analyze(Client cntxt, MalBlkPtr mb,
}
BBPunfix(bn->batCacheid);
ts = timestamp_current();
- if (!is_oid_nil(rid) &&
store->table_api.table_delete(tr, sysstats, rid) != LOG_OK) {
+ if (!is_oid_nil(rid) && (log_res =
store->table_api.table_delete(tr, sysstats, rid)) != LOG_OK) {
GDKfree(maxval);
GDKfree(minval);
- throw(SQL, "analyze", "delete
failed");
+ throw(SQL, "analyze",
SQLSTATE(42000) "ANALYZE: failed%s", log_res == LOG_CONFLICT ? " due to
conflict with another transaction" : "");
}
- if (store->table_api.table_insert(tr,
sysstats, &c->base.id, &c->type.type->sqlname, &width, &ts, samplesize ?
&samplesize : &sz, &sz, &uniq, &nils, &minval, &maxval, &sorted, &revsorted) !=
LOG_OK) {
+ if ((log_res =
store->table_api.table_insert(tr, sysstats, &c->base.id,
&c->type.type->sqlname, &width, &ts, samplesize ? &samplesize : &sz, &sz,
&uniq, &nils, &minval, &maxval, &sorted, &revsorted)) != LOG_OK) {
GDKfree(maxval);
GDKfree(minval);
- throw(SQL, "analyze", "insert
failed");
+ throw(SQL, "analyze",
SQLSTATE(42000) "ANALYZE: failed%s", log_res == LOG_CONFLICT ? " due to
conflict with another transaction" : "");
}
}
}
diff --git a/sql/backends/monet5/sql_user.c b/sql/backends/monet5/sql_user.c
--- a/sql/backends/monet5/sql_user.c
+++ b/sql/backends/monet5/sql_user.c
@@ -28,14 +28,22 @@ static int
monet5_drop_user(ptr _mvc, str user)
{
mvc *m = (mvc *) _mvc;
- oid rid;
- sql_schema *sys;
- sql_table *users;
- sql_column *users_name;
+ oid rid, grant_user;
+ sql_schema *sys = find_sql_schema(m->session->tr, "sys");
+ sql_table *users = find_sql_table(m->session->tr, sys, "db_user_info");
+ sql_column *users_name = find_sql_column(users, "name");
str err;
Client c = MCgetClient(m->clientid);
+ sqlstore *store = m->session->tr->store;
+ int log_res = LOG_OK;
- oid grant_user = c->user;
+ rid = store->table_api.column_find_row(m->session->tr, users_name,
user, NULL);
+ if (!is_oid_nil(rid) && (log_res =
store->table_api.table_delete(m->session->tr, users, rid)) != LOG_OK) {
+ (void) sql_error(m, 02, "DROP USER: failed%s", log_res ==
LOG_CONFLICT ? " due to conflict with another transaction" : "");
+ return FALSE;
+ }
+
+ grant_user = c->user;
c->user = MAL_ADMIN;
err = AUTHremoveUser(c, user);
c->user = grant_user;
@@ -44,14 +52,6 @@ monet5_drop_user(ptr _mvc, str user)
freeException(err);
return FALSE;
}
- sys = find_sql_schema(m->session->tr, "sys");
- users = find_sql_table(m->session->tr, sys, "db_user_info");
- users_name = find_sql_column(users, "name");
-
- sqlstore *store = m->session->tr->store;
- rid = store->table_api.column_find_row(m->session->tr, users_name,
user, NULL);
- if (!is_oid_nil(rid))
- store->table_api.table_delete(m->session->tr, users, rid);
/* FIXME: We have to ignore this inconsistency here, because the
* user was already removed from the system authorisation. Once
* we have warnings, we could issue a warning about this
diff --git a/sql/server/sql_privileges.c b/sql/server/sql_privileges.c
--- a/sql/server/sql_privileges.c
+++ b/sql/server/sql_privileges.c
@@ -215,8 +215,8 @@ sql_grant_func_privs( mvc *sql, char *gr
return NULL;
}
-static void
-sql_delete_priv(mvc *sql, sqlid auth_id, sqlid obj_id, int privilege, sqlid
grantor, int grantable)
+static char *
+sql_delete_priv(mvc *sql, sqlid auth_id, sqlid obj_id, int privilege, sqlid
grantor, int grantable, const char *op, const char *call)
{
sql_schema *ss = mvc_bind_schema(sql, "sys");
sql_table *privs = find_sql_table(sql->session->tr, ss, "privileges");
@@ -227,6 +227,7 @@ sql_delete_priv(mvc *sql, sqlid auth_id,
sqlstore *store = tr->store;
rids *A;
oid rid = oid_nil;
+ int log_res = LOG_OK;
(void) grantor;
(void) grantable;
@@ -235,9 +236,12 @@ sql_delete_priv(mvc *sql, sqlid auth_id,
A = store->table_api.rids_select(tr, priv_auth, &auth_id, &auth_id,
priv_priv, &privilege, &privilege, priv_obj, &obj_id, &obj_id, NULL );
/* remove them */
- for(rid = store->table_api.rids_next(A); !is_oid_nil(rid); rid =
store->table_api.rids_next(A))
- store->table_api.table_delete(tr, privs, rid);
+ for(rid = store->table_api.rids_next(A); !is_oid_nil(rid) && log_res ==
LOG_OK; rid = store->table_api.rids_next(A))
+ log_res = store->table_api.table_delete(tr, privs, rid);
store->table_api.rids_destroy(A);
+ if (log_res != LOG_OK)
+ throw(SQL, op, SQLSTATE(42000) "%s: failed%s", call, log_res ==
LOG_CONFLICT ? " due to conflict with another transaction" : "");
+ return NULL;
}
char *
@@ -257,8 +261,7 @@ sql_revoke_global_privs( mvc *sql, char
grantee_id = sql_find_auth(sql, grantee);
if (grantee_id <= 0)
throw(SQL, "sql.revoke_global", SQLSTATE(01006) "REVOKE:
User/role '%s' unknown", grantee);
- sql_delete_priv(sql, grantee_id, GLOBAL_OBJID, privs, grantor, grant);
- return NULL;
+ return sql_delete_priv(sql, grantee_id, GLOBAL_OBJID, privs, grantor,
grant, "sql.revoke_global", "REVOKE");
}
char *
@@ -269,6 +272,7 @@ sql_revoke_table_privs( mvc *sql, char *
bool allowed;
sqlid grantee_id;
int all = PRIV_SELECT | PRIV_UPDATE | PRIV_INSERT | PRIV_DELETE |
PRIV_TRUNCATE;
+ char *msg = NULL;
if (!(t = find_table_or_view_on_scope(sql, NULL, sname, tname,
"REVOKE", false)))
throw(SQL,"sql.revoke_table","%s", sql->errstr);
@@ -298,17 +302,18 @@ sql_revoke_table_privs( mvc *sql, char *
if (grantee_id <= 0)
throw(SQL,"sql.revoke_table", SQLSTATE(01006) "REVOKE:
User/role '%s' unknown", grantee);
if (privs == all) {
- sql_delete_priv(sql, grantee_id, t->base.id, PRIV_SELECT,
grantor, grant);
- sql_delete_priv(sql, grantee_id, t->base.id, PRIV_UPDATE,
grantor, grant);
- sql_delete_priv(sql, grantee_id, t->base.id, PRIV_INSERT,
grantor, grant);
- sql_delete_priv(sql, grantee_id, t->base.id, PRIV_DELETE,
grantor, grant);
- sql_delete_priv(sql, grantee_id, t->base.id, PRIV_TRUNCATE,
grantor, grant);
+ if ((msg = sql_delete_priv(sql, grantee_id, t->base.id,
PRIV_SELECT, grantor, grant, "sql.revoke_table", "REVOKE")) ||
+ (msg = sql_delete_priv(sql, grantee_id, t->base.id,
PRIV_UPDATE, grantor, grant, "sql.revoke_table", "REVOKE")) ||
+ (msg = sql_delete_priv(sql, grantee_id, t->base.id,
PRIV_INSERT, grantor, grant, "sql.revoke_table", "REVOKE")) ||
+ (msg = sql_delete_priv(sql, grantee_id, t->base.id,
PRIV_DELETE, grantor, grant, "sql.revoke_table", "REVOKE")) ||
+ (msg = sql_delete_priv(sql, grantee_id, t->base.id,
PRIV_TRUNCATE, grantor, grant, "sql.revoke_table", "REVOKE")))
+ return msg;
} else if (!c) {
- sql_delete_priv(sql, grantee_id, t->base.id, privs, grantor,
grant);
+ msg = sql_delete_priv(sql, grantee_id, t->base.id, privs,
grantor, grant, "sql.revoke_table", "REVOKE");
} else {
- sql_delete_priv(sql, grantee_id, c->base.id, privs, grantor,
grant);
+ msg = sql_delete_priv(sql, grantee_id, c->base.id, privs,
grantor, grant, "sql.revoke_table", "REVOKE");
}
- return NULL;
+ return msg;
}
char *
@@ -334,8 +339,7 @@ sql_revoke_func_privs( mvc *sql, char *g
grantee_id = sql_find_auth(sql, grantee);
if (grantee_id <= 0)
throw(SQL, "sql.revoke_func", SQLSTATE(01006) "REVOKE:
User/role '%s' unknown", grantee);
- sql_delete_priv(sql, grantee_id, f->base.id, privs, grantor, grant);
- return NULL;
+ return sql_delete_priv(sql, grantee_id, f->base.id, privs, grantor,
grant, "sql.revoke_func", "REVOKE");
}
static bool
@@ -376,18 +380,22 @@ sql_drop_role(mvc *m, str auth)
sqlstore *store = m->session->tr->store;
rids *A;
oid rid;
+ int log_res = LOG_OK;
rid = store->table_api.column_find_row(tr, find_sql_column(auths,
"name"), auth, NULL);
if (is_oid_nil(rid))
throw(SQL, "sql.drop_role", SQLSTATE(0P000) "DROP ROLE: no such
role '%s'", auth);
- store->table_api.table_delete(m->session->tr, auths, rid);
+ if ((log_res = store->table_api.table_delete(m->session->tr, auths,
rid)) != LOG_OK)
+ throw(SQL, "sql.drop_role", SQLSTATE(42000) "DROP ROLE:
failed%s", log_res == LOG_CONFLICT ? " due to conflict with another
transaction" : "");
/* select user roles of this role_id */
A = store->table_api.rids_select(tr, find_sql_column(user_roles,
"role_id"), &role_id, &role_id, NULL);
/* remove them */
- for(rid = store->table_api.rids_next(A); !is_oid_nil(rid); rid =
store->table_api.rids_next(A))
- store->table_api.table_delete(tr, user_roles, rid);
+ for(rid = store->table_api.rids_next(A); !is_oid_nil(rid) && log_res ==
LOG_OK; rid = store->table_api.rids_next(A))
+ log_res = store->table_api.table_delete(tr, user_roles, rid);
store->table_api.rids_destroy(A);
+ if (log_res != LOG_OK)
+ throw(SQL, "sql.drop_role", SQLSTATE(42000) "DROP ROLE:
failed%s", log_res == LOG_CONFLICT ? " due to conflict with another
transaction" : "");
return NULL;
}
@@ -553,6 +561,7 @@ sql_revoke_role(mvc *m, str grantee, str
sql_column *roles_login_id = find_sql_column(roles, "login_id");
sqlid role_id, grantee_id;
sqlstore *store = m->session->tr->store;
+ int log_res = LOG_OK;
rid = store->table_api.column_find_row(m->session->tr, auths_name,
grantee, NULL);
if (is_oid_nil(rid))
@@ -567,15 +576,17 @@ sql_revoke_role(mvc *m, str grantee, str
if (!admin) {
rid = store->table_api.column_find_row(m->session->tr,
roles_login_id, &grantee_id, roles_role_id, &role_id, NULL);
- if (!is_oid_nil(rid))
- store->table_api.table_delete(m->session->tr, roles,
rid);
- else
+ if (!is_oid_nil(rid)) {
+ if ((log_res =
store->table_api.table_delete(m->session->tr, roles, rid)) != LOG_OK)
+ throw(SQL, "sql.revoke_role", SQLSTATE(42000)
"REVOKE: failed%s", log_res == LOG_CONFLICT ? " due to conflict with another
transaction" : "");
+ } else
throw(SQL,"sql.revoke_role", SQLSTATE(01006) "REVOKE:
User '%s' does not have ROLE '%s'", grantee, role);
}
rid = sql_privilege_rid(m, grantee_id, role_id, PRIV_ROLE_ADMIN);
- if (!is_oid_nil(rid))
- store->table_api.table_delete(m->session->tr, privs, rid);
- else if (admin)
+ if (!is_oid_nil(rid)) {
+ if ((log_res = store->table_api.table_delete(m->session->tr,
privs, rid)) != LOG_OK)
+ throw(SQL, "sql.revoke_role", SQLSTATE(42000) "REVOKE:
failed%s", log_res == LOG_CONFLICT ? " due to conflict with another
transaction" : "");
+ } else if (admin)
throw(SQL,"sql.revoke_role", SQLSTATE(01006) "REVOKE: User '%s'
does not have ROLE '%s'", grantee, role);
return NULL;
}
@@ -769,6 +780,8 @@ sql_drop_granted_users(mvc *sql, sqlid u
sqlstore *store = tr->store;
rids *A;
oid rid;
+ int log_res = LOG_OK;
+ char *msg = NULL;
if (!list_find(deleted_users, &user_id, (fcmp) &id_cmp)) {
if (mvc_check_dependency(sql, user_id, OWNER_DEPENDENCY, NULL))
@@ -779,45 +792,54 @@ sql_drop_granted_users(mvc *sql, sqlid u
/* select privileges of this user_id */
A = store->table_api.rids_select(tr, find_sql_column(privs,
"auth_id"), &user_id, &user_id, NULL);
/* remove them */
- for(rid = store->table_api.rids_next(A); !is_oid_nil(rid); rid
= store->table_api.rids_next(A))
- store->table_api.table_delete(tr, privs, rid);
+ for(rid = store->table_api.rids_next(A); !is_oid_nil(rid) &&
log_res == LOG_OK; rid = store->table_api.rids_next(A))
+ log_res = store->table_api.table_delete(tr, privs, rid);
store->table_api.rids_destroy(A);
+ if (log_res != LOG_OK)
+ throw(SQL, "sql.drop_user", SQLSTATE(42000) "DROP USER:
failed%s", log_res == LOG_CONFLICT ? " due to conflict with another
transaction" : "");
/* select privileges granted by this user_id */
A = store->table_api.rids_select(tr, find_sql_column(privs,
"grantor"), &user_id, &user_id, NULL);
/* remove them */
- for(rid = store->table_api.rids_next(A); !is_oid_nil(rid); rid
= store->table_api.rids_next(A))
- store->table_api.table_delete(tr, privs, rid);
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list