Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Rework the way UPDATE works for virtual tables. (CVS 3262) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
2119e7bf5577350e4e1236ea72956808 |
User & Date: | drh 2006-06-16 21:13:22.000 |
Context
2006-06-17
| ||
03:27 | Fixes for UPDATE statements on virtual tables. (CVS 3263) (check-in: 81c5a5b48b user: danielk1977 tags: trunk) | |
2006-06-16
| ||
21:13 | Rework the way UPDATE works for virtual tables. (CVS 3262) (check-in: 2119e7bf55 user: drh tags: trunk) | |
16:08 | Add code to invoke the virtual table transaction interface. Untested at this point. (CVS 3261) (check-in: 6125140228 user: danielk1977 tags: trunk) | |
Changes
Changes to src/select.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** ** $Id: select.c,v 1.315 2006/06/16 21:13:22 drh Exp $ */ #include "sqliteInt.h" /* ** Delete all the content of a Select structure but do not deallocate ** the select structure itself. |
︙ | ︙ | |||
183 184 185 186 187 188 189 | p->n = z ? strlen(z) : 0; p->dyn = 0; } /* ** Create an expression node for an identifier with the name of zName */ | | | 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 | p->n = z ? strlen(z) : 0; p->dyn = 0; } /* ** Create an expression node for an identifier with the name of zName */ Expr *sqlite3CreateIdExpr(const char *zName){ Token dummy; setToken(&dummy, zName); return sqlite3Expr(TK_ID, 0, 0, &dummy); } /* |
︙ | ︙ | |||
207 208 209 210 211 212 213 | int iRightJoinTable, /* VDBE cursor for the right table */ Expr **ppExpr /* Add the equality term to this expression */ ){ Expr *pE1a, *pE1b, *pE1c; Expr *pE2a, *pE2b, *pE2c; Expr *pE; | | | | | | 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 | int iRightJoinTable, /* VDBE cursor for the right table */ Expr **ppExpr /* Add the equality term to this expression */ ){ Expr *pE1a, *pE1b, *pE1c; Expr *pE2a, *pE2b, *pE2c; Expr *pE; pE1a = sqlite3CreateIdExpr(zCol); pE2a = sqlite3CreateIdExpr(zCol); if( zAlias1==0 ){ zAlias1 = pTab1->zName; } pE1b = sqlite3CreateIdExpr(zAlias1); if( zAlias2==0 ){ zAlias2 = pTab2->zName; } pE2b = sqlite3CreateIdExpr(zAlias2); pE1c = sqlite3Expr(TK_DOT, pE1b, pE1a, 0); pE2c = sqlite3Expr(TK_DOT, pE2b, pE2a, 0); pE = sqlite3Expr(TK_EQ, pE1c, pE2c, 0); ExprSetProperty(pE, EP_FromJoin); pE->iRightJoinTable = iRightJoinTable; *ppExpr = sqlite3ExprAnd(*ppExpr, pE); } |
︙ | ︙ |
Changes to src/sqlite3ext.h.
︙ | ︙ | |||
11 12 13 14 15 16 17 | ************************************************************************* ** This header file defines the SQLite interface for use by ** shared libraries that want to be imported as extensions into ** an SQLite instance. Shared libraries that intend to be loaded ** as extensions by SQLite should #include this file instead of ** sqlite3.h. ** | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ************************************************************************* ** This header file defines the SQLite interface for use by ** shared libraries that want to be imported as extensions into ** an SQLite instance. Shared libraries that intend to be loaded ** as extensions by SQLite should #include this file instead of ** sqlite3.h. ** ** @(#) $Id: sqlite3ext.h,v 1.3 2006/06/16 21:13:22 drh Exp $ */ #ifndef _SQLITE3EXT_H_ #define _SQLITE3EXT_H_ #include <sqlite3.h> typedef struct sqlite3_api_routines sqlite3_api_routines; |
︙ | ︙ | |||
70 71 72 73 74 75 76 | void * (*commit_hook)(sqlite3*,int(*)(void*),void*); int (*complete)(const char*sql); int (*complete16)(const void*sql); int (*create_collation)(sqlite3*,const char*,int,void*,int(*)(void*,int,const void*,int,const void*)); int (*create_collation16)(sqlite3*,const char*,int,void*,int(*)(void*,int,const void*,int,const void*)); int (*create_function)(sqlite3*,const char*,int,int,void*,void (*xFunc)(sqlite3_context*,int,sqlite3_value**),void (*xStep)(sqlite3_context*,int,sqlite3_value**),void (*xFinal)(sqlite3_context*)); int (*create_function16)(sqlite3*,const void*,int,int,void*,void (*xFunc)(sqlite3_context*,int,sqlite3_value**),void (*xStep)(sqlite3_context*,int,sqlite3_value**),void (*xFinal)(sqlite3_context*)); | | | 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | void * (*commit_hook)(sqlite3*,int(*)(void*),void*); int (*complete)(const char*sql); int (*complete16)(const void*sql); int (*create_collation)(sqlite3*,const char*,int,void*,int(*)(void*,int,const void*,int,const void*)); int (*create_collation16)(sqlite3*,const char*,int,void*,int(*)(void*,int,const void*,int,const void*)); int (*create_function)(sqlite3*,const char*,int,int,void*,void (*xFunc)(sqlite3_context*,int,sqlite3_value**),void (*xStep)(sqlite3_context*,int,sqlite3_value**),void (*xFinal)(sqlite3_context*)); int (*create_function16)(sqlite3*,const void*,int,int,void*,void (*xFunc)(sqlite3_context*,int,sqlite3_value**),void (*xStep)(sqlite3_context*,int,sqlite3_value**),void (*xFinal)(sqlite3_context*)); int (*create_module)(sqlite3*,const char*,const sqlite3_module*,void*); int (*data_count)(sqlite3_stmt*pStmt); sqlite3 * (*db_handle)(sqlite3_stmt*); int (*declare_vtab)(sqlite3*,const char*); int (*enable_shared_cache)(int); int (*errcode)(sqlite3*db); const char * (*errmsg)(sqlite3*); const void * (*errmsg16)(sqlite3*); |
︙ | ︙ |
Changes to src/sqliteInt.h.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** ** @(#) $Id: sqliteInt.h,v 1.509 2006/06/16 21:13:22 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ /* ** Extra interface definitions for those who need them */ |
︙ | ︙ | |||
1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 | int sqlite3ExprCheck(Parse*, Expr*, int, int*); int sqlite3ExprCompare(Expr*, Expr*); int sqliteFuncId(Token*); int sqlite3ExprResolveNames(NameContext *, Expr *); int sqlite3ExprAnalyzeAggregates(NameContext*, Expr*); int sqlite3ExprAnalyzeAggList(NameContext*,ExprList*); Vdbe *sqlite3GetVdbe(Parse*); void sqlite3Randomness(int, void*); void sqlite3RollbackAll(sqlite3*); void sqlite3CodeVerifySchema(Parse*, int); void sqlite3BeginTransaction(Parse*, int); void sqlite3CommitTransaction(Parse*); void sqlite3RollbackTransaction(Parse*); int sqlite3ExprIsConstant(Expr*); | > | 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 | int sqlite3ExprCheck(Parse*, Expr*, int, int*); int sqlite3ExprCompare(Expr*, Expr*); int sqliteFuncId(Token*); int sqlite3ExprResolveNames(NameContext *, Expr *); int sqlite3ExprAnalyzeAggregates(NameContext*, Expr*); int sqlite3ExprAnalyzeAggList(NameContext*,ExprList*); Vdbe *sqlite3GetVdbe(Parse*); Expr *sqlite3CreateIdExpr(const char*); void sqlite3Randomness(int, void*); void sqlite3RollbackAll(sqlite3*); void sqlite3CodeVerifySchema(Parse*, int); void sqlite3BeginTransaction(Parse*, int); void sqlite3CommitTransaction(Parse*); void sqlite3RollbackTransaction(Parse*); int sqlite3ExprIsConstant(Expr*); |
︙ | ︙ |
Changes to src/update.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle UPDATE statements. ** | | > > > > > > > > > > > | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle UPDATE statements. ** ** $Id: update.c,v 1.127 2006/06/16 21:13:22 drh Exp $ */ #include "sqliteInt.h" /* Forward declaration */ static void updateVirtualTable( Parse *pParse, /* The parsing context */ SrcList *pSrc, /* The virtual table to be modified */ Table *pTab, /* The virtual table */ ExprList *pChanges, /* The columns to change in the UPDATE statement */ Expr *pRowidExpr, /* Expression used to recompute the rowid */ int *aXRef, /* Mapping from columns of pTab to entries in pChanges */ Expr *pWhere /* WHERE clause of the UPDATE statement */ ); /* ** The most recently coded instruction was an OP_Column to retrieve the ** i-th column of table pTab. This routine sets the P3 parameter of the ** OP_Column to the default value, if any. ** ** The default value of a column is specified by a DEFAULT clause in the |
︙ | ︙ | |||
238 239 240 241 242 243 244 | apIdx[nIdx++] = pIdx; aIdxUsed[j] = 1; }else{ aIdxUsed[j] = 0; } } | < < < < < < < > > > > > > > > > > > > > > > > > > | 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 | apIdx[nIdx++] = pIdx; aIdxUsed[j] = 1; }else{ aIdxUsed[j] = 0; } } /* Start the view context */ if( isView ){ sqlite3AuthContextPush(pParse, &sContext, pTab->zName); } /* Begin generating code. */ v = sqlite3GetVdbe(pParse); if( v==0 ) goto update_cleanup; if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); sqlite3BeginWriteOperation(pParse, 1, iDb); #ifndef SQLITE_OMIT_VIRTUALTABLE /* Virtual tables must be handled separately */ if( IsVirtual(pTab) ){ updateVirtualTable(pParse, pTabList, pTab, pChanges, pRowidExpr, aXRef, pWhere); pWhere = 0; pTabList = 0; goto update_cleanup; } #endif /* Resolve the column names in all the expressions in the ** WHERE clause. */ if( sqlite3ExprResolveNames(&sNC, pWhere) ){ goto update_cleanup; } /* If we are trying to update a view, realize that view into ** a ephemeral table. */ if( isView ){ Select *pView; pView = sqlite3SelectDup(pTab->pSelect); |
︙ | ︙ | |||
440 441 442 443 444 445 446 | } /* Create the new index entries and the new record. */ sqlite3CompleteInsertion(pParse, pTab, iCur, aIdxUsed, chngRowid, 1, -1); } | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 462 463 464 465 466 467 468 469 470 471 472 473 474 475 | } /* Create the new index entries and the new record. */ sqlite3CompleteInsertion(pParse, pTab, iCur, aIdxUsed, chngRowid, 1, -1); } /* Increment the row counter */ if( db->flags & SQLITE_CountRows && !pParse->trigStack){ sqlite3VdbeAddOp(v, OP_AddImm, 1, 0); } /* If there are triggers, close all the cursors after each iteration |
︙ | ︙ | |||
507 508 509 510 511 512 513 | /* Repeat the above with the next record to be updated, until ** all record selected by the WHERE clause have been updated. */ sqlite3VdbeAddOp(v, OP_Goto, 0, addr); sqlite3VdbeJumpHere(v, addr); /* Close all tables if there were no FOR EACH ROW triggers */ | | | 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 | /* Repeat the above with the next record to be updated, until ** all record selected by the WHERE clause have been updated. */ sqlite3VdbeAddOp(v, OP_Goto, 0, addr); sqlite3VdbeJumpHere(v, addr); /* Close all tables if there were no FOR EACH ROW triggers */ if( !triggers_exist ){ for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ if( openAll || aIdxUsed[i] ){ sqlite3VdbeAddOp(v, OP_Close, iCur+i+1, 0); } } sqlite3VdbeAddOp(v, OP_Close, iCur, 0); }else{ |
︙ | ︙ | |||
539 540 541 542 543 544 545 | sqliteFree(apIdx); sqliteFree(aXRef); sqlite3SrcListDelete(pTabList); sqlite3ExprListDelete(pChanges); sqlite3ExprDelete(pWhere); return; } | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 | sqliteFree(apIdx); sqliteFree(aXRef); sqlite3SrcListDelete(pTabList); sqlite3ExprListDelete(pChanges); sqlite3ExprDelete(pWhere); return; } #ifndef SQLITE_OMIT_VIRTUALTABLE /* ** Generate code for an UPDATE of a virtual table. ** ** The strategy is that we create an ephemerial table that contains ** for each row to be changed: ** ** (A) The original rowid of that row. ** (B) The revised rowid for the row. (note1) ** (C) The content of every column in the row. ** ** Then we loop over this ephemeral table and for each row in ** the ephermeral table call VUpdate. ** ** When finished, drop the ephemeral table. ** ** (note1) Actually, if we know in advance that (A) is always the same ** as (B) we only store (A), then duplicate (A) when pulling ** it out of the ephemeral table before calling VUpdate. */ static void updateVirtualTable( Parse *pParse, /* The parsing context */ SrcList *pSrc, /* The virtual table to be modified */ Table *pTab, /* The virtual table */ ExprList *pChanges, /* The columns to change in the UPDATE statement */ Expr *pRowid, /* Expression used to recompute the rowid */ int *aXRef, /* Mapping from columns of pTab to entries in pChanges */ Expr *pWhere /* WHERE clause of the UPDATE statement */ ){ Vdbe *v = pParse->pVdbe; /* Virtual machine under construction */ ExprList *pEList = 0; /* The result set of the SELECT statement */ Select *pSelect = 0; /* The SELECT statement */ Expr *pExpr; /* Temporary expression */ int ephemTab; /* Table holding the result of the SELECT */ int i; /* Loop counter */ int addr; /* Address of top of loop */ /* Construct the SELECT statement that will find the new values for ** all updated rows. */ pEList = sqlite3ExprListAppend(0, sqlite3CreateIdExpr("_rowid_"), 0); if( pRowid ){ pEList = sqlite3ExprListAppend(pEList, pRowid, 0); } for(i=0; i<pTab->nCol; i++){ if( i==pTab->iPKey ){ pExpr = sqlite3Expr(TK_NULL, 0, 0, 0); }else if( aXRef[i]>=0 ){ pExpr = sqlite3ExprDup(pChanges->a[aXRef[i]].pExpr); }else{ pExpr = sqlite3CreateIdExpr(pTab->aCol[i].zName); } pEList = sqlite3ExprListAppend(pEList, pExpr, 0); } pSelect = sqlite3SelectNew(pEList, pSrc, pWhere, 0, 0, 0, 0, 0, 0); /* Create the ephemeral table into which the update results will ** be stored. */ assert( v ); ephemTab = pParse->nTab++; sqlite3VdbeAddOp(v, OP_OpenEphemeral, ephemTab, pTab->nCol+1+(pRowid!=0)); /* fill the ephemeral table */ sqlite3Select(pParse, pSelect, SRT_Table, ephemTab, 0, 0, 0, 0); /* ** Generate code to scan the ephemeral table and call VDelete and ** VInsert */ sqlite3VdbeAddOp(v, OP_Rewind, ephemTab, 0); addr = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp(v, OP_Column, ephemTab, 0); if( pRowid ){ sqlite3VdbeAddOp(v, OP_Column, ephemTab, 1); }else{ sqlite3VdbeAddOp(v, OP_Dup, 1, 0); } for(i=0; i<pTab->nCol; i++){ sqlite3VdbeAddOp(v, OP_Column, ephemTab, i+1+(pRowid!=0)); } sqlite3VdbeOp3(v, OP_VUpdate, 0, pTab->nCol+2, (const char*)pTab->pVtab, P3_VTAB); sqlite3VdbeAddOp(v, OP_Next, ephemTab, addr); sqlite3VdbeAddOp(v, OP_Close, ephemTab, 0); /* Cleanup */ sqlite3SelectDelete(pSelect); } #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
Changes to src/vdbe.c.
︙ | ︙ | |||
39 40 41 42 43 44 45 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** 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.564 2006/06/16 21:13:22 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> #include "vdbeInt.h" /* |
︙ | ︙ | |||
4768 4769 4770 4771 4772 4773 4774 | } } break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ | < < < < < < < < < < < < < < < | < < < < | 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4797 4798 | } } break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ #ifndef SQLITE_OMIT_VIRTUALTABLE /* 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 ** are taken from the stack to pass to the xUpdate invocation. The ** value on the top of the stack corresponds to the p2th element ** of the argv array passed to xUpdate. ** ** The xUpdate method will do a DELETE or an INSERT or both. ** The argv[0] element (which corresponds to the P2-th element down ** on the stack) is the rowid of a row to delete. If argv[0] is ** NULL then no deletion occurs. The argv[1] element is the rowid ** of the new row. This can be NULL to have the virtual table ** select the new rowid for itself. The higher elements in the ** stack are the values of columns in the new row. ** ** 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. |
︙ | ︙ | |||
4826 4827 4828 4829 4830 4831 4832 | 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++){ | > | | 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 | 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++){ storeTypeInfo(pX, 0); apArg[i] = pX; } if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; 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; |
︙ | ︙ |
Changes to test/vtab1.test.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 2006 June 10 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is creating and dropping virtual tables. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 2006 June 10 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is creating and dropping virtual tables. # # $Id: vtab1.test,v 1.19 2006/06/16 21:13:23 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable !vtab { finish_test return |
︙ | ︙ | |||
404 405 406 407 408 409 410 411 412 413 414 415 416 417 | } [list xBestIndex {SELECT rowid, * FROM 'treal'} \ xFilter {SELECT rowid, * FROM 'treal'} ] execsql { DROP TABLE t1; DROP TABLE treal; } #---------------------------------------------------------------------- # Test cases vtab1-6 test INSERT, UPDATE and DELETE operations # on virtual tables. do_test vtab1-6-1 { execsql { SELECT sql FROM sqlite_master } } {} | > > | 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 | } [list xBestIndex {SELECT rowid, * FROM 'treal'} \ xFilter {SELECT rowid, * FROM 'treal'} ] execsql { DROP TABLE t1; DROP TABLE treal; } if 0 { # FIXME #---------------------------------------------------------------------- # Test cases vtab1-6 test INSERT, UPDATE and DELETE operations # on virtual tables. do_test vtab1-6-1 { execsql { SELECT sql FROM sqlite_master } } {} |
︙ | ︙ | |||
456 457 458 459 460 461 462 463 464 465 466 467 468 469 | do_test vtab1-6-7 { execsql { DELETE FROM techo; SELECT * FROM techo; } } {} file delete -force test2.db file delete -force test2.db-journal sqlite3 db2 test2.db execsql { CREATE TABLE techo(a PRIMARY KEY, b, c); } db2 | > | 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 | do_test vtab1-6-7 { execsql { DELETE FROM techo; SELECT * FROM techo; } } {} file delete -force test2.db file delete -force test2.db-journal sqlite3 db2 test2.db execsql { CREATE TABLE techo(a PRIMARY KEY, b, c); } db2 |
︙ | ︙ | |||
487 488 489 490 491 492 493 494 495 496 497 498 499 500 | ] { execsql $stmt execsql $stmt db2 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 { | > > | 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 | ] { execsql $stmt execsql $stmt db2 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 { |
︙ | ︙ | |||
576 577 578 579 580 581 582 583 584 | } } {31429} do_test vtab1.7-13 { execsql { SELECT rowid, a, b, c FROM real_abc } } {} finish_test | > < | 581 582 583 584 585 586 587 588 589 590 | } } {31429} do_test vtab1.7-13 { execsql { SELECT rowid, a, b, c FROM real_abc } } {} } ;# END if 0 finish_test |