aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/build.c17
-rw-r--r--src/prepare.c6
-rw-r--r--src/sqliteInt.h14
-rw-r--r--src/vdbe.c31
-rw-r--r--src/vdbeInt.h5
-rw-r--r--src/vdbeaux.c46
6 files changed, 71 insertions, 48 deletions
diff --git a/src/build.c b/src/build.c
index 39de2fdc9..b0e81003d 100644
--- a/src/build.c
+++ b/src/build.c
@@ -22,7 +22,7 @@
** COMMIT
** ROLLBACK
**
-** $Id: build.c,v 1.362 2005/12/29 01:11:37 drh Exp $
+** $Id: build.c,v 1.363 2005/12/29 19:23:07 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@@ -764,7 +764,7 @@ void sqlite3StartTable(
sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 1); /* file_format */
lbl = sqlite3VdbeMakeLabel(v);
sqlite3VdbeAddOp(v, OP_If, 0, lbl);
- sqlite3VdbeAddOp(v, OP_Integer, 1, 0); /* file format defaults to 1 */
+ sqlite3VdbeAddOp(v, OP_Integer, SQLITE_DEFAULT_FILE_FORMAT, 0);
sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 1);
sqlite3VdbeAddOp(v, OP_Integer, db->enc, 0);
sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 4);
@@ -2112,7 +2112,6 @@ void sqlite3CreateIndex(
Token nullId; /* Fake token for an empty ID list */
DbFixer sFix; /* For assigning database names to pTable */
int sortOrderMask; /* 1 to honor DESC in index. 0 to ignore. */
- int descSeen = 0; /* Changes to true if a DESC is seen */
sqlite3 *db = pParse->db;
Db *pDb; /* The specific table containing the indexed database */
int iDb; /* Index of the database that is being written */
@@ -2264,7 +2263,7 @@ void sqlite3CreateIndex(
/* Check to see if we should honor DESC requests on index columns
*/
- if( pDb->file_format>=4 || (!pDb->descIndex && !db->init.busy) ){
+ if( pDb->file_format>=4 ){
sortOrderMask = -1; /* Honor DESC */
}else{
sortOrderMask = 0; /* Ignore DESC */
@@ -2299,11 +2298,8 @@ void sqlite3CreateIndex(
){
goto exit_create_index;
}
- requestedSortOrder = pListItem->sortOrder;
- pDb->descIndex |= requestedSortOrder;
- requestedSortOrder &= sortOrderMask;
+ requestedSortOrder = pListItem->sortOrder & sortOrderMask;
pIndex->keyInfo.aSortOrder[i] = requestedSortOrder;
- descSeen |= requestedSortOrder;
}
pIndex->keyInfo.nField = pList->nExpr;
sqlite3DefaultRowEst(pIndex);
@@ -2404,11 +2400,6 @@ void sqlite3CreateIndex(
sqlite3VdbeAddOp(v, OP_CreateIndex, iDb, 0);
sqlite3VdbeAddOp(v, OP_MemStore, iMem, 0);
- /* Make sure the file_format is at least 4 if we have DESC indices. */
- if( descSeen ){
- sqlite3MinimumFileFormat(pParse, iDb, 4);
- }
-
/* Gather the complete text of the CREATE INDEX statement into
** the zStmt variable
*/
diff --git a/src/prepare.c b/src/prepare.c
index f530dd874..164c4149e 100644
--- a/src/prepare.c
+++ b/src/prepare.c
@@ -13,7 +13,7 @@
** interface, and routines that contribute to loading the database schema
** from disk.
**
-** $Id: prepare.c,v 1.10 2005/12/16 01:06:17 drh Exp $
+** $Id: prepare.c,v 1.11 2005/12/29 19:23:07 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -258,13 +258,13 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
** file_format==1 Version 3.0.0.
** file_format==2 Version 3.1.3. // ALTER TABLE ADD COLUMN
** file_format==3 Version 3.1.4. // ditto but with non-NULL defaults
- ** file_format==4 Version 3.3.0. // DESC indices
+ ** file_format==4 Version 3.3.0. // DESC indices. Boolean constants
*/
pDb->file_format = meta[1];
if( pDb->file_format==0 ){
pDb->file_format = 1;
}
- if( pDb->file_format>4 ){
+ if( pDb->file_format>SQLITE_MAX_FILE_FORMAT ){
sqlite3BtreeCloseCursor(curMain);
sqlite3SetString(pzErrMsg, "unsupported file format", (char*)0);
return SQLITE_ERROR;
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index b5ff1c207..2737c1d16 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -11,7 +11,7 @@
*************************************************************************
** Internal interface definitions for SQLite.
**
-** @(#) $Id: sqliteInt.h,v 1.443 2005/12/29 01:11:37 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.444 2005/12/29 19:23:07 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
@@ -141,6 +141,17 @@
#define SQLITE_MAX_VARIABLE_NUMBER 999
/*
+** The "file format" number is an integer that is incremented whenever
+** the VDBE-level file format changes. The following macros define the
+** the default file format for new databases and the maximum file format
+** that the library can read.
+*/
+#define SQLITE_MAX_FILE_FORMAT 4
+#ifndef SQLITE_DEFAULT_FILE_FORMAT
+# define SQLITE_DEFAULT_FILE_FORMAT 4
+#endif
+
+/*
** Provide a default value for TEMP_STORE in case it is not specified
** on the command-line
*/
@@ -360,7 +371,6 @@ struct Db {
u8 inTrans; /* 0: not writable. 1: Transaction. 2: Checkpoint */
u8 safety_level; /* How aggressive at synching data to disk */
u8 file_format; /* Schema format version for this file */
- u8 descIndex; /* True if any index uses the DESC attribute */
int cache_size; /* Number of pages to use in the cache */
Table *pSeqTab; /* The sqlite_sequence table used by AUTOINCREMENT */
void *pAux; /* Auxiliary data. Usually NULL */
diff --git a/src/vdbe.c b/src/vdbe.c
index ed8f392b8..0c1a9f7c4 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -43,7 +43,7 @@
** 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.508 2005/12/21 18:36:46 drh Exp $
+** $Id: vdbe.c,v 1.509 2005/12/29 19:23:07 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -2107,7 +2107,7 @@ op_column_out:
**
** See also OP_MakeIdxRec
*/
-/* Opcode: MakeRecordI P1 P2 P3
+/* Opcode: MakeIdxRec P1 P2 P3
**
** This opcode works just OP_MakeRecord except that it reads an extra
** integer from the stack (thus reading a total of abs(P1+1) entries)
@@ -2149,6 +2149,7 @@ case OP_MakeRecord: {
int jumpIfNull; /* Jump here if non-zero and any entries are NULL. */
int addRowid; /* True to append a rowid column at the end */
char *zAffinity; /* The affinity string for the record */
+ int file_format; /* File format to use for encoding */
leaveOnStack = ((pOp->p1<0)?1:0);
nField = pOp->p1 * (leaveOnStack?-1:1);
@@ -2159,6 +2160,7 @@ case OP_MakeRecord: {
pData0 = &pTos[1-nField];
assert( pData0>=p->aStack );
containsNull = 0;
+ file_format = p->minWriteFileFormat;
/* Loop through the elements that will make up the record to figure
** out how much space is required for the new record.
@@ -2170,7 +2172,7 @@ case OP_MakeRecord: {
if( pRec->flags&MEM_Null ){
containsNull = 1;
}
- serial_type = sqlite3VdbeSerialType(pRec);
+ serial_type = sqlite3VdbeSerialType(pRec, file_format);
nData += sqlite3VdbeSerialTypeLen(serial_type);
nHdr += sqlite3VarintLen(serial_type);
}
@@ -2183,7 +2185,7 @@ case OP_MakeRecord: {
pRowid = &pTos[0-nField];
assert( pRowid>=p->aStack );
sqlite3VdbeMemIntegerify(pRowid);
- serial_type = sqlite3VdbeSerialType(pRowid);
+ serial_type = sqlite3VdbeSerialType(pRowid, 0);
nData += sqlite3VdbeSerialTypeLen(serial_type);
nHdr += sqlite3VarintLen(serial_type);
}
@@ -2209,17 +2211,17 @@ case OP_MakeRecord: {
zCsr = zNewRecord;
zCsr += sqlite3PutVarint(zCsr, nHdr);
for(pRec=pData0; pRec<=pTos; pRec++){
- serial_type = sqlite3VdbeSerialType(pRec);
+ serial_type = sqlite3VdbeSerialType(pRec, file_format);
zCsr += sqlite3PutVarint(zCsr, serial_type); /* serial type */
}
if( addRowid ){
- zCsr += sqlite3PutVarint(zCsr, sqlite3VdbeSerialType(pRowid));
+ zCsr += sqlite3PutVarint(zCsr, sqlite3VdbeSerialType(pRowid, 0));
}
for(pRec=pData0; pRec<=pTos; pRec++){
- zCsr += sqlite3VdbeSerialPut(zCsr, pRec); /* serial data */
+ zCsr += sqlite3VdbeSerialPut(zCsr, pRec, file_format); /* serial data */
}
if( addRowid ){
- zCsr += sqlite3VdbeSerialPut(zCsr, pRowid);
+ zCsr += sqlite3VdbeSerialPut(zCsr, pRowid, 0);
}
assert( zCsr==(zNewRecord+nByte) );
@@ -2515,6 +2517,7 @@ case OP_OpenWrite: { /* no-push */
Btree *pX;
int iDb;
Cursor *pCur;
+ Db *pDb;
assert( pTos>=p->aStack );
sqlite3VdbeMemIntegerify(pTos);
@@ -2522,9 +2525,17 @@ case OP_OpenWrite: { /* no-push */
assert( (pTos->flags & MEM_Dyn)==0 );
pTos--;
assert( iDb>=0 && iDb<db->nDb );
- pX = db->aDb[iDb].pBt;
+ pDb = &db->aDb[iDb];
+ pX = pDb->pBt;
assert( pX!=0 );
- wrFlag = pOp->opcode==OP_OpenWrite;
+ if( pOp->opcode==OP_OpenWrite ){
+ wrFlag = 1;
+ if( pDb->file_format < p->minWriteFileFormat ){
+ p->minWriteFileFormat = pDb->file_format;
+ }
+ }else{
+ wrFlag = 0;
+ }
if( p2<=0 ){
assert( pTos>=p->aStack );
sqlite3VdbeMemIntegerify(pTos);
diff --git a/src/vdbeInt.h b/src/vdbeInt.h
index 10f3e0660..5871bf296 100644
--- a/src/vdbeInt.h
+++ b/src/vdbeInt.h
@@ -307,6 +307,7 @@ struct Vdbe {
u8 changeCntOn; /* True to update the change-counter */
u8 aborted; /* True if ROLLBACK in another VM causes an abort */
u8 expired; /* True if the VM needs to be recompiled */
+ u8 minWriteFileFormat; /* Minimum file format for writable database files */
int nChange; /* Number of db changes made since last reset */
i64 startTime; /* Time when query started - used for profiling */
};
@@ -332,8 +333,8 @@ void sqlite3VdbePrintOp(FILE*, int, Op*);
void sqlite3VdbePrintSql(Vdbe*);
#endif
int sqlite3VdbeSerialTypeLen(u32);
-u32 sqlite3VdbeSerialType(Mem*);
-int sqlite3VdbeSerialPut(unsigned char*, Mem*);
+u32 sqlite3VdbeSerialType(Mem*, int);
+int sqlite3VdbeSerialPut(unsigned char*, Mem*, int);
int sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
void sqlite3VdbeDeleteAuxData(VdbeFunc*, int);
diff --git a/src/vdbeaux.c b/src/vdbeaux.c
index 4f291e385..33652fbe6 100644
--- a/src/vdbeaux.c
+++ b/src/vdbeaux.c
@@ -782,6 +782,7 @@ void sqlite3VdbeMakeReady(
p->explain |= isExplain;
p->magic = VDBE_MAGIC_RUN;
p->nChange = 0;
+ p->minWriteFileFormat = 255;
#ifdef VDBE_PROFILE
{
int i;
@@ -1490,7 +1491,9 @@ int sqlite3VdbeCursorMoveto(Cursor *p){
** 5 6 signed integer
** 6 8 signed integer
** 7 8 IEEE float
-** 8-11 reserved for expansion
+** 8 0 Integer constant 0
+** 9 0 Integer constant 1
+** 10,11 reserved for expansion
** N>=12 and even (N-12)/2 BLOB
** N>=13 and odd (N-13)/2 text
**
@@ -1499,7 +1502,7 @@ int sqlite3VdbeCursorMoveto(Cursor *p){
/*
** Return the serial-type for the value stored in pMem.
*/
-u32 sqlite3VdbeSerialType(Mem *pMem){
+u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){
int flags = pMem->flags;
if( flags&MEM_Null ){
@@ -1509,7 +1512,11 @@ u32 sqlite3VdbeSerialType(Mem *pMem){
/* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */
# define MAX_6BYTE ((((i64)0x00001000)<<32)-1)
i64 i = pMem->i;
- u64 u = i<0 ? -i : i;
+ u64 u;
+ if( file_format>=4 && (i&1)==i ){
+ return 8+i;
+ }
+ u = i<0 ? -i : i;
if( u<=127 ) return 1;
if( u<=32767 ) return 2;
if( u<=8388607 ) return 3;
@@ -1548,17 +1555,12 @@ int sqlite3VdbeSerialTypeLen(u32 serial_type){
** buf. It is assumed that the caller has allocated sufficient space.
** Return the number of bytes written.
*/
-int sqlite3VdbeSerialPut(unsigned char *buf, Mem *pMem){
- u32 serial_type = sqlite3VdbeSerialType(pMem);
+int sqlite3VdbeSerialPut(unsigned char *buf, Mem *pMem, int file_format){
+ u32 serial_type = sqlite3VdbeSerialType(pMem, file_format);
int len;
- /* NULL */
- if( serial_type==0 ){
- return 0;
- }
-
/* Integer and Real */
- if( serial_type<=7 ){
+ if( serial_type<=7 && serial_type>0 ){
u64 v;
int i;
if( serial_type==7 ){
@@ -1573,12 +1575,16 @@ int sqlite3VdbeSerialPut(unsigned char *buf, Mem *pMem){
}
return len;
}
-
+
/* String or blob */
- assert( serial_type>=12 );
- len = sqlite3VdbeSerialTypeLen(serial_type);
- memcpy(buf, pMem->z, len);
- return len;
+ if( serial_type>=12 ){
+ len = sqlite3VdbeSerialTypeLen(serial_type);
+ memcpy(buf, pMem->z, len);
+ return len;
+ }
+
+ /* NULL or constants 0 or 1 */
+ return 0;
}
/*
@@ -1591,8 +1597,6 @@ int sqlite3VdbeSerialGet(
Mem *pMem /* Memory cell to write value into */
){
switch( serial_type ){
- case 8: /* Reserved for future use */
- case 9: /* Reserved for future use */
case 10: /* Reserved for future use */
case 11: /* Reserved for future use */
case 0: { /* NULL */
@@ -1651,6 +1655,12 @@ int sqlite3VdbeSerialGet(
}
return 8;
}
+ case 8: /* Integer 0 */
+ case 9: { /* Integer 1 */
+ pMem->i = serial_type-8;
+ pMem->flags = MEM_Int;
+ return 0;
+ }
default: {
int len = (serial_type-12)/2;
pMem->z = (char *)buf;