summaryrefslogtreecommitdiff
path: root/src/build.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/build.c')
-rw-r--r--src/build.c129
1 files changed, 63 insertions, 66 deletions
diff --git a/src/build.c b/src/build.c
index 25e4740..3c91cdc 100644
--- a/src/build.c
+++ b/src/build.c
@@ -127,6 +127,7 @@ void sqlite3FinishCoding(Parse *pParse){
sqlite3 *db;
Vdbe *v;
+ assert( pParse->pToplevel==0 );
db = pParse->db;
if( db->mallocFailed ) return;
if( pParse->nested ) return;
@@ -320,6 +321,31 @@ Table *sqlite3LocateTable(
}
/*
+** Locate the table identified by *p.
+**
+** This is a wrapper around sqlite3LocateTable(). The difference between
+** sqlite3LocateTable() and this function is that this function restricts
+** the search to schema (p->pSchema) if it is not NULL. p->pSchema may be
+** non-NULL if it is part of a view or trigger program definition. See
+** sqlite3FixSrcList() for details.
+*/
+Table *sqlite3LocateTableItem(
+ Parse *pParse,
+ int isView,
+ struct SrcList_item *p
+){
+ const char *zDb;
+ assert( p->pSchema==0 || p->zDatabase==0 );
+ if( p->pSchema ){
+ int iDb = sqlite3SchemaToIndex(pParse->db, p->pSchema);
+ zDb = pParse->db->aDb[iDb].zName;
+ }else{
+ zDb = p->zDatabase;
+ }
+ return sqlite3LocateTable(pParse, isView, p->zName, zDb);
+}
+
+/*
** Locate the in-memory structure that describes
** a particular index given the name of that index
** and the name of the database that contains the index.
@@ -1169,7 +1195,7 @@ void sqlite3AddPrimaryKey(
pTab->tabFlags |= TF_HasPrimaryKey;
if( pList==0 ){
iCol = pTab->nCol - 1;
- pTab->aCol[iCol].isPrimKey = 1;
+ pTab->aCol[iCol].colFlags |= COLFLAG_PRIMKEY;
}else{
for(i=0; i<pList->nExpr; i++){
for(iCol=0; iCol<pTab->nCol; iCol++){
@@ -1178,7 +1204,7 @@ void sqlite3AddPrimaryKey(
}
}
if( iCol<pTab->nCol ){
- pTab->aCol[iCol].isPrimKey = 1;
+ pTab->aCol[iCol].colFlags |= COLFLAG_PRIMKEY;
}
}
if( pList->nExpr>1 ) iCol = -1;
@@ -1295,10 +1321,7 @@ CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName){
pColl = sqlite3FindCollSeq(db, enc, zName, initbusy);
if( !initbusy && (!pColl || !pColl->xCmp) ){
- pColl = sqlite3GetCollSeq(db, enc, pColl, zName);
- if( !pColl ){
- sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
- }
+ pColl = sqlite3GetCollSeq(pParse, enc, pColl, zName);
}
return pColl;
@@ -1997,6 +2020,7 @@ static void destroyTable(Parse *pParse, Table *pTab){
return;
}else{
int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
+ assert( iDb>=0 && iDb<pParse->db->nDb );
destroyRootPage(pParse, iLargest, iDb);
iDestroyed = iLargest;
}
@@ -2076,7 +2100,7 @@ void sqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, int isView){
/* Drop all SQLITE_MASTER table and index entries that refer to the
** table. The program name loops through the master table and deletes
** every row that refers to a table of the same name as the one being
- ** dropped. Triggers are handled seperately because a trigger can be
+ ** dropped. Triggers are handled separately because a trigger can be
** created in the temp database that refers to a table in another
** database.
*/
@@ -2114,8 +2138,7 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
assert( pParse->nErr==0 );
assert( pName->nSrc==1 );
if( noErr ) db->suppressErr++;
- pTab = sqlite3LocateTable(pParse, isView,
- pName->a[0].zName, pName->a[0].zDatabase);
+ pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]);
if( noErr ) db->suppressErr--;
if( pTab==0 ){
@@ -2369,9 +2392,6 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
int tnum; /* Root page of index */
Vdbe *v; /* Generate code into this virtual machine */
KeyInfo *pKey; /* KeyInfo for index */
-#ifdef SQLITE_OMIT_MERGE_SORT
- int regIdxKey; /* Registers containing the index key */
-#endif
int regRecord; /* Register holding assemblied index record */
sqlite3 *db = pParse->db; /* The database connection */
int iDb = sqlite3SchemaToIndex(db, pIndex->pSchema);
@@ -2399,13 +2419,9 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
(char *)pKey, P4_KEYINFO_HANDOFF);
sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0));
-#ifndef SQLITE_OMIT_MERGE_SORT
/* Open the sorter cursor if we are to use one. */
iSorter = pParse->nTab++;
sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, 0, (char*)pKey, P4_KEYINFO);
-#else
- iSorter = iTab;
-#endif
/* Open the table. Loop through all rows of the table, inserting index
** records into the sorter. */
@@ -2413,7 +2429,6 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0);
regRecord = sqlite3GetTempReg(pParse);
-#ifndef SQLITE_OMIT_MERGE_SORT
sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1);
sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord);
sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1);
@@ -2424,8 +2439,8 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
sqlite3VdbeAddOp2(v, OP_Goto, 0, j2);
addr2 = sqlite3VdbeCurrentAddr(v);
sqlite3VdbeAddOp3(v, OP_SorterCompare, iSorter, j2, regRecord);
- sqlite3HaltConstraint(
- pParse, OE_Abort, "indexed columns are not unique", P4_STATIC
+ sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_UNIQUE,
+ OE_Abort, "indexed columns are not unique", P4_STATIC
);
}else{
addr2 = sqlite3VdbeCurrentAddr(v);
@@ -2433,30 +2448,6 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
sqlite3VdbeAddOp2(v, OP_SorterData, iSorter, regRecord);
sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 1);
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
-#else
- regIdxKey = sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1);
- addr2 = addr1 + 1;
- if( pIndex->onError!=OE_None ){
- const int regRowid = regIdxKey + pIndex->nColumn;
- const int j2 = sqlite3VdbeCurrentAddr(v) + 2;
- void * const pRegKey = SQLITE_INT_TO_PTR(regIdxKey);
-
- /* The registers accessed by the OP_IsUnique opcode were allocated
- ** using sqlite3GetTempRange() inside of the sqlite3GenerateIndexKey()
- ** call above. Just before that function was freed they were released
- ** (made available to the compiler for reuse) using
- ** sqlite3ReleaseTempRange(). So in some ways having the OP_IsUnique
- ** opcode use the values stored within seems dangerous. However, since
- ** we can be sure that no other temp registers have been allocated
- ** since sqlite3ReleaseTempRange() was called, it is safe to do so.
- */
- sqlite3VdbeAddOp4(v, OP_IsUnique, iIdx, j2, regRowid, pRegKey, P4_INT32);
- sqlite3HaltConstraint(
- pParse, OE_Abort, "indexed columns are not unique", P4_STATIC);
- }
- sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 0);
- sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
-#endif
sqlite3ReleaseTempReg(pParse, regRecord);
sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2);
sqlite3VdbeJumpHere(v, addr1);
@@ -2555,9 +2546,9 @@ Index *sqlite3CreateIndex(
** sqlite3FixSrcList can never fail. */
assert(0);
}
- pTab = sqlite3LocateTable(pParse, 0, pTblName->a[0].zName,
- pTblName->a[0].zDatabase);
- if( !pTab || db->mallocFailed ) goto exit_create_index;
+ pTab = sqlite3LocateTableItem(pParse, 0, &pTblName->a[0]);
+ assert( db->mallocFailed==0 || pTab==0 );
+ if( pTab==0 ) goto exit_create_index;
assert( db->aDb[iDb].pSchema==pTab->pSchema );
}else{
assert( pName==0 );
@@ -2571,7 +2562,7 @@ Index *sqlite3CreateIndex(
assert( pTab!=0 );
assert( pParse->nErr==0 );
if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0
- && memcmp(&pTab->zName[7],"altertab_",9)!=0 ){
+ && sqlite3StrNICmp(&pTab->zName[7],"altertab_",9)!=0 ){
sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName);
goto exit_create_index;
}
@@ -2668,12 +2659,8 @@ Index *sqlite3CreateIndex(
for(i=0; i<pList->nExpr; i++){
Expr *pExpr = pList->a[i].pExpr;
if( pExpr ){
- CollSeq *pColl = pExpr->pColl;
- /* Either pColl!=0 or there was an OOM failure. But if an OOM
- ** failure we have quit before reaching this point. */
- if( ALWAYS(pColl) ){
- nExtra += (1 + sqlite3Strlen30(pColl->zName));
- }
+ assert( pExpr->op==TK_COLLATE );
+ nExtra += (1 + sqlite3Strlen30(pExpr->u.zToken));
}
}
@@ -2746,14 +2733,10 @@ Index *sqlite3CreateIndex(
goto exit_create_index;
}
pIndex->aiColumn[i] = j;
- /* Justification of the ALWAYS(pListItem->pExpr->pColl): Because of
- ** the way the "idxlist" non-terminal is constructed by the parser,
- ** if pListItem->pExpr is not null then either pListItem->pExpr->pColl
- ** must exist or else there must have been an OOM error. But if there
- ** was an OOM error, we would never reach this point. */
- if( pListItem->pExpr && ALWAYS(pListItem->pExpr->pColl) ){
+ if( pListItem->pExpr ){
int nColl;
- zColl = pListItem->pExpr->pColl->zName;
+ assert( pListItem->pExpr->op==TK_COLLATE );
+ zColl = pListItem->pExpr->u.zToken;
nColl = sqlite3Strlen30(zColl) + 1;
assert( nExtra>=nColl );
memcpy(zExtra, zColl, nColl);
@@ -2762,9 +2745,7 @@ Index *sqlite3CreateIndex(
nExtra -= nColl;
}else{
zColl = pTab->aCol[j].zColl;
- if( !zColl ){
- zColl = "BINARY";
- }
+ if( !zColl ) zColl = "BINARY";
}
if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl) ){
goto exit_create_index;
@@ -2820,7 +2801,7 @@ Index *sqlite3CreateIndex(
** However the ON CONFLICT clauses are different. If both this
** constraint and the previous equivalent constraint have explicit
** ON CONFLICT clauses this is an error. Otherwise, use the
- ** explicitly specified behaviour for the index.
+ ** explicitly specified behavior for the index.
*/
if( !(pIdx->onError==OE_Default || pIndex->onError==OE_Default) ){
sqlite3ErrorMsg(pParse,
@@ -3567,6 +3548,15 @@ int sqlite3OpenTempDatabase(Parse *pParse){
void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
Parse *pToplevel = sqlite3ParseToplevel(pParse);
+#ifndef SQLITE_OMIT_TRIGGER
+ if( pToplevel!=pParse ){
+ /* This branch is taken if a trigger is currently being coded. In this
+ ** case, set cookieGoto to a non-zero value to show that this function
+ ** has been called. This is used by the sqlite3ExprCodeConstants()
+ ** function. */
+ pParse->cookieGoto = -1;
+ }
+#endif
if( pToplevel->cookieGoto==0 ){
Vdbe *v = sqlite3GetVdbe(pToplevel);
if( v==0 ) return; /* This only happens if there was a prior error */
@@ -3664,12 +3654,19 @@ void sqlite3MayAbort(Parse *pParse){
** error. The onError parameter determines which (if any) of the statement
** and/or current transaction is rolled back.
*/
-void sqlite3HaltConstraint(Parse *pParse, int onError, char *p4, int p4type){
+void sqlite3HaltConstraint(
+ Parse *pParse, /* Parsing context */
+ int errCode, /* extended error code */
+ int onError, /* Constraint type */
+ char *p4, /* Error message */
+ int p4type /* P4_STATIC or P4_TRANSIENT */
+){
Vdbe *v = sqlite3GetVdbe(pParse);
+ assert( (errCode&0xff)==SQLITE_CONSTRAINT );
if( onError==OE_Abort ){
sqlite3MayAbort(pParse);
}
- sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, onError, 0, p4, p4type);
+ sqlite3VdbeAddOp4(v, OP_Halt, errCode, onError, 0, p4, p4type);
}
/*