/ Check-in [4f396707]
Login

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

Overview
Comment:Update OP_Rowid, OP_Column and related opcodes to use registers. (CVS 4671)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 4f3967073d2df9eae5a61b9770d5de2e1af47b4c
User & Date: drh 2008-01-03 18:44:59
Context
2008-01-03
18:56
Fix typo in comment. Ticket #2870. (CVS 4672) check-in: e97e4578 user: danielk1977 tags: trunk
18:44
Update OP_Rowid, OP_Column and related opcodes to use registers. (CVS 4671) check-in: 4f396707 user: drh tags: trunk
18:39
Modify VFilter and VRename to use registers instead of the vdbe stack for inputs. (CVS 4670) check-in: 253ed40a user: danielk1977 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
....
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904






1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
....
1956
1957
1958
1959
1960
1961
1962
1963

1964
1965
1966
1967
1968
1969
1970
....
2357
2358
2359
2360
2361
2362
2363


2364
2365
2366
2367
2368





2369

2370
2371
2372
2373
2374
2375
2376
**    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.327 2008/01/03 18:03:09 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Return the 'affinity' of the expression pExpr if any.
**
................................................................................
    }
  }
}


/*
** Generate code that will extract the iColumn-th column from
** table pTab and push that column value on the stack.  There
** is an open cursor to pTab in iTable.  If iColumn<0 then
** code is generated that extracts the rowid.
*/
void sqlite3ExprCodeGetColumn(Vdbe *v, Table *pTab, int iColumn, int iTable){






  if( iColumn<0 ){
    int op = (pTab && IsVirtual(pTab)) ? OP_VRowid : OP_Rowid;
    sqlite3VdbeAddOp1(v, op, iTable);
  }else if( pTab==0 ){
    sqlite3VdbeAddOp2(v, OP_Column, iTable, iColumn);
  }else{
    int op = IsVirtual(pTab) ? OP_VColumn : OP_Column;
    sqlite3VdbeAddOp2(v, op, iTable, iColumn);
    sqlite3ColumnDefault(v, pTab, iColumn);
#ifndef SQLITE_OMIT_FLOATING_POINT
    if( pTab->aCol[iColumn].affinity==SQLITE_AFF_REAL ){
      sqlite3VdbeAddOp0(v, OP_RealAffinity);
    }
#endif
  }
}

/*
** Generate code into the current Vdbe to evaluate the given
................................................................................
    }
    case TK_COLUMN: {
      if( pExpr->iTable<0 ){
        /* This only happens when coding check constraints */
        assert( pParse->ckOffset>0 );
        sqlite3VdbeAddOp2(v, OP_Dup, pParse->ckOffset-pExpr->iColumn-1, 1);
      }else{
        sqlite3ExprCodeGetColumn(v, pExpr->pTab, pExpr->iColumn, pExpr->iTable);

      }
      break;
    }
    case TK_INTEGER: {
      codeInteger(v, (char*)pExpr->token.z, pExpr->token.n, 0);
      break;
    }
................................................................................
** register number regardless.
**
** The current implementation is a rough prototype for experimental
** purposes.  There are many optimization opportunities here.
*/
int sqlite3ExprIntoReg(Parse *pParse, Expr *pExpr, int target){
  Vdbe *v = pParse->pVdbe;


  if( v==0 ) return -1;
  sqlite3ExprCode(pParse, pExpr);
  if( target<0 ){
    target = ++pParse->nMem;
  }





  sqlite3VdbeAddOp2(v, OP_MemStore, target, 1);

  return target;
}

/*
** Generate code that pushes the value of every element of the given
** expression list onto the stack.
**







|







 







|
|
|

|
>
>
>
>
>
>


|

|


|



|







 







|
>







 







>
>
|
<
|


>
>
>
>
>
|
>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
....
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
....
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373

2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
**    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.328 2008/01/03 18:44:59 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Return the 'affinity' of the expression pExpr if any.
**
................................................................................
    }
  }
}


/*
** Generate code that will extract the iColumn-th column from
** table pTab and store the column value in register iMem, or on
** the stack if iMem==0.  There is an open cursor to pTab in 
** iTable.  If iColumn<0 then code is generated that extracts the rowid.
*/
void sqlite3ExprCodeGetColumn(
  Vdbe *v,         /* The VM being created */
  Table *pTab,     /* Description of the table we are reading from */
  int iColumn,     /* Index of the table column */
  int iTable,      /* The cursor pointing to the table */
  int iReg         /* Store results here */
){
  if( iColumn<0 ){
    int op = (pTab && IsVirtual(pTab)) ? OP_VRowid : OP_Rowid;
    sqlite3VdbeAddOp2(v, op, iTable, iReg);
  }else if( pTab==0 ){
    sqlite3VdbeAddOp3(v, OP_Column, iTable, iColumn, iReg);
  }else{
    int op = IsVirtual(pTab) ? OP_VColumn : OP_Column;
    sqlite3VdbeAddOp3(v, op, iTable, iColumn, iReg);
    sqlite3ColumnDefault(v, pTab, iColumn);
#ifndef SQLITE_OMIT_FLOATING_POINT
    if( pTab->aCol[iColumn].affinity==SQLITE_AFF_REAL ){
      sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg);
    }
#endif
  }
}

/*
** Generate code into the current Vdbe to evaluate the given
................................................................................
    }
    case TK_COLUMN: {
      if( pExpr->iTable<0 ){
        /* This only happens when coding check constraints */
        assert( pParse->ckOffset>0 );
        sqlite3VdbeAddOp2(v, OP_Dup, pParse->ckOffset-pExpr->iColumn-1, 1);
      }else{
        sqlite3ExprCodeGetColumn(v, pExpr->pTab,
                                 pExpr->iColumn, pExpr->iTable, 0);
      }
      break;
    }
    case TK_INTEGER: {
      codeInteger(v, (char*)pExpr->token.z, pExpr->token.n, 0);
      break;
    }
................................................................................
** register number regardless.
**
** The current implementation is a rough prototype for experimental
** purposes.  There are many optimization opportunities here.
*/
int sqlite3ExprIntoReg(Parse *pParse, Expr *pExpr, int target){
  Vdbe *v = pParse->pVdbe;
  assert( v!=0 || pParse->db->mallocFailed );
  assert( pExpr!=0 || pParse->db->mallocFailed );
  if( v==0 || pExpr==0 ) return -1;

  if( target<=0 ){
    target = ++pParse->nMem;
  }
  if( pExpr->op==TK_COLUMN && pExpr->iTable>=0 ){
    sqlite3ExprCodeGetColumn(v, pExpr->pTab,
                             pExpr->iColumn, pExpr->iTable, target);
  }else{
    sqlite3ExprCode(pParse, pExpr);
    sqlite3VdbeAddOp2(v, OP_MemStore, target, 1);
  }
  return target;
}

/*
** Generate code that pushes the value of every element of the given
** expression list onto the stack.
**

Changes to src/select.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.381 2008/01/03 18:03:09 drh Exp $
*/
#include "sqliteInt.h"


/*
** Delete all the content of a Select structure but do not deallocate
** the select structure itself.
................................................................................
        groupBySort = 1;
        sqlite3ExprCodeExprList(pParse, pGroupBy);
        sqlite3VdbeAddOp2(v, OP_Sequence, sAggInfo.sortingIdx, 0);
        j = pGroupBy->nExpr+1;
        for(i=0; i<sAggInfo.nColumn; i++){
          struct AggInfo_col *pCol = &sAggInfo.aCol[i];
          if( pCol->iSorterColumn<j ) continue;
          sqlite3ExprCodeGetColumn(v, pCol->pTab, pCol->iColumn, pCol->iTable);
          j++;
        }
        sqlite3VdbeAddOp2(v, OP_MakeRecord, j, 0);
        sqlite3VdbeAddOp2(v, OP_IdxInsert, sAggInfo.sortingIdx, 0);
        sqlite3WhereEnd(pWInfo);
        sqlite3VdbeAddOp2(v, OP_Sort, sAggInfo.sortingIdx, addrEnd);
        VdbeComment((v, "GROUP BY sort"));







|







 







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.382 2008/01/03 18:44:59 drh Exp $
*/
#include "sqliteInt.h"


/*
** Delete all the content of a Select structure but do not deallocate
** the select structure itself.
................................................................................
        groupBySort = 1;
        sqlite3ExprCodeExprList(pParse, pGroupBy);
        sqlite3VdbeAddOp2(v, OP_Sequence, sAggInfo.sortingIdx, 0);
        j = pGroupBy->nExpr+1;
        for(i=0; i<sAggInfo.nColumn; i++){
          struct AggInfo_col *pCol = &sAggInfo.aCol[i];
          if( pCol->iSorterColumn<j ) continue;
          sqlite3ExprCodeGetColumn(v, pCol->pTab, pCol->iColumn,pCol->iTable,0);
          j++;
        }
        sqlite3VdbeAddOp2(v, OP_MakeRecord, j, 0);
        sqlite3VdbeAddOp2(v, OP_IdxInsert, sAggInfo.sortingIdx, 0);
        sqlite3WhereEnd(pWInfo);
        sqlite3VdbeAddOp2(v, OP_Sort, sAggInfo.sortingIdx, addrEnd);
        VdbeComment((v, "GROUP BY sort"));

Changes to src/sqliteInt.h.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.634 2008/01/03 17:31:45 danielk1977 Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** The macro unlikely() is a hint that surrounds a boolean
** expression that is usually false.  Macro likely() surrounds
................................................................................
Table *sqlite3SrcListLookup(Parse*, SrcList*);
int sqlite3IsReadOnly(Parse*, Table*, int);
void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int);
void sqlite3DeleteFrom(Parse*, SrcList*, Expr*);
void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int);
WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, ExprList**);
void sqlite3WhereEnd(WhereInfo*);
void sqlite3ExprCodeGetColumn(Vdbe*, Table*, int, int);
void sqlite3ExprCode(Parse*, Expr*);
void sqlite3ExprCodeAndCache(Parse*, Expr*);
int sqlite3ExprIntoReg(Parse*,Expr*,int);
int sqlite3ExprCodeExprList(Parse*, ExprList*);
void sqlite3ExprIfTrue(Parse*, Expr*, int, int);
void sqlite3ExprIfFalse(Parse*, Expr*, int, int);
Table *sqlite3FindTable(sqlite3*,const char*, const char*);







|







 







|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.635 2008/01/03 18:44:59 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** The macro unlikely() is a hint that surrounds a boolean
** expression that is usually false.  Macro likely() surrounds
................................................................................
Table *sqlite3SrcListLookup(Parse*, SrcList*);
int sqlite3IsReadOnly(Parse*, Table*, int);
void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int);
void sqlite3DeleteFrom(Parse*, SrcList*, Expr*);
void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int);
WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, ExprList**);
void sqlite3WhereEnd(WhereInfo*);
void sqlite3ExprCodeGetColumn(Vdbe*, Table*, int, int, int);
void sqlite3ExprCode(Parse*, Expr*);
void sqlite3ExprCodeAndCache(Parse*, Expr*);
int sqlite3ExprIntoReg(Parse*,Expr*,int);
int sqlite3ExprCodeExprList(Parse*, ExprList*);
void sqlite3ExprIfTrue(Parse*, Expr*, int, int);
void sqlite3ExprIfFalse(Parse*, Expr*, int, int);
Table *sqlite3FindTable(sqlite3*,const char*, const char*);

Changes to src/vdbe.c.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550

1551
1552






1553
1554
1555
1556
1557
1558
1559
....
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813

3814
3815
3816
3817
3818
3819





3820

3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
....
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065

4066
4067
4068





4069

4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
....
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057

5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069

5070
5071
5072
5073
5074





5075

5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088


5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099

5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111




5112
5113

5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
**
** 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.672 2008/01/03 18:39:42 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor
................................................................................
  }else{
    Release(pTos);
    pTos->flags = MEM_Int;
  }
  break;
}

/* Opcode: RealAffinity * * *
**
** If the top of the stack is an integer, convert it to a real value.
**
** This opcode is used when extracting information from a column that
** has REAL affinity.  Such column values may still be stored as
** integers, for space efficiency, but after extraction we want them
** to have only a real value.
*/
case OP_RealAffinity: {                  /* no-push */
  assert( pTos>=p->aStack );

  if( pTos->flags & MEM_Int ){
    sqlite3VdbeMemRealify(pTos);






  }
  break;
}

#ifndef SQLITE_OMIT_CAST
/* Opcode: ToText * * *
**
................................................................................
  }else{
    pTos->flags = MEM_Null;
  }
  pTos->enc = SQLITE_UTF8;  /* In case the blob is ever cast to text */
  break;
}

/* Opcode: Rowid P1 * *
**
** Push onto the stack an integer which is the key of the table entry that
** P1 is currently point to.
*/
case OP_Rowid: {
  int i = pOp->p1;
  Cursor *pC;
  i64 v;


  assert( i>=0 && i<p->nCursor );
  pC = p->apCsr[i];
  assert( pC!=0 );
  rc = sqlite3VdbeCursorMoveto(pC);
  if( rc ) goto abort_due_to_error;





  pTos++;

  if( pC->rowidIsValid ){
    v = pC->lastRowid;
  }else if( pC->pseudoTable ){
    v = keyToInt(pC->iKey);
  }else if( pC->nullRow || pC->pCursor==0 ){
    pTos->flags = MEM_Null;
    break;
  }else{
    assert( pC->pCursor!=0 );
    sqlite3BtreeKeySize(pC->pCursor, &v);
    v = keyToInt(v);
  }
  pTos->u.i = v;
  pTos->flags = MEM_Int;
  break;
}

/* Opcode: NullRow P1 * *
**
** Move the cursor P1 to a null row.  Any OP_Column operations
** that occur while the cursor is on the null row will always push 
................................................................................
    pC->cacheStatus = CACHE_STALE;
  }
  Release(pTos);
  pTos--;
  break;
}

/* Opcode: IdxRowid P1 * *
**
** Push onto the stack an integer which is the last entry in the record at
** the end of the index key pointed to by cursor P1.  This integer should be
** the rowid of the table entry to which this index entry points.
**
** See also: Rowid, MakeIdxRec.
*/
case OP_IdxRowid: {
  int i = pOp->p1;
  BtCursor *pCrsr;
  Cursor *pC;


  assert( i>=0 && i<p->nCursor );
  assert( p->apCsr[i]!=0 );





  pTos++;

  pTos->flags = MEM_Null;
  if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
    i64 rowid;

    assert( pC->deferredMoveto==0 );
    assert( pC->isTable==0 );
    if( pC->nullRow ){
      pTos->flags = MEM_Null;
    }else{
      rc = sqlite3VdbeIdxRowid(pCrsr, &rowid);
      if( rc!=SQLITE_OK ){
        goto abort_due_to_error;
      }
      pTos->flags = MEM_Int;
      pTos->u.i = rowid;
    }
  }
  break;
}

/* Opcode: IdxGT P1 P2 *
**
................................................................................
  }

  break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VRowid P1 * *
**
** Push an integer onto the stack which is the rowid of
** the virtual-table that the P1 cursor is pointing to.

*/
case OP_VRowid: {
  const sqlite3_module *pModule;

  Cursor *pCur = p->apCsr[pOp->p1];
  assert( pCur->pVtabCursor );
  pModule = pCur->pVtabCursor->pVtab->pModule;
  if( pModule->xRowid==0 ){
    sqlite3SetString(&p->zErrMsg, "Unsupported module operation: xRowid", 0);
    rc = SQLITE_ERROR;
  } else {
    sqlite_int64 iRow;


    if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
    rc = pModule->xRowid(pCur->pVtabCursor, &iRow);
    if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;






    pTos++;

    pTos->flags = MEM_Int;
    pTos->u.i = iRow;
  }

  break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VColumn P1 P2 *
**
** Push onto the stack the value of the P2-th column of
** the row of the virtual-table that the P1 cursor is pointing to.


*/
case OP_VColumn: {
  const sqlite3_module *pModule;

  Cursor *pCur = p->apCsr[pOp->p1];
  assert( pCur->pVtabCursor );
  pModule = pCur->pVtabCursor->pVtab->pModule;
  if( pModule->xColumn==0 ){
    sqlite3SetString(&p->zErrMsg, "Unsupported module operation: xColumn", 0);
    rc = SQLITE_ERROR;
  } else {

    sqlite3_context sContext;
    memset(&sContext, 0, sizeof(sContext));
    sContext.s.flags = MEM_Null;
    sContext.s.db = db;
    if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
    rc = pModule->xColumn(pCur->pVtabCursor, &sContext, pOp->p2);

    /* Copy the result of the function to the top of the stack. We
    ** do this regardless of whether or not an error occured to ensure any
    ** dynamic allocation in sContext.s (a Mem struct) is  released.
    */
    sqlite3VdbeChangeEncoding(&sContext.s, encoding);




    pTos++;
    pTos->flags = 0;

    sqlite3VdbeMemMove(pTos, &sContext.s);

    if( sqlite3SafetyOn(db) ){
      goto abort_due_to_misuse;
    }
    if( sqlite3VdbeMemTooBig(pTos) ){
      goto too_big;
    }
  }
  
  break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */







|







 







|

|







|
>
|
|
>
>
>
>
>
>







 







|

|
|





>






>
>
>
>
>
|
>





|






|
|







 







|

|









>



>
>
>
>
>
|
>
|






|





|
|







 







|

|

>












>





>
>
>
>
>
|
>
|
|







|

|
|
>
>











>












>
>
>
>
|
|
>
|




|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
....
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
....
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
....
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
**
** 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.673 2008/01/03 18:44:59 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor
................................................................................
  }else{
    Release(pTos);
    pTos->flags = MEM_Int;
  }
  break;
}

/* Opcode: RealAffinity P1 * *
**
** If register P1 holds an integer convert it to a real value.
**
** This opcode is used when extracting information from a column that
** has REAL affinity.  Such column values may still be stored as
** integers, for space efficiency, but after extraction we want them
** to have only a real value.
*/
case OP_RealAffinity: {                  /* no-push */
  assert( pOp->p1>=0 && pOp->p1<=p->nMem );
  if( pOp->p1==0 ){
    if( pTos->flags & MEM_Int ){
      sqlite3VdbeMemRealify(pTos);
    }
  }else{
    Mem *pX = &p->aMem[pOp->p1];
    if( pX->flags & MEM_Int ){
      sqlite3VdbeMemRealify(pX);
    }
  }
  break;
}

#ifndef SQLITE_OMIT_CAST
/* Opcode: ToText * * *
**
................................................................................
  }else{
    pTos->flags = MEM_Null;
  }
  pTos->enc = SQLITE_UTF8;  /* In case the blob is ever cast to text */
  break;
}

/* Opcode: Rowid P1 P2 * * *
**
** Store in register P2 an integer which is the key of the table entry that
** P1 is currently point to.  If p2==0 then pust the integer.
*/
case OP_Rowid: {
  int i = pOp->p1;
  Cursor *pC;
  i64 v;
  Mem *pDest;

  assert( i>=0 && i<p->nCursor );
  pC = p->apCsr[i];
  assert( pC!=0 );
  rc = sqlite3VdbeCursorMoveto(pC);
  if( rc ) goto abort_due_to_error;
  if( pOp->p2>0 ){
    assert( pOp->p2<=p->nMem );
    pDest = &p->aMem[pOp->p2];
    sqlite3VdbeMemRelease(pDest);
  }else{
    pDest = ++pTos;
  }
  if( pC->rowidIsValid ){
    v = pC->lastRowid;
  }else if( pC->pseudoTable ){
    v = keyToInt(pC->iKey);
  }else if( pC->nullRow || pC->pCursor==0 ){
    pDest->flags = MEM_Null;
    break;
  }else{
    assert( pC->pCursor!=0 );
    sqlite3BtreeKeySize(pC->pCursor, &v);
    v = keyToInt(v);
  }
  pDest->u.i = v;
  pDest->flags = MEM_Int;
  break;
}

/* Opcode: NullRow P1 * *
**
** Move the cursor P1 to a null row.  Any OP_Column operations
** that occur while the cursor is on the null row will always push 
................................................................................
    pC->cacheStatus = CACHE_STALE;
  }
  Release(pTos);
  pTos--;
  break;
}

/* Opcode: IdxRowid P1 P2 * * *
**
** Write into register P2 an integer which is the last entry in the record at
** the end of the index key pointed to by cursor P1.  This integer should be
** the rowid of the table entry to which this index entry points.
**
** See also: Rowid, MakeIdxRec.
*/
case OP_IdxRowid: {
  int i = pOp->p1;
  BtCursor *pCrsr;
  Cursor *pC;
  Mem *pDest;

  assert( i>=0 && i<p->nCursor );
  assert( p->apCsr[i]!=0 );
  if( pOp->p2>0 ){
    assert( pOp->p2<=p->nMem );
    pDest = &p->aMem[pOp->p2];
    sqlite3VdbeMemRelease(pDest);
  }else{
    pDest = ++pTos;
  }
  pDest->flags = MEM_Null;
  if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
    i64 rowid;

    assert( pC->deferredMoveto==0 );
    assert( pC->isTable==0 );
    if( pC->nullRow ){
      pDest->flags = MEM_Null;
    }else{
      rc = sqlite3VdbeIdxRowid(pCrsr, &rowid);
      if( rc!=SQLITE_OK ){
        goto abort_due_to_error;
      }
      pDest->flags = MEM_Int;
      pDest->u.i = rowid;
    }
  }
  break;
}

/* Opcode: IdxGT P1 P2 *
**
................................................................................
  }

  break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VRowid P1 P2 *
**
** Store into register P2  the rowid of
** the virtual-table that the P1 cursor is pointing to.
** If P2==0, push the value onto the stack.
*/
case OP_VRowid: {
  const sqlite3_module *pModule;

  Cursor *pCur = p->apCsr[pOp->p1];
  assert( pCur->pVtabCursor );
  pModule = pCur->pVtabCursor->pVtab->pModule;
  if( pModule->xRowid==0 ){
    sqlite3SetString(&p->zErrMsg, "Unsupported module operation: xRowid", 0);
    rc = SQLITE_ERROR;
  } else {
    sqlite_int64 iRow;
    Mem *pDest;

    if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
    rc = pModule->xRowid(pCur->pVtabCursor, &iRow);
    if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;

    if( pOp->p2>0 ){
      assert( pOp->p2<=p->nMem );
      pDest = &p->aMem[pOp->p2];
      sqlite3VdbeMemRelease(pDest);
    }else{
      pDest = ++pTos;
    }
    pDest->flags = MEM_Int;
    pDest->u.i = iRow;
  }

  break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VColumn P1 P2 P3
**
** Store the value of the P2-th column of
** the row of the virtual-table that the 
** P1 cursor is pointing to into register P3.
** Or if P3==0 push the value onto the stack.
*/
case OP_VColumn: {
  const sqlite3_module *pModule;

  Cursor *pCur = p->apCsr[pOp->p1];
  assert( pCur->pVtabCursor );
  pModule = pCur->pVtabCursor->pVtab->pModule;
  if( pModule->xColumn==0 ){
    sqlite3SetString(&p->zErrMsg, "Unsupported module operation: xColumn", 0);
    rc = SQLITE_ERROR;
  } else {
    Mem *pDest;
    sqlite3_context sContext;
    memset(&sContext, 0, sizeof(sContext));
    sContext.s.flags = MEM_Null;
    sContext.s.db = db;
    if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
    rc = pModule->xColumn(pCur->pVtabCursor, &sContext, pOp->p2);

    /* Copy the result of the function to the top of the stack. We
    ** do this regardless of whether or not an error occured to ensure any
    ** dynamic allocation in sContext.s (a Mem struct) is  released.
    */
    sqlite3VdbeChangeEncoding(&sContext.s, encoding);
    if( pOp->p3>0 ){
      assert( pOp->p3<=p->nMem );
      pDest = &p->aMem[pOp->p3];
    }else{
      pDest = ++pTos;
      pDest->flags = 0;
    }
    sqlite3VdbeMemMove(pDest, &sContext.s);

    if( sqlite3SafetyOn(db) ){
      goto abort_due_to_misuse;
    }
    if( sqlite3VdbeMemTooBig(pDest) ){
      goto too_big;
    }
  }
  
  break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */