// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.

//go:build (darwin && amd64) || (darwin && arm64) || (freebsd && amd64) || (freebsd && arm64) || (linux && amd64) || (linux && arm64) || (linux && loong64) || (linux && ppc64le) || (linux && riscv64) || (netbsd && amd64) || (openbsd && amd64) || (openbsd && arm64)

package sqlite3

import (
	"unsafe"

	"modernc.org/libc"
)

// C documentation
//
//	/*
//	** This version of balance() handles the common special case where
//	** a new entry is being inserted on the extreme right-end of the
//	** tree, in other words, when the new entry will become the largest
//	** entry in the tree.
//	**
//	** Instead of trying to balance the 3 right-most leaf pages, just add
//	** a new page to the right-hand side and put the one new entry in
//	** that page.  This leaves the right side of the tree somewhat
//	** unbalanced.  But odds are that we will be inserting new entries
//	** at the end soon afterwards so the nearly empty page will quickly
//	** fill up.  On average.
//	**
//	** pPage is the leaf page which is the right-most page in the tree.
//	** pParent is its parent.  pPage must have a single overflow entry
//	** which is also the right-most entry on the page.
//	**
//	** The pSpace buffer is used to store a temporary copy of the divider
//	** cell that will be inserted into pParent. Such a cell consists of a 4
//	** byte page number followed by a variable length integer. In other
//	** words, at most 13 bytes. Hence the pSpace buffer must be at
//	** least 13 bytes in size.
//	*/
func _balance_quick(tls *libc.TLS, pParent uintptr, pPage uintptr, pSpace uintptr) (r int32) {
	bp := tls.Alloc(144)
	defer tls.Free(144)
	var pBt, pOut, pStop, v1, v3 uintptr
	var v2 Tu8
	var _ /* b at bp+32 */ TCellArray
	var _ /* pCell at bp+16 */ uintptr
	var _ /* pNew at bp+0 */ uintptr
	var _ /* pgnoNew at bp+12 */ TPgno
	var _ /* rc at bp+8 */ int32
	var _ /* szCell at bp+24 */ Tu16
	_, _, _, _, _, _ = pBt, pOut, pStop, v1, v2, v3
	pBt = (*TMemPage)(unsafe.Pointer(pPage)).FpBt /* Page number of pNew */
	if libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FnCell) == 0 {
		return _sqlite3CorruptError(tls, int32(81151))
	} /* dbfuzz001.test */
	/* Allocate a new page. This page will become the right-sibling of
	 ** pPage. Make the parent page writable, so that the new divider cell
	 ** may be inserted. If both these operations are successful, proceed.
	 */
	**(**int32)(__ccgo_up(bp + 8)) = _allocateBtreePage(tls, pBt, bp, bp+12, uint32(0), uint8(0))
	if **(**int32)(__ccgo_up(bp + 8)) == SQLITE_OK {
		pOut = pSpace + 4
		**(**uintptr)(__ccgo_up(bp + 16)) = **(**uintptr)(__ccgo_up(pPage + 40))
		**(**Tu16)(__ccgo_up(bp + 24)) = (*(*func(*libc.TLS, uintptr, uintptr) Tu16)(unsafe.Pointer(&struct{ uintptr }{(*TMemPage)(unsafe.Pointer(pPage)).FxCellSize})))(tls, pPage, **(**uintptr)(__ccgo_up(bp + 16)))
		_zeroPage(tls, **(**uintptr)(__ccgo_up(bp)), libc.Int32FromInt32(PTF_INTKEY)|libc.Int32FromInt32(PTF_LEAFDATA)|libc.Int32FromInt32(PTF_LEAF))
		(**(**TCellArray)(__ccgo_up(bp + 32))).FnCell = int32(1)
		(**(**TCellArray)(__ccgo_up(bp + 32))).FpRef = pPage
		(**(**TCellArray)(__ccgo_up(bp + 32))).FapCell = bp + 16
		(**(**TCellArray)(__ccgo_up(bp + 32))).FszCell = bp + 24
		**(**uintptr)(__ccgo_up(bp + 32 + 32)) = (*TMemPage)(unsafe.Pointer(pPage)).FaDataEnd
		**(**int32)(__ccgo_up(bp + 32 + 80)) = int32(2)
		**(**int32)(__ccgo_up(bp + 32 + 80 + uintptr(libc.Int32FromInt32(NB)*libc.Int32FromInt32(2)-libc.Int32FromInt32(1))*4)) = int32(0x7fffffff)
		**(**int32)(__ccgo_up(bp + 8)) = _rebuildPage(tls, bp+32, 0, int32(1), **(**uintptr)(__ccgo_up(bp)))
		if **(**int32)(__ccgo_up(bp + 8)) != 0 {
			_releasePage(tls, **(**uintptr)(__ccgo_up(bp)))
			return **(**int32)(__ccgo_up(bp + 8))
		}
		(*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FnFree = libc.Int32FromUint32((*TBtShared)(unsafe.Pointer(pBt)).FusableSize - uint32((*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FcellOffset) - uint32(2) - uint32(**(**Tu16)(__ccgo_up(bp + 24))))
		/* If this is an auto-vacuum database, update the pointer map
		 ** with entries for the new page, and any pointer from the
		 ** cell on the page to an overflow page. If either of these
		 ** operations fails, the return code is set, but the contents
		 ** of the parent page are still manipulated by the code below.
		 ** That is Ok, at this point the parent page is guaranteed to
		 ** be marked as dirty. Returning an error code will cause a
		 ** rollback, undoing any changes made to the parent page.
		 */
		if (*TBtShared)(unsafe.Pointer(pBt)).FautoVacuum != 0 {
			_ptrmapPut(tls, pBt, **(**TPgno)(__ccgo_up(bp + 12)), uint8(PTRMAP_BTREE), (*TMemPage)(unsafe.Pointer(pParent)).Fpgno, bp+8)
			if libc.Int32FromUint16(**(**Tu16)(__ccgo_up(bp + 24))) > libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FminLocal) {
				_ptrmapPutOvflPtr(tls, **(**uintptr)(__ccgo_up(bp)), **(**uintptr)(__ccgo_up(bp)), **(**uintptr)(__ccgo_up(bp + 16)), bp+8)
			}
		}
		/* Create a divider cell to insert into pParent. The divider cell
		 ** consists of a 4-byte page number (the page number of pPage) and
		 ** a variable length key value (which must be the same value as the
		 ** largest key on pPage).
		 **
		 ** To find the largest key value on pPage, first find the right-most
		 ** cell on pPage. The first two fields of this cell are the
		 ** record-length (a variable length integer at most 32-bits in size)
		 ** and the key value (a variable length integer, may have any value).
		 ** The first of the while(...) loops below skips over the record-length
		 ** field. The second while(...) loop copies the key value from the
		 ** cell on pPage into the pSpace buffer.
		 */
		**(**uintptr)(__ccgo_up(bp + 16)) = (*TMemPage)(unsafe.Pointer(pPage)).FaData + uintptr(libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FmaskPage)&(libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TMemPage)(unsafe.Pointer(pPage)).FaCellIdx + uintptr(int32(2)*(libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FnCell)-int32(1))))))<<libc.Int32FromInt32(8)|libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TMemPage)(unsafe.Pointer(pPage)).FaCellIdx + uintptr(int32(2)*(libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FnCell)-int32(1))) + 1)))))
		pStop = **(**uintptr)(__ccgo_up(bp + 16)) + 9
		for {
			v1 = **(**uintptr)(__ccgo_up(bp + 16))
			**(**uintptr)(__ccgo_up(bp + 16)) = **(**uintptr)(__ccgo_up(bp + 16)) + 1
			if !(libc.Int32FromUint8(**(**Tu8)(__ccgo_up(v1)))&int32(0x80) != 0 && **(**uintptr)(__ccgo_up(bp + 16)) < pStop) {
				break
			}
		}
		pStop = **(**uintptr)(__ccgo_up(bp + 16)) + 9
		for {
			v1 = **(**uintptr)(__ccgo_up(bp + 16))
			**(**uintptr)(__ccgo_up(bp + 16)) = **(**uintptr)(__ccgo_up(bp + 16)) + 1
			v2 = **(**Tu8)(__ccgo_up(v1))
			v3 = pOut
			pOut = pOut + 1
			**(**Tu8)(__ccgo_up(v3)) = v2
			if !(libc.Int32FromUint8(v2)&int32(0x80) != 0 && **(**uintptr)(__ccgo_up(bp + 16)) < pStop) {
				break
			}
		}
		/* Insert the new divider cell into pParent. */
		if **(**int32)(__ccgo_up(bp + 8)) == SQLITE_OK {
			**(**int32)(__ccgo_up(bp + 8)) = _insertCell(tls, pParent, libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pParent)).FnCell), pSpace, int32(int64(pOut)-int64(pSpace)), uintptr(0), (*TMemPage)(unsafe.Pointer(pPage)).Fpgno)
		}
		/* Set the right-child pointer of pParent to point to the new page. */
		_sqlite3Put4byte(tls, (*TMemPage)(unsafe.Pointer(pParent)).FaData+uintptr(libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pParent)).FhdrOffset)+int32(8)), **(**TPgno)(__ccgo_up(bp + 12)))
		/* Release the reference to the new page. */
		_releasePage(tls, **(**uintptr)(__ccgo_up(bp)))
	}
	return **(**int32)(__ccgo_up(bp + 8))
}

// C documentation
//
//	/*
//	** Erase the given database page and all its children.  Return
//	** the page to the freelist.
//	*/
func _clearDatabasePage(tls *libc.TLS, pBt uintptr, pgno TPgno, freePageFlag int32, pnChange uintptr) (r int32) {
	bp := tls.Alloc(48)
	defer tls.Free(48)
	var hdr, i, v2 int32
	var pCell uintptr
	var _ /* info at bp+16 */ TCellInfo
	var _ /* pPage at bp+0 */ uintptr
	var _ /* rc at bp+8 */ int32
	_, _, _, _ = hdr, i, pCell, v2
	if pgno > _btreePagecount(tls, pBt) {
		return _sqlite3CorruptError(tls, int32(83360))
	}
	**(**int32)(__ccgo_up(bp + 8)) = _getAndInitPage(tls, pBt, pgno, bp, 0)
	if **(**int32)(__ccgo_up(bp + 8)) != 0 {
		return **(**int32)(__ccgo_up(bp + 8))
	}
	if libc.Int32FromUint8((*TBtShared)(unsafe.Pointer(pBt)).FopenFlags)&int32(BTREE_SINGLE) == 0 && _sqlite3PagerPageRefcount(tls, (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FpDbPage) != int32(1)+libc.BoolInt32(pgno == uint32(1)) {
		**(**int32)(__ccgo_up(bp + 8)) = _sqlite3CorruptError(tls, int32(83367))
		goto cleardatabasepage_out
	}
	hdr = libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FhdrOffset)
	i = 0
	for {
		if !(i < libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FnCell)) {
			break
		}
		pCell = (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FaData + uintptr(libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FmaskPage)&(libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FaCellIdx + uintptr(int32(2)*i))))<<libc.Int32FromInt32(8)|libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FaCellIdx + uintptr(int32(2)*i) + 1)))))
		if !((*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).Fleaf != 0) {
			**(**int32)(__ccgo_up(bp + 8)) = _clearDatabasePage(tls, pBt, _sqlite3Get4byte(tls, pCell), int32(1), pnChange)
			if **(**int32)(__ccgo_up(bp + 8)) != 0 {
				goto cleardatabasepage_out
			}
		}
		(*(*func(*libc.TLS, uintptr, uintptr, uintptr))(unsafe.Pointer(&struct{ uintptr }{(*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FxParseCell})))(tls, **(**uintptr)(__ccgo_up(bp)), pCell, bp+16)
		if uint32((**(**TCellInfo)(__ccgo_up(bp + 16))).FnLocal) != (**(**TCellInfo)(__ccgo_up(bp + 16))).FnPayload {
			**(**int32)(__ccgo_up(bp + 8)) = _clearCellOverflow(tls, **(**uintptr)(__ccgo_up(bp)), pCell, bp+16)
		} else {
			**(**int32)(__ccgo_up(bp + 8)) = SQLITE_OK
		}
		if **(**int32)(__ccgo_up(bp + 8)) != 0 {
			goto cleardatabasepage_out
		}
		goto _1
	_1:
		;
		i = i + 1
	}
	if !((*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).Fleaf != 0) {
		**(**int32)(__ccgo_up(bp + 8)) = _clearDatabasePage(tls, pBt, _sqlite3Get4byte(tls, (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FaData+uintptr(hdr+int32(8))), int32(1), pnChange)
		if **(**int32)(__ccgo_up(bp + 8)) != 0 {
			goto cleardatabasepage_out
		}
		if (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FintKey != 0 {
			pnChange = uintptr(0)
		}
	}
	if pnChange != 0 {
		**(**Ti64)(__ccgo_up(pnChange)) += libc.Int64FromUint16((*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FnCell)
	}
	if freePageFlag != 0 {
		_freePage(tls, **(**uintptr)(__ccgo_up(bp)), bp+8)
	} else {
		v2 = _sqlite3PagerWrite(tls, (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FpDbPage)
		**(**int32)(__ccgo_up(bp + 8)) = v2
		if v2 == 0 {
			_zeroPage(tls, **(**uintptr)(__ccgo_up(bp)), libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FaData + uintptr(hdr))))|int32(PTF_LEAF))
		}
	}
	goto cleardatabasepage_out
cleardatabasepage_out:
	;
	_releasePage(tls, **(**uintptr)(__ccgo_up(bp)))
	return **(**int32)(__ccgo_up(bp + 8))
}

// C documentation
//
//	/*
//	** The first argument, pCur, is a cursor opened on some b-tree. Count the
//	** number of entries in the b-tree and write the result to *pnEntry.
//	**
//	** SQLITE_OK is returned if the operation is successfully executed.
//	** Otherwise, if an error is encountered (i.e. an IO error or database
//	** corruption) an SQLite error code is returned.
//	*/
func _sqlite3BtreeCount(tls *libc.TLS, db uintptr, pCur uintptr, pnEntry uintptr) (r int32) {
	var iIdx, rc int32
	var nEntry Ti64
	var pPage uintptr
	_, _, _, _ = iIdx, nEntry, pPage, rc
	nEntry = 0 /* Return code */
	rc = _moveToRoot(tls, pCur)
	if rc == int32(SQLITE_EMPTY) {
		**(**Ti64)(__ccgo_up(pnEntry)) = 0
		return SQLITE_OK
	}
	/* Unless an error occurs, the following loop runs one iteration for each
	 ** page in the B-Tree structure (not including overflow pages).
	 */
	for rc == SQLITE_OK && !(libc.AtomicLoadNInt32(db+432, libc.Int32FromInt32(__ATOMIC_RELAXED)) != 0) { /* Current page of the b-tree */
		/* If this is a leaf page or the tree is not an int-key tree, then
		 ** this page contains countable entries. Increment the entry counter
		 ** accordingly.
		 */
		pPage = (*TBtCursor)(unsafe.Pointer(pCur)).FpPage
		if (*TMemPage)(unsafe.Pointer(pPage)).Fleaf != 0 || !((*TMemPage)(unsafe.Pointer(pPage)).FintKey != 0) {
			nEntry = nEntry + libc.Int64FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FnCell)
		}
		/* pPage is a leaf node. This loop navigates the cursor so that it
		 ** points to the first interior cell that it points to the parent of
		 ** the next page in the tree that has not yet been visited. The
		 ** pCur->aiIdx[pCur->iPage] value is set to the index of the parent cell
		 ** of the page, or to the number of cells in the page if the next page
		 ** to visit is the right-child of its parent.
		 **
		 ** If all pages in the tree have been visited, return SQLITE_OK to the
		 ** caller.
		 */
		if (*TMemPage)(unsafe.Pointer(pPage)).Fleaf != 0 {
			for cond := true; cond; cond = libc.Int32FromUint16((*TBtCursor)(unsafe.Pointer(pCur)).Fix) >= libc.Int32FromUint16((*TMemPage)(unsafe.Pointer((*TBtCursor)(unsafe.Pointer(pCur)).FpPage)).FnCell) {
				if int32((*TBtCursor)(unsafe.Pointer(pCur)).FiPage) == 0 {
					/* All pages of the b-tree have been visited. Return successfully. */
					**(**Ti64)(__ccgo_up(pnEntry)) = nEntry
					return _moveToRoot(tls, pCur)
				}
				_moveToParent(tls, pCur)
			}
			(*TBtCursor)(unsafe.Pointer(pCur)).Fix = (*TBtCursor)(unsafe.Pointer(pCur)).Fix + 1
			pPage = (*TBtCursor)(unsafe.Pointer(pCur)).FpPage
		}
		/* Descend to the child node of the cell that the cursor currently
		 ** points at. This is the right-child if (iIdx==pPage->nCell).
		 */
		iIdx = libc.Int32FromUint16((*TBtCursor)(unsafe.Pointer(pCur)).Fix)
		if iIdx == libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FnCell) {
			rc = _moveToChild(tls, pCur, _sqlite3Get4byte(tls, (*TMemPage)(unsafe.Pointer(pPage)).FaData+uintptr(libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pPage)).FhdrOffset)+int32(8))))
		} else {
			rc = _moveToChild(tls, pCur, _sqlite3Get4byte(tls, (*TMemPage)(unsafe.Pointer(pPage)).FaData+uintptr(libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FmaskPage)&(libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TMemPage)(unsafe.Pointer(pPage)).FaCellIdx + uintptr(int32(2)*iIdx))))<<libc.Int32FromInt32(8)|libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TMemPage)(unsafe.Pointer(pPage)).FaCellIdx + uintptr(int32(2)*iIdx) + 1)))))))
		}
	}
	/* An error has occurred. Return an error code. */
	return rc
}

// C documentation
//
//	/*
//	** Delete the entry that the cursor is pointing to.
//	**
//	** If the BTREE_SAVEPOSITION bit of the flags parameter is zero, then
//	** the cursor is left pointing at an arbitrary location after the delete.
//	** But if that bit is set, then the cursor is left in a state such that
//	** the next call to BtreeNext() or BtreePrev() moves it to the same row
//	** as it would have been on if the call to BtreeDelete() had been omitted.
//	**
//	** The BTREE_AUXDELETE bit of flags indicates that is one of several deletes
//	** associated with a single table entry and its indexes.  Only one of those
//	** deletes is considered the "primary" delete.  The primary delete occurs
//	** on a cursor that is not a BTREE_FORDELETE cursor.  All but one delete
//	** operation on non-FORDELETE cursors is tagged with the AUXDELETE flag.
//	** The BTREE_AUXDELETE bit is a hint that is not used by this implementation,
//	** but which might be used by alternative storage engines.
//	*/
func _sqlite3BtreeDelete(tls *libc.TLS, pCur uintptr, flags Tu8) (r int32) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var bPreserve Tu8
	var iCellDepth, iCellIdx, nCell int32
	var n TPgno
	var p, pBt, pCell, pLeaf, pPage, pTmp, v2 uintptr
	var v1 Ti8
	var _ /* info at bp+8 */ TCellInfo
	var _ /* rc at bp+0 */ int32
	_, _, _, _, _, _, _, _, _, _, _, _, _ = bPreserve, iCellDepth, iCellIdx, n, nCell, p, pBt, pCell, pLeaf, pPage, pTmp, v1, v2
	p = (*TBtCursor)(unsafe.Pointer(pCur)).FpBtree
	pBt = (*TBtree)(unsafe.Pointer(p)).FpBt /* Keep cursor valid.  2 for CURSOR_SKIPNEXT */
	if libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCur)).FeState) != CURSOR_VALID {
		if libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCur)).FeState) >= int32(CURSOR_REQUIRESEEK) {
			**(**int32)(__ccgo_up(bp)) = _btreeRestoreCursorPosition(tls, pCur)
			if **(**int32)(__ccgo_up(bp)) != 0 || libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCur)).FeState) != CURSOR_VALID {
				return **(**int32)(__ccgo_up(bp))
			}
		} else {
			return _sqlite3CorruptError(tls, int32(82999))
		}
	}
	iCellDepth = int32((*TBtCursor)(unsafe.Pointer(pCur)).FiPage)
	iCellIdx = libc.Int32FromUint16((*TBtCursor)(unsafe.Pointer(pCur)).Fix)
	pPage = (*TBtCursor)(unsafe.Pointer(pCur)).FpPage
	if libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FnCell) <= iCellIdx {
		return _sqlite3CorruptError(tls, int32(83008))
	}
	pCell = (*TMemPage)(unsafe.Pointer(pPage)).FaData + uintptr(libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FmaskPage)&(libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TMemPage)(unsafe.Pointer(pPage)).FaCellIdx + uintptr(int32(2)*iCellIdx))))<<libc.Int32FromInt32(8)|libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TMemPage)(unsafe.Pointer(pPage)).FaCellIdx + uintptr(int32(2)*iCellIdx) + 1)))))
	if (*TMemPage)(unsafe.Pointer(pPage)).FnFree < 0 && _btreeComputeFreeSpace(tls, pPage) != 0 {
		return _sqlite3CorruptError(tls, int32(83012))
	}
	if pCell < (*TMemPage)(unsafe.Pointer(pPage)).FaCellIdx+uintptr((*TMemPage)(unsafe.Pointer(pPage)).FnCell) {
		return _sqlite3CorruptError(tls, int32(83015))
	}
	/* If the BTREE_SAVEPOSITION bit is on, then the cursor position must
	 ** be preserved following this delete operation. If the current delete
	 ** will cause a b-tree rebalance, then this is done by saving the cursor
	 ** key and leaving the cursor in CURSOR_REQUIRESEEK state before
	 ** returning.
	 **
	 ** If the current delete will not cause a rebalance, then the cursor
	 ** will be left in CURSOR_SKIPNEXT state pointing to the entry immediately
	 ** before or after the deleted entry.
	 **
	 ** The bPreserve value records which path is required:
	 **
	 **    bPreserve==0         Not necessary to save the cursor position
	 **    bPreserve==1         Use CURSOR_REQUIRESEEK to save the cursor position
	 **    bPreserve==2         Cursor won't move.  Set CURSOR_SKIPNEXT.
	 */
	bPreserve = libc.BoolUint8(libc.Int32FromUint8(flags)&int32(BTREE_SAVEPOSITION) != 0)
	if bPreserve != 0 {
		if !((*TMemPage)(unsafe.Pointer(pPage)).Fleaf != 0) || (*TMemPage)(unsafe.Pointer(pPage)).FnFree+libc.Int32FromUint16((*(*func(*libc.TLS, uintptr, uintptr) Tu16)(unsafe.Pointer(&struct{ uintptr }{(*TMemPage)(unsafe.Pointer(pPage)).FxCellSize})))(tls, pPage, pCell))+int32(2) > libc.Int32FromUint32((*TBtShared)(unsafe.Pointer(pBt)).FusableSize*libc.Uint32FromInt32(2)/libc.Uint32FromInt32(3)) || libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FnCell) == int32(1) {
			/* A b-tree rebalance will be required after deleting this entry.
			 ** Save the cursor key.  */
			**(**int32)(__ccgo_up(bp)) = _saveCursorKey(tls, pCur)
			if **(**int32)(__ccgo_up(bp)) != 0 {
				return **(**int32)(__ccgo_up(bp))
			}
		} else {
			bPreserve = uint8(2)
		}
	}
	/* If the page containing the entry to delete is not a leaf page, move
	 ** the cursor to the largest entry in the tree that is smaller than
	 ** the entry being deleted. This cell will replace the cell being deleted
	 ** from the internal node. The 'previous' entry is used for this instead
	 ** of the 'next' entry, as the previous entry is always a part of the
	 ** sub-tree headed by the child page of the cell being deleted. This makes
	 ** balancing the tree following the delete operation easier.  */
	if !((*TMemPage)(unsafe.Pointer(pPage)).Fleaf != 0) {
		**(**int32)(__ccgo_up(bp)) = _sqlite3BtreePrevious(tls, pCur, 0)
		if **(**int32)(__ccgo_up(bp)) != 0 {
			return **(**int32)(__ccgo_up(bp))
		}
	}
	/* Save the positions of any other cursors open on this table before
	 ** making any modifications.  */
	if libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCur)).FcurFlags)&int32(BTCF_Multiple) != 0 {
		**(**int32)(__ccgo_up(bp)) = _saveAllCursors(tls, pBt, (*TBtCursor)(unsafe.Pointer(pCur)).FpgnoRoot, pCur)
		if **(**int32)(__ccgo_up(bp)) != 0 {
			return **(**int32)(__ccgo_up(bp))
		}
	}
	/* If this is a delete operation to remove a row from a table b-tree,
	 ** invalidate any incrblob cursors open on the row being deleted.  */
	if (*TBtCursor)(unsafe.Pointer(pCur)).FpKeyInfo == uintptr(0) && (*TBtree)(unsafe.Pointer(p)).FhasIncrblobCur != 0 {
		_invalidateIncrblobCursors(tls, p, (*TBtCursor)(unsafe.Pointer(pCur)).FpgnoRoot, (*TBtCursor)(unsafe.Pointer(pCur)).Finfo.FnKey, 0)
	}
	/* Make the page containing the entry to be deleted writable. Then free any
	 ** overflow pages associated with the entry and finally remove the cell
	 ** itself from within the page.  */
	**(**int32)(__ccgo_up(bp)) = _sqlite3PagerWrite(tls, (*TMemPage)(unsafe.Pointer(pPage)).FpDbPage)
	if **(**int32)(__ccgo_up(bp)) != 0 {
		return **(**int32)(__ccgo_up(bp))
	}
	(*(*func(*libc.TLS, uintptr, uintptr, uintptr))(unsafe.Pointer(&struct{ uintptr }{(*TMemPage)(unsafe.Pointer(pPage)).FxParseCell})))(tls, pPage, pCell, bp+8)
	if uint32((**(**TCellInfo)(__ccgo_up(bp + 8))).FnLocal) != (**(**TCellInfo)(__ccgo_up(bp + 8))).FnPayload {
		**(**int32)(__ccgo_up(bp)) = _clearCellOverflow(tls, pPage, pCell, bp+8)
	} else {
		**(**int32)(__ccgo_up(bp)) = SQLITE_OK
	}
	_dropCell(tls, pPage, iCellIdx, libc.Int32FromUint16((**(**TCellInfo)(__ccgo_up(bp + 8))).FnSize), bp)
	if **(**int32)(__ccgo_up(bp)) != 0 {
		return **(**int32)(__ccgo_up(bp))
	}
	/* If the cell deleted was not located on a leaf page, then the cursor
	 ** is currently pointing to the largest entry in the sub-tree headed
	 ** by the child-page of the cell that was just deleted from an internal
	 ** node. The cell from the leaf node needs to be moved to the internal
	 ** node to replace the deleted cell.  */
	if !((*TMemPage)(unsafe.Pointer(pPage)).Fleaf != 0) {
		pLeaf = (*TBtCursor)(unsafe.Pointer(pCur)).FpPage
		if (*TMemPage)(unsafe.Pointer(pLeaf)).FnFree < 0 {
			**(**int32)(__ccgo_up(bp)) = _btreeComputeFreeSpace(tls, pLeaf)
			if **(**int32)(__ccgo_up(bp)) != 0 {
				return **(**int32)(__ccgo_up(bp))
			}
		}
		if iCellDepth < int32((*TBtCursor)(unsafe.Pointer(pCur)).FiPage)-int32(1) {
			n = (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(pCur + 144 + uintptr(iCellDepth+int32(1))*8)))).Fpgno
		} else {
			n = (*TMemPage)(unsafe.Pointer((*TBtCursor)(unsafe.Pointer(pCur)).FpPage)).Fpgno
		}
		pCell = (*TMemPage)(unsafe.Pointer(pLeaf)).FaData + uintptr(libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pLeaf)).FmaskPage)&(libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TMemPage)(unsafe.Pointer(pLeaf)).FaCellIdx + uintptr(int32(2)*(libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pLeaf)).FnCell)-int32(1))))))<<libc.Int32FromInt32(8)|libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TMemPage)(unsafe.Pointer(pLeaf)).FaCellIdx + uintptr(int32(2)*(libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pLeaf)).FnCell)-int32(1))) + 1)))))
		if pCell < (*TMemPage)(unsafe.Pointer(pLeaf)).FaData+4 {
			return _sqlite3CorruptError(tls, int32(83106))
		}
		nCell = libc.Int32FromUint16((*(*func(*libc.TLS, uintptr, uintptr) Tu16)(unsafe.Pointer(&struct{ uintptr }{(*TMemPage)(unsafe.Pointer(pLeaf)).FxCellSize})))(tls, pLeaf, pCell))
		pTmp = (*TBtShared)(unsafe.Pointer(pBt)).FpTmpSpace
		**(**int32)(__ccgo_up(bp)) = _sqlite3PagerWrite(tls, (*TMemPage)(unsafe.Pointer(pLeaf)).FpDbPage)
		if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
			**(**int32)(__ccgo_up(bp)) = _insertCell(tls, pPage, iCellIdx, pCell-uintptr(4), nCell+int32(4), pTmp, n)
		}
		_dropCell(tls, pLeaf, libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pLeaf)).FnCell)-int32(1), nCell, bp)
		if **(**int32)(__ccgo_up(bp)) != 0 {
			return **(**int32)(__ccgo_up(bp))
		}
	}
	/* Balance the tree. If the entry deleted was located on a leaf page,
	 ** then the cursor still points to that page. In this case the first
	 ** call to balance() repairs the tree, and the if(...) condition is
	 ** never true.
	 **
	 ** Otherwise, if the entry deleted was on an internal node page, then
	 ** pCur is pointing to the leaf page from which a cell was removed to
	 ** replace the cell deleted from the internal node. This is slightly
	 ** tricky as the leaf node may be underfull, and the internal node may
	 ** be either under or overfull. In this case run the balancing algorithm
	 ** on the leaf node first. If the balance proceeds far enough up the
	 ** tree that we can be sure that any problem in the internal node has
	 ** been corrected, so be it. Otherwise, after balancing the leaf node,
	 ** walk the cursor up the tree to the internal node and balance it as
	 ** well.  */
	if (*TMemPage)(unsafe.Pointer((*TBtCursor)(unsafe.Pointer(pCur)).FpPage)).FnFree*int32(3) <= libc.Int32FromUint32((*TBtShared)(unsafe.Pointer((*TBtCursor)(unsafe.Pointer(pCur)).FpBt)).FusableSize)*int32(2) {
		/* Optimization: If the free space is less than 2/3rds of the page,
		 ** then balance() will always be a no-op.  No need to invoke it. */
		**(**int32)(__ccgo_up(bp)) = SQLITE_OK
	} else {
		**(**int32)(__ccgo_up(bp)) = _balance(tls, pCur)
	}
	if **(**int32)(__ccgo_up(bp)) == SQLITE_OK && int32((*TBtCursor)(unsafe.Pointer(pCur)).FiPage) > iCellDepth {
		_releasePageNotNull(tls, (*TBtCursor)(unsafe.Pointer(pCur)).FpPage)
		(*TBtCursor)(unsafe.Pointer(pCur)).FiPage = (*TBtCursor)(unsafe.Pointer(pCur)).FiPage - 1
		for int32((*TBtCursor)(unsafe.Pointer(pCur)).FiPage) > iCellDepth {
			v2 = pCur + 84
			v1 = *(*Ti8)(unsafe.Pointer(v2))
			*(*Ti8)(unsafe.Pointer(v2)) = *(*Ti8)(unsafe.Pointer(v2)) - 1
			_releasePage(tls, **(**uintptr)(__ccgo_up(pCur + 144 + uintptr(v1)*8)))
		}
		(*TBtCursor)(unsafe.Pointer(pCur)).FpPage = **(**uintptr)(__ccgo_up(pCur + 144 + uintptr((*TBtCursor)(unsafe.Pointer(pCur)).FiPage)*8))
		**(**int32)(__ccgo_up(bp)) = _balance(tls, pCur)
	}
	if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
		if libc.Int32FromUint8(bPreserve) > int32(1) {
			(*TBtCursor)(unsafe.Pointer(pCur)).FeState = uint8(CURSOR_SKIPNEXT)
			if iCellIdx >= libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FnCell) {
				(*TBtCursor)(unsafe.Pointer(pCur)).FskipNext = -int32(1)
				(*TBtCursor)(unsafe.Pointer(pCur)).Fix = libc.Uint16FromInt32(libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FnCell) - int32(1))
			} else {
				(*TBtCursor)(unsafe.Pointer(pCur)).FskipNext = int32(1)
			}
		} else {
			**(**int32)(__ccgo_up(bp)) = _moveToRoot(tls, pCur)
			if bPreserve != 0 {
				_btreeReleaseAllCursorPages(tls, pCur)
				(*TBtCursor)(unsafe.Pointer(pCur)).FeState = uint8(CURSOR_REQUIRESEEK)
			}
			if **(**int32)(__ccgo_up(bp)) == int32(SQLITE_EMPTY) {
				**(**int32)(__ccgo_up(bp)) = SQLITE_OK
			}
		}
	}
	return **(**int32)(__ccgo_up(bp))
}

// C documentation
//
//	/*
//	** zIn is a UTF-16 encoded unicode string at least nByte bytes long.
//	** Return the number of bytes in the first nChar unicode characters
//	** in pZ.  nChar must be non-negative.  Surrogate pairs count as a single
//	** character.
//	*/
func _sqlite3Utf16ByteLen(tls *libc.TLS, zIn uintptr, nByte int32, nChar int32) (r int32) {
	var c, n int32
	var z, zEnd uintptr
	_, _, _, _ = c, n, z, zEnd
	z = zIn
	zEnd = z + uintptr(nByte-int32(1))
	n = 0
	if true {
		z = z + 1
	}
	for n < nChar && z <= zEnd {
		c = libc.Int32FromUint8(**(**uint8)(__ccgo_up(z)))
		z = z + uintptr(2)
		if c >= int32(0xd8) && c < int32(0xdc) && z <= zEnd && libc.Int32FromUint8(**(**uint8)(__ccgo_up(z))) >= int32(0xdc) && libc.Int32FromUint8(**(**uint8)(__ccgo_up(z))) < int32(0xe0) {
			z = z + uintptr(2)
		}
		n = n + 1
	}
	return int32(int64(z)-int64(zIn)) - libc.BoolInt32(true)
}

// C documentation
//
//	/*
//	** Check to see if the frame with header in aFrame[] and content
//	** in aData[] is valid.  If it is a valid frame, fill *piPage and
//	** *pnTruncate and return true.  Return if the frame is not valid.
//	*/
func _walDecodeFrame(tls *libc.TLS, pWal uintptr, piPage uintptr, pnTruncate uintptr, aData uintptr, aFrame uintptr) (r int32) {
	var aCksum uintptr
	var nativeCksum int32
	var pgno Tu32
	_, _, _ = aCksum, nativeCksum, pgno /* True for native byte-order checksums */
	aCksum = pWal + 72 + 24             /* Page number of the frame */
	/* A frame is only valid if the salt values in the frame-header
	 ** match the salt values in the wal-header.
	 */
	if libc.Xmemcmp(tls, pWal+72+32, aFrame+8, uint64(8)) != 0 {
		return 0
	}
	/* A frame is only valid if the page number is greater than zero.
	 */
	pgno = _sqlite3Get4byte(tls, aFrame)
	if pgno == uint32(0) {
		return 0
	}
	/* A frame is only valid if a checksum of the WAL header,
	 ** all prior frames, the first 16 bytes of this frame-header,
	 ** and the frame-data matches the checksum in the last 8
	 ** bytes of this frame-header.
	 */
	nativeCksum = libc.BoolInt32(libc.Int32FromUint8((*TWal)(unsafe.Pointer(pWal)).Fhdr.FbigEndCksum) == SQLITE_BIGENDIAN)
	_walChecksumBytes(tls, nativeCksum, aFrame, int32(8), aCksum, aCksum)
	_walChecksumBytes(tls, nativeCksum, aData, libc.Int32FromUint32((*TWal)(unsafe.Pointer(pWal)).FszPage), aCksum, aCksum)
	if **(**Tu32)(__ccgo_up(aCksum)) != _sqlite3Get4byte(tls, aFrame+16) || **(**Tu32)(__ccgo_up(aCksum + 1*4)) != _sqlite3Get4byte(tls, aFrame+20) {
		/* Checksum failed. */
		return 0
	}
	/* If we reach this point, the frame is valid.  Return the page number
	 ** and the new database size.
	 */
	**(**Tu32)(__ccgo_up(piPage)) = pgno
	**(**Tu32)(__ccgo_up(pnTruncate)) = _sqlite3Get4byte(tls, aFrame+4)
	return int32(1)
}
