#
#
# patch "ChangeLog"
# from [7044edcbf9586840754451d599adce80fd28085e]
# to [7fbfacfd6eb7f8444712762f48501ae2b206ad6b]
#
# patch "sqlite/alter.c"
# from [faf98b04050d674d06df21bcf23ded5bbff7b5b7]
# to [451b34fc4eb2475ca76a2e86b21e1030a9428091]
#
# patch "sqlite/btree.c"
# from [f45f57e6cbd3b3db947cdd699db64e5215d20b2a]
# to [23bbfb4745e549ca224f6c933a6e9bc106d77f56]
#
# patch "sqlite/btree.h"
# from [5663c4f43e8521546ccebc8fc95acb013b8f3184]
# to [40055cfc09defd1146bc5b922399c035f969e56d]
#
# patch "sqlite/build.c"
# from [feaa61e769d7887ffeaa060d746638c7b3e994ef]
# to [b46cd7d0e2daca775d9de0cba8abae1b1625caf4]
#
# patch "sqlite/date.c"
# from [c70a4f88e495ae2c523f6ef3848c26a021c96de8]
# to [cd2bd5d1ebc6fa12d6312f69789ae5b0a2766f2e]
#
# patch "sqlite/delete.c"
# from [56ab34c3a384caa5d5ea06f5739944957e2e4213]
# to [ca404d5fd5f678e32f2f46377ad802cd0219aa99]
#
# patch "sqlite/expr.c"
# from [1149c3380bfce27703f5e9bec7dfb8e51baaf9d9]
# to [9c957fabf95ef62288151eecd5c490a629470666]
#
# patch "sqlite/func.c"
# from [96b26601c092b7b43a13e440e3f988b32a385f6a]
# to [93d004b453a5d9aa754e673eef75d3c9527e0f54]
#
# patch "sqlite/insert.c"
# from [7e931b7f06afbcefcbbaab175c02eff8268db33f]
# to [67b3dc11831c58d8703eb502355ad3704ee18f66]
#
# patch "sqlite/main.c"
# from [2693776249865dc69b97904205638e84a34a059c]
# to [9a42464c44a6532003391486e802e65e88789cfc]
#
# patch "sqlite/os_common.h"
# from [061fba8511a656b118551424f64e366ad0d4cb3b]
# to [108cd719c96a2b714b64e02aeabbd40684274e6a]
#
# patch "sqlite/os_unix.c"
# from [73c5e722a661ed98d8919f204911e4e34e51fa41]
# to [378a89aaf15d83b901c1b73350e91ddecf743986]
#
# patch "sqlite/os_win.c"
# from [566bf7b41b72556fd7dca390bceaa2769dc395e9]
# to [c67a2c46d929cf54c8f80ec5e6079cf684a141a9]
#
# patch "sqlite/pager.c"
# from [b5b380ea7a36f84e50c3adc1a414820a0eb3baa6]
# to [c438aa5fc248e0523e80591eeae33a3993c47278]
#
# patch "sqlite/pager.h"
# from [e0acb095b3ad0bca48f2ab00c87346665643f64f]
# to [425a9e52d5404158de016799715cbc2c3d685178]
#
# patch "sqlite/parse.h"
# from [20eb1ccb1fa5d4e4493dd0ca916ad74b515eefcf]
# to [ae4ee794251454f9c8b4c97ef7fee85deecdcec5]
#
# patch "sqlite/pragma.c"
# from [4496cc77dc35824e1c978c3d1413b8a5a4c777d3]
# to [31d3e1b74cab2172807894e70c674d6a577501fd]
#
# patch "sqlite/prepare.c"
# from [40ae23c8aeb641dc7b9bb271eb5e295b815154a7]
# to [cf0fc8ebaf94409955ecb09ffeb0099c9ef44693]
#
# patch "sqlite/select.c"
# from [daee9b20702ba51cf3807fc1b130edd8846e3e48]
# to [7d069e875d0eec05129c7e8b9c99422d7c9c6321]
#
# patch "sqlite/sqlite3.h"
# from [6b9ed927e0a9a3c6051a372929c97c2ac87ab314]
# to [d0605a62334179d9c38bf587ac38b777d6daee2b]
#
# patch "sqlite/sqliteInt.h"
# from [0121298397ac14eb468ab1ba9d488ac7ed7d88a1]
# to [f61b60f243f1709c943c62cfb6d7a50209080e38]
#
# patch "sqlite/table.c"
# from [486dcfce532685b53b5a2b5da8bba0ded6fb2316]
# to [f64ec4fbfe333f8df925bc6ba494f55e05b0e75e]
#
# patch "sqlite/tokenize.c"
# from [9ae9a59238eb97fbc61baea280563b91100518fb]
# to [382b3bb0ca26eb9153b5d20b246ef512a114a24f]
#
# patch "sqlite/update.c"
# from [14be4ba2f438919b4217085c02feff569e6cf1f2]
# to [050a7e0ddaac03dec5271712eee62f1a9e699049]
#
# patch "sqlite/util.c"
# from [82ee598519b8193184bdeab06b51a4ffa05ad60b]
# to [405f46fef062b476826d2c171ec21def29563b75]
#
# patch "sqlite/vdbe.c"
# from [fee677e05236e483d6c75d1d4229955fc1b89193]
# to [0a7fd81609429bae2b3c326687b02a60a9c01c49]
#
# patch "sqlite/vdbe.h"
# from [8729a4ee16ff9aeab2af9667df3cf300ff978e13]
# to [80ba1c391ec28180dd07a630577f50b22c2062da]
#
# patch "sqlite/vdbeapi.c"
# from [dcb2636f49b4807e34960d52a2fc257b3a751140]
# to [7dc662e7c905ce666bb506dced932e0307115cbf]
#
# patch "sqlite/vdbeaux.c"
# from [9bf50cdb6a6c40b8c06ca9a8d87cf90120a16797]
# to [95f4ed0bc8ed45f16823d84504310495b5dc587d]
#
# patch "sqlite/where.c"
# from [8409e00fa2cb5fce873b4c911165cfed097e9c49]
# to [c7d71d5e55c9c4c1e948089280fb0dec7c7d1ef6]
#
============================================================
--- ChangeLog 7044edcbf9586840754451d599adce80fd28085e
+++ ChangeLog 7fbfacfd6eb7f8444712762f48501ae2b206ad6b
@@ -1,3 +1,7 @@
+2006-02-17 Matthew Gregan
+
+ * sqlite/*: Import SQLite 3.3.4.
+
2006-02-16 Patrick Mauritz
* netsync.cc (handle_new_connection): Netxx::Address.get_name()
============================================================
--- sqlite/alter.c faf98b04050d674d06df21bcf23ded5bbff7b5b7
+++ sqlite/alter.c 451b34fc4eb2475ca76a2e86b21e1030a9428091
@@ -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.19 2006/01/31 14:28:45 drh Exp $
+** $Id: alter.c,v 1.20 2006/02/09 02:56:03 drh Exp $
*/
#include "sqliteInt.h"
#include
@@ -541,6 +541,7 @@
for(i=0; inCol; i++){
Column *pCol = &pNew->aCol[i];
pCol->zName = sqliteStrDup(pCol->zName);
+ pCol->zColl = 0;
pCol->zType = 0;
pCol->pDflt = 0;
}
============================================================
--- sqlite/btree.c f45f57e6cbd3b3db947cdd699db64e5215d20b2a
+++ sqlite/btree.c 23bbfb4745e549ca224f6c933a6e9bc106d77f56
@@ -9,7 +9,7 @@
** May you share freely, never taking more than you give.
**
*************************************************************************
-** $Id: btree.c,v 1.311 2006/01/24 16:37:58 danielk1977 Exp $
+** $Id: btree.c,v 1.314 2006/02/11 01:25:51 drh Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
@@ -411,8 +411,8 @@
** The table that this cursor was opened on still exists, but has been
** modified since the cursor was last used. The cursor position is saved
** in variables BtCursor.pKey and BtCursor.nKey. When a cursor is in
-** this state, restoreOrClearCursorPosition() can be called to attempt to seek
-** the cursor to the saved position.
+** this state, restoreOrClearCursorPosition() can be called to attempt to
+** seek the cursor to the saved position.
*/
#define CURSOR_INVALID 0
#define CURSOR_VALID 1
@@ -756,10 +756,20 @@
** used to test if pgno is a pointer-map page. PTRMAP_ISPAGE implements
** this test.
*/
-#define PTRMAP_PAGENO(pgsz, pgno) (((pgno-2)/(pgsz/5+1))*(pgsz/5+1)+2)
-#define PTRMAP_PTROFFSET(pgsz, pgno) (((pgno-2)%(pgsz/5+1)-1)*5)
-#define PTRMAP_ISPAGE(pgsz, pgno) (PTRMAP_PAGENO(pgsz,pgno)==pgno)
+#define PTRMAP_PAGENO(pBt, pgno) ptrmapPageno(pBt, pgno)
+#define PTRMAP_PTROFFSET(pBt, pgno) (5*(pgno-ptrmapPageno(pBt, pgno)-1))
+#define PTRMAP_ISPAGE(pBt, pgno) (PTRMAP_PAGENO((pBt),(pgno))==(pgno))
+static Pgno ptrmapPageno(BtShared *pBt, Pgno pgno){
+ int nPagesPerMapPage = (pBt->usableSize/5)+1;
+ int iPtrMap = (pgno-2)/nPagesPerMapPage;
+ int ret = (iPtrMap*nPagesPerMapPage) + 2;
+ if( ret==PENDING_BYTE_PAGE(pBt) ){
+ ret++;
+ }
+ return ret;
+}
+
/*
** The pointer map is a lookup table that identifies the parent page for
** each child page in the database file. The parent page is the page that
@@ -810,16 +820,19 @@
int offset; /* Offset in pointer map page */
int rc;
+ /* The master-journal page number must never be used as a pointer map page */
+ assert( 0==PTRMAP_ISPAGE(pBt, PENDING_BYTE_PAGE(pBt)) );
+
assert( pBt->autoVacuum );
if( key==0 ){
return SQLITE_CORRUPT_BKPT;
}
- iPtrmap = PTRMAP_PAGENO(pBt->usableSize, key);
+ iPtrmap = PTRMAP_PAGENO(pBt, key);
rc = sqlite3pager_get(pBt->pPager, iPtrmap, (void **)&pPtrmap);
if( rc!=SQLITE_OK ){
return rc;
}
- offset = PTRMAP_PTROFFSET(pBt->usableSize, key);
+ offset = PTRMAP_PTROFFSET(pBt, key);
if( eType!=pPtrmap[offset] || get4byte(&pPtrmap[offset+1])!=parent ){
TRACE(("PTRMAP_UPDATE: %d->(%d,%d)\n", key, eType, parent));
@@ -847,13 +860,13 @@
int offset; /* Offset of entry in pointer map */
int rc;
- iPtrmap = PTRMAP_PAGENO(pBt->usableSize, key);
+ iPtrmap = PTRMAP_PAGENO(pBt, key);
rc = sqlite3pager_get(pBt->pPager, iPtrmap, (void **)&pPtrmap);
if( rc!=0 ){
return rc;
}
- offset = PTRMAP_PTROFFSET(pBt->usableSize, key);
+ offset = PTRMAP_PTROFFSET(pBt, key);
if( pEType ) *pEType = pPtrmap[offset];
if( pPgno ) *pPgno = get4byte(&pPtrmap[offset+1]);
@@ -1790,9 +1803,9 @@
** probability of damage to near zero but with a write performance reduction.
*/
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
-int sqlite3BtreeSetSafetyLevel(Btree *p, int level){
+int sqlite3BtreeSetSafetyLevel(Btree *p, int level, int fullSync){
BtShared *pBt = p->pBt;
- sqlite3pager_set_safety_level(pBt->pPager, level);
+ sqlite3pager_set_safety_level(pBt->pPager, level, fullSync);
return SQLITE_OK;
}
#endif
@@ -2344,7 +2357,7 @@
#endif
assert( pBt->autoVacuum );
- if( PTRMAP_ISPAGE(pgsz, sqlite3pager_pagecount(pPager)) ){
+ if( PTRMAP_ISPAGE(pBt, sqlite3pager_pagecount(pPager)) ){
return SQLITE_CORRUPT_BKPT;
}
@@ -2357,15 +2370,27 @@
return SQLITE_OK;
}
+ /* This block figures out how many pages there are in the database
+ ** now (variable origSize), and how many there will be after the
+ ** truncation (variable finSize).
+ **
+ ** The final size is the original size, less the number of free pages
+ ** in the database, less any pointer-map pages that will no longer
+ ** be required, less 1 if the pending-byte page was part of the database
+ ** but is not after the truncation.
+ **/
origSize = sqlite3pager_pagecount(pPager);
- nPtrMap = (nFreeList-origSize+PTRMAP_PAGENO(pgsz, origSize)+pgsz/5)/(pgsz/5);
+ if( origSize==PENDING_BYTE_PAGE(pBt) ){
+ origSize--;
+ }
+ nPtrMap = (nFreeList-origSize+PTRMAP_PAGENO(pBt, origSize)+pgsz/5)/(pgsz/5);
finSize = origSize - nFreeList - nPtrMap;
- if( origSize>=PENDING_BYTE_PAGE(pBt) && finSize<=PENDING_BYTE_PAGE(pBt) ){
+ if( origSize>PENDING_BYTE_PAGE(pBt) && finSize<=PENDING_BYTE_PAGE(pBt) ){
finSize--;
- if( PTRMAP_ISPAGE(pBt->usableSize, finSize) ){
- finSize--;
- }
}
+ while( PTRMAP_ISPAGE(pBt, finSize) || finSize==PENDING_BYTE_PAGE(pBt) ){
+ finSize--;
+ }
TRACE(("AUTOVACUUM: Begin (db size %d->%d)\n", origSize, finSize));
/* Variable 'finSize' will be the size of the file in pages after
@@ -2376,7 +2401,7 @@
*/
for( iDbPage=finSize+1; iDbPage<=origSize; iDbPage++ ){
/* If iDbPage is a pointer map page, or the pending-byte page, skip it. */
- if( PTRMAP_ISPAGE(pgsz, iDbPage) || iDbPage==PENDING_BYTE_PAGE(pBt) ){
+ if( PTRMAP_ISPAGE(pBt, iDbPage) || iDbPage==PENDING_BYTE_PAGE(pBt) ){
continue;
}
@@ -2434,6 +2459,7 @@
put4byte(&pBt->pPage1->aData[36], 0);
if( rc!=SQLITE_OK ) goto autovacuum_out;
*nTrunc = finSize;
+ assert( finSize!=PENDING_BYTE_PAGE(pBt) );
autovacuum_out:
assert( nRef==*sqlite3pager_stats(pPager) );
@@ -3806,7 +3832,7 @@
*pPgno = sqlite3pager_pagecount(pBt->pPager) + 1;
#ifndef SQLITE_OMIT_AUTOVACUUM
- if( pBt->autoVacuum && PTRMAP_ISPAGE(pBt->usableSize, *pPgno) ){
+ if( pBt->autoVacuum && PTRMAP_ISPAGE(pBt, *pPgno) ){
/* If *pPgno refers to a pointer-map page, allocate two new pages
** at the end of the file instead of one. The first allocated page
** becomes a new pointer-map page, the second is used by the caller.
@@ -5440,7 +5466,7 @@
/* The new root-page may not be allocated on a pointer-map page, or the
** PENDING_BYTE page.
*/
- if( pgnoRoot==PTRMAP_PAGENO(pBt->usableSize, pgnoRoot) ||
+ if( pgnoRoot==PTRMAP_PAGENO(pBt, pgnoRoot) ||
pgnoRoot==PENDING_BYTE_PAGE(pBt) ){
pgnoRoot++;
}
@@ -5713,7 +5739,7 @@
if( maxRootPgno==PENDING_BYTE_PAGE(pBt) ){
maxRootPgno--;
}
- if( maxRootPgno==PTRMAP_PAGENO(pBt->usableSize, maxRootPgno) ){
+ if( maxRootPgno==PTRMAP_PAGENO(pBt, maxRootPgno) ){
maxRootPgno--;
}
assert( maxRootPgno!=PENDING_BYTE_PAGE(pBt) );
@@ -6390,11 +6416,11 @@
** references to pointer-map pages.
*/
if( sCheck.anRef[i]==0 &&
- (PTRMAP_PAGENO(pBt->usableSize, i)!=i || !pBt->autoVacuum) ){
+ (PTRMAP_PAGENO(pBt, i)!=i || !pBt->autoVacuum) ){
checkAppendMsg(&sCheck, 0, "Page %d is never used", i);
}
if( sCheck.anRef[i]!=0 &&
- (PTRMAP_PAGENO(pBt->usableSize, i)==i && pBt->autoVacuum) ){
+ (PTRMAP_PAGENO(pBt, i)==i && pBt->autoVacuum) ){
checkAppendMsg(&sCheck, 0, "Pointer map page %d is referenced", i);
}
#endif
@@ -6522,19 +6548,21 @@
** the write-transaction for this database file is to delete the journal.
*/
int sqlite3BtreeSync(Btree *p, const char *zMaster){
+ int rc = SQLITE_OK;
if( p->inTrans==TRANS_WRITE ){
BtShared *pBt = p->pBt;
-#ifndef SQLITE_OMIT_AUTOVACUUM
Pgno nTrunc = 0;
+#ifndef SQLITE_OMIT_AUTOVACUUM
if( pBt->autoVacuum ){
- int rc = autoVacuumCommit(pBt, &nTrunc);
- if( rc!=SQLITE_OK ) return rc;
+ rc = autoVacuumCommit(pBt, &nTrunc);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
}
- return sqlite3pager_sync(pBt->pPager, zMaster, nTrunc);
#endif
- return sqlite3pager_sync(pBt->pPager, zMaster, 0);
+ rc = sqlite3pager_sync(pBt->pPager, zMaster, nTrunc);
}
- return SQLITE_OK;
+ return rc;
}
/*
============================================================
--- sqlite/btree.h 5663c4f43e8521546ccebc8fc95acb013b8f3184
+++ sqlite/btree.h 40055cfc09defd1146bc5b922399c035f969e56d
@@ -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.69 2006/01/07 13:21:04 danielk1977 Exp $
+** @(#) $Id: btree.h,v 1.70 2006/02/11 01:25:51 drh Exp $
*/
#ifndef _BTREE_H_
#define _BTREE_H_
@@ -59,7 +59,7 @@
int sqlite3BtreeClose(Btree*);
int sqlite3BtreeSetBusyHandler(Btree*,BusyHandler*);
int sqlite3BtreeSetCacheSize(Btree*,int);
-int sqlite3BtreeSetSafetyLevel(Btree*,int);
+int sqlite3BtreeSetSafetyLevel(Btree*,int,int);
int sqlite3BtreeSyncDisabled(Btree*);
int sqlite3BtreeSetPageSize(Btree*,int,int);
int sqlite3BtreeGetPageSize(Btree*);
============================================================
--- sqlite/build.c feaa61e769d7887ffeaa060d746638c7b3e994ef
+++ sqlite/build.c b46cd7d0e2daca775d9de0cba8abae1b1625caf4
@@ -22,7 +22,7 @@
** COMMIT
** ROLLBACK
**
-** $Id: build.c,v 1.383 2006/01/24 12:09:19 danielk1977 Exp $
+** $Id: build.c,v 1.386 2006/02/10 18:08:09 drh Exp $
*/
#include "sqliteInt.h"
#include
@@ -1662,12 +1662,10 @@
** Actually, this error is caught previously and so the following test
** should always fail. But we will leave it in place just to be safe.
*/
-#if 0
if( pTable->nCol<0 ){
sqlite3ErrorMsg(pParse, "view %s is circularly defined", pTable->zName);
return 1;
}
-#endif
assert( pTable->nCol>=0 );
/* If we get this far, it means we need to compute the table names.
@@ -2364,10 +2362,10 @@
nExtra /* Collation sequence names */
);
if( sqlite3MallocFailed() ) goto exit_create_index;
- pIndex->aiColumn = (int *)(&pIndex[1]);
+ pIndex->azColl = (char**)(&pIndex[1]);
+ pIndex->aiColumn = (int *)(&pIndex->azColl[nCol]);
pIndex->aiRowEst = (unsigned *)(&pIndex->aiColumn[nCol]);
- pIndex->azColl = (char **)(&pIndex->aiRowEst[nCol+1]);
- pIndex->aSortOrder = (u8 *)(&pIndex->azColl[nCol]);
+ pIndex->aSortOrder = (u8 *)(&pIndex->aiRowEst[nCol+1]);
pIndex->zName = (char *)(&pIndex->aSortOrder[nCol]);
zExtra = (char *)(&pIndex->zName[nName+1]);
strcpy(pIndex->zName, zName);
@@ -2849,6 +2847,7 @@
pItem->zName = sqlite3NameFromToken(pTable);
pItem->zDatabase = sqlite3NameFromToken(pDatabase);
pItem->iCursor = -1;
+ pItem->isPopulated = 0;
pList->nSrc++;
return pList;
}
============================================================
--- sqlite/date.c c70a4f88e495ae2c523f6ef3848c26a021c96de8
+++ sqlite/date.c cd2bd5d1ebc6fa12d6312f69789ae5b0a2766f2e
@@ -16,7 +16,7 @@
** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
** All other code has file scope.
**
-** $Id: date.c,v 1.53 2006/01/24 12:09:19 danielk1977 Exp $
+** $Id: date.c,v 1.54 2006/01/31 20:49:13 drh Exp $
**
** NOTES:
**
@@ -117,8 +117,8 @@
zDate++;
cnt++;
}while( nextC );
+end_getDigits:
va_end(ap);
-end_getDigits:
return cnt;
}
============================================================
--- sqlite/delete.c 56ab34c3a384caa5d5ea06f5739944957e2e4213
+++ sqlite/delete.c ca404d5fd5f678e32f2f46377ad802cd0219aa99
@@ -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.120 2006/01/24 12:09:19 danielk1977 Exp $
+** $Id: delete.c,v 1.121 2006/02/10 02:27:43 danielk1977 Exp $
*/
#include "sqliteInt.h"
@@ -343,7 +343,7 @@
if( db->flags & SQLITE_CountRows && pParse->nested==0 && !pParse->trigStack ){
sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, "rows deleted", P3_STATIC);
+ sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", P3_STATIC);
}
delete_from_cleanup:
============================================================
--- sqlite/expr.c 1149c3380bfce27703f5e9bec7dfb8e51baaf9d9
+++ sqlite/expr.c 9c957fabf95ef62288151eecd5c490a629470666
@@ -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.253 2006/01/30 14:36:59 drh Exp $
+** $Id: expr.c,v 1.254 2006/02/10 07:07:15 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include
@@ -495,6 +495,7 @@
pNewItem->zAlias = sqliteStrDup(pOldItem->zAlias);
pNewItem->jointype = pOldItem->jointype;
pNewItem->iCursor = pOldItem->iCursor;
+ pNewItem->isPopulated = pOldItem->isPopulated;
pTab = pNewItem->pTab = pOldItem->pTab;
if( pTab ){
pTab->nRef++;
============================================================
--- sqlite/func.c 96b26601c092b7b43a13e440e3f988b32a385f6a
+++ sqlite/func.c 93d004b453a5d9aa754e673eef75d3c9527e0f54
@@ -16,7 +16,7 @@
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
**
-** $Id: func.c,v 1.117 2006/01/17 13:21:40 danielk1977 Exp $
+** $Id: func.c,v 1.121 2006/02/09 22:13:42 drh Exp $
*/
#include "sqliteInt.h"
#include
@@ -817,9 +817,9 @@
*/
typedef struct SumCtx SumCtx;
struct SumCtx {
- double sum; /* Sum of terms */
- int cnt; /* Number of elements summed */
- u8 seenFloat; /* True if there has been any floating point value */
+ LONGDOUBLE_TYPE sum; /* Sum of terms */
+ i64 cnt; /* Number of elements summed */
+ u8 approx; /* True if sum is approximate */
};
/*
@@ -830,18 +830,33 @@
** 0.0 in that case. In addition, TOTAL always returns a float where
** SUM might return an integer if it never encounters a floating point
** value.
+**
+** I am told that SUM() should raise an exception if it encounters
+** a integer overflow. But after pondering this, I decided that
+** behavior leads to brittle programs. So instead, I have coded
+** SUM() to revert to using floating point if it encounters an
+** integer overflow. The answer may not be exact, but it will be
+** close. If the SUM() function returns an integer, the value is
+** exact. If SUM() returns a floating point value, it means the
+** value might be approximated.
*/
static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){
SumCtx *p;
int type;
assert( argc==1 );
p = sqlite3_aggregate_context(context, sizeof(*p));
- type = sqlite3_value_type(argv[0]);
+ type = sqlite3_value_numeric_type(argv[0]);
if( p && type!=SQLITE_NULL ){
- p->sum += sqlite3_value_double(argv[0]);
p->cnt++;
- if( type==SQLITE_FLOAT ){
- p->seenFloat = 1;
+ 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);
+ }
+ }else{
+ p->sum += sqlite3_value_double(argv[0]);
+ p->approx = 1;
}
}
}
@@ -849,7 +864,7 @@
SumCtx *p;
p = sqlite3_aggregate_context(context, 0);
if( p && p->cnt>0 ){
- if( p->seenFloat ){
+ if( p->approx ){
sqlite3_result_double(context, p->sum);
}else{
sqlite3_result_int64(context, (i64)p->sum);
@@ -870,23 +885,12 @@
}
/*
-** An instance of the following structure holds the context of a
-** variance or standard deviation computation.
-*/
-typedef struct StdDevCtx StdDevCtx;
-struct StdDevCtx {
- double sum; /* Sum of terms */
- double sum2; /* Sum of the squares of terms */
- int cnt; /* Number of terms counted */
-};
-
-/*
** The following structure keeps track of state information for the
** count() aggregate function.
*/
typedef struct CountCtx CountCtx;
struct CountCtx {
- int n;
+ i64 n;
};
/*
@@ -902,7 +906,7 @@
static void countFinalize(sqlite3_context *context){
CountCtx *p;
p = sqlite3_aggregate_context(context, 0);
- sqlite3_result_int(context, p ? p->n : 0);
+ sqlite3_result_int64(context, p ? p->n : 0);
}
/*
============================================================
--- sqlite/insert.c 7e931b7f06afbcefcbbaab175c02eff8268db33f
+++ sqlite/insert.c 67b3dc11831c58d8703eb502355ad3704ee18f66
@@ -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.160 2006/01/24 12:09:19 danielk1977 Exp $
+** $Id: insert.c,v 1.161 2006/02/10 02:27:43 danielk1977 Exp $
*/
#include "sqliteInt.h"
@@ -703,7 +703,7 @@
sqlite3VdbeAddOp(v, OP_MemLoad, iCntMem, 0);
sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, "rows inserted", P3_STATIC);
+ sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows inserted", P3_STATIC);
}
insert_cleanup:
============================================================
--- sqlite/main.c 2693776249865dc69b97904205638e84a34a059c
+++ sqlite/main.c 9a42464c44a6532003391486e802e65e88789cfc
@@ -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.331 2006/01/24 16:37:58 danielk1977 Exp $
+** $Id: main.c,v 1.334 2006/02/09 13:43:29 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -29,7 +29,6 @@
/*
** The version of the library
*/
-const char rcsid3[] = "@(#) \044Id: SQLite version " SQLITE_VERSION " $";
const char sqlite3_version[] = SQLITE_VERSION;
const char *sqlite3_libversion(void){ return sqlite3_version; }
int sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; }
@@ -732,6 +731,10 @@
return db->errCode;
}
+/*
+** Create a new collating function for database "db". The name is zName
+** and the encoding is enc.
+*/
static int createCollation(
sqlite3* db,
const char *zName,
@@ -817,8 +820,9 @@
** and UTF-16, so add a version for each to avoid any unnecessary
** conversions. The only error that can occur here is a malloc() failure.
*/
- if( createCollation(db, "BINARY", SQLITE_UTF8, 0,binCollFunc) ||
- createCollation(db, "BINARY", SQLITE_UTF16, 0,binCollFunc) ||
+ if( createCollation(db, "BINARY", SQLITE_UTF8, 0, binCollFunc) ||
+ createCollation(db, "BINARY", SQLITE_UTF16BE, 0, binCollFunc) ||
+ createCollation(db, "BINARY", SQLITE_UTF16LE, 0, binCollFunc) ||
(db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 6, 0))==0
){
assert( sqlite3MallocFailed() );
@@ -1113,3 +1117,117 @@
sqlite3OsThreadSpecificData(-1);
}
}
+
+/*
+** Return meta information about a specific column of a database table.
+** See comment in sqlite3.h (sqlite.h.in) for details.
+*/
+#ifdef SQLITE_ENABLE_COLUMN_METADATA
+int sqlite3_table_column_metadata(
+ sqlite3 *db, /* Connection handle */
+ const char *zDbName, /* Database name or NULL */
+ const char *zTableName, /* Table name */
+ const char *zColumnName, /* Column name */
+ char const **pzDataType, /* OUTPUT: Declared data type */
+ char const **pzCollSeq, /* OUTPUT: Collation sequence name */
+ int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */
+ int *pPrimaryKey, /* OUTPUT: True if column part of PK */
+ int *pAutoinc /* OUTPUT: True if colums is auto-increment */
+){
+ int rc;
+ char *zErrMsg = 0;
+ Table *pTab = 0;
+ Column *pCol = 0;
+ int iCol;
+
+ char const *zDataType = 0;
+ char const *zCollSeq = 0;
+ int notnull = 0;
+ int primarykey = 0;
+ int autoinc = 0;
+
+ /* Ensure the database schema has been loaded */
+ if( sqlite3SafetyOn(db) ){
+ return SQLITE_MISUSE;
+ }
+ rc = sqlite3Init(db, &zErrMsg);
+ if( SQLITE_OK!=rc ){
+ goto error_out;
+ }
+
+ /* Locate the table in question */
+ pTab = sqlite3FindTable(db, zTableName, zDbName);
+ if( !pTab || pTab->pSelect ){
+ pTab = 0;
+ goto error_out;
+ }
+
+ /* Find the column for which info is requested */
+ if( sqlite3IsRowid(zColumnName) ){
+ iCol = pTab->iPKey;
+ if( iCol>=0 ){
+ pCol = &pTab->aCol[iCol];
+ }
+ }else{
+ for(iCol=0; iColnCol; iCol++){
+ pCol = &pTab->aCol[iCol];
+ if( 0==sqlite3StrICmp(pCol->zName, zColumnName) ){
+ break;
+ }
+ }
+ if( iCol==pTab->nCol ){
+ pTab = 0;
+ goto error_out;
+ }
+ }
+
+ /* The following block stores the meta information that will be returned
+ ** to the caller in local variables zDataType, zCollSeq, notnull, primarykey
+ ** and autoinc. At this point there are two possibilities:
+ **
+ ** 1. The specified column name was rowid", "oid" or "_rowid_"
+ ** and there is no explicitly declared IPK column.
+ **
+ ** 2. The table is not a view and the column name identified an
+ ** explicitly declared column. Copy meta information from *pCol.
+ */
+ if( pCol ){
+ zDataType = pCol->zType;
+ zCollSeq = pCol->zColl;
+ notnull = (pCol->notNull?1:0);
+ primarykey = (pCol->isPrimKey?1:0);
+ autoinc = ((pTab->iPKey==iCol && pTab->autoInc)?1:0);
+ }else{
+ zDataType = "INTEGER";
+ primarykey = 1;
+ }
+ if( !zCollSeq ){
+ zCollSeq = "BINARY";
+ }
+
+error_out:
+ if( sqlite3SafetyOff(db) ){
+ rc = SQLITE_MISUSE;
+ }
+
+ /* Whether the function call succeeded or failed, set the output parameters
+ ** to whatever their local counterparts contain. If an error did occur,
+ ** this has the effect of zeroing all output parameters.
+ */
+ if( pzDataType ) *pzDataType = zDataType;
+ if( pzCollSeq ) *pzCollSeq = zCollSeq;
+ if( pNotNull ) *pNotNull = notnull;
+ if( pPrimaryKey ) *pPrimaryKey = primarykey;
+ if( pAutoinc ) *pAutoinc = autoinc;
+
+ if( SQLITE_OK==rc && !pTab ){
+ sqlite3SetString(&zErrMsg, "no such table column: ", zTableName, ".",
+ zColumnName, 0);
+ rc = SQLITE_ERROR;
+ }
+ sqlite3Error(db, rc, (zErrMsg?"%s":0), zErrMsg);
+ sqliteFree(zErrMsg);
+ return sqlite3ApiExit(db, rc);
+}
+#endif
+
============================================================
--- sqlite/os_common.h 061fba8511a656b118551424f64e366ad0d4cb3b
+++ sqlite/os_common.h 108cd719c96a2b714b64e02aeabbd40684274e6a
@@ -155,7 +155,7 @@
void *sqlite3GenericRealloc(void *p, int n){
char *p2 = ((char *)p - 8);
assert(n>0);
- p2 = realloc(p2, n+8);
+ p2 = (char*)realloc(p2, n+8);
if( p2 ){
*(int *)p2 = n;
p2 += 8;
============================================================
--- sqlite/os_unix.c 73c5e722a661ed98d8919f204911e4e34e51fa41
+++ sqlite/os_unix.c 378a89aaf15d83b901c1b73350e91ddecf743986
@@ -353,14 +353,23 @@
** 1: Yes. Threads can override each others locks.
** -1: We don't know yet.
**
+** On some systems, we know at compile-time if threads can override each
+** others locks. On those systems, the SQLITE_THREAD_OVERRIDE_LOCK macro
+** will be set appropriately. On other systems, we have to check at
+** runtime. On these latter systems, SQLTIE_THREAD_OVERRIDE_LOCK is
+** undefined.
+**
** This variable normally has file scope only. But during testing, we make
** it a global so that the test code can change its value in order to verify
** that the right stuff happens in either case.
*/
+#ifndef SQLITE_THREAD_OVERRIDE_LOCK
+# define SQLITE_THREAD_OVERRIDE_LOCK -1
+#endif
#ifdef SQLITE_TEST
-int threadsOverrideEachOthersLocks = -1;
+int threadsOverrideEachOthersLocks = SQLITE_THREAD_OVERRIDE_LOCK;
#else
-static int threadsOverrideEachOthersLocks = -1;
+static int threadsOverrideEachOthersLocks = SQLITE_THREAD_OVERRIDE_LOCK;
#endif
/*
@@ -972,7 +981,18 @@
# define fdatasync fsync
#endif
+/*
+** Define HAVE_FULLFSYNC to 0 or 1 depending on whether or not
+** the F_FULLFSYNC macro is defined. F_FULLFSYNC is currently
+** only available on Mac OS X. But that could change.
+*/
+#ifdef F_FULLFSYNC
+# define HAVE_FULLFSYNC 1
+#else
+# define HAVE_FULLFSYNC 0
+#endif
+
/*
** The fsync() system call does not work as advertised on many
** unix systems. The following procedure is an attempt to make
@@ -1003,7 +1023,7 @@
rc = SQLITE_OK;
#else
-#ifdef F_FULLFSYNC
+#if HAVE_FULLFSYNC
if( fullSync ){
rc = fcntl(fd, F_FULLFSYNC, 0);
}else{
@@ -1048,10 +1068,21 @@
return SQLITE_IOERR;
}
if( pFile->dirfd>=0 ){
- TRACE2("DIRSYNC %-3d\n", pFile->dirfd);
+ TRACE4("DIRSYNC %-3d (have_fullfsync=%d fullsync=%d)\n", pFile->dirfd,
+ HAVE_FULLFSYNC, pFile->fullSync);
#ifndef SQLITE_DISABLE_DIRSYNC
- if( full_fsync(pFile->dirfd, pFile->fullSync, 0) ){
- return SQLITE_IOERR;
+ /* The directory sync is only attempted if full_fsync is
+ ** turned off or unavailable. If a full_fsync occurred above,
+ ** then the directory sync is superfluous.
+ */
+ if( (!HAVE_FULLFSYNC || !pFile->fullSync) && full_fsync(pFile->dirfd,0,0) ){
+ /*
+ ** We have received multiple reports of fsync() returning
+ ** errors when applied to directories on certain file systems.
+ ** A failed directory sync is not a big deal. So it seems
+ ** better to ignore the error. Ticket #1657
+ */
+ /* return SQLITE_IOERR; */
}
#endif
close(pFile->dirfd); /* Only need to sync once, so close the directory */
@@ -1656,13 +1687,42 @@
}
/*
-** Static variables used for thread synchronization
+** Static variables used for thread synchronization.
+**
+** inMutex the nesting depth of the recursive mutex. The thread
+** holding mutexMain can read this variable at any time.
+** But is must hold mutexAux to change this variable. Other
+** threads must hold mutexAux to read the variable and can
+** never write.
+**
+** mutexOwner The thread id of the thread holding mutexMain. Same
+** access rules as for inMutex.
+**
+** mutexOwnerValid True if the value in mutexOwner is valid. The same
+** access rules apply as for inMutex.
+**
+** mutexMain The main mutex. Hold this mutex in order to get exclusive
+** access to SQLite data structures.
+**
+** mutexAux An auxiliary mutex needed to access variables defined above.
+**
+** Mutexes are always acquired in this order: mutexMain mutexAux. It
+** is not necessary to acquire mutexMain in order to get mutexAux - just
+** do not attempt to acquire them in the reverse order: mutexAux mutexMain.
+** Either get the mutexes with mutexMain first or get mutexAux only.
+**
+** When running on a platform where the three variables inMutex, mutexOwner,
+** and mutexOwnerValid can be set atomically, the mutexAux is not required.
+** On many systems, all three are 32-bit integers and writing to a 32-bit
+** integer is atomic. I think. But there are no guarantees. So it seems
+** safer to protect them using mutexAux.
*/
static int inMutex = 0;
#ifdef SQLITE_UNIX_THREADS
-static pthread_t mutexOwner;
-static pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
+static pthread_t mutexOwner; /* Thread holding mutexMain */
+static int mutexOwnerValid = 0; /* True if mutexOwner is valid */
+static pthread_mutex_t mutexMain = PTHREAD_MUTEX_INITIALIZER; /* The mutex */
+static pthread_mutex_t mutexAux = PTHREAD_MUTEX_INITIALIZER; /* Aux mutex */
#endif
/*
@@ -1677,25 +1737,34 @@
*/
void sqlite3UnixEnterMutex(){
#ifdef SQLITE_UNIX_THREADS
- pthread_mutex_lock(&mutex1);
- if( inMutex==0 ){
- pthread_mutex_lock(&mutex2);
+ pthread_mutex_lock(&mutexAux);
+ if( !mutexOwnerValid || !pthread_equal(mutexOwner, pthread_self()) ){
+ pthread_mutex_unlock(&mutexAux);
+ pthread_mutex_lock(&mutexMain);
+ assert( inMutex==0 );
+ assert( !mutexOwnerValid );
+ pthread_mutex_lock(&mutexAux);
mutexOwner = pthread_self();
+ mutexOwnerValid = 1;
}
- pthread_mutex_unlock(&mutex1);
-#endif
inMutex++;
+ pthread_mutex_unlock(&mutexAux);
+#else
+ inMutex++;
+#endif
}
void sqlite3UnixLeaveMutex(){
assert( inMutex>0 );
#ifdef SQLITE_UNIX_THREADS
- assert( pthread_equal(mutexOwner, pthread_self()) );
- pthread_mutex_lock(&mutex1);
+ pthread_mutex_lock(&mutexAux);
inMutex--;
+ assert( pthread_equal(mutexOwner, pthread_self()) );
if( inMutex==0 ){
- pthread_mutex_unlock(&mutex2);
+ assert( mutexOwnerValid );
+ mutexOwnerValid = 0;
+ pthread_mutex_unlock(&mutexMain);
}
- pthread_mutex_unlock(&mutex1);
+ pthread_mutex_unlock(&mutexAux);
#else
inMutex--;
#endif
@@ -1704,14 +1773,17 @@
/*
** Return TRUE if the mutex is currently held.
**
-** If the thisThreadOnly parameter is true, return true only if the
+** If the thisThrd parameter is true, return true only if the
** calling thread holds the mutex. If the parameter is false, return
** true if any thread holds the mutex.
*/
-int sqlite3UnixInMutex(int thisThreadOnly){
+int sqlite3UnixInMutex(int thisThrd){
#ifdef SQLITE_UNIX_THREADS
- return inMutex>0 &&
- (thisThreadOnly==0 || pthread_equal(mutexOwner, pthread_self()));
+ int rc;
+ pthread_mutex_lock(&mutexAux);
+ rc = inMutex>0 && (thisThrd==0 || pthread_equal(mutexOwner,pthread_self()));
+ pthread_mutex_unlock(&mutexAux);
+ return rc;
#else
return inMutex>0;
#endif
============================================================
--- sqlite/os_win.c 566bf7b41b72556fd7dca390bceaa2769dc395e9
+++ sqlite/os_win.c c67a2c46d929cf54c8f80ec5e6079cf684a141a9
@@ -1479,7 +1479,7 @@
ThreadData *sqlite3WinThreadSpecificData(int allocateFlag){
static int key;
static int keyInit = 0;
- static const ThreadData zeroData;
+ static const ThreadData zeroData = {0};
ThreadData *pTsd;
if( !keyInit ){
============================================================
--- sqlite/pager.c b5b380ea7a36f84e50c3adc1a414820a0eb3baa6
+++ sqlite/pager.c c438aa5fc248e0523e80591eeae33a3993c47278
@@ -18,7 +18,7 @@
** file simultaneously, or one process from reading the database while
** another is writing.
**
-** @(#) $Id: pager.c,v 1.257 2006/01/30 22:48:44 drh Exp $
+** @(#) $Id: pager.c,v 1.258 2006/02/11 01:25:51 drh Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
@@ -244,6 +244,7 @@
u8 stmtAutoopen; /* Open stmt journal when main journal is opened*/
u8 noSync; /* Do not sync the journal if true */
u8 fullSync; /* Do extra syncs of the journal for robustness */
+ u8 full_fsync; /* Use F_FULLFSYNC when available */
u8 state; /* PAGER_UNLOCK, _SHARED, _RESERVED, etc. */
u8 errCode; /* One of several kinds of errors */
u8 tempFile; /* zFilename is a temporary file */
@@ -1509,9 +1510,10 @@
** and FULL=3.
*/
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
-void sqlite3pager_set_safety_level(Pager *pPager, int level){
+void sqlite3pager_set_safety_level(Pager *pPager, int level, int full_fsync){
pPager->noSync = level==1 || pPager->tempFile;
pPager->fullSync = level==3 && !pPager->tempFile;
+ pPager->full_fsync = full_fsync;
if( pPager->noSync ) pPager->needSync = 0;
}
#endif
@@ -2204,7 +2206,7 @@
if( rc ) return rc;
}
TRACE2("SYNC journal of %d\n", PAGERID(pPager));
- rc = sqlite3OsSync(pPager->jfd, pPager->fullSync);
+ rc = sqlite3OsSync(pPager->jfd, pPager->full_fsync);
if( rc!=0 ) return rc;
pPager->journalStarted = 1;
}
@@ -2832,8 +2834,8 @@
if( rc!=SQLITE_OK ){
goto failed_to_open_journal;
}
- sqlite3OsSetFullSync(pPager->jfd, pPager->fullSync);
- sqlite3OsSetFullSync(pPager->fd, pPager->fullSync);
+ sqlite3OsSetFullSync(pPager->jfd, pPager->full_fsync);
+ sqlite3OsSetFullSync(pPager->fd, pPager->full_fsync);
sqlite3OsOpenDirectory(pPager->jfd, pPager->zDirectory);
pPager->journalOpen = 1;
pPager->journalStarted = 0;
============================================================
--- sqlite/pager.h e0acb095b3ad0bca48f2ab00c87346665643f64f
+++ sqlite/pager.h 425a9e52d5404158de016799715cbc2c3d685178
@@ -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.48 2005/12/19 14:18:11 danielk1977 Exp $
+** @(#) $Id: pager.h,v 1.49 2006/02/11 01:25:51 drh Exp $
*/
#ifndef _PAGER_H_
@@ -99,7 +99,7 @@
void sqlite3pager_dont_rollback(void*);
void sqlite3pager_dont_write(Pager*, Pgno);
int *sqlite3pager_stats(Pager*);
-void sqlite3pager_set_safety_level(Pager*,int);
+void sqlite3pager_set_safety_level(Pager*,int,int);
const char *sqlite3pager_filename(Pager*);
const char *sqlite3pager_dirname(Pager*);
const char *sqlite3pager_journalname(Pager*);
============================================================
--- sqlite/parse.h 20eb1ccb1fa5d4e4493dd0ca916ad74b515eefcf
+++ sqlite/parse.h ae4ee794251454f9c8b4c97ef7fee85deecdcec5
@@ -149,3 +149,18 @@
#define TK_AGG_FUNCTION 149
#define TK_AGG_COLUMN 150
#define TK_CONST_FUNC 151
+#define TK_TO_TEXT 152
+#define TK_TO_BLOB 153
+#define TK_TO_NUMERIC 154
+#define TK_TO_INT 155
+#define TK_TO_REAL 156
+#define TK_END_OF_FILE 157
+#define TK_ILLEGAL 158
+#define TK_SPACE 159
+#define TK_UNCLOSED_STRING 160
+#define TK_COMMENT 161
+#define TK_FUNCTION 162
+#define TK_COLUMN 163
+#define TK_AGG_FUNCTION 164
+#define TK_AGG_COLUMN 165
+#define TK_CONST_FUNC 166
============================================================
--- sqlite/pragma.c 4496cc77dc35824e1c978c3d1413b8a5a4c777d3
+++ sqlite/pragma.c 31d3e1b74cab2172807894e70c674d6a577501fd
@@ -11,7 +11,7 @@
*************************************************************************
** This file contains code used to implement the PRAGMA command.
**
-** $Id: pragma.c,v 1.114 2006/01/12 01:56:44 drh Exp $
+** $Id: pragma.c,v 1.118 2006/02/11 01:25:51 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -128,7 +128,7 @@
sqlite3VdbeAddOp(v, OP_Integer, value, 0);
if( pParse->explain==0 ){
sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, zLabel, P3_STATIC);
+ sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, P3_STATIC);
}
sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
}
@@ -152,6 +152,7 @@
{ "count_changes", SQLITE_CountRows },
{ "empty_result_callbacks", SQLITE_NullCallback },
{ "legacy_file_format", SQLITE_LegacyFileFmt },
+ { "fullfsync", SQLITE_FullFSync },
#ifndef SQLITE_OMIT_CHECK
{ "ignore_check_constraints", SQLITE_IgnoreChecks },
#endif
@@ -180,10 +181,6 @@
db->flags &= ~p->mask;
}
}
- /* If one of these pragmas is executed, any prepared statements
- ** need to be recompiled.
- */
- sqlite3VdbeAddOp(v, OP_Expire, 0, 0);
}
return 1;
}
@@ -274,7 +271,7 @@
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
if( !zRight ){
sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, "cache_size", P3_STATIC);
+ sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cache_size", P3_STATIC);
addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
sqlite3VdbeChangeP1(v, addr, iDb);
sqlite3VdbeChangeP1(v, addr+5, MAX_PAGES);
@@ -392,7 +389,8 @@
if( !zRight ){
if( sqlite3_temp_directory ){
sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, "temp_store_directory", P3_STATIC);
+ sqlite3VdbeSetColName(v, 0, COLNAME_NAME,
+ "temp_store_directory", P3_STATIC);
sqlite3VdbeOp3(v, OP_String8, 0, 0, sqlite3_temp_directory, 0);
sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
}
@@ -436,7 +434,6 @@
"Safety level may not be changed inside a transaction");
}else{
pDb->safety_level = getSafetyLevel(zRight)+1;
- sqlite3BtreeSetSafetyLevel(pDb->pBt, pDb->safety_level);
}
}
}else
@@ -468,22 +465,23 @@
pTab = sqlite3FindTable(db, zRight, zDb);
if( pTab ){
int i;
+ Column *pCol;
sqlite3VdbeSetNumCols(v, 6);
- sqlite3VdbeSetColName(v, 0, "cid", P3_STATIC);
- sqlite3VdbeSetColName(v, 1, "name", P3_STATIC);
- sqlite3VdbeSetColName(v, 2, "type", P3_STATIC);
- sqlite3VdbeSetColName(v, 3, "notnull", P3_STATIC);
- sqlite3VdbeSetColName(v, 4, "dflt_value", P3_STATIC);
- sqlite3VdbeSetColName(v, 5, "pk", P3_STATIC);
+ sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cid", P3_STATIC);
+ sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", P3_STATIC);
+ sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "type", P3_STATIC);
+ sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "notnull", P3_STATIC);
+ sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "dflt_value", P3_STATIC);
+ sqlite3VdbeSetColName(v, 5, COLNAME_NAME, "pk", P3_STATIC);
sqlite3ViewGetColumnNames(pParse, pTab);
- for(i=0; inCol; i++){
+ for(i=0, pCol=pTab->aCol; inCol; i++, pCol++){
sqlite3VdbeAddOp(v, OP_Integer, i, 0);
- sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->aCol[i].zName, 0);
+ sqlite3VdbeOp3(v, OP_String8, 0, 0, pCol->zName, 0);
sqlite3VdbeOp3(v, OP_String8, 0, 0,
- pTab->aCol[i].zType ? pTab->aCol[i].zType : "numeric", 0);
- sqlite3VdbeAddOp(v, OP_Integer, pTab->aCol[i].notNull, 0);
- sqlite3ExprCode(pParse, pTab->aCol[i].pDflt);
- sqlite3VdbeAddOp(v, OP_Integer, pTab->aCol[i].isPrimKey, 0);
+ pCol->zType ? pCol->zType : "numeric", 0);
+ sqlite3VdbeAddOp(v, OP_Integer, pCol->notNull, 0);
+ sqlite3ExprCode(pParse, pCol->pDflt);
+ sqlite3VdbeAddOp(v, OP_Integer, pCol->isPrimKey, 0);
sqlite3VdbeAddOp(v, OP_Callback, 6, 0);
}
}
@@ -498,9 +496,9 @@
int i;
pTab = pIdx->pTable;
sqlite3VdbeSetNumCols(v, 3);
- sqlite3VdbeSetColName(v, 0, "seqno", P3_STATIC);
- sqlite3VdbeSetColName(v, 1, "cid", P3_STATIC);
- sqlite3VdbeSetColName(v, 2, "name", P3_STATIC);
+ sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seqno", P3_STATIC);
+ sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "cid", P3_STATIC);
+ sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "name", P3_STATIC);
for(i=0; inColumn; i++){
int cnum = pIdx->aiColumn[i];
sqlite3VdbeAddOp(v, OP_Integer, i, 0);
@@ -523,9 +521,9 @@
if( pIdx ){
int i = 0;
sqlite3VdbeSetNumCols(v, 3);
- sqlite3VdbeSetColName(v, 0, "seq", P3_STATIC);
- sqlite3VdbeSetColName(v, 1, "name", P3_STATIC);
- sqlite3VdbeSetColName(v, 2, "unique", P3_STATIC);
+ sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", P3_STATIC);
+ sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", P3_STATIC);
+ sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "unique", P3_STATIC);
while(pIdx){
sqlite3VdbeAddOp(v, OP_Integer, i, 0);
sqlite3VdbeOp3(v, OP_String8, 0, 0, pIdx->zName, 0);
@@ -542,9 +540,9 @@
int i;
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
sqlite3VdbeSetNumCols(v, 3);
- sqlite3VdbeSetColName(v, 0, "seq", P3_STATIC);
- sqlite3VdbeSetColName(v, 1, "name", P3_STATIC);
- sqlite3VdbeSetColName(v, 2, "file", P3_STATIC);
+ sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", P3_STATIC);
+ sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", P3_STATIC);
+ sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "file", P3_STATIC);
for(i=0; inDb; i++){
if( db->aDb[i].pBt==0 ) continue;
assert( db->aDb[i].zName!=0 );
@@ -560,8 +558,8 @@
int i = 0;
HashElem *p;
sqlite3VdbeSetNumCols(v, 2);
- sqlite3VdbeSetColName(v, 0, "seq", P3_STATIC);
- sqlite3VdbeSetColName(v, 1, "name", P3_STATIC);
+ sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", P3_STATIC);
+ sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", P3_STATIC);
for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){
CollSeq *pColl = (CollSeq *)sqliteHashData(p);
sqlite3VdbeAddOp(v, OP_Integer, i++, 0);
@@ -583,11 +581,11 @@
if( pFK ){
int i = 0;
sqlite3VdbeSetNumCols(v, 5);
- sqlite3VdbeSetColName(v, 0, "id", P3_STATIC);
- sqlite3VdbeSetColName(v, 1, "seq", P3_STATIC);
- sqlite3VdbeSetColName(v, 2, "table", P3_STATIC);
- sqlite3VdbeSetColName(v, 3, "from", P3_STATIC);
- sqlite3VdbeSetColName(v, 4, "to", P3_STATIC);
+ sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "id", P3_STATIC);
+ sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "seq", P3_STATIC);
+ sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "table", P3_STATIC);
+ sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "from", P3_STATIC);
+ sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "to", P3_STATIC);
while(pFK){
int j;
for(j=0; jnCol; j++){
@@ -649,7 +647,7 @@
/* Initialize the VDBE program */
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, "integrity_check", P3_STATIC);
+ sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "integrity_check", P3_STATIC);
sqlite3VdbeAddOp(v, OP_MemInt, 0, 0); /* Initialize error count to 0 */
/* Do an integrity check on each database file */
@@ -794,7 +792,7 @@
if( !zRight ){ /* "PRAGMA encoding" */
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, "encoding", P3_STATIC);
+ sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "encoding", P3_STATIC);
sqlite3VdbeAddOp(v, OP_String8, 0, 0);
for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
if( pEnc->enc==ENC(pParse->db) ){
@@ -900,8 +898,8 @@
int i;
Vdbe *v = sqlite3GetVdbe(pParse);
sqlite3VdbeSetNumCols(v, 2);
- sqlite3VdbeSetColName(v, 0, "database", P3_STATIC);
- sqlite3VdbeSetColName(v, 1, "status", P3_STATIC);
+ sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "database", P3_STATIC);
+ sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "status", P3_STATIC);
for(i=0; inDb; i++){
Btree *pBt;
Pager *pPager;
@@ -945,6 +943,15 @@
** are only valid for a single execution.
*/
sqlite3VdbeAddOp(v, OP_Expire, 1, 0);
+
+ /*
+ ** Reset the safety level, in case the fullfsync flag or synchronous
+ ** setting changed.
+ */
+ if( db->autoCommit ){
+ sqlite3BtreeSetSafetyLevel(pDb->pBt, pDb->safety_level,
+ (db->flags&SQLITE_FullFSync)!=0);
+ }
}
pragma_out:
sqliteFree(zLeft);
============================================================
--- sqlite/prepare.c 40ae23c8aeb641dc7b9bb271eb5e295b815154a7
+++ sqlite/prepare.c cf0fc8ebaf94409955ecb09ffeb0099c9ef44693
@@ -13,7 +13,7 @@
** interface, and routines that contribute to loading the database schema
** from disk.
**
-** $Id: prepare.c,v 1.30 2006/01/30 22:35:44 drh Exp $
+** $Id: prepare.c,v 1.31 2006/02/10 02:27:43 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -556,16 +556,16 @@
if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){
if( sParse.explain==2 ){
sqlite3VdbeSetNumCols(sParse.pVdbe, 3);
- sqlite3VdbeSetColName(sParse.pVdbe, 0, "order", P3_STATIC);
- sqlite3VdbeSetColName(sParse.pVdbe, 1, "from", P3_STATIC);
- sqlite3VdbeSetColName(sParse.pVdbe, 2, "detail", P3_STATIC);
+ sqlite3VdbeSetColName(sParse.pVdbe, 0, COLNAME_NAME, "order", P3_STATIC);
+ sqlite3VdbeSetColName(sParse.pVdbe, 1, COLNAME_NAME, "from", P3_STATIC);
+ sqlite3VdbeSetColName(sParse.pVdbe, 2, COLNAME_NAME, "detail", P3_STATIC);
}else{
sqlite3VdbeSetNumCols(sParse.pVdbe, 5);
- sqlite3VdbeSetColName(sParse.pVdbe, 0, "addr", P3_STATIC);
- sqlite3VdbeSetColName(sParse.pVdbe, 1, "opcode", P3_STATIC);
- sqlite3VdbeSetColName(sParse.pVdbe, 2, "p1", P3_STATIC);
- sqlite3VdbeSetColName(sParse.pVdbe, 3, "p2", P3_STATIC);
- sqlite3VdbeSetColName(sParse.pVdbe, 4, "p3", P3_STATIC);
+ sqlite3VdbeSetColName(sParse.pVdbe, 0, COLNAME_NAME, "addr", P3_STATIC);
+ sqlite3VdbeSetColName(sParse.pVdbe, 1, COLNAME_NAME, "opcode", P3_STATIC);
+ sqlite3VdbeSetColName(sParse.pVdbe, 2, COLNAME_NAME, "p1", P3_STATIC);
+ sqlite3VdbeSetColName(sParse.pVdbe, 3, COLNAME_NAME, "p2", P3_STATIC);
+ sqlite3VdbeSetColName(sParse.pVdbe, 4, COLNAME_NAME, "p3", P3_STATIC);
}
}
#endif
============================================================
--- sqlite/select.c daee9b20702ba51cf3807fc1b130edd8846e3e48
+++ sqlite/select.c 7d069e875d0eec05129c7e8b9c99422d7c9c6321
@@ -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.301 2006/01/24 12:09:19 danielk1977 Exp $
+** $Id: select.c,v 1.304 2006/02/10 07:07:16 danielk1977 Exp $
*/
#include "sqliteInt.h"
@@ -762,14 +762,31 @@
** Return a pointer to a string containing the 'declaration type' of the
** expression pExpr. The string may be treated as static by the caller.
**
-** If the declaration type is the exact datatype definition extracted from
-** the original CREATE TABLE statement if the expression is a column.
+** The declaration type is the exact datatype definition extracted from the
+** original CREATE TABLE statement if the expression is a column. The
+** declaration type for a ROWID field is INTEGER. Exactly when an expression
+** is considered a column can be complex in the presence of subqueries. The
+** result-set expression in all of the following SELECT statements is
+** considered a column by this function.
+**
+** SELECT col FROM tbl;
+** SELECT (SELECT col FROM tbl;
+** SELECT (SELECT col FROM tbl);
+** SELECT abc FROM (SELECT col AS abc FROM tbl);
**
-** The declaration type for an expression is either TEXT, NUMERIC or ANY.
-** The declaration type for a ROWID field is INTEGER.
+** The declaration type for any expression other than a column is NULL.
*/
-static const char *columnType(NameContext *pNC, Expr *pExpr){
- char const *zType;
+static const char *columnType(
+ NameContext *pNC,
+ Expr *pExpr,
+ const char **pzOriginDb,
+ const char **pzOriginTab,
+ const char **pzOriginCol
+){
+ char const *zType = 0;
+ char const *zOriginDb = 0;
+ char const *zOriginTab = 0;
+ char const *zOriginCol = 0;
int j;
if( pExpr==0 || pNC->pSrcList==0 ) return 0;
@@ -781,17 +798,24 @@
switch( pExpr->op ){
case TK_COLUMN: {
- Table *pTab = 0;
- int iCol = pExpr->iColumn;
+ /* The expression is a column. Locate the table the column is being
+ ** extracted from in NameContext.pSrcList. This table may be real
+ ** database table or a subquery.
+ */
+ Table *pTab = 0; /* Table structure column is extracted from */
+ Select *pS = 0; /* Select the column is extracted from */
+ int iCol = pExpr->iColumn; /* Index of column in pTab */
while( pNC && !pTab ){
SrcList *pTabList = pNC->pSrcList;
for(j=0;jnSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++);
if( jnSrc ){
pTab = pTabList->a[j].pTab;
+ pS = pTabList->a[j].pSelect;
}else{
pNC = pNC->pNext;
}
}
+
if( pTab==0 ){
/* FIX ME:
** This can occurs if you have something like "SELECT new.x;" inside
@@ -806,30 +830,72 @@
zType = "TEXT";
break;
}
+
assert( pTab );
- if( iCol<0 ) iCol = pTab->iPKey;
- assert( iCol==-1 || (iCol>=0 && iColnCol) );
- if( iCol<0 ){
- zType = "INTEGER";
- }else{
- zType = pTab->aCol[iCol].zType;
+#ifndef SQLITE_OMIT_SUBQUERY
+ if( pS ){
+ /* The "table" is actually a sub-select or a view in the FROM clause
+ ** of the SELECT statement. Return the declaration type and origin
+ ** data for the result-set column of the sub-select.
+ */
+ if( iCol>=0 && iColpEList->nExpr ){
+ /* If iCol is less than zero, then the expression requests the
+ ** rowid of the sub-select or view. This expression is legal (see
+ ** test case misc2.2.2) - it always evaluates to NULL.
+ */
+ NameContext sNC;
+ Expr *p = pS->pEList->a[iCol].pExpr;
+ sNC.pSrcList = pS->pSrc;
+ sNC.pNext = 0;
+ sNC.pParse = pNC->pParse;
+ zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol);
+ }
+ }else
+#endif
+ if( pTab->pSchema ){
+ /* A real table */
+ assert( !pS );
+ if( iCol<0 ) iCol = pTab->iPKey;
+ assert( iCol==-1 || (iCol>=0 && iColnCol) );
+ if( iCol<0 ){
+ zType = "INTEGER";
+ zOriginCol = "rowid";
+ }else{
+ zType = pTab->aCol[iCol].zType;
+ zOriginCol = pTab->aCol[iCol].zName;
+ }
+ zOriginTab = pTab->zName;
+ if( pNC->pParse ){
+ int iDb = sqlite3SchemaToIndex(pNC->pParse->db, pTab->pSchema);
+ zOriginDb = pNC->pParse->db->aDb[iDb].zName;
+ }
}
break;
}
#ifndef SQLITE_OMIT_SUBQUERY
case TK_SELECT: {
+ /* The expression is a sub-select. Return the declaration type and
+ ** origin info for the single column in the result set of the SELECT
+ ** statement.
+ */
NameContext sNC;
Select *pS = pExpr->pSelect;
- sNC.pSrcList = pExpr->pSelect->pSrc;
+ Expr *p = pS->pEList->a[0].pExpr;
+ sNC.pSrcList = pS->pSrc;
sNC.pNext = pNC;
- zType = columnType(&sNC, pS->pEList->a[0].pExpr);
+ sNC.pParse = pNC->pParse;
+ zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol);
break;
}
#endif
- default:
- zType = 0;
}
+ if( pzOriginDb ){
+ assert( pzOriginTab && pzOriginCol );
+ *pzOriginDb = zOriginDb;
+ *pzOriginTab = zOriginTab;
+ *pzOriginCol = zOriginCol;
+ }
return zType;
}
@@ -846,14 +912,22 @@
int i;
NameContext sNC;
sNC.pSrcList = pTabList;
+ sNC.pParse = pParse;
for(i=0; inExpr; i++){
Expr *p = pEList->a[i].pExpr;
- const char *zType = columnType(&sNC, p);
- if( zType==0 ) continue;
- /* The vdbe must make it's own copy of the column-type, in case the
- ** schema is reset before this virtual machine is deleted.
+ const char *zOrigDb = 0;
+ const char *zOrigTab = 0;
+ const char *zOrigCol = 0;
+ const char *zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol);
+
+ /* The vdbe must make it's own copy of the column-type and other
+ ** column specific strings, in case the schema is reset before this
+ ** virtual machine is deleted.
*/
- sqlite3VdbeSetColName(v, i+pEList->nExpr, zType, strlen(zType));
+ sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, P3_TRANSIENT);
+ sqlite3VdbeSetColName(v, i, COLNAME_DATABASE, zOrigDb, P3_TRANSIENT);
+ sqlite3VdbeSetColName(v, i, COLNAME_TABLE, zOrigTab, P3_TRANSIENT);
+ sqlite3VdbeSetColName(v, i, COLNAME_COLUMN, zOrigCol, P3_TRANSIENT);
}
}
@@ -891,7 +965,7 @@
if( p==0 ) continue;
if( pEList->a[i].zName ){
char *zName = pEList->a[i].zName;
- sqlite3VdbeSetColName(v, i, zName, strlen(zName));
+ sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, strlen(zName));
continue;
}
if( p->op==TK_COLUMN && pTabList ){
@@ -909,7 +983,7 @@
zCol = pTab->aCol[iCol].zName;
}
if( !shortNames && !fullNames && p->span.z && p->span.z[0] ){
- sqlite3VdbeSetColName(v, i, (char*)p->span.z, p->span.n);
+ sqlite3VdbeSetColName(v, i, COLNAME_NAME, (char*)p->span.z, p->span.n);
}else if( fullNames || (!shortNames && pTabList->nSrc>1) ){
char *zName = 0;
char *zTab;
@@ -917,18 +991,18 @@
zTab = pTabList->a[j].zAlias;
if( fullNames || zTab==0 ) zTab = pTab->zName;
sqlite3SetString(&zName, zTab, ".", zCol, (char*)0);
- sqlite3VdbeSetColName(v, i, zName, P3_DYNAMIC);
+ sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, P3_DYNAMIC);
}else{
- sqlite3VdbeSetColName(v, i, zCol, strlen(zCol));
+ sqlite3VdbeSetColName(v, i, COLNAME_NAME, zCol, strlen(zCol));
}
}else if( p->span.z && p->span.z[0] ){
- sqlite3VdbeSetColName(v, i, (char*)p->span.z, p->span.n);
+ sqlite3VdbeSetColName(v, i, COLNAME_NAME, (char*)p->span.z, p->span.n);
/* sqlite3VdbeCompressSpace(v, addr); */
}else{
char zName[30];
assert( p->op!=TK_COLUMN || pTabList==0 );
sprintf(zName, "column%d", i+1);
- sqlite3VdbeSetColName(v, i, zName, 0);
+ sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, 0);
}
}
generateColumnTypes(pParse, pTabList, pEList);
@@ -1036,7 +1110,7 @@
*/
memset(&sNC, 0, sizeof(sNC));
sNC.pSrcList = pSelect->pSrc;
- zType = sqliteStrDup(columnType(&sNC, p));
+ zType = sqliteStrDup(columnType(&sNC, p, 0, 0, 0));
pCol->zType = zType;
pCol->affinity = sqlite3ExprAffinity(p);
pColl = sqlite3ExprCollSeq(pParse, p);
@@ -2783,13 +2857,6 @@
v = sqlite3GetVdbe(pParse);
if( v==0 ) goto select_end;
- /* Identify column names if we will be using them in a callback. This
- ** step is skipped if the output is going to some other destination.
- */
- if( eDest==SRT_Callback ){
- generateColumnNames(pParse, pTabList, pEList);
- }
-
/* Generate code for all sub-queries in the FROM clause
*/
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
@@ -2798,7 +2865,7 @@
int needRestoreContext;
struct SrcList_item *pItem = &pTabList->a[i];
- if( pItem->pSelect==0 ) continue;
+ if( pItem->pSelect==0 || pItem->isPopulated ) continue;
if( pItem->zName!=0 ){
zSavedAuthContext = pParse->zAuthContext;
pParse->zAuthContext = pItem->zName;
@@ -3192,15 +3259,14 @@
#ifndef SQLITE_OMIT_SUBQUERY
/* If this was a subquery, we have now converted the subquery into a
- ** temporary table. So delete the subquery structure from the parent
- ** to prevent this subquery from being evaluated again and to force the
- ** the use of the temporary table.
+ ** temporary table. So set the SrcList_item.isPopulated flag to prevent
+ ** this subquery from being evaluated again and to force the use of
+ ** the temporary table.
*/
if( pParent ){
assert( pParent->pSrc->nSrc>parentTab );
assert( pParent->pSrc->a[parentTab].pSelect==p );
- sqlite3SelectDelete(p);
- pParent->pSrc->a[parentTab].pSelect = 0;
+ pParent->pSrc->a[parentTab].isPopulated = 1;
}
#endif
@@ -3217,6 +3283,14 @@
** successful coding of the SELECT.
*/
select_end:
+
+ /* Identify column names if we will be using them in a callback. This
+ ** step is skipped if the output is going to some other destination.
+ */
+ if( rc==SQLITE_OK && eDest==SRT_Callback ){
+ generateColumnNames(pParse, pTabList, pEList);
+ }
+
sqliteFree(sAggInfo.aCol);
sqliteFree(sAggInfo.aFunc);
return rc;
============================================================
--- sqlite/sqlite3.h 6b9ed927e0a9a3c6051a372929c97c2ac87ab314
+++ sqlite/sqlite3.h d0605a62334179d9c38bf587ac38b777d6daee2b
@@ -12,7 +12,7 @@
** This header file defines the interface that the SQLite library
** presents to client programs.
**
-** @(#) $Id: sqlite.h.in,v 1.156 2006/01/12 02:50:10 drh Exp $
+** @(#) $Id: sqlite.h.in,v 1.162 2006/02/10 03:06:10 danielk1977 Exp $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
@@ -31,7 +31,7 @@
#ifdef SQLITE_VERSION
# undef SQLITE_VERSION
#endif
-#define SQLITE_VERSION "3.3.3"
+#define SQLITE_VERSION "3.3.4"
/*
** The format of the version string is "X.Y.Z", where
@@ -48,7 +48,7 @@
#ifdef SQLITE_VERSION_NUMBER
# undef SQLITE_VERSION_NUMBER
#endif
-#define SQLITE_VERSION_NUMBER 3003003
+#define SQLITE_VERSION_NUMBER 3003004
/*
** The version string is also compiled into the library so that a program
@@ -164,6 +164,7 @@
** Return values for sqlite3_exec() and sqlite3_step()
*/
#define SQLITE_OK 0 /* Successful result */
+/* beginning-of-error-codes */
#define SQLITE_ERROR 1 /* SQL error or missing database */
#define SQLITE_INTERNAL 2 /* NOT USED. Internal logic error in SQLite */
#define SQLITE_PERM 3 /* Access permission denied */
@@ -192,7 +193,7 @@
#define SQLITE_NOTADB 26 /* File opened that is not a database file */
#define SQLITE_ROW 100 /* sqlite3_step() has another row ready */
#define SQLITE_DONE 101 /* sqlite3_step() has finished executing */
-/* end-of-return-codes */
+/* end-of-error-codes */
/*
** Each entry in an SQLite table has a unique integer key. (The key is
@@ -725,6 +726,30 @@
const void *sqlite3_column_name16(sqlite3_stmt*,int);
/*
+** The first parameter to the following calls is a compiled SQL statement.
+** These functions return information about the Nth column returned by
+** the statement, where N is the second function argument.
+**
+** If the Nth column returned by the statement is not a column value,
+** then all of the functions return NULL. Otherwise, the return the
+** name of the attached database, table and column that the expression
+** extracts a value from.
+**
+** As with all other SQLite APIs, those postfixed with "16" return UTF-16
+** encoded strings, the other functions return UTF-8. The memory containing
+** the returned strings is valid until the statement handle is finalized().
+**
+** These APIs are only available if the library was compiled with the
+** SQLITE_ENABLE_COLUMN_METADATA preprocessor symbol defined.
+*/
+const char *sqlite3_column_database_name(sqlite3_stmt*,int);
+const void *sqlite3_column_database_name16(sqlite3_stmt*,int);
+const char *sqlite3_column_table_name(sqlite3_stmt*,int);
+const void *sqlite3_column_table_name16(sqlite3_stmt*,int);
+const char *sqlite3_column_origin_name(sqlite3_stmt*,int);
+const void *sqlite3_column_origin_name16(sqlite3_stmt*,int);
+
+/*
** The first parameter is a compiled SQL statement. If this statement
** is a SELECT statement, the Nth column of the returned result set
** of the SELECT is a table column then the declared type of the table
@@ -736,7 +761,7 @@
**
** And the following statement compiled:
**
-** SELECT c1 + 1, 0 FROM t1;
+** SELECT c1 + 1, c1 FROM t1;
**
** Then this routine would return the string "VARIANT" for the second
** result column (i==1), and a NULL pointer for the first result column
@@ -756,7 +781,7 @@
**
** And the following statement compiled:
**
-** SELECT c1 + 1, 0 FROM t1;
+** SELECT c1 + 1, c1 FROM t1;
**
** Then this routine would return the string "INTEGER" for the second
** result column (i==1), and a NULL pointer for the first result column
@@ -897,6 +922,7 @@
const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);
int sqlite3_column_type(sqlite3_stmt*, int iCol);
+int sqlite3_column_numeric_type(sqlite3_stmt*, int iCol);
/*
** The sqlite3_finalize() function is called to delete a compiled
@@ -980,9 +1006,8 @@
);
/*
-** The next routine returns the number of calls to xStep for a particular
-** aggregate function instance. The current call to xStep counts so this
-** routine always returns at least 1.
+** This function is deprecated. Do not use it. It continues to exist
+** so as not to break legacy code. But new code should avoid using it.
*/
int sqlite3_aggregate_count(sqlite3_context*);
@@ -1005,6 +1030,7 @@
const void *sqlite3_value_text16le(sqlite3_value*);
const void *sqlite3_value_text16be(sqlite3_value*);
int sqlite3_value_type(sqlite3_value*);
+int sqlite3_value_numeric_type(sqlite3_value*);
/*
** Aggregate functions use the following routine to allocate
@@ -1370,6 +1396,75 @@
void sqlite3_thread_cleanup(void);
/*
+** Return meta information about a specific column of a specific database
+** table accessible using the connection handle passed as the first function
+** argument.
+**
+** The column is identified by the second, third and fourth parameters to
+** this function. The second parameter is either the name of the database
+** (i.e. "main", "temp" or an attached database) containing the specified
+** table or NULL. If it is NULL, then all attached databases are searched
+** for the table using the same algorithm as the database engine uses to
+** resolve unqualified table references.
+**
+** The third and fourth parameters to this function are the table and column
+** name of the desired column, respectively. Neither of these parameters
+** may be NULL.
+**
+** Meta information is returned by writing to the memory locations passed as
+** the 5th and subsequent parameters to this function. Any of these
+** arguments may be NULL, in which case the corresponding element of meta
+** information is ommitted.
+**
+** Parameter Output Type Description
+** -----------------------------------
+**
+** 5th const char* Data type
+** 6th const char* Name of the default collation sequence
+** 7th int True if the column has a NOT NULL constraint
+** 8th int True if the column is part of the PRIMARY KEY
+** 9th int True if the column is AUTOINCREMENT
+**
+**
+** The memory pointed to by the character pointers returned for the
+** declaration type and collation sequence is valid only until the next
+** call to any sqlite API function.
+**
+** If the specified table is actually a view, then an error is returned.
+**
+** If the specified column is "rowid", "oid" or "_rowid_" and an
+** INTEGER PRIMARY KEY column has been explicitly declared, then the output
+** parameters are set for the explicitly declared column. If there is no
+** explicitly declared IPK column, then the output parameters are set as
+** follows:
+**
+** data type: "INTEGER"
+** collation sequence: "BINARY"
+** not null: 0
+** primary key: 1
+** auto increment: 0
+**
+** This function may load one or more schemas from database files. If an
+** error occurs during this process, or if the requested table or column
+** cannot be found, an SQLITE error code is returned and an error message
+** left in the database handle (to be retrieved using sqlite3_errmsg()).
+**
+** This API is only available if the library was compiled with the
+** SQLITE_ENABLE_COLUMN_METADATA preprocessor symbol defined.
+*/
+int sqlite3_table_column_metadata(
+ sqlite3 *db, /* Connection handle */
+ const char *zDbName, /* Database name or NULL */
+ const char *zTableName, /* Table name */
+ const char *zColumnName, /* Column name */
+ char const **pzDataType, /* OUTPUT: Declared data type */
+ char const **pzCollSeq, /* OUTPUT: Collation sequence name */
+ int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */
+ int *pPrimaryKey, /* OUTPUT: True if column part of PK */
+ int *pAutoinc /* OUTPUT: True if colums is auto-increment */
+);
+
+/*
** Undo the hack that converts floating point types to integer for
** builds on processors without floating point support.
*/
============================================================
--- sqlite/sqliteInt.h 0121298397ac14eb468ab1ba9d488ac7ed7d88a1
+++ sqlite/sqliteInt.h f61b60f243f1709c943c62cfb6d7a50209080e38
@@ -11,7 +11,7 @@
*************************************************************************
** Internal interface definitions for SQLite.
**
-** @(#) $Id: sqliteInt.h,v 1.479 2006/01/24 16:37:58 danielk1977 Exp $
+** @(#) $Id: sqliteInt.h,v 1.481 2006/02/11 01:25:51 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
@@ -544,6 +544,7 @@
#define SQLITE_IgnoreChecks 0x00002000 /* Do not enforce check constraints */
#define SQLITE_ReadUncommitted 0x00004000 /* For shared-cache mode */
#define SQLITE_LegacyFileFmt 0x00008000 /* Create new databases in format 1 */
+#define SQLITE_FullFSync 0x00010000 /* Use full fsync on the backend */
/*
** Possible values for the sqlite.magic field.
@@ -1069,6 +1070,7 @@
char *zAlias; /* The "B" part of a "A AS B" phrase. zName is the "A" */
Table *pTab; /* An SQL table corresponding to zName */
Select *pSelect; /* A SELECT statement used in place of a table name */
+ u8 isPopulated; /* Temporary table associated with SELECT is populated */
u8 jointype; /* Type of join between this table and the next */
i16 iCursor; /* The VDBE cursor number used to access this table */
Expr *pOn; /* The ON clause of a join */
============================================================
--- sqlite/table.c 486dcfce532685b53b5a2b5da8bba0ded6fb2316
+++ sqlite/table.c f64ec4fbfe333f8df925bc6ba494f55e05b0e75e
@@ -145,6 +145,7 @@
res.azResult[0] = 0;
rc = sqlite3_exec(db, zSql, sqlite3_get_table_cb, &res, pzErrMsg);
if( res.azResult ){
+ assert( sizeof(res.azResult[0])>= sizeof(res.nData) );
res.azResult[0] = (char*)res.nData;
}
if( rc==SQLITE_ABORT ){
============================================================
--- sqlite/tokenize.c 9ae9a59238eb97fbc61baea280563b91100518fb
+++ sqlite/tokenize.c 382b3bb0ca26eb9153b5d20b246ef512a114a24f
@@ -15,7 +15,7 @@
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
**
-** $Id: tokenize.c,v 1.116 2006/01/20 17:56:33 drh Exp $
+** $Id: tokenize.c,v 1.117 2006/02/09 22:24:41 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -261,6 +261,7 @@
#ifndef SQLITE_OMIT_TCL_VARIABLE
case '$':
#endif
+ case '@': /* For compatibility with MS SQL Server */
case ':': {
int n = 0;
*tokenType = TK_VARIABLE;
============================================================
--- sqlite/update.c 14be4ba2f438919b4217085c02feff569e6cf1f2
+++ sqlite/update.c 050a7e0ddaac03dec5271712eee62f1a9e699049
@@ -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.121 2006/01/18 16:51:36 danielk1977 Exp $
+** $Id: update.c,v 1.122 2006/02/10 02:27:43 danielk1977 Exp $
*/
#include "sqliteInt.h"
@@ -494,7 +494,7 @@
if( db->flags & SQLITE_CountRows && !pParse->trigStack && pParse->nested==0 ){
sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, "rows updated", P3_STATIC);
+ sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", P3_STATIC);
}
update_cleanup:
============================================================
--- sqlite/util.c 82ee598519b8193184bdeab06b51a4ffa05ad60b
+++ sqlite/util.c 405f46fef062b476826d2c171ec21def29563b75
@@ -14,7 +14,7 @@
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
-** $Id: util.c,v 1.182 2006/01/23 15:39:59 drh Exp $
+** $Id: util.c,v 1.184 2006/02/06 21:22:31 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -521,34 +521,56 @@
**--------------------------------------------------------------------------*/
/*
-** The handleSoftLimit() function is called before each call to
-** sqlite3OsMalloc() or xRealloc(). The parameter 'n' is the number of
-** extra bytes about to be allocated (for Realloc() this means the size of the
-** new allocation less the size of the old allocation). If the extra allocation
-** means that the total memory allocated to SQLite in this thread would exceed
-** the limit set by sqlite3_soft_heap_limit(), then sqlite3_release_memory() is
-** called to try to avoid this. No indication of whether or not this is
-** successful is returned to the caller.
+** This routine is called when we are about to allocate n additional bytes
+** of memory. If the new allocation will put is over the soft allocation
+** limit, then invoke sqlite3_release_memory() to try to release some
+** memory before continuing with the allocation.
**
+** This routine also makes sure that the thread-specific-data (TSD) has
+** be allocated. If it has not and can not be allocated, then return
+** false. The updateMemoryUsedCount() routine below will deallocate
+** the TSD if it ought to be.
+**
** If SQLITE_ENABLE_MEMORY_MANAGEMENT is not defined, this routine is
** a no-op
+*/
+#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
+static int enforceSoftLimit(int n){
+ ThreadData *pTsd = sqlite3ThreadData();
+ if( pTsd==0 ){
+ return 0;
+ }
+ assert( pTsd->nAlloc>=0 );
+ if( n>0 && pTsd->nSoftHeapLimit>0 ){
+ while( pTsd->nAlloc+n>pTsd->nSoftHeapLimit && sqlite3_release_memory(n) );
+ }
+ return 1;
+}
+#else
+# define enforceSoftLimit(X) 1
+#endif
+
+/*
+** Update the count of total outstanding memory that is held in
+** thread-specific-data (TSD). If after this update the TSD is
+** no longer being used, then deallocate it.
+**
+** If SQLITE_ENABLE_MEMORY_MANAGEMENT is not defined, this routine is
+** a no-op
*/
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
-static int handleSoftLimit(int n){
+static void updateMemoryUsedCount(int n){
ThreadData *pTsd = sqlite3ThreadData();
if( pTsd ){
pTsd->nAlloc += n;
assert( pTsd->nAlloc>=0 );
- if( n>0 && pTsd->nSoftHeapLimit>0 ){
- while( pTsd->nAlloc>pTsd->nSoftHeapLimit && sqlite3_release_memory(n) );
- }else if( pTsd->nAlloc==0 && pTsd->nSoftHeapLimit==0 ){
+ if( pTsd->nAlloc==0 && pTsd->nSoftHeapLimit==0 ){
sqlite3ReleaseThreadData();
}
}
- return (pTsd ? 0 : 1);
}
#else
-#define handleSoftLimit(x) 0
+#define updateMemoryUsedCount(x) /* no-op */
#endif
/*
@@ -558,17 +580,13 @@
*/
void *sqlite3MallocRaw(int n){
void *p = 0;
- if( n>0 && !sqlite3MallocFailed() && !handleSoftLimit(n) ){
+ if( n>0 && !sqlite3MallocFailed() && enforceSoftLimit(n) ){
while( (p = OSMALLOC(n))==0 && sqlite3_release_memory(n) );
if( !p ){
- /* If the allocation failed, call handleSoftLimit() again, this time
- ** with the additive inverse of the argument passed to
- ** handleSoftLimit() above. This is so the ThreadData.nAlloc variable is
- ** still correct after a malloc() failure.
- */
- (void)handleSoftLimit(n * -1);
sqlite3FailedMalloc();
OSMALLOC_FAILED();
+ }else{
+ updateMemoryUsedCount(OSSIZEOF(p));
}
}
return p;
@@ -588,17 +606,16 @@
return sqlite3Malloc(n);
}else{
void *np = 0;
- if( !handleSoftLimit(n - OSSIZEOF(p)) ){
+#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
+ int origSize = OSSIZEOF(p);
+#endif
+ if( enforceSoftLimit(n - origSize) ){
while( (np = OSREALLOC(p, n))==0 && sqlite3_release_memory(n) );
if( !np ){
- /* If the allocation failed, call handleSoftLimit() again, this time
- ** with the additive inverse of the argument passed to
- ** handleSoftLimit() above. This is so the ThreadData.nAlloc variable is
- ** still correct after a malloc() failure.
- */
- (void)handleSoftLimit(OSSIZEOF(p) - n);
sqlite3FailedMalloc();
OSMALLOC_FAILED();
+ }else{
+ updateMemoryUsedCount(OSSIZEOF(np) - origSize);
}
}
return np;
@@ -610,8 +627,8 @@
** value returned by a previous call to sqlite3Malloc() or sqlite3Realloc().
*/
void sqlite3FreeX(void *p){
- (void)handleSoftLimit(0 - OSSIZEOF(p));
if( p ){
+ updateMemoryUsedCount(0 - OSSIZEOF(p));
OSFREE(p);
}
}
============================================================
--- sqlite/vdbe.c fee677e05236e483d6c75d1d4229955fc1b89193
+++ sqlite/vdbe.c 0a7fd81609429bae2b3c326687b02a60a9c01c49
@@ -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.540 2006/01/30 15:34:23 drh Exp $
+** $Id: vdbe.c,v 1.543 2006/02/10 14:02:07 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -190,6 +190,31 @@
}
/*
+** Try to convert a value into a numeric representation if we can
+** do so without loss of information. In other words, if the string
+** looks like a number, convert it into a number. If it does not
+** look like a number, leave it alone.
+*/
+static void applyNumericAffinity(Mem *pRec){
+ if( (pRec->flags & (MEM_Real|MEM_Int))==0 ){
+ int realnum;
+ sqlite3VdbeMemNulTerminate(pRec);
+ if( (pRec->flags&MEM_Str)
+ && sqlite3IsNumber(pRec->z, &realnum, pRec->enc) ){
+ i64 value;
+ sqlite3VdbeChangeEncoding(pRec, SQLITE_UTF8);
+ if( !realnum && sqlite3atoi64(pRec->z, &value) ){
+ sqlite3VdbeMemRelease(pRec);
+ pRec->i = value;
+ pRec->flags = MEM_Int;
+ }else{
+ sqlite3VdbeMemRealify(pRec);
+ }
+ }
+ }
+}
+
+/*
** Processing is determine by the affinity parameter:
**
** SQLITE_AFF_INTEGER:
@@ -220,32 +245,29 @@
}else if( affinity!=SQLITE_AFF_NONE ){
assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL
|| affinity==SQLITE_AFF_NUMERIC );
- if( 0==(pRec->flags&(MEM_Real|MEM_Int)) ){
- /* pRec does not have a valid integer or real representation.
- ** Attempt a conversion if pRec has a string representation and
- ** it looks like a number.
- */
- int realnum;
- sqlite3VdbeMemNulTerminate(pRec);
- if( (pRec->flags&MEM_Str)
- && sqlite3IsNumber(pRec->z, &realnum, pRec->enc) ){
- i64 value;
- sqlite3VdbeChangeEncoding(pRec, SQLITE_UTF8);
- if( !realnum && sqlite3atoi64(pRec->z, &value) ){
- sqlite3VdbeMemRelease(pRec);
- pRec->i = value;
- pRec->flags = MEM_Int;
- }else{
- sqlite3VdbeMemNumerify(pRec);
- }
- }
- }else if( pRec->flags & MEM_Real ){
+ applyNumericAffinity(pRec);
+ if( pRec->flags & MEM_Real ){
sqlite3VdbeIntegerAffinity(pRec);
}
}
}
/*
+** Try to convert the type of a function argument or a result column
+** into a numeric representation. Use either INTEGER or REAL whichever
+** is appropriate. But only do the conversion if it is possible without
+** loss of information and return the revised type of the argument.
+**
+** This is an EXPERIMENTAL api and is subject to change or removal.
+*/
+int sqlite3_value_numeric_type(sqlite3_value *pVal){
+ Mem *pMem = (Mem*)pVal;
+ applyNumericAffinity(pMem);
+ storeTypeInfo(pMem, 0);
+ return pMem->type;
+}
+
+/*
** Exported version of applyAffinity(). This one works on sqlite3_value*,
** not the internal Mem* type.
*/
@@ -1965,6 +1987,7 @@
u8 *zIdx; /* Index into header */
u8 *zEndHdr; /* Pointer to first byte after the header */
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;
@@ -1997,7 +2020,8 @@
pC->aRow = 0;
}
}
- zIdx = (u8 *)GetVarint((u8*)zData, offset);
+ assert( zRec!=0 || avail>=payloadSize || avail>=9 );
+ szHdrSz = GetVarint((u8*)zData, offset);
/* The KeyFetch() or DataFetch() above are fast and will get the entire
** record header in most cases. But they will fail to get the complete
@@ -2012,8 +2036,8 @@
}
zData = sMem.z;
}
- zEndHdr = (u8 *)zData + offset;
- zIdx = (u8 *)zData + (int)zIdx;
+ zEndHdr = (u8 *)&zData[offset];
+ zIdx = (u8 *)&zData[szHdrSz];
/* Scan the header and use it to fill in the aType[] and aOffset[]
** arrays. aType[i] will contain the type integer for the i-th
@@ -3815,7 +3839,7 @@
assert( p->apCsr[i]!=0 );
assert( pTos>=p->aStack );
if( (pC = p->apCsr[i])->pCursor!=0 ){
- int res, rc;
+ int res;
assert( pTos->flags & MEM_Blob ); /* Created using OP_Make*Key */
Stringify(pTos, encoding);
============================================================
--- sqlite/vdbe.h 8729a4ee16ff9aeab2af9667df3cf300ff978e13
+++ sqlite/vdbe.h 80ba1c391ec28180dd07a630577f50b22c2062da
@@ -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.99 2005/09/20 17:42:23 drh Exp $
+** $Id: vdbe.h,v 1.101 2006/02/10 03:06:10 danielk1977 Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
@@ -69,6 +69,7 @@
#define P3_KEYINFO (-6) /* P3 is a pointer to a KeyInfo structure */
#define P3_VDBEFUNC (-7) /* P3 is a pointer to a VdbeFunc structure */
#define P3_MEM (-8) /* P3 is a pointer to a Mem* structure */
+#define P3_TRANSIENT (-9) /* P3 is a pointer to a transient string */
/* When adding a P3 argument using P3_KEYINFO, a copy of the KeyInfo structure
** is made. That copy is freed when the Vdbe is finalized. But if the
@@ -80,6 +81,17 @@
#define P3_KEYINFO_HANDOFF (-9)
/*
+** The Vdbe.aColName array contains 5n Mem structures, where n is the
+** number of columns of data returned by the statement.
+*/
+#define COLNAME_NAME 0
+#define COLNAME_DECLTYPE 1
+#define COLNAME_DATABASE 2
+#define COLNAME_TABLE 3
+#define COLNAME_COLUMN 4
+#define COLNAME_N 5 /* Number of COLNAME_xxx symbols */
+
+/*
** The following macro converts a relative address in the p2 field
** of a VdbeOp structure into a negative number so that
** sqlite3VdbeAddOpList() knows that the address is relative. Calling
@@ -117,7 +129,7 @@
int sqlite3VdbeReset(Vdbe*);
int sqliteVdbeSetVariables(Vdbe*,int,const char**);
void sqlite3VdbeSetNumCols(Vdbe*,int);
-int sqlite3VdbeSetColName(Vdbe*, int, const char *, int);
+int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, int);
void sqlite3VdbeCountChanges(Vdbe*);
sqlite3 *sqlite3VdbeDb(Vdbe*);
============================================================
--- sqlite/vdbeapi.c dcb2636f49b4807e34960d52a2fc257b3a751140
+++ sqlite/vdbeapi.c 7dc662e7c905ce666bb506dced932e0307115cbf
@@ -74,6 +74,7 @@
int sqlite3_value_type(sqlite3_value* pVal){
return pVal->type;
}
+/* sqlite3_value_numeric_type() defined in vdbe.c */
/**************************** sqlite3_result_ *******************************
** The following routines are used by user-defined functions to specify
@@ -335,9 +336,10 @@
** Return the number of times the Step function of a aggregate has been
** called.
**
-** This routine is defined here in vdbe.c because it depends on knowing
-** the internals of the sqlite3_context structure which is only defined in
-** this source file.
+** This function is deprecated. Do not use it for new code. It is
+** provide only to avoid breaking legacy code. New aggregate function
+** implementations should keep their own counts within their aggregate
+** context.
*/
int sqlite3_aggregate_count(sqlite3_context *p){
assert( p && p->pFunc && p->pFunc->xStep );
@@ -468,6 +470,13 @@
return sqlite3_value_type( columnMem(pStmt,i) );
}
+/* The following function is experimental and subject to change or
+** removal */
+/*int sqlite3_column_numeric_type(sqlite3_stmt *pStmt, int i){
+** return sqlite3_value_numeric_type( columnMem(pStmt,i) );
+**}
+*/
+
/*
** Convert the N-th element of pStmt->pColName[] into a string using
** xFunc() then return that string. If N is out of range, return 0.
@@ -512,11 +521,13 @@
** statement pStmt.
*/
const char *sqlite3_column_name(sqlite3_stmt *pStmt, int N){
- return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, 0);
+ return columnName(
+ pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_NAME);
}
#ifndef SQLITE_OMIT_UTF16
const void *sqlite3_column_name16(sqlite3_stmt *pStmt, int N){
- return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, 0);
+ return columnName(
+ pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_NAME);
}
#endif
@@ -525,26 +536,30 @@
** of the result set of SQL statement pStmt.
*/
const char *sqlite3_column_decltype(sqlite3_stmt *pStmt, int N){
- return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, 1);
+ return columnName(
+ pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_DECLTYPE);
}
#ifndef SQLITE_OMIT_UTF16
const void *sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){
- return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, 1);
+ return columnName(
+ pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_DECLTYPE);
}
#endif /* SQLITE_OMIT_UTF16 */
-#if !defined(SQLITE_OMIT_ORIGIN_NAMES) && 0
+#ifdef SQLITE_ENABLE_COLUMN_METADATA
/*
** Return the name of the database from which a result column derives.
** NULL is returned if the result column is an expression or constant or
** anything else which is not an unabiguous reference to a database column.
*/
const char *sqlite3_column_database_name(sqlite3_stmt *pStmt, int N){
- return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, 2);
+ return columnName(
+ pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_DATABASE);
}
#ifndef SQLITE_OMIT_UTF16
const void *sqlite3_column_database_name16(sqlite3_stmt *pStmt, int N){
- return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, 2);
+ return columnName(
+ pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_DATABASE);
}
#endif /* SQLITE_OMIT_UTF16 */
@@ -554,11 +569,13 @@
** anything else which is not an unabiguous reference to a database column.
*/
const char *sqlite3_column_table_name(sqlite3_stmt *pStmt, int N){
- return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, 3);
+ return columnName(
+ pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_TABLE);
}
#ifndef SQLITE_OMIT_UTF16
const void *sqlite3_column_table_name16(sqlite3_stmt *pStmt, int N){
- return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, 3);
+ return columnName(
+ pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_TABLE);
}
#endif /* SQLITE_OMIT_UTF16 */
@@ -568,18 +585,18 @@
** anything else which is not an unabiguous reference to a database column.
*/
const char *sqlite3_column_origin_name(sqlite3_stmt *pStmt, int N){
- return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, 4);
+ return columnName(
+ pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_COLUMN);
}
#ifndef SQLITE_OMIT_UTF16
const void *sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){
- return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, 4);
+ return columnName(
+ pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_COLUMN);
}
#endif /* SQLITE_OMIT_UTF16 */
-#endif /* SQLITE_OMIT_ORIGIN_NAMES */
+#endif /* SQLITE_ENABLE_COLUMN_METADATA */
-
-
/******************************* sqlite3_bind_ ***************************
**
** Routines used to attach values to wildcards in a compiled SQL statement.
============================================================
--- sqlite/vdbeaux.c 9bf50cdb6a6c40b8c06ca9a8d87cf90120a16797
+++ sqlite/vdbeaux.c 95f4ed0bc8ed45f16823d84504310495b5dc587d
@@ -871,9 +871,9 @@
void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){
Mem *pColName;
int n;
- releaseMemArray(p->aColName, p->nResColumn*2);
+ releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
sqliteFree(p->aColName);
- n = nResColumn*2;
+ n = nResColumn*COLNAME_N;
p->nResColumn = nResColumn;
p->aColName = pColName = (Mem*)sqliteMalloc( sizeof(Mem)*n );
if( p->aColName==0 ) return;
@@ -893,13 +893,14 @@
** the string is freed using sqliteFree() when the vdbe is finished with
** it. Otherwise, N bytes of zName are copied.
*/
-int sqlite3VdbeSetColName(Vdbe *p, int idx, const char *zName, int N){
+int sqlite3VdbeSetColName(Vdbe *p, int idx, int var, const char *zName, int N){
int rc;
Mem *pColName;
- assert( idx<(2*p->nResColumn) );
+ assert( idxnResColumn );
+ assert( varaColName!=0 );
- pColName = &(p->aColName[idx]);
+ pColName = &(p->aColName[idx+var*p->nResColumn]);
if( N==P3_DYNAMIC || N==P3_STATIC ){
rc = sqlite3VdbeMemSetStr(pColName, zName, -1, SQLITE_UTF8, SQLITE_STATIC);
}else{
@@ -1481,7 +1482,7 @@
releaseMemArray(p->aVar, p->nVar);
sqliteFree(p->aLabel);
sqliteFree(p->aStack);
- releaseMemArray(p->aColName, p->nResColumn*2);
+ releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
sqliteFree(p->aColName);
p->magic = VDBE_MAGIC_DEAD;
sqliteFree(p);
============================================================
--- sqlite/where.c 8409e00fa2cb5fce873b4c911165cfed097e9c49
+++ sqlite/where.c c7d71d5e55c9c4c1e948089280fb0dec7c7d1ef6
@@ -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.203 2006/01/24 12:09:20 danielk1977 Exp $
+** $Id: where.c,v 1.204 2006/02/01 02:45:02 drh Exp $
*/
#include "sqliteInt.h"
@@ -1500,9 +1500,16 @@
double lowestCost; /* Cost of the pBest */
int bestJ = 0; /* The value of j */
Bitmask m; /* Bitmask value for j or bestJ */
+ int once = 0; /* True when first table is seen */
lowestCost = SQLITE_BIG_DBL;
for(j=iFrom, pTabItem=&pTabList->a[j]; jnSrc; j++, pTabItem++){
+ if( once &&
+ ((pTabItem->jointype & (JT_LEFT|JT_CROSS))!=0
+ || (j>0 && (pTabItem[-1].jointype & (JT_LEFT|JT_CROSS))!=0))
+ ){
+ break;
+ }
m = getMask(&maskSet, pTabItem->iCursor);
if( (m & notReady)==0 ){
if( j==iFrom ) iFrom++;
@@ -1512,17 +1519,13 @@
(i==0 && ppOrderBy) ? *ppOrderBy : 0,
&pIdx, &flags, &nEq);
if( costjointype & (JT_LEFT|JT_CROSS))!=0
- || (j>0 && (pTabItem[-1].jointype & (JT_LEFT|JT_CROSS))!=0)
- ){
- break;
- }
}
TRACE(("*** Optimizer choose table %d for loop %d\n", bestJ,
pLevel-pWInfo->a));