Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Change the SQLITE_FCNTL_PRAGMA file-control so that it can return a string value. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | file-control-pragma |
Files: | files | file ages | folders |
SHA1: |
fd8d7440277b17f57a6dc0a210f42adf |
User & Date: | drh 2012-02-22 16:58:36.697 |
Context
2012-02-22
| ||
18:21 | Make benign any malloc failures inside the sqlite3_file_control() call within PRAGMA parsing. Add a couple simple tests for SQLITE_FCNTL_PRAGMA. (check-in: a1f29fa653 user: drh tags: file-control-pragma) | |
16:58 | Change the SQLITE_FCNTL_PRAGMA file-control so that it can return a string value. (check-in: fd8d744027 user: drh tags: file-control-pragma) | |
14:45 | Begin adding support for SQLITE_FCNTL_PRAGMA. (check-in: 5be07904ba user: drh tags: file-control-pragma) | |
Changes
Changes to src/os_unix.c.
︙ | ︙ | |||
3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 | case SQLITE_FCNTL_POWERSAFE_OVERWRITE: { unixModeBit(pFile, UNIXFILE_PSOW, (int*)pArg); return SQLITE_OK; } case SQLITE_FCNTL_VFSNAME: { *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName); return SQLITE_OK; } #ifndef NDEBUG /* The pager calls this method to signal that it has done ** a rollback and that the database is therefore unchanged and ** it hence it is OK for the transaction change counter to be ** unchanged. */ | > > > > > > > > | 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 | case SQLITE_FCNTL_POWERSAFE_OVERWRITE: { unixModeBit(pFile, UNIXFILE_PSOW, (int*)pArg); return SQLITE_OK; } case SQLITE_FCNTL_VFSNAME: { *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName); return SQLITE_OK; } case SQLITE_FCNTL_PRAGMA: { char **azArg = (char**)pArg; if( sqlite3_stricmp(azArg[1], "filename")==0 ){ azArg[0] = sqlite3_mprintf("%s", pFile->zPath); return SQLITE_OK; } break; } #ifndef NDEBUG /* The pager calls this method to signal that it has done ** a rollback and that the database is therefore unchanged and ** it hence it is OK for the transaction change counter to be ** unchanged. */ |
︙ | ︙ |
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 | 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); |
︙ | ︙ | |||
349 350 351 352 353 354 355 | 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. */ | | | | > > | > > > > > | > | 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 | 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 !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) /* ** PRAGMA [database.]default_cache_size ** PRAGMA [database.]default_cache_size=N ** |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
6591 6592 6593 6594 6595 6596 6597 | void *pNotifyArg /* Argument to pass to xNotify */ ); /* ** CAPI3REF: String Comparison ** | | | | | > | 6591 6592 6593 6594 6595 6596 6597 6598 6599 6600 6601 6602 6603 6604 6605 6606 6607 6608 6609 6610 | 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_vfstrace.c.
︙ | ︙ | |||
474 475 476 477 478 479 480 | 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; | | > > > > | 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_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->zFNmae, 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/attach.test.
︙ | ︙ | |||
65 66 67 68 69 70 71 72 73 74 75 76 77 78 | } {} do_test attach-1.3.4 { file tail [sqlite3_db_filename db two] } {test2.db} do_test attach-1.3.5 { file tail [sqlite3_db_filename db three] } {} do_test attach-1.4 { execsql { SELECT * FROM t2; } } {1 x 2 y} do_test attach-1.5 { | > | 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | } {} do_test attach-1.3.4 { file tail [sqlite3_db_filename db two] } {test2.db} do_test attach-1.3.5 { file tail [sqlite3_db_filename db three] } {} do_test attach-1.4 { execsql { SELECT * FROM t2; } } {1 x 2 y} do_test attach-1.5 { |
︙ | ︙ | |||
266 267 268 269 270 271 272 273 274 275 276 277 278 279 | } else { do_test attach-1.29 { db_list db } {0 main} } } ;# ifcapable schema_pragmas ifcapable {trigger} { # Only do the following tests if triggers are enabled do_test attach-2.1 { execsql { CREATE TABLE tx(x1,x2,y1,y2); CREATE TRIGGER r1 AFTER UPDATE ON t2 FOR EACH ROW BEGIN INSERT INTO tx(x1,x2,y1,y2) VALUES(OLD.x,NEW.x,OLD.y,NEW.y); END; | > > > > > > > > > > | 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 | } else { do_test attach-1.29 { db_list db } {0 main} } } ;# ifcapable schema_pragmas if {[regexp unix [file_control_vfsname db]]} { do_test attach-1.30.1 { file tail [db eval {PRAGMA main.filename}] } {test.db} do_test attach-1.30.2 { db eval {PRAGMA temp.filename} } {} } ifcapable {trigger} { # Only do the following tests if triggers are enabled do_test attach-2.1 { execsql { CREATE TABLE tx(x1,x2,y1,y2); CREATE TRIGGER r1 AFTER UPDATE ON t2 FOR EACH ROW BEGIN INSERT INTO tx(x1,x2,y1,y2) VALUES(OLD.x,NEW.x,OLD.y,NEW.y); END; |
︙ | ︙ |