From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from localhost (localhost [127.0.0.1]) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTP id 92A9D228B4 for ; Wed, 25 Jul 2018 08:58:14 -0400 (EDT) Received: from turing.freelists.org ([127.0.0.1]) by localhost (turing.freelists.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id gKffq_yXmNQH for ; Wed, 25 Jul 2018 08:58:14 -0400 (EDT) Received: from smtp43.i.mail.ru (smtp43.i.mail.ru [94.100.177.103]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTPS id E616E22878 for ; Wed, 25 Jul 2018 08:58:13 -0400 (EDT) Content-Type: text/plain; charset=utf-8 Mime-Version: 1.0 (Mac OS X Mail 10.3 \(3273\)) Subject: [tarantool-patches] Re: [PATCH v1 1/1] sql: introduce TRUNCATE TABLE operation From: "n.pettik" In-Reply-To: <2ec56870-e8cb-6112-f12a-a654f59315dc@tarantool.org> Date: Wed, 25 Jul 2018 15:58:10 +0300 Content-Transfer-Encoding: quoted-printable Message-Id: <28A6DE0C-68D4-4155-BB94-ACD742757291@tarantool.org> References: <70326bb69fbe25215df79e2d5e01043f93ff7c5a.1531902074.git.kshcherbatov@tarantool.org> <797d52e5-1387-dd3d-1fb2-0fafbbbdcf56@tarantool.org> <606f657b-26df-35b9-ddf1-d5bae5654d82@tarantool.org> <119B20FA-F3FD-484C-A17E-0B63131CC4DE@tarantool.org> <43f1d131-3e6a-1791-758e-e39b0a605c29@tarantool.org> <4ED1247F-9E59-4C2F-AF92-556D7D93DCD5@tarantool.org> <2ec56870-e8cb-6112-f12a-a654f59315dc@tarantool.org> Sender: tarantool-patches-bounce@freelists.org Errors-to: tarantool-patches-bounce@freelists.org Reply-To: tarantool-patches@freelists.org List-help: List-unsubscribe: List-software: Ecartis version 1.0.0 List-Id: tarantool-patches List-subscribe: List-owner: List-post: List-archive: To: tarantool-patches@freelists.org Cc: Kirill Shcherbatov Except for comments below, also pls add to tarantool-doc bot request notice concerning the fact that in our implementation TRUNCATE is DDL = operation. > diff --git a/extra/mkkeywordhash.c b/extra/mkkeywordhash.c > index 1ec1538..705caf1 100644 > --- a/extra/mkkeywordhash.c > +++ b/extra/mkkeywordhash.c > @@ -281,6 +281,7 @@ static Keyword aKeywordTable[] =3D { > { "VARCHAR", "TK_ID", RESERVED, true = }, > { "WHENEVER", "TK_STANDARD", RESERVED, true = }, > { "WHILE", "TK_STANDARD", RESERVED, true = }, > + { "TRUNCATE", "TK_TRUNCATE", ALWAYS, = true }, > }; >=20 > /* Number of keywords */ > diff --git a/src/box/sql/delete.c b/src/box/sql/delete.c > index 0681177..b016084 100644 > --- a/src/box/sql/delete.c > +++ b/src/box/sql/delete.c > @@ -72,6 +72,62 @@ sql_materialize_view(struct Parse *parse, const = char *name, struct Expr *where, > } >=20 > void > +sql_table_truncate(struct Parse *parse, struct SrcList *tab_list) > +{ > + struct sqlite3 *db =3D parse->db; > + if (parse->nErr || db->mallocFailed) > + goto cleanup; Is this check reasonable? > + assert(tab_list->nSrc =3D=3D 1); > + > + struct Vdbe *v =3D sqlite3GetVdbe(parse); > + if (v =3D=3D NULL) > + goto cleanup; > + > + const char *tab_name =3D tab_list->a->zName; > + struct Table *table =3D sqlite3LocateTable(parse, LOCATE_NOERR, = tab_name); I guess here you can explicitly use space_by_id and box_space_id_by_name to bypass table hash. If you do so, you will be able to get rid off=20 if (table =3D=3D NULL) branch. > + struct space_def *space_def =3D NULL; > + if (table =3D=3D NULL) { > + /* Space created with LUA. */ > + uint32_t space_id =3D > + box_space_id_by_name(tab_name, = strlen(tab_name)); > + if (space_id =3D=3D BOX_ID_NIL) { > + diag_set(ClientError, ER_NO_SUCH_SPACE, = tab_name); > + parse->rc =3D SQL_TARANTOOL_ERROR; > + parse->nErr++; During exception handling you three times process parse->rc =3D SQL_TARANTOOL_ERROR; parse->nErr++; Lets use separate label for this purpose. > + goto cleanup; > + } > + struct space *space =3D space_cache_find(space_id); > + assert(space !=3D NULL); > + space_def =3D space->def; > + } else { > + space_def =3D table->def; > + if (sqlite3FkRequired(table, NULL) !=3D 0) { sqlite3FkRequired is too strict condition. I guess you are still capable of truncating child (or referencing) table, since no FK violations may take place in this case. So, what you need is simple check: sqlite3References() !=3D NULL; > + const char *err_msg =3D > + tt_sprintf("cannot truncate %s because = it has " > + "foreign keys=E2=80=9D); Lets add =E2=80=99space=E2=80=99 or =E2=80=99table' word to message to = avoid confusing: =E2=80=9Ccan no truncate table %s becase other objects depend on it=E2=80=9D= OR =E2=80=9Ccan no truncate table %s becase other objects reference it=E2=80=9D= > + diag_set(ClientError, ER_SQL, err_msg); > + parse->rc =3D SQL_TARANTOOL_ERROR; > + parse->nErr++; > + goto cleanup; > + } > + } > + assert(space_def !=3D NULL); > + if (space_def->opts.is_view) { > + const char *err_msg =3D > + tt_sprintf("cannot truncate %s because it is a = view", > + space_def->name); > + diag_set(ClientError, ER_SQL, err_msg); > + parse->rc =3D SQL_TARANTOOL_ERROR; > + parse->nErr++; > + goto cleanup; > + } > + sqlite3VdbeAddOp2(v, OP_Clear, space_def->id, true); > + > +cleanup: > + sqlite3SrcListDelete(parse->db, tab_list); > +} > + > +void > sql_table_delete_from(struct Parse *parse, struct SrcList *tab_list, > struct Expr *where) > { >=20 > diff --git a/src/box/sql/sqliteInt.h b/src/box/sql/sqliteInt.h > index 07e7829..a90b10e 100644 > --- a/src/box/sql/sqliteInt.h > +++ b/src/box/sql/sqliteInt.h > @@ -3710,11 +3710,22 @@ void sqlite3OpenTable(Parse *, int iCur, Table = *, int); > * @param tab_list List of single element which table from which > * deletetion if performed. > * @param where The WHERE clause. May be NULL. > + * @param is_truncate use OP_Clear to truncate table. This comment is remained from previous patch version, I guess. > --- a/test/sql/delete.test.lua > +++ b/test/sql/delete.test.lua > @@ -37,3 +37,42 @@ box.sql.execute("CREATE TRIGGER t2 BEFORE INSERT ON = t2 BEGIN DELETE FROM t1; END > box.sql.execute("INSERT INTO t2 VALUES (0);") >=20 > box.sql.execute("DROP TABLE t2;") > + > + > +-- > +-- gh-2201: TRUNCATE TABLE operation > +-- > + > +-- can't truncate system table Pls start comments (even in tests) from capital letter and end with dot. > +box.sql.execute("TRUNCATE TABLE \"_sql_stat1\";") > + > +box.sql.execute("CREATE TABLE t1(id INTEGER PRIMARY KEY, a, b);=E2=80=9D= ) Specify types for all columns. Static typing is on the way.