/ Check-in [6c78d2a4]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Expression code generator takes advantage of recent opcode changes. (CVS 4685)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:6c78d2a49a3e6ee8bc31f16488a430cba9eda59d
User & Date: drh 2008-01-05 06:51:30
Context
2008-01-05
16:29
Registerify binary operators. Add register tracing to debugging output. (CVS 4686) check-in: 66396d2f user: drh tags: trunk
06:51
Expression code generator takes advantage of recent opcode changes. (CVS 4685) check-in: 6c78d2a4 user: drh tags: trunk
05:38
Register-ify the OP_ForceInt opcode. (CVS 4684) check-in: 32380dca user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/expr.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
....
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968

1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982

1983
1984
1985
1986
1987
1988
1989
1990
1991

1992
1993
1994
1995

1996
1997
1998
1999
2000
2001

2002
2003
2004
2005

2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019

2020
2021
2022
2023
2024
2025
2026
2027

2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047

2048
2049
2050
2051
2052
2053
2054
....
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107

2108
2109
2110
2111
2112
2113
2114
....
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131

2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
....
2197
2198
2199
2200
2201
2202
2203

2204
2205
2206
2207
2208
2209
2210
2211
2212
....
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
....
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312

2313
2314
2315
2316
2317
2318
2319
....
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
** $Id: expr.c,v 1.332 2008/01/05 05:20:10 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Return the 'affinity' of the expression pExpr if any.
**
................................................................................
** Generate an instruction that will put the floating point
** value described by z[0..n-1] on the stack.
**
** The z[] string will probably not be zero-terminated.  But the 
** z[n] character is guaranteed to be something that does not look
** like the continuation of the number.
*/
static void codeReal(Vdbe *v, const char *z, int n, int negateFlag){
  assert( z || v==0 || sqlite3VdbeDb(v)->mallocFailed );
  if( z ){
    double value;
    char *zV;
    assert( !isdigit(z[n]) );
    sqlite3AtoF(z, &value);
    if( negateFlag ) value = -value;
    zV = dup8bytes(v, (char*)&value);
    sqlite3VdbeAddOp4(v, OP_Real, 0, 0, 0, zV, P4_REAL);
  }
}


/*
** Generate an instruction that will put the integer describe by
** text z[0..n-1] on the stack.
**
** The z[] string will probably not be zero-terminated.  But the 
** z[n] character is guaranteed to be something that does not look
** like the continuation of the number.
*/
static void codeInteger(Vdbe *v, const char *z, int n, int negateFlag){
  assert( z || v==0 || sqlite3VdbeDb(v)->mallocFailed );
  if( z ){
    int i;
    assert( !isdigit(z[n]) );
    if( sqlite3GetInt32(z, &i) ){
      if( negateFlag ) i = -i;
      sqlite3VdbeAddOp1(v, OP_Integer, i);
    }else if( sqlite3FitsIn64Bits(z, negateFlag) ){
      i64 value;
      char *zV;
      sqlite3Atoi64(z, &value);
      if( negateFlag ) value = -value;
      zV = dup8bytes(v, (char*)&value);
      sqlite3VdbeAddOp4(v, OP_Int64, 0, 0, 0, zV, P4_INT64);
    }else{
      codeReal(v, z, n, negateFlag);
    }
  }
}


/*
** Generate code that will extract the iColumn-th column from
................................................................................
** below verify that the numbers are aligned correctly.
*/
int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
  Vdbe *v = pParse->pVdbe;
  int op;
  int inReg = 0;
  int stackChng = 0;
  int subtarget = -1;

  assert( v!=0 || pParse->db->mallocFailed );
  if( v==0 ) return 0;
  if( target<0 ){
    target = ++pParse->nMem;
  }else if( target==0 ){
    stackChng = 1;
    subtarget = 0;
  }

  if( pExpr==0 ){
    op = TK_NULL;
  }else{
    op = pExpr->op;
  }
  switch( op ){
    case TK_AGG_COLUMN: {
      AggInfo *pAggInfo = pExpr->pAggInfo;
      struct AggInfo_col *pCol = &pAggInfo->aCol[pExpr->iAgg];
      if( !pAggInfo->directMode ){
        sqlite3VdbeAddOp1(v, OP_SCopy, pCol->iMem);

        break;
      }else if( pAggInfo->useSortingIdx ){
        sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdx,
                              pCol->iSorterColumn, target);
        inReg = 1;
        break;
      }
      /* Otherwise, fall thru into the TK_COLUMN case */
    }
    case TK_COLUMN: {
      if( pExpr->iTable<0 ){
        /* This only happens when coding check constraints */
        assert( pParse->ckOffset>0 );
        sqlite3VdbeAddOp1(v, OP_SCopy, -(pParse->ckOffset-pExpr->iColumn-1));

      }else{
        sqlite3ExprCodeGetColumn(v, pExpr->pTab,
                                 pExpr->iColumn, pExpr->iTable, target);
        inReg = 1;
      }
      break;
    }
    case TK_INTEGER: {
      codeInteger(v, (char*)pExpr->token.z, pExpr->token.n, 0);

      break;
    }
    case TK_FLOAT: {
      codeReal(v, (char*)pExpr->token.z, pExpr->token.n, 0);

      break;
    }
    case TK_STRING: {
      sqlite3DequoteExpr(pParse->db, pExpr);
      sqlite3VdbeAddOp4(v,OP_String8, 0, 0, 0,
                        (char*)pExpr->token.z, pExpr->token.n);

      break;
    }
    case TK_NULL: {
      sqlite3VdbeAddOp0(v, OP_Null);

      break;
    }
#ifndef SQLITE_OMIT_BLOB_LITERAL
    case TK_BLOB: {
      int n;
      const char *z;
      assert( TK_BLOB==OP_HexBlob );
      n = pExpr->token.n - 3;
      z = (char*)pExpr->token.z + 2;
      assert( n>=0 );
      if( n==0 ){
        z = "";
      }
      sqlite3VdbeAddOp4(v, op, 0, 0, 0, z, n);

      break;
    }
#endif
    case TK_VARIABLE: {
      sqlite3VdbeAddOp1(v, OP_Variable, pExpr->iTable);
      if( pExpr->token.n>1 ){
        sqlite3VdbeChangeP4(v, -1, (char*)pExpr->token.z, pExpr->token.n);
      }

      break;
    }
    case TK_REGISTER: {
      sqlite3VdbeAddOp1(v, OP_SCopy, pExpr->iTable);
      break;
    }
#ifndef SQLITE_OMIT_CAST
    case TK_CAST: {
      /* Expressions of the form:   CAST(pLeft AS token) */
      int aff, to_op;
      sqlite3ExprCode(pParse, pExpr->pLeft, 0);
      aff = sqlite3AffinityType(&pExpr->token);
      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    );
      sqlite3VdbeAddOp0(v, to_op);
      stackChng = 0;

      break;
    }
#endif /* SQLITE_OMIT_CAST */
    case TK_LT:
    case TK_LE:
    case TK_GT:
    case TK_GE:
................................................................................
    }
    case TK_UMINUS: {
      Expr *pLeft = pExpr->pLeft;
      assert( pLeft );
      if( pLeft->op==TK_FLOAT || pLeft->op==TK_INTEGER ){
        Token *p = &pLeft->token;
        if( pLeft->op==TK_FLOAT ){
          codeReal(v, (char*)p->z, p->n, 1);
        }else{
          codeInteger(v, (char*)p->z, p->n, 1);
        }

        break;
      }
      /* Fall through into TK_NOT */
    }
    case TK_BITNOT:
    case TK_NOT: {
      assert( TK_BITNOT==OP_BitNot );
................................................................................
      break;
    }
    case TK_ISNULL:
    case TK_NOTNULL: {
      int dest;
      assert( TK_ISNULL==OP_IsNull );
      assert( TK_NOTNULL==OP_NotNull );
      sqlite3VdbeAddOp1(v, OP_Integer, 1);
      sqlite3ExprCode(pParse, pExpr->pLeft, 0);
      dest = sqlite3VdbeCurrentAddr(v) + 2;
      sqlite3VdbeAddOp2(v, op, 1, dest);
      sqlite3VdbeAddOp2(v, OP_AddImm, 0, -1);
      stackChng = 0;

      break;
    }
    case TK_AGG_FUNCTION: {
      AggInfo *pInfo = pExpr->pAggInfo;
      if( pInfo==0 ){
        sqlite3ErrorMsg(pParse, "misuse of aggregate: %T",
            &pExpr->span);
      }else{
        sqlite3VdbeAddOp1(v, OP_SCopy, pInfo->aFunc[pExpr->iAgg].iMem);
      }
      break;
    }
    case TK_CONST_FUNC:
    case TK_FUNCTION: {
      ExprList *pList = pExpr->pList;
      int nExpr = pList ? pList->nExpr : 0;
................................................................................
    }
#ifndef SQLITE_OMIT_SUBQUERY
    case TK_EXISTS:
    case TK_SELECT: {
      if( pExpr->iColumn==0 ){
        sqlite3CodeSubselect(pParse, pExpr);
      }

      sqlite3VdbeAddOp1(v, OP_SCopy, pExpr->iColumn);
      VdbeComment((v, "load subquery result"));
      break;
    }
    case TK_IN: {
      int addr;
      char affinity;
      int ckOffset = pParse->ckOffset;
      int eType;
................................................................................
      pRight = pLItem->pExpr;
      sqlite3ExprCode(pParse, pRight, 0);
      codeCompare(pParse, pLeft, pRight, OP_Le, 0, 0);
      sqlite3VdbeAddOp0(v, OP_And);
      break;
    }
    case TK_UPLUS: {
      sqlite3ExprCode(pParse, pExpr->pLeft, 0);
      stackChng = 0;
      break;
    }
    case TK_CASE: {
      int expr_end_label;
      int jumpInst;
      int nExpr;
................................................................................
          sqlite3VdbeAddOp1(v, OP_SCopy, -1);
          jumpInst = codeCompare(pParse, pExpr->pLeft, aListelem[i].pExpr,
                                 OP_Ne, 0, 1);
          sqlite3VdbeAddOp1(v, OP_Pop, 1);
        }else{
          jumpInst = sqlite3VdbeAddOp2(v, OP_IfNot, 1, 0);
        }
        sqlite3ExprCode(pParse, aListelem[i+1].pExpr, 0);
        sqlite3VdbeAddOp2(v, OP_Goto, 0, expr_end_label);
        sqlite3VdbeJumpHere(v, jumpInst);
      }
      if( pExpr->pLeft ){
        sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
      }
      if( pExpr->pRight ){
        sqlite3ExprCode(pParse, pExpr->pRight, 0);
      }else{
        sqlite3VdbeAddOp2(v, OP_Null, 0, 0);
      }
      sqlite3VdbeResolveLabel(v, expr_end_label);

      break;
    }
#ifndef SQLITE_OMIT_TRIGGER
    case TK_RAISE: {
      if( !pParse->trigStack ){
        sqlite3ErrorMsg(pParse,
                       "RAISE() may only be used within a trigger-program");
................................................................................
         VdbeComment((v, "raise(IGNORE)"));
      }
      stackChng = 0;
      break;
    }
#endif
  }
  if( target && !inReg ){
    sqlite3VdbeAddOp2(v, OP_Move, 0, target);
    stackChng = 0;
  }
  if( pParse->ckOffset ){
    pParse->ckOffset += stackChng;
    assert( pParse->ckOffset );
  }
  return target;







|







 







|








|












|





|
|
|



|

|

|







 







|







<












|
>




|









>



|




|
>



|
>




|

>



|
>













|
>




|



>



|






|







|

>







 







|

|

>







 







|



|

>








|







 







>
|
|







 







|







 







|







|

|


>







 







|
|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
....
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954

1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
....
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
....
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
....
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
....
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
....
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
....
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
** $Id: expr.c,v 1.333 2008/01/05 06:51:30 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Return the 'affinity' of the expression pExpr if any.
**
................................................................................
** Generate an instruction that will put the floating point
** value described by z[0..n-1] on the stack.
**
** The z[] string will probably not be zero-terminated.  But the 
** z[n] character is guaranteed to be something that does not look
** like the continuation of the number.
*/
static void codeReal(Vdbe *v, const char *z, int n, int negateFlag, int iMem){
  assert( z || v==0 || sqlite3VdbeDb(v)->mallocFailed );
  if( z ){
    double value;
    char *zV;
    assert( !isdigit(z[n]) );
    sqlite3AtoF(z, &value);
    if( negateFlag ) value = -value;
    zV = dup8bytes(v, (char*)&value);
    sqlite3VdbeAddOp4(v, OP_Real, 0, iMem, 0, zV, P4_REAL);
  }
}


/*
** Generate an instruction that will put the integer describe by
** text z[0..n-1] on the stack.
**
** The z[] string will probably not be zero-terminated.  But the 
** z[n] character is guaranteed to be something that does not look
** like the continuation of the number.
*/
static void codeInteger(Vdbe *v, const char *z, int n, int negFlag, int iMem){
  assert( z || v==0 || sqlite3VdbeDb(v)->mallocFailed );
  if( z ){
    int i;
    assert( !isdigit(z[n]) );
    if( sqlite3GetInt32(z, &i) ){
      if( negFlag ) i = -i;
      sqlite3VdbeAddOp2(v, OP_Integer, i, iMem);
    }else if( sqlite3FitsIn64Bits(z, negFlag) ){
      i64 value;
      char *zV;
      sqlite3Atoi64(z, &value);
      if( negFlag ) value = -value;
      zV = dup8bytes(v, (char*)&value);
      sqlite3VdbeAddOp4(v, OP_Int64, 0, iMem, 0, zV, P4_INT64);
    }else{
      codeReal(v, z, n, negFlag, iMem);
    }
  }
}


/*
** Generate code that will extract the iColumn-th column from
................................................................................
** below verify that the numbers are aligned correctly.
*/
int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
  Vdbe *v = pParse->pVdbe;
  int op;
  int inReg = 0;
  int stackChng = 0;
  int origTarget = target;

  assert( v!=0 || pParse->db->mallocFailed );
  if( v==0 ) return 0;
  if( target<0 ){
    target = ++pParse->nMem;
  }else if( target==0 ){
    stackChng = 1;

  }

  if( pExpr==0 ){
    op = TK_NULL;
  }else{
    op = pExpr->op;
  }
  switch( op ){
    case TK_AGG_COLUMN: {
      AggInfo *pAggInfo = pExpr->pAggInfo;
      struct AggInfo_col *pCol = &pAggInfo->aCol[pExpr->iAgg];
      if( !pAggInfo->directMode ){
        assert( pCol->iMem>0 );
        inReg = pCol->iMem;
        break;
      }else if( pAggInfo->useSortingIdx ){
        sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdx,
                              pCol->iSorterColumn, target);
        inReg = target;
        break;
      }
      /* Otherwise, fall thru into the TK_COLUMN case */
    }
    case TK_COLUMN: {
      if( pExpr->iTable<0 ){
        /* This only happens when coding check constraints */
        assert( pParse->ckOffset>0 );
        sqlite3VdbeAddOp1(v, OP_SCopy, -(pParse->ckOffset-pExpr->iColumn-1));
        /* inReg = -(pParse->ckOffset-pExpr->iColumn-1); */
      }else{
        sqlite3ExprCodeGetColumn(v, pExpr->pTab,
                                 pExpr->iColumn, pExpr->iTable, target);
        inReg = target;
      }
      break;
    }
    case TK_INTEGER: {
      codeInteger(v, (char*)pExpr->token.z, pExpr->token.n, 0, target);
      inReg = target;
      break;
    }
    case TK_FLOAT: {
      codeReal(v, (char*)pExpr->token.z, pExpr->token.n, 0, target);
      inReg = target;
      break;
    }
    case TK_STRING: {
      sqlite3DequoteExpr(pParse->db, pExpr);
      sqlite3VdbeAddOp4(v,OP_String8, 0, target, 0,
                        (char*)pExpr->token.z, pExpr->token.n);
      inReg = target;
      break;
    }
    case TK_NULL: {
      sqlite3VdbeAddOp2(v, OP_Null, 0, target);
      inReg = target;
      break;
    }
#ifndef SQLITE_OMIT_BLOB_LITERAL
    case TK_BLOB: {
      int n;
      const char *z;
      assert( TK_BLOB==OP_HexBlob );
      n = pExpr->token.n - 3;
      z = (char*)pExpr->token.z + 2;
      assert( n>=0 );
      if( n==0 ){
        z = "";
      }
      sqlite3VdbeAddOp4(v, op, 0, target, 0, z, n);
      inReg = target;
      break;
    }
#endif
    case TK_VARIABLE: {
      sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iTable, target);
      if( pExpr->token.n>1 ){
        sqlite3VdbeChangeP4(v, -1, (char*)pExpr->token.z, pExpr->token.n);
      }
      inReg = target;
      break;
    }
    case TK_REGISTER: {
      inReg = pExpr->iTable;
      break;
    }
#ifndef SQLITE_OMIT_CAST
    case TK_CAST: {
      /* Expressions of the form:   CAST(pLeft AS token) */
      int aff, to_op;
      sqlite3ExprCode(pParse, pExpr->pLeft, target);
      aff = sqlite3AffinityType(&pExpr->token);
      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    );
      sqlite3VdbeAddOp1(v, to_op, target);
      stackChng = 0;
      inReg = target;
      break;
    }
#endif /* SQLITE_OMIT_CAST */
    case TK_LT:
    case TK_LE:
    case TK_GT:
    case TK_GE:
................................................................................
    }
    case TK_UMINUS: {
      Expr *pLeft = pExpr->pLeft;
      assert( pLeft );
      if( pLeft->op==TK_FLOAT || pLeft->op==TK_INTEGER ){
        Token *p = &pLeft->token;
        if( pLeft->op==TK_FLOAT ){
          codeReal(v, (char*)p->z, p->n, 1, target);
        }else{
          codeInteger(v, (char*)p->z, p->n, 1, target);
        }
        inReg = target;
        break;
      }
      /* Fall through into TK_NOT */
    }
    case TK_BITNOT:
    case TK_NOT: {
      assert( TK_BITNOT==OP_BitNot );
................................................................................
      break;
    }
    case TK_ISNULL:
    case TK_NOTNULL: {
      int dest;
      assert( TK_ISNULL==OP_IsNull );
      assert( TK_NOTNULL==OP_NotNull );
      sqlite3VdbeAddOp2(v, OP_Integer, 1, target);
      sqlite3ExprCode(pParse, pExpr->pLeft, 0);
      dest = sqlite3VdbeCurrentAddr(v) + 2;
      sqlite3VdbeAddOp2(v, op, 1, dest);
      sqlite3VdbeAddOp2(v, OP_AddImm, target, -1);
      stackChng = 0;
      inReg = target;
      break;
    }
    case TK_AGG_FUNCTION: {
      AggInfo *pInfo = pExpr->pAggInfo;
      if( pInfo==0 ){
        sqlite3ErrorMsg(pParse, "misuse of aggregate: %T",
            &pExpr->span);
      }else{
        inReg = pInfo->aFunc[pExpr->iAgg].iMem;
      }
      break;
    }
    case TK_CONST_FUNC:
    case TK_FUNCTION: {
      ExprList *pList = pExpr->pList;
      int nExpr = pList ? pList->nExpr : 0;
................................................................................
    }
#ifndef SQLITE_OMIT_SUBQUERY
    case TK_EXISTS:
    case TK_SELECT: {
      if( pExpr->iColumn==0 ){
        sqlite3CodeSubselect(pParse, pExpr);
      }
      inReg = pExpr->iColumn;
      /* sqlite3VdbeAddOp1(v, OP_SCopy, pExpr->iColumn);
      VdbeComment((v, "load subquery result")); */
      break;
    }
    case TK_IN: {
      int addr;
      char affinity;
      int ckOffset = pParse->ckOffset;
      int eType;
................................................................................
      pRight = pLItem->pExpr;
      sqlite3ExprCode(pParse, pRight, 0);
      codeCompare(pParse, pLeft, pRight, OP_Le, 0, 0);
      sqlite3VdbeAddOp0(v, OP_And);
      break;
    }
    case TK_UPLUS: {
      inReg = sqlite3ExprCode(pParse, pExpr->pLeft, origTarget);
      stackChng = 0;
      break;
    }
    case TK_CASE: {
      int expr_end_label;
      int jumpInst;
      int nExpr;
................................................................................
          sqlite3VdbeAddOp1(v, OP_SCopy, -1);
          jumpInst = codeCompare(pParse, pExpr->pLeft, aListelem[i].pExpr,
                                 OP_Ne, 0, 1);
          sqlite3VdbeAddOp1(v, OP_Pop, 1);
        }else{
          jumpInst = sqlite3VdbeAddOp2(v, OP_IfNot, 1, 0);
        }
        sqlite3ExprCode(pParse, aListelem[i+1].pExpr, target);
        sqlite3VdbeAddOp2(v, OP_Goto, 0, expr_end_label);
        sqlite3VdbeJumpHere(v, jumpInst);
      }
      if( pExpr->pLeft ){
        sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
      }
      if( pExpr->pRight ){
        sqlite3ExprCode(pParse, pExpr->pRight, target);
      }else{
        sqlite3VdbeAddOp2(v, OP_Null, 0, target);
      }
      sqlite3VdbeResolveLabel(v, expr_end_label);
      inReg = target;
      break;
    }
#ifndef SQLITE_OMIT_TRIGGER
    case TK_RAISE: {
      if( !pParse->trigStack ){
        sqlite3ErrorMsg(pParse,
                       "RAISE() may only be used within a trigger-program");
................................................................................
         VdbeComment((v, "raise(IGNORE)"));
      }
      stackChng = 0;
      break;
    }
#endif
  }
  if( inReg!=target && origTarget!=-1 ){
    sqlite3VdbeAddOp2(v, (inReg>0 ? OP_SCopy : OP_Move), inReg, target);
    stackChng = 0;
  }
  if( pParse->ckOffset ){
    pParse->ckOffset += stackChng;
    assert( pParse->ckOffset );
  }
  return target;

Changes to src/vdbe.c.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
...
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.682 2008/01/05 05:38:21 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor
................................................................................
    pOp->p4type = P4_STATIC;
    pOp->p4.z = "";
  }

  /* Fall through to the next case, OP_Blob. */
}

/* Opcode: Blob P1 * P4
**
** P4 points to a blob of data P1 bytes long. Push this
** value onto the stack. This instruction is not coded directly
** by the compiler. Instead, the compiler layer specifies
** an OP_HexBlob opcode, with the hex string representation of
** the blob as P4. This opcode is transformed to an OP_Blob
** the first time it is executed.
*/
case OP_Blob: {                /* out2-prerelease */
  assert( pOp->p1 <= SQLITE_MAX_LENGTH );
  sqlite3VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0);
  pTos->enc = encoding;
  break;
}
#endif /* SQLITE_OMIT_BLOB_LITERAL */

/* Opcode: Variable P1 * *
**
** The value of variable P1 is written into register P2 or pushed







|







 







|

|
|








|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
...
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.683 2008/01/05 06:51:32 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor
................................................................................
    pOp->p4type = P4_STATIC;
    pOp->p4.z = "";
  }

  /* Fall through to the next case, OP_Blob. */
}

/* Opcode: Blob P1 P2 * P4
**
** P4 points to a blob of data P1 bytes long.  Store this
** blob in register P2. This instruction is not coded directly
** by the compiler. Instead, the compiler layer specifies
** an OP_HexBlob opcode, with the hex string representation of
** the blob as P4. This opcode is transformed to an OP_Blob
** the first time it is executed.
*/
case OP_Blob: {                /* out2-prerelease */
  assert( pOp->p1 <= SQLITE_MAX_LENGTH );
  sqlite3VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0);
  pOut->enc = encoding;
  break;
}
#endif /* SQLITE_OMIT_BLOB_LITERAL */

/* Opcode: Variable P1 * *
**
** The value of variable P1 is written into register P2 or pushed