Skip to content
Snippets Groups Projects
Commit 2677b823 authored by Vladislav Shpilevoy's avatar Vladislav Shpilevoy Committed by Kirill Yukhin
Browse files

sql: transactional DDL

Box recently added support of transactional DDL allowing to do
any number of non-yielding DDL operations atomically. This is
really a big relief of one of the biggest pains of SQL. Before
this patch each multirow SQL DDL statement needed to prepare its
own rollback procedure for a case if something would go wrong.

Now with box support SQL wraps each DDL statement into a
transaction, and doesn't need own escape-routes in a form of
'struct save_record' and others.

Closes #4086

@TarantoolBot document
Title: SQL DDL is transactional

SQL DDL operations are atomic now. For example, if a CREATE TABLE
request fails somewhere in the middle, it won't leave any
garbage. Like a space without indexes, or unused sequences. Even
if the instance is powered off during the request.

Also, SQL DDL can be manually included into transactions, with
certain limitations - such a transaction can't yield.

For example, this is legal:

    START TRANSACTION;
    CREATE TABLE test(a INTEGER PRIMARY KEY, b INTEGER);
    CREATE INDEX test_a ON test(a);
    COMMIT;

If you want to test it in the console, then wrap it into a
function to do not get a rollback by yield, because the console
yields after each command:

    function create()
        box.execute('START TRANSACTION;')
        box.execute('CREATE TABLE test(a INTEGER PRIMARY KEY, b INTEGER);')
        box.execute('CREATE INDEX test_a ON test(a);')
        box.execute('COMMIT;')
    end

    create()

But the following example is illegal and you will get an error:

    box.execute('CREATE TABLE test(a INTEGER PRIMARY KEY, b INTEGER, c INTEGER);')
    box.execute('INSERT INTO test VALUES (1, 1, 1), (2, 2, 2), (3, 3, 3);')

    function index()
        box.execute('START TRANSACTION;')
        box.execute('CREATE INDEX test_b ON test(b);')
        box.execute('CREATE INDEX test_c ON test(c);')
        box.execute('COMMIT;')
    end

    tarantool> index()
    ---
    - error: Can not perform index build in a multi-statement transaction
    ...

The error is because an attempt to build an index on a non-empty
space leads to immediate yield.
parent e094965b
No related merge requests found
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment