Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Expose the sqlite3_stricmp() interface. Add the SQLITE_FCNTL_PRAGMA file control. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
c539cf21ef8f4eb4782790aa97a67d10 |
User & Date: | drh 2012-02-23 14:28:46.056 |
Context
2012-02-23
| ||
15:35 | Add the sqlite3PagerWalFramesize() function to pager.c. This is used by zipvfs. (check-in: 786e24dc56 user: dan tags: trunk) | |
14:28 | Expose the sqlite3_stricmp() interface. Add the SQLITE_FCNTL_PRAGMA file control. (check-in: c539cf21ef user: drh tags: trunk) | |
2012-02-22
| ||
20:08 | Move test logic for SQLITE_FCNTL_PRAGMA out of os_unix.c and into test_vfs.c. (Closed-Leaf check-in: c81fc40b2b user: drh tags: file-control-pragma) | |
2012-02-21
| ||
18:35 | Avoid redefining NDEBUG if the fuzzer is included in an amalagmated source file. (check-in: f8ac826f95 user: drh tags: trunk) | |
Changes
Changes to src/pragma.c.
︙ | ︙ | |||
308 309 310 311 312 313 314 | int minusFlag /* True if a '-' sign preceded <value> */ ){ char *zLeft = 0; /* Nul-terminated UTF-8 string <id> */ char *zRight = 0; /* Nul-terminated UTF-8 string <value>, or NULL */ const char *zDb = 0; /* The database name */ Token *pId; /* Pointer to <id> token */ int iDb; /* Database index for <database> */ | > > | | | > | 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 | int minusFlag /* True if a '-' sign preceded <value> */ ){ char *zLeft = 0; /* Nul-terminated UTF-8 string <id> */ char *zRight = 0; /* Nul-terminated UTF-8 string <value>, or NULL */ const char *zDb = 0; /* The database name */ Token *pId; /* Pointer to <id> token */ int iDb; /* Database index for <database> */ char *aFcntl[4]; /* Argument to SQLITE_FCNTL_PRAGMA */ int rc; /* return value form SQLITE_FCNTL_PRAGMA */ sqlite3 *db = pParse->db; /* The database connection */ Db *pDb; /* The specific database being pragmaed */ Vdbe *v = pParse->pVdbe = sqlite3VdbeCreate(db); /* Prepared statement */ if( v==0 ) return; sqlite3VdbeRunOnlyOnce(v); pParse->nMem = 2; /* Interpret the [database.] part of the pragma statement. iDb is the ** index of the database this pragma is being applied to in db.aDb[]. */ iDb = sqlite3TwoPartName(pParse, pId1, pId2, &pId); |
︙ | ︙ | |||
341 342 343 344 345 346 347 348 349 350 351 352 353 354 | } assert( pId2 ); zDb = pId2->n>0 ? pDb->zName : 0; if( sqlite3AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, zDb) ){ goto pragma_out; } #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) /* ** PRAGMA [database.]default_cache_size ** PRAGMA [database.]default_cache_size=N ** ** The first form reports the current persistent setting for the | > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 | } assert( pId2 ); zDb = pId2->n>0 ? pDb->zName : 0; if( sqlite3AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, zDb) ){ goto pragma_out; } /* Send an SQLITE_FCNTL_PRAGMA file-control to the underlying VFS ** connection. If it returns SQLITE_OK, then assume that the VFS ** handled the pragma and generate a no-op prepared statement. */ aFcntl[0] = 0; aFcntl[1] = zLeft; aFcntl[2] = zRight; aFcntl[3] = 0; rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_PRAGMA, (void*)aFcntl); if( rc==SQLITE_OK ){ if( aFcntl[0] ){ int mem = ++pParse->nMem; sqlite3VdbeAddOp4(v, OP_String8, 0, mem, 0, aFcntl[0], 0); sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "result", SQLITE_STATIC); sqlite3VdbeAddOp2(v, OP_ResultRow, mem, 1); sqlite3_free(aFcntl[0]); } }else if( rc!=SQLITE_NOTFOUND ){ if( aFcntl[0] ){ sqlite3ErrorMsg(pParse, "%s", aFcntl[0]); sqlite3_free(aFcntl[0]); } pParse->nErr++; pParse->rc = rc; } #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) /* ** PRAGMA [database.]default_cache_size ** PRAGMA [database.]default_cache_size=N ** ** The first form reports the current persistent setting for the |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
708 709 710 711 712 713 714 | ** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging. This ** opcode causes the xFileControl method to write the current state of ** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED], ** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE]) ** into an integer that the pArg argument points to. This capability ** is used during testing and only needs to be supported when SQLITE_TEST ** is defined. | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 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 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 | ** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging. This ** opcode causes the xFileControl method to write the current state of ** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED], ** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE]) ** into an integer that the pArg argument points to. This capability ** is used during testing and only needs to be supported when SQLITE_TEST ** is defined. ** <ul> ** <li>[[SQLITE_FCNTL_SIZE_HINT]] ** The [SQLITE_FCNTL_SIZE_HINT] opcode is used by SQLite to give the VFS ** layer a hint of how large the database file will grow to be during the ** current transaction. This hint is not guaranteed to be accurate but it ** is often close. The underlying VFS might choose to preallocate database ** file space based on this hint in order to help writes to the database ** file run faster. ** ** <li>[[SQLITE_FCNTL_CHUNK_SIZE]] ** The [SQLITE_FCNTL_CHUNK_SIZE] opcode is used to request that the VFS ** extends and truncates the database file in chunks of a size specified ** by the user. The fourth argument to [sqlite3_file_control()] should ** point to an integer (type int) containing the new chunk-size to use ** for the nominated database. Allocating database file space in large ** chunks (say 1MB at a time), may reduce file-system fragmentation and ** improve performance on some systems. ** ** <li>[[SQLITE_FCNTL_FILE_POINTER]] ** The [SQLITE_FCNTL_FILE_POINTER] opcode is used to obtain a pointer ** to the [sqlite3_file] object associated with a particular database ** connection. See the [sqlite3_file_control()] documentation for ** additional information. ** ** <li>[[SQLITE_FCNTL_SYNC_OMITTED]] ** ^(The [SQLITE_FCNTL_SYNC_OMITTED] opcode is generated internally by ** SQLite and sent to all VFSes in place of a call to the xSync method ** when the database connection has [PRAGMA synchronous] set to OFF.)^ ** Some specialized VFSes need this signal in order to operate correctly ** when [PRAGMA synchronous | PRAGMA synchronous=OFF] is set, but most ** VFSes do not need this signal and should silently ignore this opcode. ** Applications should not call [sqlite3_file_control()] with this ** opcode as doing so may disrupt the operation of the specialized VFSes ** that do require it. ** ** <li>[[SQLITE_FCNTL_WIN32_AV_RETRY]] ** ^The [SQLITE_FCNTL_WIN32_AV_RETRY] opcode is used to configure automatic ** retry counts and intervals for certain disk I/O operations for the ** windows [VFS] in order to provide robustness in the presence of ** anti-virus programs. By default, the windows VFS will retry file read, ** file write, and file delete operations up to 10 times, with a delay ** of 25 milliseconds before the first retry and with the delay increasing ** by an additional 25 milliseconds with each subsequent retry. This ** opcode allows these two values (10 retries and 25 milliseconds of delay) ** to be adjusted. The values are changed for all database connections ** within the same process. The argument is a pointer to an array of two ** integers where the first integer i the new retry count and the second ** integer is the delay. If either integer is negative, then the setting ** is not changed but instead the prior value of that setting is written ** into the array entry, allowing the current retry settings to be ** interrogated. The zDbName parameter is ignored. ** ** <li>[[SQLITE_FCNTL_PERSIST_WAL]] ** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the ** persistent [WAL | Write AHead Log] setting. By default, the auxiliary ** write ahead log and shared memory files used for transaction control ** are automatically deleted when the latest connection to the database ** closes. Setting persistent WAL mode causes those files to persist after ** close. Persisting the files is useful when other processes that do not ** have write permission on the directory containing the database file want ** to read the database file, as the WAL and shared memory files must exist ** in order for the database to be readable. The fourth parameter to ** [sqlite3_file_control()] for this opcode should be a pointer to an integer. ** That integer is 0 to disable persistent WAL mode or 1 to enable persistent ** WAL mode. If the integer is -1, then it is overwritten with the current ** WAL persistence setting. ** ** <li>[[SQLITE_FCNTL_POWERSAFE_OVERWRITE]] ** ^The [SQLITE_FCNTL_POWERSAFE_OVERWRITE] opcode is used to set or query the ** persistent "powersafe-overwrite" or "PSOW" setting. The PSOW setting ** determines the [SQLITE_IOCAP_POWERSAFE_OVERWRITE] bit of the ** xDeviceCharacteristics methods. The fourth parameter to ** [sqlite3_file_control()] for this opcode should be a pointer to an integer. ** That integer is 0 to disable zero-damage mode or 1 to enable zero-damage ** mode. If the integer is -1, then it is overwritten with the current ** zero-damage mode setting. ** ** <li>[[SQLITE_FCNTL_OVERWRITE]] ** ^The [SQLITE_FCNTL_OVERWRITE] opcode is invoked by SQLite after opening ** a write transaction to indicate that, unless it is rolled back for some ** reason, the entire database file will be overwritten by the current ** transaction. This is used by VACUUM operations. ** ** <li>[[SQLITE_FCNTL_VFSNAME]] ** ^The [SQLITE_FCNTL_VFSNAME] opcode can be used to obtain the names of ** all [VFSes] in the VFS stack. The names are of all VFS shims and the ** final bottom-level VFS are written into memory obtained from ** [sqlite3_malloc()] and the result is stored in the char* variable ** that the fourth parameter of [sqlite3_file_control()] points to. ** The caller is responsible for freeing the memory when done. As with ** all file-control actions, there is no guarantee that this will actually ** do anything. Callers should initialize the char* variable to a NULL ** pointer in case this file-control is not implemented. This file-control ** is intended for diagnostic use only. ** ** <li>[[SQLITE_FCNTL_PRAGMA]] ** ^Whenever a [PRAGMA] statement is parsed, an [SQLITE_FCNTL_PRAGMA] ** file control is sent to the open [sqlite3_file] object corresponding ** to the database file to which the pragma statement refers. ^The argument ** to the [SQLITE_FCNTL_PRAGMA] file control is an array of ** pointers to strings (char**) in which the second element of the array ** is the name of the pragma and the third element is the argument to the ** pragma or NULL if the pragma has no argument. ^The handler for an ** [SQLITE_FCNTL_PRAGMA] file control can optionally make the first element ** of the char** argument point to a string obtained from [sqlite3_mprintf()] ** or the equivalent and that string will become the result of the pragma or ** the error message if the pragma fails. ^If the ** [SQLITE_FCNTL_PRAGMA] file control returns [SQLITE_NOTFOUND], then normal ** [PRAGMA] processing continues. ^If the [SQLITE_FCNTL_PRAGMA] ** file control returns [SQLITE_OK], then the parser assumes that the ** VFS has handled the PRAGMA itself and the parser generates a no-op ** prepared statement. ^If the [SQLITE_FCNTL_PRAGMA] file control returns ** any result code other than [SQLITE_OK] or [SQLITE_NOTFOUND], that means ** that the VFS encountered an error while handling the [PRAGMA] and the ** compilation of the PRAGMA fails with an error. ^The [SQLITE_FCNTL_PRAGMA] ** file control occurs at the beginning of pragma statement analysis and so ** it is able to override built-in [PRAGMA] statements. ** </ul> */ #define SQLITE_FCNTL_LOCKSTATE 1 #define SQLITE_GET_LOCKPROXYFILE 2 #define SQLITE_SET_LOCKPROXYFILE 3 #define SQLITE_LAST_ERRNO 4 #define SQLITE_FCNTL_SIZE_HINT 5 #define SQLITE_FCNTL_CHUNK_SIZE 6 #define SQLITE_FCNTL_FILE_POINTER 7 #define SQLITE_FCNTL_SYNC_OMITTED 8 #define SQLITE_FCNTL_WIN32_AV_RETRY 9 #define SQLITE_FCNTL_PERSIST_WAL 10 #define SQLITE_FCNTL_OVERWRITE 11 #define SQLITE_FCNTL_VFSNAME 12 #define SQLITE_FCNTL_POWERSAFE_OVERWRITE 13 #define SQLITE_FCNTL_PRAGMA 14 /* ** CAPI3REF: Mutex Handle ** ** The mutex module within SQLite defines [sqlite3_mutex] to be an ** abstract type for a mutex object. The SQLite core never looks ** at the internal representation of an [sqlite3_mutex]. It only |
︙ | ︙ | |||
6581 6582 6583 6584 6585 6586 6587 | void *pNotifyArg /* Argument to pass to xNotify */ ); /* ** CAPI3REF: String Comparison ** | | | | | > | 6615 6616 6617 6618 6619 6620 6621 6622 6623 6624 6625 6626 6627 6628 6629 6630 6631 6632 6633 6634 | void *pNotifyArg /* Argument to pass to xNotify */ ); /* ** CAPI3REF: String Comparison ** ** ^The [sqlite3_stricmp()] and [sqlite3_strnicmp()] APIs allow applications ** and extensions to compare the contents of two buffers containing UTF-8 ** strings in a case-independent fashion, using the same definition of "case ** independence" that SQLite uses internally when comparing identifiers. */ int sqlite3_stricmp(const char *, const char *); int sqlite3_strnicmp(const char *, const char *, int); /* ** CAPI3REF: Error Logging Interface ** ** ^The [sqlite3_log()] interface writes a message into the error log ** established by the [SQLITE_CONFIG_LOG] option to [sqlite3_config()]. |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
2549 2550 2551 2552 2553 2554 2555 | # define sqlite3Isxdigit(x) isxdigit((unsigned char)(x)) # define sqlite3Tolower(x) tolower((unsigned char)(x)) #endif /* ** Internal function prototypes */ | | | 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 | # define sqlite3Isxdigit(x) isxdigit((unsigned char)(x)) # define sqlite3Tolower(x) tolower((unsigned char)(x)) #endif /* ** Internal function prototypes */ #define sqlite3StrICmp sqlite3_stricmp int sqlite3Strlen30(const char*); #define sqlite3StrNICmp sqlite3_strnicmp int sqlite3MallocInit(void); void sqlite3MallocEnd(void); void *sqlite3Malloc(int); void *sqlite3MallocZero(int); |
︙ | ︙ |
Changes to src/test_vfs.c.
︙ | ︙ | |||
476 477 478 479 480 481 482 483 484 485 486 487 488 489 | } /* ** File control method. For custom operations on an tvfs-file. */ static int tvfsFileControl(sqlite3_file *pFile, int op, void *pArg){ TestvfsFd *p = tvfsGetFd(pFile); return sqlite3OsFileControl(p->pReal, op, pArg); } /* ** Return the sector-size in bytes for an tvfs-file. */ static int tvfsSectorSize(sqlite3_file *pFile){ | > > > > > > > > > > > > > > > > > > > > > | 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 | } /* ** File control method. For custom operations on an tvfs-file. */ static int tvfsFileControl(sqlite3_file *pFile, int op, void *pArg){ TestvfsFd *p = tvfsGetFd(pFile); if( op==SQLITE_FCNTL_PRAGMA ){ char **argv = (char**)pArg; if( sqlite3_stricmp(argv[1],"error")==0 ){ int rc = SQLITE_ERROR; if( argv[2] ){ const char *z = argv[2]; int x = atoi(z); if( x ){ rc = x; while( sqlite3Isdigit(z[0]) ){ z++; } while( sqlite3Isspace(z[0]) ){ z++; } } if( z[0] ) argv[0] = sqlite3_mprintf("%s", z); } return rc; } if( sqlite3_stricmp(argv[1], "filename")==0 ){ argv[0] = sqlite3_mprintf("%s", p->zFilename); return SQLITE_OK; } } return sqlite3OsFileControl(p->pReal, op, pArg); } /* ** Return the sector-size in bytes for an tvfs-file. */ static int tvfsSectorSize(sqlite3_file *pFile){ |
︙ | ︙ |
Changes to src/test_vfstrace.c.
︙ | ︙ | |||
472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 | case SQLITE_FCNTL_FILE_POINTER: zOp = "FILE_POINTER"; break; case SQLITE_FCNTL_SYNC_OMITTED: zOp = "SYNC_OMITTED"; break; case SQLITE_FCNTL_WIN32_AV_RETRY: zOp = "WIN32_AV_RETRY"; break; case SQLITE_FCNTL_PERSIST_WAL: zOp = "PERSIST_WAL"; break; case SQLITE_FCNTL_OVERWRITE: zOp = "OVERWRITE"; break; case SQLITE_FCNTL_VFSNAME: zOp = "VFSNAME"; break; case 0xca093fa0: zOp = "DB_UNCHANGED"; break; default: { sqlite3_snprintf(sizeof zBuf, zBuf, "%d", op); zOp = zBuf; break; } } vfstrace_printf(pInfo, "%s.xFileControl(%s,%s)", pInfo->zVfsName, p->zFName, zOp); rc = p->pReal->pMethods->xFileControl(p->pReal, op, pArg); vfstrace_print_errcode(pInfo, " -> %s\n", rc); if( op==SQLITE_FCNTL_VFSNAME && rc==SQLITE_OK ){ *(char**)pArg = sqlite3_mprintf("vfstrace.%s/%z", pInfo->zVfsName, *(char**)pArg); } return rc; } /* ** Return the sector-size in bytes for an vfstrace-file. */ static int vfstraceSectorSize(sqlite3_file *pFile){ | > > > > > > > > > > | 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 | case SQLITE_FCNTL_FILE_POINTER: zOp = "FILE_POINTER"; break; case SQLITE_FCNTL_SYNC_OMITTED: zOp = "SYNC_OMITTED"; break; case SQLITE_FCNTL_WIN32_AV_RETRY: zOp = "WIN32_AV_RETRY"; break; case SQLITE_FCNTL_PERSIST_WAL: zOp = "PERSIST_WAL"; break; case SQLITE_FCNTL_OVERWRITE: zOp = "OVERWRITE"; break; case SQLITE_FCNTL_VFSNAME: zOp = "VFSNAME"; break; case 0xca093fa0: zOp = "DB_UNCHANGED"; break; case SQLITE_FCNTL_PRAGMA: { const char *const* a = (const char*const*)pArg; sqlite3_snprintf(sizeof(zBuf), zBuf, "PRAGMA,[%s,%s]",a[1],a[2]); zOp = zBuf; break; } default: { sqlite3_snprintf(sizeof zBuf, zBuf, "%d", op); zOp = zBuf; break; } } vfstrace_printf(pInfo, "%s.xFileControl(%s,%s)", pInfo->zVfsName, p->zFName, zOp); rc = p->pReal->pMethods->xFileControl(p->pReal, op, pArg); vfstrace_print_errcode(pInfo, " -> %s\n", rc); if( op==SQLITE_FCNTL_VFSNAME && rc==SQLITE_OK ){ *(char**)pArg = sqlite3_mprintf("vfstrace.%s/%z", pInfo->zVfsName, *(char**)pArg); } if( op==SQLITE_FCNTL_PRAGMA && rc==SQLITE_OK && *(char**)pArg ){ vfstrace_printf(pInfo, "%s.xFileControl(%s,%s) returns %s", pInfo->zVfsName, p->zFName, zOp, *(char**)pArg); } return rc; } /* ** Return the sector-size in bytes for an vfstrace-file. */ static int vfstraceSectorSize(sqlite3_file *pFile){ |
︙ | ︙ |
Changes to src/util.c.
︙ | ︙ | |||
218 219 220 221 222 223 224 | ** ** IMPLEMENTATION-OF: R-20522-24639 The sqlite3_strnicmp() API allows ** applications and extensions to compare the contents of two buffers ** containing UTF-8 strings in a case-independent fashion, using the same ** definition of case independence that SQLite uses internally when ** comparing identifiers. */ | | | 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 | ** ** IMPLEMENTATION-OF: R-20522-24639 The sqlite3_strnicmp() API allows ** applications and extensions to compare the contents of two buffers ** containing UTF-8 strings in a case-independent fashion, using the same ** definition of case independence that SQLite uses internally when ** comparing identifiers. */ int sqlite3_stricmp(const char *zLeft, const char *zRight){ register unsigned char *a, *b; a = (unsigned char *)zLeft; b = (unsigned char *)zRight; while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; } return UpperToLower[*a] - UpperToLower[*b]; } int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){ |
︙ | ︙ |
Changes to test/pragma.test.
︙ | ︙ | |||
1484 1485 1486 1487 1488 1489 1490 1491 1492 | execsql " PRAGMA temp_store=$::temp_setting; PRAGMA temp_store=$::temp_setting; PRAGMA temp_store; " } $val } finish_test | > > > > > > > > > > > > > > > > > > > > > > | 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 | execsql " PRAGMA temp_store=$::temp_setting; PRAGMA temp_store=$::temp_setting; PRAGMA temp_store; " } $val } # The SQLITE_FCNTL_PRAGMA logic, with error handling. # db close testvfs tvfs sqlite3 db test.db -vfs tvfs do_test pragma-19.1 { catchsql {PRAGMA error} } {1 {SQL logic error or missing database}} do_test pragma-19.2 { catchsql {PRAGMA error='This is the error message'} } {1 {This is the error message}} do_test pragma-19.3 { catchsql {PRAGMA error='7 This is the error message'} } {1 {This is the error message}} do_test pragma-19.4 { catchsql {PRAGMA error=7} } {1 {out of memory}} do_test pragma-19.5 { file tail [execsql {PRAGMA filename}] } {test.db} finish_test |