diff options
author | drh <drh@noemail.net> | 2013-10-23 13:30:58 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2013-10-23 13:30:58 +0000 |
commit | ad124329ab8e45dafc04ca612c87768843d9ed4b (patch) | |
tree | 3c114a5fe81269f2e43c2a576527087ba41872fb /src | |
parent | ec95c4417559b3f9c0fc43886bed9219c78a48bf (diff) | |
download | sqlite-ad124329ab8e45dafc04ca612c87768843d9ed4b.tar.gz sqlite-ad124329ab8e45dafc04ca612c87768843d9ed4b.zip |
Some inserts and queries working for multi-column primary keys
and WITHOUT ROWID.
FossilOrigin-Name: b21d831b2aa55507dd9def2acb02cdbffddf10d1
Diffstat (limited to 'src')
-rw-r--r-- | src/build.c | 7 | ||||
-rw-r--r-- | src/expr.c | 2 | ||||
-rw-r--r-- | src/insert.c | 8 | ||||
-rw-r--r-- | src/select.c | 21 | ||||
-rw-r--r-- | src/sqliteInt.h | 5 | ||||
-rw-r--r-- | src/vdbe.c | 2 | ||||
-rw-r--r-- | src/vdbeaux.c | 8 |
7 files changed, 30 insertions, 23 deletions
diff --git a/src/build.c b/src/build.c index f1ef19b38..1f6315ec5 100644 --- a/src/build.c +++ b/src/build.c @@ -4027,14 +4027,15 @@ void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){ */ KeyInfo *sqlite3IndexKeyinfo(Parse *pParse, Index *pIdx){ int i; - int nCol = pIdx->nKeyCol; + int nCol = pIdx->nColumn; + int nKey = pIdx->nKeyCol; KeyInfo *pKey; - pKey = sqlite3KeyInfoAlloc(pParse->db, nCol); + pKey = sqlite3KeyInfoAlloc(pParse->db, nKey, nCol-nKey); if( pKey ){ for(i=0; i<nCol; i++){ char *zColl = pIdx->azColl[i]; - assert( zColl ); + if( zColl==0 ) zColl = "BINARY"; pKey->aColl[i] = sqlite3LocateCollSeq(pParse, zColl); pKey->aSortOrder[i] = pIdx->aSortOrder[i]; } diff --git a/src/expr.c b/src/expr.c index 58895562d..99890d94c 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1728,7 +1728,7 @@ int sqlite3CodeSubselect( pExpr->iTable = pParse->nTab++; addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, !isRowid); if( rMayHaveNull==0 ) sqlite3VdbeChangeP5(v, BTREE_UNORDERED); - pKeyInfo = isRowid ? 0 : sqlite3KeyInfoAlloc(pParse->db, 1); + pKeyInfo = isRowid ? 0 : sqlite3KeyInfoAlloc(pParse->db, 1, 1); if( ExprHasProperty(pExpr, EP_xIsSelect) ){ /* Case 1: expr IN (SELECT ...) diff --git a/src/insert.c b/src/insert.c index d9bf67216..0c654d3dc 100644 --- a/src/insert.c +++ b/src/insert.c @@ -69,15 +69,15 @@ const char *sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){ int n; Table *pTab = pIdx->pTable; sqlite3 *db = sqlite3VdbeDb(v); - pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nKeyCol+2); + pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nColumn+1); if( !pIdx->zColAff ){ db->mallocFailed = 1; return 0; } - for(n=0; n<pIdx->nKeyCol; n++){ - pIdx->zColAff[n] = pTab->aCol[pIdx->aiColumn[n]].affinity; + for(n=0; n<pIdx->nColumn; n++){ + i16 x = pIdx->aiColumn[n]; + pIdx->zColAff[n] = x<0 ? SQLITE_AFF_INTEGER : pTab->aCol[x].affinity; } - pIdx->zColAff[n++] = SQLITE_AFF_INTEGER; pIdx->zColAff[n] = 0; } diff --git a/src/select.c b/src/select.c index badd6249a..3382c26b5 100644 --- a/src/select.c +++ b/src/select.c @@ -803,18 +803,20 @@ static void selectInnerLoop( } /* -** Allocate a KeyInfo object sufficient for an index of N columns. +** Allocate a KeyInfo object sufficient for an index of N key columns and +** X extra columns. ** ** Actually, always allocate one extra column for the rowid at the end ** of the index. So the KeyInfo returned will have space sufficient for ** N+1 columns. */ -KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N){ +KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){ KeyInfo *p = sqlite3DbMallocZero(db, - sizeof(KeyInfo) + (N+1)*(sizeof(CollSeq*)+1)); + sizeof(KeyInfo) + (N+X)*(sizeof(CollSeq*)+1)); if( p ){ - p->aSortOrder = (u8*)&p->aColl[N+1]; + p->aSortOrder = (u8*)&p->aColl[N+X]; p->nField = (u16)N; + p->nXField = (u16)X; p->enc = ENC(db); p->db = db; } @@ -844,7 +846,7 @@ static KeyInfo *keyInfoFromExprList(Parse *pParse, ExprList *pList){ int i; nExpr = pList->nExpr; - pInfo = sqlite3KeyInfoAlloc(db, nExpr); + pInfo = sqlite3KeyInfoAlloc(db, nExpr, 1); if( pInfo ){ for(i=0, pItem=pList->a; i<nExpr; i++, pItem++){ CollSeq *pColl; @@ -1988,7 +1990,7 @@ static int multiSelect( assert( p->pRightmost==p ); nCol = p->pEList->nExpr; - pKeyInfo = sqlite3KeyInfoAlloc(db, nCol); + pKeyInfo = sqlite3KeyInfoAlloc(db, nCol, 1); if( !pKeyInfo ){ rc = SQLITE_NOMEM; goto multi_select_end; @@ -2367,7 +2369,7 @@ static int multiSelectOrderBy( assert( pItem->iOrderByCol>0 && pItem->iOrderByCol<=p->pEList->nExpr ); aPermute[i] = pItem->iOrderByCol - 1; } - pKeyMerge = sqlite3KeyInfoAlloc(db, nOrderBy); + pKeyMerge = sqlite3KeyInfoAlloc(db, nOrderBy, 1); if( pKeyMerge ){ for(i=0; i<nOrderBy; i++){ CollSeq *pColl; @@ -2405,7 +2407,7 @@ static int multiSelectOrderBy( regPrev = pParse->nMem+1; pParse->nMem += nExpr+1; sqlite3VdbeAddOp2(v, OP_Integer, 0, regPrev); - pKeyDup = sqlite3KeyInfoAlloc(db, nExpr); + pKeyDup = sqlite3KeyInfoAlloc(db, nExpr, 1); if( pKeyDup ){ for(i=0; i<nExpr; i++){ pKeyDup->aColl[i] = multiSelectCollSeq(pParse, p, i); @@ -4654,7 +4656,8 @@ int sqlite3Select( } /* Open a read-only cursor, execute the OP_Count, close the cursor. */ - sqlite3VdbeAddOp3(v, OP_OpenRead, iCsr, iRoot, iDb); + sqlite3VdbeAddOp4(v, OP_OpenRead, iCsr, iRoot, iDb, + SQLITE_INT_TO_PTR(1), P4_INT32); if( pKeyInfo ){ sqlite3VdbeChangeP4(v, -1, (char *)pKeyInfo, P4_KEYINFO_HANDOFF); } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 43cf27436..0522171ca 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1518,7 +1518,8 @@ struct FKey { struct KeyInfo { sqlite3 *db; /* The database connection */ u8 enc; /* Text encoding - one of the SQLITE_UTF* values */ - u16 nField; /* Maximum index for aColl[] and aSortOrder[] */ + u16 nField; /* Number of key columns in the index */ + u16 nXField; /* Number of columns beyond the key columns */ u8 *aSortOrder; /* Sort order for each column. */ CollSeq *aColl[1]; /* Collating sequence for each term of the key */ }; @@ -3139,7 +3140,7 @@ void sqlite3MinimumFileFormat(Parse*, int, int); void sqlite3SchemaClear(void *); Schema *sqlite3SchemaGet(sqlite3 *, Btree *); int sqlite3SchemaToIndex(sqlite3 *db, Schema *); -KeyInfo *sqlite3KeyInfoAlloc(sqlite3*,int); +KeyInfo *sqlite3KeyInfoAlloc(sqlite3*,int,int); KeyInfo *sqlite3IndexKeyinfo(Parse *, Index *); int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *, void (*)(sqlite3_context*,int,sqlite3_value **), diff --git a/src/vdbe.c b/src/vdbe.c index 29adca632..6d39861c6 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3218,7 +3218,7 @@ case OP_OpenWrite: { if( pOp->p4type==P4_KEYINFO ){ pKeyInfo = pOp->p4.pKeyInfo; pKeyInfo->enc = ENC(p->db); - nField = pKeyInfo->nField+1; + nField = pKeyInfo->nField+pKeyInfo->nXField; }else if( pOp->p4type==P4_INT32 ){ nField = pOp->p4.i; } diff --git a/src/vdbeaux.c b/src/vdbeaux.c index d2e495ea1..68a9fbd51 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -752,10 +752,12 @@ void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){ KeyInfo *pOrig, *pNew; pOrig = (KeyInfo*)zP4; - pOp->p4.pKeyInfo = pNew = sqlite3KeyInfoAlloc(db, pOrig->nField); + pNew = sqlite3KeyInfoAlloc(db, pOrig->nField, pOrig->nXField); + pOp->p4.pKeyInfo = pNew; if( pNew ){ - memcpy(pNew->aColl, pOrig->aColl, pOrig->nField*sizeof(pNew->aColl[0])); - memcpy(pNew->aSortOrder, pOrig->aSortOrder, pOrig->nField); + int n = pOrig->nField+pOrig->nXField; + memcpy(pNew->aColl, pOrig->aColl, n*sizeof(pNew->aColl[0])); + memcpy(pNew->aSortOrder, pOrig->aSortOrder, n); pOp->p4type = P4_KEYINFO; }else{ p->db->mallocFailed = 1; |