mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-10 01:02:56 +03:00
Handle an SQLITE_IGNORE returned when requesting authorization to read parent key columns by pretending the parent key columns contain NULL values.
FossilOrigin-Name: 3c24df38e6ae5dfe999bbf3133b65df0074c6a50
This commit is contained in:
18
manifest
18
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Add\sone\smore\sauthentication\stest\sto\sfkey2.test\sto\scover\san\suntested\sbranch.
|
C Handle\san\sSQLITE_IGNORE\sreturned\swhen\srequesting\sauthorization\sto\sread\sparent\skey\scolumns\sby\spretending\sthe\sparent\skey\scolumns\scontain\sNULL\svalues.
|
||||||
D 2009-10-02T15:29:10
|
D 2009-10-03T07:04:12
|
||||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
||||||
F Makefile.in 4ca3f1dd6efa2075bcb27f4dc43eef749877740d
|
F Makefile.in 4ca3f1dd6efa2075bcb27f4dc43eef749877740d
|
||||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||||
@@ -102,7 +102,7 @@ F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad
|
|||||||
F src/alter.c 1b63d4f2a6e76af9e2964d4d86ccc8e74c3fae4a
|
F src/alter.c 1b63d4f2a6e76af9e2964d4d86ccc8e74c3fae4a
|
||||||
F src/analyze.c 5a8b8aa3d170eac5e71af45458cec61f83c623ee
|
F src/analyze.c 5a8b8aa3d170eac5e71af45458cec61f83c623ee
|
||||||
F src/attach.c 13995348fc5a26cdd136a50806faf292aabc173f
|
F src/attach.c 13995348fc5a26cdd136a50806faf292aabc173f
|
||||||
F src/auth.c 50a4fd3ad4a0d3dec95cec7c022a6ca9d5ca3f4e
|
F src/auth.c a5471a6951a18f79d783da34be22cd94dfbe603a
|
||||||
F src/backup.c 6f1c2d9862c8a3feb7739dfcca02c1f5352e37f3
|
F src/backup.c 6f1c2d9862c8a3feb7739dfcca02c1f5352e37f3
|
||||||
F src/bitvec.c ed215b95734045e58358c3b3e16448f8fe6a235a
|
F src/bitvec.c ed215b95734045e58358c3b3e16448f8fe6a235a
|
||||||
F src/btmutex.c 0f43a75bb5b8147b386e8e1c3e71ba734e3863b7
|
F src/btmutex.c 0f43a75bb5b8147b386e8e1c3e71ba734e3863b7
|
||||||
@@ -116,7 +116,7 @@ F src/date.c 657ff12ca0f1195b531561afacbb38b772d16638
|
|||||||
F src/delete.c 308e300d599d2d11b838687e2cf7309d42f29a1a
|
F src/delete.c 308e300d599d2d11b838687e2cf7309d42f29a1a
|
||||||
F src/expr.c c7f3f718bd5c392344ec8694a41c1824f30cf375
|
F src/expr.c c7f3f718bd5c392344ec8694a41c1824f30cf375
|
||||||
F src/fault.c dc88c821842157460750d2d61a8a8b4197d047ff
|
F src/fault.c dc88c821842157460750d2d61a8a8b4197d047ff
|
||||||
F src/fkey.c bcc2af88a4f88cb2127cd5fb68d4e09e73e03063
|
F src/fkey.c 720f049dc4615a568b07cd7d65bbc499b8604f8a
|
||||||
F src/func.c e536218d193b8d326aab91120bc4c6f28aa2b606
|
F src/func.c e536218d193b8d326aab91120bc4c6f28aa2b606
|
||||||
F src/global.c 271952d199a8cc59d4ce840b3bbbfd2f30c8ba32
|
F src/global.c 271952d199a8cc59d4ce840b3bbbfd2f30c8ba32
|
||||||
F src/hash.c ebcaa921ffd9d86f7ea5ae16a0a29d1c871130a7
|
F src/hash.c ebcaa921ffd9d86f7ea5ae16a0a29d1c871130a7
|
||||||
@@ -164,7 +164,7 @@ F src/select.c 1d0a13137532321b4364f964e46f057d271691e3
|
|||||||
F src/shell.c d6e64471aafb81f355262533393169a70529847a
|
F src/shell.c d6e64471aafb81f355262533393169a70529847a
|
||||||
F src/sqlite.h.in 5af8181f815831a8672c3834c60e6b4418448bcc
|
F src/sqlite.h.in 5af8181f815831a8672c3834c60e6b4418448bcc
|
||||||
F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17
|
F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17
|
||||||
F src/sqliteInt.h 20ca4172804c85745445bd3291d7884446b67bd7
|
F src/sqliteInt.h 61c55f5f83c63813903f374e9b33173572f0559a
|
||||||
F src/sqliteLimit.h 504a3161886d2938cbd163054ad620b8356df758
|
F src/sqliteLimit.h 504a3161886d2938cbd163054ad620b8356df758
|
||||||
F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76
|
F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76
|
||||||
F src/table.c cc86ad3d6ad54df7c63a3e807b5783c90411a08d
|
F src/table.c cc86ad3d6ad54df7c63a3e807b5783c90411a08d
|
||||||
@@ -330,7 +330,7 @@ F test/expr.test 9f521ae22f00e074959f72ce2e55d46b9ed23f68
|
|||||||
F test/filectrl.test 8923a6dc7630f31c8a9dd3d3d740aa0922df7bf8
|
F test/filectrl.test 8923a6dc7630f31c8a9dd3d3d740aa0922df7bf8
|
||||||
F test/filefmt.test 84e3d0fe9f12d0d2ac852465c6f8450aea0d6f43
|
F test/filefmt.test 84e3d0fe9f12d0d2ac852465c6f8450aea0d6f43
|
||||||
F test/fkey1.test 01c7de578e11747e720c2d9aeef27f239853c4da
|
F test/fkey1.test 01c7de578e11747e720c2d9aeef27f239853c4da
|
||||||
F test/fkey2.test 10ac5a185bd82fccebc1644960baee89a9a24bcc
|
F test/fkey2.test 2220d7384624d792b692a94c65239f6359480312
|
||||||
F test/fkey3.test 42f88d6048d8dc079e2a8cf7baad1cc1483a7620
|
F test/fkey3.test 42f88d6048d8dc079e2a8cf7baad1cc1483a7620
|
||||||
F test/fkey_malloc.test a5ede29bd2f6e56dea78c3d43fb86dd696c068c8
|
F test/fkey_malloc.test a5ede29bd2f6e56dea78c3d43fb86dd696c068c8
|
||||||
F test/format4.test 1f0cac8ff3895e9359ed87e41aaabee982a812eb
|
F test/format4.test 1f0cac8ff3895e9359ed87e41aaabee982a812eb
|
||||||
@@ -755,7 +755,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
|||||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||||
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
||||||
P 9842f2d5f606eb8f641ecae9fbc5368b8d7e4286
|
P e4fa8be770eb79806d489be46f68f969de17378b
|
||||||
R 3f4f5605b427a8a3e05e79ea9061feda
|
R 2ef0920c3026f22dce7b0a365b2419f0
|
||||||
U dan
|
U dan
|
||||||
Z 6f95349be215c026d8008f1f1d0bb69d
|
Z c958d9e98d78b6ad7096dbaf02193139
|
||||||
|
@@ -1 +1 @@
|
|||||||
e4fa8be770eb79806d489be46f68f969de17378b
|
3c24df38e6ae5dfe999bbf3133b65df0074c6a50
|
18
src/auth.c
18
src/auth.c
@@ -100,30 +100,28 @@ static void sqliteAuthBadReturnCode(Parse *pParse){
|
|||||||
** to an SQL NULL expression. Otherwise, if pExpr is NULL, then SQLITE_IGNORE
|
** to an SQL NULL expression. Otherwise, if pExpr is NULL, then SQLITE_IGNORE
|
||||||
** is treated as SQLITE_DENY. In this case an error is left in pParse.
|
** is treated as SQLITE_DENY. In this case an error is left in pParse.
|
||||||
*/
|
*/
|
||||||
void sqlite3AuthReadCol(
|
int sqlite3AuthReadCol(
|
||||||
Parse *pParse, /* The parser context */
|
Parse *pParse, /* The parser context */
|
||||||
const char *zTab, /* Table name */
|
const char *zTab, /* Table name */
|
||||||
const char *zCol, /* Column name */
|
const char *zCol, /* Column name */
|
||||||
int iDb, /* Index of containing database. */
|
int iDb /* Index of containing database. */
|
||||||
Expr *pExpr /* Optional expression */
|
|
||||||
){
|
){
|
||||||
sqlite3 *db = pParse->db; /* Database handle */
|
sqlite3 *db = pParse->db; /* Database handle */
|
||||||
char *zDb = db->aDb[iDb].zName; /* Name of attached database */
|
char *zDb = db->aDb[iDb].zName; /* Name of attached database */
|
||||||
int rc; /* Auth callback return code */
|
int rc; /* Auth callback return code */
|
||||||
|
|
||||||
rc = db->xAuth(db->pAuthArg, SQLITE_READ, zTab,zCol,zDb,pParse->zAuthContext);
|
rc = db->xAuth(db->pAuthArg, SQLITE_READ, zTab,zCol,zDb,pParse->zAuthContext);
|
||||||
if( rc!=SQLITE_IGNORE && rc!=SQLITE_DENY && rc!=SQLITE_OK ){
|
if( rc==SQLITE_DENY ){
|
||||||
sqliteAuthBadReturnCode(pParse);
|
|
||||||
}else if( rc==SQLITE_IGNORE && pExpr ){
|
|
||||||
pExpr->op = TK_NULL;
|
|
||||||
}else if( rc!=SQLITE_OK ){
|
|
||||||
if( db->nDb>2 || iDb!=0 ){
|
if( db->nDb>2 || iDb!=0 ){
|
||||||
sqlite3ErrorMsg(pParse, "access to %s.%s.%s is prohibited",zDb,zTab,zCol);
|
sqlite3ErrorMsg(pParse, "access to %s.%s.%s is prohibited",zDb,zTab,zCol);
|
||||||
}else{
|
}else{
|
||||||
sqlite3ErrorMsg(pParse, "access to %s.%s is prohibited", zTab, zCol);
|
sqlite3ErrorMsg(pParse, "access to %s.%s is prohibited", zTab, zCol);
|
||||||
}
|
}
|
||||||
pParse->rc = SQLITE_AUTH;
|
pParse->rc = SQLITE_AUTH;
|
||||||
|
}else if( rc!=SQLITE_IGNORE && rc!=SQLITE_OK ){
|
||||||
|
sqliteAuthBadReturnCode(pParse);
|
||||||
}
|
}
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -181,7 +179,9 @@ void sqlite3AuthRead(
|
|||||||
zCol = "ROWID";
|
zCol = "ROWID";
|
||||||
}
|
}
|
||||||
assert( iDb>=0 && iDb<db->nDb );
|
assert( iDb>=0 && iDb<db->nDb );
|
||||||
sqlite3AuthReadCol(pParse, pTab->zName, zCol, iDb, pExpr);
|
if( SQLITE_IGNORE==sqlite3AuthReadCol(pParse, pTab->zName, zCol, iDb) ){
|
||||||
|
pExpr->op = TK_NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
132
src/fkey.c
132
src/fkey.c
@@ -319,7 +319,8 @@ static void fkLookupParent(
|
|||||||
FKey *pFKey, /* Foreign key constraint */
|
FKey *pFKey, /* Foreign key constraint */
|
||||||
int *aiCol, /* Map from parent key columns to child table columns */
|
int *aiCol, /* Map from parent key columns to child table columns */
|
||||||
int regData, /* Address of array containing child table row */
|
int regData, /* Address of array containing child table row */
|
||||||
int nIncr /* Increment constraint counter by this */
|
int nIncr, /* Increment constraint counter by this */
|
||||||
|
int isIgnore /* If true, pretend pTab contains all NULL values */
|
||||||
){
|
){
|
||||||
int i; /* Iterator variable */
|
int i; /* Iterator variable */
|
||||||
Vdbe *v = sqlite3GetVdbe(pParse); /* Vdbe to add code to */
|
Vdbe *v = sqlite3GetVdbe(pParse); /* Vdbe to add code to */
|
||||||
@@ -341,66 +342,68 @@ static void fkLookupParent(
|
|||||||
sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iOk);
|
sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iOk);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( pIdx==0 ){
|
if( isIgnore==0 ){
|
||||||
/* If pIdx is NULL, then the parent key is the INTEGER PRIMARY KEY
|
if( pIdx==0 ){
|
||||||
** column of the parent table (table pTab). */
|
/* If pIdx is NULL, then the parent key is the INTEGER PRIMARY KEY
|
||||||
int iMustBeInt; /* Address of MustBeInt instruction */
|
** column of the parent table (table pTab). */
|
||||||
int regTemp = sqlite3GetTempReg(pParse);
|
int iMustBeInt; /* Address of MustBeInt instruction */
|
||||||
|
int regTemp = sqlite3GetTempReg(pParse);
|
||||||
/* Invoke MustBeInt to coerce the child key value to an integer (i.e.
|
|
||||||
** apply the affinity of the parent key). If this fails, then there
|
/* Invoke MustBeInt to coerce the child key value to an integer (i.e.
|
||||||
** is no matching parent key. Before using MustBeInt, make a copy of
|
** apply the affinity of the parent key). If this fails, then there
|
||||||
** the value. Otherwise, the value inserted into the child key column
|
** is no matching parent key. Before using MustBeInt, make a copy of
|
||||||
** will have INTEGER affinity applied to it, which may not be correct. */
|
** the value. Otherwise, the value inserted into the child key column
|
||||||
sqlite3VdbeAddOp2(v, OP_SCopy, aiCol[0]+1+regData, regTemp);
|
** will have INTEGER affinity applied to it, which may not be correct. */
|
||||||
iMustBeInt = sqlite3VdbeAddOp2(v, OP_MustBeInt, regTemp, 0);
|
sqlite3VdbeAddOp2(v, OP_SCopy, aiCol[0]+1+regData, regTemp);
|
||||||
|
iMustBeInt = sqlite3VdbeAddOp2(v, OP_MustBeInt, regTemp, 0);
|
||||||
/* If the parent table is the same as the child table, and we are about
|
|
||||||
** to increment the constraint-counter (i.e. this is an INSERT operation),
|
/* If the parent table is the same as the child table, and we are about
|
||||||
** then check if the row being inserted matches itself. If so, do not
|
** to increment the constraint-counter (i.e. this is an INSERT operation),
|
||||||
** increment the constraint-counter. */
|
** then check if the row being inserted matches itself. If so, do not
|
||||||
if( pTab==pFKey->pFrom && nIncr==1 ){
|
** increment the constraint-counter. */
|
||||||
sqlite3VdbeAddOp3(v, OP_Eq, regData, iOk, regTemp);
|
if( pTab==pFKey->pFrom && nIncr==1 ){
|
||||||
}
|
sqlite3VdbeAddOp3(v, OP_Eq, regData, iOk, regTemp);
|
||||||
|
|
||||||
sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead);
|
|
||||||
sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regTemp);
|
|
||||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, iOk);
|
|
||||||
sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
|
|
||||||
sqlite3VdbeJumpHere(v, iMustBeInt);
|
|
||||||
sqlite3ReleaseTempReg(pParse, regTemp);
|
|
||||||
}else{
|
|
||||||
int nCol = pFKey->nCol;
|
|
||||||
int regTemp = sqlite3GetTempRange(pParse, nCol);
|
|
||||||
int regRec = sqlite3GetTempReg(pParse);
|
|
||||||
KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
|
|
||||||
|
|
||||||
sqlite3VdbeAddOp3(v, OP_OpenRead, iCur, pIdx->tnum, iDb);
|
|
||||||
sqlite3VdbeChangeP4(v, -1, (char*)pKey, P4_KEYINFO_HANDOFF);
|
|
||||||
for(i=0; i<nCol; i++){
|
|
||||||
sqlite3VdbeAddOp2(v, OP_SCopy, aiCol[i]+1+regData, regTemp+i);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If the parent table is the same as the child table, and we are about
|
|
||||||
** to increment the constraint-counter (i.e. this is an INSERT operation),
|
|
||||||
** then check if the row being inserted matches itself. If so, do not
|
|
||||||
** increment the constraint-counter. */
|
|
||||||
if( pTab==pFKey->pFrom && nIncr==1 ){
|
|
||||||
int iJump = sqlite3VdbeCurrentAddr(v) + nCol + 1;
|
|
||||||
for(i=0; i<nCol; i++){
|
|
||||||
int iChild = aiCol[i]+1+regData;
|
|
||||||
int iParent = pIdx->aiColumn[i]+1+regData;
|
|
||||||
sqlite3VdbeAddOp3(v, OP_Ne, iChild, iJump, iParent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead);
|
||||||
|
sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regTemp);
|
||||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, iOk);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, iOk);
|
||||||
|
sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
|
||||||
|
sqlite3VdbeJumpHere(v, iMustBeInt);
|
||||||
|
sqlite3ReleaseTempReg(pParse, regTemp);
|
||||||
|
}else{
|
||||||
|
int nCol = pFKey->nCol;
|
||||||
|
int regTemp = sqlite3GetTempRange(pParse, nCol);
|
||||||
|
int regRec = sqlite3GetTempReg(pParse);
|
||||||
|
KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
|
||||||
|
|
||||||
|
sqlite3VdbeAddOp3(v, OP_OpenRead, iCur, pIdx->tnum, iDb);
|
||||||
|
sqlite3VdbeChangeP4(v, -1, (char*)pKey, P4_KEYINFO_HANDOFF);
|
||||||
|
for(i=0; i<nCol; i++){
|
||||||
|
sqlite3VdbeAddOp2(v, OP_SCopy, aiCol[i]+1+regData, regTemp+i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the parent table is the same as the child table, and we are about
|
||||||
|
** to increment the constraint-counter (i.e. this is an INSERT operation),
|
||||||
|
** then check if the row being inserted matches itself. If so, do not
|
||||||
|
** increment the constraint-counter. */
|
||||||
|
if( pTab==pFKey->pFrom && nIncr==1 ){
|
||||||
|
int iJump = sqlite3VdbeCurrentAddr(v) + nCol + 1;
|
||||||
|
for(i=0; i<nCol; i++){
|
||||||
|
int iChild = aiCol[i]+1+regData;
|
||||||
|
int iParent = pIdx->aiColumn[i]+1+regData;
|
||||||
|
sqlite3VdbeAddOp3(v, OP_Ne, iChild, iJump, iParent);
|
||||||
|
}
|
||||||
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, iOk);
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3VdbeAddOp3(v, OP_MakeRecord, regTemp, nCol, regRec);
|
||||||
|
sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), 0);
|
||||||
|
sqlite3VdbeAddOp3(v, OP_Found, iCur, iOk, regRec);
|
||||||
|
|
||||||
|
sqlite3ReleaseTempReg(pParse, regRec);
|
||||||
|
sqlite3ReleaseTempRange(pParse, regTemp, nCol);
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlite3VdbeAddOp3(v, OP_MakeRecord, regTemp, nCol, regRec);
|
|
||||||
sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), 0);
|
|
||||||
sqlite3VdbeAddOp3(v, OP_Found, iCur, iOk, regRec);
|
|
||||||
|
|
||||||
sqlite3ReleaseTempReg(pParse, regRec);
|
|
||||||
sqlite3ReleaseTempRange(pParse, regTemp, nCol);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !pFKey->isDeferred && !pParse->pToplevel && !pParse->isMultiWrite ){
|
if( !pFKey->isDeferred && !pParse->pToplevel && !pParse->isMultiWrite ){
|
||||||
@@ -706,6 +709,7 @@ void sqlite3FkCheck(
|
|||||||
int *aiCol;
|
int *aiCol;
|
||||||
int iCol;
|
int iCol;
|
||||||
int i;
|
int i;
|
||||||
|
int isIgnore = 0;
|
||||||
|
|
||||||
/* Find the parent table of this foreign key. Also find a unique index
|
/* Find the parent table of this foreign key. Also find a unique index
|
||||||
** on the parent key columns in the parent table. If either of these
|
** on the parent key columns in the parent table. If either of these
|
||||||
@@ -733,10 +737,14 @@ void sqlite3FkCheck(
|
|||||||
aiCol[i] = -1;
|
aiCol[i] = -1;
|
||||||
}
|
}
|
||||||
#ifndef SQLITE_OMIT_AUTHORIZATION
|
#ifndef SQLITE_OMIT_AUTHORIZATION
|
||||||
/* Request permission to read the parent key columns. */
|
/* Request permission to read the parent key columns. If the
|
||||||
|
** authorization callback returns SQLITE_IGNORE, behave as if any
|
||||||
|
** values read from the parent table are NULL. */
|
||||||
if( db->xAuth ){
|
if( db->xAuth ){
|
||||||
|
int rcauth;
|
||||||
char *zCol = pTo->aCol[pIdx ? pIdx->aiColumn[i] : pTo->iPKey].zName;
|
char *zCol = pTo->aCol[pIdx ? pIdx->aiColumn[i] : pTo->iPKey].zName;
|
||||||
sqlite3AuthReadCol(pParse, pTo->zName, zCol, iDb, 0);
|
rcauth = sqlite3AuthReadCol(pParse, pTo->zName, zCol, iDb);
|
||||||
|
isIgnore = (rcauth==SQLITE_IGNORE);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -751,12 +759,12 @@ void sqlite3FkCheck(
|
|||||||
/* A row is being removed from the child table. Search for the parent.
|
/* A row is being removed from the child table. Search for the parent.
|
||||||
** If the parent does not exist, removing the child row resolves an
|
** If the parent does not exist, removing the child row resolves an
|
||||||
** outstanding foreign key constraint violation. */
|
** outstanding foreign key constraint violation. */
|
||||||
fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regOld, -1);
|
fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regOld, -1,isIgnore);
|
||||||
}
|
}
|
||||||
if( regNew!=0 ){
|
if( regNew!=0 ){
|
||||||
/* A row is being added to the child table. If a parent row cannot
|
/* A row is being added to the child table. If a parent row cannot
|
||||||
** be found, adding the child row has violated the FK constraint. */
|
** be found, adding the child row has violated the FK constraint. */
|
||||||
fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regNew, +1);
|
fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regNew, +1,isIgnore);
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlite3DbFree(db, aiFree);
|
sqlite3DbFree(db, aiFree);
|
||||||
|
@@ -2734,7 +2734,7 @@ void sqlite3DeferForeignKey(Parse*, int);
|
|||||||
int sqlite3AuthCheck(Parse*,int, const char*, const char*, const char*);
|
int sqlite3AuthCheck(Parse*,int, const char*, const char*, const char*);
|
||||||
void sqlite3AuthContextPush(Parse*, AuthContext*, const char*);
|
void sqlite3AuthContextPush(Parse*, AuthContext*, const char*);
|
||||||
void sqlite3AuthContextPop(AuthContext*);
|
void sqlite3AuthContextPop(AuthContext*);
|
||||||
void sqlite3AuthReadCol(Parse*, const char *, const char *, int, Expr *);
|
int sqlite3AuthReadCol(Parse*, const char *, const char *, int);
|
||||||
#else
|
#else
|
||||||
# define sqlite3AuthRead(a,b,c,d)
|
# define sqlite3AuthRead(a,b,c,d)
|
||||||
# define sqlite3AuthCheck(a,b,c,d,e) SQLITE_OK
|
# define sqlite3AuthCheck(a,b,c,d,e) SQLITE_OK
|
||||||
|
@@ -1421,6 +1421,9 @@ ifcapable auth {
|
|||||||
set authargs
|
set authargs
|
||||||
} {SQLITE_INSERT two {} main {} SQLITE_READ one a main {}}
|
} {SQLITE_INSERT two {} main {} SQLITE_READ one a main {}}
|
||||||
|
|
||||||
|
# Return SQLITE_IGNORE to requests to read from the parent table. This
|
||||||
|
# causes inserts of non-NULL keys into the child table to fail.
|
||||||
|
#
|
||||||
rename auth {}
|
rename auth {}
|
||||||
proc auth {args} {
|
proc auth {args} {
|
||||||
if {[lindex $args 1] == "long"} {return SQLITE_IGNORE}
|
if {[lindex $args 1] == "long"} {return SQLITE_IGNORE}
|
||||||
@@ -1428,7 +1431,16 @@ ifcapable auth {
|
|||||||
}
|
}
|
||||||
do_test fkey2-18.8 {
|
do_test fkey2-18.8 {
|
||||||
catchsql { INSERT INTO short VALUES(1, 3, 2) }
|
catchsql { INSERT INTO short VALUES(1, 3, 2) }
|
||||||
} {1 {access to long.b is prohibited}}
|
} {1 {foreign key constraint failed}}
|
||||||
|
do_test fkey2-18.9 {
|
||||||
|
execsql { INSERT INTO short VALUES(1, 3, NULL) }
|
||||||
|
} {}
|
||||||
|
do_test fkey2-18.10 {
|
||||||
|
execsql { SELECT * FROM short }
|
||||||
|
} {1 3 2 1 3 {}}
|
||||||
|
do_test fkey2-18.11 {
|
||||||
|
catchsql { UPDATE short SET f = 2 WHERE f IS NULL }
|
||||||
|
} {1 {foreign key constraint failed}}
|
||||||
|
|
||||||
db auth {}
|
db auth {}
|
||||||
unset authargs
|
unset authargs
|
||||||
|
Reference in New Issue
Block a user