Upgraded bundled sqlite lib to 3.2.2

This commit is contained in:
Ilia Alshanetsky 2005-06-30 20:58:36 +00:00
parent efc6ccaa01
commit 7d02c9dcb2
51 changed files with 5222 additions and 3790 deletions

View file

@ -138,7 +138,7 @@ int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity){
*/
static int binaryCompareP1(Expr *pExpr1, Expr *pExpr2, int jumpIfNull){
char aff = sqlite3ExprAffinity(pExpr2);
return (((int)sqlite3CompareAffinity(pExpr1, aff))<<8)+(jumpIfNull?1:0);
return ((int)sqlite3CompareAffinity(pExpr1, aff))+(jumpIfNull?0x100:0);
}
/*
@ -183,7 +183,12 @@ Expr *sqlite3Expr(int op, Expr *pLeft, Expr *pRight, const Token *pToken){
Expr *pNew;
pNew = sqliteMalloc( sizeof(Expr) );
if( pNew==0 ){
/* When malloc fails, we leak memory from pLeft and pRight */
/* When malloc fails, delete pLeft and pRight. Expressions passed to
** this function must always be allocated with sqlite3Expr() for this
** reason.
*/
sqlite3ExprDelete(pLeft);
sqlite3ExprDelete(pRight);
return 0;
}
pNew->op = op;
@ -260,7 +265,7 @@ void sqlite3ExprSpan(Expr *pExpr, Token *pLeft, Token *pRight){
assert( pLeft->dyn==0 || pLeft->z[pLeft->n]==0 );
if( pLeft->dyn==0 && pRight->dyn==0 ){
pExpr->span.z = pLeft->z;
pExpr->span.n = pRight->n + Addr(pRight->z) - Addr(pLeft->z);
pExpr->span.n = pRight->n + (pRight->z - pLeft->z);
}else{
pExpr->span.z = 0;
}
@ -275,7 +280,7 @@ Expr *sqlite3ExprFunction(ExprList *pList, Token *pToken){
Expr *pNew;
pNew = sqliteMalloc( sizeof(Expr) );
if( pNew==0 ){
/* sqlite3ExprListDelete(pList); // Leak pList when malloc fails */
sqlite3ExprListDelete(pList); /* Avoid leaking memory when malloc fails */
return 0;
}
pNew->op = TK_FUNCTION;
@ -403,6 +408,7 @@ Expr *sqlite3ExprDup(Expr *p){
pNew->pRight = sqlite3ExprDup(p->pRight);
pNew->pList = sqlite3ExprListDup(p->pList);
pNew->pSelect = sqlite3SelectDup(p->pSelect);
pNew->pTab = p->pTab;
return pNew;
}
void sqlite3TokenCopy(Token *pTo, Token *pFrom){
@ -468,14 +474,15 @@ SrcList *sqlite3SrcListDup(SrcList *p){
for(i=0; i<p->nSrc; i++){
struct SrcList_item *pNewItem = &pNew->a[i];
struct SrcList_item *pOldItem = &p->a[i];
Table *pTab;
pNewItem->zDatabase = sqliteStrDup(pOldItem->zDatabase);
pNewItem->zName = sqliteStrDup(pOldItem->zName);
pNewItem->zAlias = sqliteStrDup(pOldItem->zAlias);
pNewItem->jointype = pOldItem->jointype;
pNewItem->iCursor = pOldItem->iCursor;
pNewItem->pTab = pOldItem->pTab;
if( pNewItem->pTab ){
pNewItem->pTab->isTransient = 0;
pTab = pNewItem->pTab = pOldItem->pTab;
if( pTab ){
pTab->nRef++;
}
pNewItem->pSelect = sqlite3SelectDup(pOldItem->pSelect);
pNewItem->pOn = sqlite3ExprDup(pOldItem->pOn);
@ -492,7 +499,10 @@ IdList *sqlite3IdListDup(IdList *p){
if( pNew==0 ) return 0;
pNew->nId = pNew->nAlloc = p->nId;
pNew->a = sqliteMallocRaw( p->nId*sizeof(p->a[0]) );
if( pNew->a==0 ) return 0;
if( pNew->a==0 ){
sqliteFree(pNew);
return 0;
}
for(i=0; i<p->nId; i++){
struct IdList_item *pNewItem = &pNew->a[i];
struct IdList_item *pOldItem = &p->a[i];
@ -520,7 +530,6 @@ Select *sqlite3SelectDup(Select *p){
pNew->iLimit = -1;
pNew->iOffset = -1;
pNew->ppOpenTemp = 0;
pNew->pFetch = 0;
pNew->isResolved = p->isResolved;
pNew->isAgg = p->isAgg;
return pNew;
@ -541,28 +550,34 @@ ExprList *sqlite3ExprListAppend(ExprList *pList, Expr *pExpr, Token *pName){
if( pList==0 ){
pList = sqliteMalloc( sizeof(ExprList) );
if( pList==0 ){
/* sqlite3ExprDelete(pExpr); // Leak memory if malloc fails */
return 0;
goto no_mem;
}
assert( pList->nAlloc==0 );
}
if( pList->nAlloc<=pList->nExpr ){
pList->nAlloc = pList->nAlloc*2 + 4;
pList->a = sqliteRealloc(pList->a, pList->nAlloc*sizeof(pList->a[0]));
if( pList->a==0 ){
/* sqlite3ExprDelete(pExpr); // Leak memory if malloc fails */
pList->nExpr = pList->nAlloc = 0;
return pList;
struct ExprList_item *a;
int n = pList->nAlloc*2 + 4;
a = sqliteRealloc(pList->a, n*sizeof(pList->a[0]));
if( a==0 ){
goto no_mem;
}
pList->a = a;
pList->nAlloc = n;
}
assert( pList->a!=0 );
if( pExpr || pName ){
struct ExprList_item *pItem = &pList->a[pList->nExpr++];
memset(pItem, 0, sizeof(*pItem));
pItem->pExpr = pExpr;
pItem->zName = sqlite3NameFromToken(pName);
pItem->pExpr = pExpr;
}
return pList;
no_mem:
/* Avoid leaking memory if malloc has failed. */
sqlite3ExprDelete(pExpr);
sqlite3ExprListDelete(pList);
return 0;
}
/*
@ -768,7 +783,7 @@ static int lookupName(
zTab = sqlite3NameFromToken(pTableToken);
zCol = sqlite3NameFromToken(pColumnToken);
if( sqlite3_malloc_failed ){
return 1; /* Leak memory (zDb and zTab) if malloc fails */
goto lookupname_end;
}
pExpr->iTable = -1;
@ -776,7 +791,6 @@ static int lookupName(
SrcList *pSrcList = pNC->pSrcList;
ExprList *pEList = pNC->pEList;
pNC->nRef++;
/* assert( zTab==0 || pEList==0 ); */
if( pSrcList ){
for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){
@ -804,6 +818,7 @@ static int lookupName(
}
for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){
if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
IdList *pUsing;
cnt++;
pExpr->iTable = pItem->iCursor;
pMatch = pItem;
@ -812,6 +827,25 @@ static int lookupName(
pExpr->iColumn = j==pTab->iPKey ? -1 : j;
pExpr->affinity = pTab->aCol[j].affinity;
pExpr->pColl = pTab->aCol[j].pColl;
if( pItem->jointype & JT_NATURAL ){
/* If this match occurred in the left table of a natural join,
** then skip the right table to avoid a duplicate match */
pItem++;
i++;
}
if( (pUsing = pItem->pUsing)!=0 ){
/* If this match occurs on a column that is in the USING clause
** of a join, skip the search of the right table of the join
** to avoid a duplicate match there. */
int k;
for(k=0; k<pUsing->nId; k++){
if( sqlite3StrICmp(pUsing->a[k].zName, zCol)==0 ){
pItem++;
i++;
break;
}
}
}
break;
}
}
@ -847,6 +881,7 @@ static int lookupName(
pExpr->iColumn = j==pTab->iPKey ? -1 : j;
pExpr->affinity = pTab->aCol[j].affinity;
pExpr->pColl = pTab->aCol[j].pColl;
pExpr->pTab = pTab;
break;
}
}
@ -883,9 +918,9 @@ static int lookupName(
pExpr->op = TK_AS;
pExpr->iColumn = j;
pExpr->pLeft = sqlite3ExprDup(pEList->a[j].pExpr);
sqliteFree(zCol);
cnt = 1;
assert( zTab==0 && zDb==0 );
return 0;
goto lookupname_end_2;
}
}
}
@ -904,6 +939,9 @@ static int lookupName(
** Z is a string literal if it doesn't match any column names. In that
** case, we need to return right away and not make any changes to
** pExpr.
**
** Because no reference was made to outer contexts, the pNC->nRef
** fields are not changed in any context.
*/
if( cnt==0 && zTab==0 && pColumnToken->z[0]=='"' ){
sqliteFree(zCol);
@ -945,63 +983,35 @@ static int lookupName(
pMatch->colUsed |= 1<<n;
}
lookupname_end:
/* Clean up and return
*/
sqliteFree(zDb);
sqliteFree(zTab);
sqliteFree(zCol);
sqlite3ExprDelete(pExpr->pLeft);
pExpr->pLeft = 0;
sqlite3ExprDelete(pExpr->pRight);
pExpr->pRight = 0;
pExpr->op = TK_COLUMN;
lookupname_end_2:
sqliteFree(zCol);
if( cnt==1 ){
assert( pNC!=0 );
sqlite3AuthRead(pParse, pExpr, pNC->pSrcList);
}
return cnt!=1;
}
/*
** pExpr is a node that defines a function of some kind. It might
** be a syntactic function like "count(x)" or it might be a function
** that implements an operator, like "a LIKE b".
**
** This routine makes *pzName point to the name of the function and
** *pnName hold the number of characters in the function name.
*/
static void getFunctionName(Expr *pExpr, const char **pzName, int *pnName){
switch( pExpr->op ){
case TK_FUNCTION: {
*pzName = pExpr->token.z;
*pnName = pExpr->token.n;
break;
if( pMatch && !pMatch->pSelect ){
pExpr->pTab = pMatch->pTab;
}
case TK_LIKE: {
*pzName = "like";
*pnName = 4;
break;
}
case TK_GLOB: {
*pzName = "glob";
*pnName = 4;
break;
}
case TK_CTIME: {
*pzName = "current_time";
*pnName = 12;
break;
}
case TK_CDATE: {
*pzName = "current_date";
*pnName = 12;
break;
}
case TK_CTIMESTAMP: {
*pzName = "current_timestamp";
*pnName = 17;
break;
/* Increment the nRef value on all name contexts from TopNC up to
** the point where the name matched. */
for(;;){
assert( pTopNC!=0 );
pTopNC->nRef++;
if( pTopNC==pNC ) break;
pTopNC = pTopNC->pNext;
}
return 0;
} else {
return 1;
}
}
@ -1079,11 +1089,7 @@ static int nameResolverStep(void *pArg, Expr *pExpr){
/* Resolve function names
*/
case TK_CTIME:
case TK_CTIMESTAMP:
case TK_CDATE:
case TK_GLOB:
case TK_LIKE:
case TK_CONST_FUNC:
case TK_FUNCTION: {
ExprList *pList = pExpr->pList; /* The argument list */
int n = pList ? pList->nExpr : 0; /* Number of arguments */
@ -1096,7 +1102,8 @@ static int nameResolverStep(void *pArg, Expr *pExpr){
FuncDef *pDef; /* Information about the function */
int enc = pParse->db->enc; /* The database encoding */
getFunctionName(pExpr, &zId, &nId);
zId = pExpr->token.z;
nId = pExpr->token.n;
pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
if( pDef==0 ){
pDef = sqlite3FindFunction(pParse->db, zId, nId, -1, enc, 0);
@ -1302,8 +1309,7 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
/* Evaluate the expression and insert it into the temp table */
sqlite3ExprCode(pParse, pE2);
sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &affinity, 1);
sqlite3VdbeAddOp(v, OP_String8, 0, 0);
sqlite3VdbeAddOp(v, OP_PutStrKey, pExpr->iTable, 0);
sqlite3VdbeAddOp(v, OP_IdxInsert, pExpr->iTable, 0);
}
}
sqlite3VdbeChangeP3(v, addr, (void *)&keyInfo, P3_KEYINFO);
@ -1375,7 +1381,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
int op;
if( v==0 ) return;
if( pExpr==0 ){
sqlite3VdbeAddOp(v, OP_String8, 0, 0); /* Empty expression evals to NULL */
sqlite3VdbeAddOp(v, OP_Null, 0, 0);
return;
}
op = pExpr->op;
@ -1385,13 +1391,9 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
sqlite3VdbeAddOp(v, OP_AggGet, pExpr->iAggCtx, pExpr->iAgg);
}else if( pExpr->iColumn>=0 ){
sqlite3VdbeAddOp(v, OP_Column, pExpr->iTable, pExpr->iColumn);
#ifndef NDEBUG
if( pExpr->span.z && pExpr->span.n>0 && pExpr->span.n<100 ){
VdbeComment((v, "# %T", &pExpr->span));
}
#endif
sqlite3ColumnDefault(v, pExpr->pTab, pExpr->iColumn);
}else{
sqlite3VdbeAddOp(v, OP_Recno, pExpr->iTable, 0);
sqlite3VdbeAddOp(v, OP_Rowid, pExpr->iTable, 0);
}
break;
}
@ -1407,6 +1409,10 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
sqlite3VdbeDequoteP3(v, -1);
break;
}
case TK_NULL: {
sqlite3VdbeAddOp(v, OP_Null, 0, 0);
break;
}
#ifndef SQLITE_OMIT_BLOB_LITERAL
case TK_BLOB: {
assert( TK_BLOB==OP_HexBlob );
@ -1415,10 +1421,6 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
break;
}
#endif
case TK_NULL: {
sqlite3VdbeAddOp(v, OP_String8, 0, 0);
break;
}
case TK_VARIABLE: {
sqlite3VdbeAddOp(v, OP_Variable, pExpr->iTable, 0);
if( pExpr->token.n>1 ){
@ -1516,11 +1518,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
sqlite3VdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg);
break;
}
case TK_CDATE:
case TK_CTIME:
case TK_CTIMESTAMP:
case TK_GLOB:
case TK_LIKE:
case TK_CONST_FUNC:
case TK_FUNCTION: {
ExprList *pList = pExpr->pList;
int nExpr = pList ? pList->nExpr : 0;
@ -1531,7 +1529,8 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
int i;
u8 enc = pParse->db->enc;
CollSeq *pColl = 0;
getFunctionName(pExpr, &zId, &nId);
zId = pExpr->token.z;
nId = pExpr->token.n;
pDef = sqlite3FindFunction(pParse->db, zId, nId, nExpr, enc, 0);
assert( pDef!=0 );
nExpr = sqlite3ExprCodeExprList(pParse, pList);
@ -1578,7 +1577,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
addr = sqlite3VdbeCurrentAddr(v);
sqlite3VdbeAddOp(v, OP_NotNull, -1, addr+4); /* addr + 0 */
sqlite3VdbeAddOp(v, OP_Pop, 2, 0);
sqlite3VdbeAddOp(v, OP_String8, 0, 0);
sqlite3VdbeAddOp(v, OP_Null, 0, 0);
sqlite3VdbeAddOp(v, OP_Goto, 0, addr+7);
sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &affinity, 1); /* addr + 4 */
sqlite3VdbeAddOp(v, OP_Found, pExpr->iTable, addr+7);
@ -1648,7 +1647,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
if( pExpr->pRight ){
sqlite3ExprCode(pParse, pExpr->pRight);
}else{
sqlite3VdbeAddOp(v, OP_String8, 0, 0);
sqlite3VdbeAddOp(v, OP_Null, 0, 0);
}
sqlite3VdbeResolveLabel(v, expr_end_label);
break;
@ -2070,104 +2069,3 @@ int sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){
walkExprTree(pExpr, analyzeAggregate, pNC);
return pNC->pParse->nErr - nErr;
}
/*
** Locate a user function given a name, a number of arguments and a flag
** indicating whether the function prefers UTF-16 over UTF-8. Return a
** pointer to the FuncDef structure that defines that function, or return
** NULL if the function does not exist.
**
** If the createFlag argument is true, then a new (blank) FuncDef
** structure is created and liked into the "db" structure if a
** no matching function previously existed. When createFlag is true
** and the nArg parameter is -1, then only a function that accepts
** any number of arguments will be returned.
**
** If createFlag is false and nArg is -1, then the first valid
** function found is returned. A function is valid if either xFunc
** or xStep is non-zero.
**
** If createFlag is false, then a function with the required name and
** number of arguments may be returned even if the eTextRep flag does not
** match that requested.
*/
FuncDef *sqlite3FindFunction(
sqlite3 *db, /* An open database */
const char *zName, /* Name of the function. Not null-terminated */
int nName, /* Number of characters in the name */
int nArg, /* Number of arguments. -1 means any number */
u8 enc, /* Preferred text encoding */
int createFlag /* Create new entry if true and does not otherwise exist */
){
FuncDef *p; /* Iterator variable */
FuncDef *pFirst; /* First function with this name */
FuncDef *pBest = 0; /* Best match found so far */
int bestmatch = 0;
assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
if( nArg<-1 ) nArg = -1;
pFirst = (FuncDef*)sqlite3HashFind(&db->aFunc, zName, nName);
for(p=pFirst; p; p=p->pNext){
/* During the search for the best function definition, bestmatch is set
** as follows to indicate the quality of the match with the definition
** pointed to by pBest:
**
** 0: pBest is NULL. No match has been found.
** 1: A variable arguments function that prefers UTF-8 when a UTF-16
** encoding is requested, or vice versa.
** 2: A variable arguments function that uses UTF-16BE when UTF-16LE is
** requested, or vice versa.
** 3: A variable arguments function using the same text encoding.
** 4: A function with the exact number of arguments requested that
** prefers UTF-8 when a UTF-16 encoding is requested, or vice versa.
** 5: A function with the exact number of arguments requested that
** prefers UTF-16LE when UTF-16BE is requested, or vice versa.
** 6: An exact match.
**
** A larger value of 'matchqual' indicates a more desirable match.
*/
if( p->nArg==-1 || p->nArg==nArg || nArg==-1 ){
int match = 1; /* Quality of this match */
if( p->nArg==nArg || nArg==-1 ){
match = 4;
}
if( enc==p->iPrefEnc ){
match += 2;
}
else if( (enc==SQLITE_UTF16LE && p->iPrefEnc==SQLITE_UTF16BE) ||
(enc==SQLITE_UTF16BE && p->iPrefEnc==SQLITE_UTF16LE) ){
match += 1;
}
if( match>bestmatch ){
pBest = p;
bestmatch = match;
}
}
}
/* If the createFlag parameter is true, and the seach did not reveal an
** exact match for the name, number of arguments and encoding, then add a
** new entry to the hash table and return it.
*/
if( createFlag && bestmatch<6 &&
(pBest = sqliteMalloc(sizeof(*pBest)+nName+1)) ){
pBest->nArg = nArg;
pBest->pNext = pFirst;
pBest->zName = (char*)&pBest[1];
pBest->iPrefEnc = enc;
memcpy(pBest->zName, zName, nName);
pBest->zName[nName] = 0;
if( pBest==sqlite3HashInsert(&db->aFunc,pBest->zName,nName,(void*)pBest) ){
sqliteFree(pBest);
return 0;
}
}
if( pBest && (pBest->xStep || pBest->xFunc || createFlag) ){
return pBest;
}
return 0;
}