Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 818d5bcf28 | |||
| 8941cb4817 | |||
| 1082e86417 | |||
| 7267c510ac | |||
| f53ed4e68e | |||
| 7210e4c5b4 |
+2
-82
@@ -595,86 +595,6 @@ oPutbUtf8(const char *cBuf, int nAccept){
|
||||
# endif
|
||||
}
|
||||
|
||||
/*
|
||||
** Flush the given output stream. Return non-zero for success, else 0.
|
||||
*/
|
||||
#if !defined(SQLITE_CIO_NO_FLUSH) && !defined(SQLITE_CIO_NO_SETMODE)
|
||||
SQLITE_INTERNAL_LINKAGE int
|
||||
fFlushBuffer(FILE *pfOut){
|
||||
# if CIO_WIN_WC_XLATE && !defined(SHELL_OMIT_FIO_DUPE)
|
||||
return FlushFileBuffers(handleOfFile(pfOut))? 1 : 0;
|
||||
# else
|
||||
return fflush(pfOut);
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CIO_WIN_WC_XLATE \
|
||||
&& !defined(SHELL_OMIT_FIO_DUPE) \
|
||||
&& defined(SQLITE_USE_ONLY_WIN32)
|
||||
static struct FileAltIds {
|
||||
int fd;
|
||||
HANDLE fh;
|
||||
} altIdsOfFile(FILE *pf){
|
||||
struct FileAltIds rv = { _fileno(pf) };
|
||||
union { intptr_t osfh; HANDLE fh; } fid = {
|
||||
(rv.fd>=0)? _get_osfhandle(rv.fd) : (intptr_t)INVALID_HANDLE_VALUE
|
||||
};
|
||||
rv.fh = fid.fh;
|
||||
return rv;
|
||||
}
|
||||
|
||||
SQLITE_INTERNAL_LINKAGE size_t
|
||||
cfWrite(const void *buf, size_t osz, size_t ocnt, FILE *pf){
|
||||
size_t rv = 0;
|
||||
struct FileAltIds fai = altIdsOfFile(pf);
|
||||
int fmode = _setmode(fai.fd, _O_BINARY);
|
||||
_setmode(fai.fd, fmode);
|
||||
while( rv < ocnt ){
|
||||
size_t nbo = osz;
|
||||
while( nbo > 0 ){
|
||||
DWORD dwno = (nbo>(1L<<24))? 1L<<24 : (DWORD)nbo;
|
||||
BOOL wrc = TRUE;
|
||||
BOOL genCR = (fmode & _O_TEXT)!=0;
|
||||
if( genCR ){
|
||||
const char *pnl = (const char*)memchr(buf, '\n', nbo);
|
||||
if( pnl ) nbo = pnl - (const char*)buf;
|
||||
else genCR = 0;
|
||||
}
|
||||
if( dwno>0 ) wrc = WriteFile(fai.fh, buf, dwno, 0,0);
|
||||
if( genCR && wrc ){
|
||||
wrc = WriteFile(fai.fh, "\r\n", 2, 0,0);
|
||||
++dwno; /* Skip over the LF */
|
||||
}
|
||||
if( !wrc ) return rv;
|
||||
buf = (const char*)buf + dwno;
|
||||
nbo += dwno;
|
||||
}
|
||||
++rv;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
SQLITE_INTERNAL_LINKAGE char *
|
||||
cfGets(char *cBuf, int n, FILE *pf){
|
||||
int nci = 0;
|
||||
struct FileAltIds fai = altIdsOfFile(pf);
|
||||
int fmode = _setmode(fai.fd, _O_BINARY);
|
||||
BOOL eatCR = (fmode & _O_TEXT)!=0;
|
||||
_setmode(fai.fd, fmode);
|
||||
while( nci < n-1 ){
|
||||
DWORD nr;
|
||||
if( !ReadFile(fai.fh, cBuf+nci, 1, &nr, 0) || nr==0 ) break;
|
||||
if( nr>0 && (!eatCR || cBuf[nci]!='\r') ) nci += nr;
|
||||
}
|
||||
if( nci < n ) cBuf[nci] = 0;
|
||||
return (nci>0)? cBuf : 0;
|
||||
}
|
||||
# else
|
||||
# define cfWrite(b,os,no,f) fwrite(b,os,no,f)
|
||||
# define cfGets(b,n,f) fgets(b,n,f)
|
||||
# endif
|
||||
|
||||
# ifdef CONSIO_EPUTB
|
||||
SQLITE_INTERNAL_LINKAGE int
|
||||
ePutbUtf8(const char *cBuf, int nAccept){
|
||||
@@ -686,7 +606,7 @@ ePutbUtf8(const char *cBuf, int nAccept){
|
||||
return conZstrEmit(ppst, cBuf, nAccept);
|
||||
}else {
|
||||
# endif
|
||||
return (int)cfWrite(cBuf, 1, nAccept, pfErr);
|
||||
return (int)fwrite(cBuf, 1, nAccept, pfErr);
|
||||
# if CIO_WIN_WC_XLATE
|
||||
}
|
||||
# endif
|
||||
@@ -752,7 +672,7 @@ SQLITE_INTERNAL_LINKAGE char* fGetsUtf8(char *cBuf, int ncMax, FILE *pfIn){
|
||||
# endif
|
||||
}else{
|
||||
# endif
|
||||
return cfGets(cBuf, ncMax, pfIn);
|
||||
return fgets(cBuf, ncMax, pfIn);
|
||||
# if CIO_WIN_WC_XLATE
|
||||
}
|
||||
# endif
|
||||
|
||||
+4
-11
@@ -176,19 +176,12 @@ SQLITE_INTERNAL_LINKAGE int
|
||||
ePutbUtf8(const char *cBuf, int nAccept);
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Flush the given output stream. Return non-zero for success, else 0.
|
||||
*/
|
||||
#if !defined(SQLITE_CIO_NO_FLUSH) && !defined(SQLITE_CIO_NO_SETMODE)
|
||||
SQLITE_INTERNAL_LINKAGE int
|
||||
fFlushBuffer(FILE *pfOut);
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Collect input like fgets(...) with special provisions for input
|
||||
** from the console on such platforms as require same. Newline
|
||||
** translation may be done as set by set{Binary,Text}Mode().
|
||||
** As a convenience, pfIn==NULL is treated as stdin.
|
||||
** from the console on platforms that require same. Defers to the
|
||||
** C library fgets() when input is not from the console. Newline
|
||||
** translation may be done as set by set{Binary,Text}Mode(). As a
|
||||
** convenience, pfIn==NULL is treated as stdin.
|
||||
*/
|
||||
SQLITE_INTERNAL_LINKAGE char* fGetsUtf8(char *cBuf, int ncMax, FILE *pfIn);
|
||||
/* Like fGetsUtf8 except stream is always the designated input. */
|
||||
|
||||
+6
-7
@@ -493,19 +493,18 @@ struct Fts5ExtensionApi {
|
||||
**
|
||||
** FTS5_TOKENIZER
|
||||
**
|
||||
** There is also an fts5_tokenizer object. This is an older, deprecated,
|
||||
** version of fts5_tokenizer_v2. It is similar except that:
|
||||
** There is also an fts5_tokenizer object. This is an older version of
|
||||
** fts5_tokenizer_v2. It is similar except that:
|
||||
**
|
||||
** <ul>
|
||||
** <li> There is no "iVersion" field, and
|
||||
** <li> The xTokenize() method does not take a locale argument.
|
||||
** </ul>
|
||||
**
|
||||
** Legacy fts5_tokenizer tokenizers must be registered using the
|
||||
** legacy xCreateTokenizer() function, instead of xCreateTokenizer_v2().
|
||||
**
|
||||
** Tokenizer implementations registered using either API may be retrieved
|
||||
** using both xFindTokenizer() and xFindTokenizer_v2().
|
||||
** fts5_tokenizer tokenizers should be registered with the xCreateTokenizer()
|
||||
** function, instead of xCreateTokenizer_v2(). Tokenizers implementations
|
||||
** registered using either API may be retrieved using both xFindTokenizer()
|
||||
** and xFindTokenizer_v2().
|
||||
**
|
||||
** SYNONYM SUPPORT
|
||||
**
|
||||
|
||||
+12
-13
@@ -3267,9 +3267,7 @@ static int fts5NewTokenizerModule(
|
||||
*/
|
||||
typedef struct Fts5VtoVTokenizer Fts5VtoVTokenizer;
|
||||
struct Fts5VtoVTokenizer {
|
||||
int bV2Native; /* True if v2 native tokenizer */
|
||||
fts5_tokenizer x1; /* Tokenizer functions */
|
||||
fts5_tokenizer_v2 x2; /* V2 tokenizer functions */
|
||||
Fts5TokenizerModule *pMod;
|
||||
Fts5Tokenizer *pReal;
|
||||
};
|
||||
|
||||
@@ -3289,9 +3287,7 @@ static int fts5VtoVCreate(
|
||||
|
||||
pNew = (Fts5VtoVTokenizer*)sqlite3Fts5MallocZero(&rc, sizeof(*pNew));
|
||||
if( rc==SQLITE_OK ){
|
||||
pNew->x1 = pMod->x1;
|
||||
pNew->x2 = pMod->x2;
|
||||
pNew->bV2Native = pMod->bV2Native;
|
||||
pNew->pMod = pMod;
|
||||
if( pMod->bV2Native ){
|
||||
rc = pMod->x2.xCreate(pMod->pUserData, azArg, nArg, &pNew->pReal);
|
||||
}else{
|
||||
@@ -3313,10 +3309,11 @@ static int fts5VtoVCreate(
|
||||
static void fts5VtoVDelete(Fts5Tokenizer *pTok){
|
||||
Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok;
|
||||
if( p ){
|
||||
if( p->bV2Native ){
|
||||
p->x2.xDelete(p->pReal);
|
||||
Fts5TokenizerModule *pMod = p->pMod;
|
||||
if( pMod->bV2Native ){
|
||||
pMod->x2.xDelete(p->pReal);
|
||||
}else{
|
||||
p->x1.xDelete(p->pReal);
|
||||
pMod->x1.xDelete(p->pReal);
|
||||
}
|
||||
sqlite3_free(p);
|
||||
}
|
||||
@@ -3334,8 +3331,9 @@ static int fts5V1toV2Tokenize(
|
||||
int (*xToken)(void*, int, const char*, int, int, int)
|
||||
){
|
||||
Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok;
|
||||
assert( p->bV2Native );
|
||||
return p->x2.xTokenize(p->pReal, pCtx, flags, pText, nText, 0, 0, xToken);
|
||||
Fts5TokenizerModule *pMod = p->pMod;
|
||||
assert( pMod->bV2Native );
|
||||
return pMod->x2.xTokenize(p->pReal, pCtx, flags, pText, nText, 0, 0, xToken);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3350,9 +3348,10 @@ static int fts5V2toV1Tokenize(
|
||||
int (*xToken)(void*, int, const char*, int, int, int)
|
||||
){
|
||||
Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok;
|
||||
assert( p->bV2Native==0 );
|
||||
Fts5TokenizerModule *pMod = p->pMod;
|
||||
assert( pMod->bV2Native==0 );
|
||||
UNUSED_PARAM2(pLocale,nLocale);
|
||||
return p->x1.xTokenize(p->pReal, pCtx, flags, pText, nText, xToken);
|
||||
return pMod->x1.xTokenize(p->pReal, pCtx, flags, pText, nText, xToken);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+15
-96
@@ -96,14 +96,14 @@ static int SQLITE_TCLAPI f5tDbAndApi(
|
||||
|
||||
rc = sqlite3_prepare_v2(db, "SELECT fts5(?1)", -1, &pStmt, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_AppendResult(interp, "error: ", sqlite3_errmsg(db), (char*)0);
|
||||
Tcl_AppendResult(interp, "error: ", sqlite3_errmsg(db), 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
sqlite3_bind_pointer(pStmt, 1, (void*)&pApi, "fts5_api_ptr", 0);
|
||||
sqlite3_step(pStmt);
|
||||
|
||||
if( sqlite3_finalize(pStmt)!=SQLITE_OK ){
|
||||
Tcl_AppendResult(interp, "error: ", sqlite3_errmsg(db), (char*)0);
|
||||
Tcl_AppendResult(interp, "error: ", sqlite3_errmsg(db), 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -392,7 +392,7 @@ static int SQLITE_TCLAPI xF5tApi(
|
||||
CASE(12, "xSetAuxdata") {
|
||||
F5tAuxData *pData = (F5tAuxData*)sqlite3_malloc(sizeof(F5tAuxData));
|
||||
if( pData==0 ){
|
||||
Tcl_AppendResult(interp, "out of memory", (char*)0);
|
||||
Tcl_AppendResult(interp, "out of memory", 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
pData->pObj = objv[2];
|
||||
@@ -452,7 +452,7 @@ static int SQLITE_TCLAPI xF5tApi(
|
||||
|
||||
rc = p->pApi->xPhraseFirst(p->pFts, iPhrase, &iter, &iCol, &iOff);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_AppendResult(interp, sqlite3ErrName(rc), (char*)0);
|
||||
Tcl_AppendResult(interp, sqlite3ErrName(rc), 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
for( ;iCol>=0; p->pApi->xPhraseNext(p->pFts, &iter, &iCol, &iOff) ){
|
||||
@@ -683,7 +683,7 @@ static int SQLITE_TCLAPI f5tCreateFunction(
|
||||
pApi, zName, (void*)pCtx, xF5tFunction, xF5tDestroy
|
||||
);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_AppendResult(interp, "error: ", sqlite3_errmsg(db), (char*)0);
|
||||
Tcl_AppendResult(interp, "error: ", sqlite3_errmsg(db), 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -750,7 +750,7 @@ static int SQLITE_TCLAPI f5tTokenize(
|
||||
if( objc==5 ){
|
||||
char *zOpt = Tcl_GetString(objv[1]);
|
||||
if( strcmp("-subst", zOpt) ){
|
||||
Tcl_AppendResult(interp, "unrecognized option: ", zOpt, (char*)0);
|
||||
Tcl_AppendResult(interp, "unrecognized option: ", zOpt, 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
@@ -759,7 +759,7 @@ static int SQLITE_TCLAPI f5tTokenize(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( nArg==0 ){
|
||||
Tcl_AppendResult(interp, "no such tokenizer: ", (char*)0);
|
||||
Tcl_AppendResult(interp, "no such tokenizer: ", 0);
|
||||
Tcl_Free((void*)azArg);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -767,13 +767,13 @@ static int SQLITE_TCLAPI f5tTokenize(
|
||||
|
||||
rc = pApi->xFindTokenizer(pApi, azArg[0], &pUserdata, &tokenizer);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_AppendResult(interp, "no such tokenizer: ", azArg[0], (char*)0);
|
||||
Tcl_AppendResult(interp, "no such tokenizer: ", azArg[0], 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
rc = tokenizer.xCreate(pUserdata, &azArg[1], (int)(nArg-1), &pTok);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_AppendResult(interp, "error in tokenizer.xCreate()", (char*)0);
|
||||
Tcl_AppendResult(interp, "error in tokenizer.xCreate()", 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -787,7 +787,7 @@ static int SQLITE_TCLAPI f5tTokenize(
|
||||
);
|
||||
tokenizer.xDelete(pTok);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_AppendResult(interp, "error in tokenizer.xTokenize()", (char*)0);
|
||||
Tcl_AppendResult(interp, "error in tokenizer.xTokenize()", 0);
|
||||
Tcl_DecrRefCount(pRet);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -1049,7 +1049,7 @@ static int SQLITE_TCLAPI f5tTokenizerLocale(
|
||||
|
||||
if( p->xToken==0 ){
|
||||
Tcl_AppendResult(interp,
|
||||
"sqlite3_fts5_locale may only be used by tokenizer callback", (char*)0
|
||||
"sqlite3_fts5_locale may only be used by tokenizer callback", 0
|
||||
);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -1098,7 +1098,7 @@ static int SQLITE_TCLAPI f5tTokenizerReturn(
|
||||
|
||||
if( p->xToken==0 ){
|
||||
Tcl_AppendResult(interp,
|
||||
"sqlite3_fts5_token may only be used by tokenizer callback", (char*)0
|
||||
"sqlite3_fts5_token may only be used by tokenizer callback", 0
|
||||
);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -1250,7 +1250,7 @@ static int SQLITE_TCLAPI f5tCreateTokenizer(
|
||||
Tcl_AppendResult(interp, (
|
||||
bV2 ? "error in fts5_api.xCreateTokenizer_v2()"
|
||||
: "error in fts5_api.xCreateTokenizer()"
|
||||
), (char*)0);
|
||||
), 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -1540,92 +1540,12 @@ static int SQLITE_TCLAPI f5tRegisterOriginText(
|
||||
|
||||
Tcl_ResetResult(interp);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_AppendResult(interp, "error: ", sqlite3_errmsg(db), (void*)0);
|
||||
Tcl_AppendResult(interp, "error: ", sqlite3_errmsg(db), 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** This function is used to DROP an fts5 table. It works even if the data
|
||||
** structures fts5 stores within the database are corrupt, which sometimes
|
||||
** prevents a straight "DROP TABLE" command from succeeding.
|
||||
**
|
||||
** The first parameter is the database handle to use for the DROP TABLE
|
||||
** operation. The second is the name of the database to drop the fts5 table
|
||||
** from (i.e. "main", "temp" or the name of an attached database). The
|
||||
** third parameter is the name of the fts5 table to drop.
|
||||
**
|
||||
** SQLITE_OK is returned if the table is successfully dropped. Or, if an
|
||||
** error occurs, an SQLite error code.
|
||||
*/
|
||||
static int sqlite3_fts5_drop_corrupt_table(
|
||||
sqlite3 *db, /* Database handle */
|
||||
const char *zDb, /* Database name ("main", "temp" etc.) */
|
||||
const char *zTab /* Name of fts5 table to drop */
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
int bDef = 0;
|
||||
|
||||
rc = sqlite3_db_config(db, SQLITE_DBCONFIG_DEFENSIVE, -1, &bDef);
|
||||
if( rc==SQLITE_OK ){
|
||||
char *zScript = sqlite3_mprintf(
|
||||
"DELETE FROM %Q.'%q_data';"
|
||||
"DELETE FROM %Q.'%q_config';"
|
||||
"INSERT INTO %Q.'%q_data' VALUES(10, X'0000000000');"
|
||||
"INSERT INTO %Q.'%q_config' VALUES('version', 4);"
|
||||
"DROP TABLE %Q.'%q';",
|
||||
zDb, zTab, zDb, zTab, zDb, zTab, zDb, zTab, zDb, zTab
|
||||
);
|
||||
|
||||
if( zScript==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
if( bDef ) sqlite3_db_config(db, SQLITE_DBCONFIG_DEFENSIVE, 0, 0);
|
||||
rc = sqlite3_exec(db, zScript, 0, 0, 0);
|
||||
if( bDef ) sqlite3_db_config(db, SQLITE_DBCONFIG_DEFENSIVE, 1, 0);
|
||||
sqlite3_free(zScript);
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** sqlite3_fts5_drop_corrupt_table DB DATABASE TABLE
|
||||
**
|
||||
** Description...
|
||||
*/
|
||||
static int SQLITE_TCLAPI f5tDropCorruptTable(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
sqlite3 *db = 0;
|
||||
const char *zDb = 0;
|
||||
const char *zTab = 0;
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
if( objc!=4 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "DB DATABASE TABLE");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( f5tDbPointer(interp, objv[1], &db) ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
zDb = Tcl_GetString(objv[2]);
|
||||
zTab = Tcl_GetString(objv[3]);
|
||||
|
||||
rc = sqlite3_fts5_drop_corrupt_table(db, zDb, zTab);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_AppendResult(interp, "error: ", sqlite3_errmsg(db), (void*)0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Entry point.
|
||||
*/
|
||||
@@ -1644,8 +1564,7 @@ int Fts5tcl_Init(Tcl_Interp *interp){
|
||||
{ "sqlite3_fts5_token_hash", f5tTokenHash, 0 },
|
||||
{ "sqlite3_fts5_register_matchinfo", f5tRegisterMatchinfo, 0 },
|
||||
{ "sqlite3_fts5_register_fts5tokenize", f5tRegisterTok, 0 },
|
||||
{ "sqlite3_fts5_register_origintext",f5tRegisterOriginText, 0 },
|
||||
{ "sqlite3_fts5_drop_corrupt_table", f5tDropCorruptTable, 0 }
|
||||
{ "sqlite3_fts5_register_origintext",f5tRegisterOriginText, 0 }
|
||||
};
|
||||
int i;
|
||||
F5tTokenizerContext *pContext;
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
# 2024 Aug 28
|
||||
#
|
||||
# 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]] fts5_common.tcl]
|
||||
set testprefix fts5corrupt8
|
||||
|
||||
# If SQLITE_ENABLE_FTS5 is not defined, omit this file.
|
||||
ifcapable !fts5 {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(x);
|
||||
}
|
||||
|
||||
do_execsql_test 1.1 {
|
||||
UPDATE t1_data SET block='hello world' WHERE id=10
|
||||
}
|
||||
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
|
||||
do_catchsql_test 1.2 {
|
||||
SELECT * FROM t1
|
||||
} {1 {vtable constructor failed: t1}}
|
||||
do_catchsql_test 1.3 {
|
||||
DROP TABLE t1
|
||||
} {1 {vtable constructor failed: t1}}
|
||||
do_test 1.4 {
|
||||
sqlite3_db_config db DEFENSIVE 0
|
||||
} {0}
|
||||
do_test 1.5 {
|
||||
sqlite3_fts5_drop_corrupt_table db main t1
|
||||
} {}
|
||||
do_test 1.6 {
|
||||
sqlite3_db_config db DEFENSIVE -1
|
||||
} {0}
|
||||
do_execsql_test 1.7 {
|
||||
SELECT * FROM sqlite_schema
|
||||
}
|
||||
|
||||
do_execsql_test 2.0 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(x);
|
||||
}
|
||||
do_execsql_test 2.1 {
|
||||
UPDATE t1_config SET v=555 WHERE k='version'
|
||||
}
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
do_catchsql_test 2.2 {
|
||||
SELECT * FROM t1
|
||||
} {1 {invalid fts5 file format (found 555, expected 4 or 5) - run 'rebuild'}}
|
||||
do_catchsql_test 2.3 {
|
||||
DROP TABLE t1
|
||||
} {1 {invalid fts5 file format (found 555, expected 4 or 5) - run 'rebuild'}}
|
||||
do_test 2.4 {
|
||||
sqlite3_fts5_drop_corrupt_table db main t1
|
||||
} {}
|
||||
do_execsql_test 2.5 {
|
||||
SELECT * FROM sqlite_schema
|
||||
}
|
||||
|
||||
do_execsql_test 3.0 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(x);
|
||||
}
|
||||
do_execsql_test 3.1 {
|
||||
DELETE FROM t1_config;
|
||||
}
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
do_catchsql_test 3.2 {
|
||||
SELECT * FROM t1
|
||||
} {1 {invalid fts5 file format (found 0, expected 4 or 5) - run 'rebuild'}}
|
||||
do_catchsql_test 3.3 {
|
||||
DROP TABLE t1
|
||||
} {1 {invalid fts5 file format (found 0, expected 4 or 5) - run 'rebuild'}}
|
||||
|
||||
|
||||
do_test 3.4 {
|
||||
sqlite3_db_config db DEFENSIVE 1
|
||||
} {1}
|
||||
do_test 3.5 {
|
||||
sqlite3_fts5_drop_corrupt_table db main t1
|
||||
} {}
|
||||
do_test 3.6 {
|
||||
sqlite3_db_config db DEFENSIVE -1
|
||||
} {1}
|
||||
do_execsql_test 3.7 {
|
||||
SELECT * FROM sqlite_schema
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
C Fix\stypo\sin\sthe\sprevious\scheck-in.\s\sEnsure\sthat\s--status\sheader\slines\sdo\snot\noverflow\sand\swrap.
|
||||
D 2024-08-27T19:48:19.164
|
||||
C Remove\sredundant\s#ifdef\saccidentally\sinserted\sinto\smkkeywordhash.c
|
||||
D 2024-08-26T14:20:20.876
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@@ -53,8 +53,8 @@ F ext/README.md fd5f78013b0a2bc6f0067afb19e6ad040e89a10179b4f6f03eee58fac5f169bd
|
||||
F ext/async/README.txt e12275968f6fde133a80e04387d0e839b0c51f91
|
||||
F ext/async/sqlite3async.c 6f247666b495c477628dd19364d279c78ea48cd90c72d9f9b98ad1aff3294f94
|
||||
F ext/async/sqlite3async.h 46b47c79357b97ad85d20d2795942c0020dc20c532114a49808287f04aa5309a
|
||||
F ext/consio/console_io.c 6e02dea912a49f55785b0027fe77960aafee6c236307c23f82ec86a69f1a2001 x
|
||||
F ext/consio/console_io.h b5ebe34aa15b357621ebbea3d3f2e2b24750d4280b5802516409e23947fd9ee5
|
||||
F ext/consio/console_io.c b4885dfea71ed583315de8f0792a29d5fc7c7460b4a26c0aebe5cda5da8b38f8 x
|
||||
F ext/consio/console_io.h 0548b83d7c4b7270ad544a67f2bb90cebc519637fa39b1838df4744cf0d87646
|
||||
F ext/expert/README.md b321c2762bb93c18ea102d5a5f7753a4b8bac646cb392b3b437f633caf2020c3
|
||||
F ext/expert/expert.c d548d603a4cc9e61f446cc179c120c6713511c413f82a4a32b1e1e69d3f086a4
|
||||
F ext/expert/expert1.test 661f873fd451127edf822ef0d520088faa319135f6a15bd10be6801ac284ac9b
|
||||
@@ -92,7 +92,7 @@ F ext/fts3/unicode/UnicodeData.txt cd07314edb62d49fde34debdaf92fa2aa69011e7
|
||||
F ext/fts3/unicode/mkunicode.tcl 63db9624ccf70d4887836c320eda93ab552f21008f3be7ede551eac3ead62baa
|
||||
F ext/fts3/unicode/parseunicode.tcl a981bd6466d12dd17967515801c3ff23f74a281be1a03cf1e6f52a6959fc77eb
|
||||
F ext/fts5/extract_api_docs.tcl 009cf59c77afa86d137b0cca3e3b1a5efbe2264faa2df233f9a7aa8563926d15
|
||||
F ext/fts5/fts5.h efaaac0df3d3bc740383044c144b582f47921aafa21d7b10eb98f42c24c740b0
|
||||
F ext/fts5/fts5.h c72759fd15179934f10b71ae51ee999e8558f696335e4ec2d049243b764354ee
|
||||
F ext/fts5/fts5Int.h 26a71a09cefa4ef6b4516b204ed48da3e1380970a19b3482eea7c5d805655360
|
||||
F ext/fts5/fts5_aux.c 65a0468dd177d6093aa9ae1622e6d86b0136b8d267c62c0ad6493ad1e9a3d759
|
||||
F ext/fts5/fts5_buffer.c 0eec58bff585f1a44ea9147eae5da2447292080ea435957f7488c70673cb6f09
|
||||
@@ -100,9 +100,9 @@ F ext/fts5/fts5_config.c 353d2a0d12678cae6ab5b9ce54aed8dac0825667b69248b5a4ed81c
|
||||
F ext/fts5/fts5_expr.c 9a56f53700d1860f0ee2f373c2b9074eaf2a7aa0637d0e27a6476de26a3fee33
|
||||
F ext/fts5/fts5_hash.c adda4272be401566a6e0ba1acbe70ee5cb97fce944bc2e04dc707152a0ec91b1
|
||||
F ext/fts5/fts5_index.c eb9a0dda3bc6ef969a6be8d2746af56856e67251810ddba08622b45be8477abe
|
||||
F ext/fts5/fts5_main.c 0dbe241c50b62e24a229a176d66d580e359b3c32cb0970c39bb6dd6b86e125d5
|
||||
F ext/fts5/fts5_main.c 3d8b778f65fe5be218f6a8e4019048f092c0c09621b035ce3e8804093036b578
|
||||
F ext/fts5/fts5_storage.c 9a9b880be12901f1962ae2a5a7e1b74348b3099a1e728764e419f75d98e3e612
|
||||
F ext/fts5/fts5_tcl.c 4db9258a7882c5eac0da4433042132aaf15b87dd1e1636c7a6ca203abd2c8bfe
|
||||
F ext/fts5/fts5_tcl.c 1dcf08028141c40a32634bdcf2d5601622ce4edc48f82ac4ce0cbe0a92a6961d
|
||||
F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee
|
||||
F ext/fts5/fts5_test_tok.c 3cb0a9b508b30d17ef025ccddd26ae3dc8ddffbe76c057616e59a9aa85d36f3b
|
||||
F ext/fts5/fts5_tokenize.c ae9c4fa93174ef06ffc138bd4280a1c37f7e13624d3d2706aad4b80573f23c41
|
||||
@@ -153,7 +153,6 @@ F ext/fts5/test/fts5corrupt4.test dc08d19f5b8943e95a7778a7d8da592042504faf18dd93
|
||||
F ext/fts5/test/fts5corrupt5.test 11b47126f5772cc37b67e3e8b2ed05895c4d07c05338bc07e4eea225bfe32c76
|
||||
F ext/fts5/test/fts5corrupt6.test 2d72db743db7b5d9c9a6d0cfef24d799ed1aa5e8192b66c40e871a37ed9eed06
|
||||
F ext/fts5/test/fts5corrupt7.test 4e830875c33b9ea3c4cf1ba71e692b63893cbb4faae8c69b1071889dc26e211c
|
||||
F ext/fts5/test/fts5corrupt8.test f78b6de9e4327e16ba7a7958b1ce576f9b5d886b4b97690f90b7f3cf654da458
|
||||
F ext/fts5/test/fts5delete.test 619295b20dbc1d840b403ee07c878f52378849c3c02e44f2ee143b3e978a0aa7
|
||||
F ext/fts5/test/fts5detail.test 54015e9c43ec4ba542cfb93268abdf280e0300f350efd08ee411284b03595cc4
|
||||
F ext/fts5/test/fts5determin.test 1b77879b2ae818b5b71c859e534ee334dac088b7cf3ff3bf76a2c82b1c788d11
|
||||
@@ -754,7 +753,7 @@ F src/os_win.c 6ff43bac175bd9ed79e7c0f96840b139f2f51d01689a638fd05128becf94908a
|
||||
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
|
||||
F src/pager.c b08600ebf0db90b6d1e9b8b6577c6fa3877cbe1a100bd0b2899e4c6e9adad4b3
|
||||
F src/pager.h 4b1140d691860de0be1347474c51fee07d5420bd7f802d38cbab8ea4ab9f538a
|
||||
F src/parse.y 5972b7d00af4c8d96fdad781af1ea1d5d51fc3b907ad61bda60e49503274e5ed
|
||||
F src/parse.y f4c8ded81b05059c284bc9512aaa07f6ecd29add585e35d53d72a67894b6e4d7
|
||||
F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484
|
||||
F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5
|
||||
F src/pcache1.c 49516ad7718a3626f28f710fa7448ef1fce3c07fd169acbb4817341950264319
|
||||
@@ -766,7 +765,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
|
||||
F src/resolve.c 2c127880c0634962837f16f2f48a295e514357af959330cc038de73015d5b5e8
|
||||
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
|
||||
F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe
|
||||
F src/shell.c.in 40de636c1d90fb8a9ca7f49dc8f50d930f1b60736e73aca5eb37c4c7d0e47f9d
|
||||
F src/shell.c.in 5a05e1a1d187ab916afe9a628d7e9b20b5997273b595bd748db324814e0ccca9
|
||||
F src/sqlite.h.in f07bff4225a1244efd604a0ffef81ed69f29d3dbaed7e22f906f26229ba3ca9e
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54
|
||||
@@ -828,14 +827,14 @@ F src/test_windirent.h da2e5b73c32d09905fbdd00f27cd802212a32a58ead882736fe4f5eb7
|
||||
F src/test_window.c 6d80e11fba89a1796525e6f0048ff0c7789aa2c6b0b11c80827dc1437bd8ea72
|
||||
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
||||
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
|
||||
F src/tokenize.c 3f703cacdab728d7741e5a6ac242006d74fe1c2754d4f03ed889d7253259bd68
|
||||
F src/tokenize.c 6fac7f14dd021fecfdd8be93c27937804c4b665d2da9e667a10e4b5f04c6e085
|
||||
F src/treeview.c 88aa39b754f5ef7214385c1bbbdd2f3dc20efafeed0cf590e8d1199b9c6e44aa
|
||||
F src/trigger.c 0bb986a5b96047fd597c6aac28588853df56064e576e6b81ba777ef2ccaac461
|
||||
F src/update.c 0e01aa6a3edf9ec112b33eb714b9016a81241497b1fb7c3e74332f4f71756508
|
||||
F src/upsert.c 215328c3f91623c520ec8672c44323553f12caeb4f01b1090ebdca99fdf7b4f1
|
||||
F src/utf.c f23165685a67b4caf8ec08fb274cb3f319103decfb2a980b7cfd55d18dfa855e
|
||||
F src/util.c 5d1a0134cf4240648d1c6bb5cc8efaca0ea2b5d5c840985aec7e947271f04375
|
||||
F src/vacuum.c b763b6457bd058d2072ef9364832351fd8d11e8abf70cbb349657360f7d55c40
|
||||
F src/vacuum.c 604fcdaebe76f3497c855afcbf91b8fa5046b32de3045bab89cc008d68e40104
|
||||
F src/vdbe.c be5f58bc29f60252e041a618eae59e8d57d460ba136c5403cf0abf955560c457
|
||||
F src/vdbe.h c2549a215898a390de6669cfa32adba56f0d7e17ba5a7f7b14506d6fd5f0c36a
|
||||
F src/vdbeInt.h 949669dfd8a41550d27dcb905b494f2ccde9a2e6c1b0b04daa1227e2e74c2b2c
|
||||
@@ -1714,8 +1713,8 @@ F test/temptable2.test 76821347810ecc88203e6ef0dd6897b6036ac788e9dd3e6b04fd4d163
|
||||
F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637
|
||||
F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc
|
||||
F test/tester.tcl 2c203a2dd664298f239f0ec3ce22fbc65b5f021c1e09edbae8452af8a694e052
|
||||
F test/testrunner.tcl c27905c57f54450411be922037d227fee65b08928d09715d784380a398b0e758
|
||||
F test/testrunner_data.tcl 6a0facfbff26f2f8573ebaeb209426bbb59809d5c0f6925f983bd030ab5248cd
|
||||
F test/testrunner.tcl 5d02deeba7a53baeadae6aa7641d90aac58fdfa3a7bcac85cfcfd752b1aab87c
|
||||
F test/testrunner_data.tcl c5ae2b1f9a99210b0600d002fb3af1fee350997cee9416551e83b93501360ebf
|
||||
F test/thread001.test a0985c117eab62c0c65526e9fa5d1360dd1cac5b03bde223902763274ce21899
|
||||
F test/thread002.test c24c83408e35ba5a952a3638b7ac03ccdf1ce4409289c54a050ac4c5f1de7502
|
||||
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
|
||||
@@ -2132,7 +2131,7 @@ F tool/merge-test.tcl de76b62f2de2a92d4c1ca4f976bce0aea6899e0229e250479b229b2a19
|
||||
F tool/mkautoconfamal.sh cbdcf993fa83dccbef7fb77b39cdeb31ef9f77d9d88c9e343b58d35ca3898a6a
|
||||
F tool/mkccode.tcl 86463e68ce9c15d3041610fedd285ce32a5cf7a58fc88b3202b8b76837650dbe x
|
||||
F tool/mkctimec.tcl 060e9785e9503bf51f8b1b11b542bdeef90fd0ceb0738154f6762acec0c61e5f x
|
||||
F tool/mkkeywordhash.c b9faa0ae7e14e4dbbcd951cddd786bf46b8a65bb07b129ba8c0cfade723aaffd
|
||||
F tool/mkkeywordhash.c 8a0a0401a6e0f01ca6e02f58b294a813d067554474875f4fe0222c2b8b0d6ed3
|
||||
F tool/mkmsvcmin.tcl d76c45efda1cce2d4005bcea7b8a22bb752e3256009f331120fb4fecb14ebb7a
|
||||
F tool/mkopcodec.tcl 33d20791e191df43209b77d37f0ff0904620b28465cca6990cf8d60da61a07ef
|
||||
F tool/mkopcodeh.tcl 2b4e6967a670ef21bf53a164964c35c6163277d002a4c6f56fa231d68c88d023
|
||||
@@ -2211,8 +2210,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 7c195f132cb48ee44124eb4af3532937493429f7c45f6ac611f7a9b128799ad7
|
||||
R 15868716c90b102057036239341d8066
|
||||
P 16d32676e2e98a7710787de16850c328e7519e893f81ed56f6155a8fa9cbc3a4
|
||||
R a100ff1c9bda3fc624920cd66e34ae7c
|
||||
U drh
|
||||
Z fde036223228b7af985cf94952c295a1
|
||||
Z 58c98d8befdb125e16f0435abf5b1a98
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
2eaea67495fd9961b7145d829789889bf1d8fa7a834d40d1be43e7c74c233bc2
|
||||
b08f3b74495e125f92c8968472fc8028c73d8df5400195df3081e3d8df8bd985
|
||||
|
||||
+231
-40
@@ -268,7 +268,7 @@ columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,A,Y);}
|
||||
GENERATED ALWAYS
|
||||
%endif
|
||||
MATERIALIZED
|
||||
REINDEX RENAME CTIME_KW IF
|
||||
REINDEX RENAME CTIME_KW IF AGGREGATE
|
||||
.
|
||||
%wildcard ANY.
|
||||
|
||||
@@ -295,7 +295,8 @@ columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,A,Y);}
|
||||
%left CONCAT PTR.
|
||||
%left COLLATE.
|
||||
%right BITNOT.
|
||||
%nonassoc ON.
|
||||
%nonassoc ON FROM.
|
||||
%nonassoc JOIN_KW JOIN.
|
||||
|
||||
// An IDENTIFIER can be a generic identifier, or one of several
|
||||
// keywords. Any non-standard keyword can also be an identifier.
|
||||
@@ -624,6 +625,233 @@ oneselect(A) ::= SELECT distinct(D) selcollist(W) from(X) where_opt(Y)
|
||||
}
|
||||
%endif
|
||||
|
||||
%ifndef SQLITE_OMIT_SUBQUERY
|
||||
%include {
|
||||
SQLITE_NOINLINE SrcList *sqlite3SrcListAppendSubFrom(
|
||||
Parse *pParse, /* Parsing context */
|
||||
SrcList *pFrom, /* LHS of the FROM clause */
|
||||
SrcList *pSubFrom, /* New parenthesized sub-FROM to append */
|
||||
Token *pAs, /* AS-Name of the sub-FROM */
|
||||
OnOrUsing *pOnUsing /* ON or USING clause associated with the join */
|
||||
){
|
||||
if( pFrom==0 && pAs->n==0 && pOnUsing->pOn==0 && pOnUsing->pUsing==0 ){
|
||||
pFrom = pSubFrom;
|
||||
}else if( ALWAYS(pSubFrom!=0) && pSubFrom->nSrc==1 ){
|
||||
pFrom = sqlite3SrcListAppendFromTerm(pParse,pFrom,0,0,pAs,0,pOnUsing);
|
||||
if( pFrom ){
|
||||
SrcItem *pNew = &pFrom->a[pFrom->nSrc-1];
|
||||
SrcItem *pOld = pSubFrom->a;
|
||||
assert( pOld->fg.fixedSchema==0 );
|
||||
pNew->zName = pOld->zName;
|
||||
assert( pOld->fg.fixedSchema==0 );
|
||||
if( pOld->fg.isSubquery ){
|
||||
pNew->fg.isSubquery = 1;
|
||||
pNew->u4.pSubq = pOld->u4.pSubq;
|
||||
pOld->u4.pSubq = 0;
|
||||
pOld->fg.isSubquery = 0;
|
||||
assert( pNew->u4.pSubq!=0 && pNew->u4.pSubq->pSelect!=0 );
|
||||
if( (pNew->u4.pSubq->pSelect->selFlags & SF_NestedFrom)!=0 ){
|
||||
pNew->fg.isNestedFrom = 1;
|
||||
}
|
||||
}else{
|
||||
pNew->u4.zDatabase = pOld->u4.zDatabase;
|
||||
pOld->u4.zDatabase = 0;
|
||||
}
|
||||
if( pOld->fg.isTabFunc ){
|
||||
pNew->u1.pFuncArg = pOld->u1.pFuncArg;
|
||||
pOld->u1.pFuncArg = 0;
|
||||
pOld->fg.isTabFunc = 0;
|
||||
pNew->fg.isTabFunc = 1;
|
||||
}
|
||||
pOld->zName = 0;
|
||||
}
|
||||
sqlite3SrcListDelete(pParse->db, pSubFrom);
|
||||
}else{
|
||||
Select *pSubquery;
|
||||
sqlite3SrcListShiftJoinType(pParse,pSubFrom);
|
||||
pSubquery = sqlite3SelectNew(pParse,0,pSubFrom,0,0,0,0,SF_NestedFrom,0);
|
||||
pFrom = sqlite3SrcListAppendFromTerm(pParse,pFrom,0,0,pAs,pSubquery,pOnUsing);
|
||||
}
|
||||
return pFrom;
|
||||
}
|
||||
}
|
||||
%endif SQLITE_OMIT_SUBQUERY
|
||||
|
||||
%ifndef SQLITE_OMIT_FROM_FIRST
|
||||
%include {
|
||||
/* The Pipe object represents a pipe under construction. It is a transient
|
||||
** object found only on the LALR(1) parser stack. */
|
||||
typedef struct Pipe Pipe;
|
||||
struct Pipe {
|
||||
SrcList *pFrom; /* The FROM clause */
|
||||
ExprList *pProj; /* The projection - list of columns to return */
|
||||
ExprList *pOrderBy; /* The ORDER BY clause */
|
||||
ExprList *pGroupBy; /* The GROUP BY clause */
|
||||
Expr *pLimit; /* The LIMIT or LIMIT/OFFSET clause */
|
||||
Expr *pWhere; /* The WHERE clause */
|
||||
Expr *pHaving; /* The HAVING clause */
|
||||
int selFlags; /* SF_DISTINCT or SF_ALL or 0 */
|
||||
u8 bSeenAgg; /* True if AGGREGATE has been seen */
|
||||
u8 bNeedPush; /* PipePush needed before adding terms to pProj */
|
||||
Token sAs; /* Value of a pending AS clause */
|
||||
};
|
||||
|
||||
/* Delete a pipe object */
|
||||
void sqlite3PipeDelete(sqlite3 *db, Pipe *p){
|
||||
sqlite3SrcListDelete(db, p->pFrom);
|
||||
sqlite3ExprListDelete(db, p->pProj);
|
||||
sqlite3ExprListDelete(db, p->pOrderBy);
|
||||
sqlite3ExprListDelete(db, p->pGroupBy);
|
||||
sqlite3ExprDelete(db, p->pLimit);
|
||||
sqlite3ExprDelete(db, p->pWhere);
|
||||
sqlite3ExprDelete(db, p->pHaving);
|
||||
sqlite3DbFree(db, p);
|
||||
}
|
||||
|
||||
/* Generate a Select from the current content of a Pipe. Reset the Pipe
|
||||
** to be empty, except do not remove the AS token if there is one and do
|
||||
** not delete the Pipe.
|
||||
*/
|
||||
Select *sqlite3SelectFromPipe(Parse *pParse, Pipe *p){
|
||||
Token sAs = p->sAs;
|
||||
Select *pSel = sqlite3SelectNew(pParse, p->pProj, p->pFrom, p->pWhere,
|
||||
p->pGroupBy, p->pHaving, p->pOrderBy,
|
||||
p->selFlags, p->pLimit);
|
||||
memset(p, 0, sizeof(*p));
|
||||
p->sAs = sAs;
|
||||
return pSel;
|
||||
}
|
||||
|
||||
/* Take the current content of the pipe and make it "FROM <subquery>" pipe.
|
||||
*/
|
||||
void sqlite3PipePush(Parse *pParse, Pipe *pPipe, int jointype){
|
||||
Select *pSel = sqlite3SelectFromPipe(pParse, pPipe);
|
||||
SrcList *pFrom = pPipe->pFrom;
|
||||
if( pFrom ) pFrom->a[pFrom->nSrc-1].fg.jointype = jointype;
|
||||
pPipe->pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&pPipe->sAs,pSel,0);
|
||||
pPipe->sAs.z = 0;
|
||||
}
|
||||
|
||||
}
|
||||
%type pipeline {Pipe*}
|
||||
%destructor pipeline {sqlite3PipeDelete(pParse->db,$$);}
|
||||
|
||||
oneselect(A) ::= pipeline(X). {
|
||||
Pipe *pPipe = X;
|
||||
Select *pSel = sqlite3SelectFromPipe(pParse,pPipe);
|
||||
sqlite3DbFree(pParse->db, pPipe);
|
||||
A = pSel; /*A-overwrites-X */
|
||||
}
|
||||
pipeline(A) ::= FROM seltablist(X). {
|
||||
Pipe *pPipe = sqlite3DbMallocZero(pParse->db, sizeof(*pPipe));
|
||||
A = pPipe;
|
||||
if( pPipe ){
|
||||
pPipe->pFrom = X;
|
||||
}else{
|
||||
sqlite3SrcListDelete(pParse->db, X);
|
||||
}
|
||||
}
|
||||
pipeline(A) ::= pipeline(A) pipe pipejoinop(J) nm(Y) dbnm(D) as(Z) on_using(N). {
|
||||
Pipe *p = A;
|
||||
if( p->bNeedPush ) sqlite3PipePush(pParse, p, J);
|
||||
p->pFrom = sqlite3SrcListAppendFromTerm(pParse, p->pFrom, &Y, &D, &Z, 0, &N);
|
||||
}
|
||||
pipeline(A) ::= pipeline(A) pipe
|
||||
pipejoinop(J) nm(Y) dbnm(D) LP exprlist(E) RP as(Z) on_using(N). {
|
||||
Pipe *p = A;
|
||||
if( p->bNeedPush ) sqlite3PipePush(pParse, p, J);
|
||||
p->pFrom = sqlite3SrcListAppendFromTerm(pParse, p->pFrom, &Y, &D, &Z, 0, &N);
|
||||
sqlite3SrcListFuncArgs(pParse, p->pFrom, E);
|
||||
}
|
||||
pipeline(A) ::= pipeline(A) pipe pipejoinop(J) LP select(S) RP as(Z) on_using(N). {
|
||||
Pipe *p = A;
|
||||
if( p->bNeedPush ) sqlite3PipePush(pParse, p, J);
|
||||
p->pFrom = sqlite3SrcListAppendFromTerm(pParse,p->pFrom,0,0,&Z,S,&N);
|
||||
}
|
||||
pipeline(A) ::= pipeline(A) pipe pipejoinop(J) LP seltablist(F) RP as(Z) on_using(N).{
|
||||
Pipe *p = A;
|
||||
if( p->bNeedPush ) sqlite3PipePush(pParse, p, J);
|
||||
p->pFrom = sqlite3SrcListAppendSubFrom(pParse,p->pFrom,F,&Z,&N);
|
||||
}
|
||||
pipeline(A) ::= pipeline(A) pipe WHERE expr(W). {
|
||||
Pipe *p = A;
|
||||
if( p->bSeenAgg ){
|
||||
p->pHaving = sqlite3ExprAnd(pParse, A->pHaving, W);
|
||||
}else{
|
||||
p->pWhere = sqlite3ExprAnd(pParse, A->pWhere, W);
|
||||
}
|
||||
p->bNeedPush = 1;
|
||||
}
|
||||
pipeline(A) ::= pipeline(A) pipe HAVING expr(W). {
|
||||
Pipe *p = A;
|
||||
p->pHaving = sqlite3ExprAnd(pParse, A->pHaving, W);
|
||||
p->bNeedPush = 1;
|
||||
}
|
||||
pipeline(A) ::= pipeline(A) pipe AGGREGATE selcollist(W) groupby_opt(G). {
|
||||
Pipe *p = A;
|
||||
ExprList *pProj = W;
|
||||
ExprList *pGroupby = G;
|
||||
if( p->pProj ) sqlite3PipePush(pParse, p, 0);
|
||||
if( pGroupby ){
|
||||
int i;
|
||||
for(i=0; i<pGroupby->nExpr; i++){
|
||||
pProj = sqlite3ExprListAppend(pParse, pProj,
|
||||
sqlite3ExprDup(pParse->db, pGroupby->a[i].pExpr, 0));
|
||||
}
|
||||
p->pGroupBy = pGroupby;
|
||||
}
|
||||
p->pProj = pProj;
|
||||
p->bSeenAgg = 1;
|
||||
p->bNeedPush = 1;
|
||||
}
|
||||
pipeline(A) ::= pipeline(A) pipe SELECT distinct(D) selcollist(W). {
|
||||
Pipe *p = A;
|
||||
if( p->pProj ) sqlite3PipePush(pParse, p, 0);
|
||||
p->pProj = W;
|
||||
p->selFlags = D;
|
||||
p->bNeedPush = 1;
|
||||
}
|
||||
pipeline(A) ::= pipeline(A) pipe ORDER BY sortlist(X). {
|
||||
Pipe *p = A;
|
||||
if( p->pOrderBy || p->pLimit ) sqlite3PipePush(pParse, p, 0);
|
||||
p->pOrderBy = X;
|
||||
p->bNeedPush = 1;
|
||||
}
|
||||
pipeline(A) ::= pipeline(A) pipe LIMIT expr(X). {
|
||||
Pipe *p = A;
|
||||
Expr *pLimit = sqlite3PExpr(pParse,TK_LIMIT,X,0);
|
||||
if( pLimit ){
|
||||
sqlite3ExprDelete(pParse->db, p->pLimit);
|
||||
p->pLimit = pLimit;
|
||||
}
|
||||
p->bNeedPush = 1;
|
||||
}
|
||||
pipeline(A) ::= pipeline(A) pipe LIMIT expr(X) OFFSET expr(Y). {
|
||||
Pipe *p = A;
|
||||
Expr *pLimit = sqlite3PExpr(pParse,TK_LIMIT,X,Y);
|
||||
if( pLimit ){
|
||||
sqlite3ExprDelete(pParse->db, p->pLimit);
|
||||
p->pLimit = pLimit;
|
||||
}
|
||||
p->bNeedPush = 1;
|
||||
}
|
||||
pipeline(A) ::= pipeline(A) PIPE AS nm(X). {A->sAs = X; A->bNeedPush = 1;}
|
||||
pipeline(A) ::= pipeline(A) pipe VIEW nm(X). {A->sAs = X; A->bNeedPush = 1;}
|
||||
//pipeline ::= pipeline pipe DISTINCT ON nexprlist.
|
||||
|
||||
pipe ::= .
|
||||
pipe ::= PIPE.
|
||||
|
||||
%type pipejoinop {int}
|
||||
pipejoinop(X) ::= JOIN. { X = JT_INNER; }
|
||||
pipejoinop(X) ::= JOIN_KW(A) JOIN.
|
||||
{X = sqlite3JoinType(pParse,&A,0,0); /*X-overwrites-A*/}
|
||||
pipejoinop(X) ::= JOIN_KW(A) nm(B) JOIN.
|
||||
{X = sqlite3JoinType(pParse,&A,&B,0); /*X-overwrites-A*/}
|
||||
pipejoinop(X) ::= JOIN_KW(A) nm(B) nm(C) JOIN.
|
||||
{X = sqlite3JoinType(pParse,&A,&B,&C);/*X-overwrites-A*/}
|
||||
|
||||
%endif FROM_first
|
||||
|
||||
// Single row VALUES clause.
|
||||
//
|
||||
@@ -733,44 +961,7 @@ seltablist(A) ::= stl_prefix(A) nm(Y) dbnm(D) LP exprlist(E) RP as(Z) on_using(N
|
||||
A = sqlite3SrcListAppendFromTerm(pParse,A,0,0,&Z,S,&N);
|
||||
}
|
||||
seltablist(A) ::= stl_prefix(A) LP seltablist(F) RP as(Z) on_using(N). {
|
||||
if( A==0 && Z.n==0 && N.pOn==0 && N.pUsing==0 ){
|
||||
A = F;
|
||||
}else if( ALWAYS(F!=0) && F->nSrc==1 ){
|
||||
A = sqlite3SrcListAppendFromTerm(pParse,A,0,0,&Z,0,&N);
|
||||
if( A ){
|
||||
SrcItem *pNew = &A->a[A->nSrc-1];
|
||||
SrcItem *pOld = F->a;
|
||||
assert( pOld->fg.fixedSchema==0 );
|
||||
pNew->zName = pOld->zName;
|
||||
assert( pOld->fg.fixedSchema==0 );
|
||||
if( pOld->fg.isSubquery ){
|
||||
pNew->fg.isSubquery = 1;
|
||||
pNew->u4.pSubq = pOld->u4.pSubq;
|
||||
pOld->u4.pSubq = 0;
|
||||
pOld->fg.isSubquery = 0;
|
||||
assert( pNew->u4.pSubq!=0 && pNew->u4.pSubq->pSelect!=0 );
|
||||
if( (pNew->u4.pSubq->pSelect->selFlags & SF_NestedFrom)!=0 ){
|
||||
pNew->fg.isNestedFrom = 1;
|
||||
}
|
||||
}else{
|
||||
pNew->u4.zDatabase = pOld->u4.zDatabase;
|
||||
pOld->u4.zDatabase = 0;
|
||||
}
|
||||
if( pOld->fg.isTabFunc ){
|
||||
pNew->u1.pFuncArg = pOld->u1.pFuncArg;
|
||||
pOld->u1.pFuncArg = 0;
|
||||
pOld->fg.isTabFunc = 0;
|
||||
pNew->fg.isTabFunc = 1;
|
||||
}
|
||||
pOld->zName = 0;
|
||||
}
|
||||
sqlite3SrcListDelete(pParse->db, F);
|
||||
}else{
|
||||
Select *pSubquery;
|
||||
sqlite3SrcListShiftJoinType(pParse,F);
|
||||
pSubquery = sqlite3SelectNew(pParse,0,F,0,0,0,0,SF_NestedFrom,0);
|
||||
A = sqlite3SrcListAppendFromTerm(pParse,A,0,0,&Z,pSubquery,&N);
|
||||
}
|
||||
A = sqlite3SrcListAppendSubFrom(pParse,A,F,&Z,&N);
|
||||
}
|
||||
%endif SQLITE_OMIT_SUBQUERY
|
||||
|
||||
|
||||
@@ -246,7 +246,6 @@ extern LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText);
|
||||
# define SQLITE_CIO_NO_CLASSIFY
|
||||
# define SQLITE_CIO_NO_TRANSLATE
|
||||
# define SQLITE_CIO_NO_SETMODE
|
||||
# define SQLITE_CIO_NO_FLUSH
|
||||
#endif
|
||||
INCLUDE ../ext/consio/console_io.h
|
||||
INCLUDE ../ext/consio/console_io.c
|
||||
@@ -280,7 +279,6 @@ INCLUDE ../ext/consio/console_io.c
|
||||
# define eputz(z) ePutsUtf8(z)
|
||||
# define eputf ePrintfUtf8
|
||||
# define oputb(buf,na) oPutbUtf8(buf,na)
|
||||
# define fflush(s) fFlushBuffer(s);
|
||||
|
||||
#else
|
||||
/* For Fiddle, all console handling and emit redirection is omitted. */
|
||||
@@ -297,7 +295,6 @@ INCLUDE ../ext/consio/console_io.c
|
||||
# define eputz(z) fputs(z,stderr)
|
||||
# define sputz(fp,z) fputs(z,fp)
|
||||
# define oputb(buf,na) fwrite(buf,1,na,stdout)
|
||||
# undef fflush
|
||||
#endif
|
||||
|
||||
/* True if the timer is enabled */
|
||||
|
||||
+9
-4
@@ -372,12 +372,17 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){
|
||||
}
|
||||
}
|
||||
case CC_PIPE: {
|
||||
if( z[1]!='|' ){
|
||||
*tokenType = TK_BITOR;
|
||||
return 1;
|
||||
}else{
|
||||
if( z[1]=='|' ){
|
||||
*tokenType = TK_CONCAT;
|
||||
return 2;
|
||||
#ifdef TK_PIPE
|
||||
}else if( z[1]=='>' ){
|
||||
*tokenType = TK_PIPE;
|
||||
return 2;
|
||||
#endif
|
||||
}else{
|
||||
*tokenType = TK_BITOR;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
case CC_COMMA: {
|
||||
|
||||
+9
-14
@@ -162,9 +162,6 @@ SQLITE_NOINLINE int sqlite3RunVacuum(
|
||||
const char *zDbMain; /* Schema name of database to vacuum */
|
||||
const char *zOut; /* Name of output file */
|
||||
u32 pgflags = PAGER_SYNCHRONOUS_OFF; /* sync flags for output db */
|
||||
u64 iRandom; /* Random value used for zDbVacuum[] */
|
||||
char zDbVacuum[42]; /* Name of the ATTACH-ed database used for vacuum */
|
||||
|
||||
|
||||
if( !db->autoCommit ){
|
||||
sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction");
|
||||
@@ -205,29 +202,27 @@ SQLITE_NOINLINE int sqlite3RunVacuum(
|
||||
pMain = db->aDb[iDb].pBt;
|
||||
isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain));
|
||||
|
||||
/* Attach the temporary database as 'vacuum_XXXXXX'. The synchronous pragma
|
||||
/* Attach the temporary database as 'vacuum_db'. The synchronous pragma
|
||||
** can be set to 'off' for this file, as it is not recovered if a crash
|
||||
** occurs anyway. The integrity of the database is maintained by a
|
||||
** (possibly synchronous) transaction opened on the main database before
|
||||
** sqlite3BtreeCopyFile() is called.
|
||||
**
|
||||
** An optimization would be to use a non-journaled pager.
|
||||
** (Later:) I tried setting "PRAGMA vacuum_XXXXXX.journal_mode=OFF" but
|
||||
** (Later:) I tried setting "PRAGMA vacuum_db.journal_mode=OFF" but
|
||||
** that actually made the VACUUM run slower. Very little journalling
|
||||
** actually occurs when doing a vacuum since the vacuum_db is initially
|
||||
** empty. Only the journal header is written. Apparently it takes more
|
||||
** time to parse and run the PRAGMA to turn journalling off than it does
|
||||
** to write the journal header file.
|
||||
*/
|
||||
sqlite3_randomness(sizeof(iRandom),&iRandom);
|
||||
sqlite3_snprintf(sizeof(zDbVacuum), zDbVacuum, "vacuum_%016llx", iRandom);
|
||||
nDb = db->nDb;
|
||||
rc = execSqlF(db, pzErrMsg, "ATTACH %Q AS %s", zOut, zDbVacuum);
|
||||
rc = execSqlF(db, pzErrMsg, "ATTACH %Q AS vacuum_db", zOut);
|
||||
db->openFlags = saved_openFlags;
|
||||
if( rc!=SQLITE_OK ) goto end_of_vacuum;
|
||||
assert( (db->nDb-1)==nDb );
|
||||
pDb = &db->aDb[nDb];
|
||||
assert( strcmp(pDb->zDbSName,zDbVacuum)==0 );
|
||||
assert( strcmp(pDb->zDbSName,"vacuum_db")==0 );
|
||||
pTemp = pDb->pBt;
|
||||
if( pOut ){
|
||||
sqlite3_file *id = sqlite3PagerFile(sqlite3BtreePager(pTemp));
|
||||
@@ -304,11 +299,11 @@ SQLITE_NOINLINE int sqlite3RunVacuum(
|
||||
** the contents to the temporary database.
|
||||
*/
|
||||
rc = execSqlF(db, pzErrMsg,
|
||||
"SELECT'INSERT INTO %s.'||quote(name)"
|
||||
"SELECT'INSERT INTO vacuum_db.'||quote(name)"
|
||||
"||' SELECT*FROM\"%w\".'||quote(name)"
|
||||
"FROM %s.sqlite_schema "
|
||||
"FROM vacuum_db.sqlite_schema "
|
||||
"WHERE type='table'AND coalesce(rootpage,1)>0",
|
||||
zDbVacuum, zDbMain, zDbVacuum
|
||||
zDbMain
|
||||
);
|
||||
assert( (db->mDbFlags & DBFLAG_Vacuum)!=0 );
|
||||
db->mDbFlags &= ~DBFLAG_Vacuum;
|
||||
@@ -320,11 +315,11 @@ SQLITE_NOINLINE int sqlite3RunVacuum(
|
||||
** from the schema table.
|
||||
*/
|
||||
rc = execSqlF(db, pzErrMsg,
|
||||
"INSERT INTO %s.sqlite_schema"
|
||||
"INSERT INTO vacuum_db.sqlite_schema"
|
||||
" SELECT*FROM \"%w\".sqlite_schema"
|
||||
" WHERE type IN('view','trigger')"
|
||||
" OR(type='table'AND rootpage=0)",
|
||||
zDbVacuum, zDbMain
|
||||
zDbMain
|
||||
);
|
||||
if( rc ) goto end_of_vacuum;
|
||||
|
||||
|
||||
+31
-78
@@ -89,9 +89,7 @@ Other PERMUTATION arguments must be run using testfixture, not tclsh:
|
||||
If no PATTERN arguments are present, all tests specified by the PERMUTATION
|
||||
are run. Otherwise, each pattern is interpreted as a glob pattern. Only
|
||||
those tcl tests for which the final component of the filename matches at
|
||||
least one specified pattern are run. The glob wildcard '*' is prepended
|
||||
to the pattern if it does not start with '^' and appended to every
|
||||
pattern that does not end with '$'.
|
||||
least one specified pattern are run.
|
||||
|
||||
If no PATTERN arguments are present, then various fuzztest, threadtest
|
||||
and other tests are run as part of the "release" permutation. These are
|
||||
@@ -279,12 +277,10 @@ set TRG(schema) {
|
||||
priority INTEGER NOT NULL, -- higher priority jobs may run earlier
|
||||
|
||||
/* Fields updated as jobs run */
|
||||
starttime INTEGER, -- Start time (milliseconds since 1970)
|
||||
endtime INTEGER, -- End time
|
||||
starttime INTEGER,
|
||||
endtime INTEGER,
|
||||
state TEXT CHECK( state IN ('','ready','running','done','failed','omit') ),
|
||||
ntest INT, -- Number of test cases run
|
||||
nerr INT, -- Number of errors reported
|
||||
output TEXT -- test output
|
||||
output TEXT
|
||||
);
|
||||
|
||||
CREATE TABLE config(
|
||||
@@ -393,36 +389,14 @@ if {[string compare -nocase script [lindex $argv 0]]==0} {
|
||||
exit
|
||||
}
|
||||
|
||||
# Compute an elapse time string MM:SS or HH:MM:SS based on the
|
||||
# number of milliseconds in the argument.
|
||||
#
|
||||
proc elapsetime {ms} {
|
||||
set s [expr {int(($ms+500.0)*0.001)}]
|
||||
set hr [expr {$s/3600}]
|
||||
set mn [expr {($s/60)%60}]
|
||||
set sc [expr {$s%60}]
|
||||
if {$hr>0} {
|
||||
return [format %02d:%02d:%02d $hr $mn $sc]
|
||||
} else {
|
||||
return [format %02d:%02d $mn $sc]
|
||||
}
|
||||
}
|
||||
|
||||
# Helper routine for show_status
|
||||
#
|
||||
proc display_job {jobdict {tm ""}} {
|
||||
array set job $jobdict
|
||||
if {[string length $job(displayname)]>65} {
|
||||
set dfname [format %.65s... $job(displayname)]
|
||||
} else {
|
||||
set dfname [format %-68s $job(displayname)]
|
||||
}
|
||||
set dfname [format %-60s $job(displayname)]
|
||||
set dtm ""
|
||||
if {$tm!=""} {
|
||||
set dtm [expr {$tm-$job(starttime)}]
|
||||
set dtm [format %8s [elapsetime $dtm]]
|
||||
} else {
|
||||
set dtm [format %8s ""]
|
||||
set dtm [format %-10s "\[[expr {$tm-$job(starttime)}]ms\]"]
|
||||
}
|
||||
puts " $dfname $dtm"
|
||||
}
|
||||
@@ -457,11 +431,6 @@ proc show_status {db cls} {
|
||||
incr S($state) $cnt
|
||||
incr total $cnt
|
||||
}
|
||||
set nt 0
|
||||
set ne 0
|
||||
$db eval {
|
||||
SELECT sum(ntest) AS nt, sum(nerr) AS ne FROM jobs HAVING nt>0
|
||||
} break
|
||||
set fin [expr $S(done)+$S(failed)]
|
||||
if {$cmdline!=""} {set cmdline " $cmdline"}
|
||||
|
||||
@@ -474,10 +443,14 @@ proc show_status {db cls} {
|
||||
} else {
|
||||
set clreol ""
|
||||
}
|
||||
puts [format %-79.79s "Command: \[testrunner.tcl$cmdline\]$clreol"]
|
||||
puts [format %-79.79s "Cores: $nJob max $S(running) active"]
|
||||
puts [format %-79.79s "Summary: [elapsetime $tm], $fin/$total tasks,\
|
||||
$ne errors, $nt tests"]
|
||||
set f ""
|
||||
if {$S(failed)>0} {
|
||||
set f "$S(failed) FAILED, "
|
||||
}
|
||||
puts "Command line: \[testrunner.tcl$cmdline\]$clreol"
|
||||
puts "Jobs: $nJob "
|
||||
puts "Summary: ${tm}ms, ($fin/$total) finished,\
|
||||
${f}$S(running) running "
|
||||
|
||||
set srcdir [file dirname [file dirname $TRG(info_script)]]
|
||||
if {$S(running)>0} {
|
||||
@@ -497,7 +470,7 @@ proc show_status {db cls} {
|
||||
}
|
||||
set nOmit [$db one {SELECT count(*) FROM jobs WHERE state='omit'}]
|
||||
if {$nOmit} {
|
||||
puts [format %-79s "$nOmit jobs omitted due to failures$clreol"]
|
||||
puts "$nOmit jobs omitted due to failures$clreol"
|
||||
}
|
||||
}
|
||||
if {$cls} {
|
||||
@@ -869,17 +842,6 @@ proc add_tcl_jobs {build config patternlist {shelldepid ""}} {
|
||||
if {[llength $patternlist]>0} {
|
||||
set bMatch 0
|
||||
foreach p $patternlist {
|
||||
set p [string trim $p *]
|
||||
if {[string index $p 0]=="^"} {
|
||||
set p [string range $p 1 end]
|
||||
} else {
|
||||
set p "*$p"
|
||||
}
|
||||
if {[string index $p end]=="\$"} {
|
||||
set p [string range $p 0 end-1]
|
||||
} else {
|
||||
set p "$p*"
|
||||
}
|
||||
if {[string match $p [file tail $f]]} {
|
||||
set bMatch 1
|
||||
break
|
||||
@@ -1100,13 +1062,25 @@ proc add_jobs_from_cmdline {patternlist} {
|
||||
}
|
||||
|
||||
release {
|
||||
set config_set {}
|
||||
set patternlist [lrange $patternlist 1 end]
|
||||
foreach b [trd_builds $TRG(platform)] {
|
||||
if {$TRG(config)!="" && ![regexp "\\y$b\\y" $TRG(config)]} continue
|
||||
if {[regexp "\\y$b\\y" $TRG(omitconfig)]} continue
|
||||
lappend config_set $b
|
||||
set bld [add_build_job $b $TRG(testfixture)]
|
||||
foreach c [trd_configs $TRG(platform) $b] {
|
||||
add_tcl_jobs $bld $c $patternlist
|
||||
}
|
||||
|
||||
if {$patternlist==""} {
|
||||
foreach e [trd_extras $TRG(platform) $b] {
|
||||
if {$e=="fuzztest"} {
|
||||
add_fuzztest_jobs $b
|
||||
} else {
|
||||
add_make_job $bld $e
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
add_devtest_jobs $config_set [lrange $patternlist 1 end]
|
||||
}
|
||||
|
||||
list {
|
||||
@@ -1146,25 +1120,15 @@ proc make_new_testset {} {
|
||||
}
|
||||
|
||||
proc mark_job_as_finished {jobid output state endtm} {
|
||||
set ntest 1
|
||||
set nerr 0
|
||||
if {$endtm>0} {
|
||||
if {[regexp {\y(\d+) errors out of (\d+) tests} $output all a b]} {
|
||||
set nerr $a
|
||||
set ntest $b
|
||||
}
|
||||
}
|
||||
r_write_db {
|
||||
if {$state=="failed"} {
|
||||
set childstate omit
|
||||
if {$nerr<=0} {set nerr 1}
|
||||
} else {
|
||||
set childstate ready
|
||||
}
|
||||
trdb eval {
|
||||
UPDATE jobs
|
||||
SET output=$output, state=$state, endtime=$endtm,
|
||||
ntest=$ntest, nerr=$nerr
|
||||
SET output=$output, state=$state, endtime=$endtm
|
||||
WHERE jobid=$jobid;
|
||||
UPDATE jobs SET state=$childstate WHERE depid=$jobid;
|
||||
}
|
||||
@@ -1407,17 +1371,6 @@ proc run_testset {} {
|
||||
|
||||
puts "\nTest database is $TRG(dbname)"
|
||||
puts "Test log is $TRG(logname)"
|
||||
trdb eval {
|
||||
SELECT sum(ntest) AS totaltest,
|
||||
sum(nerr) AS totalerr
|
||||
FROM jobs
|
||||
} break
|
||||
trdb eval {
|
||||
SELECT max(endtime)-min(starttime) AS totaltime
|
||||
FROM jobs WHERE endtime>0
|
||||
} break;
|
||||
set et [elapsetime $totaltime]
|
||||
puts "$totalerr errors out of $totaltest tests in about $et"
|
||||
}
|
||||
|
||||
# Handle the --buildonly option, if it was specified.
|
||||
|
||||
@@ -16,6 +16,7 @@ namespace eval trd {
|
||||
set tcltest(linux.Have-Not) veryquick
|
||||
set tcltest(linux.Secure-Delete) veryquick
|
||||
set tcltest(linux.Unlock-Notify) veryquick
|
||||
set tcltest(linux.User-Auth) veryquick
|
||||
set tcltest(linux.Update-Delete-Limit) veryquick
|
||||
set tcltest(linux.Extra-Robustness) veryquick
|
||||
set tcltest(linux.Device-Two) veryquick
|
||||
@@ -115,7 +116,6 @@ namespace eval trd {
|
||||
}
|
||||
set build(Stdcall) {
|
||||
-DUSE_STDCALL=1
|
||||
-DSQLITE_USE_ONLY_WIN32=1
|
||||
-O2
|
||||
}
|
||||
|
||||
@@ -139,6 +139,10 @@ namespace eval trd {
|
||||
-DSQLITE_THREADSAFE
|
||||
-DSQLITE_TCL_DEFAULT_FULLMUTEX=1
|
||||
}
|
||||
set build(User-Auth) {
|
||||
-O2
|
||||
-DSQLITE_USER_AUTHENTICATION=1
|
||||
}
|
||||
set build(Secure-Delete) {
|
||||
-O2
|
||||
-DSQLITE_SECURE_DELETE=1
|
||||
@@ -218,7 +222,7 @@ namespace eval trd {
|
||||
-DSQLITE_MAX_PAGE_SIZE=4096
|
||||
-DSQLITE_OMIT_LOAD_EXTENSION=1
|
||||
-DSQLITE_OMIT_PROGRESS_CALLBACK=1
|
||||
-DSQLITE_OMIT_VIRTUALTABLEx=1
|
||||
-DSQLITE_OMIT_VIRTUALTABLE=1
|
||||
-DSQLITE_ENABLE_HIDDEN_COLUMNS
|
||||
-DSQLITE_TEMP_STORE=3
|
||||
}
|
||||
|
||||
@@ -164,6 +164,11 @@ struct Keyword {
|
||||
#else
|
||||
# define RETURNING 0x00400000
|
||||
#endif
|
||||
#ifdef SQLITE_OMIT_FROM_FIRST
|
||||
# define PIPE 0
|
||||
#else
|
||||
# define PIPE 0x00800000
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
@@ -174,6 +179,7 @@ static Keyword aKeywordTable[] = {
|
||||
{ "ACTION", "TK_ACTION", FKEY, 0 },
|
||||
{ "ADD", "TK_ADD", ALTER, 1 },
|
||||
{ "AFTER", "TK_AFTER", TRIGGER, 0 },
|
||||
{ "AGGREGATE", "TK_AGGREGATE", PIPE, 10 },
|
||||
{ "ALL", "TK_ALL", ALWAYS, 0 },
|
||||
{ "ALTER", "TK_ALTER", ALTER, 0 },
|
||||
{ "ALWAYS", "TK_ALWAYS", GENCOL, 0 },
|
||||
|
||||
Reference in New Issue
Block a user