aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2013-10-23 13:30:58 +0000
committerdrh <drh@noemail.net>2013-10-23 13:30:58 +0000
commitad124329ab8e45dafc04ca612c87768843d9ed4b (patch)
tree3c114a5fe81269f2e43c2a576527087ba41872fb /src
parentec95c4417559b3f9c0fc43886bed9219c78a48bf (diff)
downloadsqlite-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.c7
-rw-r--r--src/expr.c2
-rw-r--r--src/insert.c8
-rw-r--r--src/select.c21
-rw-r--r--src/sqliteInt.h5
-rw-r--r--src/vdbe.c2
-rw-r--r--src/vdbeaux.c8
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;