Merge branches "fix-onerow-opt", "faster-openread", "fts5-delay-tokenizer" and "enhanced-raise", each containing minor enhancements prepared for 3.47, into this branch.
FossilOrigin-Name: 6dc6472175bccbed15ebf6811c209d1a0b5fad60158fb32040210f2cdae916a6
This commit is contained in:
commit
c83386cbe5
@ -142,6 +142,15 @@ struct Fts5Colset {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct Fts5Config Fts5Config;
|
typedef struct Fts5Config Fts5Config;
|
||||||
|
typedef struct Fts5TokenizerConfig Fts5TokenizerConfig;
|
||||||
|
|
||||||
|
struct Fts5TokenizerConfig {
|
||||||
|
Fts5Tokenizer *pTok;
|
||||||
|
fts5_tokenizer *pTokApi;
|
||||||
|
const char **azArg;
|
||||||
|
int nArg;
|
||||||
|
int ePattern; /* FTS_PATTERN_XXX constant */
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** An instance of the following structure encodes all information that can
|
** An instance of the following structure encodes all information that can
|
||||||
@ -184,6 +193,7 @@ typedef struct Fts5Config Fts5Config;
|
|||||||
*/
|
*/
|
||||||
struct Fts5Config {
|
struct Fts5Config {
|
||||||
sqlite3 *db; /* Database handle */
|
sqlite3 *db; /* Database handle */
|
||||||
|
Fts5Global *pGlobal; /* Global fts5 object for handle db */
|
||||||
char *zDb; /* Database holding FTS index (e.g. "main") */
|
char *zDb; /* Database holding FTS index (e.g. "main") */
|
||||||
char *zName; /* Name of FTS index */
|
char *zName; /* Name of FTS index */
|
||||||
int nCol; /* Number of columns */
|
int nCol; /* Number of columns */
|
||||||
@ -199,10 +209,8 @@ struct Fts5Config {
|
|||||||
int bTokendata; /* "tokendata=" option value (dflt==0) */
|
int bTokendata; /* "tokendata=" option value (dflt==0) */
|
||||||
int eDetail; /* FTS5_DETAIL_XXX value */
|
int eDetail; /* FTS5_DETAIL_XXX value */
|
||||||
char *zContentExprlist;
|
char *zContentExprlist;
|
||||||
Fts5Tokenizer *pTok;
|
Fts5TokenizerConfig t;
|
||||||
fts5_tokenizer *pTokApi;
|
|
||||||
int bLock; /* True when table is preparing statement */
|
int bLock; /* True when table is preparing statement */
|
||||||
int ePattern; /* FTS_PATTERN_XXX constant */
|
|
||||||
|
|
||||||
/* Values loaded from the %_config table */
|
/* Values loaded from the %_config table */
|
||||||
int iVersion; /* fts5 file format 'version' */
|
int iVersion; /* fts5 file format 'version' */
|
||||||
@ -597,13 +605,7 @@ struct Fts5Table {
|
|||||||
Fts5Index *pIndex; /* Full-text index */
|
Fts5Index *pIndex; /* Full-text index */
|
||||||
};
|
};
|
||||||
|
|
||||||
int sqlite3Fts5GetTokenizer(
|
int sqlite3Fts5LoadTokenizer(Fts5Config *pConfig);
|
||||||
Fts5Global*,
|
|
||||||
const char **azArg,
|
|
||||||
int nArg,
|
|
||||||
Fts5Config*,
|
|
||||||
char **pzErr
|
|
||||||
);
|
|
||||||
|
|
||||||
Fts5Table *sqlite3Fts5TableFromCsrid(Fts5Global*, i64);
|
Fts5Table *sqlite3Fts5TableFromCsrid(Fts5Global*, i64);
|
||||||
|
|
||||||
@ -866,6 +868,7 @@ int sqlite3Fts5TokenizerPattern(
|
|||||||
int (*xCreate)(void*, const char**, int, Fts5Tokenizer**),
|
int (*xCreate)(void*, const char**, int, Fts5Tokenizer**),
|
||||||
Fts5Tokenizer *pTok
|
Fts5Tokenizer *pTok
|
||||||
);
|
);
|
||||||
|
int sqlite3Fts5TokenizerPreload(Fts5TokenizerConfig*);
|
||||||
/*
|
/*
|
||||||
** End of interface to code in fts5_tokenizer.c.
|
** End of interface to code in fts5_tokenizer.c.
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
@ -298,12 +298,11 @@ static int fts5ConfigParseSpecial(
|
|||||||
if( sqlite3_strnicmp("tokenize", zCmd, nCmd)==0 ){
|
if( sqlite3_strnicmp("tokenize", zCmd, nCmd)==0 ){
|
||||||
const char *p = (const char*)zArg;
|
const char *p = (const char*)zArg;
|
||||||
sqlite3_int64 nArg = strlen(zArg) + 1;
|
sqlite3_int64 nArg = strlen(zArg) + 1;
|
||||||
char **azArg = sqlite3Fts5MallocZero(&rc, sizeof(char*) * nArg);
|
char **azArg = sqlite3Fts5MallocZero(&rc, (sizeof(char*) + 2) * nArg);
|
||||||
char *pDel = sqlite3Fts5MallocZero(&rc, nArg * 2);
|
|
||||||
char *pSpace = pDel;
|
|
||||||
|
|
||||||
if( azArg && pSpace ){
|
if( azArg ){
|
||||||
if( pConfig->pTok ){
|
char *pSpace = (char*)&azArg[nArg];
|
||||||
|
if( pConfig->t.azArg ){
|
||||||
*pzErr = sqlite3_mprintf("multiple tokenize=... directives");
|
*pzErr = sqlite3_mprintf("multiple tokenize=... directives");
|
||||||
rc = SQLITE_ERROR;
|
rc = SQLITE_ERROR;
|
||||||
}else{
|
}else{
|
||||||
@ -326,16 +325,14 @@ static int fts5ConfigParseSpecial(
|
|||||||
*pzErr = sqlite3_mprintf("parse error in tokenize directive");
|
*pzErr = sqlite3_mprintf("parse error in tokenize directive");
|
||||||
rc = SQLITE_ERROR;
|
rc = SQLITE_ERROR;
|
||||||
}else{
|
}else{
|
||||||
rc = sqlite3Fts5GetTokenizer(pGlobal,
|
pConfig->t.azArg = (const char**)azArg;
|
||||||
(const char**)azArg, (int)nArg, pConfig,
|
pConfig->t.nArg = nArg;
|
||||||
pzErr
|
azArg = 0;
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlite3_free(azArg);
|
sqlite3_free(azArg);
|
||||||
sqlite3_free(pDel);
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -412,16 +409,6 @@ static int fts5ConfigParseSpecial(
|
|||||||
return SQLITE_ERROR;
|
return SQLITE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
** Allocate an instance of the default tokenizer ("simple") at
|
|
||||||
** Fts5Config.pTokenizer. Return SQLITE_OK if successful, or an SQLite error
|
|
||||||
** code if an error occurs.
|
|
||||||
*/
|
|
||||||
static int fts5ConfigDefaultTokenizer(Fts5Global *pGlobal, Fts5Config *pConfig){
|
|
||||||
assert( pConfig->pTok==0 && pConfig->pTokApi==0 );
|
|
||||||
return sqlite3Fts5GetTokenizer(pGlobal, 0, 0, pConfig, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Gobble up the first bareword or quoted word from the input buffer zIn.
|
** Gobble up the first bareword or quoted word from the input buffer zIn.
|
||||||
** Return a pointer to the character immediately following the last in
|
** Return a pointer to the character immediately following the last in
|
||||||
@ -554,6 +541,7 @@ int sqlite3Fts5ConfigParse(
|
|||||||
*ppOut = pRet = (Fts5Config*)sqlite3_malloc(sizeof(Fts5Config));
|
*ppOut = pRet = (Fts5Config*)sqlite3_malloc(sizeof(Fts5Config));
|
||||||
if( pRet==0 ) return SQLITE_NOMEM;
|
if( pRet==0 ) return SQLITE_NOMEM;
|
||||||
memset(pRet, 0, sizeof(Fts5Config));
|
memset(pRet, 0, sizeof(Fts5Config));
|
||||||
|
pRet->pGlobal = pGlobal;
|
||||||
pRet->db = db;
|
pRet->db = db;
|
||||||
pRet->iCookie = -1;
|
pRet->iCookie = -1;
|
||||||
|
|
||||||
@ -640,13 +628,6 @@ int sqlite3Fts5ConfigParse(
|
|||||||
rc = SQLITE_ERROR;
|
rc = SQLITE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If a tokenizer= option was successfully parsed, the tokenizer has
|
|
||||||
** already been allocated. Otherwise, allocate an instance of the default
|
|
||||||
** tokenizer (unicode61) now. */
|
|
||||||
if( rc==SQLITE_OK && pRet->pTok==0 ){
|
|
||||||
rc = fts5ConfigDefaultTokenizer(pGlobal, pRet);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If no zContent option was specified, fill in the default values. */
|
/* If no zContent option was specified, fill in the default values. */
|
||||||
if( rc==SQLITE_OK && pRet->zContent==0 ){
|
if( rc==SQLITE_OK && pRet->zContent==0 ){
|
||||||
const char *zTail = 0;
|
const char *zTail = 0;
|
||||||
@ -688,9 +669,10 @@ int sqlite3Fts5ConfigParse(
|
|||||||
void sqlite3Fts5ConfigFree(Fts5Config *pConfig){
|
void sqlite3Fts5ConfigFree(Fts5Config *pConfig){
|
||||||
if( pConfig ){
|
if( pConfig ){
|
||||||
int i;
|
int i;
|
||||||
if( pConfig->pTok ){
|
if( pConfig->t.pTok ){
|
||||||
pConfig->pTokApi->xDelete(pConfig->pTok);
|
pConfig->t.pTokApi->xDelete(pConfig->t.pTok);
|
||||||
}
|
}
|
||||||
|
sqlite3_free(pConfig->t.azArg);
|
||||||
sqlite3_free(pConfig->zDb);
|
sqlite3_free(pConfig->zDb);
|
||||||
sqlite3_free(pConfig->zName);
|
sqlite3_free(pConfig->zName);
|
||||||
for(i=0; i<pConfig->nCol; i++){
|
for(i=0; i<pConfig->nCol; i++){
|
||||||
@ -765,10 +747,18 @@ int sqlite3Fts5Tokenize(
|
|||||||
void *pCtx, /* Context passed to xToken() */
|
void *pCtx, /* Context passed to xToken() */
|
||||||
int (*xToken)(void*, int, const char*, int, int, int) /* Callback */
|
int (*xToken)(void*, int, const char*, int, int, int) /* Callback */
|
||||||
){
|
){
|
||||||
if( pText==0 ) return SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
return pConfig->pTokApi->xTokenize(
|
if( pText ){
|
||||||
pConfig->pTok, pCtx, flags, pText, nText, xToken
|
if( pConfig->t.pTok==0 ){
|
||||||
);
|
rc = sqlite3Fts5LoadTokenizer(pConfig);
|
||||||
|
}
|
||||||
|
if( rc==SQLITE_OK ){
|
||||||
|
rc = pConfig->t.pTokApi->xTokenize(
|
||||||
|
pConfig->t.pTok, pCtx, flags, pText, nText, xToken
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -324,7 +324,7 @@ int sqlite3Fts5ExprNew(
|
|||||||
}
|
}
|
||||||
|
|
||||||
sqlite3_free(sParse.apPhrase);
|
sqlite3_free(sParse.apPhrase);
|
||||||
*pzErr = sParse.zErr;
|
if( 0==*pzErr ) *pzErr = sParse.zErr;
|
||||||
return sParse.rc;
|
return sParse.rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -377,8 +377,12 @@ static int fts5InitVtab(
|
|||||||
assert( (rc==SQLITE_OK && *pzErr==0) || pConfig==0 );
|
assert( (rc==SQLITE_OK && *pzErr==0) || pConfig==0 );
|
||||||
}
|
}
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
|
pConfig->pzErrmsg = pzErr;
|
||||||
pTab->p.pConfig = pConfig;
|
pTab->p.pConfig = pConfig;
|
||||||
pTab->pGlobal = pGlobal;
|
pTab->pGlobal = pGlobal;
|
||||||
|
if( bCreate || sqlite3Fts5TokenizerPreload(&pConfig->t) ){
|
||||||
|
rc = sqlite3Fts5LoadTokenizer(pConfig);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Open the index sub-system */
|
/* Open the index sub-system */
|
||||||
@ -400,11 +404,8 @@ static int fts5InitVtab(
|
|||||||
|
|
||||||
/* Load the initial configuration */
|
/* Load the initial configuration */
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
assert( pConfig->pzErrmsg==0 );
|
|
||||||
pConfig->pzErrmsg = pzErr;
|
|
||||||
rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex);
|
rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex);
|
||||||
sqlite3Fts5IndexRollback(pTab->p.pIndex);
|
sqlite3Fts5IndexRollback(pTab->p.pIndex);
|
||||||
pConfig->pzErrmsg = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){
|
if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){
|
||||||
@ -414,6 +415,7 @@ static int fts5InitVtab(
|
|||||||
rc = sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
|
rc = sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( pConfig ) pConfig->pzErrmsg = 0;
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
fts5FreeVtab(pTab);
|
fts5FreeVtab(pTab);
|
||||||
pTab = 0;
|
pTab = 0;
|
||||||
@ -481,10 +483,10 @@ static int fts5UsePatternMatch(
|
|||||||
){
|
){
|
||||||
assert( FTS5_PATTERN_GLOB==SQLITE_INDEX_CONSTRAINT_GLOB );
|
assert( FTS5_PATTERN_GLOB==SQLITE_INDEX_CONSTRAINT_GLOB );
|
||||||
assert( FTS5_PATTERN_LIKE==SQLITE_INDEX_CONSTRAINT_LIKE );
|
assert( FTS5_PATTERN_LIKE==SQLITE_INDEX_CONSTRAINT_LIKE );
|
||||||
if( pConfig->ePattern==FTS5_PATTERN_GLOB && p->op==FTS5_PATTERN_GLOB ){
|
if( pConfig->t.ePattern==FTS5_PATTERN_GLOB && p->op==FTS5_PATTERN_GLOB ){
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if( pConfig->ePattern==FTS5_PATTERN_LIKE
|
if( pConfig->t.ePattern==FTS5_PATTERN_LIKE
|
||||||
&& (p->op==FTS5_PATTERN_LIKE || p->op==FTS5_PATTERN_GLOB)
|
&& (p->op==FTS5_PATTERN_LIKE || p->op==FTS5_PATTERN_GLOB)
|
||||||
){
|
){
|
||||||
return 1;
|
return 1;
|
||||||
@ -626,6 +628,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
|
|||||||
idxStr += strlen(&idxStr[iIdxStr]);
|
idxStr += strlen(&idxStr[iIdxStr]);
|
||||||
pInfo->aConstraintUsage[i].argvIndex = ++iCons;
|
pInfo->aConstraintUsage[i].argvIndex = ++iCons;
|
||||||
assert( idxStr[iIdxStr]=='\0' );
|
assert( idxStr[iIdxStr]=='\0' );
|
||||||
|
bSeenMatch = 1;
|
||||||
}else if( bSeenEq==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol<0 ){
|
}else if( bSeenEq==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol<0 ){
|
||||||
idxStr[iIdxStr++] = '=';
|
idxStr[iIdxStr++] = '=';
|
||||||
bSeenEq = 1;
|
bSeenEq = 1;
|
||||||
@ -2860,7 +2863,7 @@ static int fts5FindTokenizer(
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sqlite3Fts5GetTokenizer(
|
int fts5GetTokenizer(
|
||||||
Fts5Global *pGlobal,
|
Fts5Global *pGlobal,
|
||||||
const char **azArg,
|
const char **azArg,
|
||||||
int nArg,
|
int nArg,
|
||||||
@ -2877,26 +2880,37 @@ int sqlite3Fts5GetTokenizer(
|
|||||||
*pzErr = sqlite3_mprintf("no such tokenizer: %s", azArg[0]);
|
*pzErr = sqlite3_mprintf("no such tokenizer: %s", azArg[0]);
|
||||||
}else{
|
}else{
|
||||||
rc = pMod->x.xCreate(
|
rc = pMod->x.xCreate(
|
||||||
pMod->pUserData, (azArg?&azArg[1]:0), (nArg?nArg-1:0), &pConfig->pTok
|
pMod->pUserData, (azArg?&azArg[1]:0), (nArg?nArg-1:0), &pConfig->t.pTok
|
||||||
);
|
);
|
||||||
pConfig->pTokApi = &pMod->x;
|
pConfig->t.pTokApi = &pMod->x;
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
if( pzErr ) *pzErr = sqlite3_mprintf("error in tokenizer constructor");
|
if( pzErr ) *pzErr = sqlite3_mprintf("error in tokenizer constructor");
|
||||||
}else{
|
}else{
|
||||||
pConfig->ePattern = sqlite3Fts5TokenizerPattern(
|
pConfig->t.ePattern = sqlite3Fts5TokenizerPattern(
|
||||||
pMod->x.xCreate, pConfig->pTok
|
pMod->x.xCreate, pConfig->t.pTok
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
pConfig->pTokApi = 0;
|
pConfig->t.pTokApi = 0;
|
||||||
pConfig->pTok = 0;
|
pConfig->t.pTok = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Attempt to instantiate the tokenizer.
|
||||||
|
*/
|
||||||
|
int sqlite3Fts5LoadTokenizer(Fts5Config *pConfig){
|
||||||
|
return fts5GetTokenizer(
|
||||||
|
pConfig->pGlobal, pConfig->t.azArg, pConfig->t.nArg,
|
||||||
|
pConfig, pConfig->pzErrmsg
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void fts5ModuleDestroy(void *pCtx){
|
static void fts5ModuleDestroy(void *pCtx){
|
||||||
Fts5TokenizerModule *pTok, *pNextTok;
|
Fts5TokenizerModule *pTok, *pNextTok;
|
||||||
Fts5Auxiliary *pAux, *pNextAux;
|
Fts5Auxiliary *pAux, *pNextAux;
|
||||||
|
@ -1428,6 +1428,16 @@ int sqlite3Fts5TokenizerPattern(
|
|||||||
return FTS5_PATTERN_NONE;
|
return FTS5_PATTERN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Return true if the tokenizer described by p->azArg[] is the trigram
|
||||||
|
** tokenizer. This tokenizer needs to be loaded before xBestIndex is
|
||||||
|
** called for the first time in order to correctly handle LIKE/GLOB.
|
||||||
|
*/
|
||||||
|
int sqlite3Fts5TokenizerPreload(Fts5TokenizerConfig *p){
|
||||||
|
return (p->nArg>=1 && 0==sqlite3_stricmp(p->azArg[0], "trigram"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Register all built-in tokenizers with FTS5.
|
** Register all built-in tokenizers with FTS5.
|
||||||
*/
|
*/
|
||||||
|
@ -64,6 +64,7 @@ struct Fts5VocabCursor {
|
|||||||
|
|
||||||
int nLeTerm; /* Size of zLeTerm in bytes */
|
int nLeTerm; /* Size of zLeTerm in bytes */
|
||||||
char *zLeTerm; /* (term <= $zLeTerm) paramater, or NULL */
|
char *zLeTerm; /* (term <= $zLeTerm) paramater, or NULL */
|
||||||
|
int colUsed; /* Copy of sqlite3_index_info.colUsed */
|
||||||
|
|
||||||
/* These are used by 'col' tables only */
|
/* These are used by 'col' tables only */
|
||||||
int iCol;
|
int iCol;
|
||||||
@ -90,9 +91,11 @@ struct Fts5VocabCursor {
|
|||||||
/*
|
/*
|
||||||
** Bits for the mask used as the idxNum value by xBestIndex/xFilter.
|
** Bits for the mask used as the idxNum value by xBestIndex/xFilter.
|
||||||
*/
|
*/
|
||||||
#define FTS5_VOCAB_TERM_EQ 0x01
|
#define FTS5_VOCAB_TERM_EQ 0x0100
|
||||||
#define FTS5_VOCAB_TERM_GE 0x02
|
#define FTS5_VOCAB_TERM_GE 0x0200
|
||||||
#define FTS5_VOCAB_TERM_LE 0x04
|
#define FTS5_VOCAB_TERM_LE 0x0400
|
||||||
|
|
||||||
|
#define FTS5_VOCAB_COLUSED_MASK 0xFF
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -269,11 +272,13 @@ static int fts5VocabBestIndexMethod(
|
|||||||
int iTermEq = -1;
|
int iTermEq = -1;
|
||||||
int iTermGe = -1;
|
int iTermGe = -1;
|
||||||
int iTermLe = -1;
|
int iTermLe = -1;
|
||||||
int idxNum = 0;
|
int idxNum = (int)pInfo->colUsed;
|
||||||
int nArg = 0;
|
int nArg = 0;
|
||||||
|
|
||||||
UNUSED_PARAM(pUnused);
|
UNUSED_PARAM(pUnused);
|
||||||
|
|
||||||
|
assert( (pInfo->colUsed & FTS5_VOCAB_COLUSED_MASK)==pInfo->colUsed );
|
||||||
|
|
||||||
for(i=0; i<pInfo->nConstraint; i++){
|
for(i=0; i<pInfo->nConstraint; i++){
|
||||||
struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
|
struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
|
||||||
if( p->usable==0 ) continue;
|
if( p->usable==0 ) continue;
|
||||||
@ -365,7 +370,7 @@ static int fts5VocabOpenMethod(
|
|||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
pVTab->zErrMsg = sqlite3_mprintf(
|
pVTab->zErrMsg = sqlite3_mprintf(
|
||||||
"no such fts5 table: %s.%s", pTab->zFts5Db, pTab->zFts5Tbl
|
"no such fts5 table: %s.%s", pTab->zFts5Db, pTab->zFts5Tbl
|
||||||
);
|
);
|
||||||
rc = SQLITE_ERROR;
|
rc = SQLITE_ERROR;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
@ -525,9 +530,19 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
|
|||||||
|
|
||||||
switch( pTab->eType ){
|
switch( pTab->eType ){
|
||||||
case FTS5_VOCAB_ROW:
|
case FTS5_VOCAB_ROW:
|
||||||
if( eDetail==FTS5_DETAIL_FULL ){
|
/* Do not bother counting the number of instances if the "cnt"
|
||||||
while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){
|
** column is not being read (according to colUsed). */
|
||||||
pCsr->aCnt[0]++;
|
if( eDetail==FTS5_DETAIL_FULL && (pCsr->colUsed & 0x04) ){
|
||||||
|
while( iPos<nPos ){
|
||||||
|
u32 ii;
|
||||||
|
fts5FastGetVarint32(pPos, iPos, ii);
|
||||||
|
if( ii==1 ){
|
||||||
|
/* New column in the position list */
|
||||||
|
fts5FastGetVarint32(pPos, iPos, ii);
|
||||||
|
}else{
|
||||||
|
/* An instance - increment pCsr->aCnt[] */
|
||||||
|
pCsr->aCnt[0]++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pCsr->aDoc[0]++;
|
pCsr->aDoc[0]++;
|
||||||
@ -625,6 +640,7 @@ static int fts5VocabFilterMethod(
|
|||||||
if( idxNum & FTS5_VOCAB_TERM_EQ ) pEq = apVal[iVal++];
|
if( idxNum & FTS5_VOCAB_TERM_EQ ) pEq = apVal[iVal++];
|
||||||
if( idxNum & FTS5_VOCAB_TERM_GE ) pGe = apVal[iVal++];
|
if( idxNum & FTS5_VOCAB_TERM_GE ) pGe = apVal[iVal++];
|
||||||
if( idxNum & FTS5_VOCAB_TERM_LE ) pLe = apVal[iVal++];
|
if( idxNum & FTS5_VOCAB_TERM_LE ) pLe = apVal[iVal++];
|
||||||
|
pCsr->colUsed = (idxNum & FTS5_VOCAB_COLUSED_MASK);
|
||||||
|
|
||||||
if( pEq ){
|
if( pEq ){
|
||||||
zTerm = (const char *)sqlite3_value_text(pEq);
|
zTerm = (const char *)sqlite3_value_text(pEq);
|
||||||
|
@ -300,5 +300,75 @@ set ::flags [list]
|
|||||||
do_execsql_test 9.5.1 { SELECT * FROM t1('"abc xyz*"'); } {}
|
do_execsql_test 9.5.1 { SELECT * FROM t1('"abc xyz*"'); } {}
|
||||||
do_test 9.5.2 { set ::flags } {query}
|
do_test 9.5.2 { set ::flags } {query}
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
reset_db
|
||||||
|
do_execsql_test 10.1 {
|
||||||
|
CREATE VIRTUAL TABLE x1 USING fts5(x, tokenize=unicode61);
|
||||||
|
PRAGMA writable_schema = 1;
|
||||||
|
UPDATE sqlite_schema
|
||||||
|
SET sql = 'CREATE VIRTUAL TABLE x1 USING fts5(x, tokenize="unicode61 error");'
|
||||||
|
WHERE name = 'x1';
|
||||||
|
}
|
||||||
|
|
||||||
|
db close
|
||||||
|
sqlite3 db test.db
|
||||||
|
|
||||||
|
do_catchsql_test 10.2 {
|
||||||
|
SELECT * FROM x1('abc');
|
||||||
|
} {1 {error in tokenizer constructor}}
|
||||||
|
|
||||||
|
do_catchsql_test 10.3 {
|
||||||
|
INSERT INTO x1 VALUES('abc');
|
||||||
|
} {1 {error in tokenizer constructor}}
|
||||||
|
|
||||||
|
do_execsql_test 10.4 {
|
||||||
|
PRAGMA writable_schema = 1;
|
||||||
|
UPDATE sqlite_schema
|
||||||
|
SET sql = 'CREATE VIRTUAL TABLE x1 USING fts5(x, tokenize="nosuch error");'
|
||||||
|
WHERE name = 'x1';
|
||||||
|
}
|
||||||
|
|
||||||
|
db close
|
||||||
|
sqlite3 db test.db
|
||||||
|
|
||||||
|
do_catchsql_test 10.5 {
|
||||||
|
SELECT * FROM x1('abc');
|
||||||
|
} {1 {no such tokenizer: nosuch}}
|
||||||
|
do_catchsql_test 10.6 {
|
||||||
|
INSERT INTO x1 VALUES('abc');
|
||||||
|
} {1 {no such tokenizer: nosuch}}
|
||||||
|
|
||||||
|
do_execsql_test 10.7 {
|
||||||
|
DROP TABLE x1;
|
||||||
|
SELECT * FROM sqlite_schema;
|
||||||
|
}
|
||||||
|
|
||||||
|
reset_db
|
||||||
|
do_execsql_test 10.8 {
|
||||||
|
CREATE VIRTUAL TABLE x1 USING fts5(x, tokenize=unicode61);
|
||||||
|
INSERT INTO x1 VALUES('a b c'), ('d e f'), ('a b c');
|
||||||
|
CREATE VIRTUAL TABLE x1v USING fts5vocab(x1, row);
|
||||||
|
|
||||||
|
PRAGMA writable_schema = 1;
|
||||||
|
UPDATE sqlite_schema
|
||||||
|
SET sql = 'CREATE VIRTUAL TABLE x1 USING fts5(x, tokenize=simplify);'
|
||||||
|
WHERE name = 'x1';
|
||||||
|
}
|
||||||
|
|
||||||
|
do_execsql_test 10.9 {
|
||||||
|
SELECT * FROM x1v
|
||||||
|
} {
|
||||||
|
a 2 2 b 2 2 c 2 2 d 1 1 e 1 1 f 1 1
|
||||||
|
}
|
||||||
|
|
||||||
|
db close
|
||||||
|
sqlite3 db test.db
|
||||||
|
|
||||||
|
do_execsql_test 10.10 {
|
||||||
|
SELECT * FROM x1v
|
||||||
|
} {
|
||||||
|
a 2 2 b 2 2 c 2 2 d 1 1 e 1 1 f 1 1
|
||||||
|
}
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
@ -101,9 +101,20 @@ do_execsql_test 4.0 {
|
|||||||
CREATE VIRTUAL TABLE t4 USING fts5(z, tokenize=trigram);
|
CREATE VIRTUAL TABLE t4 USING fts5(z, tokenize=trigram);
|
||||||
} {}
|
} {}
|
||||||
|
|
||||||
breakpoint
|
|
||||||
do_execsql_test 4.1 {
|
do_execsql_test 4.1 {
|
||||||
INSERT INTO t4 VALUES('ABCD');
|
INSERT INTO t4 VALUES('ABCD');
|
||||||
|
INSERT INTO t4 VALUES('DEFG');
|
||||||
} {}
|
} {}
|
||||||
|
|
||||||
|
db close
|
||||||
|
sqlite3 db test.db
|
||||||
|
|
||||||
|
do_eqp_test 4.1 {
|
||||||
|
SELECT rowid FROM t4 WHERE z LIKE '%abc%'
|
||||||
|
} {VIRTUAL TABLE INDEX 0:L0}
|
||||||
|
|
||||||
|
do_execsql_test 4.2 {
|
||||||
|
SELECT rowid FROM t4 WHERE z LIKE '%abc%'
|
||||||
|
} {1}
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
49
manifest
49
manifest
@ -1,5 +1,5 @@
|
|||||||
C Add\sextra\stests\sfor\sthe\serror\smessages\sgenerated\sby\ssqlite3_declare_vtab()\swhen\spassed\ssomething\sother\sthan\sa\swell-formed\sCREATE\sTABLE\sstatement.
|
C Merge\sbranches\s"fix-onerow-opt",\s"faster-openread",\s"fts5-delay-tokenizer"\sand\s"enhanced-raise",\seach\scontaining\sminor\senhancements\sprepared\sfor\s3.47,\sinto\sthis\sbranch.
|
||||||
D 2024-05-16T16:22:51.903
|
D 2024-05-17T14:26:32.984
|
||||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||||
@ -93,22 +93,22 @@ F ext/fts3/unicode/mkunicode.tcl d5aebf022fa4577ee8cdf27468f0d847879993959101f6d
|
|||||||
F ext/fts3/unicode/parseunicode.tcl a981bd6466d12dd17967515801c3ff23f74a281be1a03cf1e6f52a6959fc77eb
|
F ext/fts3/unicode/parseunicode.tcl a981bd6466d12dd17967515801c3ff23f74a281be1a03cf1e6f52a6959fc77eb
|
||||||
F ext/fts5/extract_api_docs.tcl bc3a0ca78be7d3df08e7602c00ca48021ebae40682d75eb001bfdf6e54ffb44e
|
F ext/fts5/extract_api_docs.tcl bc3a0ca78be7d3df08e7602c00ca48021ebae40682d75eb001bfdf6e54ffb44e
|
||||||
F ext/fts5/fts5.h 8856e11a5f0269cd346754cea0765efe8089635b80cad3222e8bfdb08cd5348a
|
F ext/fts5/fts5.h 8856e11a5f0269cd346754cea0765efe8089635b80cad3222e8bfdb08cd5348a
|
||||||
F ext/fts5/fts5Int.h defa43c0932265138ee910ca416e6baccf8b774e0f3d610e74be1ab2880e9834
|
F ext/fts5/fts5Int.h 407ee36addad0ae6df5d37a811f0bd509ab6708b29640884ed5c7509e5f75143
|
||||||
F ext/fts5/fts5_aux.c 4584e88878e54828bf7d4d0d83deedd232ec60628b7731be02bad6adb62304b1
|
F ext/fts5/fts5_aux.c 4584e88878e54828bf7d4d0d83deedd232ec60628b7731be02bad6adb62304b1
|
||||||
F ext/fts5/fts5_buffer.c 0eec58bff585f1a44ea9147eae5da2447292080ea435957f7488c70673cb6f09
|
F ext/fts5/fts5_buffer.c 0eec58bff585f1a44ea9147eae5da2447292080ea435957f7488c70673cb6f09
|
||||||
F ext/fts5/fts5_config.c 8072a207034b51ae9b7694121d1b5715c794e94b275e088f70ae532378ca5cdf
|
F ext/fts5/fts5_config.c 74093394dc26750becc302922e5fe308a8597a70e6e83e66c892242952468163
|
||||||
F ext/fts5/fts5_expr.c e91156ebdcc08d837f4f324168f69f3c0d7fdef0e521fd561efb48ef3297b696
|
F ext/fts5/fts5_expr.c a84df51a1d178fe38a89c0feb9ee6da3e5b98d204dde4d241fc8115464987d7a
|
||||||
F ext/fts5/fts5_hash.c adda4272be401566a6e0ba1acbe70ee5cb97fce944bc2e04dc707152a0ec91b1
|
F ext/fts5/fts5_hash.c adda4272be401566a6e0ba1acbe70ee5cb97fce944bc2e04dc707152a0ec91b1
|
||||||
F ext/fts5/fts5_index.c ee0f4d50bc0c58a7c5ef7d645e7e38e1e59315b8ea9d722ae00c5f949ee65379
|
F ext/fts5/fts5_index.c ee0f4d50bc0c58a7c5ef7d645e7e38e1e59315b8ea9d722ae00c5f949ee65379
|
||||||
F ext/fts5/fts5_main.c d68bd9533d5a638b7f6fae61c3cb0a15257dcdcccedaf3d0b3c9f55940c85048
|
F ext/fts5/fts5_main.c dc6938b7233e9d88b3612fe2e88ce0a62130c43083be59beab8e6f01aa496689
|
||||||
F ext/fts5/fts5_storage.c f9e31b0d155e9b2c92d5d3a09ad7a56b937fbf1c7f962e10f4ca6281349f3934
|
F ext/fts5/fts5_storage.c f9e31b0d155e9b2c92d5d3a09ad7a56b937fbf1c7f962e10f4ca6281349f3934
|
||||||
F ext/fts5/fts5_tcl.c fdf7e2bb9a9186cfcaf2d2ce11d338309342b7a7593c2812bc54455db53da5d2
|
F ext/fts5/fts5_tcl.c fdf7e2bb9a9186cfcaf2d2ce11d338309342b7a7593c2812bc54455db53da5d2
|
||||||
F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee
|
F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee
|
||||||
F ext/fts5/fts5_test_tok.c 3cb0a9b508b30d17ef025ccddd26ae3dc8ddffbe76c057616e59a9aa85d36f3b
|
F ext/fts5/fts5_test_tok.c 3cb0a9b508b30d17ef025ccddd26ae3dc8ddffbe76c057616e59a9aa85d36f3b
|
||||||
F ext/fts5/fts5_tokenize.c 83cfcede3898001cab84432a36ce1503e3080cf9b1c682b022ec82e267ea4c13
|
F ext/fts5/fts5_tokenize.c fa5493075101540270f572038fc1723d44fcc97bfbf237c8530013b8a27860be
|
||||||
F ext/fts5/fts5_unicode2.c eca63dbc797f8ff0572e97caf4631389c0ab900d6364861b915bdd4735973f00
|
F ext/fts5/fts5_unicode2.c eca63dbc797f8ff0572e97caf4631389c0ab900d6364861b915bdd4735973f00
|
||||||
F ext/fts5/fts5_varint.c e64d2113f6e1bfee0032972cffc1207b77af63319746951bf1d09885d1dadf80
|
F ext/fts5/fts5_varint.c e64d2113f6e1bfee0032972cffc1207b77af63319746951bf1d09885d1dadf80
|
||||||
F ext/fts5/fts5_vocab.c 209e0c151e108d5f3621fa24b91e9b02f3750ee6c3f9ccec312df39481b68a09
|
F ext/fts5/fts5_vocab.c e4830b00809e5da53bc10f93adc59e321407b0f801c7f4167c0e47f5552267e0
|
||||||
F ext/fts5/fts5parse.y eb526940f892ade5693f22ffd6c4f2702543a9059942772526eac1fde256bb05
|
F ext/fts5/fts5parse.y eb526940f892ade5693f22ffd6c4f2702543a9059942772526eac1fde256bb05
|
||||||
F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba
|
F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba
|
||||||
F ext/fts5/test/fts5_common.tcl 3378732aae2a7d9a4b9b5c40bde678d4259ca16bd490883325aecc4747bcb384
|
F ext/fts5/test/fts5_common.tcl 3378732aae2a7d9a4b9b5c40bde678d4259ca16bd490883325aecc4747bcb384
|
||||||
@ -227,10 +227,10 @@ F ext/fts5/test/fts5synonym.test 1651815b8008de170e8e600dcacc17521d765482ea8f074
|
|||||||
F ext/fts5/test/fts5synonym2.test e2f6ff68c4fbe12a866a3a87510f553d9dac99bcb74c10b56487c4c0a562fcf5
|
F ext/fts5/test/fts5synonym2.test e2f6ff68c4fbe12a866a3a87510f553d9dac99bcb74c10b56487c4c0a562fcf5
|
||||||
F ext/fts5/test/fts5tok1.test 1f7817499f5971450d8c4a652114b3d833393c8134e32422d0af27884ffe9cef
|
F ext/fts5/test/fts5tok1.test 1f7817499f5971450d8c4a652114b3d833393c8134e32422d0af27884ffe9cef
|
||||||
F ext/fts5/test/fts5tok2.test dcacb32d4a2a3f0dd3215d4a3987f78ae4be21a2
|
F ext/fts5/test/fts5tok2.test dcacb32d4a2a3f0dd3215d4a3987f78ae4be21a2
|
||||||
F ext/fts5/test/fts5tokenizer.test ac3c9112b263a639fb0508ae73a3ee886bf4866d2153771a8e8a20c721305a43
|
F ext/fts5/test/fts5tokenizer.test abeb8b2d00415e5c8eae48d2dcb91357b7f7e1fddbb2b650f00b589a7bea9659
|
||||||
F ext/fts5/test/fts5tokenizer2.test cb5428c7cfb3b6a74b7adfcde65506e329112003e8dffa7501d01c2d18d02569
|
F ext/fts5/test/fts5tokenizer2.test cb5428c7cfb3b6a74b7adfcde65506e329112003e8dffa7501d01c2d18d02569
|
||||||
F ext/fts5/test/fts5trigram.test 6c4e37864f3e7d90673db5563d9736d7e40080ab94d10ebdffa94c1b77941da0
|
F ext/fts5/test/fts5trigram.test 6c4e37864f3e7d90673db5563d9736d7e40080ab94d10ebdffa94c1b77941da0
|
||||||
F ext/fts5/test/fts5trigram2.test 9fe4207f8a4241747aff1005258b564958588d21bfd240d6cd4c2e955d31c156
|
F ext/fts5/test/fts5trigram2.test c91f0a94f7e1ff859682228646abeab4c0eba2effc46af2cbc8f0f48b05a0566
|
||||||
F ext/fts5/test/fts5ubsan.test 783d5a8d13ebfa169e634940228db54540780e3ba7a87ad1e4510e61440bf64b
|
F ext/fts5/test/fts5ubsan.test 783d5a8d13ebfa169e634940228db54540780e3ba7a87ad1e4510e61440bf64b
|
||||||
F ext/fts5/test/fts5umlaut.test a42fe2fe6387c40c49ab27ccbd070e1ae38e07f38d05926482cc0bccac9ad602
|
F ext/fts5/test/fts5umlaut.test a42fe2fe6387c40c49ab27ccbd070e1ae38e07f38d05926482cc0bccac9ad602
|
||||||
F ext/fts5/test/fts5unicode.test 17056f4efe6b0a5d4f41fdf7a7dc9af2873004562eaa899d40633b93dc95f5a9
|
F ext/fts5/test/fts5unicode.test 17056f4efe6b0a5d4f41fdf7a7dc9af2873004562eaa899d40633b93dc95f5a9
|
||||||
@ -704,9 +704,9 @@ F src/date.c 126ba2ab10aeb2e7ba6e089b5f07b747c0625b8287f78b60da346eda8d23c875
|
|||||||
F src/dbpage.c 80e46e1df623ec40486da7a5086cb723b0275a6e2a7b01d9f9b5da0f04ba2782
|
F src/dbpage.c 80e46e1df623ec40486da7a5086cb723b0275a6e2a7b01d9f9b5da0f04ba2782
|
||||||
F src/dbstat.c 3b677254d512fcafd4d0b341bf267b38b235ccfddbef24f9154e19360fa22e43
|
F src/dbstat.c 3b677254d512fcafd4d0b341bf267b38b235ccfddbef24f9154e19360fa22e43
|
||||||
F src/delete.c cb766727c78e715f9fb7ec8a7d03658ed2a3016343ca687acfcec9083cdca500
|
F src/delete.c cb766727c78e715f9fb7ec8a7d03658ed2a3016343ca687acfcec9083cdca500
|
||||||
F src/expr.c f7bad20d2f74005f1f876e7fbb627222ea28250e44b296b047403720c5c21818
|
F src/expr.c 50e71ed518f1b1ba8401006922a309e200d205b2ca5b93d6fd8a006a336dbf67
|
||||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||||
F src/fkey.c a47610f0a5c6cb0ad79f8fcef039c01833dec0c751bb695f28dc0ec6a4c3ba00
|
F src/fkey.c 852f93c0ef995e0c2b8983059a2b97151c194cc8259e21f5bc2b7ac508348c2a
|
||||||
F src/func.c 283d4f3b2751a1d9339fd93a8a013d1948fd5f4474a3cab0955eb4fafd445d0f
|
F src/func.c 283d4f3b2751a1d9339fd93a8a013d1948fd5f4474a3cab0955eb4fafd445d0f
|
||||||
F src/global.c 61a419dd9e993b9be0f91de4c4ccf322b053eb829868e089f0321dd669be3b90
|
F src/global.c 61a419dd9e993b9be0f91de4c4ccf322b053eb829868e089f0321dd669be3b90
|
||||||
F src/hash.c 9ee4269fb1d6632a6fecfb9479c93a1f29271bddbbaf215dd60420bcb80c7220
|
F src/hash.c 9ee4269fb1d6632a6fecfb9479c93a1f29271bddbbaf215dd60420bcb80c7220
|
||||||
@ -743,7 +743,7 @@ F src/os_win.c 6ff43bac175bd9ed79e7c0f96840b139f2f51d01689a638fd05128becf94908a
|
|||||||
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
|
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
|
||||||
F src/pager.c 9beb80f6e330dd63c5d8ba0f7a7f3a55fff22067a68d424949c389bfc6fa0c56
|
F src/pager.c 9beb80f6e330dd63c5d8ba0f7a7f3a55fff22067a68d424949c389bfc6fa0c56
|
||||||
F src/pager.h 4b1140d691860de0be1347474c51fee07d5420bd7f802d38cbab8ea4ab9f538a
|
F src/pager.h 4b1140d691860de0be1347474c51fee07d5420bd7f802d38cbab8ea4ab9f538a
|
||||||
F src/parse.y 50516253433303673ff6b009983bb246d1527415e5a9af22acc51b0eedb9a10d
|
F src/parse.y de2da0ffd33f6532c1640e7c6a6c6d8ac5ae85b0dbb0b1d7c3194d243a4c1e6a
|
||||||
F src/pcache.c 040b165f30622a21b7a9a77c6f2e4877a32fb7f22d4c7f0d2a6fa6833a156a75
|
F src/pcache.c 040b165f30622a21b7a9a77c6f2e4877a32fb7f22d4c7f0d2a6fa6833a156a75
|
||||||
F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5
|
F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5
|
||||||
F src/pcache1.c 602acb23c471bb8d557a6f0083cc2be641d6cafcafa19e481eba7ef4c9ca0f00
|
F src/pcache1.c 602acb23c471bb8d557a6f0083cc2be641d6cafcafa19e481eba7ef4c9ca0f00
|
||||||
@ -817,14 +817,14 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394
|
|||||||
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
||||||
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
|
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
|
||||||
F src/tokenize.c 3f703cacdab728d7741e5a6ac242006d74fe1c2754d4f03ed889d7253259bd68
|
F src/tokenize.c 3f703cacdab728d7741e5a6ac242006d74fe1c2754d4f03ed889d7253259bd68
|
||||||
F src/treeview.c 4f9ba6c1c7c9893fc046fdb0bc1f6bdec7660122b1ae37e51fb9b64c286caafd
|
F src/treeview.c 5538cc0e88cb87c55e26326c7a02d5fe45deaeb2edbd5436af7a674ed6491ff2
|
||||||
F src/trigger.c 0858f75818ed1580332db274f1032bcc5effe567cb132df5c5be8b1d800ca97f
|
F src/trigger.c 0858f75818ed1580332db274f1032bcc5effe567cb132df5c5be8b1d800ca97f
|
||||||
F src/update.c 732404a04d1737ef14bb6ec6b84f74edf28b3c102a92ae46b4855438a710efe7
|
F src/update.c 732404a04d1737ef14bb6ec6b84f74edf28b3c102a92ae46b4855438a710efe7
|
||||||
F src/upsert.c 2e60567a0e9e8520c18671b30712a88dc73534474304af94f32bb5f3ef65ac65
|
F src/upsert.c 2e60567a0e9e8520c18671b30712a88dc73534474304af94f32bb5f3ef65ac65
|
||||||
F src/utf.c f23165685a67b4caf8ec08fb274cb3f319103decfb2a980b7cfd55d18dfa855e
|
F src/utf.c f23165685a67b4caf8ec08fb274cb3f319103decfb2a980b7cfd55d18dfa855e
|
||||||
F src/util.c 4d6d7ebfe6772a1b950c97bbb1d1a72ad4874617ec498ab8aa73b7f5a43e44bb
|
F src/util.c 4d6d7ebfe6772a1b950c97bbb1d1a72ad4874617ec498ab8aa73b7f5a43e44bb
|
||||||
F src/vacuum.c 604fcdaebe76f3497c855afcbf91b8fa5046b32de3045bab89cc008d68e40104
|
F src/vacuum.c 604fcdaebe76f3497c855afcbf91b8fa5046b32de3045bab89cc008d68e40104
|
||||||
F src/vdbe.c 3b1793c5d2235ae89b01ef051a33d7d2ad3704c71799653b112686735ad401ff
|
F src/vdbe.c 2448b34ff095efa5a8d9dd525c4c0842ef7226e44b68fe8df1053ee9894aa5fd
|
||||||
F src/vdbe.h c2d78d15112c3fc5ab87f5e8e0b75d2db1c624409de2e858c3d1aafb1650bb4f
|
F src/vdbe.h c2d78d15112c3fc5ab87f5e8e0b75d2db1c624409de2e858c3d1aafb1650bb4f
|
||||||
F src/vdbeInt.h 949669dfd8a41550d27dcb905b494f2ccde9a2e6c1b0b04daa1227e2e74c2b2c
|
F src/vdbeInt.h 949669dfd8a41550d27dcb905b494f2ccde9a2e6c1b0b04daa1227e2e74c2b2c
|
||||||
F src/vdbeapi.c 80235ac380e9467fec1cb0883354d841f2a771976e766995f7e0c77f845406df
|
F src/vdbeapi.c 80235ac380e9467fec1cb0883354d841f2a771976e766995f7e0c77f845406df
|
||||||
@ -839,7 +839,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
|||||||
F src/wal.c 887fc4ca3f020ebb2e376f222069570834ac63bf50111ef0cbf3ae417048ed89
|
F src/wal.c 887fc4ca3f020ebb2e376f222069570834ac63bf50111ef0cbf3ae417048ed89
|
||||||
F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452
|
F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452
|
||||||
F src/walker.c 7c7ea0115345851c3da4e04e2e239a29983b61fb5b038b94eede6aba462640e2
|
F src/walker.c 7c7ea0115345851c3da4e04e2e239a29983b61fb5b038b94eede6aba462640e2
|
||||||
F src/where.c d235ba520b0147f60732b3bd411e119b43be33d348251edaa6e304a8ad52c511
|
F src/where.c 211c073b4295cf3087fca78d77aff8309cf6ec8267a510f38336080740fb3bb1
|
||||||
F src/whereInt.h 82a13766f13d1a53b05387c2e60726289ef26404bc7b9b1f7770204d97357fb8
|
F src/whereInt.h 82a13766f13d1a53b05387c2e60726289ef26404bc7b9b1f7770204d97357fb8
|
||||||
F src/wherecode.c b9908c0a1aab095822a1e7032556bedc03b6d29641191e9ca535fb2307cd733d
|
F src/wherecode.c b9908c0a1aab095822a1e7032556bedc03b6d29641191e9ca535fb2307cd733d
|
||||||
F src/whereexpr.c 67d15caf88a1a9528283d68ff578e024cf9fe810b517bb0343e5aaf695ad97dd
|
F src/whereexpr.c 67d15caf88a1a9528283d68ff578e024cf9fe810b517bb0343e5aaf695ad97dd
|
||||||
@ -998,7 +998,7 @@ F test/collate9.test 3adcc799229545940df2f25308dd1ad65869145a
|
|||||||
F test/collateA.test b8218ab90d1fa5c59dcf156efabb1b2599c580d6
|
F test/collateA.test b8218ab90d1fa5c59dcf156efabb1b2599c580d6
|
||||||
F test/collateB.test 1e68906951b846570f29f20102ed91d29e634854ee47454d725f2151ecac0b95
|
F test/collateB.test 1e68906951b846570f29f20102ed91d29e634854ee47454d725f2151ecac0b95
|
||||||
F test/colmeta.test 2c765ea61ee37bc43bbe6d6047f89004e6508eb1
|
F test/colmeta.test 2c765ea61ee37bc43bbe6d6047f89004e6508eb1
|
||||||
F test/colname.test 87ad5458bb8709312dac0d6755fd30e8e4ca83298d0a9ef6e5c24277a3c3390e
|
F test/colname.test 387e880eeac0889900f7b3e9703c375515f5d323f71fd4f2bb5428a4ac8e2023
|
||||||
F test/columncount.test 6fe99c2f35738b0129357a1cf3fa483f76140f4cd8a89014c88c33c876d2638f
|
F test/columncount.test 6fe99c2f35738b0129357a1cf3fa483f76140f4cd8a89014c88c33c876d2638f
|
||||||
F test/conflict.test b705cddf025a675d3c13d62fa78ab1e2696fb8e07a3d7cccce1596ff8b301492
|
F test/conflict.test b705cddf025a675d3c13d62fa78ab1e2696fb8e07a3d7cccce1596ff8b301492
|
||||||
F test/conflict2.test 5557909ce683b1073982f5d1b61dfb1d41e369533bfdaf003180c5bc87282dd1
|
F test/conflict2.test 5557909ce683b1073982f5d1b61dfb1d41e369533bfdaf003180c5bc87282dd1
|
||||||
@ -1868,7 +1868,7 @@ F test/trans.test 45f6f9ab6f66a7b5744f1caac06b558f95da62501916906cf55586a896f9f4
|
|||||||
F test/trans2.test 62bd045bfc7a1c14c5ba83ba64d21ade31583f76
|
F test/trans2.test 62bd045bfc7a1c14c5ba83ba64d21ade31583f76
|
||||||
F test/trans3.test 91a100e5412b488e22a655fe423a14c26403ab94
|
F test/trans3.test 91a100e5412b488e22a655fe423a14c26403ab94
|
||||||
F test/transitive1.test f8ee983600b33d167da1885657f064aec404e1c0d0bc8765fdf163f4c749237a
|
F test/transitive1.test f8ee983600b33d167da1885657f064aec404e1c0d0bc8765fdf163f4c749237a
|
||||||
F test/trigger1.test 02cc64dc98278816c1c1ed8e472e18db8edbad88f37018bf46223e9614831963
|
F test/trigger1.test 2834f8830a1ae338d95c2e3ea0c2a7bc4cda126cdeb715004cf0fd071892e44f
|
||||||
F test/trigger2.test 30fcb3a6aa6782020d47968735ee6086ed795f73a7affa9406c8d5a36e7b5265
|
F test/trigger2.test 30fcb3a6aa6782020d47968735ee6086ed795f73a7affa9406c8d5a36e7b5265
|
||||||
F test/trigger3.test aa640bb2bbb03edd5ff69c055117ea088f121945
|
F test/trigger3.test aa640bb2bbb03edd5ff69c055117ea088f121945
|
||||||
F test/trigger4.test 74700b76ebf3947b2f7a92405141eb2cf2a5d359
|
F test/trigger4.test 74700b76ebf3947b2f7a92405141eb2cf2a5d359
|
||||||
@ -2191,8 +2191,15 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
|||||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||||
P 1ec2961a0341619ae88832942b52606b3246fc0de07ca6da0300e4bfc656ecf0
|
P 5fa0c2a026f0467af3a76ea80cee8168b7a49553c350f642d1dff02ff9e7aeed 003e1c8c27824cb917b3869bdf9000f32ff0b6887a2aff8516712cfe865cf34d 96a591c202cb4218999ece3de063bf466b6fd81bd23383893f3913ecb52dda36 3a256a1667b15702dc5048fdf2fdba9c1e551106ce8cf391360f156fab35ecc5 b41e71208abcdf988f57c3fd7e6a372bbaf442c32a8e2c051beb8d45c8001e0f
|
||||||
R 3e80a1a8d16383b10a9edc0a3a535e00
|
R e8336e7694086906c728a80981692620
|
||||||
|
T *branch * pending-3.46
|
||||||
|
T *sym-pending-3.46 *
|
||||||
|
T +closed 003e1c8c27824cb917b3869bdf9000f32ff0b6887a2aff8516712cfe865cf34d
|
||||||
|
T +closed 3a256a1667b15702dc5048fdf2fdba9c1e551106ce8cf391360f156fab35ecc5
|
||||||
|
T +closed 96a591c202cb4218999ece3de063bf466b6fd81bd23383893f3913ecb52dda36
|
||||||
|
T +closed b41e71208abcdf988f57c3fd7e6a372bbaf442c32a8e2c051beb8d45c8001e0f
|
||||||
|
T -sym-trunk *
|
||||||
U dan
|
U dan
|
||||||
Z 4379dfd9de0672673743bdb6b799c4de
|
Z c49a8bf6544e23e44208d0244df34726
|
||||||
# Remove this line to create a well-formed Fossil manifest.
|
# Remove this line to create a well-formed Fossil manifest.
|
||||||
|
@ -1 +1 @@
|
|||||||
5fa0c2a026f0467af3a76ea80cee8168b7a49553c350f642d1dff02ff9e7aeed
|
6dc6472175bccbed15ebf6811c209d1a0b5fad60158fb32040210f2cdae916a6
|
@ -5306,15 +5306,14 @@ expr_code_doover:
|
|||||||
}
|
}
|
||||||
assert( !ExprHasProperty(pExpr, EP_IntValue) );
|
assert( !ExprHasProperty(pExpr, EP_IntValue) );
|
||||||
if( pExpr->affExpr==OE_Ignore ){
|
if( pExpr->affExpr==OE_Ignore ){
|
||||||
sqlite3VdbeAddOp4(
|
sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_OK, OE_Ignore);
|
||||||
v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0);
|
|
||||||
VdbeCoverage(v);
|
VdbeCoverage(v);
|
||||||
}else{
|
}else{
|
||||||
sqlite3HaltConstraint(pParse,
|
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
|
||||||
|
sqlite3VdbeAddOp3(v, OP_Halt,
|
||||||
pParse->pTriggerTab ? SQLITE_CONSTRAINT_TRIGGER : SQLITE_ERROR,
|
pParse->pTriggerTab ? SQLITE_CONSTRAINT_TRIGGER : SQLITE_ERROR,
|
||||||
pExpr->affExpr, pExpr->u.zToken, 0, 0);
|
pExpr->affExpr, r1);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1328,7 +1328,8 @@ static Trigger *fkActionTrigger(
|
|||||||
SrcList *pSrc;
|
SrcList *pSrc;
|
||||||
Expr *pRaise;
|
Expr *pRaise;
|
||||||
|
|
||||||
pRaise = sqlite3Expr(db, TK_RAISE, "FOREIGN KEY constraint failed");
|
pRaise = sqlite3Expr(db, TK_STRING, "FOREIGN KEY constraint failed"),
|
||||||
|
pRaise = sqlite3PExpr(pParse, TK_RAISE, pRaise, 0);
|
||||||
if( pRaise ){
|
if( pRaise ){
|
||||||
pRaise->affExpr = OE_Abort;
|
pRaise->affExpr = OE_Abort;
|
||||||
}
|
}
|
||||||
|
@ -1658,8 +1658,8 @@ expr(A) ::= RAISE LP IGNORE RP. {
|
|||||||
A->affExpr = OE_Ignore;
|
A->affExpr = OE_Ignore;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expr(A) ::= RAISE LP raisetype(T) COMMA nm(Z) RP. {
|
expr(A) ::= RAISE LP raisetype(T) COMMA expr(Z) RP. {
|
||||||
A = sqlite3ExprAlloc(pParse->db, TK_RAISE, &Z, 1);
|
A = sqlite3PExpr(pParse, TK_RAISE, Z, 0);
|
||||||
if( A ) {
|
if( A ) {
|
||||||
A->affExpr = (char)T;
|
A->affExpr = (char)T;
|
||||||
}
|
}
|
||||||
|
@ -818,7 +818,8 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
|
|||||||
case OE_Ignore: zType = "ignore"; break;
|
case OE_Ignore: zType = "ignore"; break;
|
||||||
}
|
}
|
||||||
assert( !ExprHasProperty(pExpr, EP_IntValue) );
|
assert( !ExprHasProperty(pExpr, EP_IntValue) );
|
||||||
sqlite3TreeViewLine(pView, "RAISE %s(%Q)", zType, pExpr->u.zToken);
|
sqlite3TreeViewLine(pView, "RAISE %s", zType);
|
||||||
|
sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
56
src/vdbe.c
56
src/vdbe.c
@ -1214,7 +1214,7 @@ case OP_HaltIfNull: { /* in3 */
|
|||||||
/* no break */ deliberate_fall_through
|
/* no break */ deliberate_fall_through
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: Halt P1 P2 * P4 P5
|
/* Opcode: Halt P1 P2 P3 P4 P5
|
||||||
**
|
**
|
||||||
** Exit immediately. All open cursors, etc are closed
|
** Exit immediately. All open cursors, etc are closed
|
||||||
** automatically.
|
** automatically.
|
||||||
@ -1227,18 +1227,22 @@ case OP_HaltIfNull: { /* in3 */
|
|||||||
** then back out all changes that have occurred during this execution of the
|
** then back out all changes that have occurred during this execution of the
|
||||||
** VDBE, but do not rollback the transaction.
|
** VDBE, but do not rollback the transaction.
|
||||||
**
|
**
|
||||||
** If P4 is not null then it is an error message string.
|
** If P3 is not zero and P4 is NULL, then P3 is a register that holds the
|
||||||
|
** text of an error message.
|
||||||
**
|
**
|
||||||
** P5 is a value between 0 and 4, inclusive, that modifies the P4 string.
|
** If P3 is zero and P4 is not null then the error message string is held
|
||||||
|
** in P4.
|
||||||
|
**
|
||||||
|
** P5 is a value between 1 and 4, inclusive, then the P4 error message
|
||||||
|
** string is modified as follows:
|
||||||
**
|
**
|
||||||
** 0: (no change)
|
|
||||||
** 1: NOT NULL constraint failed: P4
|
** 1: NOT NULL constraint failed: P4
|
||||||
** 2: UNIQUE constraint failed: P4
|
** 2: UNIQUE constraint failed: P4
|
||||||
** 3: CHECK constraint failed: P4
|
** 3: CHECK constraint failed: P4
|
||||||
** 4: FOREIGN KEY constraint failed: P4
|
** 4: FOREIGN KEY constraint failed: P4
|
||||||
**
|
**
|
||||||
** If P5 is not zero and P4 is NULL, then everything after the ":" is
|
** If P3 is zero and P5 is not zero and P4 is NULL, then everything after
|
||||||
** omitted.
|
** the ":" is omitted.
|
||||||
**
|
**
|
||||||
** There is an implied "Halt 0 0 0" instruction inserted at the very end of
|
** There is an implied "Halt 0 0 0" instruction inserted at the very end of
|
||||||
** every program. So a jump past the last instruction of the program
|
** every program. So a jump past the last instruction of the program
|
||||||
@ -1251,6 +1255,9 @@ case OP_Halt: {
|
|||||||
#ifdef SQLITE_DEBUG
|
#ifdef SQLITE_DEBUG
|
||||||
if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); }
|
if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); }
|
||||||
#endif
|
#endif
|
||||||
|
assert( pOp->p4type==P4_NOTUSED
|
||||||
|
|| pOp->p4type==P4_STATIC
|
||||||
|
|| pOp->p4type==P4_DYNAMIC );
|
||||||
|
|
||||||
/* A deliberately coded "OP_Halt SQLITE_INTERNAL * * * *" opcode indicates
|
/* A deliberately coded "OP_Halt SQLITE_INTERNAL * * * *" opcode indicates
|
||||||
** something is wrong with the code generator. Raise an assertion in order
|
** something is wrong with the code generator. Raise an assertion in order
|
||||||
@ -1281,7 +1288,12 @@ case OP_Halt: {
|
|||||||
p->errorAction = (u8)pOp->p2;
|
p->errorAction = (u8)pOp->p2;
|
||||||
assert( pOp->p5<=4 );
|
assert( pOp->p5<=4 );
|
||||||
if( p->rc ){
|
if( p->rc ){
|
||||||
if( pOp->p5 ){
|
if( pOp->p3>0 && pOp->p4type==P4_NOTUSED ){
|
||||||
|
const char *zErr;
|
||||||
|
assert( pOp->p3<=(p->nMem + 1 - p->nCursor) );
|
||||||
|
zErr = sqlite3ValueText(&aMem[pOp->p3], SQLITE_UTF8);
|
||||||
|
sqlite3VdbeError(p, "%s", zErr);
|
||||||
|
}else if( pOp->p5 ){
|
||||||
static const char * const azType[] = { "NOT NULL", "UNIQUE", "CHECK",
|
static const char * const azType[] = { "NOT NULL", "UNIQUE", "CHECK",
|
||||||
"FOREIGN KEY" };
|
"FOREIGN KEY" };
|
||||||
testcase( pOp->p5==1 );
|
testcase( pOp->p5==1 );
|
||||||
@ -4324,23 +4336,23 @@ case OP_OpenWrite:
|
|||||||
if( pDb->pSchema->file_format < p->minWriteFileFormat ){
|
if( pDb->pSchema->file_format < p->minWriteFileFormat ){
|
||||||
p->minWriteFileFormat = pDb->pSchema->file_format;
|
p->minWriteFileFormat = pDb->pSchema->file_format;
|
||||||
}
|
}
|
||||||
|
if( pOp->p5 & OPFLAG_P2ISREG ){
|
||||||
|
assert( p2>0 );
|
||||||
|
assert( p2<=(u32)(p->nMem+1 - p->nCursor) );
|
||||||
|
pIn2 = &aMem[p2];
|
||||||
|
assert( memIsValid(pIn2) );
|
||||||
|
assert( (pIn2->flags & MEM_Int)!=0 );
|
||||||
|
sqlite3VdbeMemIntegerify(pIn2);
|
||||||
|
p2 = (int)pIn2->u.i;
|
||||||
|
/* The p2 value always comes from a prior OP_CreateBtree opcode and
|
||||||
|
** that opcode will always set the p2 value to 2 or more or else fail.
|
||||||
|
** If there were a failure, the prepared statement would have halted
|
||||||
|
** before reaching this instruction. */
|
||||||
|
assert( p2>=2 );
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
wrFlag = 0;
|
wrFlag = 0;
|
||||||
}
|
assert( (pOp->p5 & OPFLAG_P2ISREG)==0 );
|
||||||
if( pOp->p5 & OPFLAG_P2ISREG ){
|
|
||||||
assert( p2>0 );
|
|
||||||
assert( p2<=(u32)(p->nMem+1 - p->nCursor) );
|
|
||||||
assert( pOp->opcode==OP_OpenWrite );
|
|
||||||
pIn2 = &aMem[p2];
|
|
||||||
assert( memIsValid(pIn2) );
|
|
||||||
assert( (pIn2->flags & MEM_Int)!=0 );
|
|
||||||
sqlite3VdbeMemIntegerify(pIn2);
|
|
||||||
p2 = (int)pIn2->u.i;
|
|
||||||
/* The p2 value always comes from a prior OP_CreateBtree opcode and
|
|
||||||
** that opcode will always set the p2 value to 2 or more or else fail.
|
|
||||||
** If there were a failure, the prepared statement would have halted
|
|
||||||
** before reaching this instruction. */
|
|
||||||
assert( p2>=2 );
|
|
||||||
}
|
}
|
||||||
if( pOp->p4type==P4_KEYINFO ){
|
if( pOp->p4type==P4_KEYINFO ){
|
||||||
pKeyInfo = pOp->p4.pKeyInfo;
|
pKeyInfo = pOp->p4.pKeyInfo;
|
||||||
|
@ -3170,7 +3170,7 @@ static int whereLoopAddBtreeIndex(
|
|||||||
|| (iCol>=0 && nInMul==0 && saved_nEq==pProbe->nKeyCol-1)
|
|| (iCol>=0 && nInMul==0 && saved_nEq==pProbe->nKeyCol-1)
|
||||||
){
|
){
|
||||||
if( iCol==XN_ROWID || pProbe->uniqNotNull
|
if( iCol==XN_ROWID || pProbe->uniqNotNull
|
||||||
|| (pProbe->nKeyCol==1 && pProbe->onError && eOp==WO_EQ)
|
|| (pProbe->nKeyCol==1 && pProbe->onError && (eOp & WO_EQ))
|
||||||
){
|
){
|
||||||
pNew->wsFlags |= WHERE_ONEROW;
|
pNew->wsFlags |= WHERE_ONEROW;
|
||||||
}else{
|
}else{
|
||||||
|
@ -424,7 +424,7 @@ do_catchsql_test colname-9.400 {
|
|||||||
#
|
#
|
||||||
do_catchsql_test colname-9.410 {
|
do_catchsql_test colname-9.410 {
|
||||||
CREATE TABLE t5 AS SELECT RAISE(abort,a);
|
CREATE TABLE t5 AS SELECT RAISE(abort,a);
|
||||||
} {1 {RAISE() may only be used within a trigger-program}}
|
} {1 {no such column: a}}
|
||||||
|
|
||||||
# Make sure the quotation marks get removed from the column names
|
# Make sure the quotation marks get removed from the column names
|
||||||
# when constructing a new table from an aggregate SELECT.
|
# when constructing a new table from an aggregate SELECT.
|
||||||
|
@ -838,4 +838,17 @@ do_catchsql_test trigger1-23.1 {
|
|||||||
END;
|
END;
|
||||||
} {1 {near "#1": syntax error}}
|
} {1 {near "#1": syntax error}}
|
||||||
|
|
||||||
|
# 2024-05-08 Allow arbitrary expressions as the 2nd argument to RAISE().
|
||||||
|
#
|
||||||
|
do_catchsql_test trigger1-24.1 {
|
||||||
|
CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN
|
||||||
|
SELECT raise(abort,format('attempt to insert %d where is not a power of 2',new.a))
|
||||||
|
WHERE (new.a & (new.a-1))!=0;
|
||||||
|
END;
|
||||||
|
INSERT INTO t1 VALUES(0),(1),(2),(4),(8),(65536);
|
||||||
|
} {0 {}}
|
||||||
|
do_catchsql_test trigger1-24.2 {
|
||||||
|
INSERT INTO t1 VALUES(9876);
|
||||||
|
} {1 {attempt to insert 9876 where is not a power of 2}}
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
Loading…
Reference in New Issue
Block a user