1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-21 09:00:59 +03:00

Ensure that the correct number of columns in a UNIQUE index are checked for

uniqueness, regardless of whether or not the original table has a ROWID or
if the columns are NOT NULL, etc.  Ticket [9a6daf340df99ba93c].

FossilOrigin-Name: 6b785e92f279cb65746834d5cd25594fd3333342
This commit is contained in:
drh
2014-07-30 13:56:48 +00:00
parent a7f37491a7
commit ac50232d0f
6 changed files with 102 additions and 24 deletions

View File

@@ -2712,7 +2712,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
sqlite3VdbeAddOp2(v, OP_Goto, 0, j2);
addr2 = sqlite3VdbeCurrentAddr(v);
sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord,
pKey->nField - pIndex->nKeyCol); VdbeCoverage(v);
pIndex->nKeyCol); VdbeCoverage(v);
sqlite3UniqueConstraint(pParse, OE_Abort, pIndex);
}else{
addr2 = sqlite3VdbeCurrentAddr(v);

View File

@@ -4271,12 +4271,12 @@ case OP_ResetCount: {
}
/* Opcode: SorterCompare P1 P2 P3 P4
** Synopsis: if key(P1)!=rtrim(r[P3],P4) goto P2
** Synopsis: if key(P1)!=trim(r[P3],P4) goto P2
**
** P1 is a sorter cursor. This instruction compares a prefix of the
** the record blob in register P3 against a prefix of the entry that
** the sorter cursor currently points to. The final P4 fields of both
** the P3 and sorter record are ignored.
** the sorter cursor currently points to. Only the first P4 fields
** of r[P3] and the sorter record are compared.
**
** If either P3 or the sorter contains a NULL in one of their significant
** fields (not counting the P4 fields at the end which are ignored) then
@@ -4288,14 +4288,14 @@ case OP_ResetCount: {
case OP_SorterCompare: {
VdbeCursor *pC;
int res;
int nIgnore;
int nKeyCol;
pC = p->apCsr[pOp->p1];
assert( isSorter(pC) );
assert( pOp->p4type==P4_INT32 );
pIn3 = &aMem[pOp->p3];
nIgnore = pOp->p4.i;
rc = sqlite3VdbeSorterCompare(pC, pIn3, nIgnore, &res);
nKeyCol = pOp->p4.i;
rc = sqlite3VdbeSorterCompare(pC, pIn3, nKeyCol, &res);
VdbeBranchTaken(res!=0,2);
if( res ){
pc = pOp->p2-1;

View File

@@ -385,7 +385,7 @@ static int vdbeSorterIterInit(
*/
static void vdbeSorterCompare(
const VdbeCursor *pCsr, /* Cursor object (for pKeyInfo) */
int nIgnore, /* Ignore the last nIgnore fields */
int nKeyCol, /* Num of columns. 0 means "all" */
const void *pKey1, int nKey1, /* Left side of comparison */
const void *pKey2, int nKey2, /* Right side of comparison */
int *pRes /* OUT: Result of comparison */
@@ -399,10 +399,9 @@ static void vdbeSorterCompare(
sqlite3VdbeRecordUnpack(pKeyInfo, nKey2, pKey2, r2);
}
if( nIgnore ){
r2->nField = pKeyInfo->nField - nIgnore;
assert( r2->nField>0 );
for(i=0; i<r2->nField; i++){
if( nKeyCol ){
r2->nField = nKeyCol;
for(i=0; i<nKeyCol; i++){
if( r2->aMem[i].flags & MEM_Null ){
*pRes = -1;
return;
@@ -1084,13 +1083,13 @@ int sqlite3VdbeSorterRowkey(const VdbeCursor *pCsr, Mem *pOut){
int sqlite3VdbeSorterCompare(
const VdbeCursor *pCsr, /* Sorter cursor */
Mem *pVal, /* Value to compare to current sorter key */
int nIgnore, /* Ignore this many fields at the end */
int nKeyCol, /* Only compare this many fields */
int *pRes /* OUT: Result of comparison */
){
VdbeSorter *pSorter = pCsr->pSorter;
void *pKey; int nKey; /* Sorter key to compare pVal with */
pKey = vdbeSorterRowkey(pSorter, &nKey);
vdbeSorterCompare(pCsr, nIgnore, pVal->z, pVal->n, pKey, nKey, pRes);
vdbeSorterCompare(pCsr, nKeyCol, pVal->z, pVal->n, pKey, nKey, pRes);
return SQLITE_OK;
}