From: "n.pettik" <korablev@tarantool.org> To: tarantool-patches@freelists.org Cc: Ivan Koptelov <ivan.koptelov@tarantool.org> Subject: [tarantool-patches] Re: [PATCH v2] sql: add index_def to struct Index Date: Fri, 13 Jul 2018 22:19:08 +0300 [thread overview] Message-ID: <513397CB-4A4B-4C7D-A0C9-249000100E03@tarantool.org> (raw) In-Reply-To: <0566bdde-5972-6c5e-707d-0ad58b6b45da@tarantool.org> [-- Attachment #1: Type: text/plain, Size: 8016 bytes --] > + /* > + * Here we handle cases like > + * CREATE TABLE t1(a UNIQUE, PRIMARY KEY(a)) > + * In these cases (where UNIQUE constraints precede > + * PRIMARY constraint) appropriate Index->def->cmp_def > + * can not be set 'on the fly' for indexes implementing > + * UNIQUE constraints as PK key_def is missing and > + * needed for it. > + * At this point we can set appropriate cmp_def, since > + * all indexes (from CREATE TABLE statement) is created. > + */ > + if (!p->def->opts.is_view) { > + assert(p->pIndex != NULL); > + struct Index *pk; > + for (struct Index *idx = p->pIndex; idx != NULL; > + idx = idx->pNext) { > + if (idx->index_type == SQL_INDEX_TYPE_CONSTRAINT_PK) > + pk = idx; > + } > + struct key_def *pk_def = pk->def->key_def; > + > + for (struct Index *idx = p->pIndex; idx != NULL; > + idx = idx->pNext) { > + if (idx->index_type != SQL_INDEX_TYPE_CONSTRAINT_PK) { > + struct index_def *def = idx->def; > + struct key_def *cmp_def = > + key_def_merge(def->key_def, > + pk_def); > + if (cmp_def == NULL) { > + pParse->rc = SQL_TARANTOOL_ERROR; > + ++pParse->nErr; > + return; > + } > + if (!def->opts.is_unique) { > + def->cmp_def->unique_part_count = > + def->cmp_def->part_count; > + } else { > + def->cmp_def->unique_part_count = > + def->key_def->part_count; > + } > + } > + } > + } I don’t understand: why do you need at all this cmp_def? In SQL it is extremely unlikely to be useful. > if (db->init.busy) { > /* > * As rebuild creates a new ExpList tree and > @@ -2398,8 +2441,7 @@ > struct Index * > sql_index_alloc(struct sqlite3 *db) > { > - int index_size = ROUND8(sizeof(struct Index)); > - struct Index *p = sqlite3DbMallocZero(db, index_size); > + struct Index *p = sqlite3DbMallocZero(db, sizeof(struct Index)); > return p; > } > > @@ -2566,12 +2608,25 @@ > if (parse->nErr > 0) > goto cleanup; > > - struct key_def *pk_key_def; > - if (idx_type == SQL_INDEX_TYPE_UNIQUE || > - idx_type == SQL_INDEX_TYPE_NON_UNIQUE) > + struct key_def *pk_key_def = NULL; > + if (idx_type != SQL_INDEX_TYPE_CONSTRAINT_PK && > + parse->pNewTable == NULL) > pk_key_def = table->pIndex->def->key_def; > - else > - pk_key_def = NULL; > + /* > + * In cases like CREATE TABLE t1(a UNIQUE, PRIMARY KEY(a)) > + * fill_index_def() will be firstly executed for creating > + * index_def for UNIQUE constraint and then for creating > + * index_def for PRIMARY KEY constraint. So when > + * fill_index_def will be called for UNIQUE constraint > + * there will be no PK, while PK->def->key_def is needed > + * to create cmp_def (inside index_def_new()). Again: explain pls why do you need cmp_def on client-side (i.e. parser)? > To handle > + * this case we set here pk_key_def to key_def and later > + * in sqlite3EndTable (when PK index is already created) > + * we go over all indexes and set appropriate cmp_def in > + * them. > + */ > + if (parse->pNewTable != NULL) > + pk_key_def = key_def; > > index->def = index_def_new(space_def->id, iid, name, name_len, TREE, > &opts, key_def, pk_key_def); > @@ -2618,12 +2673,6 @@ > */ > struct Table *table = NULL; > if (tbl_name != NULL) { > - /* > - * Use the two-part index name to determine the > - * database to search for the table. 'Fix' the > - * table name to this db before looking up the > - * table. > - */ > assert(token != NULL && token->z != NULL); > table = sqlite3LocateTable(parse, 0, tbl_name->a[0].zName); > assert(db->mallocFailed == 0 || table == NULL); > @@ -2642,7 +2691,7 @@ > } > /* > * Find the name of the index. Make sure there is not > - * already another index or table with the same name. > + * already another index with the same name. > * > * Exception: If we are reading the names of permanent > * indices from the Tarantool schema (because some other > @@ -2660,7 +2709,7 @@ > * 2) UNIQUE constraint is non-named and standard > * auto-index name will be generated. > */ > - bool is_constraint_named = false; > + bool is_constraint_named; > if (token != NULL) { > name = sqlite3NameFromToken(db, token); > if (name == NULL) > @@ -2691,14 +2740,26 @@ > } > name = sqlite3MPrintf(db, "sql_autoindex_%s_%d", > table->def->name, n); > + is_constraint_named = false; > } else { > - name = sqlite3MPrintf(db, "sql_autoindex_%s", > - constraint_name); > + /* > + * This naming is temporary. Now it's not > + * possible (since we implement UNIQUE > + * and PK constraints with indexes and > + * indexes can not have same names), but > + * in future we would use names exactly > + * as they are set by user. > + */ > + if (idx_type == SQL_INDEX_TYPE_CONSTRAINT_UNIQUE) > + name = sqlite3MPrintf(db, > + "unique_constraint_%s", > + constraint_name); > + if (idx_type == SQL_INDEX_TYPE_CONSTRAINT_PK) > + name = sqlite3MPrintf(db, "pk_constraint_%s", > + constraint_name); > is_constraint_named = true; > } > - if (constraint_name != NULL) { > - sqlite3DbFree(db, constraint_name); > - } > + sqlite3DbFree(db, constraint_name); > } > > if (name == NULL) > @@ -2708,7 +2769,8 @@ > table->def->id < BOX_SYSTEM_ID_MAX; > if (is_system_space && (idx_type == SQL_INDEX_TYPE_NON_UNIQUE || > idx_type == SQL_INDEX_TYPE_UNIQUE)) { > - diag_set(ClientError, ER_MODIFY_INDEX, name, table->def->name, > + diag_set(ClientError, ER_MODIFY_INDEX, name, > + table->def->name, > "can't create index on system space"); > parse->nErr++; > parse->rc = SQL_TARANTOOL_ERROR; > @@ -2745,7 +2807,7 @@ > > index->pTable = table; > index->onError = (u8) on_error; > - index->index_type = idx_type; > + index->index_type = idx_type; > index->pSchema = db->pSchema; > /* Tarantool have access to each column by any index. */ > if (where != NULL) { > @@ -2775,8 +2837,22 @@ > goto exit_create_index; > } > > - /* If it is parsing stage, then iid may have any value. */ > - uint32_t iid = 1; > + /* > + * We set no SQL statement for indexes created during > + * CREATE TABLE statement. Instead we use > + * Index->index_def->opts.sql to store information if > + * this index implements named or non-named constraint. > + */ > + if (tbl_name == NULL && > + idx_type == SQL_INDEX_TYPE_CONSTRAINT_UNIQUE) If idx_type == SQL_INDEX_TYPE_CONSTRAINT_UNIQUE than tbl_name must be NULL: you can’t declare unique constraint outside CREATE TABLE statement. > + sql_stmt = is_constraint_named ? > + "named constraint" : "non-named constraint”; You can set ‘sql_stmt’ only for name constraints: sql_stmt = is_constraint_name ? “_named_constr” : “”; And use strncmp when comparing with it. Also, if <if-clause> contains mode than one row, we wrap it in brackets. > + > + /* > + * If it is parsing stage, then iid may have any value, > + * but PK still must have iid == 0 > + */ > + uint32_t iid = idx_type == SQL_INDEX_TYPE_CONSTRAINT_PK ? 0 : 1; > if (db->init.busy) > iid = SQLITE_PAGENO_TO_INDEXID(db->init.newTnum); You can just do this: uint32_t iid = idx_type == SQL_INDEX_TYPE_CONSTRAINT_PK; > + > + if (k != key_def->part_count) > + continue; > + > + if (index->onError != existing_idx->onError) { > + if (index->onError != > + ON_CONFLICT_ACTION_DEFAULT && > + existing_idx->onError != > + ON_CONFLICT_ACTION_DEFAULT) > + sqlite3ErrorMsg(parse, > + "conflicting "\ > + "ON CONFLICT "\ > + "clauses specified”); Again: here you have already set error. What is the reason to continue process smth? You are able to go to exit_create_index. [-- Attachment #2: Type: text/html, Size: 10540 bytes --]
next prev parent reply other threads:[~2018-07-13 19:19 UTC|newest] Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-07-09 10:46 Ivan Koptelov 2018-07-12 11:18 ` n.pettik 2018-07-13 15:58 ` Ivan Koptelov 2018-07-13 19:19 ` n.pettik [this message] 2018-07-16 5:54 ` Ivan Koptelov 2018-07-17 1:22 ` n.pettik 2018-07-17 11:21 ` Kirill Yukhin -- strict thread matches above, loose matches on Subject: below -- 2018-07-09 0:31 Ivan Koptelov 2018-06-13 7:30 [tarantool-patches] Re: [PATCH v3] " Ivan Koptelov 2018-06-18 18:45 ` Kirill Shcherbatov 2018-06-21 12:57 ` [tarantool-patches] Re: [PATCH v4] " Ivan Koptelov 2018-06-22 8:46 ` Kirill Shcherbatov 2018-06-27 17:46 ` [tarantool-patches] Re: [PATCH v5] " Ivan Koptelov 2018-06-27 17:57 ` Kirill Shcherbatov 2018-06-28 18:49 ` Vladislav Shpilevoy 2018-06-29 13:49 ` [tarantool-patches] Re: [PATCH v6] " Ivan Koptelov 2018-06-29 20:46 ` Vladislav Shpilevoy 2018-07-03 11:37 ` [tarantool-patches] Re: [PATCH v9] " Ivan Koptelov 2018-07-03 23:54 ` n.pettik 2018-07-04 15:55 ` [tarantool-patches] Re: [PATCH v11] " Ivan Koptelov 2018-07-04 19:28 ` n.pettik 2018-07-05 14:50 ` Ivan Koptelov 2018-07-06 0:51 ` n.pettik 2018-07-08 14:17 ` [tarantool-patches] Re: [PATCH v2] " Ivan Koptelov
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=513397CB-4A4B-4C7D-A0C9-249000100E03@tarantool.org \ --to=korablev@tarantool.org \ --cc=ivan.koptelov@tarantool.org \ --cc=tarantool-patches@freelists.org \ --subject='[tarantool-patches] Re: [PATCH v2] sql: add index_def to struct Index' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox