Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Regression tests now work - except for some changes in error message text. The library is now safe to use for experimental work. (CVS 885) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
8a593e9c2d57e758739a7ef54fa40ca6 |
User & Date: | drh 2003-03-27 13:50:00.000 |
Context
2003-03-30
| ||
00:19 | Fix a memory leak in triggers and update tests to show the latest error message text. (CVS 886) (check-in: b90d9de32d user: drh tags: trunk) | |
2003-03-27
| ||
13:50 | Regression tests now work - except for some changes in error message text. The library is now safe to use for experimental work. (CVS 885) (check-in: 8a593e9c2d user: drh tags: trunk) | |
13:01 | Fix a segfault in the trigger code. (CVS 884) (check-in: 7672914b19 user: drh tags: trunk) | |
Changes
Changes to src/build.c.
︙ | ︙ | |||
21 22 23 24 25 26 27 | ** COPY ** VACUUM ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** PRAGMA ** | | | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | ** COPY ** VACUUM ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** PRAGMA ** ** $Id: build.c,v 1.135 2003/03/27 13:50:00 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 |
︙ | ︙ | |||
113 114 115 116 117 118 119 | ** a particular database table given the name ** of that table. Return NULL if not found. */ Table *sqliteFindTable(sqlite *db, const char *zName, const char *zDatabase){ Table *p = 0; int i; for(i=0; i<db->nDb; i++){ | > | | > | | | 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 | ** a particular database table given the name ** of that table. Return NULL if not found. */ Table *sqliteFindTable(sqlite *db, const char *zName, const char *zDatabase){ Table *p = 0; int i; for(i=0; i<db->nDb; i++){ int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ if( zDatabase!=0 && sqliteStrICmp(zDatabase, db->aDb[j].zName) ) continue; p = sqliteHashFind(&db->aDb[j].tblHash, zName, strlen(zName)+1); if( p ) break; } return p; } /* ** Locate the in-memory structure that describes ** a particular index given the name of that index. ** Return NULL if not found. */ Index *sqliteFindIndex(sqlite *db, const char *zName, const char *zDb){ Index *p = 0; int i; for(i=0; i<db->nDb; i++){ int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ if( zDb && sqliteStrICmp(zDb, db->aDb[j].zName) ) continue; p = sqliteHashFind(&db->aDb[j].idxHash, zName, strlen(zName)+1); if( p ) break; } return p; } /* ** Remove the given index from the index hash table, and free |
︙ | ︙ | |||
1440 1441 1442 1443 1444 1445 1446 | /* ** Find the table that is to be indexed. Return early if not found. */ if( pTable!=0 ){ assert( pName!=0 ); assert( pTable->nSrc==1 ); | | < | 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 | /* ** Find the table that is to be indexed. Return early if not found. */ if( pTable!=0 ){ assert( pName!=0 ); assert( pTable->nSrc==1 ); pTab = sqliteSrcListLookup(pParse, pTable); }else{ assert( pName==0 ); pTab = pParse->pNewTable; } if( pTab==0 || pParse->nErr ) goto exit_create_index; if( !isTemp && (pTab->readOnly || pTab->iDb>=2) ){ sqliteSetString(&pParse->zErrMsg, "table ", pTab->zName, |
︙ | ︙ | |||
1981 1982 1983 1984 1985 1986 1987 | Index *pIdx; char *zFile = 0; sqlite *db = pParse->db; if( sqlite_malloc_failed ) goto copy_cleanup; assert( pTableName->nSrc==1 ); | | < | | 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 | Index *pIdx; char *zFile = 0; sqlite *db = pParse->db; if( sqlite_malloc_failed ) goto copy_cleanup; assert( pTableName->nSrc==1 ); pTab = sqliteSrcListLookup(pParse, pTableName); if( pTab==0 || sqliteIsReadOnly(pParse, pTab) ) goto copy_cleanup; zFile = sqliteStrNDup(pFilename->z, pFilename->n); sqliteDequote(zFile); if( sqliteAuthCheck(pParse, SQLITE_INSERT, pTab->zName, zFile) || sqliteAuthCheck(pParse, SQLITE_COPY, pTab->zName, zFile) ){ goto copy_cleanup; } v = sqliteGetVdbe(pParse); |
︙ | ︙ |
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 ** to handle DELETE FROM statements. ** | | < < > | | | | > > > > | | | | | | | | > > > > | | > > > > > > > | < | | | 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 | ** 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 DELETE FROM statements. ** ** $Id: delete.c,v 1.49 2003/03/27 13:50:00 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. */ Table *sqliteSrcListLookup(Parse *pParse, SrcList *pSrc){ Table *pTab = 0; int i; for(i=0; i<pSrc->nSrc; i++){ const char *zTab = pSrc->a[i].zName; const char *zDb = pSrc->a[i].zDatabase; pTab = sqliteFindTable(pParse->db, zTab, zDb); if( pTab==0 ){ if( zDb==0 || zDb[0]==0 ){ sqliteSetString(&pParse->zErrMsg, "no such table: ", zTab, 0); }else{ sqliteSetString(&pParse->zErrMsg, "no such table: ", zDb, ".", zTab, 0); } pParse->nErr++; break; } pSrc->a[i].pTab = pTab; } return pTab; } /* ** Check to make sure the given table is writable. If it is not ** writable, generate an error message and return 1. If it is ** writable return 0; */ int sqliteIsReadOnly(Parse *pParse, Table *pTab){ if( pTab->readOnly || pTab->pSelect ){ sqliteSetString(&pParse->zErrMsg, pTab->pSelect ? "view " : "table ", pTab->zName, " may not be modified", 0); pParse->nErr++; return 1; } return 0; } /* ** Process a DELETE FROM statement. */ void sqliteDeleteFrom( Parse *pParse, /* The parser context */ SrcList *pTabList, /* The table from which we should delete things */ |
︙ | ︙ | |||
97 98 99 100 101 102 103 | } /* 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. */ | | | | 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | } /* 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. */ pTab = sqliteSrcListLookup(pParse, pTabList); if( pTab==0 || sqliteIsReadOnly(pParse, pTab) ){ goto delete_from_cleanup; } assert( pTab->pSelect==0 ); /* This table is not a view */ if( sqliteAuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0) ){ goto delete_from_cleanup; } |
︙ | ︙ |
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.76 2003/03/27 13:50:00 drh Exp $ */ #include "sqliteInt.h" /* ** This routine is call to handle SQL of the following forms: ** ** insert into TABLE (IDLIST) values(EXPRLIST) |
︙ | ︙ | |||
89 90 91 92 93 94 95 | ExprList *pList, /* List of values to be inserted */ Select *pSelect, /* A SELECT statement to use as the data source */ IdList *pColumn, /* Column names corresponding to IDLIST. */ int onError /* How to handle constraint errors */ ){ Table *pTab; /* The table to insert into */ char *zTab; /* Name of the table into which we are inserting */ | < | 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | ExprList *pList, /* List of values to be inserted */ Select *pSelect, /* A SELECT statement to use as the data source */ IdList *pColumn, /* Column names corresponding to IDLIST. */ int onError /* How to handle constraint errors */ ){ Table *pTab; /* The table to insert into */ char *zTab; /* Name of the table into which we are inserting */ int i, j, idx; /* Loop counters */ Vdbe *v; /* Generate code into this virtual machine */ Index *pIdx; /* For looping over indices of the table */ int nColumn; /* Number of columns in the data */ int base; /* First available cursor */ int iCont, iBreak; /* Beginning and end of the loop over srcTab */ sqlite *db; /* The main database structure */ |
︙ | ︙ | |||
117 118 119 120 121 122 123 | db = pParse->db; /* 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; | < | | 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | db = pParse->db; /* 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 = sqliteSrcListLookup(pParse, pTabList); if( pTab==0 ){ goto insert_cleanup; } if( sqliteAuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0) ){ goto insert_cleanup; } |
︙ | ︙ |
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.166 2003/03/27 13:50:00 drh Exp $ */ #include "config.h" #include "sqlite.h" #include "hash.h" #include "vdbe.h" #include "parse.h" #include "btree.h" |
︙ | ︙ | |||
249 250 251 252 253 254 255 256 257 258 259 260 261 262 | #endif #ifndef SQLITE_OMIT_AUTHORIZATION int (*xAuth)(void*,int,const char*,const char*); /* Access Auth function */ void *pAuthArg; /* 1st argument to the access auth function */ #endif }; /* ** Possible values for the sqlite.flags. */ #define SQLITE_VdbeTrace 0x00000001 /* True to trace VDBE execution */ #define SQLITE_Initialized 0x00000002 /* True after initialization */ #define SQLITE_Interrupt 0x00000004 /* Cancel current operation */ #define SQLITE_InTrans 0x00000008 /* True if in a transaction */ | > > > > > > > | 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 | #endif #ifndef SQLITE_OMIT_AUTHORIZATION int (*xAuth)(void*,int,const char*,const char*); /* Access Auth function */ void *pAuthArg; /* 1st argument to the access auth function */ #endif }; /* ** The following are the indices of in sqlite.aDb[] of the main database ** file and the file used to store TEMP tables. */ #define DB_TMP 0 #define DB_MAIN 1 /* ** Possible values for the sqlite.flags. */ #define SQLITE_VdbeTrace 0x00000001 /* True to trace VDBE execution */ #define SQLITE_Initialized 0x00000002 /* True after initialization */ #define SQLITE_Interrupt 0x00000004 /* Cancel current operation */ #define SQLITE_InTrans 0x00000008 /* True if in a transaction */ |
︙ | ︙ | |||
997 998 999 1000 1001 1002 1003 | void sqliteAddKeyType(Vdbe*, ExprList*); void sqliteAddIdxKeyType(Vdbe*, Index*); int sqliteSelect(Parse*, Select*, int, int, Select*, int, int*); Select *sqliteSelectNew(ExprList*,SrcList*,Expr*,ExprList*,Expr*,ExprList*, int,int,int); void sqliteSelectDelete(Select*); void sqliteSelectUnbind(Select*); | | > | 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 | void sqliteAddKeyType(Vdbe*, ExprList*); void sqliteAddIdxKeyType(Vdbe*, Index*); int sqliteSelect(Parse*, Select*, int, int, Select*, int, int*); Select *sqliteSelectNew(ExprList*,SrcList*,Expr*,ExprList*,Expr*,ExprList*, int,int,int); void sqliteSelectDelete(Select*); void sqliteSelectUnbind(Select*); Table *sqliteSrcListLookup(Parse*, SrcList*); int sqliteIsReadOnly(Parse*, Table*); void sqliteDeleteFrom(Parse*, SrcList*, Expr*); void sqliteUpdate(Parse*, SrcList*, ExprList*, Expr*, int); WhereInfo *sqliteWhereBegin(Parse*, int, SrcList*, Expr*, int, ExprList**); void sqliteWhereEnd(WhereInfo*); void sqliteExprCode(Parse*, Expr*); void sqliteExprIfTrue(Parse*, Expr*, int, int); void sqliteExprIfFalse(Parse*, Expr*, int, int); |
︙ | ︙ |
Changes to src/trigger.c.
︙ | ︙ | |||
57 58 59 60 61 62 63 | ** 2. the table (or view) does exist. ** 3. that we are not trying to create a trigger on the sqlite_master table ** 4. That we are not trying to create an INSTEAD OF trigger on a table. ** 5. That we are not trying to create a BEFORE or AFTER trigger on a view. */ if( sqlite_malloc_failed ) goto trigger_cleanup; assert( pTableName->nSrc==1 ); | | < | 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | ** 2. the table (or view) does exist. ** 3. that we are not trying to create a trigger on the sqlite_master table ** 4. That we are not trying to create an INSTEAD OF trigger on a table. ** 5. That we are not trying to create a BEFORE or AFTER trigger on a view. */ if( sqlite_malloc_failed ) goto trigger_cleanup; assert( pTableName->nSrc==1 ); tab = sqliteSrcListLookup(pParse, pTableName); if( !tab ){ goto trigger_cleanup; } if( tab->iDb>=2 ){ sqliteSetString(&pParse->zErrMsg, "triggers may not be added to " "auxiliary database \"", db->aDb[tab->iDb].zName, "\"", 0); pParse->nErr++; |
︙ | ︙ | |||
352 353 354 355 356 357 358 | if( sqlite_malloc_failed ) goto drop_trigger_cleanup; assert( pName->nSrc==1 ); zDb = pName->a[0].zDatabase; zName = pName->a[0].zName; nName = strlen(zName); for(i=0; i<db->nDb; i++){ | > | | | 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 | if( sqlite_malloc_failed ) goto drop_trigger_cleanup; assert( pName->nSrc==1 ); zDb = pName->a[0].zDatabase; zName = pName->a[0].zName; nName = strlen(zName); for(i=0; i<db->nDb; i++){ int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ if( zDb && sqliteStrICmp(db->aDb[j].zName, zDb) ) continue; pTrigger = sqliteHashFind(&(db->aDb[j].trigHash), zName, nName+1); if( pTrigger ) break; } if( !pTrigger ){ sqliteSetString(&pParse->zErrMsg, "no such trigger: ", zName, 0); goto drop_trigger_cleanup; } assert( pTrigger->iDb>=0 && pTrigger->iDb<db->nDb ); |
︙ | ︙ |
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.57 2003/03/27 13:50:00 drh Exp $ */ #include "sqliteInt.h" /* ** Process an UPDATE statement. */ void sqliteUpdate( |
︙ | ︙ | |||
80 81 82 83 84 85 86 | } /* Locate the table which we want to update. 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. */ | | | | 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | } /* Locate the table which we want to update. 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. */ pTab = sqliteSrcListLookup(pParse, pTabList); if( pTab==0 || sqliteIsReadOnly(pParse, pTab) ) goto update_cleanup; assert( pTab->pSelect==0 ); /* This table is not a VIEW */ aXRef = sqliteMalloc( 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 temp tables */ if( row_triggers_exist ){ |
︙ | ︙ |