SQLite4
Check-in [70f15a5352]
Not logged in

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

Overview
Comment:CREATE INDEX runs, though index queries does not work yet so there is no way to test that the index was correctly created.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 70f15a535241dda4ca059f384584a0eb98c2f177
User & Date: drh 2012-02-22 13:15:27
Context
2012-02-22
14:20
Add the "kvdump" pragma for debugging. check-in: 4746d99cc1 user: drh tags: trunk
13:15
CREATE INDEX runs, though index queries does not work yet so there is no way to test that the index was correctly created. check-in: 70f15a5352 user: drh tags: trunk
02:44
Remove the OP_Destroy opcode. Add an implementation for OP_Clear. check-in: 15cf832dfc user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/delete.c.

640
641
642
643
644
645
646
647
648
649
650
651
652
653
  if( doMakeRec ){
    const char *zAff;
    if( pTab->pSelect || (pParse->db->flags & SQLITE_IdxRealAsInt)!=0 ){
      zAff = 0;
    }else{
      zAff = sqlite4IndexAffinityStr(v, pIdx);
    }
    sqlite4VdbeAddOp1(v, OP_MakeKey, iIdxCur);
    sqlite4VdbeAddOp3(v, OP_MakeRecord, regBase, nCol+1, regOut);
    sqlite4VdbeChangeP4(v, -1, zAff, P4_TRANSIENT);
  }
  sqlite4ReleaseTempRange(pParse, regBase, nCol+1);
  return regBase;
}







|






640
641
642
643
644
645
646
647
648
649
650
651
652
653
  if( doMakeRec ){
    const char *zAff;
    if( pTab->pSelect || (pParse->db->flags & SQLITE_IdxRealAsInt)!=0 ){
      zAff = 0;
    }else{
      zAff = sqlite4IndexAffinityStr(v, pIdx);
    }
    sqlite4VdbeAddOp2(v, OP_MakeKey, iIdxCur, regOut+1);
    sqlite4VdbeAddOp3(v, OP_MakeRecord, regBase, nCol+1, regOut);
    sqlite4VdbeChangeP4(v, -1, zAff, P4_TRANSIENT);
  }
  sqlite4ReleaseTempRange(pParse, regBase, nCol+1);
  return regBase;
}

Changes to src/storage.h.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
..
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95



96
97
98



99
100
101
102
103
104
105
106
107


108



109
110
111



112
113
114
115
116
117
118
**
*************************************************************************
**
** This header file defines the interface to the KV storage engine(s).
**
** Notes on the storage subsystem interface:
** 
** The storage subsystem is a key/value store.  All keys and values are
** binary with arbitrary content.  Keys are unique.  Keys compare in
** memcmp() order.  Shorter keys appear first.
** 
** The xBegin, xCommit, and xRollback methods change the transaction level
** of the store.  The transaction level is a non-negative integer that is
** initialized to zero.  The transaction level must be at least 1 in order
** for content to be read.  The transaction level must be at least 2 for 
** content to be modified.
** 
** The xBegin method increases transaction level.  The increase may be no
** more than 1 unless the transaction level is initially 0 in which case
** it can be increased immediately to 2.  Increasing the transaction level
** to 1 or more makes a "snapshot" of the complete store such that changes
** made by other connections are not visible.  An xBegin call may fail
** with SQLITE_BUSY if the initial transaction level is 0 or 1.
** 
** A read-only store will fail an attempt to increase xBegin above 1.  An
** implementation that does not support nested transactions will fail any
** attempt to increase the transaction level above 2.
** 
** The xCommitPhaseOne and xCommitPhaseTwo methods implementat a 2-phase
** commit that lowers the transaction level to the value given in the
** second argument, and makes all the changes made at higher transaction levels
** permanent.  A rollback is still possible following phase one.  If
** possible, errors should be reported during phase one so that a
** multiple-database transaction can still be rolled back if the
** phase one fails on a different database.  Implementations that do not
** support two-phase commit can implement xCommitPhaseOne as a no-op function
** returning SQLITE_OK.
** 
................................................................................
** its argument and reverts or undoes all changes made at higher transaction
** levels.  An xRollback to level N causes the database to revert to the state
** it was in on the most recent xBegin to level N+1.
** 
** The xRevert(N) method causes the state of the database file to go back
** to what it was immediately after the most recent xCommit(N).  Higher-level
** subtransactions are cancelled.  This call is equivalent to xRollback(N-1)
** followed by xBegin(N) but might be more efficient.
** 
** The xReplace method replaces the value for an existing entry with the
** given key, or creates a new entry with the given key and value if no
** prior entry exists with the given key.  The key and value pointers passed
** into xReplace will likely be destroyed when the call to xReplace returns
** so the xReplace routine must make its own copy of that information.
** 
** The xDelete method delets an existing entry with the given key.  If no
** such entry exists, xDelete is a no-op.
** 
** A cursor is at all times pointing to ether an entry in the store or
** to EOF.  EOF means "no entry".  Cursor operations other than xCloseCursor 
** will fail if the transaction level is less than 1.
** 
** The xSeek method moves a cursor to a point in the store that matches
** the supplied key as closely as possible.  If the dir argument is 0, then
** the match must be exact or else the seek fails and the cursor is left
** pointing to EOF.  If dir is negative, then an exact match is
** found if it is available, otherwise the cursor is positioned at the largest
** entry that is less than the search key or to EOF if the store contains no
** entry less than the search key.  If dir is positive, then an exist match
** is found if it is available, otherwise the cursor is left pointing the
** the smallest entry that is larger than the search key, or to EOF if there
** are no entries larger than the search key.
**
** The xSeek return code might be one of the following:
**
**    SQLITE_OK        The cursor is left pointing to any entry that
**                     exactly matchings the probe key.
**
**    SQLITE_INEXACT   The cursor is left pointing to the nearest entry
**                     to the probe it could find, either before or after
**                     the probe, according to the dir argument.
**
**    SQLITE_NOTFOUND  No suitable entry could be found.  Either dir==0 and
**                     there was no exact match, or dir<0 and the probe is
**                     smaller than every entry in the database, or dir>0 and
**                     the probe is larger than every entry in the database.
** 



** The xNext method may only be used following an xSeek with a positive dir,
** or another xNext.  The xPrev method may only be used following an xSeek with
** a negative dir or another xPrev.



** 
** Values returned by xKey and xData are guaranteed to remain stable until
** the next xSeek, xNext, xPrev, xReset, or xCloseCursor on the same cursor.  
** This is true even if the transaction level is reduced to zero, or if the
** content of the entry is changed by xInsert, xDelete, or xRollback.  The
** content returned by repeated calls to xKey and xData is allowed (but is not
** required) to change if xInsert, xDelete, or xRollback are invoked in between
** the calls, but the content returned by every call must be stable until 
** the cursor moves, or is reset or closed.


** 



** It is acceptable to xDelete an entry out from under a cursor.  Subsequent
** xNext or xPrev calls on that cursor will work the same as if the entry
** had not been deleted.



*/

/* Typedefs of datatypes */
typedef struct KVStore KVStore;
typedef struct KVStoreMethods KVStoreMethods;
typedef struct KVCursor KVCursor;
typedef unsigned char KVByteArray;







|












|



|



|

|







 







|




|
|
|
<
<

|



|










|












|
>
>
>
|
|
|
>
>
>


|
|
|
|
|
|
|
>
>

>
>
>
|

|
>
>
>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
..
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63


64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
**
*************************************************************************
**
** This header file defines the interface to the KV storage engine(s).
**
** Notes on the storage subsystem interface:
** 
** The storage subsystem is a key/value database.  All keys and values are
** binary with arbitrary content.  Keys are unique.  Keys compare in
** memcmp() order.  Shorter keys appear first.
** 
** The xBegin, xCommit, and xRollback methods change the transaction level
** of the store.  The transaction level is a non-negative integer that is
** initialized to zero.  The transaction level must be at least 1 in order
** for content to be read.  The transaction level must be at least 2 for 
** content to be modified.
** 
** The xBegin method increases transaction level.  The increase may be no
** more than 1 unless the transaction level is initially 0 in which case
** it can be increased immediately to 2.  Increasing the transaction level
** to 1 or more makes a "snapshot" of the database file such that changes
** made by other connections are not visible.  An xBegin call may fail
** with SQLITE_BUSY if the initial transaction level is 0 or 1.
** 
** A read-only database will fail an attempt to increase xBegin above 1.  An
** implementation that does not support nested transactions will fail any
** attempt to increase the transaction level above 2.
** 
** The xCommitPhaseOne and xCommitPhaseTwo methods implement a 2-phase
** commit that lowers the transaction level to the value given in the
** second argument, making all the changes made at higher transaction levels
** permanent.  A rollback is still possible following phase one.  If
** possible, errors should be reported during phase one so that a
** multiple-database transaction can still be rolled back if the
** phase one fails on a different database.  Implementations that do not
** support two-phase commit can implement xCommitPhaseOne as a no-op function
** returning SQLITE_OK.
** 
................................................................................
** its argument and reverts or undoes all changes made at higher transaction
** levels.  An xRollback to level N causes the database to revert to the state
** it was in on the most recent xBegin to level N+1.
** 
** The xRevert(N) method causes the state of the database file to go back
** to what it was immediately after the most recent xCommit(N).  Higher-level
** subtransactions are cancelled.  This call is equivalent to xRollback(N-1)
** followed by xBegin(N) but is atomic and might be more efficient.
** 
** The xReplace method replaces the value for an existing entry with the
** given key, or creates a new entry with the given key and value if no
** prior entry exists with the given key.  The key and value pointers passed
** into xReplace belong to the caller will likely be destroyed when the
** call to xReplace returns so the xReplace routine must make its own
** copy of that information.


** 
** A cursor is at all times pointing to ether an entry in the database or
** to EOF.  EOF means "no entry".  Cursor operations other than xCloseCursor 
** will fail if the transaction level is less than 1.
** 
** The xSeek method moves a cursor to an entry in the database that matches
** the supplied key as closely as possible.  If the dir argument is 0, then
** the match must be exact or else the seek fails and the cursor is left
** pointing to EOF.  If dir is negative, then an exact match is
** found if it is available, otherwise the cursor is positioned at the largest
** entry that is less than the search key or to EOF if the store contains no
** entry less than the search key.  If dir is positive, then an exist match
** is found if it is available, otherwise the cursor is left pointing the
** the smallest entry that is larger than the search key, or to EOF if there
** are no entries larger than the search key.
**
** The return code from xSeek might be one of the following:
**
**    SQLITE_OK        The cursor is left pointing to any entry that
**                     exactly matchings the probe key.
**
**    SQLITE_INEXACT   The cursor is left pointing to the nearest entry
**                     to the probe it could find, either before or after
**                     the probe, according to the dir argument.
**
**    SQLITE_NOTFOUND  No suitable entry could be found.  Either dir==0 and
**                     there was no exact match, or dir<0 and the probe is
**                     smaller than every entry in the database, or dir>0 and
**                     the probe is larger than every entry in the database.
**
** xSeek might also return some error code like SQLITE_IOERR or
** SQLITE_NOMEM.
** 
** The xNext method will only be called following an xSeek with a positive dir,
** or another xNext.  The xPrev method will only be called following an xSeek
** with a negative dir or another xPrev.  Both xNext and xPrev will return
** SQLITE_OK on success and SQLITE_NOTFOUND if they run off the end of the
** database.  Both routines might also return error codes such as
** SQLITE_IOERR, SQLITE_CORRUPT, or SQLITE_NOMEM.
** 
** Values returned by xKey and xData are guaranteed to remain stable until
** the next xSeek, xNext, xPrev, xReset, xDelete, or xCloseCursor on the same
** cursor.  This is true even if the transaction level is reduced to zero,
** or if the content of the entry is changed by xInsert, xDelete on a different
** cursor, or xRollback.  The content returned by repeated calls to xKey and
** xData is allowed (but is not required) to change if xInsert, xDelete, or
** xRollback are invoked in between the calls, but the content returned by
** every call must be stable until the cursor moves, or is reset or closed.
** The cursor owns the values returned by xKey and xData and will take
** responsiblity for freeing memory used to hold those values when appropriate.
** 
** The xDelete method deletes the entry that the cursor is currently
** pointing at.  However, subsequent xNext or xPrev calls behave as if the
** entries is not actually deleted until the cursor moves.  In other words
** it is acceptable to xDelete an entry out from under a cursor.  Subsequent
** xNext or xPrev calls on that cursor will work the same as if the entry
** had not been deleted.  Two cursors can be pointing to the same entry and
** one cursor can xDelete and the other cursor is expected to continue
** functioning normally, including responding correctly to subsequent
** xNext and xPrev calls.
*/

/* Typedefs of datatypes */
typedef struct KVStore KVStore;
typedef struct KVStoreMethods KVStoreMethods;
typedef struct KVCursor KVCursor;
typedef unsigned char KVByteArray;

Changes to src/vdbe.c.

2204
2205
2206
2207
2208
2209
2210



2211
2212
2213
2214
2215
2216
2217
....
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620






3621











3622
3623
3624
3625
3626
3627
3628
    pKeyOut = &aMem[keyReg];
    memAboutToChange(p, pKeyOut);
    assert( pC!=0 );
    assert( pC->pKeyInfo!=0 );
    pc++;
    pOp++;
    assert( pOp->opcode==OP_MakeRecord );



  }else{
    pC = 0;
  }
  nField = pOp->p1;
  zAffinity = pOp->p4.z;
  assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=p->nMem+1 );
  pData0 = &aMem[nField];
................................................................................
  if( rc==SQLITE_OK ){
    rc = sqlite4VdbeSorterWrite(db, pC, pIn2);
  }
  break;
}


/* Opcode: IdxInsert P1 P2 * * P5
**
** Register P2 holds an SQL index key made using the
** MakeRecord instructions.  This opcode writes that key
** into the index P1.  Data for the entry is nil.
**
** P3 is a flag that provides a hint to the b-tree layer that this
** insert is likely to be an append.
**
** This instruction only works for indices.  The equivalent instruction
** for tables is OP_Insert.
*/
case OP_IdxInsert: {        /* in2 */






  assert( 0 );











  break;
}

/* Opcode: IdxDelete P1 P2 P3 * *
**
** The content of P3 registers starting at register P2 form
** an unpacked index key. This opcode removes that entry from the 







>
>
>







 







|

|
|
|

|






>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>







2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
....
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
    pKeyOut = &aMem[keyReg];
    memAboutToChange(p, pKeyOut);
    assert( pC!=0 );
    assert( pC->pKeyInfo!=0 );
    pc++;
    pOp++;
    assert( pOp->opcode==OP_MakeRecord );
#ifdef SQLITE_DEBUG
    if( p->trace ) sqlite4VdbePrintOp(p->trace, pc, pOp);
#endif
  }else{
    pC = 0;
  }
  nField = pOp->p1;
  zAffinity = pOp->p4.z;
  assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=p->nMem+1 );
  pData0 = &aMem[nField];
................................................................................
  if( rc==SQLITE_OK ){
    rc = sqlite4VdbeSorterWrite(db, pC, pIn2);
  }
  break;
}


/* Opcode: IdxInsert P1 P2 P3 * P5
**
** Register P2 holds the data and register P3 holds the key for an
** index record.  Write this record into the index specified by the
** cursor P1.
**
** P5 is a flag that provides a hint to the storage layer that this
** insert is likely to be an append.
**
** This instruction only works for indices.  The equivalent instruction
** for tables is OP_Insert.
*/
case OP_IdxInsert: {        /* in2 */
  VdbeCursor *pC;
  Mem *pKey;
  Mem *pData;

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC );
  assert( pC->pKVCur );
  assert( pC->pKVCur->pStore );
  pKey = &aMem[pOp->p3];
  assert( pKey->flags & MEM_Blob );
  pData = &aMem[pOp->p2];
  assert( pData->flags & MEM_Blob );
  rc = sqlite4KVStoreReplace(
     pC->pKVCur->pStore,
     pKey->z, pKey->n,
     pData->z, pData->n
  );
  break;
}

/* Opcode: IdxDelete P1 P2 P3 * *
**
** The content of P3 registers starting at register P2 form
** an unpacked index key. This opcode removes that entry from the