mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
Arrange for sqlite3_last_insert_rowid() to work with virtual tables. (CVS 3259)
FossilOrigin-Name: afa39a46320e9996a5478ea6e19eb4c2014327ac
This commit is contained in:
22
manifest
22
manifest
@ -1,5 +1,5 @@
|
||||
C Fix\stype\sin\stest_schema.c.\s(CVS\s3258)
|
||||
D 2006-06-15T16:26:45
|
||||
C Arrange\sfor\ssqlite3_last_insert_rowid()\sto\swork\swith\svirtual\stables.\s(CVS\s3259)
|
||||
D 2006-06-16T06:17:47
|
||||
F Makefile.in f839b470345d3cb4b0644068474623fe2464b5d3
|
||||
F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
|
||||
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
||||
@ -46,7 +46,7 @@ F src/expr.c 78b521337d628b1fd9d87b12dbbe771247aab585
|
||||
F src/func.c 01e559893b5e43bea85135ad3e481d86c447942a
|
||||
F src/hash.c 449f3d6620193aa557f5d86cbc5cc6b87702b185
|
||||
F src/hash.h 1b3f7e2609141fd571f62199fc38687d262e9564
|
||||
F src/insert.c eba160c6d7f2c44232ff0f168f7b047e20d6f473
|
||||
F src/insert.c 09440829e4fa2b0e11dbde5508b8a291025a745d
|
||||
F src/legacy.c fa15d505dd4e45044177ee4d1c6aeaf8c836d390
|
||||
F src/loadext.c 676257ae268457e7f03261d8ca0d1e72968a26c8
|
||||
F src/main.c 7875e8835539d4f16e8b62fad1dee9bda2091272
|
||||
@ -72,7 +72,7 @@ F src/random.c d40f8d356cecbd351ccfab6eaedd7ec1b54f5261
|
||||
F src/select.c 38eda11d950ed5e631ea9054f84a4a8b9e9b39d8
|
||||
F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
|
||||
F src/shell.c ad73192b30a338a58fe81183d4a5d5a1d4e51d36
|
||||
F src/sqlite.h.in 1dc44da025da28a011d11ad1608c11a951047fab
|
||||
F src/sqlite.h.in 2fc589cf9b550c5bb8b0bac6414389e2057940d1
|
||||
F src/sqlite3ext.h fc8647211af0caa9d8e49ab31624b357c1332380
|
||||
F src/sqliteInt.h 5eb64f1dd9a8b237d147962bc57637d87e044ff4
|
||||
F src/table.c f64ec4fbfe333f8df925bc6ba494f55e05b0e75e
|
||||
@ -84,11 +84,11 @@ F src/test4.c 8b784cd82de158a2317cb4ac4bc86f91ad315e25
|
||||
F src/test5.c 7162f8526affb771c4ed256826eee7bb9eca265f
|
||||
F src/test6.c 60a02961ceb7b3edc25f5dc5c1ac2556622a76de
|
||||
F src/test7.c 03fa8d787f6aebc6d1f72504d52f33013ad2c8e3
|
||||
F src/test8.c 9579de4645c9b8be3f8de217224bcf9280da9b6a
|
||||
F src/test8.c 75d9ef60e12ea8a281ab6cd9643992a5a99b2c6a
|
||||
F src/test_async.c e3deaedd4d86a56391b81808fde9e44fbd92f1d3
|
||||
F src/test_loadext.c 22065d601a18878e5542191001f0eaa5d77c0ed8
|
||||
F src/test_md5.c 6c42bc0a3c0b54be34623ff77a0eec32b2fa96e3
|
||||
F src/test_schema.c 889fde757c78b11538c7e448c392198a1ccc8be3
|
||||
F src/test_schema.c 3b9fb30f0fed8297097c9b7bd3df484d0cd5e639
|
||||
F src/test_server.c a6460daed0b92ecbc2531b6dc73717470e7a648c
|
||||
F src/test_tclvar.c c52f67fbe06d32804af2ba9a2d7aadfc15f5910c
|
||||
F src/tokenize.c 6ebcafa6622839968dda4418a7b6945f277a128f
|
||||
@ -97,7 +97,7 @@ F src/update.c 5e638a61102776c0f0333994e18361b40598b44f
|
||||
F src/utf.c ab81ac59084ff1c07d421eb1a0a84ec809603b44
|
||||
F src/util.c ca6ee72772c0f5dc04d2e0ab1973fd3b6a9bf79d
|
||||
F src/vacuum.c 5b37d0f436f8e1ffacd17934e44720b38d2247f9
|
||||
F src/vdbe.c 4a66e5815c50e7f39454fe75d2e3f342785ea20a
|
||||
F src/vdbe.c f17a90ab6c630438394807c4e21c0c1c7731ee4f
|
||||
F src/vdbe.h 258b5d1c0aaa72192f09ff0568ce42b383f156fa
|
||||
F src/vdbeInt.h 6ccb7eaae76ebd761470f6a035501ff33aa92c20
|
||||
F src/vdbeapi.c 6af0e7160af260052a7a4500464221a03dada75f
|
||||
@ -291,7 +291,7 @@ F test/vacuum.test 37f998b841cb335397c26d9bbc3457182af2565f
|
||||
F test/vacuum2.test 5aea8c88a65cb29f7d175296e7c819c6158d838c
|
||||
F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
|
||||
F test/view.test 16e2774fe35e47a07ac4471b7f0bcc948b1aa6d5
|
||||
F test/vtab1.test 519f360d15b8009845e7957789801807346286ff
|
||||
F test/vtab1.test a31c323cf158bf7326b3a4af4156b1bdd98cf8a8
|
||||
F test/where.test ee7c9a6659b07e1ee61177f6e7ff71565ee2c9df
|
||||
F test/where2.test a16476a5913e75cf65b38f2daa6157a6b7791394
|
||||
F test/where3.test 3b5ad2c58069e12be2bd86bc5e211a82810521aa
|
||||
@ -367,7 +367,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
|
||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
||||
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
|
||||
P de8d32ac71a6e113e83b952813424cb3fb5a2e59
|
||||
R a9b9717f996b4f699ae87b1b5716d890
|
||||
P d65d83d38321258a7bb8c38f4b2657650b0f1033
|
||||
R cbf7f69fafe0127b012e719eed74f4d3
|
||||
U danielk1977
|
||||
Z c802729e8f39cde93a7672cc85fc0701
|
||||
Z 33e3dbe7c063b046d5656223c8b15932
|
||||
|
@ -1 +1 @@
|
||||
d65d83d38321258a7bb8c38f4b2657650b0f1033
|
||||
afa39a46320e9996a5478ea6e19eb4c2014327ac
|
@ -12,7 +12,7 @@
|
||||
** This file contains C code routines that are called by the parser
|
||||
** to handle INSERT statements in SQLite.
|
||||
**
|
||||
** $Id: insert.c,v 1.167 2006/06/15 07:29:01 danielk1977 Exp $
|
||||
** $Id: insert.c,v 1.168 2006/06/16 06:17:47 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@ -632,7 +632,7 @@ void sqlite3Insert(
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
if( IsVirtual(pTab) ){
|
||||
sqlite3VdbeOp3(v, OP_VUpdate, 0, pTab->nCol+2,
|
||||
sqlite3VdbeOp3(v, OP_VUpdate, 1, pTab->nCol+2,
|
||||
(const char*)pTab->pVtab, P3_VTAB);
|
||||
}else
|
||||
#endif
|
||||
|
@ -12,7 +12,7 @@
|
||||
** This header file defines the interface that the SQLite library
|
||||
** presents to client programs.
|
||||
**
|
||||
** @(#) $Id: sqlite.h.in,v 1.177 2006/06/15 04:28:13 danielk1977 Exp $
|
||||
** @(#) $Id: sqlite.h.in,v 1.178 2006/06/16 06:17:47 danielk1977 Exp $
|
||||
*/
|
||||
#ifndef _SQLITE3_H_
|
||||
#define _SQLITE3_H_
|
||||
@ -1552,7 +1552,7 @@ struct sqlite3_module {
|
||||
int (*xNext)(sqlite3_vtab_cursor*);
|
||||
int (*xColumn)(sqlite3_vtab_cursor*, sqlite3_context*, int);
|
||||
int (*xRowid)(sqlite3_vtab_cursor*, sqlite_int64 *pRowid);
|
||||
int (*xUpdate)(sqlite3_vtab *pVTab, int, sqlite3_value **apData);
|
||||
int (*xUpdate)(sqlite3_vtab *, int, sqlite3_value **, sqlite_int64 *);
|
||||
int (*xBegin)(sqlite3_vtab *pVTab);
|
||||
int (*xSync)(sqlite3_vtab *pVTab);
|
||||
int (*xCommit)(sqlite3_vtab *pVTab);
|
||||
|
15
src/test8.c
15
src/test8.c
@ -13,7 +13,7 @@
|
||||
** is not included in the SQLite library. It is used for automated
|
||||
** testing of the SQLite library.
|
||||
**
|
||||
** $Id: test8.c,v 1.23 2006/06/15 15:38:42 danielk1977 Exp $
|
||||
** $Id: test8.c,v 1.24 2006/06/16 06:17:47 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "tcl.h"
|
||||
@ -512,7 +512,12 @@ static void string_concat(char **pzStr, char *zAppend, int doFree){
|
||||
** NULL INTEGER (nCol args) INSERT (incl. rowid value)
|
||||
**
|
||||
*/
|
||||
int echoUpdate(sqlite3_vtab *tab, int nData, sqlite3_value **apData){
|
||||
int echoUpdate(
|
||||
sqlite3_vtab *tab,
|
||||
int nData,
|
||||
sqlite3_value **apData,
|
||||
sqlite_int64 *pRowid
|
||||
){
|
||||
echo_vtab *pVtab = (echo_vtab *)tab;
|
||||
sqlite3 *db = pVtab->db;
|
||||
int rc = SQLITE_OK;
|
||||
@ -557,7 +562,7 @@ int echoUpdate(sqlite3_vtab *tab, int nData, sqlite3_value **apData){
|
||||
int ii;
|
||||
char *zInsert = 0;
|
||||
char *zValues = 0;
|
||||
|
||||
|
||||
zInsert = sqlite3_mprintf("INSERT OR REPLACE INTO %Q (", pVtab->zTableName);
|
||||
if( sqlite3_value_type(apData[1])==SQLITE_INTEGER ){
|
||||
bindArgOne = 1;
|
||||
@ -602,6 +607,10 @@ int echoUpdate(sqlite3_vtab *tab, int nData, sqlite3_value **apData){
|
||||
rc = sqlite3_finalize(pStmt);
|
||||
}
|
||||
|
||||
if( pRowid && rc==SQLITE_OK ){
|
||||
*pRowid = sqlite3_last_insert_rowid(db);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
** is not included in the SQLite library. It is used for automated
|
||||
** testing of the SQLite library.
|
||||
**
|
||||
** $Id: test_schema.c,v 1.2 2006/06/15 16:26:45 danielk1977 Exp $
|
||||
** $Id: test_schema.c,v 1.3 2006/06/16 06:17:47 danielk1977 Exp $
|
||||
*/
|
||||
|
||||
/* The code in this file defines a sqlite3 module that provides
|
||||
@ -301,6 +301,7 @@ static int register_schema_module(
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "DB");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
sqlite3_create_module(db, "schema", &schemaModule, 0);
|
||||
#endif
|
||||
|
19
src/vdbe.c
19
src/vdbe.c
@ -43,7 +43,7 @@
|
||||
** in this file for details. If in doubt, do not deviate from existing
|
||||
** commenting and indentation practices when changing or adding code.
|
||||
**
|
||||
** $Id: vdbe.c,v 1.561 2006/06/15 07:29:01 danielk1977 Exp $
|
||||
** $Id: vdbe.c,v 1.562 2006/06/16 06:17:47 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "os.h"
|
||||
@ -3269,6 +3269,10 @@ case OP_NewRowid: {
|
||||
** then rowid is stored for subsequent return by the
|
||||
** sqlite3_last_insert_rowid() function (otherwise it's unmodified).
|
||||
**
|
||||
** Parameter P3 may point to a string containing the table-name, or
|
||||
** may be NULL. If it is not NULL, then the update-hook
|
||||
** (sqlite3.xUpdateCallback) is invoked following a successful insert.
|
||||
**
|
||||
** This instruction only works on tables. The equivalent instruction
|
||||
** for indices is OP_IdxInsert.
|
||||
*/
|
||||
@ -4773,7 +4777,7 @@ case OP_VNoChange: {
|
||||
|
||||
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
/* Opcode: VUpdate * P2 P3
|
||||
/* Opcode: VUpdate P1 P2 P3
|
||||
**
|
||||
** P3 is a pointer to a virtual table object, an sqlite3_vtab structure.
|
||||
** This opcode invokes the corresponding xUpdate method. P2 values
|
||||
@ -4795,6 +4799,10 @@ case OP_VNoChange: {
|
||||
**
|
||||
** If P2==1 then no insert is performed. argv[0] is the rowid of
|
||||
** a row to delete.
|
||||
**
|
||||
** P1 is a boolean flag. If it is set to true and the xUpdate call
|
||||
** is successful, then the value returned by sqlite3_last_insert_rowid()
|
||||
** is set to the value of the rowid for the row just inserted.
|
||||
*/
|
||||
case OP_VUpdate: { /* no-push */
|
||||
sqlite3_vtab *pVtab = (sqlite3_vtab *)(pOp->p3);
|
||||
@ -4806,14 +4814,19 @@ case OP_VUpdate: { /* no-push */
|
||||
rc = SQLITE_ERROR;
|
||||
}else{
|
||||
int i;
|
||||
sqlite_int64 rowid;
|
||||
Mem **apArg = p->apArg;
|
||||
Mem *pX = &pTos[1-nArg];
|
||||
for(i = 0; i<nArg; i++, pX++){
|
||||
apArg[i] = pX->flags ? storeTypeInfo(pX,0), pX : 0;
|
||||
}
|
||||
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
|
||||
rc = pModule->xUpdate(pVtab, nArg, apArg);
|
||||
rc = pModule->xUpdate(pVtab, nArg, apArg, &rowid);
|
||||
if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
|
||||
if( pOp->p1 && rc==SQLITE_OK ){
|
||||
assert( nArg>1 && apArg[0] && (apArg[0]->flags&MEM_Null) );
|
||||
db->lastRowid = rowid;
|
||||
}
|
||||
}
|
||||
popStack(&pTos, nArg);
|
||||
break;
|
||||
|
@ -11,7 +11,7 @@
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this file is creating and dropping virtual tables.
|
||||
#
|
||||
# $Id: vtab1.test,v 1.17 2006/06/15 10:41:16 danielk1977 Exp $
|
||||
# $Id: vtab1.test,v 1.18 2006/06/16 06:17:47 danielk1977 Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
@ -31,6 +31,7 @@ ifcapable !vtab {
|
||||
# vtab1-4.*: Table scans and ORDER BY clauses.
|
||||
# vtab1-5.*: Test queries that include joins. This brings the
|
||||
# sqlite3_index_info.estimatedCost variable into play.
|
||||
# vtab1-6.*: Test UPDATE/INSERT/DELETE on vtables.
|
||||
#
|
||||
# This file uses the "echo" module (see src/test8.c). Refer to comments
|
||||
# in that file for the special behaviour of the Tcl $echo_module variable.
|
||||
@ -38,7 +39,6 @@ ifcapable !vtab {
|
||||
# TODO:
|
||||
# * How to test the sqlite3_index_constraint_usage.omit field?
|
||||
# * vtab1-5.*
|
||||
# *
|
||||
#
|
||||
|
||||
|
||||
@ -487,10 +487,99 @@ foreach stmt [list \
|
||||
] {
|
||||
execsql $stmt
|
||||
execsql $stmt db2
|
||||
check_echo_table vtab1-6.6.[incr tn]
|
||||
check_echo_table vtab1-6.8.[incr tn]
|
||||
}
|
||||
|
||||
|
||||
db2 close
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# Test cases vtab1-7 tests that the value returned by
|
||||
# sqlite3_last_insert_rowid() is set correctly when rows are inserted
|
||||
# into virtual tables.
|
||||
do_test vtab1.7-1 {
|
||||
execsql {
|
||||
CREATE TABLE real_abc(a PRIMARY KEY, b, c);
|
||||
CREATE VIRTUAL TABLE echo_abc USING echo(real_abc);
|
||||
}
|
||||
} {}
|
||||
do_test vtab1.7-2 {
|
||||
execsql {
|
||||
INSERT INTO echo_abc VALUES(1, 2, 3);
|
||||
SELECT last_insert_rowid();
|
||||
}
|
||||
} {1}
|
||||
do_test vtab1.7-3 {
|
||||
execsql {
|
||||
INSERT INTO echo_abc(rowid) VALUES(31427);
|
||||
SELECT last_insert_rowid();
|
||||
}
|
||||
} {31427}
|
||||
do_test vtab1.7-4 {
|
||||
execsql {
|
||||
INSERT INTO echo_abc SELECT a||'.v2', b, c FROM echo_abc;
|
||||
SELECT last_insert_rowid();
|
||||
}
|
||||
} {31429}
|
||||
do_test vtab1.7-5 {
|
||||
execsql {
|
||||
SELECT rowid, a, b, c FROM echo_abc
|
||||
}
|
||||
} [list 1 1 2 3 \
|
||||
31427 {} {} {} \
|
||||
31428 1.v2 2 3 \
|
||||
31429 {} {} {} \
|
||||
]
|
||||
|
||||
# Now test that DELETE and UPDATE operations do not modify the value.
|
||||
do_test vtab1.7-6 {
|
||||
execsql {
|
||||
UPDATE echo_abc SET c = 5 WHERE b = 2;
|
||||
SELECT last_insert_rowid();
|
||||
}
|
||||
} {31429}
|
||||
do_test vtab1.7-7 {
|
||||
execsql {
|
||||
UPDATE echo_abc SET rowid = 5 WHERE rowid = 1;
|
||||
SELECT last_insert_rowid();
|
||||
}
|
||||
} {31429}
|
||||
do_test vtab1.7-8 {
|
||||
execsql {
|
||||
DELETE FROM echo_abc WHERE b = 2;
|
||||
SELECT last_insert_rowid();
|
||||
}
|
||||
} {31429}
|
||||
do_test vtab1.7-9 {
|
||||
execsql {
|
||||
SELECT rowid, a, b, c FROM echo_abc
|
||||
}
|
||||
} [list 31427 {} {} {} \
|
||||
31429 {} {} {} \
|
||||
]
|
||||
do_test vtab1.7-10 {
|
||||
execsql {
|
||||
DELETE FROM echo_abc WHERE b = 2;
|
||||
SELECT last_insert_rowid();
|
||||
}
|
||||
} {31429}
|
||||
do_test vtab1.7-11 {
|
||||
execsql {
|
||||
SELECT rowid, a, b, c FROM real_abc
|
||||
}
|
||||
} [list 31427 {} {} {} \
|
||||
31429 {} {} {} \
|
||||
]
|
||||
do_test vtab1.7-12 {
|
||||
execsql {
|
||||
DELETE FROM echo_abc;
|
||||
SELECT last_insert_rowid();
|
||||
}
|
||||
} {31429}
|
||||
do_test vtab1.7-13 {
|
||||
execsql {
|
||||
SELECT rowid, a, b, c FROM real_abc
|
||||
}
|
||||
} {}
|
||||
|
||||
finish_test
|
||||
|
||||
|
Reference in New Issue
Block a user