mirror of
https://github.com/php/php-src.git
synced 2025-08-19 17:04:47 +02:00
Upgraded bunbled SQLite lib to 3.3.7
This commit is contained in:
parent
0091c7e1b3
commit
e8f30d4502
83 changed files with 17306 additions and 7930 deletions
|
@ -75,12 +75,10 @@ CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
|
|||
char sqlite3CompareAffinity(Expr *pExpr, char aff2){
|
||||
char aff1 = sqlite3ExprAffinity(pExpr);
|
||||
if( aff1 && aff2 ){
|
||||
/* Both sides of the comparison are columns. If one has numeric or
|
||||
** integer affinity, use that. Otherwise use no affinity.
|
||||
/* Both sides of the comparison are columns. If one has numeric
|
||||
** affinity, use that. Otherwise use no affinity.
|
||||
*/
|
||||
if( aff1==SQLITE_AFF_INTEGER || aff2==SQLITE_AFF_INTEGER ){
|
||||
return SQLITE_AFF_INTEGER;
|
||||
}else if( aff1==SQLITE_AFF_NUMERIC || aff2==SQLITE_AFF_NUMERIC ){
|
||||
if( sqlite3IsNumericAffinity(aff1) || sqlite3IsNumericAffinity(aff2) ){
|
||||
return SQLITE_AFF_NUMERIC;
|
||||
}else{
|
||||
return SQLITE_AFF_NONE;
|
||||
|
@ -89,7 +87,6 @@ char sqlite3CompareAffinity(Expr *pExpr, char aff2){
|
|||
/* Neither side of the comparison is a column. Compare the
|
||||
** results directly.
|
||||
*/
|
||||
/* return SQLITE_AFF_NUMERIC; // Ticket #805 */
|
||||
return SQLITE_AFF_NONE;
|
||||
}else{
|
||||
/* One side is a column, the other is not. Use the columns affinity. */
|
||||
|
@ -129,11 +126,14 @@ static char comparisonAffinity(Expr *pExpr){
|
|||
*/
|
||||
int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity){
|
||||
char aff = comparisonAffinity(pExpr);
|
||||
return
|
||||
(aff==SQLITE_AFF_NONE) ||
|
||||
(aff==SQLITE_AFF_NUMERIC && idx_affinity==SQLITE_AFF_INTEGER) ||
|
||||
(aff==SQLITE_AFF_INTEGER && idx_affinity==SQLITE_AFF_NUMERIC) ||
|
||||
(aff==idx_affinity);
|
||||
switch( aff ){
|
||||
case SQLITE_AFF_NONE:
|
||||
return 1;
|
||||
case SQLITE_AFF_TEXT:
|
||||
return idx_affinity==SQLITE_AFF_TEXT;
|
||||
default:
|
||||
return sqlite3IsNumericAffinity(idx_affinity);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -211,6 +211,19 @@ Expr *sqlite3Expr(int op, Expr *pLeft, Expr *pRight, const Token *pToken){
|
|||
return pNew;
|
||||
}
|
||||
|
||||
/*
|
||||
** Works like sqlite3Expr() but frees its pLeft and pRight arguments
|
||||
** if it fails due to a malloc problem.
|
||||
*/
|
||||
Expr *sqlite3ExprOrFree(int op, Expr *pLeft, Expr *pRight, const Token *pToken){
|
||||
Expr *pNew = sqlite3Expr(op, pLeft, pRight, pToken);
|
||||
if( pNew==0 ){
|
||||
sqlite3ExprDelete(pLeft);
|
||||
sqlite3ExprDelete(pRight);
|
||||
}
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/*
|
||||
** When doing a nested parse, you can include terms in an expression
|
||||
** that look like this: #0 #1 #2 ... These terms refer to elements
|
||||
|
@ -235,7 +248,7 @@ Expr *sqlite3RegisterExpr(Parse *pParse, Token *pToken){
|
|||
if( p==0 ){
|
||||
return 0; /* Malloc failed */
|
||||
}
|
||||
depth = atoi(&pToken->z[1]);
|
||||
depth = atoi((char*)&pToken->z[1]);
|
||||
p->iTable = pParse->nMem++;
|
||||
sqlite3VdbeAddOp(v, OP_Dup, depth, 0);
|
||||
sqlite3VdbeAddOp(v, OP_MemStore, p->iTable, 1);
|
||||
|
@ -263,7 +276,7 @@ Expr *sqlite3ExprAnd(Expr *pLeft, Expr *pRight){
|
|||
void sqlite3ExprSpan(Expr *pExpr, Token *pLeft, Token *pRight){
|
||||
assert( pRight!=0 );
|
||||
assert( pLeft!=0 );
|
||||
if( !sqlite3_malloc_failed && pRight->z && pLeft->z ){
|
||||
if( !sqlite3MallocFailed() && pRight->z && pLeft->z ){
|
||||
assert( pLeft->dyn==0 || pLeft->z[pLeft->n]==0 );
|
||||
if( pLeft->dyn==0 && pRight->dyn==0 ){
|
||||
pExpr->span.z = pLeft->z;
|
||||
|
@ -280,6 +293,7 @@ void sqlite3ExprSpan(Expr *pExpr, Token *pLeft, Token *pRight){
|
|||
*/
|
||||
Expr *sqlite3ExprFunction(ExprList *pList, Token *pToken){
|
||||
Expr *pNew;
|
||||
assert( pToken );
|
||||
pNew = sqliteMalloc( sizeof(Expr) );
|
||||
if( pNew==0 ){
|
||||
sqlite3ExprListDelete(pList); /* Avoid leaking memory when malloc fails */
|
||||
|
@ -287,12 +301,8 @@ Expr *sqlite3ExprFunction(ExprList *pList, Token *pToken){
|
|||
}
|
||||
pNew->op = TK_FUNCTION;
|
||||
pNew->pList = pList;
|
||||
if( pToken ){
|
||||
assert( pToken->dyn==0 );
|
||||
pNew->token = *pToken;
|
||||
}else{
|
||||
pNew->token.z = 0;
|
||||
}
|
||||
assert( pToken->dyn==0 );
|
||||
pNew->token = *pToken;
|
||||
pNew->span = pNew->token;
|
||||
return pNew;
|
||||
}
|
||||
|
@ -327,7 +337,7 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){
|
|||
/* Wildcard of the form "?nnn". Convert "nnn" to an integer and
|
||||
** use it as the variable number */
|
||||
int i;
|
||||
pExpr->iTable = i = atoi(&pToken->z[1]);
|
||||
pExpr->iTable = i = atoi((char*)&pToken->z[1]);
|
||||
if( i<1 || i>SQLITE_MAX_VARIABLE_NUMBER ){
|
||||
sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d",
|
||||
SQLITE_MAX_VARIABLE_NUMBER);
|
||||
|
@ -355,10 +365,10 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){
|
|||
pExpr->iTable = ++pParse->nVar;
|
||||
if( pParse->nVarExpr>=pParse->nVarExprAlloc-1 ){
|
||||
pParse->nVarExprAlloc += pParse->nVarExprAlloc + 10;
|
||||
sqlite3ReallocOrFree((void**)&pParse->apVarExpr,
|
||||
sqliteReallocOrFree((void**)&pParse->apVarExpr,
|
||||
pParse->nVarExprAlloc*sizeof(pParse->apVarExpr[0]) );
|
||||
}
|
||||
if( !sqlite3_malloc_failed ){
|
||||
if( !sqlite3MallocFailed() ){
|
||||
assert( pParse->apVarExpr!=0 );
|
||||
pParse->apVarExpr[pParse->nVarExpr++] = pExpr;
|
||||
}
|
||||
|
@ -415,7 +425,7 @@ Expr *sqlite3ExprDup(Expr *p){
|
|||
if( pNew==0 ) return 0;
|
||||
memcpy(pNew, p, sizeof(*pNew));
|
||||
if( p->token.z!=0 ){
|
||||
pNew->token.z = sqliteStrNDup(p->token.z, p->token.n);
|
||||
pNew->token.z = (u8*)sqliteStrNDup((char*)p->token.z, p->token.n);
|
||||
pNew->token.dyn = 1;
|
||||
}else{
|
||||
assert( pNew->token.z==0 );
|
||||
|
@ -432,7 +442,7 @@ void sqlite3TokenCopy(Token *pTo, Token *pFrom){
|
|||
if( pTo->dyn ) sqliteFree((char*)pTo->z);
|
||||
if( pFrom->z ){
|
||||
pTo->n = pFrom->n;
|
||||
pTo->z = sqliteStrNDup(pFrom->z, pFrom->n);
|
||||
pTo->z = (u8*)sqliteStrNDup((char*)pFrom->z, pFrom->n);
|
||||
pTo->dyn = 1;
|
||||
}else{
|
||||
pTo->z = 0;
|
||||
|
@ -462,7 +472,8 @@ ExprList *sqlite3ExprListDup(ExprList *p){
|
|||
sqlite3TokenCopy(&pNewExpr->span, &pOldExpr->span);
|
||||
}
|
||||
assert( pNewExpr==0 || pNewExpr->span.z!=0
|
||||
|| pOldExpr->span.z==0 || sqlite3_malloc_failed );
|
||||
|| pOldExpr->span.z==0
|
||||
|| sqlite3MallocFailed() );
|
||||
pItem->zName = sqliteStrDup(pOldItem->zName);
|
||||
pItem->sortOrder = pOldItem->sortOrder;
|
||||
pItem->isAgg = pOldItem->isAgg;
|
||||
|
@ -497,6 +508,7 @@ SrcList *sqlite3SrcListDup(SrcList *p){
|
|||
pNewItem->zAlias = sqliteStrDup(pOldItem->zAlias);
|
||||
pNewItem->jointype = pOldItem->jointype;
|
||||
pNewItem->iCursor = pOldItem->iCursor;
|
||||
pNewItem->isPopulated = pOldItem->isPopulated;
|
||||
pTab = pNewItem->pTab = pOldItem->pTab;
|
||||
if( pTab ){
|
||||
pTab->nRef++;
|
||||
|
@ -548,12 +560,12 @@ Select *sqlite3SelectDup(Select *p){
|
|||
pNew->iOffset = -1;
|
||||
pNew->isResolved = p->isResolved;
|
||||
pNew->isAgg = p->isAgg;
|
||||
pNew->usesVirt = 0;
|
||||
pNew->usesEphm = 0;
|
||||
pNew->disallowOrderBy = 0;
|
||||
pNew->pRightmost = 0;
|
||||
pNew->addrOpenVirt[0] = -1;
|
||||
pNew->addrOpenVirt[1] = -1;
|
||||
pNew->addrOpenVirt[2] = -1;
|
||||
pNew->addrOpenEphm[0] = -1;
|
||||
pNew->addrOpenEphm[1] = -1;
|
||||
pNew->addrOpenEphm[2] = -1;
|
||||
return pNew;
|
||||
}
|
||||
#else
|
||||
|
@ -752,7 +764,7 @@ int sqlite3ExprIsConstantOrFunction(Expr *p){
|
|||
int sqlite3ExprIsInteger(Expr *p, int *pValue){
|
||||
switch( p->op ){
|
||||
case TK_INTEGER: {
|
||||
if( sqlite3GetInt32(p->token.z, pValue) ){
|
||||
if( sqlite3GetInt32((char*)p->token.z, pValue) ){
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
@ -809,7 +821,7 @@ int sqlite3IsRowid(const char *z){
|
|||
** in pParse and return non-zero. Return zero on success.
|
||||
*/
|
||||
static int lookupName(
|
||||
Parse *pParse, /* The parsing context */
|
||||
Parse *pParse, /* The parsing context */
|
||||
Token *pDbToken, /* Name of the database containing table, or NULL */
|
||||
Token *pTableToken, /* Name of table containing column, or NULL */
|
||||
Token *pColumnToken, /* Name of the column. */
|
||||
|
@ -831,22 +843,24 @@ static int lookupName(
|
|||
zDb = sqlite3NameFromToken(pDbToken);
|
||||
zTab = sqlite3NameFromToken(pTableToken);
|
||||
zCol = sqlite3NameFromToken(pColumnToken);
|
||||
if( sqlite3_malloc_failed ){
|
||||
if( sqlite3MallocFailed() ){
|
||||
goto lookupname_end;
|
||||
}
|
||||
|
||||
pExpr->iTable = -1;
|
||||
while( pNC && cnt==0 ){
|
||||
ExprList *pEList;
|
||||
SrcList *pSrcList = pNC->pSrcList;
|
||||
ExprList *pEList = pNC->pEList;
|
||||
|
||||
/* assert( zTab==0 || pEList==0 ); */
|
||||
if( pSrcList ){
|
||||
for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){
|
||||
Table *pTab = pItem->pTab;
|
||||
Table *pTab;
|
||||
int iDb;
|
||||
Column *pCol;
|
||||
|
||||
if( pTab==0 ) continue;
|
||||
pTab = pItem->pTab;
|
||||
assert( pTab!=0 );
|
||||
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
|
||||
assert( pTab->nCol>0 );
|
||||
if( zTab ){
|
||||
if( pItem->zAlias ){
|
||||
|
@ -855,27 +869,28 @@ static int lookupName(
|
|||
}else{
|
||||
char *zTabName = pTab->zName;
|
||||
if( zTabName==0 || sqlite3StrICmp(zTabName, zTab)!=0 ) continue;
|
||||
if( zDb!=0 && sqlite3StrICmp(db->aDb[pTab->iDb].zName, zDb)!=0 ){
|
||||
if( zDb!=0 && sqlite3StrICmp(db->aDb[iDb].zName, zDb)!=0 ){
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( 0==(cntTab++) ){
|
||||
pExpr->iTable = pItem->iCursor;
|
||||
pExpr->iDb = pTab->iDb;
|
||||
pExpr->pSchema = pTab->pSchema;
|
||||
pMatch = pItem;
|
||||
}
|
||||
for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){
|
||||
if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
|
||||
const char *zColl = pTab->aCol[j].zColl;
|
||||
IdList *pUsing;
|
||||
cnt++;
|
||||
pExpr->iTable = pItem->iCursor;
|
||||
pMatch = pItem;
|
||||
pExpr->iDb = pTab->iDb;
|
||||
pExpr->pSchema = pTab->pSchema;
|
||||
/* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */
|
||||
pExpr->iColumn = j==pTab->iPKey ? -1 : j;
|
||||
pExpr->affinity = pTab->aCol[j].affinity;
|
||||
pExpr->pColl = pTab->aCol[j].pColl;
|
||||
pExpr->pColl = sqlite3FindCollSeq(db, ENC(db), zColl,-1, 0);
|
||||
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 */
|
||||
|
@ -919,17 +934,18 @@ static int lookupName(
|
|||
}
|
||||
|
||||
if( pTab ){
|
||||
int j;
|
||||
int iCol;
|
||||
Column *pCol = pTab->aCol;
|
||||
|
||||
pExpr->iDb = pTab->iDb;
|
||||
pExpr->pSchema = pTab->pSchema;
|
||||
cntTab++;
|
||||
for(j=0; j < pTab->nCol; j++, pCol++) {
|
||||
for(iCol=0; iCol < pTab->nCol; iCol++, pCol++) {
|
||||
if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
|
||||
const char *zColl = pTab->aCol[iCol].zColl;
|
||||
cnt++;
|
||||
pExpr->iColumn = j==pTab->iPKey ? -1 : j;
|
||||
pExpr->affinity = pTab->aCol[j].affinity;
|
||||
pExpr->pColl = pTab->aCol[j].pColl;
|
||||
pExpr->iColumn = iCol==pTab->iPKey ? -1 : iCol;
|
||||
pExpr->affinity = pTab->aCol[iCol].affinity;
|
||||
pExpr->pColl = sqlite3FindCollSeq(db, ENC(db), zColl,-1, 0);
|
||||
pExpr->pTab = pTab;
|
||||
break;
|
||||
}
|
||||
|
@ -959,7 +975,7 @@ static int lookupName(
|
|||
** Note that the expression in the result set should have already been
|
||||
** resolved by the time the WHERE clause is resolved.
|
||||
*/
|
||||
if( cnt==0 && pEList!=0 && zTab==0 ){
|
||||
if( cnt==0 && (pEList = pNC->pEList)!=0 && zTab==0 ){
|
||||
for(j=0; j<pEList->nExpr; j++){
|
||||
char *zAs = pEList->a[j].zName;
|
||||
if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){
|
||||
|
@ -1006,9 +1022,9 @@ static int lookupName(
|
|||
char *zErr;
|
||||
zErr = cnt==0 ? "no such column: %s" : "ambiguous column name: %s";
|
||||
if( zDb ){
|
||||
sqlite3SetString(&z, zDb, ".", zTab, ".", zCol, 0);
|
||||
sqlite3SetString(&z, zDb, ".", zTab, ".", zCol, (char*)0);
|
||||
}else if( zTab ){
|
||||
sqlite3SetString(&z, zTab, ".", zCol, 0);
|
||||
sqlite3SetString(&z, zTab, ".", zCol, (char*)0);
|
||||
}else{
|
||||
z = sqliteStrDup(zCol);
|
||||
}
|
||||
|
@ -1077,20 +1093,19 @@ lookupname_end_2:
|
|||
*/
|
||||
static int nameResolverStep(void *pArg, Expr *pExpr){
|
||||
NameContext *pNC = (NameContext*)pArg;
|
||||
SrcList *pSrcList;
|
||||
Parse *pParse;
|
||||
|
||||
if( pExpr==0 ) return 1;
|
||||
assert( pNC!=0 );
|
||||
pSrcList = pNC->pSrcList;
|
||||
pParse = pNC->pParse;
|
||||
|
||||
if( ExprHasAnyProperty(pExpr, EP_Resolved) ) return 1;
|
||||
ExprSetProperty(pExpr, EP_Resolved);
|
||||
#ifndef NDEBUG
|
||||
if( pSrcList ){
|
||||
if( pNC->pSrcList && pNC->pSrcList->nAlloc>0 ){
|
||||
SrcList *pSrcList = pNC->pSrcList;
|
||||
int i;
|
||||
for(i=0; i<pSrcList->nSrc; i++){
|
||||
for(i=0; i<pNC->pSrcList->nSrc; i++){
|
||||
assert( pSrcList->a[i].iCursor>=0 && pSrcList->a[i].iCursor<pParse->nTab);
|
||||
}
|
||||
}
|
||||
|
@ -1149,9 +1164,9 @@ static int nameResolverStep(void *pArg, Expr *pExpr){
|
|||
int nId; /* Number of characters in function name */
|
||||
const char *zId; /* The function name. */
|
||||
FuncDef *pDef; /* Information about the function */
|
||||
int enc = pParse->db->enc; /* The database encoding */
|
||||
int enc = ENC(pParse->db); /* The database encoding */
|
||||
|
||||
zId = pExpr->token.z;
|
||||
zId = (char*)pExpr->token.z;
|
||||
nId = pExpr->token.n;
|
||||
pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
|
||||
if( pDef==0 ){
|
||||
|
@ -1197,13 +1212,27 @@ static int nameResolverStep(void *pArg, Expr *pExpr){
|
|||
case TK_IN: {
|
||||
if( pExpr->pSelect ){
|
||||
int nRef = pNC->nRef;
|
||||
#ifndef SQLITE_OMIT_CHECK
|
||||
if( pNC->isCheck ){
|
||||
sqlite3ErrorMsg(pParse,"subqueries prohibited in CHECK constraints");
|
||||
}
|
||||
#endif
|
||||
sqlite3SelectResolve(pParse, pExpr->pSelect, pNC);
|
||||
assert( pNC->nRef>=nRef );
|
||||
if( nRef!=pNC->nRef ){
|
||||
ExprSetProperty(pExpr, EP_VarSelect);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
#ifndef SQLITE_OMIT_CHECK
|
||||
case TK_VARIABLE: {
|
||||
if( pNC->isCheck ){
|
||||
sqlite3ErrorMsg(pParse,"parameters prohibited in CHECK constraints");
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1261,17 +1290,16 @@ struct QueryCoder {
|
|||
|
||||
|
||||
/*
|
||||
** Generate code for subqueries and IN operators.
|
||||
** Generate code for scalar subqueries used as an expression
|
||||
** and IN operators. Examples:
|
||||
**
|
||||
** IN operators comes in two forms:
|
||||
** (SELECT a FROM b) -- subquery
|
||||
** EXISTS (SELECT a FROM b) -- EXISTS subquery
|
||||
** x IN (4,5,11) -- IN operator with list on right-hand side
|
||||
** x IN (SELECT a FROM b) -- IN operator with subquery on the right
|
||||
**
|
||||
** expr IN (exprlist)
|
||||
** and
|
||||
** expr IN (SELECT ...)
|
||||
**
|
||||
** The first form is handled by creating a set holding the list
|
||||
** of allowed values. The second form causes the SELECT to generate
|
||||
** a temporary table.
|
||||
** The pExpr parameter describes the expression that contains the IN
|
||||
** operator or subquery.
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_SUBQUERY
|
||||
void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
|
||||
|
@ -1293,7 +1321,7 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
|
|||
int mem = pParse->nMem++;
|
||||
sqlite3VdbeAddOp(v, OP_MemLoad, mem, 0);
|
||||
testAddr = sqlite3VdbeAddOp(v, OP_If, 0, 0);
|
||||
assert( testAddr>0 || sqlite3_malloc_failed );
|
||||
assert( testAddr>0 || sqlite3MallocFailed() );
|
||||
sqlite3VdbeAddOp(v, OP_MemInt, 1, mem);
|
||||
}
|
||||
|
||||
|
@ -1301,7 +1329,7 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
|
|||
case TK_IN: {
|
||||
char affinity;
|
||||
KeyInfo keyInfo;
|
||||
int addr; /* Address of OP_OpenVirtual instruction */
|
||||
int addr; /* Address of OP_OpenEphemeral instruction */
|
||||
|
||||
affinity = sqlite3ExprAffinity(pExpr->pLeft);
|
||||
|
||||
|
@ -1319,7 +1347,7 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
|
|||
** is used.
|
||||
*/
|
||||
pExpr->iTable = pParse->nTab++;
|
||||
addr = sqlite3VdbeAddOp(v, OP_OpenVirtual, pExpr->iTable, 0);
|
||||
addr = sqlite3VdbeAddOp(v, OP_OpenEphemeral, pExpr->iTable, 0);
|
||||
memset(&keyInfo, 0, sizeof(keyInfo));
|
||||
keyInfo.nField = 1;
|
||||
sqlite3VdbeAddOp(v, OP_SetNumColumns, pExpr->iTable, 1);
|
||||
|
@ -1352,7 +1380,7 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
|
|||
struct ExprList_item *pItem;
|
||||
|
||||
if( !affinity ){
|
||||
affinity = SQLITE_AFF_NUMERIC;
|
||||
affinity = SQLITE_AFF_NONE;
|
||||
}
|
||||
keyInfo.aColl[0] = pExpr->pLeft->pColl;
|
||||
|
||||
|
@ -1366,11 +1394,7 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
|
|||
** expression we need to rerun this code each time.
|
||||
*/
|
||||
if( testAddr>0 && !sqlite3ExprIsConstant(pE2) ){
|
||||
VdbeOp *aOp = sqlite3VdbeGetOp(v, testAddr-1);
|
||||
int i;
|
||||
for(i=0; i<3; i++){
|
||||
aOp[i].opcode = OP_Noop;
|
||||
}
|
||||
sqlite3VdbeChangeToNoop(v, testAddr-1, 3);
|
||||
testAddr = 0;
|
||||
}
|
||||
|
||||
|
@ -1390,21 +1414,25 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
|
|||
** value of this select in a memory cell and record the number
|
||||
** of the memory cell in iColumn.
|
||||
*/
|
||||
int sop;
|
||||
static const Token one = { (u8*)"1", 0, 1 };
|
||||
Select *pSel;
|
||||
int iMem;
|
||||
int sop;
|
||||
|
||||
pExpr->iColumn = pParse->nMem++;
|
||||
pExpr->iColumn = iMem = pParse->nMem++;
|
||||
pSel = pExpr->pSelect;
|
||||
if( pExpr->op==TK_SELECT ){
|
||||
sop = SRT_Mem;
|
||||
sqlite3VdbeAddOp(v, OP_MemNull, iMem, 0);
|
||||
VdbeComment((v, "# Init subquery result"));
|
||||
}else{
|
||||
static const Token one = { "1", 0, 1 };
|
||||
sop = SRT_Exists;
|
||||
sqlite3ExprListDelete(pSel->pEList);
|
||||
pSel->pEList = sqlite3ExprListAppend(0,
|
||||
sqlite3Expr(TK_INTEGER, 0, 0, &one), 0);
|
||||
sqlite3VdbeAddOp(v, OP_MemInt, 0, iMem);
|
||||
VdbeComment((v, "# Init EXISTS result"));
|
||||
}
|
||||
sqlite3Select(pParse, pSel, sop, pExpr->iColumn, 0, 0, 0, 0);
|
||||
sqlite3ExprDelete(pSel->pLimit);
|
||||
pSel->pLimit = sqlite3Expr(TK_INTEGER, 0, 0, &one);
|
||||
sqlite3Select(pParse, pSel, sop, iMem, 0, 0, 0, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1444,6 +1472,8 @@ static void codeInteger(Vdbe *v, const char *z, int n){
|
|||
void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
||||
Vdbe *v = pParse->pVdbe;
|
||||
int op;
|
||||
int stackChng = 1; /* Amount of change to stack depth */
|
||||
|
||||
if( v==0 ) return;
|
||||
if( pExpr==0 ){
|
||||
sqlite3VdbeAddOp(v, OP_Null, 0, 0);
|
||||
|
@ -1465,16 +1495,30 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
|||
/* Otherwise, fall thru into the TK_COLUMN case */
|
||||
}
|
||||
case TK_COLUMN: {
|
||||
if( pExpr->iColumn>=0 ){
|
||||
sqlite3VdbeAddOp(v, OP_Column, pExpr->iTable, pExpr->iColumn);
|
||||
sqlite3ColumnDefault(v, pExpr->pTab, pExpr->iColumn);
|
||||
if( pExpr->iTable<0 ){
|
||||
/* This only happens when coding check constraints */
|
||||
assert( pParse->ckOffset>0 );
|
||||
sqlite3VdbeAddOp(v, OP_Dup, pParse->ckOffset-pExpr->iColumn-1, 1);
|
||||
}else if( pExpr->iColumn>=0 ){
|
||||
Table *pTab = pExpr->pTab;
|
||||
int iCol = pExpr->iColumn;
|
||||
int op = (pTab && IsVirtual(pTab)) ? OP_VColumn : OP_Column;
|
||||
sqlite3VdbeAddOp(v, op, pExpr->iTable, iCol);
|
||||
sqlite3ColumnDefault(v, pTab, iCol);
|
||||
#ifndef SQLITE_OMIT_FLOATING_POINT
|
||||
if( pTab && pTab->aCol[iCol].affinity==SQLITE_AFF_REAL ){
|
||||
sqlite3VdbeAddOp(v, OP_RealAffinity, 0, 0);
|
||||
}
|
||||
#endif
|
||||
}else{
|
||||
sqlite3VdbeAddOp(v, OP_Rowid, pExpr->iTable, 0);
|
||||
Table *pTab = pExpr->pTab;
|
||||
int op = (pTab && IsVirtual(pTab)) ? OP_VRowid : OP_Rowid;
|
||||
sqlite3VdbeAddOp(v, op, pExpr->iTable, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TK_INTEGER: {
|
||||
codeInteger(v, pExpr->token.z, pExpr->token.n);
|
||||
codeInteger(v, (char*)pExpr->token.z, pExpr->token.n);
|
||||
break;
|
||||
}
|
||||
case TK_FLOAT:
|
||||
|
@ -1482,7 +1526,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
|||
assert( TK_FLOAT==OP_Real );
|
||||
assert( TK_STRING==OP_String8 );
|
||||
sqlite3DequoteExpr(pExpr);
|
||||
sqlite3VdbeOp3(v, op, 0, 0, pExpr->token.z, pExpr->token.n);
|
||||
sqlite3VdbeOp3(v, op, 0, 0, (char*)pExpr->token.z, pExpr->token.n);
|
||||
break;
|
||||
}
|
||||
case TK_NULL: {
|
||||
|
@ -1495,7 +1539,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
|||
const char *z;
|
||||
assert( TK_BLOB==OP_HexBlob );
|
||||
n = pExpr->token.n - 3;
|
||||
z = pExpr->token.z + 2;
|
||||
z = (char*)pExpr->token.z + 2;
|
||||
assert( n>=0 );
|
||||
if( n==0 ){
|
||||
z = "";
|
||||
|
@ -1507,7 +1551,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
|||
case TK_VARIABLE: {
|
||||
sqlite3VdbeAddOp(v, OP_Variable, pExpr->iTable, 0);
|
||||
if( pExpr->token.n>1 ){
|
||||
sqlite3VdbeChangeP3(v, -1, pExpr->token.z, pExpr->token.n);
|
||||
sqlite3VdbeChangeP3(v, -1, (char*)pExpr->token.z, pExpr->token.n);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1518,16 +1562,17 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
|||
#ifndef SQLITE_OMIT_CAST
|
||||
case TK_CAST: {
|
||||
/* Expressions of the form: CAST(pLeft AS token) */
|
||||
int aff, op;
|
||||
int aff, to_op;
|
||||
sqlite3ExprCode(pParse, pExpr->pLeft);
|
||||
aff = sqlite3AffinityType(&pExpr->token);
|
||||
switch( aff ){
|
||||
case SQLITE_AFF_INTEGER: op = OP_ToInt; break;
|
||||
case SQLITE_AFF_NUMERIC: op = OP_ToNumeric; break;
|
||||
case SQLITE_AFF_TEXT: op = OP_ToText; break;
|
||||
case SQLITE_AFF_NONE: op = OP_ToBlob; break;
|
||||
}
|
||||
sqlite3VdbeAddOp(v, op, 0, 0);
|
||||
to_op = aff - SQLITE_AFF_TEXT + OP_ToText;
|
||||
assert( to_op==OP_ToText || aff!=SQLITE_AFF_TEXT );
|
||||
assert( to_op==OP_ToBlob || aff!=SQLITE_AFF_NONE );
|
||||
assert( to_op==OP_ToNumeric || aff!=SQLITE_AFF_NUMERIC );
|
||||
assert( to_op==OP_ToInt || aff!=SQLITE_AFF_INTEGER );
|
||||
assert( to_op==OP_ToReal || aff!=SQLITE_AFF_REAL );
|
||||
sqlite3VdbeAddOp(v, to_op, 0, 0);
|
||||
stackChng = 0;
|
||||
break;
|
||||
}
|
||||
#endif /* SQLITE_OMIT_CAST */
|
||||
|
@ -1546,6 +1591,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
|||
sqlite3ExprCode(pParse, pExpr->pLeft);
|
||||
sqlite3ExprCode(pParse, pExpr->pRight);
|
||||
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, 0, 0);
|
||||
stackChng = -1;
|
||||
break;
|
||||
}
|
||||
case TK_AND:
|
||||
|
@ -1574,6 +1620,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
|||
sqlite3ExprCode(pParse, pExpr->pLeft);
|
||||
sqlite3ExprCode(pParse, pExpr->pRight);
|
||||
sqlite3VdbeAddOp(v, op, 0, 0);
|
||||
stackChng = -1;
|
||||
break;
|
||||
}
|
||||
case TK_UMINUS: {
|
||||
|
@ -1581,8 +1628,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
|||
assert( pLeft );
|
||||
if( pLeft->op==TK_FLOAT || pLeft->op==TK_INTEGER ){
|
||||
Token *p = &pLeft->token;
|
||||
char *z = sqliteMalloc( p->n + 2 );
|
||||
sprintf(z, "-%.*s", p->n, p->z);
|
||||
char *z = sqlite3MPrintf("-%.*s", p->n, p->z);
|
||||
if( pLeft->op==TK_FLOAT ){
|
||||
sqlite3VdbeOp3(v, OP_Real, 0, 0, z, p->n+1);
|
||||
}else{
|
||||
|
@ -1599,6 +1645,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
|||
assert( TK_NOT==OP_Not );
|
||||
sqlite3ExprCode(pParse, pExpr->pLeft);
|
||||
sqlite3VdbeAddOp(v, op, 0, 0);
|
||||
stackChng = 0;
|
||||
break;
|
||||
}
|
||||
case TK_ISNULL:
|
||||
|
@ -1611,11 +1658,17 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
|||
dest = sqlite3VdbeCurrentAddr(v) + 2;
|
||||
sqlite3VdbeAddOp(v, op, 1, dest);
|
||||
sqlite3VdbeAddOp(v, OP_AddImm, -1, 0);
|
||||
stackChng = 0;
|
||||
break;
|
||||
}
|
||||
case TK_AGG_FUNCTION: {
|
||||
AggInfo *pInfo = pExpr->pAggInfo;
|
||||
sqlite3VdbeAddOp(v, OP_MemLoad, pInfo->aFunc[pExpr->iAgg].iMem, 0);
|
||||
if( pInfo==0 ){
|
||||
sqlite3ErrorMsg(pParse, "misuse of aggregate: %T",
|
||||
&pExpr->span);
|
||||
}else{
|
||||
sqlite3VdbeAddOp(v, OP_MemLoad, pInfo->aFunc[pExpr->iAgg].iMem, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TK_CONST_FUNC:
|
||||
|
@ -1627,13 +1680,32 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
|||
const char *zId;
|
||||
int constMask = 0;
|
||||
int i;
|
||||
u8 enc = pParse->db->enc;
|
||||
u8 enc = ENC(pParse->db);
|
||||
CollSeq *pColl = 0;
|
||||
zId = pExpr->token.z;
|
||||
zId = (char*)pExpr->token.z;
|
||||
nId = pExpr->token.n;
|
||||
pDef = sqlite3FindFunction(pParse->db, zId, nId, nExpr, enc, 0);
|
||||
assert( pDef!=0 );
|
||||
nExpr = sqlite3ExprCodeExprList(pParse, pList);
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
/* Possibly overload the function if the first argument is
|
||||
** a virtual table column.
|
||||
**
|
||||
** For infix functions (LIKE, GLOB, REGEXP, and MATCH) use the
|
||||
** second argument, not the first, as the argument to test to
|
||||
** see if it is a column in a virtual table. This is done because
|
||||
** the left operand of infix functions (the operand we want to
|
||||
** control overloading) ends up as the second argument to the
|
||||
** function. The expression "A glob B" is equivalent to
|
||||
** "glob(B,A). We want to use the A in "A glob B" to test
|
||||
** for function overloading. But we use the B term in "glob(B,A)".
|
||||
*/
|
||||
if( nExpr>=2 && (pExpr->flags & EP_InfixFunc) ){
|
||||
pDef = sqlite3VtabOverloadFunction(pDef, nExpr, pList->a[1].pExpr);
|
||||
}else if( nExpr>0 ){
|
||||
pDef = sqlite3VtabOverloadFunction(pDef, nExpr, pList->a[0].pExpr);
|
||||
}
|
||||
#endif
|
||||
for(i=0; i<nExpr && i<32; i++){
|
||||
if( sqlite3ExprIsConstant(pList->a[i].pExpr) ){
|
||||
constMask |= (1<<i);
|
||||
|
@ -1647,12 +1719,15 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
|||
sqlite3VdbeOp3(v, OP_CollSeq, 0, 0, (char *)pColl, P3_COLLSEQ);
|
||||
}
|
||||
sqlite3VdbeOp3(v, OP_Function, constMask, nExpr, (char*)pDef, P3_FUNCDEF);
|
||||
stackChng = 1-nExpr;
|
||||
break;
|
||||
}
|
||||
#ifndef SQLITE_OMIT_SUBQUERY
|
||||
case TK_EXISTS:
|
||||
case TK_SELECT: {
|
||||
sqlite3CodeSubselect(pParse, pExpr);
|
||||
if( pExpr->iColumn==0 ){
|
||||
sqlite3CodeSubselect(pParse, pExpr);
|
||||
}
|
||||
sqlite3VdbeAddOp(v, OP_MemLoad, pExpr->iColumn, 0);
|
||||
VdbeComment((v, "# load subquery result"));
|
||||
break;
|
||||
|
@ -1660,6 +1735,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
|||
case TK_IN: {
|
||||
int addr;
|
||||
char affinity;
|
||||
int ckOffset = pParse->ckOffset;
|
||||
sqlite3CodeSubselect(pParse, pExpr);
|
||||
|
||||
/* Figure out the affinity to use to create a key from the results
|
||||
|
@ -1669,6 +1745,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
|||
affinity = comparisonAffinity(pExpr);
|
||||
|
||||
sqlite3VdbeAddOp(v, OP_Integer, 1, 0);
|
||||
pParse->ckOffset = ckOffset+1;
|
||||
|
||||
/* Code the <expr> from "<expr> IN (...)". The temporary table
|
||||
** pExpr->iTable contains the values that make up the (...) set.
|
||||
|
@ -1705,6 +1782,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
|||
case TK_UPLUS:
|
||||
case TK_AS: {
|
||||
sqlite3ExprCode(pParse, pExpr->pLeft);
|
||||
stackChng = 0;
|
||||
break;
|
||||
}
|
||||
case TK_CASE: {
|
||||
|
@ -1763,16 +1841,22 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
|
|||
pExpr->iColumn == OE_Fail );
|
||||
sqlite3DequoteExpr(pExpr);
|
||||
sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, pExpr->iColumn,
|
||||
pExpr->token.z, pExpr->token.n);
|
||||
(char*)pExpr->token.z, pExpr->token.n);
|
||||
} else {
|
||||
assert( pExpr->iColumn == OE_Ignore );
|
||||
sqlite3VdbeAddOp(v, OP_ContextPop, 0, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Goto, 0, pParse->trigStack->ignoreJump);
|
||||
VdbeComment((v, "# raise(IGNORE)"));
|
||||
}
|
||||
stackChng = 0;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
if( pParse->ckOffset ){
|
||||
pParse->ckOffset += stackChng;
|
||||
assert( pParse->ckOffset );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1840,6 +1924,7 @@ int sqlite3ExprCodeExprList(
|
|||
void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
||||
Vdbe *v = pParse->pVdbe;
|
||||
int op = 0;
|
||||
int ckOffset = pParse->ckOffset;
|
||||
if( v==0 || pExpr==0 ) return;
|
||||
op = pExpr->op;
|
||||
switch( op ){
|
||||
|
@ -1914,6 +1999,7 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
|||
break;
|
||||
}
|
||||
}
|
||||
pParse->ckOffset = ckOffset;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1927,6 +2013,7 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
|||
void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
||||
Vdbe *v = pParse->pVdbe;
|
||||
int op = 0;
|
||||
int ckOffset = pParse->ckOffset;
|
||||
if( v==0 || pExpr==0 ) return;
|
||||
|
||||
/* The value of pExpr->op and op are related as follows:
|
||||
|
@ -2023,6 +2110,7 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
|||
break;
|
||||
}
|
||||
}
|
||||
pParse->ckOffset = ckOffset;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2031,10 +2119,8 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
|||
*/
|
||||
int sqlite3ExprCompare(Expr *pA, Expr *pB){
|
||||
int i;
|
||||
if( pA==0 ){
|
||||
return pB==0;
|
||||
}else if( pB==0 ){
|
||||
return 0;
|
||||
if( pA==0||pB==0 ){
|
||||
return pB==pA;
|
||||
}
|
||||
if( pA->op!=pB->op ) return 0;
|
||||
if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 0;
|
||||
|
@ -2056,7 +2142,9 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB){
|
|||
if( pA->token.z ){
|
||||
if( pB->token.z==0 ) return 0;
|
||||
if( pB->token.n!=pA->token.n ) return 0;
|
||||
if( sqlite3StrNICmp(pA->token.z, pB->token.z, pB->token.n)!=0 ) return 0;
|
||||
if( sqlite3StrNICmp((char*)pA->token.z,(char*)pB->token.z,pB->token.n)!=0 ){
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -2180,14 +2268,14 @@ static int analyzeAggregate(void *pArg, Expr *pExpr){
|
|||
if( i>=pAggInfo->nFunc ){
|
||||
/* pExpr is original. Make a new entry in pAggInfo->aFunc[]
|
||||
*/
|
||||
u8 enc = pParse->db->enc;
|
||||
u8 enc = ENC(pParse->db);
|
||||
i = addAggInfoFunc(pAggInfo);
|
||||
if( i>=0 ){
|
||||
pItem = &pAggInfo->aFunc[i];
|
||||
pItem->pExpr = pExpr;
|
||||
pItem->iMem = pParse->nMem++;
|
||||
pItem->pFunc = sqlite3FindFunction(pParse->db,
|
||||
pExpr->token.z, pExpr->token.n,
|
||||
(char*)pExpr->token.z, pExpr->token.n,
|
||||
pExpr->pList ? pExpr->pList->nExpr : 0, enc, 0);
|
||||
if( pExpr->flags & EP_Distinct ){
|
||||
pItem->iDistinct = pParse->nTab++;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue