updated to Sqlite 3.3.5 sources

This commit is contained in:
tabuleiro
2006-05-04 13:48:36 +00:00
parent cb37ba2c45
commit ff68326d19
46 changed files with 1807 additions and 1543 deletions

View File

@@ -35,7 +35,7 @@
<string>Version 1.3
SQLite Database Browser is an open source, public domain, freeware visual tool used to create, design and edit SQLite 3.x database files.
This program was built with version 3.3.4 of the SQLite engine.
This program was built with version 3.3.5 of the SQLite engine.
More information at http://sqlitebrowser.sourceforge.net.</string>
</property>

View File

@@ -12,7 +12,7 @@
** This file contains C code routines that used to generate VDBE code
** that implements the ALTER TABLE command.
**
** $Id: alter.c,v 1.4 2006-02-16 10:11:46 jmiltner Exp $
** $Id: alter.c,v 1.5 2006-05-04 13:48:36 tabuleiro Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

View File

@@ -11,7 +11,7 @@
*************************************************************************
** This file contains code associated with the ANALYZE command.
**
** @(#) $Id: analyze.c,v 1.1 2006-02-16 10:11:46 jmiltner Exp $
** @(#) $Id: analyze.c,v 1.2 2006-05-04 13:48:36 tabuleiro Exp $
*/
#ifndef SQLITE_OMIT_ANALYZE
#include "sqliteInt.h"

View File

@@ -11,7 +11,7 @@
*************************************************************************
** This file contains code used to implement the ATTACH and DETACH commands.
**
** $Id: attach.c,v 1.6 2006-02-16 10:11:46 jmiltner Exp $
** $Id: attach.c,v 1.7 2006-05-04 13:48:36 tabuleiro Exp $
*/
#include "sqliteInt.h"
@@ -185,7 +185,12 @@ static void attachFunc(
}
sqlite3ResetInternalSchema(db, 0);
db->nDb = iDb;
sqlite3_snprintf(127, zErr, "unable to open database: %s", zFile);
if( rc==SQLITE_NOMEM ){
sqlite3MallocFailed();
sqlite3_snprintf(127, zErr, "out of memory");
}else{
sqlite3_snprintf(127, zErr, "unable to open database: %s", zFile);
}
goto attach_error;
}

View File

@@ -14,7 +14,7 @@
** systems that do not need this facility may omit it by recompiling
** the library with -DSQLITE_OMIT_AUTHORIZATION=1
**
** $Id: auth.c,v 1.6 2006-02-16 10:11:46 jmiltner Exp $
** $Id: auth.c,v 1.7 2006-05-04 13:48:36 tabuleiro Exp $
*/
#include "sqliteInt.h"

View File

@@ -9,7 +9,7 @@
** May you share freely, never taking more than you give.
**
*************************************************************************
** $Id: btree.c,v 1.6 2006-02-16 10:11:46 jmiltner Exp $
** $Id: btree.c,v 1.7 2006-05-04 13:48:36 tabuleiro Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
@@ -388,8 +388,8 @@ struct BtCursor {
u8 wrFlag; /* True if writable */
u8 eState; /* One of the CURSOR_XXX constants (see below) */
#ifndef SQLITE_OMIT_SHARED_CACHE
void *pKey;
i64 nKey;
void *pKey; /* Saved key that was cursor's last known position */
i64 nKey; /* Size of pKey, or last integer key */
int skip; /* (skip<0) -> Prev() is a no-op. (skip>0) -> Next() is */
#endif
};
@@ -469,8 +469,15 @@ static void put4byte(unsigned char *p, u32 v){
/* The database page the PENDING_BYTE occupies. This page is never used.
** TODO: This macro is very similary to PAGER_MJ_PGNO() in pager.c. They
** should possibly be consolidated (presumably in pager.h).
**
** If disk I/O is omitted (meaning that the database is stored purely
** in memory) then there is no pending byte.
*/
#define PENDING_BYTE_PAGE(pBt) ((PENDING_BYTE/(pBt)->pageSize)+1)
#ifdef SQLITE_OMIT_DISKIO
# define PENDING_BYTE_PAGE(pBt) 0x7fffffff
#else
# define PENDING_BYTE_PAGE(pBt) ((PENDING_BYTE/(pBt)->pageSize)+1)
#endif
/*
** A linked list of the following structures is stored at BtShared.pLock.
@@ -867,7 +874,8 @@ static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){
}
offset = PTRMAP_PTROFFSET(pBt, key);
if( pEType ) *pEType = pPtrmap[offset];
assert( pEType!=0 );
*pEType = pPtrmap[offset];
if( pPgno ) *pPgno = get4byte(&pPtrmap[offset+1]);
sqlite3pager_unref(pPtrmap);
@@ -1273,6 +1281,12 @@ static void freeSpace(MemPage *pPage, int start, int size){
assert( (start + size)<=pPage->pBt->usableSize );
if( size<4 ) size = 4;
#ifdef SQLITE_SECURE_DELETE
/* Overwrite deleted information with zeros when the SECURE_DELETE
** option is enabled at compile-time */
memset(&data[start], 0, size);
#endif
/* Add the space back into the linked list of freeblocks */
hdr = pPage->hdrOffset;
addr = hdr + 1;
@@ -1618,8 +1632,8 @@ int sqlite3BtreeOpen(
** the right size. This is to guard against size changes that result
** when compiling on a different architecture.
*/
assert( sizeof(i64)==8 );
assert( sizeof(u64)==8 );
assert( sizeof(i64)==8 || sizeof(i64)==4 );
assert( sizeof(u64)==8 || sizeof(u64)==4 );
assert( sizeof(u32)==4 );
assert( sizeof(u16)==2 );
assert( sizeof(Pgno)==4 );
@@ -1679,7 +1693,7 @@ int sqlite3BtreeOpen(
assert( (pBt->pageSize & 7)==0 ); /* 8-byte alignment of pageSize */
sqlite3pager_set_pagesize(pBt->pPager, pBt->pageSize);
#ifndef SQLITE_OMIT_SHARED_CACHE
#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
/* Add the new btree to the linked list starting at ThreadData.pBtree.
** There is no chance that a malloc() may fail inside of the
** sqlite3ThreadData() call, as the ThreadData structure must have already
@@ -1744,7 +1758,7 @@ int sqlite3BtreeClose(Btree *p){
pTsd->pBtree = pBt->pNext;
}else{
BtShared *pPrev;
for(pPrev=pTsd->pBtree; pPrev && pPrev->pNext!=pBt; pPrev=pPrev->pNext);
for(pPrev=pTsd->pBtree; pPrev && pPrev->pNext!=pBt; pPrev=pPrev->pNext){}
if( pPrev ){
assert( pTsd==sqlite3ThreadData() );
pPrev->pNext = pBt->pNext;
@@ -2457,7 +2471,6 @@ static int autoVacuumCommit(BtShared *pBt, Pgno *nTrunc){
if( rc!=SQLITE_OK ) goto autovacuum_out;
put4byte(&pBt->pPage1->aData[32], 0);
put4byte(&pBt->pPage1->aData[36], 0);
if( rc!=SQLITE_OK ) goto autovacuum_out;
*nTrunc = finSize;
assert( finSize!=PENDING_BYTE_PAGE(pBt) );
@@ -3879,6 +3892,15 @@ static int freePage(MemPage *pPage){
n = get4byte(&pPage1->aData[36]);
put4byte(&pPage1->aData[36], n+1);
#ifdef SQLITE_SECURE_DELETE
/* If the SQLITE_SECURE_DELETE compile-time option is enabled, then
** always fully overwrite deleted information with zeros.
*/
rc = sqlite3pager_write(pPage->aData);
if( rc ) return rc;
memset(pPage->aData, 0, pPage->pBt->pageSize);
#endif
#ifndef SQLITE_OMIT_AUTOVACUUM
/* If the database supports auto-vacuum, write an entry in the pointer-map
** to indicate that the page is free.
@@ -3919,7 +3941,9 @@ static int freePage(MemPage *pPage){
if( rc ) return rc;
put4byte(&pTrunk->aData[4], k+1);
put4byte(&pTrunk->aData[8+k*4], pPage->pgno);
#ifndef SQLITE_SECURE_DELETE
sqlite3pager_dont_write(pBt->pPager, pPage->pgno);
#endif
TRACE(("FREE-PAGE: %d leaf on trunk page %d\n",pPage->pgno,pTrunk->pgno));
}
releasePage(pTrunk);
@@ -4052,6 +4076,7 @@ static int fillInCell(
n = nPayload;
if( n>spaceLeft ) n = spaceLeft;
if( n>nSrc ) n = nSrc;
assert( pSrc );
memcpy(pPayload, pSrc, n);
nPayload -= n;
pPayload += n;
@@ -4076,6 +4101,7 @@ static int reparentPage(BtShared *pBt, Pgno pgno, MemPage *pNewParent, int idx){
MemPage *pThis;
unsigned char *aData;
assert( pNewParent!=0 );
if( pgno==0 ) return SQLITE_OK;
assert( pBt->pPager!=0 );
aData = sqlite3pager_lookup(pBt->pPager, pgno);
@@ -4086,7 +4112,7 @@ static int reparentPage(BtShared *pBt, Pgno pgno, MemPage *pNewParent, int idx){
if( pThis->pParent!=pNewParent ){
if( pThis->pParent ) sqlite3pager_unref(pThis->pParent->aData);
pThis->pParent = pNewParent;
if( pNewParent ) sqlite3pager_ref(pNewParent->aData);
sqlite3pager_ref(pNewParent->aData);
}
pThis->idxParent = idx;
}
@@ -4799,6 +4825,7 @@ static int balance_nonroot(MemPage *pPage){
rc = sqlite3pager_write(pNew->aData);
if( rc ) goto balance_cleanup;
}else{
assert( i>0 );
rc = allocatePage(pBt, &pNew, &pgnoNew[i], pgnoNew[i-1], 0);
if( rc ) goto balance_cleanup;
apNew[i] = pNew;
@@ -4950,6 +4977,8 @@ static int balance_nonroot(MemPage *pPage){
}
}
assert( j==nCell );
assert( nOld>0 );
assert( nNew>0 );
if( (pageFlags & PTF_LEAF)==0 ){
memcpy(&apNew[nNew-1]->aData[8], &apCopy[nOld-1]->aData[8], 4);
}
@@ -6204,11 +6233,7 @@ static int checkTreePage(
IntegrityCk *pCheck, /* Context for the sanity check */
int iPage, /* Page number of the page to check */
MemPage *pParent, /* Parent page */
char *zParentContext, /* Parent context */
char *zLowerBound, /* All keys should be greater than this, if not NULL */
int nLower, /* Number of characters in zLowerBound */
char *zUpperBound, /* All keys should be less than this, if not NULL */
int nUpper /* Number of characters in zUpperBound */
char *zParentContext /* Parent context */
){
MemPage *pPage;
int i, rc, depth, d2, pgno, cnt;
@@ -6274,7 +6299,7 @@ static int checkTreePage(
checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage, zContext);
}
#endif
d2 = checkTreePage(pCheck,pgno,pPage,zContext,0,0,0,0);
d2 = checkTreePage(pCheck,pgno,pPage,zContext);
if( i>0 && d2!=depth ){
checkAppendMsg(pCheck, zContext, "Child page depth differs");
}
@@ -6289,7 +6314,7 @@ static int checkTreePage(
checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage, 0);
}
#endif
checkTreePage(pCheck, pgno, pPage, zContext,0,0,0,0);
checkTreePage(pCheck, pgno, pPage, zContext);
}
/* Check for complete coverage of the page
@@ -6401,7 +6426,7 @@ char *sqlite3BtreeIntegrityCheck(Btree *p, int *aRoot, int nRoot){
checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0, 0);
}
#endif
checkTreePage(&sCheck, aRoot[i], 0, "List of tree roots: ", 0,0,0,0);
checkTreePage(&sCheck, aRoot[i], 0, "List of tree roots: ");
}
/* Make sure every page in the file is referenced
@@ -6598,17 +6623,23 @@ int sqlite3BtreeSchemaLocked(Btree *p){
return (queryTableLock(p, MASTER_ROOT, READ_LOCK)!=SQLITE_OK);
}
#ifndef SQLITE_OMIT_SHARED_CACHE
/*
** Obtain a lock on the table whose root page is iTab. The
** lock is a write lock if isWritelock is true or a read lock
** if it is false.
*/
int sqlite3BtreeLockTable(Btree *p, int iTab, u8 isWriteLock){
int rc = SQLITE_OK;
#ifndef SQLITE_OMIT_SHARED_CACHE
u8 lockType = (isWriteLock?WRITE_LOCK:READ_LOCK);
rc = queryTableLock(p, iTab, lockType);
if( rc==SQLITE_OK ){
rc = lockTable(p, iTab, lockType);
}
#endif
return rc;
}
#endif
/*
** The following debugging interface has to be in this file (rather
@@ -6623,6 +6654,7 @@ int sqlite3_shared_cache_report(
int objc,
Tcl_Obj *CONST objv[]
){
#ifndef SQLITE_OMIT_SHARED_CACHE
const ThreadData *pTd = sqlite3ThreadDataReadOnly();
if( pTd->useSharedData ){
BtShared *pBt;
@@ -6634,6 +6666,7 @@ int sqlite3_shared_cache_report(
}
Tcl_SetObjResult(interp, pRet);
}
#endif
return TCL_OK;
}
#endif

View File

@@ -13,7 +13,7 @@
** subsystem. See comments in the source code for a detailed description
** of what each interface routine does.
**
** @(#) $Id: btree.h,v 1.6 2006-02-16 10:11:46 jmiltner Exp $
** @(#) $Id: btree.h,v 1.7 2006-05-04 13:48:36 tabuleiro Exp $
*/
#ifndef _BTREE_H_
#define _BTREE_H_

View File

@@ -22,7 +22,7 @@
** COMMIT
** ROLLBACK
**
** $Id: build.c,v 1.6 2006-02-16 10:11:46 jmiltner Exp $
** $Id: build.c,v 1.7 2006-05-04 13:48:36 tabuleiro Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@@ -42,26 +42,28 @@ void sqlite3BeginParse(Parse *pParse, int explainFlag){
** codeTableLocks() functions.
*/
struct TableLock {
int iDb;
int iTab;
u8 isWriteLock;
const char *zName;
int iDb; /* The database containing the table to be locked */
int iTab; /* The root page of the table to be locked */
u8 isWriteLock; /* True for write lock. False for a read lock */
const char *zName; /* Name of the table */
};
/*
** Have the compiled statement lock the table with rootpage iTab in database
** iDb at the shared-cache level when executed. The isWriteLock argument
** is zero for a read-lock, or non-zero for a write-lock.
** Record the fact that we want to lock a table at run-time.
**
** The zName parameter should point to the unqualified table name. This is
** used to provide a more informative error message should the lock fail.
** The table to be locked has root page iTab and is found in database iDb.
** A read or a write lock can be taken depending on isWritelock.
**
** This routine just records the fact that the lock is desired. The
** code to make the lock occur is generated by a later call to
** codeTableLocks() which occurs during sqlite3FinishCoding().
*/
void sqlite3TableLock(
Parse *pParse,
int iDb,
int iTab,
u8 isWriteLock,
const char *zName
Parse *pParse, /* Parsing context */
int iDb, /* Index of the database containing the table to lock */
int iTab, /* Root page number of the table to be locked */
u8 isWriteLock, /* True for a write lock */
const char *zName /* Name of the table to be locked */
){
int i;
int nBytes;
@@ -135,8 +137,8 @@ void sqlite3FinishCoding(Parse *pParse){
if( !pParse->pVdbe ){
if( pParse->rc==SQLITE_OK && pParse->nErr ){
pParse->rc = SQLITE_ERROR;
return;
}
return;
}
/* Begin by generating some termination code at the end of the
@@ -185,7 +187,7 @@ void sqlite3FinishCoding(Parse *pParse){
/* Get the VDBE program ready for execution
*/
if( v && pParse->nErr==0 ){
if( v && pParse->nErr==0 && !sqlite3MallocFailed() ){
FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0;
sqlite3VdbeTrace(v, trace);
sqlite3VdbeMakeReady(v, pParse->nVar, pParse->nMem+3,
@@ -338,7 +340,7 @@ static void freeIndex(Index *p){
** it is not unlinked from the Table that it indexes.
** Unlinking from the Table must be done by the calling function.
*/
static void sqliteDeleteIndex(sqlite3 *db, Index *p){
static void sqliteDeleteIndex(Index *p){
Index *pOld;
const char *zName = p->zName;
@@ -507,7 +509,7 @@ void sqlite3DeleteTable(sqlite3 *db, Table *pTable){
for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){
pNext = pIndex->pNext;
assert( pIndex->pSchema==pTable->pSchema );
sqliteDeleteIndex(db, pIndex);
sqliteDeleteIndex(pIndex);
}
#ifndef SQLITE_OMIT_FOREIGN_KEY
@@ -690,8 +692,7 @@ int sqlite3CheckObjectName(Parse *pParse, const char *zName){
** Begin constructing a new table representation in memory. This is
** the first of several action routines that get called in response
** to a CREATE TABLE statement. In particular, this routine is called
** after seeing tokens "CREATE" and "TABLE" and the table name. The
** pStart token is the CREATE and pName is the table name. The isTemp
** after seeing tokens "CREATE" and "TABLE" and the table name. The isTemp
** flag is true if the table should be stored in the auxiliary database
** file instead of in the main database file. This is normally the case
** when the "TEMP" or "TEMPORARY" keyword occurs in between
@@ -705,7 +706,6 @@ int sqlite3CheckObjectName(Parse *pParse, const char *zName){
*/
void sqlite3StartTable(
Parse *pParse, /* Parser context */
Token *pStart, /* The "CREATE" token */
Token *pName1, /* First part of the name of the table or view */
Token *pName2, /* Second part of the name of the table or view */
int isTemp, /* True if this is a TEMP table */
@@ -1584,7 +1584,7 @@ void sqlite3CreateView(
sqlite3SelectDelete(pSelect);
return;
}
sqlite3StartTable(pParse, pBegin, pName1, pName2, isTemp, 1, 0);
sqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0);
p = pParse->pNewTable;
if( p==0 || pParse->nErr ){
sqlite3SelectDelete(pSelect);
@@ -1727,6 +1727,17 @@ static void sqliteViewResetAll(sqlite3 *db, int idx){
** used by SQLite when the btree layer moves a table root page. The
** root-page of a table or index in database iDb has changed from iFrom
** to iTo.
**
** Ticket #1728: The symbol table might still contain information
** on tables and/or indices that are the process of being deleted.
** If you are unlucky, one of those deleted indices or tables might
** have the same rootpage number as the real table or index that is
** being moved. So we cannot stop searching after the first match
** because the first match might be for one of the deleted indices
** or tables and not the table/index that is actually being moved.
** We must continue looping until all tables and indices with
** rootpage==iFrom have been converted to have a rootpage of iTo
** in order to be certain that we got the right one.
*/
#ifndef SQLITE_OMIT_AUTOVACUUM
void sqlite3RootPageMoved(Db *pDb, int iFrom, int iTo){
@@ -1738,7 +1749,6 @@ void sqlite3RootPageMoved(Db *pDb, int iFrom, int iTo){
Table *pTab = sqliteHashData(pElem);
if( pTab->tnum==iFrom ){
pTab->tnum = iTo;
return;
}
}
pHash = &pDb->pSchema->idxHash;
@@ -1746,10 +1756,8 @@ void sqlite3RootPageMoved(Db *pDb, int iFrom, int iTo){
Index *pIdx = sqliteHashData(pElem);
if( pIdx->tnum==iFrom ){
pIdx->tnum = iTo;
return;
}
}
assert(0);
}
#endif
@@ -1925,7 +1933,7 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
while( pTrigger ){
assert( pTrigger->pSchema==pTab->pSchema ||
pTrigger->pSchema==db->aDb[1].pSchema );
sqlite3DropTriggerPtr(pParse, pTrigger, 1);
sqlite3DropTriggerPtr(pParse, pTrigger);
pTrigger = pTrigger->pNext;
}
@@ -2958,7 +2966,7 @@ void sqlite3RollbackTransaction(Parse *pParse){
** Make sure the TEMP database is open and available for use. Return
** the number of errors. Leave any error messages in the pParse structure.
*/
static int sqlite3OpenTempDatabase(Parse *pParse){
int sqlite3OpenTempDatabase(Parse *pParse){
sqlite3 *db = pParse->db;
if( db->aDb[1].pBt==0 && !pParse->explain ){
int rc = sqlite3BtreeFactory(db, 0, 0, MAX_PAGES, &db->aDb[1].pBt);
@@ -3018,7 +3026,7 @@ void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
if( iDb>=0 ){
assert( iDb<db->nDb );
assert( db->aDb[iDb].pBt!=0 || iDb==1 );
assert( iDb<32 );
assert( iDb<MAX_ATTACHED+2 );
mask = 1<<iDb;
if( (pParse->cookieMask & mask)==0 ){
pParse->cookieMask |= mask;
@@ -3110,7 +3118,7 @@ static void reindexDatabases(Parse *pParse, char const *zColl){
Table *pTab; /* A table in the database */
for(iDb=0, pDb=db->aDb; iDb<db->nDb; iDb++, pDb++){
if( pDb==0 ) continue;
assert( pDb!=0 );
for(k=sqliteHashFirst(&pDb->pSchema->tblHash); k; k=sqliteHashNext(k)){
pTab = (Table*)sqliteHashData(k);
reindexTable(pParse, pTab, zColl);

View File

@@ -13,7 +13,7 @@
** This file contains functions used to access the internal hash tables
** of user defined functions and collation sequences.
**
** $Id: callback.c,v 1.1 2006-02-16 10:11:46 jmiltner Exp $
** $Id: callback.c,v 1.2 2006-05-04 13:48:36 tabuleiro Exp $
*/
#include "sqliteInt.h"
@@ -178,9 +178,11 @@ static CollSeq *findCollSeqEntry(
** return the pColl pointer to be deleted (because it wasn't added
** to the hash table).
*/
assert( !pDel ||
(sqlite3MallocFailed() && pDel==pColl) );
sqliteFree(pDel);
assert( !pDel || (sqlite3MallocFailed() && pDel==pColl) );
if( pDel ){
sqliteFree(pDel);
pColl = 0;
}
}
}
return pColl;
@@ -312,3 +314,54 @@ FuncDef *sqlite3FindFunction(
}
return 0;
}
/*
** Free all resources held by the schema structure. The void* argument points
** at a Schema struct. This function does not call sqliteFree() on the
** pointer itself, it just cleans up subsiduary resources (i.e. the contents
** of the schema hash tables).
*/
void sqlite3SchemaFree(void *p){
Hash temp1;
Hash temp2;
HashElem *pElem;
Schema *pSchema = (Schema *)p;
temp1 = pSchema->tblHash;
temp2 = pSchema->trigHash;
sqlite3HashInit(&pSchema->trigHash, SQLITE_HASH_STRING, 0);
sqlite3HashClear(&pSchema->aFKey);
sqlite3HashClear(&pSchema->idxHash);
for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){
sqlite3DeleteTrigger((Trigger*)sqliteHashData(pElem));
}
sqlite3HashClear(&temp2);
sqlite3HashInit(&pSchema->tblHash, SQLITE_HASH_STRING, 0);
for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){
Table *pTab = sqliteHashData(pElem);
sqlite3DeleteTable(0, pTab);
}
sqlite3HashClear(&temp1);
pSchema->pSeqTab = 0;
pSchema->flags &= ~DB_SchemaLoaded;
}
/*
** Find and return the schema associated with a BTree. Create
** a new one if necessary.
*/
Schema *sqlite3SchemaGet(Btree *pBt){
Schema * p;
if( pBt ){
p = (Schema *)sqlite3BtreeSchema(pBt,sizeof(Schema),sqlite3SchemaFree);
}else{
p = (Schema *)sqliteMalloc(sizeof(Schema));
}
if( p && 0==p->file_format ){
sqlite3HashInit(&p->tblHash, SQLITE_HASH_STRING, 0);
sqlite3HashInit(&p->idxHash, SQLITE_HASH_STRING, 0);
sqlite3HashInit(&p->trigHash, SQLITE_HASH_STRING, 0);
sqlite3HashInit(&p->aFKey, SQLITE_HASH_STRING, 1);
}
return p;
}

View File

@@ -16,7 +16,7 @@
** separating it out, the code will be automatically omitted from
** static links that do not use it.
**
** $Id: complete.c,v 1.1 2006-02-16 10:11:46 jmiltner Exp $
** $Id: complete.c,v 1.2 2006-05-04 13:48:36 tabuleiro Exp $
*/
#include "sqliteInt.h"
#ifndef SQLITE_OMIT_COMPLETE

View File

@@ -16,7 +16,7 @@
** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: date.c,v 1.4 2006-02-16 10:11:46 jmiltner Exp $
** $Id: date.c,v 1.5 2006-05-04 13:48:36 tabuleiro Exp $
**
** NOTES:
**

View File

@@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser
** in order to generate code for DELETE FROM statements.
**
** $Id: delete.c,v 1.6 2006-02-16 10:11:46 jmiltner Exp $
** $Id: delete.c,v 1.7 2006-05-04 13:48:36 tabuleiro Exp $
*/
#include "sqliteInt.h"
@@ -382,7 +382,7 @@ void sqlite3GenerateRowDelete(
){
int addr;
addr = sqlite3VdbeAddOp(v, OP_NotExists, iCur, 0);
sqlite3GenerateRowIndexDelete(db, v, pTab, iCur, 0);
sqlite3GenerateRowIndexDelete(v, pTab, iCur, 0);
sqlite3VdbeAddOp(v, OP_Delete, iCur, (count?OPFLAG_NCHANGE:0));
if( count ){
sqlite3VdbeChangeP3(v, -1, pTab->zName, P3_STATIC);
@@ -407,7 +407,6 @@ void sqlite3GenerateRowDelete(
** deleted.
*/
void sqlite3GenerateRowIndexDelete(
sqlite3 *db, /* The database containing the index */
Vdbe *v, /* Generate code into this VDBE */
Table *pTab, /* Table containing the row to be deleted */
int iCur, /* Cursor number for the table */

View File

@@ -12,7 +12,7 @@
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
** $Id: expr.c,v 1.6 2006-02-16 10:11:46 jmiltner Exp $
** $Id: expr.c,v 1.7 2006-05-04 13:48:36 tabuleiro Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@@ -841,11 +841,13 @@ static int lookupName(
if( pSrcList ){
for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){
Table *pTab = pItem->pTab;
int iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
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 ){
@@ -1379,11 +1381,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 j;
for(j=0; j<3; j++){
aOp[j].opcode = OP_Noop;
}
sqlite3VdbeChangeToNoop(v, testAddr-1, 3);
testAddr = 0;
}
@@ -1692,7 +1690,9 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
#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;

View File

@@ -16,7 +16,7 @@
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: func.c,v 1.6 2006-02-16 10:11:46 jmiltner Exp $
** $Id: func.c,v 1.7 2006-05-04 13:48:36 tabuleiro Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@@ -121,7 +121,13 @@ static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
switch( sqlite3_value_type(argv[0]) ){
case SQLITE_INTEGER: {
i64 iVal = sqlite3_value_int64(argv[0]);
if( iVal<0 ) iVal = iVal * -1;
if( iVal<0 ){
if( (iVal<<1)==0 ){
sqlite3_result_error(context, "integer overflow", -1);
return;
}
iVal = -iVal;
}
sqlite3_result_int64(context, iVal);
break;
}
@@ -131,7 +137,7 @@ static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
}
default: {
double rVal = sqlite3_value_double(argv[0]);
if( rVal<0 ) rVal = rVal * -1.0;
if( rVal<0 ) rVal = -rVal;
sqlite3_result_double(context, rVal);
break;
}
@@ -195,10 +201,10 @@ static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
if( n>30 ) n = 30;
if( n<0 ) n = 0;
}
if( SQLITE_NULL==sqlite3_value_type(argv[0]) ) return;
if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
r = sqlite3_value_double(argv[0]);
sqlite3_snprintf(sizeof(zBuf),zBuf,"%.*f",n,r);
sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
sqlite3_result_double(context, atof(zBuf));
}
/*
@@ -258,9 +264,11 @@ static void randomFunc(
int argc,
sqlite3_value **argv
){
int r;
sqlite_int64 r;
sqlite3Randomness(sizeof(r), &r);
sqlite3_result_int(context, r);
if( (r<<1)==0 ) r = 0; /* Prevent 0x8000.... as the result so that we */
/* can always do abs() of the result */
sqlite3_result_int64(context, r);
}
/*
@@ -817,9 +825,11 @@ static void test_error(
*/
typedef struct SumCtx SumCtx;
struct SumCtx {
LONGDOUBLE_TYPE sum; /* Sum of terms */
i64 cnt; /* Number of elements summed */
u8 approx; /* True if sum is approximate */
double rSum; /* Floating point sum */
i64 iSum; /* Integer sum */
i64 cnt; /* Number of elements summed */
u8 overflow; /* True if integer overflow seen */
u8 approx; /* True if non-integer value was input to the sum */
};
/*
@@ -849,13 +859,18 @@ static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){
if( p && type!=SQLITE_NULL ){
p->cnt++;
if( type==SQLITE_INTEGER ){
p->sum += sqlite3_value_int64(argv[0]);
if( !p->approx ){
i64 iVal;
p->approx = p->sum!=(LONGDOUBLE_TYPE)(iVal = (i64)p->sum);
i64 v = sqlite3_value_int64(argv[0]);
p->rSum += v;
if( (p->approx|p->overflow)==0 ){
i64 iNewSum = p->iSum + v;
int s1 = p->iSum >> (sizeof(i64)*8-1);
int s2 = v >> (sizeof(i64)*8-1);
int s3 = iNewSum >> (sizeof(i64)*8-1);
p->overflow = (s1&s2&~s3) | (~s1&~s2&s3);
p->iSum = iNewSum;
}
}else{
p->sum += sqlite3_value_double(argv[0]);
p->rSum += sqlite3_value_double(argv[0]);
p->approx = 1;
}
}
@@ -864,10 +879,12 @@ static void sumFinalize(sqlite3_context *context){
SumCtx *p;
p = sqlite3_aggregate_context(context, 0);
if( p && p->cnt>0 ){
if( p->approx ){
sqlite3_result_double(context, p->sum);
if( p->overflow ){
sqlite3_result_error(context,"integer overflow",-1);
}else if( p->approx ){
sqlite3_result_double(context, p->rSum);
}else{
sqlite3_result_int64(context, (i64)p->sum);
sqlite3_result_int64(context, p->iSum);
}
}
}
@@ -875,13 +892,13 @@ static void avgFinalize(sqlite3_context *context){
SumCtx *p;
p = sqlite3_aggregate_context(context, 0);
if( p && p->cnt>0 ){
sqlite3_result_double(context, p->sum/(double)p->cnt);
sqlite3_result_double(context, p->rSum/(double)p->cnt);
}
}
static void totalFinalize(sqlite3_context *context){
SumCtx *p;
p = sqlite3_aggregate_context(context, 0);
sqlite3_result_double(context, p ? p->sum : 0.0);
sqlite3_result_double(context, p ? p->rSum : 0.0);
}
/*
@@ -1062,7 +1079,7 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
}
sqlite3RegisterDateTimeFunctions(db);
#ifdef SQLITE_SSE
sqlite3SseFunctions(db);
(void)sqlite3SseFunctions(db);
#endif
#ifdef SQLITE_CASE_SENSITIVE_LIKE
sqlite3RegisterLikeFunctions(db, 1);

View File

@@ -12,7 +12,7 @@
** This is the implementation of generic hash-tables
** used in SQLite.
**
** $Id: hash.c,v 1.6 2006-02-16 10:11:46 jmiltner Exp $
** $Id: hash.c,v 1.7 2006-05-04 13:48:36 tabuleiro Exp $
*/
#include "sqliteInt.h"
#include <assert.h>
@@ -41,6 +41,8 @@ void sqlite3HashInit(Hash *pNew, int keyClass, int copyKey){
pNew->count = 0;
pNew->htsize = 0;
pNew->ht = 0;
pNew->xMalloc = sqlite3MallocX;
pNew->xFree = sqlite3FreeX;
}
/* Remove all entries from a hash table. Reclaim all memory.
@@ -53,15 +55,15 @@ void sqlite3HashClear(Hash *pH){
assert( pH!=0 );
elem = pH->first;
pH->first = 0;
if( pH->ht ) sqliteFree(pH->ht);
if( pH->ht ) pH->xFree(pH->ht);
pH->ht = 0;
pH->htsize = 0;
while( elem ){
HashElem *next_elem = elem->next;
if( pH->copyKey && elem->pKey ){
sqliteFree(elem->pKey);
pH->xFree(elem->pKey);
}
sqliteFree(elem);
pH->xFree(elem);
elem = next_elem;
}
pH->count = 0;
@@ -222,9 +224,9 @@ static void rehash(Hash *pH, int new_size){
int (*xHash)(const void*,int); /* The hash function */
assert( (new_size & (new_size-1))==0 );
new_ht = (struct _ht *)sqliteMalloc( new_size*sizeof(struct _ht) );
new_ht = (struct _ht *)pH->xMalloc( new_size*sizeof(struct _ht) );
if( new_ht==0 ) return;
if( pH->ht ) sqliteFree(pH->ht);
if( pH->ht ) pH->xFree(pH->ht);
pH->ht = new_ht;
pH->htsize = new_size;
xHash = hashFunction(pH->keyClass);
@@ -290,9 +292,9 @@ static void removeElementGivenHash(
pEntry->chain = 0;
}
if( pH->copyKey && elem->pKey ){
sqliteFree(elem->pKey);
pH->xFree(elem->pKey);
}
sqliteFree( elem );
pH->xFree( elem );
pH->count--;
if( pH->count<=0 ){
assert( pH->first==0 );
@@ -358,12 +360,12 @@ void *sqlite3HashInsert(Hash *pH, const void *pKey, int nKey, void *data){
return old_data;
}
if( data==0 ) return 0;
new_elem = (HashElem*)sqliteMalloc( sizeof(HashElem) );
new_elem = (HashElem*)pH->xMalloc( sizeof(HashElem) );
if( new_elem==0 ) return data;
if( pH->copyKey && pKey!=0 ){
new_elem->pKey = sqliteMallocRaw( nKey );
new_elem->pKey = pH->xMalloc( nKey );
if( new_elem->pKey==0 ){
sqliteFree(new_elem);
pH->xFree(new_elem);
return data;
}
memcpy((void*)new_elem->pKey, pKey, nKey);
@@ -376,7 +378,7 @@ void *sqlite3HashInsert(Hash *pH, const void *pKey, int nKey, void *data){
rehash(pH,8);
if( pH->htsize==0 ){
pH->count = 0;
sqliteFree(new_elem);
pH->xFree(new_elem);
return data;
}
}

View File

@@ -12,7 +12,7 @@
** This is the header file for the generic hash-table implemenation
** used in SQLite.
**
** $Id: hash.h,v 1.6 2006-02-16 10:11:46 jmiltner Exp $
** $Id: hash.h,v 1.7 2006-05-04 13:48:36 tabuleiro Exp $
*/
#ifndef _SQLITE_HASH_H_
#define _SQLITE_HASH_H_
@@ -34,6 +34,8 @@ struct Hash {
char copyKey; /* True if copy of key made on insert */
int count; /* Number of entries in this table */
HashElem *first; /* The first element of the array */
void *(*xMalloc)(int); /* malloc() function to use */
void (*xFree)(void *); /* free() function to use */
int htsize; /* Number of buckets in the hash table */
struct _ht { /* the hash table */
int count; /* Number of entries with this hash */

View File

@@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser
** to handle INSERT statements in SQLite.
**
** $Id: insert.c,v 1.6 2006-02-16 10:11:46 jmiltner Exp $
** $Id: insert.c,v 1.7 2006-05-04 13:48:36 tabuleiro Exp $
*/
#include "sqliteInt.h"
@@ -269,7 +269,7 @@ void sqlite3Insert(
if( sqlite3IsReadOnly(pParse, pTab, triggers_exist) ){
goto insert_cleanup;
}
if( pTab==0 ) goto insert_cleanup;
assert( pTab!=0 );
/* If pTab is really a view, make sure it has been initialized.
*/
@@ -874,7 +874,13 @@ void sqlite3GenerateConstraintChecks(
sqlite3ExprIfTrue(pParse, pTab->pCheck, allOk, 1);
assert( pParse->ckOffset==nCol );
pParse->ckOffset = 0;
sqlite3VdbeAddOp(v, OP_Halt, SQLITE_CONSTRAINT, OE_Abort);
onError = overrideError!=OE_Default ? overrideError : OE_Abort;
if( onError==OE_Ignore || onError==OE_Replace ){
sqlite3VdbeAddOp(v, OP_Pop, nCol+1+hasTwoRowids, 0);
sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest);
}else{
sqlite3VdbeAddOp(v, OP_Halt, SQLITE_CONSTRAINT, onError);
}
sqlite3VdbeResolveLabel(v, allOk);
}
#endif /* !defined(SQLITE_OMIT_CHECK) */
@@ -911,7 +917,7 @@ void sqlite3GenerateConstraintChecks(
break;
}
case OE_Replace: {
sqlite3GenerateRowIndexDelete(pParse->db, v, pTab, base, 0);
sqlite3GenerateRowIndexDelete(v, pTab, base, 0);
if( isUpdate ){
sqlite3VdbeAddOp(v, OP_Dup, nCol+hasTwoRowids, 1);
sqlite3VdbeAddOp(v, OP_MoveGe, base, 0);

View File

@@ -12,12 +12,12 @@ static int keywordCode(const char *z, int n){
"UNIQUEUSINGVACUUMVALUESVIEWHERE";
static const unsigned char aHash[127] = {
92, 80, 107, 91, 0, 4, 0, 0, 114, 0, 83, 0, 0,
96, 44, 76, 93, 0, 106, 109, 97, 90, 0, 10, 0, 0,
95, 44, 76, 93, 0, 106, 109, 97, 90, 0, 10, 0, 0,
113, 0, 110, 103, 0, 28, 48, 0, 41, 0, 0, 65, 71,
0, 63, 19, 0, 105, 36, 104, 0, 108, 75, 0, 0, 33,
0, 63, 19, 0, 105, 36, 104, 0, 108, 74, 0, 0, 33,
0, 61, 37, 0, 8, 0, 115, 38, 12, 0, 77, 40, 25,
66, 0, 0, 31, 81, 53, 30, 50, 20, 88, 0, 34, 0,
74, 26, 0, 72, 0, 0, 0, 64, 47, 67, 22, 87, 29,
75, 26, 0, 72, 0, 0, 0, 64, 47, 67, 22, 87, 29,
69, 86, 0, 1, 0, 9, 101, 58, 18, 0, 112, 82, 99,
54, 6, 85, 0, 0, 49, 94, 0, 102, 0, 70, 0, 0,
15, 0, 116, 51, 56, 0, 2, 55, 0, 111,
@@ -28,9 +28,9 @@ static int keywordCode(const char *z, int n){
0, 11, 0, 0, 0, 0, 5, 13, 0, 7, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 43, 0, 0, 0, 0, 0,
0, 0, 16, 0, 23, 52, 0, 0, 0, 0, 45, 0, 59,
0, 0, 0, 0, 0, 0, 0, 0, 42, 73, 0, 24, 60,
0, 0, 0, 0, 0, 0, 0, 0, 73, 42, 0, 24, 60,
21, 0, 79, 0, 0, 68, 0, 0, 84, 46, 0, 0, 0,
0, 0, 0, 0, 0, 39, 95, 98, 0, 0, 100, 0, 32,
0, 0, 0, 0, 0, 39, 96, 98, 0, 0, 100, 0, 32,
0, 14, 27, 78, 0, 57, 89, 0, 35, 0, 62, 0,
};
static const unsigned char aLen[116] = {
@@ -39,9 +39,9 @@ static int keywordCode(const char *z, int n){
7, 6, 7, 9, 3, 7, 9, 6, 9, 3, 10, 6, 6,
4, 6, 3, 7, 6, 7, 5, 13, 2, 2, 5, 5, 6,
7, 3, 7, 4, 4, 2, 7, 3, 8, 6, 4, 4, 7,
6, 6, 8, 10, 9, 6, 5, 12, 17, 12, 4, 4, 6,
6, 6, 8, 10, 9, 6, 5, 12, 12, 17, 4, 4, 6,
8, 2, 4, 6, 5, 4, 5, 4, 4, 5, 6, 2, 9,
6, 7, 4, 6, 2, 3, 6, 4, 5, 7, 5, 8, 7,
6, 7, 4, 2, 6, 3, 6, 4, 5, 7, 5, 8, 7,
5, 5, 8, 3, 4, 5, 6, 5, 6, 6, 4, 5,
};
static const unsigned short int aOffset[116] = {
@@ -74,8 +74,8 @@ static int keywordCode(const char *z, int n){
TK_PLAN, TK_DESC, TK_DETACH, TK_DISTINCT, TK_IS,
TK_DROP, TK_PRAGMA, TK_MATCH, TK_FAIL, TK_LIMIT,
TK_FROM, TK_JOIN_KW, TK_GROUP, TK_UPDATE, TK_IF,
TK_IMMEDIATE, TK_INSERT, TK_INSTEAD, TK_INTO, TK_OFFSET,
TK_OF, TK_SET, TK_ISNULL, TK_JOIN, TK_ORDER,
TK_IMMEDIATE, TK_INSERT, TK_INSTEAD, TK_INTO, TK_OF,
TK_OFFSET, TK_SET, TK_ISNULL, TK_JOIN, TK_ORDER,
TK_REPLACE, TK_JOIN_KW, TK_RESTRICT, TK_PRIMARY, TK_QUERY,
TK_JOIN_KW, TK_ROLLBACK, TK_ROW, TK_WHEN, TK_UNION,
TK_UNIQUE, TK_USING, TK_VACUUM, TK_VALUES, TK_VIEW,
@@ -83,8 +83,8 @@ static int keywordCode(const char *z, int n){
};
int h, i;
if( n<2 ) return TK_ID;
h = ((sqlite3UpperToLower[((unsigned char*)z)[0]]*4) ^
(sqlite3UpperToLower[((unsigned char*)z)[n-1]]*3) ^
h = ((charMap(z[0])*4) ^
(charMap(z[n-1])*3) ^
n) % 127;
for(i=((int)aHash[h])-1; i>=0; i=((int)aNext[i])-1){
if( aLen[i]==n && sqlite3StrNICmp(&zText[aOffset[i]],z,n)==0 ){

View File

@@ -14,7 +14,7 @@
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: legacy.c,v 1.4 2006-02-16 10:11:46 jmiltner Exp $
** $Id: legacy.c,v 1.5 2006-05-04 13:48:36 tabuleiro Exp $
*/
#include "sqliteInt.h"
@@ -54,8 +54,8 @@ int sqlite3_exec(
pStmt = 0;
rc = sqlite3_prepare(db, zSql, -1, &pStmt, &zLeftover);
assert( rc==SQLITE_OK || pStmt==0 );
if( rc!=SQLITE_OK ){
if( pStmt ) sqlite3_finalize(pStmt);
continue;
}
if( !pStmt ){

View File

@@ -14,7 +14,7 @@
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.6 2006-02-16 10:11:46 jmiltner Exp $
** $Id: main.c,v 1.7 2006-05-04 13:48:36 tabuleiro Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -109,7 +109,10 @@ int sqlite3_close(sqlite3 *db){
}
#ifdef SQLITE_SSE
sqlite3_finalize(db->pFetch);
{
extern void sqlite3SseCleanup(sqlite3*);
sqlite3SseCleanup(db);
}
#endif
/* If there are any outstanding VMs, return SQLITE_BUSY. */
@@ -250,7 +253,7 @@ static int sqliteDefaultBusyCallback(
void *ptr, /* Database connection */
int count /* Number of times table has been busy */
){
#if SQLITE_MIN_SLEEP_MS==1
#if OS_WIN || (defined(HAVE_USLEEP) && HAVE_USLEEP)
static const u8 delays[] =
{ 1, 2, 5, 10, 15, 20, 25, 25, 25, 50, 50, 100 };
static const u8 totals[] =
@@ -743,6 +746,7 @@ static int createCollation(
int(*xCompare)(void*,int,const void*,int,const void*)
){
CollSeq *pColl;
int enc2;
if( sqlite3SafetyCheck(db) ){
return SQLITE_MISUSE;
@@ -752,15 +756,13 @@ static int createCollation(
** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the
** SQLITE_UTF16NATIVE macro. SQLITE_UTF16 is not used internally.
*/
if( enc==SQLITE_UTF16 ){
enc = SQLITE_UTF16NATIVE;
enc2 = enc & ~SQLITE_UTF16_ALIGNED;
if( enc2==SQLITE_UTF16 ){
enc2 = SQLITE_UTF16NATIVE;
}
if( enc!=SQLITE_UTF8 && enc!=SQLITE_UTF16LE && enc!=SQLITE_UTF16BE ){
sqlite3Error(db, SQLITE_ERROR,
"Param 3 to sqlite3_create_collation() must be one of "
"SQLITE_UTF8, SQLITE_UTF16, SQLITE_UTF16LE or SQLITE_UTF16BE"
);
if( (enc2&~3)!=0 ){
sqlite3Error(db, SQLITE_ERROR, "unknown encoding");
return SQLITE_ERROR;
}
@@ -768,7 +770,7 @@ static int createCollation(
** sequence. If so, and there are active VMs, return busy. If there
** are no active VMs, invalidate any pre-compiled statements.
*/
pColl = sqlite3FindCollSeq(db, (u8)enc, zName, strlen(zName), 0);
pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, strlen(zName), 0);
if( pColl && pColl->xCmp ){
if( db->activeVdbeCnt ){
sqlite3Error(db, SQLITE_BUSY,
@@ -778,11 +780,11 @@ static int createCollation(
sqlite3ExpirePreparedStatements(db);
}
pColl = sqlite3FindCollSeq(db, (u8)enc, zName, strlen(zName), 1);
pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, strlen(zName), 1);
if( pColl ){
pColl->xCmp = xCompare;
pColl->pUser = pCtx;
pColl->enc = enc;
pColl->enc = enc2 | (enc & SQLITE_UTF16_ALIGNED);
}
sqlite3Error(db, SQLITE_OK, 0);
return SQLITE_OK;
@@ -847,15 +849,13 @@ static int openDatabase(
db->magic = SQLITE_MAGIC_CLOSED;
goto opendb_out;
}
#ifndef SQLITE_OMIT_PARSER
db->aDb[0].pSchema = sqlite3SchemaGet(db->aDb[0].pBt);
db->aDb[1].pSchema = sqlite3SchemaGet(0);
#endif
if( db->aDb[0].pSchema ){
ENC(db) = SQLITE_UTF8;
}
/* The default safety_level for the main database is 'full'; for the temp
** database it is 'NONE'. This matches the pager layer defaults.
*/
@@ -1230,4 +1230,3 @@ error_out:
return sqlite3ApiExit(db, rc);
}
#endif

View File

@@ -2,69 +2,69 @@
/* See the mkopcodec.awk script for details. */
#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
const char *const sqlite3OpcodeNames[] = { "?",
/* 1 */ "ReadCookie",
/* 2 */ "AutoCommit",
/* 3 */ "Found",
/* 4 */ "NullRow",
/* 5 */ "MoveLe",
/* 6 */ "Variable",
/* 7 */ "Pull",
/* 8 */ "RealAffinity",
/* 9 */ "Sort",
/* 10 */ "IfNot",
/* 11 */ "Gosub",
/* 12 */ "NotFound",
/* 13 */ "MoveLt",
/* 14 */ "Rowid",
/* 15 */ "CreateIndex",
/* 1 */ "MemLoad",
/* 2 */ "Column",
/* 3 */ "SetCookie",
/* 4 */ "IfMemPos",
/* 5 */ "Sequence",
/* 6 */ "MoveGt",
/* 7 */ "RowKey",
/* 8 */ "OpenWrite",
/* 9 */ "If",
/* 10 */ "Pop",
/* 11 */ "CollSeq",
/* 12 */ "OpenRead",
/* 13 */ "Expire",
/* 14 */ "AutoCommit",
/* 15 */ "IntegrityCk",
/* 16 */ "Not",
/* 17 */ "Push",
/* 18 */ "Explain",
/* 19 */ "Statement",
/* 20 */ "Callback",
/* 21 */ "MemLoad",
/* 22 */ "DropIndex",
/* 23 */ "Null",
/* 24 */ "Int64",
/* 25 */ "LoadAnalysis",
/* 26 */ "IdxInsert",
/* 27 */ "Next",
/* 28 */ "SetNumColumns",
/* 29 */ "MemInt",
/* 30 */ "Dup",
/* 31 */ "Rewind",
/* 32 */ "Last",
/* 17 */ "Sort",
/* 18 */ "Function",
/* 19 */ "Noop",
/* 20 */ "Return",
/* 21 */ "NewRowid",
/* 22 */ "IfMemNeg",
/* 23 */ "Variable",
/* 24 */ "String",
/* 25 */ "RealAffinity",
/* 26 */ "ParseSchema",
/* 27 */ "Close",
/* 28 */ "CreateIndex",
/* 29 */ "IsUnique",
/* 30 */ "IdxIsNull",
/* 31 */ "NotFound",
/* 32 */ "Int64",
/* 33 */ "MustBeInt",
/* 34 */ "MoveGe",
/* 35 */ "String",
/* 36 */ "ForceInt",
/* 37 */ "Close",
/* 38 */ "AggFinal",
/* 39 */ "AbsValue",
/* 40 */ "RowData",
/* 41 */ "IdxRowid",
/* 42 */ "MoveGt",
/* 43 */ "OpenPseudo",
/* 44 */ "Halt",
/* 45 */ "MemMove",
/* 46 */ "NewRowid",
/* 47 */ "IdxLT",
/* 48 */ "Distinct",
/* 49 */ "MemMax",
/* 50 */ "Function",
/* 51 */ "IntegrityCk",
/* 52 */ "FifoWrite",
/* 53 */ "NotExists",
/* 54 */ "MemStore",
/* 55 */ "IdxDelete",
/* 56 */ "Vacuum",
/* 57 */ "If",
/* 58 */ "Destroy",
/* 34 */ "Halt",
/* 35 */ "Rowid",
/* 36 */ "IdxLT",
/* 37 */ "AddImm",
/* 38 */ "Statement",
/* 39 */ "RowData",
/* 40 */ "MemMax",
/* 41 */ "Push",
/* 42 */ "NotExists",
/* 43 */ "MemIncr",
/* 44 */ "Gosub",
/* 45 */ "Integer",
/* 46 */ "MemInt",
/* 47 */ "Prev",
/* 48 */ "CreateTable",
/* 49 */ "Last",
/* 50 */ "IdxRowid",
/* 51 */ "MakeIdxRec",
/* 52 */ "ResetCount",
/* 53 */ "FifoWrite",
/* 54 */ "Callback",
/* 55 */ "ContextPush",
/* 56 */ "DropTrigger",
/* 57 */ "DropIndex",
/* 58 */ "IdxGE",
/* 59 */ "Or",
/* 60 */ "And",
/* 61 */ "AggStep",
/* 62 */ "Clear",
/* 63 */ "Insert",
/* 61 */ "IdxDelete",
/* 62 */ "Vacuum",
/* 63 */ "MoveLe",
/* 64 */ "IsNull",
/* 65 */ "NotNull",
/* 66 */ "Ne",
@@ -73,7 +73,7 @@ const char *const sqlite3OpcodeNames[] = { "?",
/* 69 */ "Le",
/* 70 */ "Lt",
/* 71 */ "Ge",
/* 72 */ "IdxGE",
/* 72 */ "IfNot",
/* 73 */ "BitAnd",
/* 74 */ "BitOr",
/* 75 */ "ShiftLeft",
@@ -85,49 +85,49 @@ const char *const sqlite3OpcodeNames[] = { "?",
/* 81 */ "Remainder",
/* 82 */ "Concat",
/* 83 */ "Negative",
/* 84 */ "IfMemZero",
/* 84 */ "DropTable",
/* 85 */ "BitNot",
/* 86 */ "String8",
/* 87 */ "MakeRecord",
/* 88 */ "SetCookie",
/* 89 */ "Prev",
/* 90 */ "ContextPush",
/* 91 */ "DropTrigger",
/* 92 */ "IdxGT",
/* 93 */ "MemNull",
/* 94 */ "IfMemNeg",
/* 95 */ "Return",
/* 96 */ "OpenWrite",
/* 97 */ "Integer",
/* 98 */ "Transaction",
/* 99 */ "OpenVirtual",
/* 100 */ "CollSeq",
/* 101 */ "Sequence",
/* 102 */ "ContextPop",
/* 103 */ "CreateTable",
/* 104 */ "AddImm",
/* 105 */ "IdxIsNull",
/* 106 */ "DropTable",
/* 107 */ "IsUnique",
/* 108 */ "Noop",
/* 109 */ "RowKey",
/* 110 */ "Expire",
/* 111 */ "FifoRead",
/* 112 */ "Delete",
/* 113 */ "IfMemPos",
/* 114 */ "MemIncr",
/* 115 */ "Blob",
/* 116 */ "MakeIdxRec",
/* 117 */ "Goto",
/* 118 */ "ParseSchema",
/* 119 */ "Pop",
/* 120 */ "TableLock",
/* 121 */ "VerifyCookie",
/* 122 */ "Column",
/* 123 */ "OpenRead",
/* 88 */ "Delete",
/* 89 */ "AggFinal",
/* 90 */ "Dup",
/* 91 */ "Goto",
/* 92 */ "TableLock",
/* 93 */ "FifoRead",
/* 94 */ "Clear",
/* 95 */ "IdxGT",
/* 96 */ "MoveLt",
/* 97 */ "VerifyCookie",
/* 98 */ "AggStep",
/* 99 */ "Pull",
/* 100 */ "SetNumColumns",
/* 101 */ "AbsValue",
/* 102 */ "Transaction",
/* 103 */ "ContextPop",
/* 104 */ "Next",
/* 105 */ "IdxInsert",
/* 106 */ "Distinct",
/* 107 */ "Insert",
/* 108 */ "Destroy",
/* 109 */ "ReadCookie",
/* 110 */ "ForceInt",
/* 111 */ "LoadAnalysis",
/* 112 */ "OpenVirtual",
/* 113 */ "Explain",
/* 114 */ "IfMemZero",
/* 115 */ "OpenPseudo",
/* 116 */ "Null",
/* 117 */ "Blob",
/* 118 */ "MemStore",
/* 119 */ "Rewind",
/* 120 */ "MoveGe",
/* 121 */ "MemMove",
/* 122 */ "MemNull",
/* 123 */ "Found",
/* 124 */ "Real",
/* 125 */ "HexBlob",
/* 126 */ "ResetCount",
/* 126 */ "NullRow",
/* 127 */ "NotUsed_127",
/* 128 */ "NotUsed_128",
/* 129 */ "NotUsed_129",

View File

@@ -1,136 +1,136 @@
/* Automatically generated. Do not edit */
/* See the mkopcodeh.awk script for details */
#define OP_ReadCookie 1
#define OP_AutoCommit 2
#define OP_Found 3
#define OP_NullRow 4
#define OP_Lt 70 /* same as TK_LT */
#define OP_MoveLe 5
#define OP_Variable 6
#define OP_Pull 7
#define OP_RealAffinity 8
#define OP_Sort 9
#define OP_IfNot 10
#define OP_Gosub 11
#define OP_Add 77 /* same as TK_PLUS */
#define OP_NotFound 12
#define OP_IsNull 64 /* same as TK_ISNULL */
#define OP_MoveLt 13
#define OP_Rowid 14
#define OP_CreateIndex 15
#define OP_Push 17
#define OP_Explain 18
#define OP_Statement 19
#define OP_Callback 20
#define OP_MemLoad 21
#define OP_DropIndex 22
#define OP_Null 23
#define OP_ToInt 140 /* same as TK_TO_INT */
#define OP_Int64 24
#define OP_LoadAnalysis 25
#define OP_IdxInsert 26
#define OP_Next 27
#define OP_SetNumColumns 28
#define OP_ToNumeric 139 /* same as TK_TO_NUMERIC*/
#define OP_Ge 71 /* same as TK_GE */
#define OP_BitNot 85 /* same as TK_BITNOT */
#define OP_MemInt 29
#define OP_Dup 30
#define OP_Rewind 31
#define OP_Multiply 79 /* same as TK_STAR */
#define OP_ToReal 141 /* same as TK_TO_REAL */
#define OP_Gt 68 /* same as TK_GT */
#define OP_Last 32
#define OP_MustBeInt 33
#define OP_Ne 66 /* same as TK_NE */
#define OP_MoveGe 34
#define OP_String 35
#define OP_ForceInt 36
#define OP_Close 37
#define OP_AggFinal 38
#define OP_AbsValue 39
#define OP_RowData 40
#define OP_IdxRowid 41
#define OP_BitOr 74 /* same as TK_BITOR */
#define OP_NotNull 65 /* same as TK_NOTNULL */
#define OP_MoveGt 42
#define OP_Not 16 /* same as TK_NOT */
#define OP_OpenPseudo 43
#define OP_Halt 44
#define OP_MemMove 45
#define OP_NewRowid 46
#define OP_Real 124 /* same as TK_FLOAT */
#define OP_IdxLT 47
#define OP_Distinct 48
#define OP_MemMax 49
#define OP_Function 50
#define OP_IntegrityCk 51
#define OP_Remainder 81 /* same as TK_REM */
#define OP_MemLoad 1
#define OP_HexBlob 125 /* same as TK_BLOB */
#define OP_ShiftLeft 75 /* same as TK_LSHIFT */
#define OP_FifoWrite 52
#define OP_BitAnd 73 /* same as TK_BITAND */
#define OP_Or 59 /* same as TK_OR */
#define OP_NotExists 53
#define OP_MemStore 54
#define OP_IdxDelete 55
#define OP_Vacuum 56
#define OP_If 57
#define OP_Destroy 58
#define OP_AggStep 61
#define OP_Clear 62
#define OP_Insert 63
#define OP_IdxGE 72
#define OP_Divide 80 /* same as TK_SLASH */
#define OP_String8 86 /* same as TK_STRING */
#define OP_IfMemZero 84
#define OP_Concat 82 /* same as TK_CONCAT */
#define OP_MakeRecord 87
#define OP_SetCookie 88
#define OP_Prev 89
#define OP_ContextPush 90
#define OP_DropTrigger 91
#define OP_IdxGT 92
#define OP_MemNull 93
#define OP_IfMemNeg 94
#define OP_And 60 /* same as TK_AND */
#define OP_Return 95
#define OP_OpenWrite 96
#define OP_Integer 97
#define OP_Transaction 98
#define OP_OpenVirtual 99
#define OP_CollSeq 100
#define OP_ToBlob 138 /* same as TK_TO_BLOB */
#define OP_Sequence 101
#define OP_ContextPop 102
#define OP_ShiftRight 76 /* same as TK_RSHIFT */
#define OP_CreateTable 103
#define OP_AddImm 104
#define OP_ToText 137 /* same as TK_TO_TEXT */
#define OP_IdxIsNull 105
#define OP_DropTable 106
#define OP_IsUnique 107
#define OP_Noop 108
#define OP_RowKey 109
#define OP_Expire 110
#define OP_FifoRead 111
#define OP_Delete 112
#define OP_IfMemPos 113
#define OP_Subtract 78 /* same as TK_MINUS */
#define OP_MemIncr 114
#define OP_Blob 115
#define OP_MakeIdxRec 116
#define OP_Goto 117
#define OP_Negative 83 /* same as TK_UMINUS */
#define OP_ParseSchema 118
#define OP_Column 2
#define OP_SetCookie 3
#define OP_IfMemPos 4
#define OP_Real 124 /* same as TK_FLOAT */
#define OP_Sequence 5
#define OP_MoveGt 6
#define OP_Ge 71 /* same as TK_GE */
#define OP_RowKey 7
#define OP_Eq 67 /* same as TK_EQ */
#define OP_Pop 119
#define OP_OpenWrite 8
#define OP_NotNull 65 /* same as TK_NOTNULL */
#define OP_If 9
#define OP_ToInt 140 /* same as TK_TO_INT */
#define OP_String8 86 /* same as TK_STRING */
#define OP_Pop 10
#define OP_CollSeq 11
#define OP_OpenRead 12
#define OP_Expire 13
#define OP_AutoCommit 14
#define OP_Gt 68 /* same as TK_GT */
#define OP_IntegrityCk 15
#define OP_Sort 17
#define OP_Function 18
#define OP_And 60 /* same as TK_AND */
#define OP_Subtract 78 /* same as TK_MINUS */
#define OP_Noop 19
#define OP_Return 20
#define OP_Remainder 81 /* same as TK_REM */
#define OP_NewRowid 21
#define OP_Multiply 79 /* same as TK_STAR */
#define OP_IfMemNeg 22
#define OP_Variable 23
#define OP_String 24
#define OP_RealAffinity 25
#define OP_ParseSchema 26
#define OP_Close 27
#define OP_CreateIndex 28
#define OP_IsUnique 29
#define OP_IdxIsNull 30
#define OP_NotFound 31
#define OP_Int64 32
#define OP_MustBeInt 33
#define OP_Halt 34
#define OP_Rowid 35
#define OP_IdxLT 36
#define OP_AddImm 37
#define OP_Statement 38
#define OP_RowData 39
#define OP_MemMax 40
#define OP_Push 41
#define OP_Or 59 /* same as TK_OR */
#define OP_NotExists 42
#define OP_MemIncr 43
#define OP_Gosub 44
#define OP_Divide 80 /* same as TK_SLASH */
#define OP_Integer 45
#define OP_ToNumeric 139 /* same as TK_TO_NUMERIC*/
#define OP_MemInt 46
#define OP_Prev 47
#define OP_Concat 82 /* same as TK_CONCAT */
#define OP_BitAnd 73 /* same as TK_BITAND */
#define OP_CreateTable 48
#define OP_Last 49
#define OP_IsNull 64 /* same as TK_ISNULL */
#define OP_IdxRowid 50
#define OP_MakeIdxRec 51
#define OP_ShiftRight 76 /* same as TK_RSHIFT */
#define OP_ResetCount 52
#define OP_FifoWrite 53
#define OP_Callback 54
#define OP_ContextPush 55
#define OP_DropTrigger 56
#define OP_DropIndex 57
#define OP_IdxGE 58
#define OP_IdxDelete 61
#define OP_Vacuum 62
#define OP_MoveLe 63
#define OP_IfNot 72
#define OP_DropTable 84
#define OP_MakeRecord 87
#define OP_ToBlob 138 /* same as TK_TO_BLOB */
#define OP_Delete 88
#define OP_AggFinal 89
#define OP_ShiftLeft 75 /* same as TK_LSHIFT */
#define OP_Dup 90
#define OP_Goto 91
#define OP_TableLock 92
#define OP_FifoRead 93
#define OP_Clear 94
#define OP_IdxGT 95
#define OP_MoveLt 96
#define OP_Le 69 /* same as TK_LE */
#define OP_TableLock 120
#define OP_VerifyCookie 121
#define OP_Column 122
#define OP_OpenRead 123
#define OP_ResetCount 126
#define OP_VerifyCookie 97
#define OP_AggStep 98
#define OP_Pull 99
#define OP_ToText 137 /* same as TK_TO_TEXT */
#define OP_Not 16 /* same as TK_NOT */
#define OP_ToReal 141 /* same as TK_TO_REAL */
#define OP_SetNumColumns 100
#define OP_AbsValue 101
#define OP_Transaction 102
#define OP_Negative 83 /* same as TK_UMINUS */
#define OP_Ne 66 /* same as TK_NE */
#define OP_ContextPop 103
#define OP_BitOr 74 /* same as TK_BITOR */
#define OP_Next 104
#define OP_IdxInsert 105
#define OP_Distinct 106
#define OP_Lt 70 /* same as TK_LT */
#define OP_Insert 107
#define OP_Destroy 108
#define OP_ReadCookie 109
#define OP_ForceInt 110
#define OP_LoadAnalysis 111
#define OP_OpenVirtual 112
#define OP_Explain 113
#define OP_IfMemZero 114
#define OP_OpenPseudo 115
#define OP_Null 116
#define OP_Blob 117
#define OP_Add 77 /* same as TK_PLUS */
#define OP_MemStore 118
#define OP_Rewind 119
#define OP_MoveGe 120
#define OP_BitNot 85 /* same as TK_BITNOT */
#define OP_MemMove 121
#define OP_MemNull 122
#define OP_Found 123
#define OP_NullRow 126
/* The following opcode values are never used */
#define OP_NotUsed_127 127
@@ -147,13 +147,13 @@
/* Opcodes that are guaranteed to never push a value onto the stack
** contain a 1 their corresponding position of the following mask
** set. See the opcodeNoPush() function in vdbeaux.c */
#define NOPUSH_MASK_0 0x3fbc
#define NOPUSH_MASK_1 0x9e5b
#define NOPUSH_MASK_2 0x9c77
#define NOPUSH_MASK_3 0xfbf3
#define NOPUSH_MASK_0 0x7f58
#define NOPUSH_MASK_1 0xee5b
#define NOPUSH_MASK_2 0x9f76
#define NOPUSH_MASK_3 0xfff2
#define NOPUSH_MASK_4 0xffff
#define NOPUSH_MASK_5 0xdf3b
#define NOPUSH_MASK_6 0x5f5d
#define NOPUSH_MASK_7 0x4be7
#define NOPUSH_MASK_5 0xdb3b
#define NOPUSH_MASK_6 0xcfdf
#define NOPUSH_MASK_7 0x49cd
#define NOPUSH_MASK_8 0x3e00
#define NOPUSH_MASK_9 0x0000

View File

@@ -80,6 +80,7 @@ struct unixFile {
unsigned char isOpen; /* True if needs to be closed */
unsigned char fullSync; /* Use F_FULLSYNC if available */
int dirfd; /* File descriptor for the directory */
i64 offset; /* Seek offset */
#ifdef SQLITE_UNIX_THREADS
pthread_t tid; /* The thread that "owns" this OsFile */
#endif
@@ -340,9 +341,10 @@ struct openCnt {
** openKey structures) into lockInfo and openCnt structures. Access to
** these hash tables must be protected by a mutex.
*/
static Hash lockHash = { SQLITE_HASH_BINARY, 0, 0, 0, 0, 0 };
static Hash openHash = { SQLITE_HASH_BINARY, 0, 0, 0, 0, 0 };
static Hash lockHash = {SQLITE_HASH_BINARY, 0, 0, 0,
sqlite3ThreadSafeMalloc, sqlite3ThreadSafeFree, 0, 0};
static Hash openHash = {SQLITE_HASH_BINARY, 0, 0, 0,
sqlite3ThreadSafeMalloc, sqlite3ThreadSafeFree, 0, 0};
#ifdef SQLITE_UNIX_THREADS
/*
@@ -491,7 +493,7 @@ static void releaseLockInfo(struct lockInfo *pLock){
pLock->nRef--;
if( pLock->nRef==0 ){
sqlite3HashInsert(&lockHash, &pLock->key, sizeof(pLock->key), 0);
sqliteFree(pLock);
sqlite3ThreadSafeFree(pLock);
}
}
@@ -504,7 +506,7 @@ static void releaseOpenCnt(struct openCnt *pOpen){
if( pOpen->nRef==0 ){
sqlite3HashInsert(&openHash, &pOpen->key, sizeof(pOpen->key), 0);
free(pOpen->aPending);
sqliteFree(pOpen);
sqlite3ThreadSafeFree(pOpen);
}
}
@@ -545,7 +547,7 @@ static int findLockInfo(
pLock = (struct lockInfo*)sqlite3HashFind(&lockHash, &key1, sizeof(key1));
if( pLock==0 ){
struct lockInfo *pOld;
pLock = sqliteMallocRaw( sizeof(*pLock) );
pLock = sqlite3ThreadSafeMalloc( sizeof(*pLock) );
if( pLock==0 ){
rc = 1;
goto exit_findlockinfo;
@@ -557,7 +559,7 @@ static int findLockInfo(
pOld = sqlite3HashInsert(&lockHash, &pLock->key, sizeof(key1), pLock);
if( pOld!=0 ){
assert( pOld==pLock );
sqliteFree(pLock);
sqlite3ThreadSafeFree(pLock);
rc = 1;
goto exit_findlockinfo;
}
@@ -569,7 +571,7 @@ static int findLockInfo(
pOpen = (struct openCnt*)sqlite3HashFind(&openHash, &key2, sizeof(key2));
if( pOpen==0 ){
struct openCnt *pOld;
pOpen = sqliteMallocRaw( sizeof(*pOpen) );
pOpen = sqlite3ThreadSafeMalloc( sizeof(*pOpen) );
if( pOpen==0 ){
releaseLockInfo(pLock);
rc = 1;
@@ -583,7 +585,7 @@ static int findLockInfo(
pOld = sqlite3HashInsert(&openHash, &pOpen->key, sizeof(key2), pOpen);
if( pOld!=0 ){
assert( pOld==pOpen );
sqliteFree(pOpen);
sqlite3ThreadSafeFree(pOpen);
releaseLockInfo(pLock);
rc = 1;
goto exit_findlockinfo;
@@ -903,6 +905,24 @@ int sqlite3UnixIsDirWritable(char *zBuf){
return 1;
}
/*
** Seek to the offset in id->offset then read cnt bytes into pBuf.
** Return the number of bytes actually read. Update the offset.
*/
static int seekAndRead(unixFile *id, void *pBuf, int cnt){
int got;
#ifdef USE_PREAD
got = pread(id->h, pBuf, cnt, id->offset);
#else
lseek(id->h, id->offset, SEEK_SET);
got = read(id->h, pBuf, cnt);
#endif
if( got>0 ){
id->offset += got;
}
return got;
}
/*
** Read data from a file into a buffer. Return SQLITE_OK if all
** bytes were read successfully and SQLITE_IOERR if anything goes
@@ -913,7 +933,7 @@ static int unixRead(OsFile *id, void *pBuf, int amt){
assert( id );
SimulateIOError(SQLITE_IOERR);
TIMER_START;
got = read(((unixFile*)id)->h, pBuf, amt);
got = seekAndRead((unixFile*)id, pBuf, amt);
TIMER_END;
TRACE5("READ %-3d %5d %7d %d\n", ((unixFile*)id)->h, got,
last_page, TIMER_ELAPSED);
@@ -926,6 +946,25 @@ static int unixRead(OsFile *id, void *pBuf, int amt){
}
}
/*
** Seek to the offset in id->offset then read cnt bytes into pBuf.
** Return the number of bytes actually read. Update the offset.
*/
static int seekAndWrite(unixFile *id, const void *pBuf, int cnt){
int got;
#ifdef USE_PREAD
got = pwrite(id->h, pBuf, cnt, id->offset);
#else
lseek(id->h, id->offset, SEEK_SET);
got = write(id->h, pBuf, cnt);
#endif
if( got>0 ){
id->offset += got;
}
return got;
}
/*
** Write data from a buffer into a file. Return SQLITE_OK on success
** or some other error code on failure.
@@ -937,7 +976,7 @@ static int unixWrite(OsFile *id, const void *pBuf, int amt){
SimulateIOError(SQLITE_IOERR);
SimulateDiskfullError;
TIMER_START;
while( amt>0 && (wrote = write(((unixFile*)id)->h, pBuf, amt))>0 ){
while( amt>0 && (wrote = seekAndWrite((unixFile*)id, pBuf, amt))>0 ){
amt -= wrote;
pBuf = &((char*)pBuf)[wrote];
}
@@ -960,7 +999,7 @@ static int unixSeek(OsFile *id, i64 offset){
#ifdef SQLITE_TEST
if( offset ) SimulateDiskfullError
#endif
lseek(((unixFile*)id)->h, offset, SEEK_SET);
((unixFile*)id)->offset = offset;
return SQLITE_OK;
}
@@ -1526,7 +1565,7 @@ static int unixClose(OsFile **pId){
id->isOpen = 0;
TRACE2("CLOSE %-3d\n", id->h);
OpenCounter(-1);
sqliteFree(id);
sqlite3ThreadSafeFree(id);
*pId = 0;
return SQLITE_OK;
}
@@ -1551,6 +1590,33 @@ char *sqlite3UnixFullPathname(const char *zRelative){
(char*)0);
sqliteFree(zBuf);
}
#if 0
/*
** Remove "/./" path elements and convert "/A/./" path elements
** to just "/".
*/
if( zFull ){
int i, j;
for(i=j=0; zFull[i]; i++){
if( zFull[i]=='/' ){
if( zFull[i+1]=='/' ) continue;
if( zFull[i+1]=='.' && zFull[i+2]=='/' ){
i += 1;
continue;
}
if( zFull[i+1]=='.' && zFull[i+2]=='.' && zFull[i+3]=='/' ){
while( j>0 && zFull[j-1]!='/' ){ j--; }
i += 3;
continue;
}
}
zFull[j++] = zFull[i];
}
zFull[j] = 0;
}
#endif
return zFull;
}
@@ -1607,8 +1673,9 @@ static int allocateUnixFile(unixFile *pInit, OsFile **pId){
pInit->dirfd = -1;
pInit->fullSync = 0;
pInit->locktype = 0;
pInit->offset = 0;
SET_THREADID(pInit);
pNew = sqliteMalloc( sizeof(unixFile) );
pNew = sqlite3ThreadSafeMalloc( sizeof(unixFile) );
if( pNew==0 ){
close(pInit->h);
sqlite3OsEnterMutex();

View File

@@ -128,19 +128,19 @@ int sqlite3_os_type = 0;
** is obtained from sqliteMalloc.
*/
static WCHAR *utf8ToUnicode(const char *zFilename){
int nByte;
int nChar;
WCHAR *zWideFilename;
if( !isNT() ){
return 0;
}
nByte = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0)*sizeof(WCHAR);
zWideFilename = sqliteMalloc( nByte*sizeof(zWideFilename[0]) );
nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
zWideFilename = sqliteMalloc( nChar*sizeof(zWideFilename[0]) );
if( zWideFilename==0 ){
return 0;
}
nByte = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, nByte);
if( nByte==0 ){
nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, nChar);
if( nChar==0 ){
sqliteFree(zWideFilename);
zWideFilename = 0;
}

View File

@@ -18,7 +18,7 @@
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.6 2006-02-16 10:11:46 jmiltner Exp $
** @(#) $Id: pager.c,v 1.7 2006-05-04 13:48:36 tabuleiro Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
@@ -52,8 +52,8 @@
** associated file-descriptor is returned. FILEHANDLEID() takes an OsFile
** struct as it's argument.
*/
#define PAGERID(p) FILEHANDLEID(&(p)->fd)
#define FILEHANDLEID(fd) (sqlite3OsFileHandle(&fd))
#define PAGERID(p) ((int)(p->fd))
#define FILEHANDLEID(fd) ((int)fd)
/*
** The page cache as a whole is always in one of the following
@@ -190,9 +190,11 @@ struct PgHistory {
** A macro used for invoking the codec if there is one
*/
#ifdef SQLITE_HAS_CODEC
# define CODEC(P,D,N,X) if( P->xCodec ){ P->xCodec(P->pCodecArg,D,N,X); }
# define CODEC1(P,D,N,X) if( P->xCodec!=0 ){ P->xCodec(P->pCodecArg,D,N,X); }
# define CODEC2(P,D,N,X) ((char*)(P->xCodec!=0?P->xCodec(P->pCodecArg,D,N,X):D))
#else
# define CODEC(P,D,N,X)
# define CODEC1(P,D,N,X) /* NO-OP */
# define CODEC2(P,D,N,X) ((char*)D)
#endif
/*
@@ -290,7 +292,7 @@ struct Pager {
#endif
void (*xDestructor)(void*,int); /* Call this routine when freeing pages */
void (*xReiniter)(void*,int); /* Call this routine when reloading pages */
void (*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */
void *(*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */
void *pCodecArg; /* First argument to xCodec() */
PgHdr *aHash[N_PG_HASH]; /* Hash table to map page number to PgHdr */
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
@@ -435,16 +437,6 @@ static int write32bits(OsFile *fd, u32 val){
return sqlite3OsWrite(fd, ac, 4);
}
/*
** Write the 32-bit integer 'val' into the page identified by page header
** 'p' at offset 'offset'.
*/
static void store32bits(u32 val, PgHdr *p, int offset){
char *ac;
ac = &((char*)PGHDR_TO_DATA(p))[offset];
put32bits(ac, val);
}
/*
** Read a 32-bit integer at offset 'offset' from the page identified by
** page header 'p'.
@@ -935,7 +927,7 @@ static int pager_unwritelock(Pager *pPager){
** only the middle sector is corrupt, we will still have a reasonable
** chance of failing the checksum and thus detecting the problem.
*/
static u32 pager_cksum(Pager *pPager, Pgno pgno, const u8 *aData){
static u32 pager_cksum(Pager *pPager, const u8 *aData){
u32 cksum = pPager->cksumInit;
int i = pPager->pageSize-200;
while( i>0 ){
@@ -987,7 +979,7 @@ static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){
rc = read32bits(jfd, &cksum);
if( rc ) return rc;
pPager->journalOff += 4;
if( pager_cksum(pPager, pgno, aData)!=cksum ){
if( pager_cksum(pPager, aData)!=cksum ){
return SQLITE_DONE;
}
}
@@ -1041,7 +1033,7 @@ static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){
#ifdef SQLITE_CHECK_PAGES
pPg->pageHash = pager_pagehash(pPg);
#endif
CODEC(pPager, pData, pPg->pgno, 3);
CODEC1(pPager, pData, pPg->pgno, 3);
}
return rc;
}
@@ -1154,7 +1146,7 @@ static int pager_reload_cache(Pager *pPager){
}
TRACE3("REFETCH %d page %d\n", PAGERID(pPager), pPg->pgno);
if( rc ) break;
CODEC(pPager, zBuf, pPg->pgno, 2);
CODEC1(pPager, zBuf, pPg->pgno, 2);
}else{
memset(zBuf, 0, pPager->pageSize);
}
@@ -1310,9 +1302,6 @@ static int pager_playback(Pager *pPager){
pPager->dbSize = mxPg;
}
/* rc = sqlite3OsSeek(pPager->jfd, JOURNAL_HDR_SZ(pPager)); */
if( rc!=SQLITE_OK ) goto end_playback;
/* Copy original pages out of the journal and back into the database file.
*/
for(i=0; i<nRec; i++){
@@ -1328,13 +1317,8 @@ static int pager_playback(Pager *pPager){
}
}
}
/* Pages that have been written to the journal but never synced
** where not restored by the loop above. We have to restore those
** pages by reading them back from the original database.
*/
assert( rc==SQLITE_OK );
pager_reload_cache(pPager);
/*NOTREACHED*/
assert( 0 );
end_playback:
if( rc==SQLITE_OK ){
@@ -1825,6 +1809,7 @@ int sqlite3pager_pagecount(Pager *pPager){
** Forward declaration
*/
static int syncJournal(Pager*);
static void clearHistory(PgHistory*);
/*
@@ -1849,7 +1834,9 @@ static void unlinkHashChain(Pager *pPager, PgHdr *pPg){
assert( pPager->aHash[h]==pPg );
pPager->aHash[h] = pPg->pNextHash;
}
if( MEMDB ){
clearHistory(PGHDR_TO_HIST(pPg, pPager));
}
pPg->pgno = 0;
pPg->pNextHash = pPg->pPrevHash = 0;
}
@@ -2070,7 +2057,7 @@ int sqlite3pager_close(Pager *pPager){
pTsd->pPager = pPager->pNext;
}else{
Pager *pTmp;
for(pTmp = pTsd->pPager; pTmp->pNext!=pPager; pTmp=pTmp->pNext);
for(pTmp = pTsd->pPager; pTmp->pNext!=pPager; pTmp=pTmp->pNext){}
pTmp->pNext = pPager->pNext;
}
#endif
@@ -2279,11 +2266,9 @@ static int pager_write_pagelist(PgHdr *pList){
** any such pages to the file.
*/
if( pList->pgno<=pPager->dbSize ){
CODEC(pPager, PGHDR_TO_DATA(pList), pList->pgno, 6);
char *pData = CODEC2(pPager, PGHDR_TO_DATA(pList), pList->pgno, 6);
TRACE3("STORE %d page %d\n", PAGERID(pPager), pList->pgno);
rc = sqlite3OsWrite(pPager->fd, PGHDR_TO_DATA(pList),
pPager->pageSize);
CODEC(pPager, PGHDR_TO_DATA(pList), pList->pgno, 0);
rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize);
TEST_INCR(pPager->nWrite);
}
#ifndef NDEBUG
@@ -2477,7 +2462,7 @@ int sqlite3pager_release_memory(int nReq){
if( pPg==p->pAll ){
p->pAll = pPg->pNextAll;
}else{
for( pTmp=p->pAll; pTmp->pNextAll!=pPg; pTmp=pTmp->pNextAll );
for( pTmp=p->pAll; pTmp->pNextAll!=pPg; pTmp=pTmp->pNextAll ){}
pTmp->pNextAll = pPg->pNextAll;
}
nReleased += sqliteAllocSize(pPg);
@@ -2688,7 +2673,7 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){
pPager->pageSize);
}
TRACE3("FETCH %d page %d\n", PAGERID(pPager), pPg->pgno);
CODEC(pPager, PGHDR_TO_DATA(pPg), pPg->pgno, 3);
CODEC1(pPager, PGHDR_TO_DATA(pPg), pPg->pgno, 3);
if( rc!=SQLITE_OK ){
i64 fileSize;
int rc2 = sqlite3OsFileSize(pPager->fd, &fileSize);
@@ -3007,7 +2992,6 @@ int sqlite3pager_write(void *pData){
if( !pPg->inJournal && (pPager->useJournal || MEMDB) ){
if( (int)pPg->pgno <= pPager->origDbSize ){
int szPg;
u32 saved;
if( MEMDB ){
PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager);
TRACE3("JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno);
@@ -3017,24 +3001,25 @@ int sqlite3pager_write(void *pData){
memcpy(pHist->pOrig, PGHDR_TO_DATA(pPg), pPager->pageSize);
}
}else{
u32 cksum;
u32 cksum, saved;
char *pData2, *pEnd;
/* We should never write to the journal file the page that
** contains the database locks. The following assert verifies
** that we do not. */
assert( pPg->pgno!=PAGER_MJ_PGNO(pPager) );
CODEC(pPager, pData, pPg->pgno, 7);
cksum = pager_cksum(pPager, pPg->pgno, pData);
saved = *(u32*)PGHDR_TO_EXTRA(pPg, pPager);
store32bits(cksum, pPg, pPager->pageSize);
pData2 = CODEC2(pPager, pData, pPg->pgno, 7);
cksum = pager_cksum(pPager, (u8*)pData2);
pEnd = pData2 + pPager->pageSize;
pData2 -= 4;
saved = *(u32*)pEnd;
put32bits(pEnd, cksum);
szPg = pPager->pageSize+8;
store32bits(pPg->pgno, pPg, -4);
rc = sqlite3OsWrite(pPager->jfd, &((char*)pData)[-4], szPg);
put32bits(pData2, pPg->pgno);
rc = sqlite3OsWrite(pPager->jfd, pData2, szPg);
pPager->journalOff += szPg;
TRACE4("JOURNAL %d page %d needSync=%d\n",
PAGERID(pPager), pPg->pgno, pPg->needSync);
CODEC(pPager, pData, pPg->pgno, 0);
*(u32*)PGHDR_TO_EXTRA(pPg, pPager) = saved;
*(u32*)pEnd = saved;
/* An error has occured writing to the journal file. The
** transaction will be rolled back by the layer above.
@@ -3079,12 +3064,10 @@ int sqlite3pager_write(void *pData){
}
TRACE3("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno);
}else{
store32bits(pPg->pgno, pPg, -4);
CODEC(pPager, pData, pPg->pgno, 7);
rc = sqlite3OsWrite(pPager->stfd,((char*)pData)-4,
pPager->pageSize+4);
char *pData2 = CODEC2(pPager, pData, pPg->pgno, 7)-4;
put32bits(pData2, pPg->pgno);
rc = sqlite3OsWrite(pPager->stfd, pData2, pPager->pageSize+4);
TRACE3("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno);
CODEC(pPager, pData, pPg->pgno, 0);
if( rc!=SQLITE_OK ){
return rc;
}
@@ -3170,8 +3153,9 @@ void sqlite3pager_dont_write(Pager *pPager, Pgno pgno){
if( MEMDB ) return;
pPg = pager_lookup(pPager, pgno);
assert( pPg!=0 ); /* We never call _dont_write unless the page is in mem */
pPg->alwaysRollback = 1;
if( pPg && pPg->dirty && !pPager->stmtInUse ){
if( pPg->dirty && !pPager->stmtInUse ){
if( pPager->dbSize==(int)pPg->pgno && pPager->origDbSize<pPager->dbSize ){
/* If this pages is the last page in the file and the file has grown
** during the current transaction, then do NOT mark the page as clean.
@@ -3261,6 +3245,7 @@ int sqlite3pager_commit(Pager *pPager){
pPg->dirty = 0;
pPg->inJournal = 0;
pPg->inStmt = 0;
pPg->needSync = 0;
pPg->pPrevStmt = pPg->pNextStmt = 0;
pPg = pPg->pDirty;
}
@@ -3556,7 +3541,7 @@ int sqlite3pager_nosync(Pager *pPager){
*/
void sqlite3pager_set_codec(
Pager *pPager,
void (*xCodec)(void*,void*,Pgno,int),
void *(*xCodec)(void*,void*,Pgno,int),
void *pCodecArg
){
pPager->xCodec = xCodec;
@@ -3585,7 +3570,7 @@ static int pager_incr_changecounter(Pager *pPager){
/* Increment the value just read and write it back to byte 24. */
change_counter++;
store32bits(change_counter, pPgHdr, 24);
put32bits(((char*)PGHDR_TO_DATA(pPgHdr))+24, change_counter);
/* Release the page reference. */
sqlite3pager_unref(pPage);
@@ -3675,6 +3660,8 @@ int sqlite3pager_sync(Pager *pPager, const char *zMaster, Pgno nTrunc){
}
pPager->state = PAGER_SYNCED;
}else if( MEMDB && nTrunc!=0 ){
rc = sqlite3pager_truncate(pPager, nTrunc);
}
sync_exit:

View File

@@ -13,7 +13,7 @@
** subsystem. The page cache subsystem reads and writes a file a page
** at a time and provides a journal for rollback.
**
** @(#) $Id: pager.h,v 1.6 2006-02-16 10:11:46 jmiltner Exp $
** @(#) $Id: pager.h,v 1.7 2006-05-04 13:48:36 tabuleiro Exp $
*/
#ifndef _PAGER_H_
@@ -105,7 +105,7 @@ const char *sqlite3pager_dirname(Pager*);
const char *sqlite3pager_journalname(Pager*);
int sqlite3pager_nosync(Pager*);
int sqlite3pager_rename(Pager*, const char *zNewName);
void sqlite3pager_set_codec(Pager*,void(*)(void*,void*,Pgno,int),void*);
void sqlite3pager_set_codec(Pager*,void*(*)(void*,void*,Pgno,int),void*);
int sqlite3pager_movepage(Pager*,void*,Pgno);
int sqlite3pager_reset(Pager*);
int sqlite3pager_release_memory(int);

File diff suppressed because it is too large Load Diff

View File

@@ -11,7 +11,7 @@
*************************************************************************
** This file contains code used to implement the PRAGMA command.
**
** $Id: pragma.c,v 1.6 2006-02-16 10:11:46 jmiltner Exp $
** $Id: pragma.c,v 1.7 2006-05-04 13:48:36 tabuleiro Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -227,6 +227,13 @@ void sqlite3Pragma(
if( iDb<0 ) return;
pDb = &db->aDb[iDb];
/* If the temp database has been explicitly named as part of the
** pragma, make sure it is open.
*/
if( iDb==1 && sqlite3OpenTempDatabase(pParse) ){
return;
}
zLeft = sqlite3NameFromToken(pId);
if( !zLeft ) return;
if( minusFlag ){
@@ -478,7 +485,7 @@ void sqlite3Pragma(
sqlite3VdbeAddOp(v, OP_Integer, i, 0);
sqlite3VdbeOp3(v, OP_String8, 0, 0, pCol->zName, 0);
sqlite3VdbeOp3(v, OP_String8, 0, 0,
pCol->zType ? pCol->zType : "numeric", 0);
pCol->zType ? pCol->zType : "", 0);
sqlite3VdbeAddOp(v, OP_Integer, pCol->notNull, 0);
sqlite3ExprCode(pParse, pCol->pDflt);
sqlite3VdbeAddOp(v, OP_Integer, pCol->isPrimKey, 0);
@@ -948,10 +955,12 @@ void sqlite3Pragma(
** Reset the safety level, in case the fullfsync flag or synchronous
** setting changed.
*/
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
if( db->autoCommit ){
sqlite3BtreeSetSafetyLevel(pDb->pBt, pDb->safety_level,
(db->flags&SQLITE_FullFSync)!=0);
}
#endif
}
pragma_out:
sqliteFree(zLeft);

View File

@@ -13,7 +13,7 @@
** interface, and routines that contribute to loading the database schema
** from disk.
**
** $Id: prepare.c,v 1.1 2006-02-16 10:11:46 jmiltner Exp $
** $Id: prepare.c,v 1.2 2006-05-04 13:48:36 tabuleiro Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -74,6 +74,7 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **azColName){
db->init.newTnum = atoi(argv[1]);
rc = sqlite3_exec(db, argv[2], 0, 0, &zErr);
db->init.iDb = 0;
assert( rc!=SQLITE_OK || zErr==0 );
if( SQLITE_OK!=rc ){
if( rc==SQLITE_NOMEM ){
sqlite3FailedMalloc();
@@ -409,57 +410,6 @@ static int schemaIsValid(sqlite3 *db){
return allOk;
}
/*
** Free all resources held by the schema structure. The void* argument points
** at a Schema struct. This function does not call sqliteFree() on the
** pointer itself, it just cleans up subsiduary resources (i.e. the contents
** of the schema hash tables).
*/
void sqlite3SchemaFree(void *p){
Hash temp1;
Hash temp2;
HashElem *pElem;
Schema *pSchema = (Schema *)p;
temp1 = pSchema->tblHash;
temp2 = pSchema->trigHash;
sqlite3HashInit(&pSchema->trigHash, SQLITE_HASH_STRING, 0);
sqlite3HashClear(&pSchema->aFKey);
sqlite3HashClear(&pSchema->idxHash);
for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){
sqlite3DeleteTrigger((Trigger*)sqliteHashData(pElem));
}
sqlite3HashClear(&temp2);
sqlite3HashInit(&pSchema->tblHash, SQLITE_HASH_STRING, 0);
for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){
Table *pTab = sqliteHashData(pElem);
sqlite3DeleteTable(0, pTab);
}
sqlite3HashClear(&temp1);
pSchema->pSeqTab = 0;
pSchema->flags &= ~DB_SchemaLoaded;
}
/*
** Find and return the schema associated with a BTree. Create
** a new one if necessary.
*/
Schema *sqlite3SchemaGet(Btree *pBt){
Schema * p;
if( pBt ){
p = (Schema *)sqlite3BtreeSchema(pBt,sizeof(Schema),sqlite3SchemaFree);
}else{
p = (Schema *)sqliteMalloc(sizeof(Schema));
}
if( p && 0==p->file_format ){
sqlite3HashInit(&p->tblHash, SQLITE_HASH_STRING, 0);
sqlite3HashInit(&p->idxHash, SQLITE_HASH_STRING, 0);
sqlite3HashInit(&p->trigHash, SQLITE_HASH_STRING, 0);
sqlite3HashInit(&p->aFKey, SQLITE_HASH_STRING, 1);
}
return p;
}
/*
** Convert a schema pointer into the iDb index that indicates
** which database file in db->aDb[] the schema refers to.

View File

@@ -65,15 +65,14 @@
#define etDYNSTRING 7 /* Dynamically allocated strings. %z */
#define etPERCENT 8 /* Percent symbol. %% */
#define etCHARX 9 /* Characters. %c */
#define etERROR 10 /* Used to indicate no such conversion type */
/* The rest are extensions, not normally found in printf() */
#define etCHARLIT 11 /* Literal characters. %' */
#define etSQLESCAPE 12 /* Strings with '\'' doubled. %q */
#define etSQLESCAPE2 13 /* Strings with '\'' doubled and enclosed in '',
#define etCHARLIT 10 /* Literal characters. %' */
#define etSQLESCAPE 11 /* Strings with '\'' doubled. %q */
#define etSQLESCAPE2 12 /* Strings with '\'' doubled and enclosed in '',
NULL pointers replaced by SQL NULL. %Q */
#define etTOKEN 14 /* a pointer to a Token structure */
#define etSRCLIST 15 /* a pointer to a SrcList */
#define etPOINTER 16 /* The %p conversion */
#define etTOKEN 13 /* a pointer to a Token structure */
#define etSRCLIST 14 /* a pointer to a SrcList */
#define etPOINTER 15 /* The %p conversion */
/*
@@ -225,7 +224,7 @@ static int vxprintf(
etByte flag_long; /* True if "l" flag is present */
etByte flag_longlong; /* True if the "ll" flag is present */
etByte done; /* Loop termination flag */
UINT64_TYPE longvalue; /* Value for integer types */
sqlite_uint64 longvalue; /* Value for integer types */
LONGDOUBLE_TYPE realvalue; /* Value for real types */
const et_info *infop; /* Pointer to the appropriate info structure */
char buf[etBUFSIZE]; /* Conversion buffer */
@@ -329,7 +328,6 @@ static int vxprintf(
}
/* Fetch the info entry for the field */
infop = 0;
xtype = etERROR;
for(idx=0; idx<etNINFO; idx++){
if( c==fmtinfo[idx].fmttype ){
infop = &fmtinfo[idx];
@@ -340,6 +338,10 @@ static int vxprintf(
}
}
zExtra = 0;
if( infop==0 ){
return -1;
}
/* Limit the precision to prevent overflowing buf[] during conversion */
if( precision>etBUFSIZE-40 && (infop->flags & FLAG_STRING)==0 ){
@@ -444,7 +446,7 @@ static int vxprintf(
for(idx=precision, rounder=0.4999; idx>0; idx--, rounder*=0.1);
#else
/* It makes more sense to use 0.5 */
for(idx=precision, rounder=0.5; idx>0; idx--, rounder*=0.1);
for(idx=precision, rounder=0.5; idx>0; idx--, rounder*=0.1){}
#endif
if( xtype==etFLOAT ) realvalue += rounder;
/* Normalize realvalue to within 10.0 > realvalue >= 1.0 */
@@ -621,7 +623,8 @@ static int vxprintf(
if( needQuote ) bufpt[j++] = '\'';
bufpt[j] = 0;
length = j;
if( precision>=0 && precision<length ) length = precision;
/* The precision is ignored on %q and %Q */
/* if( precision>=0 && precision<length ) length = precision; */
break;
}
case etTOKEN: {
@@ -645,15 +648,6 @@ static int vxprintf(
length = width = 0;
break;
}
case etERROR:
buf[0] = '%';
buf[1] = c;
errorflag = 0;
idx = 1+(c!=0);
(*func)(arg,"%",idx);
count += idx;
if( c==0 ) fmt--;
break;
}/* End switch over the format type */
/*
** The text of the conversion is pointed to by "bufpt" and is

View File

@@ -15,7 +15,7 @@
** Random numbers are used by some of the database backends in order
** to generate random integer keys for tables or random filenames.
**
** $Id: random.c,v 1.6 2006-02-16 10:11:46 jmiltner Exp $
** $Id: random.c,v 1.7 2006-05-04 13:48:36 tabuleiro Exp $
*/
#include "sqliteInt.h"
#include "os.h"

View File

@@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.6 2006-02-16 10:11:46 jmiltner Exp $
** $Id: select.c,v 1.7 2006-05-04 13:48:36 tabuleiro Exp $
*/
#include "sqliteInt.h"
@@ -411,22 +411,18 @@ static void codeOffset(
** seen combinations of the N values. A new entry is made in iTab
** if the current N values are new.
**
** A jump to addrRepeat is made and the K values are popped from the
** A jump to addrRepeat is made and the N+1 values are popped from the
** stack if the top N elements are not distinct.
*/
static void codeDistinct(
Vdbe *v, /* Generate code into this VM */
int iTab, /* A sorting index used to test for distinctness */
int addrRepeat, /* Jump to here if not distinct */
int N, /* The top N elements of the stack must be distinct */
int K /* Pop K elements from the stack if indistinct */
int N /* The top N elements of the stack must be distinct */
){
#if NULL_ALWAYS_DISTINCT
sqlite3VdbeAddOp(v, OP_IsNull, -N, sqlite3VdbeCurrentAddr(v)+6);
#endif
sqlite3VdbeAddOp(v, OP_MakeRecord, -N, 0);
sqlite3VdbeAddOp(v, OP_Distinct, iTab, sqlite3VdbeCurrentAddr(v)+3);
sqlite3VdbeAddOp(v, OP_Pop, K, 0);
sqlite3VdbeAddOp(v, OP_Pop, N+1, 0);
sqlite3VdbeAddOp(v, OP_Goto, 0, addrRepeat);
VdbeComment((v, "# skip indistinct records"));
sqlite3VdbeAddOp(v, OP_IdxInsert, iTab, 0);
@@ -487,8 +483,9 @@ static int selectInnerLoop(
** part of the result.
*/
if( hasDistinct ){
int n = pEList->nExpr;
codeDistinct(v, distinct, iContinue, n, n+1);
assert( pEList!=0 );
assert( pEList->nExpr==nColumn );
codeDistinct(v, distinct, iContinue, nColumn);
if( pOrderBy==0 ){
codeOffset(v, p, iContinue, nColumn);
}
@@ -500,7 +497,7 @@ static int selectInnerLoop(
*/
#ifndef SQLITE_OMIT_COMPOUND_SELECT
case SRT_Union: {
sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, NULL_ALWAYS_DISTINCT);
sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
if( aff ){
sqlite3VdbeChangeP3(v, -1, aff, P3_STATIC);
}
@@ -514,7 +511,7 @@ static int selectInnerLoop(
*/
case SRT_Except: {
int addr;
addr = sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, NULL_ALWAYS_DISTINCT);
addr = sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
sqlite3VdbeChangeP3(v, -1, aff, P3_STATIC);
sqlite3VdbeAddOp(v, OP_NotFound, iParm, addr+3);
sqlite3VdbeAddOp(v, OP_Delete, iParm, 0);
@@ -680,7 +677,7 @@ static KeyInfo *keyInfoFromExprList(Parse *pParse, ExprList *pList){
** routine generates the code needed to do that.
*/
static void generateSortTail(
Parse *pParse, /* The parsing context */
Parse *pParse, /* Parsing context */
Select *p, /* The SELECT statement */
Vdbe *v, /* Generate code into this VDBE */
int nColumn, /* Number of columns of data */
@@ -691,11 +688,20 @@ static void generateSortTail(
int cont = sqlite3VdbeMakeLabel(v);
int addr;
int iTab;
int pseudoTab;
ExprList *pOrderBy = p->pOrderBy;
iTab = pOrderBy->iECursor;
if( eDest==SRT_Callback || eDest==SRT_Subroutine ){
pseudoTab = pParse->nTab++;
sqlite3VdbeAddOp(v, OP_OpenPseudo, pseudoTab, 0);
sqlite3VdbeAddOp(v, OP_SetNumColumns, pseudoTab, nColumn);
}
addr = 1 + sqlite3VdbeAddOp(v, OP_Sort, iTab, brk);
codeOffset(v, p, cont, 0);
if( eDest==SRT_Callback || eDest==SRT_Subroutine ){
sqlite3VdbeAddOp(v, OP_Integer, 1, 0);
}
sqlite3VdbeAddOp(v, OP_Column, iTab, pOrderBy->nExpr + 1);
switch( eDest ){
case SRT_Table:
@@ -725,17 +731,15 @@ static void generateSortTail(
case SRT_Callback:
case SRT_Subroutine: {
int i;
sqlite3VdbeAddOp(v, OP_Integer, p->pEList->nExpr, 0);
sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
sqlite3VdbeAddOp(v, OP_Insert, pseudoTab, 0);
for(i=0; i<nColumn; i++){
sqlite3VdbeAddOp(v, OP_Column, -1-i, i);
sqlite3VdbeAddOp(v, OP_Column, pseudoTab, i);
}
if( eDest==SRT_Callback ){
sqlite3VdbeAddOp(v, OP_Callback, nColumn, 0);
}else{
sqlite3VdbeAddOp(v, OP_Gosub, 0, iParm);
}
sqlite3VdbeAddOp(v, OP_Pop, 2, 0);
break;
}
default: {
@@ -756,6 +760,10 @@ static void generateSortTail(
sqlite3VdbeResolveLabel(v, cont);
sqlite3VdbeAddOp(v, OP_Next, iTab, addr);
sqlite3VdbeResolveLabel(v, brk);
if( eDest==SRT_Callback || eDest==SRT_Subroutine ){
sqlite3VdbeAddOp(v, OP_Close, pseudoTab, 0);
}
}
/*
@@ -1039,6 +1047,7 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){
ExprList *pEList;
Column *aCol, *pCol;
while( pSelect->pPrior ) pSelect = pSelect->pPrior;
if( prepSelectStmt(pParse, pSelect) ){
return 0;
}
@@ -1535,20 +1544,6 @@ static void createSortingIndex(Parse *pParse, Select *p, ExprList *pOrderBy){
}
}
/*
** The opcode at addr is an OP_OpenVirtual that created a sorting
** index tha we ended up not needing. This routine changes that
** opcode to OP_Noop.
*/
static void uncreateSortingIndex(Parse *pParse, int addr){
Vdbe *v = pParse->pVdbe;
VdbeOp *pOp = sqlite3VdbeGetOp(v, addr);
sqlite3VdbeChangeP3(v, addr, 0, 0);
pOp->opcode = OP_Noop;
pOp->p1 = 0;
pOp->p2 = 0;
}
#ifndef SQLITE_OMIT_COMPOUND_SELECT
/*
** Return the appropriate collating sequence for the iCol-th column of
@@ -1771,7 +1766,9 @@ static int multiSelect(
int iCont, iBreak, iStart;
assert( p->pEList );
if( eDest==SRT_Callback ){
generateColumnNames(pParse, 0, p->pEList);
Select *pFirst = p;
while( pFirst->pPrior ) pFirst = pFirst->pPrior;
generateColumnNames(pParse, 0, pFirst->pEList);
}
iBreak = sqlite3VdbeMakeLabel(v);
iCont = sqlite3VdbeMakeLabel(v);
@@ -1847,7 +1844,9 @@ static int multiSelect(
*/
assert( p->pEList );
if( eDest==SRT_Callback ){
generateColumnNames(pParse, 0, p->pEList);
Select *pFirst = p;
while( pFirst->pPrior ) pFirst = pFirst->pPrior;
generateColumnNames(pParse, 0, pFirst->pEList);
}
iBreak = sqlite3VdbeMakeLabel(v);
iCont = sqlite3VdbeMakeLabel(v);
@@ -2117,7 +2116,6 @@ static void substSelect(Select *p, int iTable, ExprList *pEList){
** the subquery before this routine runs.
*/
static int flattenSubquery(
Parse *pParse, /* The parsing context */
Select *p, /* The parent or outer SELECT statement */
int iFrom, /* Index in p->pSrc->a[] of the inner subquery */
int isAgg, /* True if outer SELECT uses aggregate functions */
@@ -2245,7 +2243,6 @@ static int flattenSubquery(
** We look at every expression in the outer query and every place we see
** "a" we substitute "x*3" and every place we see "b" we substitute "y+10".
*/
substExprList(p->pEList, iParent, pSub->pEList);
pList = p->pEList;
for(i=0; i<pList->nExpr; i++){
Expr *pExpr;
@@ -2253,6 +2250,7 @@ static int flattenSubquery(
pList->a[i].zName = sqliteStrNDup((char*)pExpr->span.z, pExpr->span.n);
}
}
substExprList(p->pEList, iParent, pSub->pEList);
if( isAgg ){
substExprList(p->pGroupBy, iParent, pSub->pEList);
substExpr(p->pHaving, iParent, pSub->pEList);
@@ -2683,13 +2681,14 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
if( pF->iDistinct>=0 ){
addrNext = sqlite3VdbeMakeLabel(v);
assert( nArg==1 );
codeDistinct(v, pF->iDistinct, addrNext, 1, 2);
codeDistinct(v, pF->iDistinct, addrNext, 1);
}
if( pF->pFunc->needCollSeq ){
CollSeq *pColl = 0;
struct ExprList_item *pItem;
int j;
for(j=0, pItem=pList->a; !pColl && j<pList->nExpr; j++, pItem++){
assert( pList!=0 ); /* pList!=0 if pF->pFunc->needCollSeq is true */
for(j=0, pItem=pList->a; !pColl && j<nArg; j++, pItem++){
pColl = sqlite3ExprCollSeq(pParse, pItem->pExpr);
}
if( !pColl ){
@@ -2902,7 +2901,7 @@ int sqlite3Select(
*/
#ifndef SQLITE_OMIT_VIEW
if( pParent && pParentAgg &&
flattenSubquery(pParse, pParent, parentTab, *pParentAgg, isAgg) ){
flattenSubquery(pParent, parentTab, *pParentAgg, isAgg) ){
if( isAgg ) *pParentAgg = 1;
goto select_end;
}
@@ -2973,7 +2972,7 @@ int sqlite3Select(
** into an OP_Noop.
*/
if( addrSortIndex>=0 && pOrderBy==0 ){
uncreateSortingIndex(pParse, addrSortIndex);
sqlite3VdbeChangeToNoop(v, addrSortIndex, 1);
p->addrOpenVirt[2] = -1;
}
@@ -3219,7 +3218,7 @@ int sqlite3Select(
sqlite3VdbeAddOp(v, OP_Next, sAggInfo.sortingIdx, addrTopOfLoop);
}else{
sqlite3WhereEnd(pWInfo);
uncreateSortingIndex(pParse, addrSortingIdx);
sqlite3VdbeChangeToNoop(v, addrSortingIdx, 1);
}
/* Output the final row of result

View File

@@ -12,7 +12,7 @@
** This header file defines the interface that the SQLite library
** presents to client programs.
**
** @(#) $Id: sqlite3.h,v 1.4 2006-02-16 10:11:46 jmiltner Exp $
** @(#) $Id: sqlite3.h,v 1.5 2006-05-04 13:48:36 tabuleiro Exp $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
@@ -31,7 +31,7 @@ extern "C" {
#ifdef SQLITE_VERSION
# undef SQLITE_VERSION
#endif
#define SQLITE_VERSION "3.3.4"
#define SQLITE_VERSION "3.3.5"
/*
** The format of the version string is "X.Y.Z<trailing string>", where
@@ -48,7 +48,7 @@ extern "C" {
#ifdef SQLITE_VERSION_NUMBER
# undef SQLITE_VERSION_NUMBER
#endif
#define SQLITE_VERSION_NUMBER 3003004
#define SQLITE_VERSION_NUMBER 3003005
/*
** The version string is also compiled into the library so that a program
@@ -78,7 +78,10 @@ typedef struct sqlite3 sqlite3;
** to do a typedef that for 64-bit integers that depends on what compiler
** is being used.
*/
#if defined(_MSC_VER) || defined(__BORLANDC__)
#ifdef SQLITE_INT64_TYPE
typedef SQLITE_INT64_TYPE sqlite_int64;
typedef unsigned SQLITE_INT64_TYPE sqlite_uint64;
#elif defined(_MSC_VER) || defined(__BORLANDC__)
typedef __int64 sqlite_int64;
typedef unsigned __int64 sqlite_uint64;
#else
@@ -1114,11 +1117,12 @@ void sqlite3_result_value(sqlite3_context*, sqlite3_value*);
** These are the allowed values for the eTextRep argument to
** sqlite3_create_collation and sqlite3_create_function.
*/
#define SQLITE_UTF8 1
#define SQLITE_UTF16LE 2
#define SQLITE_UTF16BE 3
#define SQLITE_UTF16 4 /* Use native byte order */
#define SQLITE_ANY 5 /* sqlite3_create_function only */
#define SQLITE_UTF8 1
#define SQLITE_UTF16LE 2
#define SQLITE_UTF16BE 3
#define SQLITE_UTF16 4 /* Use native byte order */
#define SQLITE_ANY 5 /* sqlite3_create_function only */
#define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */
/*
** These two functions are used to add new collation sequences to the

View File

@@ -11,7 +11,7 @@
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.6 2006-02-16 10:11:46 jmiltner Exp $
** @(#) $Id: sqliteInt.h,v 1.7 2006-05-04 13:48:36 tabuleiro Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
@@ -112,18 +112,6 @@
#define OMIT_TEMPDB 0
#endif
/*
** If the following macro is set to 1, then NULL values are considered
** distinct for the SELECT DISTINCT statement and for UNION or EXCEPT
** compound queries. No other SQL database engine (among those tested)
** works this way except for OCELOT. But the SQL92 spec implies that
** this is how things should work.
**
** If the following macro is set to 0, then NULLs are indistinct for
** SELECT DISTINCT and for UNION.
*/
#define NULL_ALWAYS_DISTINCT 0
/*
** If the following macro is set to 1, then NULL values are considered
** distinct when determining whether or not two entries are the same
@@ -179,6 +167,16 @@
#define offsetof(STRUCTURE,FIELD) ((int)((char*)&((STRUCTURE*)0)->FIELD))
#endif
/*
** Check to see if this machine uses EBCDIC. (Yes, believe it or
** not, there are still machines out there that use EBCDIC.)
*/
#if 'A' == '\301'
# define SQLITE_EBCDIC 1
#else
# define SQLITE_ASCII 1
#endif
/*
** Integers of known sizes. These typedefs might change for architectures
** where the sizes very. Preprocessor macros are available so that the
@@ -186,13 +184,6 @@
**
** cc '-DUINTPTR_TYPE=long long int' ...
*/
#ifndef UINT64_TYPE
# if defined(_MSC_VER) || defined(__BORLANDC__)
# define UINT64_TYPE unsigned __int64
# else
# define UINT64_TYPE unsigned long long int
# endif
#endif
#ifndef UINT32_TYPE
# define UINT32_TYPE unsigned int
#endif
@@ -212,7 +203,7 @@
# define LONGDOUBLE_TYPE long double
#endif
typedef sqlite_int64 i64; /* 8-byte signed integer */
typedef UINT64_TYPE u64; /* 8-byte unsigned integer */
typedef sqlite_uint64 u64; /* 8-byte unsigned integer */
typedef UINT32_TYPE u32; /* 4-byte unsigned integer */
typedef UINT16_TYPE u16; /* 2-byte unsigned integer */
typedef INT16_TYPE i16; /* 2-byte signed integer */
@@ -251,12 +242,6 @@ struct BusyHandler {
#include "btree.h"
#include "pager.h"
/*
** This macro casts a pointer to an integer. Useful for doing
** pointer arithmetic.
*/
#define Addr(X) ((uptr)X)
#ifdef SQLITE_MEMDEBUG
/*
** The following global variables are used for testing and debugging
@@ -267,7 +252,6 @@ extern int sqlite3_nFree; /* Number of sqliteFree() calls */
extern int sqlite3_iMallocFail; /* Fail sqliteMalloc() after this many calls */
extern int sqlite3_iMallocReset; /* Set iMallocFail to this when it reaches 0 */
extern void *sqlite3_pFirst; /* Pointer to linked list of allocations */
extern int sqlite3_nMaxAlloc; /* High water mark of ThreadData.nAlloc */
extern int sqlite3_mallocDisallowed; /* assert() in sqlite3Malloc() if set */
@@ -276,8 +260,8 @@ extern const char *sqlite3_zFile; /* Filename to associate debug info with */
extern int sqlite3_iLine; /* Line number for debug info */
#define ENTER_MALLOC (sqlite3_zFile = __FILE__, sqlite3_iLine = __LINE__)
#define sqliteMalloc(x) (ENTER_MALLOC, sqlite3Malloc(x))
#define sqliteMallocRaw(x) (ENTER_MALLOC, sqlite3MallocRaw(x))
#define sqliteMalloc(x) (ENTER_MALLOC, sqlite3Malloc(x,1))
#define sqliteMallocRaw(x) (ENTER_MALLOC, sqlite3MallocRaw(x,1))
#define sqliteRealloc(x,y) (ENTER_MALLOC, sqlite3Realloc(x,y))
#define sqliteStrDup(x) (ENTER_MALLOC, sqlite3StrDup(x))
#define sqliteStrNDup(x,y) (ENTER_MALLOC, sqlite3StrNDup(x,y))
@@ -285,8 +269,9 @@ extern int sqlite3_iLine; /* Line number for debug info */
#else
#define sqliteMalloc(x) sqlite3Malloc(x)
#define sqliteMallocRaw(x) sqlite3MallocRaw(x)
#define ENTER_MALLOC 0
#define sqliteMalloc(x) sqlite3Malloc(x,1)
#define sqliteMallocRaw(x) sqlite3MallocRaw(x,1)
#define sqliteRealloc(x,y) sqlite3Realloc(x,y)
#define sqliteStrDup(x) sqlite3StrDup(x)
#define sqliteStrNDup(x,y) sqlite3StrNDup(x,y)
@@ -516,6 +501,9 @@ struct sqlite3 {
#endif
};
/*
** A macro to discover the encoding of a database.
*/
#define ENC(db) ((db)->aDb[0].pSchema->enc)
/*
@@ -1389,8 +1377,8 @@ struct TriggerStep {
ExprList *pExprList; /* Valid for UPDATE statements and sometimes
INSERT steps (when pSelect == 0) */
IdList *pIdList; /* Valid for INSERT statements only */
TriggerStep * pNext; /* Next in the link-list */
TriggerStep *pNext; /* Next in the link-list */
TriggerStep *pLast; /* Last element in link-list. Valid for 1st elem only */
};
/*
@@ -1483,8 +1471,8 @@ int sqlite3Compare(const char *, const char *);
int sqlite3SortCompare(const char *, const char *);
void sqlite3RealToSortable(double r, char *);
void *sqlite3Malloc(int);
void *sqlite3MallocRaw(int);
void *sqlite3Malloc(int,int);
void *sqlite3MallocRaw(int,int);
void sqlite3Free(void*);
void *sqlite3Realloc(void*,int);
char *sqlite3StrDup(const char*);
@@ -1525,7 +1513,7 @@ void sqlite3RollbackInternalChanges(sqlite3*);
void sqlite3CommitInternalChanges(sqlite3*);
Table *sqlite3ResultSetOfSelect(Parse*,char*,Select*);
void sqlite3OpenMasterTable(Parse *, int);
void sqlite3StartTable(Parse*,Token*,Token*,Token*,int,int,int);
void sqlite3StartTable(Parse*,Token*,Token*,int,int,int);
void sqlite3AddColumn(Parse*,Token*);
void sqlite3AddNotNull(Parse*, int);
void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int);
@@ -1581,7 +1569,7 @@ Table *sqlite3LocateTable(Parse*,const char*, const char*);
Index *sqlite3FindIndex(sqlite3*,const char*, const char*);
void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
void sqlite3Vacuum(Parse*, Token*);
void sqlite3Vacuum(Parse*);
int sqlite3RunVacuum(char**, sqlite3*);
char *sqlite3NameFromToken(Token*);
int sqlite3ExprCheck(Parse*, Expr*, int, int*);
@@ -1602,7 +1590,7 @@ int sqlite3ExprIsConstantOrFunction(Expr*);
int sqlite3ExprIsInteger(Expr*, int*);
int sqlite3IsRowid(const char*);
void sqlite3GenerateRowDelete(sqlite3*, Vdbe*, Table*, int, int);
void sqlite3GenerateRowIndexDelete(sqlite3*, Vdbe*, Table*, int, char*);
void sqlite3GenerateRowIndexDelete(Vdbe*, Table*, int, char*);
void sqlite3GenerateIndexKey(Vdbe*, Index*, int);
void sqlite3GenerateConstraintChecks(Parse*,Table*,int,char*,int,int,int,int);
void sqlite3CompleteInsertion(Parse*, Table*, int, char*, int, int, int);
@@ -1627,7 +1615,7 @@ void sqlite3ChangeCookie(sqlite3*, Vdbe*, int);
int,Expr*,int);
void sqlite3FinishTrigger(Parse*, TriggerStep*, Token*);
void sqlite3DropTrigger(Parse*, SrcList*);
void sqlite3DropTriggerPtr(Parse*, Trigger*, int);
void sqlite3DropTriggerPtr(Parse*, Trigger*);
int sqlite3TriggersExist(Parse*, Table*, int, ExprList*);
int sqlite3CodeRowTrigger(Parse*, int, ExprList*, int, Table *, int, int,
int, int);
@@ -1642,7 +1630,7 @@ void sqlite3ChangeCookie(sqlite3*, Vdbe*, int);
#else
# define sqlite3TriggersExist(A,B,C,D,E,F) 0
# define sqlite3DeleteTrigger(A)
# define sqlite3DropTriggerPtr(A,B,C)
# define sqlite3DropTriggerPtr(A,B)
# define sqlite3UnlinkAndDeleteTrigger(A,B,C)
# define sqlite3CodeRowTrigger(A,B,C,D,E,F,G,H,I) 0
#endif
@@ -1750,6 +1738,7 @@ int sqlite3ApiExit(sqlite3 *db, int);
int sqlite3MallocFailed(void);
void sqlite3FailedMalloc(void);
void sqlite3AbortOtherActiveVdbes(sqlite3 *, Vdbe *);
int sqlite3OpenTempDatabase(Parse *);
#ifndef SQLITE_OMIT_SHARED_CACHE
void sqlite3TableLock(Parse *, int, int, u8, const char *);
@@ -1767,6 +1756,14 @@ void sqlite3AbortOtherActiveVdbes(sqlite3 *, Vdbe *);
#define sqlite3MallocAllow()
#endif
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
void *sqlite3ThreadSafeMalloc(int);
void sqlite3ThreadSafeFree(void *);
#else
#define sqlite3ThreadSafeMalloc sqlite3MallocX
#define sqlite3ThreadSafeFree sqlite3FreeX
#endif
#ifdef SQLITE_SSE
#include "sseInt.h"
#endif

View File

@@ -15,13 +15,46 @@
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
**
** $Id: tokenize.c,v 1.6 2006-02-16 10:11:46 jmiltner Exp $
** $Id: tokenize.c,v 1.7 2006-05-04 13:48:36 tabuleiro Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include <stdlib.h>
/*
** The charMap() macro maps alphabetic characters into their
** lower-case ASCII equivalent. On ASCII machines, this is just
** an upper-to-lower case map. On EBCDIC machines we also need
** to adjust the encoding. Only alphabetic characters and underscores
** need to be translated.
*/
#ifdef SQLITE_ASCII
# define charMap(X) sqlite3UpperToLower[(unsigned char)X]
#endif
#ifdef SQLITE_EBCDIC
# define charMap(X) ebcdicToAscii[(unsigned char)X]
const unsigned char ebcdicToAscii[] = {
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1x */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2x */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 3x */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 4x */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 5x */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 0, 0, /* 6x */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7x */
0, 97, 98, 99,100,101,102,103,104,105, 0, 0, 0, 0, 0, 0, /* 8x */
0,106,107,108,109,110,111,112,113,114, 0, 0, 0, 0, 0, 0, /* 9x */
0, 0,115,116,117,118,119,120,121,122, 0, 0, 0, 0, 0, 0, /* Ax */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Bx */
0, 97, 98, 99,100,101,102,103,104,105, 0, 0, 0, 0, 0, 0, /* Cx */
0,106,107,108,109,110,111,112,113,114, 0, 0, 0, 0, 0, 0, /* Dx */
0, 0,115,116,117,118,119,120,121,122, 0, 0, 0, 0, 0, 0, /* Ex */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Fx */
};
#endif
/*
** The sqlite3KeywordCode function looks up an identifier to determine if
** it is a keyword. If it is a keyword, the token code of that keyword is
@@ -37,24 +70,22 @@
/*
** If X is a character that can be used in an identifier and
** X&0x80==0 then sqlite3IsIdChar[X] will be 1. If X&0x80==0x80 then
** X is always an identifier character. (Hence all UTF-8
** characters can be part of an identifier). sqlite3IsIdChar[X] will
** be 0 for every character in the lower 128 ASCII characters
** that cannot be used as part of an identifier.
** If X is a character that can be used in an identifier then
** IdChar(X) will be true. Otherwise it is false.
**
** In this implementation, an identifier can be a string of
** alphabetic characters, digits, and "_" plus any character
** with the high-order bit set. The latter rule means that
** any sequence of UTF-8 characters or characters taken from
** an extended ISO8859 character set can form an identifier.
** For ASCII, any character with the high-order bit set is
** allowed in an identifier. For 7-bit characters,
** sqlite3IsIdChar[X] must be 1.
**
** For EBCDIC, the rules are more complex but have the same
** end result.
**
** Ticket #1066. the SQL standard does not allow '$' in the
** middle of identfiers. But many SQL implementations do.
** SQLite will allow '$' in identifiers for compatibility.
** But the feature is undocumented.
*/
#ifdef SQLITE_ASCII
const char sqlite3IsIdChar[] = {
/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */
0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2x */
@@ -64,8 +95,27 @@ const char sqlite3IsIdChar[] = {
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6x */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 7x */
};
#define IdChar(C) (((c=C)&0x80)!=0 || (c>0x1f && sqlite3IsIdChar[c-0x20]))
#endif
#ifdef SQLITE_EBCDIC
const char sqlite3IsIdChar[] = {
/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */
0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 4x */
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, /* 5x */
0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, /* 6x */
0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, /* 7x */
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, /* 8x */
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, /* 9x */
1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, /* Ax */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Bx */
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, /* Cx */
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, /* Dx */
0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, /* Ex */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, /* Fx */
};
#define IdChar(C) (((c=C)>=0x42 && sqlite3IsIdChar[c-0x40]))
#endif
/*
** Return the length of the token that begins at z[0].

View File

@@ -60,9 +60,11 @@ void sqlite3BeginTrigger(
DbFixer sFix;
int iTabDb;
assert( pName1!=0 ); /* pName1->z might be NULL, but not pName1 itself */
assert( pName2!=0 );
if( isTemp ){
/* If TEMP was specified, then the trigger name may not be qualified. */
if( pName2 && pName2->n>0 ){
if( pName2->n>0 ){
sqlite3ErrorMsg(pParse, "temporary trigger may not have qualified name");
goto trigger_cleanup;
}
@@ -108,7 +110,7 @@ void sqlite3BeginTrigger(
if( !zName || SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
goto trigger_cleanup;
}
if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash), zName,pName->n+1) ){
if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash), zName,strlen(zName)) ){
sqlite3ErrorMsg(pParse, "trigger %T already exists", pName);
goto trigger_cleanup;
}
@@ -255,7 +257,7 @@ void sqlite3FinishTrigger(
Table *pTab;
Trigger *pDel;
pDel = sqlite3HashInsert(&db->aDb[iDb].pSchema->trigHash,
pTrig->name, strlen(pTrig->name)+1, pTrig);
pTrig->name, strlen(pTrig->name), pTrig);
if( pDel ){
assert( sqlite3MallocFailed() && pDel==pTrig );
goto triggerfinish_cleanup;
@@ -453,14 +455,14 @@ void sqlite3DropTrigger(Parse *pParse, SrcList *pName){
for(i=OMIT_TEMPDB; i<db->nDb; i++){
int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
if( zDb && sqlite3StrICmp(db->aDb[j].zName, zDb) ) continue;
pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName, nName+1);
pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName, nName);
if( pTrigger ) break;
}
if( !pTrigger ){
sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0);
goto drop_trigger_cleanup;
}
sqlite3DropTriggerPtr(pParse, pTrigger, 0);
sqlite3DropTriggerPtr(pParse, pTrigger);
drop_trigger_cleanup:
sqlite3SrcListDelete(pName);
@@ -470,18 +472,16 @@ drop_trigger_cleanup:
** Return a pointer to the Table structure for the table that a trigger
** is set on.
*/
static Table *tableOfTrigger(sqlite3 *db, Trigger *pTrigger){
static Table *tableOfTrigger(Trigger *pTrigger){
int n = strlen(pTrigger->table) + 1;
return sqlite3HashFind(&pTrigger->pTabSchema->tblHash, pTrigger->table, n);
}
/*
** Drop a trigger given a pointer to that trigger. If nested is false,
** then also generate code to remove the trigger from the SQLITE_MASTER
** table.
** Drop a trigger given a pointer to that trigger.
*/
void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger, int nested){
void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){
Table *pTable;
Vdbe *v;
sqlite3 *db = pParse->db;
@@ -489,8 +489,8 @@ void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger, int nested){
iDb = sqlite3SchemaToIndex(pParse->db, pTrigger->pSchema);
assert( iDb>=0 && iDb<db->nDb );
pTable = tableOfTrigger(db, pTrigger);
assert(pTable);
pTable = tableOfTrigger(pTrigger);
assert( pTable );
assert( pTable->pSchema==pTrigger->pSchema || iDb==1 );
#ifndef SQLITE_OMIT_AUTHORIZATION
{
@@ -507,7 +507,8 @@ void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger, int nested){
/* Generate code to destroy the database record of the trigger.
*/
if( pTable!=0 && (v = sqlite3GetVdbe(pParse))!=0 ){
assert( pTable!=0 );
if( (v = sqlite3GetVdbe(pParse))!=0 ){
int base;
static const VdbeOpList dropTrigger[] = {
{ OP_Rewind, 0, ADDR(9), 0},
@@ -537,9 +538,10 @@ void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger, int nested){
void sqlite3UnlinkAndDeleteTrigger(sqlite3 *db, int iDb, const char *zName){
Trigger *pTrigger;
int nName = strlen(zName);
pTrigger = sqlite3HashInsert(&(db->aDb[iDb].pSchema->trigHash), zName, nName+1, 0);
pTrigger = sqlite3HashInsert(&(db->aDb[iDb].pSchema->trigHash),
zName, nName, 0);
if( pTrigger ){
Table *pTable = tableOfTrigger(db, pTrigger);
Table *pTable = tableOfTrigger(pTrigger);
assert( pTable!=0 );
if( pTable->pTrigger == pTrigger ){
pTable->pTrigger = pTrigger->pNext;
@@ -597,14 +599,7 @@ int sqlite3TriggersExist(
while( pTrigger ){
if( pTrigger->op==op && checkColumnOverLap(pTrigger->pColumns, pChanges) ){
TriggerStack *ss;
ss = pParse->trigStack;
while( ss && ss->pTrigger!=pTab->pTrigger ){
ss = ss->pNext;
}
if( ss==0 ){
mask |= pTrigger->tr_tm;
}
mask |= pTrigger->tr_tm;
}
pTrigger = pTrigger->pNext;
}
@@ -761,10 +756,17 @@ int sqlite3CodeRowTrigger(
(op!=TK_UPDATE||!p->pColumns||checkColumnOverLap(p->pColumns,pChanges))
){
TriggerStack *pS; /* Pointer to trigger-stack entry */
for(pS=pParse->trigStack; pS && p!=pS->pTrigger; pS=pS->pNext);
for(pS=pParse->trigStack; pS && p!=pS->pTrigger; pS=pS->pNext){}
if( !pS ){
fire_this = 1;
}
#if 0 /* Give no warning for recursive triggers. Just do not do them */
else{
sqlite3ErrorMsg(pParse, "recursive triggers not supported (%s)",
p->name);
return SQLITE_ERROR;
}
#endif
}
if( fire_this ){

View File

@@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser
** to handle UPDATE statements.
**
** $Id: update.c,v 1.6 2006-02-16 10:11:47 jmiltner Exp $
** $Id: update.c,v 1.7 2006-05-04 13:48:36 tabuleiro Exp $
*/
#include "sqliteInt.h"
@@ -431,7 +431,7 @@ void sqlite3Update(
/* Delete the old indices for the current record.
*/
sqlite3GenerateRowIndexDelete(db, v, pTab, iCur, aIdxUsed);
sqlite3GenerateRowIndexDelete(v, pTab, iCur, aIdxUsed);
/* If changing the record number, delete the old record.
*/

View File

@@ -12,7 +12,7 @@
** This file contains routines used to translate between UTF-8,
** UTF-16, UTF-16BE, and UTF-16LE.
**
** $Id: utf.c,v 1.4 2006-02-16 10:11:47 jmiltner Exp $
** $Id: utf.c,v 1.5 2006-05-04 13:48:36 tabuleiro Exp $
**
** Notes on UTF-8:
**
@@ -255,7 +255,7 @@ int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){
#if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG)
{
char zBuf[100];
sqlite3VdbeMemPrettyPrint(pMem, zBuf, 100);
sqlite3VdbeMemPrettyPrint(pMem, zBuf);
fprintf(stderr, "INPUT: %s\n", zBuf);
}
#endif
@@ -371,7 +371,7 @@ translate_out:
#if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG)
{
char zBuf[100];
sqlite3VdbeMemPrettyPrint(pMem, zBuf, 100);
sqlite3VdbeMemPrettyPrint(pMem, zBuf);
fprintf(stderr, "OUTPUT: %s\n", zBuf);
}
#endif

View File

@@ -14,7 +14,7 @@
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.6 2006-02-16 10:11:47 jmiltner Exp $
** $Id: util.c,v 1.7 2006-05-04 13:48:36 tabuleiro Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -443,6 +443,7 @@ int sqlite3OutstandingMallocs(Tcl_Interp *interp){
** This is the test layer's wrapper around sqlite3OsMalloc().
*/
static void * OSMALLOC(int n){
sqlite3OsEnterMutex();
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
sqlite3_nMaxAlloc =
MAX(sqlite3_nMaxAlloc, sqlite3ThreadDataReadOnly()->nAlloc);
@@ -455,8 +456,10 @@ static void * OSMALLOC(int n){
sqlite3_nMalloc++;
applyGuards(p);
linkAlloc(p);
sqlite3OsLeaveMutex();
return (void *)(&p[TESTALLOC_NGUARD + 2*sizeof(void *)/sizeof(u32)]);
}
sqlite3OsLeaveMutex();
return 0;
}
@@ -473,12 +476,14 @@ static int OSSIZEOF(void *p){
** pointer to the space allocated for the application to use.
*/
static void OSFREE(void *pFree){
sqlite3OsEnterMutex();
u32 *p = (u32 *)getOsPointer(pFree); /* p points to Os level allocation */
checkGuards(p);
unlinkAlloc(p);
memset(pFree, 0x55, OSSIZEOF(pFree));
sqlite3OsFree(p);
sqlite3_nFree++;
sqlite3OsLeaveMutex();
}
/*
@@ -542,7 +547,7 @@ static int enforceSoftLimit(int n){
}
assert( pTsd->nAlloc>=0 );
if( n>0 && pTsd->nSoftHeapLimit>0 ){
while( pTsd->nAlloc+n>pTsd->nSoftHeapLimit && sqlite3_release_memory(n) );
while( pTsd->nAlloc+n>pTsd->nSoftHeapLimit && sqlite3_release_memory(n) ){}
}
return 1;
}
@@ -578,14 +583,14 @@ static void updateMemoryUsedCount(int n){
** sqlite3OsMalloc(). If the Malloc() call fails, attempt to free memory
** by calling sqlite3_release_memory().
*/
void *sqlite3MallocRaw(int n){
void *sqlite3MallocRaw(int n, int doMemManage){
void *p = 0;
if( n>0 && !sqlite3MallocFailed() && enforceSoftLimit(n) ){
while( (p = OSMALLOC(n))==0 && sqlite3_release_memory(n) );
if( n>0 && !sqlite3MallocFailed() && (!doMemManage || enforceSoftLimit(n)) ){
while( (p = OSMALLOC(n))==0 && sqlite3_release_memory(n) ){}
if( !p ){
sqlite3FailedMalloc();
OSMALLOC_FAILED();
}else{
}else if( doMemManage ){
updateMemoryUsedCount(OSSIZEOF(p));
}
}
@@ -603,14 +608,14 @@ void *sqlite3Realloc(void *p, int n){
}
if( !p ){
return sqlite3Malloc(n);
return sqlite3Malloc(n, 1);
}else{
void *np = 0;
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
int origSize = OSSIZEOF(p);
#endif
if( enforceSoftLimit(n - origSize) ){
while( (np = OSREALLOC(p, n))==0 && sqlite3_release_memory(n) );
while( (np = OSREALLOC(p, n))==0 && sqlite3_release_memory(n) ){}
if( !np ){
sqlite3FailedMalloc();
OSMALLOC_FAILED();
@@ -648,8 +653,8 @@ void *sqlite3MallocX(int n){
** These two are implemented as wrappers around sqlite3MallocRaw(),
** sqlite3Realloc() and sqlite3Free().
*/
void *sqlite3Malloc(int n){
void *p = sqlite3MallocRaw(n);
void *sqlite3Malloc(int n, int doMemManage){
void *p = sqlite3MallocRaw(n, doMemManage);
if( p ){
memset(p, 0, n);
}
@@ -663,6 +668,33 @@ void sqlite3ReallocOrFree(void **pp, int n){
*pp = p;
}
/*
** sqlite3ThreadSafeMalloc() and sqlite3ThreadSafeFree() are used in those
** rare scenarios where sqlite may allocate memory in one thread and free
** it in another. They are exactly the same as sqlite3Malloc() and
** sqlite3Free() except that:
**
** * The allocated memory is not included in any calculations with
** respect to the soft-heap-limit, and
**
** * sqlite3ThreadSafeMalloc() must be matched with ThreadSafeFree(),
** not sqlite3Free(). Calling sqlite3Free() on memory obtained from
** ThreadSafeMalloc() will cause an error somewhere down the line.
*/
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
void *sqlite3ThreadSafeMalloc(int n){
ENTER_MALLOC;
return sqlite3Malloc(n, 0);
}
void sqlite3ThreadSafeFree(void *p){
ENTER_MALLOC;
if( p ){
OSFREE(p);
}
}
#endif
/*
** Return the number of bytes allocated at location p. p must be either
** a NULL pointer (in which case 0 is returned) or a pointer returned by
@@ -689,14 +721,14 @@ int sqlite3AllocSize(void *p){
char *sqlite3StrDup(const char *z){
char *zNew;
if( z==0 ) return 0;
zNew = sqlite3MallocRaw(strlen(z)+1);
zNew = sqlite3MallocRaw(strlen(z)+1, 1);
if( zNew ) strcpy(zNew, z);
return zNew;
}
char *sqlite3StrNDup(const char *z, int n){
char *zNew;
if( z==0 ) return 0;
zNew = sqlite3MallocRaw(n+1);
zNew = sqlite3MallocRaw(n+1, 1);
if( zNew ){
memcpy(zNew, z, n);
zNew[n] = 0;
@@ -851,6 +883,7 @@ void sqlite3Dequote(char *z){
** lower-case character.
*/
const unsigned char sqlite3UpperToLower[] = {
#ifdef SQLITE_ASCII
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 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, 48, 49, 50, 51, 52, 53,
@@ -866,6 +899,25 @@ const unsigned char sqlite3UpperToLower[] = {
216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,
234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,
252,253,254,255
#endif
#ifdef SQLITE_EBCDIC
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 0x */
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* 1x */
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, /* 2x */
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, /* 3x */
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, /* 4x */
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, /* 5x */
96, 97, 66, 67, 68, 69, 70, 71, 72, 73,106,107,108,109,110,111, /* 6x */
112, 81, 82, 83, 84, 85, 86, 87, 88, 89,122,123,124,125,126,127, /* 7x */
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, /* 8x */
144,145,146,147,148,149,150,151,152,153,154,155,156,157,156,159, /* 9x */
160,161,162,163,164,165,166,167,168,169,170,171,140,141,142,175, /* Ax */
176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, /* Bx */
192,129,130,131,132,133,134,135,136,137,202,203,204,205,206,207, /* Cx */
208,145,146,147,148,149,150,151,152,153,218,219,220,221,222,223, /* Dx */
224,225,162,163,164,165,166,167,168,169,232,203,204,205,206,207, /* Ex */
239,240,241,242,243,244,245,246,247,248,249,219,220,221,222,255, /* Fx */
#endif
};
#define UpperToLower sqlite3UpperToLower
@@ -939,6 +991,7 @@ int sqlite3AtoF(const char *z, double *pResult){
int sign = 1;
const char *zBegin = z;
LONGDOUBLE_TYPE v1 = 0.0;
while( isspace(*z) ) z++;
if( *z=='-' ){
sign = -1;
z++;
@@ -1006,6 +1059,7 @@ int sqlite3atoi64(const char *zNum, i64 *pNum){
i64 v = 0;
int neg;
int i, c;
while( isspace(*zNum) ) zNum++;
if( *zNum=='-' ){
neg = 1;
zNum++;

View File

@@ -14,7 +14,7 @@
** Most of the code in this file may be omitted by defining the
** SQLITE_OMIT_VACUUM macro.
**
** $Id: vacuum.c,v 1.6 2006-02-16 10:11:47 jmiltner Exp $
** $Id: vacuum.c,v 1.7 2006-05-04 13:48:36 tabuleiro Exp $
*/
#include "sqliteInt.h"
#include "vdbeInt.h"
@@ -43,7 +43,7 @@ static int execSql(sqlite3 *db, const char *zSql){
if( SQLITE_OK!=sqlite3_prepare(db, zSql, -1, &pStmt, 0) ){
return sqlite3_errcode(db);
}
while( SQLITE_ROW==sqlite3_step(pStmt) );
while( SQLITE_ROW==sqlite3_step(pStmt) ){}
return sqlite3_finalize(pStmt);
}
@@ -81,7 +81,7 @@ static int execExecSql(sqlite3 *db, const char *zSql){
** with 2.0.0, SQLite no longer uses GDBM so this command has
** become a no-op.
*/
void sqlite3Vacuum(Parse *pParse, Token *pTableName){
void sqlite3Vacuum(Parse *pParse){
Vdbe *v = sqlite3GetVdbe(pParse);
if( v ){
sqlite3VdbeAddOp(v, OP_Vacuum, 0, 0);

View File

@@ -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.6 2006-02-16 10:11:47 jmiltner Exp $
** $Id: vdbe.c,v 1.7 2006-05-04 13:48:36 tabuleiro Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -280,7 +280,7 @@ void sqlite3ValueApplyAffinity(sqlite3_value *pVal, u8 affinity, u8 enc){
** Write a nice string representation of the contents of cell pMem
** into buffer zBuf, length nBuf.
*/
void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf, int nBuf){
void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf){
char *zCsr = zBuf;
int f = pMem->flags;
@@ -1871,13 +1871,6 @@ case OP_SetNumColumns: { /* no-push */
** If the KeyAsData opcode has previously executed on this cursor, then the
** field might be extracted from the key rather than the data.
**
** If P1 is negative, then the record is stored on the stack rather than in
** a table. For P1==-1, the top of the stack is used. For P1==-2, the
** next on the stack is used. And so forth. The value pushed is always
** just a pointer into the record which is stored further down on the
** stack. The column value is not copied. The number of columns in the
** record is stored on the stack just above the record itself.
**
** If the column contains fewer than P2 fields, then push a NULL. Or
** if P3 is of type P3_MEM, then push the P3 value. The P3 value will
** be default value for a column that has been added using the ALTER TABLE
@@ -1909,31 +1902,19 @@ case OP_Column: {
** bytes in the record.
**
** zRec is set to be the complete text of the record if it is available.
** The complete record text is always available for pseudo-tables and
** when we are decoded a record from the stack. If the record is stored
** in a cursor, the complete record text might be available in the
** pC->aRow cache. Or it might not be. If the data is unavailable,
** zRec is set to NULL.
** The complete record text is always available for pseudo-tables
** If the record is stored in a cursor, the complete record text
** might be available in the pC->aRow cache. Or it might not be.
** If the data is unavailable, zRec is set to NULL.
**
** We also compute the number of columns in the record. For cursors,
** the number of columns is stored in the Cursor.nField element. For
** records on the stack, the next entry down on the stack is an integer
** which is the number of records.
*/
assert( p1<0 || p->apCsr[p1]!=0 );
if( p1<0 ){
/* Take the record off of the stack */
Mem *pRec = &pTos[p1];
Mem *pCnt = &pRec[-1];
assert( pRec>=p->aStack );
assert( pRec->flags & MEM_Blob );
payloadSize = pRec->n;
zRec = pRec->z;
assert( pCnt>=p->aStack );
assert( pCnt->flags & MEM_Int );
nField = pCnt->i;
pCrsr = 0;
}else if( (pC = p->apCsr[p1])->pCursor!=0 ){
pC = p->apCsr[p1];
assert( pC!=0 );
if( pC->pCursor!=0 ){
/* The record is stored in a B-Tree */
rc = sqlite3VdbeCursorMoveto(pC);
if( rc ) goto abort_due_to_error;
@@ -1952,7 +1933,6 @@ case OP_Column: {
sqlite3BtreeDataSize(pCrsr, &payloadSize);
}
nField = pC->nField;
#ifndef SQLITE_OMIT_TRIGGER
}else if( pC->pseudoTable ){
/* The record is the sole entry of a pseudo-table */
payloadSize = pC->nData;
@@ -1961,7 +1941,6 @@ case OP_Column: {
assert( payloadSize==0 || zRec!=0 );
nField = pC->nField;
pCrsr = 0;
#endif
}else{
zRec = 0;
payloadSize = 0;
@@ -1989,15 +1968,17 @@ case OP_Column: {
u32 offset; /* Offset into the data */
int szHdrSz; /* Size of the header size field at start of record */
int avail; /* Number of bytes of available data */
if( pC && pC->aType ){
aType = pC->aType;
}else{
aType = sqliteMallocRaw( 2*nField*sizeof(aType) );
aType = pC->aType;
if( aType==0 ){
pC->aType = aType = sqliteMallocRaw( 2*nField*sizeof(aType) );
}
aOffset = &aType[nField];
if( aType==0 ){
goto no_mem;
}
pC->aOffset = aOffset = &aType[nField];
pC->payloadSize = payloadSize;
pC->cacheStatus = p->cacheCtr;
/* Figure out how many bytes are in the header */
if( zRec ){
@@ -2070,15 +2051,6 @@ case OP_Column: {
rc = SQLITE_CORRUPT_BKPT;
goto op_column_out;
}
/* Remember all aType and aColumn information if we have a cursor
** to remember it in. */
if( pC ){
pC->payloadSize = payloadSize;
pC->aType = aType;
pC->aOffset = aOffset;
pC->cacheStatus = p->cacheCtr;
}
}
/* Get the column information. If aOffset[p2] is non-zero, then
@@ -2111,7 +2083,7 @@ case OP_Column: {
/* If we dynamically allocated space to hold the data (in the
** sqlite3VdbeMemFromBtree() call above) then transfer control of that
** dynamically allocated space over to the pTos structure rather.
** dynamically allocated space over to the pTos structure.
** This prevents a memory copy.
*/
if( (sMem.flags & MEM_Dyn)!=0 ){
@@ -2128,10 +2100,6 @@ case OP_Column: {
rc = sqlite3VdbeMemMakeWriteable(pTos);
op_column_out:
/* Release the aType[] memory if we are not dealing with cursor */
if( !pC || !pC->aType ){
sqliteFree(aType);
}
break;
}
@@ -2722,7 +2690,6 @@ case OP_OpenVirtual: { /* no-push */
break;
}
#ifndef SQLITE_OMIT_TRIGGER
/* Opcode: OpenPseudo P1 * *
**
** Open a new cursor that points to a fake table that contains a single
@@ -2731,7 +2698,9 @@ case OP_OpenVirtual: { /* no-push */
** closed.
**
** A pseudo-table created by this opcode is useful for holding the
** NEW or OLD tables in a trigger.
** NEW or OLD tables in a trigger. Also used to hold the a single
** row output from the sorter so that the row can be decomposed into
** individual columns using the OP_Column opcode.
*/
case OP_OpenPseudo: { /* no-push */
int i = pOp->p1;
@@ -2746,7 +2715,6 @@ case OP_OpenPseudo: { /* no-push */
pCx->isIndex = 0;
break;
}
#endif
/* Opcode: Close P1 * *
**
@@ -3013,7 +2981,7 @@ case OP_IsUnique: { /* no-push */
zKey = pNos->z;
nKey = pNos->n;
szRowid = sqlite3VdbeIdxRowidLen(nKey, (u8*)zKey);
szRowid = sqlite3VdbeIdxRowidLen((u8*)zKey);
len = nKey-szRowid;
/* Search for an entry in P1 where all but the last four bytes match K.
@@ -3320,7 +3288,6 @@ case OP_Insert: { /* no-push */
}else{
assert( pTos->flags & (MEM_Blob|MEM_Str) );
}
#ifndef SQLITE_OMIT_TRIGGER
if( pC->pseudoTable ){
sqliteFree(pC->pData);
pC->iKey = iKey;
@@ -3337,11 +3304,8 @@ case OP_Insert: { /* no-push */
}
pC->nullRow = 0;
}else{
#endif
rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey, pTos->z, pTos->n);
#ifndef SQLITE_OMIT_TRIGGER
}
#endif
pC->rowidIsValid = 0;
pC->deferredMoveto = 0;
@@ -3498,12 +3462,10 @@ case OP_RowData: {
}else{
sqlite3BtreeData(pCrsr, 0, n, pTos->z);
}
#ifndef SQLITE_OMIT_TRIGGER
}else if( pC->pseudoTable ){
pTos->n = pC->nData;
pTos->z = pC->pData;
pTos->flags = MEM_Blob|MEM_Ephem;
#endif
}else{
pTos->flags = MEM_Null;
}
@@ -4071,7 +4033,7 @@ case OP_ParseSchema: { /* no-push */
break;
}
#ifndef SQLITE_OMIT_ANALYZE
#if !defined(SQLITE_OMIT_ANALYZE) && !defined(SQLITE_OMIT_PARSER)
/* Opcode: LoadAnalysis P1 * *
**
** Read the sqlite_stat1 table for database P1 and load the content
@@ -4084,7 +4046,7 @@ case OP_LoadAnalysis: { /* no-push */
sqlite3AnalysisLoad(db, iDb);
break;
}
#endif /* SQLITE_OMIT_ANALYZE */
#endif /* !defined(SQLITE_OMIT_ANALYZE) && !defined(SQLITE_OMIT_PARSER) */
/* Opcode: DropTable P1 * P3
**
@@ -4536,7 +4498,7 @@ case OP_Expire: { /* no-push */
** Obtain a lock on a particular table. This instruction is only used when
** the shared-cache feature is enabled.
**
** If P1 is not negative, then it is the index of the index of the database
** If P1 is not negative, then it is the index of the database
** in sqlite3.aDb[] and a read-lock is required. If P1 is negative, a
** write-lock is required. In this case the index of the database is the
** absolute value of P1 minus one (iDb = abs(P1) - 1;) and a write-lock is
@@ -4600,7 +4562,7 @@ default: {
#ifndef NDEBUG
/* Sanity checking on the top element of the stack */
if( pTos>=p->aStack ){
sqlite3VdbeMemSanity(pTos, encoding);
sqlite3VdbeMemSanity(pTos);
}
assert( pc>=-1 && pc<p->nOp );
#ifdef SQLITE_DEBUG
@@ -4619,7 +4581,7 @@ default: {
fprintf(p->trace, " r:%g", pTos[i].r);
}else{
char zBuf[100];
sqlite3VdbeMemPrettyPrint(&pTos[i], zBuf, 100);
sqlite3VdbeMemPrettyPrint(&pTos[i], zBuf);
fprintf(p->trace, " ");
fprintf(p->trace, "%s", zBuf);
}

View File

@@ -15,7 +15,7 @@
** or VDBE. The VDBE implements an abstract machine that runs a
** simple program to access and modify the underlying database.
**
** $Id: vdbe.h,v 1.6 2006-02-16 10:11:47 jmiltner Exp $
** $Id: vdbe.h,v 1.7 2006-05-04 13:48:36 tabuleiro Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
@@ -117,6 +117,7 @@ int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp);
void sqlite3VdbeChangeP1(Vdbe*, int addr, int P1);
void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2);
void sqlite3VdbeJumpHere(Vdbe*, int addr);
void sqlite3VdbeChangeToNoop(Vdbe*, int addr, int N);
void sqlite3VdbeChangeP3(Vdbe*, int addr, const char *zP1, int N);
VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
int sqlite3VdbeMakeLabel(Vdbe*);

View File

@@ -317,6 +317,10 @@ struct Vdbe {
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 */
#ifdef SQLITE_SSE
int fetchId; /* Statement number used by sqlite3_fetch_statement */
int lru; /* Counter used for LRU cache replacement */
#endif
};
/*
@@ -350,7 +354,7 @@ int sqlite3VdbeIdxKeyCompare(Cursor*, int , const unsigned char*, int*);
int sqlite3VdbeIdxRowid(BtCursor *, i64 *);
int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
int sqlite3VdbeRecordCompare(void*,int,const void*,int, const void*);
int sqlite3VdbeIdxRowidLen(int,const u8*);
int sqlite3VdbeIdxRowidLen(const u8*);
int sqlite3VdbeExec(Vdbe*);
int sqlite3VdbeList(Vdbe*);
int sqlite3VdbeHalt(Vdbe*);
@@ -376,11 +380,11 @@ int sqlite3VdbeMemFromBtree(BtCursor*,int,int,int,Mem*);
void sqlite3VdbeMemRelease(Mem *p);
int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
#ifndef NDEBUG
void sqlite3VdbeMemSanity(Mem*, u8);
void sqlite3VdbeMemSanity(Mem*);
int sqlite3VdbeOpcodeNoPush(u8);
#endif
int sqlite3VdbeMemTranslate(Mem*, u8);
void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf, int nBuf);
void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf);
int sqlite3VdbeMemHandleBom(Mem *pMem);
void sqlite3VdbeFifoInit(Fifo*);
int sqlite3VdbeFifoPush(Fifo*, i64);

View File

@@ -107,9 +107,11 @@ int sqlite3VdbeAddOp(Vdbe *p, int op, int p1, int p2){
i = p->nOp;
p->nOp++;
assert( p->magic==VDBE_MAGIC_INIT );
resizeOpArray(p, i+1);
if( sqlite3MallocFailed() ){
return 0;
if( p->nOpAlloc<=i ){
resizeOpArray(p, i+1);
if( sqlite3MallocFailed() ){
return 0;
}
}
pOp = &p->aOp[i];
pOp->opcode = op;
@@ -202,11 +204,11 @@ static int opcodeNoPush(u8 op){
** IEEE floats.
*/
static const u32 masks[5] = {
NOPUSH_MASK_0 + (NOPUSH_MASK_1<<16),
NOPUSH_MASK_2 + (NOPUSH_MASK_3<<16),
NOPUSH_MASK_4 + (NOPUSH_MASK_5<<16),
NOPUSH_MASK_6 + (NOPUSH_MASK_7<<16),
NOPUSH_MASK_8 + (NOPUSH_MASK_9<<16)
NOPUSH_MASK_0 + (((unsigned)NOPUSH_MASK_1)<<16),
NOPUSH_MASK_2 + (((unsigned)NOPUSH_MASK_3)<<16),
NOPUSH_MASK_4 + (((unsigned)NOPUSH_MASK_5)<<16),
NOPUSH_MASK_6 + (((unsigned)NOPUSH_MASK_7)<<16),
NOPUSH_MASK_8 + (((unsigned)NOPUSH_MASK_9)<<16)
};
assert( op<32*5 );
return (masks[op>>5] & (1<<(op&0x1F)));
@@ -340,7 +342,7 @@ int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp){
** few minor changes to the program.
*/
void sqlite3VdbeChangeP1(Vdbe *p, int addr, int val){
assert( p->magic==VDBE_MAGIC_INIT );
assert( p==0 || p->magic==VDBE_MAGIC_INIT );
if( p && addr>=0 && p->nOp>addr && p->aOp ){
p->aOp[addr].p1 = val;
}
@@ -352,14 +354,14 @@ void sqlite3VdbeChangeP1(Vdbe *p, int addr, int val){
*/
void sqlite3VdbeChangeP2(Vdbe *p, int addr, int val){
assert( val>=0 );
assert( p->magic==VDBE_MAGIC_INIT );
assert( p==0 || p->magic==VDBE_MAGIC_INIT );
if( p && addr>=0 && p->nOp>addr && p->aOp ){
p->aOp[addr].p2 = val;
}
}
/*
** Change teh P2 operand of instruction addr so that it points to
** Change the P2 operand of instruction addr so that it points to
** the address of the next instruction to be coded.
*/
void sqlite3VdbeJumpHere(Vdbe *p, int addr){
@@ -393,6 +395,19 @@ static void freeP3(int p3type, void *p3){
}
/*
** Change N opcodes starting at addr to No-ops.
*/
void sqlite3VdbeChangeToNoop(Vdbe *p, int addr, int N){
VdbeOp *pOp = &p->aOp[addr];
while( N-- ){
freeP3(pOp->p3type, pOp->p3);
memset(pOp, 0, sizeof(pOp[0]));
pOp->opcode = OP_Noop;
pOp++;
}
}
/*
** Change the value of the P3 operand for a specific instruction.
** This routine is useful when a large program is loaded from a
@@ -420,7 +435,7 @@ static void freeP3(int p3type, void *p3){
*/
void sqlite3VdbeChangeP3(Vdbe *p, int addr, const char *zP3, int n){
Op *pOp;
assert( p->magic==VDBE_MAGIC_INIT );
assert( p==0 || p->magic==VDBE_MAGIC_INIT );
if( p==0 || p->aOp==0 || sqlite3MallocFailed() ){
if (n != P3_KEYINFO) {
freeP3(n, (void*)*(char**)&zP3);
@@ -656,8 +671,9 @@ int sqlite3VdbeList(
pMem->type = SQLITE_INTEGER;
pMem++;
pMem->flags = MEM_Short|MEM_Str|MEM_Term; /* P3 */
pMem->flags = MEM_Ephem|MEM_Str|MEM_Term; /* P3 */
pMem->z = displayP3(pOp, pMem->zShort, sizeof(pMem->zShort));
pMem->n = strlen(pMem->z);
pMem->type = SQLITE_TEXT;
pMem->enc = SQLITE_UTF8;
@@ -1841,7 +1857,7 @@ int sqlite3VdbeRecordCompare(
** an integer rowid). This routine returns the number of bytes in
** that integer.
*/
int sqlite3VdbeIdxRowidLen(int nKey, const u8 *aKey){
int sqlite3VdbeIdxRowidLen(const u8 *aKey){
u32 szHdr; /* Size of the header */
u32 typeRowid; /* Serial type of the rowid */
@@ -1911,7 +1927,7 @@ int sqlite3VdbeIdxKeyCompare(
if( rc ){
return rc;
}
lenRowid = sqlite3VdbeIdxRowidLen(m.n, (u8*)m.z);
lenRowid = sqlite3VdbeIdxRowidLen((u8*)m.z);
*res = sqlite3VdbeRecordCompare(pC->pKeyInfo, m.n-lenRowid, m.z, nKey, pKey);
sqlite3VdbeMemRelease(&m);
return SQLITE_OK;

View File

@@ -42,6 +42,7 @@ int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){
return SQLITE_ERROR;
#else
/* MemTranslate() may return SQLITE_OK or SQLITE_NOMEM. If NOMEM is returned,
** then the encoding of the value may not have changed.
*/
@@ -118,6 +119,7 @@ int sqlite3VdbeMemMakeWriteable(Mem *pMem){
z[n+1] = 0;
pMem->z = (char*)z;
pMem->flags &= ~(MEM_Ephem|MEM_Static);
assert(0==(1&(int)pMem->z));
return SQLITE_OK;
}
@@ -596,19 +598,25 @@ int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){
if( pColl ){
if( pMem1->enc==pColl->enc ){
/* The strings are already in the correct encoding. Call the
** comparison function directly */
return pColl->xCmp(pColl->pUser,pMem1->n,pMem1->z,pMem2->n,pMem2->z);
}else{
u8 origEnc = pMem1->enc;
rc = pColl->xCmp(
pColl->pUser,
sqlite3ValueBytes((sqlite3_value*)pMem1, pColl->enc),
sqlite3ValueText((sqlite3_value*)pMem1, pColl->enc),
sqlite3ValueBytes((sqlite3_value*)pMem2, pColl->enc),
sqlite3ValueText((sqlite3_value*)pMem2, pColl->enc)
);
sqlite3ValueBytes((sqlite3_value*)pMem1, origEnc);
const void *v1, *v2;
int n1, n2;
/* Convert the strings into the encoding that the comparison
** function expects */
v1 = sqlite3ValueText((sqlite3_value*)pMem1, pColl->enc);
n1 = v1==0 ? 0 : pMem1->n;
assert( n1==sqlite3ValueBytes((sqlite3_value*)pMem1, pColl->enc) );
v2 = sqlite3ValueText((sqlite3_value*)pMem2, pColl->enc);
n2 = v2==0 ? 0 : pMem2->n;
assert( n2==sqlite3ValueBytes((sqlite3_value*)pMem2, pColl->enc) );
/* Do the comparison */
rc = pColl->xCmp(pColl->pUser, n1, v1, n2, v2);
/* Convert the strings back into the database encoding */
sqlite3ValueText((sqlite3_value*)pMem1, origEnc);
sqlite3ValueBytes((sqlite3_value*)pMem2, origEnc);
sqlite3ValueText((sqlite3_value*)pMem2, origEnc);
return rc;
}
@@ -703,7 +711,7 @@ int sqlite3VdbeMemFromBtree(
** Perform various checks on the memory cell pMem. An assert() will
** fail if pMem is internally inconsistent.
*/
void sqlite3VdbeMemSanity(Mem *pMem, u8 db_enc){
void sqlite3VdbeMemSanity(Mem *pMem){
int flags = pMem->flags;
assert( flags!=0 ); /* Must define some type */
if( pMem->flags & (MEM_Str|MEM_Blob) ){
@@ -752,10 +760,14 @@ void sqlite3VdbeMemSanity(Mem *pMem, u8 db_enc){
** except the data returned is in the encoding specified by the second
** parameter, which must be one of SQLITE_UTF16BE, SQLITE_UTF16LE or
** SQLITE_UTF8.
**
** (2006-02-16:) The enc value can be or-ed with SQLITE_UTF16_ALIGNED.
** If that is the case, then the result must be aligned on an even byte
** boundary.
*/
const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){
if( !pVal ) return 0;
assert( enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE || enc==SQLITE_UTF8);
assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
if( pVal->flags&MEM_Null ){
return 0;
@@ -763,12 +775,23 @@ const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){
assert( (MEM_Blob>>3) == MEM_Str );
pVal->flags |= (pVal->flags & MEM_Blob)>>3;
if( pVal->flags&MEM_Str ){
sqlite3VdbeChangeEncoding(pVal, enc);
sqlite3VdbeChangeEncoding(pVal, enc & ~SQLITE_UTF16_ALIGNED);
if( (enc & SQLITE_UTF16_ALIGNED)!=0 && 1==(1&(int)pVal->z) ){
assert( (pVal->flags & (MEM_Ephem|MEM_Static))!=0 );
if( sqlite3VdbeMemMakeWriteable(pVal)!=SQLITE_OK ){
return 0;
}
}
}else if( !(pVal->flags&MEM_Blob) ){
sqlite3VdbeMemStringify(pVal, enc);
assert( 0==(1&(int)pVal->z) );
}
assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || sqlite3MallocFailed() );
if( pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) ){
return pVal->z;
}else{
return 0;
}
assert(pVal->enc==enc || sqlite3MallocFailed() );
return (const void *)(pVal->enc==enc ? (pVal->z) : 0);
}
/*

View File

@@ -16,7 +16,7 @@
** so is applicable. Because this module is responsible for selecting
** indices, you might also think of this module as the "query optimizer".
**
** $Id: where.c,v 1.6 2006-02-16 10:11:47 jmiltner Exp $
** $Id: where.c,v 1.7 2006-05-04 13:48:36 tabuleiro Exp $
*/
#include "sqliteInt.h"
@@ -771,8 +771,7 @@ or_not_possible:
static int isSortingIndex(
Parse *pParse, /* Parsing context */
Index *pIdx, /* The index we are testing */
Table *pTab, /* The table to be sorted */
int base, /* Cursor number for pTab */
int base, /* Cursor number for the table to be sorted */
ExprList *pOrderBy, /* The ORDER BY clause */
int nEqCol, /* Number of index columns with == constraints */
int *pbRev /* Set to 1 if ORDER BY is DESC */
@@ -927,6 +926,22 @@ static double bestIndex(
TRACE(("bestIndex: tbl=%s notReady=%x\n", pSrc->pTab->zName, notReady));
lowestCost = SQLITE_BIG_DBL;
pProbe = pSrc->pTab->pIndex;
/* If the table has no indices and there are no terms in the where
** clause that refer to the ROWID, then we will never be able to do
** anything other than a full table scan on this table. We might as
** well put it first in the join order. That way, perhaps it can be
** referenced by other tables in the join.
*/
if( pProbe==0 &&
findTerm(pWC, iCur, -1, 0, WO_EQ|WO_IN|WO_LT|WO_LE|WO_GT|WO_GE,0)==0 &&
(pOrderBy==0 || !sortableByRowid(iCur, pOrderBy, &rev)) ){
*pFlags = 0;
*ppIndex = 0;
*pnEq = 0;
return 0.0;
}
/* Check for a rowid=EXPR or rowid IN (...) constraints
*/
@@ -959,7 +974,6 @@ static double bestIndex(
/* Estimate the cost of a table scan. If we do not know how many
** entries are in the table, use 1 million as a guess.
*/
pProbe = pSrc->pTab->pIndex;
cost = pProbe ? pProbe->aiRowEst[0] : 1000000;
TRACE(("... table scan base cost: %.9g\n", cost));
flags = WHERE_ROWID_RANGE;
@@ -1057,7 +1071,7 @@ static double bestIndex(
*/
if( pOrderBy ){
if( (flags & WHERE_COLUMN_IN)==0 &&
isSortingIndex(pParse,pProbe,pSrc->pTab,iCur,pOrderBy,nEq,&rev) ){
isSortingIndex(pParse,pProbe,iCur,pOrderBy,nEq,&rev) ){
if( flags==0 ){
flags = WHERE_COLUMN_RANGE;
}
@@ -1591,7 +1605,7 @@ WhereInfo *sqlite3WhereBegin(
if( pTab->nCol<(sizeof(Bitmask)*8) ){
Bitmask b = pTabItem->colUsed;
int n = 0;
for(; b; b=b>>1, n++);
for(; b; b=b>>1, n++){}
sqlite3VdbeChangeP2(v, sqlite3VdbeCurrentAddr(v)-1, n);
assert( n<=pTab->nCol );
}