Index: src/build.c ================================================================== --- src/build.c +++ src/build.c @@ -20,20 +20,18 @@ ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** -** $Id: build.c,v 1.289 2004/12/07 12:29:18 drh Exp $ +** $Id: build.c,v 1.290 2004/12/14 03:34:34 drh Exp $ */ #include "sqliteInt.h" #include /* ** This routine is called when a new SQL statement is beginning to -** be parsed. Check to see if the schema for the database needs -** to be read from the SQLITE_MASTER and SQLITE_TEMP_MASTER tables. -** If it does, then read it. +** be parsed. Initialize the pParse structure as needed. */ void sqlite3BeginParse(Parse *pParse, int explainFlag){ pParse->explain = explainFlag; pParse->nVar = 0; } @@ -83,11 +81,11 @@ /* Add a No-op that contains the complete text of the compiled SQL ** statement as its P3 argument. This does not change the functionality ** of the program. ** - ** This is used to implement sqlite3_trace() functionality. + ** This is used to implement sqlite3_trace(). */ sqlite3VdbeOp3(v, OP_Noop, 0, 0, pParse->zSql, pParse->zTail-pParse->zSql); } @@ -516,11 +514,11 @@ ** The token *pName contains the name of a database (either "main" or ** "temp" or the name of an attached db). This routine returns the ** index of the named database in db->aDb[], or -1 if the named db ** does not exist. */ -int findDb(sqlite3 *db, Token *pName){ +static int findDb(sqlite3 *db, Token *pName){ int i; /* 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 */ @@ -621,11 +619,11 @@ int isTemp, /* True if this is a TEMP table */ int isView /* True if this is a VIEW */ ){ Table *pTable; Index *pIdx; - char *zName; + char *zName = 0; /* The name of the new table */ sqlite3 *db = pParse->db; Vdbe *v; int iDb; /* Database number to create the table in */ Token *pName; /* Unqualified name of the table to create */ @@ -649,31 +647,28 @@ iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName); if( iDb<0 ) return; if( isTemp && iDb>1 ){ /* If creating a temp table, the name may not be qualified */ sqlite3ErrorMsg(pParse, "temporary table name must be unqualified"); - pParse->nErr++; return; } if( isTemp ) iDb = 1; pParse->sNameToken = *pName; zName = sqlite3NameFromToken(pName); if( zName==0 ) return; if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ - sqliteFree(zName); - return; + goto begin_table_error; } if( db->init.iDb==1 ) isTemp = 1; #ifndef SQLITE_OMIT_AUTHORIZATION assert( (isTemp & 1)==isTemp ); { int code; char *zDb = db->aDb[iDb].zName; if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0, zDb) ){ - sqliteFree(zName); - return; + goto begin_table_error; } if( isView ){ if( isTemp ){ code = SQLITE_CREATE_TEMP_VIEW; }else{ @@ -685,12 +680,11 @@ }else{ code = SQLITE_CREATE_TABLE; } } if( sqlite3AuthCheck(pParse, code, zName, 0, zDb) ){ - sqliteFree(zName); - return; + goto begin_table_error; } } #endif /* Make sure the new table name does not collide with an existing @@ -699,25 +693,22 @@ */ if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) return; pTable = sqlite3FindTable(db, zName, db->aDb[iDb].zName); if( pTable ){ sqlite3ErrorMsg(pParse, "table %T already exists", pName); - sqliteFree(zName); - return; + goto begin_table_error; } if( (pIdx = sqlite3FindIndex(db, zName, 0))!=0 && ( iDb==0 || !db->init.busy) ){ sqlite3ErrorMsg(pParse, "there is already an index named %s", zName); - sqliteFree(zName); - return; + goto begin_table_error; } pTable = sqliteMalloc( sizeof(Table) ); if( pTable==0 ){ pParse->rc = SQLITE_NOMEM; pParse->nErr++; - sqliteFree(zName); - return; + goto begin_table_error; } pTable->zName = zName; pTable->nCol = 0; pTable->aCol = 0; pTable->iPKey = -1; @@ -769,10 +760,18 @@ sqlite3VdbeAddOp(v, OP_Dup, 0, 0); sqlite3VdbeAddOp(v, OP_String8, 0, 0); sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0); sqlite3VdbeAddOp(v, OP_Close, 0, 0); } + + /* Normal (non-error) return. */ + return; + + /* If an error occurs, we jump here */ +begin_table_error: + sqliteFree(zName); + return; } /* ** Add a new column to the table currently being constructed. ** @@ -896,13 +895,11 @@ ** A table can have at most one primary key. If the table already has ** a primary key (and this is the second primary key) then create an ** error. ** ** If the PRIMARY KEY is on a single column whose datatype is INTEGER, -** then we will try to use that column as the row id. (Exception: -** For backwards compatibility with older databases, do not do this -** if the file format version number is less than 1.) Set the Table.iPKey +** then we will try to use that column as the rowid. Set the Table.iPKey ** field of the table under construction to be the index of the ** INTEGER PRIMARY KEY column. Table.iPKey is set to -1 if there is ** no INTEGER PRIMARY KEY. ** ** If the key is not an INTEGER PRIMARY KEY, then create a unique @@ -2073,12 +2070,12 @@ sqlite3VdbeAddOp(v, OP_Close, iTab, 0); sqlite3VdbeAddOp(v, OP_Close, iIdx, 0); } /* -** Create a new index for an SQL table. pIndex is the name of the index -** and pTable is the name of the table that is to be indexed. Both will +** Create a new index for an SQL table. pName1.pName2 is the name of the index +** and pTblList is the name of the table that is to be indexed. Both will ** be NULL for a primary key or an index that is created to satisfy a ** UNIQUE constraint. If pTable and pIndex are NULL, use pParse->pNewTable ** as the table to be indexed. pParse->pNewTable is a table that is ** currently being constructed by a CREATE TABLE statement. ** @@ -2085,20 +2082,20 @@ ** pList is a list of columns to be indexed. pList will be NULL if this ** is a primary key or unique-constraint on the most recent column added ** to the table currently under construction. */ void sqlite3CreateIndex( - Parse *pParse, /* All information about this parse */ - Token *pName1, /* First part of index name. May be NULL */ - Token *pName2, /* Second part of index name. May be NULL */ - SrcList *pTblName, /* Table to index. Use pParse->pNewTable if 0 */ + Parse *pParse, /* All information about this parse */ + Token *pName1, /* First part of index name. May be NULL */ + Token *pName2, /* Second part of index name. May be NULL */ + SrcList *pTblName, /* Table to index. Use pParse->pNewTable if 0 */ ExprList *pList, /* A list of columns to be indexed */ - int onError, /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ - Token *pStart, /* The CREATE token that begins a CREATE TABLE statement */ - Token *pEnd /* The ")" that closes the CREATE INDEX statement */ + int onError, /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ + Token *pStart, /* The CREATE token that begins a CREATE TABLE statement */ + Token *pEnd /* The ")" that closes the CREATE INDEX statement */ ){ - Table *pTab = 0; /* Table to be indexed */ + Table *pTab = 0; /* Table to be indexed */ Index *pIndex = 0; /* The index to be created */ char *zName = 0; int i, j; Token nullId; /* Fake token for an empty ID list */ DbFixer sFix; /* For assigning database names to pTable */ Index: src/delete.c ================================================================== --- src/delete.c +++ src/delete.c @@ -8,13 +8,13 @@ ** 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. +** in order to generate code for DELETE FROM statements. ** -** $Id: delete.c,v 1.92 2004/12/07 14:06:13 drh Exp $ +** $Id: delete.c,v 1.93 2004/12/14 03:34:34 drh Exp $ */ #include "sqliteInt.h" /* ** Look up every table that is named in pSrc. If any table is not found, @@ -64,11 +64,15 @@ sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, pTab->nCol); } /* -** Process a DELETE FROM statement. +** Generate code for a DELETE FROM statement. +** +** DELETE FROM table_wxyz WHERE a<5 AND b NOT NULL; +** \________/ \________________/ +** pTabList pWhere */ void sqlite3DeleteFrom( Parse *pParse, /* The parser context */ SrcList *pTabList, /* The table from which we should delete things */ Expr *pWhere /* The WHERE clause. May be null */ Index: src/where.c ================================================================== --- src/where.c +++ src/where.c @@ -10,11 +10,11 @@ ** ************************************************************************* ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. ** -** $Id: where.c,v 1.120 2004/11/23 01:47:31 drh Exp $ +** $Id: where.c,v 1.121 2004/12/14 03:34:34 drh Exp $ */ #include "sqliteInt.h" /* ** The query generator uses an array of instances of this structure to @@ -356,11 +356,11 @@ ** ** (1) SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x WHERE t2.z='ok' ** (2) SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x AND t2.z='ok' ** (3) SELECT * FROM t1, t2 WHERE t1.a=t2.x AND t2.z='ok' ** -** The t2.z='ok' is disabled in the in (2) because it did not originate +** The t2.z='ok' is disabled in the in (2) because it originates ** in the ON clause. The term is disabled in (3) because it is not part ** of a LEFT OUTER JOIN. In (1), the term is not disabled. ** ** Disabling a term causes that term to not be tested in the inner loop ** of the join. Disabling is an optimization. We would get the correct