Hello,
On 2016-03-26 15:37, John Found wrote:
> Why cannot drop the table test?
>
> sqlite> begin transaction;
> sqlite> create virtual table test using fts5;
> Error: vtable constructor failed: test
> sqlite> commit;
It is not required. Non-commited-and-non-rolledback, dangling
transaction suppresses all operations on vtable ``test''. COMMIT is
required to damage database file permanently.
> sqlite>
> sqlite> drop table test;
> Error: vtable constructor failed: test
>
> sqlite> .tables
> test test_content test_docsize
> test_config test_data test_idx
>
> $sqlite3 --version
> 3.11.1 2016-03-03 16:17:53 f047920ce16971e573bc6ec9a48b118c9de2b3a7
It should not be possible to damage a database by an using of clean SQL
commands only. Hopefully SQLite has a helpful statement transaction,
which can be used in this case.
I must stipulate that in the following is an ad-hoc solution, which may
be inaccurate and is included to illustrate a problem only.
In ``vtab.c:sqlite3VtabBeginParse()'', at the beginning insert two lines:
======
sqlite3MultiWrite(pParse);
sqlite3MayAbort(pParse);
======
or
======
pParse->isMultiWrite = 1;
pParse->mayAbort = 1;
======
I'm not sure which solution is better (if any), but I've tested the
former one and it works ok. It forces ``OP_Transaction'' to be a
statement transaction, which causes rolling back all VDBE ops in case of
an error.
In ``vdbeaux.c:sqlite3VdbeAssertMayAbort()'' change:
======
if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename
======
to
======
if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename
|| opcode==OP_VCreate
======
This allows assertions to be passed, because ``CREATE VIRTUAL TABLE''
does not produce any of ``abortable'' opcodes.
-- best regards
Cezary H. Noweta