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

Reply via email to