aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2013-10-22 14:28:02 +0000
committerdrh <drh@noemail.net>2013-10-22 14:28:02 +0000
commit77e57dfbc8f40ecfdab70be2514165d5c74e914c (patch)
tree133d1eb62075a3493da6910ed50fbf5bd3b868d1 /src
parent42533337e28f0654c7335a3a062d51f2ed81b1fe (diff)
downloadsqlite-77e57dfbc8f40ecfdab70be2514165d5c74e914c.tar.gz
sqlite-77e57dfbc8f40ecfdab70be2514165d5c74e914c.zip
Add a procedure to handle the messy details of allocating an Index object
from the heap. FossilOrigin-Name: 45efc94f9a8169433ffcb4aa35760551c55df4c4
Diffstat (limited to 'src')
-rw-r--r--src/build.c57
-rw-r--r--src/sqliteInt.h1
-rw-r--r--src/where.c12
3 files changed, 41 insertions, 29 deletions
diff --git a/src/build.c b/src/build.c
index cac5c89d4..acd498350 100644
--- a/src/build.c
+++ b/src/build.c
@@ -2516,6 +2516,40 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
}
/*
+** Allocate heap space to hold an Index object with nCol columns.
+**
+** Increase the allocation size to provide an extra nExtra bytes
+** of 8-byte aligned space after the Index object and return a
+** pointer to this extra space in *ppExtra.
+*/
+Index *sqlite3AllocateIndexObject(
+ sqlite3 *db, /* Database connection */
+ int nCol, /* Number of columns in the index */
+ int nExtra, /* Number of bytes of extra space to alloc */
+ char **ppExtra /* Pointer to the "extra" space */
+){
+ Index *p; /* Allocated index object */
+ int nByte; /* Bytes of space for Index object + arrays */
+
+ nByte = ROUND8(sizeof(Index)) + /* Index structure */
+ ROUND8(sizeof(char*)*nCol) + /* Index.azColl */
+ ROUND8(sizeof(tRowcnt)*(nCol+1) + /* Index.aiRowEst */
+ sizeof(int)*nCol + /* Index.aiColumn */
+ sizeof(u8)*nCol); /* Index.aSortOrder */
+ p = sqlite3DbMallocZero(db, nByte + nExtra);
+ if( p ){
+ char *pExtra = ((char*)p)+ROUND8(sizeof(Index));
+ p->azColl = (char**)pExtra; pExtra += ROUND8(sizeof(char*)*nCol);
+ p->aiRowEst = (tRowcnt*)pExtra; pExtra += sizeof(tRowcnt)*(nCol+1);
+ p->aiColumn = (int*)pExtra; pExtra += sizeof(int)*nCol;
+ p->aSortOrder = (u8*)pExtra;
+ p->nColumn = nCol;
+ *ppExtra = ((char*)p) + nByte;
+ }
+ return p;
+}
+
+/*
** Create a new index for an SQL table. pName1.pName2 is the name of the index
** and pTblList is the name of the table that is to be indexed. Both will
** be NULL for a primary key or an index that is created to satisfy a
@@ -2558,7 +2592,6 @@ Index *sqlite3CreateIndex(
Token *pName = 0; /* Unqualified name of the index to create */
struct ExprList_item *pListItem; /* For looping over pList */
const Column *pTabCol; /* A column in the table */
- int nCol; /* Number of columns */
int nExtra = 0; /* Space allocated for zExtra[] */
char *zExtra; /* Extra space after the Index object */
@@ -2730,29 +2763,15 @@ Index *sqlite3CreateIndex(
** Allocate the index structure.
*/
nName = sqlite3Strlen30(zName);
- nCol = pList->nExpr;
- pIndex = sqlite3DbMallocZero(db,
- ROUND8(sizeof(Index)) + /* Index structure */
- ROUND8(sizeof(tRowcnt)*(nCol+1)) + /* Index.aiRowEst */
- sizeof(char *)*nCol + /* Index.azColl */
- sizeof(int)*nCol + /* Index.aiColumn */
- sizeof(u8)*nCol + /* Index.aSortOrder */
- nName + 1 + /* Index.zName */
- nExtra /* Collation sequence names */
- );
+ pIndex = sqlite3AllocateIndexObject(db, pList->nExpr,
+ nName + nExtra + 1, &zExtra);
if( db->mallocFailed ){
goto exit_create_index;
}
- zExtra = (char*)pIndex;
- pIndex->aiRowEst = (tRowcnt*)&zExtra[ROUND8(sizeof(Index))];
- pIndex->azColl = (char**)
- ((char*)pIndex->aiRowEst + ROUND8(sizeof(tRowcnt)*nCol+1));
assert( EIGHT_BYTE_ALIGNMENT(pIndex->aiRowEst) );
assert( EIGHT_BYTE_ALIGNMENT(pIndex->azColl) );
- pIndex->aiColumn = (int *)(&pIndex->azColl[nCol]);
- pIndex->aSortOrder = (u8 *)(&pIndex->aiColumn[nCol]);
- pIndex->zName = (char *)(&pIndex->aSortOrder[nCol]);
- zExtra = (char *)(&pIndex->zName[nName+1]);
+ pIndex->zName = zExtra;
+ zExtra += nName + 1;
memcpy(pIndex->zName, zName, nName+1);
pIndex->pTable = pTab;
pIndex->nColumn = pList->nExpr;
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index e69f274bc..11053b9af 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -2826,6 +2826,7 @@ void sqlite3SrcListShiftJoinType(SrcList*);
void sqlite3SrcListAssignCursors(Parse*, SrcList*);
void sqlite3IdListDelete(sqlite3*, IdList*);
void sqlite3SrcListDelete(sqlite3*, SrcList*);
+Index *sqlite3AllocateIndexObject(sqlite3*,int,int,char**);
Index *sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
Expr*, int, int);
void sqlite3DropIndex(Parse*, SrcList*, int);
diff --git a/src/where.c b/src/where.c
index d89ce6513..d9f4a9c42 100644
--- a/src/where.c
+++ b/src/where.c
@@ -2008,7 +2008,6 @@ static void constructAutomaticIndex(
int nColumn; /* Number of columns in the constructed index */
WhereTerm *pTerm; /* A single term of the WHERE clause */
WhereTerm *pWCEnd; /* End of pWC->a[] */
- int nByte; /* Byte of memory needed for pIdx */
Index *pIdx; /* Object describing the transient index */
Vdbe *v; /* Prepared statement under construction */
int addrInit; /* Address of the initialization bypass jump */
@@ -2021,6 +2020,7 @@ static void constructAutomaticIndex(
int mxBitCol; /* Maximum column in pSrc->colUsed */
CollSeq *pColl; /* Collating sequence to on a column */
WhereLoop *pLoop; /* The Loop object */
+ char *zNotUsed; /* Extra space on the end of pIdx */
Bitmask idxCols; /* Bitmap of columns used for indexing */
Bitmask extraCols; /* Bitmap of additional columns */
u8 sentWarning = 0; /* True if a warnning has been issued */
@@ -2083,18 +2083,10 @@ static void constructAutomaticIndex(
pLoop->wsFlags |= WHERE_COLUMN_EQ | WHERE_IDX_ONLY;
/* Construct the Index object to describe this index */
- nByte = sizeof(Index);
- nByte += nColumn*sizeof(int); /* Index.aiColumn */
- nByte += nColumn*sizeof(char*); /* Index.azColl */
- nByte += nColumn; /* Index.aSortOrder */
- pIdx = sqlite3DbMallocZero(pParse->db, nByte);
+ pIdx = sqlite3AllocateIndexObject(pParse->db, nColumn, 0, &zNotUsed);
if( pIdx==0 ) return;
pLoop->u.btree.pIndex = pIdx;
- pIdx->azColl = (char**)&pIdx[1];
- pIdx->aiColumn = (int*)&pIdx->azColl[nColumn];
- pIdx->aSortOrder = (u8*)&pIdx->aiColumn[nColumn];
pIdx->zName = "auto-index";
- pIdx->nColumn = nColumn;
pIdx->pTable = pTable;
n = 0;
idxCols = 0;