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