From 670a1baa28a568e65cd1dc09dfb02b3942e0d572 Mon Sep 17 00:00:00 2001 From: Liu Hongyang Date: Sat, 23 Aug 2025 16:37:01 +0800 Subject: [PATCH] fix binlog not skip temp db Signed-off-by: Liu Hongyang --- patch/0006-Support-Binlog.patch | 214 ++++++++++++++++++++------------ 1 file changed, 134 insertions(+), 80 deletions(-) diff --git a/patch/0006-Support-Binlog.patch b/patch/0006-Support-Binlog.patch index faaee02..66fd947 100644 --- a/patch/0006-Support-Binlog.patch +++ b/patch/0006-Support-Binlog.patch @@ -1,14 +1,14 @@ -From d9bf27e15f4d3ebe73de27fa608c06c5049d34e3 Mon Sep 17 00:00:00 2001 +From 8ebfac479cbf79a2dfa38297733bf83eae8d27fe Mon Sep 17 00:00:00 2001 From: Liu Hongyang -Date: Fri, 15 Aug 2025 14:28:12 +0800 -Subject: [PATCH 06/12] Support-Binlog +Date: Mon, 25 Aug 2025 16:20:43 +0800 +[PATCH 06/12] Support-Binlog --- - src/sqlite3.c | 1522 ++++++++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 1513 insertions(+), 9 deletions(-) + src/sqlite3.c | 1576 ++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 1567 insertions(+), 9 deletions(-) diff --git a/src/sqlite3.c b/src/sqlite3.c -index b433dfb..4105866 100644 +index b433dfb..21cd9c9 100644 --- a/src/sqlite3.c +++ b/src/sqlite3.c @@ -2938,7 +2938,9 @@ SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*); @@ -42,7 +42,7 @@ index b433dfb..4105866 100644 /* ** CAPI3REF: Number of columns in a result set ** METHOD: sqlite3_stmt -@@ -17617,6 +17632,201 @@ typedef struct CodecParameter { +@@ -17617,6 +17632,202 @@ typedef struct CodecParameter { } CodecParameter; #endif /* defined(SQLITE_HAS_CODEC) && defined(SQLITE_CODEC_ATTACH_CHANGED) */ @@ -149,6 +149,7 @@ index b433dfb..4105866 100644 + int op; // one of the SQLITE_INSERT, SQLITE_UPDATE, SQLITE_DELETE + sqlite3_int64 rowid; // rowid of changed data, -1 for without rowid table + sqlite3_uint64 nData; // size of pData ++ int nZero; // extra zero bytes at the end of pData + const char *pData; // pointer to the row data in record format +} BinlogRow; + @@ -204,6 +205,7 @@ index b433dfb..4105866 100644 + STMT_TYPE_ROLLBACK_TRANSACTION, + STMT_TYPE_PRAGMA, + STMT_TYPE_SAVEPOINT, ++ STMT_TYPE_TEMP_DB_MODIFY, +} StmtType; + +typedef struct Sqlite3BinlogStmt { @@ -234,8 +236,7 @@ index b433dfb..4105866 100644 +SQLITE_PRIVATE int sqlite3IsSkipWriteBinlog(Vdbe *p); +SQLITE_PRIVATE int sqlite3IsRowBasedBinlog(Vdbe *p); +SQLITE_PRIVATE Table *sqlite3BinlogFindTable(BtCursor *pC); -+SQLITE_PRIVATE void sqlite3StoreBinlogRowData(Vdbe *p, BtCursor *pCursor, sqlite3_uint64 nData, -+ const char *pData, int op, sqlite3_int64 rowid); ++SQLITE_PRIVATE void sqlite3StoreBinlogRowData(Vdbe *p, BtCursor *pCursor, const BinlogRow *pRow); +SQLITE_PRIVATE void sqlite3FreeBinlogRowData(Vdbe *p); +SQLITE_PRIVATE char *sqlite3BinlogGetNthCol(sqlite3 *db, const Table *pTab, const BinlogRow *pRow, int iCol); +/************** Binlog typedef in sqlite3 END ************************************/ @@ -244,7 +245,7 @@ index b433dfb..4105866 100644 /* ** Each database connection is an instance of the following structure. */ -@@ -17770,6 +17980,9 @@ struct sqlite3 { +@@ -17770,6 +17981,9 @@ struct sqlite3 { #if defined(SQLITE_HAS_CODEC) && defined(SQLITE_CODEC_ATTACH_CHANGED) CodecParameter codecParm; #endif /* defined(SQLITE_HAS_CODEC) && defined(SQLITE_CODEC_ATTACH_CHANGED) */ @@ -254,7 +255,7 @@ index b433dfb..4105866 100644 }; /* -@@ -23666,6 +23879,14 @@ struct Vdbe { +@@ -23666,6 +23880,14 @@ struct Vdbe { int startPos; int addedRows; #endif /* SQLITE_SHARED_BLOCK_OPTIMIZATION */ @@ -269,7 +270,7 @@ index b433dfb..4105866 100644 }; /* -@@ -88435,7 +88656,11 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){ +@@ -88435,7 +88657,11 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){ rc = sqlite3BtreeCommitPhaseOne(pBt, 0); } } @@ -282,7 +283,7 @@ index b433dfb..4105866 100644 /* Do the commit only if all databases successfully complete phase 1. ** If one of the BtreeCommitPhaseOne() calls fails, this indicates an ** IO error while deleting or truncating a journal file. It is unlikely, -@@ -88583,6 +88808,9 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){ +@@ -88583,6 +88809,9 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){ ** transaction is already guaranteed, but some stray 'cold' journals ** may be lying around. Returning an error code won't help matters. */ @@ -292,7 +293,7 @@ index b433dfb..4105866 100644 disable_simulated_io_errors(); sqlite3BeginBenignMalloc(); for(i=0; inDb; i++){ -@@ -88868,6 +89096,9 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){ +@@ -88868,6 +89097,9 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){ }else if( eStatementOp==0 ){ if( p->rc==SQLITE_OK || p->errorAction==OE_Fail ){ eStatementOp = SAVEPOINT_RELEASE; @@ -302,7 +303,7 @@ index b433dfb..4105866 100644 }else if( p->errorAction==OE_Abort ){ eStatementOp = SAVEPOINT_ROLLBACK; }else{ -@@ -89090,6 +89321,9 @@ SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){ +@@ -89090,6 +89322,9 @@ SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){ fclose(out); } } @@ -312,7 +313,7 @@ index b433dfb..4105866 100644 #endif return p->rc & db->errMask; } -@@ -89194,6 +89428,9 @@ static void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){ +@@ -89194,6 +89429,9 @@ static void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){ sqlite3DbFree(db, p->aScan); } #endif @@ -322,7 +323,7 @@ index b433dfb..4105866 100644 } /* -@@ -91886,6 +92123,44 @@ SQLITE_API int sqlite3_set_droptable_handle(sqlite3 *db, void (*xFunc)(sqlite3*, +@@ -91886,6 +92124,44 @@ SQLITE_API int sqlite3_set_droptable_handle(sqlite3 *db, void (*xFunc)(sqlite3*, } #endif /* SQLITE_ENABLE_DROPTABLE_CALLBACK */ @@ -367,7 +368,7 @@ index b433dfb..4105866 100644 /* ** This is the top-level implementation of sqlite3_step(). Call ** sqlite3Step() to do most of the work. If a schema error occurs, -@@ -99189,6 +99464,12 @@ case OP_Found: { /* jump, in3, ncycle */ +@@ -99189,6 +99465,12 @@ case OP_Found: { /* jump, in3, ncycle */ pC->nullRow = 1-alreadyExists; pC->deferredMoveto = 0; pC->cacheStatus = CACHE_STALE; @@ -380,7 +381,7 @@ index b433dfb..4105866 100644 if( pOp->opcode==OP_Found ){ VdbeBranchTaken(alreadyExists!=0,2); if( alreadyExists ) goto jump_to_p2; -@@ -99584,6 +99865,15 @@ case OP_Insert: { +@@ -99584,6 +99866,16 @@ case OP_Insert: { } x.pKey = 0; assert( BTREE_PREFORMAT==OPFLAG_PREFORMAT ); @@ -389,14 +390,15 @@ index b433dfb..4105866 100644 + && !sqlite3IsSkipWriteBinlog(p) + && sqlite3IsRowBasedBinlog(p) + && sqlite3TransferLogEventType(p->stmtType) == BINLOG_EVENT_TYPE_DML ) { -+ sqlite3StoreBinlogRowData(p, pC->uc.pCursor, x.nData, pData->z, -+ (pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT, x.nKey); ++ BinlogRow rowData = { ++ (pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT,x.nKey, x.nData, x.nZero, pData->z}; ++ sqlite3StoreBinlogRowData(p, pC->uc.pCursor, &rowData); + } +#endif rc = sqlite3BtreeInsert(pC->uc.pCursor, &x, (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION|OPFLAG_PREFORMAT)), seekResult -@@ -99699,6 +99989,27 @@ case OP_Delete: { +@@ -99699,6 +99991,29 @@ case OP_Delete: { assert( CORRUPT_DB || pC->movetoTarget==iKey ); } #endif @@ -405,7 +407,8 @@ index b433dfb..4105866 100644 + && sqlite3IsRowBasedBinlog(p) + && sqlite3TransferLogEventType(p->stmtType) == BINLOG_EVENT_TYPE_DML ){ + if (pC->isTable) { -+ sqlite3StoreBinlogRowData(p, pC->uc.pCursor, 0, NULL, SQLITE_DELETE, sqlite3BtreeIntegerKey(pC->uc.pCursor)); ++ BinlogRow rowData = {SQLITE_DELETE, sqlite3BtreeIntegerKey(pC->uc.pCursor), 0, 0, NULL}; ++ sqlite3StoreBinlogRowData(p, pC->uc.pCursor, &rowData); + } else { + Table *pBinlogTab = sqlite3BinlogFindTable(pC->uc.pCursor); + if (pBinlogTab != NULL && !HasRowid(pBinlogTab)) { @@ -416,7 +419,8 @@ index b433dfb..4105866 100644 + int isUseTmpData = pOp->p4type == P4_TABLE && p->nDataTmp != 0 && p->pDataTmp != NULL; + sqlite3_uint64 nData = isUseTmpData ? p->nDataTmp : pC->szRow; + const char *pData = isUseTmpData ? p->pDataTmp : (const char *)pC->aRow; -+ sqlite3StoreBinlogRowData(p, pC->uc.pCursor, nData, pData, SQLITE_DELETE, -1); ++ BinlogRow rowData = {SQLITE_DELETE, -1, nData, 0, pData}; ++ sqlite3StoreBinlogRowData(p, pC->uc.pCursor, &rowData); + } + } + } @@ -424,7 +428,7 @@ index b433dfb..4105866 100644 /* If the update-hook or pre-update-hook will be invoked, set zDb to ** the name of the db to pass as to it. Also set local pTab to a copy -@@ -100322,6 +100633,14 @@ case OP_IdxInsert: { /* in2 */ +@@ -100322,6 +100637,15 @@ case OP_IdxInsert: { /* in2 */ x.pKey = pIn2->z; x.aMem = aMem + pOp->p3; x.nMem = (u16)pOp->p4.i; @@ -433,36 +437,37 @@ index b433dfb..4105866 100644 + && !sqlite3IsSkipWriteBinlog(p) + && sqlite3IsRowBasedBinlog(p) + && sqlite3TransferLogEventType(p->stmtType) == BINLOG_EVENT_TYPE_DML ){ -+ sqlite3StoreBinlogRowData(p, pC->uc.pCursor, x.nKey, pIn2->z, SQLITE_INSERT, -1); ++ BinlogRow rowData = {SQLITE_INSERT, -1, x.nKey, 0, pIn2->z}; ++ sqlite3StoreBinlogRowData(p, pC->uc.pCursor, &rowData); + } +#endif rc = sqlite3BtreeInsert(pC->uc.pCursor, &x, (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION|OPFLAG_PREFORMAT)), ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0) -@@ -116953,7 +117272,11 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable( +@@ -116953,7 +117277,11 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable( renameReloadSchema(pParse, iDb, INITFLAG_AlterRename); renameTestSchema(pParse, zDb, iDb==1, "after rename", 0); - +#ifdef SQLITE_ENABLE_BINLOG + if( v ){ -+ v->stmtType = STMT_TYPE_ALTER_RENAME_TABLE; ++ v->stmtType = iDb==1 ? STMT_TYPE_TEMP_DB_MODIFY : STMT_TYPE_ALTER_RENAME_TABLE; + } +#endif exit_rename_table: sqlite3SrcListDelete(db, pSrc); sqlite3DbFree(db, zName); -@@ -117135,6 +117458,9 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ +@@ -117135,6 +117463,9 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ zTab, zDb ); } +#ifdef SQLITE_ENABLE_BINLOG -+ v->stmtType = STMT_TYPE_ALTER_ADD_COL; ++ v->stmtType = iDb==1 ? STMT_TYPE_TEMP_DB_MODIFY : STMT_TYPE_ALTER_ADD_COL; +#endif } } -@@ -117346,7 +117672,13 @@ SQLITE_PRIVATE void sqlite3AlterRenameColumn( +@@ -117346,7 +117677,13 @@ SQLITE_PRIVATE void sqlite3AlterRenameColumn( /* Drop and reload the database schema. */ renameReloadSchema(pParse, iSchema, INITFLAG_AlterRename); renameTestSchema(pParse, zDb, iSchema==1, "after rename", 1); @@ -471,13 +476,13 @@ index b433dfb..4105866 100644 + Vdbe *v = NULL; + v = sqlite3GetVdbe(pParse); + if( v ){ -+ v->stmtType = STMT_TYPE_ALTER_RENAME_COL; ++ v->stmtType = iSchema==1 ? STMT_TYPE_TEMP_DB_MODIFY : STMT_TYPE_ALTER_RENAME_COL; + } +#endif exit_rename_column: sqlite3SrcListDelete(db, pSrc); sqlite3DbFree(db, zOld); -@@ -118957,7 +119289,13 @@ SQLITE_PRIVATE void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, const T +@@ -118957,7 +119294,13 @@ SQLITE_PRIVATE void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, const T sqlite3VdbeAddOp2(v, OP_Next, iCur, addr+1); VdbeCoverage(v); sqlite3VdbeJumpHere(v, addr); } @@ -486,23 +491,23 @@ index b433dfb..4105866 100644 + Vdbe *v = NULL; + v = sqlite3GetVdbe(pParse); + if( v ){ -+ v->stmtType = STMT_TYPE_ALTER_DROP_COL; ++ v->stmtType = iDb==1 ? STMT_TYPE_TEMP_DB_MODIFY : STMT_TYPE_ALTER_DROP_COL; + } +#endif exit_drop_column: sqlite3DbFree(db, zCol); sqlite3SrcListDelete(db, pSrc); -@@ -123295,6 +123633,9 @@ SQLITE_PRIVATE void sqlite3StartTable( +@@ -123295,6 +123638,9 @@ SQLITE_PRIVATE void sqlite3StartTable( sqlite3VdbeAddOp3(v, OP_Insert, 0, reg3, reg1); sqlite3VdbeChangeP5(v, OPFLAG_APPEND); sqlite3VdbeAddOp0(v, OP_Close); +#ifdef SQLITE_ENABLE_BINLOG -+ v->stmtType = STMT_TYPE_CREATE_TABLE; ++ v->stmtType = iDb==1 ? STMT_TYPE_TEMP_DB_MODIFY : STMT_TYPE_CREATE_TABLE; +#endif } /* Normal (non-error) return. */ -@@ -124963,7 +125304,13 @@ SQLITE_PRIVATE void sqlite3CreateView( +@@ -124963,7 +125309,13 @@ SQLITE_PRIVATE void sqlite3CreateView( /* Use sqlite3EndTable() to add the view to the schema table */ sqlite3EndTable(pParse, 0, &sEnd, 0, 0); @@ -511,43 +516,47 @@ index b433dfb..4105866 100644 + Vdbe *v = NULL; + v = sqlite3GetVdbe(pParse); + if( v ){ -+ v->stmtType = STMT_TYPE_CREATE_VIEW; ++ v->stmtType = iDb==1 ? STMT_TYPE_TEMP_DB_MODIFY : STMT_TYPE_CREATE_VIEW; + } +#endif create_view_fail: sqlite3SelectDelete(db, pSelect); if( IN_RENAME_OBJECT ){ -@@ -125486,6 +125833,9 @@ SQLITE_PRIVATE void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, +@@ -125486,6 +125838,13 @@ SQLITE_PRIVATE void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, sqlite3FkDropTable(pParse, pName, pTab); } sqlite3CodeDropTable(pParse, pTab, iDb, isView); +#ifdef SQLITE_ENABLE_BINLOG -+ v->stmtType = (isView > 0) ? STMT_TYPE_DROP_VIEW : STMT_TYPE_DROP_TABLE; ++ if( iDb == 1) { ++ v->stmtType = STMT_TYPE_TEMP_DB_MODIFY; ++ } else { ++ v->stmtType = (isView > 0) ? STMT_TYPE_DROP_VIEW : STMT_TYPE_DROP_TABLE; ++ } +#endif } exit_drop_table: -@@ -126344,6 +126694,9 @@ SQLITE_PRIVATE void sqlite3CreateIndex( +@@ -126344,6 +126703,9 @@ SQLITE_PRIVATE void sqlite3CreateIndex( /* A named index with an explicit CREATE INDEX statement */ zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s", onError==OE_None ? "" : " UNIQUE", n, pName->z); +#ifdef SQLITE_ENABLE_BINLOG -+ v->stmtType = STMT_TYPE_CREATE_INDEX; ++ v->stmtType = iDb==1 ? STMT_TYPE_TEMP_DB_MODIFY : STMT_TYPE_CREATE_INDEX; +#endif }else{ /* An automatic index created by a PRIMARY KEY or UNIQUE constraint */ /* zStmt = sqlite3MPrintf(""); */ -@@ -126546,6 +126899,9 @@ SQLITE_PRIVATE void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists +@@ -126546,6 +126908,9 @@ SQLITE_PRIVATE void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists sqlite3ChangeCookie(pParse, iDb); destroyRootPage(pParse, pIndex->tnum, iDb); sqlite3VdbeAddOp4(v, OP_DropIndex, iDb, 0, 0, pIndex->zName, 0); +#ifdef SQLITE_ENABLE_BINLOG -+ v->stmtType = STMT_TYPE_DROP_INDEX; ++ v->stmtType = iDb==1 ? STMT_TYPE_TEMP_DB_MODIFY : STMT_TYPE_DROP_INDEX; +#endif } exit_drop_index: -@@ -127070,6 +127426,9 @@ SQLITE_PRIVATE void sqlite3BeginTransaction(Parse *pParse, int type){ +@@ -127070,6 +127435,9 @@ SQLITE_PRIVATE void sqlite3BeginTransaction(Parse *pParse, int type){ } } sqlite3VdbeAddOp0(v, OP_AutoCommit); @@ -557,7 +566,7 @@ index b433dfb..4105866 100644 } /* -@@ -127092,6 +127451,9 @@ SQLITE_PRIVATE void sqlite3EndTransaction(Parse *pParse, int eType){ +@@ -127092,6 +127460,9 @@ SQLITE_PRIVATE void sqlite3EndTransaction(Parse *pParse, int eType){ v = sqlite3GetVdbe(pParse); if( v ){ sqlite3VdbeAddOp2(v, OP_AutoCommit, 1, isRollback); @@ -567,7 +576,7 @@ index b433dfb..4105866 100644 } } -@@ -127112,6 +127474,9 @@ SQLITE_PRIVATE void sqlite3Savepoint(Parse *pParse, int op, Token *pName){ +@@ -127112,6 +127483,9 @@ SQLITE_PRIVATE void sqlite3Savepoint(Parse *pParse, int op, Token *pName){ return; } sqlite3VdbeAddOp4(v, OP_Savepoint, op, 0, 0, zName, P4_DYNAMIC); @@ -577,7 +586,7 @@ index b433dfb..4105866 100644 } } -@@ -137480,6 +137845,13 @@ typedef int (*sqlite3_loadext_entry)( +@@ -137480,6 +137854,13 @@ typedef int (*sqlite3_loadext_entry)( /* handle after drop table done */ #define sqlite3_set_droptable_handle sqlite3_api->set_droptable_handle #endif /* SQLITE_ENABLE_DROPTABLE_CALLBACK */ @@ -591,7 +600,7 @@ index b433dfb..4105866 100644 #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) -@@ -139533,6 +139905,9 @@ SQLITE_PRIVATE void sqlite3Pragma( +@@ -139533,6 +139914,9 @@ SQLITE_PRIVATE void sqlite3Pragma( if( v==0 ) return; sqlite3VdbeRunOnlyOnce(v); pParse->nMem = 2; @@ -601,7 +610,7 @@ index b433dfb..4105866 100644 /* Interpret the [schema.] part of the pragma statement. iDb is the ** index of the database this pragma is being applied to in db.aDb[]. */ -@@ -152286,7 +152661,13 @@ SQLITE_PRIVATE void sqlite3BeginTrigger( +@@ -152286,7 +152670,13 @@ SQLITE_PRIVATE void sqlite3BeginTrigger( if (tr_tm == TK_INSTEAD){ tr_tm = TK_BEFORE; } @@ -610,13 +619,13 @@ index b433dfb..4105866 100644 + Vdbe *v = NULL; + v = sqlite3GetVdbe(pParse); + if( v ){ -+ v->stmtType = STMT_TYPE_CREATE_TRIGGER; ++ v->stmtType = iDb==1 ? STMT_TYPE_TEMP_DB_MODIFY : STMT_TYPE_CREATE_TRIGGER; + } +#endif /* Build the Trigger object */ pTrigger = (Trigger*)sqlite3DbMallocZero(db, sizeof(Trigger)); if( pTrigger==0 ) goto trigger_cleanup; -@@ -152681,6 +153062,13 @@ SQLITE_PRIVATE void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr) +@@ -152681,6 +153071,13 @@ SQLITE_PRIVATE void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr) goto drop_trigger_cleanup; } sqlite3DropTriggerPtr(pParse, pTrigger); @@ -624,13 +633,13 @@ index b433dfb..4105866 100644 + Vdbe *v = NULL; + v = sqlite3GetVdbe(pParse); + if (v) { -+ v->stmtType = STMT_TYPE_DROP_TRIGGER; ++ v->stmtType = i==0 ? STMT_TYPE_TEMP_DB_MODIFY : STMT_TYPE_DROP_TRIGGER; + } +#endif drop_trigger_cleanup: sqlite3SrcListDelete(db, pName); -@@ -153427,6 +153815,15 @@ SQLITE_PRIVATE void sqlite3CodeRowTrigger( +@@ -153427,6 +153824,15 @@ SQLITE_PRIVATE void sqlite3CodeRowTrigger( assert( tr_tm==TRIGGER_BEFORE || tr_tm==TRIGGER_AFTER ); assert( (op==TK_UPDATE)==(pChanges!=0) ); @@ -646,7 +655,7 @@ index b433dfb..4105866 100644 for(p=pTrigger; p; p=p->pNext){ /* Sanity checking: The schema for the trigger and for the table are -@@ -180656,6 +181053,13 @@ SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){ +@@ -180656,6 +181062,13 @@ SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){ break; } #endif /* SQLITE_SHARED_BLOCK_OPTIMIZATION */ @@ -660,7 +669,7 @@ index b433dfb..4105866 100644 default: { static const struct { int op; /* The opcode */ -@@ -181083,6 +181487,9 @@ SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){ +@@ -181083,6 +181496,9 @@ SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){ sqlite3CollapseDatabaseArray(db); assert( db->nDb<=2 ); assert( db->aDb==db->aDbStatic ); @@ -670,7 +679,7 @@ index b433dfb..4105866 100644 /* Tell the code in notify.c that the connection no longer holds any ** locks and does not require any further unlock-notify callbacks. -@@ -183308,6 +183715,9 @@ opendb_out: +@@ -183308,6 +183724,9 @@ opendb_out: db->mDropSchemaName = NULL; db->xDropTableHandle = NULL; #endif /* SQLITE_ENABLE_DROPTABLE_CALLBACK */ @@ -680,7 +689,7 @@ index b433dfb..4105866 100644 *ppDb = db; #ifdef SQLITE_ENABLE_SQLLOG if( sqlite3GlobalConfig.xSqllog ){ -@@ -256913,6 +257323,1088 @@ static void walLogCheckpointInfo(Wal *pWal, sqlite3 *db, sqlite3_int64 startTime +@@ -256913,6 +257332,1133 @@ static void walLogCheckpointInfo(Wal *pWal, sqlite3 *db, sqlite3_int64 startTime } #endif @@ -1113,7 +1122,7 @@ index b433dfb..4105866 100644 +} + +SQLITE_PRIVATE int sqlite3BinlogDecodeRowBuffer(char *buffer, u32 nBuffer, u8 *op, -+ sqlite3_int64 *rowid, sqlite3_uint64 *nData, char **pData) ++ sqlite3_int64 *rowid, sqlite3_uint64 *nData, int *nZero, char **pData) +{ + if (nBuffer < sizeof(u8) + sizeof(sqlite3_int64) + sizeof(sqlite3_uint64)) { + sqlite3_log(SQLITE_WARNING, "Failed to decode binlog row, %u", nBuffer); @@ -1138,16 +1147,31 @@ index b433dfb..4105866 100644 + } + offset += sizeof(sqlite3_uint64); + ++ if (nBuffer == (sizeof(u8) + sizeof(sqlite3_int64) + sizeof(sqlite3_uint64) + *nData + sizeof(int))) { ++ errNo = memcpy_s(nZero, sizeof(int), buffer + offset, sizeof(int)); ++ if (errNo != EOK) { ++ sqlite3_log(SQLITE_WARNING, "Failed to decode binlog row nZero"); ++ return SQLITE_ERROR; ++ } ++ offset += sizeof(int); ++ } ++ + *pData = buffer + offset; + return SQLITE_OK; +} + -+SQLITE_PRIVATE int sqlite3BinlogGetRowBuffer(sqlite3_uint64 nData, const char *pData, u8 op, -+ sqlite3_int64 rowid, char **pOutBuffer, u64 *nOutBuffer){ ++SQLITE_PRIVATE int sqlite3BinlogGetRowBuffer(const BinlogRow *pRow, char **pOutBuffer, u64 *nOutBuffer){ ++ assert( pRow!=NULL ); + assert( pOutBuffer!=NULL ); + assert( nOutBuffer!=NULL ); + -+ u64 nRowBuffer = sizeof(op) + sizeof(rowid) + sizeof(nData) + nData; ++ u8 op = pRow->op == SQLITE_DELETE ? SQLITE_DELETE: SQLITE_INSERT; ++ sqlite3_int64 rowid = pRow->rowid; ++ sqlite3_uint64 nData = pRow->nData; ++ int nZero = pRow->nZero; ++ const char* pData = pRow->pData; ++ ++ u64 nRowBuffer = sizeof(op) + sizeof(rowid) + sizeof(nData) + +sizeof(nZero) + nData; + char *pRowBuffer = sqlite3MallocZero(nRowBuffer); + if (pRowBuffer == NULL) { + sqlite3_log(SQLITE_ERROR, "Failed to malloc binlog row, %lu", nRowBuffer); @@ -1172,6 +1196,12 @@ index b433dfb..4105866 100644 + goto error_when_memcpy_binlog_row; + } + ++ errNo = memcpy_s(pRowBuffer + offset, nRowBuffer, &nZero, sizeof(nZero)); ++ offset += sizeof(nZero); ++ if (errNo != EOK) { ++ goto error_when_memcpy_binlog_row; ++ } ++ + if (nData > 0) { + errNo = memcpy_s(pRowBuffer + offset, nRowBuffer, pData, nData); + if (errNo != EOK) { @@ -1189,17 +1219,16 @@ index b433dfb..4105866 100644 + return SQLITE_ERROR; +} + -+SQLITE_PRIVATE int sqlite3BinlogWriteRowData( -+ Vdbe *p, sqlite3_uint64 nData, const char *pData, int op, sqlite3_int64 rowid){ -+ if ((nData == 0 || pData == NULL) && op != SQLITE_DELETE) { -+ sqlite3_log(SQLITE_ERROR, "binlog row data empty, %llu", nData); ++SQLITE_PRIVATE int sqlite3BinlogWriteRowData(Vdbe *p, const BinlogRow *pRow){ ++ assert( p!=NULL && pRow!=NULL ); ++ if ((pRow->nData == 0 || pRow->pData == NULL) && pRow->op != SQLITE_DELETE) { ++ sqlite3_log(SQLITE_ERROR, "binlog row data empty, %llu", pRow->nData); + return SQLITE_ERROR; + } + -+ u8 opData = op == SQLITE_DELETE ? SQLITE_DELETE: SQLITE_INSERT; + u64 nRowBuffer = 0; + char *pRowBuffer = NULL; -+ int rc = sqlite3BinlogGetRowBuffer(nData, pData, opData, rowid, &pRowBuffer, &nRowBuffer); ++ int rc = sqlite3BinlogGetRowBuffer(pRow, &pRowBuffer, &nRowBuffer); + if (rc != SQLITE_OK) { + return rc; + } @@ -1213,15 +1242,17 @@ index b433dfb..4105866 100644 +** This is the function called in sqlite3VdbeExec to write a row-based binlog statement. +** If an error occured, then the row data is cleared and the state will be logged in statement mode +**/ -+SQLITE_PRIVATE void sqlite3StoreBinlogRowData(Vdbe *p, BtCursor *pCursor, -+ sqlite3_uint64 nData, const char *pData, int op, sqlite3_int64 rowid){ -+ assert( p!=NULL && pCursor!=NULL ); ++SQLITE_PRIVATE void sqlite3StoreBinlogRowData(Vdbe *p, BtCursor *pCursor, const BinlogRow *pRow){ ++ assert( p!=NULL && pCursor!=NULL && pRow!=NULL ); + assert( p->db!=NULL ); + assert( sqlite3IsRowBasedBinlog(p) ); -+ assert( op==SQLITE_INSERT || op==SQLITE_UPDATE || op==SQLITE_DELETE ); + sqlite3 *db = p->db; + BinlogDMLData *dataContainer = NULL; + ++ if (pCursor->pBtree == p->db->aDb[1].pBt) { ++ p->stmtType = STMT_TYPE_TEMP_DB_MODIFY; ++ } ++ + Table *pTab = sqlite3BinlogFindTable(pCursor); + if (pTab == NULL) { + goto error_when_store_binlog; @@ -1268,7 +1299,7 @@ index b433dfb..4105866 100644 + dataContainer->pTable = pTab; + } + -+ if (sqlite3BinlogWriteRowData(p, nData, pData, op, rowid) == SQLITE_OK) { ++ if (sqlite3BinlogWriteRowData(p, pRow) == SQLITE_OK) { + return; + } + @@ -1365,9 +1396,22 @@ index b433dfb..4105866 100644 + } + + sqlite3_value *tempVal = NULL; -+ sqlite3BinlogStat4Column(db, pRow->pData, pRow->nData, iCol, &tempVal); ++ sqlite3_uint64 nData = pRow->nData + (sqlite3_uint64)pRow->nZero; ++ char *pData = sqlite3MallocZero(nData); ++ if (pData == NULL) { ++ sqlite3_log(SQLITE_ERROR, "binlog failed to allocate memory"); ++ return NULL; ++ } ++ errno_t errNo = memcpy_s(pData, nData, pRow->pData, pRow->nData); ++ if (errNo != EOK) { ++ sqlite3_log(SQLITE_ERROR, "binlog failed to copy data, rc:%d, errno:%d", errNo, errno); ++ sqlite3_free(pData); ++ return NULL; ++ } ++ sqlite3BinlogStat4Column(db, pData, nData, iCol, &tempVal); + if (tempVal == NULL) { + sqlite3_log(SQLITE_ERROR, "decode data failed"); ++ sqlite3_free(pData); + return NULL; + } + int type = sqlite3_value_type(tempVal); @@ -1390,7 +1434,7 @@ index b433dfb..4105866 100644 + res = sqlite3_mprintf("%s", temp); + } + sqlite3ValueFree(tempVal); -+ ++ sqlite3_free(pData); + return res; +} + @@ -1424,6 +1468,10 @@ index b433dfb..4105866 100644 + zSql = sqlite3_mprintf("%s", p->pBinlogDMLData->pSavePointName); + logData.type = BINLOG_EVENT_TYPE_ROW_COMMIT; + p->pBinlogDMLData->isSavePointReleased = 1; ++ } else if (p->stmtType == STMT_TYPE_TEMP_DB_MODIFY) { ++ sqlite3_log(SQLITE_WARNING, "binlog skip temp, t=%d", p->stmtType); ++ sqlite3FreeBinlogRowData(p); ++ return; + } else { + zSql = sqlite3_expanded_sql((sqlite3_stmt *)p); + } @@ -1558,8 +1606,9 @@ index b433dfb..4105866 100644 + u8 op = 0; + sqlite3_int64 rowid = 0; + sqlite3_uint64 nData = 0; ++ int nZero = 0; + char *pData = NULL; -+ *rc = sqlite3BinlogDecodeRowBuffer(buffer, nBuffer, &op, &rowid, &nData, &pData); ++ *rc = sqlite3BinlogDecodeRowBuffer(buffer, nBuffer, &op, &rowid, &nData, &nZero, &pData); + if (*rc != SQLITE_OK) { + return NULL; + } @@ -1567,9 +1616,14 @@ index b433dfb..4105866 100644 + BinlogRow pRow; + pRow.op = op; + pRow.nData = nData; ++ pRow.nZero = nZero; + pRow.pData = pData; + pRow.rowid = rowid; -+ return sqlite3GetBinlogRowStmt(db, &pRow, pTable); ++ char *sql = sqlite3GetBinlogRowStmt(db, &pRow, pTable); ++ if (sql == NULL) { ++ *rc = SQLITE_ERROR; ++ } ++ return sql; +} + +SQLITE_PRIVATE Table *sqliteBinlogGetTable(sqlite3 *db, const char *pTableName, int *rc) @@ -1769,7 +1823,7 @@ index b433dfb..4105866 100644 // export the symbols #ifdef SQLITE_EXPORT_SYMBOLS #ifndef SQLITE_CKSUMVFS_STATIC -@@ -256942,6 +258434,9 @@ struct sqlite3_api_routines_extra { +@@ -256942,6 +258488,9 @@ struct sqlite3_api_routines_extra { int (*key_v2)(sqlite3*,const char*,const void*,int); int (*rekey)(sqlite3*,const void*,int); int (*rekey_v2)(sqlite3*,const char*,const void*,int); @@ -1779,7 +1833,7 @@ index b433dfb..4105866 100644 }; typedef struct sqlite3_api_routines_extra sqlite3_api_routines_extra; -@@ -256952,13 +258447,22 @@ static const sqlite3_api_routines_extra sqlite3ExtraApis = { +@@ -256952,13 +258501,22 @@ static const sqlite3_api_routines_extra sqlite3ExtraApis = { sqlite3_key, sqlite3_key_v2, sqlite3_rekey, @@ -1805,5 +1859,5 @@ index b433dfb..4105866 100644 EXPORT_SYMBOLS const sqlite3_api_routines *sqlite3_export_symbols = &sqlite3Apis; -- -2.47.0.windows.2 +2.25.1 -- Gitee