Compare commits

..

2 Commits

Author SHA1 Message Date
drh 282b14c9c6 Add the shardvtab virtual table that uses the new cost estimation functions.
FossilOrigin-Name: 9404300ac1dd0ef4e4b42f618901c6120b15a158c230f76e47c4c6346f6f4f58
2019-04-27 20:39:38 +00:00
drh ac2fa465e9 An experimental interface for retrieving the estimated cost and estimated
number of output rows for a query.

FossilOrigin-Name: 1b25fa108ab2c4ada75935abf919de2b4c3b39553b2a0ab2a485645a02352e7e
2019-04-26 17:20:33 +00:00
71 changed files with 881 additions and 4451 deletions
-851
View File
@@ -1,851 +0,0 @@
/*
** 2019-04-17
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
******************************************************************************
**
** This file contains an implementation of two eponymous virtual tables,
** "sqlite_dbdata" and "sqlite_dbptr". Both modules require that the
** "sqlite_dbpage" eponymous virtual table be available.
**
** SQLITE_DBDATA:
** sqlite_dbdata is used to extract data directly from a database b-tree
** page and its associated overflow pages, bypassing the b-tree layer.
** The table schema is equivalent to:
**
** CREATE TABLE sqlite_dbdata(
** pgno INTEGER,
** cell INTEGER,
** field INTEGER,
** value ANY,
** schema TEXT HIDDEN
** );
**
** IMPORTANT: THE VIRTUAL TABLE SCHEMA ABOVE IS SUBJECT TO CHANGE. IN THE
** FUTURE NEW NON-HIDDEN COLUMNS MAY BE ADDED BETWEEN "value" AND
** "schema".
**
** Each page of the database is inspected. If it cannot be interpreted as
** a b-tree page, or if it is a b-tree page containing 0 entries, the
** sqlite_dbdata table contains no rows for that page. Otherwise, the
** table contains one row for each field in the record associated with
** each cell on the page. For intkey b-trees, the key value is stored in
** field -1.
**
** For example, for the database:
**
** CREATE TABLE t1(a, b); -- root page is page 2
** INSERT INTO t1(rowid, a, b) VALUES(5, 'v', 'five');
** INSERT INTO t1(rowid, a, b) VALUES(10, 'x', 'ten');
**
** the sqlite_dbdata table contains, as well as from entries related to
** page 1, content equivalent to:
**
** INSERT INTO sqlite_dbdata(pgno, cell, field, value) VALUES
** (2, 0, -1, 5 ),
** (2, 0, 0, 'v' ),
** (2, 0, 1, 'five'),
** (2, 1, -1, 10 ),
** (2, 1, 0, 'x' ),
** (2, 1, 1, 'ten' );
**
** If database corruption is encountered, this module does not report an
** error. Instead, it attempts to extract as much data as possible and
** ignores the corruption.
**
** SQLITE_DBPTR:
** The sqlite_dbptr table has the following schema:
**
** CREATE TABLE sqlite_dbptr(
** pgno INTEGER,
** child INTEGER,
** schema TEXT HIDDEN
** );
**
** It contains one entry for each b-tree pointer between a parent and
** child page in the database.
*/
#if !defined(SQLITEINT_H)
#include "sqlite3ext.h"
typedef unsigned char u8;
#endif
SQLITE_EXTENSION_INIT1
#include <string.h>
#include <assert.h>
#define DBDATA_PADDING_BYTES 100
typedef struct DbdataTable DbdataTable;
typedef struct DbdataCursor DbdataCursor;
/* Cursor object */
struct DbdataCursor {
sqlite3_vtab_cursor base; /* Base class. Must be first */
sqlite3_stmt *pStmt; /* For fetching database pages */
int iPgno; /* Current page number */
u8 *aPage; /* Buffer containing page */
int nPage; /* Size of aPage[] in bytes */
int nCell; /* Number of cells on aPage[] */
int iCell; /* Current cell number */
int bOnePage; /* True to stop after one page */
int szDb;
sqlite3_int64 iRowid;
/* Only for the sqlite_dbdata table */
u8 *pRec; /* Buffer containing current record */
int nRec; /* Size of pRec[] in bytes */
int nHdr; /* Size of header in bytes */
int iField; /* Current field number */
u8 *pHdrPtr;
u8 *pPtr;
sqlite3_int64 iIntkey; /* Integer key value */
};
/* Table object */
struct DbdataTable {
sqlite3_vtab base; /* Base class. Must be first */
sqlite3 *db; /* The database connection */
sqlite3_stmt *pStmt; /* For fetching database pages */
int bPtr; /* True for sqlite3_dbptr table */
};
/* Column and schema definitions for sqlite_dbdata */
#define DBDATA_COLUMN_PGNO 0
#define DBDATA_COLUMN_CELL 1
#define DBDATA_COLUMN_FIELD 2
#define DBDATA_COLUMN_VALUE 3
#define DBDATA_COLUMN_SCHEMA 4
#define DBDATA_SCHEMA \
"CREATE TABLE x(" \
" pgno INTEGER," \
" cell INTEGER," \
" field INTEGER," \
" value ANY," \
" schema TEXT HIDDEN" \
")"
/* Column and schema definitions for sqlite_dbptr */
#define DBPTR_COLUMN_PGNO 0
#define DBPTR_COLUMN_CHILD 1
#define DBPTR_COLUMN_SCHEMA 2
#define DBPTR_SCHEMA \
"CREATE TABLE x(" \
" pgno INTEGER," \
" child INTEGER," \
" schema TEXT HIDDEN" \
")"
/*
** Connect to an sqlite_dbdata (pAux==0) or sqlite_dbptr (pAux!=0) virtual
** table.
*/
static int dbdataConnect(
sqlite3 *db,
void *pAux,
int argc, const char *const*argv,
sqlite3_vtab **ppVtab,
char **pzErr
){
DbdataTable *pTab = 0;
int rc = sqlite3_declare_vtab(db, pAux ? DBPTR_SCHEMA : DBDATA_SCHEMA);
if( rc==SQLITE_OK ){
pTab = (DbdataTable*)sqlite3_malloc64(sizeof(DbdataTable));
if( pTab==0 ){
rc = SQLITE_NOMEM;
}else{
memset(pTab, 0, sizeof(DbdataTable));
pTab->db = db;
pTab->bPtr = (pAux!=0);
}
}
*ppVtab = (sqlite3_vtab*)pTab;
return rc;
}
/*
** Disconnect from or destroy a sqlite_dbdata or sqlite_dbptr virtual table.
*/
static int dbdataDisconnect(sqlite3_vtab *pVtab){
DbdataTable *pTab = (DbdataTable*)pVtab;
if( pTab ){
sqlite3_finalize(pTab->pStmt);
sqlite3_free(pVtab);
}
return SQLITE_OK;
}
/*
** This function interprets two types of constraints:
**
** schema=?
** pgno=?
**
** If neither are present, idxNum is set to 0. If schema=? is present,
** the 0x01 bit in idxNum is set. If pgno=? is present, the 0x02 bit
** in idxNum is set.
**
** If both parameters are present, schema is in position 0 and pgno in
** position 1.
*/
static int dbdataBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdx){
DbdataTable *pTab = (DbdataTable*)tab;
int i;
int iSchema = -1;
int iPgno = -1;
int colSchema = (pTab->bPtr ? DBPTR_COLUMN_SCHEMA : DBDATA_COLUMN_SCHEMA);
for(i=0; i<pIdx->nConstraint; i++){
struct sqlite3_index_constraint *p = &pIdx->aConstraint[i];
if( p->op==SQLITE_INDEX_CONSTRAINT_EQ ){
if( p->iColumn==colSchema ){
if( p->usable==0 ) return SQLITE_CONSTRAINT;
iSchema = i;
}
if( p->iColumn==DBDATA_COLUMN_PGNO && p->usable ){
iPgno = i;
}
}
}
if( iSchema>=0 ){
pIdx->aConstraintUsage[iSchema].argvIndex = 1;
pIdx->aConstraintUsage[iSchema].omit = 1;
}
if( iPgno>=0 ){
pIdx->aConstraintUsage[iPgno].argvIndex = 1 + (iSchema>=0);
pIdx->aConstraintUsage[iPgno].omit = 1;
pIdx->estimatedCost = 100;
pIdx->estimatedRows = 50;
if( pTab->bPtr==0 && pIdx->nOrderBy && pIdx->aOrderBy[0].desc==0 ){
int iCol = pIdx->aOrderBy[0].iColumn;
if( pIdx->nOrderBy==1 ){
pIdx->orderByConsumed = (iCol==0 || iCol==1);
}else if( pIdx->nOrderBy==2 && pIdx->aOrderBy[1].desc==0 && iCol==0 ){
pIdx->orderByConsumed = (pIdx->aOrderBy[1].iColumn==1);
}
}
}else{
pIdx->estimatedCost = 100000000;
pIdx->estimatedRows = 1000000000;
}
pIdx->idxNum = (iSchema>=0 ? 0x01 : 0x00) | (iPgno>=0 ? 0x02 : 0x00);
return SQLITE_OK;
}
/*
** Open a new sqlite_dbdata or sqlite_dbptr cursor.
*/
static int dbdataOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
DbdataCursor *pCsr;
pCsr = (DbdataCursor*)sqlite3_malloc64(sizeof(DbdataCursor));
if( pCsr==0 ){
return SQLITE_NOMEM;
}else{
memset(pCsr, 0, sizeof(DbdataCursor));
pCsr->base.pVtab = pVTab;
}
*ppCursor = (sqlite3_vtab_cursor *)pCsr;
return SQLITE_OK;
}
/*
** Restore a cursor object to the state it was in when first allocated
** by dbdataOpen().
*/
static void dbdataResetCursor(DbdataCursor *pCsr){
DbdataTable *pTab = (DbdataTable*)(pCsr->base.pVtab);
if( pTab->pStmt==0 ){
pTab->pStmt = pCsr->pStmt;
}else{
sqlite3_finalize(pCsr->pStmt);
}
pCsr->pStmt = 0;
pCsr->iPgno = 1;
pCsr->iCell = 0;
pCsr->iField = 0;
pCsr->bOnePage = 0;
sqlite3_free(pCsr->aPage);
sqlite3_free(pCsr->pRec);
pCsr->pRec = 0;
pCsr->aPage = 0;
}
/*
** Close an sqlite_dbdata or sqlite_dbptr cursor.
*/
static int dbdataClose(sqlite3_vtab_cursor *pCursor){
DbdataCursor *pCsr = (DbdataCursor*)pCursor;
dbdataResetCursor(pCsr);
sqlite3_free(pCsr);
return SQLITE_OK;
}
/*
** Utility methods to decode 16 and 32-bit big-endian unsigned integers.
*/
static unsigned int get_uint16(unsigned char *a){
return (a[0]<<8)|a[1];
}
static unsigned int get_uint32(unsigned char *a){
return ((unsigned int)a[0]<<24)
| ((unsigned int)a[1]<<16)
| ((unsigned int)a[2]<<8)
| ((unsigned int)a[3]);
}
/*
** Load page pgno from the database via the sqlite_dbpage virtual table.
** If successful, set (*ppPage) to point to a buffer containing the page
** data, (*pnPage) to the size of that buffer in bytes and return
** SQLITE_OK. In this case it is the responsibility of the caller to
** eventually free the buffer using sqlite3_free().
**
** Or, if an error occurs, set both (*ppPage) and (*pnPage) to 0 and
** return an SQLite error code.
*/
static int dbdataLoadPage(
DbdataCursor *pCsr, /* Cursor object */
unsigned int pgno, /* Page number of page to load */
u8 **ppPage, /* OUT: pointer to page buffer */
int *pnPage /* OUT: Size of (*ppPage) in bytes */
){
int rc2;
int rc = SQLITE_OK;
sqlite3_stmt *pStmt = pCsr->pStmt;
*ppPage = 0;
*pnPage = 0;
sqlite3_bind_int64(pStmt, 2, pgno);
if( SQLITE_ROW==sqlite3_step(pStmt) ){
int nCopy = sqlite3_column_bytes(pStmt, 0);
if( nCopy>0 ){
u8 *pPage;
pPage = (u8*)sqlite3_malloc64(nCopy + DBDATA_PADDING_BYTES);
if( pPage==0 ){
rc = SQLITE_NOMEM;
}else{
const u8 *pCopy = sqlite3_column_blob(pStmt, 0);
memcpy(pPage, pCopy, nCopy);
memset(&pPage[nCopy], 0, DBDATA_PADDING_BYTES);
}
*ppPage = pPage;
*pnPage = nCopy;
}
}
rc2 = sqlite3_reset(pStmt);
if( rc==SQLITE_OK ) rc = rc2;
return rc;
}
/*
** Read a varint. Put the value in *pVal and return the number of bytes.
*/
static int dbdataGetVarint(const u8 *z, sqlite3_int64 *pVal){
sqlite3_int64 v = 0;
int i;
for(i=0; i<8; i++){
v = (v<<7) + (z[i]&0x7f);
if( (z[i]&0x80)==0 ){ *pVal = v; return i+1; }
}
v = (v<<8) + (z[i]&0xff);
*pVal = v;
return 9;
}
/*
** Return the number of bytes of space used by an SQLite value of type
** eType.
*/
static int dbdataValueBytes(int eType){
switch( eType ){
case 0: case 8: case 9:
case 10: case 11:
return 0;
case 1:
return 1;
case 2:
return 2;
case 3:
return 3;
case 4:
return 4;
case 5:
return 6;
case 6:
case 7:
return 8;
default:
if( eType>0 ){
return ((eType-12) / 2);
}
return 0;
}
}
/*
** Load a value of type eType from buffer pData and use it to set the
** result of context object pCtx.
*/
static void dbdataValue(
sqlite3_context *pCtx,
int eType,
u8 *pData,
int nData
){
if( eType>=0 && dbdataValueBytes(eType)<=nData ){
switch( eType ){
case 0:
case 10:
case 11:
sqlite3_result_null(pCtx);
break;
case 8:
sqlite3_result_int(pCtx, 0);
break;
case 9:
sqlite3_result_int(pCtx, 1);
break;
case 1: case 2: case 3: case 4: case 5: case 6: case 7: {
sqlite3_uint64 v = (signed char)pData[0];
pData++;
switch( eType ){
case 7:
case 6: v = (v<<16) + (pData[0]<<8) + pData[1]; pData += 2;
case 5: v = (v<<16) + (pData[0]<<8) + pData[1]; pData += 2;
case 4: v = (v<<8) + pData[0]; pData++;
case 3: v = (v<<8) + pData[0]; pData++;
case 2: v = (v<<8) + pData[0]; pData++;
}
if( eType==7 ){
double r;
memcpy(&r, &v, sizeof(r));
sqlite3_result_double(pCtx, r);
}else{
sqlite3_result_int64(pCtx, (sqlite3_int64)v);
}
break;
}
default: {
int n = ((eType-12) / 2);
if( eType % 2 ){
sqlite3_result_text(pCtx, (const char*)pData, n, SQLITE_TRANSIENT);
}else{
sqlite3_result_blob(pCtx, pData, n, SQLITE_TRANSIENT);
}
}
}
}
}
/*
** Move an sqlite_dbdata or sqlite_dbptr cursor to the next entry.
*/
static int dbdataNext(sqlite3_vtab_cursor *pCursor){
DbdataCursor *pCsr = (DbdataCursor*)pCursor;
DbdataTable *pTab = (DbdataTable*)pCursor->pVtab;
pCsr->iRowid++;
while( 1 ){
int rc;
int iOff = (pCsr->iPgno==1 ? 100 : 0);
int bNextPage = 0;
if( pCsr->aPage==0 ){
while( 1 ){
if( pCsr->bOnePage==0 && pCsr->iPgno>pCsr->szDb ) return SQLITE_OK;
rc = dbdataLoadPage(pCsr, pCsr->iPgno, &pCsr->aPage, &pCsr->nPage);
if( rc!=SQLITE_OK ) return rc;
if( pCsr->aPage ) break;
pCsr->iPgno++;
}
pCsr->iCell = pTab->bPtr ? -2 : 0;
pCsr->nCell = get_uint16(&pCsr->aPage[iOff+3]);
}
if( pTab->bPtr ){
if( pCsr->aPage[iOff]!=0x02 && pCsr->aPage[iOff]!=0x05 ){
pCsr->iCell = pCsr->nCell;
}
pCsr->iCell++;
if( pCsr->iCell>=pCsr->nCell ){
sqlite3_free(pCsr->aPage);
pCsr->aPage = 0;
if( pCsr->bOnePage ) return SQLITE_OK;
pCsr->iPgno++;
}else{
return SQLITE_OK;
}
}else{
/* If there is no record loaded, load it now. */
if( pCsr->pRec==0 ){
int bHasRowid = 0;
int nPointer = 0;
sqlite3_int64 nPayload = 0;
sqlite3_int64 nHdr = 0;
int iHdr;
int U, X;
int nLocal;
switch( pCsr->aPage[iOff] ){
case 0x02:
nPointer = 4;
break;
case 0x0a:
break;
case 0x0d:
bHasRowid = 1;
break;
default:
/* This is not a b-tree page with records on it. Continue. */
pCsr->iCell = pCsr->nCell;
break;
}
if( pCsr->iCell>=pCsr->nCell ){
bNextPage = 1;
}else{
iOff += 8 + nPointer + pCsr->iCell*2;
if( iOff>pCsr->nPage ){
bNextPage = 1;
}else{
iOff = get_uint16(&pCsr->aPage[iOff]);
}
/* For an interior node cell, skip past the child-page number */
iOff += nPointer;
/* Load the "byte of payload including overflow" field */
if( bNextPage || iOff>pCsr->nPage ){
bNextPage = 1;
}else{
iOff += dbdataGetVarint(&pCsr->aPage[iOff], &nPayload);
}
/* If this is a leaf intkey cell, load the rowid */
if( bHasRowid && !bNextPage && iOff<pCsr->nPage ){
iOff += dbdataGetVarint(&pCsr->aPage[iOff], &pCsr->iIntkey);
}
/* Figure out how much data to read from the local page */
U = pCsr->nPage;
if( bHasRowid ){
X = U-35;
}else{
X = ((U-12)*64/255)-23;
}
if( nPayload<=X ){
nLocal = nPayload;
}else{
int M, K;
M = ((U-12)*32/255)-23;
K = M+((nPayload-M)%(U-4));
if( K<=X ){
nLocal = K;
}else{
nLocal = M;
}
}
if( bNextPage || nLocal+iOff>pCsr->nPage ){
bNextPage = 1;
}else{
/* Allocate space for payload. And a bit more to catch small buffer
** overruns caused by attempting to read a varint or similar from
** near the end of a corrupt record. */
pCsr->pRec = (u8*)sqlite3_malloc64(nPayload+DBDATA_PADDING_BYTES);
if( pCsr->pRec==0 ) return SQLITE_NOMEM;
memset(pCsr->pRec, 0, nPayload+DBDATA_PADDING_BYTES);
pCsr->nRec = nPayload;
/* Load the nLocal bytes of payload */
memcpy(pCsr->pRec, &pCsr->aPage[iOff], nLocal);
iOff += nLocal;
/* Load content from overflow pages */
if( nPayload>nLocal ){
sqlite3_int64 nRem = nPayload - nLocal;
unsigned int pgnoOvfl = get_uint32(&pCsr->aPage[iOff]);
while( nRem>0 ){
u8 *aOvfl = 0;
int nOvfl = 0;
int nCopy;
rc = dbdataLoadPage(pCsr, pgnoOvfl, &aOvfl, &nOvfl);
assert( rc!=SQLITE_OK || aOvfl==0 || nOvfl==pCsr->nPage );
if( rc!=SQLITE_OK ) return rc;
if( aOvfl==0 ) break;
nCopy = U-4;
if( nCopy>nRem ) nCopy = nRem;
memcpy(&pCsr->pRec[nPayload-nRem], &aOvfl[4], nCopy);
nRem -= nCopy;
pgnoOvfl = get_uint32(aOvfl);
sqlite3_free(aOvfl);
}
}
iHdr = dbdataGetVarint(pCsr->pRec, &nHdr);
pCsr->nHdr = nHdr;
pCsr->pHdrPtr = &pCsr->pRec[iHdr];
pCsr->pPtr = &pCsr->pRec[pCsr->nHdr];
pCsr->iField = (bHasRowid ? -1 : 0);
}
}
}else{
pCsr->iField++;
if( pCsr->iField>0 ){
sqlite3_int64 iType;
if( pCsr->pHdrPtr>&pCsr->pRec[pCsr->nRec] ){
bNextPage = 1;
}else{
pCsr->pHdrPtr += dbdataGetVarint(pCsr->pHdrPtr, &iType);
pCsr->pPtr += dbdataValueBytes(iType);
}
}
}
if( bNextPage ){
sqlite3_free(pCsr->aPage);
sqlite3_free(pCsr->pRec);
pCsr->aPage = 0;
pCsr->pRec = 0;
if( pCsr->bOnePage ) return SQLITE_OK;
pCsr->iPgno++;
}else{
if( pCsr->iField<0 || pCsr->pHdrPtr<&pCsr->pRec[pCsr->nHdr] ){
return SQLITE_OK;
}
/* Advance to the next cell. The next iteration of the loop will load
** the record and so on. */
sqlite3_free(pCsr->pRec);
pCsr->pRec = 0;
pCsr->iCell++;
}
}
}
assert( !"can't get here" );
return SQLITE_OK;
}
/*
** Return true if the cursor is at EOF.
*/
static int dbdataEof(sqlite3_vtab_cursor *pCursor){
DbdataCursor *pCsr = (DbdataCursor*)pCursor;
return pCsr->aPage==0;
}
/*
** Determine the size in pages of database zSchema (where zSchema is
** "main", "temp" or the name of an attached database) and set
** pCsr->szDb accordingly. If successful, return SQLITE_OK. Otherwise,
** an SQLite error code.
*/
static int dbdataDbsize(DbdataCursor *pCsr, const char *zSchema){
DbdataTable *pTab = (DbdataTable*)pCsr->base.pVtab;
char *zSql = 0;
int rc, rc2;
sqlite3_stmt *pStmt = 0;
zSql = sqlite3_mprintf("PRAGMA %Q.page_count", zSchema);
if( zSql==0 ) return SQLITE_NOMEM;
rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pStmt, 0);
sqlite3_free(zSql);
if( rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
pCsr->szDb = sqlite3_column_int(pStmt, 0);
}
rc2 = sqlite3_finalize(pStmt);
if( rc==SQLITE_OK ) rc = rc2;
return rc;
}
/*
** xFilter method for sqlite_dbdata and sqlite_dbptr.
*/
static int dbdataFilter(
sqlite3_vtab_cursor *pCursor,
int idxNum, const char *idxStr,
int argc, sqlite3_value **argv
){
DbdataCursor *pCsr = (DbdataCursor*)pCursor;
DbdataTable *pTab = (DbdataTable*)pCursor->pVtab;
int rc = SQLITE_OK;
const char *zSchema = "main";
dbdataResetCursor(pCsr);
assert( pCsr->iPgno==1 );
if( idxNum & 0x01 ){
zSchema = (const char*)sqlite3_value_text(argv[0]);
}
if( idxNum & 0x02 ){
pCsr->iPgno = sqlite3_value_int(argv[(idxNum & 0x01)]);
pCsr->bOnePage = 1;
}else{
pCsr->nPage = dbdataDbsize(pCsr, zSchema);
rc = dbdataDbsize(pCsr, zSchema);
}
if( rc==SQLITE_OK ){
if( pTab->pStmt ){
pCsr->pStmt = pTab->pStmt;
pTab->pStmt = 0;
}else{
rc = sqlite3_prepare_v2(pTab->db,
"SELECT data FROM sqlite_dbpage(?) WHERE pgno=?", -1,
&pCsr->pStmt, 0
);
}
}
if( rc==SQLITE_OK ){
rc = sqlite3_bind_text(pCsr->pStmt, 1, zSchema, -1, SQLITE_TRANSIENT);
}else{
pTab->base.zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pTab->db));
}
if( rc==SQLITE_OK ){
rc = dbdataNext(pCursor);
}
return rc;
}
/*
** Return a column for the sqlite_dbdata or sqlite_dbptr table.
*/
static int dbdataColumn(
sqlite3_vtab_cursor *pCursor,
sqlite3_context *ctx,
int i
){
DbdataCursor *pCsr = (DbdataCursor*)pCursor;
DbdataTable *pTab = (DbdataTable*)pCursor->pVtab;
if( pTab->bPtr ){
switch( i ){
case DBPTR_COLUMN_PGNO:
sqlite3_result_int64(ctx, pCsr->iPgno);
break;
case DBPTR_COLUMN_CHILD: {
int iOff = pCsr->iPgno==1 ? 100 : 0;
if( pCsr->iCell<0 ){
iOff += 8;
}else{
iOff += 12 + pCsr->iCell*2;
if( iOff>pCsr->nPage ) return SQLITE_OK;
iOff = get_uint16(&pCsr->aPage[iOff]);
}
if( iOff<=pCsr->nPage ){
sqlite3_result_int64(ctx, get_uint32(&pCsr->aPage[iOff]));
}
break;
}
}
}else{
switch( i ){
case DBDATA_COLUMN_PGNO:
sqlite3_result_int64(ctx, pCsr->iPgno);
break;
case DBDATA_COLUMN_CELL:
sqlite3_result_int(ctx, pCsr->iCell);
break;
case DBDATA_COLUMN_FIELD:
sqlite3_result_int(ctx, pCsr->iField);
break;
case DBDATA_COLUMN_VALUE: {
if( pCsr->iField<0 ){
sqlite3_result_int64(ctx, pCsr->iIntkey);
}else{
sqlite3_int64 iType;
dbdataGetVarint(pCsr->pHdrPtr, &iType);
dbdataValue(
ctx, iType, pCsr->pPtr, &pCsr->pRec[pCsr->nRec] - pCsr->pPtr
);
}
break;
}
}
}
return SQLITE_OK;
}
/*
** Return the rowid for an sqlite_dbdata or sqlite_dptr table.
*/
static int dbdataRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
DbdataCursor *pCsr = (DbdataCursor*)pCursor;
*pRowid = pCsr->iRowid;
return SQLITE_OK;
}
/*
** Invoke this routine to register the "sqlite_dbdata" virtual table module
*/
static int sqlite3DbdataRegister(sqlite3 *db){
static sqlite3_module dbdata_module = {
0, /* iVersion */
0, /* xCreate */
dbdataConnect, /* xConnect */
dbdataBestIndex, /* xBestIndex */
dbdataDisconnect, /* xDisconnect */
0, /* xDestroy */
dbdataOpen, /* xOpen - open a cursor */
dbdataClose, /* xClose - close a cursor */
dbdataFilter, /* xFilter - configure scan constraints */
dbdataNext, /* xNext - advance a cursor */
dbdataEof, /* xEof - check for end of scan */
dbdataColumn, /* xColumn - read data */
dbdataRowid, /* xRowid - read data */
0, /* xUpdate */
0, /* xBegin */
0, /* xSync */
0, /* xCommit */
0, /* xRollback */
0, /* xFindMethod */
0, /* xRename */
0, /* xSavepoint */
0, /* xRelease */
0, /* xRollbackTo */
0 /* xShadowName */
};
int rc = sqlite3_create_module(db, "sqlite_dbdata", &dbdata_module, 0);
if( rc==SQLITE_OK ){
rc = sqlite3_create_module(db, "sqlite_dbptr", &dbdata_module, (void*)1);
}
return rc;
}
#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_dbdata_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
){
SQLITE_EXTENSION_INIT2(pApi);
return sqlite3DbdataRegister(db);
}
+375
View File
@@ -0,0 +1,375 @@
/*
** 2019-04-26
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file implements a virtual-table that can be used to access a
** sharded table implemented as the UNION ALL of various separate tables.
*/
#if !defined(SQLITEINT_H)
#include "sqlite3ext.h"
#endif
SQLITE_EXTENSION_INIT1
#include <string.h>
#include <assert.h>
#include <math.h>
/* shardvtab_vtab is a subclass of sqlite3_vtab which is
** underlying representation of the virtual table
*/
typedef struct shardvtab_vtab shardvtab_vtab;
struct shardvtab_vtab {
sqlite3_vtab base; /* Base class - must be first */
sqlite3 *db; /* The database connection */
char *zView; /* Name of view that implements the shard */
int nCol; /* Number of columns in the view */
char **azCol; /* Names of the columns, individually malloced */
};
/* shardvtab_cursor is a subclass of sqlite3_vtab_cursor which will
** serve as the underlying representation of a cursor that scans
** over rows of the result
*/
typedef struct shardvtab_cursor shardvtab_cursor;
struct shardvtab_cursor {
sqlite3_vtab_cursor base; /* Base class - must be first */
sqlite3_stmt *pStmt; /* Prepared statement to access the shard */
int rcLastStep; /* Last return from sqlite3_step() */
};
/*
** The shardvtabConnect() method is invoked to create a new
** shard virtual table.
**
** Think of this routine as the constructor for shardvtab_vtab objects.
**
** All this routine needs to do is:
**
** (1) Allocate the shardvtab_vtab object and initialize all fields.
**
** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the
** result set of queries against the virtual table will look like.
*/
static int shardvtabConnect(
sqlite3 *db,
void *pAux,
int argc, const char *const*argv,
sqlite3_vtab **ppVtab,
char **pzErr
){
shardvtab_vtab *pNew;
int rc;
char *zSql;
sqlite3_str *pSchema;
sqlite3_stmt *pStmt = 0;
const char *zView = 0;
char **azCol = 0;
int nCol = 0;
char cSep;
int i;
if( argc!=4 || argv[0]==0 ){
*pzErr = sqlite3_mprintf("one argument requires: the name of a view");
return SQLITE_ERROR;
}
zView = argv[3];
zSql = sqlite3_mprintf("SELECT * FROM \"%w\"", zView);
if( zSql==0 ){
return SQLITE_NOMEM;
}
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
sqlite3_free(zSql);
if( rc ){
*pzErr = sqlite3_mprintf("not a valid view: \"%w\"", zView);
return SQLITE_NOMEM;
}
pSchema = sqlite3_str_new(db);
if( pSchema==0 ){
sqlite3_finalize(pStmt);
return SQLITE_NOMEM;
}
sqlite3_str_appendall(pSchema, "CREATE TABLE x");
cSep = '(';
for(i=0; i<sqlite3_column_count(pStmt); i++){
const char *zName = sqlite3_column_name(pStmt,i);
char **azNew = sqlite3_realloc64(azCol, sizeof(azCol[0])*(i+1));
if( azNew==0 ){
rc = SQLITE_NOMEM;
goto shardvtab_connect_error;
}
sqlite3_str_appendf(pSchema, "%c\"%w\"", cSep, zName);
cSep = ',';
azCol = azNew;
azCol[nCol] = sqlite3_mprintf("%s", zName);
if( azCol[nCol]==0 ){
rc = SQLITE_NOMEM;
goto shardvtab_connect_error;
}
nCol++;
}
sqlite3_str_appendall(pSchema, ")");
sqlite3_finalize(pStmt);
pStmt = 0;
zSql = sqlite3_str_finish(pSchema);
pSchema = 0;
if( zSql==0 ){
rc = SQLITE_NOMEM;
goto shardvtab_connect_error;
}
rc = sqlite3_declare_vtab(db, zSql);
sqlite3_free(zSql);
if( rc!=SQLITE_OK ){
goto shardvtab_connect_error;
}else{
size_t n = strlen(zView) + 1;
pNew = sqlite3_malloc64( sizeof(*pNew) + n );
*ppVtab = (sqlite3_vtab*)pNew;
if( pNew==0 ){
rc = SQLITE_NOMEM;
goto shardvtab_connect_error;
}
memset(pNew, 0, sizeof(*pNew));
pNew->db = db;
pNew->zView = (char*)&pNew[1];
memcpy(pNew->zView, zView, n);
pNew->nCol = nCol;
pNew->azCol = azCol;
}
return SQLITE_OK;
shardvtab_connect_error:
sqlite3_finalize(pStmt);
for(i=0; i<nCol; i++) sqlite3_free(azCol[i]);
sqlite3_free(azCol);
sqlite3_free(sqlite3_str_finish(pSchema));
return rc;
}
/*
** This method is the destructor for shardvtab_vtab objects.
*/
static int shardvtabDisconnect(sqlite3_vtab *pVtab){
int i;
shardvtab_vtab *p = (shardvtab_vtab*)pVtab;
for(i=0; i<p->nCol; i++) sqlite3_free(p->azCol[i]);
sqlite3_free(p->azCol);
sqlite3_free(p);
return SQLITE_OK;
}
/*
** Constructor for a new shardvtab_cursor object.
*/
static int shardvtabOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
shardvtab_cursor *pCur;
pCur = sqlite3_malloc( sizeof(*pCur) );
if( pCur==0 ) return SQLITE_NOMEM;
memset(pCur, 0, sizeof(*pCur));
*ppCursor = &pCur->base;
return SQLITE_OK;
}
/*
** Destructor for a shardvtab_cursor.
*/
static int shardvtabClose(sqlite3_vtab_cursor *cur){
shardvtab_cursor *pCur = (shardvtab_cursor*)cur;
sqlite3_finalize(pCur->pStmt);
sqlite3_free(pCur);
return SQLITE_OK;
}
/*
** Advance a shardvtab_cursor to its next row of output.
*/
static int shardvtabNext(sqlite3_vtab_cursor *cur){
shardvtab_cursor *pCur = (shardvtab_cursor*)cur;
int rc;
rc = pCur->rcLastStep = sqlite3_step(pCur->pStmt);
if( rc==SQLITE_ROW || rc==SQLITE_DONE ) return SQLITE_OK;
return rc;
}
/*
** Return values of columns for the row at which the shardvtab_cursor
** is currently pointing.
*/
static int shardvtabColumn(
sqlite3_vtab_cursor *cur, /* The cursor */
sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
int i /* Which column to return */
){
shardvtab_cursor *pCur = (shardvtab_cursor*)cur;
sqlite3_result_value(ctx, sqlite3_column_value(pCur->pStmt, i));
return SQLITE_OK;
}
/*
** Return the rowid for the current row. In this implementation, the
** rowid is the same as the output value.
*/
static int shardvtabRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
*pRowid = 0;
return SQLITE_OK;
}
/*
** Return TRUE if the cursor has been moved off of the last
** row of output.
*/
static int shardvtabEof(sqlite3_vtab_cursor *cur){
shardvtab_cursor *pCur = (shardvtab_cursor*)cur;
return pCur->rcLastStep!=SQLITE_ROW;
}
/*
** This method is called to "rewind" the shardvtab_cursor object back
** to the first row of output. This method is always called at least
** once prior to any call to shardvtabColumn() or shardvtabRowid() or
** shardvtabEof().
*/
static int shardvtabFilter(
sqlite3_vtab_cursor *pVtabCursor,
int idxNum, const char *idxStr,
int argc, sqlite3_value **argv
){
shardvtab_cursor *pCur = (shardvtab_cursor *)pVtabCursor;
shardvtab_vtab *pTab = (shardvtab_vtab *)pVtabCursor->pVtab;
int rc;
sqlite3_finalize(pCur->pStmt);
pCur->pStmt = 0;
rc = sqlite3_prepare_v2(pTab->db, idxStr, -1, &pCur->pStmt, 0);
if( rc==SQLITE_OK ){
int i;
for(i=0; i<argc; i++){
sqlite3_bind_value(pCur->pStmt, i+1, argv[i]);
}
}else{
sqlite3_finalize(pCur->pStmt);
pCur->pStmt = 0;
}
pCur->rcLastStep = rc;
return rc;
}
/*
** SQLite will invoke this method one or more times while planning a query
** that uses the virtual table. This routine needs to create
** a query plan for each invocation and compute an estimated cost for that
** plan.
*/
static int shardvtabBestIndex(
sqlite3_vtab *tab,
sqlite3_index_info *p
){
shardvtab_vtab *pTab = (shardvtab_vtab*)tab;
int i;
int n;
sqlite3_stmt *pStmt;
int rc;
sqlite3_str *pSql;
char *zSep = "WHERE";
char *zSql;
pSql = sqlite3_str_new(pTab->db);
if( pSql==0 ) return SQLITE_NOMEM;
sqlite3_str_appendf(pSql, "SELECT * FROM \"%w\"", pTab->zView);
for(i=n=0; i<p->nConstraint; i++){
const char *zOp;
int iCol;
if( p->aConstraint[i].usable==0 ) continue;
iCol = p->aConstraint[i].iColumn;
if( iCol<0 ) continue;
zOp = 0;
switch( p->aConstraint[i].op ){
case SQLITE_INDEX_CONSTRAINT_EQ: zOp = "=="; break;
case SQLITE_INDEX_CONSTRAINT_GT: zOp = ">"; break;
case SQLITE_INDEX_CONSTRAINT_LE: zOp = "<="; break;
case SQLITE_INDEX_CONSTRAINT_LT: zOp = "<"; break;
case SQLITE_INDEX_CONSTRAINT_GE: zOp = ">="; break;
case SQLITE_INDEX_CONSTRAINT_MATCH: zOp = "MATCH"; break;
case SQLITE_INDEX_CONSTRAINT_LIKE: zOp = "LIKE"; break;
case SQLITE_INDEX_CONSTRAINT_GLOB: zOp = "GLOB"; break;
case SQLITE_INDEX_CONSTRAINT_REGEXP: zOp = "REGEXP"; break;
case SQLITE_INDEX_CONSTRAINT_NE: zOp = "<>"; break;
case SQLITE_INDEX_CONSTRAINT_IS: zOp = "IS"; break;
}
if( zOp ){
n++;
p->aConstraintUsage[i].argvIndex = n;
sqlite3_str_appendf(pSql, " %s (\"%w\" %s ?%d)",
zSep, pTab->azCol[iCol], zOp, n);
zSep = "AND";
}
}
zSql = sqlite3_str_finish(pSql);
if( zSql==0 ){
return SQLITE_NOMEM;
}
rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pStmt, 0);
if( rc==SQLITE_OK ){
int x = sqlite3_stmt_status(pStmt, SQLITE_STMTSTATUS_EST_COST, 0);
p->estimatedCost = pow(2.0, 0.1*x);
p->estimatedRows =
sqlite3_stmt_status(pStmt, SQLITE_STMTSTATUS_EST_ROWS, 0);
p->idxStr = zSql;
p->needToFreeIdxStr = 1;
}else{
sqlite3_free(zSql);
}
sqlite3_finalize(pStmt);
return rc;
}
/*
** This following structure defines all the methods for the
** virtual table.
*/
static sqlite3_module shardvtabModule = {
/* iVersion */ 0,
/* xCreate */ shardvtabConnect,
/* xConnect */ shardvtabConnect,
/* xBestIndex */ shardvtabBestIndex,
/* xDisconnect */ shardvtabDisconnect,
/* xDestroy */ shardvtabDisconnect,
/* xOpen */ shardvtabOpen,
/* xClose */ shardvtabClose,
/* xFilter */ shardvtabFilter,
/* xNext */ shardvtabNext,
/* xEof */ shardvtabEof,
/* xColumn */ shardvtabColumn,
/* xRowid */ shardvtabRowid,
/* xUpdate */ 0,
/* xBegin */ 0,
/* xSync */ 0,
/* xCommit */ 0,
/* xRollback */ 0,
/* xFindMethod */ 0,
/* xRename */ 0,
/* xSavepoint */ 0,
/* xRelease */ 0,
/* xRollbackTo */ 0,
/* xShadowName */ 0
};
#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_shardvtab_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
){
int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);
rc = sqlite3_create_module(db, "shardvtab", &shardvtabModule, 0);
return rc;
}
+4 -4
View File
@@ -89,16 +89,16 @@ proc step_rbu_legacy {target rbu} {
proc do_rbu_vacuum_test {tn step {statedb state.db}} {
forcedelete $statedb
if {$statedb=="" && $step==1} breakpoint
uplevel [list do_test $tn.1 [string map [list %state% $statedb %step% $step] {
if {%step%==0} { sqlite3rbu_vacuum rbu test.db {%state%}}
uplevel [list do_test $tn.1 [string map [list %state% $statedb] {
if {$step==0} { sqlite3rbu_vacuum rbu test.db {%state%}}
while 1 {
if {%step%==1} { sqlite3rbu_vacuum rbu test.db {%state%}}
if {$step==1} { sqlite3rbu_vacuum rbu test.db {%state%}}
set state [rbu state]
check_prestep_state test.db $state
set rc [rbu step]
check_poststep_state $rc test.db $state
if {$rc!="SQLITE_OK"} break
if {%step%==1} { rbu close }
if {$step==1} { rbu close }
}
rbu close
}] {SQLITE_DONE}]
+2
View File
@@ -83,6 +83,7 @@ foreach {fault errlist} {
do_faultsim_test 3 -faults $fault -prep {
faultsim_restore_and_reopen
forcedelete test.db2
} -body {
sqlite3rbu_vacuum rbu test.db test.db2
rbu step
@@ -90,6 +91,7 @@ foreach {fault errlist} {
} -test {
eval [list faultsim_test_result {0 SQLITE_OK} {*}$::errlist]
}
}
finish_test
-80
View File
@@ -1,80 +0,0 @@
# 2014 August 30
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
source [file join [file dirname [info script]] rbu_common.tcl]
set ::testprefix rbumisc
db close
sqlite3_shutdown
sqlite3_config_uri 1
reset_db
#-------------------------------------------------------------------------
# Ensure that RBU is not confused by oddly named tables in an RBU
# database.
#
do_execsql_test 1.0 {
CREATE TABLE x1(a, b, c INTEGER PRIMARY KEY);
}
do_test 1.1 {
forcedelete rbu.db
sqlite3 rbu rbu.db
rbu eval {
CREATE TABLE data_x1(a, b, c, rbu_control);
INSERT INTO data_x1 VALUES(1, 1, 1, 0);
INSERT INTO data_x1 VALUES(2, 2, 2, 0);
CREATE TABLE dat(a, b, c, rbu_control);
CREATE TABLE "data x1"(a, b, c, rbu_control);
CREATE TABLE datax1(a, b, c, rbu_control);
CREATE TABLE data_(a, b, c, rbu_control);
INSERT INTO "data x1" VALUES(3, 3, 3, 0);
INSERT INTO datax1 VALUES(3, 3, 3, 0);
INSERT INTO data_ VALUES(3, 3, 3, 0);
INSERT INTO dat VALUES(3, 3, 3, 0);
}
rbu close
} {}
do_test 1.2 {
step_rbu test.db rbu.db
db eval { SELECT * FROM x1 }
} {1 1 1 2 2 2}
do_test 1.3 {
db eval { DELETE FROM x1 }
sqlite3 rbu rbu.db
rbu eval { DELETE FROM rbu_state }
rbu close
step_rbu test.db rbu.db
db eval { SELECT * FROM x1 }
} {1 1 1 2 2 2}
do_test 1.4 {
db eval { DELETE FROM x1 }
sqlite3 rbu rbu.db
rbu eval { DELETE FROM rbu_state }
rbu close
sqlite3rbu rbu test.db rbu.db
rbu step
rbu step
rbu close
forcecopy test.db-oal test.db-wal
sqlite3rbu rbu test.db rbu.db
rbu step
list [catch { rbu close } msg] $msg
} {1 {SQLITE_ERROR - cannot update wal mode database}}
finish_test
-4
View File
@@ -80,10 +80,6 @@ foreach {tn without_rowid a b c d} {
set step 0
do_rbu_vacuum_test $tn.1.5 0
do_test $tn.1.6 {
execsql { PRAGMA integrity_check }
} {ok}
}]
}
-1
View File
@@ -65,7 +65,6 @@ proc step_rbu_cachesize {target rbu stepsize cachesize temp_limit} {
while 1 {
sqlite3rbu rbu $target $rbu
rbu temp_size_limit $temp_limit
if { [rbu temp_size_limit -1]!=$temp_limit } { error "round trip problem!" }
sqlite3_exec_nr [rbu db 1] "PRAGMA cache_size = $cachesize"
for {set i 0} {$i < $stepsize} {incr i} {
set rc [rbu step]
-116
View File
@@ -1,116 +0,0 @@
# 2019 Jan 3
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file contains tests for the RBU module. More specifically, it
# contains tests to ensure that the sqlite3rbu_vacuum() API works as
# expected.
#
source [file join [file dirname [info script]] rbu_common.tcl]
set testprefix rbuvacuum4
set step 1
do_execsql_test 1.0 {
CREATE TABLE t1(a PRIMARY KEY, b, c) WITHOUT ROWID;
INSERT INTO t1 VALUES(1, 2, 3);
INSERT INTO t1 VALUES(4, 5, 6);
INSERT INTO t1 VALUES(7, 8, 9);
}
do_rbu_vacuum_test 1.1 1
#-------------------------------------------------------------------------
reset_db
do_execsql_test 2.0 {
CREATE TABLE t1(a, b, c, PRIMARY KEY(a, b, c)) WITHOUT ROWID;
INSERT INTO t1 VALUES(1, 2, 3);
INSERT INTO t1 VALUES(4, 5, 6);
INSERT INTO t1 VALUES(7, 8, 9);
}
do_rbu_vacuum_test 2.1 1
do_execsql_test 2.2 {
SELECT * FROM t1;
} {1 2 3 4 5 6 7 8 9}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 3.0 {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
CREATE INDEX i1 oN t1(b, c);
INSERT INTO t1 VALUES(1, 2, 3);
INSERT INTO t1 VALUES(4, 5, 6);
INSERT INTO t1 VALUES(7, 8, 9);
CREATE TABLE t2(a, b, c INTEGER, PRIMARY KEY(c));
CREATE INDEX i2 oN t2(b, a);
INSERT INTO t2 VALUES('a', 'b', -1);
INSERT INTO t2 VALUES('c', 'd', -2);
INSERT INTO t2 VALUES('e', 'f', -3);
}
do_rbu_vacuum_test 3.1 1
do_execsql_test 3.2 {
SELECT * FROM t1;
SELECT * FROM t2;
} {1 2 3 4 5 6 7 8 9 e f -3 c d -2 a b -1}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 4.0 {
CREATE TABLE x1(a, b, c, d, PRIMARY KEY(c, b)) WITHOUT ROWID;
INSERT INTO x1 VALUES(1, 1, 1, 1);
INSERT INTO x1 VALUES(1, 1, 2, 1);
INSERT INTO x1 VALUES(1, 2, 2, 1);
INSERT INTO x1 VALUES(NULL, 2, 3, NULL);
INSERT INTO x1 VALUES(NULL, 2, 4, NULL);
INSERT INTO x1 VALUES(NULL, 2, 5, NULL);
CREATE INDEX x1ad ON x1(d, a);
CREATE INDEX x1null ON x1(d, a) WHERE d>15;
}
do_rbu_vacuum_test 4.1.1 1
do_execsql_test 4.2 {
SELECT count(*) fROM x1
} 6
do_rbu_vacuum_test 4.1.2 0
#-------------------------------------------------------------------------
reset_db
do_execsql_test 5.0 {
CREATE TABLE "a b c"(a, "b b" PRIMARY KEY, "c c");
CREATE INDEX abc1 ON "a b c"(a, "c c");
INSERT INTO "a b c" VALUES(NULL, 'a', NULL);
INSERT INTO "a b c" VALUES(NULL, 'b', NULL);
INSERT INTO "a b c" VALUES(NULL, 'c', NULL);
INSERT INTO "a b c" VALUES(1, 2, 3);
INSERT INTO "a b c" VALUES(3, 9, 1);
INSERT INTO "a b c" VALUES('aaa', 'bbb', 'ccc');
CREATE INDEX abc2 ON "a b c"("c c" DESC, a);
CREATE TABLE x(a);
INSERT INTO x VALUES('a'), ('b'), ('d');
CREATE UNIQUE INDEX y ON x(a);
}
do_rbu_vacuum_test 5.1 1
finish_test
+15 -265
View File
@@ -930,8 +930,7 @@ static void rbuTargetNameFunc(
zIn = (const char*)sqlite3_value_text(argv[0]);
if( zIn ){
if( rbuIsVacuum(p) ){
assert( argc==2 );
if( 0==sqlite3_value_int(argv[1]) ){
if( argc==1 || 0==sqlite3_value_int(argv[1]) ){
sqlite3_result_text(pCtx, zIn, -1, SQLITE_STATIC);
}
}else{
@@ -1382,8 +1381,7 @@ static int rbuObjIterCacheTableInfo(sqlite3rbu *p, RbuObjIter *pIter){
}
pIter->azTblType[iOrder] = rbuStrndup(zType, &p->rc);
assert( iPk>=0 );
pIter->abTblPk[iOrder] = (u8)iPk;
pIter->abTblPk[iOrder] = (iPk!=0);
pIter->abNotNull[iOrder] = (u8)bNotNull || (iPk!=0);
iOrder++;
}
@@ -1418,213 +1416,6 @@ static char *rbuObjIterGetCollist(
return zList;
}
/*
** Return a comma separated list of the quoted PRIMARY KEY column names,
** in order, for the current table. Before each column name, add the text
** zPre. After each column name, add the zPost text. Use zSeparator as
** the separator text (usually ", ").
*/
static char *rbuObjIterGetPkList(
sqlite3rbu *p, /* RBU object */
RbuObjIter *pIter, /* Object iterator for column names */
const char *zPre, /* Before each quoted column name */
const char *zSeparator, /* Separator to use between columns */
const char *zPost /* After each quoted column name */
){
int iPk = 1;
char *zRet = 0;
const char *zSep = "";
while( 1 ){
int i;
for(i=0; i<pIter->nTblCol; i++){
if( (int)pIter->abTblPk[i]==iPk ){
const char *zCol = pIter->azTblCol[i];
zRet = rbuMPrintf(p, "%z%s%s\"%w\"%s", zRet, zSep, zPre, zCol, zPost);
zSep = zSeparator;
break;
}
}
if( i==pIter->nTblCol ) break;
iPk++;
}
return zRet;
}
/*
** This function is called as part of restarting an RBU vacuum within
** stage 1 of the process (while the *-oal file is being built) while
** updating a table (not an index). The table may be a rowid table or
** a WITHOUT ROWID table. It queries the target database to find the
** largest key that has already been written to the target table and
** constructs a WHERE clause that can be used to extract the remaining
** rows from the source table. For a rowid table, the WHERE clause
** is of the form:
**
** "WHERE _rowid_ > ?"
**
** and for WITHOUT ROWID tables:
**
** "WHERE (key1, key2) > (?, ?)"
**
** Instead of "?" placeholders, the actual WHERE clauses created by
** this function contain literal SQL values.
*/
static char *rbuVacuumTableStart(
sqlite3rbu *p, /* RBU handle */
RbuObjIter *pIter, /* RBU iterator object */
int bRowid, /* True for a rowid table */
const char *zWrite /* Target table name prefix */
){
sqlite3_stmt *pMax = 0;
char *zRet = 0;
if( bRowid ){
p->rc = prepareFreeAndCollectError(p->dbMain, &pMax, &p->zErrmsg,
sqlite3_mprintf(
"SELECT max(_rowid_) FROM \"%s%w\"", zWrite, pIter->zTbl
)
);
if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pMax) ){
sqlite3_int64 iMax = sqlite3_column_int64(pMax, 0);
zRet = rbuMPrintf(p, " WHERE _rowid_ > %lld ", iMax);
}
rbuFinalize(p, pMax);
}else{
char *zOrder = rbuObjIterGetPkList(p, pIter, "", ", ", " DESC");
char *zSelect = rbuObjIterGetPkList(p, pIter, "quote(", "||','||", ")");
char *zList = rbuObjIterGetPkList(p, pIter, "", ", ", "");
if( p->rc==SQLITE_OK ){
p->rc = prepareFreeAndCollectError(p->dbMain, &pMax, &p->zErrmsg,
sqlite3_mprintf(
"SELECT %s FROM \"%s%w\" ORDER BY %s LIMIT 1",
zSelect, zWrite, pIter->zTbl, zOrder
)
);
if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pMax) ){
const char *zVal = (const char*)sqlite3_column_text(pMax, 0);
zRet = rbuMPrintf(p, " WHERE (%s) > (%s) ", zList, zVal);
}
rbuFinalize(p, pMax);
}
sqlite3_free(zOrder);
sqlite3_free(zSelect);
sqlite3_free(zList);
}
return zRet;
}
/*
** This function is called as part of restating an RBU vacuum when the
** current operation is writing content to an index. If possible, it
** queries the target index b-tree for the largest key already written to
** it, then composes and returns an expression that can be used in a WHERE
** clause to select the remaining required rows from the source table.
** It is only possible to return such an expression if:
**
** * The index contains no DESC columns, and
** * The last key written to the index before the operation was
** suspended does not contain any NULL values.
**
** The expression is of the form:
**
** (index-field1, index-field2, ...) > (?, ?, ...)
**
** except that the "?" placeholders are replaced with literal values.
**
** If the expression cannot be created, NULL is returned. In this case,
** the caller has to use an OFFSET clause to extract only the required
** rows from the sourct table, just as it does for an RBU update operation.
*/
char *rbuVacuumIndexStart(
sqlite3rbu *p, /* RBU handle */
RbuObjIter *pIter /* RBU iterator object */
){
char *zOrder = 0;
char *zLhs = 0;
char *zSelect = 0;
char *zVector = 0;
char *zRet = 0;
int bFailed = 0;
const char *zSep = "";
int iCol = 0;
sqlite3_stmt *pXInfo = 0;
p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg,
sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", pIter->zIdx)
);
while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){
int iCid = sqlite3_column_int(pXInfo, 1);
const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4);
const char *zCol;
if( sqlite3_column_int(pXInfo, 3) ){
bFailed = 1;
break;
}
if( iCid<0 ){
if( pIter->eType==RBU_PK_IPK ){
int i;
for(i=0; pIter->abTblPk[i]==0; i++);
assert( i<pIter->nTblCol );
zCol = pIter->azTblCol[i];
}else{
zCol = "_rowid_";
}
}else{
zCol = pIter->azTblCol[iCid];
}
zLhs = rbuMPrintf(p, "%z%s \"%w\" COLLATE %Q",
zLhs, zSep, zCol, zCollate
);
zOrder = rbuMPrintf(p, "%z%s \"rbu_imp_%d%w\" COLLATE %Q DESC",
zOrder, zSep, iCol, zCol, zCollate
);
zSelect = rbuMPrintf(p, "%z%s quote(\"rbu_imp_%d%w\")",
zSelect, zSep, iCol, zCol
);
zSep = ", ";
iCol++;
}
rbuFinalize(p, pXInfo);
if( bFailed ) goto index_start_out;
if( p->rc==SQLITE_OK ){
sqlite3_stmt *pSel = 0;
p->rc = prepareFreeAndCollectError(p->dbMain, &pSel, &p->zErrmsg,
sqlite3_mprintf("SELECT %s FROM \"rbu_imp_%w\" ORDER BY %s LIMIT 1",
zSelect, pIter->zTbl, zOrder
)
);
if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSel) ){
zSep = "";
for(iCol=0; iCol<pIter->nCol; iCol++){
const char *zQuoted = (const char*)sqlite3_column_text(pSel, iCol);
if( zQuoted[0]=='N' ){
bFailed = 1;
break;
}
zVector = rbuMPrintf(p, "%z%s%s", zVector, zSep, zQuoted);
zSep = ", ";
}
if( !bFailed ){
zRet = rbuMPrintf(p, "(%s) > (%s)", zLhs, zVector);
}
}
rbuFinalize(p, pSel);
}
index_start_out:
sqlite3_free(zOrder);
sqlite3_free(zSelect);
sqlite3_free(zVector);
sqlite3_free(zLhs);
return zRet;
}
/*
** This function is used to create a SELECT list (the list of SQL
** expressions that follows a SELECT keyword) for a SELECT statement
@@ -2301,24 +2092,12 @@ static int rbuObjIterPrepareAll(
if( p->rc==SQLITE_OK ){
char *zSql;
if( rbuIsVacuum(p) ){
char *zStart = 0;
if( nOffset ){
zStart = rbuVacuumIndexStart(p, pIter);
if( zStart ){
sqlite3_free(zLimit);
zLimit = 0;
}
}
zSql = sqlite3_mprintf(
"SELECT %s, 0 AS rbu_control FROM '%q' %s %s %s ORDER BY %s%s",
"SELECT %s, 0 AS rbu_control FROM '%q' %s ORDER BY %s%s",
zCollist,
pIter->zDataTbl,
zPart,
(zStart ? (zPart ? "AND" : "WHERE") : ""), zStart,
zCollist, zLimit
zPart, zCollist, zLimit
);
sqlite3_free(zStart);
}else
if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){
@@ -2341,11 +2120,7 @@ static int rbuObjIterPrepareAll(
zCollist, zLimit
);
}
if( p->rc==SQLITE_OK ){
p->rc = prepareFreeAndCollectError(p->dbRbu,&pIter->pSelect,pz,zSql);
}else{
sqlite3_free(zSql);
}
p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz, zSql);
}
sqlite3_free(zImposterCols);
@@ -2445,42 +2220,18 @@ static int rbuObjIterPrepareAll(
/* Create the SELECT statement to read keys from data_xxx */
if( p->rc==SQLITE_OK ){
const char *zRbuRowid = "";
char *zStart = 0;
char *zOrder = 0;
if( bRbuRowid ){
zRbuRowid = rbuIsVacuum(p) ? ",_rowid_ " : ",rbu_rowid";
}
if( rbuIsVacuum(p) ){
if( nOffset ){
zStart = rbuVacuumTableStart(p, pIter, bRbuRowid, zWrite);
if( zStart ){
sqlite3_free(zLimit);
zLimit = 0;
}
}
if( bRbuRowid ){
zOrder = rbuMPrintf(p, "_rowid_");
}else{
zOrder = rbuObjIterGetPkList(p, pIter, "", ", ", "");
}
}
if( p->rc==SQLITE_OK ){
p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz,
sqlite3_mprintf(
"SELECT %s,%s rbu_control%s FROM '%q'%s %s %s %s",
zCollist,
(rbuIsVacuum(p) ? "0 AS " : ""),
zRbuRowid,
pIter->zDataTbl, (zStart ? zStart : ""),
(zOrder ? "ORDER BY" : ""), zOrder,
zLimit
)
);
}
sqlite3_free(zStart);
sqlite3_free(zOrder);
p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz,
sqlite3_mprintf(
"SELECT %s,%s rbu_control%s FROM '%q'%s",
zCollist,
(rbuIsVacuum(p) ? "0 AS " : ""),
zRbuRowid,
pIter->zDataTbl, zLimit
)
);
}
sqlite3_free(zWhere);
@@ -5050,8 +4801,7 @@ static int rbuVfsAccess(
*/
if( rc==SQLITE_OK && flags==SQLITE_ACCESS_EXISTS ){
rbu_file *pDb = rbuFindMaindb(pRbuVfs, zPath, 1);
if( pDb && pDb->pRbu->eStage==RBU_STAGE_OAL ){
assert( pDb->pRbu );
if( pDb && pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){
if( *pResOut ){
rc = SQLITE_CANTOPEN;
}else{
-1
View File
@@ -738,7 +738,6 @@ SHELL_SRC = \
$(TOP)/ext/expert/sqlite3expert.h \
$(TOP)/ext/misc/zipfile.c \
$(TOP)/ext/misc/memtrace.c \
$(TOP)/ext/misc/dbdata.c \
$(TOP)/src/test_windirent.c
shell.c: $(SHELL_SRC) $(TOP)/tool/mkshellc.tcl
+68 -77
View File
@@ -1,5 +1,5 @@
C Fix\ssome\sharmless\scompiler\swarnings.
D 2019-05-10T16:16:19.390
C Add\sthe\sshardvtab\svirtual\stable\sthat\suses\sthe\snew\scost\sestimation\sfunctions.
D 2019-04-27T20:39:38.045
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -284,7 +284,6 @@ F ext/misc/closure.c dbfd8543b2a017ae6b1a5843986b22ddf99ff126ec9634a2f4047cd14c8
F ext/misc/completion.c cec672d40604075bb341a7f11ac48393efdcd90a979269b8fe7977ea62d0547f
F ext/misc/compress.c dd4f8a6d0baccff3c694757db5b430f3bbd821d8686d1fc24df55cf9f035b189
F ext/misc/csv.c 7f047aeb68f5802e7ce6639292095d622a488bb43526ed04810e0649faa71ceb
F ext/misc/dbdata.c e316fba936571584e55abd5b974a32a191727a6b746053a0c9d439bd2cf93940
F ext/misc/dbdump.c baf6e37447c9d6968417b1cd34cbedb0b0ab3f91b5329501d8a8d5be3287c336
F ext/misc/eval.c 4b4757592d00fd32e44c7a067e6a0e4839c81a4d57abc4131ee7806d1be3104e
F ext/misc/explain.c d5c12962d79913ef774b297006872af1fccda388f61a11d37758f9179a09551f
@@ -307,6 +306,7 @@ F ext/misc/rot13.c 540a169cb0d74f15522a8930b0cccdcb37a4fd071d219a5a083a319fc6e8d
F ext/misc/scrub.c db9fff56fed322ca587d73727c6021b11ae79ce3f31b389e1d82891d144f22ad
F ext/misc/series.c 0c97f63378fddc9f425e82ba139b9aaf902211f24ced115c2b6ae12b425f7334
F ext/misc/sha1.c df0a667211baa2c0612d8486acbf6331b9f8633fd4d605c17c7cccd26d59c6bd
F ext/misc/shardvtab.c 5ff824125e1cbb4040ac2646f3ab3444fdc867a617c263f04f2f4d4da6ef4667
F ext/misc/shathree.c 22ba7ca84a433d6466a7d05dcc876910b435a715da8cc462517db9351412b8c8
F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52
F ext/misc/spellfix.c f88ecb2c0294453ce8b7704b211f5350c41b085b38c8e056852e3a08b0f5e484
@@ -338,7 +338,7 @@ F ext/rbu/rbu9.test 0e4d985e25620d61920597e8ea69c871c9e8c1f5a0be2ae9fa70bb641d74
F ext/rbu/rbuA.test b34a90cb495682c25b5fc03a9d5e7a4fc99541c29256f25e2e2a4f6542b4f5b3
F ext/rbu/rbuB.test 52b07158824c6927b7e25554ace92a695cdebfc296ae3d308ac386984aded9bc
F ext/rbu/rbuC.test 80f1cc2fb74f44b1128fd0ed8eedab3a76fefeb72a947860e2869ef76fc8dc6b
F ext/rbu/rbu_common.tcl 60d904133ff843fe72cc0514e9dd2486707181e6e0fbab20979da28c48d21de9
F ext/rbu/rbu_common.tcl 4b3d033b3e3844292ae3a1aefc0e524e64b0db5a0e4310657919e4504ac3073f
F ext/rbu/rbucollate.test cac528a9a46318cba42e61258bb42660bbbf4fdb9a8c863de5a54ad0c658d197
F ext/rbu/rbucrash.test 000981a1fe8a6e4d9a684232f6a129e66a3ef595f5ed74655e2f9c68ffa613b4
F ext/rbu/rbucrash2.test efa143cc94228eb0266d3f1abfbee60a5838a84cef7cc3fcb8c145b74d96fd41
@@ -346,22 +346,20 @@ F ext/rbu/rbudiff.test 156957851136b63c143478518dc1bda6c832103cdbe8ac1d7cdd47edb
F ext/rbu/rbudor.test e3e8623926012f43eebe51fedf06a102df2640750d971596b052495f2536db20
F ext/rbu/rbufault.test 2d7f567b79d558f6e093c58808cab4354f8a174e3802f69e7790a9689b3c09f8
F ext/rbu/rbufault2.test 06e735c002c17802d93debca41f59b027e7429db7de17f2a81318ecfd3c651d4
F ext/rbu/rbufault3.test b2fcc9db5c982b869f67d1d4688d8cb515d5b92f58011fff95665f2e62cec179
F ext/rbu/rbufault3.test e0052ccba428ffdd2bb989d3ae84716f058ec5ab5f7196c64ba407b9d23c7255
F ext/rbu/rbufault4.test 03d2849c3df7d7bd14a622e789ff049e5080edd34a79cd432e01204db2a5930a
F ext/rbu/rbufts.test 0ae8d1da191c75bd776b86e24456db0fb6e97b7c944259fae5407ea55d23c31d
F ext/rbu/rbumisc.test df6201ac3263ac8c68c4f1a4803d8c006c241102eb1d30d8074b0c14e59de335
F ext/rbu/rbumulti.test 5fb139058f37ddc5a113c5b93238de915b769b7792de41b44c983bc7c18cf5b9
F ext/rbu/rbupartial.test 1c8bd6d42615b94caf08f129f5817fa26975523f0f51bceda1dca90e8114c7c4
F ext/rbu/rbupartial.test 73baf12a5941fe6891a829106a6f2e0a973f89aa49bd8659b12f547beb29b482
F ext/rbu/rbuprogress.test 04614ff8820bab9c1ec1b7dbec1edc4b45474421d4fe7abbd2a879a9c02884f9
F ext/rbu/rburesume.test dbdc4ca504e9c76375a69e5f0d91205db967dcc509a5166ca80231f8fda49eb1
F ext/rbu/rbusave.test f4190a1a86fccf84f723af5c93813365ae33feda35845ba107b59683d1cdd926
F ext/rbu/rbusplit.test b37e7b40b38760881dc9c854bd40b4744c6b6cd74990754eca3bda0f407051e8
F ext/rbu/rbutemplimit.test 05ceefa90a2e26a99f40dd48282ed63a00df5e59c1f2bfd479c143e201a1b0ba
F ext/rbu/rbutemplimit.test 7f408f49b90fa0a720d7599f3aec74a3c85e6cd78e56fdf726ce00af9147a341
F ext/rbu/rbuvacuum.test 55e101e90168c2b31df6c9638fe73dc7f7cc666b6142266d1563697d79f73534
F ext/rbu/rbuvacuum2.test b8e5b51dc8b2c0153373d024c0936be3f66f9234acbd6d0baab0869d56b14e6b
F ext/rbu/rbuvacuum3.test 8addd82e4b83b4c93fa47428eae4fd0dbf410f8512c186f38e348feb49ba03dc
F ext/rbu/rbuvacuum4.test a78898e438a44803eb2bc897ba3323373c9f277418e2d6d76e90f2f1dbccfd10
F ext/rbu/sqlite3rbu.c 311fe2c2bc73e2ddb9ee8eb10be35aca90f6074869734671f615270b1a1ce283
F ext/rbu/sqlite3rbu.c f222350c33f063cbc754001cd4e9683164c6cb06be76ae43f15b396ec6fc1993
F ext/rbu/sqlite3rbu.h 1dc88ab7bd32d0f15890ea08d23476c4198d3da3056985403991f8c9cd389812
F ext/rbu/test_rbu.c 03f6f177096a5f822d68d8e4069ad8907fe572c62ff2d19b141f59742821828a
F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15
@@ -443,7 +441,7 @@ F ext/userauth/userauth.c f81aa5a3ecacf406f170c62a144405858f6f6de51dbdc0920134e6
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
F main.mk 125adda36bb32c99dc3a11340bd029ef373b9523eac2b2af76087bfe82d4fdf8
F main.mk 23d3660f7053d196aef76938bf78b10fc3ce1831a85d96bd71565758788f34d4
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
@@ -459,13 +457,13 @@ F src/alter.c 85b41586b2527c8288b249fb0beb96f25860e5b2bf94c02f788b3d0f686354ee
F src/analyze.c 58db66344a5c58dcabb57f26696f6f2993956c830446da40b444051d2fdaf644
F src/attach.c 78e986baee90cb7b83fb9eafa79c22581a8ada14030fd633b0683c95cf11213c
F src/auth.c 0fac71038875693a937e506bceb492c5f136dd7b1249fbd4ae70b4e8da14f9df
F src/backup.c b1d37f6f7f5913944583733ed0f9e182f3ece0d42c27f46701142141a6e6fd33
F src/backup.c 78d3cecfbe28230a3a9a1793e2ead609f469be43e8f486ca996006be551857ab
F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
F src/btree.c 5e15f903fd44b076b864a8d2449d63b44a546efabb66fca7dfed90f106f5c756
F src/btree.c ffe7101006aee2ab9e9dec2fc001998e57a8e59419c6ea4072d6c3935d3d50fb
F src/btree.h c11446f07ec0e9dc85af8041cb0855c52f5359c8b2a43e47e02a685282504d89
F src/btreeInt.h 6111c15868b90669f79081039d19e7ea8674013f907710baa3c814dc3f8bfd3f
F src/build.c 23e9332b260cd0e45f6cbfabe711957a0776ea3ff836746378868fdfa64d267b
F src/build.c 61655dad911a967a69fb49df57268fd15ce8f1af3fe0a1bd90c128ef2cacfb7a
F src/callback.c 25dda5e1c2334a367b94a64077b1d06b2553369f616261ca6783c48bcb6bda73
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
F src/ctime.c 109e58d00f62e8e71ee1eb5944ac18b90171c928ab2e082e058056e1137cc20b
@@ -473,19 +471,19 @@ F src/date.c ebe1dc7c8a347117bb02570f1a931c62dd78f4a2b1b516f4837d45b7d6426957
F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7
F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319
F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf
F src/expr.c 55e71df830d43bfedd2910e45b097c445a493978b21a0544a54011db1d2fa933
F src/expr.c f65db06a0fcff760cadfb79d579a41e3eb7eff38848d5d6359137822f4fa2ec9
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F src/fkey.c 0e14d4bef8eac2d87bbd517e492d9084c65008d117823f8922c5e7b2b599bd33
F src/func.c 08d6d07d138735dd79f12a2b0c623d1dc9270d0eea61b8be584625391ef84475
F src/func.c 2ccf4ae12430b1ae7096be5f0675887e1bd0732828af0ac0f7496339b7c6edee
F src/global.c 0dea3065ea72a65ae941559b6686aad6516d4913e76fa4f79a95ff7787f624ec
F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19
F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38
F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
F src/insert.c 4ffc3aa5d2aed178b501533428a76e150907e92a1e4bf7af4ffbcb0d77e99823
F src/insert.c fc3cf5c371f9a400144e8c2f148ab29cd3f67f7da7eaf47e6a6959f8255fd92c
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
F src/loadext.c 22afc33c3a61b4fd80a60a54f1882688371e6bc64685df2696b008fce65a999c
F src/main.c 3c3925b0bcb4c45687fd52f54c79e98e379252e1d3393f8b7dcccfa26181b661
F src/main.c 16eea1ab004331312da0538dafb497cc0ed82fd9bb2e67f7684b40bf2797b666
F src/malloc.c 0f9da2a66b230a5785af94b9672126845099b57b70a32c987d04ac28c69da990
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
@@ -514,24 +512,24 @@ F src/parse.y 22f64d8a8910acd17580450513b58d64187b0962848380c7f0a39376b8a48cee
F src/pcache.c 696a01f1a6370c1b50a09c15972bc3bee3333f8fcd1f2da8e9a76b1b062c59ee
F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
F src/pcache1.c be64b2f3908a7f97c56c963676eb12f0d6254c95b28cdc1d73a186eff213219d
F src/pragma.c 2e9fbfcb23cb72eabb38ab6fa84c36a65f9c4839ce1e9bb3dd982ab26b67a5a8
F src/pragma.h 482c26f352efd7a4ed1354d83ffa992e13004f6528edeee44cdbfd5025a490bd
F src/pragma.c af67dedaad8bafe9a5f9adcec32a0da6dd118617dd8220ad1d118f5a6bf83a02
F src/pragma.h a776bb9c915207e9d1117b5754743ddf1bf6a39cc092a4a44e74e6cb5fab1177
F src/prepare.c 78027c6231fbb19ca186a5f5f0c0a1375d9c2cec0655273f9bd90d9ff74a34b3
F src/printf.c 67f79227273a9009d86a017619717c3f554f50b371294526da59faa6014ed2cd
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
F src/resolve.c 408632d9531ca8f1df8591f00530797daaa7bde3fe0d3211de4d431cbb99347e
F src/resolve.c 567888ee3faec14dae06519b4306201771058364a37560186a3e0e755ebc4cb8
F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93
F src/select.c ef860c7e5882c89c030432a6d2cf13c67d1d51fd511cf45cbdfd5c2faf44d51d
F src/shell.c.in 1f3e8c7032f54d3aef8653cfa5d0289afe3a08d112be8c4e69dc56c4100ac144
F src/sqlite.h.in 0605c88d98c85fbcba8bbd9716e7cc10b361e7b21cf2375171130f577388c943
F src/select.c b7304d2f491c11a03a7fbdf34bc218282ac54052377809d4dc3b4b1e7f4bfc93
F src/shell.c.in 7544d68921f2c3919da2150c1f7b53a4942c212dd59e68b7926fd903101c3cab
F src/sqlite.h.in 0c4ec0ea145005e2a458b892a8e6778d980efcd2ad36a68565b8774712eb79c1
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5
F src/sqliteInt.h 443270b81c96101914eadd4e649d2f8210f4bbed569a6ff5ca8facfc74e20f26
F src/sqliteInt.h 866311ac436c0c2039fccc7ea976fbc79d40c1c2ea687161fa4ba64379b53ae6
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
F src/tclsqlite.c cfe7f93daf9d8787f65e099efb67d7cdfc2c35236dec5d3f6758520bd3519424
F src/test1.c f4e0be5c344587b2beac474a58018a3833208fb6bbec35d37d58b1270a7a5917
F src/test1.c c02d8bc27bb61d987b6f696ef62ce583272dbdd03042a241bc5ac767d3558709
F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644
F src/test4.c 405834f6a93ec395cc4c9bb8ecebf7c3d8079e7ca16ae65e82d01afd229694bb
@@ -588,30 +586,30 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
F src/tokenize.c d3615f0cbe4db5949503bf5916f3cd4fa5de855d5b4ef560f3b6dd5629423a1e
F src/treeview.c 56724725c62a0d0f408f7c257475dc33309198afee36a1d18be1bc268b09055e
F src/trigger.c bb034c08eca111e66a19cda045903a12547c1be2294b5570d794b869d9c44a73
F src/update.c 3cb9150d2cf661d938e2f1b1749945f3faa767f88febdb739ab1793bbf895ff2
F src/update.c 0b973357d88092140531e07ff641139c26fb4380b0b9f5ed98c5f7691b4604d1
F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4
F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507
F src/util.c 4c0669e042b4e50a08a9e5fd14cecc76e5f877efa288533dccddb6fe98f4d6b5
F src/util.c 5061987401c2e8003177fa30d73196aa036727c8f04bf36a2df0c82b1904a236
F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf
F src/vdbe.c 4ab7c36d29e156835b23b6b797107f0dbdf6d729798d8cf0d33e40e411f02d68
F src/vdbe.h 712bca562eaed1c25506b9faf9680bdc75fc42e2f4a1cd518d883fa79c7a4237
F src/vdbeInt.h 3ba14553508d66f58753952d6dd287dce4ec735de02c6440858b4891aed51c17
F src/vdbeapi.c f9161e5c77f512fbb80091ce8af621d19c9556bda5e734cffaac1198407400da
F src/vdbeaux.c d444f4a3ff9c571965329a186701a57fe445e4c3f4c42f87402aca75386ba358
F src/vdbe.c 711ef421b3bb3db3b2476067b2dc3c71ef5844d9b1a723026578f89f6da621e8
F src/vdbe.h f99dbc42943d945f2aa61377dc67e571688310be51dbc9b3e4299bd0124fdd70
F src/vdbeInt.h a9089cdf0d5f4a1f076d5b22e5690b6ee2f70b1db0a4814ae1a6397c497c838b
F src/vdbeapi.c 69fae8eb6e1e762e04bfce308f8180294f98a95f7b346f6cb3a1364fd8095cdd
F src/vdbeaux.c cf9159eaf4b2ac4d0c0daa61544055d9db924989d433c1f77e2af61ebdcb6a05
F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191
F src/vdbemem.c b76b42ac9d6a36fc55a0797929fc94cc33e1334eea2792f5ee1eef868ce13320
F src/vdbemem.c dd2ee49255c4c5450f2b0887ef44cea8faa1cd7a46501b39a1a82b113ae418e3
F src/vdbesort.c 66592d478dbb46f19aed0b42222325eadb84deb40a90eebe25c6e7c1d8468f47
F src/vdbetrace.c fa3bf238002f0bbbdfb66cc8afb0cea284ff9f148d6439bc1f6f2b4c3b7143f0
F src/vtab.c 1fa256c6ddad7a81e2a4dc080d015d4b0a7135767717d311298e47f6fca64bb3
F src/vdbetrace.c 79d6dbbc479267b255a7de8080eee6e729928a0ef93ed9b0bfa5618875b48392
F src/vtab.c 4c5959e00b7a142198d178e3a822f4e05f36f2d1a3c57657373f9487154fc06b
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
F src/wal.c b09a2a9cab50efa08451a8c81d47052120ad5da174048c6d0b08d405384abdf2
F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a
F src/walker.c 7607f1a68130c028255d8d56094ea602fc402c79e1e35a46e6282849d90d5fe4
F src/where.c 99c7b718ef846ac952016083aaf4e22ede2290beceaf4730a2df55c023251369
F src/whereInt.h 1b728f71654ebf8421a1715497a587f02d6f538e819af58dc826908f8577e810
F src/wherecode.c 37a1004237d630d785c47bba2290eac652a7a8b0047518eba3cb7c808b604c4a
F src/whereexpr.c 4219bdd5d310ba6424166d918efef301c21e1b7f6444e964b415c4a5b877a8fe
F src/window.c 5be2cf7d8763cc97137fc44d015aed8a1a4a56fe9700d7933ed560172617c756
F src/where.c 3e9689df25c0410dc60ee28d81ca21ea4dcdbdd925bff764afea95ef6c105975
F src/whereInt.h 50e1ddaae281e056eb71d8209ffc194e730745fb521fa8f22d0867cc34e9f3d7
F src/wherecode.c 0e76672930bea322eb3606d891a4744be55c09bcd3a995bfd501af62a46e0625
F src/whereexpr.c 90859652920f153d2c03f075488744be2926625ebd36911bcbcb17d0d29c891c
F src/window.c 038c248267e74ff70a2bb9b1884d40fd145c5183b017823ecb6cbb14bc781478
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d
@@ -629,9 +627,9 @@ F test/altercol.test 54374d2ba18af25bb24e23acf18a60270d4ec120b7ec0558078b59d5aa1
F test/alterlegacy.test 82022721ce0de29cedc9a7af63bc9fcc078b0ee000f8283b4b6ea9c3eab2f44b
F test/altermalloc.test 167a47de41b5c638f5f5c6efb59784002b196fff70f98d9b4ed3cd74a3fb80c9
F test/altermalloc2.test fa7b1c1139ea39b8dec407cf1feb032ca8e0076bd429574969b619175ad0174b
F test/altertab.test b6901287474841cffbd8f90b098d3bd7d8445868b42caeb01b27034698f7245f
F test/altertab.test 372df7d8f09e1ee22d23551677cedff3b048b0059c1f1b9a01a6401b94a2367c
F test/altertab2.test 5d423a2d1006085b05cc1b788863d5a860ea2da21c4f892d15e2f2a34c78348a
F test/altertab3.test 2433d0cc6cb9cffe087f9138cd36818c7abd5c396804aa6e6dc8c2b80e2cd406
F test/altertab3.test 40f2ce9be675e354d3e55c72f8baf38813be975ff4dd9e6b3144493c3c5bc033
F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f
F test/analyze.test 7168c8bffa5d5cbc53c05b7e9c7fcdd24b365a1bc5046ce80c45efa3c02e6b7c
F test/analyze3.test ff62d9029e6deb2c914490c6b00caf7fae47cc85cdc046e4a0d0a4d4b87c71d8
@@ -765,7 +763,7 @@ F test/corruptH.test 79801d97ec5c2f9f3c87739aa1ec2eb786f96454
F test/corruptI.test a17bbf54fdde78d43cf3cc34b0057719fd4a173a3d824285b67dc5257c064c7b
F test/corruptJ.test 4d5ccc4bf959464229a836d60142831ef76a5aa4
F test/corruptK.test 5b4212fe346699831c5ad559a62c54e11c0611bdde1ea8423a091f9c01aa32af
F test/corruptL.test b6ea0f657b26a8fe10405a9f5970f94de47fdfcc02fce2a635954aef13e55a88
F test/corruptL.test 13763e4769eeef308badfcc95dea5d5e00e61a1732a1214a48ff24d3f5db8cbc
F test/cost.test 51f4fcaae6e78ad5a57096831259ed6c760e2ac6876836e91c00030fad385b34
F test/count.test cb2e0f934c6eb33670044520748d2ecccd46259c
F test/countofview.test e3d4cd6900e4e4f074968ab24b8b87d3671cd624961bef40fd3a6b8f574343cf
@@ -789,7 +787,6 @@ F test/cursorhint2.test 6f3aa9cb19e7418967a10ec6905209bcbb5968054da855fc36c8beee
F test/dataversion1.test 6e5e86ac681f0782e766ebcb56c019ae001522d114e0e111e5ebf68ccf2a7bb8
F test/date.test 9b73bbeb1b82d9c1f44dec5cf563bf7da58d2373
F test/date2.test 74c234bece1b016e94dd4ef9c8cc7a199a8806c0e2291cab7ba64bace6350b10
F test/dbdata.test 042f49acff3438f940eeba5868d3af080ae64ddf26ae78f80c92bec3ca7d8603
F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e
F test/dbfuzz001.test e32d14465f1c77712896fda6a1ccc0f037b481c191c1696a9c44f6c9e4964faf
F test/dbfuzz2-seed1.db e6225c6f3d7b63f9c5b6867146a5f329d997ab105bee64644dc2b3a2f2aebaee
@@ -819,7 +816,7 @@ F test/e_createtable.test 1c602347e73ab80b11b9fa083f47155861aaafcff8054aac9e0b76
F test/e_delete.test ab39084f26ae1f033c940b70ebdbbd523dc4962e
F test/e_droptrigger.test 3cd080807622c13e5bbb61fc9a57bd7754da2412
F test/e_dropview.test 21ce09c361227ddbc9819a5608ee2700c276bdd5
F test/e_expr.test 698c8c6e9b4b737f494c39b2210a3eb7af0efd8167137844483b7add5c76a951
F test/e_expr.test ca8896601ade1e27c6559614c7f32c63d44636fdfa720436a160f09b8bf66c89
F test/e_fkey.test 2febb2084aef9b0186782421c07bc9d377abf067c9cb4efd49d9647ae31f5afe
F test/e_fts3.test 17ba7c373aba4d4f5696ba147ee23fd1a1ef70782af050e03e262ca187c5ee07
F test/e_insert.test f02f7f17852b2163732c6611d193f84fc67bc641fb4882c77a464076e5eba80e
@@ -859,8 +856,8 @@ F test/fkey3.test 76d475c80b84ee7a5d062e56ccb6ea68882e2b49
F test/fkey4.test 86446017011273aad8f9a99c1a65019e7bd9ca9d
F test/fkey5.test 24dd28eb3d9f1b5a174f47e9899ace5facb08373a4223593c8c631e6cf9f7d5a
F test/fkey6.test d078a1e323a740062bed38df32b8a736fd320dc0
F test/fkey7.test 64fb28da03da5dfe3cdef5967aa7e832c2507bf7fb8f0780cacbca1f2338d031
F test/fkey8.test 1d44df25d3b9cba72db4b4324201daf6ae1fc8a85cb68146bd6669a977d8867d
F test/fkey7.test 24076d43d3449f12f25503909ca4bfb5fc5fefd5af1f930723a496343eb28454
F test/fkey8.test 863c6d84f0d289fd2c1a1c293abb9803f77efd35211d9012c0986c8f6ccf5d5a
F test/fkey_malloc.test 594a7ea1fbab553c036c70813cd8bd9407d63749
F test/fordelete.test eb93a2f34137bb87bdab88fcab06c0bd92719aff
F test/format4.test 1f0cac8ff3895e9359ed87e41aaabee982a812eb
@@ -977,11 +974,10 @@ F test/fts4merge4.test d895b1057a7798b67e03455d0fa50e9ea836c47b
F test/fts4noti.test 5553d7bb2e20bf4a06b23e849352efc022ce6309
F test/fts4onepass.test d69ddc4ee3415e40b0c5d1d0408488a87614d4f63ba9c44f3e52db541d6b7cc7
F test/fts4opt.test 0fd0cc84000743ff2a883b9b84b4a5be07249f0ba790c8848a757164cdd46b2a
F test/fts4rename.test 6015a355ec3a11a51eb5b88802b3b2c1788786c54b77b17f3e077b7c93ff8611
F test/fts4umlaut.test fcaca4471de7e78c9d1f7e8976e3e8704d7d8ad979d57a739d00f3f757380429
F test/fts4unicode.test ceca76422abc251818cb25dabe33d3c3970da5f7c90e1540f190824e6b3a7c95
F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d
F test/func.test e4313baba80bf933e58eb89a7c617bec0f0c348c862b096ec4387f36e05ad0a6
F test/func.test 150270b6e2e0281697c116e5ca0e46b41ace8d34b1c92461d88fdd9968c9b03c
F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f
F test/func3.test d202a7606d23f90988a664e88e268aed1087c11c
F test/func4.test 6beacdfcb0e18c358e6c2dcacf1b65d1fa80955f
@@ -1001,8 +997,8 @@ F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba
F test/fuzzdata4.db b502c7d5498261715812dd8b3c2005bad08b3a26e6489414bd13926cd3e42ed2
F test/fuzzdata5.db e35f64af17ec48926481cfaf3b3855e436bd40d1cfe2d59a9474cb4b748a52a5
F test/fuzzdata6.db 92a80e4afc172c24f662a10a612d188fb272de4a9bd19e017927c95f737de6d7
F test/fuzzdata7.db 2b13f8d7a4e475f164c733e64c9ebc459424ec58d0876ef103de62c1a99e2fca
F test/fuzzdata8.db 038627908808f88bad9c3ac90f3b7865766f92b2cfed585c7e083a792d554ade
F test/fuzzdata7.db f46c9a5698c1ca75ca6280c7c879a3f46dc82fe4b1ce246827496b806488952d
F test/fuzzdata8.db 1786362da75b8696f804b0b4548b59830e148718bce827548c006031105e7783
F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8
F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14
F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536
@@ -1033,13 +1029,13 @@ F test/incrvacuum.test 2aaee202b1f230e55779f70d155f6ba67bbdff8481d650214d256ab0f
F test/incrvacuum2.test 7d26cfda66c7e55898d196de54ac4ec7d86a4e3d
F test/incrvacuum3.test 75256fb1377e7c39ef2de62bfc42bbff67be295a
F test/incrvacuum_ioerr.test 6ae2f783424e47a0033304808fe27789cf93e635
F test/index.test a2e948ed949e575487b5c1d521767d4584ac42d352f2dcd8e48004638e7bc7dc
F test/index.test df4cddf4435314a948237fdfa9acee67de21f7bebc789beab4b89b575b4f6a70
F test/index2.test f835d5e13ca163bd78c4459ca15fd2e4ed487407
F test/index3.test 51685f39345462b84fcf77eb8537af847fdf438cc96b05c45d6aaca4e473ade0
F test/index4.test ab92e736d5946840236cd61ac3191f91a7856bf6
F test/index5.test 8621491915800ec274609e42e02a97d67e9b13e7
F test/index6.test 448fa05f5d78f5feee4832fe4017dede4ccbc660601fb7e84d02329389cb638c
F test/index7.test be02a0b4e53ac4ad7db4995fe02b428597a2e104c4f574b0d4b2f6b082e96b28
F test/index6.test 6b3e6cd4bef343ed4541e74c55936ed112962a6552c085242612b598e12910a4
F test/index7.test 72b59b8ddc5c13f4962886b4011eb9975014317d17ef36c6297921362fb7dd98
F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7
F test/index9.test 0aa3e509dddf81f93380396e40e9bb386904c1054924ba8fa9bcdfe85a8e7721
F test/indexedby.test a52c8c6abfae4fbfb51d99440de4ca1840dbacc606b05e29328a2a8ba7cd914e
@@ -1059,7 +1055,6 @@ F test/intarray.test 8319986182af37c8eb4879c6bfe9cf0074e9d43b193a4c728a0efa3417c
F test/interrupt.test 16ea879ec728cb76414c148c5f24afd5d1f91054
F test/interrupt2.test e4408ca770a6feafbadb0801e54a0dcd1a8d108d
F test/intpkey.test ac71107a49a06492b69b82aafaf225400598d3c8
F test/intreal.test 1d03e48c53224b69efc8cb7349f009e388c116790bfdb4d320b233d603aaba9a
F test/io.test f95bca1783b01ea7761671560d023360d2dfa4cc
F test/ioerr.test 470fcc78e9cd352d162baf782fe301ea807d764241f58a48fc58109c2dfcdb6b
F test/ioerr2.test 2593563599e2cc6b6b4fcf5878b177bdd5d8df26
@@ -1091,7 +1086,7 @@ F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
F test/lemon-test01.y 58b764610fd934e189ffbb0bbfa33d171b9cb06019b55bdc04d090d6767e11d7
F test/like.test 11cfd7d4ef8625389df9efc46735ff0b0b41d5e62047ef0f3bc24c380d28a7a6
F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da
F test/like3.test ac61947ef35bde9d97718bcfa04659a17d9218f1fffc4104b135b3f82ed43836
F test/like3.test 0ce2630e39e32e42ce02d171f0a315189ca71fec37c5ddfb0191eecc3fe9d4da
F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e
F test/limit2.test 9409b033284642a859fafc95f29a5a6a557bd57c1f0d7c3f554bd64ed69df77e
F test/loadext.test faa4f6eed07a5aac35d57fdd7bc07f8fc82464cfd327567c10cf0ba3c86cde04
@@ -1189,7 +1184,7 @@ F test/orderby6.test 8b38138ab0972588240b3fca0985d2e400432859
F test/orderby7.test 3d1383d52ade5b9eb3a173b3147fdd296f0202da
F test/orderby8.test 23ef1a5d72bd3adcc2f65561c654295d1b8047bd
F test/orderby9.test 87fb9548debcc2cd141c5299002dd94672fa76a3
F test/oserror.test 1fc9746b83d778e70d115049747ba19c7fba154afce7cc165b09feb6ca6abbc5
F test/oserror.test e7b3416be4b9d5dd2fe0b42dd394daaddbb6c83eeec1f0e47b120b53e0ad3ace
F test/ossfuzz.c 18af635fa73d12a109b305faca727a734c1fa28a421b161d9d15c5a84a4998a2
F test/ossshell.c f125c5bd16e537a2549aa579b328dd1c59905e7ab1338dfc210e755bb7b69f17
F test/ovfl.test 199c482696defceacee8c8e0e0ef36da62726b2f
@@ -1230,7 +1225,6 @@ F test/randexpr1.tcl 40dec52119ed3a2b8b2a773bce24b63a3a746459
F test/randexpr1.test eda062a97e60f9c38ae8d806b03b0ddf23d796df
F test/rbu.test 168573d353cd0fd10196b87b0caa322c144ef736
F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8
F test/recover.test ccb8c2623902a92ebb76770edd075cb4f75a4760bb7afde38026572c6e79070d
F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8
F test/regexp2.test 40e894223b3d6672655481493f1be12012f2b33c
F test/reindex.test 44edd3966b474468b823d481eafef0c305022254
@@ -1243,7 +1237,7 @@ F test/rollback2.test bc868d57899dc6972e2b4483faae0e03365a0556941474eec487ae21d8
F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a
F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc
F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81
F test/rowid.test 6d43c560e212f99499c31d3f75caacd0b9e059baf88b5fc31fba6b0e280f8b4c
F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d
F test/rowvalue.test b8680f07d19c8c5223b808bba998faffcec6d505f5689ff6070280119173bb51
F test/rowvalue2.test 060d238b7e5639a7c5630cb5e63e311b44efef2b
F test/rowvalue3.test 3068f508753af69884b12125995f023da0dbb256
@@ -1275,7 +1269,7 @@ F test/securedel.test 2f70b2449186a1921bd01ec9da407fbfa98c3a7a5521854c300c194b2f
F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5
F test/select1.test 7d41f354998524070317207d4e2b68e725e4cf14a57835fc746d4bea686a8714
F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56
F test/select3.test 3905450067c28766bc83ee397f6d87342de868baa60f2bcfd00f286dfbd62cb9
F test/select3.test 2ce595f8fb8e2ac10071d3b4e424cadd4634a054
F test/select4.test 5389d9895968d1196c457d59b3ee6515d771d328
F test/select5.test df9ec0d218cedceb4fe7b63262025b547b50a55e59148c6f40b60ca25f1d4546
F test/select6.test 39eac4a5c03650b2b473c532882273283ee8b7a0
@@ -1600,7 +1594,7 @@ F test/vacuum5.test 263b144d537e92ad8e9ca8a73cc6e1583f41cfd0dda9432b87f7806174a2
F test/vacuummem.test 7b42abb3208bd82dd23a7536588396f295a314f2
F test/varint.test bbce22cda8fc4d135bcc2b589574be8410614e62
F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661
F test/view.test ee9262cee79c7f4002fd2869887d3e8eccf70d9a4e1016f847242851edb18964
F test/view.test 71e1bf4c0e2e0d37c84d7db5b33cd47eb4a7662c19d93ede4112b350b186f61f
F test/vtab1.test 60b4f70aafa6078d6fdfc11417af3bd216d7ef5eafce16707a6ca3dae5166d20
F test/vtab2.test 14d4ab26cee13ba6cf5c5601b158e4f57552d3b055cdd9406cf7f711e9c84082
F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e
@@ -1659,7 +1653,7 @@ F test/walslow.test c05c68d4dc2700a982f89133ce103a1a84cc285f
F test/walthread.test 14b20fcfa6ae152f5d8e12f5dc8a8a724b7ef189f5d8ef1e2ceab79f2af51747
F test/walvfs.test c0faffda13d045a96dfc541347886bb1a3d6f3205857fc98e683edfab766ea88
F test/wapp.tcl b440cd8cf57953d3a49e7ee81e6a18f18efdaf113b69f7d8482b0710a64566ec
F test/wapptest.tcl f387e81750b2938ccf445b8a061541626a4a31f55e9e500b3e38ef3ce177bc61 x
F test/wapptest.tcl 78aff97afe76fd9728cf5f84710a772412735bc68a612b4789279072177a424e x
F test/where.test 0607caa5a1fbfe7b93b95705981b463a3a0408038f22ae6e9dc11b36902b0e95
F test/where2.test 478d2170637b9211f593120648858593bf2445a1
F test/where3.test 2341a294e17193a6b1699ea7f192124a5286ca6acfcc3f4b06d16c931fbcda2c
@@ -1691,8 +1685,8 @@ F test/win32lock.test fbf107c91d8f5512be5a5b87c4c42ab9fdd54972
F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d
F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc
F test/window1.test 8d453bfaa3f8f0873ba16ca1270c7368f18445065a0003a1b5954ac4e95797b4
F test/window2.tcl 0c2918ef2a1640553fd791972d458356808a608418c64c02a0a379cecfc7fb0d
F test/window2.test 96ef949f0197c025652f6c6e5812cdbfb948989bd40cf79cbb02104249a89513
F test/window2.tcl 9bfa842d8a62b0d36dc8c1b5972206393c43847433c6d75940b87fec93ce3143
F test/window2.test 8e6d2a1b9f54dfebee1cde961c8590cd87b4db45c50f44947a211e1b63c2a05e
F test/window3.tcl acea6e86a4324a210fd608d06741010ca83ded9fde438341cb978c49928faf03
F test/window3.test e9959a993c8a71e96433be8daaa1827d78b8921e4f12debd7bdbeb3c856ef3cb
F test/window4.tcl 5fbaab489677914ee5686b2008426e336daf88a2f58be7df92757f780a5ebf91
@@ -1708,10 +1702,10 @@ F test/windowerr.test 675b5e6debfc9370bfacb0b91e2a93a8923512f92600b16f4ea70a1cd9
F test/windowfault.test 16e906a2c4110c88372ff4bd5de59ac7397ec2f025912eff8e5677eedd126898
F test/with1.test a07b5aad7f77acdf13e52e8814ea94606fcc72e9ea4c99baf293e9d7c63940be
F test/with2.test e0030e2f0267a910d6c0e4f46f2dfe941c1cc0d4f659ba69b3597728e7e8f1ab
F test/with3.test b5f1372097690c6ef84db2f13fc7e64a88c7263c3f88493605f90597e8a68d45
F test/with3.test 8d26920c88283e0a473ceebd3451554922108ce7b2a6a1157c47eb0a7011212c
F test/with4.test 257be66c0c67fee1defbbac0f685c3465e2cad037f21ce65f23f86084f198205
F test/withM.test 693b61765f2b387b5e3e24a4536e2e82de15ff64
F test/without_rowid1.test 7ac016d20317e36a2f142e960679e558e74f6809ce5f27bde668af01782500df
F test/without_rowid1.test b5ec93f7df2c1d684e0923247dac6aca8888e088bf50a9f244c3933e0e813a72
F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99
F test/without_rowid3.test ea4b59dd1b0d7f5f5e4b7cca978cdb905752a9d7c57dc4344a591dba765a3691
F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a
@@ -1744,7 +1738,7 @@ F tool/genfkey.test b6afd7b825d797a1e1274f519ab5695373552ecad5cd373530c63533638a
F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce
F tool/index_usage.c 9ec344d29cbeb03fdc0fce668eedfb7495792170de933adf95cf8d6904a166ad
F tool/kvtest-speed.sh 4761a9c4b3530907562314d7757995787f7aef8f
F tool/lemon.c dbcb617f0d815a60c2cb5fedc09ac575af0ba7026b48726c7f80a5a20a5ba345
F tool/lemon.c 900a15b9efba9890d10e7959914db94c4ad5162912127f061c4328add122d6fb
F tool/lempar.c 61af95b8fac2bfd59c09d55330e78f3f5e352d7aa80bf37404b96ef795be3fdc
F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9
F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862
@@ -1758,8 +1752,8 @@ F tool/mkmsvcmin.tcl cad0c7b54d7dd92bc87d59f36d4cc4f070eb2e625f14159dc2f5c4204e6
F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c
F tool/mkopcodeh.tcl 352a4319c0ad869eb26442bf7c3b015aa15594c21f1cce5a6420dbe999367c21
F tool/mkopts.tcl 680f785fdb09729fd9ac50632413da4eadbdf9071535e3f26d03795828ab07fa
F tool/mkpragmatab.tcl d8887dfbd5a40c9e5de2c011db989af52152b9bcc64059d9e93b28edf38af9b9
F tool/mkshellc.tcl 70a9978e363b0f3280ca9ce1c46d72563ff479c1930a12a7375e3881b7325712
F tool/mkpragmatab.tcl 49039adedafbc430d2959400da2e0e8f20ef8dcf6898e447c946e7d50ef5906b
F tool/mkshellc.tcl 1f45770aea226ac093a9c72f718efbb88a2a2833409ec2e1c4cecae4202626f5
F tool/mksourceid.c d458f9004c837bee87a6382228ac20d3eae3c49ea3b0a5aace936f8b60748d3b
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
F tool/mksqlite3c-noext.tcl 4f7cfef5152b0c91920355cbfc1d608a4ad242cb819f1aea07f6d0274f584a7f
@@ -1825,10 +1819,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P e6d5fee8cdbdce8515957e8288e4d1e7b06f417fd3f9deeeb636fbf5b995af51
R 18dbde46f443280c6eecde54f8c54e7b
T *branch * warnings
T *sym-warnings *
T -sym-trunk *
U mistachkin
Z b2da933afeced894c61f5f453a40ac1b
P 1b25fa108ab2c4ada75935abf919de2b4c3b39553b2a0ab2a485645a02352e7e
R d379d98b062e48bddb17018fbaab4555
U drh
Z d532b28c8391dbdee92daa0c2fe6ec79
+1 -1
View File
@@ -1 +1 @@
ca068d82387fc3cda9d2050cedb4f9c61b6d9dc54f89015b4b2ee492243ed5c9
9404300ac1dd0ef4e4b42f618901c6120b15a158c230f76e47c4c6346f6f4f58
+1 -1
View File
@@ -274,7 +274,7 @@ static int backupOnePage(
if( nSrcReserve!=nDestReserve ){
u32 newPgsz = nSrcPgsz;
rc = sqlite3PagerSetPagesize(pDestPager, &newPgsz, nSrcReserve);
if( rc==SQLITE_OK && newPgsz!=(u32)nSrcPgsz ) rc = SQLITE_READONLY;
if( rc==SQLITE_OK && newPgsz!=nSrcPgsz ) rc = SQLITE_READONLY;
}
#endif
+8 -24
View File
@@ -1628,7 +1628,7 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
** However, that integer is too large to be stored in a 2-byte unsigned
** integer, so a value of 0 is used in its place. */
top = get2byte(&data[hdr+5]);
assert( top<=(int)pPage->pBt->usableSize ); /* by btreeComputeFreeSpace() */
assert( top<=(int)pPage->pBt->usableSize ); /* Prevent by getAndInitPage() */
if( gap>top ){
if( top==0 && pPage->pBt->usableSize==65536 ){
top = 65536;
@@ -1925,7 +1925,7 @@ static int btreeComputeFreeSpace(MemPage *pPage){
** serves to verify that the offset to the start of the cell-content
** area, according to the page header, lies within the page.
*/
if( nFree>usableSize || nFree<iCellFirst ){
if( nFree>usableSize ){
return SQLITE_CORRUPT_PAGE(pPage);
}
pPage->nFree = (u16)(nFree - iCellFirst);
@@ -4153,18 +4153,6 @@ int sqlite3BtreeTripAllCursors(Btree *pBtree, int errCode, int writeOnly){
return rc;
}
/*
** Set the pBt->nPage field correctly, according to the current
** state of the database. Assume pBt->pPage1 is valid.
*/
static void btreeSetNPage(BtShared *pBt, MemPage *pPage1){
int nPage = get4byte(&pPage1->aData[28]);
testcase( nPage==0 );
if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage);
testcase( pBt->nPage!=nPage );
pBt->nPage = nPage;
}
/*
** Rollback the transaction in progress.
**
@@ -4210,7 +4198,11 @@ int sqlite3BtreeRollback(Btree *p, int tripCode, int writeOnly){
** call btreeGetPage() on page 1 again to make
** sure pPage1->aData is set correctly. */
if( btreeGetPage(pBt, 1, &pPage1, 0)==SQLITE_OK ){
btreeSetNPage(pBt, pPage1);
int nPage = get4byte(28+(u8*)pPage1->aData);
testcase( nPage==0 );
if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage);
testcase( pBt->nPage!=nPage );
pBt->nPage = nPage;
releasePageOne(pPage1);
}
assert( countValidCursors(pBt, 1)==0 );
@@ -4290,7 +4282,7 @@ int sqlite3BtreeSavepoint(Btree *p, int op, int iSavepoint){
pBt->nPage = 0;
}
rc = newDatabase(pBt);
btreeSetNPage(pBt, pBt->pPage1);
pBt->nPage = get4byte(28 + pBt->pPage1->aData);
/* pBt->nPage might be zero if the database was corrupt when
** the transaction was started. Otherwise, it must be at least 1. */
@@ -5302,7 +5294,6 @@ int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
assert( pCur->ix==pCur->pPage->nCell-1 );
assert( pCur->pPage->leaf );
#endif
*pRes = 0;
return SQLITE_OK;
}
@@ -7645,7 +7636,6 @@ static int balance_nonroot(
u16 maskPage = pOld->maskPage;
u8 *piCell = aData + pOld->cellOffset;
u8 *piEnd;
VVA_ONLY( int nCellAtStart = b.nCell; )
/* Verify that all sibling pages are of the same "type" (table-leaf,
** table-interior, index-leaf, or index-interior).
@@ -7674,10 +7664,6 @@ static int balance_nonroot(
*/
memset(&b.szCell[b.nCell], 0, sizeof(b.szCell[0])*(limit+pOld->nOverflow));
if( pOld->nOverflow>0 ){
if( limit<pOld->aiOvfl[0] ){
rc = SQLITE_CORRUPT_BKPT;
goto balance_cleanup;
}
limit = pOld->aiOvfl[0];
for(j=0; j<limit; j++){
b.apCell[b.nCell] = aData + (maskPage & get2byteAligned(piCell));
@@ -7697,7 +7683,6 @@ static int balance_nonroot(
piCell += 2;
b.nCell++;
}
assert( (b.nCell-nCellAtStart)==(pOld->nCell+pOld->nOverflow) );
cntOld[i] = b.nCell;
if( i<nOld-1 && !leafData){
@@ -7998,7 +7983,6 @@ static int balance_nonroot(
while( i==cntOldNext ){
iOld++;
assert( iOld<nNew || iOld<nOld );
assert( iOld>=0 && iOld<NB );
pOld = iOld<nNew ? apNew[iOld] : apOld[iOld];
cntOldNext += pOld->nCell + pOld->nOverflow + !leafData;
}
+8 -58
View File
@@ -1329,7 +1329,7 @@ void sqlite3AddDefaultValue(
** accept it. This routine does the necessary conversion. It converts
** the expression given in its argument from a TK_STRING into a TK_ID
** if the expression is just a TK_STRING with an optional COLLATE clause.
** If the expression is anything other than TK_STRING, the expression is
** If the epxression is anything other than TK_STRING, the expression is
** unchanged.
*/
static void sqlite3StringToId(Expr *p){
@@ -1726,51 +1726,10 @@ static void estimateIndexWidth(Index *pIdx){
pIdx->szIdxRow = sqlite3LogEst(wIndex*4);
}
/* Return true if column number x is any of the first nCol entries of aiCol[].
** This is used to determine if the column number x appears in any of the
** first nCol entries of an index.
/* Return true if value x is found any of the first nCol entries of aiCol[]
*/
static int hasColumn(const i16 *aiCol, int nCol, int x){
while( nCol-- > 0 ){
assert( aiCol[0]>=0 );
if( x==*(aiCol++) ){
return 1;
}
}
return 0;
}
/*
** Return true if any of the first nKey entries of index pIdx exactly
** match the iCol-th entry of pPk. pPk is always a WITHOUT ROWID
** PRIMARY KEY index. pIdx is an index on the same table. pIdx may
** or may not be the same index as pPk.
**
** The first nKey entries of pIdx are guaranteed to be ordinary columns,
** not a rowid or expression.
**
** This routine differs from hasColumn() in that both the column and the
** collating sequence must match for this routine, but for hasColumn() only
** the column name must match.
*/
static int isDupColumn(Index *pIdx, int nKey, Index *pPk, int iCol){
int i, j;
assert( nKey<=pIdx->nColumn );
assert( iCol<MAX(pPk->nColumn,pPk->nKeyCol) );
assert( pPk->idxType==SQLITE_IDXTYPE_PRIMARYKEY );
assert( pPk->pTable->tabFlags & TF_WithoutRowid );
assert( pPk->pTable==pIdx->pTable );
testcase( pPk==pIdx );
j = pPk->aiColumn[iCol];
assert( j!=XN_ROWID && j!=XN_EXPR );
for(i=0; i<nKey; i++){
assert( pIdx->aiColumn[i]>=0 || j>=0 );
if( pIdx->aiColumn[i]==j
&& sqlite3StrICmp(pIdx->azColl[i], pPk->azColl[iCol])==0
){
return 1;
}
}
while( nCol-- > 0 ) if( x==*(aiCol++) ) return 1;
return 0;
}
@@ -1859,16 +1818,13 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
pList = sqlite3ExprListAppend(pParse, 0,
sqlite3ExprAlloc(db, TK_ID, &ipkToken, 0));
if( pList==0 ) return;
if( IN_RENAME_OBJECT ){
sqlite3RenameTokenRemap(pParse, pList->a[0].pExpr, &pTab->iPKey);
}
pList->a[0].sortOrder = pParse->iPkSortOrder;
assert( pParse->pNewTable==pTab );
pTab->iPKey = -1;
sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0,
SQLITE_IDXTYPE_PRIMARYKEY);
if( db->mallocFailed || pParse->nErr ) return;
pPk = sqlite3PrimaryKeyIndex(pTab);
pTab->iPKey = -1;
}else{
pPk = sqlite3PrimaryKeyIndex(pTab);
assert( pPk!=0 );
@@ -1879,10 +1835,9 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
** code assumes the PRIMARY KEY contains no repeated columns.
*/
for(i=j=1; i<pPk->nKeyCol; i++){
if( isDupColumn(pPk, j, pPk, i) ){
if( hasColumn(pPk->aiColumn, j, pPk->aiColumn[i]) ){
pPk->nColumn--;
}else{
testcase( hasColumn(pPk->aiColumn, j, pPk->aiColumn[i]) );
pPk->aiColumn[j++] = pPk->aiColumn[i];
}
}
@@ -1912,10 +1867,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
int n;
if( IsPrimaryKeyIndex(pIdx) ) continue;
for(i=n=0; i<nPk; i++){
if( !isDupColumn(pIdx, pIdx->nKeyCol, pPk, i) ){
testcase( hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) );
n++;
}
if( !hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ) n++;
}
if( n==0 ){
/* This index is a superset of the primary key */
@@ -1924,8 +1876,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
}
if( resizeIndexObject(db, pIdx, pIdx->nKeyCol+n) ) return;
for(i=0, j=pIdx->nKeyCol; i<nPk; i++){
if( !isDupColumn(pIdx, pIdx->nKeyCol, pPk, i) ){
testcase( hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) );
if( !hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ){
pIdx->aiColumn[j] = pPk->aiColumn[i];
pIdx->azColl[j] = pPk->azColl[i];
j++;
@@ -3441,10 +3392,9 @@ void sqlite3CreateIndex(
for(j=0; j<pPk->nKeyCol; j++){
int x = pPk->aiColumn[j];
assert( x>=0 );
if( isDupColumn(pIndex, pIndex->nKeyCol, pPk, j) ){
if( hasColumn(pIndex->aiColumn, pIndex->nKeyCol, x) ){
pIndex->nColumn--;
}else{
testcase( hasColumn(pIndex->aiColumn,pIndex->nKeyCol,x) );
pIndex->aiColumn[i] = x;
pIndex->azColl[i] = pPk->azColl[j];
pIndex->aSortOrder[i] = pPk->aSortOrder[j];
+1 -5
View File
@@ -4943,11 +4943,7 @@ int sqlite3ExprImpliesExpr(Parse *pParse, Expr *pE1, Expr *pE2, int iTab){
){
return 1;
}
if( pE2->op==TK_NOTNULL
&& pE1->op!=TK_ISNULL
&& pE1->op!=TK_IS
&& pE1->op!=TK_OR
){
if( pE2->op==TK_NOTNULL && pE1->op!=TK_ISNULL && pE1->op!=TK_IS ){
Expr *pX = sqlite3ExprSkipCollate(pE1->pLeft);
testcase( pX!=pE1->pLeft );
if( sqlite3ExprCompare(pParse, pX, pE2->pLeft, iTab)==0 ) return 1;
+27 -14
View File
@@ -16,7 +16,6 @@
#include "sqliteInt.h"
#include <stdlib.h>
#include <assert.h>
#include <math.h>
#include "vdbeInt.h"
/*
@@ -397,10 +396,7 @@ static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
sqlite3_result_error_nomem(context);
return;
}
if( !sqlite3AtoF(zBuf, &r, sqlite3Strlen30(zBuf), SQLITE_UTF8) ){
assert( sqlite3_strglob("*Inf", zBuf)==0 );
r = zBuf[0]=='-' ? -HUGE_VAL : +HUGE_VAL;
}
sqlite3AtoF(zBuf, &r, sqlite3Strlen30(zBuf), SQLITE_UTF8);
sqlite3_free(zBuf);
}
sqlite3_result_double(context, r);
@@ -847,6 +843,8 @@ static void likeFunc(
return;
}
#endif
zB = sqlite3_value_text(argv[0]);
zA = sqlite3_value_text(argv[1]);
/* Limit the length of the LIKE or GLOB pattern to avoid problems
** of deep recursion and N*N behavior in patternCompare().
@@ -858,6 +856,8 @@ static void likeFunc(
sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1);
return;
}
assert( zB==sqlite3_value_text(argv[0]) ); /* Encoding did not change */
if( argc==3 ){
/* The escape character string must consist of a single UTF-8 character.
** Otherwise, return an error.
@@ -873,8 +873,6 @@ static void likeFunc(
}else{
escape = pInfo->matchSet;
}
zB = sqlite3_value_text(argv[0]);
zA = sqlite3_value_text(argv[1]);
if( zA && zB ){
#ifdef SQLITE_TEST
sqlite3_like_count++;
@@ -1800,24 +1798,39 @@ void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3 *db){
}
/*
** Re-register the built-in LIKE functions. The caseSensitive
** Set the LIKEOPT flag on the 2-argument function with the given name.
*/
static void setLikeOptFlag(sqlite3 *db, const char *zName, u8 flagVal){
FuncDef *pDef;
pDef = sqlite3FindFunction(db, zName, 2, SQLITE_UTF8, 0);
if( ALWAYS(pDef) ){
pDef->funcFlags |= flagVal;
}
pDef = sqlite3FindFunction(db, zName, 3, SQLITE_UTF8, 0);
if( pDef ){
pDef->funcFlags |= flagVal;
}
}
/*
** Register the built-in LIKE and GLOB functions. The caseSensitive
** parameter determines whether or not the LIKE operator is case
** sensitive.
** sensitive. GLOB is always case sensitive.
*/
void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){
struct compareInfo *pInfo;
int flags;
if( caseSensitive ){
pInfo = (struct compareInfo*)&likeInfoAlt;
flags = SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE;
}else{
pInfo = (struct compareInfo*)&likeInfoNorm;
flags = SQLITE_FUNC_LIKE;
}
sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0);
sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0);
sqlite3FindFunction(db, "like", 2, SQLITE_UTF8, 0)->funcFlags |= flags;
sqlite3FindFunction(db, "like", 3, SQLITE_UTF8, 0)->funcFlags |= flags;
sqlite3CreateFunc(db, "glob", 2, SQLITE_UTF8,
(struct compareInfo*)&globInfo, likeFunc, 0, 0, 0, 0, 0);
setLikeOptFlag(db, "glob", SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE);
setLikeOptFlag(db, "like",
caseSensitive ? (SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE) : SQLITE_FUNC_LIKE);
}
/*
+13 -21
View File
@@ -814,7 +814,7 @@ void sqlite3Insert(
int nIdx;
nIdx = sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, -1, 0,
&iDataCur, &iIdxCur);
aRegIdx = sqlite3DbMallocRawNN(db, sizeof(int)*(nIdx+2));
aRegIdx = sqlite3DbMallocRawNN(db, sizeof(int)*(nIdx+1));
if( aRegIdx==0 ){
goto insert_cleanup;
}
@@ -823,7 +823,6 @@ void sqlite3Insert(
aRegIdx[i] = ++pParse->nMem;
pParse->nMem += pIdx->nColumn;
}
aRegIdx[i] = ++pParse->nMem; /* Register to store the table record */
}
#ifndef SQLITE_OMIT_UPSERT
if( pUpsert ){
@@ -1227,14 +1226,6 @@ int sqlite3ExprReferencesUpdatedColumn(
** the same as the order of indices on the linked list of indices
** at pTab->pIndex.
**
** (2019-05-07) The generated code also creates a new record for the
** main table, if pTab is a rowid table, and stores that record in the
** register identified by aRegIdx[nIdx] - in other words in the first
** entry of aRegIdx[] past the last index. It is important that the
** record be generated during constraint checks to avoid affinity changes
** to the register content that occur after constraint checks but before
** the new record is inserted.
**
** The caller must have already opened writeable cursors on the main
** table and all applicable indices (that is to say, all indices for which
** aRegIdx[] is not zero). iDataCur is the cursor for the main table when
@@ -1854,16 +1845,6 @@ void sqlite3GenerateConstraintChecks(
sqlite3VdbeJumpHere(v, ipkBottom);
}
/* Generate the table record */
if( HasRowid(pTab) ){
int regRec = aRegIdx[ix];
sqlite3VdbeAddOp3(v, OP_MakeRecord, regNewData+1, pTab->nCol, regRec);
sqlite3SetMakeRecordP5(v, pTab);
if( !bAffinityDone ){
sqlite3TableAffinity(v, pTab, 0);
}
}
*pbMayReplace = seenReplace;
VdbeModuleComment((v, "END: GenCnstCks(%d)", seenReplace));
}
@@ -1913,7 +1894,10 @@ void sqlite3CompleteInsertion(
Vdbe *v; /* Prepared statements under construction */
Index *pIdx; /* An index being inserted or updated */
u8 pik_flags; /* flag values passed to the btree insert */
int regData; /* Content registers (after the rowid) */
int regRec; /* Register holding assembled record for the table */
int i; /* Loop counter */
u8 bAffinityDone = 0; /* True if OP_Affinity has been run already */
assert( update_flags==0
|| update_flags==OPFLAG_ISUPDATE
@@ -1925,6 +1909,7 @@ void sqlite3CompleteInsertion(
assert( pTab->pSelect==0 ); /* This table is not a VIEW */
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
if( aRegIdx[i]==0 ) continue;
bAffinityDone = 1;
if( pIdx->pPartIdxWhere ){
sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2);
VdbeCoverage(v);
@@ -1952,6 +1937,13 @@ void sqlite3CompleteInsertion(
sqlite3VdbeChangeP5(v, pik_flags);
}
if( !HasRowid(pTab) ) return;
regData = regNewData + 1;
regRec = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp3(v, OP_MakeRecord, regData, pTab->nCol, regRec);
sqlite3SetMakeRecordP5(v, pTab);
if( !bAffinityDone ){
sqlite3TableAffinity(v, pTab, 0);
}
if( pParse->nested ){
pik_flags = 0;
}else{
@@ -1964,7 +1956,7 @@ void sqlite3CompleteInsertion(
if( useSeekResult ){
pik_flags |= OPFLAG_USESEEKRESULT;
}
sqlite3VdbeAddOp3(v, OP_Insert, iDataCur, aRegIdx[i], regNewData);
sqlite3VdbeAddOp3(v, OP_Insert, iDataCur, regRec, regNewData);
if( !pParse->nested ){
sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
}
-16
View File
@@ -4104,22 +4104,6 @@ int sqlite3_test_control(int op, ...){
break;
}
#endif /* defined(YYCOVERAGE) */
/* sqlite3_test_control(SQLITE_TESTCTRL_RESULT_INTREAL, sqlite3_context*);
**
** This test-control causes the most recent sqlite3_result_int64() value
** to be interpreted as a MEM_IntReal instead of as an MEM_Int. Normally,
** MEM_IntReal values only arise during an INSERT operation of integer
** values into a REAL column, so they can be challenging to test. This
** test-control enables us to write an intreal() SQL function that can
** inject an intreal() value at arbitrary places in an SQL statement,
** for testing purposes.
*/
case SQLITE_TESTCTRL_RESULT_INTREAL: {
sqlite3_context *pCtx = va_arg(ap, sqlite3_context*);
sqlite3ResultIntReal(pCtx);
break;
}
}
va_end(ap);
#endif /* SQLITE_UNTESTABLE */
-2
View File
@@ -1421,7 +1421,6 @@ void sqlite3Pragma(
#endif /* !defined(SQLITE_OMIT_TRIGGER) */
#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
#ifndef SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA
/* Reinstall the LIKE and GLOB functions. The variant of LIKE
** used will be case sensitive or not depending on the RHS.
*/
@@ -1431,7 +1430,6 @@ void sqlite3Pragma(
}
}
break;
#endif /* SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA */
#ifndef SQLITE_INTEGRITY_CHECK_ERROR_MAX
# define SQLITE_INTEGRITY_CHECK_ERROR_MAX 100
-2
View File
@@ -178,13 +178,11 @@ static const PragmaName aPragmaName[] = {
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA)
{/* zName: */ "case_sensitive_like",
/* ePragTyp: */ PragTyp_CASE_SENSITIVE_LIKE,
/* ePragFlg: */ PragFlg_NoColumns,
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
#endif
{/* zName: */ "cell_size_check",
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+1 -3
View File
@@ -866,9 +866,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
#ifndef SQLITE_OMIT_WINDOWFUNC
if( pExpr->y.pWin ){
Select *pSel = pNC->pWinSelect;
if( IN_RENAME_OBJECT==0 ){
sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->y.pWin, pDef);
}
sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->y.pWin, pDef);
sqlite3WalkExprList(pWalker, pExpr->y.pWin->pPartition);
sqlite3WalkExprList(pWalker, pExpr->y.pWin->pOrderBy);
sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter);
+1 -3
View File
@@ -5481,9 +5481,7 @@ static struct SrcList_item *isSelfJoinView(
** names in the same FROM clause. */
continue;
}
if( sqlite3ExprCompare(0, pThis->pSelect->pWhere, pS1->pWhere, -1)
|| sqlite3ExprCompare(0, pThis->pSelect->pHaving, pS1->pHaving, -1)
){
if( sqlite3ExprCompare(0, pThis->pSelect->pWhere, pS1->pWhere, -1) ){
/* The view was modified by some other optimization such as
** pushDownWhereTerms() */
continue;
+17 -790
View File
@@ -948,10 +948,6 @@ INCLUDE ../ext/misc/sqlar.c
INCLUDE ../ext/expert/sqlite3expert.h
INCLUDE ../ext/expert/sqlite3expert.c
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
INCLUDE ../ext/misc/dbdata.c
#endif
#if defined(SQLITE_ENABLE_SESSION)
/*
** State information for a single open session
@@ -1681,8 +1677,6 @@ static int shellAuth(
** in FTS3/4/5 into CREATE TABLE IF NOT EXISTS statements.
*/
static void printSchemaLine(FILE *out, const char *z, const char *zTail){
if( z==0 ) return;
if( zTail==0 ) return;
if( sqlite3_strglob("CREATE TABLE ['\"]*", z)==0 ){
utf8_printf(out, "CREATE TABLE IF NOT EXISTS %s%s", z+13, zTail);
}else{
@@ -1778,7 +1772,7 @@ static void eqp_render_level(ShellState *p, int iEqpId){
/*
** Display and reset the EXPLAIN QUERY PLAN data
*/
static void eqp_render(ShellState *p){
static void eqp_render(ShellState *p, sqlite3_stmt *pStmt){
EQPGraphRow *pRow = p->sGraph.pRow;
if( pRow ){
if( pRow->zText[0]=='-' ){
@@ -1790,7 +1784,10 @@ static void eqp_render(ShellState *p){
p->sGraph.pRow = pRow->pNext;
sqlite3_free(pRow);
}else{
utf8_printf(p->out, "QUERY PLAN\n");
int iCost, nRow;
iCost = sqlite3_stmt_status(pStmt, SQLITE_STMTSTATUS_EST_COST, 0);
nRow = sqlite3_stmt_status(pStmt, SQLITE_STMTSTATUS_EST_ROWS, 0);
utf8_printf(p->out, "QUERY PLAN (log est cost=%d rows=%d)\n", iCost, nRow);
}
p->sGraph.zPrefix[0] = 0;
eqp_render_level(p, 0);
@@ -3081,10 +3078,10 @@ static int shell_exec(
const char *zEQPLine = (const char*)sqlite3_column_text(pExplain,3);
int iEqpId = sqlite3_column_int(pExplain, 0);
int iParentId = sqlite3_column_int(pExplain, 1);
if( zEQPLine[0]=='-' ) eqp_render(pArg);
if( zEQPLine[0]=='-' ) eqp_render(pArg, pExplain);
eqp_append(pArg, iEqpId, iParentId, zEQPLine);
}
eqp_render(pArg);
eqp_render(pArg, pExplain);
}
sqlite3_finalize(pExplain);
sqlite3_free(zEQP);
@@ -3132,7 +3129,7 @@ static int shell_exec(
bind_prepared_stmt(pArg, pStmt);
exec_prepared_stmt(pArg, pStmt);
explain_data_delete(pArg);
eqp_render(pArg);
eqp_render(pArg, pStmt);
/* print usage stats if stats on */
if( pArg && pArg->statsOn ){
@@ -3580,9 +3577,6 @@ static const char *(azHelp[]) = {
".prompt MAIN CONTINUE Replace the standard prompts",
".quit Exit this program",
".read FILE Read input from FILE",
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
".recover Recover as much data as possible from corrupt db.",
#endif
".restore ?DB? FILE Restore content of DB (default \"main\") from FILE",
".save FILE Write in-memory database into FILE",
".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off",
@@ -3879,15 +3873,14 @@ static unsigned char *readHexDb(ShellState *p, int *pnData){
}else{
in = p->in;
nLine = p->lineno;
if( in==0 ) in = stdin;
}
*pnData = 0;
nLine++;
if( fgets(zLine, sizeof(zLine), in)==0 ) goto readHexDb_error;
rc = sscanf(zLine, "| size %d pagesize %d", &n, &pgsz);
if( rc!=2 ) goto readHexDb_error;
if( n<0 ) goto readHexDb_error;
a = sqlite3_malloc( n ? n : 1 );
if( n<=0 ) goto readHexDb_error;
a = sqlite3_malloc( n );
if( a==0 ){
utf8_printf(stderr, "Out of memory!\n");
goto readHexDb_error;
@@ -3926,7 +3919,7 @@ static unsigned char *readHexDb(ShellState *p, int *pnData){
return a;
readHexDb_error:
if( in!=p->in ){
if( in!=stdin ){
fclose(in);
}else{
while( fgets(zLine, sizeof(zLine), p->in)!=0 ){
@@ -3941,125 +3934,6 @@ readHexDb_error:
}
#endif /* SQLITE_ENABLE_DESERIALIZE */
/*
** Scalar function "shell_int32". The first argument to this function
** must be a blob. The second a non-negative integer. This function
** reads and returns a 32-bit big-endian integer from byte
** offset (4*<arg2>) of the blob.
*/
static void shellInt32(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
const unsigned char *pBlob;
int nBlob;
int iInt;
nBlob = sqlite3_value_bytes(argv[0]);
pBlob = (const unsigned char*)sqlite3_value_blob(argv[0]);
iInt = sqlite3_value_int(argv[1]);
if( iInt>=0 && (iInt+1)*4<=nBlob ){
const unsigned char *a = &pBlob[iInt*4];
sqlite3_int64 iVal = ((sqlite3_int64)a[0]<<24)
+ ((sqlite3_int64)a[1]<<16)
+ ((sqlite3_int64)a[2]<< 8)
+ ((sqlite3_int64)a[3]<< 0);
sqlite3_result_int64(context, iVal);
}
}
/*
** Scalar function "shell_escape_crnl" used by the .recover command.
** The argument passed to this function is the output of built-in
** function quote(). If the first character of the input is "'",
** indicating that the value passed to quote() was a text value,
** then this function searches the input for "\n" and "\r" characters
** and adds a wrapper similar to the following:
**
** replace(replace(<input>, '\n', char(10), '\r', char(13));
**
** Or, if the first character of the input is not "'", then a copy
** of the input is returned.
*/
static void shellEscapeCrnl(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
const char *zText = (const char*)sqlite3_value_text(argv[0]);
if( zText[0]=='\'' ){
int nText = sqlite3_value_bytes(argv[0]);
int i;
char zBuf1[20];
char zBuf2[20];
const char *zNL = 0;
const char *zCR = 0;
int nCR = 0;
int nNL = 0;
for(i=0; zText[i]; i++){
if( zNL==0 && zText[i]=='\n' ){
zNL = unused_string(zText, "\\n", "\\012", zBuf1);
nNL = (int)strlen(zNL);
}
if( zCR==0 && zText[i]=='\r' ){
zCR = unused_string(zText, "\\r", "\\015", zBuf2);
nCR = (int)strlen(zCR);
}
}
if( zNL || zCR ){
int iOut = 0;
i64 nMax = (nNL > nCR) ? nNL : nCR;
i64 nAlloc = nMax * nText + (nMax+64)*2;
char *zOut = (char*)sqlite3_malloc64(nAlloc);
if( zOut==0 ){
sqlite3_result_error_nomem(context);
return;
}
if( zNL && zCR ){
memcpy(&zOut[iOut], "replace(replace(", 16);
iOut += 16;
}else{
memcpy(&zOut[iOut], "replace(", 8);
iOut += 8;
}
for(i=0; zText[i]; i++){
if( zText[i]=='\n' ){
memcpy(&zOut[iOut], zNL, nNL);
iOut += nNL;
}else if( zText[i]=='\r' ){
memcpy(&zOut[iOut], zCR, nCR);
iOut += nCR;
}else{
zOut[iOut] = zText[i];
iOut++;
}
}
if( zNL ){
memcpy(&zOut[iOut], ",'", 2); iOut += 2;
memcpy(&zOut[iOut], zNL, nNL); iOut += nNL;
memcpy(&zOut[iOut], "', char(10))", 12); iOut += 12;
}
if( zCR ){
memcpy(&zOut[iOut], ",'", 2); iOut += 2;
memcpy(&zOut[iOut], zCR, nCR); iOut += nCR;
memcpy(&zOut[iOut], "', char(13))", 12); iOut += 12;
}
sqlite3_result_text(context, zOut, iOut, SQLITE_TRANSIENT);
sqlite3_free(zOut);
return;
}
}
sqlite3_result_value(context, argv[0]);
}
/* Flags for open_db().
**
** The default behavior of open_db() is to exit(1) if the database fails to
@@ -4128,9 +4002,6 @@ static void open_db(ShellState *p, int openFlags){
sqlite3_fileio_init(p->db, 0, 0);
sqlite3_shathree_init(p->db, 0, 0);
sqlite3_completion_init(p->db, 0, 0);
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
sqlite3_dbdata_init(p->db, 0, 0);
#endif
#ifdef SQLITE_HAVE_ZLIB
sqlite3_zipfile_init(p->db, 0, 0);
sqlite3_sqlar_init(p->db, 0, 0);
@@ -4141,10 +4012,6 @@ static void open_db(ShellState *p, int openFlags){
shellModuleSchema, 0, 0);
sqlite3_create_function(p->db, "shell_putsnl", 1, SQLITE_UTF8, p,
shellPutsFunc, 0, 0);
sqlite3_create_function(p->db, "shell_escape_crnl", 1, SQLITE_UTF8, 0,
shellEscapeCrnl, 0, 0);
sqlite3_create_function(p->db, "shell_int32", 2, SQLITE_UTF8, 0,
shellInt32, 0, 0);
#ifndef SQLITE_NOHAVE_SYSTEM
sqlite3_create_function(p->db, "edit", 1, SQLITE_UTF8, 0,
editFunc, 0, 0);
@@ -4168,6 +4035,7 @@ static void open_db(ShellState *p, int openFlags){
}else{
aData = readHexDb(p, &nData);
if( aData==0 ){
utf8_printf(stderr, "Error in hexdb input\n");
return;
}
}
@@ -5398,7 +5266,10 @@ static int lintDotCommand(
return SQLITE_ERROR;
}
#if !defined SQLITE_OMIT_VIRTUALTABLE
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
/*********************************************************************************
** The ".archive" or ".ar" command.
*/
static void shellPrepare(
sqlite3 *db,
int *pRc,
@@ -5469,12 +5340,6 @@ static void shellReset(
*pRc = rc;
}
}
#endif /* !defined SQLITE_OMIT_VIRTUALTABLE */
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
/*********************************************************************************
** The ".archive" or ".ar" command.
*/
/*
** Structure representing a single ".ar" command.
*/
@@ -6164,635 +6029,6 @@ end_ar_command:
**********************************************************************************/
#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) */
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
/*
** If (*pRc) is not SQLITE_OK when this function is called, it is a no-op.
** Otherwise, the SQL statement or statements in zSql are executed using
** database connection db and the error code written to *pRc before
** this function returns.
*/
static void shellExec(sqlite3 *db, int *pRc, const char *zSql){
int rc = *pRc;
if( rc==SQLITE_OK ){
char *zErr = 0;
rc = sqlite3_exec(db, zSql, 0, 0, &zErr);
if( rc!=SQLITE_OK ){
raw_printf(stderr, "SQL error: %s\n", zErr);
}
*pRc = rc;
}
}
/*
** Like shellExec(), except that zFmt is a printf() style format string.
*/
static void shellExecPrintf(sqlite3 *db, int *pRc, const char *zFmt, ...){
char *z = 0;
if( *pRc==SQLITE_OK ){
va_list ap;
va_start(ap, zFmt);
z = sqlite3_vmprintf(zFmt, ap);
va_end(ap);
if( z==0 ){
*pRc = SQLITE_NOMEM;
}else{
shellExec(db, pRc, z);
}
sqlite3_free(z);
}
}
/*
** If *pRc is not SQLITE_OK when this function is called, it is a no-op.
** Otherwise, an attempt is made to allocate, zero and return a pointer
** to a buffer nByte bytes in size. If an OOM error occurs, *pRc is set
** to SQLITE_NOMEM and NULL returned.
*/
static void *shellMalloc(int *pRc, sqlite3_int64 nByte){
void *pRet = 0;
if( *pRc==SQLITE_OK ){
pRet = sqlite3_malloc64(nByte);
if( pRet==0 ){
*pRc = SQLITE_NOMEM;
}else{
memset(pRet, 0, nByte);
}
}
return pRet;
}
/*
** If *pRc is not SQLITE_OK when this function is called, it is a no-op.
** Otherwise, zFmt is treated as a printf() style string. The result of
** formatting it along with any trailing arguments is written into a
** buffer obtained from sqlite3_malloc(), and pointer to which is returned.
** It is the responsibility of the caller to eventually free this buffer
** using a call to sqlite3_free().
**
** If an OOM error occurs, (*pRc) is set to SQLITE_NOMEM and a NULL
** pointer returned.
*/
static char *shellMPrintf(int *pRc, const char *zFmt, ...){
char *z = 0;
if( *pRc==SQLITE_OK ){
va_list ap;
va_start(ap, zFmt);
z = sqlite3_vmprintf(zFmt, ap);
va_end(ap);
if( z==0 ){
*pRc = SQLITE_NOMEM;
}
}
return z;
}
/*
** When running the ".recover" command, each output table, and the special
** orphaned row table if it is required, is represented by an instance
** of the following struct.
*/
typedef struct RecoverTable RecoverTable;
struct RecoverTable {
char *zQuoted; /* Quoted version of table name */
int nCol; /* Number of columns in table */
char **azlCol; /* Array of column lists */
int iPk; /* Index of IPK column */
};
/*
** Free a RecoverTable object allocated by recoverFindTable() or
** recoverOrphanTable().
*/
static void recoverFreeTable(RecoverTable *pTab){
if( pTab ){
sqlite3_free(pTab->zQuoted);
if( pTab->azlCol ){
int i;
for(i=0; i<=pTab->nCol; i++){
sqlite3_free(pTab->azlCol[i]);
}
sqlite3_free(pTab->azlCol);
}
sqlite3_free(pTab);
}
}
/*
** This function is a no-op if (*pRc) is not SQLITE_OK when it is called.
** Otherwise, it allocates and returns a RecoverTable object based on the
** final four arguments passed to this function. It is the responsibility
** of the caller to eventually free the returned object using
** recoverFreeTable().
*/
static RecoverTable *recoverNewTable(
int *pRc, /* IN/OUT: Error code */
const char *zName, /* Name of table */
const char *zSql, /* CREATE TABLE statement */
int bIntkey,
int nCol
){
sqlite3 *dbtmp = 0; /* sqlite3 handle for testing CREATE TABLE */
int rc = *pRc;
RecoverTable *pTab = 0;
pTab = (RecoverTable*)shellMalloc(&rc, sizeof(RecoverTable));
if( rc==SQLITE_OK ){
int nSqlCol = 0;
int bSqlIntkey = 0;
sqlite3_stmt *pStmt = 0;
rc = sqlite3_open("", &dbtmp);
if( rc==SQLITE_OK ){
rc = sqlite3_exec(dbtmp, "PRAGMA writable_schema = on", 0, 0, 0);
}
if( rc==SQLITE_OK ){
rc = sqlite3_exec(dbtmp, zSql, 0, 0, 0);
if( rc==SQLITE_ERROR ){
rc = SQLITE_OK;
goto finished;
}
}
shellPreparePrintf(dbtmp, &rc, &pStmt,
"SELECT count(*) FROM pragma_table_info(%Q)", zName
);
if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
nSqlCol = sqlite3_column_int(pStmt, 0);
}
shellFinalize(&rc, pStmt);
if( rc!=SQLITE_OK || nSqlCol<nCol ){
goto finished;
}
shellPreparePrintf(dbtmp, &rc, &pStmt,
"SELECT ("
" SELECT substr(data,1,1)==X'0D' FROM sqlite_dbpage WHERE pgno=rootpage"
") FROM sqlite_master WHERE name = %Q", zName
);
if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
bSqlIntkey = sqlite3_column_int(pStmt, 0);
}
shellFinalize(&rc, pStmt);
if( bIntkey==bSqlIntkey ){
int i;
const char *zPk = "_rowid_";
sqlite3_stmt *pPkFinder = 0;
/* If this is an intkey table and there is an INTEGER PRIMARY KEY,
** set zPk to the name of the PK column, and pTab->iPk to the index
** of the column, where columns are 0-numbered from left to right.
** Or, if this is a WITHOUT ROWID table or if there is no IPK column,
** leave zPk as "_rowid_" and pTab->iPk at -2. */
pTab->iPk = -2;
if( bIntkey ){
shellPreparePrintf(dbtmp, &rc, &pPkFinder,
"SELECT cid, name FROM pragma_table_info(%Q) "
" WHERE pk=1 AND type='integer' COLLATE nocase"
" AND NOT EXISTS (SELECT cid FROM pragma_table_info(%Q) WHERE pk=2)"
, zName, zName
);
if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPkFinder) ){
pTab->iPk = sqlite3_column_int(pPkFinder, 0);
zPk = (const char*)sqlite3_column_text(pPkFinder, 1);
}
}
pTab->zQuoted = shellMPrintf(&rc, "%Q", zName);
pTab->azlCol = (char**)shellMalloc(&rc, sizeof(char*) * (nSqlCol+1));
pTab->nCol = nSqlCol;
if( bIntkey ){
pTab->azlCol[0] = shellMPrintf(&rc, "%Q", zPk);
}else{
pTab->azlCol[0] = shellMPrintf(&rc, "");
}
i = 1;
shellPreparePrintf(dbtmp, &rc, &pStmt,
"SELECT %Q || group_concat(name, ', ') "
" FILTER (WHERE cid!=%d) OVER (ORDER BY %s cid) "
"FROM pragma_table_info(%Q)",
bIntkey ? ", " : "", pTab->iPk,
bIntkey ? "" : "(CASE WHEN pk=0 THEN 1000000 ELSE pk END), ",
zName
);
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
const char *zText = (const char*)sqlite3_column_text(pStmt, 0);
pTab->azlCol[i] = shellMPrintf(&rc, "%s%s", pTab->azlCol[0], zText);
i++;
}
shellFinalize(&rc, pStmt);
shellFinalize(&rc, pPkFinder);
}
}
finished:
sqlite3_close(dbtmp);
*pRc = rc;
if( rc!=SQLITE_OK || (pTab && pTab->zQuoted==0) ){
recoverFreeTable(pTab);
pTab = 0;
}
return pTab;
}
/*
** This function is called to search the schema recovered from the
** sqlite_master table of the (possibly) corrupt database as part
** of a ".recover" command. Specifically, for a table with root page
** iRoot and at least nCol columns. Additionally, if bIntkey is 0, the
** table must be a WITHOUT ROWID table, or if non-zero, not one of
** those.
**
** If a table is found, a (RecoverTable*) object is returned. Or, if
** no such table is found, but bIntkey is false and iRoot is the
** root page of an index in the recovered schema, then (*pbNoop) is
** set to true and NULL returned. Or, if there is no such table or
** index, NULL is returned and (*pbNoop) set to 0, indicating that
** the caller should write data to the orphans table.
*/
static RecoverTable *recoverFindTable(
ShellState *pState, /* Shell state object */
int *pRc, /* IN/OUT: Error code */
int iRoot, /* Root page of table */
int bIntkey, /* True for an intkey table */
int nCol, /* Number of columns in table */
int *pbNoop /* OUT: True if iRoot is root of index */
){
sqlite3_stmt *pStmt = 0;
RecoverTable *pRet = 0;
int bNoop = 0;
const char *zSql = 0;
const char *zName = 0;
/* Search the recovered schema for an object with root page iRoot. */
shellPreparePrintf(pState->db, pRc, &pStmt,
"SELECT type, name, sql FROM recovery.schema WHERE rootpage=%d", iRoot
);
while( *pRc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
const char *zType = (const char*)sqlite3_column_text(pStmt, 0);
if( bIntkey==0 && sqlite3_stricmp(zType, "index")==0 ){
bNoop = 1;
break;
}
if( sqlite3_stricmp(zType, "table")==0 ){
zName = (const char*)sqlite3_column_text(pStmt, 1);
zSql = (const char*)sqlite3_column_text(pStmt, 2);
pRet = recoverNewTable(pRc, zName, zSql, bIntkey, nCol);
break;
}
}
shellFinalize(pRc, pStmt);
*pbNoop = bNoop;
return pRet;
}
/*
** Return a RecoverTable object representing the orphans table.
*/
static RecoverTable *recoverOrphanTable(
ShellState *pState, /* Shell state object */
int *pRc, /* IN/OUT: Error code */
const char *zLostAndFound, /* Base name for orphans table */
int nCol /* Number of user data columns */
){
RecoverTable *pTab = 0;
if( nCol>=0 && *pRc==SQLITE_OK ){
int i;
/* This block determines the name of the orphan table. The prefered
** name is zLostAndFound. But if that clashes with another name
** in the recovered schema, try zLostAndFound_0, zLostAndFound_1
** and so on until a non-clashing name is found. */
int iTab = 0;
char *zTab = shellMPrintf(pRc, "%s", zLostAndFound);
sqlite3_stmt *pTest = 0;
shellPrepare(pState->db, pRc,
"SELECT 1 FROM recovery.schema WHERE name=?", &pTest
);
if( pTest ) sqlite3_bind_text(pTest, 1, zTab, -1, SQLITE_TRANSIENT);
while( *pRc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pTest) ){
shellReset(pRc, pTest);
sqlite3_free(zTab);
zTab = shellMPrintf(pRc, "%s_%d", zLostAndFound, iTab++);
sqlite3_bind_text(pTest, 1, zTab, -1, SQLITE_TRANSIENT);
}
shellFinalize(pRc, pTest);
pTab = (RecoverTable*)shellMalloc(pRc, sizeof(RecoverTable));
if( pTab ){
pTab->zQuoted = shellMPrintf(pRc, "%Q", zTab);
pTab->nCol = nCol;
pTab->iPk = -2;
if( nCol>0 ){
pTab->azlCol = (char**)shellMalloc(pRc, sizeof(char*) * (nCol+1));
if( pTab->azlCol ){
pTab->azlCol[nCol] = shellMPrintf(pRc, "");
for(i=nCol-1; i>=0; i--){
pTab->azlCol[i] = shellMPrintf(pRc, "%s, NULL", pTab->azlCol[i+1]);
}
}
}
if( *pRc!=SQLITE_OK ){
recoverFreeTable(pTab);
pTab = 0;
}else{
raw_printf(pState->out,
"CREATE TABLE %s(rootpgno INTEGER, "
"pgno INTEGER, nfield INTEGER, id INTEGER", pTab->zQuoted
);
for(i=0; i<nCol; i++){
raw_printf(pState->out, ", c%d", i);
}
raw_printf(pState->out, ");\n");
}
}
sqlite3_free(zTab);
}
return pTab;
}
/*
** This function is called to recover data from the database. A script
** to construct a new database containing all recovered data is output
** on stream pState->out.
*/
static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){
int rc = SQLITE_OK;
sqlite3_stmt *pLoop = 0; /* Loop through all root pages */
sqlite3_stmt *pPages = 0; /* Loop through all pages in a group */
sqlite3_stmt *pCells = 0; /* Loop through all cells in a page */
const char *zRecoveryDb = ""; /* Name of "recovery" database */
const char *zLostAndFound = "lost_and_found";
int i;
int nOrphan = -1;
RecoverTable *pOrphan = 0;
int bFreelist = 1; /* 0 if --freelist-corrupt is specified */
for(i=1; i<nArg; i++){
char *z = azArg[i];
int n;
if( z[0]=='-' && z[1]=='-' ) z++;
n = strlen(z);
if( n<=17 && memcmp("-freelist-corrupt", z, n)==0 ){
bFreelist = 0;
}else
if( n<=12 && memcmp("-recovery-db", z, n)==0 && i<(nArg-1) ){
i++;
zRecoveryDb = azArg[i];
}else
if( n<=15 && memcmp("-lost-and-found", z, n)==0 && i<(nArg-1) ){
i++;
zLostAndFound = azArg[i];
}
else{
raw_printf(stderr, "unexpected option: %s\n", azArg[i]);
raw_printf(stderr, "options are:\n");
raw_printf(stderr, " --freelist-corrupt\n");
raw_printf(stderr, " --recovery-db DATABASE\n");
raw_printf(stderr, " --lost-and-found TABLE-NAME\n");
return 1;
}
}
shellExecPrintf(pState->db, &rc,
/* Attach an in-memory database named 'recovery'. Create an indexed
** cache of the sqlite_dbptr virtual table. */
"ATTACH %Q AS recovery;"
"DROP TABLE IF EXISTS recovery.dbptr;"
"DROP TABLE IF EXISTS recovery.freelist;"
"DROP TABLE IF EXISTS recovery.map;"
"DROP TABLE IF EXISTS recovery.schema;"
"CREATE TABLE recovery.freelist(pgno INTEGER PRIMARY KEY);", zRecoveryDb
);
if( bFreelist ){
shellExec(pState->db, &rc,
"WITH trunk(pgno) AS ("
" SELECT shell_int32("
" (SELECT data FROM sqlite_dbpage WHERE pgno=1), 8) AS x "
" WHERE x>0"
" UNION"
" SELECT shell_int32("
" (SELECT data FROM sqlite_dbpage WHERE pgno=trunk.pgno), 0) AS x "
" FROM trunk WHERE x>0"
"),"
"freelist(data, n, freepgno) AS ("
" SELECT data, min(16384, shell_int32(data, 1)-1), t.pgno "
" FROM trunk t, sqlite_dbpage s WHERE s.pgno=t.pgno"
" UNION ALL"
" SELECT data, n-1, shell_int32(data, 2+n) "
" FROM freelist WHERE n>=0"
")"
"REPLACE INTO recovery.freelist SELECT freepgno FROM freelist;"
);
}
shellExec(pState->db, &rc,
"CREATE TABLE recovery.dbptr("
" pgno, child, PRIMARY KEY(child, pgno)"
") WITHOUT ROWID;"
"INSERT OR IGNORE INTO recovery.dbptr(pgno, child) "
" SELECT * FROM sqlite_dbptr"
" WHERE pgno NOT IN freelist AND child NOT IN freelist;"
/* Delete any pointer to page 1. This ensures that page 1 is considered
** a root page, regardless of how corrupt the db is. */
"DELETE FROM recovery.dbptr WHERE child = 1;"
/* Delete all pointers to any pages that have more than one pointer
** to them. Such pages will be treated as root pages when recovering
** data. */
"DELETE FROM recovery.dbptr WHERE child IN ("
" SELECT child FROM recovery.dbptr GROUP BY child HAVING count(*)>1"
");"
/* Create the "map" table that will (eventually) contain instructions
** for dealing with each page in the db that contains one or more
** records. */
"CREATE TABLE recovery.map("
"pgno INTEGER PRIMARY KEY, maxlen INT, intkey, root INT"
");"
/* Populate table [map]. If there are circular loops of pages in the
** database, the following adds all pages in such a loop to the map
** as individual root pages. This could be handled better. */
"WITH pages(i, maxlen) AS ("
" SELECT page_count, ("
" SELECT max(field+1) FROM sqlite_dbdata WHERE pgno=page_count"
" ) FROM pragma_page_count WHERE page_count>0"
" UNION ALL"
" SELECT i-1, ("
" SELECT max(field+1) FROM sqlite_dbdata WHERE pgno=i-1"
" ) FROM pages WHERE i>=2"
")"
"INSERT INTO recovery.map(pgno, maxlen, intkey, root) "
" SELECT i, maxlen, NULL, ("
" WITH p(orig, pgno, parent) AS ("
" SELECT 0, i, (SELECT pgno FROM recovery.dbptr WHERE child=i)"
" UNION "
" SELECT i, p.parent, "
" (SELECT pgno FROM recovery.dbptr WHERE child=p.parent) FROM p"
" )"
" SELECT pgno FROM p WHERE (parent IS NULL OR pgno = orig)"
") "
"FROM pages WHERE maxlen > 0 AND i NOT IN freelist;"
"UPDATE recovery.map AS o SET intkey = ("
" SELECT substr(data, 1, 1)==X'0D' FROM sqlite_dbpage WHERE pgno=o.pgno"
");"
/* Extract data from page 1 and any linked pages into table
** recovery.schema. With the same schema as an sqlite_master table. */
"CREATE TABLE recovery.schema(type, name, tbl_name, rootpage, sql);"
"INSERT INTO recovery.schema SELECT "
" max(CASE WHEN field=0 THEN value ELSE NULL END),"
" max(CASE WHEN field=1 THEN value ELSE NULL END),"
" max(CASE WHEN field=2 THEN value ELSE NULL END),"
" max(CASE WHEN field=3 THEN value ELSE NULL END),"
" max(CASE WHEN field=4 THEN value ELSE NULL END)"
"FROM sqlite_dbdata WHERE pgno IN ("
" SELECT pgno FROM recovery.map WHERE root=1"
")"
"GROUP BY pgno, cell;"
"CREATE INDEX recovery.schema_rootpage ON schema(rootpage);"
);
/* Open a transaction, then print out all non-virtual, non-"sqlite_%"
** CREATE TABLE statements that extracted from the existing schema. */
if( rc==SQLITE_OK ){
sqlite3_stmt *pStmt = 0;
raw_printf(pState->out, "BEGIN;\n");
raw_printf(pState->out, "PRAGMA writable_schema = on;\n");
shellPrepare(pState->db, &rc,
"SELECT sql FROM recovery.schema "
"WHERE type='table' AND sql LIKE 'create table%'", &pStmt
);
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
const char *zCreateTable = (const char*)sqlite3_column_text(pStmt, 0);
raw_printf(pState->out, "CREATE TABLE IF NOT EXISTS %s;\n",
&zCreateTable[12]
);
}
shellFinalize(&rc, pStmt);
}
/* Figure out if an orphan table will be required. And if so, how many
** user columns it should contain */
shellPrepare(pState->db, &rc,
"SELECT coalesce(max(maxlen), -2) FROM recovery.map WHERE root>1"
, &pLoop
);
if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pLoop) ){
nOrphan = sqlite3_column_int(pLoop, 0);
}
shellFinalize(&rc, pLoop);
pLoop = 0;
shellPrepare(pState->db, &rc,
"SELECT pgno FROM recovery.map WHERE root=?", &pPages
);
shellPrepare(pState->db, &rc,
"SELECT max(field), group_concat(shell_escape_crnl(quote(value)), ', ')"
"FROM sqlite_dbdata WHERE pgno = ? AND field != ?"
"GROUP BY cell", &pCells
);
/* Loop through each root page. */
shellPrepare(pState->db, &rc,
"SELECT root, intkey, max(maxlen) FROM recovery.map"
" WHERE root>1 GROUP BY root, intkey ORDER BY root=("
" SELECT rootpage FROM recovery.schema WHERE name='sqlite_sequence'"
")", &pLoop
);
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pLoop) ){
int iRoot = sqlite3_column_int(pLoop, 0);
int bIntkey = sqlite3_column_int(pLoop, 1);
int nCol = sqlite3_column_int(pLoop, 2);
int bNoop = 0;
RecoverTable *pTab;
pTab = recoverFindTable(pState, &rc, iRoot, bIntkey, nCol, &bNoop);
if( bNoop || rc ) continue;
if( pTab==0 ){
if( pOrphan==0 ){
pOrphan = recoverOrphanTable(pState, &rc, zLostAndFound, nOrphan);
}
pTab = pOrphan;
if( pTab==0 ) break;
}
if( 0==sqlite3_stricmp(pTab->zQuoted, "'sqlite_sequence'") ){
raw_printf(pState->out, "DELETE FROM sqlite_sequence;\n");
}
sqlite3_bind_int(pPages, 1, iRoot);
sqlite3_bind_int(pCells, 2, pTab->iPk);
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPages) ){
int iPgno = sqlite3_column_int(pPages, 0);
sqlite3_bind_int(pCells, 1, iPgno);
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pCells) ){
int nField = sqlite3_column_int(pCells, 0);
const char *zVal = (const char*)sqlite3_column_text(pCells, 1);
nField = nField+1;
if( pTab==pOrphan ){
raw_printf(pState->out,
"INSERT INTO %s VALUES(%d, %d, %d, %s%s%s);\n",
pTab->zQuoted, iRoot, iPgno, nField,
bIntkey ? "" : "NULL, ", zVal, pTab->azlCol[nField]
);
}else{
raw_printf(pState->out, "INSERT INTO %s(%s) VALUES( %s );\n",
pTab->zQuoted, pTab->azlCol[nField], zVal
);
}
}
shellReset(&rc, pCells);
}
shellReset(&rc, pPages);
if( pTab!=pOrphan ) recoverFreeTable(pTab);
}
shellFinalize(&rc, pLoop);
shellFinalize(&rc, pPages);
shellFinalize(&rc, pCells);
recoverFreeTable(pOrphan);
/* The rest of the schema */
if( rc==SQLITE_OK ){
sqlite3_stmt *pStmt = 0;
shellPrepare(pState->db, &rc,
"SELECT sql, name FROM recovery.schema "
"WHERE sql NOT LIKE 'create table%'", &pStmt
);
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
const char *zSql = (const char*)sqlite3_column_text(pStmt, 0);
if( sqlite3_strnicmp(zSql, "create virt", 11)==0 ){
const char *zName = (const char*)sqlite3_column_text(pStmt, 1);
char *zPrint = shellMPrintf(&rc,
"INSERT INTO sqlite_master VALUES('table', %Q, %Q, 0, %Q)",
zName, zName, zSql
);
raw_printf(pState->out, "%s;\n", zPrint);
sqlite3_free(zPrint);
}else{
raw_printf(pState->out, "%s;\n", zSql);
}
}
shellFinalize(&rc, pStmt);
}
if( rc==SQLITE_OK ){
raw_printf(pState->out, "PRAGMA writable_schema = off;\n");
raw_printf(pState->out, "COMMIT;\n");
}
sqlite3_exec(pState->db, "DETACH recovery", 0, 0, 0);
return rc;
}
#endif /* !(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) */
/*
** If an input line begins with "." then invoke this routine to
@@ -7080,13 +6316,6 @@ static int do_meta_command(char *zLine, ShellState *p){
rc = shell_dbinfo_command(p, nArg, azArg);
}else
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
if( c=='r' && strncmp(azArg[0], "recover", n)==0 ){
open_db(p, 0);
rc = recoverDatabaseCmd(p, nArg, azArg);
}else
#endif /* !(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) */
if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
const char *zLike = 0;
int i;
@@ -7124,9 +6353,7 @@ static int do_meta_command(char *zLine, ShellState *p){
zLike = azArg[i];
}
}
open_db(p, 0);
/* When playing back a "dump", the content might appear in an order
** which causes immediate foreign key constraints to be violated.
** So disable foreign-key constraint enforcement to prevent problems. */
@@ -7174,7 +6401,7 @@ static int do_meta_command(char *zLine, ShellState *p){
}
sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
raw_printf(p->out, p->nErr?"ROLLBACK; -- due to errors\n":"COMMIT;\n");
raw_printf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
p->showHeader = savedShowHeader;
p->shellFlgs = savedShellFlags;
}else
+12 -2
View File
@@ -7319,8 +7319,7 @@ int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_SORTER_MMAP 24
#define SQLITE_TESTCTRL_IMPOSTER 25
#define SQLITE_TESTCTRL_PARSER_COVERAGE 26
#define SQLITE_TESTCTRL_RESULT_INTREAL 27
#define SQLITE_TESTCTRL_LAST 27 /* Largest TESTCTRL */
#define SQLITE_TESTCTRL_LAST 26 /* Largest TESTCTRL */
/*
** CAPI3REF: SQL Keyword Checking
@@ -7848,6 +7847,15 @@ int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
** used to store the prepared statement. ^This value is not actually
** a counter, and so the resetFlg parameter to sqlite3_stmt_status()
** is ignored when the opcode is SQLITE_STMTSTATUS_MEMUSED.
**
** [[SQLITE_STMTSTATUS_EST_ROWS]] <dt>SQLITE_STMTSTATUS_EST_ROWS</dt>
** <dd>^A return value of X indicates that the query planner estimated
** that the query will return pow(2,X/10.0) rows.
**
** [[SQLITE_STMTSTATUS_EST_COST]] <dt>SQLITE_STMTSTATUS_EST_COST</dt>
** <dd>^A return value of X indicates that the query planner estimated
** the relative cost of running this statement to completion is
** pow(2,X/10.0).
** </dd>
** </dl>
*/
@@ -7858,6 +7866,8 @@ int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
#define SQLITE_STMTSTATUS_REPREPARE 5
#define SQLITE_STMTSTATUS_RUN 6
#define SQLITE_STMTSTATUS_MEMUSED 99
#define SQLITE_STMTSTATUS_EST_ROWS 100
#define SQLITE_STMTSTATUS_EST_COST 101
/*
** CAPI3REF: Custom Page Cache Object
-3
View File
@@ -4272,9 +4272,6 @@ void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8,
void(*)(void*));
void sqlite3ValueSetNull(sqlite3_value*);
void sqlite3ValueFree(sqlite3_value*);
#ifndef SQLITE_UNTESTABLE
void sqlite3ResultIntReal(sqlite3_context*);
#endif
sqlite3_value *sqlite3ValueNew(sqlite3 *);
#ifndef SQLITE_OMIT_UTF16
char *sqlite3Utf16to8(sqlite3 *, const void*, int, u8);
-22
View File
@@ -998,20 +998,6 @@ static void nondeterministicFunction(
sqlite3_result_int(context, cnt++);
}
/*
** This SQL function returns the integer value of its argument as a MEM_IntReal
** value.
*/
static void intrealFunction(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
sqlite3_int64 v = sqlite3_value_int64(argv[0]);
sqlite3_result_int64(context, v);
sqlite3_test_control(SQLITE_TESTCTRL_RESULT_INTREAL, context);
}
/*
** Usage: sqlite3_create_function DB
**
@@ -1076,14 +1062,6 @@ static int SQLITE_TCLAPI test_create_function(
0, nondeterministicFunction, 0, 0);
}
/* The intreal() function converts its argument to an integer and returns
** it as a MEM_IntReal.
*/
if( rc==SQLITE_OK ){
rc = sqlite3_create_function(db, "intreal", 1, SQLITE_UTF8,
0, intrealFunction, 0, 0);
}
#ifndef SQLITE_OMIT_UTF16
/* Use the sqlite3_create_function16() API here. Mainly for fun, but also
** because it is not tested anywhere else. */
+7 -17
View File
@@ -155,12 +155,11 @@ void sqlite3Update(
Index *pIdx; /* For looping over indices */
Index *pPk; /* The PRIMARY KEY index for WITHOUT ROWID tables */
int nIdx; /* Number of indices that need updating */
int nAllIdx; /* Total number of indexes */
int iBaseCur; /* Base cursor number */
int iDataCur; /* Cursor for the canonical data btree */
int iIdxCur; /* Cursor for the first index */
sqlite3 *db; /* The database structure */
int *aRegIdx = 0; /* Registers for to each index and the main table */
int *aRegIdx = 0; /* First register in array assigned to each index */
int *aXRef = 0; /* aXRef[i] is the index in pChanges->a[] of the
** an expression for the i-th column of the table.
** aXRef[i]==-1 if the i-th column is not changed. */
@@ -274,10 +273,10 @@ void sqlite3Update(
/* Allocate space for aXRef[], aRegIdx[], and aToOpen[].
** Initialize aXRef[] and aToOpen[] to their default values.
*/
aXRef = sqlite3DbMallocRawNN(db, sizeof(int) * (pTab->nCol+nIdx+1) + nIdx+2 );
aXRef = sqlite3DbMallocRawNN(db, sizeof(int) * (pTab->nCol+nIdx) + nIdx+2 );
if( aXRef==0 ) goto update_cleanup;
aRegIdx = aXRef+pTab->nCol;
aToOpen = (u8*)(aRegIdx+nIdx+1);
aToOpen = (u8*)(aRegIdx+nIdx);
memset(aToOpen, 1, nIdx+1);
aToOpen[nIdx+1] = 0;
for(i=0; i<pTab->nCol; i++) aXRef[i] = -1;
@@ -356,7 +355,7 @@ void sqlite3Update(
** the key for accessing each index.
*/
if( onError==OE_Replace ) bReplace = 1;
for(nAllIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nAllIdx++){
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
int reg;
if( chngKey || hasFK>1 || pIdx==pPk
|| indexWhereClauseMightChange(pIdx,aXRef,chngRowid)
@@ -376,10 +375,9 @@ void sqlite3Update(
}
}
}
if( reg==0 ) aToOpen[nAllIdx+1] = 0;
aRegIdx[nAllIdx] = reg;
if( reg==0 ) aToOpen[j+1] = 0;
aRegIdx[j] = reg;
}
aRegIdx[nAllIdx] = ++pParse->nMem; /* Register storing the table record */
if( bReplace ){
/* If REPLACE conflict resolution might be invoked, open cursors on all
** indexes in case they are needed to delete records. */
@@ -394,13 +392,7 @@ void sqlite3Update(
/* Allocate required registers. */
if( !IsVirtual(pTab) ){
/* For now, regRowSet and aRegIdx[nAllIdx] share the same register.
** If regRowSet turns out to be needed, then aRegIdx[nAllIdx] will be
** reallocated. aRegIdx[nAllIdx] is the register in which the main
** table record is written. regRowSet holds the RowSet for the
** two-pass update algorithm. */
assert( aRegIdx[nAllIdx]==pParse->nMem );
regRowSet = aRegIdx[nAllIdx];
regRowSet = ++pParse->nMem;
regOldRowid = regNewRowid = ++pParse->nMem;
if( chngPk || pTrigger || hasFK ){
regOld = pParse->nMem + 1;
@@ -530,8 +522,6 @@ void sqlite3Update(
** leave it in register regOldRowid. */
sqlite3VdbeAddOp2(v, OP_Rowid, iDataCur, regOldRowid);
if( eOnePass==ONEPASS_OFF ){
/* We need to use regRowSet, so reallocate aRegIdx[nAllIdx] */
aRegIdx[nAllIdx] = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, regOldRowid);
}
}else{
+3 -1
View File
@@ -17,7 +17,9 @@
*/
#include "sqliteInt.h"
#include <stdarg.h>
#include <math.h>
#if HAVE_ISNAN || SQLITE_HAVE_ISNAN
# include <math.h>
#endif
/*
** Routine needed to support the testcase() macro.
+59 -112
View File
@@ -195,6 +195,14 @@ int sqlite3_found_count = 0;
}
#endif
/*
** Convert the given register into a string if it isn't one
** already. Return non-zero if a malloc() fails.
*/
#define Stringify(P, enc) \
if(((P)->flags&(MEM_Str|MEM_Blob))==0 && sqlite3VdbeMemStringify(P,enc,0)) \
{ goto no_mem; }
/*
** An ephemeral string value (signified by the MEM_Ephem flag) contains
** a pointer to a dynamically allocated string where some other entity
@@ -256,7 +264,7 @@ static VdbeCursor *allocateCursor(
** is clear. Otherwise, if this is an ephemeral cursor created by
** OP_OpenDup, the cursor will not be closed and will still be part
** of a BtShared.pCursor list. */
if( p->apCsr[iCur]->pBtx==0 ) p->apCsr[iCur]->isEphemeral = 0;
p->apCsr[iCur]->isEphemeral = 0;
sqlite3VdbeFreeCursor(p, p->apCsr[iCur]);
p->apCsr[iCur] = 0;
}
@@ -295,7 +303,7 @@ static void applyNumericAffinity(Mem *pRec, int bTryForInt){
double rValue;
i64 iValue;
u8 enc = pRec->enc;
assert( (pRec->flags & (MEM_Str|MEM_Int|MEM_Real|MEM_IntReal))==MEM_Str );
assert( (pRec->flags & (MEM_Str|MEM_Int|MEM_Real))==MEM_Str );
if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return;
if( 0==sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){
pRec->u.i = iValue;
@@ -352,14 +360,11 @@ static void applyAffinity(
** there is already a string rep, but it is pointless to waste those
** CPU cycles. */
if( 0==(pRec->flags&MEM_Str) ){ /*OPTIMIZATION-IF-FALSE*/
if( (pRec->flags&(MEM_Real|MEM_Int|MEM_IntReal)) ){
testcase( pRec->flags & MEM_Int );
testcase( pRec->flags & MEM_Real );
testcase( pRec->flags & MEM_IntReal );
if( (pRec->flags&(MEM_Real|MEM_Int)) ){
sqlite3VdbeMemStringify(pRec, enc, 1);
}
}
pRec->flags &= ~(MEM_Real|MEM_Int|MEM_IntReal);
pRec->flags &= ~(MEM_Real|MEM_Int);
}
}
@@ -398,7 +403,7 @@ void sqlite3ValueApplyAffinity(
** accordingly.
*/
static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){
assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal))==0 );
assert( (pMem->flags & (MEM_Int|MEM_Real))==0 );
assert( (pMem->flags & (MEM_Str|MEM_Blob))!=0 );
ExpandBlob(pMem);
if( sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc)==0 ){
@@ -418,15 +423,10 @@ static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){
** But it does set pMem->u.r and pMem->u.i appropriately.
*/
static u16 numericType(Mem *pMem){
if( pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal) ){
testcase( pMem->flags & MEM_Int );
testcase( pMem->flags & MEM_Real );
testcase( pMem->flags & MEM_IntReal );
return pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal);
if( pMem->flags & (MEM_Int|MEM_Real) ){
return pMem->flags & (MEM_Int|MEM_Real);
}
if( pMem->flags & (MEM_Str|MEM_Blob) ){
testcase( pMem->flags & MEM_Str );
testcase( pMem->flags & MEM_Blob );
return computeNumericType(pMem);
}
return 0;
@@ -522,8 +522,6 @@ static void memTracePrint(Mem *p){
printf(p->flags & MEM_Zero ? " NULL-nochng" : " NULL");
}else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
printf(" si:%lld", p->u.i);
}else if( (p->flags & (MEM_IntReal))!=0 ){
printf(" ir:%lld", p->u.i);
}else if( p->flags & MEM_Int ){
printf(" i:%lld", p->u.i);
#ifndef SQLITE_OMIT_FLOATING_POINT
@@ -1465,38 +1463,19 @@ case OP_ResultRow: {
** to avoid a memcpy().
*/
case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
i64 nByte; /* Total size of the output string or blob */
u16 flags1; /* Initial flags for P1 */
u16 flags2; /* Initial flags for P2 */
i64 nByte;
pIn1 = &aMem[pOp->p1];
pIn2 = &aMem[pOp->p2];
pOut = &aMem[pOp->p3];
testcase( pIn1==pIn2 );
testcase( pOut==pIn2 );
assert( pIn1!=pOut );
flags1 = pIn1->flags;
testcase( flags1 & MEM_Null );
testcase( pIn2->flags & MEM_Null );
if( (flags1 | pIn2->flags) & MEM_Null ){
if( (pIn1->flags | pIn2->flags) & MEM_Null ){
sqlite3VdbeMemSetNull(pOut);
break;
}
if( (flags1 & (MEM_Str|MEM_Blob))==0 ){
if( sqlite3VdbeMemStringify(pIn1,encoding,0) ) goto no_mem;
flags1 = pIn1->flags & ~MEM_Str;
}else if( (flags1 & MEM_Zero)!=0 ){
if( sqlite3VdbeMemExpandBlob(pIn1) ) goto no_mem;
flags1 = pIn1->flags & ~MEM_Str;
}
flags2 = pIn2->flags;
if( (flags2 & (MEM_Str|MEM_Blob))==0 ){
if( sqlite3VdbeMemStringify(pIn2,encoding,0) ) goto no_mem;
flags2 = pIn2->flags & ~MEM_Str;
}else if( (flags2 & MEM_Zero)!=0 ){
if( sqlite3VdbeMemExpandBlob(pIn2) ) goto no_mem;
flags2 = pIn2->flags & ~MEM_Str;
}
if( ExpandBlob(pIn1) || ExpandBlob(pIn2) ) goto no_mem;
Stringify(pIn1, encoding);
Stringify(pIn2, encoding);
nByte = pIn1->n + pIn2->n;
if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
@@ -1507,12 +1486,8 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
MemSetTypeFlag(pOut, MEM_Str);
if( pOut!=pIn2 ){
memcpy(pOut->z, pIn2->z, pIn2->n);
assert( (pIn2->flags & MEM_Dyn) == (flags2 & MEM_Dyn) );
pIn2->flags = flags2;
}
memcpy(&pOut->z[pIn2->n], pIn1->z, pIn1->n);
assert( (pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn) );
pIn1->flags = flags1;
pOut->z[nByte]=0;
pOut->z[nByte+1] = 0;
pOut->flags |= MEM_Term;
@@ -1638,7 +1613,7 @@ fp_math:
}
pOut->u.r = rB;
MemSetTypeFlag(pOut, MEM_Real);
if( ((type1|type2)&(MEM_Real|MEM_IntReal))==0 && !bIntint ){
if( ((type1|type2)&MEM_Real)==0 && !bIntint ){
sqlite3VdbeIntegerAffinity(pOut);
}
#endif
@@ -1809,9 +1784,7 @@ case OP_MustBeInt: { /* jump, in1 */
*/
case OP_RealAffinity: { /* in1 */
pIn1 = &aMem[pOp->p1];
if( pIn1->flags & (MEM_Int|MEM_IntReal) ){
testcase( pIn1->flags & MEM_Int );
testcase( pIn1->flags & MEM_IntReal );
if( pIn1->flags & MEM_Int ){
sqlite3VdbeMemRealify(pIn1);
}
break;
@@ -2003,7 +1976,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
affinity = pOp->p5 & SQLITE_AFF_MASK;
if( affinity>=SQLITE_AFF_NUMERIC ){
if( (flags1 | flags3)&MEM_Str ){
if( (flags1 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){
if( (flags1 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
applyNumericAffinity(pIn1,0);
assert( flags3==pIn3->flags );
/* testcase( flags3!=pIn3->flags );
@@ -2013,7 +1986,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
** in case our analysis is incorrect, so it is left in. */
flags3 = pIn3->flags;
}
if( (flags3 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){
if( (flags3 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
applyNumericAffinity(pIn3,0);
}
}
@@ -2026,19 +1999,17 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
goto compare_op;
}
}else if( affinity==SQLITE_AFF_TEXT ){
if( (flags1 & MEM_Str)==0 && (flags1&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){
if( (flags1 & MEM_Str)==0 && (flags1 & (MEM_Int|MEM_Real))!=0 ){
testcase( pIn1->flags & MEM_Int );
testcase( pIn1->flags & MEM_Real );
testcase( pIn1->flags & MEM_IntReal );
sqlite3VdbeMemStringify(pIn1, encoding, 1);
testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) );
flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask);
assert( pIn1!=pIn3 );
}
if( (flags3 & MEM_Str)==0 && (flags3&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){
if( (flags3 & MEM_Str)==0 && (flags3 & (MEM_Int|MEM_Real))!=0 ){
testcase( pIn3->flags & MEM_Int );
testcase( pIn3->flags & MEM_Real );
testcase( pIn3->flags & MEM_IntReal );
sqlite3VdbeMemStringify(pIn3, encoding, 1);
testcase( (flags3&MEM_Dyn) != (pIn3->flags&MEM_Dyn) );
flags3 = (pIn3->flags & ~MEM_TypeMask) | (flags3 & MEM_TypeMask);
@@ -2794,21 +2765,12 @@ case OP_Affinity: {
assert( pOp->p2>0 );
assert( zAffinity[pOp->p2]==0 );
pIn1 = &aMem[pOp->p1];
while( 1 /*edit-by-break*/ ){
do{
assert( pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)] );
assert( memIsValid(pIn1) );
applyAffinity(pIn1, zAffinity[0], encoding);
if( zAffinity[0]==SQLITE_AFF_REAL && (pIn1->flags & MEM_Int)!=0 ){
/* When applying REAL affinity, if the result is still MEM_Int,
** indicate that REAL is actually desired */
pIn1->flags |= MEM_IntReal;
pIn1->flags &= ~MEM_Int;
}
REGISTER_TRACE((int)(pIn1-aMem), pIn1);
zAffinity++;
if( zAffinity[0]==0 ) break;
applyAffinity(pIn1, *(zAffinity++), encoding);
pIn1++;
}
}while( zAffinity[0] );
break;
}
@@ -2829,6 +2791,7 @@ case OP_Affinity: {
** If P4 is NULL then all index fields have the affinity BLOB.
*/
case OP_MakeRecord: {
u8 *zNewRecord; /* A buffer to hold the data for the new record */
Mem *pRec; /* The new record */
u64 nData; /* Number of bytes of data space */
int nHdr; /* Number of bytes of header space */
@@ -2841,9 +2804,9 @@ case OP_MakeRecord: {
int nField; /* Number of fields in the record */
char *zAffinity; /* The affinity string for the record */
int file_format; /* File format to use for encoding */
int i; /* Space used in zNewRecord[] header */
int j; /* Space used in zNewRecord[] content */
u32 len; /* Length of a field */
u8 *zHdr; /* Where to write next byte of the header */
u8 *zPayload; /* Where to write next byte of the payload */
/* Assuming the record contains N fields, the record format looks
** like this:
@@ -2882,10 +2845,7 @@ case OP_MakeRecord: {
if( zAffinity ){
pRec = pData0;
do{
applyAffinity(pRec, zAffinity[0], encoding);
REGISTER_TRACE((int)(pRec-aMem), pRec);
zAffinity++;
pRec++;
applyAffinity(pRec++, *(zAffinity++), encoding);
assert( zAffinity[0]==0 || pRec<=pLast );
}while( zAffinity[0] );
}
@@ -2973,34 +2933,34 @@ case OP_MakeRecord: {
goto no_mem;
}
}
pOut->n = (int)nByte;
pOut->flags = MEM_Blob;
if( nZero ){
pOut->u.nZero = nZero;
pOut->flags |= MEM_Zero;
}
UPDATE_MAX_BLOBSIZE(pOut);
zHdr = (u8 *)pOut->z;
zPayload = zHdr + nHdr;
zNewRecord = (u8 *)pOut->z;
/* Write the record */
zHdr += putVarint32(zHdr, nHdr);
i = putVarint32(zNewRecord, nHdr);
j = nHdr;
assert( pData0<=pLast );
pRec = pData0;
do{
serial_type = pRec->uTemp;
/* EVIDENCE-OF: R-06529-47362 Following the size varint are one or more
** additional varints, one per column. */
zHdr += putVarint32(zHdr, serial_type); /* serial type */
i += putVarint32(&zNewRecord[i], serial_type); /* serial type */
/* EVIDENCE-OF: R-64536-51728 The values for each column in the record
** immediately follow the header. */
zPayload += sqlite3VdbeSerialPut(zPayload, pRec, serial_type); /* content */
j += sqlite3VdbeSerialPut(&zNewRecord[j], pRec, serial_type); /* content */
}while( (++pRec)<=pLast );
assert( nHdr==(int)(zHdr - (u8*)pOut->z) );
assert( nByte==(int)(zPayload - (u8*)pOut->z) );
assert( i==nHdr );
assert( j==nByte );
assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
pOut->n = (int)nByte;
pOut->flags = MEM_Blob;
if( nZero ){
pOut->u.nZero = nZero;
pOut->flags |= MEM_Zero;
}
REGISTER_TRACE(pOp->p3, pOut);
UPDATE_MAX_BLOBSIZE(pOut);
break;
}
@@ -3030,9 +2990,8 @@ case OP_Count: { /* out2 */
/* Opcode: Savepoint P1 * * P4 *
**
** Open, release or rollback the savepoint named by parameter P4, depending
** on the value of P1. To open a new savepoint set P1==0 (SAVEPOINT_BEGIN).
** To release (commit) an existing savepoint set P1==1 (SAVEPOINT_RELEASE).
** To rollback an existing savepoint set P1==2 (SAVEPOINT_ROLLBACK).
** on the value of P1. To open a new savepoint, P1==0. To release (commit) an
** existing savepoint, P1==1, or to rollback an existing savepoint P1==2.
*/
case OP_Savepoint: {
int p1; /* Value of P1 operand */
@@ -3100,7 +3059,6 @@ case OP_Savepoint: {
}
}
}else{
assert( p1==SAVEPOINT_RELEASE || p1==SAVEPOINT_ROLLBACK );
iSavepoint = 0;
/* Find the named savepoint. If there is no such savepoint, then an
@@ -3154,7 +3112,6 @@ case OP_Savepoint: {
if( rc!=SQLITE_OK ) goto abort_due_to_error;
}
}else{
assert( p1==SAVEPOINT_RELEASE );
isSchemaChange = 0;
}
for(ii=0; ii<db->nDb; ii++){
@@ -3191,7 +3148,6 @@ case OP_Savepoint: {
db->nSavepoint--;
}
}else{
assert( p1==SAVEPOINT_ROLLBACK );
db->nDeferredCons = pSavepoint->nDeferredCons;
db->nDeferredImmCons = pSavepoint->nDeferredImmCons;
}
@@ -3730,10 +3686,7 @@ case OP_OpenEphemeral: {
if( pCx ){
/* If the ephermeral table is already open, erase all existing content
** so that the table is empty again, rather than creating a new table. */
assert( pCx->isEphemeral );
if( pCx->pBtx ){
rc = sqlite3BtreeClearTable(pCx->pBtx, pCx->pgnoRoot, 0);
}
rc = sqlite3BtreeClearTable(pCx->pBtx, pCx->pgnoRoot, 0);
}else{
pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_BTREE);
if( pCx==0 ) goto no_mem;
@@ -4010,24 +3963,20 @@ case OP_SeekGT: { /* jump, in3, group */
** blob, or NULL. But it needs to be an integer before we can do
** the seek, so convert it. */
pIn3 = &aMem[pOp->p3];
if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Str))==MEM_Str ){
if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
applyNumericAffinity(pIn3, 0);
}
iKey = sqlite3VdbeIntValue(pIn3);
/* If the P3 value could not be converted into an integer without
** loss of information, then special processing is required... */
if( (pIn3->flags & (MEM_Int|MEM_IntReal))==0 ){
if( (pIn3->flags & MEM_Int)==0 ){
if( (pIn3->flags & MEM_Real)==0 ){
if( (pIn3->flags & MEM_Null) || oc>=OP_SeekGE ){
VdbeBranchTaken(1,2); goto jump_to_p2;
break;
}else{
rc = sqlite3BtreeLast(pC->uc.pCursor, &res);
if( rc!=SQLITE_OK ) goto abort_due_to_error;
goto seek_not_found;
}
}else
/* If the P3 value cannot be converted into any kind of a number,
** then the seek is not possible, so jump to P2 */
VdbeBranchTaken(1,2); goto jump_to_p2;
break;
}
/* If the approximation iKey is larger than the actual real search
** term, substitute >= for > and < for <=. e.g. if the search term
@@ -4051,7 +4000,7 @@ case OP_SeekGT: { /* jump, in3, group */
assert( (OP_SeekLT & 0x0001)==(OP_SeekGE & 0x0001) );
if( (oc & 0x0001)==(OP_SeekLT & 0x0001) ) oc++;
}
}
}
rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, 0, (u64)iKey, 0, &res);
pC->movetoTarget = iKey; /* Used by OP_Delete */
if( rc!=SQLITE_OK ){
@@ -4406,9 +4355,7 @@ case OP_SeekRowid: { /* jump, in3 */
u64 iKey;
pIn3 = &aMem[pOp->p3];
testcase( pIn3->flags & MEM_Int );
testcase( pIn3->flags & MEM_IntReal );
if( (pIn3->flags & (MEM_Int|MEM_IntReal))==0 ){
if( (pIn3->flags & MEM_Int)==0 ){
/* Make sure pIn3->u.i contains a valid integer representation of
** the key value, but do not change the datatype of the register, as
** other parts of the perpared statement might be depending on the
+1
View File
@@ -264,6 +264,7 @@ void sqlite3VdbeSwap(Vdbe*,Vdbe*);
VdbeOp *sqlite3VdbeTakeOpArray(Vdbe*, int*, int*);
sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe*, int, u8);
void sqlite3VdbeSetVarmask(Vdbe*, int);
void sqlite3VdbeUpdateCostEstimates(Parse*, LogEst, LogEst);
#ifndef SQLITE_OMIT_TRACE
char *sqlite3VdbeExpandSql(Vdbe*, const char*);
#endif
+6 -4
View File
@@ -245,12 +245,12 @@ struct sqlite3_value {
#define MEM_Int 0x0004 /* Value is an integer */
#define MEM_Real 0x0008 /* Value is a real number */
#define MEM_Blob 0x0010 /* Value is a BLOB */
#define MEM_IntReal 0x0020 /* MEM_Int that stringifies like MEM_Real */
#define MEM_AffMask 0x003f /* Mask of affinity bits */
#define MEM_FromBind 0x0040 /* Value originates from sqlite3_bind() */
#define MEM_AffMask 0x001f /* Mask of affinity bits */
#define MEM_FromBind 0x0020 /* Value originates from sqlite3_bind() */
/* Available 0x0040 */
#define MEM_Undefined 0x0080 /* Value is undefined */
#define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */
#define MEM_TypeMask 0xc1bf /* Mask of type bits */
#define MEM_TypeMask 0xc1df /* Mask of type bits */
/* Whenever Mem contains a valid string or blob representation, one of
@@ -425,6 +425,8 @@ struct Vdbe {
bft usesStmtJournal:1; /* True if uses a statement journal */
bft readOnly:1; /* True for statements that do not write */
bft bIsReader:1; /* True for statements that read */
LogEst nRowEst; /* Query planner of estimated number of output rows */
LogEst iCostEst; /* Query planner cost estimate */
yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */
yDbMask lockMask; /* Subset of btreeMask that requires a lock */
u32 aCounter[7]; /* Counters used by sqlite3_stmt_status() */
+63 -115
View File
@@ -234,86 +234,39 @@ const void *sqlite3_value_text16le(sqlite3_value *pVal){
*/
int sqlite3_value_type(sqlite3_value* pVal){
static const u8 aType[] = {
SQLITE_BLOB, /* 0x00 (not possible) */
SQLITE_NULL, /* 0x01 NULL */
SQLITE_TEXT, /* 0x02 TEXT */
SQLITE_NULL, /* 0x03 (not possible) */
SQLITE_INTEGER, /* 0x04 INTEGER */
SQLITE_NULL, /* 0x05 (not possible) */
SQLITE_INTEGER, /* 0x06 INTEGER + TEXT */
SQLITE_NULL, /* 0x07 (not possible) */
SQLITE_FLOAT, /* 0x08 FLOAT */
SQLITE_NULL, /* 0x09 (not possible) */
SQLITE_FLOAT, /* 0x0a FLOAT + TEXT */
SQLITE_NULL, /* 0x0b (not possible) */
SQLITE_INTEGER, /* 0x0c (not possible) */
SQLITE_NULL, /* 0x0d (not possible) */
SQLITE_INTEGER, /* 0x0e (not possible) */
SQLITE_NULL, /* 0x0f (not possible) */
SQLITE_BLOB, /* 0x10 BLOB */
SQLITE_NULL, /* 0x11 (not possible) */
SQLITE_TEXT, /* 0x12 (not possible) */
SQLITE_NULL, /* 0x13 (not possible) */
SQLITE_INTEGER, /* 0x14 INTEGER + BLOB */
SQLITE_NULL, /* 0x15 (not possible) */
SQLITE_INTEGER, /* 0x16 (not possible) */
SQLITE_NULL, /* 0x17 (not possible) */
SQLITE_FLOAT, /* 0x18 FLOAT + BLOB */
SQLITE_NULL, /* 0x19 (not possible) */
SQLITE_FLOAT, /* 0x1a (not possible) */
SQLITE_NULL, /* 0x1b (not possible) */
SQLITE_INTEGER, /* 0x1c (not possible) */
SQLITE_NULL, /* 0x1d (not possible) */
SQLITE_INTEGER, /* 0x1e (not possible) */
SQLITE_NULL, /* 0x1f (not possible) */
SQLITE_FLOAT, /* 0x20 INTREAL */
SQLITE_NULL, /* 0x21 (not possible) */
SQLITE_TEXT, /* 0x22 INTREAL + TEXT */
SQLITE_NULL, /* 0x23 (not possible) */
SQLITE_FLOAT, /* 0x24 (not possible) */
SQLITE_NULL, /* 0x25 (not possible) */
SQLITE_FLOAT, /* 0x26 (not possible) */
SQLITE_NULL, /* 0x27 (not possible) */
SQLITE_FLOAT, /* 0x28 (not possible) */
SQLITE_NULL, /* 0x29 (not possible) */
SQLITE_FLOAT, /* 0x2a (not possible) */
SQLITE_NULL, /* 0x2b (not possible) */
SQLITE_FLOAT, /* 0x2c (not possible) */
SQLITE_NULL, /* 0x2d (not possible) */
SQLITE_FLOAT, /* 0x2e (not possible) */
SQLITE_NULL, /* 0x2f (not possible) */
SQLITE_BLOB, /* 0x30 (not possible) */
SQLITE_NULL, /* 0x31 (not possible) */
SQLITE_TEXT, /* 0x32 (not possible) */
SQLITE_NULL, /* 0x33 (not possible) */
SQLITE_FLOAT, /* 0x34 (not possible) */
SQLITE_NULL, /* 0x35 (not possible) */
SQLITE_FLOAT, /* 0x36 (not possible) */
SQLITE_NULL, /* 0x37 (not possible) */
SQLITE_FLOAT, /* 0x38 (not possible) */
SQLITE_NULL, /* 0x39 (not possible) */
SQLITE_FLOAT, /* 0x3a (not possible) */
SQLITE_NULL, /* 0x3b (not possible) */
SQLITE_FLOAT, /* 0x3c (not possible) */
SQLITE_NULL, /* 0x3d (not possible) */
SQLITE_FLOAT, /* 0x3e (not possible) */
SQLITE_NULL, /* 0x3f (not possible) */
SQLITE_BLOB, /* 0x00 */
SQLITE_NULL, /* 0x01 */
SQLITE_TEXT, /* 0x02 */
SQLITE_NULL, /* 0x03 */
SQLITE_INTEGER, /* 0x04 */
SQLITE_NULL, /* 0x05 */
SQLITE_INTEGER, /* 0x06 */
SQLITE_NULL, /* 0x07 */
SQLITE_FLOAT, /* 0x08 */
SQLITE_NULL, /* 0x09 */
SQLITE_FLOAT, /* 0x0a */
SQLITE_NULL, /* 0x0b */
SQLITE_INTEGER, /* 0x0c */
SQLITE_NULL, /* 0x0d */
SQLITE_INTEGER, /* 0x0e */
SQLITE_NULL, /* 0x0f */
SQLITE_BLOB, /* 0x10 */
SQLITE_NULL, /* 0x11 */
SQLITE_TEXT, /* 0x12 */
SQLITE_NULL, /* 0x13 */
SQLITE_INTEGER, /* 0x14 */
SQLITE_NULL, /* 0x15 */
SQLITE_INTEGER, /* 0x16 */
SQLITE_NULL, /* 0x17 */
SQLITE_FLOAT, /* 0x18 */
SQLITE_NULL, /* 0x19 */
SQLITE_FLOAT, /* 0x1a */
SQLITE_NULL, /* 0x1b */
SQLITE_INTEGER, /* 0x1c */
SQLITE_NULL, /* 0x1d */
SQLITE_INTEGER, /* 0x1e */
SQLITE_NULL, /* 0x1f */
};
#ifdef SQLITE_DEBUG
{
int eType = SQLITE_BLOB;
if( pVal->flags & MEM_Null ){
eType = SQLITE_NULL;
}else if( pVal->flags & (MEM_Real|MEM_IntReal) ){
eType = SQLITE_FLOAT;
}else if( pVal->flags & MEM_Int ){
eType = SQLITE_INTEGER;
}else if( pVal->flags & MEM_Str ){
eType = SQLITE_TEXT;
}
assert( eType == aType[pVal->flags&MEM_AffMask] );
}
#endif
return aType[pVal->flags&MEM_AffMask];
}
@@ -563,21 +516,6 @@ void sqlite3_result_error_nomem(sqlite3_context *pCtx){
sqlite3OomFault(pCtx->pOut->db);
}
#ifndef SQLITE_UNTESTABLE
/* Force the INT64 value currently stored as the result to be
** a MEM_IntReal value. See the SQLITE_TESTCTRL_RESULT_INTREAL
** test-control.
*/
void sqlite3ResultIntReal(sqlite3_context *pCtx){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
if( pCtx->pOut->flags & MEM_Int ){
pCtx->pOut->flags &= ~MEM_Int;
pCtx->pOut->flags |= MEM_IntReal;
}
}
#endif
/*
** This function is called after a transaction has been committed. It
** invokes callbacks registered with sqlite3_wal_hook() as required.
@@ -1720,27 +1658,39 @@ sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt){
*/
int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){
Vdbe *pVdbe = (Vdbe*)pStmt;
u32 v;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !pStmt
|| (op!=SQLITE_STMTSTATUS_MEMUSED && (op<0||op>=ArraySize(pVdbe->aCounter)))
){
u32 v = 0;
if( !pStmt ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
if( op==SQLITE_STMTSTATUS_MEMUSED ){
sqlite3 *db = pVdbe->db;
sqlite3_mutex_enter(db->mutex);
v = 0;
db->pnBytesFreed = (int*)&v;
sqlite3VdbeClearObject(db, pVdbe);
sqlite3DbFree(db, pVdbe);
db->pnBytesFreed = 0;
sqlite3_mutex_leave(db->mutex);
}else{
v = pVdbe->aCounter[op];
if( resetFlag ) pVdbe->aCounter[op] = 0;
switch( op ){
case SQLITE_STMTSTATUS_MEMUSED: {
sqlite3 *db = pVdbe->db;
sqlite3_mutex_enter(db->mutex);
v = 0;
db->pnBytesFreed = (int*)&v;
sqlite3VdbeClearObject(db, pVdbe);
sqlite3DbFree(db, pVdbe);
db->pnBytesFreed = 0;
sqlite3_mutex_leave(db->mutex);
break;
}
case SQLITE_STMTSTATUS_EST_ROWS: {
v = pVdbe->nRowEst;
break;
}
case SQLITE_STMTSTATUS_EST_COST: {
v = pVdbe->iCostEst;
break;
}
default: {
if( op>=0 && op<ArraySize(pVdbe->aCounter) ){
v = pVdbe->aCounter[op];
if( resetFlag ) pVdbe->aCounter[op] = 0;
}else{
(void)SQLITE_MISUSE_BKPT;
}
}
}
return (int)v;
}
@@ -1864,9 +1814,7 @@ int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){
}else if( iIdx>=p->pUnpacked->nField ){
*ppValue = (sqlite3_value *)columnNullValue();
}else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){
if( pMem->flags & (MEM_Int|MEM_IntReal) ){
testcase( pMem->flags & MEM_Int );
testcase( pMem->flags & MEM_IntReal );
if( pMem->flags & MEM_Int ){
sqlite3VdbeMemRealify(pMem);
}
}
+23 -39
View File
@@ -1534,7 +1534,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
Mem *pMem = pOp->p4.pMem;
if( pMem->flags & MEM_Str ){
zP4 = pMem->z;
}else if( pMem->flags & (MEM_Int|MEM_IntReal) ){
}else if( pMem->flags & MEM_Int ){
sqlite3_str_appendf(&x, "%lld", pMem->u.i);
}else if( pMem->flags & MEM_Real ){
sqlite3_str_appendf(&x, "%.16g", pMem->u.r);
@@ -2896,7 +2896,7 @@ int sqlite3VdbeHalt(Vdbe *p){
}
/* Check for immediate foreign key violations. */
if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){
if( p->rc==SQLITE_OK ){
sqlite3VdbeCheckFk(p, 0);
}
@@ -3422,8 +3422,6 @@ int sqlite3VdbeCursorMoveto(VdbeCursor **pp, int *piCol){
/*
** Return the serial-type for the value stored in pMem.
**
** This routine might convert a large MEM_IntReal value into MEM_Real.
*/
u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
int flags = pMem->flags;
@@ -3434,13 +3432,11 @@ u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
*pLen = 0;
return 0;
}
if( flags&(MEM_Int|MEM_IntReal) ){
if( flags&MEM_Int ){
/* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */
# define MAX_6BYTE ((((i64)0x00008000)<<32)-1)
i64 i = pMem->u.i;
u64 u;
testcase( flags & MEM_Int );
testcase( flags & MEM_IntReal );
if( i<0 ){
u = ~i;
}else{
@@ -3460,15 +3456,6 @@ u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
if( u<=2147483647 ){ *pLen = 4; return 4; }
if( u<=MAX_6BYTE ){ *pLen = 6; return 5; }
*pLen = 8;
if( flags&MEM_IntReal ){
/* If the value is IntReal and is going to take up 8 bytes to store
** as an integer, then we might as well make it an 8-byte floating
** point value */
pMem->u.r = (double)pMem->u.i;
pMem->flags &= ~MEM_IntReal;
pMem->flags |= MEM_Real;
return 7;
}
return 6;
}
if( flags&MEM_Real ){
@@ -4124,13 +4111,8 @@ int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){
/* At least one of the two values is a number
*/
if( combined_flags&(MEM_Int|MEM_Real|MEM_IntReal) ){
testcase( combined_flags & MEM_Int );
testcase( combined_flags & MEM_Real );
testcase( combined_flags & MEM_IntReal );
if( (f1 & f2 & (MEM_Int|MEM_IntReal))!=0 ){
testcase( f1 & f2 & MEM_Int );
testcase( f1 & f2 & MEM_IntReal );
if( combined_flags&(MEM_Int|MEM_Real) ){
if( (f1 & f2 & MEM_Int)!=0 ){
if( pMem1->u.i < pMem2->u.i ) return -1;
if( pMem1->u.i > pMem2->u.i ) return +1;
return 0;
@@ -4140,23 +4122,15 @@ int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){
if( pMem1->u.r > pMem2->u.r ) return +1;
return 0;
}
if( (f1&(MEM_Int|MEM_IntReal))!=0 ){
testcase( f1 & MEM_Int );
testcase( f1 & MEM_IntReal );
if( (f1&MEM_Int)!=0 ){
if( (f2&MEM_Real)!=0 ){
return sqlite3IntFloatCompare(pMem1->u.i, pMem2->u.r);
}else if( (f2&(MEM_Int|MEM_IntReal))!=0 ){
if( pMem1->u.i < pMem2->u.i ) return -1;
if( pMem1->u.i > pMem2->u.i ) return +1;
return 0;
}else{
return -1;
}
}
if( (f1&MEM_Real)!=0 ){
if( (f2&(MEM_Int|MEM_IntReal))!=0 ){
testcase( f2 & MEM_Int );
testcase( f2 & MEM_IntReal );
if( (f2&MEM_Int)!=0 ){
return -sqlite3IntFloatCompare(pMem2->u.i, pMem1->u.r);
}else{
return -1;
@@ -4305,9 +4279,7 @@ int sqlite3VdbeRecordCompareWithSkip(
u32 serial_type;
/* RHS is an integer */
if( pRhs->flags & (MEM_Int|MEM_IntReal) ){
testcase( pRhs->flags & MEM_Int );
testcase( pRhs->flags & MEM_IntReal );
if( pRhs->flags & MEM_Int ){
serial_type = aKey1[idx1];
testcase( serial_type==12 );
if( serial_type>=10 ){
@@ -4652,9 +4624,7 @@ RecordCompare sqlite3VdbeFindCompare(UnpackedRecord *p){
testcase( flags & MEM_Real );
testcase( flags & MEM_Null );
testcase( flags & MEM_Blob );
if( (flags & (MEM_Real|MEM_IntReal|MEM_Null|MEM_Blob))==0
&& p->pKeyInfo->aColl[0]==0
){
if( (flags & (MEM_Real|MEM_Null|MEM_Blob))==0 && p->pKeyInfo->aColl[0]==0 ){
assert( flags & MEM_Str );
return vdbeRecordCompareString;
}
@@ -4878,6 +4848,20 @@ void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){
}
}
/*
** Update the estimated cost fields
*/
void sqlite3VdbeUpdateCostEstimates(Parse *pParse, LogEst iCost, LogEst nRow){
Vdbe *v = pParse->pVdbe;
if( v->iCostEst ){
v->iCostEst = sqlite3LogEstAdd(v->iCostEst, iCost+pParse->nQueryLoop) + 1;
if( nRow > v->nRowEst ) v->nRowEst = nRow;
}else{
v->nRowEst = nRow;
v->iCostEst = iCost + 1;
}
}
/*
** Cause a function to throw an error if it was call from OP_PureFunc
** rather than OP_Function.
+43 -69
View File
@@ -18,11 +18,6 @@
#include "sqliteInt.h"
#include "vdbeInt.h"
/* True if X is a power of two. 0 is considered a power of two here.
** In other words, return true if X has at most one bit set.
*/
#define ISPOWEROF2(X) (((X)&((X)-1))==0)
#ifdef SQLITE_DEBUG
/*
** Check invariants on a Mem object.
@@ -42,8 +37,8 @@ int sqlite3VdbeCheckMemInvariants(Mem *p){
** That saves a few cycles in inner loops. */
assert( (p->flags & MEM_Dyn)==0 || p->szMalloc==0 );
/* Cannot have more than one of MEM_Int, MEM_Real, or MEM_IntReal */
assert( ISPOWEROF2(p->flags & (MEM_Int|MEM_Real|MEM_IntReal)) );
/* Cannot be both MEM_Int and MEM_Real at the same time */
assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) );
if( p->flags & MEM_Null ){
/* Cannot be both MEM_Null and some other type */
@@ -97,25 +92,6 @@ int sqlite3VdbeCheckMemInvariants(Mem *p){
}
#endif
/*
** Render a Mem object which is one of MEM_Int, MEM_Real, or MEM_IntReal
** into a buffer.
*/
static void vdbeMemRenderNum(int sz, char *zBuf, Mem *p){
StrAccum acc;
assert( p->flags & (MEM_Int|MEM_Real|MEM_IntReal) );
sqlite3StrAccumInit(&acc, 0, zBuf, sz, 0);
if( p->flags & MEM_Int ){
sqlite3_str_appendf(&acc, "%lld", p->u.i);
}else if( p->flags & MEM_IntReal ){
sqlite3_str_appendf(&acc, "%!.15g", (double)p->u.i);
}else{
sqlite3_str_appendf(&acc, "%!.15g", p->u.r);
}
assert( acc.zText==zBuf && acc.mxAlloc<=0 );
zBuf[acc.nChar] = 0; /* Fast version of sqlite3StrAccumFinish(&acc) */
}
#ifdef SQLITE_DEBUG
/*
** Check that string value of pMem agrees with its integer or real value.
@@ -141,8 +117,12 @@ int sqlite3VdbeMemConsistentDualRep(Mem *p){
char *z;
int i, j, incr;
if( (p->flags & MEM_Str)==0 ) return 1;
if( (p->flags & (MEM_Int|MEM_Real|MEM_IntReal))==0 ) return 1;
vdbeMemRenderNum(sizeof(zBuf), zBuf, p);
if( (p->flags & (MEM_Int|MEM_Real))==0 ) return 1;
if( p->flags & MEM_Int ){
sqlite3_snprintf(sizeof(zBuf),zBuf,"%lld",p->u.i);
}else{
sqlite3_snprintf(sizeof(zBuf),zBuf,"%!.15g",p->u.r);
}
z = p->z;
i = j = 0;
incr = 1;
@@ -254,8 +234,8 @@ SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){
**
** Any prior string or blob content in the pMem object may be discarded.
** The pMem->xDel destructor is called, if it exists. Though MEM_Str
** and MEM_Blob values may be discarded, MEM_Int, MEM_Real, MEM_IntReal,
** and MEM_Null values are preserved.
** and MEM_Blob values may be discarded, MEM_Int, MEM_Real, and MEM_Null
** values are preserved.
**
** Return SQLITE_OK on success or an error code (probably SQLITE_NOMEM)
** if unable to complete the resizing.
@@ -268,26 +248,20 @@ int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){
}
assert( (pMem->flags & MEM_Dyn)==0 );
pMem->z = pMem->zMalloc;
pMem->flags &= (MEM_Null|MEM_Int|MEM_Real|MEM_IntReal);
pMem->flags &= (MEM_Null|MEM_Int|MEM_Real);
return SQLITE_OK;
}
/*
** It is already known that pMem contains an unterminated string.
** Add the zero terminator.
**
** Three bytes of zero are added. In this way, there is guaranteed
** to be a double-zero byte at an even byte boundary in order to
** terminate a UTF16 string, even if the initial size of the buffer
** is an odd number of bytes.
*/
static SQLITE_NOINLINE int vdbeMemAddTerminator(Mem *pMem){
if( sqlite3VdbeMemGrow(pMem, pMem->n+3, 1) ){
if( sqlite3VdbeMemGrow(pMem, pMem->n+2, 1) ){
return SQLITE_NOMEM_BKPT;
}
pMem->z[pMem->n] = 0;
pMem->z[pMem->n+1] = 0;
pMem->z[pMem->n+2] = 0;
pMem->flags |= MEM_Term;
return SQLITE_OK;
}
@@ -361,12 +335,12 @@ int sqlite3VdbeMemNulTerminate(Mem *pMem){
}
/*
** Add MEM_Str to the set of representations for the given Mem. This
** routine is only called if pMem is a number of some kind, not a NULL
** or a BLOB.
** Add MEM_Str to the set of representations for the given Mem. Numbers
** are converted using sqlite3_snprintf(). Converting a BLOB to a string
** is a no-op.
**
** Existing representations MEM_Int, MEM_Real, or MEM_IntReal are invalidated
** if bForce is true but are retained if bForce is false.
** Existing representations MEM_Int and MEM_Real are invalidated if
** bForce is true but are retained if bForce is false.
**
** A MEM_Null value will never be passed to this function. This function is
** used for converting values to text for returning to the user (i.e. via
@@ -375,12 +349,13 @@ int sqlite3VdbeMemNulTerminate(Mem *pMem){
** user and the latter is an internal programming error.
*/
int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){
int fg = pMem->flags;
const int nByte = 32;
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
assert( !(pMem->flags&MEM_Zero) );
assert( !(pMem->flags&(MEM_Str|MEM_Blob)) );
assert( pMem->flags&(MEM_Int|MEM_Real|MEM_IntReal) );
assert( !(fg&MEM_Zero) );
assert( !(fg&(MEM_Str|MEM_Blob)) );
assert( fg&(MEM_Int|MEM_Real) );
assert( !sqlite3VdbeMemIsRowSet(pMem) );
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
@@ -390,12 +365,23 @@ int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){
return SQLITE_NOMEM_BKPT;
}
vdbeMemRenderNum(nByte, pMem->z, pMem);
/* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8
** string representation of the value. Then, if the required encoding
** is UTF-16le or UTF-16be do a translation.
**
** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16.
*/
if( fg & MEM_Int ){
sqlite3_snprintf(nByte, pMem->z, "%lld", pMem->u.i);
}else{
assert( fg & MEM_Real );
sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->u.r);
}
assert( pMem->z!=0 );
pMem->n = sqlite3Strlen30NN(pMem->z);
pMem->enc = SQLITE_UTF8;
pMem->flags |= MEM_Str|MEM_Term;
if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal);
if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real);
sqlite3VdbeChangeEncoding(pMem, enc);
return SQLITE_OK;
}
@@ -569,8 +555,7 @@ i64 sqlite3VdbeIntValue(Mem *pMem){
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
flags = pMem->flags;
if( flags & (MEM_Int|MEM_IntReal) ){
testcase( flags & MEM_IntReal );
if( flags & MEM_Int ){
return pMem->u.i;
}else if( flags & MEM_Real ){
return doubleToInt64(pMem->u.r);
@@ -599,8 +584,7 @@ double sqlite3VdbeRealValue(Mem *pMem){
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
if( pMem->flags & MEM_Real ){
return pMem->u.r;
}else if( pMem->flags & (MEM_Int|MEM_IntReal) ){
testcase( pMem->flags & MEM_IntReal );
}else if( pMem->flags & MEM_Int ){
return (double)pMem->u.i;
}else if( pMem->flags & (MEM_Str|MEM_Blob) ){
return memRealValue(pMem);
@@ -615,8 +599,7 @@ double sqlite3VdbeRealValue(Mem *pMem){
** Return the value ifNull if pMem is NULL.
*/
int sqlite3VdbeBooleanValue(Mem *pMem, int ifNull){
testcase( pMem->flags & MEM_IntReal );
if( pMem->flags & (MEM_Int|MEM_IntReal) ) return pMem->u.i!=0;
if( pMem->flags & MEM_Int ) return pMem->u.i!=0;
if( pMem->flags & MEM_Null ) return ifNull;
return sqlite3VdbeRealValue(pMem)!=0.0;
}
@@ -689,7 +672,7 @@ static int sqlite3RealSameAsInt(double r1, sqlite3_int64 i){
}
/*
** Convert pMem so that it has type MEM_Real or MEM_Int.
** Convert pMem so that it has types MEM_Real or MEM_Int or both.
** Invalidate any prior representations.
**
** Every effort is made to force the conversion, even if the input
@@ -697,11 +680,7 @@ static int sqlite3RealSameAsInt(double r1, sqlite3_int64 i){
** as much of the string as we can and ignore the rest.
*/
int sqlite3VdbeMemNumerify(Mem *pMem){
testcase( pMem->flags & MEM_Int );
testcase( pMem->flags & MEM_Real );
testcase( pMem->flags & MEM_IntReal );
testcase( pMem->flags & MEM_Null );
if( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null))==0 ){
if( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 ){
int rc;
assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 );
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
@@ -719,7 +698,7 @@ int sqlite3VdbeMemNumerify(Mem *pMem){
}
}
}
assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null))!=0 );
assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))!=0 );
pMem->flags &= ~(MEM_Str|MEM_Blob|MEM_Zero);
return SQLITE_OK;
}
@@ -762,7 +741,7 @@ void sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){
pMem->flags |= (pMem->flags&MEM_Blob)>>3;
sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding);
assert( pMem->flags & MEM_Str || pMem->db->mallocFailed );
pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal|MEM_Blob|MEM_Zero);
pMem->flags &= ~(MEM_Int|MEM_Real|MEM_Blob|MEM_Zero);
break;
}
}
@@ -946,7 +925,7 @@ void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){
** dual type, are allowed, as long as the underlying value is the
** same. */
u16 mFlags = pMem->flags & pX->flags & pX->mScopyFlags;
assert( (mFlags&(MEM_Int|MEM_IntReal))==0 || pMem->u.i==pX->u.i );
assert( (mFlags&MEM_Int)==0 || pMem->u.i==pX->u.i );
assert( (mFlags&MEM_Real)==0 || pMem->u.r==pX->u.r );
assert( (mFlags&MEM_Str)==0 || (pMem->n==pX->n && pMem->z==pX->z) );
assert( (mFlags&MEM_Blob)==0 || sqlite3BlobCompare(pMem,pX)==0 );
@@ -1509,12 +1488,7 @@ static int valueFromExpr(
}else{
sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8);
}
assert( (pVal->flags & MEM_IntReal)==0 );
if( pVal->flags & (MEM_Int|MEM_IntReal|MEM_Real) ){
testcase( pVal->flags & MEM_Int );
testcase( pVal->flags & MEM_Real );
pVal->flags &= ~MEM_Str;
}
if( pVal->flags & (MEM_Int|MEM_Real) ) pVal->flags &= ~MEM_Str;
if( enc!=SQLITE_UTF8 ){
rc = sqlite3VdbeChangeEncoding(pVal, enc);
}
+1 -1
View File
@@ -130,7 +130,7 @@ char *sqlite3VdbeExpandSql(
pVar = &p->aVar[idx-1];
if( pVar->flags & MEM_Null ){
sqlite3_str_append(&out, "NULL", 4);
}else if( pVar->flags & (MEM_Int|MEM_IntReal) ){
}else if( pVar->flags & MEM_Int ){
sqlite3_str_appendf(&out, "%lld", pVar->u.i);
}else if( pVar->flags & MEM_Real ){
sqlite3_str_appendf(&out, "%!.15g", pVar->u.r);
-2
View File
@@ -841,7 +841,6 @@ int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){
p = vtabDisconnectAll(db, pTab);
xDestroy = p->pMod->pModule->xDestroy;
assert( xDestroy!=0 ); /* Checked before the virtual table is created */
pTab->nTabRef++;
rc = xDestroy(p->pVtab);
/* Remove the sqlite3_vtab* from the aVTrans[] array, if applicable */
if( rc==SQLITE_OK ){
@@ -850,7 +849,6 @@ int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){
pTab->pVTable = 0;
sqlite3VtabUnlock(p);
}
sqlite3DeleteTable(db, pTab);
}
return rc;
+2
View File
@@ -4363,6 +4363,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
pWInfo->nRowOut = pFrom->nRow;
pWInfo->iTotalCost = pFrom->rCost;
/* Free temporary memory and return success */
sqlite3DbFreeNN(db, pSpace);
@@ -5145,6 +5146,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
/* Generate loop termination code.
*/
sqlite3VdbeUpdateCostEstimates(pParse, pWInfo->iTotalCost, pWInfo->nRowOut);
VdbeModuleComment((v, "End WHERE-core"));
for(i=pWInfo->nLevel-1; i>=0; i--){
int addr;
+1 -4
View File
@@ -14,8 +14,6 @@
** planner logic in "where.c". These definitions are broken out into
** a separate source file for easier editing.
*/
#ifndef SQLITE_WHEREINT_H
#define SQLITE_WHEREINT_H
/*
** Trace output macros
@@ -464,6 +462,7 @@ struct WhereInfo {
WhereLoop *pLoops; /* List of all WhereLoop objects */
Bitmask revMask; /* Mask of ORDER BY terms that need reversing */
LogEst nRowOut; /* Estimated number of output rows */
LogEst iTotalCost; /* Cost estimate for the whole plan */
WhereClause sWC; /* Decomposition of the WHERE clause */
WhereMaskSet sMaskSet; /* Map cursor numbers to bitmasks */
WhereLevel a[1]; /* Information about each nest loop in WHERE */
@@ -586,5 +585,3 @@ void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereClause*);
#define WHERE_UNQ_WANTED 0x00010000 /* WHERE_ONEROW would have been helpful*/
#define WHERE_PARTIALIDX 0x00020000 /* The automatic index is partial */
#define WHERE_IN_EARLYOUT 0x00040000 /* Perhaps quit IN loops early */
#endif /* !defined(SQLITE_WHEREINT_H) */
+1 -1
View File
@@ -2115,7 +2115,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
sqlite3VdbeGoto(v, pLevel->addrBrk);
sqlite3VdbeResolveLabel(v, iLoopBody);
if( pWInfo->nLevel>1 ){ sqlite3StackFree(db, pOrTab); }
if( pWInfo->nLevel>1 ) sqlite3StackFree(db, pOrTab);
if( !untestedTerms ) disableTerm(pLevel, pTerm);
}else
#endif /* SQLITE_OMIT_OR_OPTIMIZATION */
+3 -5
View File
@@ -262,13 +262,12 @@ static int isLikeOrGlob(
zNew[iTo++] = zNew[iFrom];
}
zNew[iTo] = 0;
assert( iTo>0 );
/* If the RHS begins with a digit or a +/- sign, then the LHS must be
/* If the RHS begins with a digit or a minus sign, then the LHS must be
** an ordinary column (not a virtual table column) with TEXT affinity.
** Otherwise the LHS might be numeric and "lhs >= rhs" would be false
** even though "lhs LIKE rhs" is true. But if the RHS does not start
** with a digit or +/-, then "lhs LIKE rhs" will always be false if
** with a digit or '-', then "lhs LIKE rhs" will always be false if
** the LHS is numeric and so the optimization still works.
**
** 2018-09-10 ticket c94369cae9b561b1f996d0054bfab11389f9d033
@@ -278,8 +277,7 @@ static int isLikeOrGlob(
*/
if( sqlite3Isdigit(zNew[0])
|| zNew[0]=='-'
|| zNew[0]=='+'
|| zNew[iTo-1]=='0'-1
|| (zNew[0]+1=='0' && iTo==1)
){
if( pLeft->op!=TK_COLUMN
|| sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT
+5 -10
View File
@@ -868,18 +868,13 @@ static void selectWindowRewriteEList(
static ExprList *exprListAppendList(
Parse *pParse, /* Parsing context */
ExprList *pList, /* List to which to append. Might be NULL */
ExprList *pAppend, /* List of values to append. Might be NULL */
int bIntToNull
ExprList *pAppend /* List of values to append. Might be NULL */
){
if( pAppend ){
int i;
int nInit = pList ? pList->nExpr : 0;
for(i=0; i<pAppend->nExpr; i++){
Expr *pDup = sqlite3ExprDup(pParse->db, pAppend->a[i].pExpr, 0);
if( bIntToNull && pDup && pDup->op==TK_INTEGER ){
pDup->op = TK_NULL;
pDup->flags &= ~(EP_IntValue|EP_IsTrue|EP_IsFalse);
}
pList = sqlite3ExprListAppend(pParse, pList, pDup);
if( pList ) pList->a[nInit+i].sortOrder = pAppend->a[i].sortOrder;
}
@@ -919,7 +914,7 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
** of the window PARTITION and ORDER BY clauses. Then, if this makes it
** redundant, remove the ORDER BY from the parent SELECT. */
pSort = sqlite3ExprListDup(db, pMWin->pPartition, 0);
pSort = exprListAppendList(pParse, pSort, pMWin->pOrderBy, 1);
pSort = exprListAppendList(pParse, pSort, pMWin->pOrderBy);
if( pSort && p->pOrderBy ){
if( sqlite3ExprListCompare(pSort, p->pOrderBy, -1)==0 ){
sqlite3ExprListDelete(db, p->pOrderBy);
@@ -940,8 +935,8 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
/* Append the PARTITION BY and ORDER BY expressions to the to the
** sub-select expression list. They are required to figure out where
** boundaries for partitions and sets of peer rows lie. */
pSublist = exprListAppendList(pParse, pSublist, pMWin->pPartition, 0);
pSublist = exprListAppendList(pParse, pSublist, pMWin->pOrderBy, 0);
pSublist = exprListAppendList(pParse, pSublist, pMWin->pPartition);
pSublist = exprListAppendList(pParse, pSublist, pMWin->pOrderBy);
/* Append the arguments passed to each window function to the
** sub-select expression list. Also allocate two registers for each
@@ -949,7 +944,7 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
** results. */
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
pSublist = exprListAppendList(pParse, pSublist, pWin->pOwner->x.pList, 0);
pSublist = exprListAppendList(pParse, pSublist, pWin->pOwner->x.pList);
if( pWin->pFilter ){
Expr *pFilter = sqlite3ExprDup(db, pWin->pFilter, 0);
pSublist = sqlite3ExprListAppend(pParse, pSublist, pFilter);
-25
View File
@@ -569,29 +569,4 @@ do_execsql_test 17.0 {
User {CREATE TABLE "User" (id integer)}
}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 18.1.0 {
CREATE TABLE t0 (c0 INTEGER, PRIMARY KEY(c0)) WITHOUT ROWID;
}
breakpoint
do_execsql_test 18.1.1 {
ALTER TABLE t0 RENAME COLUMN c0 TO c1;
}
do_execsql_test 18.1.2 {
SELECT sql FROM sqlite_master;
} {{CREATE TABLE t0 (c1 INTEGER, PRIMARY KEY(c1)) WITHOUT ROWID}}
reset_db
do_execsql_test 18.2.0 {
CREATE TABLE t0 (c0 INTEGER, PRIMARY KEY(c0));
}
do_execsql_test 18.2.1 {
ALTER TABLE t0 RENAME COLUMN c0 TO c1;
}
do_execsql_test 18.2.2 {
SELECT sql FROM sqlite_master;
} {{CREATE TABLE t0 (c1 INTEGER, PRIMARY KEY(c1))}}
finish_test
-33
View File
@@ -142,39 +142,6 @@ do_execsql_test 6.1 {
ALTER TABLE Table0 RENAME Col0 TO Col0;
}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 7.1.0 {
CREATE TABLE t1(a,b,c);
CREATE TRIGGER AFTER INSERT ON t1 BEGIN
SELECT a, rank() OVER w1 FROM t1
WINDOW w1 AS (PARTITION BY b, percent_rank() OVER w1);
END;
}
do_execsql_test 7.1.2 {
ALTER TABLE t1 RENAME TO t1x;
SELECT sql FROM sqlite_master;
} {
{CREATE TABLE "t1x"(a,b,c)}
{CREATE TRIGGER AFTER INSERT ON "t1x" BEGIN
SELECT a, rank() OVER w1 FROM "t1x"
WINDOW w1 AS (PARTITION BY b, percent_rank() OVER w1);
END}
}
do_execsql_test 7.2.1 {
DROP TRIGGER after;
CREATE TRIGGER AFTER INSERT ON t1x BEGIN
SELECT a, rank() OVER w1 FROM t1x
WINDOW w1 AS (PARTITION BY b, percent_rank() OVER w1 ORDER BY d);
END;
}
do_catchsql_test 7.2.2 {
ALTER TABLE t1x RENAME TO t1;
} {1 {error in trigger AFTER: no such column: d}}
finish_test
-142
View File
@@ -866,146 +866,4 @@ do_execsql_test 9.3 {
ROLLBACK TO one;
}
#-------------------------------------------------------------------------
reset_db
do_test 10.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
| size 180224 pagesize 4096 filename crash-41390d95d613b6.db
| page 1 offset 0
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00 .....@ ........
| 96: 00 00 00 00 0d 00 00 00 04 0e e2 00 0f 96 0f 44 ...............D
| 112: 0f 10 0e e2 00 00 00 00 00 00 00 00 00 00 00 00 ................
| 3808: 00 00 2c 14 06 17 15 11 01 41 69 6e 64 65 78 74 ..,......Aindext
| 3824: 41 78 33 74 31 06 43 52 45 41 54 45 20 49 4e 44 Ax3t1.CREATE IND
| 3840: 45 58 20 74 31 78 32 20 4f 4e 20 74 31 28 62 29 EX t1x2 ON t1(b)
| 3856: 32 03 06 17 15 11 01 4d 69 6e 64 65 78 74 31 88 2......Mindext1.
| 3872: 31 74 31 05 43 52 45 41 54 45 20 49 4e 44 45 58 1t1.CREATE INDEX
| 3888: 20 74 31 78 31 20 4f 4e 20 74 31 28 67 2b 68 2c t1x1 ON t1(g+h,
| 3904: 6a 2d 6b 29 50 02 06 17 2b 2b 01 59 74 61 62 6c j-k)P...++.Ytabl
| 3920: 65 73 71 6c 69 74 65 5e 73 65 71 74 65 6e 63 65 esqlite^seqtence
| 3936: 73 71 6c 69 74 65 5f 73 65 71 75 65 6e 63 65 04 sqlite_sequence.
| 3952: 43 52 45 41 54 45 20 54 41 42 4c 45 20 73 71 6c CREATE TABLE sql
| 3968: 69 74 65 5f 73 65 71 75 65 6e 63 65 28 6e 61 6d ite_sequence(nam
| 3984: 65 2c 73 65 71 29 68 00 07 17 11 11 01 81 3b 74 e,seq)h.......;t
| 4000: 61 62 6c 65 74 31 74 31 03 43 52 45 41 54 45 20 ablet1t1.CREATE
| 4016: 54 41 42 4c 45 20 74 31 28 61 20 49 4e 54 45 47 TABLE t1(a INTEG
| 4032: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 20 41 ER PRIMARY KEY A
| 4048: 55 54 4f 49 4e 43 52 45 4d 45 4e 54 2c 0a 62 2c UTOINCREMENT,.b,
| 4064: 63 2c 64 2c 65 2c 66 2c 67 2c 68 2c 6a 2c 6b 2c c,d,e,f,g,h,j,k,
| 4080: 6c 2c 6d 2c 6e 2c 6f 2c 70 2c 71 2c 72 2c 73 29 l,m,n,o,p,q,r,s)
| page 2 offset 4096
| 0: 01 00 00 00 00 01 00 00 10 00 01 00 00 00 00 01 ................
| 16: 00 00 00 00 02 00 0f f0 00 15 00 00 00 03 02 00 ................
| 32: 00 00 d9 05 00 00 00 03 02 00 00 00 00 05 00 00 ................
| 48: 10 03 02 00 00 00 00 05 00 00 00 03 02 00 00 00 ................
| 64: 00 05 00 00 00 02 62 00 00 00 00 05 00 00 00 03 ......b.........
| 80: 02 00 00 00 00 05 00 00 00 03 02 00 00 00 00 05 ................
| 96: 00 00 00 03 02 00 00 00 00 05 00 00 00 03 05 00 ................
| 112: 00 00 03 03 01 00 00 23 02 00 00 4f 00 02 00 00 .......#...O....
| 128: 10 25 02 00 00 00 00 03 00 00 00 23 02 00 00 00 .%.........#....
| 144: 00 03 00 00 00 23 02 00 00 00 00 03 00 00 00 23 .....#.........#
| 160: 05 00 08 90 06 05 00 00 00 06 01 ff 00 00 00 03 ................
| 176: 00 00 00 06 02 00 00 00 00 02 ff 00 00 00 00 00 ................
| page 3 offset 8192
| 0: 05 00 00 00 09 0f d0 00 00 00 00 19 0f fb 0f f6 ................
| 16: 0f f1 10 ec ec e7 0f e2 0f dc 0f d6 0f 00 00 00 ................
| 1072: 00 97 4c 0a 24 00 ae 00 00 00 00 00 00 00 00 00 ..L.$...........
| 4048: 00 00 00 16 83 39 ff ff ff 14 81 16 00 00 00 12 .....9..........
| 4064: 81 02 00 00 00 10 6e 00 00 00 0e 5a 00 00 00 0c ......n....Z....
| 4080: 46 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F...............
| page 4 offset 12288
| 1072: 97 4d 32 14 00 ae 00 00 00 00 00 00 00 00 00 00 .M2.............
| 4080: 00 00 00 00 00 00 00 07 01 03 11 02 74 31 00 bd ............t1..
| page 5 offset 16384
| 0: fa 0f 7c 00 0a 0f 74 00 0f f9 0f eb 0f dd 0f cf ..|...t.........
| 16: 0f c1 0f b3 0f a4 0e 94 0f 84 0f 74 0f 74 0f 74 ...........t.t.t
| 32: 0f 74 0f 64 0f 00 00 00 00 00 00 00 00 00 00 00 .t.d............
| 3952: 00 00 00 00 07 05 00 00 00 02 00 be 0f 8c 10 07 ................
| 3968: ff ff 00 00 07 05 00 00 00 02 00 aa 0f 9b f0 08 ................
| 3984: c8 00 00 00 37 06 00 00 00 01 00 96 0f ac 00 08 ....7...........
| 4000: 00 00 00 b3 07 15 00 10 00 02 00 82 0f ba 00 07 ................
| 4016: 00 00 00 06 05 00 00 00 01 6e 0f c8 00 07 00 00 .........n......
| 4032: 00 06 05 00 00 00 01 5a 03 f6 00 07 00 00 00 06 .......Z........
| 4048: 05 00 00 00 01 46 0f e4 00 07 00 00 10 06 05 00 .....F..........
| 4064: 00 00 01 32 10 02 00 07 00 00 00 07 05 00 00 00 ...2............
| 4080: 01 1d ff ff ff 07 10 00 00 06 05 00 00 00 01 0a ................
| page 6 offset 20480
| 624: 00 00 00 00 00 21 97 00 00 00 00 00 00 00 00 00 .....!..........
| 1120: 00 00 00 00 00 24 57 3e 00 00 00 00 00 00 00 00 .....$W>........
| 1616: 00 00 00 00 1f 97 00 00 00 00 00 00 00 00 00 00 ................
| 2112: 00 00 00 1e 97 3d 00 00 00 00 00 00 00 00 00 00 .....=..........
| 2608: 00 1d 97 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
| page 8 offset 28672
| 1184: 00 00 00 00 00 00 00 00 00 97 4d 1e 13 ff ae 7c ..........M....|
| 4080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90 ................
| page 9 offset 32768
| 256: 0d 01 c0 00 01 04 30 00 04 30 00 00 00 00 00 00 ......0..0......
| page 10 offset 36864
| 0: 0d 00 22 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
| 4080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 05 ................
| page 12 offset 45056
| 0: 0d 00 00 00 01 04 30 00 00 00 00 00 00 00 00 00 ......0.........
| page 14 offset 53248
| 0: 0d 00 00 00 01 04 30 00 04 30 00 00 00 00 00 00 ......0..0......
| 1072: 96 4d 5a 14 00 00 00 00 00 00 00 00 00 00 00 00 .MZ.............
| page 16 offset 61440
| 0: 0d 00 00 00 01 04 30 00 04 30 00 00 00 00 00 00 ......0..0......
| 1072: 97 4d 6e 14 00 ae 7b ff ff ff ff 00 00 00 00 00 .Mn.............
| page 18 offset 69632
| 1056: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 97 ................
| 1072: 4d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 M...............
| 4080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0d ................
| page 20 offset 77824
| 1056: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 97 ................
| 1072: 4d 81 16 14 00 ae 00 00 00 00 00 00 00 00 00 00 M...............
| 4080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0f ................
| page 22 offset 86016
| 0: 0d 00 00 00 01 04 2f 00 04 2f 01 00 00 00 00 00 ....../../......
| 1056: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 97 ................
| 1072: 4d 81 2a 14 00 00 00 00 00 00 00 00 00 00 00 00 M.*.............
| page 24 offset 94208
| 1072: 00 97 4c 0a 14 00 ae 7c 00 00 00 00 00 00 00 00 ..L....|........
| page 25 offset 98304
| 1056: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 97 ................
| 1072: 4d 81 3e 14 00 ae 7c 00 00 18 ff 00 00 00 00 00 M.>...|.........
| page 27 offset 106496
| 0: 00 00 00 00 00 00 00 12 00 00 00 07 00 00 00 1d ................
| 16: 00 00 00 09 00 00 00 1f 00 00 00 0b 00 00 00 21 ...............!
| 32: 00 00 00 0d 00 10 00 25 00 00 00 0f 00 00 00 27 .......%.......'
| 48: 00 00 00 11 00 00 00 00 00 00 00 00 00 00 00 00 ................
| page 32 offset 126976
| 2512: 00 00 00 00 00 00 00 45 21 00 00 00 00 00 00 00 .......E!.......
| page 35 offset 139264
| 0: 00 0a 08 44 00 05 02 77 00 0e 11 0a 92 00 00 00 ...D...w........
| 1120: 00 00 00 00 00 20 97 00 00 00 00 00 00 00 00 00 ..... ..........
| 1616: 00 00 00 00 22 00 00 00 00 00 00 00 00 00 00 00 ................
| 2608: 00 00 00 97 3d 04 00 00 00 00 00 00 00 00 00 00 ....=...........
| 3104: 00 1c 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
| 3600: 00 97 3d 04 ae 7c 00 00 00 00 00 00 00 00 00 00 ..=..|..........
| 4080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1a ................
| page 36 offset 143360
| 0: 0a 08 44 00 04 02 00 00 00 00 00 00 00 00 00 00 ..D.............
| 1120: 00 00 00 00 00 2a 97 3e 04 00 00 00 00 00 00 00 .....*.>........
| 1616: 00 00 00 00 2c 97 3e 00 00 00 00 00 00 00 00 00 ....,.>.........
| 2112: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 38 ...............8
| 2128: 00 00 05 cd 00 00 00 00 00 00 00 00 00 00 00 00 ................
| 3600: 00 97 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
| page 38 offset 151552
| 2464: 00 00 00 00 00 00 00 00 00 6e 00 00 00 00 00 00 .........n......
| page 40 offset 159744
| 2512: 00 00 00 00 00 00 00 00 82 00 00 00 00 00 00 00 ................
| page 42 offset 167936
| 2512: 00 00 00 00 00 00 00 96 00 00 00 00 00 00 00 00 ................
| page 44 offset 176128
| 2512: 00 00 00 00 00 00 00 00 aa 00 00 00 00 00 00 00 ................
| end crash-41390d95d613b6.db
}]} {}
do_catchsql_test 10.1 {
SELECT * FROM t1 WHERE a<='2019-05-09' ORDER BY a DESC;
} {1 {database disk image is malformed}}
finish_test
-115
View File
@@ -1,115 +0,0 @@
# 2019-04-11
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library. The
# focus of this file is testing the sqlite_dbpage virtual table.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix dbdata
ifcapable !vtab||!compound {
finish_test
return
}
if { [catch { db enable_load_extension 1 }]
|| [catch { db eval { SELECT load_extension('../dbdata') } }]
} {
finish_test
return
}
do_execsql_test 1.0 {
CREATE TABLE T1(a, b);
INSERT INTO t1(rowid, a ,b) VALUES(5, 'v', 'five');
INSERT INTO t1(rowid, a, b) VALUES(10, 'x', 'ten');
}
do_execsql_test 1.1 {
SELECT pgno, cell, field, quote(value) FROM sqlite_dbdata WHERE pgno=2;
} {
2 0 -1 5
2 0 0 'v'
2 0 1 'five'
2 1 -1 10
2 1 0 'x'
2 1 1 'ten'
}
breakpoint
do_execsql_test 1.2 {
SELECT pgno, cell, field, quote(value) FROM sqlite_dbdata;
} {
1 0 -1 1
1 0 0 'table'
1 0 1 'T1'
1 0 2 'T1'
1 0 3 2
1 0 4 {'CREATE TABLE T1(a, b)'}
2 0 -1 5
2 0 0 'v'
2 0 1 'five'
2 1 -1 10
2 1 0 'x'
2 1 1 'ten'
}
set big [string repeat big 2000]
do_execsql_test 1.3 {
INSERT INTO t1 VALUES(NULL, $big);
SELECT value FROM sqlite_dbdata WHERE pgno=2 AND cell=2 AND field=1;
} $big
do_execsql_test 1.4 {
DELETE FROM t1;
INSERT INTO t1 VALUES(NULL, randomblob(5050));
}
do_test 1.5 {
execsql {
SELECT quote(value) FROM sqlite_dbdata WHERE pgno=2 AND cell=0 AND field=1;
}
} [db one {SELECT quote(b) FROM t1}]
#-------------------------------------------------------------------------
reset_db
db enable_load_extension 1
db eval { SELECT load_extension('../dbdata') }
do_execsql_test 2.0 {
CREATE TABLE t1(a);
CREATE INDEX i1 ON t1(a);
WITH s(i) AS (
SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<10
)
INSERT INTO t1 SELECT randomblob(900) FROM s;
}
do_execsql_test 2.1 {
SELECT * FROM sqlite_dbptr WHERE pgno=2;
} {
2 25 2 6 2 7 2 9 2 11 2 13 2 15 2 17 2 19 2 21
}
do_execsql_test 2.2 {
SELECT * FROM sqlite_dbptr WHERE pgno=3;
} {
3 24 3 23
}
do_execsql_test 2.3 {
SELECT * FROM sqlite_dbptr
} {
2 25 2 6 2 7 2 9 2 11 2 13 2 15 2 17 2 19 2 21
3 24 3 23
}
finish_test
+7 -12
View File
@@ -1013,18 +1013,13 @@ sqlite3 db test.db
# EVIDENCE-OF: R-22868-25880 The LIKE operator can be made case
# sensitive using the case_sensitive_like pragma.
#
do_execsql_test e_expr-16.1.1 { SELECT 'abcxyz' LIKE 'ABC%' } 1
do_execsql_test e_expr-16.1.1b { SELECT 'abc%xyz' LIKE 'ABC\%x%' ESCAPE '\' } 1
do_execsql_test e_expr-16.1.2 { PRAGMA case_sensitive_like = 1 } {}
do_execsql_test e_expr-16.1.3 { SELECT 'abcxyz' LIKE 'ABC%' } 0
do_execsql_test e_expr-16.1.3b { SELECT 'abc%xyz' LIKE 'ABC\%X%' ESCAPE '\' } 0
do_execsql_test e_expr-16.1.4 { SELECT 'ABCxyz' LIKE 'ABC%' } 1
do_execsql_test e_expr-16.1.4b { SELECT 'ABC%xyz' LIKE 'ABC\%x%' ESCAPE '\' } 1
do_execsql_test e_expr-16.1.5 { PRAGMA case_sensitive_like = 0 } {}
do_execsql_test e_expr-16.1.6 { SELECT 'abcxyz' LIKE 'ABC%' } 1
do_execsql_test e_expr-16.1.6b { SELECT 'abc%xyz' LIKE 'ABC\%X%' ESCAPE '\' } 1
do_execsql_test e_expr-16.1.7 { SELECT 'ABCxyz' LIKE 'ABC%' } 1
do_execsql_test e_expr-16.1.7b { SELECT 'ABC%xyz' LIKE 'ABC\%X%' ESCAPE '\' } 1
do_execsql_test e_expr-16.1.1 { SELECT 'abcxyz' LIKE 'ABC%' } 1
do_execsql_test e_expr-16.1.2 { PRAGMA case_sensitive_like = 1 } {}
do_execsql_test e_expr-16.1.3 { SELECT 'abcxyz' LIKE 'ABC%' } 0
do_execsql_test e_expr-16.1.4 { SELECT 'ABCxyz' LIKE 'ABC%' } 1
do_execsql_test e_expr-16.1.5 { PRAGMA case_sensitive_like = 0 } {}
do_execsql_test e_expr-16.1.6 { SELECT 'abcxyz' LIKE 'ABC%' } 1
do_execsql_test e_expr-16.1.7 { SELECT 'ABCxyz' LIKE 'ABC%' } 1
# EVIDENCE-OF: R-52087-12043 The GLOB operator is similar to LIKE but
# uses the Unix file globbing syntax for its wildcards.
-36
View File
@@ -82,40 +82,4 @@ ifcapable stat4 {
}
}
do_execsql_test 4.0 {
PRAGMA foreign_keys = true;
CREATE TABLE parent(
p PRIMARY KEY
);
CREATE TABLE child(
c UNIQUE REFERENCES parent(p)
);
}
do_catchsql_test 4.1 {
INSERT OR FAIL INTO child VALUES(123), (123);
} {1 {FOREIGN KEY constraint failed}}
do_execsql_test 4.2 {
SELECT * FROM child;
} {}
do_execsql_test 4.3 {
PRAGMA foreign_key_check;
} {}
do_catchsql_test 4.4 {
INSERT INTO parent VALUES(123);
INSERT OR FAIL INTO child VALUES(123), (123);
} {1 {UNIQUE constraint failed: child.c}}
do_execsql_test 4.5 {
SELECT * FROM child;
} {123}
do_execsql_test 4.6 {
PRAGMA foreign_key_check;
} {}
finish_test
-31
View File
@@ -197,36 +197,5 @@ do_execsql_test 4.2 {
INSERT OR REPLACE INTO t1 VALUES(20000, 20000);
}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 5.0 {
PRAGMA foreign_keys = true;
CREATE TABLE parent(
p TEXT PRIMARY KEY
);
CREATE TABLE child(
c INTEGER UNIQUE,
FOREIGN KEY(c) REFERENCES parent(p) DEFERRABLE INITIALLY DEFERRED
);
BEGIN;
INSERT INTO child VALUES(123);
INSERT INTO parent VALUES('123');
COMMIT;
}
do_execsql_test 5.1 {
PRAGMA integrity_check;
} {ok}
do_execsql_test 5.2 {
INSERT INTO parent VALUES(1200);
BEGIN;
INSERT INTO child VALUES(456);
UPDATE parent SET p = '456' WHERE p=1200;
COMMIT;
}
do_execsql_test 5.3 {
PRAGMA integrity_check;
} {ok}
finish_test
-44
View File
@@ -1,44 +0,0 @@
# 2019 April 30
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#*************************************************************************
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/fts3_common.tcl
set ::testprefix fts4rename
# If SQLITE_ENABLE_FTS3 is defined, omit this file.
ifcapable !fts3 {
finish_test
return
}
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE temp.t1 USING fts3(a);
BEGIN;
CREATE TABLE t2(x);
} {}
do_catchsql_test 1.1 {
ALTER TABLE t1_content RENAME c0a TO docid;
} {1 {duplicate column name: docid}}
do_catchsql_test 1.2 {
UPDATE t1 SET Col0 = 1 ;
} {1 {no such column: Col0}}
do_catchsql_test 1.3 {
ROLLBACK;
DROP TABLE t1;
} {0 {}}
finish_test
-3
View File
@@ -315,9 +315,6 @@ ifcapable floatingpoint {
do_test func-4.38 {
execsql {SELECT round(9999999999999.556,2);}
} {9999999999999.56}
do_execsql_test func-4.39 {
SELECT round(1e500), round(-1e500);
} {Inf -Inf}
}
# Test the upper() and lower() functions
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+1 -27
View File
@@ -738,32 +738,6 @@ do_test index-21.2 {
}
} {0 {9 5 1}}
# 2019-05-01 ticket https://www.sqlite.org/src/info/3be1295b264be2fa
do_execsql_test index-22.0 {
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(a, b TEXT);
CREATE UNIQUE INDEX IF NOT EXISTS x1 ON t1(b==0);
CREATE INDEX IF NOT EXISTS x2 ON t1(a || 0) WHERE b;
INSERT INTO t1(a,b) VALUES('a',1),('a',0);
SELECT a, b, '|' FROM t1;
} {a 1 | a 0 |}
# 2019-05-10 ticket https://www.sqlite.org/src/info/ae0f637bddc5290b
do_execsql_test index-23.0 {
DROP TABLE t1;
CREATE TABLE t1(a TEXT, b REAL);
CREATE UNIQUE INDEX t1x1 ON t1(a GLOB b);
INSERT INTO t1(a,b) VALUES('0.0','1'),('1.0','1');
SELECT * FROM t1;
REINDEX;
} {0.0 1.0 1.0 1.0}
do_execsql_test index-23.1 {
DROP TABLE t1;
CREATE TABLE t1(a REAL);
CREATE UNIQUE INDEX index_0 ON t1(TYPEOF(a));
INSERT OR IGNORE INTO t1(a) VALUES (0.1),(FALSE);
SELECT * FROM t1;
REINDEX;
} {0.1}
finish_test
-13
View File
@@ -410,17 +410,4 @@ do_execsql_test index6-12.1 {
do_execsql_test index6-12.2 {
SELECT x FROM t2 WHERE x IN (SELECT a FROM t1) ORDER BY +x;
} {1 2}
# 2019-05-04
# Ticket https://www.sqlite.org/src/tktview/5c6955204c392ae763a95
# Theorem prover error
#
do_execsql_test index6-13.1 {
DROP TABLE IF EXISTS t0;
CREATE TABLE t0(c0);
CREATE INDEX index_0 ON t0(c0) WHERE c0 NOT NULL;
INSERT INTO t0(c0) VALUES (NULL);
SELECT * FROM t0 WHERE c0 OR 1;
} {{}}
finish_test
+1 -1
View File
@@ -186,7 +186,7 @@ do_test index7-1.15 {
}
} {t1 {15 1} t1a {10 1} t1b {8 1} t1c {15 1} ok}
# Queries use partial indices at appropriate times.
# Queries use partial indices as appropriate times.
#
do_test index7-2.1 {
execsql {
-52
View File
@@ -1,52 +0,0 @@
# 2019-05-03
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# Tests to exercise the MEM_IntReal representation of Mem objects.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set ::testprefix intreal
sqlite3_create_function db
do_execsql_test 100 {
SELECT intreal(5);
} {5.0}
do_execsql_test 110 {
SELECT intreal(5)=5, 6=intreal(6);
} {1 1}
do_execsql_test 120 {
SELECT intreal(7)=7.0, 8.0=intreal(8);
} {1 1}
do_execsql_test 130 {
SELECT typeof(intreal(9));
} {real}
do_execsql_test 140 {
SELECT 'a'||intreal(11)||'z';
} {a11.0z}
do_execsql_test 150 {
SELECT max(1.0,intreal(2),3.0), max(1,intreal(2),3);
} {3.0 3}
do_execsql_test 160 {
SELECT max(1.0,intreal(4),3.0), max(1,intreal(4),3);
} {4.0 4.0}
do_execsql_test 170 {
SELECT max(1.0,intreal(2),intreal(3),4.0),
max(1,intreal(2),intreal(3),4);
} {4.0 4}
do_execsql_test 180 {
SELECT max(1.0,intreal(5),intreal(3),4.0),
max(1,intreal(5),intreal(3),4);
} {5.0 5.0}
finish_test
-23
View File
@@ -178,32 +178,10 @@ do_eqp_test like3-5.211 {
`--SEARCH TABLE t5b USING COVERING INDEX sqlite_autoindex_t5b_1 (x>? AND x<?)
}
# 2019-05-01
# another case of the above reported on the mailing list by Manuel Rigger.
#
do_execsql_test like3-5.300 {
CREATE TABLE t5c (c0 REAL);
CREATE INDEX t5c_0 ON t5c(c0 COLLATE NOCASE);
INSERT INTO t5c(rowid, c0) VALUES (99,'+/');
SELECT * FROM t5c WHERE (c0 LIKE '+/');
} {+/}
# 2019-05-08
# Yet another case for the above from Manuel Rigger.
#
do_execsql_test like3-5.400 {
DROP TABLE IF EXISTS t0;
CREATE TABLE t0(c0 INT UNIQUE COLLATE NOCASE);
INSERT INTO t0(c0) VALUES ('./');
SELECT * FROM t0 WHERE t0.c0 LIKE './';
} {./}
# 2019-02-27
# Verify that the LIKE optimization works with an ESCAPE clause when
# using PRAGMA case_sensitive_like=ON.
#
ifcapable !icu {
do_execsql_test like3-6.100 {
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(path TEXT COLLATE nocase PRIMARY KEY,a,b,c) WITHOUT ROWID;
@@ -251,6 +229,5 @@ do_eqp_test like3-6.240 {
QUERY PLAN
`--SEARCH TABLE t2 USING INDEX t2path2 (path>? AND path<?)
}
}
finish_test
+9 -23
View File
@@ -52,32 +52,18 @@ proc do_re_test {tn script expression} {
# an error may be reported for either open() or getcwd() here.
#
if {![clang_sanitize_address]} {
unset -nocomplain rc
unset -nocomplain nOpen
set nOpen 20000
do_test 1.1.1 {
set ::log [list]
set ::rc [catch {
for {set i 0} {$i < $::nOpen} {incr i} { sqlite3 dbh_$i test.db -readonly 1 }
} msg]
if {$::rc==0} {
# Some system (ex: Debian) are able to create 20000+ file descriptiors
# such systems will not fail here
set x ok
} elseif {$::rc==1 && $msg=="unable to open database file"} {
set x ok
} else {
set x [list $::rc $msg]
}
} {ok}
list [catch {
for {set i 0} {$i < 20000} {incr i} { sqlite3 dbh_$i test.db -readonly 1 }
} msg] $msg
} {1 {unable to open database file}}
do_test 1.1.2 {
catch { for {set i 0} {$i < $::nOpen} {incr i} { dbh_$i close } }
} $::rc
if {$rc} {
do_re_test 1.1.3 {
lindex $::log 0
} {^os_unix.c:\d+: \(\d+\) (open|getcwd)\(.*test.db\) - }
}
catch { for {set i 0} {$i < 20000} {incr i} { dbh_$i close } }
} {1}
do_re_test 1.1.3 {
lindex $::log 0
} {^os_unix.c:\d+: \(\d+\) (open|getcwd)\(.*test.db\) - }
}
-134
View File
@@ -1,134 +0,0 @@
# 2019 April 23
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
# Test the shell tool ".ar" command.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix recover
ifcapable !vtab {
finish_test; return
}
set CLI [test_find_cli]
proc compare_result {db1 db2 sql} {
set r1 [$db1 eval $sql]
set r2 [$db2 eval $sql]
if {$r1 != $r2} {
puts "r1: $r1"
puts "r2: $r2"
error "mismatch for $sql"
}
return ""
}
proc compare_dbs {db1 db2} {
compare_result $db1 $db2 "SELECT sql FROM sqlite_master ORDER BY 1"
foreach tbl [$db1 eval {SELECT name FROM sqlite_master WHERE type='table'}] {
compare_result $db1 $db2 "SELECT * FROM $tbl"
}
}
proc do_recover_test {tn {tsql {}} {res {}}} {
set fd [open "|$::CLI test.db .recover"]
fconfigure $fd -encoding binary
fconfigure $fd -translation binary
set sql [read $fd]
close $fd
forcedelete test.db2
sqlite3 db2 test.db2
execsql $sql db2
if {$tsql==""} {
uplevel [list do_test $tn [list compare_dbs db db2] {}]
} else {
uplevel [list do_execsql_test -db db2 $tn $tsql $res]
}
db2 close
}
set doc {
hello
world
}
do_execsql_test 1.1.1 {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
INSERT INTO t1 VALUES(1, 4, X'1234567800');
INSERT INTO t1 VALUES(2, 'test', 8.1);
INSERT INTO t1 VALUES(3, $doc, 8.4);
}
do_recover_test 1.1.2
do_execsql_test 1.2.1 "
DELETE FROM t1;
INSERT INTO t1 VALUES(13, 'hello\r\nworld', 13);
"
do_recover_test 1.2.2
do_execsql_test 1.3.1 "
CREATE TABLE t2(i INTEGER PRIMARY KEY AUTOINCREMENT, b, c);
INSERT INTO t2 VALUES(NULL, 1, 2);
INSERT INTO t2 VALUES(NULL, 3, 4);
INSERT INTO t2 VALUES(NULL, 5, 6);
CREATE TABLE t3(i INTEGER PRIMARY KEY AUTOINCREMENT, b, c);
INSERT INTO t3 VALUES(NULL, 1, 2);
INSERT INTO t3 VALUES(NULL, 3, 4);
INSERT INTO t3 VALUES(NULL, 5, 6);
DELETE FROM t2;
"
do_recover_test 1.3.2
#-------------------------------------------------------------------------
reset_db
do_execsql_test 2.1.0 {
PRAGMA auto_vacuum = 0;
CREATE TABLE t1(a, b, c, PRIMARY KEY(b, c)) WITHOUT ROWID;
INSERT INTO t1 VALUES(1, 2, 3);
INSERT INTO t1 VALUES(4, 5, 6);
INSERT INTO t1 VALUES(7, 8, 9);
}
do_recover_test 2.1.1
do_execsql_test 2.2.0 {
PRAGMA writable_schema = 1;
DELETE FROM sqlite_master WHERE name='t1';
}
do_recover_test 2.2.1 {
SELECT name FROM sqlite_master
} {lost_and_found}
do_execsql_test 2.3.0 {
CREATE TABLE lost_and_found(a, b, c);
}
do_recover_test 2.3.1 {
SELECT name FROM sqlite_master
} {lost_and_found lost_and_found_0}
do_execsql_test 2.4.0 {
CREATE TABLE lost_and_found_0(a, b, c);
}
do_recover_test 2.4.1 {
SELECT name FROM sqlite_master;
SELECT * FROM lost_and_found_1;
} {lost_and_found lost_and_found_0 lost_and_found_1
2 2 3 {} 2 3 1
2 2 3 {} 5 6 4
2 2 3 {} 8 9 7
}
#-------------------------------------------------------------------------
reset_db
do_recover_test 3.0
finish_test
-46
View File
@@ -659,32 +659,6 @@ do_test rowid-11.4 {
execsql {SELECT rowid, a FROM t5 WHERE rowid<='abc'}
} {1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8}
do_test rowid-11.asc.1 {
execsql {SELECT rowid, a FROM t5 WHERE rowid>'abc' ORDER BY 1 ASC}
} {}
do_test rowid-11.asc.2 {
execsql {SELECT rowid, a FROM t5 WHERE rowid>='abc' ORDER BY 1 ASC}
} {}
do_test rowid-11.asc.3 {
execsql {SELECT rowid, a FROM t5 WHERE rowid<'abc' ORDER BY 1 ASC}
} {1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8}
do_test rowid-11.asc.4 {
execsql {SELECT rowid, a FROM t5 WHERE rowid<='abc' ORDER BY 1 ASC}
} {1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8}
do_test rowid-11.desc.1 {
execsql {SELECT rowid, a FROM t5 WHERE rowid>'abc' ORDER BY 1 DESC}
} {}
do_test rowid-11.desc.2 {
execsql {SELECT rowid, a FROM t5 WHERE rowid>='abc' ORDER BY 1 DESC}
} {}
do_test rowid-11.desc.3 {
execsql {SELECT rowid, a FROM t5 WHERE rowid<'abc' ORDER BY 1 DESC}
} {8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1}
do_test rowid-11.desc.4 {
execsql {SELECT rowid, a FROM t5 WHERE rowid<='abc' ORDER BY 1 DESC}
} {8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1}
# Test the automatic generation of rowids when the table already contains
# a rowid with the maximum value.
#
@@ -745,24 +719,4 @@ do_execsql_test rowid-13.1 {
SELECT last_insert_rowid();
} {1234 5 2234 | 2234 4990756 3234 | 3234 10458756 4234 | 4234}
#-------------------------------------------------------------------------
do_execsql_test rowid-14.0 {
CREATE TABLE t14(x INTEGER PRIMARY KEY);
INSERT INTO t14(x) VALUES (100);
}
do_execsql_test rowid-14.1 {
SELECT * FROM t14 WHERE x < 'a' ORDER BY rowid ASC;
} {100}
do_execsql_test rowid-14.2 {
SELECT * FROM t14 WHERE x < 'a' ORDER BY rowid DESC;
} {100}
do_execsql_test rowid-14.3 {
DELETE FROM t14;
SELECT * FROM t14 WHERE x < 'a' ORDER BY rowid ASC;
} {}
do_execsql_test rowid-14.4 {
SELECT * FROM t14 WHERE x < 'a' ORDER BY rowid DESC;
} {}
finish_test
-45
View File
@@ -261,49 +261,4 @@ do_test select3-8.2 {
}
} {real}
# 2019-05-09 ticket https://www.sqlite.org/src/tktview/6c1d3febc00b22d457c7
#
unset -nocomplain x
foreach {id x} {
100 127
101 128
102 -127
103 -128
104 -129
110 32767
111 32768
112 -32767
113 -32768
114 -32769
120 2147483647
121 2147483648
122 -2147483647
123 -2147483648
124 -2147483649
130 140737488355327
131 140737488355328
132 -140737488355327
133 -140737488355328
134 -140737488355329
140 9223372036854775807
141 -9223372036854775807
142 -9223372036854775808
143 9223372036854775806
144 9223372036854775805
145 -9223372036854775806
146 -9223372036854775805
} {
set x [expr {$x+0}]
do_execsql_test select3-8.$id {
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c0, c1 REAL PRIMARY KEY);
INSERT INTO t1(c0, c1) VALUES (0, $x), (0, 0);
UPDATE t1 SET c0 = NULL;
UPDATE OR REPLACE t1 SET c1 = 1;
SELECT DISTINCT * FROM t1 WHERE (t1.c0 IS NULL);
PRAGMA integrity_check;
} {{} 1.0 ok}
}
finish_test
-15
View File
@@ -701,19 +701,4 @@ do_test view-25.2 {
set log
} $res
#-------------------------------------------------------------------------
do_execsql_test view-26.0 {
CREATE TABLE t16(a, b, c UNIQUE);
INSERT INTO t16 VALUES(1, 1, 1);
INSERT INTO t16 VALUES(2, 2, 2);
INSERT INTO t16 VALUES(3, 3, 3);
CREATE VIEW v16 AS SELECT max(a) AS mx, min(b) AS mn FROM t16 GROUP BY c;
SELECT * FROM v16 AS one, v16 AS two WHERE one.mx=1;
} {
1 1 1 1
1 1 2 2
1 1 3 3
}
finish_test
+35 -309
View File
@@ -20,20 +20,16 @@ source [file join [file dirname [info script]] releasetest_data.tcl]
#
set G(platform) $::tcl_platform(os)-$::tcl_platform(machine)
set G(test) Normal
set G(keep) 1
set G(keep) 0
set G(msvc) 0
set G(tcl) [::tcl::pkgconfig get libdir,install]
set G(jobs) 3
set G(debug) 0
set G(noui) 0
set G(stdout) 0
proc wapptest_init {} {
global G
set lSave [list platform test keep msvc tcl jobs debug noui stdout]
set lSave [list platform test keep msvc tcl jobs debug]
foreach k $lSave { set A($k) $G($k) }
array unset G
foreach k $lSave { set G($k) $A($k) }
@@ -41,6 +37,9 @@ proc wapptest_init {} {
# The root of the SQLite source tree.
set G(srcdir) [file dirname [file dirname [info script]]]
# releasetest.tcl script
set G(releaseTest) [file join [file dirname [info script]] releasetest.tcl]
set G(sqlite_version) "unknown"
# Either "config", "running" or "stopped":
@@ -53,36 +52,28 @@ proc wapptest_init {} {
append G(host) " $::tcl_platform(machine) $::tcl_platform(byteOrder)"
}
proc wapptest_run {} {
# Check to see if there are uncommitted changes in the SQLite source
# directory. Return true if there are, or false otherwise.
#
proc check_uncommitted {} {
global G
set_test_array
set G(state) "running"
wapptest_openlog
wapptest_output "Running the following for $G(platform). $G(jobs) jobs."
foreach t $G(test_array) {
set config [dict get $t config]
set target [dict get $t target]
wapptest_output [format " %-25s%s" $config $target]
set ret 0
set pwd [pwd]
cd $G(srcdir)
if {[catch {exec fossil changes} res]==0 && [string trim $res]!=""} {
set ret 1
}
wapptest_output [string repeat * 70]
cd $pwd
return $ret
}
# Generate the text for the box at the top of the UI. The current SQLite
# version, according to fossil, along with a warning if there are
# uncommitted changes in the checkout.
#
proc generate_fossil_info {} {
global G
set pwd [pwd]
cd $G(srcdir)
set rc [catch {
set r1 [exec fossil info]
set r2 [exec fossil changes]
}]
if {[catch {exec fossil info} r1]} return
if {[catch {exec fossil changes} r2]} return
cd $pwd
if {$rc} return
foreach line [split $r1 "\n"] {
if {[regexp {^checkout: *(.*)$} $line -> co]} {
@@ -217,35 +208,6 @@ proc count_tests_and_errors {name logfile} {
}
}
proc wapptest_output {str} {
global G
if {$G(stdout)} { puts $str }
if {[info exists G(log)]} {
puts $G(log) $str
flush $G(log)
}
}
proc wapptest_openlog {} {
global G
set G(log) [open wapptest-out.txt w+]
}
proc wapptest_closelog {} {
global G
close $G(log)
unset G(log)
}
proc format_seconds {seconds} {
set min [format %.2d [expr ($seconds / 60) % 60]]
set hr [format %.2d [expr $seconds / 3600]]
set sec [format %.2d [expr $seconds % 60]]
return "$hr:$min:$sec"
}
# This command is invoked once a slave process has finished running its
# tests, successfully or otherwise. Parameter $name is the name of the
# test, $rc the exit code returned by the slave process.
#
proc slave_test_done {name rc} {
global G
set G(test.$name.done) [clock seconds]
@@ -258,43 +220,8 @@ proc slave_test_done {name rc} {
if {[file exists $G(test.$name.log)]} {
count_tests_and_errors $name $G(test.$name.log)
}
# If the "keep files" checkbox is clear, delete all files except for
# the executables and test logs. And any core file that is present.
if {$G(keep)==0} {
set keeplist {
testfixture testfixture.exe
sqlite3 sqlite3.exe
test.log test-out.txt
core
wapptest_make.sh
wapptest_configure.sh
wapptest_run.tcl
}
foreach f [glob -nocomplain [file join $G(test.$name.dir) *]] {
set t [file tail $f]
if {[lsearch $keeplist $t]<0} {
catch { file delete -force $f }
}
}
}
# Format a message regarding the success or failure of hte test.
set t [format_seconds [expr $G(test.$name.done) - $G(test.$name.start)]]
set res "OK"
if {$G(test.$name.nError)} { set res "FAILED" }
set dots [string repeat . [expr 60 - [string length $name]]]
set msg "$name $dots $res ($t)"
wapptest_output $msg
if {[info exists G(test.$name.errmsg)] && $G(test.$name.errmsg)!=""} {
wapptest_output " $G(test.$config.errmsg)"
}
}
# This is a fileevent callback invoked each time a file-descriptor that
# connects this process to a slave process is readable.
#
proc slave_fileevent {name} {
global G
set fd $G(test.$name.channel)
@@ -312,99 +239,6 @@ proc slave_fileevent {name} {
do_some_stuff
}
# Return the contents of the "slave script" - the script run by slave
# processes to actually perform the test. It does two things:
#
# 1. Reads and [exec]s the contents of file wapptest_configure.sh.
# 2. Reads and [exec]s the contents of file wapptest_make.sh.
#
# Step 1 is omitted if the test uses MSVC (which does not use configure).
#
proc wapptest_slave_script {} {
global G
set res {
proc readfile {filename} {
set fd [open $filename]
set data [read $fd]
close $fd
return $data
}
}
if {$G(msvc)==0} {
append res {
set cfg [readfile wapptest_configure.sh]
set rc [catch { exec {*}$cfg >& test.log } msg]
if {$rc==0} {
set make [readfile wapptest_make.sh]
set rc [catch { exec {*}$make >>& test.log }]
}
}
} else {
append res {
set make [readfile wapptest_make.sh]
set rc [catch { exec {*}$make >>& test.log }]
}
}
append res { exit $rc }
set res
}
# Launch a slave process to run a test.
#
proc slave_launch {
name wtcl title dir configOpts testtarget makeOpts cflags opts
} {
global G
catch { file mkdir $dir } msg
foreach f [glob -nocomplain [file join $dir *]] {
catch { file delete -force $f }
}
set G(test.$name.dir) $dir
# Write the configure command to wapptest_configure.sh. This file
# is empty if using MSVC - MSVC does not use configure.
#
set fd1 [open [file join $dir wapptest_configure.sh] w]
if {$G(msvc)==0} {
puts $fd1 "[file join .. $G(srcdir) configure] $wtcl $configOpts"
}
close $fd1
# Write the make command to wapptest_make.sh. Using nmake for MSVC and
# make for all other systems.
#
set makecmd "make"
if {$G(msvc)} {
set nativedir [file nativename $G(srcdir)]
set nativedir [string map [list "\\" "\\\\"] $nativedir]
set makecmd "nmake /f [file join $nativedir Makefile.msc] TOP=$nativedir"
}
set fd2 [open [file join $dir wapptest_make.sh] w]
puts $fd2 "$makecmd $makeOpts $testtarget \"CFLAGS=$cflags\" \"OPTS=$opts\""
close $fd2
# Write the wapptest_run.tcl script to the test directory. To run the
# commands in the other two files.
#
set fd3 [open [file join $dir wapptest_run.tcl] w]
puts $fd3 [wapptest_slave_script]
close $fd3
set pwd [pwd]
cd $dir
set fd [open "|[info nameofexecutable] wapptest_run.tcl" r+]
cd $pwd
set G(test.$name.channel) $fd
fconfigure $fd -blocking 0
fileevent $fd readable [list slave_fileevent $name]
}
proc do_some_stuff {} {
global G
@@ -429,15 +263,10 @@ proc do_some_stuff {} {
incr nConfig
}
set G(result) "$nError errors from $nTest tests in $nConfig configurations."
wapptest_output [string repeat * 70]
wapptest_output $G(result)
catch {
append G(result) " SQLite version $G(sqlite_version)"
wapptest_output " SQLite version $G(sqlite_version)"
}
set G(state) "stopped"
wapptest_closelog
if {$G(noui)} { exit 0 }
} else {
set nLaunch [expr $G(jobs) - $nRunning]
foreach j $G(test_array) {
@@ -446,9 +275,15 @@ proc do_some_stuff {} {
if { ![info exists G(test.$name.channel)]
&& ![info exists G(test.$name.done)]
} {
set target [dict get $j target]
set G(test.$name.start) [clock seconds]
set fd [open "|[info nameofexecutable] $G(releaseTest) --slave" r+]
set G(test.$name.channel) $fd
fconfigure $fd -blocking 0
fileevent $fd readable [list slave_fileevent $name]
puts $fd [list 0 $G(msvc) 0 $G(keep)]
set wtcl ""
if {$G(tcl)!=""} { set wtcl "--with-tcl=$G(tcl)" }
@@ -468,9 +303,8 @@ proc do_some_stuff {} {
}
set L [make_test_suite $G(msvc) $wtcl $name $target $opts]
set G(test.$name.log) [file join [lindex $L 1] test.log]
slave_launch $name $wtcl {*}$L
puts $fd $L
flush $fd
set G(test.$name.log) [file join [lindex $L 1] test.log]
incr nLaunch -1
}
@@ -605,7 +439,11 @@ proc wapp-page-tests {} {
}
set seconds [expr $G(test.$config.done) - $G(test.$config.start)]
}
set seconds [format_seconds $seconds]
set min [format %.2d [expr ($seconds / 60) % 60]]
set hr [format %.2d [expr $seconds / 3600]]
set sec [format %.2d [expr $seconds % 60]]
set seconds "$hr:$min:$sec"
}
wapp-trim {
@@ -664,7 +502,8 @@ proc wapp-page-control {} {
if {[wapp-param-exists control_run]} {
# This is a "run test" command.
wapptest_run
set_test_array
set ::G(state) "running"
}
if {[wapp-param-exists control_stop]} {
@@ -679,7 +518,6 @@ proc wapp-page-control {} {
slave_test_done $name 1
}
}
wapptest_closelog
}
if {[wapp-param-exists control_reset]} {
@@ -831,118 +669,6 @@ proc wapp-page-log {} {
}
}
# Print out a usage message. Then do [exit 1].
#
proc wapptest_usage {} {
puts stderr {
This Tcl script is used to test various configurations of SQLite. By
default it uses "wapp" to provide an interactive interface. Supported
command line options (all optional) are:
--platform PLATFORM (which tests to run)
--smoketest (run "make smoketest" only)
--veryquick (run veryquick.test only)
--buildonly (build executables, do not run tests)
--jobs N (number of concurrent jobs)
--tcl DIR (where to find tclConfig.sh)
--deletefiles (delete extra files after each test)
--msvc (Use MS Visual C)
--debug (Also run [n]debugging versions of tests)
--noui (do not use wapp)
}
exit 1
}
# Sort command line arguments into two groups: those that belong to wapp,
# and those that belong to the application.
set WAPPARG(-server) 1
set WAPPARG(-local) 1
set WAPPARG(-scgi) 1
set WAPPARG(-remote-scgi) 1
set WAPPARG(-fromip) 1
set WAPPARG(-nowait) 0
set WAPPARG(-cgi) 0
set lWappArg [list]
set lTestArg [list]
for {set i 0} {$i < [llength $argv]} {incr i} {
set arg [lindex $argv $i]
if {[string range $arg 0 1]=="--"} {
set arg [string range $arg 1 end]
}
if {[info exists WAPPARG($arg)]} {
lappend lWappArg $arg
if {$WAPPARG($arg)} {
incr i
lappend lWappArg [lindex $argv $i]
}
} else {
lappend lTestArg $arg
}
}
for {set i 0} {$i < [llength $lTestArg]} {incr i} {
switch -- [lindex $lTestArg $i] {
-platform {
if {$i==[llength $lTestArg]-1} { wapptest_usage }
incr i
set arg [lindex $lTestArg $i]
set lPlatform [array names ::Platforms]
if {[lsearch $lPlatform $arg]<0} {
puts stderr "No such platform: $arg. Platforms are: $lPlatform"
exit -1
}
set G(platform) $arg
}
-smoketest { set G(test) Smoketest }
-veryquick { set G(test) Veryquick }
-buildonly { set G(test) Build-Only }
-jobs {
if {$i==[llength $lTestArg]-1} { wapptest_usage }
incr i
set G(jobs) [lindex $lTestArg $i]
}
-tcl {
if {$i==[llength $lTestArg]-1} { wapptest_usage }
incr i
set G(tcl) [lindex $lTestArg $i]
}
-deletefiles {
set G(keep) 0
}
-msvc {
set G(msvc) 1
}
-debug {
set G(debug) 1
}
-noui {
set G(noui) 1
set G(stdout) 1
}
-stdout {
set G(stdout) 1
}
default {
puts stderr "Unrecognized option: [lindex $lTestArg $i]"
wapptest_usage
}
}
}
wapptest_init
if {$G(noui)==0} {
wapp-start $lWappArg
} else {
wapptest_run
do_some_stuff
vwait forever
}
wapp-start $argv
-7
View File
@@ -417,13 +417,6 @@ execsql_test 4.8.4 {
) FROM t2 ORDER BY 1, 2;
}
execsql_float_test 4.9 {
SELECT
rank() OVER win AS rank,
cume_dist() OVER win AS cume_dist FROM t1
WINDOW win AS (ORDER BY 1);
}
finish_test
+17 -479
View File
@@ -326,32 +326,7 @@ do_execsql_test 4.1 {
PARTITION BY (b%10)
ORDER BY b
) FROM t2 ORDER BY a;
} {1 0 2 754 3 251 4 754 5 101 6 1247 7 132 8 266 9 6 10 950
11 667 12 1052 13 535 14 128 15 428 16 250 17 336 18 1122
19 368 20 6 21 1247 22 1000 23 92 24 368 25 584 26 320
27 1000 28 24 29 478 30 133 31 1049 32 1090 33 632 34 101
35 54 36 54 37 1049 38 450 39 145 40 354 41 21 42 764
43 754 44 424 45 1122 46 930 47 42 48 930 49 352 50 535
51 42 52 118 53 536 54 6 55 1122 56 86 57 770 58 255 59 50
60 52 61 950 62 75 63 354 64 2 65 536 66 160 67 352 68 536
69 54 70 675 71 276 72 950 73 868 74 678 75 667 76 4
77 1184 78 160 79 120 80 584 81 266 82 133 83 405 84 468
85 6 86 806 87 166 88 500 89 1090 90 552 91 251 92 27
93 424 94 687 95 1215 96 450 97 32 98 360 99 1052 100 868
101 2 102 66 103 754 104 450 105 145 106 5 107 687 108 24
109 302 110 806 111 251 112 42 113 24 114 30 115 128 116 128
117 50 118 1215 119 86 120 687 121 683 122 672 123 178 124 24
125 24 126 299 127 178 128 770 129 535 130 1052 131 270
132 255 133 675 134 632 135 266 136 6 137 21 138 930 139 411
140 754 141 133 142 340 143 535 144 46 145 250 146 132
147 132 148 354 149 500 150 770 151 276 152 360 153 354
154 27 155 552 156 552 157 602 158 266 159 1049 160 675
161 384 162 667 163 27 164 101 165 166 166 32 167 42 168 18
169 336 170 1122 171 276 172 1122 173 266 174 50 175 178
176 276 177 1247 178 6 179 1215 180 604 181 360 182 212
183 120 184 210 185 1090 186 10 187 1090 188 266 189 66
190 250 191 266 192 360 193 120 194 128 195 178 196 770
197 92 198 634 199 38 200 21}
} {1 0 2 754 3 251 4 754 5 101 6 1247 7 132 8 266 9 6 10 950 11 667 12 1052 13 535 14 128 15 428 16 250 17 336 18 1122 19 368 20 6 21 1247 22 1000 23 92 24 368 25 584 26 320 27 1000 28 24 29 478 30 133 31 1049 32 1090 33 632 34 101 35 54 36 54 37 1049 38 450 39 145 40 354 41 21 42 764 43 754 44 424 45 1122 46 930 47 42 48 930 49 352 50 535 51 42 52 118 53 536 54 6 55 1122 56 86 57 770 58 255 59 50 60 52 61 950 62 75 63 354 64 2 65 536 66 160 67 352 68 536 69 54 70 675 71 276 72 950 73 868 74 678 75 667 76 4 77 1184 78 160 79 120 80 584 81 266 82 133 83 405 84 468 85 6 86 806 87 166 88 500 89 1090 90 552 91 251 92 27 93 424 94 687 95 1215 96 450 97 32 98 360 99 1052 100 868 101 2 102 66 103 754 104 450 105 145 106 5 107 687 108 24 109 302 110 806 111 251 112 42 113 24 114 30 115 128 116 128 117 50 118 1215 119 86 120 687 121 683 122 672 123 178 124 24 125 24 126 299 127 178 128 770 129 535 130 1052 131 270 132 255 133 675 134 632 135 266 136 6 137 21 138 930 139 411 140 754 141 133 142 340 143 535 144 46 145 250 146 132 147 132 148 354 149 500 150 770 151 276 152 360 153 354 154 27 155 552 156 552 157 602 158 266 159 1049 160 675 161 384 162 667 163 27 164 101 165 166 166 32 167 42 168 18 169 336 170 1122 171 276 172 1122 173 266 174 50 175 178 176 276 177 1247 178 6 179 1215 180 604 181 360 182 212 183 120 184 210 185 1090 186 10 187 1090 188 266 189 66 190 250 191 266 192 360 193 120 194 128 195 178 196 770 197 92 198 634 199 38 200 21}
do_execsql_test 4.2 {
SELECT a, sum(b) OVER (
@@ -359,538 +334,101 @@ do_execsql_test 4.2 {
ORDER BY b
RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) FROM t2 ORDER BY a;
} {1 0 2 754 3 251 4 754 5 101 6 1247 7 132 8 266 9 6 10 950
11 667 12 1052 13 535 14 128 15 428 16 250 17 336 18 1122
19 368 20 6 21 1247 22 1000 23 92 24 368 25 584 26 320
27 1000 28 24 29 478 30 133 31 1049 32 1090 33 632 34 101
35 54 36 54 37 1049 38 450 39 145 40 354 41 21 42 764
43 754 44 424 45 1122 46 930 47 42 48 930 49 352 50 535
51 42 52 118 53 536 54 6 55 1122 56 86 57 770 58 255 59 50
60 52 61 950 62 75 63 354 64 2 65 536 66 160 67 352 68 536
69 54 70 675 71 276 72 950 73 868 74 678 75 667 76 4
77 1184 78 160 79 120 80 584 81 266 82 133 83 405 84 468
85 6 86 806 87 166 88 500 89 1090 90 552 91 251 92 27
93 424 94 687 95 1215 96 450 97 32 98 360 99 1052 100 868
101 2 102 66 103 754 104 450 105 145 106 5 107 687 108 24
109 302 110 806 111 251 112 42 113 24 114 30 115 128 116 128
117 50 118 1215 119 86 120 687 121 683 122 672 123 178 124 24
125 24 126 299 127 178 128 770 129 535 130 1052 131 270
132 255 133 675 134 632 135 266 136 6 137 21 138 930 139 411
140 754 141 133 142 340 143 535 144 46 145 250 146 132
147 132 148 354 149 500 150 770 151 276 152 360 153 354
154 27 155 552 156 552 157 602 158 266 159 1049 160 675
161 384 162 667 163 27 164 101 165 166 166 32 167 42 168 18
169 336 170 1122 171 276 172 1122 173 266 174 50 175 178
176 276 177 1247 178 6 179 1215 180 604 181 360 182 212
183 120 184 210 185 1090 186 10 187 1090 188 266 189 66
190 250 191 266 192 360 193 120 194 128 195 178 196 770
197 92 198 634 199 38 200 21}
} {1 0 2 754 3 251 4 754 5 101 6 1247 7 132 8 266 9 6 10 950 11 667 12 1052 13 535 14 128 15 428 16 250 17 336 18 1122 19 368 20 6 21 1247 22 1000 23 92 24 368 25 584 26 320 27 1000 28 24 29 478 30 133 31 1049 32 1090 33 632 34 101 35 54 36 54 37 1049 38 450 39 145 40 354 41 21 42 764 43 754 44 424 45 1122 46 930 47 42 48 930 49 352 50 535 51 42 52 118 53 536 54 6 55 1122 56 86 57 770 58 255 59 50 60 52 61 950 62 75 63 354 64 2 65 536 66 160 67 352 68 536 69 54 70 675 71 276 72 950 73 868 74 678 75 667 76 4 77 1184 78 160 79 120 80 584 81 266 82 133 83 405 84 468 85 6 86 806 87 166 88 500 89 1090 90 552 91 251 92 27 93 424 94 687 95 1215 96 450 97 32 98 360 99 1052 100 868 101 2 102 66 103 754 104 450 105 145 106 5 107 687 108 24 109 302 110 806 111 251 112 42 113 24 114 30 115 128 116 128 117 50 118 1215 119 86 120 687 121 683 122 672 123 178 124 24 125 24 126 299 127 178 128 770 129 535 130 1052 131 270 132 255 133 675 134 632 135 266 136 6 137 21 138 930 139 411 140 754 141 133 142 340 143 535 144 46 145 250 146 132 147 132 148 354 149 500 150 770 151 276 152 360 153 354 154 27 155 552 156 552 157 602 158 266 159 1049 160 675 161 384 162 667 163 27 164 101 165 166 166 32 167 42 168 18 169 336 170 1122 171 276 172 1122 173 266 174 50 175 178 176 276 177 1247 178 6 179 1215 180 604 181 360 182 212 183 120 184 210 185 1090 186 10 187 1090 188 266 189 66 190 250 191 266 192 360 193 120 194 128 195 178 196 770 197 92 198 634 199 38 200 21}
do_execsql_test 4.3 {
SELECT b, sum(b) OVER (
ORDER BY b
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) FROM t2 ORDER BY b;
} {0 0 1 1 1 2 2 4 2 6 2 8 3 11 3 14 4 18 5 23 6 29 7 36
7 43 7 50 8 58 8 66 8 74 9 83 9 92 9 101 10 111 11 122
11 133 12 145 12 157 12 169 13 182 13 195 14 209 15 224
15 239 15 254 16 270 16 286 16 302 17 319 19 338 20 358
21 379 21 400 22 422 22 444 23 467 23 490 23 513 24 537
25 562 26 588 26 614 26 640 27 667 27 694 28 722 29 751
29 780 29 809 30 839 30 869 30 899 31 930 31 961 32 993
33 1026 33 1059 33 1092 33 1125 33 1158 34 1192 34 1226
34 1260 34 1294 35 1329 35 1364 36 1400 36 1436 36 1472
36 1508 37 1545 37 1582 38 1620 38 1658 39 1697 39 1736
39 1775 40 1815 41 1856 41 1897 41 1938 42 1980 43 2023
43 2066 44 2110 44 2154 46 2200 46 2246 47 2293 47 2340
47 2387 47 2434 49 2483 50 2533 51 2584 52 2636 53 2689
54 2743 55 2798 55 2853 56 2909 56 2965 56 3021 57 3078
58 3136 58 3194 58 3252 58 3310 59 3369 59 3428 59 3487
59 3546 60 3606 61 3667 61 3728 62 3790 62 3852 63 3915
64 3979 65 4044 65 4109 65 4174 66 4240 67 4307 68 4375
69 4444 70 4514 72 4586 72 4658 72 4730 73 4803 73 4876
73 4949 74 5023 74 5097 74 5171 74 5245 74 5319 75 5394
75 5469 75 5544 76 5620 77 5697 77 5774 78 5852 78 5930
79 6009 80 6089 80 6169 81 6250 81 6331 81 6412 82 6494
83 6577 84 6661 84 6745 84 6829 84 6913 85 6998 85 7083
85 7168 86 7254 87 7341 87 7428 88 7516 89 7605 89 7694
89 7783 90 7873 90 7963 90 8053 91 8144 91 8235 91 8326
91 8417 91 8508 93 8601 93 8694 93 8787 94 8881 95 8976
95 9071 95 9166 96 9262 96 9358 96 9454 97 9551 97 9648
98 9746 98 9844 99 9943 99 10042 99 10141}
} {0 0 1 1 1 2 2 4 2 6 2 8 3 11 3 14 4 18 5 23 6 29 7 36 7 43 7 50 8 58 8 66 8 74 9 83 9 92 9 101 10 111 11 122 11 133 12 145 12 157 12 169 13 182 13 195 14 209 15 224 15 239 15 254 16 270 16 286 16 302 17 319 19 338 20 358 21 379 21 400 22 422 22 444 23 467 23 490 23 513 24 537 25 562 26 588 26 614 26 640 27 667 27 694 28 722 29 751 29 780 29 809 30 839 30 869 30 899 31 930 31 961 32 993 33 1026 33 1059 33 1092 33 1125 33 1158 34 1192 34 1226 34 1260 34 1294 35 1329 35 1364 36 1400 36 1436 36 1472 36 1508 37 1545 37 1582 38 1620 38 1658 39 1697 39 1736 39 1775 40 1815 41 1856 41 1897 41 1938 42 1980 43 2023 43 2066 44 2110 44 2154 46 2200 46 2246 47 2293 47 2340 47 2387 47 2434 49 2483 50 2533 51 2584 52 2636 53 2689 54 2743 55 2798 55 2853 56 2909 56 2965 56 3021 57 3078 58 3136 58 3194 58 3252 58 3310 59 3369 59 3428 59 3487 59 3546 60 3606 61 3667 61 3728 62 3790 62 3852 63 3915 64 3979 65 4044 65 4109 65 4174 66 4240 67 4307 68 4375 69 4444 70 4514 72 4586 72 4658 72 4730 73 4803 73 4876 73 4949 74 5023 74 5097 74 5171 74 5245 74 5319 75 5394 75 5469 75 5544 76 5620 77 5697 77 5774 78 5852 78 5930 79 6009 80 6089 80 6169 81 6250 81 6331 81 6412 82 6494 83 6577 84 6661 84 6745 84 6829 84 6913 85 6998 85 7083 85 7168 86 7254 87 7341 87 7428 88 7516 89 7605 89 7694 89 7783 90 7873 90 7963 90 8053 91 8144 91 8235 91 8326 91 8417 91 8508 93 8601 93 8694 93 8787 94 8881 95 8976 95 9071 95 9166 96 9262 96 9358 96 9454 97 9551 97 9648 98 9746 98 9844 99 9943 99 10042 99 10141}
do_execsql_test 4.4 {
SELECT b, sum(b) OVER (
ORDER BY b
RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
) FROM t2 ORDER BY b;
} {0 10141 1 10141 1 10141 2 10141 2 10141 2 10141 3 10141
3 10141 4 10141 5 10141 6 10141 7 10141 7 10141 7 10141
8 10141 8 10141 8 10141 9 10141 9 10141 9 10141 10 10141
11 10141 11 10141 12 10141 12 10141 12 10141 13 10141 13 10141
14 10141 15 10141 15 10141 15 10141 16 10141 16 10141 16 10141
17 10141 19 10141 20 10141 21 10141 21 10141 22 10141 22 10141
23 10141 23 10141 23 10141 24 10141 25 10141 26 10141 26 10141
26 10141 27 10141 27 10141 28 10141 29 10141 29 10141 29 10141
30 10141 30 10141 30 10141 31 10141 31 10141 32 10141 33 10141
33 10141 33 10141 33 10141 33 10141 34 10141 34 10141 34 10141
34 10141 35 10141 35 10141 36 10141 36 10141 36 10141 36 10141
37 10141 37 10141 38 10141 38 10141 39 10141 39 10141 39 10141
40 10141 41 10141 41 10141 41 10141 42 10141 43 10141 43 10141
44 10141 44 10141 46 10141 46 10141 47 10141 47 10141 47 10141
47 10141 49 10141 50 10141 51 10141 52 10141 53 10141 54 10141
55 10141 55 10141 56 10141 56 10141 56 10141 57 10141 58 10141
58 10141 58 10141 58 10141 59 10141 59 10141 59 10141 59 10141
60 10141 61 10141 61 10141 62 10141 62 10141 63 10141 64 10141
65 10141 65 10141 65 10141 66 10141 67 10141 68 10141 69 10141
70 10141 72 10141 72 10141 72 10141 73 10141 73 10141 73 10141
74 10141 74 10141 74 10141 74 10141 74 10141 75 10141 75 10141
75 10141 76 10141 77 10141 77 10141 78 10141 78 10141 79 10141
80 10141 80 10141 81 10141 81 10141 81 10141 82 10141 83 10141
84 10141 84 10141 84 10141 84 10141 85 10141 85 10141 85 10141
86 10141 87 10141 87 10141 88 10141 89 10141 89 10141 89 10141
90 10141 90 10141 90 10141 91 10141 91 10141 91 10141 91 10141
91 10141 93 10141 93 10141 93 10141 94 10141 95 10141 95 10141
95 10141 96 10141 96 10141 96 10141 97 10141 97 10141 98 10141
98 10141 99 10141 99 10141 99 10141}
} {0 10141 1 10141 1 10141 2 10141 2 10141 2 10141 3 10141 3 10141 4 10141 5 10141 6 10141 7 10141 7 10141 7 10141 8 10141 8 10141 8 10141 9 10141 9 10141 9 10141 10 10141 11 10141 11 10141 12 10141 12 10141 12 10141 13 10141 13 10141 14 10141 15 10141 15 10141 15 10141 16 10141 16 10141 16 10141 17 10141 19 10141 20 10141 21 10141 21 10141 22 10141 22 10141 23 10141 23 10141 23 10141 24 10141 25 10141 26 10141 26 10141 26 10141 27 10141 27 10141 28 10141 29 10141 29 10141 29 10141 30 10141 30 10141 30 10141 31 10141 31 10141 32 10141 33 10141 33 10141 33 10141 33 10141 33 10141 34 10141 34 10141 34 10141 34 10141 35 10141 35 10141 36 10141 36 10141 36 10141 36 10141 37 10141 37 10141 38 10141 38 10141 39 10141 39 10141 39 10141 40 10141 41 10141 41 10141 41 10141 42 10141 43 10141 43 10141 44 10141 44 10141 46 10141 46 10141 47 10141 47 10141 47 10141 47 10141 49 10141 50 10141 51 10141 52 10141 53 10141 54 10141 55 10141 55 10141 56 10141 56 10141 56 10141 57 10141 58 10141 58 10141 58 10141 58 10141 59 10141 59 10141 59 10141 59 10141 60 10141 61 10141 61 10141 62 10141 62 10141 63 10141 64 10141 65 10141 65 10141 65 10141 66 10141 67 10141 68 10141 69 10141 70 10141 72 10141 72 10141 72 10141 73 10141 73 10141 73 10141 74 10141 74 10141 74 10141 74 10141 74 10141 75 10141 75 10141 75 10141 76 10141 77 10141 77 10141 78 10141 78 10141 79 10141 80 10141 80 10141 81 10141 81 10141 81 10141 82 10141 83 10141 84 10141 84 10141 84 10141 84 10141 85 10141 85 10141 85 10141 86 10141 87 10141 87 10141 88 10141 89 10141 89 10141 89 10141 90 10141 90 10141 90 10141 91 10141 91 10141 91 10141 91 10141 91 10141 93 10141 93 10141 93 10141 94 10141 95 10141 95 10141 95 10141 96 10141 96 10141 96 10141 97 10141 97 10141 98 10141 98 10141 99 10141 99 10141 99 10141}
do_execsql_test 4.5 {
SELECT b, sum(b) OVER (
ORDER BY b
RANGE BETWEEN CURRENT ROW AND CURRENT ROW
) FROM t2 ORDER BY b;
} {0 0 1 2 1 2 2 6 2 6 2 6 3 6 3 6 4 4 5 5 6 6 7 21
7 21 7 21 8 24 8 24 8 24 9 27 9 27 9 27 10 10 11 22
11 22 12 36 12 36 12 36 13 26 13 26 14 14 15 45 15 45
15 45 16 48 16 48 16 48 17 17 19 19 20 20 21 42 21 42
22 44 22 44 23 69 23 69 23 69 24 24 25 25 26 78 26 78
26 78 27 54 27 54 28 28 29 87 29 87 29 87 30 90 30 90
30 90 31 62 31 62 32 32 33 165 33 165 33 165 33 165 33 165
34 136 34 136 34 136 34 136 35 70 35 70 36 144 36 144
36 144 36 144 37 74 37 74 38 76 38 76 39 117 39 117 39 117
40 40 41 123 41 123 41 123 42 42 43 86 43 86 44 88 44 88
46 92 46 92 47 188 47 188 47 188 47 188 49 49 50 50 51 51
52 52 53 53 54 54 55 110 55 110 56 168 56 168 56 168 57 57
58 232 58 232 58 232 58 232 59 236 59 236 59 236 59 236
60 60 61 122 61 122 62 124 62 124 63 63 64 64 65 195 65 195
65 195 66 66 67 67 68 68 69 69 70 70 72 216 72 216 72 216
73 219 73 219 73 219 74 370 74 370 74 370 74 370 74 370
75 225 75 225 75 225 76 76 77 154 77 154 78 156 78 156
79 79 80 160 80 160 81 243 81 243 81 243 82 82 83 83 84 336
84 336 84 336 84 336 85 255 85 255 85 255 86 86 87 174
87 174 88 88 89 267 89 267 89 267 90 270 90 270 90 270
91 455 91 455 91 455 91 455 91 455 93 279 93 279 93 279
94 94 95 285 95 285 95 285 96 288 96 288 96 288 97 194
97 194 98 196 98 196 99 297 99 297 99 297}
} {0 0 1 2 1 2 2 6 2 6 2 6 3 6 3 6 4 4 5 5 6 6 7 21 7 21 7 21 8 24 8 24 8 24 9 27 9 27 9 27 10 10 11 22 11 22 12 36 12 36 12 36 13 26 13 26 14 14 15 45 15 45 15 45 16 48 16 48 16 48 17 17 19 19 20 20 21 42 21 42 22 44 22 44 23 69 23 69 23 69 24 24 25 25 26 78 26 78 26 78 27 54 27 54 28 28 29 87 29 87 29 87 30 90 30 90 30 90 31 62 31 62 32 32 33 165 33 165 33 165 33 165 33 165 34 136 34 136 34 136 34 136 35 70 35 70 36 144 36 144 36 144 36 144 37 74 37 74 38 76 38 76 39 117 39 117 39 117 40 40 41 123 41 123 41 123 42 42 43 86 43 86 44 88 44 88 46 92 46 92 47 188 47 188 47 188 47 188 49 49 50 50 51 51 52 52 53 53 54 54 55 110 55 110 56 168 56 168 56 168 57 57 58 232 58 232 58 232 58 232 59 236 59 236 59 236 59 236 60 60 61 122 61 122 62 124 62 124 63 63 64 64 65 195 65 195 65 195 66 66 67 67 68 68 69 69 70 70 72 216 72 216 72 216 73 219 73 219 73 219 74 370 74 370 74 370 74 370 74 370 75 225 75 225 75 225 76 76 77 154 77 154 78 156 78 156 79 79 80 160 80 160 81 243 81 243 81 243 82 82 83 83 84 336 84 336 84 336 84 336 85 255 85 255 85 255 86 86 87 174 87 174 88 88 89 267 89 267 89 267 90 270 90 270 90 270 91 455 91 455 91 455 91 455 91 455 93 279 93 279 93 279 94 94 95 285 95 285 95 285 96 288 96 288 96 288 97 194 97 194 98 196 98 196 99 297 99 297 99 297}
do_execsql_test 4.6.1 {
SELECT b, sum(b) OVER (
RANGE BETWEEN CURRENT ROW AND CURRENT ROW
) FROM t2 ORDER BY b;
} {0 10141 1 10141 1 10141 2 10141 2 10141 2 10141 3 10141
3 10141 4 10141 5 10141 6 10141 7 10141 7 10141 7 10141
8 10141 8 10141 8 10141 9 10141 9 10141 9 10141 10 10141
11 10141 11 10141 12 10141 12 10141 12 10141 13 10141 13 10141
14 10141 15 10141 15 10141 15 10141 16 10141 16 10141 16 10141
17 10141 19 10141 20 10141 21 10141 21 10141 22 10141 22 10141
23 10141 23 10141 23 10141 24 10141 25 10141 26 10141 26 10141
26 10141 27 10141 27 10141 28 10141 29 10141 29 10141 29 10141
30 10141 30 10141 30 10141 31 10141 31 10141 32 10141 33 10141
33 10141 33 10141 33 10141 33 10141 34 10141 34 10141 34 10141
34 10141 35 10141 35 10141 36 10141 36 10141 36 10141 36 10141
37 10141 37 10141 38 10141 38 10141 39 10141 39 10141 39 10141
40 10141 41 10141 41 10141 41 10141 42 10141 43 10141 43 10141
44 10141 44 10141 46 10141 46 10141 47 10141 47 10141 47 10141
47 10141 49 10141 50 10141 51 10141 52 10141 53 10141 54 10141
55 10141 55 10141 56 10141 56 10141 56 10141 57 10141 58 10141
58 10141 58 10141 58 10141 59 10141 59 10141 59 10141 59 10141
60 10141 61 10141 61 10141 62 10141 62 10141 63 10141 64 10141
65 10141 65 10141 65 10141 66 10141 67 10141 68 10141 69 10141
70 10141 72 10141 72 10141 72 10141 73 10141 73 10141 73 10141
74 10141 74 10141 74 10141 74 10141 74 10141 75 10141 75 10141
75 10141 76 10141 77 10141 77 10141 78 10141 78 10141 79 10141
80 10141 80 10141 81 10141 81 10141 81 10141 82 10141 83 10141
84 10141 84 10141 84 10141 84 10141 85 10141 85 10141 85 10141
86 10141 87 10141 87 10141 88 10141 89 10141 89 10141 89 10141
90 10141 90 10141 90 10141 91 10141 91 10141 91 10141 91 10141
91 10141 93 10141 93 10141 93 10141 94 10141 95 10141 95 10141
95 10141 96 10141 96 10141 96 10141 97 10141 97 10141 98 10141
98 10141 99 10141 99 10141 99 10141}
} {0 10141 1 10141 1 10141 2 10141 2 10141 2 10141 3 10141 3 10141 4 10141 5 10141 6 10141 7 10141 7 10141 7 10141 8 10141 8 10141 8 10141 9 10141 9 10141 9 10141 10 10141 11 10141 11 10141 12 10141 12 10141 12 10141 13 10141 13 10141 14 10141 15 10141 15 10141 15 10141 16 10141 16 10141 16 10141 17 10141 19 10141 20 10141 21 10141 21 10141 22 10141 22 10141 23 10141 23 10141 23 10141 24 10141 25 10141 26 10141 26 10141 26 10141 27 10141 27 10141 28 10141 29 10141 29 10141 29 10141 30 10141 30 10141 30 10141 31 10141 31 10141 32 10141 33 10141 33 10141 33 10141 33 10141 33 10141 34 10141 34 10141 34 10141 34 10141 35 10141 35 10141 36 10141 36 10141 36 10141 36 10141 37 10141 37 10141 38 10141 38 10141 39 10141 39 10141 39 10141 40 10141 41 10141 41 10141 41 10141 42 10141 43 10141 43 10141 44 10141 44 10141 46 10141 46 10141 47 10141 47 10141 47 10141 47 10141 49 10141 50 10141 51 10141 52 10141 53 10141 54 10141 55 10141 55 10141 56 10141 56 10141 56 10141 57 10141 58 10141 58 10141 58 10141 58 10141 59 10141 59 10141 59 10141 59 10141 60 10141 61 10141 61 10141 62 10141 62 10141 63 10141 64 10141 65 10141 65 10141 65 10141 66 10141 67 10141 68 10141 69 10141 70 10141 72 10141 72 10141 72 10141 73 10141 73 10141 73 10141 74 10141 74 10141 74 10141 74 10141 74 10141 75 10141 75 10141 75 10141 76 10141 77 10141 77 10141 78 10141 78 10141 79 10141 80 10141 80 10141 81 10141 81 10141 81 10141 82 10141 83 10141 84 10141 84 10141 84 10141 84 10141 85 10141 85 10141 85 10141 86 10141 87 10141 87 10141 88 10141 89 10141 89 10141 89 10141 90 10141 90 10141 90 10141 91 10141 91 10141 91 10141 91 10141 91 10141 93 10141 93 10141 93 10141 94 10141 95 10141 95 10141 95 10141 96 10141 96 10141 96 10141 97 10141 97 10141 98 10141 98 10141 99 10141 99 10141 99 10141}
do_execsql_test 4.6.2 {
SELECT b, sum(b) OVER () FROM t2 ORDER BY b;
} {0 10141 1 10141 1 10141 2 10141 2 10141 2 10141 3 10141
3 10141 4 10141 5 10141 6 10141 7 10141 7 10141 7 10141
8 10141 8 10141 8 10141 9 10141 9 10141 9 10141 10 10141
11 10141 11 10141 12 10141 12 10141 12 10141 13 10141 13 10141
14 10141 15 10141 15 10141 15 10141 16 10141 16 10141 16 10141
17 10141 19 10141 20 10141 21 10141 21 10141 22 10141 22 10141
23 10141 23 10141 23 10141 24 10141 25 10141 26 10141 26 10141
26 10141 27 10141 27 10141 28 10141 29 10141 29 10141 29 10141
30 10141 30 10141 30 10141 31 10141 31 10141 32 10141 33 10141
33 10141 33 10141 33 10141 33 10141 34 10141 34 10141 34 10141
34 10141 35 10141 35 10141 36 10141 36 10141 36 10141 36 10141
37 10141 37 10141 38 10141 38 10141 39 10141 39 10141 39 10141
40 10141 41 10141 41 10141 41 10141 42 10141 43 10141 43 10141
44 10141 44 10141 46 10141 46 10141 47 10141 47 10141 47 10141
47 10141 49 10141 50 10141 51 10141 52 10141 53 10141 54 10141
55 10141 55 10141 56 10141 56 10141 56 10141 57 10141 58 10141
58 10141 58 10141 58 10141 59 10141 59 10141 59 10141 59 10141
60 10141 61 10141 61 10141 62 10141 62 10141 63 10141 64 10141
65 10141 65 10141 65 10141 66 10141 67 10141 68 10141 69 10141
70 10141 72 10141 72 10141 72 10141 73 10141 73 10141 73 10141
74 10141 74 10141 74 10141 74 10141 74 10141 75 10141 75 10141
75 10141 76 10141 77 10141 77 10141 78 10141 78 10141 79 10141
80 10141 80 10141 81 10141 81 10141 81 10141 82 10141 83 10141
84 10141 84 10141 84 10141 84 10141 85 10141 85 10141 85 10141
86 10141 87 10141 87 10141 88 10141 89 10141 89 10141 89 10141
90 10141 90 10141 90 10141 91 10141 91 10141 91 10141 91 10141
91 10141 93 10141 93 10141 93 10141 94 10141 95 10141 95 10141
95 10141 96 10141 96 10141 96 10141 97 10141 97 10141 98 10141
98 10141 99 10141 99 10141 99 10141}
} {0 10141 1 10141 1 10141 2 10141 2 10141 2 10141 3 10141 3 10141 4 10141 5 10141 6 10141 7 10141 7 10141 7 10141 8 10141 8 10141 8 10141 9 10141 9 10141 9 10141 10 10141 11 10141 11 10141 12 10141 12 10141 12 10141 13 10141 13 10141 14 10141 15 10141 15 10141 15 10141 16 10141 16 10141 16 10141 17 10141 19 10141 20 10141 21 10141 21 10141 22 10141 22 10141 23 10141 23 10141 23 10141 24 10141 25 10141 26 10141 26 10141 26 10141 27 10141 27 10141 28 10141 29 10141 29 10141 29 10141 30 10141 30 10141 30 10141 31 10141 31 10141 32 10141 33 10141 33 10141 33 10141 33 10141 33 10141 34 10141 34 10141 34 10141 34 10141 35 10141 35 10141 36 10141 36 10141 36 10141 36 10141 37 10141 37 10141 38 10141 38 10141 39 10141 39 10141 39 10141 40 10141 41 10141 41 10141 41 10141 42 10141 43 10141 43 10141 44 10141 44 10141 46 10141 46 10141 47 10141 47 10141 47 10141 47 10141 49 10141 50 10141 51 10141 52 10141 53 10141 54 10141 55 10141 55 10141 56 10141 56 10141 56 10141 57 10141 58 10141 58 10141 58 10141 58 10141 59 10141 59 10141 59 10141 59 10141 60 10141 61 10141 61 10141 62 10141 62 10141 63 10141 64 10141 65 10141 65 10141 65 10141 66 10141 67 10141 68 10141 69 10141 70 10141 72 10141 72 10141 72 10141 73 10141 73 10141 73 10141 74 10141 74 10141 74 10141 74 10141 74 10141 75 10141 75 10141 75 10141 76 10141 77 10141 77 10141 78 10141 78 10141 79 10141 80 10141 80 10141 81 10141 81 10141 81 10141 82 10141 83 10141 84 10141 84 10141 84 10141 84 10141 85 10141 85 10141 85 10141 86 10141 87 10141 87 10141 88 10141 89 10141 89 10141 89 10141 90 10141 90 10141 90 10141 91 10141 91 10141 91 10141 91 10141 91 10141 93 10141 93 10141 93 10141 94 10141 95 10141 95 10141 95 10141 96 10141 96 10141 96 10141 97 10141 97 10141 98 10141 98 10141 99 10141 99 10141 99 10141}
do_execsql_test 4.6.3 {
SELECT b, sum(b) OVER (
RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
) FROM t2 ORDER BY b;
} {0 10141 1 10141 1 10141 2 10141 2 10141 2 10141 3 10141
3 10141 4 10141 5 10141 6 10141 7 10141 7 10141 7 10141
8 10141 8 10141 8 10141 9 10141 9 10141 9 10141 10 10141
11 10141 11 10141 12 10141 12 10141 12 10141 13 10141 13 10141
14 10141 15 10141 15 10141 15 10141 16 10141 16 10141 16 10141
17 10141 19 10141 20 10141 21 10141 21 10141 22 10141 22 10141
23 10141 23 10141 23 10141 24 10141 25 10141 26 10141 26 10141
26 10141 27 10141 27 10141 28 10141 29 10141 29 10141 29 10141
30 10141 30 10141 30 10141 31 10141 31 10141 32 10141 33 10141
33 10141 33 10141 33 10141 33 10141 34 10141 34 10141 34 10141
34 10141 35 10141 35 10141 36 10141 36 10141 36 10141 36 10141
37 10141 37 10141 38 10141 38 10141 39 10141 39 10141 39 10141
40 10141 41 10141 41 10141 41 10141 42 10141 43 10141 43 10141
44 10141 44 10141 46 10141 46 10141 47 10141 47 10141 47 10141
47 10141 49 10141 50 10141 51 10141 52 10141 53 10141 54 10141
55 10141 55 10141 56 10141 56 10141 56 10141 57 10141 58 10141
58 10141 58 10141 58 10141 59 10141 59 10141 59 10141 59 10141
60 10141 61 10141 61 10141 62 10141 62 10141 63 10141 64 10141
65 10141 65 10141 65 10141 66 10141 67 10141 68 10141 69 10141
70 10141 72 10141 72 10141 72 10141 73 10141 73 10141 73 10141
74 10141 74 10141 74 10141 74 10141 74 10141 75 10141 75 10141
75 10141 76 10141 77 10141 77 10141 78 10141 78 10141 79 10141
80 10141 80 10141 81 10141 81 10141 81 10141 82 10141 83 10141
84 10141 84 10141 84 10141 84 10141 85 10141 85 10141 85 10141
86 10141 87 10141 87 10141 88 10141 89 10141 89 10141 89 10141
90 10141 90 10141 90 10141 91 10141 91 10141 91 10141 91 10141
91 10141 93 10141 93 10141 93 10141 94 10141 95 10141 95 10141
95 10141 96 10141 96 10141 96 10141 97 10141 97 10141 98 10141
98 10141 99 10141 99 10141 99 10141}
} {0 10141 1 10141 1 10141 2 10141 2 10141 2 10141 3 10141 3 10141 4 10141 5 10141 6 10141 7 10141 7 10141 7 10141 8 10141 8 10141 8 10141 9 10141 9 10141 9 10141 10 10141 11 10141 11 10141 12 10141 12 10141 12 10141 13 10141 13 10141 14 10141 15 10141 15 10141 15 10141 16 10141 16 10141 16 10141 17 10141 19 10141 20 10141 21 10141 21 10141 22 10141 22 10141 23 10141 23 10141 23 10141 24 10141 25 10141 26 10141 26 10141 26 10141 27 10141 27 10141 28 10141 29 10141 29 10141 29 10141 30 10141 30 10141 30 10141 31 10141 31 10141 32 10141 33 10141 33 10141 33 10141 33 10141 33 10141 34 10141 34 10141 34 10141 34 10141 35 10141 35 10141 36 10141 36 10141 36 10141 36 10141 37 10141 37 10141 38 10141 38 10141 39 10141 39 10141 39 10141 40 10141 41 10141 41 10141 41 10141 42 10141 43 10141 43 10141 44 10141 44 10141 46 10141 46 10141 47 10141 47 10141 47 10141 47 10141 49 10141 50 10141 51 10141 52 10141 53 10141 54 10141 55 10141 55 10141 56 10141 56 10141 56 10141 57 10141 58 10141 58 10141 58 10141 58 10141 59 10141 59 10141 59 10141 59 10141 60 10141 61 10141 61 10141 62 10141 62 10141 63 10141 64 10141 65 10141 65 10141 65 10141 66 10141 67 10141 68 10141 69 10141 70 10141 72 10141 72 10141 72 10141 73 10141 73 10141 73 10141 74 10141 74 10141 74 10141 74 10141 74 10141 75 10141 75 10141 75 10141 76 10141 77 10141 77 10141 78 10141 78 10141 79 10141 80 10141 80 10141 81 10141 81 10141 81 10141 82 10141 83 10141 84 10141 84 10141 84 10141 84 10141 85 10141 85 10141 85 10141 86 10141 87 10141 87 10141 88 10141 89 10141 89 10141 89 10141 90 10141 90 10141 90 10141 91 10141 91 10141 91 10141 91 10141 91 10141 93 10141 93 10141 93 10141 94 10141 95 10141 95 10141 95 10141 96 10141 96 10141 96 10141 97 10141 97 10141 98 10141 98 10141 99 10141 99 10141 99 10141}
do_execsql_test 4.6.4 {
SELECT b, sum(b) OVER (
RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
) FROM t2 ORDER BY b;
} {0 10141 1 10141 1 10141 2 10141 2 10141 2 10141 3 10141
3 10141 4 10141 5 10141 6 10141 7 10141 7 10141 7 10141
8 10141 8 10141 8 10141 9 10141 9 10141 9 10141 10 10141
11 10141 11 10141 12 10141 12 10141 12 10141 13 10141 13 10141
14 10141 15 10141 15 10141 15 10141 16 10141 16 10141 16 10141
17 10141 19 10141 20 10141 21 10141 21 10141 22 10141 22 10141
23 10141 23 10141 23 10141 24 10141 25 10141 26 10141 26 10141
26 10141 27 10141 27 10141 28 10141 29 10141 29 10141 29 10141
30 10141 30 10141 30 10141 31 10141 31 10141 32 10141 33 10141
33 10141 33 10141 33 10141 33 10141 34 10141 34 10141 34 10141
34 10141 35 10141 35 10141 36 10141 36 10141 36 10141 36 10141
37 10141 37 10141 38 10141 38 10141 39 10141 39 10141 39 10141
40 10141 41 10141 41 10141 41 10141 42 10141 43 10141 43 10141
44 10141 44 10141 46 10141 46 10141 47 10141 47 10141 47 10141
47 10141 49 10141 50 10141 51 10141 52 10141 53 10141 54 10141
55 10141 55 10141 56 10141 56 10141 56 10141 57 10141 58 10141
58 10141 58 10141 58 10141 59 10141 59 10141 59 10141 59 10141
60 10141 61 10141 61 10141 62 10141 62 10141 63 10141 64 10141
65 10141 65 10141 65 10141 66 10141 67 10141 68 10141 69 10141
70 10141 72 10141 72 10141 72 10141 73 10141 73 10141 73 10141
74 10141 74 10141 74 10141 74 10141 74 10141 75 10141 75 10141
75 10141 76 10141 77 10141 77 10141 78 10141 78 10141 79 10141
80 10141 80 10141 81 10141 81 10141 81 10141 82 10141 83 10141
84 10141 84 10141 84 10141 84 10141 85 10141 85 10141 85 10141
86 10141 87 10141 87 10141 88 10141 89 10141 89 10141 89 10141
90 10141 90 10141 90 10141 91 10141 91 10141 91 10141 91 10141
91 10141 93 10141 93 10141 93 10141 94 10141 95 10141 95 10141
95 10141 96 10141 96 10141 96 10141 97 10141 97 10141 98 10141
98 10141 99 10141 99 10141 99 10141}
} {0 10141 1 10141 1 10141 2 10141 2 10141 2 10141 3 10141 3 10141 4 10141 5 10141 6 10141 7 10141 7 10141 7 10141 8 10141 8 10141 8 10141 9 10141 9 10141 9 10141 10 10141 11 10141 11 10141 12 10141 12 10141 12 10141 13 10141 13 10141 14 10141 15 10141 15 10141 15 10141 16 10141 16 10141 16 10141 17 10141 19 10141 20 10141 21 10141 21 10141 22 10141 22 10141 23 10141 23 10141 23 10141 24 10141 25 10141 26 10141 26 10141 26 10141 27 10141 27 10141 28 10141 29 10141 29 10141 29 10141 30 10141 30 10141 30 10141 31 10141 31 10141 32 10141 33 10141 33 10141 33 10141 33 10141 33 10141 34 10141 34 10141 34 10141 34 10141 35 10141 35 10141 36 10141 36 10141 36 10141 36 10141 37 10141 37 10141 38 10141 38 10141 39 10141 39 10141 39 10141 40 10141 41 10141 41 10141 41 10141 42 10141 43 10141 43 10141 44 10141 44 10141 46 10141 46 10141 47 10141 47 10141 47 10141 47 10141 49 10141 50 10141 51 10141 52 10141 53 10141 54 10141 55 10141 55 10141 56 10141 56 10141 56 10141 57 10141 58 10141 58 10141 58 10141 58 10141 59 10141 59 10141 59 10141 59 10141 60 10141 61 10141 61 10141 62 10141 62 10141 63 10141 64 10141 65 10141 65 10141 65 10141 66 10141 67 10141 68 10141 69 10141 70 10141 72 10141 72 10141 72 10141 73 10141 73 10141 73 10141 74 10141 74 10141 74 10141 74 10141 74 10141 75 10141 75 10141 75 10141 76 10141 77 10141 77 10141 78 10141 78 10141 79 10141 80 10141 80 10141 81 10141 81 10141 81 10141 82 10141 83 10141 84 10141 84 10141 84 10141 84 10141 85 10141 85 10141 85 10141 86 10141 87 10141 87 10141 88 10141 89 10141 89 10141 89 10141 90 10141 90 10141 90 10141 91 10141 91 10141 91 10141 91 10141 91 10141 93 10141 93 10141 93 10141 94 10141 95 10141 95 10141 95 10141 96 10141 96 10141 96 10141 97 10141 97 10141 98 10141 98 10141 99 10141 99 10141 99 10141}
do_execsql_test 4.7.1 {
SELECT b, sum(b) OVER (
ROWS BETWEEN CURRENT ROW AND CURRENT ROW
) FROM t2 ORDER BY 1, 2;
} {0 0 1 1 1 1 2 2 2 2 2 2 3 3 3 3 4 4 5 5 6 6 7 7 7 7
7 7 8 8 8 8 8 8 9 9 9 9 9 9 10 10 11 11 11 11 12 12
12 12 12 12 13 13 13 13 14 14 15 15 15 15 15 15 16 16
16 16 16 16 17 17 19 19 20 20 21 21 21 21 22 22 22 22
23 23 23 23 23 23 24 24 25 25 26 26 26 26 26 26 27 27
27 27 28 28 29 29 29 29 29 29 30 30 30 30 30 30 31 31
31 31 32 32 33 33 33 33 33 33 33 33 33 33 34 34 34 34
34 34 34 34 35 35 35 35 36 36 36 36 36 36 36 36 37 37
37 37 38 38 38 38 39 39 39 39 39 39 40 40 41 41 41 41
41 41 42 42 43 43 43 43 44 44 44 44 46 46 46 46 47 47
47 47 47 47 47 47 49 49 50 50 51 51 52 52 53 53 54 54
55 55 55 55 56 56 56 56 56 56 57 57 58 58 58 58 58 58
58 58 59 59 59 59 59 59 59 59 60 60 61 61 61 61 62 62
62 62 63 63 64 64 65 65 65 65 65 65 66 66 67 67 68 68
69 69 70 70 72 72 72 72 72 72 73 73 73 73 73 73 74 74
74 74 74 74 74 74 74 74 75 75 75 75 75 75 76 76 77 77
77 77 78 78 78 78 79 79 80 80 80 80 81 81 81 81 81 81
82 82 83 83 84 84 84 84 84 84 84 84 85 85 85 85 85 85
86 86 87 87 87 87 88 88 89 89 89 89 89 89 90 90 90 90
90 90 91 91 91 91 91 91 91 91 91 91 93 93 93 93 93 93
94 94 95 95 95 95 95 95 96 96 96 96 96 96 97 97 97 97
98 98 98 98 99 99 99 99 99 99}
} {0 0 1 1 1 1 2 2 2 2 2 2 3 3 3 3 4 4 5 5 6 6 7 7 7 7 7 7 8 8 8 8 8 8 9 9 9 9 9 9 10 10 11 11 11 11 12 12 12 12 12 12 13 13 13 13 14 14 15 15 15 15 15 15 16 16 16 16 16 16 17 17 19 19 20 20 21 21 21 21 22 22 22 22 23 23 23 23 23 23 24 24 25 25 26 26 26 26 26 26 27 27 27 27 28 28 29 29 29 29 29 29 30 30 30 30 30 30 31 31 31 31 32 32 33 33 33 33 33 33 33 33 33 33 34 34 34 34 34 34 34 34 35 35 35 35 36 36 36 36 36 36 36 36 37 37 37 37 38 38 38 38 39 39 39 39 39 39 40 40 41 41 41 41 41 41 42 42 43 43 43 43 44 44 44 44 46 46 46 46 47 47 47 47 47 47 47 47 49 49 50 50 51 51 52 52 53 53 54 54 55 55 55 55 56 56 56 56 56 56 57 57 58 58 58 58 58 58 58 58 59 59 59 59 59 59 59 59 60 60 61 61 61 61 62 62 62 62 63 63 64 64 65 65 65 65 65 65 66 66 67 67 68 68 69 69 70 70 72 72 72 72 72 72 73 73 73 73 73 73 74 74 74 74 74 74 74 74 74 74 75 75 75 75 75 75 76 76 77 77 77 77 78 78 78 78 79 79 80 80 80 80 81 81 81 81 81 81 82 82 83 83 84 84 84 84 84 84 84 84 85 85 85 85 85 85 86 86 87 87 87 87 88 88 89 89 89 89 89 89 90 90 90 90 90 90 91 91 91 91 91 91 91 91 91 91 93 93 93 93 93 93 94 94 95 95 95 95 95 95 96 96 96 96 96 96 97 97 97 97 98 98 98 98 99 99 99 99 99 99}
do_execsql_test 4.7.2 {
SELECT b, sum(b) OVER (
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) FROM t2 ORDER BY 1, 2;
} {0 0 1 3379 1 5443 2 372 2 4473 2 7074 3 2916 3 9096 4 4049
5 5643 6 1047 7 2205 7 7081 7 10141 8 1553 8 5926 8 6422
9 4883 9 7932 9 8497 10 9544 11 5727 11 6433 12 2825 12 5918
12 8582 13 5190 13 8570 14 8596 15 3189 15 6023 15 8924
16 1942 16 1958 16 3590 17 10134 19 7474 20 5946 21 5464
21 9682 22 3029 22 6140 23 212 23 1926 23 8520 24 2626
25 3331 26 337 26 7539 26 7565 27 1270 27 10035 28 3217
29 1649 29 4355 29 7326 30 4215 30 9400 30 9853 31 5977
31 6008 32 2857 33 370 33 4326 33 8175 33 8909 33 9661
34 6414 34 6516 34 8958 34 9925 35 2151 35 5638 36 3701
36 7818 36 8785 36 8994 37 4597 37 8557 38 735 38 9891 39 842
39 7513 39 9721 40 3475 41 115 41 4874 41 5906 42 4185
43 2754 43 3518 44 7072 44 9765 46 1041 46 1316 47 2198
47 3378 47 7612 47 7923 49 6482 50 9450 51 5778 52 9370
53 4408 54 1448 55 3174 55 6876 56 2913 56 3435 56 3574
57 7223 58 5248 58 7876 58 9318 58 9823 59 697 59 2813
59 6665 59 7455 60 6821 61 2426 61 4944 62 904 62 8658
63 4471 64 8407 65 2116 65 5177 65 5603 66 8142 67 1620
68 803 69 9260 70 7396 72 4833 72 8004 72 8076 73 5017
73 5716 73 6213 74 74 74 189 74 2365 74 5538 74 7297 75 3665
75 6951 75 8343 76 3964 77 1903 77 7028 78 1394 78 4293
79 6292 80 4677 80 7692 81 542 81 4045 81 8488 82 10117
83 10008 84 1826 84 4761 84 9534 84 9628 85 2602 85 2711
85 7166 86 2291 87 4560 87 5865 88 6380 89 461 89 3306
89 3790 90 3119 90 6606 90 7782 91 995 91 2517 91 3007
91 8749 91 8876 93 1742 93 2051 93 8268 94 4143 95 5112
95 6118 95 9191 96 638 96 5344 96 6761 97 1243 97 1545
98 3888 98 5442 99 311 99 1146 99 9093}
} {0 0 1 3379 1 5443 2 372 2 4473 2 7074 3 2916 3 9096 4 4049 5 5643 6 1047 7 2205 7 7081 7 10141 8 1553 8 5926 8 6422 9 4883 9 7932 9 8497 10 9544 11 5727 11 6433 12 2825 12 5918 12 8582 13 5190 13 8570 14 8596 15 3189 15 6023 15 8924 16 1942 16 1958 16 3590 17 10134 19 7474 20 5946 21 5464 21 9682 22 3029 22 6140 23 212 23 1926 23 8520 24 2626 25 3331 26 337 26 7539 26 7565 27 1270 27 10035 28 3217 29 1649 29 4355 29 7326 30 4215 30 9400 30 9853 31 5977 31 6008 32 2857 33 370 33 4326 33 8175 33 8909 33 9661 34 6414 34 6516 34 8958 34 9925 35 2151 35 5638 36 3701 36 7818 36 8785 36 8994 37 4597 37 8557 38 735 38 9891 39 842 39 7513 39 9721 40 3475 41 115 41 4874 41 5906 42 4185 43 2754 43 3518 44 7072 44 9765 46 1041 46 1316 47 2198 47 3378 47 7612 47 7923 49 6482 50 9450 51 5778 52 9370 53 4408 54 1448 55 3174 55 6876 56 2913 56 3435 56 3574 57 7223 58 5248 58 7876 58 9318 58 9823 59 697 59 2813 59 6665 59 7455 60 6821 61 2426 61 4944 62 904 62 8658 63 4471 64 8407 65 2116 65 5177 65 5603 66 8142 67 1620 68 803 69 9260 70 7396 72 4833 72 8004 72 8076 73 5017 73 5716 73 6213 74 74 74 189 74 2365 74 5538 74 7297 75 3665 75 6951 75 8343 76 3964 77 1903 77 7028 78 1394 78 4293 79 6292 80 4677 80 7692 81 542 81 4045 81 8488 82 10117 83 10008 84 1826 84 4761 84 9534 84 9628 85 2602 85 2711 85 7166 86 2291 87 4560 87 5865 88 6380 89 461 89 3306 89 3790 90 3119 90 6606 90 7782 91 995 91 2517 91 3007 91 8749 91 8876 93 1742 93 2051 93 8268 94 4143 95 5112 95 6118 95 9191 96 638 96 5344 96 6761 97 1243 97 1545 98 3888 98 5442 99 311 99 1146 99 9093}
do_execsql_test 4.7.3 {
SELECT b, sum(b) OVER (
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
) FROM t2 ORDER BY 1, 2;
} {0 10141 1 10141 1 10141 2 10141 2 10141 2 10141 3 10141
3 10141 4 10141 5 10141 6 10141 7 10141 7 10141 7 10141
8 10141 8 10141 8 10141 9 10141 9 10141 9 10141 10 10141
11 10141 11 10141 12 10141 12 10141 12 10141 13 10141 13 10141
14 10141 15 10141 15 10141 15 10141 16 10141 16 10141 16 10141
17 10141 19 10141 20 10141 21 10141 21 10141 22 10141 22 10141
23 10141 23 10141 23 10141 24 10141 25 10141 26 10141 26 10141
26 10141 27 10141 27 10141 28 10141 29 10141 29 10141 29 10141
30 10141 30 10141 30 10141 31 10141 31 10141 32 10141 33 10141
33 10141 33 10141 33 10141 33 10141 34 10141 34 10141 34 10141
34 10141 35 10141 35 10141 36 10141 36 10141 36 10141 36 10141
37 10141 37 10141 38 10141 38 10141 39 10141 39 10141 39 10141
40 10141 41 10141 41 10141 41 10141 42 10141 43 10141 43 10141
44 10141 44 10141 46 10141 46 10141 47 10141 47 10141 47 10141
47 10141 49 10141 50 10141 51 10141 52 10141 53 10141 54 10141
55 10141 55 10141 56 10141 56 10141 56 10141 57 10141 58 10141
58 10141 58 10141 58 10141 59 10141 59 10141 59 10141 59 10141
60 10141 61 10141 61 10141 62 10141 62 10141 63 10141 64 10141
65 10141 65 10141 65 10141 66 10141 67 10141 68 10141 69 10141
70 10141 72 10141 72 10141 72 10141 73 10141 73 10141 73 10141
74 10141 74 10141 74 10141 74 10141 74 10141 75 10141 75 10141
75 10141 76 10141 77 10141 77 10141 78 10141 78 10141 79 10141
80 10141 80 10141 81 10141 81 10141 81 10141 82 10141 83 10141
84 10141 84 10141 84 10141 84 10141 85 10141 85 10141 85 10141
86 10141 87 10141 87 10141 88 10141 89 10141 89 10141 89 10141
90 10141 90 10141 90 10141 91 10141 91 10141 91 10141 91 10141
91 10141 93 10141 93 10141 93 10141 94 10141 95 10141 95 10141
95 10141 96 10141 96 10141 96 10141 97 10141 97 10141 98 10141
98 10141 99 10141 99 10141 99 10141}
} {0 10141 1 10141 1 10141 2 10141 2 10141 2 10141 3 10141 3 10141 4 10141 5 10141 6 10141 7 10141 7 10141 7 10141 8 10141 8 10141 8 10141 9 10141 9 10141 9 10141 10 10141 11 10141 11 10141 12 10141 12 10141 12 10141 13 10141 13 10141 14 10141 15 10141 15 10141 15 10141 16 10141 16 10141 16 10141 17 10141 19 10141 20 10141 21 10141 21 10141 22 10141 22 10141 23 10141 23 10141 23 10141 24 10141 25 10141 26 10141 26 10141 26 10141 27 10141 27 10141 28 10141 29 10141 29 10141 29 10141 30 10141 30 10141 30 10141 31 10141 31 10141 32 10141 33 10141 33 10141 33 10141 33 10141 33 10141 34 10141 34 10141 34 10141 34 10141 35 10141 35 10141 36 10141 36 10141 36 10141 36 10141 37 10141 37 10141 38 10141 38 10141 39 10141 39 10141 39 10141 40 10141 41 10141 41 10141 41 10141 42 10141 43 10141 43 10141 44 10141 44 10141 46 10141 46 10141 47 10141 47 10141 47 10141 47 10141 49 10141 50 10141 51 10141 52 10141 53 10141 54 10141 55 10141 55 10141 56 10141 56 10141 56 10141 57 10141 58 10141 58 10141 58 10141 58 10141 59 10141 59 10141 59 10141 59 10141 60 10141 61 10141 61 10141 62 10141 62 10141 63 10141 64 10141 65 10141 65 10141 65 10141 66 10141 67 10141 68 10141 69 10141 70 10141 72 10141 72 10141 72 10141 73 10141 73 10141 73 10141 74 10141 74 10141 74 10141 74 10141 74 10141 75 10141 75 10141 75 10141 76 10141 77 10141 77 10141 78 10141 78 10141 79 10141 80 10141 80 10141 81 10141 81 10141 81 10141 82 10141 83 10141 84 10141 84 10141 84 10141 84 10141 85 10141 85 10141 85 10141 86 10141 87 10141 87 10141 88 10141 89 10141 89 10141 89 10141 90 10141 90 10141 90 10141 91 10141 91 10141 91 10141 91 10141 91 10141 93 10141 93 10141 93 10141 94 10141 95 10141 95 10141 95 10141 96 10141 96 10141 96 10141 97 10141 97 10141 98 10141 98 10141 99 10141 99 10141 99 10141}
do_execsql_test 4.7.4 {
SELECT b, sum(b) OVER (
ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
) FROM t2 ORDER BY 1, 2;
} {0 10141 1 4699 1 6763 2 3069 2 5670 2 9771 3 1048 3 7228
4 6096 5 4503 6 9100 7 7 7 3067 7 7943 8 3727 8 4223 8 8596
9 1653 9 2218 9 5267 10 607 11 3719 11 4425 12 1571 12 4235
12 7328 13 1584 13 4964 14 1559 15 1232 15 4133 15 6967
16 6567 16 8199 16 8215 17 24 19 2686 20 4215 21 480 21 4698
22 4023 22 7134 23 1644 23 8238 23 9952 24 7539 25 6835
26 2602 26 2628 26 9830 27 133 27 8898 28 6952 29 2844
29 5815 29 8521 30 318 30 771 30 5956 31 4164 31 4195 32 7316
33 513 33 1265 33 1999 33 5848 33 9804 34 250 34 1217 34 3659
34 3761 35 4538 35 8025 36 1183 36 1392 36 2359 36 6476
37 1621 37 5581 38 288 38 9444 39 459 39 2667 39 9338 40 6706
41 4276 41 5308 41 10067 42 5998 43 6666 43 7430 44 420
44 3113 46 8871 46 9146 47 2265 47 2576 47 6810 47 7990
49 3708 50 741 51 4414 52 823 53 5786 54 8747 55 3320 55 7022
56 6623 56 6762 56 7284 57 2975 58 376 58 881 58 2323 58 4951
59 2745 59 3535 59 7387 59 9503 60 3380 61 5258 61 7776
62 1545 62 9299 63 5733 64 1798 65 4603 65 5029 65 8090
66 2065 67 8588 68 9406 69 950 70 2815 72 2137 72 2209
72 5380 73 4001 73 4498 73 5197 74 2918 74 4677 74 7850
74 10026 74 10141 75 1873 75 3265 75 6551 76 6253 77 3190
77 8315 78 5926 78 8825 79 3928 80 2529 80 5544 81 1734
81 6177 81 9680 82 106 83 216 84 597 84 691 84 5464 84 8399
85 3060 85 7515 85 7624 86 7936 87 4363 87 5668 88 3849
89 6440 89 6924 89 9769 90 2449 90 3625 90 7112 91 1356
91 1483 91 7225 91 7715 91 9237 93 1966 93 8183 93 8492
94 6092 95 1045 95 4118 95 5124 96 3476 96 4893 96 9599
97 8693 97 8995 98 4797 98 6351 99 1147 99 9094 99 9929}
} {0 10141 1 4699 1 6763 2 3069 2 5670 2 9771 3 1048 3 7228 4 6096 5 4503 6 9100 7 7 7 3067 7 7943 8 3727 8 4223 8 8596 9 1653 9 2218 9 5267 10 607 11 3719 11 4425 12 1571 12 4235 12 7328 13 1584 13 4964 14 1559 15 1232 15 4133 15 6967 16 6567 16 8199 16 8215 17 24 19 2686 20 4215 21 480 21 4698 22 4023 22 7134 23 1644 23 8238 23 9952 24 7539 25 6835 26 2602 26 2628 26 9830 27 133 27 8898 28 6952 29 2844 29 5815 29 8521 30 318 30 771 30 5956 31 4164 31 4195 32 7316 33 513 33 1265 33 1999 33 5848 33 9804 34 250 34 1217 34 3659 34 3761 35 4538 35 8025 36 1183 36 1392 36 2359 36 6476 37 1621 37 5581 38 288 38 9444 39 459 39 2667 39 9338 40 6706 41 4276 41 5308 41 10067 42 5998 43 6666 43 7430 44 420 44 3113 46 8871 46 9146 47 2265 47 2576 47 6810 47 7990 49 3708 50 741 51 4414 52 823 53 5786 54 8747 55 3320 55 7022 56 6623 56 6762 56 7284 57 2975 58 376 58 881 58 2323 58 4951 59 2745 59 3535 59 7387 59 9503 60 3380 61 5258 61 7776 62 1545 62 9299 63 5733 64 1798 65 4603 65 5029 65 8090 66 2065 67 8588 68 9406 69 950 70 2815 72 2137 72 2209 72 5380 73 4001 73 4498 73 5197 74 2918 74 4677 74 7850 74 10026 74 10141 75 1873 75 3265 75 6551 76 6253 77 3190 77 8315 78 5926 78 8825 79 3928 80 2529 80 5544 81 1734 81 6177 81 9680 82 106 83 216 84 597 84 691 84 5464 84 8399 85 3060 85 7515 85 7624 86 7936 87 4363 87 5668 88 3849 89 6440 89 6924 89 9769 90 2449 90 3625 90 7112 91 1356 91 1483 91 7225 91 7715 91 9237 93 1966 93 8183 93 8492 94 6092 95 1045 95 4118 95 5124 96 3476 96 4893 96 9599 97 8693 97 8995 98 4797 98 6351 99 1147 99 9094 99 9929}
do_execsql_test 4.8.1 {
SELECT b, sum(b) OVER (
ORDER BY a
ROWS BETWEEN CURRENT ROW AND CURRENT ROW
) FROM t2 ORDER BY 1, 2;
} {0 0 1 1 1 1 2 2 2 2 2 2 3 3 3 3 4 4 5 5 6 6 7 7 7 7
7 7 8 8 8 8 8 8 9 9 9 9 9 9 10 10 11 11 11 11 12 12
12 12 12 12 13 13 13 13 14 14 15 15 15 15 15 15 16 16
16 16 16 16 17 17 19 19 20 20 21 21 21 21 22 22 22 22
23 23 23 23 23 23 24 24 25 25 26 26 26 26 26 26 27 27
27 27 28 28 29 29 29 29 29 29 30 30 30 30 30 30 31 31
31 31 32 32 33 33 33 33 33 33 33 33 33 33 34 34 34 34
34 34 34 34 35 35 35 35 36 36 36 36 36 36 36 36 37 37
37 37 38 38 38 38 39 39 39 39 39 39 40 40 41 41 41 41
41 41 42 42 43 43 43 43 44 44 44 44 46 46 46 46 47 47
47 47 47 47 47 47 49 49 50 50 51 51 52 52 53 53 54 54
55 55 55 55 56 56 56 56 56 56 57 57 58 58 58 58 58 58
58 58 59 59 59 59 59 59 59 59 60 60 61 61 61 61 62 62
62 62 63 63 64 64 65 65 65 65 65 65 66 66 67 67 68 68
69 69 70 70 72 72 72 72 72 72 73 73 73 73 73 73 74 74
74 74 74 74 74 74 74 74 75 75 75 75 75 75 76 76 77 77
77 77 78 78 78 78 79 79 80 80 80 80 81 81 81 81 81 81
82 82 83 83 84 84 84 84 84 84 84 84 85 85 85 85 85 85
86 86 87 87 87 87 88 88 89 89 89 89 89 89 90 90 90 90
90 90 91 91 91 91 91 91 91 91 91 91 93 93 93 93 93 93
94 94 95 95 95 95 95 95 96 96 96 96 96 96 97 97 97 97
98 98 98 98 99 99 99 99 99 99}
} {0 0 1 1 1 1 2 2 2 2 2 2 3 3 3 3 4 4 5 5 6 6 7 7 7 7 7 7 8 8 8 8 8 8 9 9 9 9 9 9 10 10 11 11 11 11 12 12 12 12 12 12 13 13 13 13 14 14 15 15 15 15 15 15 16 16 16 16 16 16 17 17 19 19 20 20 21 21 21 21 22 22 22 22 23 23 23 23 23 23 24 24 25 25 26 26 26 26 26 26 27 27 27 27 28 28 29 29 29 29 29 29 30 30 30 30 30 30 31 31 31 31 32 32 33 33 33 33 33 33 33 33 33 33 34 34 34 34 34 34 34 34 35 35 35 35 36 36 36 36 36 36 36 36 37 37 37 37 38 38 38 38 39 39 39 39 39 39 40 40 41 41 41 41 41 41 42 42 43 43 43 43 44 44 44 44 46 46 46 46 47 47 47 47 47 47 47 47 49 49 50 50 51 51 52 52 53 53 54 54 55 55 55 55 56 56 56 56 56 56 57 57 58 58 58 58 58 58 58 58 59 59 59 59 59 59 59 59 60 60 61 61 61 61 62 62 62 62 63 63 64 64 65 65 65 65 65 65 66 66 67 67 68 68 69 69 70 70 72 72 72 72 72 72 73 73 73 73 73 73 74 74 74 74 74 74 74 74 74 74 75 75 75 75 75 75 76 76 77 77 77 77 78 78 78 78 79 79 80 80 80 80 81 81 81 81 81 81 82 82 83 83 84 84 84 84 84 84 84 84 85 85 85 85 85 85 86 86 87 87 87 87 88 88 89 89 89 89 89 89 90 90 90 90 90 90 91 91 91 91 91 91 91 91 91 91 93 93 93 93 93 93 94 94 95 95 95 95 95 95 96 96 96 96 96 96 97 97 97 97 98 98 98 98 99 99 99 99 99 99}
do_execsql_test 4.8.2 {
SELECT b, sum(b) OVER (
ORDER BY a
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) FROM t2 ORDER BY 1, 2;
} {0 0 1 3379 1 5443 2 372 2 4473 2 7074 3 2916 3 9096 4 4049
5 5643 6 1047 7 2205 7 7081 7 10141 8 1553 8 5926 8 6422
9 4883 9 7932 9 8497 10 9544 11 5727 11 6433 12 2825 12 5918
12 8582 13 5190 13 8570 14 8596 15 3189 15 6023 15 8924
16 1942 16 1958 16 3590 17 10134 19 7474 20 5946 21 5464
21 9682 22 3029 22 6140 23 212 23 1926 23 8520 24 2626
25 3331 26 337 26 7539 26 7565 27 1270 27 10035 28 3217
29 1649 29 4355 29 7326 30 4215 30 9400 30 9853 31 5977
31 6008 32 2857 33 370 33 4326 33 8175 33 8909 33 9661
34 6414 34 6516 34 8958 34 9925 35 2151 35 5638 36 3701
36 7818 36 8785 36 8994 37 4597 37 8557 38 735 38 9891 39 842
39 7513 39 9721 40 3475 41 115 41 4874 41 5906 42 4185
43 2754 43 3518 44 7072 44 9765 46 1041 46 1316 47 2198
47 3378 47 7612 47 7923 49 6482 50 9450 51 5778 52 9370
53 4408 54 1448 55 3174 55 6876 56 2913 56 3435 56 3574
57 7223 58 5248 58 7876 58 9318 58 9823 59 697 59 2813
59 6665 59 7455 60 6821 61 2426 61 4944 62 904 62 8658
63 4471 64 8407 65 2116 65 5177 65 5603 66 8142 67 1620
68 803 69 9260 70 7396 72 4833 72 8004 72 8076 73 5017
73 5716 73 6213 74 74 74 189 74 2365 74 5538 74 7297 75 3665
75 6951 75 8343 76 3964 77 1903 77 7028 78 1394 78 4293
79 6292 80 4677 80 7692 81 542 81 4045 81 8488 82 10117
83 10008 84 1826 84 4761 84 9534 84 9628 85 2602 85 2711
85 7166 86 2291 87 4560 87 5865 88 6380 89 461 89 3306
89 3790 90 3119 90 6606 90 7782 91 995 91 2517 91 3007
91 8749 91 8876 93 1742 93 2051 93 8268 94 4143 95 5112
95 6118 95 9191 96 638 96 5344 96 6761 97 1243 97 1545
98 3888 98 5442 99 311 99 1146 99 9093}
} {0 0 1 3379 1 5443 2 372 2 4473 2 7074 3 2916 3 9096 4 4049 5 5643 6 1047 7 2205 7 7081 7 10141 8 1553 8 5926 8 6422 9 4883 9 7932 9 8497 10 9544 11 5727 11 6433 12 2825 12 5918 12 8582 13 5190 13 8570 14 8596 15 3189 15 6023 15 8924 16 1942 16 1958 16 3590 17 10134 19 7474 20 5946 21 5464 21 9682 22 3029 22 6140 23 212 23 1926 23 8520 24 2626 25 3331 26 337 26 7539 26 7565 27 1270 27 10035 28 3217 29 1649 29 4355 29 7326 30 4215 30 9400 30 9853 31 5977 31 6008 32 2857 33 370 33 4326 33 8175 33 8909 33 9661 34 6414 34 6516 34 8958 34 9925 35 2151 35 5638 36 3701 36 7818 36 8785 36 8994 37 4597 37 8557 38 735 38 9891 39 842 39 7513 39 9721 40 3475 41 115 41 4874 41 5906 42 4185 43 2754 43 3518 44 7072 44 9765 46 1041 46 1316 47 2198 47 3378 47 7612 47 7923 49 6482 50 9450 51 5778 52 9370 53 4408 54 1448 55 3174 55 6876 56 2913 56 3435 56 3574 57 7223 58 5248 58 7876 58 9318 58 9823 59 697 59 2813 59 6665 59 7455 60 6821 61 2426 61 4944 62 904 62 8658 63 4471 64 8407 65 2116 65 5177 65 5603 66 8142 67 1620 68 803 69 9260 70 7396 72 4833 72 8004 72 8076 73 5017 73 5716 73 6213 74 74 74 189 74 2365 74 5538 74 7297 75 3665 75 6951 75 8343 76 3964 77 1903 77 7028 78 1394 78 4293 79 6292 80 4677 80 7692 81 542 81 4045 81 8488 82 10117 83 10008 84 1826 84 4761 84 9534 84 9628 85 2602 85 2711 85 7166 86 2291 87 4560 87 5865 88 6380 89 461 89 3306 89 3790 90 3119 90 6606 90 7782 91 995 91 2517 91 3007 91 8749 91 8876 93 1742 93 2051 93 8268 94 4143 95 5112 95 6118 95 9191 96 638 96 5344 96 6761 97 1243 97 1545 98 3888 98 5442 99 311 99 1146 99 9093}
do_execsql_test 4.8.3 {
SELECT b, sum(b) OVER (
ORDER BY a
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
) FROM t2 ORDER BY 1, 2;
} {0 10141 1 10141 1 10141 2 10141 2 10141 2 10141 3 10141
3 10141 4 10141 5 10141 6 10141 7 10141 7 10141 7 10141
8 10141 8 10141 8 10141 9 10141 9 10141 9 10141 10 10141
11 10141 11 10141 12 10141 12 10141 12 10141 13 10141 13 10141
14 10141 15 10141 15 10141 15 10141 16 10141 16 10141 16 10141
17 10141 19 10141 20 10141 21 10141 21 10141 22 10141 22 10141
23 10141 23 10141 23 10141 24 10141 25 10141 26 10141 26 10141
26 10141 27 10141 27 10141 28 10141 29 10141 29 10141 29 10141
30 10141 30 10141 30 10141 31 10141 31 10141 32 10141 33 10141
33 10141 33 10141 33 10141 33 10141 34 10141 34 10141 34 10141
34 10141 35 10141 35 10141 36 10141 36 10141 36 10141 36 10141
37 10141 37 10141 38 10141 38 10141 39 10141 39 10141 39 10141
40 10141 41 10141 41 10141 41 10141 42 10141 43 10141 43 10141
44 10141 44 10141 46 10141 46 10141 47 10141 47 10141 47 10141
47 10141 49 10141 50 10141 51 10141 52 10141 53 10141 54 10141
55 10141 55 10141 56 10141 56 10141 56 10141 57 10141 58 10141
58 10141 58 10141 58 10141 59 10141 59 10141 59 10141 59 10141
60 10141 61 10141 61 10141 62 10141 62 10141 63 10141 64 10141
65 10141 65 10141 65 10141 66 10141 67 10141 68 10141 69 10141
70 10141 72 10141 72 10141 72 10141 73 10141 73 10141 73 10141
74 10141 74 10141 74 10141 74 10141 74 10141 75 10141 75 10141
75 10141 76 10141 77 10141 77 10141 78 10141 78 10141 79 10141
80 10141 80 10141 81 10141 81 10141 81 10141 82 10141 83 10141
84 10141 84 10141 84 10141 84 10141 85 10141 85 10141 85 10141
86 10141 87 10141 87 10141 88 10141 89 10141 89 10141 89 10141
90 10141 90 10141 90 10141 91 10141 91 10141 91 10141 91 10141
91 10141 93 10141 93 10141 93 10141 94 10141 95 10141 95 10141
95 10141 96 10141 96 10141 96 10141 97 10141 97 10141 98 10141
98 10141 99 10141 99 10141 99 10141}
} {0 10141 1 10141 1 10141 2 10141 2 10141 2 10141 3 10141 3 10141 4 10141 5 10141 6 10141 7 10141 7 10141 7 10141 8 10141 8 10141 8 10141 9 10141 9 10141 9 10141 10 10141 11 10141 11 10141 12 10141 12 10141 12 10141 13 10141 13 10141 14 10141 15 10141 15 10141 15 10141 16 10141 16 10141 16 10141 17 10141 19 10141 20 10141 21 10141 21 10141 22 10141 22 10141 23 10141 23 10141 23 10141 24 10141 25 10141 26 10141 26 10141 26 10141 27 10141 27 10141 28 10141 29 10141 29 10141 29 10141 30 10141 30 10141 30 10141 31 10141 31 10141 32 10141 33 10141 33 10141 33 10141 33 10141 33 10141 34 10141 34 10141 34 10141 34 10141 35 10141 35 10141 36 10141 36 10141 36 10141 36 10141 37 10141 37 10141 38 10141 38 10141 39 10141 39 10141 39 10141 40 10141 41 10141 41 10141 41 10141 42 10141 43 10141 43 10141 44 10141 44 10141 46 10141 46 10141 47 10141 47 10141 47 10141 47 10141 49 10141 50 10141 51 10141 52 10141 53 10141 54 10141 55 10141 55 10141 56 10141 56 10141 56 10141 57 10141 58 10141 58 10141 58 10141 58 10141 59 10141 59 10141 59 10141 59 10141 60 10141 61 10141 61 10141 62 10141 62 10141 63 10141 64 10141 65 10141 65 10141 65 10141 66 10141 67 10141 68 10141 69 10141 70 10141 72 10141 72 10141 72 10141 73 10141 73 10141 73 10141 74 10141 74 10141 74 10141 74 10141 74 10141 75 10141 75 10141 75 10141 76 10141 77 10141 77 10141 78 10141 78 10141 79 10141 80 10141 80 10141 81 10141 81 10141 81 10141 82 10141 83 10141 84 10141 84 10141 84 10141 84 10141 85 10141 85 10141 85 10141 86 10141 87 10141 87 10141 88 10141 89 10141 89 10141 89 10141 90 10141 90 10141 90 10141 91 10141 91 10141 91 10141 91 10141 91 10141 93 10141 93 10141 93 10141 94 10141 95 10141 95 10141 95 10141 96 10141 96 10141 96 10141 97 10141 97 10141 98 10141 98 10141 99 10141 99 10141 99 10141}
do_execsql_test 4.8.4 {
SELECT b, sum(b) OVER (
ORDER BY a
ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
) FROM t2 ORDER BY 1, 2;
} {0 10141 1 4699 1 6763 2 3069 2 5670 2 9771 3 1048 3 7228
4 6096 5 4503 6 9100 7 7 7 3067 7 7943 8 3727 8 4223 8 8596
9 1653 9 2218 9 5267 10 607 11 3719 11 4425 12 1571 12 4235
12 7328 13 1584 13 4964 14 1559 15 1232 15 4133 15 6967
16 6567 16 8199 16 8215 17 24 19 2686 20 4215 21 480 21 4698
22 4023 22 7134 23 1644 23 8238 23 9952 24 7539 25 6835
26 2602 26 2628 26 9830 27 133 27 8898 28 6952 29 2844
29 5815 29 8521 30 318 30 771 30 5956 31 4164 31 4195 32 7316
33 513 33 1265 33 1999 33 5848 33 9804 34 250 34 1217 34 3659
34 3761 35 4538 35 8025 36 1183 36 1392 36 2359 36 6476
37 1621 37 5581 38 288 38 9444 39 459 39 2667 39 9338 40 6706
41 4276 41 5308 41 10067 42 5998 43 6666 43 7430 44 420
44 3113 46 8871 46 9146 47 2265 47 2576 47 6810 47 7990
49 3708 50 741 51 4414 52 823 53 5786 54 8747 55 3320 55 7022
56 6623 56 6762 56 7284 57 2975 58 376 58 881 58 2323 58 4951
59 2745 59 3535 59 7387 59 9503 60 3380 61 5258 61 7776
62 1545 62 9299 63 5733 64 1798 65 4603 65 5029 65 8090
66 2065 67 8588 68 9406 69 950 70 2815 72 2137 72 2209
72 5380 73 4001 73 4498 73 5197 74 2918 74 4677 74 7850
74 10026 74 10141 75 1873 75 3265 75 6551 76 6253 77 3190
77 8315 78 5926 78 8825 79 3928 80 2529 80 5544 81 1734
81 6177 81 9680 82 106 83 216 84 597 84 691 84 5464 84 8399
85 3060 85 7515 85 7624 86 7936 87 4363 87 5668 88 3849
89 6440 89 6924 89 9769 90 2449 90 3625 90 7112 91 1356
91 1483 91 7225 91 7715 91 9237 93 1966 93 8183 93 8492
94 6092 95 1045 95 4118 95 5124 96 3476 96 4893 96 9599
97 8693 97 8995 98 4797 98 6351 99 1147 99 9094 99 9929}
do_test 4.9 {
set myres {}
foreach r [db eval {SELECT
rank() OVER win AS rank,
cume_dist() OVER win AS cume_dist FROM t1
WINDOW win AS (ORDER BY 1);}] {
lappend myres [format %.4f [set r]]
}
set res2 {1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000}
set i 0
foreach r [set myres] r2 [set res2] {
if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} {
error "list element [set i] does not match: got=[set r] expected=[set r2]"
}
incr i
}
set {} {}
} {}
} {0 10141 1 4699 1 6763 2 3069 2 5670 2 9771 3 1048 3 7228 4 6096 5 4503 6 9100 7 7 7 3067 7 7943 8 3727 8 4223 8 8596 9 1653 9 2218 9 5267 10 607 11 3719 11 4425 12 1571 12 4235 12 7328 13 1584 13 4964 14 1559 15 1232 15 4133 15 6967 16 6567 16 8199 16 8215 17 24 19 2686 20 4215 21 480 21 4698 22 4023 22 7134 23 1644 23 8238 23 9952 24 7539 25 6835 26 2602 26 2628 26 9830 27 133 27 8898 28 6952 29 2844 29 5815 29 8521 30 318 30 771 30 5956 31 4164 31 4195 32 7316 33 513 33 1265 33 1999 33 5848 33 9804 34 250 34 1217 34 3659 34 3761 35 4538 35 8025 36 1183 36 1392 36 2359 36 6476 37 1621 37 5581 38 288 38 9444 39 459 39 2667 39 9338 40 6706 41 4276 41 5308 41 10067 42 5998 43 6666 43 7430 44 420 44 3113 46 8871 46 9146 47 2265 47 2576 47 6810 47 7990 49 3708 50 741 51 4414 52 823 53 5786 54 8747 55 3320 55 7022 56 6623 56 6762 56 7284 57 2975 58 376 58 881 58 2323 58 4951 59 2745 59 3535 59 7387 59 9503 60 3380 61 5258 61 7776 62 1545 62 9299 63 5733 64 1798 65 4603 65 5029 65 8090 66 2065 67 8588 68 9406 69 950 70 2815 72 2137 72 2209 72 5380 73 4001 73 4498 73 5197 74 2918 74 4677 74 7850 74 10026 74 10141 75 1873 75 3265 75 6551 76 6253 77 3190 77 8315 78 5926 78 8825 79 3928 80 2529 80 5544 81 1734 81 6177 81 9680 82 106 83 216 84 597 84 691 84 5464 84 8399 85 3060 85 7515 85 7624 86 7936 87 4363 87 5668 88 3849 89 6440 89 6924 89 9769 90 2449 90 3625 90 7112 91 1356 91 1483 91 7225 91 7715 91 9237 93 1966 93 8183 93 8492 94 6092 95 1045 95 4118 95 5124 96 3476 96 4893 96 9599 97 8693 97 8995 98 4797 98 6351 99 1147 99 9094 99 9929}
finish_test
-36
View File
@@ -130,40 +130,4 @@ do_eqp_test 3.2.2 {
`--SEARCH TABLE w1 USING INTEGER PRIMARY KEY (rowid=?)
}
do_execsql_test 4.0 {
WITH t5(t5col1) AS (
SELECT (
WITH t3(t3col1) AS (
WITH t2 AS (
WITH t1 AS (SELECT 1 AS c1 GROUP BY 1)
SELECT a.c1 FROM t1 AS a, t1 AS b
WHERE anoncol1 = 1
)
SELECT (SELECT 1 FROM t2) FROM t2
)
SELECT t3col1 FROM t3 WHERE t3col1
) FROM (SELECT 1 AS anoncol1)
)
SELECT t5col1, t5col1 FROM t5
} {1 1}
do_execsql_test 4.1 {
SELECT EXISTS (
WITH RECURSIVE Table0 AS (
WITH RECURSIVE Table0(Col0) AS (SELECT ALL 1 )
SELECT ALL (
WITH RECURSIVE Table0 AS (
WITH RECURSIVE Table0 AS (
WITH RECURSIVE Table0 AS (SELECT DISTINCT 1 GROUP BY 1 )
SELECT DISTINCT * FROM Table0 NATURAL INNER JOIN Table0
WHERE Col0 = 1
)
SELECT ALL (SELECT DISTINCT * FROM Table0) FROM Table0 WHERE Col0 = 1
)
SELECT ALL * FROM Table0 NATURAL INNER JOIN Table0
) FROM Table0 )
SELECT DISTINCT * FROM Table0 NATURAL INNER JOIN Table0
);
} {1}
finish_test
-8
View File
@@ -391,13 +391,5 @@ do_execsql_test 10.6 {
SELECT * FROM t1;
} {b a 3 b b 4}
# 2019-04-29 ticket https://www.sqlite.org/src/info/3182d3879020ef3
do_execsql_test 11.1 {
CREATE TABLE t11(a TEXT PRIMARY KEY, b INT) WITHOUT ROWID;
CREATE INDEX t11a ON t11(a COLLATE NOCASE);
INSERT INTO t11(a,b) VALUES ('A',1),('a',2);
PRAGMA integrity_check;
SELECT a FROM t11 ORDER BY a COLLATE binary;
} {ok A a}
finish_test
+38 -38
View File
@@ -483,22 +483,22 @@ void Configtable_clear(int(*)(struct config *));
/* Allocate a new parser action */
static struct action *Action_new(void){
static struct action *actionfreelist = 0;
static struct action *freelist = 0;
struct action *newaction;
if( actionfreelist==0 ){
if( freelist==0 ){
int i;
int amt = 100;
actionfreelist = (struct action *)calloc(amt, sizeof(struct action));
if( actionfreelist==0 ){
freelist = (struct action *)calloc(amt, sizeof(struct action));
if( freelist==0 ){
fprintf(stderr,"Unable to allocate memory for a new parser action.");
exit(1);
}
for(i=0; i<amt-1; i++) actionfreelist[i].next = &actionfreelist[i+1];
actionfreelist[amt-1].next = 0;
for(i=0; i<amt-1; i++) freelist[i].next = &freelist[i+1];
freelist[amt-1].next = 0;
}
newaction = actionfreelist;
actionfreelist = actionfreelist->next;
newaction = freelist;
freelist = freelist->next;
return newaction;
}
@@ -1907,7 +1907,7 @@ static char *msort(
return ep;
}
/************************ From the file "option.c" **************************/
static char **g_argv;
static char **argv;
static struct s_options *op;
static FILE *errstream;
@@ -1920,14 +1920,14 @@ static FILE *errstream;
static void errline(int n, int k, FILE *err)
{
int spcnt, i;
if( g_argv[0] ) fprintf(err,"%s",g_argv[0]);
spcnt = lemonStrlen(g_argv[0]) + 1;
for(i=1; i<n && g_argv[i]; i++){
fprintf(err," %s",g_argv[i]);
spcnt += lemonStrlen(g_argv[i])+1;
if( argv[0] ) fprintf(err,"%s",argv[0]);
spcnt = lemonStrlen(argv[0]) + 1;
for(i=1; i<n && argv[i]; i++){
fprintf(err," %s",argv[i]);
spcnt += lemonStrlen(argv[i])+1;
}
spcnt += k;
for(; g_argv[i]; i++) fprintf(err," %s",g_argv[i]);
for(; argv[i]; i++) fprintf(err," %s",argv[i]);
if( spcnt<20 ){
fprintf(err,"\n%*s^-- here\n",spcnt,"");
}else{
@@ -1943,13 +1943,13 @@ static int argindex(int n)
{
int i;
int dashdash = 0;
if( g_argv!=0 && *g_argv!=0 ){
for(i=1; g_argv[i]; i++){
if( dashdash || !ISOPT(g_argv[i]) ){
if( argv!=0 && *argv!=0 ){
for(i=1; argv[i]; i++){
if( dashdash || !ISOPT(argv[i]) ){
if( n==0 ) return i;
n--;
}
if( strcmp(g_argv[i],"--")==0 ) dashdash = 1;
if( strcmp(argv[i],"--")==0 ) dashdash = 1;
}
}
return -1;
@@ -1966,9 +1966,9 @@ static int handleflags(int i, FILE *err)
int errcnt = 0;
int j;
for(j=0; op[j].label; j++){
if( strncmp(&g_argv[i][1],op[j].label,lemonStrlen(op[j].label))==0 ) break;
if( strncmp(&argv[i][1],op[j].label,lemonStrlen(op[j].label))==0 ) break;
}
v = g_argv[i][0]=='-' ? 1 : 0;
v = argv[i][0]=='-' ? 1 : 0;
if( op[j].label==0 ){
if( err ){
fprintf(err,"%sundefined option.\n",emsg);
@@ -1982,7 +1982,7 @@ static int handleflags(int i, FILE *err)
}else if( op[j].type==OPT_FFLAG ){
(*(void(*)(int))(op[j].arg))(v);
}else if( op[j].type==OPT_FSTR ){
(*(void(*)(char *))(op[j].arg))(&g_argv[i][2]);
(*(void(*)(char *))(op[j].arg))(&argv[i][2]);
}else{
if( err ){
fprintf(err,"%smissing argument on switch.\n",emsg);
@@ -2004,11 +2004,11 @@ static int handleswitch(int i, FILE *err)
char *cp;
int j;
int errcnt = 0;
cp = strchr(g_argv[i],'=');
cp = strchr(argv[i],'=');
assert( cp!=0 );
*cp = 0;
for(j=0; op[j].label; j++){
if( strcmp(g_argv[i],op[j].label)==0 ) break;
if( strcmp(argv[i],op[j].label)==0 ) break;
}
*cp = '=';
if( op[j].label==0 ){
@@ -2035,7 +2035,7 @@ static int handleswitch(int i, FILE *err)
if( err ){
fprintf(err,
"%sillegal character in floating-point argument.\n",emsg);
errline(i,(int)((char*)end-(char*)g_argv[i]),err);
errline(i,(int)((char*)end-(char*)argv[i]),err);
}
errcnt++;
}
@@ -2046,7 +2046,7 @@ static int handleswitch(int i, FILE *err)
if( *end ){
if( err ){
fprintf(err,"%sillegal character in integer argument.\n",emsg);
errline(i,(int)((char*)end-(char*)g_argv[i]),err);
errline(i,(int)((char*)end-(char*)argv[i]),err);
}
errcnt++;
}
@@ -2086,15 +2086,15 @@ static int handleswitch(int i, FILE *err)
int OptInit(char **a, struct s_options *o, FILE *err)
{
int errcnt = 0;
g_argv = a;
argv = a;
op = o;
errstream = err;
if( g_argv && *g_argv && op ){
if( argv && *argv && op ){
int i;
for(i=1; g_argv[i]; i++){
if( g_argv[i][0]=='+' || g_argv[i][0]=='-' ){
for(i=1; argv[i]; i++){
if( argv[i][0]=='+' || argv[i][0]=='-' ){
errcnt += handleflags(i,err);
}else if( strchr(g_argv[i],'=') ){
}else if( strchr(argv[i],'=') ){
errcnt += handleswitch(i,err);
}
}
@@ -2111,10 +2111,10 @@ int OptNArgs(void){
int cnt = 0;
int dashdash = 0;
int i;
if( g_argv!=0 && g_argv[0]!=0 ){
for(i=1; g_argv[i]; i++){
if( dashdash || !ISOPT(g_argv[i]) ) cnt++;
if( strcmp(g_argv[i],"--")==0 ) dashdash = 1;
if( argv!=0 && argv[0]!=0 ){
for(i=1; argv[i]; i++){
if( dashdash || !ISOPT(argv[i]) ) cnt++;
if( strcmp(argv[i],"--")==0 ) dashdash = 1;
}
}
return cnt;
@@ -2124,7 +2124,7 @@ char *OptArg(int n)
{
int i;
i = argindex(n);
return i>=0 ? g_argv[i] : 0;
return i>=0 ? argv[i] : 0;
}
void OptErr(int n)
@@ -2728,7 +2728,7 @@ to follow the previous rule.");
case WAITING_FOR_CLASS_ID:
if( !ISLOWER(x[0]) ){
ErrorMsg(psp->filename, psp->tokenlineno,
"%%token_class must be followed by an identifier: %s", x);
"%%token_class must be followed by an identifier: ", x);
psp->errorcnt++;
psp->state = RESYNC_AFTER_DECL_ERROR;
}else if( Symbol_find(x) ){
@@ -3848,7 +3848,7 @@ PRIVATE int translate_code(struct lemon *lemp, struct rule *rp){
ErrorMsg(lemp->filename,rp->ruleline,
"%s(%s) has the same label as the LHS but is not the left-most "
"symbol on the RHS.",
rp->rhs[i]->name, rp->rhsalias[i]);
rp->rhs[i]->name, rp->rhsalias);
lemp->errorcnt++;
}
for(j=0; j<i; j++){
-1
View File
@@ -301,7 +301,6 @@ set pragma_def {
NAME: case_sensitive_like
FLAG: NoColumns
IF: !defined(SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA)
NAME: integrity_check
FLAG: NeedSchema Result0 Result1
+1 -7
View File
@@ -40,21 +40,16 @@ proc omit_redundant_typedefs {line} {
}
return $line
}
set iLine 0
while {1} {
set lx [omit_redundant_typedefs [gets $in]]
if {[eof $in]} break;
incr iLine
if {[regexp {^INCLUDE } $lx]} {
set cfile [lindex $lx 1]
puts $out "/************************* Begin $cfile ******************/"
# puts $out "#line 1 \"$cfile\""
set in2 [open $topdir/src/$cfile rb]
while {![eof $in2]} {
set lx [omit_redundant_typedefs [gets $in2]]
if {[regexp {^#include "sqlite} $lx]} {
set lx "/* $lx */"
}
if {[regexp {^#include "sqlite} $lx]} continue
if {[regexp {^# *include "test_windirent.h"} $lx]} {
set lx "/* $lx */"
}
@@ -63,7 +58,6 @@ while {1} {
}
close $in2
puts $out "/************************* End $cfile ********************/"
# puts $out "#line [expr $iLine+1] \"shell.c.in\""
continue
}
puts $out $lx