<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <p>Thank you for review! Diff between two last patches and new patch<br>
      below.<br>
    </p>
    <br>
    <div class="moz-cite-prefix">On 10/11/2018 06:09 PM, n.pettik wrote:<br>
    </div>
    <blockquote type="cite"
      cite="mid:A38890C9-9974-4677-AFED-E6D0C3FBDD8F@tarantool.org">
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
      <div><br class="">
        <blockquote type="cite" class="">
          <div class="">
            <blockquote type="cite"
              cite="mid:1AF44E5C-F76B-4783-8578-FC4AFA437E66@tarantool.org"
              style="font-family: Helvetica; font-size: 12px;
              font-style: normal; font-variant-caps: normal;
              font-weight: normal; letter-spacing: normal; orphans:
              auto; text-align: start; text-indent: 0px; text-transform:
              none; white-space: normal; widows: auto; word-spacing:
              0px; -webkit-text-size-adjust: auto;
              -webkit-text-stroke-width: 0px; background-color: rgb(255,
              255, 255);" class="">
              <blockquote type="cite" class="">
                <pre class="" wrap="">+--
+-- Check that _space, _index and _sequence have the same number of
+-- records.
+--
+space_count == #box.space._space:select()
+index_count == #box.space._index:select()
+sequence_count == #box.space._sequence:select()
+
+box.schema.user.drop('tmp’)
</pre>
              </blockquote>
              <pre class="" wrap="">I see no tests involving FK constraints. Add them as well.

</pre>
            </blockquote>
            <span style="font-family: Helvetica; font-size: 12px;
              font-style: normal; font-variant-caps: normal;
              font-weight: normal; letter-spacing: normal; text-align:
              start; text-indent: 0px; text-transform: none;
              white-space: normal; word-spacing: 0px;
              -webkit-text-stroke-width: 0px; background-color: rgb(255,
              255, 255); float: none; display: inline !important;"
              class="">Added.</span><br style="font-family: Helvetica;
              font-size: 12px; font-style: normal; font-variant-caps:
              normal; font-weight: normal; letter-spacing: normal;
              text-align: start; text-indent: 0px; text-transform: none;
              white-space: normal; word-spacing: 0px;
              -webkit-text-stroke-width: 0px; background-color: rgb(255,
              255, 255);" class="">
          </div>
        </blockquote>
        <div><br class="">
        </div>
        <br class="">
        <blockquote type="cite" class="">
          <div class=""><span style="font-family: Helvetica; font-size:
              12px; font-style: normal; font-variant-caps: normal;
              font-weight: normal; letter-spacing: normal; text-align:
              start; text-indent: 0px; text-transform: none;
              white-space: normal; word-spacing: 0px;
              -webkit-text-stroke-width: 0px; background-color: rgb(255,
              255, 255); float: none; display: inline !important;"
              class="">diff --git a/test/sql/drop-table.test.lua
              b/test/sql/drop-table.test.lua</span><br
              style="font-family: Helvetica; font-size: 12px;
              font-style: normal; font-variant-caps: normal;
              font-weight: normal; letter-spacing: normal; text-align:
              start; text-indent: 0px; text-transform: none;
              white-space: normal; word-spacing: 0px;
              -webkit-text-stroke-width: 0px; background-color: rgb(255,
              255, 255);" class="">
            <span style="font-family: Helvetica; font-size: 12px;
              font-style: normal; font-variant-caps: normal;
              font-weight: normal; letter-spacing: normal; text-align:
              start; text-indent: 0px; text-transform: none;
              white-space: normal; word-spacing: 0px;
              -webkit-text-stroke-width: 0px; background-color: rgb(255,
              255, 255); float: none; display: inline !important;"
              class="">index 1bc8894..f86e3d8 100644</span><br
              style="font-family: Helvetica; font-size: 12px;
              font-style: normal; font-variant-caps: normal;
              font-weight: normal; letter-spacing: normal; text-align:
              start; text-indent: 0px; text-transform: none;
              white-space: normal; word-spacing: 0px;
              -webkit-text-stroke-width: 0px; background-color: rgb(255,
              255, 255);" class="">
            <span style="font-family: Helvetica; font-size: 12px;
              font-style: normal; font-variant-caps: normal;
              font-weight: normal; letter-spacing: normal; text-align:
              start; text-indent: 0px; text-transform: none;
              white-space: normal; word-spacing: 0px;
              -webkit-text-stroke-width: 0px; background-color: rgb(255,
              255, 255); float: none; display: inline !important;"
              class="">--- a/test/sql/drop-table.test.lua</span><br
              style="font-family: Helvetica; font-size: 12px;
              font-style: normal; font-variant-caps: normal;
              font-weight: normal; letter-spacing: normal; text-align:
              start; text-indent: 0px; text-transform: none;
              white-space: normal; word-spacing: 0px;
              -webkit-text-stroke-width: 0px; background-color: rgb(255,
              255, 255);" class="">
            <span style="font-family: Helvetica; font-size: 12px;
              font-style: normal; font-variant-caps: normal;
              font-weight: normal; letter-spacing: normal; text-align:
              start; text-indent: 0px; text-transform: none;
              white-space: normal; word-spacing: 0px;
              -webkit-text-stroke-width: 0px; background-color: rgb(255,
              255, 255); float: none; display: inline !important;"
              class="">+++ b/test/sql/drop-table.test.lua</span><br
              style="font-family: Helvetica; font-size: 12px;
              font-style: normal; font-variant-caps: normal;
              font-weight: normal; letter-spacing: normal; text-align:
              start; text-indent: 0px; text-transform: none;
              white-space: normal; word-spacing: 0px;
              -webkit-text-stroke-width: 0px; background-color: rgb(255,
              255, 255);" class="">
            <br style="font-family: Helvetica; font-size: 12px;
              font-style: normal; font-variant-caps: normal;
              font-weight: normal; letter-spacing: normal; text-align:
              start; text-indent: 0px; text-transform: none;
              white-space: normal; word-spacing: 0px;
              -webkit-text-stroke-width: 0px; background-color: rgb(255,
              255, 255);" class="">
            <span style="font-family: Helvetica; font-size: 12px;
              font-style: normal; font-variant-caps: normal;
              font-weight: normal; letter-spacing: normal; text-align:
              start; text-indent: 0px; text-transform: none;
              white-space: normal; word-spacing: 0px;
              -webkit-text-stroke-width: 0px; background-color: rgb(255,
              255, 255); float: none; display: inline !important;"
              class="">+-- Give user right to write in _sequence. Still
              have not enough</span><br style="font-family: Helvetica;
              font-size: 12px; font-style: normal; font-variant-caps:
              normal; font-weight: normal; letter-spacing: normal;
              text-align: start; text-indent: 0px; text-transform: none;
              white-space: normal; word-spacing: 0px;
              -webkit-text-stroke-width: 0px; background-color: rgb(255,
              255, 255);" class="">
            <span style="font-family: Helvetica; font-size: 12px;
              font-style: normal; font-variant-caps: normal;
              font-weight: normal; letter-spacing: normal; text-align:
              start; text-indent: 0px; text-transform: none;
              white-space: normal; word-spacing: 0px;
              -webkit-text-stroke-width: 0px; background-color: rgb(255,
              255, 255); float: none; display: inline !important;"
              class="">+-- rights to write in _fk_constraint.</span><br
              style="font-family: Helvetica; font-size: 12px;
              font-style: normal; font-variant-caps: normal;
              font-weight: normal; letter-spacing: normal; text-align:
              start; text-indent: 0px; text-transform: none;
              white-space: normal; word-spacing: 0px;
              -webkit-text-stroke-width: 0px; background-color: rgb(255,
              255, 255);" class="">
            <span style="font-family: Helvetica; font-size: 12px;
              font-style: normal; font-variant-caps: normal;
              font-weight: normal; letter-spacing: normal; text-align:
              start; text-indent: 0px; text-transform: none;
              white-space: normal; word-spacing: 0px;
              -webkit-text-stroke-width: 0px; background-color: rgb(255,
              255, 255); float: none; display: inline !important;"
              class="">+--</span><br style="font-family: Helvetica;
              font-size: 12px; font-style: normal; font-variant-caps:
              normal; font-weight: normal; letter-spacing: normal;
              text-align: start; text-indent: 0px; text-transform: none;
              white-space: normal; word-spacing: 0px;
              -webkit-text-stroke-width: 0px; background-color: rgb(255,
              255, 255);" class="">
            <span style="font-family: Helvetica; font-size: 12px;
              font-style: normal; font-variant-caps: normal;
              font-weight: normal; letter-spacing: normal; text-align:
              start; text-indent: 0px; text-transform: none;
              white-space: normal; word-spacing: 0px;
              -webkit-text-stroke-width: 0px; background-color: rgb(255,
              255, 255); float: none; display: inline !important;"
              class="">+box.schema.user.grant('tmp', 'write', 'space',
              '_sequence')</span><br style="font-family: Helvetica;
              font-size: 12px; font-style: normal; font-variant-caps:
              normal; font-weight: normal; letter-spacing: normal;
              text-align: start; text-indent: 0px; text-transform: none;
              white-space: normal; word-spacing: 0px;
              -webkit-text-stroke-width: 0px; background-color: rgb(255,
              255, 255);" class="">
            <span style="font-family: Helvetica; font-size: 12px;
              font-style: normal; font-variant-caps: normal;
              font-weight: normal; letter-spacing: normal; text-align:
              start; text-indent: 0px; text-transform: none;
              white-space: normal; word-spacing: 0px;
              -webkit-text-stroke-width: 0px; background-color: rgb(255,
              255, 255); float: none; display: inline !important;"
              class="">+box.session.su('tmp')</span><br
              style="font-family: Helvetica; font-size: 12px;
              font-style: normal; font-variant-caps: normal;
              font-weight: normal; letter-spacing: normal; text-align:
              start; text-indent: 0px; text-transform: none;
              white-space: normal; word-spacing: 0px;
              -webkit-text-stroke-width: 0px; background-color: rgb(255,
              255, 255);" class="">
            <span style="font-family: Helvetica; font-size: 12px;
              font-style: normal; font-variant-caps: normal;
              font-weight: normal; letter-spacing: normal; text-align:
              start; text-indent: 0px; text-transform: none;
              white-space: normal; word-spacing: 0px;
              -webkit-text-stroke-width: 0px; background-color: rgb(255,
              255, 255); float: none; display: inline !important;"
              class="">+</span><br style="font-family: Helvetica;
              font-size: 12px; font-style: normal; font-variant-caps:
              normal; font-weight: normal; letter-spacing: normal;
              text-align: start; text-indent: 0px; text-transform: none;
              white-space: normal; word-spacing: 0px;
              -webkit-text-stroke-width: 0px; background-color: rgb(255,
              255, 255);" class="">
            <span style="font-family: Helvetica; font-size: 12px;
              font-style: normal; font-variant-caps: normal;
              font-weight: normal; letter-spacing: normal; text-align:
              start; text-indent: 0px; text-transform: none;
              white-space: normal; word-spacing: 0px;
              -webkit-text-stroke-width: 0px; background-color: rgb(255,
              255, 255); float: none; display: inline !important;"
              class="">+box.sql.execute('CREATE TABLE t3(a INTEGER
              PRIMARY KEY);')</span><br style="font-family: Helvetica;
              font-size: 12px; font-style: normal; font-variant-caps:
              normal; font-weight: normal; letter-spacing: normal;
              text-align: start; text-indent: 0px; text-transform: none;
              white-space: normal; word-spacing: 0px;
              -webkit-text-stroke-width: 0px; background-color: rgb(255,
              255, 255);" class="">
            <span style="font-family: Helvetica; font-size: 12px;
              font-style: normal; font-variant-caps: normal;
              font-weight: normal; letter-spacing: normal; text-align:
              start; text-indent: 0px; text-transform: none;
              white-space: normal; word-spacing: 0px;
              -webkit-text-stroke-width: 0px; background-color: rgb(255,
              255, 255); float: none; display: inline !important;"
              class="">+--</span><br style="font-family: Helvetica;
              font-size: 12px; font-style: normal; font-variant-caps:
              normal; font-weight: normal; letter-spacing: normal;
              text-align: start; text-indent: 0px; text-transform: none;
              white-space: normal; word-spacing: 0px;
              -webkit-text-stroke-width: 0px; background-color: rgb(255,
              255, 255);" class="">
            <span style="font-family: Helvetica; font-size: 12px;
              font-style: normal; font-variant-caps: normal;
              font-weight: normal; letter-spacing: normal; text-align:
              start; text-indent: 0px; text-transform: none;
              white-space: normal; word-spacing: 0px;
              -webkit-text-stroke-width: 0px; background-color: rgb(255,
              255, 255); float: none; display: inline !important;"
              class="">+-- Error: user do not have rights to write in
              _fk_constraint.</span><br style="font-family: Helvetica;
              font-size: 12px; font-style: normal; font-variant-caps:
              normal; font-weight: normal; letter-spacing: normal;
              text-align: start; text-indent: 0px; text-transform: none;
              white-space: normal; word-spacing: 0px;
              -webkit-text-stroke-width: 0px; background-color: rgb(255,
              255, 255);" class="">
            <span style="font-family: Helvetica; font-size: 12px;
              font-style: normal; font-variant-caps: normal;
              font-weight: normal; letter-spacing: normal; text-align:
              start; text-indent: 0px; text-transform: none;
              white-space: normal; word-spacing: 0px;
              -webkit-text-stroke-width: 0px; background-color: rgb(255,
              255, 255); float: none; display: inline !important;"
              class="">+--</span><br style="font-family: Helvetica;
              font-size: 12px; font-style: normal; font-variant-caps:
              normal; font-weight: normal; letter-spacing: normal;
              text-align: start; text-indent: 0px; text-transform: none;
              white-space: normal; word-spacing: 0px;
              -webkit-text-stroke-width: 0px; background-color: rgb(255,
              255, 255);" class="">
            <span style="font-family: Helvetica; font-size: 12px;
              font-style: normal; font-variant-caps: normal;
              font-weight: normal; letter-spacing: normal; text-align:
              start; text-indent: 0px; text-transform: none;
              white-space: normal; word-spacing: 0px;
              -webkit-text-stroke-width: 0px; background-color: rgb(255,
              255, 255); float: none; display: inline !important;"
              class="">+box.sql.execute('CREATE TABLE t4(x INTEGER
              PRIMARY KEY REFERENCES t3);')</span><br
              style="font-family: Helvetica; font-size: 12px;
              font-style: normal; font-variant-caps: normal;
              font-weight: normal; letter-spacing: normal; text-align:
              start; text-indent: 0px; text-transform: none;
              white-space: normal; word-spacing: 0px;
              -webkit-text-stroke-width: 0px; background-color: rgb(255,
              255, 255);" class="">
            <span style="font-family: Helvetica; font-size: 12px;
              font-style: normal; font-variant-caps: normal;
              font-weight: normal; letter-spacing: normal; text-align:
              start; text-indent: 0px; text-transform: none;
              white-space: normal; word-spacing: 0px;
              -webkit-text-stroke-width: 0px; background-color: rgb(255,
              255, 255); float: none; display: inline !important;"
              class="">+box.sql.execute('DROP TABLE t3;’)</span><br
              style="font-family: Helvetica; font-size: 12px;
              font-style: normal; font-variant-caps: normal;
              font-weight: normal; letter-spacing: normal; text-align:
              start; text-indent: 0px; text-transform: none;
              white-space: normal; word-spacing: 0px;
              -webkit-text-stroke-width: 0px; background-color: rgb(255,
              255, 255);" class="">
          </div>
        </blockquote>
        <div><br class="">
        </div>
        <div>You misunderstood me a bit. I mean following test:</div>
        <div><span style="background-color: rgb(255, 255, 255);"
            class=""><br class="">
          </span></div>
        <div>fk_count = <span style="background-color: rgb(255, 255,
            255);" class="">#box.space._fk_constraints:select()</span></div>
        <div><span style="background-color: rgb(255, 255, 255);"
            class=""><br class="">
          </span></div>
        <div><span style="background-color: rgb(255, 255, 255);"
            class="">box.sql.execute('CREATE TABLE t4(x INTEGER PRIMARY
            KEY REFERENCES t3, a INT UNIQUE, c INT REFERENCES t3);’)</span></div>
        <div><span style="background-color: rgb(255, 255, 255);"
            class=""><br class="">
          </span></div>
        <div><span style="background-color: rgb(255, 255, 255);"
            class="">Here creation of last FK fails - for instance due
            to type mismatch.</span></div>
        <div><span style="background-color: rgb(255, 255, 255);"
            class="">Then, number of created FK constraints (and
            indexes) should be unchanged:</span></div>
        <div><span style="background-color: rgb(255, 255, 255);"
            class=""><br class="">
          </span></div>
        <div>fk_count == <span style="background-color: rgb(255, 255,
            255);" class="">#box.space._fk_constraints:select()</span></div>
        <div><span style="background-color: rgb(255, 255, 255);"
            class="">index_count == </span><span
            style="background-color: rgb(255, 255, 255);" class="">#box.space._fk_constraints:select()</span></div>
        <div><br class="">
        </div>
        <div>Note that FK constraints are created after indexes.</div>
        <div><br class="">
        </div>
      </div>
    </blockquote>
    Fixed - changed last test.<br>
    <br>
    <b>Diff between last two patches:</b><br>
    <br>
    diff --git a/test/sql/drop-table.result b/test/sql/drop-table.result<br>
    index 43da275..297799e 100644<br>
    --- a/test/sql/drop-table.result<br>
    +++ b/test/sql/drop-table.result<br>
    @@ -132,11 +132,13 @@ sequence_count ==
    #box.space._sequence:select()<br>
     ---<br>
     - true<br>
     ...<br>
    +fk_constraint_count = #box.space._fk_constraint:select()<br>
    +---<br>
    +...<br>
     --<br>
    --- Give user right to write in _sequence. Still have not enough<br>
    --- rights to write in _fk_constraint.<br>
    +-- Check that clean-up works fine after another error.<br>
     --<br>
    -box.schema.user.grant('tmp', 'write', 'space', '_sequence')<br>
    +box.schema.user.grant('tmp', 'write', 'space')<br>
     ---<br>
     ...<br>
     box.session.su('tmp')<br>
    @@ -146,18 +148,16 @@ box.sql.execute('CREATE TABLE t3(a INTEGER
    PRIMARY KEY);')<br>
     ---<br>
     ...<br>
     --<br>
    --- Error: user do not have rights to write in _fk_constraint.<br>
    +-- Error: Failed to create foreign key constraint.<br>
     --<br>
    -box.sql.execute('CREATE TABLE t4(x INTEGER PRIMARY KEY REFERENCES
    t3);')<br>
    +box.sql.execute('CREATE TABLE t4(x INTEGER PRIMARY KEY REFERENCES
    t3, a INT UNIQUE, c INT REFERENCES t3);')<br>
     ---<br>
    -- error: Write access to space '_fk_constraint' is denied for user
    'tmp'<br>
    +- error: 'Failed to create foreign key constraint
    ''FK_CONSTRAINT_2_T4'': field type<br>
    +    mismatch'<br>
     ...<br>
     box.sql.execute('DROP TABLE t3;')<br>
     ---<br>
     ...<br>
    -box.session.su('admin')<br>
    ----<br>
    -...<br>
     --<br>
     -- Check that _space, _index and _sequence have the same number of<br>
     -- records.<br>
    @@ -174,6 +174,13 @@ sequence_count == #box.space._sequence:select()<br>
     ---<br>
     - true<br>
     ...<br>
    +fk_constraint_count == #box.space._fk_constraint:select()<br>
    +---<br>
    +- true<br>
    +...<br>
    +box.session.su('admin')<br>
    +---<br>
    +...<br>
     box.schema.user.drop('tmp')<br>
     ---<br>
     ...<br>
    diff --git a/test/sql/drop-table.test.lua
    b/test/sql/drop-table.test.lua<br>
    index f86e3d8..b1c5253 100644<br>
    --- a/test/sql/drop-table.test.lua<br>
    +++ b/test/sql/drop-table.test.lua<br>
    @@ -83,22 +83,21 @@ space_count == #box.space._space:select()<br>
     index_count == #box.space._index:select()<br>
     sequence_count == #box.space._sequence:select()<br>
     <br>
    +fk_constraint_count = #box.space._fk_constraint:select()<br>
    +<br>
     --<br>
    --- Give user right to write in _sequence. Still have not enough<br>
    --- rights to write in _fk_constraint.<br>
    +-- Check that clean-up works fine after another error.<br>
     --<br>
    -box.schema.user.grant('tmp', 'write', 'space', '_sequence')<br>
    +box.schema.user.grant('tmp', 'write', 'space')<br>
     box.session.su('tmp')<br>
     <br>
     box.sql.execute('CREATE TABLE t3(a INTEGER PRIMARY KEY);')<br>
     --<br>
    --- Error: user do not have rights to write in _fk_constraint.<br>
    +-- Error: Failed to create foreign key constraint.<br>
     --<br>
    -box.sql.execute('CREATE TABLE t4(x INTEGER PRIMARY KEY REFERENCES
    t3);')<br>
    +box.sql.execute('CREATE TABLE t4(x INTEGER PRIMARY KEY REFERENCES
    t3, a INT UNIQUE, c INT REFERENCES t3);')<br>
     box.sql.execute('DROP TABLE t3;')<br>
     <br>
    -box.session.su('admin')<br>
    -<br>
     --<br>
     -- Check that _space, _index and _sequence have the same number of<br>
     -- records.<br>
    @@ -106,5 +105,8 @@ box.session.su('admin')<br>
     space_count == #box.space._space:select()<br>
     index_count == #box.space._index:select()<br>
     sequence_count == #box.space._sequence:select()<br>
    +fk_constraint_count == #box.space._fk_constraint:select()<br>
    +<br>
    +box.session.su('admin')<br>
     <br>
     box.schema.user.drop('tmp')<br>
    <br>
    <b>New patch:</b><br>
    <br>
    commit f9092f3fd17676bfe220bf9d31aa4ed9a648590c<br>
    Author: Mergen Imeev <a class="moz-txt-link-rfc2396E"
      href="mailto:imeevma@gmail.com"><imeevma@gmail.com></a><br>
    Date:   Fri Aug 31 15:50:17 2018 +0300<br>
    <br>
        sql: clean-up on failed CREATE TABLE<br>
        <br>
        In case statement "CREATE TABLE ..." fails it can left some<br>
        records in system spaces that shouldn't be there. These records<br>
        won't be left behind after this patch.<br>
        <br>
        @TarantoolBot document<br>
        Title: Clean up after failure of CREATE TABLE<br>
        Usually CREATE TABLE creates no less than two objects which are<br>
        space and index. If creation of index (or any object after
    space)<br>
        failed, created space (and other created objects) won't be
    deleted<br>
        though operation failed. Now these objects will be deleted<br>
        properly.<br>
        <br>
        Closes #3592<br>
    <br>
    diff --git a/src/box/sql/build.c b/src/box/sql/build.c<br>
    index a806fb4..28b488c 100644<br>
    --- a/src/box/sql/build.c<br>
    +++ b/src/box/sql/build.c<br>
    @@ -55,6 +55,53 @@<br>
     #include "box/tuple_format.h"<br>
     #include "box/coll_id_cache.h"<br>
     <br>
    +/**<br>
    + * Structure that contains information about record that was<br>
    + * inserted into system space.<br>
    + */<br>
    +struct saved_record<br>
    +{<br>
    +    /** A link in a record list. */<br>
    +    struct rlist link;<br>
    +    /** Id of space in which the record was inserted. */<br>
    +    uint32_t space_id;<br>
    +    /** First register of the key of the record. */<br>
    +    int reg_key;<br>
    +    /** Number of registers the key consists of. */<br>
    +    int reg_key_count;<br>
    +    /** The number of the OP_SInsert operation. */<br>
    +    int insertion_opcode;<br>
    +};<br>
    +<br>
    +/**<br>
    + * Save inserted in system space record in list.<br>
    + *<br>
    + * @param parser SQL Parser object.<br>
    + * @param space_id Id of table in which record is inserted.<br>
    + * @param reg_key Register that contains first field of the key.<br>
    + * @param reg_key_count Exact number of fields of the key.<br>
    + * @param insertion_opcode Number of OP_SInsert opcode.<br>
    + */<br>
    +static inline void<br>
    +save_record(struct Parse *parser, uint32_t space_id, int reg_key,<br>
    +        int reg_key_count, int insertion_opcode)<br>
    +{<br>
    +    struct saved_record *record =<br>
    +        region_alloc(&parser->region, sizeof(*record));<br>
    +    if (record == NULL) {<br>
    +        diag_set(OutOfMemory, sizeof(*record), "region_alloc",<br>
    +             "record");<br>
    +        parser->rc = SQL_TARANTOOL_ERROR;<br>
    +        parser->nErr++;<br>
    +        return;<br>
    +    }<br>
    +    record->space_id = space_id;<br>
    +    record->reg_key = reg_key;<br>
    +    record->reg_key_count = reg_key_count;<br>
    +    record->insertion_opcode = insertion_opcode;<br>
    +    rlist_add_entry(&parser->record_list, record, link);<br>
    +}<br>
    +<br>
     void<br>
     sql_finish_coding(struct Parse *parse_context)<br>
     {<br>
    @@ -62,6 +109,42 @@ sql_finish_coding(struct Parse *parse_context)<br>
         struct sqlite3 *db = parse_context->db;<br>
         struct Vdbe *v = sqlite3GetVdbe(parse_context);<br>
         sqlite3VdbeAddOp0(v, OP_Halt);<br>
    +    /*<br>
    +     * In case statement "CREATE TABLE ..." fails it can<br>
    +     * left some records in system spaces that shouldn't be<br>
    +     * there. To clean-up properly this code is added. Last<br>
    +     * record isn't deleted because if statement fails than<br>
    +     * it won't be created. This code works the same way for<br>
    +     * other "CREATE ..." statements but it won't delete<br>
    +     * anything as these statements create no more than one<br>
    +     * record.<br>
    +     */<br>
    +    if (!rlist_empty(&parse_context->record_list)) {<br>
    +        struct saved_record *record =<br>
    +            rlist_shift_entry(&parse_context->record_list,<br>
    +                      struct saved_record, link);<br>
    +        /* Set P2 of SInsert. */<br>
    +        sqlite3VdbeChangeP2(v, record->insertion_opcode,
    v->nOp);<br>
    +        MAYBE_UNUSED const char *comment =<br>
    +            "Delete entry from %s if CREATE TABLE fails";<br>
    +        rlist_foreach_entry(record,
    &parse_context->record_list, link) {<br>
    +            int record_reg = ++parse_context->nMem;<br>
    +            sqlite3VdbeAddOp3(v, OP_MakeRecord, record->reg_key,<br>
    +                      record->reg_key_count, record_reg);<br>
    +            sqlite3VdbeAddOp2(v, OP_SDelete, record->space_id,<br>
    +                      record_reg);<br>
    +            MAYBE_UNUSED struct space *space =<br>
    +                space_by_id(record->space_id);<br>
    +            VdbeComment((v, comment, space_name(space)));<br>
    +            /* Set P2 of SInsert. */<br>
    +            sqlite3VdbeChangeP2(v, record->insertion_opcode,<br>
    +                        v->nOp);<br>
    +        }<br>
    +        sqlite3VdbeAddOp1(v, OP_Halt, SQL_TARANTOOL_ERROR);<br>
    +        VdbeComment((v,<br>
    +                 "Exit with an error if CREATE statement fails"));<br>
    +    }<br>
    +<br>
         if (db->mallocFailed || parse_context->nErr != 0) {<br>
             if (parse_context->rc == SQLITE_OK)<br>
                 parse_context->rc = SQLITE_ERROR;<br>
    @@ -1101,13 +1184,14 @@ vdbe_emit_create_index(struct Parse *parse,
    struct space_def *def,<br>
         sqlite3VdbeAddOp4(v, OP_Blob, index_parts_sz, entry_reg + 5,<br>
                   SQL_SUBTYPE_MSGPACK, index_parts, P4_STATIC);<br>
         sqlite3VdbeAddOp3(v, OP_MakeRecord, entry_reg, 6, tuple_reg);<br>
    -    sqlite3VdbeAddOp2(v, OP_SInsert, BOX_INDEX_ID, tuple_reg);<br>
    +    sqlite3VdbeAddOp3(v, OP_SInsert, BOX_INDEX_ID, 0, tuple_reg);<br>
         /*<br>
          * Non-NULL value means that index has been created via<br>
          * separate CREATE INDEX statement.<br>
          */<br>
         if (idx_def->opts.sql != NULL)<br>
             sqlite3VdbeChangeP5(v, OPFLAG_NCHANGE);<br>
    +    save_record(parse, BOX_INDEX_ID, entry_reg, 2, v->nOp - 1);<br>
         return;<br>
     error:<br>
         parse->rc = SQL_TARANTOOL_ERROR;<br>
    @@ -1165,8 +1249,9 @@ createSpace(Parse * pParse, int iSpaceId, char
    *zStmt)<br>
         sqlite3VdbeAddOp4(v, OP_Blob, table_stmt_sz, iFirstCol + 6,<br>
                   SQL_SUBTYPE_MSGPACK, table_stmt, P4_STATIC);<br>
         sqlite3VdbeAddOp3(v, OP_MakeRecord, iFirstCol, 7, iRecord);<br>
    -    sqlite3VdbeAddOp2(v, OP_SInsert, BOX_SPACE_ID, iRecord);<br>
    +    sqlite3VdbeAddOp3(v, OP_SInsert, BOX_SPACE_ID, 0, iRecord);<br>
         sqlite3VdbeChangeP5(v, OPFLAG_NCHANGE);<br>
    +    save_record(pParse, BOX_SPACE_ID, iFirstCol, 1, v->nOp - 1);<br>
         return;<br>
     error:<br>
         pParse->nErr++;<br>
    @@ -1340,9 +1425,11 @@ vdbe_emit_fkey_create(struct Parse
    *parse_context, const struct fkey_def *fk)<br>
                   parent_links, P4_DYNAMIC);<br>
         sqlite3VdbeAddOp3(vdbe, OP_MakeRecord, constr_tuple_reg, 9,<br>
                   constr_tuple_reg + 9);<br>
    -    sqlite3VdbeAddOp2(vdbe, OP_SInsert, BOX_FK_CONSTRAINT_ID,<br>
    +    sqlite3VdbeAddOp3(vdbe, OP_SInsert, BOX_FK_CONSTRAINT_ID, 0,<br>
                   constr_tuple_reg + 9);<br>
         sqlite3VdbeChangeP5(vdbe, OPFLAG_NCHANGE);<br>
    +    save_record(parse_context, BOX_FK_CONSTRAINT_ID,
    constr_tuple_reg, 2,<br>
    +            vdbe->nOp - 1);<br>
         sqlite3ReleaseTempRange(parse_context, constr_tuple_reg, 10);<br>
         return;<br>
     error:<br>
    @@ -1487,14 +1574,18 @@ sqlite3EndTable(Parse * pParse,    /* Parse
    context */<br>
             int reg_seq_record =<br>
                 emitNewSysSequenceRecord(pParse, reg_seq_id,<br>
                              p->def->name);<br>
    -        sqlite3VdbeAddOp2(v, OP_SInsert, BOX_SEQUENCE_ID,<br>
    +        sqlite3VdbeAddOp3(v, OP_SInsert, BOX_SEQUENCE_ID, 0,<br>
                       reg_seq_record);<br>
    +        save_record(pParse, BOX_SEQUENCE_ID, reg_seq_record + 1, 1,<br>
    +                v->nOp - 1);<br>
             /* Do an insertion into _space_sequence. */<br>
             int reg_space_seq_record =<br>
                 emitNewSysSpaceSequenceRecord(pParse, reg_space_id,<br>
                                   reg_seq_id);<br>
    -        sqlite3VdbeAddOp2(v, OP_SInsert, BOX_SPACE_SEQUENCE_ID,<br>
    +        sqlite3VdbeAddOp3(v, OP_SInsert, BOX_SPACE_SEQUENCE_ID, 0,<br>
                       reg_space_seq_record);<br>
    +        save_record(pParse, BOX_SPACE_SEQUENCE_ID,<br>
    +                reg_space_seq_record + 1, 1, v->nOp - 1);<br>
         }<br>
         /* Code creation of FK constraints, if any. */<br>
         struct fkey_parse *fk_parse;<br>
    diff --git a/src/box/sql/prepare.c b/src/box/sql/prepare.c<br>
    index e98e845..a4b65eb 100644<br>
    --- a/src/box/sql/prepare.c<br>
    +++ b/src/box/sql/prepare.c<br>
    @@ -274,6 +274,7 @@ sql_parser_create(struct Parse *parser, sqlite3
    *db)<br>
         memset(parser, 0, sizeof(struct Parse));<br>
         parser->db = db;<br>
         rlist_create(&parser->new_fkey);<br>
    +    rlist_create(&parser->record_list);<br>
         region_create(&parser->region, &cord()->slabc);<br>
     }<br>
     <br>
    diff --git a/src/box/sql/sqliteInt.h b/src/box/sql/sqliteInt.h<br>
    index 744b660..d8eb516 100644<br>
    --- a/src/box/sql/sqliteInt.h<br>
    +++ b/src/box/sql/sqliteInt.h<br>
    @@ -2765,6 +2765,11 @@ struct Parse {<br>
          * Foreign key constraint appeared in CREATE TABLE stmt.<br>
          */<br>
         struct rlist new_fkey;<br>
    +    /**<br>
    +     * List of all records that were inserted in system spaces<br>
    +     * in current statement.<br>
    +     */<br>
    +    struct rlist record_list;<br>
         bool initiateTTrans;    /* Initiate Tarantool transaction */<br>
         /** True, if table to be created has AUTOINCREMENT PK. */<br>
         bool is_new_table_autoinc;<br>
    diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c<br>
    index 7c1015c..1bec2fa 100644<br>
    --- a/src/box/sql/vdbe.c<br>
    +++ b/src/box/sql/vdbe.c<br>
    @@ -1010,8 +1010,12 @@ case OP_Halt: {<br>
         p->pc = pcx;<br>
         if (p->rc) {<br>
             if (p->rc == SQL_TARANTOOL_ERROR) {<br>
    -            assert(pOp->p4.z != NULL);<br>
    -            box_error_set(__FILE__, __LINE__, pOp->p5,
    pOp->p4.z);<br>
    +            if (pOp->p4.z == NULL) {<br>
    +                assert(! diag_is_empty(diag_get()));<br>
    +            } else {<br>
    +                box_error_set(__FILE__, __LINE__, pOp->p5,<br>
    +                          pOp->p4.z);<br>
    +            }<br>
             } else if (pOp->p5 != 0) {<br>
                 static const char * const azType[] = { "NOT NULL",
    "UNIQUE", "CHECK",<br>
                                        "FOREIGN KEY" };<br>
    @@ -4308,8 +4312,8 @@ case OP_IdxInsert: {<br>
         break;<br>
     }<br>
     <br>
    -/* Opcode: SInsert P1 P2 * * P5<br>
    - * Synopsis: space id = P1, key = r[P2]<br>
    +/* Opcode: SInsert P1 P2 P3 * P5<br>
    + * Synopsis: space id = P1, key = r[P3], on error goto P2<br>
      *<br>
      * This opcode is used only during DDL routine.<br>
      * In contrast to ordinary insertion, insertion to system spaces<br>
    @@ -4322,15 +4326,15 @@ case OP_IdxInsert: {<br>
      */<br>
     case OP_SInsert: {<br>
         assert(pOp->p1 > 0);<br>
    -    assert(pOp->p2 >= 0);<br>
    +    assert(pOp->p2 > 0);<br>
    +    assert(pOp->p3 >= 0);<br>
     <br>
    -    pIn2 = &aMem[pOp->p2];<br>
    +    pIn3 = &aMem[pOp->p3];<br>
         struct space *space = space_by_id(pOp->p1);<br>
         assert(space != NULL);<br>
         assert(space_is_system(space));<br>
    -    rc = tarantoolSqlite3Insert(space, pIn2->z, pIn2->z +
    pIn2->n);<br>
    -    if (rc)<br>
    -        goto abort_due_to_error;<br>
    +    if (tarantoolSqlite3Insert(space, pIn3->z, pIn3->z +
    pIn3->n) != 0)<br>
    +        goto jump_to_p2;<br>
         if (pOp->p5 & OPFLAG_NCHANGE)<br>
             p->nChange++;<br>
         break;<br>
    diff --git a/test/sql/drop-table.result b/test/sql/drop-table.result<br>
    index 08f2496..297799e 100644<br>
    --- a/test/sql/drop-table.result<br>
    +++ b/test/sql/drop-table.result<br>
    @@ -33,3 +33,154 @@ box.sql.execute("INSERT INTO zzzoobar VALUES
    (111, 222, 'c3', 444)")<br>
     -- DROP TABLE should do the job<br>
     -- Debug<br>
     -- require("console").start()<br>
    +--<br>
    +-- gh-3592: clean-up garbage on failed CREATE TABLE statement.<br>
    +--<br>
    +-- Let user have enough rights to create space, but not enough to<br>
    +-- create index.<br>
    +--<br>
    +box.schema.user.create('tmp')<br>
    +---<br>
    +...<br>
    +box.schema.user.grant('tmp', 'create, read', 'universe')<br>
    +---<br>
    +...<br>
    +box.schema.user.grant('tmp', 'write', 'space', '_space')<br>
    +---<br>
    +...<br>
    +box.schema.user.grant('tmp', 'write', 'space', '_schema')<br>
    +---<br>
    +...<br>
    +-- Number of records in _space, _index, _sequence:<br>
    +space_count = #box.space._space:select()<br>
    +---<br>
    +...<br>
    +index_count = #box.space._index:select()<br>
    +---<br>
    +...<br>
    +sequence_count = #box.space._sequence:select()<br>
    +---<br>
    +...<br>
    +box.session.su('tmp')<br>
    +---<br>
    +...<br>
    +--<br>
    +-- Error: user do not have rights to write in box.space._index.<br>
    +-- Space that was already created should be automatically dropped.<br>
    +--<br>
    +box.sql.execute('CREATE TABLE t1 (id INT PRIMARY KEY, a INT)')<br>
    +---<br>
    +- error: Write access to space '_index' is denied for user 'tmp'<br>
    +...<br>
    +-- Error: no such table.<br>
    +box.sql.execute('DROP TABLE t1')<br>
    +---<br>
    +- error: 'no such table: T1'<br>
    +...<br>
    +box.session.su('admin')<br>
    +---<br>
    +...<br>
    +--<br>
    +-- Check that _space, _index and _sequence have the same number of<br>
    +-- records.<br>
    +--<br>
    +space_count == #box.space._space:select()<br>
    +---<br>
    +- true<br>
    +...<br>
    +index_count == #box.space._index:select()<br>
    +---<br>
    +- true<br>
    +...<br>
    +sequence_count == #box.space._sequence:select()<br>
    +---<br>
    +- true<br>
    +...<br>
    +--<br>
    +-- Give user right to write in _index. Still have not enough<br>
    +-- rights to write in _sequence.<br>
    +--<br>
    +box.schema.user.grant('tmp', 'write', 'space', '_index')<br>
    +---<br>
    +...<br>
    +box.session.su('tmp')<br>
    +---<br>
    +...<br>
    +--<br>
    +-- Error: user do not have rights to write in _sequence.<br>
    +--<br>
    +box.sql.execute('CREATE TABLE t2 (id INT PRIMARY KEY AUTOINCREMENT,
    a UNIQUE, b UNIQUE, c UNIQUE, d UNIQUE)')<br>
    +---<br>
    +- error: Write access to space '_sequence' is denied for user 'tmp'<br>
    +...<br>
    +box.session.su('admin')<br>
    +---<br>
    +...<br>
    +--<br>
    +-- Check that _space, _index and _sequence have the same number of<br>
    +-- records.<br>
    +--<br>
    +space_count == #box.space._space:select()<br>
    +---<br>
    +- true<br>
    +...<br>
    +index_count == #box.space._index:select()<br>
    +---<br>
    +- true<br>
    +...<br>
    +sequence_count == #box.space._sequence:select()<br>
    +---<br>
    +- true<br>
    +...<br>
    +fk_constraint_count = #box.space._fk_constraint:select()<br>
    +---<br>
    +...<br>
    +--<br>
    +-- Check that clean-up works fine after another error.<br>
    +--<br>
    +box.schema.user.grant('tmp', 'write', 'space')<br>
    +---<br>
    +...<br>
    +box.session.su('tmp')<br>
    +---<br>
    +...<br>
    +box.sql.execute('CREATE TABLE t3(a INTEGER PRIMARY KEY);')<br>
    +---<br>
    +...<br>
    +--<br>
    +-- Error: Failed to create foreign key constraint.<br>
    +--<br>
    +box.sql.execute('CREATE TABLE t4(x INTEGER PRIMARY KEY REFERENCES
    t3, a INT UNIQUE, c INT REFERENCES t3);')<br>
    +---<br>
    +- error: 'Failed to create foreign key constraint
    ''FK_CONSTRAINT_2_T4'': field type<br>
    +    mismatch'<br>
    +...<br>
    +box.sql.execute('DROP TABLE t3;')<br>
    +---<br>
    +...<br>
    +--<br>
    +-- Check that _space, _index and _sequence have the same number of<br>
    +-- records.<br>
    +--<br>
    +space_count == #box.space._space:select()<br>
    +---<br>
    +- true<br>
    +...<br>
    +index_count == #box.space._index:select()<br>
    +---<br>
    +- true<br>
    +...<br>
    +sequence_count == #box.space._sequence:select()<br>
    +---<br>
    +- true<br>
    +...<br>
    +fk_constraint_count == #box.space._fk_constraint:select()<br>
    +---<br>
    +- true<br>
    +...<br>
    +box.session.su('admin')<br>
    +---<br>
    +...<br>
    +box.schema.user.drop('tmp')<br>
    +---<br>
    +...<br>
    diff --git a/test/sql/drop-table.test.lua
    b/test/sql/drop-table.test.lua<br>
    index 9663074..b1c5253 100644<br>
    --- a/test/sql/drop-table.test.lua<br>
    +++ b/test/sql/drop-table.test.lua<br>
    @@ -25,3 +25,88 @@ box.sql.execute("INSERT INTO zzzoobar VALUES
    (111, 222, 'c3', 444)")<br>
     <br>
     -- Debug<br>
     -- require("console").start()<br>
    +<br>
    +--<br>
    +-- gh-3592: clean-up garbage on failed CREATE TABLE statement.<br>
    +--<br>
    +-- Let user have enough rights to create space, but not enough to<br>
    +-- create index.<br>
    +--<br>
    +box.schema.user.create('tmp')<br>
    +box.schema.user.grant('tmp', 'create, read', 'universe')<br>
    +box.schema.user.grant('tmp', 'write', 'space', '_space')<br>
    +box.schema.user.grant('tmp', 'write', 'space', '_schema')<br>
    +<br>
    +-- Number of records in _space, _index, _sequence:<br>
    +space_count = #box.space._space:select()<br>
    +index_count = #box.space._index:select()<br>
    +sequence_count = #box.space._sequence:select()<br>
    +<br>
    +box.session.su('tmp')<br>
    +--<br>
    +-- Error: user do not have rights to write in box.space._index.<br>
    +-- Space that was already created should be automatically dropped.<br>
    +--<br>
    +box.sql.execute('CREATE TABLE t1 (id INT PRIMARY KEY, a INT)')<br>
    +-- Error: no such table.<br>
    +box.sql.execute('DROP TABLE t1')<br>
    +<br>
    +box.session.su('admin')<br>
    +<br>
    +--<br>
    +-- Check that _space, _index and _sequence have the same number of<br>
    +-- records.<br>
    +--<br>
    +space_count == #box.space._space:select()<br>
    +index_count == #box.space._index:select()<br>
    +sequence_count == #box.space._sequence:select()<br>
    +<br>
    +--<br>
    +-- Give user right to write in _index. Still have not enough<br>
    +-- rights to write in _sequence.<br>
    +--<br>
    +box.schema.user.grant('tmp', 'write', 'space', '_index')<br>
    +box.session.su('tmp')<br>
    +<br>
    +--<br>
    +-- Error: user do not have rights to write in _sequence.<br>
    +--<br>
    +box.sql.execute('CREATE TABLE t2 (id INT PRIMARY KEY AUTOINCREMENT,
    a UNIQUE, b UNIQUE, c UNIQUE, d UNIQUE)')<br>
    +<br>
    +box.session.su('admin')<br>
    +<br>
    +--<br>
    +-- Check that _space, _index and _sequence have the same number of<br>
    +-- records.<br>
    +--<br>
    +space_count == #box.space._space:select()<br>
    +index_count == #box.space._index:select()<br>
    +sequence_count == #box.space._sequence:select()<br>
    +<br>
    +fk_constraint_count = #box.space._fk_constraint:select()<br>
    +<br>
    +--<br>
    +-- Check that clean-up works fine after another error.<br>
    +--<br>
    +box.schema.user.grant('tmp', 'write', 'space')<br>
    +box.session.su('tmp')<br>
    +<br>
    +box.sql.execute('CREATE TABLE t3(a INTEGER PRIMARY KEY);')<br>
    +--<br>
    +-- Error: Failed to create foreign key constraint.<br>
    +--<br>
    +box.sql.execute('CREATE TABLE t4(x INTEGER PRIMARY KEY REFERENCES
    t3, a INT UNIQUE, c INT REFERENCES t3);')<br>
    +box.sql.execute('DROP TABLE t3;')<br>
    +<br>
    +--<br>
    +-- Check that _space, _index and _sequence have the same number of<br>
    +-- records.<br>
    +--<br>
    +space_count == #box.space._space:select()<br>
    +index_count == #box.space._index:select()<br>
    +sequence_count == #box.space._sequence:select()<br>
    +fk_constraint_count == #box.space._fk_constraint:select()<br>
    +<br>
    +box.session.su('admin')<br>
    +<br>
    +box.schema.user.drop('tmp')<br>
    <br>
  </body>
</html>