Changeset: 340f9e7aea68 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/340f9e7aea68
Modified Files:
        sql/backends/monet5/sql_user.c
        sql/server/sql_mvc.c
        sql/server/sql_privileges.c
        sql/storage/sql_storage.h
        sql/storage/store.c
Branch: userprofile
Log Message:

create schema matching new user
if none provided on create user ...


diffs (241 lines):

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
@@ -164,25 +164,57 @@ static str
 monet5_create_user(ptr _mvc, str user, str passwd, char enc, str fullname, 
sqlid schema_id, str schema_path, sqlid grantorid, lng max_memory, int 
max_workers, str optimizer, sqlid role_id)
 {
        mvc *m = (mvc *) _mvc;
-       oid uid = 0;
-       str ret, pwd;
+       oid rid, uid = 0;
+       str ret, pwd, schema_buf;
        sqlid user_id;
        sql_schema *s = find_sql_schema(m->session->tr, "sys");
-       sql_table *db_user_info = find_sql_table(m->session->tr, s, 
"db_user_info"), *auths = find_sql_table(m->session->tr, s, "auths");
+       sql_table *db_user_info = find_sql_table(m->session->tr, s, 
"db_user_info"),
+                         *auths = find_sql_table(m->session->tr, s, "auths"),
+                         *schemas_tbl = find_sql_table(m->session->tr, s, 
"schemas");
        Client c = MCgetClient(m->clientid);
        sqlstore *store = m->session->tr->store;
        int log_res = 0;
+       bool new_schema = false;
 
-       if (!schema_path)
-               schema_path = default_schema_path;
+       if (schema_id == 0) {
+               // create default schema matching $user
+               switch (sql_trans_create_schema(m->session->tr, user, 
m->role_id, m->user_id, &schema_id)) {
+                       case -1:
+                               throw(SQL,"sql.create_user",SQLSTATE(HY013) 
MAL_MALLOC_FAIL);
+                       case -2:
+                       case -3:
+                               throw(SQL,"sql.create_user",SQLSTATE(42000) 
"Create user schema failed due to transaction conflict");
+                       default:
+                               break;
+               }
+               if (is_oid_nil(rid = 
store->table_api.column_find_row(m->session->tr, find_sql_column(schemas_tbl, 
"id"), &schema_id, NULL)))
+                       throw(SQL,"sql.create_user",SQLSTATE(42000) "User 
schema not found");
+               new_schema = true;
+       }
+
+       // default path is $user
+       if (!schema_path) {
+               // "\"$user\"\0"
+               schema_buf = GDKmalloc(strlen(user) + 3);
+               assert(snprintf(schema_buf, strlen(schema_buf) + 1, "\"%s\"", 
user) > 0);
+               schema_path = schema_buf;
+       }
+
+       if ((ret = parse_schema_path_str(m, schema_path, false)) != 
MAL_SUCCEED) {
+               if (schema_buf)
+                       GDKfree(schema_buf);
+               return ret;
+       }
+
        if (!optimizer)
                optimizer = default_optimizer;
-       if ((ret = parse_schema_path_str(m, schema_path, false)) != MAL_SUCCEED)
-               return ret;
 
        if (!enc) {
-               if (!(pwd = mcrypt_BackendSum(passwd, strlen(passwd))))
+               if (!(pwd = mcrypt_BackendSum(passwd, strlen(passwd)))) {
+                       if (schema_buf)
+                               GDKfree(schema_buf);
                        throw(MAL, "sql.create_user", SQLSTATE(42000) "Crypt 
backend hash not found");
+               }
        } else {
                pwd = passwd;
        }
@@ -192,14 +224,40 @@ monet5_create_user(ptr _mvc, str user, s
        if ((log_res = store->table_api.table_insert(m->session->tr, 
db_user_info, &user, &fullname, &schema_id, &schema_path, &max_memory, 
&max_workers, &optimizer, &default_role_id))) {
                if (!enc)
                        free(pwd);
+               if (schema_buf)
+                       GDKfree(schema_buf);
                throw(SQL, "sql.create_user", SQLSTATE(42000) "Create user 
failed%s", log_res == LOG_CONFLICT ? " due to conflict with another 
transaction" : "");
        }
        if ((log_res = store->table_api.table_insert(m->session->tr, auths, 
&user_id, &user, &grantorid))) {
                if (!enc)
                        free(pwd);
+               if (schema_buf)
+                       GDKfree(schema_buf);
                throw(SQL, "sql.create_user", SQLSTATE(42000) "Create user 
failed%s", log_res == LOG_CONFLICT ? " due to conflict with another 
transaction" : "");
        }
 
+       if (new_schema) {
+               // update schema authorization to be default_role_id
+               switch (sql_trans_change_schema_authorization(m->session->tr, 
schema_id, default_role_id)) {
+                       case -1:
+                               if (!enc)
+                                       free(pwd);
+                               if (schema_buf)
+                                       GDKfree(schema_buf);
+                               throw(SQL,"sql.create_user",SQLSTATE(HY013) 
MAL_MALLOC_FAIL);
+                       case -2:
+                       case -3:
+                               if (!enc)
+                                       free(pwd);
+                               if (schema_buf)
+                                       GDKfree(schema_buf);
+                               throw(SQL,"sql.create_user",SQLSTATE(42000) 
"Update schema authorization failed due to transaction conflict");
+                       default:
+                               break;
+               }
+
+       }
+
        /* add the user to the M5 authorisation administration */
        oid grant_user = c->user;
        c->user = MAL_ADMIN;
@@ -207,6 +265,8 @@ monet5_create_user(ptr _mvc, str user, s
        c->user = grant_user;
        if (!enc)
                free(pwd);
+       if (schema_buf)
+               GDKfree(schema_buf);
        return ret;
 }
 
diff --git a/sql/server/sql_mvc.c b/sql/server/sql_mvc.c
--- a/sql/server/sql_mvc.c
+++ b/sql/server/sql_mvc.c
@@ -1115,7 +1115,7 @@ int
 mvc_create_schema(mvc *m, const char *name, sqlid auth_id, sqlid owner)
 {
        TRC_DEBUG(SQL_TRANS, "Create schema: %s %d %d\n", name, auth_id, owner);
-       return sql_trans_create_schema(m->session->tr, name, auth_id, owner);
+       return sql_trans_create_schema(m->session->tr, name, auth_id, owner, 
NULL);
 }
 
 int
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
@@ -792,11 +792,23 @@ sql_create_user(mvc *sql, char *user, ch
        if (backend_find_user(sql, user) >= 0)
                throw(SQL,"sql.create_user", SQLSTATE(42M31) "CREATE USER: user 
'%s' already exists", user);
 
-       if (!(s = find_sql_schema(sql->session->tr, schema)))
-               throw(SQL,"sql.create_user", SQLSTATE(3F000) "CREATE USER: no 
such schema '%s'", schema);
-       schema_id = s->base.id;
-       if (!isNew(s) && sql_trans_add_dependency(sql->session->tr, schema_id, 
ddl) != LOG_OK)
-               throw(SQL, "sql.create_user", SQLSTATE(HY013) MAL_MALLOC_FAIL);
+       if (schema) {
+               if (!(s = find_sql_schema(sql->session->tr, schema)))
+                       throw(SQL,"sql.create_user", SQLSTATE(3F000) "CREATE 
USER: no such schema '%s'", schema);
+               schema_id = s->base.id;
+               if (!isNew(s) && sql_trans_add_dependency(sql->session->tr, 
schema_id, ddl) != LOG_OK)
+                       throw(SQL, "sql.create_user", SQLSTATE(HY013) 
MAL_MALLOC_FAIL);
+
+       } else {
+               // look for an existing schema matching user
+               if ((s = find_sql_schema(sql->session->tr, user))) {
+                       schema_id = s->base.id;
+                       if (!isNew(s) && 
sql_trans_add_dependency(sql->session->tr, schema_id, ddl) != LOG_OK)
+                               throw(SQL, "sql.create_user", SQLSTATE(HY013) 
MAL_MALLOC_FAIL);
+               }
+       }
+
+
        if (sql_trans_add_dependency(sql->session->tr, sql->user_id, ddl) != 
LOG_OK)
                throw(SQL, "sql.create_user", SQLSTATE(HY013) MAL_MALLOC_FAIL);
 
@@ -817,6 +829,7 @@ sql_create_user(mvc *sql, char *user, ch
                _DELETE(err);
                return r;
        }
+
        return NULL;
 }
 
diff --git a/sql/storage/sql_storage.h b/sql/storage/sql_storage.h
--- a/sql/storage/sql_storage.h
+++ b/sql/storage/sql_storage.h
@@ -366,8 +366,9 @@ extern int sql_trans_drop_all_func(sql_t
 extern void sql_trans_update_tables(sql_trans *tr, sql_schema *s);
 extern void sql_trans_update_schemas(sql_trans *tr);
 
-extern int sql_trans_create_schema(sql_trans *tr, const char *name, sqlid 
auth_id, sqlid owner);
+extern int sql_trans_create_schema(sql_trans *tr, const char *name, sqlid 
auth_id, sqlid owner, sqlid *schema_id_ptr);
 extern int sql_trans_rename_schema(sql_trans *tr, sqlid id, const char 
*new_name);
+extern int sql_trans_change_schema_authorization(sql_trans *tr, sqlid id, 
sqlid auth_id);
 extern int sql_trans_drop_schema(sql_trans *tr, sqlid id, int drop_action);
 
 sql_export int sql_trans_create_table(sql_table **tres, sql_trans *tr, 
sql_schema *s, const char *name, const char *sql, int tt, bit system, int 
persistence, int commit_action, int sz, bte properties);
diff --git a/sql/storage/store.c b/sql/storage/store.c
--- a/sql/storage/store.c
+++ b/sql/storage/store.c
@@ -5031,7 +5031,7 @@ sql_trans_drop_all_func(sql_trans *tr, s
 }
 
 int
-sql_trans_create_schema(sql_trans *tr, const char *name, sqlid auth_id, sqlid 
owner)
+sql_trans_create_schema(sql_trans *tr, const char *name, sqlid auth_id, sqlid 
owner, sqlid *schema_id_ptr)
 {
        sqlstore *store = tr->store;
        sql_schema *s = SA_ZNEW(tr->sa, sql_schema);
@@ -5062,6 +5062,8 @@ sql_trans_create_schema(sql_trans *tr, c
                return res;
        if ((res = sql_trans_add_dependency(tr, s->owner, ddl)))
                return res;
+       if (schema_id_ptr)
+               *schema_id_ptr = s->base.id;
        return res;
 }
 
@@ -5093,6 +5095,34 @@ sql_trans_rename_schema(sql_trans *tr, s
 }
 
 int
+sql_trans_change_schema_authorization(sql_trans *tr, sqlid id, sqlid auth_id)
+{
+       sqlstore *store = tr->store;
+       sql_table *sysschema = find_sql_table(tr, find_sql_schema(tr, "sys"), 
"schemas");
+       sql_schema *s = find_sql_schema_id(tr, id), *ns = NULL;
+       oid rid;
+       int res = LOG_OK;
+
+       assert(auth_id);
+       s->auth_id = auth_id;
+
+       rid = store->table_api.column_find_row(tr, find_sql_column(sysschema, 
"id"), &id, NULL);
+       assert(!is_oid_nil(rid));
+       if ((res = store->table_api.column_update_value(tr, 
find_sql_column(sysschema, "authorization"), rid, &auth_id)))
+               return res;
+
+       if (!isNew(s) && (res = sql_trans_add_dependency_change(tr, id, ddl)))
+               return res;
+       /* delete schema, add schema */
+       if ((res = os_del(tr->cat->schemas, tr, s->base.name, 
dup_base(&s->base))))
+               return res;
+       if ((res = schema_dup(tr, s, s->base.name, &ns)) || (res = 
os_add(tr->cat->schemas, tr, ns->base.name, &ns->base))) {
+               return res;
+       }
+       return res;
+}
+
+int
 sql_trans_drop_schema(sql_trans *tr, sqlid id, int drop_action)
 {
        sqlstore *store = tr->store;
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to