Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | A few more test cases to improve coverage of virtual table module related code. (CVS 3292) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
255aa9121a2ef4fec7fa5523e52969ac |
User & Date: | danielk1977 2006-06-24 11:51:33.000 |
Context
2006-06-24
| ||
12:39 | (OS/2) Armor OS/2 against accidental deletion of files, too (patch by Daniel Kruse, verified by me) (CVS 3293) (check-in: f357efb373 user: pweilbacher tags: trunk) | |
11:51 | A few more test cases to improve coverage of virtual table module related code. (CVS 3292) (check-in: 255aa9121a user: danielk1977 tags: trunk) | |
09:34 | Add tests to improve coverage of vtab.c. (CVS 3291) (check-in: 0c5f4ee39c user: danielk1977 tags: trunk) | |
Changes
Changes to src/func.c.
︙ | ︙ | |||
12 13 14 15 16 17 18 | ** This file contains the C functions that implement various SQL ** functions of SQLite. ** ** There is only one exported symbol in this file - the function ** sqliteRegisterBuildinFunctions() found at the bottom of the file. ** All other code has file scope. ** | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | ** This file contains the C functions that implement various SQL ** functions of SQLite. ** ** There is only one exported symbol in this file - the function ** sqliteRegisterBuildinFunctions() found at the bottom of the file. ** All other code has file scope. ** ** $Id: func.c,v 1.132 2006/06/24 11:51:33 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* #include <math.h> */ #include <stdlib.h> #include <assert.h> #include "vdbeInt.h" |
︙ | ︙ | |||
677 678 679 680 681 682 683 | #endif #ifndef SQLITE_OMIT_LOAD_EXTENSION /* ** A function that loads a shared-library extension then returns NULL. */ static void loadExt(sqlite3_context *context, int argc, sqlite3_value **argv){ | | | | 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 | #endif #ifndef SQLITE_OMIT_LOAD_EXTENSION /* ** A function that loads a shared-library extension then returns NULL. */ static void loadExt(sqlite3_context *context, int argc, sqlite3_value **argv){ const char *zFile = (const char *)sqlite3_value_text(argv[0]); const char *zProc = 0; sqlite3 *db = sqlite3_user_data(context); char *zErrMsg = 0; if( argc==2 ){ zProc = (const char *)sqlite3_value_text(argv[1]); } if( sqlite3_load_extension(db, zFile, zProc, &zErrMsg) ){ sqlite3_result_error(context, zErrMsg, -1); sqlite3_free(zErrMsg); } } #endif |
︙ | ︙ |
Changes to src/main.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** ** $Id: main.c,v 1.348 2006/06/24 11:51:33 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> /* ** The following constant value is used by the SQLITE_BIGENDIAN and |
︙ | ︙ | |||
470 471 472 473 474 475 476 477 478 479 480 481 482 483 | p = sqlite3FindFunction(db, zFunctionName, nName, nArg, enc, 1); if( p ){ p->flags = 0; p->xFunc = xFunc; p->xStep = xStep; p->xFinalize = xFinal; p->pUserData = pUserData; } return SQLITE_OK; } /* ** Create new user functions. */ | > | 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 | p = sqlite3FindFunction(db, zFunctionName, nName, nArg, enc, 1); if( p ){ p->flags = 0; p->xFunc = xFunc; p->xStep = xStep; p->xFinalize = xFinal; p->pUserData = pUserData; p->nArg = nArg; } return SQLITE_OK; } /* ** Create new user functions. */ |
︙ | ︙ |
Changes to src/test8.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the virtual table interfaces. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the virtual table interfaces. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** ** $Id: test8.c,v 1.37 2006/06/24 11:51:34 danielk1977 Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include "os.h" #include <stdlib.h> #include <string.h> |
︙ | ︙ | |||
185 186 187 188 189 190 191 | rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); sqliteFree(zSql); /* For each index, figure out the left-most column and set the ** corresponding entry in aIndex[] to 1. */ while( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){ | | | 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); sqliteFree(zSql); /* For each index, figure out the left-most column and set the ** corresponding entry in aIndex[] to 1. */ while( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){ const char *zIdx = (const char *)sqlite3_column_text(pStmt, 1); sqlite3_stmt *pStmt2 = 0; zSql = sqlite3MPrintf("PRAGMA index_info(%s)", zIdx); if( !zSql ){ rc = SQLITE_NOMEM; goto get_index_array_out; } rc = sqlite3_prepare(db, zSql, -1, &pStmt2, 0); |
︙ | ︙ | |||
264 265 266 267 268 269 270 | if( argc>=4 ){ sqlite3_stmt *pStmt = 0; sqlite3_prepare(db, "SELECT sql FROM sqlite_master WHERE type = 'table' AND name = ?", -1, &pStmt, 0); sqlite3_bind_text(pStmt, 1, argv[3], -1, 0); if( sqlite3_step(pStmt)==SQLITE_ROW ){ | | | 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 | if( argc>=4 ){ sqlite3_stmt *pStmt = 0; sqlite3_prepare(db, "SELECT sql FROM sqlite_master WHERE type = 'table' AND name = ?", -1, &pStmt, 0); sqlite3_bind_text(pStmt, 1, argv[3], -1, 0); if( sqlite3_step(pStmt)==SQLITE_ROW ){ const char *zCreateTable = (const char *)sqlite3_column_text(pStmt, 0); sqlite3_declare_vtab(db, zCreateTable); rc = sqlite3_finalize(pStmt); } else { rc = sqlite3_finalize(pStmt); if( rc==SQLITE_OK ){ rc = SQLITE_ERROR; } |
︙ | ︙ | |||
538 539 540 541 542 543 544 | /* Check that idxNum matches idxStr */ assert( idxNum==hashString(idxStr) ); /* Log arguments to the ::echo_module Tcl variable */ appendToEchoModule(pVtab->interp, "xFilter"); appendToEchoModule(pVtab->interp, idxStr); for(i=0; i<argc; i++){ | | | 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 | /* Check that idxNum matches idxStr */ assert( idxNum==hashString(idxStr) ); /* Log arguments to the ::echo_module Tcl variable */ appendToEchoModule(pVtab->interp, "xFilter"); appendToEchoModule(pVtab->interp, idxStr); for(i=0; i<argc; i++){ appendToEchoModule(pVtab->interp, (const char*)sqlite3_value_text(argv[i])); } sqlite3_finalize(pCur->pStmt); pCur->pStmt = 0; /* Prepare the SQL statement created by echoBestIndex and bind the ** runtime parameters passed to this function to it. |
︙ | ︙ | |||
691 692 693 694 695 696 697 | } /* If there is only one term in the ORDER BY clause, and it is ** on a column that this virtual table has an index for, then consume ** the ORDER BY clause. */ if( pIdxInfo->nOrderBy==1 && pVtab->aIndex[pIdxInfo->aOrderBy->iColumn] ){ | > | > > > | 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 | } /* If there is only one term in the ORDER BY clause, and it is ** on a column that this virtual table has an index for, then consume ** the ORDER BY clause. */ if( pIdxInfo->nOrderBy==1 && pVtab->aIndex[pIdxInfo->aOrderBy->iColumn] ){ int iCol = pIdxInfo->aOrderBy->iColumn; char *zCol = pVtab->aCol[iCol]; char *zDir = pIdxInfo->aOrderBy->desc?"DESC":"ASC"; if( iCol<0 ){ zCol = "rowid"; } zNew = sqlite3_mprintf(" ORDER BY %s %s", zCol, zDir); string_concat(&zQuery, zNew, 1); pIdxInfo->orderByConsumed = 1; } appendToEchoModule(pVtab->interp, "xBestIndex");; appendToEchoModule(pVtab->interp, zQuery); |
︙ | ︙ | |||
961 962 963 964 965 966 967 | if( objc!=3 ){ Tcl_WrongNumArgs(interp, 1, objv, "DB SQL"); return TCL_ERROR; } if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; rc = sqlite3_declare_vtab(db, Tcl_GetString(objv[2])); if( rc!=SQLITE_OK ){ | | | 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 | if( objc!=3 ){ Tcl_WrongNumArgs(interp, 1, objv, "DB SQL"); return TCL_ERROR; } if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; rc = sqlite3_declare_vtab(db, Tcl_GetString(objv[2])); if( rc!=SQLITE_OK ){ Tcl_SetResult(interp, (char *)sqlite3_errmsg(db), TCL_VOLATILE); return TCL_ERROR; } return TCL_OK; } #endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */ |
︙ | ︙ |
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 | ** 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.132 2006/06/24 11:51:34 danielk1977 Exp $ */ #include "sqliteInt.h" /* Forward declaration */ static void updateVirtualTable( Parse *pParse, /* The parsing context */ SrcList *pSrc, /* The virtual table to be modified */ |
︙ | ︙ | |||
567 568 569 570 571 572 573 574 | /* 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, sqlite3ExprDup(pRowid), 0); } for(i=0; i<pTab->nCol; i++){ | > < < | | 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 | /* 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, sqlite3ExprDup(pRowid), 0); } assert( pTab->iPKey<0 ); for(i=0; i<pTab->nCol; i++){ 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); |
︙ | ︙ |
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.569 2006/06/24 11:51:34 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> #include "vdbeInt.h" /* |
︙ | ︙ | |||
4544 4545 4546 4547 4548 4549 4550 | sqlite3SetString(&p->zErrMsg, "database table is locked: ", z, (char*)0); } break; } #endif /* SQLITE_OMIT_SHARED_CACHE */ #ifndef SQLITE_OMIT_VIRTUALTABLE | | | | 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 | sqlite3SetString(&p->zErrMsg, "database table is locked: ", z, (char*)0); } break; } #endif /* SQLITE_OMIT_SHARED_CACHE */ #ifndef SQLITE_OMIT_VIRTUALTABLE /* Opcode: VBegin * * P3 ** ** P3 a pointer to an sqlite3_vtab structure. Call the xBegin method ** for that table. */ case OP_VBegin: { /* no-push */ rc = sqlite3VtabBegin(db, (sqlite3_vtab *)pOp->p3); break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
257 258 259 260 261 262 263 | #endif ){ if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2; }else if( opcode==OP_Halt ){ if( pOp->p1==SQLITE_CONSTRAINT && pOp->p2==OE_Abort ){ doesStatementRollback = 1; } | < < < < | 257 258 259 260 261 262 263 264 265 266 267 268 269 270 | #endif ){ if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2; }else if( opcode==OP_Halt ){ if( pOp->p1==SQLITE_CONSTRAINT && pOp->p2==OE_Abort ){ doesStatementRollback = 1; } }else if( opcode==OP_Statement ){ hasStatementBegin = 1; }else if( opcode==OP_VFilter ){ int n; assert( p->nOp - i >= 3 ); assert( pOp[-2].opcode==OP_Integer ); n = pOp[-2].p1; |
︙ | ︙ | |||
1380 1381 1382 1383 1384 1385 1386 | /* Rollback or commit any schema changes that occurred. */ if( p->rc!=SQLITE_OK && db->flags&SQLITE_InternChanges ){ sqlite3ResetInternalSchema(db, 0); db->flags = (db->flags | SQLITE_InternChanges); } } | > | | 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 | /* Rollback or commit any schema changes that occurred. */ if( p->rc!=SQLITE_OK && db->flags&SQLITE_InternChanges ){ sqlite3ResetInternalSchema(db, 0); db->flags = (db->flags | SQLITE_InternChanges); } } /* We have successfully halted and closed the VM. Record this fact. */ if( p->pc>=0 ){ db->activeVdbeCnt--; } p->magic = VDBE_MAGIC_HALT; checkActiveVdbeCnt(db); return SQLITE_OK; } |
︙ | ︙ |
Changes to src/where.c.
︙ | ︙ | |||
12 13 14 15 16 17 18 | ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. This module is reponsible for ** generating the code that loops through a table looking for applicable ** rows. Indices are selected and used to speed the search when doing ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. This module is reponsible for ** generating the code that loops through a table looking for applicable ** rows. Indices are selected and used to speed the search when doing ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** ** $Id: where.c,v 1.223 2006/06/24 11:51:35 danielk1977 Exp $ */ #include "sqliteInt.h" /* ** The number of bits in a Bitmask. "BMS" means "BitMask Size". */ #define BMS (sizeof(Bitmask)*8) |
︙ | ︙ | |||
1896 1897 1898 1899 1900 1901 1902 | zMsg = sqlite3MPrintf("%z WITH INDEX %s", zMsg, pIx->zName); }else if( pLevel->flags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){ zMsg = sqlite3MPrintf("%z USING PRIMARY KEY", zMsg); } #ifndef SQLITE_OMIT_VIRTUALTABLE else if( pLevel->pIdxInfo ){ sqlite3_index_info *pIdxInfo = pLevel->pIdxInfo; | | | 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 | zMsg = sqlite3MPrintf("%z WITH INDEX %s", zMsg, pIx->zName); }else if( pLevel->flags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){ zMsg = sqlite3MPrintf("%z USING PRIMARY KEY", zMsg); } #ifndef SQLITE_OMIT_VIRTUALTABLE else if( pLevel->pIdxInfo ){ sqlite3_index_info *pIdxInfo = pLevel->pIdxInfo; zMsg = sqlite3MPrintf("%z VIRTUAL TABLE INDEX %d:%s", zMsg, pIdxInfo->idxNum, pIdxInfo->idxStr); } #endif if( pLevel->flags & WHERE_ORDERBY ){ zMsg = sqlite3MPrintf("%z ORDER BY", zMsg); } sqlite3VdbeOp3(v, OP_Explain, i, pLevel->iFrom, zMsg, P3_DYNAMIC); |
︙ | ︙ |
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.33 2006/06/24 11:51:35 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable !vtab||!schema_pragmas { finish_test return |
︙ | ︙ | |||
799 800 801 802 803 804 805 806 807 808 | } {1 {library routine called out of sequence}} do_test vtab1.10-3 { set ::echo_module_begin_fail r catchsql { INSERT INTO e VALUES(1, 2, 3); } } {1 {SQL logic error or missing database}} finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 | } {1 {library routine called out of sequence}} do_test vtab1.10-3 { set ::echo_module_begin_fail r catchsql { INSERT INTO e VALUES(1, 2, 3); } } {1 {SQL logic error or missing database}} do_test vtab1.10-4 { catch {execsql { EXPLAIN SELECT * FROM e WHERE rowid = 2; EXPLAIN QUERY PLAN SELECT * FROM e WHERE rowid = 2 ORDER BY rowid; }} } {0} do_test vtab1.10-5 { set echo_module "" execsql { SELECT * FROM e WHERE rowid||'' MATCH 'pattern'; } set echo_module } [list \ xBestIndex {SELECT rowid, * FROM 'r'} \ xFilter {SELECT rowid, * FROM 'r'} \ ] proc match_func {args} {return ""} do_test vtab1.10-6 { set echo_module "" db function match match_func execsql { SELECT * FROM e WHERE match('pattern', rowid, 'pattern2'); } set echo_module } [list \ xBestIndex {SELECT rowid, * FROM 'r'} \ xFilter {SELECT rowid, * FROM 'r'} \ ] finish_test |