1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-30 19:03:16 +03:00

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:
dan
2024-05-17 14:26:32 +00:00
18 changed files with 268 additions and 121 deletions

View File

@ -5306,15 +5306,14 @@ expr_code_doover:
}
assert( !ExprHasProperty(pExpr, EP_IntValue) );
if( pExpr->affExpr==OE_Ignore ){
sqlite3VdbeAddOp4(
v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0);
sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_OK, OE_Ignore);
VdbeCoverage(v);
}else{
sqlite3HaltConstraint(pParse,
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
sqlite3VdbeAddOp3(v, OP_Halt,
pParse->pTriggerTab ? SQLITE_CONSTRAINT_TRIGGER : SQLITE_ERROR,
pExpr->affExpr, pExpr->u.zToken, 0, 0);
pExpr->affExpr, r1);
}
break;
}
#endif

View File

@ -1328,7 +1328,8 @@ static Trigger *fkActionTrigger(
SrcList *pSrc;
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 ){
pRaise->affExpr = OE_Abort;
}

View File

@ -1658,8 +1658,8 @@ expr(A) ::= RAISE LP IGNORE RP. {
A->affExpr = OE_Ignore;
}
}
expr(A) ::= RAISE LP raisetype(T) COMMA nm(Z) RP. {
A = sqlite3ExprAlloc(pParse->db, TK_RAISE, &Z, 1);
expr(A) ::= RAISE LP raisetype(T) COMMA expr(Z) RP. {
A = sqlite3PExpr(pParse, TK_RAISE, Z, 0);
if( A ) {
A->affExpr = (char)T;
}

View File

@ -818,7 +818,8 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
case OE_Ignore: zType = "ignore"; break;
}
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;
}
#endif

View File

@ -1214,7 +1214,7 @@ case OP_HaltIfNull: { /* in3 */
/* 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
** automatically.
@ -1227,18 +1227,22 @@ case OP_HaltIfNull: { /* in3 */
** then back out all changes that have occurred during this execution of the
** 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
** 2: UNIQUE constraint failed: P4
** 3: CHECK constraint failed: P4
** 4: FOREIGN KEY constraint failed: P4
**
** If P5 is not zero and P4 is NULL, then everything after the ":" is
** omitted.
** If P3 is zero and P5 is not zero and P4 is NULL, then everything after
** the ":" is omitted.
**
** 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
@ -1251,6 +1255,9 @@ case OP_Halt: {
#ifdef SQLITE_DEBUG
if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); }
#endif
assert( pOp->p4type==P4_NOTUSED
|| pOp->p4type==P4_STATIC
|| pOp->p4type==P4_DYNAMIC );
/* A deliberately coded "OP_Halt SQLITE_INTERNAL * * * *" opcode indicates
** something is wrong with the code generator. Raise an assertion in order
@ -1281,7 +1288,12 @@ case OP_Halt: {
p->errorAction = (u8)pOp->p2;
assert( pOp->p5<=4 );
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",
"FOREIGN KEY" };
testcase( pOp->p5==1 );
@ -4324,23 +4336,23 @@ case OP_OpenWrite:
if( pDb->pSchema->file_format < p->minWriteFileFormat ){
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{
wrFlag = 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 );
assert( (pOp->p5 & OPFLAG_P2ISREG)==0 );
}
if( pOp->p4type==P4_KEYINFO ){
pKeyInfo = pOp->p4.pKeyInfo;

View File

@ -3170,7 +3170,7 @@ static int whereLoopAddBtreeIndex(
|| (iCol>=0 && nInMul==0 && saved_nEq==pProbe->nKeyCol-1)
){
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;
}else{