Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Half-way through a major refactoring of the memory allocation. I have not even attempted to compile so I am certain there are countless errors. (CVS 4231) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
deb7ecd65f7b83eaf0ba610eeef3b0ed |
User & Date: | drh 2007-08-16 04:30:39.000 |
Context
2007-08-16
| ||
04:39 | Add a test for malloc() failure when compiling a trigger step of the form "INSERT INTO ... SELECT ...". Currently causes a segfault. (CVS 4232) (check-in: 161643a694 user: danielk1977 tags: trunk) | |
04:30 | Half-way through a major refactoring of the memory allocation. I have not even attempted to compile so I am certain there are countless errors. (CVS 4231) (check-in: deb7ecd65f user: drh tags: trunk) | |
2007-08-15
| ||
20:41 | Enhancements and smoke testing of the new memory allocation subsystem. Have not yet cut it over to the core, though. (CVS 4230) (check-in: 1dad2c0a1f user: drh tags: trunk) | |
Changes
Changes to src/alter.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 used to generate VDBE code ** that implements the ALTER TABLE command. ** | | | 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 used to generate VDBE code ** that implements the ALTER TABLE command. ** ** $Id: alter.c,v 1.28 2007/08/16 04:30:39 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** The code in this file only exists if we are not omitting the ** ALTER TABLE logic from the build. |
︙ | ︙ | |||
199 200 201 202 203 204 205 | for( pTrig=pTab->pTrigger; pTrig; pTrig=pTrig->pNext ){ if( pTrig->pSchema==pTempSchema ){ if( !zWhere ){ zWhere = sqlite3MPrintf("name=%Q", pTrig->name); }else{ tmp = zWhere; zWhere = sqlite3MPrintf("%s OR name=%Q", zWhere, pTrig->name); | | | 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 | for( pTrig=pTab->pTrigger; pTrig; pTrig=pTrig->pNext ){ if( pTrig->pSchema==pTempSchema ){ if( !zWhere ){ zWhere = sqlite3MPrintf("name=%Q", pTrig->name); }else{ tmp = zWhere; zWhere = sqlite3MPrintf("%s OR name=%Q", zWhere, pTrig->name); sqlite3_free(tmp); } } } } return zWhere; } |
︙ | ︙ | |||
277 278 279 280 281 282 283 | const char *zTabName; /* Original name of the table */ Vdbe *v; #ifndef SQLITE_OMIT_TRIGGER char *zWhere = 0; /* Where clause to locate temp triggers */ #endif int isVirtualRename = 0; /* True if this is a v-table with an xRename() */ | | | | 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 | const char *zTabName; /* Original name of the table */ Vdbe *v; #ifndef SQLITE_OMIT_TRIGGER char *zWhere = 0; /* Where clause to locate temp triggers */ #endif int isVirtualRename = 0; /* True if this is a v-table with an xRename() */ if( db->mallocFailed ) goto exit_rename_table; assert( pSrc->nSrc==1 ); pTab = sqlite3LocateTable(pParse, pSrc->a[0].zName, pSrc->a[0].zDatabase); if( !pTab ) goto exit_rename_table; iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); zDb = db->aDb[iDb].zName; /* Get a NULL terminated version of the new table name. */ zName = sqlite3NameFromToken(db, pName); if( !zName ) goto exit_rename_table; /* Check that a table or index named 'zName' does not already exist ** in database iDb. If so, this is an error. */ if( sqlite3FindTable(db, zName, zDb) || sqlite3FindIndex(db, zName, zDb) ){ sqlite3ErrorMsg(pParse, |
︙ | ︙ | |||
400 401 402 403 404 405 406 | */ if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){ sqlite3NestedParse(pParse, "UPDATE sqlite_temp_master SET " "sql = sqlite_rename_trigger(sql, %Q), " "tbl_name = %Q " "WHERE %s;", zName, zName, zWhere); | | | > > | | | | 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 | */ if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){ sqlite3NestedParse(pParse, "UPDATE sqlite_temp_master SET " "sql = sqlite_rename_trigger(sql, %Q), " "tbl_name = %Q " "WHERE %s;", zName, zName, zWhere); sqlite3_free(zWhere); } #endif /* Drop and reload the internal table schema. */ reloadTableSchema(pParse, pTab, zName); exit_rename_table: sqlite3SrcListDelete(pSrc); sqlite3_free(zName); } /* ** This function is called after an "ALTER TABLE ... ADD" statement ** has been parsed. Argument pColDef contains the text of the new ** column definition. ** ** The Table structure pParse->pNewTable was extended to include ** the new column during parsing. */ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ Table *pNew; /* Copy of pParse->pNewTable */ Table *pTab; /* Table being altered */ int iDb; /* Database number */ const char *zDb; /* Database name */ const char *zTab; /* Table name */ char *zCol; /* Null-terminated column definition */ Column *pCol; /* The new column */ Expr *pDflt; /* Default value for the new column */ sqlite3 *db; /* The database connection; */ if( pParse->nErr ) return; pNew = pParse->pNewTable; assert( pNew ); db = pParse->db; iDb = sqlite3SchemaToIndex(db, pNew->pSchema); zDb = db->aDb[iDb].zName; zTab = pNew->zName; pCol = &pNew->aCol[pNew->nCol-1]; pDflt = pCol->pDflt; pTab = sqlite3FindTable(db, zTab, zDb); assert( pTab ); #ifndef SQLITE_OMIT_AUTHORIZATION /* Invoke the authorization callback. */ if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){ return; } |
︙ | ︙ | |||
482 483 484 485 486 487 488 | /* Ensure the default expression is something that sqlite3ValueFromExpr() ** can handle (i.e. not CURRENT_TIME etc.) */ if( pDflt ){ sqlite3_value *pVal; if( sqlite3ValueFromExpr(pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal) ){ | | | | | 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 511 512 513 514 515 516 517 518 519 520 521 522 | /* Ensure the default expression is something that sqlite3ValueFromExpr() ** can handle (i.e. not CURRENT_TIME etc.) */ if( pDflt ){ sqlite3_value *pVal; if( sqlite3ValueFromExpr(pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal) ){ db->mallocFailed = 1; return; } if( !pVal ){ sqlite3ErrorMsg(pParse, "Cannot add a column with non-constant default"); return; } sqlite3ValueFree(pVal); } /* Modify the CREATE TABLE statement. */ zCol = sqlite3DbStrNDup(db, (char*)pColDef->z, pColDef->n); if( zCol ){ char *zEnd = &zCol[pColDef->n-1]; while( (zEnd>zCol && *zEnd==';') || isspace(*(unsigned char *)zEnd) ){ *zEnd-- = '\0'; } sqlite3NestedParse(pParse, "UPDATE %Q.%s SET " "sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d,length(sql)) " "WHERE type = 'table' AND name = %Q", zDb, SCHEMA_TABLE(iDb), pNew->addColOffset, zCol, pNew->addColOffset+1, zTab ); sqlite3_free(zCol); } /* If the default value of the new column is NULL, then set the file ** format to 2. If the default value of the new column is not NULL, ** the file format becomes 3. */ sqlite3MinimumFileFormat(pParse, iDb, pDflt ? 3 : 2); |
︙ | ︙ | |||
541 542 543 544 545 546 547 548 549 550 | void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ Table *pNew; Table *pTab; Vdbe *v; int iDb; int i; int nAlloc; /* Look up the table being altered. */ assert( pParse->pNewTable==0 ); | > | | | | | > | | | | 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 | void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ Table *pNew; Table *pTab; Vdbe *v; int iDb; int i; int nAlloc; sqlite3 *db = pParse->db; /* Look up the table being altered. */ assert( pParse->pNewTable==0 ); if( db->mallocFailed ) goto exit_begin_add_column; pTab = sqlite3LocateTable(pParse, pSrc->a[0].zName, pSrc->a[0].zDatabase); if( !pTab ) goto exit_begin_add_column; #ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pTab) ){ sqlite3ErrorMsg(pParse, "virtual tables may not be altered"); goto exit_begin_add_column; } #endif /* Make sure this is not an attempt to ALTER a view. */ if( pTab->pSelect ){ sqlite3ErrorMsg(pParse, "Cannot add a column to a view"); goto exit_begin_add_column; } assert( pTab->addColOffset>0 ); iDb = sqlite3SchemaToIndex(db, pTab->pSchema); /* Put a copy of the Table struct in Parse.pNewTable for the ** sqlite3AddColumn() function and friends to modify. */ pNew = (Table*)sqlite3DbMallocZero(db, sizeof(Table)); if( !pNew ) goto exit_begin_add_column; pParse->pNewTable = pNew; pNew->nRef = 1; pNew->nCol = pTab->nCol; assert( pNew->nCol>0 ); nAlloc = (((pNew->nCol-1)/8)*8)+8; assert( nAlloc>=pNew->nCol && nAlloc%8==0 && nAlloc-pNew->nCol<8 ); pNew->aCol = (Column*)sqlite3_malloc(sizeof(Column)*nAlloc); pNew->zName = sqlite3DbStrDup(db, pTab->zName); if( !pNew->aCol || !pNew->zName ){ db->mallocFailed = 1; goto exit_begin_add_column; } memcpy(pNew->aCol, pTab->aCol, sizeof(Column)*pNew->nCol); for(i=0; i<pNew->nCol; i++){ Column *pCol = &pNew->aCol[i]; pCol->zName = sqlite3DbStrDup(db, pCol->zName); pCol->zColl = 0; pCol->zType = 0; pCol->pDflt = 0; } pNew->pSchema = db->aDb[iDb].pSchema; pNew->addColOffset = pTab->addColOffset; pNew->nRef = 1; /* Begin a transaction and increment the schema cookie. */ sqlite3BeginWriteOperation(pParse, 0, iDb); v = sqlite3GetVdbe(pParse); if( !v ) goto exit_begin_add_column; sqlite3ChangeCookie(db, v, iDb); exit_begin_add_column: sqlite3SrcListDelete(pSrc); return; } #endif /* SQLITE_ALTER_TABLE */ |
Changes to src/analyze.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2005 July 8 ** ** 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 contains code associated with the ANALYZE command. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2005 July 8 ** ** 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 contains code associated with the ANALYZE command. ** ** @(#) $Id: analyze.c,v 1.20 2007/08/16 04:30:39 drh Exp $ */ #ifndef SQLITE_OMIT_ANALYZE #include "sqliteInt.h" /* ** This routine generates code that opens the sqlite_stat1 table on cursor ** iStatCur. |
︙ | ︙ | |||
300 301 302 303 304 305 306 | } }else if( pName2==0 || pName2->n==0 ){ /* Form 2: Analyze the database or table named */ iDb = sqlite3FindDb(db, pName1); if( iDb>=0 ){ analyzeDatabase(pParse, iDb); }else{ | | | | | | 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 | } }else if( pName2==0 || pName2->n==0 ){ /* Form 2: Analyze the database or table named */ iDb = sqlite3FindDb(db, pName1); if( iDb>=0 ){ analyzeDatabase(pParse, iDb); }else{ z = sqlite3NameFromToken(db, pName1); pTab = sqlite3LocateTable(pParse, z, 0); sqlite3_free(z); if( pTab ){ analyzeTable(pParse, pTab); } } }else{ /* Form 3: Analyze the fully qualified table name */ iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pTableName); if( iDb>=0 ){ zDb = db->aDb[iDb].zName; z = sqlite3NameFromToken(db, pTableName); if( z ){ pTab = sqlite3LocateTable(pParse, z, zDb); sqlite3_free(z); if( pTab ){ analyzeTable(pParse, pTab); } } } } } |
︙ | ︙ | |||
398 399 400 401 402 403 404 | /* Load new statistics out of the sqlite_stat1 table */ zSql = sqlite3MPrintf("SELECT idx, stat FROM %Q.sqlite_stat1", sInfo.zDatabase); sqlite3SafetyOff(db); rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0); sqlite3SafetyOn(db); | | | 398 399 400 401 402 403 404 405 406 407 408 409 410 | /* Load new statistics out of the sqlite_stat1 table */ zSql = sqlite3MPrintf("SELECT idx, stat FROM %Q.sqlite_stat1", sInfo.zDatabase); sqlite3SafetyOff(db); rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0); sqlite3SafetyOn(db); sqlite3_free(zSql); return rc; } #endif /* SQLITE_OMIT_ANALYZE */ |
Changes to src/attach.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2003 April 6 ** ** 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 contains code used to implement the ATTACH and DETACH commands. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2003 April 6 ** ** 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 contains code used to implement the ATTACH and DETACH commands. ** ** $Id: attach.c,v 1.61 2007/08/16 04:30:39 drh Exp $ */ #include "sqliteInt.h" #ifndef SQLITE_OMIT_ATTACH /* ** Resolve an expression that was part of an ATTACH or DETACH statement. This ** is slightly different from resolving a normal SQL expression, because simple |
︙ | ︙ | |||
98 99 100 101 102 103 104 | sqlite3_snprintf(sizeof(zErr), zErr, "cannot ATTACH database within transaction"); goto attach_error; } for(i=0; i<db->nDb; i++){ char *z = db->aDb[i].zName; if( z && zName && sqlite3StrICmp(z, zName)==0 ){ | | > | > | > | | | | 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | sqlite3_snprintf(sizeof(zErr), zErr, "cannot ATTACH database within transaction"); goto attach_error; } for(i=0; i<db->nDb; i++){ char *z = db->aDb[i].zName; if( z && zName && sqlite3StrICmp(z, zName)==0 ){ sqlite3_snprintf(sizeof(zErr), zErr, "database %s is already in use", zName); goto attach_error; } } /* Allocate the new entry in the db->aDb[] array and initialise the schema ** hash tables. */ if( db->aDb==db->aDbStatic ){ aNew = sqlite3_malloc( sizeof(db->aDb[0])*3 ); if( aNew==0 ){ db->mallocFailed = 1; return; } memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2); }else{ aNew = sqlite3_realloc(db->aDb, sizeof(db->aDb[0])*(db->nDb+1) ); if( aNew==0 ){ db->mallocFailed = 1; return; } } db->aDb = aNew; aNew = &db->aDb[db->nDb++]; memset(aNew, 0, sizeof(*aNew)); /* Open the database file. If the btree is successfully opened, use ** it to obtain the database schema. At this point the schema may ** or may not be initialised. */ rc = sqlite3BtreeFactory(db, zFile, 0, SQLITE_DEFAULT_CACHE_SIZE, &aNew->pBt); if( rc==SQLITE_OK ){ aNew->pSchema = sqlite3SchemaGet(db, aNew->pBt); if( !aNew->pSchema ){ rc = SQLITE_NOMEM; }else if( aNew->pSchema->file_format && aNew->pSchema->enc!=ENC(db) ){ sqlite3_snprintf(sizeof(zErr), zErr, "attached databases must use the same text encoding as main database"); goto attach_error; } sqlite3PagerLockingMode(sqlite3BtreePager(aNew->pBt), db->dfltLockMode); } aNew->zName = sqlite3DbStrDup(db, zName); aNew->safety_level = 3; #if SQLITE_HAS_CODEC { extern int sqlite3CodecAttach(sqlite3*, int, const void*, int); extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*); int nKey; char *zKey; int t = sqlite3_value_type(argv[2]); switch( t ){ case SQLITE_INTEGER: case SQLITE_FLOAT: zErrDyn = sqlite3DbStrDup(db, "Invalid key value"); rc = SQLITE_ERROR; break; case SQLITE_TEXT: case SQLITE_BLOB: nKey = sqlite3_value_bytes(argv[2]); zKey = (char *)sqlite3_value_blob(argv[2]); |
︙ | ︙ | |||
192 193 194 195 196 197 198 | sqlite3BtreeClose(db->aDb[iDb].pBt); db->aDb[iDb].pBt = 0; db->aDb[iDb].pSchema = 0; } sqlite3ResetInternalSchema(db, 0); db->nDb = iDb; if( rc==SQLITE_NOMEM ){ | | | | 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 | sqlite3BtreeClose(db->aDb[iDb].pBt); db->aDb[iDb].pBt = 0; db->aDb[iDb].pSchema = 0; } sqlite3ResetInternalSchema(db, 0); db->nDb = iDb; if( rc==SQLITE_NOMEM ){ db->mallocFailed = 1; sqlite3_snprintf(sizeof(zErr),zErr, "out of memory"); }else{ sqlite3_snprintf(sizeof(zErr),zErr, "unable to open database: %s", zFile); } goto attach_error; } return; attach_error: /* Return an error if we get here */ if( zErrDyn ){ sqlite3_result_error(context, zErrDyn, -1); sqlite3_free(zErrDyn); }else{ zErr[sizeof(zErr)-1] = 0; sqlite3_result_error(context, zErr, -1); } } /* |
︙ | ︙ | |||
288 289 290 291 292 293 294 | int rc; NameContext sName; Vdbe *v; FuncDef *pFunc; sqlite3* db = pParse->db; #ifndef SQLITE_OMIT_AUTHORIZATION | | | | | 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 | int rc; NameContext sName; Vdbe *v; FuncDef *pFunc; sqlite3* db = pParse->db; #ifndef SQLITE_OMIT_AUTHORIZATION assert( db->mallocFailed || pAuthArg ); if( pAuthArg ){ char *zAuthArg = sqlite3NameFromToken(db, &pAuthArg->span); if( !zAuthArg ){ goto attach_end; } rc = sqlite3AuthCheck(pParse, type, zAuthArg, 0, 0); sqlite3_free(zAuthArg); if(rc!=SQLITE_OK ){ goto attach_end; } } #endif /* SQLITE_OMIT_AUTHORIZATION */ memset(&sName, 0, sizeof(NameContext)); |
︙ | ︙ | |||
319 320 321 322 323 324 325 | } v = sqlite3GetVdbe(pParse); sqlite3ExprCode(pParse, pFilename); sqlite3ExprCode(pParse, pDbname); sqlite3ExprCode(pParse, pKey); | | | 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 | } v = sqlite3GetVdbe(pParse); sqlite3ExprCode(pParse, pFilename); sqlite3ExprCode(pParse, pDbname); sqlite3ExprCode(pParse, pKey); assert( v || db->mallocFailed ); if( v ){ sqlite3VdbeAddOp(v, OP_Function, 0, nFunc); pFunc = sqlite3FindFunction(db, zFunc, strlen(zFunc), nFunc, SQLITE_UTF8,0); sqlite3VdbeChangeP3(v, -1, (char *)pFunc, P3_FUNCDEF); /* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this ** statement only). For DETACH, set it to false (expire all existing |
︙ | ︙ | |||
420 421 422 423 424 425 426 | const char *zDb; struct SrcList_item *pItem; if( pList==0 ) return 0; zDb = pFix->zDb; for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){ if( pItem->zDatabase==0 ){ | | | 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 | const char *zDb; struct SrcList_item *pItem; if( pList==0 ) return 0; zDb = pFix->zDb; for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){ if( pItem->zDatabase==0 ){ pItem->zDatabase = sqlite3DbStrDup(pFix->pParse->db, zDb); }else if( sqlite3StrICmp(pItem->zDatabase,zDb)!=0 ){ sqlite3ErrorMsg(pFix->pParse, "%s %T cannot reference objects in database %s", pFix->zType, pFix->pName, pItem->zDatabase); return 1; } #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) |
︙ | ︙ |
Changes to src/btree.c.
1 2 3 4 5 6 7 8 9 10 11 | /* ** 2004 April 6 ** ** 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. ** ************************************************************************* | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /* ** 2004 April 6 ** ** 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. ** ************************************************************************* ** $Id: btree.c,v 1.397 2007/08/16 04:30:39 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** See the header comment on "btreeInt.h" for additional information. ** Including a description of file format and an overview of operation. */ #include "btreeInt.h" |
︙ | ︙ | |||
139 140 141 142 143 144 145 | } } /* If the above search did not find a BtLock struct associating Btree p ** with table iTable, allocate one and link it into the list. */ if( !pLock ){ | | | 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | } } /* If the above search did not find a BtLock struct associating Btree p ** with table iTable, allocate one and link it into the list. */ if( !pLock ){ pLock = (BtLock *)sqlite3MallocZero(sizeof(BtLock)); if( !pLock ){ return SQLITE_NOMEM; } pLock->iTable = iTable; pLock->pBtree = p; pLock->pNext = pBt->pLock; pBt->pLock = pLock; |
︙ | ︙ | |||
178 179 180 181 182 183 184 | */ assert( sqlite3ThreadDataReadOnly()->useSharedData || 0==*ppIter ); while( *ppIter ){ BtLock *pLock = *ppIter; if( pLock->pBtree==p ){ *ppIter = pLock->pNext; | | | | 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 | */ assert( sqlite3ThreadDataReadOnly()->useSharedData || 0==*ppIter ); while( *ppIter ){ BtLock *pLock = *ppIter; if( pLock->pBtree==p ){ *ppIter = pLock->pNext; sqlite3_free(pLock); }else{ ppIter = &pLock->pNext; } } } #endif /* SQLITE_OMIT_SHARED_CACHE */ static void releasePage(MemPage *pPage); /* Forward reference */ #ifndef SQLITE_OMIT_INCRBLOB /* ** Invalidate the overflow page-list cache for cursor pCur, if any. */ static void invalidateOverflowCache(BtCursor *pCur){ sqlite3_free(pCur->aOverflow); pCur->aOverflow = 0; } /* ** Invalidate the overflow page-list cache for all cursors opened ** on the shared btree structure pBt. */ |
︙ | ︙ | |||
231 232 233 234 235 236 237 | /* If this is an intKey table, then the above call to BtreeKeySize() ** stores the integer key in pCur->nKey. In this case this value is ** all that is required. Otherwise, if pCur is not open on an intKey ** table, then malloc space for and store the pCur->nKey bytes of key ** data. */ if( rc==SQLITE_OK && 0==pCur->pPage->intKey){ | | | | 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 | /* If this is an intKey table, then the above call to BtreeKeySize() ** stores the integer key in pCur->nKey. In this case this value is ** all that is required. Otherwise, if pCur is not open on an intKey ** table, then malloc space for and store the pCur->nKey bytes of key ** data. */ if( rc==SQLITE_OK && 0==pCur->pPage->intKey){ void *pKey = sqlite3_malloc(pCur->nKey); if( pKey ){ rc = sqlite3BtreeKey(pCur, 0, pCur->nKey, pKey); if( rc==SQLITE_OK ){ pCur->pKey = pKey; }else{ sqlite3_free(pKey); } }else{ rc = SQLITE_NOMEM; } } assert( !pCur->pPage->intKey || !pCur->pKey ); |
︙ | ︙ | |||
278 279 280 281 282 283 284 | return SQLITE_OK; } /* ** Clear the current cursor position. */ static void clearCursorPosition(BtCursor *pCur){ | | | 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 | return SQLITE_OK; } /* ** Clear the current cursor position. */ static void clearCursorPosition(BtCursor *pCur){ sqlite3_free(pCur->pKey); pCur->pKey = 0; pCur->eState = CURSOR_INVALID; } /* ** Restore the cursor to the position it was in (or as close to as possible) ** when saveCursorPosition() was called. Note that this call deletes the |
︙ | ︙ | |||
305 306 307 308 309 310 311 | if( pCur->isIncrblobHandle ){ return SQLITE_ABORT; } #endif pCur->eState = CURSOR_INVALID; rc = sqlite3BtreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &pCur->skip); if( rc==SQLITE_OK ){ | | | 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 | if( pCur->isIncrblobHandle ){ return SQLITE_ABORT; } #endif pCur->eState = CURSOR_INVALID; rc = sqlite3BtreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &pCur->skip); if( rc==SQLITE_OK ){ sqlite3_free(pCur->pKey); pCur->pKey = 0; assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_INVALID ); } return rc; } #define restoreOrClearCursorPosition(p) \ |
︙ | ︙ | |||
604 605 606 607 608 609 610 | unsigned char *data; /* The page data */ unsigned char *temp; /* Temp area for cell content */ assert( sqlite3PagerIswriteable(pPage->pDbPage) ); assert( pPage->pBt!=0 ); assert( pPage->pBt->usableSize <= SQLITE_MAX_PAGE_SIZE ); assert( pPage->nOverflow==0 ); | | | 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 | unsigned char *data; /* The page data */ unsigned char *temp; /* Temp area for cell content */ assert( sqlite3PagerIswriteable(pPage->pDbPage) ); assert( pPage->pBt!=0 ); assert( pPage->pBt->usableSize <= SQLITE_MAX_PAGE_SIZE ); assert( pPage->nOverflow==0 ); temp = sqlite3_malloc( pPage->pBt->pageSize ); if( temp==0 ) return SQLITE_NOMEM; data = pPage->aData; hdr = pPage->hdrOffset; cellOffset = pPage->cellOffset; nCell = pPage->nCell; assert( nCell==get2byte(&data[hdr+3]) ); usableSize = pPage->pBt->usableSize; |
︙ | ︙ | |||
632 633 634 635 636 637 638 | assert( brk>=cellOffset+2*nCell ); put2byte(&data[hdr+5], brk); data[hdr+1] = 0; data[hdr+2] = 0; data[hdr+7] = 0; addr = cellOffset+2*nCell; memset(&data[addr], 0, brk-addr); | | | 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 | assert( brk>=cellOffset+2*nCell ); put2byte(&data[hdr+5], brk); data[hdr+1] = 0; data[hdr+2] = 0; data[hdr+7] = 0; addr = cellOffset+2*nCell; memset(&data[addr], 0, brk-addr); sqlite3_free(temp); return SQLITE_OK; } /* ** Allocate nByte bytes of space on a page. ** ** Return the index into pPage->aData[] of the first byte of |
︙ | ︙ | |||
1048 1049 1050 1051 1052 1053 1054 | #ifdef SQLITE_OMIT_MEMORYDB const int isMemdb = 0; #else const int isMemdb = zFilename && !strcmp(zFilename, ":memory:"); #endif #endif | | | | | | | 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 | #ifdef SQLITE_OMIT_MEMORYDB const int isMemdb = 0; #else const int isMemdb = zFilename && !strcmp(zFilename, ":memory:"); #endif #endif p = sqlite3MallocZero(sizeof(Btree)); if( !p ){ return SQLITE_NOMEM; } p->inTrans = TRANS_NONE; p->pSqlite = pSqlite; /* Try to find an existing Btree structure opened on zFilename. */ #if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO) pTsdro = sqlite3ThreadDataReadOnly(); if( pTsdro->useSharedData && zFilename && !isMemdb ){ char *zFullPathname = sqlite3OsFullPathname(zFilename); if( !zFullPathname ){ sqlite3_free(p); return SQLITE_NOMEM; } for(pBt=pTsdro->pBtree; pBt; pBt=pBt->pNext){ assert( pBt->nRef>0 ); if( 0==strcmp(zFullPathname, sqlite3PagerFilename(pBt->pPager)) ){ p->pBt = pBt; *ppBtree = p; pBt->nRef++; sqlite3_free(zFullPathname); return SQLITE_OK; } } sqlite3_free(zFullPathname); } #endif /* ** The following asserts make sure that structures used by the btree are ** the right size. This is to guard against size changes that result ** when compiling on a different architecture. */ assert( sizeof(i64)==8 || sizeof(i64)==4 ); assert( sizeof(u64)==8 || sizeof(u64)==4 ); assert( sizeof(u32)==4 ); assert( sizeof(u16)==2 ); assert( sizeof(Pgno)==4 ); pBt = sqlite3MallocZero( sizeof(*pBt) ); if( pBt==0 ){ rc = SQLITE_NOMEM; goto btree_open_out; } rc = sqlite3PagerOpen(&pBt->pPager, zFilename, EXTRA_SIZE, flags); if( rc==SQLITE_OK ){ rc = sqlite3PagerReadFileheader(pBt->pPager,sizeof(zDbHeader),zDbHeader); |
︙ | ︙ | |||
1162 1163 1164 1165 1166 1167 1168 | *ppBtree = p; btree_open_out: if( rc!=SQLITE_OK ){ if( pBt && pBt->pPager ){ sqlite3PagerClose(pBt->pPager); } | | | | 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 | *ppBtree = p; btree_open_out: if( rc!=SQLITE_OK ){ if( pBt && pBt->pPager ){ sqlite3PagerClose(pBt->pPager); } sqlite3_free(pBt); sqlite3_free(p); *ppBtree = 0; } return rc; } /* ** Close an open database and invalidate all cursors. |
︙ | ︙ | |||
1195 1196 1197 1198 1199 1200 1201 | } /* Rollback any active transaction and free the handle structure. ** The call to sqlite3BtreeRollback() drops any table-locks held by ** this handle. */ sqlite3BtreeRollback(p); | | | 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 | } /* Rollback any active transaction and free the handle structure. ** The call to sqlite3BtreeRollback() drops any table-locks held by ** this handle. */ sqlite3BtreeRollback(p); sqlite3_free(p); #ifndef SQLITE_OMIT_SHARED_CACHE /* If there are still other outstanding references to the shared-btree ** structure, return now. The remainder of this procedure cleans ** up the shared-btree. */ assert( pBt->nRef>0 ); |
︙ | ︙ | |||
1232 1233 1234 1235 1236 1237 1238 | /* Close the pager and free the shared-btree structure */ assert( !pBt->pCursor ); sqlite3PagerClose(pBt->pPager); if( pBt->xFreeSchema && pBt->pSchema ){ pBt->xFreeSchema(pBt->pSchema); } | | | | 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 | /* Close the pager and free the shared-btree structure */ assert( !pBt->pCursor ); sqlite3PagerClose(pBt->pPager); if( pBt->xFreeSchema && pBt->pSchema ){ pBt->xFreeSchema(pBt->pSchema); } sqlite3_free(pBt->pSchema); sqlite3_free(pBt); return SQLITE_OK; } /* ** Change the busy handler callback function. */ int sqlite3BtreeSetBusyHandler(Btree *p, BusyHandler *pHandler){ |
︙ | ︙ | |||
2377 2378 2379 2380 2381 2382 2383 | if( rc!=SQLITE_OK ){ return rc; } if( pBt->readOnly && wrFlag ){ return SQLITE_READONLY; } } | | | 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 | if( rc!=SQLITE_OK ){ return rc; } if( pBt->readOnly && wrFlag ){ return SQLITE_READONLY; } } pCur = sqlite3MallocZero( sizeof(*pCur) ); if( pCur==0 ){ rc = SQLITE_NOMEM; goto create_cursor_exception; } pCur->pgnoRoot = (Pgno)iTable; if( iTable==1 && sqlite3PagerPagecount(pBt->pPager)==0 ){ rc = SQLITE_EMPTY; |
︙ | ︙ | |||
2412 2413 2414 2415 2416 2417 2418 | pCur->eState = CURSOR_INVALID; *ppCur = pCur; return SQLITE_OK; create_cursor_exception: if( pCur ){ releasePage(pCur->pPage); | | | 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 | pCur->eState = CURSOR_INVALID; *ppCur = pCur; return SQLITE_OK; create_cursor_exception: if( pCur ){ releasePage(pCur->pPage); sqlite3_free(pCur); } unlockBtreeIfUnused(pBt); return rc; } /* ** Close a cursor. The read lock on the database file is released |
︙ | ︙ | |||
2436 2437 2438 2439 2440 2441 2442 | } if( pCur->pNext ){ pCur->pNext->pPrev = pCur->pPrev; } releasePage(pCur->pPage); unlockBtreeIfUnused(pBt); invalidateOverflowCache(pCur); | | | 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 | } if( pCur->pNext ){ pCur->pNext->pPrev = pCur->pPrev; } releasePage(pCur->pPage); unlockBtreeIfUnused(pBt); invalidateOverflowCache(pCur); sqlite3_free(pCur); return SQLITE_OK; } /* ** Make a temporary cursor by filling in the fields of pTempCur. ** The temporary cursor is not on the cursor list for the Btree. */ |
︙ | ︙ | |||
2759 2760 2761 2762 2763 2764 2765 | ** one entry for each overflow page in the overflow chain. The ** page number of the first overflow page is stored in aOverflow[0], ** etc. A value of 0 in the aOverflow[] array means "not yet known" ** (the cache is lazily populated). */ if( pCur->isIncrblobHandle && !pCur->aOverflow ){ int nOvfl = (pCur->info.nPayload-pCur->info.nLocal+ovflSize-1)/ovflSize; | | | 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 | ** one entry for each overflow page in the overflow chain. The ** page number of the first overflow page is stored in aOverflow[0], ** etc. A value of 0 in the aOverflow[] array means "not yet known" ** (the cache is lazily populated). */ if( pCur->isIncrblobHandle && !pCur->aOverflow ){ int nOvfl = (pCur->info.nPayload-pCur->info.nLocal+ovflSize-1)/ovflSize; pCur->aOverflow = (Pgno *)sqlite3MallocZero(sizeof(Pgno)*nOvfl); if( nOvfl && !pCur->aOverflow ){ rc = SQLITE_NOMEM; } } /* If the overflow page-list cache has been allocated and the ** entry for the first required overflow page is valid, skip |
︙ | ︙ | |||
3234 3235 3236 3237 3238 3239 3240 | }else{ int available; pCellKey = (void *)fetchPayload(pCur, &available, 0); nCellKey = pCur->info.nKey; if( available>=nCellKey ){ c = pCur->xCompare(pCur->pArg, nCellKey, pCellKey, nKey, pKey); }else{ | | | | 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 | }else{ int available; pCellKey = (void *)fetchPayload(pCur, &available, 0); nCellKey = pCur->info.nKey; if( available>=nCellKey ){ c = pCur->xCompare(pCur->pArg, nCellKey, pCellKey, nKey, pKey); }else{ pCellKey = sqlite3_malloc( nCellKey ); if( pCellKey==0 ) return SQLITE_NOMEM; rc = sqlite3BtreeKey(pCur, 0, nCellKey, (void *)pCellKey); c = pCur->xCompare(pCur->pArg, nCellKey, pCellKey, nKey, pKey); sqlite3_free(pCellKey); if( rc ) return rc; } } if( c==0 ){ if( pPage->leafData && !pPage->leaf ){ lwr = pCur->idx; upr = lwr - 1; |
︙ | ︙ | |||
4448 4449 4450 4451 4452 4453 4454 | /* Make nMaxCells a multiple of 2 in order to preserve 8-byte ** alignment */ nMaxCells = (nMaxCells + 1)&~1; /* ** Allocate space for memory structures */ | | | 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 | /* Make nMaxCells a multiple of 2 in order to preserve 8-byte ** alignment */ nMaxCells = (nMaxCells + 1)&~1; /* ** Allocate space for memory structures */ apCell = sqlite3_malloc( nMaxCells*sizeof(u8*) /* apCell */ + nMaxCells*sizeof(int) /* szCell */ + ROUND8(sizeof(MemPage))*NB /* aCopy */ + pBt->pageSize*(5+NB) /* aSpace */ + (ISAUTOVACUUM ? nMaxCells : 0) /* aFrom */ ); if( apCell==0 ){ |
︙ | ︙ | |||
4859 4860 4861 4862 4863 4864 4865 | assert( pParent->isInit ); rc = balance(pParent, 0); /* ** Cleanup before returning. */ balance_cleanup: | | | 4859 4860 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 | assert( pParent->isInit ); rc = balance(pParent, 0); /* ** Cleanup before returning. */ balance_cleanup: sqlite3_free(apCell); for(i=0; i<nOld; i++){ releasePage(apOld[i]); } for(i=0; i<nNew; i++){ releasePage(apNew[i]); } releasePage(pParent); |
︙ | ︙ | |||
4890 4891 4892 4893 4894 4895 4896 | u8 **apCell; /* All cells from pages being balanced */ int *szCell; /* Local size of all cells */ assert( pPage->pParent==0 ); assert( pPage->nCell==0 ); pBt = pPage->pBt; mxCellPerPage = MX_CELL(pBt); | | | 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 | u8 **apCell; /* All cells from pages being balanced */ int *szCell; /* Local size of all cells */ assert( pPage->pParent==0 ); assert( pPage->nCell==0 ); pBt = pPage->pBt; mxCellPerPage = MX_CELL(pBt); apCell = sqlite3_malloc( mxCellPerPage*(sizeof(u8*)+sizeof(int)) ); if( apCell==0 ) return SQLITE_NOMEM; szCell = (int*)&apCell[mxCellPerPage]; if( pPage->leaf ){ /* The table is completely empty */ TRACE(("BALANCE: empty table %d\n", pPage->pgno)); }else{ /* The root page is empty but has one child. Transfer the |
︙ | ︙ | |||
4964 4965 4966 4967 4968 4969 4970 | } } } #endif releasePage(pChild); } end_shallow_balance: | | | 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 | } } } #endif releasePage(pChild); } end_shallow_balance: sqlite3_free(apCell); return rc; } /* ** The root page is overfull ** |
︙ | ︙ | |||
5147 5148 5149 5150 5151 5152 5153 | assert( pPage->leaf || !pPage->leafData ); TRACE(("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n", pCur->pgnoRoot, nKey, nData, pPage->pgno, loc==0 ? "overwrite" : "new entry")); assert( pPage->isInit ); rc = sqlite3PagerWrite(pPage->pDbPage); if( rc ) return rc; | | | 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 | assert( pPage->leaf || !pPage->leafData ); TRACE(("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n", pCur->pgnoRoot, nKey, nData, pPage->pgno, loc==0 ? "overwrite" : "new entry")); assert( pPage->isInit ); rc = sqlite3PagerWrite(pPage->pDbPage); if( rc ) return rc; newCell = sqlite3_malloc( MX_CELL_SIZE(pBt) ); if( newCell==0 ) return SQLITE_NOMEM; rc = fillInCell(pPage, newCell, pKey, nKey, pData, nData, nZero, &szNew); if( rc ) goto end_insert; assert( szNew==cellSizePtr(pPage, newCell) ); assert( szNew<=MX_CELL_SIZE(pBt) ); if( loc==0 && CURSOR_VALID==pCur->eState ){ int szOld; |
︙ | ︙ | |||
5180 5181 5182 5183 5184 5185 5186 | rc = balance(pPage, 1); /* sqlite3BtreePageDump(pCur->pBt, pCur->pgnoRoot, 1); */ /* fflush(stdout); */ if( rc==SQLITE_OK ){ moveToRoot(pCur); } end_insert: | | | 5180 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 5191 5192 5193 5194 | rc = balance(pPage, 1); /* sqlite3BtreePageDump(pCur->pBt, pCur->pgnoRoot, 1); */ /* fflush(stdout); */ if( rc==SQLITE_OK ){ moveToRoot(pCur); } end_insert: sqlite3_free(newCell); return rc; } /* ** Delete the entry that the cursor is pointing to. The cursor ** is left pointing at a random location. */ |
︙ | ︙ | |||
5263 5264 5265 5266 5267 5268 5269 | if( rc==SQLITE_OK ){ TRACE(("DELETE: table=%d delete internal from %d replace from leaf %d\n", pCur->pgnoRoot, pPage->pgno, leafCur.pPage->pgno)); dropCell(pPage, pCur->idx, cellSizePtr(pPage, pCell)); pNext = findCell(leafCur.pPage, leafCur.idx); szNext = cellSizePtr(leafCur.pPage, pNext); assert( MX_CELL_SIZE(pBt)>=szNext+4 ); | | | | 5263 5264 5265 5266 5267 5268 5269 5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 5293 | if( rc==SQLITE_OK ){ TRACE(("DELETE: table=%d delete internal from %d replace from leaf %d\n", pCur->pgnoRoot, pPage->pgno, leafCur.pPage->pgno)); dropCell(pPage, pCur->idx, cellSizePtr(pPage, pCell)); pNext = findCell(leafCur.pPage, leafCur.idx); szNext = cellSizePtr(leafCur.pPage, pNext); assert( MX_CELL_SIZE(pBt)>=szNext+4 ); tempCell = sqlite3_malloc( MX_CELL_SIZE(pBt) ); if( tempCell==0 ){ rc = SQLITE_NOMEM; } } if( rc==SQLITE_OK ){ rc = insertCell(pPage, pCur->idx, pNext-4, szNext+4, tempCell, 0); } if( rc==SQLITE_OK ){ put4byte(findOverflowCell(pPage, pCur->idx), pgnoChild); rc = balance(pPage, 0); } if( rc==SQLITE_OK ){ dropCell(leafCur.pPage, leafCur.idx, szNext); rc = balance(leafCur.pPage, 0); } sqlite3_free(tempCell); sqlite3BtreeReleaseTempCursor(&leafCur); }else{ TRACE(("DELETE: table=%d delete from leaf %d\n", pCur->pgnoRoot, pPage->pgno)); dropCell(pPage, pCur->idx, cellSizePtr(pPage, pCell)); rc = balance(pPage, 0); } |
︙ | ︙ | |||
5744 5745 5746 5747 5748 5749 5750 | zMsg2 = sqlite3VMPrintf(zFormat, ap); va_end(ap); if( zMsg1==0 ) zMsg1 = ""; if( pCheck->zErrMsg ){ char *zOld = pCheck->zErrMsg; pCheck->zErrMsg = 0; sqlite3SetString(&pCheck->zErrMsg, zOld, "\n", zMsg1, zMsg2, (char*)0); | | | | 5744 5745 5746 5747 5748 5749 5750 5751 5752 5753 5754 5755 5756 5757 5758 5759 5760 5761 5762 | zMsg2 = sqlite3VMPrintf(zFormat, ap); va_end(ap); if( zMsg1==0 ) zMsg1 = ""; if( pCheck->zErrMsg ){ char *zOld = pCheck->zErrMsg; pCheck->zErrMsg = 0; sqlite3SetString(&pCheck->zErrMsg, zOld, "\n", zMsg1, zMsg2, (char*)0); sqlite3_free(zOld); }else{ sqlite3SetString(&pCheck->zErrMsg, zMsg1, zMsg2, (char*)0); } sqlite3_free(zMsg2); } #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ #ifndef SQLITE_OMIT_INTEGRITY_CHECK /* ** Add 1 to the reference count for page iPage. If this is the second ** reference to the page, add an error message to pCheck->zErrMsg. |
︙ | ︙ | |||
5991 5992 5993 5994 5995 5996 5997 | checkTreePage(pCheck, pgno, pPage, zContext); } /* Check for complete coverage of the page */ data = pPage->aData; hdr = pPage->hdrOffset; | | | 5991 5992 5993 5994 5995 5996 5997 5998 5999 6000 6001 6002 6003 6004 6005 | checkTreePage(pCheck, pgno, pPage, zContext); } /* Check for complete coverage of the page */ data = pPage->aData; hdr = pPage->hdrOffset; hit = sqlite3MallocZero( usableSize ); if( hit ){ memset(hit, 1, get2byte(&data[hdr+5])); nCell = get2byte(&data[hdr+3]); cellStart = hdr + 12 - 4*pPage->leaf; for(i=0; i<nCell; i++){ int pc = get2byte(&data[cellStart+i*2]); int size = cellSizePtr(pPage, &data[pc]); |
︙ | ︙ | |||
6034 6035 6036 6037 6038 6039 6040 | } if( cnt!=data[hdr+7] ){ checkAppendMsg(pCheck, 0, "Fragmented space is %d byte reported as %d on page %d", cnt, data[hdr+7], iPage); } } | | | 6034 6035 6036 6037 6038 6039 6040 6041 6042 6043 6044 6045 6046 6047 6048 | } if( cnt!=data[hdr+7] ){ checkAppendMsg(pCheck, 0, "Fragmented space is %d byte reported as %d on page %d", cnt, data[hdr+7], iPage); } } sqlite3_free(hit); releasePage(pPage); return depth+1; } #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ #ifndef SQLITE_OMIT_INTEGRITY_CHECK |
︙ | ︙ | |||
6066 6067 6068 6069 6070 6071 6072 | int i; int nRef; IntegrityCk sCheck; BtShared *pBt = p->pBt; nRef = sqlite3PagerRefcount(pBt->pPager); if( lockBtreeWithRetry(p)!=SQLITE_OK ){ | | | | 6066 6067 6068 6069 6070 6071 6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 6090 6091 6092 6093 6094 6095 6096 6097 | int i; int nRef; IntegrityCk sCheck; BtShared *pBt = p->pBt; nRef = sqlite3PagerRefcount(pBt->pPager); if( lockBtreeWithRetry(p)!=SQLITE_OK ){ return sqlite3StrDup("Unable to acquire a read lock on the database"); } sCheck.pBt = pBt; sCheck.pPager = pBt->pPager; sCheck.nPage = sqlite3PagerPagecount(sCheck.pPager); sCheck.mxErr = mxErr; sCheck.nErr = 0; *pnErr = 0; #ifndef SQLITE_OMIT_AUTOVACUUM if( pBt->nTrunc!=0 ){ sCheck.nPage = pBt->nTrunc; } #endif if( sCheck.nPage==0 ){ unlockBtreeIfUnused(pBt); return 0; } sCheck.anRef = sqlite3_malloc( (sCheck.nPage+1)*sizeof(sCheck.anRef[0]) ); if( !sCheck.anRef ){ unlockBtreeIfUnused(pBt); *pnErr = 1; return sqlite3MPrintf("Unable to malloc %d bytes", (sCheck.nPage+1)*sizeof(sCheck.anRef[0])); } for(i=0; i<=sCheck.nPage; i++){ sCheck.anRef[i] = 0; } |
︙ | ︙ | |||
6148 6149 6150 6151 6152 6153 6154 | "Outstanding page count goes from %d to %d during this analysis", nRef, sqlite3PagerRefcount(pBt->pPager) ); } /* Clean up and report errors. */ | | | 6148 6149 6150 6151 6152 6153 6154 6155 6156 6157 6158 6159 6160 6161 6162 | "Outstanding page count goes from %d to %d during this analysis", nRef, sqlite3PagerRefcount(pBt->pPager) ); } /* Clean up and report errors. */ sqlite3_free(sCheck.anRef); *pnErr = sCheck.nErr; return sCheck.zErrMsg; } #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ /* ** Return the full pathname of the underlying database file. |
︙ | ︙ | |||
6276 6277 6278 6279 6280 6281 6282 | ** The first time this is called on a shared-btree, nBytes bytes of memory ** are allocated, zeroed, and returned to the caller. For each subsequent ** call the nBytes parameter is ignored and a pointer to the same blob ** of memory returned. ** ** Just before the shared-btree is closed, the function passed as the ** xFree argument when the memory allocation was made is invoked on the | | | | 6276 6277 6278 6279 6280 6281 6282 6283 6284 6285 6286 6287 6288 6289 6290 6291 6292 6293 6294 6295 6296 | ** The first time this is called on a shared-btree, nBytes bytes of memory ** are allocated, zeroed, and returned to the caller. For each subsequent ** call the nBytes parameter is ignored and a pointer to the same blob ** of memory returned. ** ** Just before the shared-btree is closed, the function passed as the ** xFree argument when the memory allocation was made is invoked on the ** blob of allocated memory. This function should not call sqlite3_free() ** on the memory, the btree layer does that. */ void *sqlite3BtreeSchema(Btree *p, int nBytes, void(*xFree)(void *)){ BtShared *pBt = p->pBt; if( !pBt->pSchema ){ pBt->pSchema = sqlite3MallocZero(nBytes); pBt->xFreeSchema = xFree; } return pBt->pSchema; } /* ** Return true if another user of the same shared btree as the argument |
︙ | ︙ |
Changes to src/build.c.
︙ | ︙ | |||
18 19 20 21 22 23 24 | ** CREATE INDEX ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | ** CREATE INDEX ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** ** $Id: build.c,v 1.434 2007/08/16 04:30:39 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** This routine is called when a new SQL statement is beginning to ** be parsed. Initialize the pParse structure as needed. |
︙ | ︙ | |||
78 79 80 81 82 83 84 | if( p->iDb==iDb && p->iTab==iTab ){ p->isWriteLock = (p->isWriteLock || isWriteLock); return; } } nBytes = sizeof(TableLock) * (pParse->nTableLock+1); | | > | 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | if( p->iDb==iDb && p->iTab==iTab ){ p->isWriteLock = (p->isWriteLock || isWriteLock); return; } } nBytes = sizeof(TableLock) * (pParse->nTableLock+1); pParse->aTableLock = sqlite3DbReallocOrFree(pParse->db, pParse->aTableLock, nBytes); if( pParse->aTableLock ){ p = &pParse->aTableLock[pParse->nTableLock++]; p->iDb = iDb; p->iTab = iTab; p->isWriteLock = isWriteLock; p->zName = zName; } |
︙ | ︙ | |||
128 129 130 131 132 133 134 | ** Note that if an error occurred, it might be the case that ** no VDBE code was generated. */ void sqlite3FinishCoding(Parse *pParse){ sqlite3 *db; Vdbe *v; | > | < | 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | ** Note that if an error occurred, it might be the case that ** no VDBE code was generated. */ void sqlite3FinishCoding(Parse *pParse){ sqlite3 *db; Vdbe *v; db = pParse->db; if( db->mallocFailed ) return; if( pParse->nested ) return; if( !pParse->pVdbe ){ if( pParse->rc==SQLITE_OK && pParse->nErr ){ pParse->rc = SQLITE_ERROR; return; } } /* Begin by generating some termination code at the end of the ** vdbe program */ v = sqlite3GetVdbe(pParse); if( v ){ sqlite3VdbeAddOp(v, OP_Halt, 0, 0); /* The cookie mask contains one bit for each database file open. ** (Bit 0 is for main, bit 1 is for temp, and so forth.) Bits are ** set for each database that is used. Generate code to start a |
︙ | ︙ | |||
189 190 191 192 193 194 195 | sqlite3VdbeOp3(v, OP_Noop, 0, 0, pParse->zSql, pParse->zTail-pParse->zSql); #endif /* SQLITE_OMIT_TRACE */ } /* Get the VDBE program ready for execution */ | | | 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 | sqlite3VdbeOp3(v, OP_Noop, 0, 0, pParse->zSql, pParse->zTail-pParse->zSql); #endif /* SQLITE_OMIT_TRACE */ } /* Get the VDBE program ready for execution */ if( v && pParse->nErr==0 && !db->mallocFailed ){ #ifdef SQLITE_DEBUG FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0; sqlite3VdbeTrace(v, trace); #endif sqlite3VdbeMakeReady(v, pParse->nVar, pParse->nMem+3, pParse->nTab+3, pParse->explain); pParse->rc = SQLITE_DONE; |
︙ | ︙ | |||
233 234 235 236 237 238 239 240 241 242 243 244 245 | if( pParse->nErr ) return; assert( pParse->nested<10 ); /* Nesting should only be of limited depth */ va_start(ap, zFormat); zSql = sqlite3VMPrintf(zFormat, ap); va_end(ap); if( zSql==0 ){ return; /* A malloc must have failed */ } pParse->nested++; memcpy(saveBuf, &pParse->nVar, SAVE_SZ); memset(&pParse->nVar, 0, SAVE_SZ); sqlite3RunParser(pParse, zSql, 0); | > | | 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 | if( pParse->nErr ) return; assert( pParse->nested<10 ); /* Nesting should only be of limited depth */ va_start(ap, zFormat); zSql = sqlite3VMPrintf(zFormat, ap); va_end(ap); if( zSql==0 ){ pParse->db->mallocFailed = 1; return; /* A malloc must have failed */ } pParse->nested++; memcpy(saveBuf, &pParse->nVar, SAVE_SZ); memset(&pParse->nVar, 0, SAVE_SZ); sqlite3RunParser(pParse, zSql, 0); sqlite3_free(zSql); memcpy(&pParse->nVar, saveBuf, SAVE_SZ); pParse->nested--; } /* ** Locate the in-memory structure that describes a particular database ** table given the name of that table and (optionally) the name of the |
︙ | ︙ | |||
332 333 334 335 336 337 338 | return p; } /* ** Reclaim the memory used by an index */ static void freeIndex(Index *p){ | | | | 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 | return p; } /* ** Reclaim the memory used by an index */ static void freeIndex(Index *p){ sqlite3_free(p->zColAff); sqlite3_free(p); } /* ** Remove the given index from the index hash table, and free ** its memory structures. ** ** The index is removed from the database hash tables but |
︙ | ︙ | |||
422 423 424 425 426 427 428 | if( pDb->pAux && pDb->xFreeAux ) pDb->xFreeAux(pDb->pAux); pDb->pAux = 0; } } for(i=j=2; i<db->nDb; i++){ struct Db *pDb = &db->aDb[i]; if( pDb->pBt==0 ){ | | | | | | | | 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 | if( pDb->pAux && pDb->xFreeAux ) pDb->xFreeAux(pDb->pAux); pDb->pAux = 0; } } for(i=j=2; i<db->nDb; i++){ struct Db *pDb = &db->aDb[i]; if( pDb->pBt==0 ){ sqlite3_free(pDb->zName); pDb->zName = 0; continue; } if( j<i ){ db->aDb[j] = db->aDb[i]; } j++; } memset(&db->aDb[j], 0, (db->nDb-j)*sizeof(db->aDb[j])); db->nDb = j; if( db->nDb<=2 && db->aDb!=db->aDbStatic ){ memcpy(db->aDbStatic, db->aDb, 2*sizeof(db->aDb[0])); sqlite3_free(db->aDb); db->aDb = db->aDbStatic; } } /* ** This routine is called when a commit occurs. */ void sqlite3CommitInternalChanges(sqlite3 *db){ db->flags &= ~SQLITE_InternChanges; } /* ** Clear the column names from a table or view. */ static void sqliteResetColumnNames(Table *pTable){ int i; Column *pCol; assert( pTable!=0 ); if( (pCol = pTable->aCol)!=0 ){ for(i=0; i<pTable->nCol; i++, pCol++){ sqlite3_free(pCol->zName); sqlite3ExprDelete(pCol->pDflt); sqlite3_free(pCol->zType); sqlite3_free(pCol->zColl); } sqlite3_free(pTable->aCol); } pTable->aCol = 0; pTable->nCol = 0; } /* ** Remove the memory data structures associated with the given |
︙ | ︙ | |||
506 507 508 509 510 511 512 | /* Delete all foreign keys associated with this table. The keys ** should have already been unlinked from the pSchema->aFKey hash table */ for(pFKey=pTable->pFKey; pFKey; pFKey=pNextFKey){ pNextFKey = pFKey->pNextFrom; assert( sqlite3HashFind(&pTable->pSchema->aFKey, pFKey->zTo, strlen(pFKey->zTo)+1)!=pFKey ); | | | | | | 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 | /* Delete all foreign keys associated with this table. The keys ** should have already been unlinked from the pSchema->aFKey hash table */ for(pFKey=pTable->pFKey; pFKey; pFKey=pNextFKey){ pNextFKey = pFKey->pNextFrom; assert( sqlite3HashFind(&pTable->pSchema->aFKey, pFKey->zTo, strlen(pFKey->zTo)+1)!=pFKey ); sqlite3_free(pFKey); } #endif /* Delete the Table structure itself. */ sqliteResetColumnNames(pTable); sqlite3_free(pTable->zName); sqlite3_free(pTable->zColAff); sqlite3SelectDelete(pTable->pSelect); #ifndef SQLITE_OMIT_CHECK sqlite3ExprDelete(pTable->pCheck); #endif sqlite3VtabClear(pTable); sqlite3_free(pTable); } /* ** Unlink the given table from the hash tables and the delete the ** table structure with all its indices and foreign keys. */ void sqlite3UnlinkAndDeleteTable(sqlite3 *db, int iDb, const char *zTabName){ |
︙ | ︙ | |||
567 568 569 570 571 572 573 | ** is obtained from sqliteMalloc() and must be freed by the calling ** function. ** ** Tokens are often just pointers into the original SQL text and so ** are not \000 terminated and are not persistent. The returned string ** is \000 terminated and is persistent. */ | | | | 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 | ** is obtained from sqliteMalloc() and must be freed by the calling ** function. ** ** Tokens are often just pointers into the original SQL text and so ** are not \000 terminated and are not persistent. The returned string ** is \000 terminated and is persistent. */ char *sqlite3NameFromToken(sqlite3 *db, Token *pName){ char *zName; if( pName ){ zName = sqlite3DbStrNDup(db, (char*)pName->z, pName->n); sqlite3Dequote(zName); }else{ zName = 0; } return zName; } |
︙ | ︙ | |||
602 603 604 605 606 607 608 | */ int sqlite3FindDb(sqlite3 *db, Token *pName){ int i = -1; /* Database number */ int n; /* Number of characters in the name */ Db *pDb; /* A database whose name space is being searched */ char *zName; /* Name we are searching for */ | | | | 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 | */ int sqlite3FindDb(sqlite3 *db, Token *pName){ int i = -1; /* Database number */ int n; /* Number of characters in the name */ Db *pDb; /* A database whose name space is being searched */ char *zName; /* Name we are searching for */ zName = sqlite3NameFromToken(db, pName); if( zName ){ n = strlen(zName); for(i=(db->nDb-1), pDb=&db->aDb[i]; i>=0; i--, pDb--){ if( (!OMIT_TEMPDB || i!=1 ) && n==strlen(pDb->zName) && 0==sqlite3StrICmp(pDb->zName, zName) ){ break; } } sqlite3_free(zName); } return i; } /* The table or view or trigger name is passed to this routine via tokens ** pName1 and pName2. If the table name was fully qualified, for example: ** |
︙ | ︙ | |||
734 735 736 737 738 739 740 | /* If creating a temp table, the name may not be qualified */ sqlite3ErrorMsg(pParse, "temporary table name must be unqualified"); return; } if( !OMIT_TEMPDB && isTemp ) iDb = 1; pParse->sNameToken = *pName; | | | 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 | /* If creating a temp table, the name may not be qualified */ sqlite3ErrorMsg(pParse, "temporary table name must be unqualified"); return; } if( !OMIT_TEMPDB && isTemp ) iDb = 1; pParse->sNameToken = *pName; zName = sqlite3NameFromToken(db, pName); if( zName==0 ) return; if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ goto begin_table_error; } if( db->init.iDb==1 ) isTemp = 1; #ifndef SQLITE_OMIT_AUTHORIZATION assert( (isTemp & 1)==isTemp ); |
︙ | ︙ | |||
791 792 793 794 795 796 797 | } if( sqlite3FindIndex(db, zName, 0)!=0 && (iDb==0 || !db->init.busy) ){ sqlite3ErrorMsg(pParse, "there is already an index named %s", zName); goto begin_table_error; } } | | > | 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 | } if( sqlite3FindIndex(db, zName, 0)!=0 && (iDb==0 || !db->init.busy) ){ sqlite3ErrorMsg(pParse, "there is already an index named %s", zName); goto begin_table_error; } } pTable = sqlite3MallocZero( sizeof(Table) ); if( pTable==0 ){ db->mallocFailed = 1; pParse->rc = SQLITE_NOMEM; pParse->nErr++; goto begin_table_error; } pTable->zName = zName; pTable->iPKey = -1; pTable->pSchema = db->aDb[iDb].pSchema; |
︙ | ︙ | |||
877 878 879 880 881 882 883 | } /* Normal (non-error) return. */ return; /* If an error occurs, we jump here */ begin_table_error: | | | 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 | } /* Normal (non-error) return. */ return; /* If an error occurs, we jump here */ begin_table_error: sqlite3_free(zName); return; } /* ** This macro is used to compare two strings in a case-insensitive manner. ** It is slightly faster than calling sqlite3StrICmp() directly, but ** produces larger code. |
︙ | ︙ | |||
912 913 914 915 916 917 918 | char *z; Column *pCol; if( (p = pParse->pNewTable)==0 ) return; if( p->nCol+1>SQLITE_MAX_COLUMN ){ sqlite3ErrorMsg(pParse, "too many columns on %s", p->zName); return; } | | | | > | | 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 | char *z; Column *pCol; if( (p = pParse->pNewTable)==0 ) return; if( p->nCol+1>SQLITE_MAX_COLUMN ){ sqlite3ErrorMsg(pParse, "too many columns on %s", p->zName); return; } z = sqlite3NameFromToken(pParse->db, pName); if( z==0 ) return; for(i=0; i<p->nCol; i++){ if( STRICMP(z, p->aCol[i].zName) ){ sqlite3ErrorMsg(pParse, "duplicate column name: %s", z); sqlite3_free(z); return; } } if( (p->nCol & 0x7)==0 ){ Column *aNew; aNew = sqlite3_realloc( p->aCol, (p->nCol+8)*sizeof(p->aCol[0])); if( aNew==0 ){ pParse->db->mallocFailed = 1; sqlite3_free(z); return; } p->aCol = aNew; } pCol = &p->aCol[p->nCol]; memset(pCol, 0, sizeof(p->aCol[0])); pCol->zName = z; |
︙ | ︙ | |||
1037 1038 1039 1040 1041 1042 1043 | int i; Column *pCol; if( (p = pParse->pNewTable)==0 ) return; i = p->nCol-1; if( i<0 ) return; pCol = &p->aCol[i]; | | | | 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 | int i; Column *pCol; if( (p = pParse->pNewTable)==0 ) return; i = p->nCol-1; if( i<0 ) return; pCol = &p->aCol[i]; sqlite3_free(pCol->zType); pCol->zType = sqlite3NameFromToken(pParse->db, pType); pCol->affinity = sqlite3AffinityType(pType); } /* ** The expression is the default value for the most recently added column ** of the table currently under construction. ** |
︙ | ︙ | |||
1062 1063 1064 1065 1066 1067 1068 1069 | if( (p = pParse->pNewTable)!=0 ){ pCol = &(p->aCol[p->nCol-1]); if( !sqlite3ExprIsConstantOrFunction(pExpr) ){ sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant", pCol->zName); }else{ Expr *pCopy; sqlite3ExprDelete(pCol->pDflt); | > | | | 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 | if( (p = pParse->pNewTable)!=0 ){ pCol = &(p->aCol[p->nCol-1]); if( !sqlite3ExprIsConstantOrFunction(pExpr) ){ sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant", pCol->zName); }else{ Expr *pCopy; sqlite3 *db = pParse->db; sqlite3ExprDelete(pCol->pDflt); pCol->pDflt = pCopy = sqlite3ExprDup(db, pExpr); if( pCopy ){ sqlite3TokenCopy(db, &pCopy->span, &pExpr->span); } } } sqlite3ExprDelete(pExpr); } /* |
︙ | ︙ | |||
1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 | */ void sqlite3AddCheckConstraint( Parse *pParse, /* Parsing context */ Expr *pCheckExpr /* The check expression */ ){ #ifndef SQLITE_OMIT_CHECK Table *pTab = pParse->pNewTable; if( pTab && !IN_DECLARE_VTAB ){ /* The CHECK expression must be duplicated so that tokens refer ** to malloced space and not the (ephemeral) text of the CREATE TABLE ** statement */ | > | > | | 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 | */ void sqlite3AddCheckConstraint( Parse *pParse, /* Parsing context */ Expr *pCheckExpr /* The check expression */ ){ #ifndef SQLITE_OMIT_CHECK Table *pTab = pParse->pNewTable; sqlite3 *db = pParse->db; if( pTab && !IN_DECLARE_VTAB ){ /* The CHECK expression must be duplicated so that tokens refer ** to malloced space and not the (ephemeral) text of the CREATE TABLE ** statement */ pTab->pCheck = sqlite3ExprAnd(db, pTab->pCheck, sqlite3ExprDup(db, pCheckExpr)); } #endif sqlite3ExprDelete(pCheckExpr); } /* ** Set the collation function of the most recently parsed table column ** to the CollSeq given. */ void sqlite3AddCollateType(Parse *pParse, const char *zType, int nType){ Table *p; int i; if( (p = pParse->pNewTable)==0 ) return; i = p->nCol-1; if( sqlite3LocateCollSeq(pParse, zType, nType) ){ Index *pIdx; p->aCol[i].zColl = sqlite3DbStrNDup(pParse->db, zType, nType); /* If the column is declared as "<name> PRIMARY KEY COLLATE <type>", ** then an index may have been created on this column before the ** collation type was added. Correct this if it is the case. */ for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){ assert( pIdx->nColumn==1 ); |
︙ | ︙ | |||
1322 1323 1324 1325 1326 1327 1328 | zEnd = ")"; }else{ zSep = "\n "; zSep2 = ",\n "; zEnd = "\n)"; } n += 35 + 6*p->nCol; | | | 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 | zEnd = ")"; }else{ zSep = "\n "; zSep2 = ",\n "; zEnd = "\n)"; } n += 35 + 6*p->nCol; zStmt = sqlite3_malloc( n ); if( zStmt==0 ) return 0; sqlite3_snprintf(n, zStmt, !OMIT_TEMPDB&&isTemp ? "CREATE TEMP TABLE ":"CREATE TABLE "); k = strlen(zStmt); identPut(zStmt, &k, p->zName); zStmt[k++] = '('; for(pCol=p->aCol, i=0; i<p->nCol; i++, pCol++){ |
︙ | ︙ | |||
1375 1376 1377 1378 1379 1380 1381 | Token *pEnd, /* The final ')' token in the CREATE TABLE */ Select *pSelect /* Select from a "CREATE ... AS SELECT" */ ){ Table *p; sqlite3 *db = pParse->db; int iDb; | | | 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 | Token *pEnd, /* The final ')' token in the CREATE TABLE */ Select *pSelect /* Select from a "CREATE ... AS SELECT" */ ){ Table *p; sqlite3 *db = pParse->db; int iDb; if( (pEnd==0 && pSelect==0) || pParse->nErr || db->mallocFailed ) { return; } p = pParse->pNewTable; if( p==0 ) return; assert( !db->init.busy || !pSelect ); |
︙ | ︙ | |||
1509 1510 1511 1512 1513 1514 1515 | "WHERE rowid=#1", db->aDb[iDb].zName, SCHEMA_TABLE(iDb), zType, p->zName, p->zName, zStmt ); | | | 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 | "WHERE rowid=#1", db->aDb[iDb].zName, SCHEMA_TABLE(iDb), zType, p->zName, p->zName, zStmt ); sqlite3_free(zStmt); sqlite3ChangeCookie(db, v, iDb); #ifndef SQLITE_OMIT_AUTOINCREMENT /* Check to see if we need to create an sqlite_sequence table for ** keeping track of autoincrement keys. */ if( p->autoInc ){ |
︙ | ︙ | |||
1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 | if( db->init.busy && pParse->nErr==0 ){ Table *pOld; FKey *pFKey; Schema *pSchema = p->pSchema; pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName, strlen(p->zName)+1,p); if( pOld ){ assert( p==pOld ); /* Malloc must have failed inside HashInsert() */ return; } #ifndef SQLITE_OMIT_FOREIGN_KEY for(pFKey=p->pFKey; pFKey; pFKey=pFKey->pNextFrom){ int nTo = strlen(pFKey->zTo) + 1; pFKey->pNextTo = sqlite3HashFind(&pSchema->aFKey, pFKey->zTo, nTo); sqlite3HashInsert(&pSchema->aFKey, pFKey->zTo, nTo, pFKey); | > | 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 | if( db->init.busy && pParse->nErr==0 ){ Table *pOld; FKey *pFKey; Schema *pSchema = p->pSchema; pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName, strlen(p->zName)+1,p); if( pOld ){ assert( p==pOld ); /* Malloc must have failed inside HashInsert() */ db->mallocFailed = 1; return; } #ifndef SQLITE_OMIT_FOREIGN_KEY for(pFKey=p->pFKey; pFKey; pFKey=pFKey->pNextFrom){ int nTo = strlen(pFKey->zTo) + 1; pFKey->pNextTo = sqlite3HashFind(&pSchema->aFKey, pFKey->zTo, nTo); sqlite3HashInsert(&pSchema->aFKey, pFKey->zTo, nTo, pFKey); |
︙ | ︙ | |||
1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 | Table *p; int n; const unsigned char *z; Token sEnd; DbFixer sFix; Token *pName; int iDb; if( pParse->nVar>0 ){ sqlite3ErrorMsg(pParse, "parameters are not allowed in views"); sqlite3SelectDelete(pSelect); return; } sqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0, noErr); p = pParse->pNewTable; if( p==0 || pParse->nErr ){ sqlite3SelectDelete(pSelect); return; } sqlite3TwoPartName(pParse, pName1, pName2, &pName); | > | | | | | 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 | Table *p; int n; const unsigned char *z; Token sEnd; DbFixer sFix; Token *pName; int iDb; sqlite3 *db = pParse->db; if( pParse->nVar>0 ){ sqlite3ErrorMsg(pParse, "parameters are not allowed in views"); sqlite3SelectDelete(pSelect); return; } sqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0, noErr); p = pParse->pNewTable; if( p==0 || pParse->nErr ){ sqlite3SelectDelete(pSelect); return; } sqlite3TwoPartName(pParse, pName1, pName2, &pName); iDb = sqlite3SchemaToIndex(db, p->pSchema); if( sqlite3FixInit(&sFix, pParse, iDb, "view", pName) && sqlite3FixSelect(&sFix, pSelect) ){ sqlite3SelectDelete(pSelect); return; } /* Make a copy of the entire SELECT statement that defines the view. ** This will force all the Expr.token.z values to be dynamically ** allocated rather than point to the input string - which means that ** they will persist after the current sqlite3_exec() call returns. */ p->pSelect = sqlite3SelectDup(db, pSelect); sqlite3SelectDelete(pSelect); if( db->mallocFailed ){ return; } if( !db->init.busy ){ sqlite3ViewGetColumnNames(pParse, p); } /* Locate the end of the CREATE VIEW statement. Make sEnd point to ** the end. */ sEnd = pParse->sLastToken; |
︙ | ︙ | |||
1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 | ** of errors. If an error is seen leave an error message in pParse->zErrMsg. */ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ Table *pSelTab; /* A fake table from which we get the result set */ Select *pSel; /* Copy of the SELECT that implements the view */ int nErr = 0; /* Number of errors encountered */ int n; /* Temporarily holds the number of cursors assigned */ assert( pTable ); #ifndef SQLITE_OMIT_VIRTUALTABLE if( sqlite3VtabCallConnect(pParse, pTable) ){ return SQLITE_ERROR; } | > | 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 | ** of errors. If an error is seen leave an error message in pParse->zErrMsg. */ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ Table *pSelTab; /* A fake table from which we get the result set */ Select *pSel; /* Copy of the SELECT that implements the view */ int nErr = 0; /* Number of errors encountered */ int n; /* Temporarily holds the number of cursors assigned */ sqlite3 *db = pParse->db; /* Database connection for malloc errors */ assert( pTable ); #ifndef SQLITE_OMIT_VIRTUALTABLE if( sqlite3VtabCallConnect(pParse, pTable) ){ return SQLITE_ERROR; } |
︙ | ︙ | |||
1696 1697 1698 1699 1700 1701 1702 | ** Note that the call to sqlite3ResultSetOfSelect() will expand any ** "*" elements in the results set of the view and will assign cursors ** to the elements of the FROM clause. But we do not want these changes ** to be permanent. So the computation is done on a copy of the SELECT ** statement that defines the view. */ assert( pTable->pSelect ); | | | 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 | ** Note that the call to sqlite3ResultSetOfSelect() will expand any ** "*" elements in the results set of the view and will assign cursors ** to the elements of the FROM clause. But we do not want these changes ** to be permanent. So the computation is done on a copy of the SELECT ** statement that defines the view. */ assert( pTable->pSelect ); pSel = sqlite3SelectDup(db, pTable->pSelect); if( pSel ){ n = pParse->nTab; sqlite3SrcListAssignCursors(pParse, pSel->pSrc); pTable->nCol = -1; pSelTab = sqlite3ResultSetOfSelect(pParse, 0, pSel); pParse->nTab = n; if( pSelTab ){ |
︙ | ︙ | |||
1875 1876 1877 1878 1879 1880 1881 | */ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){ Table *pTab; Vdbe *v; sqlite3 *db = pParse->db; int iDb; | | | 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 | */ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){ Table *pTab; Vdbe *v; sqlite3 *db = pParse->db; int iDb; if( pParse->nErr || db->mallocFailed ){ goto exit_drop_table; } assert( pName->nSrc==1 ); pTab = sqlite3LocateTable(pParse, pName->a[0].zName, pName->a[0].zDatabase); if( pTab==0 ){ if( noErr ){ |
︙ | ︙ | |||
2078 2079 2080 2081 2082 2083 2084 | } nByte = sizeof(*pFKey) + nCol*sizeof(pFKey->aCol[0]) + pTo->n + 1; if( pToCol ){ for(i=0; i<pToCol->nExpr; i++){ nByte += strlen(pToCol->a[i].zName) + 1; } } | | | > > | 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 | } nByte = sizeof(*pFKey) + nCol*sizeof(pFKey->aCol[0]) + pTo->n + 1; if( pToCol ){ for(i=0; i<pToCol->nExpr; i++){ nByte += strlen(pToCol->a[i].zName) + 1; } } pFKey = sqlite3DbMallocZero(pParse->db, nByte ); if( pFKey==0 ){ goto fk_end; } pFKey->pFrom = p; pFKey->pNextFrom = p->pFKey; z = (char*)&pFKey[1]; pFKey->aCol = (struct sColMap*)z; z += sizeof(struct sColMap)*nCol; pFKey->zTo = z; memcpy(z, pTo->z, pTo->n); |
︙ | ︙ | |||
2130 2131 2132 2133 2134 2135 2136 | /* Link the foreign key to the table as the last step. */ p->pFKey = pFKey; pFKey = 0; fk_end: | | | 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 | /* Link the foreign key to the table as the last step. */ p->pFKey = pFKey; pFKey = 0; fk_end: sqlite3_free(pFKey); #endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */ sqlite3ExprListDelete(pFromCol); sqlite3ExprListDelete(pToCol); } /* ** This routine is called when an INITIALLY IMMEDIATE or INITIALLY DEFERRED |
︙ | ︙ | |||
2171 2172 2173 2174 2175 2176 2177 | Table *pTab = pIndex->pTable; /* The table that is indexed */ int iTab = pParse->nTab; /* Btree cursor used for pTab */ int iIdx = pParse->nTab+1; /* Btree cursor used for pIndex */ int addr1; /* Address of top of loop */ int tnum; /* Root page of index */ Vdbe *v; /* Generate code into this virtual machine */ KeyInfo *pKey; /* KeyInfo for index */ | > | | | 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 | Table *pTab = pIndex->pTable; /* The table that is indexed */ int iTab = pParse->nTab; /* Btree cursor used for pTab */ int iIdx = pParse->nTab+1; /* Btree cursor used for pIndex */ int addr1; /* Address of top of loop */ int tnum; /* Root page of index */ Vdbe *v; /* Generate code into this virtual machine */ KeyInfo *pKey; /* KeyInfo for index */ sqlite3 *db = pParse->db; /* The database connection */ int iDb = sqlite3SchemaToIndex(db, pIndex->pSchema); #ifndef SQLITE_OMIT_AUTHORIZATION if( sqlite3AuthCheck(pParse, SQLITE_REINDEX, pIndex->zName, 0, db->aDb[iDb].zName ) ){ return; } #endif /* Require a write-lock on the table to perform this operation */ sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName); |
︙ | ︙ | |||
2207 2208 2209 2210 2211 2212 2213 | int addr2 = curaddr+4; sqlite3VdbeChangeP2(v, curaddr-1, addr2); sqlite3VdbeAddOp(v, OP_Rowid, iTab, 0); sqlite3VdbeAddOp(v, OP_AddImm, 1, 0); sqlite3VdbeAddOp(v, OP_IsUnique, iIdx, addr2); sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, OE_Abort, "indexed columns are not unique", P3_STATIC); | | | 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 | int addr2 = curaddr+4; sqlite3VdbeChangeP2(v, curaddr-1, addr2); sqlite3VdbeAddOp(v, OP_Rowid, iTab, 0); sqlite3VdbeAddOp(v, OP_AddImm, 1, 0); sqlite3VdbeAddOp(v, OP_IsUnique, iIdx, addr2); sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, OE_Abort, "indexed columns are not unique", P3_STATIC); assert( db->mallocFailed || addr2==sqlite3VdbeCurrentAddr(v) ); } sqlite3VdbeAddOp(v, OP_IdxInsert, iIdx, 0); sqlite3VdbeAddOp(v, OP_Next, iTab, addr1+1); sqlite3VdbeJumpHere(v, addr1); sqlite3VdbeAddOp(v, OP_Close, iTab, 0); sqlite3VdbeAddOp(v, OP_Close, iIdx, 0); } |
︙ | ︙ | |||
2257 2258 2259 2260 2261 2262 2263 | int iDb; /* Index of the database that is being written */ Token *pName = 0; /* Unqualified name of the index to create */ struct ExprList_item *pListItem; /* For looping over pList */ int nCol; int nExtra = 0; char *zExtra; | | | 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 | int iDb; /* Index of the database that is being written */ Token *pName = 0; /* Unqualified name of the index to create */ struct ExprList_item *pListItem; /* For looping over pList */ int nCol; int nExtra = 0; char *zExtra; if( pParse->nErr || db->mallocFailed || IN_DECLARE_VTAB ){ goto exit_create_index; } /* ** Find the table that is to be indexed. Return early if not found. */ if( pTblName!=0 ){ |
︙ | ︙ | |||
2335 2336 2337 2338 2339 2340 2341 | ** index, then we will continue to process this index. ** ** If pName==0 it means that we are ** dealing with a primary key or UNIQUE constraint. We have to invent our ** own name. */ if( pName ){ | | | 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 | ** index, then we will continue to process this index. ** ** If pName==0 it means that we are ** dealing with a primary key or UNIQUE constraint. We have to invent our ** own name. */ if( pName ){ zName = sqlite3NameFromToken(db, pName); if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) goto exit_create_index; if( zName==0 ) goto exit_create_index; if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ goto exit_create_index; } if( !db->init.busy ){ if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) goto exit_create_index; |
︙ | ︙ | |||
2408 2409 2410 2411 2412 2413 2414 | } /* ** Allocate the index structure. */ nName = strlen(zName); nCol = pList->nExpr; | | > | > | 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 | } /* ** Allocate the index structure. */ nName = strlen(zName); nCol = pList->nExpr; pIndex = sqlite3DbMallocZero(db, sizeof(Index) + /* Index structure */ sizeof(int)*nCol + /* Index.aiColumn */ sizeof(int)*(nCol+1) + /* Index.aiRowEst */ sizeof(char *)*nCol + /* Index.azColl */ sizeof(u8)*nCol + /* Index.aSortOrder */ nName + 1 + /* Index.zName */ nExtra /* Collation sequence names */ ); if( db->mallocFailed ){ goto exit_create_index; } pIndex->azColl = (char**)(&pIndex[1]); pIndex->aiColumn = (int *)(&pIndex->azColl[nCol]); pIndex->aiRowEst = (unsigned *)(&pIndex->aiColumn[nCol]); pIndex->aSortOrder = (u8 *)(&pIndex->aiRowEst[nCol+1]); pIndex->zName = (char *)(&pIndex->aSortOrder[nCol]); zExtra = (char *)(&pIndex->zName[nName+1]); memcpy(pIndex->zName, zName, nName+1); |
︙ | ︙ | |||
2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 | */ if( db->init.busy ){ Index *p; p = sqlite3HashInsert(&pIndex->pSchema->idxHash, pIndex->zName, strlen(pIndex->zName)+1, pIndex); if( p ){ assert( p==pIndex ); /* Malloc must have failed */ goto exit_create_index; } db->flags |= SQLITE_InternChanges; if( pTblName!=0 ){ pIndex->tnum = db->init.newTnum; } } | > | 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 | */ if( db->init.busy ){ Index *p; p = sqlite3HashInsert(&pIndex->pSchema->idxHash, pIndex->zName, strlen(pIndex->zName)+1, pIndex); if( p ){ assert( p==pIndex ); /* Malloc must have failed */ db->mallocFailed = 1; goto exit_create_index; } db->flags |= SQLITE_InternChanges; if( pTblName!=0 ){ pIndex->tnum = db->init.newTnum; } } |
︙ | ︙ | |||
2607 2608 2609 2610 2611 2612 2613 | "INSERT INTO %Q.%s VALUES('index',%Q,%Q,#0,%Q);", db->aDb[iDb].zName, SCHEMA_TABLE(iDb), pIndex->zName, pTab->zName, zStmt ); sqlite3VdbeAddOp(v, OP_Pop, 1, 0); | | | 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 | "INSERT INTO %Q.%s VALUES('index',%Q,%Q,#0,%Q);", db->aDb[iDb].zName, SCHEMA_TABLE(iDb), pIndex->zName, pTab->zName, zStmt ); sqlite3VdbeAddOp(v, OP_Pop, 1, 0); sqlite3_free(zStmt); /* Fill the index with data and reparse the schema. Code an OP_Expire ** to invalidate all pre-compiled statements. */ if( pTblName ){ sqlite3RefillIndex(pParse, pIndex, iMem); sqlite3ChangeCookie(db, v, iDb); |
︙ | ︙ | |||
2649 2650 2651 2652 2653 2654 2655 | /* Clean up before exiting */ exit_create_index: if( pIndex ){ freeIndex(pIndex); } sqlite3ExprListDelete(pList); sqlite3SrcListDelete(pTblName); | | | 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 | /* Clean up before exiting */ exit_create_index: if( pIndex ){ freeIndex(pIndex); } sqlite3ExprListDelete(pList); sqlite3SrcListDelete(pTblName); sqlite3_free(zName); return; } /* ** Generate code to make sure the file format number is at least minFormat. ** The generated code will increase the file format number if necessary. */ |
︙ | ︙ | |||
2714 2715 2716 2717 2718 2719 2720 | */ void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists){ Index *pIndex; Vdbe *v; sqlite3 *db = pParse->db; int iDb; | | | 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 | */ void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists){ Index *pIndex; Vdbe *v; sqlite3 *db = pParse->db; int iDb; if( pParse->nErr || db->mallocFailed ){ goto exit_drop_index; } assert( pName->nSrc==1 ); if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ goto exit_drop_index; } pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase); |
︙ | ︙ | |||
2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 | ** The index of the new entry is returned in *pIdx. ** ** This routine returns a pointer to the array of objects. This ** might be the same as the pArray parameter or it might be a different ** pointer if the array was resized. */ void *sqlite3ArrayAllocate( void *pArray, /* Array of objects. Might be reallocated */ int szEntry, /* Size of each object in the array */ int initSize, /* Suggested initial allocation, in elements */ int *pnEntry, /* Number of objects currently in use */ int *pnAlloc, /* Current size of the allocation, in elements */ int *pIdx /* Write the index of a new slot here */ ){ char *z; if( *pnEntry >= *pnAlloc ){ void *pNew; int newSize; newSize = (*pnAlloc)*2 + initSize; | > | > | | > | | | | | 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 | ** The index of the new entry is returned in *pIdx. ** ** This routine returns a pointer to the array of objects. This ** might be the same as the pArray parameter or it might be a different ** pointer if the array was resized. */ void *sqlite3ArrayAllocate( sqlite3 *db, /* Connection to notify of malloc failures */ void *pArray, /* Array of objects. Might be reallocated */ int szEntry, /* Size of each object in the array */ int initSize, /* Suggested initial allocation, in elements */ int *pnEntry, /* Number of objects currently in use */ int *pnAlloc, /* Current size of the allocation, in elements */ int *pIdx /* Write the index of a new slot here */ ){ char *z; if( *pnEntry >= *pnAlloc ){ void *pNew; int newSize; newSize = (*pnAlloc)*2 + initSize; pNew = sqlite3_realloc(pArray, newSize*szEntry); if( pNew==0 ){ db->mallocFailed = 1; *pIdx = -1; return pArray; } *pnAlloc = newSize; pArray = pNew; } z = (char*)pArray; memset(&z[*pnEntry * szEntry], 0, szEntry); *pIdx = *pnEntry; ++*pnEntry; return pArray; } /* ** Append a new element to the given IdList. Create a new IdList if ** need be. ** ** A new IdList is returned, or NULL if malloc() fails. */ IdList *sqlite3IdListAppend(sqlite3 *db, IdList *pList, Token *pToken){ int i; if( pList==0 ){ pList = sqlite3DbMallocZero(db, sizeof(IdList) ); if( pList==0 ) return 0; pList->nAlloc = 0; } pList->a = sqlite3ArrayAllocate( db, pList->a, sizeof(pList->a[0]), 5, &pList->nId, &pList->nAlloc, &i ); if( i<0 ){ sqlite3IdListDelete(pList); return 0; } pList->a[i].zName = sqlite3NameFromToken(db, pToken); return pList; } /* ** Delete an IdList. */ void sqlite3IdListDelete(IdList *pList){ int i; if( pList==0 ) return; for(i=0; i<pList->nId; i++){ sqlite3_free(pList->a[i].zName); } sqlite3_free(pList->a); sqlite3_free(pList); } /* ** Return the index in pList of the identifier named zId. Return -1 ** if not found. */ int sqlite3IdListIndex(IdList *pList, const char *zName){ |
︙ | ︙ | |||
2882 2883 2884 2885 2886 2887 2888 | ** The SrcList.a[].zName field is filled with the table name which might ** come from pTable (if pDatabase is NULL) or from pDatabase. ** SrcList.a[].zDatabase is filled with the database name from pTable, ** or with NULL if no database is specified. ** ** In other words, if call like this: ** | | | | > > > > > | | > | | | | | | | > > | | | 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 | ** The SrcList.a[].zName field is filled with the table name which might ** come from pTable (if pDatabase is NULL) or from pDatabase. ** SrcList.a[].zDatabase is filled with the database name from pTable, ** or with NULL if no database is specified. ** ** In other words, if call like this: ** ** sqlite3SrcListAppend(D,A,B,0); ** ** Then B is a table name and the database name is unspecified. If called ** like this: ** ** sqlite3SrcListAppend(D,A,B,C); ** ** Then C is the table name and B is the database name. */ SrcList *sqlite3SrcListAppend( sqlite3 *db, /* Connection to notify of malloc failures */ SrcList *pList, /* Append to this SrcList. NULL creates a new SrcList */ Token *pTable, /* Table to append */ Token *pDatabase /* Database of the table */ ){ struct SrcList_item *pItem; if( pList==0 ){ pList = sqlite3DbMallocZero(db, sizeof(SrcList) ); if( pList==0 ) return 0; pList->nAlloc = 1; } if( pList->nSrc>=pList->nAlloc ){ SrcList *pNew; pList->nAlloc *= 2; pNew = sqlite3_realloc(pList, sizeof(*pList) + (pList->nAlloc-1)*sizeof(pList->a[0]) ); if( pNew==0 ){ db->mallocFailed = 1; sqlite3SrcListDelete(pList); return 0; } pList = pNew; } pItem = &pList->a[pList->nSrc]; memset(pItem, 0, sizeof(pList->a[0])); if( pDatabase && pDatabase->z==0 ){ pDatabase = 0; } if( pDatabase && pTable ){ Token *pTemp = pDatabase; pDatabase = pTable; pTable = pTemp; } pItem->zName = sqlite3NameFromToken(db, pTable); pItem->zDatabase = sqlite3NameFromToken(db, pDatabase); pItem->iCursor = -1; pItem->isPopulated = 0; pList->nSrc++; return pList; } /* ** Assign cursors to all tables in a SrcList */ void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){ int i; struct SrcList_item *pItem; assert(pList || pParse->db->mallocFailed ); if( pList ){ for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){ if( pItem->iCursor>=0 ) break; pItem->iCursor = pParse->nTab++; if( pItem->pSelect ){ sqlite3SrcListAssignCursors(pParse, pItem->pSelect->pSrc); } } } } /* ** Delete an entire SrcList including all its substructure. */ void sqlite3SrcListDelete(SrcList *pList){ int i; struct SrcList_item *pItem; if( pList==0 ) return; for(pItem=pList->a, i=0; i<pList->nSrc; i++, pItem++){ sqlite3_free(pItem->zDatabase); sqlite3_free(pItem->zName); sqlite3_free(pItem->zAlias); sqlite3DeleteTable(pItem->pTab); sqlite3SelectDelete(pItem->pSelect); sqlite3ExprDelete(pItem->pOn); sqlite3IdListDelete(pItem->pUsing); } sqlite3_free(pList); } /* ** This routine is called by the parser to add a new term to the ** end of a growing FROM clause. The "p" parameter is the part of ** the FROM clause that has already been constructed. "p" is NULL ** if this is the first term of the FROM clause. pTable and pDatabase ** are the name of the table and database named in the FROM clause term. ** pDatabase is NULL if the database name qualifier is missing - the ** usual case. If the term has a alias, then pAlias points to the ** alias token. If the term is a subquery, then pSubquery is the ** SELECT statement that the subquery encodes. The pTable and ** pDatabase parameters are NULL for subqueries. The pOn and pUsing ** parameters are the content of the ON and USING clauses. ** ** Return a new SrcList which encodes is the FROM with the new ** term added. */ SrcList *sqlite3SrcListAppendFromTerm( Parse *pParse, /* Parsing context */ SrcList *p, /* The left part of the FROM clause already seen */ Token *pTable, /* Name of the table to add to the FROM clause */ Token *pDatabase, /* Name of the database containing pTable */ Token *pAlias, /* The right-hand side of the AS subexpression */ Select *pSubquery, /* A subquery used in place of a table name */ Expr *pOn, /* The ON clause of a join */ IdList *pUsing /* The USING clause of a join */ ){ struct SrcList_item *pItem; sqlite3 *db = pParse->db; p = sqlite3SrcListAppend(db, p, pTable, pDatabase); if( p==0 || p->nSrc==0 ){ sqlite3ExprDelete(pOn); sqlite3IdListDelete(pUsing); sqlite3SelectDelete(pSubquery); return p; } pItem = &p->a[p->nSrc-1]; if( pAlias && pAlias->n ){ pItem->zAlias = sqlite3NameFromToken(db, pAlias); } pItem->pSelect = pSubquery; pItem->pOn = pOn; pItem->pUsing = pUsing; return p; } |
︙ | ︙ | |||
3041 3042 3043 3044 3045 3046 3047 | */ void sqlite3BeginTransaction(Parse *pParse, int type){ sqlite3 *db; Vdbe *v; int i; if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return; | | | | | 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 | */ void sqlite3BeginTransaction(Parse *pParse, int type){ sqlite3 *db; Vdbe *v; int i; if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return; if( pParse->nErr || db->mallocFailed ) return; if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0, 0) ) return; v = sqlite3GetVdbe(pParse); if( !v ) return; if( type!=TK_DEFERRED ){ for(i=0; i<db->nDb; i++){ sqlite3VdbeAddOp(v, OP_Transaction, i, (type==TK_EXCLUSIVE)+1); } } sqlite3VdbeAddOp(v, OP_AutoCommit, 0, 0); } /* ** Commit a transaction */ void sqlite3CommitTransaction(Parse *pParse){ sqlite3 *db; Vdbe *v; if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return; if( pParse->nErr || db->mallocFailed ) return; if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "COMMIT", 0, 0) ) return; v = sqlite3GetVdbe(pParse); if( v ){ sqlite3VdbeAddOp(v, OP_AutoCommit, 1, 0); } } /* ** Rollback a transaction */ void sqlite3RollbackTransaction(Parse *pParse){ sqlite3 *db; Vdbe *v; if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return; if( pParse->nErr || db->mallocFailed ) return; if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "ROLLBACK", 0, 0) ) return; v = sqlite3GetVdbe(pParse); if( v ){ sqlite3VdbeAddOp(v, OP_AutoCommit, 1, 1); } } |
︙ | ︙ | |||
3291 3292 3293 3294 3295 3296 3297 | if( pName1==0 || pName1->z==0 ){ reindexDatabases(pParse, 0); return; }else if( pName2==0 || pName2->z==0 ){ assert( pName1->z ); pColl = sqlite3FindCollSeq(db, ENC(db), (char*)pName1->z, pName1->n, 0); if( pColl ){ | | | | | | | | | | 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 | if( pName1==0 || pName1->z==0 ){ reindexDatabases(pParse, 0); return; }else if( pName2==0 || pName2->z==0 ){ assert( pName1->z ); pColl = sqlite3FindCollSeq(db, ENC(db), (char*)pName1->z, pName1->n, 0); if( pColl ){ char *zColl = sqlite3DbStrNDup(db, (const char *)pName1->z, pName1->n); if( zColl ){ reindexDatabases(pParse, zColl); sqlite3_free(zColl); } return; } } iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pObjName); if( iDb<0 ) return; z = sqlite3NameFromToken(db, pObjName); if( z==0 ) return; zDb = db->aDb[iDb].zName; pTab = sqlite3FindTable(db, z, zDb); if( pTab ){ reindexTable(pParse, pTab, 0); sqlite3_free(z); return; } pIndex = sqlite3FindIndex(db, z, zDb); sqlite3_free(z); if( pIndex ){ sqlite3BeginWriteOperation(pParse, 0, iDb); sqlite3RefillIndex(pParse, pIndex, -1); return; } sqlite3ErrorMsg(pParse, "unable to identify the object to be reindexed"); } #endif /* ** Return a dynamicly allocated KeyInfo structure that can be used ** with OP_OpenRead or OP_OpenWrite to access database index pIdx. ** ** If successful, a pointer to the new structure is returned. In this case ** the caller is responsible for calling sqlite3_free() on the returned ** pointer. If an error occurs (out of memory or missing collation ** sequence), NULL is returned and the state of pParse updated to reflect ** the error. */ KeyInfo *sqlite3IndexKeyinfo(Parse *pParse, Index *pIdx){ int i; int nCol = pIdx->nColumn; int nBytes = sizeof(KeyInfo) + (nCol-1)*sizeof(CollSeq*) + nCol; KeyInfo *pKey = (KeyInfo *)sqlite3DbMallocZer(pParse->db, nBytes); if( pKey ){ pKey->aSortOrder = (u8 *)&(pKey->aColl[nCol]); assert( &pKey->aSortOrder[nCol]==&(((u8 *)pKey)[nBytes]) ); for(i=0; i<nCol; i++){ char *zColl = pIdx->azColl[i]; assert( zColl ); pKey->aColl[i] = sqlite3LocateCollSeq(pParse, zColl, -1); pKey->aSortOrder[i] = pIdx->aSortOrder[i]; } pKey->nField = nCol; } if( pParse->nErr ){ sqlite3_free(pKey); pKey = 0; } return pKey; } |
Changes to src/callback.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** This file contains functions used to access the internal hash tables ** of user defined functions and collation sequences. ** | | | | | 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 36 37 38 39 40 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** This file contains functions used to access the internal hash tables ** of user defined functions and collation sequences. ** ** $Id: callback.c,v 1.19 2007/08/16 04:30:39 drh Exp $ */ #include "sqliteInt.h" /* ** Invoke the 'collation needed' callback to request a collation sequence ** in the database text encoding of name zName, length nName. ** If the collation sequence */ static void callCollNeeded(sqlite3 *db, const char *zName, int nName){ assert( !db->xCollNeeded || !db->xCollNeeded16 ); if( nName<0 ) nName = strlen(zName); if( db->xCollNeeded ){ char *zExternal = sqlite3DbStrNDup(db, zName, nName); if( !zExternal ) return; db->xCollNeeded(db->pCollNeededArg, db, (int)ENC(db), zExternal); sqlite3_free(zExternal); } #ifndef SQLITE_OMIT_UTF16 if( db->xCollNeeded16 ){ char const *zExternal; sqlite3_value *pTmp = sqlite3ValueNew(); sqlite3ValueSetStr(pTmp, nName, zName, SQLITE_UTF8, SQLITE_STATIC); zExternal = sqlite3ValueText(pTmp, SQLITE_UTF16NATIVE); |
︙ | ︙ | |||
158 159 160 161 162 163 164 | int create ){ CollSeq *pColl; if( nName<0 ) nName = strlen(zName); pColl = sqlite3HashFind(&db->aCollSeq, zName, nName); if( 0==pColl && create ){ | | | | | 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 | int create ){ CollSeq *pColl; if( nName<0 ) nName = strlen(zName); pColl = sqlite3HashFind(&db->aCollSeq, zName, nName); if( 0==pColl && create ){ pColl = sqlite3DbMallocZero(db, 3*sizeof(*pColl) + nName + 1 ); if( pColl ){ CollSeq *pDel = 0; pColl[0].zName = (char*)&pColl[3]; pColl[0].enc = SQLITE_UTF8; pColl[1].zName = (char*)&pColl[3]; pColl[1].enc = SQLITE_UTF16LE; pColl[2].zName = (char*)&pColl[3]; pColl[2].enc = SQLITE_UTF16BE; memcpy(pColl[0].zName, zName, nName); pColl[0].zName[nName] = 0; pDel = sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, nName, pColl); /* If a malloc() failure occured in sqlite3HashInsert(), it will ** return the pColl pointer to be deleted (because it wasn't added ** to the hash table). */ assert( !pDel || (db->mallocFailed && pDel==pColl) ); if( pDel ){ sqlite3_free(pDel); pColl = 0; } } } return pColl; } |
︙ | ︙ | |||
299 300 301 302 303 304 305 | } /* If the createFlag parameter is true, and the seach did not reveal an ** exact match for the name, number of arguments and encoding, then add a ** new entry to the hash table and return it. */ if( createFlag && bestmatch<6 && | | | | | 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 | } /* If the createFlag parameter is true, and the seach did not reveal an ** exact match for the name, number of arguments and encoding, then add a ** new entry to the hash table and return it. */ if( createFlag && bestmatch<6 && (pBest = sqlite3DbMallocZero(db, sizeof(*pBest)+nName))!=0 ){ pBest->nArg = nArg; pBest->pNext = pFirst; pBest->iPrefEnc = enc; memcpy(pBest->zName, zName, nName); pBest->zName[nName] = 0; if( pBest==sqlite3HashInsert(&db->aFunc,pBest->zName,nName,(void*)pBest) ){ sqlite3_free(pBest); return 0; } } if( pBest && (pBest->xStep || pBest->xFunc || createFlag) ){ return pBest; } return 0; } /* ** Free all resources held by the schema structure. The void* argument points ** at a Schema struct. This function does not call sqlite3_free() on the ** pointer itself, it just cleans up subsiduary resources (i.e. the contents ** of the schema hash tables). */ void sqlite3SchemaFree(void *p){ Hash temp1; Hash temp2; HashElem *pElem; |
︙ | ︙ | |||
352 353 354 355 356 357 358 | pSchema->flags &= ~DB_SchemaLoaded; } /* ** Find and return the schema associated with a BTree. Create ** a new one if necessary. */ | | | | 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 | pSchema->flags &= ~DB_SchemaLoaded; } /* ** Find and return the schema associated with a BTree. Create ** a new one if necessary. */ Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){ Schema * p; if( pBt ){ p = (Schema *)sqlite3BtreeSchema(pBt,sizeof(Schema),sqlite3SchemaFree); }else{ p = (Schema *)sqlite3DbMallocZero(db,sizeof(Schema)); } if( p && 0==p->file_format ){ sqlite3HashInit(&p->tblHash, SQLITE_HASH_STRING, 0); sqlite3HashInit(&p->idxHash, SQLITE_HASH_STRING, 0); sqlite3HashInit(&p->trigHash, SQLITE_HASH_STRING, 0); sqlite3HashInit(&p->aFKey, SQLITE_HASH_STRING, 1); p->enc = SQLITE_UTF8; } return p; } |
Changes to src/date.c.
︙ | ︙ | |||
12 13 14 15 16 17 18 | ** This file contains the C functions that implement date and time ** functions for SQLite. ** ** There is only one exported symbol in this file - the function ** sqlite3RegisterDateTimeFunctions() 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 date and time ** functions for SQLite. ** ** There is only one exported symbol in this file - the function ** sqlite3RegisterDateTimeFunctions() found at the bottom of the file. ** All other code has file scope. ** ** $Id: date.c,v 1.67 2007/08/16 04:30:40 drh Exp $ ** ** SQLite processes all times and dates as Julian Day numbers. The ** dates and times are stored as the number of days since noon ** in Greenwich on November 24, 4714 B.C. according to the Gregorian ** calendar system. ** ** 1970-01-01 00:00:00 is JD 2440587.5 |
︙ | ︙ | |||
813 814 815 816 817 818 819 | } if( n<sizeof(zBuf) ){ z = zBuf; }else if( n>SQLITE_MAX_LENGTH ){ sqlite3_result_error_toobig(context); return; }else{ | | | 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 | } if( n<sizeof(zBuf) ){ z = zBuf; }else if( n>SQLITE_MAX_LENGTH ){ sqlite3_result_error_toobig(context); return; }else{ z = sqlite3_malloc( n ); if( z==0 ) return; } computeJD(&x); computeYMD_HMS(&x); for(i=j=0; zFmt[i]; i++){ if( zFmt[i]!='%' ){ z[j++] = zFmt[i]; |
︙ | ︙ | |||
876 877 878 879 880 881 882 | case '%': z[j++] = '%'; break; } } } z[j] = 0; sqlite3_result_text(context, z, -1, SQLITE_TRANSIENT); if( z!=zBuf ){ | | | 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 | case '%': z[j++] = '%'; break; } } } z[j] = 0; sqlite3_result_text(context, z, -1, SQLITE_TRANSIENT); if( z!=zBuf ){ sqlite3_free(z); } } /* ** current_time() ** ** This function returns the same value as time('now'). |
︙ | ︙ |
Changes to src/delete.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 ** in order to generate code for DELETE FROM 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 ** in order to generate code for DELETE FROM statements. ** ** $Id: delete.c,v 1.130 2007/08/16 04:30:40 drh Exp $ */ #include "sqliteInt.h" /* ** Look up every table that is named in pSrc. If any table is not found, ** add an error message to pParse->zErrMsg and return NULL. If all tables ** are found, return a pointer to the last table. |
︙ | ︙ | |||
111 112 113 114 115 116 117 | #ifndef SQLITE_OMIT_TRIGGER int isView; /* True if attempting to delete from a view */ int triggers_exist = 0; /* True if any triggers exist */ #endif sContext.pParse = 0; | > | < | 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | #ifndef SQLITE_OMIT_TRIGGER int isView; /* True if attempting to delete from a view */ int triggers_exist = 0; /* True if any triggers exist */ #endif sContext.pParse = 0; db = pParse->db; if( pParse->nErr || db->mallocFailed ){ goto delete_from_cleanup; } assert( pTabList->nSrc==1 ); /* Locate the table which we want to delete. This table has to be ** put in an SrcList structure because some of the subroutines we ** will be calling are designed to work with multiple tables and expect ** an SrcList* parameter instead of just a Table* parameter. */ |
︙ | ︙ | |||
192 193 194 195 196 197 198 | if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); sqlite3BeginWriteOperation(pParse, triggers_exist, iDb); /* If we are trying to delete from a view, realize that view into ** a ephemeral table. */ if( isView ){ | | | 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 | if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); sqlite3BeginWriteOperation(pParse, triggers_exist, iDb); /* If we are trying to delete from a view, realize that view into ** a ephemeral table. */ if( isView ){ Select *pView = sqlite3SelectDup(db, pTab->pSelect); sqlite3Select(pParse, pView, SRT_EphemTab, iCur, 0, 0, 0, 0); sqlite3SelectDelete(pView); } /* Initialize the counter of the number of rows deleted, if ** we are counting rows. */ |
︙ | ︙ |
Changes to src/expr.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 routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions 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 routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** ** $Id: expr.c,v 1.304 2007/08/16 04:30:40 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** Return the 'affinity' of the expression pExpr if any. ** |
︙ | ︙ | |||
213 214 215 216 217 218 219 | int p1 = binaryCompareP1(pLeft, pRight, jumpIfNull); CollSeq *p3 = sqlite3BinaryCompareCollSeq(pParse, pLeft, pRight); return sqlite3VdbeOp3(pParse->pVdbe, opcode, p1, dest, (void*)p3, P3_COLLSEQ); } /* ** Construct a new expression node and return a pointer to it. Memory | | | > > > > > | | 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 | int p1 = binaryCompareP1(pLeft, pRight, jumpIfNull); CollSeq *p3 = sqlite3BinaryCompareCollSeq(pParse, pLeft, pRight); return sqlite3VdbeOp3(pParse->pVdbe, opcode, p1, dest, (void*)p3, P3_COLLSEQ); } /* ** Construct a new expression node and return a pointer to it. Memory ** for this node is obtained from sqlite3_malloc(). The calling function ** is responsible for making sure the node eventually gets freed. */ Expr *sqlite3Expr( int op, /* Expression opcode */ Expr *pLeft, /* Left operand */ Expr *pRight, /* Right operand */ const Token *pToken /* Argument token */ ){ Expr *pNew; pNew = sqlite3MallocZero( sizeof(Expr) ); if( pNew==0 ){ /* When malloc fails, delete pLeft and pRight. Expressions passed to ** this function must always be allocated with sqlite3Expr() for this ** reason. */ sqlite3ExprDelete(pLeft); sqlite3ExprDelete(pRight); |
︙ | ︙ | |||
254 255 256 257 258 259 260 | } sqlite3ExprSetHeight(pNew); return pNew; } /* | | | | > > > > > > > | 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 | } sqlite3ExprSetHeight(pNew); return pNew; } /* ** Works like sqlite3Expr() except that it takes an extra Parse* ** argument and notifies the associated connection object if malloc fails. */ Expr *sqlite3PExpr( Parse *pParse, /* Parsing context */ int op, /* Expression opcode */ Expr *pLeft, /* Left operand */ Expr *pRight, /* Right operand */ const Token *pToken /* Argument token */ ){ Expr *pNew = sqlite3Expr(op, pLeft, pRight, pToken); if( pNew==0 ){ sqlite3ExprDelete(pLeft); sqlite3ExprDelete(pRight); pParse->db->mallocFailed = 1; } return pNew; } /* ** When doing a nested parse, you can include terms in an expression ** that look like this: #0 #1 #2 ... These terms refer to elements |
︙ | ︙ | |||
288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 | if( pParse->nested==0 ){ sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", pToken); return sqlite3Expr(TK_NULL, 0, 0, 0); } if( v==0 ) return 0; p = sqlite3Expr(TK_REGISTER, 0, 0, pToken); if( p==0 ){ return 0; /* Malloc failed */ } depth = atoi((char*)&pToken->z[1]); p->iTable = pParse->nMem++; sqlite3VdbeAddOp(v, OP_Dup, depth, 0); sqlite3VdbeAddOp(v, OP_MemStore, p->iTable, 1); return p; } /* ** Join two expressions using an AND operator. If either expression is ** NULL, then just return the other expression. */ | > | | > > > | | | | 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 | if( pParse->nested==0 ){ sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", pToken); return sqlite3Expr(TK_NULL, 0, 0, 0); } if( v==0 ) return 0; p = sqlite3Expr(TK_REGISTER, 0, 0, pToken); if( p==0 ){ pParse->db->mallocFailed = 1; return 0; /* Malloc failed */ } depth = atoi((char*)&pToken->z[1]); p->iTable = pParse->nMem++; sqlite3VdbeAddOp(v, OP_Dup, depth, 0); sqlite3VdbeAddOp(v, OP_MemStore, p->iTable, 1); return p; } /* ** Join two expressions using an AND operator. If either expression is ** NULL, then just return the other expression. */ Expr *sqlite3ExprAnd(sqlite *db, Expr *pLeft, Expr *pRight){ if( pLeft==0 ){ return pRight; }else if( pRight==0 ){ return pLeft; }else{ Expr *p = sqlite3Expr(TK_AND, pLeft, pRight, 0); if( p==0 ){ db->mallocFailed = 1; } } } /* ** Set the Expr.span field of the given expression to span all ** text between the two given tokens. */ void sqlite3ExprSpan(Expr *pExpr, Token *pLeft, Token *pRight){ assert( pRight!=0 ); assert( pLeft!=0 ); if( pRight->z && pLeft->z ){ assert( pLeft->dyn==0 || pLeft->z[pLeft->n]==0 ); if( pLeft->dyn==0 && pRight->dyn==0 ){ pExpr->span.z = pLeft->z; pExpr->span.n = pRight->n + (pRight->z - pLeft->z); }else{ pExpr->span.z = 0; } } } /* ** Construct a new expression node for a function with multiple ** arguments. */ Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *pToken){ Expr *pNew; assert( pToken ); pNew = sqlite3DbMallocZero(pParse->db, sizeof(Expr) ); if( pNew==0 ){ sqlite3ExprListDelete(pList); /* Avoid leaking memory when malloc fails */ return 0; } pNew->op = TK_FUNCTION; pNew->pList = pList; assert( pToken->dyn==0 ); |
︙ | ︙ | |||
369 370 371 372 373 374 375 376 377 378 379 380 381 382 | ** Wildcards of the form ":aaa" or "$aaa" are assigned the same number ** as the previous instance of the same wildcard. Or if this is the first ** instance of the wildcard, the next sequenial variable number is ** assigned. */ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){ Token *pToken; if( pExpr==0 ) return; pToken = &pExpr->token; assert( pToken->n>=1 ); assert( pToken->z!=0 ); assert( pToken->z[0]!=0 ); if( pToken->n==1 ){ /* Wildcard of the form "?". Assign the next variable number */ | > > | 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 | ** Wildcards of the form ":aaa" or "$aaa" are assigned the same number ** as the previous instance of the same wildcard. Or if this is the first ** instance of the wildcard, the next sequenial variable number is ** assigned. */ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){ Token *pToken; sqlite3 *db = pParse->db; if( pExpr==0 ) return; pToken = &pExpr->token; assert( pToken->n>=1 ); assert( pToken->z!=0 ); assert( pToken->z[0]!=0 ); if( pToken->n==1 ){ /* Wildcard of the form "?". Assign the next variable number */ |
︙ | ︙ | |||
409 410 411 412 413 414 415 | break; } } if( i>=pParse->nVarExpr ){ pExpr->iTable = ++pParse->nVar; if( pParse->nVarExpr>=pParse->nVarExprAlloc-1 ){ pParse->nVarExprAlloc += pParse->nVarExprAlloc + 10; | | > > > | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > > > > > > | | | > | 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 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 510 511 512 513 514 515 516 517 518 519 520 521 522 523 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 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 | break; } } if( i>=pParse->nVarExpr ){ pExpr->iTable = ++pParse->nVar; if( pParse->nVarExpr>=pParse->nVarExprAlloc-1 ){ pParse->nVarExprAlloc += pParse->nVarExprAlloc + 10; pParse->apVarExpr = sqlite3DbReallocOrFree( db, pParse->apVarExpr, pParse->nVarExprAlloc*sizeof(pParse->apVarExpr[0]) ); } if( !db->mallocFailed ){ assert( pParse->apVarExpr!=0 ); pParse->apVarExpr[pParse->nVarExpr++] = pExpr; } } } if( !pParse->nErr && pParse->nVar>SQLITE_MAX_VARIABLE_NUMBER ){ sqlite3ErrorMsg(pParse, "too many SQL variables"); } } /* ** Recursively delete an expression tree. */ void sqlite3ExprDelete(Expr *p){ if( p==0 ) return; if( p->span.dyn ) sqlite3_free((char*)p->span.z); if( p->token.dyn ) sqlite3_free((char*)p->token.z); sqlite3ExprDelete(p->pLeft); sqlite3ExprDelete(p->pRight); sqlite3ExprListDelete(p->pList); sqlite3SelectDelete(p->pSelect); sqlite3_free(p); } /* ** The Expr.token field might be a string literal that is quoted. ** If so, remove the quotation marks. */ void sqlite3DequoteExpr(sqlite3 *db, Expr *p){ if( ExprHasAnyProperty(p, EP_Dequoted) ){ return; } ExprSetProperty(p, EP_Dequoted); if( p->token.dyn==0 ){ sqlite3TokenCopy(db, &p->token, &p->token); } sqlite3Dequote((char*)p->token.z); } /* ** The following group of routines make deep copies of expressions, ** expression lists, ID lists, and select statements. The copies can ** be deleted (by being passed to their respective ...Delete() routines) ** without effecting the originals. ** ** The expression list, ID, and source lists return by sqlite3ExprListDup(), ** sqlite3IdListDup(), and sqlite3SrcListDup() can not be further expanded ** by subsequent calls to sqlite*ListAppend() routines. ** ** Any tables that the SrcList might point to are not duplicated. */ Expr *sqlite3ExprDup(sqlite *db, Expr *p){ Expr *pNew; if( p==0 ) return 0; pNew = sqlite3DbMallocRaw(db, sizeof(*p) ); if( pNew==0 ) return 0; memcpy(pNew, p, sizeof(*pNew)); if( p->token.z!=0 ){ pNew->token.z = (u8*)sqlite3DbStrNDup(db, (char*)p->token.z, p->token.n); pNew->token.dyn = 1; }else{ assert( pNew->token.z==0 ); } pNew->span.z = 0; pNew->pLeft = sqlite3ExprDup(db, p->pLeft); pNew->pRight = sqlite3ExprDup(db, p->pRight); pNew->pList = sqlite3ExprListDup(db, p->pList); pNew->pSelect = sqlite3SelectDup(db, p->pSelect); return pNew; } void sqlite3TokenCopy(sqlite3 *db, Token *pTo, Token *pFrom){ if( pTo->dyn ) sqlite3_free((char*)pTo->z); if( pFrom->z ){ pTo->n = pFrom->n; pTo->z = (u8*)sqlite3DbStrNDup(db, (char*)pFrom->z, pFrom->n); pTo->dyn = 1; }else{ pTo->z = 0; } } ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p){ ExprList *pNew; struct ExprList_item *pItem, *pOldItem; int i; if( p==0 ) return 0; pNew = sqlite3DbMallocRaw(db, sizeof(*pNew) ); if( pNew==0 ) return 0; pNew->nExpr = pNew->nAlloc = p->nExpr; pNew->a = pItem = sqlite3DbMallocRaw(db, p->nExpr*sizeof(p->a[0]) ); if( pItem==0 ){ sqlite3_free(pNew); return 0; } pOldItem = p->a; for(i=0; i<p->nExpr; i++, pItem++, pOldItem++){ Expr *pNewExpr, *pOldExpr; pItem->pExpr = pNewExpr = sqlite3ExprDup(db, pOldExpr = pOldItem->pExpr); if( pOldExpr->span.z!=0 && pNewExpr ){ /* Always make a copy of the span for top-level expressions in the ** expression list. The logic in SELECT processing that determines ** the names of columns in the result set needs this information */ sqlite3TokenCopy(db, &pNewExpr->span, &pOldExpr->span); } assert( pNewExpr==0 || pNewExpr->span.z!=0 || pOldExpr->span.z==0 || db->mallocFailed ); pItem->zName = sqlite3DbStrDup(db, pOldItem->zName); pItem->sortOrder = pOldItem->sortOrder; pItem->isAgg = pOldItem->isAgg; pItem->done = 0; } return pNew; } /* ** If cursors, triggers, views and subqueries are all omitted from ** the build, then none of the following routines, except for ** sqlite3SelectDup(), can be called. sqlite3SelectDup() is sometimes ** called with a NULL argument. */ #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) \ || !defined(SQLITE_OMIT_SUBQUERY) SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p){ SrcList *pNew; int i; int nByte; if( p==0 ) return 0; nByte = sizeof(*p) + (p->nSrc>0 ? sizeof(p->a[0]) * (p->nSrc-1) : 0); pNew = sqlite3DbMallocRaw(db, nByte ); if( pNew==0 ) return 0; pNew->nSrc = pNew->nAlloc = p->nSrc; for(i=0; i<p->nSrc; i++){ struct SrcList_item *pNewItem = &pNew->a[i]; struct SrcList_item *pOldItem = &p->a[i]; Table *pTab; pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase); pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName); pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias); pNewItem->jointype = pOldItem->jointype; pNewItem->iCursor = pOldItem->iCursor; pNewItem->isPopulated = pOldItem->isPopulated; pTab = pNewItem->pTab = pOldItem->pTab; if( pTab ){ pTab->nRef++; } pNewItem->pSelect = sqlite3SelectDup(db, pOldItem->pSelect); pNewItem->pOn = sqlite3ExprDup(db, pOldItem->pOn); pNewItem->pUsing = sqlite3IdListDup(db, pOldItem->pUsing); pNewItem->colUsed = pOldItem->colUsed; } return pNew; } IdList *sqlite3IdListDup(sqlite3 *db, IdList *p){ IdList *pNew; int i; if( p==0 ) return 0; pNew = sqlite3DbMallocRaw(db, sizeof(*pNew) ); if( pNew==0 ) return 0; pNew->nId = pNew->nAlloc = p->nId; pNew->a = sqlite3DbMallocRaw(db, p->nId*sizeof(p->a[0]) ); if( pNew->a==0 ){ sqlite3_free(pNew); return 0; } for(i=0; i<p->nId; i++){ struct IdList_item *pNewItem = &pNew->a[i]; struct IdList_item *pOldItem = &p->a[i]; pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName); pNewItem->idx = pOldItem->idx; } return pNew; } Select *sqlite3SelectDup(sqlite3 *db, Select *p){ Select *pNew; if( p==0 ) return 0; pNew = sqlite3DbMallocRaw(db, sizeof(*p) ); if( pNew==0 ) return 0; pNew->isDistinct = p->isDistinct; pNew->pEList = sqlite3ExprListDup(db, p->pEList); pNew->pSrc = sqlite3SrcListDup(db, p->pSrc); pNew->pWhere = sqlite3ExprDup(db, p->pWhere); pNew->pGroupBy = sqlite3ExprListDup(db, p->pGroupBy); pNew->pHaving = sqlite3ExprDup(db, p->pHaving); pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy); pNew->op = p->op; pNew->pPrior = sqlite3SelectDup(db, p->pPrior); pNew->pLimit = sqlite3ExprDup(db, p->pLimit); pNew->pOffset = sqlite3ExprDup(db, p->pOffset); pNew->iLimit = -1; pNew->iOffset = -1; pNew->isResolved = p->isResolved; pNew->isAgg = p->isAgg; pNew->usesEphm = 0; pNew->disallowOrderBy = 0; pNew->pRightmost = 0; pNew->addrOpenEphm[0] = -1; pNew->addrOpenEphm[1] = -1; pNew->addrOpenEphm[2] = -1; return pNew; } #else Select *sqlite3SelectDup(sqlite3 *db, Select *p){ assert( p==0 ); return 0; } #endif /* ** Add a new element to the end of an expression list. If pList is ** initially NULL, then create a new expression list. */ ExprList *sqlite3ExprListAppend( Parse *pParse, /* Parsing context */ ExprList *pList, /* List to which to append. Might be NULL */ Expr *pExpr, /* Expression to be appended */ Token *pName /* AS keyword for the expression */ ){ sqlite3 *db = pParse->db; if( pList==0 ){ pList = sqlite3DbMallocZero(db, sizeof(ExprList) ); if( pList==0 ){ goto no_mem; } assert( pList->nAlloc==0 ); } if( pList->nAlloc<=pList->nExpr ){ struct ExprList_item *a; int n = pList->nAlloc*2 + 4; a = sqlite3_realloc(pList->a, n*sizeof(pList->a[0])); if( a==0 ){ goto no_mem; } pList->a = a; pList->nAlloc = n; } assert( pList->a!=0 ); if( pExpr || pName ){ struct ExprList_item *pItem = &pList->a[pList->nExpr++]; memset(pItem, 0, sizeof(*pItem)); pItem->zName = sqlite3NameFromToken(db, pName); pItem->pExpr = pExpr; } return pList; no_mem: /* Avoid leaking memory if malloc has failed. */ db->mallocFailed = 1; sqlite3ExprDelete(pExpr); sqlite3ExprListDelete(pList); return 0; } /* ** If the expression list pEList contains more than iLimit elements, |
︙ | ︙ | |||
752 753 754 755 756 757 758 | int i; struct ExprList_item *pItem; if( pList==0 ) return; assert( pList->a!=0 || (pList->nExpr==0 && pList->nAlloc==0) ); assert( pList->nExpr<=pList->nAlloc ); for(pItem=pList->a, i=0; i<pList->nExpr; i++, pItem++){ sqlite3ExprDelete(pItem->pExpr); | | | | | 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 | int i; struct ExprList_item *pItem; if( pList==0 ) return; assert( pList->a!=0 || (pList->nExpr==0 && pList->nAlloc==0) ); assert( pList->nExpr<=pList->nAlloc ); for(pItem=pList->a, i=0; i<pList->nExpr; i++, pItem++){ sqlite3ExprDelete(pItem->pExpr); sqlite3_free(pItem->zName); } sqlite3_free(pList->a); sqlite3_free(pList); } /* ** Walk an expression tree. Call xFunc for each node visited. ** ** The return value from xFunc determines whether the tree walk continues. ** 0 means continue walking the tree. 1 means do not walk children |
︙ | ︙ | |||
992 993 994 995 996 997 998 | int cntTab = 0; /* Number of matching table names */ sqlite3 *db = pParse->db; /* The database */ struct SrcList_item *pItem; /* Use for looping over pSrcList items */ struct SrcList_item *pMatch = 0; /* The matching pSrcList item */ NameContext *pTopNC = pNC; /* First namecontext in the list */ assert( pColumnToken && pColumnToken->z ); /* The Z in X.Y.Z cannot be NULL */ | | | | | | 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 | int cntTab = 0; /* Number of matching table names */ sqlite3 *db = pParse->db; /* The database */ struct SrcList_item *pItem; /* Use for looping over pSrcList items */ struct SrcList_item *pMatch = 0; /* The matching pSrcList item */ NameContext *pTopNC = pNC; /* First namecontext in the list */ assert( pColumnToken && pColumnToken->z ); /* The Z in X.Y.Z cannot be NULL */ zDb = sqlite3NameFromToken(db, pDbToken); zTab = sqlite3NameFromToken(db, pTableToken); zCol = sqlite3NameFromToken(db, pColumnToken); if( db->mallocFailed ){ goto lookupname_end; } pExpr->iTable = -1; while( pNC && cnt==0 ){ ExprList *pEList; SrcList *pSrcList = pNC->pSrcList; |
︙ | ︙ | |||
1143 1144 1145 1146 1147 1148 1149 | Expr *pDup, *pOrig; assert( pExpr->pLeft==0 && pExpr->pRight==0 ); assert( pExpr->pList==0 ); assert( pExpr->pSelect==0 ); pOrig = pEList->a[j].pExpr; if( !pNC->allowAgg && ExprHasProperty(pOrig, EP_Agg) ){ sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs); | | | | | | 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 | Expr *pDup, *pOrig; assert( pExpr->pLeft==0 && pExpr->pRight==0 ); assert( pExpr->pList==0 ); assert( pExpr->pSelect==0 ); pOrig = pEList->a[j].pExpr; if( !pNC->allowAgg && ExprHasProperty(pOrig, EP_Agg) ){ sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs); sqlite3_free(zCol); return 2; } pDup = sqlite3ExprDup(pOrig); if( pExpr->flags & EP_ExpCollate ){ pDup->pColl = pExpr->pColl; pDup->flags |= EP_ExpCollate; } if( pExpr->span.dyn ) sqlite3_free((char*)pExpr->span.z); if( pExpr->token.dyn ) sqlite3_free((char*)pExpr->token.z); memcpy(pExpr, pDup, sizeof(*pExpr)); sqlite3_free(pDup); cnt = 1; pMatch = 0; assert( zTab==0 && zDb==0 ); goto lookupname_end_2; } } } |
︙ | ︙ | |||
1182 1183 1184 1185 1186 1187 1188 | ** case, we need to return right away and not make any changes to ** pExpr. ** ** Because no reference was made to outer contexts, the pNC->nRef ** fields are not changed in any context. */ if( cnt==0 && zTab==0 && pColumnToken->z[0]=='"' ){ | | | | | 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 | ** case, we need to return right away and not make any changes to ** pExpr. ** ** Because no reference was made to outer contexts, the pNC->nRef ** fields are not changed in any context. */ if( cnt==0 && zTab==0 && pColumnToken->z[0]=='"' ){ sqlite3_free(zCol); return 0; } /* ** cnt==0 means there was not match. cnt>1 means there were two or ** more matches. Either way, we have an error. */ if( cnt!=1 ){ char *z = 0; char *zErr; zErr = cnt==0 ? "no such column: %s" : "ambiguous column name: %s"; if( zDb ){ sqlite3SetString(&z, zDb, ".", zTab, ".", zCol, (char*)0); }else if( zTab ){ sqlite3SetString(&z, zTab, ".", zCol, (char*)0); }else{ z = sqlite3StrDup(zCol); } sqlite3ErrorMsg(pParse, zErr, z); sqlite3_free(z); pTopNC->nErr++; } /* If a column from a table in pSrcList is referenced, then record ** this fact in the pSrcList.a[].colUsed bitmask. Column 0 causes ** bit 0 to be set. Column 1 sets bit 1. And so forth. If the ** column number is greater than the number of bits in the bitmask |
︙ | ︙ | |||
1224 1225 1226 1227 1228 1229 1230 | assert( pMatch->iCursor==pExpr->iTable ); pMatch->colUsed |= ((Bitmask)1)<<n; } lookupname_end: /* Clean up and return */ | | | | | 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 | assert( pMatch->iCursor==pExpr->iTable ); pMatch->colUsed |= ((Bitmask)1)<<n; } lookupname_end: /* Clean up and return */ sqlite3_free(zDb); sqlite3_free(zTab); sqlite3ExprDelete(pExpr->pLeft); pExpr->pLeft = 0; sqlite3ExprDelete(pExpr->pRight); pExpr->pRight = 0; pExpr->op = TK_COLUMN; lookupname_end_2: sqlite3_free(zCol); if( cnt==1 ){ assert( pNC!=0 ); sqlite3AuthRead(pParse, pExpr, pNC->pSrcList); if( pMatch && !pMatch->pSelect ){ pExpr->pTab = pMatch->pTab; } /* Increment the nRef value on all name contexts from TopNC up to |
︙ | ︙ | |||
1523 1524 1525 1526 1527 1528 1529 | ** If all of the above are false, then we can run this code just once ** save the results, and reuse the same result on subsequent invocations. */ if( !ExprHasAnyProperty(pExpr, EP_VarSelect) && !pParse->trigStack ){ int mem = pParse->nMem++; sqlite3VdbeAddOp(v, OP_MemLoad, mem, 0); testAddr = sqlite3VdbeAddOp(v, OP_If, 0, 0); | | | 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 | ** If all of the above are false, then we can run this code just once ** save the results, and reuse the same result on subsequent invocations. */ if( !ExprHasAnyProperty(pExpr, EP_VarSelect) && !pParse->trigStack ){ int mem = pParse->nMem++; sqlite3VdbeAddOp(v, OP_MemLoad, mem, 0); testAddr = sqlite3VdbeAddOp(v, OP_If, 0, 0); assert( testAddr>0 || pParse->db->mallocFailed ); sqlite3VdbeAddOp(v, OP_MemInt, 1, mem); } switch( pExpr->op ){ case TK_IN: { char affinity; KeyInfo keyInfo; |
︙ | ︙ | |||
1656 1657 1658 1659 1660 1661 1662 | #endif /* SQLITE_OMIT_SUBQUERY */ /* ** Generate an instruction that will put the integer describe by ** text z[0..n-1] on the stack. */ static void codeInteger(Vdbe *v, const char *z, int n){ | | | 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 | #endif /* SQLITE_OMIT_SUBQUERY */ /* ** Generate an instruction that will put the integer describe by ** text z[0..n-1] on the stack. */ static void codeInteger(Vdbe *v, const char *z, int n){ assert( z || v==0 || sqlite3DbOfVdbe(v)->mallocFailed ); if( z ){ int i; if( sqlite3GetInt32(z, &i) ){ sqlite3VdbeAddOp(v, OP_Integer, i, 0); }else if( sqlite3FitsIn64Bits(z) ){ sqlite3VdbeOp3(v, OP_Int64, 0, 0, z, n); }else{ |
︙ | ︙ | |||
1856 1857 1858 1859 1860 1861 1862 | Token *p = &pLeft->token; char *z = sqlite3MPrintf("-%.*s", p->n, p->z); if( pLeft->op==TK_FLOAT ){ sqlite3VdbeOp3(v, OP_Real, 0, 0, z, p->n+1); }else{ codeInteger(v, z, p->n+1); } | | | 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 | Token *p = &pLeft->token; char *z = sqlite3MPrintf("-%.*s", p->n, p->z); if( pLeft->op==TK_FLOAT ){ sqlite3VdbeOp3(v, OP_Real, 0, 0, z, p->n+1); }else{ codeInteger(v, z, p->n+1); } sqlite3_free(z); break; } /* Fall through into TK_NOT */ } case TK_BITNOT: case TK_NOT: { assert( TK_BITNOT==OP_BitNot ); |
︙ | ︙ | |||
1902 1903 1904 1905 1906 1907 1908 | ExprList *pList = pExpr->pList; int nExpr = pList ? pList->nExpr : 0; FuncDef *pDef; int nId; const char *zId; int constMask = 0; int i; | > | > | | | 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 | ExprList *pList = pExpr->pList; int nExpr = pList ? pList->nExpr : 0; FuncDef *pDef; int nId; const char *zId; int constMask = 0; int i; sqlite3 *db = pParse->db; u8 enc = ENC(db); CollSeq *pColl = 0; zId = (char*)pExpr->token.z; nId = pExpr->token.n; pDef = sqlite3FindFunction(pParse->db, zId, nId, nExpr, enc, 0); assert( pDef!=0 ); nExpr = sqlite3ExprCodeExprList(pParse, pList); #ifndef SQLITE_OMIT_VIRTUALTABLE /* Possibly overload the function if the first argument is ** a virtual table column. ** ** For infix functions (LIKE, GLOB, REGEXP, and MATCH) use the ** second argument, not the first, as the argument to test to ** see if it is a column in a virtual table. This is done because ** the left operand of infix functions (the operand we want to ** control overloading) ends up as the second argument to the ** function. The expression "A glob B" is equivalent to ** "glob(B,A). We want to use the A in "A glob B" to test ** for function overloading. But we use the B term in "glob(B,A)". */ if( nExpr>=2 && (pExpr->flags & EP_InfixFunc) ){ pDef = sqlite3VtabOverloadFunction(db, pDef, nExpr, pList->a[1].pExpr); }else if( nExpr>0 ){ pDef = sqlite3VtabOverloadFunction(db, pDef, nExpr, pList->a[0].pExpr); } #endif for(i=0; i<nExpr && i<32; i++){ if( sqlite3ExprIsConstant(pList->a[i].pExpr) ){ constMask |= (1<<i); } if( pDef->needCollSeq && !pColl ){ |
︙ | ︙ | |||
2385 2386 2387 2388 2389 2390 2391 | } /* ** Add a new element to the pAggInfo->aCol[] array. Return the index of ** the new element. Return a negative number if malloc fails. */ | | > | > | 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 | } /* ** Add a new element to the pAggInfo->aCol[] array. Return the index of ** the new element. Return a negative number if malloc fails. */ static int addAggInfoColumn(sqlite3 *db, AggInfo *pInfo){ int i; pInfo->aCol = sqlite3ArrayAllocate( db, pInfo->aCol, sizeof(pInfo->aCol[0]), 3, &pInfo->nColumn, &pInfo->nColumnAlloc, &i ); return i; } /* ** Add a new element to the pAggInfo->aFunc[] array. Return the index of ** the new element. Return a negative number if malloc fails. */ static int addAggInfoFunc(sqlite3 *db, AggInfo *pInfo){ int i; pInfo->aFunc = sqlite3ArrayAllocate( db, pInfo->aFunc, sizeof(pInfo->aFunc[0]), 3, &pInfo->nFunc, &pInfo->nFuncAlloc, &i ); |
︙ | ︙ |
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.164 2007/08/16 04:30:40 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* #include <math.h> */ #include <stdlib.h> #include <assert.h> #include "vdbeInt.h" |
︙ | ︙ | |||
330 331 332 333 334 335 336 | if( n<1 ){ n = 1; } if( n>SQLITE_MAX_LENGTH ){ sqlite3_result_error_toobig(context); return; } | | | | 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 | if( n<1 ){ n = 1; } if( n>SQLITE_MAX_LENGTH ){ sqlite3_result_error_toobig(context); return; } p = sqlite3_malloc(n); if( p ){ sqlite3Randomness(n, p); sqlite3_result_blob(context, (char*)p, n, sqlite3_free); } } /* ** Implementation of the last_insert_rowid() SQL function. The return ** value is the same as the sqlite3_last_insert_rowid() API function. */ |
︙ | ︙ | |||
663 664 665 666 667 668 669 | int nBlob = sqlite3_value_bytes(argv[0]); assert( zBlob==sqlite3_value_blob(argv[0]) ); /* No encoding change */ if( 2*nBlob+4>SQLITE_MAX_LENGTH ){ sqlite3_result_error_toobig(context); return; } | | | | | | 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 | int nBlob = sqlite3_value_bytes(argv[0]); assert( zBlob==sqlite3_value_blob(argv[0]) ); /* No encoding change */ if( 2*nBlob+4>SQLITE_MAX_LENGTH ){ sqlite3_result_error_toobig(context); return; } zText = (char *)sqlite3_malloc((2*nBlob)+4); if( !zText ){ sqlite3_result_error(context, "out of memory", -1); }else{ int i; for(i=0; i<nBlob; i++){ zText[(i*2)+2] = hexdigits[(zBlob[i]>>4)&0x0F]; zText[(i*2)+3] = hexdigits[(zBlob[i])&0x0F]; } zText[(nBlob*2)+2] = '\''; zText[(nBlob*2)+3] = '\0'; zText[0] = 'X'; zText[1] = '\''; sqlite3_result_text(context, zText, -1, SQLITE_TRANSIENT); sqlite3_free(zText); } break; } case SQLITE_TEXT: { int i,j; u64 n; const unsigned char *zArg = sqlite3_value_text(argv[0]); char *z; if( zArg==0 ) return; for(i=0, n=0; zArg[i]; i++){ if( zArg[i]=='\'' ) n++; } if( i+n+3>SQLITE_MAX_LENGTH ){ sqlite3_result_error_toobig(context); return; } z = sqlite3_malloc( i+n+3 ); if( z==0 ) return; z[0] = '\''; for(i=0, j=1; zArg[i]; i++){ z[j++] = zArg[i]; if( zArg[i]=='\'' ){ z[j++] = '\''; } } z[j++] = '\''; z[j] = 0; sqlite3_result_text(context, z, j, SQLITE_TRANSIENT); sqlite3_free(z); } } } /* ** The hex() function. Interpret the argument as a blob. Return ** a hexadecimal rendering as text. |
︙ | ︙ | |||
1045 1046 1047 1048 1049 1050 1051 | ** WARNING: Not threadsafe. */ static int test_destructor_count_var = 0; static void destructor(void *p){ char *zVal = (char *)p; assert(zVal); zVal--; | | | 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 | ** WARNING: Not threadsafe. */ static int test_destructor_count_var = 0; static void destructor(void *p){ char *zVal = (char *)p; assert(zVal); zVal--; sqlite3_free(zVal); test_destructor_count_var--; } static void test_destructor( sqlite3_context *pCtx, int nArg, sqlite3_value **argv ){ |
︙ | ︙ | |||
1098 1099 1100 1101 1102 1103 1104 | ** The test_auxdata() SQL function attempts to register each of its arguments ** as auxiliary data. If there are no prior registrations of aux data for ** that argument (meaning the argument is not a constant or this is its first ** call) then the result for that argument is 0. If there is a prior ** registration, the result for that argument is 1. The overall result ** is the individual argument results separated by spaces. */ | | | 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 | ** The test_auxdata() SQL function attempts to register each of its arguments ** as auxiliary data. If there are no prior registrations of aux data for ** that argument (meaning the argument is not a constant or this is its first ** call) then the result for that argument is 0. If there is a prior ** registration, the result for that argument is 1. The overall result ** is the individual argument results separated by spaces. */ static void free_test_auxdata(void *p) {sqlite3_free(p);} static void test_auxdata( sqlite3_context *pCtx, int nArg, sqlite3_value **argv ){ int i; char *zRet = sqliteMalloc(nArg*2); |
︙ | ︙ | |||
1120 1121 1122 1123 1124 1125 1126 | if( strcmp(zAux, z) ){ free_test_auxdata((void *)zRet); sqlite3_result_error(pCtx, "Auxilary data corruption", -1); return; } }else{ zRet[i*2] = '0'; | | | 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 | if( strcmp(zAux, z) ){ free_test_auxdata((void *)zRet); sqlite3_result_error(pCtx, "Auxilary data corruption", -1); return; } }else{ zRet[i*2] = '0'; zAux = sqlite3StrDup(z); sqlite3_set_auxdata(pCtx, i, zAux, free_test_auxdata); } zRet[i*2+1] = ' '; } } sqlite3_result_text(pCtx, zRet, 2*nArg-1, free_test_auxdata); } |
︙ | ︙ |
Changes to src/hash.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 is the implementation of generic hash-tables ** used 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 is the implementation of generic hash-tables ** used in SQLite. ** ** $Id: hash.c,v 1.20 2007/08/16 04:30:40 drh Exp $ */ #include "sqliteInt.h" #include <assert.h> /* Turn bulk memory into a hash table object by initializing the ** fields of the Hash structure. ** |
︙ | ︙ | |||
37 38 39 40 41 42 43 | if( keyClass==SQLITE_HASH_POINTER || keyClass==SQLITE_HASH_INT ) copyKey = 0; #endif pNew->copyKey = copyKey; pNew->first = 0; pNew->count = 0; pNew->htsize = 0; pNew->ht = 0; | < < | | | | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | if( keyClass==SQLITE_HASH_POINTER || keyClass==SQLITE_HASH_INT ) copyKey = 0; #endif pNew->copyKey = copyKey; pNew->first = 0; pNew->count = 0; pNew->htsize = 0; pNew->ht = 0; } /* Remove all entries from a hash table. Reclaim all memory. ** Call this routine to delete a hash table or to reset a hash table ** to the empty state. */ void sqlite3HashClear(Hash *pH){ HashElem *elem; /* For looping over all elements of the table */ assert( pH!=0 ); elem = pH->first; pH->first = 0; if( pH->ht ) sqlite3_free(pH->ht); pH->ht = 0; pH->htsize = 0; while( elem ){ HashElem *next_elem = elem->next; if( pH->copyKey && elem->pKey ){ sqlite3_free(elem->pKey); } sqlite3_free(elem); elem = next_elem; } pH->count = 0; } #if 0 /* NOT USED */ /* |
︙ | ︙ | |||
212 213 214 215 216 217 218 | pEntry->count++; pEntry->chain = pNew; } /* Resize the hash table so that it cantains "new_size" buckets. ** "new_size" must be a power of 2. The hash table might fail | | | | | 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 | pEntry->count++; pEntry->chain = pNew; } /* Resize the hash table so that it cantains "new_size" buckets. ** "new_size" must be a power of 2. The hash table might fail ** to resize if sqlite3_malloc() fails. */ static void rehash(Hash *pH, int new_size){ struct _ht *new_ht; /* The new hash table */ HashElem *elem, *next_elem; /* For looping over existing elements */ int (*xHash)(const void*,int); /* The hash function */ assert( (new_size & (new_size-1))==0 ); new_ht = (struct _ht *)sqlite3_malloc( new_size*sizeof(struct _ht) ); if( new_ht==0 ) return; if( pH->ht ) sqlite3_free(pH->ht); pH->ht = new_ht; pH->htsize = new_size; xHash = hashFunction(pH->keyClass); for(elem=pH->first, pH->first=0; elem; elem = next_elem){ int h = (*xHash)(elem->pKey, elem->nKey) & (new_size-1); next_elem = elem->next; insertElement(pH, &new_ht[h], elem); |
︙ | ︙ | |||
288 289 290 291 292 293 294 | pEntry->chain = elem->next; } pEntry->count--; if( pEntry->count<=0 ){ pEntry->chain = 0; } if( pH->copyKey ){ | | | | 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 | pEntry->chain = elem->next; } pEntry->count--; if( pEntry->count<=0 ){ pEntry->chain = 0; } if( pH->copyKey ){ sqlite3_free(elem->pKey); } sqlite3_free( elem ); pH->count--; if( pH->count<=0 ){ assert( pH->first==0 ); assert( pH->count==0 ); sqlite3HashClear(pH); } } |
︙ | ︙ | |||
356 357 358 359 360 361 362 | removeElementGivenHash(pH,elem,h); }else{ elem->data = data; } return old_data; } if( data==0 ) return 0; | | | | | | | 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 386 387 388 389 390 391 392 393 394 395 | removeElementGivenHash(pH,elem,h); }else{ elem->data = data; } return old_data; } if( data==0 ) return 0; new_elem = (HashElem*)sqlite3_malloc( sizeof(HashElem) ); if( new_elem==0 ) return data; if( pH->copyKey && pKey!=0 ){ new_elem->pKey = sqlite3_malloc( nKey ); if( new_elem->pKey==0 ){ sqlite3_free(new_elem); return data; } memcpy((void*)new_elem->pKey, pKey, nKey); }else{ new_elem->pKey = (void*)pKey; } new_elem->nKey = nKey; pH->count++; if( pH->htsize==0 ){ rehash(pH,8); if( pH->htsize==0 ){ pH->count = 0; if( pH->copyKey ){ sqlite3_free(new_elem->pKey); } sqlite3_free(new_elem); return data; } } if( pH->count > pH->htsize ){ rehash(pH,pH->htsize*2); } assert( pH->htsize>0 ); assert( (pH->htsize & (pH->htsize-1))==0 ); h = hraw & (pH->htsize-1); insertElement(pH, &pH->ht[h], new_elem); new_elem->data = data; return 0; } |
Changes to src/hash.h.
︙ | ︙ | |||
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 is the header file for the generic hash-table implemenation ** used in SQLite. ** | | < < < > | 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 36 37 38 39 40 41 42 43 44 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This is the header file for the generic hash-table implemenation ** used in SQLite. ** ** $Id: hash.h,v 1.10 2007/08/16 04:30:40 drh Exp $ */ #ifndef _SQLITE_HASH_H_ #define _SQLITE_HASH_H_ /* Forward declarations of structures. */ typedef struct Hash Hash; typedef struct HashElem HashElem; /* A complete hash table is an instance of the following structure. ** The internals of this structure are intended to be opaque -- client ** code should not attempt to access or modify the fields of this structure ** directly. Change this structure only by using the routines below. ** However, many of the "procedures" and "functions" for modifying and ** accessing this structure are really macros, so we can't really make ** this structure opaque. */ struct Hash { char keyClass; /* SQLITE_HASH_INT, _POINTER, _STRING, _BINARY */ char copyKey; /* True if copy of key made on insert */ int count; /* Number of entries in this table */ int htsize; /* Number of buckets in the hash table */ HashElem *first; /* The first element of the array */ struct _ht { /* the hash table */ int count; /* Number of entries with this hash */ HashElem *chain; /* Pointer to first entry with this hash */ } *ht; }; /* Each element in the hash table is an instance of the following |
︙ | ︙ |
Changes to src/insert.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 INSERT 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 INSERT statements in SQLite. ** ** $Id: insert.c,v 1.189 2007/08/16 04:30:40 drh Exp $ */ #include "sqliteInt.h" /* ** Set P3 of the most recently inserted opcode to a column affinity ** string for index pIdx. A column affinity string has one character ** for each column in the table, according to the affinity of the column: |
︙ | ︙ | |||
37 38 39 40 41 42 43 | ** ** The column affinity string will eventually be deleted by ** sqliteDeleteIndex() when the Index structure itself is cleaned ** up. */ int n; Table *pTab = pIdx->pTable; | > | | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | ** ** The column affinity string will eventually be deleted by ** sqliteDeleteIndex() when the Index structure itself is cleaned ** up. */ int n; Table *pTab = pIdx->pTable; sqlite3 *db = sqlite3DbOfVdbe(v); pIdx->zColAff = (char *)sqlite3DbMallocZero(db, pIdx->nColumn+1); if( !pIdx->zColAff ){ return; } for(n=0; n<pIdx->nColumn; n++){ pIdx->zColAff[n] = pTab->aCol[pIdx->aiColumn[n]].affinity; } pIdx->zColAff[pIdx->nColumn] = '\0'; |
︙ | ︙ | |||
75 76 77 78 79 80 81 82 | ** ** The column affinity string will eventually be deleted by ** sqlite3DeleteTable() when the Table structure itself is cleaned up. */ if( !pTab->zColAff ){ char *zColAff; int i; | > | | 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | ** ** The column affinity string will eventually be deleted by ** sqlite3DeleteTable() when the Table structure itself is cleaned up. */ if( !pTab->zColAff ){ char *zColAff; int i; sqlite3 *db = sqlite3DbOfVdbe(v); zColAff = (char *)sqlite3DbMallocZero(db, pTab->nCol+1); if( !zColAff ){ return; } for(i=0; i<pTab->nCol; i++){ zColAff[i] = pTab->aCol[i].affinity; } |
︙ | ︙ | |||
352 353 354 355 356 357 358 | int nHidden = 0; #ifndef SQLITE_OMIT_TRIGGER int isView; /* True if attempting to insert into a view */ int triggers_exist = 0; /* True if there are FOR EACH ROW triggers */ #endif | > | < | 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 | int nHidden = 0; #ifndef SQLITE_OMIT_TRIGGER int isView; /* True if attempting to insert into a view */ int triggers_exist = 0; /* True if there are FOR EACH ROW triggers */ #endif db = pParse->db; if( pParse->nErr || db->mallocFailed ){ goto insert_cleanup; } /* Locate the table into which we will be inserting new information. */ assert( pTabList->nSrc==1 ); zTab = pTabList->a[0].zName; if( zTab==0 ) goto insert_cleanup; pTab = sqlite3SrcListLookup(pParse, pTabList); |
︙ | ︙ | |||
458 459 460 461 462 463 464 | int rc, iInitCode; iInitCode = sqlite3VdbeAddOp(v, OP_Goto, 0, 0); iSelectLoop = sqlite3VdbeCurrentAddr(v); iInsertBlock = sqlite3VdbeMakeLabel(v); /* Resolve the expressions in the SELECT statement and execute it. */ rc = sqlite3Select(pParse, pSelect, SRT_Subroutine, iInsertBlock,0,0,0,0); | | | 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 | int rc, iInitCode; iInitCode = sqlite3VdbeAddOp(v, OP_Goto, 0, 0); iSelectLoop = sqlite3VdbeCurrentAddr(v); iInsertBlock = sqlite3VdbeMakeLabel(v); /* Resolve the expressions in the SELECT statement and execute it. */ rc = sqlite3Select(pParse, pSelect, SRT_Subroutine, iInsertBlock,0,0,0,0); if( rc || pParse->nErr || db->mallocFailed ){ goto insert_cleanup; } iCleanup = sqlite3VdbeMakeLabel(v); sqlite3VdbeAddOp(v, OP_Goto, 0, iCleanup); assert( pSelect->pEList ); nColumn = pSelect->pEList->nExpr; |
︙ | ︙ |
Changes to src/legacy.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: legacy.c,v 1.19 2007/08/16 04:30:40 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> /* |
︙ | ︙ | |||
62 63 64 65 66 67 68 | zSql = zLeftover; continue; } nCallback = 0; nCol = sqlite3_column_count(pStmt); | | | 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | zSql = zLeftover; continue; } nCallback = 0; nCol = sqlite3_column_count(pStmt); azCols = sqlite3DbMallocZero(db, 2*nCol*sizeof(const char *) + 1); if( azCols==0 ){ goto exec_out; } while( 1 ){ int i; rc = sqlite3_step(pStmt); |
︙ | ︙ | |||
104 105 106 107 108 109 110 | zSql = zLeftover; while( isspace((unsigned char)zSql[0]) ) zSql++; } break; } } | | | | 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | zSql = zLeftover; while( isspace((unsigned char)zSql[0]) ) zSql++; } break; } } sqlite3_free(azCols); azCols = 0; } exec_out: if( pStmt ) sqlite3_finalize(pStmt); if( azCols ) sqlite3_free(azCols); rc = sqlite3ApiExit(0, rc); if( rc!=SQLITE_OK && rc==sqlite3_errcode(db) && pzErrMsg ){ int nErrMsg = 1 + strlen(sqlite3_errmsg(db)); *pzErrMsg = sqlite3_malloc(nErrMsg); if( *pzErrMsg ){ memcpy(*pzErrMsg, sqlite3_errmsg(db), nErrMsg); |
︙ | ︙ |
Changes to src/loadext.c.
︙ | ︙ | |||
312 313 314 315 316 317 318 | sqlite3_free(zErrmsg); sqlite3OsDlclose(handle); return SQLITE_ERROR; } /* Append the new shared library handle to the db->aExtension array. */ db->nExtension++; | | | | | 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 | sqlite3_free(zErrmsg); sqlite3OsDlclose(handle); return SQLITE_ERROR; } /* Append the new shared library handle to the db->aExtension array. */ db->nExtension++; aHandle = sqlite3DbMallocZero(db, sizeof(handle)*db->nExtension); if( aHandle==0 ){ return SQLITE_NOMEM; } if( db->nExtension>0 ){ memcpy(aHandle, db->aExtension, sizeof(handle)*(db->nExtension-1)); } sqlite3_free(db->aExtension); db->aExtension = aHandle; db->aExtension[db->nExtension-1] = handle; return SQLITE_OK; } /* ** Call this routine when the database connection is closing in order ** to clean up loaded extensions */ void sqlite3CloseExtensions(sqlite3 *db){ int i; for(i=0; i<db->nExtension; i++){ sqlite3OsDlclose(db->aExtension[i]); } sqlite3_free(db->aExtension); } /* ** Enable or disable extension loading. Extension loading is disabled by ** default so as not to open security holes in older applications. */ int sqlite3_enable_load_extension(sqlite3 *db, int onoff){ |
︙ | ︙ | |||
374 375 376 377 378 379 380 | int rc = SQLITE_OK; sqlite3OsEnterMutex(); for(i=0; i<nAutoExtension; i++){ if( aAutoExtension[i]==xInit ) break; } if( i==nAutoExtension ){ nAutoExtension++; | | | | 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 | int rc = SQLITE_OK; sqlite3OsEnterMutex(); for(i=0; i<nAutoExtension; i++){ if( aAutoExtension[i]==xInit ) break; } if( i==nAutoExtension ){ nAutoExtension++; aAutoExtension = sqlite3_realloc( aAutoExtension, nAutoExtension*sizeof(aAutoExtension[0]) ); if( aAutoExtension==0 ){ nAutoExtension = 0; rc = SQLITE_NOMEM; }else{ aAutoExtension[nAutoExtension-1] = xInit; } } sqlite3OsLeaveMutex(); assert( (rc&0xff)==rc ); return rc; } /* ** Reset the automatic extension loading mechanism. */ void sqlite3_reset_auto_extension(void){ sqlite3OsEnterMutex(); sqlite3_free(aAutoExtension); aAutoExtension = 0; nAutoExtension = 0; sqlite3OsLeaveMutex(); } /* ** Load all automatic extensions. |
︙ | ︙ |
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.380 2007/08/16 04:30:40 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> /* ** The version of the library |
︙ | ︙ | |||
172 173 174 175 176 177 178 | sqlite3ResetInternalSchema(db, 0); assert( db->nDb<=2 ); assert( db->aDb==db->aDbStatic ); for(i=sqliteHashFirst(&db->aFunc); i; i=sqliteHashNext(i)){ FuncDef *pFunc, *pNext; for(pFunc = (FuncDef*)sqliteHashData(i); pFunc; pFunc=pNext){ pNext = pFunc->pNext; | | | | | | | 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 | sqlite3ResetInternalSchema(db, 0); assert( db->nDb<=2 ); assert( db->aDb==db->aDbStatic ); for(i=sqliteHashFirst(&db->aFunc); i; i=sqliteHashNext(i)){ FuncDef *pFunc, *pNext; for(pFunc = (FuncDef*)sqliteHashData(i); pFunc; pFunc=pNext){ pNext = pFunc->pNext; sqlite3_free(pFunc); } } for(i=sqliteHashFirst(&db->aCollSeq); i; i=sqliteHashNext(i)){ CollSeq *pColl = (CollSeq *)sqliteHashData(i); /* Invoke any destructors registered for collation sequence user data. */ for(j=0; j<3; j++){ if( pColl[j].xDel ){ pColl[j].xDel(pColl[j].pUser); } } sqlite3_free(pColl); } sqlite3HashClear(&db->aCollSeq); #ifndef SQLITE_OMIT_VIRTUALTABLE for(i=sqliteHashFirst(&db->aModule); i; i=sqliteHashNext(i)){ Module *pMod = (Module *)sqliteHashData(i); if( pMod->xDestroy ){ pMod->xDestroy(pMod->pAux); } sqlite3_free(pMod); } sqlite3HashClear(&db->aModule); #endif sqlite3HashClear(&db->aFunc); sqlite3Error(db, SQLITE_OK, 0); /* Deallocates any cached error strings. */ if( db->pErr ){ sqlite3ValueFree(db->pErr); } sqlite3CloseExtensions(db); db->magic = SQLITE_MAGIC_ERROR; /* The temp-database schema is allocated differently from the other schema ** objects (using sqliteMalloc() directly, instead of sqlite3BtreeSchema()). ** So it needs to be freed here. Todo: Why not roll the temp schema into ** the same sqliteMalloc() as the one that allocates the database ** structure? */ sqlite3_free(db->aDb[1].pSchema); sqlite3_free(db); sqlite3ReleaseThreadData(); return SQLITE_OK; } /* ** Rollback all database files. */ |
︙ | ︙ | |||
484 485 486 487 488 489 490 | ** operation to continue but invalidate all precompiled statements. */ p = sqlite3FindFunction(db, zFunctionName, nName, nArg, enc, 0); if( p && p->iPrefEnc==enc && p->nArg==nArg ){ if( db->activeVdbeCnt ){ sqlite3Error(db, SQLITE_BUSY, "Unable to delete/modify user-function due to active statements"); | | | 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 | ** operation to continue but invalidate all precompiled statements. */ p = sqlite3FindFunction(db, zFunctionName, nName, nArg, enc, 0); if( p && p->iPrefEnc==enc && p->nArg==nArg ){ if( db->activeVdbeCnt ){ sqlite3Error(db, SQLITE_BUSY, "Unable to delete/modify user-function due to active statements"); assert( !db->mallocFailed ); return SQLITE_BUSY; }else{ sqlite3ExpirePreparedStatements(db); } } p = sqlite3FindFunction(db, zFunctionName, nName, nArg, enc, 1); |
︙ | ︙ | |||
517 518 519 520 521 522 523 | int enc, void *p, void (*xFunc)(sqlite3_context*,int,sqlite3_value **), void (*xStep)(sqlite3_context*,int,sqlite3_value **), void (*xFinal)(sqlite3_context*) ){ int rc; | | | | | 517 518 519 520 521 522 523 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 | int enc, void *p, void (*xFunc)(sqlite3_context*,int,sqlite3_value **), void (*xStep)(sqlite3_context*,int,sqlite3_value **), void (*xFinal)(sqlite3_context*) ){ int rc; assert( !db->mallocFailed ); rc = sqlite3CreateFunc(db, zFunctionName, nArg, enc, p, xFunc, xStep, xFinal); return sqlite3ApiExit(db, rc); } #ifndef SQLITE_OMIT_UTF16 int sqlite3_create_function16( sqlite3 *db, const void *zFunctionName, int nArg, int eTextRep, void *p, void (*xFunc)(sqlite3_context*,int,sqlite3_value**), void (*xStep)(sqlite3_context*,int,sqlite3_value**), void (*xFinal)(sqlite3_context*) ){ int rc; char *zFunc8; assert( !db->mallocFailed ); zFunc8 = sqlite3Utf16to8(zFunctionName, -1); rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xFunc, xStep, xFinal); sqlite3_free(zFunc8); return sqlite3ApiExit(db, rc); } #endif /* |
︙ | ︙ | |||
727 728 729 730 731 732 733 | /* ** Return UTF-8 encoded English language explanation of the most recent ** error. */ const char *sqlite3_errmsg(sqlite3 *db){ const char *z; | < > | 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 | /* ** Return UTF-8 encoded English language explanation of the most recent ** error. */ const char *sqlite3_errmsg(sqlite3 *db){ const char *z; if( !db ){ return sqlite3ErrStr(SQLITE_NOMEM); } assert( !db->mallocFailed ); if( sqlite3SafetyCheck(db) || db->errCode==SQLITE_MISUSE ){ return sqlite3ErrStr(SQLITE_MISUSE); } z = (char*)sqlite3_value_text(db->pErr); if( z==0 ){ z = sqlite3ErrStr(db->errCode); } |
︙ | ︙ | |||
767 768 769 770 771 772 773 | 0, 'c', 0, 'a', 0, 'l', 0, 'l', 0, 'e', 0, 'd', 0, ' ', 0, 'o', 0, 'u', 0, 't', 0, ' ', 0, 'o', 0, 'f', 0, ' ', 0, 's', 0, 'e', 0, 'q', 0, 'u', 0, 'e', 0, 'n', 0, 'c', 0, 'e', 0, 0, 0 }; const void *z; | | | 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 | 0, 'c', 0, 'a', 0, 'l', 0, 'l', 0, 'e', 0, 'd', 0, ' ', 0, 'o', 0, 'u', 0, 't', 0, ' ', 0, 'o', 0, 'f', 0, ' ', 0, 's', 0, 'e', 0, 'q', 0, 'u', 0, 'e', 0, 'n', 0, 'c', 0, 'e', 0, 0, 0 }; const void *z; assert( !db->mallocFailed ); if( !db ){ return (void *)(&outOfMemBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]); } if( sqlite3SafetyCheck(db) || db->errCode==SQLITE_MISUSE ){ return (void *)(&misuseBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]); } z = sqlite3_value_text16(db->pErr); |
︙ | ︙ | |||
790 791 792 793 794 795 796 | #endif /* SQLITE_OMIT_UTF16 */ /* ** Return the most recent error code generated by an SQLite routine. If NULL is ** passed to this function, we assume a malloc() failed during sqlite3_open(). */ int sqlite3_errcode(sqlite3 *db){ | | | 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 | #endif /* SQLITE_OMIT_UTF16 */ /* ** Return the most recent error code generated by an SQLite routine. If NULL is ** passed to this function, we assume a malloc() failed during sqlite3_open(). */ int sqlite3_errcode(sqlite3 *db){ if( !db || db->mallocFailed ){ return SQLITE_NOMEM; } if( sqlite3SafetyCheck(db) ){ return SQLITE_MISUSE; } return db->errCode & db->errMask; } |
︙ | ︙ | |||
891 892 893 894 895 896 897 | const char *zFilename, /* Database filename UTF-8 encoded */ sqlite3 **ppDb /* OUT: Returned database handle */ ){ sqlite3 *db; int rc; CollSeq *pColl; | < < | | 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 | const char *zFilename, /* Database filename UTF-8 encoded */ sqlite3 **ppDb /* OUT: Returned database handle */ ){ sqlite3 *db; int rc; CollSeq *pColl; /* Allocate the sqlite data structure */ db = sqlite3MallocZero( sizeof(sqlite3) ); if( db==0 ) goto opendb_out; db->errMask = 0xff; db->priorNewRowid = 0; db->magic = SQLITE_MAGIC_BUSY; db->nDb = 2; db->aDb = db->aDbStatic; db->autoCommit = 1; |
︙ | ︙ | |||
925 926 927 928 929 930 931 | ** conversions. The only error that can occur here is a malloc() failure. */ if( createCollation(db, "BINARY", SQLITE_UTF8, 0, binCollFunc, 0) || createCollation(db, "BINARY", SQLITE_UTF16BE, 0, binCollFunc, 0) || createCollation(db, "BINARY", SQLITE_UTF16LE, 0, binCollFunc, 0) || (db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 6, 0))==0 ){ | | | 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 | ** conversions. The only error that can occur here is a malloc() failure. */ if( createCollation(db, "BINARY", SQLITE_UTF8, 0, binCollFunc, 0) || createCollation(db, "BINARY", SQLITE_UTF16BE, 0, binCollFunc, 0) || createCollation(db, "BINARY", SQLITE_UTF16LE, 0, binCollFunc, 0) || (db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 6, 0))==0 ){ assert( db->mallocFailed ); db->magic = SQLITE_MAGIC_CLOSED; goto opendb_out; } /* Also add a UTF-8 case-insensitive collation sequence. */ createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0); |
︙ | ︙ | |||
948 949 950 951 952 953 954 | rc = sqlite3BtreeFactory(db, zFilename, 0, SQLITE_DEFAULT_CACHE_SIZE, &db->aDb[0].pBt); if( rc!=SQLITE_OK ){ sqlite3Error(db, rc, 0); db->magic = SQLITE_MAGIC_CLOSED; goto opendb_out; } | | | | | | | | 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 | rc = sqlite3BtreeFactory(db, zFilename, 0, SQLITE_DEFAULT_CACHE_SIZE, &db->aDb[0].pBt); if( rc!=SQLITE_OK ){ sqlite3Error(db, rc, 0); db->magic = SQLITE_MAGIC_CLOSED; goto opendb_out; } db->aDb[0].pSchema = sqlite3SchemaGet(db, db->aDb[0].pBt); db->aDb[1].pSchema = sqlite3SchemaGet(db, 0); /* The default safety_level for the main database is 'full'; for the temp ** database it is 'NONE'. This matches the pager layer defaults. */ db->aDb[0].zName = "main"; db->aDb[0].safety_level = 3; #ifndef SQLITE_OMIT_TEMPDB db->aDb[1].zName = "temp"; db->aDb[1].safety_level = 1; #endif db->magic = SQLITE_MAGIC_OPEN; if( db->mallocFailed ){ goto opendb_out; } /* Register all built-in functions, but do not attempt to read the ** database schema yet. This is delayed until the first time the database ** is accessed. */ sqlite3Error(db, SQLITE_OK, 0); sqlite3RegisterBuiltinFunctions(db); /* Load automatic extensions - extensions that have been registered ** using the sqlite3_automatic_extension() API. */ (void)sqlite3AutoLoadExtensions(db); if( sqlite3_errcode(db)!=SQLITE_OK ){ goto opendb_out; } #ifdef SQLITE_ENABLE_FTS1 if( !db->mallocFailed ){ extern int sqlite3Fts1Init(sqlite3*); rc = sqlite3Fts1Init(db); } #endif #ifdef SQLITE_ENABLE_FTS2 if( !db->mallocFailed && rc==SQLITE_OK ){ extern int sqlite3Fts2Init(sqlite3*); rc = sqlite3Fts2Init(db); } #endif #ifdef SQLITE_ENABLE_ICU if( !db->mallocFailed && rc==SQLITE_OK ){ extern int sqlite3IcuInit(sqlite3*); rc = sqlite3IcuInit(db); } #endif sqlite3Error(db, rc, 0); /* -DSQLITE_DEFAULT_LOCKING_MODE=1 makes EXCLUSIVE the default locking |
︙ | ︙ | |||
1117 1118 1119 1120 1121 1122 1123 | sqlite3* db, const char *zName, int enc, void* pCtx, int(*xCompare)(void*,int,const void*,int,const void*) ){ int rc; | | | | | | 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 | sqlite3* db, const char *zName, int enc, void* pCtx, int(*xCompare)(void*,int,const void*,int,const void*) ){ int rc; assert( !db->mallocFailed ); rc = createCollation(db, zName, enc, pCtx, xCompare, 0); return sqlite3ApiExit(db, rc); } /* ** Register a new collation sequence with the database handle db. */ int sqlite3_create_collation_v2( sqlite3* db, const char *zName, int enc, void* pCtx, int(*xCompare)(void*,int,const void*,int,const void*), void(*xDel)(void*) ){ int rc; assert( !db->mallocFailed ); rc = createCollation(db, zName, enc, pCtx, xCompare, xDel); return sqlite3ApiExit(db, rc); } #ifndef SQLITE_OMIT_UTF16 /* ** Register a new collation sequence with the database handle db. */ int sqlite3_create_collation16( sqlite3* db, const char *zName, int enc, void* pCtx, int(*xCompare)(void*,int,const void*,int,const void*) ){ int rc = SQLITE_OK; char *zName8; assert( !db->mallocFailed ); zName8 = sqlite3Utf16to8(zName, -1); if( zName8 ){ rc = createCollation(db, zName8, enc, pCtx, xCompare, 0); sqlite3_free(zName8); } return sqlite3ApiExit(db, rc); } #endif /* SQLITE_OMIT_UTF16 */ /* ** Register a collation sequence factory callback with the database handle |
︙ | ︙ | |||
1382 1383 1384 1385 1386 1387 1388 | if( SQLITE_OK==rc && !pTab ){ sqlite3SetString(&zErrMsg, "no such table column: ", zTableName, ".", zColumnName, 0); rc = SQLITE_ERROR; } sqlite3Error(db, rc, (zErrMsg?"%s":0), zErrMsg); | | | 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 | if( SQLITE_OK==rc && !pTab ){ sqlite3SetString(&zErrMsg, "no such table column: ", zTableName, ".", zColumnName, 0); rc = SQLITE_ERROR; } sqlite3Error(db, rc, (zErrMsg?"%s":0), zErrMsg); sqlite3_free(zErrMsg); return sqlite3ApiExit(db, rc); } #endif /* ** Set all the parameters in the compiled SQL statement to NULL. */ |
︙ | ︙ |
Changes to src/malloc.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. ** ************************************************************************* ** Memory allocation functions used throughout sqlite. ** ** | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | | < < | < < | < < < < < < < > | < < < < < < | | < < < < < < < | < < < < < < < < < < < < < < < | < < < < < | < < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < | < < < < < | < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < | | < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < | < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < | > < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Memory allocation functions used throughout sqlite. ** ** ** $Id: malloc.c,v 1.5 2007/08/16 04:30:40 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <stdarg.h> #include <ctype.h> /* ** Set the soft heap-size limit for the current thread. Passing a negative ** value indicates no limit. */ void sqlite3_soft_heap_limit(int n){ ThreadData *pTd = sqlite3ThreadData(); if( pTd ){ pTd->nSoftHeapLimit = n; } sqlite3ReleaseThreadData(); } /* ** Release memory held by SQLite instances created by the current thread. */ int sqlite3_release_memory(int n){ return sqlite3PagerReleaseMemory(n); } /* ** Allocate and zero memory. */ void *sqlite3MallocZero(unsigned n){ void *p = sqlite3_malloc(n); if( p ){ memset(p, 0, n); } return p; } /* ** Allocate and zero memory. If the allocation fails, make ** the mallocFailed flag in the connection pointer. */ void *sqlite3DbMallocZero(sqlite3 *db, unsigned n){ void *p = sqlite3_malloc(n); if( p ){ memset(p, 0, n); }else{ db->mallocFailed = 1; } return p; } /* ** Allocate and zero memory. If the allocation fails, make ** the mallocFailed flag in the connection pointer. */ void *sqlite3DbMallocRaw(sqlite3 *db, unsigned n){ void *p = sqlite3_malloc(n); if( !p ){ db->mallocFailed = 1; } return p; } /* ** Attempt to reallocate p. If the reallocation fails, then free p ** and set the mallocFailed flag in the database connection. */ void *sqlite3DbReallocOrFree(sqlite3 *db, void *p, int n){ void *pNew; pNew = sqlite3_realloc(p, n); if( !pNew ){ sqlite3FreeX(p); db->mallocFailed = 1; } return pNew; } /* ** Make a copy of a string in memory obtained from sqliteMalloc(). These ** functions call sqlite3MallocRaw() directly instead of sqliteMalloc(). This ** is because when memory debugging is turned on, these two functions are ** called via macros that record the current file and line number in the ** ThreadData structure. |
︙ | ︙ | |||
777 778 779 780 781 782 783 | zResult[0] = 0; va_end(ap); } /* ** This function must be called before exiting any API function (i.e. | | | < | < < > < < < < < < < < < < < > > > > | 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 | zResult[0] = 0; va_end(ap); } /* ** This function must be called before exiting any API function (i.e. ** returning control to the user) that has called sqlite3_malloc or ** sqlite3_realloc. ** ** The returned value is normally a copy of the second argument to this ** function. However, if a malloc() failure has occured since the previous ** invocation SQLITE_NOMEM is returned instead. ** ** If the first argument, db, is not NULL and a malloc() error has occured, ** then the connection error-code (the value returned by sqlite3_errcode()) ** is set to SQLITE_NOMEM. */ int sqlite3ApiExit(sqlite3* db, int rc){ if( db->mallocFailed ){ sqlite3Error(db, SQLITE_NOMEM, 0); db->mallocFailed = 0; rc = SQLITE_NOMEM; } return rc & (db ? db->errMask : 0xff); } #ifdef SQLITE_MEMDEBUG /* ** This function sets a flag in the thread-specific-data structure that will ** cause an assert to fail if sqliteMalloc() or sqliteRealloc() is called. */ void sqlite3MallocDisallow(){ #if 0 assert( sqlite3_mallocDisallowed>=0 ); sqlite3_mallocDisallowed++; #endif } /* ** This function clears the flag set in the thread-specific-data structure set ** by sqlite3MallocDisallow(). */ void sqlite3MallocAllow(){ #if 0 assert( sqlite3_mallocDisallowed>0 ); sqlite3_mallocDisallowed--; #endif } #endif |
Changes to src/os_unix.c.
︙ | ︙ | |||
353 354 355 356 357 358 359 | }; /* ** These hash tables map inodes and file descriptors (really, lockKey and ** openKey structures) into lockInfo and openCnt structures. Access to ** these hash tables must be protected by a mutex. */ | | < | < | 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 | }; /* ** These hash tables map inodes and file descriptors (really, lockKey and ** openKey structures) into lockInfo and openCnt structures. Access to ** these hash tables must be protected by a mutex. */ static Hash lockHash = {SQLITE_HASH_BINARY, 0, 0, 0, 0, 0}; static Hash openHash = {SQLITE_HASH_BINARY, 0, 0, 0, 0, 0}; #ifdef SQLITE_ENABLE_LOCKING_STYLE /* ** The locking styles are associated with the different file locking ** capabilities supported by different file systems. ** ** POSIX locking style fully supports shared and exclusive byte-range locks |
︙ | ︙ | |||
533 534 535 536 537 538 539 | static void releaseLockInfo(struct lockInfo *pLock){ assert( sqlite3OsInMutex(1) ); if (pLock == NULL) return; pLock->nRef--; if( pLock->nRef==0 ){ sqlite3HashInsert(&lockHash, &pLock->key, sizeof(pLock->key), 0); | | | | 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 | static void releaseLockInfo(struct lockInfo *pLock){ assert( sqlite3OsInMutex(1) ); if (pLock == NULL) return; pLock->nRef--; if( pLock->nRef==0 ){ sqlite3HashInsert(&lockHash, &pLock->key, sizeof(pLock->key), 0); sqlite3_free(pLock); } } /* ** Release a openCnt structure previously allocated by findLockInfo(). */ static void releaseOpenCnt(struct openCnt *pOpen){ assert( sqlite3OsInMutex(1) ); if (pOpen == NULL) return; pOpen->nRef--; if( pOpen->nRef==0 ){ sqlite3HashInsert(&openHash, &pOpen->key, sizeof(pOpen->key), 0); free(pOpen->aPending); sqlite3_free(pOpen); } } #ifdef SQLITE_ENABLE_LOCKING_STYLE /* ** Tests a byte-range locking query to see if byte range locks are ** supported, if not we fall back to dotlockLockingStyle. |
︙ | ︙ | |||
660 661 662 663 664 665 666 | #endif memset(&key2, 0, sizeof(key2)); key2.dev = statbuf.st_dev; key2.ino = statbuf.st_ino; pLock = (struct lockInfo*)sqlite3HashFind(&lockHash, &key1, sizeof(key1)); if( pLock==0 ){ struct lockInfo *pOld; | | | | | | 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 | #endif memset(&key2, 0, sizeof(key2)); key2.dev = statbuf.st_dev; key2.ino = statbuf.st_ino; pLock = (struct lockInfo*)sqlite3HashFind(&lockHash, &key1, sizeof(key1)); if( pLock==0 ){ struct lockInfo *pOld; pLock = sqlite3_malloc( sizeof(*pLock) ); if( pLock==0 ){ rc = 1; goto exit_findlockinfo; } pLock->key = key1; pLock->nRef = 1; pLock->cnt = 0; pLock->locktype = 0; pOld = sqlite3HashInsert(&lockHash, &pLock->key, sizeof(key1), pLock); if( pOld!=0 ){ assert( pOld==pLock ); sqlite3_free(pLock); rc = 1; goto exit_findlockinfo; } }else{ pLock->nRef++; } *ppLock = pLock; if( ppOpen!=0 ){ pOpen = (struct openCnt*)sqlite3HashFind(&openHash, &key2, sizeof(key2)); if( pOpen==0 ){ struct openCnt *pOld; pOpen = sqlite3_malloc( sizeof(*pOpen) ); if( pOpen==0 ){ releaseLockInfo(pLock); rc = 1; goto exit_findlockinfo; } pOpen->key = key2; pOpen->nRef = 1; pOpen->nLock = 0; pOpen->nPending = 0; pOpen->aPending = 0; pOld = sqlite3HashInsert(&openHash, &pOpen->key, sizeof(key2), pOpen); if( pOld!=0 ){ assert( pOld==pOpen ); sqlite3_free(pOpen); releaseLockInfo(pLock); rc = 1; goto exit_findlockinfo; } }else{ pOpen->nRef++; } |
︙ | ︙ | |||
1697 1698 1699 1700 1701 1702 1703 | releaseLockInfo(pFile->pLock); releaseOpenCnt(pFile->pOpen); sqlite3OsLeaveMutex(); pFile->isOpen = 0; OSTRACE2("CLOSE %-3d\n", pFile->h); OpenCounter(-1); | | | 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 | releaseLockInfo(pFile->pLock); releaseOpenCnt(pFile->pOpen); sqlite3OsLeaveMutex(); pFile->isOpen = 0; OSTRACE2("CLOSE %-3d\n", pFile->h); OpenCounter(-1); sqlite3_free(id); return SQLITE_OK; } #ifdef SQLITE_ENABLE_LOCKING_STYLE #pragma mark AFP Support |
︙ | ︙ | |||
2002 2003 2004 2005 2006 2007 2008 | unixFile *id = (unixFile*)*pId; if( !id ) return SQLITE_OK; afpUnixUnlock(*pId, NO_LOCK); /* free the AFP locking structure */ if (id->lockingContext != NULL) { if (((afpLockingContext *)id->lockingContext)->filePath != NULL) | | | | | 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 | unixFile *id = (unixFile*)*pId; if( !id ) return SQLITE_OK; afpUnixUnlock(*pId, NO_LOCK); /* free the AFP locking structure */ if (id->lockingContext != NULL) { if (((afpLockingContext *)id->lockingContext)->filePath != NULL) sqlite3_free(((afpLockingContext*)id->lockingContext)->filePath); sqlite3_free(id->lockingContext); } if( id->dirfd>=0 ) close(id->dirfd); id->dirfd = -1; close(id->h); id->isOpen = 0; OSTRACE2("CLOSE %-3d\n", id->h); OpenCounter(-1); sqlite3_free(id); *pId = 0; return SQLITE_OK; } #pragma mark flock() style locking |
︙ | ︙ | |||
2108 2109 2110 2111 2112 2113 2114 | sqlite3OsEnterMutex(); close(id->h); sqlite3OsLeaveMutex(); id->isOpen = 0; OSTRACE2("CLOSE %-3d\n", id->h); OpenCounter(-1); | | | 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 | sqlite3OsEnterMutex(); close(id->h); sqlite3OsLeaveMutex(); id->isOpen = 0; OSTRACE2("CLOSE %-3d\n", id->h); OpenCounter(-1); sqlite3_free(id); *pId = 0; return SQLITE_OK; } #pragma mark Old-School .lock file based locking /* |
︙ | ︙ | |||
2212 2213 2214 2215 2216 2217 2218 | unixFile *id = (unixFile*)*pId; if( !id ) return SQLITE_OK; dotlockUnixUnlock(*pId, NO_LOCK); /* free the dotlock locking structure */ if (id->lockingContext != NULL) { if (((dotlockLockingContext *)id->lockingContext)->lockPath != NULL) | | | | | 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 | unixFile *id = (unixFile*)*pId; if( !id ) return SQLITE_OK; dotlockUnixUnlock(*pId, NO_LOCK); /* free the dotlock locking structure */ if (id->lockingContext != NULL) { if (((dotlockLockingContext *)id->lockingContext)->lockPath != NULL) sqlite3_free( ( (dotlockLockingContext *) id->lockingContext)->lockPath); sqlite3_free(id->lockingContext); } if( id->dirfd>=0 ) close(id->dirfd); id->dirfd = -1; sqlite3OsEnterMutex(); close(id->h); sqlite3OsLeaveMutex(); id->isOpen = 0; OSTRACE2("CLOSE %-3d\n", id->h); OpenCounter(-1); sqlite3_free(id); *pId = 0; return SQLITE_OK; } #pragma mark No locking |
︙ | ︙ | |||
2269 2270 2271 2272 2273 2274 2275 | close(id->h); sqlite3OsLeaveMutex(); id->isOpen = 0; OSTRACE2("CLOSE %-3d\n", id->h); OpenCounter(-1); | | | | 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 | close(id->h); sqlite3OsLeaveMutex(); id->isOpen = 0; OSTRACE2("CLOSE %-3d\n", id->h); OpenCounter(-1); sqlite3_free(id); *pId = 0; return SQLITE_OK; } #endif /* SQLITE_ENABLE_LOCKING_STYLE */ /* ** Turn a relative pathname into a full pathname. Return a pointer ** to the full pathname stored in space obtained from sqliteMalloc(). ** The calling function is responsible for freeing this space once it ** is no longer needed. */ char *sqlite3UnixFullPathname(const char *zRelative){ char *zFull = 0; if( zRelative[0]=='/' ){ sqlite3SetString(&zFull, zRelative, (char*)0); }else{ char *zBuf = sqlite3_malloc(5000); if( zBuf==0 ){ return 0; } zBuf[0] = 0; sqlite3SetString(&zFull, getcwd(zBuf, 5000), "/", zRelative, (char*)0); sqliteFree(zBuf); |
︙ | ︙ | |||
2527 2528 2529 2530 2531 2532 2533 | } if( delFlag ){ unlink(zFilename); } f.dirfd = -1; f.h = h; SET_THREADID(&f); | | | | | | | 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 | } if( delFlag ){ unlink(zFilename); } f.dirfd = -1; f.h = h; SET_THREADID(&f); pNew = sqlite3_malloc( sizeof(unixFile) ); if( pNew==0 ){ close(h); sqlite3OsEnterMutex(); releaseLockInfo(f.pLock); releaseOpenCnt(f.pOpen); sqlite3OsLeaveMutex(); *pId = 0; return SQLITE_NOMEM; }else{ *pNew = f; switch(lockingStyle) { case afpLockingStyle: { /* afp locking uses the file path so it needs to be included in ** the afpLockingContext */ int nFilename; pNew->pMethod = &sqlite3AFPLockingUnixIoMethod; pNew->lockingContext = sqlite3_malloc(sizeof(afpLockingContext)); nFilename = strlen(zFilename)+1; ((afpLockingContext *)pNew->lockingContext)->filePath = sqlite3_malloc(nFilename); memcpy(((afpLockingContext *)pNew->lockingContext)->filePath, zFilename, nFilename); srandomdev(); break; } case flockLockingStyle: /* flock locking doesn't need additional lockingContext information */ pNew->pMethod = &sqlite3FlockLockingUnixIoMethod; break; case dotlockLockingStyle: { /* dotlock locking uses the file path so it needs to be included in ** the dotlockLockingContext */ int nFilename; pNew->pMethod = &sqlite3DotlockLockingUnixIoMethod; pNew->lockingContext = sqlite3_malloc( sizeof(dotlockLockingContext)); nFilename = strlen(zFilename) + 6; ((dotlockLockingContext *)pNew->lockingContext)->lockPath = sqlite3_malloc( nFilename ); sqlite3_snprintf(nFilename, ((dotlockLockingContext *)pNew->lockingContext)->lockPath, "%s.lock", zFilename); break; } case posixLockingStyle: /* posix locking doesn't need additional lockingContext information */ |
︙ | ︙ | |||
2616 2617 2618 2619 2620 2621 2622 | close(h); return SQLITE_NOMEM; } OSTRACE3("OPEN %-3d %s\n", h, zFilename); f.dirfd = -1; f.h = h; SET_THREADID(&f); | | | 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 | close(h); return SQLITE_NOMEM; } OSTRACE3("OPEN %-3d %s\n", h, zFilename); f.dirfd = -1; f.h = h; SET_THREADID(&f); pNew = sqlite3_malloc( sizeof(unixFile) ); if( pNew==0 ){ close(h); sqlite3OsEnterMutex(); releaseLockInfo(f.pLock); releaseOpenCnt(f.pOpen); sqlite3OsLeaveMutex(); *pId = 0; |
︙ | ︙ |
Changes to src/pager.c.
︙ | ︙ | |||
14 15 16 17 18 19 20 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** ** @(#) $Id: pager.c,v 1.357 2007/08/16 04:30:40 drh Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" #include "os.h" #include "pager.h" #include <assert.h> #include <string.h> |
︙ | ︙ | |||
491 492 493 494 495 496 497 | /* ** Change the size of the pager hash table to N. N must be a power ** of two. */ static void pager_resize_hash_table(Pager *pPager, int N){ PgHdr **aHash, *pPg; assert( N>0 && (N&(N-1))==0 ); | | | | 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 | /* ** Change the size of the pager hash table to N. N must be a power ** of two. */ static void pager_resize_hash_table(Pager *pPager, int N){ PgHdr **aHash, *pPg; assert( N>0 && (N&(N-1))==0 ); aHash = sqlite3MallocZero( sizeof(aHash[0])*N ); if( aHash==0 ){ /* Failure to rehash is not an error. It is only a performance hit. */ return; } sqlite3_free(pPager->aHash); pPager->nHash = N; pPager->aHash = aHash; for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){ int h; if( pPg->pgno==0 ){ assert( pPg->pNextHash==0 && pPg->pPrevHash==0 ); continue; |
︙ | ︙ | |||
616 617 618 619 620 621 622 | #define pager_pagehash(X) 0 #define CHECK_PAGE(x) #endif /* ** When this is called the journal file for pager pPager must be open. ** The master journal file name is read from the end of the file and | | | | 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 | #define pager_pagehash(X) 0 #define CHECK_PAGE(x) #endif /* ** When this is called the journal file for pager pPager must be open. ** The master journal file name is read from the end of the file and ** written into memory obtained from sqlite3_malloc(). *pzMaster is ** set to point at the memory and SQLITE_OK returned. The caller must ** sqlite3_free() *pzMaster. ** ** If no master journal file name is present *pzMaster is set to 0 and ** SQLITE_OK returned. */ static int readMasterJournal(sqlite3_file *pJrnl, char **pzMaster){ int rc; u32 len; |
︙ | ︙ | |||
645 646 647 648 649 650 651 | rc = read32bits(pJrnl, szJ-12, &cksum); if( rc!=SQLITE_OK ) return rc; rc = sqlite3OsRead(pJrnl, aMagic, 8, szJ-8); if( rc!=SQLITE_OK || memcmp(aMagic, aJournalMagic, 8) ) return rc; | | | | | 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 | rc = read32bits(pJrnl, szJ-12, &cksum); if( rc!=SQLITE_OK ) return rc; rc = sqlite3OsRead(pJrnl, aMagic, 8, szJ-8); if( rc!=SQLITE_OK || memcmp(aMagic, aJournalMagic, 8) ) return rc; *pzMaster = (char *)sqlite3MallocZero(len+1); if( !*pzMaster ){ return SQLITE_NOMEM; } rc = sqlite3OsRead(pJrnl, *pzMaster, len, szJ-16-len); if( rc!=SQLITE_OK ){ sqlite3_free(*pzMaster); *pzMaster = 0; return rc; } /* See if the checksum matches the master journal name */ for(i=0; i<len; i++){ cksum -= (*pzMaster)[i]; } if( cksum ){ /* If the checksum doesn't add up, then one or more of the disk sectors ** containing the master journal filename is corrupted. This means ** definitely roll back, so just return SQLITE_OK and report a (nul) ** master-journal filename. */ sqlite3_free(*pzMaster); *pzMaster = 0; }else{ (*pzMaster)[len] = '\0'; } return SQLITE_OK; } |
︙ | ︙ | |||
966 967 968 969 970 971 972 | static void pager_reset(Pager *pPager){ PgHdr *pPg, *pNext; if( pPager->errCode ) return; for(pPg=pPager->pAll; pPg; pPg=pNext){ IOTRACE(("PGFREE %p %d\n", pPager, pPg->pgno)); PAGER_INCR(sqlite3_pager_pgfree_count); pNext = pPg->pNextAll; | | | | 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 | static void pager_reset(Pager *pPager){ PgHdr *pPg, *pNext; if( pPager->errCode ) return; for(pPg=pPager->pAll; pPg; pPg=pNext){ IOTRACE(("PGFREE %p %d\n", pPager, pPg->pgno)); PAGER_INCR(sqlite3_pager_pgfree_count); pNext = pPg->pNextAll; sqlite3_free(pPg); } pPager->pStmt = 0; pPager->pFirst = 0; pPager->pFirstSynced = 0; pPager->pLast = 0; pPager->pAll = 0; pPager->nHash = 0; sqlite3_free(pPager->aHash); pPager->nPage = 0; pPager->aHash = 0; pPager->nRef = 0; } /* ** This routine ends a transaction. A transaction is ended by either |
︙ | ︙ | |||
1022 1023 1024 1025 1026 1027 1028 | }else{ sqlite3OsClose(&pPager->jfd); pPager->journalOpen = 0; if( rc==SQLITE_OK ){ rc = sqlite3OsDelete(pPager->zJournal); } } | | | 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 | }else{ sqlite3OsClose(&pPager->jfd); pPager->journalOpen = 0; if( rc==SQLITE_OK ){ rc = sqlite3OsDelete(pPager->zJournal); } } sqlite3_free( pPager->aInJournal ); pPager->aInJournal = 0; for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){ pPg->inJournal = 0; pPg->dirty = 0; pPg->needSync = 0; pPg->alwaysRollback = 0; #ifdef SQLITE_CHECK_PAGES |
︙ | ︙ | |||
1243 1244 1245 1246 1247 1248 1249 | if( rc!=SQLITE_OK ) goto delmaster_out; if( nMasterJournal>0 ){ char *zJournal; char *zMasterPtr = 0; /* Load the entire master journal file into space obtained from | | | | 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 | if( rc!=SQLITE_OK ) goto delmaster_out; if( nMasterJournal>0 ){ char *zJournal; char *zMasterPtr = 0; /* Load the entire master journal file into space obtained from ** sqlite3_malloc() and pointed to by zMasterJournal. */ zMasterJournal = (char *)sqlite3_malloc(nMasterJournal); if( !zMasterJournal ){ rc = SQLITE_NOMEM; goto delmaster_out; } rc = sqlite3OsRead(master, zMasterJournal, nMasterJournal, 0); if( rc!=SQLITE_OK ) goto delmaster_out; |
︙ | ︙ | |||
1276 1277 1278 1279 1280 1281 1282 | rc = readMasterJournal(journal, &zMasterPtr); sqlite3OsClose(&journal); if( rc!=SQLITE_OK ){ goto delmaster_out; } c = zMasterPtr!=0 && strcmp(zMasterPtr, zMaster)==0; | | | | 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 | rc = readMasterJournal(journal, &zMasterPtr); sqlite3OsClose(&journal); if( rc!=SQLITE_OK ){ goto delmaster_out; } c = zMasterPtr!=0 && strcmp(zMasterPtr, zMaster)==0; sqlite3_free(zMasterPtr); if( c ){ /* We have a match. Do not delete the master journal file. */ goto delmaster_out; } } zJournal += (strlen(zJournal)+1); } } rc = sqlite3OsDelete(zMaster); delmaster_out: if( zMasterJournal ){ sqlite3_free(zMasterJournal); } if( master_open ){ sqlite3OsClose(&master); } return rc; } |
︙ | ︙ | |||
1408 1409 1410 1411 1412 1413 1414 | ** If a master journal file name is specified, but the file is not ** present on disk, then the journal is not hot and does not need to be ** played back. */ rc = readMasterJournal(pPager->jfd, &zMaster); assert( rc!=SQLITE_DONE ); if( rc!=SQLITE_OK || (zMaster && !sqlite3OsFileExists(zMaster)) ){ | | | 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 | ** If a master journal file name is specified, but the file is not ** present on disk, then the journal is not hot and does not need to be ** played back. */ rc = readMasterJournal(pPager->jfd, &zMaster); assert( rc!=SQLITE_DONE ); if( rc!=SQLITE_OK || (zMaster && !sqlite3OsFileExists(zMaster)) ){ sqlite3_free(zMaster); zMaster = 0; if( rc==SQLITE_DONE ) rc = SQLITE_OK; goto end_playback; } pPager->journalOff = 0; /* This loop terminates either when the readJournalHdr() call returns |
︙ | ︙ | |||
1494 1495 1496 1497 1498 1499 1500 | if( zMaster ){ /* If there was a master journal and this routine will return success, ** see if it is possible to delete the master journal. */ if( rc==SQLITE_OK ){ rc = pager_delmaster(zMaster); } | | | 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 | if( zMaster ){ /* If there was a master journal and this routine will return success, ** see if it is possible to delete the master journal. */ if( rc==SQLITE_OK ){ rc = pager_delmaster(zMaster); } sqlite3_free(zMaster); } /* The Pager.sectorSize variable may have been updated while rolling ** back a journal created by a process with a different sector size ** value. Reset it to the correct value for this process. */ setSectorSize(pPager); |
︙ | ︙ | |||
1741 1742 1743 1744 1745 1746 1747 | ThreadData *pTsd = sqlite3ThreadData(); assert( pTsd ); #endif /* We used to test if malloc() had already failed before proceeding. ** But the way this function is used in SQLite means that can never ** happen. Furthermore, if the malloc-failed flag is already set, | | | | 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 | ThreadData *pTsd = sqlite3ThreadData(); assert( pTsd ); #endif /* We used to test if malloc() had already failed before proceeding. ** But the way this function is used in SQLite means that can never ** happen. Furthermore, if the malloc-failed flag is already set, ** either the call to sqlite3StrDup() or sqlite3_malloc() below will ** fail shortly and SQLITE_NOMEM returned anyway. */ *ppPager = 0; /* Open the pager file and set zFullPathname to point at malloc()ed ** memory containing the complete filename (i.e. including the directory). */ if( zFilename && zFilename[0] ){ #ifndef SQLITE_OMIT_MEMORYDB if( strcmp(zFilename,":memory:")==0 ){ memDb = 1; zFullPathname = sqlite3StrDup(""); }else #endif { zFullPathname = sqlite3OsFullPathname(zFilename); if( zFullPathname ){ rc = sqlite3OsOpenReadWrite(zFullPathname, &fd, &readOnly); assert( rc!=SQLITE_OK || fd ); |
︙ | ︙ | |||
1779 1780 1781 1782 1783 1784 1785 | /* Allocate the Pager structure. As part of the same allocation, allocate ** space for the full paths of the file, directory and journal ** (Pager.zFilename, Pager.zDirectory and Pager.zJournal). */ if( zFullPathname ){ nameLen = strlen(zFullPathname); | | | | | | | 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 | /* Allocate the Pager structure. As part of the same allocation, allocate ** space for the full paths of the file, directory and journal ** (Pager.zFilename, Pager.zDirectory and Pager.zJournal). */ if( zFullPathname ){ nameLen = strlen(zFullPathname); pPager = sqlite3MallocZero( sizeof(*pPager) + nameLen*3 + 30 ); if( pPager && rc==SQLITE_OK ){ pPager->pTmpSpace = (char *)sqlite3_malloc(SQLITE_DEFAULT_PAGE_SIZE); } } /* If an error occured in either of the blocks above, free the memory ** pointed to by zFullPathname, free the Pager structure and close the ** file. Since the pager is not allocated there is no need to set ** any Pager.errMask variables. */ if( !pPager || !zFullPathname || !pPager->pTmpSpace || rc!=SQLITE_OK ){ sqlite3OsClose(&fd); sqlite3_free(zFullPathname); sqlite3_free(pPager); return ((rc==SQLITE_OK)?SQLITE_NOMEM:rc); } PAGERTRACE3("OPEN %d %s\n", FILEHANDLEID(fd), zFullPathname); IOTRACE(("OPEN %p %s\n", pPager, zFullPathname)) pPager->zFilename = (char*)&pPager[1]; pPager->zDirectory = &pPager->zFilename[nameLen+1]; pPager->zJournal = &pPager->zDirectory[nameLen+1]; memcpy(pPager->zFilename, zFullPathname, nameLen+1); memcpy(pPager->zDirectory, zFullPathname, nameLen+1); for(i=nameLen; i>0 && pPager->zDirectory[i-1]!='/'; i--){} if( i>0 ) pPager->zDirectory[i-1] = 0; memcpy(pPager->zJournal, zFullPathname,nameLen); sqlite3_free(zFullPathname); memcpy(&pPager->zJournal[nameLen], "-journal",sizeof("-journal")); pPager->fd = fd; /* pPager->journalOpen = 0; */ pPager->useJournal = useJournal && !memDb; pPager->noReadlock = noReadlock && readOnly; /* pPager->stmtOpen = 0; */ /* pPager->stmtInUse = 0; */ |
︙ | ︙ | |||
1896 1897 1898 1899 1900 1901 1902 | ** and returned. */ int sqlite3PagerSetPagesize(Pager *pPager, int pageSize){ assert( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE ); if( !pPager->memDb && pPager->nRef==0 ){ pager_reset(pPager); pPager->pageSize = pageSize; | > | | 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 | ** and returned. */ int sqlite3PagerSetPagesize(Pager *pPager, int pageSize){ assert( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE ); if( !pPager->memDb && pPager->nRef==0 ){ pager_reset(pPager); pPager->pageSize = pageSize; sqlite3_free(pPager->pTmpSpace); pPager->pTmpSpace = sqlite3_malloc(pageSize); } return pPager->pageSize; } /* ** Attempt to set the maximum database page count if mxPage is positive. ** Make no changes if mxPage is zero or negative. And never reduce the |
︙ | ︙ | |||
2010 2011 2012 2013 2014 2015 2016 | #ifndef SQLITE_OMIT_MEMORYDB /* ** Clear a PgHistory block */ static void clearHistory(PgHistory *pHist){ | | | | 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 | #ifndef SQLITE_OMIT_MEMORYDB /* ** Clear a PgHistory block */ static void clearHistory(PgHistory *pHist){ sqlite3_free(pHist->pOrig); sqlite3_free(pHist->pStmt); pHist->pOrig = 0; pHist->pStmt = 0; } #else #define clearHistory(x) #endif |
︙ | ︙ | |||
2115 2116 2117 2118 2119 2120 2121 | ppPg = &pPg->pNextAll; }else{ *ppPg = pPg->pNextAll; IOTRACE(("PGFREE %p %d\n", pPager, pPg->pgno)); PAGER_INCR(sqlite3_pager_pgfree_count); unlinkPage(pPg); makeClean(pPg); | | | 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 | ppPg = &pPg->pNextAll; }else{ *ppPg = pPg->pNextAll; IOTRACE(("PGFREE %p %d\n", pPager, pPg->pgno)); PAGER_INCR(sqlite3_pager_pgfree_count); unlinkPage(pPg); makeClean(pPg); sqlite3_free(pPg); pPager->nPage--; } } } /* ** Try to obtain a lock on a file. Invoke the busy callback if the lock |
︙ | ︙ | |||
2226 2227 2228 2229 2230 2231 2232 | enable_simulated_io_errors(); PAGERTRACE2("CLOSE %d\n", PAGERID(pPager)); IOTRACE(("CLOSE %p\n", pPager)) assert( pPager->errCode || (pPager->journalOpen==0 && pPager->stmtOpen==0) ); if( pPager->journalOpen ){ sqlite3OsClose(&pPager->jfd); } | | | 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 | enable_simulated_io_errors(); PAGERTRACE2("CLOSE %d\n", PAGERID(pPager)); IOTRACE(("CLOSE %p\n", pPager)) assert( pPager->errCode || (pPager->journalOpen==0 && pPager->stmtOpen==0) ); if( pPager->journalOpen ){ sqlite3OsClose(&pPager->jfd); } sqlite3_free(pPager->aInJournal); if( pPager->stmtOpen ){ sqlite3OsClose(&pPager->stfd); } sqlite3OsClose(&pPager->fd); /* Temp files are automatically deleted by the OS ** if( pPager->tempFile ){ ** sqlite3OsDelete(pPager->zFilename); |
︙ | ︙ | |||
2249 2250 2251 2252 2253 2254 2255 | pTsd->pPager = pPager->pNext; }else{ Pager *pTmp; for(pTmp = pTsd->pPager; pTmp->pNext!=pPager; pTmp=pTmp->pNext){} pTmp->pNext = pPager->pNext; } #endif | | | | | 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 | pTsd->pPager = pPager->pNext; }else{ Pager *pTmp; for(pTmp = pTsd->pPager; pTmp->pNext!=pPager; pTmp=pTmp->pNext){} pTmp->pNext = pPager->pNext; } #endif sqlite3_free(pPager->aHash); sqlite3_free(pPager->pTmpSpace); sqlite3_free(pPager); return SQLITE_OK; } #if !defined(NDEBUG) || defined(SQLITE_TEST) /* ** Return the page number for the given page data. */ |
︙ | ︙ | |||
2679 2680 2681 2682 2683 2684 2685 | *ppPg = pPg; return SQLITE_OK; } /* ** This function is called to free superfluous dynamically allocated memory ** held by the pager system. Memory in use by any SQLite pager allocated | | | 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 | *ppPg = pPg; return SQLITE_OK; } /* ** This function is called to free superfluous dynamically allocated memory ** held by the pager system. Memory in use by any SQLite pager allocated ** by the current thread may be sqlite3_free()ed. ** ** nReq is the number of bytes of memory required. Once this much has ** been released, the function returns. A negative value for nReq means ** free as much memory as possible. The return value is the total number ** of bytes of memory released. */ #if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) && !defined(SQLITE_OMIT_DISKIO) |
︙ | ︙ | |||
2743 2744 2745 2746 2747 2748 2749 | }else{ for( pTmp=pPager->pAll; pTmp->pNextAll!=pPg; pTmp=pTmp->pNextAll ){} pTmp->pNextAll = pPg->pNextAll; } nReleased += sqliteAllocSize(pPg); IOTRACE(("PGFREE %p %d *\n", pPager, pPg->pgno)); PAGER_INCR(sqlite3_pager_pgfree_count); | | | 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 | }else{ for( pTmp=pPager->pAll; pTmp->pNextAll!=pPg; pTmp=pTmp->pNextAll ){} pTmp->pNextAll = pPg->pNextAll; } nReleased += sqliteAllocSize(pPg); IOTRACE(("PGFREE %p %d *\n", pPager, pPg->pgno)); PAGER_INCR(sqlite3_pager_pgfree_count); sqlite3_free(pPg); } if( rc!=SQLITE_OK ){ /* An error occured whilst writing to the database file or ** journal in pager_recycle(). The error is not returned to the ** caller of this function. Instead, set the Pager.errCode variable. ** The error will be returned to the user (or users, in the case |
︙ | ︙ | |||
2982 2983 2984 2985 2986 2987 2988 | pager_resize_hash_table(pPager, pPager->nHash<256 ? 256 : pPager->nHash*2); if( pPager->nHash==0 ){ rc = SQLITE_NOMEM; goto pager_allocate_out; } } | | | 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 | pager_resize_hash_table(pPager, pPager->nHash<256 ? 256 : pPager->nHash*2); if( pPager->nHash==0 ){ rc = SQLITE_NOMEM; goto pager_allocate_out; } } pPg = sqlite3_malloc( sizeof(*pPg) + pPager->pageSize + sizeof(u32) + pPager->nExtra + MEMDB*sizeof(PgHistory) ); if( pPg==0 ){ rc = SQLITE_NOMEM; goto pager_allocate_out; } memset(pPg, 0, sizeof(*pPg)); |
︙ | ︙ | |||
3286 3287 3288 3289 3290 3291 3292 | int rc; assert( !MEMDB ); assert( pPager->state>=PAGER_RESERVED ); assert( pPager->journalOpen==0 ); assert( pPager->useJournal ); assert( pPager->aInJournal==0 ); sqlite3PagerPagecount(pPager); | | | 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 | int rc; assert( !MEMDB ); assert( pPager->state>=PAGER_RESERVED ); assert( pPager->journalOpen==0 ); assert( pPager->useJournal ); assert( pPager->aInJournal==0 ); sqlite3PagerPagecount(pPager); pPager->aInJournal = sqlite3MallocZero( pPager->dbSize/8 + 1 ); if( pPager->aInJournal==0 ){ rc = SQLITE_NOMEM; goto failed_to_open_journal; } rc = sqlite3OsOpenExclusive(pPager->zJournal, &pPager->jfd, pPager->tempFile); assert( rc!=SQLITE_OK || pPager->jfd ); |
︙ | ︙ | |||
3333 3334 3335 3336 3337 3338 3339 | if( rc==SQLITE_OK ){ rc = SQLITE_FULL; } } return rc; failed_to_open_journal: | | | 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 | if( rc==SQLITE_OK ){ rc = SQLITE_FULL; } } return rc; failed_to_open_journal: sqlite3_free(pPager->aInJournal); pPager->aInJournal = 0; return rc; } /* ** Acquire a write-lock on the database. The lock is removed when ** the any of the following happen: |
︙ | ︙ | |||
3402 3403 3404 3405 3406 3407 3408 | ** by this connection. Instead of deleting the journal file it was ** kept open and truncated to 0 bytes. */ assert( pPager->nRec==0 ); assert( pPager->origDbSize==0 ); assert( pPager->aInJournal==0 ); sqlite3PagerPagecount(pPager); | | | 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 | ** by this connection. Instead of deleting the journal file it was ** kept open and truncated to 0 bytes. */ assert( pPager->nRec==0 ); assert( pPager->origDbSize==0 ); assert( pPager->aInJournal==0 ); sqlite3PagerPagecount(pPager); pPager->aInJournal = sqlite3MallocZero( pPager->dbSize/8 + 1 ); if( !pPager->aInJournal ){ rc = SQLITE_NOMEM; }else{ pPager->origDbSize = pPager->dbSize; rc = writeJournalHdr(pPager); } } |
︙ | ︙ | |||
3537 3538 3539 3540 3541 3542 3543 | if( !pPg->inJournal && (pPager->useJournal || MEMDB) ){ if( (int)pPg->pgno <= pPager->origDbSize ){ int szPg; if( MEMDB ){ PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager); PAGERTRACE3("JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno); assert( pHist->pOrig==0 ); | | | 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 | if( !pPg->inJournal && (pPager->useJournal || MEMDB) ){ if( (int)pPg->pgno <= pPager->origDbSize ){ int szPg; if( MEMDB ){ PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager); PAGERTRACE3("JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno); assert( pHist->pOrig==0 ); pHist->pOrig = sqlite3_malloc( pPager->pageSize ); if( pHist->pOrig ){ memcpy(pHist->pOrig, PGHDR_TO_DATA(pPg), pPager->pageSize); } }else{ u32 cksum, saved; char *pData2, *pEnd; /* We should never write to the journal file the page that |
︙ | ︙ | |||
3604 3605 3606 3607 3608 3609 3610 | && !pageInStatement(pPg) && (int)pPg->pgno<=pPager->stmtSize ){ assert( pPg->inJournal || (int)pPg->pgno>pPager->origDbSize ); if( MEMDB ){ PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager); assert( pHist->pStmt==0 ); | | | 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 | && !pageInStatement(pPg) && (int)pPg->pgno<=pPager->stmtSize ){ assert( pPg->inJournal || (int)pPg->pgno>pPager->origDbSize ); if( MEMDB ){ PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager); assert( pHist->pStmt==0 ); pHist->pStmt = sqlite3_malloc( pPager->pageSize ); if( pHist->pStmt ){ memcpy(pHist->pStmt, PGHDR_TO_DATA(pPg), pPager->pageSize); } PAGERTRACE3("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno); page_add_to_stmt_list(pPg); }else{ i64 offset = pPager->stmtNRec*(4+pPager->pageSize); |
︙ | ︙ | |||
4150 4151 4152 4153 4154 4155 4156 | return SQLITE_OK; } if( !pPager->journalOpen ){ pPager->stmtAutoopen = 1; return SQLITE_OK; } assert( pPager->journalOpen ); | | | 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 | return SQLITE_OK; } if( !pPager->journalOpen ){ pPager->stmtAutoopen = 1; return SQLITE_OK; } assert( pPager->journalOpen ); pPager->aInStmt = sqlite3MallocZero( pPager->dbSize/8 + 1 ); if( pPager->aInStmt==0 ){ /* sqlite3OsLock(pPager->fd, SHARED_LOCK); */ return SQLITE_NOMEM; } #ifndef NDEBUG rc = sqlite3OsFileSize(pPager->jfd, &pPager->stmtJSize); if( rc ) goto stmt_begin_failed; |
︙ | ︙ | |||
4175 4176 4177 4178 4179 4180 4181 | pPager->stmtNRec = 0; } pPager->stmtInUse = 1; return SQLITE_OK; stmt_begin_failed: if( pPager->aInStmt ){ | | | | | 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 | pPager->stmtNRec = 0; } pPager->stmtInUse = 1; return SQLITE_OK; stmt_begin_failed: if( pPager->aInStmt ){ sqlite3_free(pPager->aInStmt); pPager->aInStmt = 0; } return rc; } /* ** Commit a statement. */ int sqlite3PagerStmtCommit(Pager *pPager){ if( pPager->stmtInUse ){ PgHdr *pPg, *pNext; PAGERTRACE2("STMT-COMMIT %d\n", PAGERID(pPager)); if( !MEMDB ){ /* sqlite3OsTruncate(pPager->stfd, 0); */ sqlite3_free( pPager->aInStmt ); pPager->aInStmt = 0; }else{ for(pPg=pPager->pStmt; pPg; pPg=pNext){ PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager); pNext = pHist->pNextStmt; assert( pHist->inStmt ); pHist->inStmt = 0; pHist->pPrevStmt = pHist->pNextStmt = 0; sqlite3_free(pHist->pStmt); pHist->pStmt = 0; } } pPager->stmtNRec = 0; pPager->stmtInUse = 0; pPager->pStmt = 0; } |
︙ | ︙ | |||
4225 4226 4227 4228 4229 4230 4231 | if( MEMDB ){ PgHdr *pPg; PgHistory *pHist; for(pPg=pPager->pStmt; pPg; pPg=pHist->pNextStmt){ pHist = PGHDR_TO_HIST(pPg, pPager); if( pHist->pStmt ){ memcpy(PGHDR_TO_DATA(pPg), pHist->pStmt, pPager->pageSize); | | | 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 | if( MEMDB ){ PgHdr *pPg; PgHistory *pHist; for(pPg=pPager->pStmt; pPg; pPg=pHist->pNextStmt){ pHist = PGHDR_TO_HIST(pPg, pPager); if( pHist->pStmt ){ memcpy(PGHDR_TO_DATA(pPg), pHist->pStmt, pPager->pageSize); sqlite3_free(pHist->pStmt); pHist->pStmt = 0; } } pPager->dbSize = pPager->stmtSize; pager_truncate_cache(pPager); rc = SQLITE_OK; }else{ |
︙ | ︙ |
Changes to src/parse.y.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** This file contains SQLite's grammar for SQL. Process this file ** using the lemon parser generator to generate C code that runs ** the parser. Lemon will also generate a header file containing ** numeric codes for all of the tokens. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** This file contains SQLite's grammar for SQL. Process this file ** using the lemon parser generator to generate C code that runs ** the parser. Lemon will also generate a header file containing ** numeric codes for all of the tokens. ** ** @(#) $Id: parse.y,v 1.232 2007/08/16 04:30:40 drh Exp $ */ // All token codes are small integers with #defines that begin with "TK_" %token_prefix TK_ // The type of the data attached to each token is Token. This is also the // default type for non-terminals. |
︙ | ︙ | |||
249 250 251 252 253 254 255 | carglist ::= . carg ::= CONSTRAINT nm ccons. carg ::= ccons. ccons ::= DEFAULT term(X). {sqlite3AddDefaultValue(pParse,X);} ccons ::= DEFAULT LP expr(X) RP. {sqlite3AddDefaultValue(pParse,X);} ccons ::= DEFAULT PLUS term(X). {sqlite3AddDefaultValue(pParse,X);} ccons ::= DEFAULT MINUS term(X). { | | | | 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 | carglist ::= . carg ::= CONSTRAINT nm ccons. carg ::= ccons. ccons ::= DEFAULT term(X). {sqlite3AddDefaultValue(pParse,X);} ccons ::= DEFAULT LP expr(X) RP. {sqlite3AddDefaultValue(pParse,X);} ccons ::= DEFAULT PLUS term(X). {sqlite3AddDefaultValue(pParse,X);} ccons ::= DEFAULT MINUS term(X). { Expr *p = sqlite3PExpr(pParse, TK_UMINUS, X, 0, 0); sqlite3AddDefaultValue(pParse,p); } ccons ::= DEFAULT id(X). { Expr *p = sqlite3PExpr(pParse, TK_STRING, 0, 0, &X); sqlite3AddDefaultValue(pParse,p); } // In addition to the type name, we also care about the primary key and // UNIQUE constraints. // ccons ::= NULL onconf. |
︙ | ︙ | |||
389 390 391 392 393 394 395 | %type multiselect_op {int} multiselect_op(A) ::= UNION(OP). {A = @OP;} multiselect_op(A) ::= UNION ALL. {A = TK_ALL;} multiselect_op(A) ::= EXCEPT|INTERSECT(OP). {A = @OP;} %endif SQLITE_OMIT_COMPOUND_SELECT oneselect(A) ::= SELECT distinct(D) selcollist(W) from(X) where_opt(Y) groupby_opt(P) having_opt(Q) orderby_opt(Z) limit_opt(L). { | | | 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 | %type multiselect_op {int} multiselect_op(A) ::= UNION(OP). {A = @OP;} multiselect_op(A) ::= UNION ALL. {A = TK_ALL;} multiselect_op(A) ::= EXCEPT|INTERSECT(OP). {A = @OP;} %endif SQLITE_OMIT_COMPOUND_SELECT oneselect(A) ::= SELECT distinct(D) selcollist(W) from(X) where_opt(Y) groupby_opt(P) having_opt(Q) orderby_opt(Z) limit_opt(L). { A = sqlite3SelectNew(pParse,W,X,Y,P,Q,Z,D,L.pLimit,L.pOffset); } // The "distinct" nonterminal is true (1) if the DISTINCT keyword is // present and false (0) if it is not. // %type distinct {int} distinct(A) ::= DISTINCT. {A = 1;} |
︙ | ︙ | |||
412 413 414 415 416 417 418 | %type selcollist {ExprList*} %destructor selcollist {sqlite3ExprListDelete($$);} %type sclp {ExprList*} %destructor sclp {sqlite3ExprListDelete($$);} sclp(A) ::= selcollist(X) COMMA. {A = X;} sclp(A) ::= . {A = 0;} selcollist(A) ::= sclp(P) expr(X) as(Y). { | | > | | | > | | | | | | | | 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 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 | %type selcollist {ExprList*} %destructor selcollist {sqlite3ExprListDelete($$);} %type sclp {ExprList*} %destructor sclp {sqlite3ExprListDelete($$);} sclp(A) ::= selcollist(X) COMMA. {A = X;} sclp(A) ::= . {A = 0;} selcollist(A) ::= sclp(P) expr(X) as(Y). { A = sqlite3ExprListAppend(pParse,P,X,Y.n?&Y:0); } selcollist(A) ::= sclp(P) STAR. { Expr *p = sqlite3Expr(pParse, TK_ALL, 0, 0, 0); A = sqlite3ExprListAppend(pParse, P, p, 0); } selcollist(A) ::= sclp(P) nm(X) DOT STAR. { Expr *pRight = sqlite3PExpr(pParse, TK_ALL, 0, 0, 0); Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, &X); Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0); A = sqlite3ExprListAppend(pParse,P, pDot, 0); } // An option "AS <id>" phrase that can follow one of the expressions that // define the result set, or one of the tables in the FROM clause. // %type as {Token} as(X) ::= AS nm(Y). {X = Y;} as(X) ::= ids(Y). {X = Y;} as(X) ::= . {X.n = 0;} %type seltablist {SrcList*} %destructor seltablist {sqlite3SrcListDelete($$);} %type stl_prefix {SrcList*} %destructor stl_prefix {sqlite3SrcListDelete($$);} %type from {SrcList*} %destructor from {sqlite3SrcListDelete($$);} // A complete FROM clause. // from(A) ::= . {A = sqlite3DbMallocZero(pParse->db, sizeof(*A));} from(A) ::= FROM seltablist(X). { A = X; sqlite3SrcListShiftJoinType(A); } // "seltablist" is a "Select Table List" - the content of the FROM clause // in a SELECT statement. "stl_prefix" is a prefix of this list. // stl_prefix(A) ::= seltablist(X) joinop(Y). { A = X; if( A && A->nSrc>0 ) A->a[A->nSrc-1].jointype = Y; } stl_prefix(A) ::= . {A = 0;} seltablist(A) ::= stl_prefix(X) nm(Y) dbnm(D) as(Z) on_opt(N) using_opt(U). { A = sqlite3SrcListAppendFromTerm(pParse,X,&Y,&D,&Z,0,N,U); } %ifndef SQLITE_OMIT_SUBQUERY seltablist(A) ::= stl_prefix(X) LP seltablist_paren(S) RP as(Z) on_opt(N) using_opt(U). { A = sqlite3SrcListAppendFromTerm(pParse,X,0,0,&Z,S,N,U); } // A seltablist_paren nonterminal represents anything in a FROM that // is contained inside parentheses. This can be either a subquery or // a grouping of table and subqueries. // %type seltablist_paren {Select*} %destructor seltablist_paren {sqlite3SelectDelete($$);} seltablist_paren(A) ::= select(S). {A = S;} seltablist_paren(A) ::= seltablist(F). { sqlite3SrcListShiftJoinType(F); A = sqlite3SelectNew(pParse,0,F,0,0,0,0,0,0,0); } %endif SQLITE_OMIT_SUBQUERY %type dbnm {Token} dbnm(A) ::= . {A.z=0; A.n=0;} dbnm(A) ::= DOT nm(X). {A = X;} %type fullname {SrcList*} %destructor fullname {sqlite3SrcListDelete($$);} fullname(A) ::= nm(X) dbnm(Y). {A = sqlite3SrcListAppend(pParse->db,0,&X,&Y);} %type joinop {int} %type joinop2 {int} joinop(X) ::= COMMA|JOIN. { X = JT_INNER; } joinop(X) ::= JOIN_KW(A) JOIN. { X = sqlite3JoinType(pParse,&A,0,0); } joinop(X) ::= JOIN_KW(A) nm(B) JOIN. { X = sqlite3JoinType(pParse,&A,&B,0); } joinop(X) ::= JOIN_KW(A) nm(B) nm(C) JOIN. |
︙ | ︙ | |||
514 515 516 517 518 519 520 | %destructor sortlist {sqlite3ExprListDelete($$);} %type sortitem {Expr*} %destructor sortitem {sqlite3ExprDelete($$);} orderby_opt(A) ::= . {A = 0;} orderby_opt(A) ::= ORDER BY sortlist(X). {A = X;} sortlist(A) ::= sortlist(X) COMMA sortitem(Y) sortorder(Z). { | | | | 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 | %destructor sortlist {sqlite3ExprListDelete($$);} %type sortitem {Expr*} %destructor sortitem {sqlite3ExprDelete($$);} orderby_opt(A) ::= . {A = 0;} orderby_opt(A) ::= ORDER BY sortlist(X). {A = X;} sortlist(A) ::= sortlist(X) COMMA sortitem(Y) sortorder(Z). { A = sqlite3ExprListAppend(pParse,X,Y,0); if( A ) A->a[A->nExpr-1].sortOrder = Z; } sortlist(A) ::= sortitem(Y) sortorder(Z). { A = sqlite3ExprListAppend(pParse,0,Y,0); if( A && A->a ) A->a[0].sortOrder = Z; } sortitem(A) ::= expr(X). {A = X;} %type sortorder {int} sortorder(A) ::= ASC. {A = SQLITE_SO_ASC;} |
︙ | ︙ | |||
580 581 582 583 584 585 586 | sqlite3Update(pParse,X,Y,Z,R); } %type setlist {ExprList*} %destructor setlist {sqlite3ExprListDelete($$);} setlist(A) ::= setlist(Z) COMMA nm(X) EQ expr(Y). | | | > | > | > | > | > | | | | | | | | | | | | | | | | | | | | | > | | | | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > | > | > | | | | | 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 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 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 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 | sqlite3Update(pParse,X,Y,Z,R); } %type setlist {ExprList*} %destructor setlist {sqlite3ExprListDelete($$);} setlist(A) ::= setlist(Z) COMMA nm(X) EQ expr(Y). {A = sqlite3ExprListAppend(pParse,Z,Y,&X);} setlist(A) ::= nm(X) EQ expr(Y). {A = sqlite3ExprListAppend(pParse,0,Y,&X);} ////////////////////////// The INSERT command ///////////////////////////////// // cmd ::= insert_cmd(R) INTO fullname(X) inscollist_opt(F) VALUES LP itemlist(Y) RP. {sqlite3Insert(pParse, X, Y, 0, F, R);} cmd ::= insert_cmd(R) INTO fullname(X) inscollist_opt(F) select(S). {sqlite3Insert(pParse, X, 0, S, F, R);} cmd ::= insert_cmd(R) INTO fullname(X) inscollist_opt(F) DEFAULT VALUES. {sqlite3Insert(pParse, X, 0, 0, F, R);} %type insert_cmd {int} insert_cmd(A) ::= INSERT orconf(R). {A = R;} insert_cmd(A) ::= REPLACE. {A = OE_Replace;} %type itemlist {ExprList*} %destructor itemlist {sqlite3ExprListDelete($$);} itemlist(A) ::= itemlist(X) COMMA expr(Y). {A = sqlite3ExprListAppend(pParse,X,Y,0);} itemlist(A) ::= expr(X). {A = sqlite3ExprListAppend(pParse,0,X,0);} %type inscollist_opt {IdList*} %destructor inscollist_opt {sqlite3IdListDelete($$);} %type inscollist {IdList*} %destructor inscollist {sqlite3IdListDelete($$);} inscollist_opt(A) ::= . {A = 0;} inscollist_opt(A) ::= LP inscollist(X) RP. {A = X;} inscollist(A) ::= inscollist(X) COMMA nm(Y). {A = sqlite3IdListAppend(pParse->db,X,&Y);} inscollist(A) ::= nm(Y). {A = sqlite3IdListAppend(pParse->db,0,&Y);} /////////////////////////// Expression Processing ///////////////////////////// // %type expr {Expr*} %destructor expr {sqlite3ExprDelete($$);} %type term {Expr*} %destructor term {sqlite3ExprDelete($$);} expr(A) ::= term(X). {A = X;} expr(A) ::= LP(B) expr(X) RP(E). {A = X; sqlite3ExprSpan(A,&B,&E); } term(A) ::= NULL(X). {A = sqlite3PExpr(pParse, @X, 0, 0, &X);} expr(A) ::= ID(X). {A = sqlite3PExpr(pParse, TK_ID, 0, 0, &X);} expr(A) ::= JOIN_KW(X). {A = sqlite3PExpr(pParse, TK_ID, 0, 0, &X);} expr(A) ::= nm(X) DOT nm(Y). { Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &X); Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &Y); A = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0); } expr(A) ::= nm(X) DOT nm(Y) DOT nm(Z). { Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &X); Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &Y); Expr *temp3 = sqlite3PExpr(pParse, TK_ID, 0, 0, &Z); Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3, 0); A = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0); } term(A) ::= INTEGER|FLOAT|BLOB(X). {A = sqlite3PExpr(pParse, @X, 0, 0, &X);} term(A) ::= STRING(X). {A = sqlite3PExpr(pParse, @X, 0, 0, &X);} expr(A) ::= REGISTER(X). {A = sqlite3RegisterExpr(pParse, &X);} expr(A) ::= VARIABLE(X). { Token *pToken = &X; Expr *pExpr = A = sqlite3PExpr(pParse, TK_VARIABLE, 0, 0, pToken); sqlite3ExprAssignVarNumber(pParse, pExpr); } expr(A) ::= expr(E) COLLATE id(C). { A = sqlite3ExprSetColl(pParse, E, &C); } %ifndef SQLITE_OMIT_CAST expr(A) ::= CAST(X) LP expr(E) AS typetoken(T) RP(Y). { A = sqlite3PExpr(pParse, TK_CAST, E, 0, &T); sqlite3ExprSpan(A,&X,&Y); } %endif SQLITE_OMIT_CAST expr(A) ::= ID(X) LP distinct(D) exprlist(Y) RP(E). { if( Y && Y->nExpr>SQLITE_MAX_FUNCTION_ARG ){ sqlite3ErrorMsg(pParse, "too many arguments on function %T", &X); } A = sqlite3ExprFunction(pParse, Y, &X); sqlite3ExprSpan(A,&X,&E); if( D && A ){ A->flags |= EP_Distinct; } } expr(A) ::= ID(X) LP STAR RP(E). { A = sqlite3ExprFunction(pParse, 0, &X); sqlite3ExprSpan(A,&X,&E); } term(A) ::= CTIME_KW(OP). { /* The CURRENT_TIME, CURRENT_DATE, and CURRENT_TIMESTAMP values are ** treated as functions that return constants */ A = sqlite3ExprFunction(pParse, 0,&OP); if( A ){ A->op = TK_CONST_FUNC; A->span = OP; } } expr(A) ::= expr(X) AND(OP) expr(Y). {A = sqlite3PExpr(pParse,@OP,X,Y,0);} expr(A) ::= expr(X) OR(OP) expr(Y). {A = sqlite3PExpr(pParse,@OP,X,Y,0);} expr(A) ::= expr(X) LT|GT|GE|LE(OP) expr(Y). {A = sqlite3PExpr(pParse,@OP,X,Y,0);} expr(A) ::= expr(X) EQ|NE(OP) expr(Y). {A = sqlite3PExpr(pParse,@OP,X,Y,0);} expr(A) ::= expr(X) BITAND|BITOR|LSHIFT|RSHIFT(OP) expr(Y). {A = sqlite3PExpr(pParse,@OP,X,Y,0);} expr(A) ::= expr(X) PLUS|MINUS(OP) expr(Y).{A = sqlite3PExpr(pParse,@OP,X,Y,0);} expr(A) ::= expr(X) STAR|SLASH|REM(OP) expr(Y). {A = sqlite3PExpr(pParse,@OP,X,Y,0);} expr(A) ::= expr(X) CONCAT(OP) expr(Y). {A = sqlite3PExpr(pParse,@OP,X,Y,0);} %type likeop {struct LikeOp} likeop(A) ::= LIKE_KW(X). {A.eOperator = X; A.not = 0;} likeop(A) ::= NOT LIKE_KW(X). {A.eOperator = X; A.not = 1;} likeop(A) ::= MATCH(X). {A.eOperator = X; A.not = 0;} likeop(A) ::= NOT MATCH(X). {A.eOperator = X; A.not = 1;} %type escape {Expr*} %destructor escape {sqlite3ExprDelete($$);} escape(X) ::= ESCAPE expr(A). [ESCAPE] {X = A;} escape(X) ::= . [ESCAPE] {X = 0;} expr(A) ::= expr(X) likeop(OP) expr(Y) escape(E). [LIKE_KW] { ExprList *pList; pList = sqlite3ExprListAppend(pParse,0, Y, 0); pList = sqlite3ExprListAppend(pParse,pList, X, 0); if( E ){ pList = sqlite3ExprListAppend(pParse,pList, E, 0); } A = sqlite3ExprFunction(pParse, pList, &OP.eOperator); if( OP.not ) A = sqlite3PExpr(pParse, TK_NOT, A, 0, 0); sqlite3ExprSpan(A, &X->span, &Y->span); if( A ) A->flags |= EP_InfixFunc; } expr(A) ::= expr(X) ISNULL|NOTNULL(E). { A = sqlite3PExpr(pParse, @E, X, 0, 0); sqlite3ExprSpan(A,&X->span,&E); } expr(A) ::= expr(X) IS NULL(E). { A = sqlite3PExpr(pParse, TK_ISNULL, X, 0, 0); sqlite3ExprSpan(A,&X->span,&E); } expr(A) ::= expr(X) NOT NULL(E). { A = sqlite3PExpr(pParse, TK_NOTNULL, X, 0, 0); sqlite3ExprSpan(A,&X->span,&E); } expr(A) ::= expr(X) IS NOT NULL(E). { A = sqlite3PExpr(pParse, TK_NOTNULL, X, 0, 0); sqlite3ExprSpan(A,&X->span,&E); } expr(A) ::= NOT|BITNOT(B) expr(X). { A = sqlite3PExpr(pParse, @B, X, 0, 0); sqlite3ExprSpan(A,&B,&X->span); } expr(A) ::= MINUS(B) expr(X). [UMINUS] { A = sqlite3PExpr(pParse, TK_UMINUS, X, 0, 0); sqlite3ExprSpan(A,&B,&X->span); } expr(A) ::= PLUS(B) expr(X). [UPLUS] { A = sqlite3PExpr(pParse, TK_UPLUS, X, 0, 0); sqlite3ExprSpan(A,&B,&X->span); } %type between_op {int} between_op(A) ::= BETWEEN. {A = 0;} between_op(A) ::= NOT BETWEEN. {A = 1;} expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] { ExprList *pList = sqlite3ExprListAppend(pParse,0, X, 0); pList = sqlite3ExprListAppend(pParse,pList, Y, 0); A = sqlite3PExpr(pParse, TK_BETWEEN, W, 0, 0); if( A ){ A->pList = pList; }else{ sqlite3ExprListDelete(pList); } if( N ) A = sqlite3PExpr(pParse, TK_NOT, A, 0, 0); sqlite3ExprSpan(A,&W->span,&Y->span); } %ifndef SQLITE_OMIT_SUBQUERY %type in_op {int} in_op(A) ::= IN. {A = 0;} in_op(A) ::= NOT IN. {A = 1;} expr(A) ::= expr(X) in_op(N) LP exprlist(Y) RP(E). [IN] { A = sqlite3PExpr(pParse, TK_IN, X, 0, 0); if( A ){ A->pList = Y; sqlite3ExprSetHeight(A); }else{ sqlite3ExprListDelete(Y); } if( N ) A = sqlite3PExpr(pParse, TK_NOT, A, 0, 0); sqlite3ExprSpan(A,&X->span,&E); } expr(A) ::= LP(B) select(X) RP(E). { A = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0); if( A ){ A->pSelect = X; sqlite3ExprSetHeight(A); }else{ sqlite3SelectDelete(X); } sqlite3ExprSpan(A,&B,&E); } expr(A) ::= expr(X) in_op(N) LP select(Y) RP(E). [IN] { A = sqlite3PExpr(pParse, TK_IN, X, 0, 0); if( A ){ A->pSelect = Y; sqlite3ExprSetHeight(A); }else{ sqlite3SelectDelete(Y); } if( N ) A = sqlite3PExpr(pParse, TK_NOT, A, 0, 0); sqlite3ExprSpan(A,&X->span,&E); } expr(A) ::= expr(X) in_op(N) nm(Y) dbnm(Z). [IN] { SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&Y,&Z); A = sqlite3PExpr(pParse, TK_IN, X, 0, 0); if( A ){ A->pSelect = sqlite3SelectNew(0,pSrc,0,0,0,0,0,0,0); sqlite3ExprSetHeight(A); }else{ sqlite3SrcListDelete(pSrc); } if( N ) A = sqlite3PExpr(pParse, TK_NOT, A, 0, 0); sqlite3ExprSpan(A,&X->span,Z.z?&Z:&Y); } expr(A) ::= EXISTS(B) LP select(Y) RP(E). { Expr *p = A = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0); if( p ){ p->pSelect = Y; sqlite3ExprSpan(p,&B,&E); sqlite3ExprSetHeight(A); }else{ sqlite3SelectDelete(Y); } } %endif SQLITE_OMIT_SUBQUERY /* CASE expressions */ expr(A) ::= CASE(C) case_operand(X) case_exprlist(Y) case_else(Z) END(E). { A = sqlite3PExpr(pParse, TK_CASE, X, Z, 0); if( A ){ A->pList = Y; sqlite3ExprSetHeight(A); }else{ sqlite3ExprListDelete(Y); } sqlite3ExprSpan(A, &C, &E); } %type case_exprlist {ExprList*} %destructor case_exprlist {sqlite3ExprListDelete($$);} case_exprlist(A) ::= case_exprlist(X) WHEN expr(Y) THEN expr(Z). { A = sqlite3ExprListAppend(pParse,X, Y, 0); A = sqlite3ExprListAppend(pParse,A, Z, 0); } case_exprlist(A) ::= WHEN expr(Y) THEN expr(Z). { A = sqlite3ExprListAppend(pParse,0, Y, 0); A = sqlite3ExprListAppend(pParse,A, Z, 0); } %type case_else {Expr*} %destructor case_else {sqlite3ExprDelete($$);} case_else(A) ::= ELSE expr(X). {A = X;} case_else(A) ::= . {A = 0;} %type case_operand {Expr*} %destructor case_operand {sqlite3ExprDelete($$);} case_operand(A) ::= expr(X). {A = X;} case_operand(A) ::= . {A = 0;} %type exprlist {ExprList*} %destructor exprlist {sqlite3ExprListDelete($$);} %type nexprlist {ExprList*} %destructor nexprlist {sqlite3ExprListDelete($$);} exprlist(A) ::= nexprlist(X). {A = X;} exprlist(A) ::= . {A = 0;} nexprlist(A) ::= nexprlist(X) COMMA expr(Y). {A = sqlite3ExprListAppend(pParse,X,Y,0);} nexprlist(A) ::= expr(Y). {A = sqlite3ExprListAppend(pParse,0,Y,0);} ///////////////////////////// The CREATE INDEX command /////////////////////// // cmd ::= CREATE(S) uniqueflag(U) INDEX ifnotexists(NE) nm(X) dbnm(D) ON nm(Y) LP idxlist(Z) RP(E). { sqlite3CreateIndex(pParse, &X, &D, sqlite3SrcListAppend(pParse->db,0,&Y,0), Z, U, &S, &E, SQLITE_SO_ASC, NE); } %type uniqueflag {int} uniqueflag(A) ::= UNIQUE. {A = OE_Abort;} uniqueflag(A) ::= . {A = OE_None;} %type idxlist {ExprList*} %destructor idxlist {sqlite3ExprListDelete($$);} %type idxlist_opt {ExprList*} %destructor idxlist_opt {sqlite3ExprListDelete($$);} %type idxitem {Token} idxlist_opt(A) ::= . {A = 0;} idxlist_opt(A) ::= LP idxlist(X) RP. {A = X;} idxlist(A) ::= idxlist(X) COMMA idxitem(Y) collate(C) sortorder(Z). { Expr *p = 0; if( C.n>0 ){ p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0); if( p ) p->pColl = sqlite3LocateCollSeq(pParse, (char*)C.z, C.n); } A = sqlite3ExprListAppend(pParse,X, p, &Y); sqlite3ExprListCheckLength(pParse, A, SQLITE_MAX_COLUMN, "index"); if( A ) A->a[A->nExpr-1].sortOrder = Z; } idxlist(A) ::= idxitem(Y) collate(C) sortorder(Z). { Expr *p = 0; if( C.n>0 ){ p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0); if( p ) p->pColl = sqlite3LocateCollSeq(pParse, (char*)C.z, C.n); } A = sqlite3ExprListAppend(pParse,0, p, &Y); sqlite3ExprListCheckLength(pParse, A, SQLITE_MAX_COLUMN, "index"); if( A ) A->a[A->nExpr-1].sortOrder = Z; } idxitem(A) ::= nm(X). {A = X;} %type collate {Token} collate(C) ::= . {C.z = 0; C.n = 0;} |
︙ | ︙ | |||
988 989 990 991 992 993 994 | } trigger_cmd_list(A) ::= . { A = 0; } %type trigger_cmd {TriggerStep*} %destructor trigger_cmd {sqlite3DeleteTriggerStep($$);} // UPDATE trigger_cmd(A) ::= UPDATE orconf(R) nm(X) SET setlist(Y) where_opt(Z). | | | | | | | | | 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 | } trigger_cmd_list(A) ::= . { A = 0; } %type trigger_cmd {TriggerStep*} %destructor trigger_cmd {sqlite3DeleteTriggerStep($$);} // UPDATE trigger_cmd(A) ::= UPDATE orconf(R) nm(X) SET setlist(Y) where_opt(Z). { A = sqlite3TriggerUpdateStep(pParse->db, &X, Y, Z, R); } // INSERT trigger_cmd(A) ::= insert_cmd(R) INTO nm(X) inscollist_opt(F) VALUES LP itemlist(Y) RP. {A = sqlite3TriggerInsertStep(pParse->db, &X, F, Y, 0, R);} trigger_cmd(A) ::= insert_cmd(R) INTO nm(X) inscollist_opt(F) select(S). {A = sqlite3TriggerInsertStep(pParse->db, &X, F, 0, S, R);} // DELETE trigger_cmd(A) ::= DELETE FROM nm(X) where_opt(Y). {A = sqlite3TriggerDeleteStep(pParse->db, &X, Y);} // SELECT trigger_cmd(A) ::= select(X). {A = sqlite3TriggerSelectStep(pParse->db, X); } // The special RAISE expression that may occur in trigger programs expr(A) ::= RAISE(X) LP IGNORE RP(Y). { A = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0); if( A ){ A->iColumn = OE_Ignore; sqlite3ExprSpan(A, &X, &Y); } } expr(A) ::= RAISE(X) LP raisetype(T) COMMA nm(Z) RP(Y). { A = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &Z); if( A ) { A->iColumn = T; sqlite3ExprSpan(A, &X, &Y); } } %endif !SQLITE_OMIT_TRIGGER |
︙ | ︙ |
Changes to src/pragma.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2003 April 6 ** ** 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 contains code used to implement the PRAGMA command. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2003 April 6 ** ** 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 contains code used to implement the PRAGMA command. ** ** $Id: pragma.c,v 1.143 2007/08/16 04:30:40 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> /* Ignore this whole file if pragmas are disabled */ |
︙ | ︙ | |||
260 261 262 263 264 265 266 | /* If the temp database has been explicitly named as part of the ** pragma, make sure it is open. */ if( iDb==1 && sqlite3OpenTempDatabase(pParse) ){ return; } | | | | | 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 | /* If the temp database has been explicitly named as part of the ** pragma, make sure it is open. */ if( iDb==1 && sqlite3OpenTempDatabase(pParse) ){ return; } zLeft = sqlite3NameFromToken(db, pId); if( !zLeft ) return; if( minusFlag ){ zRight = sqlite3MPrintf(db, "-%T", pValue); }else{ zRight = sqlite3NameFromToken(db, pValue); } zDb = ((iDb>0)?pDb->zName:0); if( sqlite3AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, zDb) ){ goto pragma_out; } |
︙ | ︙ | |||
563 564 565 566 567 568 569 | } if( TEMP_STORE==0 || (TEMP_STORE==1 && db->temp_store<=1) || (TEMP_STORE==2 && db->temp_store==1) ){ invalidateTempStorage(pParse); } | | | 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 | } if( TEMP_STORE==0 || (TEMP_STORE==1 && db->temp_store<=1) || (TEMP_STORE==2 && db->temp_store==1) ){ invalidateTempStorage(pParse); } sqlite3_free(sqlite3_temp_directory); if( zRight[0] ){ sqlite3_temp_directory = zRight; zRight = 0; }else{ sqlite3_temp_directory = 0; } } |
︙ | ︙ | |||
1169 1170 1171 1172 1173 1174 1175 | if( db->autoCommit ){ sqlite3BtreeSetSafetyLevel(pDb->pBt, pDb->safety_level, (db->flags&SQLITE_FullFSync)!=0); } #endif } pragma_out: | | | | 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 | if( db->autoCommit ){ sqlite3BtreeSetSafetyLevel(pDb->pBt, pDb->safety_level, (db->flags&SQLITE_FullFSync)!=0); } #endif } pragma_out: sqlite3_free(zLeft); sqlite3_free(zRight); } #endif /* SQLITE_OMIT_PRAGMA || SQLITE_OMIT_PARSER */ |
Changes to src/prepare.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the implementation of the sqlite3_prepare() ** interface, and routines that contribute to loading the database schema ** from disk. ** | | | | 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 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the implementation of the sqlite3_prepare() ** interface, and routines that contribute to loading the database schema ** from disk. ** ** $Id: prepare.c,v 1.53 2007/08/16 04:30:40 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> /* ** Fill the InitData structure with an error message that indicates ** that the database is corrupt. */ static void corruptSchema(InitData *pData, const char *zExtra){ if( !pData->db->mallocFailed ){ sqlite3SetString(pData->pzErrMsg, "malformed database schema", zExtra!=0 && zExtra[0]!=0 ? " - " : (char*)0, zExtra, (char*)0); } pData->rc = SQLITE_CORRUPT; } /* |
︙ | ︙ | |||
46 47 48 49 50 51 52 | int sqlite3InitCallback(void *pInit, int argc, char **argv, char **azColName){ InitData *pData = (InitData*)pInit; sqlite3 *db = pData->db; int iDb = pData->iDb; pData->rc = SQLITE_OK; DbClearProperty(db, iDb, DB_Empty); | | | 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | int sqlite3InitCallback(void *pInit, int argc, char **argv, char **azColName){ InitData *pData = (InitData*)pInit; sqlite3 *db = pData->db; int iDb = pData->iDb; pData->rc = SQLITE_OK; DbClearProperty(db, iDb, DB_Empty); if( db->mallocFailed ){ corruptSchema(pData, 0); return SQLITE_NOMEM; } assert( argc==3 ); if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */ if( argv[1]==0 ){ |
︙ | ︙ | |||
75 76 77 78 79 80 81 | db->init.newTnum = atoi(argv[1]); rc = sqlite3_exec(db, argv[2], 0, 0, &zErr); db->init.iDb = 0; assert( rc!=SQLITE_OK || zErr==0 ); if( SQLITE_OK!=rc ){ pData->rc = rc; if( rc==SQLITE_NOMEM ){ | | | 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | db->init.newTnum = atoi(argv[1]); rc = sqlite3_exec(db, argv[2], 0, 0, &zErr); db->init.iDb = 0; assert( rc!=SQLITE_OK || zErr==0 ); if( SQLITE_OK!=rc ){ pData->rc = rc; if( rc==SQLITE_NOMEM ){ db->mallocFailed = 1; }else if( rc!=SQLITE_INTERRUPT ){ corruptSchema(pData, zErr); } sqlite3_free(zErr); return 1; } }else{ |
︙ | ︙ | |||
293 294 295 296 297 298 299 | zSql = sqlite3MPrintf( "SELECT name, rootpage, sql FROM '%q'.%s", db->aDb[iDb].zName, zMasterName); sqlite3SafetyOff(db); rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); if( rc==SQLITE_ABORT ) rc = initData.rc; sqlite3SafetyOn(db); | | | | 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 | zSql = sqlite3MPrintf( "SELECT name, rootpage, sql FROM '%q'.%s", db->aDb[iDb].zName, zMasterName); sqlite3SafetyOff(db); rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); if( rc==SQLITE_ABORT ) rc = initData.rc; sqlite3SafetyOn(db); sqlite3_free(zSql); #ifndef SQLITE_OMIT_ANALYZE if( rc==SQLITE_OK ){ sqlite3AnalysisLoad(db, iDb); } #endif sqlite3BtreeCloseCursor(curMain); } if( db->mallocFailed ){ /* sqlite3SetString(pzErrMsg, "out of memory", (char*)0); */ rc = SQLITE_NOMEM; sqlite3ResetInternalSchema(db, 0); } if( rc==SQLITE_OK || (db->flags&SQLITE_RecoveryMode)){ /* Black magic: If the SQLITE_RecoveryMode flag is set, then consider ** the schema loaded, even if errors occured. In this situation the |
︙ | ︙ | |||
460 461 462 463 464 465 466 | ){ Parse sParse; char *zErrMsg = 0; int rc = SQLITE_OK; int i; /* Assert that malloc() has not failed */ | | | 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 | ){ Parse sParse; char *zErrMsg = 0; int rc = SQLITE_OK; int i; /* Assert that malloc() has not failed */ assert( !db->mallocFailed ); assert( ppStmt ); *ppStmt = 0; if( sqlite3SafetyOn(db) ){ return SQLITE_MISUSE; } |
︙ | ︙ | |||
488 489 490 491 492 493 494 | memset(&sParse, 0, sizeof(sParse)); sParse.db = db; if( nBytes>=0 && zSql[nBytes]!=0 ){ char *zSqlCopy; if( nBytes>SQLITE_MAX_SQL_LENGTH ){ return SQLITE_TOOBIG; } | | | | | | 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 | memset(&sParse, 0, sizeof(sParse)); sParse.db = db; if( nBytes>=0 && zSql[nBytes]!=0 ){ char *zSqlCopy; if( nBytes>SQLITE_MAX_SQL_LENGTH ){ return SQLITE_TOOBIG; } zSqlCopy = sqlite3DbStrNDup(db, zSql, nBytes); if( zSqlCopy ){ sqlite3RunParser(&sParse, zSqlCopy, &zErrMsg); sqlite3_free(zSqlCopy); } sParse.zTail = &zSql[nBytes]; }else{ sqlite3RunParser(&sParse, zSql, &zErrMsg); } if( db->mallocFailed ){ sParse.rc = SQLITE_NOMEM; } if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK; if( sParse.checkSchema && !schemaIsValid(db) ){ sParse.rc = SQLITE_SCHEMA; } if( sParse.rc==SQLITE_SCHEMA ){ sqlite3ResetInternalSchema(db, 0); } if( db->mallocFailed ){ sParse.rc = SQLITE_NOMEM; } if( pzTail ){ *pzTail = sParse.zTail; } rc = sParse.rc; |
︙ | ︙ | |||
541 542 543 544 545 546 547 | if( sqlite3SafetyOff(db) ){ rc = SQLITE_MISUSE; } if( saveSqlFlag ){ sqlite3VdbeSetSql(sParse.pVdbe, zSql, sParse.zTail - zSql); } | | | | 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 | if( sqlite3SafetyOff(db) ){ rc = SQLITE_MISUSE; } if( saveSqlFlag ){ sqlite3VdbeSetSql(sParse.pVdbe, zSql, sParse.zTail - zSql); } if( rc!=SQLITE_OK || db->mallocFailed ){ sqlite3_finalize((sqlite3_stmt*)sParse.pVdbe); assert(!(*ppStmt)); }else{ *ppStmt = (sqlite3_stmt*)sParse.pVdbe; } if( zErrMsg ){ sqlite3Error(db, rc, "%s", zErrMsg); sqlite3_free(zErrMsg); }else{ sqlite3Error(db, rc, 0); } rc = sqlite3ApiExit(db, rc); sqlite3ReleaseThreadData(); assert( (rc&db->errMask)==rc ); |
︙ | ︙ | |||
657 658 659 660 661 662 663 | ** equivalent pointer into the UTF-16 string by counting the unicode ** characters between zSql8 and zTail8, and then returning a pointer ** the same number of characters into the UTF-16 string. */ int chars_parsed = sqlite3Utf8CharLen(zSql8, zTail8-zSql8); *pzTail = (u8 *)zSql + sqlite3Utf16ByteLen(zSql, chars_parsed); } | | | 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 | ** equivalent pointer into the UTF-16 string by counting the unicode ** characters between zSql8 and zTail8, and then returning a pointer ** the same number of characters into the UTF-16 string. */ int chars_parsed = sqlite3Utf8CharLen(zSql8, zTail8-zSql8); *pzTail = (u8 *)zSql + sqlite3Utf16ByteLen(zSql, chars_parsed); } sqlite3_free(zSql8); return sqlite3ApiExit(db, rc); } /* ** Two versions of the official API. Legacy and new use. In the legacy ** version, the original SQL text is not saved in the prepared statement ** and so if a schema change occurs, SQLITE_SCHEMA is returned by |
︙ | ︙ |
Changes to src/printf.c.
︙ | ︙ | |||
623 624 625 626 627 628 629 | if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)"); for(i=n=0; (ch=escarg[i])!=0; i++){ if( ch==q ) n++; } needQuote = !isnull && xtype==etSQLESCAPE2; n += i + 1 + needQuote*2; if( n>etBUFSIZE ){ | | | 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 | if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)"); for(i=n=0; (ch=escarg[i])!=0; i++){ if( ch==q ) n++; } needQuote = !isnull && xtype==etSQLESCAPE2; n += i + 1 + needQuote*2; if( n>etBUFSIZE ){ bufpt = zExtra = sqlite3_malloc( n ); if( bufpt==0 ) return -1; }else{ bufpt = buf; } j = 0; if( needQuote ) bufpt[j++] = q; for(i=0; (ch=escarg[i])!=0; i++){ |
︙ | ︙ | |||
725 726 727 728 729 730 731 | ** ** This routine add nNewChar characters of text in zNewText to ** the sgMprintf structure pointed to by "arg". */ static void mout(void *arg, const char *zNewText, int nNewChar){ struct sgMprintf *pM = (struct sgMprintf*)arg; pM->nTotal += nNewChar; | > | | | | | | | | > > | | | | | | | | > > | | | | | | < | 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 | ** ** This routine add nNewChar characters of text in zNewText to ** the sgMprintf structure pointed to by "arg". */ static void mout(void *arg, const char *zNewText, int nNewChar){ struct sgMprintf *pM = (struct sgMprintf*)arg; pM->nTotal += nNewChar; if( pM->zText ){ if( pM->nChar + nNewChar + 1 > pM->nAlloc ){ if( pM->xRealloc==0 ){ nNewChar = pM->nAlloc - pM->nChar - 1; }else{ int nAlloc = pM->nChar + nNewChar*2 + 1; if( pM->zText==pM->zBase ){ pM->zText = pM->xRealloc(0, nAlloc); if( pM->zText==0 ){ return; }else if( pM->nChar ){ memcpy(pM->zText, pM->zBase, pM->nChar); } }else{ char *zNew; zNew = pM->xRealloc(pM->zText, nAlloc); if( zNew ){ pM->zText = zNew; }else{ pM->xRealloc(pM->zText, 0); pM->zText = 0; return; } } pM->nAlloc = nAlloc; } } if( nNewChar>0 ){ memcpy(&pM->zText[pM->nChar], zNewText, nNewChar); pM->nChar += nNewChar; } pM->zText[pM->nChar] = 0; } } |
︙ | ︙ | |||
794 795 796 797 798 799 800 | return sM.zText; } /* ** Realloc that is a real function, not a macro. */ static void *printf_realloc(void *old, int size){ | | | > | > > > > | > > > | 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 | return sM.zText; } /* ** Realloc that is a real function, not a macro. */ static void *printf_realloc(void *old, int size){ return sqlite3_realloc(old,size); } /* ** Print into memory obtained from sqliteMalloc(). Use the internal ** %-conversion extensions. */ char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list ap){ char *z; char zBase[SQLITE_PRINT_BUF_SIZE]; z = base_vprintf(printf_realloc, 1, zBase, sizeof(zBase), zFormat, ap); if( z==0 && db!=0 ){ db->mallocFailed = 1; } return z; } /* ** Print into memory obtained from sqliteMalloc(). Use the internal ** %-conversion extensions. */ char *sqlite3MPrintf(sqlite3 *db, const char *zFormat, ...){ va_list ap; char *z; char zBase[SQLITE_PRINT_BUF_SIZE]; va_start(ap, zFormat); z = base_vprintf(printf_realloc, 1, zBase, sizeof(zBase), zFormat, ap); va_end(ap); if( z==0 && db!=0 ){ db->mallocFailed = 1; } return z; } /* ** Print into memory obtained from sqlite3_malloc(). Omit the internal ** %-conversion extensions. */ |
︙ | ︙ |
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.355 2007/08/16 04:30:40 drh Exp $ */ #include "sqliteInt.h" /* ** Delete all the content of a Select structure but do not deallocate ** the select structure itself. |
︙ | ︙ | |||
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | /* ** Allocate a new Select structure and return a pointer to that ** structure. */ Select *sqlite3SelectNew( ExprList *pEList, /* which columns to include in the result */ SrcList *pSrc, /* the FROM clause -- which tables to scan */ Expr *pWhere, /* the WHERE clause */ ExprList *pGroupBy, /* the GROUP BY clause */ Expr *pHaving, /* the HAVING clause */ ExprList *pOrderBy, /* the ORDER BY clause */ int isDistinct, /* true if the DISTINCT keyword is present */ Expr *pLimit, /* LIMIT value. NULL means not used */ Expr *pOffset /* OFFSET value. NULL means no offset */ ){ Select *pNew; Select standin; | > > | | | 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | /* ** Allocate a new Select structure and return a pointer to that ** structure. */ Select *sqlite3SelectNew( Parse *pParse, /* Parsing context */ ExprList *pEList, /* which columns to include in the result */ SrcList *pSrc, /* the FROM clause -- which tables to scan */ Expr *pWhere, /* the WHERE clause */ ExprList *pGroupBy, /* the GROUP BY clause */ Expr *pHaving, /* the HAVING clause */ ExprList *pOrderBy, /* the ORDER BY clause */ int isDistinct, /* true if the DISTINCT keyword is present */ Expr *pLimit, /* LIMIT value. NULL means not used */ Expr *pOffset /* OFFSET value. NULL means no offset */ ){ Select *pNew; Select standin; sqlite3 *db = pParse->db; pNew = sqlite3DbMallocZero(db, sizeof(*pNew) ); assert( !pOffset || pLimit ); /* Can't have OFFSET without LIMIT. */ if( pNew==0 ){ pNew = &standin; memset(pNew, 0, sizeof(*pNew)); } if( pEList==0 ){ pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(TK_ALL,0,0,0), 0); } pNew->pEList = pEList; pNew->pSrc = pSrc; pNew->pWhere = pWhere; pNew->pGroupBy = pGroupBy; pNew->pHaving = pHaving; pNew->pOrderBy = pOrderBy; |
︙ | ︙ | |||
85 86 87 88 89 90 91 | /* ** Delete the given Select structure and all of its substructures. */ void sqlite3SelectDelete(Select *p){ if( p ){ clearSelect(p); | | | 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | /* ** Delete the given Select structure and all of its substructures. */ void sqlite3SelectDelete(Select *p){ if( p ){ clearSelect(p); sqlite3_free(p); } } /* ** Given 1 to 3 identifiers preceeding the JOIN keyword, determine the ** type of join. Return an integer constant that expresses that type ** in terms of the following bit values: |
︙ | ︙ | |||
198 199 200 201 202 203 204 | p->n = strlen((char *)p->z); } } /* ** Create an expression node for an identifier with the name of zName */ | | | > | | | | | | | | | 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 | p->n = strlen((char *)p->z); } } /* ** Create an expression node for an identifier with the name of zName */ Expr *sqlite3CreateIdExpr(Parse *pParse, const char *zName){ Token dummy; setToken(&dummy, zName); return sqlite3PExpr(pParse, TK_ID, 0, 0, &dummy); } /* ** Add a term to the WHERE expression in *ppExpr that requires the ** zCol column to be equal in the two tables pTab1 and pTab2. */ static void addWhereTerm( Parse *pParse, /* Parsing context */ const char *zCol, /* Name of the column */ const Table *pTab1, /* First table */ const char *zAlias1, /* Alias for first table. May be NULL */ const Table *pTab2, /* Second table */ const char *zAlias2, /* Alias for second table. May be NULL */ 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(pParse, zCol); pE2a = sqlite3CreateIdExpr(pParse, zCol); if( zAlias1==0 ){ zAlias1 = pTab1->zName; } pE1b = sqlite3CreateIdExpr(pParse, zAlias1); if( zAlias2==0 ){ zAlias2 = pTab2->zName; } pE2b = sqlite3CreateIdExpr(pParse, zAlias2); pE1c = sqlite3PExpr(pParse, TK_DOT, pE1b, pE1a, 0); pE2c = sqlite3PExpr(pParse, TK_DOT, pE2b, pE2a, 0); pE = sqlite3DbExpr(pParse, TK_EQ, pE1c, pE2c, 0); if( pE ){ ExprSetProperty(pE, EP_FromJoin); pE->iRightJoinTable = iRightJoinTable; } pE = sqlite3ExprAnd(pParse->db,*ppExpr, pE); if( pE ){ *ppExpr = pE; } } /* ** Set the EP_FromJoin property on all terms of the given expression. |
︙ | ︙ | |||
342 343 344 345 346 347 348 | } /* Add the ON clause to the end of the WHERE clause, connected by ** an AND operator. */ if( pRight->pOn ){ setJoinExpr(pRight->pOn, pRight->iCursor); | | | 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 | } /* Add the ON clause to the end of the WHERE clause, connected by ** an AND operator. */ if( pRight->pOn ){ setJoinExpr(pRight->pOn, pRight->iCursor); p->pWhere = sqlite3ExprAnd(pParse->db, p->pWhere, pRight->pOn); pRight->pOn = 0; } /* Create extra terms on the WHERE clause for each column named ** in the USING clause. Example: If the two tables to be joined are ** A and B and the USING clause names X, Y, and Z, then add this ** to the WHERE clause: A.X=B.X AND A.Y=B.Y AND A.Z=B.Z |
︙ | ︙ | |||
685 686 687 688 689 690 691 | sqlite3 *db = pParse->db; int nExpr; KeyInfo *pInfo; struct ExprList_item *pItem; int i; nExpr = pList->nExpr; | | | 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 | sqlite3 *db = pParse->db; int nExpr; KeyInfo *pInfo; struct ExprList_item *pItem; int i; nExpr = pList->nExpr; pInfo = sqlite3DbMallocZero(db, sizeof(*pInfo) + nExpr*(sizeof(CollSeq*)+1) ); if( pInfo ){ pInfo->aSortOrder = (u8*)&pInfo->aColl[nExpr]; pInfo->nField = nExpr; pInfo->enc = ENC(db); for(i=0, pItem=pList->a; i<nExpr; i++, pItem++){ CollSeq *pColl; pColl = sqlite3ExprCollSeq(pParse, pItem->pExpr); |
︙ | ︙ | |||
988 989 990 991 992 993 994 | /* If this is an EXPLAIN, skip this step */ if( pParse->explain ){ return; } #endif assert( v!=0 ); | | | 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 | /* If this is an EXPLAIN, skip this step */ if( pParse->explain ){ return; } #endif assert( v!=0 ); if( pParse->colNamesSet || v==0 || db->mallocFailed ) return; pParse->colNamesSet = 1; fullNames = (db->flags & SQLITE_FullColNames)!=0; shortNames = (db->flags & SQLITE_ShortColNames)!=0; sqlite3VdbeSetNumCols(v, pEList->nExpr); for(i=0; i<pEList->nExpr; i++){ Expr *p; p = pEList->a[i].pExpr; |
︙ | ︙ | |||
1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 | ** the result set of that SELECT. */ Table *sqlite3ResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){ Table *pTab; int i, j; ExprList *pEList; Column *aCol, *pCol; while( pSelect->pPrior ) pSelect = pSelect->pPrior; if( prepSelectStmt(pParse, pSelect) ){ return 0; } if( sqlite3SelectResolve(pParse, pSelect, 0) ){ return 0; } | > | | | | | | | | | | 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 | ** the result set of that SELECT. */ Table *sqlite3ResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){ Table *pTab; int i, j; ExprList *pEList; Column *aCol, *pCol; sqlite3 *db = pParse->db; while( pSelect->pPrior ) pSelect = pSelect->pPrior; if( prepSelectStmt(pParse, pSelect) ){ return 0; } if( sqlite3SelectResolve(pParse, pSelect, 0) ){ return 0; } pTab = sqlite3DbMallocZero(db, sizeof(Table) ); if( pTab==0 ){ return 0; } pTab->nRef = 1; pTab->zName = zTabName ? sqlite3DbStrDup(db, zTabName) : 0; pEList = pSelect->pEList; pTab->nCol = pEList->nExpr; assert( pTab->nCol>0 ); pTab->aCol = aCol = sqlite3DbMallocZero(db, sizeof(pTab->aCol[0])*pTab->nCol); for(i=0, pCol=aCol; i<pTab->nCol; i++, pCol++){ Expr *p, *pR; char *zType; char *zName; int nName; CollSeq *pColl; int cnt; NameContext sNC; /* Get an appropriate name for the column */ p = pEList->a[i].pExpr; assert( p->pRight==0 || p->pRight->token.z==0 || p->pRight->token.z[0]!=0 ); if( (zName = pEList->a[i].zName)!=0 ){ /* If the column contains an "AS <name>" phrase, use <name> as the name */ zName = sqlite3DbStrDup(db, zName); }else if( p->op==TK_DOT && (pR=p->pRight)!=0 && pR->token.z && pR->token.z[0] ){ /* For columns of the from A.B use B as the name */ zName = sqlite3MPrintf(db, "%T", &pR->token); }else if( p->span.z && p->span.z[0] ){ /* Use the original text of the column expression as its name */ zName = sqlite3MPrintf(db, "%T", &p->span); }else{ /* If all else fails, make up a name */ zName = sqlite3MPrintf(db, "column%d", i+1); } sqlite3Dequote(zName); if( db->mallocFailed ){ sqlite3_free(zName); sqlite3DeleteTable(pTab); return 0; } /* Make sure the column name is unique. If the name is not unique, ** append a integer to the name so that it becomes unique. */ |
︙ | ︙ | |||
1143 1144 1145 1146 1147 1148 1149 | pCol->zName = zName; /* Get the typename, type affinity, and collating sequence for the ** column. */ memset(&sNC, 0, sizeof(sNC)); sNC.pSrcList = pSelect->pSrc; | | | | 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 | pCol->zName = zName; /* Get the typename, type affinity, and collating sequence for the ** column. */ memset(&sNC, 0, sizeof(sNC)); sNC.pSrcList = pSelect->pSrc; zType = sqlite3DbStrDup(db, columnType(&sNC, p, 0, 0, 0)); pCol->zType = zType; pCol->affinity = sqlite3ExprAffinity(p); pColl = sqlite3ExprCollSeq(pParse, p); if( pColl ){ pCol->zColl = sqlite3DbStrDup(db, pColl->zName); } } pTab->iPKey = -1; return pTab; } /* |
︙ | ︙ | |||
1186 1187 1188 1189 1190 1191 1192 1193 | ** in pParse and return non-zero. */ static int prepSelectStmt(Parse *pParse, Select *p){ int i, j, k, rc; SrcList *pTabList; ExprList *pEList; struct SrcList_item *pFrom; | > | | 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 | ** in pParse and return non-zero. */ static int prepSelectStmt(Parse *pParse, Select *p){ int i, j, k, rc; SrcList *pTabList; ExprList *pEList; struct SrcList_item *pFrom; sqlite3 *db = pParse->db; if( p==0 || p->pSrc==0 || db->mallocFailed ){ return 1; } pTabList = p->pSrc; pEList = p->pEList; /* Make sure cursor numbers have been assigned to all entries in ** the FROM clause of the SELECT statement. |
︙ | ︙ | |||
1251 1252 1253 1254 1255 1256 1257 | } /* If pFrom->pSelect!=0 it means we are dealing with a ** view within a view. The SELECT structure has already been ** copied by the outer view so we can skip the copy step here ** in the inner view. */ if( pFrom->pSelect==0 ){ | | | 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 | } /* If pFrom->pSelect!=0 it means we are dealing with a ** view within a view. The SELECT structure has already been ** copied by the outer view so we can skip the copy step here ** in the inner view. */ if( pFrom->pSelect==0 ){ pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect); } } #endif } } /* Process NATURAL keywords, and ON and USING clauses of joins. |
︙ | ︙ | |||
1297 1298 1299 1300 1301 1302 1303 | for(k=0; k<pEList->nExpr; k++){ Expr *pE = a[k].pExpr; if( pE->op!=TK_ALL && (pE->op!=TK_DOT || pE->pRight==0 || pE->pRight->op!=TK_ALL) ){ /* This particular expression does not need to be expanded. */ | | | | 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 | for(k=0; k<pEList->nExpr; k++){ Expr *pE = a[k].pExpr; if( pE->op!=TK_ALL && (pE->op!=TK_DOT || pE->pRight==0 || pE->pRight->op!=TK_ALL) ){ /* This particular expression does not need to be expanded. */ pNew = sqlite3ExprListAppend(pParse, pNew, a[k].pExpr, 0); if( pNew ){ pNew->a[pNew->nExpr-1].zName = a[k].zName; }else{ rc = 1; } a[k].pExpr = 0; a[k].zName = 0; }else{ /* This expression is a "*" or a "TABLE.*" and needs to be ** expanded. */ int tableSeen = 0; /* Set to 1 when TABLE matches */ char *zTName; /* text of name of TABLE */ if( pE->op==TK_DOT && pE->pLeft ){ zTName = sqlite3NameFromToken(db, &pE->pLeft->token); }else{ zTName = 0; } for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){ Table *pTab = pFrom->pTab; char *zTabName = pFrom->zAlias; if( zTabName==0 || zTabName[0]==0 ){ |
︙ | ︙ | |||
1372 1373 1374 1375 1376 1377 1378 | pExpr->token.dyn = 0; }else{ pExpr = pRight; pExpr->span = pExpr->token; pExpr->span.dyn = 0; } if( longNames ){ | | | | | | 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 | pExpr->token.dyn = 0; }else{ pExpr = pRight; pExpr->span = pExpr->token; pExpr->span.dyn = 0; } if( longNames ){ pNew = sqlite3ExprListAppend(pParse, pNew, pExpr, &pExpr->span); }else{ pNew = sqlite3ExprListAppend(pParse, pNew, pExpr, &pRight->token); } } } if( !tableSeen ){ if( zTName ){ sqlite3ErrorMsg(pParse, "no such table: %s", zTName); }else{ sqlite3ErrorMsg(pParse, "no tables specified"); } rc = 1; } sqlite3_free(zTName); } } sqlite3ExprListDelete(pEList); p->pEList = pNew; } if( p->pEList && p->pEList->nExpr>SQLITE_MAX_COLUMN ){ sqlite3ErrorMsg(pParse, "too many columns in result set"); rc = SQLITE_ERROR; } if( db->mallocFailed ){ rc = SQLITE_NOMEM; } return rc; } #ifndef SQLITE_OMIT_COMPOUND_SELECT /* |
︙ | ︙ | |||
1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 | ExprList *pOrderBy, /* The ORDER BY values to match against columns */ int iTable, /* Insert this value in iTable */ int mustComplete /* If TRUE all ORDER BYs must match */ ){ int nErr = 0; int i, j; ExprList *pEList; if( pSelect==0 || pOrderBy==0 ) return 1; if( mustComplete ){ for(i=0; i<pOrderBy->nExpr; i++){ pOrderBy->a[i].done = 0; } } if( prepSelectStmt(pParse, pSelect) ){ return 1; | > | 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 | ExprList *pOrderBy, /* The ORDER BY values to match against columns */ int iTable, /* Insert this value in iTable */ int mustComplete /* If TRUE all ORDER BYs must match */ ){ int nErr = 0; int i, j; ExprList *pEList; sqlite3 *db = pParse->db; if( pSelect==0 || pOrderBy==0 ) return 1; if( mustComplete ){ for(i=0; i<pOrderBy->nExpr; i++){ pOrderBy->a[i].done = 0; } } if( prepSelectStmt(pParse, pSelect) ){ return 1; |
︙ | ︙ | |||
1458 1459 1460 1461 1462 1463 1464 | iCol, pEList->nExpr); nErr++; break; } if( !mustComplete ) continue; iCol--; } | | | | | | | 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 | iCol, pEList->nExpr); nErr++; break; } if( !mustComplete ) continue; iCol--; } if( iCol<0 && (zLabel = sqlite3NameFromToken(db, &pE->token))!=0 ){ for(j=0, pItem=pEList->a; j<pEList->nExpr; j++, pItem++){ char *zName; int isMatch; if( pItem->zName ){ zName = sqlite3DbStrDup(db, pItem->zName); }else{ zName = sqlite3NameFromToken(db, &pItem->pExpr->token); } isMatch = zName && sqlite3StrICmp(zName, zLabel)==0; sqlite3_free(zName); if( isMatch ){ iCol = j; break; } } sqlite3_free(zLabel); } if( iCol>=0 ){ pE->op = TK_COLUMN; pE->iColumn = iCol; pE->iTable = iTable; pE->iAgg = -1; pOrderBy->a[i].done = 1; |
︙ | ︙ | |||
1958 1959 1960 1961 1962 1963 1964 | Select *pLoop; /* For looping through SELECT statements */ int nKeyCol; /* Number of entries in pKeyInfo->aCol[] */ CollSeq **apColl; /* For looping through pKeyInfo->aColl[] */ CollSeq **aCopy; /* A copy of pKeyInfo->aColl[] */ assert( p->pRightmost==p ); nKeyCol = nCol + (pOrderBy ? pOrderBy->nExpr : 0); | > | | 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 | Select *pLoop; /* For looping through SELECT statements */ int nKeyCol; /* Number of entries in pKeyInfo->aCol[] */ CollSeq **apColl; /* For looping through pKeyInfo->aColl[] */ CollSeq **aCopy; /* A copy of pKeyInfo->aColl[] */ assert( p->pRightmost==p ); nKeyCol = nCol + (pOrderBy ? pOrderBy->nExpr : 0); pKeyInfo = sqlite3DbMallocZero(pParse->db, sizeof(*pKeyInfo)+nKeyCol*(sizeof(CollSeq*) + 1)); if( !pKeyInfo ){ rc = SQLITE_NOMEM; goto multi_select_end; } pKeyInfo->enc = ENC(pParse->db); pKeyInfo->nField = nCol; |
︙ | ︙ | |||
2033 2034 2035 2036 2037 2038 2039 | sqlite3VdbeChangeP2(v, addr, p->pOrderBy->nExpr+2); pKeyInfo->nField = nOrderByExpr; sqlite3VdbeChangeP3(v, addr, (char*)pKeyInfo, P3_KEYINFO_HANDOFF); pKeyInfo = 0; generateSortTail(pParse, p, v, p->pEList->nExpr, eDest, iParm); } | | > > > > | | > > | > | | | | | | | | | | | > > > > > | | > > > > > | | | | | | | 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 | sqlite3VdbeChangeP2(v, addr, p->pOrderBy->nExpr+2); pKeyInfo->nField = nOrderByExpr; sqlite3VdbeChangeP3(v, addr, (char*)pKeyInfo, P3_KEYINFO_HANDOFF); pKeyInfo = 0; generateSortTail(pParse, p, v, p->pEList->nExpr, eDest, iParm); } sqlite3_free(pKeyInfo); } multi_select_end: return rc; } #endif /* SQLITE_OMIT_COMPOUND_SELECT */ #ifndef SQLITE_OMIT_VIEW /* Forward Declarations */ static void substExprList(sqlite3*, ExprList*, int, ExprList*); static void substSelect(sqlite3*, Select *, int, ExprList *); /* ** Scan through the expression pExpr. Replace every reference to ** a column in table number iTable with a copy of the iColumn-th ** entry in pEList. (But leave references to the ROWID column ** unchanged.) ** ** This routine is part of the flattening procedure. A subquery ** whose result set is defined by pEList appears as entry in the ** FROM clause of a SELECT such that the VDBE cursor assigned to that ** FORM clause entry is iTable. This routine make the necessary ** changes to pExpr so that it refers directly to the source table ** of the subquery rather the result set of the subquery. */ static void substExpr( sqlite3 *db, /* Report malloc errors to this connection */ Expr *pExpr, /* Expr in which substitution occurs */ int iTable, /* Table to be substituted */ ExprList *pEList /* Substitute expressions */ ){ if( pExpr==0 ) return; if( pExpr->op==TK_COLUMN && pExpr->iTable==iTable ){ if( pExpr->iColumn<0 ){ pExpr->op = TK_NULL; }else{ Expr *pNew; assert( pEList!=0 && pExpr->iColumn<pEList->nExpr ); assert( pExpr->pLeft==0 && pExpr->pRight==0 && pExpr->pList==0 ); pNew = pEList->a[pExpr->iColumn].pExpr; assert( pNew!=0 ); pExpr->op = pNew->op; assert( pExpr->pLeft==0 ); pExpr->pLeft = sqlite3ExprDup(db, pNew->pLeft); assert( pExpr->pRight==0 ); pExpr->pRight = sqlite3ExprDup(db, pNew->pRight); assert( pExpr->pList==0 ); pExpr->pList = sqlite3ExprListDup(db, pNew->pList); pExpr->iTable = pNew->iTable; pExpr->pTab = pNew->pTab; pExpr->iColumn = pNew->iColumn; pExpr->iAgg = pNew->iAgg; sqlite3TokenCopy(db, &pExpr->token, &pNew->token); sqlite3TokenCopy(db, &pExpr->span, &pNew->span); pExpr->pSelect = sqlite3SelectDup(db, pNew->pSelect); pExpr->flags = pNew->flags; } }else{ substExpr(db, pExpr->pLeft, iTable, pEList); substExpr(db, pExpr->pRight, iTable, pEList); substSelect(db, pExpr->pSelect, iTable, pEList); substExprList(db, pExpr->pList, iTable, pEList); } } static void substExprList( sqlite3 *db, /* Report malloc errors here */ ExprList *pList, /* List to scan and in which to make substitutes */ int iTable, /* Table to be substituted */ ExprList *pEList /* Substitute values */ ){ int i; if( pList==0 ) return; for(i=0; i<pList->nExpr; i++){ substExpr(db, pList->a[i].pExpr, iTable, pEList); } } static void substSelect( sqlite3 *db, /* Report malloc errors here */ Select *p, /* SELECT statement in which to make substitutions */ int iTable, /* Table to be replaced */ ExprList *pEList /* Substitute values */ ){ if( !p ) return; substExprList(db, p->pEList, iTable, pEList); substExprList(db, p->pGroupBy, iTable, pEList); substExprList(db, p->pOrderBy, iTable, pEList); substExpr(db, p->pHaving, iTable, pEList); substExpr(db, p->pWhere, iTable, pEList); substSelect(db, p->pPrior, iTable, pEList); } #endif /* !defined(SQLITE_OMIT_VIEW) */ #ifndef SQLITE_OMIT_VIEW /* ** This routine attempts to flatten subqueries in order to speed ** execution. It returns 1 if it makes changes and 0 if no flattening |
︙ | ︙ | |||
2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 | ** If flattening is not attempted, this routine is a no-op and returns 0. ** If flattening is attempted this routine returns 1. ** ** All of the expression analysis must occur on both the outer query and ** the subquery before this routine runs. */ static int flattenSubquery( Select *p, /* The parent or outer SELECT statement */ int iFrom, /* Index in p->pSrc->a[] of the inner subquery */ int isAgg, /* True if outer SELECT uses aggregate functions */ int subqueryIsAgg /* True if the subquery uses aggregate functions */ ){ Select *pSub; /* The inner query or "subquery" */ SrcList *pSrc; /* The FROM clause of the outer query */ | > | 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 | ** If flattening is not attempted, this routine is a no-op and returns 0. ** If flattening is attempted this routine returns 1. ** ** All of the expression analysis must occur on both the outer query and ** the subquery before this routine runs. */ static int flattenSubquery( sqlite3 *db, /* Database connection */ Select *p, /* The parent or outer SELECT statement */ int iFrom, /* Index in p->pSrc->a[] of the inner subquery */ int isAgg, /* True if outer SELECT uses aggregate functions */ int subqueryIsAgg /* True if the subquery uses aggregate functions */ ){ Select *pSub; /* The inner query or "subquery" */ SrcList *pSrc; /* The FROM clause of the outer query */ |
︙ | ︙ | |||
2285 2286 2287 2288 2289 2290 2291 | */ iParent = pSubitem->iCursor; { int nSubSrc = pSubSrc->nSrc; int jointype = pSubitem->jointype; sqlite3DeleteTable(pSubitem->pTab); | | | | | | 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 | */ iParent = pSubitem->iCursor; { int nSubSrc = pSubSrc->nSrc; int jointype = pSubitem->jointype; sqlite3DeleteTable(pSubitem->pTab); sqlite3_free(pSubitem->zDatabase); sqlite3_free(pSubitem->zName); sqlite3_free(pSubitem->zAlias); if( nSubSrc>1 ){ int extra = nSubSrc - 1; for(i=1; i<nSubSrc; i++){ pSrc = sqlite3SrcListAppend(db, pSrc, 0, 0); } p->pSrc = pSrc; for(i=pSrc->nSrc-1; i-extra>=iFrom; i--){ pSrc->a[i] = pSrc->a[i-extra]; } } for(i=0; i<nSubSrc; i++){ |
︙ | ︙ | |||
2321 2322 2323 2324 2325 2326 2327 | ** We look at every expression in the outer query and every place we see ** "a" we substitute "x*3" and every place we see "b" we substitute "y+10". */ pList = p->pEList; for(i=0; i<pList->nExpr; i++){ Expr *pExpr; if( pList->a[i].zName==0 && (pExpr = pList->a[i].pExpr)->span.z!=0 ){ | | > | | > | | | 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 | ** We look at every expression in the outer query and every place we see ** "a" we substitute "x*3" and every place we see "b" we substitute "y+10". */ pList = p->pEList; for(i=0; i<pList->nExpr; i++){ Expr *pExpr; if( pList->a[i].zName==0 && (pExpr = pList->a[i].pExpr)->span.z!=0 ){ pList->a[i].zName = sqlite3DbStrNDup(db, (char*)pExpr->span.z, pExpr->span.n); } } substExprList(p->pEList, iParent, pSub->pEList); if( isAgg ){ substExprList(p->pGroupBy, iParent, pSub->pEList); substExpr(p->pHaving, iParent, pSub->pEList); } if( pSub->pOrderBy ){ assert( p->pOrderBy==0 ); p->pOrderBy = pSub->pOrderBy; pSub->pOrderBy = 0; }else if( p->pOrderBy ){ substExprList(p->pOrderBy, iParent, pSub->pEList); } if( pSub->pWhere ){ pWhere = sqlite3ExprDup(db, pSub->pWhere); }else{ pWhere = 0; } if( subqueryIsAgg ){ assert( p->pHaving==0 ); p->pHaving = p->pWhere; p->pWhere = pWhere; substExpr(p->pHaving, iParent, pSub->pEList); p->pHaving = sqlite3ExprAnd(db, p->pHaving, sqlite3ExprDup(db, pSub->pHaving)); assert( p->pGroupBy==0 ); p->pGroupBy = sqlite3ExprListDup(db, pSub->pGroupBy); }else{ substExpr(p->pWhere, iParent, pSub->pEList); p->pWhere = sqlite3ExprAnd(db, p->pWhere, pWhere); } /* The flattened query is distinct if either the inner or the ** outer query is distinct. */ p->isDistinct = p->isDistinct || pSub->isDistinct; |
︙ | ︙ | |||
2567 2568 2569 2570 2571 2572 2573 | int iCol; Expr *pE = pOrderBy->a[i].pExpr; if( sqlite3ExprIsInteger(pE, &iCol) ){ if( iCol>0 && iCol<=pEList->nExpr ){ CollSeq *pColl = pE->pColl; int flags = pE->flags & EP_ExpCollate; sqlite3ExprDelete(pE); | > | | 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 | int iCol; Expr *pE = pOrderBy->a[i].pExpr; if( sqlite3ExprIsInteger(pE, &iCol) ){ if( iCol>0 && iCol<=pEList->nExpr ){ CollSeq *pColl = pE->pColl; int flags = pE->flags & EP_ExpCollate; sqlite3ExprDelete(pE); pE = sqlite3ExprDup(pParse->db, pEList->a[iCol-1].pExpr); pOrderBy->a[i].pExpr = pE; if( pColl && flags ){ pE->pColl = pColl; pE->flags |= flags; } }else{ sqlite3ErrorMsg(pParse, "%s BY column number %d out of range - should be " |
︙ | ︙ | |||
2686 2687 2688 2689 2690 2691 2692 | if( p->pPrior==0 ){ if( processOrderGroupBy(&sNC, p->pOrderBy, "ORDER") || processOrderGroupBy(&sNC, pGroupBy, "GROUP") ){ return SQLITE_ERROR; } } | | | 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 | if( p->pPrior==0 ){ if( processOrderGroupBy(&sNC, p->pOrderBy, "ORDER") || processOrderGroupBy(&sNC, pGroupBy, "GROUP") ){ return SQLITE_ERROR; } } if( db->mallocFailed ){ return SQLITE_NOMEM; } /* Make sure the GROUP BY clause does not contain aggregate functions. */ if( pGroupBy ){ struct ExprList_item *pItem; |
︙ | ︙ | |||
2893 2894 2895 2896 2897 2898 2899 2900 | Expr *pHaving; /* The HAVING clause. May be NULL */ int isDistinct; /* True if the DISTINCT keyword is present */ int distinct; /* Table to use for the distinct set */ int rc = 1; /* Value to return from this function */ int addrSortIndex; /* Address of an OP_OpenEphemeral instruction */ AggInfo sAggInfo; /* Information used by aggregate queries */ int iEnd; /* Address of the end of the query */ | > > | | 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 | Expr *pHaving; /* The HAVING clause. May be NULL */ int isDistinct; /* True if the DISTINCT keyword is present */ int distinct; /* Table to use for the distinct set */ int rc = 1; /* Value to return from this function */ int addrSortIndex; /* Address of an OP_OpenEphemeral instruction */ AggInfo sAggInfo; /* Information used by aggregate queries */ int iEnd; /* Address of the end of the query */ sqlite3 *db; /* The database connection */ db = pParse->db; if( p==0 || db->mallocFailed || pParse->nErr ){ return 1; } if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1; memset(&sAggInfo, 0, sizeof(sAggInfo)); #ifndef SQLITE_OMIT_COMPOUND_SELECT /* If there is are a sequence of queries, do the earlier ones first. |
︙ | ︙ | |||
3023 3024 3025 3026 3027 3028 3029 | } /* Check to see if this is a subquery that can be "flattened" into its parent. ** If flattening is a possiblity, do so and return immediately. */ #ifndef SQLITE_OMIT_VIEW if( pParent && pParentAgg && | | | 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 | } /* Check to see if this is a subquery that can be "flattened" into its parent. ** If flattening is a possiblity, do so and return immediately. */ #ifndef SQLITE_OMIT_VIEW if( pParent && pParentAgg && flattenSubquery(db, pParent, parentTab, *pParentAgg, isAgg) ){ if( isAgg ) *pParentAgg = 1; goto select_end; } #endif /* If there is an ORDER BY clause, then this sorting ** index might end up being unused if the data can be |
︙ | ︙ | |||
3150 3151 3152 3153 3154 3155 3156 | } sAggInfo.nAccumulator = sAggInfo.nColumn; for(i=0; i<sAggInfo.nFunc; i++){ if( sqlite3ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->pList) ){ goto select_end; } } | | | 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 | } sAggInfo.nAccumulator = sAggInfo.nColumn; for(i=0; i<sAggInfo.nFunc; i++){ if( sqlite3ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->pList) ){ goto select_end; } } if( db->mallocFailed ) goto select_end; /* Processing for aggregates with GROUP BY is very different and ** much more complex tha aggregates without a GROUP BY. */ if( pGroupBy ){ KeyInfo *pKeyInfo; /* Keying information for the group by clause */ |
︙ | ︙ | |||
3399 3400 3401 3402 3403 3404 3405 | /* Identify column names if we will be using them in a callback. This ** step is skipped if the output is going to some other destination. */ if( rc==SQLITE_OK && eDest==SRT_Callback ){ generateColumnNames(pParse, pTabList, pEList); } | | | | 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 | /* Identify column names if we will be using them in a callback. This ** step is skipped if the output is going to some other destination. */ if( rc==SQLITE_OK && eDest==SRT_Callback ){ generateColumnNames(pParse, pTabList, pEList); } sqlite3_free(sAggInfo.aCol); sqlite3_free(sAggInfo.aFunc); return rc; } #if defined(SQLITE_DEBUG) /* ******************************************************************************* ** The following code is used for testing and debugging only. The code |
︙ | ︙ |
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.587 2007/08/16 04:30:40 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ #include "sqliteLimit.h" #if defined(SQLITE_TCL) || defined(TCLSH) |
︙ | ︙ | |||
445 446 447 448 449 450 451 452 453 454 455 456 457 458 | int nDb; /* Number of backends currently in use */ Db *aDb; /* All backends */ int flags; /* Miscellanous flags. See below */ int errCode; /* Most recent error code (SQLITE_*) */ int errMask; /* & result codes with this before returning */ u8 autoCommit; /* The auto-commit flag. */ u8 temp_store; /* 1: file 2: memory 0: default */ int nTable; /* Number of tables in the database */ CollSeq *pDfltColl; /* The default collating sequence (BINARY) */ i64 lastRowid; /* ROWID of most recent insert (see above) */ i64 priorNewRowid; /* Last randomly generated ROWID */ int magic; /* Magic number for detect library misuse */ int nChange; /* Value returned by sqlite3_changes() */ int nTotalChange; /* Value returned by sqlite3_total_changes() */ | > | 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 | int nDb; /* Number of backends currently in use */ Db *aDb; /* All backends */ int flags; /* Miscellanous flags. See below */ int errCode; /* Most recent error code (SQLITE_*) */ int errMask; /* & result codes with this before returning */ u8 autoCommit; /* The auto-commit flag. */ u8 temp_store; /* 1: file 2: memory 0: default */ u8 mallocFailed; /* True if we have seen a malloc failure */ int nTable; /* Number of tables in the database */ CollSeq *pDfltColl; /* The default collating sequence (BINARY) */ i64 lastRowid; /* ROWID of most recent insert (see above) */ i64 priorNewRowid; /* Last randomly generated ROWID */ int magic; /* Magic number for detect library misuse */ int nChange; /* Value returned by sqlite3_changes() */ int nTotalChange; /* Value returned by sqlite3_total_changes() */ |
︙ | ︙ | |||
1575 1576 1577 1578 1579 1580 1581 | /* ** Internal function prototypes */ int sqlite3StrICmp(const char *, const char *); int sqlite3StrNICmp(const char *, const char *, int); int sqlite3IsNumber(const char*, int*, u8); | | > | | < | < | < < < | | | | | | | | 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 | /* ** Internal function prototypes */ int sqlite3StrICmp(const char *, const char *); int sqlite3StrNICmp(const char *, const char *, int); int sqlite3IsNumber(const char*, int*, u8); void *sqlite3MallocZero(unsigned); void *sqlite3DbMallocZero(sqlite3*, unsigned); void *sqlite3DbMallocRaw(sqlite3*, unsigned); void *sqlite3ReallocOrFree(sqlite3*,void*,int); char *sqlite3StrDup(const char*); char *sqlite3StrNDup(const char*, int); char *sqlite3DbStrDup(sqlite3*,const char*); char *sqlite3DbStrNDup(sqlite3*,const char*, int); char *sqlite3MPrintf(sqlite3*,const char*, ...); char *sqlite3VMPrintf(sqlite3*,const char*, va_list); #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG) void sqlite3DebugPrintf(const char*, ...); void *sqlite3TextToPtr(const char*); #endif void sqlite3SetString(char **, ...); void sqlite3ErrorMsg(Parse*, const char*, ...); void sqlite3ErrorClear(Parse*); void sqlite3Dequote(char*); void sqlite3DequoteExpr(sqlite3*, Expr*); int sqlite3KeywordCode(const unsigned char*, int); int sqlite3RunParser(Parse*, const char*, char **); void sqlite3FinishCoding(Parse*); Expr *sqlite3Expr(int, Expr*, Expr*, const Token*); Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*, const Token*); Expr *sqlite3RegisterExpr(Parse*,Token*); Expr *sqlite3ExprAnd(sqlite*,Expr*, Expr*); void sqlite3ExprSpan(Expr*,Token*,Token*); Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*); void sqlite3ExprAssignVarNumber(Parse*, Expr*); void sqlite3ExprDelete(Expr*); ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*,Token*); void sqlite3ExprListDelete(ExprList*); int sqlite3Init(sqlite3*, char**); int sqlite3InitCallback(void*, int, char**, char**); void sqlite3Pragma(Parse*,Token*,Token*,Token*,int); void sqlite3ResetInternalSchema(sqlite3*, int); void sqlite3BeginParse(Parse*,int); void sqlite3CommitInternalChanges(sqlite3*); |
︙ | ︙ | |||
1641 1642 1643 1644 1645 1646 1647 | #else # define sqlite3ViewGetColumnNames(A,B) 0 #endif void sqlite3DropTable(Parse*, SrcList*, int, int); void sqlite3DeleteTable(Table*); void sqlite3Insert(Parse*, SrcList*, ExprList*, Select*, IdList*, int); | | | | | | | | 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 | #else # define sqlite3ViewGetColumnNames(A,B) 0 #endif void sqlite3DropTable(Parse*, SrcList*, int, int); void sqlite3DeleteTable(Table*); void sqlite3Insert(Parse*, SrcList*, ExprList*, Select*, IdList*, int); void *sqlite3ArrayAllocate(sqlite3*,void*,int,int,int*,int*,int*); IdList *sqlite3IdListAppend(sqlite3*, IdList*, Token*); int sqlite3IdListIndex(IdList*,const char*); SrcList *sqlite3SrcListAppend(sqlite3*, SrcList*, Token*, Token*); SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*, Token*, Select*, Expr*, IdList*); void sqlite3SrcListShiftJoinType(SrcList*); void sqlite3SrcListAssignCursors(Parse*, SrcList*); void sqlite3IdListDelete(IdList*); void sqlite3SrcListDelete(SrcList*); void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*, Token*, int, int); void sqlite3DropIndex(Parse*, SrcList*, int); int sqlite3Select(Parse*, Select*, int, int, Select*, int, int*, char *aff); Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*, Expr*,ExprList*,int,Expr*,Expr*); void sqlite3SelectDelete(Select*); Table *sqlite3SrcListLookup(Parse*, SrcList*); int sqlite3IsReadOnly(Parse*, Table*, int); void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int); void sqlite3DeleteFrom(Parse*, SrcList*, Expr*); void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int); WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, ExprList**); |
︙ | ︙ | |||
1678 1679 1680 1681 1682 1683 1684 | Table *sqlite3FindTable(sqlite3*,const char*, const char*); Table *sqlite3LocateTable(Parse*,const char*, const char*); Index *sqlite3FindIndex(sqlite3*,const char*, const char*); void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*); void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*); void sqlite3Vacuum(Parse*); int sqlite3RunVacuum(char**, sqlite3*); | | < | 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 | Table *sqlite3FindTable(sqlite3*,const char*, const char*); Table *sqlite3LocateTable(Parse*,const char*, const char*); Index *sqlite3FindIndex(sqlite3*,const char*, const char*); void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*); void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*); void sqlite3Vacuum(Parse*); int sqlite3RunVacuum(char**, sqlite3*); char *sqlite3NameFromToken(sqlite3*, Token*); int sqlite3ExprCompare(Expr*, Expr*); 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*); |
︙ | ︙ | |||
1704 1705 1706 1707 1708 1709 1710 | void sqlite3GenerateRowDelete(sqlite3*, Vdbe*, Table*, int, int); void sqlite3GenerateRowIndexDelete(Vdbe*, Table*, int, char*); void sqlite3GenerateIndexKey(Vdbe*, Index*, int); void sqlite3GenerateConstraintChecks(Parse*,Table*,int,char*,int,int,int,int); void sqlite3CompleteInsertion(Parse*, Table*, int, char*, int, int, int, int); void sqlite3OpenTableAndIndices(Parse*, Table*, int, int); void sqlite3BeginWriteOperation(Parse*, int, int); | | | | | | | | | > | | | 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 | void sqlite3GenerateRowDelete(sqlite3*, Vdbe*, Table*, int, int); void sqlite3GenerateRowIndexDelete(Vdbe*, Table*, int, char*); void sqlite3GenerateIndexKey(Vdbe*, Index*, int); void sqlite3GenerateConstraintChecks(Parse*,Table*,int,char*,int,int,int,int); void sqlite3CompleteInsertion(Parse*, Table*, int, char*, int, int, int, int); void sqlite3OpenTableAndIndices(Parse*, Table*, int, int); void sqlite3BeginWriteOperation(Parse*, int, int); Expr *sqlite3ExprDup(sqlite3*,Expr*); void sqlite3TokenCopy(sqlite3*,Token*, Token*); ExprList *sqlite3ExprListDup(sqlite3*,ExprList*); SrcList *sqlite3SrcListDup(sqlite3*,SrcList*); IdList *sqlite3IdListDup(sqlite3*,IdList*); Select *sqlite3SelectDup(sqlite3*,Select*); FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,int,u8,int); void sqlite3RegisterBuiltinFunctions(sqlite3*); void sqlite3RegisterDateTimeFunctions(sqlite3*); int sqlite3SafetyOn(sqlite3*); int sqlite3SafetyOff(sqlite3*); int sqlite3SafetyCheck(sqlite3*); void sqlite3ChangeCookie(sqlite3*, Vdbe*, int); #ifndef SQLITE_OMIT_TRIGGER void sqlite3BeginTrigger(Parse*, Token*,Token*,int,int,IdList*,SrcList*, Expr*,int, int); void sqlite3FinishTrigger(Parse*, TriggerStep*, Token*); void sqlite3DropTrigger(Parse*, SrcList*, int); void sqlite3DropTriggerPtr(Parse*, Trigger*); int sqlite3TriggersExist(Parse*, Table*, int, ExprList*); int sqlite3CodeRowTrigger(Parse*, int, ExprList*, int, Table *, int, int, int, int); void sqliteViewTriggers(Parse*, Table*, Expr*, int, ExprList*); void sqlite3DeleteTriggerStep(TriggerStep*); TriggerStep *sqlite3TriggerSelectStep(sqlite3*,Select*); TriggerStep *sqlite3TriggerInsertStep(sqlite3*,Token*, IdList*, ExprList*,Select*,int); TriggerStep *sqlite3TriggerUpdateStep(sqlite3*,Token*,ExprList*, Expr*, int); TriggerStep *sqlite3TriggerDeleteStep(sqlite3*,Token*, Expr*); void sqlite3DeleteTrigger(Trigger*); void sqlite3UnlinkAndDeleteTrigger(sqlite3*,int,const char*); #else # define sqlite3TriggersExist(A,B,C,D,E,F) 0 # define sqlite3DeleteTrigger(A) # define sqlite3DropTriggerPtr(A,B) # define sqlite3UnlinkAndDeleteTrigger(A,B,C) |
︙ | ︙ | |||
1869 1870 1871 1872 1873 1874 1875 | #define sqlite3TableLock(v,w,x,y,z) #endif #ifdef SQLITE_TEST int sqlite3Utf8To8(unsigned char*); #endif | < < < < > | < > | | < < < < < < < < | 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 | #define sqlite3TableLock(v,w,x,y,z) #endif #ifdef SQLITE_TEST int sqlite3Utf8To8(unsigned char*); #endif /* ** FIX ME: create these routines */ #define sqlite3MallocDisallow() #define sqlite3MallocAllow() #ifdef SQLITE_OMIT_VIRTUALTABLE # define sqlite3VtabClear(X) # define sqlite3VtabSync(X,Y) (Y) # define sqlite3VtabRollback(X) # define sqlite3VtabCommit(X) #else |
︙ | ︙ |
Changes to src/test1.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing all sorts of SQLite 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 all sorts of SQLite interfaces. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** ** $Id: test1.c,v 1.260 2007/08/16 04:30:40 drh Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include "os.h" #include <stdlib.h> #include <string.h> |
︙ | ︙ | |||
411 412 413 414 415 416 417 | char *zResult = 0; int i; for(i=2; i<argc; i++){ zResult = sqlite3MPrintf("%z%s%s", zResult, argv[1], argv[i]); } Tcl_AppendResult(interp, zResult, 0); | | | | 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 | char *zResult = 0; int i; for(i=2; i<argc; i++){ zResult = sqlite3MPrintf("%z%s%s", zResult, argv[1], argv[i]); } Tcl_AppendResult(interp, zResult, 0); sqlite3_free(zResult); return TCL_OK; } /* ** Usage: sqlite3_mprintf_n_test STRING ** ** Test the %n format of sqliteMPrintf(). Return the length of the ** input string. */ static int test_mprintf_n( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ char **argv /* Text of each argument */ ){ char *zStr; int n = 0; zStr = sqlite3MPrintf("%s%n", argv[1], &n); sqlite3_free(zStr); Tcl_SetObjResult(interp, Tcl_NewIntObj(n)); return TCL_OK; } /* ** Usage: sqlite3_snprintf_int SIZE FORMAT INT ** |
︙ | ︙ | |||
685 686 687 688 689 690 691 | ** Append text to a dstr */ static void dstrAppend(struct dstr *p, const char *z, int divider){ int n = strlen(z); if( p->nUsed + n + 2 > p->nAlloc ){ char *zNew; p->nAlloc = p->nAlloc*2 + n + 200; | | | | 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 | ** Append text to a dstr */ static void dstrAppend(struct dstr *p, const char *z, int divider){ int n = strlen(z); if( p->nUsed + n + 2 > p->nAlloc ){ char *zNew; p->nAlloc = p->nAlloc*2 + n + 200; zNew = sqlite3_realloc(p->z, p->nAlloc); if( zNew==0 ){ sqlite3_free(p->z); memset(p, 0, sizeof(*p)); return; } p->z = zNew; } if( divider && p->nUsed>0 ){ p->z[p->nUsed++] = divider; |
︙ | ︙ | |||
738 739 740 741 742 743 744 | ){ struct dstr x; memset(&x, 0, sizeof(x)); (void)sqlite3_exec((sqlite3*)sqlite3_user_data(context), (char*)sqlite3_value_text(argv[0]), execFuncCallback, &x, 0); sqlite3_result_text(context, x.z, x.nUsed, SQLITE_TRANSIENT); | | | 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 | ){ struct dstr x; memset(&x, 0, sizeof(x)); (void)sqlite3_exec((sqlite3*)sqlite3_user_data(context), (char*)sqlite3_value_text(argv[0]), execFuncCallback, &x, 0); sqlite3_result_text(context, x.z, x.nUsed, SQLITE_TRANSIENT); sqlite3_free(x.z); } /* ** Implementation of tkt2213func(), a scalar function that takes exactly ** one argument. It has two interesting features: ** ** * It calls sqlite3_value_text() 3 times on the argument sqlite3_value*. |
︙ | ︙ | |||
913 914 915 916 917 918 919 | } #ifndef SQLITE_OMIT_UTF16 /* Use the sqlite3_create_function16() API here. Mainly for fun, but also ** because it is not tested anywhere else. */ if( rc==SQLITE_OK ){ sqlite3_value *pVal; | | | 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 | } #ifndef SQLITE_OMIT_UTF16 /* Use the sqlite3_create_function16() API here. Mainly for fun, but also ** because it is not tested anywhere else. */ if( rc==SQLITE_OK ){ sqlite3_value *pVal; #ifdef 0 if( sqlite3_iMallocFail>0 ){ sqlite3_iMallocFail++; } #endif pVal = sqlite3ValueNew(); sqlite3ValueSetStr(pVal, -1, "x_sqlite_exec", SQLITE_UTF8, SQLITE_STATIC); rc = sqlite3_create_function16(db, |
︙ | ︙ | |||
1294 1295 1296 1297 1298 1299 1300 | memcpy(&r, &d, sizeof(r)); z = sqlite3_mprintf(argv[1], r); Tcl_AppendResult(interp, z, 0); sqlite3_free(z); return TCL_OK; } | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 | memcpy(&r, &d, sizeof(r)); z = sqlite3_mprintf(argv[1], r); Tcl_AppendResult(interp, z, 0); sqlite3_free(z); return TCL_OK; } /* ** Usage: sqlite3_enable_shared_cache BOOLEAN ** */ #if !defined(SQLITE_OMIT_SHARED_CACHE) static int test_enable_shared( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ |
︙ | ︙ | |||
4300 4301 4302 4303 4304 4305 4306 | { "sqlite3_exec_nr", (Tcl_CmdProc*)test_exec_nr }, { "sqlite3_get_table_printf", (Tcl_CmdProc*)test_get_table_printf }, { "sqlite3_close", (Tcl_CmdProc*)sqlite_test_close }, { "sqlite3_create_function", (Tcl_CmdProc*)test_create_function }, { "sqlite3_create_aggregate", (Tcl_CmdProc*)test_create_aggregate }, { "sqlite_register_test_function", (Tcl_CmdProc*)test_register_func }, { "sqlite_abort", (Tcl_CmdProc*)sqlite_abort }, | < < < < | 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 | { "sqlite3_exec_nr", (Tcl_CmdProc*)test_exec_nr }, { "sqlite3_get_table_printf", (Tcl_CmdProc*)test_get_table_printf }, { "sqlite3_close", (Tcl_CmdProc*)sqlite_test_close }, { "sqlite3_create_function", (Tcl_CmdProc*)test_create_function }, { "sqlite3_create_aggregate", (Tcl_CmdProc*)test_create_aggregate }, { "sqlite_register_test_function", (Tcl_CmdProc*)test_register_func }, { "sqlite_abort", (Tcl_CmdProc*)sqlite_abort }, { "sqlite_bind", (Tcl_CmdProc*)test_bind }, { "breakpoint", (Tcl_CmdProc*)test_breakpoint }, { "sqlite3_key", (Tcl_CmdProc*)test_key }, { "sqlite3_rekey", (Tcl_CmdProc*)test_rekey }, { "sqlite_set_magic", (Tcl_CmdProc*)sqlite_set_magic }, { "sqlite3_interrupt", (Tcl_CmdProc*)test_interrupt }, { "sqlite_delete_function", (Tcl_CmdProc*)delete_function }, |
︙ | ︙ | |||
4416 4417 4418 4419 4420 4421 4422 | { "sqlite3OsUnlock", test_sqlite3OsUnlock, 0 }, #endif #ifndef SQLITE_OMIT_UTF16 { "add_test_collate", test_collate, 0 }, { "add_test_collate_needed", test_collate_needed, 0 }, { "add_test_function", test_function, 0 }, #endif | < < < | 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 | { "sqlite3OsUnlock", test_sqlite3OsUnlock, 0 }, #endif #ifndef SQLITE_OMIT_UTF16 { "add_test_collate", test_collate, 0 }, { "add_test_collate_needed", test_collate_needed, 0 }, { "add_test_function", test_function, 0 }, #endif { "sqlite3_test_errstr", test_errstr, 0 }, { "tcl_variable_type", tcl_variable_type, 0 }, #ifndef SQLITE_OMIT_SHARED_CACHE { "sqlite3_enable_shared_cache", test_enable_shared, 0 }, { "sqlite3_shared_cache_report", sqlite3BtreeSharedCacheReport, 0}, #endif { "sqlite3_libversion_number", test_libversion_number, 0 }, |
︙ | ︙ | |||
4507 4508 4509 4510 4511 4512 4513 | #if OS_UNIX && defined(SQLITE_TEST) && defined(THREADSAFE) && THREADSAFE Tcl_LinkVar(interp, "threadsOverrideEachOthersLocks", (char*)&threadsOverrideEachOthersLocks, TCL_LINK_INT); #endif #ifndef SQLITE_OMIT_UTF16 Tcl_LinkVar(interp, "sqlite_last_needed_collation", (char*)&pzNeededCollation, TCL_LINK_STRING|TCL_LINK_READ_ONLY); | < < < < < < < < < < | 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 | #if OS_UNIX && defined(SQLITE_TEST) && defined(THREADSAFE) && THREADSAFE Tcl_LinkVar(interp, "threadsOverrideEachOthersLocks", (char*)&threadsOverrideEachOthersLocks, TCL_LINK_INT); #endif #ifndef SQLITE_OMIT_UTF16 Tcl_LinkVar(interp, "sqlite_last_needed_collation", (char*)&pzNeededCollation, TCL_LINK_STRING|TCL_LINK_READ_ONLY); #endif #if OS_WIN Tcl_LinkVar(interp, "sqlite_os_type", (char*)&sqlite3_os_type, TCL_LINK_INT); #endif #ifdef SQLITE_TEST Tcl_LinkVar(interp, "sqlite_query_plan", |
︙ | ︙ |
Changes to src/test3.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the btree.c module in SQLite. 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 btree.c module in SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** ** $Id: test3.c,v 1.76 2007/08/16 04:30:40 drh Exp $ */ #include "sqliteInt.h" #include "pager.h" #include "btree.h" #include "tcl.h" #include <stdlib.h> #include <string.h> |
︙ | ︙ | |||
573 574 575 576 577 578 579 | if( argc<3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ID ROOT ...\"", 0); return TCL_ERROR; } pBt = sqlite3TextToPtr(argv[1]); nRoot = argc-2; | | | | 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 | if( argc<3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ID ROOT ...\"", 0); return TCL_ERROR; } pBt = sqlite3TextToPtr(argv[1]); nRoot = argc-2; aRoot = (int*)sqlite3_malloc( sizeof(int)*(argc-2) ); for(i=0; i<argc-2; i++){ if( Tcl_GetInt(interp, argv[i+2], &aRoot[i]) ) return TCL_ERROR; } #ifndef SQLITE_OMIT_INTEGRITY_CHECK zResult = sqlite3BtreeIntegrityCheck(pBt, aRoot, nRoot, 10000, &nErr); #else zResult = 0; #endif sqlite3_free((void*)aRoot); if( zResult ){ Tcl_AppendResult(interp, zResult, 0); sqliteFree(zResult); } return TCL_OK; } |
︙ | ︙ | |||
1010 1011 1012 1013 1014 1015 1016 | pCur = sqlite3TextToPtr(argv[1]); sqlite3BtreeKeySize(pCur, (i64*)&n); if( sqlite3BtreeFlags(pCur) & BTREE_INTKEY ){ char zBuf2[60]; sqlite3_snprintf(sizeof(zBuf2),zBuf2, "%llu", n); Tcl_AppendResult(interp, zBuf2, 0); }else{ | | | | 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 | pCur = sqlite3TextToPtr(argv[1]); sqlite3BtreeKeySize(pCur, (i64*)&n); if( sqlite3BtreeFlags(pCur) & BTREE_INTKEY ){ char zBuf2[60]; sqlite3_snprintf(sizeof(zBuf2),zBuf2, "%llu", n); Tcl_AppendResult(interp, zBuf2, 0); }else{ zBuf = sqlite3_malloc( n+1 ); rc = sqlite3BtreeKey(pCur, 0, n, zBuf); if( rc ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } zBuf[n] = 0; Tcl_AppendResult(interp, zBuf, 0); sqlite3_free(zBuf); } return SQLITE_OK; } /* ** Usage: btree_data ID ?N? ** |
︙ | ︙ | |||
1050 1051 1052 1053 1054 1055 1056 | } pCur = sqlite3TextToPtr(argv[1]); if( argc==2 ){ sqlite3BtreeDataSize(pCur, &n); }else{ n = atoi(argv[2]); } | | | | 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 | } pCur = sqlite3TextToPtr(argv[1]); if( argc==2 ){ sqlite3BtreeDataSize(pCur, &n); }else{ n = atoi(argv[2]); } zBuf = sqlite3_malloc( n+1 ); rc = sqlite3BtreeData(pCur, 0, n, zBuf); if( rc ){ Tcl_AppendResult(interp, errorName(rc), 0); free(zBuf); return TCL_ERROR; } zBuf[n] = 0; Tcl_AppendResult(interp, zBuf, 0); sqlite3_free(zBuf); return SQLITE_OK; } /* ** Usage: btree_fetch_key ID AMT ** ** Use the sqlite3BtreeKeyFetch() routine to get AMT bytes of the key. |
︙ | ︙ |
Changes to src/test4.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2003 December 18 ** ** 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. ** ************************************************************************* ** Code for testing the the SQLite library in a multithreaded environment. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2003 December 18 ** ** 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. ** ************************************************************************* ** Code for testing the the SQLite library in a multithreaded environment. ** ** $Id: test4.c,v 1.18 2007/08/16 04:30:40 drh Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include "os.h" #if defined(OS_UNIX) && OS_UNIX==1 && defined(THREADSAFE) && THREADSAFE==1 #include <stdlib.h> #include <string.h> |
︙ | ︙ | |||
139 140 141 142 143 144 145 | if( i<0 ) return TCL_ERROR; if( threadset[i].busy ){ Tcl_AppendResult(interp, "thread ", argv[1], " is already running", 0); return TCL_ERROR; } threadset[i].busy = 1; sqliteFree(threadset[i].zFilename); | | | 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | if( i<0 ) return TCL_ERROR; if( threadset[i].busy ){ Tcl_AppendResult(interp, "thread ", argv[1], " is already running", 0); return TCL_ERROR; } threadset[i].busy = 1; sqliteFree(threadset[i].zFilename); threadset[i].zFilename = sqlite3StrDup(argv[2]); threadset[i].opnum = 1; threadset[i].completed = 0; rc = pthread_create(&x, 0, thread_main, &threadset[i]); if( rc ){ Tcl_AppendResult(interp, "failed to create the thread", 0); sqliteFree(threadset[i].zFilename); threadset[i].busy = 0; |
︙ | ︙ | |||
473 474 475 476 477 478 479 | if( !threadset[i].busy ){ Tcl_AppendResult(interp, "no such thread", 0); return TCL_ERROR; } thread_wait(&threadset[i]); threadset[i].xOp = do_compile; sqliteFree(threadset[i].zArg); | | | 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 | if( !threadset[i].busy ){ Tcl_AppendResult(interp, "no such thread", 0); return TCL_ERROR; } thread_wait(&threadset[i]); threadset[i].xOp = do_compile; sqliteFree(threadset[i].zArg); threadset[i].zArg = sqlite3StrDup(argv[2]); threadset[i].opnum++; return TCL_OK; } /* ** This procedure runs in the thread to step the virtual machine. */ |
︙ | ︙ |
Changes to src/test5.c.
︙ | ︙ | |||
11 12 13 14 15 16 17 | ************************************************************************* ** Code for testing the utf.c module in SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. Specifically, the code in this file ** is used for testing the SQLite routines for converting between ** the various supported unicode encodings. ** | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ************************************************************************* ** Code for testing the utf.c module in SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. Specifically, the code in this file ** is used for testing the SQLite routines for converting between ** the various supported unicode encodings. ** ** $Id: test5.c,v 1.17 2007/08/16 04:30:40 drh Exp $ */ #include "sqliteInt.h" #include "vdbeInt.h" #include "os.h" /* to get SQLITE_BIGENDIAN */ #include "tcl.h" #include <stdlib.h> #include <string.h> |
︙ | ︙ | |||
151 152 153 154 155 156 157 | if( !enc_to ) return TCL_ERROR; pVal = sqlite3ValueNew(); if( enc_from==SQLITE_UTF8 ){ z = Tcl_GetString(objv[1]); if( objc==5 ){ | | | | 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 | if( !enc_to ) return TCL_ERROR; pVal = sqlite3ValueNew(); if( enc_from==SQLITE_UTF8 ){ z = Tcl_GetString(objv[1]); if( objc==5 ){ z = sqlite3StrDup(z); } sqlite3ValueSetStr(pVal, -1, z, enc_from, xDel); }else{ z = (char*)Tcl_GetByteArrayFromObj(objv[1], &len); if( objc==5 ){ char *zTmp = z; z = sqlite3_malloc(len); memcpy(z, zTmp, len); } sqlite3ValueSetStr(pVal, -1, z, enc_from, xDel); } z = (char *)sqlite3ValueText(pVal, enc_to); len = sqlite3ValueBytes(pVal, enc_to) + (enc_to==SQLITE_UTF8?1:2); |
︙ | ︙ |
Changes to src/test6.c.
︙ | ︙ | |||
202 203 204 205 206 207 208 | rc = sqlite3OsWrite( pFile->pRealFile, pWrite->zBuf, pWrite->nBuf, pWrite->iOffset ); }else{ rc = sqlite3OsTruncate(pFile->pRealFile, pWrite->iOffset); } *ppPtr = pWrite->pNext; | | | | | 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 | rc = sqlite3OsWrite( pFile->pRealFile, pWrite->zBuf, pWrite->nBuf, pWrite->iOffset ); }else{ rc = sqlite3OsTruncate(pFile->pRealFile, pWrite->iOffset); } *ppPtr = pWrite->pNext; sqlite3_free(pWrite); break; } case 2: { /* Do nothing */ ppPtr = &pWrite->pNext; break; } case 3: { /* Trash sectors */ u8 *zGarbage; sqlite3_int64 iFirst = (pWrite->iOffset%g.iSectorSize); sqlite3_int64 iLast = (pWrite->iOffset+pWrite->nBuf-1)%g.iSectorSize; zGarbage = sqlite3_malloc(g.iSectorSize); if( zGarbage ){ sqlite3_int64 i; for(i=iFirst; rc==SQLITE_OK && i<=iLast; i++){ sqlite3Randomness(g.iSectorSize, zGarbage); rc = sqlite3OsWrite( pFile->pRealFile, i*g.iSectorSize, zGarbage, g.iSectorSize ); } sqlite3_free(zGarbage); }else{ rc = SQLITE_NOMEM; } ppPtr = &pWrite->pNext; break; } |
︙ | ︙ | |||
259 260 261 262 263 264 265 | const u8 *zBuf, int nBuf ){ WriteBuffer *pNew; assert((zBuf && nBuf) || (!nBuf && !zBuf)); | | | 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 | const u8 *zBuf, int nBuf ){ WriteBuffer *pNew; assert((zBuf && nBuf) || (!nBuf && !zBuf)); pNew = (WriteBuffer *)sqlite3_malloc(sizeof(WriteBuffer) + nBuf); pNew->iOffset = iOffset; pNew->nBuf = nBuf; pNew->pFile = (CrashFile *)pFile; if( zBuf ){ pNew->zBuf = (u8 *)&pNew[1]; memcpy(pNew->zBuf, zBuf, nBuf); } |
︙ | ︙ | |||
467 468 469 470 471 472 473 | sqlite3_file *pFile, int flags, int *pOutFlags ){ CrashFile *pWrapper = (CrashFile *)pFile; int rc = SQLITE_NOMEM; sqlite3_file *pReal; | | | | | 467 468 469 470 471 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 | sqlite3_file *pFile, int flags, int *pOutFlags ){ CrashFile *pWrapper = (CrashFile *)pFile; int rc = SQLITE_NOMEM; sqlite3_file *pReal; pReal = (sqlite3_file *)sqlite3_malloc(pVfs->szOsFile); if( pReal ){ pWrapper->pMethod = &CrashFileVtab; pWrapper->zName = zName; rc = pVfs->xOpen(pVfs->pAppData, zName, pReal, flags, pOutFlags); if( rc==SQLITE_OK ){ pWrapper->pRealFile = pFile; }else{ sqlite3_free(pReal); } } return rc; } int sqlite3CrashFileWrap( sqlite3_file *pFile, const char *zName, sqlite3_file **ppWrapper ){ CrashFile *pWrapper; pWrapper = (CrashFile *)sqlite3_malloc(sizeof(CrashFile)+strlen(zName)+1); if( !pWrapper ){ return SQLITE_NOMEM; } pWrapper->pMethod = &CrashFileVtab; pWrapper->pRealFile = pFile; pWrapper->zName = &pWrapper[1]; |
︙ | ︙ |
Changes to src/test7.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. ** ************************************************************************* ** Code for testing the client/server version of the SQLite library. ** Derived from test4.c. ** | | | 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. ** ************************************************************************* ** Code for testing the client/server version of the SQLite library. ** Derived from test4.c. ** ** $Id: test7.c,v 1.5 2007/08/16 04:30:40 drh Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include "os.h" /* ** This test only works on UNIX with a THREADSAFE build that includes |
︙ | ︙ | |||
161 162 163 164 165 166 167 | if( i<0 ) return TCL_ERROR; if( threadset[i].busy ){ Tcl_AppendResult(interp, "thread ", argv[1], " is already running", 0); return TCL_ERROR; } threadset[i].busy = 1; sqliteFree(threadset[i].zFilename); | | | 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | if( i<0 ) return TCL_ERROR; if( threadset[i].busy ){ Tcl_AppendResult(interp, "thread ", argv[1], " is already running", 0); return TCL_ERROR; } threadset[i].busy = 1; sqliteFree(threadset[i].zFilename); threadset[i].zFilename = sqlite3StrDup(argv[2]); threadset[i].opnum = 1; threadset[i].completed = 0; rc = pthread_create(&x, 0, client_main, &threadset[i]); if( rc ){ Tcl_AppendResult(interp, "failed to create the thread", 0); sqliteFree(threadset[i].zFilename); threadset[i].busy = 0; |
︙ | ︙ | |||
504 505 506 507 508 509 510 | if( !threadset[i].busy ){ Tcl_AppendResult(interp, "no such thread", 0); return TCL_ERROR; } client_wait(&threadset[i]); threadset[i].xOp = do_compile; sqliteFree(threadset[i].zArg); | | | 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 | if( !threadset[i].busy ){ Tcl_AppendResult(interp, "no such thread", 0); return TCL_ERROR; } client_wait(&threadset[i]); threadset[i].xOp = do_compile; sqliteFree(threadset[i].zArg); threadset[i].zArg = sqlite3StrDup(argv[2]); threadset[i].opnum++; return TCL_OK; } /* ** This procedure runs in the thread to step the virtual machine. */ |
︙ | ︙ |
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.49 2007/08/16 04:30:40 drh Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include "os.h" #include <stdlib.h> #include <string.h> |
︙ | ︙ | |||
118 119 120 121 122 123 124 | /* ** Retrieve the column names for the table named zTab via database ** connection db. SQLITE_OK is returned on success, or an sqlite error ** code otherwise. ** ** If successful, the number of columns is written to *pnCol. *paCol is | | | | | | | 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | /* ** Retrieve the column names for the table named zTab via database ** connection db. SQLITE_OK is returned on success, or an sqlite error ** code otherwise. ** ** If successful, the number of columns is written to *pnCol. *paCol is ** set to point at sqlite3_malloc()'d space containing the array of ** nCol column names. The caller is responsible for calling sqlite3_free ** on *paCol. */ static int getColumnNames( sqlite3 *db, const char *zTab, char ***paCol, int *pnCol ){ char **aCol = 0; char *zSql; sqlite3_stmt *pStmt = 0; int rc = SQLITE_OK; int nCol = 0; /* Prepare the statement "SELECT * FROM <tbl>". The column names ** of the result set of the compiled SELECT will be the same as ** the column names of table <tbl>. */ zSql = sqlite3_mprintf("SELECT * FROM %Q", zTab); if( !zSql ){ rc = SQLITE_NOMEM; goto out; } rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); sqlite3_free(zSql); if( rc==SQLITE_OK ){ int ii; int nBytes; char *zSpace; nCol = sqlite3_column_count(pStmt); /* Figure out how much space to allocate for the array of column names ** (including space for the strings themselves). Then allocate it. */ nBytes = sizeof(char *) * nCol; for(ii=0; ii<nCol; ii++){ nBytes += (strlen(sqlite3_column_name(pStmt, ii)) + 1); } aCol = (char **)sqlite3_malloc(nBytes); if( !aCol ){ rc = SQLITE_NOMEM; goto out; } /* Copy the column names into the allocated space and set up the ** pointers in the aCol[] array. |
︙ | ︙ | |||
209 210 211 212 213 214 215 | ){ sqlite3_stmt *pStmt = 0; int *aIndex = 0; int rc; char *zSql; /* Allocate space for the index array */ | | | | | 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 | ){ sqlite3_stmt *pStmt = 0; int *aIndex = 0; int rc; char *zSql; /* Allocate space for the index array */ aIndex = (int *)sqlite3_malloc(sizeof(int) * nCol); if( !aIndex ){ rc = SQLITE_NOMEM; goto get_index_array_out; } /* Compile an sqlite pragma to loop through all indices on table zTab */ zSql = sqlite3MPrintf("PRAGMA index_list(%s)", zTab); if( !zSql ){ rc = SQLITE_NOMEM; goto get_index_array_out; } rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); sqlite3_free(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); sqlite3_free(zSql); if( pStmt2 && sqlite3_step(pStmt2)==SQLITE_ROW ){ int cid = sqlite3_column_int(pStmt2, 1); assert( cid>=0 && cid<nCol ); aIndex[cid] = 1; } if( pStmt2 ){ rc = sqlite3_finalize(pStmt2); |
︙ | ︙ | |||
259 260 261 262 263 264 265 | if( pStmt ){ int rc2 = sqlite3_finalize(pStmt); if( rc==SQLITE_OK ){ rc = rc2; } } if( rc!=SQLITE_OK ){ | | | 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 | if( pStmt ){ int rc2 = sqlite3_finalize(pStmt); if( rc==SQLITE_OK ){ rc = rc2; } } if( rc!=SQLITE_OK ){ sqlite3_free(aIndex); aIndex = 0; } *paIndex = aIndex; return rc; } /* |
︙ | ︙ | |||
335 336 337 338 339 340 341 | /* ** This function frees all runtime structures associated with the virtual ** table pVtab. */ static int echoDestructor(sqlite3_vtab *pVtab){ echo_vtab *p = (echo_vtab*)pVtab; | | | | | | | | | | 335 336 337 338 339 340 341 342 343 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 386 387 388 389 390 391 392 393 394 | /* ** This function frees all runtime structures associated with the virtual ** table pVtab. */ static int echoDestructor(sqlite3_vtab *pVtab){ echo_vtab *p = (echo_vtab*)pVtab; sqlite3_free(p->aIndex); sqlite3_free(p->aCol); sqlite3_free(p->zThis); sqlite3_free(p->zTableName); sqlite3_free(p->zLogName); sqlite3_free(p); return 0; } /* ** This function is called to do the work of the xConnect() method - ** to allocate the required in-memory structures for a newly connected ** virtual table. */ static int echoConstructor( sqlite3 *db, void *pAux, int argc, const char *const*argv, sqlite3_vtab **ppVtab, char **pzErr ){ int i; echo_vtab *pVtab; /* Allocate the sqlite3_vtab/echo_vtab structure itself */ pVtab = sqlite3_malloc( sizeof(*pVtab) ); if( !pVtab ){ return SQLITE_NOMEM; } pVtab->interp = (Tcl_Interp *)pAux; pVtab->db = db; /* Allocate echo_vtab.zThis */ pVtab->zThis = sqlite3MPrintf("%s", argv[2]); if( !pVtab->zThis ){ echoDestructor((sqlite3_vtab *)pVtab); return SQLITE_NOMEM; } /* Allocate echo_vtab.zTableName */ if( argc>3 ){ pVtab->zTableName = sqlite3MPrintf("%s", argv[3]); dequoteString(pVtab->zTableName); if( pVtab->zTableName && pVtab->zTableName[0]=='*' ){ char *z = sqlite3MPrintf("%s%s", argv[2], &(pVtab->zTableName[1])); sqlite3_free(pVtab->zTableName); pVtab->zTableName = z; pVtab->isPattern = 1; } if( !pVtab->zTableName ){ echoDestructor((sqlite3_vtab *)pVtab); return SQLITE_NOMEM; } |
︙ | ︙ | |||
439 440 441 442 443 444 445 | */ if( rc==SQLITE_OK && argc==5 ){ char *zSql; echo_vtab *pVtab = *(echo_vtab **)ppVtab; pVtab->zLogName = sqlite3MPrintf("%s", argv[4]); zSql = sqlite3MPrintf("CREATE TABLE %Q(logmsg)", pVtab->zLogName); rc = sqlite3_exec(db, zSql, 0, 0, 0); | | | 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 | */ if( rc==SQLITE_OK && argc==5 ){ char *zSql; echo_vtab *pVtab = *(echo_vtab **)ppVtab; pVtab->zLogName = sqlite3MPrintf("%s", argv[4]); zSql = sqlite3MPrintf("CREATE TABLE %Q(logmsg)", pVtab->zLogName); rc = sqlite3_exec(db, zSql, 0, 0, 0); sqlite3_free(zSql); } return rc; } /* ** Echo virtual table module xConnect method. |
︙ | ︙ | |||
480 481 482 483 484 485 486 | appendToEchoModule(((echo_vtab *)pVtab)->interp, "xDestroy"); /* Drop the "log" table, if one exists (see echoCreate() for details) */ if( p && p->zLogName ){ char *zSql; zSql = sqlite3MPrintf("DROP TABLE %Q", p->zLogName); rc = sqlite3_exec(p->db, zSql, 0, 0, 0); | | | | | 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 511 512 513 514 515 516 517 518 519 520 521 | appendToEchoModule(((echo_vtab *)pVtab)->interp, "xDestroy"); /* Drop the "log" table, if one exists (see echoCreate() for details) */ if( p && p->zLogName ){ char *zSql; zSql = sqlite3MPrintf("DROP TABLE %Q", p->zLogName); rc = sqlite3_exec(p->db, zSql, 0, 0, 0); sqlite3_free(zSql); } if( rc==SQLITE_OK ){ rc = echoDestructor(pVtab); } return rc; } /* ** Echo virtual table module xOpen method. */ static int echoOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ echo_cursor *pCur; pCur = sqlite3_malloc(sizeof(echo_cursor)); *ppCursor = (sqlite3_vtab_cursor *)pCur; return (pCur ? SQLITE_OK : SQLITE_NOMEM); } /* ** Echo virtual table module xClose method. */ static int echoClose(sqlite3_vtab_cursor *cur){ int rc; echo_cursor *pCur = (echo_cursor *)cur; sqlite3_stmt *pStmt = pCur->pStmt; pCur->pStmt = 0; sqlite3_free(pCur); rc = sqlite3_finalize(pStmt); return rc; } /* ** Return non-zero if the cursor does not currently point to a valid record ** (i.e if the scan has finished), or zero otherwise. |
︙ | ︙ | |||
1037 1038 1039 1040 1041 1042 1043 | if( p->isPattern ){ int nThis = strlen(p->zThis); char *zSql = sqlite3MPrintf("ALTER TABLE %s RENAME TO %s%s", p->zTableName, zNewName, &p->zTableName[nThis] ); rc = sqlite3_exec(p->db, zSql, 0, 0, 0); | | | 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 | if( p->isPattern ){ int nThis = strlen(p->zThis); char *zSql = sqlite3MPrintf("ALTER TABLE %s RENAME TO %s%s", p->zTableName, zNewName, &p->zTableName[nThis] ); rc = sqlite3_exec(p->db, zSql, 0, 0, 0); sqlite3_free(zSql); } return rc; } /* ** A virtual table module that merely "echos" the contents of another |
︙ | ︙ |
Changes to src/test_async.c.
︙ | ︙ | |||
312 313 314 315 316 317 318 | ** ** ASYNC_OPENEXCLUSIVE: ** iOffset -> Value of "delflag". ** nByte -> Number of bytes of zBuf points to (file name). ** ** ** For an ASYNC_WRITE operation, zBuf points to the data to write to the file. | | | | 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 | ** ** ASYNC_OPENEXCLUSIVE: ** iOffset -> Value of "delflag". ** nByte -> Number of bytes of zBuf points to (file name). ** ** ** For an ASYNC_WRITE operation, zBuf points to the data to write to the file. ** This space is sqlite3_malloc()d along with the AsyncWrite structure in a ** single blob, so is deleted when sqlite3_free() is called on the parent ** structure. */ struct AsyncWrite { AsyncFile *pFile; /* File to write data to or sync */ int op; /* One of ASYNC_xxx etc. */ i64 iOffset; /* See above */ int nByte; /* See above */ |
︙ | ︙ | |||
339 340 341 342 343 344 345 | int nName; /* Number of characters in zName */ OsFile *pBaseRead; /* Read handle to the underlying Os file */ OsFile *pBaseWrite; /* Write handle to the underlying Os file */ }; /* ** Add an entry to the end of the global write-op list. pWrite should point | | | | 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 | int nName; /* Number of characters in zName */ OsFile *pBaseRead; /* Read handle to the underlying Os file */ OsFile *pBaseWrite; /* Write handle to the underlying Os file */ }; /* ** Add an entry to the end of the global write-op list. pWrite should point ** to an AsyncWrite structure allocated using sqlite3_malloc(). The writer ** thread will call sqlite3_free() to free the structure after the specified ** operation has been completed. ** ** Once an AsyncWrite structure has been added to the list, it becomes the ** property of the writer thread and must not be read or modified by the ** caller. */ static void addAsyncWrite(AsyncWrite *pWrite){ |
︙ | ︙ | |||
406 407 408 409 410 411 412 | int nByte, const char *zByte ){ AsyncWrite *p; if( op!=ASYNC_CLOSE && async.ioError ){ return async.ioError; } | | | 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 | int nByte, const char *zByte ){ AsyncWrite *p; if( op!=ASYNC_CLOSE && async.ioError ){ return async.ioError; } p = sqlite3_malloc(sizeof(AsyncWrite) + (zByte?nByte:0)); if( !p ){ return SQLITE_NOMEM; } p->op = op; p->iOffset = iOffset; p->nByte = nByte; p->pFile = pFile; |
︙ | ︙ | |||
714 715 716 717 718 719 720 | if( rc!=SQLITE_OK ){ goto error_out; } } n = strlen(zName); for(i=n-1; i>=0 && zName[i]!='/'; i--){} | | | 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 | if( rc!=SQLITE_OK ){ goto error_out; } } n = strlen(zName); for(i=n-1; i>=0 && zName[i]!='/'; i--){} p = (AsyncFile *)sqlite3_malloc(sizeof(AsyncFile) + n - i); if( !p ){ rc = SQLITE_NOMEM; goto error_out; } memset(p, 0, sizeof(AsyncFile)); p->zName = (char*)&p[1]; strcpy(p->zName, &zName[i+1]); |
︙ | ︙ | |||
751 752 753 754 755 756 757 | int rc = asyncOpenFile(z, ppFile, 0, 0); if( rc==SQLITE_OK ){ AsyncFile *pFile = (AsyncFile *)(*ppFile); int nByte = strlen(z)+1; i64 i = (i64)(delFlag); rc = addNewAsyncWrite(pFile, ASYNC_OPENEXCLUSIVE, i, nByte, z); if( rc!=SQLITE_OK ){ | | | 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 | int rc = asyncOpenFile(z, ppFile, 0, 0); if( rc==SQLITE_OK ){ AsyncFile *pFile = (AsyncFile *)(*ppFile); int nByte = strlen(z)+1; i64 i = (i64)(delFlag); rc = addNewAsyncWrite(pFile, ASYNC_OPENEXCLUSIVE, i, nByte, z); if( rc!=SQLITE_OK ){ sqlite3_free(pFile); *ppFile = 0; } } if( rc==SQLITE_OK ){ incrOpenFileCount(); } return rc; |
︙ | ︙ | |||
987 988 989 990 991 992 993 | rc = sqlite3OsTruncate(pBase, p->iOffset); break; case ASYNC_CLOSE: ASYNC_TRACE(("CLOSE %s\n", p->pFile->zName)); sqlite3OsClose(&p->pFile->pBaseWrite); sqlite3OsClose(&p->pFile->pBaseRead); | | | 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 | rc = sqlite3OsTruncate(pBase, p->iOffset); break; case ASYNC_CLOSE: ASYNC_TRACE(("CLOSE %s\n", p->pFile->zName)); sqlite3OsClose(&p->pFile->pBaseWrite); sqlite3OsClose(&p->pFile->pBaseRead); sqlite3_free(p->pFile); break; case ASYNC_OPENDIRECTORY: assert( pBase ); ASYNC_TRACE(("OPENDIR %s\n", p->zBuf)); sqlite3OsOpenDirectory(pBase, p->zBuf); break; |
︙ | ︙ | |||
1044 1045 1046 1047 1048 1049 1050 | holdingMutex = 1; } /* ASYNC_TRACE(("UNLINK %p\n", p)); */ if( p==async.pQueueLast ){ async.pQueueLast = 0; } async.pQueueFirst = p->pNext; | | | 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 | holdingMutex = 1; } /* ASYNC_TRACE(("UNLINK %p\n", p)); */ if( p==async.pQueueLast ){ async.pQueueLast = 0; } async.pQueueFirst = p->pNext; sqlite3_free(p); assert( holdingMutex ); /* An IO error has occured. We cannot report the error back to the ** connection that requested the I/O since the error happened ** asynchronously. The connection has already moved on. There ** really is nobody to report the error to. ** |
︙ | ︙ |
Changes to src/test_hexio.c.
︙ | ︙ | |||
13 14 15 16 17 18 19 | ** implements TCL commands for reading and writing the binary ** database files and displaying the content of those files as ** hexadecimal. We could, in theory, use the built-in "binary" ** command of TCL to do a lot of this, but there are some issues ** with historical versions of the "binary" command. So it seems ** easier and safer to build our own mechanism. ** | | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | ** implements TCL commands for reading and writing the binary ** database files and displaying the content of those files as ** hexadecimal. We could, in theory, use the built-in "binary" ** command of TCL to do a lot of this, but there are some issues ** with historical versions of the "binary" command. So it seems ** easier and safer to build our own mechanism. ** ** $Id: test_hexio.c,v 1.4 2007/08/16 04:30:40 drh Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include <stdlib.h> #include <string.h> #include <assert.h> |
︙ | ︙ | |||
111 112 113 114 115 116 117 | if( objc!=4 ){ Tcl_WrongNumArgs(interp, 1, objv, "FILENAME OFFSET AMT"); return TCL_ERROR; } if( Tcl_GetIntFromObj(interp, objv[2], &offset) ) return TCL_ERROR; if( Tcl_GetIntFromObj(interp, objv[3], &amt) ) return TCL_ERROR; zFile = Tcl_GetString(objv[1]); | | | | 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | if( objc!=4 ){ Tcl_WrongNumArgs(interp, 1, objv, "FILENAME OFFSET AMT"); return TCL_ERROR; } if( Tcl_GetIntFromObj(interp, objv[2], &offset) ) return TCL_ERROR; if( Tcl_GetIntFromObj(interp, objv[3], &amt) ) return TCL_ERROR; zFile = Tcl_GetString(objv[1]); zBuf = sqlite3_malloc( amt*2+1 ); if( zBuf==0 ){ return TCL_ERROR; } in = fopen(zFile, "r"); if( in==0 ){ Tcl_AppendResult(interp, "cannot open input file ", zFile, 0); return TCL_ERROR; } fseek(in, offset, SEEK_SET); got = fread(zBuf, 1, amt, in); fclose(in); if( got<0 ){ got = 0; } binToHex(zBuf, got); Tcl_AppendResult(interp, zBuf, 0); sqlite3_free(zBuf); return TCL_OK; } /* ** Usage: hexio_write FILENAME OFFSET DATA ** |
︙ | ︙ | |||
159 160 161 162 163 164 165 | if( objc!=4 ){ Tcl_WrongNumArgs(interp, 1, objv, "FILENAME OFFSET HEXDATA"); return TCL_ERROR; } if( Tcl_GetIntFromObj(interp, objv[2], &offset) ) return TCL_ERROR; zFile = Tcl_GetString(objv[1]); zIn = (const unsigned char *)Tcl_GetStringFromObj(objv[3], &nIn); | | | | 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | if( objc!=4 ){ Tcl_WrongNumArgs(interp, 1, objv, "FILENAME OFFSET HEXDATA"); return TCL_ERROR; } if( Tcl_GetIntFromObj(interp, objv[2], &offset) ) return TCL_ERROR; zFile = Tcl_GetString(objv[1]); zIn = (const unsigned char *)Tcl_GetStringFromObj(objv[3], &nIn); aOut = sqlite3_malloc( nIn/2 ); if( aOut==0 ){ return TCL_ERROR; } nOut = hexToBin(zIn, nIn, aOut); out = fopen(zFile, "r+"); if( out==0 ){ Tcl_AppendResult(interp, "cannot open output file ", zFile, 0); return TCL_ERROR; } fseek(out, offset, SEEK_SET); written = fwrite(aOut, 1, nOut, out); sqlite3_free(aOut); fclose(out); Tcl_SetObjResult(interp, Tcl_NewIntObj(written)); return TCL_OK; } /* ** USAGE: hexio_get_int HEXDATA |
︙ | ︙ | |||
201 202 203 204 205 206 207 | unsigned char aNum[4]; if( objc!=2 ){ Tcl_WrongNumArgs(interp, 1, objv, "HEXDATA"); return TCL_ERROR; } zIn = (const unsigned char *)Tcl_GetStringFromObj(objv[1], &nIn); | | | | 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 | unsigned char aNum[4]; if( objc!=2 ){ Tcl_WrongNumArgs(interp, 1, objv, "HEXDATA"); return TCL_ERROR; } zIn = (const unsigned char *)Tcl_GetStringFromObj(objv[1], &nIn); aOut = sqlite3_malloc( nIn/2 ); if( aOut==0 ){ return TCL_ERROR; } nOut = hexToBin(zIn, nIn, aOut); if( nOut>=4 ){ memcpy(aNum, aOut, 4); }else{ memset(aNum, 0, sizeof(aNum)); memcpy(&aNum[4-nOut], aOut, nOut); } sqlite3_free(aOut); val = (aNum[0]<<24) | (aNum[1]<<16) | (aNum[2]<<8) | aNum[3]; Tcl_SetObjResult(interp, Tcl_NewIntObj(val)); return TCL_OK; } /* |
︙ | ︙ |
Changes to src/test_schema.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: test_schema.c,v 1.13 2007/08/16 04:30:40 drh Exp $ */ /* The code in this file defines a sqlite3 virtual-table module that ** provides a read-only view of the current database schema. There is one ** row in the schema table for each column in the database schema. */ #define SCHEMA \ |
︙ | ︙ | |||
35 36 37 38 39 40 41 | /* If SQLITE_TEST is defined this code is preprocessed for use as part ** of the sqlite test binary "testfixture". Otherwise it is preprocessed ** to be compiled into an sqlite dynamic extension. */ #ifdef SQLITE_TEST #include "sqliteInt.h" #include "tcl.h" | < < < < | 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | /* If SQLITE_TEST is defined this code is preprocessed for use as part ** of the sqlite test binary "testfixture". Otherwise it is preprocessed ** to be compiled into an sqlite dynamic extension. */ #ifdef SQLITE_TEST #include "sqliteInt.h" #include "tcl.h" #else #include "sqlite3ext.h" SQLITE_EXTENSION_INIT1 #endif #include <stdlib.h> #include <string.h> #include <assert.h> typedef struct schema_vtab schema_vtab; |
︙ | ︙ | |||
70 71 72 73 74 75 76 | int rowid; }; /* ** Table destructor for the schema module. */ static int schemaDestroy(sqlite3_vtab *pVtab){ | | | | | | 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | int rowid; }; /* ** Table destructor for the schema module. */ static int schemaDestroy(sqlite3_vtab *pVtab){ sqlite3_free(pVtab); return 0; } /* ** Table constructor for the schema module. */ static int schemaCreate( sqlite3 *db, void *pAux, int argc, const char *const*argv, sqlite3_vtab **ppVtab, char **pzErr ){ int rc = SQLITE_NOMEM; schema_vtab *pVtab = sqlite3_malloc(sizeof(schema_vtab)); if( pVtab ){ memset(pVtab, 0, sizeof(schema_vtab)); pVtab->db = db; #ifndef SQLITE_OMIT_VIRTUALTABLE rc = sqlite3_declare_vtab(db, SCHEMA); #endif } *ppVtab = (sqlite3_vtab *)pVtab; return rc; } /* ** Open a new cursor on the schema table. */ static int schemaOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ int rc = SQLITE_NOMEM; schema_cursor *pCur; pCur = sqlite3_malloc(sizeof(schema_cursor)); if( pCur ){ memset(pCur, 0, sizeof(schema_cursor)); *ppCursor = (sqlite3_vtab_cursor *)pCur; rc = SQLITE_OK; } return rc; } /* ** Close a schema table cursor. */ static int schemaClose(sqlite3_vtab_cursor *cur){ schema_cursor *pCur = (schema_cursor *)cur; sqlite3_finalize(pCur->pDbList); sqlite3_finalize(pCur->pTableList); sqlite3_finalize(pCur->pColumnList); sqlite3_free(pCur); return SQLITE_OK; } /* ** Retrieve a column of data. */ static int schemaColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ |
︙ | ︙ |
Changes to src/test_tclvar.c.
︙ | ︙ | |||
12 13 14 15 16 17 18 | ** 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. ** ** The emphasis of this file is a virtual table that provides ** access to TCL variables. ** | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | ** 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. ** ** The emphasis of this file is a virtual table that provides ** access to TCL variables. ** ** $Id: test_tclvar.c,v 1.12 2007/08/16 04:30:40 drh Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include "os.h" #include <stdlib.h> #include <string.h> |
︙ | ︙ | |||
54 55 56 57 58 59 60 | int argc, const char *const*argv, sqlite3_vtab **ppVtab, char **pzErr ){ tclvar_vtab *pVtab; static const char zSchema[] = "CREATE TABLE whatever(name TEXT, arrayname TEXT, value TEXT)"; | | | | | | 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | int argc, const char *const*argv, sqlite3_vtab **ppVtab, char **pzErr ){ tclvar_vtab *pVtab; static const char zSchema[] = "CREATE TABLE whatever(name TEXT, arrayname TEXT, value TEXT)"; pVtab = sqlite3_malloc( sizeof(*pVtab) ); if( pVtab==0 ) return SQLITE_NOMEM; *ppVtab = &pVtab->base; pVtab->interp = (Tcl_Interp *)pAux; sqlite3_declare_vtab(db, zSchema); return SQLITE_OK; } /* Note that for this virtual table, the xCreate and xConnect ** methods are identical. */ static int tclvarDisconnect(sqlite3_vtab *pVtab){ sqlite3_free(pVtab); return SQLITE_OK; } /* The xDisconnect and xDestroy methods are also the same */ /* ** Open a new tclvar cursor. */ static int tclvarOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ tclvar_cursor *pCur; pCur = sqlite3_malloc(sizeof(tclvar_cursor)); *ppCursor = &pCur->base; return SQLITE_OK; } /* ** Close a tclvar cursor. */ static int tclvarClose(sqlite3_vtab_cursor *cur){ tclvar_cursor *pCur = (tclvar_cursor *)cur; if( pCur->pList1 ){ Tcl_DecrRefCount(pCur->pList1); } if( pCur->pList2 ){ Tcl_DecrRefCount(pCur->pList2); } sqlite3_free(pCur); return SQLITE_OK; } /* ** Returns 1 if data is ready, or 0 if not. */ static int next2(Tcl_Interp *interp, tclvar_cursor *pCur, Tcl_Obj *pObj){ |
︙ | ︙ |
Changes to src/tokenize.c.
︙ | ︙ | |||
11 12 13 14 15 16 17 | ************************************************************************* ** An tokenizer for SQL ** ** This file contains C code that splits an SQL input string up into ** individual tokens and sends those tokens one-by-one over to the ** parser for analysis. ** | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ************************************************************************* ** An tokenizer for SQL ** ** This file contains C code that splits an SQL input string up into ** individual tokens and sends those tokens one-by-one over to the ** parser for analysis. ** ** $Id: tokenize.c,v 1.132 2007/08/16 04:30:40 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> #include <stdlib.h> /* |
︙ | ︙ | |||
380 381 382 383 384 385 386 | return getToken(z, tokenType); } /* ** Run the parser on the given SQL string. The parser structure is ** passed in. An SQLITE_ status code is returned. If an error occurs ** and pzErrMsg!=NULL then an error message might be written into | | | | | 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 | return getToken(z, tokenType); } /* ** Run the parser on the given SQL string. The parser structure is ** passed in. An SQLITE_ status code is returned. If an error occurs ** and pzErrMsg!=NULL then an error message might be written into ** memory obtained from sqlite3_malloc() and *pzErrMsg made to point to that ** error message. Or maybe not. */ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ int nErr = 0; int i; void *pEngine; int tokenType; int lastTokenParsed = -1; sqlite3 *db = pParse->db; if( db->activeVdbeCnt==0 ){ db->u1.isInterrupted = 0; } pParse->rc = SQLITE_OK; i = 0; pEngine = sqlite3ParserAlloc((void*(*)(size_t))sqlite3_malloc); if( pEngine==0 ){ return SQLITE_NOMEM; } assert( pParse->sLastToken.dyn==0 ); assert( pParse->pNewTable==0 ); assert( pParse->pNewTrigger==0 ); assert( pParse->nVar==0 ); assert( pParse->nVarExpr==0 ); assert( pParse->nVarExprAlloc==0 ); assert( pParse->apVarExpr==0 ); pParse->zTail = pParse->zSql = zSql; while( !db->mallocFailed && zSql[i]!=0 ){ assert( i>=0 ); pParse->sLastToken.z = (u8*)&zSql[i]; assert( pParse->sLastToken.dyn==0 ); pParse->sLastToken.n = getToken((unsigned char*)&zSql[i],&tokenType); i += pParse->sLastToken.n; if( i>SQLITE_MAX_SQL_LENGTH ){ pParse->rc = SQLITE_TOOBIG; |
︙ | ︙ | |||
430 431 432 433 434 435 436 | sqlite3SetString(pzErrMsg, "interrupt", (char*)0); goto abort_parse; } break; } case TK_ILLEGAL: { if( pzErrMsg ){ | | | 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 | sqlite3SetString(pzErrMsg, "interrupt", (char*)0); goto abort_parse; } break; } case TK_ILLEGAL: { if( pzErrMsg ){ sqlite3_free(*pzErrMsg); *pzErrMsg = sqlite3MPrintf("unrecognized token: \"%T\"", &pParse->sLastToken); } nErr++; goto abort_parse; } case TK_SEMI: { |
︙ | ︙ | |||
459 460 461 462 463 464 465 | if( zSql[i]==0 && nErr==0 && pParse->rc==SQLITE_OK ){ if( lastTokenParsed!=TK_SEMI ){ sqlite3Parser(pEngine, TK_SEMI, pParse->sLastToken, pParse); pParse->zTail = &zSql[i]; } sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse); } | | | | | | | 459 460 461 462 463 464 465 466 467 468 469 470 471 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 | if( zSql[i]==0 && nErr==0 && pParse->rc==SQLITE_OK ){ if( lastTokenParsed!=TK_SEMI ){ sqlite3Parser(pEngine, TK_SEMI, pParse->sLastToken, pParse); pParse->zTail = &zSql[i]; } sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse); } sqlite3ParserFree(pEngine, sqlite3_free); if( db->mallocFailed ){ pParse->rc = SQLITE_NOMEM; } if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){ sqlite3SetString(&pParse->zErrMsg, sqlite3ErrStr(pParse->rc), (char*)0); } if( pParse->zErrMsg ){ if( pzErrMsg && *pzErrMsg==0 ){ *pzErrMsg = pParse->zErrMsg; }else{ sqlite3_free(pParse->zErrMsg); } pParse->zErrMsg = 0; if( !nErr ) nErr++; } if( pParse->pVdbe && pParse->nErr>0 && pParse->nested==0 ){ sqlite3VdbeDelete(pParse->pVdbe); pParse->pVdbe = 0; } #ifndef SQLITE_OMIT_SHARED_CACHE if( pParse->nested==0 ){ sqlite3_free(pParse->aTableLock); pParse->aTableLock = 0; pParse->nTableLock = 0; } #endif if( !IN_DECLARE_VTAB ){ /* If the pParse->declareVtab flag is set, do not delete any table ** structure built up in pParse->pNewTable. The calling code (see vtab.c) ** will take responsibility for freeing the Table structure. */ sqlite3DeleteTable(pParse->pNewTable); } sqlite3DeleteTrigger(pParse->pNewTrigger); sqlite3_free(pParse->apVarExpr); if( nErr>0 && (pParse->rc==SQLITE_OK || pParse->rc==SQLITE_DONE) ){ pParse->rc = SQLITE_ERROR; } return nErr; } |
Changes to src/trigger.c.
︙ | ︙ | |||
17 18 19 20 21 22 23 | ** Delete a linked list of TriggerStep structures. */ void sqlite3DeleteTriggerStep(TriggerStep *pTriggerStep){ while( pTriggerStep ){ TriggerStep * pTmp = pTriggerStep; pTriggerStep = pTriggerStep->pNext; | | | | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | ** Delete a linked list of TriggerStep structures. */ void sqlite3DeleteTriggerStep(TriggerStep *pTriggerStep){ while( pTriggerStep ){ TriggerStep * pTmp = pTriggerStep; pTriggerStep = pTriggerStep->pNext; if( pTmp->target.dyn ) sqlite3_free((char*)pTmp->target.z); sqlite3ExprDelete(pTmp->pWhere); sqlite3ExprListDelete(pTmp->pExprList); sqlite3SelectDelete(pTmp->pSelect); sqlite3IdListDelete(pTmp->pIdList); sqlite3_free(pTmp); } } /* ** This is called by the parser when it sees a CREATE TRIGGER statement ** up to the point of the BEGIN before the trigger actions. A Trigger ** structure is generated based on the information available and stored |
︙ | ︙ | |||
79 80 81 82 83 84 85 | } /* If the trigger name was unqualified, and the table is a temp table, ** then set iDb to 1 to create the trigger in the temporary database. ** If sqlite3SrcListLookup() returns 0, indicating the table does not ** exist, the error is caught by the block below. */ | | | | | 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | } /* If the trigger name was unqualified, and the table is a temp table, ** then set iDb to 1 to create the trigger in the temporary database. ** If sqlite3SrcListLookup() returns 0, indicating the table does not ** exist, the error is caught by the block below. */ if( !pTableName || db->mallocFailed ){ goto trigger_cleanup; } pTab = sqlite3SrcListLookup(pParse, pTableName); if( pName2->n==0 && pTab && pTab->pSchema==db->aDb[1].pSchema ){ iDb = 1; } /* Ensure the table name matches database name and that the table exists */ if( db->mallocFailed ) goto trigger_cleanup; assert( pTableName->nSrc==1 ); if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", pName) && sqlite3FixSrcList(&sFix, pTableName) ){ goto trigger_cleanup; } pTab = sqlite3SrcListLookup(pParse, pTableName); if( !pTab ){ /* The table does not exist. */ goto trigger_cleanup; } if( IsVirtual(pTab) ){ sqlite3ErrorMsg(pParse, "cannot create triggers on virtual tables"); goto trigger_cleanup; } /* Check that the trigger name is not reserved and that no trigger of the ** specified name exists */ zName = sqlite3NameFromToken(db, pName); if( !zName || SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ goto trigger_cleanup; } if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash), zName,strlen(zName)) ){ if( !noErr ){ sqlite3ErrorMsg(pParse, "trigger %T already exists", pName); } |
︙ | ︙ | |||
164 165 166 167 168 169 170 | ** elsewhere. */ if (tr_tm == TK_INSTEAD){ tr_tm = TK_BEFORE; } /* Build the Trigger object */ | | | | | | | | 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 | ** elsewhere. */ if (tr_tm == TK_INSTEAD){ tr_tm = TK_BEFORE; } /* Build the Trigger object */ pTrigger = (Trigger*)sqlite3DbMallocZero(db, sizeof(Trigger)); if( pTrigger==0 ) goto trigger_cleanup; pTrigger->name = zName; zName = 0; pTrigger->table = sqlite3DbStrDup(db, pTableName->a[0].zName); pTrigger->pSchema = db->aDb[iDb].pSchema; pTrigger->pTabSchema = pTab->pSchema; pTrigger->op = op; pTrigger->tr_tm = tr_tm==TK_BEFORE ? TRIGGER_BEFORE : TRIGGER_AFTER; pTrigger->pWhen = sqlite3ExprDup(db, pWhen); pTrigger->pColumns = sqlite3IdListDup(db, pColumns); sqlite3TokenCopy(db, &pTrigger->nameToken,pName); assert( pParse->pNewTrigger==0 ); pParse->pNewTrigger = pTrigger; trigger_cleanup: sqlite3_free(zName); sqlite3SrcListDelete(pTableName); sqlite3IdListDelete(pColumns); sqlite3ExprDelete(pWhen); if( !pParse->pNewTrigger ){ sqlite3DeleteTrigger(pTrigger); }else{ assert( pParse->pNewTrigger==pTrigger ); |
︙ | ︙ | |||
260 261 262 263 264 265 266 | if( db->init.busy ){ int n; Table *pTab; Trigger *pDel; pDel = sqlite3HashInsert(&db->aDb[iDb].pSchema->trigHash, pTrig->name, strlen(pTrig->name), pTrig); if( pDel ){ | | | | | | | | | | | | > | | | > | | | > > > > | | | | | | | | 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 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 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 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 | if( db->init.busy ){ int n; Table *pTab; Trigger *pDel; pDel = sqlite3HashInsert(&db->aDb[iDb].pSchema->trigHash, pTrig->name, strlen(pTrig->name), pTrig); if( pDel ){ assert( db->mallocFailed && pDel==pTrig ); goto triggerfinish_cleanup; } n = strlen(pTrig->table) + 1; pTab = sqlite3HashFind(&pTrig->pTabSchema->tblHash, pTrig->table, n); assert( pTab!=0 ); pTrig->pNext = pTab->pTrigger; pTab->pTrigger = pTrig; pTrig = 0; } triggerfinish_cleanup: sqlite3DeleteTrigger(pTrig); assert( !pParse->pNewTrigger ); sqlite3DeleteTriggerStep(pStepList); } /* ** Make a copy of all components of the given trigger step. This has ** the effect of copying all Expr.token.z values into memory obtained ** from sqlite3_malloc(). As initially created, the Expr.token.z values ** all point to the input string that was fed to the parser. But that ** string is ephemeral - it will go away as soon as the sqlite3_exec() ** call that started the parser exits. This routine makes a persistent ** copy of all the Expr.token.z strings so that the TriggerStep structure ** will be valid even after the sqlite3_exec() call returns. */ static void sqlitePersistTriggerStep(sqlite3 *db, TriggerStep *p){ if( p->target.z ){ p->target.z = (u8*)sqlite3DbStrNDup(db, (char*)p->target.z, p->target.n); p->target.dyn = 1; } if( p->pSelect ){ Select *pNew = sqlite3SelectDup(db, p->pSelect); sqlite3SelectDelete(p->pSelect); p->pSelect = pNew; } if( p->pWhere ){ Expr *pNew = sqlite3ExprDup(db, p->pWhere); sqlite3ExprDelete(p->pWhere); p->pWhere = pNew; } if( p->pExprList ){ ExprList *pNew = sqlite3ExprListDup(db, p->pExprList); sqlite3ExprListDelete(p->pExprList); p->pExprList = pNew; } if( p->pIdList ){ IdList *pNew = sqlite3IdListDup(db, p->pIdList); sqlite3IdListDelete(p->pIdList); p->pIdList = pNew; } } /* ** Turn a SELECT statement (that the pSelect parameter points to) into ** a trigger step. Return a pointer to a TriggerStep structure. ** ** The parser calls this routine when it finds a SELECT statement in ** body of a TRIGGER. */ TriggerStep *sqlite3TriggerSelectStep(sqlite3 *db, Select *pSelect){ TriggerStep *pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep)); if( pTriggerStep==0 ) { sqlite3SelectDelete(pSelect); return 0; } pTriggerStep->op = TK_SELECT; pTriggerStep->pSelect = pSelect; pTriggerStep->orconf = OE_Default; sqlitePersistTriggerStep(db, pTriggerStep); return pTriggerStep; } /* ** Build a trigger step out of an INSERT statement. Return a pointer ** to the new trigger step. ** ** The parser calls this routine when it sees an INSERT inside the ** body of a trigger. */ TriggerStep *sqlite3TriggerInsertStep( sqlite3 *db, /* The database connection */ Token *pTableName, /* Name of the table into which we insert */ IdList *pColumn, /* List of columns in pTableName to insert into */ ExprList *pEList, /* The VALUE clause: a list of values to be inserted */ Select *pSelect, /* A SELECT statement that supplies values */ int orconf /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */ ){ TriggerStep *pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep)); assert(pEList == 0 || pSelect == 0); assert(pEList != 0 || pSelect != 0); if( pTriggerStep ){ pTriggerStep->op = TK_INSERT; pTriggerStep->pSelect = pSelect; pTriggerStep->target = *pTableName; pTriggerStep->pIdList = pColumn; pTriggerStep->pExprList = pEList; pTriggerStep->orconf = orconf; sqlitePersistTriggerStep(db, pTriggerStep); }else{ sqlite3IdListDelete(pColumn); sqlite3ExprListDelete(pEList); sqlite3SelectDelete(pSelect); } return pTriggerStep; } /* ** Construct a trigger step that implements an UPDATE statement and return ** a pointer to that trigger step. The parser calls this routine when it ** sees an UPDATE statement inside the body of a CREATE TRIGGER. */ TriggerStep *sqlite3TriggerUpdateStep( sqlite3 *db, /* The database connection */ Token *pTableName, /* Name of the table to be updated */ ExprList *pEList, /* The SET clause: list of column and new values */ Expr *pWhere, /* The WHERE clause */ int orconf /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */ ){ TriggerStep *pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep)); if( pTriggerStep==0 ){ sqlite3ExprListDelete(pEList); sqlite3ExprDelete(pWhere); return 0; } pTriggerStep->op = TK_UPDATE; pTriggerStep->target = *pTableName; pTriggerStep->pExprList = pEList; pTriggerStep->pWhere = pWhere; pTriggerStep->orconf = orconf; sqlitePersistTriggerStep(db, pTriggerStep); return pTriggerStep; } /* ** Construct a trigger step that implements a DELETE statement and return ** a pointer to that trigger step. The parser calls this routine when it ** sees a DELETE statement inside the body of a CREATE TRIGGER. */ TriggerStep *sqlite3TriggerDeleteStep( sqlite3 *db, /* Database connection */ Token *pTableName, /* The table from which rows are deleted */ Expr *pWhere /* The WHERE clause */ ){ TriggerStep *pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep)); if( pTriggerStep==0 ){ sqlite3ExprDelete(pWhere); return 0; } pTriggerStep->op = TK_DELETE; pTriggerStep->target = *pTableName; pTriggerStep->pWhere = pWhere; pTriggerStep->orconf = OE_Default; sqlitePersistTriggerStep(db, pTriggerStep); return pTriggerStep; } /* ** Recursively delete a Trigger structure */ void sqlite3DeleteTrigger(Trigger *pTrigger){ if( pTrigger==0 ) return; sqlite3DeleteTriggerStep(pTrigger->step_list); sqlite3_free(pTrigger->name); sqlite3_free(pTrigger->table); sqlite3ExprDelete(pTrigger->pWhen); sqlite3IdListDelete(pTrigger->pColumns); if( pTrigger->nameToken.dyn ) sqlite3_free((char*)pTrigger->nameToken.z); sqlite3_free(pTrigger); } /* ** This function is called to drop a trigger from the database schema. ** ** This may be called directly from the parser and therefore identifies ** the trigger by name. The sqlite3DropTriggerPtr() routine does the ** same job as this routine except it takes a pointer to the trigger ** instead of the trigger name. **/ void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr){ Trigger *pTrigger = 0; int i; const char *zDb; const char *zName; int nName; sqlite3 *db = pParse->db; if( db->mallocFailed ) goto drop_trigger_cleanup; if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ goto drop_trigger_cleanup; } assert( pName->nSrc==1 ); zDb = pName->a[0].zDatabase; zName = pName->a[0].zName; |
︙ | ︙ | |||
640 641 642 643 644 645 646 | SrcList *pSrc; /* SrcList to be returned */ iDb = sqlite3SchemaToIndex(pParse->db, pStep->pTrig->pSchema); if( iDb==0 || iDb>=2 ){ assert( iDb<pParse->db->nDb ); sDb.z = (u8*)pParse->db->aDb[iDb].zName; sDb.n = strlen((char*)sDb.z); | | | > | | | | | | | > | 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 | SrcList *pSrc; /* SrcList to be returned */ iDb = sqlite3SchemaToIndex(pParse->db, pStep->pTrig->pSchema); if( iDb==0 || iDb>=2 ){ assert( iDb<pParse->db->nDb ); sDb.z = (u8*)pParse->db->aDb[iDb].zName; sDb.n = strlen((char*)sDb.z); pSrc = sqlite3SrcListAppend(pParse->db, 0, &sDb, &pStep->target); } else { pSrc = sqlite3SrcListAppend(pParse->db, 0, &pStep->target, 0); } return pSrc; } /* ** Generate VDBE code for zero or more statements inside the body of a ** trigger. */ static int codeTriggerProgram( Parse *pParse, /* The parser context */ TriggerStep *pStepList, /* List of statements inside the trigger body */ int orconfin /* Conflict algorithm. (OE_Abort, etc) */ ){ TriggerStep * pTriggerStep = pStepList; int orconf; Vdbe *v = pParse->pVdbe; sqlite3 *db = pParse->db; assert( pTriggerStep!=0 ); assert( v!=0 ); sqlite3VdbeAddOp(v, OP_ContextPush, 0, 0); VdbeComment((v, "# begin trigger %s", pStepList->pTrig->name)); while( pTriggerStep ){ orconf = (orconfin == OE_Default)?pTriggerStep->orconf:orconfin; pParse->trigStack->orconf = orconf; switch( pTriggerStep->op ){ case TK_SELECT: { Select *ss = sqlite3SelectDup(db, pTriggerStep->pSelect); if( ss ){ sqlite3SelectResolve(pParse, ss, 0); sqlite3Select(pParse, ss, SRT_Discard, 0, 0, 0, 0, 0); sqlite3SelectDelete(ss); } break; } case TK_UPDATE: { SrcList *pSrc; pSrc = targetSrcList(pParse, pTriggerStep); sqlite3VdbeAddOp(v, OP_ResetCount, 0, 0); sqlite3Update(pParse, pSrc, sqlite3ExprListDup(db, pTriggerStep->pExprList), sqlite3ExprDup(db, pTriggerStep->pWhere), orconf); sqlite3VdbeAddOp(v, OP_ResetCount, 1, 0); break; } case TK_INSERT: { SrcList *pSrc; pSrc = targetSrcList(pParse, pTriggerStep); sqlite3VdbeAddOp(v, OP_ResetCount, 0, 0); sqlite3Insert(pParse, pSrc, sqlite3ExprListDup(db, pTriggerStep->pExprList), sqlite3SelectDup(db, pTriggerStep->pSelect), sqlite3IdListDup(db, pTriggerStep->pIdList), orconf); sqlite3VdbeAddOp(v, OP_ResetCount, 1, 0); break; } case TK_DELETE: { SrcList *pSrc; sqlite3VdbeAddOp(v, OP_ResetCount, 0, 0); pSrc = targetSrcList(pParse, pTriggerStep); sqlite3DeleteFrom(pParse, pSrc, sqlite3ExprDup(db, pTriggerStep->pWhere)); sqlite3VdbeAddOp(v, OP_ResetCount, 1, 0); break; } default: assert(0); } pTriggerStep = pTriggerStep->pNext; |
︙ | ︙ | |||
801 802 803 804 805 806 807 | trigStackEntry.pNext = pParse->trigStack; trigStackEntry.ignoreJump = ignoreJump; pParse->trigStack = &trigStackEntry; sqlite3AuthContextPush(pParse, &sContext, p->name); /* code the WHEN clause */ endTrigger = sqlite3VdbeMakeLabel(pParse->pVdbe); | | | 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 | trigStackEntry.pNext = pParse->trigStack; trigStackEntry.ignoreJump = ignoreJump; pParse->trigStack = &trigStackEntry; sqlite3AuthContextPush(pParse, &sContext, p->name); /* code the WHEN clause */ endTrigger = sqlite3VdbeMakeLabel(pParse->pVdbe); whenExpr = sqlite3ExprDup(pParse->db, p->pWhen); if( sqlite3ExprResolveNames(&sNC, whenExpr) ){ pParse->trigStack = trigStackEntry.pNext; sqlite3ExprDelete(whenExpr); return 1; } sqlite3ExprIfFalse(pParse, whenExpr, endTrigger, 1); sqlite3ExprDelete(whenExpr); |
︙ | ︙ |
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.139 2007/08/16 04:30:40 drh Exp $ */ #include "sqliteInt.h" #ifndef SQLITE_OMIT_VIRTUALTABLE /* Forward declaration */ static void updateVirtualTable( Parse *pParse, /* The parsing context */ |
︙ | ︙ | |||
111 112 113 114 115 116 117 | int triggers_exist = 0; /* True if any row triggers exist */ #endif int newIdx = -1; /* index of trigger "new" temp table */ int oldIdx = -1; /* index of trigger "old" temp table */ sContext.pParse = 0; | > | < | 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | int triggers_exist = 0; /* True if any row triggers exist */ #endif int newIdx = -1; /* index of trigger "new" temp table */ int oldIdx = -1; /* index of trigger "old" temp table */ sContext.pParse = 0; db = pParse->db; if( pParse->nErr || db->mallocFailed ){ goto update_cleanup; } assert( pTabList->nSrc==1 ); /* Locate the table which we want to update. */ pTab = sqlite3SrcListLookup(pParse, pTabList); if( pTab==0 ) goto update_cleanup; iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); |
︙ | ︙ | |||
144 145 146 147 148 149 150 | if( sqlite3IsReadOnly(pParse, pTab, triggers_exist) ){ goto update_cleanup; } if( sqlite3ViewGetColumnNames(pParse, pTab) ){ goto update_cleanup; } | | | 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | if( sqlite3IsReadOnly(pParse, pTab, triggers_exist) ){ goto update_cleanup; } if( sqlite3ViewGetColumnNames(pParse, pTab) ){ goto update_cleanup; } aXRef = sqlite3DbMallocRaw(db, sizeof(int) * pTab->nCol ); if( aXRef==0 ) goto update_cleanup; for(i=0; i<pTab->nCol; i++) aXRef[i] = -1; /* If there are FOR EACH ROW triggers, allocate cursors for the ** special OLD and NEW tables */ if( triggers_exist ){ |
︙ | ︙ | |||
231 232 233 234 235 236 237 | for(i=0; i<pIdx->nColumn; i++){ if( aXRef[pIdx->aiColumn[i]]>=0 ) break; } } if( i<pIdx->nColumn ) nIdx++; } if( nIdxTotal>0 ){ | | | 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 | for(i=0; i<pIdx->nColumn; i++){ if( aXRef[pIdx->aiColumn[i]]>=0 ) break; } } if( i<pIdx->nColumn ) nIdx++; } if( nIdxTotal>0 ){ apIdx = sqlite3DbMallocRaw(db, sizeof(Index*) * nIdx + nIdxTotal ); if( apIdx==0 ) goto update_cleanup; aIdxUsed = (char*)&apIdx[nIdx]; } for(nIdx=j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ if( chngRowid ){ i = 0; }else{ |
︙ | ︙ | |||
287 288 289 290 291 292 293 | } /* If we are trying to update a view, realize that view into ** a ephemeral table. */ if( isView ){ Select *pView; | | | 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 | } /* If we are trying to update a view, realize that view into ** a ephemeral table. */ if( isView ){ Select *pView; pView = sqlite3SelectDup(db, pTab->pSelect); sqlite3Select(pParse, pView, SRT_EphemTab, iCur, 0, 0, 0, 0); sqlite3SelectDelete(pView); } /* Begin the database scan */ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0); |
︙ | ︙ | |||
521 522 523 524 525 526 527 | sqlite3VdbeAddOp(v, OP_Callback, 1, 0); sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", P3_STATIC); } update_cleanup: sqlite3AuthContextPop(&sContext); | | | | 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 | sqlite3VdbeAddOp(v, OP_Callback, 1, 0); sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", P3_STATIC); } update_cleanup: sqlite3AuthContextPop(&sContext); sqlite3_free(apIdx); sqlite3_free(aXRef); sqlite3SrcListDelete(pTabList); sqlite3ExprListDelete(pChanges); sqlite3ExprDelete(pWhere); return; } #ifndef SQLITE_OMIT_VIRTUALTABLE |
︙ | ︙ | |||
565 566 567 568 569 570 571 572 573 574 575 | 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. */ | > | > | > | | | | | 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 | 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 */ sqlite3 *db = pParse->db; /* Database connection */ /* Construct the SELECT statement that will find the new values for ** all updated rows. */ pEList = sqlite3ExprListAppend(pParse, 0, sqlite3CreateIdExpr(pParse, "_rowid_"), 0); if( pRowid ){ pEList = sqlite3ExprListAppend(pParse, pEList, sqlite3ExprDup(db, pRowid), 0); } assert( pTab->iPKey<0 ); for(i=0; i<pTab->nCol; i++){ if( aXRef[i]>=0 ){ pExpr = sqlite3ExprDup(db, pChanges->a[aXRef[i]].pExpr); }else{ pExpr = sqlite3CreateIdExpr(pParse, pTab->aCol[i].zName); } pEList = sqlite3ExprListAppend(pParse, pEList, pExpr, 0); } pSelect = sqlite3SelectNew(pParse, 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)); |
︙ | ︙ |
Changes to src/utf.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 routines used to translate between UTF-8, ** UTF-16, UTF-16BE, and UTF-16LE. ** | | | 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 routines used to translate between UTF-8, ** UTF-16, UTF-16BE, and UTF-16LE. ** ** $Id: utf.c,v 1.54 2007/08/16 04:30:40 drh Exp $ ** ** Notes on UTF-8: ** ** Byte-0 Byte-1 Byte-2 Byte-3 Value ** 0xxxxxxx 00000000 00000000 0xxxxxxx ** 110yyyyy 10xxxxxx 00000000 00000yyy yyxxxxxx ** 1110zzzz 10yyyyyy 10xxxxxx 00000000 zzzzyyyy yyxxxxxx |
︙ | ︙ | |||
183 184 185 186 187 188 189 | #ifndef SQLITE_OMIT_UTF16 /* ** This routine transforms the internal text encoding used by pMem to ** desiredEnc. It is an error if the string is already of the desired ** encoding, or if *pMem does not contain a string value. */ | | | 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 | #ifndef SQLITE_OMIT_UTF16 /* ** This routine transforms the internal text encoding used by pMem to ** desiredEnc. It is an error if the string is already of the desired ** encoding, or if *pMem does not contain a string value. */ int sqlite3VdbeMemTranslate(sqlite3 *db, Mem *pMem, u8 desiredEnc){ unsigned char zShort[NBFS]; /* Temporary short output buffer */ int len; /* Maximum length of output string in bytes */ unsigned char *zOut; /* Output buffer */ unsigned char *zIn; /* Input iterator */ unsigned char *zTerm; /* End of input */ unsigned char *z; /* Output iterator */ unsigned int c; |
︙ | ︙ | |||
250 251 252 253 254 255 256 | len = pMem->n * 2 + 2; } /* Set zIn to point at the start of the input buffer and zTerm to point 1 ** byte past the end. ** ** Variable zOut is set to point at the output buffer. This may be space | | | | | 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 | len = pMem->n * 2 + 2; } /* Set zIn to point at the start of the input buffer and zTerm to point 1 ** byte past the end. ** ** Variable zOut is set to point at the output buffer. This may be space ** obtained from sqlite3_malloc(), or Mem.zShort, if it large enough and ** not in use, or the zShort array on the stack (see above). */ zIn = (u8*)pMem->z; zTerm = &zIn[pMem->n]; if( len>NBFS ){ zOut = sqlite3DbMallocRaw(db, len); if( !zOut ) return SQLITE_NOMEM; }else{ zOut = zShort; } z = zOut; if( pMem->enc==SQLITE_UTF8 ){ |
︙ | ︙ | |||
398 399 400 401 402 403 404 | } return r; } #ifndef SQLITE_OMIT_UTF16 /* ** Convert a UTF-16 string in the native encoding into a UTF-8 string. | | | | | | | | | | 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 | } return r; } #ifndef SQLITE_OMIT_UTF16 /* ** Convert a UTF-16 string in the native encoding into a UTF-8 string. ** Memory to hold the UTF-8 string is obtained from sqlite3_malloc and must ** be freed by the calling function. ** ** NULL is returned if there is an allocation error. */ char *sqlite3Utf16to8(sqlite3 *db, const void *z, int nByte){ Mem m; memset(&m, 0, sizeof(m)); sqlite3VdbeMemSetStr(db, &m, z, nByte, SQLITE_UTF16NATIVE, SQLITE_STATIC); sqlite3VdbeChangeEncoding(db, &m, SQLITE_UTF8); assert( (m.flags & MEM_Term)!=0 || db->mallocFailed ); assert( (m.flags & MEM_Str)!=0 || db->mallocFailed ); return (m.flags & MEM_Dyn)!=0 ? m.z : sqlite3DbStrDup(db, m.z); } /* ** pZ is a UTF-16 encoded unicode string. If nChar is less than zero, ** return the number of bytes up to (but not including), the first pair ** of consecutive 0x00 bytes in pZ. If nChar is not less than zero, ** then return the number of bytes in the first nChar unicode characters |
︙ | ︙ |
Changes to src/util.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** Utility functions used throughout sqlite. ** ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** Utility functions used throughout sqlite. ** ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** ** $Id: util.c,v 1.208 2007/08/16 04:30:40 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <stdarg.h> #include <ctype.h> |
︙ | ︙ | |||
627 628 629 630 631 632 633 | #if !defined(SQLITE_OMIT_BLOB_LITERAL) || defined(SQLITE_HAS_CODEC) /* ** Convert a BLOB literal of the form "x'hhhhhh'" into its binary ** value. Return a pointer to its binary value. Space to hold the ** binary value has been obtained from malloc and must be freed by ** the calling routine. */ | | | | 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 | #if !defined(SQLITE_OMIT_BLOB_LITERAL) || defined(SQLITE_HAS_CODEC) /* ** Convert a BLOB literal of the form "x'hhhhhh'" into its binary ** value. Return a pointer to its binary value. Space to hold the ** binary value has been obtained from malloc and must be freed by ** the calling routine. */ void *sqlite3HexToBlob(sqlite3 *db, const char *z){ char *zBlob; int i; int n = strlen(z); if( n%2 ) return 0; zBlob = (char *)sqlite3DbMallocRaw(db, n/2); if( zBlob ){ for(i=0; i<n; i+=2){ zBlob[i/2] = (hexToInt(z[i])<<4) | hexToInt(z[i+1]); } } return zBlob; } |
︙ | ︙ | |||
695 696 697 698 699 700 701 | return 0; }else { db->magic = SQLITE_MAGIC_ERROR; db->u1.isInterrupted = 1; return 1; } } | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 695 696 697 698 699 700 701 | return 0; }else { db->magic = SQLITE_MAGIC_ERROR; db->u1.isInterrupted = 1; return 1; } } |
Changes to src/vacuum.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** This file contains code used to implement the VACUUM command. ** ** Most of the code in this file may be omitted by defining the ** SQLITE_OMIT_VACUUM macro. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** This file contains code used to implement the VACUUM command. ** ** Most of the code in this file may be omitted by defining the ** SQLITE_OMIT_VACUUM macro. ** ** $Id: vacuum.c,v 1.70 2007/08/16 04:30:40 drh Exp $ */ #include "sqliteInt.h" #include "vdbeInt.h" #include "os.h" #if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH) /* |
︙ | ︙ | |||
108 109 110 111 112 113 114 | rc = execSql(db, zSql); if( rc!=SQLITE_OK ) goto end_of_vacuum; pDb = &db->aDb[db->nDb-1]; assert( strcmp(db->aDb[db->nDb-1].zName,"vacuum_db")==0 ); pTemp = db->aDb[db->nDb-1].pBt; sqlite3BtreeSetPageSize(pTemp, sqlite3BtreeGetPageSize(pMain), sqlite3BtreeGetReserve(pMain)); | | | 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | rc = execSql(db, zSql); if( rc!=SQLITE_OK ) goto end_of_vacuum; pDb = &db->aDb[db->nDb-1]; assert( strcmp(db->aDb[db->nDb-1].zName,"vacuum_db")==0 ); pTemp = db->aDb[db->nDb-1].pBt; sqlite3BtreeSetPageSize(pTemp, sqlite3BtreeGetPageSize(pMain), sqlite3BtreeGetReserve(pMain)); if( db->mallocFailed ){ rc = SQLITE_NOMEM; goto end_of_vacuum; } assert( sqlite3BtreeGetPageSize(pTemp)==sqlite3BtreeGetPageSize(pMain) ); rc = execSql(db, "PRAGMA vacuum_db.synchronous=OFF"); if( rc!=SQLITE_OK ){ goto end_of_vacuum; |
︙ | ︙ |
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.640 2007/08/16 04:30:40 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> #include <math.h> #include "vdbeInt.h" |
︙ | ︙ | |||
106 107 108 109 110 111 112 | ** Convert the given stack entity into a string if it isn't one ** already. Return non-zero if a malloc() fails. */ #define Stringify(P, enc) \ if(((P)->flags&(MEM_Str|MEM_Blob))==0 && sqlite3VdbeMemStringify(P,enc)) \ { goto no_mem; } | < < < < < < < < < | 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | ** Convert the given stack entity into a string if it isn't one ** already. Return non-zero if a malloc() fails. */ #define Stringify(P, enc) \ if(((P)->flags&(MEM_Str|MEM_Blob))==0 && sqlite3VdbeMemStringify(P,enc)) \ { goto no_mem; } /* ** The header of a record consists of a sequence variable-length integers. ** These integers are almost always small and are encoded as a single byte. ** The following macro takes advantage this fact to provide a fast decode ** of the integers in a record header. It is faster for the common case ** where the integer is a single byte. It is a little slower when the ** integer is two or more bytes. But overall it is faster. |
︙ | ︙ | |||
202 203 204 205 206 207 208 | */ static Cursor *allocateCursor(Vdbe *p, int iCur, int iDb){ Cursor *pCx; assert( iCur<p->nCursor ); if( p->apCsr[iCur] ){ sqlite3VdbeFreeCursor(p, p->apCsr[iCur]); } | | | | | | 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 | */ static Cursor *allocateCursor(Vdbe *p, int iCur, int iDb){ Cursor *pCx; assert( iCur<p->nCursor ); if( p->apCsr[iCur] ){ sqlite3VdbeFreeCursor(p, p->apCsr[iCur]); } p->apCsr[iCur] = pCx = sqlite3MallocZero( sizeof(Cursor) ); if( pCx ){ pCx->iDb = iDb; } return pCx; } /* ** Try to convert a value into a numeric representation if we can ** do so without loss of information. In other words, if the string ** looks like a number, convert it into a number. If it does not ** look like a number, leave it alone. */ static void applyNumericAffinity(sqlite3 *db, Mem *pRec){ if( (pRec->flags & (MEM_Real|MEM_Int))==0 ){ int realnum; sqlite3VdbeMemNulTerminate(db, pRec); if( (pRec->flags&MEM_Str) && sqlite3IsNumber(pRec->z, &realnum, pRec->enc) ){ i64 value; sqlite3VdbeChangeEncoding(db, pRec, SQLITE_UTF8); if( !realnum && sqlite3Atoi64(pRec->z, &value) ){ sqlite3VdbeMemRelease(pRec); pRec->u.i = value; pRec->flags = MEM_Int; }else{ sqlite3VdbeMemRealify(pRec); } |
︙ | ︙ | |||
252 253 254 255 256 257 258 | ** ** SQLITE_AFF_TEXT: ** Convert pRec to a text representation. ** ** SQLITE_AFF_NONE: ** No-op. pRec is unchanged. */ | | > > > > > | | | 243 244 245 246 247 248 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 | ** ** SQLITE_AFF_TEXT: ** Convert pRec to a text representation. ** ** SQLITE_AFF_NONE: ** No-op. pRec is unchanged. */ static void applyAffinity( sqlite3 *db, /* Report malloc() errors to this db connection */ Mem *pRec, /* The value to apply affinity to */ char affinity, /* The affinity to be applied */ u8 enc /* Use this text encoding */ ){ if( affinity==SQLITE_AFF_TEXT ){ /* Only attempt the conversion to TEXT if there is an integer or real ** representation (blob and NULL do not get converted) but no string ** representation. */ if( 0==(pRec->flags&MEM_Str) && (pRec->flags&(MEM_Real|MEM_Int)) ){ sqlite3VdbeMemStringify(db, pRec, enc); } pRec->flags &= ~(MEM_Real|MEM_Int); }else if( affinity!=SQLITE_AFF_NONE ){ assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL || affinity==SQLITE_AFF_NUMERIC ); applyNumericAffinity(db, pRec); if( pRec->flags & MEM_Real ){ sqlite3VdbeIntegerAffinity(pRec); } } } /* |
︙ | ︙ | |||
425 426 427 428 429 430 431 | ** SQLITE_ROW. ** ** If an attempt is made to open a locked database, then this routine ** will either invoke the busy callback (if there is one) or it will ** return SQLITE_BUSY. ** ** If an error occurs, an error message is written to memory obtained | | | 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 | ** SQLITE_ROW. ** ** If an attempt is made to open a locked database, then this routine ** will either invoke the busy callback (if there is one) or it will ** return SQLITE_BUSY. ** ** If an error occurs, an error message is written to memory obtained ** from sqlite3_malloc() and p->zErrMsg is made to point to that memory. ** The error code is stored in p->rc and this routine returns SQLITE_ERROR. ** ** If the callback ever returns non-zero, then the program exits ** immediately. There will be no error message but the p->rc field is ** set to SQLITE_ABORT and this routine will return SQLITE_ERROR. ** ** A memory allocation error causes p->rc to be set to SQLITE_NOMEM and this |
︙ | ︙ | |||
497 498 499 500 501 502 503 | if( sqlite3OsFileExists("vdbe_trace") ){ p->trace = stdout; } #endif for(pc=p->pc; rc==SQLITE_OK; pc++){ assert( pc>=0 && pc<p->nOp ); assert( pTos<=&p->aStack[pc] ); | | | 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 | if( sqlite3OsFileExists("vdbe_trace") ){ p->trace = stdout; } #endif for(pc=p->pc; rc==SQLITE_OK; pc++){ assert( pc>=0 && pc<p->nOp ); assert( pTos<=&p->aStack[pc] ); if( db->mallocFailed ) goto no_mem; #ifdef VDBE_PROFILE origPc = pc; start = hwtime(); #endif pOp = &p->aOp[pc]; /* Only allow tracing if SQLITE_DEBUG is defined. |
︙ | ︙ | |||
749 750 751 752 753 754 755 | assert( pOp->p1 < SQLITE_MAX_LENGTH ); #ifndef SQLITE_OMIT_UTF16 if( encoding!=SQLITE_UTF8 ){ pTos++; sqlite3VdbeMemSetStr(pTos, pOp->p3, -1, SQLITE_UTF8, SQLITE_STATIC); if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pTos, encoding) ) goto no_mem; | | | | 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 | assert( pOp->p1 < SQLITE_MAX_LENGTH ); #ifndef SQLITE_OMIT_UTF16 if( encoding!=SQLITE_UTF8 ){ pTos++; sqlite3VdbeMemSetStr(pTos, pOp->p3, -1, SQLITE_UTF8, SQLITE_STATIC); if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pTos, encoding) ) goto no_mem; if( SQLITE_OK!=sqlite3VdbeMemDynamicify(db, pTos) ) goto no_mem; pTos->flags &= ~(MEM_Dyn); pTos->flags |= MEM_Static; if( pOp->p3type==P3_DYNAMIC ){ sqlite3_free(pOp->p3); } pOp->p3type = P3_DYNAMIC; pOp->p3 = pTos->z; pOp->p1 = pTos->n; assert( pOp->p1 < SQLITE_MAX_LENGTH ); /* Due to SQLITE_MAX_SQL_LENGTH */ break; } |
︙ | ︙ | |||
810 811 812 813 814 815 816 | pOp->p1 = strlen(pOp->p3)/2; assert( SQLITE_MAX_SQL_LENGTH < SQLITE_MAX_LENGTH ); assert( pOp->p1 < SQLITE_MAX_LENGTH ); if( pOp->p1 ){ char *zBlob = sqlite3HexToBlob(pOp->p3); if( !zBlob ) goto no_mem; if( pOp->p3type==P3_DYNAMIC ){ | | | | 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 | pOp->p1 = strlen(pOp->p3)/2; assert( SQLITE_MAX_SQL_LENGTH < SQLITE_MAX_LENGTH ); assert( pOp->p1 < SQLITE_MAX_LENGTH ); if( pOp->p1 ){ char *zBlob = sqlite3HexToBlob(pOp->p3); if( !zBlob ) goto no_mem; if( pOp->p3type==P3_DYNAMIC ){ sqlite3_free(pOp->p3); } pOp->p3 = zBlob; pOp->p3type = P3_DYNAMIC; }else{ if( pOp->p3type==P3_DYNAMIC ){ sqlite3_free(pOp->p3); } pOp->p3type = P3_STATIC; pOp->p3 = ""; } /* Fall through to the next case, OP_Blob. */ } |
︙ | ︙ | |||
1011 1012 1013 1014 1015 1016 1017 | ** ** Look at the first P1+2 elements of the stack. Append them all ** together with the lowest element first. The original P1+2 elements ** are popped from the stack if P2==0 and retained if P2==1. If ** any element of the stack is NULL, then the result is NULL. ** ** When P1==1, this routine makes a copy of the top stack element | | | 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 | ** ** Look at the first P1+2 elements of the stack. Append them all ** together with the lowest element first. The original P1+2 elements ** are popped from the stack if P2==0 and retained if P2==1. If ** any element of the stack is NULL, then the result is NULL. ** ** When P1==1, this routine makes a copy of the top stack element ** into memory obtained from sqlite3_malloc(). */ case OP_Concat: { /* same as TK_CONCAT */ char *zNew; i64 nByte; int nField; int i, j; Mem *pTerm; |
︙ | ︙ | |||
1052 1053 1054 1055 1056 1057 1058 | }else{ /* Otherwise malloc() space for the result and concatenate all the ** stack values. */ if( nByte+2>SQLITE_MAX_LENGTH ){ goto too_big; } | | | 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 | }else{ /* Otherwise malloc() space for the result and concatenate all the ** stack values. */ if( nByte+2>SQLITE_MAX_LENGTH ){ goto too_big; } zNew = sqlite3DbMallocRaw(db, nByte+2 ); if( zNew==0 ) goto no_mem; j = 0; pTerm = &pTos[1-nField]; for(i=j=0; i<nField; i++, pTerm++){ int n = pTerm->n; assert( pTerm->flags & (MEM_Str|MEM_Blob) ); memcpy(&zNew[j], pTerm->z, n); |
︙ | ︙ | |||
1285 1286 1287 1288 1289 1290 1291 | assert( pOp[-1].p3type==P3_COLLSEQ ); assert( pOp[-1].opcode==OP_CollSeq ); ctx.pColl = (CollSeq *)pOp[-1].p3; } if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; (*ctx.pFunc->xFunc)(&ctx, n, apVal); if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; | | | 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 | assert( pOp[-1].p3type==P3_COLLSEQ ); assert( pOp[-1].opcode==OP_CollSeq ); ctx.pColl = (CollSeq *)pOp[-1].p3; } if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; (*ctx.pFunc->xFunc)(&ctx, n, apVal); if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; if( db->mallocFailed ){ /* Even though a malloc() has failed, the implementation of the ** user function may have called an sqlite3_result_XXX() function ** to return a value. The following call releases any resources ** associated with such a value. ** ** Note: Maybe MemRelease() should be called if sqlite3SafetyOn() ** fails also (the if(...) statement above). But if people are |
︙ | ︙ | |||
2071 2072 2073 2074 2075 2076 2077 | u8 *zEndHdr; /* Pointer to first byte after the header */ u32 offset; /* Offset into the data */ int szHdrSz; /* Size of the header size field at start of record */ int avail; /* Number of bytes of available data */ aType = pC->aType; if( aType==0 ){ | | | 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 | u8 *zEndHdr; /* Pointer to first byte after the header */ u32 offset; /* Offset into the data */ int szHdrSz; /* Size of the header size field at start of record */ int avail; /* Number of bytes of available data */ aType = pC->aType; if( aType==0 ){ pC->aType = aType = sqlite3DbMallocRaw(db, 2*nField*sizeof(aType) ); } if( aType==0 ){ goto no_mem; } pC->aOffset = aOffset = &aType[nField]; pC->payloadSize = payloadSize; pC->cacheStatus = p->cacheCtr; |
︙ | ︙ | |||
2342 2343 2344 2345 2346 2347 2348 | nByte = nHdr+nData-nZero; if( nByte>SQLITE_MAX_LENGTH ){ goto too_big; } /* Allocate space for the new record. */ if( nByte>sizeof(zTemp) ){ | | | 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 | nByte = nHdr+nData-nZero; if( nByte>SQLITE_MAX_LENGTH ){ goto too_big; } /* Allocate space for the new record. */ if( nByte>sizeof(zTemp) ){ zNewRecord = sqlite3DbMallocRaw(db, nByte); if( !zNewRecord ){ goto no_mem; } }else{ zNewRecord = (u8*)zTemp; } |
︙ | ︙ | |||
3464 3465 3466 3467 3468 3469 3470 | if( pTos->flags & MEM_Null ){ pTos->z = 0; pTos->n = 0; }else{ assert( pTos->flags & (MEM_Blob|MEM_Str) ); } if( pC->pseudoTable ){ | | | | 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 | if( pTos->flags & MEM_Null ){ pTos->z = 0; pTos->n = 0; }else{ assert( pTos->flags & (MEM_Blob|MEM_Str) ); } if( pC->pseudoTable ){ sqlite3_free(pC->pData); pC->iKey = iKey; pC->nData = pTos->n; if( pTos->flags & MEM_Dyn ){ pC->pData = pTos->z; pTos->flags = MEM_Null; }else{ pC->pData = sqlite3_malloc( pC->nData+2 ); if( !pC->pData ) goto no_mem; memcpy(pC->pData, pTos->z, pC->nData); pC->pData[pC->nData] = 0; pC->pData[pC->nData+1] = 0; } pC->nullRow = 0; }else{ |
︙ | ︙ | |||
3640 3641 3642 3643 3644 3645 3646 | goto too_big; } pTos->n = n; if( n<=NBFS ){ pTos->flags = MEM_Blob | MEM_Short; pTos->z = pTos->zShort; }else{ | | | 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 | goto too_big; } pTos->n = n; if( n<=NBFS ){ pTos->flags = MEM_Blob | MEM_Short; pTos->z = pTos->zShort; }else{ char *z = sqlite3_malloc( n ); if( z==0 ) goto no_mem; pTos->flags = MEM_Blob | MEM_Dyn; pTos->xDel = 0; pTos->z = z; } if( pC->isIndex ){ rc = sqlite3BtreeKey(pCrsr, 0, n, pTos->z); |
︙ | ︙ | |||
4209 4210 4211 4212 4213 4214 4215 | zSql = sqlite3MPrintf( "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s", db->aDb[iDb].zName, zMaster, pOp->p3); if( zSql==0 ) goto no_mem; sqlite3SafetyOff(db); assert( db->init.busy==0 ); db->init.busy = 1; | | | < | 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 | zSql = sqlite3MPrintf( "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s", db->aDb[iDb].zName, zMaster, pOp->p3); if( zSql==0 ) goto no_mem; sqlite3SafetyOff(db); assert( db->init.busy==0 ); db->init.busy = 1; assert( !db->mallocFailed ); rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); if( rc==SQLITE_ABORT ) rc = initData.rc; sqlite3_free(zSql); db->init.busy = 0; sqlite3SafetyOn(db); if( rc==SQLITE_NOMEM ){ goto no_mem; } break; } #if !defined(SQLITE_OMIT_ANALYZE) && !defined(SQLITE_OMIT_PARSER) /* Opcode: LoadAnalysis P1 * * |
︙ | ︙ | |||
4307 4308 4309 4310 4311 4312 4313 | char *z; Mem *pnErr; for(nRoot=0; &pTos[-nRoot]>=p->aStack; nRoot++){ if( (pTos[-nRoot].flags & MEM_Int)==0 ) break; } assert( nRoot>0 ); | | | 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 | char *z; Mem *pnErr; for(nRoot=0; &pTos[-nRoot]>=p->aStack; nRoot++){ if( (pTos[-nRoot].flags & MEM_Int)==0 ) break; } assert( nRoot>0 ); aRoot = sqlite3_malloc( sizeof(int)*(nRoot+1) ); if( aRoot==0 ) goto no_mem; j = pOp->p1; assert( j>=0 && j<p->nMem ); pnErr = &p->aMem[j]; assert( (pnErr->flags & MEM_Int)!=0 ); for(j=0; j<nRoot; j++){ aRoot[j] = (pTos-j)->u.i; |
︙ | ︙ | |||
4333 4334 4335 4336 4337 4338 4339 | pTos->z = z; pTos->n = strlen(z); pTos->flags = MEM_Str | MEM_Dyn | MEM_Term; pTos->xDel = 0; } pTos->enc = SQLITE_UTF8; sqlite3VdbeChangeEncoding(pTos, encoding); | | | > > | 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 | pTos->z = z; pTos->n = strlen(z); pTos->flags = MEM_Str | MEM_Dyn | MEM_Term; pTos->xDel = 0; } pTos->enc = SQLITE_UTF8; sqlite3VdbeChangeEncoding(pTos, encoding); sqlite3_free(aRoot); break; } #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ /* Opcode: FifoWrite * * * ** ** Write the integer on the top of the stack ** into the Fifo. */ case OP_FifoWrite: { /* no-push */ assert( pTos>=p->aStack ); sqlite3VdbeMemIntegerify(pTos); if( sqlite3VdbeFifoPush(&p->sFifo, pTos->u.i)==SQLITE_NOMEM ){ goto nomem; } assert( (pTos->flags & MEM_Dyn)==0 ); pTos--; break; } /* Opcode: FifoRead * P2 * ** |
︙ | ︙ | |||
4386 4387 4388 4389 4390 4391 4392 | int i = p->contextStackTop++; Context *pContext; assert( i>=0 ); /* FIX ME: This should be allocated as part of the vdbe at compile-time */ if( i>=p->contextStackDepth ){ p->contextStackDepth = i+1; | | | 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 | int i = p->contextStackTop++; Context *pContext; assert( i>=0 ); /* FIX ME: This should be allocated as part of the vdbe at compile-time */ if( i>=p->contextStackDepth ){ p->contextStackDepth = i+1; p->contextStack = sqlite3ReallocOrFree(db, p->contextStack, sizeof(Context)*(i+1)); if( p->contextStack==0 ) goto no_mem; } pContext = &p->contextStack[i]; pContext->lastRowid = db->lastRowid; pContext->nChange = p->nChange; pContext->sFifo = p->sFifo; |
︙ | ︙ | |||
4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 | ctx.pMem = pMem = &p->aMem[pOp->p1]; pMem->n++; ctx.s.flags = MEM_Null; ctx.s.z = 0; ctx.s.xDel = 0; ctx.isError = 0; ctx.pColl = 0; if( ctx.pFunc->needCollSeq ){ assert( pOp>p->aOp ); assert( pOp[-1].p3type==P3_COLLSEQ ); assert( pOp[-1].opcode==OP_CollSeq ); ctx.pColl = (CollSeq *)pOp[-1].p3; } (ctx.pFunc->xStep)(&ctx, n, apVal); | > | 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 | ctx.pMem = pMem = &p->aMem[pOp->p1]; pMem->n++; ctx.s.flags = MEM_Null; ctx.s.z = 0; ctx.s.xDel = 0; ctx.isError = 0; ctx.pColl = 0; ctx.db = db; if( ctx.pFunc->needCollSeq ){ assert( pOp>p->aOp ); assert( pOp[-1].p3type==P3_COLLSEQ ); assert( pOp[-1].opcode==OP_CollSeq ); ctx.pColl = (CollSeq *)pOp[-1].p3; } (ctx.pFunc->xStep)(&ctx, n, apVal); |
︙ | ︙ | |||
4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 | /* Initialise vdbe cursor object */ pCur = allocateCursor(p, pOp->p1, -1); if( pCur ){ pCur->pVtabCursor = pVtabCursor; pCur->pModule = pVtabCursor->pVtab->pModule; }else{ pModule->xClose(pVtabCursor); } } break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ | > | 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 | /* Initialise vdbe cursor object */ pCur = allocateCursor(p, pOp->p1, -1); if( pCur ){ pCur->pVtabCursor = pVtabCursor; pCur->pModule = pVtabCursor->pVtab->pModule; }else{ db->mallocFailed = 1; pModule->xClose(pVtabCursor); } } break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
︙ | ︙ | |||
5197 5198 5199 5200 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 | sqlite3SetString(&p->zErrMsg, "string or blob too big", (char*)0); rc = SQLITE_TOOBIG; goto vdbe_halt; /* Jump to here if a malloc() fails. */ no_mem: sqlite3SetString(&p->zErrMsg, "out of memory", (char*)0); rc = SQLITE_NOMEM; goto vdbe_halt; /* Jump to here for an SQLITE_MISUSE error. */ abort_due_to_misuse: rc = SQLITE_MISUSE; /* Fall thru into abort_due_to_error */ /* Jump to here for any other kind of fatal error. The "rc" variable ** should hold the error number. */ abort_due_to_error: if( p->zErrMsg==0 ){ | > | | 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226 | sqlite3SetString(&p->zErrMsg, "string or blob too big", (char*)0); rc = SQLITE_TOOBIG; goto vdbe_halt; /* Jump to here if a malloc() fails. */ no_mem: db->mallocFailed = 1; sqlite3SetString(&p->zErrMsg, "out of memory", (char*)0); rc = SQLITE_NOMEM; goto vdbe_halt; /* Jump to here for an SQLITE_MISUSE error. */ abort_due_to_misuse: rc = SQLITE_MISUSE; /* Fall thru into abort_due_to_error */ /* Jump to here for any other kind of fatal error. The "rc" variable ** should hold the error number. */ abort_due_to_error: if( p->zErrMsg==0 ){ if( db->mallocFailed ) rc = SQLITE_NOMEM; sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(rc), (char*)0); } goto vdbe_halt; /* Jump to here if the sqlite3_interrupt() API sets the interrupt ** flag. */ |
︙ | ︙ |
Changes to src/vdbeInt.h.
︙ | ︙ | |||
215 216 217 218 219 220 221 222 223 224 225 226 227 228 | struct sqlite3_context { FuncDef *pFunc; /* Pointer to function information. MUST BE FIRST */ VdbeFunc *pVdbeFunc; /* Auxilary data, if created. */ Mem s; /* The return value is stored here */ Mem *pMem; /* Memory cell used to store aggregate context */ u8 isError; /* Set to true for an error */ CollSeq *pColl; /* Collating sequence */ }; /* ** A Set structure is used for quick testing to see if a value ** is part of a small set. Sets are used to implement code like ** this: ** x.y IN ('hi','hoo','hum') | > | 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 | struct sqlite3_context { FuncDef *pFunc; /* Pointer to function information. MUST BE FIRST */ VdbeFunc *pVdbeFunc; /* Auxilary data, if created. */ Mem s; /* The return value is stored here */ Mem *pMem; /* Memory cell used to store aggregate context */ u8 isError; /* Set to true for an error */ CollSeq *pColl; /* Collating sequence */ sqlite3 *db; /* Database connection */ }; /* ** A Set structure is used for quick testing to see if a value ** is part of a small set. Sets are used to implement code like ** this: ** x.y IN ('hi','hoo','hum') |
︙ | ︙ | |||
357 358 359 360 361 362 363 364 365 366 367 368 369 370 | #define VDBE_MAGIC_RUN 0xbdf20da3 /* VDBE is ready to execute */ #define VDBE_MAGIC_HALT 0x519c2973 /* VDBE has completed execution */ #define VDBE_MAGIC_DEAD 0xb606c3c8 /* The VDBE has been deallocated */ /* ** Function prototypes */ void sqlite3VdbeFreeCursor(Vdbe *, Cursor*); void sqliteVdbePopStack(Vdbe*,int); int sqlite3VdbeCursorMoveto(Cursor*); #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) void sqlite3VdbePrintOp(FILE*, int, Op*); #endif int sqlite3VdbeSerialTypeLen(u32); | > | 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 | #define VDBE_MAGIC_RUN 0xbdf20da3 /* VDBE is ready to execute */ #define VDBE_MAGIC_HALT 0x519c2973 /* VDBE has completed execution */ #define VDBE_MAGIC_DEAD 0xb606c3c8 /* The VDBE has been deallocated */ /* ** Function prototypes */ sqlite3 *sqlite3DbOfVdbe(Vdbe*); void sqlite3VdbeFreeCursor(Vdbe *, Cursor*); void sqliteVdbePopStack(Vdbe*,int); int sqlite3VdbeCursorMoveto(Cursor*); #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) void sqlite3VdbePrintOp(FILE*, int, Op*); #endif int sqlite3VdbeSerialTypeLen(u32); |
︙ | ︙ |
Changes to src/vdbeapi.c.
︙ | ︙ | |||
171 172 173 174 175 176 177 | ** outer sqlite3_step() wrapper procedure. */ static int sqlite3Step(Vdbe *p){ sqlite3 *db; int rc; /* Assert that malloc() has not failed */ | > | < | 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 | ** outer sqlite3_step() wrapper procedure. */ static int sqlite3Step(Vdbe *p){ sqlite3 *db; int rc; /* Assert that malloc() has not failed */ db = p->db; assert( !db->mallocFailed ); if( p==0 || p->magic!=VDBE_MAGIC_RUN ){ return SQLITE_MISUSE; } if( p->aborted ){ return SQLITE_ABORT; } if( p->pc<=0 && p->expired ){ if( p->rc==SQLITE_OK ){ p->rc = SQLITE_SCHEMA; } rc = SQLITE_ERROR; goto end_of_step; } if( sqlite3SafetyOn(db) ){ p->rc = SQLITE_MISUSE; return SQLITE_MISUSE; } if( p->pc<0 ){ /* If there are no other statements currently running, then ** reset the interrupt flag. This prevents a call to sqlite3_interrupt |
︙ | ︙ | |||
354 355 356 357 358 359 360 | pMem->flags = MEM_Agg; pMem->xDel = sqlite3FreeX; pMem->u.pDef = p->pFunc; if( nByte<=NBFS ){ pMem->z = pMem->zShort; memset(pMem->z, 0, nByte); }else{ | | | 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 | pMem->flags = MEM_Agg; pMem->xDel = sqlite3FreeX; pMem->u.pDef = p->pFunc; if( nByte<=NBFS ){ pMem->z = pMem->zShort; memset(pMem->z, 0, nByte); }else{ pMem->z = sqlite3DbMallocZero(p->db, nByte); } } } return (void*)pMem->z; } /* |
︙ | ︙ | |||
391 392 393 394 395 396 397 | struct AuxData *pAuxData; VdbeFunc *pVdbeFunc; if( iArg<0 ) goto failed; pVdbeFunc = pCtx->pVdbeFunc; if( !pVdbeFunc || pVdbeFunc->nAux<=iArg ){ int nMalloc = sizeof(VdbeFunc) + sizeof(struct AuxData)*iArg; | | | > > > | 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 | struct AuxData *pAuxData; VdbeFunc *pVdbeFunc; if( iArg<0 ) goto failed; pVdbeFunc = pCtx->pVdbeFunc; if( !pVdbeFunc || pVdbeFunc->nAux<=iArg ){ int nMalloc = sizeof(VdbeFunc) + sizeof(struct AuxData)*iArg; pVdbeFunc = sqlite3_realloc(pVdbeFunc, nMalloc); if( !pVdbeFunc ){ pCtx->db->mallocFailed = 1; goto failed; } pCtx->pVdbeFunc = pVdbeFunc; memset(&pVdbeFunc->apAux[pVdbeFunc->nAux], 0, sizeof(struct AuxData)*(iArg+1-pVdbeFunc->nAux)); pVdbeFunc->nAux = iArg+1; pVdbeFunc->pFunc = pCtx->pFunc; } |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
25 26 27 28 29 30 31 32 33 34 35 36 37 | ** set the sqlite3_vdbe_addop_trace to 1 and all opcodes will be printed ** as they are added to the instruction stream. */ #ifdef SQLITE_DEBUG int sqlite3_vdbe_addop_trace = 0; #endif /* ** Create a new virtual database engine. */ Vdbe *sqlite3VdbeCreate(sqlite3 *db){ Vdbe *p; | > > > > > > > | | | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | ** set the sqlite3_vdbe_addop_trace to 1 and all opcodes will be printed ** as they are added to the instruction stream. */ #ifdef SQLITE_DEBUG int sqlite3_vdbe_addop_trace = 0; #endif /* ** Return the database connection associated with a VDBE */ sqlite3 *sqlite3DbOfVdbe(Vdbe *p){ return p->db; } /* ** Create a new virtual database engine. */ Vdbe *sqlite3VdbeCreate(sqlite3 *db){ Vdbe *p; p = sqlite3DbMallocZero(db, sizeof(Vdbe) ); if( p==0 ) return 0; p->db = db; if( db->pVdbe ){ db->pVdbe->pPrev = p; } p->pNext = db->pVdbe; p->pPrev = 0; db->pVdbe = p; p->magic = VDBE_MAGIC_INIT; return p; } /* ** Remember the SQL string for a prepared statement. */ void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n){ if( p==0 ) return; assert( p->zSql==0 ); p->zSql = sqlite3DbStrNDup(p->db, z, n); } /* ** Return the SQL associated with a prepared statement */ const char *sqlite3VdbeGetSql(Vdbe *p){ return p->zSql; |
︙ | ︙ | |||
111 112 113 114 115 116 117 | */ static void resizeOpArray(Vdbe *p, int N){ int runMode = p->magic==VDBE_MAGIC_RUN; if( runMode || p->nOpAlloc<N ){ VdbeOp *pNew; int nNew = N + 100*(!runMode); int oldSize = p->nOpAlloc; | | > > | 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | */ static void resizeOpArray(Vdbe *p, int N){ int runMode = p->magic==VDBE_MAGIC_RUN; if( runMode || p->nOpAlloc<N ){ VdbeOp *pNew; int nNew = N + 100*(!runMode); int oldSize = p->nOpAlloc; pNew = sqlite_realloc(p->aOp, nNew*sizeof(Op)); if( pNew ){ p->nOpAlloc = nNew; p->aOp = pNew; if( nNew>oldSize ){ memset(&p->aOp[oldSize], 0, (nNew-oldSize)*sizeof(Op)); } }else{ p->db->mallocFailed = 1; } } } /* ** Add a new instruction to the list of instructions current in the ** VDBE. Return the address of the new instruction. |
︙ | ︙ | |||
146 147 148 149 150 151 152 | int i; VdbeOp *pOp; i = p->nOp; assert( p->magic==VDBE_MAGIC_INIT ); if( p->nOpAlloc<=i ){ resizeOpArray(p, i+1); | | | 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | int i; VdbeOp *pOp; i = p->nOp; assert( p->magic==VDBE_MAGIC_INIT ); if( p->nOpAlloc<=i ){ resizeOpArray(p, i+1); if( p->db->mallocFailed ){ return 0; } } p->nOp++; pOp = &p->aOp[i]; pOp->opcode = op; pOp->p1 = p1; |
︙ | ︙ | |||
193 194 195 196 197 198 199 | */ int sqlite3VdbeMakeLabel(Vdbe *p){ int i; i = p->nLabel++; assert( p->magic==VDBE_MAGIC_INIT ); if( i>=p->nLabelAlloc ){ p->nLabelAlloc = p->nLabelAlloc*2 + 10; | | | 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 | */ int sqlite3VdbeMakeLabel(Vdbe *p){ int i; i = p->nLabel++; assert( p->magic==VDBE_MAGIC_INIT ); if( i>=p->nLabelAlloc ){ p->nLabelAlloc = p->nLabelAlloc*2 + 10; p->aLabel = sqlite3ReallocOrFree(p->db, p->aLabel, p->nLabelAlloc*sizeof(p->aLabel[0])); } if( p->aLabel ){ p->aLabel[i] = -1; } return -1-i; } |
︙ | ︙ | |||
321 322 323 324 325 326 327 | nMaxStack--; } if( pOp->p2>=0 ) continue; assert( -1-pOp->p2<p->nLabel ); pOp->p2 = aLabel[-1-pOp->p2]; } | | | 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 | nMaxStack--; } if( pOp->p2>=0 ) continue; assert( -1-pOp->p2<p->nLabel ); pOp->p2 = aLabel[-1-pOp->p2]; } sqlite3_free(p->aLabel); p->aLabel = 0; *pMaxFuncArgs = nMaxArgs; *pMaxStack = nMaxStack; /* If we never rollback a statement transaction, then statement ** transactions are not needed. So change every OP_Statement |
︙ | ︙ | |||
357 358 359 360 361 362 363 | ** Add a whole list of operations to the operation stack. Return the ** address of the first operation added. */ int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp){ int addr; assert( p->magic==VDBE_MAGIC_INIT ); resizeOpArray(p, p->nOp + nOp); | | | 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 | ** Add a whole list of operations to the operation stack. Return the ** address of the first operation added. */ int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp){ int addr; assert( p->magic==VDBE_MAGIC_INIT ); resizeOpArray(p, p->nOp + nOp); if( p->db->mallocFailed ){ return 0; } addr = p->nOp; if( nOp>0 ){ int i; VdbeOpList const *pIn = aOp; for(i=0; i<nOp; i++, pIn++){ |
︙ | ︙ | |||
423 424 425 426 427 428 429 | /* ** If the input FuncDef structure is ephemeral, then free it. If ** the FuncDef is not ephermal, then do nothing. */ static void freeEphemeralFunction(FuncDef *pDef){ if( pDef && (pDef->flags & SQLITE_FUNC_EPHEM)!=0 ){ | | | | | 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 | /* ** If the input FuncDef structure is ephemeral, then free it. If ** the FuncDef is not ephermal, then do nothing. */ static void freeEphemeralFunction(FuncDef *pDef){ if( pDef && (pDef->flags & SQLITE_FUNC_EPHEM)!=0 ){ sqlite3_free(pDef); } } /* ** Delete a P3 value if necessary. */ static void freeP3(int p3type, void *p3){ if( p3 ){ switch( p3type ){ case P3_DYNAMIC: case P3_KEYINFO: case P3_KEYINFO_HANDOFF: { sqlite3_free(p3); break; } case P3_MPRINTF: { sqlite3_free(p3); break; } case P3_VDBEFUNC: { VdbeFunc *pVdbeFunc = (VdbeFunc *)p3; freeEphemeralFunction(pVdbeFunc->pFunc); sqlite3VdbeDeleteAuxData(pVdbeFunc, 0); sqlite3_free(pVdbeFunc); break; } case P3_FUNCDEF: { freeEphemeralFunction((FuncDef*)p3); break; } case P3_MEM: { |
︙ | ︙ | |||
485 486 487 488 489 490 491 | /* ** Change the value of the P3 operand for a specific instruction. ** This routine is useful when a large program is loaded from a ** static array using sqlite3VdbeAddOpList but we want to make a ** few minor changes to the program. ** ** If n>=0 then the P3 operand is dynamic, meaning that a copy of | | | | | | 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 | /* ** Change the value of the P3 operand for a specific instruction. ** This routine is useful when a large program is loaded from a ** static array using sqlite3VdbeAddOpList but we want to make a ** few minor changes to the program. ** ** If n>=0 then the P3 operand is dynamic, meaning that a copy of ** the string is made into memory obtained from sqlite3_malloc(). ** A value of n==0 means copy bytes of zP3 up to and including the ** first null byte. If n>0 then copy n+1 bytes of zP3. ** ** If n==P3_KEYINFO it means that zP3 is a pointer to a KeyInfo structure. ** A copy is made of the KeyInfo structure into memory obtained from ** sqlite3_malloc, to be freed when the Vdbe is finalized. ** n==P3_KEYINFO_HANDOFF indicates that zP3 points to a KeyInfo structure ** stored in memory that the caller has obtained from sqlite3_malloc. The ** caller should not free the allocation, it will be freed when the Vdbe is ** finalized. ** ** Other values of n (P3_STATIC, P3_COLLSEQ etc.) indicate that zP3 points ** to a string or structure that is guaranteed to exist for the lifetime of ** the Vdbe. In these cases we can just copy the pointer. ** ** If addr<0 then change P3 on the most recently inserted instruction. */ void sqlite3VdbeChangeP3(Vdbe *p, int addr, const char *zP3, int n){ Op *pOp; assert( p==0 || p->magic==VDBE_MAGIC_INIT ); if( p==0 || p->aOp==0 || p->db->mallocFailed ){ if (n != P3_KEYINFO) { freeP3(n, (void*)*(char**)&zP3); } return; } if( addr<0 || addr>=p->nOp ){ addr = p->nOp - 1; |
︙ | ︙ | |||
528 529 530 531 532 533 534 | pOp->p3type = P3_NOTUSED; }else if( n==P3_KEYINFO ){ KeyInfo *pKeyInfo; int nField, nByte; nField = ((KeyInfo*)zP3)->nField; nByte = sizeof(*pKeyInfo) + (nField-1)*sizeof(pKeyInfo->aColl[0]) + nField; | | > | | | | 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 | pOp->p3type = P3_NOTUSED; }else if( n==P3_KEYINFO ){ KeyInfo *pKeyInfo; int nField, nByte; nField = ((KeyInfo*)zP3)->nField; nByte = sizeof(*pKeyInfo) + (nField-1)*sizeof(pKeyInfo->aColl[0]) + nField; pKeyInfo = sqlite3_malloc( nByte ); pOp->p3 = (char*)pKeyInfo; if( pKeyInfo ){ unsigned char *aSortOrder; memcpy(pKeyInfo, zP3, nByte); aSortOrder = pKeyInfo->aSortOrder; if( aSortOrder ){ pKeyInfo->aSortOrder = (unsigned char*)&pKeyInfo->aColl[nField]; memcpy(pKeyInfo->aSortOrder, aSortOrder, nField); } pOp->p3type = P3_KEYINFO; }else{ p->db->mallocFailed = 1; pOp->p3type = P3_NOTUSED; } }else if( n==P3_KEYINFO_HANDOFF ){ pOp->p3 = (char*)zP3; pOp->p3type = P3_KEYINFO; }else if( n<0 ){ pOp->p3 = (char*)zP3; pOp->p3type = n; }else{ if( n==0 ) n = strlen(zP3); pOp->p3 = sqlite3DbStrNDup(p->db, zP3, n); pOp->p3type = P3_DYNAMIC; } } #ifndef NDEBUG /* ** Replace the P3 field of the most recently coded instruction with ** comment text. */ void sqlite3VdbeComment(Vdbe *p, const char *zFormat, ...){ va_list ap; assert( p->nOp>0 || p->aOp==0 ); assert( p->aOp==0 || p->aOp[p->nOp-1].p3==0 || p->db->mallocFailed ); va_start(ap, zFormat); sqlite3VdbeChangeP3(p, -1, sqlite3VMPrintf(zFormat, ap), P3_DYNAMIC); va_end(ap); } #endif /* ** Return the opcode for a given address. */ VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){ assert( p->magic==VDBE_MAGIC_INIT ); assert( (addr>=0 && addr<p->nOp) || p->db->mallocFailed ); return ((addr>=0 && addr<p->nOp)?(&p->aOp[addr]):0); } #if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \ || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG) /* ** Compute a string that describes the P3 parameter for an opcode. |
︙ | ︙ | |||
860 861 862 863 864 865 866 | resolveP2Values(p, &nArg, &nStack); resizeOpArray(p, p->nOp); assert( nVar>=0 ); assert( nStack<p->nOp ); if( isExplain ){ nStack = 10; } | | | | 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 | resolveP2Values(p, &nArg, &nStack); resizeOpArray(p, p->nOp); assert( nVar>=0 ); assert( nStack<p->nOp ); if( isExplain ){ nStack = 10; } p->aStack = sqlite3DbMallocZer(db, nStack*sizeof(p->aStack[0]) /* aStack */ + nArg*sizeof(Mem*) /* apArg */ + nVar*sizeof(Mem) /* aVar */ + nVar*sizeof(char*) /* azVar */ + nMem*sizeof(Mem) /* aMem */ + nCursor*sizeof(Cursor*) /* apCsr */ ); if( !db->mallocFailed ){ p->aMem = &p->aStack[nStack]; p->nMem = nMem; p->aVar = &p->aMem[nMem]; p->nVar = nVar; p->okVar = 0; p->apArg = (Mem**)&p->aVar[nVar]; p->azVar = (char**)&p->apArg[nArg]; |
︙ | ︙ | |||
936 937 938 939 940 941 942 | p->inVtabMethod = 1; sqlite3SafetyOff(p->db); pModule->xClose(pVtabCursor); sqlite3SafetyOn(p->db); p->inVtabMethod = 0; } #endif | | | | | 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 | p->inVtabMethod = 1; sqlite3SafetyOff(p->db); pModule->xClose(pVtabCursor); sqlite3SafetyOn(p->db); p->inVtabMethod = 0; } #endif sqlite3_free(pCx->pData); sqlite3_free(pCx->aType); sqlite3_free(pCx); } /* ** Close all cursors */ static void closeAllCursors(Vdbe *p){ int i; |
︙ | ︙ | |||
975 976 977 978 979 980 981 | closeAllCursors(p); releaseMemArray(p->aMem, p->nMem); sqlite3VdbeFifoClear(&p->sFifo); if( p->contextStack ){ for(i=0; i<p->contextStackTop; i++){ sqlite3VdbeFifoClear(&p->contextStack[i].sFifo); } | | | | | | | | 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 | closeAllCursors(p); releaseMemArray(p->aMem, p->nMem); sqlite3VdbeFifoClear(&p->sFifo); if( p->contextStack ){ for(i=0; i<p->contextStackTop; i++){ sqlite3VdbeFifoClear(&p->contextStack[i].sFifo); } sqlite3_free(p->contextStack); } p->contextStack = 0; p->contextStackDepth = 0; p->contextStackTop = 0; sqlite3_free(p->zErrMsg); p->zErrMsg = 0; p->resOnStack = 0; } /* ** Set the number of result columns that will be returned by this SQL ** statement. This is now set at compile time, rather than during ** execution of the vdbe program so that sqlite3_column_count() can ** be called on an SQL statement before sqlite3_step(). */ void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){ Mem *pColName; int n; releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); sqlite3_free(p->aColName); n = nResColumn*COLNAME_N; p->nResColumn = nResColumn; p->aColName = pColName = (Mem*)sqlite3DbMallocZero(db, sizeof(Mem)*n ); if( p->aColName==0 ) return; while( n-- > 0 ){ (pColName++)->flags = MEM_Null; } } /* ** Set the name of the idx'th column to be returned by the SQL statement. ** zName must be a pointer to a nul terminated string. ** ** This call must be made after a call to sqlite3VdbeSetNumCols(). ** ** If N==P3_STATIC it means that zName is a pointer to a constant static ** string and we can just copy the pointer. If it is P3_DYNAMIC, then ** the string is freed using sqlite3_free() when the vdbe is finished with ** it. Otherwise, N bytes of zName are copied. */ int sqlite3VdbeSetColName(Vdbe *p, int idx, int var, const char *zName, int N){ int rc; Mem *pColName; assert( idx<p->nResColumn ); assert( var<COLNAME_N ); if( p->db->mallocFailed ) return SQLITE_NOMEM; assert( p->aColName!=0 ); pColName = &(p->aColName[idx+var*p->nResColumn]); if( N==P3_DYNAMIC || N==P3_STATIC ){ rc = sqlite3VdbeMemSetStr(pColName, zName, -1, SQLITE_UTF8, SQLITE_STATIC); }else{ rc = sqlite3VdbeMemSetStr(pColName, zName, N, SQLITE_UTF8,SQLITE_TRANSIENT); } |
︙ | ︙ | |||
1131 1132 1133 1134 1135 1136 1137 | char const *zMainFile = sqlite3BtreeGetFilename(db->aDb[0].pBt); sqlite3_file *master = 0; i64 offset = 0; /* Select a master journal file name */ do { u32 random; | | | | 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 | char const *zMainFile = sqlite3BtreeGetFilename(db->aDb[0].pBt); sqlite3_file *master = 0; i64 offset = 0; /* Select a master journal file name */ do { u32 random; sqlite3_free(zMaster); sqlite3Randomness(sizeof(random), &random); zMaster = sqlite3MPrintf("%s-mj%08X", zMainFile, random&0x7fffffff); if( !zMaster ){ return SQLITE_NOMEM; } }while( sqlite3OsFileExists(zMaster) ); /* Open the master journal. */ rc = sqlite3OsOpenExclusive(zMaster, &master, 0); if( rc!=SQLITE_OK ){ sqlite3_free(zMaster); return rc; } /* Write the name of each database file in the transaction into the new ** master journal file. If an error occurs at this point close ** and delete the master journal file. All the individual journal files ** still have 'null' as the master journal pointer, so they will roll |
︙ | ︙ | |||
1166 1167 1168 1169 1170 1171 1172 | needSync = 1; } rc = sqlite3OsWrite(master, zFile, strlen(zFile)+1, offset); offset += strlen(zFile)+1; if( rc!=SQLITE_OK ){ sqlite3OsClose(&master); sqlite3OsDelete(zMaster); | | | | 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 | needSync = 1; } rc = sqlite3OsWrite(master, zFile, strlen(zFile)+1, offset); offset += strlen(zFile)+1; if( rc!=SQLITE_OK ){ sqlite3OsClose(&master); sqlite3OsDelete(zMaster); sqlite3_free(zMaster); return rc; } } } /* Sync the master journal file. Before doing this, open the directory ** the master journal file is store in so that it gets synced too. */ zMainFile = sqlite3BtreeGetDirname(db->aDb[0].pBt); #if 0 rc = sqlite3OsOpenDirectory(master, zMainFile); if( rc!=SQLITE_OK || (needSync && (rc=sqlite3OsSync(master,0))!=SQLITE_OK) ){ sqlite3OsClose(&master); sqlite3OsDelete(zMaster); sqlite3_free(zMaster); return rc; } #endif /* Sync all the db files involved in the transaction. The same call ** sets the master journal pointer in each individual journal. If ** an error occurs here, do not delete the master journal file. |
︙ | ︙ | |||
1206 1207 1208 1209 1210 1211 1212 | Btree *pBt = db->aDb[i].pBt; if( pBt && sqlite3BtreeIsInTrans(pBt) ){ rc = sqlite3BtreeCommitPhaseOne(pBt, zMaster); } } sqlite3OsClose(&master); if( rc!=SQLITE_OK ){ | | | | 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 | Btree *pBt = db->aDb[i].pBt; if( pBt && sqlite3BtreeIsInTrans(pBt) ){ rc = sqlite3BtreeCommitPhaseOne(pBt, zMaster); } } sqlite3OsClose(&master); if( rc!=SQLITE_OK ){ sqlite3_free(zMaster); return rc; } /* Delete the master journal file. This commits the transaction. After ** doing this the directory is synced again before any individual ** transaction files are deleted. */ rc = sqlite3OsDelete(zMaster); sqlite3_free(zMaster); zMaster = 0; if( rc ){ return rc; } rc = sqlite3OsSyncDirectory(zMainFile); if( rc!=SQLITE_OK ){ /* This is not good. The master journal file has been deleted, but |
︙ | ︙ | |||
1346 1347 1348 1349 1350 1351 1352 | ** ** Other errors: ** ** No error: ** */ | | | 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 | ** ** Other errors: ** ** No error: ** */ if( p->db->mallocFailed ){ p->rc = SQLITE_NOMEM; } if( p->magic!=VDBE_MAGIC_RUN ){ /* Already halted. Nothing to do. */ assert( p->magic==VDBE_MAGIC_HALT ); #ifndef SQLITE_OMIT_VIRTUALTABLE closeAllCursors(p); |
︙ | ︙ | |||
1659 1660 1661 1662 1663 1664 1665 | p->pNext->pPrev = p->pPrev; } if( p->aOp ){ for(i=0; i<p->nOp; i++){ Op *pOp = &p->aOp[i]; freeP3(pOp->p3type, pOp->p3); } | | | | | | | | 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 | p->pNext->pPrev = p->pPrev; } if( p->aOp ){ for(i=0; i<p->nOp; i++){ Op *pOp = &p->aOp[i]; freeP3(pOp->p3type, pOp->p3); } sqlite3_free(p->aOp); } releaseMemArray(p->aVar, p->nVar); sqlite3_free(p->aLabel); sqlite3_free(p->aStack); releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); sqlite3_free(p->aColName); sqlite3_free(p->zSql); p->magic = VDBE_MAGIC_DEAD; sqlite3_free(p); } /* ** If a MoveTo operation is pending on the given cursor, then do that ** MoveTo now. Return an error code. If no MoveTo is pending, this ** routine does nothing and returns SQLITE_OK. */ |
︙ | ︙ |
Changes to src/vdbeblob.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 code used to implement incremental BLOB I/O. ** | | | 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 code used to implement incremental BLOB I/O. ** ** $Id: vdbeblob.c,v 1.12 2007/08/16 04:30:41 drh Exp $ */ #include "sqliteInt.h" #include "vdbeInt.h" #ifndef SQLITE_OMIT_INCRBLOB |
︙ | ︙ | |||
100 101 102 103 104 105 106 | } pTab = sqlite3LocateTable(&sParse, zTable, zDb); if( !pTab ){ if( sParse.zErrMsg ){ sqlite3_snprintf(sizeof(zErr), zErr, "%s", sParse.zErrMsg); } | | | 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | } pTab = sqlite3LocateTable(&sParse, zTable, zDb); if( !pTab ){ if( sParse.zErrMsg ){ sqlite3_snprintf(sizeof(zErr), zErr, "%s", sParse.zErrMsg); } sqlite3_free(sParse.zErrMsg); rc = SQLITE_ERROR; sqlite3SafetyOff(db); goto blob_open_out; } /* Now search pTab for the exact column. */ for(iCol=0; iCol < pTab->nCol; iCol++) { |
︙ | ︙ | |||
169 170 171 172 173 174 175 | ** think that the table has one more column than it really ** does. An OP_Column to retrieve this imaginary column will ** always return an SQL NULL. This is useful because it means ** we can invoke OP_Column to fill in the vdbe cursors type ** and offset cache without causing any IO. */ sqlite3VdbeChangeP2(v, 5, pTab->nCol+1); | | | | 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 | ** think that the table has one more column than it really ** does. An OP_Column to retrieve this imaginary column will ** always return an SQL NULL. This is useful because it means ** we can invoke OP_Column to fill in the vdbe cursors type ** and offset cache without causing any IO. */ sqlite3VdbeChangeP2(v, 5, pTab->nCol+1); if( !db->mallocFailed ){ sqlite3VdbeMakeReady(v, 1, 0, 1, 0); } } rc = sqlite3SafetyOff(db); if( rc!=SQLITE_OK || db->mallocFailed ){ goto blob_open_out; } sqlite3_bind_int64((sqlite3_stmt *)v, 1, iRow); rc = sqlite3_step((sqlite3_stmt *)v); if( rc!=SQLITE_ROW ){ nAttempt++; |
︙ | ︙ | |||
204 205 206 207 208 209 210 | if( type<12 ){ sqlite3_snprintf(sizeof(zErr), zErr, "cannot open value of type %s", type==0?"null": type==7?"real": "integer" ); rc = SQLITE_ERROR; goto blob_open_out; } | | | | | | | 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 | if( type<12 ){ sqlite3_snprintf(sizeof(zErr), zErr, "cannot open value of type %s", type==0?"null": type==7?"real": "integer" ); rc = SQLITE_ERROR; goto blob_open_out; } pBlob = (Incrblob *)sqlite3DbMallocZero(db, sizeof(Incrblob)); if( db->mallocFailed ){ sqlite3_free(pBlob); goto blob_open_out; } pBlob->flags = flags; pBlob->pCsr = v->apCsr[0]->pCursor; sqlite3BtreeCacheOverflow(pBlob->pCsr); pBlob->pStmt = (sqlite3_stmt *)v; pBlob->iOffset = v->apCsr[0]->aOffset[iCol]; pBlob->nByte = sqlite3VdbeSerialTypeLen(type); *ppBlob = (sqlite3_blob *)pBlob; rc = SQLITE_OK; }else if( rc==SQLITE_OK ){ sqlite3_snprintf(sizeof(zErr), zErr, "no such rowid: %lld", iRow); rc = SQLITE_ERROR; } blob_open_out: zErr[sizeof(zErr)-1] = '\0'; if( rc!=SQLITE_OK || db->mallocFailed ){ sqlite3_finalize((sqlite3_stmt *)v); } sqlite3Error(db, rc, (rc==SQLITE_OK?0:zErr)); return sqlite3ApiExit(db, rc); } /* ** Close a blob handle that was previously created using ** sqlite3_blob_open(). */ int sqlite3_blob_close(sqlite3_blob *pBlob){ Incrblob *p = (Incrblob *)pBlob; sqlite3_stmt *pStmt = p->pStmt; sqlite3_free(p); return sqlite3_finalize(pStmt); } static int blobReadWrite( sqlite3_blob *pBlob, void *z, |
︙ | ︙ |
Changes to src/vdbefifo.c.
︙ | ︙ | |||
20 21 22 23 24 25 26 | ** we run out of memory. Leave space on the page for nEntry entries. */ static FifoPage *allocateFifoPage(int nEntry){ FifoPage *pPage; if( nEntry>32767 ){ nEntry = 32767; } | | | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | ** we run out of memory. Leave space on the page for nEntry entries. */ static FifoPage *allocateFifoPage(int nEntry){ FifoPage *pPage; if( nEntry>32767 ){ nEntry = 32767; } pPage = sqlite3_malloc( sizeof(FifoPage) + sizeof(i64)*(nEntry-1) ); if( pPage ){ pPage->nSlot = nEntry; pPage->iWrite = 0; pPage->iRead = 0; pPage->pNext = 0; } return pPage; |
︙ | ︙ | |||
83 84 85 86 87 88 89 | assert( pPage->iWrite<=pPage->nSlot ); assert( pPage->iRead<pPage->nSlot ); assert( pPage->iRead>=0 ); *pVal = pPage->aSlot[pPage->iRead++]; pFifo->nEntry--; if( pPage->iRead>=pPage->iWrite ){ pFifo->pFirst = pPage->pNext; | | | | 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | assert( pPage->iWrite<=pPage->nSlot ); assert( pPage->iRead<pPage->nSlot ); assert( pPage->iRead>=0 ); *pVal = pPage->aSlot[pPage->iRead++]; pFifo->nEntry--; if( pPage->iRead>=pPage->iWrite ){ pFifo->pFirst = pPage->pNext; sqlite3_free(pPage); if( pFifo->nEntry==0 ){ assert( pFifo->pLast==pPage ); pFifo->pLast = 0; }else{ assert( pFifo->pFirst!=0 ); } }else{ assert( pFifo->nEntry>0 ); } return SQLITE_OK; } /* ** Delete all information from a Fifo object. Free all memory held ** by the Fifo. */ void sqlite3VdbeFifoClear(Fifo *pFifo){ FifoPage *pPage, *pNextPage; for(pPage=pFifo->pFirst; pPage; pPage=pNextPage){ pNextPage = pPage->pNext; sqlite3_free(pPage); } sqlite3VdbeFifoInit(pFifo); } |
Changes to src/vdbemem.c.
︙ | ︙ | |||
21 22 23 24 25 26 27 | #include <ctype.h> #include "vdbeInt.h" /* ** Call sqlite3VdbeMemExpandBlob() on the supplied value (type Mem*) ** P if required. */ | | | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #include <ctype.h> #include "vdbeInt.h" /* ** Call sqlite3VdbeMemExpandBlob() on the supplied value (type Mem*) ** P if required. */ #define expandBlob(D,P) (((P)->flags&MEM_Zero)?sqlite3VdbeMemExpandBlob(D,P):0) /* ** If pMem is an object with a valid string representation, this routine ** ensures the internal encoding for the string representation is ** 'desiredEnc', one of SQLITE_UTF8, SQLITE_UTF16LE or SQLITE_UTF16BE. ** ** If pMem is not a string object, or the encoding of the string |
︙ | ︙ | |||
62 63 64 65 66 67 68 | } /* ** Make the given Mem object MEM_Dyn. ** ** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails. */ | | | | | | | > | 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | } /* ** Make the given Mem object MEM_Dyn. ** ** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails. */ int sqlite3VdbeMemDynamicify(sqlite3 *db, Mem *pMem){ int n; u8 *z; expandBlob(db, pMem); if( (pMem->flags & (MEM_Ephem|MEM_Static|MEM_Short))==0 ){ return SQLITE_OK; } assert( (pMem->flags & MEM_Dyn)==0 ); n = pMem->n; assert( pMem->flags & (MEM_Str|MEM_Blob) ); z = sqlite3_malloc( n+2 ); if( z==0 ){ return SQLITE_NOMEM; } pMem->flags |= MEM_Dyn|MEM_Term; pMem->xDel = 0; memcpy(z, pMem->z, n ); z[n] = 0; z[n+1] = 0; pMem->z = (char*)z; pMem->flags &= ~(MEM_Ephem|MEM_Static|MEM_Short); return SQLITE_OK; } /* ** If the given Mem* has a zero-filled tail, turn it into an ordinary ** blob stored in dynamically allocated space. */ #ifndef SQLITE_OMIT_INCRBLOB int sqlite3VdbeMemExpandBlob(sqlite3 *db, Mem *pMem){ if( pMem->flags & MEM_Zero ){ char *pNew; int nByte; assert( (pMem->flags & MEM_Blob)!=0 ); nByte = pMem->n + pMem->u.i; if( nByte<=0 ) nByte = 1; pNew = sqlite3_malloc(nByte); if( pNew==0 ){ if( db ) db->mallocFailed = 1; return SQLITE_NOMEM; } memcpy(pNew, pMem->z, pMem->n); memset(&pNew[pMem->n], 0, pMem->u.i); sqlite3VdbeMemRelease(pMem); pMem->z = pNew; pMem->n += pMem->u.i; |
︙ | ︙ | |||
122 123 124 125 126 127 128 | /* ** Make the given Mem object either MEM_Short or MEM_Dyn so that bytes ** of the Mem.z[] array can be modified. ** ** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails. */ | | | | > | | | | > | > | | 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | /* ** Make the given Mem object either MEM_Short or MEM_Dyn so that bytes ** of the Mem.z[] array can be modified. ** ** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails. */ int sqlite3VdbeMemMakeWriteable(sqlite3 *db, Mem *pMem){ int n; u8 *z; expandBlob(db, pMem); if( (pMem->flags & (MEM_Ephem|MEM_Static))==0 ){ return SQLITE_OK; } assert( (pMem->flags & MEM_Dyn)==0 ); assert( pMem->flags & (MEM_Str|MEM_Blob) ); if( (n = pMem->n)+2<sizeof(pMem->zShort) ){ z = (u8*)pMem->zShort; pMem->flags |= MEM_Short|MEM_Term; }else{ z = sqlite3_malloc( n+2 ); if( z==0 ){ db->mallocFailed = 1; return SQLITE_NOMEM; } pMem->flags |= MEM_Dyn|MEM_Term; pMem->xDel = 0; } memcpy(z, pMem->z, n ); z[n] = 0; z[n+1] = 0; pMem->z = (char*)z; pMem->flags &= ~(MEM_Ephem|MEM_Static); assert(0==(1&(int)pMem->z)); return SQLITE_OK; } /* ** Make sure the given Mem is \u0000 terminated. */ int sqlite3VdbeMemNulTerminate(sqlite3 *db, Mem *pMem){ if( (pMem->flags & MEM_Term)!=0 || (pMem->flags & MEM_Str)==0 ){ return SQLITE_OK; /* Nothing to do */ } if( pMem->flags & (MEM_Static|MEM_Ephem) ){ return sqlite3VdbeMemMakeWriteable(pMem); }else{ char *z; sqlite3VdbeMemExpandBlob(db, pMem); z = sqlite3_malloc(pMem->n+2); if( !z ){ db->mallocFailed = 1; return SQLITE_NOMEM; } memcpy(z, pMem->z, pMem->n); z[pMem->n] = 0; z[pMem->n+1] = 0; if( pMem->xDel ){ pMem->xDel(pMem->z); }else{ sqlite3_free(pMem->z); } pMem->xDel = 0; pMem->z = z; pMem->flags |= MEM_Term; } return SQLITE_OK; } |
︙ | ︙ | |||
243 244 245 246 247 248 249 | ctx.s.flags = MEM_Null; ctx.s.z = pMem->zShort; ctx.pMem = pMem; ctx.pFunc = pFunc; ctx.isError = 0; pFunc->xFinalize(&ctx); if( pMem->z && pMem->z!=pMem->zShort ){ | | | 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 | ctx.s.flags = MEM_Null; ctx.s.z = pMem->zShort; ctx.pMem = pMem; ctx.pFunc = pFunc; ctx.isError = 0; pFunc->xFinalize(&ctx); if( pMem->z && pMem->z!=pMem->zShort ){ sqlite3_free( pMem->z ); } *pMem = ctx.s; if( pMem->flags & MEM_Short ){ pMem->z = pMem->zShort; } if( ctx.isError ){ rc = SQLITE_ERROR; |
︙ | ︙ | |||
272 273 274 275 276 277 278 | sqlite3VdbeMemFinalize(p, p->u.pDef); assert( (p->flags & MEM_Agg)==0 ); sqlite3VdbeMemRelease(p); }else{ p->xDel((void *)p->z); } }else{ | | | 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 | sqlite3VdbeMemFinalize(p, p->u.pDef); assert( (p->flags & MEM_Agg)==0 ); sqlite3VdbeMemRelease(p); }else{ p->xDel((void *)p->z); } }else{ sqlite3_free(p->z); } p->z = 0; p->xDel = 0; } } /* |
︙ | ︙ | |||
719 720 721 722 723 724 725 726 727 728 729 730 731 732 | ** The pMem structure is assumed to be uninitialized. Any prior content ** is overwritten without being freed. ** ** If this routine fails for any reason (malloc returns NULL or unable ** to read from the disk) then the pMem is left in an inconsistent state. */ int sqlite3VdbeMemFromBtree( BtCursor *pCur, /* Cursor pointing at record to retrieve. */ int offset, /* Offset from the start of data to return bytes from. */ int amt, /* Number of bytes to return. */ int key, /* If true, retrieve from the btree key, not data. */ Mem *pMem /* OUT: Return data in this Mem structure. */ ){ char *zData; /* Data from the btree layer */ | > | 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 | ** The pMem structure is assumed to be uninitialized. Any prior content ** is overwritten without being freed. ** ** If this routine fails for any reason (malloc returns NULL or unable ** to read from the disk) then the pMem is left in an inconsistent state. */ int sqlite3VdbeMemFromBtree( sqlite3 *db, /* Database connect to report malloc errors to */ BtCursor *pCur, /* Cursor pointing at record to retrieve. */ int offset, /* Offset from the start of data to return bytes from. */ int amt, /* Number of bytes to return. */ int key, /* If true, retrieve from the btree key, not data. */ Mem *pMem /* OUT: Return data in this Mem structure. */ ){ char *zData; /* Data from the btree layer */ |
︙ | ︙ | |||
742 743 744 745 746 747 748 | pMem->n = amt; if( offset+amt<=available ){ pMem->z = &zData[offset]; pMem->flags = MEM_Blob|MEM_Ephem; }else{ int rc; if( amt>NBFS-2 ){ | | > | 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 | pMem->n = amt; if( offset+amt<=available ){ pMem->z = &zData[offset]; pMem->flags = MEM_Blob|MEM_Ephem; }else{ int rc; if( amt>NBFS-2 ){ zData = (char *)sqlite3_malloc(amt+2); if( !zData ){ db->mallocFailed = 1; return SQLITE_NOMEM; } pMem->flags = MEM_Blob|MEM_Dyn|MEM_Term; pMem->xDel = 0; }else{ zData = &(pMem->zShort[0]); pMem->flags = MEM_Blob|MEM_Short|MEM_Term; |
︙ | ︙ | |||
767 768 769 770 771 772 773 | } zData[amt] = 0; zData[amt+1] = 0; if( rc!=SQLITE_OK ){ if( amt>NBFS-2 ){ assert( zData!=pMem->zShort ); assert( pMem->flags & MEM_Dyn ); | | | 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 | } zData[amt] = 0; zData[amt+1] = 0; if( rc!=SQLITE_OK ){ if( amt>NBFS-2 ){ assert( zData!=pMem->zShort ); assert( pMem->flags & MEM_Dyn ); sqlite3_free(zData); } else { assert( zData==pMem->zShort ); assert( pMem->flags & MEM_Short ); } return rc; } } |
︙ | ︙ | |||
838 839 840 841 842 843 844 | ** parameter, which must be one of SQLITE_UTF16BE, SQLITE_UTF16LE or ** SQLITE_UTF8. ** ** (2006-02-16:) The enc value can be or-ed with SQLITE_UTF16_ALIGNED. ** If that is the case, then the result must be aligned on an even byte ** boundary. */ | | | | | | | | | > > > | | | | | | | | | > | > | | | | | | | | 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 | ** parameter, which must be one of SQLITE_UTF16BE, SQLITE_UTF16LE or ** SQLITE_UTF8. ** ** (2006-02-16:) The enc value can be or-ed with SQLITE_UTF16_ALIGNED. ** If that is the case, then the result must be aligned on an even byte ** boundary. */ const void *sqlite3ValueText(sqlite3 *db, sqlite3_value* pVal, u8 enc){ if( !pVal ) return 0; assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) ); if( pVal->flags&MEM_Null ){ return 0; } assert( (MEM_Blob>>3) == MEM_Str ); pVal->flags |= (pVal->flags & MEM_Blob)>>3; expandBlob(db, pVal); if( pVal->flags&MEM_Str ){ sqlite3VdbeChangeEncoding(pVal, enc & ~SQLITE_UTF16_ALIGNED); if( (enc & SQLITE_UTF16_ALIGNED)!=0 && 1==(1&(int)pVal->z) ){ assert( (pVal->flags & (MEM_Ephem|MEM_Static))!=0 ); if( sqlite3VdbeMemMakeWriteable(db, pVal)!=SQLITE_OK ){ return 0; } } sqlite3VdbeMemNulTerminate(db, pVal); }else{ assert( (pVal->flags&MEM_Blob)==0 ); sqlite3VdbeMemStringify(db, pVal, enc); assert( 0==(1&(int)pVal->z) ); } assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || db->mallocFailed ); if( pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) ){ return pVal->z; }else{ return 0; } } /* ** Create a new sqlite3_value object. */ sqlite3_value *sqlite3ValueNew(sqlite3 *db){ Mem *p = sqlite3_malloc(sizeof(*p)); if( p ){ p->flags = MEM_Null; p->type = SQLITE_NULL; }else{ db->mallocFailed = 1; } return p; } /* ** Create a new sqlite3_value object, containing the value of pExpr. ** ** This only works for very simple expressions that consist of one constant ** token (i.e. "5", "5.1", "NULL", "'a string'"). If the expression can ** be converted directly into a value, then the value is allocated and ** a pointer written to *ppVal. The caller is responsible for deallocating ** the value by passing it to sqlite3ValueFree() later on. If the expression ** cannot be converted to a value, then *ppVal is set to NULL. */ int sqlite3ValueFromExpr( sqlite3 *db, /* Report malloc() errors here */ Expr *pExpr, /* The expression to evaluate */ u8 enc, /* Encoding to use */ u8 affinity, /* Affinity to use */ sqlite3_value **ppVal /* Write the new value here */ ){ int op; char *zVal = 0; sqlite3_value *pVal = 0; if( !pExpr ){ *ppVal = 0; return SQLITE_OK; } op = pExpr->op; if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){ zVal = sqlite3StrNDup((char*)pExpr->token.z, pExpr->token.n); pVal = sqlite3ValueNew(db); if( !zVal || !pVal ) goto no_mem; sqlite3Dequote(zVal); sqlite3ValueSetStr(db, pVal, -1, zVal, SQLITE_UTF8, sqlite3FreeX); if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_NONE ){ sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, enc); }else{ sqlite3ValueApplyAffinity(pVal, affinity, enc); } }else if( op==TK_UMINUS ) { if( SQLITE_OK==sqlite3ValueFromExpr(pExpr->pLeft, enc, affinity, &pVal) ){ pVal->u.i = -1 * pVal->u.i; pVal->r = -1.0 * pVal->r; } } #ifndef SQLITE_OMIT_BLOB_LITERAL else if( op==TK_BLOB ){ int nVal; pVal = sqlite3ValueNew(); zVal = sqlite3StrNDup((char*)pExpr->token.z+1, pExpr->token.n-1); if( !zVal || !pVal ) goto no_mem; sqlite3Dequote(zVal); nVal = strlen(zVal)/2; sqlite3VdbeMemSetStr(pVal, sqlite3HexToBlob(zVal), nVal, 0, sqlite3FreeX); sqlite3_free(zVal); } #endif *ppVal = pVal; return SQLITE_OK; no_mem: db->mallocFailed = 1; sqlite3_free(zVal); sqlite3ValueFree(pVal); *ppVal = 0; return SQLITE_NOMEM; } /* ** Change the string value of an sqlite3_value object */ void sqlite3ValueSetStr( sqlite3 *db, /* Report malloc errors here */ sqlite3_value *v, /* Value to be set */ int n, /* Length of string z */ const void *z, /* Text of the new string */ u8 enc, /* Encoding to use */ void (*xDel)(void*) /* Destructor for the string */ ){ if( v ) sqlite3VdbeMemSetStr(db, (Mem *)v, z, n, enc, xDel); } /* ** Free an sqlite3_value object */ void sqlite3ValueFree(sqlite3_value *v){ if( !v ) return; sqlite3ValueSetStr(v, 0, 0, SQLITE_UTF8, SQLITE_STATIC); sqlite3_free(v); } /* ** Return the number of bytes in the sqlite3_value object assuming ** that it uses the encoding "enc" */ int sqlite3ValueBytes(sqlite3_value *pVal, u8 enc){ |
︙ | ︙ |
Changes to src/vtab.c.
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 contains code used to help implement virtual tables. ** | | | | | 1 2 3 4 5 6 7 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 36 37 38 39 40 41 42 43 44 45 46 | /* ** 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 contains code used to help implement virtual tables. ** ** $Id: vtab.c,v 1.49 2007/08/16 04:30:41 drh Exp $ */ #ifndef SQLITE_OMIT_VIRTUALTABLE #include "sqliteInt.h" static int createModule( sqlite3 *db, /* Database in which module is registered */ const char *zName, /* Name assigned to this module */ const sqlite3_module *pModule, /* The definition of the module */ void *pAux, /* Context pointer for xCreate/xConnect */ void (*xDestroy)(void *) /* Module destructor function */ ) { int nName = strlen(zName); Module *pMod = (Module *)sqlite3DbMallocRaw(db, sizeof(Module) + nName + 1); if( pMod ){ char *zCopy = (char *)(&pMod[1]); memcpy(zCopy, zName, nName+1); pMod->zName = zCopy; pMod->pModule = pModule; pMod->pAux = pAux; pMod->xDestroy = xDestroy; pMod = (Module *)sqlite3HashInsert(&db->aModule, zCopy, nName, (void*)pMod); if( pMod && pMod->xDestroy ){ pMod->xDestroy(pMod->pAux); } sqlite3_free(pMod); sqlite3ResetInternalSchema(db, 0); } return sqlite3ApiExit(db, SQLITE_OK); } /* |
︙ | ︙ | |||
110 111 112 113 114 115 116 | assert( p->pMod && p->pMod->pModule ); sqlite3VtabUnlock(p->pSchema->db, pVtab); p->pVtab = 0; } if( p->azModuleArg ){ int i; for(i=0; i<p->nModuleArg; i++){ | | | | | | | | > > > | | | | | 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | assert( p->pMod && p->pMod->pModule ); sqlite3VtabUnlock(p->pSchema->db, pVtab); p->pVtab = 0; } if( p->azModuleArg ){ int i; for(i=0; i<p->nModuleArg; i++){ sqlite3_free(p->azModuleArg[i]); } sqlite3_free(p->azModuleArg); } } /* ** Add a new module argument to pTable->azModuleArg[]. ** The string is not copied - the pointer is stored. The ** string will be freed automatically when the table is ** deleted. */ static void addModuleArgument(sqlite3 *db, Table *pTable, char *zArg){ int i = pTable->nModuleArg++; int nBytes = sizeof(char *)*(1+pTable->nModuleArg); char **azModuleArg; azModuleArg = sqlite3_realloc(pTable->azModuleArg, nBytes); if( azModuleArg==0 ){ int j; for(j=0; j<i; j++){ sqlite3_free(pTable->azModuleArg[j]); } sqlite3_free(zArg); sqlite3_free(pTable->azModuleArg); pTable->nModuleArg = 0; db->mallocFailed = 1; }else{ azModuleArg[i] = zArg; azModuleArg[i+1] = 0; } pTable->azModuleArg = azModuleArg; } /* ** The parser calls this routine when it first sees a CREATE VIRTUAL TABLE ** statement. The module name has been parsed, but the optional list ** of parameters that follow the module name are still pending. */ void sqlite3VtabBeginParse( Parse *pParse, /* Parsing context */ Token *pName1, /* Name of new table, or database name */ Token *pName2, /* Name of new table or NULL */ Token *pModuleName /* Name of the module for the virtual table */ ){ int iDb; /* The database the table is being created in */ Table *pTable; /* The new virtual table */ sqlite3 *db; /* Database connection */ #ifndef SQLITE_OMIT_SHARED_CACHE if( sqlite3ThreadDataReadOnly()->useSharedData ){ sqlite3ErrorMsg(pParse, "Cannot use virtual tables in shared-cache mode"); return; } #endif sqlite3StartTable(pParse, pName1, pName2, 0, 0, 1, 0); pTable = pParse->pNewTable; if( pTable==0 || pParse->nErr ) return; assert( 0==pTable->pIndex ); db = pParse->db; iDb = sqlite3SchemaToIndex(db, pTable->pSchema); assert( iDb>=0 ); pTable->isVirtual = 1; pTable->nModuleArg = 0; addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName)); addModuleArgument(db, pTable, sqlite3DbStrDup(db, db->aDb[iDb].zName)); addModuleArgument(db, pTable, sqlite3DbStrDup(db, pTable->zName)); pParse->sNameToken.n = pModuleName->z + pModuleName->n - pName1->z; #ifndef SQLITE_OMIT_AUTHORIZATION /* Creating a virtual table invokes the authorization callback twice. ** The first invocation, to obtain permission to INSERT a row into the ** sqlite_master table, has already been made by sqlite3StartTable(). ** The second call, to obtain permission to create the table, is made now. |
︙ | ︙ | |||
200 201 202 203 204 205 206 | ** in pParse->zArg[] and appends it to the list of arguments on the ** virtual table currently under construction in pParse->pTable. */ static void addArgumentToVtab(Parse *pParse){ if( pParse->sArg.z && pParse->pNewTable ){ const char *z = (const char*)pParse->sArg.z; int n = pParse->sArg.n; | > | | 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 | ** in pParse->zArg[] and appends it to the list of arguments on the ** virtual table currently under construction in pParse->pTable. */ static void addArgumentToVtab(Parse *pParse){ if( pParse->sArg.z && pParse->pNewTable ){ const char *z = (const char*)pParse->sArg.z; int n = pParse->sArg.n; sqlite3 *db = pParse->db; addModuleArgument(db, pParse->pNewTable, sqlite3DbStrNDup(db, z, n)); } } /* ** The parser calls this routine after the CREATE VIRTUAL TABLE statement ** has been completely parsed. */ |
︙ | ︙ | |||
263 264 265 266 267 268 269 | "SET type='table', name=%Q, tbl_name=%Q, rootpage=0, sql=%Q " "WHERE rowid=#1", db->aDb[iDb].zName, SCHEMA_TABLE(iDb), pTab->zName, pTab->zName, zStmt ); | | | 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 | "SET type='table', name=%Q, tbl_name=%Q, rootpage=0, sql=%Q " "WHERE rowid=#1", db->aDb[iDb].zName, SCHEMA_TABLE(iDb), pTab->zName, pTab->zName, zStmt ); sqlite3_free(zStmt); v = sqlite3GetVdbe(pParse); sqlite3ChangeCookie(db, v, iDb); sqlite3VdbeAddOp(v, OP_Expire, 0, 0); zWhere = sqlite3MPrintf("name='%q'", pTab->zName); sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 1, zWhere, P3_DYNAMIC); sqlite3VdbeOp3(v, OP_VCreate, iDb, 0, pTab->zName, strlen(pTab->zName) + 1); |
︙ | ︙ | |||
371 372 373 374 375 376 377 | *pzErr = sqlite3MPrintf(zFormat, pTab->zName); rc = SQLITE_ERROR; } if( rc==SQLITE_OK ){ rc = rc2; } db->pVTab = 0; | | | 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 | *pzErr = sqlite3MPrintf(zFormat, pTab->zName); rc = SQLITE_ERROR; } if( rc==SQLITE_OK ){ rc = rc2; } db->pVTab = 0; sqlite3_free(zModuleName); /* If everything went according to plan, loop through the columns ** of the table to see if any of them contain the token "hidden". ** If so, set the Column.isHidden flag and remove the token from ** the type string. */ if( rc==SQLITE_OK ){ |
︙ | ︙ | |||
440 441 442 443 444 445 446 | } else { char *zErr = 0; sqlite3 *db = pParse->db; rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xConnect, &zErr); if( rc!=SQLITE_OK ){ sqlite3ErrorMsg(pParse, "%s", zErr); } | | | > | | 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 | } else { char *zErr = 0; sqlite3 *db = pParse->db; rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xConnect, &zErr); if( rc!=SQLITE_OK ){ sqlite3ErrorMsg(pParse, "%s", zErr); } sqlite3_free(zErr); } return rc; } /* ** Add the virtual table pVtab to the array sqlite3.aVTrans[]. */ static int addToVTrans(sqlite3 *db, sqlite3_vtab *pVtab){ const int ARRAY_INCR = 5; /* Grow the sqlite3.aVTrans array if required */ if( (db->nVTrans%ARRAY_INCR)==0 ){ sqlite3_vtab **aVTrans; int nBytes = sizeof(sqlite3_vtab *) * (db->nVTrans + ARRAY_INCR); aVTrans = sqlite3_realloc((void *)db->aVTrans, nBytes); if( !aVTrans ){ db->mallocFailed = 1; return SQLITE_NOMEM; } memset(&aVTrans[db->nVTrans], 0, sizeof(sqlite3_vtab *)*ARRAY_INCR); db->aVTrans = aVTrans; } /* Add pVtab to the end of sqlite3.aVTrans */ db->aVTrans[db->nVTrans++] = pVtab; sqlite3VtabLock(pVtab); return SQLITE_OK; } /* ** This function is invoked by the vdbe to call the xCreate method ** of the virtual table named zTab in database iDb. ** ** If an error occurs, *pzErr is set to point an an English language ** description of the error and an SQLITE_XXX error code is returned. ** In this case the caller must call sqlite3_free() on *pzErr. */ int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){ int rc = SQLITE_OK; Table *pTab; Module *pMod; const char *zModule; |
︙ | ︙ | |||
542 543 544 545 546 547 548 | pTab->aCol = sParse.pNewTable->aCol; pTab->nCol = sParse.pNewTable->nCol; sParse.pNewTable->nCol = 0; sParse.pNewTable->aCol = 0; db->pVTab = 0; } else { sqlite3Error(db, SQLITE_ERROR, zErr); | | | 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 | pTab->aCol = sParse.pNewTable->aCol; pTab->nCol = sParse.pNewTable->nCol; sParse.pNewTable->nCol = 0; sParse.pNewTable->aCol = 0; db->pVTab = 0; } else { sqlite3Error(db, SQLITE_ERROR, zErr); sqlite3_free(zErr); rc = SQLITE_ERROR; } sParse.declareVtab = 0; sqlite3_finalize((sqlite3_stmt*)sParse.pVdbe); sqlite3DeleteTable(sParse.pNewTable); sParse.pNewTable = 0; |
︙ | ︙ | |||
603 604 605 606 607 608 609 | for(i=0; i<db->nVTrans && db->aVTrans[i]; i++){ sqlite3_vtab *pVtab = db->aVTrans[i]; int (*x)(sqlite3_vtab *); x = *(int (**)(sqlite3_vtab *))((char *)pVtab->pModule + offset); if( x ) x(pVtab); sqlite3VtabUnlock(db, pVtab); } | | | 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 | for(i=0; i<db->nVTrans && db->aVTrans[i]; i++){ sqlite3_vtab *pVtab = db->aVTrans[i]; int (*x)(sqlite3_vtab *); x = *(int (**)(sqlite3_vtab *))((char *)pVtab->pModule + offset); if( x ) x(pVtab); sqlite3VtabUnlock(db, pVtab); } sqlite3_free(db->aVTrans); db->nVTrans = 0; db->aVTrans = 0; } } /* ** If argument rc2 is not SQLITE_OK, then return it and do nothing. |
︙ | ︙ | |||
720 721 722 723 724 725 726 727 728 729 730 731 732 733 | ** overload MATCH, LIKE, GLOB, and REGEXP operators. ** ** Return either the pDef argument (indicating no change) or a ** new FuncDef structure that is marked as ephemeral using the ** SQLITE_FUNC_EPHEM flag. */ FuncDef *sqlite3VtabOverloadFunction( FuncDef *pDef, /* Function to possibly overload */ int nArg, /* Number of arguments to the function */ Expr *pExpr /* First argument to the function */ ){ Table *pTab; sqlite3_vtab *pVtab; sqlite3_module *pMod; | > | 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 | ** overload MATCH, LIKE, GLOB, and REGEXP operators. ** ** Return either the pDef argument (indicating no change) or a ** new FuncDef structure that is marked as ephemeral using the ** SQLITE_FUNC_EPHEM flag. */ FuncDef *sqlite3VtabOverloadFunction( sqlite3 *db, /* Database connection for reporting malloc problems */ FuncDef *pDef, /* Function to possibly overload */ int nArg, /* Number of arguments to the function */ Expr *pExpr /* First argument to the function */ ){ Table *pTab; sqlite3_vtab *pVtab; sqlite3_module *pMod; |
︙ | ︙ | |||
750 751 752 753 754 755 756 | assert( pVtab->pModule!=0 ); pMod = (sqlite3_module *)pVtab->pModule; if( pMod->xFindFunction==0 ) return pDef; /* Call the xFuncFunction method on the virtual table implementation ** to see if the implementation wants to overload this function */ | | > | | | | | > | | 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 | assert( pVtab->pModule!=0 ); pMod = (sqlite3_module *)pVtab->pModule; if( pMod->xFindFunction==0 ) return pDef; /* Call the xFuncFunction method on the virtual table implementation ** to see if the implementation wants to overload this function */ zLowerName = sqlite3DbStrDup(db, pDef->zName); if( zLowerName ){ for(z=(unsigned char*)zLowerName; *z; z++){ *z = sqlite3UpperToLower[*z]; } rc = pMod->xFindFunction(pVtab, nArg, zLowerName, &xFunc, &pArg); sqlite3_free(zLowerName); } if( rc==0 ){ return pDef; } /* Create a new ephemeral function definition for the overloaded ** function */ pNew = sqlite3DbMallocZero(db, sizeof(*pNew) + strlen(pDef->zName) ); if( pNew==0 ){ return pDef; } *pNew = *pDef; memcpy(pNew->zName, pDef->zName, strlen(pDef->zName)+1); pNew->xFunc = xFunc; pNew->pUserData = pArg; pNew->flags |= SQLITE_FUNC_EPHEM; return pNew; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
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.255 2007/08/16 04:30:41 drh Exp $ */ #include "sqliteInt.h" /* ** The number of bits in a Bitmask. "BMS" means "BitMask Size". */ #define BMS (sizeof(Bitmask)*8) |
︙ | ︙ | |||
203 204 205 206 207 208 209 | WhereTerm *a; for(i=pWC->nTerm-1, a=pWC->a; i>=0; i--, a++){ if( a->flags & TERM_DYNAMIC ){ sqlite3ExprDelete(a->pExpr); } } if( pWC->a!=pWC->aStatic ){ | | | > | | 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 | WhereTerm *a; for(i=pWC->nTerm-1, a=pWC->a; i>=0; i--, a++){ if( a->flags & TERM_DYNAMIC ){ sqlite3ExprDelete(a->pExpr); } } if( pWC->a!=pWC->aStatic ){ sqlite3_free(pWC->a); } } /* ** Add a new entries to the WhereClause structure. Increase the allocated ** space as necessary. ** ** If the flags argument includes TERM_DYNAMIC, then responsibility ** for freeing the expression p is assumed by the WhereClause object. ** ** WARNING: This routine might reallocate the space used to store ** WhereTerms. All pointers to WhereTerms should be invalided after ** calling this routine. Such pointers may be reinitialized by referencing ** the pWC->a[] array. */ static int whereClauseInsert(WhereClause *pWC, Expr *p, int flags){ WhereTerm *pTerm; int idx; if( pWC->nTerm>=pWC->nSlot ){ WhereTerm *pOld = pWC->a; pWC->a = sqlite3_malloc( sizeof(pWC->a[0])*pWC->nSlot*2 ); if( pWC->a==0 ){ pWC->pParse->db->mallocFailed = 1; if( flags & TERM_DYNAMIC ){ sqlite3ExprDelete(p); } return 0; } memcpy(pWC->a, pOld, sizeof(pWC->a[0])*pWC->nTerm); if( pOld!=pWC->aStatic ){ sqlite3_free(pOld); } pWC->nSlot *= 2; } pTerm = &pWC->a[idx = pWC->nTerm]; pWC->nTerm++; pTerm->pExpr = p; pTerm->flags = flags; |
︙ | ︙ | |||
546 547 548 549 550 551 552 | */ pColl = db->pDfltColl; } if( (pColl->type!=SQLITE_COLL_BINARY || noCase) && (pColl->type!=SQLITE_COLL_NOCASE || !noCase) ){ return 0; } | | | 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 | */ pColl = db->pDfltColl; } if( (pColl->type!=SQLITE_COLL_BINARY || noCase) && (pColl->type!=SQLITE_COLL_NOCASE || !noCase) ){ return 0; } sqlite3DequoteExpr(db, pRight); z = (char *)pRight->token.z; for(cnt=0; (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2]; cnt++){} if( cnt==0 || 255==(u8)z[cnt] ){ return 0; } *pisComplete = z[cnt]==wc[0] && z[cnt+1]==0; *pnPattern = cnt; |
︙ | ︙ | |||
711 712 713 714 715 716 717 718 | ExprMaskSet *pMaskSet = pWC->pMaskSet; Expr *pExpr = pTerm->pExpr; Bitmask prereqLeft; Bitmask prereqAll; int nPattern; int isComplete; int op; | > | | 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 | ExprMaskSet *pMaskSet = pWC->pMaskSet; Expr *pExpr = pTerm->pExpr; Bitmask prereqLeft; Bitmask prereqAll; int nPattern; int isComplete; int op; sqlite3 *db = pWC->pParse->db; if( db->mallocFailed ) return; prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft); op = pExpr->op; if( op==TK_IN ){ assert( pExpr->pRight==0 ); pTerm->prereqRight = exprListTableUsage(pMaskSet, pExpr->pList) | exprSelectTableUsage(pMaskSet, pExpr->pSelect); }else if( op==TK_ISNULL ){ |
︙ | ︙ | |||
745 746 747 748 749 750 751 | pTerm->eOperator = operatorMask(op); } if( pRight && pRight->op==TK_COLUMN ){ WhereTerm *pNew; Expr *pDup; if( pTerm->leftCursor>=0 ){ int idxNew; | | | | 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 | pTerm->eOperator = operatorMask(op); } if( pRight && pRight->op==TK_COLUMN ){ WhereTerm *pNew; Expr *pDup; if( pTerm->leftCursor>=0 ){ int idxNew; pDup = sqlite3ExprDup(db, pExpr); if( db->mallocFailed ){ sqlite3ExprDelete(pDup); return; } idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC); if( idxNew==0 ) return; pNew = &pWC->a[idxNew]; pNew->iParent = idxTerm; |
︙ | ︙ | |||
784 785 786 787 788 789 790 | int i; static const u8 ops[] = {TK_GE, TK_LE}; assert( pList!=0 ); assert( pList->nExpr==2 ); for(i=0; i<2; i++){ Expr *pNewExpr; int idxNew; | | | | 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 | int i; static const u8 ops[] = {TK_GE, TK_LE}; assert( pList!=0 ); assert( pList->nExpr==2 ); for(i=0; i<2; i++){ Expr *pNewExpr; int idxNew; pNewExpr = sqlite3Expr(ops[i], sqlite3ExprDup(db, pExpr->pLeft), sqlite3ExprDup(db, pList->a[i].pExpr), 0); idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC); exprAnalyze(pSrc, pWC, idxNew); pTerm = &pWC->a[idxTerm]; pWC->a[idxNew].iParent = idxTerm; } pTerm->nChild = 2; } |
︙ | ︙ | |||
845 846 847 848 849 850 851 | }while( !ok && (sOr.a[j++].flags & TERM_COPIED)!=0 && j<2 ); if( ok ){ ExprList *pList = 0; Expr *pNew, *pDup; Expr *pLeft = 0; for(i=sOr.nTerm-1, pOrTerm=sOr.a; i>=0 && ok; i--, pOrTerm++){ if( (pOrTerm->flags & TERM_OR_OK)==0 ) continue; | | | | | 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 | }while( !ok && (sOr.a[j++].flags & TERM_COPIED)!=0 && j<2 ); if( ok ){ ExprList *pList = 0; Expr *pNew, *pDup; Expr *pLeft = 0; for(i=sOr.nTerm-1, pOrTerm=sOr.a; i>=0 && ok; i--, pOrTerm++){ if( (pOrTerm->flags & TERM_OR_OK)==0 ) continue; pDup = sqlite3ExprDup(db, pOrTerm->pExpr->pRight); pList = sqlite3ExprListAppend(pWC->pParse, pList, pDup, 0); pLeft = pOrTerm->pExpr->pLeft; } assert( pLeft!=0 ); pDup = sqlite3ExprDup(db, pLeft); pNew = sqlite3Expr(TK_IN, pDup, 0, 0); if( pNew ){ int idxNew; transferJoinMarkings(pNew, pExpr); pNew->pList = pList; idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC); exprAnalyze(pSrc, pWC, idxNew); |
︙ | ︙ | |||
874 875 876 877 878 879 880 | } #endif /* SQLITE_OMIT_OR_OPTIMIZATION */ #ifndef SQLITE_OMIT_LIKE_OPTIMIZATION /* Add constraints to reduce the search space on a LIKE or GLOB ** operator. */ | | | | | | | | 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 | } #endif /* SQLITE_OMIT_OR_OPTIMIZATION */ #ifndef SQLITE_OMIT_LIKE_OPTIMIZATION /* Add constraints to reduce the search space on a LIKE or GLOB ** operator. */ if( isLikeOrGlob(db, pExpr, &nPattern, &isComplete) ){ Expr *pLeft, *pRight; Expr *pStr1, *pStr2; Expr *pNewExpr1, *pNewExpr2; int idxNew1, idxNew2; pLeft = pExpr->pList->a[1].pExpr; pRight = pExpr->pList->a[0].pExpr; pStr1 = sqlite3PExpr(pParse, TK_STRING, 0, 0, 0); if( pStr1 ){ sqlite3TokenCopy(db, &pStr1->token, &pRight->token); pStr1->token.n = nPattern; pStr1->flags = EP_Dequoted; } pStr2 = sqlite3ExprDup(db, pStr1); if( pStr2 ){ assert( pStr2->token.dyn ); ++*(u8*)&pStr2->token.z[nPattern-1]; } pNewExpr1 = sqlite3PExpr(pParse, TK_GE, sqlite3ExprDup(db,pLeft), pStr1, 0); idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC); exprAnalyze(pSrc, pWC, idxNew1); pNewExpr2 = sqlite3PExpr(pParse, TK_LT, sqlite3ExprDup(db,pLeft), pStr2, 0); idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC); exprAnalyze(pSrc, pWC, idxNew2); pTerm = &pWC->a[idxTerm]; if( isComplete ){ pWC->a[idxNew1].iParent = idxTerm; pWC->a[idxNew2].iParent = idxTerm; pTerm->nChild = 2; |
︙ | ︙ | |||
927 928 929 930 931 932 933 | pRight = pExpr->pList->a[0].pExpr; pLeft = pExpr->pList->a[1].pExpr; prereqExpr = exprTableUsage(pMaskSet, pRight); prereqColumn = exprTableUsage(pMaskSet, pLeft); if( (prereqExpr & prereqColumn)==0 ){ Expr *pNewExpr; | | | 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 | pRight = pExpr->pList->a[0].pExpr; pLeft = pExpr->pList->a[1].pExpr; prereqExpr = exprTableUsage(pMaskSet, pRight); prereqColumn = exprTableUsage(pMaskSet, pLeft); if( (prereqExpr & prereqColumn)==0 ){ Expr *pNewExpr; pNewExpr = sqlite3Expr(TK_MATCH, 0, sqlite3ExprDup(db, pRight), 0); idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC); pNewTerm = &pWC->a[idxNew]; pNewTerm->prereqRight = prereqExpr; pNewTerm->leftCursor = pLeft->iTable; pNewTerm->leftColumn = pLeft->iColumn; pNewTerm->eOperator = WO_MATCH; pNewTerm->iParent = idxTerm; |
︙ | ︙ | |||
1253 1254 1255 1256 1257 1258 1259 | if( i==pOrderBy->nExpr ){ nOrderBy = pOrderBy->nExpr; } } /* Allocate the sqlite3_index_info structure */ | | > | 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 | if( i==pOrderBy->nExpr ){ nOrderBy = pOrderBy->nExpr; } } /* Allocate the sqlite3_index_info structure */ pIdxInfo = sqlite3_malloc( sizeof(*pIdxInfo) + (sizeof(*pIdxCons) + sizeof(*pUsage))*nTerm + sizeof(*pIdxOrderBy)*nOrderBy ); if( pIdxInfo==0 ){ pParse->db->mallocFailed = 1; sqlite3ErrorMsg(pParse, "out of memory"); return 0.0; } *ppIdxInfo = pIdxInfo; /* Initialize the structure. The sqlite3_index_info structure contains ** many fields that are declared "const" to prevent xBestIndex from |
︙ | ︙ | |||
1371 1372 1373 1374 1375 1376 1377 | sqlite3SafetyOff(pParse->db); WHERETRACE(("xBestIndex for %s\n", pTab->zName)); TRACE_IDX_INPUTS(pIdxInfo); rc = pTab->pVtab->pModule->xBestIndex(pTab->pVtab, pIdxInfo); TRACE_IDX_OUTPUTS(pIdxInfo); if( rc!=SQLITE_OK ){ if( rc==SQLITE_NOMEM ){ | | | 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 | sqlite3SafetyOff(pParse->db); WHERETRACE(("xBestIndex for %s\n", pTab->zName)); TRACE_IDX_INPUTS(pIdxInfo); rc = pTab->pVtab->pModule->xBestIndex(pTab->pVtab, pIdxInfo); TRACE_IDX_OUTPUTS(pIdxInfo); if( rc!=SQLITE_OK ){ if( rc==SQLITE_NOMEM ){ pParse->db->mallocFailed = 1; }else { sqlite3ErrorMsg(pParse, "%s", sqlite3ErrStr(rc)); } sqlite3SafetyOn(pParse->db); }else{ rc = sqlite3SafetyOn(pParse->db); } |
︙ | ︙ | |||
1732 1733 1734 1735 1736 1737 1738 | iTab = pX->iTable; sqlite3VdbeAddOp(v, OP_Rewind, iTab, 0); VdbeComment((v, "# %.*s", pX->span.n, pX->span.z)); if( pLevel->nIn==0 ){ pLevel->nxt = sqlite3VdbeMakeLabel(v); } pLevel->nIn++; | | | 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 | iTab = pX->iTable; sqlite3VdbeAddOp(v, OP_Rewind, iTab, 0); VdbeComment((v, "# %.*s", pX->span.n, pX->span.z)); if( pLevel->nIn==0 ){ pLevel->nxt = sqlite3VdbeMakeLabel(v); } pLevel->nIn++; pLevel->aInLoop = sqlite3DbReallocOrFree(pParse->db, pLevel->aInLoop, sizeof(pLevel->aInLoop[0])*pLevel->nIn); pIn = pLevel->aInLoop; if( pIn ){ pIn += pLevel->nIn - 1; pIn->iCur = iTab; pIn->topAddr = sqlite3VdbeAddOp(v, OP_Column, iTab, 0); sqlite3VdbeAddOp(v, OP_IsNull, -1, 0); |
︙ | ︙ | |||
1851 1852 1853 1854 1855 1856 1857 | if( pInfo->needToFreeIdxStr ){ /* Coverage: Don't think this can be reached. By the time this ** function is called, the index-strings have been passed ** to the vdbe layer for deletion. */ sqlite3_free(pInfo->idxStr); } | | | | 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 | if( pInfo->needToFreeIdxStr ){ /* Coverage: Don't think this can be reached. By the time this ** function is called, the index-strings have been passed ** to the vdbe layer for deletion. */ sqlite3_free(pInfo->idxStr); } sqlite3_free(pInfo); } } sqlite3_free(pWInfo); } } /* ** Generate the beginning of the loop used for WHERE clause processing. ** The return value is a pointer to an opaque structure that contains |
︙ | ︙ | |||
1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 | WhereTerm *pTerm; /* A single term in the WHERE clause */ ExprMaskSet maskSet; /* The expression mask set */ WhereClause wc; /* The WHERE clause is divided into these terms */ struct SrcList_item *pTabItem; /* A single entry from pTabList */ WhereLevel *pLevel; /* A single level in the pWInfo list */ int iFrom; /* First unused FROM clause element */ int andFlags; /* AND-ed combination of all wc.a[].flags */ /* The number of tables in the FROM clause is limited by the number of ** bits in a Bitmask */ if( pTabList->nSrc>BMS ){ sqlite3ErrorMsg(pParse, "at most %d tables in a join", BMS); return 0; } /* Split the WHERE clause into separate subexpressions where each ** subexpression is separated by an AND operator. */ initMaskSet(&maskSet); whereClauseInit(&wc, pParse, &maskSet); whereSplit(&wc, pWhere, TK_AND); /* Allocate and initialize the WhereInfo structure that will become the ** return value. */ | > > > | | | 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 | WhereTerm *pTerm; /* A single term in the WHERE clause */ ExprMaskSet maskSet; /* The expression mask set */ WhereClause wc; /* The WHERE clause is divided into these terms */ struct SrcList_item *pTabItem; /* A single entry from pTabList */ WhereLevel *pLevel; /* A single level in the pWInfo list */ int iFrom; /* First unused FROM clause element */ int andFlags; /* AND-ed combination of all wc.a[].flags */ sqlite3 *db; /* Database connection */ /* The number of tables in the FROM clause is limited by the number of ** bits in a Bitmask */ if( pTabList->nSrc>BMS ){ sqlite3ErrorMsg(pParse, "at most %d tables in a join", BMS); return 0; } /* Split the WHERE clause into separate subexpressions where each ** subexpression is separated by an AND operator. */ initMaskSet(&maskSet); whereClauseInit(&wc, pParse, &maskSet); whereSplit(&wc, pWhere, TK_AND); /* Allocate and initialize the WhereInfo structure that will become the ** return value. */ db = pParse->db; pWInfo = sqlite3DbMallocZero(db, sizeof(WhereInfo) + pTabList->nSrc*sizeof(WhereLevel)); if( db->mallocFailed ){ goto whereBeginNoMem; } pWInfo->nLevel = pTabList->nSrc; pWInfo->pParse = pParse; pWInfo->pTabList = pTabList; pWInfo->iBreak = sqlite3VdbeMakeLabel(v); |
︙ | ︙ | |||
2010 2011 2012 2013 2014 2015 2016 | ** want to analyze these virtual terms, so start analyzing at the end ** and work forward so that the added virtual terms are never processed. */ for(i=0; i<pTabList->nSrc; i++){ createMask(&maskSet, pTabList->a[i].iCursor); } exprAnalyzeAll(pTabList, &wc); | | | 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 | ** want to analyze these virtual terms, so start analyzing at the end ** and work forward so that the added virtual terms are never processed. */ for(i=0; i<pTabList->nSrc; i++){ createMask(&maskSet, pTabList->a[i].iCursor); } exprAnalyzeAll(pTabList, &wc); if( db->mallocFailed ){ goto whereBeginNoMem; } /* Chose the best index to use for each table in the FROM clause. ** ** This loop fills in the following fields: ** |
︙ | ︙ | |||
2687 2688 2689 2690 2691 2692 2693 | int j; sqlite3VdbeResolveLabel(v, pLevel->nxt); for(j=pLevel->nIn, pIn=&pLevel->aInLoop[j-1]; j>0; j--, pIn--){ sqlite3VdbeJumpHere(v, pIn->topAddr+1); sqlite3VdbeAddOp(v, OP_Next, pIn->iCur, pIn->topAddr); sqlite3VdbeJumpHere(v, pIn->topAddr-1); } | | | 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 | int j; sqlite3VdbeResolveLabel(v, pLevel->nxt); for(j=pLevel->nIn, pIn=&pLevel->aInLoop[j-1]; j>0; j--, pIn--){ sqlite3VdbeJumpHere(v, pIn->topAddr+1); sqlite3VdbeAddOp(v, OP_Next, pIn->iCur, pIn->topAddr); sqlite3VdbeJumpHere(v, pIn->topAddr-1); } sqlite3_free(pLevel->aInLoop); } sqlite3VdbeResolveLabel(v, pLevel->brk); if( pLevel->iLeftJoin ){ int addr; addr = sqlite3VdbeAddOp(v, OP_IfMemPos, pLevel->iLeftJoin, 0); sqlite3VdbeAddOp(v, OP_NullRow, pTabList->a[i].iCursor, 0); if( pLevel->iIdxCur>=0 ){ |
︙ | ︙ |