Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(229)

Side by Side Diff: third_party/sqlite/sqlite-src-3100200/src/fkey.c

Issue 1610543003: [sql] Import reference version of SQLite 3.10.2. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 break; 242 break;
243 } 243 }
244 }else{ 244 }else{
245 /* If zKey is non-NULL, then this foreign key was declared to 245 /* If zKey is non-NULL, then this foreign key was declared to
246 ** map to an explicit list of columns in table pParent. Check if this 246 ** map to an explicit list of columns in table pParent. Check if this
247 ** index matches those columns. Also, check that the index uses 247 ** index matches those columns. Also, check that the index uses
248 ** the default collation sequences for each column. */ 248 ** the default collation sequences for each column. */
249 int i, j; 249 int i, j;
250 for(i=0; i<nCol; i++){ 250 for(i=0; i<nCol; i++){
251 i16 iCol = pIdx->aiColumn[i]; /* Index of column in parent tbl */ 251 i16 iCol = pIdx->aiColumn[i]; /* Index of column in parent tbl */
252 char *zDfltColl; /* Def. collation for column */ 252 const char *zDfltColl; /* Def. collation for column */
253 char *zIdxCol; /* Name of indexed column */ 253 char *zIdxCol; /* Name of indexed column */
254 254
255 if( iCol<0 ) break; /* No foreign keys against expression indexes */
256
255 /* If the index uses a collation sequence that is different from 257 /* If the index uses a collation sequence that is different from
256 ** the default collation sequence for the column, this index is 258 ** the default collation sequence for the column, this index is
257 ** unusable. Bail out early in this case. */ 259 ** unusable. Bail out early in this case. */
258 zDfltColl = pParent->aCol[iCol].zColl; 260 zDfltColl = pParent->aCol[iCol].zColl;
259 if( !zDfltColl ){ 261 if( !zDfltColl ) zDfltColl = sqlite3StrBINARY;
260 zDfltColl = "BINARY";
261 }
262 if( sqlite3StrICmp(pIdx->azColl[i], zDfltColl) ) break; 262 if( sqlite3StrICmp(pIdx->azColl[i], zDfltColl) ) break;
263 263
264 zIdxCol = pParent->aCol[iCol].zName; 264 zIdxCol = pParent->aCol[iCol].zName;
265 for(j=0; j<nCol; j++){ 265 for(j=0; j<nCol; j++){
266 if( sqlite3StrICmp(pFKey->aCol[j].zCol, zIdxCol)==0 ){ 266 if( sqlite3StrICmp(pFKey->aCol[j].zCol, zIdxCol)==0 ){
267 if( aiCol ) aiCol[i] = pFKey->aCol[j].iFrom; 267 if( aiCol ) aiCol[i] = pFKey->aCol[j].iFrom;
268 break; 268 break;
269 } 269 }
270 } 270 }
271 if( j==nCol ) break; 271 if( j==nCol ) break;
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 ** to increment the constraint-counter (i.e. this is an INSERT operation), 367 ** to increment the constraint-counter (i.e. this is an INSERT operation),
368 ** then check if the row being inserted matches itself. If so, do not 368 ** then check if the row being inserted matches itself. If so, do not
369 ** increment the constraint-counter. */ 369 ** increment the constraint-counter. */
370 if( pTab==pFKey->pFrom && nIncr==1 ){ 370 if( pTab==pFKey->pFrom && nIncr==1 ){
371 sqlite3VdbeAddOp3(v, OP_Eq, regData, iOk, regTemp); VdbeCoverage(v); 371 sqlite3VdbeAddOp3(v, OP_Eq, regData, iOk, regTemp); VdbeCoverage(v);
372 sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); 372 sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
373 } 373 }
374 374
375 sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead); 375 sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead);
376 sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regTemp); VdbeCoverage(v); 376 sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regTemp); VdbeCoverage(v);
377 sqlite3VdbeAddOp2(v, OP_Goto, 0, iOk); 377 sqlite3VdbeGoto(v, iOk);
378 sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2); 378 sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
379 sqlite3VdbeJumpHere(v, iMustBeInt); 379 sqlite3VdbeJumpHere(v, iMustBeInt);
380 sqlite3ReleaseTempReg(pParse, regTemp); 380 sqlite3ReleaseTempReg(pParse, regTemp);
381 }else{ 381 }else{
382 int nCol = pFKey->nCol; 382 int nCol = pFKey->nCol;
383 int regTemp = sqlite3GetTempRange(pParse, nCol); 383 int regTemp = sqlite3GetTempRange(pParse, nCol);
384 int regRec = sqlite3GetTempReg(pParse); 384 int regRec = sqlite3GetTempReg(pParse);
385 385
386 sqlite3VdbeAddOp3(v, OP_OpenRead, iCur, pIdx->tnum, iDb); 386 sqlite3VdbeAddOp3(v, OP_OpenRead, iCur, pIdx->tnum, iDb);
387 sqlite3VdbeSetP4KeyInfo(pParse, pIdx); 387 sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
388 for(i=0; i<nCol; i++){ 388 for(i=0; i<nCol; i++){
389 sqlite3VdbeAddOp2(v, OP_Copy, aiCol[i]+1+regData, regTemp+i); 389 sqlite3VdbeAddOp2(v, OP_Copy, aiCol[i]+1+regData, regTemp+i);
390 } 390 }
391 391
392 /* If the parent table is the same as the child table, and we are about 392 /* If the parent table is the same as the child table, and we are about
393 ** to increment the constraint-counter (i.e. this is an INSERT operation), 393 ** to increment the constraint-counter (i.e. this is an INSERT operation),
394 ** then check if the row being inserted matches itself. If so, do not 394 ** then check if the row being inserted matches itself. If so, do not
395 ** increment the constraint-counter. 395 ** increment the constraint-counter.
396 ** 396 **
397 ** If any of the parent-key values are NULL, then the row cannot match 397 ** If any of the parent-key values are NULL, then the row cannot match
398 ** itself. So set JUMPIFNULL to make sure we do the OP_Found if any 398 ** itself. So set JUMPIFNULL to make sure we do the OP_Found if any
399 ** of the parent-key values are NULL (at this point it is known that 399 ** of the parent-key values are NULL (at this point it is known that
400 ** none of the child key values are). 400 ** none of the child key values are).
401 */ 401 */
402 if( pTab==pFKey->pFrom && nIncr==1 ){ 402 if( pTab==pFKey->pFrom && nIncr==1 ){
403 int iJump = sqlite3VdbeCurrentAddr(v) + nCol + 1; 403 int iJump = sqlite3VdbeCurrentAddr(v) + nCol + 1;
404 for(i=0; i<nCol; i++){ 404 for(i=0; i<nCol; i++){
405 int iChild = aiCol[i]+1+regData; 405 int iChild = aiCol[i]+1+regData;
406 int iParent = pIdx->aiColumn[i]+1+regData; 406 int iParent = pIdx->aiColumn[i]+1+regData;
407 assert( pIdx->aiColumn[i]>=0 );
407 assert( aiCol[i]!=pTab->iPKey ); 408 assert( aiCol[i]!=pTab->iPKey );
408 if( pIdx->aiColumn[i]==pTab->iPKey ){ 409 if( pIdx->aiColumn[i]==pTab->iPKey ){
409 /* The parent key is a composite key that includes the IPK column */ 410 /* The parent key is a composite key that includes the IPK column */
410 iParent = regData; 411 iParent = regData;
411 } 412 }
412 sqlite3VdbeAddOp3(v, OP_Ne, iChild, iJump, iParent); VdbeCoverage(v); 413 sqlite3VdbeAddOp3(v, OP_Ne, iChild, iJump, iParent); VdbeCoverage(v);
413 sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL); 414 sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
414 } 415 }
415 sqlite3VdbeAddOp2(v, OP_Goto, 0, iOk); 416 sqlite3VdbeGoto(v, iOk);
416 } 417 }
417 418
418 sqlite3VdbeAddOp4(v, OP_MakeRecord, regTemp, nCol, regRec, 419 sqlite3VdbeAddOp4(v, OP_MakeRecord, regTemp, nCol, regRec,
419 sqlite3IndexAffinityStr(v,pIdx), nCol); 420 sqlite3IndexAffinityStr(pParse->db,pIdx), nCol);
420 sqlite3VdbeAddOp4Int(v, OP_Found, iCur, iOk, regRec, 0); VdbeCoverage(v); 421 sqlite3VdbeAddOp4Int(v, OP_Found, iCur, iOk, regRec, 0); VdbeCoverage(v);
421 422
422 sqlite3ReleaseTempReg(pParse, regRec); 423 sqlite3ReleaseTempReg(pParse, regRec);
423 sqlite3ReleaseTempRange(pParse, regTemp, nCol); 424 sqlite3ReleaseTempRange(pParse, regTemp, nCol);
424 } 425 }
425 } 426 }
426 427
427 if( !pFKey->isDeferred && !(pParse->db->flags & SQLITE_DeferFKs) 428 if( !pFKey->isDeferred && !(pParse->db->flags & SQLITE_DeferFKs)
428 && !pParse->pToplevel 429 && !pParse->pToplevel
429 && !pParse->isMultiWrite 430 && !pParse->isMultiWrite
430 ){ 431 ){
431 /* Special case: If this is an INSERT statement that will insert exactly 432 /* Special case: If this is an INSERT statement that will insert exactly
432 ** one row into the table, raise a constraint immediately instead of 433 ** one row into the table, raise a constraint immediately instead of
433 ** incrementing a counter. This is necessary as the VM code is being 434 ** incrementing a counter. This is necessary as the VM code is being
434 ** generated for will not open a statement transaction. */ 435 ** generated for will not open a statement transaction. */
435 assert( nIncr==1 ); 436 assert( nIncr==1 );
436 sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY, 437 sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY,
437 OE_Abort, 0, P4_STATIC, P5_ConstraintFK); 438 OE_Abort, 0, P4_STATIC, P5_ConstraintFK);
438 }else{ 439 }else{
439 if( nIncr>0 && pFKey->isDeferred==0 ){ 440 if( nIncr>0 && pFKey->isDeferred==0 ){
440 sqlite3ParseToplevel(pParse)->mayAbort = 1; 441 sqlite3MayAbort(pParse);
441 } 442 }
442 sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr); 443 sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
443 } 444 }
444 445
445 sqlite3VdbeResolveLabel(v, iOk); 446 sqlite3VdbeResolveLabel(v, iOk);
446 sqlite3VdbeAddOp1(v, OP_Close, iCur); 447 sqlite3VdbeAddOp1(v, OP_Close, iCur);
447 } 448 }
448 449
449 450
450 /* 451 /*
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 return pExpr; 503 return pExpr;
503 } 504 }
504 505
505 /* 506 /*
506 ** This function is called to generate code executed when a row is deleted 507 ** This function is called to generate code executed when a row is deleted
507 ** from the parent table of foreign key constraint pFKey and, if pFKey is 508 ** from the parent table of foreign key constraint pFKey and, if pFKey is
508 ** deferred, when a row is inserted into the same table. When generating 509 ** deferred, when a row is inserted into the same table. When generating
509 ** code for an SQL UPDATE operation, this function may be called twice - 510 ** code for an SQL UPDATE operation, this function may be called twice -
510 ** once to "delete" the old row and once to "insert" the new row. 511 ** once to "delete" the old row and once to "insert" the new row.
511 ** 512 **
513 ** Parameter nIncr is passed -1 when inserting a row (as this may decrease
514 ** the number of FK violations in the db) or +1 when deleting one (as this
515 ** may increase the number of FK constraint problems).
516 **
512 ** The code generated by this function scans through the rows in the child 517 ** The code generated by this function scans through the rows in the child
513 ** table that correspond to the parent table row being deleted or inserted. 518 ** table that correspond to the parent table row being deleted or inserted.
514 ** For each child row found, one of the following actions is taken: 519 ** For each child row found, one of the following actions is taken:
515 ** 520 **
516 ** Operation | FK type | Action taken 521 ** Operation | FK type | Action taken
517 ** -------------------------------------------------------------------------- 522 ** --------------------------------------------------------------------------
518 ** DELETE immediate Increment the "immediate constraint counter". 523 ** DELETE immediate Increment the "immediate constraint counter".
519 ** Or, if the ON (UPDATE|DELETE) action is RESTRICT, 524 ** Or, if the ON (UPDATE|DELETE) action is RESTRICT,
520 ** throw a "FOREIGN KEY constraint failed" exception. 525 ** throw a "FOREIGN KEY constraint failed" exception.
521 ** 526 **
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
601 if( HasRowid(pTab) ){ 606 if( HasRowid(pTab) ){
602 pLeft = exprTableRegister(pParse, pTab, regData, -1); 607 pLeft = exprTableRegister(pParse, pTab, regData, -1);
603 pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, -1); 608 pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, -1);
604 pNe = sqlite3PExpr(pParse, TK_NE, pLeft, pRight, 0); 609 pNe = sqlite3PExpr(pParse, TK_NE, pLeft, pRight, 0);
605 }else{ 610 }else{
606 Expr *pEq, *pAll = 0; 611 Expr *pEq, *pAll = 0;
607 Index *pPk = sqlite3PrimaryKeyIndex(pTab); 612 Index *pPk = sqlite3PrimaryKeyIndex(pTab);
608 assert( pIdx!=0 ); 613 assert( pIdx!=0 );
609 for(i=0; i<pPk->nKeyCol; i++){ 614 for(i=0; i<pPk->nKeyCol; i++){
610 i16 iCol = pIdx->aiColumn[i]; 615 i16 iCol = pIdx->aiColumn[i];
616 assert( iCol>=0 );
611 pLeft = exprTableRegister(pParse, pTab, regData, iCol); 617 pLeft = exprTableRegister(pParse, pTab, regData, iCol);
612 pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, iCol); 618 pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, iCol);
613 pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight, 0); 619 pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight, 0);
614 pAll = sqlite3ExprAnd(db, pAll, pEq); 620 pAll = sqlite3ExprAnd(db, pAll, pEq);
615 } 621 }
616 pNe = sqlite3PExpr(pParse, TK_NOT, pAll, 0, 0); 622 pNe = sqlite3PExpr(pParse, TK_NOT, pAll, 0, 0);
617 } 623 }
618 pWhere = sqlite3ExprAnd(db, pWhere, pNe); 624 pWhere = sqlite3ExprAnd(db, pWhere, pNe);
619 } 625 }
620 626
621 /* Resolve the references in the WHERE clause. */ 627 /* Resolve the references in the WHERE clause. */
622 memset(&sNameContext, 0, sizeof(NameContext)); 628 memset(&sNameContext, 0, sizeof(NameContext));
623 sNameContext.pSrcList = pSrc; 629 sNameContext.pSrcList = pSrc;
624 sNameContext.pParse = pParse; 630 sNameContext.pParse = pParse;
625 sqlite3ResolveExprNames(&sNameContext, pWhere); 631 sqlite3ResolveExprNames(&sNameContext, pWhere);
626 632
627 /* Create VDBE to loop through the entries in pSrc that match the WHERE 633 /* Create VDBE to loop through the entries in pSrc that match the WHERE
628 ** clause. If the constraint is not deferred, throw an exception for 634 ** clause. For each row found, increment either the deferred or immediate
629 ** each row found. Otherwise, for deferred constraints, increment the 635 ** foreign key constraint counter. */
630 ** deferred constraint counter by nIncr for each row selected. */
631 pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0, 0); 636 pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0, 0);
632 if( nIncr>0 && pFKey->isDeferred==0 ){
633 sqlite3ParseToplevel(pParse)->mayAbort = 1;
634 }
635 sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr); 637 sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
636 if( pWInfo ){ 638 if( pWInfo ){
637 sqlite3WhereEnd(pWInfo); 639 sqlite3WhereEnd(pWInfo);
638 } 640 }
639 641
640 /* Clean up the WHERE clause constructed above. */ 642 /* Clean up the WHERE clause constructed above. */
641 sqlite3ExprDelete(db, pWhere); 643 sqlite3ExprDelete(db, pWhere);
642 if( iFkIfZero ){ 644 if( iFkIfZero ){
643 sqlite3VdbeJumpHere(v, iFkIfZero); 645 sqlite3VdbeJumpHere(v, iFkIfZero);
644 } 646 }
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
804 }else if( pCol->colFlags & COLFLAG_PRIMKEY ){ 806 }else if( pCol->colFlags & COLFLAG_PRIMKEY ){
805 return 1; 807 return 1;
806 } 808 }
807 } 809 }
808 } 810 }
809 } 811 }
810 return 0; 812 return 0;
811 } 813 }
812 814
813 /* 815 /*
816 ** Return true if the parser passed as the first argument is being
817 ** used to code a trigger that is really a "SET NULL" action belonging
818 ** to trigger pFKey.
819 */
820 static int isSetNullAction(Parse *pParse, FKey *pFKey){
821 Parse *pTop = sqlite3ParseToplevel(pParse);
822 if( pTop->pTriggerPrg ){
823 Trigger *p = pTop->pTriggerPrg->pTrigger;
824 if( (p==pFKey->apTrigger[0] && pFKey->aAction[0]==OE_SetNull)
825 || (p==pFKey->apTrigger[1] && pFKey->aAction[1]==OE_SetNull)
826 ){
827 return 1;
828 }
829 }
830 return 0;
831 }
832
833 /*
814 ** This function is called when inserting, deleting or updating a row of 834 ** This function is called when inserting, deleting or updating a row of
815 ** table pTab to generate VDBE code to perform foreign key constraint 835 ** table pTab to generate VDBE code to perform foreign key constraint
816 ** processing for the operation. 836 ** processing for the operation.
817 ** 837 **
818 ** For a DELETE operation, parameter regOld is passed the index of the 838 ** For a DELETE operation, parameter regOld is passed the index of the
819 ** first register in an array of (pTab->nCol+1) registers containing the 839 ** first register in an array of (pTab->nCol+1) registers containing the
820 ** rowid of the row being deleted, followed by each of the column values 840 ** rowid of the row being deleted, followed by each of the column values
821 ** of the row being deleted, from left to right. Parameter regNew is passed 841 ** of the row being deleted, from left to right. Parameter regNew is passed
822 ** zero in this case. 842 ** zero in this case.
823 ** 843 **
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
855 875
856 /* 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
857 ** 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). */
858 for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){ 878 for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){
859 Table *pTo; /* Parent table of foreign key pFKey */ 879 Table *pTo; /* Parent table of foreign key pFKey */
860 Index *pIdx = 0; /* Index on key columns in pTo */ 880 Index *pIdx = 0; /* Index on key columns in pTo */
861 int *aiFree = 0; 881 int *aiFree = 0;
862 int *aiCol; 882 int *aiCol;
863 int iCol; 883 int iCol;
864 int i; 884 int i;
865 int isIgnore = 0; 885 int bIgnore = 0;
866 886
867 if( aChange 887 if( aChange
868 && sqlite3_stricmp(pTab->zName, pFKey->zTo)!=0 888 && sqlite3_stricmp(pTab->zName, pFKey->zTo)!=0
869 && fkChildIsModified(pTab, pFKey, aChange, bChngRowid)==0 889 && fkChildIsModified(pTab, pFKey, aChange, bChngRowid)==0
870 ){ 890 ){
871 continue; 891 continue;
872 } 892 }
873 893
874 /* Find the parent table of this foreign key. Also find a unique index 894 /* Find the parent table of this foreign key. Also find a unique index
875 ** on the parent key columns in the parent table. If either of these 895 ** on the parent key columns in the parent table. If either of these
(...skipping 30 matching lines...) Expand all
906 if( aiFree ){ 926 if( aiFree ){
907 aiCol = aiFree; 927 aiCol = aiFree;
908 }else{ 928 }else{
909 iCol = pFKey->aCol[0].iFrom; 929 iCol = pFKey->aCol[0].iFrom;
910 aiCol = &iCol; 930 aiCol = &iCol;
911 } 931 }
912 for(i=0; i<pFKey->nCol; i++){ 932 for(i=0; i<pFKey->nCol; i++){
913 if( aiCol[i]==pTab->iPKey ){ 933 if( aiCol[i]==pTab->iPKey ){
914 aiCol[i] = -1; 934 aiCol[i] = -1;
915 } 935 }
936 assert( pIdx==0 || pIdx->aiColumn[i]>=0 );
916 #ifndef SQLITE_OMIT_AUTHORIZATION 937 #ifndef SQLITE_OMIT_AUTHORIZATION
917 /* Request permission to read the parent key columns. If the 938 /* Request permission to read the parent key columns. If the
918 ** authorization callback returns SQLITE_IGNORE, behave as if any 939 ** authorization callback returns SQLITE_IGNORE, behave as if any
919 ** values read from the parent table are NULL. */ 940 ** values read from the parent table are NULL. */
920 if( db->xAuth ){ 941 if( db->xAuth ){
921 int rcauth; 942 int rcauth;
922 char *zCol = pTo->aCol[pIdx ? pIdx->aiColumn[i] : pTo->iPKey].zName; 943 char *zCol = pTo->aCol[pIdx ? pIdx->aiColumn[i] : pTo->iPKey].zName;
923 rcauth = sqlite3AuthReadCol(pParse, pTo->zName, zCol, iDb); 944 rcauth = sqlite3AuthReadCol(pParse, pTo->zName, zCol, iDb);
924 isIgnore = (rcauth==SQLITE_IGNORE); 945 bIgnore = (rcauth==SQLITE_IGNORE);
925 } 946 }
926 #endif 947 #endif
927 } 948 }
928 949
929 /* Take a shared-cache advisory read-lock on the parent table. Allocate 950 /* Take a shared-cache advisory read-lock on the parent table. Allocate
930 ** a cursor to use to search the unique index on the parent key columns 951 ** a cursor to use to search the unique index on the parent key columns
931 ** in the parent table. */ 952 ** in the parent table. */
932 sqlite3TableLock(pParse, iDb, pTo->tnum, 0, pTo->zName); 953 sqlite3TableLock(pParse, iDb, pTo->tnum, 0, pTo->zName);
933 pParse->nTab++; 954 pParse->nTab++;
934 955
935 if( regOld!=0 ){ 956 if( regOld!=0 ){
936 /* A row is being removed from the child table. Search for the parent. 957 /* A row is being removed from the child table. Search for the parent.
937 ** If the parent does not exist, removing the child row resolves an 958 ** If the parent does not exist, removing the child row resolves an
938 ** outstanding foreign key constraint violation. */ 959 ** outstanding foreign key constraint violation. */
939 fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regOld, -1,isIgnore); 960 fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regOld, -1, bIgnore);
940 } 961 }
941 if( regNew!=0 ){ 962 if( regNew!=0 && !isSetNullAction(pParse, pFKey) ){
942 /* A row is being added to the child table. If a parent row cannot 963 /* A row is being added to the child table. If a parent row cannot
943 ** be found, adding the child row has violated the FK constraint. */ 964 ** be found, adding the child row has violated the FK constraint.
944 fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regNew, +1,isIgnore); 965 **
966 ** If this operation is being performed as part of a trigger program
967 ** that is actually a "SET NULL" action belonging to this very
968 ** foreign key, then omit this scan altogether. As all child key
969 ** values are guaranteed to be NULL, it is not possible for adding
970 ** this row to cause an FK violation. */
971 fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regNew, +1, bIgnore);
945 } 972 }
946 973
947 sqlite3DbFree(db, aiFree); 974 sqlite3DbFree(db, aiFree);
948 } 975 }
949 976
950 /* Loop through all the foreign key constraints that refer to this table. 977 /* Loop through all the foreign key constraints that refer to this table.
951 ** (the "child" constraints) */ 978 ** (the "child" constraints) */
952 for(pFKey = sqlite3FkReferences(pTab); pFKey; pFKey=pFKey->pNextTo){ 979 for(pFKey = sqlite3FkReferences(pTab); pFKey; pFKey=pFKey->pNextTo){
953 Index *pIdx = 0; /* Foreign key index for pFKey */ 980 Index *pIdx = 0; /* Foreign key index for pFKey */
954 SrcList *pSrc; 981 SrcList *pSrc;
955 int *aiCol = 0; 982 int *aiCol = 0;
956 983
957 if( aChange && fkParentIsModified(pTab, pFKey, aChange, bChngRowid)==0 ){ 984 if( aChange && fkParentIsModified(pTab, pFKey, aChange, bChngRowid)==0 ){
958 continue; 985 continue;
959 } 986 }
960 987
961 if( !pFKey->isDeferred && !(db->flags & SQLITE_DeferFKs) 988 if( !pFKey->isDeferred && !(db->flags & SQLITE_DeferFKs)
962 && !pParse->pToplevel && !pParse->isMultiWrite 989 && !pParse->pToplevel && !pParse->isMultiWrite
963 ){ 990 ){
964 assert( regOld==0 && regNew!=0 ); 991 assert( regOld==0 && regNew!=0 );
965 /* Inserting a single row into a parent table cannot cause an immediate 992 /* Inserting a single row into a parent table cannot cause (or fix)
966 ** foreign key violation. So do nothing in this case. */ 993 ** an immediate foreign key violation. So do nothing in this case. */
967 continue; 994 continue;
968 } 995 }
969 996
970 if( sqlite3FkLocateIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ){ 997 if( sqlite3FkLocateIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ){
971 if( !isIgnoreErrors || db->mallocFailed ) return; 998 if( !isIgnoreErrors || db->mallocFailed ) return;
972 continue; 999 continue;
973 } 1000 }
974 assert( aiCol || pFKey->nCol==1 ); 1001 assert( aiCol || pFKey->nCol==1 );
975 1002
976 /* Create a SrcList structure containing the child table. We need the 1003 /* Create a SrcList structure containing the child table. We need the
977 ** child table as a SrcList for sqlite3WhereBegin() */ 1004 ** child table as a SrcList for sqlite3WhereBegin() */
978 pSrc = sqlite3SrcListAppend(db, 0, 0, 0); 1005 pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
979 if( pSrc ){ 1006 if( pSrc ){
980 struct SrcList_item *pItem = pSrc->a; 1007 struct SrcList_item *pItem = pSrc->a;
981 pItem->pTab = pFKey->pFrom; 1008 pItem->pTab = pFKey->pFrom;
982 pItem->zName = pFKey->pFrom->zName; 1009 pItem->zName = pFKey->pFrom->zName;
983 pItem->pTab->nRef++; 1010 pItem->pTab->nRef++;
984 pItem->iCursor = pParse->nTab++; 1011 pItem->iCursor = pParse->nTab++;
985 1012
986 if( regNew!=0 ){ 1013 if( regNew!=0 ){
987 fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regNew, -1); 1014 fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regNew, -1);
988 } 1015 }
989 if( regOld!=0 ){ 1016 if( regOld!=0 ){
990 /* If there is a RESTRICT action configured for the current operation 1017 int eAction = pFKey->aAction[aChange!=0];
991 ** on the parent table of this FK, then throw an exception
992 ** immediately if the FK constraint is violated, even if this is a
993 ** deferred trigger. That's what RESTRICT means. To defer checking
994 ** the constraint, the FK should specify NO ACTION (represented
995 ** using OE_None). NO ACTION is the default. */
996 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
1020 ** action applies, then any foreign key violations caused by
1021 ** removing the parent key will be rectified by the action trigger.
1022 ** So do not set the "may-abort" flag in this case.
1023 **
1024 ** Note 1: If the FK is declared "ON UPDATE CASCADE", then the
1025 ** may-abort flag will eventually be set on this statement anyway
1026 ** (when this function is called as part of processing the UPDATE
1027 ** within the action trigger).
1028 **
1029 ** Note 2: At first glance it may seem like SQLite could simply omit
1030 ** all OP_FkCounter related scans when either CASCADE or SET NULL
1031 ** applies. The trouble starts if the CASCADE or SET NULL action
1032 ** trigger causes other triggers or action rules attached to the
1033 ** child table to fire. In these cases the fk constraint counters
1034 ** might be set incorrectly if any OP_FkCounter related scans are
1035 ** omitted. */
1036 if( !pFKey->isDeferred && eAction!=OE_Cascade && eAction!=OE_SetNull ){
1037 sqlite3MayAbort(pParse);
1038 }
997 } 1039 }
998 pItem->zName = 0; 1040 pItem->zName = 0;
999 sqlite3SrcListDelete(db, pSrc); 1041 sqlite3SrcListDelete(db, pSrc);
1000 } 1042 }
1001 sqlite3DbFree(db, aiCol); 1043 sqlite3DbFree(db, aiCol);
1002 } 1044 }
1003 } 1045 }
1004 1046
1005 #define COLUMN_MASK(x) (((x)>31) ? 0xffffffff : ((u32)1<<(x))) 1047 #define COLUMN_MASK(x) (((x)>31) ? 0xffffffff : ((u32)1<<(x)))
1006 1048
1007 /* 1049 /*
1008 ** This function is called before generating code to update or delete a 1050 ** This function is called before generating code to update or delete a
1009 ** row contained in table pTab. 1051 ** row contained in table pTab.
1010 */ 1052 */
1011 u32 sqlite3FkOldmask( 1053 u32 sqlite3FkOldmask(
1012 Parse *pParse, /* Parse context */ 1054 Parse *pParse, /* Parse context */
1013 Table *pTab /* Table being modified */ 1055 Table *pTab /* Table being modified */
1014 ){ 1056 ){
1015 u32 mask = 0; 1057 u32 mask = 0;
1016 if( pParse->db->flags&SQLITE_ForeignKeys ){ 1058 if( pParse->db->flags&SQLITE_ForeignKeys ){
1017 FKey *p; 1059 FKey *p;
1018 int i; 1060 int i;
1019 for(p=pTab->pFKey; p; p=p->pNextFrom){ 1061 for(p=pTab->pFKey; p; p=p->pNextFrom){
1020 for(i=0; i<p->nCol; i++) mask |= COLUMN_MASK(p->aCol[i].iFrom); 1062 for(i=0; i<p->nCol; i++) mask |= COLUMN_MASK(p->aCol[i].iFrom);
1021 } 1063 }
1022 for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){ 1064 for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){
1023 Index *pIdx = 0; 1065 Index *pIdx = 0;
1024 sqlite3FkLocateIndex(pParse, pTab, p, &pIdx, 0); 1066 sqlite3FkLocateIndex(pParse, pTab, p, &pIdx, 0);
1025 if( pIdx ){ 1067 if( pIdx ){
1026 for(i=0; i<pIdx->nKeyCol; i++) mask |= COLUMN_MASK(pIdx->aiColumn[i]); 1068 for(i=0; i<pIdx->nKeyCol; i++){
1069 assert( pIdx->aiColumn[i]>=0 );
1070 mask |= COLUMN_MASK(pIdx->aiColumn[i]);
1071 }
1027 } 1072 }
1028 } 1073 }
1029 } 1074 }
1030 return mask; 1075 return mask;
1031 } 1076 }
1032 1077
1033 1078
1034 /* 1079 /*
1035 ** This function is called before generating code to update or delete a 1080 ** This function is called before generating code to update or delete a
1036 ** row contained in table pTab. If the operation is a DELETE, then 1081 ** row contained in table pTab. If the operation is a DELETE, then
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
1138 for(i=0; i<pFKey->nCol; i++){ 1183 for(i=0; i<pFKey->nCol; i++){
1139 Token tOld = { "old", 3 }; /* Literal "old" token */ 1184 Token tOld = { "old", 3 }; /* Literal "old" token */
1140 Token tNew = { "new", 3 }; /* Literal "new" token */ 1185 Token tNew = { "new", 3 }; /* Literal "new" token */
1141 Token tFromCol; /* Name of column in child table */ 1186 Token tFromCol; /* Name of column in child table */
1142 Token tToCol; /* Name of column in parent table */ 1187 Token tToCol; /* Name of column in parent table */
1143 int iFromCol; /* Idx of column in child table */ 1188 int iFromCol; /* Idx of column in child table */
1144 Expr *pEq; /* tFromCol = OLD.tToCol */ 1189 Expr *pEq; /* tFromCol = OLD.tToCol */
1145 1190
1146 iFromCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom; 1191 iFromCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom;
1147 assert( iFromCol>=0 ); 1192 assert( iFromCol>=0 );
1148 tToCol.z = pIdx ? pTab->aCol[pIdx->aiColumn[i]].zName : "oid"; 1193 assert( pIdx!=0 || (pTab->iPKey>=0 && pTab->iPKey<pTab->nCol) );
1194 assert( pIdx==0 || pIdx->aiColumn[i]>=0 );
1195 tToCol.z = pTab->aCol[pIdx ? pIdx->aiColumn[i] : pTab->iPKey].zName;
1149 tFromCol.z = pFKey->pFrom->aCol[iFromCol].zName; 1196 tFromCol.z = pFKey->pFrom->aCol[iFromCol].zName;
1150 1197
1151 tToCol.n = sqlite3Strlen30(tToCol.z); 1198 tToCol.n = sqlite3Strlen30(tToCol.z);
1152 tFromCol.n = sqlite3Strlen30(tFromCol.z); 1199 tFromCol.n = sqlite3Strlen30(tFromCol.z);
1153 1200
1154 /* Create the expression "OLD.zToCol = zFromCol". It is important 1201 /* Create the expression "OLD.zToCol = zFromCol". It is important
1155 ** 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
1156 ** that the affinity and collation sequence associated with the 1203 ** that the affinity and collation sequence associated with the
1157 ** parent table are used for the comparison. */ 1204 ** parent table are used for the comparison. */
1158 pEq = sqlite3PExpr(pParse, TK_EQ, 1205 pEq = sqlite3PExpr(pParse, TK_EQ,
1159 sqlite3PExpr(pParse, TK_DOT, 1206 sqlite3PExpr(pParse, TK_DOT,
1160 sqlite3PExpr(pParse, TK_ID, 0, 0, &tOld), 1207 sqlite3ExprAlloc(db, TK_ID, &tOld, 0),
1161 sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol) 1208 sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)
1162 , 0), 1209 , 0),
1163 sqlite3PExpr(pParse, TK_ID, 0, 0, &tFromCol) 1210 sqlite3ExprAlloc(db, TK_ID, &tFromCol, 0)
1164 , 0); 1211 , 0);
1165 pWhere = sqlite3ExprAnd(db, pWhere, pEq); 1212 pWhere = sqlite3ExprAnd(db, pWhere, pEq);
1166 1213
1167 /* For ON UPDATE, construct the next term of the WHEN clause. 1214 /* For ON UPDATE, construct the next term of the WHEN clause.
1168 ** The final WHEN clause will be like this: 1215 ** The final WHEN clause will be like this:
1169 ** 1216 **
1170 ** WHEN NOT(old.col1 IS new.col1 AND ... AND old.colN IS new.colN) 1217 ** WHEN NOT(old.col1 IS new.col1 AND ... AND old.colN IS new.colN)
1171 */ 1218 */
1172 if( pChanges ){ 1219 if( pChanges ){
1173 pEq = sqlite3PExpr(pParse, TK_IS, 1220 pEq = sqlite3PExpr(pParse, TK_IS,
1174 sqlite3PExpr(pParse, TK_DOT, 1221 sqlite3PExpr(pParse, TK_DOT,
1175 sqlite3PExpr(pParse, TK_ID, 0, 0, &tOld), 1222 sqlite3ExprAlloc(db, TK_ID, &tOld, 0),
1176 sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol), 1223 sqlite3ExprAlloc(db, TK_ID, &tToCol, 0),
1177 0), 1224 0),
1178 sqlite3PExpr(pParse, TK_DOT, 1225 sqlite3PExpr(pParse, TK_DOT,
1179 sqlite3PExpr(pParse, TK_ID, 0, 0, &tNew), 1226 sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
1180 sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol), 1227 sqlite3ExprAlloc(db, TK_ID, &tToCol, 0),
1181 0), 1228 0),
1182 0); 1229 0);
1183 pWhen = sqlite3ExprAnd(db, pWhen, pEq); 1230 pWhen = sqlite3ExprAnd(db, pWhen, pEq);
1184 } 1231 }
1185 1232
1186 if( action!=OE_Restrict && (action!=OE_Cascade || pChanges) ){ 1233 if( action!=OE_Restrict && (action!=OE_Cascade || pChanges) ){
1187 Expr *pNew; 1234 Expr *pNew;
1188 if( action==OE_Cascade ){ 1235 if( action==OE_Cascade ){
1189 pNew = sqlite3PExpr(pParse, TK_DOT, 1236 pNew = sqlite3PExpr(pParse, TK_DOT,
1190 sqlite3PExpr(pParse, TK_ID, 0, 0, &tNew), 1237 sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
1191 sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol) 1238 sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)
1192 , 0); 1239 , 0);
1193 }else if( action==OE_SetDflt ){ 1240 }else if( action==OE_SetDflt ){
1194 Expr *pDflt = pFKey->pFrom->aCol[iFromCol].pDflt; 1241 Expr *pDflt = pFKey->pFrom->aCol[iFromCol].pDflt;
1195 if( pDflt ){ 1242 if( pDflt ){
1196 pNew = sqlite3ExprDup(db, pDflt, 0); 1243 pNew = sqlite3ExprDup(db, pDflt, 0);
1197 }else{ 1244 }else{
1198 pNew = sqlite3PExpr(pParse, TK_NULL, 0, 0, 0); 1245 pNew = sqlite3PExpr(pParse, TK_NULL, 0, 0, 0);
1199 } 1246 }
1200 }else{ 1247 }else{
1201 pNew = sqlite3PExpr(pParse, TK_NULL, 0, 0, 0); 1248 pNew = sqlite3PExpr(pParse, TK_NULL, 0, 0, 0);
(...skipping 26 matching lines...) Expand all
1228 pWhere = 0; 1275 pWhere = 0;
1229 } 1276 }
1230 1277
1231 /* Disable lookaside memory allocation */ 1278 /* Disable lookaside memory allocation */
1232 enableLookaside = db->lookaside.bEnabled; 1279 enableLookaside = db->lookaside.bEnabled;
1233 db->lookaside.bEnabled = 0; 1280 db->lookaside.bEnabled = 0;
1234 1281
1235 pTrigger = (Trigger *)sqlite3DbMallocZero(db, 1282 pTrigger = (Trigger *)sqlite3DbMallocZero(db,
1236 sizeof(Trigger) + /* struct Trigger */ 1283 sizeof(Trigger) + /* struct Trigger */
1237 sizeof(TriggerStep) + /* Single step in trigger program */ 1284 sizeof(TriggerStep) + /* Single step in trigger program */
1238 nFrom + 1 /* Space for pStep->target.z */ 1285 nFrom + 1 /* Space for pStep->zTarget */
1239 ); 1286 );
1240 if( pTrigger ){ 1287 if( pTrigger ){
1241 pStep = pTrigger->step_list = (TriggerStep *)&pTrigger[1]; 1288 pStep = pTrigger->step_list = (TriggerStep *)&pTrigger[1];
1242 pStep->target.z = (char *)&pStep[1]; 1289 pStep->zTarget = (char *)&pStep[1];
1243 pStep->target.n = nFrom; 1290 memcpy((char *)pStep->zTarget, zFrom, nFrom);
1244 memcpy((char *)pStep->target.z, zFrom, nFrom);
1245 1291
1246 pStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); 1292 pStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
1247 pStep->pExprList = sqlite3ExprListDup(db, pList, EXPRDUP_REDUCE); 1293 pStep->pExprList = sqlite3ExprListDup(db, pList, EXPRDUP_REDUCE);
1248 pStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); 1294 pStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
1249 if( pWhen ){ 1295 if( pWhen ){
1250 pWhen = sqlite3PExpr(pParse, TK_NOT, pWhen, 0, 0); 1296 pWhen = sqlite3PExpr(pParse, TK_NOT, pWhen, 0, 0);
1251 pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE); 1297 pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE);
1252 } 1298 }
1253 } 1299 }
1254 1300
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
1353 #ifndef SQLITE_OMIT_TRIGGER 1399 #ifndef SQLITE_OMIT_TRIGGER
1354 fkTriggerDelete(db, pFKey->apTrigger[0]); 1400 fkTriggerDelete(db, pFKey->apTrigger[0]);
1355 fkTriggerDelete(db, pFKey->apTrigger[1]); 1401 fkTriggerDelete(db, pFKey->apTrigger[1]);
1356 #endif 1402 #endif
1357 1403
1358 pNext = pFKey->pNextFrom; 1404 pNext = pFKey->pNextFrom;
1359 sqlite3DbFree(db, pFKey); 1405 sqlite3DbFree(db, pFKey);
1360 } 1406 }
1361 } 1407 }
1362 #endif /* ifndef SQLITE_OMIT_FOREIGN_KEY */ 1408 #endif /* ifndef SQLITE_OMIT_FOREIGN_KEY */
OLDNEW
« no previous file with comments | « third_party/sqlite/sqlite-src-3100200/src/fault.c ('k') | third_party/sqlite/sqlite-src-3100200/src/func.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698