mirror of
https://github.com/sqlitebrowser/sqlitebrowser.git
synced 2026-01-20 19:11:39 -06:00
updated to Sqlite 3.3.5 sources
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
**
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 ){
|
||||
|
||||
@@ -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 ){
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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].
|
||||
|
||||
@@ -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 ){
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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++;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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*);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user