// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT. //go:build (linux && amd64) || (linux && arm64) || (linux && ppc64le) || (linux && riscv64) package sqlite3 import ( "unsafe" "modernc.org/libc" ) // C documentation // // /* // ** Do various sanity checks on a single page of a tree. Return // ** the tree depth. Root pages return 0. Parents of root pages // ** return 1, and so forth. // ** // ** These checks are done: // ** // ** 1. Make sure that cells and freeblocks do not overlap // ** but combine to completely cover the page. // ** 2. Make sure integer cell keys are in order. // ** 3. Check the integrity of overflow pages. // ** 4. Recursively call checkTreePage on all children. // ** 5. Verify that the depth of all children is the same. // */ func _checkTreePage(tls *libc.TLS, pCheck uintptr, iPage TPgno, piMinKey uintptr, _maxKey Ti64) (r int32) { bp := tls.Alloc(80) defer tls.Free(80) *(*Ti64)(unsafe.Pointer(bp)) = _maxKey var cellStart, d2, depth, doCoverageCheck, hdr, i, j, keyCanBeEqual, nCell, nFrag, pgno, rc, saved_v1, saved_v2, size1, v1 int32 var contentOffset, nPage, pc, prev, size, usableSize Tu32 var data, heap, pBt, pCell, pCellIdx, saved_zPfx uintptr var pgnoOvfl TPgno var savedIsInit Tu8 var _ /* info at bp+24 */ TCellInfo var _ /* pPage at bp+8 */ uintptr var _ /* x at bp+16 */ Tu32 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = cellStart, contentOffset, d2, data, depth, doCoverageCheck, hdr, heap, i, j, keyCanBeEqual, nCell, nFrag, nPage, pBt, pCell, pCellIdx, pc, pgno, pgnoOvfl, prev, rc, savedIsInit, saved_v1, saved_v2, saved_zPfx, size, size1, usableSize, v1 **(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0) /* Result code from subroutine call */ depth = -int32(1) /* Number of cells */ doCoverageCheck = int32(1) /* True if cell coverage checking should be done */ keyCanBeEqual = int32(1) /* Offset to the start of the cell content area */ heap = uintptr(0) prev = uint32(0) /* Next and previous entry on the min-heap */ saved_zPfx = (*TIntegrityCk)(unsafe.Pointer(pCheck)).FzPfx saved_v1 = libc.Int32FromUint32((*TIntegrityCk)(unsafe.Pointer(pCheck)).Fv1) saved_v2 = (*TIntegrityCk)(unsafe.Pointer(pCheck)).Fv2 savedIsInit = uint8(0) /* Check that the page exists */ _checkProgress(tls, pCheck) if (*TIntegrityCk)(unsafe.Pointer(pCheck)).FmxErr == 0 { goto end_of_check } pBt = (*TIntegrityCk)(unsafe.Pointer(pCheck)).FpBt usableSize = (*TBtShared)(unsafe.Pointer(pBt)).FusableSize if iPage == uint32(0) { return 0 } if _checkRef(tls, pCheck, iPage) != 0 { return 0 } (*TIntegrityCk)(unsafe.Pointer(pCheck)).FzPfx = __ccgo_ts + 4602 (*TIntegrityCk)(unsafe.Pointer(pCheck)).Fv1 = iPage v1 = _btreeGetPage(tls, pBt, iPage, bp+8, 0) rc = v1 if v1 != 0 { _checkAppendMsg(tls, pCheck, __ccgo_ts+4620, libc.VaList(bp+56, rc)) if rc == libc.Int32FromInt32(SQLITE_IOERR)|libc.Int32FromInt32(12)<= 0 && (*TIntegrityCk)(unsafe.Pointer(pCheck)).FmxErr != 0) { break } /* Check cell size */ (*TIntegrityCk)(unsafe.Pointer(pCheck)).Fv2 = i pc = libc.Uint32FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up(pCellIdx)))< usableSize-uint32(4) { _checkAppendMsg(tls, pCheck, __ccgo_ts+4774, libc.VaList(bp+56, pc, contentOffset, usableSize-uint32(4))) doCoverageCheck = 0 goto _4 } pCell = data + uintptr(pc) (*(*func(*libc.TLS, uintptr, uintptr, uintptr))(unsafe.Pointer(&struct{ uintptr }{(*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 8)))).FxParseCell})))(tls, **(**uintptr)(__ccgo_up(bp + 8)), pCell, bp+24) if pc+uint32((**(**TCellInfo)(__ccgo_up(bp + 24))).FnSize) > usableSize { _checkAppendMsg(tls, pCheck, __ccgo_ts+4804, 0) doCoverageCheck = 0 goto _4 } /* Check for integer primary key out of range */ if (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 8)))).FintKey != 0 { if keyCanBeEqual != 0 { v1 = libc.BoolInt32((**(**TCellInfo)(__ccgo_up(bp + 24))).FnKey > **(**Ti64)(__ccgo_up(bp))) } else { v1 = libc.BoolInt32((**(**TCellInfo)(__ccgo_up(bp + 24))).FnKey >= **(**Ti64)(__ccgo_up(bp))) } if v1 != 0 { _checkAppendMsg(tls, pCheck, __ccgo_ts+4828, libc.VaList(bp+56, (**(**TCellInfo)(__ccgo_up(bp + 24))).FnKey)) } **(**Ti64)(__ccgo_up(bp)) = (**(**TCellInfo)(__ccgo_up(bp + 24))).FnKey keyCanBeEqual = 0 /* Only the first key on the page may ==maxKey */ } /* Check the content overflow list */ if (**(**TCellInfo)(__ccgo_up(bp + 24))).FnPayload > uint32((**(**TCellInfo)(__ccgo_up(bp + 24))).FnLocal) { /* First page of the overflow chain */ nPage = ((**(**TCellInfo)(__ccgo_up(bp + 24))).FnPayload - uint32((**(**TCellInfo)(__ccgo_up(bp + 24))).FnLocal) + usableSize - uint32(5)) / (usableSize - uint32(4)) pgnoOvfl = _sqlite3Get4byte(tls, pCell+uintptr(libc.Int32FromUint16((**(**TCellInfo)(__ccgo_up(bp + 24))).FnSize)-int32(4))) if (*TBtShared)(unsafe.Pointer(pBt)).FautoVacuum != 0 { _checkPtrmap(tls, pCheck, pgnoOvfl, uint8(PTRMAP_OVERFLOW1), iPage) } _checkList(tls, pCheck, 0, pgnoOvfl, nPage) } if !((*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 8)))).Fleaf != 0) { /* Check sanity of left child page for internal pages */ pgno = libc.Int32FromUint32(_sqlite3Get4byte(tls, pCell)) if (*TBtShared)(unsafe.Pointer(pBt)).FautoVacuum != 0 { _checkPtrmap(tls, pCheck, libc.Uint32FromInt32(pgno), uint8(PTRMAP_BTREE), iPage) } d2 = _checkTreePage(tls, pCheck, libc.Uint32FromInt32(pgno), bp, **(**Ti64)(__ccgo_up(bp))) keyCanBeEqual = 0 if d2 != depth { _checkAppendMsg(tls, pCheck, __ccgo_ts+4852, 0) depth = d2 } } else { /* Populate the coverage-checking heap for leaf pages */ _btreeHeapInsert(tls, heap, pc< 0 { /* For leaf pages, the min-heap has already been initialized and the ** cells have already been inserted. But for internal pages, that has ** not yet been done, so do it now */ if !((*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 8)))).Fleaf != 0) { heap = (*TIntegrityCk)(unsafe.Pointer(pCheck)).Fheap **(**Tu32)(__ccgo_up(heap)) = uint32(0) i = nCell - int32(1) for { if !(i >= 0) { break } pc = libc.Uint32FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up(data + uintptr(cellStart+i*int32(2)))))< 0 { /* Enforced by btreeComputeFreeSpace() */ size1 = libc.Int32FromUint8(**(**Tu8)(__ccgo_up(data + uintptr(i+int32(2)))))<= **(**Tu32)(__ccgo_up(bp + 16))>>libc.Int32FromInt32(16) { _checkAppendMsg(tls, pCheck, __ccgo_ts+4877, libc.VaList(bp+56, **(**Tu32)(__ccgo_up(bp + 16))>>int32(16), iPage)) break } else { nFrag = libc.Int32FromUint32(uint32(nFrag) + (**(**Tu32)(__ccgo_up(bp + 16))>>libc.Int32FromInt32(16) - prev&libc.Uint32FromInt32(0xffff) - libc.Uint32FromInt32(1))) prev = **(**Tu32)(__ccgo_up(bp + 16)) } } nFrag = libc.Int32FromUint32(uint32(nFrag) + (usableSize - prev&libc.Uint32FromInt32(0xffff) - libc.Uint32FromInt32(1))) /* EVIDENCE-OF: R-43263-13491 The total number of bytes in all fragments ** is stored in the fifth field of the b-tree page header. ** EVIDENCE-OF: R-07161-27322 The one-byte integer at offset 7 gives the ** number of fragmented free bytes within the cell content area. */ if **(**Tu32)(__ccgo_up(heap)) == uint32(0) && nFrag != libc.Int32FromUint8(**(**Tu8)(__ccgo_up(data + uintptr(hdr+int32(7))))) { _checkAppendMsg(tls, pCheck, __ccgo_ts+4914, libc.VaList(bp+56, nFrag, libc.Int32FromUint8(**(**Tu8)(__ccgo_up(data + uintptr(hdr+int32(7))))), iPage)) } } goto end_of_check end_of_check: ; if !(doCoverageCheck != 0) { (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 8)))).FisInit = savedIsInit } _releasePage(tls, **(**uintptr)(__ccgo_up(bp + 8))) (*TIntegrityCk)(unsafe.Pointer(pCheck)).FzPfx = saved_zPfx (*TIntegrityCk)(unsafe.Pointer(pCheck)).Fv1 = libc.Uint32FromInt32(saved_v1) (*TIntegrityCk)(unsafe.Pointer(pCheck)).Fv2 = saved_v2 return depth + int32(1) } // C documentation // // /* // ** Create a new collating function for database "db". The name is zName // ** and the encoding is enc. // */ func _createCollation(tls *libc.TLS, db uintptr, zName uintptr, enc Tu8, pCtx uintptr, __ccgo_fp_xCompare uintptr, __ccgo_fp_xDel uintptr) (r int32) { var aColl, p, pColl uintptr var enc2, j int32 _, _, _, _, _ = aColl, enc2, j, p, pColl /* If SQLITE_UTF16 is specified as the encoding type, transform this ** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the ** SQLITE_UTF16NATIVE macro. SQLITE_UTF16 is not used internally. */ enc2 = libc.Int32FromUint8(enc) if enc2 == int32(SQLITE_UTF16) || enc2 == int32(SQLITE_UTF16_ALIGNED) { enc2 = int32(SQLITE_UTF16LE) } if enc2 < int32(SQLITE_UTF8) || enc2 > int32(SQLITE_UTF16BE) { return _sqlite3MisuseError(tls, int32(190273)) } /* Check if this call is removing or replacing an existing collation ** sequence. If so, and there are active VMs, return busy. If there ** are no active VMs, invalidate any pre-compiled statements. */ pColl = _sqlite3FindCollSeq(tls, db, libc.Uint8FromInt32(enc2), zName, 0) if pColl != 0 && (*TCollSeq)(unsafe.Pointer(pColl)).FxCmp != 0 { if (*Tsqlite3)(unsafe.Pointer(db)).FnVdbeActive != 0 { _sqlite3ErrorWithMsg(tls, db, int32(SQLITE_BUSY), __ccgo_ts+26050, 0) return int32(SQLITE_BUSY) } _sqlite3ExpirePreparedStatements(tls, db, 0) /* If collation sequence pColl was created directly by a call to ** sqlite3_create_collation, and not generated by synthCollSeq(), ** then any copies made by synthCollSeq() need to be invalidated. ** Also, collation destructor - CollSeq.xDel() - function may need ** to be called. */ if libc.Int32FromUint8((*TCollSeq)(unsafe.Pointer(pColl)).Fenc) & ^libc.Int32FromInt32(SQLITE_UTF16_ALIGNED) == enc2 { aColl = _sqlite3HashFind(tls, db+648, zName) j = 0 for { if !(j < int32(3)) { break } p = aColl + uintptr(j)*40 if libc.Int32FromUint8((*TCollSeq)(unsafe.Pointer(p)).Fenc) == libc.Int32FromUint8((*TCollSeq)(unsafe.Pointer(pColl)).Fenc) { if (*TCollSeq)(unsafe.Pointer(p)).FxDel != 0 { (*(*func(*libc.TLS, uintptr))(unsafe.Pointer(&struct{ uintptr }{(*TCollSeq)(unsafe.Pointer(p)).FxDel})))(tls, (*TCollSeq)(unsafe.Pointer(p)).FpUser) } (*TCollSeq)(unsafe.Pointer(p)).FxCmp = uintptr(0) } goto _1 _1: ; j = j + 1 } } } pColl = _sqlite3FindCollSeq(tls, db, libc.Uint8FromInt32(enc2), zName, int32(1)) if pColl == uintptr(0) { return int32(SQLITE_NOMEM) } (*TCollSeq)(unsafe.Pointer(pColl)).FxCmp = __ccgo_fp_xCompare (*TCollSeq)(unsafe.Pointer(pColl)).FpUser = pCtx (*TCollSeq)(unsafe.Pointer(pColl)).FxDel = __ccgo_fp_xDel (*TCollSeq)(unsafe.Pointer(pColl)).Fenc = libc.Uint8FromInt32(enc2 | libc.Int32FromUint8(enc)&libc.Int32FromInt32(SQLITE_UTF16_ALIGNED)) _sqlite3Error(tls, db, SQLITE_OK) return SQLITE_OK } // C documentation // // /* // ** This function is exactly the same as sqlite3_create_function(), except // ** that it is designed to be called by internal code. The difference is // ** that if a malloc() fails in sqlite3_create_function(), an error code // ** is returned and the mallocFailed flag cleared. // */ func _sqlite3CreateFunc(tls *libc.TLS, db uintptr, zFunctionName uintptr, nArg int32, enc int32, pUserData uintptr, __ccgo_fp_xSFunc uintptr, __ccgo_fp_xStep uintptr, __ccgo_fp_xFinal uintptr, __ccgo_fp_xValue uintptr, __ccgo_fp_xInverse uintptr, pDestructor uintptr) (r int32) { var extraFlags, rc int32 var p, v1 uintptr _, _, _, _ = extraFlags, p, rc, v1 if zFunctionName == uintptr(0) || __ccgo_fp_xSFunc != uintptr(0) && __ccgo_fp_xFinal != uintptr(0) || libc.BoolInt32(__ccgo_fp_xFinal == uintptr(0)) != libc.BoolInt32(__ccgo_fp_xStep == uintptr(0)) || libc.BoolInt32(__ccgo_fp_xValue == uintptr(0)) != libc.BoolInt32(__ccgo_fp_xInverse == uintptr(0)) || (nArg < -int32(1) || nArg > int32(SQLITE_MAX_FUNCTION_ARG)) || int32(255) < _sqlite3Strlen30(tls, zFunctionName) { return _sqlite3MisuseError(tls, int32(189333)) } extraFlags = enc & (libc.Int32FromInt32(SQLITE_DETERMINISTIC) | libc.Int32FromInt32(SQLITE_DIRECTONLY) | libc.Int32FromInt32(SQLITE_SUBTYPE) | libc.Int32FromInt32(SQLITE_INNOCUOUS) | libc.Int32FromInt32(SQLITE_RESULT_SUBTYPE) | libc.Int32FromInt32(SQLITE_SELFORDER1)) enc = enc & (libc.Int32FromInt32(SQLITE_FUNC_ENCMASK) | libc.Int32FromInt32(SQLITE_ANY)) /* The SQLITE_INNOCUOUS flag is the same bit as SQLITE_FUNC_UNSAFE. But ** the meaning is inverted. So flip the bit. */ extraFlags = extraFlags ^ int32(SQLITE_FUNC_UNSAFE) /* tag-20230109-1 */ /* If SQLITE_UTF16 is specified as the encoding type, transform this ** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the ** SQLITE_UTF16NATIVE macro. SQLITE_UTF16 is not used internally. ** ** If SQLITE_ANY is specified, add three versions of the function ** to the hash table. */ switch enc { case int32(SQLITE_UTF16): enc = int32(SQLITE_UTF16LE) case int32(SQLITE_ANY): rc = _sqlite3CreateFunc(tls, db, zFunctionName, nArg, int32(SQLITE_UTF8)|extraFlags^int32(SQLITE_FUNC_UNSAFE), pUserData, __ccgo_fp_xSFunc, __ccgo_fp_xStep, __ccgo_fp_xFinal, __ccgo_fp_xValue, __ccgo_fp_xInverse, pDestructor) if rc == SQLITE_OK { rc = _sqlite3CreateFunc(tls, db, zFunctionName, nArg, int32(SQLITE_UTF16LE)|extraFlags^int32(SQLITE_FUNC_UNSAFE), pUserData, __ccgo_fp_xSFunc, __ccgo_fp_xStep, __ccgo_fp_xFinal, __ccgo_fp_xValue, __ccgo_fp_xInverse, pDestructor) } if rc != SQLITE_OK { return rc } enc = int32(SQLITE_UTF16BE) case int32(SQLITE_UTF8): fallthrough case int32(SQLITE_UTF16LE): fallthrough case int32(SQLITE_UTF16BE): default: enc = int32(SQLITE_UTF8) break } /* Check if an existing function is being overridden or deleted. If so, ** and there are active VMs, then return SQLITE_BUSY. If a function ** is being overridden/deleted but there are no active VMs, allow the ** operation to continue but invalidate all precompiled statements. */ p = _sqlite3FindFunction(tls, db, zFunctionName, nArg, libc.Uint8FromInt32(enc), uint8(0)) if p != 0 && (*TFuncDef)(unsafe.Pointer(p)).FfuncFlags&uint32(SQLITE_FUNC_ENCMASK) == libc.Uint32FromInt32(enc) && int32((*TFuncDef)(unsafe.Pointer(p)).FnArg) == nArg { if (*Tsqlite3)(unsafe.Pointer(db)).FnVdbeActive != 0 { _sqlite3ErrorWithMsg(tls, db, int32(SQLITE_BUSY), __ccgo_ts+25915, 0) return int32(SQLITE_BUSY) } else { _sqlite3ExpirePreparedStatements(tls, db, 0) } } else { if __ccgo_fp_xSFunc == uintptr(0) && __ccgo_fp_xFinal == uintptr(0) { /* Trying to delete a function that does not exist. This is a no-op. ** https://sqlite.org/forum/forumpost/726219164b */ return SQLITE_OK } } p = _sqlite3FindFunction(tls, db, zFunctionName, nArg, libc.Uint8FromInt32(enc), uint8(1)) if !(p != 0) { return int32(SQLITE_NOMEM) } /* If an older version of the function with a configured destructor is ** being replaced invoke the destructor function here. */ _functionDestroy(tls, db, p) if pDestructor != 0 { (*TFuncDestructor)(unsafe.Pointer(pDestructor)).FnRef = (*TFuncDestructor)(unsafe.Pointer(pDestructor)).FnRef + 1 } *(*uintptr)(unsafe.Pointer(p + 64)) = pDestructor (*TFuncDef)(unsafe.Pointer(p)).FfuncFlags = (*TFuncDef)(unsafe.Pointer(p)).FfuncFlags&uint32(SQLITE_FUNC_ENCMASK) | libc.Uint32FromInt32(extraFlags) if __ccgo_fp_xSFunc != 0 { v1 = __ccgo_fp_xSFunc } else { v1 = __ccgo_fp_xStep } (*TFuncDef)(unsafe.Pointer(p)).FxSFunc = v1 (*TFuncDef)(unsafe.Pointer(p)).FxFinalize = __ccgo_fp_xFinal (*TFuncDef)(unsafe.Pointer(p)).FxValue = __ccgo_fp_xValue (*TFuncDef)(unsafe.Pointer(p)).FxInverse = __ccgo_fp_xInverse (*TFuncDef)(unsafe.Pointer(p)).FpUserData = pUserData (*TFuncDef)(unsafe.Pointer(p)).FnArg = libc.Int16FromUint16(libc.Uint16FromInt32(nArg)) return SQLITE_OK } // C documentation // // /* // ** Recover the wal-index by reading the write-ahead log file. // ** // ** This routine first tries to establish an exclusive lock on the // ** wal-index to prevent other threads/processes from doing anything // ** with the WAL or wal-index while recovery is running. The // ** WAL_RECOVER_LOCK is also held so that other threads will know // ** that this thread is running recovery. If unable to establish // ** the necessary locks, this routine returns SQLITE_BUSY. // */ func _walIndexRecover(tls *libc.TLS, pWal uintptr) (r int32) { bp := tls.Alloc(80) defer tls.Free(80) var aData, aFrame, aPrivate, pInfo uintptr var aFrameCksum [2]Tu32 var i, iLock, isValid, rc, szFrame, szPage int32 var iFirst, iFrame, iLast, iLastFrame, iPg, magic, nHdr, nHdr32, version Tu32 var iOffset Ti64 var v2, v3 uint64 var _ /* aBuf at bp+8 */ [32]Tu8 var _ /* aShare at bp+40 */ uintptr var _ /* nSize at bp+0 */ Ti64 var _ /* nTruncate at bp+52 */ Tu32 var _ /* pgno at bp+48 */ Tu32 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = aData, aFrame, aFrameCksum, aPrivate, i, iFirst, iFrame, iLast, iLastFrame, iLock, iOffset, iPg, isValid, magic, nHdr, nHdr32, pInfo, rc, szFrame, szPage, version, v2, v3 /* Size of log file */ aFrameCksum = [2]Tu32{} /* Lock offset to lock for checkpoint */ /* Obtain an exclusive lock on all byte in the locking range not already ** locked by the caller. The caller is guaranteed to have locked the ** WAL_WRITE_LOCK byte, and may have also locked the WAL_CKPT_LOCK byte. ** If successful, the same bytes that are locked here are unlocked before ** this function returns. */ iLock = int32(WAL_ALL_BUT_WRITE) + libc.Int32FromUint8((*TWal)(unsafe.Pointer(pWal)).FckptLock) rc = _walLockExclusive(tls, pWal, iLock, libc.Int32FromInt32(3)+libc.Int32FromInt32(0)-iLock) if rc != 0 { return rc } libc.Xmemset(tls, pWal+72, 0, uint64(48)) rc = _sqlite3OsFileSize(tls, (*TWal)(unsafe.Pointer(pWal)).FpWalFd, bp) if rc != SQLITE_OK { goto recovery_error } if **(**Ti64)(__ccgo_up(bp)) > int64(WAL_HDRSIZE) { /* Buffer to load WAL header into */ aPrivate = uintptr(0) /* Heap copy of *-shm hash being populated */ aFrame = uintptr(0) /* Last frame in wal, based on nSize alone */ /* Read in the WAL header. */ rc = _sqlite3OsRead(tls, (*TWal)(unsafe.Pointer(pWal)).FpWalFd, bp+8, int32(WAL_HDRSIZE), 0) if rc != SQLITE_OK { goto recovery_error } /* If the database page size is not a power of two, or is greater than ** SQLITE_MAX_PAGE_SIZE, conclude that the WAL file contains no valid ** data. Similarly, if the 'magic' value is invalid, ignore the whole ** WAL file. */ magic = _sqlite3Get4byte(tls, bp+8) szPage = libc.Int32FromUint32(_sqlite3Get4byte(tls, bp+8+8)) if magic&uint32(0xFFFFFFFE) != uint32(WAL_MAGIC) || szPage&(szPage-int32(1)) != 0 || szPage > int32(SQLITE_MAX_PAGE_SIZE) || szPage < int32(512) { goto finished } (*TWal)(unsafe.Pointer(pWal)).Fhdr.FbigEndCksum = uint8(magic & libc.Uint32FromInt32(0x00000001)) (*TWal)(unsafe.Pointer(pWal)).FszPage = libc.Uint32FromInt32(szPage) (*TWal)(unsafe.Pointer(pWal)).FnCkpt = _sqlite3Get4byte(tls, bp+8+12) libc.Xmemcpy(tls, pWal+72+32, bp+8+16, uint64(8)) /* Verify that the WAL header checksum is correct */ _walChecksumBytes(tls, libc.BoolInt32(libc.Int32FromUint8((*TWal)(unsafe.Pointer(pWal)).Fhdr.FbigEndCksum) == SQLITE_BIGENDIAN), bp+8, libc.Int32FromInt32(WAL_HDRSIZE)-libc.Int32FromInt32(2)*libc.Int32FromInt32(4), uintptr(0), pWal+72+24) if **(**Tu32)(__ccgo_up(pWal + 72 + 24)) != _sqlite3Get4byte(tls, bp+8+24) || **(**Tu32)(__ccgo_up(pWal + 72 + 24 + 1*4)) != _sqlite3Get4byte(tls, bp+8+28) { goto finished } /* Verify that the version number on the WAL format is one that ** are able to understand */ version = _sqlite3Get4byte(tls, bp+8+4) if version != uint32(WAL_MAX_VERSION) { rc = _sqlite3CantopenError(tls, int32(68992)) goto finished } /* Malloc a buffer to read frames into. */ szFrame = szPage + int32(WAL_FRAME_HDRSIZE) aFrame = Xsqlite3_malloc64(tls, uint64(libc.Uint64FromInt32(szFrame)+(libc.Uint64FromInt64(2)*libc.Uint64FromInt32(libc.Int32FromInt32(HASHTABLE_NPAGE)*libc.Int32FromInt32(2))+libc.Uint64FromInt32(HASHTABLE_NPAGE)*libc.Uint64FromInt64(4)))) if !(aFrame != 0) { rc = int32(SQLITE_NOMEM) goto recovery_error } aData = aFrame + 24 aPrivate = aData + uintptr(szPage) /* Read all frames from the log file. */ iLastFrame = libc.Uint32FromInt64((**(**Ti64)(__ccgo_up(bp)) - int64(WAL_HDRSIZE)) / int64(szFrame)) iPg = uint32(0) for { if !(iPg <= libc.Uint32FromInt32(_walFramePage(tls, iLastFrame))) { break } if uint64(iLastFrame) < libc.Uint64FromInt32(HASHTABLE_NPAGE)-(libc.Uint64FromInt64(48)*libc.Uint64FromInt32(2)+libc.Uint64FromInt64(40))/libc.Uint64FromInt64(4)+uint64(iPg*uint32(HASHTABLE_NPAGE)) { v2 = uint64(iLastFrame) } else { v2 = libc.Uint64FromInt32(HASHTABLE_NPAGE) - (libc.Uint64FromInt64(48)*libc.Uint64FromInt32(2)+libc.Uint64FromInt64(40))/libc.Uint64FromInt64(4) + uint64(iPg*uint32(HASHTABLE_NPAGE)) } /* Index of last frame read */ iLast = uint32(v2) if iPg == uint32(0) { v3 = uint64(0) } else { v3 = libc.Uint64FromInt32(HASHTABLE_NPAGE) - (libc.Uint64FromInt64(48)*libc.Uint64FromInt32(2)+libc.Uint64FromInt64(40))/libc.Uint64FromInt64(4) + uint64((iPg-uint32(1))*uint32(HASHTABLE_NPAGE)) } iFirst = uint32(uint64(1) + v3) rc = _walIndexPage(tls, pWal, libc.Int32FromUint32(iPg), bp+40) if **(**uintptr)(__ccgo_up(bp + 40)) == uintptr(0) { break } **(**uintptr)(__ccgo_up((*TWal)(unsafe.Pointer(pWal)).FapWiData + uintptr(iPg)*8)) = aPrivate iFrame = iFirst for { if !(iFrame <= iLast) { break } iOffset = libc.Int64FromInt32(WAL_HDRSIZE) + libc.Int64FromUint32(iFrame-libc.Uint32FromInt32(1))*int64(szPage+libc.Int32FromInt32(WAL_FRAME_HDRSIZE)) /* dbsize field from frame header */ /* Read and decode the next log frame. */ rc = _sqlite3OsRead(tls, (*TWal)(unsafe.Pointer(pWal)).FpWalFd, aFrame, szFrame, iOffset) if rc != SQLITE_OK { break } isValid = _walDecodeFrame(tls, pWal, bp+48, bp+52, aData, aFrame) if !(isValid != 0) { break } rc = _walIndexAppend(tls, pWal, iFrame, **(**Tu32)(__ccgo_up(bp + 48))) if rc != SQLITE_OK { break } /* If nTruncate is non-zero, this is a commit record. */ if **(**Tu32)(__ccgo_up(bp + 52)) != 0 { (*TWal)(unsafe.Pointer(pWal)).Fhdr.FmxFrame = iFrame (*TWal)(unsafe.Pointer(pWal)).Fhdr.FnPage = **(**Tu32)(__ccgo_up(bp + 52)) (*TWal)(unsafe.Pointer(pWal)).Fhdr.FszPage = libc.Uint16FromInt32(szPage&libc.Int32FromInt32(0xff00) | szPage>>libc.Int32FromInt32(16)) aFrameCksum[0] = **(**Tu32)(__ccgo_up(pWal + 72 + 24)) aFrameCksum[int32(1)] = **(**Tu32)(__ccgo_up(pWal + 72 + 24 + 1*4)) } goto _4 _4: ; iFrame = iFrame + 1 } **(**uintptr)(__ccgo_up((*TWal)(unsafe.Pointer(pWal)).FapWiData + uintptr(iPg)*8)) = **(**uintptr)(__ccgo_up(bp + 40)) if iPg == uint32(0) { v2 = libc.Uint64FromInt64(48)*libc.Uint64FromInt32(2) + libc.Uint64FromInt64(40) } else { v2 = uint64(0) } nHdr = uint32(v2) nHdr32 = uint32(uint64(nHdr) / uint64(4)) /* Memcpy() should work fine here, on all reasonable implementations. ** Technically, memcpy() might change the destination to some ** intermediate value before setting to the final value, and that might ** cause a concurrent reader to malfunction. Memcpy() is allowed to ** do that, according to the spec, but no memcpy() implementation that ** we know of actually does that, which is why we say that memcpy() ** is safe for this. Memcpy() is certainly a lot faster. */ libc.Xmemcpy(tls, **(**uintptr)(__ccgo_up(bp + 40))+uintptr(nHdr32)*4, aPrivate+uintptr(nHdr32)*4, libc.Uint64FromInt64(2)*libc.Uint64FromInt32(libc.Int32FromInt32(HASHTABLE_NPAGE)*libc.Int32FromInt32(2))+libc.Uint64FromInt32(HASHTABLE_NPAGE)*libc.Uint64FromInt64(4)-uint64(nHdr)) if iFrame <= iLast { break } goto _1 _1: ; iPg = iPg + 1 } Xsqlite3_free(tls, aFrame) } goto finished finished: ; if rc == SQLITE_OK { **(**Tu32)(__ccgo_up(pWal + 72 + 24)) = aFrameCksum[0] **(**Tu32)(__ccgo_up(pWal + 72 + 24 + 1*4)) = aFrameCksum[int32(1)] _walIndexWriteHdr(tls, pWal) /* Reset the checkpoint-header. This is safe because this thread is ** currently holding locks that exclude all other writers and ** checkpointers. Then set the values of read-mark slots 1 through N. */ pInfo = _walCkptInfo(tls, pWal) (*TWalCkptInfo)(unsafe.Pointer(pInfo)).FnBackfill = uint32(0) (*TWalCkptInfo)(unsafe.Pointer(pInfo)).FnBackfillAttempted = (*TWal)(unsafe.Pointer(pWal)).Fhdr.FmxFrame **(**Tu32)(__ccgo_up(pInfo + 4)) = uint32(0) i = int32(1) for { if !(i < libc.Int32FromInt32(SQLITE_SHM_NLOCK)-libc.Int32FromInt32(3)) { break } rc = _walLockExclusive(tls, pWal, int32(3)+i, int32(1)) if rc == SQLITE_OK { if i == int32(1) && (*TWal)(unsafe.Pointer(pWal)).Fhdr.FmxFrame != 0 { **(**Tu32)(__ccgo_up(pInfo + 4 + uintptr(i)*4)) = (*TWal)(unsafe.Pointer(pWal)).Fhdr.FmxFrame } else { **(**Tu32)(__ccgo_up(pInfo + 4 + uintptr(i)*4)) = uint32(READMARK_NOT_USED) } _walUnlockExclusive(tls, pWal, int32(3)+i, int32(1)) } else { if rc != int32(SQLITE_BUSY) { goto recovery_error } } goto _6 _6: ; i = i + 1 } /* If more than one frame was recovered from the log file, report an ** event via sqlite3_log(). This is to help with identifying performance ** problems caused by applications routinely shutting down without ** checkpointing the log file. */ if (*TWal)(unsafe.Pointer(pWal)).Fhdr.FnPage != 0 { Xsqlite3_log(tls, libc.Int32FromInt32(SQLITE_NOTICE)|libc.Int32FromInt32(1)<