Changeset: dab1a23251da for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=dab1a23251da Removed Files: sql/test/Users/Tests/privs2.test sql/test/Users/Tests/test_privs2_p1.SQL.py sql/test/Users/Tests/test_privs2_p2.SQL.py Modified Files: sql/backends/monet5/rel_bin.c sql/include/sql_catalog.h sql/server/sql_parser.y sql/server/sql_privileges.c sql/server/sql_semantic.c Branch: indirect-privs Log Message:
Merged with default diffs (truncated from 2409 to 300 lines): diff --git a/gdk/gdk_logger.c b/gdk/gdk_logger.c --- a/gdk/gdk_logger.c +++ b/gdk/gdk_logger.c @@ -3181,8 +3181,8 @@ bm_commit(logger *lg, lng save_id) logbat_destroy(n); return GDK_FAIL; } + assert(BBP_lrefs(bid) == lb->batSharecnt + 1 && BBP_refs(bid) <= lb->batSharecnt); BBPrelease(bid); - assert(BBP_lrefs(bid)<=0 && BBP_refs(bid)==0); } if (leftover) { nfreed = logbat_new(TYPE_int, leftover, TRANSIENT); diff --git a/gdk/gdk_project.c b/gdk/gdk_project.c --- a/gdk/gdk_project.c +++ b/gdk/gdk_project.c @@ -305,7 +305,7 @@ project_str(BAT *restrict l, struct cand var_t v; if ((bn = COLnew(l->hseqbase, TYPE_str, ci ? ci->ncand : BATcount(l), - TRANSIENT)) != NULL) + TRANSIENT)) == NULL) return NULL; v = (var_t) r1->tvheap->free; @@ -329,6 +329,7 @@ project_str(BAT *restrict l, struct cand memset(bn->tvheap->base + r1->tvheap->free, 0, h1off - r1->tvheap->free); #endif memcpy(bn->tvheap->base + h1off, r2->tvheap->base, r2->tvheap->free); + bn->tvheap->free = h1off + r2->tvheap->free; } if (v >= ((var_t) 1 << (8 * bn->twidth)) && diff --git a/sql/backends/monet5/rel_bin.c b/sql/backends/monet5/rel_bin.c --- a/sql/backends/monet5/rel_bin.c +++ b/sql/backends/monet5/rel_bin.c @@ -5318,15 +5318,11 @@ sql_truncate(backend *be, sql_table *t, mvc *sql = be->mvc; list *l = sa_list(sql->sa); stmt *v, *ret = NULL, *other = NULL; - const char *next_value_for = "next value for \"sys\".\"seq_"; - char *seq_name = NULL; - str seq_pos = NULL; + const char *next_value_for = "next value for "; sql_column *col = NULL; - sql_sequence *seq = NULL; sql_schema *sche = NULL; sql_table *next = NULL; sql_trans *tr = sql->session->tr; - node *n = NULL; int error = 0; struct tablelist* new_list = SA_NEW(sql->ta, struct tablelist), *list_node; @@ -5347,18 +5343,20 @@ sql_truncate(backend *be, sql_table *t, sche = next->s; if (restart_sequences) { /* restart the sequences if it's the case */ - for (n = next->columns.set->h; n; n = n->next) { + for (node *n = next->columns.set->h; n; n = n->next) { col = n->data; - if (col->def && (seq_pos = strstr(col->def, next_value_for))) { - seq_name = sa_strdup(sql->ta, seq_pos + (strlen(next_value_for) - strlen("seq_"))); - if (!seq_name) { - sql_error(sql, 02, SQLSTATE(HY013) MAL_MALLOC_FAIL); - error = 1; - goto finalize; - } - seq_name[strlen(seq_name)-1] = '\0'; - seq = find_sql_sequence(sche, seq_name); - if (seq) { + + if (col->def && !strncmp(col->def, next_value_for, strlen(next_value_for))) { + sql_schema *s = NULL; + sql_sequence *seq = NULL; + char *schema = NULL, *seq_name = NULL; + + extract_schema_and_sequence_name(sql->ta, col->def + strlen(next_value_for), &schema, &seq_name); + if (!schema || !seq_name || !(s = find_sql_schema(tr, schema))) + continue; + + assert(s->base.id == sche->base.id); + if ((seq = find_sql_sequence(s, seq_name))) { if (!sql_trans_sequence_restart(tr, seq, seq->start)) { sql_error(sql, 02, SQLSTATE(HY005) "Could not restart sequence %s.%s", sche->base.name, seq_name); error = 1; diff --git a/sql/include/sql_catalog.h b/sql/include/sql_catalog.h --- a/sql/include/sql_catalog.h +++ b/sql/include/sql_catalog.h @@ -775,4 +775,55 @@ typedef struct { extern int nested_mergetable(sql_trans *tr, sql_table *t, const char *sname, const char *tname); extern sql_part *partition_find_part(sql_trans *tr, sql_table *pt, sql_part *pp); +#define outside_str 1 +#define inside_str 2 + +#define extracting_schema 1 +#define extracting_sequence 2 + +static inline void +extract_schema_and_sequence_name(sql_allocator *sa, char *default_value, char **schema, char **sequence) +{ + int status = outside_str, identifier = extracting_schema; + char next_identifier[1024]; /* needs one extra character for null terminator */ + size_t bp = 0; + + for (size_t i = 0; default_value[i]; i++) { + char next = default_value[i]; + + if (next == '"') { + if (status == inside_str && default_value[i + 1] == '"') { + next_identifier[bp++] = '"'; + i++; /* has to advance two positions */ + } else if (status == inside_str) { + next_identifier[bp++] = '\0'; + if (identifier == extracting_schema) { + *schema = sa_strdup(sa, next_identifier); + identifier = extracting_sequence; + } else if (identifier == extracting_sequence) { + *sequence = sa_strdup(sa, next_identifier); + break; /* done extracting */ + } + bp = 0; + status = outside_str; + } else { + assert(status == outside_str); + status = inside_str; + } + } else if (next == '.') { + if (status == outside_str && default_value[i + 1] == '"') { + status = inside_str; + i++; /* has to advance two positions */ + } else { + assert(status == inside_str); + next_identifier[bp++] = '.'; /* used inside an identifier name */ + } + } else if (status == inside_str) { + next_identifier[bp++] = next; + } else { + assert(status == outside_str); + } + } +} + #endif /* SQL_CATALOG_H */ diff --git a/sql/server/sql_parser.y b/sql/server/sql_parser.y --- a/sql/server/sql_parser.y +++ b/sql/server/sql_parser.y @@ -6416,7 +6416,6 @@ sqlerror(mvc * sql, const char *err) static void *ma_alloc(sql_allocator *sa, size_t sz) { - printf("#ma_alloc\n"); return sa_alloc(sa, sz); } static void ma_free(void *p) 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 @@ -528,7 +528,7 @@ sql_grant_role(mvc *m, str grantee, str rid = table_funcs.column_find_row(m->session->tr, auths_name, role, NULL); if (is_oid_nil(rid)) - throw(SQL, "sql.grant_role", SQLSTATE(M1M05) "GRANT: Cannot grant ROLE '%s' to user '%s'", role, grantee); + throw(SQL, "sql.grant_role", SQLSTATE(M1M05) "GRANT: no such role '%s' or grantee '%s'", role, grantee); role_id = table_funcs.column_find_sqlid(m->session->tr, auths_id, rid); if (backend_find_user(m, role) >= 0) throw(SQL,"sql.grant_role", SQLSTATE(M1M05) "GRANT: '%s' is a USER not a ROLE", role); @@ -536,7 +536,7 @@ sql_grant_role(mvc *m, str grantee, str throw(SQL,"sql.grant_role", SQLSTATE(0P000) "GRANT: Insufficient privileges to grant ROLE '%s'", role); rid = table_funcs.column_find_row(m->session->tr, auths_name, grantee, NULL); if (is_oid_nil(rid)) - throw(SQL,"sql.grant_role", SQLSTATE(M1M05) "GRANT: Cannot grant ROLE '%s' to user '%s'", role, grantee); + throw(SQL,"sql.grant_role", SQLSTATE(M1M05) "GRANT: no such role '%s' or grantee '%s'", role, grantee); grantee_id = table_funcs.column_find_sqlid(m->session->tr, auths_id, rid); rid = table_funcs.column_find_row(m->session->tr, find_sql_column(roles, "login_id"), &grantee_id, find_sql_column(roles, "role_id"), &role_id, NULL); if (!is_oid_nil(rid)) diff --git a/sql/server/sql_semantic.c b/sql/server/sql_semantic.c --- a/sql/server/sql_semantic.c +++ b/sql/server/sql_semantic.c @@ -933,14 +933,34 @@ dlist2string(mvc *sql, dlist *l, int exp return b; } +static const char * +symbol_escape_ident(sql_allocator *sa, const char *s) +{ + char *res = NULL; + if (s) { + size_t l = strlen(s); + char *r = SA_NEW_ARRAY(sa, char, (l * 2) + 1); + + res = r; + while (*s) { + if (*s == '"') + *r++ = '"'; + *r++ = *s++; + } + *r = '\0'; + } + return res; +} + char * -_symbol2string(mvc *sql, symbol *se, int expression, char **err) /**/ +_symbol2string(mvc *sql, symbol *se, int expression, char **err) { /* inner symbol2string uses the temporary allocator */ switch (se->token) { case SQL_NOP: { dnode *lst = se->data.lval->h, *ops = lst->next->next->data.lval->h, *aux; - const char *op = qname_schema_object(lst->data.lval), *sname = qname_schema(lst->data.lval); + const char *op = symbol_escape_ident(sql->ta, qname_schema_object(lst->data.lval)), + *sname = symbol_escape_ident(sql->ta, qname_schema(lst->data.lval)); int i = 0, nargs = 0; char** inputs = NULL, *res; size_t inputs_length = 0, extra = sname ? strlen(sname) + 3 : 0; @@ -976,7 +996,8 @@ char * } break; case SQL_BINOP: { dnode *lst = se->data.lval->h; - const char *op = qname_schema_object(lst->data.lval), *sname = qname_schema(lst->data.lval); + const char *op = symbol_escape_ident(sql->ta, qname_schema_object(lst->data.lval)), + *sname = symbol_escape_ident(sql->ta, qname_schema(lst->data.lval)); char *l = NULL, *r = NULL, *res; size_t extra = sname ? strlen(sname) + 3 : 0; @@ -993,7 +1014,8 @@ char * } break; case SQL_OP: { dnode *lst = se->data.lval->h; - const char *op = qname_schema_object(lst->data.lval), *sname = qname_schema(lst->data.lval); + const char *op = symbol_escape_ident(sql->ta, qname_schema_object(lst->data.lval)), + *sname = symbol_escape_ident(sql->ta, qname_schema(lst->data.lval)); char *res; size_t extra = sname ? strlen(sname) + 3 : 0; @@ -1007,7 +1029,8 @@ char * } break; case SQL_UNOP: { dnode *lst = se->data.lval->h; - const char *op = qname_schema_object(lst->data.lval), *sname = qname_schema(lst->data.lval); + const char *op = symbol_escape_ident(sql->ta, qname_schema_object(lst->data.lval)), + *sname = symbol_escape_ident(sql->ta, qname_schema(lst->data.lval)); char *l = _symbol2string(sql, lst->next->next->data.sym, expression, err), *res; size_t extra = sname ? strlen(sname) + 3 : 0; @@ -1034,11 +1057,13 @@ char * return sa_strdup(sql->ta, "NULL"); } case SQL_NEXT: { - const char *seq = qname_schema_object(se->data.lval), *sname = qname_schema(se->data.lval); + const char *seq = symbol_escape_ident(sql->ta, qname_schema_object(se->data.lval)), + *sname = qname_schema(se->data.lval); char *res; if (!sname) sname = sql->session->schema->base.name; + sname = symbol_escape_ident(sql->ta, sname); if ((res = SA_NEW_ARRAY(sql->ta, char, strlen("next value for \"") + strlen(sname) + strlen(seq) + 5))) stpcpy(stpcpy(stpcpy(stpcpy(stpcpy(res, "next value for \""), sname), "\".\""), seq), "\""); @@ -1051,14 +1076,16 @@ char * assert(l->h->type != type_lng); if (expression && dlist_length(l) == 1 && l->h->type == type_string) { /* when compiling an expression, a column of a table might be present in the symbol, so we need this case */ - const char *op = l->h->data.sval; + const char *op = symbol_escape_ident(sql->ta, l->h->data.sval); char *res; if ((res = SA_NEW_ARRAY(sql->ta, char, strlen(op) + 3))) stpcpy(stpcpy(stpcpy(res, "\""), op), "\""); return res; } else if (expression && dlist_length(l) == 2 && l->h->type == type_string && l->h->next->type == type_string) { - char *first = l->h->data.sval, *second = l->h->next->data.sval, *res; + const char *first = symbol_escape_ident(sql->ta, l->h->data.sval), + *second = symbol_escape_ident(sql->ta, l->h->next->data.sval); + char *res; if (!first || !second) return NULL; diff --git a/sql/storage/store.c b/sql/storage/store.c --- a/sql/storage/store.c +++ b/sql/storage/store.c @@ -5510,27 +5510,26 @@ sys_drop_statistics(sql_trans *tr, sql_c static int sys_drop_default_object(sql_trans *tr, sql_column *col, int drop_action) { - char *seq_pos = NULL; - const char *next_value_for = "next value for \"sys\".\"seq_"; - sql_schema *syss = find_sql_schema(tr, isGlobal(col->t)?"sys":"tmp"); + const char *next_value_for = "next value for "; /* Drop sequence for generated column if it's the case */ - if (col->def && (seq_pos = strstr(col->def, next_value_for))) { + if (col->def && !strncmp(col->def, next_value_for, strlen(next_value_for))) { + sql_schema *s = NULL; sql_sequence *seq = NULL; - char *seq_name = _STRDUP(seq_pos + (strlen(next_value_for) - strlen("seq_"))); node *n = NULL; - _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list