OLD | NEW |
1 /* | 1 /* |
2 ** | 2 ** |
3 ** The author disclaims copyright to this source code. In place of | 3 ** The author disclaims copyright to this source code. In place of |
4 ** a legal notice, here is a blessing: | 4 ** a legal notice, here is a blessing: |
5 ** | 5 ** |
6 ** May you do good and not evil. | 6 ** May you do good and not evil. |
7 ** May you find forgiveness for yourself and forgive others. | 7 ** May you find forgiveness for yourself and forgive others. |
8 ** May you share freely, never taking more than you give. | 8 ** May you share freely, never taking more than you give. |
9 ** | 9 ** |
10 ************************************************************************* | 10 ************************************************************************* |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 ** mapped to the primary key of table pParent, or | 212 ** mapped to the primary key of table pParent, or |
213 ** 2) The FK is explicitly mapped to a column declared as INTEGER | 213 ** 2) The FK is explicitly mapped to a column declared as INTEGER |
214 ** PRIMARY KEY. | 214 ** PRIMARY KEY. |
215 */ | 215 */ |
216 if( pParent->iPKey>=0 ){ | 216 if( pParent->iPKey>=0 ){ |
217 if( !zKey ) return 0; | 217 if( !zKey ) return 0; |
218 if( !sqlite3StrICmp(pParent->aCol[pParent->iPKey].zName, zKey) ) return 0; | 218 if( !sqlite3StrICmp(pParent->aCol[pParent->iPKey].zName, zKey) ) return 0; |
219 } | 219 } |
220 }else if( paiCol ){ | 220 }else if( paiCol ){ |
221 assert( nCol>1 ); | 221 assert( nCol>1 ); |
222 aiCol = (int *)sqlite3DbMallocRaw(pParse->db, nCol*sizeof(int)); | 222 aiCol = (int *)sqlite3DbMallocRawNN(pParse->db, nCol*sizeof(int)); |
223 if( !aiCol ) return 1; | 223 if( !aiCol ) return 1; |
224 *paiCol = aiCol; | 224 *paiCol = aiCol; |
225 } | 225 } |
226 | 226 |
227 for(pIdx=pParent->pIndex; pIdx; pIdx=pIdx->pNext){ | 227 for(pIdx=pParent->pIndex; pIdx; pIdx=pIdx->pNext){ |
228 if( pIdx->nKeyCol==nCol && IsUniqueIndex(pIdx) ){ | 228 if( pIdx->nKeyCol==nCol && IsUniqueIndex(pIdx) && pIdx->pPartIdxWhere==0 ){ |
229 /* pIdx is a UNIQUE index (or a PRIMARY KEY) and has the right number | 229 /* pIdx is a UNIQUE index (or a PRIMARY KEY) and has the right number |
230 ** of columns. If each indexed column corresponds to a foreign key | 230 ** of columns. If each indexed column corresponds to a foreign key |
231 ** column of pFKey, then this index is a winner. */ | 231 ** column of pFKey, then this index is a winner. */ |
232 | 232 |
233 if( zKey==0 ){ | 233 if( zKey==0 ){ |
234 /* If zKey is NULL, then this foreign key is implicitly mapped to | 234 /* If zKey is NULL, then this foreign key is implicitly mapped to |
235 ** the PRIMARY KEY of table pParent. The PRIMARY KEY index may be | 235 ** the PRIMARY KEY of table pParent. The PRIMARY KEY index may be |
236 ** identified by the test. */ | 236 ** identified by the test. */ |
237 if( IsPrimaryKeyIndex(pIdx) ){ | 237 if( IsPrimaryKeyIndex(pIdx) ){ |
238 if( aiCol ){ | 238 if( aiCol ){ |
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
577 Expr *pEq; /* Expression (pLeft = pRight) */ | 577 Expr *pEq; /* Expression (pLeft = pRight) */ |
578 i16 iCol; /* Index of column in child table */ | 578 i16 iCol; /* Index of column in child table */ |
579 const char *zCol; /* Name of column in child table */ | 579 const char *zCol; /* Name of column in child table */ |
580 | 580 |
581 iCol = pIdx ? pIdx->aiColumn[i] : -1; | 581 iCol = pIdx ? pIdx->aiColumn[i] : -1; |
582 pLeft = exprTableRegister(pParse, pTab, regData, iCol); | 582 pLeft = exprTableRegister(pParse, pTab, regData, iCol); |
583 iCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom; | 583 iCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom; |
584 assert( iCol>=0 ); | 584 assert( iCol>=0 ); |
585 zCol = pFKey->pFrom->aCol[iCol].zName; | 585 zCol = pFKey->pFrom->aCol[iCol].zName; |
586 pRight = sqlite3Expr(db, TK_ID, zCol); | 586 pRight = sqlite3Expr(db, TK_ID, zCol); |
587 pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight, 0); | 587 pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight); |
588 pWhere = sqlite3ExprAnd(db, pWhere, pEq); | 588 pWhere = sqlite3ExprAnd(db, pWhere, pEq); |
589 } | 589 } |
590 | 590 |
591 /* If the child table is the same as the parent table, then add terms | 591 /* If the child table is the same as the parent table, then add terms |
592 ** to the WHERE clause that prevent this entry from being scanned. | 592 ** to the WHERE clause that prevent this entry from being scanned. |
593 ** The added WHERE clause terms are like this: | 593 ** The added WHERE clause terms are like this: |
594 ** | 594 ** |
595 ** $current_rowid!=rowid | 595 ** $current_rowid!=rowid |
596 ** NOT( $current_a==a AND $current_b==b AND ... ) | 596 ** NOT( $current_a==a AND $current_b==b AND ... ) |
597 ** | 597 ** |
598 ** The first form is used for rowid tables. The second form is used | 598 ** The first form is used for rowid tables. The second form is used |
599 ** for WITHOUT ROWID tables. In the second form, the primary key is | 599 ** for WITHOUT ROWID tables. In the second form, the primary key is |
600 ** (a,b,...) | 600 ** (a,b,...) |
601 */ | 601 */ |
602 if( pTab==pFKey->pFrom && nIncr>0 ){ | 602 if( pTab==pFKey->pFrom && nIncr>0 ){ |
603 Expr *pNe; /* Expression (pLeft != pRight) */ | 603 Expr *pNe; /* Expression (pLeft != pRight) */ |
604 Expr *pLeft; /* Value from parent table row */ | 604 Expr *pLeft; /* Value from parent table row */ |
605 Expr *pRight; /* Column ref to child table */ | 605 Expr *pRight; /* Column ref to child table */ |
606 if( HasRowid(pTab) ){ | 606 if( HasRowid(pTab) ){ |
607 pLeft = exprTableRegister(pParse, pTab, regData, -1); | 607 pLeft = exprTableRegister(pParse, pTab, regData, -1); |
608 pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, -1); | 608 pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, -1); |
609 pNe = sqlite3PExpr(pParse, TK_NE, pLeft, pRight, 0); | 609 pNe = sqlite3PExpr(pParse, TK_NE, pLeft, pRight); |
610 }else{ | 610 }else{ |
611 Expr *pEq, *pAll = 0; | 611 Expr *pEq, *pAll = 0; |
612 Index *pPk = sqlite3PrimaryKeyIndex(pTab); | 612 Index *pPk = sqlite3PrimaryKeyIndex(pTab); |
613 assert( pIdx!=0 ); | 613 assert( pIdx!=0 ); |
614 for(i=0; i<pPk->nKeyCol; i++){ | 614 for(i=0; i<pPk->nKeyCol; i++){ |
615 i16 iCol = pIdx->aiColumn[i]; | 615 i16 iCol = pIdx->aiColumn[i]; |
616 assert( iCol>=0 ); | 616 assert( iCol>=0 ); |
617 pLeft = exprTableRegister(pParse, pTab, regData, iCol); | 617 pLeft = exprTableRegister(pParse, pTab, regData, iCol); |
618 pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, iCol); | 618 pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, iCol); |
619 pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight, 0); | 619 pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight); |
620 pAll = sqlite3ExprAnd(db, pAll, pEq); | 620 pAll = sqlite3ExprAnd(db, pAll, pEq); |
621 } | 621 } |
622 pNe = sqlite3PExpr(pParse, TK_NOT, pAll, 0, 0); | 622 pNe = sqlite3PExpr(pParse, TK_NOT, pAll, 0); |
623 } | 623 } |
624 pWhere = sqlite3ExprAnd(db, pWhere, pNe); | 624 pWhere = sqlite3ExprAnd(db, pWhere, pNe); |
625 } | 625 } |
626 | 626 |
627 /* Resolve the references in the WHERE clause. */ | 627 /* Resolve the references in the WHERE clause. */ |
628 memset(&sNameContext, 0, sizeof(NameContext)); | 628 memset(&sNameContext, 0, sizeof(NameContext)); |
629 sNameContext.pSrcList = pSrc; | 629 sNameContext.pSrcList = pSrc; |
630 sNameContext.pParse = pParse; | 630 sNameContext.pParse = pParse; |
631 sqlite3ResolveExprNames(&sNameContext, pWhere); | 631 sqlite3ResolveExprNames(&sNameContext, pWhere); |
632 | 632 |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
864 const char *zDb; /* Name of database containing pTab */ | 864 const char *zDb; /* Name of database containing pTab */ |
865 int isIgnoreErrors = pParse->disableTriggers; | 865 int isIgnoreErrors = pParse->disableTriggers; |
866 | 866 |
867 /* Exactly one of regOld and regNew should be non-zero. */ | 867 /* Exactly one of regOld and regNew should be non-zero. */ |
868 assert( (regOld==0)!=(regNew==0) ); | 868 assert( (regOld==0)!=(regNew==0) ); |
869 | 869 |
870 /* If foreign-keys are disabled, this function is a no-op. */ | 870 /* If foreign-keys are disabled, this function is a no-op. */ |
871 if( (db->flags&SQLITE_ForeignKeys)==0 ) return; | 871 if( (db->flags&SQLITE_ForeignKeys)==0 ) return; |
872 | 872 |
873 iDb = sqlite3SchemaToIndex(db, pTab->pSchema); | 873 iDb = sqlite3SchemaToIndex(db, pTab->pSchema); |
874 zDb = db->aDb[iDb].zName; | 874 zDb = db->aDb[iDb].zDbSName; |
875 | 875 |
876 /* Loop through all the foreign key constraints for which pTab is the | 876 /* Loop through all the foreign key constraints for which pTab is the |
877 ** child table (the table that the foreign key definition is part of). */ | 877 ** child table (the table that the foreign key definition is part of). */ |
878 for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){ | 878 for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){ |
879 Table *pTo; /* Parent table of foreign key pFKey */ | 879 Table *pTo; /* Parent table of foreign key pFKey */ |
880 Index *pIdx = 0; /* Index on key columns in pTo */ | 880 Index *pIdx = 0; /* Index on key columns in pTo */ |
881 int *aiFree = 0; | 881 int *aiFree = 0; |
882 int *aiCol; | 882 int *aiCol; |
883 int iCol; | 883 int iCol; |
884 int i; | 884 int i; |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1000 } | 1000 } |
1001 assert( aiCol || pFKey->nCol==1 ); | 1001 assert( aiCol || pFKey->nCol==1 ); |
1002 | 1002 |
1003 /* Create a SrcList structure containing the child table. We need the | 1003 /* Create a SrcList structure containing the child table. We need the |
1004 ** child table as a SrcList for sqlite3WhereBegin() */ | 1004 ** child table as a SrcList for sqlite3WhereBegin() */ |
1005 pSrc = sqlite3SrcListAppend(db, 0, 0, 0); | 1005 pSrc = sqlite3SrcListAppend(db, 0, 0, 0); |
1006 if( pSrc ){ | 1006 if( pSrc ){ |
1007 struct SrcList_item *pItem = pSrc->a; | 1007 struct SrcList_item *pItem = pSrc->a; |
1008 pItem->pTab = pFKey->pFrom; | 1008 pItem->pTab = pFKey->pFrom; |
1009 pItem->zName = pFKey->pFrom->zName; | 1009 pItem->zName = pFKey->pFrom->zName; |
1010 pItem->pTab->nRef++; | 1010 pItem->pTab->nTabRef++; |
1011 pItem->iCursor = pParse->nTab++; | 1011 pItem->iCursor = pParse->nTab++; |
1012 | 1012 |
1013 if( regNew!=0 ){ | 1013 if( regNew!=0 ){ |
1014 fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regNew, -1); | 1014 fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regNew, -1); |
1015 } | 1015 } |
1016 if( regOld!=0 ){ | 1016 if( regOld!=0 ){ |
1017 int eAction = pFKey->aAction[aChange!=0]; | 1017 int eAction = pFKey->aAction[aChange!=0]; |
1018 fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regOld, 1); | 1018 fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regOld, 1); |
1019 /* If this is a deferred FK constraint, or a CASCADE or SET NULL | 1019 /* If this is a deferred FK constraint, or a CASCADE or SET NULL |
1020 ** action applies, then any foreign key violations caused by | 1020 ** action applies, then any foreign key violations caused by |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1155 Table *pTab, /* Table being updated or deleted from */ | 1155 Table *pTab, /* Table being updated or deleted from */ |
1156 FKey *pFKey, /* Foreign key to get action for */ | 1156 FKey *pFKey, /* Foreign key to get action for */ |
1157 ExprList *pChanges /* Change-list for UPDATE, NULL for DELETE */ | 1157 ExprList *pChanges /* Change-list for UPDATE, NULL for DELETE */ |
1158 ){ | 1158 ){ |
1159 sqlite3 *db = pParse->db; /* Database handle */ | 1159 sqlite3 *db = pParse->db; /* Database handle */ |
1160 int action; /* One of OE_None, OE_Cascade etc. */ | 1160 int action; /* One of OE_None, OE_Cascade etc. */ |
1161 Trigger *pTrigger; /* Trigger definition to return */ | 1161 Trigger *pTrigger; /* Trigger definition to return */ |
1162 int iAction = (pChanges!=0); /* 1 for UPDATE, 0 for DELETE */ | 1162 int iAction = (pChanges!=0); /* 1 for UPDATE, 0 for DELETE */ |
1163 | 1163 |
1164 action = pFKey->aAction[iAction]; | 1164 action = pFKey->aAction[iAction]; |
| 1165 if( action==OE_Restrict && (db->flags & SQLITE_DeferFKs) ){ |
| 1166 return 0; |
| 1167 } |
1165 pTrigger = pFKey->apTrigger[iAction]; | 1168 pTrigger = pFKey->apTrigger[iAction]; |
1166 | 1169 |
1167 if( action!=OE_None && !pTrigger ){ | 1170 if( action!=OE_None && !pTrigger ){ |
1168 u8 enableLookaside; /* Copy of db->lookaside.bEnabled */ | |
1169 char const *zFrom; /* Name of child table */ | 1171 char const *zFrom; /* Name of child table */ |
1170 int nFrom; /* Length in bytes of zFrom */ | 1172 int nFrom; /* Length in bytes of zFrom */ |
1171 Index *pIdx = 0; /* Parent key index for this FK */ | 1173 Index *pIdx = 0; /* Parent key index for this FK */ |
1172 int *aiCol = 0; /* child table cols -> parent key cols */ | 1174 int *aiCol = 0; /* child table cols -> parent key cols */ |
1173 TriggerStep *pStep = 0; /* First (only) step of trigger program */ | 1175 TriggerStep *pStep = 0; /* First (only) step of trigger program */ |
1174 Expr *pWhere = 0; /* WHERE clause of trigger step */ | 1176 Expr *pWhere = 0; /* WHERE clause of trigger step */ |
1175 ExprList *pList = 0; /* Changes list if ON UPDATE CASCADE */ | 1177 ExprList *pList = 0; /* Changes list if ON UPDATE CASCADE */ |
1176 Select *pSelect = 0; /* If RESTRICT, "SELECT RAISE(...)" */ | 1178 Select *pSelect = 0; /* If RESTRICT, "SELECT RAISE(...)" */ |
1177 int i; /* Iterator variable */ | 1179 int i; /* Iterator variable */ |
1178 Expr *pWhen = 0; /* WHEN clause for the trigger */ | 1180 Expr *pWhen = 0; /* WHEN clause for the trigger */ |
1179 | 1181 |
1180 if( sqlite3FkLocateIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ) return 0; | 1182 if( sqlite3FkLocateIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ) return 0; |
1181 assert( aiCol || pFKey->nCol==1 ); | 1183 assert( aiCol || pFKey->nCol==1 ); |
1182 | 1184 |
1183 for(i=0; i<pFKey->nCol; i++){ | 1185 for(i=0; i<pFKey->nCol; i++){ |
1184 Token tOld = { "old", 3 }; /* Literal "old" token */ | 1186 Token tOld = { "old", 3 }; /* Literal "old" token */ |
1185 Token tNew = { "new", 3 }; /* Literal "new" token */ | 1187 Token tNew = { "new", 3 }; /* Literal "new" token */ |
1186 Token tFromCol; /* Name of column in child table */ | 1188 Token tFromCol; /* Name of column in child table */ |
1187 Token tToCol; /* Name of column in parent table */ | 1189 Token tToCol; /* Name of column in parent table */ |
1188 int iFromCol; /* Idx of column in child table */ | 1190 int iFromCol; /* Idx of column in child table */ |
1189 Expr *pEq; /* tFromCol = OLD.tToCol */ | 1191 Expr *pEq; /* tFromCol = OLD.tToCol */ |
1190 | 1192 |
1191 iFromCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom; | 1193 iFromCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom; |
1192 assert( iFromCol>=0 ); | 1194 assert( iFromCol>=0 ); |
1193 assert( pIdx!=0 || (pTab->iPKey>=0 && pTab->iPKey<pTab->nCol) ); | 1195 assert( pIdx!=0 || (pTab->iPKey>=0 && pTab->iPKey<pTab->nCol) ); |
1194 assert( pIdx==0 || pIdx->aiColumn[i]>=0 ); | 1196 assert( pIdx==0 || pIdx->aiColumn[i]>=0 ); |
1195 tToCol.z = pTab->aCol[pIdx ? pIdx->aiColumn[i] : pTab->iPKey].zName; | 1197 sqlite3TokenInit(&tToCol, |
1196 tFromCol.z = pFKey->pFrom->aCol[iFromCol].zName; | 1198 pTab->aCol[pIdx ? pIdx->aiColumn[i] : pTab->iPKey].zName); |
1197 | 1199 sqlite3TokenInit(&tFromCol, pFKey->pFrom->aCol[iFromCol].zName); |
1198 tToCol.n = sqlite3Strlen30(tToCol.z); | |
1199 tFromCol.n = sqlite3Strlen30(tFromCol.z); | |
1200 | 1200 |
1201 /* Create the expression "OLD.zToCol = zFromCol". It is important | 1201 /* Create the expression "OLD.zToCol = zFromCol". It is important |
1202 ** that the "OLD.zToCol" term is on the LHS of the = operator, so | 1202 ** that the "OLD.zToCol" term is on the LHS of the = operator, so |
1203 ** that the affinity and collation sequence associated with the | 1203 ** that the affinity and collation sequence associated with the |
1204 ** parent table are used for the comparison. */ | 1204 ** parent table are used for the comparison. */ |
1205 pEq = sqlite3PExpr(pParse, TK_EQ, | 1205 pEq = sqlite3PExpr(pParse, TK_EQ, |
1206 sqlite3PExpr(pParse, TK_DOT, | 1206 sqlite3PExpr(pParse, TK_DOT, |
1207 sqlite3ExprAlloc(db, TK_ID, &tOld, 0), | 1207 sqlite3ExprAlloc(db, TK_ID, &tOld, 0), |
1208 sqlite3ExprAlloc(db, TK_ID, &tToCol, 0) | 1208 sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)), |
1209 , 0), | |
1210 sqlite3ExprAlloc(db, TK_ID, &tFromCol, 0) | 1209 sqlite3ExprAlloc(db, TK_ID, &tFromCol, 0) |
1211 , 0); | 1210 ); |
1212 pWhere = sqlite3ExprAnd(db, pWhere, pEq); | 1211 pWhere = sqlite3ExprAnd(db, pWhere, pEq); |
1213 | 1212 |
1214 /* For ON UPDATE, construct the next term of the WHEN clause. | 1213 /* For ON UPDATE, construct the next term of the WHEN clause. |
1215 ** The final WHEN clause will be like this: | 1214 ** The final WHEN clause will be like this: |
1216 ** | 1215 ** |
1217 ** WHEN NOT(old.col1 IS new.col1 AND ... AND old.colN IS new.colN) | 1216 ** WHEN NOT(old.col1 IS new.col1 AND ... AND old.colN IS new.colN) |
1218 */ | 1217 */ |
1219 if( pChanges ){ | 1218 if( pChanges ){ |
1220 pEq = sqlite3PExpr(pParse, TK_IS, | 1219 pEq = sqlite3PExpr(pParse, TK_IS, |
1221 sqlite3PExpr(pParse, TK_DOT, | 1220 sqlite3PExpr(pParse, TK_DOT, |
1222 sqlite3ExprAlloc(db, TK_ID, &tOld, 0), | 1221 sqlite3ExprAlloc(db, TK_ID, &tOld, 0), |
1223 sqlite3ExprAlloc(db, TK_ID, &tToCol, 0), | 1222 sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)), |
1224 0), | |
1225 sqlite3PExpr(pParse, TK_DOT, | 1223 sqlite3PExpr(pParse, TK_DOT, |
1226 sqlite3ExprAlloc(db, TK_ID, &tNew, 0), | 1224 sqlite3ExprAlloc(db, TK_ID, &tNew, 0), |
1227 sqlite3ExprAlloc(db, TK_ID, &tToCol, 0), | 1225 sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)) |
1228 0), | 1226 ); |
1229 0); | |
1230 pWhen = sqlite3ExprAnd(db, pWhen, pEq); | 1227 pWhen = sqlite3ExprAnd(db, pWhen, pEq); |
1231 } | 1228 } |
1232 | 1229 |
1233 if( action!=OE_Restrict && (action!=OE_Cascade || pChanges) ){ | 1230 if( action!=OE_Restrict && (action!=OE_Cascade || pChanges) ){ |
1234 Expr *pNew; | 1231 Expr *pNew; |
1235 if( action==OE_Cascade ){ | 1232 if( action==OE_Cascade ){ |
1236 pNew = sqlite3PExpr(pParse, TK_DOT, | 1233 pNew = sqlite3PExpr(pParse, TK_DOT, |
1237 sqlite3ExprAlloc(db, TK_ID, &tNew, 0), | 1234 sqlite3ExprAlloc(db, TK_ID, &tNew, 0), |
1238 sqlite3ExprAlloc(db, TK_ID, &tToCol, 0) | 1235 sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)); |
1239 , 0); | |
1240 }else if( action==OE_SetDflt ){ | 1236 }else if( action==OE_SetDflt ){ |
1241 Expr *pDflt = pFKey->pFrom->aCol[iFromCol].pDflt; | 1237 Expr *pDflt = pFKey->pFrom->aCol[iFromCol].pDflt; |
1242 if( pDflt ){ | 1238 if( pDflt ){ |
1243 pNew = sqlite3ExprDup(db, pDflt, 0); | 1239 pNew = sqlite3ExprDup(db, pDflt, 0); |
1244 }else{ | 1240 }else{ |
1245 pNew = sqlite3PExpr(pParse, TK_NULL, 0, 0, 0); | 1241 pNew = sqlite3ExprAlloc(db, TK_NULL, 0, 0); |
1246 } | 1242 } |
1247 }else{ | 1243 }else{ |
1248 pNew = sqlite3PExpr(pParse, TK_NULL, 0, 0, 0); | 1244 pNew = sqlite3ExprAlloc(db, TK_NULL, 0, 0); |
1249 } | 1245 } |
1250 pList = sqlite3ExprListAppend(pParse, pList, pNew); | 1246 pList = sqlite3ExprListAppend(pParse, pList, pNew); |
1251 sqlite3ExprListSetName(pParse, pList, &tFromCol, 0); | 1247 sqlite3ExprListSetName(pParse, pList, &tFromCol, 0); |
1252 } | 1248 } |
1253 } | 1249 } |
1254 sqlite3DbFree(db, aiCol); | 1250 sqlite3DbFree(db, aiCol); |
1255 | 1251 |
1256 zFrom = pFKey->pFrom->zName; | 1252 zFrom = pFKey->pFrom->zName; |
1257 nFrom = sqlite3Strlen30(zFrom); | 1253 nFrom = sqlite3Strlen30(zFrom); |
1258 | 1254 |
(...skipping 10 matching lines...) Expand all Loading... |
1269 pSelect = sqlite3SelectNew(pParse, | 1265 pSelect = sqlite3SelectNew(pParse, |
1270 sqlite3ExprListAppend(pParse, 0, pRaise), | 1266 sqlite3ExprListAppend(pParse, 0, pRaise), |
1271 sqlite3SrcListAppend(db, 0, &tFrom, 0), | 1267 sqlite3SrcListAppend(db, 0, &tFrom, 0), |
1272 pWhere, | 1268 pWhere, |
1273 0, 0, 0, 0, 0, 0 | 1269 0, 0, 0, 0, 0, 0 |
1274 ); | 1270 ); |
1275 pWhere = 0; | 1271 pWhere = 0; |
1276 } | 1272 } |
1277 | 1273 |
1278 /* Disable lookaside memory allocation */ | 1274 /* Disable lookaside memory allocation */ |
1279 enableLookaside = db->lookaside.bEnabled; | 1275 db->lookaside.bDisable++; |
1280 db->lookaside.bEnabled = 0; | |
1281 | 1276 |
1282 pTrigger = (Trigger *)sqlite3DbMallocZero(db, | 1277 pTrigger = (Trigger *)sqlite3DbMallocZero(db, |
1283 sizeof(Trigger) + /* struct Trigger */ | 1278 sizeof(Trigger) + /* struct Trigger */ |
1284 sizeof(TriggerStep) + /* Single step in trigger program */ | 1279 sizeof(TriggerStep) + /* Single step in trigger program */ |
1285 nFrom + 1 /* Space for pStep->zTarget */ | 1280 nFrom + 1 /* Space for pStep->zTarget */ |
1286 ); | 1281 ); |
1287 if( pTrigger ){ | 1282 if( pTrigger ){ |
1288 pStep = pTrigger->step_list = (TriggerStep *)&pTrigger[1]; | 1283 pStep = pTrigger->step_list = (TriggerStep *)&pTrigger[1]; |
1289 pStep->zTarget = (char *)&pStep[1]; | 1284 pStep->zTarget = (char *)&pStep[1]; |
1290 memcpy((char *)pStep->zTarget, zFrom, nFrom); | 1285 memcpy((char *)pStep->zTarget, zFrom, nFrom); |
1291 | 1286 |
1292 pStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); | 1287 pStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); |
1293 pStep->pExprList = sqlite3ExprListDup(db, pList, EXPRDUP_REDUCE); | 1288 pStep->pExprList = sqlite3ExprListDup(db, pList, EXPRDUP_REDUCE); |
1294 pStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); | 1289 pStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); |
1295 if( pWhen ){ | 1290 if( pWhen ){ |
1296 pWhen = sqlite3PExpr(pParse, TK_NOT, pWhen, 0, 0); | 1291 pWhen = sqlite3PExpr(pParse, TK_NOT, pWhen, 0); |
1297 pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE); | 1292 pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE); |
1298 } | 1293 } |
1299 } | 1294 } |
1300 | 1295 |
1301 /* Re-enable the lookaside buffer, if it was disabled earlier. */ | 1296 /* Re-enable the lookaside buffer, if it was disabled earlier. */ |
1302 db->lookaside.bEnabled = enableLookaside; | 1297 db->lookaside.bDisable--; |
1303 | 1298 |
1304 sqlite3ExprDelete(db, pWhere); | 1299 sqlite3ExprDelete(db, pWhere); |
1305 sqlite3ExprDelete(db, pWhen); | 1300 sqlite3ExprDelete(db, pWhen); |
1306 sqlite3ExprListDelete(db, pList); | 1301 sqlite3ExprListDelete(db, pList); |
1307 sqlite3SelectDelete(db, pSelect); | 1302 sqlite3SelectDelete(db, pSelect); |
1308 if( db->mallocFailed==1 ){ | 1303 if( db->mallocFailed==1 ){ |
1309 fkTriggerDelete(db, pTrigger); | 1304 fkTriggerDelete(db, pTrigger); |
1310 return 0; | 1305 return 0; |
1311 } | 1306 } |
1312 assert( pStep!=0 ); | 1307 assert( pStep!=0 ); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1366 | 1361 |
1367 /* | 1362 /* |
1368 ** Free all memory associated with foreign key definitions attached to | 1363 ** Free all memory associated with foreign key definitions attached to |
1369 ** table pTab. Remove the deleted foreign keys from the Schema.fkeyHash | 1364 ** table pTab. Remove the deleted foreign keys from the Schema.fkeyHash |
1370 ** hash table. | 1365 ** hash table. |
1371 */ | 1366 */ |
1372 void sqlite3FkDelete(sqlite3 *db, Table *pTab){ | 1367 void sqlite3FkDelete(sqlite3 *db, Table *pTab){ |
1373 FKey *pFKey; /* Iterator variable */ | 1368 FKey *pFKey; /* Iterator variable */ |
1374 FKey *pNext; /* Copy of pFKey->pNextFrom */ | 1369 FKey *pNext; /* Copy of pFKey->pNextFrom */ |
1375 | 1370 |
1376 assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pTab->pSchema) ); | 1371 assert( db==0 || IsVirtual(pTab) |
| 1372 || sqlite3SchemaMutexHeld(db, 0, pTab->pSchema) ); |
1377 for(pFKey=pTab->pFKey; pFKey; pFKey=pNext){ | 1373 for(pFKey=pTab->pFKey; pFKey; pFKey=pNext){ |
1378 | 1374 |
1379 /* Remove the FK from the fkeyHash hash table. */ | 1375 /* Remove the FK from the fkeyHash hash table. */ |
1380 if( !db || db->pnBytesFreed==0 ){ | 1376 if( !db || db->pnBytesFreed==0 ){ |
1381 if( pFKey->pPrevTo ){ | 1377 if( pFKey->pPrevTo ){ |
1382 pFKey->pPrevTo->pNextTo = pFKey->pNextTo; | 1378 pFKey->pPrevTo->pNextTo = pFKey->pNextTo; |
1383 }else{ | 1379 }else{ |
1384 void *p = (void *)pFKey->pNextTo; | 1380 void *p = (void *)pFKey->pNextTo; |
1385 const char *z = (p ? pFKey->pNextTo->zTo : pFKey->zTo); | 1381 const char *z = (p ? pFKey->pNextTo->zTo : pFKey->zTo); |
1386 sqlite3HashInsert(&pTab->pSchema->fkeyHash, z, p); | 1382 sqlite3HashInsert(&pTab->pSchema->fkeyHash, z, p); |
(...skipping 12 matching lines...) Expand all Loading... |
1399 #ifndef SQLITE_OMIT_TRIGGER | 1395 #ifndef SQLITE_OMIT_TRIGGER |
1400 fkTriggerDelete(db, pFKey->apTrigger[0]); | 1396 fkTriggerDelete(db, pFKey->apTrigger[0]); |
1401 fkTriggerDelete(db, pFKey->apTrigger[1]); | 1397 fkTriggerDelete(db, pFKey->apTrigger[1]); |
1402 #endif | 1398 #endif |
1403 | 1399 |
1404 pNext = pFKey->pNextFrom; | 1400 pNext = pFKey->pNextFrom; |
1405 sqlite3DbFree(db, pFKey); | 1401 sqlite3DbFree(db, pFKey); |
1406 } | 1402 } |
1407 } | 1403 } |
1408 #endif /* ifndef SQLITE_OMIT_FOREIGN_KEY */ | 1404 #endif /* ifndef SQLITE_OMIT_FOREIGN_KEY */ |
OLD | NEW |