Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Make sure VdbeFunc entries are initialized before trying to destroy them. Also, unrelated comment changes in build.c. (CVS 1643) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
fc3b3a8fe86980db4de402bb8e85f8f7 |
User & Date: | drh 2004-06-19 17:33:07.000 |
Context
2004-06-20
| ||
03:06 | fix fulltest error by restoring unset (CVS 1644) (check-in: d2ccac9d01 user: dougcurrie tags: trunk) | |
2004-06-19
| ||
17:33 | Make sure VdbeFunc entries are initialized before trying to destroy them. Also, unrelated comment changes in build.c. (CVS 1643) (check-in: fc3b3a8fe8 user: drh tags: trunk) | |
16:06 | Omit the DB_Locked and DB_Cookie flags. Other minor cleanup. (CVS 1642) (check-in: 01f74b420c user: drh tags: trunk) | |
Changes
Changes to src/build.c.
︙ | ︙ | |||
19 20 21 22 23 24 25 | ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** PRAGMA ** | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** PRAGMA ** ** $Id: build.c,v 1.227 2004/06/19 17:33:07 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** This routine is called when a new SQL statement is beginning to ** be parsed. Check to see if the schema for the database needs |
︙ | ︙ | |||
58 59 60 61 62 63 64 65 66 67 68 69 70 71 | /* Begin by generating some termination code at the end of the ** vdbe program */ db = pParse->db; v = sqlite3GetVdbe(pParse); if( v ){ sqlite3VdbeAddOp(v, OP_Halt, 0, 0); if( pParse->cookieMask!=0 ){ u32 mask; int iDb; sqlite3VdbeChangeP2(v, pParse->cookieGoto, sqlite3VdbeCurrentAddr(v)); for(iDb=0, mask=1; iDb<db->nDb; mask<<=1, iDb++){ if( (mask & pParse->cookieMask)==0 ) continue; sqlite3VdbeAddOp(v, OP_Transaction, iDb, (mask & pParse->writeMask)!=0); | > > > > > > > | 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | /* Begin by generating some termination code at the end of the ** vdbe program */ db = pParse->db; 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 ** transaction on each used database and to verify the schema cookie ** on each used database. */ if( pParse->cookieMask!=0 ){ u32 mask; int iDb; sqlite3VdbeChangeP2(v, pParse->cookieGoto, sqlite3VdbeCurrentAddr(v)); for(iDb=0, mask=1; iDb<db->nDb; mask<<=1, iDb++){ if( (mask & pParse->cookieMask)==0 ) continue; sqlite3VdbeAddOp(v, OP_Transaction, iDb, (mask & pParse->writeMask)!=0); |
︙ | ︙ | |||
217 218 219 220 221 222 223 | } } sqliteDeleteIndex(db, pIndex); } /* ** Erase all schema information from the in-memory hash tables of | | | | 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 | } } sqliteDeleteIndex(db, pIndex); } /* ** Erase all schema information from the in-memory hash tables of ** a sigle database. This routine is called to reclaim memory ** before the closes. It is also called during a rollback ** if there were schema changes during the transaction. ** ** If iDb<=0 then reset the internal schema tables for all database ** files. If iDb>=2 then reset the internal schema for only the ** single file indicated. */ void sqlite3ResetInternalSchema(sqlite *db, int iDb){ |
︙ | ︙ | |||
353 354 355 356 357 358 359 | pFKey->zTo, strlen(pFKey->zTo)+1)!=pFKey ); sqliteFree(pFKey); } /* Delete the Table structure itself. */ for(i=0; i<pTable->nCol; i++){ | | | | > | | 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 | pFKey->zTo, strlen(pFKey->zTo)+1)!=pFKey ); sqliteFree(pFKey); } /* Delete the Table structure itself. */ for(i=0; i<pTable->nCol; i++){ Column *pCol = &pTable->aCol[i]; sqliteFree(pCol->zName); sqliteFree(pCol->zDflt); sqliteFree(pCol->zType); } sqliteFree(pTable->zName); sqliteFree(pTable->aCol); if( pTable->zColAff ){ sqliteFree(pTable->zColAff); } sqlite3SelectDelete(pTable->pSelect); sqliteFree(pTable); } /* ** Unlink the given table from the hash tables and the delete the ** table structure with all its indices and foreign keys. */ static void sqliteUnlinkAndDeleteTable(sqlite *db, Table *p){ Table *pOld; FKey *pF1, *pF2; int i = p->iDb; assert( db!=0 ); pOld = sqlite3HashInsert(&db->aDb[i].tblHash, p->zName, strlen(p->zName)+1,0); assert( pOld==0 || pOld==p ); for(pF1=p->pFKey; pF1; pF1=pF1->pNextFrom){ int nTo = strlen(pF1->zTo) + 1; pF2 = sqlite3HashFind(&db->aDb[i].aFKey, pF1->zTo, nTo); if( pF2==pF1 ){ sqlite3HashInsert(&db->aDb[i].aFKey, pF1->zTo, nTo, pF1->pNextTo); }else{ |
︙ | ︙ | |||
440 441 442 443 444 445 446 447 | 0==sqlite3StrNICmp(db->aDb[i].zName, pName->z, pName->n) ){ return i; } } return -1; } int sqlite3TwoPartName( | > > > > > > > > > > > > > > > > | | | | | | 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 | 0==sqlite3StrNICmp(db->aDb[i].zName, pName->z, pName->n) ){ return i; } } return -1; } /* 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: ** ** CREATE TABLE xxx.yyy (...); ** ** Then pName1 is set to "xxx" and pName2 "yyy". On the other hand if ** the table name is not fully qualified, i.e.: ** ** CREATE TABLE yyy(...); ** ** Then pName1 is set to "yyy" and pName2 is "". ** ** This routine sets the *ppUnqual pointer to point at the token (pName1 or ** pName2) that stores the unqualified table name. The index of the ** database "xxx" is returned. */ int sqlite3TwoPartName( Parse *pParse, /* Parsing and code generating context */ Token *pName1, /* The "xxx" in the name "xxx.yyy" */ Token *pName2, /* The "yyy" in the name "xxx.yyy" */ Token **pUnqual /* Write the unqualified object name here */ ){ int iDb; /* Database holding the object */ sqlite3 *db = pParse->db; if( pName2 && pName2->n>0 ){ assert( !db->init.busy ); *pUnqual = pName2; iDb = findDb(db, pName1); if( iDb<0 ){ |
︙ | ︙ |
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.74 2004/06/19 17:33:07 drh Exp $ */ #include <ctype.h> #include <math.h> #include <stdlib.h> #include <assert.h> #include "sqliteInt.h" #include "vdbeInt.h" |
︙ | ︙ | |||
764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 | sqlite3Randomness(n, zBuf); for(i=0; i<n; i++){ zBuf[i] = zSrc[zBuf[i]%(sizeof(zSrc)-1)]; } zBuf[n] = 0; sqlite3_result_text(context, zBuf, n, SQLITE_TRANSIENT); } /* ** The following two SQL functions are used to test returning a text ** result with a destructor. Function 'test_destructor' takes one argument ** and returns the same argument interpreted as TEXT. A destructor is ** passed with the sqlite3_result_text() call. ** ** SQL function 'test_destructor_count' returns the number of outstanding | > > | 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 | sqlite3Randomness(n, zBuf); for(i=0; i<n; i++){ zBuf[i] = zSrc[zBuf[i]%(sizeof(zSrc)-1)]; } zBuf[n] = 0; sqlite3_result_text(context, zBuf, n, SQLITE_TRANSIENT); } #endif /* SQLITE_TEST */ #ifdef SQLITE_TEST /* ** The following two SQL functions are used to test returning a text ** result with a destructor. Function 'test_destructor' takes one argument ** and returns the same argument interpreted as TEXT. A destructor is ** passed with the sqlite3_result_text() call. ** ** SQL function 'test_destructor_count' returns the number of outstanding |
︙ | ︙ | |||
806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 | static void test_destructor_count( sqlite3_context *pCtx, int nArg, sqlite3_value **argv ){ sqlite3_result_int(pCtx, test_destructor_count_var); } static void free_test_auxdata(void *p) {sqliteFree(p);} static void test_auxdata( sqlite3_context *pCtx, int nArg, sqlite3_value **argv ){ int i; | > > > > > > > > > > > > > | 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 | static void test_destructor_count( sqlite3_context *pCtx, int nArg, sqlite3_value **argv ){ sqlite3_result_int(pCtx, test_destructor_count_var); } #endif /* SQLITE_TEST */ #ifdef SQLITE_TEST /* ** Routines for testing the sqlite3_get_auxdata() and sqlite3_set_auxdata() ** interface. ** ** 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) {sqliteFree(p);} static void test_auxdata( sqlite3_context *pCtx, int nArg, sqlite3_value **argv ){ int i; |
︙ | ︙ | |||
836 837 838 839 840 841 842 | sqlite3_set_auxdata(pCtx, i, zAux, free_test_auxdata); } zRet[i*2+1] = ' '; } } sqlite3_result_text(pCtx, zRet, 2*nArg-1, free_test_auxdata); } | | | 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 | sqlite3_set_auxdata(pCtx, i, zAux, free_test_auxdata); } zRet[i*2+1] = ' '; } } sqlite3_result_text(pCtx, zRet, 2*nArg-1, free_test_auxdata); } #endif /* SQLITE_TEST */ /* ** An instance of the following structure holds the context of a ** sum() or avg() aggregate computation. */ typedef struct SumCtx SumCtx; struct SumCtx { |
︙ | ︙ |
Changes to src/vdbeapi.c.
︙ | ︙ | |||
237 238 239 240 241 242 243 244 245 246 247 248 249 250 | if( iArg<0 ) return; pVdbeFunc = pCtx->pVdbeFunc; if( !pVdbeFunc || pVdbeFunc->nAux<=iArg ){ int nMalloc = sizeof(VdbeFunc) + sizeof(struct AuxData)*iArg; pCtx->pVdbeFunc = pVdbeFunc = sqliteRealloc(pVdbeFunc, nMalloc); if( !pVdbeFunc ) return; pVdbeFunc->nAux = iArg+1; pVdbeFunc->pFunc = pCtx->pFunc; } pAuxData = &pVdbeFunc->apAux[iArg]; if( pAuxData->pAux && pAuxData->xDelete ){ pAuxData->xDelete(pAuxData->pAux); | > > | 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 | if( iArg<0 ) return; pVdbeFunc = pCtx->pVdbeFunc; if( !pVdbeFunc || pVdbeFunc->nAux<=iArg ){ int nMalloc = sizeof(VdbeFunc) + sizeof(struct AuxData)*iArg; pCtx->pVdbeFunc = pVdbeFunc = sqliteRealloc(pVdbeFunc, nMalloc); if( !pVdbeFunc ) return; memset(&pVdbeFunc->apAux[pVdbeFunc->nAux], 0, sizeof(struct AuxData)*(iArg+1-pVdbeFunc->nAux)); pVdbeFunc->nAux = iArg+1; pVdbeFunc->pFunc = pCtx->pFunc; } pAuxData = &pVdbeFunc->apAux[iArg]; if( pAuxData->pAux && pAuxData->xDelete ){ pAuxData->xDelete(pAuxData->pAux); |
︙ | ︙ |
Changes to test/func.test.
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. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing built-in functions. # | | | 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. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing built-in functions. # # $Id: func.test,v 1.24 2004/06/19 17:33:08 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Create a table to work with. # do_test func-0.0 { |
︙ | ︙ | |||
432 433 434 435 436 437 438 | lappend res [sqlite3_column_text $STMT 0] } lappend res [sqlite3_finalize $STMT] } {{0 0} {1 0} SQLITE_OK} finish_test | < < < | 432 433 434 435 436 437 438 | lappend res [sqlite3_column_text $STMT 0] } lappend res [sqlite3_finalize $STMT] } {{0 0} {1 0} SQLITE_OK} finish_test |