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

//go:build (freebsd && 386) || (linux && 386)

package sqlite3

import (
	"unsafe"

	"modernc.org/libc"
)

type TFts5DlidxIter = struct {
	FnLvl   int32
	FiSegid int32
}

type TIndex = struct {
	FzName         uintptr
	FaiColumn      uintptr
	FaiRowLogEst   uintptr
	FpTable        uintptr
	FzColAff       uintptr
	FpNext         uintptr
	FpSchema       uintptr
	FaSortOrder    uintptr
	FazColl        uintptr
	FpPartIdxWhere uintptr
	FaColExpr      uintptr
	Ftnum          TPgno
	FszIdxRow      TLogEst
	FnKeyCol       Tu16
	FnColumn       Tu16
	FonError       Tu8
	F__ccgo56      uint16
	FnSample       int32
	FmxSample      int32
	FnSampleCol    int32
	FaAvgEq        uintptr
	FaSample       uintptr
	FaiRowEst      uintptr
	FnRowEst0      TtRowcnt
	FcolNotIdxed   TBitmask
}

type TPreUpdate = struct {
	Fv            uintptr
	FpCsr         uintptr
	Fop           int32
	FaRecord      uintptr
	FpKeyinfo     uintptr
	FpUnpacked    uintptr
	FpNewUnpacked uintptr
	FiNewReg      int32
	FiBlobWrite   int32
	FiKey1        Ti64
	FiKey2        Ti64
	Foldipk       TMem
	FaNew         uintptr
	FpTab         uintptr
	FpPk          uintptr
	FapDflt       uintptr
	FuKey         struct {
		FkeyinfoSpace [20]Tu8
	}
}

/*
** RowSetEntry objects are allocated in large chunks (instances of the
** following structure) to reduce memory allocation overhead.  The
** chunks are kept on a linked list so that they can be deallocated
** when the RowSet is destroyed.
 */
type TRowSetChunk = struct {
	FpNextChunk uintptr
	FaEntry     [63]TRowSetEntry
}

type TSrcList = struct {
	FnSrc   int32
	FnAlloc Tu32
}

type TUnpackedRecord = struct {
	FpKeyInfo uintptr
	FaMem     uintptr
	Fu        struct {
		Fi           [0]Ti64
		Fz           uintptr
		F__ccgo_pad2 [4]byte
	}
	Fn          int32
	FnField     Tu16
	Fdefault_rc Ti8
	FerrCode    Tu8
	Fr1         Ti8
	Fr2         Ti8
	FeqSeen     Tu8
}

// C documentation
//
//	/*
//	** A single VDBE is an opaque structure named "Vdbe".  Only routines
//	** in the source file sqliteVdbe.c are allowed to see the insides
//	** of this structure.
//	*/
type TVdbe = struct {
	Fdb                 uintptr
	FppVPrev            uintptr
	FpVNext             uintptr
	FpParse             uintptr
	FnVar               TynVar
	FnMem               int32
	FnCursor            int32
	FcacheCtr           Tu32
	Fpc                 int32
	Frc                 int32
	FnChange            Ti64
	FiStatement         int32
	FiCurrentTime       Ti64
	FnFkConstraint      Ti64
	FnStmtDefCons       Ti64
	FnStmtDefImmCons    Ti64
	FaMem               uintptr
	FapArg              uintptr
	FapCsr              uintptr
	FaVar               uintptr
	FaOp                uintptr
	FnOp                int32
	FnOpAlloc           int32
	FaColName           uintptr
	FpResultRow         uintptr
	FzErrMsg            uintptr
	FpVList             uintptr
	FstartTime          Ti64
	FnResColumn         Tu16
	FnResAlloc          Tu16
	FerrorAction        Tu8
	FminWriteFileFormat Tu8
	FprepFlags          Tu8
	FeVdbeState         Tu8
	F__ccgo144          uint16
	FbtreeMask          TyDbMask
	FlockMask           TyDbMask
	FaCounter           [9]Tu32
	FzSql               uintptr
	FpFree              uintptr
	FpFrame             uintptr
	FpDelFrame          uintptr
	FnFrame             int32
	Fexpmask            Tu32
	FpProgram           uintptr
	FpAuxData           uintptr
}

type TWhereInfo = struct {
	FpParse          uintptr
	FpTabList        uintptr
	FpOrderBy        uintptr
	FpResultSet      uintptr
	FpSelect         uintptr
	FaiCurOnePass    [2]int32
	FiContinue       int32
	FiBreak          int32
	FsavedNQueryLoop int32
	FwctrlFlags      Tu16
	FiLimit          TLogEst
	FnLevel          Tu8
	FnOBSat          Ti8
	FeOnePass        Tu8
	FeDistinct       Tu8
	F__ccgo48        uint8
	FnRowOut         TLogEst
	FiTop            int32
	FiEndWhere       int32
	FpLoops          uintptr
	FpMemToFree      uintptr
	FrevMask         TBitmask
	FsWC             TWhereClause
	FsMaskSet        TWhereMaskSet
}

func Xsqlite3_bind_zeroblob64(tls *libc.TLS, pStmt uintptr, i int32, n Tsqlite3_uint64) (r int32) {
	var p uintptr
	var rc int32
	_, _ = p, rc
	p = pStmt
	Xsqlite3_mutex_enter(tls, (*Tsqlite3)(unsafe.Pointer((*TVdbe)(unsafe.Pointer(p)).Fdb)).Fmutex)
	if n > libc.Uint64FromInt32(**(**int32)(__ccgo_up((*TVdbe)(unsafe.Pointer(p)).Fdb + 116))) {
		rc = int32(SQLITE_TOOBIG)
	} else {
		rc = Xsqlite3_bind_zeroblob(tls, pStmt, i, libc.Int32FromUint64(n))
	}
	rc = _sqlite3ApiExit(tls, (*TVdbe)(unsafe.Pointer(p)).Fdb, rc)
	Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer((*TVdbe)(unsafe.Pointer(p)).Fdb)).Fmutex)
	return rc
}

// C documentation
//
//	/*
//	** Set all the parameters in the compiled SQL statement to NULL.
//	*/
func Xsqlite3_clear_bindings(tls *libc.TLS, pStmt uintptr) (r int32) {
	var i, rc int32
	var mutex, p uintptr
	_, _, _, _ = i, mutex, p, rc
	rc = SQLITE_OK
	p = pStmt
	mutex = (*Tsqlite3)(unsafe.Pointer((*TVdbe)(unsafe.Pointer(p)).Fdb)).Fmutex
	Xsqlite3_mutex_enter(tls, mutex)
	i = 0
	for {
		if !(i < int32((*TVdbe)(unsafe.Pointer(p)).FnVar)) {
			break
		}
		_sqlite3VdbeMemRelease(tls, (*TVdbe)(unsafe.Pointer(p)).FaVar+uintptr(i)*40)
		(**(**TMem)(__ccgo_up((*TVdbe)(unsafe.Pointer(p)).FaVar + uintptr(i)*40))).Fflags = uint16(MEM_Null)
		goto _1
	_1:
		;
		i = i + 1
	}
	if (*TVdbe)(unsafe.Pointer(p)).Fexpmask != 0 {
		libc.SetBitFieldPtr16Uint32(p+144, libc.Uint32FromInt32(1), 0, 0x3)
	}
	Xsqlite3_mutex_leave(tls, mutex)
	return rc
}

// C documentation
//
//	/*
//	** Allocate memory to hold names for a database, journal file, WAL file,
//	** and query parameters.  The pointer returned is valid for use by
//	** sqlite3_filename_database() and sqlite3_uri_parameter() and related
//	** functions.
//	**
//	** Memory layout must be compatible with that generated by the pager
//	** and expected by sqlite3_uri_parameter() and databaseName().
//	*/
func Xsqlite3_create_filename(tls *libc.TLS, zDatabase uintptr, zJournal uintptr, zWal uintptr, nParam int32, azParam uintptr) (r uintptr) {
	var i int32
	var nByte Tsqlite3_int64
	var p, pResult, v2 uintptr
	_, _, _, _, _ = i, nByte, p, pResult, v2
	nByte = libc.Int64FromUint32(libc.Xstrlen(tls, zDatabase) + libc.Xstrlen(tls, zJournal) + libc.Xstrlen(tls, zWal) + uint32(10))
	i = 0
	for {
		if !(i < nParam*int32(2)) {
			break
		}
		nByte = nByte + libc.Int64FromUint32(libc.Xstrlen(tls, **(**uintptr)(__ccgo_up(azParam + uintptr(i)*4)))+uint32(1))
		goto _1
	_1:
		;
		i = i + 1
	}
	v2 = Xsqlite3_malloc64(tls, libc.Uint64FromInt64(nByte))
	p = v2
	pResult = v2
	if p == uintptr(0) {
		return uintptr(0)
	}
	libc.Xmemset(tls, p, 0, uint32(4))
	p = p + uintptr(4)
	p = _appendText(tls, p, zDatabase)
	i = 0
	for {
		if !(i < nParam*int32(2)) {
			break
		}
		p = _appendText(tls, p, **(**uintptr)(__ccgo_up(azParam + uintptr(i)*4)))
		goto _3
	_3:
		;
		i = i + 1
	}
	v2 = p
	p = p + 1
	**(**int8)(__ccgo_up(v2)) = 0
	p = _appendText(tls, p, zJournal)
	p = _appendText(tls, p, zWal)
	v2 = p
	p = p + 1
	**(**int8)(__ccgo_up(v2)) = 0
	v2 = p
	p = p + 1
	**(**int8)(__ccgo_up(v2)) = 0
	return pResult + uintptr(4)
}

// C documentation
//
//	/*
//	** Configuration settings for an individual database connection
//	*/
func Xsqlite3_db_config(tls *libc.TLS, db uintptr, op int32, va uintptr) (r int32) {
	var ap Tva_list
	var cnt, nIn, onoff, rc, sz int32
	var i uint32
	var oldFlags Tu64
	var pBuf, pOut, pRes uintptr
	_, _, _, _, _, _, _, _, _, _, _ = ap, cnt, i, nIn, oldFlags, onoff, pBuf, pOut, pRes, rc, sz
	Xsqlite3_mutex_enter(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
	ap = va
	switch op {
	case int32(SQLITE_DBCONFIG_MAINDBNAME):
		/* IMP: R-06824-28531 */
		/* IMP: R-36257-52125 */
		(**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb))).FzDbSName = libc.VaUintptr(&ap)
		rc = SQLITE_OK
	case int32(SQLITE_DBCONFIG_LOOKASIDE):
		pBuf = libc.VaUintptr(&ap) /* IMP: R-26835-10964 */
		sz = libc.VaInt32(&ap)     /* IMP: R-47871-25994 */
		cnt = libc.VaInt32(&ap)    /* IMP: R-04460-53386 */
		rc = _setupLookaside(tls, db, pBuf, sz, cnt)
	case int32(SQLITE_DBCONFIG_FP_DIGITS):
		nIn = libc.VaInt32(&ap)
		pOut = libc.VaUintptr(&ap)
		if nIn > int32(3) && nIn < int32(24) {
			(*Tsqlite3)(unsafe.Pointer(db)).FnFpDigit = libc.Uint8FromInt32(nIn)
		}
		if pOut != 0 {
			**(**int32)(__ccgo_up(pOut)) = libc.Int32FromUint8((*Tsqlite3)(unsafe.Pointer(db)).FnFpDigit)
		}
		rc = SQLITE_OK
	default:
		rc = int32(SQLITE_ERROR) /* IMP: R-42790-23372 */
		i = uint32(0)
		for {
			if !(i < libc.Uint32FromInt32(libc.Int32FromUint32(libc.Uint32FromInt64(252)/libc.Uint32FromInt64(12)))) {
				break
			}
			if _aFlagOp[i].Fop == op {
				onoff = libc.VaInt32(&ap)
				pRes = libc.VaUintptr(&ap)
				oldFlags = (*Tsqlite3)(unsafe.Pointer(db)).Fflags
				if onoff > 0 {
					**(**Tu64)(__ccgo_up(db + 28)) |= _aFlagOp[i].Fmask
				} else {
					if onoff == 0 {
						**(**Tu64)(__ccgo_up(db + 28)) &= ^_aFlagOp[i].Fmask
					}
				}
				if oldFlags != (*Tsqlite3)(unsafe.Pointer(db)).Fflags {
					_sqlite3ExpirePreparedStatements(tls, db, 0)
				}
				if pRes != 0 {
					**(**int32)(__ccgo_up(pRes)) = libc.BoolInt32((*Tsqlite3)(unsafe.Pointer(db)).Fflags&_aFlagOp[i].Fmask != uint64(0))
				}
				rc = SQLITE_OK
				break
			}
			goto _1
		_1:
			;
			i = i + 1
		}
		break
	}
	_ = ap
	Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
	return rc
}

// C documentation
//
//	/*
//	** Query status information for a single database connection
//	*/
func Xsqlite3_db_status64(tls *libc.TLS, db uintptr, op int32, pCurrent uintptr, pHighwtr uintptr, resetFlag int32) (r int32) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var i, i1, i2, nByte, rc int32
	var p, p1, pBt, pPager, pPager1, pPager2, pSchema, pVdbe uintptr
	var totalUsed Tsqlite3_int64
	var _ /* H at bp+0 */ int32
	var _ /* nByte at bp+4 */ int32
	var _ /* nByte at bp+8 */ int32
	var _ /* nRet at bp+16 */ Tu64
	var _ /* nRet at bp+24 */ Tu64
	_, _, _, _, _, _, _, _, _, _, _, _, _, _ = i, i1, i2, nByte, p, p1, pBt, pPager, pPager1, pPager2, pSchema, pVdbe, rc, totalUsed
	rc = SQLITE_OK /* Return code */
	Xsqlite3_mutex_enter(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
	switch op {
	case SQLITE_DBSTATUS_LOOKASIDE_USED:
		**(**int32)(__ccgo_up(bp)) = 0
		**(**Tsqlite3_int64)(__ccgo_up(pCurrent)) = int64(_sqlite3LookasideUsed(tls, db, bp))
		**(**Tsqlite3_int64)(__ccgo_up(pHighwtr)) = int64(**(**int32)(__ccgo_up(bp)))
		if resetFlag != 0 {
			p = (*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpFree
			if p != 0 {
				for (*TLookasideSlot)(unsafe.Pointer(p)).FpNext != 0 {
					p = (*TLookasideSlot)(unsafe.Pointer(p)).FpNext
				}
				(*TLookasideSlot)(unsafe.Pointer(p)).FpNext = (*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpInit
				(*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpInit = (*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpFree
				(*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpFree = uintptr(0)
			}
			p = (*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpSmallFree
			if p != 0 {
				for (*TLookasideSlot)(unsafe.Pointer(p)).FpNext != 0 {
					p = (*TLookasideSlot)(unsafe.Pointer(p)).FpNext
				}
				(*TLookasideSlot)(unsafe.Pointer(p)).FpNext = (*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpSmallInit
				(*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpSmallInit = (*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpSmallFree
				(*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpSmallFree = uintptr(0)
			}
		}
	case int32(SQLITE_DBSTATUS_LOOKASIDE_HIT):
		fallthrough
	case int32(SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE):
		fallthrough
	case int32(SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL):
		**(**Tsqlite3_int64)(__ccgo_up(pCurrent)) = 0
		**(**Tsqlite3_int64)(__ccgo_up(pHighwtr)) = libc.Int64FromUint32(**(**Tu32)(__ccgo_up(db + 316 + 16 + uintptr(op-int32(SQLITE_DBSTATUS_LOOKASIDE_HIT))*4)))
		if resetFlag != 0 {
			**(**Tu32)(__ccgo_up(db + 316 + 16 + uintptr(op-int32(SQLITE_DBSTATUS_LOOKASIDE_HIT))*4)) = uint32(0)
		}
		break
		/*
		 ** Return an approximation for the amount of memory currently used
		 ** by all pagers associated with the given database connection.  The
		 ** highwater mark is meaningless and is returned as zero.
		 */
		fallthrough
	case int32(SQLITE_DBSTATUS_CACHE_USED_SHARED):
		fallthrough
	case int32(SQLITE_DBSTATUS_CACHE_USED):
		totalUsed = 0
		_sqlite3BtreeEnterAll(tls, db)
		i = 0
		for {
			if !(i < (*Tsqlite3)(unsafe.Pointer(db)).FnDb) {
				break
			}
			pBt = (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(i)*16))).FpBt
			if pBt != 0 {
				pPager = _sqlite3BtreePager(tls, pBt)
				nByte = _sqlite3PagerMemUsed(tls, pPager)
				if op == int32(SQLITE_DBSTATUS_CACHE_USED_SHARED) {
					nByte = nByte / _sqlite3BtreeConnectionCount(tls, pBt)
				}
				totalUsed = totalUsed + int64(nByte)
			}
			goto _1
		_1:
			;
			i = i + 1
		}
		_sqlite3BtreeLeaveAll(tls, db)
		**(**Tsqlite3_int64)(__ccgo_up(pCurrent)) = totalUsed
		**(**Tsqlite3_int64)(__ccgo_up(pHighwtr)) = 0
		break
		/*
		 ** *pCurrent gets an accurate estimate of the amount of memory used
		 ** to store the schema for all databases (main, temp, and any ATTACHed
		 ** databases.  *pHighwtr is set to zero.
		 */
		fallthrough
	case int32(SQLITE_DBSTATUS_SCHEMA_USED): /* Used to iterate through schemas */
		**(**int32)(__ccgo_up(bp + 4)) = 0 /* Used to accumulate return value */
		_sqlite3BtreeEnterAll(tls, db)
		(*Tsqlite3)(unsafe.Pointer(db)).FpnBytesFreed = bp + 4
		(*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpEnd = (*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpStart
		i1 = 0
		for {
			if !(i1 < (*Tsqlite3)(unsafe.Pointer(db)).FnDb) {
				break
			}
			pSchema = (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(i1)*16))).FpSchema
			if pSchema != uintptr(0) {
				**(**int32)(__ccgo_up(bp + 4)) = libc.Int32FromUint32(uint32(**(**int32)(__ccgo_up(bp + 4))) + libc.Uint32FromInt32((*(*func(*libc.TLS, int32) int32)(unsafe.Pointer(&struct{ uintptr }{_sqlite3Config.Fm.FxRoundup})))(tls, int32(20)))*((*TSchema)(unsafe.Pointer(pSchema)).FtblHash.Fcount+(*TSchema)(unsafe.Pointer(pSchema)).FtrigHash.Fcount+(*TSchema)(unsafe.Pointer(pSchema)).FidxHash.Fcount+(*TSchema)(unsafe.Pointer(pSchema)).FfkeyHash.Fcount))
				**(**int32)(__ccgo_up(bp + 4)) = libc.Int32FromUint64(uint64(**(**int32)(__ccgo_up(bp + 4))) + Xsqlite3_msize(tls, (*TSchema)(unsafe.Pointer(pSchema)).FtblHash.Fht))
				**(**int32)(__ccgo_up(bp + 4)) = libc.Int32FromUint64(uint64(**(**int32)(__ccgo_up(bp + 4))) + Xsqlite3_msize(tls, (*TSchema)(unsafe.Pointer(pSchema)).FtrigHash.Fht))
				**(**int32)(__ccgo_up(bp + 4)) = libc.Int32FromUint64(uint64(**(**int32)(__ccgo_up(bp + 4))) + Xsqlite3_msize(tls, (*TSchema)(unsafe.Pointer(pSchema)).FidxHash.Fht))
				**(**int32)(__ccgo_up(bp + 4)) = libc.Int32FromUint64(uint64(**(**int32)(__ccgo_up(bp + 4))) + Xsqlite3_msize(tls, (*TSchema)(unsafe.Pointer(pSchema)).FfkeyHash.Fht))
				p1 = (*THash)(unsafe.Pointer(pSchema + 40)).Ffirst
				for {
					if !(p1 != 0) {
						break
					}
					_sqlite3DeleteTrigger(tls, db, (*THashElem)(unsafe.Pointer(p1)).Fdata)
					goto _3
				_3:
					;
					p1 = (*THashElem)(unsafe.Pointer(p1)).Fnext
				}
				p1 = (*THash)(unsafe.Pointer(pSchema + 8)).Ffirst
				for {
					if !(p1 != 0) {
						break
					}
					_sqlite3DeleteTable(tls, db, (*THashElem)(unsafe.Pointer(p1)).Fdata)
					goto _4
				_4:
					;
					p1 = (*THashElem)(unsafe.Pointer(p1)).Fnext
				}
			}
			goto _2
		_2:
			;
			i1 = i1 + 1
		}
		(*Tsqlite3)(unsafe.Pointer(db)).FpnBytesFreed = uintptr(0)
		(*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpEnd = (*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpTrueEnd
		_sqlite3BtreeLeaveAll(tls, db)
		**(**Tsqlite3_int64)(__ccgo_up(pHighwtr)) = 0
		**(**Tsqlite3_int64)(__ccgo_up(pCurrent)) = int64(**(**int32)(__ccgo_up(bp + 4)))
		break
		/*
		 ** *pCurrent gets an accurate estimate of the amount of memory used
		 ** to store all prepared statements.
		 ** *pHighwtr is set to zero.
		 */
		fallthrough
	case int32(SQLITE_DBSTATUS_STMT_USED): /* Used to iterate through VMs */
		**(**int32)(__ccgo_up(bp + 8)) = 0 /* Used to accumulate return value */
		(*Tsqlite3)(unsafe.Pointer(db)).FpnBytesFreed = bp + 8
		(*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpEnd = (*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpStart
		pVdbe = (*Tsqlite3)(unsafe.Pointer(db)).FpVdbe
		for {
			if !(pVdbe != 0) {
				break
			}
			_sqlite3VdbeDelete(tls, pVdbe)
			goto _5
		_5:
			;
			pVdbe = (*TVdbe)(unsafe.Pointer(pVdbe)).FpVNext
		}
		(*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpEnd = (*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpTrueEnd
		(*Tsqlite3)(unsafe.Pointer(db)).FpnBytesFreed = uintptr(0)
		**(**Tsqlite3_int64)(__ccgo_up(pHighwtr)) = 0 /* IMP: R-64479-57858 */
		**(**Tsqlite3_int64)(__ccgo_up(pCurrent)) = int64(**(**int32)(__ccgo_up(bp + 8)))
		break
		/*
		 ** Set *pCurrent to the total cache hits or misses encountered by all
		 ** pagers the database handle is connected to. *pHighwtr is always set
		 ** to zero.
		 */
		fallthrough
	case int32(SQLITE_DBSTATUS_CACHE_SPILL):
		op = libc.Int32FromInt32(SQLITE_DBSTATUS_CACHE_WRITE) + libc.Int32FromInt32(1)
		fallthrough
	case int32(SQLITE_DBSTATUS_CACHE_HIT):
		fallthrough
	case int32(SQLITE_DBSTATUS_CACHE_MISS):
		fallthrough
	case int32(SQLITE_DBSTATUS_CACHE_WRITE):
		**(**Tu64)(__ccgo_up(bp + 16)) = uint64(0)
		i2 = 0
		for {
			if !(i2 < (*Tsqlite3)(unsafe.Pointer(db)).FnDb) {
				break
			}
			if (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(i2)*16))).FpBt != 0 {
				pPager1 = _sqlite3BtreePager(tls, (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(i2)*16))).FpBt)
				_sqlite3PagerCacheStat(tls, pPager1, op, resetFlag, bp+16)
			}
			goto _6
		_6:
			;
			i2 = i2 + 1
		}
		**(**Tsqlite3_int64)(__ccgo_up(pHighwtr)) = 0 /* IMP: R-42420-56072 */
		/* IMP: R-54100-20147 */
		/* IMP: R-29431-39229 */
		**(**Tsqlite3_int64)(__ccgo_up(pCurrent)) = libc.Int64FromUint64(**(**Tu64)(__ccgo_up(bp + 16)))
		break
		/* Set *pCurrent to the number of bytes that the db database connection
		 ** has spilled to the filesystem in temporary files that could have been
		 ** stored in memory, had sufficient memory been available.
		 ** The *pHighwater is always set to zero.
		 */
		fallthrough
	case int32(SQLITE_DBSTATUS_TEMPBUF_SPILL):
		**(**Tu64)(__ccgo_up(bp + 24)) = uint64(0)
		if (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + 1*16))).FpBt != 0 {
			pPager2 = _sqlite3BtreePager(tls, (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + 1*16))).FpBt)
			_sqlite3PagerCacheStat(tls, pPager2, int32(SQLITE_DBSTATUS_CACHE_WRITE), resetFlag, bp+24)
			**(**Tu64)(__ccgo_up(bp + 24)) = **(**Tu64)(__ccgo_up(bp + 24)) * libc.Uint64FromInt32(_sqlite3BtreeGetPageSize(tls, (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + 1*16))).FpBt))
		}
		**(**Tu64)(__ccgo_up(bp + 24)) = **(**Tu64)(__ccgo_up(bp + 24)) + (*Tsqlite3)(unsafe.Pointer(db)).FnSpill
		if resetFlag != 0 {
			(*Tsqlite3)(unsafe.Pointer(db)).FnSpill = uint64(0)
		}
		**(**Tsqlite3_int64)(__ccgo_up(pHighwtr)) = 0
		**(**Tsqlite3_int64)(__ccgo_up(pCurrent)) = libc.Int64FromUint64(**(**Tu64)(__ccgo_up(bp + 24)))
		break
		/* Set *pCurrent to non-zero if there are unresolved deferred foreign
		 ** key constraints.  Set *pCurrent to zero if all foreign key constraints
		 ** have been satisfied.  The *pHighwtr is always set to zero.
		 */
		fallthrough
	case int32(SQLITE_DBSTATUS_DEFERRED_FKS):
		**(**Tsqlite3_int64)(__ccgo_up(pHighwtr)) = 0 /* IMP: R-11967-56545 */
		**(**Tsqlite3_int64)(__ccgo_up(pCurrent)) = libc.BoolInt64((*Tsqlite3)(unsafe.Pointer(db)).FnDeferredImmCons > 0 || (*Tsqlite3)(unsafe.Pointer(db)).FnDeferredCons > 0)
	default:
		rc = int32(SQLITE_ERROR)
	}
	Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
	return rc
}

// C documentation
//
//	/*
//	** External API to drop all virtual-table modules, except those named
//	** on the azNames list.
//	*/
func Xsqlite3_drop_modules(tls *libc.TLS, db uintptr, azNames uintptr) (r int32) {
	var ii int32
	var pMod, pNext, pThis uintptr
	_, _, _, _ = ii, pMod, pNext, pThis
	pThis = (*THash)(unsafe.Pointer(db + 400)).Ffirst
	for {
		if !(pThis != 0) {
			break
		}
		pMod = (*THashElem)(unsafe.Pointer(pThis)).Fdata
		pNext = (*THashElem)(unsafe.Pointer(pThis)).Fnext
		if azNames != 0 {
			ii = 0
			for {
				if !(**(**uintptr)(__ccgo_up(azNames + uintptr(ii)*4)) != uintptr(0) && libc.Xstrcmp(tls, **(**uintptr)(__ccgo_up(azNames + uintptr(ii)*4)), (*TModule)(unsafe.Pointer(pMod)).FzName) != 0) {
					break
				}
				goto _2
			_2:
				;
				ii = ii + 1
			}
			if **(**uintptr)(__ccgo_up(azNames + uintptr(ii)*4)) != uintptr(0) {
				goto _1
			}
		}
		_createModule(tls, db, (*TModule)(unsafe.Pointer(pMod)).FzName, uintptr(0), uintptr(0), uintptr(0))
		goto _1
	_1:
		;
		pThis = pNext
	}
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** Enable or disable extension loading.  Extension loading is disabled by
//	** default so as not to open security holes in older applications.
//	*/
func Xsqlite3_enable_load_extension(tls *libc.TLS, db uintptr, onoff int32) (r int32) {
	Xsqlite3_mutex_enter(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
	if onoff != 0 {
		**(**Tu64)(__ccgo_up(db + 28)) |= libc.Uint64FromInt32(libc.Int32FromInt32(SQLITE_LoadExtension) | libc.Int32FromInt32(SQLITE_LoadExtFunc))
	} else {
		**(**Tu64)(__ccgo_up(db + 28)) &= ^libc.Uint64FromInt32(libc.Int32FromInt32(SQLITE_LoadExtension) | libc.Int32FromInt32(SQLITE_LoadExtFunc))
	}
	Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** Return TRUE (non-zero) of the statement supplied as an argument needs
//	** to be recompiled.  A statement needs to be recompiled whenever the
//	** execution environment changes in a way that would alter the program
//	** that sqlite3_prepare() generates.  For example, if new functions or
//	** collating sequences are registered or if an authorizer function is
//	** added or changed.
//	*/
func Xsqlite3_expired(tls *libc.TLS, pStmt uintptr) (r int32) {
	var p uintptr
	_ = p
	p = pStmt
	return libc.BoolInt32(p == uintptr(0) || int32(Tbft(*(*uint16)(unsafe.Pointer(p + 144))&0x3>>0)) != 0)
}

// C documentation
//
//	/*
//	** Cause any pending operation to stop at its earliest opportunity.
//	*/
func Xsqlite3_interrupt(tls *libc.TLS, db uintptr) {
	libc.AtomicStoreNInt32(db+308, libc.Int32FromInt32(1), libc.Int32FromInt32(__ATOMIC_RELAXED))
}

// C documentation
//
//	/*
//	** Return true or false depending on whether or not an interrupt is
//	** pending on connection db.
//	*/
func Xsqlite3_is_interrupted(tls *libc.TLS, db uintptr) (r int32) {
	return libc.BoolInt32(libc.AtomicLoadNInt32(db+308, libc.Int32FromInt32(__ATOMIC_RELAXED)) != 0)
}

// C documentation
//
//	/*
//	** Change the value of a limit.  Report the old value.
//	** If an invalid limit index is supplied, report -1.
//	** Make no changes but still report the old value if the
//	** new limit is negative.
//	**
//	** A new lower limit does not shrink existing constructs.
//	** It merely prevents new constructs that exceed the limit
//	** from forming.
//	*/
func Xsqlite3_limit(tls *libc.TLS, db uintptr, limitId int32, newLimit int32) (r int32) {
	var oldLimit int32
	_ = oldLimit
	/* EVIDENCE-OF: R-30189-54097 For each limit category SQLITE_LIMIT_NAME
	 ** there is a hard upper bound set at compile-time by a C preprocessor
	 ** macro called SQLITE_MAX_NAME. (The "_LIMIT_" in the name is changed to
	 ** "_MAX_".)
	 */
	if limitId < 0 || limitId >= libc.Int32FromInt32(SQLITE_LIMIT_PARSER_DEPTH)+libc.Int32FromInt32(1) {
		return -int32(1)
	}
	oldLimit = **(**int32)(__ccgo_up(db + 116 + uintptr(limitId)*4))
	if newLimit >= 0 { /* IMP: R-52476-28732 */
		if newLimit > _aHardLimit[limitId] {
			newLimit = _aHardLimit[limitId] /* IMP: R-51463-25634 */
		} else {
			if newLimit < int32(SQLITE_MIN_LENGTH) && limitId == SQLITE_LIMIT_LENGTH {
				newLimit = int32(SQLITE_MIN_LENGTH)
			}
		}
		**(**int32)(__ccgo_up(db + 116 + uintptr(limitId)*4)) = newLimit
	}
	return oldLimit /* IMP: R-53341-35419 */
}

// C documentation
//
//	/*
//	** This function is called from within a pre-update callback to retrieve
//	** a field of the row currently being updated or deleted.
//	*/
func Xsqlite3_preupdate_old(tls *libc.TLS, db uintptr, iIdx int32, ppValue uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var aRec, p, pCol, pDflt, pMem, v1 uintptr
	var iStore, nByte, rc int32
	var nRec Tu32
	var _ /* pVal at bp+0 */ uintptr
	_, _, _, _, _, _, _, _, _, _ = aRec, iStore, nByte, nRec, p, pCol, pDflt, pMem, rc, v1
	rc = SQLITE_OK
	iStore = 0
	p = (*Tsqlite3)(unsafe.Pointer(db)).FpPreUpdate
	/* Test that this call is being made from within an SQLITE_DELETE or
	 ** SQLITE_UPDATE pre-update callback, and that iIdx is within range. */
	if !(p != 0) || (*TPreUpdate)(unsafe.Pointer(p)).Fop == int32(SQLITE_INSERT) {
		rc = _sqlite3MisuseError(tls, int32(95782))
		goto preupdate_old_out
	}
	if (*TPreUpdate)(unsafe.Pointer(p)).FpPk != 0 {
		iStore = _sqlite3TableColumnToIndex(tls, (*TPreUpdate)(unsafe.Pointer(p)).FpPk, iIdx)
	} else {
		if iIdx >= int32((*TTable)(unsafe.Pointer((*TPreUpdate)(unsafe.Pointer(p)).FpTab)).FnCol) {
			rc = _sqlite3MisuseError(tls, int32(95788))
			goto preupdate_old_out
		} else {
			iStore = int32(_sqlite3TableColumnToStorage(tls, (*TPreUpdate)(unsafe.Pointer(p)).FpTab, int16(iIdx)))
		}
	}
	if iStore >= int32((*TVdbeCursor)(unsafe.Pointer((*TPreUpdate)(unsafe.Pointer(p)).FpCsr)).FnField) || iStore < 0 {
		rc = int32(SQLITE_RANGE)
		goto preupdate_old_out
	}
	if iIdx == int32((*TTable)(unsafe.Pointer((*TPreUpdate)(unsafe.Pointer(p)).FpTab)).FiPKey) {
		v1 = p + 52
		pMem = v1
		**(**uintptr)(__ccgo_up(ppValue)) = v1
		_sqlite3VdbeMemSetInt64(tls, pMem, (*TPreUpdate)(unsafe.Pointer(p)).FiKey1)
	} else {
		/* If the old.* record has not yet been loaded into memory, do so now. */
		if (*TPreUpdate)(unsafe.Pointer(p)).FpUnpacked == uintptr(0) {
			nRec = _sqlite3BtreePayloadSize(tls, *(*uintptr)(unsafe.Pointer((*TPreUpdate)(unsafe.Pointer(p)).FpCsr + 36)))
			aRec = _sqlite3DbMallocRaw(tls, db, uint64(nRec))
			if !(aRec != 0) {
				goto preupdate_old_out
			}
			rc = _sqlite3BtreePayload(tls, *(*uintptr)(unsafe.Pointer((*TPreUpdate)(unsafe.Pointer(p)).FpCsr + 36)), uint32(0), nRec, aRec)
			if rc == SQLITE_OK {
				(*TPreUpdate)(unsafe.Pointer(p)).FpUnpacked = _vdbeUnpackRecord(tls, (*TPreUpdate)(unsafe.Pointer(p)).FpKeyinfo, libc.Int32FromUint32(nRec), aRec)
				if !((*TPreUpdate)(unsafe.Pointer(p)).FpUnpacked != 0) {
					rc = int32(SQLITE_NOMEM)
				}
			}
			if rc != SQLITE_OK {
				_sqlite3DbFree(tls, db, aRec)
				goto preupdate_old_out
			}
			(*TPreUpdate)(unsafe.Pointer(p)).FaRecord = aRec
		}
		v1 = (*TUnpackedRecord)(unsafe.Pointer((*TPreUpdate)(unsafe.Pointer(p)).FpUnpacked)).FaMem + uintptr(iStore)*40
		**(**uintptr)(__ccgo_up(ppValue)) = v1
		pMem = v1
		if iStore >= libc.Int32FromUint16((*TUnpackedRecord)(unsafe.Pointer((*TPreUpdate)(unsafe.Pointer(p)).FpUnpacked)).FnField) {
			/* This occurs when the table has been extended using ALTER TABLE
			 ** ADD COLUMN. The value to return is the default value of the column. */
			pCol = (*TTable)(unsafe.Pointer((*TPreUpdate)(unsafe.Pointer(p)).FpTab)).FaCol + uintptr(iIdx)*12
			if libc.Int32FromUint16((*TColumn)(unsafe.Pointer(pCol)).FiDflt) > 0 {
				if (*TPreUpdate)(unsafe.Pointer(p)).FapDflt == uintptr(0) {
					nByte = libc.Int32FromUint32(uint32(4) * libc.Uint32FromInt16((*TTable)(unsafe.Pointer((*TPreUpdate)(unsafe.Pointer(p)).FpTab)).FnCol))
					(*TPreUpdate)(unsafe.Pointer(p)).FapDflt = _sqlite3DbMallocZero(tls, db, libc.Uint64FromInt32(nByte))
					if (*TPreUpdate)(unsafe.Pointer(p)).FapDflt == uintptr(0) {
						goto preupdate_old_out
					}
				}
				if **(**uintptr)(__ccgo_up((*TPreUpdate)(unsafe.Pointer(p)).FapDflt + uintptr(iIdx)*4)) == uintptr(0) {
					**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
					pDflt = (*(*TExprList_item)(unsafe.Pointer((*(*struct {
						FaddColOffset int32
						FpFKey        uintptr
						FpDfltList    uintptr
					})(unsafe.Pointer((*TPreUpdate)(unsafe.Pointer(p)).FpTab + 44))).FpDfltList + 8 + uintptr(libc.Int32FromUint16((*TColumn)(unsafe.Pointer(pCol)).FiDflt)-int32(1))*20))).FpExpr
					rc = _sqlite3ValueFromExpr(tls, db, pDflt, (*Tsqlite3)(unsafe.Pointer(db)).Fenc, libc.Uint8FromInt8((*TColumn)(unsafe.Pointer(pCol)).Faffinity), bp)
					if rc == SQLITE_OK && **(**uintptr)(__ccgo_up(bp)) == uintptr(0) {
						rc = _sqlite3CorruptError(tls, int32(95844))
					}
					**(**uintptr)(__ccgo_up((*TPreUpdate)(unsafe.Pointer(p)).FapDflt + uintptr(iIdx)*4)) = **(**uintptr)(__ccgo_up(bp))
				}
				**(**uintptr)(__ccgo_up(ppValue)) = **(**uintptr)(__ccgo_up((*TPreUpdate)(unsafe.Pointer(p)).FapDflt + uintptr(iIdx)*4))
			} else {
				**(**uintptr)(__ccgo_up(ppValue)) = _columnNullValue(tls)
			}
		} else {
			if int32((**(**TColumn)(__ccgo_up((*TTable)(unsafe.Pointer((*TPreUpdate)(unsafe.Pointer(p)).FpTab)).FaCol + uintptr(iIdx)*12))).Faffinity) == int32(SQLITE_AFF_REAL) {
				if libc.Int32FromUint16((*TMem)(unsafe.Pointer(pMem)).Fflags)&(libc.Int32FromInt32(MEM_Int)|libc.Int32FromInt32(MEM_IntReal)) != 0 {
					_sqlite3VdbeMemRealify(tls, pMem)
				}
			}
		}
	}
	goto preupdate_old_out
preupdate_old_out:
	;
	_sqlite3Error(tls, db, rc)
	return _sqlite3ApiExit(tls, db, rc)
}

// C documentation
//
//	/*
//	** Register a profile function.  The pArg from the previously registered
//	** profile function is returned.
//	**
//	** A NULL profile function means that no profiling is executes.  A non-NULL
//	** profile is a pointer to a function that is invoked at the conclusion of
//	** each SQL statement that is run.
//	*/
func Xsqlite3_profile(tls *libc.TLS, db uintptr, __ccgo_fp_xProfile uintptr, pArg uintptr) (r uintptr) {
	var pOld, v1 uintptr
	_, _ = pOld, v1
	Xsqlite3_mutex_enter(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
	pOld = (*Tsqlite3)(unsafe.Pointer(db)).FpProfileArg
	(*Tsqlite3)(unsafe.Pointer(db)).FxProfile = __ccgo_fp_xProfile
	(*Tsqlite3)(unsafe.Pointer(db)).FpProfileArg = pArg
	v1 = db + 90
	*(*Tu8)(unsafe.Pointer(v1)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v1))) & libc.Int32FromInt32(SQLITE_TRACE_NONLEGACY_MASK))
	if (*Tsqlite3)(unsafe.Pointer(db)).FxProfile != 0 {
		v1 = db + 90
		*(*Tu8)(unsafe.Pointer(v1)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v1))) | libc.Int32FromInt32(SQLITE_TRACE_XPROFILE))
	}
	Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
	return pOld
}

func Xsqlite3_result_zeroblob64(tls *libc.TLS, pCtx uintptr, n Tu64) (r int32) {
	var pOut uintptr
	_ = pOut
	pOut = (*Tsqlite3_context)(unsafe.Pointer(pCtx)).FpOut
	if n > libc.Uint64FromInt32(**(**int32)(__ccgo_up((*TMem)(unsafe.Pointer(pOut)).Fdb + 116))) {
		Xsqlite3_result_error_toobig(tls, pCtx)
		return int32(SQLITE_TOOBIG)
	}
	_sqlite3VdbeMemSetZeroBlob(tls, (*Tsqlite3_context)(unsafe.Pointer(pCtx)).FpOut, libc.Int32FromUint64(n))
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** Add new client data to a database connection.
//	*/
func Xsqlite3_set_clientdata(tls *libc.TLS, db uintptr, zName uintptr, pData uintptr, __ccgo_fp_xDestructor uintptr) (r int32) {
	var n Tsize_t
	var p, pp uintptr
	_, _, _ = n, p, pp
	Xsqlite3_mutex_enter(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
	pp = db + 544
	p = (*Tsqlite3)(unsafe.Pointer(db)).FpDbData
	for {
		if !(p != 0 && libc.Xstrcmp(tls, p+12, zName) != 0) {
			break
		}
		pp = p
		goto _1
	_1:
		;
		p = (*TDbClientData)(unsafe.Pointer(p)).FpNext
	}
	if p != 0 {
		if (*TDbClientData)(unsafe.Pointer(p)).FxDestructor != 0 {
			(*(*func(*libc.TLS, uintptr))(unsafe.Pointer(&struct{ uintptr }{(*TDbClientData)(unsafe.Pointer(p)).FxDestructor})))(tls, (*TDbClientData)(unsafe.Pointer(p)).FpData)
		}
		if pData == uintptr(0) {
			**(**uintptr)(__ccgo_up(pp)) = (*TDbClientData)(unsafe.Pointer(p)).FpNext
			Xsqlite3_free(tls, p)
			Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
			return SQLITE_OK
		}
	} else {
		if pData == uintptr(0) {
			Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
			return SQLITE_OK
		} else {
			n = libc.Xstrlen(tls, zName)
			p = Xsqlite3_malloc64(tls, uint64(uint32(libc.UintptrFromInt32(0)+12)+(n+libc.Uint32FromInt32(1))))
			if p == uintptr(0) {
				if __ccgo_fp_xDestructor != 0 {
					(*(*func(*libc.TLS, uintptr))(unsafe.Pointer(&struct{ uintptr }{__ccgo_fp_xDestructor})))(tls, pData)
				}
				Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
				return int32(SQLITE_NOMEM)
			}
			libc.Xmemcpy(tls, p+12, zName, n+uint32(1))
			(*TDbClientData)(unsafe.Pointer(p)).FpNext = (*Tsqlite3)(unsafe.Pointer(db)).FpDbData
			(*Tsqlite3)(unsafe.Pointer(db)).FpDbData = p
		}
	}
	(*TDbClientData)(unsafe.Pointer(p)).FpData = pData
	(*TDbClientData)(unsafe.Pointer(p)).FxDestructor = __ccgo_fp_xDestructor
	Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** Set the soft heap-size limit for the library.  An argument of
//	** zero disables the limit.  A negative argument is a no-op used to
//	** obtain the return value.
//	**
//	** The return value is the value of the heap limit just before this
//	** interface was called.
//	**
//	** If the hard heap limit is enabled, then the soft heap limit cannot
//	** be disabled nor raised above the hard heap limit.
//	*/
func Xsqlite3_soft_heap_limit64(tls *libc.TLS, n Tsqlite3_int64) (r Tsqlite3_int64) {
	var excess, nUsed, priorLimit Tsqlite3_int64
	var rc int32
	_, _, _, _ = excess, nUsed, priorLimit, rc
	rc = Xsqlite3_initialize(tls)
	if rc != 0 {
		return int64(-int32(1))
	}
	Xsqlite3_mutex_enter(tls, _mem0.Fmutex)
	priorLimit = _mem0.FalarmThreshold
	if n < 0 {
		Xsqlite3_mutex_leave(tls, _mem0.Fmutex)
		return priorLimit
	}
	if _mem0.FhardLimit > 0 && (n > _mem0.FhardLimit || n == 0) {
		n = _mem0.FhardLimit
	}
	_mem0.FalarmThreshold = n
	nUsed = _sqlite3StatusValue(tls, SQLITE_STATUS_MEMORY_USED)
	libc.AtomicStoreNInt32(uintptr(unsafe.Pointer(&_mem0))+20, libc.BoolInt32(n > 0 && n <= nUsed), libc.Int32FromInt32(__ATOMIC_RELAXED))
	Xsqlite3_mutex_leave(tls, _mem0.Fmutex)
	excess = Xsqlite3_memory_used(tls) - n
	if excess > 0 {
		Xsqlite3_release_memory(tls, int32(excess&libc.Int64FromInt32(0x7fffffff)))
	}
	return priorLimit
}

// C documentation
//
//	/*
//	** Set the explain mode for a statement.
//	*/
func Xsqlite3_stmt_explain(tls *libc.TLS, pStmt uintptr, eMode int32) (r int32) {
	var rc int32
	var v uintptr
	_, _ = rc, v
	v = pStmt
	Xsqlite3_mutex_enter(tls, (*Tsqlite3)(unsafe.Pointer((*TVdbe)(unsafe.Pointer(v)).Fdb)).Fmutex)
	if int32(Tbft(*(*uint16)(unsafe.Pointer(v + 144))&0xc>>2)) == eMode {
		rc = SQLITE_OK
	} else {
		if eMode < 0 || eMode > int32(2) {
			rc = int32(SQLITE_ERROR)
		} else {
			if libc.Int32FromUint8((*TVdbe)(unsafe.Pointer(v)).FprepFlags)&int32(SQLITE_PREPARE_SAVESQL) == 0 {
				rc = int32(SQLITE_ERROR)
			} else {
				if libc.Int32FromUint8((*TVdbe)(unsafe.Pointer(v)).FeVdbeState) != int32(VDBE_READY_STATE) {
					rc = int32(SQLITE_BUSY)
				} else {
					if (*TVdbe)(unsafe.Pointer(v)).FnMem >= int32(10) && (eMode != int32(2) || int32(Tbft(*(*uint16)(unsafe.Pointer(v + 144))&0x100>>8)) != 0) {
						/* No reprepare necessary */
						libc.SetBitFieldPtr16Uint32(v+144, libc.Uint32FromInt32(eMode), 2, 0xc)
						rc = SQLITE_OK
					} else {
						libc.SetBitFieldPtr16Uint32(v+144, libc.Uint32FromInt32(eMode), 2, 0xc)
						rc = _sqlite3Reprepare(tls, v)
						libc.SetBitFieldPtr16Uint32(v+144, libc.BoolUint32(eMode == libc.Int32FromInt32(2)), 8, 0x100)
					}
				}
			}
		}
	}
	if int32(Tbft(*(*uint16)(unsafe.Pointer(v + 144))&0xc>>2)) != 0 {
		(*TVdbe)(unsafe.Pointer(v)).FnResColumn = libc.Uint16FromInt32(int32(12) - int32(4)*int32(Tbft(*(*uint16)(unsafe.Pointer(v + 144))&0xc>>2)))
	} else {
		(*TVdbe)(unsafe.Pointer(v)).FnResColumn = (*TVdbe)(unsafe.Pointer(v)).FnResAlloc
	}
	Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer((*TVdbe)(unsafe.Pointer(v)).Fdb)).Fmutex)
	return rc
}

// C documentation
//
//	/*
//	** Return 1 if the statement is an EXPLAIN and return 2 if the
//	** statement is an EXPLAIN QUERY PLAN
//	*/
func Xsqlite3_stmt_isexplain(tls *libc.TLS, pStmt uintptr) (r int32) {
	var v1 int32
	_ = v1
	if pStmt != 0 {
		v1 = int32(Tbft(*(*uint16)(unsafe.Pointer(pStmt + 144)) & 0xc >> 2))
	} else {
		v1 = 0
	}
	return v1
}

// C documentation
//
//	/*
//	** Return true if the prepared statement is guaranteed to not modify the
//	** database.
//	*/
func Xsqlite3_stmt_readonly(tls *libc.TLS, pStmt uintptr) (r int32) {
	var v1 int32
	_ = v1
	if pStmt != 0 {
		v1 = int32(Tbft(*(*uint16)(unsafe.Pointer(pStmt + 144)) & 0x40 >> 6))
	} else {
		v1 = int32(1)
	}
	return v1
}

// C documentation
//
//	/*
//	** Return the value of a status counter for a prepared statement
//	*/
func Xsqlite3_stmt_status(tls *libc.TLS, pStmt uintptr, op int32, resetFlag int32) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var db, pVdbe uintptr
	var _ /* v at bp+0 */ Tu32
	_, _ = db, pVdbe
	pVdbe = pStmt
	if op == int32(SQLITE_STMTSTATUS_MEMUSED) {
		db = (*TVdbe)(unsafe.Pointer(pVdbe)).Fdb
		Xsqlite3_mutex_enter(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
		**(**Tu32)(__ccgo_up(bp)) = uint32(0)
		(*Tsqlite3)(unsafe.Pointer(db)).FpnBytesFreed = bp
		(*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpEnd = (*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpStart
		_sqlite3VdbeDelete(tls, pVdbe)
		(*Tsqlite3)(unsafe.Pointer(db)).FpnBytesFreed = uintptr(0)
		(*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpEnd = (*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpTrueEnd
		Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
	} else {
		**(**Tu32)(__ccgo_up(bp)) = **(**Tu32)(__ccgo_up(pVdbe + 156 + uintptr(op)*4))
		if resetFlag != 0 {
			**(**Tu32)(__ccgo_up(pVdbe + 156 + uintptr(op)*4)) = uint32(0)
		}
	}
	return libc.Int32FromUint32(**(**Tu32)(__ccgo_up(bp)))
}

// C documentation
//
//	/*
//	** Append N copies of character c to the given string buffer.
//	*/
func Xsqlite3_str_appendchar(tls *libc.TLS, p uintptr, N int32, c int8) {
	var v1 int32
	var v2 bool
	var v4 Tu32
	var v5 uintptr
	_, _, _, _ = v1, v2, v4, v5
	if v2 = libc.Int64FromUint32((*Tsqlite3_str)(unsafe.Pointer(p)).FnChar)+int64(N) >= libc.Int64FromUint32((*Tsqlite3_str)(unsafe.Pointer(p)).FnAlloc); v2 {
		v1 = _sqlite3StrAccumEnlarge(tls, p, int64(N))
		N = v1
	}
	if v2 && v1 <= 0 {
		return
	}
	for {
		v1 = N
		N = N - 1
		if !(v1 > 0) {
			break
		}
		v5 = p + 16
		v4 = *(*Tu32)(unsafe.Pointer(v5))
		*(*Tu32)(unsafe.Pointer(v5)) = *(*Tu32)(unsafe.Pointer(v5)) + 1
		**(**int8)(__ccgo_up((*Tsqlite3_str)(unsafe.Pointer(p)).FzText + uintptr(v4))) = c
	}
}

// C documentation
//
//	/* Allocate and initialize a new dynamic string object */
func Xsqlite3_str_new(tls *libc.TLS, db uintptr) (r uintptr) {
	var p uintptr
	var v1 int32
	_, _ = p, v1
	p = Xsqlite3_malloc64(tls, uint64(24))
	if p != 0 {
		if db != 0 {
			v1 = **(**int32)(__ccgo_up(db + 116))
		} else {
			v1 = int32(SQLITE_MAX_LENGTH)
		}
		_sqlite3StrAccumInit(tls, p, uintptr(0), uintptr(0), 0, v1)
	} else {
		p = uintptr(unsafe.Pointer(&_sqlite3OomStr))
	}
	return p
}

// C documentation
//
//	/*
//	** Interface to the testing logic.
//	*/
func Xsqlite3_test_control(tls *libc.TLS, op int32, va uintptr) (r int32) {
	var aProg, db, db1, db2, db3, db4, db5, db6, db7, pCtx, pI1, pI2, pN, pR, pU64, pn, ptr, xBenignBegin, xBenignEnd, z uintptr
	var ap Tva_list
	var b, iDb, opTrace, rc, sz, x, x1, x2, y, v1 int32
	var newVal uint32
	var rIn float64
	var rLogEst TLogEst
	var v2 bool
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = aProg, ap, b, db, db1, db2, db3, db4, db5, db6, db7, iDb, newVal, opTrace, pCtx, pI1, pI2, pN, pR, pU64, pn, ptr, rIn, rLogEst, rc, sz, x, x1, x2, xBenignBegin, xBenignEnd, y, z, v1, v2
	rc = 0
	ap = va
	switch op {
	/*
	 ** Save the current state of the PRNG.
	 */
	case int32(SQLITE_TESTCTRL_PRNG_SAVE):
		_sqlite3PrngSaveState(tls)
		break
		/*
		 ** Restore the state of the PRNG to the last state saved using
		 ** PRNG_SAVE.  If PRNG_SAVE has never before been called, then
		 ** this verb acts like PRNG_RESET.
		 */
		fallthrough
	case int32(SQLITE_TESTCTRL_PRNG_RESTORE):
		_sqlite3PrngRestoreState(tls)
		break
		/*  sqlite3_test_control(SQLITE_TESTCTRL_PRNG_SEED, int x, sqlite3 *db);
		 **
		 ** Control the seed for the pseudo-random number generator (PRNG) that
		 ** is built into SQLite.  Cases:
		 **
		 **    x!=0 && db!=0       Seed the PRNG to the current value of the
		 **                        schema cookie in the main database for db, or
		 **                        x if the schema cookie is zero.  This case
		 **                        is convenient to use with database fuzzers
		 **                        as it allows the fuzzer some control over the
		 **                        the PRNG seed.
		 **
		 **    x!=0 && db==0       Seed the PRNG to the value of x.
		 **
		 **    x==0 && db==0       Revert to default behavior of using the
		 **                        xRandomness method on the primary VFS.
		 **
		 ** This test-control also resets the PRNG so that the new seed will
		 ** be used for the next call to sqlite3_randomness().
		 */
		fallthrough
	case int32(SQLITE_TESTCTRL_PRNG_SEED):
		x = libc.VaInt32(&ap)
		db = libc.VaUintptr(&ap)
		if v2 = db != 0; v2 {
			v1 = (*TSchema)(unsafe.Pointer((**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb))).FpSchema)).Fschema_cookie
			y = v1
		}
		if v2 && v1 != 0 {
			x = y
		}
		_sqlite3Config.FiPrngSeed = libc.Uint32FromInt32(x)
		Xsqlite3_randomness(tls, 0, uintptr(0))
		break
		/*  sqlite3_test_control(SQLITE_TESTCTRL_FK_NO_ACTION, sqlite3 *db, int b);
		 **
		 ** If b is true, then activate the SQLITE_FkNoAction setting.  If b is
		 ** false then clear that setting.  If the SQLITE_FkNoAction setting is
		 ** enabled, all foreign key ON DELETE and ON UPDATE actions behave as if
		 ** they were NO ACTION, regardless of how they are defined.
		 **
		 ** NB:  One must usually run "PRAGMA writable_schema=RESET" after
		 ** using this test-control, before it will take full effect.  failing
		 ** to reset the schema can result in some unexpected behavior.
		 */
		fallthrough
	case int32(SQLITE_TESTCTRL_FK_NO_ACTION):
		db1 = libc.VaUintptr(&ap)
		b = libc.VaInt32(&ap)
		if b != 0 {
			**(**Tu64)(__ccgo_up(db1 + 28)) |= libc.Uint64FromInt32(libc.Int32FromInt32(0x00008)) << libc.Int32FromInt32(32)
		} else {
			**(**Tu64)(__ccgo_up(db1 + 28)) &= ^(libc.Uint64FromInt32(libc.Int32FromInt32(0x00008)) << libc.Int32FromInt32(32))
		}
		break
		/*
		 **  sqlite3_test_control(BITVEC_TEST, size, program)
		 **
		 ** Run a test against a Bitvec object of size.  The program argument
		 ** is an array of integers that defines the test.  Return -1 on a
		 ** memory allocation error, 0 on success, or non-zero for an error.
		 ** See the sqlite3BitvecBuiltinTest() for additional information.
		 */
		fallthrough
	case int32(SQLITE_TESTCTRL_BITVEC_TEST):
		sz = libc.VaInt32(&ap)
		aProg = libc.VaUintptr(&ap)
		rc = _sqlite3BitvecBuiltinTest(tls, sz, aProg)
		break
		/*
		 **  sqlite3_test_control(FAULT_INSTALL, xCallback)
		 **
		 ** Arrange to invoke xCallback() whenever sqlite3FaultSim() is called,
		 ** if xCallback is not NULL.
		 **
		 ** As a test of the fault simulator mechanism itself, sqlite3FaultSim(0)
		 ** is called immediately after installing the new callback and the return
		 ** value from sqlite3FaultSim(0) becomes the return from
		 ** sqlite3_test_control().
		 */
		fallthrough
	case int32(SQLITE_TESTCTRL_FAULT_INSTALL):
		_sqlite3Config.FxTestCallback = libc.VaUintptr(&ap)
		rc = _sqlite3FaultSim(tls, 0)
		break
		/*
		 **  sqlite3_test_control(BENIGN_MALLOC_HOOKS, xBegin, xEnd)
		 **
		 ** Register hooks to call to indicate which malloc() failures
		 ** are benign.
		 */
		fallthrough
	case int32(SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS):
		xBenignBegin = libc.VaUintptr(&ap)
		xBenignEnd = libc.VaUintptr(&ap)
		_sqlite3BenignMallocHooks(tls, xBenignBegin, xBenignEnd)
		break
		/*
		 **  sqlite3_test_control(SQLITE_TESTCTRL_PENDING_BYTE, unsigned int X)
		 **
		 ** Set the PENDING byte to the value in the argument, if X>0.
		 ** Make no changes if X==0.  Return the value of the pending byte
		 ** as it existing before this routine was called.
		 **
		 ** IMPORTANT:  Changing the PENDING byte from 0x40000000 results in
		 ** an incompatible database file format.  Changing the PENDING byte
		 ** while any database connection is open results in undefined and
		 ** deleterious behavior.
		 */
		fallthrough
	case int32(SQLITE_TESTCTRL_PENDING_BYTE):
		rc = _sqlite3PendingByte
		newVal = libc.VaUint32(&ap)
		if newVal != 0 {
			_sqlite3PendingByte = libc.Int32FromUint32(newVal)
		}
		break
		/*
		 **  sqlite3_test_control(SQLITE_TESTCTRL_ASSERT, int X)
		 **
		 ** This action provides a run-time test to see whether or not
		 ** assert() was enabled at compile-time.  If X is true and assert()
		 ** is enabled, then the return value is true.  If X is true and
		 ** assert() is disabled, then the return value is zero.  If X is
		 ** false and assert() is enabled, then the assertion fires and the
		 ** process aborts.  If X is false and assert() is disabled, then the
		 ** return value is zero.
		 */
		fallthrough
	case int32(SQLITE_TESTCTRL_ASSERT):
		x1 = 0
		rc = x1
		break
		/*
		 **  sqlite3_test_control(SQLITE_TESTCTRL_ALWAYS, int X)
		 **
		 ** This action provides a run-time test to see how the ALWAYS and
		 ** NEVER macros were defined at compile-time.
		 **
		 ** The return value is ALWAYS(X) if X is true, or 0 if X is false.
		 **
		 ** The recommended test is X==2.  If the return value is 2, that means
		 ** ALWAYS() and NEVER() are both no-op pass-through macros, which is the
		 ** default setting.  If the return value is 1, then ALWAYS() is either
		 ** hard-coded to true or else it asserts if its argument is false.
		 ** The first behavior (hard-coded to true) is the case if
		 ** SQLITE_TESTCTRL_ASSERT shows that assert() is disabled and the second
		 ** behavior (assert if the argument to ALWAYS() is false) is the case if
		 ** SQLITE_TESTCTRL_ASSERT shows that assert() is enabled.
		 **
		 ** The run-time test procedure might look something like this:
		 **
		 **    if( sqlite3_test_control(SQLITE_TESTCTRL_ALWAYS, 2)==2 ){
		 **      // ALWAYS() and NEVER() are no-op pass-through macros
		 **    }else if( sqlite3_test_control(SQLITE_TESTCTRL_ASSERT, 1) ){
		 **      // ALWAYS(x) asserts that x is true. NEVER(x) asserts x is false.
		 **    }else{
		 **      // ALWAYS(x) is a constant 1.  NEVER(x) is a constant 0.
		 **    }
		 */
		fallthrough
	case int32(SQLITE_TESTCTRL_ALWAYS):
		x2 = libc.VaInt32(&ap)
		if x2 != 0 {
			v1 = x2
		} else {
			v1 = 0
		}
		rc = v1
		break
		/*
		 **   sqlite3_test_control(SQLITE_TESTCTRL_BYTEORDER);
		 **
		 ** The integer returned reveals the byte-order of the computer on which
		 ** SQLite is running:
		 **
		 **       1     big-endian,    determined at run-time
		 **      10     little-endian, determined at run-time
		 **  432101     big-endian,    determined at compile-time
		 **  123410     little-endian, determined at compile-time
		 */
		fallthrough
	case int32(SQLITE_TESTCTRL_BYTEORDER):
		rc = libc.Int32FromInt32(SQLITE_BYTEORDER)*libc.Int32FromInt32(100) + libc.Int32FromInt32(SQLITE_LITTLEENDIAN)*libc.Int32FromInt32(10) + libc.Int32FromInt32(SQLITE_BIGENDIAN)
		break
		/*  sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, sqlite3 *db, int N)
		 **
		 ** Enable or disable various optimizations for testing purposes.  The
		 ** argument N is a bitmask of optimizations to be disabled.  For normal
		 ** operation N should be 0.  The idea is that a test program (like the
		 ** SQL Logic Test or SLT test module) can run the same SQL multiple times
		 ** with various optimizations disabled to verify that the same answer
		 ** is obtained in every case.
		 */
		fallthrough
	case int32(SQLITE_TESTCTRL_OPTIMIZATIONS):
		db2 = libc.VaUintptr(&ap)
		(*Tsqlite3)(unsafe.Pointer(db2)).FdbOptFlags = libc.VaUint32(&ap)
		break
		/*  sqlite3_test_control(SQLITE_TESTCTRL_GETOPT, sqlite3 *db, int *N)
		 **
		 ** Write the current optimization settings into *N.  A zero bit means that
		 ** the optimization is on, and a 1 bit means that the optimization is off.
		 */
		fallthrough
	case int32(SQLITE_TESTCTRL_GETOPT):
		db3 = libc.VaUintptr(&ap)
		pN = libc.VaUintptr(&ap)
		**(**int32)(__ccgo_up(pN)) = libc.Int32FromUint32((*Tsqlite3)(unsafe.Pointer(db3)).FdbOptFlags)
		break
		/*   sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, onoff, xAlt);
		 **
		 ** If parameter onoff is 1, subsequent calls to localtime() fail.
		 ** If 2, then invoke xAlt() instead of localtime().  If 0, normal
		 ** processing.
		 **
		 ** xAlt arguments are void pointers, but they really want to be:
		 **
		 **    int xAlt(const time_t*, struct tm*);
		 **
		 ** xAlt should write results in to struct tm object of its 2nd argument
		 ** and return zero on success, or return non-zero on failure.
		 */
		fallthrough
	case int32(SQLITE_TESTCTRL_LOCALTIME_FAULT):
		_sqlite3Config.FbLocaltimeFault = libc.VaInt32(&ap)
		if _sqlite3Config.FbLocaltimeFault == int32(2) {
			_sqlite3Config.FxAltLocaltime = libc.VaUintptr(&ap)
		} else {
			_sqlite3Config.FxAltLocaltime = uintptr(0)
		}
		break
		/*   sqlite3_test_control(SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, sqlite3*);
		 **
		 ** Toggle the ability to use internal functions on or off for
		 ** the database connection given in the argument.
		 */
		fallthrough
	case int32(SQLITE_TESTCTRL_INTERNAL_FUNCTIONS):
		db4 = libc.VaUintptr(&ap)
		**(**Tu32)(__ccgo_up(db4 + 24)) ^= uint32(DBFLAG_InternalFunc)
		break
		/*   sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, int);
		 **
		 ** Set or clear a flag that indicates that the database file is always well-
		 ** formed and never corrupt.  This flag is clear by default, indicating that
		 ** database files might have arbitrary corruption.  Setting the flag during
		 ** testing causes certain assert() statements in the code to be activated
		 ** that demonstrate invariants on well-formed database files.
		 */
		fallthrough
	case int32(SQLITE_TESTCTRL_NEVER_CORRUPT):
		_sqlite3Config.FneverCorrupt = libc.VaInt32(&ap)
		break
		/*   sqlite3_test_control(SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS, int);
		 **
		 ** Set or clear a flag that causes SQLite to verify that type, name,
		 ** and tbl_name fields of the sqlite_schema table.  This is normally
		 ** on, but it is sometimes useful to turn it off for testing.
		 **
		 ** 2020-07-22:  Disabling EXTRA_SCHEMA_CHECKS also disables the
		 ** verification of rootpage numbers when parsing the schema.  This
		 ** is useful to make it easier to reach strange internal error states
		 ** during testing.  The EXTRA_SCHEMA_CHECKS setting is always enabled
		 ** in production.
		 */
		fallthrough
	case int32(SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS):
		_sqlite3Config.FbExtraSchemaChecks = libc.Uint8FromInt32(libc.VaInt32(&ap))
		break
		/* Set the threshold at which OP_Once counters reset back to zero.
		 ** By default this is 0x7ffffffe (over 2 billion), but that value is
		 ** too big to test in a reasonable amount of time, so this control is
		 ** provided to set a small and easily reachable reset value.
		 */
		fallthrough
	case int32(SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD):
		_sqlite3Config.FiOnceResetThreshold = libc.VaInt32(&ap)
		break
		/*   sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE, xCallback, ptr);
		 **
		 ** Set the VDBE coverage callback function to xCallback with context
		 ** pointer ptr.
		 */
		fallthrough
	case int32(SQLITE_TESTCTRL_VDBE_COVERAGE):
		break
		/*   sqlite3_test_control(SQLITE_TESTCTRL_SORTER_MMAP, db, nMax); */
		fallthrough
	case int32(SQLITE_TESTCTRL_SORTER_MMAP):
		db5 = libc.VaUintptr(&ap)
		(*Tsqlite3)(unsafe.Pointer(db5)).FnMaxSorterMmap = libc.VaInt32(&ap)
		break
		/*   sqlite3_test_control(SQLITE_TESTCTRL_ISINIT);
		 **
		 ** Return SQLITE_OK if SQLite has been initialized and SQLITE_ERROR if
		 ** not.
		 */
		fallthrough
	case int32(SQLITE_TESTCTRL_ISINIT):
		if libc.AtomicLoadPInt32(uintptr(unsafe.Pointer(&_sqlite3Config))+208) == 0 {
			rc = int32(SQLITE_ERROR)
		}
		break
		/*  sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, dbName, mode, tnum);
		 **
		 ** This test control is used to create imposter tables.  "db" is a pointer
		 ** to the database connection.  dbName is the database name (ex: "main" or
		 ** "temp") which will receive the imposter.  "mode" turns imposter mode on
		 ** or off.  mode==0 means imposter mode is off.  mode==1 means imposter mode
		 ** is on.  mode==2 means imposter mode is on but results in an imposter
		 ** table that is read-only unless writable_schema is on.  "tnum" is the
		 ** root page of the b-tree to which the imposter table should connect.
		 **
		 ** Enable imposter mode only when the schema has already been parsed.  Then
		 ** run a single CREATE TABLE statement to construct the imposter table in
		 ** the parsed schema.  Then turn imposter mode back off again.
		 **
		 ** If onOff==0 and tnum>0 then reset the schema for all databases, causing
		 ** the schema to be reparsed the next time it is needed.  This has the
		 ** effect of erasing all imposter tables.
		 */
		fallthrough
	case int32(SQLITE_TESTCTRL_IMPOSTER):
		db6 = libc.VaUintptr(&ap)
		Xsqlite3_mutex_enter(tls, (*Tsqlite3)(unsafe.Pointer(db6)).Fmutex)
		iDb = _sqlite3FindDbName(tls, db6, libc.VaUintptr(&ap))
		if iDb >= 0 {
			(*Tsqlite3)(unsafe.Pointer(db6)).Finit1.FiDb = libc.Uint8FromInt32(iDb)
			(*Tsqlite3)(unsafe.Pointer(db6)).Finit1.Fbusy = uint8(libc.AssignBitFieldPtr8Uint32(db6+172+8, libc.Uint32FromInt32(libc.VaInt32(&ap)), 2, 1, 0x6))
			(*Tsqlite3)(unsafe.Pointer(db6)).Finit1.FnewTnum = libc.Uint32FromInt32(libc.VaInt32(&ap))
			if libc.Int32FromUint8((*Tsqlite3)(unsafe.Pointer(db6)).Finit1.Fbusy) == 0 && (*Tsqlite3)(unsafe.Pointer(db6)).Finit1.FnewTnum > uint32(0) {
				_sqlite3ResetAllSchemasOfConnection(tls, db6)
			}
		}
		Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer(db6)).Fmutex)
		break
		/*  sqlite3_test_control(SQLITE_TESTCTRL_RESULT_INTREAL, sqlite3_context*);
		 **
		 ** This test-control causes the most recent sqlite3_result_int64() value
		 ** to be interpreted as a MEM_IntReal instead of as an MEM_Int.  Normally,
		 ** MEM_IntReal values only arise during an INSERT operation of integer
		 ** values into a REAL column, so they can be challenging to test.  This
		 ** test-control enables us to write an intreal() SQL function that can
		 ** inject an intreal() value at arbitrary places in an SQL statement,
		 ** for testing purposes.
		 */
		fallthrough
	case int32(SQLITE_TESTCTRL_RESULT_INTREAL):
		pCtx = libc.VaUintptr(&ap)
		_sqlite3ResultIntReal(tls, pCtx)
		break
		/*  sqlite3_test_control(SQLITE_TESTCTRL_SEEK_COUNT,
		 **    sqlite3 *db,    // Database connection
		 **    u64 *pnSeek     // Write seek count here
		 **  );
		 **
		 ** This test-control queries the seek-counter on the "main" database
		 ** file.  The seek-counter is written into *pnSeek and is then reset.
		 ** The seek-count is only available if compiled with SQLITE_DEBUG.
		 */
		fallthrough
	case int32(SQLITE_TESTCTRL_SEEK_COUNT):
		db7 = libc.VaUintptr(&ap)
		pn = libc.VaUintptr(&ap)
		**(**Tu64)(__ccgo_up(pn)) = uint64(0)
		_ = db7 /* Silence harmless unused variable warning */
		break
		/*  sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, op, ptr)
		 **
		 **  "ptr" is a pointer to a u32.
		 **
		 **   op==0       Store the current sqlite3TreeTrace in *ptr
		 **   op==1       Set sqlite3TreeTrace to the value *ptr
		 **   op==2       Store the current sqlite3WhereTrace in *ptr
		 **   op==3       Set sqlite3WhereTrace to the value *ptr
		 */
		fallthrough
	case int32(SQLITE_TESTCTRL_TRACEFLAGS):
		opTrace = libc.VaInt32(&ap)
		ptr = libc.VaUintptr(&ap)
		switch opTrace {
		case 0:
			**(**Tu32)(__ccgo_up(ptr)) = _sqlite3TreeTrace
		case int32(1):
			_sqlite3TreeTrace = **(**Tu32)(__ccgo_up(ptr))
		case int32(2):
			**(**Tu32)(__ccgo_up(ptr)) = _sqlite3WhereTrace
		case int32(3):
			_sqlite3WhereTrace = **(**Tu32)(__ccgo_up(ptr))
			break
		}
		break
		/* sqlite3_test_control(SQLITE_TESTCTRL_LOGEST,
		 **      double fIn,     // Input value
		 **      int *pLogEst,   // sqlite3LogEstFromDouble(fIn)
		 **      u64 *pInt,      // sqlite3LogEstToInt(*pLogEst)
		 **      int *pLogEst2   // sqlite3LogEst(*pInt)
		 ** );
		 **
		 ** Test access for the LogEst conversion routines.
		 */
		fallthrough
	case int32(SQLITE_TESTCTRL_LOGEST):
		rIn = libc.VaFloat64(&ap)
		rLogEst = _sqlite3LogEstFromDouble(tls, rIn)
		pI1 = libc.VaUintptr(&ap)
		pU64 = libc.VaUintptr(&ap)
		pI2 = libc.VaUintptr(&ap)
		**(**int32)(__ccgo_up(pI1)) = int32(rLogEst)
		**(**Tu64)(__ccgo_up(pU64)) = _sqlite3LogEstToInt(tls, rLogEst)
		**(**int32)(__ccgo_up(pI2)) = int32(_sqlite3LogEst(tls, **(**Tu64)(__ccgo_up(pU64))))
		break
		/* sqlite3_test_control(SQLITE_TESTCTRL_ATOF, const char *z, double *p);
		 **
		 ** Test access to the sqlite3AtoF() routine.
		 */
		fallthrough
	case int32(SQLITE_TESTCTRL_ATOF):
		z = libc.VaUintptr(&ap)
		pR = libc.VaUintptr(&ap)
		rc = _sqlite3AtoF(tls, z, pR)
		break
		/* sqlite3_test_control(SQLITE_TESTCTRL_JSON_SELFCHECK, &onOff);
		 **
		 ** Activate or deactivate validation of JSONB that is generated from
		 ** text.  Off by default, as the validation is slow.  Validation is
		 ** only available if compiled using SQLITE_DEBUG.
		 **
		 ** If onOff is initially 1, then turn it on.  If onOff is initially
		 ** off, turn it off.  If onOff is initially -1, then change onOff
		 ** to be the current setting.
		 */
		fallthrough
	case int32(SQLITE_TESTCTRL_JSON_SELFCHECK):
		break
	}
	_ = ap
	return rc
}

// C documentation
//
//	/*
//	** Register a trace function.  The pArg from the previously registered trace
//	** is returned.
//	**
//	** A NULL trace function means that no tracing is executes.  A non-NULL
//	** trace is a pointer to a function that is invoked at the start of each
//	** SQL statement.
//	*/
func Xsqlite3_trace(tls *libc.TLS, db uintptr, __ccgo_fp_xTrace uintptr, pArg uintptr) (r uintptr) {
	var pOld uintptr
	var v1 int32
	_, _ = pOld, v1
	Xsqlite3_mutex_enter(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
	pOld = (*Tsqlite3)(unsafe.Pointer(db)).FpTraceArg
	if __ccgo_fp_xTrace != 0 {
		v1 = int32(SQLITE_TRACE_LEGACY)
	} else {
		v1 = 0
	}
	(*Tsqlite3)(unsafe.Pointer(db)).FmTrace = libc.Uint8FromInt32(v1)
	*(*uintptr)(unsafe.Pointer(db + 216)) = __ccgo_fp_xTrace
	(*Tsqlite3)(unsafe.Pointer(db)).FpTraceArg = pArg
	Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
	return pOld
}

// C documentation
//
//	/* Register a trace callback using the version-2 interface.
//	*/
func Xsqlite3_trace_v2(tls *libc.TLS, db uintptr, mTrace uint32, __ccgo_fp_xTrace uintptr, pArg uintptr) (r int32) {
	Xsqlite3_mutex_enter(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
	if mTrace == uint32(0) {
		__ccgo_fp_xTrace = uintptr(0)
	}
	if __ccgo_fp_xTrace == uintptr(0) {
		mTrace = uint32(0)
	}
	(*Tsqlite3)(unsafe.Pointer(db)).FmTrace = uint8(mTrace)
	*(*uintptr)(unsafe.Pointer(db + 216)) = __ccgo_fp_xTrace
	(*Tsqlite3)(unsafe.Pointer(db)).FpTraceArg = pArg
	Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** Deprecated external interface.  Internal/core SQLite code
//	** should call sqlite3TransferBindings.
//	**
//	** It is misuse to call this routine with statements from different
//	** database connections.  But as this is a deprecated interface, we
//	** will not bother to check for that condition.
//	**
//	** If the two statements contain a different number of bindings, then
//	** an SQLITE_ERROR is returned.  Nothing else can go wrong, so otherwise
//	** SQLITE_OK is returned.
//	*/
func Xsqlite3_transfer_bindings(tls *libc.TLS, pFromStmt uintptr, pToStmt uintptr) (r int32) {
	var pFrom, pTo uintptr
	_, _ = pFrom, pTo
	pFrom = pFromStmt
	pTo = pToStmt
	if int32((*TVdbe)(unsafe.Pointer(pFrom)).FnVar) != int32((*TVdbe)(unsafe.Pointer(pTo)).FnVar) {
		return int32(SQLITE_ERROR)
	}
	if (*TVdbe)(unsafe.Pointer(pTo)).Fexpmask != 0 {
		libc.SetBitFieldPtr16Uint32(pTo+144, libc.Uint32FromInt32(1), 0, 0x3)
	}
	if (*TVdbe)(unsafe.Pointer(pFrom)).Fexpmask != 0 {
		libc.SetBitFieldPtr16Uint32(pFrom+144, libc.Uint32FromInt32(1), 0, 0x3)
	}
	return _sqlite3TransferBindings(tls, pFromStmt, pToStmt)
}

// C documentation
//
//	/*
//	** Return the collating sequence for a constraint passed into xBestIndex.
//	**
//	** pIdxInfo must be an sqlite3_index_info structure passed into xBestIndex.
//	** This routine depends on there being a HiddenIndexInfo structure immediately
//	** following the sqlite3_index_info structure.
//	**
//	** Return a pointer to the collation name:
//	**
//	**    1. If there is an explicit COLLATE operator on the constraint, return it.
//	**
//	**    2. Else, if the column has an alternative collation, return that.
//	**
//	**    3. Otherwise, return "BINARY".
//	*/
func Xsqlite3_vtab_collation(tls *libc.TLS, pIdxInfo uintptr, iCons int32) (r uintptr) {
	var iTerm int32
	var pC, pHidden, pX, zRet, v1 uintptr
	_, _, _, _, _, _ = iTerm, pC, pHidden, pX, zRet, v1
	pHidden = pIdxInfo + 1*64
	zRet = uintptr(0)
	if iCons >= 0 && iCons < (*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FnConstraint {
		pC = uintptr(0)
		iTerm = (**(**Tsqlite3_index_constraint)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraint + uintptr(iCons)*12))).FiTermOffset
		pX = (*TWhereTerm)(unsafe.Pointer(_termFromWhereClause(tls, (*THiddenIndexInfo)(unsafe.Pointer(pHidden)).FpWC, iTerm))).FpExpr
		if (*TExpr)(unsafe.Pointer(pX)).FpLeft != 0 {
			pC = _sqlite3ExprCompareCollSeq(tls, (*THiddenIndexInfo)(unsafe.Pointer(pHidden)).FpParse, pX)
		}
		if pC != 0 {
			v1 = (*TCollSeq)(unsafe.Pointer(pC)).FzName
		} else {
			v1 = uintptr(unsafe.Pointer(&_sqlite3StrBINARY))
		}
		zRet = v1
	}
	return zRet
}

// C documentation
//
//	/*
//	** Return true if ORDER BY clause may be handled as DISTINCT.
//	*/
func Xsqlite3_vtab_distinct(tls *libc.TLS, pIdxInfo uintptr) (r int32) {
	var pHidden uintptr
	_ = pHidden
	pHidden = pIdxInfo + 1*64
	return (*THiddenIndexInfo)(unsafe.Pointer(pHidden)).FeDistinct
}

// C documentation
//
//	/*
//	** Return true if constraint iCons is really an IN(...) constraint, or
//	** false otherwise. If iCons is an IN(...) constraint, set (if bHandle!=0)
//	** or clear (if bHandle==0) the flag to handle it using an iterator.
//	*/
func Xsqlite3_vtab_in(tls *libc.TLS, pIdxInfo uintptr, iCons int32, bHandle int32) (r int32) {
	var m Tu32
	var pHidden uintptr
	var v1 uint32
	_, _, _ = m, pHidden, v1
	pHidden = pIdxInfo + 1*64
	if iCons <= int32(31) {
		v1 = libc.Uint32FromInt32(1) << iCons
	} else {
		v1 = uint32(0)
	}
	m = v1
	if m&(*THiddenIndexInfo)(unsafe.Pointer(pHidden)).FmIn != 0 {
		if bHandle == 0 {
			**(**Tu32)(__ccgo_up(pHidden + 16)) &= ^m
		} else {
			if bHandle > 0 {
				**(**Tu32)(__ccgo_up(pHidden + 16)) |= m
			}
		}
		return int32(1)
	}
	return 0
}

// C documentation
//
//	/*
//	** This interface is callable from within the xBestIndex callback only.
//	**
//	** If possible, set (*ppVal) to point to an object containing the value
//	** on the right-hand-side of constraint iCons.
//	*/
func Xsqlite3_vtab_rhs_value(tls *libc.TLS, pIdxInfo uintptr, iCons int32, ppVal uintptr) (r int32) {
	var pH, pTerm, pVal uintptr
	var rc int32
	_, _, _, _ = pH, pTerm, pVal, rc
	pH = pIdxInfo + 1*64
	pVal = uintptr(0)
	rc = SQLITE_OK
	if iCons < 0 || iCons >= (*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FnConstraint {
		rc = _sqlite3MisuseError(tls, int32(173284)) /* EV: R-30545-25046 */
	} else {
		if *(*uintptr)(unsafe.Pointer(pH + 20 + uintptr(iCons)*4)) == uintptr(0) {
			pTerm = _termFromWhereClause(tls, (*THiddenIndexInfo)(unsafe.Pointer(pH)).FpWC, (**(**Tsqlite3_index_constraint)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraint + uintptr(iCons)*12))).FiTermOffset)
			rc = _sqlite3ValueFromExpr(tls, (*TParse)(unsafe.Pointer((*THiddenIndexInfo)(unsafe.Pointer(pH)).FpParse)).Fdb, (*TExpr)(unsafe.Pointer((*TWhereTerm)(unsafe.Pointer(pTerm)).FpExpr)).FpRight, (*Tsqlite3)(unsafe.Pointer((*TParse)(unsafe.Pointer((*THiddenIndexInfo)(unsafe.Pointer(pH)).FpParse)).Fdb)).Fenc, uint8(SQLITE_AFF_BLOB), pH+20+uintptr(iCons)*4)
		}
		pVal = *(*uintptr)(unsafe.Pointer(pH + 20 + uintptr(iCons)*4))
	}
	**(**uintptr)(__ccgo_up(ppVal)) = pVal
	if rc == SQLITE_OK && pVal == uintptr(0) { /* IMP: R-19933-32160 */
		rc = int32(SQLITE_NOTFOUND) /* IMP: R-36424-56542 */
	}
	return rc
}

// C documentation
//
//	/*
//	** Add connection db to the blocked connections list. It is assumed
//	** that it is not already a part of the list.
//	*/
func _addToBlockedList(tls *libc.TLS, db uintptr) {
	var pp uintptr
	_ = pp
	pp = uintptr(unsafe.Pointer(&_sqlite3BlockedList))
	for {
		if !(**(**uintptr)(__ccgo_up(pp)) != 0 && (*Tsqlite3)(unsafe.Pointer(**(**uintptr)(__ccgo_up(pp)))).FxUnlockNotify != (*Tsqlite3)(unsafe.Pointer(db)).FxUnlockNotify) {
			break
		}
		goto _1
	_1:
		;
		pp = **(**uintptr)(__ccgo_up(pp)) + 572
	}
	(*Tsqlite3)(unsafe.Pointer(db)).FpNextBlocked = **(**uintptr)(__ccgo_up(pp))
	**(**uintptr)(__ccgo_up(pp)) = db
}

// C documentation
//
//	/*
//	** Add the virtual table pVTab to the array sqlite3.aVTrans[]. Space should
//	** have already been reserved using growVTrans().
//	*/
func _addToVTrans(tls *libc.TLS, db uintptr, pVTab uintptr) {
	var v1 int32
	var v2 uintptr
	_, _ = v1, v2
	/* Add pVtab to the end of sqlite3.aVTrans */
	v2 = db + 396
	v1 = *(*int32)(unsafe.Pointer(v2))
	*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1
	**(**uintptr)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaVTrans + uintptr(v1)*4)) = pVTab
	_sqlite3VtabLock(tls, pVTab)
}

// C documentation
//
//	/* Try to allocate nByte bytes of 8-byte aligned bulk memory for pBuf
//	** from the ReusableSpace object.  Return a pointer to the allocated
//	** memory on success.  If insufficient memory is available in the
//	** ReusableSpace object, increase the ReusableSpace.nNeeded
//	** value by the amount needed and return NULL.
//	**
//	** If pBuf is not initially NULL, that means that the memory has already
//	** been allocated by a prior call to this routine, so just return a copy
//	** of pBuf and leave ReusableSpace unchanged.
//	**
//	** This allocator is employed to repurpose unused slots at the end of the
//	** opcode array of prepared state for other memory needs of the prepared
//	** statement.
//	*/
func _allocSpace(tls *libc.TLS, p uintptr, pBuf uintptr, nByte Tsqlite3_int64) (r uintptr) {
	if pBuf == uintptr(0) {
		nByte = (nByte + libc.Int64FromInt32(7)) & int64(^libc.Int32FromInt32(7))
		if nByte <= (*TReusableSpace)(unsafe.Pointer(p)).FnFree {
			**(**Tsqlite3_int64)(__ccgo_up(p + 4)) -= nByte
			pBuf = (*TReusableSpace)(unsafe.Pointer(p)).FpSpace + uintptr((*TReusableSpace)(unsafe.Pointer(p)).FnFree)
		} else {
			**(**Tsqlite3_int64)(__ccgo_up(p + 12)) += nByte
		}
	}
	return pBuf
}

// C documentation
//
//	/*
//	** Make sure pBt->pTmpSpace points to an allocation of
//	** MX_CELL_SIZE(pBt) bytes with a 4-byte prefix for a left-child
//	** pointer.
//	*/
func _allocateTempSpace(tls *libc.TLS, pBt uintptr) (r int32) {
	var pCur uintptr
	_ = pCur
	/* This routine is called only by btreeCursor() when allocating the
	 ** first write cursor for the BtShared object */
	(*TBtShared)(unsafe.Pointer(pBt)).FpTmpSpace = _sqlite3PageMalloc(tls, libc.Int32FromUint32((*TBtShared)(unsafe.Pointer(pBt)).FpageSize))
	if (*TBtShared)(unsafe.Pointer(pBt)).FpTmpSpace == uintptr(0) {
		pCur = (*TBtShared)(unsafe.Pointer(pBt)).FpCursor
		(*TBtShared)(unsafe.Pointer(pBt)).FpCursor = (*TBtCursor)(unsafe.Pointer(pCur)).FpNext /* Unlink the cursor */
		libc.Xmemset(tls, pCur, 0, uint32(188))
		return int32(SQLITE_NOMEM)
	}
	/* One of the uses of pBt->pTmpSpace is to format cells before
	 ** inserting them into a leaf page (function fillInCell()). If
	 ** a cell is less than 4 bytes in size, it is rounded up to 4 bytes
	 ** by the various routines that manipulate binary cells. Which
	 ** can mean that fillInCell() only initializes the first 2 or 3
	 ** bytes of pTmpSpace, but that the first 4 bytes are copied from
	 ** it into a database page. This is not actually a problem, but it
	 ** does cause a valgrind error when the 1 or 2 bytes of uninitialized
	 ** data is passed to system call write(). So to avoid this error,
	 ** zero the first 4 bytes of temp space here.
	 **
	 ** Also:  Provide four bytes of initialized space before the
	 ** beginning of pTmpSpace as an area available to prepend the
	 ** left-child pointer to the beginning of a cell.
	 */
	libc.Xmemset(tls, (*TBtShared)(unsafe.Pointer(pBt)).FpTmpSpace, 0, uint32(8))
	**(**uintptr)(__ccgo_up(pBt + 84)) += uintptr(4)
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** Processing is determine by the affinity parameter:
//	**
//	** SQLITE_AFF_INTEGER:
//	** SQLITE_AFF_REAL:
//	** SQLITE_AFF_NUMERIC:
//	**    Try to convert pRec to an integer representation or a
//	**    floating-point representation if an integer representation
//	**    is not possible.  Note that the integer representation is
//	**    always preferred, even if the affinity is REAL, because
//	**    an integer representation is more space efficient on disk.
//	**
//	** SQLITE_AFF_FLEXNUM:
//	**    If the value is text, then try to convert it into a number of
//	**    some kind (integer or real) but do not make any other changes.
//	**
//	** SQLITE_AFF_TEXT:
//	**    Convert pRec to a text representation.
//	**
//	** SQLITE_AFF_BLOB:
//	** SQLITE_AFF_NONE:
//	**    No-op.  pRec is unchanged.
//	*/
func _applyAffinity(tls *libc.TLS, pRec uintptr, affinity int8, enc Tu8) {
	var v1 uintptr
	_ = v1
	if int32(affinity) >= int32(SQLITE_AFF_NUMERIC) {
		if libc.Int32FromUint16((*TMem)(unsafe.Pointer(pRec)).Fflags)&int32(MEM_Int) == 0 { /*OPTIMIZATION-IF-FALSE*/
			if libc.Int32FromUint16((*TMem)(unsafe.Pointer(pRec)).Fflags)&(libc.Int32FromInt32(MEM_Real)|libc.Int32FromInt32(MEM_IntReal)) == 0 {
				if libc.Int32FromUint16((*TMem)(unsafe.Pointer(pRec)).Fflags)&int32(MEM_Str) != 0 {
					_applyNumericAffinity(tls, pRec, int32(1))
				}
			} else {
				if int32(affinity) <= int32(SQLITE_AFF_REAL) {
					_sqlite3VdbeIntegerAffinity(tls, pRec)
				}
			}
		}
	} else {
		if int32(affinity) == int32(SQLITE_AFF_TEXT) {
			/* Only attempt the conversion to TEXT if there is an integer or real
			 ** representation (blob and NULL do not get converted) but no string
			 ** representation.  It would be harmless to repeat the conversion if
			 ** there is already a string rep, but it is pointless to waste those
			 ** CPU cycles. */
			if 0 == libc.Int32FromUint16((*TMem)(unsafe.Pointer(pRec)).Fflags)&int32(MEM_Str) { /*OPTIMIZATION-IF-FALSE*/
				if libc.Int32FromUint16((*TMem)(unsafe.Pointer(pRec)).Fflags)&(libc.Int32FromInt32(MEM_Real)|libc.Int32FromInt32(MEM_Int)|libc.Int32FromInt32(MEM_IntReal)) != 0 {
					_sqlite3VdbeMemStringify(tls, pRec, enc, uint8(1))
				}
			}
			v1 = pRec + 16
			*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) & ^(libc.Int32FromInt32(MEM_Real) | libc.Int32FromInt32(MEM_Int) | libc.Int32FromInt32(MEM_IntReal)))
		}
	}
}

// C documentation
//
//	/*
//	** The page that pCur currently points to has just been modified in
//	** some way. This function figures out if this modification means the
//	** tree needs to be balanced, and if so calls the appropriate balancing
//	** routine. Balancing routines are:
//	**
//	**   balance_quick()
//	**   balance_deeper()
//	**   balance_nonroot()
//	*/
func _balance(tls *libc.TLS, pCur uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var iIdx, iPage, rc, v1, v2 int32
	var pFree, pPage, pParent, pSpace uintptr
	var v3 bool
	var _ /* aBalanceQuickSpace at bp+0 */ [13]Tu8
	_, _, _, _, _, _, _, _, _, _ = iIdx, iPage, pFree, pPage, pParent, pSpace, rc, v1, v2, v3
	rc = SQLITE_OK
	pFree = uintptr(0)
	for cond := true; cond; cond = rc == SQLITE_OK {
		pPage = (*TBtCursor)(unsafe.Pointer(pCur)).FpPage
		if (*TMemPage)(unsafe.Pointer(pPage)).FnFree < 0 && _btreeComputeFreeSpace(tls, pPage) != 0 {
			break
		}
		if libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pPage)).FnOverflow) == 0 && (*TMemPage)(unsafe.Pointer(pPage)).FnFree*int32(3) <= libc.Int32FromUint32((*TBtShared)(unsafe.Pointer((*TBtCursor)(unsafe.Pointer(pCur)).FpBt)).FusableSize)*int32(2) {
			/* No rebalance required as long as:
			 **   (1) There are no overflow cells
			 **   (2) The amount of free space on the page is less than 2/3rds of
			 **       the total usable space on the page. */
			break
		} else {
			v1 = int32((*TBtCursor)(unsafe.Pointer(pCur)).FiPage)
			iPage = v1
			if v1 == 0 {
				if v3 = (*TMemPage)(unsafe.Pointer(pPage)).FnOverflow != 0; v3 {
					v2 = _anotherValidCursor(tls, pCur)
					rc = v2
				}
				if v3 && v2 == SQLITE_OK {
					/* The root page of the b-tree is overfull. In this case call the
					 ** balance_deeper() function to create a new child for the root-page
					 ** and copy the current contents of the root-page to it. The
					 ** next iteration of the do-loop will balance the child page.
					 */
					rc = _balance_deeper(tls, pPage, pCur+112+1*4)
					if rc == SQLITE_OK {
						(*TBtCursor)(unsafe.Pointer(pCur)).FiPage = int8(1)
						(*TBtCursor)(unsafe.Pointer(pCur)).Fix = uint16(0)
						**(**Tu16)(__ccgo_up(pCur + 64)) = uint16(0)
						**(**uintptr)(__ccgo_up(pCur + 112)) = pPage
						(*TBtCursor)(unsafe.Pointer(pCur)).FpPage = **(**uintptr)(__ccgo_up(pCur + 112 + 1*4))
					}
				} else {
					break
				}
			} else {
				if _sqlite3PagerPageRefcount(tls, (*TMemPage)(unsafe.Pointer(pPage)).FpDbPage) > int32(1) {
					/* The page being written is not a root page, and there is currently
					 ** more than one reference to it. This only happens if the page is one
					 ** of its own ancestor pages. Corruption. */
					rc = _sqlite3CorruptError(tls, int32(82308))
				} else {
					pParent = **(**uintptr)(__ccgo_up(pCur + 112 + uintptr(iPage-int32(1))*4))
					iIdx = libc.Int32FromUint16(**(**Tu16)(__ccgo_up(pCur + 64 + uintptr(iPage-int32(1))*2)))
					rc = _sqlite3PagerWrite(tls, (*TMemPage)(unsafe.Pointer(pParent)).FpDbPage)
					if rc == SQLITE_OK && (*TMemPage)(unsafe.Pointer(pParent)).FnFree < 0 {
						rc = _btreeComputeFreeSpace(tls, pParent)
					}
					if rc == SQLITE_OK {
						if (*TMemPage)(unsafe.Pointer(pPage)).FintKeyLeaf != 0 && libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pPage)).FnOverflow) == int32(1) && libc.Int32FromUint16(**(**Tu16)(__ccgo_up(pPage + 28))) == libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FnCell) && (*TMemPage)(unsafe.Pointer(pParent)).Fpgno != uint32(1) && libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pParent)).FnCell) == iIdx {
							/* Call balance_quick() to create a new sibling of pPage on which
							 ** to store the overflow cell. balance_quick() inserts a new cell
							 ** into pParent, which may cause pParent overflow. If this
							 ** happens, the next iteration of the do-loop will balance pParent
							 ** use either balance_nonroot() or balance_deeper(). Until this
							 ** happens, the overflow cell is stored in the aBalanceQuickSpace[]
							 ** buffer.
							 **
							 ** The purpose of the following assert() is to check that only a
							 ** single call to balance_quick() is made for each call to this
							 ** function. If this were not verified, a subtle bug involving reuse
							 ** of the aBalanceQuickSpace[] might sneak in.
							 */
							rc = _balance_quick(tls, pParent, pPage, bp)
						} else {
							/* In this case, call balance_nonroot() to redistribute cells
							 ** between pPage and up to 2 of its sibling pages. This involves
							 ** modifying the contents of pParent, which may cause pParent to
							 ** become overfull or underfull. The next iteration of the do-loop
							 ** will balance the parent page to correct this.
							 **
							 ** If the parent page becomes overfull, the overflow cell or cells
							 ** are stored in the pSpace buffer allocated immediately below.
							 ** A subsequent iteration of the do-loop will deal with this by
							 ** calling balance_nonroot() (balance_deeper() may be called first,
							 ** but it doesn't deal with overflow cells - just moves them to a
							 ** different page). Once this subsequent call to balance_nonroot()
							 ** has completed, it is safe to release the pSpace buffer used by
							 ** the previous call, as the overflow cell data will have been
							 ** copied either into the body of a database page or into the new
							 ** pSpace buffer passed to the latter call to balance_nonroot().
							 */
							pSpace = _sqlite3PageMalloc(tls, libc.Int32FromUint32((*TBtShared)(unsafe.Pointer((*TBtCursor)(unsafe.Pointer(pCur)).FpBt)).FpageSize))
							rc = _balance_nonroot(tls, pParent, iIdx, pSpace, libc.BoolInt32(iPage == int32(1)), libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCur)).Fhints)&int32(BTREE_BULKLOAD))
							if pFree != 0 {
								/* If pFree is not NULL, it points to the pSpace buffer used
								 ** by a previous call to balance_nonroot(). Its contents are
								 ** now stored either on real database pages or within the
								 ** new pSpace buffer, so it may be safely freed here. */
								_sqlite3PageFree(tls, pFree)
							}
							/* The pSpace buffer will be freed after the next call to
							 ** balance_nonroot(), or just before this function returns, whichever
							 ** comes first. */
							pFree = pSpace
						}
					}
					(*TMemPage)(unsafe.Pointer(pPage)).FnOverflow = uint8(0)
					/* The next iteration of the do-loop balances the parent page. */
					_releasePage(tls, pPage)
					(*TBtCursor)(unsafe.Pointer(pCur)).FiPage = (*TBtCursor)(unsafe.Pointer(pCur)).FiPage - 1
					(*TBtCursor)(unsafe.Pointer(pCur)).FpPage = **(**uintptr)(__ccgo_up(pCur + 112 + uintptr((*TBtCursor)(unsafe.Pointer(pCur)).FiPage)*4))
				}
			}
		}
	}
	if pFree != 0 {
		_sqlite3PageFree(tls, pFree)
	}
	return rc
}

// C documentation
//
//	/*
//	** This routine redistributes cells on the iParentIdx'th child of pParent
//	** (hereafter "the page") and up to 2 siblings so that all pages have about the
//	** same amount of free space. Usually a single sibling on either side of the
//	** page are used in the balancing, though both siblings might come from one
//	** side if the page is the first or last child of its parent. If the page
//	** has fewer than 2 siblings (something which can only happen if the page
//	** is a root page or a child of a root page) then all available siblings
//	** participate in the balancing.
//	**
//	** The number of siblings of the page might be increased or decreased by
//	** one or two in an effort to keep pages nearly full but not over full.
//	**
//	** Note that when this routine is called, some of the cells on the page
//	** might not actually be stored in MemPage.aData[]. This can happen
//	** if the page is overfull. This routine ensures that all cells allocated
//	** to the page and its siblings fit into MemPage.aData[] before returning.
//	**
//	** In the course of balancing the page and its siblings, cells may be
//	** inserted into or removed from the parent page (pParent). Doing so
//	** may cause the parent page to become overfull or underfull. If this
//	** happens, it is the responsibility of the caller to invoke the correct
//	** balancing routine to fix this problem (see the balance() routine).
//	**
//	** If this routine fails for any reason, it might leave the database
//	** in a corrupted state. So if this routine fails, the database should
//	** be rolled back.
//	**
//	** The third argument to this function, aOvflSpace, is a pointer to a
//	** buffer big enough to hold one page. If while inserting cells into the parent
//	** page (pParent) the parent page becomes overfull, this buffer is
//	** used to store the parent's overflow cells. Because this function inserts
//	** a maximum of four divider cells into the parent page, and the maximum
//	** size of a cell stored within an internal node is always less than 1/4
//	** of the page-size, the aOvflSpace[] buffer is guaranteed to be large
//	** enough for all overflow cells.
//	**
//	** If aOvflSpace is set to a null pointer, this function returns
//	** SQLITE_NOMEM.
//	*/
func _balance_nonroot(tls *libc.TLS, pParent uintptr, iParentIdx int32, aOvflSpace uintptr, isRoot int32, bBulk int32) (r1 int32) {
	bp := tls.Alloc(144)
	defer tls.Free(144)
	var aData, aSpace1, p, pBt, pCell, pCell1, pNew1, pNew2, pOld, pOld1, pOld2, pRight, pSrcEnd, pTemp, pTemp1, piCell, piEnd, v17 uintptr
	var aPgno [5]TPgno
	var apDiv [2]uintptr
	var apNew [5]uintptr
	var cntNew, cntOld [5]int32
	var cntOldNext, d, i, iB, iNew, iNew1, iOff, iOld, iOld1, iOvflSpace, iPg, iSpace1, j, k, leafData, limit, nMaxCells, nNew, nNewCell, nOld, nxDiv, pageFlags, r, sz1, sz2, szD, szLeft, szR, szRight, usableSpace, v1 int32
	var fgA, fgB, leafCorrection, maskPage, sz Tu16
	var key Tu32
	var pgnoA, pgnoB, pgnoTemp TPgno
	var szScratch Tu64
	var v13, v14 bool
	var v18 uint32
	var _ /* abDone at bp+40 */ [5]Tu8
	var _ /* apOld at bp+4 */ [3]uintptr
	var _ /* b at bp+48 */ TCellArray
	var _ /* info at bp+116 */ TCellInfo
	var _ /* pNew at bp+112 */ uintptr
	var _ /* pgno at bp+36 */ TPgno
	var _ /* rc at bp+0 */ int32
	var _ /* szNew at bp+16 */ [5]int32
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = aData, aPgno, aSpace1, apDiv, apNew, cntNew, cntOld, cntOldNext, d, fgA, fgB, i, iB, iNew, iNew1, iOff, iOld, iOld1, iOvflSpace, iPg, iSpace1, j, k, key, leafCorrection, leafData, limit, maskPage, nMaxCells, nNew, nNewCell, nOld, nxDiv, p, pBt, pCell, pCell1, pNew1, pNew2, pOld, pOld1, pOld2, pRight, pSrcEnd, pTemp, pTemp1, pageFlags, pgnoA, pgnoB, pgnoTemp, piCell, piEnd, r, sz, sz1, sz2, szD, szLeft, szR, szRight, szScratch, usableSpace, v1, v13, v14, v17, v18 /* The whole database */
	nMaxCells = 0                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                /* Allocated size of apCell, szCell, aFrom. */
	nNew = 0                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     /* Next divider slot in pParent->aCell[] */
	**(**int32)(__ccgo_up(bp)) = SQLITE_OK                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       /* Value of pPage->aData[0] */
	iSpace1 = 0                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  /* First unused byte of aSpace1[] */
	iOvflSpace = 0                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               /* Parsed information on cells being balanced */
	libc.Xmemset(tls, bp+40, 0, uint32(5))
	libc.Xmemset(tls, bp+48, 0, libc.Uint32FromInt64(64)-libc.Uint32FromInt64(4))
	**(**int32)(__ccgo_up(bp + 48 + 40 + uintptr(libc.Int32FromInt32(NB)*libc.Int32FromInt32(2)-libc.Int32FromInt32(1))*4)) = int32(0x7fffffff)
	pBt = (*TMemPage)(unsafe.Pointer(pParent)).FpBt
	/* At this point pParent may have at most one overflow cell. And if
	 ** this overflow cell is present, it must be the cell with
	 ** index iParentIdx. This scenario comes about when this function
	 ** is called (indirectly) from sqlite3BtreeDelete().
	 */
	if !(aOvflSpace != 0) {
		return int32(SQLITE_NOMEM)
	}
	/* Find the sibling pages to balance. Also locate the cells in pParent
	 ** that divide the siblings. An attempt is made to find NN siblings on
	 ** either side of pPage. More siblings are taken from one side, however,
	 ** if there are fewer than NN siblings on the other side. If pParent
	 ** has NB or fewer children then all children of pParent are taken.
	 **
	 ** This loop also drops the divider cells from the parent page. This
	 ** way, the remainder of the function does not have to deal with any
	 ** overflow cells in the parent page, since if any existed they will
	 ** have already been removed.
	 */
	i = libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pParent)).FnOverflow) + libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pParent)).FnCell)
	if i < int32(2) {
		nxDiv = 0
	} else {
		if iParentIdx == 0 {
			nxDiv = 0
		} else {
			if iParentIdx == i {
				nxDiv = i - int32(2) + bBulk
			} else {
				nxDiv = iParentIdx - int32(1)
			}
		}
		i = int32(2) - bBulk
	}
	nOld = i + int32(1)
	if i+nxDiv-libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pParent)).FnOverflow) == libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pParent)).FnCell) {
		pRight = (*TMemPage)(unsafe.Pointer(pParent)).FaData + uintptr(libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pParent)).FhdrOffset)+int32(8))
	} else {
		pRight = (*TMemPage)(unsafe.Pointer(pParent)).FaData + uintptr(libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pParent)).FmaskPage)&(libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TMemPage)(unsafe.Pointer(pParent)).FaCellIdx + uintptr(int32(2)*(i+nxDiv-libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pParent)).FnOverflow))))))<<libc.Int32FromInt32(8)|libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TMemPage)(unsafe.Pointer(pParent)).FaCellIdx + uintptr(int32(2)*(i+nxDiv-libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pParent)).FnOverflow))) + 1)))))
	}
	**(**TPgno)(__ccgo_up(bp + 36)) = _sqlite3Get4byte(tls, pRight)
	for int32(1) != 0 {
		if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
			**(**int32)(__ccgo_up(bp)) = _getAndInitPage(tls, pBt, **(**TPgno)(__ccgo_up(bp + 36)), bp+4+uintptr(i)*4, 0)
		}
		if **(**int32)(__ccgo_up(bp)) != 0 {
			libc.Xmemset(tls, bp+4, 0, libc.Uint32FromInt32(i+libc.Int32FromInt32(1))*uint32(4))
			goto balance_cleanup
		}
		if (*TMemPage)(unsafe.Pointer((**(**[3]uintptr)(__ccgo_up(bp + 4)))[i])).FnFree < 0 {
			**(**int32)(__ccgo_up(bp)) = _btreeComputeFreeSpace(tls, (**(**[3]uintptr)(__ccgo_up(bp + 4)))[i])
			if **(**int32)(__ccgo_up(bp)) != 0 {
				libc.Xmemset(tls, bp+4, 0, libc.Uint32FromInt32(i)*uint32(4))
				goto balance_cleanup
			}
		}
		nMaxCells = nMaxCells + (libc.Int32FromUint16((*TMemPage)(unsafe.Pointer((**(**[3]uintptr)(__ccgo_up(bp + 4)))[i])).FnCell) + libc.Int32FromUint32(libc.Uint32FromInt64(16)/libc.Uint32FromInt64(4)))
		v1 = i
		i = i - 1
		if v1 == 0 {
			break
		}
		if (*TMemPage)(unsafe.Pointer(pParent)).FnOverflow != 0 && i+nxDiv == libc.Int32FromUint16(**(**Tu16)(__ccgo_up(pParent + 28))) {
			apDiv[i] = **(**uintptr)(__ccgo_up(pParent + 36))
			**(**TPgno)(__ccgo_up(bp + 36)) = _sqlite3Get4byte(tls, apDiv[i])
			(**(**[5]int32)(__ccgo_up(bp + 16)))[i] = libc.Int32FromUint16((*(*func(*libc.TLS, uintptr, uintptr) Tu16)(unsafe.Pointer(&struct{ uintptr }{(*TMemPage)(unsafe.Pointer(pParent)).FxCellSize})))(tls, pParent, apDiv[i]))
			(*TMemPage)(unsafe.Pointer(pParent)).FnOverflow = uint8(0)
		} else {
			apDiv[i] = (*TMemPage)(unsafe.Pointer(pParent)).FaData + uintptr(libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pParent)).FmaskPage)&(libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TMemPage)(unsafe.Pointer(pParent)).FaCellIdx + uintptr(int32(2)*(i+nxDiv-libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pParent)).FnOverflow))))))<<libc.Int32FromInt32(8)|libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TMemPage)(unsafe.Pointer(pParent)).FaCellIdx + uintptr(int32(2)*(i+nxDiv-libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pParent)).FnOverflow))) + 1)))))
			**(**TPgno)(__ccgo_up(bp + 36)) = _sqlite3Get4byte(tls, apDiv[i])
			(**(**[5]int32)(__ccgo_up(bp + 16)))[i] = libc.Int32FromUint16((*(*func(*libc.TLS, uintptr, uintptr) Tu16)(unsafe.Pointer(&struct{ uintptr }{(*TMemPage)(unsafe.Pointer(pParent)).FxCellSize})))(tls, pParent, apDiv[i]))
			/* Drop the cell from the parent page. apDiv[i] still points to
			 ** the cell within the parent, even though it has been dropped.
			 ** This is safe because dropping a cell only overwrites the first
			 ** four bytes of it, and this function does not need the first
			 ** four bytes of the divider cell. So the pointer is safe to use
			 ** later on.
			 **
			 ** But not if we are in secure-delete mode. In secure-delete mode,
			 ** the dropCell() routine will overwrite the entire cell with zeroes.
			 ** In this case, temporarily copy the cell into the aOvflSpace[]
			 ** buffer. It will be copied out again as soon as the aSpace[] buffer
			 ** is allocated.  */
			if libc.Int32FromUint16((*TBtShared)(unsafe.Pointer(pBt)).FbtsFlags)&int32(BTS_FAST_SECURE) != 0 {
				/* If the following if() condition is not true, the db is corrupted.
				 ** The call to dropCell() below will detect this.  */
				iOff = int32(apDiv[i]) - int32((*TMemPage)(unsafe.Pointer(pParent)).FaData)
				if iOff+(**(**[5]int32)(__ccgo_up(bp + 16)))[i] <= libc.Int32FromUint32((*TBtShared)(unsafe.Pointer(pBt)).FusableSize) {
					libc.Xmemcpy(tls, aOvflSpace+uintptr(iOff), apDiv[i], libc.Uint32FromInt32((**(**[5]int32)(__ccgo_up(bp + 16)))[i]))
					apDiv[i] = aOvflSpace + uintptr(int32(apDiv[i])-int32((*TMemPage)(unsafe.Pointer(pParent)).FaData))
				}
			}
			_dropCell(tls, pParent, i+nxDiv-libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pParent)).FnOverflow), (**(**[5]int32)(__ccgo_up(bp + 16)))[i], bp)
		}
	}
	/* Make nMaxCells a multiple of 4 in order to preserve 8-byte
	 ** alignment */
	nMaxCells = (nMaxCells + int32(3)) & ^libc.Int32FromInt32(3)
	/*
	 ** Allocate space for memory structures
	 */
	szScratch = uint64(libc.Uint32FromInt32(nMaxCells)*uint32(4) + libc.Uint32FromInt32(nMaxCells)*uint32(2) + (*TBtShared)(unsafe.Pointer(pBt)).FpageSize) /* aSpace1 */
	(**(**TCellArray)(__ccgo_up(bp + 48))).FapCell = _sqlite3DbMallocRaw(tls, uintptr(0), szScratch)
	if (**(**TCellArray)(__ccgo_up(bp + 48))).FapCell == uintptr(0) {
		**(**int32)(__ccgo_up(bp)) = int32(SQLITE_NOMEM)
		goto balance_cleanup
	}
	(**(**TCellArray)(__ccgo_up(bp + 48))).FszCell = (**(**TCellArray)(__ccgo_up(bp + 48))).FapCell + uintptr(nMaxCells)*4
	aSpace1 = (**(**TCellArray)(__ccgo_up(bp + 48))).FszCell + uintptr(nMaxCells)*2
	/*
	 ** Load pointers to all cells on sibling pages and the divider cells
	 ** into the local b.apCell[] array.  Make copies of the divider cells
	 ** into space obtained from aSpace1[]. The divider cells have already
	 ** been removed from pParent.
	 **
	 ** If the siblings are on leaf pages, then the child pointers of the
	 ** divider cells are stripped from the cells before they are copied
	 ** into aSpace1[].  In this way, all cells in b.apCell[] are without
	 ** child pointers.  If siblings are not leaves, then all cell in
	 ** b.apCell[] include child pointers.  Either way, all cells in b.apCell[]
	 ** are alike.
	 **
	 ** leafCorrection:  4 if pPage is a leaf.  0 if pPage is not a leaf.
	 **       leafData:  1 if pPage holds key+data and pParent holds only keys.
	 */
	(**(**TCellArray)(__ccgo_up(bp + 48))).FpRef = (**(**[3]uintptr)(__ccgo_up(bp + 4)))[0]
	leafCorrection = libc.Uint16FromInt32(libc.Int32FromUint8((*TMemPage)(unsafe.Pointer((**(**TCellArray)(__ccgo_up(bp + 48))).FpRef)).Fleaf) * int32(4))
	leafData = libc.Int32FromUint8((*TMemPage)(unsafe.Pointer((**(**TCellArray)(__ccgo_up(bp + 48))).FpRef)).FintKeyLeaf)
	i = 0
	for {
		if !(i < nOld) {
			break
		}
		pOld = (**(**[3]uintptr)(__ccgo_up(bp + 4)))[i]
		limit = libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pOld)).FnCell)
		aData = (*TMemPage)(unsafe.Pointer(pOld)).FaData
		maskPage = (*TMemPage)(unsafe.Pointer(pOld)).FmaskPage
		piCell = aData + uintptr((*TMemPage)(unsafe.Pointer(pOld)).FcellOffset)
		/* Verify that all sibling pages are of the same "type" (table-leaf,
		 ** table-interior, index-leaf, or index-interior).
		 */
		if libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TMemPage)(unsafe.Pointer(pOld)).FaData))) != libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TMemPage)(unsafe.Pointer((**(**[3]uintptr)(__ccgo_up(bp + 4)))[0])).FaData))) {
			**(**int32)(__ccgo_up(bp)) = _sqlite3CorruptError(tls, int32(81575))
			goto balance_cleanup
		}
		/* Load b.apCell[] with pointers to all cells in pOld.  If pOld
		 ** contains overflow cells, include them in the b.apCell[] array
		 ** in the correct spot.
		 **
		 ** Note that when there are multiple overflow cells, it is always the
		 ** case that they are sequential and adjacent.  This invariant arises
		 ** because multiple overflows can only occurs when inserting divider
		 ** cells into a parent on a prior balance, and divider cells are always
		 ** adjacent and are inserted in order.  There is an assert() tagged
		 ** with "NOTE 1" in the overflow cell insertion loop to prove this
		 ** invariant.
		 **
		 ** This must be done in advance.  Once the balance starts, the cell
		 ** offset section of the btree page will be overwritten and we will no
		 ** long be able to find the cells if a pointer to each cell is not saved
		 ** first.
		 */
		libc.Xmemset(tls, (**(**TCellArray)(__ccgo_up(bp + 48))).FszCell+uintptr((**(**TCellArray)(__ccgo_up(bp + 48))).FnCell)*2, 0, uint32(2)*libc.Uint32FromInt32(limit+libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pOld)).FnOverflow)))
		if libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pOld)).FnOverflow) > 0 {
			if limit < libc.Int32FromUint16(**(**Tu16)(__ccgo_up(pOld + 28))) {
				**(**int32)(__ccgo_up(bp)) = _sqlite3CorruptError(tls, int32(81599))
				goto balance_cleanup
			}
			limit = libc.Int32FromUint16(**(**Tu16)(__ccgo_up(pOld + 28)))
			j = 0
			for {
				if !(j < limit) {
					break
				}
				**(**uintptr)(__ccgo_up((**(**TCellArray)(__ccgo_up(bp + 48))).FapCell + uintptr((**(**TCellArray)(__ccgo_up(bp + 48))).FnCell)*4)) = aData + uintptr(libc.Int32FromUint16(maskPage)&(libc.Int32FromUint8(**(**Tu8)(__ccgo_up(piCell)))<<libc.Int32FromInt32(8)|libc.Int32FromUint8(**(**Tu8)(__ccgo_up(piCell + 1)))))
				piCell = piCell + uintptr(2)
				(**(**TCellArray)(__ccgo_up(bp + 48))).FnCell = (**(**TCellArray)(__ccgo_up(bp + 48))).FnCell + 1
				goto _3
			_3:
				;
				j = j + 1
			}
			k = 0
			for {
				if !(k < libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pOld)).FnOverflow)) {
					break
				}
				/* NOTE 1 */
				**(**uintptr)(__ccgo_up((**(**TCellArray)(__ccgo_up(bp + 48))).FapCell + uintptr((**(**TCellArray)(__ccgo_up(bp + 48))).FnCell)*4)) = **(**uintptr)(__ccgo_up(pOld + 36 + uintptr(k)*4))
				(**(**TCellArray)(__ccgo_up(bp + 48))).FnCell = (**(**TCellArray)(__ccgo_up(bp + 48))).FnCell + 1
				goto _4
			_4:
				;
				k = k + 1
			}
		}
		piEnd = aData + uintptr((*TMemPage)(unsafe.Pointer(pOld)).FcellOffset) + uintptr(int32(2)*libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pOld)).FnCell))
		for piCell < piEnd {
			**(**uintptr)(__ccgo_up((**(**TCellArray)(__ccgo_up(bp + 48))).FapCell + uintptr((**(**TCellArray)(__ccgo_up(bp + 48))).FnCell)*4)) = aData + uintptr(libc.Int32FromUint16(maskPage)&(libc.Int32FromUint8(**(**Tu8)(__ccgo_up(piCell)))<<libc.Int32FromInt32(8)|libc.Int32FromUint8(**(**Tu8)(__ccgo_up(piCell + 1)))))
			piCell = piCell + uintptr(2)
			(**(**TCellArray)(__ccgo_up(bp + 48))).FnCell = (**(**TCellArray)(__ccgo_up(bp + 48))).FnCell + 1
		}
		cntOld[i] = (**(**TCellArray)(__ccgo_up(bp + 48))).FnCell
		if i < nOld-int32(1) && !(leafData != 0) {
			sz = libc.Uint16FromInt32((**(**[5]int32)(__ccgo_up(bp + 16)))[i])
			**(**Tu16)(__ccgo_up((**(**TCellArray)(__ccgo_up(bp + 48))).FszCell + uintptr((**(**TCellArray)(__ccgo_up(bp + 48))).FnCell)*2)) = sz
			pTemp = aSpace1 + uintptr(iSpace1)
			iSpace1 = iSpace1 + libc.Int32FromUint16(sz)
			libc.Xmemcpy(tls, pTemp, apDiv[i], uint32(sz))
			**(**uintptr)(__ccgo_up((**(**TCellArray)(__ccgo_up(bp + 48))).FapCell + uintptr((**(**TCellArray)(__ccgo_up(bp + 48))).FnCell)*4)) = pTemp + uintptr(leafCorrection)
			**(**Tu16)(__ccgo_up((**(**TCellArray)(__ccgo_up(bp + 48))).FszCell + uintptr((**(**TCellArray)(__ccgo_up(bp + 48))).FnCell)*2)) = libc.Uint16FromInt32(libc.Int32FromUint16(**(**Tu16)(__ccgo_up((**(**TCellArray)(__ccgo_up(bp + 48))).FszCell + uintptr((**(**TCellArray)(__ccgo_up(bp + 48))).FnCell)*2))) - libc.Int32FromUint16(leafCorrection))
			if !((*TMemPage)(unsafe.Pointer(pOld)).Fleaf != 0) {
				/* The right pointer of the child page pOld becomes the left
				 ** pointer of the divider cell */
				libc.Xmemcpy(tls, **(**uintptr)(__ccgo_up((**(**TCellArray)(__ccgo_up(bp + 48))).FapCell + uintptr((**(**TCellArray)(__ccgo_up(bp + 48))).FnCell)*4)), (*TMemPage)(unsafe.Pointer(pOld)).FaData+8, uint32(4))
			} else {
				for libc.Int32FromUint16(**(**Tu16)(__ccgo_up((**(**TCellArray)(__ccgo_up(bp + 48))).FszCell + uintptr((**(**TCellArray)(__ccgo_up(bp + 48))).FnCell)*2))) < int32(4) {
					/* Do not allow any cells smaller than 4 bytes. If a smaller cell
					 ** does exist, pad it with 0x00 bytes. */
					v1 = iSpace1
					iSpace1 = iSpace1 + 1
					**(**Tu8)(__ccgo_up(aSpace1 + uintptr(v1))) = uint8(0x00)
					**(**Tu16)(__ccgo_up((**(**TCellArray)(__ccgo_up(bp + 48))).FszCell + uintptr((**(**TCellArray)(__ccgo_up(bp + 48))).FnCell)*2)) = **(**Tu16)(__ccgo_up((**(**TCellArray)(__ccgo_up(bp + 48))).FszCell + uintptr((**(**TCellArray)(__ccgo_up(bp + 48))).FnCell)*2)) + 1
				}
			}
			(**(**TCellArray)(__ccgo_up(bp + 48))).FnCell = (**(**TCellArray)(__ccgo_up(bp + 48))).FnCell + 1
		}
		goto _2
	_2:
		;
		i = i + 1
	}
	/*
	 ** Figure out the number of pages needed to hold all b.nCell cells.
	 ** Store this number in "k".  Also compute szNew[] which is the total
	 ** size of all cells on the i-th page and cntNew[] which is the index
	 ** in b.apCell[] of the cell that divides page i from page i+1.
	 ** cntNew[k] should equal b.nCell.
	 **
	 ** Values computed by this block:
	 **
	 **           k: The total number of sibling pages
	 **    szNew[i]: Spaced used on the i-th sibling page.
	 **   cntNew[i]: Index in b.apCell[] and b.szCell[] for the first cell to
	 **              the right of the i-th sibling page.
	 ** usableSpace: Number of bytes of space available on each sibling.
	 **
	 */
	usableSpace = libc.Int32FromUint32((*TBtShared)(unsafe.Pointer(pBt)).FusableSize - uint32(12) + uint32(leafCorrection))
	v1 = libc.Int32FromInt32(0)
	k = v1
	i = v1
	for {
		if !(i < nOld) {
			break
		}
		p = (**(**[3]uintptr)(__ccgo_up(bp + 4)))[i]
		**(**uintptr)(__ccgo_up(bp + 48 + 16 + uintptr(k)*4)) = (*TMemPage)(unsafe.Pointer(p)).FaDataEnd
		**(**int32)(__ccgo_up(bp + 48 + 40 + uintptr(k)*4)) = cntOld[i]
		if k != 0 && **(**int32)(__ccgo_up(bp + 48 + 40 + uintptr(k)*4)) == **(**int32)(__ccgo_up(bp + 48 + 40 + uintptr(k-int32(1))*4)) {
			k = k - 1 /* Omit b.ixNx[] entry for child pages with no cells */
		}
		if !(leafData != 0) {
			k = k + 1
			**(**uintptr)(__ccgo_up(bp + 48 + 16 + uintptr(k)*4)) = (*TMemPage)(unsafe.Pointer(pParent)).FaDataEnd
			**(**int32)(__ccgo_up(bp + 48 + 40 + uintptr(k)*4)) = cntOld[i] + int32(1)
		}
		(**(**[5]int32)(__ccgo_up(bp + 16)))[i] = usableSpace - (*TMemPage)(unsafe.Pointer(p)).FnFree
		j = 0
		for {
			if !(j < libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(p)).FnOverflow)) {
				break
			}
			**(**int32)(__ccgo_up(bp + 16 + uintptr(i)*4)) += int32(2) + libc.Int32FromUint16((*(*func(*libc.TLS, uintptr, uintptr) Tu16)(unsafe.Pointer(&struct{ uintptr }{(*TMemPage)(unsafe.Pointer(p)).FxCellSize})))(tls, p, **(**uintptr)(__ccgo_up(p + 36 + uintptr(j)*4))))
			goto _8
		_8:
			;
			j = j + 1
		}
		cntNew[i] = cntOld[i]
		goto _6
	_6:
		;
		i = i + 1
		k = k + 1
	}
	k = nOld
	i = 0
	for {
		if !(i < k) {
			break
		}
		for (**(**[5]int32)(__ccgo_up(bp + 16)))[i] > usableSpace {
			if i+int32(1) >= k {
				k = i + int32(2)
				if k > libc.Int32FromInt32(NB)+libc.Int32FromInt32(2) {
					**(**int32)(__ccgo_up(bp)) = _sqlite3CorruptError(tls, int32(81700))
					goto balance_cleanup
				}
				(**(**[5]int32)(__ccgo_up(bp + 16)))[k-int32(1)] = 0
				cntNew[k-int32(1)] = (**(**TCellArray)(__ccgo_up(bp + 48))).FnCell
			}
			sz1 = int32(2) + libc.Int32FromUint16(_cachedCellSize(tls, bp+48, cntNew[i]-int32(1)))
			**(**int32)(__ccgo_up(bp + 16 + uintptr(i)*4)) -= sz1
			if !(leafData != 0) {
				if cntNew[i] < (**(**TCellArray)(__ccgo_up(bp + 48))).FnCell {
					sz1 = int32(2) + libc.Int32FromUint16(_cachedCellSize(tls, bp+48, cntNew[i]))
				} else {
					sz1 = 0
				}
			}
			**(**int32)(__ccgo_up(bp + 16 + uintptr(i+int32(1))*4)) += sz1
			cntNew[i] = cntNew[i] - 1
		}
		for cntNew[i] < (**(**TCellArray)(__ccgo_up(bp + 48))).FnCell {
			sz1 = int32(2) + libc.Int32FromUint16(_cachedCellSize(tls, bp+48, cntNew[i]))
			if (**(**[5]int32)(__ccgo_up(bp + 16)))[i]+sz1 > usableSpace {
				break
			}
			**(**int32)(__ccgo_up(bp + 16 + uintptr(i)*4)) += sz1
			cntNew[i] = cntNew[i] + 1
			if !(leafData != 0) {
				if cntNew[i] < (**(**TCellArray)(__ccgo_up(bp + 48))).FnCell {
					sz1 = int32(2) + libc.Int32FromUint16(_cachedCellSize(tls, bp+48, cntNew[i]))
				} else {
					sz1 = 0
				}
			}
			**(**int32)(__ccgo_up(bp + 16 + uintptr(i+int32(1))*4)) -= sz1
		}
		if cntNew[i] >= (**(**TCellArray)(__ccgo_up(bp + 48))).FnCell {
			k = i + int32(1)
		} else {
			if i > 0 {
				v1 = cntNew[i-int32(1)]
			} else {
				v1 = 0
			}
			if cntNew[i] <= v1 {
				**(**int32)(__ccgo_up(bp)) = _sqlite3CorruptError(tls, int32(81733))
				goto balance_cleanup
			}
		}
		goto _9
	_9:
		;
		i = i + 1
	}
	/*
	 ** The packing computed by the previous block is biased toward the siblings
	 ** on the left side (siblings with smaller keys). The left siblings are
	 ** always nearly full, while the right-most sibling might be nearly empty.
	 ** The next block of code attempts to adjust the packing of siblings to
	 ** get a better balance.
	 **
	 ** This adjustment is more than an optimization.  The packing above might
	 ** be so out of balance as to be illegal.  For example, the right-most
	 ** sibling might be completely empty.  This adjustment is not optional.
	 */
	i = k - int32(1)
	for {
		if !(i > 0) {
			break
		}
		szRight = (**(**[5]int32)(__ccgo_up(bp + 16)))[i]         /* Size of sibling on the right */
		szLeft = (**(**[5]int32)(__ccgo_up(bp + 16)))[i-int32(1)] /* Index of first cell to the left of right sibling */
		r = cntNew[i-int32(1)] - int32(1)
		d = r + int32(1) - leafData
		_cachedCellSize(tls, bp+48, d)
		for cond := true; cond; cond = r >= 0 {
			szR = libc.Int32FromUint16(_cachedCellSize(tls, bp+48, r))
			szD = libc.Int32FromUint16(**(**Tu16)(__ccgo_up((**(**TCellArray)(__ccgo_up(bp + 48))).FszCell + uintptr(d)*2)))
			if v14 = szRight != 0; v14 {
				if v13 = bBulk != 0; !v13 {
					if i == k-int32(1) {
						v1 = 0
					} else {
						v1 = int32(2)
					}
				}
			}
			if v14 && (v13 || szRight+szD+int32(2) > szLeft-(szR+v1)) {
				break
			}
			szRight = szRight + (szD + int32(2))
			szLeft = szLeft - (szR + int32(2))
			cntNew[i-int32(1)] = r
			r = r - 1
			d = d - 1
		}
		(**(**[5]int32)(__ccgo_up(bp + 16)))[i] = szRight
		(**(**[5]int32)(__ccgo_up(bp + 16)))[i-int32(1)] = szLeft
		if i > int32(1) {
			v1 = cntNew[i-int32(2)]
		} else {
			v1 = 0
		}
		if cntNew[i-int32(1)] <= v1 {
			**(**int32)(__ccgo_up(bp)) = _sqlite3CorruptError(tls, int32(81777))
			goto balance_cleanup
		}
		goto _11
	_11:
		;
		i = i - 1
	}
	/* Sanity check:  For a non-corrupt database file one of the following
	 ** must be true:
	 **    (1) We found one or more cells (cntNew[0])>0), or
	 **    (2) pPage is a virtual root page.  A virtual root page is when
	 **        the real root page is page 1 and we are the only child of
	 **        that page.
	 */
	/*
	 ** Allocate k new pages.  Reuse old pages where possible.
	 */
	pageFlags = libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TMemPage)(unsafe.Pointer((**(**[3]uintptr)(__ccgo_up(bp + 4)))[0])).FaData)))
	i = 0
	for {
		if !(i < k) {
			break
		}
		if i < nOld {
			v17 = (**(**[3]uintptr)(__ccgo_up(bp + 4)))[i]
			apNew[i] = v17
			**(**uintptr)(__ccgo_up(bp + 112)) = v17
			(**(**[3]uintptr)(__ccgo_up(bp + 4)))[i] = uintptr(0)
			**(**int32)(__ccgo_up(bp)) = _sqlite3PagerWrite(tls, (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 112)))).FpDbPage)
			nNew = nNew + 1
			if _sqlite3PagerPageRefcount(tls, (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 112)))).FpDbPage) != int32(1)+libc.BoolInt32(i == iParentIdx-nxDiv) && **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
				**(**int32)(__ccgo_up(bp)) = _sqlite3CorruptError(tls, int32(81810))
			}
			if **(**int32)(__ccgo_up(bp)) != 0 {
				goto balance_cleanup
			}
		} else {
			if bBulk != 0 {
				v18 = uint32(1)
			} else {
				v18 = **(**TPgno)(__ccgo_up(bp + 36))
			}
			**(**int32)(__ccgo_up(bp)) = _allocateBtreePage(tls, pBt, bp+112, bp+36, v18, uint8(0))
			if **(**int32)(__ccgo_up(bp)) != 0 {
				goto balance_cleanup
			}
			_zeroPage(tls, **(**uintptr)(__ccgo_up(bp + 112)), pageFlags)
			apNew[i] = **(**uintptr)(__ccgo_up(bp + 112))
			nNew = nNew + 1
			cntOld[i] = (**(**TCellArray)(__ccgo_up(bp + 48))).FnCell
			/* Set the pointer-map entry for the new sibling page. */
			if (*TBtShared)(unsafe.Pointer(pBt)).FautoVacuum != 0 {
				_ptrmapPut(tls, pBt, (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 112)))).Fpgno, uint8(PTRMAP_BTREE), (*TMemPage)(unsafe.Pointer(pParent)).Fpgno, bp)
				if **(**int32)(__ccgo_up(bp)) != SQLITE_OK {
					goto balance_cleanup
				}
			}
		}
		goto _16
	_16:
		;
		i = i + 1
	}
	/*
	 ** Reassign page numbers so that the new pages are in ascending order.
	 ** This helps to keep entries in the disk file in order so that a scan
	 ** of the table is closer to a linear scan through the file. That in turn
	 ** helps the operating system to deliver pages from the disk more rapidly.
	 **
	 ** An O(N*N) sort algorithm is used, but since N is never more than NB+2
	 ** (5), that is not a performance concern.
	 **
	 ** When NB==3, this one optimization makes the database about 25% faster
	 ** for large insertions and deletions.
	 */
	i = 0
	for {
		if !(i < nNew) {
			break
		}
		aPgno[i] = (*TMemPage)(unsafe.Pointer(apNew[i])).Fpgno
		goto _19
	_19:
		;
		i = i + 1
	}
	i = 0
	for {
		if !(i < nNew-int32(1)) {
			break
		}
		iB = i
		j = i + int32(1)
		for {
			if !(j < nNew) {
				break
			}
			if (*TMemPage)(unsafe.Pointer(apNew[j])).Fpgno < (*TMemPage)(unsafe.Pointer(apNew[iB])).Fpgno {
				iB = j
			}
			goto _21
		_21:
			;
			j = j + 1
		}
		/* If apNew[i] has a page number that is bigger than any of the
		 ** subsequence apNew[i] entries, then swap apNew[i] with the subsequent
		 ** entry that has the smallest page number (which we know to be
		 ** entry apNew[iB]).
		 */
		if iB != i {
			pgnoA = (*TMemPage)(unsafe.Pointer(apNew[i])).Fpgno
			pgnoB = (*TMemPage)(unsafe.Pointer(apNew[iB])).Fpgno
			pgnoTemp = libc.Uint32FromInt32(_sqlite3PendingByte)/(*TBtShared)(unsafe.Pointer(pBt)).FpageSize + uint32(1)
			fgA = (*TDbPage)(unsafe.Pointer((*TMemPage)(unsafe.Pointer(apNew[i])).FpDbPage)).Fflags
			fgB = (*TDbPage)(unsafe.Pointer((*TMemPage)(unsafe.Pointer(apNew[iB])).FpDbPage)).Fflags
			_sqlite3PagerRekey(tls, (*TMemPage)(unsafe.Pointer(apNew[i])).FpDbPage, pgnoTemp, fgB)
			_sqlite3PagerRekey(tls, (*TMemPage)(unsafe.Pointer(apNew[iB])).FpDbPage, pgnoA, fgA)
			_sqlite3PagerRekey(tls, (*TMemPage)(unsafe.Pointer(apNew[i])).FpDbPage, pgnoB, fgB)
			(*TMemPage)(unsafe.Pointer(apNew[i])).Fpgno = pgnoB
			(*TMemPage)(unsafe.Pointer(apNew[iB])).Fpgno = pgnoA
		}
		goto _20
	_20:
		;
		i = i + 1
	}
	_sqlite3Put4byte(tls, pRight, (*TMemPage)(unsafe.Pointer(apNew[nNew-int32(1)])).Fpgno)
	/* If the sibling pages are not leaves, ensure that the right-child pointer
	 ** of the right-most new sibling page is set to the value that was
	 ** originally in the same field of the right-most old sibling page. */
	if pageFlags&int32(PTF_LEAF) == 0 && nOld != nNew {
		if nNew > nOld {
			pOld1 = apNew[nOld-int32(1)]
		} else {
			pOld1 = (**(**[3]uintptr)(__ccgo_up(bp + 4)))[nOld-int32(1)]
		}
		libc.Xmemcpy(tls, (*TMemPage)(unsafe.Pointer(apNew[nNew-int32(1)])).FaData+8, (*TMemPage)(unsafe.Pointer(pOld1)).FaData+8, uint32(4))
	}
	/* Make any required updates to pointer map entries associated with
	 ** cells stored on sibling pages following the balance operation. Pointer
	 ** map entries associated with divider cells are set by the insertCell()
	 ** routine. The associated pointer map entries are:
	 **
	 **   a) if the cell contains a reference to an overflow chain, the
	 **      entry associated with the first page in the overflow chain, and
	 **
	 **   b) if the sibling pages are not leaves, the child page associated
	 **      with the cell.
	 **
	 ** If the sibling pages are not leaves, then the pointer map entry
	 ** associated with the right-child of each sibling may also need to be
	 ** updated. This happens below, after the sibling pages have been
	 ** populated, not here.
	 */
	if (*TBtShared)(unsafe.Pointer(pBt)).FautoVacuum != 0 {
		v17 = apNew[0]
		pOld2 = v17
		pNew1 = v17
		cntOldNext = libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pNew1)).FnCell) + libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pNew1)).FnOverflow)
		iNew = 0
		iOld = 0
		i = 0
		for {
			if !(i < (**(**TCellArray)(__ccgo_up(bp + 48))).FnCell) {
				break
			}
			pCell = **(**uintptr)(__ccgo_up((**(**TCellArray)(__ccgo_up(bp + 48))).FapCell + uintptr(i)*4))
			for i == cntOldNext {
				iOld = iOld + 1
				if iOld < nNew {
					v17 = apNew[iOld]
				} else {
					v17 = (**(**[3]uintptr)(__ccgo_up(bp + 4)))[iOld]
				}
				pOld2 = v17
				cntOldNext = cntOldNext + (libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pOld2)).FnCell) + libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pOld2)).FnOverflow) + libc.BoolInt32(!(leafData != 0)))
			}
			if i == cntNew[iNew] {
				iNew = iNew + 1
				v1 = iNew
				pNew1 = apNew[v1]
				if !(leafData != 0) {
					goto _23
				}
			}
			/* Cell pCell is destined for new sibling page pNew. Originally, it
			 ** was either part of sibling page iOld (possibly an overflow cell),
			 ** or else the divider cell to the left of sibling page iOld. So,
			 ** if sibling page iOld had the same page number as pNew, and if
			 ** pCell really was a part of sibling page iOld (not a divider or
			 ** overflow cell), we can skip updating the pointer map entries.  */
			if iOld >= nNew || (*TMemPage)(unsafe.Pointer(pNew1)).Fpgno != aPgno[iOld] || !(uint32(pCell) >= uint32((*TMemPage)(unsafe.Pointer(pOld2)).FaData) && uint32(pCell) < uint32((*TMemPage)(unsafe.Pointer(pOld2)).FaDataEnd)) {
				if !(leafCorrection != 0) {
					_ptrmapPut(tls, pBt, _sqlite3Get4byte(tls, pCell), uint8(PTRMAP_BTREE), (*TMemPage)(unsafe.Pointer(pNew1)).Fpgno, bp)
				}
				if libc.Int32FromUint16(_cachedCellSize(tls, bp+48, i)) > libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pNew1)).FminLocal) {
					_ptrmapPutOvflPtr(tls, pNew1, pOld2, pCell, bp)
				}
				if **(**int32)(__ccgo_up(bp)) != 0 {
					goto balance_cleanup
				}
			}
			goto _23
		_23:
			;
			i = i + 1
		}
	}
	/* Insert new divider cells into pParent. */
	i = 0
	for {
		if !(i < nNew-int32(1)) {
			break
		}
		pNew2 = apNew[i]
		j = cntNew[i]
		pCell1 = **(**uintptr)(__ccgo_up((**(**TCellArray)(__ccgo_up(bp + 48))).FapCell + uintptr(j)*4))
		sz2 = libc.Int32FromUint16(**(**Tu16)(__ccgo_up((**(**TCellArray)(__ccgo_up(bp + 48))).FszCell + uintptr(j)*2))) + libc.Int32FromUint16(leafCorrection)
		pTemp1 = aOvflSpace + uintptr(iOvflSpace)
		if !((*TMemPage)(unsafe.Pointer(pNew2)).Fleaf != 0) {
			libc.Xmemcpy(tls, (*TMemPage)(unsafe.Pointer(pNew2)).FaData+8, pCell1, uint32(4))
		} else {
			if leafData != 0 {
				j = j - 1
				(*(*func(*libc.TLS, uintptr, uintptr, uintptr))(unsafe.Pointer(&struct{ uintptr }{(*TMemPage)(unsafe.Pointer(pNew2)).FxParseCell})))(tls, pNew2, **(**uintptr)(__ccgo_up((**(**TCellArray)(__ccgo_up(bp + 48))).FapCell + uintptr(j)*4)), bp+116)
				pCell1 = pTemp1
				sz2 = int32(4) + _sqlite3PutVarint(tls, pCell1+4, libc.Uint64FromInt64((**(**TCellInfo)(__ccgo_up(bp + 116))).FnKey))
				pTemp1 = uintptr(0)
			} else {
				pCell1 = pCell1 - uintptr(4)
				/* Obscure case for non-leaf-data trees: If the cell at pCell was
				 ** previously stored on a leaf node, and its reported size was 4
				 ** bytes, then it may actually be smaller than this
				 ** (see btreeParseCellPtr(), 4 bytes is the minimum size of
				 ** any cell). But it is important to pass the correct size to
				 ** insertCell(), so reparse the cell now.
				 **
				 ** This can only happen for b-trees used to evaluate "IN (SELECT ...)"
				 ** and WITHOUT ROWID tables with exactly one column which is the
				 ** primary key.
				 */
				if libc.Int32FromUint16(**(**Tu16)(__ccgo_up((**(**TCellArray)(__ccgo_up(bp + 48))).FszCell + uintptr(j)*2))) == int32(4) {
					sz2 = libc.Int32FromUint16((*(*func(*libc.TLS, uintptr, uintptr) Tu16)(unsafe.Pointer(&struct{ uintptr }{(*TMemPage)(unsafe.Pointer(pParent)).FxCellSize})))(tls, pParent, pCell1))
				}
			}
		}
		iOvflSpace = iOvflSpace + sz2
		k = 0
		for {
			if !(**(**int32)(__ccgo_up(bp + 48 + 40 + uintptr(k)*4)) <= j) {
				break
			}
			goto _27
		_27:
			;
			k = k + 1
		}
		pSrcEnd = **(**uintptr)(__ccgo_up(bp + 48 + 16 + uintptr(k)*4))
		if uint32(pCell1) < uint32(pSrcEnd) && uint32(pCell1+uintptr(sz2)) > uint32(pSrcEnd) {
			**(**int32)(__ccgo_up(bp)) = _sqlite3CorruptError(tls, int32(82016))
			goto balance_cleanup
		}
		**(**int32)(__ccgo_up(bp)) = _insertCell(tls, pParent, nxDiv+i, pCell1, sz2, pTemp1, (*TMemPage)(unsafe.Pointer(pNew2)).Fpgno)
		if **(**int32)(__ccgo_up(bp)) != SQLITE_OK {
			goto balance_cleanup
		}
		goto _26
	_26:
		;
		i = i + 1
	}
	/* Now update the actual sibling pages. The order in which they are updated
	 ** is important, as this code needs to avoid disrupting any page from which
	 ** cells may still to be read. In practice, this means:
	 **
	 **  (1) If cells are moving left (from apNew[iPg] to apNew[iPg-1])
	 **      then it is not safe to update page apNew[iPg] until after
	 **      the left-hand sibling apNew[iPg-1] has been updated.
	 **
	 **  (2) If cells are moving right (from apNew[iPg] to apNew[iPg+1])
	 **      then it is not safe to update page apNew[iPg] until after
	 **      the right-hand sibling apNew[iPg+1] has been updated.
	 **
	 ** If neither of the above apply, the page is safe to update.
	 **
	 ** The iPg value in the following loop starts at nNew-1 goes down
	 ** to 0, then back up to nNew-1 again, thus making two passes over
	 ** the pages.  On the initial downward pass, only condition (1) above
	 ** needs to be tested because (2) will always be true from the previous
	 ** step.  On the upward pass, both conditions are always true, so the
	 ** upwards pass simply processes pages that were missed on the downward
	 ** pass.
	 */
	i = int32(1) - nNew
	for {
		if !(i < nNew) {
			break
		}
		if i < 0 {
			v1 = -i
		} else {
			v1 = i
		}
		iPg = v1
		if (**(**[5]Tu8)(__ccgo_up(bp + 40)))[iPg] != 0 {
			goto _28
		} /* Skip pages already processed */
		if i >= 0 || cntOld[iPg-int32(1)] >= cntNew[iPg-int32(1)] {
			/* Verify condition (1):  If cells are moving left, update iPg
			 ** only after iPg-1 has already been updated. */
			/* Verify condition (2):  If cells are moving right, update iPg
			 ** only after iPg+1 has already been updated. */
			if iPg == 0 {
				v1 = libc.Int32FromInt32(0)
				iOld1 = v1
				iNew1 = v1
				nNewCell = cntNew[0]
			} else {
				if iPg < nOld {
					v1 = cntOld[iPg-int32(1)] + libc.BoolInt32(!(leafData != 0))
				} else {
					v1 = (**(**TCellArray)(__ccgo_up(bp + 48))).FnCell
				}
				iOld1 = v1
				iNew1 = cntNew[iPg-int32(1)] + libc.BoolInt32(!(leafData != 0))
				nNewCell = cntNew[iPg] - iNew1
			}
			**(**int32)(__ccgo_up(bp)) = _editPage(tls, apNew[iPg], iOld1, iNew1, nNewCell, bp+48)
			if **(**int32)(__ccgo_up(bp)) != 0 {
				goto balance_cleanup
			}
			(**(**[5]Tu8)(__ccgo_up(bp + 40)))[iPg] = (**(**[5]Tu8)(__ccgo_up(bp + 40)))[iPg] + 1
			(*TMemPage)(unsafe.Pointer(apNew[iPg])).FnFree = usableSpace - (**(**[5]int32)(__ccgo_up(bp + 16)))[iPg]
		}
		goto _28
	_28:
		;
		i = i + 1
	}
	/* All pages have been processed exactly once */
	if isRoot != 0 && libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pParent)).FnCell) == 0 && libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pParent)).FhdrOffset) <= (*TMemPage)(unsafe.Pointer(apNew[0])).FnFree {
		/* The root page of the b-tree now contains no cells. The only sibling
		 ** page is the right-child of the parent. Copy the contents of the
		 ** child page into the parent, decreasing the overall height of the
		 ** b-tree structure by one. This is described as the "balance-shallower"
		 ** sub-algorithm in some documentation.
		 **
		 ** If this is an auto-vacuum database, the call to copyNodeContent()
		 ** sets all pointer-map entries corresponding to database image pages
		 ** for which the pointer is stored within the content being copied.
		 **
		 ** It is critical that the child page be defragmented before being
		 ** copied into the parent, because if the parent is page 1 then it will
		 ** by smaller than the child due to the database header, and so all the
		 ** free space needs to be up front.
		 */
		**(**int32)(__ccgo_up(bp)) = _defragmentPage(tls, apNew[0], -int32(1))
		_copyNodeContent(tls, apNew[0], pParent, bp)
		_freePage(tls, apNew[0], bp)
	} else {
		if (*TBtShared)(unsafe.Pointer(pBt)).FautoVacuum != 0 && !(leafCorrection != 0) {
			/* Fix the pointer map entries associated with the right-child of each
			 ** sibling page. All other pointer map entries have already been taken
			 ** care of.  */
			i = 0
			for {
				if !(i < nNew) {
					break
				}
				key = _sqlite3Get4byte(tls, (*TMemPage)(unsafe.Pointer(apNew[i])).FaData+8)
				_ptrmapPut(tls, pBt, key, uint8(PTRMAP_BTREE), (*TMemPage)(unsafe.Pointer(apNew[i])).Fpgno, bp)
				goto _32
			_32:
				;
				i = i + 1
			}
		}
	}
	/* Free any old pages that were not reused as new pages.
	 */
	i = nNew
	for {
		if !(i < nOld) {
			break
		}
		_freePage(tls, (**(**[3]uintptr)(__ccgo_up(bp + 4)))[i], bp)
		goto _33
	_33:
		;
		i = i + 1
	}
	/*
	 ** Cleanup before returning.
	 */
	goto balance_cleanup
balance_cleanup:
	;
	_sqlite3DbFree(tls, uintptr(0), (**(**TCellArray)(__ccgo_up(bp + 48))).FapCell)
	i = 0
	for {
		if !(i < nOld) {
			break
		}
		_releasePage(tls, (**(**[3]uintptr)(__ccgo_up(bp + 4)))[i])
		goto _34
	_34:
		;
		i = i + 1
	}
	i = 0
	for {
		if !(i < nNew) {
			break
		}
		_releasePage(tls, apNew[i])
		goto _35
	_35:
		;
		i = i + 1
	}
	return **(**int32)(__ccgo_up(bp))
}

// C documentation
//
//	/*
//	** Invoke the busy handler for a btree.
//	*/
func _btreeInvokeBusyHandler(tls *libc.TLS, pArg uintptr) (r int32) {
	var pBt uintptr
	_ = pBt
	pBt = pArg
	return _sqlite3InvokeBusyHandler(tls, (*TBtShared)(unsafe.Pointer(pBt)).Fdb+460)
}

// C documentation
//
//	/*
//	** Advance the cursor to the next entry in the database.
//	** Return value:
//	**
//	**    SQLITE_OK        success
//	**    SQLITE_DONE      cursor is already pointing at the last element
//	**    otherwise        some kind of error occurred
//	**
//	** The main entry point is sqlite3BtreeNext().  That routine is optimized
//	** for the common case of merely incrementing the cell counter BtCursor.aiIdx
//	** to the next cell on the current page.  The (slower) btreeNext() helper
//	** routine is called when it is necessary to move to a different page or
//	** to restore the cursor.
//	**
//	** If bit 0x01 of the F argument in sqlite3BtreeNext(C,F) is 1, then the
//	** cursor corresponds to an SQL index and this routine could have been
//	** skipped if the SQL index had been a unique index.  The F argument
//	** is a hint to the implement.  SQLite btree implementation does not use
//	** this hint, but COMDB2 does.
//	*/
func _btreeNext(tls *libc.TLS, pCur uintptr) (r int32) {
	var idx, rc, v1 int32
	var pPage, v3 uintptr
	var v2 Tu16
	_, _, _, _, _, _ = idx, pPage, rc, v1, v2, v3
	if libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCur)).FeState) != CURSOR_VALID {
		if libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCur)).FeState) >= int32(CURSOR_REQUIRESEEK) {
			v1 = _btreeRestoreCursorPosition(tls, pCur)
		} else {
			v1 = SQLITE_OK
		}
		rc = v1
		if rc != SQLITE_OK {
			return rc
		}
		if int32(CURSOR_INVALID) == libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCur)).FeState) {
			return int32(SQLITE_DONE)
		}
		if libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCur)).FeState) == int32(CURSOR_SKIPNEXT) {
			(*TBtCursor)(unsafe.Pointer(pCur)).FeState = uint8(CURSOR_VALID)
			if (*TBtCursor)(unsafe.Pointer(pCur)).FskipNext > 0 {
				return SQLITE_OK
			}
		}
	}
	pPage = (*TBtCursor)(unsafe.Pointer(pCur)).FpPage
	v3 = pCur + 62
	*(*Tu16)(unsafe.Pointer(v3)) = *(*Tu16)(unsafe.Pointer(v3)) + 1
	v2 = *(*Tu16)(unsafe.Pointer(v3))
	idx = libc.Int32FromUint16(v2)
	if _sqlite3FaultSim(tls, int32(412)) != 0 {
		(*TMemPage)(unsafe.Pointer(pPage)).FisInit = uint8(0)
	}
	if !((*TMemPage)(unsafe.Pointer(pPage)).FisInit != 0) {
		return _sqlite3CorruptError(tls, int32(79489))
	}
	if idx >= libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FnCell) {
		if !((*TMemPage)(unsafe.Pointer(pPage)).Fleaf != 0) {
			rc = _moveToChild(tls, pCur, _sqlite3Get4byte(tls, (*TMemPage)(unsafe.Pointer(pPage)).FaData+uintptr(libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pPage)).FhdrOffset)+int32(8))))
			if rc != 0 {
				return rc
			}
			return _moveToLeftmost(tls, pCur)
		}
		for cond := true; cond; cond = libc.Int32FromUint16((*TBtCursor)(unsafe.Pointer(pCur)).Fix) >= libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FnCell) {
			if int32((*TBtCursor)(unsafe.Pointer(pCur)).FiPage) == 0 {
				(*TBtCursor)(unsafe.Pointer(pCur)).FeState = uint8(CURSOR_INVALID)
				return int32(SQLITE_DONE)
			}
			_moveToParent(tls, pCur)
			pPage = (*TBtCursor)(unsafe.Pointer(pCur)).FpPage
		}
		if (*TMemPage)(unsafe.Pointer(pPage)).FintKey != 0 {
			return _sqlite3BtreeNext(tls, pCur, 0)
		} else {
			return SQLITE_OK
		}
	}
	if (*TMemPage)(unsafe.Pointer(pPage)).Fleaf != 0 {
		return SQLITE_OK
	} else {
		return _moveToLeftmost(tls, pCur)
	}
	return r
}

// C documentation
//
//	/*
//	** Release all of the apPage[] pages for a cursor.
//	*/
func _btreeReleaseAllCursorPages(tls *libc.TLS, pCur uintptr) {
	var i int32
	_ = i
	if int32((*TBtCursor)(unsafe.Pointer(pCur)).FiPage) >= 0 {
		i = 0
		for {
			if !(i < int32((*TBtCursor)(unsafe.Pointer(pCur)).FiPage)) {
				break
			}
			_releasePageNotNull(tls, **(**uintptr)(__ccgo_up(pCur + 112 + uintptr(i)*4)))
			goto _1
		_1:
			;
			i = i + 1
		}
		_releasePageNotNull(tls, (*TBtCursor)(unsafe.Pointer(pCur)).FpPage)
		(*TBtCursor)(unsafe.Pointer(pCur)).FiPage = int8(-int32(1))
	}
}

// C documentation
//
//	/*
//	** Invoke the progress handler, if appropriate.  Also check for an
//	** interrupt.
//	*/
func _checkProgress(tls *libc.TLS, pCheck uintptr) {
	var db uintptr
	_ = db
	db = (*TIntegrityCk)(unsafe.Pointer(pCheck)).Fdb
	if libc.AtomicLoadNInt32(db+308, libc.Int32FromInt32(__ATOMIC_RELAXED)) != 0 {
		(*TIntegrityCk)(unsafe.Pointer(pCheck)).Frc = int32(SQLITE_INTERRUPT)
		(*TIntegrityCk)(unsafe.Pointer(pCheck)).FnErr = (*TIntegrityCk)(unsafe.Pointer(pCheck)).FnErr + 1
		(*TIntegrityCk)(unsafe.Pointer(pCheck)).FmxErr = 0
	}
	if (*Tsqlite3)(unsafe.Pointer(db)).FxProgress != 0 {
		(*TIntegrityCk)(unsafe.Pointer(pCheck)).FnStep = (*TIntegrityCk)(unsafe.Pointer(pCheck)).FnStep + 1
		if (*TIntegrityCk)(unsafe.Pointer(pCheck)).FnStep%(*Tsqlite3)(unsafe.Pointer(db)).FnProgressOps == uint32(0) && (*(*func(*libc.TLS, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*Tsqlite3)(unsafe.Pointer(db)).FxProgress})))(tls, (*Tsqlite3)(unsafe.Pointer(db)).FpProgressArg) != 0 {
			(*TIntegrityCk)(unsafe.Pointer(pCheck)).Frc = int32(SQLITE_INTERRUPT)
			(*TIntegrityCk)(unsafe.Pointer(pCheck)).FnErr = (*TIntegrityCk)(unsafe.Pointer(pCheck)).FnErr + 1
			(*TIntegrityCk)(unsafe.Pointer(pCheck)).FmxErr = 0
		}
	}
}

// C documentation
//
//	/*
//	** Close all cursors.
//	**
//	** Also release any dynamic memory held by the VM in the Vdbe.aMem memory
//	** cell array. This is necessary as the memory cell array may contain
//	** pointers to VdbeFrame objects, which may in turn contain pointers to
//	** open cursors.
//	*/
func _closeAllCursors(tls *libc.TLS, p uintptr) {
	var pDel, pFrame uintptr
	_, _ = pDel, pFrame
	if (*TVdbe)(unsafe.Pointer(p)).FpFrame != 0 {
		pFrame = (*TVdbe)(unsafe.Pointer(p)).FpFrame
		for {
			if !((*TVdbeFrame)(unsafe.Pointer(pFrame)).FpParent != 0) {
				break
			}
			goto _1
		_1:
			;
			pFrame = (*TVdbeFrame)(unsafe.Pointer(pFrame)).FpParent
		}
		_sqlite3VdbeFrameRestore(tls, pFrame)
		(*TVdbe)(unsafe.Pointer(p)).FpFrame = uintptr(0)
		(*TVdbe)(unsafe.Pointer(p)).FnFrame = 0
	}
	_closeCursorsInFrame(tls, p)
	_releaseMemArray(tls, (*TVdbe)(unsafe.Pointer(p)).FaMem, (*TVdbe)(unsafe.Pointer(p)).FnMem)
	for (*TVdbe)(unsafe.Pointer(p)).FpDelFrame != 0 {
		pDel = (*TVdbe)(unsafe.Pointer(p)).FpDelFrame
		(*TVdbe)(unsafe.Pointer(p)).FpDelFrame = (*TVdbeFrame)(unsafe.Pointer(pDel)).FpParent
		_sqlite3VdbeFrameDelete(tls, pDel)
	}
	/* Delete any auxdata allocations made by the VM */
	if (*TVdbe)(unsafe.Pointer(p)).FpAuxData != 0 {
		_sqlite3VdbeDeleteAuxData(tls, (*TVdbe)(unsafe.Pointer(p)).Fdb, p+220, -int32(1), 0)
	}
}

// C documentation
//
//	/*
//	** This function performs the parts of the "close file" operation
//	** common to all locking schemes. It closes the directory and file
//	** handles, if they are valid, and sets all fields of the unixFile
//	** structure to 0.
//	**
//	** It is *not* necessary to hold the mutex when this routine is called,
//	** even on VxWorks.  A mutex will be acquired on VxWorks by the
//	** vxworksReleaseFileId() routine.
//	*/
func _closeUnixFile(tls *libc.TLS, id uintptr) (r int32) {
	var pFile uintptr
	_ = pFile
	pFile = id
	_unixUnmapfile(tls, pFile)
	if (*TunixFile)(unsafe.Pointer(pFile)).Fh >= 0 {
		_robust_close(tls, pFile, (*TunixFile)(unsafe.Pointer(pFile)).Fh, int32(42499))
		(*TunixFile)(unsafe.Pointer(pFile)).Fh = -int32(1)
	}
	Xsqlite3_free(tls, (*TunixFile)(unsafe.Pointer(pFile)).FpPreallocatedUnused)
	libc.Xmemset(tls, pFile, 0, uint32(84))
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** Generate code that will evaluate all == and IN constraints for an
//	** index scan.
//	**
//	** For example, consider table t1(a,b,c,d,e,f) with index i1(a,b,c).
//	** Suppose the WHERE clause is this:  a==5 AND b IN (1,2,3) AND c>5 AND c<10
//	** The index has as many as three equality constraints, but in this
//	** example, the third "c" value is an inequality.  So only two
//	** constraints are coded.  This routine will generate code to evaluate
//	** a==5 and b IN (1,2,3).  The current values for a and b will be stored
//	** in consecutive registers and the index of the first register is returned.
//	**
//	** In the example above nEq==2.  But this subroutine works for any value
//	** of nEq including 0.  If nEq==0, this routine is nearly a no-op.
//	** The only thing it does is allocate the pLevel->iMem memory cell and
//	** compute the affinity string.
//	**
//	** The nExtraReg parameter is 0 or 1.  It is 0 if all WHERE clause constraints
//	** are == or IN and are covered by the nEq.  nExtraReg is 1 if there is
//	** an inequality constraint (such as the "c>=5 AND c<10" in the example) that
//	** occurs after the nEq quality constraints.
//	**
//	** This routine allocates a range of nEq+nExtraReg memory cells and returns
//	** the index of the first memory cell in that range. The code that
//	** calls this routine will use that memory range to store keys for
//	** start and termination conditions of the loop.
//	** key value of the loop.  If one or more IN operators appear, then
//	** this routine allocates an additional nEq memory cells for internal
//	** use.
//	**
//	** Before returning, *pzAff is set to point to a buffer containing a
//	** copy of the column affinity string of the index allocated using
//	** sqlite3DbMalloc(). Except, entries in the copy of the string associated
//	** with equality constraints that use BLOB or NONE affinity are set to
//	** SQLITE_AFF_BLOB. This is to deal with SQL such as the following:
//	**
//	**   CREATE TABLE t1(a TEXT PRIMARY KEY, b);
//	**   SELECT ... FROM t1 AS t2, t1 WHERE t1.a = t2.b;
//	**
//	** In the example above, the index on t1(a) has TEXT affinity. But since
//	** the right hand side of the equality constraint (t2.b) has BLOB/NONE affinity,
//	** no conversion should be attempted before using a t2.b value as part of
//	** a key to search the index. Hence the first byte in the returned affinity
//	** string in this example would be set to SQLITE_AFF_BLOB.
//	*/
func _codeAllEqualityTerms(tls *libc.TLS, pParse uintptr, pLevel uintptr, bRev int32, nExtraReg int32, pzAff uintptr) (r int32) {
	var iIdxCur, j, nReg, r1, regBase, v1 int32
	var nEq, nSkip Tu16
	var pIdx, pLoop, pRight, pTerm, v, zAff uintptr
	_, _, _, _, _, _, _, _, _, _, _, _, _, _ = iIdxCur, j, nEq, nReg, nSkip, pIdx, pLoop, pRight, pTerm, r1, regBase, v, zAff, v1 /* Number of left-most columns to skip */
	v = (*TParse)(unsafe.Pointer(pParse)).FpVdbe                                                                                  /* Affinity string to return */
	/* This module is only called on query plans that use an index. */
	pLoop = (*TWhereLevel)(unsafe.Pointer(pLevel)).FpWLoop
	nEq = (*(*struct {
		FnEq          Tu16
		FnBtm         Tu16
		FnTop         Tu16
		FnDistinctCol Tu16
		FpIndex       uintptr
		FpOrderBy     uintptr
	})(unsafe.Pointer(pLoop + 24))).FnEq
	nSkip = (*TWhereLoop)(unsafe.Pointer(pLoop)).FnSkip
	pIdx = (*(*struct {
		FnEq          Tu16
		FnBtm         Tu16
		FnTop         Tu16
		FnDistinctCol Tu16
		FpIndex       uintptr
		FpOrderBy     uintptr
	})(unsafe.Pointer(pLoop + 24))).FpIndex
	/* Figure out how many memory cells we will need then allocate them.
	 */
	regBase = (*TParse)(unsafe.Pointer(pParse)).FnMem + int32(1)
	nReg = libc.Int32FromUint16(nEq) + nExtraReg
	**(**int32)(__ccgo_up(pParse + 48)) += nReg
	zAff = _sqlite3DbStrDup(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, _sqlite3IndexAffinityStr(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, pIdx))
	if nSkip != 0 {
		iIdxCur = (*TWhereLevel)(unsafe.Pointer(pLevel)).FiIdxCur
		_sqlite3VdbeAddOp3(tls, v, int32(OP_Null), 0, regBase, regBase+libc.Int32FromUint16(nSkip)-int32(1))
		if bRev != 0 {
			v1 = int32(OP_Last)
		} else {
			v1 = int32(OP_Rewind)
		}
		_sqlite3VdbeAddOp1(tls, v, v1, iIdxCur)
		j = _sqlite3VdbeAddOp0(tls, v, int32(OP_Goto))
		if bRev != 0 {
			v1 = int32(OP_SeekLT)
		} else {
			v1 = int32(OP_SeekGT)
		}
		(*TWhereLevel)(unsafe.Pointer(pLevel)).FaddrSkip = _sqlite3VdbeAddOp4Int(tls, v, v1, iIdxCur, 0, regBase, libc.Int32FromUint16(nSkip))
		_sqlite3VdbeJumpHere(tls, v, j)
		j = 0
		for {
			if !(j < libc.Int32FromUint16(nSkip)) {
				break
			}
			_sqlite3VdbeAddOp3(tls, v, int32(OP_Column), iIdxCur, j, regBase+j)
			goto _3
		_3:
			;
			j = j + 1
		}
	}
	/* Evaluate the equality constraints
	 */
	j = libc.Int32FromUint16(nSkip)
	for {
		if !(j < libc.Int32FromUint16(nEq)) {
			break
		}
		pTerm = **(**uintptr)(__ccgo_up((*TWhereLoop)(unsafe.Pointer(pLoop)).FaLTerm + uintptr(j)*4))
		/* The following testcase is true for indices with redundant columns.
		 ** Ex: CREATE INDEX i1 ON t1(a,b,a); SELECT * FROM t1 WHERE a=0 AND b=0; */
		r1 = _codeEqualityTerm(tls, pParse, pTerm, pLevel, j, bRev, regBase+j)
		if r1 != regBase+j {
			if nReg == int32(1) {
				_sqlite3ReleaseTempReg(tls, pParse, regBase)
				regBase = r1
			} else {
				_sqlite3VdbeAddOp2(tls, v, int32(OP_Copy), r1, regBase+j)
			}
		}
		if libc.Int32FromUint16((*TWhereTerm)(unsafe.Pointer(pTerm)).FeOperator)&int32(WO_IN) != 0 {
			if (*TExpr)(unsafe.Pointer((*TWhereTerm)(unsafe.Pointer(pTerm)).FpExpr)).Fflags&uint32(EP_xIsSelect) != 0 {
				/* No affinity ever needs to be (or should be) applied to a value
				 ** from the RHS of an "? IN (SELECT ...)" expression. The
				 ** sqlite3FindInIndex() routine has already ensured that the
				 ** affinity of the comparison has been applied to the value.  */
				if zAff != 0 {
					**(**int8)(__ccgo_up(zAff + uintptr(j))) = int8(SQLITE_AFF_BLOB)
				}
			}
		} else {
			if libc.Int32FromUint16((*TWhereTerm)(unsafe.Pointer(pTerm)).FeOperator)&int32(WO_ISNULL) == 0 {
				pRight = (*TExpr)(unsafe.Pointer((*TWhereTerm)(unsafe.Pointer(pTerm)).FpExpr)).FpRight
				if libc.Int32FromUint16((*TWhereTerm)(unsafe.Pointer(pTerm)).FwtFlags)&int32(TERM_IS) == 0 && _sqlite3ExprCanBeNull(tls, pRight) != 0 {
					_sqlite3VdbeAddOp2(tls, v, int32(OP_IsNull), regBase+j, (*TWhereLevel)(unsafe.Pointer(pLevel)).FaddrBrk)
				}
				if (*TParse)(unsafe.Pointer(pParse)).FnErr == 0 {
					if int32(_sqlite3CompareAffinity(tls, pRight, **(**int8)(__ccgo_up(zAff + uintptr(j))))) == int32(SQLITE_AFF_BLOB) {
						**(**int8)(__ccgo_up(zAff + uintptr(j))) = int8(SQLITE_AFF_BLOB)
					}
					if _sqlite3ExprNeedsNoAffinityChange(tls, pRight, **(**int8)(__ccgo_up(zAff + uintptr(j)))) != 0 {
						**(**int8)(__ccgo_up(zAff + uintptr(j))) = int8(SQLITE_AFF_BLOB)
					}
				}
			}
		}
		goto _4
	_4:
		;
		j = j + 1
	}
	**(**uintptr)(__ccgo_up(pzAff)) = zAff
	return regBase
}

// C documentation
//
//	/*
//	** Generate code for the RETURNING trigger.  Unlike other triggers
//	** that invoke a subprogram in the bytecode, the code for RETURNING
//	** is generated in-line.
//	*/
func _codeReturningTrigger(tls *libc.TLS, pParse uintptr, pTrigger uintptr, pTab uintptr, regIn int32) {
	bp := tls.Alloc(160)
	defer tls.Free(160)
	var db, pCol, pFrom, pNew, pReturning, v, v2 uintptr
	var i, nCol, reg, v1 int32
	var _ /* sNC at bp+124 */ TNameContext
	var _ /* sSelect at bp+0 */ TSelect
	var _ /* uSrc at bp+68 */ struct {
		FfromSpace   [0][56]Tu8
		FsSrc        TSrcList
		F__ccgo_pad2 [48]byte
	}
	_, _, _, _, _, _, _, _, _, _, _ = db, i, nCol, pCol, pFrom, pNew, pReturning, reg, v, v1, v2
	v = (*TParse)(unsafe.Pointer(pParse)).FpVdbe
	db = (*TParse)(unsafe.Pointer(pParse)).Fdb
	if !(int32(Tbft(*(*uint16)(unsafe.Pointer(pParse + 28))&0x8>>3)) != 0) {
		/* This RETURNING trigger must be for a different statement as
		 ** this statement lacks a RETURNING clause. */
		return
	}
	pReturning = (*(*struct {
		FpReturning uintptr
	})(unsafe.Pointer(&(*TParse)(unsafe.Pointer(pParse)).Fu1))).FpReturning
	if pTrigger != pReturning+8 {
		/* This RETURNING trigger is for a different statement */
		return
	}
	libc.Xmemset(tls, bp, 0, uint32(68))
	libc.Xmemset(tls, bp+68, 0, uint32(56))
	pFrom = bp + 68
	(**(**TSelect)(__ccgo_up(bp))).FpEList = _sqlite3ExprListDup(tls, db, (*TReturning)(unsafe.Pointer(pReturning)).FpReturnEL, 0)
	(**(**TSelect)(__ccgo_up(bp))).FpSrc = pFrom
	(*TSrcList)(unsafe.Pointer(pFrom)).FnSrc = int32(1)
	(*(*TSrcItem)(unsafe.Pointer(pFrom + 8))).FpSTab = pTab
	(*(*TSrcItem)(unsafe.Pointer(pFrom + 8))).FzName = (*TTable)(unsafe.Pointer(pTab)).FzName /* tag-20240424-1 */
	(*(*TSrcItem)(unsafe.Pointer(pFrom + 8))).FiCursor = -int32(1)
	_sqlite3SelectPrep(tls, pParse, bp, uintptr(0))
	if (*TParse)(unsafe.Pointer(pParse)).FnErr == 0 {
		_sqlite3GenerateColumnNames(tls, pParse, bp)
	}
	_sqlite3ExprListDelete(tls, db, (**(**TSelect)(__ccgo_up(bp))).FpEList)
	pNew = _sqlite3ExpandReturning(tls, pParse, (*TReturning)(unsafe.Pointer(pReturning)).FpReturnEL, pTab)
	if (*TParse)(unsafe.Pointer(pParse)).FnErr == 0 {
		libc.Xmemset(tls, bp+124, 0, uint32(36))
		if (*TReturning)(unsafe.Pointer(pReturning)).FnRetCol == 0 {
			(*TReturning)(unsafe.Pointer(pReturning)).FnRetCol = (*TExprList)(unsafe.Pointer(pNew)).FnExpr
			v2 = pParse + 44
			v1 = *(*int32)(unsafe.Pointer(v2))
			*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1
			(*TReturning)(unsafe.Pointer(pReturning)).FiRetCur = v1
		}
		(**(**TNameContext)(__ccgo_up(bp + 124))).FpParse = pParse
		*(*int32)(unsafe.Pointer(bp + 124 + 8)) = regIn
		(**(**TNameContext)(__ccgo_up(bp + 124))).FncFlags = int32(NC_UBaseReg)
		(*TParse)(unsafe.Pointer(pParse)).FeTriggerOp = (*TTrigger)(unsafe.Pointer(pTrigger)).Fop
		(*TParse)(unsafe.Pointer(pParse)).FpTriggerTab = pTab
		if _sqlite3ResolveExprListNames(tls, bp+124, pNew) == SQLITE_OK && !((*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0) {
			nCol = (*TExprList)(unsafe.Pointer(pNew)).FnExpr
			reg = (*TParse)(unsafe.Pointer(pParse)).FnMem + int32(1)
			_sqlite3ProcessReturningSubqueries(tls, pNew, pTab)
			**(**int32)(__ccgo_up(pParse + 48)) += nCol + int32(2)
			(*TReturning)(unsafe.Pointer(pReturning)).FiRetReg = reg
			i = 0
			for {
				if !(i < nCol) {
					break
				}
				pCol = (*(*TExprList_item)(unsafe.Pointer(pNew + 8 + uintptr(i)*20))).FpExpr
				/* Due to !db->mallocFailed ~9 lines above */
				_sqlite3ExprCodeFactorable(tls, pParse, pCol, reg+i)
				if int32(_sqlite3ExprAffinity(tls, pCol)) == int32(SQLITE_AFF_REAL) {
					_sqlite3VdbeAddOp1(tls, v, int32(OP_RealAffinity), reg+i)
				}
				goto _3
			_3:
				;
				i = i + 1
			}
			_sqlite3VdbeAddOp3(tls, v, int32(OP_MakeRecord), reg, i, reg+i)
			_sqlite3VdbeAddOp2(tls, v, int32(OP_NewRowid), (*TReturning)(unsafe.Pointer(pReturning)).FiRetCur, reg+i+int32(1))
			_sqlite3VdbeAddOp3(tls, v, int32(OP_Insert), (*TReturning)(unsafe.Pointer(pReturning)).FiRetCur, reg+i, reg+i+int32(1))
		}
	}
	_sqlite3ExprListDelete(tls, db, pNew)
	(*TParse)(unsafe.Pointer(pParse)).FeTriggerOp = uint8(0)
	(*TParse)(unsafe.Pointer(pParse)).FpTriggerTab = uintptr(0)
}

// C documentation
//
//	/*
//	** Convert the N-th element of pStmt->pColName[] into a string using
//	** xFunc() then return that string.  If N is out of range, return 0.
//	**
//	** There are up to 5 names for each column.  useType determines which
//	** name is returned.  Here are the names:
//	**
//	**    0      The column name as it should be displayed for output
//	**    1      The datatype name for the column
//	**    2      The name of the database that the column derives from
//	**    3      The name of the table that the column derives from
//	**    4      The name of the table column that the result column derives from
//	**
//	** If the result is not a simple column reference (if it is an expression
//	** or a constant) then useTypes 2, 3, and 4 return NULL.
//	*/
func _columnName(tls *libc.TLS, pStmt uintptr, N int32, useUtf16 int32, useType int32) (r uintptr) {
	var db, p, ret uintptr
	var i, n, v1 int32
	var prior_mallocFailed Tu8
	_, _, _, _, _, _, _ = db, i, n, p, prior_mallocFailed, ret, v1
	if N < 0 {
		return uintptr(0)
	}
	ret = uintptr(0)
	p = pStmt
	db = (*TVdbe)(unsafe.Pointer(p)).Fdb
	Xsqlite3_mutex_enter(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
	if int32(Tbft(*(*uint16)(unsafe.Pointer(p + 144))&0xc>>2)) != 0 {
		if useType > 0 {
			goto columnName_end
		}
		if int32(Tbft(*(*uint16)(unsafe.Pointer(p + 144))&0xc>>2)) == int32(1) {
			v1 = int32(8)
		} else {
			v1 = int32(4)
		}
		n = v1
		if N >= n {
			goto columnName_end
		}
		if useUtf16 != 0 {
			i = libc.Int32FromUint8(_iExplainColNames16[N+int32(8)*int32(Tbft(*(*uint16)(unsafe.Pointer(p + 144))&0xc>>2))-int32(8)])
			ret = uintptr(unsafe.Pointer(&_azExplainColNames16data)) + uintptr(i)*2
		} else {
			ret = _azExplainColNames8[N+int32(8)*int32(Tbft(*(*uint16)(unsafe.Pointer(p + 144))&0xc>>2))-int32(8)]
		}
		goto columnName_end
	}
	n = libc.Int32FromUint16((*TVdbe)(unsafe.Pointer(p)).FnResColumn)
	if N < n {
		prior_mallocFailed = (*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed
		N = N + useType*n
		if useUtf16 != 0 {
			ret = Xsqlite3_value_text16(tls, (*TVdbe)(unsafe.Pointer(p)).FaColName+uintptr(N)*40)
		} else {
			ret = Xsqlite3_value_text(tls, (*TVdbe)(unsafe.Pointer(p)).FaColName+uintptr(N)*40)
		}
		/* A malloc may have failed inside of the _text() call. If this
		 ** is the case, clear the mallocFailed flag and return NULL.
		 */
		if libc.Int32FromUint8((*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed) > libc.Int32FromUint8(prior_mallocFailed) {
			_sqlite3OomClear(tls, db)
			ret = uintptr(0)
		}
	}
	goto columnName_end
columnName_end:
	;
	Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
	return ret
}

// C documentation
//
//	/*
//	** Return a pointer to the column affinity string associated with index
//	** pIdx. A column affinity string has one character for each column in
//	** the table, according to the affinity of the column:
//	**
//	**  Character      Column affinity
//	**  ------------------------------
//	**  'A'            BLOB
//	**  'B'            TEXT
//	**  'C'            NUMERIC
//	**  'D'            INTEGER
//	**  'F'            REAL
//	**
//	** An extra 'D' is appended to the end of the string to cover the
//	** rowid that appears as the last column in every index.
//	**
//	** Memory for the buffer containing the column index affinity string
//	** is managed along with the rest of the Index structure. It will be
//	** released when sqlite3DeleteIndex() is called.
//	*/
func _computeIndexAffStr(tls *libc.TLS, db uintptr, pIdx uintptr) (r uintptr) {
	var aff int8
	var n int32
	var pTab uintptr
	var x Ti16
	_, _, _, _ = aff, n, pTab, x
	pTab = (*TIndex)(unsafe.Pointer(pIdx)).FpTable
	(*TIndex)(unsafe.Pointer(pIdx)).FzColAff = _sqlite3DbMallocRaw(tls, uintptr(0), libc.Uint64FromInt32(libc.Int32FromUint16((*TIndex)(unsafe.Pointer(pIdx)).FnColumn)+int32(1)))
	if !((*TIndex)(unsafe.Pointer(pIdx)).FzColAff != 0) {
		_sqlite3OomFault(tls, db)
		return uintptr(0)
	}
	n = 0
	for {
		if !(n < libc.Int32FromUint16((*TIndex)(unsafe.Pointer(pIdx)).FnColumn)) {
			break
		}
		x = **(**Ti16)(__ccgo_up((*TIndex)(unsafe.Pointer(pIdx)).FaiColumn + uintptr(n)*2))
		if int32(x) >= 0 {
			aff = (**(**TColumn)(__ccgo_up((*TTable)(unsafe.Pointer(pTab)).FaCol + uintptr(x)*12))).Faffinity
		} else {
			if int32(x) == -int32(1) {
				aff = int8(SQLITE_AFF_INTEGER)
			} else {
				aff = _sqlite3ExprAffinity(tls, (*(*TExprList_item)(unsafe.Pointer((*TIndex)(unsafe.Pointer(pIdx)).FaColExpr + 8 + uintptr(n)*20))).FpExpr)
			}
		}
		if int32(aff) < int32(SQLITE_AFF_BLOB) {
			aff = int8(SQLITE_AFF_BLOB)
		}
		if int32(aff) > int32(SQLITE_AFF_NUMERIC) {
			aff = int8(SQLITE_AFF_NUMERIC)
		}
		**(**int8)(__ccgo_up((*TIndex)(unsafe.Pointer(pIdx)).FzColAff + uintptr(n))) = aff
		goto _1
	_1:
		;
		n = n + 1
	}
	**(**int8)(__ccgo_up((*TIndex)(unsafe.Pointer(pIdx)).FzColAff + uintptr(n))) = 0
	return (*TIndex)(unsafe.Pointer(pIdx)).FzColAff
}

// C documentation
//
//	/* The core implementation of the CONCAT(...) and CONCAT_WS(SEP,...)
//	** functions.
//	**
//	** Return a string value that is the concatenation of all non-null
//	** entries in argv[].  Use zSep as the separator.
//	*/
func _concatFuncCore(tls *libc.TLS, context uintptr, argc int32, argv uintptr, nSep int32, zSep uintptr) {
	var bNotNull, i, k int32
	var j, n Ti64
	var v, z uintptr
	_, _, _, _, _, _, _ = bNotNull, i, j, k, n, v, z
	n = 0
	bNotNull = 0
	i = 0
	for {
		if !(i < argc) {
			break
		}
		n = n + int64(Xsqlite3_value_bytes(tls, **(**uintptr)(__ccgo_up(argv + uintptr(i)*4))))
		goto _1
	_1:
		;
		i = i + 1
	}
	n = n + int64(argc-libc.Int32FromInt32(1))*int64(nSep)
	z = Xsqlite3_malloc64(tls, libc.Uint64FromInt64(n+int64(1)))
	if z == uintptr(0) {
		Xsqlite3_result_error_nomem(tls, context)
		return
	}
	j = 0
	i = 0
	for {
		if !(i < argc) {
			break
		}
		if Xsqlite3_value_type(tls, **(**uintptr)(__ccgo_up(argv + uintptr(i)*4))) != int32(SQLITE_NULL) {
			k = Xsqlite3_value_bytes(tls, **(**uintptr)(__ccgo_up(argv + uintptr(i)*4)))
			v = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv + uintptr(i)*4)))
			if v != uintptr(0) {
				if bNotNull != 0 && nSep > 0 {
					libc.Xmemcpy(tls, z+uintptr(j), zSep, libc.Uint32FromInt32(nSep))
					j = j + int64(nSep)
				}
				libc.Xmemcpy(tls, z+uintptr(j), v, libc.Uint32FromInt32(k))
				j = j + int64(k)
				bNotNull = int32(1)
			}
		}
		goto _2
	_2:
		;
		i = i + 1
	}
	**(**int8)(__ccgo_up(z + uintptr(j))) = 0
	Xsqlite3_result_text64(tls, context, z, libc.Uint64FromInt64(j), __ccgo_fp(Xsqlite3_free), uint8(SQLITE_UTF8_ZT))
}

// C documentation
//
//	/*
//	** Add a new entry to the pConst object.  Except, do not add duplicate
//	** pColumn entries.  Also, do not add if doing so would not be appropriate.
//	**
//	** The caller guarantees the pColumn is a column and pValue is a constant.
//	** This routine has to do some additional checks before completing the
//	** insert.
//	*/
func _constInsert(tls *libc.TLS, pConst uintptr, pColumn uintptr, pValue uintptr, pExpr uintptr) {
	var i int32
	var pE2 uintptr
	_, _ = i, pE2
	if (*TExpr)(unsafe.Pointer(pColumn)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_FixedCol)) != uint32(0) {
		return
	}
	if int32(_sqlite3ExprAffinity(tls, pValue)) != 0 {
		return
	}
	if !(_sqlite3IsBinary(tls, _sqlite3ExprCompareCollSeq(tls, (*TWhereConst)(unsafe.Pointer(pConst)).FpParse, pExpr)) != 0) {
		return
	}
	/* 2018-10-25 ticket [cf5ed20f]
	 ** Make sure the same pColumn is not inserted more than once */
	i = 0
	for {
		if !(i < (*TWhereConst)(unsafe.Pointer(pConst)).FnConst) {
			break
		}
		pE2 = **(**uintptr)(__ccgo_up((*TWhereConst)(unsafe.Pointer(pConst)).FapExpr + uintptr(i*int32(2))*4))
		if (*TExpr)(unsafe.Pointer(pE2)).FiTable == (*TExpr)(unsafe.Pointer(pColumn)).FiTable && int32((*TExpr)(unsafe.Pointer(pE2)).FiColumn) == int32((*TExpr)(unsafe.Pointer(pColumn)).FiColumn) {
			return /* Already present.  Return without doing anything. */
		}
		goto _1
	_1:
		;
		i = i + 1
	}
	if int32(_sqlite3ExprAffinity(tls, pColumn)) <= int32(SQLITE_AFF_BLOB) {
		(*TWhereConst)(unsafe.Pointer(pConst)).FbHasAffBlob = int32(1)
	}
	(*TWhereConst)(unsafe.Pointer(pConst)).FnConst = (*TWhereConst)(unsafe.Pointer(pConst)).FnConst + 1
	(*TWhereConst)(unsafe.Pointer(pConst)).FapExpr = _sqlite3DbReallocOrFree(tls, (*TParse)(unsafe.Pointer((*TWhereConst)(unsafe.Pointer(pConst)).FpParse)).Fdb, (*TWhereConst)(unsafe.Pointer(pConst)).FapExpr, uint64(libc.Uint32FromInt32((*TWhereConst)(unsafe.Pointer(pConst)).FnConst*int32(2))*uint32(4)))
	if (*TWhereConst)(unsafe.Pointer(pConst)).FapExpr == uintptr(0) {
		(*TWhereConst)(unsafe.Pointer(pConst)).FnConst = 0
	} else {
		**(**uintptr)(__ccgo_up((*TWhereConst)(unsafe.Pointer(pConst)).FapExpr + uintptr((*TWhereConst)(unsafe.Pointer(pConst)).FnConst*int32(2)-int32(2))*4)) = pColumn
		**(**uintptr)(__ccgo_up((*TWhereConst)(unsafe.Pointer(pConst)).FapExpr + uintptr((*TWhereConst)(unsafe.Pointer(pConst)).FnConst*int32(2)-int32(1))*4)) = pValue
	}
}

// C documentation
//
//	/*
//	** Allocate nByte bytes of space using sqlite3Malloc(). If the
//	** allocation fails, call sqlite3_result_error_nomem() to notify
//	** the database handle that malloc() has failed and return NULL.
//	** If nByte is larger than the maximum string or blob length, then
//	** raise an SQLITE_TOOBIG exception and return NULL.
//	*/
func _contextMalloc(tls *libc.TLS, context uintptr, nByte Ti64) (r uintptr) {
	var db, z uintptr
	_, _ = db, z
	db = Xsqlite3_context_db_handle(tls, context)
	if nByte > int64(**(**int32)(__ccgo_up(db + 116))) {
		Xsqlite3_result_error_toobig(tls, context)
		z = uintptr(0)
	} else {
		z = _sqlite3Malloc(tls, libc.Uint64FromInt64(nByte))
		if !(z != 0) {
			Xsqlite3_result_error_nomem(tls, context)
		}
	}
	return z
}

// C documentation
//
//	/*
//	** This routine runs at the end of parsing a CREATE TABLE statement that
//	** has a WITHOUT ROWID clause.  The job of this routine is to convert both
//	** internal schema data structures and the generated VDBE code so that they
//	** are appropriate for a WITHOUT ROWID table instead of a rowid table.
//	** Changes include:
//	**
//	**     (1)  Set all columns of the PRIMARY KEY schema object to be NOT NULL.
//	**     (2)  Convert P3 parameter of the OP_CreateBtree from BTREE_INTKEY
//	**          into BTREE_BLOBKEY.
//	**     (3)  Bypass the creation of the sqlite_schema table entry
//	**          for the PRIMARY KEY as the primary key index is now
//	**          identified by the sqlite_schema table entry of the table itself.
//	**     (4)  Set the Index.tnum of the PRIMARY KEY Index object in the
//	**          schema to the rootpage from the main table.
//	**     (5)  Add all table columns to the PRIMARY KEY Index object
//	**          so that the PRIMARY KEY is a covering index.  The surplus
//	**          columns are part of KeyInfo.nAllField and are not used for
//	**          sorting or lookup or uniqueness checks.
//	**     (6)  Replace the rowid tail on all automatically generated UNIQUE
//	**          indices with the PRIMARY KEY columns.
//	**
//	** For virtual tables, only (1) is performed.
//	*/
func _convertToWithoutRowidTable(tls *libc.TLS, pParse uintptr, pTab uintptr) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var db, pIdx, pList, pPk, v, zColl, v12 uintptr
	var i, j, n, nExtra, nPk, v3 int32
	var v5 Tu16
	var _ /* ipkToken at bp+0 */ TToken
	_, _, _, _, _, _, _, _, _, _, _, _, _, _ = db, i, j, n, nExtra, nPk, pIdx, pList, pPk, v, zColl, v12, v3, v5
	db = (*TParse)(unsafe.Pointer(pParse)).Fdb
	v = (*TParse)(unsafe.Pointer(pParse)).FpVdbe
	/* Mark every PRIMARY KEY column as NOT NULL (except for imposter tables)
	 */
	if !(int32(uint32(*(*uint8)(unsafe.Pointer(db + 172 + 8))&0x6>>1)) != 0) {
		i = 0
		for {
			if !(i < int32((*TTable)(unsafe.Pointer(pTab)).FnCol)) {
				break
			}
			if libc.Int32FromUint16((**(**TColumn)(__ccgo_up((*TTable)(unsafe.Pointer(pTab)).FaCol + uintptr(i)*12))).FcolFlags)&int32(COLFLAG_PRIMKEY) != 0 && int32(uint32(*(*uint8)(unsafe.Pointer((*TTable)(unsafe.Pointer(pTab)).FaCol + uintptr(i)*12 + 4))&0xf>>0)) == OE_None {
				libc.SetBitFieldPtr8Uint32((*TTable)(unsafe.Pointer(pTab)).FaCol+uintptr(i)*12+4, libc.Uint32FromInt32(OE_Abort), 0, 0xf)
			}
			goto _1
		_1:
			;
			i = i + 1
		}
		**(**Tu32)(__ccgo_up(pTab + 28)) |= uint32(TF_HasNotNull)
	}
	/* Convert the P3 operand of the OP_CreateBtree opcode from BTREE_INTKEY
	 ** into BTREE_BLOBKEY.
	 */
	if (*(*struct {
		FaddrCrTab      int32
		FregRowid       int32
		FregRoot        int32
		FconstraintName TToken
	})(unsafe.Pointer(pParse + 184))).FaddrCrTab != 0 {
		_sqlite3VdbeChangeP3(tls, v, (*(*struct {
			FaddrCrTab      int32
			FregRowid       int32
			FregRoot        int32
			FconstraintName TToken
		})(unsafe.Pointer(pParse + 184))).FaddrCrTab, int32(BTREE_BLOBKEY))
	}
	/* Locate the PRIMARY KEY index.  Or, if this table was originally
	 ** an INTEGER PRIMARY KEY table, create a new PRIMARY KEY index.
	 */
	if int32((*TTable)(unsafe.Pointer(pTab)).FiPKey) >= 0 {
		_sqlite3TokenInit(tls, bp, (**(**TColumn)(__ccgo_up((*TTable)(unsafe.Pointer(pTab)).FaCol + uintptr((*TTable)(unsafe.Pointer(pTab)).FiPKey)*12))).FzCnName)
		pList = _sqlite3ExprListAppend(tls, pParse, uintptr(0), _sqlite3ExprAlloc(tls, db, int32(TK_ID), bp, 0))
		if pList == uintptr(0) {
			**(**Tu32)(__ccgo_up(pTab + 28)) &= libc.Uint32FromInt32(^libc.Int32FromInt32(TF_WithoutRowid))
			return
		}
		if libc.Int32FromUint8((*TParse)(unsafe.Pointer(pParse)).FeParseMode) >= int32(PARSE_MODE_RENAME) {
			_sqlite3RenameTokenRemap(tls, pParse, (*(*TExprList_item)(unsafe.Pointer(pList + 8))).FpExpr, pTab+32)
		}
		(*(*TExprList_item)(unsafe.Pointer(pList + 8))).Ffg.FsortFlags = (*TParse)(unsafe.Pointer(pParse)).FiPkSortOrder
		(*TTable)(unsafe.Pointer(pTab)).FiPKey = int16(-int32(1))
		_sqlite3CreateIndex(tls, pParse, uintptr(0), uintptr(0), uintptr(0), pList, libc.Int32FromUint8((*TTable)(unsafe.Pointer(pTab)).FkeyConf), uintptr(0), uintptr(0), 0, 0, uint8(SQLITE_IDXTYPE_PRIMARYKEY))
		if (*TParse)(unsafe.Pointer(pParse)).FnErr != 0 {
			**(**Tu32)(__ccgo_up(pTab + 28)) &= libc.Uint32FromInt32(^libc.Int32FromInt32(TF_WithoutRowid))
			return
		}
		pPk = _sqlite3PrimaryKeyIndex(tls, pTab)
	} else {
		pPk = _sqlite3PrimaryKeyIndex(tls, pTab)
		/*
		 ** Remove all redundant columns from the PRIMARY KEY.  For example, change
		 ** "PRIMARY KEY(a,b,a,b,c,b,c,d)" into just "PRIMARY KEY(a,b,c,d)".  Later
		 ** code assumes the PRIMARY KEY contains no repeated columns.
		 */
		v3 = libc.Int32FromInt32(1)
		j = v3
		i = v3
		for {
			if !(i < libc.Int32FromUint16((*TIndex)(unsafe.Pointer(pPk)).FnKeyCol)) {
				break
			}
			if _isDupColumn(tls, pPk, j, pPk, i) != 0 {
				(*TIndex)(unsafe.Pointer(pPk)).FnColumn = (*TIndex)(unsafe.Pointer(pPk)).FnColumn - 1
			} else {
				**(**uintptr)(__ccgo_up((*TIndex)(unsafe.Pointer(pPk)).FazColl + uintptr(j)*4)) = **(**uintptr)(__ccgo_up((*TIndex)(unsafe.Pointer(pPk)).FazColl + uintptr(i)*4))
				**(**Tu8)(__ccgo_up((*TIndex)(unsafe.Pointer(pPk)).FaSortOrder + uintptr(j))) = **(**Tu8)(__ccgo_up((*TIndex)(unsafe.Pointer(pPk)).FaSortOrder + uintptr(i)))
				v3 = j
				j = j + 1
				**(**Ti16)(__ccgo_up((*TIndex)(unsafe.Pointer(pPk)).FaiColumn + uintptr(v3)*2)) = **(**Ti16)(__ccgo_up((*TIndex)(unsafe.Pointer(pPk)).FaiColumn + uintptr(i)*2))
			}
			goto _2
		_2:
			;
			i = i + 1
		}
		(*TIndex)(unsafe.Pointer(pPk)).FnKeyCol = libc.Uint16FromInt32(j)
	}
	libc.SetBitFieldPtr16Uint32(pPk+56, libc.Uint32FromInt32(1), 5, 0x20)
	if !(int32(uint32(*(*uint8)(unsafe.Pointer(db + 172 + 8))&0x6>>1)) != 0) {
		libc.SetBitFieldPtr16Uint32(pPk+56, libc.Uint32FromInt32(1), 3, 0x8)
	}
	v5 = (*TIndex)(unsafe.Pointer(pPk)).FnKeyCol
	(*TIndex)(unsafe.Pointer(pPk)).FnColumn = v5
	nPk = libc.Int32FromUint16(v5)
	/* Bypass the creation of the PRIMARY KEY btree and the sqlite_schema
	 ** table entry. This is only required if currently generating VDBE
	 ** code for a CREATE TABLE (not when parsing one as part of reading
	 ** a database schema).  */
	if v != 0 && (*TIndex)(unsafe.Pointer(pPk)).Ftnum > uint32(0) {
		_sqlite3VdbeChangeOpcode(tls, v, libc.Int32FromUint32((*TIndex)(unsafe.Pointer(pPk)).Ftnum), uint8(OP_Goto))
	}
	/* The root page of the PRIMARY KEY is the table root page */
	(*TIndex)(unsafe.Pointer(pPk)).Ftnum = (*TTable)(unsafe.Pointer(pTab)).Ftnum
	/* Update the in-memory representation of all UNIQUE indices by converting
	 ** the final rowid column into one or more columns of the PRIMARY KEY.
	 */
	pIdx = (*TTable)(unsafe.Pointer(pTab)).FpIndex
	for {
		if !(pIdx != 0) {
			break
		}
		if int32(uint32(*(*uint16)(unsafe.Pointer(pIdx + 56))&0x3>>0)) == int32(SQLITE_IDXTYPE_PRIMARYKEY) {
			goto _6
		}
		v3 = libc.Int32FromInt32(0)
		n = v3
		i = v3
		for {
			if !(i < nPk) {
				break
			}
			if !(_isDupColumn(tls, pIdx, libc.Int32FromUint16((*TIndex)(unsafe.Pointer(pIdx)).FnKeyCol), pPk, i) != 0) {
				n = n + 1
			}
			goto _7
		_7:
			;
			i = i + 1
		}
		if n == 0 {
			/* This index is a superset of the primary key */
			(*TIndex)(unsafe.Pointer(pIdx)).FnColumn = (*TIndex)(unsafe.Pointer(pIdx)).FnKeyCol
			goto _6
		}
		if _resizeIndexObject(tls, pParse, pIdx, libc.Int32FromUint16((*TIndex)(unsafe.Pointer(pIdx)).FnKeyCol)+n) != 0 {
			return
		}
		i = 0
		j = libc.Int32FromUint16((*TIndex)(unsafe.Pointer(pIdx)).FnKeyCol)
		for {
			if !(i < nPk) {
				break
			}
			if !(_isDupColumn(tls, pIdx, libc.Int32FromUint16((*TIndex)(unsafe.Pointer(pIdx)).FnKeyCol), pPk, i) != 0) {
				**(**Ti16)(__ccgo_up((*TIndex)(unsafe.Pointer(pIdx)).FaiColumn + uintptr(j)*2)) = **(**Ti16)(__ccgo_up((*TIndex)(unsafe.Pointer(pPk)).FaiColumn + uintptr(i)*2))
				**(**uintptr)(__ccgo_up((*TIndex)(unsafe.Pointer(pIdx)).FazColl + uintptr(j)*4)) = **(**uintptr)(__ccgo_up((*TIndex)(unsafe.Pointer(pPk)).FazColl + uintptr(i)*4))
				if **(**Tu8)(__ccgo_up((*TIndex)(unsafe.Pointer(pPk)).FaSortOrder + uintptr(i))) != 0 {
					/* See ticket https://sqlite.org/src/info/bba7b69f9849b5bf */
					libc.SetBitFieldPtr16Uint32(pIdx+56, libc.Uint32FromInt32(1), 9, 0x200)
				}
				j = j + 1
			}
			goto _9
		_9:
			;
			i = i + 1
		}
		goto _6
	_6:
		;
		pIdx = (*TIndex)(unsafe.Pointer(pIdx)).FpNext
	}
	/* Add all table columns to the PRIMARY KEY index
	 */
	nExtra = 0
	i = 0
	for {
		if !(i < int32((*TTable)(unsafe.Pointer(pTab)).FnCol)) {
			break
		}
		if !(_hasColumn(tls, (*TIndex)(unsafe.Pointer(pPk)).FaiColumn, nPk, i) != 0) && libc.Int32FromUint16((**(**TColumn)(__ccgo_up((*TTable)(unsafe.Pointer(pTab)).FaCol + uintptr(i)*12))).FcolFlags)&int32(COLFLAG_VIRTUAL) == 0 {
			nExtra = nExtra + 1
		}
		goto _10
	_10:
		;
		i = i + 1
	}
	if _resizeIndexObject(tls, pParse, pPk, nPk+nExtra) != 0 {
		return
	}
	i = 0
	j = nPk
	for {
		if !(i < int32((*TTable)(unsafe.Pointer(pTab)).FnCol)) {
			break
		}
		if !(_hasColumn(tls, (*TIndex)(unsafe.Pointer(pPk)).FaiColumn, j, i) != 0) && libc.Int32FromUint16((**(**TColumn)(__ccgo_up((*TTable)(unsafe.Pointer(pTab)).FaCol + uintptr(i)*12))).FcolFlags)&int32(COLFLAG_VIRTUAL) == 0 {
			zColl = _sqlite3ColumnColl(tls, (*TTable)(unsafe.Pointer(pTab)).FaCol+uintptr(i)*12)
			**(**Ti16)(__ccgo_up((*TIndex)(unsafe.Pointer(pPk)).FaiColumn + uintptr(j)*2)) = int16(i)
			if zColl != 0 {
				v12 = zColl
			} else {
				v12 = uintptr(unsafe.Pointer(&_sqlite3StrBINARY))
			}
			**(**uintptr)(__ccgo_up((*TIndex)(unsafe.Pointer(pPk)).FazColl + uintptr(j)*4)) = v12
			j = j + 1
		}
		goto _11
	_11:
		;
		i = i + 1
	}
	_recomputeColumnsNotIndexed(tls, pPk)
}

// C documentation
//
//	/*
//	** Return true (non-zero) if pCur is current pointing to the last
//	** page of a table.
//	*/
func _cursorOnLastPage(tls *libc.TLS, pCur uintptr) (r int32) {
	var i int32
	var pPage uintptr
	_, _ = i, pPage
	i = 0
	for {
		if !(i < int32((*TBtCursor)(unsafe.Pointer(pCur)).FiPage)) {
			break
		}
		pPage = **(**uintptr)(__ccgo_up(pCur + 112 + uintptr(i)*4))
		if libc.Int32FromUint16(**(**Tu16)(__ccgo_up(pCur + 64 + uintptr(i)*2))) < libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FnCell) {
			return 0
		}
		goto _1
	_1:
		;
		i = i + 1
	}
	return int32(1)
}

// C documentation
//
//	/*
//	** Disconnect all sqlite3_vtab objects that belong to database connection
//	** db. This is called when db is being closed.
//	*/
func _disconnectAllVtab(tls *libc.TLS, db uintptr) {
	var i int32
	var p, pMod, pSchema, pTab uintptr
	_, _, _, _, _ = i, p, pMod, pSchema, pTab
	_sqlite3BtreeEnterAll(tls, db)
	i = 0
	for {
		if !(i < (*Tsqlite3)(unsafe.Pointer(db)).FnDb) {
			break
		}
		pSchema = (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(i)*16))).FpSchema
		if pSchema != 0 {
			p = (*THash)(unsafe.Pointer(pSchema + 8)).Ffirst
			for {
				if !(p != 0) {
					break
				}
				pTab = (*THashElem)(unsafe.Pointer(p)).Fdata
				if libc.Int32FromUint8((*TTable)(unsafe.Pointer(pTab)).FeTabType) == int32(TABTYP_VTAB) {
					_sqlite3VtabDisconnect(tls, db, pTab)
				}
				goto _2
			_2:
				;
				p = (*THashElem)(unsafe.Pointer(p)).Fnext
			}
		}
		goto _1
	_1:
		;
		i = i + 1
	}
	p = (*THash)(unsafe.Pointer(db + 400)).Ffirst
	for {
		if !(p != 0) {
			break
		}
		pMod = (*THashElem)(unsafe.Pointer(p)).Fdata
		if (*TModule)(unsafe.Pointer(pMod)).FpEpoTab != 0 {
			_sqlite3VtabDisconnect(tls, db, (*TModule)(unsafe.Pointer(pMod)).FpEpoTab)
		}
		goto _3
	_3:
		;
		p = (*THashElem)(unsafe.Pointer(p)).Fnext
	}
	_sqlite3VtabUnlockList(tls, db)
	_sqlite3BtreeLeaveAll(tls, db)
}

// C documentation
//
//	/*
//	** Analyze a term that consists of two or more OR-connected
//	** subterms.  So in:
//	**
//	**     ... WHERE  (a=5) AND (b=7 OR c=9 OR d=13) AND (d=13)
//	**                          ^^^^^^^^^^^^^^^^^^^^
//	**
//	** This routine analyzes terms such as the middle term in the above example.
//	** A WhereOrTerm object is computed and attached to the term under
//	** analysis, regardless of the outcome of the analysis.  Hence:
//	**
//	**     WhereTerm.wtFlags   |=  TERM_ORINFO
//	**     WhereTerm.u.pOrInfo  =  a dynamically allocated WhereOrTerm object
//	**
//	** The term being analyzed must have two or more of OR-connected subterms.
//	** A single subterm might be a set of AND-connected sub-subterms.
//	** Examples of terms under analysis:
//	**
//	**     (A)     t1.x=t2.y OR t1.x=t2.z OR t1.y=15 OR t1.z=t3.a+5
//	**     (B)     x=expr1 OR expr2=x OR x=expr3
//	**     (C)     t1.x=t2.y OR (t1.x=t2.z AND t1.y=15)
//	**     (D)     x=expr1 OR (y>11 AND y<22 AND z LIKE '*hello*')
//	**     (E)     (p.a=1 AND q.b=2 AND r.c=3) OR (p.x=4 AND q.y=5 AND r.z=6)
//	**     (F)     x>A OR (x=A AND y>=B)
//	**
//	** CASE 1:
//	**
//	** If all subterms are of the form T.C=expr for some single column of C and
//	** a single table T (as shown in example B above) then create a new virtual
//	** term that is an equivalent IN expression.  In other words, if the term
//	** being analyzed is:
//	**
//	**      x = expr1  OR  expr2 = x  OR  x = expr3
//	**
//	** then create a new virtual term like this:
//	**
//	**      x IN (expr1,expr2,expr3)
//	**
//	** CASE 2:
//	**
//	** If there are exactly two disjuncts and one side has x>A and the other side
//	** has x=A (for the same x and A) then add a new virtual conjunct term to the
//	** WHERE clause of the form "x>=A".  Example:
//	**
//	**      x>A OR (x=A AND y>B)    adds:    x>=A
//	**
//	** The added conjunct can sometimes be helpful in query planning.
//	**
//	** CASE 3:
//	**
//	** If all subterms are indexable by a single table T, then set
//	**
//	**     WhereTerm.eOperator              =  WO_OR
//	**     WhereTerm.u.pOrInfo->indexable  |=  the cursor number for table T
//	**
//	** A subterm is "indexable" if it is of the form
//	** "T.C <op> <expr>" where C is any column of table T and
//	** <op> is one of "=", "<", "<=", ">", ">=", "IS NULL", or "IN".
//	** A subterm is also indexable if it is an AND of two or more
//	** subsubterms at least one of which is indexable.  Indexable AND
//	** subterms have their eOperator set to WO_AND and they have
//	** u.pAndInfo set to a dynamically allocated WhereAndTerm object.
//	**
//	** From another point of view, "indexable" means that the subterm could
//	** potentially be used with an index if an appropriate index exists.
//	** This analysis does not consider whether or not the index exists; that
//	** is decided elsewhere.  This analysis only looks at whether subterms
//	** appropriate for indexing exist.
//	**
//	** All examples A through E above satisfy case 3.  But if a term
//	** also satisfies case 1 (such as B) we know that the optimizer will
//	** always prefer case 1, so in that case we pretend that case 3 is not
//	** satisfied.
//	**
//	** It might be the case that multiple tables are indexable.  For example,
//	** (E) above is indexable on tables P, Q, and R.
//	**
//	** Terms that satisfy case 3 are candidates for lookup by using
//	** separate indices to find rowids for each subterm and composing
//	** the union of all rowids using a RowSet object.  This is similar
//	** to "bitmap indices" in other database engines.
//	**
//	** OTHERWISE:
//	**
//	** If none of cases 1, 2, or 3 apply, then leave the eOperator set to
//	** zero.  This term is not useful for search.
//	*/
func _exprAnalyzeOrTerm(tls *libc.TLS, pSrc uintptr, pWC uintptr, idxTerm int32) {
	var affLeft, affRight, i, iColumn, iCursor, iOne, iTwo, idxNew, j, j1, okToChngToIN, v7, v9 int32
	var b, b1, chngToIN, indexable TBitmask
	var db, pAndInfo, pAndTerm, pAndWC, pDup, pExpr, pLeft, pLeft1, pList, pNew, pOne, pOrInfo, pOrTerm, pOrWc, pOther, pParse, pTerm, pTwo, pWInfo, v1, v2 uintptr
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = affLeft, affRight, b, b1, chngToIN, db, i, iColumn, iCursor, iOne, iTwo, idxNew, indexable, j, j1, okToChngToIN, pAndInfo, pAndTerm, pAndWC, pDup, pExpr, pLeft, pLeft1, pList, pNew, pOne, pOrInfo, pOrTerm, pOrWc, pOther, pParse, pTerm, pTwo, pWInfo, v1, v2, v7, v9
	pWInfo = (*TWhereClause)(unsafe.Pointer(pWC)).FpWInfo                 /* WHERE clause processing context */
	pParse = (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpParse                /* Parser context */
	db = (*TParse)(unsafe.Pointer(pParse)).Fdb                            /* Database connection */
	pTerm = (*TWhereClause)(unsafe.Pointer(pWC)).Fa + uintptr(idxTerm)*48 /* The term to be analyzed */
	pExpr = (*TWhereTerm)(unsafe.Pointer(pTerm)).FpExpr                   /* Tables that are indexable, satisfying case 2 */
	/*
	 ** Break the OR clause into its separate subterms.  The subterms are
	 ** stored in a WhereClause structure containing within the WhereOrInfo
	 ** object that is attached to the original OR clause term.
	 */
	v1 = _sqlite3DbMallocZero(tls, db, uint64(420))
	pOrInfo = v1
	*(*uintptr)(unsafe.Pointer(&(*TWhereTerm)(unsafe.Pointer(pTerm)).Fu)) = v1
	if pOrInfo == uintptr(0) {
		return
	}
	v1 = pTerm + 10
	*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) | libc.Int32FromInt32(TERM_ORINFO))
	pOrWc = pOrInfo
	libc.Xmemset(tls, pOrWc+28, 0, uint32(384))
	_sqlite3WhereClauseInit(tls, pOrWc, pWInfo)
	_sqlite3WhereSplit(tls, pOrWc, pExpr, uint8(TK_OR))
	_sqlite3WhereExprAnalyze(tls, pSrc, pOrWc)
	if (*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0 {
		return
	}
	/*
	 ** Compute the set of tables that might satisfy cases 1 or 3.
	 */
	indexable = ^libc.Uint64FromInt32(0)
	chngToIN = ^libc.Uint64FromInt32(0)
	i = (*TWhereClause)(unsafe.Pointer(pOrWc)).FnTerm - int32(1)
	pOrTerm = (*TWhereClause)(unsafe.Pointer(pOrWc)).Fa
	for {
		if !(i >= 0 && indexable != 0) {
			break
		}
		if libc.Int32FromUint16((*TWhereTerm)(unsafe.Pointer(pOrTerm)).FeOperator)&int32(WO_SINGLE) == 0 {
			chngToIN = uint64(0)
			pAndInfo = _sqlite3DbMallocRawNN(tls, db, uint64(412))
			if pAndInfo != 0 {
				b = uint64(0)
				*(*uintptr)(unsafe.Pointer(&(*TWhereTerm)(unsafe.Pointer(pOrTerm)).Fu)) = pAndInfo
				v1 = pOrTerm + 10
				*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) | libc.Int32FromInt32(TERM_ANDINFO))
				(*TWhereTerm)(unsafe.Pointer(pOrTerm)).FeOperator = uint16(WO_AND)
				(*TWhereTerm)(unsafe.Pointer(pOrTerm)).FleftCursor = -int32(1)
				pAndWC = pAndInfo
				libc.Xmemset(tls, pAndWC+28, 0, uint32(384))
				_sqlite3WhereClauseInit(tls, pAndWC, (*TWhereClause)(unsafe.Pointer(pWC)).FpWInfo)
				_sqlite3WhereSplit(tls, pAndWC, (*TWhereTerm)(unsafe.Pointer(pOrTerm)).FpExpr, uint8(TK_AND))
				_sqlite3WhereExprAnalyze(tls, pSrc, pAndWC)
				(*TWhereClause)(unsafe.Pointer(pAndWC)).FpOuter = pWC
				if !((*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0) {
					j = 0
					pAndTerm = (*TWhereClause)(unsafe.Pointer(pAndWC)).Fa
					for {
						if !(j < (*TWhereClause)(unsafe.Pointer(pAndWC)).FnTerm) {
							break
						}
						if _allowedOp(tls, libc.Int32FromUint8((*TExpr)(unsafe.Pointer((*TWhereTerm)(unsafe.Pointer(pAndTerm)).FpExpr)).Fop)) != 0 || libc.Int32FromUint16((*TWhereTerm)(unsafe.Pointer(pAndTerm)).FeOperator) == int32(WO_AUX) {
							b = b | _sqlite3WhereGetMask(tls, pWInfo+488, (*TWhereTerm)(unsafe.Pointer(pAndTerm)).FleftCursor)
						}
						goto _5
					_5:
						;
						j = j + 1
						pAndTerm += 48
					}
				}
				indexable = indexable & b
			}
		} else {
			if libc.Int32FromUint16((*TWhereTerm)(unsafe.Pointer(pOrTerm)).FwtFlags)&int32(TERM_COPIED) != 0 {
				/* Skip this term for now.  We revisit it when we process the
				 ** corresponding TERM_VIRTUAL term */
			} else {
				b1 = _sqlite3WhereGetMask(tls, pWInfo+488, (*TWhereTerm)(unsafe.Pointer(pOrTerm)).FleftCursor)
				if libc.Int32FromUint16((*TWhereTerm)(unsafe.Pointer(pOrTerm)).FwtFlags)&int32(TERM_VIRTUAL) != 0 {
					pOther = (*TWhereClause)(unsafe.Pointer(pOrWc)).Fa + uintptr((*TWhereTerm)(unsafe.Pointer(pOrTerm)).FiParent)*48
					b1 = b1 | _sqlite3WhereGetMask(tls, pWInfo+488, (*TWhereTerm)(unsafe.Pointer(pOther)).FleftCursor)
				}
				indexable = indexable & b1
				if libc.Int32FromUint16((*TWhereTerm)(unsafe.Pointer(pOrTerm)).FeOperator)&int32(WO_EQ) == 0 {
					chngToIN = uint64(0)
				} else {
					chngToIN = chngToIN & b1
				}
			}
		}
		goto _3
	_3:
		;
		i = i - 1
		pOrTerm += 48
	}
	/*
	 ** Record the set of tables that satisfy case 3.  The set might be
	 ** empty.
	 */
	(*TWhereOrInfo)(unsafe.Pointer(pOrInfo)).Findexable = indexable
	(*TWhereTerm)(unsafe.Pointer(pTerm)).FeOperator = uint16(WO_OR)
	(*TWhereTerm)(unsafe.Pointer(pTerm)).FleftCursor = -int32(1)
	if indexable != 0 {
		(*TWhereClause)(unsafe.Pointer(pWC)).FhasOr = uint8(1)
	}
	/* For a two-way OR, attempt to implementation case 2.
	 */
	if indexable != 0 && (*TWhereClause)(unsafe.Pointer(pOrWc)).FnTerm == int32(2) {
		iOne = 0
		for {
			v7 = iOne
			iOne = iOne + 1
			v1 = _whereNthSubterm(tls, (*TWhereClause)(unsafe.Pointer(pOrWc)).Fa, v7)
			pOne = v1
			if !(v1 != uintptr(0)) {
				break
			}
			iTwo = 0
			for {
				v9 = iTwo
				iTwo = iTwo + 1
				v2 = _whereNthSubterm(tls, (*TWhereClause)(unsafe.Pointer(pOrWc)).Fa+1*48, v9)
				pTwo = v2
				if !(v2 != uintptr(0)) {
					break
				}
				_whereCombineDisjuncts(tls, pSrc, pWC, pOne, pTwo)
			}
		}
	}
	/*
	 ** chngToIN holds a set of tables that *might* satisfy case 1.  But
	 ** we have to do some additional checking to see if case 1 really
	 ** is satisfied.
	 **
	 ** chngToIN will hold either 0, 1, or 2 bits.  The 0-bit case means
	 ** that there is no possibility of transforming the OR clause into an
	 ** IN operator because one or more terms in the OR clause contain
	 ** something other than == on a column in the single table.  The 1-bit
	 ** case means that every term of the OR clause is of the form
	 ** "table.column=expr" for some single table.  The one bit that is set
	 ** will correspond to the common table.  We still need to check to make
	 ** sure the same column is used on all terms.  The 2-bit case is when
	 ** the all terms are of the form "table1.column=table2.column".  It
	 ** might be possible to form an IN operator with either table1.column
	 ** or table2.column as the LHS if either is common to every term of
	 ** the OR clause.
	 **
	 ** Note that terms of the form "table.column1=table.column2" (the
	 ** same table on both sizes of the ==) cannot be optimized.
	 */
	if chngToIN != 0 {
		okToChngToIN = 0    /* True if the conversion to IN is valid */
		iColumn = -int32(1) /* Column index on lhs of IN operator */
		iCursor = -int32(1) /* Table cursor common to all terms */
		j1 = 0              /* Loop counter */
		/* Search for a table and column that appears on one side or the
		 ** other of the == operator in every subterm.  That table and column
		 ** will be recorded in iCursor and iColumn.  There might not be any
		 ** such table and column.  Set okToChngToIN if an appropriate table
		 ** and column is found but leave okToChngToIN false if not found.
		 */
		j1 = 0
		for {
			if !(j1 < int32(2) && !(okToChngToIN != 0)) {
				break
			}
			pLeft = uintptr(0)
			pOrTerm = (*TWhereClause)(unsafe.Pointer(pOrWc)).Fa
			i = (*TWhereClause)(unsafe.Pointer(pOrWc)).FnTerm - int32(1)
			for {
				if !(i >= 0) {
					break
				}
				v1 = pOrTerm + 10
				*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) & ^libc.Int32FromInt32(TERM_OK))
				if (*TWhereTerm)(unsafe.Pointer(pOrTerm)).FleftCursor == iCursor {
					/* This is the 2-bit case and we are on the second iteration and
					 ** current term is from the first iteration.  So skip this term. */
					goto _11
				}
				if chngToIN&_sqlite3WhereGetMask(tls, pWInfo+488, (*TWhereTerm)(unsafe.Pointer(pOrTerm)).FleftCursor) == uint64(0) {
					/* This term must be of the form t1.a==t2.b where t2 is in the
					 ** chngToIN set but t1 is not.  This term will be either preceded
					 ** or followed by an inverted copy (t2.b==t1.a).  Skip this term
					 ** and use its inversion. */
					goto _11
				}
				iColumn = (*(*struct {
					FleftColumn int32
					FiField     int32
				})(unsafe.Pointer(pOrTerm + 24))).FleftColumn
				iCursor = (*TWhereTerm)(unsafe.Pointer(pOrTerm)).FleftCursor
				pLeft = (*TExpr)(unsafe.Pointer((*TWhereTerm)(unsafe.Pointer(pOrTerm)).FpExpr)).FpLeft
				break
				goto _11
			_11:
				;
				i = i - 1
				pOrTerm += 48
			}
			if i < 0 {
				/* No candidate table+column was found.  This can only occur
				 ** on the second iteration */
				break
			}
			/* We have found a candidate table and column.  Check to see if that
			 ** table and column is common to every term in the OR clause */
			okToChngToIN = int32(1)
			for {
				if !(i >= 0 && okToChngToIN != 0) {
					break
				}
				if (*TWhereTerm)(unsafe.Pointer(pOrTerm)).FleftCursor != iCursor {
					v1 = pOrTerm + 10
					*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) & ^libc.Int32FromInt32(TERM_OK))
				} else {
					if (*(*struct {
						FleftColumn int32
						FiField     int32
					})(unsafe.Pointer(pOrTerm + 24))).FleftColumn != iColumn || iColumn == -int32(2) && _sqlite3ExprCompare(tls, pParse, (*TExpr)(unsafe.Pointer((*TWhereTerm)(unsafe.Pointer(pOrTerm)).FpExpr)).FpLeft, pLeft, -int32(1)) != 0 {
						okToChngToIN = 0
					} else {
						/* If the right-hand side is also a column, then the affinities
						 ** of both right and left sides must be such that no type
						 ** conversions are required on the right.  (Ticket #2249)
						 */
						affRight = int32(_sqlite3ExprAffinity(tls, (*TExpr)(unsafe.Pointer((*TWhereTerm)(unsafe.Pointer(pOrTerm)).FpExpr)).FpRight))
						affLeft = int32(_sqlite3ExprAffinity(tls, (*TExpr)(unsafe.Pointer((*TWhereTerm)(unsafe.Pointer(pOrTerm)).FpExpr)).FpLeft))
						if affRight != 0 && affRight != affLeft {
							okToChngToIN = 0
						} else {
							v1 = pOrTerm + 10
							*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) | libc.Int32FromInt32(TERM_OK))
						}
					}
				}
				goto _13
			_13:
				;
				i = i - 1
				pOrTerm += 48
			}
			goto _10
		_10:
			;
			j1 = j1 + 1
		}
		/* At this point, okToChngToIN is true if original pTerm satisfies
		 ** case 1.  In that case, construct a new virtual term that is
		 ** pTerm converted into an IN operator.
		 */
		if okToChngToIN != 0 { /* A transient duplicate expression */
			pList = uintptr(0)  /* The RHS of the IN operator */
			pLeft1 = uintptr(0) /* The complete IN operator */
			i = (*TWhereClause)(unsafe.Pointer(pOrWc)).FnTerm - int32(1)
			pOrTerm = (*TWhereClause)(unsafe.Pointer(pOrWc)).Fa
			for {
				if !(i >= 0) {
					break
				}
				if libc.Int32FromUint16((*TWhereTerm)(unsafe.Pointer(pOrTerm)).FwtFlags)&int32(TERM_OK) == 0 {
					goto _16
				}
				pDup = _sqlite3ExprDup(tls, db, (*TExpr)(unsafe.Pointer((*TWhereTerm)(unsafe.Pointer(pOrTerm)).FpExpr)).FpRight, 0)
				pList = _sqlite3ExprListAppend(tls, (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpParse, pList, pDup)
				pLeft1 = (*TExpr)(unsafe.Pointer((*TWhereTerm)(unsafe.Pointer(pOrTerm)).FpExpr)).FpLeft
				goto _16
			_16:
				;
				i = i - 1
				pOrTerm += 48
			}
			pDup = _sqlite3ExprDup(tls, db, pLeft1, 0)
			pNew = _sqlite3PExpr(tls, pParse, int32(TK_IN), pDup, uintptr(0))
			if pNew != 0 {
				_transferJoinMarkings(tls, pNew, pExpr)
				*(*uintptr)(unsafe.Pointer(pNew + 20)) = pList
				idxNew = _whereClauseInsert(tls, pWC, pNew, libc.Uint16FromInt32(libc.Int32FromInt32(TERM_VIRTUAL)|libc.Int32FromInt32(TERM_DYNAMIC)))
				_exprAnalyze(tls, pSrc, pWC, idxNew)
				/* pTerm = &pWC->a[idxTerm]; // would be needed if pTerm where reused */
				_markTermAsChild(tls, pWC, idxNew, idxTerm)
			} else {
				_sqlite3ExprListDelete(tls, db, pList)
			}
		}
	}
}

// C documentation
//
//	/*
//	** Argument pExpr is an (?, ?...) IN(...) expression. This
//	** function allocates and returns a nul-terminated string containing
//	** the affinities to be used for each column of the comparison.
//	**
//	** It is the responsibility of the caller to ensure that the returned
//	** string is eventually freed using sqlite3DbFree().
//	*/
func _exprINAffinity(tls *libc.TLS, pParse uintptr, pExpr uintptr) (r uintptr) {
	var a int8
	var i, nVal int32
	var pA, pLeft, pSelect, zRet, v1 uintptr
	_, _, _, _, _, _, _, _ = a, i, nVal, pA, pLeft, pSelect, zRet, v1
	pLeft = (*TExpr)(unsafe.Pointer(pExpr)).FpLeft
	nVal = _sqlite3ExprVectorSize(tls, pLeft)
	if (*TExpr)(unsafe.Pointer(pExpr)).Fflags&uint32(EP_xIsSelect) != uint32(0) {
		v1 = *(*uintptr)(unsafe.Pointer(pExpr + 20))
	} else {
		v1 = uintptr(0)
	}
	pSelect = v1
	zRet = _sqlite3DbMallocRaw(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, libc.Uint64FromInt64(int64(1)+int64(nVal)))
	if zRet != 0 {
		i = 0
		for {
			if !(i < nVal) {
				break
			}
			pA = _sqlite3VectorFieldSubexpr(tls, pLeft, i)
			a = _sqlite3ExprAffinity(tls, pA)
			if pSelect != 0 {
				**(**int8)(__ccgo_up(zRet + uintptr(i))) = _sqlite3CompareAffinity(tls, (*(*TExprList_item)(unsafe.Pointer((*TSelect)(unsafe.Pointer(pSelect)).FpEList + 8 + uintptr(i)*20))).FpExpr, a)
			} else {
				**(**int8)(__ccgo_up(zRet + uintptr(i))) = a
			}
			goto _2
		_2:
			;
			i = i + 1
		}
		**(**int8)(__ccgo_up(zRet + uintptr(nVal))) = int8('\000')
	}
	return zRet
}

// C documentation
//
//	/*
//	** Create the byte sequence used to represent a cell on page pPage
//	** and write that byte sequence into pCell[].  Overflow pages are
//	** allocated and filled in as necessary.  The calling procedure
//	** is responsible for making sure sufficient space has been allocated
//	** for pCell[].
//	**
//	** Note that pCell does not necessary need to point to the pPage->aData
//	** area.  pCell might point to some temporary storage.  The cell will
//	** be constructed in this temporary area then copied into pPage->aData
//	** later.
//	*/
func _fillInCell(tls *libc.TLS, pPage uintptr, pCell uintptr, pX uintptr, pnSize uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var eType Tu8
	var mn, n, nHeader, nPayload, nSrc, spaceLeft, v1 int32
	var pBt, pPayload, pPrior, pSrc, pToRelease uintptr
	var pgnoPtrmap TPgno
	var _ /* pOvfl at bp+8 */ uintptr
	var _ /* pgnoOvfl at bp+4 */ TPgno
	var _ /* rc at bp+0 */ int32
	_, _, _, _, _, _, _, _, _, _, _, _, _, _ = eType, mn, n, nHeader, nPayload, nSrc, pBt, pPayload, pPrior, pSrc, pToRelease, pgnoPtrmap, spaceLeft, v1
	/* pPage is not necessarily writeable since pCell might be auxiliary
	 ** buffer space that is separate from the pPage buffer area */
	/* Fill in the header. */
	nHeader = libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pPage)).FchildPtrSize)
	if (*TMemPage)(unsafe.Pointer(pPage)).FintKey != 0 {
		nPayload = (*TBtreePayload)(unsafe.Pointer(pX)).FnData + (*TBtreePayload)(unsafe.Pointer(pX)).FnZero
		pSrc = (*TBtreePayload)(unsafe.Pointer(pX)).FpData
		nSrc = (*TBtreePayload)(unsafe.Pointer(pX)).FnData
		/* fillInCell() only called for leaves */
		if libc.Uint32FromInt32(nPayload) < libc.Uint32FromInt32(0x80) {
			**(**uint8)(__ccgo_up(pCell + uintptr(nHeader))) = libc.Uint8FromInt32(nPayload)
			v1 = libc.Int32FromInt32(1)
		} else {
			v1 = _sqlite3PutVarint(tls, pCell+uintptr(nHeader), libc.Uint64FromInt32(nPayload))
		}
		nHeader = nHeader + libc.Int32FromUint8(libc.Uint8FromInt32(v1))
		nHeader = nHeader + _sqlite3PutVarint(tls, pCell+uintptr(nHeader), **(**Tu64)(__ccgo_up(pX + 4)))
	} else {
		v1 = int32((*TBtreePayload)(unsafe.Pointer(pX)).FnKey)
		nPayload = v1
		nSrc = v1
		pSrc = (*TBtreePayload)(unsafe.Pointer(pX)).FpKey
		if libc.Uint32FromInt32(nPayload) < libc.Uint32FromInt32(0x80) {
			**(**uint8)(__ccgo_up(pCell + uintptr(nHeader))) = libc.Uint8FromInt32(nPayload)
			v1 = libc.Int32FromInt32(1)
		} else {
			v1 = _sqlite3PutVarint(tls, pCell+uintptr(nHeader), libc.Uint64FromInt32(nPayload))
		}
		nHeader = nHeader + libc.Int32FromUint8(libc.Uint8FromInt32(v1))
	}
	/* Fill in the payload */
	pPayload = pCell + uintptr(nHeader)
	if nPayload <= libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FmaxLocal) {
		/* This is the common case where everything fits on the btree page
		 ** and no overflow pages are required. */
		n = nHeader + nPayload
		if n < int32(4) {
			n = int32(4)
			**(**uint8)(__ccgo_up(pPayload + uintptr(nPayload))) = uint8(0)
		}
		**(**int32)(__ccgo_up(pnSize)) = n
		libc.Xmemcpy(tls, pPayload, pSrc, libc.Uint32FromInt32(nSrc))
		libc.Xmemset(tls, pPayload+uintptr(nSrc), 0, libc.Uint32FromInt32(nPayload-nSrc))
		return SQLITE_OK
	}
	/* If we reach this point, it means that some of the content will need
	 ** to spill onto overflow pages.
	 */
	mn = libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FminLocal)
	n = libc.Int32FromUint32(libc.Uint32FromInt32(mn) + libc.Uint32FromInt32(nPayload-mn)%((*TBtShared)(unsafe.Pointer((*TMemPage)(unsafe.Pointer(pPage)).FpBt)).FusableSize-uint32(4)))
	if n > libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FmaxLocal) {
		n = mn
	}
	spaceLeft = n
	**(**int32)(__ccgo_up(pnSize)) = n + nHeader + int32(4)
	pPrior = pCell + uintptr(nHeader+n)
	pToRelease = uintptr(0)
	**(**TPgno)(__ccgo_up(bp + 4)) = uint32(0)
	pBt = (*TMemPage)(unsafe.Pointer(pPage)).FpBt
	/* At this point variables should be set as follows:
	 **
	 **   nPayload           Total payload size in bytes
	 **   pPayload           Begin writing payload here
	 **   spaceLeft          Space available at pPayload.  If nPayload>spaceLeft,
	 **                      that means content must spill into overflow pages.
	 **   *pnSize            Size of the local cell (not counting overflow pages)
	 **   pPrior             Where to write the pgno of the first overflow page
	 **
	 ** Use a call to btreeParseCellPtr() to verify that the values above
	 ** were computed correctly.
	 */
	/* Write the payload into the local Cell and any extra into overflow pages */
	for int32(1) != 0 {
		n = nPayload
		if n > spaceLeft {
			n = spaceLeft
		}
		/* If pToRelease is not zero than pPayload points into the data area
		 ** of pToRelease.  Make sure pToRelease is still writeable. */
		/* If pPayload is part of the data area of pPage, then make sure pPage
		 ** is still writeable */
		if nSrc >= n {
			libc.Xmemcpy(tls, pPayload, pSrc, libc.Uint32FromInt32(n))
		} else {
			if nSrc > 0 {
				n = nSrc
				libc.Xmemcpy(tls, pPayload, pSrc, libc.Uint32FromInt32(n))
			} else {
				libc.Xmemset(tls, pPayload, 0, libc.Uint32FromInt32(n))
			}
		}
		nPayload = nPayload - n
		if nPayload <= 0 {
			break
		}
		pPayload = pPayload + uintptr(n)
		pSrc = pSrc + uintptr(n)
		nSrc = nSrc - n
		spaceLeft = spaceLeft - n
		if spaceLeft == 0 {
			**(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0)
			pgnoPtrmap = **(**TPgno)(__ccgo_up(bp + 4)) /* Overflow page pointer-map entry page */
			if (*TBtShared)(unsafe.Pointer(pBt)).FautoVacuum != 0 {
				for cond := true; cond; cond = _ptrmapPageno(tls, pBt, **(**TPgno)(__ccgo_up(bp + 4))) == **(**TPgno)(__ccgo_up(bp + 4)) || **(**TPgno)(__ccgo_up(bp + 4)) == libc.Uint32FromInt32(_sqlite3PendingByte)/(*TBtShared)(unsafe.Pointer(pBt)).FpageSize+libc.Uint32FromInt32(1) {
					**(**TPgno)(__ccgo_up(bp + 4)) = **(**TPgno)(__ccgo_up(bp + 4)) + 1
				}
			}
			**(**int32)(__ccgo_up(bp)) = _allocateBtreePage(tls, pBt, bp+8, bp+4, **(**TPgno)(__ccgo_up(bp + 4)), uint8(0))
			/* If the database supports auto-vacuum, and the second or subsequent
			 ** overflow page is being allocated, add an entry to the pointer-map
			 ** for that page now.
			 **
			 ** If this is the first overflow page, then write a partial entry
			 ** to the pointer-map. If we write nothing to this pointer-map slot,
			 ** then the optimistic overflow chain processing in clearCell()
			 ** may misinterpret the uninitialized values and delete the
			 ** wrong pages from the database.
			 */
			if (*TBtShared)(unsafe.Pointer(pBt)).FautoVacuum != 0 && **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
				if pgnoPtrmap != 0 {
					v1 = int32(PTRMAP_OVERFLOW2)
				} else {
					v1 = int32(PTRMAP_OVERFLOW1)
				}
				eType = libc.Uint8FromInt32(v1)
				_ptrmapPut(tls, pBt, **(**TPgno)(__ccgo_up(bp + 4)), eType, pgnoPtrmap, bp)
				if **(**int32)(__ccgo_up(bp)) != 0 {
					_releasePage(tls, **(**uintptr)(__ccgo_up(bp + 8)))
				}
			}
			if **(**int32)(__ccgo_up(bp)) != 0 {
				_releasePage(tls, pToRelease)
				return **(**int32)(__ccgo_up(bp))
			}
			/* If pToRelease is not zero than pPrior points into the data area
			 ** of pToRelease.  Make sure pToRelease is still writeable. */
			/* If pPrior is part of the data area of pPage, then make sure pPage
			 ** is still writeable */
			_sqlite3Put4byte(tls, pPrior, **(**TPgno)(__ccgo_up(bp + 4)))
			_releasePage(tls, pToRelease)
			pToRelease = **(**uintptr)(__ccgo_up(bp + 8))
			pPrior = (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 8)))).FaData
			_sqlite3Put4byte(tls, pPrior, uint32(0))
			pPayload = (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 8)))).FaData + 4
			spaceLeft = libc.Int32FromUint32((*TBtShared)(unsafe.Pointer(pBt)).FusableSize - uint32(4))
		}
	}
	_releasePage(tls, pToRelease)
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** This routine is called right after An OP_Filter has been generated and
//	** before the corresponding index search has been performed.  This routine
//	** checks to see if there are additional Bloom filters in inner loops that
//	** can be checked prior to doing the index lookup.  If there are available
//	** inner-loop Bloom filters, then evaluate those filters now, before the
//	** index lookup.  The idea is that a Bloom filter check is way faster than
//	** an index lookup, and the Bloom filter might return false, meaning that
//	** the index lookup can be skipped.
//	**
//	** We know that an inner loop uses a Bloom filter because it has the
//	** WhereLevel.regFilter set.  If an inner-loop Bloom filter is checked,
//	** then clear the WhereLevel.regFilter value to prevent the Bloom filter
//	** from being checked a second time when the inner loop is evaluated.
//	*/
func _filterPullDown(tls *libc.TLS, pParse uintptr, pWInfo uintptr, iLevel int32, addrNxt int32, notReady TBitmask) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var nEq Tu16
	var pLevel, pLoop, pTerm uintptr
	var r1, regRowid, saved_addrBrk, v1 int32
	var _ /* zStartAff at bp+0 */ uintptr
	_, _, _, _, _, _, _, _ = nEq, pLevel, pLoop, pTerm, r1, regRowid, saved_addrBrk, v1
	for {
		iLevel = iLevel + 1
		v1 = iLevel
		if !(v1 < libc.Int32FromUint8((*TWhereInfo)(unsafe.Pointer(pWInfo)).FnLevel)) {
			break
		}
		pLevel = pWInfo + 752 + uintptr(iLevel)*88
		pLoop = (*TWhereLevel)(unsafe.Pointer(pLevel)).FpWLoop
		if (*TWhereLevel)(unsafe.Pointer(pLevel)).FregFilter == 0 {
			continue
		}
		if (*TWhereLoop)(unsafe.Pointer((*TWhereLevel)(unsafe.Pointer(pLevel)).FpWLoop)).FnSkip != 0 {
			continue
		}
		/*         ,--- Because sqlite3ConstructBloomFilter() has will not have set
		 **  vvvvv--'    pLevel->regFilter if this were true. */
		if (*TWhereLoop)(unsafe.Pointer(pLoop)).Fprereq&notReady != 0 {
			continue
		}
		saved_addrBrk = (*TWhereLevel)(unsafe.Pointer(pLevel)).FaddrBrk
		(*TWhereLevel)(unsafe.Pointer(pLevel)).FaddrBrk = addrNxt
		if (*TWhereLoop)(unsafe.Pointer(pLoop)).FwsFlags&uint32(WHERE_IPK) != 0 {
			pTerm = **(**uintptr)(__ccgo_up((*TWhereLoop)(unsafe.Pointer(pLoop)).FaLTerm))
			regRowid = _sqlite3GetTempReg(tls, pParse)
			regRowid = _codeEqualityTerm(tls, pParse, pTerm, pLevel, 0, 0, regRowid)
			_sqlite3VdbeAddOp2(tls, (*TParse)(unsafe.Pointer(pParse)).FpVdbe, int32(OP_MustBeInt), regRowid, addrNxt)
			_sqlite3VdbeAddOp4Int(tls, (*TParse)(unsafe.Pointer(pParse)).FpVdbe, int32(OP_Filter), (*TWhereLevel)(unsafe.Pointer(pLevel)).FregFilter, addrNxt, regRowid, int32(1))
		} else {
			nEq = (*(*struct {
				FnEq          Tu16
				FnBtm         Tu16
				FnTop         Tu16
				FnDistinctCol Tu16
				FpIndex       uintptr
				FpOrderBy     uintptr
			})(unsafe.Pointer(pLoop + 24))).FnEq
			r1 = _codeAllEqualityTerms(tls, pParse, pLevel, 0, 0, bp)
			_codeApplyAffinity(tls, pParse, r1, libc.Int32FromUint16(nEq), **(**uintptr)(__ccgo_up(bp)))
			_sqlite3DbFree(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, **(**uintptr)(__ccgo_up(bp)))
			_sqlite3VdbeAddOp4Int(tls, (*TParse)(unsafe.Pointer(pParse)).FpVdbe, int32(OP_Filter), (*TWhereLevel)(unsafe.Pointer(pLevel)).FregFilter, addrNxt, r1, libc.Int32FromUint16(nEq))
		}
		(*TWhereLevel)(unsafe.Pointer(pLevel)).FregFilter = 0
		(*TWhereLevel)(unsafe.Pointer(pLevel)).FaddrBrk = saved_addrBrk
	}
}

// C documentation
//
//	/*
//	** Locate and return an entry from the db.aCollSeq hash table. If the entry
//	** specified by zName and nName is not found and parameter 'create' is
//	** true, then create a new entry. Otherwise return NULL.
//	**
//	** Each pointer stored in the sqlite3.aCollSeq hash table contains an
//	** array of three CollSeq structures. The first is the collation sequence
//	** preferred for UTF-8, the second UTF-16le, and the third UTF-16be.
//	**
//	** Stored immediately after the three collation sequences is a copy of
//	** the collation sequence name. A pointer to this string is stored in
//	** each collation sequence structure.
//	*/
func _findCollSeqEntry(tls *libc.TLS, db uintptr, zName uintptr, create int32) (r uintptr) {
	var nName int32
	var pColl, pDel uintptr
	_, _, _ = nName, pColl, pDel
	pColl = _sqlite3HashFind(tls, db+444, zName)
	if uintptr(0) == pColl && create != 0 {
		nName = _sqlite3Strlen30(tls, zName) + int32(1)
		pColl = _sqlite3DbMallocZero(tls, db, uint64(libc.Uint32FromInt32(3)*libc.Uint32FromInt64(20)+libc.Uint32FromInt32(nName)))
		if pColl != 0 {
			pDel = uintptr(0)
			(**(**TCollSeq)(__ccgo_up(pColl))).FzName = pColl + 3*20
			(**(**TCollSeq)(__ccgo_up(pColl))).Fenc = uint8(SQLITE_UTF8)
			(**(**TCollSeq)(__ccgo_up(pColl + 1*20))).FzName = pColl + 3*20
			(**(**TCollSeq)(__ccgo_up(pColl + 1*20))).Fenc = uint8(SQLITE_UTF16LE)
			(**(**TCollSeq)(__ccgo_up(pColl + 2*20))).FzName = pColl + 3*20
			(**(**TCollSeq)(__ccgo_up(pColl + 2*20))).Fenc = uint8(SQLITE_UTF16BE)
			libc.Xmemcpy(tls, (**(**TCollSeq)(__ccgo_up(pColl))).FzName, zName, libc.Uint32FromInt32(nName))
			pDel = _sqlite3HashInsert(tls, db+444, (**(**TCollSeq)(__ccgo_up(pColl))).FzName, pColl)
			/* If a malloc() failure occurred in sqlite3HashInsert(), it will
			 ** return the pColl pointer to be deleted (because it wasn't added
			 ** to the hash table).
			 */
			if pDel != uintptr(0) {
				_sqlite3OomFault(tls, db)
				_sqlite3DbFree(tls, db, pDel)
				pColl = uintptr(0)
			}
		}
	}
	return pColl
}

func _first_valueFinalizeFunc(tls *libc.TLS, pCtx uintptr) {
	var p uintptr
	_ = p
	p = Xsqlite3_aggregate_context(tls, pCtx, int32(12))
	if p != 0 && (*TNthValueCtx)(unsafe.Pointer(p)).FpValue != 0 {
		Xsqlite3_result_value(tls, pCtx, (*TNthValueCtx)(unsafe.Pointer(p)).FpValue)
		Xsqlite3_value_free(tls, (*TNthValueCtx)(unsafe.Pointer(p)).FpValue)
		(*TNthValueCtx)(unsafe.Pointer(p)).FpValue = uintptr(0)
	}
}

func _first_valueStepFunc(tls *libc.TLS, pCtx uintptr, nArg int32, apArg uintptr) {
	var p uintptr
	_ = p
	p = Xsqlite3_aggregate_context(tls, pCtx, int32(12))
	if p != 0 && (*TNthValueCtx)(unsafe.Pointer(p)).FpValue == uintptr(0) {
		(*TNthValueCtx)(unsafe.Pointer(p)).FpValue = Xsqlite3_value_dup(tls, **(**uintptr)(__ccgo_up(apArg)))
		if !((*TNthValueCtx)(unsafe.Pointer(p)).FpValue != 0) {
			Xsqlite3_result_error_nomem(tls, pCtx)
		}
	}
	_ = nArg
	_ = apArg
}

func _fixBoundingBox(tls *libc.TLS, pRtree uintptr, pNode uintptr) (r int32) {
	bp := tls.Alloc(112)
	defer tls.Free(112)
	var nCell, rc int32
	var pParent uintptr
	var _ /* box at bp+4 */ TRtreeCell
	var _ /* cell at bp+52 */ TRtreeCell
	var _ /* ii at bp+0 */ int32
	_, _, _ = nCell, pParent, rc
	pParent = (*TRtreeNode)(unsafe.Pointer(pNode)).FpParent
	rc = SQLITE_OK
	if pParent != 0 {
		nCell = _readInt16(tls, (*TRtreeNode)(unsafe.Pointer(pNode)).FzData+2) /* Bounding box for pNode */
		_nodeGetCell(tls, pRtree, pNode, 0, bp+4)
		**(**int32)(__ccgo_up(bp)) = int32(1)
		for {
			if !(**(**int32)(__ccgo_up(bp)) < nCell) {
				break
			}
			_nodeGetCell(tls, pRtree, pNode, **(**int32)(__ccgo_up(bp)), bp+52)
			_cellUnion(tls, pRtree, bp+4, bp+52)
			goto _1
		_1:
			;
			**(**int32)(__ccgo_up(bp)) = **(**int32)(__ccgo_up(bp)) + 1
		}
		(**(**TRtreeCell)(__ccgo_up(bp + 4))).FiRowid = (*TRtreeNode)(unsafe.Pointer(pNode)).FiNode
		rc = _nodeParentIndex(tls, pRtree, pNode, bp)
		if rc == SQLITE_OK {
			_nodeOverwriteCell(tls, pRtree, pParent, bp+4, **(**int32)(__ccgo_up(bp)))
			rc = _fixBoundingBox(tls, pRtree, pParent)
		}
	}
	return rc
}

// C documentation
//
//	/*
//	** Free an sqlite3_index_info structure allocated by allocateIndexInfo()
//	** and possibly modified by xBestIndex methods.
//	*/
func _freeIndexInfo(tls *libc.TLS, db uintptr, pIdxInfo uintptr) {
	var i int32
	var pHidden uintptr
	_, _ = i, pHidden
	pHidden = pIdxInfo + 1*64
	i = 0
	for {
		if !(i < (*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FnConstraint) {
			break
		}
		_sqlite3ValueFree(tls, *(*uintptr)(unsafe.Pointer(pHidden + 20 + uintptr(i)*4))) /* IMP: R-14553-25174 */
		*(*uintptr)(unsafe.Pointer(pHidden + 20 + uintptr(i)*4)) = uintptr(0)
		goto _1
	_1:
		;
		i = i + 1
	}
	_freeIdxStr(tls, pIdxInfo)
	_sqlite3DbFree(tls, db, pIdxInfo)
}

// C documentation
//
//	/*
//	** Allocate a new segment-id for the structure pStruct. The new segment
//	** id must be between 1 and 65335 inclusive, and must not be used by
//	** any currently existing segment. If a free segment id cannot be found,
//	** SQLITE_FULL is returned.
//	**
//	** If an error has already occurred, this function is a no-op. 0 is
//	** returned in this case.
//	*/
func _fts5AllocateSegid(tls *libc.TLS, p uintptr, pStruct uintptr) (r int32) {
	bp := tls.Alloc(256)
	defer tls.Free(256)
	var i, iId, iLvl, iSeg, iSegid int32
	var mask Tu32
	var _ /* aUsed at bp+0 */ [63]Tu32
	_, _, _, _, _, _ = i, iId, iLvl, iSeg, iSegid, mask
	iSegid = 0
	if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
		if (*TFts5Structure)(unsafe.Pointer(pStruct)).FnSegment >= int32(FTS5_MAX_SEGMENT) {
			(*TFts5Index)(unsafe.Pointer(p)).Frc = int32(SQLITE_FULL)
		} else {
			libc.Xmemset(tls, bp, 0, uint32(252))
			iLvl = 0
			for {
				if !(iLvl < (*TFts5Structure)(unsafe.Pointer(pStruct)).FnLevel) {
					break
				}
				iSeg = 0
				for {
					if !(iSeg < (*(*TFts5StructureLevel)(unsafe.Pointer(pStruct + 28 + uintptr(iLvl)*12))).FnSeg) {
						break
					}
					iId = (**(**TFts5StructureSegment)(__ccgo_up((*(*TFts5StructureLevel)(unsafe.Pointer(pStruct + 28 + uintptr(iLvl)*12))).FaSeg + uintptr(iSeg)*48))).FiSegid
					if iId <= int32(FTS5_MAX_SEGMENT) && iId > 0 {
						**(**Tu32)(__ccgo_up(bp + uintptr((iId-int32(1))/int32(32))*4)) |= libc.Uint32FromInt32(1) << ((iId - int32(1)) % int32(32))
					}
					goto _2
				_2:
					;
					iSeg = iSeg + 1
				}
				goto _1
			_1:
				;
				iLvl = iLvl + 1
			}
			i = 0
			for {
				if !((**(**[63]Tu32)(__ccgo_up(bp)))[i] == uint32(0xFFFFFFFF)) {
					break
				}
				goto _3
			_3:
				;
				i = i + 1
			}
			mask = (**(**[63]Tu32)(__ccgo_up(bp)))[i]
			iSegid = 0
			for {
				if !(mask&(libc.Uint32FromInt32(1)<<iSegid) != 0) {
					break
				}
				goto _4
			_4:
				;
				iSegid = iSegid + 1
			}
			iSegid = iSegid + (int32(1) + i*int32(32))
		}
	}
	return iSegid
}

func _fts5ApiColumnSize(tls *libc.TLS, pCtx uintptr, iCol int32, pnToken uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var i, i1, i2, rc int32
	var iRowid Ti64
	var pConfig, pCsr, pTab uintptr
	var _ /* n at bp+4 */ int32
	var _ /* z at bp+0 */ uintptr
	_, _, _, _, _, _, _, _ = i, i1, i2, iRowid, pConfig, pCsr, pTab, rc
	pCsr = pCtx
	pTab = (*TFts5Cursor)(unsafe.Pointer(pCsr)).Fbase.FpVtab
	pConfig = (*TFts5FullTable)(unsafe.Pointer(pTab)).Fp.FpConfig
	rc = SQLITE_OK
	if (*TFts5Cursor)(unsafe.Pointer(pCsr)).Fcsrflags&int32(FTS5CSR_REQUIRE_DOCSIZE) != 0 {
		if (*TFts5Config)(unsafe.Pointer(pConfig)).FbColumnsize != 0 {
			iRowid = _fts5CursorRowid(tls, pCsr)
			rc = _sqlite3Fts5StorageDocsize(tls, (*TFts5FullTable)(unsafe.Pointer(pTab)).FpStorage, iRowid, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FaColumnSize)
		} else {
			if !((*TFts5Config)(unsafe.Pointer(pConfig)).FzContent != 0) || (*TFts5Config)(unsafe.Pointer(pConfig)).FeContent == int32(FTS5_CONTENT_UNINDEXED) {
				i = 0
				for {
					if !(i < (*TFts5Config)(unsafe.Pointer(pConfig)).FnCol) {
						break
					}
					if libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TFts5Config)(unsafe.Pointer(pConfig)).FabUnindexed + uintptr(i)))) == 0 {
						**(**int32)(__ccgo_up((*TFts5Cursor)(unsafe.Pointer(pCsr)).FaColumnSize + uintptr(i)*4)) = -int32(1)
					}
					goto _1
				_1:
					;
					i = i + 1
				}
			} else {
				rc = _fts5SeekCursor(tls, pCsr, 0)
				i1 = 0
				for {
					if !(rc == SQLITE_OK && i1 < (*TFts5Config)(unsafe.Pointer(pConfig)).FnCol) {
						break
					}
					if libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TFts5Config)(unsafe.Pointer(pConfig)).FabUnindexed + uintptr(i1)))) == 0 {
						**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
						**(**int32)(__ccgo_up(bp + 4)) = 0
						**(**int32)(__ccgo_up((*TFts5Cursor)(unsafe.Pointer(pCsr)).FaColumnSize + uintptr(i1)*4)) = 0
						rc = _fts5TextFromStmt(tls, pConfig, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpStmt, i1, bp, bp+4)
						if rc == SQLITE_OK {
							rc = _sqlite3Fts5Tokenize(tls, pConfig, int32(FTS5_TOKENIZE_AUX), **(**uintptr)(__ccgo_up(bp)), **(**int32)(__ccgo_up(bp + 4)), (*TFts5Cursor)(unsafe.Pointer(pCsr)).FaColumnSize+uintptr(i1)*4, __ccgo_fp(_fts5ColumnSizeCb))
						}
						_sqlite3Fts5ClearLocale(tls, pConfig)
					}
					goto _2
				_2:
					;
					i1 = i1 + 1
				}
			}
		}
		**(**int32)(__ccgo_up(pCsr + 56)) &= ^libc.Int32FromInt32(FTS5CSR_REQUIRE_DOCSIZE)
	}
	if iCol < 0 {
		**(**int32)(__ccgo_up(pnToken)) = 0
		i2 = 0
		for {
			if !(i2 < (*TFts5Config)(unsafe.Pointer(pConfig)).FnCol) {
				break
			}
			**(**int32)(__ccgo_up(pnToken)) += **(**int32)(__ccgo_up((*TFts5Cursor)(unsafe.Pointer(pCsr)).FaColumnSize + uintptr(i2)*4))
			goto _3
		_3:
			;
			i2 = i2 + 1
		}
	} else {
		if iCol < (*TFts5Config)(unsafe.Pointer(pConfig)).FnCol {
			**(**int32)(__ccgo_up(pnToken)) = **(**int32)(__ccgo_up((*TFts5Cursor)(unsafe.Pointer(pCsr)).FaColumnSize + uintptr(iCol)*4))
		} else {
			**(**int32)(__ccgo_up(pnToken)) = 0
			rc = int32(SQLITE_RANGE)
		}
	}
	return rc
}

func _fts5ApiPhraseFirstColumn(tls *libc.TLS, pCtx uintptr, iPhrase int32, pIter uintptr, piCol uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var i1, rc, v1 int32
	var pConfig, pCsr, pSorter, v2 uintptr
	var _ /* n at bp+0 */ int32
	var _ /* n at bp+4 */ int32
	_, _, _, _, _, _, _ = i1, pConfig, pCsr, pSorter, rc, v1, v2
	rc = SQLITE_OK
	pCsr = pCtx
	pConfig = (*TFts5Table)(unsafe.Pointer((*TFts5Cursor)(unsafe.Pointer(pCsr)).Fbase.FpVtab)).FpConfig
	if (*TFts5Config)(unsafe.Pointer(pConfig)).FeDetail == int32(FTS5_DETAIL_COLUMNS) {
		pSorter = (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpSorter
		if pSorter != 0 {
			if iPhrase == 0 {
				v1 = 0
			} else {
				v1 = *(*int32)(unsafe.Pointer(pSorter + 20 + uintptr(iPhrase-int32(1))*4))
			}
			i1 = v1
			**(**int32)(__ccgo_up(bp)) = *(*int32)(unsafe.Pointer(pSorter + 20 + uintptr(iPhrase)*4)) - i1
			(*TFts5PhraseIter)(unsafe.Pointer(pIter)).Fa = (*TFts5Sorter)(unsafe.Pointer(pSorter)).FaPoslist + uintptr(i1)
		} else {
			rc = _sqlite3Fts5ExprPhraseCollist(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpExpr, iPhrase, pIter, bp)
		}
		if rc == SQLITE_OK {
			if (*TFts5PhraseIter)(unsafe.Pointer(pIter)).Fa != 0 {
				v2 = (*TFts5PhraseIter)(unsafe.Pointer(pIter)).Fa + uintptr(**(**int32)(__ccgo_up(bp)))
			} else {
				v2 = uintptr(0)
			}
			(*TFts5PhraseIter)(unsafe.Pointer(pIter)).Fb = v2
			**(**int32)(__ccgo_up(piCol)) = 0
			_fts5ApiPhraseNextColumn(tls, pCtx, pIter, piCol)
		}
	} else {
		rc = _fts5CsrPoslist(tls, pCsr, iPhrase, pIter, bp+4)
		if rc == SQLITE_OK {
			if (*TFts5PhraseIter)(unsafe.Pointer(pIter)).Fa != 0 {
				v2 = (*TFts5PhraseIter)(unsafe.Pointer(pIter)).Fa + uintptr(**(**int32)(__ccgo_up(bp + 4)))
			} else {
				v2 = uintptr(0)
			}
			(*TFts5PhraseIter)(unsafe.Pointer(pIter)).Fb = v2
			if **(**int32)(__ccgo_up(bp + 4)) <= 0 {
				**(**int32)(__ccgo_up(piCol)) = -int32(1)
			} else {
				if libc.Int32FromUint8(**(**uint8)(__ccgo_up((*TFts5PhraseIter)(unsafe.Pointer(pIter)).Fa))) == int32(0x01) {
					**(**uintptr)(__ccgo_up(pIter)) += uintptr(int32(1) + _sqlite3Fts5GetVarint32(tls, (*TFts5PhraseIter)(unsafe.Pointer(pIter)).Fa+1, piCol))
				} else {
					**(**int32)(__ccgo_up(piCol)) = 0
				}
			}
		}
	}
	return rc
}

// C documentation
//
//	/*
//	** Implementation of API function xQueryPhrase().
//	*/
func _fts5ApiQueryPhrase(tls *libc.TLS, pCtx uintptr, iPhrase int32, pUserData uintptr, __ccgo_fp_xCallback uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var pCsr, pTab uintptr
	var rc int32
	var _ /* pNew at bp+0 */ uintptr
	_, _, _ = pCsr, pTab, rc
	pCsr = pCtx
	pTab = (*TFts5Cursor)(unsafe.Pointer(pCsr)).Fbase.FpVtab
	**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
	rc = _fts5OpenMethod(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).Fbase.FpVtab, bp)
	if rc == SQLITE_OK {
		(*TFts5Cursor)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FePlan = int32(FTS5_PLAN_MATCH)
		(*TFts5Cursor)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FiFirstRowid = int64(-libc.Int32FromInt32(1)) - (libc.Int64FromUint32(0xffffffff) | libc.Int64FromInt32(0x7fffffff)<<libc.Int32FromInt32(32))
		(*TFts5Cursor)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FiLastRowid = libc.Int64FromUint32(0xffffffff) | libc.Int64FromInt32(0x7fffffff)<<libc.Int32FromInt32(32)
		(*TFts5Cursor)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).Fbase.FpVtab = pTab
		rc = _sqlite3Fts5ExprClonePhrase(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpExpr, iPhrase, **(**uintptr)(__ccgo_up(bp))+48)
	}
	if rc == SQLITE_OK {
		rc = _fts5CursorFirst(tls, pTab, **(**uintptr)(__ccgo_up(bp)), 0)
		for {
			if !(rc == SQLITE_OK && (*TFts5Cursor)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).Fcsrflags&int32(FTS5CSR_EOF) == 0) {
				break
			}
			rc = (*(*func(*libc.TLS, uintptr, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{__ccgo_fp_xCallback})))(tls, uintptr(unsafe.Pointer(&_sFts5Api)), **(**uintptr)(__ccgo_up(bp)), pUserData)
			if rc != SQLITE_OK {
				if rc == int32(SQLITE_DONE) {
					rc = SQLITE_OK
				}
				break
			}
			goto _1
		_1:
			;
			rc = _fts5NextMethod(tls, **(**uintptr)(__ccgo_up(bp)))
		}
	}
	_fts5CloseMethod(tls, **(**uintptr)(__ccgo_up(bp)))
	return rc
}

func _fts5AppendPoslist(tls *libc.TLS, p uintptr, iDelta Tu64, pMulti uintptr, pBuf uintptr) {
	var nByte, nData, v1 int32
	var v2 bool
	_, _, _, _ = nByte, nData, v1, v2
	nData = (*TFts5Iter)(unsafe.Pointer(pMulti)).Fbase.FnData
	nByte = nData + int32(9) + int32(9) + int32(FTS5_DATA_ZERO_PADDING)
	if v2 = (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK; v2 {
		if libc.Uint32FromInt32((*TFts5Buffer)(unsafe.Pointer(pBuf)).Fn)+libc.Uint32FromInt32(nByte) <= libc.Uint32FromInt32((*TFts5Buffer)(unsafe.Pointer(pBuf)).FnSpace) {
			v1 = 0
		} else {
			v1 = _sqlite3Fts5BufferSize(tls, p+40, pBuf, libc.Uint32FromInt32(nByte+(*TFts5Buffer)(unsafe.Pointer(pBuf)).Fn))
		}
	}
	if v2 && 0 == v1 {
		**(**int32)(__ccgo_up(pBuf + 4)) += _sqlite3Fts5PutVarint(tls, (*TFts5Buffer)(unsafe.Pointer(pBuf)).Fp+uintptr((*TFts5Buffer)(unsafe.Pointer(pBuf)).Fn), iDelta)
		**(**int32)(__ccgo_up(pBuf + 4)) += _sqlite3Fts5PutVarint(tls, (*TFts5Buffer)(unsafe.Pointer(pBuf)).Fp+uintptr((*TFts5Buffer)(unsafe.Pointer(pBuf)).Fn), libc.Uint64FromInt32(nData*libc.Int32FromInt32(2)))
		libc.Xmemcpy(tls, (*TFts5Buffer)(unsafe.Pointer(pBuf)).Fp+uintptr((*TFts5Buffer)(unsafe.Pointer(pBuf)).Fn), (*TFts5Iter)(unsafe.Pointer(pMulti)).Fbase.FpData, libc.Uint32FromInt32(nData))
		**(**int32)(__ccgo_up(pBuf + 4)) += nData
		libc.Xmemset(tls, (*TFts5Buffer)(unsafe.Pointer(pBuf)).Fp+uintptr((*TFts5Buffer)(unsafe.Pointer(pBuf)).Fn), 0, uint32(FTS5_DATA_ZERO_PADDING))
	}
}

func _fts5AppendRowid(tls *libc.TLS, p uintptr, iDelta Tu64, pUnused uintptr, pBuf uintptr) {
	_ = pUnused
	_sqlite3Fts5BufferAppendVarint(tls, p+40, pBuf, libc.Int64FromUint64(iDelta))
}

// C documentation
//
//	/*
//	** This function appends iterator pAppend to Fts5TokenDataIter pIn and
//	** returns the result.
//	*/
func _fts5AppendTokendataIter(tls *libc.TLS, p uintptr, pIn uintptr, pAppend uintptr) (r uintptr) {
	var nAlloc, nByte, v2 Ti64
	var pNew, pRet, v3 uintptr
	var v1 int64
	_, _, _, _, _, _, _ = nAlloc, nByte, pNew, pRet, v1, v2, v3
	pRet = pIn
	if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
		if pIn == uintptr(0) || (*TFts5TokenDataIter)(unsafe.Pointer(pIn)).FnIter == (*TFts5TokenDataIter)(unsafe.Pointer(pIn)).FnIterAlloc {
			if pIn != 0 {
				v1 = (*TFts5TokenDataIter)(unsafe.Pointer(pIn)).FnIterAlloc * int64(2)
			} else {
				v1 = int64(16)
			}
			nAlloc = v1
			nByte = libc.Int64FromUint32(uint32(libc.UintptrFromInt32(0)+56)) + (nAlloc+libc.Int64FromInt32(1))*libc.Int64FromInt64(72)
			pNew = Xsqlite3_realloc64(tls, pIn, libc.Uint64FromInt64(nByte))
			if pNew == uintptr(0) {
				(*TFts5Index)(unsafe.Pointer(p)).Frc = int32(SQLITE_NOMEM)
			} else {
				if pIn == uintptr(0) {
					libc.Xmemset(tls, pNew, 0, libc.Uint32FromInt64(nByte))
				}
				pRet = pNew
				(*TFts5TokenDataIter)(unsafe.Pointer(pNew)).FnIterAlloc = nAlloc
			}
		}
	}
	if (*TFts5Index)(unsafe.Pointer(p)).Frc != 0 {
		_fts5IterClose(tls, pAppend)
	} else {
		v3 = pRet + 32
		v2 = *(*Ti64)(unsafe.Pointer(v3))
		*(*Ti64)(unsafe.Pointer(v3)) = *(*Ti64)(unsafe.Pointer(v3)) + 1
		*(*uintptr)(unsafe.Pointer(pRet + 56 + uintptr(v2)*4)) = pAppend
	}
	return pRet
}

// C documentation
//
//	/*
//	** Set *ppData to point to the Fts5Bm25Data object for the current query.
//	** If the object has not already been allocated, allocate and populate it
//	** now.
//	*/
func _fts5Bm25GetData(tls *libc.TLS, pApi uintptr, pFts uintptr, ppData uintptr) (r int32) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var i, nPhrase, rc int32
	var idf float64
	var nByte Tsqlite3_int64
	var p uintptr
	var _ /* nHit at bp+16 */ Tsqlite3_int64
	var _ /* nRow at bp+0 */ Tsqlite3_int64
	var _ /* nToken at bp+8 */ Tsqlite3_int64
	_, _, _, _, _, _ = i, idf, nByte, nPhrase, p, rc
	rc = SQLITE_OK /* Object to return */
	p = (*(*func(*libc.TLS, uintptr, int32) uintptr)(unsafe.Pointer(&struct{ uintptr }{(*TFts5ExtensionApi)(unsafe.Pointer(pApi)).FxGetAuxdata})))(tls, pFts, 0)
	if p == uintptr(0) { /* Number of phrases in query */
		**(**Tsqlite3_int64)(__ccgo_up(bp)) = 0 /* Number of rows in table */
		**(**Tsqlite3_int64)(__ccgo_up(bp + 8)) = 0
		/* Allocate the Fts5Bm25Data object */
		nPhrase = (*(*func(*libc.TLS, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*TFts5ExtensionApi)(unsafe.Pointer(pApi)).FxPhraseCount})))(tls, pFts)
		nByte = libc.Int64FromUint32(uint32(20) + libc.Uint32FromInt32(nPhrase*int32(2))*uint32(8))
		p = Xsqlite3_malloc64(tls, libc.Uint64FromInt64(nByte))
		if p == uintptr(0) {
			rc = int32(SQLITE_NOMEM)
		} else {
			libc.Xmemset(tls, p, 0, libc.Uint32FromInt64(nByte))
			(*TFts5Bm25Data)(unsafe.Pointer(p)).FnPhrase = nPhrase
			(*TFts5Bm25Data)(unsafe.Pointer(p)).FaIDF = p + 1*20
			(*TFts5Bm25Data)(unsafe.Pointer(p)).FaFreq = (*TFts5Bm25Data)(unsafe.Pointer(p)).FaIDF + uintptr(nPhrase)*8
		}
		/* Calculate the average document length for this FTS5 table */
		if rc == SQLITE_OK {
			rc = (*(*func(*libc.TLS, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*TFts5ExtensionApi)(unsafe.Pointer(pApi)).FxRowCount})))(tls, pFts, bp)
		}
		if rc == SQLITE_OK {
			rc = (*(*func(*libc.TLS, uintptr, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*TFts5ExtensionApi)(unsafe.Pointer(pApi)).FxColumnTotalSize})))(tls, pFts, -int32(1), bp+8)
		}
		if rc == SQLITE_OK {
			(*TFts5Bm25Data)(unsafe.Pointer(p)).Favgdl = float64(**(**Tsqlite3_int64)(__ccgo_up(bp + 8))) / float64(**(**Tsqlite3_int64)(__ccgo_up(bp)))
		}
		/* Calculate an IDF for each phrase in the query */
		i = 0
		for {
			if !(rc == SQLITE_OK && i < nPhrase) {
				break
			}
			**(**Tsqlite3_int64)(__ccgo_up(bp + 16)) = 0
			rc = (*(*func(*libc.TLS, uintptr, int32, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*TFts5ExtensionApi)(unsafe.Pointer(pApi)).FxQueryPhrase})))(tls, pFts, i, bp+16, __ccgo_fp(_fts5CountCb))
			if rc == SQLITE_OK {
				/* Calculate the IDF (Inverse Document Frequency) for phrase i.
				 ** This is done using the standard BM25 formula as found on wikipedia:
				 **
				 **   IDF = log( (N - nHit + 0.5) / (nHit + 0.5) )
				 **
				 ** where "N" is the total number of documents in the set and nHit
				 ** is the number that contain at least one instance of the phrase
				 ** under consideration.
				 **
				 ** The problem with this is that if (N < 2*nHit), the IDF is
				 ** negative. Which is undesirable. So the minimum allowable IDF is
				 ** (1e-6) - roughly the same as a term that appears in just over
				 ** half of set of 5,000,000 documents.  */
				idf = libc.Xlog(tls, (float64(**(**Tsqlite3_int64)(__ccgo_up(bp))-**(**Tsqlite3_int64)(__ccgo_up(bp + 16)))+float64(0.5))/(float64(**(**Tsqlite3_int64)(__ccgo_up(bp + 16)))+float64(0.5)))
				if idf <= float64(0) {
					idf = float64(1e-06)
				}
				**(**float64)(__ccgo_up((*TFts5Bm25Data)(unsafe.Pointer(p)).FaIDF + uintptr(i)*8)) = idf
			}
			goto _1
		_1:
			;
			i = i + 1
		}
		if rc != SQLITE_OK {
			Xsqlite3_free(tls, p)
		} else {
			rc = (*(*func(*libc.TLS, uintptr, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*TFts5ExtensionApi)(unsafe.Pointer(pApi)).FxSetAuxdata})))(tls, pFts, p, __ccgo_fp(Xsqlite3_free))
		}
		if rc != SQLITE_OK {
			p = uintptr(0)
		}
	}
	**(**uintptr)(__ccgo_up(ppData)) = p
	return rc
}

// C documentation
//
//	/*
//	** Ensure that the Fts5Cursor.nInstCount and aInst[] variables are populated
//	** correctly for the current view. Return SQLITE_OK if successful, or an
//	** SQLite error code otherwise.
//	*/
func _fts5CacheInstArray(tls *libc.TLS, pCsr uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var aInst, aIter uintptr
	var i, iBest, nCol, nInst, nIter, nNewSize, v3 int32
	var nByte Tsqlite3_int64
	var _ /* a at bp+4 */ uintptr
	var _ /* n at bp+8 */ int32
	var _ /* rc at bp+0 */ int32
	_, _, _, _, _, _, _, _, _, _ = aInst, aIter, i, iBest, nByte, nCol, nInst, nIter, nNewSize, v3
	**(**int32)(__ccgo_up(bp)) = SQLITE_OK /* Number of iterators/phrases */
	nCol = (*TFts5Config)(unsafe.Pointer((*TFts5Table)(unsafe.Pointer((*TFts5Cursor)(unsafe.Pointer(pCsr)).Fbase.FpVtab)).FpConfig)).FnCol
	nIter = _sqlite3Fts5ExprPhraseCount(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpExpr)
	if (*TFts5Cursor)(unsafe.Pointer(pCsr)).FaInstIter == uintptr(0) {
		nByte = libc.Int64FromUint32(uint32(24) * libc.Uint32FromInt32(nIter))
		(*TFts5Cursor)(unsafe.Pointer(pCsr)).FaInstIter = _sqlite3Fts5MallocZero(tls, bp, nByte)
	}
	aIter = (*TFts5Cursor)(unsafe.Pointer(pCsr)).FaInstIter
	if aIter != 0 {
		nInst = 0
		/* Initialize all iterators */
		i = 0
		for {
			if !(i < nIter && **(**int32)(__ccgo_up(bp)) == SQLITE_OK) {
				break
			}
			**(**int32)(__ccgo_up(bp)) = _fts5CsrPoslist(tls, pCsr, i, bp+4, bp+8)
			if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
				_sqlite3Fts5PoslistReaderInit(tls, **(**uintptr)(__ccgo_up(bp + 4)), **(**int32)(__ccgo_up(bp + 8)), aIter+uintptr(i)*24)
			}
			goto _1
		_1:
			;
			i = i + 1
		}
		if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
			for int32(1) != 0 {
				iBest = -int32(1)
				i = 0
				for {
					if !(i < nIter) {
						break
					}
					if libc.Int32FromUint8((**(**TFts5PoslistReader)(__ccgo_up(aIter + uintptr(i)*24))).FbEof) == 0 && (iBest < 0 || (**(**TFts5PoslistReader)(__ccgo_up(aIter + uintptr(i)*24))).FiPos < (**(**TFts5PoslistReader)(__ccgo_up(aIter + uintptr(iBest)*24))).FiPos) {
						iBest = i
					}
					goto _2
				_2:
					;
					i = i + 1
				}
				if iBest < 0 {
					break
				}
				nInst = nInst + 1
				if nInst >= (*TFts5Cursor)(unsafe.Pointer(pCsr)).FnInstAlloc {
					if (*TFts5Cursor)(unsafe.Pointer(pCsr)).FnInstAlloc != 0 {
						v3 = (*TFts5Cursor)(unsafe.Pointer(pCsr)).FnInstAlloc * int32(2)
					} else {
						v3 = int32(32)
					}
					nNewSize = v3
					aInst = Xsqlite3_realloc64(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FaInst, uint64(libc.Uint32FromInt32(nNewSize)*uint32(4)*uint32(3)))
					if aInst != 0 {
						(*TFts5Cursor)(unsafe.Pointer(pCsr)).FaInst = aInst
						(*TFts5Cursor)(unsafe.Pointer(pCsr)).FnInstAlloc = nNewSize
					} else {
						nInst = nInst - 1
						**(**int32)(__ccgo_up(bp)) = int32(SQLITE_NOMEM)
						break
					}
				}
				aInst = (*TFts5Cursor)(unsafe.Pointer(pCsr)).FaInst + uintptr(int32(3)*(nInst-int32(1)))*4
				**(**int32)(__ccgo_up(aInst)) = iBest
				**(**int32)(__ccgo_up(aInst + 1*4)) = int32((**(**TFts5PoslistReader)(__ccgo_up(aIter + uintptr(iBest)*24))).FiPos >> libc.Int32FromInt32(32) & libc.Int64FromInt32(0x7FFFFFFF))
				**(**int32)(__ccgo_up(aInst + 2*4)) = int32((**(**TFts5PoslistReader)(__ccgo_up(aIter + uintptr(iBest)*24))).FiPos & libc.Int64FromInt32(0x7FFFFFFF))
				if **(**int32)(__ccgo_up(aInst + 1*4)) >= nCol {
					**(**int32)(__ccgo_up(bp)) = libc.Int32FromInt32(SQLITE_CORRUPT) | libc.Int32FromInt32(1)<<libc.Int32FromInt32(8)
					break
				}
				_sqlite3Fts5PoslistReaderNext(tls, aIter+uintptr(iBest)*24)
			}
		}
		(*TFts5Cursor)(unsafe.Pointer(pCsr)).FnInstCount = nInst
		**(**int32)(__ccgo_up(pCsr + 56)) &= ^libc.Int32FromInt32(FTS5CSR_REQUIRE_INST)
	}
	return **(**int32)(__ccgo_up(bp))
}

// C documentation
//
//	/*
//	** Close the cursor.  For additional information see the documentation
//	** on the xClose method of the virtual table interface.
//	*/
func _fts5CloseMethod(tls *libc.TLS, pCursor uintptr) (r int32) {
	var pCsr, pTab, pp uintptr
	_, _, _ = pCsr, pTab, pp
	if pCursor != 0 {
		pTab = (*Tsqlite3_vtab_cursor)(unsafe.Pointer(pCursor)).FpVtab
		pCsr = pCursor
		_fts5FreeCursorComponents(tls, pCsr)
		/* Remove the cursor from the Fts5Global.pCsr list */
		pp = (*TFts5FullTable)(unsafe.Pointer(pTab)).FpGlobal + 48
		for {
			if !(**(**uintptr)(__ccgo_up(pp)) != pCsr) {
				break
			}
			goto _1
		_1:
			;
			pp = **(**uintptr)(__ccgo_up(pp)) + 4
		}
		**(**uintptr)(__ccgo_up(pp)) = (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpNext
		Xsqlite3_free(tls, pCsr)
	}
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** Gobble up the first bareword or quoted word from the input buffer zIn.
//	** Return a pointer to the character immediately following the last in
//	** the gobbled word if successful, or a NULL pointer otherwise (failed
//	** to find close-quote character).
//	**
//	** Before returning, set pzOut to point to a new buffer containing a
//	** nul-terminated, dequoted copy of the gobbled word. If the word was
//	** quoted, *pbQuoted is also set to 1 before returning.
//	**
//	** If *pRc is other than SQLITE_OK when this function is called, it is
//	** a no-op (NULL is returned). Otherwise, if an OOM occurs within this
//	** function, *pRc is set to SQLITE_NOMEM before returning. *pRc is *not*
//	** set if a parse error (failed to find close quote) occurs.
//	*/
func _fts5ConfigGobbleWord(tls *libc.TLS, pRc uintptr, zIn uintptr, pzOut uintptr, pbQuoted uintptr) (r uintptr) {
	var ii int32
	var nIn Tsqlite3_int64
	var zOut, zRet uintptr
	_, _, _, _ = ii, nIn, zOut, zRet
	zRet = uintptr(0)
	nIn = libc.Int64FromUint32(libc.Xstrlen(tls, zIn))
	zOut = Xsqlite3_malloc64(tls, libc.Uint64FromInt64(nIn+int64(1)))
	**(**int32)(__ccgo_up(pbQuoted)) = 0
	**(**uintptr)(__ccgo_up(pzOut)) = uintptr(0)
	if zOut == uintptr(0) {
		**(**int32)(__ccgo_up(pRc)) = int32(SQLITE_NOMEM)
	} else {
		libc.Xmemcpy(tls, zOut, zIn, libc.Uint32FromInt64(nIn+libc.Int64FromInt32(1)))
		if _fts5_isopenquote(tls, **(**int8)(__ccgo_up(zOut))) != 0 {
			ii = _fts5Dequote(tls, zOut)
			zRet = zIn + uintptr(ii)
			**(**int32)(__ccgo_up(pbQuoted)) = int32(1)
		} else {
			zRet = _fts5ConfigSkipBareword(tls, zIn)
			if zRet != 0 {
				**(**int8)(__ccgo_up(zOut + uintptr(int32(zRet)-int32(zIn)))) = int8('\000')
			}
		}
	}
	if zRet == uintptr(0) {
		Xsqlite3_free(tls, zOut)
	} else {
		**(**uintptr)(__ccgo_up(pzOut)) = zOut
	}
	return zRet
}

// C documentation
//
//	/*
//	** This function is called after the cursor passed as the only argument
//	** is moved to point at a different row. It clears all cached data
//	** specific to the previous row stored by the cursor object.
//	*/
func _fts5CsrNewrow(tls *libc.TLS, pCsr uintptr) {
	**(**int32)(__ccgo_up(pCsr + 56)) |= libc.Int32FromInt32(FTS5CSR_REQUIRE_CONTENT) | libc.Int32FromInt32(FTS5CSR_REQUIRE_DOCSIZE) | libc.Int32FromInt32(FTS5CSR_REQUIRE_INST) | libc.Int32FromInt32(FTS5CSR_REQUIRE_POSLIST)
}

// C documentation
//
//	/*
//	** This is called by various API functions - xInst, xPhraseFirst,
//	** xPhraseFirstColumn etc. - to obtain the position list for phrase iPhrase
//	** of the current row. This function works for both detail=full tables (in
//	** which case the position-list was read from the fts index) or for other
//	** detail= modes if the row content is available.
//	*/
func _fts5CsrPoslist(tls *libc.TLS, pCsr uintptr, iPhrase int32, pa uintptr, pn uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var aPopulator, pConfig, pSorter uintptr
	var bLive, i, i1, rc, v2 int32
	var _ /* n at bp+4 */ int32
	var _ /* z at bp+0 */ uintptr
	_, _, _, _, _, _, _, _ = aPopulator, bLive, i, i1, pConfig, pSorter, rc, v2
	pConfig = (*TFts5Table)(unsafe.Pointer((*TFts5Cursor)(unsafe.Pointer(pCsr)).Fbase.FpVtab)).FpConfig
	rc = SQLITE_OK
	bLive = libc.BoolInt32((*TFts5Cursor)(unsafe.Pointer(pCsr)).FpSorter == uintptr(0))
	if iPhrase < 0 || iPhrase >= _sqlite3Fts5ExprPhraseCount(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpExpr) {
		rc = int32(SQLITE_RANGE)
	} else {
		if (*TFts5Config)(unsafe.Pointer(pConfig)).FeDetail != FTS5_DETAIL_FULL && _fts5IsContentless(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).Fbase.FpVtab, int32(1)) != 0 {
			**(**uintptr)(__ccgo_up(pa)) = uintptr(0)
			**(**int32)(__ccgo_up(pn)) = 0
			return SQLITE_OK
		} else {
			if (*TFts5Cursor)(unsafe.Pointer(pCsr)).Fcsrflags&int32(FTS5CSR_REQUIRE_POSLIST) != 0 {
				if (*TFts5Config)(unsafe.Pointer(pConfig)).FeDetail != FTS5_DETAIL_FULL {
					aPopulator = _sqlite3Fts5ExprClearPoslists(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpExpr, bLive)
					if aPopulator == uintptr(0) {
						rc = int32(SQLITE_NOMEM)
					}
					if rc == SQLITE_OK {
						rc = _fts5SeekCursor(tls, pCsr, 0)
					}
					i = 0
					for {
						if !(i < (*TFts5Config)(unsafe.Pointer(pConfig)).FnCol && rc == SQLITE_OK) {
							break
						}
						**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
						**(**int32)(__ccgo_up(bp + 4)) = 0
						rc = _fts5TextFromStmt(tls, pConfig, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpStmt, i, bp, bp+4)
						if rc == SQLITE_OK {
							rc = _sqlite3Fts5ExprPopulatePoslists(tls, pConfig, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpExpr, aPopulator, i, **(**uintptr)(__ccgo_up(bp)), **(**int32)(__ccgo_up(bp + 4)))
						}
						_sqlite3Fts5ClearLocale(tls, pConfig)
						goto _1
					_1:
						;
						i = i + 1
					}
					Xsqlite3_free(tls, aPopulator)
					if (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpSorter != 0 {
						_sqlite3Fts5ExprCheckPoslists(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpExpr, (*TFts5Sorter)(unsafe.Pointer((*TFts5Cursor)(unsafe.Pointer(pCsr)).FpSorter)).FiRowid)
					}
				}
				**(**int32)(__ccgo_up(pCsr + 56)) &= ^libc.Int32FromInt32(FTS5CSR_REQUIRE_POSLIST)
			}
		}
	}
	if rc == SQLITE_OK {
		if (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpSorter != 0 && (*TFts5Config)(unsafe.Pointer(pConfig)).FeDetail == FTS5_DETAIL_FULL {
			pSorter = (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpSorter
			if iPhrase == 0 {
				v2 = 0
			} else {
				v2 = *(*int32)(unsafe.Pointer(pSorter + 20 + uintptr(iPhrase-int32(1))*4))
			}
			i1 = v2
			**(**int32)(__ccgo_up(pn)) = *(*int32)(unsafe.Pointer(pSorter + 20 + uintptr(iPhrase)*4)) - i1
			**(**uintptr)(__ccgo_up(pa)) = (*TFts5Sorter)(unsafe.Pointer(pSorter)).FaPoslist + uintptr(i1)
		} else {
			**(**int32)(__ccgo_up(pn)) = _sqlite3Fts5ExprPoslist(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpExpr, iPhrase, pa)
		}
	} else {
		**(**uintptr)(__ccgo_up(pa)) = uintptr(0)
		**(**int32)(__ccgo_up(pn)) = 0
	}
	return rc
}

func _fts5CursorFirst(tls *libc.TLS, pTab uintptr, pCsr uintptr, bDesc int32) (r int32) {
	var pExpr uintptr
	var rc int32
	_, _ = pExpr, rc
	pExpr = (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpExpr
	rc = _sqlite3Fts5ExprFirst(tls, pExpr, (*TFts5FullTable)(unsafe.Pointer(pTab)).Fp.FpIndex, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FiFirstRowid, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FiLastRowid, bDesc)
	if _sqlite3Fts5ExprEof(tls, pExpr) != 0 {
		**(**int32)(__ccgo_up(pCsr + 56)) |= int32(FTS5CSR_EOF)
	}
	_fts5CsrNewrow(tls, pCsr)
	return rc
}

// C documentation
//
//	/*
//	** If the REQUIRE_RESEEK flag is set on the cursor passed as the first
//	** argument, close and reopen all Fts5IndexIter iterators that the cursor
//	** is using. Then attempt to move the cursor to a rowid equal to or laster
//	** (in the cursors sort order - ASC or DESC) than the current rowid.
//	**
//	** If the new rowid is not equal to the old, set output parameter *pbSkip
//	** to 1 before returning. Otherwise, leave it unchanged.
//	**
//	** Return SQLITE_OK if successful or if no reseek was required, or an
//	** error code if an error occurred.
//	*/
func _fts5CursorReseek(tls *libc.TLS, pCsr uintptr, pbSkip uintptr) (r int32) {
	var bDesc, rc int32
	var iRowid Ti64
	var pTab uintptr
	_, _, _, _ = bDesc, iRowid, pTab, rc
	rc = SQLITE_OK
	if (*TFts5Cursor)(unsafe.Pointer(pCsr)).Fcsrflags&int32(FTS5CSR_REQUIRE_RESEEK) != 0 {
		pTab = (*TFts5Cursor)(unsafe.Pointer(pCsr)).Fbase.FpVtab
		bDesc = (*TFts5Cursor)(unsafe.Pointer(pCsr)).FbDesc
		iRowid = _sqlite3Fts5ExprRowid(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpExpr)
		rc = _sqlite3Fts5ExprFirst(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpExpr, (*TFts5FullTable)(unsafe.Pointer(pTab)).Fp.FpIndex, iRowid, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FiLastRowid, bDesc)
		if rc == SQLITE_OK && iRowid != _sqlite3Fts5ExprRowid(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpExpr) {
			**(**int32)(__ccgo_up(pbSkip)) = int32(1)
		}
		**(**int32)(__ccgo_up(pCsr + 56)) &= ^libc.Int32FromInt32(FTS5CSR_REQUIRE_RESEEK)
		_fts5CsrNewrow(tls, pCsr)
		if _sqlite3Fts5ExprEof(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpExpr) != 0 {
			**(**int32)(__ccgo_up(pCsr + 56)) |= int32(FTS5CSR_EOF)
			**(**int32)(__ccgo_up(pbSkip)) = int32(1)
		}
	}
	return rc
}

// C documentation
//
//	/*
//	** The iterator passed as the first argument has the following fields set
//	** as follows. This function sets up the rest of the iterator so that it
//	** points to the first rowid in the doclist-index.
//	**
//	**   pData:
//	**     pointer to doclist-index record,
//	**
//	** When this function is called pIter->iLeafPgno is the page number the
//	** doclist is associated with (the one featuring the term).
//	*/
func _fts5DlidxIterFirst(tls *libc.TLS, pIter uintptr) (r int32) {
	var i int32
	_ = i
	i = 0
	for {
		if !(i < (*TFts5DlidxIter)(unsafe.Pointer(pIter)).FnLvl) {
			break
		}
		_fts5DlidxLvlNext(tls, pIter+8+uintptr(i)*28)
		goto _1
	_1:
		;
		i = i + 1
	}
	return (*(*TFts5DlidxLvl)(unsafe.Pointer(pIter + 8))).FbEof
}

// C documentation
//
//	/*
//	** Free a doclist-index iterator object allocated by fts5DlidxIterInit().
//	*/
func _fts5DlidxIterFree(tls *libc.TLS, pIter uintptr) {
	var i int32
	_ = i
	if pIter != 0 {
		i = 0
		for {
			if !(i < (*TFts5DlidxIter)(unsafe.Pointer(pIter)).FnLvl) {
				break
			}
			_fts5DataRelease(tls, (*(*TFts5DlidxLvl)(unsafe.Pointer(pIter + 8 + uintptr(i)*28))).FpData)
			goto _1
		_1:
			;
			i = i + 1
		}
		Xsqlite3_free(tls, pIter)
	}
}

func _fts5DlidxIterInit(tls *libc.TLS, p uintptr, bRev int32, iSegid int32, iLeafPg int32) (r uintptr) {
	var bDone, i int32
	var iRowid Ti64
	var nByte Tsqlite3_int64
	var pIter, pLvl, pNew uintptr
	_, _, _, _, _, _, _ = bDone, i, iRowid, nByte, pIter, pLvl, pNew
	pIter = uintptr(0)
	bDone = 0
	i = 0
	for {
		if !((*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK && bDone == 0) {
			break
		}
		nByte = libc.Int64FromUint32(uint32(libc.UintptrFromInt32(0)+8) + libc.Uint32FromInt32(i+libc.Int32FromInt32(1))*libc.Uint32FromInt64(28))
		pNew = Xsqlite3_realloc64(tls, pIter, libc.Uint64FromInt64(nByte))
		if pNew == uintptr(0) {
			(*TFts5Index)(unsafe.Pointer(p)).Frc = int32(SQLITE_NOMEM)
		} else {
			iRowid = int64(iSegid)<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B)+libc.Int32FromInt32(FTS5_DATA_DLI_B)) + int64(libc.Int32FromInt32(1))<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B)) + int64(i)<<libc.Int32FromInt32(FTS5_DATA_PAGE_B) + int64(iLeafPg)
			pLvl = pNew + 8 + uintptr(i)*28
			pIter = pNew
			libc.Xmemset(tls, pLvl, 0, uint32(28))
			(*TFts5DlidxLvl)(unsafe.Pointer(pLvl)).FpData = _fts5DataRead(tls, p, iRowid)
			if (*TFts5DlidxLvl)(unsafe.Pointer(pLvl)).FpData != 0 && libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TFts5Data)(unsafe.Pointer((*TFts5DlidxLvl)(unsafe.Pointer(pLvl)).FpData)).Fp)))&int32(0x0001) == 0 {
				bDone = int32(1)
			}
			(*TFts5DlidxIter)(unsafe.Pointer(pIter)).FnLvl = i + int32(1)
		}
		goto _1
	_1:
		;
		i = i + 1
	}
	if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
		(*TFts5DlidxIter)(unsafe.Pointer(pIter)).FiSegid = iSegid
		if bRev == 0 {
			_fts5DlidxIterFirst(tls, pIter)
		} else {
			_fts5DlidxIterLast(tls, p, pIter)
		}
	}
	if (*TFts5Index)(unsafe.Pointer(p)).Frc != SQLITE_OK {
		_fts5DlidxIterFree(tls, pIter)
		pIter = uintptr(0)
	}
	return pIter
}

func _fts5DlidxIterLast(tls *libc.TLS, p uintptr, pIter uintptr) {
	var i int32
	var pChild, pLvl uintptr
	_, _, _ = i, pChild, pLvl
	/* Advance each level to the last entry on the last page */
	i = (*TFts5DlidxIter)(unsafe.Pointer(pIter)).FnLvl - int32(1)
	for {
		if !((*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK && i >= 0) {
			break
		}
		pLvl = pIter + 8 + uintptr(i)*28
		for _fts5DlidxLvlNext(tls, pLvl) == 0 {
		}
		(*TFts5DlidxLvl)(unsafe.Pointer(pLvl)).FbEof = 0
		if i > 0 {
			pChild = pLvl + uintptr(-libc.Int32FromInt32(1))*28
			_fts5DataRelease(tls, (*TFts5DlidxLvl)(unsafe.Pointer(pChild)).FpData)
			libc.Xmemset(tls, pChild, 0, uint32(28))
			(*TFts5DlidxLvl)(unsafe.Pointer(pChild)).FpData = _fts5DataRead(tls, p, int64((*TFts5DlidxIter)(unsafe.Pointer(pIter)).FiSegid)<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B)+libc.Int32FromInt32(FTS5_DATA_DLI_B))+int64(libc.Int32FromInt32(1))<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B))+int64(i-libc.Int32FromInt32(1))<<libc.Int32FromInt32(FTS5_DATA_PAGE_B)+int64((*TFts5DlidxLvl)(unsafe.Pointer(pLvl)).FiLeafPgno))
		}
		goto _1
	_1:
		;
		i = i - 1
	}
}

// C documentation
//
//	/*
//	** Advance the iterator passed as the only argument.
//	*/
func _fts5DlidxIterNextR(tls *libc.TLS, p uintptr, pIter uintptr, iLvl int32) (r int32) {
	var pLvl uintptr
	_ = pLvl
	pLvl = pIter + 8 + uintptr(iLvl)*28
	if _fts5DlidxLvlNext(tls, pLvl) != 0 {
		if iLvl+int32(1) < (*TFts5DlidxIter)(unsafe.Pointer(pIter)).FnLvl {
			_fts5DlidxIterNextR(tls, p, pIter, iLvl+int32(1))
			if (**(**TFts5DlidxLvl)(__ccgo_up(pLvl + 1*28))).FbEof == 0 {
				_fts5DataRelease(tls, (*TFts5DlidxLvl)(unsafe.Pointer(pLvl)).FpData)
				libc.Xmemset(tls, pLvl, 0, uint32(28))
				(*TFts5DlidxLvl)(unsafe.Pointer(pLvl)).FpData = _fts5DataRead(tls, p, int64((*TFts5DlidxIter)(unsafe.Pointer(pIter)).FiSegid)<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B)+libc.Int32FromInt32(FTS5_DATA_DLI_B))+int64(libc.Int32FromInt32(1))<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B))+int64(iLvl)<<libc.Int32FromInt32(FTS5_DATA_PAGE_B)+int64((**(**TFts5DlidxLvl)(__ccgo_up(pLvl + 1*28))).FiLeafPgno))
				if (*TFts5DlidxLvl)(unsafe.Pointer(pLvl)).FpData != 0 {
					_fts5DlidxLvlNext(tls, pLvl)
				}
			}
		}
	}
	return (*(*TFts5DlidxLvl)(unsafe.Pointer(pIter + 8))).FbEof
}

func _fts5DlidxIterPrevR(tls *libc.TLS, p uintptr, pIter uintptr, iLvl int32) (r int32) {
	var pLvl uintptr
	_ = pLvl
	pLvl = pIter + 8 + uintptr(iLvl)*28
	if _fts5DlidxLvlPrev(tls, pLvl) != 0 {
		if iLvl+int32(1) < (*TFts5DlidxIter)(unsafe.Pointer(pIter)).FnLvl {
			_fts5DlidxIterPrevR(tls, p, pIter, iLvl+int32(1))
			if (**(**TFts5DlidxLvl)(__ccgo_up(pLvl + 1*28))).FbEof == 0 {
				_fts5DataRelease(tls, (*TFts5DlidxLvl)(unsafe.Pointer(pLvl)).FpData)
				libc.Xmemset(tls, pLvl, 0, uint32(28))
				(*TFts5DlidxLvl)(unsafe.Pointer(pLvl)).FpData = _fts5DataRead(tls, p, int64((*TFts5DlidxIter)(unsafe.Pointer(pIter)).FiSegid)<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B)+libc.Int32FromInt32(FTS5_DATA_DLI_B))+int64(libc.Int32FromInt32(1))<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B))+int64(iLvl)<<libc.Int32FromInt32(FTS5_DATA_PAGE_B)+int64((**(**TFts5DlidxLvl)(__ccgo_up(pLvl + 1*28))).FiLeafPgno))
				if (*TFts5DlidxLvl)(unsafe.Pointer(pLvl)).FpData != 0 {
					for _fts5DlidxLvlNext(tls, pLvl) == 0 {
					}
					(*TFts5DlidxLvl)(unsafe.Pointer(pLvl)).FbEof = 0
				}
			}
		}
	}
	return (*(*TFts5DlidxLvl)(unsafe.Pointer(pIter + 8))).FbEof
}

// C documentation
//
//	/*
//	** Advance the iterator passed as the only argument. If the end of the
//	** doclist-index page is reached, return non-zero.
//	*/
func _fts5DlidxLvlNext(tls *libc.TLS, pLvl uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var iOff int32
	var pData, v2 uintptr
	var _ /* iVal at bp+0 */ Tu64
	_, _, _ = iOff, pData, v2
	pData = (*TFts5DlidxLvl)(unsafe.Pointer(pLvl)).FpData
	if (*TFts5DlidxLvl)(unsafe.Pointer(pLvl)).FiOff == 0 {
		(*TFts5DlidxLvl)(unsafe.Pointer(pLvl)).FiOff = int32(1)
		**(**int32)(__ccgo_up(pLvl + 4)) += _sqlite3Fts5GetVarint32(tls, (*TFts5Data)(unsafe.Pointer(pData)).Fp+1, pLvl+16)
		**(**int32)(__ccgo_up(pLvl + 4)) += libc.Int32FromUint8(_sqlite3Fts5GetVarint(tls, (*TFts5Data)(unsafe.Pointer(pData)).Fp+uintptr((*TFts5DlidxLvl)(unsafe.Pointer(pLvl)).FiOff), pLvl+20))
		(*TFts5DlidxLvl)(unsafe.Pointer(pLvl)).FiFirstOff = (*TFts5DlidxLvl)(unsafe.Pointer(pLvl)).FiOff
	} else {
		iOff = (*TFts5DlidxLvl)(unsafe.Pointer(pLvl)).FiOff
		for {
			if !(iOff < (*TFts5Data)(unsafe.Pointer(pData)).Fnn) {
				break
			}
			if **(**Tu8)(__ccgo_up((*TFts5Data)(unsafe.Pointer(pData)).Fp + uintptr(iOff))) != 0 {
				break
			}
			goto _1
		_1:
			;
			iOff = iOff + 1
		}
		if iOff < (*TFts5Data)(unsafe.Pointer(pData)).Fnn {
			**(**int32)(__ccgo_up(pLvl + 16)) += iOff - (*TFts5DlidxLvl)(unsafe.Pointer(pLvl)).FiOff + int32(1)
			iOff = iOff + libc.Int32FromUint8(_sqlite3Fts5GetVarint(tls, (*TFts5Data)(unsafe.Pointer(pData)).Fp+uintptr(iOff), bp))
			v2 = pLvl + 20
			*(*Ti64)(unsafe.Pointer(v2)) = Ti64(uint64(*(*Ti64)(unsafe.Pointer(v2))) + **(**Tu64)(__ccgo_up(bp)))
			(*TFts5DlidxLvl)(unsafe.Pointer(pLvl)).FiOff = iOff
		} else {
			(*TFts5DlidxLvl)(unsafe.Pointer(pLvl)).FbEof = int32(1)
		}
	}
	return (*TFts5DlidxLvl)(unsafe.Pointer(pLvl)).FbEof
}

// C documentation
//
//	/*
//	** Move the iterator passed as the only argument to the previous entry.
//	*/
func _fts5DlidxLvlPrev(tls *libc.TLS, pLvl uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var a, v1 uintptr
	var iOff, ii, nZero int32
	var _ /* delta at bp+0 */ Tu64
	_, _, _, _, _ = a, iOff, ii, nZero, v1
	iOff = (*TFts5DlidxLvl)(unsafe.Pointer(pLvl)).FiOff
	if iOff <= (*TFts5DlidxLvl)(unsafe.Pointer(pLvl)).FiFirstOff {
		(*TFts5DlidxLvl)(unsafe.Pointer(pLvl)).FbEof = int32(1)
	} else {
		a = (*TFts5Data)(unsafe.Pointer((*TFts5DlidxLvl)(unsafe.Pointer(pLvl)).FpData)).Fp
		(*TFts5DlidxLvl)(unsafe.Pointer(pLvl)).FiOff = 0
		_fts5DlidxLvlNext(tls, pLvl)
		for int32(1) != 0 {
			nZero = 0
			ii = (*TFts5DlidxLvl)(unsafe.Pointer(pLvl)).FiOff
			**(**Tu64)(__ccgo_up(bp)) = uint64(0)
			for libc.Int32FromUint8(**(**Tu8)(__ccgo_up(a + uintptr(ii)))) == 0 {
				nZero = nZero + 1
				ii = ii + 1
			}
			ii = ii + libc.Int32FromUint8(_sqlite3Fts5GetVarint(tls, a+uintptr(ii), bp))
			if ii >= iOff {
				break
			}
			**(**int32)(__ccgo_up(pLvl + 16)) += nZero + int32(1)
			v1 = pLvl + 20
			*(*Ti64)(unsafe.Pointer(v1)) = Ti64(uint64(*(*Ti64)(unsafe.Pointer(v1))) + **(**Tu64)(__ccgo_up(bp)))
			(*TFts5DlidxLvl)(unsafe.Pointer(pLvl)).FiOff = ii
		}
	}
	return (*TFts5DlidxLvl)(unsafe.Pointer(pLvl)).FbEof
}

// C documentation
//
//	/*
//	** Completely remove the entry that pSeg currently points to from
//	** the database.
//	*/
func _fts5DoSecureDelete(tls *libc.TLS, p uintptr, pSeg uintptr) {
	bp := tls.Alloc(80)
	defer tls.Free(80)
	var aIdx, aPg, aTermIdx, pPg, pTerm uintptr
	var bDetailNone, bEmpty, iDelKeyOff, iIdx, iKey, iKeyIn, iKeyOff, iKeyOff1, iKeyOut, iNextOff, iOff, iPgIdx, iPgno, iPrevKeyOut, iSOP, iSegid, iStart, iTermIdx, nByte, nIdx, nMove, nPg, nShift, nTermIdx, pgno, v2 int32
	var iId, iTermOff Ti64
	var v5 uint64
	var _ /* bLastInDoclist at bp+8 */ int32
	var _ /* iDelta at bp+0 */ Tu64
	var _ /* iNextDelta at bp+24 */ Tu64
	var _ /* iVal at bp+16 */ Tu32
	var _ /* iVal at bp+32 */ Tu32
	var _ /* iVal at bp+72 */ Tu32
	var _ /* iVal at bp+76 */ Tu32
	var _ /* nPos at bp+12 */ int32
	var _ /* nPrefix at bp+40 */ Tu64
	var _ /* nPrefix2 at bp+56 */ Tu64
	var _ /* nSuffix at bp+48 */ Tu64
	var _ /* nSuffix2 at bp+64 */ Tu64
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = aIdx, aPg, aTermIdx, bDetailNone, bEmpty, iDelKeyOff, iId, iIdx, iKey, iKeyIn, iKeyOff, iKeyOff1, iKeyOut, iNextOff, iOff, iPgIdx, iPgno, iPrevKeyOut, iSOP, iSegid, iStart, iTermIdx, iTermOff, nByte, nIdx, nMove, nPg, nShift, nTermIdx, pPg, pTerm, pgno, v2, v5
	bDetailNone = libc.BoolInt32((*TFts5Config)(unsafe.Pointer((*TFts5Index)(unsafe.Pointer(p)).FpConfig)).FeDetail == libc.Int32FromInt32(FTS5_DETAIL_NONE))
	iSegid = (*TFts5StructureSegment)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pSeg)).FpSeg)).FiSegid
	aPg = (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pSeg)).FpLeaf)).Fp
	nPg = (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pSeg)).FpLeaf)).Fnn
	iPgIdx = (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pSeg)).FpLeaf)).FszLeaf /* Offset of page footer */
	**(**Tu64)(__ccgo_up(bp)) = uint64(0)
	iNextOff = 0
	iOff = 0
	nIdx = 0
	aIdx = uintptr(0)
	**(**int32)(__ccgo_up(bp + 8)) = 0
	iIdx = 0
	iStart = 0
	iDelKeyOff = 0 /* Offset of deleted key, if any */
	nIdx = nPg - iPgIdx
	aIdx = _sqlite3Fts5MallocZero(tls, p+40, int64(nIdx)+int64(16))
	if (*TFts5Index)(unsafe.Pointer(p)).Frc != 0 {
		return
	}
	libc.Xmemcpy(tls, aIdx, aPg+uintptr(iPgIdx), libc.Uint32FromInt32(nIdx))
	/* At this point segment iterator pSeg points to the entry
	 ** this function should remove from the b-tree segment.
	 **
	 ** In detail=full or detail=column mode, pSeg->iLeafOffset is the
	 ** offset of the first byte in the position-list for the entry to
	 ** remove. Immediately before this comes two varints that will also
	 ** need to be removed:
	 **
	 **     + the rowid or delta rowid value for the entry, and
	 **     + the size of the position list in bytes.
	 **
	 ** Or, in detail=none mode, there is a single varint prior to
	 ** pSeg->iLeafOffset - the rowid or delta rowid value.
	 **
	 ** This block sets the following variables:
	 **
	 **   iStart:
	 **     The offset of the first byte of the rowid or delta-rowid
	 **     value for the doclist entry being removed.
	 **
	 **   iDelta:
	 **     The value of the rowid or delta-rowid value for the doclist
	 **     entry being removed.
	 **
	 **   iNextOff:
	 **     The offset of the next entry following the position list
	 **     for the one being removed. If the position list for this
	 **     entry overflows onto the next leaf page, this value will be
	 **     greater than pLeaf->szLeaf.
	 */
	/* Start-Of-Position-list */
	if (*TFts5SegIter)(unsafe.Pointer(pSeg)).FiLeafPgno == (*TFts5SegIter)(unsafe.Pointer(pSeg)).FiTermLeafPgno {
		iStart = (*TFts5SegIter)(unsafe.Pointer(pSeg)).FiTermLeafOffset
	} else {
		iStart = libc.Int32FromUint16(_fts5GetU16(tls, aPg))
	}
	if iStart > nPg {
		_fts5IndexCorruptIdx(tls, p)
		Xsqlite3_free(tls, aIdx)
		return
	}
	iSOP = iStart + libc.Int32FromUint8(_sqlite3Fts5GetVarint(tls, aPg+uintptr(iStart), bp))
	if bDetailNone != 0 {
		for int64(iSOP) < (*TFts5SegIter)(unsafe.Pointer(pSeg)).FiLeafOffset {
			if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aPg + uintptr(iSOP)))) == 0x00 {
				iSOP = iSOP + 1
			}
			if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aPg + uintptr(iSOP)))) == 0x00 {
				iSOP = iSOP + 1
			}
			iStart = iSOP
			iSOP = iStart + libc.Int32FromUint8(_sqlite3Fts5GetVarint(tls, aPg+uintptr(iStart), bp))
		}
		iNextOff = iSOP
		if iNextOff < (*TFts5SegIter)(unsafe.Pointer(pSeg)).FiEndofDoclist && libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aPg + uintptr(iNextOff)))) == 0x00 {
			iNextOff = iNextOff + 1
		}
		if iNextOff < (*TFts5SegIter)(unsafe.Pointer(pSeg)).FiEndofDoclist && libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aPg + uintptr(iNextOff)))) == 0x00 {
			iNextOff = iNextOff + 1
		}
	} else {
		**(**int32)(__ccgo_up(bp + 12)) = 0
		iSOP = iSOP + _sqlite3Fts5GetVarint32(tls, aPg+uintptr(iSOP), bp+12)
		for int64(iSOP) < (*TFts5SegIter)(unsafe.Pointer(pSeg)).FiLeafOffset {
			iStart = iSOP + **(**int32)(__ccgo_up(bp + 12))/int32(2)
			iSOP = iStart + libc.Int32FromUint8(_sqlite3Fts5GetVarint(tls, aPg+uintptr(iStart), bp))
			iSOP = iSOP + _sqlite3Fts5GetVarint32(tls, aPg+uintptr(iSOP), bp+12)
		}
		iNextOff = iSOP + (*TFts5SegIter)(unsafe.Pointer(pSeg)).FnPos
	}
	iOff = iStart
	/* If the position-list for the entry being removed flows over past
	 ** the end of this page, delete the portion of the position-list on the
	 ** next page and beyond.
	 **
	 ** Set variable bLastInDoclist to true if this entry happens
	 ** to be the last rowid in the doclist for its term.  */
	if iNextOff >= iPgIdx {
		pgno = (*TFts5SegIter)(unsafe.Pointer(pSeg)).FiLeafPgno + int32(1)
		_fts5SecureDeleteOverflow(tls, p, (*TFts5SegIter)(unsafe.Pointer(pSeg)).FpSeg, pgno, bp+8)
		iNextOff = iPgIdx
	}
	if libc.Int32FromUint8((*TFts5SegIter)(unsafe.Pointer(pSeg)).FbDel) == 0 {
		if iNextOff != iPgIdx {
			/* Loop through the page-footer. If iNextOff (offset of the
			 ** entry following the one we are removing) is equal to the
			 ** offset of a key on this page, then the entry is the last
			 ** in its doclist. */
			iKeyOff = 0
			iIdx = 0
			for {
				if !(iIdx < nIdx) {
					break
				}
				**(**Tu32)(__ccgo_up(bp + 16)) = uint32(0)
				iIdx = iIdx + _sqlite3Fts5GetVarint32(tls, aIdx+uintptr(iIdx), bp+16)
				iKeyOff = libc.Int32FromUint32(uint32(iKeyOff) + **(**Tu32)(__ccgo_up(bp + 16)))
				if iKeyOff == iNextOff {
					**(**int32)(__ccgo_up(bp + 8)) = int32(1)
				}
				goto _1
			_1:
			}
		}
		/* If this is (a) the first rowid on a page and (b) is not followed by
		 ** another position list on the same page, set the "first-rowid" field
		 ** of the header to 0.  */
		if libc.Int32FromUint16(_fts5GetU16(tls, aPg)) == iStart && (**(**int32)(__ccgo_up(bp + 8)) != 0 || iNextOff == iPgIdx) {
			_fts5PutU16(tls, aPg, uint16(0))
		}
	}
	if (*TFts5SegIter)(unsafe.Pointer(pSeg)).FbDel != 0 {
		iOff = iOff + _sqlite3Fts5PutVarint(tls, aPg+uintptr(iOff), **(**Tu64)(__ccgo_up(bp)))
		v2 = iOff
		iOff = iOff + 1
		**(**Tu8)(__ccgo_up(aPg + uintptr(v2))) = uint8(0x01)
	} else {
		if **(**int32)(__ccgo_up(bp + 8)) == 0 {
			if iNextOff != iPgIdx {
				**(**Tu64)(__ccgo_up(bp + 24)) = uint64(0)
				iNextOff = iNextOff + libc.Int32FromUint8(_sqlite3Fts5GetVarint(tls, aPg+uintptr(iNextOff), bp+24))
				iOff = iOff + _sqlite3Fts5PutVarint(tls, aPg+uintptr(iOff), **(**Tu64)(__ccgo_up(bp))+**(**Tu64)(__ccgo_up(bp + 24)))
			}
		} else {
			if (*TFts5SegIter)(unsafe.Pointer(pSeg)).FiLeafPgno == (*TFts5SegIter)(unsafe.Pointer(pSeg)).FiTermLeafPgno && iStart == (*TFts5SegIter)(unsafe.Pointer(pSeg)).FiTermLeafOffset {
				/* The entry being removed was the only position list in its
				 ** doclist. Therefore the term needs to be removed as well. */
				iKey = 0
				iKeyOff1 = 0
				/* Set iKeyOff to the offset of the term that will be removed - the
				 ** last offset in the footer that is not greater than iStart. */
				iIdx = 0
				for {
					if !(iIdx < nIdx) {
						break
					}
					**(**Tu32)(__ccgo_up(bp + 32)) = uint32(0)
					iIdx = iIdx + _sqlite3Fts5GetVarint32(tls, aIdx+uintptr(iIdx), bp+32)
					if libc.Uint32FromInt32(iKeyOff1)+**(**Tu32)(__ccgo_up(bp + 32)) > libc.Uint32FromInt32(iStart) {
						break
					}
					iKeyOff1 = libc.Int32FromUint32(uint32(iKeyOff1) + **(**Tu32)(__ccgo_up(bp + 32)))
					goto _3
				_3:
					;
					iKey = iKey + 1
				}
				/* Set iDelKeyOff to the value of the footer entry to remove from
				 ** the page. */
				v2 = iKeyOff1
				iOff = v2
				iDelKeyOff = v2
				if iNextOff != iPgIdx {
					/* This is the only position-list associated with the term, and there
					 ** is another term following it on this page. So the subsequent term
					 ** needs to be moved to replace the term associated with the entry
					 ** being removed. */
					**(**Tu64)(__ccgo_up(bp + 40)) = uint64(0)
					**(**Tu64)(__ccgo_up(bp + 48)) = uint64(0)
					**(**Tu64)(__ccgo_up(bp + 56)) = uint64(0)
					**(**Tu64)(__ccgo_up(bp + 64)) = uint64(0)
					iDelKeyOff = iNextOff
					iNextOff = iNextOff + libc.Int32FromUint8(_sqlite3Fts5GetVarint(tls, aPg+uintptr(iNextOff), bp+56))
					iNextOff = iNextOff + libc.Int32FromUint8(_sqlite3Fts5GetVarint(tls, aPg+uintptr(iNextOff), bp+64))
					if iKey != int32(1) {
						iKeyOff1 = iKeyOff1 + libc.Int32FromUint8(_sqlite3Fts5GetVarint(tls, aPg+uintptr(iKeyOff1), bp+40))
					}
					iKeyOff1 = iKeyOff1 + libc.Int32FromUint8(_sqlite3Fts5GetVarint(tls, aPg+uintptr(iKeyOff1), bp+48))
					if **(**Tu64)(__ccgo_up(bp + 40)) < **(**Tu64)(__ccgo_up(bp + 56)) {
						v5 = **(**Tu64)(__ccgo_up(bp + 40))
					} else {
						v5 = **(**Tu64)(__ccgo_up(bp + 56))
					}
					**(**Tu64)(__ccgo_up(bp + 40)) = v5
					**(**Tu64)(__ccgo_up(bp + 48)) = **(**Tu64)(__ccgo_up(bp + 56)) + **(**Tu64)(__ccgo_up(bp + 64)) - **(**Tu64)(__ccgo_up(bp + 40))
					if libc.Uint64FromInt32(iKeyOff1)+**(**Tu64)(__ccgo_up(bp + 48)) > libc.Uint64FromInt32(iPgIdx) || libc.Uint64FromInt32(iNextOff)+**(**Tu64)(__ccgo_up(bp + 64)) > libc.Uint64FromInt32(iPgIdx) {
						_fts5IndexCorruptIdx(tls, p)
					} else {
						if iKey != int32(1) {
							iOff = iOff + _sqlite3Fts5PutVarint(tls, aPg+uintptr(iOff), **(**Tu64)(__ccgo_up(bp + 40)))
						}
						iOff = iOff + _sqlite3Fts5PutVarint(tls, aPg+uintptr(iOff), **(**Tu64)(__ccgo_up(bp + 48)))
						if **(**Tu64)(__ccgo_up(bp + 56)) > libc.Uint64FromInt32((*TFts5SegIter)(unsafe.Pointer(pSeg)).Fterm.Fn) {
							_fts5IndexCorruptIdx(tls, p)
						} else {
							if **(**Tu64)(__ccgo_up(bp + 56)) > **(**Tu64)(__ccgo_up(bp + 40)) {
								libc.Xmemcpy(tls, aPg+uintptr(iOff), (*TFts5SegIter)(unsafe.Pointer(pSeg)).Fterm.Fp+uintptr(**(**Tu64)(__ccgo_up(bp + 40))), uint32(**(**Tu64)(__ccgo_up(bp + 56))-**(**Tu64)(__ccgo_up(bp + 40))))
								iOff = libc.Int32FromUint64(uint64(iOff) + (**(**Tu64)(__ccgo_up(bp + 56)) - **(**Tu64)(__ccgo_up(bp + 40))))
							}
						}
						libc.Xmemmove(tls, aPg+uintptr(iOff), aPg+uintptr(iNextOff), uint32(**(**Tu64)(__ccgo_up(bp + 64))))
						iOff = libc.Int32FromUint64(uint64(iOff) + **(**Tu64)(__ccgo_up(bp + 64)))
						iNextOff = libc.Int32FromUint64(uint64(iNextOff) + **(**Tu64)(__ccgo_up(bp + 64)))
					}
				}
			} else {
				if iStart == int32(4) {
					/* The entry being removed may be the only position list in
					 ** its doclist. */
					iPgno = (*TFts5SegIter)(unsafe.Pointer(pSeg)).FiLeafPgno - int32(1)
					for {
						if !(iPgno > (*TFts5SegIter)(unsafe.Pointer(pSeg)).FiTermLeafPgno) {
							break
						}
						pPg = _fts5DataRead(tls, p, int64(iSegid)<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B)+libc.Int32FromInt32(FTS5_DATA_DLI_B))+int64(libc.Int32FromInt32(0))<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B))+int64(libc.Int32FromInt32(0))<<libc.Int32FromInt32(FTS5_DATA_PAGE_B)+int64(iPgno))
						bEmpty = libc.BoolInt32(pPg != 0 && (*TFts5Data)(unsafe.Pointer(pPg)).Fnn == int32(4))
						_fts5DataRelease(tls, pPg)
						if bEmpty == 0 {
							break
						}
						goto _6
					_6:
						;
						iPgno = iPgno - 1
					}
					if iPgno == (*TFts5SegIter)(unsafe.Pointer(pSeg)).FiTermLeafPgno {
						iId = int64(iSegid)<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B)+libc.Int32FromInt32(FTS5_DATA_DLI_B)) + int64(libc.Int32FromInt32(0))<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B)) + int64(libc.Int32FromInt32(0))<<libc.Int32FromInt32(FTS5_DATA_PAGE_B) + int64((*TFts5SegIter)(unsafe.Pointer(pSeg)).FiTermLeafPgno)
						pTerm = _fts5DataRead(tls, p, iId)
						if pTerm != 0 && (*TFts5Data)(unsafe.Pointer(pTerm)).FszLeaf == (*TFts5SegIter)(unsafe.Pointer(pSeg)).FiTermLeafOffset {
							aTermIdx = (*TFts5Data)(unsafe.Pointer(pTerm)).Fp + uintptr((*TFts5Data)(unsafe.Pointer(pTerm)).FszLeaf)
							nTermIdx = (*TFts5Data)(unsafe.Pointer(pTerm)).Fnn - (*TFts5Data)(unsafe.Pointer(pTerm)).FszLeaf
							iTermIdx = 0
							iTermOff = 0
							for int32(1) != 0 {
								**(**Tu32)(__ccgo_up(bp + 72)) = uint32(0)
								nByte = _sqlite3Fts5GetVarint32(tls, aTermIdx+uintptr(iTermIdx), bp+72)
								iTermOff = iTermOff + libc.Int64FromUint32(**(**Tu32)(__ccgo_up(bp + 72)))
								if iTermIdx+nByte >= nTermIdx {
									break
								}
								iTermIdx = iTermIdx + nByte
							}
							nTermIdx = iTermIdx
							if iTermOff > int64((*TFts5Data)(unsafe.Pointer(pTerm)).FszLeaf) {
								_fts5IndexCorruptIdx(tls, p)
							} else {
								libc.Xmemmove(tls, (*TFts5Data)(unsafe.Pointer(pTerm)).Fp+uintptr(iTermOff), (*TFts5Data)(unsafe.Pointer(pTerm)).Fp+uintptr((*TFts5Data)(unsafe.Pointer(pTerm)).FszLeaf), libc.Uint32FromInt32(nTermIdx))
								_fts5PutU16(tls, (*TFts5Data)(unsafe.Pointer(pTerm)).Fp+2, libc.Uint16FromInt64(iTermOff))
								_fts5DataWrite(tls, p, iId, (*TFts5Data)(unsafe.Pointer(pTerm)).Fp, int32(iTermOff+int64(nTermIdx)))
								if nTermIdx == 0 {
									_fts5SecureDeleteIdxEntry(tls, p, iSegid, (*TFts5SegIter)(unsafe.Pointer(pSeg)).FiTermLeafPgno)
								}
							}
						}
						_fts5DataRelease(tls, pTerm)
					}
				}
			}
		}
	}
	/* Assuming no error has occurred, this block does final edits to the
	 ** leaf page before writing it back to disk. Input variables are:
	 **
	 **   nPg: Total initial size of leaf page.
	 **   iPgIdx: Initial offset of page footer.
	 **
	 **   iOff: Offset to move data to
	 **   iNextOff: Offset to move data from
	 */
	if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
		nMove = nPg - iNextOff   /* Number of bytes to move */
		nShift = iNextOff - iOff /* Distance to move them */
		iPrevKeyOut = 0
		iKeyIn = 0
		if nMove > 0 {
			libc.Xmemmove(tls, aPg+uintptr(iOff), aPg+uintptr(iNextOff), libc.Uint32FromInt32(nMove))
		}
		iPgIdx = iPgIdx - nShift
		nPg = iPgIdx
		_fts5PutU16(tls, aPg+2, libc.Uint16FromInt32(iPgIdx))
		iIdx = 0
		for {
			if !(iIdx < nIdx) {
				break
			}
			**(**Tu32)(__ccgo_up(bp + 76)) = uint32(0)
			iIdx = iIdx + _sqlite3Fts5GetVarint32(tls, aIdx+uintptr(iIdx), bp+76)
			iKeyIn = libc.Int32FromUint32(uint32(iKeyIn) + **(**Tu32)(__ccgo_up(bp + 76)))
			if iKeyIn != iDelKeyOff {
				if iKeyIn > iOff {
					v2 = nShift
				} else {
					v2 = 0
				}
				iKeyOut = iKeyIn - v2
				nPg = nPg + _sqlite3Fts5PutVarint(tls, aPg+uintptr(nPg), libc.Uint64FromInt32(iKeyOut-iPrevKeyOut))
				iPrevKeyOut = iKeyOut
			}
			goto _7
		_7:
		}
		if iPgIdx == nPg && nIdx > 0 && (*TFts5SegIter)(unsafe.Pointer(pSeg)).FiLeafPgno != int32(1) {
			_fts5SecureDeleteIdxEntry(tls, p, iSegid, (*TFts5SegIter)(unsafe.Pointer(pSeg)).FiLeafPgno)
		}
		_fts5DataWrite(tls, p, int64(iSegid)<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B)+libc.Int32FromInt32(FTS5_DATA_DLI_B))+int64(libc.Int32FromInt32(0))<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B))+int64(libc.Int32FromInt32(0))<<libc.Int32FromInt32(FTS5_DATA_PAGE_B)+int64((*TFts5SegIter)(unsafe.Pointer(pSeg)).FiLeafPgno), aPg, nPg)
	}
	Xsqlite3_free(tls, aIdx)
}

func _fts5DoclistIterInit(tls *libc.TLS, pBuf uintptr, pIter uintptr) {
	libc.Xmemset(tls, pIter, 0, uint32(24))
	if (*TFts5Buffer)(unsafe.Pointer(pBuf)).Fn > 0 {
		(*TFts5DoclistIter)(unsafe.Pointer(pIter)).FaPoslist = (*TFts5Buffer)(unsafe.Pointer(pBuf)).Fp
		(*TFts5DoclistIter)(unsafe.Pointer(pIter)).FaEof = (*TFts5Buffer)(unsafe.Pointer(pBuf)).Fp + uintptr((*TFts5Buffer)(unsafe.Pointer(pBuf)).Fn)
		_fts5DoclistIterNext(tls, pIter)
	}
}

func _fts5DoclistIterNext(tls *libc.TLS, pIter uintptr) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var p uintptr
	var _ /* iDelta at bp+0 */ Ti64
	var _ /* nPos at bp+8 */ int32
	_ = p
	p = (*TFts5DoclistIter)(unsafe.Pointer(pIter)).FaPoslist + uintptr((*TFts5DoclistIter)(unsafe.Pointer(pIter)).FnSize) + uintptr((*TFts5DoclistIter)(unsafe.Pointer(pIter)).FnPoslist)
	if p >= (*TFts5DoclistIter)(unsafe.Pointer(pIter)).FaEof {
		(*TFts5DoclistIter)(unsafe.Pointer(pIter)).FaPoslist = uintptr(0)
	} else {
		p = p + uintptr(_sqlite3Fts5GetVarint(tls, p, bp))
		**(**Ti64)(__ccgo_up(pIter + 4)) += **(**Ti64)(__ccgo_up(bp))
		/* Read position list size */
		if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(p)))&int32(0x80) != 0 {
			(*TFts5DoclistIter)(unsafe.Pointer(pIter)).FnSize = _sqlite3Fts5GetVarint32(tls, p, bp+8)
			(*TFts5DoclistIter)(unsafe.Pointer(pIter)).FnPoslist = **(**int32)(__ccgo_up(bp + 8)) >> int32(1)
		} else {
			(*TFts5DoclistIter)(unsafe.Pointer(pIter)).FnPoslist = libc.Int32FromUint8(**(**Tu8)(__ccgo_up(p))) >> int32(1)
			(*TFts5DoclistIter)(unsafe.Pointer(pIter)).FnSize = int32(1)
		}
		(*TFts5DoclistIter)(unsafe.Pointer(pIter)).FaPoslist = p
		if (*TFts5DoclistIter)(unsafe.Pointer(pIter)).FaPoslist+uintptr((*TFts5DoclistIter)(unsafe.Pointer(pIter)).FnPoslist) > (*TFts5DoclistIter)(unsafe.Pointer(pIter)).FaEof {
			(*TFts5DoclistIter)(unsafe.Pointer(pIter)).FaPoslist = uintptr(0)
		}
	}
}

// C documentation
//
//	/*
//	** Add pSub as a child of p.
//	*/
func _fts5ExprAddChildren(tls *libc.TLS, p uintptr, pSub uintptr) {
	var ii, nByte, v1 int32
	var v2 uintptr
	_, _, _, _ = ii, nByte, v1, v2
	ii = (*TFts5ExprNode)(unsafe.Pointer(p)).FnChild
	if (*TFts5ExprNode)(unsafe.Pointer(p)).FeType != int32(FTS5_NOT) && (*TFts5ExprNode)(unsafe.Pointer(pSub)).FeType == (*TFts5ExprNode)(unsafe.Pointer(p)).FeType {
		nByte = libc.Int32FromUint32(uint32(4) * libc.Uint32FromInt32((*TFts5ExprNode)(unsafe.Pointer(pSub)).FnChild))
		libc.Xmemcpy(tls, p+36+uintptr((*TFts5ExprNode)(unsafe.Pointer(p)).FnChild)*4, pSub+36, libc.Uint32FromInt32(nByte))
		**(**int32)(__ccgo_up(p + 32)) += (*TFts5ExprNode)(unsafe.Pointer(pSub)).FnChild
		Xsqlite3_free(tls, pSub)
	} else {
		v2 = p + 32
		v1 = *(*int32)(unsafe.Pointer(v2))
		*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1
		*(*uintptr)(unsafe.Pointer(p + 36 + uintptr(v1)*4)) = pSub
	}
	for {
		if !(ii < (*TFts5ExprNode)(unsafe.Pointer(p)).FnChild) {
			break
		}
		if (*TFts5ExprNode)(unsafe.Pointer(p)).FiHeight > (*TFts5ExprNode)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(p + 36 + uintptr(ii)*4)))).FiHeight+int32(1) {
			v1 = (*TFts5ExprNode)(unsafe.Pointer(p)).FiHeight
		} else {
			v1 = (*TFts5ExprNode)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(p + 36 + uintptr(ii)*4)))).FiHeight + int32(1)
		}
		(*TFts5ExprNode)(unsafe.Pointer(p)).FiHeight = v1
		goto _3
	_3:
		;
		ii = ii + 1
	}
}

func _fts5ExprCheckPoslists(tls *libc.TLS, pNode uintptr, iRowid Ti64) (r int32) {
	var bRet, i, i1 int32
	_, _, _ = bRet, i, i1
	(*TFts5ExprNode)(unsafe.Pointer(pNode)).FiRowid = iRowid
	(*TFts5ExprNode)(unsafe.Pointer(pNode)).FbEof = 0
	switch (*TFts5ExprNode)(unsafe.Pointer(pNode)).FeType {
	case 0:
		fallthrough
	case int32(FTS5_TERM):
		fallthrough
	case int32(FTS5_STRING):
		return libc.BoolInt32((*TFts5ExprPhrase)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer((*TFts5ExprNode)(unsafe.Pointer(pNode)).FpNear + 12)))).Fposlist.Fn > 0)
	case int32(FTS5_AND):
		i = 0
		for {
			if !(i < (*TFts5ExprNode)(unsafe.Pointer(pNode)).FnChild) {
				break
			}
			if _fts5ExprCheckPoslists(tls, *(*uintptr)(unsafe.Pointer(pNode + 36 + uintptr(i)*4)), iRowid) == 0 {
				_fts5ExprClearPoslists(tls, pNode)
				return 0
			}
			goto _1
		_1:
			;
			i = i + 1
		}
	case int32(FTS5_OR):
		bRet = 0
		i1 = 0
		for {
			if !(i1 < (*TFts5ExprNode)(unsafe.Pointer(pNode)).FnChild) {
				break
			}
			if _fts5ExprCheckPoslists(tls, *(*uintptr)(unsafe.Pointer(pNode + 36 + uintptr(i1)*4)), iRowid) != 0 {
				bRet = int32(1)
			}
			goto _2
		_2:
			;
			i1 = i1 + 1
		}
		return bRet
	default:
		if 0 == _fts5ExprCheckPoslists(tls, *(*uintptr)(unsafe.Pointer(pNode + 36)), iRowid) || 0 != _fts5ExprCheckPoslists(tls, *(*uintptr)(unsafe.Pointer(pNode + 36 + 1*4)), iRowid) {
			_fts5ExprClearPoslists(tls, pNode)
			return 0
		}
		break
	}
	return int32(1)
}

func _fts5ExprClearPoslists(tls *libc.TLS, pNode uintptr) {
	var i int32
	_ = i
	if (*TFts5ExprNode)(unsafe.Pointer(pNode)).FeType == int32(FTS5_TERM) || (*TFts5ExprNode)(unsafe.Pointer(pNode)).FeType == int32(FTS5_STRING) {
		(*TFts5ExprPhrase)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer((*TFts5ExprNode)(unsafe.Pointer(pNode)).FpNear + 12)))).Fposlist.Fn = 0
	} else {
		i = 0
		for {
			if !(i < (*TFts5ExprNode)(unsafe.Pointer(pNode)).FnChild) {
				break
			}
			_fts5ExprClearPoslists(tls, *(*uintptr)(unsafe.Pointer(pNode + 36 + uintptr(i)*4)))
			goto _1
		_1:
			;
			i = i + 1
		}
	}
}

// C documentation
//
//	/*
//	** The near-set object passed as the first argument contains more than
//	** one phrase. All phrases currently point to the same row. The
//	** Fts5ExprPhrase.poslist buffers are populated accordingly. This function
//	** tests if the current row contains instances of each phrase sufficiently
//	** close together to meet the NEAR constraint. Non-zero is returned if it
//	** does, or zero otherwise.
//	**
//	** If in/out parameter (*pRc) is set to other than SQLITE_OK when this
//	** function is called, it is a no-op. Or, if an error (e.g. SQLITE_NOMEM)
//	** occurs within this function (*pRc) is set accordingly before returning.
//	** The return value is undefined in both these cases.
//	**
//	** If no error occurs and non-zero (a match) is returned, the position-list
//	** of each phrase object is edited to contain only those entries that
//	** meet the constraint before returning.
//	*/
func _fts5ExprNearIsMatch(tls *libc.TLS, pRc uintptr, pNear uintptr) (r int32) {
	bp := tls.Alloc(176)
	defer tls.Free(176)
	var a, apPhrase, pPos, pPoslist, pWriter uintptr
	var bMatch, bRet, i, iAdv int32
	var iMax, iMin, iPos Ti64
	var nByte Tsqlite3_int64
	var _ /* aStatic at bp+0 */ [4]TFts5NearTrimmer
	var _ /* rc at bp+160 */ int32
	_, _, _, _, _, _, _, _, _, _, _, _, _ = a, apPhrase, bMatch, bRet, i, iAdv, iMax, iMin, iPos, nByte, pPos, pPoslist, pWriter
	a = bp
	apPhrase = pNear + 12
	**(**int32)(__ccgo_up(bp + 160)) = **(**int32)(__ccgo_up(pRc))
	/* If the aStatic[] array is not large enough, allocate a large array
	 ** using sqlite3_malloc(). This approach could be improved upon. */
	if (*TFts5ExprNearset)(unsafe.Pointer(pNear)).FnPhrase > libc.Int32FromUint32(libc.Uint32FromInt64(160)/libc.Uint32FromInt64(40)) {
		nByte = libc.Int64FromUint32(uint32(40) * libc.Uint32FromInt32((*TFts5ExprNearset)(unsafe.Pointer(pNear)).FnPhrase))
		a = _sqlite3Fts5MallocZero(tls, bp+160, nByte)
	} else {
		libc.Xmemset(tls, bp, 0, uint32(160))
	}
	if **(**int32)(__ccgo_up(bp + 160)) != SQLITE_OK {
		**(**int32)(__ccgo_up(pRc)) = **(**int32)(__ccgo_up(bp + 160))
		return 0
	}
	/* Initialize a lookahead iterator for each phrase. After passing the
	 ** buffer and buffer size to the lookaside-reader init function, zero
	 ** the phrase poslist buffer. The new poslist for the phrase (containing
	 ** the same entries as the original with some entries removed on account
	 ** of the NEAR constraint) is written over the original even as it is
	 ** being read. This is safe as the entries for the new poslist are a
	 ** subset of the old, so it is not possible for data yet to be read to
	 ** be overwritten.  */
	i = 0
	for {
		if !(i < (*TFts5ExprNearset)(unsafe.Pointer(pNear)).FnPhrase) {
			break
		}
		pPoslist = **(**uintptr)(__ccgo_up(apPhrase + uintptr(i)*4)) + 4
		_fts5LookaheadReaderInit(tls, (*TFts5Buffer)(unsafe.Pointer(pPoslist)).Fp, (*TFts5Buffer)(unsafe.Pointer(pPoslist)).Fn, a+uintptr(i)*40)
		(*TFts5Buffer)(unsafe.Pointer(pPoslist)).Fn = 0
		(**(**TFts5NearTrimmer)(__ccgo_up(a + uintptr(i)*40))).FpOut = pPoslist
		goto _1
	_1:
		;
		i = i + 1
	}
	for int32(1) != 0 {
		/* This block advances the phrase iterators until they point to a set of
		 ** entries that together comprise a match.  */
		iMax = (**(**TFts5NearTrimmer)(__ccgo_up(a))).Freader.FiPos
		for cond := true; cond; cond = bMatch == 0 {
			bMatch = int32(1)
			i = 0
			for {
				if !(i < (*TFts5ExprNearset)(unsafe.Pointer(pNear)).FnPhrase) {
					break
				}
				pPos = a + uintptr(i)*40
				iMin = iMax - int64((*TFts5ExprPhrase)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pNear + 12 + uintptr(i)*4)))).FnTerm) - int64((*TFts5ExprNearset)(unsafe.Pointer(pNear)).FnNear)
				if (*TFts5LookaheadReader)(unsafe.Pointer(pPos)).FiPos < iMin || (*TFts5LookaheadReader)(unsafe.Pointer(pPos)).FiPos > iMax {
					bMatch = 0
					for (*TFts5LookaheadReader)(unsafe.Pointer(pPos)).FiPos < iMin {
						if _fts5LookaheadReaderNext(tls, pPos) != 0 {
							goto ismatch_out
						}
					}
					if (*TFts5LookaheadReader)(unsafe.Pointer(pPos)).FiPos > iMax {
						iMax = (*TFts5LookaheadReader)(unsafe.Pointer(pPos)).FiPos
					}
				}
				goto _2
			_2:
				;
				i = i + 1
			}
		}
		/* Add an entry to each output position list */
		i = 0
		for {
			if !(i < (*TFts5ExprNearset)(unsafe.Pointer(pNear)).FnPhrase) {
				break
			}
			iPos = (**(**TFts5NearTrimmer)(__ccgo_up(a + uintptr(i)*40))).Freader.FiPos
			pWriter = a + uintptr(i)*40 + 28
			if (*TFts5Buffer)(unsafe.Pointer((**(**TFts5NearTrimmer)(__ccgo_up(a + uintptr(i)*40))).FpOut)).Fn == 0 || iPos != (*TFts5PoslistWriter)(unsafe.Pointer(pWriter)).FiPrev {
				_sqlite3Fts5PoslistWriterAppend(tls, (**(**TFts5NearTrimmer)(__ccgo_up(a + uintptr(i)*40))).FpOut, pWriter, iPos)
			}
			goto _3
		_3:
			;
			i = i + 1
		}
		iAdv = 0
		iMin = (**(**TFts5NearTrimmer)(__ccgo_up(a))).Freader.FiLookahead
		i = 0
		for {
			if !(i < (*TFts5ExprNearset)(unsafe.Pointer(pNear)).FnPhrase) {
				break
			}
			if (**(**TFts5NearTrimmer)(__ccgo_up(a + uintptr(i)*40))).Freader.FiLookahead < iMin {
				iMin = (**(**TFts5NearTrimmer)(__ccgo_up(a + uintptr(i)*40))).Freader.FiLookahead
				iAdv = i
			}
			goto _4
		_4:
			;
			i = i + 1
		}
		if _fts5LookaheadReaderNext(tls, a+uintptr(iAdv)*40) != 0 {
			goto ismatch_out
		}
	}
	goto ismatch_out
ismatch_out:
	;
	bRet = libc.BoolInt32((*TFts5Buffer)(unsafe.Pointer((**(**TFts5NearTrimmer)(__ccgo_up(a))).FpOut)).Fn > 0)
	**(**int32)(__ccgo_up(pRc)) = **(**int32)(__ccgo_up(bp + 160))
	if a != bp {
		Xsqlite3_free(tls, a)
	}
	return bRet
	return r
}

// C documentation
//
//	/*
//	** Set node pNode, which is part of expression pExpr, to point to the first
//	** match. If there are no matches, set the Node.bEof flag to indicate EOF.
//	**
//	** Return an SQLite error code if an error occurs, or SQLITE_OK otherwise.
//	** It is not an error if there are no matches.
//	*/
func _fts5ExprNodeFirst(tls *libc.TLS, pExpr uintptr, pNode uintptr) (r int32) {
	var i, nEof, rc int32
	var pChild uintptr
	_, _, _, _ = i, nEof, pChild, rc
	rc = SQLITE_OK
	(*TFts5ExprNode)(unsafe.Pointer(pNode)).FbEof = 0
	(*TFts5ExprNode)(unsafe.Pointer(pNode)).FbNomatch = 0
	if (*TFts5ExprNode)(unsafe.Pointer(pNode)).FeType == int32(FTS5_TERM) || (*TFts5ExprNode)(unsafe.Pointer(pNode)).FeType == int32(FTS5_STRING) {
		/* Initialize all term iterators in the NEAR object. */
		rc = _fts5ExprNearInitAll(tls, pExpr, pNode)
	} else {
		if (*TFts5ExprNode)(unsafe.Pointer(pNode)).FxNext == uintptr(0) {
			(*TFts5ExprNode)(unsafe.Pointer(pNode)).FbEof = int32(1)
		} else {
			nEof = 0
			i = 0
			for {
				if !(i < (*TFts5ExprNode)(unsafe.Pointer(pNode)).FnChild && rc == SQLITE_OK) {
					break
				}
				pChild = *(*uintptr)(unsafe.Pointer(pNode + 36 + uintptr(i)*4))
				rc = _fts5ExprNodeFirst(tls, pExpr, *(*uintptr)(unsafe.Pointer(pNode + 36 + uintptr(i)*4)))
				nEof = nEof + (*TFts5ExprNode)(unsafe.Pointer(pChild)).FbEof
				goto _1
			_1:
				;
				i = i + 1
			}
			(*TFts5ExprNode)(unsafe.Pointer(pNode)).FiRowid = (*TFts5ExprNode)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pNode + 36)))).FiRowid
			switch (*TFts5ExprNode)(unsafe.Pointer(pNode)).FeType {
			case int32(FTS5_AND):
				if nEof > 0 {
					_fts5ExprSetEof(tls, pNode)
				}
			case int32(FTS5_OR):
				if (*TFts5ExprNode)(unsafe.Pointer(pNode)).FnChild == nEof {
					_fts5ExprSetEof(tls, pNode)
				}
			default:
				(*TFts5ExprNode)(unsafe.Pointer(pNode)).FbEof = (*TFts5ExprNode)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pNode + 36)))).FbEof
				break
			}
		}
	}
	if rc == SQLITE_OK {
		rc = _fts5ExprNodeTest(tls, pExpr, pNode)
	}
	return rc
}

func _fts5ExprNodeNext_AND(tls *libc.TLS, pExpr uintptr, pNode uintptr, bFromValid int32, iFrom Ti64) (r int32) {
	var rc int32
	_ = rc
	rc = (*(*func(*libc.TLS, uintptr, uintptr, int32, Ti64) int32)(unsafe.Pointer(&struct{ uintptr }{(*TFts5ExprNode)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pNode + 36)))).FxNext})))(tls, pExpr, *(*uintptr)(unsafe.Pointer(pNode + 36)), bFromValid, iFrom)
	if rc == SQLITE_OK {
		rc = _fts5ExprNodeTest_AND(tls, pExpr, pNode)
	} else {
		(*TFts5ExprNode)(unsafe.Pointer(pNode)).FbNomatch = 0
	}
	return rc
}

func _fts5ExprNodeNext_NOT(tls *libc.TLS, pExpr uintptr, pNode uintptr, bFromValid int32, iFrom Ti64) (r int32) {
	var rc int32
	_ = rc
	rc = (*(*func(*libc.TLS, uintptr, uintptr, int32, Ti64) int32)(unsafe.Pointer(&struct{ uintptr }{(*TFts5ExprNode)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pNode + 36)))).FxNext})))(tls, pExpr, *(*uintptr)(unsafe.Pointer(pNode + 36)), bFromValid, iFrom)
	if rc == SQLITE_OK {
		rc = _fts5ExprNodeTest_NOT(tls, pExpr, pNode)
	}
	if rc != SQLITE_OK {
		(*TFts5ExprNode)(unsafe.Pointer(pNode)).FbNomatch = 0
	}
	return rc
}

func _fts5ExprNodeNext_OR(tls *libc.TLS, pExpr uintptr, pNode uintptr, bFromValid int32, iFrom Ti64) (r int32) {
	var i, rc int32
	var iLast Ti64
	var p1 uintptr
	_, _, _, _ = i, iLast, p1, rc
	iLast = (*TFts5ExprNode)(unsafe.Pointer(pNode)).FiRowid
	i = 0
	for {
		if !(i < (*TFts5ExprNode)(unsafe.Pointer(pNode)).FnChild) {
			break
		}
		p1 = *(*uintptr)(unsafe.Pointer(pNode + 36 + uintptr(i)*4))
		if (*TFts5ExprNode)(unsafe.Pointer(p1)).FbEof == 0 {
			if (*TFts5ExprNode)(unsafe.Pointer(p1)).FiRowid == iLast || bFromValid != 0 && _fts5RowidCmp(tls, pExpr, (*TFts5ExprNode)(unsafe.Pointer(p1)).FiRowid, iFrom) < 0 {
				rc = (*(*func(*libc.TLS, uintptr, uintptr, int32, Ti64) int32)(unsafe.Pointer(&struct{ uintptr }{(*TFts5ExprNode)(unsafe.Pointer(p1)).FxNext})))(tls, pExpr, p1, bFromValid, iFrom)
				if rc != SQLITE_OK {
					(*TFts5ExprNode)(unsafe.Pointer(pNode)).FbNomatch = 0
					return rc
				}
			}
		}
		goto _1
	_1:
		;
		i = i + 1
	}
	_fts5ExprNodeTest_OR(tls, pExpr, pNode)
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** Argument pNode is an FTS5_AND node.
//	*/
func _fts5ExprNodeTest_AND(tls *libc.TLS, pExpr uintptr, pAnd uintptr) (r int32) {
	var bMatch, cmp, iChild, rc int32
	var iLast Ti64
	var pChild uintptr
	_, _, _, _, _, _ = bMatch, cmp, iChild, iLast, pChild, rc
	iLast = (*TFts5ExprNode)(unsafe.Pointer(pAnd)).FiRowid
	rc = SQLITE_OK
	for cond := true; cond; cond = bMatch == 0 {
		(*TFts5ExprNode)(unsafe.Pointer(pAnd)).FbNomatch = 0
		bMatch = int32(1)
		iChild = 0
		for {
			if !(iChild < (*TFts5ExprNode)(unsafe.Pointer(pAnd)).FnChild) {
				break
			}
			pChild = *(*uintptr)(unsafe.Pointer(pAnd + 36 + uintptr(iChild)*4))
			cmp = _fts5RowidCmp(tls, pExpr, iLast, (*TFts5ExprNode)(unsafe.Pointer(pChild)).FiRowid)
			if cmp > 0 {
				/* Advance pChild until it points to iLast or laster */
				rc = (*(*func(*libc.TLS, uintptr, uintptr, int32, Ti64) int32)(unsafe.Pointer(&struct{ uintptr }{(*TFts5ExprNode)(unsafe.Pointer(pChild)).FxNext})))(tls, pExpr, pChild, int32(1), iLast)
				if rc != SQLITE_OK {
					(*TFts5ExprNode)(unsafe.Pointer(pAnd)).FbNomatch = 0
					return rc
				}
			}
			/* If the child node is now at EOF, so is the parent AND node. Otherwise,
			 ** the child node is guaranteed to have advanced at least as far as
			 ** rowid iLast. So if it is not at exactly iLast, pChild->iRowid is the
			 ** new lastest rowid seen so far.  */
			if (*TFts5ExprNode)(unsafe.Pointer(pChild)).FbEof != 0 {
				_fts5ExprSetEof(tls, pAnd)
				bMatch = int32(1)
				break
			} else {
				if iLast != (*TFts5ExprNode)(unsafe.Pointer(pChild)).FiRowid {
					bMatch = 0
					iLast = (*TFts5ExprNode)(unsafe.Pointer(pChild)).FiRowid
				}
			}
			if (*TFts5ExprNode)(unsafe.Pointer(pChild)).FbNomatch != 0 {
				(*TFts5ExprNode)(unsafe.Pointer(pAnd)).FbNomatch = int32(1)
			}
			goto _1
		_1:
			;
			iChild = iChild + 1
		}
	}
	if (*TFts5ExprNode)(unsafe.Pointer(pAnd)).FbNomatch != 0 && pAnd != (*TFts5Expr)(unsafe.Pointer(pExpr)).FpRoot {
		_fts5ExprNodeZeroPoslist(tls, pAnd)
	}
	(*TFts5ExprNode)(unsafe.Pointer(pAnd)).FiRowid = iLast
	return SQLITE_OK
}

func _fts5ExprNodeTest_NOT(tls *libc.TLS, pExpr uintptr, pNode uintptr) (r int32) {
	var cmp, rc int32
	var p1, p2 uintptr
	_, _, _, _ = cmp, p1, p2, rc
	rc = SQLITE_OK
	p1 = *(*uintptr)(unsafe.Pointer(pNode + 36))
	p2 = *(*uintptr)(unsafe.Pointer(pNode + 36 + 1*4))
	for rc == SQLITE_OK && (*TFts5ExprNode)(unsafe.Pointer(p1)).FbEof == 0 {
		cmp = _fts5NodeCompare(tls, pExpr, p1, p2)
		if cmp > 0 {
			rc = (*(*func(*libc.TLS, uintptr, uintptr, int32, Ti64) int32)(unsafe.Pointer(&struct{ uintptr }{(*TFts5ExprNode)(unsafe.Pointer(p2)).FxNext})))(tls, pExpr, p2, int32(1), (*TFts5ExprNode)(unsafe.Pointer(p1)).FiRowid)
			cmp = _fts5NodeCompare(tls, pExpr, p1, p2)
		}
		if cmp != 0 || (*TFts5ExprNode)(unsafe.Pointer(p2)).FbNomatch != 0 {
			break
		}
		rc = (*(*func(*libc.TLS, uintptr, uintptr, int32, Ti64) int32)(unsafe.Pointer(&struct{ uintptr }{(*TFts5ExprNode)(unsafe.Pointer(p1)).FxNext})))(tls, pExpr, p1, 0, int64(libc.Int32FromInt32(0)))
	}
	(*TFts5ExprNode)(unsafe.Pointer(pNode)).FbEof = (*TFts5ExprNode)(unsafe.Pointer(p1)).FbEof
	(*TFts5ExprNode)(unsafe.Pointer(pNode)).FbNomatch = (*TFts5ExprNode)(unsafe.Pointer(p1)).FbNomatch
	(*TFts5ExprNode)(unsafe.Pointer(pNode)).FiRowid = (*TFts5ExprNode)(unsafe.Pointer(p1)).FiRowid
	if (*TFts5ExprNode)(unsafe.Pointer(p1)).FbEof != 0 {
		_fts5ExprNodeZeroPoslist(tls, p2)
	}
	return rc
}

func _fts5ExprNodeTest_OR(tls *libc.TLS, pExpr uintptr, pNode uintptr) {
	var cmp, i int32
	var pChild, pNext uintptr
	_, _, _, _ = cmp, i, pChild, pNext
	pNext = *(*uintptr)(unsafe.Pointer(pNode + 36))
	i = int32(1)
	for {
		if !(i < (*TFts5ExprNode)(unsafe.Pointer(pNode)).FnChild) {
			break
		}
		pChild = *(*uintptr)(unsafe.Pointer(pNode + 36 + uintptr(i)*4))
		cmp = _fts5NodeCompare(tls, pExpr, pNext, pChild)
		if cmp > 0 || cmp == 0 && (*TFts5ExprNode)(unsafe.Pointer(pChild)).FbNomatch == 0 {
			pNext = pChild
		}
		goto _1
	_1:
		;
		i = i + 1
	}
	(*TFts5ExprNode)(unsafe.Pointer(pNode)).FiRowid = (*TFts5ExprNode)(unsafe.Pointer(pNext)).FiRowid
	(*TFts5ExprNode)(unsafe.Pointer(pNode)).FbEof = (*TFts5ExprNode)(unsafe.Pointer(pNext)).FbEof
	(*TFts5ExprNode)(unsafe.Pointer(pNode)).FbNomatch = (*TFts5ExprNode)(unsafe.Pointer(pNext)).FbNomatch
}

func _fts5ExprNodeZeroPoslist(tls *libc.TLS, pNode uintptr) {
	var i, i1 int32
	var pNear, pPhrase uintptr
	_, _, _, _ = i, i1, pNear, pPhrase
	if (*TFts5ExprNode)(unsafe.Pointer(pNode)).FeType == int32(FTS5_STRING) || (*TFts5ExprNode)(unsafe.Pointer(pNode)).FeType == int32(FTS5_TERM) {
		pNear = (*TFts5ExprNode)(unsafe.Pointer(pNode)).FpNear
		i = 0
		for {
			if !(i < (*TFts5ExprNearset)(unsafe.Pointer(pNear)).FnPhrase) {
				break
			}
			pPhrase = *(*uintptr)(unsafe.Pointer(pNear + 12 + uintptr(i)*4))
			(*TFts5ExprPhrase)(unsafe.Pointer(pPhrase)).Fposlist.Fn = 0
			goto _1
		_1:
			;
			i = i + 1
		}
	} else {
		i1 = 0
		for {
			if !(i1 < (*TFts5ExprNode)(unsafe.Pointer(pNode)).FnChild) {
				break
			}
			_fts5ExprNodeZeroPoslist(tls, *(*uintptr)(unsafe.Pointer(pNode + 36 + uintptr(i1)*4)))
			goto _2
		_2:
			;
			i1 = i1 + 1
		}
	}
}

func _fts5ExprSetEof(tls *libc.TLS, pNode uintptr) {
	var i int32
	_ = i
	(*TFts5ExprNode)(unsafe.Pointer(pNode)).FbEof = int32(1)
	(*TFts5ExprNode)(unsafe.Pointer(pNode)).FbNomatch = 0
	i = 0
	for {
		if !(i < (*TFts5ExprNode)(unsafe.Pointer(pNode)).FnChild) {
			break
		}
		_fts5ExprSetEof(tls, *(*uintptr)(unsafe.Pointer(pNode + 36 + uintptr(i)*4)))
		goto _1
	_1:
		;
		i = i + 1
	}
}

// C documentation
//
//	/*
//	** Flush the contents of in-memory hash table iHash to a new level-0
//	** segment on disk. Also update the corresponding structure record.
//	**
//	** If an error occurs, set the Fts5Index.rc error code. If an error has
//	** already occurred, this function is a no-op.
//	*/
func _fts5FlushOneHash(tls *libc.TLS, p uintptr) {
	bp := tls.Alloc(144)
	defer tls.Free(144)
	var bSecureDelete, bTermWritten, eDetail, iOff, iPos, iSegid, n, nCopy, nSpace, pgsz, v1 int32
	var iPrev, iRowid Ti64
	var iRowidDelta Tu64
	var pBuf, pHash, pPgidx, pPoslist, pSeg, v2 uintptr
	var _ /* bDel at bp+128 */ int32
	var _ /* iDelta at bp+120 */ Tu64
	var _ /* nDoclist at bp+112 */ int32
	var _ /* nPos at bp+132 */ int32
	var _ /* nTerm at bp+104 */ int32
	var _ /* pDoclist at bp+108 */ uintptr
	var _ /* pStruct at bp+0 */ uintptr
	var _ /* pgnoLast at bp+4 */ int32
	var _ /* writer at bp+8 */ TFts5SegWriter
	var _ /* zTerm at bp+100 */ uintptr
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = bSecureDelete, bTermWritten, eDetail, iOff, iPos, iPrev, iRowid, iRowidDelta, iSegid, n, nCopy, nSpace, pBuf, pHash, pPgidx, pPoslist, pSeg, pgsz, v1, v2
	pHash = (*TFts5Index)(unsafe.Pointer(p)).FpHash
	**(**int32)(__ccgo_up(bp + 4)) = 0 /* Last leaf page number in segment */
	/* Obtain a reference to the index structure and allocate a new segment-id
	 ** for the new level-0 segment.  */
	**(**uintptr)(__ccgo_up(bp)) = _fts5StructureRead(tls, p)
	_fts5StructureInvalidate(tls, p)
	if _sqlite3Fts5HashIsEmpty(tls, pHash) == 0 {
		iSegid = _fts5AllocateSegid(tls, p, **(**uintptr)(__ccgo_up(bp)))
		if iSegid != 0 {
			pgsz = (*TFts5Config)(unsafe.Pointer((*TFts5Index)(unsafe.Pointer(p)).FpConfig)).Fpgsz
			eDetail = (*TFts5Config)(unsafe.Pointer((*TFts5Index)(unsafe.Pointer(p)).FpConfig)).FeDetail
			bSecureDelete = (*TFts5Config)(unsafe.Pointer((*TFts5Index)(unsafe.Pointer(p)).FpConfig)).FbSecureDelete
			_fts5WriteInit(tls, p, bp+8, iSegid)
			pBuf = bp + 8 + 4 + 8
			pPgidx = bp + 8 + 4 + 20
			/* fts5WriteInit() should have initialized the buffers to (most likely)
			 ** the maximum space required. */
			/* Begin scanning through hash table entries. This loop runs once for each
			 ** term/doclist currently stored within the hash table. */
			if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
				(*TFts5Index)(unsafe.Pointer(p)).Frc = _sqlite3Fts5HashScanInit(tls, pHash, uintptr(0), 0)
			}
			for (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK && 0 == _sqlite3Fts5HashScanEof(tls, pHash) { /* Size of doclist in bytes */
				/* Get the term and doclist for this entry. */
				_sqlite3Fts5HashScanEntry(tls, pHash, bp+100, bp+104, bp+108, bp+112)
				if bSecureDelete == 0 {
					_fts5WriteAppendTerm(tls, p, bp+8, **(**int32)(__ccgo_up(bp + 104)), **(**uintptr)(__ccgo_up(bp + 100)))
					if (*TFts5Index)(unsafe.Pointer(p)).Frc != SQLITE_OK {
						break
					}
				}
				if !(bSecureDelete != 0) && pgsz >= (*TFts5Buffer)(unsafe.Pointer(pBuf)).Fn+(*TFts5Buffer)(unsafe.Pointer(pPgidx)).Fn+**(**int32)(__ccgo_up(bp + 112))+int32(1) {
					/* The entire doclist will fit on the current leaf. */
					libc.Xmemcpy(tls, (*TFts5Buffer)(unsafe.Pointer(pBuf)).Fp+uintptr((*TFts5Buffer)(unsafe.Pointer(pBuf)).Fn), **(**uintptr)(__ccgo_up(bp + 108)), libc.Uint32FromInt32(**(**int32)(__ccgo_up(bp + 112))))
					**(**int32)(__ccgo_up(pBuf + 4)) += **(**int32)(__ccgo_up(bp + 112))
				} else {
					bTermWritten = libc.BoolInt32(!(bSecureDelete != 0))
					iRowid = 0
					iPrev = 0
					iOff = 0
					/* The entire doclist will not fit on this leaf. The following
					 ** loop iterates through the poslists that make up the current
					 ** doclist.  */
					for (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK && iOff < **(**int32)(__ccgo_up(bp + 112)) {
						**(**Tu64)(__ccgo_up(bp + 120)) = uint64(0)
						iOff = iOff + libc.Int32FromUint8(_sqlite3Fts5GetVarint(tls, **(**uintptr)(__ccgo_up(bp + 108))+uintptr(iOff), bp+120))
						iRowid = libc.Int64FromUint64(uint64(iRowid) + **(**Tu64)(__ccgo_up(bp + 120)))
						/* If in secure delete mode, and if this entry in the poslist is
						 ** in fact a delete, then edit the existing segments directly
						 ** using fts5FlushSecureDelete().  */
						if bSecureDelete != 0 {
							if eDetail == int32(FTS5_DETAIL_NONE) {
								if iOff < **(**int32)(__ccgo_up(bp + 112)) && libc.Int32FromUint8(**(**Tu8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp + 108)) + uintptr(iOff)))) == 0x00 && !(_fts5FlushSecureDelete(tls, p, **(**uintptr)(__ccgo_up(bp)), **(**uintptr)(__ccgo_up(bp + 100)), **(**int32)(__ccgo_up(bp + 104)), iRowid) != 0) {
									iOff = iOff + 1
									if iOff < **(**int32)(__ccgo_up(bp + 112)) && libc.Int32FromUint8(**(**Tu8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp + 108)) + uintptr(iOff)))) == 0x00 {
										iOff = iOff + 1
										**(**int32)(__ccgo_up(bp + 112)) = 0
									} else {
										continue
									}
								}
							} else {
								if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp + 108)) + uintptr(iOff))))&int32(0x01) != 0 && !(_fts5FlushSecureDelete(tls, p, **(**uintptr)(__ccgo_up(bp)), **(**uintptr)(__ccgo_up(bp + 100)), **(**int32)(__ccgo_up(bp + 104)), iRowid) != 0) {
									if (*TFts5Index)(unsafe.Pointer(p)).Frc != SQLITE_OK || libc.Int32FromUint8(**(**Tu8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp + 108)) + uintptr(iOff)))) == int32(0x01) {
										iOff = iOff + 1
										continue
									}
								}
							}
						}
						if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK && bTermWritten == 0 {
							_fts5WriteAppendTerm(tls, p, bp+8, **(**int32)(__ccgo_up(bp + 104)), **(**uintptr)(__ccgo_up(bp + 100)))
							bTermWritten = int32(1)
						}
						if (**(**TFts5SegWriter)(__ccgo_up(bp + 8))).FbFirstRowidInPage != 0 {
							_fts5PutU16(tls, (*TFts5Buffer)(unsafe.Pointer(pBuf)).Fp, libc.Uint16FromInt32((*TFts5Buffer)(unsafe.Pointer(pBuf)).Fn)) /* first rowid on page */
							**(**int32)(__ccgo_up(pBuf + 4)) += _sqlite3Fts5PutVarint(tls, (*TFts5Buffer)(unsafe.Pointer(pBuf)).Fp+uintptr((*TFts5Buffer)(unsafe.Pointer(pBuf)).Fn), libc.Uint64FromInt64(iRowid))
							(**(**TFts5SegWriter)(__ccgo_up(bp + 8))).FbFirstRowidInPage = uint8(0)
							_fts5WriteDlidxAppend(tls, p, bp+8, iRowid)
						} else {
							iRowidDelta = libc.Uint64FromInt64(iRowid) - libc.Uint64FromInt64(iPrev)
							**(**int32)(__ccgo_up(pBuf + 4)) += _sqlite3Fts5PutVarint(tls, (*TFts5Buffer)(unsafe.Pointer(pBuf)).Fp+uintptr((*TFts5Buffer)(unsafe.Pointer(pBuf)).Fn), iRowidDelta)
						}
						if (*TFts5Index)(unsafe.Pointer(p)).Frc != SQLITE_OK {
							break
						}
						iPrev = iRowid
						if eDetail == int32(FTS5_DETAIL_NONE) {
							if iOff < **(**int32)(__ccgo_up(bp + 112)) && libc.Int32FromUint8(**(**Tu8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp + 108)) + uintptr(iOff)))) == 0 {
								v2 = pBuf + 4
								v1 = *(*int32)(unsafe.Pointer(v2))
								*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1
								**(**Tu8)(__ccgo_up((*TFts5Buffer)(unsafe.Pointer(pBuf)).Fp + uintptr(v1))) = uint8(0)
								iOff = iOff + 1
								if iOff < **(**int32)(__ccgo_up(bp + 112)) && libc.Int32FromUint8(**(**Tu8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp + 108)) + uintptr(iOff)))) == 0 {
									v2 = pBuf + 4
									v1 = *(*int32)(unsafe.Pointer(v2))
									*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1
									**(**Tu8)(__ccgo_up((*TFts5Buffer)(unsafe.Pointer(pBuf)).Fp + uintptr(v1))) = uint8(0)
									iOff = iOff + 1
								}
							}
							if (*TFts5Buffer)(unsafe.Pointer(pBuf)).Fn+(*TFts5Buffer)(unsafe.Pointer(pPgidx)).Fn >= pgsz {
								_fts5WriteFlushLeaf(tls, p, bp+8)
							}
						} else {
							**(**int32)(__ccgo_up(bp + 128)) = 0
							**(**int32)(__ccgo_up(bp + 132)) = 0
							nCopy = _fts5GetPoslistSize(tls, **(**uintptr)(__ccgo_up(bp + 108))+uintptr(iOff), bp+132, bp+128)
							if **(**int32)(__ccgo_up(bp + 128)) != 0 && bSecureDelete != 0 {
								_sqlite3Fts5BufferAppendVarint(tls, p+40, pBuf, int64(**(**int32)(__ccgo_up(bp + 132)))*int64(2))
								iOff = iOff + nCopy
								nCopy = **(**int32)(__ccgo_up(bp + 132))
							} else {
								nCopy = nCopy + **(**int32)(__ccgo_up(bp + 132))
							}
							if (*TFts5Buffer)(unsafe.Pointer(pBuf)).Fn+(*TFts5Buffer)(unsafe.Pointer(pPgidx)).Fn+nCopy <= pgsz {
								/* The entire poslist will fit on the current leaf. So copy
								 ** it in one go. */
								libc.Xmemcpy(tls, (*TFts5Buffer)(unsafe.Pointer(pBuf)).Fp+uintptr((*TFts5Buffer)(unsafe.Pointer(pBuf)).Fn), **(**uintptr)(__ccgo_up(bp + 108))+uintptr(iOff), libc.Uint32FromInt32(nCopy))
								**(**int32)(__ccgo_up(pBuf + 4)) += nCopy
							} else {
								/* The entire poslist will not fit on this leaf. So it needs
								 ** to be broken into sections. The only qualification being
								 ** that each varint must be stored contiguously.  */
								pPoslist = **(**uintptr)(__ccgo_up(bp + 108)) + uintptr(iOff)
								iPos = 0
								for (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
									nSpace = pgsz - (*TFts5Buffer)(unsafe.Pointer(pBuf)).Fn - (*TFts5Buffer)(unsafe.Pointer(pPgidx)).Fn
									n = 0
									if nCopy-iPos <= nSpace {
										n = nCopy - iPos
									} else {
										n = _fts5PoslistPrefix(tls, pPoslist+uintptr(iPos), nSpace)
									}
									libc.Xmemcpy(tls, (*TFts5Buffer)(unsafe.Pointer(pBuf)).Fp+uintptr((*TFts5Buffer)(unsafe.Pointer(pBuf)).Fn), pPoslist+uintptr(iPos), libc.Uint32FromInt32(n))
									**(**int32)(__ccgo_up(pBuf + 4)) += n
									iPos = iPos + n
									if (*TFts5Buffer)(unsafe.Pointer(pBuf)).Fn+(*TFts5Buffer)(unsafe.Pointer(pPgidx)).Fn >= pgsz {
										_fts5WriteFlushLeaf(tls, p, bp+8)
									}
									if iPos >= nCopy {
										break
									}
								}
							}
							iOff = iOff + nCopy
						}
					}
				}
				/* TODO2: Doclist terminator written here. */
				/* pBuf->p[pBuf->n++] = '\0'; */
				if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
					_sqlite3Fts5HashScanNext(tls, pHash)
				}
			}
			_fts5WriteFinish(tls, p, bp+8, bp+4)
			if **(**int32)(__ccgo_up(bp + 4)) > 0 {
				/* Update the Fts5Structure. It is written back to the database by the
				 ** fts5StructureRelease() call below.  */
				if (*TFts5Structure)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FnLevel == 0 {
					_fts5StructureAddLevel(tls, p+40, bp)
				}
				_fts5StructureExtendLevel(tls, p+40, **(**uintptr)(__ccgo_up(bp)), 0, int32(1), 0)
				if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
					v2 = **(**uintptr)(__ccgo_up(bp)) + 28 + 4
					v1 = *(*int32)(unsafe.Pointer(v2))
					*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1
					pSeg = (*(*TFts5StructureLevel)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)) + 28))).FaSeg + uintptr(v1)*48
					(*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FiSegid = iSegid
					(*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FpgnoFirst = int32(1)
					(*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FpgnoLast = **(**int32)(__ccgo_up(bp + 4))
					if (*TFts5Structure)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FnOriginCntr > uint64(0) {
						(*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FiOrigin1 = (*TFts5Structure)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FnOriginCntr
						(*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FiOrigin2 = (*TFts5Structure)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FnOriginCntr
						(*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FnEntry = libc.Uint64FromInt32((*TFts5Index)(unsafe.Pointer(p)).FnPendingRow)
						(*TFts5Structure)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FnOriginCntr = (*TFts5Structure)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FnOriginCntr + 1
					}
					(*TFts5Structure)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FnSegment = (*TFts5Structure)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FnSegment + 1
				}
				_fts5StructurePromote(tls, p, 0, **(**uintptr)(__ccgo_up(bp)))
			}
		}
	}
	_fts5IndexAutomerge(tls, p, bp, **(**int32)(__ccgo_up(bp + 4))+(*TFts5Index)(unsafe.Pointer(p)).FnContentlessDelete)
	_fts5IndexCrisismerge(tls, p, bp)
	_fts5StructureWrite(tls, p, **(**uintptr)(__ccgo_up(bp)))
	_fts5StructureRelease(tls, **(**uintptr)(__ccgo_up(bp)))
}

func _fts5FreeCursorComponents(tls *libc.TLS, pCsr uintptr) {
	var eStmt int32
	var pData, pNext, pSorter, pTab uintptr
	_, _, _, _, _ = eStmt, pData, pNext, pSorter, pTab
	pTab = (*TFts5Cursor)(unsafe.Pointer(pCsr)).Fbase.FpVtab
	Xsqlite3_free(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FaInstIter)
	Xsqlite3_free(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FaInst)
	if (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpStmt != 0 {
		eStmt = _fts5StmtType(tls, pCsr)
		_sqlite3Fts5StorageStmtRelease(tls, (*TFts5FullTable)(unsafe.Pointer(pTab)).FpStorage, eStmt, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpStmt)
	}
	if (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpSorter != 0 {
		pSorter = (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpSorter
		Xsqlite3_finalize(tls, (*TFts5Sorter)(unsafe.Pointer(pSorter)).FpStmt)
		Xsqlite3_free(tls, pSorter)
	}
	if (*TFts5Cursor)(unsafe.Pointer(pCsr)).FePlan != int32(FTS5_PLAN_SOURCE) {
		_sqlite3Fts5ExprFree(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpExpr)
	}
	pData = (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpAuxdata
	for {
		if !(pData != 0) {
			break
		}
		pNext = (*TFts5Auxdata)(unsafe.Pointer(pData)).FpNext
		if (*TFts5Auxdata)(unsafe.Pointer(pData)).FxDelete != 0 {
			(*(*func(*libc.TLS, uintptr))(unsafe.Pointer(&struct{ uintptr }{(*TFts5Auxdata)(unsafe.Pointer(pData)).FxDelete})))(tls, (*TFts5Auxdata)(unsafe.Pointer(pData)).FpPtr)
		}
		Xsqlite3_free(tls, pData)
		goto _1
	_1:
		;
		pData = pNext
	}
	Xsqlite3_finalize(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpRankArgStmt)
	Xsqlite3_free(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FapRankArg)
	if (*TFts5Cursor)(unsafe.Pointer(pCsr)).Fcsrflags&int32(FTS5CSR_FREE_ZRANK) != 0 {
		Xsqlite3_free(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FzRank)
		Xsqlite3_free(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FzRankArgs)
	}
	_sqlite3Fts5IndexCloseReader(tls, (*TFts5FullTable)(unsafe.Pointer(pTab)).Fp.FpIndex)
	libc.Xmemset(tls, pCsr+20, 0, uint32(116)-libc.Uint32FromInt32(int32(pCsr+20)-int32(pCsr)))
}

// C documentation
//
//	/*
//	** Allocate and return a buffer at least nByte bytes in size.
//	**
//	** If an OOM error is encountered, return NULL and set the error code in
//	** the Fts5Index handle passed as the first argument.
//	*/
func _fts5IdxMalloc(tls *libc.TLS, p uintptr, nByte Tsqlite3_int64) (r uintptr) {
	return _sqlite3Fts5MallocZero(tls, p+40, nByte)
}

/*
** Compare the contents of the pLeft buffer with the pRight/nRight blob.
**
** Return -ve if pLeft is smaller than pRight, 0 if they are equal or
** +ve if pRight is smaller than pLeft. In other words:
**
**     res = *pLeft - *pRight
 */

// C documentation
//
//	/*
//	** A total of nLeaf leaf pages of data has just been flushed to a level-0
//	** segment. This function updates the write-counter accordingly and, if
//	** necessary, performs incremental merge work.
//	**
//	** If an error occurs, set the Fts5Index.rc error code. If an error has
//	** already occurred, this function is a no-op.
//	*/
func _fts5IndexAutomerge(tls *libc.TLS, p uintptr, ppStruct uintptr, nLeaf int32) {
	var nRem, nWork int32
	var nWrite Tu64
	var pStruct uintptr
	_, _, _, _ = nRem, nWork, nWrite, pStruct
	if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK && (*TFts5Config)(unsafe.Pointer((*TFts5Index)(unsafe.Pointer(p)).FpConfig)).FnAutomerge > 0 && **(**uintptr)(__ccgo_up(ppStruct)) != uintptr(0) {
		pStruct = **(**uintptr)(__ccgo_up(ppStruct)) /* Number of leaf pages left to write */
		/* Update the write-counter. While doing so, set nWork. */
		nWrite = (*TFts5Structure)(unsafe.Pointer(pStruct)).FnWriteCounter
		nWork = libc.Int32FromUint64((nWrite+libc.Uint64FromInt32(nLeaf))/libc.Uint64FromInt32((*TFts5Index)(unsafe.Pointer(p)).FnWorkUnit) - nWrite/libc.Uint64FromInt32((*TFts5Index)(unsafe.Pointer(p)).FnWorkUnit))
		**(**Tu64)(__ccgo_up(pStruct + 4)) += libc.Uint64FromInt32(nLeaf)
		nRem = (*TFts5Index)(unsafe.Pointer(p)).FnWorkUnit * nWork * (*TFts5Structure)(unsafe.Pointer(pStruct)).FnLevel
		_fts5IndexMerge(tls, p, ppStruct, nRem, (*TFts5Config)(unsafe.Pointer((*TFts5Index)(unsafe.Pointer(p)).FpConfig)).FnAutomerge)
	}
}

func _fts5IndexCrisismerge(tls *libc.TLS, p uintptr, ppStruct uintptr) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var iLvl, nCrisis int32
	var _ /* pStruct at bp+0 */ uintptr
	_, _ = iLvl, nCrisis
	nCrisis = (*TFts5Config)(unsafe.Pointer((*TFts5Index)(unsafe.Pointer(p)).FpConfig)).FnCrisisMerge
	**(**uintptr)(__ccgo_up(bp)) = **(**uintptr)(__ccgo_up(ppStruct))
	if **(**uintptr)(__ccgo_up(bp)) != 0 && (*TFts5Structure)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FnLevel > 0 {
		iLvl = 0
		for (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK && (*(*TFts5StructureLevel)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)) + 28 + uintptr(iLvl)*12))).FnSeg >= nCrisis {
			_fts5IndexMergeLevel(tls, p, bp, iLvl, uintptr(0))
			_fts5StructurePromote(tls, p, iLvl+int32(1), **(**uintptr)(__ccgo_up(bp)))
			iLvl = iLvl + 1
		}
		**(**uintptr)(__ccgo_up(ppStruct)) = **(**uintptr)(__ccgo_up(bp))
	}
}

// C documentation
//
//	/*
//	** Parameter pPos points to a buffer containing a position list, size nPos.
//	** This function filters it according to pColset (which must be non-NULL)
//	** and sets pIter->base.pData/nData to point to the new position list.
//	** If memory is required for the new position list, use buffer pIter->poslist.
//	** Or, if the new position list is a contiguous subset of the input, set
//	** pIter->base.pData/nData to point directly to it.
//	**
//	** This function is a no-op if *pRc is other than SQLITE_OK when it is
//	** called. If an OOM error is encountered, *pRc is set to SQLITE_NOMEM
//	** before returning.
//	*/
func _fts5IndexExtractColset(tls *libc.TLS, pRc uintptr, pColset uintptr, pPos uintptr, nPos int32, pIter uintptr) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var aCopy, p, pEnd, v1 uintptr
	var i int32
	var v2 bool
	var _ /* iCurrent at bp+0 */ int32
	_, _, _, _, _, _ = aCopy, i, p, pEnd, v1, v2
	if **(**int32)(__ccgo_up(pRc)) == SQLITE_OK {
		p = pPos
		aCopy = p
		pEnd = p + uintptr(nPos) /* One byte past end of position list */
		i = 0
		**(**int32)(__ccgo_up(bp)) = 0
		if (*TFts5Colset)(unsafe.Pointer(pColset)).FnCol > int32(1) && _sqlite3Fts5BufferSize(tls, pRc, pIter+28, libc.Uint32FromInt32(nPos)) != 0 {
			return
		}
		for int32(1) != 0 {
			for *(*int32)(unsafe.Pointer(pColset + 4 + uintptr(i)*4)) < **(**int32)(__ccgo_up(bp)) {
				i = i + 1
				if i == (*TFts5Colset)(unsafe.Pointer(pColset)).FnCol {
					(*TFts5Iter)(unsafe.Pointer(pIter)).Fbase.FpData = (*TFts5Iter)(unsafe.Pointer(pIter)).Fposlist.Fp
					(*TFts5Iter)(unsafe.Pointer(pIter)).Fbase.FnData = (*TFts5Iter)(unsafe.Pointer(pIter)).Fposlist.Fn
					return
				}
			}
			/* Advance pointer p until it points to pEnd or an 0x01 byte that is
			 ** not part of a varint */
			for p < pEnd && libc.Int32FromUint8(**(**Tu8)(__ccgo_up(p))) != int32(0x01) {
				for {
					if v2 = p < pEnd; v2 {
						v1 = p
						p = p + 1
					}
					if !(v2 && libc.Int32FromUint8(**(**Tu8)(__ccgo_up(v1)))&int32(0x80) != 0) {
						break
					}
				}
			}
			if *(*int32)(unsafe.Pointer(pColset + 4 + uintptr(i)*4)) == **(**int32)(__ccgo_up(bp)) {
				if (*TFts5Colset)(unsafe.Pointer(pColset)).FnCol == int32(1) {
					(*TFts5Iter)(unsafe.Pointer(pIter)).Fbase.FpData = aCopy
					(*TFts5Iter)(unsafe.Pointer(pIter)).Fbase.FnData = int32(p) - int32(aCopy)
					return
				}
				libc.Xmemcpy(tls, (*TFts5Buffer)(unsafe.Pointer(pIter+28)).Fp+uintptr((*TFts5Buffer)(unsafe.Pointer(pIter+28)).Fn), aCopy, libc.Uint32FromInt32(int32(p)-int32(aCopy)))
				**(**int32)(__ccgo_up(pIter + 28 + 4)) += int32(p) - int32(aCopy)
			}
			if p >= pEnd {
				(*TFts5Iter)(unsafe.Pointer(pIter)).Fbase.FpData = (*TFts5Iter)(unsafe.Pointer(pIter)).Fposlist.Fp
				(*TFts5Iter)(unsafe.Pointer(pIter)).Fbase.FnData = (*TFts5Iter)(unsafe.Pointer(pIter)).Fposlist.Fn
				return
			}
			v1 = p
			p = p + 1
			aCopy = v1
			v1 = p
			p = p + 1
			**(**int32)(__ccgo_up(bp)) = libc.Int32FromUint8(**(**Tu8)(__ccgo_up(v1)))
			if **(**int32)(__ccgo_up(bp))&int32(0x80) != 0 {
				p = p - 1
				p = p + uintptr(_sqlite3Fts5GetVarint32(tls, p, bp))
			}
		}
	}
}

// C documentation
//
//	/*
//	** If this is not a contentless_delete=1 table, or if the 'deletemerge'
//	** configuration option is set to 0, then this function always returns -1.
//	** Otherwise, it searches the structure object passed as the second argument
//	** for a level suitable for merging due to having a large number of
//	** tombstones in the tombstone hash. If one is found, its index is returned.
//	** Otherwise, if there is no suitable level, -1.
//	*/
func _fts5IndexFindDeleteMerge(tls *libc.TLS, p uintptr, pStruct uintptr) (r int32) {
	var iRet, iSeg, ii, nBest, nPercent int32
	var nEntry, nTomb Ti64
	var pConfig, pLvl uintptr
	_, _, _, _, _, _, _, _, _ = iRet, iSeg, ii, nBest, nEntry, nPercent, nTomb, pConfig, pLvl
	pConfig = (*TFts5Index)(unsafe.Pointer(p)).FpConfig
	iRet = -int32(1)
	if (*TFts5Config)(unsafe.Pointer(pConfig)).FbContentlessDelete != 0 && (*TFts5Config)(unsafe.Pointer(pConfig)).FnDeleteMerge > 0 {
		nBest = 0
		ii = 0
		for {
			if !(ii < (*TFts5Structure)(unsafe.Pointer(pStruct)).FnLevel) {
				break
			}
			pLvl = pStruct + 28 + uintptr(ii)*12
			nEntry = 0
			nTomb = 0
			iSeg = 0
			for {
				if !(iSeg < (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnSeg) {
					break
				}
				nEntry = libc.Int64FromUint64(uint64(nEntry) + (**(**TFts5StructureSegment)(__ccgo_up((*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FaSeg + uintptr(iSeg)*48))).FnEntry)
				nTomb = libc.Int64FromUint64(uint64(nTomb) + (**(**TFts5StructureSegment)(__ccgo_up((*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FaSeg + uintptr(iSeg)*48))).FnEntryTombstone)
				goto _2
			_2:
				;
				iSeg = iSeg + 1
			}
			if nEntry > 0 {
				nPercent = int32(nTomb * int64(100) / nEntry)
				if nPercent >= (*TFts5Config)(unsafe.Pointer(pConfig)).FnDeleteMerge && nPercent > nBest {
					iRet = ii
					nBest = nPercent
				}
			}
			/* If pLvl is already the input level to an ongoing merge, look no
			 ** further for a merge candidate. The caller should be allowed to
			 ** continue merging from pLvl first.  */
			if (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnMerge != 0 {
				break
			}
			goto _1
		_1:
			;
			ii = ii + 1
		}
	}
	return iRet
}

// C documentation
//
//	/*
//	** Do up to nPg pages of automerge work on the index.
//	**
//	** Return true if any changes were actually made, or false otherwise.
//	*/
func _fts5IndexMerge(tls *libc.TLS, p uintptr, ppStruct uintptr, nPg int32, nMin int32) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var bRet, iBestLvl, iLvl, nBest int32
	var pLvl uintptr
	var _ /* nRem at bp+0 */ int32
	var _ /* pStruct at bp+4 */ uintptr
	_, _, _, _, _ = bRet, iBestLvl, iLvl, nBest, pLvl
	**(**int32)(__ccgo_up(bp)) = nPg
	bRet = 0
	**(**uintptr)(__ccgo_up(bp + 4)) = **(**uintptr)(__ccgo_up(ppStruct))
	for **(**int32)(__ccgo_up(bp)) > 0 && (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK { /* To iterate through levels */
		iBestLvl = 0 /* Level offering the most input segments */
		nBest = 0    /* Number of input segments on best level */
		/* Set iBestLvl to the level to read input segments from. Or to -1 if
		 ** there is no level suitable to merge segments from.  */
		iLvl = 0
		for {
			if !(iLvl < (*TFts5Structure)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 4)))).FnLevel) {
				break
			}
			pLvl = **(**uintptr)(__ccgo_up(bp + 4)) + 28 + uintptr(iLvl)*12
			if (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnMerge != 0 {
				if (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnMerge > nBest {
					iBestLvl = iLvl
					nBest = nMin
				}
				break
			}
			if (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnSeg > nBest {
				nBest = (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnSeg
				iBestLvl = iLvl
			}
			goto _1
		_1:
			;
			iLvl = iLvl + 1
		}
		if nBest < nMin {
			iBestLvl = _fts5IndexFindDeleteMerge(tls, p, **(**uintptr)(__ccgo_up(bp + 4)))
		}
		if iBestLvl < 0 {
			break
		}
		bRet = int32(1)
		_fts5IndexMergeLevel(tls, p, bp+4, iBestLvl, bp)
		if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK && (*(*TFts5StructureLevel)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 4)) + 28 + uintptr(iBestLvl)*12))).FnMerge == 0 {
			_fts5StructurePromote(tls, p, iBestLvl+int32(1), **(**uintptr)(__ccgo_up(bp + 4)))
		}
		if nMin == int32(1) {
			nMin = int32(2)
		}
	}
	**(**uintptr)(__ccgo_up(ppStruct)) = **(**uintptr)(__ccgo_up(bp + 4))
	return bRet
}

// C documentation
//
//	/*
//	**
//	*/
func _fts5IndexMergeLevel(tls *libc.TLS, p uintptr, ppStruct uintptr, iLvl int32, pnRem uintptr) {
	bp := tls.Alloc(112)
	defer tls.Free(112)
	var bOldest, bTermWritten, eDetail, flags, i, iSegid, nInput, nMove, nPos, nRem, v1 int32
	var pLvl, pLvlOut, pOld, pSeg, pSegIter, pStruct, pTerm uintptr
	var v4 bool
	var _ /* nTerm at bp+108 */ int32
	var _ /* pIter at bp+0 */ uintptr
	var _ /* term at bp+96 */ TFts5Buffer
	var _ /* writer at bp+4 */ TFts5SegWriter
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = bOldest, bTermWritten, eDetail, flags, i, iSegid, nInput, nMove, nPos, nRem, pLvl, pLvlOut, pOld, pSeg, pSegIter, pStruct, pTerm, v1, v4
	pStruct = **(**uintptr)(__ccgo_up(ppStruct))
	pLvl = pStruct + 28 + uintptr(iLvl)*12
	**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
	if pnRem != 0 {
		v1 = **(**int32)(__ccgo_up(pnRem))
	} else {
		v1 = 0
	} /* Iterator to read input data */
	nRem = v1 /* True if the output segment is the oldest */
	eDetail = (*TFts5Config)(unsafe.Pointer((*TFts5Index)(unsafe.Pointer(p)).FpConfig)).FeDetail
	flags = int32(FTS5INDEX_QUERY_NOOUTPUT)
	bTermWritten = 0 /* True if current term already output */
	libc.Xmemset(tls, bp+4, 0, uint32(92))
	libc.Xmemset(tls, bp+96, 0, uint32(12))
	if (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnMerge != 0 {
		pLvlOut = pStruct + 28 + uintptr(iLvl+int32(1))*12
		nInput = (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnMerge
		pSeg = (*TFts5StructureLevel)(unsafe.Pointer(pLvlOut)).FaSeg + uintptr((*TFts5StructureLevel)(unsafe.Pointer(pLvlOut)).FnSeg-int32(1))*48
		_fts5WriteInit(tls, p, bp+4, (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FiSegid)
		(**(**TFts5SegWriter)(__ccgo_up(bp + 4))).Fwriter.Fpgno = (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FpgnoLast + int32(1)
		(**(**TFts5SegWriter)(__ccgo_up(bp + 4))).FiBtPage = 0
	} else {
		iSegid = _fts5AllocateSegid(tls, p, pStruct)
		/* Extend the Fts5Structure object as required to ensure the output
		 ** segment exists. */
		if iLvl == (*TFts5Structure)(unsafe.Pointer(pStruct)).FnLevel-int32(1) {
			_fts5StructureAddLevel(tls, p+40, ppStruct)
			pStruct = **(**uintptr)(__ccgo_up(ppStruct))
		}
		_fts5StructureExtendLevel(tls, p+40, pStruct, iLvl+int32(1), int32(1), 0)
		if (*TFts5Index)(unsafe.Pointer(p)).Frc != 0 {
			return
		}
		pLvl = pStruct + 28 + uintptr(iLvl)*12
		pLvlOut = pStruct + 28 + uintptr(iLvl+int32(1))*12
		_fts5WriteInit(tls, p, bp+4, iSegid)
		/* Add the new segment to the output level */
		pSeg = (*TFts5StructureLevel)(unsafe.Pointer(pLvlOut)).FaSeg + uintptr((*TFts5StructureLevel)(unsafe.Pointer(pLvlOut)).FnSeg)*48
		(*TFts5StructureLevel)(unsafe.Pointer(pLvlOut)).FnSeg = (*TFts5StructureLevel)(unsafe.Pointer(pLvlOut)).FnSeg + 1
		(*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FpgnoFirst = int32(1)
		(*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FiSegid = iSegid
		(*TFts5Structure)(unsafe.Pointer(pStruct)).FnSegment = (*TFts5Structure)(unsafe.Pointer(pStruct)).FnSegment + 1
		/* Read input from all segments in the input level */
		nInput = (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnSeg
		/* Set the range of origins that will go into the output segment. */
		if (*TFts5Structure)(unsafe.Pointer(pStruct)).FnOriginCntr > uint64(0) {
			(*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FiOrigin1 = (**(**TFts5StructureSegment)(__ccgo_up((*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FaSeg))).FiOrigin1
			(*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FiOrigin2 = (**(**TFts5StructureSegment)(__ccgo_up((*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FaSeg + uintptr((*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnSeg-int32(1))*48))).FiOrigin2
		}
	}
	bOldest = libc.BoolInt32((*TFts5StructureLevel)(unsafe.Pointer(pLvlOut)).FnSeg == int32(1) && (*TFts5Structure)(unsafe.Pointer(pStruct)).FnLevel == iLvl+int32(2))
	_fts5MultiIterNew(tls, p, pStruct, flags, uintptr(0), uintptr(0), 0, iLvl, nInput, bp)
	for {
		if !(_fts5MultiIterEof(tls, p, **(**uintptr)(__ccgo_up(bp))) == 0) {
			break
		}
		pSegIter = **(**uintptr)(__ccgo_up(bp)) + 72 + uintptr((**(**TFts5CResult)(__ccgo_up((*TFts5Iter)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FaFirst + 1*4))).FiFirst)*96
		pTerm = _fts5MultiIterTerm(tls, **(**uintptr)(__ccgo_up(bp)), bp+108)
		if v4 = **(**int32)(__ccgo_up(bp + 108)) != (**(**TFts5Buffer)(__ccgo_up(bp + 96))).Fn; !v4 {
			if **(**int32)(__ccgo_up(bp + 108)) <= 0 {
				v1 = 0
			} else {
				v1 = libc.Xmemcmp(tls, pTerm, (**(**TFts5Buffer)(__ccgo_up(bp + 96))).Fp, libc.Uint32FromInt32(**(**int32)(__ccgo_up(bp + 108))))
			}
		}
		if v4 || v1 != 0 {
			if pnRem != 0 && (**(**TFts5SegWriter)(__ccgo_up(bp + 4))).FnLeafWritten > nRem {
				break
			}
			_sqlite3Fts5BufferSet(tls, p+40, bp+96, **(**int32)(__ccgo_up(bp + 108)), pTerm)
			bTermWritten = 0
		}
		/* Check for key annihilation. */
		if (*TFts5SegIter)(unsafe.Pointer(pSegIter)).FnPos == 0 && (bOldest != 0 || libc.Int32FromUint8((*TFts5SegIter)(unsafe.Pointer(pSegIter)).FbDel) == 0) {
			goto _2
		}
		if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK && bTermWritten == 0 {
			/* This is a new term. Append a term to the output segment. */
			_fts5WriteAppendTerm(tls, p, bp+4, **(**int32)(__ccgo_up(bp + 108)), pTerm)
			bTermWritten = int32(1)
		}
		/* Append the rowid to the output */
		/* WRITEPOSLISTSIZE */
		_fts5WriteAppendRowid(tls, p, bp+4, _fts5MultiIterRowid(tls, **(**uintptr)(__ccgo_up(bp))))
		if eDetail == int32(FTS5_DETAIL_NONE) {
			if (*TFts5SegIter)(unsafe.Pointer(pSegIter)).FbDel != 0 {
				_sqlite3Fts5BufferAppendVarint(tls, p+40, bp+4+4+8, libc.Int64FromInt32(0))
				if (*TFts5SegIter)(unsafe.Pointer(pSegIter)).FnPos > 0 {
					_sqlite3Fts5BufferAppendVarint(tls, p+40, bp+4+4+8, libc.Int64FromInt32(0))
				}
			}
		} else {
			/* Append the position-list data to the output */
			nPos = (*TFts5SegIter)(unsafe.Pointer(pSegIter)).FnPos*int32(2) + libc.Int32FromUint8((*TFts5SegIter)(unsafe.Pointer(pSegIter)).FbDel)
			_sqlite3Fts5BufferAppendVarint(tls, p+40, bp+4+4+8, int64(nPos))
			_fts5ChunkIterate(tls, p, pSegIter, bp+4, __ccgo_fp(_fts5MergeChunkCallback))
		}
		goto _2
	_2:
		;
		_fts5MultiIterNext(tls, p, **(**uintptr)(__ccgo_up(bp)), 0, 0)
	}
	/* Flush the last leaf page to disk. Set the output segment b-tree height
	 ** and last leaf page number at the same time.  */
	_fts5WriteFinish(tls, p, bp+4, pSeg+8)
	if _fts5MultiIterEof(tls, p, **(**uintptr)(__ccgo_up(bp))) != 0 {
		/* Remove the redundant segments from the %_data table */
		i = 0
		for {
			if !(i < nInput) {
				break
			}
			pOld = (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FaSeg + uintptr(i)*48
			**(**Tu64)(__ccgo_up(pSeg + 40)) += (*TFts5StructureSegment)(unsafe.Pointer(pOld)).FnEntry - (*TFts5StructureSegment)(unsafe.Pointer(pOld)).FnEntryTombstone
			_fts5DataRemoveSegment(tls, p, pOld)
			goto _5
		_5:
			;
			i = i + 1
		}
		/* Remove the redundant segments from the input level */
		if (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnSeg != nInput {
			nMove = libc.Int32FromUint32(libc.Uint32FromInt32((*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnSeg-nInput) * uint32(48))
			libc.Xmemmove(tls, (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FaSeg, (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FaSeg+uintptr(nInput)*48, libc.Uint32FromInt32(nMove))
		}
		**(**int32)(__ccgo_up(pStruct + 20)) -= nInput
		**(**int32)(__ccgo_up(pLvl + 4)) -= nInput
		(*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnMerge = 0
		if (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FpgnoLast == 0 {
			(*TFts5StructureLevel)(unsafe.Pointer(pLvlOut)).FnSeg = (*TFts5StructureLevel)(unsafe.Pointer(pLvlOut)).FnSeg - 1
			(*TFts5Structure)(unsafe.Pointer(pStruct)).FnSegment = (*TFts5Structure)(unsafe.Pointer(pStruct)).FnSegment - 1
		}
	} else {
		_fts5TrimSegments(tls, p, **(**uintptr)(__ccgo_up(bp)))
		(*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnMerge = nInput
	}
	_fts5MultiIterFree(tls, **(**uintptr)(__ccgo_up(bp)))
	_sqlite3Fts5BufferFree(tls, bp+96)
	if pnRem != 0 {
		**(**int32)(__ccgo_up(pnRem)) -= (**(**TFts5SegWriter)(__ccgo_up(bp + 4))).FnLeafWritten
	}
}

func _fts5IndexOptimizeStruct(tls *libc.TLS, p uintptr, pStruct uintptr) (r uintptr) {
	var i, iLvl, iSeg, iSegOut, nMerge, nSeg, nThis, v2 int32
	var nByte Tsqlite3_int64
	var pLvl, pNew uintptr
	_, _, _, _, _, _, _, _, _, _, _ = i, iLvl, iSeg, iSegOut, nByte, nMerge, nSeg, nThis, pLvl, pNew, v2
	pNew = uintptr(0)
	nByte = libc.Int64FromUint32(uint32(libc.UintptrFromInt32(0)+28) + libc.Uint32FromInt32(libc.Int32FromInt32(1))*libc.Uint32FromInt64(12))
	nSeg = (*TFts5Structure)(unsafe.Pointer(pStruct)).FnSegment
	/* Figure out if this structure requires optimization. A structure does
	 ** not require optimization if either:
	 **
	 **  1. it consists of fewer than two segments, or
	 **  2. all segments are on the same level, or
	 **  3. all segments except one are currently inputs to a merge operation.
	 **
	 ** In the first case, if there are no tombstone hash pages, return NULL. In
	 ** the second, increment the ref-count on *pStruct and return a copy of the
	 ** pointer to it.
	 */
	if nSeg == 0 {
		return uintptr(0)
	}
	i = 0
	for {
		if !(i < (*TFts5Structure)(unsafe.Pointer(pStruct)).FnLevel) {
			break
		}
		nThis = (*(*TFts5StructureLevel)(unsafe.Pointer(pStruct + 28 + uintptr(i)*12))).FnSeg
		nMerge = (*(*TFts5StructureLevel)(unsafe.Pointer(pStruct + 28 + uintptr(i)*12))).FnMerge
		if nThis > 0 && (nThis == nSeg || nThis == nSeg-int32(1) && nMerge == nThis) {
			if nSeg == int32(1) && nThis == int32(1) && (**(**TFts5StructureSegment)(__ccgo_up((*(*TFts5StructureLevel)(unsafe.Pointer(pStruct + 28 + uintptr(i)*12))).FaSeg))).FnPgTombstone == 0 {
				return uintptr(0)
			}
			_fts5StructureRef(tls, pStruct)
			return pStruct
		}
		goto _1
	_1:
		;
		i = i + 1
	}
	nByte = nByte + (int64((*TFts5Structure)(unsafe.Pointer(pStruct)).FnLevel)+int64(1))*int64(12)
	pNew = _sqlite3Fts5MallocZero(tls, p+40, nByte)
	if pNew != 0 {
		nByte = libc.Int64FromUint32(libc.Uint32FromInt32(nSeg) * uint32(48))
		if (*TFts5Structure)(unsafe.Pointer(pStruct)).FnLevel+int32(1) < int32(FTS5_MAX_LEVEL) {
			v2 = (*TFts5Structure)(unsafe.Pointer(pStruct)).FnLevel + int32(1)
		} else {
			v2 = int32(FTS5_MAX_LEVEL)
		}
		(*TFts5Structure)(unsafe.Pointer(pNew)).FnLevel = v2
		(*TFts5Structure)(unsafe.Pointer(pNew)).FnRef = int32(1)
		(*TFts5Structure)(unsafe.Pointer(pNew)).FnWriteCounter = (*TFts5Structure)(unsafe.Pointer(pStruct)).FnWriteCounter
		(*TFts5Structure)(unsafe.Pointer(pNew)).FnOriginCntr = (*TFts5Structure)(unsafe.Pointer(pStruct)).FnOriginCntr
		pLvl = pNew + 28 + uintptr((*TFts5Structure)(unsafe.Pointer(pNew)).FnLevel-int32(1))*12
		(*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FaSeg = _sqlite3Fts5MallocZero(tls, p+40, nByte)
		if (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FaSeg != 0 {
			iSegOut = 0
			/* Iterate through all segments, from oldest to newest. Add them to
			 ** the new Fts5Level object so that pLvl->aSeg[0] is the oldest
			 ** segment in the data structure.  */
			iLvl = (*TFts5Structure)(unsafe.Pointer(pStruct)).FnLevel - int32(1)
			for {
				if !(iLvl >= 0) {
					break
				}
				iSeg = 0
				for {
					if !(iSeg < (*(*TFts5StructureLevel)(unsafe.Pointer(pStruct + 28 + uintptr(iLvl)*12))).FnSeg) {
						break
					}
					**(**TFts5StructureSegment)(__ccgo_up((*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FaSeg + uintptr(iSegOut)*48)) = **(**TFts5StructureSegment)(__ccgo_up((*(*TFts5StructureLevel)(unsafe.Pointer(pStruct + 28 + uintptr(iLvl)*12))).FaSeg + uintptr(iSeg)*48))
					iSegOut = iSegOut + 1
					goto _4
				_4:
					;
					iSeg = iSeg + 1
				}
				goto _3
			_3:
				;
				iLvl = iLvl - 1
			}
			v2 = nSeg
			(*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnSeg = v2
			(*TFts5Structure)(unsafe.Pointer(pNew)).FnSegment = v2
		} else {
			Xsqlite3_free(tls, pNew)
			pNew = uintptr(0)
		}
	}
	return pNew
}

// C documentation
//
//	/*
//	** This is called to rebuild the hash table belonging to segment pSeg.
//	** If parameter pData1 is not NULL, then one page of the existing hash table
//	** has already been loaded - pData1, which is page iPg1. The key-size for
//	** the new hash table is szKey (4 or 8).
//	**
//	** If successful, the new hash table is not written to disk. Instead,
//	** output parameter (*pnOut) is set to the number of pages in the new
//	** hash table, and (*papOut) to point to an array of buffers containing
//	** the new page data.
//	**
//	** If an error occurs, an error code is left in the Fts5Index object and
//	** both output parameters set to 0 before returning.
//	*/
func _fts5IndexTombstoneRebuild(tls *libc.TLS, p uintptr, pSeg uintptr, pData1 uintptr, iPg1 int32, szKey int32, pnOut uintptr, papOut uintptr) {
	var MINSLOT, ii, nElem, nOut, nSlot, nSlotPerPage, res, szPage, v1 int32
	var apOut, pNew uintptr
	_, _, _, _, _, _, _, _, _, _, _ = MINSLOT, apOut, ii, nElem, nOut, nSlot, nSlotPerPage, pNew, res, szPage, v1
	MINSLOT = int32(32)
	if MINSLOT > ((*TFts5Config)(unsafe.Pointer((*TFts5Index)(unsafe.Pointer(p)).FpConfig)).Fpgsz-int32(8))/szKey {
		v1 = MINSLOT
	} else {
		v1 = ((*TFts5Config)(unsafe.Pointer((*TFts5Index)(unsafe.Pointer(p)).FpConfig)).Fpgsz - int32(8)) / szKey
	}
	nSlotPerPage = v1
	nSlot = 0 /* Number of slots in each output page */
	nOut = 0
	/* Figure out how many output pages (nOut) and how many slots per
	 ** page (nSlot).  There are three possibilities:
	 **
	 **   1. The hash table does not yet exist. In this case the new hash
	 **      table will consist of a single page with MINSLOT slots.
	 **
	 **   2. The hash table exists but is currently a single page. In this
	 **      case an attempt is made to grow the page to accommodate the new
	 **      entry. The page is allowed to grow up to nSlotPerPage (see above)
	 **      slots.
	 **
	 **   3. The hash table already consists of more than one page, or of
	 **      a single page already so large that it cannot be grown. In this
	 **      case the new hash consists of (nPg*2+1) pages of nSlotPerPage
	 **      slots each, where nPg is the current number of pages in the
	 **      hash table.
	 */
	if (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FnPgTombstone == 0 {
		/* Case 1. */
		nOut = int32(1)
		nSlot = MINSLOT
	} else {
		if (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FnPgTombstone == int32(1) {
			/* Case 2. */
			nElem = libc.Int32FromUint32(_fts5GetU32(tls, (*TFts5Data)(unsafe.Pointer(pData1)).Fp+4))
			nOut = int32(1)
			if nElem*int32(4) > MINSLOT {
				v1 = nElem * int32(4)
			} else {
				v1 = MINSLOT
			}
			nSlot = v1
			if nSlot > nSlotPerPage {
				nOut = 0
			}
		}
	}
	if nOut == 0 {
		/* Case 3. */
		nOut = (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FnPgTombstone*int32(2) + int32(1)
		nSlot = nSlotPerPage
	}
	/* Allocate the required array and output pages */
	for int32(1) != 0 {
		res = 0
		ii = 0
		szPage = 0
		apOut = uintptr(0)
		/* Allocate space for the new hash table */
		apOut = _sqlite3Fts5MallocZero(tls, p+40, libc.Int64FromUint32(uint32(4)*libc.Uint32FromInt32(nOut)))
		szPage = int32(8) + nSlot*szKey
		ii = 0
		for {
			if !(ii < nOut) {
				break
			}
			pNew = _sqlite3Fts5MallocZero(tls, p+40, libc.Int64FromUint32(uint32(12)+libc.Uint32FromInt32(szPage)))
			if pNew != 0 {
				(*TFts5Data)(unsafe.Pointer(pNew)).Fnn = szPage
				(*TFts5Data)(unsafe.Pointer(pNew)).Fp = pNew + 1*12
				**(**uintptr)(__ccgo_up(apOut + uintptr(ii)*4)) = pNew
			}
			goto _3
		_3:
			;
			ii = ii + 1
		}
		/* Rebuild the hash table. */
		if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
			res = _fts5IndexTombstoneRehash(tls, p, pSeg, pData1, iPg1, szKey, nOut, apOut)
		}
		if res == 0 {
			if (*TFts5Index)(unsafe.Pointer(p)).Frc != 0 {
				_fts5IndexFreeArray(tls, apOut, nOut)
				apOut = uintptr(0)
				nOut = 0
			}
			**(**int32)(__ccgo_up(pnOut)) = nOut
			**(**uintptr)(__ccgo_up(papOut)) = apOut
			break
		}
		/* If control flows to here, it was not possible to rebuild the hash
		 ** table. Free all buffers and then try again with more pages. */
		_fts5IndexFreeArray(tls, apOut, nOut)
		nSlot = nSlotPerPage
		nOut = nOut*int32(2) + int32(1)
	}
}

func _fts5IntegrityCheckPgidx(tls *libc.TLS, p uintptr, iRowid Ti64, pLeaf uintptr) {
	bp := tls.Alloc(48)
	defer tls.Free(48)
	var iOff, iTermOff Ti64
	var ii, res int32
	var _ /* buf1 at bp+0 */ TFts5Buffer
	var _ /* buf2 at bp+12 */ TFts5Buffer
	var _ /* nByte at bp+28 */ int32
	var _ /* nByte at bp+36 */ int32
	var _ /* nIncr at bp+24 */ int32
	var _ /* nKeep at bp+32 */ int32
	_, _, _, _ = iOff, iTermOff, ii, res
	iTermOff = 0
	**(**TFts5Buffer)(__ccgo_up(bp)) = TFts5Buffer{}
	**(**TFts5Buffer)(__ccgo_up(bp + 12)) = TFts5Buffer{}
	ii = (*TFts5Data)(unsafe.Pointer(pLeaf)).FszLeaf
	for ii < (*TFts5Data)(unsafe.Pointer(pLeaf)).Fnn && (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
		ii = ii + _sqlite3Fts5GetVarint32(tls, (*TFts5Data)(unsafe.Pointer(pLeaf)).Fp+uintptr(ii), bp+24)
		iTermOff = iTermOff + int64(**(**int32)(__ccgo_up(bp + 24)))
		iOff = iTermOff
		if iOff >= int64((*TFts5Data)(unsafe.Pointer(pLeaf)).FszLeaf) {
			_fts5IndexCorruptRowid(tls, p, iRowid)
		} else {
			if iTermOff == int64(**(**int32)(__ccgo_up(bp + 24))) {
				iOff = iOff + int64(_sqlite3Fts5GetVarint32(tls, (*TFts5Data)(unsafe.Pointer(pLeaf)).Fp+uintptr(iOff), bp+28))
				if iOff+int64(**(**int32)(__ccgo_up(bp + 28))) > int64((*TFts5Data)(unsafe.Pointer(pLeaf)).FszLeaf) {
					_fts5IndexCorruptRowid(tls, p, iRowid)
				} else {
					_sqlite3Fts5BufferSet(tls, p+40, bp, **(**int32)(__ccgo_up(bp + 28)), (*TFts5Data)(unsafe.Pointer(pLeaf)).Fp+uintptr(iOff))
				}
			} else {
				iOff = iOff + int64(_sqlite3Fts5GetVarint32(tls, (*TFts5Data)(unsafe.Pointer(pLeaf)).Fp+uintptr(iOff), bp+32))
				iOff = iOff + int64(_sqlite3Fts5GetVarint32(tls, (*TFts5Data)(unsafe.Pointer(pLeaf)).Fp+uintptr(iOff), bp+36))
				if **(**int32)(__ccgo_up(bp + 32)) > (**(**TFts5Buffer)(__ccgo_up(bp))).Fn || iOff+int64(**(**int32)(__ccgo_up(bp + 36))) > int64((*TFts5Data)(unsafe.Pointer(pLeaf)).FszLeaf) {
					_fts5IndexCorruptRowid(tls, p, iRowid)
				} else {
					(**(**TFts5Buffer)(__ccgo_up(bp))).Fn = **(**int32)(__ccgo_up(bp + 32))
					_sqlite3Fts5BufferAppendBlob(tls, p+40, bp, libc.Uint32FromInt32(**(**int32)(__ccgo_up(bp + 36))), (*TFts5Data)(unsafe.Pointer(pLeaf)).Fp+uintptr(iOff))
				}
				if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
					res = _fts5BufferCompare(tls, bp, bp+12)
					if res <= 0 {
						_fts5IndexCorruptRowid(tls, p, iRowid)
					}
				}
			}
		}
		_sqlite3Fts5BufferSet(tls, p+40, bp+12, (**(**TFts5Buffer)(__ccgo_up(bp))).Fn, (**(**TFts5Buffer)(__ccgo_up(bp))).Fp)
	}
	_sqlite3Fts5BufferFree(tls, bp)
	_sqlite3Fts5BufferFree(tls, bp+12)
}

func _fts5IterSetOutputCb(tls *libc.TLS, pRc uintptr, pIter uintptr) {
	var pConfig uintptr
	_ = pConfig
	if **(**int32)(__ccgo_up(pRc)) == SQLITE_OK {
		pConfig = (*TFts5Index)(unsafe.Pointer((*TFts5Iter)(unsafe.Pointer(pIter)).FpIndex)).FpConfig
		if (*TFts5Config)(unsafe.Pointer(pConfig)).FeDetail == int32(FTS5_DETAIL_NONE) {
			(*TFts5Iter)(unsafe.Pointer(pIter)).FxSetOutputs = __ccgo_fp(_fts5IterSetOutputs_None)
		} else {
			if (*TFts5Iter)(unsafe.Pointer(pIter)).FpColset == uintptr(0) {
				(*TFts5Iter)(unsafe.Pointer(pIter)).FxSetOutputs = __ccgo_fp(_fts5IterSetOutputs_Nocolset)
			} else {
				if (*TFts5Colset)(unsafe.Pointer((*TFts5Iter)(unsafe.Pointer(pIter)).FpColset)).FnCol == 0 {
					(*TFts5Iter)(unsafe.Pointer(pIter)).FxSetOutputs = __ccgo_fp(_fts5IterSetOutputs_ZeroColset)
				} else {
					if (*TFts5Config)(unsafe.Pointer(pConfig)).FeDetail == FTS5_DETAIL_FULL {
						(*TFts5Iter)(unsafe.Pointer(pIter)).FxSetOutputs = __ccgo_fp(_fts5IterSetOutputs_Full)
					} else {
						if (*TFts5Config)(unsafe.Pointer(pConfig)).FnCol <= int32(100) {
							(*TFts5Iter)(unsafe.Pointer(pIter)).FxSetOutputs = __ccgo_fp(_fts5IterSetOutputs_Col100)
							_sqlite3Fts5BufferSize(tls, pRc, pIter+28, libc.Uint32FromInt32((*TFts5Config)(unsafe.Pointer(pConfig)).FnCol))
						} else {
							(*TFts5Iter)(unsafe.Pointer(pIter)).FxSetOutputs = __ccgo_fp(_fts5IterSetOutputs_Col)
						}
					}
				}
			}
		}
	}
}

// C documentation
//
//	/*
//	** The iterator passed as the only argument must be a tokendata=1 iterator
//	** (pIter->pTokenDataIter!=0). This function sets the iterator output
//	** variables (pIter->base.*) according to the contents of the current
//	** row.
//	*/
func _fts5IterSetOutputsTokendata(tls *libc.TLS, pIter uintptr) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var aNew, p, p1, pReader, pT uintptr
	var eDetail, iMin, ii, nByte, nHit, nReader, v3 int32
	var iMinPos, iRowid, nNew Ti64
	var _ /* iPrev at bp+0 */ Ti64
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = aNew, eDetail, iMin, iMinPos, iRowid, ii, nByte, nHit, nNew, nReader, p, p1, pReader, pT, v3
	nHit = 0
	iRowid = int64(-libc.Int32FromInt32(1)) - (libc.Int64FromUint32(0xffffffff) | libc.Int64FromInt32(0x7fffffff)<<libc.Int32FromInt32(32))
	iMin = 0
	pT = (*TFts5Iter)(unsafe.Pointer(pIter)).FpTokenDataIter
	(*TFts5Iter)(unsafe.Pointer(pIter)).Fbase.FnData = 0
	(*TFts5Iter)(unsafe.Pointer(pIter)).Fbase.FpData = uintptr(0)
	ii = 0
	for {
		if !(int64(ii) < (*TFts5TokenDataIter)(unsafe.Pointer(pT)).FnIter) {
			break
		}
		p = *(*uintptr)(unsafe.Pointer(pT + 56 + uintptr(ii)*4))
		if libc.Int32FromUint8((*TFts5Iter)(unsafe.Pointer(p)).Fbase.FbEof) == 0 {
			if nHit == 0 || (*TFts5Iter)(unsafe.Pointer(p)).Fbase.FiRowid < iRowid {
				iRowid = (*TFts5Iter)(unsafe.Pointer(p)).Fbase.FiRowid
				nHit = int32(1)
				(*TFts5Iter)(unsafe.Pointer(pIter)).Fbase.FpData = (*TFts5Iter)(unsafe.Pointer(p)).Fbase.FpData
				(*TFts5Iter)(unsafe.Pointer(pIter)).Fbase.FnData = (*TFts5Iter)(unsafe.Pointer(p)).Fbase.FnData
				iMin = ii
			} else {
				if (*TFts5Iter)(unsafe.Pointer(p)).Fbase.FiRowid == iRowid {
					nHit = nHit + 1
				}
			}
		}
		goto _1
	_1:
		;
		ii = ii + 1
	}
	if nHit == 0 {
		(*TFts5Iter)(unsafe.Pointer(pIter)).Fbase.FbEof = uint8(1)
	} else {
		eDetail = (*TFts5Config)(unsafe.Pointer((*TFts5Index)(unsafe.Pointer((*TFts5Iter)(unsafe.Pointer(pIter)).FpIndex)).FpConfig)).FeDetail
		(*TFts5Iter)(unsafe.Pointer(pIter)).Fbase.FbEof = uint8(0)
		(*TFts5Iter)(unsafe.Pointer(pIter)).Fbase.FiRowid = iRowid
		if nHit == int32(1) && eDetail == FTS5_DETAIL_FULL {
			_fts5TokendataIterAppendMap(tls, (*TFts5Iter)(unsafe.Pointer(pIter)).FpIndex, pT, iMin, 0, iRowid, int64(-int32(1)))
		} else {
			if nHit > int32(1) && eDetail != int32(FTS5_DETAIL_NONE) {
				nReader = 0
				nByte = 0
				**(**Ti64)(__ccgo_up(bp)) = 0
				/* Allocate array of iterators if they are not already allocated. */
				if (*TFts5TokenDataIter)(unsafe.Pointer(pT)).FaPoslistReader == uintptr(0) {
					(*TFts5TokenDataIter)(unsafe.Pointer(pT)).FaPoslistReader = _sqlite3Fts5MallocZero(tls, (*TFts5Iter)(unsafe.Pointer(pIter)).FpIndex+40, (*TFts5TokenDataIter)(unsafe.Pointer(pT)).FnIter*libc.Int64FromUint32(libc.Uint32FromInt64(24)+libc.Uint32FromInt64(4)))
					if (*TFts5TokenDataIter)(unsafe.Pointer(pT)).FaPoslistReader == uintptr(0) {
						return
					}
					(*TFts5TokenDataIter)(unsafe.Pointer(pT)).FaPoslistToIter = (*TFts5TokenDataIter)(unsafe.Pointer(pT)).FaPoslistReader + uintptr((*TFts5TokenDataIter)(unsafe.Pointer(pT)).FnIter)*24
				}
				/* Populate an iterator for each poslist that will be merged */
				ii = 0
				for {
					if !(int64(ii) < (*TFts5TokenDataIter)(unsafe.Pointer(pT)).FnIter) {
						break
					}
					p1 = *(*uintptr)(unsafe.Pointer(pT + 56 + uintptr(ii)*4))
					if iRowid == (*TFts5Iter)(unsafe.Pointer(p1)).Fbase.FiRowid {
						**(**int32)(__ccgo_up((*TFts5TokenDataIter)(unsafe.Pointer(pT)).FaPoslistToIter + uintptr(nReader)*4)) = ii
						v3 = nReader
						nReader = nReader + 1
						_sqlite3Fts5PoslistReaderInit(tls, (*TFts5Iter)(unsafe.Pointer(p1)).Fbase.FpData, (*TFts5Iter)(unsafe.Pointer(p1)).Fbase.FnData, (*TFts5TokenDataIter)(unsafe.Pointer(pT)).FaPoslistReader+uintptr(v3)*24)
						nByte = nByte + (*TFts5Iter)(unsafe.Pointer(p1)).Fbase.FnData
					}
					goto _2
				_2:
					;
					ii = ii + 1
				}
				/* Ensure the output buffer is large enough */
				if libc.Uint32FromInt32((*TFts5Buffer)(unsafe.Pointer(pIter+28)).Fn)+libc.Uint32FromInt32(nByte+nHit*libc.Int32FromInt32(10)) <= libc.Uint32FromInt32((*TFts5Buffer)(unsafe.Pointer(pIter+28)).FnSpace) {
					v3 = 0
				} else {
					v3 = _sqlite3Fts5BufferSize(tls, (*TFts5Iter)(unsafe.Pointer(pIter)).FpIndex+40, pIter+28, libc.Uint32FromInt32(nByte+nHit*int32(10)+(*TFts5Buffer)(unsafe.Pointer(pIter+28)).Fn))
				}
				if v3 != 0 {
					return
				}
				/* Ensure the token-mapping is large enough */
				if eDetail == FTS5_DETAIL_FULL && (*TFts5TokenDataIter)(unsafe.Pointer(pT)).FnMapAlloc < (*TFts5TokenDataIter)(unsafe.Pointer(pT)).FnMap+int64(nByte) {
					nNew = ((*TFts5TokenDataIter)(unsafe.Pointer(pT)).FnMapAlloc + int64(nByte)) * int64(2)
					aNew = Xsqlite3_realloc64(tls, (*TFts5TokenDataIter)(unsafe.Pointer(pT)).FaMap, libc.Uint64FromInt64(nNew*int64(24)))
					if aNew == uintptr(0) {
						(*TFts5Index)(unsafe.Pointer((*TFts5Iter)(unsafe.Pointer(pIter)).FpIndex)).Frc = int32(SQLITE_NOMEM)
						return
					}
					(*TFts5TokenDataIter)(unsafe.Pointer(pT)).FaMap = aNew
					(*TFts5TokenDataIter)(unsafe.Pointer(pT)).FnMapAlloc = nNew
				}
				(*TFts5Iter)(unsafe.Pointer(pIter)).Fposlist.Fn = 0
				for int32(1) != 0 {
					iMinPos = libc.Int64FromUint32(0xffffffff) | libc.Int64FromInt32(0x7fffffff)<<libc.Int32FromInt32(32)
					/* Find smallest position */
					iMin = 0
					ii = 0
					for {
						if !(ii < nReader) {
							break
						}
						pReader = (*TFts5TokenDataIter)(unsafe.Pointer(pT)).FaPoslistReader + uintptr(ii)*24
						if libc.Int32FromUint8((*TFts5PoslistReader)(unsafe.Pointer(pReader)).FbEof) == 0 {
							if (*TFts5PoslistReader)(unsafe.Pointer(pReader)).FiPos < iMinPos {
								iMinPos = (*TFts5PoslistReader)(unsafe.Pointer(pReader)).FiPos
								iMin = ii
							}
						}
						goto _5
					_5:
						;
						ii = ii + 1
					}
					/* If all readers were at EOF, break out of the loop. */
					if iMinPos == libc.Int64FromUint32(0xffffffff)|libc.Int64FromInt32(0x7fffffff)<<libc.Int32FromInt32(32) {
						break
					}
					_sqlite3Fts5PoslistSafeAppend(tls, pIter+28, bp, iMinPos)
					_sqlite3Fts5PoslistReaderNext(tls, (*TFts5TokenDataIter)(unsafe.Pointer(pT)).FaPoslistReader+uintptr(iMin)*24)
					if eDetail == FTS5_DETAIL_FULL {
						(**(**TFts5TokenDataMap)(__ccgo_up((*TFts5TokenDataIter)(unsafe.Pointer(pT)).FaMap + uintptr((*TFts5TokenDataIter)(unsafe.Pointer(pT)).FnMap)*24))).FiPos = iMinPos
						(**(**TFts5TokenDataMap)(__ccgo_up((*TFts5TokenDataIter)(unsafe.Pointer(pT)).FaMap + uintptr((*TFts5TokenDataIter)(unsafe.Pointer(pT)).FnMap)*24))).FiIter = **(**int32)(__ccgo_up((*TFts5TokenDataIter)(unsafe.Pointer(pT)).FaPoslistToIter + uintptr(iMin)*4))
						(**(**TFts5TokenDataMap)(__ccgo_up((*TFts5TokenDataIter)(unsafe.Pointer(pT)).FaMap + uintptr((*TFts5TokenDataIter)(unsafe.Pointer(pT)).FnMap)*24))).FiRowid = iRowid
						(*TFts5TokenDataIter)(unsafe.Pointer(pT)).FnMap = (*TFts5TokenDataIter)(unsafe.Pointer(pT)).FnMap + 1
					}
				}
				(*TFts5Iter)(unsafe.Pointer(pIter)).Fbase.FpData = (*TFts5Iter)(unsafe.Pointer(pIter)).Fposlist.Fp
				(*TFts5Iter)(unsafe.Pointer(pIter)).Fbase.FnData = (*TFts5Iter)(unsafe.Pointer(pIter)).Fposlist.Fn
			}
		}
	}
}

// C documentation
//
//	/*
//	** xSetOutputs callback used by detail=col when there is a column filter
//	** and there are 100 or more columns. Also called as a fallback from
//	** fts5IterSetOutputs_Col100 if the column-list spans more than one page.
//	*/
func _fts5IterSetOutputs_Col(tls *libc.TLS, pIter uintptr, pSeg uintptr) {
	_sqlite3Fts5BufferZero(tls, pIter+28)
	_fts5SegiterPoslist(tls, (*TFts5Iter)(unsafe.Pointer(pIter)).FpIndex, pSeg, (*TFts5Iter)(unsafe.Pointer(pIter)).FpColset, pIter+28)
	(*TFts5Iter)(unsafe.Pointer(pIter)).Fbase.FiRowid = (*TFts5SegIter)(unsafe.Pointer(pSeg)).FiRowid
	(*TFts5Iter)(unsafe.Pointer(pIter)).Fbase.FpData = (*TFts5Iter)(unsafe.Pointer(pIter)).Fposlist.Fp
	(*TFts5Iter)(unsafe.Pointer(pIter)).Fbase.FnData = (*TFts5Iter)(unsafe.Pointer(pIter)).Fposlist.Fn
}

// C documentation
//
//	/*
//	** xSetOutputs callback used by detail=full when there is a column filter.
//	*/
func _fts5IterSetOutputs_Full(tls *libc.TLS, pIter uintptr, pSeg uintptr) {
	var a, pColset, pRc uintptr
	_, _, _ = a, pColset, pRc
	pColset = (*TFts5Iter)(unsafe.Pointer(pIter)).FpColset
	(*TFts5Iter)(unsafe.Pointer(pIter)).Fbase.FiRowid = (*TFts5SegIter)(unsafe.Pointer(pSeg)).FiRowid
	if (*TFts5SegIter)(unsafe.Pointer(pSeg)).FiLeafOffset+int64((*TFts5SegIter)(unsafe.Pointer(pSeg)).FnPos) <= int64((*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pSeg)).FpLeaf)).FszLeaf) {
		/* All data is stored on the current page. Populate the output
		 ** variables to point into the body of the page object. */
		a = (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pSeg)).FpLeaf)).Fp + uintptr((*TFts5SegIter)(unsafe.Pointer(pSeg)).FiLeafOffset)
		pRc = (*TFts5Iter)(unsafe.Pointer(pIter)).FpIndex + 40
		_sqlite3Fts5BufferZero(tls, pIter+28)
		_fts5IndexExtractColset(tls, pRc, pColset, a, (*TFts5SegIter)(unsafe.Pointer(pSeg)).FnPos, pIter)
	} else {
		/* The data is distributed over two or more pages. Copy it into the
		 ** Fts5Iter.poslist buffer and then set the output pointer to point
		 ** to this buffer.  */
		_sqlite3Fts5BufferZero(tls, pIter+28)
		_fts5SegiterPoslist(tls, (*TFts5Iter)(unsafe.Pointer(pIter)).FpIndex, pSeg, pColset, pIter+28)
		(*TFts5Iter)(unsafe.Pointer(pIter)).Fbase.FpData = (*TFts5Iter)(unsafe.Pointer(pIter)).Fposlist.Fp
		(*TFts5Iter)(unsafe.Pointer(pIter)).Fbase.FnData = (*TFts5Iter)(unsafe.Pointer(pIter)).Fposlist.Fn
	}
}

// C documentation
//
//	/*
//	** xSetOutputs callback used by detail=full and detail=col tables when no
//	** column filters are specified.
//	*/
func _fts5IterSetOutputs_Nocolset(tls *libc.TLS, pIter uintptr, pSeg uintptr) {
	(*TFts5Iter)(unsafe.Pointer(pIter)).Fbase.FiRowid = (*TFts5SegIter)(unsafe.Pointer(pSeg)).FiRowid
	(*TFts5Iter)(unsafe.Pointer(pIter)).Fbase.FnData = (*TFts5SegIter)(unsafe.Pointer(pSeg)).FnPos
	if (*TFts5SegIter)(unsafe.Pointer(pSeg)).FiLeafOffset+int64((*TFts5SegIter)(unsafe.Pointer(pSeg)).FnPos) <= int64((*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pSeg)).FpLeaf)).FszLeaf) {
		/* All data is stored on the current page. Populate the output
		 ** variables to point into the body of the page object. */
		(*TFts5Iter)(unsafe.Pointer(pIter)).Fbase.FpData = (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pSeg)).FpLeaf)).Fp + uintptr((*TFts5SegIter)(unsafe.Pointer(pSeg)).FiLeafOffset)
	} else {
		/* The data is distributed over two or more pages. Copy it into the
		 ** Fts5Iter.poslist buffer and then set the output pointer to point
		 ** to this buffer.  */
		_sqlite3Fts5BufferZero(tls, pIter+28)
		_fts5SegiterPoslist(tls, (*TFts5Iter)(unsafe.Pointer(pIter)).FpIndex, pSeg, uintptr(0), pIter+28)
		(*TFts5Iter)(unsafe.Pointer(pIter)).Fbase.FpData = (*TFts5Iter)(unsafe.Pointer(pIter)).Fposlist.Fp
	}
}

// C documentation
//
//	/*
//	** The iterator object passed as the second argument currently contains
//	** no valid values except for the Fts5SegIter.pLeaf member variable. This
//	** function searches the leaf page for a term matching (pTerm/nTerm).
//	**
//	** If the specified term is found on the page, then the iterator is left
//	** pointing to it. If argument bGe is zero and the term is not found,
//	** the iterator is left pointing at EOF.
//	**
//	** If bGe is non-zero and the specified term is not found, then the
//	** iterator is left pointing to the smallest term in the segment that
//	** is larger than the specified term, even if this term is not on the
//	** current page.
//	*/
func _fts5LeafSeek(tls *libc.TLS, p uintptr, bGe int32, pIter uintptr, pTerm uintptr, nTerm int32) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var a uintptr
	var bEndOfPage int32
	var i, iPgidx, n, nCmp, nMatch, v1 Tu32
	var v2 uint32
	var _ /* iOff at bp+0 */ Tu32
	var _ /* iTermOff at bp+12 */ Tu32
	var _ /* nExtra at bp+16 */ int32
	var _ /* nKeep at bp+4 */ Tu32
	var _ /* nNew at bp+8 */ Tu32
	_, _, _, _, _, _, _, _, _ = a, bEndOfPage, i, iPgidx, n, nCmp, nMatch, v1, v2
	a = (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).Fp
	n = libc.Uint32FromInt32((*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).Fnn)
	nMatch = uint32(0)
	**(**Tu32)(__ccgo_up(bp + 4)) = uint32(0)
	**(**Tu32)(__ccgo_up(bp + 8)) = uint32(0) /* Current offset in pgidx */
	bEndOfPage = 0
	iPgidx = libc.Uint32FromInt32((*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).FszLeaf)
	iPgidx = iPgidx + libc.Uint32FromInt32(_sqlite3Fts5GetVarint32(tls, a+uintptr(iPgidx), bp+12))
	**(**Tu32)(__ccgo_up(bp)) = **(**Tu32)(__ccgo_up(bp + 12))
	if **(**Tu32)(__ccgo_up(bp)) > n {
		_fts5IndexCorruptIter(tls, p, pIter)
		return
	}
	for int32(1) != 0 {
		/* Figure out how many new bytes are in this term */
		v1 = **(**Tu32)(__ccgo_up(bp))
		**(**Tu32)(__ccgo_up(bp)) = **(**Tu32)(__ccgo_up(bp)) + 1
		**(**Tu32)(__ccgo_up(bp + 8)) = uint32(**(**Tu8)(__ccgo_up(a + uintptr(v1))))
		if **(**Tu32)(__ccgo_up(bp + 8))&uint32(0x80) != 0 {
			**(**Tu32)(__ccgo_up(bp)) = **(**Tu32)(__ccgo_up(bp)) - 1
			**(**Tu32)(__ccgo_up(bp)) = **(**Tu32)(__ccgo_up(bp)) + libc.Uint32FromInt32(_sqlite3Fts5GetVarint32(tls, a+uintptr(**(**Tu32)(__ccgo_up(bp))), bp+8))
		}
		if **(**Tu32)(__ccgo_up(bp + 4)) < nMatch {
			goto search_failed
		}
		if **(**Tu32)(__ccgo_up(bp))+**(**Tu32)(__ccgo_up(bp + 8)) > n {
			_fts5IndexCorruptIter(tls, p, pIter)
			return
		}
		if **(**Tu32)(__ccgo_up(bp + 4)) == nMatch {
			if **(**Tu32)(__ccgo_up(bp + 8)) < libc.Uint32FromInt32(nTerm)-nMatch {
				v2 = **(**Tu32)(__ccgo_up(bp + 8))
			} else {
				v2 = libc.Uint32FromInt32(nTerm) - nMatch
			}
			nCmp = v2
			i = uint32(0)
			for {
				if !(i < nCmp) {
					break
				}
				if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(a + uintptr(**(**Tu32)(__ccgo_up(bp))+i)))) != libc.Int32FromUint8(**(**Tu8)(__ccgo_up(pTerm + uintptr(nMatch+i)))) {
					break
				}
				goto _3
			_3:
				;
				i = i + 1
			}
			nMatch = nMatch + i
			if libc.Uint32FromInt32(nTerm) == nMatch {
				if i == **(**Tu32)(__ccgo_up(bp + 8)) {
					goto search_success
				} else {
					goto search_failed
				}
			} else {
				if i < **(**Tu32)(__ccgo_up(bp + 8)) && libc.Int32FromUint8(**(**Tu8)(__ccgo_up(a + uintptr(**(**Tu32)(__ccgo_up(bp))+i)))) > libc.Int32FromUint8(**(**Tu8)(__ccgo_up(pTerm + uintptr(nMatch)))) {
					goto search_failed
				}
			}
		}
		if iPgidx >= n {
			bEndOfPage = int32(1)
			break
		}
		iPgidx = iPgidx + libc.Uint32FromInt32(_sqlite3Fts5GetVarint32(tls, a+uintptr(iPgidx), bp+4))
		**(**Tu32)(__ccgo_up(bp + 12)) = **(**Tu32)(__ccgo_up(bp + 12)) + **(**Tu32)(__ccgo_up(bp + 4))
		**(**Tu32)(__ccgo_up(bp)) = **(**Tu32)(__ccgo_up(bp + 12))
		if **(**Tu32)(__ccgo_up(bp)) >= n {
			_fts5IndexCorruptIter(tls, p, pIter)
			return
		}
		/* Read the nKeep field of the next term. */
		v1 = **(**Tu32)(__ccgo_up(bp))
		**(**Tu32)(__ccgo_up(bp)) = **(**Tu32)(__ccgo_up(bp)) + 1
		**(**Tu32)(__ccgo_up(bp + 4)) = uint32(**(**Tu8)(__ccgo_up(a + uintptr(v1))))
		if **(**Tu32)(__ccgo_up(bp + 4))&uint32(0x80) != 0 {
			**(**Tu32)(__ccgo_up(bp)) = **(**Tu32)(__ccgo_up(bp)) - 1
			**(**Tu32)(__ccgo_up(bp)) = **(**Tu32)(__ccgo_up(bp)) + libc.Uint32FromInt32(_sqlite3Fts5GetVarint32(tls, a+uintptr(**(**Tu32)(__ccgo_up(bp))), bp+4))
		}
	}
	goto search_failed
search_failed:
	;
	if bGe == 0 {
		_fts5DataRelease(tls, (*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)
		(*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf = uintptr(0)
		return
	} else {
		if bEndOfPage != 0 {
			for cond := true; cond; cond = int32(1) != 0 {
				_fts5SegIterNextPage(tls, p, pIter)
				if (*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf == uintptr(0) {
					return
				}
				a = (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).Fp
				if libc.BoolInt32((*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).FszLeaf >= (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).Fnn) == 0 {
					iPgidx = libc.Uint32FromInt32((*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).FszLeaf)
					iPgidx = iPgidx + libc.Uint32FromInt32(_sqlite3Fts5GetVarint32(tls, (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).Fp+uintptr(iPgidx), bp))
					if **(**Tu32)(__ccgo_up(bp)) < uint32(4) || libc.Int64FromUint32(**(**Tu32)(__ccgo_up(bp))) >= int64((*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).FszLeaf) {
						_fts5IndexCorruptIter(tls, p, pIter)
						return
					} else {
						**(**Tu32)(__ccgo_up(bp + 4)) = uint32(0)
						**(**Tu32)(__ccgo_up(bp + 12)) = **(**Tu32)(__ccgo_up(bp))
						n = libc.Uint32FromInt32((*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).Fnn)
						**(**Tu32)(__ccgo_up(bp)) = **(**Tu32)(__ccgo_up(bp)) + libc.Uint32FromInt32(_sqlite3Fts5GetVarint32(tls, a+uintptr(**(**Tu32)(__ccgo_up(bp))), bp+8))
						break
					}
				}
			}
		}
	}
	goto search_success
search_success:
	;
	if libc.Int64FromUint32(**(**Tu32)(__ccgo_up(bp)))+libc.Int64FromUint32(**(**Tu32)(__ccgo_up(bp + 8))) > libc.Int64FromUint32(n) || **(**Tu32)(__ccgo_up(bp + 8)) < uint32(1) {
		_fts5IndexCorruptIter(tls, p, pIter)
		return
	}
	(*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafOffset = libc.Int64FromUint32(**(**Tu32)(__ccgo_up(bp)) + **(**Tu32)(__ccgo_up(bp + 8)))
	(*TFts5SegIter)(unsafe.Pointer(pIter)).FiTermLeafOffset = int32((*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafOffset)
	(*TFts5SegIter)(unsafe.Pointer(pIter)).FiTermLeafPgno = (*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafPgno
	_sqlite3Fts5BufferSet(tls, p+40, pIter+68, libc.Int32FromUint32(**(**Tu32)(__ccgo_up(bp + 4))), pTerm)
	_sqlite3Fts5BufferAppendBlob(tls, p+40, pIter+68, **(**Tu32)(__ccgo_up(bp + 8)), a+uintptr(**(**Tu32)(__ccgo_up(bp))))
	if iPgidx >= n {
		(*TFts5SegIter)(unsafe.Pointer(pIter)).FiEndofDoclist = (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).Fnn + int32(1)
	} else {
		iPgidx = iPgidx + libc.Uint32FromInt32(_sqlite3Fts5GetVarint32(tls, a+uintptr(iPgidx), bp+16))
		(*TFts5SegIter)(unsafe.Pointer(pIter)).FiEndofDoclist = libc.Int32FromUint32(**(**Tu32)(__ccgo_up(bp + 12)) + libc.Uint32FromInt32(**(**int32)(__ccgo_up(bp + 16))))
	}
	(*TFts5SegIter)(unsafe.Pointer(pIter)).FiPgidxOff = libc.Int32FromUint32(iPgidx)
	_fts5SegIterLoadRowid(tls, p, pIter)
	_fts5SegIterLoadNPos(tls, p, pIter)
}

// C documentation
//
//	/*
//	** Implementation of fts5_locale(LOCALE, TEXT) function.
//	**
//	** If parameter LOCALE is NULL, or a zero-length string, then a copy of
//	** TEXT is returned. Otherwise, both LOCALE and TEXT are interpreted as
//	** text, and the value returned is a blob consisting of:
//	**
//	**     * The 4 bytes 0x00, 0xE0, 0xB2, 0xEb (FTS5_LOCALE_HEADER).
//	**     * The LOCALE, as utf-8 text, followed by
//	**     * 0x00, followed by
//	**     * The TEXT, as utf-8 text.
//	**
//	** There is no final nul-terminator following the TEXT value.
//	*/
func _fts5LocaleFunc(tls *libc.TLS, pCtx uintptr, nArg int32, apArg uintptr) {
	var nBlob, nLocale, nText Ti64
	var p, pBlob, pCsr, zLocale, zText, v1 uintptr
	_, _, _, _, _, _, _, _, _ = nBlob, nLocale, nText, p, pBlob, pCsr, zLocale, zText, v1
	zLocale = uintptr(0)
	nLocale = 0
	zText = uintptr(0)
	nText = 0
	_ = nArg
	zLocale = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(apArg)))
	nLocale = int64(Xsqlite3_value_bytes(tls, **(**uintptr)(__ccgo_up(apArg))))
	zText = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(apArg + 1*4)))
	nText = int64(Xsqlite3_value_bytes(tls, **(**uintptr)(__ccgo_up(apArg + 1*4))))
	if zLocale == uintptr(0) || int32(**(**int8)(__ccgo_up(zLocale))) == int32('\000') {
		Xsqlite3_result_text(tls, pCtx, zText, int32(nText), uintptr(-libc.Int32FromInt32(1)))
	} else {
		p = Xsqlite3_user_data(tls, pCtx)
		pBlob = uintptr(0)
		pCsr = uintptr(0)
		nBlob = 0
		nBlob = int64(libc.Int32FromInt64(16)) + nLocale + int64(1) + nText
		pBlob = Xsqlite3_malloc64(tls, libc.Uint64FromInt64(nBlob))
		if pBlob == uintptr(0) {
			Xsqlite3_result_error_nomem(tls, pCtx)
			return
		}
		pCsr = pBlob
		libc.Xmemcpy(tls, pCsr, p+52, libc.Uint32FromInt32(libc.Int32FromInt64(16)))
		pCsr = pCsr + uintptr(libc.Int32FromInt64(16))
		libc.Xmemcpy(tls, pCsr, zLocale, libc.Uint32FromInt64(nLocale))
		pCsr = pCsr + uintptr(nLocale)
		v1 = pCsr
		pCsr = pCsr + 1
		**(**Tu8)(__ccgo_up(v1)) = uint8(0x00)
		if zText != 0 {
			libc.Xmemcpy(tls, pCsr, zText, libc.Uint32FromInt64(nText))
		}
		Xsqlite3_result_blob(tls, pCtx, pBlob, int32(nBlob), __ccgo_fp(Xsqlite3_free))
	}
}

func _fts5LookaheadReaderInit(tls *libc.TLS, a uintptr, n int32, p uintptr) (r int32) {
	libc.Xmemset(tls, p, 0, uint32(28))
	(*TFts5LookaheadReader)(unsafe.Pointer(p)).Fa = a
	(*TFts5LookaheadReader)(unsafe.Pointer(p)).Fn = n
	_fts5LookaheadReaderNext(tls, p)
	return _fts5LookaheadReaderNext(tls, p)
}

func _fts5LookaheadReaderNext(tls *libc.TLS, p uintptr) (r int32) {
	(*TFts5LookaheadReader)(unsafe.Pointer(p)).FiPos = (*TFts5LookaheadReader)(unsafe.Pointer(p)).FiLookahead
	if _sqlite3Fts5PoslistNext64(tls, (*TFts5LookaheadReader)(unsafe.Pointer(p)).Fa, (*TFts5LookaheadReader)(unsafe.Pointer(p)).Fn, p+8, p+20) != 0 {
		(*TFts5LookaheadReader)(unsafe.Pointer(p)).FiLookahead = libc.Int64FromInt32(1) << libc.Int32FromInt32(62)
	}
	return libc.BoolInt32((*TFts5LookaheadReader)(unsafe.Pointer(p)).FiPos == libc.Int64FromInt32(1)<<libc.Int32FromInt32(62))
}

// C documentation
//
//	/*
//	** Array aBuf[] contains nBuf doclists. These are all merged in with the
//	** doclist in buffer p1.
//	*/
func _fts5MergePrefixLists(tls *libc.TLS, p uintptr, p1 uintptr, nBuf int32, aBuf uintptr) {
	bp := tls.Alloc(752)
	defer tls.Free(752)
	var i, nMerge, nOut, nTail, nTmp int32
	var iLastRowid Ti64
	var pI, pNext, pSave, pThis, pThis1, pX uintptr
	var _ /* aMerger at bp+0 */ [16]TPrefixMerger
	var _ /* iPrev at bp+736 */ Ti64
	var _ /* out at bp+708 */ TFts5Buffer
	var _ /* pHead at bp+704 */ uintptr
	var _ /* tmp at bp+720 */ TFts5Buffer
	_, _, _, _, _, _, _, _, _, _, _, _ = i, iLastRowid, nMerge, nOut, nTail, nTmp, pI, pNext, pSave, pThis, pThis1, pX
	**(**uintptr)(__ccgo_up(bp + 704)) = uintptr(0)
	nOut = 0
	**(**TFts5Buffer)(__ccgo_up(bp + 708)) = TFts5Buffer{}
	**(**TFts5Buffer)(__ccgo_up(bp + 720)) = TFts5Buffer{}
	iLastRowid = 0
	/* Initialize a doclist-iterator for each input buffer. Arrange them in
	 ** a linked-list starting at pHead in ascending order of rowid. Avoid
	 ** linking any iterators already at EOF into the linked list at all. */
	libc.Xmemset(tls, bp, 0, uint32(44)*libc.Uint32FromInt32(nBuf+libc.Int32FromInt32(1)))
	**(**uintptr)(__ccgo_up(bp + 704)) = bp + uintptr(nBuf)*44
	_fts5DoclistIterInit(tls, p1, **(**uintptr)(__ccgo_up(bp + 704)))
	i = 0
	for {
		if !(i < nBuf) {
			break
		}
		_fts5DoclistIterInit(tls, aBuf+uintptr(i)*12, bp+uintptr(i)*44)
		_fts5PrefixMergerInsertByRowid(tls, bp+704, bp+uintptr(i)*44)
		nOut = nOut + (**(**TFts5Buffer)(__ccgo_up(aBuf + uintptr(i)*12))).Fn
		goto _1
	_1:
		;
		i = i + 1
	}
	if nOut == 0 {
		return
	}
	nOut = nOut + ((*TFts5Buffer)(unsafe.Pointer(p1)).Fn + int32(9) + int32(10)*nBuf)
	/* The maximum size of the output is equal to the sum of the
	 ** input sizes + 1 varint (9 bytes). The extra varint is because if the
	 ** first rowid in one input is a large negative number, and the first in
	 ** the other a non-negative number, the delta for the non-negative
	 ** number will be larger on disk than the literal integer value
	 ** was.
	 **
	 ** Or, if the input position-lists are corrupt, then the output might
	 ** include up to (nBuf+1) extra 10-byte positions created by interpreting -1
	 ** (the value PoslistNext64() uses for EOF) as a position and appending
	 ** it to the output. This can happen at most once for each input
	 ** position-list, hence (nBuf+1) 10 byte paddings.  */
	if _sqlite3Fts5BufferSize(tls, p+40, bp+708, libc.Uint32FromInt32(nOut)) != 0 {
		return
	}
	for **(**uintptr)(__ccgo_up(bp + 704)) != 0 {
		**(**int32)(__ccgo_up(bp + 708 + 4)) += _sqlite3Fts5PutVarint(tls, (*TFts5Buffer)(unsafe.Pointer(bp+708)).Fp+uintptr((*TFts5Buffer)(unsafe.Pointer(bp+708)).Fn), libc.Uint64FromInt64((*TPrefixMerger)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 704)))).Fiter.FiRowid)-libc.Uint64FromInt64(iLastRowid))
		iLastRowid = (*TPrefixMerger)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 704)))).Fiter.FiRowid
		if (*TPrefixMerger)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 704)))).FpNext != 0 && iLastRowid == (*TPrefixMerger)(unsafe.Pointer((*TPrefixMerger)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 704)))).FpNext)).Fiter.FiRowid {
			/* Merge data from two or more poslists */
			**(**Ti64)(__ccgo_up(bp + 736)) = 0
			nTmp = int32(FTS5_DATA_ZERO_PADDING)
			nMerge = 0
			pSave = **(**uintptr)(__ccgo_up(bp + 704))
			pThis = uintptr(0)
			nTail = 0
			**(**uintptr)(__ccgo_up(bp + 704)) = uintptr(0)
			for pSave != 0 && (*TPrefixMerger)(unsafe.Pointer(pSave)).Fiter.FiRowid == iLastRowid {
				pNext = (*TPrefixMerger)(unsafe.Pointer(pSave)).FpNext
				(*TPrefixMerger)(unsafe.Pointer(pSave)).FiOff = 0
				(*TPrefixMerger)(unsafe.Pointer(pSave)).FiPos = 0
				(*TPrefixMerger)(unsafe.Pointer(pSave)).FaPos = (*TPrefixMerger)(unsafe.Pointer(pSave)).Fiter.FaPoslist + uintptr((*TPrefixMerger)(unsafe.Pointer(pSave)).Fiter.FnSize)
				_sqlite3Fts5PoslistNext64(tls, (*TPrefixMerger)(unsafe.Pointer(pSave)).FaPos, (*TPrefixMerger)(unsafe.Pointer(pSave)).Fiter.FnPoslist, pSave+32, pSave+24)
				nTmp = nTmp + ((*TPrefixMerger)(unsafe.Pointer(pSave)).Fiter.FnPoslist + int32(10))
				nMerge = nMerge + 1
				_fts5PrefixMergerInsertByPosition(tls, bp+704, pSave)
				pSave = pNext
			}
			if **(**uintptr)(__ccgo_up(bp + 704)) == uintptr(0) || (*TPrefixMerger)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 704)))).FpNext == uintptr(0) {
				_fts5IndexCorruptIdx(tls, p)
				break
			}
			/* See the earlier comment in this function for an explanation of why
			 ** corrupt input position lists might cause the output to consume
			 ** at most nMerge*10 bytes of unexpected space. */
			if _sqlite3Fts5BufferSize(tls, p+40, bp+720, libc.Uint32FromInt32(nTmp+nMerge*int32(10))) != 0 {
				break
			}
			_sqlite3Fts5BufferZero(tls, bp+720)
			pThis = **(**uintptr)(__ccgo_up(bp + 704))
			**(**uintptr)(__ccgo_up(bp + 704)) = (*TPrefixMerger)(unsafe.Pointer(pThis)).FpNext
			_sqlite3Fts5PoslistSafeAppend(tls, bp+720, bp+736, (*TPrefixMerger)(unsafe.Pointer(pThis)).FiPos)
			_sqlite3Fts5PoslistNext64(tls, (*TPrefixMerger)(unsafe.Pointer(pThis)).FaPos, (*TPrefixMerger)(unsafe.Pointer(pThis)).Fiter.FnPoslist, pThis+32, pThis+24)
			_fts5PrefixMergerInsertByPosition(tls, bp+704, pThis)
			for (*TPrefixMerger)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 704)))).FpNext != 0 {
				pThis = **(**uintptr)(__ccgo_up(bp + 704))
				if (*TPrefixMerger)(unsafe.Pointer(pThis)).FiPos != **(**Ti64)(__ccgo_up(bp + 736)) {
					_sqlite3Fts5PoslistSafeAppend(tls, bp+720, bp+736, (*TPrefixMerger)(unsafe.Pointer(pThis)).FiPos)
				}
				_sqlite3Fts5PoslistNext64(tls, (*TPrefixMerger)(unsafe.Pointer(pThis)).FaPos, (*TPrefixMerger)(unsafe.Pointer(pThis)).Fiter.FnPoslist, pThis+32, pThis+24)
				**(**uintptr)(__ccgo_up(bp + 704)) = (*TPrefixMerger)(unsafe.Pointer(pThis)).FpNext
				_fts5PrefixMergerInsertByPosition(tls, bp+704, pThis)
			}
			if (*TPrefixMerger)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 704)))).FiPos != **(**Ti64)(__ccgo_up(bp + 736)) {
				_sqlite3Fts5PoslistSafeAppend(tls, bp+720, bp+736, (*TPrefixMerger)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 704)))).FiPos)
			}
			nTail = (*TPrefixMerger)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 704)))).Fiter.FnPoslist - (*TPrefixMerger)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 704)))).FiOff
			/* WRITEPOSLISTSIZE */
			if (**(**TFts5Buffer)(__ccgo_up(bp + 720))).Fn+nTail > nTmp-int32(FTS5_DATA_ZERO_PADDING) {
				if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
					_fts5IndexCorruptIdx(tls, p)
				}
				break
			}
			**(**int32)(__ccgo_up(bp + 708 + 4)) += _sqlite3Fts5PutVarint(tls, (*TFts5Buffer)(unsafe.Pointer(bp+708)).Fp+uintptr((*TFts5Buffer)(unsafe.Pointer(bp+708)).Fn), libc.Uint64FromInt32(((**(**TFts5Buffer)(__ccgo_up(bp + 720))).Fn+nTail)*libc.Int32FromInt32(2)))
			libc.Xmemcpy(tls, (*TFts5Buffer)(unsafe.Pointer(bp+708)).Fp+uintptr((*TFts5Buffer)(unsafe.Pointer(bp+708)).Fn), (**(**TFts5Buffer)(__ccgo_up(bp + 720))).Fp, libc.Uint32FromInt32((**(**TFts5Buffer)(__ccgo_up(bp + 720))).Fn))
			**(**int32)(__ccgo_up(bp + 708 + 4)) += (**(**TFts5Buffer)(__ccgo_up(bp + 720))).Fn
			if nTail > 0 {
				libc.Xmemcpy(tls, (*TFts5Buffer)(unsafe.Pointer(bp+708)).Fp+uintptr((*TFts5Buffer)(unsafe.Pointer(bp+708)).Fn), (*TPrefixMerger)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 704)))).FaPos+uintptr((*TPrefixMerger)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 704)))).FiOff), libc.Uint32FromInt32(nTail))
				**(**int32)(__ccgo_up(bp + 708 + 4)) += nTail
			}
			**(**uintptr)(__ccgo_up(bp + 704)) = pSave
			i = 0
			for {
				if !(i < nBuf+int32(1)) {
					break
				}
				pX = bp + uintptr(i)*44
				if (*TPrefixMerger)(unsafe.Pointer(pX)).Fiter.FaPoslist != 0 && (*TPrefixMerger)(unsafe.Pointer(pX)).Fiter.FiRowid == iLastRowid {
					_fts5DoclistIterNext(tls, pX)
					_fts5PrefixMergerInsertByRowid(tls, bp+704, pX)
				}
				goto _2
			_2:
				;
				i = i + 1
			}
		} else {
			/* Copy poslist from pHead to output */
			pThis1 = **(**uintptr)(__ccgo_up(bp + 704))
			pI = pThis1
			libc.Xmemcpy(tls, (*TFts5Buffer)(unsafe.Pointer(bp+708)).Fp+uintptr((*TFts5Buffer)(unsafe.Pointer(bp+708)).Fn), (*TFts5DoclistIter)(unsafe.Pointer(pI)).FaPoslist, libc.Uint32FromInt32((*TFts5DoclistIter)(unsafe.Pointer(pI)).FnPoslist+(*TFts5DoclistIter)(unsafe.Pointer(pI)).FnSize))
			**(**int32)(__ccgo_up(bp + 708 + 4)) += (*TFts5DoclistIter)(unsafe.Pointer(pI)).FnPoslist + (*TFts5DoclistIter)(unsafe.Pointer(pI)).FnSize
			_fts5DoclistIterNext(tls, pI)
			**(**uintptr)(__ccgo_up(bp + 704)) = (*TPrefixMerger)(unsafe.Pointer(pThis1)).FpNext
			_fts5PrefixMergerInsertByRowid(tls, bp+704, pThis1)
		}
	}
	_sqlite3Fts5BufferFree(tls, p1)
	_sqlite3Fts5BufferFree(tls, bp+720)
	libc.Xmemset(tls, (**(**TFts5Buffer)(__ccgo_up(bp + 708))).Fp+uintptr((**(**TFts5Buffer)(__ccgo_up(bp + 708))).Fn), 0, uint32(FTS5_DATA_ZERO_PADDING))
	**(**TFts5Buffer)(__ccgo_up(p1)) = **(**TFts5Buffer)(__ccgo_up(bp + 708))
}

// C documentation
//
//	/*
//	** This is the equivalent of fts5MergePrefixLists() for detail=none mode.
//	** In this case the buffers consist of a delta-encoded list of rowids only.
//	*/
func _fts5MergeRowidLists(tls *libc.TLS, p uintptr, p1 uintptr, nBuf int32, aBuf uintptr) {
	bp := tls.Alloc(48)
	defer tls.Free(48)
	var iOut Ti64
	var p2 uintptr
	var _ /* i1 at bp+0 */ int32
	var _ /* i2 at bp+4 */ int32
	var _ /* iRowid1 at bp+8 */ Ti64
	var _ /* iRowid2 at bp+16 */ Ti64
	var _ /* out at bp+24 */ TFts5Buffer
	_, _ = iOut, p2
	**(**int32)(__ccgo_up(bp)) = 0
	**(**int32)(__ccgo_up(bp + 4)) = 0
	**(**Ti64)(__ccgo_up(bp + 8)) = 0
	**(**Ti64)(__ccgo_up(bp + 16)) = 0
	iOut = 0
	p2 = aBuf
	_ = nBuf
	libc.Xmemset(tls, bp+24, 0, uint32(12))
	_sqlite3Fts5BufferSize(tls, p+40, bp+24, libc.Uint32FromInt32((*TFts5Buffer)(unsafe.Pointer(p1)).Fn+(*TFts5Buffer)(unsafe.Pointer(p2)).Fn))
	if (*TFts5Index)(unsafe.Pointer(p)).Frc != 0 {
		return
	}
	_fts5NextRowid(tls, p1, bp, bp+8)
	_fts5NextRowid(tls, p2, bp+4, bp+16)
	for **(**int32)(__ccgo_up(bp)) >= 0 || **(**int32)(__ccgo_up(bp + 4)) >= 0 {
		if **(**int32)(__ccgo_up(bp)) >= 0 && (**(**int32)(__ccgo_up(bp + 4)) < 0 || **(**Ti64)(__ccgo_up(bp + 8)) < **(**Ti64)(__ccgo_up(bp + 16))) {
			**(**int32)(__ccgo_up(bp + 24 + 4)) += _sqlite3Fts5PutVarint(tls, (*TFts5Buffer)(unsafe.Pointer(bp+24)).Fp+uintptr((*TFts5Buffer)(unsafe.Pointer(bp+24)).Fn), libc.Uint64FromInt64(**(**Ti64)(__ccgo_up(bp + 8))-iOut))
			iOut = **(**Ti64)(__ccgo_up(bp + 8))
			_fts5NextRowid(tls, p1, bp, bp+8)
		} else {
			**(**int32)(__ccgo_up(bp + 24 + 4)) += _sqlite3Fts5PutVarint(tls, (*TFts5Buffer)(unsafe.Pointer(bp+24)).Fp+uintptr((*TFts5Buffer)(unsafe.Pointer(bp+24)).Fn), libc.Uint64FromInt64(**(**Ti64)(__ccgo_up(bp + 16))-iOut))
			iOut = **(**Ti64)(__ccgo_up(bp + 16))
			if **(**int32)(__ccgo_up(bp)) >= 0 && **(**Ti64)(__ccgo_up(bp + 8)) == **(**Ti64)(__ccgo_up(bp + 16)) {
				_fts5NextRowid(tls, p1, bp, bp+8)
			}
			_fts5NextRowid(tls, p2, bp+4, bp+16)
		}
	}
	_fts5BufferSwap(tls, bp+24, p1)
	_sqlite3Fts5BufferFree(tls, bp+24)
}

// C documentation
//
//	/*
//	** Sub-iterator iChanged of iterator pIter has just been advanced. It still
//	** points to the same term though - just a different rowid. This function
//	** attempts to update the contents of the pIter->aFirst[] accordingly.
//	** If it does so successfully, 0 is returned. Otherwise 1.
//	**
//	** If non-zero is returned, the caller should call fts5MultiIterAdvanced()
//	** on the iterator instead. That function does the same as this one, except
//	** that it deals with more complicated cases as well.
//	*/
func _fts5MultiIterAdvanceRowid(tls *libc.TLS, pIter uintptr, iChanged int32, ppFirst uintptr) (r int32) {
	var i int32
	var pNew, pOther, pRes uintptr
	var v1 int64
	_, _, _, _, _ = i, pNew, pOther, pRes, v1
	pNew = pIter + 72 + uintptr(iChanged)*96
	if (*TFts5SegIter)(unsafe.Pointer(pNew)).FiRowid == (*TFts5Iter)(unsafe.Pointer(pIter)).FiSwitchRowid || libc.BoolInt32((*TFts5SegIter)(unsafe.Pointer(pNew)).FiRowid < (*TFts5Iter)(unsafe.Pointer(pIter)).FiSwitchRowid) == (*TFts5Iter)(unsafe.Pointer(pIter)).FbRev {
		pOther = pIter + 72 + uintptr(iChanged^int32(0x0001))*96
		if (*TFts5Iter)(unsafe.Pointer(pIter)).FbRev != 0 {
			v1 = int64(-libc.Int32FromInt32(1)) - (libc.Int64FromUint32(0xffffffff) | libc.Int64FromInt32(0x7fffffff)<<libc.Int32FromInt32(32))
		} else {
			v1 = libc.Int64FromUint32(0xffffffff) | libc.Int64FromInt32(0x7fffffff)<<libc.Int32FromInt32(32)
		}
		(*TFts5Iter)(unsafe.Pointer(pIter)).FiSwitchRowid = v1
		i = ((*TFts5Iter)(unsafe.Pointer(pIter)).FnSeg + iChanged) / int32(2)
		for {
			if !(int32(1) != 0) {
				break
			}
			pRes = (*TFts5Iter)(unsafe.Pointer(pIter)).FaFirst + uintptr(i)*4
			if (*TFts5CResult)(unsafe.Pointer(pRes)).FbTermEq != 0 {
				if (*TFts5SegIter)(unsafe.Pointer(pNew)).FiRowid == (*TFts5SegIter)(unsafe.Pointer(pOther)).FiRowid {
					return int32(1)
				} else {
					if libc.BoolInt32((*TFts5SegIter)(unsafe.Pointer(pOther)).FiRowid > (*TFts5SegIter)(unsafe.Pointer(pNew)).FiRowid) == (*TFts5Iter)(unsafe.Pointer(pIter)).FbRev {
						(*TFts5Iter)(unsafe.Pointer(pIter)).FiSwitchRowid = (*TFts5SegIter)(unsafe.Pointer(pOther)).FiRowid
						pNew = pOther
					} else {
						if libc.BoolInt32((*TFts5SegIter)(unsafe.Pointer(pOther)).FiRowid > (*TFts5Iter)(unsafe.Pointer(pIter)).FiSwitchRowid) == (*TFts5Iter)(unsafe.Pointer(pIter)).FbRev {
							(*TFts5Iter)(unsafe.Pointer(pIter)).FiSwitchRowid = (*TFts5SegIter)(unsafe.Pointer(pOther)).FiRowid
						}
					}
				}
			}
			(*TFts5CResult)(unsafe.Pointer(pRes)).FiFirst = libc.Uint16FromInt32((int32(pNew) - t__predefined_ptrdiff_t(pIter+72)) / 96)
			if i == int32(1) {
				break
			}
			pOther = pIter + 72 + uintptr((**(**TFts5CResult)(__ccgo_up((*TFts5Iter)(unsafe.Pointer(pIter)).FaFirst + uintptr(i^int32(0x0001))*4))).FiFirst)*96
			goto _2
		_2:
			;
			i = i / int32(2)
		}
	}
	**(**uintptr)(__ccgo_up(ppFirst)) = pNew
	return 0
}

func _fts5MultiIterAdvanced(tls *libc.TLS, p uintptr, pIter uintptr, iChanged int32, iMinset int32) {
	var i, iEq, v2 int32
	var pSeg uintptr
	_, _, _, _ = i, iEq, pSeg, v2
	i = ((*TFts5Iter)(unsafe.Pointer(pIter)).FnSeg + iChanged) / int32(2)
	for {
		if !(i >= iMinset && (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK) {
			break
		}
		v2 = _fts5MultiIterDoCompare(tls, pIter, i)
		iEq = v2
		if v2 != 0 {
			pSeg = pIter + 72 + uintptr(iEq)*96
			(*(*func(*libc.TLS, uintptr, uintptr, uintptr))(unsafe.Pointer(&struct{ uintptr }{(*TFts5SegIter)(unsafe.Pointer(pSeg)).FxNext})))(tls, p, pSeg, uintptr(0))
			i = (*TFts5Iter)(unsafe.Pointer(pIter)).FnSeg + iEq
		}
		goto _1
	_1:
		;
		i = i / int32(2)
	}
}

func _fts5MultiIterAlloc(tls *libc.TLS, p uintptr, nSeg int32) (r uintptr) {
	var nSlot Ti64
	var pNew uintptr
	_, _ = nSlot, pNew /* Power of two >= nSeg */
	nSlot = int64(2)
	for {
		if !(nSlot < int64(nSeg)) {
			break
		}
		goto _1
	_1:
		;
		nSlot = nSlot * int64(2)
	}
	pNew = _fts5IdxMalloc(tls, p, libc.Int64FromUint32(uint32(libc.UintptrFromInt32(0)+72))+nSlot*int64(96)+int64(4)*nSlot)
	if pNew != 0 {
		(*TFts5Iter)(unsafe.Pointer(pNew)).FnSeg = int32(nSlot)
		(*TFts5Iter)(unsafe.Pointer(pNew)).FaFirst = pNew + 72 + uintptr(nSlot)*96
		(*TFts5Iter)(unsafe.Pointer(pNew)).FpIndex = p
		(*TFts5Iter)(unsafe.Pointer(pNew)).FxSetOutputs = __ccgo_fp(_fts5IterSetOutputs_Noop)
	}
	return pNew
}

// C documentation
//
//	/*
//	** Do the comparison necessary to populate pIter->aFirst[iOut].
//	**
//	** If the returned value is non-zero, then it is the index of an entry
//	** in the pIter->aSeg[] array that is (a) not at EOF, and (b) pointing
//	** to a key that is a duplicate of another, higher priority,
//	** segment-iterator in the pSeg->aSeg[] array.
//	*/
func _fts5MultiIterDoCompare(tls *libc.TLS, pIter uintptr, iOut int32) (r int32) {
	var i1, i2, iRes, res, v1 int32
	var p1, p2, pRes uintptr
	_, _, _, _, _, _, _, _ = i1, i2, iRes, p1, p2, pRes, res, v1 /* Right-hand Fts5SegIter */
	pRes = (*TFts5Iter)(unsafe.Pointer(pIter)).FaFirst + uintptr(iOut)*4
	if iOut >= (*TFts5Iter)(unsafe.Pointer(pIter)).FnSeg/int32(2) {
		i1 = (iOut - (*TFts5Iter)(unsafe.Pointer(pIter)).FnSeg/int32(2)) * int32(2)
		i2 = i1 + int32(1)
	} else {
		i1 = libc.Int32FromUint16((**(**TFts5CResult)(__ccgo_up((*TFts5Iter)(unsafe.Pointer(pIter)).FaFirst + uintptr(iOut*int32(2))*4))).FiFirst)
		i2 = libc.Int32FromUint16((**(**TFts5CResult)(__ccgo_up((*TFts5Iter)(unsafe.Pointer(pIter)).FaFirst + uintptr(iOut*int32(2)+int32(1))*4))).FiFirst)
	}
	p1 = pIter + 72 + uintptr(i1)*96
	p2 = pIter + 72 + uintptr(i2)*96
	(*TFts5CResult)(unsafe.Pointer(pRes)).FbTermEq = uint8(0)
	if (*TFts5SegIter)(unsafe.Pointer(p1)).FpLeaf == uintptr(0) { /* If p1 is at EOF */
		iRes = i2
	} else {
		if (*TFts5SegIter)(unsafe.Pointer(p2)).FpLeaf == uintptr(0) { /* If p2 is at EOF */
			iRes = i1
		} else {
			res = _fts5BufferCompare(tls, p1+68, p2+68)
			if res == 0 {
				(*TFts5CResult)(unsafe.Pointer(pRes)).FbTermEq = uint8(1)
				if (*TFts5SegIter)(unsafe.Pointer(p1)).FiRowid == (*TFts5SegIter)(unsafe.Pointer(p2)).FiRowid {
					return i2
				}
				if libc.BoolInt32((*TFts5SegIter)(unsafe.Pointer(p1)).FiRowid > (*TFts5SegIter)(unsafe.Pointer(p2)).FiRowid) == (*TFts5Iter)(unsafe.Pointer(pIter)).FbRev {
					v1 = -int32(1)
				} else {
					v1 = +libc.Int32FromInt32(1)
				}
				res = v1
			}
			if res < 0 {
				iRes = i1
			} else {
				iRes = i2
			}
		}
	}
	(*TFts5CResult)(unsafe.Pointer(pRes)).FiFirst = libc.Uint16FromInt32(iRes)
	return 0
}

// C documentation
//
//	/*
//	** All the component segment-iterators of pIter have been set up. This
//	** functions finishes setup for iterator pIter itself.
//	*/
func _fts5MultiIterFinishSetup(tls *libc.TLS, p uintptr, pIter uintptr) {
	var iEq, iIter, v2 int32
	var pSeg, pSeg1 uintptr
	_, _, _, _, _ = iEq, iIter, pSeg, pSeg1, v2
	iIter = (*TFts5Iter)(unsafe.Pointer(pIter)).FnSeg - int32(1)
	for {
		if !(iIter > 0) {
			break
		}
		v2 = _fts5MultiIterDoCompare(tls, pIter, iIter)
		iEq = v2
		if v2 != 0 {
			pSeg = pIter + 72 + uintptr(iEq)*96
			if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
				(*(*func(*libc.TLS, uintptr, uintptr, uintptr))(unsafe.Pointer(&struct{ uintptr }{(*TFts5SegIter)(unsafe.Pointer(pSeg)).FxNext})))(tls, p, pSeg, uintptr(0))
			}
			_fts5MultiIterAdvanced(tls, p, pIter, iEq, iIter)
		}
		goto _1
	_1:
		;
		iIter = iIter - 1
	}
	_fts5MultiIterSetEof(tls, pIter)
	if (*TFts5Iter)(unsafe.Pointer(pIter)).FbSkipEmpty != 0 && _fts5MultiIterIsEmpty(tls, p, pIter) != 0 || _fts5MultiIterIsDeleted(tls, pIter) != 0 {
		_fts5MultiIterNext(tls, p, pIter, 0, 0)
	} else {
		if libc.Int32FromUint8((*TFts5Iter)(unsafe.Pointer(pIter)).Fbase.FbEof) == 0 {
			pSeg1 = pIter + 72 + uintptr((**(**TFts5CResult)(__ccgo_up((*TFts5Iter)(unsafe.Pointer(pIter)).FaFirst + 1*4))).FiFirst)*96
			(*(*func(*libc.TLS, uintptr, uintptr))(unsafe.Pointer(&struct{ uintptr }{(*TFts5Iter)(unsafe.Pointer(pIter)).FxSetOutputs})))(tls, pIter, pSeg1)
		}
	}
}

// C documentation
//
//	/*
//	** Free the iterator object passed as the second argument.
//	*/
func _fts5MultiIterFree(tls *libc.TLS, pIter uintptr) {
	var i int32
	_ = i
	if pIter != 0 {
		i = 0
		for {
			if !(i < (*TFts5Iter)(unsafe.Pointer(pIter)).FnSeg) {
				break
			}
			_fts5SegIterClear(tls, pIter+72+uintptr(i)*96)
			goto _1
		_1:
			;
			i = i + 1
		}
		_sqlite3Fts5BufferFree(tls, pIter+28)
		Xsqlite3_free(tls, pIter)
	}
}

// C documentation
//
//	/*
//	** Return true if the iterator passed as the only argument points
//	** to an segment entry for which there is a tombstone. Return false
//	** if there is no tombstone or if the iterator is already at EOF.
//	*/
func _fts5MultiIterIsDeleted(tls *libc.TLS, pIter uintptr) (r int32) {
	var iFirst, iPg int32
	var pArray, pSeg uintptr
	_, _, _, _ = iFirst, iPg, pArray, pSeg
	iFirst = libc.Int32FromUint16((**(**TFts5CResult)(__ccgo_up((*TFts5Iter)(unsafe.Pointer(pIter)).FaFirst + 1*4))).FiFirst)
	pSeg = pIter + 72 + uintptr(iFirst)*96
	pArray = (*TFts5SegIter)(unsafe.Pointer(pSeg)).FpTombArray
	if (*TFts5SegIter)(unsafe.Pointer(pSeg)).FpLeaf != 0 && pArray != 0 {
		/* Figure out which page the rowid might be present on. */
		iPg = libc.Int32FromUint64(libc.Uint64FromInt64((*TFts5SegIter)(unsafe.Pointer(pSeg)).FiRowid) % libc.Uint64FromInt32((*TFts5TombstoneArray)(unsafe.Pointer(pArray)).FnTombstone))
		/* If tombstone hash page iPg has not yet been loaded from the
		 ** database, load it now. */
		if *(*uintptr)(unsafe.Pointer(pArray + 8 + uintptr(iPg)*4)) == uintptr(0) {
			*(*uintptr)(unsafe.Pointer(pArray + 8 + uintptr(iPg)*4)) = _fts5DataRead(tls, (*TFts5Iter)(unsafe.Pointer(pIter)).FpIndex, int64((*TFts5StructureSegment)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pSeg)).FpSeg)).FiSegid+libc.Int32FromInt32(1)<<libc.Int32FromInt32(16))<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B)+libc.Int32FromInt32(FTS5_DATA_DLI_B))+int64(libc.Int32FromInt32(0))<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B))+int64(libc.Int32FromInt32(0))<<libc.Int32FromInt32(FTS5_DATA_PAGE_B)+int64(iPg))
			if *(*uintptr)(unsafe.Pointer(pArray + 8 + uintptr(iPg)*4)) == uintptr(0) {
				return 0
			}
		}
		return _fts5IndexTombstoneQuery(tls, *(*uintptr)(unsafe.Pointer(pArray + 8 + uintptr(iPg)*4)), (*TFts5TombstoneArray)(unsafe.Pointer(pArray)).FnTombstone, libc.Uint64FromInt64((*TFts5SegIter)(unsafe.Pointer(pSeg)).FiRowid))
	}
	return 0
}

// C documentation
//
//	/*
//	** Return true if the iterator passed as the second argument currently
//	** points to a delete marker. A delete marker is an entry with a 0 byte
//	** position-list.
//	*/
func _fts5MultiIterIsEmpty(tls *libc.TLS, p uintptr, pIter uintptr) (r int32) {
	var pSeg uintptr
	_ = pSeg
	pSeg = pIter + 72 + uintptr((**(**TFts5CResult)(__ccgo_up((*TFts5Iter)(unsafe.Pointer(pIter)).FaFirst + 1*4))).FiFirst)*96
	return libc.BoolInt32((*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK && (*TFts5SegIter)(unsafe.Pointer(pSeg)).FpLeaf != 0 && (*TFts5SegIter)(unsafe.Pointer(pSeg)).FnPos == 0)
}

// C documentation
//
//	/*
//	** Allocate a new Fts5Iter object.
//	**
//	** The new object will be used to iterate through data in structure pStruct.
//	** If iLevel is -ve, then all data in all segments is merged. Or, if iLevel
//	** is zero or greater, data from the first nSegment segments on level iLevel
//	** is merged.
//	**
//	** The iterator initially points to the first term/rowid entry in the
//	** iterated data.
//	*/
func _fts5MultiIterNew(tls *libc.TLS, p uintptr, pStruct uintptr, flags int32, pColset uintptr, pTerm uintptr, nTerm int32, iLevel int32, nSegment int32, ppOut uintptr) {
	var iIter, iSeg, nSeg, v1 int32
	var pEnd, pIter, pIter1, pLvl, pNew, pSeg, v2 uintptr
	_, _, _, _, _, _, _, _, _, _, _ = iIter, iSeg, nSeg, pEnd, pIter, pIter1, pLvl, pNew, pSeg, v1, v2
	nSeg = 0 /* Number of segment-iters in use */
	iIter = 0
	/* Allocate space for the new multi-seg-iterator. */
	if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
		if iLevel < 0 {
			nSeg = (*TFts5Structure)(unsafe.Pointer(pStruct)).FnSegment
			nSeg = nSeg + libc.BoolInt32((*TFts5Index)(unsafe.Pointer(p)).FpHash != 0 && 0 == flags&int32(FTS5INDEX_QUERY_SKIPHASH))
		} else {
			if (*(*TFts5StructureLevel)(unsafe.Pointer(pStruct + 28 + uintptr(iLevel)*12))).FnSeg < nSegment {
				v1 = (*(*TFts5StructureLevel)(unsafe.Pointer(pStruct + 28 + uintptr(iLevel)*12))).FnSeg
			} else {
				v1 = nSegment
			}
			nSeg = v1
		}
	}
	v2 = _fts5MultiIterAlloc(tls, p, nSeg)
	pNew = v2
	**(**uintptr)(__ccgo_up(ppOut)) = v2
	if pNew == uintptr(0) {
		goto fts5MultiIterNew_post_check
	}
	(*TFts5Iter)(unsafe.Pointer(pNew)).FbRev = libc.BoolInt32(0 != flags&int32(FTS5INDEX_QUERY_DESC))
	(*TFts5Iter)(unsafe.Pointer(pNew)).FbSkipEmpty = libc.BoolUint8(libc.Int32FromInt32(0) != flags&libc.Int32FromInt32(FTS5INDEX_QUERY_SKIPEMPTY))
	(*TFts5Iter)(unsafe.Pointer(pNew)).FpColset = pColset
	if flags&int32(FTS5INDEX_QUERY_NOOUTPUT) == 0 {
		_fts5IterSetOutputCb(tls, p+40, pNew)
	}
	/* Initialize each of the component segment iterators. */
	if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
		if iLevel < 0 {
			pEnd = pStruct + 28 + uintptr((*TFts5Structure)(unsafe.Pointer(pStruct)).FnLevel)*12
			if (*TFts5Index)(unsafe.Pointer(p)).FpHash != 0 && 0 == flags&int32(FTS5INDEX_QUERY_SKIPHASH) {
				v1 = iIter
				iIter = iIter + 1
				/* Add a segment iterator for the current contents of the hash table. */
				pIter = pNew + 72 + uintptr(v1)*96
				_fts5SegIterHashInit(tls, p, pTerm, nTerm, flags, pIter)
			}
			pLvl = pStruct + 28
			for {
				if !(pLvl < pEnd) {
					break
				}
				iSeg = (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnSeg - int32(1)
				for {
					if !(iSeg >= 0) {
						break
					}
					pSeg = (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FaSeg + uintptr(iSeg)*48
					v1 = iIter
					iIter = iIter + 1
					pIter1 = pNew + 72 + uintptr(v1)*96
					if pTerm == uintptr(0) {
						_fts5SegIterInit(tls, p, pSeg, pIter1)
					} else {
						_fts5SegIterSeekInit(tls, p, pTerm, nTerm, flags, pSeg, pIter1)
					}
					goto _5
				_5:
					;
					iSeg = iSeg - 1
				}
				goto _4
			_4:
				;
				pLvl += 12
			}
		} else {
			pLvl = pStruct + 28 + uintptr(iLevel)*12
			iSeg = nSeg - int32(1)
			for {
				if !(iSeg >= 0) {
					break
				}
				v1 = iIter
				iIter = iIter + 1
				_fts5SegIterInit(tls, p, (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FaSeg+uintptr(iSeg)*48, pNew+72+uintptr(v1)*96)
				goto _7
			_7:
				;
				iSeg = iSeg - 1
			}
		}
	}
	/* If the above was successful, each component iterator now points
	 ** to the first entry in its segment. In this case initialize the
	 ** aFirst[] array. Or, if an error has occurred, free the iterator
	 ** object and set the output variable to NULL.  */
	if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
		_fts5MultiIterFinishSetup(tls, p, pNew)
	} else {
		_fts5MultiIterFree(tls, pNew)
		**(**uintptr)(__ccgo_up(ppOut)) = uintptr(0)
	}
	goto fts5MultiIterNew_post_check
fts5MultiIterNew_post_check:
	;
	return
}

// C documentation
//
//	/*
//	** Create an Fts5Iter that iterates through the doclist provided
//	** as the second argument.
//	*/
func _fts5MultiIterNew2(tls *libc.TLS, p uintptr, pData uintptr, bDesc int32, ppOut uintptr) {
	var pIter, pNew uintptr
	_, _ = pIter, pNew
	pNew = _fts5MultiIterAlloc(tls, p, int32(2))
	if pNew != 0 {
		pIter = pNew + 72 + 1*96
		(*TFts5SegIter)(unsafe.Pointer(pIter)).Fflags = int32(FTS5_SEGITER_ONETERM)
		if (*TFts5Data)(unsafe.Pointer(pData)).FszLeaf > 0 {
			(*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf = pData
			(*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafOffset = libc.Int64FromUint8(_sqlite3Fts5GetVarint(tls, (*TFts5Data)(unsafe.Pointer(pData)).Fp, pIter+80))
			(*TFts5SegIter)(unsafe.Pointer(pIter)).FiEndofDoclist = (*TFts5Data)(unsafe.Pointer(pData)).Fnn
			(**(**TFts5CResult)(__ccgo_up((*TFts5Iter)(unsafe.Pointer(pNew)).FaFirst + 1*4))).FiFirst = uint16(1)
			if bDesc != 0 {
				(*TFts5Iter)(unsafe.Pointer(pNew)).FbRev = int32(1)
				**(**int32)(__ccgo_up(pIter + 4)) |= int32(FTS5_SEGITER_REVERSE)
				_fts5SegIterReverseInitPage(tls, p, pIter)
			} else {
				_fts5SegIterLoadNPos(tls, p, pIter)
			}
			pData = uintptr(0)
		} else {
			(*TFts5Iter)(unsafe.Pointer(pNew)).Fbase.FbEof = uint8(1)
		}
		_fts5SegIterSetNext(tls, p, pIter)
		**(**uintptr)(__ccgo_up(ppOut)) = pNew
	}
	_fts5DataRelease(tls, pData)
}

// C documentation
//
//	/*
//	** Move the iterator to the next entry.
//	**
//	** If an error occurs, an error code is left in Fts5Index.rc. It is not
//	** considered an error if the iterator reaches EOF, or if it is already at
//	** EOF when this function is called.
//	*/
func _fts5MultiIterNext(tls *libc.TLS, p uintptr, pIter uintptr, bFrom int32, iFrom Ti64) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var bUseFrom, iFirst int32
	var _ /* bNewTerm at bp+0 */ int32
	var _ /* pSeg at bp+4 */ uintptr
	_, _ = bUseFrom, iFirst
	bUseFrom = bFrom
	for (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
		iFirst = libc.Int32FromUint16((**(**TFts5CResult)(__ccgo_up((*TFts5Iter)(unsafe.Pointer(pIter)).FaFirst + 1*4))).FiFirst)
		**(**int32)(__ccgo_up(bp)) = 0
		**(**uintptr)(__ccgo_up(bp + 4)) = pIter + 72 + uintptr(iFirst)*96
		if bUseFrom != 0 && (*TFts5SegIter)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 4)))).FpDlidx != 0 {
			_fts5SegIterNextFrom(tls, p, **(**uintptr)(__ccgo_up(bp + 4)), iFrom)
		} else {
			(*(*func(*libc.TLS, uintptr, uintptr, uintptr))(unsafe.Pointer(&struct{ uintptr }{(*TFts5SegIter)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 4)))).FxNext})))(tls, p, **(**uintptr)(__ccgo_up(bp + 4)), bp)
		}
		if (*TFts5SegIter)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 4)))).FpLeaf == uintptr(0) || **(**int32)(__ccgo_up(bp)) != 0 || _fts5MultiIterAdvanceRowid(tls, pIter, iFirst, bp+4) != 0 {
			_fts5MultiIterAdvanced(tls, p, pIter, iFirst, int32(1))
			_fts5MultiIterSetEof(tls, pIter)
			**(**uintptr)(__ccgo_up(bp + 4)) = pIter + 72 + uintptr((**(**TFts5CResult)(__ccgo_up((*TFts5Iter)(unsafe.Pointer(pIter)).FaFirst + 1*4))).FiFirst)*96
			if (*TFts5SegIter)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 4)))).FpLeaf == uintptr(0) {
				return
			}
		}
		if (libc.Int32FromUint8((*TFts5Iter)(unsafe.Pointer(pIter)).FbSkipEmpty) == 0 || (*TFts5SegIter)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 4)))).FnPos != 0) && 0 == _fts5MultiIterIsDeleted(tls, pIter) {
			(*(*func(*libc.TLS, uintptr, uintptr))(unsafe.Pointer(&struct{ uintptr }{(*TFts5Iter)(unsafe.Pointer(pIter)).FxSetOutputs})))(tls, pIter, **(**uintptr)(__ccgo_up(bp + 4)))
			return
		}
		bUseFrom = 0
	}
}

func _fts5MultiIterNext2(tls *libc.TLS, p uintptr, pIter uintptr, pbNewTerm uintptr) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var iFirst int32
	var _ /* bNewTerm at bp+4 */ int32
	var _ /* pSeg at bp+0 */ uintptr
	_ = iFirst
	if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
		**(**int32)(__ccgo_up(pbNewTerm)) = 0
		for cond := true; cond; cond = (_fts5MultiIterIsEmpty(tls, p, pIter) != 0 || _fts5MultiIterIsDeleted(tls, pIter) != 0) && (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
			iFirst = libc.Int32FromUint16((**(**TFts5CResult)(__ccgo_up((*TFts5Iter)(unsafe.Pointer(pIter)).FaFirst + 1*4))).FiFirst)
			**(**uintptr)(__ccgo_up(bp)) = pIter + 72 + uintptr(iFirst)*96
			**(**int32)(__ccgo_up(bp + 4)) = 0
			(*(*func(*libc.TLS, uintptr, uintptr, uintptr))(unsafe.Pointer(&struct{ uintptr }{(*TFts5SegIter)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FxNext})))(tls, p, **(**uintptr)(__ccgo_up(bp)), bp+4)
			if (*TFts5SegIter)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FpLeaf == uintptr(0) || **(**int32)(__ccgo_up(bp + 4)) != 0 || _fts5MultiIterAdvanceRowid(tls, pIter, iFirst, bp) != 0 {
				_fts5MultiIterAdvanced(tls, p, pIter, iFirst, int32(1))
				_fts5MultiIterSetEof(tls, pIter)
				**(**int32)(__ccgo_up(pbNewTerm)) = int32(1)
			}
		}
	}
}

// C documentation
//
//	/*
//	** Return the rowid of the entry that the iterator currently points
//	** to. If the iterator points to EOF when this function is called the
//	** results are undefined.
//	*/
func _fts5MultiIterRowid(tls *libc.TLS, pIter uintptr) (r Ti64) {
	return (*(*TFts5SegIter)(unsafe.Pointer(pIter + 72 + uintptr((**(**TFts5CResult)(__ccgo_up((*TFts5Iter)(unsafe.Pointer(pIter)).FaFirst + 1*4))).FiFirst)*96))).FiRowid
}

// C documentation
//
//	/*
//	** Set the pIter->bEof variable based on the state of the sub-iterators.
//	*/
func _fts5MultiIterSetEof(tls *libc.TLS, pIter uintptr) {
	var pSeg uintptr
	_ = pSeg
	pSeg = pIter + 72 + uintptr((**(**TFts5CResult)(__ccgo_up((*TFts5Iter)(unsafe.Pointer(pIter)).FaFirst + 1*4))).FiFirst)*96
	(*TFts5Iter)(unsafe.Pointer(pIter)).Fbase.FbEof = libc.BoolUint8((*TFts5SegIter)(unsafe.Pointer(pSeg)).FpLeaf == uintptr(0))
	(*TFts5Iter)(unsafe.Pointer(pIter)).FiSwitchRowid = (*TFts5SegIter)(unsafe.Pointer(pSeg)).FiRowid
}

/*
** The argument to this macro must be an Fts5Data structure containing a
** tombstone hash page. This macro returns the key-size of the hash-page.
 */

// C documentation
//
//	/*
//	** Return a pointer to a buffer containing the term associated with the
//	** entry that the iterator currently points to.
//	*/
func _fts5MultiIterTerm(tls *libc.TLS, pIter uintptr, pn uintptr) (r uintptr) {
	var p uintptr
	_ = p
	p = pIter + 72 + uintptr((**(**TFts5CResult)(__ccgo_up((*TFts5Iter)(unsafe.Pointer(pIter)).FaFirst + 1*4))).FiFirst)*96
	**(**int32)(__ccgo_up(pn)) = (*TFts5SegIter)(unsafe.Pointer(p)).Fterm.Fn
	return (*TFts5SegIter)(unsafe.Pointer(p)).Fterm.Fp
}

// C documentation
//
//	/*
//	** Implementation of xOpen method.
//	*/
func _fts5OpenMethod(tls *libc.TLS, pVTab uintptr, ppCsr uintptr) (r int32) {
	var nByte Tsqlite3_int64
	var pConfig, pCsr, pGlobal, pTab, v2 uintptr
	var rc int32
	var v1 Ti64
	_, _, _, _, _, _, _, _ = nByte, pConfig, pCsr, pGlobal, pTab, rc, v1, v2
	pTab = pVTab
	pConfig = (*TFts5FullTable)(unsafe.Pointer(pTab)).Fp.FpConfig
	pCsr = uintptr(0) /* Return code */
	rc = _fts5NewTransaction(tls, pTab)
	if rc == SQLITE_OK {
		nByte = libc.Int64FromUint32(uint32(116) + libc.Uint32FromInt32((*TFts5Config)(unsafe.Pointer(pConfig)).FnCol)*uint32(4))
		pCsr = Xsqlite3_malloc64(tls, libc.Uint64FromInt64(nByte))
		if pCsr != 0 {
			pGlobal = (*TFts5FullTable)(unsafe.Pointer(pTab)).FpGlobal
			libc.Xmemset(tls, pCsr, 0, libc.Uint32FromInt64(nByte))
			(*TFts5Cursor)(unsafe.Pointer(pCsr)).FaColumnSize = pCsr + 1*116
			(*TFts5Cursor)(unsafe.Pointer(pCsr)).FpNext = (*TFts5Global)(unsafe.Pointer(pGlobal)).FpCsr
			(*TFts5Global)(unsafe.Pointer(pGlobal)).FpCsr = pCsr
			v2 = pGlobal + 28
			*(*Ti64)(unsafe.Pointer(v2)) = *(*Ti64)(unsafe.Pointer(v2)) + 1
			v1 = *(*Ti64)(unsafe.Pointer(v2))
			(*TFts5Cursor)(unsafe.Pointer(pCsr)).FiCsrId = v1
		} else {
			rc = int32(SQLITE_NOMEM)
		}
	}
	**(**uintptr)(__ccgo_up(ppCsr)) = pCsr
	return rc
}

// C documentation
//
//	/*
//	** This function is used when parsing LIKE or GLOB patterns against
//	** trigram indexes that specify either detail=column or detail=none.
//	** It converts a phrase:
//	**
//	**     abc + def + ghi
//	**
//	** into an AND tree:
//	**
//	**     abc AND def AND ghi
//	*/
func _fts5ParsePhraseToAnd(tls *libc.TLS, pParse uintptr, pNear uintptr) (r uintptr) {
	var ii, nByte, nTerm, v2 int32
	var p, pPhrase, pRet, pTo, v3 uintptr
	_, _, _, _, _, _, _, _, _ = ii, nByte, nTerm, p, pPhrase, pRet, pTo, v2, v3
	nTerm = (*TFts5ExprPhrase)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pNear + 12)))).FnTerm
	nByte = libc.Int32FromUint32(uint32(libc.UintptrFromInt32(0)+36) + libc.Uint32FromInt32(nTerm+libc.Int32FromInt32(1))*libc.Uint32FromInt64(4))
	pRet = _sqlite3Fts5MallocZero(tls, pParse+8, int64(nByte))
	if pRet != 0 {
		(*TFts5ExprNode)(unsafe.Pointer(pRet)).FeType = int32(FTS5_AND)
		(*TFts5ExprNode)(unsafe.Pointer(pRet)).FnChild = nTerm
		(*TFts5ExprNode)(unsafe.Pointer(pRet)).FiHeight = int32(1)
		_fts5ExprAssignXNext(tls, pRet)
		(*TFts5Parse)(unsafe.Pointer(pParse)).FnPhrase = (*TFts5Parse)(unsafe.Pointer(pParse)).FnPhrase - 1
		ii = 0
		for {
			if !(ii < nTerm) {
				break
			}
			pPhrase = _sqlite3Fts5MallocZero(tls, pParse+8, libc.Int64FromUint32(uint32(libc.UintptrFromInt32(0)+20)+libc.Uint32FromInt32(libc.Int32FromInt32(1))*libc.Uint32FromInt64(24)))
			if pPhrase != 0 {
				if _parseGrowPhraseArray(tls, pParse) != 0 {
					_fts5ExprPhraseFree(tls, pPhrase)
				} else {
					p = *(*uintptr)(unsafe.Pointer(pNear + 12)) + 20 + uintptr(ii)*24
					pTo = pPhrase + 20
					v3 = pParse + 12
					v2 = *(*int32)(unsafe.Pointer(v3))
					*(*int32)(unsafe.Pointer(v3)) = *(*int32)(unsafe.Pointer(v3)) + 1
					**(**uintptr)(__ccgo_up((*TFts5Parse)(unsafe.Pointer(pParse)).FapPhrase + uintptr(v2)*4)) = pPhrase
					(*TFts5ExprPhrase)(unsafe.Pointer(pPhrase)).FnTerm = int32(1)
					(*TFts5ExprTerm)(unsafe.Pointer(pTo)).FpTerm = _sqlite3Fts5Strndup(tls, pParse+8, (*TFts5ExprTerm)(unsafe.Pointer(p)).FpTerm, (*TFts5ExprTerm)(unsafe.Pointer(p)).FnFullTerm)
					(*TFts5ExprTerm)(unsafe.Pointer(pTo)).FnQueryTerm = (*TFts5ExprTerm)(unsafe.Pointer(p)).FnQueryTerm
					(*TFts5ExprTerm)(unsafe.Pointer(pTo)).FnFullTerm = (*TFts5ExprTerm)(unsafe.Pointer(p)).FnFullTerm
					*(*uintptr)(unsafe.Pointer(pRet + 36 + uintptr(ii)*4)) = _sqlite3Fts5ParseNode(tls, pParse, int32(FTS5_STRING), uintptr(0), uintptr(0), _sqlite3Fts5ParseNearset(tls, pParse, uintptr(0), pPhrase))
				}
			}
			goto _1
		_1:
			;
			ii = ii + 1
		}
		if (*TFts5Parse)(unsafe.Pointer(pParse)).Frc != 0 {
			_sqlite3Fts5ParseNodeFree(tls, pRet)
			pRet = uintptr(0)
		} else {
			_sqlite3Fts5ParseNearsetFree(tls, pNear)
		}
	}
	return pRet
}

// C documentation
//
//	/*
//	** Recursively apply colset pColset to expression node pNode and all of
//	** its decendents. If (*ppFree) is not NULL, it contains a spare copy
//	** of pColset. This function may use the spare copy and set (*ppFree) to
//	** zero, or it may create copies of pColset using fts5CloneColset().
//	*/
func _fts5ParseSetColset(tls *libc.TLS, pParse uintptr, pNode uintptr, pColset uintptr, ppFree uintptr) {
	var i int32
	var pNear uintptr
	_, _ = i, pNear
	if (*TFts5Parse)(unsafe.Pointer(pParse)).Frc == SQLITE_OK {
		if (*TFts5ExprNode)(unsafe.Pointer(pNode)).FeType == int32(FTS5_STRING) || (*TFts5ExprNode)(unsafe.Pointer(pNode)).FeType == int32(FTS5_TERM) {
			pNear = (*TFts5ExprNode)(unsafe.Pointer(pNode)).FpNear
			if (*TFts5ExprNearset)(unsafe.Pointer(pNear)).FpColset != 0 {
				_fts5MergeColset(tls, (*TFts5ExprNearset)(unsafe.Pointer(pNear)).FpColset, pColset)
				if (*TFts5Colset)(unsafe.Pointer((*TFts5ExprNearset)(unsafe.Pointer(pNear)).FpColset)).FnCol == 0 {
					(*TFts5ExprNode)(unsafe.Pointer(pNode)).FeType = FTS5_EOF
					(*TFts5ExprNode)(unsafe.Pointer(pNode)).FxNext = uintptr(0)
				}
			} else {
				if **(**uintptr)(__ccgo_up(ppFree)) != 0 {
					(*TFts5ExprNearset)(unsafe.Pointer(pNear)).FpColset = pColset
					**(**uintptr)(__ccgo_up(ppFree)) = uintptr(0)
				} else {
					(*TFts5ExprNearset)(unsafe.Pointer(pNear)).FpColset = _fts5CloneColset(tls, pParse+8, pColset)
				}
			}
		} else {
			i = 0
			for {
				if !(i < (*TFts5ExprNode)(unsafe.Pointer(pNode)).FnChild) {
					break
				}
				_fts5ParseSetColset(tls, pParse, *(*uintptr)(unsafe.Pointer(pNode + 36 + uintptr(i)*4)), pColset, ppFree)
				goto _1
			_1:
				;
				i = i + 1
			}
		}
	}
}

func _fts5PorterCb(tls *libc.TLS, pCtx uintptr, tflags int32, pToken uintptr, nToken int32, iStart int32, iEnd int32) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var aBuf, p uintptr
	var c int8
	var v1 int32
	var _ /* nBuf at bp+0 */ int32
	_, _, _, _ = aBuf, c, p, v1
	p = pCtx
	if nToken > int32(FTS5_PORTER_MAX_TOKEN) || nToken < int32(3) {
		goto pass_through
	}
	aBuf = (*TPorterContext)(unsafe.Pointer(p)).FaBuf
	**(**int32)(__ccgo_up(bp)) = nToken
	libc.Xmemcpy(tls, aBuf, pToken, libc.Uint32FromInt32(**(**int32)(__ccgo_up(bp))))
	/* Step 1. */
	_fts5PorterStep1A(tls, aBuf, bp)
	if _fts5PorterStep1B(tls, aBuf, bp) != 0 {
		if _fts5PorterStep1B2(tls, aBuf, bp) == 0 {
			c = **(**int8)(__ccgo_up(aBuf + uintptr(**(**int32)(__ccgo_up(bp))-int32(1))))
			if _fts5PorterIsVowel(tls, c, 0) == 0 && int32(c) != int32('l') && int32(c) != int32('s') && int32(c) != int32('z') && int32(c) == int32(**(**int8)(__ccgo_up(aBuf + uintptr(**(**int32)(__ccgo_up(bp))-int32(2))))) {
				**(**int32)(__ccgo_up(bp)) = **(**int32)(__ccgo_up(bp)) - 1
			} else {
				if _fts5Porter_MEq1(tls, aBuf, **(**int32)(__ccgo_up(bp))) != 0 && _fts5Porter_Ostar(tls, aBuf, **(**int32)(__ccgo_up(bp))) != 0 {
					v1 = **(**int32)(__ccgo_up(bp))
					**(**int32)(__ccgo_up(bp)) = **(**int32)(__ccgo_up(bp)) + 1
					**(**int8)(__ccgo_up(aBuf + uintptr(v1))) = int8('e')
				}
			}
		}
	}
	/* Step 1C. */
	if int32(**(**int8)(__ccgo_up(aBuf + uintptr(**(**int32)(__ccgo_up(bp))-int32(1))))) == int32('y') && _fts5Porter_Vowel(tls, aBuf, **(**int32)(__ccgo_up(bp))-int32(1)) != 0 {
		**(**int8)(__ccgo_up(aBuf + uintptr(**(**int32)(__ccgo_up(bp))-int32(1)))) = int8('i')
	}
	/* Steps 2 through 4. */
	_fts5PorterStep2(tls, aBuf, bp)
	_fts5PorterStep3(tls, aBuf, bp)
	_fts5PorterStep4(tls, aBuf, bp)
	/* Step 5a. */
	if int32(**(**int8)(__ccgo_up(aBuf + uintptr(**(**int32)(__ccgo_up(bp))-int32(1))))) == int32('e') {
		if _fts5Porter_MGt1(tls, aBuf, **(**int32)(__ccgo_up(bp))-int32(1)) != 0 || _fts5Porter_MEq1(tls, aBuf, **(**int32)(__ccgo_up(bp))-int32(1)) != 0 && !(_fts5Porter_Ostar(tls, aBuf, **(**int32)(__ccgo_up(bp))-int32(1)) != 0) {
			**(**int32)(__ccgo_up(bp)) = **(**int32)(__ccgo_up(bp)) - 1
		}
	}
	/* Step 5b. */
	if **(**int32)(__ccgo_up(bp)) > int32(1) && int32(**(**int8)(__ccgo_up(aBuf + uintptr(**(**int32)(__ccgo_up(bp))-int32(1))))) == int32('l') && int32(**(**int8)(__ccgo_up(aBuf + uintptr(**(**int32)(__ccgo_up(bp))-int32(2))))) == int32('l') && _fts5Porter_MGt1(tls, aBuf, **(**int32)(__ccgo_up(bp))-int32(1)) != 0 {
		**(**int32)(__ccgo_up(bp)) = **(**int32)(__ccgo_up(bp)) - 1
	}
	return (*(*func(*libc.TLS, uintptr, int32, uintptr, int32, int32, int32) int32)(unsafe.Pointer(&struct{ uintptr }{(*TPorterContext)(unsafe.Pointer(p)).FxToken})))(tls, (*TPorterContext)(unsafe.Pointer(p)).FpCtx, tflags, aBuf, **(**int32)(__ccgo_up(bp)), iStart, iEnd)
	goto pass_through
pass_through:
	;
	return (*(*func(*libc.TLS, uintptr, int32, uintptr, int32, int32, int32) int32)(unsafe.Pointer(&struct{ uintptr }{(*TPorterContext)(unsafe.Pointer(p)).FxToken})))(tls, (*TPorterContext)(unsafe.Pointer(p)).FpCtx, tflags, pToken, nToken, iStart, iEnd)
	return r
}

func _fts5PrefixMergerInsertByPosition(tls *libc.TLS, ppHead uintptr, p uintptr) {
	var pp uintptr
	_ = pp
	if (*TPrefixMerger)(unsafe.Pointer(p)).FiPos >= 0 {
		pp = ppHead
		for **(**uintptr)(__ccgo_up(pp)) != 0 && (*TPrefixMerger)(unsafe.Pointer(p)).FiPos > (*TPrefixMerger)(unsafe.Pointer(**(**uintptr)(__ccgo_up(pp)))).FiPos {
			pp = **(**uintptr)(__ccgo_up(pp)) + 40
		}
		(*TPrefixMerger)(unsafe.Pointer(p)).FpNext = **(**uintptr)(__ccgo_up(pp))
		**(**uintptr)(__ccgo_up(pp)) = p
	}
}

func _fts5PrefixMergerInsertByRowid(tls *libc.TLS, ppHead uintptr, p uintptr) {
	var pp uintptr
	_ = pp
	if (*TPrefixMerger)(unsafe.Pointer(p)).Fiter.FaPoslist != 0 {
		pp = ppHead
		for **(**uintptr)(__ccgo_up(pp)) != 0 && (*TPrefixMerger)(unsafe.Pointer(p)).Fiter.FiRowid > (*TPrefixMerger)(unsafe.Pointer(**(**uintptr)(__ccgo_up(pp)))).Fiter.FiRowid {
			pp = **(**uintptr)(__ccgo_up(pp)) + 40
		}
		(*TPrefixMerger)(unsafe.Pointer(p)).FpNext = **(**uintptr)(__ccgo_up(pp))
		**(**uintptr)(__ccgo_up(pp)) = p
	}
}

// C documentation
//
//	/*
//	** This is called when a secure-delete operation removes a position-list
//	** that overflows onto segment page iPgno of segment pSeg. This function
//	** rewrites node iPgno, and possibly one or more of its right-hand peers,
//	** to remove this portion of the position list.
//	**
//	** Output variable (*pbLastInDoclist) is set to true if the position-list
//	** removed is followed by a new term or the end-of-segment, or false if
//	** it is followed by another rowid/position list.
//	*/
func _fts5SecureDeleteOverflow(tls *libc.TLS, p uintptr, pSeg uintptr, iPgno int32, pbLastInDoclist uintptr) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var aIdx, aPg, pLeaf uintptr
	var bDetailNone, i1, i2, nIdx, nPg, nShift, pgno int32
	var iRowid Ti64
	var _ /* aEmpty at bp+4 */ [4]Tu8
	var _ /* iFirst at bp+8 */ int32
	var _ /* iNext at bp+0 */ int32
	_, _, _, _, _, _, _, _, _, _, _ = aIdx, aPg, bDetailNone, i1, i2, iRowid, nIdx, nPg, nShift, pLeaf, pgno
	bDetailNone = libc.BoolInt32((*TFts5Config)(unsafe.Pointer((*TFts5Index)(unsafe.Pointer(p)).FpConfig)).FeDetail == libc.Int32FromInt32(FTS5_DETAIL_NONE))
	pLeaf = uintptr(0)
	**(**int32)(__ccgo_up(pbLastInDoclist)) = int32(1)
	pgno = iPgno
	for {
		if !((*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK && pgno <= (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FpgnoLast) {
			break
		}
		iRowid = int64((*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FiSegid)<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B)+libc.Int32FromInt32(FTS5_DATA_DLI_B)) + int64(libc.Int32FromInt32(0))<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B)) + int64(libc.Int32FromInt32(0))<<libc.Int32FromInt32(FTS5_DATA_PAGE_B) + int64(pgno)
		**(**int32)(__ccgo_up(bp)) = 0
		aPg = uintptr(0)
		pLeaf = _fts5DataRead(tls, p, iRowid)
		if pLeaf == uintptr(0) {
			break
		}
		aPg = (*TFts5Data)(unsafe.Pointer(pLeaf)).Fp
		**(**int32)(__ccgo_up(bp)) = libc.Int32FromUint16(_fts5GetU16(tls, aPg))
		if **(**int32)(__ccgo_up(bp)) != 0 {
			**(**int32)(__ccgo_up(pbLastInDoclist)) = 0
		}
		if **(**int32)(__ccgo_up(bp)) == 0 && (*TFts5Data)(unsafe.Pointer(pLeaf)).FszLeaf != (*TFts5Data)(unsafe.Pointer(pLeaf)).Fnn {
			_sqlite3Fts5GetVarint32(tls, aPg+uintptr((*TFts5Data)(unsafe.Pointer(pLeaf)).FszLeaf), bp)
		}
		if **(**int32)(__ccgo_up(bp)) == 0 {
			/* The page contains no terms or rowids. Replace it with an empty
			 ** page and move on to the right-hand peer.  */
			**(**[4]Tu8)(__ccgo_up(bp + 4)) = [4]Tu8{
				3: uint8(0x04),
			}
			if bDetailNone == 0 {
				_fts5DataWrite(tls, p, iRowid, bp+4, int32(4))
			}
			_fts5DataRelease(tls, pLeaf)
			pLeaf = uintptr(0)
		} else {
			if bDetailNone != 0 {
				break
			} else {
				if **(**int32)(__ccgo_up(bp)) >= (*TFts5Data)(unsafe.Pointer(pLeaf)).FszLeaf || (*TFts5Data)(unsafe.Pointer(pLeaf)).Fnn < (*TFts5Data)(unsafe.Pointer(pLeaf)).FszLeaf || **(**int32)(__ccgo_up(bp)) < int32(4) {
					_fts5IndexCorruptRowid(tls, p, iRowid)
					break
				} else {
					nShift = **(**int32)(__ccgo_up(bp)) - int32(4)
					nIdx = 0
					aIdx = uintptr(0)
					/* Unless the current page footer is 0 bytes in size (in which case
					 ** the new page footer will be as well), allocate and populate a
					 ** buffer containing the new page footer. Set stack variables aIdx
					 ** and nIdx accordingly.  */
					if (*TFts5Data)(unsafe.Pointer(pLeaf)).Fnn > (*TFts5Data)(unsafe.Pointer(pLeaf)).FszLeaf {
						**(**int32)(__ccgo_up(bp + 8)) = 0
						i1 = (*TFts5Data)(unsafe.Pointer(pLeaf)).FszLeaf
						i2 = 0
						i1 = i1 + _sqlite3Fts5GetVarint32(tls, aPg+uintptr(i1), bp+8)
						if **(**int32)(__ccgo_up(bp + 8)) < **(**int32)(__ccgo_up(bp)) {
							_fts5IndexCorruptRowid(tls, p, iRowid)
							break
						}
						aIdx = _sqlite3Fts5MallocZero(tls, p+40, int64((*TFts5Data)(unsafe.Pointer(pLeaf)).Fnn-(*TFts5Data)(unsafe.Pointer(pLeaf)).FszLeaf+int32(2)))
						if aIdx == uintptr(0) {
							break
						}
						i2 = _sqlite3Fts5PutVarint(tls, aIdx, libc.Uint64FromInt32(**(**int32)(__ccgo_up(bp + 8))-nShift))
						if i1 < (*TFts5Data)(unsafe.Pointer(pLeaf)).Fnn {
							libc.Xmemcpy(tls, aIdx+uintptr(i2), aPg+uintptr(i1), libc.Uint32FromInt32((*TFts5Data)(unsafe.Pointer(pLeaf)).Fnn-i1))
							i2 = i2 + ((*TFts5Data)(unsafe.Pointer(pLeaf)).Fnn - i1)
						}
						nIdx = i2
					}
					/* Modify the contents of buffer aPg[]. Set nPg to the new size
					 ** in bytes. The new page is always smaller than the old.  */
					nPg = (*TFts5Data)(unsafe.Pointer(pLeaf)).FszLeaf - nShift
					libc.Xmemmove(tls, aPg+4, aPg+uintptr(int32(4)+nShift), libc.Uint32FromInt32(nPg-int32(4)))
					_fts5PutU16(tls, aPg+2, libc.Uint16FromInt32(nPg))
					if _fts5GetU16(tls, aPg) != 0 {
						_fts5PutU16(tls, aPg, uint16(4))
					}
					if nIdx > 0 {
						libc.Xmemcpy(tls, aPg+uintptr(nPg), aIdx, libc.Uint32FromInt32(nIdx))
						nPg = nPg + nIdx
					}
					Xsqlite3_free(tls, aIdx)
					/* Write the new page to disk and exit the loop */
					_fts5DataWrite(tls, p, iRowid, aPg, nPg)
					break
				}
			}
		}
		goto _1
	_1:
		;
		pgno = pgno + 1
	}
	_fts5DataRelease(tls, pLeaf)
}

// C documentation
//
//	/*
//	** Allocate a tombstone hash page array object (pIter->pTombArray) for
//	** the iterator passed as the second argument. If an OOM error occurs,
//	** leave an error in the Fts5Index object.
//	*/
func _fts5SegIterAllocTombstone(tls *libc.TLS, p uintptr, pIter uintptr) {
	var nByte, nTomb Ti64
	var pNew uintptr
	_, _, _ = nByte, nTomb, pNew
	nTomb = int64((*TFts5StructureSegment)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpSeg)).FnPgTombstone)
	if nTomb > 0 {
		nByte = libc.Int64FromUint32(uint32(libc.UintptrFromInt32(0)+8)) + (nTomb+libc.Int64FromInt32(1))*libc.Int64FromInt64(4)
		pNew = _sqlite3Fts5MallocZero(tls, p+40, nByte)
		if pNew != 0 {
			(*TFts5TombstoneArray)(unsafe.Pointer(pNew)).FnTombstone = int32(nTomb)
			(*TFts5TombstoneArray)(unsafe.Pointer(pNew)).FnRef = int32(1)
			(*TFts5SegIter)(unsafe.Pointer(pIter)).FpTombArray = pNew
		}
	}
}

// C documentation
//
//	/*
//	** Zero the iterator passed as the only argument.
//	*/
func _fts5SegIterClear(tls *libc.TLS, pIter uintptr) {
	_sqlite3Fts5BufferFree(tls, pIter+68)
	_fts5DataRelease(tls, (*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)
	_fts5DataRelease(tls, (*TFts5SegIter)(unsafe.Pointer(pIter)).FpNextLeaf)
	_fts5TombstoneArrayDelete(tls, (*TFts5SegIter)(unsafe.Pointer(pIter)).FpTombArray)
	_fts5DlidxIterFree(tls, (*TFts5SegIter)(unsafe.Pointer(pIter)).FpDlidx)
	Xsqlite3_free(tls, (*TFts5SegIter)(unsafe.Pointer(pIter)).FaRowidOffset)
	libc.Xmemset(tls, pIter, 0, uint32(96))
}

// C documentation
//
//	/*
//	** Move the seg-iter so that it points to the first rowid on page iLeafPgno.
//	** It is an error if leaf iLeafPgno does not exist. Unless the db is
//	** a 'secure-delete' db, if it contains no rowids then this is also an error.
//	*/
func _fts5SegIterGotoPage(tls *libc.TLS, p uintptr, pIter uintptr, iLeafPgno int32) {
	var a uintptr
	var iOff, n int32
	_, _, _ = a, iOff, n
	if iLeafPgno > (*TFts5StructureSegment)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpSeg)).FpgnoLast {
		_fts5IndexCorruptIdx(tls, p)
	} else {
		_fts5DataRelease(tls, (*TFts5SegIter)(unsafe.Pointer(pIter)).FpNextLeaf)
		(*TFts5SegIter)(unsafe.Pointer(pIter)).FpNextLeaf = uintptr(0)
		(*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafPgno = iLeafPgno - int32(1)
		for (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
			_fts5SegIterNextPage(tls, p, pIter)
			if (*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf == uintptr(0) {
				break
			}
			iOff = libc.Int32FromUint16(_fts5GetU16(tls, (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).Fp))
			if iOff > 0 {
				a = (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).Fp
				n = (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).FszLeaf
				if iOff < int32(4) || iOff >= n {
					_fts5IndexCorruptIdx(tls, p)
				} else {
					iOff = iOff + libc.Int32FromUint8(_sqlite3Fts5GetVarint(tls, a+uintptr(iOff), pIter+80))
					(*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafOffset = int64(iOff)
					_fts5SegIterLoadNPos(tls, p, pIter)
				}
				break
			}
		}
	}
}

// C documentation
//
//	/*
//	** Initialize the object pIter to point to term pTerm/nTerm within the
//	** in-memory hash table. If there is no such term in the hash-table, the
//	** iterator is set to EOF.
//	**
//	** If an error occurs, Fts5Index.rc is set to an appropriate error code. If
//	** an error has already occurred when this function is called, it is a no-op.
//	*/
func _fts5SegIterHashInit(tls *libc.TLS, p uintptr, pTerm uintptr, nTerm int32, flags int32, pIter uintptr) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var v1 int32
	var _ /* n at bp+8 */ int32
	var _ /* nList at bp+0 */ int32
	var _ /* pLeaf at bp+12 */ uintptr
	var _ /* pList at bp+16 */ uintptr
	var _ /* z at bp+4 */ uintptr
	_ = v1
	**(**int32)(__ccgo_up(bp)) = 0
	**(**uintptr)(__ccgo_up(bp + 4)) = uintptr(0)
	**(**int32)(__ccgo_up(bp + 8)) = 0
	**(**uintptr)(__ccgo_up(bp + 12)) = uintptr(0)
	if pTerm == uintptr(0) || flags&int32(FTS5INDEX_QUERY_SCAN) != 0 {
		**(**uintptr)(__ccgo_up(bp + 16)) = uintptr(0)
		(*TFts5Index)(unsafe.Pointer(p)).Frc = _sqlite3Fts5HashScanInit(tls, (*TFts5Index)(unsafe.Pointer(p)).FpHash, pTerm, nTerm)
		_sqlite3Fts5HashScanEntry(tls, (*TFts5Index)(unsafe.Pointer(p)).FpHash, bp+4, bp+8, bp+16, bp)
		if **(**uintptr)(__ccgo_up(bp + 16)) != 0 {
			**(**uintptr)(__ccgo_up(bp + 12)) = _fts5IdxMalloc(tls, p, int64(12))
			if **(**uintptr)(__ccgo_up(bp + 12)) != 0 {
				(*TFts5Data)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 12)))).Fp = **(**uintptr)(__ccgo_up(bp + 16))
			}
		}
		/* The call to sqlite3Fts5HashScanInit() causes the hash table to
		 ** fill the size field of all existing position lists. This means they
		 ** can no longer be appended to. Since the only scenario in which they
		 ** can be appended to is if the previous operation on this table was
		 ** a DELETE, by clearing the Fts5Index.bDelete flag we can avoid this
		 ** possibility altogether.  */
		(*TFts5Index)(unsafe.Pointer(p)).FbDelete = 0
	} else {
		(*TFts5Index)(unsafe.Pointer(p)).Frc = _sqlite3Fts5HashQuery(tls, (*TFts5Index)(unsafe.Pointer(p)).FpHash, int32(12), pTerm, nTerm, bp+12, bp)
		if **(**uintptr)(__ccgo_up(bp + 12)) != 0 {
			(*TFts5Data)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 12)))).Fp = **(**uintptr)(__ccgo_up(bp + 12)) + 1*12
		}
		**(**uintptr)(__ccgo_up(bp + 4)) = pTerm
		**(**int32)(__ccgo_up(bp + 8)) = nTerm
		**(**int32)(__ccgo_up(pIter + 4)) |= int32(FTS5_SEGITER_ONETERM)
	}
	if **(**uintptr)(__ccgo_up(bp + 12)) != 0 {
		_sqlite3Fts5BufferSet(tls, p+40, pIter+68, **(**int32)(__ccgo_up(bp + 8)), **(**uintptr)(__ccgo_up(bp + 4)))
		v1 = **(**int32)(__ccgo_up(bp))
		(*TFts5Data)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 12)))).FszLeaf = v1
		(*TFts5Data)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 12)))).Fnn = v1
		(*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf = **(**uintptr)(__ccgo_up(bp + 12))
		(*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafOffset = libc.Int64FromUint8(_sqlite3Fts5GetVarint(tls, (*TFts5Data)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 12)))).Fp, pIter+80))
		(*TFts5SegIter)(unsafe.Pointer(pIter)).FiEndofDoclist = (*TFts5Data)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 12)))).Fnn
		if flags&int32(FTS5INDEX_QUERY_DESC) != 0 {
			**(**int32)(__ccgo_up(pIter + 4)) |= int32(FTS5_SEGITER_REVERSE)
			_fts5SegIterReverseInitPage(tls, p, pIter)
		} else {
			_fts5SegIterLoadNPos(tls, p, pIter)
		}
	}
	_fts5SegIterSetNext(tls, p, pIter)
}

// C documentation
//
//	/*
//	** Initialize the iterator object pIter to iterate through the entries in
//	** segment pSeg. The iterator is left pointing to the first entry when
//	** this function returns.
//	**
//	** If an error occurs, Fts5Index.rc is set to an appropriate error code. If
//	** an error has already occurred when this function is called, it is a no-op.
//	*/
func _fts5SegIterInit(tls *libc.TLS, p uintptr, pSeg uintptr, pIter uintptr) {
	if (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FpgnoFirst == 0 {
		/* This happens if the segment is being used as an input to an incremental
		 ** merge and all data has already been "trimmed". See function
		 ** fts5TrimSegments() for details. In this case leave the iterator empty.
		 ** The caller will see the (pIter->pLeaf==0) and assume the iterator is
		 ** at EOF already. */
		return
	}
	if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
		libc.Xmemset(tls, pIter, 0, uint32(96))
		_fts5SegIterSetNext(tls, p, pIter)
		(*TFts5SegIter)(unsafe.Pointer(pIter)).FpSeg = pSeg
		(*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafPgno = (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FpgnoFirst - int32(1)
		for cond := true; cond; cond = (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK && (*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf != 0 && (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).Fnn == int32(4) {
			_fts5SegIterNextPage(tls, p, pIter)
		}
	}
	if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK && (*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf != 0 {
		(*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafOffset = int64(4)
		(*TFts5SegIter)(unsafe.Pointer(pIter)).FiPgidxOff = (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).FszLeaf + int32(1)
		_fts5SegIterLoadTerm(tls, p, pIter, 0)
		_fts5SegIterLoadNPos(tls, p, pIter)
		_fts5SegIterAllocTombstone(tls, p, pIter)
	}
}

func _fts5SegIterLoadRowid(tls *libc.TLS, p uintptr, pIter uintptr) {
	var a uintptr
	var iOff Ti64
	_, _ = a, iOff
	a = (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).Fp /* Buffer to read data from */
	iOff = (*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafOffset
	for iOff >= int64((*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).FszLeaf) {
		_fts5SegIterNextPage(tls, p, pIter)
		if (*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf == uintptr(0) {
			if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
				_fts5IndexCorruptIter(tls, p, pIter)
			}
			return
		}
		iOff = int64(4)
		a = (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).Fp
	}
	iOff = iOff + libc.Int64FromUint8(_sqlite3Fts5GetVarint(tls, a+uintptr(iOff), pIter+80))
	(*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafOffset = iOff
}

// C documentation
//
//	/*
//	** Fts5SegIter.iLeafOffset currently points to the first byte of the
//	** "nSuffix" field of a term. Function parameter nKeep contains the value
//	** of the "nPrefix" field (if there was one - it is passed 0 if this is
//	** the first term in the segment).
//	**
//	** This function populates:
//	**
//	**   Fts5SegIter.term
//	**   Fts5SegIter.rowid
//	**
//	** accordingly and leaves (Fts5SegIter.iLeafOffset) set to the content of
//	** the first position list. The position list belonging to document
//	** (Fts5SegIter.iRowid).
//	*/
func _fts5SegIterLoadTerm(tls *libc.TLS, p uintptr, pIter uintptr, nKeep int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var a uintptr
	var iOff Ti64
	var _ /* nExtra at bp+4 */ int32
	var _ /* nNew at bp+0 */ int32
	_, _ = a, iOff
	a = (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).Fp /* Buffer to read data from */
	iOff = (*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafOffset                         /* Bytes of new data */
	iOff = iOff + int64(_sqlite3Fts5GetVarint32(tls, a+uintptr(iOff), bp))
	if iOff+int64(**(**int32)(__ccgo_up(bp))) > int64((*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).FszLeaf) || nKeep > (*TFts5SegIter)(unsafe.Pointer(pIter)).Fterm.Fn || **(**int32)(__ccgo_up(bp)) == 0 {
		_fts5IndexCorruptIter(tls, p, pIter)
		return
	}
	(*TFts5SegIter)(unsafe.Pointer(pIter)).Fterm.Fn = nKeep
	_sqlite3Fts5BufferAppendBlob(tls, p+40, pIter+68, libc.Uint32FromInt32(**(**int32)(__ccgo_up(bp))), a+uintptr(iOff))
	iOff = iOff + int64(**(**int32)(__ccgo_up(bp)))
	(*TFts5SegIter)(unsafe.Pointer(pIter)).FiTermLeafOffset = int32(iOff)
	(*TFts5SegIter)(unsafe.Pointer(pIter)).FiTermLeafPgno = (*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafPgno
	(*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafOffset = iOff
	if (*TFts5SegIter)(unsafe.Pointer(pIter)).FiPgidxOff >= (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).Fnn {
		(*TFts5SegIter)(unsafe.Pointer(pIter)).FiEndofDoclist = (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).Fnn + int32(1)
	} else {
		**(**int32)(__ccgo_up(pIter + 44)) += _sqlite3Fts5GetVarint32(tls, a+uintptr((*TFts5SegIter)(unsafe.Pointer(pIter)).FiPgidxOff), bp+4)
		**(**int32)(__ccgo_up(pIter + 48)) += **(**int32)(__ccgo_up(bp + 4))
	}
	_fts5SegIterLoadRowid(tls, p, pIter)
}

// C documentation
//
//	/*
//	** Advance iterator pIter to the next entry.
//	**
//	** If an error occurs, Fts5Index.rc is set to an appropriate error code. It
//	** is not considered an error if the iterator reaches EOF. If an error has
//	** already occurred when this function is called, it is a no-op.
//	*/
func _fts5SegIterNext(tls *libc.TLS, p uintptr, pIter uintptr, pbNewTerm uintptr) {
	bp := tls.Alloc(48)
	defer tls.Free(48)
	var a, pLeaf, v1 uintptr
	var bNewTerm, n, v2 int32
	var v3 Ti64
	var _ /* iDelta at bp+8 */ Tu64
	var _ /* iOff at bp+0 */ int32
	var _ /* nKeep at bp+4 */ int32
	var _ /* nList at bp+28 */ int32
	var _ /* nSz at bp+32 */ int32
	var _ /* nTerm at bp+24 */ int32
	var _ /* pList at bp+16 */ uintptr
	var _ /* zTerm at bp+20 */ uintptr
	_, _, _, _, _, _, _ = a, bNewTerm, n, pLeaf, v1, v2, v3
	pLeaf = (*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf
	bNewTerm = 0
	**(**int32)(__ccgo_up(bp + 4)) = 0
	/* Search for the end of the position list within the current page. */
	a = (*TFts5Data)(unsafe.Pointer(pLeaf)).Fp
	n = (*TFts5Data)(unsafe.Pointer(pLeaf)).FszLeaf
	**(**int32)(__ccgo_up(bp)) = int32((*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafOffset + int64((*TFts5SegIter)(unsafe.Pointer(pIter)).FnPos))
	if **(**int32)(__ccgo_up(bp)) < n {
		/* The next entry is on the current page. */
		if **(**int32)(__ccgo_up(bp)) >= (*TFts5SegIter)(unsafe.Pointer(pIter)).FiEndofDoclist {
			bNewTerm = int32(1)
			if **(**int32)(__ccgo_up(bp)) != _fts5LeafFirstTermOff(tls, pLeaf) {
				**(**int32)(__ccgo_up(bp)) = **(**int32)(__ccgo_up(bp)) + _sqlite3Fts5GetVarint32(tls, a+uintptr(**(**int32)(__ccgo_up(bp))), bp+4)
			}
		} else {
			**(**int32)(__ccgo_up(bp)) = **(**int32)(__ccgo_up(bp)) + libc.Int32FromUint8(_sqlite3Fts5GetVarint(tls, a+uintptr(**(**int32)(__ccgo_up(bp))), bp+8))
			v1 = pIter + 80
			*(*Ti64)(unsafe.Pointer(v1)) = Ti64(uint64(*(*Ti64)(unsafe.Pointer(v1))) + **(**Tu64)(__ccgo_up(bp + 8)))
		}
		(*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafOffset = int64(**(**int32)(__ccgo_up(bp)))
	} else {
		if (*TFts5SegIter)(unsafe.Pointer(pIter)).FpSeg == uintptr(0) {
			**(**uintptr)(__ccgo_up(bp + 16)) = uintptr(0)
			**(**uintptr)(__ccgo_up(bp + 20)) = uintptr(0)
			**(**int32)(__ccgo_up(bp + 24)) = 0
			**(**int32)(__ccgo_up(bp + 28)) = 0
			if 0 == (*TFts5SegIter)(unsafe.Pointer(pIter)).Fflags&int32(FTS5_SEGITER_ONETERM) {
				_sqlite3Fts5HashScanNext(tls, (*TFts5Index)(unsafe.Pointer(p)).FpHash)
				_sqlite3Fts5HashScanEntry(tls, (*TFts5Index)(unsafe.Pointer(p)).FpHash, bp+20, bp+24, bp+16, bp+28)
			}
			if **(**uintptr)(__ccgo_up(bp + 16)) == uintptr(0) {
				_fts5DataRelease(tls, (*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)
				(*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf = uintptr(0)
			} else {
				(*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).Fp = **(**uintptr)(__ccgo_up(bp + 16))
				(*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).Fnn = **(**int32)(__ccgo_up(bp + 28))
				(*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).FszLeaf = **(**int32)(__ccgo_up(bp + 28))
				(*TFts5SegIter)(unsafe.Pointer(pIter)).FiEndofDoclist = **(**int32)(__ccgo_up(bp + 28)) + int32(1)
				_sqlite3Fts5BufferSet(tls, p+40, pIter+68, **(**int32)(__ccgo_up(bp + 24)), **(**uintptr)(__ccgo_up(bp + 20)))
				(*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafOffset = libc.Int64FromUint8(_sqlite3Fts5GetVarint(tls, **(**uintptr)(__ccgo_up(bp + 16)), pIter+80))
				**(**int32)(__ccgo_up(pbNewTerm)) = int32(1)
			}
		} else {
			**(**int32)(__ccgo_up(bp)) = 0
			/* Next entry is not on the current page */
			for **(**int32)(__ccgo_up(bp)) == 0 {
				_fts5SegIterNextPage(tls, p, pIter)
				pLeaf = (*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf
				if pLeaf == uintptr(0) {
					break
				}
				v2 = libc.Int32FromUint16(_fts5GetU16(tls, (*TFts5Data)(unsafe.Pointer(pLeaf)).Fp))
				**(**int32)(__ccgo_up(bp)) = v2
				if v2 != 0 && **(**int32)(__ccgo_up(bp)) < (*TFts5Data)(unsafe.Pointer(pLeaf)).FszLeaf {
					**(**int32)(__ccgo_up(bp)) = **(**int32)(__ccgo_up(bp)) + libc.Int32FromUint8(_sqlite3Fts5GetVarint(tls, (*TFts5Data)(unsafe.Pointer(pLeaf)).Fp+uintptr(**(**int32)(__ccgo_up(bp))), pIter+80))
					(*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafOffset = int64(**(**int32)(__ccgo_up(bp)))
					if (*TFts5Data)(unsafe.Pointer(pLeaf)).Fnn > (*TFts5Data)(unsafe.Pointer(pLeaf)).FszLeaf {
						(*TFts5SegIter)(unsafe.Pointer(pIter)).FiPgidxOff = (*TFts5Data)(unsafe.Pointer(pLeaf)).FszLeaf + _sqlite3Fts5GetVarint32(tls, (*TFts5Data)(unsafe.Pointer(pLeaf)).Fp+uintptr((*TFts5Data)(unsafe.Pointer(pLeaf)).FszLeaf), pIter+48)
					}
				} else {
					if (*TFts5Data)(unsafe.Pointer(pLeaf)).Fnn > (*TFts5Data)(unsafe.Pointer(pLeaf)).FszLeaf {
						(*TFts5SegIter)(unsafe.Pointer(pIter)).FiPgidxOff = (*TFts5Data)(unsafe.Pointer(pLeaf)).FszLeaf + _sqlite3Fts5GetVarint32(tls, (*TFts5Data)(unsafe.Pointer(pLeaf)).Fp+uintptr((*TFts5Data)(unsafe.Pointer(pLeaf)).FszLeaf), bp)
						(*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafOffset = int64(**(**int32)(__ccgo_up(bp)))
						(*TFts5SegIter)(unsafe.Pointer(pIter)).FiEndofDoclist = **(**int32)(__ccgo_up(bp))
						bNewTerm = int32(1)
					}
				}
				if **(**int32)(__ccgo_up(bp)) > (*TFts5Data)(unsafe.Pointer(pLeaf)).FszLeaf {
					_fts5IndexCorruptIter(tls, p, pIter)
					return
				}
			}
		}
	}
	/* Check if the iterator is now at EOF. If so, return early. */
	if (*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf != 0 {
		if bNewTerm != 0 {
			if (*TFts5SegIter)(unsafe.Pointer(pIter)).Fflags&int32(FTS5_SEGITER_ONETERM) != 0 {
				_fts5DataRelease(tls, (*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)
				(*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf = uintptr(0)
			} else {
				_fts5SegIterLoadTerm(tls, p, pIter, **(**int32)(__ccgo_up(bp + 4)))
				_fts5SegIterLoadNPos(tls, p, pIter)
				if pbNewTerm != 0 {
					**(**int32)(__ccgo_up(pbNewTerm)) = int32(1)
				}
			}
		} else {
			v1 = pIter + 20
			v3 = *(*Ti64)(unsafe.Pointer(v1))
			*(*Ti64)(unsafe.Pointer(v1)) = *(*Ti64)(unsafe.Pointer(v1)) + 1
			**(**int32)(__ccgo_up(bp + 32)) = libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).Fp + uintptr(v3))))
			if **(**int32)(__ccgo_up(bp + 32))&int32(0x80) != 0 {
				(*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafOffset = (*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafOffset - 1
				**(**Ti64)(__ccgo_up(pIter + 20)) += int64(_sqlite3Fts5GetVarint32(tls, (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).Fp+uintptr((*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafOffset), bp+32))
			}
			(*TFts5SegIter)(unsafe.Pointer(pIter)).FbDel = libc.Uint8FromInt32(**(**int32)(__ccgo_up(bp + 32)) & libc.Int32FromInt32(0x0001))
			(*TFts5SegIter)(unsafe.Pointer(pIter)).FnPos = **(**int32)(__ccgo_up(bp + 32)) >> int32(1)
		}
	}
}

// C documentation
//
//	/*
//	** This is similar to fts5SegIterSeekInit(), except that it initializes
//	** the segment iterator to point to the first term following the page
//	** with pToken/nToken on it.
//	*/
func _fts5SegIterNextInit(tls *libc.TLS, p uintptr, pTerm uintptr, nTerm int32, pSeg uintptr, pIter uintptr) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var a, pSel uintptr
	var bDlidx, iPg int32
	var val Ti64
	var _ /* iTermOff at bp+0 */ int32
	_, _, _, _, _ = a, bDlidx, iPg, pSel, val
	iPg = -int32(1) /* Page of segment to open */
	bDlidx = 0
	pSel = uintptr(0) /* SELECT to find iPg */
	pSel = _fts5IdxNextStmt(tls, p)
	if pSel != 0 {
		Xsqlite3_bind_int(tls, pSel, int32(1), (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FiSegid)
		Xsqlite3_bind_blob(tls, pSel, int32(2), pTerm, nTerm, libc.UintptrFromInt32(0))
		if Xsqlite3_step(tls, pSel) == int32(SQLITE_ROW) {
			val = Xsqlite3_column_int64(tls, pSel, 0)
			iPg = int32(val >> libc.Int32FromInt32(1))
			bDlidx = int32(val & libc.Int64FromInt32(0x0001))
		}
		(*TFts5Index)(unsafe.Pointer(p)).Frc = Xsqlite3_reset(tls, pSel)
		Xsqlite3_bind_null(tls, pSel, int32(2))
		if (*TFts5Index)(unsafe.Pointer(p)).Frc != 0 {
			return
		}
	}
	libc.Xmemset(tls, pIter, 0, uint32(96))
	(*TFts5SegIter)(unsafe.Pointer(pIter)).FpSeg = pSeg
	**(**int32)(__ccgo_up(pIter + 4)) |= int32(FTS5_SEGITER_ONETERM)
	if iPg >= 0 {
		(*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafPgno = iPg - int32(1)
		_fts5SegIterNextPage(tls, p, pIter)
		_fts5SegIterSetNext(tls, p, pIter)
	}
	if (*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf != 0 {
		a = (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).Fp
		**(**int32)(__ccgo_up(bp)) = 0
		(*TFts5SegIter)(unsafe.Pointer(pIter)).FiPgidxOff = (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).FszLeaf
		**(**int32)(__ccgo_up(pIter + 44)) += _sqlite3Fts5GetVarint32(tls, a+uintptr((*TFts5SegIter)(unsafe.Pointer(pIter)).FiPgidxOff), bp)
		(*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafOffset = int64(**(**int32)(__ccgo_up(bp)))
		_fts5SegIterLoadTerm(tls, p, pIter, 0)
		_fts5SegIterLoadNPos(tls, p, pIter)
		if bDlidx != 0 {
			_fts5SegIterLoadDlidx(tls, p, pIter)
		}
	}
}

// C documentation
//
//	/*
//	** Load the next leaf page into the segment iterator.
//	*/
func _fts5SegIterNextPage(tls *libc.TLS, p uintptr, pIter uintptr) {
	var pLeaf, pSeg uintptr
	_, _ = pLeaf, pSeg
	pSeg = (*TFts5SegIter)(unsafe.Pointer(pIter)).FpSeg
	_fts5DataRelease(tls, (*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)
	(*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafPgno = (*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafPgno + 1
	if (*TFts5SegIter)(unsafe.Pointer(pIter)).FpNextLeaf != 0 {
		(*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf = (*TFts5SegIter)(unsafe.Pointer(pIter)).FpNextLeaf
		(*TFts5SegIter)(unsafe.Pointer(pIter)).FpNextLeaf = uintptr(0)
	} else {
		if (*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafPgno <= (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FpgnoLast {
			(*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf = _fts5LeafRead(tls, p, int64((*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FiSegid)<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B)+libc.Int32FromInt32(FTS5_DATA_DLI_B))+int64(libc.Int32FromInt32(0))<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B))+int64(libc.Int32FromInt32(0))<<libc.Int32FromInt32(FTS5_DATA_PAGE_B)+int64((*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafPgno))
		} else {
			(*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf = uintptr(0)
		}
	}
	pLeaf = (*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf
	if pLeaf != 0 {
		(*TFts5SegIter)(unsafe.Pointer(pIter)).FiPgidxOff = (*TFts5Data)(unsafe.Pointer(pLeaf)).FszLeaf
		if (*TFts5Data)(unsafe.Pointer(pLeaf)).FszLeaf >= (*TFts5Data)(unsafe.Pointer(pLeaf)).Fnn {
			(*TFts5SegIter)(unsafe.Pointer(pIter)).FiEndofDoclist = (*TFts5Data)(unsafe.Pointer(pLeaf)).Fnn + int32(1)
		} else {
			**(**int32)(__ccgo_up(pIter + 44)) += _sqlite3Fts5GetVarint32(tls, (*TFts5Data)(unsafe.Pointer(pLeaf)).Fp+uintptr((*TFts5SegIter)(unsafe.Pointer(pIter)).FiPgidxOff), pIter+48)
		}
	}
}

// C documentation
//
//	/*
//	** Advance iterator pIter to the next entry.
//	**
//	** This version of fts5SegIterNext() is only used if detail=none and the
//	** iterator is not a reverse direction iterator.
//	*/
func _fts5SegIterNext_None(tls *libc.TLS, p uintptr, pIter uintptr, pbNewTerm uintptr) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var iOff int32
	var v1 uintptr
	var _ /* iDelta at bp+0 */ Tu64
	var _ /* nKeep at bp+8 */ int32
	var _ /* nList at bp+24 */ int32
	var _ /* nTerm at bp+20 */ int32
	var _ /* pList at bp+12 */ uintptr
	var _ /* zTerm at bp+16 */ uintptr
	_, _ = iOff, v1
	iOff = int32((*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafOffset)
	/* Next entry is on the next page */
	for (*TFts5SegIter)(unsafe.Pointer(pIter)).FpSeg != 0 && iOff >= (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).FszLeaf {
		_fts5SegIterNextPage(tls, p, pIter)
		if (*TFts5Index)(unsafe.Pointer(p)).Frc != 0 || (*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf == uintptr(0) {
			return
		}
		(*TFts5SegIter)(unsafe.Pointer(pIter)).FiRowid = 0
		iOff = int32(4)
	}
	if iOff < (*TFts5SegIter)(unsafe.Pointer(pIter)).FiEndofDoclist {
		iOff = iOff + libc.Int32FromUint8(_sqlite3Fts5GetVarint(tls, (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).Fp+uintptr(iOff), bp))
		(*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafOffset = int64(iOff)
		v1 = pIter + 80
		*(*Ti64)(unsafe.Pointer(v1)) = Ti64(uint64(*(*Ti64)(unsafe.Pointer(v1))) + **(**Tu64)(__ccgo_up(bp)))
	} else {
		if (*TFts5SegIter)(unsafe.Pointer(pIter)).Fflags&int32(FTS5_SEGITER_ONETERM) == 0 {
			if (*TFts5SegIter)(unsafe.Pointer(pIter)).FpSeg != 0 {
				**(**int32)(__ccgo_up(bp + 8)) = 0
				if iOff != _fts5LeafFirstTermOff(tls, (*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf) {
					iOff = iOff + _sqlite3Fts5GetVarint32(tls, (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).Fp+uintptr(iOff), bp+8)
				}
				(*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafOffset = int64(iOff)
				_fts5SegIterLoadTerm(tls, p, pIter, **(**int32)(__ccgo_up(bp + 8)))
			} else {
				**(**uintptr)(__ccgo_up(bp + 12)) = uintptr(0)
				**(**uintptr)(__ccgo_up(bp + 16)) = uintptr(0)
				**(**int32)(__ccgo_up(bp + 20)) = 0
				_sqlite3Fts5HashScanNext(tls, (*TFts5Index)(unsafe.Pointer(p)).FpHash)
				_sqlite3Fts5HashScanEntry(tls, (*TFts5Index)(unsafe.Pointer(p)).FpHash, bp+16, bp+20, bp+12, bp+24)
				if **(**uintptr)(__ccgo_up(bp + 12)) == uintptr(0) {
					goto next_none_eof
				}
				(*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).Fp = **(**uintptr)(__ccgo_up(bp + 12))
				(*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).Fnn = **(**int32)(__ccgo_up(bp + 24))
				(*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).FszLeaf = **(**int32)(__ccgo_up(bp + 24))
				(*TFts5SegIter)(unsafe.Pointer(pIter)).FiEndofDoclist = **(**int32)(__ccgo_up(bp + 24))
				_sqlite3Fts5BufferSet(tls, p+40, pIter+68, **(**int32)(__ccgo_up(bp + 20)), **(**uintptr)(__ccgo_up(bp + 16)))
				(*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafOffset = libc.Int64FromUint8(_sqlite3Fts5GetVarint(tls, **(**uintptr)(__ccgo_up(bp + 12)), pIter+80))
			}
			if pbNewTerm != 0 {
				**(**int32)(__ccgo_up(pbNewTerm)) = int32(1)
			}
		} else {
			goto next_none_eof
		}
	}
	_fts5SegIterLoadNPos(tls, p, pIter)
	return
	goto next_none_eof
next_none_eof:
	;
	_fts5DataRelease(tls, (*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)
	(*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf = uintptr(0)
}

// C documentation
//
//	/*
//	** Advance iterator pIter to the next entry.
//	**
//	** This version of fts5SegIterNext() is only used by reverse iterators.
//	*/
func _fts5SegIterNext_Reverse(tls *libc.TLS, p uintptr, pIter uintptr, pbUnused uintptr) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var a, v1 uintptr
	var iOff int32
	var _ /* iDelta at bp+0 */ Tu64
	_, _, _ = a, iOff, v1
	_ = pbUnused
	if (*TFts5SegIter)(unsafe.Pointer(pIter)).FiRowidOffset > 0 {
		a = (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).Fp
		(*TFts5SegIter)(unsafe.Pointer(pIter)).FiRowidOffset = (*TFts5SegIter)(unsafe.Pointer(pIter)).FiRowidOffset - 1
		(*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafOffset = int64(**(**int32)(__ccgo_up((*TFts5SegIter)(unsafe.Pointer(pIter)).FaRowidOffset + uintptr((*TFts5SegIter)(unsafe.Pointer(pIter)).FiRowidOffset)*4)))
		_fts5SegIterLoadNPos(tls, p, pIter)
		iOff = int32((*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafOffset)
		if (*TFts5Config)(unsafe.Pointer((*TFts5Index)(unsafe.Pointer(p)).FpConfig)).FeDetail != int32(FTS5_DETAIL_NONE) {
			iOff = iOff + (*TFts5SegIter)(unsafe.Pointer(pIter)).FnPos
		}
		_sqlite3Fts5GetVarint(tls, a+uintptr(iOff), bp)
		v1 = pIter + 80
		*(*Ti64)(unsafe.Pointer(v1)) = Ti64(uint64(*(*Ti64)(unsafe.Pointer(v1))) - **(**Tu64)(__ccgo_up(bp)))
	} else {
		_fts5SegIterReverseNewPage(tls, p, pIter)
	}
}

// C documentation
//
//	/*
//	** Iterator pIter currently points to the first rowid in a doclist. This
//	** function sets the iterator up so that iterates in reverse order through
//	** the doclist.
//	*/
func _fts5SegIterReverse(tls *libc.TLS, p uintptr, pIter uintptr) {
	var bTermless, iEnd, iOff, iPoslist, iRowid, iSegid, pgno, pgnoLast, v1 int32
	var iAbs Ti64
	var pDlidx, pLast, pLeaf, pNew, pSeg, tmp uintptr
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = bTermless, iAbs, iEnd, iOff, iPoslist, iRowid, iSegid, pDlidx, pLast, pLeaf, pNew, pSeg, pgno, pgnoLast, tmp, v1
	pDlidx = (*TFts5SegIter)(unsafe.Pointer(pIter)).FpDlidx
	pLast = uintptr(0)
	pgnoLast = 0
	if pDlidx != 0 && (*TFts5Config)(unsafe.Pointer((*TFts5Index)(unsafe.Pointer(p)).FpConfig)).FiVersion == int32(FTS5_CURRENT_VERSION) {
		iSegid = (*TFts5StructureSegment)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpSeg)).FiSegid
		pgnoLast = _fts5DlidxIterPgno(tls, pDlidx)
		pLast = _fts5LeafRead(tls, p, int64(iSegid)<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B)+libc.Int32FromInt32(FTS5_DATA_DLI_B))+int64(libc.Int32FromInt32(0))<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B))+int64(libc.Int32FromInt32(0))<<libc.Int32FromInt32(FTS5_DATA_PAGE_B)+int64(pgnoLast))
	} else {
		pLeaf = (*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf
		if (*TFts5SegIter)(unsafe.Pointer(pIter)).FiTermLeafPgno == (*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafPgno {
			iPoslist = (*TFts5SegIter)(unsafe.Pointer(pIter)).FiTermLeafOffset
		} else {
			iPoslist = int32(4)
		}
		iEnd = iPoslist + int32(9)
		for {
			v1 = iPoslist
			iPoslist = iPoslist + 1
			if !(libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TFts5Data)(unsafe.Pointer(pLeaf)).Fp + uintptr(v1))))&int32(0x80) != 0 && iPoslist < iEnd) {
				break
			}
		}
		(*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafOffset = int64(iPoslist)
		/* If this condition is true then the largest rowid for the current
		 ** term may not be stored on the current page. So search forward to
		 ** see where said rowid really is.  */
		if (*TFts5SegIter)(unsafe.Pointer(pIter)).FiEndofDoclist >= (*TFts5Data)(unsafe.Pointer(pLeaf)).FszLeaf {
			pSeg = (*TFts5SegIter)(unsafe.Pointer(pIter)).FpSeg
			/* The last rowid in the doclist may not be on the current page. Search
			 ** forward to find the page containing the last rowid.  */
			pgno = (*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafPgno + int32(1)
			for {
				if !(!((*TFts5Index)(unsafe.Pointer(p)).Frc != 0) && pgno <= (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FpgnoLast) {
					break
				}
				iAbs = int64((*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FiSegid)<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B)+libc.Int32FromInt32(FTS5_DATA_DLI_B)) + int64(libc.Int32FromInt32(0))<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B)) + int64(libc.Int32FromInt32(0))<<libc.Int32FromInt32(FTS5_DATA_PAGE_B) + int64(pgno)
				pNew = _fts5LeafRead(tls, p, iAbs)
				if pNew != 0 {
					iRowid = libc.Int32FromUint16(_fts5GetU16(tls, (*TFts5Data)(unsafe.Pointer(pNew)).Fp))
					bTermless = libc.BoolInt32((*TFts5Data)(unsafe.Pointer(pNew)).FszLeaf >= (*TFts5Data)(unsafe.Pointer(pNew)).Fnn)
					if iRowid != 0 {
						tmp = pNew
						pNew = pLast
						pLast = tmp
						pgnoLast = pgno
					}
					_fts5DataRelease(tls, pNew)
					if bTermless == 0 {
						break
					}
				}
				goto _2
			_2:
				;
				pgno = pgno + 1
			}
		}
	}
	/* If pLast is NULL at this point, then the last rowid for this doclist
	 ** lies on the page currently indicated by the iterator. In this case
	 ** pIter->iLeafOffset is already set to point to the position-list size
	 ** field associated with the first relevant rowid on the page.
	 **
	 ** Or, if pLast is non-NULL, then it is the page that contains the last
	 ** rowid. In this case configure the iterator so that it points to the
	 ** first rowid on this page.
	 */
	if pLast != 0 {
		_fts5DataRelease(tls, (*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)
		(*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf = pLast
		(*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafPgno = pgnoLast
		if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
			iOff = libc.Int32FromUint16(_fts5GetU16(tls, (*TFts5Data)(unsafe.Pointer(pLast)).Fp))
			if iOff > (*TFts5Data)(unsafe.Pointer(pLast)).FszLeaf {
				_fts5IndexCorruptIter(tls, p, pIter)
				return
			}
			iOff = iOff + libc.Int32FromUint8(_sqlite3Fts5GetVarint(tls, (*TFts5Data)(unsafe.Pointer(pLast)).Fp+uintptr(iOff), pIter+80))
			(*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafOffset = int64(iOff)
			if (*TFts5Data)(unsafe.Pointer(pLast)).FszLeaf >= (*TFts5Data)(unsafe.Pointer(pLast)).Fnn {
				(*TFts5SegIter)(unsafe.Pointer(pIter)).FiEndofDoclist = (*TFts5Data)(unsafe.Pointer(pLast)).Fnn + int32(1)
			} else {
				(*TFts5SegIter)(unsafe.Pointer(pIter)).FiEndofDoclist = _fts5LeafFirstTermOff(tls, pLast)
			}
		}
	}
	_fts5SegIterReverseInitPage(tls, p, pIter)
}

// C documentation
//
//	/*
//	** This function is only ever called on iterators created by calls to
//	** Fts5IndexQuery() with the FTS5INDEX_QUERY_DESC flag set.
//	**
//	** The iterator is in an unusual state when this function is called: the
//	** Fts5SegIter.iLeafOffset variable is set to the offset of the start of
//	** the position-list size field for the first relevant rowid on the page.
//	** Fts5SegIter.rowid is set, but nPos and bDel are not.
//	**
//	** This function advances the iterator so that it points to the last
//	** relevant rowid on the page and, if necessary, initializes the
//	** aRowidOffset[] and iRowidOffset variables. At this point the iterator
//	** is in its regular state - Fts5SegIter.iLeafOffset points to the first
//	** byte of the position list content associated with said rowid.
//	*/
func _fts5SegIterReverseInitPage(tls *libc.TLS, p uintptr, pIter uintptr) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var a, aNew, v1 uintptr
	var eDetail, i, iRowidOffset, n, v2 int32
	var nNew Ti64
	var _ /* bDummy at bp+12 */ int32
	var _ /* iDelta at bp+0 */ Tu64
	var _ /* nPos at bp+8 */ int32
	_, _, _, _, _, _, _, _, _ = a, aNew, eDetail, i, iRowidOffset, n, nNew, v1, v2
	eDetail = (*TFts5Config)(unsafe.Pointer((*TFts5Index)(unsafe.Pointer(p)).FpConfig)).FeDetail
	n = (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).FszLeaf
	i = int32((*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafOffset)
	a = (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).Fp
	iRowidOffset = 0
	if n > (*TFts5SegIter)(unsafe.Pointer(pIter)).FiEndofDoclist {
		n = (*TFts5SegIter)(unsafe.Pointer(pIter)).FiEndofDoclist
	}
	for int32(1) != 0 {
		**(**Tu64)(__ccgo_up(bp)) = uint64(0)
		if i >= n {
			break
		}
		if eDetail == int32(FTS5_DETAIL_NONE) {
			/* todo */
			if i < n && libc.Int32FromUint8(**(**Tu8)(__ccgo_up(a + uintptr(i)))) == 0 {
				i = i + 1
				if i < n && libc.Int32FromUint8(**(**Tu8)(__ccgo_up(a + uintptr(i)))) == 0 {
					i = i + 1
				}
			}
		} else {
			i = i + _fts5GetPoslistSize(tls, a+uintptr(i), bp+8, bp+12)
			i = i + **(**int32)(__ccgo_up(bp + 8))
		}
		if i >= n {
			break
		}
		i = i + libc.Int32FromUint8(_sqlite3Fts5GetVarint(tls, a+uintptr(i), bp))
		v1 = pIter + 80
		*(*Ti64)(unsafe.Pointer(v1)) = Ti64(uint64(*(*Ti64)(unsafe.Pointer(v1))) + **(**Tu64)(__ccgo_up(bp)))
		/* If necessary, grow the pIter->aRowidOffset[] array. */
		if iRowidOffset >= (*TFts5SegIter)(unsafe.Pointer(pIter)).FnRowidOffset {
			nNew = int64((*TFts5SegIter)(unsafe.Pointer(pIter)).FnRowidOffset + int32(8))
			aNew = Xsqlite3_realloc64(tls, (*TFts5SegIter)(unsafe.Pointer(pIter)).FaRowidOffset, libc.Uint64FromInt64(nNew*int64(4)))
			if aNew == uintptr(0) {
				(*TFts5Index)(unsafe.Pointer(p)).Frc = int32(SQLITE_NOMEM)
				break
			}
			(*TFts5SegIter)(unsafe.Pointer(pIter)).FaRowidOffset = aNew
			(*TFts5SegIter)(unsafe.Pointer(pIter)).FnRowidOffset = int32(nNew)
		}
		v2 = iRowidOffset
		iRowidOffset = iRowidOffset + 1
		**(**int32)(__ccgo_up((*TFts5SegIter)(unsafe.Pointer(pIter)).FaRowidOffset + uintptr(v2)*4)) = int32((*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafOffset)
		(*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafOffset = int64(i)
	}
	(*TFts5SegIter)(unsafe.Pointer(pIter)).FiRowidOffset = iRowidOffset
	_fts5SegIterLoadNPos(tls, p, pIter)
}

// C documentation
//
//	/*
//	**
//	*/
func _fts5SegIterReverseNewPage(tls *libc.TLS, p uintptr, pIter uintptr) {
	var a, pNew uintptr
	var iRowidOff int32
	_, _, _ = a, iRowidOff, pNew
	_fts5DataRelease(tls, (*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)
	(*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf = uintptr(0)
	for (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK && (*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafPgno > (*TFts5SegIter)(unsafe.Pointer(pIter)).FiTermLeafPgno {
		(*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafPgno = (*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafPgno - 1
		pNew = _fts5DataRead(tls, p, int64((*TFts5StructureSegment)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpSeg)).FiSegid)<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B)+libc.Int32FromInt32(FTS5_DATA_DLI_B))+int64(libc.Int32FromInt32(0))<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B))+int64(libc.Int32FromInt32(0))<<libc.Int32FromInt32(FTS5_DATA_PAGE_B)+int64((*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafPgno))
		if pNew != 0 {
			/* iTermLeafOffset may be equal to szLeaf if the term is the last
			 ** thing on the page - i.e. the first rowid is on the following page.
			 ** In this case leave pIter->pLeaf==0, this iterator is at EOF. */
			if (*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafPgno == (*TFts5SegIter)(unsafe.Pointer(pIter)).FiTermLeafPgno {
				if (*TFts5SegIter)(unsafe.Pointer(pIter)).FiTermLeafOffset < (*TFts5Data)(unsafe.Pointer(pNew)).FszLeaf {
					(*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf = pNew
					(*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafOffset = int64((*TFts5SegIter)(unsafe.Pointer(pIter)).FiTermLeafOffset)
				}
			} else {
				iRowidOff = libc.Int32FromUint16(_fts5GetU16(tls, (*TFts5Data)(unsafe.Pointer(pNew)).Fp))
				if iRowidOff != 0 {
					if iRowidOff >= (*TFts5Data)(unsafe.Pointer(pNew)).FszLeaf {
						_fts5IndexCorruptIter(tls, p, pIter)
					} else {
						(*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf = pNew
						(*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafOffset = int64(iRowidOff)
					}
				}
			}
			if (*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf != 0 {
				a = (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).Fp + uintptr((*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafOffset)
				**(**Ti64)(__ccgo_up(pIter + 20)) += libc.Int64FromUint8(_sqlite3Fts5GetVarint(tls, a, pIter+80))
				break
			} else {
				_fts5DataRelease(tls, pNew)
			}
		}
	}
	if (*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf != 0 {
		(*TFts5SegIter)(unsafe.Pointer(pIter)).FiEndofDoclist = (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).Fnn + int32(1)
		_fts5SegIterReverseInitPage(tls, p, pIter)
	}
}

// C documentation
//
//	/*
//	** Initialize the object pIter to point to term pTerm/nTerm within segment
//	** pSeg. If there is no such term in the index, the iterator is set to EOF.
//	**
//	** If an error occurs, Fts5Index.rc is set to an appropriate error code. If
//	** an error has already occurred when this function is called, it is a no-op.
//	*/
func _fts5SegIterSeekInit(tls *libc.TLS, p uintptr, pTerm uintptr, nTerm int32, flags int32, pSeg uintptr, pIter uintptr) {
	var bDlidx, bGe, iPg int32
	var pIdxSelect uintptr
	var val Ti64
	_, _, _, _, _ = bDlidx, bGe, iPg, pIdxSelect, val
	iPg = int32(1)
	bGe = flags & int32(FTS5INDEX_QUERY_SCAN)
	bDlidx = 0 /* True if there is a doclist-index */
	pIdxSelect = uintptr(0)
	libc.Xmemset(tls, pIter, 0, uint32(96))
	(*TFts5SegIter)(unsafe.Pointer(pIter)).FpSeg = pSeg
	/* This block sets stack variable iPg to the leaf page number that may
	 ** contain term (pTerm/nTerm), if it is present in the segment. */
	pIdxSelect = _fts5IdxSelectStmt(tls, p)
	if (*TFts5Index)(unsafe.Pointer(p)).Frc != 0 {
		return
	}
	Xsqlite3_bind_int(tls, pIdxSelect, int32(1), (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FiSegid)
	Xsqlite3_bind_blob(tls, pIdxSelect, int32(2), pTerm, nTerm, libc.UintptrFromInt32(0))
	if int32(SQLITE_ROW) == Xsqlite3_step(tls, pIdxSelect) {
		val = int64(Xsqlite3_column_int(tls, pIdxSelect, 0))
		iPg = int32(val >> libc.Int32FromInt32(1))
		bDlidx = int32(val & libc.Int64FromInt32(0x0001))
	}
	(*TFts5Index)(unsafe.Pointer(p)).Frc = Xsqlite3_reset(tls, pIdxSelect)
	Xsqlite3_bind_null(tls, pIdxSelect, int32(2))
	if iPg < (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FpgnoFirst {
		iPg = (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FpgnoFirst
		bDlidx = 0
	}
	(*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafPgno = iPg - int32(1)
	_fts5SegIterNextPage(tls, p, pIter)
	if (*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf != 0 {
		_fts5LeafSeek(tls, p, bGe, pIter, pTerm, nTerm)
	}
	if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK && (bGe == 0 || flags&int32(FTS5INDEX_QUERY_SCANONETERM) != 0) {
		**(**int32)(__ccgo_up(pIter + 4)) |= int32(FTS5_SEGITER_ONETERM)
		if (*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf != 0 {
			if flags&int32(FTS5INDEX_QUERY_DESC) != 0 {
				**(**int32)(__ccgo_up(pIter + 4)) |= int32(FTS5_SEGITER_REVERSE)
			}
			if bDlidx != 0 {
				_fts5SegIterLoadDlidx(tls, p, pIter)
			}
			if flags&int32(FTS5INDEX_QUERY_DESC) != 0 {
				_fts5SegIterReverse(tls, p, pIter)
			}
		}
	}
	_fts5SegIterSetNext(tls, p, pIter)
	if 0 == flags&int32(FTS5INDEX_QUERY_SCANONETERM) {
		_fts5SegIterAllocTombstone(tls, p, pIter)
	}
	/* Either:
	 **
	 **   1) an error has occurred, or
	 **   2) the iterator points to EOF, or
	 **   3) the iterator points to an entry with term (pTerm/nTerm), or
	 **   4) the FTS5INDEX_QUERY_SCAN flag was set and the iterator points
	 **      to an entry with a term greater than or equal to (pTerm/nTerm).
	 */
}

// C documentation
//
//	/*
//	** Iterator pIter currently points to a valid entry (not EOF). This
//	** function appends the position list data for the current entry to
//	** buffer pBuf. It does not make a copy of the position-list size
//	** field.
//	*/
func _fts5SegiterPoslist(tls *libc.TLS, p uintptr, pSeg uintptr, pColset uintptr, pBuf uintptr) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var v1 int32
	var _ /* sCtx at bp+0 */ TPoslistCallbackCtx
	var _ /* sCtx at bp+12 */ TPoslistOffsetsCtx
	_ = v1
	if libc.Uint32FromInt32((*TFts5Buffer)(unsafe.Pointer(pBuf)).Fn)+libc.Uint32FromInt32((*TFts5SegIter)(unsafe.Pointer(pSeg)).FnPos+libc.Int32FromInt32(FTS5_DATA_ZERO_PADDING)) <= libc.Uint32FromInt32((*TFts5Buffer)(unsafe.Pointer(pBuf)).FnSpace) {
		v1 = 0
	} else {
		v1 = _sqlite3Fts5BufferSize(tls, p+40, pBuf, libc.Uint32FromInt32((*TFts5SegIter)(unsafe.Pointer(pSeg)).FnPos+int32(FTS5_DATA_ZERO_PADDING)+(*TFts5Buffer)(unsafe.Pointer(pBuf)).Fn))
	}
	if 0 == v1 {
		libc.Xmemset(tls, (*TFts5Buffer)(unsafe.Pointer(pBuf)).Fp+uintptr((*TFts5Buffer)(unsafe.Pointer(pBuf)).Fn+(*TFts5SegIter)(unsafe.Pointer(pSeg)).FnPos), 0, uint32(FTS5_DATA_ZERO_PADDING))
		if pColset == uintptr(0) {
			_fts5ChunkIterate(tls, p, pSeg, pBuf, __ccgo_fp(_fts5PoslistCallback))
		} else {
			if (*TFts5Config)(unsafe.Pointer((*TFts5Index)(unsafe.Pointer(p)).FpConfig)).FeDetail == FTS5_DETAIL_FULL {
				(**(**TPoslistCallbackCtx)(__ccgo_up(bp))).FpBuf = pBuf
				(**(**TPoslistCallbackCtx)(__ccgo_up(bp))).FpColset = pColset
				(**(**TPoslistCallbackCtx)(__ccgo_up(bp))).FeState = _fts5IndexColsetTest(tls, pColset, 0)
				_fts5ChunkIterate(tls, p, pSeg, bp, __ccgo_fp(_fts5PoslistFilterCallback))
			} else {
				libc.Xmemset(tls, bp+12, 0, uint32(16))
				(**(**TPoslistOffsetsCtx)(__ccgo_up(bp + 12))).FpBuf = pBuf
				(**(**TPoslistOffsetsCtx)(__ccgo_up(bp + 12))).FpColset = pColset
				_fts5ChunkIterate(tls, p, pSeg, bp+12, __ccgo_fp(_fts5PoslistOffsetsCallback))
			}
		}
	}
}

// C documentation
//
//	/*
//	** Set the SQLITE_INDEX_SCAN_UNIQUE flag in pIdxInfo->flags. Unless this
//	** extension is currently being used by a version of SQLite too old to
//	** support index-info flags. In that case this function is a no-op.
//	*/
func _fts5SetUniqueFlag(tls *libc.TLS, pIdxInfo uintptr) {
	**(**int32)(__ccgo_up(pIdxInfo + 52)) |= int32(SQLITE_INDEX_SCAN_UNIQUE)
}

func _fts5SetupPrefixIter(tls *libc.TLS, p uintptr, bDesc int32, iIdx int32, pToken uintptr, nToken int32, pColset uintptr, ppIter uintptr) {
	bp := tls.Alloc(64)
	defer tls.Free(64)
	var i, iFree, v3 int32
	var pCtx, pData, pStruct uintptr
	var _ /* s at bp+0 */ TPrefixSetupCtx
	var _ /* s2 at bp+44 */ TTokendataSetupCtx
	_, _, _, _, _, _ = i, iFree, pCtx, pData, pStruct, v3
	libc.Xmemset(tls, bp, 0, uint32(44))
	libc.Xmemset(tls, bp+44, 0, uint32(12))
	(**(**TPrefixSetupCtx)(__ccgo_up(bp))).FnMerge = int32(1)
	(**(**TPrefixSetupCtx)(__ccgo_up(bp))).FiLastRowid = 0
	(**(**TPrefixSetupCtx)(__ccgo_up(bp))).FnBuf = int32(32)
	if iIdx == 0 && (*TFts5Config)(unsafe.Pointer((*TFts5Index)(unsafe.Pointer(p)).FpConfig)).FeDetail == FTS5_DETAIL_FULL && (*TFts5Config)(unsafe.Pointer((*TFts5Index)(unsafe.Pointer(p)).FpConfig)).FbPrefixInsttoken != 0 {
		(**(**TPrefixSetupCtx)(__ccgo_up(bp))).FpTokendata = bp + 44
		(**(**TTokendataSetupCtx)(__ccgo_up(bp + 44))).FpT = _fts5IdxMalloc(tls, p, libc.Int64FromUint32(uint32(libc.UintptrFromInt32(0)+56)+libc.Uint32FromInt32(libc.Int32FromInt32(1))*libc.Uint32FromInt64(72)))
	}
	if (*TFts5Config)(unsafe.Pointer((*TFts5Index)(unsafe.Pointer(p)).FpConfig)).FeDetail == int32(FTS5_DETAIL_NONE) {
		(**(**TPrefixSetupCtx)(__ccgo_up(bp))).FxMerge = __ccgo_fp(_fts5MergeRowidLists)
		(**(**TPrefixSetupCtx)(__ccgo_up(bp))).FxAppend = __ccgo_fp(_fts5AppendRowid)
	} else {
		(**(**TPrefixSetupCtx)(__ccgo_up(bp))).FnMerge = libc.Int32FromInt32(FTS5_MERGE_NLIST) - libc.Int32FromInt32(1)
		(**(**TPrefixSetupCtx)(__ccgo_up(bp))).FnBuf = (**(**TPrefixSetupCtx)(__ccgo_up(bp))).FnMerge * int32(8) /* Sufficient to merge (16^8)==(2^32) lists */
		(**(**TPrefixSetupCtx)(__ccgo_up(bp))).FxMerge = __ccgo_fp(_fts5MergePrefixLists)
		(**(**TPrefixSetupCtx)(__ccgo_up(bp))).FxAppend = __ccgo_fp(_fts5AppendPoslist)
	}
	(**(**TPrefixSetupCtx)(__ccgo_up(bp))).FaBuf = _fts5IdxMalloc(tls, p, libc.Int64FromUint32(uint32(12)*libc.Uint32FromInt32((**(**TPrefixSetupCtx)(__ccgo_up(bp))).FnBuf)))
	pStruct = _fts5StructureRead(tls, p)
	if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
		pCtx = bp
		/* If iIdx is non-zero, then it is the number of a prefix-index for
		 ** prefixes 1 character longer than the prefix being queried for. That
		 ** index contains all the doclists required, except for the one
		 ** corresponding to the prefix itself. That one is extracted from the
		 ** main term index here.  */
		if iIdx != 0 {
			**(**Tu8)(__ccgo_up(pToken)) = uint8('0')
			_fts5VisitEntries(tls, p, pColset, pToken, nToken, 0, __ccgo_fp(_prefixIterSetupCb), pCtx)
		}
		**(**Tu8)(__ccgo_up(pToken)) = libc.Uint8FromInt32(int32('0') + iIdx)
		_fts5VisitEntries(tls, p, pColset, pToken, nToken, int32(1), __ccgo_fp(_prefixIterSetupCb), pCtx)
		i = 0
		for {
			if !(i < (**(**TPrefixSetupCtx)(__ccgo_up(bp))).FnBuf) {
				break
			}
			if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
				(*(*func(*libc.TLS, uintptr, uintptr, int32, uintptr))(unsafe.Pointer(&struct{ uintptr }{(**(**TPrefixSetupCtx)(__ccgo_up(bp))).FxMerge})))(tls, p, bp+28, (**(**TPrefixSetupCtx)(__ccgo_up(bp))).FnMerge, (**(**TPrefixSetupCtx)(__ccgo_up(bp))).FaBuf+uintptr(i)*12)
			}
			iFree = i
			for {
				if !(iFree < i+(**(**TPrefixSetupCtx)(__ccgo_up(bp))).FnMerge) {
					break
				}
				_sqlite3Fts5BufferFree(tls, (**(**TPrefixSetupCtx)(__ccgo_up(bp))).FaBuf+uintptr(iFree)*12)
				goto _2
			_2:
				;
				iFree = iFree + 1
			}
			goto _1
		_1:
			;
			i = i + (**(**TPrefixSetupCtx)(__ccgo_up(bp))).FnMerge
		}
		pData = _fts5IdxMalloc(tls, p, int64(12)+int64((**(**TPrefixSetupCtx)(__ccgo_up(bp))).Fdoclist.Fn)+int64(FTS5_DATA_ZERO_PADDING))
		if pData != 0 {
			(*TFts5Data)(unsafe.Pointer(pData)).Fp = pData + 1*12
			v3 = (**(**TPrefixSetupCtx)(__ccgo_up(bp))).Fdoclist.Fn
			(*TFts5Data)(unsafe.Pointer(pData)).FszLeaf = v3
			(*TFts5Data)(unsafe.Pointer(pData)).Fnn = v3
			if (**(**TPrefixSetupCtx)(__ccgo_up(bp))).Fdoclist.Fn != 0 {
				libc.Xmemcpy(tls, (*TFts5Data)(unsafe.Pointer(pData)).Fp, (**(**TPrefixSetupCtx)(__ccgo_up(bp))).Fdoclist.Fp, libc.Uint32FromInt32((**(**TPrefixSetupCtx)(__ccgo_up(bp))).Fdoclist.Fn))
			}
			_fts5MultiIterNew2(tls, p, pData, bDesc, ppIter)
		}
		if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK && (**(**TPrefixSetupCtx)(__ccgo_up(bp))).FpTokendata != 0 {
			_fts5TokendataIterSortMap(tls, p, (**(**TTokendataSetupCtx)(__ccgo_up(bp + 44))).FpT)
			(*TFts5Iter)(unsafe.Pointer(**(**uintptr)(__ccgo_up(ppIter)))).FpTokenDataIter = (**(**TTokendataSetupCtx)(__ccgo_up(bp + 44))).FpT
			(**(**TTokendataSetupCtx)(__ccgo_up(bp + 44))).FpT = uintptr(0)
		}
	}
	_fts5TokendataIterDelete(tls, (**(**TTokendataSetupCtx)(__ccgo_up(bp + 44))).FpT)
	_sqlite3Fts5BufferFree(tls, bp+28)
	_fts5StructureRelease(tls, pStruct)
	Xsqlite3_free(tls, (**(**TPrefixSetupCtx)(__ccgo_up(bp))).FaBuf)
}

// C documentation
//
//	/*
//	** pIter is a prefix query. This function populates pIter->pTokenDataIter
//	** with an Fts5TokenDataIter object containing mappings for all rows
//	** matched by the query.
//	*/
func _fts5SetupPrefixIterTokendata(tls *libc.TLS, pIter uintptr, pToken uintptr, nToken int32) (r int32) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var p uintptr
	var _ /* ctx at bp+12 */ TTokendataSetupCtx
	var _ /* token at bp+0 */ TFts5Buffer
	_ = p
	p = (*TFts5Iter)(unsafe.Pointer(pIter)).FpIndex
	**(**TFts5Buffer)(__ccgo_up(bp)) = TFts5Buffer{}
	libc.Xmemset(tls, bp+12, 0, uint32(12))
	if !(libc.Uint32FromInt32((*TFts5Buffer)(unsafe.Pointer(bp)).Fn)+libc.Uint32FromInt32(nToken+libc.Int32FromInt32(1)) <= libc.Uint32FromInt32((*TFts5Buffer)(unsafe.Pointer(bp)).FnSpace)) {
		_sqlite3Fts5BufferSize(tls, p+40, bp, libc.Uint32FromInt32(nToken+int32(1)+(*TFts5Buffer)(unsafe.Pointer(bp)).Fn))
	}
	(**(**TTokendataSetupCtx)(__ccgo_up(bp + 12))).FpT = _sqlite3Fts5MallocZero(tls, p+40, libc.Int64FromUint32(uint32(libc.UintptrFromInt32(0)+56)+libc.Uint32FromInt32(libc.Int32FromInt32(1))*libc.Uint32FromInt64(72)))
	if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
		/* Fill in the token prefix to search for */
		**(**Tu8)(__ccgo_up((**(**TFts5Buffer)(__ccgo_up(bp))).Fp)) = uint8('0')
		libc.Xmemcpy(tls, (**(**TFts5Buffer)(__ccgo_up(bp))).Fp+1, pToken, libc.Uint32FromInt32(nToken))
		(**(**TFts5Buffer)(__ccgo_up(bp))).Fn = nToken + int32(1)
		_fts5VisitEntries(tls, p, uintptr(0), (**(**TFts5Buffer)(__ccgo_up(bp))).Fp, (**(**TFts5Buffer)(__ccgo_up(bp))).Fn, int32(1), __ccgo_fp(_prefixIterSetupTokendataCb), bp+12)
		_fts5TokendataIterSortMap(tls, p, (**(**TTokendataSetupCtx)(__ccgo_up(bp + 12))).FpT)
	}
	if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
		(*TFts5Iter)(unsafe.Pointer(pIter)).FpTokenDataIter = (**(**TTokendataSetupCtx)(__ccgo_up(bp + 12))).FpT
	} else {
		_fts5TokendataIterDelete(tls, (**(**TTokendataSetupCtx)(__ccgo_up(bp + 12))).FpT)
	}
	_sqlite3Fts5BufferFree(tls, bp)
	return _fts5IndexReturn(tls, p)
}

func _fts5SorterNext(tls *libc.TLS, pCsr uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var a, aBlob, pSorter, v1 uintptr
	var i, iOff, nBlob, rc int32
	var _ /* iVal at bp+0 */ int32
	_, _, _, _, _, _, _, _ = a, aBlob, i, iOff, nBlob, pSorter, rc, v1
	pSorter = (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpSorter
	rc = Xsqlite3_step(tls, (*TFts5Sorter)(unsafe.Pointer(pSorter)).FpStmt)
	if rc == int32(SQLITE_DONE) {
		rc = SQLITE_OK
		**(**int32)(__ccgo_up(pCsr + 56)) |= libc.Int32FromInt32(FTS5CSR_EOF) | libc.Int32FromInt32(FTS5CSR_REQUIRE_CONTENT)
	} else {
		if rc == int32(SQLITE_ROW) {
			iOff = 0
			rc = SQLITE_OK
			(*TFts5Sorter)(unsafe.Pointer(pSorter)).FiRowid = Xsqlite3_column_int64(tls, (*TFts5Sorter)(unsafe.Pointer(pSorter)).FpStmt, 0)
			nBlob = Xsqlite3_column_bytes(tls, (*TFts5Sorter)(unsafe.Pointer(pSorter)).FpStmt, int32(1))
			v1 = Xsqlite3_column_blob(tls, (*TFts5Sorter)(unsafe.Pointer(pSorter)).FpStmt, int32(1))
			a = v1
			aBlob = v1
			/* nBlob==0 in detail=none mode. */
			if nBlob > 0 {
				i = 0
				for {
					if !(i < (*TFts5Sorter)(unsafe.Pointer(pSorter)).FnIdx-int32(1)) {
						break
					}
					a = a + uintptr(_sqlite3Fts5GetVarint32(tls, a, bp))
					iOff = iOff + **(**int32)(__ccgo_up(bp))
					*(*int32)(unsafe.Pointer(pSorter + 20 + uintptr(i)*4)) = iOff
					goto _2
				_2:
					;
					i = i + 1
				}
				*(*int32)(unsafe.Pointer(pSorter + 20 + uintptr(i)*4)) = t__predefined_ptrdiff_t(aBlob+uintptr(nBlob)) - int32(a)
				(*TFts5Sorter)(unsafe.Pointer(pSorter)).FaPoslist = a
			}
			_fts5CsrNewrow(tls, pCsr)
		}
	}
	return rc
}

// C documentation
//
//	/*
//	** Load the contents of the "averages" record from disk into the
//	** p->nTotalRow and p->aTotalSize[] variables. If successful, and if
//	** argument bCache is true, set the p->bTotalsValid flag to indicate
//	** that the contents of aTotalSize[] and nTotalRow are valid until
//	** further notice.
//	**
//	** Return SQLITE_OK if successful, or an SQLite error code if an error
//	** occurs.
//	*/
func _fts5StorageLoadTotals(tls *libc.TLS, p uintptr, bCache int32) (r int32) {
	var rc int32
	_ = rc
	rc = SQLITE_OK
	if (*TFts5Storage)(unsafe.Pointer(p)).FbTotalsValid == 0 {
		rc = _sqlite3Fts5IndexGetAverages(tls, (*TFts5Storage)(unsafe.Pointer(p)).FpIndex, p+12, (*TFts5Storage)(unsafe.Pointer(p)).FaTotalSize)
		(*TFts5Storage)(unsafe.Pointer(p)).FbTotalsValid = bCache
	}
	return rc
}

// C documentation
//
//	/*
//	** Add a level to the Fts5Structure.aLevel[] array of structure object
//	** (*ppStruct).
//	*/
func _fts5StructureAddLevel(tls *libc.TLS, pRc uintptr, ppStruct uintptr) {
	var nByte Tsqlite3_int64
	var nLevel int32
	var pStruct uintptr
	_, _, _ = nByte, nLevel, pStruct
	_fts5StructureMakeWritable(tls, pRc, ppStruct)
	if **(**int32)(__ccgo_up(pRc)) == SQLITE_OK {
		pStruct = **(**uintptr)(__ccgo_up(ppStruct))
		nLevel = (*TFts5Structure)(unsafe.Pointer(pStruct)).FnLevel
		nByte = libc.Int64FromUint32(uint32(libc.UintptrFromInt32(0)+28) + libc.Uint32FromInt32(nLevel+libc.Int32FromInt32(2))*libc.Uint32FromInt64(12))
		pStruct = Xsqlite3_realloc64(tls, pStruct, libc.Uint64FromInt64(nByte))
		if pStruct != 0 {
			libc.Xmemset(tls, pStruct+28+uintptr(nLevel)*12, 0, uint32(12))
			(*TFts5Structure)(unsafe.Pointer(pStruct)).FnLevel = (*TFts5Structure)(unsafe.Pointer(pStruct)).FnLevel + 1
			**(**uintptr)(__ccgo_up(ppStruct)) = pStruct
		} else {
			**(**int32)(__ccgo_up(pRc)) = int32(SQLITE_NOMEM)
		}
	}
}

// C documentation
//
//	/*
//	** Extend level iLvl so that there is room for at least nExtra more
//	** segments.
//	*/
func _fts5StructureExtendLevel(tls *libc.TLS, pRc uintptr, pStruct uintptr, iLvl int32, nExtra int32, bInsert int32) {
	var aNew, pLvl uintptr
	var nByte Tsqlite3_int64
	var nMove int32
	_, _, _, _ = aNew, nByte, nMove, pLvl
	if **(**int32)(__ccgo_up(pRc)) == SQLITE_OK {
		pLvl = pStruct + 28 + uintptr(iLvl)*12
		nByte = libc.Int64FromUint32(libc.Uint32FromInt32((*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnSeg+nExtra) * uint32(48))
		aNew = Xsqlite3_realloc64(tls, (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FaSeg, libc.Uint64FromInt64(nByte))
		if aNew != 0 {
			if bInsert == 0 {
				libc.Xmemset(tls, aNew+uintptr((*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnSeg)*48, 0, uint32(48)*libc.Uint32FromInt32(nExtra))
			} else {
				nMove = libc.Int32FromUint32(libc.Uint32FromInt32((*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnSeg) * uint32(48))
				libc.Xmemmove(tls, aNew+uintptr(nExtra)*48, aNew, libc.Uint32FromInt32(nMove))
				libc.Xmemset(tls, aNew, 0, uint32(48)*libc.Uint32FromInt32(nExtra))
			}
			(*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FaSeg = aNew
		} else {
			**(**int32)(__ccgo_up(pRc)) = int32(SQLITE_NOMEM)
		}
	}
}

// C documentation
//
//	/*
//	** Ensure that structure object (*pp) is writable.
//	**
//	** This function is a no-op if (*pRc) is not SQLITE_OK when it is called. If
//	** an error occurs, (*pRc) is set to an SQLite error code before returning.
//	*/
func _fts5StructureMakeWritable(tls *libc.TLS, pRc uintptr, pp uintptr) {
	var i int32
	var nByte Ti64
	var p, pLvl, pNew uintptr
	_, _, _, _, _ = i, nByte, p, pLvl, pNew
	p = **(**uintptr)(__ccgo_up(pp))
	if **(**int32)(__ccgo_up(pRc)) == SQLITE_OK && (*TFts5Structure)(unsafe.Pointer(p)).FnRef > int32(1) {
		nByte = libc.Int64FromUint32(uint32(libc.UintptrFromInt32(0)+28) + libc.Uint32FromInt32((*TFts5Structure)(unsafe.Pointer(p)).FnLevel)*libc.Uint32FromInt64(12))
		pNew = _sqlite3Fts5MallocZero(tls, pRc, nByte)
		if pNew != 0 {
			libc.Xmemcpy(tls, pNew, p, libc.Uint32FromInt64(nByte))
			i = 0
			for {
				if !(i < (*TFts5Structure)(unsafe.Pointer(p)).FnLevel) {
					break
				}
				(*(*TFts5StructureLevel)(unsafe.Pointer(pNew + 28 + uintptr(i)*12))).FaSeg = uintptr(0)
				goto _1
			_1:
				;
				i = i + 1
			}
			i = 0
			for {
				if !(i < (*TFts5Structure)(unsafe.Pointer(p)).FnLevel) {
					break
				}
				pLvl = pNew + 28 + uintptr(i)*12
				nByte = libc.Int64FromUint32(uint32(48) * libc.Uint32FromInt32((*(*TFts5StructureLevel)(unsafe.Pointer(pNew + 28 + uintptr(i)*12))).FnSeg))
				(*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FaSeg = _sqlite3Fts5MallocZero(tls, pRc, nByte)
				if (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FaSeg == uintptr(0) {
					i = 0
					for {
						if !(i < (*TFts5Structure)(unsafe.Pointer(p)).FnLevel) {
							break
						}
						Xsqlite3_free(tls, (*(*TFts5StructureLevel)(unsafe.Pointer(pNew + 28 + uintptr(i)*12))).FaSeg)
						goto _3
					_3:
						;
						i = i + 1
					}
					Xsqlite3_free(tls, pNew)
					return
				}
				libc.Xmemcpy(tls, (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FaSeg, (*(*TFts5StructureLevel)(unsafe.Pointer(p + 28 + uintptr(i)*12))).FaSeg, libc.Uint32FromInt64(nByte))
				goto _2
			_2:
				;
				i = i + 1
			}
			(*TFts5Structure)(unsafe.Pointer(p)).FnRef = (*TFts5Structure)(unsafe.Pointer(p)).FnRef - 1
			(*TFts5Structure)(unsafe.Pointer(pNew)).FnRef = int32(1)
		}
		**(**uintptr)(__ccgo_up(pp)) = pNew
	}
}

// C documentation
//
//	/*
//	** A new segment has just been written to level iLvl of index structure
//	** pStruct. This function determines if any segments should be promoted
//	** as a result. Segments are promoted in two scenarios:
//	**
//	**   a) If the segment just written is smaller than one or more segments
//	**      within the previous populated level, it is promoted to the previous
//	**      populated level.
//	**
//	**   b) If the segment just written is larger than the newest segment on
//	**      the next populated level, then that segment, and any other adjacent
//	**      segments that are also smaller than the one just written, are
//	**      promoted.
//	**
//	** If one or more segments are promoted, the structure object is updated
//	** to reflect this.
//	*/
func _fts5StructurePromote(tls *libc.TLS, p uintptr, iLvl int32, pStruct uintptr) {
	var i, iPromote, iTst, nSeg, sz, szMax, szPromote, szSeg int32
	var pSeg, pTst uintptr
	_, _, _, _, _, _, _, _, _, _ = i, iPromote, iTst, nSeg, pSeg, pTst, sz, szMax, szPromote, szSeg
	if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
		iPromote = -int32(1)
		szPromote = 0 /* Size of segment just written */
		nSeg = (*(*TFts5StructureLevel)(unsafe.Pointer(pStruct + 28 + uintptr(iLvl)*12))).FnSeg
		if nSeg == 0 {
			return
		}
		pSeg = (*(*TFts5StructureLevel)(unsafe.Pointer(pStruct + 28 + uintptr(iLvl)*12))).FaSeg + uintptr((*(*TFts5StructureLevel)(unsafe.Pointer(pStruct + 28 + uintptr(iLvl)*12))).FnSeg-int32(1))*48
		szSeg = int32(1) + (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FpgnoLast - (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FpgnoFirst
		/* Check for condition (a) */
		iTst = iLvl - int32(1)
		for {
			if !(iTst >= 0 && (*(*TFts5StructureLevel)(unsafe.Pointer(pStruct + 28 + uintptr(iTst)*12))).FnSeg == 0) {
				break
			}
			goto _1
		_1:
			;
			iTst = iTst - 1
		}
		if iTst >= 0 {
			szMax = 0
			pTst = pStruct + 28 + uintptr(iTst)*12
			i = 0
			for {
				if !(i < (*TFts5StructureLevel)(unsafe.Pointer(pTst)).FnSeg) {
					break
				}
				sz = (**(**TFts5StructureSegment)(__ccgo_up((*TFts5StructureLevel)(unsafe.Pointer(pTst)).FaSeg + uintptr(i)*48))).FpgnoLast - (**(**TFts5StructureSegment)(__ccgo_up((*TFts5StructureLevel)(unsafe.Pointer(pTst)).FaSeg + uintptr(i)*48))).FpgnoFirst + int32(1)
				if sz > szMax {
					szMax = sz
				}
				goto _2
			_2:
				;
				i = i + 1
			}
			if szMax >= szSeg {
				/* Condition (a) is true. Promote the newest segment on level
				 ** iLvl to level iTst.  */
				iPromote = iTst
				szPromote = szMax
			}
		}
		/* If condition (a) is not met, assume (b) is true. StructurePromoteTo()
		 ** is a no-op if it is not.  */
		if iPromote < 0 {
			iPromote = iLvl
			szPromote = szSeg
		}
		_fts5StructurePromoteTo(tls, p, iPromote, szPromote, pStruct)
	}
}

// C documentation
//
//	/*
//	** Return a copy of index structure pStruct. Except, promote as many
//	** segments as possible to level iPromote. If an OOM occurs, NULL is
//	** returned.
//	*/
func _fts5StructurePromoteTo(tls *libc.TLS, p uintptr, iPromote int32, szPromote int32, pStruct uintptr) {
	var il, is, sz int32
	var pLvl, pOut uintptr
	_, _, _, _, _ = il, is, pLvl, pOut, sz
	pOut = pStruct + 28 + uintptr(iPromote)*12
	if (*TFts5StructureLevel)(unsafe.Pointer(pOut)).FnMerge == 0 {
		il = iPromote + int32(1)
		for {
			if !(il < (*TFts5Structure)(unsafe.Pointer(pStruct)).FnLevel) {
				break
			}
			pLvl = pStruct + 28 + uintptr(il)*12
			if (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnMerge != 0 {
				return
			}
			is = (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnSeg - int32(1)
			for {
				if !(is >= 0) {
					break
				}
				sz = _fts5SegmentSize(tls, (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FaSeg+uintptr(is)*48)
				if sz > szPromote {
					return
				}
				_fts5StructureExtendLevel(tls, p+40, pStruct, iPromote, int32(1), int32(1))
				if (*TFts5Index)(unsafe.Pointer(p)).Frc != 0 {
					return
				}
				libc.Xmemcpy(tls, (*TFts5StructureLevel)(unsafe.Pointer(pOut)).FaSeg, (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FaSeg+uintptr(is)*48, uint32(48))
				(*TFts5StructureLevel)(unsafe.Pointer(pOut)).FnSeg = (*TFts5StructureLevel)(unsafe.Pointer(pOut)).FnSeg + 1
				(*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnSeg = (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnSeg - 1
				goto _2
			_2:
				;
				is = is - 1
			}
			goto _1
		_1:
			;
			il = il + 1
		}
	}
}

// C documentation
//
//	/*
//	** Release a reference to an Fts5Structure object returned by an earlier
//	** call to fts5StructureRead() or fts5StructureDecode().
//	*/
func _fts5StructureRelease(tls *libc.TLS, pStruct uintptr) {
	var i, v1 int32
	var v2 uintptr
	var v3 bool
	_, _, _, _ = i, v1, v2, v3
	if v3 = pStruct != 0; v3 {
		v2 = pStruct
		*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) - 1
		v1 = *(*int32)(unsafe.Pointer(v2))
	}
	if v3 && 0 >= v1 {
		i = 0
		for {
			if !(i < (*TFts5Structure)(unsafe.Pointer(pStruct)).FnLevel) {
				break
			}
			Xsqlite3_free(tls, (*(*TFts5StructureLevel)(unsafe.Pointer(pStruct + 28 + uintptr(i)*12))).FaSeg)
			goto _4
		_4:
			;
			i = i + 1
		}
		Xsqlite3_free(tls, pStruct)
	}
}

// C documentation
//
//	/*
//	** Sort the contents of the pT->aMap[] array.
//	**
//	** The sorting algorithm requires a malloc(). If this fails, an error code
//	** is left in Fts5Index.rc before returning.
//	*/
func _fts5TokendataIterSortMap(tls *libc.TLS, p uintptr, pT uintptr) {
	var a1, a2, aTmp, tmp uintptr
	var i1, n1, n2 int32
	var nByte, nHalf Ti64
	var v3, v4 int64
	_, _, _, _, _, _, _, _, _, _, _ = a1, a2, aTmp, i1, n1, n2, nByte, nHalf, tmp, v3, v4
	aTmp = uintptr(0)
	nByte = (*TFts5TokenDataIter)(unsafe.Pointer(pT)).FnMap * int64(24)
	aTmp = _sqlite3Fts5MallocZero(tls, p+40, nByte)
	if aTmp != 0 {
		a1 = (*TFts5TokenDataIter)(unsafe.Pointer(pT)).FaMap
		a2 = aTmp
		nHalf = int64(1)
		for {
			if !(nHalf < (*TFts5TokenDataIter)(unsafe.Pointer(pT)).FnMap) {
				break
			}
			i1 = 0
			for {
				if !(int64(i1) < (*TFts5TokenDataIter)(unsafe.Pointer(pT)).FnMap) {
					break
				}
				if nHalf < (*TFts5TokenDataIter)(unsafe.Pointer(pT)).FnMap-int64(i1) {
					v3 = nHalf
				} else {
					v3 = (*TFts5TokenDataIter)(unsafe.Pointer(pT)).FnMap - int64(i1)
				}
				n1 = int32(v3)
				if nHalf < (*TFts5TokenDataIter)(unsafe.Pointer(pT)).FnMap-int64(i1)-int64(n1) {
					v4 = nHalf
				} else {
					v4 = (*TFts5TokenDataIter)(unsafe.Pointer(pT)).FnMap - int64(i1) - int64(n1)
				}
				n2 = int32(v4)
				_fts5TokendataMerge(tls, a1+uintptr(i1)*24, n1, a1+uintptr(i1+n1)*24, n2, a2+uintptr(i1)*24)
				goto _2
			_2:
				;
				i1 = int32(int64(i1) + nHalf*libc.Int64FromInt32(2))
			}
			tmp = a1
			a1 = a2
			a2 = tmp
			goto _1
		_1:
			;
			nHalf = nHalf * int64(2)
		}
		if a1 != (*TFts5TokenDataIter)(unsafe.Pointer(pT)).FaMap {
			libc.Xmemcpy(tls, (*TFts5TokenDataIter)(unsafe.Pointer(pT)).FaMap, a1, libc.Uint32FromInt64((*TFts5TokenDataIter)(unsafe.Pointer(pT)).FnMap*int64(24)))
		}
		Xsqlite3_free(tls, aTmp)
	}
}

// C documentation
//
//	/*
//	** If the segment-iterator passed as the first argument is at EOF, then
//	** set pIter->term to a copy of buffer pTerm.
//	*/
func _fts5TokendataSetTermIfEof(tls *libc.TLS, pIter uintptr, pTerm uintptr) {
	if pIter != 0 && (*(*TFts5SegIter)(unsafe.Pointer(pIter + 72))).FpLeaf == uintptr(0) {
		_sqlite3Fts5BufferSet(tls, (*TFts5Iter)(unsafe.Pointer(pIter)).FpIndex+40, pIter+72+68, (*TFts5Buffer)(unsafe.Pointer(pTerm)).Fn, (*TFts5Buffer)(unsafe.Pointer(pTerm)).Fp)
	}
}

// C documentation
//
//	/*
//	** Trigram tokenizer tokenize routine.
//	*/
func _fts5TriTokenize(tls *libc.TLS, pTok uintptr, pCtx uintptr, unusedFlags int32, pText uintptr, nText int32, __ccgo_fp_xToken uintptr) (r int32) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var aStart [3]int32
	var iCode Tu32
	var iNext, ii, rc int32
	var p, z1, zEof, zIn, zOut, v1 uintptr
	var _ /* aBuf at bp+0 */ [32]int8
	_, _, _, _, _, _, _, _, _, _, _ = aStart, iCode, iNext, ii, p, rc, z1, zEof, zIn, zOut, v1
	p = pTok
	rc = SQLITE_OK
	zOut = bp
	zIn = pText
	if zIn != 0 {
		v1 = zIn + uintptr(nText)
	} else {
		v1 = uintptr(0)
	}
	zEof = v1
	iCode = uint32(0) /* Input offset of each character in aBuf[] */
	_ = unusedFlags
	/* Populate aBuf[] with the characters for the first trigram. */
	ii = 0
	for {
		if !(ii < int32(3)) {
			break
		}
		for cond := true; cond; cond = iCode == uint32(0) {
			aStart[ii] = int32(zIn) - int32(pText)
			if zIn >= zEof {
				return SQLITE_OK
			}
			v1 = zIn
			zIn = zIn + 1
			iCode = uint32(**(**uint8)(__ccgo_up(v1)))
			if iCode >= uint32(0xc0) {
				iCode = uint32(_sqlite3Utf8Trans1[iCode-uint32(0xc0)])
				for zIn < zEof && libc.Int32FromUint8(**(**uint8)(__ccgo_up(zIn)))&int32(0xc0) == int32(0x80) {
					v1 = zIn
					zIn = zIn + 1
					iCode = iCode<<libc.Int32FromInt32(6) + libc.Uint32FromInt32(libc.Int32FromInt32(0x3f)&libc.Int32FromUint8(**(**uint8)(__ccgo_up(v1))))
				}
				if iCode < uint32(0x80) || iCode&uint32(0xFFFFF800) == uint32(0xD800) || iCode&uint32(0xFFFFFFFE) == uint32(0xFFFE) {
					iCode = uint32(0xFFFD)
				}
			}
			if (*TTrigramTokenizer)(unsafe.Pointer(p)).FbFold != 0 {
				iCode = libc.Uint32FromInt32(_sqlite3Fts5UnicodeFold(tls, libc.Int32FromUint32(iCode), (*TTrigramTokenizer)(unsafe.Pointer(p)).FiFoldParam))
			}
		}
		if iCode < uint32(0x00080) {
			v1 = zOut
			zOut = zOut + 1
			**(**int8)(__ccgo_up(v1)) = libc.Int8FromUint8(uint8(iCode & libc.Uint32FromInt32(0xFF)))
		} else {
			if iCode < uint32(0x00800) {
				v1 = zOut
				zOut = zOut + 1
				**(**int8)(__ccgo_up(v1)) = int8(int32(0xC0) + libc.Int32FromUint8(uint8(iCode>>libc.Int32FromInt32(6)&libc.Uint32FromInt32(0x1F))))
				v1 = zOut
				zOut = zOut + 1
				**(**int8)(__ccgo_up(v1)) = int8(int32(0x80) + libc.Int32FromUint8(uint8(iCode&libc.Uint32FromInt32(0x3F))))
			} else {
				if iCode < uint32(0x10000) {
					v1 = zOut
					zOut = zOut + 1
					**(**int8)(__ccgo_up(v1)) = int8(int32(0xE0) + libc.Int32FromUint8(uint8(iCode>>libc.Int32FromInt32(12)&libc.Uint32FromInt32(0x0F))))
					v1 = zOut
					zOut = zOut + 1
					**(**int8)(__ccgo_up(v1)) = int8(int32(0x80) + libc.Int32FromUint8(uint8(iCode>>libc.Int32FromInt32(6)&libc.Uint32FromInt32(0x3F))))
					v1 = zOut
					zOut = zOut + 1
					**(**int8)(__ccgo_up(v1)) = int8(int32(0x80) + libc.Int32FromUint8(uint8(iCode&libc.Uint32FromInt32(0x3F))))
				} else {
					v1 = zOut
					zOut = zOut + 1
					**(**int8)(__ccgo_up(v1)) = int8(int32(0xF0) + libc.Int32FromUint8(uint8(iCode>>libc.Int32FromInt32(18)&libc.Uint32FromInt32(0x07))))
					v1 = zOut
					zOut = zOut + 1
					**(**int8)(__ccgo_up(v1)) = int8(int32(0x80) + libc.Int32FromUint8(uint8(iCode>>libc.Int32FromInt32(12)&libc.Uint32FromInt32(0x3F))))
					v1 = zOut
					zOut = zOut + 1
					**(**int8)(__ccgo_up(v1)) = int8(int32(0x80) + libc.Int32FromUint8(uint8(iCode>>libc.Int32FromInt32(6)&libc.Uint32FromInt32(0x3F))))
					v1 = zOut
					zOut = zOut + 1
					**(**int8)(__ccgo_up(v1)) = int8(int32(0x80) + libc.Int32FromUint8(uint8(iCode&libc.Uint32FromInt32(0x3F))))
				}
			}
		}
		goto _2
	_2:
		;
		ii = ii + 1
	}
	/* At the start of each iteration of this loop:
	 **
	 **  aBuf:      Contains 3 characters. The 3 characters of the next trigram.
	 **  zOut:      Points to the byte following the last character in aBuf.
	 **  aStart[3]: Contains the byte offset in the input text corresponding
	 **             to the start of each of the three characters in the buffer.
	 */
	for int32(1) != 0 {
		/* Read characters from the input up until the first non-diacritic */
		for cond := true; cond; cond = iCode == uint32(0) {
			iNext = int32(zIn) - int32(pText)
			if zIn >= zEof {
				iCode = uint32(0)
				break
			}
			v1 = zIn
			zIn = zIn + 1
			iCode = uint32(**(**uint8)(__ccgo_up(v1)))
			if iCode >= uint32(0xc0) {
				iCode = uint32(_sqlite3Utf8Trans1[iCode-uint32(0xc0)])
				for zIn < zEof && libc.Int32FromUint8(**(**uint8)(__ccgo_up(zIn)))&int32(0xc0) == int32(0x80) {
					v1 = zIn
					zIn = zIn + 1
					iCode = iCode<<libc.Int32FromInt32(6) + libc.Uint32FromInt32(libc.Int32FromInt32(0x3f)&libc.Int32FromUint8(**(**uint8)(__ccgo_up(v1))))
				}
				if iCode < uint32(0x80) || iCode&uint32(0xFFFFF800) == uint32(0xD800) || iCode&uint32(0xFFFFFFFE) == uint32(0xFFFE) {
					iCode = uint32(0xFFFD)
				}
			}
			if (*TTrigramTokenizer)(unsafe.Pointer(p)).FbFold != 0 {
				iCode = libc.Uint32FromInt32(_sqlite3Fts5UnicodeFold(tls, libc.Int32FromUint32(iCode), (*TTrigramTokenizer)(unsafe.Pointer(p)).FiFoldParam))
			}
		}
		/* Pass the current trigram back to fts5 */
		rc = (*(*func(*libc.TLS, uintptr, int32, uintptr, int32, int32, int32) int32)(unsafe.Pointer(&struct{ uintptr }{__ccgo_fp_xToken})))(tls, pCtx, 0, bp, int32(zOut)-t__predefined_ptrdiff_t(bp), aStart[0], iNext)
		if iCode == uint32(0) || rc != SQLITE_OK {
			break
		}
		/* Remove the first character from buffer aBuf[]. Append the character
		 ** with codepoint iCode.  */
		z1 = bp
		v1 = z1
		z1 = z1 + 1
		if libc.Int32FromUint8(libc.Uint8FromInt8(**(**int8)(__ccgo_up(v1)))) >= int32(0xc0) {
			for libc.Int32FromUint8(libc.Uint8FromInt8(**(**int8)(__ccgo_up(z1))))&int32(0xc0) == int32(0x80) {
				z1 = z1 + 1
			}
		}
		libc.Xmemmove(tls, bp, z1, libc.Uint32FromInt32(int32(zOut)-int32(z1)))
		zOut = zOut - uintptr(int32(z1)-t__predefined_ptrdiff_t(bp))
		if iCode < uint32(0x00080) {
			v1 = zOut
			zOut = zOut + 1
			**(**int8)(__ccgo_up(v1)) = libc.Int8FromUint8(uint8(iCode & libc.Uint32FromInt32(0xFF)))
		} else {
			if iCode < uint32(0x00800) {
				v1 = zOut
				zOut = zOut + 1
				**(**int8)(__ccgo_up(v1)) = int8(int32(0xC0) + libc.Int32FromUint8(uint8(iCode>>libc.Int32FromInt32(6)&libc.Uint32FromInt32(0x1F))))
				v1 = zOut
				zOut = zOut + 1
				**(**int8)(__ccgo_up(v1)) = int8(int32(0x80) + libc.Int32FromUint8(uint8(iCode&libc.Uint32FromInt32(0x3F))))
			} else {
				if iCode < uint32(0x10000) {
					v1 = zOut
					zOut = zOut + 1
					**(**int8)(__ccgo_up(v1)) = int8(int32(0xE0) + libc.Int32FromUint8(uint8(iCode>>libc.Int32FromInt32(12)&libc.Uint32FromInt32(0x0F))))
					v1 = zOut
					zOut = zOut + 1
					**(**int8)(__ccgo_up(v1)) = int8(int32(0x80) + libc.Int32FromUint8(uint8(iCode>>libc.Int32FromInt32(6)&libc.Uint32FromInt32(0x3F))))
					v1 = zOut
					zOut = zOut + 1
					**(**int8)(__ccgo_up(v1)) = int8(int32(0x80) + libc.Int32FromUint8(uint8(iCode&libc.Uint32FromInt32(0x3F))))
				} else {
					v1 = zOut
					zOut = zOut + 1
					**(**int8)(__ccgo_up(v1)) = int8(int32(0xF0) + libc.Int32FromUint8(uint8(iCode>>libc.Int32FromInt32(18)&libc.Uint32FromInt32(0x07))))
					v1 = zOut
					zOut = zOut + 1
					**(**int8)(__ccgo_up(v1)) = int8(int32(0x80) + libc.Int32FromUint8(uint8(iCode>>libc.Int32FromInt32(12)&libc.Uint32FromInt32(0x3F))))
					v1 = zOut
					zOut = zOut + 1
					**(**int8)(__ccgo_up(v1)) = int8(int32(0x80) + libc.Int32FromUint8(uint8(iCode>>libc.Int32FromInt32(6)&libc.Uint32FromInt32(0x3F))))
					v1 = zOut
					zOut = zOut + 1
					**(**int8)(__ccgo_up(v1)) = int8(int32(0x80) + libc.Int32FromUint8(uint8(iCode&libc.Uint32FromInt32(0x3F))))
				}
			}
		}
		/* Update the aStart[] array */
		aStart[0] = aStart[int32(1)]
		aStart[int32(1)] = aStart[int32(2)]
		aStart[int32(2)] = iNext
	}
	return rc
}

// C documentation
//
//	/*
//	** Iterator pIter was used to iterate through the input segments of on an
//	** incremental merge operation. This function is called if the incremental
//	** merge step has finished but the input has not been completely exhausted.
//	*/
func _fts5TrimSegments(tls *libc.TLS, p uintptr, pIter uintptr) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var i, iId, iOff, nDiff int32
	var iLeafRowid Ti64
	var pData, pSeg uintptr
	var _ /* aHdr at bp+12 */ [4]Tu8
	var _ /* buf at bp+0 */ TFts5Buffer
	_, _, _, _, _, _, _ = i, iId, iLeafRowid, iOff, nDiff, pData, pSeg
	libc.Xmemset(tls, bp, 0, uint32(12))
	i = 0
	for {
		if !(i < (*TFts5Iter)(unsafe.Pointer(pIter)).FnSeg && (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK) {
			break
		}
		pSeg = pIter + 72 + uintptr(i)*96
		if (*TFts5SegIter)(unsafe.Pointer(pSeg)).FpSeg == uintptr(0) {
			/* no-op */
		} else {
			if (*TFts5SegIter)(unsafe.Pointer(pSeg)).FpLeaf == uintptr(0) {
				/* All keys from this input segment have been transfered to the output.
				 ** Set both the first and last page-numbers to 0 to indicate that the
				 ** segment is now empty. */
				(*TFts5StructureSegment)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pSeg)).FpSeg)).FpgnoLast = 0
				(*TFts5StructureSegment)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pSeg)).FpSeg)).FpgnoFirst = 0
			} else {
				iOff = (*TFts5SegIter)(unsafe.Pointer(pSeg)).FiTermLeafOffset
				iId = (*TFts5StructureSegment)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pSeg)).FpSeg)).FiSegid
				**(**[4]Tu8)(__ccgo_up(bp + 12)) = [4]Tu8{}
				iLeafRowid = int64(iId)<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B)+libc.Int32FromInt32(FTS5_DATA_DLI_B)) + int64(libc.Int32FromInt32(0))<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B)) + int64(libc.Int32FromInt32(0))<<libc.Int32FromInt32(FTS5_DATA_PAGE_B) + int64((*TFts5SegIter)(unsafe.Pointer(pSeg)).FiTermLeafPgno)
				pData = _fts5LeafRead(tls, p, iLeafRowid)
				if pData != 0 {
					if iOff > (*TFts5Data)(unsafe.Pointer(pData)).FszLeaf {
						/* This can occur if the pages that the segments occupy overlap - if
						 ** a single page has been assigned to more than one segment. In
						 ** this case a prior iteration of this loop may have corrupted the
						 ** segment currently being trimmed.  */
						_fts5IndexCorruptRowid(tls, p, iLeafRowid)
					} else {
						_sqlite3Fts5BufferZero(tls, bp)
						if !(libc.Uint32FromInt32((*TFts5Buffer)(unsafe.Pointer(bp)).Fn)+libc.Uint32FromInt32((*TFts5Data)(unsafe.Pointer(pData)).Fnn) <= libc.Uint32FromInt32((*TFts5Buffer)(unsafe.Pointer(bp)).FnSpace)) {
							_sqlite3Fts5BufferSize(tls, p+40, bp, libc.Uint32FromInt32((*TFts5Data)(unsafe.Pointer(pData)).Fnn+(*TFts5Buffer)(unsafe.Pointer(bp)).Fn))
						}
						_sqlite3Fts5BufferAppendBlob(tls, p+40, bp, uint32(4), bp+12)
						_sqlite3Fts5BufferAppendVarint(tls, p+40, bp, int64((*TFts5SegIter)(unsafe.Pointer(pSeg)).Fterm.Fn))
						_sqlite3Fts5BufferAppendBlob(tls, p+40, bp, libc.Uint32FromInt32((*TFts5SegIter)(unsafe.Pointer(pSeg)).Fterm.Fn), (*TFts5SegIter)(unsafe.Pointer(pSeg)).Fterm.Fp)
						_sqlite3Fts5BufferAppendBlob(tls, p+40, bp, libc.Uint32FromInt32((*TFts5Data)(unsafe.Pointer(pData)).FszLeaf-iOff), (*TFts5Data)(unsafe.Pointer(pData)).Fp+uintptr(iOff))
						if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
							/* Set the szLeaf field */
							_fts5PutU16(tls, (**(**TFts5Buffer)(__ccgo_up(bp))).Fp+2, libc.Uint16FromInt32((**(**TFts5Buffer)(__ccgo_up(bp))).Fn))
						}
						/* Set up the new page-index array */
						_sqlite3Fts5BufferAppendVarint(tls, p+40, bp, libc.Int64FromInt32(4))
						if (*TFts5SegIter)(unsafe.Pointer(pSeg)).FiLeafPgno == (*TFts5SegIter)(unsafe.Pointer(pSeg)).FiTermLeafPgno && (*TFts5SegIter)(unsafe.Pointer(pSeg)).FiEndofDoclist < (*TFts5Data)(unsafe.Pointer(pData)).FszLeaf && (*TFts5SegIter)(unsafe.Pointer(pSeg)).FiPgidxOff <= (*TFts5Data)(unsafe.Pointer(pData)).Fnn {
							nDiff = (*TFts5Data)(unsafe.Pointer(pData)).FszLeaf - (*TFts5SegIter)(unsafe.Pointer(pSeg)).FiEndofDoclist
							_sqlite3Fts5BufferAppendVarint(tls, p+40, bp, int64((**(**TFts5Buffer)(__ccgo_up(bp))).Fn)-int64(1)-int64(nDiff)-int64(4))
							_sqlite3Fts5BufferAppendBlob(tls, p+40, bp, libc.Uint32FromInt32((*TFts5Data)(unsafe.Pointer(pData)).Fnn-(*TFts5SegIter)(unsafe.Pointer(pSeg)).FiPgidxOff), (*TFts5Data)(unsafe.Pointer(pData)).Fp+uintptr((*TFts5SegIter)(unsafe.Pointer(pSeg)).FiPgidxOff))
						}
						(*TFts5StructureSegment)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pSeg)).FpSeg)).FpgnoFirst = (*TFts5SegIter)(unsafe.Pointer(pSeg)).FiTermLeafPgno
						_fts5DataDelete(tls, p, int64(iId)<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B)+libc.Int32FromInt32(FTS5_DATA_DLI_B))+int64(libc.Int32FromInt32(0))<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B))+int64(libc.Int32FromInt32(0))<<libc.Int32FromInt32(FTS5_DATA_PAGE_B)+int64(libc.Int32FromInt32(1)), iLeafRowid)
						_fts5DataWrite(tls, p, iLeafRowid, (**(**TFts5Buffer)(__ccgo_up(bp))).Fp, (**(**TFts5Buffer)(__ccgo_up(bp))).Fn)
					}
					_fts5DataRelease(tls, pData)
				}
			}
		}
		goto _1
	_1:
		;
		i = i + 1
	}
	_sqlite3Fts5BufferFree(tls, bp)
}

// C documentation
//
//	/*
//	** Set the FTS5CSR_REQUIRE_RESEEK flag on all FTS5_PLAN_MATCH cursors
//	** open on table pTab.
//	*/
func _fts5TripCursors(tls *libc.TLS, pTab uintptr) {
	var pCsr uintptr
	_ = pCsr
	pCsr = (*TFts5Global)(unsafe.Pointer((*TFts5FullTable)(unsafe.Pointer(pTab)).FpGlobal)).FpCsr
	for {
		if !(pCsr != 0) {
			break
		}
		if (*TFts5Cursor)(unsafe.Pointer(pCsr)).FePlan == int32(FTS5_PLAN_MATCH) && (*TFts5Cursor)(unsafe.Pointer(pCsr)).Fbase.FpVtab == pTab {
			**(**int32)(__ccgo_up(pCsr + 56)) |= int32(FTS5CSR_REQUIRE_RESEEK)
		}
		goto _1
	_1:
		;
		pCsr = (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpNext
	}
}

func _fts5UnicodeTokenize(tls *libc.TLS, pTokenizer uintptr, pCtx uintptr, iUnused int32, pText uintptr, nText int32, __ccgo_fp_xToken uintptr) (r int32) {
	var a, aFold, p, pEnd, zCsr, zOut, zTerm, v3 uintptr
	var iCode Tu32
	var ie, is, nFold, rc, v7 int32
	_, _, _, _, _, _, _, _, _, _, _, _, _, _ = a, aFold, iCode, ie, is, nFold, p, pEnd, rc, zCsr, zOut, zTerm, v3, v7
	p = pTokenizer
	rc = SQLITE_OK
	a = p
	zTerm = pText + uintptr(nText)
	zCsr = pText
	/* Output buffer */
	aFold = (*TUnicode61Tokenizer)(unsafe.Pointer(p)).FaFold
	nFold = (*TUnicode61Tokenizer)(unsafe.Pointer(p)).FnFold
	pEnd = aFold + uintptr(nFold-int32(6))
	_ = iUnused
	/* Each iteration of this loop gobbles up a contiguous run of separators,
	 ** then the next token.  */
_2:
	;
	if !(rc == SQLITE_OK) {
		goto _1
	} /* non-ASCII codepoint read from input */
	zOut = aFold
	/* Skip any separator characters. */
	for int32(1) != 0 {
		if zCsr >= zTerm {
			goto tokenize_done
		}
		if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zCsr)))&int32(0x80) != 0 {
			/* A character outside of the ascii range. Skip past it if it is
			 ** a separator character. Or break out of the loop if it is not. */
			is = int32(zCsr) - int32(pText)
			v3 = zCsr
			zCsr = zCsr + 1
			iCode = uint32(**(**uint8)(__ccgo_up(v3)))
			if iCode >= uint32(0xc0) {
				iCode = uint32(_sqlite3Utf8Trans1[iCode-uint32(0xc0)])
				for zCsr < zTerm && libc.Int32FromUint8(**(**uint8)(__ccgo_up(zCsr)))&int32(0xc0) == int32(0x80) {
					v3 = zCsr
					zCsr = zCsr + 1
					iCode = iCode<<libc.Int32FromInt32(6) + libc.Uint32FromInt32(libc.Int32FromInt32(0x3f)&libc.Int32FromUint8(**(**uint8)(__ccgo_up(v3))))
				}
				if iCode < uint32(0x80) || iCode&uint32(0xFFFFF800) == uint32(0xD800) || iCode&uint32(0xFFFFFFFE) == uint32(0xFFFE) {
					iCode = uint32(0xFFFD)
				}
			}
			if _fts5UnicodeIsAlnum(tls, p, libc.Int32FromUint32(iCode)) != 0 {
				goto non_ascii_tokenchar
			}
		} else {
			if **(**uint8)(__ccgo_up(a + uintptr(**(**uint8)(__ccgo_up(zCsr))))) != 0 {
				is = int32(zCsr) - int32(pText)
				goto ascii_tokenchar
			}
			zCsr = zCsr + 1
		}
	}
	/* Run through the tokenchars. Fold them into the output buffer along
	 ** the way.  */
_6:
	;
	if !(zCsr < zTerm) {
		goto _5
	}
	/* Grow the output buffer so that there is sufficient space to fit the
	 ** largest possible utf-8 character.  */
	if zOut > pEnd {
		aFold = Xsqlite3_malloc64(tls, libc.Uint64FromInt64(int64(nFold)*int64(2)))
		if aFold == uintptr(0) {
			rc = int32(SQLITE_NOMEM)
			goto tokenize_done
		}
		zOut = aFold + uintptr(int32(zOut)-int32((*TUnicode61Tokenizer)(unsafe.Pointer(p)).FaFold))
		libc.Xmemcpy(tls, aFold, (*TUnicode61Tokenizer)(unsafe.Pointer(p)).FaFold, libc.Uint32FromInt32(nFold))
		Xsqlite3_free(tls, (*TUnicode61Tokenizer)(unsafe.Pointer(p)).FaFold)
		(*TUnicode61Tokenizer)(unsafe.Pointer(p)).FaFold = aFold
		v7 = nFold * libc.Int32FromInt32(2)
		nFold = v7
		(*TUnicode61Tokenizer)(unsafe.Pointer(p)).FnFold = v7
		pEnd = aFold + uintptr(nFold-int32(6))
	}
	if !(libc.Int32FromUint8(**(**uint8)(__ccgo_up(zCsr)))&int32(0x80) != 0) {
		goto _8
	}
	/* An non-ascii-range character. Fold it into the output buffer if
	 ** it is a token character, or break out of the loop if it is not. */
	v3 = zCsr
	zCsr = zCsr + 1
	iCode = uint32(**(**uint8)(__ccgo_up(v3)))
	if iCode >= uint32(0xc0) {
		iCode = uint32(_sqlite3Utf8Trans1[iCode-uint32(0xc0)])
		for zCsr < zTerm && libc.Int32FromUint8(**(**uint8)(__ccgo_up(zCsr)))&int32(0xc0) == int32(0x80) {
			v3 = zCsr
			zCsr = zCsr + 1
			iCode = iCode<<libc.Int32FromInt32(6) + libc.Uint32FromInt32(libc.Int32FromInt32(0x3f)&libc.Int32FromUint8(**(**uint8)(__ccgo_up(v3))))
		}
		if iCode < uint32(0x80) || iCode&uint32(0xFFFFF800) == uint32(0xD800) || iCode&uint32(0xFFFFFFFE) == uint32(0xFFFE) {
			iCode = uint32(0xFFFD)
		}
	}
	if !(_fts5UnicodeIsAlnum(tls, p, libc.Int32FromUint32(iCode)) != 0 || _sqlite3Fts5UnicodeIsdiacritic(tls, libc.Int32FromUint32(iCode)) != 0) {
		goto _12
	}
	goto non_ascii_tokenchar
non_ascii_tokenchar:
	;
	iCode = libc.Uint32FromInt32(_sqlite3Fts5UnicodeFold(tls, libc.Int32FromUint32(iCode), (*TUnicode61Tokenizer)(unsafe.Pointer(p)).FeRemoveDiacritic))
	if iCode != 0 {
		if iCode < uint32(0x00080) {
			v3 = zOut
			zOut = zOut + 1
			**(**int8)(__ccgo_up(v3)) = libc.Int8FromUint8(uint8(iCode & libc.Uint32FromInt32(0xFF)))
		} else {
			if iCode < uint32(0x00800) {
				v3 = zOut
				zOut = zOut + 1
				**(**int8)(__ccgo_up(v3)) = int8(int32(0xC0) + libc.Int32FromUint8(uint8(iCode>>libc.Int32FromInt32(6)&libc.Uint32FromInt32(0x1F))))
				v3 = zOut
				zOut = zOut + 1
				**(**int8)(__ccgo_up(v3)) = int8(int32(0x80) + libc.Int32FromUint8(uint8(iCode&libc.Uint32FromInt32(0x3F))))
			} else {
				if iCode < uint32(0x10000) {
					v3 = zOut
					zOut = zOut + 1
					**(**int8)(__ccgo_up(v3)) = int8(int32(0xE0) + libc.Int32FromUint8(uint8(iCode>>libc.Int32FromInt32(12)&libc.Uint32FromInt32(0x0F))))
					v3 = zOut
					zOut = zOut + 1
					**(**int8)(__ccgo_up(v3)) = int8(int32(0x80) + libc.Int32FromUint8(uint8(iCode>>libc.Int32FromInt32(6)&libc.Uint32FromInt32(0x3F))))
					v3 = zOut
					zOut = zOut + 1
					**(**int8)(__ccgo_up(v3)) = int8(int32(0x80) + libc.Int32FromUint8(uint8(iCode&libc.Uint32FromInt32(0x3F))))
				} else {
					v3 = zOut
					zOut = zOut + 1
					**(**int8)(__ccgo_up(v3)) = int8(int32(0xF0) + libc.Int32FromUint8(uint8(iCode>>libc.Int32FromInt32(18)&libc.Uint32FromInt32(0x07))))
					v3 = zOut
					zOut = zOut + 1
					**(**int8)(__ccgo_up(v3)) = int8(int32(0x80) + libc.Int32FromUint8(uint8(iCode>>libc.Int32FromInt32(12)&libc.Uint32FromInt32(0x3F))))
					v3 = zOut
					zOut = zOut + 1
					**(**int8)(__ccgo_up(v3)) = int8(int32(0x80) + libc.Int32FromUint8(uint8(iCode>>libc.Int32FromInt32(6)&libc.Uint32FromInt32(0x3F))))
					v3 = zOut
					zOut = zOut + 1
					**(**int8)(__ccgo_up(v3)) = int8(int32(0x80) + libc.Int32FromUint8(uint8(iCode&libc.Uint32FromInt32(0x3F))))
				}
			}
		}
	}
	goto _13
_12:
	;
	goto _5
_13:
	;
	goto _9
_8:
	;
	if !(libc.Int32FromUint8(**(**uint8)(__ccgo_up(a + uintptr(**(**uint8)(__ccgo_up(zCsr)))))) == 0) {
		goto _24
	}
	/* An ascii-range separator character. End of token. */
	goto _5
	goto _25
_24:
	;
	goto ascii_tokenchar
ascii_tokenchar:
	;
	if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zCsr))) >= int32('A') && libc.Int32FromUint8(**(**uint8)(__ccgo_up(zCsr))) <= int32('Z') {
		v3 = zOut
		zOut = zOut + 1
		**(**int8)(__ccgo_up(v3)) = int8(libc.Int32FromUint8(**(**uint8)(__ccgo_up(zCsr))) + int32(32))
	} else {
		v3 = zOut
		zOut = zOut + 1
		**(**int8)(__ccgo_up(v3)) = libc.Int8FromUint8(**(**uint8)(__ccgo_up(zCsr)))
	}
	zCsr = zCsr + 1
_25:
	;
_9:
	;
	ie = int32(zCsr) - int32(pText)
	goto _6
_5:
	;
	/* Invoke the token callback */
	rc = (*(*func(*libc.TLS, uintptr, int32, uintptr, int32, int32, int32) int32)(unsafe.Pointer(&struct{ uintptr }{__ccgo_fp_xToken})))(tls, pCtx, 0, aFold, int32(zOut)-int32(aFold), is, ie)
	goto _2
_1:
	;
	goto tokenize_done
tokenize_done:
	;
	if rc == int32(SQLITE_DONE) {
		rc = SQLITE_OK
	}
	return rc
}

/**************************************************************************
** Start of porter stemmer implementation.
 */

/* Any tokens larger than this (in bytes) are passed through without
** stemming. */

// C documentation
//
//	/*
//	** Iterate through a range of entries in the FTS index, invoking the xVisit
//	** callback for each of them.
//	**
//	** Parameter pToken points to an nToken buffer containing an FTS index term
//	** (i.e. a document term with the preceding 1 byte index identifier -
//	** FTS5_MAIN_PREFIX or similar). If bPrefix is true, then the call visits
//	** all entries for terms that have pToken/nToken as a prefix. If bPrefix
//	** is false, then only entries with pToken/nToken as the entire key are
//	** visited.
//	**
//	** If the current table is a tokendata=1 table, then if bPrefix is true then
//	** each index term is treated separately. However, if bPrefix is false, then
//	** all index terms corresponding to pToken/nToken are collapsed into a single
//	** term before the callback is invoked.
//	**
//	** The callback invoked for each entry visited is specified by paramter xVisit.
//	** Each time it is invoked, it is passed a pointer to the Fts5Index object,
//	** a copy of the 7th paramter to this function (pCtx) and a pointer to the
//	** iterator that indicates the current entry. If the current entry is the
//	** first with a new term (i.e. different from that of the previous entry,
//	** including the very first term), then the final two parameters are passed
//	** a pointer to the term and its size in bytes, respectively. If the current
//	** entry is not the first associated with its term, these two parameters
//	** are passed 0.
//	**
//	** If parameter pColset is not NULL, then it is used to filter entries before
//	** the callback is invoked.
//	*/
func _fts5VisitEntries(tls *libc.TLS, p uintptr, pColset uintptr, pToken uintptr, nToken int32, bPrefix int32, __ccgo_fp_xVisit uintptr, pCtx uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var flags, nNew, v1 int32
	var pNew, pSeg, pStruct uintptr
	var _ /* bNewTerm at bp+4 */ int32
	var _ /* p1 at bp+0 */ uintptr
	_, _, _, _, _, _ = flags, nNew, pNew, pSeg, pStruct, v1
	if bPrefix != 0 {
		v1 = int32(FTS5INDEX_QUERY_SCAN)
	} else {
		v1 = 0
	}
	flags = v1 | int32(FTS5INDEX_QUERY_SKIPEMPTY) | int32(FTS5INDEX_QUERY_NOOUTPUT)
	**(**uintptr)(__ccgo_up(bp)) = uintptr(0) /* Iterator used to gather data from index */
	**(**int32)(__ccgo_up(bp + 4)) = int32(1)
	pStruct = _fts5StructureRead(tls, p)
	_fts5MultiIterNew(tls, p, pStruct, flags, pColset, pToken, nToken, -int32(1), 0, bp)
	_fts5IterSetOutputCb(tls, p+40, **(**uintptr)(__ccgo_up(bp)))
	for {
		if !(_fts5MultiIterEof(tls, p, **(**uintptr)(__ccgo_up(bp))) == 0) {
			break
		}
		pSeg = **(**uintptr)(__ccgo_up(bp)) + 72 + uintptr((**(**TFts5CResult)(__ccgo_up((*TFts5Iter)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FaFirst + 1*4))).FiFirst)*96
		nNew = 0
		pNew = uintptr(0)
		(*(*func(*libc.TLS, uintptr, uintptr))(unsafe.Pointer(&struct{ uintptr }{(*TFts5Iter)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FxSetOutputs})))(tls, **(**uintptr)(__ccgo_up(bp)), pSeg)
		if (*TFts5Index)(unsafe.Pointer(p)).Frc != 0 {
			break
		}
		if **(**int32)(__ccgo_up(bp + 4)) != 0 {
			nNew = (*TFts5SegIter)(unsafe.Pointer(pSeg)).Fterm.Fn
			pNew = (*TFts5SegIter)(unsafe.Pointer(pSeg)).Fterm.Fp
			if nNew < nToken || libc.Xmemcmp(tls, pToken, pNew, libc.Uint32FromInt32(nToken)) != 0 {
				break
			}
		}
		(*(*func(*libc.TLS, uintptr, uintptr, uintptr, uintptr, int32))(unsafe.Pointer(&struct{ uintptr }{__ccgo_fp_xVisit})))(tls, p, pCtx, **(**uintptr)(__ccgo_up(bp)), pNew, nNew)
		goto _2
	_2:
		;
		_fts5MultiIterNext2(tls, p, **(**uintptr)(__ccgo_up(bp)), bp+4)
	}
	_fts5MultiIterFree(tls, **(**uintptr)(__ccgo_up(bp)))
	_fts5StructureRelease(tls, pStruct)
	return (*TFts5Index)(unsafe.Pointer(p)).Frc
}

/* Size in bytes of an Fts5TokenDataIter object holding up to N iterators */

func _fts5VocabInstanceNext(tls *libc.TLS, pCsr uintptr) (r int32) {
	var eDetail, rc int32
	var pIter, po, pp uintptr
	_, _, _, _, _ = eDetail, pIter, po, pp, rc
	eDetail = (*TFts5Config)(unsafe.Pointer((*TFts5Table)(unsafe.Pointer((*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FpFts5)).FpConfig)).FeDetail
	rc = SQLITE_OK
	pIter = (*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FpIter
	pp = pCsr + 68
	po = pCsr + 76
	for eDetail == int32(FTS5_DETAIL_NONE) || _sqlite3Fts5PoslistNext64(tls, (*TFts5IndexIter)(unsafe.Pointer(pIter)).FpData, (*TFts5IndexIter)(unsafe.Pointer(pIter)).FnData, po, pp) != 0 {
		(*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FiInstPos = 0
		(*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FiInstOff = 0
		rc = _sqlite3Fts5IterNextScan(tls, (*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FpIter)
		if rc == SQLITE_OK {
			rc = _fts5VocabInstanceNewTerm(tls, pCsr)
			if (*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FbEof != 0 || eDetail == int32(FTS5_DETAIL_NONE) {
				break
			}
		}
		if rc != 0 {
			(*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FbEof = int32(1)
			break
		}
	}
	return rc
}

func _fts5WriteAppendPoslistData(tls *libc.TLS, p uintptr, pWriter uintptr, aData uintptr, nData int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var a, pPage uintptr
	var n, nCopy, nReq int32
	var _ /* dummy at bp+0 */ Ti64
	_, _, _, _, _ = a, n, nCopy, nReq, pPage
	pPage = pWriter + 4
	a = aData
	n = nData
	for (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK && (*TFts5PageWriter)(unsafe.Pointer(pPage)).Fbuf.Fn+(*TFts5PageWriter)(unsafe.Pointer(pPage)).Fpgidx.Fn+n >= (*TFts5Config)(unsafe.Pointer((*TFts5Index)(unsafe.Pointer(p)).FpConfig)).Fpgsz {
		nReq = (*TFts5Config)(unsafe.Pointer((*TFts5Index)(unsafe.Pointer(p)).FpConfig)).Fpgsz - (*TFts5PageWriter)(unsafe.Pointer(pPage)).Fbuf.Fn - (*TFts5PageWriter)(unsafe.Pointer(pPage)).Fpgidx.Fn
		nCopy = 0
		for nCopy < nReq {
			nCopy = nCopy + libc.Int32FromUint8(_sqlite3Fts5GetVarint(tls, a+uintptr(nCopy), bp))
		}
		_sqlite3Fts5BufferAppendBlob(tls, p+40, pPage+8, libc.Uint32FromInt32(nCopy), a)
		a = a + uintptr(nCopy)
		n = n - nCopy
		_fts5WriteFlushLeaf(tls, p, pWriter)
	}
	if n > 0 {
		_sqlite3Fts5BufferAppendBlob(tls, p+40, pPage+8, libc.Uint32FromInt32(n), a)
	}
}

// C documentation
//
//	/*
//	** Append a rowid and position-list size field to the writers output.
//	*/
func _fts5WriteAppendRowid(tls *libc.TLS, p uintptr, pWriter uintptr, iRowid Ti64) {
	var pPage uintptr
	_ = pPage
	if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
		pPage = pWriter + 4
		if (*TFts5PageWriter)(unsafe.Pointer(pPage)).Fbuf.Fn+(*TFts5PageWriter)(unsafe.Pointer(pPage)).Fpgidx.Fn >= (*TFts5Config)(unsafe.Pointer((*TFts5Index)(unsafe.Pointer(p)).FpConfig)).Fpgsz {
			_fts5WriteFlushLeaf(tls, p, pWriter)
		}
		/* If this is to be the first rowid written to the page, set the
		 ** rowid-pointer in the page-header. Also append a value to the dlidx
		 ** buffer, in case a doclist-index is required.  */
		if (*TFts5SegWriter)(unsafe.Pointer(pWriter)).FbFirstRowidInPage != 0 {
			_fts5PutU16(tls, (*TFts5PageWriter)(unsafe.Pointer(pPage)).Fbuf.Fp, libc.Uint16FromInt32((*TFts5PageWriter)(unsafe.Pointer(pPage)).Fbuf.Fn))
			_fts5WriteDlidxAppend(tls, p, pWriter, iRowid)
		}
		/* Write the rowid. */
		if (*TFts5SegWriter)(unsafe.Pointer(pWriter)).FbFirstRowidInDoclist != 0 || (*TFts5SegWriter)(unsafe.Pointer(pWriter)).FbFirstRowidInPage != 0 {
			_sqlite3Fts5BufferAppendVarint(tls, p+40, pPage+8, iRowid)
		} else {
			_sqlite3Fts5BufferAppendVarint(tls, p+40, pPage+8, libc.Int64FromUint64(libc.Uint64FromInt64(libc.Int64FromUint64(libc.Uint64FromInt64(iRowid)))-libc.Uint64FromInt64((*TFts5SegWriter)(unsafe.Pointer(pWriter)).FiPrevRowid)))
		}
		(*TFts5SegWriter)(unsafe.Pointer(pWriter)).FiPrevRowid = iRowid
		(*TFts5SegWriter)(unsafe.Pointer(pWriter)).FbFirstRowidInDoclist = uint8(0)
		(*TFts5SegWriter)(unsafe.Pointer(pWriter)).FbFirstRowidInPage = uint8(0)
	}
}

// C documentation
//
//	/*
//	** Append term pTerm/nTerm to the segment being written by the writer passed
//	** as the second argument.
//	**
//	** If an error occurs, set the Fts5Index.rc error code. If an error has
//	** already occurred, this function is a no-op.
//	*/
func _fts5WriteAppendTerm(tls *libc.TLS, p uintptr, pWriter uintptr, nTerm int32, pTerm uintptr) {
	var n, nMin, nPrefix, v1 int32
	var pPage, pPgidx uintptr
	_, _, _, _, _, _ = n, nMin, nPrefix, pPage, pPgidx, v1 /* Bytes of prefix compression for term */
	pPage = pWriter + 4
	pPgidx = pWriter + 4 + 20
	if (*TFts5PageWriter)(unsafe.Pointer(pPage)).Fterm.Fn < nTerm {
		v1 = (*TFts5PageWriter)(unsafe.Pointer(pPage)).Fterm.Fn
	} else {
		v1 = nTerm
	}
	nMin = v1
	/* If the current leaf page is full, flush it to disk. */
	if (*TFts5PageWriter)(unsafe.Pointer(pPage)).Fbuf.Fn+(*TFts5Buffer)(unsafe.Pointer(pPgidx)).Fn+nTerm+int32(2) >= (*TFts5Config)(unsafe.Pointer((*TFts5Index)(unsafe.Pointer(p)).FpConfig)).Fpgsz {
		if (*TFts5PageWriter)(unsafe.Pointer(pPage)).Fbuf.Fn > int32(4) {
			_fts5WriteFlushLeaf(tls, p, pWriter)
			if (*TFts5Index)(unsafe.Pointer(p)).Frc != SQLITE_OK {
				return
			}
		}
		if !(libc.Uint32FromInt32((*TFts5Buffer)(unsafe.Pointer(pPage+8)).Fn)+libc.Uint32FromInt32(nTerm+libc.Int32FromInt32(FTS5_DATA_PADDING)) <= libc.Uint32FromInt32((*TFts5Buffer)(unsafe.Pointer(pPage+8)).FnSpace)) {
			_sqlite3Fts5BufferSize(tls, p+40, pPage+8, libc.Uint32FromInt32(nTerm+int32(FTS5_DATA_PADDING)+(*TFts5Buffer)(unsafe.Pointer(pPage+8)).Fn))
		}
	}
	/* TODO1: Updating pgidx here. */
	**(**int32)(__ccgo_up(pPgidx + 4)) += _sqlite3Fts5PutVarint(tls, (*TFts5Buffer)(unsafe.Pointer(pPgidx)).Fp+uintptr((*TFts5Buffer)(unsafe.Pointer(pPgidx)).Fn), libc.Uint64FromInt32((*TFts5PageWriter)(unsafe.Pointer(pPage)).Fbuf.Fn-(*TFts5PageWriter)(unsafe.Pointer(pPage)).FiPrevPgidx))
	(*TFts5PageWriter)(unsafe.Pointer(pPage)).FiPrevPgidx = (*TFts5PageWriter)(unsafe.Pointer(pPage)).Fbuf.Fn
	if (*TFts5SegWriter)(unsafe.Pointer(pWriter)).FbFirstTermInPage != 0 {
		nPrefix = 0
		if (*TFts5PageWriter)(unsafe.Pointer(pPage)).Fpgno != int32(1) {
			/* This is the first term on a leaf that is not the leftmost leaf in
			 ** the segment b-tree. In this case it is necessary to add a term to
			 ** the b-tree hierarchy that is (a) larger than the largest term
			 ** already written to the segment and (b) smaller than or equal to
			 ** this term. In other words, a prefix of (pTerm/nTerm) that is one
			 ** byte longer than the longest prefix (pTerm/nTerm) shares with the
			 ** previous term.
			 **
			 ** Usually, the previous term is available in pPage->term. The exception
			 ** is if this is the first term written in an incremental-merge step.
			 ** In this case the previous term is not available, so just write a
			 ** copy of (pTerm/nTerm) into the parent node. This is slightly
			 ** inefficient, but still correct.  */
			n = nTerm
			if (*TFts5PageWriter)(unsafe.Pointer(pPage)).Fterm.Fn != 0 {
				n = int32(1) + _fts5PrefixCompress(tls, nMin, (*TFts5PageWriter)(unsafe.Pointer(pPage)).Fterm.Fp, pTerm)
			}
			_fts5WriteBtreeTerm(tls, p, pWriter, n, pTerm)
			if (*TFts5Index)(unsafe.Pointer(p)).Frc != SQLITE_OK {
				return
			}
			pPage = pWriter + 4
		}
	} else {
		nPrefix = _fts5PrefixCompress(tls, nMin, (*TFts5PageWriter)(unsafe.Pointer(pPage)).Fterm.Fp, pTerm)
		_sqlite3Fts5BufferAppendVarint(tls, p+40, pPage+8, int64(nPrefix))
	}
	/* Append the number of bytes of new data, then the term data itself
	 ** to the page. */
	_sqlite3Fts5BufferAppendVarint(tls, p+40, pPage+8, int64(nTerm)-int64(nPrefix))
	_sqlite3Fts5BufferAppendBlob(tls, p+40, pPage+8, libc.Uint32FromInt32(nTerm-nPrefix), pTerm+uintptr(nPrefix))
	/* Update the Fts5PageWriter.term field. */
	_sqlite3Fts5BufferSet(tls, p+40, pPage+32, nTerm, pTerm)
	(*TFts5SegWriter)(unsafe.Pointer(pWriter)).FbFirstTermInPage = uint8(0)
	(*TFts5SegWriter)(unsafe.Pointer(pWriter)).FbFirstRowidInPage = uint8(0)
	(*TFts5SegWriter)(unsafe.Pointer(pWriter)).FbFirstRowidInDoclist = uint8(1)
	(**(**TFts5DlidxWriter)(__ccgo_up((*TFts5SegWriter)(unsafe.Pointer(pWriter)).FaDlidx))).Fpgno = (*TFts5PageWriter)(unsafe.Pointer(pPage)).Fpgno
}

// C documentation
//
//	/*
//	** This function is called when flushing a leaf page that contains no
//	** terms at all to disk.
//	*/
func _fts5WriteBtreeNoTerm(tls *libc.TLS, p uintptr, pWriter uintptr) {
	var pDlidx uintptr
	_ = pDlidx
	/* If there were no rowids on the leaf page either and the doclist-index
	 ** has already been started, append an 0x00 byte to it.  */
	if (*TFts5SegWriter)(unsafe.Pointer(pWriter)).FbFirstRowidInPage != 0 && (**(**TFts5DlidxWriter)(__ccgo_up((*TFts5SegWriter)(unsafe.Pointer(pWriter)).FaDlidx))).Fbuf.Fn > 0 {
		pDlidx = (*TFts5SegWriter)(unsafe.Pointer(pWriter)).FaDlidx
		_sqlite3Fts5BufferAppendVarint(tls, p+40, pDlidx+16, 0)
	}
	/* Increment the "number of sequential leaves without a term" counter. */
	(*TFts5SegWriter)(unsafe.Pointer(pWriter)).FnEmpty = (*TFts5SegWriter)(unsafe.Pointer(pWriter)).FnEmpty + 1
}

// C documentation
//
//	/*
//	** This is called once for each leaf page except the first that contains
//	** at least one term. Argument (nTerm/pTerm) is the split-key - a term that
//	** is larger than all terms written to earlier leaves, and equal to or
//	** smaller than the first term on the new leaf.
//	**
//	** If an error occurs, an error code is left in Fts5Index.rc. If an error
//	** has already occurred when this function is called, it is a no-op.
//	*/
func _fts5WriteBtreeTerm(tls *libc.TLS, p uintptr, pWriter uintptr, nTerm int32, pTerm uintptr) {
	_fts5WriteFlushBtree(tls, p, pWriter)
	if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
		_sqlite3Fts5BufferSet(tls, p+40, pWriter+76, nTerm, pTerm)
		(*TFts5SegWriter)(unsafe.Pointer(pWriter)).FiBtPage = (*TFts5SegWriter)(unsafe.Pointer(pWriter)).Fwriter.Fpgno
	}
}

// C documentation
//
//	/*
//	** Rowid iRowid has just been appended to the current leaf page. It is the
//	** first on the page. This function appends an appropriate entry to the current
//	** doclist-index.
//	*/
func _fts5WriteDlidxAppend(tls *libc.TLS, p uintptr, pWriter uintptr, iRowid Ti64) {
	var bDone, i, v2 int32
	var iFirst, iPgno, iVal Ti64
	var pDlidx uintptr
	_, _, _, _, _, _, _ = bDone, i, iFirst, iPgno, iVal, pDlidx, v2
	bDone = 0
	i = 0
	for {
		if !((*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK && bDone == 0) {
			break
		}
		pDlidx = (*TFts5SegWriter)(unsafe.Pointer(pWriter)).FaDlidx + uintptr(i)*28
		if (*TFts5DlidxWriter)(unsafe.Pointer(pDlidx)).Fbuf.Fn >= (*TFts5Config)(unsafe.Pointer((*TFts5Index)(unsafe.Pointer(p)).FpConfig)).Fpgsz {
			/* The current doclist-index page is full. Write it to disk and push
			 ** a copy of iRowid (which will become the first rowid on the next
			 ** doclist-index leaf page) up into the next level of the b-tree
			 ** hierarchy. If the node being flushed is currently the root node,
			 ** also push its first rowid upwards. */
			**(**Tu8)(__ccgo_up((*TFts5DlidxWriter)(unsafe.Pointer(pDlidx)).Fbuf.Fp)) = uint8(0x01) /* Not the root node */
			_fts5DataWrite(tls, p, int64((*TFts5SegWriter)(unsafe.Pointer(pWriter)).FiSegid)<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B)+libc.Int32FromInt32(FTS5_DATA_DLI_B))+int64(libc.Int32FromInt32(1))<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B))+int64(i)<<libc.Int32FromInt32(FTS5_DATA_PAGE_B)+int64((*TFts5DlidxWriter)(unsafe.Pointer(pDlidx)).Fpgno), (*TFts5DlidxWriter)(unsafe.Pointer(pDlidx)).Fbuf.Fp, (*TFts5DlidxWriter)(unsafe.Pointer(pDlidx)).Fbuf.Fn)
			_fts5WriteDlidxGrow(tls, p, pWriter, i+int32(2))
			pDlidx = (*TFts5SegWriter)(unsafe.Pointer(pWriter)).FaDlidx + uintptr(i)*28
			if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK && (**(**TFts5DlidxWriter)(__ccgo_up(pDlidx + 1*28))).Fbuf.Fn == 0 {
				iFirst = _fts5DlidxExtractFirstRowid(tls, pDlidx+16)
				/* This was the root node. Push its first rowid up to the new root. */
				(**(**TFts5DlidxWriter)(__ccgo_up(pDlidx + 1*28))).Fpgno = (*TFts5DlidxWriter)(unsafe.Pointer(pDlidx)).Fpgno
				_sqlite3Fts5BufferAppendVarint(tls, p+40, pDlidx+1*28+16, 0)
				_sqlite3Fts5BufferAppendVarint(tls, p+40, pDlidx+1*28+16, int64((*TFts5DlidxWriter)(unsafe.Pointer(pDlidx)).Fpgno))
				_sqlite3Fts5BufferAppendVarint(tls, p+40, pDlidx+1*28+16, iFirst)
				(**(**TFts5DlidxWriter)(__ccgo_up(pDlidx + 1*28))).FbPrevValid = int32(1)
				(**(**TFts5DlidxWriter)(__ccgo_up(pDlidx + 1*28))).FiPrev = iFirst
			}
			_sqlite3Fts5BufferZero(tls, pDlidx+16)
			(*TFts5DlidxWriter)(unsafe.Pointer(pDlidx)).FbPrevValid = 0
			(*TFts5DlidxWriter)(unsafe.Pointer(pDlidx)).Fpgno = (*TFts5DlidxWriter)(unsafe.Pointer(pDlidx)).Fpgno + 1
		} else {
			bDone = int32(1)
		}
		if (*TFts5DlidxWriter)(unsafe.Pointer(pDlidx)).FbPrevValid != 0 {
			iVal = libc.Int64FromUint64(libc.Uint64FromInt64(iRowid) - libc.Uint64FromInt64((*TFts5DlidxWriter)(unsafe.Pointer(pDlidx)).FiPrev))
		} else {
			if i == 0 {
				v2 = (*TFts5SegWriter)(unsafe.Pointer(pWriter)).Fwriter.Fpgno
			} else {
				v2 = (**(**TFts5DlidxWriter)(__ccgo_up(pDlidx + uintptr(-libc.Int32FromInt32(1))*28))).Fpgno
			}
			iPgno = int64(v2)
			_sqlite3Fts5BufferAppendVarint(tls, p+40, pDlidx+16, libc.BoolInt64(!(bDone != 0)))
			_sqlite3Fts5BufferAppendVarint(tls, p+40, pDlidx+16, iPgno)
			iVal = iRowid
		}
		_sqlite3Fts5BufferAppendVarint(tls, p+40, pDlidx+16, iVal)
		(*TFts5DlidxWriter)(unsafe.Pointer(pDlidx)).FbPrevValid = int32(1)
		(*TFts5DlidxWriter)(unsafe.Pointer(pDlidx)).FiPrev = iRowid
		goto _1
	_1:
		;
		i = i + 1
	}
}

func _fts5WriteDlidxClear(tls *libc.TLS, p uintptr, pWriter uintptr, bFlush int32) {
	var i int32
	var pDlidx uintptr
	_, _ = i, pDlidx
	i = 0
	for {
		if !(i < (*TFts5SegWriter)(unsafe.Pointer(pWriter)).FnDlidx) {
			break
		}
		pDlidx = (*TFts5SegWriter)(unsafe.Pointer(pWriter)).FaDlidx + uintptr(i)*28
		if (*TFts5DlidxWriter)(unsafe.Pointer(pDlidx)).Fbuf.Fn == 0 {
			break
		}
		if bFlush != 0 {
			_fts5DataWrite(tls, p, int64((*TFts5SegWriter)(unsafe.Pointer(pWriter)).FiSegid)<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B)+libc.Int32FromInt32(FTS5_DATA_DLI_B))+int64(libc.Int32FromInt32(1))<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B))+int64(i)<<libc.Int32FromInt32(FTS5_DATA_PAGE_B)+int64((*TFts5DlidxWriter)(unsafe.Pointer(pDlidx)).Fpgno), (*TFts5DlidxWriter)(unsafe.Pointer(pDlidx)).Fbuf.Fp, (*TFts5DlidxWriter)(unsafe.Pointer(pDlidx)).Fbuf.Fn)
		}
		_sqlite3Fts5BufferZero(tls, pDlidx+16)
		(*TFts5DlidxWriter)(unsafe.Pointer(pDlidx)).FbPrevValid = 0
		goto _1
	_1:
		;
		i = i + 1
	}
}

// C documentation
//
//	/*
//	** Grow the pWriter->aDlidx[] array to at least nLvl elements in size.
//	** Any new array elements are zeroed before returning.
//	*/
func _fts5WriteDlidxGrow(tls *libc.TLS, p uintptr, pWriter uintptr, nLvl int32) (r int32) {
	var aDlidx uintptr
	var nByte Tsize_t
	_, _ = aDlidx, nByte
	if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK && nLvl >= (*TFts5SegWriter)(unsafe.Pointer(pWriter)).FnDlidx {
		aDlidx = Xsqlite3_realloc64(tls, (*TFts5SegWriter)(unsafe.Pointer(pWriter)).FaDlidx, uint64(uint32(28)*libc.Uint32FromInt32(nLvl)))
		if aDlidx == uintptr(0) {
			(*TFts5Index)(unsafe.Pointer(p)).Frc = int32(SQLITE_NOMEM)
		} else {
			nByte = uint32(28) * libc.Uint32FromInt32(nLvl-(*TFts5SegWriter)(unsafe.Pointer(pWriter)).FnDlidx)
			libc.Xmemset(tls, aDlidx+uintptr((*TFts5SegWriter)(unsafe.Pointer(pWriter)).FnDlidx)*28, 0, nByte)
			(*TFts5SegWriter)(unsafe.Pointer(pWriter)).FaDlidx = aDlidx
			(*TFts5SegWriter)(unsafe.Pointer(pWriter)).FnDlidx = nLvl
		}
	}
	return (*TFts5Index)(unsafe.Pointer(p)).Frc
}

// C documentation
//
//	/*
//	** Flush any data cached by the writer object to the database. Free any
//	** allocations associated with the writer.
//	*/
func _fts5WriteFinish(tls *libc.TLS, p uintptr, pWriter uintptr, pnLeaf uintptr) {
	var i int32
	var pLeaf uintptr
	_, _ = i, pLeaf
	pLeaf = pWriter + 4
	if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
		if (*TFts5PageWriter)(unsafe.Pointer(pLeaf)).Fbuf.Fn > int32(4) {
			_fts5WriteFlushLeaf(tls, p, pWriter)
		}
		**(**int32)(__ccgo_up(pnLeaf)) = (*TFts5PageWriter)(unsafe.Pointer(pLeaf)).Fpgno - int32(1)
		if (*TFts5PageWriter)(unsafe.Pointer(pLeaf)).Fpgno > int32(1) {
			_fts5WriteFlushBtree(tls, p, pWriter)
		}
	}
	_sqlite3Fts5BufferFree(tls, pLeaf+32)
	_sqlite3Fts5BufferFree(tls, pLeaf+8)
	_sqlite3Fts5BufferFree(tls, pLeaf+20)
	_sqlite3Fts5BufferFree(tls, pWriter+76)
	i = 0
	for {
		if !(i < (*TFts5SegWriter)(unsafe.Pointer(pWriter)).FnDlidx) {
			break
		}
		_sqlite3Fts5BufferFree(tls, (*TFts5SegWriter)(unsafe.Pointer(pWriter)).FaDlidx+uintptr(i)*28+16)
		goto _1
	_1:
		;
		i = i + 1
	}
	Xsqlite3_free(tls, (*TFts5SegWriter)(unsafe.Pointer(pWriter)).FaDlidx)
}

func _fts5WriteFlushLeaf(tls *libc.TLS, p uintptr, pWriter uintptr) {
	var iRowid Ti64
	var pPage uintptr
	_, _ = iRowid, pPage
	pPage = pWriter + 4
	/* Set the szLeaf header field. */
	_fts5PutU16(tls, (*TFts5PageWriter)(unsafe.Pointer(pPage)).Fbuf.Fp+2, libc.Uint16FromInt32((*TFts5PageWriter)(unsafe.Pointer(pPage)).Fbuf.Fn))
	if (*TFts5SegWriter)(unsafe.Pointer(pWriter)).FbFirstTermInPage != 0 {
		/* No term was written to this page. */
		_fts5WriteBtreeNoTerm(tls, p, pWriter)
	} else {
		/* Append the pgidx to the page buffer. Set the szLeaf header field. */
		_sqlite3Fts5BufferAppendBlob(tls, p+40, pPage+8, libc.Uint32FromInt32((*TFts5PageWriter)(unsafe.Pointer(pPage)).Fpgidx.Fn), (*TFts5PageWriter)(unsafe.Pointer(pPage)).Fpgidx.Fp)
	}
	/* Write the page out to disk */
	iRowid = int64((*TFts5SegWriter)(unsafe.Pointer(pWriter)).FiSegid)<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B)+libc.Int32FromInt32(FTS5_DATA_DLI_B)) + int64(libc.Int32FromInt32(0))<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B)) + int64(libc.Int32FromInt32(0))<<libc.Int32FromInt32(FTS5_DATA_PAGE_B) + int64((*TFts5PageWriter)(unsafe.Pointer(pPage)).Fpgno)
	_fts5DataWrite(tls, p, iRowid, (*TFts5PageWriter)(unsafe.Pointer(pPage)).Fbuf.Fp, (*TFts5PageWriter)(unsafe.Pointer(pPage)).Fbuf.Fn)
	/* Initialize the next page. */
	_sqlite3Fts5BufferZero(tls, pPage+8)
	_sqlite3Fts5BufferZero(tls, pPage+20)
	_sqlite3Fts5BufferAppendBlob(tls, p+40, pPage+8, uint32(4), uintptr(unsafe.Pointer(&_zero)))
	(*TFts5PageWriter)(unsafe.Pointer(pPage)).FiPrevPgidx = 0
	(*TFts5PageWriter)(unsafe.Pointer(pPage)).Fpgno = (*TFts5PageWriter)(unsafe.Pointer(pPage)).Fpgno + 1
	/* Increase the leaves written counter */
	(*TFts5SegWriter)(unsafe.Pointer(pWriter)).FnLeafWritten = (*TFts5SegWriter)(unsafe.Pointer(pWriter)).FnLeafWritten + 1
	/* The new leaf holds no terms or rowids */
	(*TFts5SegWriter)(unsafe.Pointer(pWriter)).FbFirstTermInPage = uint8(1)
	(*TFts5SegWriter)(unsafe.Pointer(pWriter)).FbFirstRowidInPage = uint8(1)
}

// C documentation
//
//	/*
//	** Add a single segment and its associated events.
//	*/
func _geopolyAddOneSegment(tls *libc.TLS, p uintptr, x0 TGeoCoord, y0 TGeoCoord, x1 TGeoCoord, y1 TGeoCoord, side uint8, idx uint32) {
	var pEvent, pSeg uintptr
	var t TGeoCoord
	_, _, _ = pEvent, pSeg, t
	if x0 == x1 {
		return
	} /* Ignore vertical segments */
	if x0 > x1 {
		t = x0
		x0 = x1
		x1 = t
		t = y0
		y0 = y1
		y1 = t
	}
	pSeg = (*TGeoOverlap)(unsafe.Pointer(p)).FaSegment + uintptr((*TGeoOverlap)(unsafe.Pointer(p)).FnSegment)*40
	(*TGeoOverlap)(unsafe.Pointer(p)).FnSegment = (*TGeoOverlap)(unsafe.Pointer(p)).FnSegment + 1
	(*TGeoSegment)(unsafe.Pointer(pSeg)).FC = float64((y1 - y0) / (x1 - x0))
	(*TGeoSegment)(unsafe.Pointer(pSeg)).FB = float64(y1) - float64(float64(x1)*(*TGeoSegment)(unsafe.Pointer(pSeg)).FC)
	(*TGeoSegment)(unsafe.Pointer(pSeg)).Fy0 = y0
	(*TGeoSegment)(unsafe.Pointer(pSeg)).Fside = side
	(*TGeoSegment)(unsafe.Pointer(pSeg)).Fidx = idx
	pEvent = (*TGeoOverlap)(unsafe.Pointer(p)).FaEvent + uintptr((*TGeoOverlap)(unsafe.Pointer(p)).FnEvent)*20
	(*TGeoOverlap)(unsafe.Pointer(p)).FnEvent = (*TGeoOverlap)(unsafe.Pointer(p)).FnEvent + 1
	(*TGeoEvent)(unsafe.Pointer(pEvent)).Fx = float64(x0)
	(*TGeoEvent)(unsafe.Pointer(pEvent)).FeType = 0
	(*TGeoEvent)(unsafe.Pointer(pEvent)).FpSeg = pSeg
	pEvent = (*TGeoOverlap)(unsafe.Pointer(p)).FaEvent + uintptr((*TGeoOverlap)(unsafe.Pointer(p)).FnEvent)*20
	(*TGeoOverlap)(unsafe.Pointer(p)).FnEvent = (*TGeoOverlap)(unsafe.Pointer(p)).FnEvent + 1
	(*TGeoEvent)(unsafe.Pointer(pEvent)).Fx = float64(x1)
	(*TGeoEvent)(unsafe.Pointer(pEvent)).FeType = int32(1)
	(*TGeoEvent)(unsafe.Pointer(pEvent)).FpSeg = pSeg
}

// C documentation
//
//	/*
//	** GEOPOLY virtual table module xFilter method.
//	**
//	** Query plans:
//	**
//	**      1         rowid lookup
//	**      2         search for objects overlapping the same bounding box
//	**                that contains polygon argv[0]
//	**      3         search for objects overlapping the same bounding box
//	**                that contains polygon argv[0]
//	**      4         full table scan
//	*/
func _geopolyFilter(tls *libc.TLS, pVtabCursor uintptr, idxNum int32, idxStr uintptr, argc int32, argv uintptr) (r int32) {
	bp := tls.Alloc(48)
	defer tls.Free(48)
	var iRowid Ti64
	var p, p1, pCsr, pNew, pRtree, v1 uintptr
	var _ /* bbox at bp+24 */ [4]TRtreeCoord
	var _ /* iCell at bp+8 */ int32
	var _ /* iNode at bp+16 */ Ti64
	var _ /* pLeaf at bp+12 */ uintptr
	var _ /* pRoot at bp+0 */ uintptr
	var _ /* rc at bp+4 */ int32
	_, _, _, _, _, _, _ = iRowid, p, p1, pCsr, pNew, pRtree, v1
	pRtree = (*Tsqlite3_vtab_cursor)(unsafe.Pointer(pVtabCursor)).FpVtab
	pCsr = pVtabCursor
	**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
	**(**int32)(__ccgo_up(bp + 4)) = SQLITE_OK
	**(**int32)(__ccgo_up(bp + 8)) = 0
	_ = idxStr
	_rtreeReference(tls, pRtree)
	/* Reset the cursor to the same state as rtreeOpen() leaves it in. */
	_resetCursor(tls, pCsr)
	(*TRtreeCursor)(unsafe.Pointer(pCsr)).FiStrategy = idxNum
	if idxNum == int32(1) { /* Search point for the leaf */
		iRowid = Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(argv)))
		**(**Ti64)(__ccgo_up(bp + 16)) = 0
		**(**int32)(__ccgo_up(bp + 4)) = _findLeafNode(tls, pRtree, iRowid, bp+12, bp+16)
		if **(**int32)(__ccgo_up(bp + 4)) == SQLITE_OK && **(**uintptr)(__ccgo_up(bp + 12)) != uintptr(0) {
			p = _rtreeSearchPointNew(tls, pCsr, float64(0), uint8(0))
			/* Always returns pCsr->sPoint */
			**(**uintptr)(__ccgo_up(pCsr + 60)) = **(**uintptr)(__ccgo_up(bp + 12))
			(*TRtreeSearchPoint)(unsafe.Pointer(p)).Fid = **(**Ti64)(__ccgo_up(bp + 16))
			(*TRtreeSearchPoint)(unsafe.Pointer(p)).FeWithin = uint8(PARTLY_WITHIN)
			**(**int32)(__ccgo_up(bp + 4)) = _nodeRowidIndex(tls, pRtree, **(**uintptr)(__ccgo_up(bp + 12)), iRowid, bp+8)
			(*TRtreeSearchPoint)(unsafe.Pointer(p)).FiCell = libc.Uint8FromInt32(**(**int32)(__ccgo_up(bp + 8)))
		} else {
			(*TRtreeCursor)(unsafe.Pointer(pCsr)).FatEOF = uint8(1)
		}
	} else {
		/* Normal case - r-tree scan. Set up the RtreeCursor.aConstraint array
		 ** with the configured constraints.
		 */
		**(**int32)(__ccgo_up(bp + 4)) = _nodeAcquire(tls, pRtree, int64(1), uintptr(0), bp)
		if **(**int32)(__ccgo_up(bp + 4)) == SQLITE_OK && idxNum <= int32(3) {
			_geopolyBBox(tls, uintptr(0), **(**uintptr)(__ccgo_up(argv)), bp+24, bp+4)
			if **(**int32)(__ccgo_up(bp + 4)) != 0 {
				goto geopoly_filter_end
			}
			v1 = Xsqlite3_malloc(tls, libc.Int32FromUint32(libc.Uint32FromInt64(20)*libc.Uint32FromInt32(4)))
			p1 = v1
			(*TRtreeCursor)(unsafe.Pointer(pCsr)).FaConstraint = v1
			(*TRtreeCursor)(unsafe.Pointer(pCsr)).FnConstraint = int32(4)
			if p1 == uintptr(0) {
				**(**int32)(__ccgo_up(bp + 4)) = int32(SQLITE_NOMEM)
			} else {
				libc.Xmemset(tls, (*TRtreeCursor)(unsafe.Pointer(pCsr)).FaConstraint, 0, libc.Uint32FromInt64(20)*libc.Uint32FromInt32(4))
				libc.Xmemset(tls, pCsr+80, 0, uint32(4)*libc.Uint32FromInt32((*TRtree)(unsafe.Pointer(pRtree)).FiDepth+libc.Int32FromInt32(1)))
				if idxNum == int32(2) {
					/* Overlap query */
					(*TRtreeConstraint)(unsafe.Pointer(p1)).Fop = int32('B')
					(*TRtreeConstraint)(unsafe.Pointer(p1)).FiCoord = 0
					*(*TRtreeDValue)(unsafe.Pointer(p1 + 8)) = float64(*(*TRtreeValue)(unsafe.Pointer(bp + 24 + 1*4)))
					p1 += 20
					(*TRtreeConstraint)(unsafe.Pointer(p1)).Fop = int32('D')
					(*TRtreeConstraint)(unsafe.Pointer(p1)).FiCoord = int32(1)
					*(*TRtreeDValue)(unsafe.Pointer(p1 + 8)) = float64(*(*TRtreeValue)(unsafe.Pointer(bp + 24)))
					p1 += 20
					(*TRtreeConstraint)(unsafe.Pointer(p1)).Fop = int32('B')
					(*TRtreeConstraint)(unsafe.Pointer(p1)).FiCoord = int32(2)
					*(*TRtreeDValue)(unsafe.Pointer(p1 + 8)) = float64(*(*TRtreeValue)(unsafe.Pointer(bp + 24 + 3*4)))
					p1 += 20
					(*TRtreeConstraint)(unsafe.Pointer(p1)).Fop = int32('D')
					(*TRtreeConstraint)(unsafe.Pointer(p1)).FiCoord = int32(3)
					*(*TRtreeDValue)(unsafe.Pointer(p1 + 8)) = float64(*(*TRtreeValue)(unsafe.Pointer(bp + 24 + 2*4)))
				} else {
					/* Within query */
					(*TRtreeConstraint)(unsafe.Pointer(p1)).Fop = int32('D')
					(*TRtreeConstraint)(unsafe.Pointer(p1)).FiCoord = 0
					*(*TRtreeDValue)(unsafe.Pointer(p1 + 8)) = float64(*(*TRtreeValue)(unsafe.Pointer(bp + 24)))
					p1 += 20
					(*TRtreeConstraint)(unsafe.Pointer(p1)).Fop = int32('B')
					(*TRtreeConstraint)(unsafe.Pointer(p1)).FiCoord = int32(1)
					*(*TRtreeDValue)(unsafe.Pointer(p1 + 8)) = float64(*(*TRtreeValue)(unsafe.Pointer(bp + 24 + 1*4)))
					p1 += 20
					(*TRtreeConstraint)(unsafe.Pointer(p1)).Fop = int32('D')
					(*TRtreeConstraint)(unsafe.Pointer(p1)).FiCoord = int32(2)
					*(*TRtreeDValue)(unsafe.Pointer(p1 + 8)) = float64(*(*TRtreeValue)(unsafe.Pointer(bp + 24 + 2*4)))
					p1 += 20
					(*TRtreeConstraint)(unsafe.Pointer(p1)).Fop = int32('B')
					(*TRtreeConstraint)(unsafe.Pointer(p1)).FiCoord = int32(3)
					*(*TRtreeDValue)(unsafe.Pointer(p1 + 8)) = float64(*(*TRtreeValue)(unsafe.Pointer(bp + 24 + 3*4)))
				}
			}
		}
		if **(**int32)(__ccgo_up(bp + 4)) == SQLITE_OK {
			pNew = _rtreeSearchPointNew(tls, pCsr, float64(0), libc.Uint8FromInt32((*TRtree)(unsafe.Pointer(pRtree)).FiDepth+libc.Int32FromInt32(1)))
			if pNew == uintptr(0) {
				**(**int32)(__ccgo_up(bp + 4)) = int32(SQLITE_NOMEM)
				goto geopoly_filter_end
			}
			(*TRtreeSearchPoint)(unsafe.Pointer(pNew)).Fid = int64(1)
			(*TRtreeSearchPoint)(unsafe.Pointer(pNew)).FiCell = uint8(0)
			(*TRtreeSearchPoint)(unsafe.Pointer(pNew)).FeWithin = uint8(PARTLY_WITHIN)
			**(**uintptr)(__ccgo_up(pCsr + 60)) = **(**uintptr)(__ccgo_up(bp))
			**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
			**(**int32)(__ccgo_up(bp + 4)) = _rtreeStepToLeaf(tls, pCsr)
		}
	}
	goto geopoly_filter_end
geopoly_filter_end:
	;
	_nodeRelease(tls, pRtree, **(**uintptr)(__ccgo_up(bp)))
	_rtreeRelease(tls, pRtree)
	return **(**int32)(__ccgo_up(bp + 4))
}

// C documentation
//
//	/*
//	** Determine the overlap between two polygons
//	*/
func _geopolyOverlap(tls *libc.TLS, p1 uintptr, p2 uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var iMask, needSort, rc, v1 int32
	var nByte, nVertex Tsqlite3_int64
	var p, pActive, pPrev, pSeg, pThisEvent, v5 uintptr
	var rX, y, v2 float64
	var _ /* aOverlap at bp+0 */ [4]uint8
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = iMask, nByte, nVertex, needSort, p, pActive, pPrev, pSeg, pThisEvent, rX, rc, y, v1, v2, v5
	nVertex = int64((*TGeoPoly)(unsafe.Pointer(p1)).FnVertex + (*TGeoPoly)(unsafe.Pointer(p2)).FnVertex + int32(2))
	rc = 0
	needSort = 0
	pActive = uintptr(0)
	nByte = int64(20)*nVertex*int64(2) + int64(40)*nVertex + int64(16)
	p = Xsqlite3_malloc64(tls, libc.Uint64FromInt64(nByte))
	if p == uintptr(0) {
		return -int32(1)
	}
	(*TGeoOverlap)(unsafe.Pointer(p)).FaEvent = p + 1*16
	(*TGeoOverlap)(unsafe.Pointer(p)).FaSegment = (*TGeoOverlap)(unsafe.Pointer(p)).FaEvent + uintptr(nVertex*int64(2))*20
	v1 = libc.Int32FromInt32(0)
	(*TGeoOverlap)(unsafe.Pointer(p)).FnSegment = v1
	(*TGeoOverlap)(unsafe.Pointer(p)).FnEvent = v1
	_geopolyAddSegments(tls, p, p1, uint8(1))
	_geopolyAddSegments(tls, p, p2, uint8(2))
	pThisEvent = _geopolySortEventsByX(tls, (*TGeoOverlap)(unsafe.Pointer(p)).FaEvent, (*TGeoOverlap)(unsafe.Pointer(p)).FnEvent)
	if pThisEvent != 0 && (*TGeoEvent)(unsafe.Pointer(pThisEvent)).Fx == float64(0) {
		v2 = -libc.Float64FromFloat64(1)
	} else {
		v2 = float64(0)
	}
	rX = v2
	libc.Xmemset(tls, bp, 0, uint32(4))
	for pThisEvent != 0 {
		if (*TGeoEvent)(unsafe.Pointer(pThisEvent)).Fx != rX {
			pPrev = uintptr(0)
			iMask = 0
			rX = (*TGeoEvent)(unsafe.Pointer(pThisEvent)).Fx
			if needSort != 0 {
				pActive = _geopolySortSegmentsByYAndC(tls, pActive)
				needSort = 0
			}
			pSeg = pActive
			for {
				if !(pSeg != 0) {
					break
				}
				if pPrev != 0 {
					if (*TGeoSegment)(unsafe.Pointer(pPrev)).Fy != (*TGeoSegment)(unsafe.Pointer(pSeg)).Fy {
						(**(**[4]uint8)(__ccgo_up(bp)))[iMask] = uint8(1)
					}
				}
				iMask = iMask ^ libc.Int32FromUint8((*TGeoSegment)(unsafe.Pointer(pSeg)).Fside)
				pPrev = pSeg
				goto _3
			_3:
				;
				pSeg = (*TGeoSegment)(unsafe.Pointer(pSeg)).FpNext
			}
			pPrev = uintptr(0)
			pSeg = pActive
			for {
				if !(pSeg != 0) {
					break
				}
				y = float64((*TGeoSegment)(unsafe.Pointer(pSeg)).FC*rX) + (*TGeoSegment)(unsafe.Pointer(pSeg)).FB
				(*TGeoSegment)(unsafe.Pointer(pSeg)).Fy = y
				if pPrev != 0 {
					if (*TGeoSegment)(unsafe.Pointer(pPrev)).Fy > (*TGeoSegment)(unsafe.Pointer(pSeg)).Fy && libc.Int32FromUint8((*TGeoSegment)(unsafe.Pointer(pPrev)).Fside) != libc.Int32FromUint8((*TGeoSegment)(unsafe.Pointer(pSeg)).Fside) {
						rc = int32(1)
						goto geopolyOverlapDone
					} else {
						if (*TGeoSegment)(unsafe.Pointer(pPrev)).Fy != (*TGeoSegment)(unsafe.Pointer(pSeg)).Fy {
							(**(**[4]uint8)(__ccgo_up(bp)))[iMask] = uint8(1)
						}
					}
				}
				iMask = iMask ^ libc.Int32FromUint8((*TGeoSegment)(unsafe.Pointer(pSeg)).Fside)
				pPrev = pSeg
				goto _4
			_4:
				;
				pSeg = (*TGeoSegment)(unsafe.Pointer(pSeg)).FpNext
			}
		}
		if (*TGeoEvent)(unsafe.Pointer(pThisEvent)).FeType == 0 {
			/* Add a segment */
			pSeg = (*TGeoEvent)(unsafe.Pointer(pThisEvent)).FpSeg
			(*TGeoSegment)(unsafe.Pointer(pSeg)).Fy = float64((*TGeoSegment)(unsafe.Pointer(pSeg)).Fy0)
			(*TGeoSegment)(unsafe.Pointer(pSeg)).FpNext = pActive
			pActive = pSeg
			needSort = int32(1)
		} else {
			/* Remove a segment */
			if pActive == (*TGeoEvent)(unsafe.Pointer(pThisEvent)).FpSeg {
				if pActive != 0 {
					v5 = (*TGeoSegment)(unsafe.Pointer(pActive)).FpNext
				} else {
					v5 = uintptr(0)
				}
				pActive = v5
			} else {
				pSeg = pActive
				for {
					if !(pSeg != 0) {
						break
					}
					if (*TGeoSegment)(unsafe.Pointer(pSeg)).FpNext == (*TGeoEvent)(unsafe.Pointer(pThisEvent)).FpSeg {
						if (*TGeoSegment)(unsafe.Pointer(pSeg)).FpNext != 0 {
							v5 = (*TGeoSegment)(unsafe.Pointer((*TGeoSegment)(unsafe.Pointer(pSeg)).FpNext)).FpNext
						} else {
							v5 = uintptr(0)
						}
						(*TGeoSegment)(unsafe.Pointer(pSeg)).FpNext = v5
						break
					}
					goto _6
				_6:
					;
					pSeg = (*TGeoSegment)(unsafe.Pointer(pSeg)).FpNext
				}
			}
		}
		pThisEvent = (*TGeoEvent)(unsafe.Pointer(pThisEvent)).FpNext
	}
	if libc.Int32FromUint8((**(**[4]uint8)(__ccgo_up(bp)))[int32(3)]) == 0 {
		rc = 0
	} else {
		if libc.Int32FromUint8((**(**[4]uint8)(__ccgo_up(bp)))[int32(1)]) != 0 && libc.Int32FromUint8((**(**[4]uint8)(__ccgo_up(bp)))[int32(2)]) == 0 {
			rc = int32(3)
		} else {
			if libc.Int32FromUint8((**(**[4]uint8)(__ccgo_up(bp)))[int32(1)]) == 0 && libc.Int32FromUint8((**(**[4]uint8)(__ccgo_up(bp)))[int32(2)]) != 0 {
				rc = int32(2)
			} else {
				if libc.Int32FromUint8((**(**[4]uint8)(__ccgo_up(bp)))[int32(1)]) == 0 && libc.Int32FromUint8((**(**[4]uint8)(__ccgo_up(bp)))[int32(2)]) == 0 {
					rc = int32(4)
				} else {
					rc = int32(1)
				}
			}
		}
	}
	goto geopolyOverlapDone
geopolyOverlapDone:
	;
	Xsqlite3_free(tls, p)
	return rc
}

// C documentation
//
//	/*
//	** If the input is a well-formed JSON array of coordinates with at least
//	** four coordinates and where each coordinate is itself a two-value array,
//	** then convert the JSON into a GeoPoly object and return a pointer to
//	** that object.
//	**
//	** If any error occurs, return NULL.
//	*/
func _geopolyParseJson(tls *libc.TLS, z uintptr, pRc uintptr) (r uintptr) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var aNew, pOut, v1 uintptr
	var c int8
	var ii, rc int32
	var v2 bool
	var _ /* s at bp+0 */ TGeoParse
	var _ /* x at bp+20 */ int32
	_, _, _, _, _, _, _ = aNew, c, ii, pOut, rc, v1, v2
	rc = SQLITE_OK
	libc.Xmemset(tls, bp, 0, uint32(20))
	(**(**TGeoParse)(__ccgo_up(bp))).Fz = z
	if int32(_geopolySkipSpace(tls, bp)) == int32('[') {
		(**(**TGeoParse)(__ccgo_up(bp))).Fz = (**(**TGeoParse)(__ccgo_up(bp))).Fz + 1
		for int32(_geopolySkipSpace(tls, bp)) == int32('[') {
			ii = 0
			(**(**TGeoParse)(__ccgo_up(bp))).Fz = (**(**TGeoParse)(__ccgo_up(bp))).Fz + 1
			if (**(**TGeoParse)(__ccgo_up(bp))).FnVertex >= (**(**TGeoParse)(__ccgo_up(bp))).FnAlloc {
				(**(**TGeoParse)(__ccgo_up(bp))).FnAlloc = (**(**TGeoParse)(__ccgo_up(bp))).FnAlloc*int32(2) + int32(16)
				aNew = Xsqlite3_realloc64(tls, (**(**TGeoParse)(__ccgo_up(bp))).Fa, uint64(libc.Uint32FromInt32((**(**TGeoParse)(__ccgo_up(bp))).FnAlloc)*uint32(4)*uint32(2)))
				if aNew == uintptr(0) {
					rc = int32(SQLITE_NOMEM)
					(**(**TGeoParse)(__ccgo_up(bp))).FnErr = (**(**TGeoParse)(__ccgo_up(bp))).FnErr + 1
					break
				}
				(**(**TGeoParse)(__ccgo_up(bp))).Fa = aNew
			}
			for {
				if ii <= int32(1) {
					v1 = (**(**TGeoParse)(__ccgo_up(bp))).Fa + uintptr((**(**TGeoParse)(__ccgo_up(bp))).FnVertex*int32(2)+ii)*4
				} else {
					v1 = uintptr(0)
				}
				if !(_geopolyParseNumber(tls, bp, v1) != 0) {
					break
				}
				ii = ii + 1
				if ii == int32(2) {
					(**(**TGeoParse)(__ccgo_up(bp))).FnVertex = (**(**TGeoParse)(__ccgo_up(bp))).FnVertex + 1
				}
				c = _geopolySkipSpace(tls, bp)
				(**(**TGeoParse)(__ccgo_up(bp))).Fz = (**(**TGeoParse)(__ccgo_up(bp))).Fz + 1
				if int32(c) == int32(',') {
					continue
				}
				if int32(c) == int32(']') && ii >= int32(2) {
					break
				}
				(**(**TGeoParse)(__ccgo_up(bp))).FnErr = (**(**TGeoParse)(__ccgo_up(bp))).FnErr + 1
				rc = int32(SQLITE_ERROR)
				goto parse_json_err
			}
			if int32(_geopolySkipSpace(tls, bp)) == int32(',') {
				(**(**TGeoParse)(__ccgo_up(bp))).Fz = (**(**TGeoParse)(__ccgo_up(bp))).Fz + 1
				continue
			}
			break
		}
		if v2 = int32(_geopolySkipSpace(tls, bp)) == int32(']') && (**(**TGeoParse)(__ccgo_up(bp))).FnVertex >= int32(4) && **(**TGeoCoord)(__ccgo_up((**(**TGeoParse)(__ccgo_up(bp))).Fa)) == **(**TGeoCoord)(__ccgo_up((**(**TGeoParse)(__ccgo_up(bp))).Fa + uintptr((**(**TGeoParse)(__ccgo_up(bp))).FnVertex*int32(2)-int32(2))*4)) && **(**TGeoCoord)(__ccgo_up((**(**TGeoParse)(__ccgo_up(bp))).Fa + 1*4)) == **(**TGeoCoord)(__ccgo_up((**(**TGeoParse)(__ccgo_up(bp))).Fa + uintptr((**(**TGeoParse)(__ccgo_up(bp))).FnVertex*int32(2)-int32(1))*4)); v2 {
			(**(**TGeoParse)(__ccgo_up(bp))).Fz = (**(**TGeoParse)(__ccgo_up(bp))).Fz + 1
		}
		if v2 && int32(_geopolySkipSpace(tls, bp)) == libc.Int32FromInt32(0) {
			**(**int32)(__ccgo_up(bp + 20)) = int32(1)
			(**(**TGeoParse)(__ccgo_up(bp))).FnVertex = (**(**TGeoParse)(__ccgo_up(bp))).FnVertex - 1 /* Remove the redundant vertex at the end */
			pOut = Xsqlite3_malloc64(tls, libc.Uint64FromInt64(libc.Int64FromInt64(40)+libc.Int64FromUint32(libc.Uint32FromInt64(4)*libc.Uint32FromInt32(2))*(int64((**(**TGeoParse)(__ccgo_up(bp))).FnVertex)-libc.Int64FromInt32(4))))
			**(**int32)(__ccgo_up(bp + 20)) = int32(1)
			if pOut == uintptr(0) {
				goto parse_json_err
			}
			(*TGeoPoly)(unsafe.Pointer(pOut)).FnVertex = (**(**TGeoParse)(__ccgo_up(bp))).FnVertex
			libc.Xmemcpy(tls, pOut+8, (**(**TGeoParse)(__ccgo_up(bp))).Fa, libc.Uint32FromInt32((**(**TGeoParse)(__ccgo_up(bp))).FnVertex*int32(2))*uint32(4))
			**(**uint8)(__ccgo_up(pOut + 4)) = **(**uint8)(__ccgo_up(bp + 20))
			**(**uint8)(__ccgo_up(pOut + 4 + 1)) = libc.Uint8FromInt32((**(**TGeoParse)(__ccgo_up(bp))).FnVertex >> int32(16) & int32(0xff))
			**(**uint8)(__ccgo_up(pOut + 4 + 2)) = libc.Uint8FromInt32((**(**TGeoParse)(__ccgo_up(bp))).FnVertex >> int32(8) & int32(0xff))
			**(**uint8)(__ccgo_up(pOut + 4 + 3)) = libc.Uint8FromInt32((**(**TGeoParse)(__ccgo_up(bp))).FnVertex & int32(0xff))
			Xsqlite3_free(tls, (**(**TGeoParse)(__ccgo_up(bp))).Fa)
			if pRc != 0 {
				**(**int32)(__ccgo_up(pRc)) = SQLITE_OK
			}
			return pOut
		} else {
			(**(**TGeoParse)(__ccgo_up(bp))).FnErr = (**(**TGeoParse)(__ccgo_up(bp))).FnErr + 1
			rc = int32(SQLITE_ERROR)
		}
	}
	goto parse_json_err
parse_json_err:
	;
	if pRc != 0 {
		**(**int32)(__ccgo_up(pRc)) = rc
	}
	Xsqlite3_free(tls, (**(**TGeoParse)(__ccgo_up(bp))).Fa)
	return uintptr(0)
}

// C documentation
//
//	/*
//	** Sort an array of nEvent event objects into a list.
//	*/
func _geopolySortEventsByX(tls *libc.TLS, aEvent uintptr, nEvent int32) (r uintptr) {
	var a [50]uintptr
	var i, j, mx int32
	var p uintptr
	_, _, _, _, _ = a, i, j, mx, p
	mx = 0
	i = 0
	for {
		if !(i < nEvent) {
			break
		}
		p = aEvent + uintptr(i)*20
		(*TGeoEvent)(unsafe.Pointer(p)).FpNext = uintptr(0)
		j = 0
		for {
			if !(j < mx && a[j] != 0) {
				break
			}
			p = _geopolyEventMerge(tls, a[j], p)
			a[j] = uintptr(0)
			goto _2
		_2:
			;
			j = j + 1
		}
		a[j] = p
		if j >= mx {
			mx = j + int32(1)
		}
		goto _1
	_1:
		;
		i = i + 1
	}
	p = uintptr(0)
	i = 0
	for {
		if !(i < mx) {
			break
		}
		p = _geopolyEventMerge(tls, a[i], p)
		goto _3
	_3:
		;
		i = i + 1
	}
	return p
}

// C documentation
//
//	/*
//	** Make sure the BtCursor* given in the argument has a valid
//	** BtCursor.info structure.  If it is not already valid, call
//	** btreeParseCell() to fill it in.
//	**
//	** BtCursor.info is a cache of the information in the current cell.
//	** Using this cache reduces the number of calls to btreeParseCell().
//	*/
func _getCellInfo(tls *libc.TLS, pCur uintptr) {
	var v1 uintptr
	_ = v1
	if libc.Int32FromUint16((*TBtCursor)(unsafe.Pointer(pCur)).Finfo.FnSize) == 0 {
		v1 = pCur + 1
		*(*Tu8)(unsafe.Pointer(v1)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v1))) | libc.Int32FromInt32(BTCF_ValidNKey))
		_btreeParseCell(tls, (*TBtCursor)(unsafe.Pointer(pCur)).FpPage, libc.Int32FromUint16((*TBtCursor)(unsafe.Pointer(pCur)).Fix), pCur+28)
	} else {
	}
}

// C documentation
//
//	/*
//	** The page getter methods each try to acquire a reference to a
//	** page with page number pgno. If the requested reference is
//	** successfully obtained, it is copied to *ppPage and SQLITE_OK returned.
//	**
//	** There are different implementations of the getter method depending
//	** on the current state of the pager.
//	**
//	**     getPageNormal()         --  The normal getter
//	**     getPageError()          --  Used if the pager is in an error state
//	**     getPageMmap()           --  Used if memory-mapped I/O is enabled
//	**
//	** If the requested page is already in the cache, it is returned.
//	** Otherwise, a new page object is allocated and populated with data
//	** read from the database file. In some cases, the pcache module may
//	** choose not to allocate a new page object and may reuse an existing
//	** object with no outstanding references.
//	**
//	** The extra data appended to a page is always initialized to zeros the
//	** first time a page is loaded into memory. If the page requested is
//	** already in the cache when this function is called, then the extra
//	** data is left as it was when the page object was last used.
//	**
//	** If the database image is smaller than the requested page or if
//	** the flags parameter contains the PAGER_GET_NOCONTENT bit and the
//	** requested page is not already stored in the cache, then no
//	** actual disk read occurs. In this case the memory image of the
//	** page is initialized to all zeros.
//	**
//	** If PAGER_GET_NOCONTENT is true, it means that we do not care about
//	** the contents of the page. This occurs in two scenarios:
//	**
//	**   a) When reading a free-list leaf page from the database, and
//	**
//	**   b) When a savepoint is being rolled back and we need to load
//	**      a new page into the cache to be filled with the data read
//	**      from the savepoint journal.
//	**
//	** If PAGER_GET_NOCONTENT is true, then the data returned is zeroed instead
//	** of being read from the database. Additionally, the bits corresponding
//	** to pgno in Pager.pInJournal (bitvec of pages already written to the
//	** journal file) and the PagerSavepoint.pInSavepoint bitvecs of any open
//	** savepoints are set. This means if the page is made writable at any
//	** point in the future, using a call to sqlite3PagerWrite(), its contents
//	** will not be journaled. This saves IO.
//	**
//	** The acquisition might fail for several reasons.  In all cases,
//	** an appropriate error code is returned and *ppPage is set to NULL.
//	**
//	** See also sqlite3PagerLookup().  Both this routine and Lookup() attempt
//	** to find a page in the in-memory cache first.  If the page is not already
//	** in memory, this routine goes to disk to read it in whereas Lookup()
//	** just returns 0.  This routine acquires a read-lock the first time it
//	** has to go to disk, and could also playback an old journal if necessary.
//	** Since Lookup() never goes to disk, it never has to deal with locks
//	** or journal files.
//	*/
func _getPageNormal(tls *libc.TLS, pPager uintptr, pgno TPgno, ppPage uintptr, flags int32) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var noContent Tu8
	var pPg, v1 uintptr
	var rc int32
	var _ /* pBase at bp+0 */ uintptr
	_, _, _, _ = noContent, pPg, rc, v1
	rc = SQLITE_OK
	if pgno == uint32(0) {
		return _sqlite3CorruptError(tls, int32(65157))
	}
	**(**uintptr)(__ccgo_up(bp)) = _sqlite3PcacheFetch(tls, (*TPager)(unsafe.Pointer(pPager)).FpPCache, pgno, int32(3))
	if **(**uintptr)(__ccgo_up(bp)) == uintptr(0) {
		pPg = uintptr(0)
		rc = _sqlite3PcacheFetchStress(tls, (*TPager)(unsafe.Pointer(pPager)).FpPCache, pgno, bp)
		if rc != SQLITE_OK {
			goto pager_acquire_err
		}
		if **(**uintptr)(__ccgo_up(bp)) == uintptr(0) {
			rc = int32(SQLITE_NOMEM)
			goto pager_acquire_err
		}
	}
	v1 = _sqlite3PcacheFetchFinish(tls, (*TPager)(unsafe.Pointer(pPager)).FpPCache, pgno, **(**uintptr)(__ccgo_up(bp)))
	**(**uintptr)(__ccgo_up(ppPage)) = v1
	pPg = v1
	noContent = libc.BoolUint8(flags&int32(PAGER_GET_NOCONTENT) != 0)
	if (*TPgHdr)(unsafe.Pointer(pPg)).FpPager != 0 && !(noContent != 0) {
		/* In this case the pcache already contains an initialized copy of
		 ** the page. Return without further ado.  */
		**(**Tu32)(__ccgo_up(pPager + 192)) = **(**Tu32)(__ccgo_up(pPager + 192)) + 1
		return SQLITE_OK
	} else {
		/* The pager cache has created a new page. Its content needs to
		 ** be initialized. But first some error checks:
		 **
		 ** (*) obsolete.  Was: maximum page number is 2^31
		 ** (2) Never try to fetch the locking page
		 */
		if pgno == (*TPager)(unsafe.Pointer(pPager)).FlckPgno {
			rc = _sqlite3CorruptError(tls, int32(65189))
			goto pager_acquire_err
		}
		(*TPgHdr)(unsafe.Pointer(pPg)).FpPager = pPager
		if !((*Tsqlite3_file)(unsafe.Pointer((*TPager)(unsafe.Pointer(pPager)).Ffd)).FpMethods != libc.UintptrFromInt32(0)) || (*TPager)(unsafe.Pointer(pPager)).FdbSize < pgno || noContent != 0 {
			if pgno > (*TPager)(unsafe.Pointer(pPager)).FmxPgno {
				rc = int32(SQLITE_FULL)
				if pgno <= (*TPager)(unsafe.Pointer(pPager)).FdbSize {
					_sqlite3PcacheRelease(tls, pPg)
					pPg = uintptr(0)
				}
				goto pager_acquire_err
			}
			if noContent != 0 {
				/* Failure to set the bits in the InJournal bit-vectors is benign.
				 ** It merely means that we might do some extra work to journal a
				 ** page that does not need to be journaled.  Nevertheless, be sure
				 ** to test the case where a malloc error occurs while trying to set
				 ** a bit in a bit vector.
				 */
				_sqlite3BeginBenignMalloc(tls)
				if pgno <= (*TPager)(unsafe.Pointer(pPager)).FdbOrigSize {
					_sqlite3BitvecSet(tls, (*TPager)(unsafe.Pointer(pPager)).FpInJournal, pgno)
				}
				_addToSavepointBitvecs(tls, pPager, pgno)
				_sqlite3EndBenignMalloc(tls)
			}
			libc.Xmemset(tls, (*TPgHdr)(unsafe.Pointer(pPg)).FpData, 0, libc.Uint32FromInt64((*TPager)(unsafe.Pointer(pPager)).FpageSize))
		} else {
			**(**Tu32)(__ccgo_up(pPager + 192 + 1*4)) = **(**Tu32)(__ccgo_up(pPager + 192 + 1*4)) + 1
			rc = _readDbPage(tls, pPg)
			if rc != SQLITE_OK {
				goto pager_acquire_err
			}
		}
	}
	return SQLITE_OK
	goto pager_acquire_err
pager_acquire_err:
	;
	if pPg != 0 {
		_sqlite3PcacheDrop(tls, pPg)
	}
	_pagerUnlockIfUnused(tls, pPager)
	**(**uintptr)(__ccgo_up(ppPage)) = uintptr(0)
	return rc
}

// C documentation
//
//	/*
//	** Interpret the given string as a safety level.  Return 0 for OFF,
//	** 1 for ON or NORMAL, 2 for FULL, and 3 for EXTRA.  Return 1 for an empty or
//	** unrecognized string argument.  The FULL and EXTRA option is disallowed
//	** if the omitFull parameter it 1.
//	**
//	** Note that the values returned are one less that the values that
//	** should be passed into sqlite3BtreeSetSafetyLevel().  The is done
//	** to support legacy SQL code.  The safety level used to be boolean
//	** and older scripts may have used numbers 0 for OFF and 1 for ON.
//	*/
func _getSafetyLevel(tls *libc.TLS, z uintptr, omitFull int32, dflt Tu8) (r Tu8) {
	var i, n int32
	_, _ = i, n
	if libc.Int32FromUint8(_sqlite3CtypeMap[libc.Uint8FromInt8(**(**int8)(__ccgo_up(z)))])&int32(0x04) != 0 {
		return libc.Uint8FromInt32(_sqlite3Atoi(tls, z))
	}
	n = _sqlite3Strlen30(tls, z)
	i = 0
	for {
		if !(i < libc.Int32FromUint32(libc.Uint32FromInt64(8)/libc.Uint32FromInt64(1))) {
			break
		}
		if libc.Int32FromUint8(_iLength[i]) == n && Xsqlite3_strnicmp(tls, uintptr(unsafe.Pointer(&_zText))+uintptr(_iOffset[i]), z, n) == 0 && (!(omitFull != 0) || libc.Int32FromUint8(_iValue[i]) <= int32(1)) {
			return _iValue[i]
		}
		goto _1
	_1:
		;
		i = i + 1
	}
	return dflt
}

func _groupConcatStep(tls *libc.TLS, context uintptr, argc int32, argv uintptr) {
	var db, pGCC, pnsl, zSep, zVal uintptr
	var firstTerm, i, nA, nSep, nVal, v1 int32
	_, _, _, _, _, _, _, _, _, _, _ = db, firstTerm, i, nA, nSep, nVal, pGCC, pnsl, zSep, zVal, v1
	if Xsqlite3_value_type(tls, **(**uintptr)(__ccgo_up(argv))) == int32(SQLITE_NULL) {
		return
	}
	pGCC = Xsqlite3_aggregate_context(tls, context, int32(36))
	if pGCC != 0 {
		db = Xsqlite3_context_db_handle(tls, context)
		firstTerm = libc.BoolInt32((*TGroupConcatCtx)(unsafe.Pointer(pGCC)).Fstr.FmxAlloc == uint32(0))
		(*TGroupConcatCtx)(unsafe.Pointer(pGCC)).Fstr.FmxAlloc = libc.Uint32FromInt32(**(**int32)(__ccgo_up(db + 116)))
		if argc == int32(1) {
			if !(firstTerm != 0) {
				Xsqlite3_str_appendchar(tls, pGCC, int32(1), int8(','))
			} else {
				(*TGroupConcatCtx)(unsafe.Pointer(pGCC)).FnFirstSepLength = int32(1)
			}
		} else {
			if !(firstTerm != 0) {
				zSep = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv + 1*4)))
				nSep = Xsqlite3_value_bytes(tls, **(**uintptr)(__ccgo_up(argv + 1*4)))
				if zSep != 0 {
					Xsqlite3_str_append(tls, pGCC, zSep, nSep)
				} else {
					nSep = 0
				}
				if nSep != (*TGroupConcatCtx)(unsafe.Pointer(pGCC)).FnFirstSepLength || (*TGroupConcatCtx)(unsafe.Pointer(pGCC)).FpnSepLengths != uintptr(0) {
					pnsl = (*TGroupConcatCtx)(unsafe.Pointer(pGCC)).FpnSepLengths
					if pnsl == uintptr(0) {
						/* First separator length variation seen, start tracking them. */
						pnsl = Xsqlite3_malloc64(tls, uint64(libc.Uint32FromInt32((*TGroupConcatCtx)(unsafe.Pointer(pGCC)).FnAccum+libc.Int32FromInt32(1))*uint32(4)))
						if pnsl != uintptr(0) {
							i = 0
							nA = (*TGroupConcatCtx)(unsafe.Pointer(pGCC)).FnAccum - int32(1)
							for i < nA {
								v1 = i
								i = i + 1
								**(**int32)(__ccgo_up(pnsl + uintptr(v1)*4)) = (*TGroupConcatCtx)(unsafe.Pointer(pGCC)).FnFirstSepLength
							}
						}
					} else {
						pnsl = Xsqlite3_realloc64(tls, pnsl, uint64(libc.Uint32FromInt32((*TGroupConcatCtx)(unsafe.Pointer(pGCC)).FnAccum)*uint32(4)))
					}
					if pnsl != uintptr(0) {
						if (*TGroupConcatCtx)(unsafe.Pointer(pGCC)).FnAccum > 0 {
							**(**int32)(__ccgo_up(pnsl + uintptr((*TGroupConcatCtx)(unsafe.Pointer(pGCC)).FnAccum-int32(1))*4)) = nSep
						}
						(*TGroupConcatCtx)(unsafe.Pointer(pGCC)).FpnSepLengths = pnsl
					} else {
						_sqlite3StrAccumSetError(tls, pGCC, uint8(SQLITE_NOMEM))
					}
				}
			} else {
				(*TGroupConcatCtx)(unsafe.Pointer(pGCC)).FnFirstSepLength = Xsqlite3_value_bytes(tls, **(**uintptr)(__ccgo_up(argv + 1*4)))
			}
		}
		**(**int32)(__ccgo_up(pGCC + 24)) += int32(1)
		zVal = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv)))
		nVal = Xsqlite3_value_bytes(tls, **(**uintptr)(__ccgo_up(argv)))
		if zVal != 0 {
			Xsqlite3_str_append(tls, pGCC, zVal, nVal)
		}
	}
}

// C documentation
//
//	/*
//	** Resize the Vdbe.aOp array so that it is at least nOp elements larger
//	** than its current size. nOp is guaranteed to be less than or equal
//	** to 1024/sizeof(Op).
//	**
//	** If an out-of-memory error occurs while resizing the array, return
//	** SQLITE_NOMEM. In this case Vdbe.aOp and Vdbe.nOpAlloc remain
//	** unchanged (this is so that any opcodes already allocated can be
//	** correctly deallocated along with the rest of the Vdbe).
//	*/
func _growOpArray(tls *libc.TLS, v uintptr, nOp int32) (r int32) {
	var nNew Tsqlite3_int64
	var p, pNew uintptr
	var v1 int64
	var v2 int32
	_, _, _, _, _ = nNew, p, pNew, v1, v2
	p = (*TVdbe)(unsafe.Pointer(v)).FpParse
	if (*TVdbe)(unsafe.Pointer(v)).FnOpAlloc != 0 {
		v1 = int64(2) * int64((*TVdbe)(unsafe.Pointer(v)).FnOpAlloc)
	} else {
		v1 = libc.Int64FromUint32(libc.Uint32FromInt32(1024) / libc.Uint32FromInt64(20))
	}
	/* The SQLITE_TEST_REALLOC_STRESS compile-time option is designed to force
	 ** more frequent reallocs and hence provide more opportunities for
	 ** simulated OOM faults.  SQLITE_TEST_REALLOC_STRESS is generally used
	 ** during testing only.  With SQLITE_TEST_REALLOC_STRESS grow the op array
	 ** by the minimum* amount required until the size reaches 512.  Normal
	 ** operation (without SQLITE_TEST_REALLOC_STRESS) is to double the current
	 ** size of the op array or add 1KB of space, whichever is smaller. */
	nNew = v1
	_ = nOp
	/* Ensure that the size of a VDBE does not grow too large */
	if nNew > int64(**(**int32)(__ccgo_up((*TParse)(unsafe.Pointer(p)).Fdb + 116 + 5*4))) {
		_sqlite3OomFault(tls, (*TParse)(unsafe.Pointer(p)).Fdb)
		return int32(SQLITE_NOMEM)
	}
	pNew = _sqlite3DbRealloc(tls, (*TParse)(unsafe.Pointer(p)).Fdb, (*TVdbe)(unsafe.Pointer(v)).FaOp, libc.Uint64FromInt64(nNew*int64(20)))
	if pNew != 0 {
		(*TParse)(unsafe.Pointer(p)).FszOpAlloc = _sqlite3DbMallocSize(tls, (*TParse)(unsafe.Pointer(p)).Fdb, pNew)
		(*TVdbe)(unsafe.Pointer(v)).FnOpAlloc = libc.Int32FromUint32(libc.Uint32FromInt32((*TParse)(unsafe.Pointer(p)).FszOpAlloc) / uint32(20))
		(*TVdbe)(unsafe.Pointer(v)).FaOp = pNew
	}
	if pNew != 0 {
		v2 = SQLITE_OK
	} else {
		v2 = int32(SQLITE_NOMEM)
	}
	return v2
}

// C documentation
//
//	/*
//	** The hex() function.  Interpret the argument as a blob.  Return
//	** a hexadecimal rendering as text.
//	*/
func _hexFunc(tls *libc.TLS, context uintptr, argc int32, argv uintptr) {
	var c uint8
	var i, n int32
	var pBlob, z, zHex, v1 uintptr
	_, _, _, _, _, _, _ = c, i, n, pBlob, z, zHex, v1
	_ = argc
	pBlob = Xsqlite3_value_blob(tls, **(**uintptr)(__ccgo_up(argv)))
	n = Xsqlite3_value_bytes(tls, **(**uintptr)(__ccgo_up(argv)))
	/* No encoding change */
	v1 = _contextMalloc(tls, context, int64(n)*int64(2)+int64(1))
	zHex = v1
	z = v1
	if zHex != 0 {
		i = 0
		for {
			if !(i < n) {
				break
			}
			c = **(**uint8)(__ccgo_up(pBlob))
			v1 = z
			z = z + 1
			**(**int8)(__ccgo_up(v1)) = _hexdigits[libc.Int32FromUint8(c)>>int32(4)&int32(0xf)]
			v1 = z
			z = z + 1
			**(**int8)(__ccgo_up(v1)) = _hexdigits[libc.Int32FromUint8(c)&int32(0xf)]
			goto _2
		_2:
			;
			i = i + 1
			pBlob = pBlob + 1
		}
		**(**int8)(__ccgo_up(z)) = 0
		Xsqlite3_result_text64(tls, context, zHex, libc.Uint64FromInt32(int32(z)-int32(zHex)), __ccgo_fp(Xsqlite3_free), uint8(SQLITE_UTF8_ZT))
	}
}

// C documentation
//
//	/*
//	** Term pTerm is guaranteed to be a WO_IN term. It may be a component term
//	** of a vector IN expression of the form "(x, y, ...) IN (SELECT ...)".
//	** This function checks to see if the term is compatible with an index
//	** column with affinity idxaff (one of the SQLITE_AFF_XYZ values). If so,
//	** it returns a pointer to the name of the collation sequence (e.g. "BINARY"
//	** or "NOCASE") used by the comparison in pTerm. If it is not compatible
//	** with affinity idxaff, NULL is returned.
//	*/
func _indexInAffinityOk(tls *libc.TLS, pParse uintptr, pTerm uintptr, idxaff Tu8) (r uintptr) {
	bp := tls.Alloc(64)
	defer tls.Free(64)
	var iField int32
	var pRet, pX, v1 uintptr
	var _ /* inexpr at bp+0 */ TExpr
	_, _, _, _ = iField, pRet, pX, v1
	pX = (*TWhereTerm)(unsafe.Pointer(pTerm)).FpExpr
	if _sqlite3ExprIsVector(tls, (*TExpr)(unsafe.Pointer(pX)).FpLeft) != 0 {
		iField = (*(*struct {
			FleftColumn int32
			FiField     int32
		})(unsafe.Pointer(pTerm + 24))).FiField - int32(1)
		(**(**TExpr)(__ccgo_up(bp))).Fflags = uint32(0)
		(**(**TExpr)(__ccgo_up(bp))).Fop = uint8(TK_EQ)
		(**(**TExpr)(__ccgo_up(bp))).FpLeft = (*(*TExprList_item)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer((*TExpr)(unsafe.Pointer(pX)).FpLeft + 20)) + 8 + uintptr(iField)*20))).FpExpr
		(**(**TExpr)(__ccgo_up(bp))).FpRight = (*(*TExprList_item)(unsafe.Pointer((*TSelect)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pX + 20)))).FpEList + 8 + uintptr(iField)*20))).FpExpr
		pX = bp
	}
	if _sqlite3IndexAffinityOk(tls, pX, libc.Int8FromUint8(idxaff)) != 0 {
		pRet = _sqlite3ExprCompareCollSeq(tls, pParse, pX)
		if pRet != 0 {
			v1 = (*TCollSeq)(unsafe.Pointer(pRet)).FzName
		} else {
			v1 = uintptr(unsafe.Pointer(&_sqlite3StrBINARY))
		}
		return v1
	}
	return uintptr(0)
}

// C documentation
//
//	/*
//	** Check to see if the given expression is a LIKE or GLOB operator that
//	** can be optimized using inequality constraints.  Return TRUE if it is
//	** so and false if not.
//	**
//	** In order for the operator to be optimizible, the RHS must be a string
//	** literal that does not begin with a wildcard.  The LHS must be a column
//	** that may only be NULL, a string, or a BLOB, never a number. (This means
//	** that virtual tables cannot participate in the LIKE optimization.)  The
//	** collating sequence for the column on the LHS must be appropriate for
//	** the operator.
//	*/
func _isLikeOrGlob(tls *libc.TLS, pParse uintptr, pExpr uintptr, ppPrefix uintptr, pisComplete uintptr, pnoCase uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var c, v1 Tu8
	var cnt, iCol, iFrom, iTo, isNum, op, r1, rc, v3 int32
	var db, pLeft, pList, pPrefix, pReprepare, pRight, pVal, v, z, zNew uintptr
	var _ /* rDummy at bp+8 */ float64
	var _ /* wc at bp+0 */ [4]Tu8
	var _ /* z2 at bp+4 */ uintptr
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = c, cnt, db, iCol, iFrom, iTo, isNum, op, pLeft, pList, pPrefix, pReprepare, pRight, pVal, r1, rc, v, z, zNew, v1, v3
	z = uintptr(0)                             /* Wildcard characters */
	db = (*TParse)(unsafe.Pointer(pParse)).Fdb /* Database connection */
	pVal = uintptr(0)                          /* Result code to return */
	if !(_sqlite3IsLikeFunction(tls, db, pExpr, pnoCase, bp) != 0) {
		return 0
	}
	pList = *(*uintptr)(unsafe.Pointer(pExpr + 20))
	pLeft = (*(*TExprList_item)(unsafe.Pointer(pList + 8 + 1*20))).FpExpr
	pRight = _sqlite3ExprSkipCollate(tls, (*(*TExprList_item)(unsafe.Pointer(pList + 8))).FpExpr)
	op = libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pRight)).Fop)
	if op == int32(TK_VARIABLE) && (*Tsqlite3)(unsafe.Pointer(db)).Fflags&uint64(SQLITE_EnableQPSG) == uint64(0) {
		pReprepare = (*TParse)(unsafe.Pointer(pParse)).FpReprepare
		iCol = int32((*TExpr)(unsafe.Pointer(pRight)).FiColumn)
		pVal = _sqlite3VdbeGetBoundValue(tls, pReprepare, iCol, uint8(SQLITE_AFF_BLOB))
		if pVal != 0 && Xsqlite3_value_type(tls, pVal) == int32(SQLITE_TEXT) {
			z = Xsqlite3_value_text(tls, pVal)
		}
		_sqlite3VdbeSetVarmask(tls, (*TParse)(unsafe.Pointer(pParse)).FpVdbe, iCol)
	} else {
		if op == int32(TK_STRING) {
			z = *(*uintptr)(unsafe.Pointer(pRight + 8))
		}
	}
	if z != 0 {
		/* Count the number of prefix bytes prior to the first wildcard,
		 ** U+fffd character, or malformed utf-8. If the underlying database
		 ** has a UTF16LE encoding, then only consider ASCII characters.  Note that
		 ** the encoding of z[] is UTF8 - we are dealing with only UTF8 here in this
		 ** code, but the database engine itself might be processing content using a
		 ** different encoding. */
		cnt = 0
		for {
			v1 = **(**Tu8)(__ccgo_up(z + uintptr(cnt)))
			c = v1
			if !(libc.Int32FromUint8(v1) != 0 && libc.Int32FromUint8(c) != libc.Int32FromUint8((**(**[4]Tu8)(__ccgo_up(bp)))[0]) && libc.Int32FromUint8(c) != libc.Int32FromUint8((**(**[4]Tu8)(__ccgo_up(bp)))[int32(1)]) && libc.Int32FromUint8(c) != libc.Int32FromUint8((**(**[4]Tu8)(__ccgo_up(bp)))[int32(2)])) {
				break
			}
			cnt = cnt + 1
			if libc.Int32FromUint8(c) == libc.Int32FromUint8((**(**[4]Tu8)(__ccgo_up(bp)))[int32(3)]) && libc.Int32FromUint8(**(**Tu8)(__ccgo_up(z + uintptr(cnt)))) > 0 && libc.Int32FromUint8(**(**Tu8)(__ccgo_up(z + uintptr(cnt)))) < int32(0x80) {
				cnt = cnt + 1
			} else {
				if libc.Int32FromUint8(c) >= int32(0x80) {
					**(**uintptr)(__ccgo_up(bp + 4)) = z + uintptr(cnt) - uintptr(1)
					if libc.Int32FromUint8(c) == int32(0xff) || _sqlite3Utf8Read(tls, bp+4) == uint32(0xfffd) || libc.Int32FromUint8((*Tsqlite3)(unsafe.Pointer(db)).Fenc) == int32(SQLITE_UTF16LE) {
						cnt = cnt - 1
						break
					} else {
						cnt = int32(**(**uintptr)(__ccgo_up(bp + 4))) - int32(z)
					}
				}
			}
		}
		/* The optimization is possible only if (1) the pattern does not begin
		 ** with a wildcard and if (2) the non-wildcard prefix does not end with
		 ** an (illegal 0xff) character, or (3) the pattern does not consist of
		 ** a single escape character. The second condition is necessary so
		 ** that we can increment the prefix key to find an upper bound for the
		 ** range search. The third is because the caller assumes that the pattern
		 ** consists of at least one character after all escapes have been
		 ** removed.  */
		if (cnt > int32(1) || cnt > 0 && libc.Int32FromUint8(**(**Tu8)(__ccgo_up(z))) != libc.Int32FromUint8((**(**[4]Tu8)(__ccgo_up(bp)))[int32(3)])) && int32(255) != libc.Int32FromUint8(**(**Tu8)(__ccgo_up(z + uintptr(cnt-int32(1))))) {
			/* A "complete" match if the pattern ends with "*" or "%" */
			**(**int32)(__ccgo_up(pisComplete)) = libc.BoolInt32(libc.Int32FromUint8(c) == libc.Int32FromUint8((**(**[4]Tu8)(__ccgo_up(bp)))[0]) && libc.Int32FromUint8(**(**Tu8)(__ccgo_up(z + uintptr(cnt+int32(1))))) == 0 && libc.Int32FromUint8((*Tsqlite3)(unsafe.Pointer(db)).Fenc) != int32(SQLITE_UTF16LE))
			/* Get the pattern prefix.  Remove all escapes from the prefix. */
			pPrefix = _sqlite3Expr(tls, db, int32(TK_STRING), z)
			if pPrefix != 0 {
				zNew = *(*uintptr)(unsafe.Pointer(pPrefix + 8))
				**(**int8)(__ccgo_up(zNew + uintptr(cnt))) = 0
				v3 = libc.Int32FromInt32(0)
				iTo = v3
				iFrom = v3
				for {
					if !(iFrom < cnt) {
						break
					}
					if int32(**(**int8)(__ccgo_up(zNew + uintptr(iFrom)))) == libc.Int32FromUint8((**(**[4]Tu8)(__ccgo_up(bp)))[int32(3)]) {
						iFrom = iFrom + 1
					}
					v3 = iTo
					iTo = iTo + 1
					**(**int8)(__ccgo_up(zNew + uintptr(v3))) = **(**int8)(__ccgo_up(zNew + uintptr(iFrom)))
					goto _2
				_2:
					;
					iFrom = iFrom + 1
				}
				**(**int8)(__ccgo_up(zNew + uintptr(iTo))) = 0
				/* If the LHS is not an ordinary column with TEXT affinity, then the
				 ** pattern prefix boundaries (both the start and end boundaries) must
				 ** not look like a number.  Otherwise the pattern might be treated as
				 ** a number, which will invalidate the LIKE optimization.
				 **
				 ** Getting this right has been a persistent source of bugs in the
				 ** LIKE optimization.  See, for example:
				 **    2018-09-10 https://sqlite.org/src/info/c94369cae9b561b1
				 **    2019-05-02 https://sqlite.org/src/info/b043a54c3de54b28
				 **    2019-06-10 https://sqlite.org/src/info/fd76310a5e843e07
				 **    2019-06-14 https://sqlite.org/src/info/ce8717f0885af975
				 **    2019-09-03 https://sqlite.org/src/info/0f0428096f17252a
				 */
				if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pLeft)).Fop) != int32(TK_COLUMN) || int32(_sqlite3ExprAffinity(tls, pLeft)) != int32(SQLITE_AFF_TEXT) || (*TExpr)(unsafe.Pointer(pLeft)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_WinFunc)|libc.Int32FromInt32(EP_Subrtn)) == uint32(0) && (*TExpr)(unsafe.Pointer(pLeft)).Fy.FpTab != 0 && libc.Int32FromUint8((*TTable)(unsafe.Pointer((*TExpr)(unsafe.Pointer(pLeft)).Fy.FpTab)).FeTabType) == int32(TABTYP_VTAB) {
					isNum = _sqlite3AtoF(tls, zNew, bp+8)
					if isNum <= 0 {
						if iTo == int32(1) && int32(**(**int8)(__ccgo_up(zNew))) == int32('-') {
							isNum = +libc.Int32FromInt32(1)
						} else {
							**(**int8)(__ccgo_up(zNew + uintptr(iTo-int32(1)))) = **(**int8)(__ccgo_up(zNew + uintptr(iTo-int32(1)))) + 1
							isNum = _sqlite3AtoF(tls, zNew, bp+8)
							**(**int8)(__ccgo_up(zNew + uintptr(iTo-int32(1)))) = **(**int8)(__ccgo_up(zNew + uintptr(iTo-int32(1)))) - 1
						}
					}
					if isNum > 0 {
						_sqlite3ExprDelete(tls, db, pPrefix)
						_sqlite3ValueFree(tls, pVal)
						return 0
					}
				}
			}
			**(**uintptr)(__ccgo_up(ppPrefix)) = pPrefix
			/* If the RHS pattern is a bound parameter, make arrangements to
			 ** reprepare the statement when that parameter is rebound */
			if op == int32(TK_VARIABLE) {
				v = (*TParse)(unsafe.Pointer(pParse)).FpVdbe
				_sqlite3VdbeSetVarmask(tls, v, int32((*TExpr)(unsafe.Pointer(pRight)).FiColumn))
				if **(**int32)(__ccgo_up(pisComplete)) != 0 && **(**int8)(__ccgo_up(*(*uintptr)(unsafe.Pointer(pRight + 8)) + 1)) != 0 {
					/* If the rhs of the LIKE expression is a variable, and the current
					 ** value of the variable means there is no need to invoke the LIKE
					 ** function, then no OP_Variable will be added to the program.
					 ** This causes problems for the sqlite3_bind_parameter_name()
					 ** API. To work around them, add a dummy OP_Variable here.
					 */
					r1 = _sqlite3GetTempReg(tls, pParse)
					_sqlite3ExprCodeTarget(tls, pParse, pRight, r1)
					_sqlite3VdbeChangeP3(tls, v, _sqlite3VdbeCurrentAddr(tls, v)-int32(1), 0)
					_sqlite3ReleaseTempReg(tls, pParse, r1)
				}
			}
		} else {
			z = uintptr(0)
		}
	}
	rc = libc.BoolInt32(z != uintptr(0))
	_sqlite3ValueFree(tls, pVal)
	return rc
}

// C documentation
//
//	/* Append the N-byte string in zIn to the end of the JsonString string
//	** under construction.  Enclose the string in double-quotes ("...") and
//	** escape any double-quotes or backslash characters contained within the
//	** string.
//	**
//	** This routine is a high-runner.  There is a measurable performance
//	** increase associated with unwinding the jsonIsOk[] loop.
//	*/
func _jsonAppendString(tls *libc.TLS, p uintptr, zIn uintptr, N Tu32) {
	var c Tu8
	var k Tu32
	var z, v2 uintptr
	var v1 Tu64
	_, _, _, _, _ = c, k, z, v1, v2
	z = zIn
	if z == uintptr(0) {
		return
	}
	if uint64(N)+(*TJsonString)(unsafe.Pointer(p)).FnUsed+uint64(2) >= (*TJsonString)(unsafe.Pointer(p)).FnAlloc && _jsonStringGrow(tls, p, N+uint32(2)) != 0 {
		return
	}
	v2 = p + 16
	v1 = *(*Tu64)(unsafe.Pointer(v2))
	*(*Tu64)(unsafe.Pointer(v2)) = *(*Tu64)(unsafe.Pointer(v2)) + 1
	**(**int8)(__ccgo_up((*TJsonString)(unsafe.Pointer(p)).FzBuf + uintptr(v1))) = int8('"')
	for int32(1) != 0 {
		k = uint32(0)
		/* The following while() is the 4-way unwound equivalent of
		 **
		 **     while( k<N && jsonIsOk[z[k]] ){ k++; }
		 */
		for int32(1) != 0 {
			if k+uint32(3) >= N {
				for k < N && _jsonIsOk[**(**Tu8)(__ccgo_up(z + uintptr(k)))] != 0 {
					k = k + 1
				}
				break
			}
			if !(_jsonIsOk[**(**Tu8)(__ccgo_up(z + uintptr(k)))] != 0) {
				break
			}
			if !(_jsonIsOk[**(**Tu8)(__ccgo_up(z + uintptr(k+uint32(1))))] != 0) {
				k = k + uint32(1)
				break
			}
			if !(_jsonIsOk[**(**Tu8)(__ccgo_up(z + uintptr(k+uint32(2))))] != 0) {
				k = k + uint32(2)
				break
			}
			if !(_jsonIsOk[**(**Tu8)(__ccgo_up(z + uintptr(k+uint32(3))))] != 0) {
				k = k + uint32(3)
				break
			} else {
				k = k + uint32(4)
			}
		}
		if k >= N {
			if k > uint32(0) {
				libc.Xmemcpy(tls, (*TJsonString)(unsafe.Pointer(p)).FzBuf+uintptr((*TJsonString)(unsafe.Pointer(p)).FnUsed), z, k)
				**(**Tu64)(__ccgo_up(p + 16)) += uint64(k)
			}
			break
		}
		if k > uint32(0) {
			libc.Xmemcpy(tls, (*TJsonString)(unsafe.Pointer(p)).FzBuf+uintptr((*TJsonString)(unsafe.Pointer(p)).FnUsed), z, k)
			**(**Tu64)(__ccgo_up(p + 16)) += uint64(k)
			z = z + uintptr(k)
			N = N - k
		}
		c = **(**Tu8)(__ccgo_up(z))
		if libc.Int32FromUint8(c) == int32('"') || libc.Int32FromUint8(c) == int32('\\') {
			if (*TJsonString)(unsafe.Pointer(p)).FnUsed+uint64(N)+uint64(3) > (*TJsonString)(unsafe.Pointer(p)).FnAlloc && _jsonStringGrow(tls, p, N+uint32(3)) != 0 {
				return
			}
			v2 = p + 16
			v1 = *(*Tu64)(unsafe.Pointer(v2))
			*(*Tu64)(unsafe.Pointer(v2)) = *(*Tu64)(unsafe.Pointer(v2)) + 1
			**(**int8)(__ccgo_up((*TJsonString)(unsafe.Pointer(p)).FzBuf + uintptr(v1))) = int8('\\')
			v2 = p + 16
			v1 = *(*Tu64)(unsafe.Pointer(v2))
			*(*Tu64)(unsafe.Pointer(v2)) = *(*Tu64)(unsafe.Pointer(v2)) + 1
			**(**int8)(__ccgo_up((*TJsonString)(unsafe.Pointer(p)).FzBuf + uintptr(v1))) = libc.Int8FromUint8(c)
		} else {
			if libc.Int32FromUint8(c) == int32('\'') {
				v2 = p + 16
				v1 = *(*Tu64)(unsafe.Pointer(v2))
				*(*Tu64)(unsafe.Pointer(v2)) = *(*Tu64)(unsafe.Pointer(v2)) + 1
				**(**int8)(__ccgo_up((*TJsonString)(unsafe.Pointer(p)).FzBuf + uintptr(v1))) = libc.Int8FromUint8(c)
			} else {
				if (*TJsonString)(unsafe.Pointer(p)).FnUsed+uint64(N)+uint64(7) > (*TJsonString)(unsafe.Pointer(p)).FnAlloc && _jsonStringGrow(tls, p, N+uint32(7)) != 0 {
					return
				}
				_jsonAppendControlChar(tls, p, c)
			}
		}
		z = z + 1
		N = N - 1
	}
	v2 = p + 16
	v1 = *(*Tu64)(unsafe.Pointer(v2))
	*(*Tu64)(unsafe.Pointer(v2)) = *(*Tu64)(unsafe.Pointer(v2)) + 1
	**(**int8)(__ccgo_up((*TJsonString)(unsafe.Pointer(p)).FzBuf + uintptr(v1))) = int8('"')
}

// C documentation
//
//	/* This helper routine for jsonLookupStep() populates pIns with
//	** binary data that is to be inserted into pParse.
//	**
//	** In the common case, pIns just points to pParse->aIns and pParse->nIns.
//	** But if the zPath of the original edit operation includes path elements
//	** that go deeper, additional substructure must be created.
//	**
//	** For example:
//	**
//	**     json_insert('{}', '$.a.b.c', 123);
//	**
//	** The search stops at '$.a'  But additional substructure must be
//	** created for the ".b.c" part of the patch so that the final result
//	** is:  {"a":{"b":{"c"::123}}}.  This routine populates pIns with
//	** the binary equivalent of {"b":{"c":123}} so that it can be inserted.
//	**
//	** The caller is responsible for resetting pIns when it has finished
//	** using the substructure.
//	*/
func _jsonCreateEditSubstructure(tls *libc.TLS, pParse uintptr, pIns uintptr, zTail uintptr) (r Tu32) {
	var rc int32
	var v1 uintptr
	_, _ = rc, v1
	libc.Xmemset(tls, pIns, 0, uint32(56))
	(*TJsonParse)(unsafe.Pointer(pIns)).Fdb = (*TJsonParse)(unsafe.Pointer(pParse)).Fdb
	if int32(**(**int8)(__ccgo_up(zTail))) == 0 {
		/* No substructure.  Just insert what is given in pParse. */
		(*TJsonParse)(unsafe.Pointer(pIns)).FaBlob = (*TJsonParse)(unsafe.Pointer(pParse)).FaIns
		(*TJsonParse)(unsafe.Pointer(pIns)).FnBlob = (*TJsonParse)(unsafe.Pointer(pParse)).FnIns
		rc = 0
	} else {
		/* Construct the binary substructure */
		(*TJsonParse)(unsafe.Pointer(pIns)).FnBlob = uint32(1)
		(*TJsonParse)(unsafe.Pointer(pIns)).FaBlob = uintptr(unsafe.Pointer(&_emptyObject)) + libc.BoolUintptr(int32(**(**int8)(__ccgo_up(zTail))) == int32('.'))
		(*TJsonParse)(unsafe.Pointer(pIns)).FeEdit = (*TJsonParse)(unsafe.Pointer(pParse)).FeEdit
		(*TJsonParse)(unsafe.Pointer(pIns)).FnIns = (*TJsonParse)(unsafe.Pointer(pParse)).FnIns
		(*TJsonParse)(unsafe.Pointer(pIns)).FaIns = (*TJsonParse)(unsafe.Pointer(pParse)).FaIns
		(*TJsonParse)(unsafe.Pointer(pIns)).FiDepth = libc.Uint16FromInt32(libc.Int32FromUint16((*TJsonParse)(unsafe.Pointer(pParse)).FiDepth) + int32(1))
		if libc.Int32FromUint16((*TJsonParse)(unsafe.Pointer(pIns)).FiDepth) >= int32(JSON_MAX_DEPTH) {
			return uint32(JSON_LOOKUP_TOODEEP)
		}
		rc = libc.Int32FromUint32(_jsonLookupStep(tls, pIns, uint32(0), zTail, uint32(0)))
		(*TJsonParse)(unsafe.Pointer(pParse)).FiDepth = (*TJsonParse)(unsafe.Pointer(pParse)).FiDepth - 1
		v1 = pParse + 35
		*(*Tu8)(unsafe.Pointer(v1)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v1))) | libc.Int32FromUint8((*TJsonParse)(unsafe.Pointer(pIns)).Foom))
	}
	return libc.Uint32FromInt32(rc) /* Error code only */
}

// C documentation
//
//	/* Return the value of a column */
func _jsonEachColumn(tls *libc.TLS, cur uintptr, ctx uintptr, iColumn int32) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var eType Tu8
	var i, i1, i2, j, n, n1 Tu32
	var nBase Tu64
	var p uintptr
	var _ /* x at bp+0 */ Ti64
	_, _, _, _, _, _, _, _, _ = eType, i, i1, i2, j, n, n1, nBase, p
	p = cur
	switch iColumn {
	case JEACH_KEY:
		if (*TJsonEachCursor)(unsafe.Pointer(p)).FnParent == uint32(0) {
			if (*TJsonEachCursor)(unsafe.Pointer(p)).FnRoot == uint32(1) {
				break
			}
			j = libc.Uint32FromInt32(_jsonEachPathLength(tls, p))
			n = (*TJsonEachCursor)(unsafe.Pointer(p)).FnRoot - j
			if n == uint32(0) {
				break
			} else {
				if int32(**(**int8)(__ccgo_up((*TJsonEachCursor)(unsafe.Pointer(p)).Fpath.FzBuf + uintptr(j)))) == int32('[') {
					_sqlite3Atoi64(tls, (*TJsonEachCursor)(unsafe.Pointer(p)).Fpath.FzBuf+uintptr(j+uint32(1)), bp, libc.Int32FromUint32(n-uint32(1)), uint8(SQLITE_UTF8))
					Xsqlite3_result_int64(tls, ctx, **(**Ti64)(__ccgo_up(bp)))
				} else {
					if int32(**(**int8)(__ccgo_up((*TJsonEachCursor)(unsafe.Pointer(p)).Fpath.FzBuf + uintptr(j+uint32(1))))) == int32('"') {
						Xsqlite3_result_text(tls, ctx, (*TJsonEachCursor)(unsafe.Pointer(p)).Fpath.FzBuf+uintptr(j+uint32(2)), libc.Int32FromUint32(n-uint32(3)), uintptr(-libc.Int32FromInt32(1)))
					} else {
						Xsqlite3_result_text(tls, ctx, (*TJsonEachCursor)(unsafe.Pointer(p)).Fpath.FzBuf+uintptr(j+uint32(1)), libc.Int32FromUint32(n-uint32(1)), uintptr(-libc.Int32FromInt32(1)))
					}
				}
			}
			break
		}
		if libc.Int32FromUint8((*TJsonEachCursor)(unsafe.Pointer(p)).FeType) == int32(JSONB_OBJECT) {
			_jsonReturnFromBlob(tls, p+168, (*TJsonEachCursor)(unsafe.Pointer(p)).Fi, ctx, int32(1))
		} else {
			Xsqlite3_result_int64(tls, ctx, (**(**TJsonParent)(__ccgo_up((*TJsonEachCursor)(unsafe.Pointer(p)).FaParent + uintptr((*TJsonEachCursor)(unsafe.Pointer(p)).FnParent-uint32(1))*24))).FiKey)
		}
	case int32(JEACH_VALUE):
		i = libc.Uint32FromInt32(_jsonSkipLabel(tls, p))
		_jsonReturnFromBlob(tls, p+168, i, ctx, libc.Int32FromUint8((*TJsonEachCursor)(unsafe.Pointer(p)).FeMode))
		if libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TJsonEachCursor)(unsafe.Pointer(p)).FsParse.FaBlob + uintptr(i))))&int32(0x0f) >= int32(JSONB_ARRAY) {
			Xsqlite3_result_subtype(tls, ctx, uint32(JSON_SUBTYPE))
		}
	case int32(JEACH_TYPE):
		i1 = libc.Uint32FromInt32(_jsonSkipLabel(tls, p))
		eType = libc.Uint8FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TJsonEachCursor)(unsafe.Pointer(p)).FsParse.FaBlob + uintptr(i1)))) & int32(0x0f))
		Xsqlite3_result_text(tls, ctx, _jsonbType[eType], -int32(1), libc.UintptrFromInt32(0))
	case int32(JEACH_ATOM):
		i2 = libc.Uint32FromInt32(_jsonSkipLabel(tls, p))
		if libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TJsonEachCursor)(unsafe.Pointer(p)).FsParse.FaBlob + uintptr(i2))))&int32(0x0f) < int32(JSONB_ARRAY) {
			_jsonReturnFromBlob(tls, p+168, i2, ctx, int32(1))
		}
	case int32(JEACH_ID):
		Xsqlite3_result_int64(tls, ctx, libc.Int64FromUint32((*TJsonEachCursor)(unsafe.Pointer(p)).Fi))
	case int32(JEACH_PARENT):
		if (*TJsonEachCursor)(unsafe.Pointer(p)).FnParent > uint32(0) && (*TJsonEachCursor)(unsafe.Pointer(p)).FbRecursive != 0 {
			Xsqlite3_result_int64(tls, ctx, libc.Int64FromUint32((**(**TJsonParent)(__ccgo_up((*TJsonEachCursor)(unsafe.Pointer(p)).FaParent + uintptr((*TJsonEachCursor)(unsafe.Pointer(p)).FnParent-uint32(1))*24))).FiHead))
		}
	case int32(JEACH_FULLKEY):
		nBase = (*TJsonEachCursor)(unsafe.Pointer(p)).Fpath.FnUsed
		if (*TJsonEachCursor)(unsafe.Pointer(p)).FnParent != 0 {
			_jsonAppendPathName(tls, p)
		}
		Xsqlite3_result_text64(tls, ctx, (*TJsonEachCursor)(unsafe.Pointer(p)).Fpath.FzBuf, (*TJsonEachCursor)(unsafe.Pointer(p)).Fpath.FnUsed, uintptr(-libc.Int32FromInt32(1)), uint8(SQLITE_UTF8))
		(*TJsonEachCursor)(unsafe.Pointer(p)).Fpath.FnUsed = nBase
	case int32(JEACH_PATH):
		n1 = libc.Uint32FromInt32(_jsonEachPathLength(tls, p))
		Xsqlite3_result_text64(tls, ctx, (*TJsonEachCursor)(unsafe.Pointer(p)).Fpath.FzBuf, uint64(n1), uintptr(-libc.Int32FromInt32(1)), uint8(SQLITE_UTF8))
	default:
		Xsqlite3_result_text(tls, ctx, (*TJsonEachCursor)(unsafe.Pointer(p)).Fpath.FzBuf, libc.Int32FromUint32((*TJsonEachCursor)(unsafe.Pointer(p)).FnRoot), libc.UintptrFromInt32(0))
	case int32(JEACH_JSON):
		if (*TJsonEachCursor)(unsafe.Pointer(p)).FsParse.FzJson == uintptr(0) {
			Xsqlite3_result_blob(tls, ctx, (*TJsonEachCursor)(unsafe.Pointer(p)).FsParse.FaBlob, libc.Int32FromUint32((*TJsonEachCursor)(unsafe.Pointer(p)).FsParse.FnBlob), uintptr(-libc.Int32FromInt32(1)))
		} else {
			Xsqlite3_result_text(tls, ctx, (*TJsonEachCursor)(unsafe.Pointer(p)).FsParse.FzJson, -int32(1), uintptr(-libc.Int32FromInt32(1)))
		}
		break
	}
	return SQLITE_OK
}

// C documentation
//
//	/* Length of the path for rowid==0 in bRecursive mode.
//	*/
func _jsonEachPathLength(tls *libc.TLS, p uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var cSaved int8
	var n, x Tu32
	var z uintptr
	var _ /* sz at bp+0 */ Tu32
	_, _, _, _ = cSaved, n, x, z
	n = uint32((*TJsonEachCursor)(unsafe.Pointer(p)).Fpath.FnUsed)
	z = (*TJsonEachCursor)(unsafe.Pointer(p)).Fpath.FzBuf
	if (*TJsonEachCursor)(unsafe.Pointer(p)).FiRowid == uint32(0) && (*TJsonEachCursor)(unsafe.Pointer(p)).FbRecursive != 0 && n >= uint32(2) {
		for n > uint32(1) {
			n = n - 1
			if int32(**(**int8)(__ccgo_up(z + uintptr(n)))) == int32('[') || int32(**(**int8)(__ccgo_up(z + uintptr(n)))) == int32('.') {
				**(**Tu32)(__ccgo_up(bp)) = uint32(0)
				cSaved = **(**int8)(__ccgo_up(z + uintptr(n)))
				**(**int8)(__ccgo_up(z + uintptr(n))) = 0
				x = _jsonLookupStep(tls, p+168, uint32(0), z+uintptr(1), uint32(0))
				**(**int8)(__ccgo_up(z + uintptr(n))) = cSaved
				if x >= uint32(JSON_LOOKUP_PATHERROR) {
					continue
				}
				if x+_jsonbPayloadSize(tls, p+168, x, bp) == (*TJsonEachCursor)(unsafe.Pointer(p)).Fi {
					break
				}
			}
		}
	}
	return libc.Int32FromUint32(n)
}

// C documentation
//
//	/*
//	** json_error_position(JSON)
//	**
//	** If the argument is NULL, return NULL
//	**
//	** If the argument is BLOB, do a full validity check and return non-zero
//	** if the check fails.  The return value is the approximate 1-based offset
//	** to the byte of the element that contains the first error.
//	**
//	** Otherwise interpret the argument is TEXT (even if it is numeric) and
//	** return the 1-based character position for where the parser first recognized
//	** that the input was not valid JSON, or return 0 if the input text looks
//	** ok.  JSON-5 extensions are accepted.
//	*/
func _jsonErrorFunc(tls *libc.TLS, ctx uintptr, argc int32, argv uintptr) {
	bp := tls.Alloc(64)
	defer tls.Free(64)
	var iErrPos Ti64
	var k Tu32
	var _ /* s at bp+0 */ TJsonParse
	_, _ = iErrPos, k
	iErrPos = 0
	_ = argc
	libc.Xmemset(tls, bp, 0, uint32(56))
	(**(**TJsonParse)(__ccgo_up(bp))).Fdb = Xsqlite3_context_db_handle(tls, ctx)
	if _jsonArgIsJsonb(tls, **(**uintptr)(__ccgo_up(argv)), bp) != 0 {
		iErrPos = libc.Int64FromUint32(_jsonbValidityCheck(tls, bp, uint32(0), (**(**TJsonParse)(__ccgo_up(bp))).FnBlob, uint32(1)))
	} else {
		(**(**TJsonParse)(__ccgo_up(bp))).FzJson = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv)))
		if (**(**TJsonParse)(__ccgo_up(bp))).FzJson == uintptr(0) {
			return
		} /* NULL input or OOM */
		(**(**TJsonParse)(__ccgo_up(bp))).FnJson = Xsqlite3_value_bytes(tls, **(**uintptr)(__ccgo_up(argv)))
		if _jsonConvertTextToBlob(tls, bp, uintptr(0)) != 0 {
			if (**(**TJsonParse)(__ccgo_up(bp))).Foom != 0 {
				iErrPos = int64(-int32(1))
			} else {
				/* Because s.oom is false */
				k = uint32(0)
				for {
					if !(k < (**(**TJsonParse)(__ccgo_up(bp))).FiErr && **(**int8)(__ccgo_up((**(**TJsonParse)(__ccgo_up(bp))).FzJson + uintptr(k))) != 0) {
						break
					}
					if int32(**(**int8)(__ccgo_up((**(**TJsonParse)(__ccgo_up(bp))).FzJson + uintptr(k))))&int32(0xc0) != int32(0x80) {
						iErrPos = iErrPos + 1
					}
					goto _1
				_1:
					;
					k = k + 1
				}
				iErrPos = iErrPos + 1
			}
		}
	}
	_jsonParseReset(tls, bp)
	if iErrPos < 0 {
		Xsqlite3_result_error_nomem(tls, ctx)
	} else {
		Xsqlite3_result_int64(tls, ctx, iErrPos)
	}
}

// C documentation
//
//	/* argv[0] is a BLOB that seems likely to be a JSONB.  Subsequent
//	** arguments come in pairs where each pair contains a JSON path and
//	** content to insert or set at that patch.  Do the updates
//	** and return the result.
//	**
//	** The specific operation is determined by eEdit, which can be one
//	** of JEDIT_INS, JEDIT_REPL, JEDIT_SET, or JEDIT_AINS.
//	*/
func _jsonInsertIntoBlob(tls *libc.TLS, ctx uintptr, argc int32, argv uintptr, eEdit int32) {
	bp := tls.Alloc(64)
	defer tls.Free(64)
	var flgs, i, v1 int32
	var p, zPath uintptr
	var rc Tu32
	var _ /* ax at bp+0 */ TJsonParse
	_, _, _, _, _, _ = flgs, i, p, rc, zPath, v1
	rc = uint32(0)
	zPath = uintptr(0)
	if argc == int32(1) {
		v1 = 0
	} else {
		v1 = int32(JSON_EDITABLE)
	}
	flgs = v1
	p = _jsonParseFuncArg(tls, ctx, **(**uintptr)(__ccgo_up(argv)), libc.Uint32FromInt32(flgs))
	if p == uintptr(0) {
		return
	}
	i = int32(1)
	for {
		if !(i < argc-int32(1)) {
			break
		}
		if Xsqlite3_value_type(tls, **(**uintptr)(__ccgo_up(argv + uintptr(i)*4))) == int32(SQLITE_NULL) {
			goto _2
		}
		zPath = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv + uintptr(i)*4)))
		if zPath == uintptr(0) {
			Xsqlite3_result_error_nomem(tls, ctx)
			_jsonParseFree(tls, p)
			return
		}
		if int32(**(**int8)(__ccgo_up(zPath))) != int32('$') {
			goto jsonInsertIntoBlob_patherror
		}
		if _jsonFunctionArgToBlob(tls, ctx, **(**uintptr)(__ccgo_up(argv + uintptr(i+int32(1))*4)), bp) != 0 {
			_jsonParseReset(tls, bp)
			_jsonParseFree(tls, p)
			return
		}
		if int32(**(**int8)(__ccgo_up(zPath + 1))) == 0 {
			if eEdit == int32(JEDIT_REPL) || eEdit == int32(JEDIT_SET) {
				_jsonBlobEdit(tls, p, uint32(0), (*TJsonParse)(unsafe.Pointer(p)).FnBlob, (**(**TJsonParse)(__ccgo_up(bp))).FaBlob, (**(**TJsonParse)(__ccgo_up(bp))).FnBlob)
			}
			rc = uint32(0)
		} else {
			(*TJsonParse)(unsafe.Pointer(p)).FeEdit = libc.Uint8FromInt32(eEdit)
			(*TJsonParse)(unsafe.Pointer(p)).FnIns = (**(**TJsonParse)(__ccgo_up(bp))).FnBlob
			(*TJsonParse)(unsafe.Pointer(p)).FaIns = (**(**TJsonParse)(__ccgo_up(bp))).FaBlob
			(*TJsonParse)(unsafe.Pointer(p)).Fdelta = 0
			(*TJsonParse)(unsafe.Pointer(p)).FiDepth = uint16(0)
			rc = _jsonLookupStep(tls, p, uint32(0), zPath+uintptr(1), uint32(0))
		}
		_jsonParseReset(tls, bp)
		if rc == uint32(JSON_LOOKUP_NOTFOUND) {
			goto _2
		}
		if rc >= uint32(JSON_LOOKUP_PATHERROR) {
			goto jsonInsertIntoBlob_patherror
		}
		goto _2
	_2:
		;
		i = i + int32(2)
	}
	_jsonReturnParse(tls, ctx, p)
	_jsonParseFree(tls, p)
	return
	goto jsonInsertIntoBlob_patherror
jsonInsertIntoBlob_patherror:
	;
	_jsonParseFree(tls, p)
	_jsonBadPathError(tls, ctx, zPath, libc.Int32FromUint32(rc))
	return
}

// C documentation
//
//	/*
//	** json_remove(JSON, PATH, ...)
//	**
//	** Remove the named elements from JSON and return the result.  malformed
//	** JSON or PATH arguments result in an error.
//	*/
func _jsonRemoveFunc(tls *libc.TLS, ctx uintptr, argc int32, argv uintptr) {
	var i, v1 int32
	var p, zPath uintptr
	var rc Tu32
	_, _, _, _, _ = i, p, rc, zPath, v1 /* The parse */
	zPath = uintptr(0)                  /* Subroutine return code */
	if argc < int32(1) {
		return
	}
	if argc > int32(1) {
		v1 = int32(JSON_EDITABLE)
	} else {
		v1 = 0
	}
	p = _jsonParseFuncArg(tls, ctx, **(**uintptr)(__ccgo_up(argv)), libc.Uint32FromInt32(v1))
	if p == uintptr(0) {
		return
	}
	i = int32(1)
	for {
		if !(i < argc) {
			break
		}
		zPath = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv + uintptr(i)*4)))
		if zPath == uintptr(0) {
			goto json_remove_done
		}
		if int32(**(**int8)(__ccgo_up(zPath))) != int32('$') {
			goto json_remove_patherror
		}
		if int32(**(**int8)(__ccgo_up(zPath + 1))) == 0 {
			/* json_remove(j,'$') returns NULL */
			goto json_remove_done
		}
		(*TJsonParse)(unsafe.Pointer(p)).FeEdit = uint8(JEDIT_DEL)
		(*TJsonParse)(unsafe.Pointer(p)).Fdelta = 0
		rc = _jsonLookupStep(tls, p, uint32(0), zPath+uintptr(1), uint32(0))
		if rc >= uint32(JSON_LOOKUP_PATHERROR) {
			if rc == uint32(JSON_LOOKUP_NOTFOUND) {
				goto _2 /* No-op */
			} else {
				_jsonBadPathError(tls, ctx, zPath, libc.Int32FromUint32(rc))
			}
			goto json_remove_done
		}
		goto _2
	_2:
		;
		i = i + 1
	}
	_jsonReturnParse(tls, ctx, p)
	_jsonParseFree(tls, p)
	return
	goto json_remove_patherror
json_remove_patherror:
	;
	_jsonBadPathError(tls, ctx, zPath, 0)
	goto json_remove_done
json_remove_done:
	;
	_jsonParseFree(tls, p)
	return
}

// C documentation
//
//	/*
//	** json_type(JSON)
//	** json_type(JSON, PATH)
//	**
//	** Return the top-level "type" of a JSON string.  json_type() raises an
//	** error if either the JSON or PATH inputs are not well-formed.
//	*/
func _jsonTypeFunc(tls *libc.TLS, ctx uintptr, argc int32, argv uintptr) {
	var i Tu32
	var p, zPath uintptr
	_, _, _ = i, p, zPath /* The parse */
	zPath = uintptr(0)
	p = _jsonParseFuncArg(tls, ctx, **(**uintptr)(__ccgo_up(argv)), uint32(0))
	if p == uintptr(0) {
		return
	}
	if argc == int32(2) {
		zPath = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv + 1*4)))
		if zPath == uintptr(0) {
			goto json_type_done
		}
		if int32(**(**int8)(__ccgo_up(zPath))) != int32('$') {
			_jsonBadPathError(tls, ctx, zPath, 0)
			goto json_type_done
		}
		i = _jsonLookupStep(tls, p, uint32(0), zPath+uintptr(1), uint32(0))
		if i >= uint32(JSON_LOOKUP_PATHERROR) {
			if i == uint32(JSON_LOOKUP_NOTFOUND) {
				/* no-op */
			} else {
				_jsonBadPathError(tls, ctx, zPath, libc.Int32FromUint32(i))
			}
			goto json_type_done
		}
	} else {
		i = uint32(0)
	}
	Xsqlite3_result_text(tls, ctx, _jsonbType[libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TJsonParse)(unsafe.Pointer(p)).FaBlob + uintptr(i))))&int32(0x0f)], -int32(1), libc.UintptrFromInt32(0))
	goto json_type_done
json_type_done:
	;
	_jsonParseFree(tls, p)
}

// C documentation
//
//	/*
//	** Do a memory allocation with statistics and alarms.  Assume the
//	** lock is already held.
//	*/
func _mallocWithAlarm(tls *libc.TLS, n int32, pp uintptr) {
	var nFull int32
	var nUsed Tsqlite3_int64
	var p uintptr
	_, _, _ = nFull, nUsed, p
	/* In Firefox (circa 2017-02-08), xRoundup() is remapped to an internal
	 ** implementation of malloc_good_size(), which must be called in debug
	 ** mode and specifically when the DMD "Dark Matter Detector" is enabled
	 ** or else a crash results.  Hence, do not attempt to optimize out the
	 ** following xRoundup() call. */
	nFull = (*(*func(*libc.TLS, int32) int32)(unsafe.Pointer(&struct{ uintptr }{_sqlite3Config.Fm.FxRoundup})))(tls, n)
	_sqlite3StatusHighwater(tls, int32(SQLITE_STATUS_MALLOC_SIZE), n)
	if _mem0.FalarmThreshold > 0 {
		nUsed = _sqlite3StatusValue(tls, SQLITE_STATUS_MEMORY_USED)
		if nUsed >= _mem0.FalarmThreshold-int64(nFull) {
			libc.AtomicStoreNInt32(uintptr(unsafe.Pointer(&_mem0))+20, libc.Int32FromInt32(1), libc.Int32FromInt32(__ATOMIC_RELAXED))
			_sqlite3MallocAlarm(tls, nFull)
			if _mem0.FhardLimit != 0 {
				nUsed = _sqlite3StatusValue(tls, SQLITE_STATUS_MEMORY_USED)
				if nUsed >= _mem0.FhardLimit-int64(nFull) {
					**(**uintptr)(__ccgo_up(pp)) = uintptr(0)
					return
				}
			}
		} else {
			libc.AtomicStoreNInt32(uintptr(unsafe.Pointer(&_mem0))+20, libc.Int32FromInt32(0), libc.Int32FromInt32(__ATOMIC_RELAXED))
		}
	}
	p = (*(*func(*libc.TLS, int32) uintptr)(unsafe.Pointer(&struct{ uintptr }{_sqlite3Config.Fm.FxMalloc})))(tls, nFull)
	if p == uintptr(0) && _mem0.FalarmThreshold > 0 {
		_sqlite3MallocAlarm(tls, nFull)
		p = (*(*func(*libc.TLS, int32) uintptr)(unsafe.Pointer(&struct{ uintptr }{_sqlite3Config.Fm.FxMalloc})))(tls, nFull)
	}
	if p != 0 {
		nFull = _sqlite3MallocSize(tls, p)
		_sqlite3StatusUp(tls, SQLITE_STATUS_MEMORY_USED, nFull)
		_sqlite3StatusUp(tls, int32(SQLITE_STATUS_MALLOC_COUNT), int32(1))
	}
	**(**uintptr)(__ccgo_up(pp)) = p
}

// C documentation
//
//	/*
//	** Open an mem file handle.
//	*/
func _memdbOpen(tls *libc.TLS, pVfs uintptr, zName uintptr, pFd uintptr, flags int32, pOutFlags uintptr) (r int32) {
	var apNew, p, pFile, pVfsMutex, v3 uintptr
	var i, szName, v2 int32
	_, _, _, _, _, _, _, _ = apNew, i, p, pFile, pVfsMutex, szName, v2, v3
	pFile = pFd
	p = uintptr(0)
	_ = pVfs
	libc.Xmemset(tls, pFile, 0, uint32(12))
	szName = _sqlite3Strlen30(tls, zName)
	if szName > int32(1) && (int32(**(**int8)(__ccgo_up(zName))) == int32('/') || int32(**(**int8)(__ccgo_up(zName))) == int32('\\')) {
		pVfsMutex = _sqlite3MutexAlloc(tls, int32(SQLITE_MUTEX_STATIC_VFS1))
		Xsqlite3_mutex_enter(tls, pVfsMutex)
		i = 0
		for {
			if !(i < _memdb_g.FnMemStore) {
				break
			}
			if libc.Xstrcmp(tls, (*TMemStore)(unsafe.Pointer(**(**uintptr)(__ccgo_up(_memdb_g.FapMemStore + uintptr(i)*4)))).FzFName, zName) == 0 {
				p = **(**uintptr)(__ccgo_up(_memdb_g.FapMemStore + uintptr(i)*4))
				break
			}
			goto _1
		_1:
			;
			i = i + 1
		}
		if p == uintptr(0) {
			p = _sqlite3Malloc(tls, libc.Uint64FromInt64(int64(56)+int64(szName)+int64(3)))
			if p == uintptr(0) {
				Xsqlite3_mutex_leave(tls, pVfsMutex)
				return int32(SQLITE_NOMEM)
			}
			apNew = _sqlite3Realloc(tls, _memdb_g.FapMemStore, libc.Uint64FromInt64(int64(4)*(int64(1)+int64(_memdb_g.FnMemStore))))
			if apNew == uintptr(0) {
				Xsqlite3_free(tls, p)
				Xsqlite3_mutex_leave(tls, pVfsMutex)
				return int32(SQLITE_NOMEM)
			}
			v3 = uintptr(unsafe.Pointer(&_memdb_g))
			v2 = *(*int32)(unsafe.Pointer(v3))
			*(*int32)(unsafe.Pointer(v3)) = *(*int32)(unsafe.Pointer(v3)) + 1
			**(**uintptr)(__ccgo_up(apNew + uintptr(v2)*4)) = p
			_memdb_g.FapMemStore = apNew
			libc.Xmemset(tls, p, 0, uint32(56))
			(*TMemStore)(unsafe.Pointer(p)).FmFlags = libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_DESERIALIZE_RESIZEABLE) | libc.Int32FromInt32(SQLITE_DESERIALIZE_FREEONCLOSE))
			(*TMemStore)(unsafe.Pointer(p)).FszMax = _sqlite3Config.FmxMemdbSize
			(*TMemStore)(unsafe.Pointer(p)).FzFName = p + 1*56
			libc.Xmemcpy(tls, (*TMemStore)(unsafe.Pointer(p)).FzFName, zName, libc.Uint32FromInt32(szName+int32(1)))
			(*TMemStore)(unsafe.Pointer(p)).FpMutex = Xsqlite3_mutex_alloc(tls, SQLITE_MUTEX_FAST)
			if (*TMemStore)(unsafe.Pointer(p)).FpMutex == uintptr(0) {
				_memdb_g.FnMemStore = _memdb_g.FnMemStore - 1
				Xsqlite3_free(tls, p)
				Xsqlite3_mutex_leave(tls, pVfsMutex)
				return int32(SQLITE_NOMEM)
			}
			(*TMemStore)(unsafe.Pointer(p)).FnRef = int32(1)
			_memdbEnter(tls, p)
		} else {
			_memdbEnter(tls, p)
			(*TMemStore)(unsafe.Pointer(p)).FnRef = (*TMemStore)(unsafe.Pointer(p)).FnRef + 1
		}
		Xsqlite3_mutex_leave(tls, pVfsMutex)
	} else {
		p = _sqlite3Malloc(tls, uint64(56))
		if p == uintptr(0) {
			return int32(SQLITE_NOMEM)
		}
		libc.Xmemset(tls, p, 0, uint32(56))
		(*TMemStore)(unsafe.Pointer(p)).FmFlags = libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_DESERIALIZE_RESIZEABLE) | libc.Int32FromInt32(SQLITE_DESERIALIZE_FREEONCLOSE))
		(*TMemStore)(unsafe.Pointer(p)).FszMax = _sqlite3Config.FmxMemdbSize
	}
	(*TMemFile)(unsafe.Pointer(pFile)).FpStore = p
	if pOutFlags != uintptr(0) {
		**(**int32)(__ccgo_up(pOutFlags)) = flags | int32(SQLITE_OPEN_MEMORY)
	}
	(*Tsqlite3_file)(unsafe.Pointer(pFd)).FpMethods = uintptr(unsafe.Pointer(&_memdb_io_methods))
	_memdbLeave(tls, p)
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** Flush the contents of memory to a real file on disk.
//	*/
func _memjrnlCreateFile(tls *libc.TLS, p uintptr) (r int32) {
	var copy1 TMemJournal
	var iOff Ti64
	var nChunk, rc int32
	var pIter, pReal uintptr
	_, _, _, _, _, _ = copy1, iOff, nChunk, pIter, pReal, rc
	pReal = p
	copy1 = **(**TMemJournal)(__ccgo_up(p))
	libc.Xmemset(tls, p, 0, uint32(52))
	rc = _sqlite3OsOpen(tls, copy1.FpVfs, copy1.FzJournal, pReal, copy1.Fflags, uintptr(0))
	if rc == SQLITE_OK {
		nChunk = copy1.FnChunkSize
		iOff = 0
		pIter = copy1.FpFirst
		for {
			if !(pIter != 0) {
				break
			}
			if iOff+int64(nChunk) > copy1.Fendpoint.FiOffset {
				nChunk = int32(copy1.Fendpoint.FiOffset - iOff)
			}
			rc = _sqlite3OsWrite(tls, pReal, pIter+4, nChunk, iOff)
			if rc != 0 {
				break
			}
			iOff = iOff + int64(nChunk)
			goto _1
		_1:
			;
			pIter = (*TFileChunk)(unsafe.Pointer(pIter)).FpNext
		}
		if rc == SQLITE_OK {
			/* No error has occurred. Free the in-memory buffers. */
			_memjrnlFreeChunks(tls, copy1.FpFirst)
		}
	}
	if rc != SQLITE_OK {
		/* If an error occurred while creating or writing to the file, restore
		 ** the original before returning. This way, SQLite uses the in-memory
		 ** journal data to roll back changes made to the internal page-cache
		 ** before this function was called.  */
		_sqlite3OsClose(tls, pReal)
		**(**TMemJournal)(__ccgo_up(p)) = copy1
	}
	return rc
}

// C documentation
//
//	/*
//	** Move the cursor down to a new child page.  The newPgno argument is the
//	** page number of the child page to move to.
//	**
//	** This function returns SQLITE_CORRUPT if the page-header flags field of
//	** the new child page does not match the flags field of the parent (i.e.
//	** if an intkey page appears to be the parent of a non-intkey page, or
//	** vice-versa).
//	*/
func _moveToChild(tls *libc.TLS, pCur uintptr, newPgno Tu32) (r int32) {
	var rc int32
	var v1 uintptr
	var v2 Ti8
	_, _, _ = rc, v1, v2
	if int32((*TBtCursor)(unsafe.Pointer(pCur)).FiPage) >= libc.Int32FromInt32(BTCURSOR_MAX_DEPTH)-libc.Int32FromInt32(1) {
		return _sqlite3CorruptError(tls, int32(78598))
	}
	(*TBtCursor)(unsafe.Pointer(pCur)).Finfo.FnSize = uint16(0)
	v1 = pCur + 1
	*(*Tu8)(unsafe.Pointer(v1)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v1))) & ^(libc.Int32FromInt32(BTCF_ValidNKey) | libc.Int32FromInt32(BTCF_ValidOvfl)))
	**(**Tu16)(__ccgo_up(pCur + 64 + uintptr((*TBtCursor)(unsafe.Pointer(pCur)).FiPage)*2)) = (*TBtCursor)(unsafe.Pointer(pCur)).Fix
	**(**uintptr)(__ccgo_up(pCur + 112 + uintptr((*TBtCursor)(unsafe.Pointer(pCur)).FiPage)*4)) = (*TBtCursor)(unsafe.Pointer(pCur)).FpPage
	(*TBtCursor)(unsafe.Pointer(pCur)).Fix = uint16(0)
	(*TBtCursor)(unsafe.Pointer(pCur)).FiPage = (*TBtCursor)(unsafe.Pointer(pCur)).FiPage + 1
	rc = _getAndInitPage(tls, (*TBtCursor)(unsafe.Pointer(pCur)).FpBt, newPgno, pCur+108, libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCur)).FcurPagerFlags))
	if rc == SQLITE_OK && (libc.Int32FromUint16((*TMemPage)(unsafe.Pointer((*TBtCursor)(unsafe.Pointer(pCur)).FpPage)).FnCell) < int32(1) || libc.Int32FromUint8((*TMemPage)(unsafe.Pointer((*TBtCursor)(unsafe.Pointer(pCur)).FpPage)).FintKey) != libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCur)).FcurIntKey)) {
		_releasePage(tls, (*TBtCursor)(unsafe.Pointer(pCur)).FpPage)
		rc = _sqlite3CorruptError(tls, int32(78612))
	}
	if rc != 0 {
		v1 = pCur + 60
		*(*Ti8)(unsafe.Pointer(v1)) = *(*Ti8)(unsafe.Pointer(v1)) - 1
		v2 = *(*Ti8)(unsafe.Pointer(v1))
		(*TBtCursor)(unsafe.Pointer(pCur)).FpPage = **(**uintptr)(__ccgo_up(pCur + 112 + uintptr(v2)*4))
	}
	return rc
}

// C documentation
//
//	/*
//	** Move the cursor up to the parent page.
//	**
//	** pCur->idx is set to the cell index that contains the pointer
//	** to the page we are coming from.  If we are coming from the
//	** right-most child page then pCur->idx is set to one more than
//	** the largest cell index.
//	*/
func _moveToParent(tls *libc.TLS, pCur uintptr) {
	var pLeaf, v1 uintptr
	var v2 Ti8
	_, _, _ = pLeaf, v1, v2
	(*TBtCursor)(unsafe.Pointer(pCur)).Finfo.FnSize = uint16(0)
	v1 = pCur + 1
	*(*Tu8)(unsafe.Pointer(v1)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v1))) & ^(libc.Int32FromInt32(BTCF_ValidNKey) | libc.Int32FromInt32(BTCF_ValidOvfl)))
	(*TBtCursor)(unsafe.Pointer(pCur)).Fix = **(**Tu16)(__ccgo_up(pCur + 64 + uintptr(int32((*TBtCursor)(unsafe.Pointer(pCur)).FiPage)-int32(1))*2))
	pLeaf = (*TBtCursor)(unsafe.Pointer(pCur)).FpPage
	v1 = pCur + 60
	*(*Ti8)(unsafe.Pointer(v1)) = *(*Ti8)(unsafe.Pointer(v1)) - 1
	v2 = *(*Ti8)(unsafe.Pointer(v1))
	(*TBtCursor)(unsafe.Pointer(pCur)).FpPage = **(**uintptr)(__ccgo_up(pCur + 112 + uintptr(v2)*4))
	_releasePageNotNull(tls, pLeaf)
}

// C documentation
//
//	/*
//	** Move the cursor to point to the root page of its b-tree structure.
//	**
//	** If the table has a virtual root page, then the cursor is moved to point
//	** to the virtual root page instead of the actual root page. A table has a
//	** virtual root page when the actual root page contains no cells and a
//	** single child page. This can only happen with the table rooted at page 1.
//	**
//	** If the b-tree structure is empty, the cursor state is set to
//	** CURSOR_INVALID and this routine returns SQLITE_EMPTY. Otherwise,
//	** the cursor is set to point to the first cell located on the root
//	** (or virtual root) page and the cursor state is set to CURSOR_VALID.
//	**
//	** If this function returns successfully, it may be assumed that the
//	** page-header flags indicate that the [virtual] root-page is the expected
//	** kind of b-tree page (i.e. if when opening the cursor the caller did not
//	** specify a KeyInfo structure the flags byte is set to 0x05 or 0x0D,
//	** indicating a table b-tree, or if the caller did specify a KeyInfo
//	** structure the flags byte is set to 0x02 or 0x0A, indicating an index
//	** b-tree).
//	*/
func _moveToRoot(tls *libc.TLS, pCur uintptr) (r int32) {
	var pRoot, v2 uintptr
	var rc int32
	var subpage TPgno
	var v1 Ti8
	_, _, _, _, _ = pRoot, rc, subpage, v1, v2
	rc = SQLITE_OK
	if int32((*TBtCursor)(unsafe.Pointer(pCur)).FiPage) >= 0 {
		if (*TBtCursor)(unsafe.Pointer(pCur)).FiPage != 0 {
			_releasePageNotNull(tls, (*TBtCursor)(unsafe.Pointer(pCur)).FpPage)
			for {
				v2 = pCur + 60
				*(*Ti8)(unsafe.Pointer(v2)) = *(*Ti8)(unsafe.Pointer(v2)) - 1
				v1 = *(*Ti8)(unsafe.Pointer(v2))
				if !(v1 != 0) {
					break
				}
				_releasePageNotNull(tls, **(**uintptr)(__ccgo_up(pCur + 112 + uintptr((*TBtCursor)(unsafe.Pointer(pCur)).FiPage)*4)))
			}
			v2 = **(**uintptr)(__ccgo_up(pCur + 112))
			(*TBtCursor)(unsafe.Pointer(pCur)).FpPage = v2
			pRoot = v2
			goto skip_init
		}
	} else {
		if (*TBtCursor)(unsafe.Pointer(pCur)).FpgnoRoot == uint32(0) {
			(*TBtCursor)(unsafe.Pointer(pCur)).FeState = uint8(CURSOR_INVALID)
			return int32(SQLITE_EMPTY)
		} else {
			if libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCur)).FeState) >= int32(CURSOR_REQUIRESEEK) {
				if libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCur)).FeState) == int32(CURSOR_FAULT) {
					return (*TBtCursor)(unsafe.Pointer(pCur)).FskipNext
				}
				_sqlite3BtreeClearCursor(tls, pCur)
			}
			rc = _getAndInitPage(tls, (*TBtCursor)(unsafe.Pointer(pCur)).FpBt, (*TBtCursor)(unsafe.Pointer(pCur)).FpgnoRoot, pCur+108, libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCur)).FcurPagerFlags))
			if rc != SQLITE_OK {
				(*TBtCursor)(unsafe.Pointer(pCur)).FeState = uint8(CURSOR_INVALID)
				return rc
			}
			(*TBtCursor)(unsafe.Pointer(pCur)).FiPage = 0
			(*TBtCursor)(unsafe.Pointer(pCur)).FcurIntKey = (*TMemPage)(unsafe.Pointer((*TBtCursor)(unsafe.Pointer(pCur)).FpPage)).FintKey
		}
	}
	pRoot = (*TBtCursor)(unsafe.Pointer(pCur)).FpPage
	/* If pCur->pKeyInfo is not NULL, then the caller that opened this cursor
	 ** expected to open it on an index b-tree. Otherwise, if pKeyInfo is
	 ** NULL, the caller expects a table b-tree. If this is not the case,
	 ** return an SQLITE_CORRUPT error.
	 **
	 ** Earlier versions of SQLite assumed that this test could not fail
	 ** if the root page was already loaded when this function was called (i.e.
	 ** if pCur->iPage>=0). But this is not so if the database is corrupted
	 ** in such a way that page pRoot is linked into a second b-tree table
	 ** (or the freelist).  */
	if libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pRoot)).FisInit) == 0 || libc.BoolInt32((*TBtCursor)(unsafe.Pointer(pCur)).FpKeyInfo == uintptr(0)) != libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pRoot)).FintKey) {
		return _sqlite3CorruptError(tls, int32(78747))
	}
	goto skip_init
skip_init:
	;
	(*TBtCursor)(unsafe.Pointer(pCur)).Fix = uint16(0)
	(*TBtCursor)(unsafe.Pointer(pCur)).Finfo.FnSize = uint16(0)
	v2 = pCur + 1
	*(*Tu8)(unsafe.Pointer(v2)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v2))) & ^(libc.Int32FromInt32(BTCF_AtLast) | libc.Int32FromInt32(BTCF_ValidNKey) | libc.Int32FromInt32(BTCF_ValidOvfl)))
	if libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pRoot)).FnCell) > 0 {
		(*TBtCursor)(unsafe.Pointer(pCur)).FeState = uint8(CURSOR_VALID)
	} else {
		if !((*TMemPage)(unsafe.Pointer(pRoot)).Fleaf != 0) {
			if (*TMemPage)(unsafe.Pointer(pRoot)).Fpgno != uint32(1) {
				return _sqlite3CorruptError(tls, int32(78759))
			}
			subpage = _sqlite3Get4byte(tls, (*TMemPage)(unsafe.Pointer(pRoot)).FaData+uintptr(libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pRoot)).FhdrOffset)+int32(8)))
			(*TBtCursor)(unsafe.Pointer(pCur)).FeState = uint8(CURSOR_VALID)
			rc = _moveToChild(tls, pCur, subpage)
		} else {
			(*TBtCursor)(unsafe.Pointer(pCur)).FeState = uint8(CURSOR_INVALID)
			rc = int32(SQLITE_EMPTY)
		}
	}
	return rc
}

// C documentation
//
//	/*
//	** Remove node pNode from the node hash table.
//	*/
func _nodeHashDelete(tls *libc.TLS, pRtree uintptr, pNode uintptr) {
	var pp uintptr
	_ = pp
	if (*TRtreeNode)(unsafe.Pointer(pNode)).FiNode != 0 {
		pp = pRtree + 116 + uintptr(_nodeHash(tls, (*TRtreeNode)(unsafe.Pointer(pNode)).FiNode))*4
		for {
			if !(**(**uintptr)(__ccgo_up(pp)) != pNode) {
				break
			}
			goto _1
		_1:
			;
			pp = **(**uintptr)(__ccgo_up(pp)) + 24
		}
		**(**uintptr)(__ccgo_up(pp)) = (*TRtreeNode)(unsafe.Pointer(pNode)).FpNext
		(*TRtreeNode)(unsafe.Pointer(pNode)).FpNext = uintptr(0)
	}
}

// C documentation
//
//	/*
//	** Add node pNode to the node hash table.
//	*/
func _nodeHashInsert(tls *libc.TLS, pRtree uintptr, pNode uintptr) {
	var iHash int32
	_ = iHash
	iHash = libc.Int32FromUint32(_nodeHash(tls, (*TRtreeNode)(unsafe.Pointer(pNode)).FiNode))
	(*TRtreeNode)(unsafe.Pointer(pNode)).FpNext = **(**uintptr)(__ccgo_up(pRtree + 116 + uintptr(iHash)*4))
	**(**uintptr)(__ccgo_up(pRtree + 116 + uintptr(iHash)*4)) = pNode
}

// C documentation
//
//	/*
//	** Search the node hash table for node iNode. If found, return a pointer
//	** to it. Otherwise, return 0.
//	*/
func _nodeHashLookup(tls *libc.TLS, pRtree uintptr, iNode Ti64) (r uintptr) {
	var p uintptr
	_ = p
	p = **(**uintptr)(__ccgo_up(pRtree + 116 + uintptr(_nodeHash(tls, iNode))*4))
	for {
		if !(p != 0 && (*TRtreeNode)(unsafe.Pointer(p)).FiNode != iNode) {
			break
		}
		goto _1
	_1:
		;
		p = (*TRtreeNode)(unsafe.Pointer(p)).FpNext
	}
	return p
}

// C documentation
//
//	/*
//	** Allocate and return new r-tree node. Initially, (RtreeNode.iNode==0),
//	** indicating that node has not yet been assigned a node number. It is
//	** assigned a node number when nodeWrite() is called to write the
//	** node contents out to the database.
//	*/
func _nodeNew(tls *libc.TLS, pRtree uintptr, pParent uintptr) (r uintptr) {
	var pNode uintptr
	_ = pNode
	pNode = Xsqlite3_malloc64(tls, uint64(uint32(28)+libc.Uint32FromInt32((*TRtree)(unsafe.Pointer(pRtree)).FiNodeSize)))
	if pNode != 0 {
		libc.Xmemset(tls, pNode, 0, uint32(28)+libc.Uint32FromInt32((*TRtree)(unsafe.Pointer(pRtree)).FiNodeSize))
		(*TRtreeNode)(unsafe.Pointer(pNode)).FzData = pNode + 1*28
		(*TRtreeNode)(unsafe.Pointer(pNode)).FnRef = int32(1)
		(*TRtree)(unsafe.Pointer(pRtree)).FnNodeRef = (*TRtree)(unsafe.Pointer(pRtree)).FnNodeRef + 1
		(*TRtreeNode)(unsafe.Pointer(pNode)).FpParent = pParent
		(*TRtreeNode)(unsafe.Pointer(pNode)).FisDirty = int32(1)
		_nodeReference(tls, pParent)
	}
	return pNode
}

// C documentation
//
//	/*
//	** Write page pPg onto the end of the rollback journal.
//	*/
func _pagerAddPageToRollbackJournal(tls *libc.TLS, pPg uintptr) (r int32) {
	var cksum Tu32
	var iOff Ti64
	var pData2, pPager, v1 uintptr
	var rc int32
	_, _, _, _, _, _ = cksum, iOff, pData2, pPager, rc, v1
	pPager = (*TPgHdr)(unsafe.Pointer(pPg)).FpPager
	iOff = (*TPager)(unsafe.Pointer(pPager)).FjournalOff
	/* We should never write to the journal file the page that
	 ** contains the database locks.  The following assert verifies
	 ** that we do not. */
	pData2 = (*TPgHdr)(unsafe.Pointer(pPg)).FpData
	cksum = _pager_cksum(tls, pPager, pData2)
	/* Even if an IO or diskfull error occurs while journalling the
	 ** page in the block above, set the need-sync flag for the page.
	 ** Otherwise, when the transaction is rolled back, the logic in
	 ** playback_one_page() will think that the page needs to be restored
	 ** in the database file. And if an IO error occurs while doing so,
	 ** then corruption may follow.
	 */
	v1 = pPg + 28
	*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) | libc.Int32FromInt32(PGHDR_NEED_SYNC))
	rc = _write32bits(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd, iOff, (*TPgHdr)(unsafe.Pointer(pPg)).Fpgno)
	if rc != SQLITE_OK {
		return rc
	}
	rc = _sqlite3OsWrite(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd, pData2, int32((*TPager)(unsafe.Pointer(pPager)).FpageSize), iOff+int64(4))
	if rc != SQLITE_OK {
		return rc
	}
	rc = _write32bits(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd, iOff+(*TPager)(unsafe.Pointer(pPager)).FpageSize+int64(4), cksum)
	if rc != SQLITE_OK {
		return rc
	}
	**(**Ti64)(__ccgo_up(pPager + 76)) += int64(8) + (*TPager)(unsafe.Pointer(pPager)).FpageSize
	(*TPager)(unsafe.Pointer(pPager)).FnRec = (*TPager)(unsafe.Pointer(pPager)).FnRec + 1
	rc = _sqlite3BitvecSet(tls, (*TPager)(unsafe.Pointer(pPager)).FpInJournal, (*TPgHdr)(unsafe.Pointer(pPg)).Fpgno)
	rc = rc | _addToSavepointBitvecs(tls, pPager, (*TPgHdr)(unsafe.Pointer(pPg)).Fpgno)
	return rc
}

// C documentation
//
//	/*
//	** Call sqlite3WalOpen() to open the WAL handle. If the pager is in
//	** exclusive-locking mode when this function is called, take an EXCLUSIVE
//	** lock on the database file and use heap-memory to store the wal-index
//	** in. Otherwise, use the normal shared-memory.
//	*/
func _pagerOpenWal(tls *libc.TLS, pPager uintptr) (r int32) {
	var rc int32
	_ = rc
	rc = SQLITE_OK
	/* If the pager is already in exclusive-mode, the WAL module will use
	 ** heap-memory for the wal-index instead of the VFS shared-memory
	 ** implementation. Take the exclusive lock now, before opening the WAL
	 ** file, to make sure this is safe.
	 */
	if (*TPager)(unsafe.Pointer(pPager)).FexclusiveMode != 0 {
		rc = _pagerExclusiveLock(tls, pPager)
	}
	/* Open the connection to the log file. If this operation fails,
	 ** (e.g. due to malloc() failure), return an error code.
	 */
	if rc == SQLITE_OK {
		rc = _sqlite3WalOpen(tls, (*TPager)(unsafe.Pointer(pPager)).FpVfs, (*TPager)(unsafe.Pointer(pPager)).Ffd, (*TPager)(unsafe.Pointer(pPager)).FzWal, libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FexclusiveMode), (*TPager)(unsafe.Pointer(pPager)).FjournalSizeLimit, pPager+224)
	}
	_pagerFixMaplimit(tls, pPager)
	return rc
}

// C documentation
//
//	/*
//	** Playback savepoint pSavepoint. Or, if pSavepoint==NULL, then playback
//	** the entire super-journal file. The case pSavepoint==NULL occurs when
//	** a ROLLBACK TO command is invoked on a SAVEPOINT that is a transaction
//	** savepoint.
//	**
//	** When pSavepoint is not NULL (meaning a non-transaction savepoint is
//	** being rolled back), then the rollback consists of up to three stages,
//	** performed in the order specified:
//	**
//	**   * Pages are played back from the main journal starting at byte
//	**     offset PagerSavepoint.iOffset and continuing to
//	**     PagerSavepoint.iHdrOffset, or to the end of the main journal
//	**     file if PagerSavepoint.iHdrOffset is zero.
//	**
//	**   * If PagerSavepoint.iHdrOffset is not zero, then pages are played
//	**     back starting from the journal header immediately following
//	**     PagerSavepoint.iHdrOffset to the end of the main journal file.
//	**
//	**   * Pages are then played back from the sub-journal file, starting
//	**     with the PagerSavepoint.iSubRec and continuing to the end of
//	**     the journal file.
//	**
//	** Throughout the rollback process, each time a page is rolled back, the
//	** corresponding bit is set in a bitvec structure (variable pDone in the
//	** implementation below). This is used to ensure that a page is only
//	** rolled back the first time it is encountered in either journal.
//	**
//	** If pSavepoint is NULL, then pages are only played back from the main
//	** journal file. There is no need for a bitvec in this case.
//	**
//	** In either case, before playback commences the Pager.dbSize variable
//	** is reset to the value that it held at the start of the savepoint
//	** (or transaction). No page with a page-number greater than this value
//	** is played back. If one is encountered it is simply skipped.
//	*/
func _pagerPlaybackSavepoint(tls *libc.TLS, pPager uintptr, pSavepoint uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var iHdrOff, szJ Ti64
	var ii, ii1 Tu32
	var pDone uintptr
	var rc int32
	var v1 uint32
	var v2 int64
	var _ /* dummy at bp+4 */ Tu32
	var _ /* nJRec at bp+0 */ Tu32
	var _ /* offset at bp+8 */ Ti64
	_, _, _, _, _, _, _, _ = iHdrOff, ii, ii1, pDone, rc, szJ, v1, v2 /* End of first segment of main-journal records */
	rc = SQLITE_OK                                                    /* Return code */
	pDone = uintptr(0)                                                /* Bitvec to ensure pages played back only once */
	/* Allocate a bitvec to use to store the set of pages rolled back */
	if pSavepoint != 0 {
		pDone = _sqlite3BitvecCreate(tls, (*TPagerSavepoint)(unsafe.Pointer(pSavepoint)).FnOrig)
		if !(pDone != 0) {
			return int32(SQLITE_NOMEM)
		}
	}
	/* Set the database size back to the value it was before the savepoint
	 ** being reverted was opened.
	 */
	if pSavepoint != 0 {
		v1 = (*TPagerSavepoint)(unsafe.Pointer(pSavepoint)).FnOrig
	} else {
		v1 = (*TPager)(unsafe.Pointer(pPager)).FdbOrigSize
	}
	(*TPager)(unsafe.Pointer(pPager)).FdbSize = v1
	(*TPager)(unsafe.Pointer(pPager)).FchangeCountDone = (*TPager)(unsafe.Pointer(pPager)).FtempFile
	if !(pSavepoint != 0) && (*TPager)(unsafe.Pointer(pPager)).FpWal != uintptr(0) {
		return _pagerRollbackWal(tls, pPager)
	}
	/* Use pPager->journalOff as the effective size of the main rollback
	 ** journal.  The actual file might be larger than this in
	 ** PAGER_JOURNALMODE_TRUNCATE or PAGER_JOURNALMODE_PERSIST.  But anything
	 ** past pPager->journalOff is off-limits to us.
	 */
	szJ = (*TPager)(unsafe.Pointer(pPager)).FjournalOff
	/* Begin by rolling back records from the main journal starting at
	 ** PagerSavepoint.iOffset and continuing to the next journal header.
	 ** There might be records in the main journal that have a page number
	 ** greater than the current database size (pPager->dbSize) but those
	 ** will be skipped automatically.  Pages are added to pDone as they
	 ** are played back.
	 */
	if pSavepoint != 0 && !((*TPager)(unsafe.Pointer(pPager)).FpWal != libc.UintptrFromInt32(0)) {
		if (*TPagerSavepoint)(unsafe.Pointer(pSavepoint)).FiHdrOffset != 0 {
			v2 = (*TPagerSavepoint)(unsafe.Pointer(pSavepoint)).FiHdrOffset
		} else {
			v2 = szJ
		}
		iHdrOff = v2
		(*TPager)(unsafe.Pointer(pPager)).FjournalOff = (*TPagerSavepoint)(unsafe.Pointer(pSavepoint)).FiOffset
		for rc == SQLITE_OK && (*TPager)(unsafe.Pointer(pPager)).FjournalOff < iHdrOff {
			rc = _pager_playback_one_page(tls, pPager, pPager+76, pDone, int32(1), int32(1))
		}
	} else {
		(*TPager)(unsafe.Pointer(pPager)).FjournalOff = 0
	}
	/* Continue rolling back records out of the main journal starting at
	 ** the first journal header seen and continuing until the effective end
	 ** of the main journal file.  Continue to skip out-of-range pages and
	 ** continue adding pages rolled back to pDone.
	 */
	for rc == SQLITE_OK && (*TPager)(unsafe.Pointer(pPager)).FjournalOff < szJ { /* Loop counter */
		**(**Tu32)(__ccgo_up(bp)) = uint32(0)
		rc = _readJournalHdr(tls, pPager, 0, szJ, bp, bp+4)
		/*
		 ** The "pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff"
		 ** test is related to ticket #2565.  See the discussion in the
		 ** pager_playback() function for additional information.
		 */
		if **(**Tu32)(__ccgo_up(bp)) == uint32(0) && (*TPager)(unsafe.Pointer(pPager)).FjournalHdr+libc.Int64FromUint32((*TPager)(unsafe.Pointer(pPager)).FsectorSize) == (*TPager)(unsafe.Pointer(pPager)).FjournalOff {
			**(**Tu32)(__ccgo_up(bp)) = libc.Uint32FromInt64((szJ - (*TPager)(unsafe.Pointer(pPager)).FjournalOff) / ((*TPager)(unsafe.Pointer(pPager)).FpageSize + libc.Int64FromInt32(8)))
		}
		ii = uint32(0)
		for {
			if !(rc == SQLITE_OK && ii < **(**Tu32)(__ccgo_up(bp)) && (*TPager)(unsafe.Pointer(pPager)).FjournalOff < szJ) {
				break
			}
			rc = _pager_playback_one_page(tls, pPager, pPager+76, pDone, int32(1), int32(1))
			goto _3
		_3:
			;
			ii = ii + 1
		}
	}
	/* Finally,  rollback pages from the sub-journal.  Page that were
	 ** previously rolled back out of the main journal (and are hence in pDone)
	 ** will be skipped.  Out-of-range pages are also skipped.
	 */
	if pSavepoint != 0 { /* Loop counter */
		**(**Ti64)(__ccgo_up(bp + 8)) = libc.Int64FromUint32((*TPagerSavepoint)(unsafe.Pointer(pSavepoint)).FiSubRec) * (int64(4) + (*TPager)(unsafe.Pointer(pPager)).FpageSize)
		if (*TPager)(unsafe.Pointer(pPager)).FpWal != uintptr(0) {
			rc = _sqlite3WalSavepointUndo(tls, (*TPager)(unsafe.Pointer(pPager)).FpWal, pSavepoint+32)
		}
		ii1 = (*TPagerSavepoint)(unsafe.Pointer(pSavepoint)).FiSubRec
		for {
			if !(rc == SQLITE_OK && ii1 < (*TPager)(unsafe.Pointer(pPager)).FnSubRec) {
				break
			}
			rc = _pager_playback_one_page(tls, pPager, bp+8, pDone, 0, int32(1))
			goto _4
		_4:
			;
			ii1 = ii1 + 1
		}
	}
	_sqlite3BitvecDestroy(tls, pDone)
	if rc == SQLITE_OK {
		(*TPager)(unsafe.Pointer(pPager)).FjournalOff = szJ
	}
	return rc
}

// C documentation
//
//	/*
//	** This function is called by the pcache layer when it has reached some
//	** soft memory limit. The first argument is a pointer to a Pager object
//	** (cast as a void*). The pager is always 'purgeable' (not an in-memory
//	** database). The second argument is a reference to a page that is
//	** currently dirty but has no outstanding references. The page
//	** is always associated with the Pager object passed as the first
//	** argument.
//	**
//	** The job of this function is to make pPg clean by writing its contents
//	** out to the database file, if possible. This may involve syncing the
//	** journal file.
//	**
//	** If successful, sqlite3PcacheMakeClean() is called on the page and
//	** SQLITE_OK returned. If an IO error occurs while trying to make the
//	** page clean, the IO error code is returned. If the page cannot be
//	** made clean for some other reason, but no error occurs, then SQLITE_OK
//	** is returned by sqlite3PcacheMakeClean() is not called.
//	*/
func _pagerStress(tls *libc.TLS, p uintptr, pPg uintptr) (r int32) {
	var pPager uintptr
	var rc int32
	_, _ = pPager, rc
	pPager = p
	rc = SQLITE_OK
	/* The doNotSpill NOSYNC bit is set during times when doing a sync of
	 ** journal (and adding a new header) is not allowed.  This occurs
	 ** during calls to sqlite3PagerWrite() while trying to journal multiple
	 ** pages belonging to the same sector.
	 **
	 ** The doNotSpill ROLLBACK and OFF bits inhibits all cache spilling
	 ** regardless of whether or not a sync is required.  This is set during
	 ** a rollback or by user request, respectively.
	 **
	 ** Spilling is also prohibited when in an error state since that could
	 ** lead to database corruption.   In the current implementation it
	 ** is impossible for sqlite3PcacheFetch() to be called with createFlag==3
	 ** while in the error state, hence it is impossible for this routine to
	 ** be called in the error state.  Nevertheless, we include a NEVER()
	 ** test for the error state as a safeguard against future changes.
	 */
	if (*TPager)(unsafe.Pointer(pPager)).FerrCode != 0 {
		return SQLITE_OK
	}
	if (*TPager)(unsafe.Pointer(pPager)).FdoNotSpill != 0 && (libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FdoNotSpill)&(libc.Int32FromInt32(SPILLFLAG_ROLLBACK)|libc.Int32FromInt32(SPILLFLAG_OFF)) != 0 || libc.Int32FromUint16((*TPgHdr)(unsafe.Pointer(pPg)).Fflags)&int32(PGHDR_NEED_SYNC) != 0) {
		return SQLITE_OK
	}
	**(**Tu32)(__ccgo_up(pPager + 192 + 3*4)) = **(**Tu32)(__ccgo_up(pPager + 192 + 3*4)) + 1
	(*TPgHdr)(unsafe.Pointer(pPg)).FpDirty = uintptr(0)
	if (*TPager)(unsafe.Pointer(pPager)).FpWal != uintptr(0) {
		/* Write a single frame for this page to the log. */
		rc = _subjournalPageIfRequired(tls, pPg)
		if rc == SQLITE_OK {
			rc = _pagerWalFrames(tls, pPager, pPg, uint32(0), 0)
		}
	} else {
		/* Sync the journal file if required. */
		if libc.Int32FromUint16((*TPgHdr)(unsafe.Pointer(pPg)).Fflags)&int32(PGHDR_NEED_SYNC) != 0 || libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FeState) == int32(PAGER_WRITER_CACHEMOD) {
			rc = _syncJournal(tls, pPager, int32(1))
		}
		/* Write the contents of the page out to the database file. */
		if rc == SQLITE_OK {
			rc = _pager_write_pagelist(tls, pPager, pPg)
		}
	}
	/* Mark the page as clean. */
	if rc == SQLITE_OK {
		_sqlite3PcacheMakeClean(tls, pPg)
	}
	return _pager_error(tls, pPager, rc)
}

// C documentation
//
//	/*
//	** This function is called before attempting a hot-journal rollback. It
//	** syncs the journal file to disk, then sets pPager->journalHdr to the
//	** size of the journal file so that the pager_playback() routine knows
//	** that the entire journal file has been synced.
//	**
//	** Syncing a hot-journal to disk before attempting to roll it back ensures
//	** that if a power-failure occurs during the rollback, the process that
//	** attempts rollback following system recovery sees the same journal
//	** content as this process.
//	**
//	** If everything goes as planned, SQLITE_OK is returned. Otherwise,
//	** an SQLite error code.
//	*/
func _pagerSyncHotJournal(tls *libc.TLS, pPager uintptr) (r int32) {
	var rc int32
	_ = rc
	rc = SQLITE_OK
	if !((*TPager)(unsafe.Pointer(pPager)).FnoSync != 0) {
		rc = _sqlite3OsSync(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd, int32(SQLITE_SYNC_NORMAL))
	}
	if rc == SQLITE_OK {
		rc = _sqlite3OsFileSize(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd, pPager+84)
	}
	return rc
}

// C documentation
//
//	/*
//	** This function is a wrapper around sqlite3WalFrames(). As well as logging
//	** the contents of the list of pages headed by pList (connected by pDirty),
//	** this function notifies any active backup processes that the pages have
//	** changed.
//	**
//	** The list of pages passed into this routine is always sorted by page number.
//	** Hence, if page 1 appears anywhere on the list, it will be the first page.
//	*/
func _pagerWalFrames(tls *libc.TLS, pPager uintptr, _pList uintptr, nTruncate TPgno, isCommit int32) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	*(*uintptr)(unsafe.Pointer(bp)) = _pList
	var nList, rc int32
	var p, ppNext, v2 uintptr
	_, _, _, _, _ = nList, p, ppNext, rc, v2 /* For looping over pages */
	if isCommit != 0 {
		/* If a WAL transaction is being committed, there is no point in writing
		 ** any pages with page numbers greater than nTruncate into the WAL file.
		 ** They will never be read by any client. So remove them from the pDirty
		 ** list here. */
		ppNext = bp
		nList = 0
		p = **(**uintptr)(__ccgo_up(bp))
		for {
			v2 = p
			**(**uintptr)(__ccgo_up(ppNext)) = v2
			if !(v2 != uintptr(0)) {
				break
			}
			if (*TPgHdr)(unsafe.Pointer(p)).Fpgno <= nTruncate {
				ppNext = p + 16
				nList = nList + 1
			}
			goto _1
		_1:
			;
			p = (*TPgHdr)(unsafe.Pointer(p)).FpDirty
		}
	} else {
		nList = int32(1)
	}
	**(**Tu32)(__ccgo_up(pPager + 192 + 2*4)) += libc.Uint32FromInt32(nList)
	if (*TPgHdr)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).Fpgno == uint32(1) {
		_pager_write_changecounter(tls, **(**uintptr)(__ccgo_up(bp)))
	}
	rc = _sqlite3WalFrames(tls, (*TPager)(unsafe.Pointer(pPager)).FpWal, int32((*TPager)(unsafe.Pointer(pPager)).FpageSize), **(**uintptr)(__ccgo_up(bp)), nTruncate, isCommit, libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FwalSyncFlags))
	if rc == SQLITE_OK && (*TPager)(unsafe.Pointer(pPager)).FpBackup != 0 {
		p = **(**uintptr)(__ccgo_up(bp))
		for {
			if !(p != 0) {
				break
			}
			_sqlite3BackupUpdate(tls, (*TPager)(unsafe.Pointer(pPager)).FpBackup, (*TPgHdr)(unsafe.Pointer(p)).Fpgno, (*TPgHdr)(unsafe.Pointer(p)).FpData)
			goto _3
		_3:
			;
			p = (*TPgHdr)(unsafe.Pointer(p)).FpDirty
		}
	}
	return rc
}

// C documentation
//
//	/*
//	** Parameter zSuper is the name of a super-journal file. A single journal
//	** file that referred to the super-journal file has just been rolled back.
//	** This routine checks if it is possible to delete the super-journal file,
//	** and does so if it is.
//	**
//	** Argument zSuper may point to Pager.pTmpSpace. So that buffer is not
//	** available for use within this function.
//	**
//	** When a super-journal file is created, it is populated with the names
//	** of all of its child journals, one after another, formatted as utf-8
//	** encoded text. The end of each child journal file is marked with a
//	** nul-terminator byte (0x00). i.e. the entire contents of a super-journal
//	** file for a transaction involving two databases might be:
//	**
//	**   "/home/bill/a.db-journal\x00/home/bill/b.db-journal\x00"
//	**
//	** A super-journal file may only be deleted once all of its child
//	** journals have been rolled back.
//	**
//	** This function reads the contents of the super-journal file into
//	** memory and loops through each of the child journal names. For
//	** each child journal, it checks if:
//	**
//	**   * if the child journal exists, and if so
//	**   * if the child journal contains a reference to super-journal
//	**     file zSuper
//	**
//	** If a child journal can be found that matches both of the criteria
//	** above, this function returns without doing anything. Otherwise, if
//	** no such child journal can be found, file zSuper is deleted from
//	** the file-system using sqlite3OsDelete().
//	**
//	** If an IO error within this function, an error code is returned. This
//	** function allocates memory by calling sqlite3Malloc(). If an allocation
//	** fails, SQLITE_NOMEM is returned. Otherwise, if no IO or malloc errors
//	** occur, SQLITE_OK is returned.
//	**
//	** TODO: This function allocates a single block of memory to load
//	** the entire contents of the super-journal file. This could be
//	** a couple of kilobytes or so - potentially larger than the page
//	** size.
//	*/
func _pager_delsuper(tls *libc.TLS, pPager uintptr, zSuper uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var c, flags, flags1, rc int32
	var nSuperPtr Ti64
	var pJournal, pSuper, pVfs, zFree, zJournal, zSuperJournal, zSuperPtr uintptr
	var v1, v2, v3 int8
	var _ /* exists at bp+8 */ int32
	var _ /* nSuperJournal at bp+0 */ Ti64
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = c, flags, flags1, nSuperPtr, pJournal, pSuper, pVfs, rc, zFree, zJournal, zSuperJournal, zSuperPtr, v1, v2, v3
	pVfs = (*TPager)(unsafe.Pointer(pPager)).FpVfs /* Malloc'd child-journal file descriptor */
	zSuperJournal = uintptr(0)                     /* Space to hold super-journal filename */
	zFree = uintptr(0)                             /* Amount of space allocated to zSuperPtr[] */
	/* Allocate space for both the pJournal and pSuper file descriptors.
	 ** If successful, open the super-journal file for reading.
	 */
	pSuper = _sqlite3MallocZero(tls, libc.Uint64FromInt64(int64(2)*int64((*Tsqlite3_vfs)(unsafe.Pointer(pVfs)).FszOsFile)))
	if !(pSuper != 0) {
		rc = int32(SQLITE_NOMEM)
		pJournal = uintptr(0)
	} else {
		flags = libc.Int32FromInt32(SQLITE_OPEN_READONLY) | libc.Int32FromInt32(SQLITE_OPEN_SUPER_JOURNAL)
		rc = _sqlite3OsOpen(tls, pVfs, zSuper, pSuper, flags, uintptr(0))
		pJournal = pSuper + uintptr((*Tsqlite3_vfs)(unsafe.Pointer(pVfs)).FszOsFile)
	}
	if rc != SQLITE_OK {
		goto delsuper_out
	}
	/* Load the entire super-journal file into space obtained from
	 ** sqlite3_malloc() and pointed to by zSuperJournal.   Also obtain
	 ** sufficient space (in zSuperPtr) to hold the names of super-journal
	 ** files extracted from regular rollback-journals.
	 */
	rc = _sqlite3OsFileSize(tls, pSuper, bp)
	if rc != SQLITE_OK {
		goto delsuper_out
	}
	nSuperPtr = int64(1) + int64((*Tsqlite3_vfs)(unsafe.Pointer(pVfs)).FmxPathname)
	zFree = _sqlite3Malloc(tls, libc.Uint64FromInt64(int64(4)+**(**Ti64)(__ccgo_up(bp))+int64(2)+nSuperPtr+int64(2)))
	if !(zFree != 0) {
		rc = int32(SQLITE_NOMEM)
		goto delsuper_out
	} else {
	}
	v3 = libc.Int8FromInt32(0)
	**(**int8)(__ccgo_up(zFree + 3)) = v3
	v2 = v3
	**(**int8)(__ccgo_up(zFree + 2)) = v2
	v1 = v2
	**(**int8)(__ccgo_up(zFree + 1)) = v1
	**(**int8)(__ccgo_up(zFree)) = v1
	zSuperJournal = zFree + 4
	zSuperPtr = zSuperJournal + uintptr(**(**Ti64)(__ccgo_up(bp))+int64(2))
	rc = _sqlite3OsRead(tls, pSuper, zSuperJournal, int32(**(**Ti64)(__ccgo_up(bp))), 0)
	if rc != SQLITE_OK {
		goto delsuper_out
	}
	**(**int8)(__ccgo_up(zSuperJournal + uintptr(**(**Ti64)(__ccgo_up(bp))))) = 0
	**(**int8)(__ccgo_up(zSuperJournal + uintptr(**(**Ti64)(__ccgo_up(bp))+int64(1)))) = 0
	zJournal = zSuperJournal
	for int64(int32(zJournal)-int32(zSuperJournal)) < **(**Ti64)(__ccgo_up(bp)) {
		rc = _sqlite3OsAccess(tls, pVfs, zJournal, SQLITE_ACCESS_EXISTS, bp+8)
		if rc != SQLITE_OK {
			goto delsuper_out
		}
		if **(**int32)(__ccgo_up(bp + 8)) != 0 {
			flags1 = libc.Int32FromInt32(SQLITE_OPEN_READONLY) | libc.Int32FromInt32(SQLITE_OPEN_SUPER_JOURNAL)
			rc = _sqlite3OsOpen(tls, pVfs, zJournal, pJournal, flags1, uintptr(0))
			if rc != SQLITE_OK {
				goto delsuper_out
			}
			rc = _readSuperJournal(tls, pJournal, zSuperPtr, libc.Uint64FromInt64(nSuperPtr))
			_sqlite3OsClose(tls, pJournal)
			if rc != SQLITE_OK {
				goto delsuper_out
			}
			c = libc.BoolInt32(int32(**(**int8)(__ccgo_up(zSuperPtr))) != 0 && libc.Xstrcmp(tls, zSuperPtr, zSuper) == 0)
			if c != 0 {
				/* We have a match. Do not delete the super-journal file. */
				goto delsuper_out
			}
		}
		zJournal = zJournal + uintptr(_sqlite3Strlen30(tls, zJournal)+libc.Int32FromInt32(1))
	}
	_sqlite3OsClose(tls, pSuper)
	rc = _sqlite3OsDelete(tls, pVfs, zSuper, 0)
	goto delsuper_out
delsuper_out:
	;
	Xsqlite3_free(tls, zFree)
	if pSuper != 0 {
		_sqlite3OsClose(tls, pSuper)
		Xsqlite3_free(tls, pSuper)
	}
	return rc
}

// C documentation
//
//	/*
//	** This routine is called to increment the value of the database file
//	** change-counter, stored as a 4-byte big-endian integer starting at
//	** byte offset 24 of the pager file.  The secondary change counter at
//	** 92 is also updated, as is the SQLite version number at offset 96.
//	**
//	** But this only happens if the pPager->changeCountDone flag is false.
//	** To avoid excess churning of page 1, the update only happens once.
//	** See also the pager_write_changecounter() routine that does an
//	** unconditional update of the change counters.
//	**
//	** If the isDirectMode flag is zero, then this is done by calling
//	** sqlite3PagerWrite() on page 1, then modifying the contents of the
//	** page data. In this case the file will be updated when the current
//	** transaction is committed.
//	**
//	** The isDirectMode flag may only be non-zero if the library was compiled
//	** with the SQLITE_ENABLE_ATOMIC_WRITE macro defined. In this case,
//	** if isDirect is non-zero, then the database file is updated directly
//	** by writing an updated version of page 1 using a call to the
//	** sqlite3OsWrite() function.
//	*/
func _pager_incr_changecounter(tls *libc.TLS, pPager uintptr, isDirectMode int32) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var pCopy, zBuf uintptr
	var rc int32
	var _ /* pPgHdr at bp+0 */ uintptr
	_, _, _ = pCopy, rc, zBuf
	rc = SQLITE_OK
	/* Declare and initialize constant integer 'isDirect'. If the
	 ** atomic-write optimization is enabled in this build, then isDirect
	 ** is initialized to the value passed as the isDirectMode parameter
	 ** to this function. Otherwise, it is always set to zero.
	 **
	 ** The idea is that if the atomic-write optimization is not
	 ** enabled at compile time, the compiler can omit the tests of
	 ** 'isDirect' below, as well as the block enclosed in the
	 ** "if( isDirect )" condition.
	 */
	_ = isDirectMode
	if !((*TPager)(unsafe.Pointer(pPager)).FchangeCountDone != 0) && (*TPager)(unsafe.Pointer(pPager)).FdbSize > uint32(0) { /* Reference to page 1 */
		/* Open page 1 of the file for writing. */
		rc = _sqlite3PagerGet(tls, pPager, uint32(1), bp, 0)
		/* If page one was fetched successfully, and this function is not
		 ** operating in direct-mode, make page 1 writable.  When not in
		 ** direct mode, page 1 is always held in cache and hence the PagerGet()
		 ** above is always successful - hence the ALWAYS on rc==SQLITE_OK.
		 */
		if libc.Bool(!(libc.Int32FromInt32(DIRECT_MODE) != 0)) && rc == SQLITE_OK {
			rc = _sqlite3PagerWrite(tls, **(**uintptr)(__ccgo_up(bp)))
		}
		if rc == SQLITE_OK {
			/* Actually do the update of the change counter */
			_pager_write_changecounter(tls, **(**uintptr)(__ccgo_up(bp)))
			/* If running in direct mode, write the contents of page 1 to the file. */
			if DIRECT_MODE != 0 {
				zBuf = (*TPgHdr)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FpData
				if rc == SQLITE_OK {
					rc = _sqlite3OsWrite(tls, (*TPager)(unsafe.Pointer(pPager)).Ffd, zBuf, int32((*TPager)(unsafe.Pointer(pPager)).FpageSize), 0)
					**(**Tu32)(__ccgo_up(pPager + 192 + 2*4)) = **(**Tu32)(__ccgo_up(pPager + 192 + 2*4)) + 1
				}
				if rc == SQLITE_OK {
					/* Update the pager's copy of the change-counter. Otherwise, the
					 ** next time a read transaction is opened the cache will be
					 ** flushed (as the change-counter values will not match).  */
					pCopy = zBuf + 24
					libc.Xmemcpy(tls, pPager+108, pCopy, uint32(16))
					(*TPager)(unsafe.Pointer(pPager)).FchangeCountDone = uint8(1)
				}
			} else {
				(*TPager)(unsafe.Pointer(pPager)).FchangeCountDone = uint8(1)
			}
		}
		/* Release the page reference. */
		_sqlite3PagerUnref(tls, **(**uintptr)(__ccgo_up(bp)))
	}
	return rc
}

// C documentation
//
//	/*
//	** Read a single page from either the journal file (if isMainJrnl==1) or
//	** from the sub-journal (if isMainJrnl==0) and playback that page.
//	** The page begins at offset *pOffset into the file. The *pOffset
//	** value is increased to the start of the next page in the journal.
//	**
//	** The main rollback journal uses checksums - the statement journal does
//	** not.
//	**
//	** If the page number of the page record read from the (sub-)journal file
//	** is greater than the current value of Pager.dbSize, then playback is
//	** skipped and SQLITE_OK is returned.
//	**
//	** If pDone is not NULL, then it is a record of pages that have already
//	** been played back.  If the page at *pOffset has already been played back
//	** (if the corresponding pDone bit is set) then skip the playback.
//	** Make sure the pDone bit corresponding to the *pOffset page is set
//	** prior to returning.
//	**
//	** If the page record is successfully read from the (sub-)journal file
//	** and played back, then SQLITE_OK is returned. If an IO error occurs
//	** while reading the record from the (sub-)journal file or while writing
//	** to the database file, then the IO error code is returned. If data
//	** is successfully read from the (sub-)journal file but appears to be
//	** corrupted, SQLITE_DONE is returned. Data is considered corrupted in
//	** two circumstances:
//	**
//	**   * If the record page-number is illegal (0 or PAGER_SJ_PGNO), or
//	**   * If the record is being rolled back from the main journal file
//	**     and the checksum field does not match the record content.
//	**
//	** Neither of these two scenarios are possible during a savepoint rollback.
//	**
//	** If this is a savepoint rollback, then memory may have to be dynamically
//	** allocated by this function. If this is the case and an allocation fails,
//	** SQLITE_NOMEM is returned.
//	*/
func _pager_playback_one_page(tls *libc.TLS, pPager uintptr, pOffset uintptr, pDone uintptr, isMainJrnl int32, isSavepnt int32) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var aData, jfd, pData, v1 uintptr
	var isSynced, rc, v2 int32
	var ofst Ti64
	var v3 bool
	var _ /* cksum at bp+8 */ Tu32
	var _ /* pPg at bp+0 */ uintptr
	var _ /* pgno at bp+4 */ TPgno
	_, _, _, _, _, _, _, _, _ = aData, isSynced, jfd, ofst, pData, rc, v1, v2, v3 /* True if journal page is synced */
	/* isMainJrnl is 0 or 1 */
	/* isSavepnt is 0 or 1 */
	/* pDone always used on sub-journals */
	/* pDone never used on non-savepoint */
	aData = (*TPager)(unsafe.Pointer(pPager)).FpTmpSpace
	/* Temp storage must have already been allocated */
	/* Either the state is greater than PAGER_WRITER_CACHEMOD (a transaction
	 ** or savepoint rollback done at the request of the caller) or this is
	 ** a hot-journal rollback. If it is a hot-journal rollback, the pager
	 ** is in state OPEN and holds an EXCLUSIVE lock. Hot-journal rollback
	 ** only reads from the main journal, not the sub-journal.
	 */
	/* Read the page number and page data from the journal or sub-journal
	 ** file. Return an error code to the caller if an IO error occurs.
	 */
	if isMainJrnl != 0 {
		v1 = (*TPager)(unsafe.Pointer(pPager)).Fjfd
	} else {
		v1 = (*TPager)(unsafe.Pointer(pPager)).Fsjfd
	}
	jfd = v1
	rc = _read32bits(tls, jfd, **(**Ti64)(__ccgo_up(pOffset)), bp+4)
	if rc != SQLITE_OK {
		return rc
	}
	rc = _sqlite3OsRead(tls, jfd, aData, int32((*TPager)(unsafe.Pointer(pPager)).FpageSize), **(**Ti64)(__ccgo_up(pOffset))+int64(4))
	if rc != SQLITE_OK {
		return rc
	}
	**(**Ti64)(__ccgo_up(pOffset)) += (*TPager)(unsafe.Pointer(pPager)).FpageSize + int64(4) + int64(isMainJrnl*int32(4))
	/* Sanity checking on the page.  This is more important that I originally
	 ** thought.  If a power failure occurs while the journal is being written,
	 ** it could cause invalid data to be written into the journal.  We need to
	 ** detect this invalid data (with high probability) and ignore it.
	 */
	if **(**TPgno)(__ccgo_up(bp + 4)) == uint32(0) || **(**TPgno)(__ccgo_up(bp + 4)) == (*TPager)(unsafe.Pointer(pPager)).FlckPgno {
		return int32(SQLITE_DONE)
	}
	if **(**TPgno)(__ccgo_up(bp + 4)) > (*TPager)(unsafe.Pointer(pPager)).FdbSize || _sqlite3BitvecTest(tls, pDone, **(**TPgno)(__ccgo_up(bp + 4))) != 0 {
		return SQLITE_OK
	}
	if isMainJrnl != 0 {
		rc = _read32bits(tls, jfd, **(**Ti64)(__ccgo_up(pOffset))-int64(4), bp+8)
		if rc != 0 {
			return rc
		}
		if !(isSavepnt != 0) && _pager_cksum(tls, pPager, aData) != **(**Tu32)(__ccgo_up(bp + 8)) {
			return int32(SQLITE_DONE)
		}
	}
	/* If this page has already been played back before during the current
	 ** rollback, then don't bother to play it back again.
	 */
	if v3 = pDone != 0; v3 {
		v2 = _sqlite3BitvecSet(tls, pDone, **(**TPgno)(__ccgo_up(bp + 4)))
		rc = v2
	}
	if v3 && v2 != SQLITE_OK {
		return rc
	}
	/* When playing back page 1, restore the nReserve setting
	 */
	if **(**TPgno)(__ccgo_up(bp + 4)) == uint32(1) && int32((*TPager)(unsafe.Pointer(pPager)).FnReserve) != libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aData + 20))) {
		(*TPager)(unsafe.Pointer(pPager)).FnReserve = libc.Int16FromUint8(**(**Tu8)(__ccgo_up(aData + 20)))
	}
	/* If the pager is in CACHEMOD state, then there must be a copy of this
	 ** page in the pager cache. In this case just update the pager cache,
	 ** not the database file. The page is left marked dirty in this case.
	 **
	 ** An exception to the above rule: If the database is in no-sync mode
	 ** and a page is moved during an incremental vacuum then the page may
	 ** not be in the pager cache. Later: if a malloc() or IO error occurs
	 ** during a Movepage() call, then the page may not be in the cache
	 ** either. So the condition described in the above paragraph is not
	 ** assert()able.
	 **
	 ** If in WRITER_DBMOD, WRITER_FINISHED or OPEN state, then we update the
	 ** pager cache if it exists and the main file. The page is then marked
	 ** not dirty. Since this code is only executed in PAGER_OPEN state for
	 ** a hot-journal rollback, it is guaranteed that the page-cache is empty
	 ** if the pager is in OPEN state.
	 **
	 ** Ticket #1171:  The statement journal might contain page content that is
	 ** different from the page content at the start of the transaction.
	 ** This occurs when a page is changed prior to the start of a statement
	 ** then changed again within the statement.  When rolling back such a
	 ** statement we must not write to the original database unless we know
	 ** for certain that original page contents are synced into the main rollback
	 ** journal.  Otherwise, a power loss might leave modified data in the
	 ** database file without an entry in the rollback journal that can
	 ** restore the database to its original form.  Two conditions must be
	 ** met before writing to the database files. (1) the database must be
	 ** locked.  (2) we know that the original page content is fully synced
	 ** in the main journal either because the page is not in cache or else
	 ** the page is marked as needSync==0.
	 **
	 ** 2008-04-14:  When attempting to vacuum a corrupt database file, it
	 ** is possible to fail a statement on a database that does not yet exist.
	 ** Do not attempt to write if database file has never been opened.
	 */
	if (*TPager)(unsafe.Pointer(pPager)).FpWal != uintptr(0) {
		**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
	} else {
		**(**uintptr)(__ccgo_up(bp)) = _sqlite3PagerLookup(tls, pPager, **(**TPgno)(__ccgo_up(bp + 4)))
	}
	if isMainJrnl != 0 {
		isSynced = libc.BoolInt32((*TPager)(unsafe.Pointer(pPager)).FnoSync != 0 || **(**Ti64)(__ccgo_up(pOffset)) <= (*TPager)(unsafe.Pointer(pPager)).FjournalHdr)
	} else {
		isSynced = libc.BoolInt32(**(**uintptr)(__ccgo_up(bp)) == uintptr(0) || 0 == libc.Int32FromUint16((*TPgHdr)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).Fflags)&int32(PGHDR_NEED_SYNC))
	}
	if (*Tsqlite3_file)(unsafe.Pointer((*TPager)(unsafe.Pointer(pPager)).Ffd)).FpMethods != uintptr(0) && (libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FeState) >= int32(PAGER_WRITER_DBMOD) || libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FeState) == PAGER_OPEN) && isSynced != 0 {
		ofst = libc.Int64FromUint32(**(**TPgno)(__ccgo_up(bp + 4))-libc.Uint32FromInt32(1)) * (*TPager)(unsafe.Pointer(pPager)).FpageSize
		/* Write the data read from the journal back into the database file.
		 ** This is usually safe even for an encrypted database - as the data
		 ** was encrypted before it was written to the journal file. The exception
		 ** is if the data was just read from an in-memory sub-journal. In that
		 ** case it must be encrypted here before it is copied into the database
		 ** file.  */
		rc = _sqlite3OsWrite(tls, (*TPager)(unsafe.Pointer(pPager)).Ffd, aData, int32((*TPager)(unsafe.Pointer(pPager)).FpageSize), ofst)
		if **(**TPgno)(__ccgo_up(bp + 4)) > (*TPager)(unsafe.Pointer(pPager)).FdbFileSize {
			(*TPager)(unsafe.Pointer(pPager)).FdbFileSize = **(**TPgno)(__ccgo_up(bp + 4))
		}
		if (*TPager)(unsafe.Pointer(pPager)).FpBackup != 0 {
			_sqlite3BackupUpdate(tls, (*TPager)(unsafe.Pointer(pPager)).FpBackup, **(**TPgno)(__ccgo_up(bp + 4)), aData)
		}
	} else {
		if !(isMainJrnl != 0) && **(**uintptr)(__ccgo_up(bp)) == uintptr(0) {
			/* If this is a rollback of a savepoint and data was not written to
			 ** the database and the page is not in-memory, there is a potential
			 ** problem. When the page is next fetched by the b-tree layer, it
			 ** will be read from the database file, which may or may not be
			 ** current.
			 **
			 ** There are a couple of different ways this can happen. All are quite
			 ** obscure. When running in synchronous mode, this can only happen
			 ** if the page is on the free-list at the start of the transaction, then
			 ** populated, then moved using sqlite3PagerMovepage().
			 **
			 ** The solution is to add an in-memory page to the cache containing
			 ** the data just read from the sub-journal. Mark the page as dirty
			 ** and if the pager requires a journal-sync, then mark the page as
			 ** requiring a journal-sync before it is written.
			 */
			v1 = pPager + 21
			*(*Tu8)(unsafe.Pointer(v1)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v1))) | libc.Int32FromInt32(SPILLFLAG_ROLLBACK))
			rc = _sqlite3PagerGet(tls, pPager, **(**TPgno)(__ccgo_up(bp + 4)), bp, int32(1))
			v1 = pPager + 21
			*(*Tu8)(unsafe.Pointer(v1)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v1))) & ^libc.Int32FromInt32(SPILLFLAG_ROLLBACK))
			if rc != SQLITE_OK {
				return rc
			}
			_sqlite3PcacheMakeDirty(tls, **(**uintptr)(__ccgo_up(bp)))
		}
	}
	if **(**uintptr)(__ccgo_up(bp)) != 0 {
		pData = (*TPgHdr)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FpData
		libc.Xmemcpy(tls, pData, aData, libc.Uint32FromInt64((*TPager)(unsafe.Pointer(pPager)).FpageSize))
		(*(*func(*libc.TLS, uintptr))(unsafe.Pointer(&struct{ uintptr }{(*TPager)(unsafe.Pointer(pPager)).FxReiniter})))(tls, **(**uintptr)(__ccgo_up(bp)))
		/* It used to be that sqlite3PcacheMakeClean(pPg) was called here.  But
		 ** that call was dangerous and had no detectable benefit since the cache
		 ** is normally cleaned by sqlite3PcacheCleanAll() after rollback and so
		 ** has been removed. */
		/* If this was page 1, then restore the value of Pager.dbFileVers.
		 ** Do this before any decoding. */
		if **(**TPgno)(__ccgo_up(bp + 4)) == uint32(1) {
			libc.Xmemcpy(tls, pPager+108, pData+24, uint32(16))
		}
		_sqlite3PcacheRelease(tls, **(**uintptr)(__ccgo_up(bp)))
	}
	return rc
}

// C documentation
//
//	/*
//	** Update the value of the change-counter at offsets 24 and 92 in
//	** the header and the sqlite version number at offset 96.
//	**
//	** This is an unconditional update.  See also the pager_incr_changecounter()
//	** routine which only updates the change-counter if the update is actually
//	** needed, as determined by the pPager->changeCountDone state variable.
//	*/
func _pager_write_changecounter(tls *libc.TLS, pPg uintptr) {
	var change_counter Tu32
	_ = change_counter
	if pPg == uintptr(0) {
		return
	}
	/* Increment the value just read and write it back to byte 24. */
	change_counter = _sqlite3Get4byte(tls, (*TPgHdr)(unsafe.Pointer(pPg)).FpPager+108) + uint32(1)
	_sqlite3Put4byte(tls, (*TPgHdr)(unsafe.Pointer(pPg)).FpData+uintptr(24), change_counter)
	/* Also store the SQLite version number in bytes 96..99 and in
	 ** bytes 92..95 store the change counter for which the version number
	 ** is valid. */
	_sqlite3Put4byte(tls, (*TPgHdr)(unsafe.Pointer(pPg)).FpData+uintptr(92), change_counter)
	_sqlite3Put4byte(tls, (*TPgHdr)(unsafe.Pointer(pPg)).FpData+uintptr(96), uint32(SQLITE_VERSION_NUMBER))
}

// C documentation
//
//	/*
//	** The argument is the first in a linked list of dirty pages connected
//	** by the PgHdr.pDirty pointer. This function writes each one of the
//	** in-memory pages in the list to the database file. The argument may
//	** be NULL, representing an empty list. In this case this function is
//	** a no-op.
//	**
//	** The pager must hold at least a RESERVED lock when this function
//	** is called. Before writing anything to the database file, this lock
//	** is upgraded to an EXCLUSIVE lock. If the lock cannot be obtained,
//	** SQLITE_BUSY is returned and no data is written to the database file.
//	**
//	** If the pager is a temp-file pager and the actual file-system file
//	** is not yet open, it is created and opened before any data is
//	** written out.
//	**
//	** Once the lock has been upgraded and, if necessary, the file opened,
//	** the pages are written out to the database file in list order. Writing
//	** a page is skipped if it meets either of the following criteria:
//	**
//	**   * The page number is greater than Pager.dbSize, or
//	**   * The PGHDR_DONT_WRITE flag is set on the page.
//	**
//	** If writing out a page causes the database file to grow, Pager.dbFileSize
//	** is updated accordingly. If page 1 is written out, then the value cached
//	** in Pager.dbFileVers[] is updated to match the new value stored in
//	** the database file.
//	**
//	** If everything is successful, SQLITE_OK is returned. If an IO error
//	** occurs, an IO error code is returned. Or, if the EXCLUSIVE lock cannot
//	** be obtained, SQLITE_BUSY is returned.
//	*/
func _pager_write_pagelist(tls *libc.TLS, pPager uintptr, pList uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var offset Ti64
	var pData uintptr
	var pgno TPgno
	var rc int32
	var _ /* szFile at bp+0 */ Tsqlite3_int64
	_, _, _, _ = offset, pData, pgno, rc
	rc = SQLITE_OK /* Return code */
	/* This function is only called for rollback pagers in WRITER_DBMOD state. */
	/* If the file is a temp-file has not yet been opened, open it now. It
	 ** is not possible for rc to be other than SQLITE_OK if this branch
	 ** is taken, as pager_wait_on_lock() is a no-op for temp-files.
	 */
	if !((*Tsqlite3_file)(unsafe.Pointer((*TPager)(unsafe.Pointer(pPager)).Ffd)).FpMethods != libc.UintptrFromInt32(0)) {
		rc = _pagerOpentemp(tls, pPager, (*TPager)(unsafe.Pointer(pPager)).Ffd, libc.Int32FromUint32((*TPager)(unsafe.Pointer(pPager)).FvfsFlags))
	}
	/* Before the first write, give the VFS a hint of what the final
	 ** file size will be.
	 */
	if rc == SQLITE_OK && (*TPager)(unsafe.Pointer(pPager)).FdbHintSize < (*TPager)(unsafe.Pointer(pPager)).FdbSize && ((*TPgHdr)(unsafe.Pointer(pList)).FpDirty != 0 || (*TPgHdr)(unsafe.Pointer(pList)).Fpgno > (*TPager)(unsafe.Pointer(pPager)).FdbHintSize) {
		**(**Tsqlite3_int64)(__ccgo_up(bp)) = (*TPager)(unsafe.Pointer(pPager)).FpageSize * libc.Int64FromUint32((*TPager)(unsafe.Pointer(pPager)).FdbSize)
		_sqlite3OsFileControlHint(tls, (*TPager)(unsafe.Pointer(pPager)).Ffd, int32(SQLITE_FCNTL_SIZE_HINT), bp)
		(*TPager)(unsafe.Pointer(pPager)).FdbHintSize = (*TPager)(unsafe.Pointer(pPager)).FdbSize
	}
	for rc == SQLITE_OK && pList != 0 {
		pgno = (*TPgHdr)(unsafe.Pointer(pList)).Fpgno
		/* If there are dirty pages in the page cache with page numbers greater
		 ** than Pager.dbSize, this means sqlite3PagerTruncateImage() was called to
		 ** make the file smaller (presumably by auto-vacuum code). Do not write
		 ** any such pages to the file.
		 **
		 ** Also, do not write out any page that has the PGHDR_DONT_WRITE flag
		 ** set (set by sqlite3PagerDontWrite()).
		 */
		if pgno <= (*TPager)(unsafe.Pointer(pPager)).FdbSize && 0 == libc.Int32FromUint16((*TPgHdr)(unsafe.Pointer(pList)).Fflags)&int32(PGHDR_DONT_WRITE) {
			offset = libc.Int64FromUint32(pgno-libc.Uint32FromInt32(1)) * (*TPager)(unsafe.Pointer(pPager)).FpageSize /* Data to write */
			if (*TPgHdr)(unsafe.Pointer(pList)).Fpgno == uint32(1) {
				_pager_write_changecounter(tls, pList)
			}
			pData = (*TPgHdr)(unsafe.Pointer(pList)).FpData
			/* Write out the page data. */
			rc = _sqlite3OsWrite(tls, (*TPager)(unsafe.Pointer(pPager)).Ffd, pData, int32((*TPager)(unsafe.Pointer(pPager)).FpageSize), offset)
			/* If page 1 was just written, update Pager.dbFileVers to match
			 ** the value now stored in the database file. If writing this
			 ** page caused the database file to grow, update dbFileSize.
			 */
			if pgno == uint32(1) {
				libc.Xmemcpy(tls, pPager+108, pData+24, uint32(16))
			}
			if pgno > (*TPager)(unsafe.Pointer(pPager)).FdbFileSize {
				(*TPager)(unsafe.Pointer(pPager)).FdbFileSize = pgno
			}
			**(**Tu32)(__ccgo_up(pPager + 192 + 2*4)) = **(**Tu32)(__ccgo_up(pPager + 192 + 2*4)) + 1
			/* Update any backup objects copying the contents of this pager. */
			_sqlite3BackupUpdate(tls, (*TPager)(unsafe.Pointer(pPager)).FpBackup, pgno, (*TPgHdr)(unsafe.Pointer(pList)).FpData)
		} else {
		}
		pList = (*TPgHdr)(unsafe.Pointer(pList)).FpDirty
	}
	return rc
}

// C documentation
//
//	/* Return an integer that is the maximum allowed stack size */
func _parserStackSizeLimit(tls *libc.TLS, pParse uintptr) (r int32) {
	return **(**int32)(__ccgo_up((*TParse)(unsafe.Pointer(pParse)).Fdb + 116 + 12*4))
}

// C documentation
//
//	/*
//	** Compare two UTF-8 strings for equality where the first string is
//	** a GLOB or LIKE expression.  Return values:
//	**
//	**    SQLITE_MATCH:            Match
//	**    SQLITE_NOMATCH:          No match
//	**    SQLITE_NOWILDCARDMATCH:  No match in spite of having * or % wildcards.
//	**
//	** Globbing rules:
//	**
//	**      '*'       Matches any sequence of zero or more characters.
//	**
//	**      '?'       Matches exactly one character.
//	**
//	**     [...]      Matches one character from the enclosed list of
//	**                characters.
//	**
//	**     [^...]     Matches one character not in the enclosed list.
//	**
//	** With the [...] and [^...] matching, a ']' character can be included
//	** in the list by making it the first character after '[' or '^'.  A
//	** range of characters can be specified using '-'.  Example:
//	** "[a-z]" matches any single lower-case letter.  To match a '-', make
//	** it the last character in the list.
//	**
//	** Like matching rules:
//	**
//	**      '%'       Matches any sequence of zero or more characters
//	**
//	***     '_'       Matches any one character
//	**
//	**      Ec        Where E is the "esc" character and c is any other
//	**                character, including '%', '_', and esc, match exactly c.
//	**
//	** The comments within this routine usually assume glob matching.
//	**
//	** This routine is usually quick, but can be N**2 in the worst case.
//	*/
func _patternCompare(tls *libc.TLS, _zPattern uintptr, _zString uintptr, pInfo uintptr, matchOther Tu32) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	*(*uintptr)(unsafe.Pointer(bp)) = _zPattern
	*(*uintptr)(unsafe.Pointer(bp + 4)) = _zString
	var bMatch, bMatch1, bMatch2, invert, seen, v13 int32
	var c, c2, matchAll, matchOne, prior_c, v1, v4 Tu32
	var noCase Tu8
	var zEscaped, v3, v6 uintptr
	var v2, v5 uint32
	var _ /* zStop at bp+9 */ [3]int8
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = bMatch, bMatch1, bMatch2, c, c2, invert, matchAll, matchOne, noCase, prior_c, seen, zEscaped, v1, v13, v2, v3, v4, v5, v6 /* Next pattern and input string chars */
	matchOne = uint32((*TcompareInfo)(unsafe.Pointer(pInfo)).FmatchOne)                                                                                                                 /* "?" or "_" */
	matchAll = uint32((*TcompareInfo)(unsafe.Pointer(pInfo)).FmatchAll)                                                                                                                 /* "*" or "%" */
	noCase = (*TcompareInfo)(unsafe.Pointer(pInfo)).FnoCase                                                                                                                             /* True if uppercase==lowercase */
	zEscaped = uintptr(0)                                                                                                                                                               /* One past the last escaped input char */
	for {
		if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp))))) < int32(0x80) {
			v3 = **(**uintptr)(__ccgo_up(bp))
			**(**uintptr)(__ccgo_up(bp)) = **(**uintptr)(__ccgo_up(bp)) + 1
			v2 = uint32(**(**Tu8)(__ccgo_up(v3)))
		} else {
			v2 = _sqlite3Utf8Read(tls, bp)
		}
		v1 = v2
		c = v1
		if !(v1 != uint32(0)) {
			break
		}
		if c == matchAll { /* Match "*" */
			/* Skip over multiple "*" characters in the pattern.  If there
			 ** are also "?" characters, skip those as well, but consume a
			 ** single character of the input string for each "?" skipped */
			for {
				if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp))))) < int32(0x80) {
					v6 = **(**uintptr)(__ccgo_up(bp))
					**(**uintptr)(__ccgo_up(bp)) = **(**uintptr)(__ccgo_up(bp)) + 1
					v5 = uint32(**(**Tu8)(__ccgo_up(v6)))
				} else {
					v5 = _sqlite3Utf8Read(tls, bp)
				}
				v4 = v5
				c = v4
				if !(v4 == matchAll || c == matchOne && matchOne != uint32(0)) {
					break
				}
				if c == matchOne && _sqlite3Utf8Read(tls, bp+4) == uint32(0) {
					return int32(SQLITE_NOWILDCARDMATCH)
				}
			}
			if c == uint32(0) {
				return SQLITE_MATCH /* "*" at the end of the pattern matches */
			} else {
				if c == matchOther {
					if libc.Int32FromUint8((*TcompareInfo)(unsafe.Pointer(pInfo)).FmatchSet) == 0 {
						c = _sqlite3Utf8Read(tls, bp)
						if c == uint32(0) {
							return int32(SQLITE_NOWILDCARDMATCH)
						}
					} else {
						/* "[...]" immediately follows the "*".  We have to do a slow
						 ** recursive search in this case, but it is an unusual case. */
						/* '[' is a single-byte character */
						for **(**Tu8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp + 4)))) != 0 {
							bMatch = _patternCompare(tls, **(**uintptr)(__ccgo_up(bp))+uintptr(-libc.Int32FromInt32(1)), **(**uintptr)(__ccgo_up(bp + 4)), pInfo, matchOther)
							if bMatch != int32(SQLITE_NOMATCH) {
								return bMatch
							}
							v3 = **(**uintptr)(__ccgo_up(bp + 4))
							**(**uintptr)(__ccgo_up(bp + 4)) = **(**uintptr)(__ccgo_up(bp + 4)) + 1
							if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(v3))) >= int32(0xc0) {
								for libc.Int32FromUint8(**(**Tu8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp + 4)))))&int32(0xc0) == int32(0x80) {
									**(**uintptr)(__ccgo_up(bp + 4)) = **(**uintptr)(__ccgo_up(bp + 4)) + 1
								}
							}
						}
						return int32(SQLITE_NOWILDCARDMATCH)
					}
				}
			}
			/* At this point variable c contains the first character of the
			 ** pattern string past the "*".  Search in the input string for the
			 ** first matching character and recursively continue the match from
			 ** that point.
			 **
			 ** For a case-insensitive search, set variable cx to be the same as
			 ** c but in the other case and search the input string for either
			 ** c or cx.
			 */
			if c < uint32(0x80) {
				if noCase != 0 {
					(**(**[3]int8)(__ccgo_up(bp + 9)))[0] = libc.Int8FromUint32(c & libc.Uint32FromInt32(^(libc.Int32FromUint8(_sqlite3CtypeMap[uint8(c)]) & libc.Int32FromInt32(0x20))))
					(**(**[3]int8)(__ccgo_up(bp + 9)))[int32(1)] = libc.Int8FromUint8(_sqlite3UpperToLower[uint8(c)])
					(**(**[3]int8)(__ccgo_up(bp + 9)))[int32(2)] = 0
				} else {
					(**(**[3]int8)(__ccgo_up(bp + 9)))[0] = libc.Int8FromUint32(c)
					(**(**[3]int8)(__ccgo_up(bp + 9)))[int32(1)] = 0
				}
				for int32(1) != 0 {
					**(**uintptr)(__ccgo_up(bp + 4)) = **(**uintptr)(__ccgo_up(bp + 4)) + uintptr(libc.Xstrcspn(tls, **(**uintptr)(__ccgo_up(bp + 4)), bp+9))
					if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp + 4))))) == 0 {
						break
					}
					**(**uintptr)(__ccgo_up(bp + 4)) = **(**uintptr)(__ccgo_up(bp + 4)) + 1
					bMatch1 = _patternCompare(tls, **(**uintptr)(__ccgo_up(bp)), **(**uintptr)(__ccgo_up(bp + 4)), pInfo, matchOther)
					if bMatch1 != int32(SQLITE_NOMATCH) {
						return bMatch1
					}
				}
			} else {
				for {
					if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp + 4))))) < int32(0x80) {
						v3 = **(**uintptr)(__ccgo_up(bp + 4))
						**(**uintptr)(__ccgo_up(bp + 4)) = **(**uintptr)(__ccgo_up(bp + 4)) + 1
						v2 = uint32(**(**Tu8)(__ccgo_up(v3)))
					} else {
						v2 = _sqlite3Utf8Read(tls, bp+4)
					}
					v1 = v2
					c2 = v1
					if !(v1 != uint32(0)) {
						break
					}
					if c2 != c {
						continue
					}
					bMatch2 = _patternCompare(tls, **(**uintptr)(__ccgo_up(bp)), **(**uintptr)(__ccgo_up(bp + 4)), pInfo, matchOther)
					if bMatch2 != int32(SQLITE_NOMATCH) {
						return bMatch2
					}
				}
			}
			return int32(SQLITE_NOWILDCARDMATCH)
		}
		if c == matchOther {
			if libc.Int32FromUint8((*TcompareInfo)(unsafe.Pointer(pInfo)).FmatchSet) == 0 {
				c = _sqlite3Utf8Read(tls, bp)
				if c == uint32(0) {
					return int32(SQLITE_NOMATCH)
				}
				zEscaped = **(**uintptr)(__ccgo_up(bp))
			} else {
				prior_c = uint32(0)
				seen = 0
				invert = 0
				c = _sqlite3Utf8Read(tls, bp+4)
				if c == uint32(0) {
					return int32(SQLITE_NOMATCH)
				}
				c2 = _sqlite3Utf8Read(tls, bp)
				if c2 == uint32('^') {
					invert = int32(1)
					c2 = _sqlite3Utf8Read(tls, bp)
				}
				if c2 == uint32(']') {
					if c == uint32(']') {
						seen = int32(1)
					}
					c2 = _sqlite3Utf8Read(tls, bp)
				}
				for c2 != 0 && c2 != uint32(']') {
					if c2 == uint32('-') && libc.Int32FromUint8(**(**Tu8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp))))) != int32(']') && libc.Int32FromUint8(**(**Tu8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp))))) != 0 && prior_c > uint32(0) {
						c2 = _sqlite3Utf8Read(tls, bp)
						if c >= prior_c && c <= c2 {
							seen = int32(1)
						}
						prior_c = uint32(0)
					} else {
						if c == c2 {
							seen = int32(1)
						}
						prior_c = c2
					}
					c2 = _sqlite3Utf8Read(tls, bp)
				}
				if c2 == uint32(0) || seen^invert == 0 {
					return int32(SQLITE_NOMATCH)
				}
				continue
			}
		}
		if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp + 4))))) < int32(0x80) {
			v3 = **(**uintptr)(__ccgo_up(bp + 4))
			**(**uintptr)(__ccgo_up(bp + 4)) = **(**uintptr)(__ccgo_up(bp + 4)) + 1
			v2 = uint32(**(**Tu8)(__ccgo_up(v3)))
		} else {
			v2 = _sqlite3Utf8Read(tls, bp+4)
		}
		c2 = v2
		if c == c2 {
			continue
		}
		if noCase != 0 && libc.Int32FromUint8(_sqlite3UpperToLower[uint8(c)]) == libc.Int32FromUint8(_sqlite3UpperToLower[uint8(c2)]) && c < uint32(0x80) && c2 < uint32(0x80) {
			continue
		}
		if c == matchOne && **(**uintptr)(__ccgo_up(bp)) != zEscaped && c2 != uint32(0) {
			continue
		}
		return int32(SQLITE_NOMATCH)
	}
	if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp + 4))))) == 0 {
		v13 = SQLITE_MATCH
	} else {
		v13 = int32(SQLITE_NOMATCH)
	}
	return v13
}

// C documentation
//
//	/*
//	** fts5VisitEntries() callback used by fts5SetupPrefixIterTokendata(). This
//	** callback adds an entry to the Fts5TokenDataIter.aMap[] array for each
//	** position in the current position-list. It doesn't matter that some of
//	** these may be out of order - they will be sorted later.
//	*/
func _prefixIterSetupTokendataCb(tls *libc.TLS, p uintptr, pCtx uintptr, p1 uintptr, pNew uintptr, nNew int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var pSetup uintptr
	var _ /* iPos at bp+8 */ Ti64
	var _ /* iPosOff at bp+0 */ int32
	_ = pSetup
	pSetup = pCtx
	**(**int32)(__ccgo_up(bp)) = 0
	**(**Ti64)(__ccgo_up(bp + 8)) = 0
	if pNew != 0 {
		(*TTokendataSetupCtx)(unsafe.Pointer(pSetup)).FnTermByte = nNew - int32(1)
		(*TTokendataSetupCtx)(unsafe.Pointer(pSetup)).FiTermOff = (*TFts5TokenDataIter)(unsafe.Pointer((*TTokendataSetupCtx)(unsafe.Pointer(pSetup)).FpT)).Fterms.Fn
		_sqlite3Fts5BufferAppendBlob(tls, p+40, (*TTokendataSetupCtx)(unsafe.Pointer(pSetup)).FpT+20, libc.Uint32FromInt32(nNew-int32(1)), pNew+uintptr(1))
	}
	for 0 == _sqlite3Fts5PoslistNext64(tls, (*TFts5Iter)(unsafe.Pointer(p1)).Fbase.FpData, (*TFts5Iter)(unsafe.Pointer(p1)).Fbase.FnData, bp, bp+8) {
		_fts5TokendataIterAppendMap(tls, p, (*TTokendataSetupCtx)(unsafe.Pointer(pSetup)).FpT, (*TTokendataSetupCtx)(unsafe.Pointer(pSetup)).FiTermOff, (*TTokendataSetupCtx)(unsafe.Pointer(pSetup)).FnTermByte, (*TFts5Iter)(unsafe.Pointer(p1)).Fbase.FiRowid, **(**Ti64)(__ccgo_up(bp + 8)))
	}
}

// C documentation
//
//	/*
//	** Implementation of the printf() (a.k.a. format()) SQL function.
//	*/
func _printfFunc(tls *libc.TLS, context uintptr, argc int32, argv uintptr) {
	bp := tls.Alloc(64)
	defer tls.Free(64)
	var db, zFormat, v1 uintptr
	var n int32
	var v2 bool
	var _ /* str at bp+12 */ TStrAccum
	var _ /* x at bp+0 */ TPrintfArguments
	_, _, _, _, _ = db, n, zFormat, v1, v2
	db = Xsqlite3_context_db_handle(tls, context)
	if v2 = argc >= int32(1); v2 {
		v1 = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv)))
		zFormat = v1
	}
	if v2 && v1 != uintptr(0) {
		(**(**TPrintfArguments)(__ccgo_up(bp))).FnArg = argc - int32(1)
		(**(**TPrintfArguments)(__ccgo_up(bp))).FnUsed = 0
		(**(**TPrintfArguments)(__ccgo_up(bp))).FapArg = argv + uintptr(1)*4
		_sqlite3StrAccumInit(tls, bp+12, db, uintptr(0), 0, **(**int32)(__ccgo_up(db + 116)))
		(**(**TStrAccum)(__ccgo_up(bp + 12))).FprintfFlags = uint8(SQLITE_PRINTF_SQLFUNC)
		Xsqlite3_str_appendf(tls, bp+12, zFormat, libc.VaList(bp+48, bp))
		if libc.Int32FromUint8((**(**TStrAccum)(__ccgo_up(bp + 12))).FaccError) == SQLITE_OK {
			n = libc.Int32FromUint32((**(**TStrAccum)(__ccgo_up(bp + 12))).FnChar)
			Xsqlite3_result_text(tls, context, _sqlite3StrAccumFinish(tls, bp+12), n, __ccgo_fp(_sqlite3RowSetClear))
		} else {
			if libc.Int32FromUint8((**(**TStrAccum)(__ccgo_up(bp + 12))).FaccError) == int32(SQLITE_NOMEM) {
				Xsqlite3_result_error_nomem(tls, context)
			} else {
				Xsqlite3_result_error_toobig(tls, context)
			}
			Xsqlite3_str_reset(tls, bp+12)
		}
	}
}

// C documentation
//
//	/*
//	** This is a Walker expression callback. pExpr is a node from the WHERE
//	** clause of a SELECT statement. This function examines pExpr to see if
//	** any substitutions based on the contents of pWalker->u.pConst should
//	** be made to pExpr or its immediate children.
//	**
//	** A substitution is made if:
//	**
//	**   + pExpr is a column with an affinity other than BLOB that matches
//	**     one of the columns in pWalker->u.pConst, or
//	**
//	**   + pExpr is a binary comparison operator (=, <=, >=, <, >) that
//	**     uses an affinity other than TEXT and one of its immediate
//	**     children is a column that matches one of the columns in
//	**     pWalker->u.pConst.
//	*/
func _propagateConstantExprRewrite(tls *libc.TLS, pWalker uintptr, pExpr uintptr) (r int32) {
	var pConst uintptr
	_ = pConst
	pConst = *(*uintptr)(unsafe.Pointer(pWalker + 24))
	if (*TWhereConst)(unsafe.Pointer(pConst)).FbHasAffBlob != 0 {
		if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) >= int32(TK_EQ) && libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) <= int32(TK_GE) || libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) == int32(TK_IS) {
			_propagateConstantExprRewriteOne(tls, pConst, (*TExpr)(unsafe.Pointer(pExpr)).FpLeft, 0)
			if **(**Tu8)(__ccgo_up((*TWhereConst)(unsafe.Pointer(pConst)).FpOomFault)) != 0 {
				return int32(WRC_Prune)
			}
			if int32(_sqlite3ExprAffinity(tls, (*TExpr)(unsafe.Pointer(pExpr)).FpLeft)) != int32(SQLITE_AFF_TEXT) {
				_propagateConstantExprRewriteOne(tls, pConst, (*TExpr)(unsafe.Pointer(pExpr)).FpRight, 0)
			}
		}
	}
	return _propagateConstantExprRewriteOne(tls, pConst, pExpr, (*TWhereConst)(unsafe.Pointer(pConst)).FbHasAffBlob)
}

// C documentation
//
//	/*
//	** This is a helper function for Walker callback propagateConstantExprRewrite().
//	**
//	** Argument pExpr is a candidate expression to be replaced by a value. If
//	** pExpr is equivalent to one of the columns named in pWalker->u.pConst,
//	** then overwrite it with the corresponding value. Except, do not do so
//	** if argument bIgnoreAffBlob is non-zero and the affinity of pExpr
//	** is SQLITE_AFF_BLOB.
//	*/
func _propagateConstantExprRewriteOne(tls *libc.TLS, pConst uintptr, pExpr uintptr, bIgnoreAffBlob int32) (r int32) {
	var i int32
	var pColumn uintptr
	_, _ = i, pColumn
	if **(**Tu8)(__ccgo_up((*TWhereConst)(unsafe.Pointer(pConst)).FpOomFault)) != 0 {
		return int32(WRC_Prune)
	}
	if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) != int32(TK_COLUMN) {
		return WRC_Continue
	}
	if (*TExpr)(unsafe.Pointer(pExpr)).Fflags&(libc.Uint32FromInt32(EP_FixedCol)|(*TWhereConst)(unsafe.Pointer(pConst)).FmExcludeOn) != uint32(0) {
		return WRC_Continue
	}
	i = 0
	for {
		if !(i < (*TWhereConst)(unsafe.Pointer(pConst)).FnConst) {
			break
		}
		pColumn = **(**uintptr)(__ccgo_up((*TWhereConst)(unsafe.Pointer(pConst)).FapExpr + uintptr(i*int32(2))*4))
		if pColumn == pExpr {
			goto _1
		}
		if (*TExpr)(unsafe.Pointer(pColumn)).FiTable != (*TExpr)(unsafe.Pointer(pExpr)).FiTable {
			goto _1
		}
		if int32((*TExpr)(unsafe.Pointer(pColumn)).FiColumn) != int32((*TExpr)(unsafe.Pointer(pExpr)).FiColumn) {
			goto _1
		}
		if bIgnoreAffBlob != 0 && int32(_sqlite3ExprAffinity(tls, pColumn)) <= int32(SQLITE_AFF_BLOB) {
			break
		}
		/* A match is found.  Add the EP_FixedCol property */
		(*TWhereConst)(unsafe.Pointer(pConst)).FnChng = (*TWhereConst)(unsafe.Pointer(pConst)).FnChng + 1
		**(**Tu32)(__ccgo_up(pExpr + 4)) &= ^libc.Uint32FromInt32(libc.Int32FromInt32(EP_Leaf))
		**(**Tu32)(__ccgo_up(pExpr + 4)) |= libc.Uint32FromInt32(libc.Int32FromInt32(EP_FixedCol))
		(*TExpr)(unsafe.Pointer(pExpr)).FpLeft = _sqlite3ExprDup(tls, (*TParse)(unsafe.Pointer((*TWhereConst)(unsafe.Pointer(pConst)).FpParse)).Fdb, **(**uintptr)(__ccgo_up((*TWhereConst)(unsafe.Pointer(pConst)).FapExpr + uintptr(i*int32(2)+int32(1))*4)), 0)
		if (*Tsqlite3)(unsafe.Pointer((*TParse)(unsafe.Pointer((*TWhereConst)(unsafe.Pointer(pConst)).FpParse)).Fdb)).FmallocFailed != 0 {
			return int32(WRC_Prune)
		}
		break
		goto _1
	_1:
		;
		i = i + 1
	}
	return int32(WRC_Prune)
}

// C documentation
//
//	/*
//	** The WHERE-clause constant propagation optimization.
//	**
//	** If the WHERE clause contains terms of the form COLUMN=CONSTANT or
//	** CONSTANT=COLUMN that are top-level AND-connected terms that are not
//	** part of a ON clause from a LEFT JOIN, then throughout the query
//	** replace all other occurrences of COLUMN with CONSTANT.
//	**
//	** For example, the query:
//	**
//	**      SELECT * FROM t1, t2, t3 WHERE t1.a=39 AND t2.b=t1.a AND t3.c=t2.b
//	**
//	** Is transformed into
//	**
//	**      SELECT * FROM t1, t2, t3 WHERE t1.a=39 AND t2.b=39 AND t3.c=39
//	**
//	** Return true if any transformations where made and false if not.
//	**
//	** Implementation note:  Constant propagation is tricky due to affinity
//	** and collating sequence interactions.  Consider this example:
//	**
//	**    CREATE TABLE t1(a INT,b TEXT);
//	**    INSERT INTO t1 VALUES(123,'0123');
//	**    SELECT * FROM t1 WHERE a=123 AND b=a;
//	**    SELECT * FROM t1 WHERE a=123 AND b=123;
//	**
//	** The two SELECT statements above should return different answers.  b=a
//	** is always true because the comparison uses numeric affinity, but b=123
//	** is false because it uses text affinity and '0123' is not the same as '123'.
//	** To work around this, the expression tree is not actually changed from
//	** "b=a" to "b=123" but rather the "a" in "b=a" is tagged with EP_FixedCol
//	** and the "123" value is hung off of the pLeft pointer.  Code generator
//	** routines know to generate the constant "123" instead of looking up the
//	** column value.  Also, to avoid collation problems, this optimization is
//	** only attempted if the "a=123" term uses the default BINARY collation.
//	**
//	** 2021-05-25 forum post 6a06202608: Another troublesome case is...
//	**
//	**    CREATE TABLE t1(x);
//	**    INSERT INTO t1 VALUES(10.0);
//	**    SELECT 1 FROM t1 WHERE x=10 AND x LIKE 10;
//	**
//	** The query should return no rows, because the t1.x value is '10.0' not '10'
//	** and '10.0' is not LIKE '10'.  But if we are not careful, the first WHERE
//	** term "x=10" will cause the second WHERE term to become "10 LIKE 10",
//	** resulting in a false positive.  To avoid this, constant propagation for
//	** columns with BLOB affinity is only allowed if the constant is used with
//	** operators ==, <=, <, >=, >, or IS in a way that will cause the correct
//	** type conversions to occur.  See logic associated with the bHasAffBlob flag
//	** for details.
//	*/
func _propagateConstants(tls *libc.TLS, pParse uintptr, p uintptr) (r int32) {
	bp := tls.Alloc(64)
	defer tls.Free(64)
	var nChng int32
	var _ /* w at bp+28 */ TWalker
	var _ /* x at bp+0 */ TWhereConst
	_ = nChng
	nChng = 0
	(**(**TWhereConst)(__ccgo_up(bp))).FpParse = pParse
	(**(**TWhereConst)(__ccgo_up(bp))).FpOomFault = (*TParse)(unsafe.Pointer(pParse)).Fdb + 83
	for cond := true; cond; cond = (**(**TWhereConst)(__ccgo_up(bp))).FnChng != 0 {
		(**(**TWhereConst)(__ccgo_up(bp))).FnConst = 0
		(**(**TWhereConst)(__ccgo_up(bp))).FnChng = 0
		(**(**TWhereConst)(__ccgo_up(bp))).FapExpr = uintptr(0)
		(**(**TWhereConst)(__ccgo_up(bp))).FbHasAffBlob = 0
		if (*TSelect)(unsafe.Pointer(p)).FpSrc != uintptr(0) && (*TSrcList)(unsafe.Pointer((*TSelect)(unsafe.Pointer(p)).FpSrc)).FnSrc > 0 && libc.Int32FromUint8((*(*TSrcItem)(unsafe.Pointer((*TSelect)(unsafe.Pointer(p)).FpSrc + 8))).Ffg.Fjointype)&int32(JT_LTORJ) != 0 {
			/* Do not propagate constants on any ON clause if there is a
			 ** RIGHT JOIN anywhere in the query */
			(**(**TWhereConst)(__ccgo_up(bp))).FmExcludeOn = libc.Uint32FromInt32(libc.Int32FromInt32(EP_InnerON) | libc.Int32FromInt32(EP_OuterON))
		} else {
			/* Do not propagate constants through the ON clause of a LEFT JOIN */
			(**(**TWhereConst)(__ccgo_up(bp))).FmExcludeOn = uint32(EP_OuterON)
		}
		_findConstInWhere(tls, bp, (*TSelect)(unsafe.Pointer(p)).FpWhere)
		if (**(**TWhereConst)(__ccgo_up(bp))).FnConst != 0 {
			libc.Xmemset(tls, bp+28, 0, uint32(28))
			(**(**TWalker)(__ccgo_up(bp + 28))).FpParse = pParse
			(**(**TWalker)(__ccgo_up(bp + 28))).FxExprCallback = __ccgo_fp(_propagateConstantExprRewrite)
			(**(**TWalker)(__ccgo_up(bp + 28))).FxSelectCallback = __ccgo_fp(_sqlite3SelectWalkNoop)
			(**(**TWalker)(__ccgo_up(bp + 28))).FxSelectCallback2 = uintptr(0)
			(**(**TWalker)(__ccgo_up(bp + 28))).FwalkerDepth = 0
			*(*uintptr)(unsafe.Pointer(bp + 28 + 24)) = bp
			_sqlite3WalkExpr(tls, bp+28, (*TSelect)(unsafe.Pointer(p)).FpWhere)
			_sqlite3DbFree(tls, (*TParse)(unsafe.Pointer((**(**TWhereConst)(__ccgo_up(bp))).FpParse)).Fdb, (**(**TWhereConst)(__ccgo_up(bp))).FapExpr)
			nChng = nChng + (**(**TWhereConst)(__ccgo_up(bp))).FnChng
		}
	}
	return nChng
}

// C documentation
//
//	/*
//	** Implementation of the QUOTE() function.
//	**
//	** The quote(X) function returns the text of an SQL literal which is the
//	** value of its argument suitable for inclusion into an SQL statement.
//	** Strings are surrounded by single-quotes with escapes on interior quotes
//	** as needed. BLOBs are encoded as hexadecimal literals. Strings with
//	** embedded NUL characters cannot be represented as string literals in SQL
//	** and hence the returned string literal is truncated prior to the first NUL.
//	**
//	** If sqlite3_user_data() is non-zero, then the UNISTR_QUOTE() function is
//	** implemented instead.  The difference is that UNISTR_QUOTE() uses the
//	** UNISTR() function to escape control characters.
//	*/
func _quoteFunc(tls *libc.TLS, context uintptr, argc int32, argv uintptr) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var db uintptr
	var _ /* str at bp+0 */ Tsqlite3_str
	_ = db
	db = Xsqlite3_context_db_handle(tls, context)
	_ = argc
	_sqlite3StrAccumInit(tls, bp, db, uintptr(0), 0, **(**int32)(__ccgo_up(db + 116)))
	_sqlite3QuoteValue(tls, bp, **(**uintptr)(__ccgo_up(argv)), int32(Xsqlite3_user_data(tls, context)))
	Xsqlite3_result_text(tls, context, _sqlite3StrAccumFinish(tls, bp), libc.Int32FromUint32((**(**Tsqlite3_str)(__ccgo_up(bp))).FnChar), __ccgo_fp(_sqlite3RowSetClear))
	if libc.Int32FromUint8((**(**Tsqlite3_str)(__ccgo_up(bp))).FaccError) != SQLITE_OK {
		Xsqlite3_result_null(tls, context)
		Xsqlite3_result_error_code(tls, context, libc.Int32FromUint8((**(**Tsqlite3_str)(__ccgo_up(bp))).FaccError))
	}
}

// C documentation
//
//	/*
//	** Apply a delta.
//	**
//	** The output buffer should be big enough to hold the whole output
//	** file and a NUL terminator at the end.  The delta_output_size()
//	** routine will determine this size for you.
//	**
//	** The delta string should be null-terminated.  But the delta string
//	** may contain embedded NUL characters (if the input and output are
//	** binary files) so we also have to pass in the length of the delta in
//	** the lenDelta parameter.
//	**
//	** This function returns the size of the output file in bytes (excluding
//	** the final NUL terminator character).  Except, if the delta string is
//	** malformed or intended for use with a source file other than zSrc,
//	** then this routine returns -1.
//	**
//	** Refer to the delta_create() documentation above for a description
//	** of the delta file format.
//	*/
func _rbuDeltaApply(tls *libc.TLS, zSrc uintptr, lenSrc int32, _zDelta uintptr, _lenDelta int32, zOut uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	*(*uintptr)(unsafe.Pointer(bp)) = _zDelta
	*(*int32)(unsafe.Pointer(bp + 4)) = _lenDelta
	var cnt, limit, ofst, total uint32
	_, _, _, _ = cnt, limit, ofst, total
	total = uint32(0)
	limit = _rbuDeltaGetInt(tls, bp, bp+4)
	if int32(**(**int8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp))))) != int32('\n') {
		/* ERROR: size integer not terminated by "\n" */
		return -int32(1)
	}
	**(**uintptr)(__ccgo_up(bp)) = **(**uintptr)(__ccgo_up(bp)) + 1
	**(**int32)(__ccgo_up(bp + 4)) = **(**int32)(__ccgo_up(bp + 4)) - 1
	for **(**int8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp)))) != 0 && **(**int32)(__ccgo_up(bp + 4)) > 0 {
		cnt = _rbuDeltaGetInt(tls, bp, bp+4)
		switch int32(**(**int8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp))))) {
		case int32('@'):
			**(**uintptr)(__ccgo_up(bp)) = **(**uintptr)(__ccgo_up(bp)) + 1
			**(**int32)(__ccgo_up(bp + 4)) = **(**int32)(__ccgo_up(bp + 4)) - 1
			ofst = _rbuDeltaGetInt(tls, bp, bp+4)
			if **(**int32)(__ccgo_up(bp + 4)) > 0 && int32(**(**int8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp))))) != int32(',') {
				/* ERROR: copy command not terminated by ',' */
				return -int32(1)
			}
			**(**uintptr)(__ccgo_up(bp)) = **(**uintptr)(__ccgo_up(bp)) + 1
			**(**int32)(__ccgo_up(bp + 4)) = **(**int32)(__ccgo_up(bp + 4)) - 1
			total = total + cnt
			if total > limit {
				/* ERROR: copy exceeds output file size */
				return -int32(1)
			}
			if uint64(ofst)+uint64(cnt) > libc.Uint64FromInt32(lenSrc) {
				/* ERROR: copy extends past end of input */
				return -int32(1)
			}
			libc.Xmemcpy(tls, zOut, zSrc+uintptr(ofst), cnt)
			zOut = zOut + uintptr(cnt)
		case int32(':'):
			**(**uintptr)(__ccgo_up(bp)) = **(**uintptr)(__ccgo_up(bp)) + 1
			**(**int32)(__ccgo_up(bp + 4)) = **(**int32)(__ccgo_up(bp + 4)) - 1
			total = total + cnt
			if total > limit {
				/* ERROR:  insert command gives an output larger than predicted */
				return -int32(1)
			}
			if libc.Int32FromUint32(cnt) > **(**int32)(__ccgo_up(bp + 4)) {
				/* ERROR: insert count exceeds size of delta */
				return -int32(1)
			}
			libc.Xmemcpy(tls, zOut, **(**uintptr)(__ccgo_up(bp)), cnt)
			zOut = zOut + uintptr(cnt)
			**(**uintptr)(__ccgo_up(bp)) = **(**uintptr)(__ccgo_up(bp)) + uintptr(cnt)
			**(**int32)(__ccgo_up(bp + 4)) = libc.Int32FromUint32(uint32(**(**int32)(__ccgo_up(bp + 4))) - cnt)
		case int32(';'):
			**(**uintptr)(__ccgo_up(bp)) = **(**uintptr)(__ccgo_up(bp)) + 1
			**(**int32)(__ccgo_up(bp + 4)) = **(**int32)(__ccgo_up(bp + 4)) - 1
			**(**int8)(__ccgo_up(zOut)) = 0
			if total != limit {
				/* ERROR: generated size does not match predicted size */
				return -int32(1)
			}
			return libc.Int32FromUint32(total)
		default:
			/* ERROR: unknown delta operator */
			return -int32(1)
		}
	}
	/* ERROR: unterminated delta */
	return -int32(1)
}

func _rbuDeltaOutputSize(tls *libc.TLS, _zDelta uintptr, _lenDelta int32) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	*(*uintptr)(unsafe.Pointer(bp)) = _zDelta
	*(*int32)(unsafe.Pointer(bp + 4)) = _lenDelta
	var size int32
	_ = size
	size = libc.Int32FromUint32(_rbuDeltaGetInt(tls, bp, bp+4))
	if int32(**(**int8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp))))) != int32('\n') {
		/* ERROR: size integer not terminated by "\n" */
		return -int32(1)
	}
	return size
}

/*
** End of code taken from fossil.
*************************************************************************/

// C documentation
//
//	/*
//	** Allocate and return an RBU handle with all fields zeroed except for the
//	** error code, which is set to SQLITE_MISUSE.
//	*/
func _rbuMisuseError(tls *libc.TLS) (r uintptr) {
	var pRet uintptr
	_ = pRet
	pRet = Xsqlite3_malloc64(tls, uint64(256))
	if pRet != 0 {
		libc.Xmemset(tls, pRet, 0, uint32(256))
		(*Tsqlite3rbu)(unsafe.Pointer(pRet)).Frc = int32(SQLITE_MISUSE)
	}
	return pRet
}

// C documentation
//
//	/*
//	** This function does the work for an sqlite3rbu_step() call.
//	**
//	** The object-iterator (p->objiter) currently points to a valid object,
//	** and the input cursor (p->objiter.pSelect) currently points to a valid
//	** input row. Perform whatever processing is required and return.
//	**
//	** If no  error occurs, SQLITE_OK is returned. Otherwise, an error code
//	** and message is left in the RBU handle and a copy of the error code
//	** returned.
//	*/
func _rbuStep(tls *libc.TLS, p uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var c int8
	var eType, i int32
	var pIter, pVal uintptr
	var _ /* pUpdate at bp+4 */ uintptr
	var _ /* zMask at bp+0 */ uintptr
	_, _, _, _, _ = c, eType, i, pIter, pVal
	pIter = p + 52
	**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
	eType = _rbuStepType(tls, p, bp)
	if eType != 0 {
		if (*TRbuObjIter)(unsafe.Pointer(pIter)).FzIdx == uintptr(0) && (eType == int32(RBU_IDX_DELETE) || eType == int32(RBU_IDX_INSERT)) {
			_rbuBadControlError(tls, p)
		} else {
			if eType == int32(RBU_REPLACE) {
				if (*TRbuObjIter)(unsafe.Pointer(pIter)).FzIdx == uintptr(0) {
					**(**Ti64)(__ccgo_up(p + 180)) += int64((*Tsqlite3rbu)(unsafe.Pointer(p)).Fobjiter.FnIndex)
					_rbuStepOneOp(tls, p, int32(RBU_DELETE))
				}
				if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
					_rbuStepOneOp(tls, p, int32(RBU_INSERT))
				}
			} else {
				if eType != int32(RBU_UPDATE) {
					_rbuStepOneOp(tls, p, eType)
				} else {
					**(**uintptr)(__ccgo_up(bp + 4)) = uintptr(0)
					**(**Ti64)(__ccgo_up(p + 180)) -= int64((*Tsqlite3rbu)(unsafe.Pointer(p)).Fobjiter.FnIndex)
					_rbuGetUpdateStmt(tls, p, pIter, **(**uintptr)(__ccgo_up(bp)), bp+4)
					if **(**uintptr)(__ccgo_up(bp + 4)) != 0 {
						i = 0
						for {
							if !((*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK && i < (*TRbuObjIter)(unsafe.Pointer(pIter)).FnCol) {
								break
							}
							c = **(**int8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp)) + uintptr(**(**int32)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FaiSrcOrder + uintptr(i)*4)))))
							pVal = Xsqlite3_column_value(tls, (*TRbuObjIter)(unsafe.Pointer(pIter)).FpSelect, i)
							if **(**Tu8)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FabTblPk + uintptr(i))) != 0 || int32(c) != int32('.') {
								(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = Xsqlite3_bind_value(tls, **(**uintptr)(__ccgo_up(bp + 4)), i+int32(1), pVal)
							}
							goto _1
						_1:
							;
							i = i + 1
						}
						if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK && ((*TRbuObjIter)(unsafe.Pointer(pIter)).FeType == int32(RBU_PK_VTAB) || (*TRbuObjIter)(unsafe.Pointer(pIter)).FeType == int32(RBU_PK_NONE)) {
							/* Bind the rbu_rowid value to column _rowid_ */
							pVal = Xsqlite3_column_value(tls, (*TRbuObjIter)(unsafe.Pointer(pIter)).FpSelect, (*TRbuObjIter)(unsafe.Pointer(pIter)).FnCol+int32(1))
							(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = Xsqlite3_bind_value(tls, **(**uintptr)(__ccgo_up(bp + 4)), (*TRbuObjIter)(unsafe.Pointer(pIter)).FnCol+int32(1), pVal)
						}
						if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
							Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp + 4)))
							(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = _resetAndCollectError(tls, **(**uintptr)(__ccgo_up(bp + 4)), p+36)
						}
					}
				}
			}
		}
	}
	return (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc
}

func _rbuTmpInsertFunc(tls *libc.TLS, pCtx uintptr, nVal int32, apVal uintptr) {
	var i, rc int32
	var p uintptr
	_, _, _ = i, p, rc
	p = Xsqlite3_user_data(tls, pCtx)
	rc = SQLITE_OK
	if Xsqlite3_value_int(tls, **(**uintptr)(__ccgo_up(apVal))) != 0 {
		**(**Ti64)(__ccgo_up(p + 180)) += int64((*Tsqlite3rbu)(unsafe.Pointer(p)).Fobjiter.FnIndex)
	}
	i = 0
	for {
		if !(rc == SQLITE_OK && i < nVal) {
			break
		}
		rc = Xsqlite3_bind_value(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).Fobjiter.FpTmpInsert, i+int32(1), **(**uintptr)(__ccgo_up(apVal + uintptr(i)*4)))
		goto _1
	_1:
		;
		i = i + 1
	}
	if rc == SQLITE_OK {
		Xsqlite3_step(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).Fobjiter.FpTmpInsert)
		rc = Xsqlite3_reset(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).Fobjiter.FpTmpInsert)
	}
	if rc != SQLITE_OK {
		Xsqlite3_result_error_code(tls, pCtx, rc)
	}
}

// C documentation
//
//	/*
//	*/
func _rbuUpdateTempSize(tls *libc.TLS, pFd uintptr, nNew Tsqlite3_int64) (r int32) {
	var nDiff Ti64
	var pRbu uintptr
	_, _ = nDiff, pRbu
	pRbu = (*Trbu_file)(unsafe.Pointer(pFd)).FpRbu
	nDiff = nNew - (*Trbu_file)(unsafe.Pointer(pFd)).Fsz
	**(**Ti64)(__ccgo_up(pRbu + 232)) += nDiff
	(*Trbu_file)(unsafe.Pointer(pFd)).Fsz = nNew
	if (*Tsqlite3rbu)(unsafe.Pointer(pRbu)).FszTempLimit != 0 && (*Tsqlite3rbu)(unsafe.Pointer(pRbu)).FszTemp > (*Tsqlite3rbu)(unsafe.Pointer(pRbu)).FszTempLimit {
		return int32(SQLITE_FULL)
	}
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** Take or release a shared-memory lock.
//	*/
func _rbuVfsShmLock(tls *libc.TLS, pFile uintptr, ofst int32, n int32, flags int32) (r int32) {
	var bCapture, rc int32
	var p, pRbu uintptr
	_, _, _, _ = bCapture, p, pRbu, rc
	p = pFile
	pRbu = (*Trbu_file)(unsafe.Pointer(p)).FpRbu
	rc = SQLITE_OK
	if pRbu != 0 && ((*Tsqlite3rbu)(unsafe.Pointer(pRbu)).FeStage == int32(RBU_STAGE_OAL) || (*Tsqlite3rbu)(unsafe.Pointer(pRbu)).FeStage == int32(RBU_STAGE_MOVE) || (*Tsqlite3rbu)(unsafe.Pointer(pRbu)).FeStage == int32(RBU_STAGE_DONE)) {
		/* Prevent SQLite from taking a shm-lock on the target file when it
		 ** is supplying heap memory to the upper layer in place of *-shm
		 ** segments. */
		if ofst == int32(WAL_LOCK_CKPT) && n == int32(1) {
			rc = int32(SQLITE_BUSY)
		}
	} else {
		bCapture = 0
		if pRbu != 0 && (*Tsqlite3rbu)(unsafe.Pointer(pRbu)).FeStage == int32(RBU_STAGE_CAPTURE) {
			bCapture = int32(1)
		}
		if bCapture == 0 || 0 == flags&int32(SQLITE_SHM_UNLOCK) {
			rc = (*(*func(*libc.TLS, uintptr, int32, int32, int32) int32)(unsafe.Pointer(&struct{ uintptr }{(*Tsqlite3_io_methods)(unsafe.Pointer((*Tsqlite3_file)(unsafe.Pointer((*Trbu_file)(unsafe.Pointer(p)).FpReal)).FpMethods)).FxShmLock})))(tls, (*Trbu_file)(unsafe.Pointer(p)).FpReal, ofst, n, flags)
			if bCapture != 0 && rc == SQLITE_OK {
				**(**Tu32)(__ccgo_up(pRbu + 200)) |= libc.Uint32FromInt32((int32(1)<<n - int32(1)) << ofst)
			}
		}
	}
	return rc
}

// C documentation
//
//	/*
//	** Read the content for page pPg out of the database file (or out of
//	** the WAL if that is where the most recent copy if found) into
//	** pPg->pData. A shared lock or greater must be held on the database
//	** file before this function is called.
//	**
//	** If page 1 is read, then the value of Pager.dbFileVers[] is set to
//	** the value read from the database file.
//	**
//	** If an IO error occurs, then the IO error is returned to the caller.
//	** Otherwise, SQLITE_OK is returned.
//	*/
func _readDbPage(tls *libc.TLS, pPg uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var dbFileVers, pPager uintptr
	var iOffset Ti64
	var rc int32
	var _ /* iFrame at bp+0 */ Tu32
	_, _, _, _ = dbFileVers, iOffset, pPager, rc
	pPager = (*TPgHdr)(unsafe.Pointer(pPg)).FpPager /* Pager object associated with page pPg */
	rc = SQLITE_OK                                  /* Return code */
	**(**Tu32)(__ccgo_up(bp)) = uint32(0)           /* Frame of WAL containing pgno */
	if (*TPager)(unsafe.Pointer(pPager)).FpWal != uintptr(0) {
		rc = _sqlite3WalFindFrame(tls, (*TPager)(unsafe.Pointer(pPager)).FpWal, (*TPgHdr)(unsafe.Pointer(pPg)).Fpgno, bp)
		if rc != 0 {
			return rc
		}
	}
	if **(**Tu32)(__ccgo_up(bp)) != 0 {
		rc = _sqlite3WalReadFrame(tls, (*TPager)(unsafe.Pointer(pPager)).FpWal, **(**Tu32)(__ccgo_up(bp)), int32((*TPager)(unsafe.Pointer(pPager)).FpageSize), (*TPgHdr)(unsafe.Pointer(pPg)).FpData)
	} else {
		iOffset = libc.Int64FromUint32((*TPgHdr)(unsafe.Pointer(pPg)).Fpgno-libc.Uint32FromInt32(1)) * (*TPager)(unsafe.Pointer(pPager)).FpageSize
		rc = _sqlite3OsRead(tls, (*TPager)(unsafe.Pointer(pPager)).Ffd, (*TPgHdr)(unsafe.Pointer(pPg)).FpData, int32((*TPager)(unsafe.Pointer(pPager)).FpageSize), iOffset)
		if rc == libc.Int32FromInt32(SQLITE_IOERR)|libc.Int32FromInt32(2)<<libc.Int32FromInt32(8) {
			rc = SQLITE_OK
		}
	}
	if (*TPgHdr)(unsafe.Pointer(pPg)).Fpgno == uint32(1) {
		if rc != 0 {
			/* If the read is unsuccessful, set the dbFileVers[] to something
			 ** that will never be a valid file version.  dbFileVers[] is a copy
			 ** of bytes 24..39 of the database.  Bytes 28..31 should always be
			 ** zero or the size of the database in page. Bytes 32..35 and 35..39
			 ** should be page numbers which are never 0xffffffff.  So filling
			 ** pPager->dbFileVers[] with all 0xff bytes should suffice.
			 **
			 ** For an encrypted database, the situation is more complex:  bytes
			 ** 24..39 of the database are white noise.  But the probability of
			 ** white noise equaling 16 bytes of 0xff is vanishingly small so
			 ** we should still be ok.
			 */
			libc.Xmemset(tls, pPager+108, int32(0xff), uint32(16))
		} else {
			dbFileVers = (*TPgHdr)(unsafe.Pointer(pPg)).FpData + 24
			libc.Xmemcpy(tls, pPager+108, dbFileVers, uint32(16))
		}
	}
	return rc
}

// C documentation
//
//	/*
//	** The journal file must be open when this is called. A journal header file
//	** (JOURNAL_HDR_SZ bytes) is read from the current location in the journal
//	** file. The current location in the journal file is given by
//	** pPager->journalOff. See comments above function writeJournalHdr() for
//	** a description of the journal header format.
//	**
//	** If the header is read successfully, *pNRec is set to the number of
//	** page records following this header and *pDbSize is set to the size of the
//	** database before the transaction began, in pages. Also, pPager->cksumInit
//	** is set to the value read from the journal header. SQLITE_OK is returned
//	** in this case.
//	**
//	** If the journal header file appears to be corrupted, SQLITE_DONE is
//	** returned and *pNRec and *PDbSize are undefined.  If JOURNAL_HDR_SZ bytes
//	** cannot be read from the journal file an error code is returned.
//	*/
func _readJournalHdr(tls *libc.TLS, pPager uintptr, isHot int32, journalSize Ti64, pNRec uintptr, pDbSize uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var iHdrOff Ti64
	var rc, v1, v2, v4 int32
	var v3, v5 bool
	var _ /* aMagic at bp+0 */ [8]uint8
	var _ /* iPageSize at bp+8 */ Tu32
	var _ /* iSectorSize at bp+12 */ Tu32
	_, _, _, _, _, _, _ = iHdrOff, rc, v1, v2, v3, v4, v5 /* Offset of journal header being read */
	/* Journal file must be open. */
	/* Advance Pager.journalOff to the start of the next sector. If the
	 ** journal file is too small for there to be a header stored at this
	 ** point, return SQLITE_DONE.
	 */
	(*TPager)(unsafe.Pointer(pPager)).FjournalOff = _journalHdrOffset(tls, pPager)
	if (*TPager)(unsafe.Pointer(pPager)).FjournalOff+libc.Int64FromUint32((*TPager)(unsafe.Pointer(pPager)).FsectorSize) > journalSize {
		return int32(SQLITE_DONE)
	}
	iHdrOff = (*TPager)(unsafe.Pointer(pPager)).FjournalOff
	/* Read in the first 8 bytes of the journal header. If they do not match
	 ** the  magic string found at the start of each journal header, return
	 ** SQLITE_DONE. If an IO error occurs, return an error code. Otherwise,
	 ** proceed.
	 */
	if isHot != 0 || iHdrOff != (*TPager)(unsafe.Pointer(pPager)).FjournalHdr {
		rc = _sqlite3OsRead(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd, bp, int32(8), iHdrOff)
		if rc != 0 {
			return rc
		}
		if libc.Xmemcmp(tls, bp, uintptr(unsafe.Pointer(&_aJournalMagic)), uint32(8)) != 0 {
			return int32(SQLITE_DONE)
		}
	}
	/* Read the first three 32-bit fields of the journal header: The nRec
	 ** field, the checksum-initializer and the database size at the start
	 ** of the transaction. Return an error code if anything goes wrong.
	 */
	v1 = _read32bits(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd, iHdrOff+int64(8), pNRec)
	rc = v1
	if v3 = SQLITE_OK != v1; !v3 {
		v2 = _read32bits(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd, iHdrOff+int64(12), pPager+52)
		rc = v2
	}
	if v5 = v3 || SQLITE_OK != v2; !v5 {
		v4 = _read32bits(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd, iHdrOff+int64(16), pDbSize)
		rc = v4
	}
	if v5 || SQLITE_OK != v4 {
		return rc
	}
	if (*TPager)(unsafe.Pointer(pPager)).FjournalOff == 0 { /* Sector-size field of journal header */
		/* Read the page-size and sector-size journal header fields. */
		v1 = _read32bits(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd, iHdrOff+int64(20), bp+12)
		rc = v1
		if v3 = SQLITE_OK != v1; !v3 {
			v2 = _read32bits(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd, iHdrOff+int64(24), bp+8)
			rc = v2
		}
		if v3 || SQLITE_OK != v2 {
			return rc
		}
		/* Versions of SQLite prior to 3.5.8 set the page-size field of the
		 ** journal header to zero. In this case, assume that the Pager.pageSize
		 ** variable is already set to the correct page size.
		 */
		if **(**Tu32)(__ccgo_up(bp + 8)) == uint32(0) {
			**(**Tu32)(__ccgo_up(bp + 8)) = libc.Uint32FromInt64((*TPager)(unsafe.Pointer(pPager)).FpageSize)
		}
		/* Check that the values read from the page-size and sector-size fields
		 ** are within range. To be 'in range', both values need to be a power
		 ** of two greater than or equal to 512 or 32, and not greater than their
		 ** respective compile time maximum limits.
		 */
		if **(**Tu32)(__ccgo_up(bp + 8)) < uint32(512) || **(**Tu32)(__ccgo_up(bp + 12)) < uint32(32) || **(**Tu32)(__ccgo_up(bp + 8)) > uint32(SQLITE_MAX_PAGE_SIZE) || **(**Tu32)(__ccgo_up(bp + 12)) > uint32(MAX_SECTOR_SIZE) || (**(**Tu32)(__ccgo_up(bp + 8))-uint32(1))&**(**Tu32)(__ccgo_up(bp + 8)) != uint32(0) || (**(**Tu32)(__ccgo_up(bp + 12))-uint32(1))&**(**Tu32)(__ccgo_up(bp + 12)) != uint32(0) {
			/* If the either the page-size or sector-size in the journal-header is
			 ** invalid, then the process that wrote the journal-header must have
			 ** crashed before the header was synced. In this case stop reading
			 ** the journal file here.
			 */
			return int32(SQLITE_DONE)
		}
		/* Update the page-size to match the value read from the journal.
		 ** Use a testcase() macro to make sure that malloc failure within
		 ** PagerSetPagesize() is tested.
		 */
		rc = _sqlite3PagerSetPagesize(tls, pPager, bp+8, -int32(1))
		/* Update the assumed sector-size to match the value used by
		 ** the process that created this journal. If this journal was
		 ** created by a process other than this one, then this routine
		 ** is being called from within pager_playback(). The local value
		 ** of Pager.sectorSize is restored at the end of that routine.
		 */
		(*TPager)(unsafe.Pointer(pPager)).FsectorSize = **(**Tu32)(__ccgo_up(bp + 12))
	}
	**(**Ti64)(__ccgo_up(pPager + 76)) += libc.Int64FromUint32((*TPager)(unsafe.Pointer(pPager)).FsectorSize)
	return rc
}

// C documentation
//
//	/*
//	** When this is called the journal file for pager pPager must be open.
//	** This function attempts to read a super-journal file name from the
//	** end of the file and, if successful, copies it into memory supplied
//	** by the caller. See comments above writeSuperJournal() for the format
//	** used to store a super-journal file name at the end of a journal file.
//	**
//	** zSuper must point to a buffer of at least nSuper bytes allocated by
//	** the caller. This should be sqlite3_vfs.mxPathname+1 (to ensure there is
//	** enough space to write the super-journal name). If the super-journal
//	** name in the journal is longer than nSuper bytes (including a
//	** nul-terminator), then this is handled as if no super-journal name
//	** were present in the journal.
//	**
//	** If a super-journal file name is present at the end of the journal
//	** file, then it is copied into the buffer pointed to by zSuper. A
//	** nul-terminator byte is appended to the buffer following the
//	** super-journal file name.
//	**
//	** If it is determined that no super-journal file name is present
//	** zSuper[0] is set to 0 and SQLITE_OK returned.
//	**
//	** If an error occurs while reading from the journal file, an SQLite
//	** error code is returned.
//	*/
func _readSuperJournal(tls *libc.TLS, pJrnl uintptr, zSuper uintptr, nSuper Tu64) (r int32) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var rc, v1, v2, v4, v6, v8 int32
	var u Tu32
	var v3, v5, v7, v9 bool
	var _ /* aMagic at bp+24 */ [8]uint8
	var _ /* cksum at bp+16 */ Tu32
	var _ /* len at bp+0 */ Tu32
	var _ /* szJ at bp+8 */ Ti64
	_, _, _, _, _, _, _, _, _, _, _ = rc, u, v1, v2, v3, v4, v5, v6, v7, v8, v9 /* A buffer to hold the magic header */
	**(**int8)(__ccgo_up(zSuper)) = int8('\000')
	v1 = _sqlite3OsFileSize(tls, pJrnl, bp+8)
	rc = v1
	if v3 = SQLITE_OK != v1 || **(**Ti64)(__ccgo_up(bp + 8)) < int64(16); !v3 {
		v2 = _read32bits(tls, pJrnl, **(**Ti64)(__ccgo_up(bp + 8))-int64(16), bp)
		rc = v2
	}
	if v5 = v3 || SQLITE_OK != v2 || uint64(**(**Tu32)(__ccgo_up(bp))) >= nSuper || libc.Int64FromUint32(**(**Tu32)(__ccgo_up(bp))) > **(**Ti64)(__ccgo_up(bp + 8))-int64(16) || **(**Tu32)(__ccgo_up(bp)) == uint32(0); !v5 {
		v4 = _read32bits(tls, pJrnl, **(**Ti64)(__ccgo_up(bp + 8))-int64(12), bp+16)
		rc = v4
	}
	if v7 = v5 || SQLITE_OK != v4; !v7 {
		v6 = _sqlite3OsRead(tls, pJrnl, bp+24, int32(8), **(**Ti64)(__ccgo_up(bp + 8))-int64(8))
		rc = v6
	}
	if v9 = v7 || SQLITE_OK != v6 || libc.Xmemcmp(tls, bp+24, uintptr(unsafe.Pointer(&_aJournalMagic)), uint32(8)) != 0; !v9 {
		v8 = _sqlite3OsRead(tls, pJrnl, zSuper, libc.Int32FromUint32(**(**Tu32)(__ccgo_up(bp))), **(**Ti64)(__ccgo_up(bp + 8))-int64(16)-libc.Int64FromUint32(**(**Tu32)(__ccgo_up(bp))))
		rc = v8
	}
	if v9 || SQLITE_OK != v8 {
		return rc
	}
	/* See if the checksum matches the super-journal name */
	u = uint32(0)
	for {
		if !(u < **(**Tu32)(__ccgo_up(bp))) {
			break
		}
		**(**Tu32)(__ccgo_up(bp + 16)) = **(**Tu32)(__ccgo_up(bp + 16)) - libc.Uint32FromInt8(**(**int8)(__ccgo_up(zSuper + uintptr(u))))
		goto _10
	_10:
		;
		u = u + 1
	}
	if **(**Tu32)(__ccgo_up(bp + 16)) != 0 {
		/* If the checksum doesn't add up, then one or more of the disk sectors
		 ** containing the super-journal filename is corrupted. This means
		 ** definitely roll back, so just return SQLITE_OK and report a (nul)
		 ** super-journal filename.
		 */
		**(**Tu32)(__ccgo_up(bp)) = uint32(0)
	}
	**(**int8)(__ccgo_up(zSuper + uintptr(**(**Tu32)(__ccgo_up(bp))))) = int8('\000')
	**(**int8)(__ccgo_up(zSuper + uintptr(**(**Tu32)(__ccgo_up(bp))+uint32(1)))) = int8('\000')
	return SQLITE_OK
}

func _reinsertNodeContent(tls *libc.TLS, pRtree uintptr, pNode uintptr) (r int32) {
	bp := tls.Alloc(64)
	defer tls.Free(64)
	var ii, nCell, rc, rc2 int32
	var _ /* cell at bp+4 */ TRtreeCell
	var _ /* pInsert at bp+0 */ uintptr
	_, _, _, _ = ii, nCell, rc, rc2
	rc = SQLITE_OK
	nCell = _readInt16(tls, (*TRtreeNode)(unsafe.Pointer(pNode)).FzData+2)
	ii = 0
	for {
		if !(rc == SQLITE_OK && ii < nCell) {
			break
		}
		_nodeGetCell(tls, pRtree, pNode, ii, bp+4)
		/* Find a node to store this cell in. pNode->iNode currently contains
		 ** the height of the sub-tree headed by the cell.
		 */
		rc = _ChooseLeaf(tls, pRtree, bp+4, int32((*TRtreeNode)(unsafe.Pointer(pNode)).FiNode), bp)
		if rc == SQLITE_OK {
			rc = _rtreeInsertCell(tls, pRtree, **(**uintptr)(__ccgo_up(bp)), bp+4, int32((*TRtreeNode)(unsafe.Pointer(pNode)).FiNode))
			rc2 = _nodeRelease(tls, pRtree, **(**uintptr)(__ccgo_up(bp)))
			if rc == SQLITE_OK {
				rc = rc2
			}
		}
		goto _1
	_1:
		;
		ii = ii + 1
	}
	return rc
}

// C documentation
//
//	/*
//	** Remove connection db from the blocked connections list. If connection
//	** db is not currently a part of the list, this function is a no-op.
//	*/
func _removeFromBlockedList(tls *libc.TLS, db uintptr) {
	var pp uintptr
	_ = pp
	pp = uintptr(unsafe.Pointer(&_sqlite3BlockedList))
	for {
		if !(**(**uintptr)(__ccgo_up(pp)) != 0) {
			break
		}
		if **(**uintptr)(__ccgo_up(pp)) == db {
			**(**uintptr)(__ccgo_up(pp)) = (*Tsqlite3)(unsafe.Pointer(**(**uintptr)(__ccgo_up(pp)))).FpNextBlocked
			break
		}
		goto _1
	_1:
		;
		pp = **(**uintptr)(__ccgo_up(pp)) + 572
	}
}

// C documentation
//
//	/* Function:  sqlite_rename_test(DB,SQL,TYPE,NAME,ISTEMP,WHEN,DQS)
//	**
//	** An SQL user function that checks that there are no parse or symbol
//	** resolution problems in a CREATE TRIGGER|TABLE|VIEW|INDEX statement.
//	** After an ALTER TABLE .. RENAME operation is performed and the schema
//	** reloaded, this function is called on each SQL statement in the schema
//	** to ensure that it is still usable.
//	**
//	**   0: Database name ("main", "temp" etc.).
//	**   1: SQL statement.
//	**   2: Object type ("view", "table", "trigger" or "index").
//	**   3: Object name.
//	**   4: True if object is from temp schema.
//	**   5: "when" part of error message.
//	**   6: True to disable the DQS quirk when parsing SQL.
//	**
//	** The return value is computed as follows:
//	**
//	**   A. If an error is seen and not in PRAGMA writable_schema=ON mode,
//	**      then raise the error.
//	**   B. Else if a trigger is created and the the table that the trigger is
//	**      attached to is in database zDb, then return 1.
//	**   C. Otherwise return NULL.
//	*/
func _renameTableTest(tls *libc.TLS, context uintptr, NotUsed int32, argv uintptr) {
	bp := tls.Alloc(320)
	defer tls.Free(320)
	var bNoDQS, bTemp, i1, i2, isLegacy, rc int32
	var db, zDb, zInput, zWhen uintptr
	var flags Tu64
	var xAuth Tsqlite3_xauth
	var _ /* sNC at bp+280 */ TNameContext
	var _ /* sParse at bp+0 */ TParse
	_, _, _, _, _, _, _, _, _, _, _, _ = bNoDQS, bTemp, db, flags, i1, i2, isLegacy, rc, xAuth, zDb, zInput, zWhen
	db = Xsqlite3_context_db_handle(tls, context)
	zDb = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv)))
	zInput = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv + 1*4)))
	bTemp = Xsqlite3_value_int(tls, **(**uintptr)(__ccgo_up(argv + 4*4)))
	isLegacy = libc.Int32FromUint64((*Tsqlite3)(unsafe.Pointer(db)).Fflags & libc.Uint64FromInt32(SQLITE_LegacyAlter))
	zWhen = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv + 5*4)))
	bNoDQS = Xsqlite3_value_int(tls, **(**uintptr)(__ccgo_up(argv + 6*4)))
	xAuth = (*Tsqlite3)(unsafe.Pointer(db)).FxAuth
	(*Tsqlite3)(unsafe.Pointer(db)).FxAuth = uintptr(0)
	_ = NotUsed
	if zDb != 0 && zInput != 0 {
		flags = (*Tsqlite3)(unsafe.Pointer(db)).Fflags
		if bNoDQS != 0 {
			**(**Tu64)(__ccgo_up(db + 28)) &= libc.Uint64FromInt32(^(libc.Int32FromInt32(SQLITE_DqsDML) | libc.Int32FromInt32(SQLITE_DqsDDL)))
		}
		rc = _renameParseSql(tls, bp, zDb, db, zInput, bTemp)
		(*Tsqlite3)(unsafe.Pointer(db)).Fflags = flags
		if rc == SQLITE_OK {
			if isLegacy == 0 && (**(**TParse)(__ccgo_up(bp))).FpNewTable != 0 && libc.Int32FromUint8((*TTable)(unsafe.Pointer((**(**TParse)(__ccgo_up(bp))).FpNewTable)).FeTabType) == int32(TABTYP_VIEW) {
				libc.Xmemset(tls, bp+280, 0, uint32(36))
				(**(**TNameContext)(__ccgo_up(bp + 280))).FpParse = bp
				_sqlite3SelectPrep(tls, bp, (*(*struct {
					FpSelect uintptr
				})(unsafe.Pointer(&(*TTable)(unsafe.Pointer((**(**TParse)(__ccgo_up(bp))).FpNewTable)).Fu))).FpSelect, bp+280)
				if (**(**TParse)(__ccgo_up(bp))).FnErr != 0 {
					rc = (**(**TParse)(__ccgo_up(bp))).Frc
				}
			} else {
				if (**(**TParse)(__ccgo_up(bp))).FpNewTrigger != 0 {
					if isLegacy == 0 {
						rc = _renameResolveTrigger(tls, bp)
					}
					if rc == SQLITE_OK {
						i1 = _sqlite3SchemaToIndex(tls, db, (*TTrigger)(unsafe.Pointer((**(**TParse)(__ccgo_up(bp))).FpNewTrigger)).FpTabSchema)
						i2 = _sqlite3FindDbName(tls, db, zDb)
						if i1 == i2 {
							/* Handle output case B */
							Xsqlite3_result_int(tls, context, int32(1))
						}
					}
				}
			}
		}
		if rc != SQLITE_OK && zWhen != 0 && !(_sqlite3WritableSchema(tls, db) != 0) {
			/* Output case A */
			_renameColumnParseError(tls, context, zWhen, **(**uintptr)(__ccgo_up(argv + 2*4)), **(**uintptr)(__ccgo_up(argv + 3*4)), bp)
		}
		_renameParseCleanup(tls, bp)
	}
	(*Tsqlite3)(unsafe.Pointer(db)).FxAuth = xAuth
}

// C documentation
//
//	/*
//	** The replace() function.  Three arguments are all strings: call
//	** them A, B, and C. The result is also a string which is derived
//	** from A by replacing every occurrence of B with C.  The match
//	** must be exact.  Collating sequences are not used.
//	*/
func _replaceFunc(tls *libc.TLS, context uintptr, argc int32, argv uintptr) {
	var cntExpand uint32
	var db, zOld, zOut, zPattern, zRep, zStr uintptr
	var i, j, loopLimit, nPattern, nRep, nStr, v2, v3 int32
	var nOut Ti64
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = cntExpand, db, i, j, loopLimit, nOut, nPattern, nRep, nStr, zOld, zOut, zPattern, zRep, zStr, v2, v3 /* Number zOut expansions */
	db = Xsqlite3_context_db_handle(tls, context)
	_ = argc
	zStr = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv)))
	if zStr == uintptr(0) {
		return
	}
	nStr = Xsqlite3_value_bytes(tls, **(**uintptr)(__ccgo_up(argv)))
	/* No encoding change */
	zPattern = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv + 1*4)))
	if zPattern == uintptr(0) {
		return
	}
	if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zPattern))) == 0 {
		Xsqlite3_result_text(tls, context, zStr, nStr, uintptr(-libc.Int32FromInt32(1)))
		return
	}
	nPattern = Xsqlite3_value_bytes(tls, **(**uintptr)(__ccgo_up(argv + 1*4)))
	/* No encoding change */
	zRep = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv + 2*4)))
	if zRep == uintptr(0) {
		return
	}
	nRep = Xsqlite3_value_bytes(tls, **(**uintptr)(__ccgo_up(argv + 2*4)))
	nOut = int64(nStr + int32(1))
	zOut = _contextMalloc(tls, context, nOut)
	if zOut == uintptr(0) {
		return
	}
	loopLimit = nStr - nPattern
	cntExpand = uint32(0)
	v2 = libc.Int32FromInt32(0)
	j = v2
	i = v2
	for {
		if !(i <= loopLimit) {
			break
		}
		if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zStr + uintptr(i)))) != libc.Int32FromUint8(**(**uint8)(__ccgo_up(zPattern))) || libc.Xmemcmp(tls, zStr+uintptr(i), zPattern, libc.Uint32FromInt32(nPattern)) != 0 {
			v3 = j
			j = j + 1
			**(**uint8)(__ccgo_up(zOut + uintptr(v3))) = **(**uint8)(__ccgo_up(zStr + uintptr(i)))
		} else {
			if nRep > nPattern {
				nOut = nOut + int64(nRep-nPattern)
				if nOut-int64(1) > int64(**(**int32)(__ccgo_up(db + 116))) {
					Xsqlite3_result_error_toobig(tls, context)
					Xsqlite3_free(tls, zOut)
					return
				}
				cntExpand = cntExpand + 1
				if cntExpand&(cntExpand-uint32(1)) == uint32(0) {
					zOld = zOut
					zOut = _sqlite3Realloc(tls, zOut, libc.Uint64FromInt64(int64(int32(nOut))+(nOut-int64(nStr)-int64(1))))
					if zOut == uintptr(0) {
						Xsqlite3_result_error_nomem(tls, context)
						Xsqlite3_free(tls, zOld)
						return
					}
				}
			}
			libc.Xmemcpy(tls, zOut+uintptr(j), zRep, libc.Uint32FromInt32(nRep))
			j = j + nRep
			i = i + (nPattern - int32(1))
		}
		goto _1
	_1:
		;
		i = i + 1
	}
	libc.Xmemcpy(tls, zOut+uintptr(j), zStr+uintptr(i), libc.Uint32FromInt32(nStr-i))
	j = j + (nStr - i)
	**(**uint8)(__ccgo_up(zOut + uintptr(j))) = uint8(0)
	Xsqlite3_result_text(tls, context, zOut, j, __ccgo_fp(Xsqlite3_free))
}

// C documentation
//
//	/*
//	** Reset a cursor back to its initial state.
//	*/
func _resetCursor(tls *libc.TLS, pCsr uintptr) {
	var i, ii int32
	var pInfo, pRtree, pStmt uintptr
	_, _, _, _, _ = i, ii, pInfo, pRtree, pStmt
	pRtree = (*TRtreeCursor)(unsafe.Pointer(pCsr)).Fbase.FpVtab
	if (*TRtreeCursor)(unsafe.Pointer(pCsr)).FaConstraint != 0 { /* Used to iterate through constraint array */
		i = 0
		for {
			if !(i < (*TRtreeCursor)(unsafe.Pointer(pCsr)).FnConstraint) {
				break
			}
			pInfo = (**(**TRtreeConstraint)(__ccgo_up((*TRtreeCursor)(unsafe.Pointer(pCsr)).FaConstraint + uintptr(i)*20))).FpInfo
			if pInfo != 0 {
				if (*Tsqlite3_rtree_query_info)(unsafe.Pointer(pInfo)).FxDelUser != 0 {
					(*(*func(*libc.TLS, uintptr))(unsafe.Pointer(&struct{ uintptr }{(*Tsqlite3_rtree_query_info)(unsafe.Pointer(pInfo)).FxDelUser})))(tls, (*Tsqlite3_rtree_query_info)(unsafe.Pointer(pInfo)).FpUser)
				}
				Xsqlite3_free(tls, pInfo)
			}
			goto _1
		_1:
			;
			i = i + 1
		}
		Xsqlite3_free(tls, (*TRtreeCursor)(unsafe.Pointer(pCsr)).FaConstraint)
		(*TRtreeCursor)(unsafe.Pointer(pCsr)).FaConstraint = uintptr(0)
	}
	ii = 0
	for {
		if !(ii < int32(RTREE_CACHE_SZ)) {
			break
		}
		_nodeRelease(tls, pRtree, **(**uintptr)(__ccgo_up(pCsr + 60 + uintptr(ii)*4)))
		goto _2
	_2:
		;
		ii = ii + 1
	}
	Xsqlite3_free(tls, (*TRtreeCursor)(unsafe.Pointer(pCsr)).FaPoint)
	pStmt = (*TRtreeCursor)(unsafe.Pointer(pCsr)).FpReadAux
	libc.Xmemset(tls, pCsr, 0, uint32(244))
	(*TRtreeCursor)(unsafe.Pointer(pCsr)).Fbase.FpVtab = pRtree
	(*TRtreeCursor)(unsafe.Pointer(pCsr)).FpReadAux = pStmt
	/* The following will only fail if the previous sqlite3_step() call failed,
	 ** in which case the error has already been caught. This statement never
	 ** encounters an error within an sqlite3_column_xxx() function, as it
	 ** calls sqlite3_column_value(), which does not use malloc(). So it is safe
	 ** to ignore the error code here.  */
	Xsqlite3_reset(tls, pStmt)
}

// C documentation
//
//	/*
//	** pOrderBy is an ORDER BY or GROUP BY clause in SELECT statement pSelect.
//	** The Name context of the SELECT statement is pNC.  zType is either
//	** "ORDER" or "GROUP" depending on which type of clause pOrderBy is.
//	**
//	** This routine resolves each term of the clause into an expression.
//	** If the order-by term is an integer I between 1 and N (where N is the
//	** number of columns in the result set of the SELECT) then the expression
//	** in the resolution is a copy of the I-th result-set expression.  If
//	** the order-by term is an identifier that corresponds to the AS-name of
//	** a result-set expression, then the term resolves to a copy of the
//	** result-set expression.  Otherwise, the expression is resolved in
//	** the usual way - using sqlite3ResolveExprNames().
//	**
//	** This routine returns the number of errors.  If errors occur, then
//	** an appropriate error message might be left in pParse.  (OOM errors
//	** excepted.)
//	*/
func _resolveOrderGroupBy(tls *libc.TLS, pNC uintptr, pSelect uintptr, pOrderBy uintptr, zType uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var i, j, nResult int32
	var pE, pE2, pItem, pParse uintptr
	var _ /* iCol at bp+0 */ int32
	_, _, _, _, _, _, _ = i, j, nResult, pE, pE2, pItem, pParse /* Number of terms in the result set */
	nResult = (*TExprList)(unsafe.Pointer((*TSelect)(unsafe.Pointer(pSelect)).FpEList)).FnExpr
	pParse = (*TNameContext)(unsafe.Pointer(pNC)).FpParse
	i = 0
	pItem = pOrderBy + 8
	for {
		if !(i < (*TExprList)(unsafe.Pointer(pOrderBy)).FnExpr) {
			break
		}
		pE = (*TExprList_item)(unsafe.Pointer(pItem)).FpExpr
		pE2 = _sqlite3ExprSkipCollateAndLikely(tls, pE)
		if pE2 == uintptr(0) {
			goto _1
		}
		if int32(**(**int8)(__ccgo_up(zType))) != int32('G') {
			**(**int32)(__ccgo_up(bp)) = _resolveAsName(tls, pParse, (*TSelect)(unsafe.Pointer(pSelect)).FpEList, pE2)
			if **(**int32)(__ccgo_up(bp)) > 0 {
				/* If an AS-name match is found, mark this ORDER BY column as being
				 ** a copy of the iCol-th result-set column.  The subsequent call to
				 ** sqlite3ResolveOrderGroupBy() will convert the expression to a
				 ** copy of the iCol-th result-set expression. */
				(*(*struct {
					FiOrderByCol Tu16
					FiAlias      Tu16
				})(unsafe.Pointer(pItem + 16))).FiOrderByCol = libc.Uint16FromInt32(**(**int32)(__ccgo_up(bp)))
				goto _1
			}
		}
		if _sqlite3ExprIsInteger(tls, pE2, bp, uintptr(0)) != 0 {
			/* The ORDER BY term is an integer constant.  Again, set the column
			 ** number so that sqlite3ResolveOrderGroupBy() will convert the
			 ** order-by term to a copy of the result-set expression */
			if **(**int32)(__ccgo_up(bp)) < int32(1) || **(**int32)(__ccgo_up(bp)) > int32(0xffff) {
				_resolveOutOfRangeError(tls, pParse, zType, i+int32(1), nResult, pE2)
				return int32(1)
			}
			(*(*struct {
				FiOrderByCol Tu16
				FiAlias      Tu16
			})(unsafe.Pointer(pItem + 16))).FiOrderByCol = libc.Uint16FromInt32(**(**int32)(__ccgo_up(bp)))
			goto _1
		}
		/* Otherwise, treat the ORDER BY term as an ordinary expression */
		(*(*struct {
			FiOrderByCol Tu16
			FiAlias      Tu16
		})(unsafe.Pointer(pItem + 16))).FiOrderByCol = uint16(0)
		if _sqlite3ResolveExprNames(tls, pNC, pE) != 0 {
			return int32(1)
		}
		j = 0
		for {
			if !(j < (*TExprList)(unsafe.Pointer((*TSelect)(unsafe.Pointer(pSelect)).FpEList)).FnExpr) {
				break
			}
			if _sqlite3ExprCompare(tls, uintptr(0), pE, (*(*TExprList_item)(unsafe.Pointer((*TSelect)(unsafe.Pointer(pSelect)).FpEList + 8 + uintptr(j)*20))).FpExpr, -int32(1)) == 0 {
				/* Since this expression is being changed into a reference
				 ** to an identical expression in the result set, remove all Window
				 ** objects belonging to the expression from the Select.pWin list. */
				_windowRemoveExprFromSelect(tls, pSelect, pE)
				(*(*struct {
					FiOrderByCol Tu16
					FiAlias      Tu16
				})(unsafe.Pointer(pItem + 16))).FiOrderByCol = libc.Uint16FromInt32(j + int32(1))
			}
			goto _2
		_2:
			;
			j = j + 1
		}
		goto _1
	_1:
		;
		i = i + 1
		pItem += 20
	}
	return _sqlite3ResolveOrderGroupBy(tls, pParse, pSelect, pOrderBy, zType)
}

// C documentation
//
//	/*
//	** This routine is called after all opcodes have been inserted.  It loops
//	** through all the opcodes and fixes up some details.
//	**
//	** (1) For each jump instruction with a negative P2 value (a label)
//	**     resolve the P2 value to an actual address.
//	**
//	** (2) Compute the maximum number of arguments used by the xUpdate/xFilter
//	**     methods of any virtual table and store that value in *pMaxVtabArgs.
//	**
//	** (3) Update the Vdbe.readOnly and Vdbe.bIsReader flags to accurately
//	**     indicate what the prepared statement actually does.
//	**
//	** (4) (discontinued)
//	**
//	** (5) Reclaim the memory allocated for storing labels.
//	**
//	** This routine will only function correctly if the mkopcodeh.tcl generator
//	** script numbers the opcodes correctly.  Changes to this routine must be
//	** coordinated with changes to mkopcodeh.tcl.
//	*/
func _resolveP2Values(tls *libc.TLS, p uintptr, pMaxVtabArgs uintptr) {
	var aLabel, pOp, pParse uintptr
	var n, nMaxVtabArgs int32
	_, _, _, _, _ = aLabel, n, nMaxVtabArgs, pOp, pParse
	nMaxVtabArgs = **(**int32)(__ccgo_up(pMaxVtabArgs))
	pParse = (*TVdbe)(unsafe.Pointer(p)).FpParse
	aLabel = (*TParse)(unsafe.Pointer(pParse)).FaLabel
	/* tag-20230419-1 */
	libc.SetBitFieldPtr16Uint32(p+144, libc.Uint32FromInt32(1), 6, 0x40)
	libc.SetBitFieldPtr16Uint32(p+144, libc.Uint32FromInt32(0), 7, 0x80)
	pOp = (*TVdbe)(unsafe.Pointer(p)).FaOp + uintptr((*TVdbe)(unsafe.Pointer(p)).FnOp-int32(1))*20
	for int32(1) != 0 {
		/* Only JUMP opcodes and the short list of special opcodes in the switch
		 ** below need to be considered.  The mkopcodeh.tcl generator script groups
		 ** all these opcodes together near the front of the opcode list.  Skip
		 ** any opcode that does not need processing by virtual of the fact that
		 ** it is larger than SQLITE_MX_JUMP_OPCODE, as a performance optimization.
		 */
		if libc.Int32FromUint8((*TOp)(unsafe.Pointer(pOp)).Fopcode) <= int32(SQLITE_MX_JUMP_OPCODE) {
			/* NOTE: Be sure to update mkopcodeh.tcl when adding or removing
			 ** cases from this switch! */
			switch libc.Int32FromUint8((*TOp)(unsafe.Pointer(pOp)).Fopcode) {
			case int32(OP_Transaction):
				if (*TOp)(unsafe.Pointer(pOp)).Fp2 != 0 {
					libc.SetBitFieldPtr16Uint32(p+144, libc.Uint32FromInt32(0), 6, 0x40)
				}
				fallthrough
			case int32(OP_AutoCommit):
				fallthrough
			case OP_Savepoint:
				libc.SetBitFieldPtr16Uint32(p+144, libc.Uint32FromInt32(1), 7, 0x80)
			case int32(OP_Checkpoint):
				fallthrough
			case int32(OP_Vacuum):
				fallthrough
			case int32(OP_JournalMode):
				libc.SetBitFieldPtr16Uint32(p+144, libc.Uint32FromInt32(0), 6, 0x40)
				libc.SetBitFieldPtr16Uint32(p+144, libc.Uint32FromInt32(1), 7, 0x80)
			case int32(OP_Init):
				goto resolve_p2_values_loop_exit
			case int32(OP_VUpdate):
				if (*TOp)(unsafe.Pointer(pOp)).Fp2 > nMaxVtabArgs {
					nMaxVtabArgs = (*TOp)(unsafe.Pointer(pOp)).Fp2
				}
			case int32(OP_VFilter):
				/* The instruction immediately prior to VFilter will be an
				 ** OP_Integer that sets the "argc" value for the VFilter.  See
				 ** the code where OP_VFilter is generated at tag-20250207a. */
				n = (**(**TOp)(__ccgo_up(pOp + uintptr(-libc.Int32FromInt32(1))*20))).Fp1
				if n > nMaxVtabArgs {
					nMaxVtabArgs = n
				}
				/* Fall through into the default case */
				fallthrough
			default:
				if (*TOp)(unsafe.Pointer(pOp)).Fp2 < 0 {
					/* The mkopcodeh.tcl script has so arranged things that the only
					 ** non-jump opcodes less than SQLITE_MX_JUMP_CODE are guaranteed to
					 ** have non-negative values for P2. */
					/* True because of tag-20230419-1 */
					(*TOp)(unsafe.Pointer(pOp)).Fp2 = **(**int32)(__ccgo_up(aLabel + uintptr(^(*TOp)(unsafe.Pointer(pOp)).Fp2)*4))
				}
				/* OPFLG_JUMP opcodes never have P2==0, though OPFLG_JUMP0 opcodes
				 ** might */
				/* Jumps never go off the end of the bytecode array */
				break
			}
			/* The mkopcodeh.tcl script has so arranged things that the only
			 ** non-jump opcodes less than SQLITE_MX_JUMP_CODE are guaranteed to
			 ** have non-negative values for P2. */
		}
		pOp -= 20
	}
	goto resolve_p2_values_loop_exit
resolve_p2_values_loop_exit:
	;
	if aLabel != 0 {
		_sqlite3DbNNFreeNN(tls, (*TVdbe)(unsafe.Pointer(p)).Fdb, (*TParse)(unsafe.Pointer(pParse)).FaLabel)
		(*TParse)(unsafe.Pointer(pParse)).FaLabel = uintptr(0)
	}
	(*TParse)(unsafe.Pointer(pParse)).FnLabel = 0
	**(**int32)(__ccgo_up(pMaxVtabArgs)) = nMaxVtabArgs
}

// C documentation
//
//	/*
//	** Allocate a new RowSetEntry object that is associated with the
//	** given RowSet.  Return a pointer to the new and completely uninitialized
//	** object.
//	**
//	** In an OOM situation, the RowSet.db->mallocFailed flag is set and this
//	** routine returns NULL.
//	*/
func _rowSetEntryAlloc(tls *libc.TLS, p uintptr) (r uintptr) {
	var pNew, v1, v2 uintptr
	_, _, _ = pNew, v1, v2
	if libc.Int32FromUint16((*TRowSet)(unsafe.Pointer(p)).FnFresh) == 0 {
		pNew = _sqlite3DbMallocRawNN(tls, (*TRowSet)(unsafe.Pointer(p)).Fdb, uint64(1012))
		if pNew == uintptr(0) {
			return uintptr(0)
		}
		(*TRowSetChunk)(unsafe.Pointer(pNew)).FpNextChunk = (*TRowSet)(unsafe.Pointer(p)).FpChunk
		(*TRowSet)(unsafe.Pointer(p)).FpChunk = pNew
		(*TRowSet)(unsafe.Pointer(p)).FpFresh = pNew + 4
		(*TRowSet)(unsafe.Pointer(p)).FnFresh = uint16(libc.Uint32FromInt32(libc.Int32FromInt32(ROWSET_ALLOCATION_SIZE)-libc.Int32FromInt32(8)) / libc.Uint32FromInt64(16))
	}
	(*TRowSet)(unsafe.Pointer(p)).FnFresh = (*TRowSet)(unsafe.Pointer(p)).FnFresh - 1
	v2 = p + 16
	v1 = *(*uintptr)(unsafe.Pointer(v2))
	*(*uintptr)(unsafe.Pointer(v2)) += 16
	return v1
}

// C documentation
//
//	/*
//	** Rtree virtual table module xBestIndex method. There are three
//	** table scan strategies to choose from (in order from most to
//	** least desirable):
//	**
//	**   idxNum     idxStr        Strategy
//	**   ------------------------------------------------
//	**     1        Unused        Direct lookup by rowid.
//	**     2        See below     R-tree query or full-table scan.
//	**   ------------------------------------------------
//	**
//	** If strategy 1 is used, then idxStr is not meaningful. If strategy
//	** 2 is used, idxStr is formatted to contain 2 bytes for each
//	** constraint used. The first two bytes of idxStr correspond to
//	** the constraint in sqlite3_index_info.aConstraintUsage[] with
//	** (argvIndex==1) etc.
//	**
//	** The first of each pair of bytes in idxStr identifies the constraint
//	** operator as follows:
//	**
//	**   Operator    Byte Value
//	**   ----------------------
//	**      =        0x41 ('A')
//	**     <=        0x42 ('B')
//	**      <        0x43 ('C')
//	**     >=        0x44 ('D')
//	**      >        0x45 ('E')
//	**   MATCH       0x46 ('F')
//	**   ----------------------
//	**
//	** The second of each pair of bytes identifies the coordinate column
//	** to which the constraint applies. The leftmost coordinate column
//	** is 'a', the second from the left 'b' etc.
//	*/
func _rtreeBestIndex(tls *libc.TLS, tab uintptr, pIdxInfo uintptr) (r int32) {
	bp := tls.Alloc(48)
	defer tls.Free(48)
	var bMatch, iIdx, ii, jj, rc, v4 int32
	var doOmit, op Tu8
	var nRow Ti64
	var p, pRtree uintptr
	var _ /* zIdxStr at bp+0 */ [41]int8
	_, _, _, _, _, _, _, _, _, _, _ = bMatch, doOmit, iIdx, ii, jj, nRow, op, p, pRtree, rc, v4
	pRtree = tab
	rc = SQLITE_OK
	bMatch = 0 /* Estimated rows returned by this scan */
	iIdx = 0
	libc.Xmemset(tls, bp, 0, uint32(41))
	/* Check if there exists a MATCH constraint - even an unusable one. If there
	 ** is, do not consider the lookup-by-rowid plan as using such a plan would
	 ** require the VDBE to evaluate the MATCH constraint, which is not currently
	 ** possible. */
	ii = 0
	for {
		if !(ii < (*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FnConstraint) {
			break
		}
		if libc.Int32FromUint8((**(**Tsqlite3_index_constraint)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraint + uintptr(ii)*12))).Fop) == int32(SQLITE_INDEX_CONSTRAINT_MATCH) {
			bMatch = int32(1)
		}
		goto _1
	_1:
		;
		ii = ii + 1
	}
	ii = 0
	for {
		if !(ii < (*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FnConstraint && iIdx < libc.Int32FromUint32(libc.Uint32FromInt64(41)-libc.Uint32FromInt32(1))) {
			break
		}
		p = (*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraint + uintptr(ii)*12
		if bMatch == 0 && (*Tsqlite3_index_constraint)(unsafe.Pointer(p)).Fusable != 0 && (*Tsqlite3_index_constraint)(unsafe.Pointer(p)).FiColumn <= 0 && libc.Int32FromUint8((*Tsqlite3_index_constraint)(unsafe.Pointer(p)).Fop) == int32(SQLITE_INDEX_CONSTRAINT_EQ) {
			jj = 0
			for {
				if !(jj < ii) {
					break
				}
				(**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraintUsage + uintptr(jj)*8))).FargvIndex = 0
				(**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraintUsage + uintptr(jj)*8))).Fomit = uint8(0)
				goto _3
			_3:
				;
				jj = jj + 1
			}
			(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FidxNum = int32(1)
			(**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraintUsage + uintptr(ii)*8))).FargvIndex = int32(1)
			(**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraintUsage + uintptr(jj)*8))).Fomit = uint8(1)
			/* This strategy involves a two rowid lookups on an B-Tree structures
			 ** and then a linear search of an R-Tree node. This should be
			 ** considered almost as quick as a direct rowid lookup (for which
			 ** sqlite uses an internal cost of 0.0). It is expected to return
			 ** a single row.
			 */
			(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FestimatedCost = float64(30)
			(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FestimatedRows = int64(1)
			(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FidxFlags = int32(SQLITE_INDEX_SCAN_UNIQUE)
			return SQLITE_OK
		}
		if (*Tsqlite3_index_constraint)(unsafe.Pointer(p)).Fusable != 0 && ((*Tsqlite3_index_constraint)(unsafe.Pointer(p)).FiColumn > 0 && (*Tsqlite3_index_constraint)(unsafe.Pointer(p)).FiColumn <= libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FnDim2) || libc.Int32FromUint8((*Tsqlite3_index_constraint)(unsafe.Pointer(p)).Fop) == int32(SQLITE_INDEX_CONSTRAINT_MATCH)) {
			doOmit = uint8(1)
			switch libc.Int32FromUint8((*Tsqlite3_index_constraint)(unsafe.Pointer(p)).Fop) {
			case int32(SQLITE_INDEX_CONSTRAINT_EQ):
				op = uint8(RTREE_EQ)
				doOmit = uint8(0)
			case int32(SQLITE_INDEX_CONSTRAINT_GT):
				op = uint8(RTREE_GT)
				doOmit = uint8(0)
			case int32(SQLITE_INDEX_CONSTRAINT_LE):
				op = uint8(RTREE_LE)
			case int32(SQLITE_INDEX_CONSTRAINT_LT):
				op = uint8(RTREE_LT)
				doOmit = uint8(0)
			case int32(SQLITE_INDEX_CONSTRAINT_GE):
				op = uint8(RTREE_GE)
			case int32(SQLITE_INDEX_CONSTRAINT_MATCH):
				op = uint8(RTREE_MATCH)
			default:
				op = uint8(0)
				break
			}
			if op != 0 {
				v4 = iIdx
				iIdx = iIdx + 1
				(**(**[41]int8)(__ccgo_up(bp)))[v4] = libc.Int8FromUint8(op)
				v4 = iIdx
				iIdx = iIdx + 1
				(**(**[41]int8)(__ccgo_up(bp)))[v4] = int8((*Tsqlite3_index_constraint)(unsafe.Pointer(p)).FiColumn - libc.Int32FromInt32(1) + libc.Int32FromUint8('0'))
				(**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraintUsage + uintptr(ii)*8))).FargvIndex = iIdx / int32(2)
				(**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraintUsage + uintptr(ii)*8))).Fomit = doOmit
			}
		}
		goto _2
	_2:
		;
		ii = ii + 1
	}
	(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FidxNum = int32(2)
	(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FneedToFreeIdxStr = int32(1)
	if iIdx > 0 {
		(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FidxStr = Xsqlite3_malloc(tls, iIdx+int32(1))
		if (*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FidxStr == uintptr(0) {
			return int32(SQLITE_NOMEM)
		}
		libc.Xmemcpy(tls, (*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FidxStr, bp, libc.Uint32FromInt32(iIdx+int32(1)))
	}
	nRow = (*TRtree)(unsafe.Pointer(pRtree)).FnRowEst >> (iIdx / int32(2))
	(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FestimatedCost = float64(libc.Float64FromFloat64(6) * float64(nRow))
	(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FestimatedRows = nRow
	return rc
}

// C documentation
//
//	/*
//	** Check the RTree node or entry given by pCellData and p against the MATCH
//	** constraint pConstraint.
//	*/
func _rtreeCallbackConstraint(tls *libc.TLS, pConstraint uintptr, eInt int32, pCellData uintptr, pSearch uintptr, prScore uintptr, peWithin uintptr) (r int32) {
	bp := tls.Alloc(96)
	defer tls.Free(96)
	var nCoord, rc, v2 int32
	var pInfo uintptr
	var v1 Tsqlite3_rtree_dbl
	var _ /* aCoord at bp+4 */ [10]Tsqlite3_rtree_dbl
	var _ /* c at bp+0 */ TRtreeCoord
	var _ /* eWithin at bp+84 */ int32
	_, _, _, _, _ = nCoord, pInfo, rc, v1, v2
	pInfo = (*TRtreeConstraint)(unsafe.Pointer(pConstraint)).FpInfo      /* Callback info */
	nCoord = (*Tsqlite3_rtree_query_info)(unsafe.Pointer(pInfo)).FnCoord /* Decoded coordinates */
	if (*TRtreeConstraint)(unsafe.Pointer(pConstraint)).Fop == int32(RTREE_QUERY) && libc.Int32FromUint8((*TRtreeSearchPoint)(unsafe.Pointer(pSearch)).FiLevel) == int32(1) {
		(*Tsqlite3_rtree_query_info)(unsafe.Pointer(pInfo)).FiRowid = _readInt64(tls, pCellData)
	}
	pCellData = pCellData + uintptr(8)
	if eInt == 0 {
		switch nCoord {
		case int32(10):
			_readCoord(tls, pCellData+uintptr(36), bp)
			(**(**[10]Tsqlite3_rtree_dbl)(__ccgo_up(bp + 4)))[int32(9)] = float64(*(*TRtreeValue)(unsafe.Pointer(bp)))
			_readCoord(tls, pCellData+uintptr(32), bp)
			(**(**[10]Tsqlite3_rtree_dbl)(__ccgo_up(bp + 4)))[int32(8)] = float64(*(*TRtreeValue)(unsafe.Pointer(bp)))
			fallthrough
		case int32(8):
			_readCoord(tls, pCellData+uintptr(28), bp)
			(**(**[10]Tsqlite3_rtree_dbl)(__ccgo_up(bp + 4)))[int32(7)] = float64(*(*TRtreeValue)(unsafe.Pointer(bp)))
			_readCoord(tls, pCellData+uintptr(24), bp)
			(**(**[10]Tsqlite3_rtree_dbl)(__ccgo_up(bp + 4)))[int32(6)] = float64(*(*TRtreeValue)(unsafe.Pointer(bp)))
			fallthrough
		case int32(6):
			_readCoord(tls, pCellData+uintptr(20), bp)
			(**(**[10]Tsqlite3_rtree_dbl)(__ccgo_up(bp + 4)))[int32(5)] = float64(*(*TRtreeValue)(unsafe.Pointer(bp)))
			_readCoord(tls, pCellData+uintptr(16), bp)
			(**(**[10]Tsqlite3_rtree_dbl)(__ccgo_up(bp + 4)))[int32(4)] = float64(*(*TRtreeValue)(unsafe.Pointer(bp)))
			fallthrough
		case int32(4):
			_readCoord(tls, pCellData+uintptr(12), bp)
			(**(**[10]Tsqlite3_rtree_dbl)(__ccgo_up(bp + 4)))[int32(3)] = float64(*(*TRtreeValue)(unsafe.Pointer(bp)))
			_readCoord(tls, pCellData+uintptr(8), bp)
			(**(**[10]Tsqlite3_rtree_dbl)(__ccgo_up(bp + 4)))[int32(2)] = float64(*(*TRtreeValue)(unsafe.Pointer(bp)))
			fallthrough
		default:
			_readCoord(tls, pCellData+uintptr(4), bp)
			(**(**[10]Tsqlite3_rtree_dbl)(__ccgo_up(bp + 4)))[int32(1)] = float64(*(*TRtreeValue)(unsafe.Pointer(bp)))
			_readCoord(tls, pCellData, bp)
			(**(**[10]Tsqlite3_rtree_dbl)(__ccgo_up(bp + 4)))[0] = float64(*(*TRtreeValue)(unsafe.Pointer(bp)))
		}
	} else {
		switch nCoord {
		case int32(10):
			_readCoord(tls, pCellData+uintptr(36), bp)
			(**(**[10]Tsqlite3_rtree_dbl)(__ccgo_up(bp + 4)))[int32(9)] = float64(*(*int32)(unsafe.Pointer(bp)))
			_readCoord(tls, pCellData+uintptr(32), bp)
			(**(**[10]Tsqlite3_rtree_dbl)(__ccgo_up(bp + 4)))[int32(8)] = float64(*(*int32)(unsafe.Pointer(bp)))
			fallthrough
		case int32(8):
			_readCoord(tls, pCellData+uintptr(28), bp)
			(**(**[10]Tsqlite3_rtree_dbl)(__ccgo_up(bp + 4)))[int32(7)] = float64(*(*int32)(unsafe.Pointer(bp)))
			_readCoord(tls, pCellData+uintptr(24), bp)
			(**(**[10]Tsqlite3_rtree_dbl)(__ccgo_up(bp + 4)))[int32(6)] = float64(*(*int32)(unsafe.Pointer(bp)))
			fallthrough
		case int32(6):
			_readCoord(tls, pCellData+uintptr(20), bp)
			(**(**[10]Tsqlite3_rtree_dbl)(__ccgo_up(bp + 4)))[int32(5)] = float64(*(*int32)(unsafe.Pointer(bp)))
			_readCoord(tls, pCellData+uintptr(16), bp)
			(**(**[10]Tsqlite3_rtree_dbl)(__ccgo_up(bp + 4)))[int32(4)] = float64(*(*int32)(unsafe.Pointer(bp)))
			fallthrough
		case int32(4):
			_readCoord(tls, pCellData+uintptr(12), bp)
			(**(**[10]Tsqlite3_rtree_dbl)(__ccgo_up(bp + 4)))[int32(3)] = float64(*(*int32)(unsafe.Pointer(bp)))
			_readCoord(tls, pCellData+uintptr(8), bp)
			(**(**[10]Tsqlite3_rtree_dbl)(__ccgo_up(bp + 4)))[int32(2)] = float64(*(*int32)(unsafe.Pointer(bp)))
			fallthrough
		default:
			_readCoord(tls, pCellData+uintptr(4), bp)
			(**(**[10]Tsqlite3_rtree_dbl)(__ccgo_up(bp + 4)))[int32(1)] = float64(*(*int32)(unsafe.Pointer(bp)))
			_readCoord(tls, pCellData, bp)
			(**(**[10]Tsqlite3_rtree_dbl)(__ccgo_up(bp + 4)))[0] = float64(*(*int32)(unsafe.Pointer(bp)))
		}
	}
	if (*TRtreeConstraint)(unsafe.Pointer(pConstraint)).Fop == int32(RTREE_MATCH) {
		**(**int32)(__ccgo_up(bp + 84)) = 0
		rc = (*(*func(*libc.TLS, uintptr, int32, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{*(*uintptr)(unsafe.Pointer(&(*TRtreeConstraint)(unsafe.Pointer(pConstraint)).Fu))})))(tls, pInfo, nCoord, bp+4, bp+84)
		if **(**int32)(__ccgo_up(bp + 84)) == 0 {
			**(**int32)(__ccgo_up(peWithin)) = NOT_WITHIN
		}
		**(**Tsqlite3_rtree_dbl)(__ccgo_up(prScore)) = float64(0)
	} else {
		(*Tsqlite3_rtree_query_info)(unsafe.Pointer(pInfo)).FaCoord = bp + 4
		(*Tsqlite3_rtree_query_info)(unsafe.Pointer(pInfo)).FiLevel = libc.Int32FromUint8((*TRtreeSearchPoint)(unsafe.Pointer(pSearch)).FiLevel) - int32(1)
		v1 = (*TRtreeSearchPoint)(unsafe.Pointer(pSearch)).FrScore
		(*Tsqlite3_rtree_query_info)(unsafe.Pointer(pInfo)).FrParentScore = v1
		(*Tsqlite3_rtree_query_info)(unsafe.Pointer(pInfo)).FrScore = v1
		v2 = libc.Int32FromUint8((*TRtreeSearchPoint)(unsafe.Pointer(pSearch)).FeWithin)
		(*Tsqlite3_rtree_query_info)(unsafe.Pointer(pInfo)).FeParentWithin = v2
		(*Tsqlite3_rtree_query_info)(unsafe.Pointer(pInfo)).FeWithin = v2
		rc = (*(*func(*libc.TLS, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{*(*uintptr)(unsafe.Pointer(&(*TRtreeConstraint)(unsafe.Pointer(pConstraint)).Fu))})))(tls, pInfo)
		if (*Tsqlite3_rtree_query_info)(unsafe.Pointer(pInfo)).FeWithin < **(**int32)(__ccgo_up(peWithin)) {
			**(**int32)(__ccgo_up(peWithin)) = (*Tsqlite3_rtree_query_info)(unsafe.Pointer(pInfo)).FeWithin
		}
		if (*Tsqlite3_rtree_query_info)(unsafe.Pointer(pInfo)).FrScore < **(**Tsqlite3_rtree_dbl)(__ccgo_up(prScore)) || **(**Tsqlite3_rtree_dbl)(__ccgo_up(prScore)) < float64(0) {
			**(**Tsqlite3_rtree_dbl)(__ccgo_up(prScore)) = (*Tsqlite3_rtree_query_info)(unsafe.Pointer(pInfo)).FrScore
		}
	}
	return rc
}

// C documentation
//
//	/*
//	** Push a new element onto the priority queue
//	*/
func _rtreeEnqueue(tls *libc.TLS, pCur uintptr, rScore TRtreeDValue, iLevel Tu8) (r uintptr) {
	var i, j, nNew, v1 int32
	var pNew, pParent, v2 uintptr
	_, _, _, _, _, _, _ = i, j, nNew, pNew, pParent, v1, v2
	if (*TRtreeCursor)(unsafe.Pointer(pCur)).FnPoint >= (*TRtreeCursor)(unsafe.Pointer(pCur)).FnPointAlloc {
		nNew = (*TRtreeCursor)(unsafe.Pointer(pCur)).FnPointAlloc*int32(2) + int32(8)
		pNew = Xsqlite3_realloc64(tls, (*TRtreeCursor)(unsafe.Pointer(pCur)).FaPoint, uint64(libc.Uint32FromInt32(nNew)*uint32(20)))
		if pNew == uintptr(0) {
			return uintptr(0)
		}
		(*TRtreeCursor)(unsafe.Pointer(pCur)).FaPoint = pNew
		(*TRtreeCursor)(unsafe.Pointer(pCur)).FnPointAlloc = nNew
	}
	v2 = pCur + 24
	v1 = *(*int32)(unsafe.Pointer(v2))
	*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1
	i = v1
	pNew = (*TRtreeCursor)(unsafe.Pointer(pCur)).FaPoint + uintptr(i)*20
	(*TRtreeSearchPoint)(unsafe.Pointer(pNew)).FrScore = rScore
	(*TRtreeSearchPoint)(unsafe.Pointer(pNew)).FiLevel = iLevel
	for i > 0 {
		j = (i - int32(1)) / int32(2)
		pParent = (*TRtreeCursor)(unsafe.Pointer(pCur)).FaPoint + uintptr(j)*20
		if _rtreeSearchPointCompare(tls, pNew, pParent) >= 0 {
			break
		}
		_rtreeSearchPointSwap(tls, pCur, j, i)
		i = j
		pNew = pParent
	}
	return pNew
}

// C documentation
//
//	/*
//	** Rtree virtual table module xFilter method.
//	*/
func _rtreeFilter(tls *libc.TLS, pVtabCursor uintptr, idxNum int32, idxStr uintptr, argc int32, argv uintptr) (r int32) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var eType, eType1, ii, rc int32
	var iRowid Ti64
	var iVal Tsqlite3_int64
	var p, p1, pCsr, pNew, pRtree uintptr
	var _ /* iCell at bp+4 */ int32
	var _ /* iNode at bp+16 */ Ti64
	var _ /* pLeaf at bp+8 */ uintptr
	var _ /* pRoot at bp+0 */ uintptr
	_, _, _, _, _, _, _, _, _, _, _ = eType, eType1, iRowid, iVal, ii, p, p1, pCsr, pNew, pRtree, rc
	pRtree = (*Tsqlite3_vtab_cursor)(unsafe.Pointer(pVtabCursor)).FpVtab
	pCsr = pVtabCursor
	**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
	rc = SQLITE_OK
	**(**int32)(__ccgo_up(bp + 4)) = 0
	_rtreeReference(tls, pRtree)
	/* Reset the cursor to the same state as rtreeOpen() leaves it in. */
	_resetCursor(tls, pCsr)
	(*TRtreeCursor)(unsafe.Pointer(pCsr)).FiStrategy = idxNum
	if idxNum == int32(1) { /* Search point for the leaf */
		iRowid = Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(argv)))
		**(**Ti64)(__ccgo_up(bp + 16)) = 0
		eType = Xsqlite3_value_numeric_type(tls, **(**uintptr)(__ccgo_up(argv)))
		if eType == int32(SQLITE_INTEGER) || eType == int32(SQLITE_FLOAT) && 0 == _sqlite3IntFloatCompare(tls, iRowid, Xsqlite3_value_double(tls, **(**uintptr)(__ccgo_up(argv)))) {
			rc = _findLeafNode(tls, pRtree, iRowid, bp+8, bp+16)
		} else {
			rc = SQLITE_OK
			**(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0)
		}
		if rc == SQLITE_OK && **(**uintptr)(__ccgo_up(bp + 8)) != uintptr(0) {
			p = _rtreeSearchPointNew(tls, pCsr, float64(0), uint8(0))
			/* Always returns pCsr->sPoint */
			**(**uintptr)(__ccgo_up(pCsr + 60)) = **(**uintptr)(__ccgo_up(bp + 8))
			(*TRtreeSearchPoint)(unsafe.Pointer(p)).Fid = **(**Ti64)(__ccgo_up(bp + 16))
			(*TRtreeSearchPoint)(unsafe.Pointer(p)).FeWithin = uint8(PARTLY_WITHIN)
			rc = _nodeRowidIndex(tls, pRtree, **(**uintptr)(__ccgo_up(bp + 8)), iRowid, bp+4)
			(*TRtreeSearchPoint)(unsafe.Pointer(p)).FiCell = libc.Uint8FromInt32(**(**int32)(__ccgo_up(bp + 4)))
		} else {
			(*TRtreeCursor)(unsafe.Pointer(pCsr)).FatEOF = uint8(1)
		}
	} else {
		/* Normal case - r-tree scan. Set up the RtreeCursor.aConstraint array
		 ** with the configured constraints.
		 */
		rc = _nodeAcquire(tls, pRtree, int64(1), uintptr(0), bp)
		if rc == SQLITE_OK && argc > 0 {
			(*TRtreeCursor)(unsafe.Pointer(pCsr)).FaConstraint = Xsqlite3_malloc64(tls, uint64(uint32(20)*libc.Uint32FromInt32(argc)))
			(*TRtreeCursor)(unsafe.Pointer(pCsr)).FnConstraint = argc
			if !((*TRtreeCursor)(unsafe.Pointer(pCsr)).FaConstraint != 0) {
				rc = int32(SQLITE_NOMEM)
			} else {
				libc.Xmemset(tls, (*TRtreeCursor)(unsafe.Pointer(pCsr)).FaConstraint, 0, uint32(20)*libc.Uint32FromInt32(argc))
				libc.Xmemset(tls, pCsr+80, 0, uint32(4)*libc.Uint32FromInt32((*TRtree)(unsafe.Pointer(pRtree)).FiDepth+libc.Int32FromInt32(1)))
				ii = 0
				for {
					if !(ii < argc) {
						break
					}
					p1 = (*TRtreeCursor)(unsafe.Pointer(pCsr)).FaConstraint + uintptr(ii)*20
					eType1 = Xsqlite3_value_numeric_type(tls, **(**uintptr)(__ccgo_up(argv + uintptr(ii)*4)))
					(*TRtreeConstraint)(unsafe.Pointer(p1)).Fop = int32(**(**int8)(__ccgo_up(idxStr + uintptr(ii*int32(2)))))
					(*TRtreeConstraint)(unsafe.Pointer(p1)).FiCoord = int32(**(**int8)(__ccgo_up(idxStr + uintptr(ii*int32(2)+int32(1))))) - int32('0')
					if (*TRtreeConstraint)(unsafe.Pointer(p1)).Fop >= int32(RTREE_MATCH) {
						/* A MATCH operator. The right-hand-side must be a blob that
						 ** can be cast into an RtreeMatchArg object. One created using
						 ** an sqlite3_rtree_geometry_callback() SQL user function.
						 */
						rc = _deserializeGeometry(tls, **(**uintptr)(__ccgo_up(argv + uintptr(ii)*4)), p1)
						if rc != SQLITE_OK {
							break
						}
						(*Tsqlite3_rtree_query_info)(unsafe.Pointer((*TRtreeConstraint)(unsafe.Pointer(p1)).FpInfo)).FnCoord = libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FnDim2)
						(*Tsqlite3_rtree_query_info)(unsafe.Pointer((*TRtreeConstraint)(unsafe.Pointer(p1)).FpInfo)).FanQueue = pCsr + 80
						(*Tsqlite3_rtree_query_info)(unsafe.Pointer((*TRtreeConstraint)(unsafe.Pointer(p1)).FpInfo)).FmxLevel = (*TRtree)(unsafe.Pointer(pRtree)).FiDepth + int32(1)
					} else {
						if eType1 == int32(SQLITE_INTEGER) {
							iVal = Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(argv + uintptr(ii)*4)))
							*(*TRtreeDValue)(unsafe.Pointer(p1 + 8)) = float64(iVal)
							if iVal >= libc.Int64FromInt32(1)<<libc.Int32FromInt32(48) || iVal <= -(libc.Int64FromInt32(1)<<libc.Int32FromInt32(48)) {
								if (*TRtreeConstraint)(unsafe.Pointer(p1)).Fop == int32(RTREE_LT) {
									(*TRtreeConstraint)(unsafe.Pointer(p1)).Fop = int32(RTREE_LE)
								}
								if (*TRtreeConstraint)(unsafe.Pointer(p1)).Fop == int32(RTREE_GT) {
									(*TRtreeConstraint)(unsafe.Pointer(p1)).Fop = int32(RTREE_GE)
								}
							}
						} else {
							if eType1 == int32(SQLITE_FLOAT) {
								*(*TRtreeDValue)(unsafe.Pointer(p1 + 8)) = Xsqlite3_value_double(tls, **(**uintptr)(__ccgo_up(argv + uintptr(ii)*4)))
							} else {
								*(*TRtreeDValue)(unsafe.Pointer(p1 + 8)) = float64(0)
								if eType1 == int32(SQLITE_NULL) {
									(*TRtreeConstraint)(unsafe.Pointer(p1)).Fop = int32(RTREE_FALSE)
								} else {
									if (*TRtreeConstraint)(unsafe.Pointer(p1)).Fop == int32(RTREE_LT) || (*TRtreeConstraint)(unsafe.Pointer(p1)).Fop == int32(RTREE_LE) {
										(*TRtreeConstraint)(unsafe.Pointer(p1)).Fop = int32(RTREE_TRUE)
									} else {
										(*TRtreeConstraint)(unsafe.Pointer(p1)).Fop = int32(RTREE_FALSE)
									}
								}
							}
						}
					}
					goto _1
				_1:
					;
					ii = ii + 1
				}
			}
		}
		if rc == SQLITE_OK {
			/* Due to the resetCursor() call above */
			pNew = _rtreeSearchPointNew(tls, pCsr, float64(0), libc.Uint8FromInt32((*TRtree)(unsafe.Pointer(pRtree)).FiDepth+libc.Int32FromInt32(1)))
			if pNew == uintptr(0) { /* Because pCsr->bPoint was FALSE */
				return int32(SQLITE_NOMEM)
			}
			(*TRtreeSearchPoint)(unsafe.Pointer(pNew)).Fid = int64(1)
			(*TRtreeSearchPoint)(unsafe.Pointer(pNew)).FiCell = uint8(0)
			(*TRtreeSearchPoint)(unsafe.Pointer(pNew)).FeWithin = uint8(PARTLY_WITHIN)
			**(**uintptr)(__ccgo_up(pCsr + 60)) = **(**uintptr)(__ccgo_up(bp))
			**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
			rc = _rtreeStepToLeaf(tls, pCsr)
		}
	}
	_nodeRelease(tls, pRtree, **(**uintptr)(__ccgo_up(bp)))
	_rtreeRelease(tls, pRtree)
	return rc
}

// C documentation
//
//	/*
//	** Get the RtreeNode for the search point with the lowest score.
//	*/
func _rtreeNodeOfFirstSearchPoint(tls *libc.TLS, pCur uintptr, pRC uintptr) (r uintptr) {
	var id Tsqlite3_int64
	var ii int32
	var v1 int64
	_, _, _ = id, ii, v1
	ii = int32(1) - libc.Int32FromUint8((*TRtreeCursor)(unsafe.Pointer(pCur)).FbPoint)
	if **(**uintptr)(__ccgo_up(pCur + 60 + uintptr(ii)*4)) == uintptr(0) {
		if ii != 0 {
			v1 = (**(**TRtreeSearchPoint)(__ccgo_up((*TRtreeCursor)(unsafe.Pointer(pCur)).FaPoint))).Fid
		} else {
			v1 = (*TRtreeCursor)(unsafe.Pointer(pCur)).FsPoint.Fid
		}
		id = v1
		**(**int32)(__ccgo_up(pRC)) = _nodeAcquire(tls, (*TRtreeCursor)(unsafe.Pointer(pCur)).Fbase.FpVtab, id, uintptr(0), pCur+60+uintptr(ii)*4)
	}
	return **(**uintptr)(__ccgo_up(pCur + 60 + uintptr(ii)*4))
}

// C documentation
//
//	/*
//	** Rtree virtual table module xOpen method.
//	*/
func _rtreeOpen(tls *libc.TLS, pVTab uintptr, ppCursor uintptr) (r int32) {
	var pCsr, pRtree uintptr
	var rc int32
	_, _, _ = pCsr, pRtree, rc
	rc = int32(SQLITE_NOMEM)
	pRtree = pVTab
	pCsr = Xsqlite3_malloc64(tls, uint64(244))
	if pCsr != 0 {
		libc.Xmemset(tls, pCsr, 0, uint32(244))
		(*TRtreeCursor)(unsafe.Pointer(pCsr)).Fbase.FpVtab = pVTab
		rc = SQLITE_OK
		(*TRtree)(unsafe.Pointer(pRtree)).FnCursor = (*TRtree)(unsafe.Pointer(pRtree)).FnCursor + 1
	}
	**(**uintptr)(__ccgo_up(ppCursor)) = pCsr
	return rc
}

// C documentation
//
//	/*
//	** Decrement the r-tree reference count. When the reference count reaches
//	** zero the structure is deleted.
//	*/
func _rtreeRelease(tls *libc.TLS, pRtree uintptr) {
	var i int32
	var pNext uintptr
	_, _ = i, pNext
	(*TRtree)(unsafe.Pointer(pRtree)).FnBusy = (*TRtree)(unsafe.Pointer(pRtree)).FnBusy - 1
	if (*TRtree)(unsafe.Pointer(pRtree)).FnBusy == uint32(0) {
		(*TRtree)(unsafe.Pointer(pRtree)).FinWrTrans = uint8(0)
		_nodeBlobReset(tls, pRtree)
		if (*TRtree)(unsafe.Pointer(pRtree)).FnNodeRef != 0 {
			i = 0
			for {
				if !(i < int32(HASHSIZE)) {
					break
				}
				for **(**uintptr)(__ccgo_up(pRtree + 116 + uintptr(i)*4)) != 0 {
					pNext = (*TRtreeNode)(unsafe.Pointer(**(**uintptr)(__ccgo_up(pRtree + 116 + uintptr(i)*4)))).FpNext
					Xsqlite3_free(tls, **(**uintptr)(__ccgo_up(pRtree + 116 + uintptr(i)*4)))
					**(**uintptr)(__ccgo_up(pRtree + 116 + uintptr(i)*4)) = pNext
				}
				goto _1
			_1:
				;
				i = i + 1
			}
		}
		Xsqlite3_finalize(tls, (*TRtree)(unsafe.Pointer(pRtree)).FpWriteNode)
		Xsqlite3_finalize(tls, (*TRtree)(unsafe.Pointer(pRtree)).FpDeleteNode)
		Xsqlite3_finalize(tls, (*TRtree)(unsafe.Pointer(pRtree)).FpReadRowid)
		Xsqlite3_finalize(tls, (*TRtree)(unsafe.Pointer(pRtree)).FpWriteRowid)
		Xsqlite3_finalize(tls, (*TRtree)(unsafe.Pointer(pRtree)).FpDeleteRowid)
		Xsqlite3_finalize(tls, (*TRtree)(unsafe.Pointer(pRtree)).FpReadParent)
		Xsqlite3_finalize(tls, (*TRtree)(unsafe.Pointer(pRtree)).FpWriteParent)
		Xsqlite3_finalize(tls, (*TRtree)(unsafe.Pointer(pRtree)).FpDeleteParent)
		Xsqlite3_finalize(tls, (*TRtree)(unsafe.Pointer(pRtree)).FpWriteAux)
		Xsqlite3_free(tls, (*TRtree)(unsafe.Pointer(pRtree)).FzReadAuxSql)
		Xsqlite3_free(tls, pRtree)
	}
}

// C documentation
//
//	/*
//	** Allocate a new RtreeSearchPoint and return a pointer to it.  Return
//	** NULL if malloc fails.
//	*/
func _rtreeSearchPointNew(tls *libc.TLS, pCur uintptr, rScore TRtreeDValue, iLevel Tu8) (r uintptr) {
	var ii int32
	var pFirst, pNew uintptr
	_, _, _ = ii, pFirst, pNew
	pFirst = _rtreeSearchPointFirst(tls, pCur)
	**(**Tu32)(__ccgo_up(pCur + 80 + uintptr(iLevel)*4)) = **(**Tu32)(__ccgo_up(pCur + 80 + uintptr(iLevel)*4)) + 1
	if pFirst == uintptr(0) || (*TRtreeSearchPoint)(unsafe.Pointer(pFirst)).FrScore > rScore || (*TRtreeSearchPoint)(unsafe.Pointer(pFirst)).FrScore == rScore && libc.Int32FromUint8((*TRtreeSearchPoint)(unsafe.Pointer(pFirst)).FiLevel) > libc.Int32FromUint8(iLevel) {
		if (*TRtreeCursor)(unsafe.Pointer(pCur)).FbPoint != 0 {
			pNew = _rtreeEnqueue(tls, pCur, rScore, iLevel)
			if pNew == uintptr(0) {
				return uintptr(0)
			}
			ii = (int32(pNew)-int32((*TRtreeCursor)(unsafe.Pointer(pCur)).FaPoint))/20 + int32(1)
			if ii < int32(RTREE_CACHE_SZ) {
				**(**uintptr)(__ccgo_up(pCur + 60 + uintptr(ii)*4)) = **(**uintptr)(__ccgo_up(pCur + 60))
			} else {
				_nodeRelease(tls, (*TRtreeCursor)(unsafe.Pointer(pCur)).Fbase.FpVtab, **(**uintptr)(__ccgo_up(pCur + 60)))
			}
			**(**uintptr)(__ccgo_up(pCur + 60)) = uintptr(0)
			**(**TRtreeSearchPoint)(__ccgo_up(pNew)) = (*TRtreeCursor)(unsafe.Pointer(pCur)).FsPoint
		}
		(*TRtreeCursor)(unsafe.Pointer(pCur)).FsPoint.FrScore = rScore
		(*TRtreeCursor)(unsafe.Pointer(pCur)).FsPoint.FiLevel = iLevel
		(*TRtreeCursor)(unsafe.Pointer(pCur)).FbPoint = uint8(1)
		return pCur + 40
	} else {
		return _rtreeEnqueue(tls, pCur, rScore, iLevel)
	}
	return r
}

// C documentation
//
//	/* Remove the search point with the lowest current score.
//	*/
func _rtreeSearchPointPop(tls *libc.TLS, p uintptr) {
	var i, j, k, n, v1 int32
	var v2 uintptr
	_, _, _, _, _, _ = i, j, k, n, v1, v2
	i = int32(1) - libc.Int32FromUint8((*TRtreeCursor)(unsafe.Pointer(p)).FbPoint)
	if **(**uintptr)(__ccgo_up(p + 60 + uintptr(i)*4)) != 0 {
		_nodeRelease(tls, (*TRtreeCursor)(unsafe.Pointer(p)).Fbase.FpVtab, **(**uintptr)(__ccgo_up(p + 60 + uintptr(i)*4)))
		**(**uintptr)(__ccgo_up(p + 60 + uintptr(i)*4)) = uintptr(0)
	}
	if (*TRtreeCursor)(unsafe.Pointer(p)).FbPoint != 0 {
		**(**Tu32)(__ccgo_up(p + 80 + uintptr((*TRtreeCursor)(unsafe.Pointer(p)).FsPoint.FiLevel)*4)) = **(**Tu32)(__ccgo_up(p + 80 + uintptr((*TRtreeCursor)(unsafe.Pointer(p)).FsPoint.FiLevel)*4)) - 1
		(*TRtreeCursor)(unsafe.Pointer(p)).FbPoint = uint8(0)
	} else {
		if (*TRtreeCursor)(unsafe.Pointer(p)).FnPoint != 0 {
			**(**Tu32)(__ccgo_up(p + 80 + uintptr((**(**TRtreeSearchPoint)(__ccgo_up((*TRtreeCursor)(unsafe.Pointer(p)).FaPoint))).FiLevel)*4)) = **(**Tu32)(__ccgo_up(p + 80 + uintptr((**(**TRtreeSearchPoint)(__ccgo_up((*TRtreeCursor)(unsafe.Pointer(p)).FaPoint))).FiLevel)*4)) - 1
			v2 = p + 24
			*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) - 1
			v1 = *(*int32)(unsafe.Pointer(v2))
			n = v1
			**(**TRtreeSearchPoint)(__ccgo_up((*TRtreeCursor)(unsafe.Pointer(p)).FaPoint)) = **(**TRtreeSearchPoint)(__ccgo_up((*TRtreeCursor)(unsafe.Pointer(p)).FaPoint + uintptr(n)*20))
			if n < libc.Int32FromInt32(RTREE_CACHE_SZ)-libc.Int32FromInt32(1) {
				**(**uintptr)(__ccgo_up(p + 60 + 1*4)) = **(**uintptr)(__ccgo_up(p + 60 + uintptr(n+int32(1))*4))
				**(**uintptr)(__ccgo_up(p + 60 + uintptr(n+int32(1))*4)) = uintptr(0)
			}
			i = 0
			for {
				v1 = i*libc.Int32FromInt32(2) + libc.Int32FromInt32(1)
				j = v1
				if !(v1 < n) {
					break
				}
				k = j + int32(1)
				if k < n && _rtreeSearchPointCompare(tls, (*TRtreeCursor)(unsafe.Pointer(p)).FaPoint+uintptr(k)*20, (*TRtreeCursor)(unsafe.Pointer(p)).FaPoint+uintptr(j)*20) < 0 {
					if _rtreeSearchPointCompare(tls, (*TRtreeCursor)(unsafe.Pointer(p)).FaPoint+uintptr(k)*20, (*TRtreeCursor)(unsafe.Pointer(p)).FaPoint+uintptr(i)*20) < 0 {
						_rtreeSearchPointSwap(tls, p, i, k)
						i = k
					} else {
						break
					}
				} else {
					if _rtreeSearchPointCompare(tls, (*TRtreeCursor)(unsafe.Pointer(p)).FaPoint+uintptr(j)*20, (*TRtreeCursor)(unsafe.Pointer(p)).FaPoint+uintptr(i)*20) < 0 {
						_rtreeSearchPointSwap(tls, p, i, j)
						i = j
					} else {
						break
					}
				}
			}
		}
	}
}

// C documentation
//
//	/*
//	** Interchange two search points in a cursor.
//	*/
func _rtreeSearchPointSwap(tls *libc.TLS, p uintptr, i int32, j int32) {
	var pTemp uintptr
	var t TRtreeSearchPoint
	_, _ = pTemp, t
	t = **(**TRtreeSearchPoint)(__ccgo_up((*TRtreeCursor)(unsafe.Pointer(p)).FaPoint + uintptr(i)*20))
	**(**TRtreeSearchPoint)(__ccgo_up((*TRtreeCursor)(unsafe.Pointer(p)).FaPoint + uintptr(i)*20)) = **(**TRtreeSearchPoint)(__ccgo_up((*TRtreeCursor)(unsafe.Pointer(p)).FaPoint + uintptr(j)*20))
	**(**TRtreeSearchPoint)(__ccgo_up((*TRtreeCursor)(unsafe.Pointer(p)).FaPoint + uintptr(j)*20)) = t
	i = i + 1
	j = j + 1
	if i < int32(RTREE_CACHE_SZ) {
		if j >= int32(RTREE_CACHE_SZ) {
			_nodeRelease(tls, (*TRtreeCursor)(unsafe.Pointer(p)).Fbase.FpVtab, **(**uintptr)(__ccgo_up(p + 60 + uintptr(i)*4)))
			**(**uintptr)(__ccgo_up(p + 60 + uintptr(i)*4)) = uintptr(0)
		} else {
			pTemp = **(**uintptr)(__ccgo_up(p + 60 + uintptr(i)*4))
			**(**uintptr)(__ccgo_up(p + 60 + uintptr(i)*4)) = **(**uintptr)(__ccgo_up(p + 60 + uintptr(j)*4))
			**(**uintptr)(__ccgo_up(p + 60 + uintptr(j)*4)) = pTemp
		}
	}
}

// C documentation
//
//	/*
//	** Continue the search on cursor pCur until the front of the queue
//	** contains an entry suitable for returning as a result-set row,
//	** or until the RtreeSearchPoint queue is empty, indicating that the
//	** query has completed.
//	*/
func _rtreeStepToLeaf(tls *libc.TLS, pCur uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var eInt, ii, nCell, nConstraint int32
	var p, pCellData, pConstraint, pNode, pRtree, v1 uintptr
	var x TRtreeSearchPoint
	var _ /* eWithin at bp+0 */ int32
	var _ /* rScore at bp+8 */ Tsqlite3_rtree_dbl
	var _ /* rc at bp+4 */ int32
	_, _, _, _, _, _, _, _, _, _, _ = eInt, ii, nCell, nConstraint, p, pCellData, pConstraint, pNode, pRtree, x, v1
	pRtree = (*TRtreeCursor)(unsafe.Pointer(pCur)).Fbase.FpVtab
	**(**int32)(__ccgo_up(bp + 4)) = SQLITE_OK
	nConstraint = (*TRtreeCursor)(unsafe.Pointer(pCur)).FnConstraint
	eInt = libc.BoolInt32(libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FeCoordType) == int32(RTREE_COORD_INT32))
	for {
		v1 = _rtreeSearchPointFirst(tls, pCur)
		p = v1
		if !(v1 != uintptr(0) && libc.Int32FromUint8((*TRtreeSearchPoint)(unsafe.Pointer(p)).FiLevel) > 0) {
			break
		}
		pNode = _rtreeNodeOfFirstSearchPoint(tls, pCur, bp+4)
		if **(**int32)(__ccgo_up(bp + 4)) != 0 {
			return **(**int32)(__ccgo_up(bp + 4))
		}
		nCell = _readInt16(tls, (*TRtreeNode)(unsafe.Pointer(pNode)).FzData+2)
		if nCell > int32(RTREE_MAXCELLS) {
			return libc.Int32FromInt32(SQLITE_CORRUPT) | libc.Int32FromInt32(1)<<libc.Int32FromInt32(8)
		}
		pCellData = (*TRtreeNode)(unsafe.Pointer(pNode)).FzData + uintptr(libc.Int32FromInt32(4)+libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FnBytesPerCell)*libc.Int32FromUint8((*TRtreeSearchPoint)(unsafe.Pointer(p)).FiCell))
		for libc.Int32FromUint8((*TRtreeSearchPoint)(unsafe.Pointer(p)).FiCell) < nCell {
			**(**Tsqlite3_rtree_dbl)(__ccgo_up(bp + 8)) = float64(-libc.Int32FromInt32(1))
			**(**int32)(__ccgo_up(bp)) = int32(FULLY_WITHIN)
			ii = 0
			for {
				if !(ii < nConstraint) {
					break
				}
				pConstraint = (*TRtreeCursor)(unsafe.Pointer(pCur)).FaConstraint + uintptr(ii)*20
				if (*TRtreeConstraint)(unsafe.Pointer(pConstraint)).Fop >= int32(RTREE_MATCH) {
					**(**int32)(__ccgo_up(bp + 4)) = _rtreeCallbackConstraint(tls, pConstraint, eInt, pCellData, p, bp+8, bp)
					if **(**int32)(__ccgo_up(bp + 4)) != 0 {
						return **(**int32)(__ccgo_up(bp + 4))
					}
				} else {
					if libc.Int32FromUint8((*TRtreeSearchPoint)(unsafe.Pointer(p)).FiLevel) == int32(1) {
						_rtreeLeafConstraint(tls, pConstraint, eInt, pCellData, bp)
					} else {
						_rtreeNonleafConstraint(tls, pConstraint, eInt, pCellData, bp)
					}
				}
				if **(**int32)(__ccgo_up(bp)) == NOT_WITHIN {
					(*TRtreeSearchPoint)(unsafe.Pointer(p)).FiCell = (*TRtreeSearchPoint)(unsafe.Pointer(p)).FiCell + 1
					pCellData = pCellData + uintptr((*TRtree)(unsafe.Pointer(pRtree)).FnBytesPerCell)
					break
				}
				goto _2
			_2:
				;
				ii = ii + 1
			}
			if **(**int32)(__ccgo_up(bp)) == NOT_WITHIN {
				continue
			}
			(*TRtreeSearchPoint)(unsafe.Pointer(p)).FiCell = (*TRtreeSearchPoint)(unsafe.Pointer(p)).FiCell + 1
			x.FiLevel = libc.Uint8FromInt32(libc.Int32FromUint8((*TRtreeSearchPoint)(unsafe.Pointer(p)).FiLevel) - int32(1))
			if x.FiLevel != 0 {
				x.Fid = _readInt64(tls, pCellData)
				ii = 0
				for {
					if !(ii < (*TRtreeCursor)(unsafe.Pointer(pCur)).FnPoint) {
						break
					}
					if (**(**TRtreeSearchPoint)(__ccgo_up((*TRtreeCursor)(unsafe.Pointer(pCur)).FaPoint + uintptr(ii)*20))).Fid == x.Fid {
						return libc.Int32FromInt32(SQLITE_CORRUPT) | libc.Int32FromInt32(1)<<libc.Int32FromInt32(8)
					}
					goto _3
				_3:
					;
					ii = ii + 1
				}
				x.FiCell = uint8(0)
			} else {
				x.Fid = (*TRtreeSearchPoint)(unsafe.Pointer(p)).Fid
				x.FiCell = libc.Uint8FromInt32(libc.Int32FromUint8((*TRtreeSearchPoint)(unsafe.Pointer(p)).FiCell) - int32(1))
			}
			if libc.Int32FromUint8((*TRtreeSearchPoint)(unsafe.Pointer(p)).FiCell) >= nCell {
				_rtreeSearchPointPop(tls, pCur)
			}
			if **(**Tsqlite3_rtree_dbl)(__ccgo_up(bp + 8)) < float64(0) {
				**(**Tsqlite3_rtree_dbl)(__ccgo_up(bp + 8)) = float64(0)
			}
			p = _rtreeSearchPointNew(tls, pCur, **(**Tsqlite3_rtree_dbl)(__ccgo_up(bp + 8)), x.FiLevel)
			if p == uintptr(0) {
				return int32(SQLITE_NOMEM)
			}
			(*TRtreeSearchPoint)(unsafe.Pointer(p)).FeWithin = libc.Uint8FromInt32(**(**int32)(__ccgo_up(bp)))
			(*TRtreeSearchPoint)(unsafe.Pointer(p)).Fid = x.Fid
			(*TRtreeSearchPoint)(unsafe.Pointer(p)).FiCell = x.FiCell
			break
		}
		if libc.Int32FromUint8((*TRtreeSearchPoint)(unsafe.Pointer(p)).FiCell) >= nCell {
			_rtreeSearchPointPop(tls, pCur)
		}
	}
	(*TRtreeCursor)(unsafe.Pointer(pCur)).FatEOF = libc.BoolUint8(p == uintptr(0))
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** Copy the contents of object (*pFrom) into (*pTo).
//	*/
func _sampleCopy(tls *libc.TLS, p uintptr, pTo uintptr, pFrom uintptr) {
	(*TStatSample)(unsafe.Pointer(pTo)).FisPSample = (*TStatSample)(unsafe.Pointer(pFrom)).FisPSample
	(*TStatSample)(unsafe.Pointer(pTo)).FiCol = (*TStatSample)(unsafe.Pointer(pFrom)).FiCol
	(*TStatSample)(unsafe.Pointer(pTo)).FiHash = (*TStatSample)(unsafe.Pointer(pFrom)).FiHash
	libc.Xmemcpy(tls, (*TStatSample)(unsafe.Pointer(pTo)).FanEq, (*TStatSample)(unsafe.Pointer(pFrom)).FanEq, uint32(8)*libc.Uint32FromInt32((*TStatAccum)(unsafe.Pointer(p)).FnCol))
	libc.Xmemcpy(tls, (*TStatSample)(unsafe.Pointer(pTo)).FanLt, (*TStatSample)(unsafe.Pointer(pFrom)).FanLt, uint32(8)*libc.Uint32FromInt32((*TStatAccum)(unsafe.Pointer(p)).FnCol))
	libc.Xmemcpy(tls, (*TStatSample)(unsafe.Pointer(pTo)).FanDLt, (*TStatSample)(unsafe.Pointer(pFrom)).FanDLt, uint32(8)*libc.Uint32FromInt32((*TStatAccum)(unsafe.Pointer(p)).FnCol))
	if (*TStatSample)(unsafe.Pointer(pFrom)).FnRowid != 0 {
		_sampleSetRowid(tls, (*TStatAccum)(unsafe.Pointer(p)).Fdb, pTo, libc.Int32FromUint32((*TStatSample)(unsafe.Pointer(pFrom)).FnRowid), *(*uintptr)(unsafe.Pointer(&(*TStatSample)(unsafe.Pointer(pFrom)).Fu)))
	} else {
		_sampleSetRowidInt64(tls, (*TStatAccum)(unsafe.Pointer(p)).Fdb, pTo, *(*Ti64)(unsafe.Pointer(pFrom + 12)))
	}
}

// C documentation
//
//	/*
//	** Copy the contents of sample *pNew into the p->a[] array. If necessary,
//	** remove the least desirable sample from p->a[] to make room.
//	*/
func _sampleInsert(tls *libc.TLS, p uintptr, pNew uintptr, nEqZero int32) {
	var anDLt, anEq, anLt, pMin, pOld, pSample, pUpgrade uintptr
	var i, iMin int32
	_, _, _, _, _, _, _, _, _ = anDLt, anEq, anLt, i, iMin, pMin, pOld, pSample, pUpgrade
	pSample = uintptr(0)
	/* StatAccum.nMaxEqZero is set to the maximum number of leading 0
	 ** values in the anEq[] array of any sample in StatAccum.a[]. In
	 ** other words, if nMaxEqZero is n, then it is guaranteed that there
	 ** are no samples with StatSample.anEq[m]==0 for (m>=n). */
	if nEqZero > (*TStatAccum)(unsafe.Pointer(p)).FnMaxEqZero {
		(*TStatAccum)(unsafe.Pointer(p)).FnMaxEqZero = nEqZero
	}
	if libc.Int32FromUint8((*TStatSample)(unsafe.Pointer(pNew)).FisPSample) == 0 {
		pUpgrade = uintptr(0)
		/* This sample is being added because the prefix that ends in column
		 ** iCol occurs many times in the table. However, if we have already
		 ** added a sample that shares this prefix, there is no need to add
		 ** this one. Instead, upgrade the priority of the highest priority
		 ** existing sample that shares this prefix.  */
		i = (*TStatAccum)(unsafe.Pointer(p)).FnSample - int32(1)
		for {
			if !(i >= 0) {
				break
			}
			pOld = (*TStatAccum)(unsafe.Pointer(p)).Fa + uintptr(i)*36
			if **(**TtRowcnt)(__ccgo_up((*TStatSample)(unsafe.Pointer(pOld)).FanEq + uintptr((*TStatSample)(unsafe.Pointer(pNew)).FiCol)*8)) == uint64(0) {
				if (*TStatSample)(unsafe.Pointer(pOld)).FisPSample != 0 {
					return
				}
				if pUpgrade == uintptr(0) || _sampleIsBetter(tls, p, pOld, pUpgrade) != 0 {
					pUpgrade = pOld
				}
			}
			goto _1
		_1:
			;
			i = i - 1
		}
		if pUpgrade != 0 {
			(*TStatSample)(unsafe.Pointer(pUpgrade)).FiCol = (*TStatSample)(unsafe.Pointer(pNew)).FiCol
			**(**TtRowcnt)(__ccgo_up((*TStatSample)(unsafe.Pointer(pUpgrade)).FanEq + uintptr((*TStatSample)(unsafe.Pointer(pUpgrade)).FiCol)*8)) = **(**TtRowcnt)(__ccgo_up((*TStatSample)(unsafe.Pointer(pNew)).FanEq + uintptr((*TStatSample)(unsafe.Pointer(pUpgrade)).FiCol)*8))
			goto find_new_min
		}
	}
	/* If necessary, remove sample iMin to make room for the new sample. */
	if (*TStatAccum)(unsafe.Pointer(p)).FnSample >= (*TStatAccum)(unsafe.Pointer(p)).FmxSample {
		pMin = (*TStatAccum)(unsafe.Pointer(p)).Fa + uintptr((*TStatAccum)(unsafe.Pointer(p)).FiMin)*36
		anEq = (*TStatSample)(unsafe.Pointer(pMin)).FanEq
		anLt = (*TStatSample)(unsafe.Pointer(pMin)).FanLt
		anDLt = (*TStatSample)(unsafe.Pointer(pMin)).FanDLt
		_sampleClear(tls, (*TStatAccum)(unsafe.Pointer(p)).Fdb, pMin)
		libc.Xmemmove(tls, pMin, pMin+1*36, uint32(36)*libc.Uint32FromInt32((*TStatAccum)(unsafe.Pointer(p)).FnSample-(*TStatAccum)(unsafe.Pointer(p)).FiMin-libc.Int32FromInt32(1)))
		pSample = (*TStatAccum)(unsafe.Pointer(p)).Fa + uintptr((*TStatAccum)(unsafe.Pointer(p)).FnSample-int32(1))*36
		(*TStatSample)(unsafe.Pointer(pSample)).FnRowid = uint32(0)
		(*TStatSample)(unsafe.Pointer(pSample)).FanEq = anEq
		(*TStatSample)(unsafe.Pointer(pSample)).FanDLt = anDLt
		(*TStatSample)(unsafe.Pointer(pSample)).FanLt = anLt
		(*TStatAccum)(unsafe.Pointer(p)).FnSample = (*TStatAccum)(unsafe.Pointer(p)).FmxSample - int32(1)
	}
	/* The "rows less-than" for the rowid column must be greater than that
	 ** for the last sample in the p->a[] array. Otherwise, the samples would
	 ** be out of order. */
	/* Insert the new sample */
	pSample = (*TStatAccum)(unsafe.Pointer(p)).Fa + uintptr((*TStatAccum)(unsafe.Pointer(p)).FnSample)*36
	_sampleCopy(tls, p, pSample, pNew)
	(*TStatAccum)(unsafe.Pointer(p)).FnSample = (*TStatAccum)(unsafe.Pointer(p)).FnSample + 1
	/* Zero the first nEqZero entries in the anEq[] array. */
	libc.Xmemset(tls, (*TStatSample)(unsafe.Pointer(pSample)).FanEq, 0, uint32(8)*libc.Uint32FromInt32(nEqZero))
	goto find_new_min
find_new_min:
	;
	if (*TStatAccum)(unsafe.Pointer(p)).FnSample >= (*TStatAccum)(unsafe.Pointer(p)).FmxSample {
		iMin = -int32(1)
		i = 0
		for {
			if !(i < (*TStatAccum)(unsafe.Pointer(p)).FmxSample) {
				break
			}
			if (**(**TStatSample)(__ccgo_up((*TStatAccum)(unsafe.Pointer(p)).Fa + uintptr(i)*36))).FisPSample != 0 {
				goto _2
			}
			if iMin < 0 || _sampleIsBetter(tls, p, (*TStatAccum)(unsafe.Pointer(p)).Fa+uintptr(iMin)*36, (*TStatAccum)(unsafe.Pointer(p)).Fa+uintptr(i)*36) != 0 {
				iMin = i
			}
			goto _2
		_2:
			;
			i = i + 1
		}
		(*TStatAccum)(unsafe.Pointer(p)).FiMin = iMin
	}
}

// C documentation
//
//	/*
//	** Field iChng of the index being scanned has changed. So at this point
//	** p->current contains a sample that reflects the previous row of the
//	** index. The value of anEq[iChng] and subsequent anEq[] elements are
//	** correct at this point.
//	*/
func _samplePushPrevious(tls *libc.TLS, p uintptr, iChng int32) {
	var i, j, j1 int32
	var pBest uintptr
	_, _, _, _ = i, j, j1, pBest
	/* Check if any samples from the aBest[] array should be pushed
	 ** into IndexSample.a[] at this point.  */
	i = (*TStatAccum)(unsafe.Pointer(p)).FnCol - int32(2)
	for {
		if !(i >= iChng) {
			break
		}
		pBest = (*TStatAccum)(unsafe.Pointer(p)).FaBest + uintptr(i)*36
		**(**TtRowcnt)(__ccgo_up((*TStatSample)(unsafe.Pointer(pBest)).FanEq + uintptr(i)*8)) = **(**TtRowcnt)(__ccgo_up((*TStatAccum)(unsafe.Pointer(p)).Fcurrent.FanEq + uintptr(i)*8))
		if (*TStatAccum)(unsafe.Pointer(p)).FnSample < (*TStatAccum)(unsafe.Pointer(p)).FmxSample || _sampleIsBetter(tls, p, pBest, (*TStatAccum)(unsafe.Pointer(p)).Fa+uintptr((*TStatAccum)(unsafe.Pointer(p)).FiMin)*36) != 0 {
			_sampleInsert(tls, p, pBest, i)
		}
		goto _1
	_1:
		;
		i = i - 1
	}
	/* Check that no sample contains an anEq[] entry with an index of
	 ** p->nMaxEqZero or greater set to zero. */
	i = (*TStatAccum)(unsafe.Pointer(p)).FnSample - int32(1)
	for {
		if !(i >= 0) {
			break
		}
		j = (*TStatAccum)(unsafe.Pointer(p)).FnMaxEqZero
		for {
			if !(j < (*TStatAccum)(unsafe.Pointer(p)).FnCol) {
				break
			}
			goto _3
		_3:
			;
			j = j + 1
		}
		goto _2
	_2:
		;
		i = i - 1
	}
	/* Update the anEq[] fields of any samples already collected. */
	if iChng < (*TStatAccum)(unsafe.Pointer(p)).FnMaxEqZero {
		i = (*TStatAccum)(unsafe.Pointer(p)).FnSample - int32(1)
		for {
			if !(i >= 0) {
				break
			}
			j1 = iChng
			for {
				if !(j1 < (*TStatAccum)(unsafe.Pointer(p)).FnCol) {
					break
				}
				if **(**TtRowcnt)(__ccgo_up((**(**TStatSample)(__ccgo_up((*TStatAccum)(unsafe.Pointer(p)).Fa + uintptr(i)*36))).FanEq + uintptr(j1)*8)) == uint64(0) {
					**(**TtRowcnt)(__ccgo_up((**(**TStatSample)(__ccgo_up((*TStatAccum)(unsafe.Pointer(p)).Fa + uintptr(i)*36))).FanEq + uintptr(j1)*8)) = **(**TtRowcnt)(__ccgo_up((*TStatAccum)(unsafe.Pointer(p)).Fcurrent.FanEq + uintptr(j1)*8))
				}
				goto _5
			_5:
				;
				j1 = j1 + 1
			}
			goto _4
		_4:
			;
			i = i - 1
		}
		(*TStatAccum)(unsafe.Pointer(p)).FnMaxEqZero = iChng
	}
}

// C documentation
//
//	/* Initialize the INTEGER value of a ROWID.
//	*/
func _sampleSetRowidInt64(tls *libc.TLS, db uintptr, p uintptr, iRowid Ti64) {
	if (*TStatSample)(unsafe.Pointer(p)).FnRowid != 0 {
		_sqlite3DbFree(tls, db, *(*uintptr)(unsafe.Pointer(&(*TStatSample)(unsafe.Pointer(p)).Fu)))
	}
	(*TStatSample)(unsafe.Pointer(p)).FnRowid = uint32(0)
	*(*Ti64)(unsafe.Pointer(p + 12)) = iRowid
}

// C documentation
//
//	/*
//	** Add a new CHECK constraint to the table currently under construction.
//	*/
func _sqlite3AddCheckConstraint(tls *libc.TLS, pParse uintptr, pCheckExpr uintptr, zStart uintptr, zEnd uintptr) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var db, pTab uintptr
	var _ /* t at bp+0 */ TToken
	_, _ = db, pTab
	pTab = (*TParse)(unsafe.Pointer(pParse)).FpNewTable
	db = (*TParse)(unsafe.Pointer(pParse)).Fdb
	if pTab != 0 && !(libc.Int32FromUint8((*TParse)(unsafe.Pointer(pParse)).FeParseMode) == libc.Int32FromInt32(PARSE_MODE_DECLARE_VTAB)) && !(_sqlite3BtreeIsReadonly(tls, (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr((*Tsqlite3)(unsafe.Pointer(db)).Finit1.FiDb)*16))).FpBt) != 0) {
		(*TTable)(unsafe.Pointer(pTab)).FpCheck = _sqlite3ExprListAppend(tls, pParse, (*TTable)(unsafe.Pointer(pTab)).FpCheck, pCheckExpr)
		if (*(*struct {
			FaddrCrTab      int32
			FregRowid       int32
			FregRoot        int32
			FconstraintName TToken
		})(unsafe.Pointer(pParse + 184))).FconstraintName.Fn != 0 {
			_sqlite3ExprListSetName(tls, pParse, (*TTable)(unsafe.Pointer(pTab)).FpCheck, pParse+184+12, int32(1))
		} else {
			zStart = zStart + 1
			for {
				if !(libc.Int32FromUint8(_sqlite3CtypeMap[libc.Uint8FromInt8(**(**int8)(__ccgo_up(zStart)))])&int32(0x01) != 0) {
					break
				}
				goto _1
			_1:
				;
				zStart = zStart + 1
			}
			for libc.Int32FromUint8(_sqlite3CtypeMap[libc.Uint8FromInt8(**(**int8)(__ccgo_up(zEnd + uintptr(-libc.Int32FromInt32(1)))))])&int32(0x01) != 0 {
				zEnd = zEnd - 1
			}
			(**(**TToken)(__ccgo_up(bp))).Fz = zStart
			(**(**TToken)(__ccgo_up(bp))).Fn = libc.Uint32FromInt32(int32(zEnd) - int32((**(**TToken)(__ccgo_up(bp))).Fz))
			_sqlite3ExprListSetName(tls, pParse, (*TTable)(unsafe.Pointer(pTab)).FpCheck, bp, int32(1))
		}
	} else {
		_sqlite3ExprDelete(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, pCheckExpr)
	}
}

// C documentation
//
//	/*
//	** Allocate heap space to hold an Index object with nCol columns.
//	**
//	** Increase the allocation size to provide an extra nExtra bytes
//	** of 8-byte aligned space after the Index object and return a
//	** pointer to this extra space in *ppExtra.
//	*/
func _sqlite3AllocateIndexObject(tls *libc.TLS, db uintptr, nCol int32, nExtra int32, ppExtra uintptr) (r uintptr) {
	var nByte Ti64
	var p, pExtra uintptr
	_, _, _ = nByte, p, pExtra                                                                                                                                                                                                                                                                                                                                                                                                         /* Bytes of space for Index object + arrays */
	nByte = libc.Int64FromUint32((libc.Uint32FromInt64(100)+libc.Uint32FromInt32(7))&libc.Uint32FromInt32(^libc.Int32FromInt32(7)) + (uint32(4)*libc.Uint32FromInt32(nCol)+uint32(7))&libc.Uint32FromInt32(^libc.Int32FromInt32(7)) + (uint32(2)*libc.Uint32FromInt32(nCol+libc.Int32FromInt32(1))+uint32(2)*libc.Uint32FromInt32(nCol)+uint32(1)*libc.Uint32FromInt32(nCol)+uint32(7))&libc.Uint32FromInt32(^libc.Int32FromInt32(7))) /* Index.aSortOrder */
	p = _sqlite3DbMallocZero(tls, db, libc.Uint64FromInt64(nByte+int64(nExtra)))
	if p != 0 {
		pExtra = p + uintptr((libc.Uint32FromInt64(100)+libc.Uint32FromInt32(7))&libc.Uint32FromInt32(^libc.Int32FromInt32(7)))
		(*TIndex)(unsafe.Pointer(p)).FazColl = pExtra
		pExtra = pExtra + uintptr((libc.Uint32FromInt64(4)*libc.Uint32FromInt32(nCol)+libc.Uint32FromInt32(7))&libc.Uint32FromInt32(^libc.Int32FromInt32(7)))
		(*TIndex)(unsafe.Pointer(p)).FaiRowLogEst = pExtra
		pExtra = pExtra + uintptr(uint32(2)*libc.Uint32FromInt32(nCol+libc.Int32FromInt32(1)))
		(*TIndex)(unsafe.Pointer(p)).FaiColumn = pExtra
		pExtra = pExtra + uintptr(uint32(2)*libc.Uint32FromInt32(nCol))
		(*TIndex)(unsafe.Pointer(p)).FaSortOrder = pExtra
		(*TIndex)(unsafe.Pointer(p)).FnColumn = libc.Uint16FromInt32(nCol)
		(*TIndex)(unsafe.Pointer(p)).FnKeyCol = libc.Uint16FromInt32(nCol - libc.Int32FromInt32(1))
		**(**uintptr)(__ccgo_up(ppExtra)) = p + uintptr(nByte)
	}
	return p
}

// 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+308, 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
//
//	/*
//	** Return the size of a BtCursor object in bytes.
//	**
//	** This interfaces is needed so that users of cursors can preallocate
//	** sufficient storage to hold a cursor.  The BtCursor object is opaque
//	** to users so they cannot do the sizeof() themselves - they must call
//	** this routine.
//	*/
func _sqlite3BtreeCursorSize(tls *libc.TLS) (r int32) {
	return libc.Int32FromUint32((libc.Uint32FromInt64(188) + libc.Uint32FromInt32(7)) & libc.Uint32FromInt32(^libc.Int32FromInt32(7)))
}

// 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+4 */ 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+4)
	if uint32((**(**TCellInfo)(__ccgo_up(bp + 4))).FnLocal) != (**(**TCellInfo)(__ccgo_up(bp + 4))).FnPayload {
		**(**int32)(__ccgo_up(bp)) = _clearCellOverflow(tls, pPage, pCell, bp+4)
	} else {
		**(**int32)(__ccgo_up(bp)) = SQLITE_OK
	}
	_dropCell(tls, pPage, iCellIdx, libc.Int32FromUint16((**(**TCellInfo)(__ccgo_up(bp + 4))).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 + 112 + uintptr(iCellDepth+int32(1))*4)))).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 + 60
			v1 = *(*Ti8)(unsafe.Pointer(v2))
			*(*Ti8)(unsafe.Pointer(v2)) = *(*Ti8)(unsafe.Pointer(v2)) - 1
			_releasePage(tls, **(**uintptr)(__ccgo_up(pCur + 112 + uintptr(v1)*4)))
		}
		(*TBtCursor)(unsafe.Pointer(pCur)).FpPage = **(**uintptr)(__ccgo_up(pCur + 112 + uintptr((*TBtCursor)(unsafe.Pointer(pCur)).FiPage)*4))
		**(**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
//
//	/* Move the cursor so that it points to an entry in an index table
//	** near the key pIdxKey.   Return a success code.
//	**
//	** If an exact match is not found, then the cursor is always
//	** left pointing at a leaf page which would hold the entry if it
//	** were present.  The cursor might point to an entry that comes
//	** before or after the key.
//	**
//	** An integer is written into *pRes which is the result of
//	** comparing the key with the entry to which the cursor is
//	** pointing.  The meaning of the integer written into
//	** *pRes is as follows:
//	**
//	**     *pRes<0      The cursor is left pointing at an entry that
//	**                  is smaller than pIdxKey or if the table is empty
//	**                  and the cursor is therefore left point to nothing.
//	**
//	**     *pRes==0     The cursor is left pointing at an entry that
//	**                  exactly matches pIdxKey.
//	**
//	**     *pRes>0      The cursor is left pointing at an entry that
//	**                  is larger than pIdxKey.
//	**
//	** The pIdxKey->eqSeen field is set to 1 if there
//	** exists an entry in the table that exactly matches pIdxKey.
//	*/
func _sqlite3BtreeIndexMoveto(tls *libc.TLS, pCur uintptr, pIdxKey uintptr, pRes uintptr) (r int32) {
	var c, c1, idx, lwr, nCell, nOverrun, rc, upr, v1 int32
	var chldPg TPgno
	var pCell, pCellBody, pCellKey, pPage, v3 uintptr
	var xRecordCompare TRecordCompare
	var v10 Ti8
	var v2 bool
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = c, c1, chldPg, idx, lwr, nCell, nOverrun, pCell, pCellBody, pCellKey, pPage, rc, upr, xRecordCompare, v1, v10, v2, v3
	xRecordCompare = _sqlite3VdbeFindCompare(tls, pIdxKey)
	(*TUnpackedRecord)(unsafe.Pointer(pIdxKey)).FerrCode = uint8(0)
	/* Check to see if we can skip a lot of work.  Two cases:
	 **
	 **    (1) If the cursor is already pointing to the very last cell
	 **        in the table and the pIdxKey search key is greater than or
	 **        equal to that last cell, then no movement is required.
	 **
	 **    (2) If the cursor is on the last page of the table and the first
	 **        cell on that last page is less than or equal to the pIdxKey
	 **        search key, then we can start the search on the current page
	 **        without needing to go back to root.
	 */
	if libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCur)).FeState) == CURSOR_VALID && (*TMemPage)(unsafe.Pointer((*TBtCursor)(unsafe.Pointer(pCur)).FpPage)).Fleaf != 0 && _cursorOnLastPage(tls, pCur) != 0 {
		if v2 = libc.Int32FromUint16((*TBtCursor)(unsafe.Pointer(pCur)).Fix) == libc.Int32FromUint16((*TMemPage)(unsafe.Pointer((*TBtCursor)(unsafe.Pointer(pCur)).FpPage)).FnCell)-int32(1); v2 {
			v1 = _indexCellCompare(tls, (*TBtCursor)(unsafe.Pointer(pCur)).FpPage, libc.Int32FromUint16((*TBtCursor)(unsafe.Pointer(pCur)).Fix), pIdxKey, xRecordCompare)
			c = v1
		}
		if v2 && v1 <= 0 && libc.Int32FromUint8((*TUnpackedRecord)(unsafe.Pointer(pIdxKey)).FerrCode) == SQLITE_OK {
			**(**int32)(__ccgo_up(pRes)) = c
			return SQLITE_OK /* Cursor already pointing at the correct spot */
		}
		if int32((*TBtCursor)(unsafe.Pointer(pCur)).FiPage) > 0 && _indexCellCompare(tls, (*TBtCursor)(unsafe.Pointer(pCur)).FpPage, 0, pIdxKey, xRecordCompare) <= 0 && libc.Int32FromUint8((*TUnpackedRecord)(unsafe.Pointer(pIdxKey)).FerrCode) == SQLITE_OK {
			v3 = pCur + 1
			*(*Tu8)(unsafe.Pointer(v3)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v3))) & ^(libc.Int32FromInt32(BTCF_ValidOvfl) | libc.Int32FromInt32(BTCF_AtLast)))
			if !((*TMemPage)(unsafe.Pointer((*TBtCursor)(unsafe.Pointer(pCur)).FpPage)).FisInit != 0) {
				return _sqlite3CorruptError(tls, int32(79227))
			}
			goto bypass_moveto_root /* Start search on the current page */
		}
		(*TUnpackedRecord)(unsafe.Pointer(pIdxKey)).FerrCode = uint8(SQLITE_OK)
	}
	rc = _moveToRoot(tls, pCur)
	if rc != 0 {
		if rc == int32(SQLITE_EMPTY) {
			**(**int32)(__ccgo_up(pRes)) = -int32(1)
			return SQLITE_OK
		}
		return rc
	}
	goto bypass_moveto_root
bypass_moveto_root:
	;
	for {
		pPage = (*TBtCursor)(unsafe.Pointer(pCur)).FpPage /* Pointer to current cell in pPage */
		/* pPage->nCell must be greater than zero. If this is the root-page
		 ** the cursor would have been INVALID above and this for(;;) loop
		 ** not run. If this is not the root-page, then the moveToChild() routine
		 ** would have already detected db corruption. Similarly, pPage must
		 ** be the right kind (index or table) of b-tree page. Otherwise
		 ** a moveToChild() or moveToRoot() call would have detected corruption.  */
		lwr = 0
		upr = libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FnCell) - int32(1)
		idx = upr >> int32(1) /* idx = (lwr+upr)/2; */
		for {                 /* Size of the pCell cell in bytes */
			pCell = (*TMemPage)(unsafe.Pointer(pPage)).FaDataOfst + uintptr(libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FmaskPage)&(libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TMemPage)(unsafe.Pointer(pPage)).FaCellIdx + uintptr(int32(2)*idx))))<<libc.Int32FromInt32(8)|libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TMemPage)(unsafe.Pointer(pPage)).FaCellIdx + uintptr(int32(2)*idx) + 1)))))
			/* The maximum supported page-size is 65536 bytes. This means that
			 ** the maximum number of record bytes stored on an index B-Tree
			 ** page is less than 16384 bytes and may be stored as a 2-byte
			 ** varint. This information is used to attempt to avoid parsing
			 ** the entire cell by checking for the cases where the record is
			 ** stored entirely within the b-tree page by inspecting the first
			 ** 2 bytes of the cell.
			 */
			nCell = libc.Int32FromUint8(**(**Tu8)(__ccgo_up(pCell)))
			if nCell <= libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pPage)).Fmax1bytePayload) {
				/* This branch runs if the record-size field of the cell is a
				 ** single byte varint and the record fits entirely on the main
				 ** b-tree page.  */
				c1 = (*(*func(*libc.TLS, int32, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{xRecordCompare})))(tls, nCell, pCell+1, pIdxKey)
			} else {
				if v2 = !(libc.Int32FromUint8(**(**Tu8)(__ccgo_up(pCell + 1)))&libc.Int32FromInt32(0x80) != 0); v2 {
					v1 = nCell&libc.Int32FromInt32(0x7f)<<libc.Int32FromInt32(7) + libc.Int32FromUint8(**(**Tu8)(__ccgo_up(pCell + 1)))
					nCell = v1
				}
				if v2 && v1 <= libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FmaxLocal) {
					/* The record-size field is a 2 byte varint and the record
					 ** fits entirely on the main b-tree page.  */
					c1 = (*(*func(*libc.TLS, int32, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{xRecordCompare})))(tls, nCell, pCell+2, pIdxKey)
				} else {
					pCellBody = pCell - uintptr((*TMemPage)(unsafe.Pointer(pPage)).FchildPtrSize)
					nOverrun = int32(18) /* Size of the overrun padding */
					(*(*func(*libc.TLS, uintptr, uintptr, uintptr))(unsafe.Pointer(&struct{ uintptr }{(*TMemPage)(unsafe.Pointer(pPage)).FxParseCell})))(tls, pPage, pCellBody, pCur+28)
					nCell = int32((*TBtCursor)(unsafe.Pointer(pCur)).Finfo.FnKey)
					/* True if key size is 2^32 or more */
					/* Invalid key size:  0x80 0x80 0x00 */
					/* Invalid key size:  0x80 0x80 0x01 */
					/* Minimum legal index key size */
					if nCell < int32(2) || libc.Uint32FromInt32(nCell)/(*TBtShared)(unsafe.Pointer((*TBtCursor)(unsafe.Pointer(pCur)).FpBt)).FusableSize > (*TBtShared)(unsafe.Pointer((*TBtCursor)(unsafe.Pointer(pCur)).FpBt)).FnPage {
						rc = _sqlite3CorruptError(tls, int32(79314))
						goto moveto_index_finish
					}
					pCellKey = _sqlite3Malloc(tls, libc.Uint64FromInt32(nCell)+libc.Uint64FromInt32(nOverrun))
					if pCellKey == uintptr(0) {
						rc = int32(SQLITE_NOMEM)
						goto moveto_index_finish
					}
					(*TBtCursor)(unsafe.Pointer(pCur)).Fix = libc.Uint16FromInt32(idx)
					rc = _accessPayload(tls, pCur, uint32(0), libc.Uint32FromInt32(nCell), pCellKey, 0)
					libc.Xmemset(tls, pCellKey+uintptr(nCell), 0, libc.Uint32FromInt32(nOverrun)) /* Fix uninit warnings */
					v3 = pCur + 1
					*(*Tu8)(unsafe.Pointer(v3)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v3))) & ^libc.Int32FromInt32(BTCF_ValidOvfl))
					if rc != 0 {
						Xsqlite3_free(tls, pCellKey)
						goto moveto_index_finish
					}
					c1 = _sqlite3VdbeRecordCompare(tls, nCell, pCellKey, pIdxKey)
					Xsqlite3_free(tls, pCellKey)
				}
			}
			if c1 < 0 {
				lwr = idx + int32(1)
			} else {
				if c1 > 0 {
					upr = idx - int32(1)
				} else {
					**(**int32)(__ccgo_up(pRes)) = 0
					rc = SQLITE_OK
					(*TBtCursor)(unsafe.Pointer(pCur)).Fix = libc.Uint16FromInt32(idx)
					if (*TUnpackedRecord)(unsafe.Pointer(pIdxKey)).FerrCode != 0 {
						rc = _sqlite3CorruptError(tls, int32(79346))
					}
					goto moveto_index_finish
				}
			}
			if lwr > upr {
				break
			}
			idx = (lwr + upr) >> int32(1) /* idx = (lwr+upr)/2 */
			goto _5
		_5:
		}
		if (*TMemPage)(unsafe.Pointer(pPage)).Fleaf != 0 {
			(*TBtCursor)(unsafe.Pointer(pCur)).Fix = libc.Uint16FromInt32(idx)
			**(**int32)(__ccgo_up(pRes)) = c1
			rc = SQLITE_OK
			goto moveto_index_finish
		}
		if lwr >= libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FnCell) {
			chldPg = _sqlite3Get4byte(tls, (*TMemPage)(unsafe.Pointer(pPage)).FaData+uintptr(libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pPage)).FhdrOffset)+int32(8)))
		} else {
			chldPg = _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)*lwr))))<<libc.Int32FromInt32(8)|libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TMemPage)(unsafe.Pointer(pPage)).FaCellIdx + uintptr(int32(2)*lwr) + 1))))))
		}
		/* This block is similar to an in-lined version of:
		 **
		 **    pCur->ix = (u16)lwr;
		 **    rc = moveToChild(pCur, chldPg);
		 **    if( rc ) break;
		 */
		(*TBtCursor)(unsafe.Pointer(pCur)).Finfo.FnSize = uint16(0)
		v3 = pCur + 1
		*(*Tu8)(unsafe.Pointer(v3)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v3))) & ^(libc.Int32FromInt32(BTCF_ValidNKey) | libc.Int32FromInt32(BTCF_ValidOvfl)))
		if int32((*TBtCursor)(unsafe.Pointer(pCur)).FiPage) >= libc.Int32FromInt32(BTCURSOR_MAX_DEPTH)-libc.Int32FromInt32(1) {
			return _sqlite3CorruptError(tls, int32(79377))
		}
		**(**Tu16)(__ccgo_up(pCur + 64 + uintptr((*TBtCursor)(unsafe.Pointer(pCur)).FiPage)*2)) = libc.Uint16FromInt32(lwr)
		**(**uintptr)(__ccgo_up(pCur + 112 + uintptr((*TBtCursor)(unsafe.Pointer(pCur)).FiPage)*4)) = (*TBtCursor)(unsafe.Pointer(pCur)).FpPage
		(*TBtCursor)(unsafe.Pointer(pCur)).Fix = uint16(0)
		(*TBtCursor)(unsafe.Pointer(pCur)).FiPage = (*TBtCursor)(unsafe.Pointer(pCur)).FiPage + 1
		rc = _getAndInitPage(tls, (*TBtCursor)(unsafe.Pointer(pCur)).FpBt, chldPg, pCur+108, libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCur)).FcurPagerFlags))
		if rc == SQLITE_OK && (libc.Int32FromUint16((*TMemPage)(unsafe.Pointer((*TBtCursor)(unsafe.Pointer(pCur)).FpPage)).FnCell) < int32(1) || libc.Int32FromUint8((*TMemPage)(unsafe.Pointer((*TBtCursor)(unsafe.Pointer(pCur)).FpPage)).FintKey) != libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCur)).FcurIntKey)) {
			_releasePage(tls, (*TBtCursor)(unsafe.Pointer(pCur)).FpPage)
			rc = _sqlite3CorruptError(tls, int32(79388))
		}
		if rc != 0 {
			v3 = pCur + 60
			*(*Ti8)(unsafe.Pointer(v3)) = *(*Ti8)(unsafe.Pointer(v3)) - 1
			v10 = *(*Ti8)(unsafe.Pointer(v3))
			(*TBtCursor)(unsafe.Pointer(pCur)).FpPage = **(**uintptr)(__ccgo_up(pCur + 112 + uintptr(v10)*4))
			break
		}
		/*
		 ***** End of in-lined moveToChild() call */
		goto _4
	_4:
	}
	goto moveto_index_finish
moveto_index_finish:
	;
	(*TBtCursor)(unsafe.Pointer(pCur)).Finfo.FnSize = uint16(0)
	return rc
}

// C documentation
//
//	/*
//	** Insert a new record into the BTree.  The content of the new record
//	** is described by the pX object.  The pCur cursor is used only to
//	** define what table the record should be inserted into, and is left
//	** pointing at a random location.
//	**
//	** For a table btree (used for rowid tables), only the pX.nKey value of
//	** the key is used. The pX.pKey value must be NULL.  The pX.nKey is the
//	** rowid or INTEGER PRIMARY KEY of the row.  The pX.nData,pData,nZero fields
//	** hold the content of the row.
//	**
//	** For an index btree (used for indexes and WITHOUT ROWID tables), the
//	** key is an arbitrary byte sequence stored in pX.pKey,nKey.  The
//	** pX.pData,nData,nZero fields must be zero.
//	**
//	** If the seekResult parameter is non-zero, then a successful call to
//	** sqlite3BtreeIndexMoveto() to seek cursor pCur to (pKey,nKey) has already
//	** been performed.  In other words, if seekResult!=0 then the cursor
//	** is currently pointing to a cell that will be adjacent to the cell
//	** to be inserted.  If seekResult<0 then pCur points to a cell that is
//	** smaller then (pKey,nKey).  If seekResult>0 then pCur points to a cell
//	** that is larger than (pKey,nKey).
//	**
//	** If seekResult==0, that means pCur is pointing at some unknown location.
//	** In that case, this routine must seek the cursor to the correct insertion
//	** point for (pKey,nKey) before doing the insertion.  For index btrees,
//	** if pX->nMem is non-zero, then pX->aMem contains pointers to the unpacked
//	** key values and pX->aMem can be used instead of pX->pKey to avoid having
//	** to decode the key.
//	*/
func _sqlite3BtreeInsert(tls *libc.TLS, pCur uintptr, pX uintptr, flags int32, seekResult int32) (r int32) {
	bp := tls.Alloc(112)
	defer tls.Free(112)
	var idx int32
	var newCell, oldCell, p, pPage, v1 uintptr
	var ovfl TPgno
	var v2 Tu16
	var _ /* info at bp+72 */ TCellInfo
	var _ /* info at bp+92 */ TCellInfo
	var _ /* loc at bp+4 */ int32
	var _ /* r at bp+12 */ TUnpackedRecord
	var _ /* rc at bp+0 */ int32
	var _ /* szNew at bp+8 */ int32
	var _ /* x2 at bp+40 */ TBtreePayload
	_, _, _, _, _, _, _, _ = idx, newCell, oldCell, ovfl, p, pPage, v1, v2
	**(**int32)(__ccgo_up(bp + 4)) = seekResult /* -1: before desired location  +1: after */
	**(**int32)(__ccgo_up(bp + 8)) = 0
	p = (*TBtCursor)(unsafe.Pointer(pCur)).FpBtree
	newCell = uintptr(0)
	/* Save the positions of any other cursors open on this table.
	 **
	 ** In some cases, the call to btreeMoveto() below is a no-op. For
	 ** example, when inserting data into a table with auto-generated integer
	 ** keys, the VDBE layer invokes sqlite3BtreeLast() to figure out the
	 ** integer key to use. It then calls this function to actually insert the
	 ** data into the intkey B-Tree. In this case btreeMoveto() recognizes
	 ** that the cursor is already where it needs to be and returns without
	 ** doing any work. To avoid thwarting these optimizations, it is important
	 ** not to clear the cursor here.
	 */
	if libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCur)).FcurFlags)&int32(BTCF_Multiple) != 0 {
		**(**int32)(__ccgo_up(bp)) = _saveAllCursors(tls, (*TBtree)(unsafe.Pointer(p)).FpBt, (*TBtCursor)(unsafe.Pointer(pCur)).FpgnoRoot, pCur)
		if **(**int32)(__ccgo_up(bp)) != 0 {
			return **(**int32)(__ccgo_up(bp))
		}
		if **(**int32)(__ccgo_up(bp + 4)) != 0 && int32((*TBtCursor)(unsafe.Pointer(pCur)).FiPage) < 0 {
			/* This can only happen if the schema is corrupt such that there is more
			 ** than one table or index with the same root page as used by the cursor.
			 ** Which can only happen if the SQLITE_NoSchemaError flag was set when
			 ** the schema was loaded. This cannot be asserted though, as a user might
			 ** set the flag, load the schema, and then unset the flag.  */
			return _sqlite3CorruptError(tls, int32(82581))
		}
	}
	/* Ensure that the cursor is not in the CURSOR_FAULT state and that it
	 ** points to a valid cell.
	 */
	if libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCur)).FeState) >= int32(CURSOR_REQUIRESEEK) {
		**(**int32)(__ccgo_up(bp)) = _moveToRoot(tls, pCur)
		if **(**int32)(__ccgo_up(bp)) != 0 && **(**int32)(__ccgo_up(bp)) != int32(SQLITE_EMPTY) {
			return **(**int32)(__ccgo_up(bp))
		}
	}
	/* Assert that the caller has been consistent. If this cursor was opened
	 ** expecting an index b-tree, then the caller should be inserting blob
	 ** keys with no associated data. If the cursor was opened expecting an
	 ** intkey table, the caller should be inserting integer keys with a
	 ** blob of associated data.  */
	if (*TBtCursor)(unsafe.Pointer(pCur)).FpKeyInfo == uintptr(0) {
		/* If this is an insert into a table b-tree, invalidate any incrblob
		 ** cursors open on the row being replaced */
		if (*TBtree)(unsafe.Pointer(p)).FhasIncrblobCur != 0 {
			_invalidateIncrblobCursors(tls, p, (*TBtCursor)(unsafe.Pointer(pCur)).FpgnoRoot, (*TBtreePayload)(unsafe.Pointer(pX)).FnKey, 0)
		}
		/* If BTREE_SAVEPOSITION is set, the cursor must already be pointing
		 ** to a row with the same key as the new entry being inserted.
		 */
		/* On the other hand, BTREE_SAVEPOSITION==0 does not imply
		 ** that the cursor is not pointing to a row to be overwritten.
		 ** So do a complete check.
		 */
		if libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCur)).FcurFlags)&int32(BTCF_ValidNKey) != 0 && (*TBtreePayload)(unsafe.Pointer(pX)).FnKey == (*TBtCursor)(unsafe.Pointer(pCur)).Finfo.FnKey {
			/* The cursor is pointing to the entry that is to be
			 ** overwritten */
			if libc.Int32FromUint16((*TBtCursor)(unsafe.Pointer(pCur)).Finfo.FnSize) != 0 && (*TBtCursor)(unsafe.Pointer(pCur)).Finfo.FnPayload == libc.Uint32FromInt32((*TBtreePayload)(unsafe.Pointer(pX)).FnData)+libc.Uint32FromInt32((*TBtreePayload)(unsafe.Pointer(pX)).FnZero) {
				/* New entry is the same size as the old.  Do an overwrite */
				return _btreeOverwriteCell(tls, pCur, pX)
			}
		} else {
			if **(**int32)(__ccgo_up(bp + 4)) == 0 {
				/* The cursor is *not* pointing to the cell to be overwritten, nor
				 ** to an adjacent cell.  Move the cursor so that it is pointing either
				 ** to the cell to be overwritten or an adjacent cell.
				 */
				**(**int32)(__ccgo_up(bp)) = _sqlite3BtreeTableMoveto(tls, pCur, (*TBtreePayload)(unsafe.Pointer(pX)).FnKey, libc.BoolInt32(flags&int32(BTREE_APPEND) != 0), bp+4)
				if **(**int32)(__ccgo_up(bp)) != 0 {
					return **(**int32)(__ccgo_up(bp))
				}
			}
		}
	} else {
		/* This is an index or a WITHOUT ROWID table */
		/* If BTREE_SAVEPOSITION is set, the cursor must already be pointing
		 ** to a row with the same key as the new entry being inserted.
		 */
		/* If the cursor is not already pointing either to the cell to be
		 ** overwritten, or if a new cell is being inserted, if the cursor is
		 ** not pointing to an immediately adjacent cell, then move the cursor
		 ** so that it does.
		 */
		if **(**int32)(__ccgo_up(bp + 4)) == 0 && flags&int32(BTREE_SAVEPOSITION) == 0 {
			if (*TBtreePayload)(unsafe.Pointer(pX)).FnMem != 0 {
				(**(**TUnpackedRecord)(__ccgo_up(bp + 12))).FpKeyInfo = (*TBtCursor)(unsafe.Pointer(pCur)).FpKeyInfo
				(**(**TUnpackedRecord)(__ccgo_up(bp + 12))).FaMem = (*TBtreePayload)(unsafe.Pointer(pX)).FaMem
				(**(**TUnpackedRecord)(__ccgo_up(bp + 12))).FnField = (*TBtreePayload)(unsafe.Pointer(pX)).FnMem
				(**(**TUnpackedRecord)(__ccgo_up(bp + 12))).Fdefault_rc = 0
				(**(**TUnpackedRecord)(__ccgo_up(bp + 12))).FeqSeen = uint8(0)
				**(**int32)(__ccgo_up(bp)) = _sqlite3BtreeIndexMoveto(tls, pCur, bp+12, bp+4)
			} else {
				**(**int32)(__ccgo_up(bp)) = _btreeMoveto(tls, pCur, (*TBtreePayload)(unsafe.Pointer(pX)).FpKey, (*TBtreePayload)(unsafe.Pointer(pX)).FnKey, libc.BoolInt32(flags&int32(BTREE_APPEND) != 0), bp+4)
			}
			if **(**int32)(__ccgo_up(bp)) != 0 {
				return **(**int32)(__ccgo_up(bp))
			}
		}
		/* If the cursor is currently pointing to an entry to be overwritten
		 ** and the new content is the same as as the old, then use the
		 ** overwrite optimization.
		 */
		if **(**int32)(__ccgo_up(bp + 4)) == 0 {
			_getCellInfo(tls, pCur)
			if (*TBtCursor)(unsafe.Pointer(pCur)).Finfo.FnKey == (*TBtreePayload)(unsafe.Pointer(pX)).FnKey {
				(**(**TBtreePayload)(__ccgo_up(bp + 40))).FpData = (*TBtreePayload)(unsafe.Pointer(pX)).FpKey
				(**(**TBtreePayload)(__ccgo_up(bp + 40))).FnData = int32((*TBtreePayload)(unsafe.Pointer(pX)).FnKey)
				(**(**TBtreePayload)(__ccgo_up(bp + 40))).FnZero = 0
				return _btreeOverwriteCell(tls, pCur, bp+40)
			}
		}
	}
	pPage = (*TBtCursor)(unsafe.Pointer(pCur)).FpPage
	if (*TMemPage)(unsafe.Pointer(pPage)).FnFree < 0 {
		if libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCur)).FeState) > int32(CURSOR_INVALID) {
			/* ^^^^^--- due to the moveToRoot() call above */
			**(**int32)(__ccgo_up(bp)) = _sqlite3CorruptError(tls, int32(82704))
		} else {
			**(**int32)(__ccgo_up(bp)) = _btreeComputeFreeSpace(tls, pPage)
		}
		if **(**int32)(__ccgo_up(bp)) != 0 {
			return **(**int32)(__ccgo_up(bp))
		}
	}
	newCell = (*TBtShared)(unsafe.Pointer((*TBtree)(unsafe.Pointer(p)).FpBt)).FpTmpSpace
	if flags&int32(BTREE_PREFORMAT) != 0 {
		**(**int32)(__ccgo_up(bp)) = SQLITE_OK
		**(**int32)(__ccgo_up(bp + 8)) = (*TBtShared)(unsafe.Pointer((*TBtree)(unsafe.Pointer(p)).FpBt)).FnPreformatSize
		if **(**int32)(__ccgo_up(bp + 8)) < int32(4) {
			**(**int32)(__ccgo_up(bp + 8)) = int32(4)
			**(**uint8)(__ccgo_up(newCell + 3)) = uint8(0)
		}
		if (*TBtShared)(unsafe.Pointer((*TBtree)(unsafe.Pointer(p)).FpBt)).FautoVacuum != 0 && **(**int32)(__ccgo_up(bp + 8)) > libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FmaxLocal) {
			(*(*func(*libc.TLS, uintptr, uintptr, uintptr))(unsafe.Pointer(&struct{ uintptr }{(*TMemPage)(unsafe.Pointer(pPage)).FxParseCell})))(tls, pPage, newCell, bp+72)
			if (**(**TCellInfo)(__ccgo_up(bp + 72))).FnPayload != uint32((**(**TCellInfo)(__ccgo_up(bp + 72))).FnLocal) {
				ovfl = _sqlite3Get4byte(tls, newCell+uintptr(**(**int32)(__ccgo_up(bp + 8))-int32(4)))
				_ptrmapPut(tls, (*TBtree)(unsafe.Pointer(p)).FpBt, ovfl, uint8(PTRMAP_OVERFLOW1), (*TMemPage)(unsafe.Pointer(pPage)).Fpgno, bp)
				if **(**int32)(__ccgo_up(bp)) != 0 {
					goto end_insert
				}
			}
		}
	} else {
		**(**int32)(__ccgo_up(bp)) = _fillInCell(tls, pPage, newCell, pX, bp+8)
		if **(**int32)(__ccgo_up(bp)) != 0 {
			goto end_insert
		}
	}
	idx = libc.Int32FromUint16((*TBtCursor)(unsafe.Pointer(pCur)).Fix)
	(*TBtCursor)(unsafe.Pointer(pCur)).Finfo.FnSize = uint16(0)
	if **(**int32)(__ccgo_up(bp + 4)) == 0 {
		if idx >= libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FnCell) {
			return _sqlite3CorruptError(tls, int32(82746))
		}
		**(**int32)(__ccgo_up(bp)) = _sqlite3PagerWrite(tls, (*TMemPage)(unsafe.Pointer(pPage)).FpDbPage)
		if **(**int32)(__ccgo_up(bp)) != 0 {
			goto end_insert
		}
		oldCell = (*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)*idx))))<<libc.Int32FromInt32(8)|libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TMemPage)(unsafe.Pointer(pPage)).FaCellIdx + uintptr(int32(2)*idx) + 1)))))
		if !((*TMemPage)(unsafe.Pointer(pPage)).Fleaf != 0) {
			libc.Xmemcpy(tls, newCell, oldCell, uint32(4))
		}
		(*(*func(*libc.TLS, uintptr, uintptr, uintptr))(unsafe.Pointer(&struct{ uintptr }{(*TMemPage)(unsafe.Pointer(pPage)).FxParseCell})))(tls, pPage, oldCell, bp+92)
		if uint32((**(**TCellInfo)(__ccgo_up(bp + 92))).FnLocal) != (**(**TCellInfo)(__ccgo_up(bp + 92))).FnPayload {
			**(**int32)(__ccgo_up(bp)) = _clearCellOverflow(tls, pPage, oldCell, bp+92)
		} else {
			**(**int32)(__ccgo_up(bp)) = SQLITE_OK
		}
		v1 = pCur + 1
		*(*Tu8)(unsafe.Pointer(v1)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v1))) & ^libc.Int32FromInt32(BTCF_ValidOvfl))
		if libc.Int32FromUint16((**(**TCellInfo)(__ccgo_up(bp + 92))).FnSize) == **(**int32)(__ccgo_up(bp + 8)) && uint32((**(**TCellInfo)(__ccgo_up(bp + 92))).FnLocal) == (**(**TCellInfo)(__ccgo_up(bp + 92))).FnPayload && (!((*TBtShared)(unsafe.Pointer((*TBtree)(unsafe.Pointer(p)).FpBt)).FautoVacuum != 0) || **(**int32)(__ccgo_up(bp + 8)) < libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FminLocal)) {
			/* Overwrite the old cell with the new if they are the same size.
			 ** We could also try to do this if the old cell is smaller, then add
			 ** the leftover space to the free list.  But experiments show that
			 ** doing that is no faster then skipping this optimization and just
			 ** calling dropCell() and insertCell().
			 **
			 ** This optimization cannot be used on an autovacuum database if the
			 ** new entry uses overflow pages, as the insertCell() call below is
			 ** necessary to add the PTRMAP_OVERFLOW1 pointer-map entry.  */
			/* clearCell never fails when nLocal==nPayload */
			if oldCell < (*TMemPage)(unsafe.Pointer(pPage)).FaData+uintptr((*TMemPage)(unsafe.Pointer(pPage)).FhdrOffset)+uintptr(10) {
				return _sqlite3CorruptError(tls, int32(82773))
			}
			if oldCell+uintptr(**(**int32)(__ccgo_up(bp + 8))) > (*TMemPage)(unsafe.Pointer(pPage)).FaDataEnd {
				return _sqlite3CorruptError(tls, int32(82776))
			}
			libc.Xmemcpy(tls, oldCell, newCell, libc.Uint32FromInt32(**(**int32)(__ccgo_up(bp + 8))))
			return SQLITE_OK
		}
		_dropCell(tls, pPage, idx, libc.Int32FromUint16((**(**TCellInfo)(__ccgo_up(bp + 92))).FnSize), bp)
		if **(**int32)(__ccgo_up(bp)) != 0 {
			goto end_insert
		}
	} else {
		if **(**int32)(__ccgo_up(bp + 4)) < 0 && libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FnCell) > 0 {
			v1 = pCur + 62
			*(*Tu16)(unsafe.Pointer(v1)) = *(*Tu16)(unsafe.Pointer(v1)) + 1
			v2 = *(*Tu16)(unsafe.Pointer(v1))
			idx = libc.Int32FromUint16(v2)
			v1 = pCur + 1
			*(*Tu8)(unsafe.Pointer(v1)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v1))) & ^(libc.Int32FromInt32(BTCF_ValidNKey) | libc.Int32FromInt32(BTCF_ValidOvfl)))
		} else {
		}
	}
	**(**int32)(__ccgo_up(bp)) = _insertCellFast(tls, pPage, idx, newCell, **(**int32)(__ccgo_up(bp + 8)))
	/* If no error has occurred and pPage has an overflow cell, call balance()
	 ** to redistribute the cells within the tree. Since balance() may move
	 ** the cursor, zero the BtCursor.info.nSize and BTCF_ValidNKey
	 ** variables.
	 **
	 ** Previous versions of SQLite called moveToRoot() to move the cursor
	 ** back to the root page as balance() used to invalidate the contents
	 ** of BtCursor.apPage[] and BtCursor.aiIdx[]. Instead of doing that,
	 ** set the cursor state to "invalid". This makes common insert operations
	 ** slightly faster.
	 **
	 ** There is a subtle but important optimization here too. When inserting
	 ** multiple records into an intkey b-tree using a single cursor (as can
	 ** happen while processing an "INSERT INTO ... SELECT" statement), it
	 ** is advantageous to leave the cursor pointing to the last entry in
	 ** the b-tree if possible. If the cursor is left pointing to the last
	 ** entry in the table, and the next row inserted has an integer key
	 ** larger than the largest existing key, it is possible to insert the
	 ** row without seeking the cursor. This can be a big performance boost.
	 */
	if (*TMemPage)(unsafe.Pointer(pPage)).FnOverflow != 0 {
		v1 = pCur + 1
		*(*Tu8)(unsafe.Pointer(v1)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v1))) & ^(libc.Int32FromInt32(BTCF_ValidNKey) | libc.Int32FromInt32(BTCF_ValidOvfl)))
		**(**int32)(__ccgo_up(bp)) = _balance(tls, pCur)
		/* Must make sure nOverflow is reset to zero even if the balance()
		 ** fails. Internal data structure corruption will result otherwise.
		 ** Also, set the cursor state to invalid. This stops saveCursorPosition()
		 ** from trying to save the current position of the cursor.  */
		(*TMemPage)(unsafe.Pointer((*TBtCursor)(unsafe.Pointer(pCur)).FpPage)).FnOverflow = uint8(0)
		(*TBtCursor)(unsafe.Pointer(pCur)).FeState = uint8(CURSOR_INVALID)
		if flags&int32(BTREE_SAVEPOSITION) != 0 && **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
			_btreeReleaseAllCursorPages(tls, pCur)
			if (*TBtCursor)(unsafe.Pointer(pCur)).FpKeyInfo != 0 {
				(*TBtCursor)(unsafe.Pointer(pCur)).FpKey = _sqlite3Malloc(tls, libc.Uint64FromInt64((*TBtreePayload)(unsafe.Pointer(pX)).FnKey))
				if (*TBtCursor)(unsafe.Pointer(pCur)).FpKey == uintptr(0) {
					**(**int32)(__ccgo_up(bp)) = int32(SQLITE_NOMEM)
				} else {
					libc.Xmemcpy(tls, (*TBtCursor)(unsafe.Pointer(pCur)).FpKey, (*TBtreePayload)(unsafe.Pointer(pX)).FpKey, libc.Uint32FromInt64((*TBtreePayload)(unsafe.Pointer(pX)).FnKey))
				}
			}
			(*TBtCursor)(unsafe.Pointer(pCur)).FeState = uint8(CURSOR_REQUIRESEEK)
			(*TBtCursor)(unsafe.Pointer(pCur)).FnKey = (*TBtreePayload)(unsafe.Pointer(pX)).FnKey
		}
	}
	goto end_insert
end_insert:
	;
	return **(**int32)(__ccgo_up(bp))
	return r
}

func _sqlite3BtreeNext(tls *libc.TLS, pCur uintptr, flags int32) (r int32) {
	var pPage, v1 uintptr
	var v2 Tu16
	_, _, _ = pPage, v1, v2
	_ = flags /* Used in COMDB2 but not native SQLite */
	(*TBtCursor)(unsafe.Pointer(pCur)).Finfo.FnSize = uint16(0)
	v1 = pCur + 1
	*(*Tu8)(unsafe.Pointer(v1)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v1))) & ^(libc.Int32FromInt32(BTCF_ValidNKey) | libc.Int32FromInt32(BTCF_ValidOvfl)))
	if libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCur)).FeState) != CURSOR_VALID {
		return _btreeNext(tls, pCur)
	}
	pPage = (*TBtCursor)(unsafe.Pointer(pCur)).FpPage
	v1 = pCur + 62
	*(*Tu16)(unsafe.Pointer(v1)) = *(*Tu16)(unsafe.Pointer(v1)) + 1
	v2 = *(*Tu16)(unsafe.Pointer(v1))
	if libc.Int32FromUint16(v2) >= libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FnCell) {
		(*TBtCursor)(unsafe.Pointer(pCur)).Fix = (*TBtCursor)(unsafe.Pointer(pCur)).Fix - 1
		return _btreeNext(tls, pCur)
	}
	if (*TMemPage)(unsafe.Pointer(pPage)).Fleaf != 0 {
		return SQLITE_OK
	} else {
		return _moveToLeftmost(tls, pCur)
	}
	return r
}

// C documentation
//
//	/*
//	** Return an estimate for the number of rows in the table that pCur is
//	** pointing to.  Return a negative number if no estimate is currently
//	** available.
//	*/
func _sqlite3BtreeRowCountEst(tls *libc.TLS, pCur uintptr) (r Ti64) {
	var i Tu8
	var n Ti64
	_, _ = i, n
	/* Currently this interface is only called by the OP_IfSizeBetween
	 ** opcode and the OP_Count opcode with P3=1.  In either case,
	 ** the cursor will always be valid unless the btree is empty. */
	if libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCur)).FeState) != CURSOR_VALID {
		return 0
	}
	if libc.Int32FromUint8((*TMemPage)(unsafe.Pointer((*TBtCursor)(unsafe.Pointer(pCur)).FpPage)).Fleaf) == 0 {
		return int64(-int32(1))
	}
	n = libc.Int64FromUint16((*TMemPage)(unsafe.Pointer((*TBtCursor)(unsafe.Pointer(pCur)).FpPage)).FnCell)
	i = uint8(0)
	for {
		if !(libc.Int32FromUint8(i) < int32((*TBtCursor)(unsafe.Pointer(pCur)).FiPage)) {
			break
		}
		n = n * int64(libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(pCur + 112 + uintptr(i)*4)))).FnCell)+int32(1))
		goto _1
	_1:
		;
		i = i + 1
	}
	return n
}

// C documentation
//
//	/*
//	** Look through the list of open database files in db->aDb[] and if
//	** any have been closed, remove them from the list.  Reallocate the
//	** db->aDb[] structure to a smaller size, if possible.
//	**
//	** Entry 0 (the "main" database) and entry 1 (the "temp" database)
//	** are never candidates for being collapsed.
//	*/
func _sqlite3CollapseDatabaseArray(tls *libc.TLS, db uintptr) {
	var i, j, v2 int32
	var pDb uintptr
	_, _, _, _ = i, j, pDb, v2
	v2 = libc.Int32FromInt32(2)
	j = v2
	i = v2
	for {
		if !(i < (*Tsqlite3)(unsafe.Pointer(db)).FnDb) {
			break
		}
		pDb = (*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(i)*16
		if (*TDb)(unsafe.Pointer(pDb)).FpBt == uintptr(0) {
			_sqlite3DbFree(tls, db, (*TDb)(unsafe.Pointer(pDb)).FzDbSName)
			(*TDb)(unsafe.Pointer(pDb)).FzDbSName = uintptr(0)
			goto _1
		}
		if j < i {
			**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(j)*16)) = **(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(i)*16))
		}
		j = j + 1
		goto _1
	_1:
		;
		i = i + 1
	}
	(*Tsqlite3)(unsafe.Pointer(db)).FnDb = j
	if (*Tsqlite3)(unsafe.Pointer(db)).FnDb <= int32(2) && (*Tsqlite3)(unsafe.Pointer(db)).FaDb != db+472 {
		libc.Xmemcpy(tls, db+472, (*Tsqlite3)(unsafe.Pointer(db)).FaDb, libc.Uint32FromInt32(2)*libc.Uint32FromInt64(16))
		_sqlite3DbFree(tls, db, (*Tsqlite3)(unsafe.Pointer(db)).FaDb)
		(*Tsqlite3)(unsafe.Pointer(db)).FaDb = db + 472
	}
}

// C documentation
//
//	/*
//	** The most recently coded instruction was an OP_Column to retrieve the
//	** i-th column of table pTab. This routine sets the P4 parameter of the
//	** OP_Column to the default value, if any.
//	**
//	** The default value of a column is specified by a DEFAULT clause in the
//	** column definition. This was either supplied by the user when the table
//	** was created, or added later to the table definition by an ALTER TABLE
//	** command. If the latter, then the row-records in the table btree on disk
//	** may not contain a value for the column and the default value, taken
//	** from the P4 parameter of the OP_Column instruction, is returned instead.
//	** If the former, then all row-records are guaranteed to include a value
//	** for the column and the P4 value is not required.
//	**
//	** Column definitions created by an ALTER TABLE command may only have
//	** literal default values specified: a number, null or a string. (If a more
//	** complicated default expression value was provided, it is evaluated
//	** when the ALTER TABLE is executed and one of the literal values written
//	** into the sqlite_schema table.)
//	**
//	** Therefore, the P4 parameter is only required if the default value for
//	** the column is a literal number, string or null. The sqlite3ValueFromExpr()
//	** function is capable of transforming these types of expressions into
//	** sqlite3_value objects.
//	**
//	** If column as REAL affinity and the table is an ordinary b-tree table
//	** (not a virtual table) then the value might have been stored as an
//	** integer.  In that case, add an OP_RealAffinity opcode to make sure
//	** it has been converted into REAL.
//	*/
func _sqlite3ColumnDefault(tls *libc.TLS, v uintptr, pTab uintptr, i int32, iReg int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var enc Tu8
	var pCol uintptr
	var _ /* pValue at bp+0 */ uintptr
	_, _ = enc, pCol
	pCol = (*TTable)(unsafe.Pointer(pTab)).FaCol + uintptr(i)*12
	if (*TColumn)(unsafe.Pointer(pCol)).FiDflt != 0 {
		**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
		enc = (*Tsqlite3)(unsafe.Pointer(_sqlite3VdbeDb(tls, v))).Fenc
		_sqlite3ValueFromExpr(tls, _sqlite3VdbeDb(tls, v), _sqlite3ColumnExpr(tls, pTab, pCol), enc, libc.Uint8FromInt8((*TColumn)(unsafe.Pointer(pCol)).Faffinity), bp)
		if **(**uintptr)(__ccgo_up(bp)) != 0 {
			_sqlite3VdbeAppendP4(tls, v, **(**uintptr)(__ccgo_up(bp)), -int32(11))
		}
	}
	if int32((*TColumn)(unsafe.Pointer(pCol)).Faffinity) == int32(SQLITE_AFF_REAL) && !(libc.Int32FromUint8((*TTable)(unsafe.Pointer(pTab)).FeTabType) == libc.Int32FromInt32(TABTYP_VTAB)) {
		_sqlite3VdbeAddOp1(tls, v, int32(OP_RealAffinity), iReg)
	}
}

// C documentation
//
//	/*
//	** This function is called when
//	** the transaction opened by database db has just finished. Locks held
//	** by database connection db have been released.
//	**
//	** This function loops through each entry in the blocked connections
//	** list and does the following:
//	**
//	**   1) If the sqlite3.pBlockingConnection member of a list entry is
//	**      set to db, then set pBlockingConnection=0.
//	**
//	**   2) If the sqlite3.pUnlockConnection member of a list entry is
//	**      set to db, then invoke the configured unlock-notify callback and
//	**      set pUnlockConnection=0.
//	**
//	**   3) If the two steps above mean that pBlockingConnection==0 and
//	**      pUnlockConnection==0, remove the entry from the blocked connections
//	**      list.
//	*/
func _sqlite3ConnectionUnlocked(tls *libc.TLS, db uintptr) {
	bp := tls.Alloc(64)
	defer tls.Free(64)
	var aArg, aDyn, p, pNew, pp, xUnlockNotify, v2 uintptr
	var nArg, v3 int32
	var _ /* aStatic at bp+0 */ [16]uintptr
	_, _, _, _, _, _, _, _, _ = aArg, aDyn, nArg, p, pNew, pp, xUnlockNotify, v2, v3
	xUnlockNotify = uintptr(0) /* Unlock-notify cb to invoke */
	nArg = 0                   /* Arguments to the unlock callback */
	aDyn = uintptr(0)          /* Starter space for aArg[].  No malloc required */
	aArg = bp
	_enterMutex(tls) /* Enter STATIC_MAIN mutex */
	/* This loop runs once for each entry in the blocked-connections list. */
	pp = uintptr(unsafe.Pointer(&_sqlite3BlockedList))
	for {
		if !(**(**uintptr)(__ccgo_up(pp)) != 0) {
			break
		}
		p = **(**uintptr)(__ccgo_up(pp))
		/* Step 1. */
		if (*Tsqlite3)(unsafe.Pointer(p)).FpBlockingConnection == db {
			(*Tsqlite3)(unsafe.Pointer(p)).FpBlockingConnection = uintptr(0)
		}
		/* Step 2. */
		if (*Tsqlite3)(unsafe.Pointer(p)).FpUnlockConnection == db {
			if (*Tsqlite3)(unsafe.Pointer(p)).FxUnlockNotify != xUnlockNotify && nArg != 0 {
				(*(*func(*libc.TLS, uintptr, int32))(unsafe.Pointer(&struct{ uintptr }{xUnlockNotify})))(tls, aArg, nArg)
				nArg = 0
			}
			_sqlite3BeginBenignMalloc(tls)
			if !(aDyn != 0) && nArg == libc.Int32FromUint32(libc.Uint32FromInt64(64)/libc.Uint32FromInt64(4)) || aDyn != 0 && nArg == libc.Int32FromUint32(libc.Uint32FromInt32(_sqlite3MallocSize(tls, aDyn))/libc.Uint32FromInt64(4)) {
				/* The aArg[] array needs to grow. */
				pNew = _sqlite3Malloc(tls, uint64(libc.Uint32FromInt32(nArg)*uint32(4)*uint32(2)))
				if pNew != 0 {
					libc.Xmemcpy(tls, pNew, aArg, libc.Uint32FromInt32(nArg)*uint32(4))
					Xsqlite3_free(tls, aDyn)
					v2 = pNew
					aArg = v2
					aDyn = v2
				} else {
					/* This occurs when the array of context pointers that need to
					 ** be passed to the unlock-notify callback is larger than the
					 ** aStatic[] array allocated on the stack and the attempt to
					 ** allocate a larger array from the heap has failed.
					 **
					 ** This is a difficult situation to handle. Returning an error
					 ** code to the caller is insufficient, as even if an error code
					 ** is returned the transaction on connection db will still be
					 ** closed and the unlock-notify callbacks on blocked connections
					 ** will go unissued. This might cause the application to wait
					 ** indefinitely for an unlock-notify callback that will never
					 ** arrive.
					 **
					 ** Instead, invoke the unlock-notify callback with the context
					 ** array already accumulated. We can then clear the array and
					 ** begin accumulating any further context pointers without
					 ** requiring any dynamic allocation. This is sub-optimal because
					 ** it means that instead of one callback with a large array of
					 ** context pointers the application will receive two or more
					 ** callbacks with smaller arrays of context pointers, which will
					 ** reduce the applications ability to prioritize multiple
					 ** connections. But it is the best that can be done under the
					 ** circumstances.
					 */
					(*(*func(*libc.TLS, uintptr, int32))(unsafe.Pointer(&struct{ uintptr }{xUnlockNotify})))(tls, aArg, nArg)
					nArg = 0
				}
			}
			_sqlite3EndBenignMalloc(tls)
			v3 = nArg
			nArg = nArg + 1
			**(**uintptr)(__ccgo_up(aArg + uintptr(v3)*4)) = (*Tsqlite3)(unsafe.Pointer(p)).FpUnlockArg
			xUnlockNotify = (*Tsqlite3)(unsafe.Pointer(p)).FxUnlockNotify
			(*Tsqlite3)(unsafe.Pointer(p)).FpUnlockConnection = uintptr(0)
			(*Tsqlite3)(unsafe.Pointer(p)).FxUnlockNotify = uintptr(0)
			(*Tsqlite3)(unsafe.Pointer(p)).FpUnlockArg = uintptr(0)
		}
		/* Step 3. */
		if (*Tsqlite3)(unsafe.Pointer(p)).FpBlockingConnection == uintptr(0) && (*Tsqlite3)(unsafe.Pointer(p)).FpUnlockConnection == uintptr(0) {
			/* Remove connection p from the blocked connections list. */
			**(**uintptr)(__ccgo_up(pp)) = (*Tsqlite3)(unsafe.Pointer(p)).FpNextBlocked
			(*Tsqlite3)(unsafe.Pointer(p)).FpNextBlocked = uintptr(0)
		} else {
			pp = p + 572
		}
		goto _1
	_1:
	}
	if nArg != 0 {
		(*(*func(*libc.TLS, uintptr, int32))(unsafe.Pointer(&struct{ uintptr }{xUnlockNotify})))(tls, aArg, nArg)
	}
	Xsqlite3_free(tls, aDyn)
	_leaveMutex(tls) /* Leave STATIC_MAIN mutex */
}

// C documentation
//
//	/*
//	** Generate bytecode that will initialize a Bloom filter that is appropriate
//	** for pLevel.
//	**
//	** If there are inner loops within pLevel that have the WHERE_BLOOMFILTER
//	** flag set, initialize a Bloomfilter for them as well.  Except don't do
//	** this recursive initialization if the SQLITE_BloomPulldown optimization has
//	** been turned off.
//	**
//	** When the Bloom filter is initialized, the WHERE_BLOOMFILTER flag is cleared
//	** from the loop, but the regFilter value is set to a register that implements
//	** the Bloom filter.  When regFilter is positive, the
//	** sqlite3WhereCodeOneLoopStart() will generate code to test the Bloom filter
//	** and skip the subsequence B-Tree seek if the Bloom filter indicates that
//	** no matching rows exist.
//	**
//	** This routine may only be called if it has previously been determined that
//	** the loop would benefit from a Bloom filter, and the WHERE_BLOOMFILTER bit
//	** is set.
//	*/
func _sqlite3ConstructBloomFilter(tls *libc.TLS, pWInfo uintptr, iLevel int32, pLevel uintptr, notReady TBitmask) {
	var addrCont, addrOnce, addrTop, iCur, iSrc, jj, n, r1, r11, v1 int32
	var pExpr, pIdx, pItem, pLoop, pParse, pTab, pTabItem, pTabList, pTerm, pWCEnd, saved_pIdxEpr, saved_pIdxPartExpr, v, v2 uintptr
	var sz Tu64
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = addrCont, addrOnce, addrTop, iCur, iSrc, jj, n, pExpr, pIdx, pItem, pLoop, pParse, pTab, pTabItem, pTabList, pTerm, pWCEnd, r1, r11, saved_pIdxEpr, saved_pIdxPartExpr, sz, v, v1, v2 /* Last WHERE clause term */
	pParse = (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpParse                                                                                                                                                                                                            /* Parsing context */
	v = (*TParse)(unsafe.Pointer(pParse)).FpVdbe                                                                                                                                                                                                                      /* VDBE under construction */
	pLoop = (*TWhereLevel)(unsafe.Pointer(pLevel)).FpWLoop                                                                                                                                                                                                            /* saved copy of Parse.pIdxPartExpr */
	saved_pIdxEpr = (*TParse)(unsafe.Pointer(pParse)).FpIdxEpr
	saved_pIdxPartExpr = (*TParse)(unsafe.Pointer(pParse)).FpIdxPartExpr
	(*TParse)(unsafe.Pointer(pParse)).FpIdxEpr = uintptr(0)
	(*TParse)(unsafe.Pointer(pParse)).FpIdxPartExpr = uintptr(0)
	addrOnce = _sqlite3VdbeAddOp0(tls, v, int32(OP_Once))
	for cond := true; cond; cond = iLevel < libc.Int32FromUint8((*TWhereInfo)(unsafe.Pointer(pWInfo)).FnLevel) {
		_sqlite3WhereExplainBloomFilter(tls, pParse, pWInfo, pLevel)
		addrCont = _sqlite3VdbeMakeLabel(tls, pParse)
		iCur = (*TWhereLevel)(unsafe.Pointer(pLevel)).FiTabCur
		v2 = pParse + 48
		*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1
		v1 = *(*int32)(unsafe.Pointer(v2))
		(*TWhereLevel)(unsafe.Pointer(pLevel)).FregFilter = v1
		/* The Bloom filter is a Blob held in a register.  Initialize it
		 ** to zero-filled blob of at least 80K bits, but maybe more if the
		 ** estimated size of the table is larger.  We could actually
		 ** measure the size of the table at run-time using OP_Count with
		 ** P3==1 and use that value to initialize the blob.  But that makes
		 ** testing complicated.  By basing the blob size on the value in the
		 ** sqlite_stat1 table, testing is much easier.
		 */
		pTabList = (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpTabList
		iSrc = libc.Int32FromUint8((*TWhereLevel)(unsafe.Pointer(pLevel)).FiFrom)
		pItem = pTabList + 8 + uintptr(iSrc)*48
		pTab = (*TSrcItem)(unsafe.Pointer(pItem)).FpSTab
		sz = _sqlite3LogEstToInt(tls, (*TTable)(unsafe.Pointer(pTab)).FnRowLogEst)
		if sz < uint64(10000) {
			sz = uint64(10000)
		} else {
			if sz > uint64(10000000) {
				sz = uint64(10000000)
			}
		}
		_sqlite3VdbeAddOp2(tls, v, int32(OP_Blob), libc.Int32FromUint64(sz), (*TWhereLevel)(unsafe.Pointer(pLevel)).FregFilter)
		addrTop = _sqlite3VdbeAddOp1(tls, v, int32(OP_Rewind), iCur)
		pWCEnd = (*TWhereInfo)(unsafe.Pointer(pWInfo)).FsWC.Fa + uintptr((*TWhereInfo)(unsafe.Pointer(pWInfo)).FsWC.FnTerm)*48
		pTerm = (*TWhereInfo)(unsafe.Pointer(pWInfo)).FsWC.Fa
		for {
			if !(pTerm < pWCEnd) {
				break
			}
			pExpr = (*TWhereTerm)(unsafe.Pointer(pTerm)).FpExpr
			if libc.Int32FromUint16((*TWhereTerm)(unsafe.Pointer(pTerm)).FwtFlags)&int32(TERM_VIRTUAL) == 0 && _sqlite3ExprIsSingleTableConstraint(tls, pExpr, pTabList, iSrc, 0) != 0 {
				_sqlite3ExprIfFalse(tls, pParse, (*TWhereTerm)(unsafe.Pointer(pTerm)).FpExpr, addrCont, int32(SQLITE_JUMPIFNULL))
			}
			goto _3
		_3:
			;
			pTerm += 48
		}
		if (*TWhereLoop)(unsafe.Pointer(pLoop)).FwsFlags&uint32(WHERE_IPK) != 0 {
			r1 = _sqlite3GetTempReg(tls, pParse)
			_sqlite3VdbeAddOp2(tls, v, int32(OP_Rowid), iCur, r1)
			_sqlite3VdbeAddOp4Int(tls, v, int32(OP_FilterAdd), (*TWhereLevel)(unsafe.Pointer(pLevel)).FregFilter, 0, r1, int32(1))
			_sqlite3ReleaseTempReg(tls, pParse, r1)
		} else {
			pIdx = (*(*struct {
				FnEq          Tu16
				FnBtm         Tu16
				FnTop         Tu16
				FnDistinctCol Tu16
				FpIndex       uintptr
				FpOrderBy     uintptr
			})(unsafe.Pointer(pLoop + 24))).FpIndex
			n = libc.Int32FromUint16((*(*struct {
				FnEq          Tu16
				FnBtm         Tu16
				FnTop         Tu16
				FnDistinctCol Tu16
				FpIndex       uintptr
				FpOrderBy     uintptr
			})(unsafe.Pointer(pLoop + 24))).FnEq)
			r11 = _sqlite3GetTempRange(tls, pParse, n)
			jj = 0
			for {
				if !(jj < n) {
					break
				}
				_sqlite3ExprCodeLoadIndexColumn(tls, pParse, pIdx, iCur, jj, r11+jj)
				goto _4
			_4:
				;
				jj = jj + 1
			}
			_sqlite3VdbeAddOp4Int(tls, v, int32(OP_FilterAdd), (*TWhereLevel)(unsafe.Pointer(pLevel)).FregFilter, 0, r11, n)
			_sqlite3ReleaseTempRange(tls, pParse, r11, n)
		}
		_sqlite3VdbeResolveLabel(tls, v, addrCont)
		_sqlite3VdbeAddOp2(tls, v, int32(OP_Next), (*TWhereLevel)(unsafe.Pointer(pLevel)).FiTabCur, addrTop+int32(1))
		_sqlite3VdbeJumpHere(tls, v, addrTop)
		**(**Tu32)(__ccgo_up(pLoop + 40)) &= libc.Uint32FromInt32(^libc.Int32FromInt32(WHERE_BLOOMFILTER))
		if (*Tsqlite3)(unsafe.Pointer((*TParse)(unsafe.Pointer(pParse)).Fdb)).FdbOptFlags&libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_BloomPulldown)) != uint32(0) {
			break
		}
		for {
			iLevel = iLevel + 1
			v1 = iLevel
			if !(v1 < libc.Int32FromUint8((*TWhereInfo)(unsafe.Pointer(pWInfo)).FnLevel)) {
				break
			}
			pLevel = pWInfo + 752 + uintptr(iLevel)*88
			pTabItem = (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpTabList + 8 + uintptr((*TWhereLevel)(unsafe.Pointer(pLevel)).FiFrom)*48
			if libc.Int32FromUint8((*TSrcItem)(unsafe.Pointer(pTabItem)).Ffg.Fjointype)&(libc.Int32FromInt32(JT_LEFT)|libc.Int32FromInt32(JT_LTORJ)) != 0 {
				continue
			}
			pLoop = (*TWhereLevel)(unsafe.Pointer(pLevel)).FpWLoop
			if pLoop == uintptr(0) {
				continue
			}
			if (*TWhereLoop)(unsafe.Pointer(pLoop)).Fprereq&notReady != 0 {
				continue
			}
			if (*TWhereLoop)(unsafe.Pointer(pLoop)).FwsFlags&libc.Uint32FromInt32(libc.Int32FromInt32(WHERE_BLOOMFILTER)|libc.Int32FromInt32(WHERE_COLUMN_IN)) == uint32(WHERE_BLOOMFILTER) {
				/* This is a candidate for bloom-filter pull-down (early evaluation).
				 ** The test that WHERE_COLUMN_IN is omitted is important, as we are
				 ** not able to do early evaluation of bloom filters that make use of
				 ** the IN operator */
				break
			}
		}
	}
	_sqlite3VdbeJumpHere(tls, v, addrOnce)
	(*TParse)(unsafe.Pointer(pParse)).FpIdxEpr = saved_pIdxEpr
	(*TParse)(unsafe.Pointer(pParse)).FpIdxPartExpr = saved_pIdxPartExpr
}

func _sqlite3DbMallocRawNN(tls *libc.TLS, db uintptr, n Tu64) (r uintptr) {
	var pBuf, v1 uintptr
	_, _ = pBuf, v1
	if n > uint64((*Tsqlite3)(unsafe.Pointer(db)).Flookaside.Fsz) {
		if !((*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FbDisable != 0) {
			**(**Tu32)(__ccgo_up(db + 316 + 16 + 1*4)) = **(**Tu32)(__ccgo_up(db + 316 + 16 + 1*4)) + 1
		} else {
			if (*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0 {
				return uintptr(0)
			}
		}
		return _dbMallocRawFinish(tls, db, n)
	}
	if n <= uint64(LOOKASIDE_SMALL) {
		v1 = (*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpSmallFree
		pBuf = v1
		if v1 != uintptr(0) {
			(*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpSmallFree = (*TLookasideSlot)(unsafe.Pointer(pBuf)).FpNext
			**(**Tu32)(__ccgo_up(db + 316 + 16)) = **(**Tu32)(__ccgo_up(db + 316 + 16)) + 1
			return pBuf
		} else {
			v1 = (*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpSmallInit
			pBuf = v1
			if v1 != uintptr(0) {
				(*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpSmallInit = (*TLookasideSlot)(unsafe.Pointer(pBuf)).FpNext
				**(**Tu32)(__ccgo_up(db + 316 + 16)) = **(**Tu32)(__ccgo_up(db + 316 + 16)) + 1
				return pBuf
			}
		}
	}
	v1 = (*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpFree
	pBuf = v1
	if v1 != uintptr(0) {
		(*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpFree = (*TLookasideSlot)(unsafe.Pointer(pBuf)).FpNext
		**(**Tu32)(__ccgo_up(db + 316 + 16)) = **(**Tu32)(__ccgo_up(db + 316 + 16)) + 1
		return pBuf
	} else {
		v1 = (*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpInit
		pBuf = v1
		if v1 != uintptr(0) {
			(*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpInit = (*TLookasideSlot)(unsafe.Pointer(pBuf)).FpNext
			**(**Tu32)(__ccgo_up(db + 316 + 16)) = **(**Tu32)(__ccgo_up(db + 316 + 16)) + 1
			return pBuf
		} else {
			**(**Tu32)(__ccgo_up(db + 316 + 16 + 2*4)) = **(**Tu32)(__ccgo_up(db + 316 + 16 + 2*4)) + 1
		}
	}
	return _dbMallocRawFinish(tls, db, n)
}

// C documentation
//
//	/*
//	** The text between zStart and zEnd represents a phrase within a larger
//	** SQL statement.  Make a copy of this phrase in space obtained form
//	** sqlite3DbMalloc().  Omit leading and trailing whitespace.
//	*/
func _sqlite3DbSpanDup(tls *libc.TLS, db uintptr, zStart uintptr, zEnd uintptr) (r uintptr) {
	var n int32
	_ = n
	for libc.Int32FromUint8(_sqlite3CtypeMap[libc.Uint8FromInt8(**(**int8)(__ccgo_up(zStart)))])&int32(0x01) != 0 {
		zStart = zStart + 1
	}
	n = int32(zEnd) - int32(zStart)
	for libc.Int32FromUint8(_sqlite3CtypeMap[libc.Uint8FromInt8(**(**int8)(__ccgo_up(zStart + uintptr(n-int32(1)))))])&int32(0x01) != 0 {
		n = n - 1
	}
	return _sqlite3DbStrNDup(tls, db, zStart, libc.Uint64FromInt32(n))
}

// C documentation
//
//	/*
//	** If the input token p is quoted, try to adjust the token to remove
//	** the quotes.  This is not always possible:
//	**
//	**     "abc"     ->   abc
//	**     "ab""cd"  ->   (not possible because of the interior "")
//	**
//	** Remove the quotes if possible.  This is a optimization.  The overall
//	** system should still return the correct answer even if this routine
//	** is always a no-op.
//	*/
func _sqlite3DequoteToken(tls *libc.TLS, p uintptr) {
	var i uint32
	_ = i
	if (*TToken)(unsafe.Pointer(p)).Fn < uint32(2) {
		return
	}
	if !(libc.Int32FromUint8(_sqlite3CtypeMap[libc.Uint8FromInt8(**(**int8)(__ccgo_up((*TToken)(unsafe.Pointer(p)).Fz)))])&libc.Int32FromInt32(0x80) != 0) {
		return
	}
	i = uint32(1)
	for {
		if !(i < (*TToken)(unsafe.Pointer(p)).Fn-uint32(1)) {
			break
		}
		if libc.Int32FromUint8(_sqlite3CtypeMap[libc.Uint8FromInt8(**(**int8)(__ccgo_up((*TToken)(unsafe.Pointer(p)).Fz + uintptr(i))))])&int32(0x80) != 0 {
			return
		}
		goto _1
	_1:
		;
		i = i + 1
	}
	**(**uint32)(__ccgo_up(p + 4)) -= uint32(2)
	(*TToken)(unsafe.Pointer(p)).Fz = (*TToken)(unsafe.Pointer(p)).Fz + 1
}

// C documentation
//
//	/*
//	** Mark every prepared statement associated with a database connection
//	** as expired.
//	**
//	** An expired statement means that recompilation of the statement is
//	** recommend.  Statements expire when things happen that make their
//	** programs obsolete.  Removing user-defined functions or collating
//	** sequences, or changing an authorization function are the types of
//	** things that make prepared statements obsolete.
//	**
//	** If iCode is 1, then expiration is advisory.  The statement should
//	** be reprepared before being restarted, but if it is already running
//	** it is allowed to run to completion.
//	**
//	** Internally, this function just sets the Vdbe.expired flag on all
//	** prepared statements.  The flag is set to 1 for an immediate expiration
//	** and set to 2 for an advisory expiration.
//	*/
func _sqlite3ExpirePreparedStatements(tls *libc.TLS, db uintptr, iCode int32) {
	var p uintptr
	_ = p
	p = (*Tsqlite3)(unsafe.Pointer(db)).FpVdbe
	for {
		if !(p != 0) {
			break
		}
		libc.SetBitFieldPtr16Uint32(p+144, libc.Uint32FromInt32(iCode+libc.Int32FromInt32(1)), 0, 0x3)
		goto _1
	_1:
		;
		p = (*TVdbe)(unsafe.Pointer(p)).FpVNext
	}
}

// C documentation
//
//	/*
//	** Return the 'affinity' of the expression pExpr if any.
//	**
//	** If pExpr is a column, a reference to a column via an 'AS' alias,
//	** or a sub-select with a column as the return value, then the
//	** affinity of that column is returned. Otherwise, 0x00 is returned,
//	** indicating no affinity for the expression.
//	**
//	** i.e. the WHERE clause expressions in the following statements all
//	** have an affinity:
//	**
//	** CREATE TABLE t1(a);
//	** SELECT * FROM t1 WHERE a;
//	** SELECT a AS b FROM t1 WHERE b;
//	** SELECT * FROM t1 WHERE (select a from t1);
//	*/
func _sqlite3ExprAffinity(tls *libc.TLS, pExpr uintptr) (r int8) {
	var op int32
	_ = op
	op = libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop)
	for int32(1) != 0 {
		if op == int32(TK_COLUMN) || op == int32(TK_AGG_COLUMN) && (*TExpr)(unsafe.Pointer(pExpr)).Fy.FpTab != uintptr(0) {
			return _sqlite3TableColumnAffinity(tls, (*TExpr)(unsafe.Pointer(pExpr)).Fy.FpTab, int32((*TExpr)(unsafe.Pointer(pExpr)).FiColumn))
		}
		if op == int32(TK_SELECT) {
			return _sqlite3ExprAffinity(tls, (*(*TExprList_item)(unsafe.Pointer((*TSelect)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pExpr + 20)))).FpEList + 8))).FpExpr)
		}
		if op == int32(TK_CAST) {
			return _sqlite3AffinityType(tls, *(*uintptr)(unsafe.Pointer(pExpr + 8)), uintptr(0))
		}
		if op == int32(TK_SELECT_COLUMN) {
			return _sqlite3ExprAffinity(tls, (*(*TExprList_item)(unsafe.Pointer((*TSelect)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer((*TExpr)(unsafe.Pointer(pExpr)).FpLeft + 20)))).FpEList + 8 + uintptr((*TExpr)(unsafe.Pointer(pExpr)).FiColumn)*20))).FpExpr)
		}
		if op == int32(TK_VECTOR) || op == int32(TK_FUNCTION) && int32((*TExpr)(unsafe.Pointer(pExpr)).FaffExpr) == int32(SQLITE_AFF_DEFER) {
			return _sqlite3ExprAffinity(tls, (*(*TExprList_item)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pExpr + 20)) + 8))).FpExpr)
		}
		if (*TExpr)(unsafe.Pointer(pExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_Skip)|libc.Int32FromInt32(EP_IfNullRow)) != uint32(0) {
			pExpr = (*TExpr)(unsafe.Pointer(pExpr)).FpLeft
			op = libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop)
			continue
		}
		if op != int32(TK_REGISTER) {
			break
		}
		op = libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop2)
		if op == int32(TK_REGISTER) {
			break
		}
	}
	return (*TExpr)(unsafe.Pointer(pExpr)).FaffExpr
}

// C documentation
//
//	/*
//	** This routine is the core allocator for Expr nodes.
//	**
//	** Construct a new expression node and return a pointer to it.  Memory
//	** for this node and for the pToken argument is a single allocation
//	** obtained from sqlite3DbMalloc().  The calling function
//	** is responsible for making sure the node eventually gets freed.
//	**
//	** If dequote is true, then the token (if it exists) is dequoted.
//	** If dequote is false, no dequoting is performed.  The deQuote
//	** parameter is ignored if pToken is NULL or if the token does not
//	** appear to be quoted.  If the quotes were of the form "..." (double-quotes)
//	** then the EP_DblQuoted flag is set on the expression node.
//	**
//	** Special case (tag-20240227-a):  If op==TK_INTEGER and pToken points to
//	** a string that can be translated into a 32-bit integer, then the token is
//	** not stored in u.zToken.  Instead, the integer values is written
//	** into u.iValue and the EP_IntValue flag is set. No extra storage
//	** is allocated to hold the integer text and the dequote flag is ignored.
//	** See also tag-20240227-b.
//	*/
func _sqlite3ExprAlloc(tls *libc.TLS, db uintptr, op int32, pToken uintptr, dequote int32) (r uintptr) {
	var nExtra int32
	var pNew uintptr
	var v1 uint32
	_, _, _ = nExtra, pNew, v1
	if pToken != 0 {
		v1 = (*TToken)(unsafe.Pointer(pToken)).Fn + uint32(1)
	} else {
		v1 = uint32(0)
	}
	nExtra = libc.Int32FromUint32(v1)
	pNew = _sqlite3DbMallocRawNN(tls, db, uint64(uint32(52)+libc.Uint32FromInt32(nExtra)))
	if pNew != 0 {
		libc.Xmemset(tls, pNew, 0, uint32(52))
		(*TExpr)(unsafe.Pointer(pNew)).Fop = libc.Uint8FromInt32(op)
		(*TExpr)(unsafe.Pointer(pNew)).FiAgg = int16(-int32(1))
		if nExtra != 0 {
			*(*uintptr)(unsafe.Pointer(pNew + 8)) = pNew + 1*52
			if (*TToken)(unsafe.Pointer(pToken)).Fn != 0 {
				libc.Xmemcpy(tls, *(*uintptr)(unsafe.Pointer(pNew + 8)), (*TToken)(unsafe.Pointer(pToken)).Fz, (*TToken)(unsafe.Pointer(pToken)).Fn)
			}
			**(**int8)(__ccgo_up(*(*uintptr)(unsafe.Pointer(pNew + 8)) + uintptr((*TToken)(unsafe.Pointer(pToken)).Fn))) = 0
			if dequote != 0 && libc.Int32FromUint8(_sqlite3CtypeMap[libc.Uint8FromInt8(**(**int8)(__ccgo_up(*(*uintptr)(unsafe.Pointer(pNew + 8)))))])&int32(0x80) != 0 {
				_sqlite3DequoteExpr(tls, pNew)
			}
		}
		(*TExpr)(unsafe.Pointer(pNew)).FnHeight = int32(1)
	}
	return pNew
}

// C documentation
//
//	/*
//	** Generate code that will compute the value of generated column pCol
//	** and store the result in register regOut
//	*/
func _sqlite3ExprCodeGeneratedColumn(tls *libc.TLS, pParse uintptr, pTab uintptr, pCol uintptr, regOut int32) {
	var iAddr, nErr, p3 int32
	var v uintptr
	_, _, _, _ = iAddr, nErr, p3, v
	v = (*TParse)(unsafe.Pointer(pParse)).FpVdbe
	nErr = (*TParse)(unsafe.Pointer(pParse)).FnErr
	if (*TParse)(unsafe.Pointer(pParse)).FiSelfTab > 0 {
		iAddr = _sqlite3VdbeAddOp3(tls, v, int32(OP_IfNullRow), (*TParse)(unsafe.Pointer(pParse)).FiSelfTab-int32(1), 0, regOut)
	} else {
		iAddr = 0
	}
	_sqlite3ExprCodeCopy(tls, pParse, _sqlite3ColumnExpr(tls, pTab, pCol), regOut)
	if libc.Int32FromUint16((*TColumn)(unsafe.Pointer(pCol)).FcolFlags)&int32(COLFLAG_VIRTUAL) != 0 && (*TTable)(unsafe.Pointer(pTab)).FtabFlags&uint32(TF_Strict) != uint32(0) {
		p3 = int32(2) + (int32(pCol)-int32((*TTable)(unsafe.Pointer(pTab)).FaCol))/12
		_sqlite3VdbeAddOp4(tls, v, int32(OP_TypeCheck), regOut, int32(1), p3, pTab, -int32(5))
	} else {
		if int32((*TColumn)(unsafe.Pointer(pCol)).Faffinity) >= int32(SQLITE_AFF_TEXT) {
			_sqlite3VdbeAddOp4(tls, v, int32(OP_Affinity), regOut, int32(1), 0, pCol+5, int32(1))
		}
	}
	if iAddr != 0 {
		_sqlite3VdbeJumpHere(tls, v, iAddr)
	}
	if (*TParse)(unsafe.Pointer(pParse)).FnErr > nErr {
		(*Tsqlite3)(unsafe.Pointer((*TParse)(unsafe.Pointer(pParse)).Fdb)).FerrByteOffset = -int32(1)
	}
}

// C documentation
//
//	/*
//	** Generate code for an IN expression.
//	**
//	**      x IN (SELECT ...)
//	**      x IN (value, value, ...)
//	**
//	** The left-hand side (LHS) is a scalar or vector expression.  The
//	** right-hand side (RHS) is an array of zero or more scalar values, or a
//	** subquery.  If the RHS is a subquery, the number of result columns must
//	** match the number of columns in the vector on the LHS.  If the RHS is
//	** a list of values, the LHS must be a scalar.
//	**
//	** The IN operator is true if the LHS value is contained within the RHS.
//	** The result is false if the LHS is definitely not in the RHS.  The
//	** result is NULL if the presence of the LHS in the RHS cannot be
//	** determined due to NULLs.
//	**
//	** This routine generates code that jumps to destIfFalse if the LHS is not
//	** contained within the RHS.  If due to NULLs we cannot determine if the LHS
//	** is contained in the RHS then jump to destIfNull.  If the LHS is contained
//	** within the RHS then fall through.
//	**
//	** See the separate in-operator.md documentation file in the canonical
//	** SQLite source tree for additional information.
//	*/
func _sqlite3ExprCodeIN(tls *libc.TLS, pParse uintptr, pExpr uintptr, destIfFalse int32, destIfNull int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var addrTop, addrTruthOp, destNotNull, destStep2, destStep6, eType, i, ii, labelOk, nVector, op, op1, r2, r3, rLhs, rLhsOrig, regCkNull, v3 int32
	var aiMap, p, p1, pColl, pColl1, pLeft, pList, pOp, pRhs, v, zAff, v1 uintptr
	var okConstFactor Tu8
	var _ /* iDummy at bp+4 */ int32
	var _ /* iTab at bp+8 */ int32
	var _ /* rRhsHasNull at bp+0 */ int32
	var _ /* regToFree at bp+12 */ int32
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = addrTop, addrTruthOp, aiMap, destNotNull, destStep2, destStep6, eType, i, ii, labelOk, nVector, okConstFactor, op, op1, p, p1, pColl, pColl1, pLeft, pList, pOp, pRhs, r2, r3, rLhs, rLhsOrig, regCkNull, v, zAff, v1, v3
	**(**int32)(__ccgo_up(bp)) = 0     /* Statement under construction */
	aiMap = uintptr(0)                 /* Map from vector field to index column */
	zAff = uintptr(0)                  /* Where to jump when NULLs seen in step 2 */
	destStep6 = 0                      /* Top of the step-6 loop */
	**(**int32)(__ccgo_up(bp + 8)) = 0 /* Index to use */
	okConstFactor = libc.Uint8FromInt32(int32(Tbft(*(*uint16)(unsafe.Pointer(pParse + 28)) & 0x80 >> 7)))
	pLeft = (*TExpr)(unsafe.Pointer(pExpr)).FpLeft
	if _sqlite3ExprCheckIN(tls, pParse, pExpr) != 0 {
		return
	}
	zAff = _exprINAffinity(tls, pParse, pExpr)
	nVector = _sqlite3ExprVectorSize(tls, (*TExpr)(unsafe.Pointer(pExpr)).FpLeft)
	aiMap = _sqlite3DbMallocZero(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, uint64(libc.Uint32FromInt32(nVector)*uint32(4)))
	if (*Tsqlite3)(unsafe.Pointer((*TParse)(unsafe.Pointer(pParse)).Fdb)).FmallocFailed != 0 {
		goto sqlite3ExprCodeIN_oom_error
	}
	/* Attempt to compute the RHS. After this step, if anything other than
	 ** IN_INDEX_NOOP is returned, the table opened with cursor iTab
	 ** contains the values that make up the RHS. If IN_INDEX_NOOP is returned,
	 ** the RHS has not yet been coded.  */
	v = (*TParse)(unsafe.Pointer(pParse)).FpVdbe
	/* OOM detected prior to this routine */
	if destIfFalse == destIfNull {
		v1 = uintptr(0)
	} else {
		v1 = bp
	}
	eType = _sqlite3FindInIndex(tls, pParse, pExpr, libc.Uint32FromInt32(libc.Int32FromInt32(IN_INDEX_MEMBERSHIP)|libc.Int32FromInt32(IN_INDEX_NOOP_OK)), v1, aiMap, bp+8)
	/* Code the LHS, the <expr> from "<expr> IN (...)". If the LHS is a
	 ** vector, then it is stored in an array of nVector registers starting
	 ** at r1.
	 **
	 ** sqlite3FindInIndex() might have reordered the fields of the LHS vector
	 ** so that the fields are in the same order as an existing index.   The
	 ** aiMap[] array contains a mapping from the original LHS field order to
	 ** the field order that matches the RHS index.
	 **
	 ** Avoid factoring the LHS of the IN(...) expression out of the loop,
	 ** even if it is constant, as OP_Affinity may be used on the register
	 ** by code generated below.  */
	libc.SetBitFieldPtr16Uint32(pParse+28, libc.Uint32FromInt32(0), 7, 0x80)
	rLhs = _exprCodeVector(tls, pParse, pLeft, bp+4)
	libc.SetBitFieldPtr16Uint32(pParse+28, uint32(okConstFactor), 7, 0x80)
	/* If sqlite3FindInIndex() did not find or create an index that is
	 ** suitable for evaluating the IN operator, then evaluate using a
	 ** sequence of comparisons.
	 **
	 ** This is step (1) in the in-operator.md optimized algorithm.
	 */
	if eType == int32(IN_INDEX_NOOP) {
		labelOk = _sqlite3VdbeMakeLabel(tls, pParse)
		regCkNull = 0
		pList = *(*uintptr)(unsafe.Pointer(pExpr + 20))
		pColl = _sqlite3ExprCollSeq(tls, pParse, (*TExpr)(unsafe.Pointer(pExpr)).FpLeft)
		if destIfNull != destIfFalse {
			regCkNull = _sqlite3GetTempReg(tls, pParse)
			_sqlite3VdbeAddOp3(tls, v, int32(OP_BitAnd), rLhs, rLhs, regCkNull)
		}
		ii = 0
		for {
			if !(ii < (*TExprList)(unsafe.Pointer(pList)).FnExpr) {
				break
			}
			r2 = _sqlite3ExprCodeTemp(tls, pParse, (*(*TExprList_item)(unsafe.Pointer(pList + 8 + uintptr(ii)*20))).FpExpr, bp+12)
			if regCkNull != 0 && _sqlite3ExprCanBeNull(tls, (*(*TExprList_item)(unsafe.Pointer(pList + 8 + uintptr(ii)*20))).FpExpr) != 0 {
				_sqlite3VdbeAddOp3(tls, v, int32(OP_BitAnd), regCkNull, r2, regCkNull)
			}
			_sqlite3ReleaseTempReg(tls, pParse, **(**int32)(__ccgo_up(bp + 12)))
			if ii < (*TExprList)(unsafe.Pointer(pList)).FnExpr-int32(1) || destIfNull != destIfFalse {
				if rLhs != r2 {
					v3 = int32(OP_Eq)
				} else {
					v3 = int32(OP_NotNull)
				}
				op = v3
				_sqlite3VdbeAddOp4(tls, v, op, rLhs, labelOk, r2, pColl, -int32(2))
				_sqlite3VdbeChangeP5(tls, v, libc.Uint16FromInt8(**(**int8)(__ccgo_up(zAff))))
			} else {
				if rLhs != r2 {
					v3 = int32(OP_Ne)
				} else {
					v3 = int32(OP_IsNull)
				}
				op1 = v3
				_sqlite3VdbeAddOp4(tls, v, op1, rLhs, destIfFalse, r2, pColl, -int32(2))
				_sqlite3VdbeChangeP5(tls, v, libc.Uint16FromInt32(int32(**(**int8)(__ccgo_up(zAff)))|int32(SQLITE_JUMPIFNULL)))
			}
			goto _2
		_2:
			;
			ii = ii + 1
		}
		if regCkNull != 0 {
			_sqlite3VdbeAddOp2(tls, v, int32(OP_IsNull), regCkNull, destIfNull)
			_sqlite3VdbeGoto(tls, v, destIfFalse)
		}
		_sqlite3VdbeResolveLabel(tls, v, labelOk)
		_sqlite3ReleaseTempReg(tls, pParse, regCkNull)
		goto sqlite3ExprCodeIN_finished
	}
	if eType != int32(IN_INDEX_ROWID) {
		/* If this IN operator will use an index, then the order of columns in the
		 ** vector might be different from the order in the index.  In that case,
		 ** we need to reorder the LHS values to be in index order.  Run Affinity
		 ** before reordering the columns, so that the affinity is correct.
		 */
		_sqlite3VdbeAddOp4(tls, v, int32(OP_Affinity), rLhs, nVector, 0, zAff, nVector)
		i = 0
		for {
			if !(i < nVector && **(**int32)(__ccgo_up(aiMap + uintptr(i)*4)) == i) {
				break
			}
			goto _5
		_5:
			;
			i = i + 1
		} /* Are LHS fields reordered? */
		if i != nVector {
			/* Need to reorder the LHS fields according to aiMap */
			rLhsOrig = rLhs
			rLhs = _sqlite3GetTempRange(tls, pParse, nVector)
			i = 0
			for {
				if !(i < nVector) {
					break
				}
				_sqlite3VdbeAddOp3(tls, v, int32(OP_Copy), rLhsOrig+i, rLhs+**(**int32)(__ccgo_up(aiMap + uintptr(i)*4)), 0)
				goto _6
			_6:
				;
				i = i + 1
			}
			_sqlite3ReleaseTempReg(tls, pParse, rLhsOrig)
		}
	}
	/* Step 2: Check to see if the LHS contains any NULL columns.  If the
	 ** LHS does contain NULLs then the result must be either FALSE or NULL.
	 ** We will then skip the binary search of the RHS.
	 */
	if destIfNull == destIfFalse {
		destStep2 = destIfFalse
	} else {
		v3 = _sqlite3VdbeMakeLabel(tls, pParse)
		destStep6 = v3
		destStep2 = v3
	}
	i = 0
	for {
		if !(i < nVector) {
			break
		}
		p = _sqlite3VectorFieldSubexpr(tls, (*TExpr)(unsafe.Pointer(pExpr)).FpLeft, i)
		if (*TParse)(unsafe.Pointer(pParse)).FnErr != 0 {
			goto sqlite3ExprCodeIN_oom_error
		}
		if _sqlite3ExprCanBeNull(tls, p) != 0 {
			_sqlite3VdbeAddOp2(tls, v, int32(OP_IsNull), rLhs+i, destStep2)
		}
		goto _8
	_8:
		;
		i = i + 1
	}
	/* Step 3.  The LHS is now known to be non-NULL.  Do the binary search
	 ** of the RHS using the LHS as a probe.  If found, the result is
	 ** true.
	 */
	if eType == int32(IN_INDEX_ROWID) {
		/* In this case, the RHS is the ROWID of table b-tree and so we also
		 ** know that the RHS is non-NULL.  Hence, we combine steps 3 and 4
		 ** into a single opcode. */
		_sqlite3VdbeAddOp3(tls, v, int32(OP_SeekRowid), **(**int32)(__ccgo_up(bp + 8)), destIfFalse, rLhs)
		addrTruthOp = _sqlite3VdbeAddOp0(tls, v, int32(OP_Goto)) /* Return True */
	} else {
		if destIfFalse == destIfNull {
			/* Combine Step 3 and Step 5 into a single opcode */
			if (*TExpr)(unsafe.Pointer(pExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_Subrtn)) != uint32(0) {
				pOp = _sqlite3VdbeGetOp(tls, v, (*(*struct {
					FiAddr     int32
					FregReturn int32
				})(unsafe.Pointer(pExpr + 44))).FiAddr)
				if (*TVdbeOp)(unsafe.Pointer(pOp)).Fp3 > 0 { /* tag-202407032019 */
					_sqlite3VdbeAddOp4Int(tls, v, int32(OP_Filter), (*TVdbeOp)(unsafe.Pointer(pOp)).Fp3, destIfFalse, rLhs, nVector)
				}
			}
			_sqlite3VdbeAddOp4Int(tls, v, int32(OP_NotFound), **(**int32)(__ccgo_up(bp + 8)), destIfFalse, rLhs, nVector)
			goto sqlite3ExprCodeIN_finished
		}
		/* Ordinary Step 3, for the case where FALSE and NULL are distinct */
		addrTruthOp = _sqlite3VdbeAddOp4Int(tls, v, int32(OP_Found), **(**int32)(__ccgo_up(bp + 8)), 0, rLhs, nVector)
	}
	/* Step 4.  If the RHS is known to be non-NULL and we did not find
	 ** an match on the search above, then the result must be FALSE.
	 */
	if **(**int32)(__ccgo_up(bp)) != 0 && nVector == int32(1) {
		_sqlite3VdbeAddOp2(tls, v, int32(OP_NotNull), **(**int32)(__ccgo_up(bp)), destIfFalse)
	}
	/* Step 5.  If we do not care about the difference between NULL and
	 ** FALSE, then just return false.
	 */
	if destIfFalse == destIfNull {
		_sqlite3VdbeGoto(tls, v, destIfFalse)
	}
	/* Step 6: Loop through rows of the RHS.  Compare each row to the LHS.
	 ** If any comparison is NULL, then the result is NULL.  If all
	 ** comparisons are FALSE then the final result is FALSE.
	 **
	 ** For a scalar LHS, it is sufficient to check just the first row
	 ** of the RHS.
	 */
	if destStep6 != 0 {
		_sqlite3VdbeResolveLabel(tls, v, destStep6)
	}
	addrTop = _sqlite3VdbeAddOp2(tls, v, int32(OP_Rewind), **(**int32)(__ccgo_up(bp + 8)), destIfFalse)
	if nVector > int32(1) {
		destNotNull = _sqlite3VdbeMakeLabel(tls, pParse)
	} else {
		/* For nVector==1, combine steps 6 and 7 by immediately returning
		 ** FALSE if the first comparison is not NULL */
		destNotNull = destIfFalse
	}
	i = 0
	for {
		if !(i < nVector) {
			break
		}
		r3 = _sqlite3GetTempReg(tls, pParse)
		p1 = _sqlite3VectorFieldSubexpr(tls, pLeft, i)
		if (*TExpr)(unsafe.Pointer(pExpr)).Fflags&uint32(EP_xIsSelect) != uint32(0) {
			pRhs = (*(*TExprList_item)(unsafe.Pointer((*TSelect)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pExpr + 20)))).FpEList + 8 + uintptr(i)*20))).FpExpr
			pColl1 = _sqlite3BinaryCompareCollSeq(tls, pParse, p1, pRhs)
		} else {
			/* If the RHS of the IN(...) expression are scalar expressions, do
			 ** not consider their collation sequences. The documentation says
			 ** "The collating sequence used for expressions of the form "x IN (y, z,
			 ** ...)" is the collating sequence of x.".  */
			pColl1 = _sqlite3ExprCollSeq(tls, pParse, p1)
		}
		_sqlite3VdbeAddOp3(tls, v, int32(OP_Column), **(**int32)(__ccgo_up(bp + 8)), i, r3)
		_sqlite3VdbeAddOp4(tls, v, int32(OP_Ne), rLhs+i, destNotNull, r3, pColl1, -int32(2))
		_sqlite3ReleaseTempReg(tls, pParse, r3)
		goto _9
	_9:
		;
		i = i + 1
	}
	_sqlite3VdbeAddOp2(tls, v, int32(OP_Goto), 0, destIfNull)
	if nVector > int32(1) {
		_sqlite3VdbeResolveLabel(tls, v, destNotNull)
		_sqlite3VdbeAddOp2(tls, v, int32(OP_Next), **(**int32)(__ccgo_up(bp + 8)), addrTop+int32(1))
		/* Step 7:  If we reach this point, we know that the result must
		 ** be false. */
		_sqlite3VdbeAddOp2(tls, v, int32(OP_Goto), 0, destIfFalse)
	}
	/* Jumps here in order to return true. */
	_sqlite3VdbeJumpHere(tls, v, addrTruthOp)
	goto sqlite3ExprCodeIN_finished
sqlite3ExprCodeIN_finished:
	;
	goto sqlite3ExprCodeIN_oom_error
sqlite3ExprCodeIN_oom_error:
	;
	_sqlite3DbFree(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, aiMap)
	_sqlite3DbFree(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, zAff)
}

// C documentation
//
//	/*
//	** Return the collation sequence for the expression pExpr. If
//	** there is no defined collating sequence, return NULL.
//	**
//	** See also: sqlite3ExprNNCollSeq()
//	**
//	** The sqlite3ExprNNCollSeq() works the same exact that it returns the
//	** default collation if pExpr has no defined collation.
//	**
//	** The collating sequence might be determined by a COLLATE operator
//	** or by the presence of a column with a defined collating sequence.
//	** COLLATE operators take first precedence.  Left operands take
//	** precedence over right operands.
//	*/
func _sqlite3ExprCollSeq(tls *libc.TLS, pParse uintptr, pExpr uintptr) (r uintptr) {
	var db, p, pColl, pNext, zColl uintptr
	var i, j, op, v1 int32
	_, _, _, _, _, _, _, _, _ = db, i, j, op, p, pColl, pNext, zColl, v1
	db = (*TParse)(unsafe.Pointer(pParse)).Fdb
	pColl = uintptr(0)
	p = pExpr
	for p != 0 {
		op = libc.Int32FromUint8((*TExpr)(unsafe.Pointer(p)).Fop)
		if op == int32(TK_REGISTER) {
			op = libc.Int32FromUint8((*TExpr)(unsafe.Pointer(p)).Fop2)
		}
		if op == int32(TK_AGG_COLUMN) && (*TExpr)(unsafe.Pointer(p)).Fy.FpTab != uintptr(0) || op == int32(TK_COLUMN) || op == int32(TK_TRIGGER) {
			v1 = int32((*TExpr)(unsafe.Pointer(p)).FiColumn)
			j = v1
			if v1 >= 0 {
				zColl = _sqlite3ColumnColl(tls, (*TTable)(unsafe.Pointer((*TExpr)(unsafe.Pointer(p)).Fy.FpTab)).FaCol+uintptr(j)*12)
				pColl = _sqlite3FindCollSeq(tls, db, (*Tsqlite3)(unsafe.Pointer(db)).Fenc, zColl, 0)
			}
			break
		}
		if op == int32(TK_CAST) || op == int32(TK_UPLUS) {
			p = (*TExpr)(unsafe.Pointer(p)).FpLeft
			continue
		}
		if op == int32(TK_VECTOR) || op == int32(TK_FUNCTION) && int32((*TExpr)(unsafe.Pointer(p)).FaffExpr) == int32(SQLITE_AFF_DEFER) {
			p = (*(*TExprList_item)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(p + 20)) + 8))).FpExpr
			continue
		}
		if op == int32(TK_COLLATE) {
			pColl = _sqlite3GetCollSeq(tls, pParse, (*Tsqlite3)(unsafe.Pointer(db)).Fenc, uintptr(0), *(*uintptr)(unsafe.Pointer(p + 8)))
			break
		}
		if (*TExpr)(unsafe.Pointer(p)).Fflags&uint32(EP_Collate) != 0 {
			if (*TExpr)(unsafe.Pointer(p)).FpLeft != 0 && (*TExpr)(unsafe.Pointer((*TExpr)(unsafe.Pointer(p)).FpLeft)).Fflags&uint32(EP_Collate) != uint32(0) {
				p = (*TExpr)(unsafe.Pointer(p)).FpLeft
			} else {
				pNext = (*TExpr)(unsafe.Pointer(p)).FpRight
				/* The Expr.x union is never used at the same time as Expr.pRight */
				if (*TExpr)(unsafe.Pointer(p)).Fflags&uint32(EP_xIsSelect) == uint32(0) && *(*uintptr)(unsafe.Pointer(p + 20)) != uintptr(0) && !((*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0) {
					i = 0
					for {
						if !(i < (*TExprList)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(p + 20)))).FnExpr) {
							break
						}
						if (*TExpr)(unsafe.Pointer((*(*TExprList_item)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(p + 20)) + 8 + uintptr(i)*20))).FpExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_Collate)) != uint32(0) {
							pNext = (*(*TExprList_item)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(p + 20)) + 8 + uintptr(i)*20))).FpExpr
							break
						}
						goto _2
					_2:
						;
						i = i + 1
					}
				}
				p = pNext
			}
		} else {
			break
		}
	}
	if _sqlite3CheckCollSeq(tls, pParse, pColl) != 0 {
		pColl = uintptr(0)
	}
	return pColl
}

// C documentation
//
//	/*
//	** Make a guess at all the possible datatypes of the result that could
//	** be returned by an expression.  Return a bitmask indicating the answer:
//	**
//	**     0x01         Numeric
//	**     0x02         Text
//	**     0x04         Blob
//	**
//	** If the expression must return NULL, then 0x00 is returned.
//	*/
func _sqlite3ExprDataType(tls *libc.TLS, pExpr uintptr) (r int32) {
	var aff, ii, res int32
	var pList uintptr
	_, _, _, _ = aff, ii, pList, res
	for pExpr != 0 {
		switch libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) {
		case int32(TK_COLLATE):
			fallthrough
		case int32(TK_IF_NULL_ROW):
			fallthrough
		case int32(TK_UPLUS):
			pExpr = (*TExpr)(unsafe.Pointer(pExpr)).FpLeft
		case int32(TK_NULL):
			pExpr = uintptr(0)
		case int32(TK_STRING):
			return int32(0x02)
		case int32(TK_BLOB):
			return int32(0x04)
		case int32(TK_CONCAT):
			return int32(0x06)
		case int32(TK_VARIABLE):
			fallthrough
		case int32(TK_AGG_FUNCTION):
			fallthrough
		case int32(TK_FUNCTION):
			return int32(0x07)
		case int32(TK_COLUMN):
			fallthrough
		case int32(TK_AGG_COLUMN):
			fallthrough
		case int32(TK_SELECT):
			fallthrough
		case int32(TK_CAST):
			fallthrough
		case int32(TK_SELECT_COLUMN):
			fallthrough
		case int32(TK_VECTOR):
			aff = int32(_sqlite3ExprAffinity(tls, pExpr))
			if aff >= int32(SQLITE_AFF_NUMERIC) {
				return int32(0x05)
			}
			if aff == int32(SQLITE_AFF_TEXT) {
				return int32(0x06)
			}
			return int32(0x07)
		case int32(TK_CASE):
			res = 0
			pList = *(*uintptr)(unsafe.Pointer(pExpr + 20))
			ii = int32(1)
			for {
				if !(ii < (*TExprList)(unsafe.Pointer(pList)).FnExpr) {
					break
				}
				res = res | _sqlite3ExprDataType(tls, (*(*TExprList_item)(unsafe.Pointer(pList + 8 + uintptr(ii)*20))).FpExpr)
				goto _1
			_1:
				;
				ii = ii + int32(2)
			}
			if (*TExprList)(unsafe.Pointer(pList)).FnExpr%int32(2) != 0 {
				res = res | _sqlite3ExprDataType(tls, (*(*TExprList_item)(unsafe.Pointer(pList + 8 + uintptr((*TExprList)(unsafe.Pointer(pList)).FnExpr-int32(1))*20))).FpExpr)
			}
			return res
		default:
			return int32(0x01)
		} /* End of switch(op) */
	} /* End of while(pExpr) */
	return 0x00
}

// C documentation
//
//	/*
//	** Return true if the expression is one of the following:
//	**
//	**    CASE WHEN x THEN y END
//	**    CASE WHEN x THEN y ELSE NULL END
//	**    CASE WHEN x THEN y ELSE false END
//	**    iif(x,y)
//	**    iif(x,y,NULL)
//	**    iif(x,y,false)
//	*/
func _sqlite3ExprIsIIF(tls *libc.TLS, db uintptr, pExpr uintptr) (r int32) {
	var pDef, pList, z uintptr
	_, _, _ = pDef, pList, z
	if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) == int32(TK_FUNCTION) {
		z = *(*uintptr)(unsafe.Pointer(pExpr + 8))
		if int32(**(**int8)(__ccgo_up(z))) != int32('i') && int32(**(**int8)(__ccgo_up(z))) != int32('I') {
			return 0
		}
		if *(*uintptr)(unsafe.Pointer(pExpr + 20)) == uintptr(0) {
			return 0
		}
		pDef = _sqlite3FindFunction(tls, db, z, (*TExprList)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pExpr + 20)))).FnExpr, (*Tsqlite3)(unsafe.Pointer(db)).Fenc, uint8(0))
		if pDef == uintptr(0) {
			return 0
		}
		if (*TFuncDef)(unsafe.Pointer(pDef)).FfuncFlags&uint32(SQLITE_FUNC_INLINE) == uint32(0) {
			return 0
		}
		if int32((*TFuncDef)(unsafe.Pointer(pDef)).FpUserData) != int32(INLINEFUNC_iif) {
			return 0
		}
	} else {
		if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) == int32(TK_CASE) {
			if (*TExpr)(unsafe.Pointer(pExpr)).FpLeft != uintptr(0) {
				return 0
			}
		} else {
			return 0
		}
	}
	pList = *(*uintptr)(unsafe.Pointer(pExpr + 20))
	if (*TExprList)(unsafe.Pointer(pList)).FnExpr == int32(2) {
		return int32(1)
	}
	if (*TExprList)(unsafe.Pointer(pList)).FnExpr == int32(3) && _sqlite3ExprIsNotTrue(tls, (*(*TExprList_item)(unsafe.Pointer(pList + 8 + 2*20))).FpExpr) != 0 {
		return int32(1)
	}
	return 0
}

// C documentation
//
//	/*
//	** Locate a user function given a name, a number of arguments and a flag
//	** indicating whether the function prefers UTF-16 over UTF-8.  Return a
//	** pointer to the FuncDef structure that defines that function, or return
//	** NULL if the function does not exist.
//	**
//	** If the createFlag argument is true, then a new (blank) FuncDef
//	** structure is created and liked into the "db" structure if a
//	** no matching function previously existed.
//	**
//	** If nArg is -2, then the first valid function found is returned.  A
//	** function is valid if xSFunc is non-zero.  The nArg==(-2)
//	** case is used to see if zName is a valid function name for some number
//	** of arguments.  If nArg is -2, then createFlag must be 0.
//	**
//	** If createFlag is false, then a function with the required name and
//	** number of arguments may be returned even if the eTextRep flag does not
//	** match that requested.
//	*/
func _sqlite3FindFunction(tls *libc.TLS, db uintptr, zName uintptr, nArg int32, enc Tu8, createFlag Tu8) (r uintptr) {
	var bestScore, h, nName, score, score1 int32
	var p, pBest, pOther, z, v1 uintptr
	var v2 bool
	_, _, _, _, _, _, _, _, _, _, _ = bestScore, h, nName, p, pBest, pOther, score, score1, z, v1, v2 /* Iterator variable */
	pBest = uintptr(0)                                                                                /* Best match found so far */
	bestScore = 0                                                                                     /* Length of the name */
	nName = _sqlite3Strlen30(tls, zName)
	/* First search for a match amongst the application-defined functions.
	 */
	p = _sqlite3HashFind(tls, db+428, zName)
	for p != 0 {
		score = _matchQuality(tls, p, nArg, enc)
		if score > bestScore {
			pBest = p
			bestScore = score
		}
		p = (*TFuncDef)(unsafe.Pointer(p)).FpNext
	}
	/* If no match is found, search the built-in functions.
	 **
	 ** If the DBFLAG_PreferBuiltin flag is set, then search the built-in
	 ** functions even if a prior app-defined function was found.  And give
	 ** priority to built-in functions.
	 **
	 ** Except, if createFlag is true, that means that we are trying to
	 ** install a new function.  Whatever FuncDef structure is returned it will
	 ** have fields overwritten with new information appropriate for the
	 ** new function.  But the FuncDefs for built-in functions are read-only.
	 ** So we must not search for built-ins when creating a new function.
	 */
	if !(createFlag != 0) && (pBest == uintptr(0) || (*Tsqlite3)(unsafe.Pointer(db)).FmDbFlags&uint32(DBFLAG_PreferBuiltin) != uint32(0)) {
		bestScore = 0
		h = (libc.Int32FromUint8(_sqlite3UpperToLower[libc.Uint8FromInt8(**(**int8)(__ccgo_up(zName)))]) + nName) % int32(SQLITE_FUNC_HASH_SZ)
		p = _sqlite3FunctionSearch(tls, h, zName)
		for p != 0 {
			score1 = _matchQuality(tls, p, nArg, enc)
			if score1 > bestScore {
				pBest = p
				bestScore = score1
			}
			p = (*TFuncDef)(unsafe.Pointer(p)).FpNext
		}
	}
	/* If the createFlag parameter is true and the search did not reveal an
	 ** exact match for the name, number of arguments and encoding, then add a
	 ** new entry to the hash table and return it.
	 */
	if v2 = createFlag != 0 && bestScore < int32(FUNC_PERFECT_MATCH); v2 {
		v1 = _sqlite3DbMallocZero(tls, db, uint64(uint32(40)+libc.Uint32FromInt32(nName)+uint32(1)))
		pBest = v1
	}
	if v2 && v1 != uintptr(0) {
		(*TFuncDef)(unsafe.Pointer(pBest)).FzName = pBest + 1*40
		(*TFuncDef)(unsafe.Pointer(pBest)).FnArg = libc.Int16FromUint16(libc.Uint16FromInt32(nArg))
		(*TFuncDef)(unsafe.Pointer(pBest)).FfuncFlags = uint32(enc)
		libc.Xmemcpy(tls, pBest+1*40, zName, libc.Uint32FromInt32(nName+int32(1)))
		z = (*TFuncDef)(unsafe.Pointer(pBest)).FzName
		for {
			if !(**(**Tu8)(__ccgo_up(z)) != 0) {
				break
			}
			**(**Tu8)(__ccgo_up(z)) = _sqlite3UpperToLower[**(**Tu8)(__ccgo_up(z))]
			goto _3
		_3:
			;
			z = z + 1
		}
		pOther = _sqlite3HashInsert(tls, db+428, (*TFuncDef)(unsafe.Pointer(pBest)).FzName, pBest)
		if pOther == pBest {
			_sqlite3DbFree(tls, db, pBest)
			_sqlite3OomFault(tls, db)
			return uintptr(0)
		} else {
			(*TFuncDef)(unsafe.Pointer(pBest)).FpNext = pOther
		}
	}
	if pBest != 0 && ((*TFuncDef)(unsafe.Pointer(pBest)).FxSFunc != 0 || createFlag != 0) {
		return pBest
	}
	return uintptr(0)
}

// C documentation
//
//	/*
//	** Parameter zIn contains a rank() function specification. The format of
//	** this is:
//	**
//	**   + Bareword (function name)
//	**   + Open parenthesis - "("
//	**   + Zero or more SQL literals in a comma separated list
//	**   + Close parenthesis - ")"
//	*/
func _sqlite3Fts5ConfigParseRank(tls *libc.TLS, zIn uintptr, pzRank uintptr, pzRankArgs uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var p, pArgs, pRank, zRank, zRankArgs uintptr
	var _ /* rc at bp+0 */ int32
	_, _, _, _, _ = p, pArgs, pRank, zRank, zRankArgs
	p = zIn
	zRank = uintptr(0)
	zRankArgs = uintptr(0)
	**(**int32)(__ccgo_up(bp)) = SQLITE_OK
	**(**uintptr)(__ccgo_up(pzRank)) = uintptr(0)
	**(**uintptr)(__ccgo_up(pzRankArgs)) = uintptr(0)
	if p == uintptr(0) {
		**(**int32)(__ccgo_up(bp)) = int32(SQLITE_ERROR)
	} else {
		p = _fts5ConfigSkipWhitespace(tls, p)
		pRank = p
		p = _fts5ConfigSkipBareword(tls, p)
		if p != 0 {
			zRank = _sqlite3Fts5MallocZero(tls, bp, int64(int32(uintptr(1)+p)-int32(pRank)))
			if zRank != 0 {
				libc.Xmemcpy(tls, zRank, pRank, libc.Uint32FromInt32(int32(p)-int32(pRank)))
			}
		} else {
			**(**int32)(__ccgo_up(bp)) = int32(SQLITE_ERROR)
		}
		if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
			p = _fts5ConfigSkipWhitespace(tls, p)
			if int32(**(**int8)(__ccgo_up(p))) != int32('(') {
				**(**int32)(__ccgo_up(bp)) = int32(SQLITE_ERROR)
			}
			p = p + 1
		}
		if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
			p = _fts5ConfigSkipWhitespace(tls, p)
			pArgs = p
			if int32(**(**int8)(__ccgo_up(p))) != int32(')') {
				p = _fts5ConfigSkipArgs(tls, p)
				if p == uintptr(0) {
					**(**int32)(__ccgo_up(bp)) = int32(SQLITE_ERROR)
				} else {
					zRankArgs = _sqlite3Fts5MallocZero(tls, bp, int64(int32(uintptr(1)+p)-int32(pArgs)))
					if zRankArgs != 0 {
						libc.Xmemcpy(tls, zRankArgs, pArgs, libc.Uint32FromInt32(int32(p)-int32(pArgs)))
					}
				}
			}
		}
	}
	if **(**int32)(__ccgo_up(bp)) != SQLITE_OK {
		Xsqlite3_free(tls, zRank)
	} else {
		**(**uintptr)(__ccgo_up(pzRank)) = zRank
		**(**uintptr)(__ccgo_up(pzRankArgs)) = zRankArgs
	}
	return **(**int32)(__ccgo_up(bp))
}

// C documentation
//
//	/*
//	** Create a new FTS5 expression by cloning phrase iPhrase of the
//	** expression passed as the second argument.
//	*/
func _sqlite3Fts5ExprClonePhrase(tls *libc.TLS, pExpr uintptr, iPhrase int32, ppNew uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var i, tflags int32
	var nByte Tsqlite3_int64
	var p, pColset, pColsetOrig, pNew, pOrig uintptr
	var _ /* rc at bp+0 */ int32
	var _ /* sCtx at bp+4 */ TTokenCtx
	_, _, _, _, _, _, _, _ = i, nByte, p, pColset, pColsetOrig, pNew, pOrig, tflags
	**(**int32)(__ccgo_up(bp)) = SQLITE_OK           /* Return code */
	pOrig = uintptr(0)                               /* The phrase extracted from pExpr */
	pNew = uintptr(0)                                /* Expression to return via *ppNew */
	**(**TTokenCtx)(__ccgo_up(bp + 4)) = TTokenCtx{} /* Context object for fts5ParseTokenize */
	if !(pExpr != 0) || iPhrase < 0 || iPhrase >= (*TFts5Expr)(unsafe.Pointer(pExpr)).FnPhrase {
		**(**int32)(__ccgo_up(bp)) = int32(SQLITE_RANGE)
	} else {
		pOrig = **(**uintptr)(__ccgo_up((*TFts5Expr)(unsafe.Pointer(pExpr)).FapExprPhrase + uintptr(iPhrase)*4))
		pNew = _sqlite3Fts5MallocZero(tls, bp, int64(24))
	}
	if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
		(*TFts5Expr)(unsafe.Pointer(pNew)).FapExprPhrase = _sqlite3Fts5MallocZero(tls, bp, int64(4))
	}
	if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
		(*TFts5Expr)(unsafe.Pointer(pNew)).FpRoot = _sqlite3Fts5MallocZero(tls, bp, libc.Int64FromUint32(uint32(libc.UintptrFromInt32(0)+36)+libc.Uint32FromInt32(libc.Int32FromInt32(1))*libc.Uint32FromInt64(4)))
	}
	if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
		(*TFts5ExprNode)(unsafe.Pointer((*TFts5Expr)(unsafe.Pointer(pNew)).FpRoot)).FpNear = _sqlite3Fts5MallocZero(tls, bp, libc.Int64FromUint32(uint32(libc.UintptrFromInt32(0)+12)+libc.Uint32FromInt32(libc.Int32FromInt32(2))*libc.Uint32FromInt64(4)))
	}
	if **(**int32)(__ccgo_up(bp)) == SQLITE_OK && pOrig != uintptr(0) {
		pColsetOrig = (*TFts5ExprNearset)(unsafe.Pointer((*TFts5ExprNode)(unsafe.Pointer((*TFts5ExprPhrase)(unsafe.Pointer(pOrig)).FpNode)).FpNear)).FpColset
		if pColsetOrig != 0 {
			nByte = libc.Int64FromUint32(libc.Uint32FromInt64(8) * libc.Uint32FromInt32(((*TFts5Colset)(unsafe.Pointer(pColsetOrig)).FnCol+libc.Int32FromInt32(2))/libc.Int32FromInt32(2)))
			pColset = _sqlite3Fts5MallocZero(tls, bp, nByte)
			if pColset != 0 {
				libc.Xmemcpy(tls, pColset, pColsetOrig, libc.Uint32FromInt64(nByte))
			}
			(*TFts5ExprNearset)(unsafe.Pointer((*TFts5ExprNode)(unsafe.Pointer((*TFts5Expr)(unsafe.Pointer(pNew)).FpRoot)).FpNear)).FpColset = pColset
		}
	}
	if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
		if (*TFts5ExprPhrase)(unsafe.Pointer(pOrig)).FnTerm != 0 { /* Used to iterate through phrase terms */
			(**(**TTokenCtx)(__ccgo_up(bp + 4))).FpConfig = (*TFts5Expr)(unsafe.Pointer(pExpr)).FpConfig
			i = 0
			for {
				if !(**(**int32)(__ccgo_up(bp)) == SQLITE_OK && i < (*TFts5ExprPhrase)(unsafe.Pointer(pOrig)).FnTerm) {
					break
				}
				tflags = 0
				p = pOrig + 20 + uintptr(i)*24
				for {
					if !(p != 0 && **(**int32)(__ccgo_up(bp)) == SQLITE_OK) {
						break
					}
					**(**int32)(__ccgo_up(bp)) = _fts5ParseTokenize(tls, bp+4, tflags, (*TFts5ExprTerm)(unsafe.Pointer(p)).FpTerm, (*TFts5ExprTerm)(unsafe.Pointer(p)).FnFullTerm, 0, 0)
					tflags = int32(FTS5_TOKEN_COLOCATED)
					goto _2
				_2:
					;
					p = (*TFts5ExprTerm)(unsafe.Pointer(p)).FpSynonym
				}
				if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
					(*(*TFts5ExprTerm)(unsafe.Pointer((**(**TTokenCtx)(__ccgo_up(bp + 4))).FpPhrase + 20 + uintptr(i)*24))).FbPrefix = (*(*TFts5ExprTerm)(unsafe.Pointer(pOrig + 20 + uintptr(i)*24))).FbPrefix
					(*(*TFts5ExprTerm)(unsafe.Pointer((**(**TTokenCtx)(__ccgo_up(bp + 4))).FpPhrase + 20 + uintptr(i)*24))).FbFirst = (*(*TFts5ExprTerm)(unsafe.Pointer(pOrig + 20 + uintptr(i)*24))).FbFirst
				}
				goto _1
			_1:
				;
				i = i + 1
			}
		} else {
			/* This happens when parsing a token or quoted phrase that contains
			 ** no token characters at all. (e.g ... MATCH '""'). */
			(**(**TTokenCtx)(__ccgo_up(bp + 4))).FpPhrase = _sqlite3Fts5MallocZero(tls, bp, libc.Int64FromUint32(uint32(libc.UintptrFromInt32(0)+20)+libc.Uint32FromInt32(libc.Int32FromInt32(1))*libc.Uint32FromInt64(24)))
		}
	}
	if **(**int32)(__ccgo_up(bp)) == SQLITE_OK && (**(**TTokenCtx)(__ccgo_up(bp + 4))).FpPhrase != 0 {
		/* All the allocations succeeded. Put the expression object together. */
		(*TFts5Expr)(unsafe.Pointer(pNew)).FpIndex = (*TFts5Expr)(unsafe.Pointer(pExpr)).FpIndex
		(*TFts5Expr)(unsafe.Pointer(pNew)).FpConfig = (*TFts5Expr)(unsafe.Pointer(pExpr)).FpConfig
		(*TFts5Expr)(unsafe.Pointer(pNew)).FnPhrase = int32(1)
		**(**uintptr)(__ccgo_up((*TFts5Expr)(unsafe.Pointer(pNew)).FapExprPhrase)) = (**(**TTokenCtx)(__ccgo_up(bp + 4))).FpPhrase
		*(*uintptr)(unsafe.Pointer((*TFts5ExprNode)(unsafe.Pointer((*TFts5Expr)(unsafe.Pointer(pNew)).FpRoot)).FpNear + 12)) = (**(**TTokenCtx)(__ccgo_up(bp + 4))).FpPhrase
		(*TFts5ExprNearset)(unsafe.Pointer((*TFts5ExprNode)(unsafe.Pointer((*TFts5Expr)(unsafe.Pointer(pNew)).FpRoot)).FpNear)).FnPhrase = int32(1)
		(*TFts5ExprPhrase)(unsafe.Pointer((**(**TTokenCtx)(__ccgo_up(bp + 4))).FpPhrase)).FpNode = (*TFts5Expr)(unsafe.Pointer(pNew)).FpRoot
		if (*TFts5ExprPhrase)(unsafe.Pointer(pOrig)).FnTerm == int32(1) && (*(*TFts5ExprTerm)(unsafe.Pointer(pOrig + 20))).FpSynonym == uintptr(0) && libc.Int32FromUint8((*(*TFts5ExprTerm)(unsafe.Pointer(pOrig + 20))).FbFirst) == 0 {
			(*TFts5ExprNode)(unsafe.Pointer((*TFts5Expr)(unsafe.Pointer(pNew)).FpRoot)).FeType = int32(FTS5_TERM)
			(*TFts5ExprNode)(unsafe.Pointer((*TFts5Expr)(unsafe.Pointer(pNew)).FpRoot)).FxNext = __ccgo_fp(_fts5ExprNodeNext_TERM)
		} else {
			(*TFts5ExprNode)(unsafe.Pointer((*TFts5Expr)(unsafe.Pointer(pNew)).FpRoot)).FeType = int32(FTS5_STRING)
			(*TFts5ExprNode)(unsafe.Pointer((*TFts5Expr)(unsafe.Pointer(pNew)).FpRoot)).FxNext = __ccgo_fp(_fts5ExprNodeNext_STRING)
		}
	} else {
		_sqlite3Fts5ExprFree(tls, pNew)
		_fts5ExprPhraseFree(tls, (**(**TTokenCtx)(__ccgo_up(bp + 4))).FpPhrase)
		pNew = uintptr(0)
	}
	**(**uintptr)(__ccgo_up(ppNew)) = pNew
	return **(**int32)(__ccgo_up(bp))
}

// C documentation
//
//	/*
//	** This function is only called when using the special 'trigram' tokenizer.
//	** Argument zText contains the text of a LIKE or GLOB pattern matched
//	** against column iCol. This function creates and compiles an FTS5 MATCH
//	** expression that will match a superset of the rows matched by the LIKE or
//	** GLOB. If successful, SQLITE_OK is returned. Otherwise, an SQLite error
//	** code.
//	*/
func _sqlite3Fts5ExprPattern(tls *libc.TLS, pConfig uintptr, bGlob int32, iCol int32, zText uintptr, pp uintptr) (r int32) {
	var aSpec [3]int8
	var bAnd, i, iFirst, iOut, jj, rc, v1 int32
	var nText Ti64
	var zExpr uintptr
	_, _, _, _, _, _, _, _, _, _ = aSpec, bAnd, i, iFirst, iOut, jj, nText, rc, zExpr, v1
	nText = libc.Int64FromUint32(libc.Xstrlen(tls, zText))
	zExpr = Xsqlite3_malloc64(tls, libc.Uint64FromInt64(nText*int64(4)+int64(1)))
	rc = SQLITE_OK
	if zExpr == uintptr(0) {
		rc = int32(SQLITE_NOMEM)
	} else {
		iOut = 0
		i = 0
		iFirst = 0
		if bGlob == 0 {
			aSpec[0] = int8('_')
			aSpec[int32(1)] = int8('%')
			aSpec[int32(2)] = 0
		} else {
			aSpec[0] = int8('*')
			aSpec[int32(1)] = int8('?')
			aSpec[int32(2)] = int8('[')
		}
		for int64(i) <= nText {
			if int64(i) == nText || int32(**(**int8)(__ccgo_up(zText + uintptr(i)))) == int32(aSpec[0]) || int32(**(**int8)(__ccgo_up(zText + uintptr(i)))) == int32(aSpec[int32(1)]) || int32(**(**int8)(__ccgo_up(zText + uintptr(i)))) == int32(aSpec[int32(2)]) {
				if _fts5ExprCountChar(tls, zText+uintptr(iFirst), i-iFirst) >= int32(3) {
					v1 = iOut
					iOut = iOut + 1
					**(**int8)(__ccgo_up(zExpr + uintptr(v1))) = int8('"')
					jj = iFirst
					for {
						if !(jj < i) {
							break
						}
						v1 = iOut
						iOut = iOut + 1
						**(**int8)(__ccgo_up(zExpr + uintptr(v1))) = **(**int8)(__ccgo_up(zText + uintptr(jj)))
						if int32(**(**int8)(__ccgo_up(zText + uintptr(jj)))) == int32('"') {
							v1 = iOut
							iOut = iOut + 1
							**(**int8)(__ccgo_up(zExpr + uintptr(v1))) = int8('"')
						}
						goto _2
					_2:
						;
						jj = jj + 1
					}
					v1 = iOut
					iOut = iOut + 1
					**(**int8)(__ccgo_up(zExpr + uintptr(v1))) = int8('"')
					v1 = iOut
					iOut = iOut + 1
					**(**int8)(__ccgo_up(zExpr + uintptr(v1))) = int8(' ')
				}
				if int32(**(**int8)(__ccgo_up(zText + uintptr(i)))) == int32(aSpec[int32(2)]) {
					i = i + int32(2)
					if int32(**(**int8)(__ccgo_up(zText + uintptr(i-int32(1))))) == int32('^') {
						i = i + 1
					}
					for int64(i) < nText && int32(**(**int8)(__ccgo_up(zText + uintptr(i)))) != int32(']') {
						i = i + 1
					}
				}
				iFirst = i + int32(1)
			}
			i = i + 1
		}
		if iOut > 0 {
			bAnd = 0
			if (*TFts5Config)(unsafe.Pointer(pConfig)).FeDetail != FTS5_DETAIL_FULL {
				bAnd = int32(1)
				if (*TFts5Config)(unsafe.Pointer(pConfig)).FeDetail == int32(FTS5_DETAIL_NONE) {
					iCol = (*TFts5Config)(unsafe.Pointer(pConfig)).FnCol
				}
			}
			**(**int8)(__ccgo_up(zExpr + uintptr(iOut))) = int8('\000')
			rc = _sqlite3Fts5ExprNew(tls, pConfig, bAnd, iCol, zExpr, pp, (*TFts5Config)(unsafe.Pointer(pConfig)).FpzErrmsg)
		} else {
			**(**uintptr)(__ccgo_up(pp)) = uintptr(0)
		}
		Xsqlite3_free(tls, zExpr)
	}
	return rc
}

// C documentation
//
//	/*
//	** Add an entry to the in-memory hash table. The key is the concatenation
//	** of bByte and (pToken/nToken). The value is (iRowid/iCol/iPos).
//	**
//	**     (bByte || pToken) -> (iRowid,iCol,iPos)
//	**
//	** Or, if iCol is negative, then the value is a delete marker.
//	*/
func _sqlite3Fts5HashWrite(tls *libc.TLS, pHash uintptr, iRowid Ti64, iCol int32, iPos int32, bByte int8, pToken uintptr, nToken int32) (r int32) {
	var bNew, nIncr, rc, v2 int32
	var iDiff Tu64
	var iHash uint32
	var nByte, nNew Tsqlite3_int64
	var p, pNew, pPtr, pp, zKey, zKey1, v6 uintptr
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = bNew, iDiff, iHash, nByte, nIncr, nNew, p, pNew, pPtr, pp, rc, zKey, zKey1, v2, v6
	nIncr = 0 /* If non-delete entry should be written */
	bNew = libc.BoolInt32((*TFts5Hash)(unsafe.Pointer(pHash)).FeDetail == FTS5_DETAIL_FULL)
	/* Attempt to locate an existing hash entry */
	iHash = _fts5HashKey2(tls, (*TFts5Hash)(unsafe.Pointer(pHash)).FnSlot, libc.Uint8FromInt8(bByte), pToken, nToken)
	p = **(**uintptr)(__ccgo_up((*TFts5Hash)(unsafe.Pointer(pHash)).FaSlot + uintptr(iHash)*4))
	for {
		if !(p != 0) {
			break
		}
		zKey = p + 1*40
		if int32(**(**int8)(__ccgo_up(zKey))) == int32(bByte) && (*TFts5HashEntry)(unsafe.Pointer(p)).FnKey == nToken+int32(1) && libc.Xmemcmp(tls, zKey+1, pToken, libc.Uint32FromInt32(nToken)) == 0 {
			break
		}
		goto _1
	_1:
		;
		p = (*TFts5HashEntry)(unsafe.Pointer(p)).FpHashNext
	}
	/* If an existing hash entry cannot be found, create a new one. */
	if p == uintptr(0) {
		nByte = libc.Int64FromUint32(uint32(40) + libc.Uint32FromInt32(nToken+libc.Int32FromInt32(1)) + uint32(1) + uint32(64))
		if nByte < int64(128) {
			nByte = int64(128)
		}
		/* Grow the Fts5Hash.aSlot[] array if necessary. */
		if (*TFts5Hash)(unsafe.Pointer(pHash)).FnEntry*int32(2) >= (*TFts5Hash)(unsafe.Pointer(pHash)).FnSlot {
			rc = _fts5HashResize(tls, pHash)
			if rc != SQLITE_OK {
				return rc
			}
			iHash = _fts5HashKey2(tls, (*TFts5Hash)(unsafe.Pointer(pHash)).FnSlot, libc.Uint8FromInt8(bByte), pToken, nToken)
		}
		/* Allocate new Fts5HashEntry and add it to the hash table. */
		p = Xsqlite3_malloc64(tls, libc.Uint64FromInt64(nByte))
		if !(p != 0) {
			return int32(SQLITE_NOMEM)
		}
		libc.Xmemset(tls, p, 0, uint32(40))
		(*TFts5HashEntry)(unsafe.Pointer(p)).FnAlloc = int32(nByte)
		zKey1 = p + 1*40
		**(**int8)(__ccgo_up(zKey1)) = bByte
		libc.Xmemcpy(tls, zKey1+1, pToken, libc.Uint32FromInt32(nToken))
		(*TFts5HashEntry)(unsafe.Pointer(p)).FnKey = nToken + int32(1)
		**(**int8)(__ccgo_up(zKey1 + uintptr(nToken+int32(1)))) = int8('\000')
		(*TFts5HashEntry)(unsafe.Pointer(p)).FnData = libc.Int32FromUint32(libc.Uint32FromInt32(nToken+int32(1)) + uint32(40))
		(*TFts5HashEntry)(unsafe.Pointer(p)).FpHashNext = **(**uintptr)(__ccgo_up((*TFts5Hash)(unsafe.Pointer(pHash)).FaSlot + uintptr(iHash)*4))
		**(**uintptr)(__ccgo_up((*TFts5Hash)(unsafe.Pointer(pHash)).FaSlot + uintptr(iHash)*4)) = p
		(*TFts5Hash)(unsafe.Pointer(pHash)).FnEntry = (*TFts5Hash)(unsafe.Pointer(pHash)).FnEntry + 1
		/* Add the first rowid field to the hash-entry */
		**(**int32)(__ccgo_up(p + 16)) += _sqlite3Fts5PutVarint(tls, p+uintptr((*TFts5HashEntry)(unsafe.Pointer(p)).FnData), libc.Uint64FromInt64(iRowid))
		(*TFts5HashEntry)(unsafe.Pointer(p)).FiRowid = iRowid
		(*TFts5HashEntry)(unsafe.Pointer(p)).FiSzPoslist = (*TFts5HashEntry)(unsafe.Pointer(p)).FnData
		if (*TFts5Hash)(unsafe.Pointer(pHash)).FeDetail != int32(FTS5_DETAIL_NONE) {
			**(**int32)(__ccgo_up(p + 16)) += int32(1)
			if (*TFts5Hash)(unsafe.Pointer(pHash)).FeDetail == FTS5_DETAIL_FULL {
				v2 = 0
			} else {
				v2 = -int32(1)
			}
			(*TFts5HashEntry)(unsafe.Pointer(p)).FiCol = int16(v2)
		}
	} else {
		/* Appending to an existing hash-entry. Check that there is enough
		 ** space to append the largest possible new entry. Worst case scenario
		 ** is:
		 **
		 **     + 9 bytes for a new rowid,
		 **     + 4 byte reserved for the "poslist size" varint.
		 **     + 1 byte for a "new column" byte,
		 **     + 3 bytes for a new column number (16-bit max) as a varint,
		 **     + 5 bytes for the new position offset (32-bit max).
		 */
		if (*TFts5HashEntry)(unsafe.Pointer(p)).FnAlloc-(*TFts5HashEntry)(unsafe.Pointer(p)).FnData < libc.Int32FromInt32(9)+libc.Int32FromInt32(4)+libc.Int32FromInt32(1)+libc.Int32FromInt32(3)+libc.Int32FromInt32(5) {
			nNew = int64((*TFts5HashEntry)(unsafe.Pointer(p)).FnAlloc * int32(2))
			pNew = Xsqlite3_realloc64(tls, p, libc.Uint64FromInt64(nNew))
			if pNew == uintptr(0) {
				return int32(SQLITE_NOMEM)
			}
			(*TFts5HashEntry)(unsafe.Pointer(pNew)).FnAlloc = int32(nNew)
			pp = (*TFts5Hash)(unsafe.Pointer(pHash)).FaSlot + uintptr(iHash)*4
			for {
				if !(**(**uintptr)(__ccgo_up(pp)) != p) {
					break
				}
				goto _3
			_3:
				;
				pp = **(**uintptr)(__ccgo_up(pp))
			}
			**(**uintptr)(__ccgo_up(pp)) = pNew
			p = pNew
		}
		nIncr = nIncr - (*TFts5HashEntry)(unsafe.Pointer(p)).FnData
	}
	pPtr = p
	/* If this is a new rowid, append the 4-byte size field for the previous
	 ** entry, and the new rowid for this entry.  */
	if iRowid != (*TFts5HashEntry)(unsafe.Pointer(p)).FiRowid {
		iDiff = libc.Uint64FromInt64(iRowid) - libc.Uint64FromInt64((*TFts5HashEntry)(unsafe.Pointer(p)).FiRowid)
		_fts5HashAddPoslistSize(tls, pHash, p, uintptr(0))
		**(**int32)(__ccgo_up(p + 16)) += _sqlite3Fts5PutVarint(tls, pPtr+uintptr((*TFts5HashEntry)(unsafe.Pointer(p)).FnData), iDiff)
		(*TFts5HashEntry)(unsafe.Pointer(p)).FiRowid = iRowid
		bNew = int32(1)
		(*TFts5HashEntry)(unsafe.Pointer(p)).FiSzPoslist = (*TFts5HashEntry)(unsafe.Pointer(p)).FnData
		if (*TFts5Hash)(unsafe.Pointer(pHash)).FeDetail != int32(FTS5_DETAIL_NONE) {
			**(**int32)(__ccgo_up(p + 16)) += int32(1)
			if (*TFts5Hash)(unsafe.Pointer(pHash)).FeDetail == FTS5_DETAIL_FULL {
				v2 = 0
			} else {
				v2 = -int32(1)
			}
			(*TFts5HashEntry)(unsafe.Pointer(p)).FiCol = int16(v2)
			(*TFts5HashEntry)(unsafe.Pointer(p)).FiPos = 0
		}
	}
	if iCol >= 0 {
		if (*TFts5Hash)(unsafe.Pointer(pHash)).FeDetail == int32(FTS5_DETAIL_NONE) {
			(*TFts5HashEntry)(unsafe.Pointer(p)).FbContent = uint8(1)
		} else {
			/* Append a new column value, if necessary */
			if iCol != int32((*TFts5HashEntry)(unsafe.Pointer(p)).FiCol) {
				if (*TFts5Hash)(unsafe.Pointer(pHash)).FeDetail == FTS5_DETAIL_FULL {
					v6 = p + 16
					v2 = *(*int32)(unsafe.Pointer(v6))
					*(*int32)(unsafe.Pointer(v6)) = *(*int32)(unsafe.Pointer(v6)) + 1
					**(**Tu8)(__ccgo_up(pPtr + uintptr(v2))) = uint8(0x01)
					**(**int32)(__ccgo_up(p + 16)) += _sqlite3Fts5PutVarint(tls, pPtr+uintptr((*TFts5HashEntry)(unsafe.Pointer(p)).FnData), libc.Uint64FromInt32(iCol))
					(*TFts5HashEntry)(unsafe.Pointer(p)).FiCol = int16(iCol)
					(*TFts5HashEntry)(unsafe.Pointer(p)).FiPos = 0
				} else {
					bNew = int32(1)
					v2 = iCol
					iPos = v2
					(*TFts5HashEntry)(unsafe.Pointer(p)).FiCol = int16(v2)
				}
			}
			/* Append the new position offset, if necessary */
			if bNew != 0 {
				**(**int32)(__ccgo_up(p + 16)) += _sqlite3Fts5PutVarint(tls, pPtr+uintptr((*TFts5HashEntry)(unsafe.Pointer(p)).FnData), libc.Uint64FromInt32(iPos-(*TFts5HashEntry)(unsafe.Pointer(p)).FiPos+int32(2)))
				(*TFts5HashEntry)(unsafe.Pointer(p)).FiPos = iPos
			}
		}
	} else {
		/* This is a delete. Set the delete flag. */
		(*TFts5HashEntry)(unsafe.Pointer(p)).FbDel = uint8(1)
	}
	nIncr = nIncr + (*TFts5HashEntry)(unsafe.Pointer(p)).FnData
	**(**int32)(__ccgo_up((*TFts5Hash)(unsafe.Pointer(pHash)).FpnByte)) += nIncr
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** Add iRowid to the tombstone list of the segment or segments that contain
//	** rows from origin iOrigin. Return SQLITE_OK if successful, or an SQLite
//	** error code otherwise.
//	*/
func _sqlite3Fts5IndexContentlessDelete(tls *libc.TLS, p uintptr, iOrigin Ti64, iRowid Ti64) (r int32) {
	var bFound, iLvl, iSeg int32
	var pSeg, pStruct uintptr
	_, _, _, _, _ = bFound, iLvl, iSeg, pSeg, pStruct
	pStruct = _fts5StructureRead(tls, p)
	if pStruct != 0 {
		bFound = 0
		iLvl = (*TFts5Structure)(unsafe.Pointer(pStruct)).FnLevel - int32(1)
		for {
			if !(iLvl >= 0) {
				break
			}
			iSeg = (*(*TFts5StructureLevel)(unsafe.Pointer(pStruct + 28 + uintptr(iLvl)*12))).FnSeg - int32(1)
			for {
				if !(iSeg >= 0) {
					break
				}
				pSeg = (*(*TFts5StructureLevel)(unsafe.Pointer(pStruct + 28 + uintptr(iLvl)*12))).FaSeg + uintptr(iSeg)*48
				if (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FiOrigin1 <= libc.Uint64FromInt64(iOrigin) && (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FiOrigin2 >= libc.Uint64FromInt64(iOrigin) {
					if bFound == 0 {
						(*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FnEntryTombstone = (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FnEntryTombstone + 1
						bFound = int32(1)
					}
					_fts5IndexTombstoneAdd(tls, p, pSeg, libc.Uint64FromInt64(iRowid))
				}
				goto _2
			_2:
				;
				iSeg = iSeg - 1
			}
			goto _1
		_1:
			;
			iLvl = iLvl - 1
		}
		_fts5StructureRelease(tls, pStruct)
	}
	return _fts5IndexReturn(tls, p)
}

/*************************************************************************
**************************************************************************
** Below this point is the implementation of the integrity-check
** functionality.
 */

// C documentation
//
//	/*
//	** Set a token-mapping for the iterator passed as the first argument. This
//	** is used in detail=column or detail=none mode when a token is requested
//	** using the xInstToken() API. In this case the caller tokenizers the
//	** current row and configures the token-mapping via multiple calls to this
//	** function.
//	*/
func _sqlite3Fts5IndexIterWriteTokendata(tls *libc.TLS, pIndexIter uintptr, pToken uintptr, nToken int32, iRowid Ti64, iCol int32, iOff int32) (r int32) {
	var iPos Ti64
	var ii int32
	var p, pIter, pT, pTerm uintptr
	_, _, _, _, _, _ = iPos, ii, p, pIter, pT, pTerm
	pIter = pIndexIter
	pT = (*TFts5Iter)(unsafe.Pointer(pIter)).FpTokenDataIter
	p = (*TFts5Iter)(unsafe.Pointer(pIter)).FpIndex
	iPos = int64(iCol)<<libc.Int32FromInt32(32) + int64(iOff)
	if (*TFts5Iter)(unsafe.Pointer(pIter)).FnSeg > 0 {
		/* This is a prefix term iterator. */
		if pT == uintptr(0) {
			pT = _sqlite3Fts5MallocZero(tls, p+40, libc.Int64FromUint32(uint32(libc.UintptrFromInt32(0)+56)+libc.Uint32FromInt32(libc.Int32FromInt32(1))*libc.Uint32FromInt64(72)))
			(*TFts5Iter)(unsafe.Pointer(pIter)).FpTokenDataIter = pT
		}
		if pT != 0 {
			_fts5TokendataIterAppendMap(tls, p, pT, (*TFts5TokenDataIter)(unsafe.Pointer(pT)).Fterms.Fn, nToken, iRowid, iPos)
			_sqlite3Fts5BufferAppendBlob(tls, p+40, pT+20, libc.Uint32FromInt32(nToken), pToken)
		}
	} else {
		ii = 0
		for {
			if !(int64(ii) < (*TFts5TokenDataIter)(unsafe.Pointer(pT)).FnIter) {
				break
			}
			pTerm = *(*uintptr)(unsafe.Pointer(pT + 56 + uintptr(ii)*4)) + 72 + 68
			if nToken == (*TFts5Buffer)(unsafe.Pointer(pTerm)).Fn-int32(1) && libc.Xmemcmp(tls, pToken, (*TFts5Buffer)(unsafe.Pointer(pTerm)).Fp+uintptr(1), libc.Uint32FromInt32(nToken)) == 0 {
				break
			}
			goto _1
		_1:
			;
			ii = ii + 1
		}
		if int64(ii) < (*TFts5TokenDataIter)(unsafe.Pointer(pT)).FnIter {
			_fts5TokendataIterAppendMap(tls, p, pT, ii, 0, iRowid, iPos)
		}
	}
	return _fts5IndexReturn(tls, p)
}

func _sqlite3Fts5IndexOptimize(tls *libc.TLS, p uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var iLvl int32
	var pStruct uintptr
	var _ /* nRem at bp+4 */ int32
	var _ /* pNew at bp+0 */ uintptr
	_, _ = iLvl, pStruct
	**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
	_fts5IndexFlush(tls, p)
	pStruct = _fts5StructureRead(tls, p)
	_fts5StructureInvalidate(tls, p)
	if pStruct != 0 {
		**(**uintptr)(__ccgo_up(bp)) = _fts5IndexOptimizeStruct(tls, p, pStruct)
	}
	_fts5StructureRelease(tls, pStruct)
	if **(**uintptr)(__ccgo_up(bp)) != 0 {
		iLvl = 0
		for {
			if !((*(*TFts5StructureLevel)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)) + 28 + uintptr(iLvl)*12))).FnSeg == 0) {
				break
			}
			goto _1
		_1:
			;
			iLvl = iLvl + 1
		}
		for (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK && (*(*TFts5StructureLevel)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)) + 28 + uintptr(iLvl)*12))).FnSeg > 0 {
			**(**int32)(__ccgo_up(bp + 4)) = int32(FTS5_OPT_WORK_UNIT)
			_fts5IndexMergeLevel(tls, p, bp, iLvl, bp+4)
		}
		_fts5StructureWrite(tls, p, **(**uintptr)(__ccgo_up(bp)))
		_fts5StructureRelease(tls, **(**uintptr)(__ccgo_up(bp)))
	}
	return _fts5IndexReturn(tls, p)
}

// C documentation
//
//	/*
//	** Open a new iterator to iterate though all rowid that match the
//	** specified token or token prefix.
//	*/
func _sqlite3Fts5IndexQuery(tls *libc.TLS, p uintptr, pToken uintptr, nToken int32, flags int32, pColset uintptr, ppIter uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var bDesc, bTokendata, iIdx, iPrefixIdx, nChar, nIdxChar int32
	var pConfig, pSeg, pStruct uintptr
	var _ /* buf at bp+4 */ TFts5Buffer
	var _ /* pRet at bp+0 */ uintptr
	_, _, _, _, _, _, _, _, _ = bDesc, bTokendata, iIdx, iPrefixIdx, nChar, nIdxChar, pConfig, pSeg, pStruct
	pConfig = (*TFts5Index)(unsafe.Pointer(p)).FpConfig
	**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
	**(**TFts5Buffer)(__ccgo_up(bp + 4)) = TFts5Buffer{}
	/* If the QUERY_SCAN flag is set, all other flags must be clear. */
	if _sqlite3Fts5BufferSize(tls, p+40, bp+4, libc.Uint32FromInt32(nToken+int32(1))) == 0 {
		iIdx = 0       /* Index to search */
		iPrefixIdx = 0 /* +1 prefix index */
		bTokendata = (*TFts5Config)(unsafe.Pointer(pConfig)).FbTokendata
		if nToken > 0 {
			libc.Xmemcpy(tls, (**(**TFts5Buffer)(__ccgo_up(bp + 4))).Fp+1, pToken, libc.Uint32FromInt32(nToken))
		}
		/* The NOTOKENDATA flag is set when each token in a tokendata=1 table
		 ** should be treated individually, instead of merging all those with
		 ** a common prefix into a single entry. This is used, for example, by
		 ** queries performed as part of an integrity-check, or by the fts5vocab
		 ** module.  */
		if flags&(libc.Int32FromInt32(FTS5INDEX_QUERY_NOTOKENDATA)|libc.Int32FromInt32(FTS5INDEX_QUERY_SCAN)) != 0 {
			bTokendata = 0
		}
		/* Figure out which index to search and set iIdx accordingly. If this
		 ** is a prefix query for which there is no prefix index, set iIdx to
		 ** greater than pConfig->nPrefix to indicate that the query will be
		 ** satisfied by scanning multiple terms in the main index.
		 **
		 ** If the QUERY_TEST_NOIDX flag was specified, then this must be a
		 ** prefix-query. Instead of using a prefix-index (if one exists),
		 ** evaluate the prefix query using the main FTS index. This is used
		 ** for internal sanity checking by the integrity-check in debug
		 ** mode only.  */
		if flags&int32(FTS5INDEX_QUERY_PREFIX) != 0 {
			nChar = _fts5IndexCharlen(tls, pToken, nToken)
			iIdx = int32(1)
			for {
				if !(iIdx <= (*TFts5Config)(unsafe.Pointer(pConfig)).FnPrefix) {
					break
				}
				nIdxChar = **(**int32)(__ccgo_up((*TFts5Config)(unsafe.Pointer(pConfig)).FaPrefix + uintptr(iIdx-int32(1))*4))
				if nIdxChar == nChar {
					break
				}
				if nIdxChar == nChar+int32(1) {
					iPrefixIdx = iIdx
				}
				goto _1
			_1:
				;
				iIdx = iIdx + 1
			}
		}
		if bTokendata != 0 && iIdx == 0 {
			**(**Tu8)(__ccgo_up((**(**TFts5Buffer)(__ccgo_up(bp + 4))).Fp)) = uint8('0')
			**(**uintptr)(__ccgo_up(bp)) = _fts5SetupTokendataIter(tls, p, (**(**TFts5Buffer)(__ccgo_up(bp + 4))).Fp, nToken+int32(1), pColset)
		} else {
			if iIdx <= (*TFts5Config)(unsafe.Pointer(pConfig)).FnPrefix {
				/* Straight index lookup */
				pStruct = _fts5StructureRead(tls, p)
				**(**Tu8)(__ccgo_up((**(**TFts5Buffer)(__ccgo_up(bp + 4))).Fp)) = libc.Uint8FromInt32(libc.Int32FromUint8('0') + iIdx)
				if pStruct != 0 {
					_fts5MultiIterNew(tls, p, pStruct, flags|int32(FTS5INDEX_QUERY_SKIPEMPTY), pColset, (**(**TFts5Buffer)(__ccgo_up(bp + 4))).Fp, nToken+int32(1), -int32(1), 0, bp)
					_fts5StructureRelease(tls, pStruct)
				}
			} else {
				/* Scan multiple terms in the main index for a prefix query. */
				bDesc = libc.BoolInt32(flags&int32(FTS5INDEX_QUERY_DESC) != 0)
				_fts5SetupPrefixIter(tls, p, bDesc, iPrefixIdx, (**(**TFts5Buffer)(__ccgo_up(bp + 4))).Fp, nToken+int32(1), pColset, bp)
				if **(**uintptr)(__ccgo_up(bp)) == uintptr(0) {
				} else {
					_fts5IterSetOutputCb(tls, p+40, **(**uintptr)(__ccgo_up(bp)))
					if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
						pSeg = **(**uintptr)(__ccgo_up(bp)) + 72 + uintptr((**(**TFts5CResult)(__ccgo_up((*TFts5Iter)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FaFirst + 1*4))).FiFirst)*96
						if (*TFts5SegIter)(unsafe.Pointer(pSeg)).FpLeaf != 0 {
							(*(*func(*libc.TLS, uintptr, uintptr))(unsafe.Pointer(&struct{ uintptr }{(*TFts5Iter)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FxSetOutputs})))(tls, **(**uintptr)(__ccgo_up(bp)), pSeg)
						}
					}
				}
			}
		}
		if (*TFts5Index)(unsafe.Pointer(p)).Frc != 0 {
			_fts5IterClose(tls, **(**uintptr)(__ccgo_up(bp)))
			**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
			_fts5IndexCloseReader(tls, p)
		}
		**(**uintptr)(__ccgo_up(ppIter)) = **(**uintptr)(__ccgo_up(bp))
		_sqlite3Fts5BufferFree(tls, bp+4)
	}
	return _fts5IndexReturn(tls, p)
}

// C documentation
//
//	/*
//	** Return true if the value passed as the only argument is an
//	** fts5_locale() value.
//	*/
func _sqlite3Fts5IsLocaleValue(tls *libc.TLS, pConfig uintptr, pVal uintptr) (r int32) {
	var nBlob, ret int32
	var pBlob uintptr
	_, _, _ = nBlob, pBlob, ret
	ret = 0
	if Xsqlite3_value_type(tls, pVal) == int32(SQLITE_BLOB) {
		/* Call sqlite3_value_bytes() after sqlite3_value_blob() in this case.
		 ** If the blob was created using zeroblob(), then sqlite3_value_blob()
		 ** may call malloc(). If this malloc() fails, then the values returned
		 ** by both value_blob() and value_bytes() will be 0. If value_bytes() were
		 ** called first, then the NULL pointer returned by value_blob() might
		 ** be dereferenced.  */
		pBlob = Xsqlite3_value_blob(tls, pVal)
		nBlob = Xsqlite3_value_bytes(tls, pVal)
		if nBlob > libc.Int32FromInt64(16) && 0 == libc.Xmemcmp(tls, pBlob, (*TFts5Config)(unsafe.Pointer(pConfig)).FpGlobal+52, libc.Uint32FromInt32(libc.Int32FromInt64(16))) {
			ret = int32(1)
		}
	}
	return ret
}

// C documentation
//
//	/*
//	** Move to the next matching term/rowid. Used by the fts5vocab module.
//	*/
func _sqlite3Fts5IterNextScan(tls *libc.TLS, pIndexIter uintptr) (r int32) {
	var p, pIter, pSeg uintptr
	_, _, _ = p, pIter, pSeg
	pIter = pIndexIter
	p = (*TFts5Iter)(unsafe.Pointer(pIter)).FpIndex
	_fts5MultiIterNext(tls, p, pIter, 0, 0)
	if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
		pSeg = pIter + 72 + uintptr((**(**TFts5CResult)(__ccgo_up((*TFts5Iter)(unsafe.Pointer(pIter)).FaFirst + 1*4))).FiFirst)*96
		if (*TFts5SegIter)(unsafe.Pointer(pSeg)).FpLeaf != 0 && libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TFts5SegIter)(unsafe.Pointer(pSeg)).Fterm.Fp))) != int32('0') {
			_fts5DataRelease(tls, (*TFts5SegIter)(unsafe.Pointer(pSeg)).FpLeaf)
			(*TFts5SegIter)(unsafe.Pointer(pSeg)).FpLeaf = uintptr(0)
			(*TFts5Iter)(unsafe.Pointer(pIter)).Fbase.FbEof = uint8(1)
		}
	}
	return _fts5IndexReturn(tls, (*TFts5Iter)(unsafe.Pointer(pIter)).FpIndex)
}

// C documentation
//
//	/*
//	** This is used by xInstToken() to access the token at offset iOff, column
//	** iCol of row iRowid. The token is returned via output variables *ppOut
//	** and *pnOut. The iterator passed as the first argument must be a tokendata=1
//	** iterator (pIter->pTokenDataIter!=0).
//	**
//	** pToken/nToken:
//	*/
func _sqlite3Fts5IterToken(tls *libc.TLS, pIndexIter uintptr, pToken uintptr, nToken int32, iRowid Ti64, iCol int32, iOff int32, ppOut uintptr, pnOut uintptr) (r int32) {
	var aMap, p, pIter, pMap, pT uintptr
	var i1, i2, iTest, rc int32
	var iPos Ti64
	_, _, _, _, _, _, _, _, _, _ = aMap, i1, i2, iPos, iTest, p, pIter, pMap, pT, rc
	pIter = pIndexIter
	pT = (*TFts5Iter)(unsafe.Pointer(pIter)).FpTokenDataIter
	iPos = int64(iCol)<<libc.Int32FromInt32(32) + int64(iOff)
	aMap = uintptr(0)
	i1 = 0
	i2 = 0
	iTest = 0
	if pT == uintptr(0) {
		rc = _fts5SetupPrefixIterTokendata(tls, pIter, pToken, nToken)
		if rc != SQLITE_OK {
			return rc
		}
		pT = (*TFts5Iter)(unsafe.Pointer(pIter)).FpTokenDataIter
	}
	i2 = int32((*TFts5TokenDataIter)(unsafe.Pointer(pT)).FnMap)
	aMap = (*TFts5TokenDataIter)(unsafe.Pointer(pT)).FaMap
	for i2 > i1 {
		iTest = (i1 + i2) / int32(2)
		if (**(**TFts5TokenDataMap)(__ccgo_up(aMap + uintptr(iTest)*24))).FiRowid < iRowid {
			i1 = iTest + int32(1)
		} else {
			if (**(**TFts5TokenDataMap)(__ccgo_up(aMap + uintptr(iTest)*24))).FiRowid > iRowid {
				i2 = iTest
			} else {
				if (**(**TFts5TokenDataMap)(__ccgo_up(aMap + uintptr(iTest)*24))).FiPos < iPos {
					if (**(**TFts5TokenDataMap)(__ccgo_up(aMap + uintptr(iTest)*24))).FiPos < 0 {
						break
					}
					i1 = iTest + int32(1)
				} else {
					if (**(**TFts5TokenDataMap)(__ccgo_up(aMap + uintptr(iTest)*24))).FiPos > iPos {
						i2 = iTest
					} else {
						break
					}
				}
			}
		}
	}
	if i2 > i1 {
		if (*TFts5Iter)(unsafe.Pointer(pIter)).FnSeg == 0 {
			pMap = *(*uintptr)(unsafe.Pointer(pT + 56 + uintptr((**(**TFts5TokenDataMap)(__ccgo_up(aMap + uintptr(iTest)*24))).FiIter)*4))
			**(**uintptr)(__ccgo_up(ppOut)) = (*(*TFts5SegIter)(unsafe.Pointer(pMap + 72))).Fterm.Fp + uintptr(1)
			**(**int32)(__ccgo_up(pnOut)) = (*(*TFts5SegIter)(unsafe.Pointer(pMap + 72))).Fterm.Fn - int32(1)
		} else {
			p = aMap + uintptr(iTest)*24
			**(**uintptr)(__ccgo_up(ppOut)) = (*TFts5TokenDataIter)(unsafe.Pointer(pT)).Fterms.Fp + uintptr((*TFts5TokenDataMap)(unsafe.Pointer(p)).FiIter)
			**(**int32)(__ccgo_up(pnOut)) = (**(**TFts5TokenDataMap)(__ccgo_up(aMap + uintptr(iTest)*24))).FnByte
		}
	}
	return SQLITE_OK
}

func _sqlite3Fts5ParseImplicitAnd(tls *libc.TLS, pParse uintptr, pLeft uintptr, pRight uintptr) (r uintptr) {
	var ap, pPrev, pRet uintptr
	_, _, _ = ap, pPrev, pRet
	pRet = uintptr(0)
	if (*TFts5Parse)(unsafe.Pointer(pParse)).Frc != 0 {
		_sqlite3Fts5ParseNodeFree(tls, pLeft)
		_sqlite3Fts5ParseNodeFree(tls, pRight)
	} else {
		if (*TFts5ExprNode)(unsafe.Pointer(pLeft)).FeType == int32(FTS5_AND) {
			pPrev = *(*uintptr)(unsafe.Pointer(pLeft + 36 + uintptr((*TFts5ExprNode)(unsafe.Pointer(pLeft)).FnChild-int32(1))*4))
		} else {
			pPrev = pLeft
		}
		if (*TFts5ExprNode)(unsafe.Pointer(pRight)).FeType == FTS5_EOF {
			_sqlite3Fts5ParseNodeFree(tls, pRight)
			pRet = pLeft
			(*TFts5Parse)(unsafe.Pointer(pParse)).FnPhrase = (*TFts5Parse)(unsafe.Pointer(pParse)).FnPhrase - 1
		} else {
			if (*TFts5ExprNode)(unsafe.Pointer(pPrev)).FeType == FTS5_EOF {
				if pPrev == pLeft {
					pRet = pRight
				} else {
					*(*uintptr)(unsafe.Pointer(pLeft + 36 + uintptr((*TFts5ExprNode)(unsafe.Pointer(pLeft)).FnChild-int32(1))*4)) = pRight
					pRet = pLeft
				}
				ap = (*TFts5Parse)(unsafe.Pointer(pParse)).FapPhrase + uintptr((*TFts5Parse)(unsafe.Pointer(pParse)).FnPhrase-int32(1)-(*TFts5ExprNearset)(unsafe.Pointer((*TFts5ExprNode)(unsafe.Pointer(pRight)).FpNear)).FnPhrase)*4
				libc.Xmemmove(tls, ap, ap+1*4, uint32(4)*libc.Uint32FromInt32((*TFts5ExprNearset)(unsafe.Pointer((*TFts5ExprNode)(unsafe.Pointer(pRight)).FpNear)).FnPhrase))
				(*TFts5Parse)(unsafe.Pointer(pParse)).FnPhrase = (*TFts5Parse)(unsafe.Pointer(pParse)).FnPhrase - 1
				_sqlite3Fts5ParseNodeFree(tls, pPrev)
			} else {
				pRet = _sqlite3Fts5ParseNode(tls, pParse, int32(FTS5_AND), pLeft, pRight, uintptr(0))
			}
		}
	}
	return pRet
}

// C documentation
//
//	/*
//	** Free the expression node object passed as the only argument.
//	*/
func _sqlite3Fts5ParseNodeFree(tls *libc.TLS, p uintptr) {
	var i int32
	_ = i
	if p != 0 {
		i = 0
		for {
			if !(i < (*TFts5ExprNode)(unsafe.Pointer(p)).FnChild) {
				break
			}
			_sqlite3Fts5ParseNodeFree(tls, *(*uintptr)(unsafe.Pointer(p + 36 + uintptr(i)*4)))
			goto _1
		_1:
			;
			i = i + 1
		}
		_sqlite3Fts5ParseNearsetFree(tls, (*TFts5ExprNode)(unsafe.Pointer(p)).FpNear)
		Xsqlite3_free(tls, p)
	}
}

// C documentation
//
//	/*
//	** Close a handle opened by an earlier call to sqlite3Fts5StorageOpen().
//	*/
func _sqlite3Fts5StorageClose(tls *libc.TLS, p uintptr) (r int32) {
	var i, rc int32
	_, _ = i, rc
	rc = SQLITE_OK
	if p != 0 {
		/* Finalize all SQL statements */
		i = 0
		for {
			if !(i < libc.Int32FromUint32(libc.Uint32FromInt64(48)/libc.Uint32FromInt64(4))) {
				break
			}
			Xsqlite3_finalize(tls, **(**uintptr)(__ccgo_up(p + 28 + uintptr(i)*4)))
			goto _1
		_1:
			;
			i = i + 1
		}
		Xsqlite3_free(tls, p)
	}
	return rc
}

// C documentation
//
//	/*
//	** Obtain an SQLite statement handle that may be used to read data from the
//	** %_content table.
//	*/
func _sqlite3Fts5StorageStmt(tls *libc.TLS, p uintptr, eStmt int32, pp uintptr, pzErrMsg uintptr) (r int32) {
	var rc int32
	_ = rc
	rc = _fts5StorageGetStmt(tls, p, eStmt, pp, pzErrMsg)
	if rc == SQLITE_OK {
		**(**uintptr)(__ccgo_up(p + 28 + uintptr(eStmt)*4)) = uintptr(0)
	}
	return rc
}

// C documentation
//
//	/*
//	** Release an SQLite statement handle obtained via an earlier call to
//	** sqlite3Fts5StorageStmt(). The eStmt parameter passed to this function
//	** must match that passed to the sqlite3Fts5StorageStmt() call.
//	*/
func _sqlite3Fts5StorageStmtRelease(tls *libc.TLS, p uintptr, eStmt int32, pStmt uintptr) {
	if **(**uintptr)(__ccgo_up(p + 28 + uintptr(eStmt)*4)) == uintptr(0) {
		Xsqlite3_reset(tls, pStmt)
		**(**uintptr)(__ccgo_up(p + 28 + uintptr(eStmt)*4)) = pStmt
	} else {
		Xsqlite3_finalize(tls, pStmt)
	}
}

// C documentation
//
//	/*
//	** Return a nul-terminated copy of the string indicated by pIn. If nIn
//	** is non-negative, then it is the length of the string in bytes. Otherwise,
//	** the length of the string is determined using strlen().
//	**
//	** It is the responsibility of the caller to eventually free the returned
//	** buffer using sqlite3_free(). If an OOM error occurs, NULL is returned.
//	*/
func _sqlite3Fts5Strndup(tls *libc.TLS, pRc uintptr, pIn uintptr, nIn int32) (r uintptr) {
	var zRet uintptr
	_ = zRet
	zRet = uintptr(0)
	if **(**int32)(__ccgo_up(pRc)) == SQLITE_OK {
		if nIn < 0 {
			nIn = libc.Int32FromUint32(libc.Xstrlen(tls, pIn))
		}
		zRet = Xsqlite3_malloc64(tls, libc.Uint64FromInt64(int64(nIn)+int64(1)))
		if zRet != 0 {
			libc.Xmemcpy(tls, zRet, pIn, libc.Uint32FromInt32(nIn))
			**(**int8)(__ccgo_up(zRet + uintptr(nIn))) = int8('\000')
		} else {
			**(**int32)(__ccgo_up(pRc)) = int32(SQLITE_NOMEM)
		}
	}
	return zRet
}

func _sqlite3Fts5TermsetAdd(tls *libc.TLS, p uintptr, iIdx int32, pTerm uintptr, nTerm int32, pbPresent uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var hash Tu32
	var i int32
	var pEntry uintptr
	var _ /* rc at bp+0 */ int32
	_, _, _ = hash, i, pEntry
	**(**int32)(__ccgo_up(bp)) = SQLITE_OK
	**(**int32)(__ccgo_up(pbPresent)) = 0
	if p != 0 {
		hash = uint32(13)
		/* Calculate a hash value for this term. This is the same hash checksum
		 ** used by the fts5_hash.c module. This is not important for correct
		 ** operation of the module, but is necessary to ensure that some tests
		 ** designed to produce hash table collisions really do work.  */
		i = nTerm - int32(1)
		for {
			if !(i >= 0) {
				break
			}
			hash = hash<<libc.Int32FromInt32(3) ^ hash ^ libc.Uint32FromInt8(**(**int8)(__ccgo_up(pTerm + uintptr(i))))
			goto _1
		_1:
			;
			i = i - 1
		}
		hash = hash<<libc.Int32FromInt32(3) ^ hash ^ libc.Uint32FromInt32(iIdx)
		hash = hash % libc.Uint32FromInt32(libc.Int32FromUint32(libc.Uint32FromInt64(2048)/libc.Uint32FromInt64(4)))
		pEntry = **(**uintptr)(__ccgo_up(p + uintptr(hash)*4))
		for {
			if !(pEntry != 0) {
				break
			}
			if (*TFts5TermsetEntry)(unsafe.Pointer(pEntry)).FiIdx == iIdx && (*TFts5TermsetEntry)(unsafe.Pointer(pEntry)).FnTerm == nTerm && libc.Xmemcmp(tls, (*TFts5TermsetEntry)(unsafe.Pointer(pEntry)).FpTerm, pTerm, libc.Uint32FromInt32(nTerm)) == 0 {
				**(**int32)(__ccgo_up(pbPresent)) = int32(1)
				break
			}
			goto _2
		_2:
			;
			pEntry = (*TFts5TermsetEntry)(unsafe.Pointer(pEntry)).FpNext
		}
		if pEntry == uintptr(0) {
			pEntry = _sqlite3Fts5MallocZero(tls, bp, libc.Int64FromUint32(uint32(16)+libc.Uint32FromInt32(nTerm)))
			if pEntry != 0 {
				(*TFts5TermsetEntry)(unsafe.Pointer(pEntry)).FpTerm = pEntry + 1*16
				(*TFts5TermsetEntry)(unsafe.Pointer(pEntry)).FnTerm = nTerm
				(*TFts5TermsetEntry)(unsafe.Pointer(pEntry)).FiIdx = iIdx
				libc.Xmemcpy(tls, (*TFts5TermsetEntry)(unsafe.Pointer(pEntry)).FpTerm, pTerm, libc.Uint32FromInt32(nTerm))
				(*TFts5TermsetEntry)(unsafe.Pointer(pEntry)).FpNext = **(**uintptr)(__ccgo_up(p + uintptr(hash)*4))
				**(**uintptr)(__ccgo_up(p + uintptr(hash)*4)) = pEntry
			}
		}
	}
	return **(**int32)(__ccgo_up(bp))
}

// C documentation
//
//	/*
//	** If zNum represents an integer that will fit in 32-bits, then set
//	** *pValue to that integer and return true.  Otherwise return false.
//	**
//	** This routine accepts both decimal and hexadecimal notation for integers.
//	**
//	** Any non-numeric characters that following zNum are ignored.
//	** This is different from sqlite3Atoi64() which requires the
//	** input number to be zero-terminated.
//	*/
func _sqlite3GetInt32(tls *libc.TLS, zNum uintptr, pValue uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var c, i, neg, v3 int32
	var v Tsqlite_int64
	var v4 bool
	var _ /* u at bp+0 */ Tu32
	_, _, _, _, _, _ = c, i, neg, v, v3, v4
	v = 0
	neg = 0
	if int32(**(**int8)(__ccgo_up(zNum))) == int32('-') {
		neg = int32(1)
		zNum = zNum + 1
	} else {
		if int32(**(**int8)(__ccgo_up(zNum))) == int32('+') {
			zNum = zNum + 1
		} else {
			if int32(**(**int8)(__ccgo_up(zNum))) == int32('0') && (int32(**(**int8)(__ccgo_up(zNum + 1))) == int32('x') || int32(**(**int8)(__ccgo_up(zNum + 1))) == int32('X')) && libc.Int32FromUint8(_sqlite3CtypeMap[libc.Uint8FromInt8(**(**int8)(__ccgo_up(zNum + 2)))])&int32(0x08) != 0 {
				**(**Tu32)(__ccgo_up(bp)) = uint32(0)
				zNum = zNum + uintptr(2)
				for int32(**(**int8)(__ccgo_up(zNum))) == int32('0') {
					zNum = zNum + 1
				}
				i = 0
				for {
					if !(i < int32(8) && libc.Int32FromUint8(_sqlite3CtypeMap[libc.Uint8FromInt8(**(**int8)(__ccgo_up(zNum + uintptr(i))))])&int32(0x08) != 0) {
						break
					}
					**(**Tu32)(__ccgo_up(bp)) = **(**Tu32)(__ccgo_up(bp))*uint32(16) + uint32(_sqlite3HexToInt(tls, int32(**(**int8)(__ccgo_up(zNum + uintptr(i))))))
					goto _1
				_1:
					;
					i = i + 1
				}
				if **(**Tu32)(__ccgo_up(bp))&uint32(0x80000000) == uint32(0) && libc.Int32FromUint8(_sqlite3CtypeMap[libc.Uint8FromInt8(**(**int8)(__ccgo_up(zNum + uintptr(i))))])&int32(0x08) == 0 {
					libc.Xmemcpy(tls, pValue, bp, uint32(4))
					return int32(1)
				} else {
					return 0
				}
			}
		}
	}
	if !(libc.Int32FromUint8(_sqlite3CtypeMap[libc.Uint8FromInt8(**(**int8)(__ccgo_up(zNum)))])&libc.Int32FromInt32(0x04) != 0) {
		return 0
	}
	for int32(**(**int8)(__ccgo_up(zNum))) == int32('0') {
		zNum = zNum + 1
	}
	i = 0
	for {
		if v4 = i < int32(11); v4 {
			v3 = int32(**(**int8)(__ccgo_up(zNum + uintptr(i)))) - libc.Int32FromUint8('0')
			c = v3
		}
		if !(v4 && v3 >= 0 && c <= int32(9)) {
			break
		}
		v = v*int64(10) + int64(c)
		goto _2
	_2:
		;
		i = i + 1
	}
	/* The longest decimal representation of a 32 bit integer is 10 digits:
	 **
	 **             1234567890
	 **     2^31 -> 2147483648
	 */
	if i > int32(10) {
		return 0
	}
	if v-int64(neg) > int64(2147483647) {
		return 0
	}
	if neg != 0 {
		v = -v
	}
	**(**int32)(__ccgo_up(pValue)) = int32(v)
	return int32(1)
}

// C documentation
//
//	/*
//	** Return true if the heap is currently under memory pressure - in other
//	** words if the amount of heap used is close to the limit set by
//	** sqlite3_soft_heap_limit().
//	*/
func _sqlite3HeapNearlyFull(tls *libc.TLS) (r int32) {
	return libc.AtomicLoadNInt32(uintptr(unsafe.Pointer(&_mem0))+20, libc.Int32FromInt32(__ATOMIC_RELAXED))
}

// C documentation
//
//	/*
//	** Render an signed 64-bit integer as text.  Store the result in zOut[] and
//	** return the length of the string that was stored, in bytes.  The value
//	** returned does not include the zero terminator at the end of the output
//	** string.
//	**
//	** The caller must ensure that zOut[] is at least 21 bytes in size.
//	*/
func _sqlite3Int64ToText(tls *libc.TLS, v Ti64, zOut uintptr) (r int32) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var i, kk, v2 int32
	var x Tu64
	var v1 uint64
	var _ /* u at bp+0 */ struct {
		FforceAlignment [0]Tu16
		Fa              [21]int8
		F__ccgo_pad2    [1]byte
	}
	_, _, _, _, _ = i, kk, x, v1, v2
	if v > 0 {
		x = libc.Uint64FromInt64(v)
	} else {
		if v == 0 {
			**(**int8)(__ccgo_up(zOut)) = int8('0')
			**(**int8)(__ccgo_up(zOut + 1)) = 0
			return int32(1)
		} else {
			if v == int64(-libc.Int32FromInt32(1))-(libc.Int64FromUint32(0xffffffff)|libc.Int64FromInt32(0x7fffffff)<<libc.Int32FromInt32(32)) {
				v1 = libc.Uint64FromInt32(1) << libc.Int32FromInt32(63)
			} else {
				v1 = libc.Uint64FromInt64(-v)
			}
			x = v1
		}
	}
	i = libc.Int32FromUint32(libc.Uint32FromInt64(21) - libc.Uint32FromInt32(1))
	**(**int8)(__ccgo_up(bp + uintptr(i))) = 0
	for x >= uint64(10) {
		kk = libc.Int32FromUint64(x % uint64(100) * uint64(2))
		**(**Tu16)(__ccgo_up(bp + uintptr(i-int32(2)))) = **(**Tu16)(__ccgo_up(uintptr(unsafe.Pointer(&_sqlite3DigitPairs)) + uintptr(kk)))
		i = i - int32(2)
		x = x / uint64(100)
	}
	if x != 0 {
		i = i - 1
		v2 = i
		**(**int8)(__ccgo_up(bp + uintptr(v2))) = libc.Int8FromUint64(x + uint64('0'))
	}
	if v < 0 {
		i = i - 1
		v2 = i
		**(**int8)(__ccgo_up(bp + uintptr(v2))) = int8('-')
	}
	libc.Xmemcpy(tls, zOut, bp+uintptr(i), uint32(21)-libc.Uint32FromInt32(i))
	return libc.Int32FromUint32(libc.Uint32FromInt64(21) - libc.Uint32FromInt32(1) - libc.Uint32FromInt32(i))
}

// C documentation
//
//	/*
//	** pExpr points to an expression which implements a function.  If
//	** it is appropriate to apply the LIKE optimization to that function
//	** then set aWc[0] through aWc[2] to the wildcard characters and the
//	** escape character and then return TRUE.  If the function is not a
//	** LIKE-style function then return FALSE.
//	**
//	** The expression "a LIKE b ESCAPE c" is only considered a valid LIKE
//	** operator if c is a string literal that is exactly one byte in length.
//	** That one byte is stored in aWc[3].  aWc[3] is set to zero if there is
//	** no ESCAPE clause.
//	**
//	** *pIsNocase is set to true if uppercase and lowercase are equivalent for
//	** the function (default for LIKE).  If the function makes the distinction
//	** between uppercase and lowercase (as does GLOB) then *pIsNocase is set to
//	** false.
//	*/
func _sqlite3IsLikeFunction(tls *libc.TLS, db uintptr, pExpr uintptr, pIsNocase uintptr, aWc uintptr) (r int32) {
	var nExpr int32
	var pDef, pEscape, zEscape uintptr
	_, _, _, _ = nExpr, pDef, pEscape, zEscape
	if !(*(*uintptr)(unsafe.Pointer(pExpr + 20)) != 0) {
		return 0
	}
	nExpr = (*TExprList)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pExpr + 20)))).FnExpr
	pDef = _sqlite3FindFunction(tls, db, *(*uintptr)(unsafe.Pointer(pExpr + 8)), nExpr, uint8(SQLITE_UTF8), uint8(0))
	if pDef == uintptr(0) || (*TFuncDef)(unsafe.Pointer(pDef)).FfuncFlags&uint32(SQLITE_FUNC_LIKE) == uint32(0) {
		return 0
	}
	/* The memcpy() statement assumes that the wildcard characters are
	 ** the first three statements in the compareInfo structure.  The
	 ** asserts() that follow verify that assumption
	 */
	libc.Xmemcpy(tls, aWc, (*TFuncDef)(unsafe.Pointer(pDef)).FpUserData, uint32(3))
	if nExpr < int32(3) {
		**(**int8)(__ccgo_up(aWc + 3)) = 0
	} else {
		pEscape = (*(*TExprList_item)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pExpr + 20)) + 8 + 2*20))).FpExpr
		if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pEscape)).Fop) != int32(TK_STRING) {
			return 0
		}
		zEscape = *(*uintptr)(unsafe.Pointer(pEscape + 8))
		if int32(**(**int8)(__ccgo_up(zEscape))) == 0 || int32(**(**int8)(__ccgo_up(zEscape + 1))) != 0 {
			return 0
		}
		if int32(**(**int8)(__ccgo_up(zEscape))) == int32(**(**int8)(__ccgo_up(aWc))) {
			return 0
		}
		if int32(**(**int8)(__ccgo_up(zEscape))) == int32(**(**int8)(__ccgo_up(aWc + 1))) {
			return 0
		}
		**(**int8)(__ccgo_up(aWc + 3)) = **(**int8)(__ccgo_up(zEscape))
	}
	**(**int32)(__ccgo_up(pIsNocase)) = libc.BoolInt32((*TFuncDef)(unsafe.Pointer(pDef)).FfuncFlags&uint32(SQLITE_FUNC_CASE) == uint32(0))
	return int32(1)
}

/* Mathematical Constants */

// C documentation
//
//	/*
//	** Return true if pTab is a virtual table and zName is a shadow table name
//	** for that virtual table.
//	*/
func _sqlite3IsShadowTableOf(tls *libc.TLS, db uintptr, pTab uintptr, zName uintptr) (r int32) {
	var nName int32
	var pMod uintptr
	_, _ = nName, pMod /* Module for the virtual table */
	if !(libc.Int32FromUint8((*TTable)(unsafe.Pointer(pTab)).FeTabType) == libc.Int32FromInt32(TABTYP_VTAB)) {
		return 0
	}
	nName = _sqlite3Strlen30(tls, (*TTable)(unsafe.Pointer(pTab)).FzName)
	if Xsqlite3_strnicmp(tls, zName, (*TTable)(unsafe.Pointer(pTab)).FzName, nName) != 0 {
		return 0
	}
	if int32(**(**int8)(__ccgo_up(zName + uintptr(nName)))) != int32('_') {
		return 0
	}
	pMod = _sqlite3HashFind(tls, db+400, **(**uintptr)(__ccgo_up((*(*struct {
		FnArg  int32
		FazArg uintptr
		Fp     uintptr
	})(unsafe.Pointer(pTab + 44))).FazArg)))
	if pMod == uintptr(0) {
		return 0
	}
	if (*Tsqlite3_module)(unsafe.Pointer((*TModule)(unsafe.Pointer(pMod)).FpModule)).FiVersion < int32(3) {
		return 0
	}
	if (*Tsqlite3_module)(unsafe.Pointer((*TModule)(unsafe.Pointer(pMod)).FpModule)).FxShadowName == uintptr(0) {
		return 0
	}
	return (*(*func(*libc.TLS, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*Tsqlite3_module)(unsafe.Pointer((*TModule)(unsafe.Pointer(pMod)).FpModule)).FxShadowName})))(tls, zName+uintptr(nName)+uintptr(1))
}

// C documentation
//
//	/*
//	** Open a journal file.
//	**
//	** The behaviour of the journal file depends on the value of parameter
//	** nSpill. If nSpill is 0, then the journal file is always create and
//	** accessed using the underlying VFS. If nSpill is less than zero, then
//	** all content is always stored in main-memory. Finally, if nSpill is a
//	** positive value, then the journal file is initially created in-memory
//	** but may be flushed to disk later on. In this case the journal file is
//	** flushed to disk either when it grows larger than nSpill bytes in size,
//	** or when sqlite3JournalCreate() is called.
//	*/
func _sqlite3JournalOpen(tls *libc.TLS, pVfs uintptr, zName uintptr, pJfd uintptr, flags int32, nSpill int32) (r int32) {
	var p uintptr
	_ = p
	p = pJfd
	/* Zero the file-handle object. If nSpill was passed zero, initialize
	 ** it using the sqlite3OsOpen() function of the underlying VFS. In this
	 ** case none of the code in this module is executed as a result of calls
	 ** made on the journal file-handle.  */
	libc.Xmemset(tls, p, 0, uint32(52))
	if nSpill == 0 {
		return _sqlite3OsOpen(tls, pVfs, zName, pJfd, flags, uintptr(0))
	}
	if nSpill > 0 {
		(*TMemJournal)(unsafe.Pointer(p)).FnChunkSize = nSpill
	} else {
		(*TMemJournal)(unsafe.Pointer(p)).FnChunkSize = libc.Int32FromUint32(libc.Uint32FromInt32(libc.Int32FromInt32(8)+libc.Int32FromInt32(MEMJOURNAL_DFLT_FILECHUNKSIZE)) - libc.Uint32FromInt64(12))
	}
	(*Tsqlite3_file)(unsafe.Pointer(pJfd)).FpMethods = uintptr(unsafe.Pointer(&_MemJournalMethods))
	(*TMemJournal)(unsafe.Pointer(p)).FnSpill = nSpill
	(*TMemJournal)(unsafe.Pointer(p)).Fflags = flags
	(*TMemJournal)(unsafe.Pointer(p)).FzJournal = zName
	(*TMemJournal)(unsafe.Pointer(p)).FpVfs = pVfs
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** Return the number of bytes required to store a JournalFile that uses vfs
//	** pVfs to create the underlying on-disk files.
//	*/
func _sqlite3JournalSize(tls *libc.TLS, pVfs uintptr) (r int32) {
	var v1 int32
	_ = v1
	if (*Tsqlite3_vfs)(unsafe.Pointer(pVfs)).FszOsFile > libc.Int32FromInt64(52) {
		v1 = (*Tsqlite3_vfs)(unsafe.Pointer(pVfs)).FszOsFile
	} else {
		v1 = libc.Int32FromInt64(52)
	}
	return v1
}

/************** End of memjournal.c ******************************************/
/************** Begin file walker.c ******************************************/
/*
** 2008 August 16
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used for walking the parser tree for
** an SQL statement.
 */
/* #include "sqliteInt.h" */
/* #include <stdlib.h> */
/* #include <string.h> */

// C documentation
//
//	/*
//	** Close the mutex on database connection db.
//	**
//	** Furthermore, if database connection db is a zombie (meaning that there
//	** has been a prior call to sqlite3_close(db) or sqlite3_close_v2(db)) and
//	** every sqlite3_stmt has now been finalized and every sqlite3_backup has
//	** finished, then free all resources.
//	*/
func _sqlite3LeaveMutexAndCloseZombie(tls *libc.TLS, db uintptr) {
	var i, p, pColl, pDb, pMod, pNext uintptr
	var j int32
	_, _, _, _, _, _, _ = i, j, p, pColl, pDb, pMod, pNext
	/* If there are outstanding sqlite3_stmt or sqlite3_backup objects
	 ** or if the connection has not yet been closed by sqlite3_close_v2(),
	 ** then just leave the mutex and return.
	 */
	if libc.Int32FromUint8((*Tsqlite3)(unsafe.Pointer(db)).FeOpenState) != int32(SQLITE_STATE_ZOMBIE) || _connectionIsBusy(tls, db) != 0 {
		Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
		return
	}
	/* If we reach this point, it means that the database connection has
	 ** closed all sqlite3_stmt and sqlite3_backup objects and has been
	 ** passed to sqlite3_close (meaning that it is a zombie).  Therefore,
	 ** go ahead and free all resources.
	 */
	/* If a transaction is open, roll it back. This also ensures that if
	 ** any database schemas have been modified by an uncommitted transaction
	 ** they are reset. And that the required b-tree mutex is held to make
	 ** the pager rollback and schema reset an atomic operation. */
	_sqlite3RollbackAll(tls, db, SQLITE_OK)
	/* Free any outstanding Savepoint structures. */
	_sqlite3CloseSavepoints(tls, db)
	/* Close all database connections */
	j = 0
	for {
		if !(j < (*Tsqlite3)(unsafe.Pointer(db)).FnDb) {
			break
		}
		pDb = (*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(j)*16
		if (*TDb)(unsafe.Pointer(pDb)).FpBt != 0 {
			_sqlite3BtreeClose(tls, (*TDb)(unsafe.Pointer(pDb)).FpBt)
			(*TDb)(unsafe.Pointer(pDb)).FpBt = uintptr(0)
			if j != int32(1) {
				(*TDb)(unsafe.Pointer(pDb)).FpSchema = uintptr(0)
			}
		}
		goto _1
	_1:
		;
		j = j + 1
	}
	/* Clear the TEMP schema separately and last */
	if (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + 1*16))).FpSchema != 0 {
		_sqlite3SchemaClear(tls, (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + 1*16))).FpSchema)
	}
	_sqlite3VtabUnlockList(tls, db)
	/* Free up the array of auxiliary databases */
	_sqlite3CollapseDatabaseArray(tls, db)
	/* Tell the code in notify.c that the connection no longer holds any
	 ** locks and does not require any further unlock-notify callbacks.
	 */
	_sqlite3ConnectionClosed(tls, db)
	i = (*THash)(unsafe.Pointer(db + 428)).Ffirst
	for {
		if !(i != 0) {
			break
		}
		p = (*THashElem)(unsafe.Pointer(i)).Fdata
		for cond := true; cond; cond = p != 0 {
			_functionDestroy(tls, db, p)
			pNext = (*TFuncDef)(unsafe.Pointer(p)).FpNext
			_sqlite3DbFree(tls, db, p)
			p = pNext
		}
		goto _2
	_2:
		;
		i = (*THashElem)(unsafe.Pointer(i)).Fnext
	}
	_sqlite3HashClear(tls, db+428)
	i = (*THash)(unsafe.Pointer(db + 444)).Ffirst
	for {
		if !(i != 0) {
			break
		}
		pColl = (*THashElem)(unsafe.Pointer(i)).Fdata
		/* Invoke any destructors registered for collation sequence user data. */
		j = 0
		for {
			if !(j < int32(3)) {
				break
			}
			if (**(**TCollSeq)(__ccgo_up(pColl + uintptr(j)*20))).FxDel != 0 {
				(*(*func(*libc.TLS, uintptr))(unsafe.Pointer(&struct{ uintptr }{(**(**TCollSeq)(__ccgo_up(pColl + uintptr(j)*20))).FxDel})))(tls, (**(**TCollSeq)(__ccgo_up(pColl + uintptr(j)*20))).FpUser)
			}
			goto _4
		_4:
			;
			j = j + 1
		}
		_sqlite3DbFree(tls, db, pColl)
		goto _3
	_3:
		;
		i = (*THashElem)(unsafe.Pointer(i)).Fnext
	}
	_sqlite3HashClear(tls, db+444)
	i = (*THash)(unsafe.Pointer(db + 400)).Ffirst
	for {
		if !(i != 0) {
			break
		}
		pMod = (*THashElem)(unsafe.Pointer(i)).Fdata
		_sqlite3VtabEponymousTableClear(tls, db, pMod)
		_sqlite3VtabModuleUnref(tls, db, pMod)
		goto _5
	_5:
		;
		i = (*THashElem)(unsafe.Pointer(i)).Fnext
	}
	_sqlite3HashClear(tls, db+400)
	_sqlite3Error(tls, db, SQLITE_OK) /* Deallocates any cached error strings. */
	_sqlite3ValueFree(tls, (*Tsqlite3)(unsafe.Pointer(db)).FpErr)
	_sqlite3CloseExtensions(tls, db)
	(*Tsqlite3)(unsafe.Pointer(db)).FeOpenState = uint8(SQLITE_STATE_ERROR)
	/* The temp-database schema is allocated differently from the other schema
	 ** objects (using sqliteMalloc() directly, instead of sqlite3BtreeSchema()).
	 ** So it needs to be freed here. Todo: Why not roll the temp schema into
	 ** the same sqliteMalloc() as the one that allocates the database
	 ** structure?
	 */
	_sqlite3DbFree(tls, db, (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + 1*16))).FpSchema)
	if (*Tsqlite3)(unsafe.Pointer(db)).FxAutovacDestr != 0 {
		(*(*func(*libc.TLS, uintptr))(unsafe.Pointer(&struct{ uintptr }{(*Tsqlite3)(unsafe.Pointer(db)).FxAutovacDestr})))(tls, (*Tsqlite3)(unsafe.Pointer(db)).FpAutovacPagesArg)
	}
	Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
	(*Tsqlite3)(unsafe.Pointer(db)).FeOpenState = uint8(SQLITE_STATE_CLOSED)
	Xsqlite3_mutex_free(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
	if (*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FbMalloced != 0 {
		Xsqlite3_free(tls, (*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpStart)
	}
	Xsqlite3_free(tls, db)
}

// C documentation
//
//	/*
//	** Deinitialize the memory allocation subsystem.
//	*/
func _sqlite3MallocEnd(tls *libc.TLS) {
	if _sqlite3Config.Fm.FxShutdown != 0 {
		(*(*func(*libc.TLS, uintptr))(unsafe.Pointer(&struct{ uintptr }{_sqlite3Config.Fm.FxShutdown})))(tls, _sqlite3Config.Fm.FpAppData)
	}
	libc.Xmemset(tls, uintptr(unsafe.Pointer(&_mem0)), 0, uint32(24))
}

// C documentation
//
//	/*
//	** Initialize the memory allocation subsystem.
//	*/
func _sqlite3MallocInit(tls *libc.TLS) (r int32) {
	var rc int32
	_ = rc
	if _sqlite3Config.Fm.FxMalloc == uintptr(0) {
		_sqlite3MemSetDefault(tls)
	}
	_mem0.Fmutex = _sqlite3MutexAlloc(tls, int32(SQLITE_MUTEX_STATIC_MEM))
	if _sqlite3Config.FpPage == uintptr(0) || _sqlite3Config.FszPage < int32(512) || _sqlite3Config.FnPage <= 0 {
		_sqlite3Config.FpPage = uintptr(0)
		_sqlite3Config.FszPage = 0
	}
	rc = (*(*func(*libc.TLS, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_sqlite3Config.Fm.FxInit})))(tls, _sqlite3Config.Fm.FpAppData)
	if rc != SQLITE_OK {
		libc.Xmemset(tls, uintptr(unsafe.Pointer(&_mem0)), 0, uint32(24))
	}
	return rc
}

// C documentation
//
//	/*
//	** Table pTab is a virtual table.  If it the virtual table implementation
//	** exists and has an xShadowName method, then loop over all other ordinary
//	** tables within the same schema looking for shadow tables of pTab, and mark
//	** any shadow tables seen using the TF_Shadow flag.
//	*/
func _sqlite3MarkAllShadowTablesOf(tls *libc.TLS, db uintptr, pTab uintptr) {
	var k, pMod, pOther uintptr
	var nName int32
	_, _, _, _ = k, nName, pMod, pOther /* For looping through the symbol table */
	pMod = _sqlite3HashFind(tls, db+400, **(**uintptr)(__ccgo_up((*(*struct {
		FnArg  int32
		FazArg uintptr
		Fp     uintptr
	})(unsafe.Pointer(pTab + 44))).FazArg)))
	if pMod == uintptr(0) {
		return
	}
	if (*TModule)(unsafe.Pointer(pMod)).FpModule == uintptr(0) {
		return
	}
	if (*Tsqlite3_module)(unsafe.Pointer((*TModule)(unsafe.Pointer(pMod)).FpModule)).FiVersion < int32(3) {
		return
	}
	if (*Tsqlite3_module)(unsafe.Pointer((*TModule)(unsafe.Pointer(pMod)).FpModule)).FxShadowName == uintptr(0) {
		return
	}
	nName = _sqlite3Strlen30(tls, (*TTable)(unsafe.Pointer(pTab)).FzName)
	k = (*THash)(unsafe.Pointer((*TTable)(unsafe.Pointer(pTab)).FpSchema + 8)).Ffirst
	for {
		if !(k != 0) {
			break
		}
		pOther = (*THashElem)(unsafe.Pointer(k)).Fdata
		if !(libc.Int32FromUint8((*TTable)(unsafe.Pointer(pOther)).FeTabType) == libc.Int32FromInt32(TABTYP_NORM)) {
			goto _1
		}
		if (*TTable)(unsafe.Pointer(pOther)).FtabFlags&uint32(TF_Shadow) != 0 {
			goto _1
		}
		if Xsqlite3_strnicmp(tls, (*TTable)(unsafe.Pointer(pOther)).FzName, (*TTable)(unsafe.Pointer(pTab)).FzName, nName) == 0 && int32(**(**int8)(__ccgo_up((*TTable)(unsafe.Pointer(pOther)).FzName + uintptr(nName)))) == int32('_') && (*(*func(*libc.TLS, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*Tsqlite3_module)(unsafe.Pointer((*TModule)(unsafe.Pointer(pMod)).FpModule)).FxShadowName})))(tls, (*TTable)(unsafe.Pointer(pOther)).FzName+uintptr(nName)+uintptr(1)) != 0 {
			**(**Tu32)(__ccgo_up(pOther + 28)) |= uint32(TF_Shadow)
		}
		goto _1
	_1:
		;
		k = (*THashElem)(unsafe.Pointer(k)).Fnext
	}
}

// C documentation
//
//	/*
//	** This routine reactivates the memory allocator and clears the
//	** db->mallocFailed flag as necessary.
//	**
//	** The memory allocator is not restarted if there are running
//	** VDBEs.
//	*/
func _sqlite3OomClear(tls *libc.TLS, db uintptr) {
	var v1 int32
	_ = v1
	if (*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0 && (*Tsqlite3)(unsafe.Pointer(db)).FnVdbeExec == 0 {
		(*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed = uint8(0)
		libc.AtomicStoreNInt32(db+308, libc.Int32FromInt32(0), libc.Int32FromInt32(__ATOMIC_RELAXED))
		(*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FbDisable = (*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FbDisable - 1
		if (*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FbDisable != 0 {
			v1 = 0
		} else {
			v1 = libc.Int32FromUint16((*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FszTrue)
		}
		(*Tsqlite3)(unsafe.Pointer(db)).Flookaside.Fsz = libc.Uint16FromInt32(v1)
	}
}

func _sqlite3OsRandomness(tls *libc.TLS, pVfs uintptr, nByte int32, zBufOut uintptr) (r int32) {
	if _sqlite3Config.FiPrngSeed != 0 {
		libc.Xmemset(tls, zBufOut, 0, libc.Uint32FromInt32(nByte))
		if nByte > libc.Int32FromInt64(4) {
			nByte = int32(4)
		}
		libc.Xmemcpy(tls, zBufOut, uintptr(unsafe.Pointer(&_sqlite3Config))+272, libc.Uint32FromInt32(nByte))
		return SQLITE_OK
	} else {
		return (*(*func(*libc.TLS, uintptr, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*Tsqlite3_vfs)(unsafe.Pointer(pVfs)).FxRandomness})))(tls, pVfs, nByte, zBufOut)
	}
	return r
}

// C documentation
//
//	/*
//	** Return a pointer to the pPager->pBackup variable. The backup module
//	** in backup.c maintains the content of this variable. This module
//	** uses it opaquely as an argument to sqlite3BackupRestart() and
//	** sqlite3BackupUpdate() only.
//	*/
func _sqlite3PagerBackupPtr(tls *libc.TLS, pPager uintptr) (r uintptr) {
	return pPager + 92
}

// C documentation
//
//	/*
//	** Parameter eStat must be one of SQLITE_DBSTATUS_CACHE_HIT, _MISS, _WRITE,
//	** or _WRITE+1.  The SQLITE_DBSTATUS_CACHE_WRITE+1 case is a translation
//	** of SQLITE_DBSTATUS_CACHE_SPILL.  The _SPILL case is not contiguous because
//	** it was added later.
//	**
//	** Before returning, *pnVal is incremented by the
//	** current cache hit or miss count, according to the value of eStat. If the
//	** reset parameter is non-zero, the cache hit or miss count is zeroed before
//	** returning.
//	*/
func _sqlite3PagerCacheStat(tls *libc.TLS, pPager uintptr, eStat int32, reset int32, pnVal uintptr) {
	eStat = eStat - int32(SQLITE_DBSTATUS_CACHE_HIT)
	**(**Tu64)(__ccgo_up(pnVal)) += uint64(**(**Tu32)(__ccgo_up(pPager + 192 + uintptr(eStat)*4)))
	if reset != 0 {
		**(**Tu32)(__ccgo_up(pPager + 192 + uintptr(eStat)*4)) = uint32(0)
	}
}

// C documentation
//
//	/*
//	** Set the busy handler function.
//	**
//	** The pager invokes the busy-handler if sqlite3OsLock() returns
//	** SQLITE_BUSY when trying to upgrade from no-lock to a SHARED lock,
//	** or when trying to upgrade from a RESERVED lock to an EXCLUSIVE
//	** lock. It does *not* invoke the busy handler when upgrading from
//	** SHARED to RESERVED, or when upgrading from SHARED to EXCLUSIVE
//	** (which occurs during hot-journal rollback). Summary:
//	**
//	**   Transition                        | Invokes xBusyHandler
//	**   --------------------------------------------------------
//	**   NO_LOCK       -> SHARED_LOCK      | Yes
//	**   SHARED_LOCK   -> RESERVED_LOCK    | No
//	**   SHARED_LOCK   -> EXCLUSIVE_LOCK   | No
//	**   RESERVED_LOCK -> EXCLUSIVE_LOCK   | Yes
//	**
//	** If the busy-handler callback returns non-zero, the lock is
//	** retried. If it returns zero, then the SQLITE_BUSY error is
//	** returned to the caller of the pager API function.
//	*/
func _sqlite3PagerSetBusyHandler(tls *libc.TLS, pPager uintptr, __ccgo_fp_xBusyHandler uintptr, pBusyHandlerArg uintptr) {
	var ap uintptr
	_ = ap
	(*TPager)(unsafe.Pointer(pPager)).FxBusyHandler = __ccgo_fp_xBusyHandler
	(*TPager)(unsafe.Pointer(pPager)).FpBusyHandlerArg = pBusyHandlerArg
	ap = pPager + 184
	_sqlite3OsFileControlHint(tls, (*TPager)(unsafe.Pointer(pPager)).Ffd, int32(SQLITE_FCNTL_BUSYHANDLER), ap)
}

// C documentation
//
//	/*
//	** This function is called to obtain a shared lock on the database file.
//	** It is illegal to call sqlite3PagerGet() until after this function
//	** has been successfully called. If a shared-lock is already held when
//	** this function is called, it is a no-op.
//	**
//	** The following operations are also performed by this function.
//	**
//	**   1) If the pager is currently in PAGER_OPEN state (no lock held
//	**      on the database file), then an attempt is made to obtain a
//	**      SHARED lock on the database file. Immediately after obtaining
//	**      the SHARED lock, the file-system is checked for a hot-journal,
//	**      which is played back if present. Following any hot-journal
//	**      rollback, the contents of the cache are validated by checking
//	**      the 'change-counter' field of the database file header and
//	**      discarded if they are found to be invalid.
//	**
//	**   2) If the pager is running in exclusive-mode, and there are currently
//	**      no outstanding references to any pages, and is in the error state,
//	**      then an attempt is made to clear the error state by discarding
//	**      the contents of the page cache and rolling back any open journal
//	**      file.
//	**
//	** If everything is successful, SQLITE_OK is returned. If an IO error
//	** occurs while locking the database, checking for a hot-journal file or
//	** rolling back a journal file, the IO error code is returned.
//	*/
func _sqlite3PagerSharedLock(tls *libc.TLS, pPager uintptr) (r int32) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var f, rc int32
	var pVfs uintptr
	var _ /* bExists at bp+4 */ int32
	var _ /* bHotJournal at bp+0 */ int32
	var _ /* dbFileVers at bp+12 */ [16]int8
	var _ /* fout at bp+8 */ int32
	_, _, _ = f, pVfs, rc
	rc = SQLITE_OK /* Return code */
	/* This routine is only called from b-tree and only when there are no
	 ** outstanding pages. This implies that the pager state should either
	 ** be OPEN or READER. READER is only possible if the pager is or was in
	 ** exclusive access mode.  */
	if !((*TPager)(unsafe.Pointer(pPager)).FpWal != libc.UintptrFromInt32(0)) && libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FeState) == PAGER_OPEN {
		**(**int32)(__ccgo_up(bp)) = int32(1) /* True if there exists a hot journal-file */
		rc = _pager_wait_on_lock(tls, pPager, int32(SHARED_LOCK))
		if rc != SQLITE_OK {
			goto failed
		}
		/* If a journal file exists, and there is no RESERVED lock on the
		 ** database file, then it either needs to be played back or deleted.
		 */
		if libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FeLock) <= int32(SHARED_LOCK) {
			rc = _hasHotJournal(tls, pPager, bp)
		}
		if rc != SQLITE_OK {
			goto failed
		}
		if **(**int32)(__ccgo_up(bp)) != 0 {
			if (*TPager)(unsafe.Pointer(pPager)).FreadOnly != 0 {
				rc = libc.Int32FromInt32(SQLITE_READONLY) | libc.Int32FromInt32(3)<<libc.Int32FromInt32(8)
				goto failed
			}
			/* Get an EXCLUSIVE lock on the database file. At this point it is
			 ** important that a RESERVED lock is not obtained on the way to the
			 ** EXCLUSIVE lock. If it were, another process might open the
			 ** database file, detect the RESERVED lock, and conclude that the
			 ** database is safe to read while this process is still rolling the
			 ** hot-journal back.
			 **
			 ** Because the intermediate RESERVED lock is not requested, any
			 ** other process attempting to access the database file will get to
			 ** this point in the code and fail to obtain its own EXCLUSIVE lock
			 ** on the database file.
			 **
			 ** Unless the pager is in locking_mode=exclusive mode, the lock is
			 ** downgraded to SHARED_LOCK before this function returns.
			 */
			rc = _pagerLockDb(tls, pPager, int32(EXCLUSIVE_LOCK))
			if rc != SQLITE_OK {
				goto failed
			}
			/* If it is not already open and the file exists on disk, open the
			 ** journal for read/write access. Write access is required because
			 ** in exclusive-access mode the file descriptor will be kept open
			 ** and possibly used for a transaction later on. Also, write-access
			 ** is usually required to finalize the journal in journal_mode=persist
			 ** mode (and also for journal_mode=truncate on some systems).
			 **
			 ** If the journal does not exist, it usually means that some
			 ** other connection managed to get in and roll it back before
			 ** this connection obtained the exclusive lock above. Or, it
			 ** may mean that the pager was in the error-state when this
			 ** function was called and the journal file does not exist.
			 */
			if !((*Tsqlite3_file)(unsafe.Pointer((*TPager)(unsafe.Pointer(pPager)).Fjfd)).FpMethods != libc.UintptrFromInt32(0)) && libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FjournalMode) != int32(PAGER_JOURNALMODE_OFF) {
				pVfs = (*TPager)(unsafe.Pointer(pPager)).FpVfs /* True if journal file exists */
				rc = _sqlite3OsAccess(tls, pVfs, (*TPager)(unsafe.Pointer(pPager)).FzJournal, SQLITE_ACCESS_EXISTS, bp+4)
				if rc == SQLITE_OK && **(**int32)(__ccgo_up(bp + 4)) != 0 {
					**(**int32)(__ccgo_up(bp + 8)) = 0
					f = libc.Int32FromInt32(SQLITE_OPEN_READWRITE) | libc.Int32FromInt32(SQLITE_OPEN_MAIN_JOURNAL)
					rc = _sqlite3OsOpen(tls, pVfs, (*TPager)(unsafe.Pointer(pPager)).FzJournal, (*TPager)(unsafe.Pointer(pPager)).Fjfd, f, bp+8)
					if rc == SQLITE_OK && **(**int32)(__ccgo_up(bp + 8))&int32(SQLITE_OPEN_READONLY) != 0 {
						rc = _sqlite3CantopenError(tls, int32(64944))
						_sqlite3OsClose(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd)
					}
				}
			}
			/* Playback and delete the journal.  Drop the database write
			 ** lock and reacquire the read lock. Purge the cache before
			 ** playing back the hot-journal so that we don't end up with
			 ** an inconsistent cache.  Sync the hot journal before playing
			 ** it back since the process that crashed and left the hot journal
			 ** probably did not sync it and we are required to always sync
			 ** the journal before playing it back.
			 */
			if (*Tsqlite3_file)(unsafe.Pointer((*TPager)(unsafe.Pointer(pPager)).Fjfd)).FpMethods != uintptr(0) {
				rc = _pagerSyncHotJournal(tls, pPager)
				if rc == SQLITE_OK {
					rc = _pager_playback(tls, pPager, libc.BoolInt32(!((*TPager)(unsafe.Pointer(pPager)).FtempFile != 0)))
					(*TPager)(unsafe.Pointer(pPager)).FeState = uint8(PAGER_OPEN)
				}
			} else {
				if !((*TPager)(unsafe.Pointer(pPager)).FexclusiveMode != 0) {
					_pagerUnlockDb(tls, pPager, int32(SHARED_LOCK))
				}
			}
			if rc != SQLITE_OK {
				/* This branch is taken if an error occurs while trying to open
				 ** or roll back a hot-journal while holding an EXCLUSIVE lock. The
				 ** pager_unlock() routine will be called before returning to unlock
				 ** the file. If the unlock attempt fails, then Pager.eLock must be
				 ** set to UNKNOWN_LOCK (see the comment above the #define for
				 ** UNKNOWN_LOCK above for an explanation).
				 **
				 ** In order to get pager_unlock() to do this, set Pager.eState to
				 ** PAGER_ERROR now. This is not actually counted as a transition
				 ** to ERROR state in the state diagram at the top of this file,
				 ** since we know that the same call to pager_unlock() will very
				 ** shortly transition the pager object to the OPEN state. Calling
				 ** assert_pager_state() would fail now, as it should not be possible
				 ** to be in ERROR state when there are zero outstanding page
				 ** references.
				 */
				_pager_error(tls, pPager, rc)
				goto failed
			}
		}
		if !((*TPager)(unsafe.Pointer(pPager)).FtempFile != 0) && (*TPager)(unsafe.Pointer(pPager)).FhasHeldSharedLock != 0 {
			rc = _sqlite3OsRead(tls, (*TPager)(unsafe.Pointer(pPager)).Ffd, bp+12, int32(16), int64(24))
			if rc != SQLITE_OK {
				if rc != libc.Int32FromInt32(SQLITE_IOERR)|libc.Int32FromInt32(2)<<libc.Int32FromInt32(8) {
					goto failed
				}
				libc.Xmemset(tls, bp+12, 0, uint32(16))
			}
			if libc.Xmemcmp(tls, pPager+108, bp+12, uint32(16)) != 0 {
				_pager_reset(tls, pPager)
				/* Unmap the database file. It is possible that external processes
				 ** may have truncated the database file and then extended it back
				 ** to its original size while this process was not holding a lock.
				 ** In this case there may exist a Pager.pMap mapping that appears
				 ** to be the right size but is not actually valid. Avoid this
				 ** possibility by unmapping the db here. */
				if (*TPager)(unsafe.Pointer(pPager)).FbUseFetch != 0 {
					_sqlite3OsUnfetch(tls, (*TPager)(unsafe.Pointer(pPager)).Ffd, 0, uintptr(0))
				}
			}
		}
		/* If there is a WAL file in the file-system, open this database in WAL
		 ** mode. Otherwise, the following function call is a no-op.
		 */
		rc = _pagerOpenWalIfPresent(tls, pPager)
	}
	if (*TPager)(unsafe.Pointer(pPager)).FpWal != uintptr(0) {
		rc = _pagerBeginReadTransaction(tls, pPager)
	}
	if libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FtempFile) == 0 && libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FeState) == PAGER_OPEN && rc == SQLITE_OK {
		rc = _pagerPagecount(tls, pPager, pPager+28)
	}
	goto failed
failed:
	;
	if rc != SQLITE_OK {
		_pager_unlock(tls, pPager)
	} else {
		(*TPager)(unsafe.Pointer(pPager)).FeState = uint8(PAGER_READER)
		(*TPager)(unsafe.Pointer(pPager)).FhasHeldSharedLock = uint8(1)
	}
	return rc
}

// C documentation
//
//	/*
//	** Create a new PCache object. Storage space to hold the object
//	** has already been allocated and is passed in as the p pointer.
//	** The caller discovers how much space needs to be allocated by
//	** calling sqlite3PcacheSize().
//	**
//	** szExtra is some extra space allocated for each page.  The first
//	** 8 bytes of the extra space will be zeroed as the page is allocated,
//	** but remaining content will be uninitialized.  Though it is opaque
//	** to this module, the extra space really ends up being the MemPage
//	** structure in the pager.
//	*/
func _sqlite3PcacheOpen(tls *libc.TLS, szPage int32, szExtra int32, bPurgeable int32, __ccgo_fp_xStress uintptr, pStress uintptr, p uintptr) (r int32) {
	libc.Xmemset(tls, p, 0, uint32(52))
	(*TPCache)(unsafe.Pointer(p)).FszPage = int32(1)
	(*TPCache)(unsafe.Pointer(p)).FszExtra = szExtra
	/* First 8 bytes will be zeroed */
	(*TPCache)(unsafe.Pointer(p)).FbPurgeable = libc.Uint8FromInt32(bPurgeable)
	(*TPCache)(unsafe.Pointer(p)).FeCreate = uint8(2)
	(*TPCache)(unsafe.Pointer(p)).FxStress = __ccgo_fp_xStress
	(*TPCache)(unsafe.Pointer(p)).FpStress = pStress
	(*TPCache)(unsafe.Pointer(p)).FszCache = int32(100)
	(*TPCache)(unsafe.Pointer(p)).FszSpill = int32(1)
	return _sqlite3PcacheSetPageSize(tls, p, szPage)
}

// C documentation
//
//	/*
//	** Return the size in bytes of a PCache object.
//	*/
func _sqlite3PcacheSize(tls *libc.TLS) (r int32) {
	return int32(52)
}

// C documentation
//
//	/*
//	** Check for interrupts and invoke progress callback.
//	*/
func _sqlite3ProgressCheck(tls *libc.TLS, p uintptr) {
	var db, v2 uintptr
	var v1 Tu32
	_, _, _ = db, v1, v2
	db = (*TParse)(unsafe.Pointer(p)).Fdb
	if libc.AtomicLoadNInt32(db+308, libc.Int32FromInt32(__ATOMIC_RELAXED)) != 0 {
		(*TParse)(unsafe.Pointer(p)).FnErr = (*TParse)(unsafe.Pointer(p)).FnErr + 1
		(*TParse)(unsafe.Pointer(p)).Frc = int32(SQLITE_INTERRUPT)
	}
	if (*Tsqlite3)(unsafe.Pointer(db)).FxProgress != 0 {
		if (*TParse)(unsafe.Pointer(p)).Frc == int32(SQLITE_INTERRUPT) {
			(*TParse)(unsafe.Pointer(p)).FnProgressSteps = uint32(0)
		} else {
			v2 = p + 100
			*(*Tu32)(unsafe.Pointer(v2)) = *(*Tu32)(unsafe.Pointer(v2)) + 1
			v1 = *(*Tu32)(unsafe.Pointer(v2))
			if v1 >= (*Tsqlite3)(unsafe.Pointer(db)).FnProgressOps {
				if (*(*func(*libc.TLS, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*Tsqlite3)(unsafe.Pointer(db)).FxProgress})))(tls, (*Tsqlite3)(unsafe.Pointer(db)).FpProgressArg) != 0 {
					(*TParse)(unsafe.Pointer(p)).FnErr = (*TParse)(unsafe.Pointer(p)).FnErr + 1
					(*TParse)(unsafe.Pointer(p)).Frc = int32(SQLITE_INTERRUPT)
				}
				(*TParse)(unsafe.Pointer(p)).FnProgressSteps = uint32(0)
			}
		}
	}
}

// C documentation
//
//	/*
//	** Check to see if pExpr references any tables in pSrcList.
//	** Possible return values:
//	**
//	**    1         pExpr does references a table in pSrcList.
//	**
//	**    0         pExpr references some table that is not defined in either
//	**              pSrcList or in subqueries of pExpr itself.
//	**
//	**   -1         pExpr only references no tables at all, or it only
//	**              references tables defined in subqueries of pExpr itself.
//	**
//	** As currently used, pExpr is always an aggregate function call.  That
//	** fact is exploited for efficiency.
//	*/
func _sqlite3ReferencesSrcList(tls *libc.TLS, pParse uintptr, pExpr uintptr, pSrcList uintptr) (r int32) {
	bp := tls.Alloc(48)
	defer tls.Free(48)
	var _ /* w at bp+0 */ TWalker
	var _ /* x at bp+28 */ TRefSrcList
	libc.Xmemset(tls, bp, 0, uint32(28))
	libc.Xmemset(tls, bp+28, 0, uint32(20))
	(**(**TWalker)(__ccgo_up(bp))).FxExprCallback = __ccgo_fp(_exprRefToSrcList)
	(**(**TWalker)(__ccgo_up(bp))).FxSelectCallback = __ccgo_fp(_selectRefEnter)
	(**(**TWalker)(__ccgo_up(bp))).FxSelectCallback2 = __ccgo_fp(_selectRefLeave)
	*(*uintptr)(unsafe.Pointer(bp + 24)) = bp + 28
	(**(**TRefSrcList)(__ccgo_up(bp + 28))).Fdb = (*TParse)(unsafe.Pointer(pParse)).Fdb
	(**(**TRefSrcList)(__ccgo_up(bp + 28))).FpRef = pSrcList
	_sqlite3WalkExprList(tls, bp, *(*uintptr)(unsafe.Pointer(pExpr + 20)))
	if (*TExpr)(unsafe.Pointer(pExpr)).FpLeft != 0 {
		_sqlite3WalkExprList(tls, bp, *(*uintptr)(unsafe.Pointer((*TExpr)(unsafe.Pointer(pExpr)).FpLeft + 20)))
	}
	if (*TExpr)(unsafe.Pointer(pExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_WinFunc)) != uint32(0) {
		_sqlite3WalkExpr(tls, bp, (*TWindow)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(&(*TExpr)(unsafe.Pointer(pExpr)).Fy)))).FpFilter)
	}
	if (**(**TRefSrcList)(__ccgo_up(bp + 28))).FaiExclude != 0 {
		_sqlite3DbNNFreeNN(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, (**(**TRefSrcList)(__ccgo_up(bp + 28))).FaiExclude)
	}
	if libc.Int32FromUint16((**(**TWalker)(__ccgo_up(bp))).FeCode)&int32(0x01) != 0 {
		return int32(1)
	} else {
		if (**(**TWalker)(__ccgo_up(bp))).FeCode != 0 {
			return 0
		} else {
			return -int32(1)
		}
	}
	return r
}

// C documentation
//
//	/*
//	** Resolve names in expressions that can only reference a single table
//	** or which cannot reference any tables at all.  Examples:
//	**
//	**                                                    "type" flag
//	**                                                    ------------
//	**    (1)   CHECK constraints                         NC_IsCheck
//	**    (2)   WHERE clauses on partial indices          NC_PartIdx
//	**    (3)   Expressions in indexes on expressions     NC_IdxExpr
//	**    (4)   Expression arguments to VACUUM INTO.      0
//	**    (5)   GENERATED ALWAYS as expressions           NC_GenCol
//	**
//	** In all cases except (4), the Expr.iTable value for Expr.op==TK_COLUMN
//	** nodes of the expression is set to -1 and the Expr.iColumn value is
//	** set to the column number.  In case (4), TK_COLUMN nodes cause an error.
//	**
//	** Any errors cause an error message to be set in pParse.
//	*/
func _sqlite3ResolveSelfReference(tls *libc.TLS, pParse uintptr, pTab uintptr, type1 int32, pExpr uintptr, pList uintptr) (r int32) {
	bp := tls.Alloc(96)
	defer tls.Free(96)
	var pSrc uintptr
	var rc, v1 int32
	var _ /* sNC at bp+0 */ TNameContext
	var _ /* uSrc at bp+36 */ struct {
		FsrcSpace    [0][56]Tu8
		FsSrc        TSrcList
		F__ccgo_pad2 [48]byte
	}
	_, _, _ = pSrc, rc, v1
	libc.Xmemset(tls, bp, 0, uint32(36))
	libc.Xmemset(tls, bp+36, 0, uint32(56))
	pSrc = bp + 36
	if pTab != 0 {
		(*TSrcList)(unsafe.Pointer(pSrc)).FnSrc = int32(1)
		(*(*TSrcItem)(unsafe.Pointer(pSrc + 8))).FzName = (*TTable)(unsafe.Pointer(pTab)).FzName
		(*(*TSrcItem)(unsafe.Pointer(pSrc + 8))).FpSTab = pTab
		(*(*TSrcItem)(unsafe.Pointer(pSrc + 8))).FiCursor = -int32(1)
		if (*TTable)(unsafe.Pointer(pTab)).FpSchema != (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer((*TParse)(unsafe.Pointer(pParse)).Fdb)).FaDb + 1*16))).FpSchema {
			/* Cause EP_FromDDL to be set on TK_FUNCTION nodes of non-TEMP
			 ** schema elements */
			type1 = type1 | int32(NC_FromDDL)
		}
	}
	(**(**TNameContext)(__ccgo_up(bp))).FpParse = pParse
	(**(**TNameContext)(__ccgo_up(bp))).FpSrcList = pSrc
	(**(**TNameContext)(__ccgo_up(bp))).FncFlags = type1 | int32(NC_IsDDL)
	v1 = _sqlite3ResolveExprNames(tls, bp, pExpr)
	rc = v1
	if v1 != SQLITE_OK {
		return rc
	}
	if pList != 0 {
		rc = _sqlite3ResolveExprListNames(tls, bp, pList)
	}
	return rc
}

// C documentation
//
//	/*
//	** Given a SELECT statement, generate a Table structure that describes
//	** the result set of that SELECT.
//	*/
func _sqlite3ResultSetOfSelect(tls *libc.TLS, pParse uintptr, pSelect uintptr, aff int8) (r uintptr) {
	var db, pTab uintptr
	var savedFlags Tu64
	_, _, _ = db, pTab, savedFlags
	db = (*TParse)(unsafe.Pointer(pParse)).Fdb
	savedFlags = (*Tsqlite3)(unsafe.Pointer(db)).Fflags
	**(**Tu64)(__ccgo_up(db + 28)) &= ^libc.Uint64FromInt32(SQLITE_FullColNames)
	**(**Tu64)(__ccgo_up(db + 28)) |= uint64(SQLITE_ShortColNames)
	_sqlite3SelectPrep(tls, pParse, pSelect, uintptr(0))
	(*Tsqlite3)(unsafe.Pointer(db)).Fflags = savedFlags
	if (*TParse)(unsafe.Pointer(pParse)).FnErr != 0 {
		return uintptr(0)
	}
	for (*TSelect)(unsafe.Pointer(pSelect)).FpPrior != 0 {
		pSelect = (*TSelect)(unsafe.Pointer(pSelect)).FpPrior
	}
	pTab = _sqlite3DbMallocZero(tls, db, uint64(80))
	if pTab == uintptr(0) {
		return uintptr(0)
	}
	(*TTable)(unsafe.Pointer(pTab)).FnTabRef = uint32(1)
	(*TTable)(unsafe.Pointer(pTab)).FzName = uintptr(0)
	(*TTable)(unsafe.Pointer(pTab)).FnRowLogEst = int16(200)
	_sqlite3ColumnsFromExprList(tls, pParse, (*TSelect)(unsafe.Pointer(pSelect)).FpEList, pTab+34, pTab+4)
	_sqlite3SubqueryColumnTypes(tls, pParse, pTab, pSelect, aff)
	(*TTable)(unsafe.Pointer(pTab)).FiPKey = int16(-int32(1))
	if (*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0 {
		_sqlite3DeleteTable(tls, db, pTab)
		return uintptr(0)
	}
	return pTab
}

// C documentation
//
//	/*
//	** Rollback all database files.  If tripCode is not SQLITE_OK, then
//	** any write cursors are invalidated ("tripped" - as in "tripping a circuit
//	** breaker") and made to return tripCode if there are any further
//	** attempts to use that cursor.  Read cursors remain open and valid
//	** but are "saved" in case the table pages are moved around.
//	*/
func _sqlite3RollbackAll(tls *libc.TLS, db uintptr, tripCode int32) {
	var i, inTrans, schemaChange int32
	var p uintptr
	_, _, _, _ = i, inTrans, p, schemaChange
	inTrans = 0
	_sqlite3BeginBenignMalloc(tls)
	/* Obtain all b-tree mutexes before making any calls to BtreeRollback().
	 ** This is important in case the transaction being rolled back has
	 ** modified the database schema. If the b-tree mutexes are not taken
	 ** here, then another shared-cache connection might sneak in between
	 ** the database rollback and schema reset, which can cause false
	 ** corruption reports in some cases.  */
	_sqlite3BtreeEnterAll(tls, db)
	schemaChange = libc.BoolInt32((*Tsqlite3)(unsafe.Pointer(db)).FmDbFlags&uint32(DBFLAG_SchemaChange) != uint32(0) && libc.Int32FromUint8((*Tsqlite3)(unsafe.Pointer(db)).Finit1.Fbusy) == 0)
	i = 0
	for {
		if !(i < (*Tsqlite3)(unsafe.Pointer(db)).FnDb) {
			break
		}
		p = (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(i)*16))).FpBt
		if p != 0 {
			if _sqlite3BtreeTxnState(tls, p) == int32(SQLITE_TXN_WRITE) {
				inTrans = int32(1)
			}
			_sqlite3BtreeRollback(tls, p, tripCode, libc.BoolInt32(!(schemaChange != 0)))
		}
		goto _1
	_1:
		;
		i = i + 1
	}
	_sqlite3VtabRollback(tls, db)
	_sqlite3EndBenignMalloc(tls)
	if schemaChange != 0 {
		_sqlite3ExpirePreparedStatements(tls, db, 0)
		_sqlite3ResetAllSchemasOfConnection(tls, db)
	}
	_sqlite3BtreeLeaveAll(tls, db)
	/* Any deferred constraint violations have now been resolved. */
	(*Tsqlite3)(unsafe.Pointer(db)).FnDeferredCons = 0
	(*Tsqlite3)(unsafe.Pointer(db)).FnDeferredImmCons = 0
	**(**Tu64)(__ccgo_up(db + 28)) &= ^(libc.Uint64FromInt32(SQLITE_DeferFKs) | libc.Uint64FromInt32(libc.Int32FromInt32(0x00002))<<libc.Int32FromInt32(32))
	/* If one has been configured, invoke the rollback-hook callback */
	if (*Tsqlite3)(unsafe.Pointer(db)).FxRollbackCallback != 0 && (inTrans != 0 || !((*Tsqlite3)(unsafe.Pointer(db)).FautoCommit != 0)) {
		(*(*func(*libc.TLS, uintptr))(unsafe.Pointer(&struct{ uintptr }{(*Tsqlite3)(unsafe.Pointer(db)).FxRollbackCallback})))(tls, (*Tsqlite3)(unsafe.Pointer(db)).FpRollbackArg)
	}
}

/*
** Return a static string containing the name corresponding to the error code
** specified in the argument.
 */

// C documentation
//
//	/*
//	** Free all resources held by the schema structure. The void* argument points
//	** at a Schema struct. This function does not call sqlite3DbFree(db, ) on the
//	** pointer itself, it just cleans up subsidiary resources (i.e. the contents
//	** of the schema hash tables).
//	**
//	** The Schema.cache_size variable is not cleared.
//	*/
func _sqlite3SchemaClear(tls *libc.TLS, p uintptr) {
	bp := tls.Alloc(608)
	defer tls.Free(608)
	var pElem, pSchema, pTab, v3 uintptr
	var _ /* temp1 at bp+0 */ THash
	var _ /* temp2 at bp+16 */ THash
	var _ /* xdb at bp+32 */ Tsqlite3
	_, _, _, _ = pElem, pSchema, pTab, v3
	pSchema = p
	libc.Xmemset(tls, bp+32, 0, uint32(576))
	**(**THash)(__ccgo_up(bp)) = (*TSchema)(unsafe.Pointer(pSchema)).FtblHash
	**(**THash)(__ccgo_up(bp + 16)) = (*TSchema)(unsafe.Pointer(pSchema)).FtrigHash
	_sqlite3HashInit(tls, pSchema+40)
	_sqlite3HashClear(tls, pSchema+24)
	pElem = (*THash)(unsafe.Pointer(bp + 16)).Ffirst
	for {
		if !(pElem != 0) {
			break
		}
		_sqlite3DeleteTrigger(tls, bp+32, (*THashElem)(unsafe.Pointer(pElem)).Fdata)
		goto _1
	_1:
		;
		pElem = (*THashElem)(unsafe.Pointer(pElem)).Fnext
	}
	_sqlite3HashClear(tls, bp+16)
	_sqlite3HashInit(tls, pSchema+8)
	pElem = (*THash)(unsafe.Pointer(bp)).Ffirst
	for {
		if !(pElem != 0) {
			break
		}
		pTab = (*THashElem)(unsafe.Pointer(pElem)).Fdata
		_sqlite3DeleteTable(tls, bp+32, pTab)
		goto _2
	_2:
		;
		pElem = (*THashElem)(unsafe.Pointer(pElem)).Fnext
	}
	_sqlite3HashClear(tls, bp)
	_sqlite3HashClear(tls, pSchema+56)
	(*TSchema)(unsafe.Pointer(pSchema)).FpSeqTab = uintptr(0)
	if libc.Int32FromUint16((*TSchema)(unsafe.Pointer(pSchema)).FschemaFlags)&int32(DB_SchemaLoaded) != 0 {
		(*TSchema)(unsafe.Pointer(pSchema)).FiGeneration = (*TSchema)(unsafe.Pointer(pSchema)).FiGeneration + 1
	}
	v3 = pSchema + 78
	*(*Tu16)(unsafe.Pointer(v3)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v3))) & ^(libc.Int32FromInt32(DB_SchemaLoaded) | libc.Int32FromInt32(DB_ResetWanted)))
}

// C documentation
//
//	/*
//	** This function is used to allocate and populate UnpackedRecord
//	** structures intended to be compared against sample index keys stored
//	** in the sqlite_stat4 table.
//	**
//	** A single call to this function populates zero or more fields of the
//	** record starting with field iVal (fields are numbered from left to
//	** right starting with 0). A single field is populated if:
//	**
//	**  * (pExpr==0). In this case the value is assumed to be an SQL NULL,
//	**
//	**  * The expression is a bound variable, and this is a reprepare, or
//	**
//	**  * The sqlite3ValueFromExpr() function is able to extract a value
//	**    from the expression (i.e. the expression is a literal value).
//	**
//	** Or, if pExpr is a TK_VECTOR, one field is populated for each of the
//	** vector components that match either of the two latter criteria listed
//	** above.
//	**
//	** Before any value is appended to the record, the affinity of the
//	** corresponding column within index pIdx is applied to it. Before
//	** this function returns, output parameter *pnExtract is set to the
//	** number of values appended to the record.
//	**
//	** When this function is called, *ppRec must either point to an object
//	** allocated by an earlier call to this function, or must be NULL. If it
//	** is NULL and a value can be successfully extracted, a new UnpackedRecord
//	** is allocated (and *ppRec set to point to it) before returning.
//	**
//	** Unless an error is encountered, SQLITE_OK is returned. It is not an
//	** error if a value cannot be extracted from pExpr. If an error does
//	** occur, an SQLite error code is returned.
//	*/
func _sqlite3Stat4ProbeSetValue(tls *libc.TLS, pParse uintptr, pIdx uintptr, ppRec uintptr, pExpr uintptr, nElem int32, iVal int32, pnExtract uintptr) (r int32) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var aff Tu8
	var i, nExtract, rc int32
	var pElem, v2 uintptr
	var _ /* alloc at bp+0 */ TValueNewStat4Ctx
	var _ /* pVal at bp+16 */ uintptr
	_, _, _, _, _, _ = aff, i, nExtract, pElem, rc, v2
	rc = SQLITE_OK
	nExtract = 0
	if pExpr == uintptr(0) || libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) != int32(TK_SELECT) {
		(**(**TValueNewStat4Ctx)(__ccgo_up(bp))).FpParse = pParse
		(**(**TValueNewStat4Ctx)(__ccgo_up(bp))).FpIdx = pIdx
		(**(**TValueNewStat4Ctx)(__ccgo_up(bp))).FppRec = ppRec
		i = 0
		for {
			if !(i < nElem) {
				break
			}
			**(**uintptr)(__ccgo_up(bp + 16)) = uintptr(0)
			if pExpr != 0 {
				v2 = _sqlite3VectorFieldSubexpr(tls, pExpr, i)
			} else {
				v2 = uintptr(0)
			}
			pElem = v2
			aff = libc.Uint8FromInt8(_sqlite3IndexColumnAffinity(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, pIdx, iVal+i))
			(**(**TValueNewStat4Ctx)(__ccgo_up(bp))).FiVal = iVal + i
			rc = _stat4ValueFromExpr(tls, pParse, pElem, aff, bp, bp+16)
			if !(**(**uintptr)(__ccgo_up(bp + 16)) != 0) {
				break
			}
			nExtract = nExtract + 1
			goto _1
		_1:
			;
			i = i + 1
		}
	}
	**(**int32)(__ccgo_up(pnExtract)) = nExtract
	return rc
}

// C documentation
//
//	/*
//	** Execute the statement pStmt, either until a row of data is ready, the
//	** statement is completely executed or an error occurs.
//	**
//	** This routine implements the bulk of the logic behind the sqlite_step()
//	** API.  The only thing omitted is the automatic recompile if a
//	** schema change has occurred.  That detail is handled by the
//	** outer sqlite3_step() wrapper procedure.
//	*/
func _sqlite3Step(tls *libc.TLS, p uintptr) (r int32) {
	var db uintptr
	var rc int32
	_, _ = db, rc
	db = (*TVdbe)(unsafe.Pointer(p)).Fdb
	if libc.Int32FromUint8((*TVdbe)(unsafe.Pointer(p)).FeVdbeState) != int32(VDBE_RUN_STATE) {
		goto restart_step
	restart_step:
		;
		if libc.Int32FromUint8((*TVdbe)(unsafe.Pointer(p)).FeVdbeState) == int32(VDBE_READY_STATE) {
			if int32(Tbft(*(*uint16)(unsafe.Pointer(p + 144))&0x3>>0)) != 0 {
				(*TVdbe)(unsafe.Pointer(p)).Frc = int32(SQLITE_SCHEMA)
				rc = int32(SQLITE_ERROR)
				if libc.Int32FromUint8((*TVdbe)(unsafe.Pointer(p)).FprepFlags)&int32(SQLITE_PREPARE_SAVESQL) != 0 {
					/* If this statement was prepared using saved SQL and an
					 ** error has occurred, then return the error code in p->rc to the
					 ** caller. Set the error code in the database handle to the same
					 ** value.
					 */
					rc = _sqlite3VdbeTransferError(tls, p)
				}
				goto end_of_step
			}
			/* If there are no other statements currently running, then
			 ** reset the interrupt flag.  This prevents a call to sqlite3_interrupt
			 ** from interrupting a statement that has not yet started.
			 */
			if (*Tsqlite3)(unsafe.Pointer(db)).FnVdbeActive == 0 {
				libc.AtomicStoreNInt32(db+308, libc.Int32FromInt32(0), libc.Int32FromInt32(__ATOMIC_RELAXED))
			}
			if libc.Int32FromUint8((*Tsqlite3)(unsafe.Pointer(db)).FmTrace)&(libc.Int32FromInt32(SQLITE_TRACE_PROFILE)|libc.Int32FromInt32(SQLITE_TRACE_XPROFILE)) != 0 && !((*Tsqlite3)(unsafe.Pointer(db)).Finit1.Fbusy != 0) && (*TVdbe)(unsafe.Pointer(p)).FzSql != 0 {
				_sqlite3OsCurrentTimeInt64(tls, (*Tsqlite3)(unsafe.Pointer(db)).FpVfs, p+128)
			} else {
			}
			(*Tsqlite3)(unsafe.Pointer(db)).FnVdbeActive = (*Tsqlite3)(unsafe.Pointer(db)).FnVdbeActive + 1
			if int32(Tbft(*(*uint16)(unsafe.Pointer(p + 144))&0x40>>6)) == 0 {
				(*Tsqlite3)(unsafe.Pointer(db)).FnVdbeWrite = (*Tsqlite3)(unsafe.Pointer(db)).FnVdbeWrite + 1
			}
			if int32(Tbft(*(*uint16)(unsafe.Pointer(p + 144))&0x80>>7)) != 0 {
				(*Tsqlite3)(unsafe.Pointer(db)).FnVdbeRead = (*Tsqlite3)(unsafe.Pointer(db)).FnVdbeRead + 1
			}
			(*TVdbe)(unsafe.Pointer(p)).Fpc = 0
			(*TVdbe)(unsafe.Pointer(p)).FeVdbeState = uint8(VDBE_RUN_STATE)
		} else {
			if libc.Int32FromUint8((*TVdbe)(unsafe.Pointer(p)).FeVdbeState) == int32(VDBE_HALT_STATE) {
				/* We used to require that sqlite3_reset() be called before retrying
				 ** sqlite3_step() after any error or after SQLITE_DONE.  But beginning
				 ** with version 3.7.0, we changed this so that sqlite3_reset() would
				 ** be called automatically instead of throwing the SQLITE_MISUSE error.
				 ** This "automatic-reset" change is not technically an incompatibility,
				 ** since any application that receives an SQLITE_MISUSE is broken by
				 ** definition.
				 **
				 ** Nevertheless, some published applications that were originally written
				 ** for version 3.6.23 or earlier do in fact depend on SQLITE_MISUSE
				 ** returns, and those were broken by the automatic-reset change.  As a
				 ** a work-around, the SQLITE_OMIT_AUTORESET compile-time restores the
				 ** legacy behavior of returning SQLITE_MISUSE for cases where the
				 ** previous sqlite3_step() returned something other than a SQLITE_LOCKED
				 ** or SQLITE_BUSY error.
				 */
				Xsqlite3_reset(tls, p)
				goto restart_step
			}
		}
	}
	if int32(Tbft(*(*uint16)(unsafe.Pointer(p + 144))&0xc>>2)) != 0 {
		rc = _sqlite3VdbeList(tls, p)
	} else {
		(*Tsqlite3)(unsafe.Pointer(db)).FnVdbeExec = (*Tsqlite3)(unsafe.Pointer(db)).FnVdbeExec + 1
		rc = _sqlite3VdbeExec(tls, p)
		(*Tsqlite3)(unsafe.Pointer(db)).FnVdbeExec = (*Tsqlite3)(unsafe.Pointer(db)).FnVdbeExec - 1
	}
	if rc == int32(SQLITE_ROW) {
		(*Tsqlite3)(unsafe.Pointer(db)).FerrCode = int32(SQLITE_ROW)
		return int32(SQLITE_ROW)
	} else {
		/* If the statement completed successfully, invoke the profile callback */
		if (*TVdbe)(unsafe.Pointer(p)).FstartTime > 0 {
			_invokeProfileCallback(tls, db, p)
		}
		(*TVdbe)(unsafe.Pointer(p)).FpResultRow = uintptr(0)
		if rc == int32(SQLITE_DONE) && (*Tsqlite3)(unsafe.Pointer(db)).FautoCommit != 0 {
			(*TVdbe)(unsafe.Pointer(p)).Frc = _doWalCallbacks(tls, db)
			if (*TVdbe)(unsafe.Pointer(p)).Frc != SQLITE_OK {
				rc = int32(SQLITE_ERROR)
			}
		} else {
			if rc != int32(SQLITE_DONE) && libc.Int32FromUint8((*TVdbe)(unsafe.Pointer(p)).FprepFlags)&int32(SQLITE_PREPARE_SAVESQL) != 0 {
				/* If this statement was prepared using saved SQL and an
				 ** error has occurred, then return the error code in p->rc to the
				 ** caller. Set the error code in the database handle to the same value.
				 */
				rc = _sqlite3VdbeTransferError(tls, p)
			}
		}
	}
	(*Tsqlite3)(unsafe.Pointer(db)).FerrCode = rc
	if int32(SQLITE_NOMEM) == _sqlite3ApiExit(tls, (*TVdbe)(unsafe.Pointer(p)).Fdb, (*TVdbe)(unsafe.Pointer(p)).Frc) {
		(*TVdbe)(unsafe.Pointer(p)).Frc = int32(SQLITE_NOMEM)
		if libc.Int32FromUint8((*TVdbe)(unsafe.Pointer(p)).FprepFlags)&int32(SQLITE_PREPARE_SAVESQL) != 0 {
			rc = (*TVdbe)(unsafe.Pointer(p)).Frc
		}
	}
	goto end_of_step
end_of_step:
	;
	/* There are only a limited number of result codes allowed from the
	 ** statements prepared using the legacy sqlite3_prepare() interface */
	return rc & (*Tsqlite3)(unsafe.Pointer(db)).FerrMask
}

// C documentation
//
//	/*
//	** Return the current time for a statement.  If the current time
//	** is requested more than once within the same run of a single prepared
//	** statement, the exact same time is returned for each invocation regardless
//	** of the amount of time that elapses between invocations.  In other words,
//	** the time returned is always the time of the first call.
//	*/
func _sqlite3StmtCurrentTime(tls *libc.TLS, p uintptr) (r Tsqlite3_int64) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var piTime, v1 uintptr
	var rc int32
	var _ /* iTime at bp+0 */ Tsqlite3_int64
	_, _, _ = piTime, rc, v1
	**(**Tsqlite3_int64)(__ccgo_up(bp)) = 0
	if (*Tsqlite3_context)(unsafe.Pointer(p)).FpVdbe != uintptr(0) {
		v1 = (*Tsqlite3_context)(unsafe.Pointer(p)).FpVdbe + 52
	} else {
		v1 = bp
	}
	piTime = v1
	if **(**Tsqlite3_int64)(__ccgo_up(piTime)) == 0 {
		rc = _sqlite3OsCurrentTimeInt64(tls, (*Tsqlite3)(unsafe.Pointer((*TMem)(unsafe.Pointer((*Tsqlite3_context)(unsafe.Pointer(p)).FpOut)).Fdb)).FpVfs, piTime)
		if rc != 0 {
			**(**Tsqlite3_int64)(__ccgo_up(piTime)) = 0
		}
	}
	return **(**Tsqlite3_int64)(__ccgo_up(piTime))
}

// C documentation
//
//	/*
//	** Compute an affinity string for a table.   Space is obtained
//	** from sqlite3DbMalloc().  The caller is responsible for freeing
//	** the space when done.
//	*/
func _sqlite3TableAffinityStr(tls *libc.TLS, db uintptr, pTab uintptr) (r uintptr) {
	var i, j, v2, v3 int32
	var zColAff uintptr
	_, _, _, _, _ = i, j, zColAff, v2, v3
	zColAff = _sqlite3DbMallocRaw(tls, db, libc.Uint64FromInt32(int32((*TTable)(unsafe.Pointer(pTab)).FnCol)+int32(1)))
	if zColAff != 0 {
		v2 = libc.Int32FromInt32(0)
		j = v2
		i = v2
		for {
			if !(i < int32((*TTable)(unsafe.Pointer(pTab)).FnCol)) {
				break
			}
			if libc.Int32FromUint16((**(**TColumn)(__ccgo_up((*TTable)(unsafe.Pointer(pTab)).FaCol + uintptr(i)*12))).FcolFlags)&int32(COLFLAG_VIRTUAL) == 0 {
				v3 = j
				j = j + 1
				**(**int8)(__ccgo_up(zColAff + uintptr(v3))) = (**(**TColumn)(__ccgo_up((*TTable)(unsafe.Pointer(pTab)).FaCol + uintptr(i)*12))).Faffinity
			}
			goto _1
		_1:
			;
			i = i + 1
		}
		for cond := true; cond; cond = j >= 0 && int32(**(**int8)(__ccgo_up(zColAff + uintptr(j)))) <= int32(SQLITE_AFF_BLOB) {
			v2 = j
			j = j - 1
			**(**int8)(__ccgo_up(zColAff + uintptr(v2))) = 0
		}
	}
	return zColAff
}

// C documentation
//
//	/*
//	** Add a new name/number pair to a VList.  This might require that the
//	** VList object be reallocated, so return the new VList.  If an OOM
//	** error occurs, the original VList returned and the
//	** db->mallocFailed flag is set.
//	**
//	** A VList is really just an array of integers.  To destroy a VList,
//	** simply pass it to sqlite3DbFree().
//	**
//	** The first integer is the number of integers allocated for the whole
//	** VList.  The second integer is the number of integers actually used.
//	** Each name/number pair is encoded by subsequent groups of 3 or more
//	** integers.
//	**
//	** Each name/number pair starts with two integers which are the numeric
//	** value for the pair and the size of the name/number pair, respectively.
//	** The text name overlays one or more following integers.  The text name
//	** is always zero-terminated.
//	**
//	** Conceptually:
//	**
//	**    struct VList {
//	**      int nAlloc;   // Number of allocated slots
//	**      int nUsed;    // Number of used slots
//	**      struct VListEntry {
//	**        int iValue;    // Value for this entry
//	**        int nSlot;     // Slots used by this entry
//	**        // ... variable name goes here
//	**      } a[0];
//	**    }
//	**
//	** During code generation, pointers to the variable names within the
//	** VList are taken.  When that happens, nAlloc is set to zero as an
//	** indication that the VList may never again be enlarged, since the
//	** accompanying realloc() would invalidate the pointers.
//	*/
func _sqlite3VListAdd(tls *libc.TLS, db uintptr, pIn uintptr, zName uintptr, nName int32, iVal int32) (r uintptr) {
	var i, nInt int32
	var nAlloc Tsqlite3_int64
	var pOut, z uintptr
	var v1 int64
	_, _, _, _, _, _ = i, nAlloc, nInt, pOut, z, v1 /* Index in pIn[] where zName is stored */
	nInt = nName/int32(4) + int32(3)
	/* Verify ok to add new elements */
	if pIn == uintptr(0) || **(**TVList)(__ccgo_up(pIn + 1*4))+nInt > **(**TVList)(__ccgo_up(pIn)) {
		if pIn != 0 {
			v1 = int64(2) * int64(**(**TVList)(__ccgo_up(pIn)))
		} else {
			v1 = int64(10)
		}
		/* Enlarge the allocation */
		nAlloc = v1 + int64(nInt)
		pOut = _sqlite3DbRealloc(tls, db, pIn, libc.Uint64FromInt64(nAlloc*int64(4)))
		if pOut == uintptr(0) {
			return pIn
		}
		if pIn == uintptr(0) {
			**(**TVList)(__ccgo_up(pOut + 1*4)) = int32(2)
		}
		pIn = pOut
		**(**TVList)(__ccgo_up(pIn)) = int32(nAlloc)
	}
	i = **(**TVList)(__ccgo_up(pIn + 1*4))
	**(**TVList)(__ccgo_up(pIn + uintptr(i)*4)) = iVal
	**(**TVList)(__ccgo_up(pIn + uintptr(i+int32(1))*4)) = nInt
	z = pIn + uintptr(i+int32(2))*4
	**(**TVList)(__ccgo_up(pIn + 1*4)) = i + nInt
	libc.Xmemcpy(tls, z, zName, libc.Uint32FromInt32(nName))
	**(**int8)(__ccgo_up(z + uintptr(nName))) = 0
	return pIn
}

// C documentation
//
//	/*
//	** Return the number of the variable named zName, if it is in VList.
//	** or return 0 if there is no such variable.
//	*/
func _sqlite3VListNameToNum(tls *libc.TLS, pIn uintptr, zName uintptr, nName int32) (r int32) {
	var i, mx int32
	var z uintptr
	_, _, _ = i, mx, z
	if pIn == uintptr(0) {
		return 0
	}
	mx = **(**TVList)(__ccgo_up(pIn + 1*4))
	i = int32(2)
	for cond := true; cond; cond = i < mx {
		z = pIn + uintptr(i+int32(2))*4
		if libc.Xstrncmp(tls, z, zName, libc.Uint32FromInt32(nName)) == 0 && int32(**(**int8)(__ccgo_up(z + uintptr(nName)))) == 0 {
			return **(**TVList)(__ccgo_up(pIn + uintptr(i)*4))
		}
		i = i + **(**TVList)(__ccgo_up(pIn + uintptr(i+int32(1))*4))
	}
	return 0
}

/************** End of util.c ************************************************/
/************** Begin file hash.c ********************************************/
/*
** 2001 September 22
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This is the implementation of generic hash-tables
** used in SQLite.
 */
/* #include "sqliteInt.h" */
/* #include <assert.h> */

// C documentation
//
//	/*
//	** Print into memory obtained from sqliteMalloc().  Use the internal
//	** %-conversion extensions.
//	*/
func _sqlite3VMPrintf(tls *libc.TLS, db uintptr, zFormat uintptr, ap Tva_list) (r uintptr) {
	bp := tls.Alloc(96)
	defer tls.Free(96)
	var z uintptr
	var _ /* acc at bp+72 */ TStrAccum
	var _ /* zBase at bp+0 */ [70]int8
	_ = z
	_sqlite3StrAccumInit(tls, bp+72, db, bp, int32(70), **(**int32)(__ccgo_up(db + 116)))
	(**(**TStrAccum)(__ccgo_up(bp + 72))).FprintfFlags = uint8(SQLITE_PRINTF_INTERNAL)
	Xsqlite3_str_vappendf(tls, bp+72, zFormat, ap)
	z = _sqlite3StrAccumFinish(tls, bp+72)
	if libc.Int32FromUint8((**(**TStrAccum)(__ccgo_up(bp + 72))).FaccError) == int32(SQLITE_NOMEM) {
		_sqlite3OomFault(tls, db)
	}
	return z
}

// C documentation
//
//	/*
//	** Add a whole list of operations to the operation stack.  Return a
//	** pointer to the first operation inserted.
//	**
//	** Non-zero P2 arguments to jump instructions are automatically adjusted
//	** so that the jump target is relative to the first operation inserted.
//	*/
func _sqlite3VdbeAddOpList(tls *libc.TLS, p uintptr, nOp int32, aOp uintptr, iLineno int32) (r uintptr) {
	var i int32
	var pFirst, pOut, v1 uintptr
	_, _, _, _ = i, pFirst, pOut, v1
	if (*TVdbe)(unsafe.Pointer(p)).FnOp+nOp > (*TVdbe)(unsafe.Pointer(p)).FnOpAlloc && _growOpArray(tls, p, nOp) != 0 {
		return uintptr(0)
	}
	v1 = (*TVdbe)(unsafe.Pointer(p)).FaOp + uintptr((*TVdbe)(unsafe.Pointer(p)).FnOp)*20
	pOut = v1
	pFirst = v1
	i = 0
	for {
		if !(i < nOp) {
			break
		}
		(*TVdbeOp)(unsafe.Pointer(pOut)).Fopcode = (*TVdbeOpList)(unsafe.Pointer(aOp)).Fopcode
		(*TVdbeOp)(unsafe.Pointer(pOut)).Fp1 = int32((*TVdbeOpList)(unsafe.Pointer(aOp)).Fp1)
		(*TVdbeOp)(unsafe.Pointer(pOut)).Fp2 = int32((*TVdbeOpList)(unsafe.Pointer(aOp)).Fp2)
		if libc.Int32FromUint8(_sqlite3OpcodeProperty[(*TVdbeOpList)(unsafe.Pointer(aOp)).Fopcode])&int32(OPFLG_JUMP) != 0 && int32((*TVdbeOpList)(unsafe.Pointer(aOp)).Fp2) > 0 {
			**(**int32)(__ccgo_up(pOut + 8)) += (*TVdbe)(unsafe.Pointer(p)).FnOp
		}
		(*TVdbeOp)(unsafe.Pointer(pOut)).Fp3 = int32((*TVdbeOpList)(unsafe.Pointer(aOp)).Fp3)
		(*TVdbeOp)(unsafe.Pointer(pOut)).Fp4type = P4_NOTUSED
		*(*uintptr)(unsafe.Pointer(pOut + 16)) = uintptr(0)
		(*TVdbeOp)(unsafe.Pointer(pOut)).Fp5 = uint16(0)
		_ = iLineno
		goto _2
	_2:
		;
		i = i + 1
		aOp += 4
		pOut += 20
	}
	**(**int32)(__ccgo_up(p + 104)) += nOp
	return pFirst
}

// C documentation
//
//	/*
//	** Allocate sufficient space for an UnpackedRecord structure large enough
//	** to hold a decoded index record for pKeyInfo.
//	**
//	** The space is allocated using sqlite3DbMallocRaw().  If an OOM error
//	** occurs, NULL is returned.
//	*/
func _sqlite3VdbeAllocUnpackedRecord(tls *libc.TLS, pKeyInfo uintptr) (r uintptr) {
	var nByte Tu64
	var p uintptr
	_, _ = nByte, p /* Number of bytes required for *p */
	nByte = uint64((libc.Uint32FromInt64(28)+libc.Uint32FromInt32(7))&libc.Uint32FromInt32(^libc.Int32FromInt32(7)) + uint32(40)*libc.Uint32FromInt32(libc.Int32FromUint16((*TKeyInfo)(unsafe.Pointer(pKeyInfo)).FnKeyField)+libc.Int32FromInt32(1)))
	p = _sqlite3DbMallocRaw(tls, (*TKeyInfo)(unsafe.Pointer(pKeyInfo)).Fdb, nByte)
	if !(p != 0) {
		return uintptr(0)
	}
	(*TUnpackedRecord)(unsafe.Pointer(p)).FaMem = p + uintptr((libc.Uint32FromInt64(28)+libc.Uint32FromInt32(7))&libc.Uint32FromInt32(^libc.Int32FromInt32(7)))
	(*TUnpackedRecord)(unsafe.Pointer(p)).FpKeyInfo = pKeyInfo
	(*TUnpackedRecord)(unsafe.Pointer(p)).FnField = libc.Uint16FromInt32(libc.Int32FromUint16((*TKeyInfo)(unsafe.Pointer(pKeyInfo)).FnKeyField) + int32(1))
	return p
}

// C documentation
//
//	/*
//	** Set a flag in the vdbe to update the change counter when it is finalised
//	** or reset.
//	*/
func _sqlite3VdbeCountChanges(tls *libc.TLS, v uintptr) {
	libc.SetBitFieldPtr16Uint32(v+144, libc.Uint32FromInt32(1), 4, 0x10)
}

// C documentation
//
//	/*
//	** Create a new virtual database engine.
//	*/
func _sqlite3VdbeCreate(tls *libc.TLS, pParse uintptr) (r uintptr) {
	var db, p uintptr
	_, _ = db, p
	db = (*TParse)(unsafe.Pointer(pParse)).Fdb
	p = _sqlite3DbMallocRawNN(tls, db, uint64(224))
	if p == uintptr(0) {
		return uintptr(0)
	}
	libc.Xmemset(tls, p+100, 0, libc.Uint32FromInt64(224)-uint32(libc.UintptrFromInt32(0)+100))
	(*TVdbe)(unsafe.Pointer(p)).Fdb = db
	if (*Tsqlite3)(unsafe.Pointer(db)).FpVdbe != 0 {
		(*TVdbe)(unsafe.Pointer((*Tsqlite3)(unsafe.Pointer(db)).FpVdbe)).FppVPrev = p + 8
	}
	(*TVdbe)(unsafe.Pointer(p)).FpVNext = (*Tsqlite3)(unsafe.Pointer(db)).FpVdbe
	(*TVdbe)(unsafe.Pointer(p)).FppVPrev = db + 4
	(*Tsqlite3)(unsafe.Pointer(db)).FpVdbe = p
	(*TVdbe)(unsafe.Pointer(p)).FpParse = pParse
	(*TParse)(unsafe.Pointer(pParse)).FpVdbe = p
	_sqlite3VdbeAddOp2(tls, p, int32(OP_Init), 0, int32(1))
	return p
}

// C documentation
//
//	/*
//	** Delete a VdbeFrame object and its contents. VdbeFrame objects are
//	** allocated by the OP_Program opcode in sqlite3VdbeExec().
//	*/
func _sqlite3VdbeFrameDelete(tls *libc.TLS, p uintptr) {
	var aMem, apCsr uintptr
	var i int32
	_, _, _ = aMem, apCsr, i
	aMem = p + uintptr((libc.Uint32FromInt64(80)+libc.Uint32FromInt32(7))&libc.Uint32FromInt32(^libc.Int32FromInt32(7)))
	apCsr = aMem + uintptr((*TVdbeFrame)(unsafe.Pointer(p)).FnChildMem)*40
	i = 0
	for {
		if !(i < (*TVdbeFrame)(unsafe.Pointer(p)).FnChildCsr) {
			break
		}
		if **(**uintptr)(__ccgo_up(apCsr + uintptr(i)*4)) != 0 {
			_sqlite3VdbeFreeCursorNN(tls, (*TVdbeFrame)(unsafe.Pointer(p)).Fv, **(**uintptr)(__ccgo_up(apCsr + uintptr(i)*4)))
		}
		goto _1
	_1:
		;
		i = i + 1
	}
	_releaseMemArray(tls, aMem, (*TVdbeFrame)(unsafe.Pointer(p)).FnChildMem)
	_sqlite3VdbeDeleteAuxData(tls, (*TVdbe)(unsafe.Pointer((*TVdbeFrame)(unsafe.Pointer(p)).Fv)).Fdb, p+36, -int32(1), 0)
	_sqlite3DbFree(tls, (*TVdbe)(unsafe.Pointer((*TVdbeFrame)(unsafe.Pointer(p)).Fv)).Fdb, p)
}

// C documentation
//
//	/*
//	** Copy the values stored in the VdbeFrame structure to its Vdbe. This
//	** is used, for example, when a trigger sub-program is halted to restore
//	** control to the main program.
//	*/
func _sqlite3VdbeFrameRestore(tls *libc.TLS, pFrame uintptr) (r int32) {
	var v uintptr
	_ = v
	v = (*TVdbeFrame)(unsafe.Pointer(pFrame)).Fv
	_closeCursorsInFrame(tls, v)
	(*TVdbe)(unsafe.Pointer(v)).FaOp = (*TVdbeFrame)(unsafe.Pointer(pFrame)).FaOp
	(*TVdbe)(unsafe.Pointer(v)).FnOp = (*TVdbeFrame)(unsafe.Pointer(pFrame)).FnOp
	(*TVdbe)(unsafe.Pointer(v)).FaMem = (*TVdbeFrame)(unsafe.Pointer(pFrame)).FaMem
	(*TVdbe)(unsafe.Pointer(v)).FnMem = (*TVdbeFrame)(unsafe.Pointer(pFrame)).FnMem
	(*TVdbe)(unsafe.Pointer(v)).FapCsr = (*TVdbeFrame)(unsafe.Pointer(pFrame)).FapCsr
	(*TVdbe)(unsafe.Pointer(v)).FnCursor = (*TVdbeFrame)(unsafe.Pointer(pFrame)).FnCursor
	(*Tsqlite3)(unsafe.Pointer((*TVdbe)(unsafe.Pointer(v)).Fdb)).FlastRowid = (*TVdbeFrame)(unsafe.Pointer(pFrame)).FlastRowid
	(*TVdbe)(unsafe.Pointer(v)).FnChange = (*TVdbeFrame)(unsafe.Pointer(pFrame)).FnChange
	(*Tsqlite3)(unsafe.Pointer((*TVdbe)(unsafe.Pointer(v)).Fdb)).FnChange = (*TVdbeFrame)(unsafe.Pointer(pFrame)).FnDbChange
	_sqlite3VdbeDeleteAuxData(tls, (*TVdbe)(unsafe.Pointer(v)).Fdb, v+220, -int32(1), 0)
	(*TVdbe)(unsafe.Pointer(v)).FpAuxData = (*TVdbeFrame)(unsafe.Pointer(pFrame)).FpAuxData
	(*TVdbeFrame)(unsafe.Pointer(pFrame)).FpAuxData = uintptr(0)
	return (*TVdbeFrame)(unsafe.Pointer(pFrame)).Fpc
}

// C documentation
//
//	/*
//	** This routine is called the when a VDBE tries to halt.  If the VDBE
//	** has made changes and is in autocommit mode, then commit those
//	** changes.  If a rollback is needed, then do the rollback.
//	**
//	** This routine is the only way to move the sqlite3eOpenState of a VM from
//	** SQLITE_STATE_RUN to SQLITE_STATE_HALT.  It is harmless to
//	** call this on a VM that is in the SQLITE_STATE_HALT state.
//	**
//	** Return an error code.  If the commit could not complete because of
//	** lock contention, return SQLITE_BUSY.  If SQLITE_BUSY is returned, it
//	** means the close did not happen and needs to be repeated.
//	*/
func _sqlite3VdbeHalt(tls *libc.TLS, p uintptr) (r int32) {
	var db uintptr
	var eStatementOp, isSpecialError, mrc, rc, v1 int32
	_, _, _, _, _, _ = db, eStatementOp, isSpecialError, mrc, rc, v1 /* Used to store transient return codes */
	db = (*TVdbe)(unsafe.Pointer(p)).Fdb
	/* This function contains the logic that determines if a statement or
	 ** transaction will be committed or rolled back as a result of the
	 ** execution of this virtual machine.
	 **
	 ** If any of the following errors occur:
	 **
	 **     SQLITE_NOMEM
	 **     SQLITE_IOERR
	 **     SQLITE_FULL
	 **     SQLITE_INTERRUPT
	 **
	 ** Then the internal cache might have been left in an inconsistent
	 ** state.  We need to rollback the statement transaction, if there is
	 ** one, or the complete transaction if there is no statement transaction.
	 */
	if (*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0 {
		(*TVdbe)(unsafe.Pointer(p)).Frc = int32(SQLITE_NOMEM)
	}
	_closeAllCursors(tls, p)
	/* No commit or rollback needed if the program never started or if the
	 ** SQL statement does not read or write a database file.  */
	if int32(Tbft(*(*uint16)(unsafe.Pointer(p + 144))&0x80>>7)) != 0 { /* Primary error code from p->rc */
		eStatementOp = 0 /* Set to true if a 'special' error */
		/* Lock all btrees used by the statement */
		_sqlite3VdbeEnter(tls, p)
		/* Check for one of the special errors */
		if (*TVdbe)(unsafe.Pointer(p)).Frc != 0 {
			mrc = (*TVdbe)(unsafe.Pointer(p)).Frc & int32(0xff)
			isSpecialError = libc.BoolInt32(mrc == int32(SQLITE_NOMEM) || mrc == int32(SQLITE_IOERR) || mrc == int32(SQLITE_INTERRUPT) || mrc == int32(SQLITE_FULL))
		} else {
			v1 = libc.Int32FromInt32(0)
			isSpecialError = v1
			mrc = v1
		}
		if isSpecialError != 0 {
			/* If the query was read-only and the error code is SQLITE_INTERRUPT,
			 ** no rollback is necessary. Otherwise, at least a savepoint
			 ** transaction must be rolled back to restore the database to a
			 ** consistent state.
			 **
			 ** Even if the statement is read-only, it is important to perform
			 ** a statement or transaction rollback operation. If the error
			 ** occurred while writing to the journal, sub-journal or database
			 ** file as part of an effort to free up cache space (see function
			 ** pagerStress() in pager.c), the rollback is required to restore
			 ** the pager to a consistent state.
			 */
			if !(int32(Tbft(*(*uint16)(unsafe.Pointer(p + 144))&0x40>>6)) != 0) || mrc != int32(SQLITE_INTERRUPT) {
				if (mrc == int32(SQLITE_NOMEM) || mrc == int32(SQLITE_FULL)) && int32(Tbft(*(*uint16)(unsafe.Pointer(p + 144))&0x20>>5)) != 0 {
					eStatementOp = int32(SAVEPOINT_ROLLBACK)
				} else {
					/* We are forced to roll back the active transaction. Before doing
					 ** so, abort any other statements this handle currently has active.
					 */
					_sqlite3RollbackAll(tls, db, libc.Int32FromInt32(SQLITE_ABORT)|libc.Int32FromInt32(2)<<libc.Int32FromInt32(8))
					_sqlite3CloseSavepoints(tls, db)
					(*Tsqlite3)(unsafe.Pointer(db)).FautoCommit = uint8(1)
					(*TVdbe)(unsafe.Pointer(p)).FnChange = 0
				}
			}
		}
		/* Check for immediate foreign key violations. */
		if (*TVdbe)(unsafe.Pointer(p)).Frc == SQLITE_OK || libc.Int32FromUint8((*TVdbe)(unsafe.Pointer(p)).FerrorAction) == int32(OE_Fail) && !(isSpecialError != 0) {
			_sqlite3VdbeCheckFkImmediate(tls, p)
		}
		/* If the auto-commit flag is set and this is the only active writer
		 ** VM, then we do either a commit or rollback of the current transaction.
		 **
		 ** Note: This block also runs if one of the special errors handled
		 ** above has occurred.
		 */
		if !((*Tsqlite3)(unsafe.Pointer(db)).FnVTrans > 0 && (*Tsqlite3)(unsafe.Pointer(db)).FaVTrans == uintptr(0)) && (*Tsqlite3)(unsafe.Pointer(db)).FautoCommit != 0 && (*Tsqlite3)(unsafe.Pointer(db)).FnVdbeWrite == libc.BoolInt32(int32(Tbft(*(*uint16)(unsafe.Pointer(p + 144))&0x40>>6)) == 0) {
			if (*TVdbe)(unsafe.Pointer(p)).Frc == SQLITE_OK || libc.Int32FromUint8((*TVdbe)(unsafe.Pointer(p)).FerrorAction) == int32(OE_Fail) && !(isSpecialError != 0) {
				rc = _sqlite3VdbeCheckFkDeferred(tls, p)
				if rc != SQLITE_OK {
					if int32(Tbft(*(*uint16)(unsafe.Pointer(p + 144))&0x40>>6)) != 0 {
						_sqlite3VdbeLeave(tls, p)
						return int32(SQLITE_ERROR)
					}
					rc = libc.Int32FromInt32(SQLITE_CONSTRAINT) | libc.Int32FromInt32(3)<<libc.Int32FromInt32(8)
				} else {
					if (*Tsqlite3)(unsafe.Pointer(db)).Fflags&(libc.Uint64FromInt32(libc.Int32FromInt32(0x00002))<<libc.Int32FromInt32(32)) != 0 {
						rc = int32(SQLITE_CORRUPT)
						**(**Tu64)(__ccgo_up(db + 28)) &= ^(libc.Uint64FromInt32(libc.Int32FromInt32(0x00002)) << libc.Int32FromInt32(32))
					} else {
						/* The auto-commit flag is true, the vdbe program was successful
						 ** or hit an 'OR FAIL' constraint and there are no deferred foreign
						 ** key constraints to hold up the transaction. This means a commit
						 ** is required. */
						rc = _vdbeCommit(tls, db, p)
					}
				}
				if rc == int32(SQLITE_BUSY) && int32(Tbft(*(*uint16)(unsafe.Pointer(p + 144))&0x40>>6)) != 0 {
					_sqlite3VdbeLeave(tls, p)
					return int32(SQLITE_BUSY)
				} else {
					if rc != SQLITE_OK {
						_sqlite3SystemError(tls, db, rc)
						(*TVdbe)(unsafe.Pointer(p)).Frc = rc
						_sqlite3RollbackAll(tls, db, SQLITE_OK)
						(*TVdbe)(unsafe.Pointer(p)).FnChange = 0
					} else {
						(*Tsqlite3)(unsafe.Pointer(db)).FnDeferredCons = 0
						(*Tsqlite3)(unsafe.Pointer(db)).FnDeferredImmCons = 0
						**(**Tu64)(__ccgo_up(db + 28)) &= ^libc.Uint64FromInt32(SQLITE_DeferFKs)
						_sqlite3CommitInternalChanges(tls, db)
					}
				}
			} else {
				if (*TVdbe)(unsafe.Pointer(p)).Frc == int32(SQLITE_SCHEMA) && (*Tsqlite3)(unsafe.Pointer(db)).FnVdbeActive > int32(1) {
					(*TVdbe)(unsafe.Pointer(p)).FnChange = 0
				} else {
					_sqlite3RollbackAll(tls, db, SQLITE_OK)
					(*TVdbe)(unsafe.Pointer(p)).FnChange = 0
				}
			}
			(*Tsqlite3)(unsafe.Pointer(db)).FnStatement = 0
		} else {
			if eStatementOp == 0 {
				if (*TVdbe)(unsafe.Pointer(p)).Frc == SQLITE_OK || libc.Int32FromUint8((*TVdbe)(unsafe.Pointer(p)).FerrorAction) == int32(OE_Fail) {
					eStatementOp = int32(SAVEPOINT_RELEASE)
				} else {
					if libc.Int32FromUint8((*TVdbe)(unsafe.Pointer(p)).FerrorAction) == int32(OE_Abort) {
						eStatementOp = int32(SAVEPOINT_ROLLBACK)
					} else {
						_sqlite3RollbackAll(tls, db, libc.Int32FromInt32(SQLITE_ABORT)|libc.Int32FromInt32(2)<<libc.Int32FromInt32(8))
						_sqlite3CloseSavepoints(tls, db)
						(*Tsqlite3)(unsafe.Pointer(db)).FautoCommit = uint8(1)
						(*TVdbe)(unsafe.Pointer(p)).FnChange = 0
					}
				}
			}
		}
		/* If eStatementOp is non-zero, then a statement transaction needs to
		 ** be committed or rolled back. Call sqlite3VdbeCloseStatement() to
		 ** do so. If this operation returns an error, and the current statement
		 ** error code is SQLITE_OK or SQLITE_CONSTRAINT, then promote the
		 ** current statement error code.
		 */
		if eStatementOp != 0 {
			rc = _sqlite3VdbeCloseStatement(tls, p, eStatementOp)
			if rc != 0 {
				if (*TVdbe)(unsafe.Pointer(p)).Frc == SQLITE_OK || (*TVdbe)(unsafe.Pointer(p)).Frc&int32(0xff) == int32(SQLITE_CONSTRAINT) {
					(*TVdbe)(unsafe.Pointer(p)).Frc = rc
					_sqlite3DbFree(tls, db, (*TVdbe)(unsafe.Pointer(p)).FzErrMsg)
					(*TVdbe)(unsafe.Pointer(p)).FzErrMsg = uintptr(0)
				}
				_sqlite3RollbackAll(tls, db, libc.Int32FromInt32(SQLITE_ABORT)|libc.Int32FromInt32(2)<<libc.Int32FromInt32(8))
				_sqlite3CloseSavepoints(tls, db)
				(*Tsqlite3)(unsafe.Pointer(db)).FautoCommit = uint8(1)
				(*TVdbe)(unsafe.Pointer(p)).FnChange = 0
			}
		}
		/* If this was an INSERT, UPDATE or DELETE and no statement transaction
		 ** has been rolled back, update the database connection change-counter.
		 */
		if int32(Tbft(*(*uint16)(unsafe.Pointer(p + 144))&0x10>>4)) != 0 {
			if eStatementOp != int32(SAVEPOINT_ROLLBACK) {
				_sqlite3VdbeSetChanges(tls, db, (*TVdbe)(unsafe.Pointer(p)).FnChange)
			} else {
				_sqlite3VdbeSetChanges(tls, db, 0)
			}
			(*TVdbe)(unsafe.Pointer(p)).FnChange = 0
		}
		/* Release the locks */
		_sqlite3VdbeLeave(tls, p)
	}
	/* We have successfully halted and closed the VM.  Record this fact. */
	(*Tsqlite3)(unsafe.Pointer(db)).FnVdbeActive = (*Tsqlite3)(unsafe.Pointer(db)).FnVdbeActive - 1
	if !(int32(Tbft(*(*uint16)(unsafe.Pointer(p + 144))&0x40>>6)) != 0) {
		(*Tsqlite3)(unsafe.Pointer(db)).FnVdbeWrite = (*Tsqlite3)(unsafe.Pointer(db)).FnVdbeWrite - 1
	}
	if int32(Tbft(*(*uint16)(unsafe.Pointer(p + 144))&0x80>>7)) != 0 {
		(*Tsqlite3)(unsafe.Pointer(db)).FnVdbeRead = (*Tsqlite3)(unsafe.Pointer(db)).FnVdbeRead - 1
	}
	(*TVdbe)(unsafe.Pointer(p)).FeVdbeState = uint8(VDBE_HALT_STATE)
	if (*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0 {
		(*TVdbe)(unsafe.Pointer(p)).Frc = int32(SQLITE_NOMEM)
	}
	/* If the auto-commit flag is set to true, then any locks that were held
	 ** by connection db have now been released. Call sqlite3ConnectionUnlocked()
	 ** to invoke any required unlock-notify callbacks.
	 */
	if (*Tsqlite3)(unsafe.Pointer(db)).FautoCommit != 0 {
		_sqlite3ConnectionUnlocked(tls, db)
	}
	if (*TVdbe)(unsafe.Pointer(p)).Frc == int32(SQLITE_BUSY) {
		v1 = int32(SQLITE_BUSY)
	} else {
		v1 = SQLITE_OK
	}
	return v1
}

// C documentation
//
//	/*
//	** Give a listing of the program in the virtual machine.
//	**
//	** The interface is the same as sqlite3VdbeExec().  But instead of
//	** running the code, it invokes the callback once for each instruction.
//	** This feature is used to implement "EXPLAIN".
//	**
//	** When p->explain==1, each instruction is listed.  When
//	** p->explain==2, only OP_Explain instructions are listed and these
//	** are shown in a different format.  p->explain==2 is used to implement
//	** EXPLAIN QUERY PLAN.
//	** 2018-04-24:  In p->explain==2 mode, the OP_Init opcodes of triggers
//	** are also shown, so that the boundaries between the main program and
//	** each trigger are clear.
//	**
//	** When p->explain==1, first the main program is listed, then each of
//	** the trigger subprograms are listed one by one.
//	*/
func _sqlite3VdbeList(tls *libc.TLS, p uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var bListSubprogs, rc int32
	var db, pMem, pOp, pSub, zP4 uintptr
	var _ /* aOp at bp+4 */ uintptr
	var _ /* i at bp+0 */ int32
	_, _, _, _, _, _, _ = bListSubprogs, db, pMem, pOp, pSub, rc, zP4
	pSub = uintptr(0)                                                                                                                                                                    /* Memory cell hold array of subprogs */
	db = (*TVdbe)(unsafe.Pointer(p)).Fdb                                                                                                                                                 /* Loop counter */
	rc = SQLITE_OK                                                                                                                                                                       /* Return code */
	pMem = (*TVdbe)(unsafe.Pointer(p)).FaMem + 1*40                                                                                                                                      /* First Mem of result set */
	bListSubprogs = libc.BoolInt32(int32(Tbft(*(*uint16)(unsafe.Pointer(p + 144))&0xc>>2)) == int32(1) || (*Tsqlite3)(unsafe.Pointer(db)).Fflags&uint64(SQLITE_TriggerEQP) != uint64(0)) /* Current opcode */
	/* Even though this opcode does not use dynamic strings for
	 ** the result, result columns may become dynamic if the user calls
	 ** sqlite3_column_text16(), causing a translation to UTF-16 encoding.
	 */
	_releaseMemArray(tls, pMem, int32(8))
	if (*TVdbe)(unsafe.Pointer(p)).Frc == int32(SQLITE_NOMEM) {
		/* This happens if a malloc() inside a call to sqlite3_column_text() or
		 ** sqlite3_column_text16() failed.  */
		_sqlite3OomFault(tls, db)
		return int32(SQLITE_ERROR)
	}
	if bListSubprogs != 0 {
		/* The first 8 memory cells are used for the result set.  So we will
		 ** commandeer the 9th cell to use as storage for an array of pointers
		 ** to trigger subprograms.  The VDBE is guaranteed to have at least 9
		 ** cells.  */
		pSub = (*TVdbe)(unsafe.Pointer(p)).FaMem + 9*40
	} else {
		pSub = uintptr(0)
	}
	/* Figure out which opcode is next to display */
	rc = _sqlite3VdbeNextOpcode(tls, p, pSub, libc.BoolInt32(int32(Tbft(*(*uint16)(unsafe.Pointer(p + 144))&0xc>>2)) == int32(2)), p+32, bp, bp+4)
	if rc == SQLITE_OK {
		pOp = **(**uintptr)(__ccgo_up(bp + 4)) + uintptr(**(**int32)(__ccgo_up(bp)))*20
		if libc.AtomicLoadNInt32(db+308, libc.Int32FromInt32(__ATOMIC_RELAXED)) != 0 {
			(*TVdbe)(unsafe.Pointer(p)).Frc = int32(SQLITE_INTERRUPT)
			rc = int32(SQLITE_ERROR)
			_sqlite3VdbeError(tls, p, _sqlite3ErrStr(tls, (*TVdbe)(unsafe.Pointer(p)).Frc), 0)
		} else {
			zP4 = _sqlite3VdbeDisplayP4(tls, db, pOp)
			if int32(Tbft(*(*uint16)(unsafe.Pointer(p + 144))&0xc>>2)) == int32(2) {
				_sqlite3VdbeMemSetInt64(tls, pMem, int64((*TOp)(unsafe.Pointer(pOp)).Fp1))
				_sqlite3VdbeMemSetInt64(tls, pMem+uintptr(1)*40, int64((*TOp)(unsafe.Pointer(pOp)).Fp2))
				_sqlite3VdbeMemSetInt64(tls, pMem+uintptr(2)*40, int64((*TOp)(unsafe.Pointer(pOp)).Fp3))
				_sqlite3VdbeMemSetStr(tls, pMem+uintptr(3)*40, zP4, int64(-int32(1)), uint8(SQLITE_UTF8), __ccgo_fp(Xsqlite3_free))
			} else {
				_sqlite3VdbeMemSetInt64(tls, pMem+uintptr(0)*40, int64(**(**int32)(__ccgo_up(bp))))
				_sqlite3VdbeMemSetStr(tls, pMem+uintptr(1)*40, _sqlite3OpcodeName(tls, libc.Int32FromUint8((*TOp)(unsafe.Pointer(pOp)).Fopcode)), int64(-int32(1)), uint8(SQLITE_UTF8), libc.UintptrFromInt32(0))
				_sqlite3VdbeMemSetInt64(tls, pMem+uintptr(2)*40, int64((*TOp)(unsafe.Pointer(pOp)).Fp1))
				_sqlite3VdbeMemSetInt64(tls, pMem+uintptr(3)*40, int64((*TOp)(unsafe.Pointer(pOp)).Fp2))
				_sqlite3VdbeMemSetInt64(tls, pMem+uintptr(4)*40, int64((*TOp)(unsafe.Pointer(pOp)).Fp3))
				/* pMem+5 for p4 is done last */
				_sqlite3VdbeMemSetInt64(tls, pMem+uintptr(6)*40, libc.Int64FromUint16((*TOp)(unsafe.Pointer(pOp)).Fp5))
				_sqlite3VdbeMemSetNull(tls, pMem+uintptr(7)*40)
				_sqlite3VdbeMemSetStr(tls, pMem+uintptr(5)*40, zP4, int64(-int32(1)), uint8(SQLITE_UTF8), __ccgo_fp(Xsqlite3_free))
			}
			(*TVdbe)(unsafe.Pointer(p)).FpResultRow = pMem
			if (*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0 {
				(*TVdbe)(unsafe.Pointer(p)).Frc = int32(SQLITE_NOMEM)
				rc = int32(SQLITE_ERROR)
			} else {
				(*TVdbe)(unsafe.Pointer(p)).Frc = SQLITE_OK
				rc = int32(SQLITE_ROW)
			}
		}
	}
	return rc
}

// C documentation
//
//	/*
//	** Prepare a virtual machine for execution for the first time after
//	** creating the virtual machine.  This involves things such
//	** as allocating registers and initializing the program counter.
//	** After the VDBE has be prepped, it can be executed by one or more
//	** calls to sqlite3VdbeExec().
//	**
//	** This function may be called exactly once on each virtual machine.
//	** After this routine is called the VM has been "packaged" and is ready
//	** to run.  After this routine is called, further calls to
//	** sqlite3VdbeAddOp() functions are prohibited.  This routine disconnects
//	** the Vdbe from the Parse object that helped generate it so that the
//	** the Vdbe becomes an independent entity and the Parse object can be
//	** destroyed.
//	**
//	** Use the sqlite3VdbeRewind() procedure to restore a virtual machine back
//	** to its initial state after it has been run.
//	*/
func _sqlite3VdbeMakeReady(tls *libc.TLS, p uintptr, pParse uintptr) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var db, v1 uintptr
	var n, nCursor, nMem, nVar int32
	var _ /* nArg at bp+0 */ int32
	var _ /* x at bp+4 */ TReusableSpace
	_, _, _, _, _, _ = db, n, nCursor, nMem, nVar, v1 /* Reusable bulk memory */
	(*TVdbe)(unsafe.Pointer(p)).FpVList = (*TParse)(unsafe.Pointer(pParse)).FpVList
	(*TParse)(unsafe.Pointer(pParse)).FpVList = uintptr(0)
	db = (*TVdbe)(unsafe.Pointer(p)).Fdb
	nVar = int32((*TParse)(unsafe.Pointer(pParse)).FnVar)
	nMem = (*TParse)(unsafe.Pointer(pParse)).FnMem
	nCursor = (*TParse)(unsafe.Pointer(pParse)).FnTab
	**(**int32)(__ccgo_up(bp)) = (*TParse)(unsafe.Pointer(pParse)).FnMaxArg
	/* Each cursor uses a memory cell.  The first cursor (cursor 0) can
	 ** use aMem[0] which is not otherwise used by the VDBE program.  Allocate
	 ** space at the end of aMem[] for cursors 1 and greater.
	 ** See also: allocateCursor().
	 */
	nMem = nMem + nCursor
	if nCursor == 0 && nMem > 0 {
		nMem = nMem + 1
	} /* Space for aMem[0] even if not used */
	/* Figure out how much reusable memory is available at the end of the
	 ** opcode array.  This extra memory will be reallocated for other elements
	 ** of the prepared statement.
	 */
	n = libc.Int32FromUint32((libc.Uint32FromInt64(20)*libc.Uint32FromInt32((*TVdbe)(unsafe.Pointer(p)).FnOp) + libc.Uint32FromInt32(7)) & libc.Uint32FromInt32(^libc.Int32FromInt32(7))) /* Bytes of opcode memory used */
	(**(**TReusableSpace)(__ccgo_up(bp + 4))).FpSpace = (*TVdbe)(unsafe.Pointer(p)).FaOp + uintptr(n)                                                                                     /* Unused opcode memory */
	(**(**TReusableSpace)(__ccgo_up(bp + 4))).FnFree = int64(((*TParse)(unsafe.Pointer(pParse)).FszOpAlloc - n) & ^libc.Int32FromInt32(7))                                                /* Bytes of unused memory */
	_resolveP2Values(tls, p, bp)
	libc.SetBitFieldPtr16Uint32(p+144, uint32(libc.BoolUint8((*TParse)(unsafe.Pointer(pParse)).FisMultiWrite != 0 && int32(Tbft(*(*uint16)(unsafe.Pointer(pParse + 28))&0x2>>1)) != 0)), 5, 0x20)
	if (*TParse)(unsafe.Pointer(pParse)).Fexplain != 0 {
		if nMem < int32(10) {
			nMem = int32(10)
		}
		libc.SetBitFieldPtr16Uint32(p+144, uint32((*TParse)(unsafe.Pointer(pParse)).Fexplain), 2, 0xc)
		(*TVdbe)(unsafe.Pointer(p)).FnResColumn = libc.Uint16FromInt32(int32(12) - int32(4)*int32(Tbft(*(*uint16)(unsafe.Pointer(p + 144))&0xc>>2)))
	}
	libc.SetBitFieldPtr16Uint32(p+144, libc.Uint32FromInt32(0), 0, 0x3)
	/* Memory for registers, parameters, cursor, etc, is allocated in one or two
	 ** passes.  On the first pass, we try to reuse unused memory at the
	 ** end of the opcode array.  If we are unable to satisfy all memory
	 ** requirements by reusing the opcode array tail, then the second
	 ** pass will fill in the remainder using a fresh memory allocation.
	 **
	 ** This two-pass approach that reuses as much memory as possible from
	 ** the leftover memory at the end of the opcode array.  This can significantly
	 ** reduce the amount of memory held by a prepared statement.
	 */
	(**(**TReusableSpace)(__ccgo_up(bp + 4))).FnNeeded = 0
	(*TVdbe)(unsafe.Pointer(p)).FaMem = _allocSpace(tls, bp+4, uintptr(0), libc.Int64FromUint32(libc.Uint32FromInt32(nMem)*uint32(40)))
	(*TVdbe)(unsafe.Pointer(p)).FaVar = _allocSpace(tls, bp+4, uintptr(0), libc.Int64FromUint32(libc.Uint32FromInt32(nVar)*uint32(40)))
	(*TVdbe)(unsafe.Pointer(p)).FapArg = _allocSpace(tls, bp+4, uintptr(0), libc.Int64FromUint32(libc.Uint32FromInt32(**(**int32)(__ccgo_up(bp)))*uint32(4)))
	(*TVdbe)(unsafe.Pointer(p)).FapCsr = _allocSpace(tls, bp+4, uintptr(0), libc.Int64FromUint32(libc.Uint32FromInt32(nCursor)*uint32(4)))
	if (**(**TReusableSpace)(__ccgo_up(bp + 4))).FnNeeded != 0 {
		v1 = _sqlite3DbMallocRawNN(tls, db, libc.Uint64FromInt64((**(**TReusableSpace)(__ccgo_up(bp + 4))).FnNeeded))
		(*TVdbe)(unsafe.Pointer(p)).FpFree = v1
		(**(**TReusableSpace)(__ccgo_up(bp + 4))).FpSpace = v1
		(**(**TReusableSpace)(__ccgo_up(bp + 4))).FnFree = (**(**TReusableSpace)(__ccgo_up(bp + 4))).FnNeeded
		if !((*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0) {
			(*TVdbe)(unsafe.Pointer(p)).FaMem = _allocSpace(tls, bp+4, (*TVdbe)(unsafe.Pointer(p)).FaMem, libc.Int64FromUint32(libc.Uint32FromInt32(nMem)*uint32(40)))
			(*TVdbe)(unsafe.Pointer(p)).FaVar = _allocSpace(tls, bp+4, (*TVdbe)(unsafe.Pointer(p)).FaVar, libc.Int64FromUint32(libc.Uint32FromInt32(nVar)*uint32(40)))
			(*TVdbe)(unsafe.Pointer(p)).FapArg = _allocSpace(tls, bp+4, (*TVdbe)(unsafe.Pointer(p)).FapArg, libc.Int64FromUint32(libc.Uint32FromInt32(**(**int32)(__ccgo_up(bp)))*uint32(4)))
			(*TVdbe)(unsafe.Pointer(p)).FapCsr = _allocSpace(tls, bp+4, (*TVdbe)(unsafe.Pointer(p)).FapCsr, libc.Int64FromUint32(libc.Uint32FromInt32(nCursor)*uint32(4)))
		}
	}
	if (*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0 {
		(*TVdbe)(unsafe.Pointer(p)).FnVar = 0
		(*TVdbe)(unsafe.Pointer(p)).FnCursor = 0
		(*TVdbe)(unsafe.Pointer(p)).FnMem = 0
	} else {
		(*TVdbe)(unsafe.Pointer(p)).FnCursor = nCursor
		(*TVdbe)(unsafe.Pointer(p)).FnVar = int16(nVar)
		_initMemArray(tls, (*TVdbe)(unsafe.Pointer(p)).FaVar, nVar, db, uint16(MEM_Null))
		(*TVdbe)(unsafe.Pointer(p)).FnMem = nMem
		_initMemArray(tls, (*TVdbe)(unsafe.Pointer(p)).FaMem, nMem, db, uint16(MEM_Undefined))
		libc.Xmemset(tls, (*TVdbe)(unsafe.Pointer(p)).FapCsr, 0, libc.Uint32FromInt32(nCursor)*uint32(4))
	}
	_sqlite3VdbeRewind(tls, p)
}

// C documentation
//
//	/*
//	** Memory cell pMem contains the context of an aggregate function.
//	** This routine calls the finalize method for that function.  The
//	** result of the aggregate is stored back into pMem.
//	**
//	** Return SQLITE_ERROR if the finalizer reports an error.  SQLITE_OK
//	** otherwise.
//	*/
func _sqlite3VdbeMemFinalize(tls *libc.TLS, pMem uintptr, pFunc uintptr) (r int32) {
	bp := tls.Alloc(80)
	defer tls.Free(80)
	var _ /* ctx at bp+0 */ Tsqlite3_context
	var _ /* t at bp+28 */ TMem
	libc.Xmemset(tls, bp, 0, uint32(28))
	libc.Xmemset(tls, bp+28, 0, uint32(40))
	(**(**TMem)(__ccgo_up(bp + 28))).Fflags = uint16(MEM_Null)
	(**(**TMem)(__ccgo_up(bp + 28))).Fdb = (*TMem)(unsafe.Pointer(pMem)).Fdb
	(**(**Tsqlite3_context)(__ccgo_up(bp))).FpOut = bp + 28
	(**(**Tsqlite3_context)(__ccgo_up(bp))).FpMem = pMem
	(**(**Tsqlite3_context)(__ccgo_up(bp))).FpFunc = pFunc
	(**(**Tsqlite3_context)(__ccgo_up(bp))).Fenc = (*Tsqlite3)(unsafe.Pointer((**(**TMem)(__ccgo_up(bp + 28))).Fdb)).Fenc
	(*(*func(*libc.TLS, uintptr))(unsafe.Pointer(&struct{ uintptr }{(*TFuncDef)(unsafe.Pointer(pFunc)).FxFinalize})))(tls, bp) /* IMP: R-24505-23230 */
	if (*TMem)(unsafe.Pointer(pMem)).FszMalloc > 0 {
		_sqlite3DbFreeNN(tls, (*TMem)(unsafe.Pointer(pMem)).Fdb, (*TMem)(unsafe.Pointer(pMem)).FzMalloc)
	}
	libc.Xmemcpy(tls, pMem, bp+28, uint32(40))
	return (**(**Tsqlite3_context)(__ccgo_up(bp))).FisError
}

// C documentation
//
//	/*
//	** This routine checks for a byte-order mark at the beginning of the
//	** UTF-16 string stored in *pMem. If one is present, it is removed and
//	** the encoding of the Mem adjusted. This routine does not do any
//	** byte-swapping, it just sets Mem.enc appropriately.
//	**
//	** The allocation (static, dynamic etc.) and encoding of the Mem may be
//	** changed by this function.
//	*/
func _sqlite3VdbeMemHandleBom(tls *libc.TLS, pMem uintptr) (r int32) {
	var b1, b2, bom Tu8
	var rc int32
	var v1 uintptr
	_, _, _, _, _ = b1, b2, bom, rc, v1
	rc = SQLITE_OK
	bom = uint8(0)
	if (*TMem)(unsafe.Pointer(pMem)).Fn > int32(1) {
		b1 = **(**Tu8)(__ccgo_up((*TMem)(unsafe.Pointer(pMem)).Fz))
		b2 = **(**Tu8)(__ccgo_up((*TMem)(unsafe.Pointer(pMem)).Fz + libc.UintptrFromInt32(1)))
		if libc.Int32FromUint8(b1) == int32(0xFE) && libc.Int32FromUint8(b2) == int32(0xFF) {
			bom = uint8(SQLITE_UTF16BE)
		}
		if libc.Int32FromUint8(b1) == int32(0xFF) && libc.Int32FromUint8(b2) == int32(0xFE) {
			bom = uint8(SQLITE_UTF16LE)
		}
	}
	if bom != 0 {
		rc = _sqlite3VdbeMemMakeWriteable(tls, pMem)
		if rc == SQLITE_OK {
			**(**int32)(__ccgo_up(pMem + 12)) -= int32(2)
			libc.Xmemmove(tls, (*TMem)(unsafe.Pointer(pMem)).Fz, (*TMem)(unsafe.Pointer(pMem)).Fz+2, libc.Uint32FromInt32((*TMem)(unsafe.Pointer(pMem)).Fn))
			**(**int8)(__ccgo_up((*TMem)(unsafe.Pointer(pMem)).Fz + uintptr((*TMem)(unsafe.Pointer(pMem)).Fn))) = int8('\000')
			**(**int8)(__ccgo_up((*TMem)(unsafe.Pointer(pMem)).Fz + uintptr((*TMem)(unsafe.Pointer(pMem)).Fn+int32(1)))) = int8('\000')
			v1 = pMem + 16
			*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) | libc.Int32FromInt32(MEM_Term))
			(*TMem)(unsafe.Pointer(pMem)).Fenc = bom
		}
	}
	return rc
}

// C documentation
//
//	/*
//	** Change the value of a Mem to be a string or a BLOB.
//	**
//	** The memory management strategy depends on the value of the xDel
//	** parameter. If the value passed is SQLITE_TRANSIENT, then the
//	** string is copied into a (possibly existing) buffer managed by the
//	** Mem structure. Otherwise, any existing buffer is freed and the
//	** pointer copied.
//	**
//	** If the string is too large (if it exceeds the SQLITE_LIMIT_LENGTH
//	** size limit) then no memory allocation occurs.  If the string can be
//	** stored without allocating memory, then it is.  If a memory allocation
//	** is required to store the string, then value of pMem is unchanged.  In
//	** either case, SQLITE_TOOBIG is returned.
//	**
//	** The "enc" parameter is the text encoding for the string, or zero
//	** to store a blob.
//	**
//	** If n is negative, then the string consists of all bytes up to but
//	** excluding the first zero character.  The n parameter must be
//	** non-negative for blobs.
//	*/
func _sqlite3VdbeMemSetStr(tls *libc.TLS, pMem uintptr, z uintptr, n Ti64, enc Tu8, __ccgo_fp_xDel uintptr) (r int32) {
	var flags Tu16
	var iLimit, v2 int32
	var nAlloc, nByte Ti64
	var v3 int64
	_, _, _, _, _, _ = flags, iLimit, nAlloc, nByte, v2, v3
	nByte = n /* New value for pMem->flags */
	/* If z is a NULL pointer, set pMem to contain an SQL NULL. */
	if !(z != 0) {
		_sqlite3VdbeMemSetNull(tls, pMem)
		return SQLITE_OK
	}
	if (*TMem)(unsafe.Pointer(pMem)).Fdb != 0 {
		iLimit = **(**int32)(__ccgo_up((*TMem)(unsafe.Pointer(pMem)).Fdb + 116))
	} else {
		iLimit = int32(SQLITE_MAX_LENGTH)
	}
	if nByte < 0 {
		if libc.Int32FromUint8(enc) == int32(SQLITE_UTF8) {
			nByte = libc.Int64FromUint32(libc.Xstrlen(tls, z))
		} else {
			nByte = 0
			for {
				if !(nByte <= int64(iLimit) && int32(**(**int8)(__ccgo_up(z + uintptr(nByte))))|int32(**(**int8)(__ccgo_up(z + uintptr(nByte+int64(1))))) != 0) {
					break
				}
				goto _1
			_1:
				;
				nByte = nByte + int64(2)
			}
		}
		flags = libc.Uint16FromInt32(libc.Int32FromInt32(MEM_Str) | libc.Int32FromInt32(MEM_Term))
	} else {
		if libc.Int32FromUint8(enc) == 0 {
			flags = uint16(MEM_Blob)
			enc = uint8(SQLITE_UTF8)
		} else {
			flags = uint16(MEM_Str)
		}
	}
	if nByte > int64(iLimit) {
		if __ccgo_fp_xDel != 0 && __ccgo_fp_xDel != uintptr(-libc.Int32FromInt32(1)) {
			if __ccgo_fp_xDel == __ccgo_fp(_sqlite3RowSetClear) {
				_sqlite3DbFree(tls, (*TMem)(unsafe.Pointer(pMem)).Fdb, z)
			} else {
				(*(*func(*libc.TLS, uintptr))(unsafe.Pointer(&struct{ uintptr }{__ccgo_fp_xDel})))(tls, z)
			}
		}
		_sqlite3VdbeMemSetNull(tls, pMem)
		return _sqlite3ErrorToParser(tls, (*TMem)(unsafe.Pointer(pMem)).Fdb, int32(SQLITE_TOOBIG))
	}
	/* The following block sets the new values of Mem.z and Mem.xDel. It
	 ** also sets a flag in local variable "flags" to indicate the memory
	 ** management (one of MEM_Dyn or MEM_Static).
	 */
	if __ccgo_fp_xDel == uintptr(-libc.Int32FromInt32(1)) {
		nAlloc = nByte
		if libc.Int32FromUint16(flags)&int32(MEM_Term) != 0 {
			if libc.Int32FromUint8(enc) == int32(SQLITE_UTF8) {
				v2 = int32(1)
			} else {
				v2 = int32(2)
			}
			nAlloc = nAlloc + int64(v2)
		}
		if nAlloc > int64(libc.Int32FromInt32(32)) {
			v3 = nAlloc
		} else {
			v3 = int64(libc.Int32FromInt32(32))
		}
		if _sqlite3VdbeMemClearAndResize(tls, pMem, int32(v3)) != 0 {
			return int32(SQLITE_NOMEM)
		}
		libc.Xmemcpy(tls, (*TMem)(unsafe.Pointer(pMem)).Fz, z, libc.Uint32FromInt64(nAlloc))
	} else {
		_sqlite3VdbeMemRelease(tls, pMem)
		(*TMem)(unsafe.Pointer(pMem)).Fz = z
		if __ccgo_fp_xDel == __ccgo_fp(_sqlite3RowSetClear) {
			(*TMem)(unsafe.Pointer(pMem)).FzMalloc = (*TMem)(unsafe.Pointer(pMem)).Fz
			(*TMem)(unsafe.Pointer(pMem)).FszMalloc = _sqlite3DbMallocSize(tls, (*TMem)(unsafe.Pointer(pMem)).Fdb, (*TMem)(unsafe.Pointer(pMem)).FzMalloc)
		} else {
			(*TMem)(unsafe.Pointer(pMem)).FxDel = __ccgo_fp_xDel
			if __ccgo_fp_xDel == libc.UintptrFromInt32(0) {
				v2 = int32(MEM_Static)
			} else {
				v2 = int32(MEM_Dyn)
			}
			flags = libc.Uint16FromInt32(int32(flags) | v2)
		}
	}
	(*TMem)(unsafe.Pointer(pMem)).Fn = int32(nByte & libc.Int64FromInt32(0x7fffffff))
	(*TMem)(unsafe.Pointer(pMem)).Fflags = flags
	(*TMem)(unsafe.Pointer(pMem)).Fenc = enc
	if libc.Int32FromUint8(enc) > int32(SQLITE_UTF8) && _sqlite3VdbeMemHandleBom(tls, pMem) != 0 {
		return int32(SQLITE_NOMEM)
	}
	return SQLITE_OK
}

// C documentation
//
//	/* Like sqlite3VdbeMemSetStr() except:
//	**
//	**   enc is always SQLITE_UTF8
//	**   pMem->db is always non-NULL
//	*/
func _sqlite3VdbeMemSetText(tls *libc.TLS, pMem uintptr, z uintptr, n Ti64, __ccgo_fp_xDel uintptr) (r int32) {
	var flags Tu16
	var nAlloc, nByte Ti64
	var v1 int64
	_, _, _, _ = flags, nAlloc, nByte, v1
	nByte = n
	/* If z is a NULL pointer, set pMem to contain an SQL NULL. */
	if !(z != 0) {
		_sqlite3VdbeMemSetNull(tls, pMem)
		return SQLITE_OK
	}
	if nByte < 0 {
		nByte = libc.Int64FromUint32(libc.Xstrlen(tls, z))
		flags = libc.Uint16FromInt32(libc.Int32FromInt32(MEM_Str) | libc.Int32FromInt32(MEM_Term))
	} else {
		flags = uint16(MEM_Str)
	}
	if nByte > int64(**(**int32)(__ccgo_up((*TMem)(unsafe.Pointer(pMem)).Fdb + 116))) {
		if __ccgo_fp_xDel != 0 && __ccgo_fp_xDel != uintptr(-libc.Int32FromInt32(1)) {
			if __ccgo_fp_xDel == __ccgo_fp(_sqlite3RowSetClear) {
				_sqlite3DbFree(tls, (*TMem)(unsafe.Pointer(pMem)).Fdb, z)
			} else {
				(*(*func(*libc.TLS, uintptr))(unsafe.Pointer(&struct{ uintptr }{__ccgo_fp_xDel})))(tls, z)
			}
		}
		_sqlite3VdbeMemSetNull(tls, pMem)
		return _sqlite3ErrorToParser(tls, (*TMem)(unsafe.Pointer(pMem)).Fdb, int32(SQLITE_TOOBIG))
	}
	/* The following block sets the new values of Mem.z and Mem.xDel. It
	 ** also sets a flag in local variable "flags" to indicate the memory
	 ** management (one of MEM_Dyn or MEM_Static).
	 */
	if __ccgo_fp_xDel == uintptr(-libc.Int32FromInt32(1)) {
		nAlloc = nByte + int64(1)
		if nAlloc > int64(libc.Int32FromInt32(32)) {
			v1 = nAlloc
		} else {
			v1 = int64(libc.Int32FromInt32(32))
		}
		if _sqlite3VdbeMemClearAndResize(tls, pMem, int32(v1)) != 0 {
			return int32(SQLITE_NOMEM)
		}
		libc.Xmemcpy(tls, (*TMem)(unsafe.Pointer(pMem)).Fz, z, libc.Uint32FromInt64(nByte))
		**(**int8)(__ccgo_up((*TMem)(unsafe.Pointer(pMem)).Fz + uintptr(nByte))) = 0
	} else {
		_sqlite3VdbeMemRelease(tls, pMem)
		(*TMem)(unsafe.Pointer(pMem)).Fz = z
		if __ccgo_fp_xDel == __ccgo_fp(_sqlite3RowSetClear) {
			(*TMem)(unsafe.Pointer(pMem)).FzMalloc = (*TMem)(unsafe.Pointer(pMem)).Fz
			(*TMem)(unsafe.Pointer(pMem)).FszMalloc = _sqlite3DbMallocSize(tls, (*TMem)(unsafe.Pointer(pMem)).Fdb, (*TMem)(unsafe.Pointer(pMem)).FzMalloc)
			(*TMem)(unsafe.Pointer(pMem)).FxDel = uintptr(0)
		} else {
			if __ccgo_fp_xDel == libc.UintptrFromInt32(0) {
				(*TMem)(unsafe.Pointer(pMem)).FxDel = __ccgo_fp_xDel
				flags = libc.Uint16FromInt32(int32(flags) | libc.Int32FromInt32(MEM_Static))
			} else {
				(*TMem)(unsafe.Pointer(pMem)).FxDel = __ccgo_fp_xDel
				flags = libc.Uint16FromInt32(int32(flags) | libc.Int32FromInt32(MEM_Dyn))
			}
		}
	}
	(*TMem)(unsafe.Pointer(pMem)).Fflags = flags
	(*TMem)(unsafe.Pointer(pMem)).Fn = int32(nByte & libc.Int64FromInt32(0x7fffffff))
	(*TMem)(unsafe.Pointer(pMem)).Fenc = uint8(SQLITE_UTF8)
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** Return true if the Mem object contains a TEXT or BLOB that is
//	** too large - whose size exceeds SQLITE_MAX_LENGTH.
//	*/
func _sqlite3VdbeMemTooBig(tls *libc.TLS, p uintptr) (r int32) {
	var n int32
	_ = n
	if libc.Int32FromUint16((*TMem)(unsafe.Pointer(p)).Fflags)&(libc.Int32FromInt32(MEM_Str)|libc.Int32FromInt32(MEM_Blob)) != 0 {
		n = (*TMem)(unsafe.Pointer(p)).Fn
		if libc.Int32FromUint16((*TMem)(unsafe.Pointer(p)).Fflags)&int32(MEM_Zero) != 0 {
			n = n + *(*int32)(unsafe.Pointer(&(*TMem)(unsafe.Pointer(p)).Fu))
		}
		return libc.BoolInt32(n > **(**int32)(__ccgo_up((*TMem)(unsafe.Pointer(p)).Fdb + 116)))
	}
	return 0
}

// C documentation
//
//	/*
//	** If pMem is already a string, detect if it is a zero-terminated
//	** string, or make it into one if possible, and mark it as such.
//	**
//	** This is an optimization.  Correct operation continues even if
//	** this routine is a no-op.
//	**
//	** Return true if the strig is zero-terminated after this routine is
//	** called and false if it is not.
//	*/
func _sqlite3VdbeMemZeroTerminateIfAble(tls *libc.TLS, pMem uintptr) (r int32) {
	var v1 uintptr
	_ = v1
	if libc.Int32FromUint16((*TMem)(unsafe.Pointer(pMem)).Fflags)&(libc.Int32FromInt32(MEM_Str)|libc.Int32FromInt32(MEM_Term)|libc.Int32FromInt32(MEM_Ephem)|libc.Int32FromInt32(MEM_Static)) != int32(MEM_Str) {
		/* pMem must be a string, and it cannot be an ephemeral or static string */
		return 0
	}
	if libc.Int32FromUint8((*TMem)(unsafe.Pointer(pMem)).Fenc) != int32(SQLITE_UTF8) {
		return 0
	}
	if libc.Int32FromUint16((*TMem)(unsafe.Pointer(pMem)).Fflags)&int32(MEM_Dyn) != 0 {
		if (*TMem)(unsafe.Pointer(pMem)).FxDel == __ccgo_fp(Xsqlite3_free) && Xsqlite3_msize(tls, (*TMem)(unsafe.Pointer(pMem)).Fz) >= libc.Uint64FromInt32((*TMem)(unsafe.Pointer(pMem)).Fn+libc.Int32FromInt32(1)) {
			**(**int8)(__ccgo_up((*TMem)(unsafe.Pointer(pMem)).Fz + uintptr((*TMem)(unsafe.Pointer(pMem)).Fn))) = 0
			v1 = pMem + 16
			*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) | libc.Int32FromInt32(MEM_Term))
			return int32(1)
		}
		if (*TMem)(unsafe.Pointer(pMem)).FxDel == __ccgo_fp(_sqlite3RCStrUnref) {
			/* Blindly assume that all RCStr objects are zero-terminated */
			v1 = pMem + 16
			*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) | libc.Int32FromInt32(MEM_Term))
			return int32(1)
		}
	} else {
		if (*TMem)(unsafe.Pointer(pMem)).FszMalloc >= (*TMem)(unsafe.Pointer(pMem)).Fn+int32(1) {
			**(**int8)(__ccgo_up((*TMem)(unsafe.Pointer(pMem)).Fz + uintptr((*TMem)(unsafe.Pointer(pMem)).Fn))) = 0
			v1 = pMem + 16
			*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) | libc.Int32FromInt32(MEM_Term))
			return int32(1)
		}
	}
	return 0
}

// C documentation
//
//	/*
//	** Invoke the pre-update hook. If this is an UPDATE or DELETE pre-update call,
//	** then cursor passed as the second argument should point to the row about
//	** to be update or deleted. If the application calls sqlite3_preupdate_old(),
//	** the required value will be read from the row the cursor points to.
//	*/
func _sqlite3VdbePreUpdateHook(tls *libc.TLS, v uintptr, pCsr uintptr, op int32, zDb uintptr, pTab uintptr, iKey1 Ti64, iReg int32, iBlobWrite int32) {
	bp := tls.Alloc(128)
	defer tls.Free(128)
	var db, zTbl uintptr
	var i, i1 int32
	var iKey2, v1 Ti64
	var _ /* preupdate at bp+0 */ TPreUpdate
	_, _, _, _, _, _ = db, i, i1, iKey2, zTbl, v1
	db = (*TVdbe)(unsafe.Pointer(v)).Fdb
	zTbl = (*TTable)(unsafe.Pointer(pTab)).FzName
	libc.Xmemset(tls, bp, 0, uint32(128))
	if libc.BoolInt32((*TTable)(unsafe.Pointer(pTab)).FtabFlags&uint32(TF_WithoutRowid) == uint32(0)) == 0 {
		v1 = libc.Int64FromInt32(0)
		iKey2 = v1
		iKey1 = v1
		(**(**TPreUpdate)(__ccgo_up(bp))).FpPk = _sqlite3PrimaryKeyIndex(tls, pTab)
	} else {
		if op == int32(SQLITE_UPDATE) {
			iKey2 = *(*Ti64)(unsafe.Pointer((*TVdbe)(unsafe.Pointer(v)).FaMem + uintptr(iReg)*40))
		} else {
			iKey2 = iKey1
		}
	}
	(**(**TPreUpdate)(__ccgo_up(bp))).Fv = v
	(**(**TPreUpdate)(__ccgo_up(bp))).FpCsr = pCsr
	(**(**TPreUpdate)(__ccgo_up(bp))).Fop = op
	(**(**TPreUpdate)(__ccgo_up(bp))).FiNewReg = iReg
	(**(**TPreUpdate)(__ccgo_up(bp))).FpKeyinfo = bp + 108
	(*TKeyInfo)(unsafe.Pointer((**(**TPreUpdate)(__ccgo_up(bp))).FpKeyinfo)).Fdb = db
	(*TKeyInfo)(unsafe.Pointer((**(**TPreUpdate)(__ccgo_up(bp))).FpKeyinfo)).Fenc = (*Tsqlite3)(unsafe.Pointer(db)).Fenc
	(*TKeyInfo)(unsafe.Pointer((**(**TPreUpdate)(__ccgo_up(bp))).FpKeyinfo)).FnKeyField = libc.Uint16FromInt16((*TTable)(unsafe.Pointer(pTab)).FnCol)
	(*TKeyInfo)(unsafe.Pointer((**(**TPreUpdate)(__ccgo_up(bp))).FpKeyinfo)).FaSortFlags = uintptr(0) /* Indicate .aColl, .nAllField uninit */
	(**(**TPreUpdate)(__ccgo_up(bp))).FiKey1 = iKey1
	(**(**TPreUpdate)(__ccgo_up(bp))).FiKey2 = iKey2
	(**(**TPreUpdate)(__ccgo_up(bp))).FpTab = pTab
	(**(**TPreUpdate)(__ccgo_up(bp))).FiBlobWrite = iBlobWrite
	(*Tsqlite3)(unsafe.Pointer(db)).FpPreUpdate = bp
	(*(*func(*libc.TLS, uintptr, uintptr, int32, uintptr, uintptr, Tsqlite3_int64, Tsqlite3_int64))(unsafe.Pointer(&struct{ uintptr }{(*Tsqlite3)(unsafe.Pointer(db)).FxPreUpdateCallback})))(tls, (*Tsqlite3)(unsafe.Pointer(db)).FpPreUpdateArg, db, op, zDb, zTbl, iKey1, iKey2)
	(*Tsqlite3)(unsafe.Pointer(db)).FpPreUpdate = uintptr(0)
	_sqlite3DbFree(tls, db, (**(**TPreUpdate)(__ccgo_up(bp))).FaRecord)
	_vdbeFreeUnpacked(tls, db, libc.Int32FromUint16((*TKeyInfo)(unsafe.Pointer((**(**TPreUpdate)(__ccgo_up(bp))).FpKeyinfo)).FnKeyField)+int32(1), (**(**TPreUpdate)(__ccgo_up(bp))).FpUnpacked)
	_vdbeFreeUnpacked(tls, db, libc.Int32FromUint16((*TKeyInfo)(unsafe.Pointer((**(**TPreUpdate)(__ccgo_up(bp))).FpKeyinfo)).FnKeyField)+int32(1), (**(**TPreUpdate)(__ccgo_up(bp))).FpNewUnpacked)
	_sqlite3VdbeMemRelease(tls, bp+52)
	if (**(**TPreUpdate)(__ccgo_up(bp))).FaNew != 0 {
		i = 0
		for {
			if !(i < int32((*TVdbeCursor)(unsafe.Pointer(pCsr)).FnField)) {
				break
			}
			_sqlite3VdbeMemRelease(tls, (**(**TPreUpdate)(__ccgo_up(bp))).FaNew+uintptr(i)*40)
			goto _2
		_2:
			;
			i = i + 1
		}
		_sqlite3DbNNFreeNN(tls, db, (**(**TPreUpdate)(__ccgo_up(bp))).FaNew)
	}
	if (**(**TPreUpdate)(__ccgo_up(bp))).FapDflt != 0 {
		i1 = 0
		for {
			if !(i1 < int32((*TTable)(unsafe.Pointer(pTab)).FnCol)) {
				break
			}
			_sqlite3ValueFree(tls, **(**uintptr)(__ccgo_up((**(**TPreUpdate)(__ccgo_up(bp))).FapDflt + uintptr(i1)*4)))
			goto _3
		_3:
			;
			i1 = i1 + 1
		}
		_sqlite3DbFree(tls, db, (**(**TPreUpdate)(__ccgo_up(bp))).FapDflt)
	}
}

/************** End of vdbeaux.c *********************************************/
/************** Begin file vdbeapi.c *****************************************/
/*
** 2004 May 26
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains code use to implement APIs that are part of the
** VDBE.
 */
/* #include "sqliteInt.h" */
/* #include "vdbeInt.h" */
/* #include "opcodes.h" */

// C documentation
//
//	/*
//	** This function compares the two table rows or index records
//	** specified by {nKey1, pKey1} and pPKey2.  It returns a negative, zero
//	** or positive integer if key1 is less than, equal to or
//	** greater than key2.  The {nKey1, pKey1} key must be a blob
//	** created by the OP_MakeRecord opcode of the VDBE.  The pPKey2
//	** key must be a parsed key such as obtained from
//	** sqlite3VdbeParseRecord.
//	**
//	** If argument bSkip is non-zero, it is assumed that the caller has already
//	** determined that the first fields of the keys are equal.
//	**
//	** Key1 and Key2 do not have to contain the same number of fields. If all
//	** fields that appear in both keys are equal, then pPKey2->default_rc is
//	** returned.
//	**
//	** If database corruption is discovered, set pPKey2->errCode to
//	** SQLITE_CORRUPT and return 0. If an OOM error is encountered,
//	** pPKey2->errCode is set to SQLITE_NOMEM and, if it is not NULL, the
//	** malloc-failed flag set on database handle (pPKey2->pKeyInfo->db).
//	*/
func _sqlite3VdbeRecordCompareWithSkip(tls *libc.TLS, nKey1 int32, pKey1 uintptr, pPKey2 uintptr, bSkip int32) (r int32) {
	bp := tls.Alloc(64)
	defer tls.Free(64)
	var aKey1, pKeyInfo, pRhs, v4 uintptr
	var d1, idx1, v1 Tu32
	var i, nCmp, nCmp1, nStr, rc, sortFlags, v2 int32
	var lhs, rhs Ti64
	var v5 bool
	var _ /* mem1 at bp+4 */ TMem
	var _ /* s1 at bp+44 */ Tu32
	var _ /* serial_type at bp+48 */ Tu32
	var _ /* szHdr1 at bp+0 */ Tu32
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = aKey1, d1, i, idx1, lhs, nCmp, nCmp1, nStr, pKeyInfo, pRhs, rc, rhs, sortFlags, v1, v2, v4, v5 /* Offset of first type in header */
	rc = 0                                                                                                                                             /* Return value */
	pRhs = (*TUnpackedRecord)(unsafe.Pointer(pPKey2)).FaMem
	aKey1 = pKey1
	/* If bSkip is true, then the caller has already determined that the first
	 ** two elements in the keys are equal. Fix the various stack variables so
	 ** that this routine begins comparing at the second field. */
	if bSkip != 0 {
		**(**Tu32)(__ccgo_up(bp + 44)) = uint32(**(**uint8)(__ccgo_up(aKey1 + 1)))
		if **(**Tu32)(__ccgo_up(bp + 44)) < uint32(0x80) {
			idx1 = uint32(2)
		} else {
			idx1 = libc.Uint32FromInt32(int32(1) + libc.Int32FromUint8(_sqlite3GetVarint32(tls, aKey1+1, bp+44)))
		}
		**(**Tu32)(__ccgo_up(bp)) = uint32(**(**uint8)(__ccgo_up(aKey1)))
		d1 = **(**Tu32)(__ccgo_up(bp)) + _sqlite3VdbeSerialTypeLen(tls, **(**Tu32)(__ccgo_up(bp + 44)))
		i = int32(1)
		pRhs += 40
	} else {
		v1 = uint32(**(**uint8)(__ccgo_up(aKey1)))
		**(**Tu32)(__ccgo_up(bp)) = v1
		if v1 < uint32(0x80) {
			idx1 = uint32(1)
		} else {
			idx1 = uint32(_sqlite3GetVarint32(tls, aKey1, bp))
		}
		d1 = **(**Tu32)(__ccgo_up(bp))
		i = 0
	}
	if d1 > libc.Uint32FromInt32(nKey1) {
		(*TUnpackedRecord)(unsafe.Pointer(pPKey2)).FerrCode = libc.Uint8FromInt32(_sqlite3CorruptError(tls, int32(92522)))
		return 0 /* Corruption */
	}
	/* Only needed by assert() statements */
	for int32(1) != 0 {
		/* RHS is an integer */
		if libc.Int32FromUint16((*TMem)(unsafe.Pointer(pRhs)).Fflags)&(libc.Int32FromInt32(MEM_Int)|libc.Int32FromInt32(MEM_IntReal)) != 0 {
			**(**Tu32)(__ccgo_up(bp + 48)) = uint32(**(**uint8)(__ccgo_up(aKey1 + uintptr(idx1))))
			if **(**Tu32)(__ccgo_up(bp + 48)) >= uint32(10) {
				if **(**Tu32)(__ccgo_up(bp + 48)) == uint32(10) {
					v2 = -int32(1)
				} else {
					v2 = +libc.Int32FromInt32(1)
				}
				rc = v2
			} else {
				if **(**Tu32)(__ccgo_up(bp + 48)) == uint32(0) {
					rc = -int32(1)
				} else {
					if **(**Tu32)(__ccgo_up(bp + 48)) == uint32(7) {
						_serialGet7(tls, aKey1+uintptr(d1), bp+4)
						rc = -_sqlite3IntFloatCompare(tls, *(*Ti64)(unsafe.Pointer(pRhs)), *(*float64)(unsafe.Pointer(bp + 4)))
					} else {
						lhs = _vdbeRecordDecodeInt(tls, **(**Tu32)(__ccgo_up(bp + 48)), aKey1+uintptr(d1))
						rhs = *(*Ti64)(unsafe.Pointer(pRhs))
						if lhs < rhs {
							rc = -int32(1)
						} else {
							if lhs > rhs {
								rc = +libc.Int32FromInt32(1)
							}
						}
					}
				}
			}
		} else {
			if libc.Int32FromUint16((*TMem)(unsafe.Pointer(pRhs)).Fflags)&int32(MEM_Real) != 0 {
				**(**Tu32)(__ccgo_up(bp + 48)) = uint32(**(**uint8)(__ccgo_up(aKey1 + uintptr(idx1))))
				if **(**Tu32)(__ccgo_up(bp + 48)) >= uint32(10) {
					/* Serial types 12 or greater are strings and blobs (greater than
					 ** numbers). Types 10 and 11 are currently "reserved for future
					 ** use", so it doesn't really matter what the results of comparing
					 ** them to numeric values are.  */
					if **(**Tu32)(__ccgo_up(bp + 48)) == uint32(10) {
						v2 = -int32(1)
					} else {
						v2 = +libc.Int32FromInt32(1)
					}
					rc = v2
				} else {
					if **(**Tu32)(__ccgo_up(bp + 48)) == uint32(0) {
						rc = -int32(1)
					} else {
						if **(**Tu32)(__ccgo_up(bp + 48)) == uint32(7) {
							if _serialGet7(tls, aKey1+uintptr(d1), bp+4) != 0 {
								rc = -int32(1) /* mem1 is a NaN */
							} else {
								if *(*float64)(unsafe.Pointer(bp + 4)) < *(*float64)(unsafe.Pointer(pRhs)) {
									rc = -int32(1)
								} else {
									if *(*float64)(unsafe.Pointer(bp + 4)) > *(*float64)(unsafe.Pointer(pRhs)) {
										rc = +libc.Int32FromInt32(1)
									} else {
									}
								}
							}
						} else {
							_sqlite3VdbeSerialGet(tls, aKey1+uintptr(d1), **(**Tu32)(__ccgo_up(bp + 48)), bp+4)
							rc = _sqlite3IntFloatCompare(tls, *(*Ti64)(unsafe.Pointer(bp + 4)), *(*float64)(unsafe.Pointer(pRhs)))
						}
					}
				}
			} else {
				if libc.Int32FromUint16((*TMem)(unsafe.Pointer(pRhs)).Fflags)&int32(MEM_Str) != 0 {
					**(**Tu32)(__ccgo_up(bp + 48)) = uint32(**(**uint8)(__ccgo_up(aKey1 + uintptr(idx1))))
					if **(**Tu32)(__ccgo_up(bp + 48)) >= uint32(0x80) {
						_sqlite3GetVarint32(tls, aKey1+uintptr(idx1), bp+48)
					}
					if **(**Tu32)(__ccgo_up(bp + 48)) < uint32(12) {
						rc = -int32(1)
					} else {
						if !(**(**Tu32)(__ccgo_up(bp + 48))&libc.Uint32FromInt32(0x01) != 0) {
							rc = +libc.Int32FromInt32(1)
						} else {
							(**(**TMem)(__ccgo_up(bp + 4))).Fn = libc.Int32FromUint32((**(**Tu32)(__ccgo_up(bp + 48)) - uint32(12)) / uint32(2))
							if v5 = d1+libc.Uint32FromInt32((**(**TMem)(__ccgo_up(bp + 4))).Fn) > libc.Uint32FromInt32(nKey1); !v5 {
								v4 = (*TUnpackedRecord)(unsafe.Pointer(pPKey2)).FpKeyInfo
								pKeyInfo = v4
							}
							if v5 || libc.Int32FromUint16((*TKeyInfo)(unsafe.Pointer(v4)).FnAllField) <= i {
								(*TUnpackedRecord)(unsafe.Pointer(pPKey2)).FerrCode = libc.Uint8FromInt32(_sqlite3CorruptError(tls, int32(92603)))
								return 0 /* Corruption */
							} else {
								if *(*uintptr)(unsafe.Pointer(pKeyInfo + 20 + uintptr(i)*4)) != 0 {
									(**(**TMem)(__ccgo_up(bp + 4))).Fenc = (*TKeyInfo)(unsafe.Pointer(pKeyInfo)).Fenc
									(**(**TMem)(__ccgo_up(bp + 4))).Fdb = (*TKeyInfo)(unsafe.Pointer(pKeyInfo)).Fdb
									(**(**TMem)(__ccgo_up(bp + 4))).Fflags = uint16(MEM_Str)
									(**(**TMem)(__ccgo_up(bp + 4))).Fz = aKey1 + uintptr(d1)
									rc = _vdbeCompareMemString(tls, bp+4, pRhs, *(*uintptr)(unsafe.Pointer(pKeyInfo + 20 + uintptr(i)*4)), pPKey2+23)
								} else {
									if (**(**TMem)(__ccgo_up(bp + 4))).Fn < (*TMem)(unsafe.Pointer(pRhs)).Fn {
										v2 = (**(**TMem)(__ccgo_up(bp + 4))).Fn
									} else {
										v2 = (*TMem)(unsafe.Pointer(pRhs)).Fn
									}
									nCmp = v2
									rc = libc.Xmemcmp(tls, aKey1+uintptr(d1), (*TMem)(unsafe.Pointer(pRhs)).Fz, libc.Uint32FromInt32(nCmp))
									if rc == 0 {
										rc = (**(**TMem)(__ccgo_up(bp + 4))).Fn - (*TMem)(unsafe.Pointer(pRhs)).Fn
									}
								}
							}
						}
					}
				} else {
					if libc.Int32FromUint16((*TMem)(unsafe.Pointer(pRhs)).Fflags)&int32(MEM_Blob) != 0 {
						**(**Tu32)(__ccgo_up(bp + 48)) = uint32(**(**uint8)(__ccgo_up(aKey1 + uintptr(idx1))))
						if **(**Tu32)(__ccgo_up(bp + 48)) >= uint32(0x80) {
							_sqlite3GetVarint32(tls, aKey1+uintptr(idx1), bp+48)
						}
						if **(**Tu32)(__ccgo_up(bp + 48)) < uint32(12) || **(**Tu32)(__ccgo_up(bp + 48))&uint32(0x01) != 0 {
							rc = -int32(1)
						} else {
							nStr = libc.Int32FromUint32((**(**Tu32)(__ccgo_up(bp + 48)) - uint32(12)) / uint32(2))
							if d1+libc.Uint32FromInt32(nStr) > libc.Uint32FromInt32(nKey1) {
								(*TUnpackedRecord)(unsafe.Pointer(pPKey2)).FerrCode = libc.Uint8FromInt32(_sqlite3CorruptError(tls, int32(92633)))
								return 0 /* Corruption */
							} else {
								if libc.Int32FromUint16((*TMem)(unsafe.Pointer(pRhs)).Fflags)&int32(MEM_Zero) != 0 {
									if !(_isAllZero(tls, aKey1+uintptr(d1), nStr) != 0) {
										rc = int32(1)
									} else {
										rc = nStr - *(*int32)(unsafe.Pointer(&(*TMem)(unsafe.Pointer(pRhs)).Fu))
									}
								} else {
									if nStr < (*TMem)(unsafe.Pointer(pRhs)).Fn {
										v2 = nStr
									} else {
										v2 = (*TMem)(unsafe.Pointer(pRhs)).Fn
									}
									nCmp1 = v2
									rc = libc.Xmemcmp(tls, aKey1+uintptr(d1), (*TMem)(unsafe.Pointer(pRhs)).Fz, libc.Uint32FromInt32(nCmp1))
									if rc == 0 {
										rc = nStr - (*TMem)(unsafe.Pointer(pRhs)).Fn
									}
								}
							}
						}
					} else {
						**(**Tu32)(__ccgo_up(bp + 48)) = uint32(**(**uint8)(__ccgo_up(aKey1 + uintptr(idx1))))
						if **(**Tu32)(__ccgo_up(bp + 48)) == uint32(0) || **(**Tu32)(__ccgo_up(bp + 48)) == uint32(10) || **(**Tu32)(__ccgo_up(bp + 48)) == uint32(7) && _serialGet7(tls, aKey1+uintptr(d1), bp+4) != 0 {
						} else {
							rc = int32(1)
						}
					}
				}
			}
		}
		if rc != 0 {
			sortFlags = libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TKeyInfo)(unsafe.Pointer((*TUnpackedRecord)(unsafe.Pointer(pPKey2)).FpKeyInfo)).FaSortFlags + uintptr(i))))
			if sortFlags != 0 {
				if sortFlags&int32(KEYINFO_ORDER_BIGNULL) == 0 || sortFlags&int32(KEYINFO_ORDER_DESC) != libc.BoolInt32(**(**Tu32)(__ccgo_up(bp + 48)) == uint32(0) || libc.Int32FromUint16((*TMem)(unsafe.Pointer(pRhs)).Fflags)&int32(MEM_Null) != 0) {
					rc = -rc
				}
			}
			/* See comment below */
			return rc
		}
		i = i + 1
		if i == libc.Int32FromUint16((*TUnpackedRecord)(unsafe.Pointer(pPKey2)).FnField) {
			break
		}
		pRhs += 40
		d1 = d1 + _sqlite3VdbeSerialTypeLen(tls, **(**Tu32)(__ccgo_up(bp + 48)))
		if d1 > libc.Uint32FromInt32(nKey1) {
			break
		}
		idx1 = idx1 + libc.Uint32FromInt32(_sqlite3VarintLen(tls, uint64(**(**Tu32)(__ccgo_up(bp + 48)))))
		if idx1 >= **(**Tu32)(__ccgo_up(bp)) {
			(*TUnpackedRecord)(unsafe.Pointer(pPKey2)).FerrCode = libc.Uint8FromInt32(_sqlite3CorruptError(tls, int32(92684)))
			return 0 /* Corrupt index */
		}
	}
	/* No memory allocation is ever used on mem1.  Prove this using
	 ** the following assert().  If the assert() fails, it indicates a
	 ** memory leak and a need to call sqlite3VdbeMemRelease(&mem1).  */
	/* rc==0 here means that one or both of the keys ran out of fields and
	 ** all the fields up to that point were equal. Return the default_rc
	 ** value.  */
	(*TUnpackedRecord)(unsafe.Pointer(pPKey2)).FeqSeen = uint8(1)
	return int32((*TUnpackedRecord)(unsafe.Pointer(pPKey2)).Fdefault_rc)
}

// C documentation
//
//	/*
//	** This routine sets the value to be returned by subsequent calls to
//	** sqlite3_changes() on the database handle 'db'.
//	*/
func _sqlite3VdbeSetChanges(tls *libc.TLS, db uintptr, nChange Ti64) {
	(*Tsqlite3)(unsafe.Pointer(db)).FnChange = nChange
	**(**Ti64)(__ccgo_up(db + 108)) += nChange
}

// C documentation
//
//	/*
//	** Configure SQL variable iVar so that binding a new value to it signals
//	** to sqlite3_reoptimize() that re-preparing the statement may result
//	** in a better query plan.
//	*/
func _sqlite3VdbeSetVarmask(tls *libc.TLS, v uintptr, iVar int32) {
	if iVar >= int32(32) {
		**(**Tu32)(__ccgo_up(v + 212)) |= uint32(0x80000000)
	} else {
		**(**Tu32)(__ccgo_up(v + 212)) |= libc.Uint32FromInt32(1) << (iVar - libc.Int32FromInt32(1))
	}
}

// C documentation
//
//	/*
//	** Free any cursor components allocated by sqlite3VdbeSorterXXX routines.
//	*/
func _sqlite3VdbeSorterClose(tls *libc.TLS, db uintptr, pCsr uintptr) {
	var ii int32
	var pSorter uintptr
	_, _ = ii, pSorter
	pSorter = *(*uintptr)(unsafe.Pointer(pCsr + 36))
	if pSorter != 0 {
		ii = 0
		for {
			if !(ii < libc.Int32FromUint8((*TVdbeSorter)(unsafe.Pointer(pSorter)).FnTask)) {
				break
			}
			**(**Tu64)(__ccgo_up(db + 548)) += (*(*TSortSubtask)(unsafe.Pointer(pSorter + 68 + uintptr(ii)*72))).FnSpill
			goto _1
		_1:
			;
			ii = ii + 1
		}
		_sqlite3VdbeSorterReset(tls, db, pSorter)
		Xsqlite3_free(tls, (*TVdbeSorter)(unsafe.Pointer(pSorter)).Flist.FaMemory)
		_sqlite3DbFree(tls, db, pSorter)
		*(*uintptr)(unsafe.Pointer(pCsr + 36)) = uintptr(0)
	}
}

// C documentation
//
//	/*
//	** Initialize the temporary index cursor just opened as a sorter cursor.
//	**
//	** Usually, the sorter module uses the value of (pCsr->pKeyInfo->nKeyField)
//	** to determine the number of fields that should be compared from the
//	** records being sorted. However, if the value passed as argument nField
//	** is non-zero and the sorter is able to guarantee a stable sort, nField
//	** is used instead. This is used when sorting records for a CREATE INDEX
//	** statement. In this case, keys are always delivered to the sorter in
//	** order of the primary key, which happens to be make up the final part
//	** of the records being sorted. So if the sort is stable, there is never
//	** any reason to compare PK fields and they can be ignored for a small
//	** performance boost.
//	**
//	** The sorter can guarantee a stable sort when running in single-threaded
//	** mode, but not in multi-threaded mode.
//	**
//	** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
//	*/
func _sqlite3VdbeSorterInit(tls *libc.TLS, db uintptr, nField int32, pCsr uintptr) (r int32) {
	var i, nWorker, pgsz, rc, szKeyInfo, v2 int32
	var mxCache, sz Ti64
	var pBt, pKeyInfo, pSorter, pTask, v1 uintptr
	var szPma Tu32
	var v4 int64
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = i, mxCache, nWorker, pBt, pKeyInfo, pSorter, pTask, pgsz, rc, sz, szKeyInfo, szPma, v1, v2, v4 /* Size of pSorter in bytes */
	rc = SQLITE_OK
	/* Initialize the upper limit on the number of worker threads */
	if _sqlite3TempInMemory(tls, db) != 0 || libc.Int32FromUint8(_sqlite3Config.FbCoreMutex) == 0 {
		nWorker = 0
	} else {
		nWorker = **(**int32)(__ccgo_up(db + 116 + 11*4))
	}
	/* Do not allow the total number of threads (main thread + all workers)
	 ** to exceed the maximum merge count */
	szKeyInfo = libc.Int32FromUint32(uint32(libc.UintptrFromInt32(0)+20) + uint32((*TKeyInfo)(unsafe.Pointer((*TVdbeCursor)(unsafe.Pointer(pCsr)).FpKeyInfo)).FnAllField)*libc.Uint32FromInt64(4))
	sz = libc.Int64FromUint32(uint32(libc.UintptrFromInt32(0)+68) + libc.Uint32FromInt32(nWorker+libc.Int32FromInt32(1))*libc.Uint32FromInt64(72))
	pSorter = _sqlite3DbMallocZero(tls, db, libc.Uint64FromInt64(sz+int64(szKeyInfo)))
	*(*uintptr)(unsafe.Pointer(pCsr + 36)) = pSorter
	if pSorter == uintptr(0) {
		rc = int32(SQLITE_NOMEM)
	} else {
		pBt = (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb))).FpBt
		v1 = pSorter + uintptr(sz)
		pKeyInfo = v1
		(*TVdbeSorter)(unsafe.Pointer(pSorter)).FpKeyInfo = v1
		libc.Xmemcpy(tls, pKeyInfo, (*TVdbeCursor)(unsafe.Pointer(pCsr)).FpKeyInfo, libc.Uint32FromInt32(szKeyInfo))
		(*TKeyInfo)(unsafe.Pointer(pKeyInfo)).Fdb = uintptr(0)
		if nField != 0 && nWorker == 0 {
			(*TKeyInfo)(unsafe.Pointer(pKeyInfo)).FnKeyField = libc.Uint16FromInt32(nField)
		}
		/* It is OK that pKeyInfo reuses the aSortFlags field from pCsr->pKeyInfo,
		 ** since the pCsr->pKeyInfo->aSortFlags[] array is invariant and lives
		 ** longer that pSorter. */
		_sqlite3BtreeEnter(tls, pBt)
		v2 = _sqlite3BtreeGetPageSize(tls, pBt)
		pgsz = v2
		(*TVdbeSorter)(unsafe.Pointer(pSorter)).Fpgsz = v2
		_sqlite3BtreeLeave(tls, pBt)
		(*TVdbeSorter)(unsafe.Pointer(pSorter)).FnTask = libc.Uint8FromInt32(nWorker + int32(1))
		(*TVdbeSorter)(unsafe.Pointer(pSorter)).FiPrev = libc.Uint8FromInt32(nWorker - libc.Int32FromInt32(1))
		(*TVdbeSorter)(unsafe.Pointer(pSorter)).FbUseThreads = libc.BoolUint8(libc.Int32FromUint8((*TVdbeSorter)(unsafe.Pointer(pSorter)).FnTask) > libc.Int32FromInt32(1))
		(*TVdbeSorter)(unsafe.Pointer(pSorter)).Fdb = db
		i = 0
		for {
			if !(i < libc.Int32FromUint8((*TVdbeSorter)(unsafe.Pointer(pSorter)).FnTask)) {
				break
			}
			pTask = pSorter + 68 + uintptr(i)*72
			(*TSortSubtask)(unsafe.Pointer(pTask)).FpSorter = pSorter
			goto _3
		_3:
			;
			i = i + 1
		}
		if !(_sqlite3TempInMemory(tls, db) != 0) { /* Cache size in bytes*/
			szPma = _sqlite3Config.FszPma
			(*TVdbeSorter)(unsafe.Pointer(pSorter)).FmnPmaSize = libc.Int32FromUint32(szPma * libc.Uint32FromInt32(pgsz))
			mxCache = int64((*TSchema)(unsafe.Pointer((**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb))).FpSchema)).Fcache_size)
			if mxCache < 0 {
				/* A negative cache-size value C indicates that the cache is abs(C)
				 ** KiB in size.  */
				mxCache = mxCache * int64(-int32(1024))
			} else {
				mxCache = mxCache * int64(pgsz)
			}
			if mxCache < int64(libc.Int32FromInt32(1)<<libc.Int32FromInt32(29)) {
				v4 = mxCache
			} else {
				v4 = int64(libc.Int32FromInt32(1) << libc.Int32FromInt32(29))
			}
			mxCache = v4
			if (*TVdbeSorter)(unsafe.Pointer(pSorter)).FmnPmaSize > int32(mxCache) {
				v2 = (*TVdbeSorter)(unsafe.Pointer(pSorter)).FmnPmaSize
			} else {
				v2 = int32(mxCache)
			}
			(*TVdbeSorter)(unsafe.Pointer(pSorter)).FmxPmaSize = v2
			/* Avoid large memory allocations if the application has requested
			 ** SQLITE_CONFIG_SMALL_MALLOC. */
			if libc.Int32FromUint8(_sqlite3Config.FbSmallMalloc) == 0 {
				(*TVdbeSorter)(unsafe.Pointer(pSorter)).FnMemory = pgsz
				(*TVdbeSorter)(unsafe.Pointer(pSorter)).Flist.FaMemory = _sqlite3Malloc(tls, libc.Uint64FromInt32(pgsz))
				if !((*TVdbeSorter)(unsafe.Pointer(pSorter)).Flist.FaMemory != 0) {
					rc = int32(SQLITE_NOMEM)
				}
			}
		}
		if libc.Int32FromUint16((*TKeyInfo)(unsafe.Pointer(pKeyInfo)).FnAllField) < int32(13) && (*(*uintptr)(unsafe.Pointer(pKeyInfo + 20)) == uintptr(0) || *(*uintptr)(unsafe.Pointer(pKeyInfo + 20)) == (*Tsqlite3)(unsafe.Pointer(db)).FpDfltColl) && libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TKeyInfo)(unsafe.Pointer(pKeyInfo)).FaSortFlags)))&int32(KEYINFO_ORDER_BIGNULL) == 0 {
			(*TVdbeSorter)(unsafe.Pointer(pSorter)).FtypeMask = libc.Uint8FromInt32(libc.Int32FromInt32(SORTER_TYPE_INTEGER) | libc.Int32FromInt32(SORTER_TYPE_TEXT))
		}
	}
	return rc
}

// C documentation
//
//	/*
//	** Reset a sorting cursor back to its original empty state.
//	*/
func _sqlite3VdbeSorterReset(tls *libc.TLS, db uintptr, pSorter uintptr) {
	var i int32
	var pTask uintptr
	_, _ = i, pTask
	_vdbeSorterJoinAll(tls, pSorter, SQLITE_OK)
	if (*TVdbeSorter)(unsafe.Pointer(pSorter)).FpReader != 0 {
		_vdbePmaReaderClear(tls, (*TVdbeSorter)(unsafe.Pointer(pSorter)).FpReader)
		_sqlite3DbFree(tls, db, (*TVdbeSorter)(unsafe.Pointer(pSorter)).FpReader)
		(*TVdbeSorter)(unsafe.Pointer(pSorter)).FpReader = uintptr(0)
	}
	_vdbeMergeEngineFree(tls, (*TVdbeSorter)(unsafe.Pointer(pSorter)).FpMerger)
	(*TVdbeSorter)(unsafe.Pointer(pSorter)).FpMerger = uintptr(0)
	i = 0
	for {
		if !(i < libc.Int32FromUint8((*TVdbeSorter)(unsafe.Pointer(pSorter)).FnTask)) {
			break
		}
		pTask = pSorter + 68 + uintptr(i)*72
		_vdbeSortSubtaskCleanup(tls, db, pTask)
		(*TSortSubtask)(unsafe.Pointer(pTask)).FpSorter = pSorter
		goto _1
	_1:
		;
		i = i + 1
	}
	if (*TVdbeSorter)(unsafe.Pointer(pSorter)).Flist.FaMemory == uintptr(0) {
		_vdbeSorterRecordFree(tls, uintptr(0), (*TVdbeSorter)(unsafe.Pointer(pSorter)).Flist.FpList)
	}
	(*TVdbeSorter)(unsafe.Pointer(pSorter)).Flist.FpList = uintptr(0)
	(*TVdbeSorter)(unsafe.Pointer(pSorter)).Flist.FszPMA = 0
	(*TVdbeSorter)(unsafe.Pointer(pSorter)).FbUsePMA = uint8(0)
	(*TVdbeSorter)(unsafe.Pointer(pSorter)).FiMemory = 0
	(*TVdbeSorter)(unsafe.Pointer(pSorter)).FmxKeysize = 0
	_sqlite3DbFree(tls, db, (*TVdbeSorter)(unsafe.Pointer(pSorter)).FpUnpacked)
	(*TVdbeSorter)(unsafe.Pointer(pSorter)).FpUnpacked = uintptr(0)
}

// C documentation
//
//	/*
//	** Once the sorter has been populated by calls to sqlite3VdbeSorterWrite,
//	** this function is called to prepare for iterating through the records
//	** in sorted order.
//	*/
func _sqlite3VdbeSorterRewind(tls *libc.TLS, pCsr uintptr, pbEof uintptr) (r int32) {
	var pSorter uintptr
	var rc int32
	_, _ = pSorter, rc
	rc = SQLITE_OK /* Return code */
	pSorter = *(*uintptr)(unsafe.Pointer(pCsr + 36))
	/* If no data has been written to disk, then do not do so now. Instead,
	 ** sort the VdbeSorter.pRecord list. The vdbe layer will read data directly
	 ** from the in-memory list.  */
	if libc.Int32FromUint8((*TVdbeSorter)(unsafe.Pointer(pSorter)).FbUsePMA) == 0 {
		if (*TVdbeSorter)(unsafe.Pointer(pSorter)).Flist.FpList != 0 {
			**(**int32)(__ccgo_up(pbEof)) = 0
			rc = _vdbeSorterSort(tls, pSorter+68, pSorter+36)
		} else {
			**(**int32)(__ccgo_up(pbEof)) = int32(1)
		}
		return rc
	}
	/* Write the current in-memory list to a PMA. When the VdbeSorterWrite()
	 ** function flushes the contents of memory to disk, it immediately always
	 ** creates a new list consisting of a single key immediately afterwards.
	 ** So the list is never empty at this point.  */
	rc = _vdbeSorterFlushPMA(tls, pSorter)
	/* Join all threads */
	rc = _vdbeSorterJoinAll(tls, pSorter, rc)
	/* Assuming no errors have occurred, set up a merger structure to
	 ** incrementally read and merge all remaining PMAs.  */
	if rc == SQLITE_OK {
		rc = _vdbeSorterSetupMerge(tls, pSorter)
		**(**int32)(__ccgo_up(pbEof)) = 0
	}
	return rc
}

// C documentation
//
//	/*
//	** Add a record to the sorter.
//	*/
func _sqlite3VdbeSorterWrite(tls *libc.TLS, pCsr uintptr, pVal uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var aNew, pNew, pSorter, v1 uintptr
	var bFlush, iListOff, nMin, rc int32
	var nNew Tsqlite3_int64
	var nPMA, nReq Ti64
	var _ /* t at bp+0 */ int32
	_, _, _, _, _, _, _, _, _, _, _ = aNew, bFlush, iListOff, nMin, nNew, nPMA, nReq, pNew, pSorter, rc, v1
	rc = SQLITE_OK /* serial type of first record field */
	pSorter = *(*uintptr)(unsafe.Pointer(pCsr + 36))
	**(**int32)(__ccgo_up(bp)) = libc.Int32FromUint32(uint32(**(**Tu8)(__ccgo_up((*TMem)(unsafe.Pointer(pVal)).Fz + 1))))
	if **(**int32)(__ccgo_up(bp)) >= int32(0x80) {
		_sqlite3GetVarint32(tls, (*TMem)(unsafe.Pointer(pVal)).Fz+1, bp)
	}
	if **(**int32)(__ccgo_up(bp)) > 0 && **(**int32)(__ccgo_up(bp)) < int32(10) && **(**int32)(__ccgo_up(bp)) != int32(7) {
		v1 = pSorter + 64
		*(*Tu8)(unsafe.Pointer(v1)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v1))) & libc.Int32FromInt32(SORTER_TYPE_INTEGER))
	} else {
		if **(**int32)(__ccgo_up(bp)) > int32(10) && **(**int32)(__ccgo_up(bp))&int32(0x01) != 0 {
			v1 = pSorter + 64
			*(*Tu8)(unsafe.Pointer(v1)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v1))) & libc.Int32FromInt32(SORTER_TYPE_TEXT))
		} else {
			(*TVdbeSorter)(unsafe.Pointer(pSorter)).FtypeMask = uint8(0)
		}
	}
	/* Figure out whether or not the current contents of memory should be
	 ** flushed to a PMA before continuing. If so, do so.
	 **
	 ** If using the single large allocation mode (pSorter->aMemory!=0), then
	 ** flush the contents of memory to a new PMA if (a) at least one value is
	 ** already in memory and (b) the new value will not fit in memory.
	 **
	 ** Or, if using separate allocations for each record, flush the contents
	 ** of memory to a PMA if either of the following are true:
	 **
	 **   * The total memory allocated for the in-memory list is greater
	 **     than (page-size * cache-size), or
	 **
	 **   * The total memory allocated for the in-memory list is greater
	 **     than (page-size * 10) and sqlite3HeapNearlyFull() returns true.
	 */
	nReq = libc.Int64FromUint32(libc.Uint32FromInt32((*TMem)(unsafe.Pointer(pVal)).Fn) + uint32(8))
	nPMA = int64((*TMem)(unsafe.Pointer(pVal)).Fn + _sqlite3VarintLen(tls, libc.Uint64FromInt32((*TMem)(unsafe.Pointer(pVal)).Fn)))
	if (*TVdbeSorter)(unsafe.Pointer(pSorter)).FmxPmaSize != 0 {
		if (*TVdbeSorter)(unsafe.Pointer(pSorter)).Flist.FaMemory != 0 {
			bFlush = libc.BoolInt32((*TVdbeSorter)(unsafe.Pointer(pSorter)).FiMemory != 0 && int64((*TVdbeSorter)(unsafe.Pointer(pSorter)).FiMemory)+nReq > int64((*TVdbeSorter)(unsafe.Pointer(pSorter)).FmxPmaSize))
		} else {
			bFlush = libc.BoolInt32((*TVdbeSorter)(unsafe.Pointer(pSorter)).Flist.FszPMA > int64((*TVdbeSorter)(unsafe.Pointer(pSorter)).FmxPmaSize) || (*TVdbeSorter)(unsafe.Pointer(pSorter)).Flist.FszPMA > int64((*TVdbeSorter)(unsafe.Pointer(pSorter)).FmnPmaSize) && _sqlite3HeapNearlyFull(tls) != 0)
		}
		if bFlush != 0 {
			rc = _vdbeSorterFlushPMA(tls, pSorter)
			(*TVdbeSorter)(unsafe.Pointer(pSorter)).Flist.FszPMA = 0
			(*TVdbeSorter)(unsafe.Pointer(pSorter)).FiMemory = 0
		}
	}
	(*TVdbeSorter)(unsafe.Pointer(pSorter)).Flist.FszPMA += nPMA
	if nPMA > int64((*TVdbeSorter)(unsafe.Pointer(pSorter)).FmxKeysize) {
		(*TVdbeSorter)(unsafe.Pointer(pSorter)).FmxKeysize = int32(nPMA)
	}
	if (*TVdbeSorter)(unsafe.Pointer(pSorter)).Flist.FaMemory != 0 {
		nMin = int32(int64((*TVdbeSorter)(unsafe.Pointer(pSorter)).FiMemory) + nReq)
		if nMin > (*TVdbeSorter)(unsafe.Pointer(pSorter)).FnMemory {
			nNew = int64(2) * int64((*TVdbeSorter)(unsafe.Pointer(pSorter)).FnMemory)
			iListOff = -int32(1)
			if (*TVdbeSorter)(unsafe.Pointer(pSorter)).Flist.FpList != 0 {
				iListOff = int32((*TVdbeSorter)(unsafe.Pointer(pSorter)).Flist.FpList) - int32((*TVdbeSorter)(unsafe.Pointer(pSorter)).Flist.FaMemory)
			}
			for nNew < int64(nMin) {
				nNew = nNew * int64(2)
			}
			if nNew > int64((*TVdbeSorter)(unsafe.Pointer(pSorter)).FmxPmaSize) {
				nNew = int64((*TVdbeSorter)(unsafe.Pointer(pSorter)).FmxPmaSize)
			}
			if nNew < int64(nMin) {
				nNew = int64(nMin)
			}
			aNew = _sqlite3Realloc(tls, (*TVdbeSorter)(unsafe.Pointer(pSorter)).Flist.FaMemory, libc.Uint64FromInt64(nNew))
			if !(aNew != 0) {
				return int32(SQLITE_NOMEM)
			}
			if iListOff >= 0 {
				(*TVdbeSorter)(unsafe.Pointer(pSorter)).Flist.FpList = aNew + uintptr(iListOff)
			}
			(*TVdbeSorter)(unsafe.Pointer(pSorter)).Flist.FaMemory = aNew
			(*TVdbeSorter)(unsafe.Pointer(pSorter)).FnMemory = int32(nNew)
		}
		pNew = (*TVdbeSorter)(unsafe.Pointer(pSorter)).Flist.FaMemory + uintptr((*TVdbeSorter)(unsafe.Pointer(pSorter)).FiMemory)
		v1 = pSorter + 52
		*(*int32)(unsafe.Pointer(v1)) = int32(int64(*(*int32)(unsafe.Pointer(v1))) + (nReq+libc.Int64FromInt32(7))&int64(^libc.Int32FromInt32(7)))
		if (*TVdbeSorter)(unsafe.Pointer(pSorter)).Flist.FpList != 0 {
			*(*int32)(unsafe.Pointer(pNew + 4)) = int32((*TVdbeSorter)(unsafe.Pointer(pSorter)).Flist.FpList) - int32((*TVdbeSorter)(unsafe.Pointer(pSorter)).Flist.FaMemory)
		}
	} else {
		pNew = _sqlite3Malloc(tls, libc.Uint64FromInt64(nReq))
		if pNew == uintptr(0) {
			return int32(SQLITE_NOMEM)
		}
		*(*uintptr)(unsafe.Pointer(pNew + 4)) = (*TVdbeSorter)(unsafe.Pointer(pSorter)).Flist.FpList
	}
	libc.Xmemcpy(tls, pNew+libc.UintptrFromInt32(1)*8, (*TMem)(unsafe.Pointer(pVal)).Fz, libc.Uint32FromInt32((*TMem)(unsafe.Pointer(pVal)).Fn))
	(*TSorterRecord)(unsafe.Pointer(pNew)).FnVal = (*TMem)(unsafe.Pointer(pVal)).Fn
	(*TVdbeSorter)(unsafe.Pointer(pSorter)).Flist.FpList = pNew
	return rc
}

// C documentation
//
//	/*
//	** Swap byte-code between two VDBE structures.
//	**
//	** This happens after pB was previously run and returned
//	** SQLITE_SCHEMA.  The statement was then reprepared in pA.
//	** This routine transfers the new bytecode in pA over to pB
//	** so that pB can be run again.  The old pB byte code is
//	** moved back to pA so that it will be cleaned up when pA is
//	** finalized.
//	*/
func _sqlite3VdbeSwap(tls *libc.TLS, pA uintptr, pB uintptr) {
	var pTmp, ppTmp, zTmp uintptr
	var tmp TVdbe
	_, _, _, _ = pTmp, ppTmp, tmp, zTmp
	tmp = **(**TVdbe)(__ccgo_up(pA))
	**(**TVdbe)(__ccgo_up(pA)) = **(**TVdbe)(__ccgo_up(pB))
	**(**TVdbe)(__ccgo_up(pB)) = tmp
	pTmp = (*TVdbe)(unsafe.Pointer(pA)).FpVNext
	(*TVdbe)(unsafe.Pointer(pA)).FpVNext = (*TVdbe)(unsafe.Pointer(pB)).FpVNext
	(*TVdbe)(unsafe.Pointer(pB)).FpVNext = pTmp
	ppTmp = (*TVdbe)(unsafe.Pointer(pA)).FppVPrev
	(*TVdbe)(unsafe.Pointer(pA)).FppVPrev = (*TVdbe)(unsafe.Pointer(pB)).FppVPrev
	(*TVdbe)(unsafe.Pointer(pB)).FppVPrev = ppTmp
	zTmp = (*TVdbe)(unsafe.Pointer(pA)).FzSql
	(*TVdbe)(unsafe.Pointer(pA)).FzSql = (*TVdbe)(unsafe.Pointer(pB)).FzSql
	(*TVdbe)(unsafe.Pointer(pB)).FzSql = zTmp
	(*TVdbe)(unsafe.Pointer(pB)).Fexpmask = (*TVdbe)(unsafe.Pointer(pA)).Fexpmask
	(*TVdbe)(unsafe.Pointer(pB)).FprepFlags = (*TVdbe)(unsafe.Pointer(pA)).FprepFlags
	libc.Xmemcpy(tls, pB+156, pA+156, uint32(36))
	**(**Tu32)(__ccgo_up(pB + 156 + 5*4)) = **(**Tu32)(__ccgo_up(pB + 156 + 5*4)) + 1
}

// C documentation
//
//	/*
//	** Declare to the Vdbe that the BTree object at db->aDb[i] is used.
//	**
//	** The prepared statements need to know in advance the complete set of
//	** attached databases that will be use.  A mask of these databases
//	** is maintained in p->btreeMask.  The p->lockMask value is the subset of
//	** p->btreeMask of databases that will require a lock.
//	*/
func _sqlite3VdbeUsesBtree(tls *libc.TLS, p uintptr, i int32) {
	**(**TyDbMask)(__ccgo_up(p + 148)) |= libc.Uint32FromInt32(1) << i
	if i != int32(1) && _sqlite3BtreeSharable(tls, (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer((*TVdbe)(unsafe.Pointer(p)).Fdb)).FaDb + uintptr(i)*16))).FpBt) != 0 {
		**(**TyDbMask)(__ccgo_up(p + 152)) |= libc.Uint32FromInt32(1) << i
	}
}

// C documentation
//
//	/*
//	** Construct and install a Module object for a virtual table.  When this
//	** routine is called, it is guaranteed that all appropriate locks are held
//	** and the module is not already part of the connection.
//	**
//	** If there already exists a module with zName, replace it with the new one.
//	** If pModule==0, then delete the module zName if it exists.
//	*/
func _sqlite3VtabCreateModule(tls *libc.TLS, db uintptr, zName uintptr, pModule uintptr, pAux uintptr, __ccgo_fp_xDestroy uintptr) (r uintptr) {
	var nName int32
	var pDel, pMod, zCopy uintptr
	_, _, _, _ = nName, pDel, pMod, zCopy
	if pModule == uintptr(0) {
		zCopy = zName
		pMod = uintptr(0)
	} else {
		nName = _sqlite3Strlen30(tls, zName)
		pMod = _sqlite3Malloc(tls, uint64(uint32(24)+libc.Uint32FromInt32(nName)+uint32(1)))
		if pMod == uintptr(0) {
			_sqlite3OomFault(tls, db)
			return uintptr(0)
		}
		zCopy = pMod + 1*24
		libc.Xmemcpy(tls, zCopy, zName, libc.Uint32FromInt32(nName+int32(1)))
		(*TModule)(unsafe.Pointer(pMod)).FzName = zCopy
		(*TModule)(unsafe.Pointer(pMod)).FpModule = pModule
		(*TModule)(unsafe.Pointer(pMod)).FpAux = pAux
		(*TModule)(unsafe.Pointer(pMod)).FxDestroy = __ccgo_fp_xDestroy
		(*TModule)(unsafe.Pointer(pMod)).FpEpoTab = uintptr(0)
		(*TModule)(unsafe.Pointer(pMod)).FnRefModule = int32(1)
	}
	pDel = _sqlite3HashInsert(tls, db+400, zCopy, pMod)
	if pDel != 0 {
		if pDel == pMod {
			_sqlite3OomFault(tls, db)
			_sqlite3DbFree(tls, db, pDel)
			pMod = uintptr(0)
		} else {
			_sqlite3VtabEponymousTableClear(tls, db, pDel)
			_sqlite3VtabModuleUnref(tls, db, pDel)
		}
	}
	return pMod
}

// C documentation
//
//	/*
//	** Invoke either the xSavepoint, xRollbackTo or xRelease method of all
//	** virtual tables that currently have an open transaction. Pass iSavepoint
//	** as the second argument to the virtual table method invoked.
//	**
//	** If op is SAVEPOINT_BEGIN, the xSavepoint method is invoked. If it is
//	** SAVEPOINT_ROLLBACK, the xRollbackTo method. Otherwise, if op is
//	** SAVEPOINT_RELEASE, then the xRelease method of each virtual table with
//	** an open transaction is invoked.
//	**
//	** If any virtual table method returns an error code other than SQLITE_OK,
//	** processing is abandoned and the error returned to the caller of this
//	** function immediately. If all calls to virtual table methods are successful,
//	** SQLITE_OK is returned.
//	*/
func _sqlite3VtabSavepoint(tls *libc.TLS, db uintptr, op int32, iSavepoint int32) (r int32) {
	var i, rc int32
	var pMod, pVTab, xMethod uintptr
	var savedFlags Tu64
	_, _, _, _, _, _ = i, pMod, pVTab, rc, savedFlags, xMethod
	rc = SQLITE_OK
	if (*Tsqlite3)(unsafe.Pointer(db)).FaVTrans != 0 {
		i = 0
		for {
			if !(rc == SQLITE_OK && i < (*Tsqlite3)(unsafe.Pointer(db)).FnVTrans) {
				break
			}
			pVTab = **(**uintptr)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaVTrans + uintptr(i)*4))
			pMod = (*TModule)(unsafe.Pointer((*TVTable)(unsafe.Pointer(pVTab)).FpMod)).FpModule
			if (*TVTable)(unsafe.Pointer(pVTab)).FpVtab != 0 && (*Tsqlite3_module)(unsafe.Pointer(pMod)).FiVersion >= int32(2) {
				_sqlite3VtabLock(tls, pVTab)
				switch op {
				case SAVEPOINT_BEGIN:
					xMethod = (*Tsqlite3_module)(unsafe.Pointer(pMod)).FxSavepoint
					(*TVTable)(unsafe.Pointer(pVTab)).FiSavepoint = iSavepoint + int32(1)
				case int32(SAVEPOINT_ROLLBACK):
					xMethod = (*Tsqlite3_module)(unsafe.Pointer(pMod)).FxRollbackTo
				default:
					xMethod = (*Tsqlite3_module)(unsafe.Pointer(pMod)).FxRelease
					break
				}
				if xMethod != 0 && (*TVTable)(unsafe.Pointer(pVTab)).FiSavepoint > iSavepoint {
					savedFlags = (*Tsqlite3)(unsafe.Pointer(db)).Fflags & libc.Uint64FromInt32(SQLITE_Defensive)
					**(**Tu64)(__ccgo_up(db + 28)) &= ^libc.Uint64FromInt32(SQLITE_Defensive)
					rc = (*(*func(*libc.TLS, uintptr, int32) int32)(unsafe.Pointer(&struct{ uintptr }{xMethod})))(tls, (*TVTable)(unsafe.Pointer(pVTab)).FpVtab, iSavepoint)
					**(**Tu64)(__ccgo_up(db + 28)) |= savedFlags
				}
				_sqlite3VtabUnlock(tls, pVTab)
			}
			goto _1
		_1:
			;
			i = i + 1
		}
	}
	return rc
}

// C documentation
//
//	/*
//	** Open a connection to the WAL file zWalName. The database file must
//	** already be opened on connection pDbFd. The buffer that zWalName points
//	** to must remain valid for the lifetime of the returned Wal* handle.
//	**
//	** A SHARED lock should be held on the database file when this function
//	** is called. The purpose of this SHARED lock is to prevent any other
//	** client from unlinking the WAL or wal-index file. If another process
//	** were to do this just after this client opened one of these files, the
//	** system would be badly broken.
//	**
//	** If the log file is successfully opened, SQLITE_OK is returned and
//	** *ppWal is set to point to a new WAL handle. If an error occurs,
//	** an SQLite error code is returned and *ppWal is left unmodified.
//	*/
func _sqlite3WalOpen(tls *libc.TLS, pVfs uintptr, pDbFd uintptr, zWalName uintptr, bNoShm int32, mxWalSize Ti64, ppWal uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var iDC, rc, v1 int32
	var pRet uintptr
	var _ /* flags at bp+0 */ int32
	_, _, _, _ = iDC, pRet, rc, v1 /* Flags passed to OsOpen() */
	/* Verify the values of various constants.  Any changes to the values
	 ** of these constants would result in an incompatible on-disk format
	 ** for the -shm file.  Any change that causes one of these asserts to
	 ** fail is a backward compatibility problem, even if the change otherwise
	 ** works.
	 **
	 ** This table also serves as a helpful cross-reference when trying to
	 ** interpret hex dumps of the -shm file.
	 */
	/* In the amalgamation, the os_unix.c and os_win.c source files come before
	 ** this source file.  Verify that the #defines of the locking byte offsets
	 ** in os_unix.c and os_win.c agree with the WALINDEX_LOCK_OFFSET value.
	 ** For that matter, if the lock offset ever changes from its initial design
	 ** value of 120, we need to know that so there is an assert() to check it.
	 */
	/* Allocate an instance of struct Wal to return. */
	**(**uintptr)(__ccgo_up(ppWal)) = uintptr(0)
	pRet = _sqlite3MallocZero(tls, uint64(uint32(124)+libc.Uint32FromInt32((*Tsqlite3_vfs)(unsafe.Pointer(pVfs)).FszOsFile)))
	if !(pRet != 0) {
		return int32(SQLITE_NOMEM)
	}
	(*TWal)(unsafe.Pointer(pRet)).FpVfs = pVfs
	(*TWal)(unsafe.Pointer(pRet)).FpWalFd = pRet + 1*124
	(*TWal)(unsafe.Pointer(pRet)).FpDbFd = pDbFd
	(*TWal)(unsafe.Pointer(pRet)).FreadLock = int16(-int32(1))
	(*TWal)(unsafe.Pointer(pRet)).FmxWalSize = mxWalSize
	(*TWal)(unsafe.Pointer(pRet)).FzWalName = zWalName
	(*TWal)(unsafe.Pointer(pRet)).FsyncHeader = uint8(1)
	(*TWal)(unsafe.Pointer(pRet)).FpadToSectorBoundary = uint8(1)
	if bNoShm != 0 {
		v1 = int32(WAL_HEAPMEMORY_MODE)
	} else {
		v1 = WAL_NORMAL_MODE
	}
	(*TWal)(unsafe.Pointer(pRet)).FexclusiveMode = libc.Uint8FromInt32(v1)
	/* Open file handle on the write-ahead log file. */
	**(**int32)(__ccgo_up(bp)) = libc.Int32FromInt32(SQLITE_OPEN_READWRITE) | libc.Int32FromInt32(SQLITE_OPEN_CREATE) | libc.Int32FromInt32(SQLITE_OPEN_WAL)
	rc = _sqlite3OsOpen(tls, pVfs, zWalName, (*TWal)(unsafe.Pointer(pRet)).FpWalFd, **(**int32)(__ccgo_up(bp)), bp)
	if rc == SQLITE_OK && **(**int32)(__ccgo_up(bp))&int32(SQLITE_OPEN_READONLY) != 0 {
		(*TWal)(unsafe.Pointer(pRet)).FreadOnly = uint8(WAL_RDONLY)
	}
	if rc != SQLITE_OK {
		_walIndexClose(tls, pRet, 0)
		_sqlite3OsClose(tls, (*TWal)(unsafe.Pointer(pRet)).FpWalFd)
		Xsqlite3_free(tls, pRet)
	} else {
		iDC = _sqlite3OsDeviceCharacteristics(tls, pDbFd)
		if iDC&int32(SQLITE_IOCAP_SEQUENTIAL) != 0 {
			(*TWal)(unsafe.Pointer(pRet)).FsyncHeader = uint8(0)
		}
		if iDC&int32(SQLITE_IOCAP_POWERSAFE_OVERWRITE) != 0 {
			(*TWal)(unsafe.Pointer(pRet)).FpadToSectorBoundary = uint8(0)
		}
		**(**uintptr)(__ccgo_up(ppWal)) = pRet
	}
	return rc
}

// C documentation
//
//	/*
//	** Initialize a preallocated WhereClause structure.
//	*/
func _sqlite3WhereClauseInit(tls *libc.TLS, pWC uintptr, pWInfo uintptr) {
	(*TWhereClause)(unsafe.Pointer(pWC)).FpWInfo = pWInfo
	(*TWhereClause)(unsafe.Pointer(pWC)).FhasOr = uint8(0)
	(*TWhereClause)(unsafe.Pointer(pWC)).FpOuter = uintptr(0)
	(*TWhereClause)(unsafe.Pointer(pWC)).FnTerm = 0
	(*TWhereClause)(unsafe.Pointer(pWC)).FnBase = 0
	(*TWhereClause)(unsafe.Pointer(pWC)).FnSlot = libc.Int32FromUint32(libc.Uint32FromInt64(384) / libc.Uint32FromInt64(48))
	(*TWhereClause)(unsafe.Pointer(pWC)).Fa = pWC + 28
}

// C documentation
//
//	/* Allocate memory that is automatically freed when pWInfo is freed.
//	*/
func _sqlite3WhereMalloc(tls *libc.TLS, pWInfo uintptr, nByte Tu64) (r uintptr) {
	var pBlock uintptr
	_ = pBlock
	pBlock = _sqlite3DbMallocRawNN(tls, (*TParse)(unsafe.Pointer((*TWhereInfo)(unsafe.Pointer(pWInfo)).FpParse)).Fdb, nByte+uint64(12))
	if pBlock != 0 {
		(*TWhereMemBlock)(unsafe.Pointer(pBlock)).FpNext = (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpMemToFree
		(*TWhereMemBlock)(unsafe.Pointer(pBlock)).Fsz = nByte
		(*TWhereInfo)(unsafe.Pointer(pWInfo)).FpMemToFree = pBlock
		pBlock += 12
	}
	return pBlock
}

// C documentation
//
//	/*
//	** While generating code for the min/max optimization, after handling
//	** the aggregate-step call to min() or max(), check to see if any
//	** additional looping is required.  If the output order is such that
//	** we are certain that the correct answer has already been found, then
//	** code an OP_Goto to by pass subsequent processing.
//	**
//	** Any extra OP_Goto that is coded here is an optimization.  The
//	** correct answer should be obtained regardless.  This OP_Goto just
//	** makes the answer appear faster.
//	*/
func _sqlite3WhereMinMaxOptEarlyOut(tls *libc.TLS, v uintptr, pWInfo uintptr) {
	var i int32
	var pInner uintptr
	_, _ = i, pInner
	if !(int32(uint32(*(*uint8)(unsafe.Pointer(pWInfo + 48))&0x4>>2)) != 0) {
		return
	}
	if int32((*TWhereInfo)(unsafe.Pointer(pWInfo)).FnOBSat) == 0 {
		return
	}
	i = libc.Int32FromUint8((*TWhereInfo)(unsafe.Pointer(pWInfo)).FnLevel) - int32(1)
	for {
		if !(i >= 0) {
			break
		}
		pInner = pWInfo + 752 + uintptr(i)*88
		if (*TWhereLoop)(unsafe.Pointer((*TWhereLevel)(unsafe.Pointer(pInner)).FpWLoop)).FwsFlags&uint32(WHERE_COLUMN_IN) != uint32(0) {
			_sqlite3VdbeGoto(tls, v, (*TWhereLevel)(unsafe.Pointer(pInner)).FaddrNxt)
			return
		}
		goto _1
	_1:
		;
		i = i - 1
	}
	_sqlite3VdbeGoto(tls, v, (*TWhereInfo)(unsafe.Pointer(pWInfo)).FiBreak)
}

// C documentation
//
//	/*
//	** In the ORDER BY LIMIT optimization, if the inner-most loop is known
//	** to emit rows in increasing order, and if the last row emitted by the
//	** inner-most loop did not fit within the sorter, then we can skip all
//	** subsequent rows for the current iteration of the inner loop (because they
//	** will not fit in the sorter either) and continue with the second inner
//	** loop - the loop immediately outside the inner-most.
//	**
//	** When a row does not fit in the sorter (because the sorter already
//	** holds LIMIT+OFFSET rows that are smaller), then a jump is made to the
//	** label returned by this function.
//	**
//	** If the ORDER BY LIMIT optimization applies, the jump destination should
//	** be the continuation for the second-inner-most loop.  If the ORDER BY
//	** LIMIT optimization does not apply, then the jump destination should
//	** be the continuation for the inner-most loop.
//	**
//	** It is always safe for this routine to return the continuation of the
//	** inner-most loop, in the sense that a correct answer will result.
//	** Returning the continuation the second inner loop is an optimization
//	** that might make the code run a little faster, but should not change
//	** the final answer.
//	*/
func _sqlite3WhereOrderByLimitOptLabel(tls *libc.TLS, pWInfo uintptr) (r int32) {
	var pInner uintptr
	var v1 int32
	_, _ = pInner, v1
	if !(int32(uint32(*(*uint8)(unsafe.Pointer(pWInfo + 48))&0x4>>2)) != 0) {
		/* The ORDER BY LIMIT optimization does not apply.  Jump to the
		 ** continuation of the inner-most loop. */
		return (*TWhereInfo)(unsafe.Pointer(pWInfo)).FiContinue
	}
	pInner = pWInfo + 752 + uintptr(libc.Int32FromUint8((*TWhereInfo)(unsafe.Pointer(pWInfo)).FnLevel)-int32(1))*88
	if (*TWhereLevel)(unsafe.Pointer(pInner)).FpRJ != 0 {
		v1 = (*TWhereInfo)(unsafe.Pointer(pWInfo)).FiContinue
	} else {
		v1 = (*TWhereLevel)(unsafe.Pointer(pInner)).FaddrNxt
	}
	return v1
}

func _sqlite3WhereRealloc(tls *libc.TLS, pWInfo uintptr, pOld uintptr, nByte Tu64) (r uintptr) {
	var pNew, pOldBlk uintptr
	_, _ = pNew, pOldBlk
	pNew = _sqlite3WhereMalloc(tls, pWInfo, nByte)
	if pNew != 0 && pOld != 0 {
		pOldBlk = pOld
		pOldBlk -= 12
		libc.Xmemcpy(tls, pNew, pOld, uint32((*TWhereMemBlock)(unsafe.Pointer(pOldBlk)).Fsz))
	}
	return pNew
}

// C documentation
//
//	/*
//	** This is called by code in select.c before it calls sqlite3WhereBegin()
//	** to begin iterating through the sub-query results. It is used to allocate
//	** and initialize registers and cursors used by sqlite3WindowCodeStep().
//	*/
func _sqlite3WindowCodeInit(tls *libc.TLS, pParse uintptr, pSelect uintptr) {
	var nEphExpr, nExpr, v1 int32
	var p, pKeyInfo, pList, pMWin, pWin, v, v2 uintptr
	_, _, _, _, _, _, _, _, _, _ = nEphExpr, nExpr, p, pKeyInfo, pList, pMWin, pWin, v, v1, v2
	nEphExpr = (*TExprList)(unsafe.Pointer((*TSelect)(unsafe.Pointer((*TSubquery)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer((*TSelect)(unsafe.Pointer(pSelect)).FpSrc + 8 + 44)))).FpSelect)).FpEList)).FnExpr
	pMWin = (*TSelect)(unsafe.Pointer(pSelect)).FpWin
	v = _sqlite3GetVdbe(tls, pParse)
	_sqlite3VdbeAddOp2(tls, v, int32(OP_OpenEphemeral), (*TWindow)(unsafe.Pointer(pMWin)).FiEphCsr, nEphExpr)
	_sqlite3VdbeAddOp2(tls, v, int32(OP_OpenDup), (*TWindow)(unsafe.Pointer(pMWin)).FiEphCsr+int32(1), (*TWindow)(unsafe.Pointer(pMWin)).FiEphCsr)
	_sqlite3VdbeAddOp2(tls, v, int32(OP_OpenDup), (*TWindow)(unsafe.Pointer(pMWin)).FiEphCsr+int32(2), (*TWindow)(unsafe.Pointer(pMWin)).FiEphCsr)
	_sqlite3VdbeAddOp2(tls, v, int32(OP_OpenDup), (*TWindow)(unsafe.Pointer(pMWin)).FiEphCsr+int32(3), (*TWindow)(unsafe.Pointer(pMWin)).FiEphCsr)
	/* Allocate registers to use for PARTITION BY values, if any. Initialize
	 ** said registers to NULL.  */
	if (*TWindow)(unsafe.Pointer(pMWin)).FpPartition != 0 {
		nExpr = (*TExprList)(unsafe.Pointer((*TWindow)(unsafe.Pointer(pMWin)).FpPartition)).FnExpr
		(*TWindow)(unsafe.Pointer(pMWin)).FregPart = (*TParse)(unsafe.Pointer(pParse)).FnMem + int32(1)
		**(**int32)(__ccgo_up(pParse + 48)) += nExpr
		_sqlite3VdbeAddOp3(tls, v, int32(OP_Null), 0, (*TWindow)(unsafe.Pointer(pMWin)).FregPart, (*TWindow)(unsafe.Pointer(pMWin)).FregPart+nExpr-int32(1))
	}
	v2 = pParse + 48
	*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1
	v1 = *(*int32)(unsafe.Pointer(v2))
	(*TWindow)(unsafe.Pointer(pMWin)).FregOne = v1
	_sqlite3VdbeAddOp2(tls, v, int32(OP_Integer), int32(1), (*TWindow)(unsafe.Pointer(pMWin)).FregOne)
	if (*TWindow)(unsafe.Pointer(pMWin)).FeExclude != 0 {
		v2 = pParse + 48
		*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1
		v1 = *(*int32)(unsafe.Pointer(v2))
		(*TWindow)(unsafe.Pointer(pMWin)).FregStartRowid = v1
		v2 = pParse + 48
		*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1
		v1 = *(*int32)(unsafe.Pointer(v2))
		(*TWindow)(unsafe.Pointer(pMWin)).FregEndRowid = v1
		v2 = pParse + 44
		v1 = *(*int32)(unsafe.Pointer(v2))
		*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1
		(*TWindow)(unsafe.Pointer(pMWin)).FcsrApp = v1
		_sqlite3VdbeAddOp2(tls, v, int32(OP_Integer), int32(1), (*TWindow)(unsafe.Pointer(pMWin)).FregStartRowid)
		_sqlite3VdbeAddOp2(tls, v, int32(OP_Integer), 0, (*TWindow)(unsafe.Pointer(pMWin)).FregEndRowid)
		_sqlite3VdbeAddOp2(tls, v, int32(OP_OpenDup), (*TWindow)(unsafe.Pointer(pMWin)).FcsrApp, (*TWindow)(unsafe.Pointer(pMWin)).FiEphCsr)
		return
	}
	pWin = pMWin
	for {
		if !(pWin != 0) {
			break
		}
		p = (*TWindow)(unsafe.Pointer(pWin)).FpWFunc
		if (*TFuncDef)(unsafe.Pointer(p)).FfuncFlags&uint32(SQLITE_FUNC_MINMAX) != 0 && libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pWin)).FeStart) != int32(TK_UNBOUNDED) {
			pList = *(*uintptr)(unsafe.Pointer((*TWindow)(unsafe.Pointer(pWin)).FpOwner + 20))
			pKeyInfo = _sqlite3KeyInfoFromExprList(tls, pParse, pList, 0, 0)
			v2 = pParse + 44
			v1 = *(*int32)(unsafe.Pointer(v2))
			*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1
			(*TWindow)(unsafe.Pointer(pWin)).FcsrApp = v1
			(*TWindow)(unsafe.Pointer(pWin)).FregApp = (*TParse)(unsafe.Pointer(pParse)).FnMem + int32(1)
			**(**int32)(__ccgo_up(pParse + 48)) += int32(3)
			if pKeyInfo != 0 && int32(**(**int8)(__ccgo_up((*TFuncDef)(unsafe.Pointer((*TWindow)(unsafe.Pointer(pWin)).FpWFunc)).FzName + 1))) == int32('i') {
				**(**Tu8)(__ccgo_up((*TKeyInfo)(unsafe.Pointer(pKeyInfo)).FaSortFlags)) = uint8(KEYINFO_ORDER_DESC)
			}
			_sqlite3VdbeAddOp2(tls, v, int32(OP_OpenEphemeral), (*TWindow)(unsafe.Pointer(pWin)).FcsrApp, int32(2))
			_sqlite3VdbeAppendP4(tls, v, pKeyInfo, -int32(9))
			_sqlite3VdbeAddOp2(tls, v, int32(OP_Integer), 0, (*TWindow)(unsafe.Pointer(pWin)).FregApp+int32(1))
		} else {
			if (*TFuncDef)(unsafe.Pointer(p)).FzName == uintptr(unsafe.Pointer(&_nth_valueName)) || (*TFuncDef)(unsafe.Pointer(p)).FzName == uintptr(unsafe.Pointer(&_first_valueName)) {
				/* Allocate two registers at pWin->regApp. These will be used to
				 ** store the start and end index of the current frame.  */
				(*TWindow)(unsafe.Pointer(pWin)).FregApp = (*TParse)(unsafe.Pointer(pParse)).FnMem + int32(1)
				v2 = pParse + 44
				v1 = *(*int32)(unsafe.Pointer(v2))
				*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1
				(*TWindow)(unsafe.Pointer(pWin)).FcsrApp = v1
				**(**int32)(__ccgo_up(pParse + 48)) += int32(2)
				_sqlite3VdbeAddOp2(tls, v, int32(OP_OpenDup), (*TWindow)(unsafe.Pointer(pWin)).FcsrApp, (*TWindow)(unsafe.Pointer(pMWin)).FiEphCsr)
			} else {
				if (*TFuncDef)(unsafe.Pointer(p)).FzName == uintptr(unsafe.Pointer(&_leadName)) || (*TFuncDef)(unsafe.Pointer(p)).FzName == uintptr(unsafe.Pointer(&_lagName)) {
					v2 = pParse + 44
					v1 = *(*int32)(unsafe.Pointer(v2))
					*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1
					(*TWindow)(unsafe.Pointer(pWin)).FcsrApp = v1
					_sqlite3VdbeAddOp2(tls, v, int32(OP_OpenDup), (*TWindow)(unsafe.Pointer(pWin)).FcsrApp, (*TWindow)(unsafe.Pointer(pMWin)).FiEphCsr)
				}
			}
		}
		goto _9
	_9:
		;
		pWin = (*TWindow)(unsafe.Pointer(pWin)).FpNextWin
	}
}

// C documentation
//
//	/*
//	** If the SELECT statement passed as the second argument does not invoke
//	** any SQL window functions, this function is a no-op. Otherwise, it
//	** rewrites the SELECT statement so that window function xStep functions
//	** are invoked in the correct order as described under "SELECT REWRITING"
//	** at the top of this file.
//	*/
func _sqlite3WindowRewrite(tls *libc.TLS, pParse uintptr, p uintptr) (r int32) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var db, pArgs, pFilter, pGroupBy, pHaving, pMWin, pSort, pSrc, pSub, pTab, pTab2, pWhere, pWin, v, v2 uintptr
	var nSave, rc, v1 int32
	var selFlags Tu32
	var _ /* pSublist at bp+0 */ uintptr
	var _ /* w at bp+4 */ TWalker
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = db, nSave, pArgs, pFilter, pGroupBy, pHaving, pMWin, pSort, pSrc, pSub, pTab, pTab2, pWhere, pWin, rc, selFlags, v, v1, v2
	rc = SQLITE_OK
	if (*TSelect)(unsafe.Pointer(p)).FpWin != 0 && (*TSelect)(unsafe.Pointer(p)).FpPrior == uintptr(0) && (*TSelect)(unsafe.Pointer(p)).FselFlags&uint32(SF_WinRewrite) == uint32(0) && !(libc.Int32FromUint8((*TParse)(unsafe.Pointer(pParse)).FeParseMode) >= libc.Int32FromInt32(PARSE_MODE_RENAME)) {
		v = _sqlite3GetVdbe(tls, pParse)
		db = (*TParse)(unsafe.Pointer(pParse)).Fdb
		pSub = uintptr(0) /* The subquery */
		pSrc = (*TSelect)(unsafe.Pointer(p)).FpSrc
		pWhere = (*TSelect)(unsafe.Pointer(p)).FpWhere
		pGroupBy = (*TSelect)(unsafe.Pointer(p)).FpGroupBy
		pHaving = (*TSelect)(unsafe.Pointer(p)).FpHaving
		pSort = uintptr(0)
		**(**uintptr)(__ccgo_up(bp)) = uintptr(0) /* Expression list for sub-query */
		pMWin = (*TSelect)(unsafe.Pointer(p)).FpWin
		selFlags = (*TSelect)(unsafe.Pointer(p)).FselFlags
		pTab = _sqlite3DbMallocZero(tls, db, uint64(80))
		if pTab == uintptr(0) {
			return _sqlite3ErrorToParser(tls, db, int32(SQLITE_NOMEM))
		}
		_sqlite3AggInfoPersistWalkerInit(tls, bp+4, pParse)
		_sqlite3WalkSelect(tls, bp+4, p)
		if (*TSelect)(unsafe.Pointer(p)).FselFlags&uint32(SF_Aggregate) == uint32(0) {
			(**(**TWalker)(__ccgo_up(bp + 4))).FxExprCallback = __ccgo_fp(_disallowAggregatesInOrderByCb)
			(**(**TWalker)(__ccgo_up(bp + 4))).FxSelectCallback = uintptr(0)
			_sqlite3WalkExprList(tls, bp+4, (*TSelect)(unsafe.Pointer(p)).FpOrderBy)
		}
		(*TSelect)(unsafe.Pointer(p)).FpSrc = uintptr(0)
		(*TSelect)(unsafe.Pointer(p)).FpWhere = uintptr(0)
		(*TSelect)(unsafe.Pointer(p)).FpGroupBy = uintptr(0)
		(*TSelect)(unsafe.Pointer(p)).FpHaving = uintptr(0)
		**(**Tu32)(__ccgo_up(p + 4)) &= ^libc.Uint32FromInt32(SF_Aggregate)
		**(**Tu32)(__ccgo_up(p + 4)) |= uint32(SF_WinRewrite)
		/* Create the ORDER BY clause for the sub-select. This is the concatenation
		 ** of the window PARTITION and ORDER BY clauses. Then, if this makes it
		 ** redundant, remove the ORDER BY from the parent SELECT.  */
		pSort = _exprListAppendList(tls, pParse, uintptr(0), (*TWindow)(unsafe.Pointer(pMWin)).FpPartition, int32(1))
		pSort = _exprListAppendList(tls, pParse, pSort, (*TWindow)(unsafe.Pointer(pMWin)).FpOrderBy, int32(1))
		if pSort != 0 && (*TSelect)(unsafe.Pointer(p)).FpOrderBy != 0 && (*TExprList)(unsafe.Pointer((*TSelect)(unsafe.Pointer(p)).FpOrderBy)).FnExpr <= (*TExprList)(unsafe.Pointer(pSort)).FnExpr {
			nSave = (*TExprList)(unsafe.Pointer(pSort)).FnExpr
			(*TExprList)(unsafe.Pointer(pSort)).FnExpr = (*TExprList)(unsafe.Pointer((*TSelect)(unsafe.Pointer(p)).FpOrderBy)).FnExpr
			if _sqlite3ExprListCompare(tls, pSort, (*TSelect)(unsafe.Pointer(p)).FpOrderBy, -int32(1)) == 0 {
				_sqlite3ExprListDelete(tls, db, (*TSelect)(unsafe.Pointer(p)).FpOrderBy)
				(*TSelect)(unsafe.Pointer(p)).FpOrderBy = uintptr(0)
			}
			(*TExprList)(unsafe.Pointer(pSort)).FnExpr = nSave
		}
		/* Assign a cursor number for the ephemeral table used to buffer rows.
		 ** The OpenEphemeral instruction is coded later, after it is known how
		 ** many columns the table will have.  */
		v2 = pParse + 44
		v1 = *(*int32)(unsafe.Pointer(v2))
		*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1
		(*TWindow)(unsafe.Pointer(pMWin)).FiEphCsr = v1
		**(**int32)(__ccgo_up(pParse + 44)) += int32(3)
		_selectWindowRewriteEList(tls, pParse, pMWin, pSrc, (*TSelect)(unsafe.Pointer(p)).FpEList, pTab, bp)
		_selectWindowRewriteEList(tls, pParse, pMWin, pSrc, (*TSelect)(unsafe.Pointer(p)).FpOrderBy, pTab, bp)
		if **(**uintptr)(__ccgo_up(bp)) != 0 {
			v1 = (*TExprList)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FnExpr
		} else {
			v1 = 0
		}
		(*TWindow)(unsafe.Pointer(pMWin)).FnBufferCol = v1
		/* Append the PARTITION BY and ORDER BY expressions to the to the
		 ** sub-select expression list. They are required to figure out where
		 ** boundaries for partitions and sets of peer rows lie.  */
		**(**uintptr)(__ccgo_up(bp)) = _exprListAppendList(tls, pParse, **(**uintptr)(__ccgo_up(bp)), (*TWindow)(unsafe.Pointer(pMWin)).FpPartition, 0)
		**(**uintptr)(__ccgo_up(bp)) = _exprListAppendList(tls, pParse, **(**uintptr)(__ccgo_up(bp)), (*TWindow)(unsafe.Pointer(pMWin)).FpOrderBy, 0)
		/* Append the arguments passed to each window function to the
		 ** sub-select expression list. Also allocate two registers for each
		 ** window function - one for the accumulator, another for interim
		 ** results.  */
		pWin = pMWin
		for {
			if !(pWin != 0) {
				break
			}
			pArgs = *(*uintptr)(unsafe.Pointer((*TWindow)(unsafe.Pointer(pWin)).FpOwner + 20))
			if (*TFuncDef)(unsafe.Pointer((*TWindow)(unsafe.Pointer(pWin)).FpWFunc)).FfuncFlags&uint32(SQLITE_SUBTYPE) != 0 {
				_selectWindowRewriteEList(tls, pParse, pMWin, pSrc, pArgs, pTab, bp)
				if **(**uintptr)(__ccgo_up(bp)) != 0 {
					v1 = (*TExprList)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FnExpr
				} else {
					v1 = 0
				}
				(*TWindow)(unsafe.Pointer(pWin)).FiArgCol = v1
				(*TWindow)(unsafe.Pointer(pWin)).FbExprArgs = uint8(1)
			} else {
				if **(**uintptr)(__ccgo_up(bp)) != 0 {
					v1 = (*TExprList)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FnExpr
				} else {
					v1 = 0
				}
				(*TWindow)(unsafe.Pointer(pWin)).FiArgCol = v1
				**(**uintptr)(__ccgo_up(bp)) = _exprListAppendList(tls, pParse, **(**uintptr)(__ccgo_up(bp)), pArgs, 0)
			}
			if (*TWindow)(unsafe.Pointer(pWin)).FpFilter != 0 {
				pFilter = _sqlite3ExprDup(tls, db, (*TWindow)(unsafe.Pointer(pWin)).FpFilter, 0)
				**(**uintptr)(__ccgo_up(bp)) = _sqlite3ExprListAppend(tls, pParse, **(**uintptr)(__ccgo_up(bp)), pFilter)
			}
			v2 = pParse + 48
			*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1
			v1 = *(*int32)(unsafe.Pointer(v2))
			(*TWindow)(unsafe.Pointer(pWin)).FregAccum = v1
			v2 = pParse + 48
			*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1
			v1 = *(*int32)(unsafe.Pointer(v2))
			(*TWindow)(unsafe.Pointer(pWin)).FregResult = v1
			_sqlite3VdbeAddOp2(tls, v, int32(OP_Null), 0, (*TWindow)(unsafe.Pointer(pWin)).FregAccum)
			goto _4
		_4:
			;
			pWin = (*TWindow)(unsafe.Pointer(pWin)).FpNextWin
		}
		/* If there is no ORDER BY or PARTITION BY clause, and the window
		 ** function accepts zero arguments, and there are no other columns
		 ** selected (e.g. "SELECT row_number() OVER () FROM t1"), it is possible
		 ** that pSublist is still NULL here. Add a constant expression here to
		 ** keep everything legal in this case.
		 */
		if **(**uintptr)(__ccgo_up(bp)) == uintptr(0) {
			**(**uintptr)(__ccgo_up(bp)) = _sqlite3ExprListAppend(tls, pParse, uintptr(0), _sqlite3ExprInt32(tls, db, 0))
		}
		pSub = _sqlite3SelectNew(tls, pParse, **(**uintptr)(__ccgo_up(bp)), pSrc, pWhere, pGroupBy, pHaving, pSort, uint32(0), uintptr(0))
		(*TSelect)(unsafe.Pointer(p)).FpSrc = _sqlite3SrcListAppend(tls, pParse, uintptr(0), uintptr(0), uintptr(0))
		/* Due to db->mallocFailed test inside
		 ** of sqlite3DbMallocRawNN() called from
		 ** sqlite3SrcListAppend() */
		if (*TSelect)(unsafe.Pointer(p)).FpSrc == uintptr(0) {
			_sqlite3SelectDelete(tls, db, pSub)
		} else {
			if _sqlite3SrcItemAttachSubquery(tls, pParse, (*TSelect)(unsafe.Pointer(p)).FpSrc+8, pSub, 0) != 0 {
				libc.SetBitFieldPtr32Uint32((*TSelect)(unsafe.Pointer(p)).FpSrc+8+12+4, libc.Uint32FromInt32(1), 4, 0x10)
				_sqlite3SrcListAssignCursors(tls, pParse, (*TSelect)(unsafe.Pointer(p)).FpSrc)
				**(**Tu32)(__ccgo_up(pSub + 4)) |= libc.Uint32FromInt32(libc.Int32FromInt32(SF_Expanded) | libc.Int32FromInt32(SF_OrderByReqd))
				pTab2 = _sqlite3ResultSetOfSelect(tls, pParse, pSub, int8(SQLITE_AFF_NONE))
				**(**Tu32)(__ccgo_up(pSub + 4)) |= selFlags & uint32(SF_Aggregate)
				if pTab2 == uintptr(0) {
					/* Might actually be some other kind of error, but in that case
					 ** pParse->nErr will be set, so if SQLITE_NOMEM is set, we will get
					 ** the correct error message regardless. */
					rc = int32(SQLITE_NOMEM)
				} else {
					libc.Xmemcpy(tls, pTab, pTab2, uint32(80))
					**(**Tu32)(__ccgo_up(pTab + 28)) |= uint32(TF_Ephemeral)
					(*(*TSrcItem)(unsafe.Pointer((*TSelect)(unsafe.Pointer(p)).FpSrc + 8))).FpSTab = pTab
					pTab = pTab2
					libc.Xmemset(tls, bp+4, 0, uint32(28))
					(**(**TWalker)(__ccgo_up(bp + 4))).FxExprCallback = __ccgo_fp(_sqlite3WindowExtraAggFuncDepth)
					(**(**TWalker)(__ccgo_up(bp + 4))).FxSelectCallback = __ccgo_fp(_sqlite3WalkerDepthIncrease)
					(**(**TWalker)(__ccgo_up(bp + 4))).FxSelectCallback2 = __ccgo_fp(_sqlite3WalkerDepthDecrease)
					_sqlite3WalkSelect(tls, bp+4, pSub)
				}
			}
		}
		if (*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0 {
			rc = int32(SQLITE_NOMEM)
		}
		/* Defer deleting the temporary table pTab because if an error occurred,
		 ** there could still be references to that table embedded in the
		 ** result-set or ORDER BY clause of the SELECT statement p.  */
		_sqlite3ParserAddCleanup(tls, pParse, __ccgo_fp(_sqlite3DbFree), pTab)
	}
	return rc
}

// C documentation
//
//	/*
//	** Reclaim all memory of a StatAccum structure.
//	*/
func _statAccumDestructor(tls *libc.TLS, pOld uintptr) {
	var i int32
	var p uintptr
	_, _ = i, p
	p = pOld
	if (*TStatAccum)(unsafe.Pointer(p)).FmxSample != 0 {
		i = 0
		for {
			if !(i < (*TStatAccum)(unsafe.Pointer(p)).FnCol) {
				break
			}
			_sampleClear(tls, (*TStatAccum)(unsafe.Pointer(p)).Fdb, (*TStatAccum)(unsafe.Pointer(p)).FaBest+uintptr(i)*36)
			goto _1
		_1:
			;
			i = i + 1
		}
		i = 0
		for {
			if !(i < (*TStatAccum)(unsafe.Pointer(p)).FmxSample) {
				break
			}
			_sampleClear(tls, (*TStatAccum)(unsafe.Pointer(p)).Fdb, (*TStatAccum)(unsafe.Pointer(p)).Fa+uintptr(i)*36)
			goto _2
		_2:
			;
			i = i + 1
		}
		_sampleClear(tls, (*TStatAccum)(unsafe.Pointer(p)).Fdb, p+36)
	}
	_sqlite3DbFree(tls, (*TStatAccum)(unsafe.Pointer(p)).Fdb, p)
}

// C documentation
//
//	/*
//	** Compute the best query strategy and return the result in idxNum.
//	**
//	**   idxNum-Bit        Meaning
//	**   ----------        ----------------------------------------------
//	**      0x01           There is a schema=? term in the WHERE clause
//	**      0x02           There is a name=? term in the WHERE clause
//	**      0x04           There is an aggregate=? term in the WHERE clause
//	**      0x08           Output should be ordered by name and path
//	*/
func _statBestIndex(tls *libc.TLS, tab uintptr, pIdxInfo uintptr) (r int32) {
	var i, iAgg, iName, iSchema, v2 int32
	_, _, _, _, _ = i, iAgg, iName, iSchema, v2
	iSchema = -int32(1)
	iName = -int32(1)
	iAgg = -int32(1)
	_ = tab
	/* Look for a valid schema=? constraint.  If found, change the idxNum to
	 ** 1 and request the value of that constraint be sent to xFilter.  And
	 ** lower the cost estimate to encourage the constrained version to be
	 ** used.
	 */
	i = 0
	for {
		if !(i < (*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FnConstraint) {
			break
		}
		if libc.Int32FromUint8((**(**Tsqlite3_index_constraint)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraint + uintptr(i)*12))).Fop) != int32(SQLITE_INDEX_CONSTRAINT_EQ) {
			goto _1
		}
		if libc.Int32FromUint8((**(**Tsqlite3_index_constraint)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraint + uintptr(i)*12))).Fusable) == 0 {
			/* Force DBSTAT table should always be the right-most table in a join */
			return int32(SQLITE_CONSTRAINT)
		}
		switch (**(**Tsqlite3_index_constraint)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraint + uintptr(i)*12))).FiColumn {
		case 0: /* name */
			iName = i
		case int32(10): /* schema */
			iSchema = i
		case int32(11): /* aggregate */
			iAgg = i
			break
		}
		goto _1
	_1:
		;
		i = i + 1
	}
	i = 0
	if iSchema >= 0 {
		i = i + 1
		v2 = i
		(**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraintUsage + uintptr(iSchema)*8))).FargvIndex = v2
		(**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraintUsage + uintptr(iSchema)*8))).Fomit = uint8(1)
		**(**int32)(__ccgo_up(pIdxInfo + 20)) |= int32(0x01)
	}
	if iName >= 0 {
		i = i + 1
		v2 = i
		(**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraintUsage + uintptr(iName)*8))).FargvIndex = v2
		**(**int32)(__ccgo_up(pIdxInfo + 20)) |= int32(0x02)
	}
	if iAgg >= 0 {
		i = i + 1
		v2 = i
		(**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraintUsage + uintptr(iAgg)*8))).FargvIndex = v2
		**(**int32)(__ccgo_up(pIdxInfo + 20)) |= int32(0x04)
	}
	(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FestimatedCost = float64(1)
	/* Records are always returned in ascending order of (name, path).
	 ** If this will satisfy the client, set the orderByConsumed flag so that
	 ** SQLite does not do an external sort.
	 */
	if (*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FnOrderBy == int32(1) && (**(**Tsqlite3_index_orderby)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaOrderBy))).FiColumn == 0 && libc.Int32FromUint8((**(**Tsqlite3_index_orderby)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaOrderBy))).Fdesc) == 0 || (*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FnOrderBy == int32(2) && (**(**Tsqlite3_index_orderby)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaOrderBy))).FiColumn == 0 && libc.Int32FromUint8((**(**Tsqlite3_index_orderby)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaOrderBy))).Fdesc) == 0 && (**(**Tsqlite3_index_orderby)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaOrderBy + 1*8))).FiColumn == int32(1) && libc.Int32FromUint8((**(**Tsqlite3_index_orderby)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaOrderBy + 1*8))).Fdesc) == 0 {
		(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).ForderByConsumed = int32(1)
		**(**int32)(__ccgo_up(pIdxInfo + 20)) |= int32(0x08)
	}
	**(**int32)(__ccgo_up(pIdxInfo + 52)) |= int32(SQLITE_INDEX_SCAN_HEX)
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** Implementation of the stat_init(N,K,C,L) SQL function. The four parameters
//	** are:
//	**     N:    The number of columns in the index including the rowid/pk (note 1)
//	**     K:    The number of columns in the index excluding the rowid/pk.
//	**     C:    Estimated number of rows in the index
//	**     L:    A limit on the number of rows to scan, or 0 for no-limit
//	**
//	** Note 1:  In the special case of the covering index that implements a
//	** WITHOUT ROWID table, N is the number of PRIMARY KEY columns, not the
//	** total number of columns in the table.
//	**
//	** For indexes on ordinary rowid tables, N==K+1.  But for indexes on
//	** WITHOUT ROWID tables, N=K+P where P is the number of columns in the
//	** PRIMARY KEY of the table.  The covering index that implements the
//	** original WITHOUT ROWID table as N==K as a special case.
//	**
//	** This routine allocates the StatAccum object in heap memory. The return
//	** value is a pointer to the StatAccum object.  The datatype of the
//	** return value is BLOB, but it is really just a pointer to the StatAccum
//	** object.
//	*/
func _statInit(tls *libc.TLS, context uintptr, argc int32, argv uintptr) {
	var db, p, pSpace uintptr
	var i, mxSample, nCol, nColUp, nKeyCol, v1 int32
	var n Ti64
	_, _, _, _, _, _, _, _, _, _ = db, i, mxSample, n, nCol, nColUp, nKeyCol, p, pSpace, v1 /* Bytes of space to allocate */
	db = Xsqlite3_context_db_handle(tls, context)
	if (*Tsqlite3)(unsafe.Pointer(db)).FdbOptFlags&libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_Stat4)) == uint32(0) {
		v1 = int32(SQLITE_STAT4_SAMPLES)
	} else {
		v1 = 0
	} /* Database connection */
	/* Maximum number of samples.  0 if STAT4 data is not collected */
	mxSample = v1
	/* Decode the three function arguments */
	_ = argc
	nCol = Xsqlite3_value_int(tls, **(**uintptr)(__ccgo_up(argv)))
	nColUp = nCol
	nKeyCol = Xsqlite3_value_int(tls, **(**uintptr)(__ccgo_up(argv + 1*4)))
	/* Allocate the space required for the StatAccum object */
	n = libc.Int64FromUint32(uint32(112) + uint32(8)*libc.Uint32FromInt32(nColUp)) /* StatAccum.anDLt */
	n = n + libc.Int64FromUint32(uint32(8)*libc.Uint32FromInt32(nColUp))           /* StatAccum.anEq */
	if mxSample != 0 {
		n = n + libc.Int64FromUint32(uint32(8)*libc.Uint32FromInt32(nColUp)+uint32(36)*libc.Uint32FromInt32(nCol+mxSample)+libc.Uint32FromInt64(8)*libc.Uint32FromInt32(3)*libc.Uint32FromInt32(nColUp)*libc.Uint32FromInt32(nCol+mxSample))
	}
	p = _sqlite3DbMallocZero(tls, db, libc.Uint64FromInt64(n))
	if p == uintptr(0) {
		Xsqlite3_result_error_nomem(tls, context)
		return
	}
	(*TStatAccum)(unsafe.Pointer(p)).Fdb = db
	(*TStatAccum)(unsafe.Pointer(p)).FnEst = libc.Uint64FromInt64(Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(argv + 2*4))))
	(*TStatAccum)(unsafe.Pointer(p)).FnRow = uint64(0)
	(*TStatAccum)(unsafe.Pointer(p)).FnLimit = Xsqlite3_value_int(tls, **(**uintptr)(__ccgo_up(argv + 3*4)))
	(*TStatAccum)(unsafe.Pointer(p)).FnCol = nCol
	(*TStatAccum)(unsafe.Pointer(p)).FnKeyCol = nKeyCol
	(*TStatAccum)(unsafe.Pointer(p)).FnSkipAhead = uint8(0)
	(*TStatAccum)(unsafe.Pointer(p)).Fcurrent.FanDLt = p + 1*112
	(*TStatAccum)(unsafe.Pointer(p)).Fcurrent.FanEq = (*TStatAccum)(unsafe.Pointer(p)).Fcurrent.FanDLt + uintptr(nColUp)*8
	if (*TStatAccum)(unsafe.Pointer(p)).FnLimit == 0 {
		v1 = mxSample
	} else {
		v1 = 0
	}
	(*TStatAccum)(unsafe.Pointer(p)).FmxSample = v1
	if mxSample != 0 { /* Used to iterate through p->aSample[] */
		(*TStatAccum)(unsafe.Pointer(p)).FiGet = -int32(1)
		(*TStatAccum)(unsafe.Pointer(p)).FnPSample = (*TStatAccum)(unsafe.Pointer(p)).FnEst/libc.Uint64FromInt32(mxSample/libc.Int32FromInt32(3)+libc.Int32FromInt32(1)) + libc.Uint64FromInt32(1)
		(*TStatAccum)(unsafe.Pointer(p)).Fcurrent.FanLt = (*TStatAccum)(unsafe.Pointer(p)).Fcurrent.FanEq + uintptr(nColUp)*8
		(*TStatAccum)(unsafe.Pointer(p)).FiPrn = uint32(0x689e962d)*libc.Uint32FromInt32(nCol) ^ uint32(0xd0944565)*libc.Uint32FromInt32(Xsqlite3_value_int(tls, **(**uintptr)(__ccgo_up(argv + 2*4))))
		/* Set up the StatAccum.a[] and aBest[] arrays */
		(*TStatAccum)(unsafe.Pointer(p)).Fa = (*TStatAccum)(unsafe.Pointer(p)).Fcurrent.FanLt + uintptr(nColUp)*8
		(*TStatAccum)(unsafe.Pointer(p)).FaBest = (*TStatAccum)(unsafe.Pointer(p)).Fa + uintptr(mxSample)*36
		pSpace = (*TStatAccum)(unsafe.Pointer(p)).Fa + uintptr(mxSample+nCol)*36
		i = 0
		for {
			if !(i < mxSample+nCol) {
				break
			}
			(**(**TStatSample)(__ccgo_up((*TStatAccum)(unsafe.Pointer(p)).Fa + uintptr(i)*36))).FanEq = pSpace
			pSpace = pSpace + uintptr(libc.Uint32FromInt64(8)*libc.Uint32FromInt32(nColUp))
			(**(**TStatSample)(__ccgo_up((*TStatAccum)(unsafe.Pointer(p)).Fa + uintptr(i)*36))).FanLt = pSpace
			pSpace = pSpace + uintptr(libc.Uint32FromInt64(8)*libc.Uint32FromInt32(nColUp))
			(**(**TStatSample)(__ccgo_up((*TStatAccum)(unsafe.Pointer(p)).Fa + uintptr(i)*36))).FanDLt = pSpace
			pSpace = pSpace + uintptr(libc.Uint32FromInt64(8)*libc.Uint32FromInt32(nColUp))
			goto _3
		_3:
			;
			i = i + 1
		}
		i = 0
		for {
			if !(i < nCol) {
				break
			}
			(**(**TStatSample)(__ccgo_up((*TStatAccum)(unsafe.Pointer(p)).FaBest + uintptr(i)*36))).FiCol = i
			goto _4
		_4:
			;
			i = i + 1
		}
	}
	/* Return a pointer to the allocated object to the caller.  Note that
	 ** only the pointer (the 2nd parameter) matters.  The size of the object
	 ** (given by the 3rd parameter) is never used and can be any positive
	 ** value. */
	Xsqlite3_result_blob(tls, context, p, int32(112), __ccgo_fp(_statAccumDestructor))
}

// C documentation
//
//	/*
//	** Implementation of the stat_push SQL function:  stat_push(P,C,R)
//	** Arguments:
//	**
//	**    P     Pointer to the StatAccum object created by stat_init()
//	**    C     Index of left-most column to differ from previous row
//	**    R     Rowid for the current row.  Might be a key record for
//	**          WITHOUT ROWID tables.
//	**
//	** The purpose of this routine is to collect statistical data and/or
//	** samples from the index being analyzed into the StatAccum object.
//	** The stat_get() SQL function will be used afterwards to
//	** retrieve the information gathered.
//	**
//	** This SQL function usually returns NULL, but might return an integer
//	** if it wants the byte-code to do special processing.
//	**
//	** The R parameter is only used for STAT4
//	*/
func _statPush(tls *libc.TLS, context uintptr, argc int32, argv uintptr) {
	var i, iChng int32
	var nLt TtRowcnt
	var p uintptr
	var v4 Tu32
	_, _, _, _, _ = i, iChng, nLt, p, v4
	/* The three function arguments */
	p = Xsqlite3_value_blob(tls, **(**uintptr)(__ccgo_up(argv)))
	iChng = Xsqlite3_value_int(tls, **(**uintptr)(__ccgo_up(argv + 1*4)))
	_ = argc
	_ = context
	if (*TStatAccum)(unsafe.Pointer(p)).FnRow == uint64(0) {
		/* This is the first call to this function. Do initialization. */
		i = 0
		for {
			if !(i < (*TStatAccum)(unsafe.Pointer(p)).FnCol) {
				break
			}
			**(**TtRowcnt)(__ccgo_up((*TStatAccum)(unsafe.Pointer(p)).Fcurrent.FanEq + uintptr(i)*8)) = uint64(1)
			goto _1
		_1:
			;
			i = i + 1
		}
	} else {
		/* Second and subsequent calls get processed here */
		if (*TStatAccum)(unsafe.Pointer(p)).FmxSample != 0 {
			_samplePushPrevious(tls, p, iChng)
		}
		/* Update anDLt[], anLt[] and anEq[] to reflect the values that apply
		 ** to the current row of the index. */
		i = 0
		for {
			if !(i < iChng) {
				break
			}
			**(**TtRowcnt)(__ccgo_up((*TStatAccum)(unsafe.Pointer(p)).Fcurrent.FanEq + uintptr(i)*8)) = **(**TtRowcnt)(__ccgo_up((*TStatAccum)(unsafe.Pointer(p)).Fcurrent.FanEq + uintptr(i)*8)) + 1
			goto _2
		_2:
			;
			i = i + 1
		}
		i = iChng
		for {
			if !(i < (*TStatAccum)(unsafe.Pointer(p)).FnCol) {
				break
			}
			**(**TtRowcnt)(__ccgo_up((*TStatAccum)(unsafe.Pointer(p)).Fcurrent.FanDLt + uintptr(i)*8)) = **(**TtRowcnt)(__ccgo_up((*TStatAccum)(unsafe.Pointer(p)).Fcurrent.FanDLt + uintptr(i)*8)) + 1
			if (*TStatAccum)(unsafe.Pointer(p)).FmxSample != 0 {
				**(**TtRowcnt)(__ccgo_up((*TStatAccum)(unsafe.Pointer(p)).Fcurrent.FanLt + uintptr(i)*8)) += **(**TtRowcnt)(__ccgo_up((*TStatAccum)(unsafe.Pointer(p)).Fcurrent.FanEq + uintptr(i)*8))
			}
			**(**TtRowcnt)(__ccgo_up((*TStatAccum)(unsafe.Pointer(p)).Fcurrent.FanEq + uintptr(i)*8)) = uint64(1)
			goto _3
		_3:
			;
			i = i + 1
		}
	}
	(*TStatAccum)(unsafe.Pointer(p)).FnRow = (*TStatAccum)(unsafe.Pointer(p)).FnRow + 1
	if (*TStatAccum)(unsafe.Pointer(p)).FmxSample != 0 {
		if Xsqlite3_value_type(tls, **(**uintptr)(__ccgo_up(argv + 2*4))) == int32(SQLITE_INTEGER) {
			_sampleSetRowidInt64(tls, (*TStatAccum)(unsafe.Pointer(p)).Fdb, p+36, Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(argv + 2*4))))
		} else {
			_sampleSetRowid(tls, (*TStatAccum)(unsafe.Pointer(p)).Fdb, p+36, Xsqlite3_value_bytes(tls, **(**uintptr)(__ccgo_up(argv + 2*4))), Xsqlite3_value_blob(tls, **(**uintptr)(__ccgo_up(argv + 2*4))))
		}
		v4 = (*TStatAccum)(unsafe.Pointer(p)).FiPrn*libc.Uint32FromInt32(1103515245) + libc.Uint32FromInt32(12345)
		(*TStatAccum)(unsafe.Pointer(p)).FiPrn = v4
		(*TStatAccum)(unsafe.Pointer(p)).Fcurrent.FiHash = v4
		nLt = **(**TtRowcnt)(__ccgo_up((*TStatAccum)(unsafe.Pointer(p)).Fcurrent.FanLt + uintptr((*TStatAccum)(unsafe.Pointer(p)).FnCol-int32(1))*8))
		/* Check if this is to be a periodic sample. If so, add it. */
		if nLt/(*TStatAccum)(unsafe.Pointer(p)).FnPSample != (nLt+uint64(1))/(*TStatAccum)(unsafe.Pointer(p)).FnPSample {
			(*TStatAccum)(unsafe.Pointer(p)).Fcurrent.FisPSample = uint8(1)
			(*TStatAccum)(unsafe.Pointer(p)).Fcurrent.FiCol = 0
			_sampleInsert(tls, p, p+36, (*TStatAccum)(unsafe.Pointer(p)).FnCol-int32(1))
			(*TStatAccum)(unsafe.Pointer(p)).Fcurrent.FisPSample = uint8(0)
		}
		/* Update the aBest[] array. */
		i = 0
		for {
			if !(i < (*TStatAccum)(unsafe.Pointer(p)).FnCol-int32(1)) {
				break
			}
			(*TStatAccum)(unsafe.Pointer(p)).Fcurrent.FiCol = i
			if i >= iChng || _sampleIsBetterPost(tls, p, p+36, (*TStatAccum)(unsafe.Pointer(p)).FaBest+uintptr(i)*36) != 0 {
				_sampleCopy(tls, p, (*TStatAccum)(unsafe.Pointer(p)).FaBest+uintptr(i)*36, p+36)
			}
			goto _5
		_5:
			;
			i = i + 1
		}
	} else {
		if (*TStatAccum)(unsafe.Pointer(p)).FnLimit != 0 && (*TStatAccum)(unsafe.Pointer(p)).FnRow > libc.Uint64FromInt32((*TStatAccum)(unsafe.Pointer(p)).FnLimit)*libc.Uint64FromInt32(libc.Int32FromUint8((*TStatAccum)(unsafe.Pointer(p)).FnSkipAhead)+libc.Int32FromInt32(1)) {
			(*TStatAccum)(unsafe.Pointer(p)).FnSkipAhead = (*TStatAccum)(unsafe.Pointer(p)).FnSkipAhead + 1
			Xsqlite3_result_int(tls, context, libc.BoolInt32(**(**TtRowcnt)(__ccgo_up((*TStatAccum)(unsafe.Pointer(p)).Fcurrent.FanDLt)) > uint64(0)))
		}
	}
}

// C documentation
//
//	/*
//	** Implementation of the substr() function.
//	**
//	** substr(x,p1,p2)  returns p2 characters of x[] beginning with p1.
//	** p1 is 1-indexed.  So substr(x,1,1) returns the first character
//	** of x.  If x is text, then we actually count UTF-8 characters.
//	** If x is a blob, then we count bytes.
//	**
//	** If p1 is negative, then we begin abs(p1) from the end of x[].
//	**
//	** If p2 is negative, return the p2 characters preceding p1.
//	*/
func _substrFunc(tls *libc.TLS, context uintptr, argc int32, argv uintptr) {
	var len1, p0type int32
	var p1, p2, v6 Ti64
	var z, z2, v2 uintptr
	_, _, _, _, _, _, _, _ = len1, p0type, p1, p2, z, z2, v2, v6
	p0type = Xsqlite3_value_type(tls, **(**uintptr)(__ccgo_up(argv)))
	p1 = Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(argv + 1*4)))
	if p0type == int32(SQLITE_BLOB) {
		len1 = Xsqlite3_value_bytes(tls, **(**uintptr)(__ccgo_up(argv)))
		z = Xsqlite3_value_blob(tls, **(**uintptr)(__ccgo_up(argv)))
		if z == uintptr(0) {
			return
		}
	} else {
		z = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv)))
		if z == uintptr(0) {
			return
		}
		len1 = 0
		if p1 < 0 {
			z2 = z
			for {
				if !(**(**uint8)(__ccgo_up(z2)) != 0) {
					break
				}
				v2 = z2
				z2 = z2 + 1
				if libc.Int32FromUint8(**(**uint8)(__ccgo_up(v2))) >= int32(0xc0) {
					for libc.Int32FromUint8(**(**uint8)(__ccgo_up(z2)))&int32(0xc0) == int32(0x80) {
						z2 = z2 + 1
					}
				}
				goto _1
			_1:
				;
				len1 = len1 + 1
			}
		}
	}
	if argc == int32(3) {
		p2 = Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(argv + 2*4)))
		if p2 == 0 && Xsqlite3_value_type(tls, **(**uintptr)(__ccgo_up(argv + 2*4))) == int32(SQLITE_NULL) {
			return
		}
	} else {
		p2 = int64(**(**int32)(__ccgo_up(Xsqlite3_context_db_handle(tls, context) + 116)))
	}
	if p1 == 0 {
		if Xsqlite3_value_type(tls, **(**uintptr)(__ccgo_up(argv + 1*4))) == int32(SQLITE_NULL) {
			return
		}
	}
	if p1 < 0 {
		p1 = p1 + int64(len1)
		if p1 < 0 {
			if p2 < 0 {
				p2 = 0
			} else {
				p2 = p2 + p1
			}
			p1 = 0
		}
	} else {
		if p1 > 0 {
			p1 = p1 - 1
		} else {
			if p2 > 0 {
				p2 = p2 - 1
			}
		}
	}
	if p2 < 0 {
		if p2 < -p1 {
			p2 = p1
		} else {
			p2 = -p2
		}
		p1 = p1 - p2
	}
	if p0type != int32(SQLITE_BLOB) {
		for **(**uint8)(__ccgo_up(z)) != 0 && p1 != 0 {
			v2 = z
			z = z + 1
			if libc.Int32FromUint8(**(**uint8)(__ccgo_up(v2))) >= int32(0xc0) {
				for libc.Int32FromUint8(**(**uint8)(__ccgo_up(z)))&int32(0xc0) == int32(0x80) {
					z = z + 1
				}
			}
			p1 = p1 - 1
		}
		z2 = z
		for {
			if !(**(**uint8)(__ccgo_up(z2)) != 0 && p2 != 0) {
				break
			}
			v2 = z2
			z2 = z2 + 1
			if libc.Int32FromUint8(**(**uint8)(__ccgo_up(v2))) >= int32(0xc0) {
				for libc.Int32FromUint8(**(**uint8)(__ccgo_up(z2)))&int32(0xc0) == int32(0x80) {
					z2 = z2 + 1
				}
			}
			goto _4
		_4:
			;
			p2 = p2 - 1
		}
		Xsqlite3_result_text64(tls, context, z, libc.Uint64FromInt32(int32(z2)-int32(z)), uintptr(-libc.Int32FromInt32(1)), uint8(SQLITE_UTF8))
	} else {
		if p1 >= int64(len1) {
			v6 = libc.Int64FromInt32(0)
			p2 = v6
			p1 = v6
		} else {
			if p2 > int64(len1)-p1 {
				p2 = int64(len1) - p1
			}
		}
		Xsqlite3_result_blob64(tls, context, z+uintptr(p1), libc.Uint64FromInt64(p2), uintptr(-libc.Int32FromInt32(1)))
	}
}

func _sumInverse(tls *libc.TLS, context uintptr, argc int32, argv uintptr) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var iVal Ti64
	var p uintptr
	var type1 int32
	var _ /* x at bp+0 */ Ti64
	_, _, _ = iVal, p, type1
	_ = argc
	p = Xsqlite3_aggregate_context(tls, context, int32(36))
	type1 = Xsqlite3_value_numeric_type(tls, **(**uintptr)(__ccgo_up(argv)))
	/* p is always non-NULL because sumStep() will have been called first
	 ** to initialize it */
	if p != 0 && type1 != int32(SQLITE_NULL) {
		(*TSumCtx)(unsafe.Pointer(p)).Fcnt = (*TSumCtx)(unsafe.Pointer(p)).Fcnt - 1
		if !((*TSumCtx)(unsafe.Pointer(p)).Fapprox != 0) {
			**(**Ti64)(__ccgo_up(bp)) = (*TSumCtx)(unsafe.Pointer(p)).FiSum
			if _sqlite3SubInt64(tls, bp, Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(argv)))) == 0 {
				(*TSumCtx)(unsafe.Pointer(p)).FiSum = **(**Ti64)(__ccgo_up(bp))
				return
			}
			(*TSumCtx)(unsafe.Pointer(p)).Fovrfl = uint8(1)
			(*TSumCtx)(unsafe.Pointer(p)).Fapprox = uint8(1)
			_kahanBabuskaNeumaierInit(tls, p, (*TSumCtx)(unsafe.Pointer(p)).FiSum)
		}
		if type1 == int32(SQLITE_INTEGER) {
			iVal = Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(argv)))
			if iVal != int64(-libc.Int32FromInt32(1))-(libc.Int64FromUint32(0xffffffff)|libc.Int64FromInt32(0x7fffffff)<<libc.Int32FromInt32(32)) {
				_kahanBabuskaNeumaierStepInt64(tls, p, -iVal)
			} else {
				_kahanBabuskaNeumaierStepInt64(tls, p, libc.Int64FromUint32(0xffffffff)|libc.Int64FromInt32(0x7fffffff)<<libc.Int32FromInt32(32))
				_kahanBabuskaNeumaierStepInt64(tls, p, int64(1))
			}
		} else {
			_kahanBabuskaNeumaierStep(tls, p, -Xsqlite3_value_double(tls, **(**uintptr)(__ccgo_up(argv))))
		}
	}
}

// C documentation
//
//	/*
//	** Routines used to compute the sum, average, and total.
//	**
//	** The SUM() function follows the (broken) SQL standard which means
//	** that it returns NULL if it sums over no inputs.  TOTAL returns
//	** 0.0 in that case.  In addition, TOTAL always returns a float where
//	** SUM might return an integer if it never encounters a floating point
//	** value.  TOTAL never fails, but SUM might throw an exception if
//	** it overflows an integer.
//	*/
func _sumStep(tls *libc.TLS, context uintptr, argc int32, argv uintptr) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var p uintptr
	var type1 int32
	var _ /* x at bp+0 */ Ti64
	_, _ = p, type1
	_ = argc
	p = Xsqlite3_aggregate_context(tls, context, int32(36))
	type1 = Xsqlite3_value_numeric_type(tls, **(**uintptr)(__ccgo_up(argv)))
	if p != 0 && type1 != int32(SQLITE_NULL) {
		(*TSumCtx)(unsafe.Pointer(p)).Fcnt = (*TSumCtx)(unsafe.Pointer(p)).Fcnt + 1
		if libc.Int32FromUint8((*TSumCtx)(unsafe.Pointer(p)).Fapprox) == 0 {
			if type1 != int32(SQLITE_INTEGER) {
				_kahanBabuskaNeumaierInit(tls, p, (*TSumCtx)(unsafe.Pointer(p)).FiSum)
				(*TSumCtx)(unsafe.Pointer(p)).Fapprox = uint8(1)
				_kahanBabuskaNeumaierStep(tls, p, Xsqlite3_value_double(tls, **(**uintptr)(__ccgo_up(argv))))
			} else {
				**(**Ti64)(__ccgo_up(bp)) = (*TSumCtx)(unsafe.Pointer(p)).FiSum
				if _sqlite3AddInt64(tls, bp, Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(argv)))) == 0 {
					(*TSumCtx)(unsafe.Pointer(p)).FiSum = **(**Ti64)(__ccgo_up(bp))
				} else {
					(*TSumCtx)(unsafe.Pointer(p)).Fovrfl = uint8(1)
					_kahanBabuskaNeumaierInit(tls, p, (*TSumCtx)(unsafe.Pointer(p)).FiSum)
					(*TSumCtx)(unsafe.Pointer(p)).Fapprox = uint8(1)
					_kahanBabuskaNeumaierStepInt64(tls, p, Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(argv))))
				}
			}
		} else {
			if type1 == int32(SQLITE_INTEGER) {
				_kahanBabuskaNeumaierStepInt64(tls, p, Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(argv))))
			} else {
				(*TSumCtx)(unsafe.Pointer(p)).Fovrfl = uint8(0)
				_kahanBabuskaNeumaierStep(tls, p, Xsqlite3_value_double(tls, **(**uintptr)(__ccgo_up(argv))))
			}
		}
	}
}

// C documentation
//
//	/*
//	** Return TRUE if the WHERE clause term pTerm is of a form where it
//	** could be used with an index to access pSrc, assuming an appropriate
//	** index existed.
//	*/
func _termCanDriveIndex(tls *libc.TLS, pTerm uintptr, pSrc uintptr, notReady TBitmask) (r int32) {
	var aff int8
	var leftCol int32
	_, _ = aff, leftCol
	if (*TWhereTerm)(unsafe.Pointer(pTerm)).FleftCursor != (*TSrcItem)(unsafe.Pointer(pSrc)).FiCursor {
		return 0
	}
	if libc.Int32FromUint16((*TWhereTerm)(unsafe.Pointer(pTerm)).FeOperator)&(libc.Int32FromInt32(WO_EQ)|libc.Int32FromInt32(WO_IS)) == 0 {
		return 0
	}
	if libc.Int32FromUint8((*TSrcItem)(unsafe.Pointer(pSrc)).Ffg.Fjointype)&(libc.Int32FromInt32(JT_LEFT)|libc.Int32FromInt32(JT_LTORJ)|libc.Int32FromInt32(JT_RIGHT)) != 0 && !(_constraintCompatibleWithOuterJoin(tls, pTerm, pSrc) != 0) {
		return 0 /* See https://sqlite.org/forum/forumpost/51e6959f61 */
	}
	if (*TWhereTerm)(unsafe.Pointer(pTerm)).FprereqRight&notReady != uint64(0) {
		return 0
	}
	leftCol = (*(*struct {
		FleftColumn int32
		FiField     int32
	})(unsafe.Pointer(pTerm + 24))).FleftColumn
	if leftCol < 0 {
		return 0
	}
	aff = (**(**TColumn)(__ccgo_up((*TTable)(unsafe.Pointer((*TSrcItem)(unsafe.Pointer(pSrc)).FpSTab)).FaCol + uintptr(leftCol)*12))).Faffinity
	if !(_sqlite3IndexAffinityOk(tls, (*TWhereTerm)(unsafe.Pointer(pTerm)).FpExpr, aff) != 0) {
		return 0
	}
	return _columnIsGoodIndexCandidate(tls, (*TSrcItem)(unsafe.Pointer(pSrc)).FpSTab, leftCol)
}

// C documentation
//
//	/* Construct a new Expr object from a single token */
func _tokenExpr(tls *libc.TLS, pParse uintptr, op int32, _t TToken) (r uintptr) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	*(*TToken)(unsafe.Pointer(bp)) = _t
	var p, v1 uintptr
	_, _ = p, v1
	p = _sqlite3DbMallocRawNN(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, uint64(uint32(52)+(**(**TToken)(__ccgo_up(bp))).Fn+uint32(1)))
	if p != 0 {
		/* memset(p, 0, sizeof(Expr)); */
		(*TExpr)(unsafe.Pointer(p)).Fop = libc.Uint8FromInt32(op)
		(*TExpr)(unsafe.Pointer(p)).FaffExpr = 0
		(*TExpr)(unsafe.Pointer(p)).Fflags = uint32(EP_Leaf)
		/* p->iAgg = -1; // Not required */
		v1 = libc.UintptrFromInt32(0)
		(*TExpr)(unsafe.Pointer(p)).FpRight = v1
		(*TExpr)(unsafe.Pointer(p)).FpLeft = v1
		(*TExpr)(unsafe.Pointer(p)).FpAggInfo = uintptr(0)
		libc.Xmemset(tls, p+20, 0, uint32(4))
		libc.Xmemset(tls, p+44, 0, uint32(8))
		(*TExpr)(unsafe.Pointer(p)).Fop2 = uint8(0)
		(*TExpr)(unsafe.Pointer(p)).FiTable = 0
		(*TExpr)(unsafe.Pointer(p)).FiColumn = 0
		*(*uintptr)(unsafe.Pointer(p + 8)) = p + 1*52
		libc.Xmemcpy(tls, *(*uintptr)(unsafe.Pointer(p + 8)), (**(**TToken)(__ccgo_up(bp))).Fz, (**(**TToken)(__ccgo_up(bp))).Fn)
		**(**int8)(__ccgo_up(*(*uintptr)(unsafe.Pointer(p + 8)) + uintptr((**(**TToken)(__ccgo_up(bp))).Fn))) = 0
		*(*int32)(unsafe.Pointer(p + 36)) = int32((**(**TToken)(__ccgo_up(bp))).Fz) - int32((*TParse)(unsafe.Pointer(pParse)).FzTail)
		if libc.Int32FromUint8(_sqlite3CtypeMap[libc.Uint8FromInt8(**(**int8)(__ccgo_up(*(*uintptr)(unsafe.Pointer(p + 8)))))])&int32(0x80) != 0 {
			_sqlite3DequoteExpr(tls, p)
		}
		(*TExpr)(unsafe.Pointer(p)).FnHeight = int32(1)
		if libc.Int32FromUint8((*TParse)(unsafe.Pointer(pParse)).FeParseMode) >= int32(PARSE_MODE_RENAME) {
			return _sqlite3RenameTokenMap(tls, pParse, p, bp)
		}
	}
	return p
}

// C documentation
//
//	/*
//	** Implementation of sqlite3_vtab_in_first() (if bNext==0) and
//	** sqlite3_vtab_in_next() (if bNext!=0).
//	*/
func _valueFromValueList(tls *libc.TLS, pVal uintptr, ppOut uintptr, bNext int32) (r int32) {
	bp := tls.Alloc(48)
	defer tls.Free(48)
	var iOff, rc, v1 int32
	var pOut, pRhs, zBuf uintptr
	var sz Tu32
	var _ /* dummy at bp+0 */ int32
	var _ /* iSerial at bp+44 */ Tu32
	var _ /* sMem at bp+4 */ TMem
	_, _, _, _, _, _, _ = iOff, pOut, pRhs, rc, sz, zBuf, v1
	**(**uintptr)(__ccgo_up(ppOut)) = uintptr(0)
	if pVal == uintptr(0) {
		return _sqlite3MisuseError(tls, int32(94599))
	}
	if libc.Int32FromUint16((*Tsqlite3_value)(unsafe.Pointer(pVal)).Fflags)&int32(MEM_Dyn) == 0 || (*Tsqlite3_value)(unsafe.Pointer(pVal)).FxDel != __ccgo_fp(_sqlite3VdbeValueListFree) {
		return int32(SQLITE_ERROR)
	} else {
		pRhs = (*Tsqlite3_value)(unsafe.Pointer(pVal)).Fz
	}
	if bNext != 0 {
		rc = _sqlite3BtreeNext(tls, (*TValueList)(unsafe.Pointer(pRhs)).FpCsr, 0)
	} else {
		**(**int32)(__ccgo_up(bp)) = 0
		rc = _sqlite3BtreeFirst(tls, (*TValueList)(unsafe.Pointer(pRhs)).FpCsr, bp)
		if _sqlite3BtreeEof(tls, (*TValueList)(unsafe.Pointer(pRhs)).FpCsr) != 0 {
			rc = int32(SQLITE_DONE)
		}
	}
	if rc == SQLITE_OK { /* Raw content of current row */
		libc.Xmemset(tls, bp+4, 0, uint32(40))
		sz = _sqlite3BtreePayloadSize(tls, (*TValueList)(unsafe.Pointer(pRhs)).FpCsr)
		rc = _sqlite3VdbeMemFromBtreeZeroOffset(tls, (*TValueList)(unsafe.Pointer(pRhs)).FpCsr, sz, bp+4)
		if rc == SQLITE_OK {
			zBuf = (**(**TMem)(__ccgo_up(bp + 4))).Fz
			pOut = (*TValueList)(unsafe.Pointer(pRhs)).FpOut
			if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(zBuf + 1))) < libc.Int32FromUint8(libc.Uint8FromInt32(0x80)) {
				**(**Tu32)(__ccgo_up(bp + 44)) = uint32(**(**Tu8)(__ccgo_up(zBuf + 1)))
				v1 = libc.Int32FromInt32(1)
			} else {
				v1 = libc.Int32FromUint8(_sqlite3GetVarint32(tls, zBuf+1, bp+44))
			}
			iOff = int32(1) + libc.Int32FromUint8(libc.Uint8FromInt32(v1))
			_sqlite3VdbeSerialGet(tls, zBuf+uintptr(iOff), **(**Tu32)(__ccgo_up(bp + 44)), pOut)
			(*Tsqlite3_value)(unsafe.Pointer(pOut)).Fenc = (*Tsqlite3)(unsafe.Pointer((*Tsqlite3_value)(unsafe.Pointer(pOut)).Fdb)).Fenc
			if libc.Int32FromUint16((*Tsqlite3_value)(unsafe.Pointer(pOut)).Fflags)&int32(MEM_Ephem) != 0 && _sqlite3VdbeMemMakeWriteable(tls, pOut) != 0 {
				rc = int32(SQLITE_NOMEM)
			} else {
				**(**uintptr)(__ccgo_up(ppOut)) = pOut
			}
		}
		_sqlite3VdbeMemRelease(tls, bp+4)
	}
	return rc
}

// C documentation
//
//	/*
//	** Allocate and return a pointer to a new sqlite3_value object. If
//	** the second argument to this function is NULL, the object is allocated
//	** by calling sqlite3ValueNew().
//	**
//	** Otherwise, if the second argument is non-zero, then this function is
//	** being called indirectly by sqlite3Stat4ProbeSetValue(). If it has not
//	** already been allocated, allocate the UnpackedRecord structure that
//	** that function will return to its caller here. Then return a pointer to
//	** an sqlite3_value within the UnpackedRecord.a[] array.
//	*/
func _valueNew(tls *libc.TLS, db uintptr, p uintptr) (r uintptr) {
	var i, nCol int32
	var nByte Ti64
	var pIdx, pRec uintptr
	_, _, _, _, _ = i, nByte, nCol, pIdx, pRec
	if p != 0 {
		pRec = **(**uintptr)(__ccgo_up((*TValueNewStat4Ctx)(unsafe.Pointer(p)).FppRec))
		if pRec == uintptr(0) {
			pIdx = (*TValueNewStat4Ctx)(unsafe.Pointer(p)).FpIdx                  /* Counter variable */
			nCol = libc.Int32FromUint16((*TIndex)(unsafe.Pointer(pIdx)).FnColumn) /* Number of index columns including rowid */
			nByte = libc.Int64FromUint32(uint32(40)*libc.Uint32FromInt32(nCol) + (libc.Uint32FromInt64(28)+libc.Uint32FromInt32(7))&libc.Uint32FromInt32(^libc.Int32FromInt32(7)))
			pRec = _sqlite3DbMallocZero(tls, db, libc.Uint64FromInt64(nByte))
			if pRec != 0 {
				(*TUnpackedRecord)(unsafe.Pointer(pRec)).FpKeyInfo = _sqlite3KeyInfoOfIndex(tls, (*TValueNewStat4Ctx)(unsafe.Pointer(p)).FpParse, pIdx)
				if (*TUnpackedRecord)(unsafe.Pointer(pRec)).FpKeyInfo != 0 {
					(*TUnpackedRecord)(unsafe.Pointer(pRec)).FaMem = pRec + uintptr((libc.Uint32FromInt64(28)+libc.Uint32FromInt32(7))&libc.Uint32FromInt32(^libc.Int32FromInt32(7)))
					i = 0
					for {
						if !(i < nCol) {
							break
						}
						(**(**TMem)(__ccgo_up((*TUnpackedRecord)(unsafe.Pointer(pRec)).FaMem + uintptr(i)*40))).Fflags = uint16(MEM_Null)
						(**(**TMem)(__ccgo_up((*TUnpackedRecord)(unsafe.Pointer(pRec)).FaMem + uintptr(i)*40))).Fdb = db
						goto _1
					_1:
						;
						i = i + 1
					}
				} else {
					_sqlite3DbFreeNN(tls, db, pRec)
					pRec = uintptr(0)
				}
			}
			if pRec == uintptr(0) {
				return uintptr(0)
			}
			**(**uintptr)(__ccgo_up((*TValueNewStat4Ctx)(unsafe.Pointer(p)).FppRec)) = pRec
		}
		(*TUnpackedRecord)(unsafe.Pointer(pRec)).FnField = libc.Uint16FromInt32((*TValueNewStat4Ctx)(unsafe.Pointer(p)).FiVal + int32(1))
		_sqlite3VdbeMemSetNull(tls, (*TUnpackedRecord)(unsafe.Pointer(pRec)).FaMem+uintptr((*TValueNewStat4Ctx)(unsafe.Pointer(p)).FiVal)*40)
		return (*TUnpackedRecord)(unsafe.Pointer(pRec)).FaMem + uintptr((*TValueNewStat4Ctx)(unsafe.Pointer(p)).FiVal)*40
	}
	return _sqlite3ValueNew(tls, db)
}

// C documentation
//
//	/*
//	** For OP_Column, factor out the case where content is loaded from
//	** overflow pages, so that the code to implement this case is separate
//	** the common case where all content fits on the page.  Factoring out
//	** the code reduces register pressure and helps the common case
//	** to run faster.
//	*/
func _vdbeColumnFromOverflow(tls *libc.TLS, pC uintptr, iCol int32, t Tu32, iOffset Ti64, cacheStatus Tu32, colCacheCtr Tu32, pDest uintptr) (r int32) {
	var db, pBuf, pCache, v1 uintptr
	var encoding, len1, rc int32
	_, _, _, _, _, _, _ = db, encoding, len1, pBuf, pCache, rc, v1
	db = (*TMem)(unsafe.Pointer(pDest)).Fdb
	encoding = libc.Int32FromUint8((*TMem)(unsafe.Pointer(pDest)).Fenc)
	len1 = libc.Int32FromUint32(_sqlite3VdbeSerialTypeLen(tls, t))
	if len1 > **(**int32)(__ccgo_up(db + 116)) {
		return int32(SQLITE_TOOBIG)
	}
	if len1 > int32(4000) && (*TVdbeCursor)(unsafe.Pointer(pC)).FpKeyInfo == uintptr(0) {
		if int32(TBool(*(*uint8)(unsafe.Pointer(pC + 8))&0x10>>4)) == 0 {
			(*TVdbeCursor)(unsafe.Pointer(pC)).FpCache = _sqlite3DbMallocZero(tls, db, uint64(24))
			if (*TVdbeCursor)(unsafe.Pointer(pC)).FpCache == uintptr(0) {
				return int32(SQLITE_NOMEM)
			}
			libc.SetBitFieldPtr8Uint32(pC+8, libc.Uint32FromInt32(1), 4, 0x10)
		}
		pCache = (*TVdbeCursor)(unsafe.Pointer(pC)).FpCache
		if (*TVdbeTxtBlbCache)(unsafe.Pointer(pCache)).FpCValue == uintptr(0) || (*TVdbeTxtBlbCache)(unsafe.Pointer(pCache)).FiCol != iCol || (*TVdbeTxtBlbCache)(unsafe.Pointer(pCache)).FcacheStatus != cacheStatus || (*TVdbeTxtBlbCache)(unsafe.Pointer(pCache)).FcolCacheCtr != colCacheCtr || (*TVdbeTxtBlbCache)(unsafe.Pointer(pCache)).FiOffset != _sqlite3BtreeOffset(tls, *(*uintptr)(unsafe.Pointer(pC + 36))) {
			if (*TVdbeTxtBlbCache)(unsafe.Pointer(pCache)).FpCValue != 0 {
				_sqlite3RCStrUnref(tls, (*TVdbeTxtBlbCache)(unsafe.Pointer(pCache)).FpCValue)
			}
			v1 = _sqlite3RCStrNew(tls, libc.Uint64FromInt32(len1+int32(3)))
			(*TVdbeTxtBlbCache)(unsafe.Pointer(pCache)).FpCValue = v1
			pBuf = v1
			if pBuf == uintptr(0) {
				return int32(SQLITE_NOMEM)
			}
			rc = _sqlite3BtreePayload(tls, *(*uintptr)(unsafe.Pointer(pC + 36)), libc.Uint32FromInt64(iOffset), libc.Uint32FromInt32(len1), pBuf)
			if rc != 0 {
				return rc
			}
			**(**int8)(__ccgo_up(pBuf + uintptr(len1))) = 0
			**(**int8)(__ccgo_up(pBuf + uintptr(len1+int32(1)))) = 0
			**(**int8)(__ccgo_up(pBuf + uintptr(len1+int32(2)))) = 0
			(*TVdbeTxtBlbCache)(unsafe.Pointer(pCache)).FiCol = iCol
			(*TVdbeTxtBlbCache)(unsafe.Pointer(pCache)).FcacheStatus = cacheStatus
			(*TVdbeTxtBlbCache)(unsafe.Pointer(pCache)).FcolCacheCtr = colCacheCtr
			(*TVdbeTxtBlbCache)(unsafe.Pointer(pCache)).FiOffset = _sqlite3BtreeOffset(tls, *(*uintptr)(unsafe.Pointer(pC + 36)))
		} else {
			pBuf = (*TVdbeTxtBlbCache)(unsafe.Pointer(pCache)).FpCValue
		}
		_sqlite3RCStrRef(tls, pBuf)
		if t&uint32(1) != 0 {
			rc = _sqlite3VdbeMemSetStr(tls, pDest, pBuf, int64(len1), libc.Uint8FromInt32(encoding), __ccgo_fp(_sqlite3RCStrUnref))
			v1 = pDest + 16
			*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) | libc.Int32FromInt32(MEM_Term))
		} else {
			rc = _sqlite3VdbeMemSetStr(tls, pDest, pBuf, int64(len1), uint8(0), __ccgo_fp(_sqlite3RCStrUnref))
		}
	} else {
		rc = _sqlite3VdbeMemFromBtree(tls, *(*uintptr)(unsafe.Pointer(pC + 36)), libc.Uint32FromInt64(iOffset), libc.Uint32FromInt32(len1), pDest)
		if rc != 0 {
			return rc
		}
		_sqlite3VdbeSerialGet(tls, (*TMem)(unsafe.Pointer(pDest)).Fz, t, pDest)
		if t&uint32(1) != uint32(0) && encoding == int32(SQLITE_UTF8) {
			**(**int8)(__ccgo_up((*TMem)(unsafe.Pointer(pDest)).Fz + uintptr(len1))) = 0
			v1 = pDest + 16
			*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) | libc.Int32FromInt32(MEM_Term))
		}
	}
	v1 = pDest + 16
	*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) & ^libc.Int32FromInt32(MEM_Ephem))
	return rc
}

// C documentation
//
//	/*
//	** Free all resources associated with the IncrMerger object indicated by
//	** the first argument.
//	*/
func _vdbeIncrFree(tls *libc.TLS, pIncr uintptr) {
	if pIncr != 0 {
		if (*TIncrMerger)(unsafe.Pointer(pIncr)).FbUseThread != 0 {
			_vdbeSorterJoinThread(tls, (*TIncrMerger)(unsafe.Pointer(pIncr)).FpTask)
			if (**(**TSorterFile)(__ccgo_up(pIncr + 28))).FpFd != 0 {
				_sqlite3OsCloseFree(tls, (**(**TSorterFile)(__ccgo_up(pIncr + 28))).FpFd)
			}
			if (**(**TSorterFile)(__ccgo_up(pIncr + 28 + 1*12))).FpFd != 0 {
				_sqlite3OsCloseFree(tls, (**(**TSorterFile)(__ccgo_up(pIncr + 28 + 1*12))).FpFd)
			}
		}
		_vdbeMergeEngineFree(tls, (*TIncrMerger)(unsafe.Pointer(pIncr)).FpMerger)
		Xsqlite3_free(tls, pIncr)
	}
}

// C documentation
//
//	/*
//	** Allocate and return a new IncrMerger object to read data from pMerger.
//	**
//	** If an OOM condition is encountered, return NULL. In this case free the
//	** pMerger argument before returning.
//	*/
func _vdbeIncrMergerNew(tls *libc.TLS, pTask uintptr, pMerger uintptr, ppOut uintptr) (r int32) {
	var pIncr, v1, v2 uintptr
	var rc, v3 int32
	_, _, _, _, _ = pIncr, rc, v1, v2, v3
	rc = SQLITE_OK
	if _sqlite3FaultSim(tls, int32(100)) != 0 {
		v2 = uintptr(0)
	} else {
		v2 = _sqlite3MallocZero(tls, uint64(52))
	}
	v1 = v2
	**(**uintptr)(__ccgo_up(ppOut)) = v1
	pIncr = v1
	if pIncr != 0 {
		(*TIncrMerger)(unsafe.Pointer(pIncr)).FpMerger = pMerger
		(*TIncrMerger)(unsafe.Pointer(pIncr)).FpTask = pTask
		if (*TVdbeSorter)(unsafe.Pointer((*TSortSubtask)(unsafe.Pointer(pTask)).FpSorter)).FmxKeysize+int32(9) > (*TVdbeSorter)(unsafe.Pointer((*TSortSubtask)(unsafe.Pointer(pTask)).FpSorter)).FmxPmaSize/int32(2) {
			v3 = (*TVdbeSorter)(unsafe.Pointer((*TSortSubtask)(unsafe.Pointer(pTask)).FpSorter)).FmxKeysize + int32(9)
		} else {
			v3 = (*TVdbeSorter)(unsafe.Pointer((*TSortSubtask)(unsafe.Pointer(pTask)).FpSorter)).FmxPmaSize / int32(2)
		}
		(*TIncrMerger)(unsafe.Pointer(pIncr)).FmxSz = v3
		(*TSortSubtask)(unsafe.Pointer(pTask)).Ffile2.FiEof += int64((*TIncrMerger)(unsafe.Pointer(pIncr)).FmxSz)
	} else {
		_vdbeMergeEngineFree(tls, pMerger)
		rc = int32(SQLITE_NOMEM)
	}
	return rc
}

// C documentation
//
//	/*
//	** Read keys from pIncr->pMerger and populate pIncr->aFile[1]. The format
//	** of the data stored in aFile[1] is the same as that used by regular PMAs,
//	** except that the number-of-bytes varint is omitted from the start.
//	*/
func _vdbeIncrPopulate(tls *libc.TLS, pIncr uintptr) (r int32) {
	bp := tls.Alloc(48)
	defer tls.Free(48)
	var iEof, iStart Ti64
	var nKey, rc, rc2 int32
	var pMerger, pOut, pReader, pTask uintptr
	var _ /* dummy at bp+40 */ int32
	var _ /* writer at bp+0 */ TPmaWriter
	_, _, _, _, _, _, _, _, _ = iEof, iStart, nKey, pMerger, pOut, pReader, pTask, rc, rc2
	rc = SQLITE_OK
	iStart = (*TIncrMerger)(unsafe.Pointer(pIncr)).FiStartOff
	pOut = pIncr + 28 + 1*12
	pTask = (*TIncrMerger)(unsafe.Pointer(pIncr)).FpTask
	pMerger = (*TIncrMerger)(unsafe.Pointer(pIncr)).FpMerger
	_vdbePmaWriterInit(tls, (*TSorterFile)(unsafe.Pointer(pOut)).FpFd, bp, (*TVdbeSorter)(unsafe.Pointer((*TSortSubtask)(unsafe.Pointer(pTask)).FpSorter)).Fpgsz, iStart)
	for rc == SQLITE_OK {
		pReader = (*TMergeEngine)(unsafe.Pointer(pMerger)).FaReadr + uintptr(**(**int32)(__ccgo_up((*TMergeEngine)(unsafe.Pointer(pMerger)).FaTree + 1*4)))*52
		nKey = (*TPmaReader)(unsafe.Pointer(pReader)).FnKey
		iEof = (**(**TPmaWriter)(__ccgo_up(bp))).FiWriteOff + int64((**(**TPmaWriter)(__ccgo_up(bp))).FiBufEnd)
		/* Check if the output file is full or if the input has been exhausted.
		 ** In either case exit the loop. */
		if (*TPmaReader)(unsafe.Pointer(pReader)).FpFd == uintptr(0) {
			break
		}
		if iEof+int64(nKey)+int64(_sqlite3VarintLen(tls, libc.Uint64FromInt32(nKey))) > iStart+int64((*TIncrMerger)(unsafe.Pointer(pIncr)).FmxSz) {
			break
		}
		/* Write the next key to the output. */
		_vdbePmaWriteVarint(tls, bp, libc.Uint64FromInt32(nKey))
		_vdbePmaWriteBlob(tls, bp, (*TPmaReader)(unsafe.Pointer(pReader)).FaKey, nKey)
		rc = _vdbeMergeEngineStep(tls, (*TIncrMerger)(unsafe.Pointer(pIncr)).FpMerger, bp+40)
	}
	rc2 = _vdbePmaWriterFinish(tls, bp, pOut+4, pTask+64)
	if rc == SQLITE_OK {
		rc = rc2
	}
	return rc
}

// C documentation
//
//	/*
//	** This function is called when the PmaReader corresponding to pIncr has
//	** finished reading the contents of aFile[0]. Its purpose is to "refill"
//	** aFile[0] such that the PmaReader should start rereading it from the
//	** beginning.
//	**
//	** For single-threaded objects, this is accomplished by literally reading
//	** keys from pIncr->pMerger and repopulating aFile[0].
//	**
//	** For multi-threaded objects, all that is required is to wait until the
//	** background thread is finished (if it is not already) and then swap
//	** aFile[0] and aFile[1] in place. If the contents of pMerger have not
//	** been exhausted, this function also launches a new background thread
//	** to populate the new aFile[1].
//	**
//	** SQLITE_OK is returned on success, or an SQLite error code otherwise.
//	*/
func _vdbeIncrSwap(tls *libc.TLS, pIncr uintptr) (r int32) {
	var f0 TSorterFile
	var rc int32
	_, _ = f0, rc
	rc = SQLITE_OK
	if (*TIncrMerger)(unsafe.Pointer(pIncr)).FbUseThread != 0 {
		rc = _vdbeSorterJoinThread(tls, (*TIncrMerger)(unsafe.Pointer(pIncr)).FpTask)
		if rc == SQLITE_OK {
			f0 = **(**TSorterFile)(__ccgo_up(pIncr + 28))
			**(**TSorterFile)(__ccgo_up(pIncr + 28)) = **(**TSorterFile)(__ccgo_up(pIncr + 28 + 1*12))
			**(**TSorterFile)(__ccgo_up(pIncr + 28 + 1*12)) = f0
		}
		if rc == SQLITE_OK {
			if (**(**TSorterFile)(__ccgo_up(pIncr + 28))).FiEof == (*TIncrMerger)(unsafe.Pointer(pIncr)).FiStartOff {
				(*TIncrMerger)(unsafe.Pointer(pIncr)).FbEof = int32(1)
			} else {
				rc = _vdbeIncrBgPopulate(tls, pIncr)
			}
		}
	} else {
		rc = _vdbeIncrPopulate(tls, pIncr)
		**(**TSorterFile)(__ccgo_up(pIncr + 28)) = **(**TSorterFile)(__ccgo_up(pIncr + 28 + 1*12))
		if (**(**TSorterFile)(__ccgo_up(pIncr + 28))).FiEof == (*TIncrMerger)(unsafe.Pointer(pIncr)).FiStartOff {
			(*TIncrMerger)(unsafe.Pointer(pIncr)).FbEof = int32(1)
		}
	}
	return rc
}

// C documentation
//
//	/*
//	** Recompute pMerger->aTree[iOut] by comparing the next keys on the
//	** two PmaReaders that feed that entry.  Neither of the PmaReaders
//	** are advanced.  This routine merely does the comparison.
//	*/
func _vdbeMergeEngineCompare(tls *libc.TLS, pMerger uintptr, iOut int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var i1, i2, iRes, res int32
	var p1, p2, pTask uintptr
	var _ /* bCached at bp+0 */ int32
	_, _, _, _, _, _, _ = i1, i2, iRes, p1, p2, pTask, res
	if iOut >= (*TMergeEngine)(unsafe.Pointer(pMerger)).FnTree/int32(2) {
		i1 = (iOut - (*TMergeEngine)(unsafe.Pointer(pMerger)).FnTree/int32(2)) * int32(2)
		i2 = i1 + int32(1)
	} else {
		i1 = **(**int32)(__ccgo_up((*TMergeEngine)(unsafe.Pointer(pMerger)).FaTree + uintptr(iOut*int32(2))*4))
		i2 = **(**int32)(__ccgo_up((*TMergeEngine)(unsafe.Pointer(pMerger)).FaTree + uintptr(iOut*int32(2)+int32(1))*4))
	}
	p1 = (*TMergeEngine)(unsafe.Pointer(pMerger)).FaReadr + uintptr(i1)*52
	p2 = (*TMergeEngine)(unsafe.Pointer(pMerger)).FaReadr + uintptr(i2)*52
	if (*TPmaReader)(unsafe.Pointer(p1)).FpFd == uintptr(0) {
		iRes = i2
	} else {
		if (*TPmaReader)(unsafe.Pointer(p2)).FpFd == uintptr(0) {
			iRes = i1
		} else {
			pTask = (*TMergeEngine)(unsafe.Pointer(pMerger)).FpTask
			**(**int32)(__ccgo_up(bp)) = 0
			/* from vdbeSortSubtaskMain() */
			res = (*(*func(*libc.TLS, uintptr, uintptr, uintptr, int32, uintptr, int32) int32)(unsafe.Pointer(&struct{ uintptr }{(*TSortSubtask)(unsafe.Pointer(pTask)).FxCompare})))(tls, pTask, bp, (*TPmaReader)(unsafe.Pointer(p1)).FaKey, (*TPmaReader)(unsafe.Pointer(p1)).FnKey, (*TPmaReader)(unsafe.Pointer(p2)).FaKey, (*TPmaReader)(unsafe.Pointer(p2)).FnKey)
			if res <= 0 {
				iRes = i1
			} else {
				iRes = i2
			}
		}
	}
	**(**int32)(__ccgo_up((*TMergeEngine)(unsafe.Pointer(pMerger)).FaTree + uintptr(iOut)*4)) = iRes
}

// C documentation
//
//	/*
//	** Free the MergeEngine object passed as the only argument.
//	*/
func _vdbeMergeEngineFree(tls *libc.TLS, pMerger uintptr) {
	var i int32
	_ = i
	if pMerger != 0 {
		i = 0
		for {
			if !(i < (*TMergeEngine)(unsafe.Pointer(pMerger)).FnTree) {
				break
			}
			_vdbePmaReaderClear(tls, (*TMergeEngine)(unsafe.Pointer(pMerger)).FaReadr+uintptr(i)*52)
			goto _1
		_1:
			;
			i = i + 1
		}
	}
	Xsqlite3_free(tls, pMerger)
}

// C documentation
//
//	/*
//	** Initialize the MergeEngine object passed as the second argument. Once this
//	** function returns, the first key of merged data may be read from the
//	** MergeEngine object in the usual fashion.
//	**
//	** If argument eMode is INCRINIT_ROOT, then it is assumed that any IncrMerge
//	** objects attached to the PmaReader objects that the merger reads from have
//	** already been populated, but that they have not yet populated aFile[0] and
//	** set the PmaReader objects up to read from it. In this case all that is
//	** required is to call vdbePmaReaderNext() on each PmaReader to point it at
//	** its first key.
//	**
//	** Otherwise, if eMode is any value other than INCRINIT_ROOT, then use
//	** vdbePmaReaderIncrMergeInit() to initialize each PmaReader that feeds data
//	** to pMerger.
//	**
//	** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
//	*/
func _vdbeMergeEngineInit(tls *libc.TLS, pTask uintptr, pMerger uintptr, eMode int32) (r int32) {
	var i, nTree, rc int32
	_, _, _ = i, nTree, rc
	rc = SQLITE_OK /* Number of subtrees to merge */
	/* Failure to allocate the merge would have been detected prior to
	 ** invoking this routine */
	/* eMode is always INCRINIT_NORMAL in single-threaded mode */
	/* Verify that the MergeEngine is assigned to a single thread */
	(*TMergeEngine)(unsafe.Pointer(pMerger)).FpTask = pTask
	nTree = (*TMergeEngine)(unsafe.Pointer(pMerger)).FnTree
	i = 0
	for {
		if !(i < nTree) {
			break
		}
		if libc.Bool(int32(SQLITE_MAX_WORKER_THREADS) > 0) && eMode == int32(INCRINIT_ROOT) {
			/* PmaReaders should be normally initialized in order, as if they are
			 ** reading from the same temp file this makes for more linear file IO.
			 ** However, in the INCRINIT_ROOT case, if PmaReader aReadr[nTask-1] is
			 ** in use it will block the vdbePmaReaderNext() call while it uses
			 ** the main thread to fill its buffer. So calling PmaReaderNext()
			 ** on this PmaReader before any of the multi-threaded PmaReaders takes
			 ** better advantage of multi-processor hardware. */
			rc = _vdbePmaReaderNext(tls, (*TMergeEngine)(unsafe.Pointer(pMerger)).FaReadr+uintptr(nTree-i-int32(1))*52)
		} else {
			rc = _vdbePmaReaderIncrInit(tls, (*TMergeEngine)(unsafe.Pointer(pMerger)).FaReadr+uintptr(i)*52, INCRINIT_NORMAL)
		}
		if rc != SQLITE_OK {
			return rc
		}
		goto _1
	_1:
		;
		i = i + 1
	}
	i = (*TMergeEngine)(unsafe.Pointer(pMerger)).FnTree - int32(1)
	for {
		if !(i > 0) {
			break
		}
		_vdbeMergeEngineCompare(tls, pMerger, i)
		goto _2
	_2:
		;
		i = i - 1
	}
	return libc.Int32FromUint8((*TUnpackedRecord)(unsafe.Pointer((*TSortSubtask)(unsafe.Pointer(pTask)).FpUnpacked)).FerrCode)
}

// C documentation
//
//	/*
//	** Allocate a new MergeEngine object to merge the contents of nPMA level-0
//	** PMAs from pTask->file. If no error occurs, set *ppOut to point to
//	** the new object and return SQLITE_OK. Or, if an error does occur, set *ppOut
//	** to NULL and return an SQLite error code.
//	**
//	** When this function is called, *piOffset is set to the offset of the
//	** first PMA to read from pTask->file. Assuming no error occurs, it is
//	** set to the offset immediately following the last byte of the last
//	** PMA before returning. If an error does occur, then the final value of
//	** *piOffset is undefined.
//	*/
func _vdbeMergeEngineLevel0(tls *libc.TLS, pTask uintptr, nPMA int32, piOffset uintptr, ppOut uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var i, rc int32
	var iOff Ti64
	var pNew, pReadr, v1 uintptr
	var _ /* nDummy at bp+0 */ Ti64
	_, _, _, _, _, _ = i, iOff, pNew, pReadr, rc, v1 /* Merge engine to return */
	iOff = **(**Ti64)(__ccgo_up(piOffset))
	rc = SQLITE_OK
	v1 = _vdbeMergeEngineNew(tls, nPMA)
	pNew = v1
	**(**uintptr)(__ccgo_up(ppOut)) = v1
	if pNew == uintptr(0) {
		rc = int32(SQLITE_NOMEM)
	}
	i = 0
	for {
		if !(i < nPMA && rc == SQLITE_OK) {
			break
		}
		**(**Ti64)(__ccgo_up(bp)) = 0
		pReadr = (*TMergeEngine)(unsafe.Pointer(pNew)).FaReadr + uintptr(i)*52
		rc = _vdbePmaReaderInit(tls, pTask, pTask+40, iOff, pReadr, bp)
		iOff = (*TPmaReader)(unsafe.Pointer(pReadr)).FiEof
		goto _2
	_2:
		;
		i = i + 1
	}
	if rc != SQLITE_OK {
		_vdbeMergeEngineFree(tls, pNew)
		**(**uintptr)(__ccgo_up(ppOut)) = uintptr(0)
	}
	**(**Ti64)(__ccgo_up(piOffset)) = iOff
	return rc
}

// C documentation
//
//	/*
//	** Allocate a new MergeEngine object capable of handling up to
//	** nReader PmaReader inputs.
//	**
//	** nReader is automatically rounded up to the next power of two.
//	** nReader may not exceed SORTER_MAX_MERGE_COUNT even after rounding up.
//	*/
func _vdbeMergeEngineNew(tls *libc.TLS, nReader int32) (r uintptr) {
	var N int32
	var nByte Ti64
	var pNew, v1 uintptr
	_, _, _, _ = N, nByte, pNew, v1
	N = int32(2) /* Pointer to allocated object to return */
	for N < nReader {
		N = N + N
	}
	nByte = libc.Int64FromUint32(uint32(16) + libc.Uint32FromInt32(N)*(libc.Uint32FromInt64(4)+libc.Uint32FromInt64(52)))
	if _sqlite3FaultSim(tls, int32(100)) != 0 {
		v1 = uintptr(0)
	} else {
		v1 = _sqlite3MallocZero(tls, libc.Uint64FromInt64(nByte))
	}
	pNew = v1
	if pNew != 0 {
		(*TMergeEngine)(unsafe.Pointer(pNew)).FnTree = N
		(*TMergeEngine)(unsafe.Pointer(pNew)).FpTask = uintptr(0)
		(*TMergeEngine)(unsafe.Pointer(pNew)).FaReadr = pNew + 1*16
		(*TMergeEngine)(unsafe.Pointer(pNew)).FaTree = (*TMergeEngine)(unsafe.Pointer(pNew)).FaReadr + uintptr(N)*52
	}
	return pNew
}

// C documentation
//
//	/*
//	** Advance the MergeEngine to its next entry.
//	** Set *pbEof to true there is no next entry because
//	** the MergeEngine has reached the end of all its inputs.
//	**
//	** Return SQLITE_OK if successful or an error code if an error occurs.
//	*/
func _vdbeMergeEngineStep(tls *libc.TLS, pMerger uintptr, pbEof uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var i, iPrev, iRes, rc, v2 int32
	var pReadr1, pReadr2, pTask uintptr
	var _ /* bCached at bp+0 */ int32
	_, _, _, _, _, _, _, _ = i, iPrev, iRes, pReadr1, pReadr2, pTask, rc, v2
	iPrev = **(**int32)(__ccgo_up((*TMergeEngine)(unsafe.Pointer(pMerger)).FaTree + 1*4)) /* Index of PmaReader to advance */
	pTask = (*TMergeEngine)(unsafe.Pointer(pMerger)).FpTask
	/* Advance the current PmaReader */
	rc = _vdbePmaReaderNext(tls, (*TMergeEngine)(unsafe.Pointer(pMerger)).FaReadr+uintptr(iPrev)*52)
	/* Update contents of aTree[] */
	if rc == SQLITE_OK { /* Second PmaReader to compare */
		**(**int32)(__ccgo_up(bp)) = 0
		/* Find the first two PmaReaders to compare. The one that was just
		 ** advanced (iPrev) and the one next to it in the array.  */
		pReadr1 = (*TMergeEngine)(unsafe.Pointer(pMerger)).FaReadr + uintptr(iPrev&libc.Int32FromInt32(0xFFFE))*52
		pReadr2 = (*TMergeEngine)(unsafe.Pointer(pMerger)).FaReadr + uintptr(iPrev|libc.Int32FromInt32(0x0001))*52
		i = ((*TMergeEngine)(unsafe.Pointer(pMerger)).FnTree + iPrev) / int32(2)
		for {
			if !(i > 0) {
				break
			}
			if (*TPmaReader)(unsafe.Pointer(pReadr1)).FpFd == uintptr(0) {
				iRes = +libc.Int32FromInt32(1)
			} else {
				if (*TPmaReader)(unsafe.Pointer(pReadr2)).FpFd == uintptr(0) {
					iRes = -int32(1)
				} else {
					iRes = (*(*func(*libc.TLS, uintptr, uintptr, uintptr, int32, uintptr, int32) int32)(unsafe.Pointer(&struct{ uintptr }{(*TSortSubtask)(unsafe.Pointer(pTask)).FxCompare})))(tls, pTask, bp, (*TPmaReader)(unsafe.Pointer(pReadr1)).FaKey, (*TPmaReader)(unsafe.Pointer(pReadr1)).FnKey, (*TPmaReader)(unsafe.Pointer(pReadr2)).FaKey, (*TPmaReader)(unsafe.Pointer(pReadr2)).FnKey)
				}
			}
			/* If pReadr1 contained the smaller value, set aTree[i] to its index.
			 ** Then set pReadr2 to the next PmaReader to compare to pReadr1. In this
			 ** case there is no cache of pReadr2 in pTask->pUnpacked, so set
			 ** pKey2 to point to the record belonging to pReadr2.
			 **
			 ** Alternatively, if pReadr2 contains the smaller of the two values,
			 ** set aTree[i] to its index and update pReadr1. If vdbeSorterCompare()
			 ** was actually called above, then pTask->pUnpacked now contains
			 ** a value equivalent to pReadr2. So set pKey2 to NULL to prevent
			 ** vdbeSorterCompare() from decoding pReadr2 again.
			 **
			 ** If the two values were equal, then the value from the oldest
			 ** PMA should be considered smaller. The VdbeSorter.aReadr[] array
			 ** is sorted from oldest to newest, so pReadr1 contains older values
			 ** than pReadr2 iff (pReadr1<pReadr2).  */
			if iRes < 0 || iRes == 0 && pReadr1 < pReadr2 {
				**(**int32)(__ccgo_up((*TMergeEngine)(unsafe.Pointer(pMerger)).FaTree + uintptr(i)*4)) = (int32(pReadr1) - int32((*TMergeEngine)(unsafe.Pointer(pMerger)).FaReadr)) / 52
				pReadr2 = (*TMergeEngine)(unsafe.Pointer(pMerger)).FaReadr + uintptr(**(**int32)(__ccgo_up((*TMergeEngine)(unsafe.Pointer(pMerger)).FaTree + uintptr(i^int32(0x0001))*4)))*52
				**(**int32)(__ccgo_up(bp)) = 0
			} else {
				if (*TPmaReader)(unsafe.Pointer(pReadr1)).FpFd != 0 {
					**(**int32)(__ccgo_up(bp)) = 0
				}
				**(**int32)(__ccgo_up((*TMergeEngine)(unsafe.Pointer(pMerger)).FaTree + uintptr(i)*4)) = (int32(pReadr2) - int32((*TMergeEngine)(unsafe.Pointer(pMerger)).FaReadr)) / 52
				pReadr1 = (*TMergeEngine)(unsafe.Pointer(pMerger)).FaReadr + uintptr(**(**int32)(__ccgo_up((*TMergeEngine)(unsafe.Pointer(pMerger)).FaTree + uintptr(i^int32(0x0001))*4)))*52
			}
			goto _1
		_1:
			;
			i = i / int32(2)
		}
		**(**int32)(__ccgo_up(pbEof)) = libc.BoolInt32((**(**TPmaReader)(__ccgo_up((*TMergeEngine)(unsafe.Pointer(pMerger)).FaReadr + uintptr(**(**int32)(__ccgo_up((*TMergeEngine)(unsafe.Pointer(pMerger)).FaTree + 1*4)))*52))).FpFd == uintptr(0))
	}
	if rc == SQLITE_OK {
		v2 = libc.Int32FromUint8((*TUnpackedRecord)(unsafe.Pointer((*TSortSubtask)(unsafe.Pointer(pTask)).FpUnpacked)).FerrCode)
	} else {
		v2 = rc
	}
	return v2
}

// C documentation
//
//	/*
//	** Free all memory belonging to the PmaReader object passed as the
//	** argument. All structure fields are set to zero before returning.
//	*/
func _vdbePmaReaderClear(tls *libc.TLS, pReadr uintptr) {
	Xsqlite3_free(tls, (*TPmaReader)(unsafe.Pointer(pReadr)).FaAlloc)
	Xsqlite3_free(tls, (*TPmaReader)(unsafe.Pointer(pReadr)).FaBuffer)
	if (*TPmaReader)(unsafe.Pointer(pReadr)).FaMap != 0 {
		_sqlite3OsUnfetch(tls, (*TPmaReader)(unsafe.Pointer(pReadr)).FpFd, 0, (*TPmaReader)(unsafe.Pointer(pReadr)).FaMap)
	}
	_vdbeIncrFree(tls, (*TPmaReader)(unsafe.Pointer(pReadr)).FpIncr)
	libc.Xmemset(tls, pReadr, 0, uint32(52))
}

// C documentation
//
//	/*
//	** The PmaReader passed as the first argument is guaranteed to be an
//	** incremental-reader (pReadr->pIncr!=0). This function serves to open
//	** and/or initialize the temp file related fields of the IncrMerge
//	** object at (pReadr->pIncr).
//	**
//	** If argument eMode is set to INCRINIT_NORMAL, then all PmaReaders
//	** in the sub-tree headed by pReadr are also initialized. Data is then
//	** loaded into the buffers belonging to pReadr and it is set to point to
//	** the first key in its range.
//	**
//	** If argument eMode is set to INCRINIT_TASK, then pReadr is guaranteed
//	** to be a multi-threaded PmaReader and this function is being called in a
//	** background thread. In this case all PmaReaders in the sub-tree are
//	** initialized as for INCRINIT_NORMAL and the aFile[1] buffer belonging to
//	** pReadr is populated. However, pReadr itself is not set up to point
//	** to its first key. A call to vdbePmaReaderNext() is still required to do
//	** that.
//	**
//	** The reason this function does not call vdbePmaReaderNext() immediately
//	** in the INCRINIT_TASK case is that vdbePmaReaderNext() assumes that it has
//	** to block on thread (pTask->thread) before accessing aFile[1]. But, since
//	** this entire function is being run by thread (pTask->thread), that will
//	** lead to the current background thread attempting to join itself.
//	**
//	** Finally, if argument eMode is set to INCRINIT_ROOT, it may be assumed
//	** that pReadr->pIncr is a multi-threaded IncrMerge objects, and that all
//	** child-trees have already been initialized using IncrInit(INCRINIT_TASK).
//	** In this case vdbePmaReaderNext() is called on all child PmaReaders and
//	** the current PmaReader set to point to the first key in its range.
//	**
//	** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
//	*/
func _vdbePmaReaderIncrMergeInit(tls *libc.TLS, pReadr uintptr, eMode int32) (r int32) {
	var db, pIncr, pTask uintptr
	var mxSz, rc int32
	_, _, _, _, _ = db, mxSz, pIncr, pTask, rc
	rc = SQLITE_OK
	pIncr = (*TPmaReader)(unsafe.Pointer(pReadr)).FpIncr
	pTask = (*TIncrMerger)(unsafe.Pointer(pIncr)).FpTask
	db = (*TVdbeSorter)(unsafe.Pointer((*TSortSubtask)(unsafe.Pointer(pTask)).FpSorter)).Fdb
	/* eMode is always INCRINIT_NORMAL in single-threaded mode */
	rc = _vdbeMergeEngineInit(tls, pTask, (*TIncrMerger)(unsafe.Pointer(pIncr)).FpMerger, eMode)
	/* Set up the required files for pIncr. A multi-threaded IncrMerge object
	 ** requires two temp files to itself, whereas a single-threaded object
	 ** only requires a region of pTask->file2. */
	if rc == SQLITE_OK {
		mxSz = (*TIncrMerger)(unsafe.Pointer(pIncr)).FmxSz
		if (*TIncrMerger)(unsafe.Pointer(pIncr)).FbUseThread != 0 {
			rc = _vdbeSorterOpenTempFile(tls, db, int64(mxSz), pIncr+28)
			if rc == SQLITE_OK {
				rc = _vdbeSorterOpenTempFile(tls, db, int64(mxSz), pIncr+28+1*12)
			}
		} else {
			/*if( !pIncr->bUseThread )*/
			if (*TSortSubtask)(unsafe.Pointer(pTask)).Ffile2.FpFd == uintptr(0) {
				rc = _vdbeSorterOpenTempFile(tls, db, (*TSortSubtask)(unsafe.Pointer(pTask)).Ffile2.FiEof, pTask+52)
				(*TSortSubtask)(unsafe.Pointer(pTask)).Ffile2.FiEof = 0
			}
			if rc == SQLITE_OK {
				(**(**TSorterFile)(__ccgo_up(pIncr + 28 + 1*12))).FpFd = (*TSortSubtask)(unsafe.Pointer(pTask)).Ffile2.FpFd
				(*TIncrMerger)(unsafe.Pointer(pIncr)).FiStartOff = (*TSortSubtask)(unsafe.Pointer(pTask)).Ffile2.FiEof
				(*TSortSubtask)(unsafe.Pointer(pTask)).Ffile2.FiEof += int64(mxSz)
			}
		}
	}
	if rc == SQLITE_OK && (*TIncrMerger)(unsafe.Pointer(pIncr)).FbUseThread != 0 {
		/* Use the current thread to populate aFile[1], even though this
		 ** PmaReader is multi-threaded. If this is an INCRINIT_TASK object,
		 ** then this function is already running in background thread
		 ** pIncr->pTask->thread.
		 **
		 ** If this is the INCRINIT_ROOT object, then it is running in the
		 ** main VDBE thread. But that is Ok, as that thread cannot return
		 ** control to the VDBE or proceed with anything useful until the
		 ** first results are ready from this merger object anyway.
		 */
		rc = _vdbeIncrPopulate(tls, pIncr)
	}
	if rc == SQLITE_OK && (libc.Bool(false) || eMode != int32(INCRINIT_TASK)) {
		rc = _vdbePmaReaderNext(tls, pReadr)
	}
	return rc
}

// C documentation
//
//	/*
//	** Advance PmaReader pReadr to the next key in its PMA. Return SQLITE_OK if
//	** no error occurs, or an SQLite error code if one does.
//	*/
func _vdbePmaReaderNext(tls *libc.TLS, pReadr uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var bEof, rc int32
	var pIncr uintptr
	var _ /* nRec at bp+0 */ Tu64
	_, _, _ = bEof, pIncr, rc
	rc = SQLITE_OK                        /* Return Code */
	**(**Tu64)(__ccgo_up(bp)) = uint64(0) /* Size of record in bytes */
	if (*TPmaReader)(unsafe.Pointer(pReadr)).FiReadOff >= (*TPmaReader)(unsafe.Pointer(pReadr)).FiEof {
		pIncr = (*TPmaReader)(unsafe.Pointer(pReadr)).FpIncr
		bEof = int32(1)
		if pIncr != 0 {
			rc = _vdbeIncrSwap(tls, pIncr)
			if rc == SQLITE_OK && (*TIncrMerger)(unsafe.Pointer(pIncr)).FbEof == 0 {
				rc = _vdbePmaReaderSeek(tls, (*TIncrMerger)(unsafe.Pointer(pIncr)).FpTask, pReadr, pIncr+28, (*TIncrMerger)(unsafe.Pointer(pIncr)).FiStartOff)
				bEof = 0
			}
		}
		if bEof != 0 {
			/* This is an EOF condition */
			_vdbePmaReaderClear(tls, pReadr)
			return rc
		}
	}
	if rc == SQLITE_OK {
		rc = _vdbePmaReadVarint(tls, pReadr, bp)
	}
	if rc == SQLITE_OK {
		(*TPmaReader)(unsafe.Pointer(pReadr)).FnKey = libc.Int32FromUint64(**(**Tu64)(__ccgo_up(bp)))
		rc = _vdbePmaReadBlob(tls, pReadr, libc.Int32FromUint64(**(**Tu64)(__ccgo_up(bp))), pReadr+32)
	}
	return rc
}

// C documentation
//
//	/*
//	** Write nData bytes of data to the PMA. Return SQLITE_OK
//	** if successful, or an SQLite error code if an error occurs.
//	*/
func _vdbePmaWriteBlob(tls *libc.TLS, p uintptr, pData uintptr, nData int32) {
	var nCopy, nRem, v1 int32
	_, _, _ = nCopy, nRem, v1
	nRem = nData
	for nRem > 0 && (*TPmaWriter)(unsafe.Pointer(p)).FeFWErr == 0 {
		nCopy = nRem
		if nCopy > (*TPmaWriter)(unsafe.Pointer(p)).FnBuffer-(*TPmaWriter)(unsafe.Pointer(p)).FiBufEnd {
			nCopy = (*TPmaWriter)(unsafe.Pointer(p)).FnBuffer - (*TPmaWriter)(unsafe.Pointer(p)).FiBufEnd
		}
		libc.Xmemcpy(tls, (*TPmaWriter)(unsafe.Pointer(p)).FaBuffer+uintptr((*TPmaWriter)(unsafe.Pointer(p)).FiBufEnd), pData+uintptr(nData-nRem), libc.Uint32FromInt32(nCopy))
		**(**int32)(__ccgo_up(p + 16)) += nCopy
		if (*TPmaWriter)(unsafe.Pointer(p)).FiBufEnd == (*TPmaWriter)(unsafe.Pointer(p)).FnBuffer {
			(*TPmaWriter)(unsafe.Pointer(p)).FeFWErr = _sqlite3OsWrite(tls, (*TPmaWriter)(unsafe.Pointer(p)).FpFd, (*TPmaWriter)(unsafe.Pointer(p)).FaBuffer+uintptr((*TPmaWriter)(unsafe.Pointer(p)).FiBufStart), (*TPmaWriter)(unsafe.Pointer(p)).FiBufEnd-(*TPmaWriter)(unsafe.Pointer(p)).FiBufStart, (*TPmaWriter)(unsafe.Pointer(p)).FiWriteOff+int64((*TPmaWriter)(unsafe.Pointer(p)).FiBufStart))
			**(**Tu64)(__ccgo_up(p + 32)) += libc.Uint64FromInt32((*TPmaWriter)(unsafe.Pointer(p)).FiBufEnd - (*TPmaWriter)(unsafe.Pointer(p)).FiBufStart)
			v1 = libc.Int32FromInt32(0)
			(*TPmaWriter)(unsafe.Pointer(p)).FiBufEnd = v1
			(*TPmaWriter)(unsafe.Pointer(p)).FiBufStart = v1
			**(**Ti64)(__ccgo_up(p + 20)) += int64((*TPmaWriter)(unsafe.Pointer(p)).FnBuffer)
		}
		nRem = nRem - nCopy
	}
}

// C documentation
//
//	/*
//	** Flush any buffered data to disk and clean up the PMA-writer object.
//	** The results of using the PMA-writer after this call are undefined.
//	** Return SQLITE_OK if flushing the buffered data succeeds or is not
//	** required. Otherwise, return an SQLite error code.
//	**
//	** Before returning, set *piEof to the offset immediately following the
//	** last byte written to the file. Also, increment (*pnSpill) by the total
//	** number of bytes written to the file.
//	*/
func _vdbePmaWriterFinish(tls *libc.TLS, p uintptr, piEof uintptr, pnSpill uintptr) (r int32) {
	var rc int32
	_ = rc
	if (*TPmaWriter)(unsafe.Pointer(p)).FeFWErr == 0 && (*TPmaWriter)(unsafe.Pointer(p)).FaBuffer != 0 && (*TPmaWriter)(unsafe.Pointer(p)).FiBufEnd > (*TPmaWriter)(unsafe.Pointer(p)).FiBufStart {
		(*TPmaWriter)(unsafe.Pointer(p)).FeFWErr = _sqlite3OsWrite(tls, (*TPmaWriter)(unsafe.Pointer(p)).FpFd, (*TPmaWriter)(unsafe.Pointer(p)).FaBuffer+uintptr((*TPmaWriter)(unsafe.Pointer(p)).FiBufStart), (*TPmaWriter)(unsafe.Pointer(p)).FiBufEnd-(*TPmaWriter)(unsafe.Pointer(p)).FiBufStart, (*TPmaWriter)(unsafe.Pointer(p)).FiWriteOff+int64((*TPmaWriter)(unsafe.Pointer(p)).FiBufStart))
		**(**Tu64)(__ccgo_up(p + 32)) += libc.Uint64FromInt32((*TPmaWriter)(unsafe.Pointer(p)).FiBufEnd - (*TPmaWriter)(unsafe.Pointer(p)).FiBufStart)
	}
	**(**Ti64)(__ccgo_up(piEof)) = (*TPmaWriter)(unsafe.Pointer(p)).FiWriteOff + int64((*TPmaWriter)(unsafe.Pointer(p)).FiBufEnd)
	**(**Tu64)(__ccgo_up(pnSpill)) += (*TPmaWriter)(unsafe.Pointer(p)).FnPmaSpill
	Xsqlite3_free(tls, (*TPmaWriter)(unsafe.Pointer(p)).FaBuffer)
	rc = (*TPmaWriter)(unsafe.Pointer(p)).FeFWErr
	libc.Xmemset(tls, p, 0, uint32(40))
	return rc
}

// C documentation
//
//	/*
//	** Initialize a PMA-writer object.
//	*/
func _vdbePmaWriterInit(tls *libc.TLS, pFd uintptr, p uintptr, nBuf int32, iStart Ti64) {
	var v1 int32
	_ = v1
	libc.Xmemset(tls, p, 0, uint32(40))
	(*TPmaWriter)(unsafe.Pointer(p)).FaBuffer = _sqlite3Malloc(tls, libc.Uint64FromInt32(nBuf))
	if !((*TPmaWriter)(unsafe.Pointer(p)).FaBuffer != 0) {
		(*TPmaWriter)(unsafe.Pointer(p)).FeFWErr = int32(SQLITE_NOMEM)
	} else {
		v1 = int32(iStart % int64(nBuf))
		(*TPmaWriter)(unsafe.Pointer(p)).FiBufStart = v1
		(*TPmaWriter)(unsafe.Pointer(p)).FiBufEnd = v1
		(*TPmaWriter)(unsafe.Pointer(p)).FiWriteOff = iStart - int64((*TPmaWriter)(unsafe.Pointer(p)).FiBufStart)
		(*TPmaWriter)(unsafe.Pointer(p)).FnBuffer = nBuf
		(*TPmaWriter)(unsafe.Pointer(p)).FpFd = pFd
	}
}

// C documentation
//
//	/*
//	** Free all resources owned by the object indicated by argument pTask. All
//	** fields of *pTask are zeroed before returning.
//	*/
func _vdbeSortSubtaskCleanup(tls *libc.TLS, db uintptr, pTask uintptr) {
	_sqlite3DbFree(tls, db, (*TSortSubtask)(unsafe.Pointer(pTask)).FpUnpacked)
	/* pTask->list.aMemory can only be non-zero if it was handed memory
	 ** from the main thread.  That only occurs SQLITE_MAX_WORKER_THREADS>0 */
	if (*TSortSubtask)(unsafe.Pointer(pTask)).Flist.FaMemory != 0 {
		Xsqlite3_free(tls, (*TSortSubtask)(unsafe.Pointer(pTask)).Flist.FaMemory)
	} else {
		_vdbeSorterRecordFree(tls, uintptr(0), (*TSortSubtask)(unsafe.Pointer(pTask)).Flist.FpList)
	}
	if (*TSortSubtask)(unsafe.Pointer(pTask)).Ffile.FpFd != 0 {
		_sqlite3OsCloseFree(tls, (*TSortSubtask)(unsafe.Pointer(pTask)).Ffile.FpFd)
	}
	if (*TSortSubtask)(unsafe.Pointer(pTask)).Ffile2.FpFd != 0 {
		_sqlite3OsCloseFree(tls, (*TSortSubtask)(unsafe.Pointer(pTask)).Ffile2.FpFd)
	}
	libc.Xmemset(tls, pTask, 0, uint32(72))
}

// C documentation
//
//	/*
//	** pRoot is the root of an incremental merge-tree with depth nDepth (according
//	** to vdbeSorterTreeDepth()). pLeaf is the iSeq'th leaf to be added to the
//	** tree, counting from zero. This function adds pLeaf to the tree.
//	**
//	** If successful, SQLITE_OK is returned. If an error occurs, an SQLite error
//	** code is returned and pLeaf is freed.
//	*/
func _vdbeSorterAddToTree(tls *libc.TLS, pTask uintptr, nDepth int32, iSeq int32, pRoot uintptr, pLeaf uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var i, iIter, nDiv, rc int32
	var p, pNew, pReadr uintptr
	var _ /* pIncr at bp+0 */ uintptr
	_, _, _, _, _, _, _ = i, iIter, nDiv, p, pNew, pReadr, rc
	rc = SQLITE_OK
	nDiv = int32(1)
	p = pRoot
	rc = _vdbeIncrMergerNew(tls, pTask, pLeaf, bp)
	i = int32(1)
	for {
		if !(i < nDepth) {
			break
		}
		nDiv = nDiv * int32(SORTER_MAX_MERGE_COUNT)
		goto _1
	_1:
		;
		i = i + 1
	}
	i = int32(1)
	for {
		if !(i < nDepth && rc == SQLITE_OK) {
			break
		}
		iIter = iSeq / nDiv % int32(SORTER_MAX_MERGE_COUNT)
		pReadr = (*TMergeEngine)(unsafe.Pointer(p)).FaReadr + uintptr(iIter)*52
		if (*TPmaReader)(unsafe.Pointer(pReadr)).FpIncr == uintptr(0) {
			pNew = _vdbeMergeEngineNew(tls, int32(SORTER_MAX_MERGE_COUNT))
			if pNew == uintptr(0) {
				rc = int32(SQLITE_NOMEM)
			} else {
				rc = _vdbeIncrMergerNew(tls, pTask, pNew, pReadr+48)
			}
		}
		if rc == SQLITE_OK {
			p = (*TIncrMerger)(unsafe.Pointer((*TPmaReader)(unsafe.Pointer(pReadr)).FpIncr)).FpMerger
			nDiv = nDiv / int32(SORTER_MAX_MERGE_COUNT)
		}
		goto _2
	_2:
		;
		i = i + 1
	}
	if rc == SQLITE_OK {
		(**(**TPmaReader)(__ccgo_up((*TMergeEngine)(unsafe.Pointer(p)).FaReadr + uintptr(iSeq%int32(SORTER_MAX_MERGE_COUNT))*52))).FpIncr = **(**uintptr)(__ccgo_up(bp))
	} else {
		_vdbeIncrFree(tls, **(**uintptr)(__ccgo_up(bp)))
	}
	return rc
}

// C documentation
//
//	/*
//	** Flush the current contents of VdbeSorter.list to a new PMA, possibly
//	** using a background thread.
//	*/
func _vdbeSorterFlushPMA(tls *libc.TLS, pSorter uintptr) (r int32) {
	var aMem, pCtx, pTask uintptr
	var i, iTest, nWorker, rc int32
	_, _, _, _, _, _, _ = aMem, i, iTest, nWorker, pCtx, pTask, rc
	rc = SQLITE_OK
	pTask = uintptr(0) /* Thread context used to create new PMA */
	nWorker = libc.Int32FromUint8((*TVdbeSorter)(unsafe.Pointer(pSorter)).FnTask) - int32(1)
	/* Set the flag to indicate that at least one PMA has been written.
	 ** Or will be, anyhow.  */
	(*TVdbeSorter)(unsafe.Pointer(pSorter)).FbUsePMA = uint8(1)
	/* Select a sub-task to sort and flush the current list of in-memory
	 ** records to disk. If the sorter is running in multi-threaded mode,
	 ** round-robin between the first (pSorter->nTask-1) tasks. Except, if
	 ** the background thread from a sub-tasks previous turn is still running,
	 ** skip it. If the first (pSorter->nTask-1) sub-tasks are all still busy,
	 ** fall back to using the final sub-task. The first (pSorter->nTask-1)
	 ** sub-tasks are preferred as they use background threads - the final
	 ** sub-task uses the main thread. */
	i = 0
	for {
		if !(i < nWorker) {
			break
		}
		iTest = (libc.Int32FromUint8((*TVdbeSorter)(unsafe.Pointer(pSorter)).FiPrev) + i + int32(1)) % nWorker
		pTask = pSorter + 68 + uintptr(iTest)*72
		if (*TSortSubtask)(unsafe.Pointer(pTask)).FbDone != 0 {
			rc = _vdbeSorterJoinThread(tls, pTask)
		}
		if rc != SQLITE_OK || (*TSortSubtask)(unsafe.Pointer(pTask)).FpThread == uintptr(0) {
			break
		}
		goto _1
	_1:
		;
		i = i + 1
	}
	if rc == SQLITE_OK {
		if i == nWorker {
			/* Use the foreground thread for this operation */
			rc = _vdbeSorterListToPMA(tls, pSorter+68+uintptr(nWorker)*72, pSorter+36)
		} else {
			aMem = (*TSortSubtask)(unsafe.Pointer(pTask)).Flist.FaMemory
			pCtx = pTask
			(*TVdbeSorter)(unsafe.Pointer(pSorter)).FiPrev = libc.Uint8FromInt32((int32(pTask) - t__predefined_ptrdiff_t(pSorter+68)) / 72)
			(*TSortSubtask)(unsafe.Pointer(pTask)).Flist = (*TVdbeSorter)(unsafe.Pointer(pSorter)).Flist
			(*TVdbeSorter)(unsafe.Pointer(pSorter)).Flist.FpList = uintptr(0)
			(*TVdbeSorter)(unsafe.Pointer(pSorter)).Flist.FszPMA = 0
			if aMem != 0 {
				(*TVdbeSorter)(unsafe.Pointer(pSorter)).Flist.FaMemory = aMem
				(*TVdbeSorter)(unsafe.Pointer(pSorter)).FnMemory = _sqlite3MallocSize(tls, aMem)
			} else {
				if (*TVdbeSorter)(unsafe.Pointer(pSorter)).Flist.FaMemory != 0 {
					(*TVdbeSorter)(unsafe.Pointer(pSorter)).Flist.FaMemory = _sqlite3Malloc(tls, libc.Uint64FromInt32((*TVdbeSorter)(unsafe.Pointer(pSorter)).FnMemory))
					if !((*TVdbeSorter)(unsafe.Pointer(pSorter)).Flist.FaMemory != 0) {
						return int32(SQLITE_NOMEM)
					}
				}
			}
			rc = _vdbeSorterCreateThread(tls, pTask, __ccgo_fp(_vdbeSorterFlushThread), pCtx)
		}
	}
	return rc
}

// C documentation
//
//	/*
//	** The main routine for background threads that write level-0 PMAs.
//	*/
func _vdbeSorterFlushThread(tls *libc.TLS, pCtx uintptr) (r uintptr) {
	var pTask uintptr
	var rc int32
	_, _ = pTask, rc
	pTask = pCtx /* Return code */
	rc = _vdbeSorterListToPMA(tls, pTask, pTask+20)
	(*TSortSubtask)(unsafe.Pointer(pTask)).FbDone = int32(1)
	return uintptr(rc)
}

// C documentation
//
//	/*
//	** Join all outstanding threads launched by SorterWrite() to create
//	** level-0 PMAs.
//	*/
func _vdbeSorterJoinAll(tls *libc.TLS, pSorter uintptr, rcin int32) (r int32) {
	var i, rc, rc2 int32
	var pTask uintptr
	_, _, _, _ = i, pTask, rc, rc2
	rc = rcin
	/* This function is always called by the main user thread.
	 **
	 ** If this function is being called after SorterRewind() has been called,
	 ** it is possible that thread pSorter->aTask[pSorter->nTask-1].pThread
	 ** is currently attempt to join one of the other threads. To avoid a race
	 ** condition where this thread also attempts to join the same object, join
	 ** thread pSorter->aTask[pSorter->nTask-1].pThread first. */
	i = libc.Int32FromUint8((*TVdbeSorter)(unsafe.Pointer(pSorter)).FnTask) - int32(1)
	for {
		if !(i >= 0) {
			break
		}
		pTask = pSorter + 68 + uintptr(i)*72
		rc2 = _vdbeSorterJoinThread(tls, pTask)
		if rc == SQLITE_OK {
			rc = rc2
		}
		goto _1
	_1:
		;
		i = i - 1
	}
	return rc
}

// C documentation
//
//	/*
//	** Write the current contents of in-memory linked-list pList to a level-0
//	** PMA in the temp file belonging to sub-task pTask. Return SQLITE_OK if
//	** successful, or an SQLite error code otherwise.
//	**
//	** The format of a PMA is:
//	**
//	**     * A varint. This varint contains the total number of bytes of content
//	**       in the PMA (not including the varint itself).
//	**
//	**     * One or more records packed end-to-end in order of ascending keys.
//	**       Each record consists of a varint followed by a blob of data (the
//	**       key). The varint is the number of bytes in the blob of data.
//	*/
func _vdbeSorterListToPMA(tls *libc.TLS, pTask uintptr, pList uintptr) (r int32) {
	bp := tls.Alloc(48)
	defer tls.Free(48)
	var db, p, pNext uintptr
	var rc int32
	var _ /* writer at bp+0 */ TPmaWriter
	_, _, _, _ = db, p, pNext, rc
	db = (*TVdbeSorter)(unsafe.Pointer((*TSortSubtask)(unsafe.Pointer(pTask)).FpSorter)).Fdb
	rc = SQLITE_OK /* Object used to write to the file */
	libc.Xmemset(tls, bp, 0, uint32(40))
	/* If the first temporary PMA file has not been opened, open it now. */
	if (*TSortSubtask)(unsafe.Pointer(pTask)).Ffile.FpFd == uintptr(0) {
		rc = _vdbeSorterOpenTempFile(tls, db, 0, pTask+40)
	}
	/* Try to get the file to memory map */
	if rc == SQLITE_OK {
		_vdbeSorterExtendFile(tls, db, (*TSortSubtask)(unsafe.Pointer(pTask)).Ffile.FpFd, (*TSortSubtask)(unsafe.Pointer(pTask)).Ffile.FiEof+(*TSorterList)(unsafe.Pointer(pList)).FszPMA+int64(9))
	}
	/* Sort the list */
	if rc == SQLITE_OK {
		rc = _vdbeSorterSort(tls, pTask, pList)
	}
	if rc == SQLITE_OK {
		pNext = uintptr(0)
		_vdbePmaWriterInit(tls, (*TSortSubtask)(unsafe.Pointer(pTask)).Ffile.FpFd, bp, (*TVdbeSorter)(unsafe.Pointer((*TSortSubtask)(unsafe.Pointer(pTask)).FpSorter)).Fpgsz, (*TSortSubtask)(unsafe.Pointer(pTask)).Ffile.FiEof)
		(*TSortSubtask)(unsafe.Pointer(pTask)).FnPMA = (*TSortSubtask)(unsafe.Pointer(pTask)).FnPMA + 1
		_vdbePmaWriteVarint(tls, bp, libc.Uint64FromInt64((*TSorterList)(unsafe.Pointer(pList)).FszPMA))
		p = (*TSorterList)(unsafe.Pointer(pList)).FpList
		for {
			if !(p != 0) {
				break
			}
			pNext = *(*uintptr)(unsafe.Pointer(p + 4))
			_vdbePmaWriteVarint(tls, bp, libc.Uint64FromInt32((*TSorterRecord)(unsafe.Pointer(p)).FnVal))
			_vdbePmaWriteBlob(tls, bp, p+libc.UintptrFromInt32(1)*8, (*TSorterRecord)(unsafe.Pointer(p)).FnVal)
			if (*TSorterList)(unsafe.Pointer(pList)).FaMemory == uintptr(0) {
				Xsqlite3_free(tls, p)
			}
			goto _1
		_1:
			;
			p = pNext
		}
		(*TSorterList)(unsafe.Pointer(pList)).FpList = p
		rc = _vdbePmaWriterFinish(tls, bp, pTask+40+4, pTask+64)
	}
	return rc
}

// C documentation
//
//	/*
//	** This function is called as part of a SorterRewind() operation on a sorter
//	** that has already written two or more level-0 PMAs to one or more temp
//	** files. It builds a tree of MergeEngine/IncrMerger/PmaReader objects that
//	** can be used to incrementally merge all PMAs on disk.
//	**
//	** If successful, SQLITE_OK is returned and *ppOut set to point to the
//	** MergeEngine object at the root of the tree before returning. Or, if an
//	** error occurs, an SQLite error code is returned and the final value
//	** of *ppOut is undefined.
//	*/
func _vdbeSorterMergeTreeBuild(tls *libc.TLS, pSorter uintptr, ppOut uintptr) (r int32) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var i, iSeq, iTask, nDepth, nReader, rc, v3 int32
	var pMain, pTask uintptr
	var _ /* iReadOff at bp+8 */ Ti64
	var _ /* pMerger at bp+16 */ uintptr
	var _ /* pRoot at bp+0 */ uintptr
	_, _, _, _, _, _, _, _, _ = i, iSeq, iTask, nDepth, nReader, pMain, pTask, rc, v3
	pMain = uintptr(0)
	rc = SQLITE_OK
	/* If the sorter uses more than one task, then create the top-level
	 ** MergeEngine here. This MergeEngine will read data from exactly
	 ** one PmaReader per sub-task.  */
	if libc.Int32FromUint8((*TVdbeSorter)(unsafe.Pointer(pSorter)).FnTask) > int32(1) {
		pMain = _vdbeMergeEngineNew(tls, libc.Int32FromUint8((*TVdbeSorter)(unsafe.Pointer(pSorter)).FnTask))
		if pMain == uintptr(0) {
			rc = int32(SQLITE_NOMEM)
		}
	}
	iTask = 0
	for {
		if !(rc == SQLITE_OK && iTask < libc.Int32FromUint8((*TVdbeSorter)(unsafe.Pointer(pSorter)).FnTask)) {
			break
		}
		pTask = pSorter + 68 + uintptr(iTask)*72
		if libc.Bool(false) || (*TSortSubtask)(unsafe.Pointer(pTask)).FnPMA != 0 {
			**(**uintptr)(__ccgo_up(bp)) = uintptr(0) /* Root node of tree for this task */
			nDepth = _vdbeSorterTreeDepth(tls, (*TSortSubtask)(unsafe.Pointer(pTask)).FnPMA)
			**(**Ti64)(__ccgo_up(bp + 8)) = 0
			if (*TSortSubtask)(unsafe.Pointer(pTask)).FnPMA <= int32(SORTER_MAX_MERGE_COUNT) {
				rc = _vdbeMergeEngineLevel0(tls, pTask, (*TSortSubtask)(unsafe.Pointer(pTask)).FnPMA, bp+8, bp)
			} else {
				iSeq = 0
				**(**uintptr)(__ccgo_up(bp)) = _vdbeMergeEngineNew(tls, int32(SORTER_MAX_MERGE_COUNT))
				if **(**uintptr)(__ccgo_up(bp)) == uintptr(0) {
					rc = int32(SQLITE_NOMEM)
				}
				i = 0
				for {
					if !(i < (*TSortSubtask)(unsafe.Pointer(pTask)).FnPMA && rc == SQLITE_OK) {
						break
					}
					**(**uintptr)(__ccgo_up(bp + 16)) = uintptr(0) /* Number of level-0 PMAs to merge */
					if (*TSortSubtask)(unsafe.Pointer(pTask)).FnPMA-i < int32(SORTER_MAX_MERGE_COUNT) {
						v3 = (*TSortSubtask)(unsafe.Pointer(pTask)).FnPMA - i
					} else {
						v3 = int32(SORTER_MAX_MERGE_COUNT)
					}
					nReader = v3
					rc = _vdbeMergeEngineLevel0(tls, pTask, nReader, bp+8, bp+16)
					if rc == SQLITE_OK {
						v3 = iSeq
						iSeq = iSeq + 1
						rc = _vdbeSorterAddToTree(tls, pTask, nDepth, v3, **(**uintptr)(__ccgo_up(bp)), **(**uintptr)(__ccgo_up(bp + 16)))
					}
					goto _2
				_2:
					;
					i = i + int32(SORTER_MAX_MERGE_COUNT)
				}
			}
			if rc == SQLITE_OK {
				if pMain != uintptr(0) {
					rc = _vdbeIncrMergerNew(tls, pTask, **(**uintptr)(__ccgo_up(bp)), (*TMergeEngine)(unsafe.Pointer(pMain)).FaReadr+uintptr(iTask)*52+48)
				} else {
					pMain = **(**uintptr)(__ccgo_up(bp))
				}
			} else {
				_vdbeMergeEngineFree(tls, **(**uintptr)(__ccgo_up(bp)))
			}
		}
		goto _1
	_1:
		;
		iTask = iTask + 1
	}
	if rc != SQLITE_OK {
		_vdbeMergeEngineFree(tls, pMain)
		pMain = uintptr(0)
	}
	**(**uintptr)(__ccgo_up(ppOut)) = pMain
	return rc
}

// C documentation
//
//	/*
//	** Return a pointer to a buffer owned by the sorter that contains the
//	** current key.
//	*/
func _vdbeSorterRowkey(tls *libc.TLS, pSorter uintptr, pnKey uintptr) (r uintptr) {
	var pKey, pReader uintptr
	_, _ = pKey, pReader
	if (*TVdbeSorter)(unsafe.Pointer(pSorter)).FbUsePMA != 0 {
		if (*TVdbeSorter)(unsafe.Pointer(pSorter)).FbUseThreads != 0 {
			pReader = (*TVdbeSorter)(unsafe.Pointer(pSorter)).FpReader
		} else {
			/*if( !pSorter->bUseThreads )*/
			pReader = (*TMergeEngine)(unsafe.Pointer((*TVdbeSorter)(unsafe.Pointer(pSorter)).FpMerger)).FaReadr + uintptr(**(**int32)(__ccgo_up((*TMergeEngine)(unsafe.Pointer((*TVdbeSorter)(unsafe.Pointer(pSorter)).FpMerger)).FaTree + 1*4)))*52
		}
		**(**int32)(__ccgo_up(pnKey)) = (*TPmaReader)(unsafe.Pointer(pReader)).FnKey
		pKey = (*TPmaReader)(unsafe.Pointer(pReader)).FaKey
	} else {
		**(**int32)(__ccgo_up(pnKey)) = (*TSorterRecord)(unsafe.Pointer((*TVdbeSorter)(unsafe.Pointer(pSorter)).Flist.FpList)).FnVal
		pKey = (*TVdbeSorter)(unsafe.Pointer(pSorter)).Flist.FpList + libc.UintptrFromInt32(1)*8
	}
	return pKey
}

// C documentation
//
//	/*
//	** This function is called as part of an sqlite3VdbeSorterRewind() operation
//	** on a sorter that has written two or more PMAs to temporary files. It sets
//	** up either VdbeSorter.pMerger (for single threaded sorters) or pReader
//	** (for multi-threaded sorters) so that it can be used to iterate through
//	** all records stored in the sorter.
//	**
//	** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
//	*/
func _vdbeSorterSetupMerge(tls *libc.TLS, pSorter uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var db, p, pIncr, pLast, pReadr, pTask0, v3 uintptr
	var i, iTask, rc int32
	var xCompare TSorterCompare
	var _ /* pMain at bp+0 */ uintptr
	_, _, _, _, _, _, _, _, _, _, _ = db, i, iTask, p, pIncr, pLast, pReadr, pTask0, rc, xCompare, v3 /* Return code */
	pTask0 = pSorter + 68
	**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
	db = (*TVdbeSorter)(unsafe.Pointer((*TSortSubtask)(unsafe.Pointer(pTask0)).FpSorter)).Fdb
	xCompare = _vdbeSorterGetCompare(tls, pSorter)
	i = 0
	for {
		if !(i < libc.Int32FromUint8((*TVdbeSorter)(unsafe.Pointer(pSorter)).FnTask)) {
			break
		}
		(*(*TSortSubtask)(unsafe.Pointer(pSorter + 68 + uintptr(i)*72))).FxCompare = xCompare
		goto _1
	_1:
		;
		i = i + 1
	}
	rc = _vdbeSorterMergeTreeBuild(tls, pSorter, bp)
	if rc == SQLITE_OK {
		if (*TVdbeSorter)(unsafe.Pointer(pSorter)).FbUseThreads != 0 {
			pReadr = uintptr(0)
			pLast = pSorter + 68 + uintptr(libc.Int32FromUint8((*TVdbeSorter)(unsafe.Pointer(pSorter)).FnTask)-int32(1))*72
			rc = _vdbeSortAllocUnpacked(tls, pLast)
			if rc == SQLITE_OK {
				pReadr = _sqlite3DbMallocZero(tls, db, uint64(52))
				(*TVdbeSorter)(unsafe.Pointer(pSorter)).FpReader = pReadr
				if pReadr == uintptr(0) {
					rc = int32(SQLITE_NOMEM)
				}
			}
			if rc == SQLITE_OK {
				rc = _vdbeIncrMergerNew(tls, pLast, **(**uintptr)(__ccgo_up(bp)), pReadr+48)
				if rc == SQLITE_OK {
					_vdbeIncrMergerSetThreads(tls, (*TPmaReader)(unsafe.Pointer(pReadr)).FpIncr)
					iTask = 0
					for {
						if !(iTask < libc.Int32FromUint8((*TVdbeSorter)(unsafe.Pointer(pSorter)).FnTask)-int32(1)) {
							break
						}
						v3 = (**(**TPmaReader)(__ccgo_up((*TMergeEngine)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FaReadr + uintptr(iTask)*52))).FpIncr
						pIncr = v3
						if v3 != 0 {
							_vdbeIncrMergerSetThreads(tls, pIncr)
						}
						goto _2
					_2:
						;
						iTask = iTask + 1
					}
					iTask = 0
					for {
						if !(rc == SQLITE_OK && iTask < libc.Int32FromUint8((*TVdbeSorter)(unsafe.Pointer(pSorter)).FnTask)) {
							break
						}
						/* Check that:
						 **
						 **   a) The incremental merge object is configured to use the
						 **      right task, and
						 **   b) If it is using task (nTask-1), it is configured to run
						 **      in single-threaded mode. This is important, as the
						 **      root merge (INCRINIT_ROOT) will be using the same task
						 **      object.
						 */
						p = (*TMergeEngine)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FaReadr + uintptr(iTask)*52
						rc = _vdbePmaReaderIncrInit(tls, p, int32(INCRINIT_TASK))
						goto _4
					_4:
						;
						iTask = iTask + 1
					}
				}
				**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
			}
			if rc == SQLITE_OK {
				rc = _vdbePmaReaderIncrMergeInit(tls, pReadr, int32(INCRINIT_ROOT))
			}
		} else {
			rc = _vdbeMergeEngineInit(tls, pTask0, **(**uintptr)(__ccgo_up(bp)), INCRINIT_NORMAL)
			(*TVdbeSorter)(unsafe.Pointer(pSorter)).FpMerger = **(**uintptr)(__ccgo_up(bp))
			**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
		}
	}
	if rc != SQLITE_OK {
		_vdbeMergeEngineFree(tls, **(**uintptr)(__ccgo_up(bp)))
	}
	return rc
}

// C documentation
//
//	/*
//	** Copy as much content as we can from the WAL back into the database file
//	** in response to an sqlite3_wal_checkpoint() request or the equivalent.
//	**
//	** The amount of information copies from WAL to database might be limited
//	** by active readers.  This routine will never overwrite a database page
//	** that a concurrent reader might be using.
//	**
//	** All I/O barrier operations (a.k.a fsyncs) occur in this routine when
//	** SQLite is in WAL-mode in synchronous=NORMAL.  That means that if
//	** checkpoints are always run by a background thread or background
//	** process, foreground threads will never block on a lengthy fsync call.
//	**
//	** Fsync is called on the WAL before writing content out of the WAL and
//	** into the database.  This ensures that if the new content is persistent
//	** in the WAL and can be recovered following a power-loss or hard reset.
//	**
//	** Fsync is also called on the database file if (and only if) the entire
//	** WAL content is copied into the database file.  This second fsync makes
//	** it safe to delete the WAL since the new content will persist in the
//	** database file.
//	**
//	** This routine uses and updates the nBackfill field of the wal-index header.
//	** This is the only routine that will increase the value of nBackfill.
//	** (A WAL reset or recovery will revert nBackfill to zero, but not increase
//	** its value.)
//	**
//	** The caller must be holding sufficient locks to ensure that no other
//	** checkpoint is running (in any other thread or process) at the same
//	** time.
//	*/
func _walCheckpoint(tls *libc.TLS, pWal uintptr, db uintptr, eMode int32, __ccgo_fp_xBusy uintptr, pBusyArg uintptr, sync_flags int32, zBuf uintptr) (r int32) {
	bp := tls.Alloc(48)
	defer tls.Free(48)
	var bChg, i, rc, szPage, v3 int32
	var iMark, mxPage, mxSafeFrame, nBackfill, y Tu32
	var iOffset, szDb Ti64
	var pInfo, pLive uintptr
	var v2 uint32
	var v4 bool
	var _ /* iDbpage at bp+4 */ Tu32
	var _ /* iFrame at bp+8 */ Tu32
	var _ /* nReq at bp+16 */ Ti64
	var _ /* nSize at bp+24 */ Ti64
	var _ /* pIter at bp+0 */ uintptr
	var _ /* salt1 at bp+32 */ Tu32
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = bChg, i, iMark, iOffset, mxPage, mxSafeFrame, nBackfill, pInfo, pLive, rc, szDb, szPage, y, v2, v3, v4
	rc = SQLITE_OK                            /* Database page-size */
	**(**uintptr)(__ccgo_up(bp)) = uintptr(0) /* Wal iterator context */
	**(**Tu32)(__ccgo_up(bp + 4)) = uint32(0) /* Next database page to write */
	**(**Tu32)(__ccgo_up(bp + 8)) = uint32(0) /* The checkpoint status information */
	szPage = _walPagesize(tls, pWal)
	pInfo = _walCkptInfo(tls, pWal)
	if (*TWalCkptInfo)(unsafe.Pointer(pInfo)).FnBackfill < (*TWal)(unsafe.Pointer(pWal)).Fhdr.FmxFrame {
		/* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked
		 ** in the SQLITE_CHECKPOINT_PASSIVE mode. */
		/* Compute in mxSafeFrame the index of the last frame of the WAL that is
		 ** safe to write into the database.  Frames beyond mxSafeFrame might
		 ** overwrite database pages that are in use by active readers and thus
		 ** cannot be backfilled from the WAL.
		 */
		mxSafeFrame = (*TWal)(unsafe.Pointer(pWal)).Fhdr.FmxFrame
		mxPage = (*TWal)(unsafe.Pointer(pWal)).Fhdr.FnPage
		i = int32(1)
		for {
			if !(i < libc.Int32FromInt32(SQLITE_SHM_NLOCK)-libc.Int32FromInt32(3)) {
				break
			}
			y = libc.AtomicLoadNUint32(pInfo+4+uintptr(i)*4, libc.Int32FromInt32(__ATOMIC_RELAXED))
			if mxSafeFrame > y {
				rc = _walBusyLock(tls, pWal, __ccgo_fp_xBusy, pBusyArg, int32(3)+i, int32(1))
				if rc == SQLITE_OK {
					if i == int32(1) {
						v2 = mxSafeFrame
					} else {
						v2 = uint32(READMARK_NOT_USED)
					}
					iMark = v2
					libc.AtomicStoreNUint32(pInfo+4+uintptr(i)*4, iMark, libc.Int32FromInt32(__ATOMIC_RELAXED))
					_walUnlockExclusive(tls, pWal, int32(3)+i, int32(1))
				} else {
					if rc == int32(SQLITE_BUSY) {
						mxSafeFrame = y
						__ccgo_fp_xBusy = uintptr(0)
					} else {
						goto walcheckpoint_out
					}
				}
			}
			goto _1
		_1:
			;
			i = i + 1
		}
		/* Allocate the iterator */
		if (*TWalCkptInfo)(unsafe.Pointer(pInfo)).FnBackfill < mxSafeFrame {
			rc = _walIteratorInit(tls, pWal, (*TWalCkptInfo)(unsafe.Pointer(pInfo)).FnBackfill, bp)
		}
		if v4 = **(**uintptr)(__ccgo_up(bp)) != 0; v4 {
			v3 = _walBusyLock(tls, pWal, __ccgo_fp_xBusy, pBusyArg, libc.Int32FromInt32(3)+libc.Int32FromInt32(0), int32(1))
			rc = v3
		}
		if v4 && v3 == SQLITE_OK {
			nBackfill = (*TWalCkptInfo)(unsafe.Pointer(pInfo)).FnBackfill
			pLive = _walIndexHdr(tls, pWal)
			/* Now that read-lock slot 0 is locked, check that the wal has not been
			 ** wrapped since the header was read for this checkpoint. If it was, then
			 ** there was no work to do anyway.  In this case the
			 ** (pInfo->nBackfill<pWal->hdr.mxFrame) test above only passed because
			 ** pInfo->nBackfill had already been set to 0 by the writer that wrapped
			 ** the wal file. It would also be dangerous to proceed, as there may be
			 ** fewer than pWal->hdr.mxFrame valid frames in the wal file.  */
			bChg = libc.Xmemcmp(tls, pLive+32, pWal+52+32, uint32(8))
			if 0 == bChg {
				(*TWalCkptInfo)(unsafe.Pointer(pInfo)).FnBackfillAttempted = mxSafeFrame
				/* Sync the WAL to disk */
				rc = _sqlite3OsSync(tls, (*TWal)(unsafe.Pointer(pWal)).FpWalFd, sync_flags>>int32(2)&int32(0x03))
				/* If the database may grow as a result of this checkpoint, hint
				 ** about the eventual size of the db file to the VFS layer.
				 */
				if rc == SQLITE_OK {
					**(**Ti64)(__ccgo_up(bp + 16)) = libc.Int64FromUint32(mxPage) * int64(szPage) /* Current size of database file */
					_sqlite3OsFileControl(tls, (*TWal)(unsafe.Pointer(pWal)).FpDbFd, int32(SQLITE_FCNTL_CKPT_START), uintptr(0))
					rc = _sqlite3OsFileSize(tls, (*TWal)(unsafe.Pointer(pWal)).FpDbFd, bp+24)
					if rc == SQLITE_OK && **(**Ti64)(__ccgo_up(bp + 24)) < **(**Ti64)(__ccgo_up(bp + 16)) {
						if **(**Ti64)(__ccgo_up(bp + 24))+int64(65536)+libc.Int64FromUint32((*TWal)(unsafe.Pointer(pWal)).Fhdr.FmxFrame)*int64(szPage) < **(**Ti64)(__ccgo_up(bp + 16)) {
							/* If the size of the final database is larger than the current
							 ** database plus the amount of data in the wal file, plus the
							 ** maximum size of the pending-byte page (65536 bytes), then
							 ** must be corruption somewhere.  */
							rc = _sqlite3CorruptError(tls, int32(69730))
						} else {
							_sqlite3OsFileControlHint(tls, (*TWal)(unsafe.Pointer(pWal)).FpDbFd, int32(SQLITE_FCNTL_SIZE_HINT), bp+16)
						}
					}
				}
				/* Iterate through the contents of the WAL, copying data to the
				 ** db file */
				for rc == SQLITE_OK && 0 == _walIteratorNext(tls, **(**uintptr)(__ccgo_up(bp)), bp+4, bp+8) {
					if libc.AtomicLoadNInt32(db+308, libc.Int32FromInt32(__ATOMIC_RELAXED)) != 0 {
						if (*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0 {
							v3 = int32(SQLITE_NOMEM)
						} else {
							v3 = int32(SQLITE_INTERRUPT)
						}
						rc = v3
						break
					}
					if **(**Tu32)(__ccgo_up(bp + 8)) <= nBackfill || **(**Tu32)(__ccgo_up(bp + 8)) > mxSafeFrame || **(**Tu32)(__ccgo_up(bp + 4)) > mxPage {
						continue
					}
					iOffset = int64(WAL_HDRSIZE) + libc.Int64FromUint32(**(**Tu32)(__ccgo_up(bp + 8))-libc.Uint32FromInt32(1))*int64(szPage+libc.Int32FromInt32(WAL_FRAME_HDRSIZE)) + int64(WAL_FRAME_HDRSIZE)
					/* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL file */
					rc = _sqlite3OsRead(tls, (*TWal)(unsafe.Pointer(pWal)).FpWalFd, zBuf, szPage, iOffset)
					if rc != SQLITE_OK {
						break
					}
					iOffset = libc.Int64FromUint32(**(**Tu32)(__ccgo_up(bp + 4))-libc.Uint32FromInt32(1)) * int64(szPage)
					rc = _sqlite3OsWrite(tls, (*TWal)(unsafe.Pointer(pWal)).FpDbFd, zBuf, szPage, iOffset)
					if rc != SQLITE_OK {
						break
					}
				}
				_sqlite3OsFileControl(tls, (*TWal)(unsafe.Pointer(pWal)).FpDbFd, int32(SQLITE_FCNTL_CKPT_DONE), uintptr(0))
				/* If work was actually accomplished... */
				if rc == SQLITE_OK {
					if mxSafeFrame == (*TWalIndexHdr)(unsafe.Pointer(_walIndexHdr(tls, pWal))).FmxFrame {
						szDb = libc.Int64FromUint32((*TWal)(unsafe.Pointer(pWal)).Fhdr.FnPage) * int64(szPage)
						rc = _sqlite3OsTruncate(tls, (*TWal)(unsafe.Pointer(pWal)).FpDbFd, szDb)
						if rc == SQLITE_OK {
							rc = _sqlite3OsSync(tls, (*TWal)(unsafe.Pointer(pWal)).FpDbFd, sync_flags>>int32(2)&int32(0x03))
						}
					}
					if rc == SQLITE_OK {
						libc.AtomicStoreNUint32(pInfo, mxSafeFrame, libc.Int32FromInt32(__ATOMIC_RELAXED))
					}
				}
			}
			/* Release the reader lock held while backfilling */
			_walUnlockExclusive(tls, pWal, libc.Int32FromInt32(3)+libc.Int32FromInt32(0), int32(1))
		}
		if rc == int32(SQLITE_BUSY) {
			/* Reset the return code so as not to report a checkpoint failure
			 ** just because there are active readers.  */
			rc = SQLITE_OK
		}
	}
	/* If this is an SQLITE_CHECKPOINT_RESTART or TRUNCATE operation, and the
	 ** entire wal file has been copied into the database file, then block
	 ** until all readers have finished using the wal file. This ensures that
	 ** the next process to write to the database restarts the wal file.
	 */
	if rc == SQLITE_OK && eMode != SQLITE_CHECKPOINT_PASSIVE {
		if (*TWalCkptInfo)(unsafe.Pointer(pInfo)).FnBackfill < (*TWal)(unsafe.Pointer(pWal)).Fhdr.FmxFrame {
			rc = int32(SQLITE_BUSY)
		} else {
			if eMode >= int32(SQLITE_CHECKPOINT_RESTART) {
				Xsqlite3_randomness(tls, int32(4), bp+32)
				rc = _walBusyLock(tls, pWal, __ccgo_fp_xBusy, pBusyArg, libc.Int32FromInt32(3)+libc.Int32FromInt32(1), libc.Int32FromInt32(SQLITE_SHM_NLOCK)-libc.Int32FromInt32(3)-libc.Int32FromInt32(1))
				if rc == SQLITE_OK {
					if eMode == int32(SQLITE_CHECKPOINT_TRUNCATE) {
						/* IMPLEMENTATION-OF: R-44699-57140 This mode works the same way as
						 ** SQLITE_CHECKPOINT_RESTART with the addition that it also
						 ** truncates the log file to zero bytes just prior to a
						 ** successful return.
						 **
						 ** In theory, it might be safe to do this without updating the
						 ** wal-index header in shared memory, as all subsequent reader or
						 ** writer clients should see that the entire log file has been
						 ** checkpointed and behave accordingly. This seems unsafe though,
						 ** as it would leave the system in a state where the contents of
						 ** the wal-index header do not match the contents of the
						 ** file-system. To avoid this, update the wal-index header to
						 ** indicate that the log file contains zero valid frames.  */
						_walRestartHdr(tls, pWal, **(**Tu32)(__ccgo_up(bp + 32)))
						rc = _sqlite3OsTruncate(tls, (*TWal)(unsafe.Pointer(pWal)).FpWalFd, 0)
					}
					_walUnlockExclusive(tls, pWal, libc.Int32FromInt32(3)+libc.Int32FromInt32(1), libc.Int32FromInt32(SQLITE_SHM_NLOCK)-libc.Int32FromInt32(3)-libc.Int32FromInt32(1))
				}
			}
		}
	}
	goto walcheckpoint_out
walcheckpoint_out:
	;
	_walIteratorFree(tls, **(**uintptr)(__ccgo_up(bp)))
	return rc
}

// C documentation
//
//	/*
//	** The index pIdx is used by a query and contains one or more expressions.
//	** In other words pIdx is an index on an expression.  iIdxCur is the cursor
//	** number for the index and iDataCur is the cursor number for the corresponding
//	** table.
//	**
//	** This routine adds IndexedExpr entries to the Parse->pIdxEpr field for
//	** each of the expressions in the index so that the expression code generator
//	** will know to replace occurrences of the indexed expression with
//	** references to the corresponding column of the index.
//	*/
func _whereAddIndexedExpr(tls *libc.TLS, pParse uintptr, pIdx uintptr, iIdxCur int32, pTabItem uintptr) {
	var i, j int32
	var p, pArg, pExpr, pTab uintptr
	_, _, _, _, _, _ = i, j, p, pArg, pExpr, pTab
	pTab = (*TIndex)(unsafe.Pointer(pIdx)).FpTable
	i = 0
	for {
		if !(i < libc.Int32FromUint16((*TIndex)(unsafe.Pointer(pIdx)).FnColumn)) {
			break
		}
		j = int32(**(**Ti16)(__ccgo_up((*TIndex)(unsafe.Pointer(pIdx)).FaiColumn + uintptr(i)*2)))
		if j == -int32(2) {
			pExpr = (*(*TExprList_item)(unsafe.Pointer((*TIndex)(unsafe.Pointer(pIdx)).FaColExpr + 8 + uintptr(i)*20))).FpExpr
		} else {
			if j >= 0 && libc.Int32FromUint16((**(**TColumn)(__ccgo_up((*TTable)(unsafe.Pointer(pTab)).FaCol + uintptr(j)*12))).FcolFlags)&int32(COLFLAG_VIRTUAL) != 0 {
				pExpr = _sqlite3ColumnExpr(tls, pTab, (*TTable)(unsafe.Pointer(pTab)).FaCol+uintptr(j)*12)
			} else {
				goto _1
			}
		}
		if _sqlite3ExprIsConstant(tls, uintptr(0), pExpr) != 0 {
			goto _1
		}
		p = _sqlite3DbMallocRaw(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, uint64(24))
		if p == uintptr(0) {
			break
		}
		(*TIndexedExpr)(unsafe.Pointer(p)).FpIENext = (*TParse)(unsafe.Pointer(pParse)).FpIdxEpr
		(*TIndexedExpr)(unsafe.Pointer(p)).FpExpr = _sqlite3ExprDup(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, pExpr, 0)
		(*TIndexedExpr)(unsafe.Pointer(p)).FiDataCur = (*TSrcItem)(unsafe.Pointer(pTabItem)).FiCursor
		(*TIndexedExpr)(unsafe.Pointer(p)).FiIdxCur = iIdxCur
		(*TIndexedExpr)(unsafe.Pointer(p)).FiIdxCol = i
		(*TIndexedExpr)(unsafe.Pointer(p)).FbMaybeNullRow = libc.BoolUint8(libc.Int32FromUint8((*TSrcItem)(unsafe.Pointer(pTabItem)).Ffg.Fjointype)&(libc.Int32FromInt32(JT_LEFT)|libc.Int32FromInt32(JT_LTORJ)|libc.Int32FromInt32(JT_RIGHT)) != 0)
		if _sqlite3IndexAffinityStr(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, pIdx) != 0 {
			(*TIndexedExpr)(unsafe.Pointer(p)).Faff = libc.Uint8FromInt8(**(**int8)(__ccgo_up((*TIndex)(unsafe.Pointer(pIdx)).FzColAff + uintptr(i))))
		}
		(*TParse)(unsafe.Pointer(pParse)).FpIdxEpr = p
		if (*TIndexedExpr)(unsafe.Pointer(p)).FpIENext == uintptr(0) {
			pArg = pParse + 76
			_sqlite3ParserAddCleanup(tls, pParse, __ccgo_fp(_whereIndexedExprCleanup), pArg)
		}
		goto _1
	_1:
		;
		i = i + 1
	}
}

// C documentation
//
//	/*
//	** Check to see if there are any SEARCH loops that might benefit from
//	** using a Bloom filter.  Consider a Bloom filter if:
//	**
//	**   (1)  The SEARCH happens more than N times where N is the number
//	**        of rows in the table that is being considered for the Bloom
//	**        filter.
//	**   (2)  Some searches are expected to find zero rows.  (This is determined
//	**        by the WHERE_SELFCULL flag on the term.)
//	**   (3)  Bloom-filter processing is not disabled.  (Checked by the
//	**        caller.)
//	**   (4)  The size of the table being searched is known by ANALYZE.
//	**
//	** This block of code merely checks to see if a Bloom filter would be
//	** appropriate, and if so sets the WHERE_BLOOMFILTER flag on the
//	** WhereLoop.  The implementation of the Bloom filter comes further
//	** down where the code for each WhereLoop is generated.
//	*/
func _whereCheckIfBloomFilterIsUseful(tls *libc.TLS, pWInfo uintptr) {
	var i int32
	var nSearch TLogEst
	var pItem, pLoop, pTab uintptr
	var reqFlags uint32
	_, _, _, _, _, _ = i, nSearch, pItem, pLoop, pTab, reqFlags
	nSearch = 0
	i = 0
	for {
		if !(i < libc.Int32FromUint8((*TWhereInfo)(unsafe.Pointer(pWInfo)).FnLevel)) {
			break
		}
		pLoop = (*(*TWhereLevel)(unsafe.Pointer(pWInfo + 752 + uintptr(i)*88))).FpWLoop
		reqFlags = libc.Uint32FromInt32(libc.Int32FromInt32(WHERE_SELFCULL) | libc.Int32FromInt32(WHERE_COLUMN_EQ))
		pItem = (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpTabList + 8 + uintptr((*TWhereLoop)(unsafe.Pointer(pLoop)).FiTab)*48
		pTab = (*TSrcItem)(unsafe.Pointer(pItem)).FpSTab
		if (*TTable)(unsafe.Pointer(pTab)).FtabFlags&uint32(TF_HasStat1) == uint32(0) {
			break
		}
		**(**Tu32)(__ccgo_up(pTab + 28)) |= uint32(TF_MaybeReanalyze)
		if i >= int32(1) && (*TWhereLoop)(unsafe.Pointer(pLoop)).FwsFlags&reqFlags == reqFlags && (*TWhereLoop)(unsafe.Pointer(pLoop)).FwsFlags&libc.Uint32FromInt32(libc.Int32FromInt32(WHERE_IPK)|libc.Int32FromInt32(WHERE_INDEXED)) != uint32(0) {
			if int32(nSearch) > int32((*TTable)(unsafe.Pointer(pTab)).FnRowLogEst) {
				**(**Tu32)(__ccgo_up(pLoop + 40)) |= uint32(WHERE_BLOOMFILTER)
				**(**Tu32)(__ccgo_up(pLoop + 40)) &= libc.Uint32FromInt32(^libc.Int32FromInt32(WHERE_IDX_ONLY))
			}
		}
		nSearch = int16(int32(nSearch) + int32((*TWhereLoop)(unsafe.Pointer(pLoop)).FnOut))
		goto _1
	_1:
		;
		i = i + 1
	}
}

// C documentation
//
//	/*
//	** Estimate the number of rows that will be returned based on
//	** an equality constraint x=VALUE and where that VALUE occurs in
//	** the histogram data.  This only works when x is the left-most
//	** column of an index and sqlite_stat4 histogram data is available
//	** for that index.  When pExpr==NULL that means the constraint is
//	** "x IS NULL" instead of "x=VALUE".
//	**
//	** Write the estimated row count into *pnRow and return SQLITE_OK.
//	** If unable to make an estimate, leave *pnRow unchanged and return
//	** non-zero.
//	**
//	** This routine can fail if it is unable to load a collating sequence
//	** required for string comparison, or if unable to allocate memory
//	** for a UTF conversion required for comparison.  The error is stored
//	** in the pParse structure.
//	*/
func _whereEqualScanEst(tls *libc.TLS, pParse uintptr, pBuilder uintptr, pExpr uintptr, pnRow uintptr) (r int32) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var nEq, rc int32
	var p uintptr
	var _ /* a at bp+4 */ [2]TtRowcnt
	var _ /* bOk at bp+20 */ int32
	var _ /* pRec at bp+0 */ uintptr
	_, _, _ = nEq, p, rc
	p = (*(*struct {
		FnEq          Tu16
		FnBtm         Tu16
		FnTop         Tu16
		FnDistinctCol Tu16
		FpIndex       uintptr
		FpOrderBy     uintptr
	})(unsafe.Pointer((*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FpNew + 24))).FpIndex
	nEq = libc.Int32FromUint16((*(*struct {
		FnEq          Tu16
		FnBtm         Tu16
		FnTop         Tu16
		FnDistinctCol Tu16
		FpIndex       uintptr
		FpOrderBy     uintptr
	})(unsafe.Pointer((*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FpNew + 24))).FnEq)
	**(**uintptr)(__ccgo_up(bp)) = (*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FpRec
	/* If values are not available for all fields of the index to the left
	 ** of this one, no estimate can be made. Return SQLITE_NOTFOUND. */
	if (*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FnRecValid < nEq-int32(1) {
		return int32(SQLITE_NOTFOUND)
	}
	/* This is an optimization only. The call to sqlite3Stat4ProbeSetValue()
	 ** below would return the same value.  */
	if nEq >= libc.Int32FromUint16((*TIndex)(unsafe.Pointer(p)).FnColumn) {
		**(**TtRowcnt)(__ccgo_up(pnRow)) = uint64(1)
		return SQLITE_OK
	}
	rc = _sqlite3Stat4ProbeSetValue(tls, pParse, p, bp, pExpr, int32(1), nEq-int32(1), bp+20)
	(*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FpRec = **(**uintptr)(__ccgo_up(bp))
	if rc != SQLITE_OK {
		return rc
	}
	if **(**int32)(__ccgo_up(bp + 20)) == 0 {
		return int32(SQLITE_NOTFOUND)
	}
	(*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FnRecValid = nEq
	_whereKeyStats(tls, pParse, p, **(**uintptr)(__ccgo_up(bp)), 0, bp+4)
	**(**TtRowcnt)(__ccgo_up(pnRow)) = (**(**[2]TtRowcnt)(__ccgo_up(bp + 4)))[int32(1)]
	return rc
}

// C documentation
//
//	/*
//	** Free a WhereInfo structure
//	*/
func _whereInfoFree(tls *libc.TLS, db uintptr, pWInfo uintptr) {
	var p, pNext uintptr
	_, _ = p, pNext
	_sqlite3WhereClauseClear(tls, pWInfo+76)
	for (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpLoops != 0 {
		p = (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpLoops
		(*TWhereInfo)(unsafe.Pointer(pWInfo)).FpLoops = (*TWhereLoop)(unsafe.Pointer(p)).FpNextLoop
		_whereLoopDelete(tls, db, p)
	}
	for (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpMemToFree != 0 {
		pNext = (*TWhereMemBlock)(unsafe.Pointer((*TWhereInfo)(unsafe.Pointer(pWInfo)).FpMemToFree)).FpNext
		_sqlite3DbNNFreeNN(tls, db, (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpMemToFree)
		(*TWhereInfo)(unsafe.Pointer(pWInfo)).FpMemToFree = pNext
	}
	_sqlite3DbNNFreeNN(tls, db, pWInfo)
}

// C documentation
//
//	/*
//	** This routine implements a heuristic designed to improve query planning.
//	** This routine is called in between the first and second call to
//	** wherePathSolver().  Hence the name "Interstage" "Heuristic".
//	**
//	** The first call to wherePathSolver() (hereafter just "solver()") computes
//	** the best path without regard to the order of the outputs.  The second call
//	** to the solver() builds upon the first call to try to find an alternative
//	** path that satisfies the ORDER BY clause.
//	**
//	** This routine looks at the results of the first solver() run, and for
//	** every FROM clause term in the resulting query plan that uses an equality
//	** constraint against an index, disable other WhereLoops for that same
//	** FROM clause term that would try to do a full-table scan.  This prevents
//	** an index search from being converted into a full-table scan in order to
//	** satisfy an ORDER BY clause, since even though we might get slightly better
//	** performance using the full-scan without sorting if the output size
//	** estimates are very precise, we might also get severe performance
//	** degradation using the full-scan if the output size estimate is too large.
//	** It is better to err on the side of caution.
//	**
//	** Except, if the first solver() call generated a full-table scan in an outer
//	** loop then stop this analysis at the first full-scan, since the second
//	** solver() run might try to swap that full-scan for another in order to
//	** get the output into the correct order.  In other words, we allow a
//	** rewrite like this:
//	**
//	**     First Solver()                      Second Solver()
//	**       |-- SCAN t1                         |-- SCAN t2
//	**       |-- SEARCH t2                       `-- SEARCH t1
//	**       `-- SORT USING B-TREE
//	**
//	** The purpose of this routine is to disallow rewrites such as:
//	**
//	**     First Solver()                      Second Solver()
//	**       |-- SEARCH t1                       |-- SCAN t2     <--- bad!
//	**       |-- SEARCH t2                       `-- SEARCH t1
//	**       `-- SORT USING B-TREE
//	**
//	** See test cases in test/whereN.test for the real-world query that
//	** originally provoked this heuristic.
//	*/
func _whereInterstageHeuristic(tls *libc.TLS, pWInfo uintptr) {
	var i int32
	var iTab Tu8
	var p, pLoop uintptr
	_, _, _, _ = i, iTab, p, pLoop
	i = 0
	for {
		if !(i < libc.Int32FromUint8((*TWhereInfo)(unsafe.Pointer(pWInfo)).FnLevel)) {
			break
		}
		p = (*(*TWhereLevel)(unsafe.Pointer(pWInfo + 752 + uintptr(i)*88))).FpWLoop
		if p == uintptr(0) {
			break
		}
		if (*TWhereLoop)(unsafe.Pointer(p)).FwsFlags&uint32(WHERE_VIRTUALTABLE) != uint32(0) {
			/* Treat a vtab scan as similar to a full-table scan */
			break
		}
		if (*TWhereLoop)(unsafe.Pointer(p)).FwsFlags&libc.Uint32FromInt32(libc.Int32FromInt32(WHERE_COLUMN_EQ)|libc.Int32FromInt32(WHERE_COLUMN_NULL)|libc.Int32FromInt32(WHERE_COLUMN_IN)) != uint32(0) {
			iTab = (*TWhereLoop)(unsafe.Pointer(p)).FiTab
			pLoop = (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpLoops
			for {
				if !(pLoop != 0) {
					break
				}
				if libc.Int32FromUint8((*TWhereLoop)(unsafe.Pointer(pLoop)).FiTab) != libc.Int32FromUint8(iTab) {
					goto _2
				}
				if (*TWhereLoop)(unsafe.Pointer(pLoop)).FwsFlags&libc.Uint32FromInt32(libc.Int32FromInt32(WHERE_CONSTRAINT)|libc.Int32FromInt32(WHERE_AUTO_INDEX)) != uint32(0) {
					/* Auto-index and index-constrained loops allowed to remain */
					goto _2
				}
				(*TWhereLoop)(unsafe.Pointer(pLoop)).Fprereq = libc.Uint64FromInt32(-libc.Int32FromInt32(1)) /* Prevent 2nd solver() from using this one */
				goto _2
			_2:
				;
				pLoop = (*TWhereLoop)(unsafe.Pointer(pLoop)).FpNextLoop
			}
		} else {
			break
		}
		goto _1
	_1:
		;
		i = i + 1
	}
}

// C documentation
//
//	/*
//	** Add all WhereLoop objects for a single table of the join where the table
//	** is identified by pBuilder->pNew->iTab.  That table is guaranteed to be
//	** a b-tree table, not a virtual table.
//	**
//	** The costs (WhereLoop.rRun) of the b-tree loops added by this function
//	** are calculated as follows:
//	**
//	** For a full scan, assuming the table (or index) contains nRow rows:
//	**
//	**     cost = nRow * 3.0                    // full-table scan
//	**     cost = nRow * K                      // scan of covering index
//	**     cost = nRow * (K+3.0)                // scan of non-covering index
//	**
//	** where K is a value between 1.1 and 3.0 set based on the relative
//	** estimated average size of the index and table records.
//	**
//	** For an index scan, where nVisit is the number of index rows visited
//	** by the scan, and nSeek is the number of seek operations required on
//	** the index b-tree:
//	**
//	**     cost = nSeek * (log(nRow) + K * nVisit)          // covering index
//	**     cost = nSeek * (log(nRow) + (K+3.0) * nVisit)    // non-covering index
//	**
//	** Normally, nSeek is 1. nSeek values greater than 1 come about if the
//	** WHERE clause includes "x IN (....)" terms used in place of "x=?". Or when
//	** implicit "x IN (SELECT x FROM tbl)" terms are added for skip-scans.
//	**
//	** The estimated values (nRow, nVisit, nSeek) often contain a large amount
//	** of uncertainty.  For this reason, scoring is designed to pick plans that
//	** "do the least harm" if the estimates are inaccurate.  For example, a
//	** log(nRow) factor is omitted from a non-covering index scan in order to
//	** bias the scoring in favor of using an index, since the worst-case
//	** performance of using an index is far better than the worst-case performance
//	** of a full table scan.
//	*/
func _whereLoopAddBtree(tls *libc.TLS, pBuilder uintptr, mPrereq TBitmask) (r int32) {
	bp := tls.Alloc(128)
	defer tls.Free(128)
	var b, iCur, iSortIdx, ii, rc, v5 int32
	var isCov Tu32
	var nLookup, rLogSize, rSize TLogEst
	var pFirst, pNew, pProbe, pSrc, pTab, pTabList, pTerm, pTerm1, pWC, pWC2, pWCEnd, pWInfo, v2 uintptr
	var _ /* aiColumnPk at bp+104 */ Ti16
	var _ /* aiRowEstPk at bp+100 */ [2]TLogEst
	var _ /* m at bp+112 */ TBitmask
	var _ /* sPk at bp+0 */ TIndex
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = b, iCur, iSortIdx, ii, isCov, nLookup, pFirst, pNew, pProbe, pSrc, pTab, pTabList, pTerm, pTerm1, pWC, pWC2, pWCEnd, pWInfo, rLogSize, rSize, rc, v2, v5 /* The aiRowLogEst[] value for the sPk index */
	**(**Ti16)(__ccgo_up(bp + 104)) = int16(-int32(1))                                                                                                                                                                             /* Template WhereLoop object */
	rc = SQLITE_OK                                                                                                                                                                                                                 /* Return code */
	iSortIdx = int32(1)                                                                                                                                                                                                            /* Table being queried */
	pNew = (*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FpNew
	pWInfo = (*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FpWInfo
	pTabList = (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpTabList
	pSrc = pTabList + 8 + uintptr((*TWhereLoop)(unsafe.Pointer(pNew)).FiTab)*48
	pTab = (*TSrcItem)(unsafe.Pointer(pSrc)).FpSTab
	pWC = (*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FpWC
	if int32(*(*uint32)(unsafe.Pointer(pSrc + 12 + 4))&0x2>>1) != 0 {
		/* An INDEXED BY clause specifies a particular index to use */
		pProbe = *(*uintptr)(unsafe.Pointer(pSrc + 36))
	} else {
		if !((*TTable)(unsafe.Pointer(pTab)).FtabFlags&libc.Uint32FromInt32(TF_WithoutRowid) == libc.Uint32FromInt32(0)) {
			pProbe = (*TTable)(unsafe.Pointer(pTab)).FpIndex
		} else { /* First of real indices on the table */
			libc.Xmemset(tls, bp, 0, uint32(100))
			(**(**TIndex)(__ccgo_up(bp))).FnKeyCol = uint16(1)
			(**(**TIndex)(__ccgo_up(bp))).FnColumn = uint16(1)
			(**(**TIndex)(__ccgo_up(bp))).FaiColumn = bp + 104
			(**(**TIndex)(__ccgo_up(bp))).FaiRowLogEst = bp + 100
			(**(**TIndex)(__ccgo_up(bp))).FonError = uint8(OE_Replace)
			(**(**TIndex)(__ccgo_up(bp))).FpTable = pTab
			(**(**TIndex)(__ccgo_up(bp))).FszIdxRow = int16(3) /* TUNING: Interior rows of IPK table are very small */
			libc.SetBitFieldPtr16Uint32(bp+56, libc.Uint32FromInt32(SQLITE_IDXTYPE_IPK), 0, 0x3)
			(**(**[2]TLogEst)(__ccgo_up(bp + 100)))[0] = (*TTable)(unsafe.Pointer(pTab)).FnRowLogEst
			(**(**[2]TLogEst)(__ccgo_up(bp + 100)))[int32(1)] = 0
			pFirst = (*TTable)(unsafe.Pointer((*TSrcItem)(unsafe.Pointer(pSrc)).FpSTab)).FpIndex
			if int32(*(*uint32)(unsafe.Pointer(pSrc + 12 + 4))&0x1>>0) == 0 {
				/* The real indices of the table are only considered if the
				 ** NOT INDEXED qualifier is omitted from the FROM clause */
				(**(**TIndex)(__ccgo_up(bp))).FpNext = pFirst
			}
			pProbe = bp
		}
	}
	rSize = (*TTable)(unsafe.Pointer(pTab)).FnRowLogEst
	/* Automatic indexes */
	if !((*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FpOrSet != 0) && libc.Int32FromUint16((*TWhereInfo)(unsafe.Pointer(pWInfo)).FwctrlFlags)&(libc.Int32FromInt32(WHERE_RIGHT_JOIN)|libc.Int32FromInt32(WHERE_OR_SUBCLAUSE)) == 0 && (*Tsqlite3)(unsafe.Pointer((*TParse)(unsafe.Pointer((*TWhereInfo)(unsafe.Pointer(pWInfo)).FpParse)).Fdb)).Fflags&uint64(SQLITE_AutoIndex) != uint64(0) && !(int32(*(*uint32)(unsafe.Pointer(pSrc + 12 + 4))&0x2>>1) != 0) && !(int32(*(*uint32)(unsafe.Pointer(pSrc + 12 + 4))&0x1>>0) != 0) && !(int32(*(*uint32)(unsafe.Pointer(pSrc + 12 + 4))&0x10>>4) != 0) && !(int32(*(*uint32)(unsafe.Pointer(pSrc + 12 + 4))&0x80>>7) != 0) && libc.Int32FromUint8((*TSrcItem)(unsafe.Pointer(pSrc)).Ffg.Fjointype)&int32(JT_RIGHT) == 0 {
		pWCEnd = (*TWhereClause)(unsafe.Pointer(pWC)).Fa + uintptr((*TWhereClause)(unsafe.Pointer(pWC)).FnTerm)*48
		rLogSize = _estLog(tls, rSize)
		pTerm = (*TWhereClause)(unsafe.Pointer(pWC)).Fa
		for {
			if !(rc == SQLITE_OK && pTerm < pWCEnd) {
				break
			}
			if (*TWhereTerm)(unsafe.Pointer(pTerm)).FprereqRight&(*TWhereLoop)(unsafe.Pointer(pNew)).FmaskSelf != 0 {
				goto _1
			}
			if _termCanDriveIndex(tls, pTerm, pSrc, uint64(0)) != 0 {
				(*(*struct {
					FnEq          Tu16
					FnBtm         Tu16
					FnTop         Tu16
					FnDistinctCol Tu16
					FpIndex       uintptr
					FpOrderBy     uintptr
				})(unsafe.Pointer(pNew + 24))).FnEq = uint16(1)
				(*TWhereLoop)(unsafe.Pointer(pNew)).FnSkip = uint16(0)
				(*(*struct {
					FnEq          Tu16
					FnBtm         Tu16
					FnTop         Tu16
					FnDistinctCol Tu16
					FpIndex       uintptr
					FpOrderBy     uintptr
				})(unsafe.Pointer(pNew + 24))).FpIndex = uintptr(0)
				(*TWhereLoop)(unsafe.Pointer(pNew)).FnLTerm = uint16(1)
				**(**uintptr)(__ccgo_up((*TWhereLoop)(unsafe.Pointer(pNew)).FaLTerm)) = pTerm
				/* TUNING: One-time cost for computing the automatic index is
				 ** estimated to be X*N*log2(N) where N is the number of rows in
				 ** the table being indexed and where X is 7 (LogEst=28) for normal
				 ** tables or 0.5 (LogEst=-10) for views and subqueries.  The value
				 ** of X is smaller for views and subqueries so that the query planner
				 ** will be more aggressive about generating automatic indexes for
				 ** those objects, since there is no opportunity to add schema
				 ** indexes on subqueries and views. */
				(*TWhereLoop)(unsafe.Pointer(pNew)).FrSetup = int16(int32(rLogSize) + int32(rSize))
				if !(libc.Int32FromUint8((*TTable)(unsafe.Pointer(pTab)).FeTabType) == libc.Int32FromInt32(TABTYP_VIEW)) && (*TTable)(unsafe.Pointer(pTab)).FtabFlags&uint32(TF_Ephemeral) == uint32(0) {
					v2 = pNew + 18
					*(*TLogEst)(unsafe.Pointer(v2)) = TLogEst(int32(*(*TLogEst)(unsafe.Pointer(v2))) + libc.Int32FromInt32(28))
				} else {
					v2 = pNew + 18
					*(*TLogEst)(unsafe.Pointer(v2)) = TLogEst(int32(*(*TLogEst)(unsafe.Pointer(v2))) - libc.Int32FromInt32(25)) /* Greatly reduced setup cost for auto indexes
					 ** on ephemeral materializations of views */
				}
				if int32((*TWhereLoop)(unsafe.Pointer(pNew)).FrSetup) < 0 {
					(*TWhereLoop)(unsafe.Pointer(pNew)).FrSetup = 0
				}
				/* TUNING: Each index lookup yields 20 rows in the table.  This
				 ** is more than the usual guess of 10 rows, since we have no way
				 ** of knowing how selective the index will ultimately be.  It would
				 ** not be unreasonable to make this value much larger. */
				(*TWhereLoop)(unsafe.Pointer(pNew)).FnOut = int16(43)
				(*TWhereLoop)(unsafe.Pointer(pNew)).FrRun = _sqlite3LogEstAdd(tls, rLogSize, (*TWhereLoop)(unsafe.Pointer(pNew)).FnOut)
				(*TWhereLoop)(unsafe.Pointer(pNew)).FwsFlags = uint32(WHERE_AUTO_INDEX)
				(*TWhereLoop)(unsafe.Pointer(pNew)).Fprereq = mPrereq | (*TWhereTerm)(unsafe.Pointer(pTerm)).FprereqRight
				rc = _whereLoopInsert(tls, pBuilder, pNew)
			}
			goto _1
		_1:
			;
			pTerm += 48
		}
	}
	/* Loop over all indices. If there was an INDEXED BY clause, then only
	 ** consider index pProbe.  */
	for {
		if !(rc == SQLITE_OK && pProbe != 0) {
			break
		}
		if (*TIndex)(unsafe.Pointer(pProbe)).FpPartIdxWhere != uintptr(0) && !(_whereUsablePartialIndex(tls, (*TSrcItem)(unsafe.Pointer(pSrc)).FiCursor, (*TSrcItem)(unsafe.Pointer(pSrc)).Ffg.Fjointype, pWC, (*TIndex)(unsafe.Pointer(pProbe)).FpPartIdxWhere) != 0) {
			/* See ticket [98d973b8f5] */
			goto _4 /* Partial index inappropriate for this query */
		}
		if int32(uint32(*(*uint16)(unsafe.Pointer(pProbe + 56))&0x100>>8)) != 0 {
			goto _4
		}
		rSize = **(**TLogEst)(__ccgo_up((*TIndex)(unsafe.Pointer(pProbe)).FaiRowLogEst))
		(*(*struct {
			FnEq          Tu16
			FnBtm         Tu16
			FnTop         Tu16
			FnDistinctCol Tu16
			FpIndex       uintptr
			FpOrderBy     uintptr
		})(unsafe.Pointer(pNew + 24))).FnEq = uint16(0)
		(*(*struct {
			FnEq          Tu16
			FnBtm         Tu16
			FnTop         Tu16
			FnDistinctCol Tu16
			FpIndex       uintptr
			FpOrderBy     uintptr
		})(unsafe.Pointer(pNew + 24))).FnBtm = uint16(0)
		(*(*struct {
			FnEq          Tu16
			FnBtm         Tu16
			FnTop         Tu16
			FnDistinctCol Tu16
			FpIndex       uintptr
			FpOrderBy     uintptr
		})(unsafe.Pointer(pNew + 24))).FnTop = uint16(0)
		(*(*struct {
			FnEq          Tu16
			FnBtm         Tu16
			FnTop         Tu16
			FnDistinctCol Tu16
			FpIndex       uintptr
			FpOrderBy     uintptr
		})(unsafe.Pointer(pNew + 24))).FnDistinctCol = uint16(0)
		(*TWhereLoop)(unsafe.Pointer(pNew)).FnSkip = uint16(0)
		(*TWhereLoop)(unsafe.Pointer(pNew)).FnLTerm = uint16(0)
		(*TWhereLoop)(unsafe.Pointer(pNew)).FiSortIdx = uint8(0)
		(*TWhereLoop)(unsafe.Pointer(pNew)).FrSetup = 0
		(*TWhereLoop)(unsafe.Pointer(pNew)).Fprereq = mPrereq
		(*TWhereLoop)(unsafe.Pointer(pNew)).FnOut = rSize
		(*(*struct {
			FnEq          Tu16
			FnBtm         Tu16
			FnTop         Tu16
			FnDistinctCol Tu16
			FpIndex       uintptr
			FpOrderBy     uintptr
		})(unsafe.Pointer(pNew + 24))).FpIndex = pProbe
		(*(*struct {
			FnEq          Tu16
			FnBtm         Tu16
			FnTop         Tu16
			FnDistinctCol Tu16
			FpIndex       uintptr
			FpOrderBy     uintptr
		})(unsafe.Pointer(pNew + 24))).FpOrderBy = uintptr(0)
		b = _indexMightHelpWithOrderBy(tls, pBuilder, pProbe, (*TSrcItem)(unsafe.Pointer(pSrc)).FiCursor)
		/* The ONEPASS_DESIRED flags never occurs together with ORDER BY */
		if int32(uint32(*(*uint16)(unsafe.Pointer(pProbe + 56))&0x3>>0)) == int32(SQLITE_IDXTYPE_IPK) {
			/* Integer primary key index */
			(*TWhereLoop)(unsafe.Pointer(pNew)).FwsFlags = uint32(WHERE_IPK)
			/* Full table scan */
			if b != 0 {
				v5 = iSortIdx
			} else {
				v5 = 0
			}
			(*TWhereLoop)(unsafe.Pointer(pNew)).FiSortIdx = libc.Uint8FromInt32(v5)
			/* TUNING: Cost of full table scan is 3.0*N.  The 3.0 factor is an
			 ** extra cost designed to discourage the use of full table scans,
			 ** since index lookups have better worst-case performance if our
			 ** stat guesses are wrong.  Reduce the 3.0 penalty slightly
			 ** (to 2.75) if we have valid STAT4 information for the table.
			 ** At 2.75, a full table scan is preferred over using an index on
			 ** a column with just two distinct values where each value has about
			 ** an equal number of appearances.  Without STAT4 data, we still want
			 ** to use an index in that case, since the constraint might be for
			 ** the scarcer of the two values, and in that case an index lookup is
			 ** better.
			 */
			(*TWhereLoop)(unsafe.Pointer(pNew)).FrRun = int16(int32(rSize) + int32(16) - int32(2)*libc.BoolInt32((*TTable)(unsafe.Pointer(pTab)).FtabFlags&uint32(TF_HasStat4) != uint32(0)))
			_whereLoopOutputAdjust(tls, pWC, pNew, rSize)
			if int32(*(*uint32)(unsafe.Pointer(pSrc + 12 + 4))&0x4>>2) != 0 {
				if int32(*(*uint32)(unsafe.Pointer(pSrc + 12 + 4))&0x40>>6) != 0 {
					**(**Tu32)(__ccgo_up(pNew + 40)) |= uint32(WHERE_COROUTINE)
				}
				/* Do not set btree.pOrderBy for a recursive CTE. In this case
				 ** the ORDER BY clause does not determine the overall order that
				 ** rows are emitted from the CTE in.  */
				if (*TSelect)(unsafe.Pointer((*TSubquery)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pSrc + 44)))).FpSelect)).FselFlags&uint32(SF_Recursive) == uint32(0) {
					(*(*struct {
						FnEq          Tu16
						FnBtm         Tu16
						FnTop         Tu16
						FnDistinctCol Tu16
						FpIndex       uintptr
						FpOrderBy     uintptr
					})(unsafe.Pointer(pNew + 24))).FpOrderBy = (*TSelect)(unsafe.Pointer((*TSubquery)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pSrc + 44)))).FpSelect)).FpOrderBy
				}
			} else {
				if int32(*(*uint32)(unsafe.Pointer(pSrc + 12 + 4))&0x40000>>18) != 0 {
					(*TWhereLoop)(unsafe.Pointer(pNew)).FnOut = 0
				}
			}
			rc = _whereLoopInsert(tls, pBuilder, pNew)
			(*TWhereLoop)(unsafe.Pointer(pNew)).FnOut = rSize
			if rc != 0 {
				break
			}
		} else {
			if int32(uint32(*(*uint16)(unsafe.Pointer(pProbe + 56))&0x20>>5)) != 0 {
				**(**TBitmask)(__ccgo_up(bp + 112)) = uint64(0)
				(*TWhereLoop)(unsafe.Pointer(pNew)).FwsFlags = libc.Uint32FromInt32(libc.Int32FromInt32(WHERE_IDX_ONLY) | libc.Int32FromInt32(WHERE_INDEXED))
			} else {
				**(**TBitmask)(__ccgo_up(bp + 112)) = (*TSrcItem)(unsafe.Pointer(pSrc)).FcolUsed & (*TIndex)(unsafe.Pointer(pProbe)).FcolNotIdxed
				if (*TIndex)(unsafe.Pointer(pProbe)).FpPartIdxWhere != 0 {
					_wherePartIdxExpr(tls, (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpParse, pProbe, (*TIndex)(unsafe.Pointer(pProbe)).FpPartIdxWhere, bp+112, 0, uintptr(0))
				}
				(*TWhereLoop)(unsafe.Pointer(pNew)).FwsFlags = uint32(WHERE_INDEXED)
				if **(**TBitmask)(__ccgo_up(bp + 112)) == libc.Uint64FromInt32(1)<<(libc.Int32FromUint32(libc.Uint32FromInt64(8)*libc.Uint32FromInt32(8))-libc.Int32FromInt32(1)) || int32(uint32(*(*uint16)(unsafe.Pointer(pProbe + 56))&0x800>>11)) != 0 && !(int32(uint32(*(*uint16)(unsafe.Pointer(pProbe + 56))&0x400>>10)) != 0) && **(**TBitmask)(__ccgo_up(bp + 112)) != uint64(0) {
					isCov = _whereIsCoveringIndex(tls, pWInfo, pProbe, (*TSrcItem)(unsafe.Pointer(pSrc)).FiCursor)
					if isCov == uint32(0) {
					} else {
						**(**TBitmask)(__ccgo_up(bp + 112)) = uint64(0)
						**(**Tu32)(__ccgo_up(pNew + 40)) |= isCov
						if isCov&uint32(WHERE_IDX_ONLY) != 0 {
						} else {
						}
					}
				} else {
					if **(**TBitmask)(__ccgo_up(bp + 112)) == uint64(0) && ((*TTable)(unsafe.Pointer(pTab)).FtabFlags&uint32(TF_WithoutRowid) == uint32(0) || (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpSelect != uintptr(0) || _sqlite3FaultSim(tls, int32(700)) != 0) {
						(*TWhereLoop)(unsafe.Pointer(pNew)).FwsFlags = libc.Uint32FromInt32(libc.Int32FromInt32(WHERE_IDX_ONLY) | libc.Int32FromInt32(WHERE_INDEXED))
					}
				}
			}
			/* Full scan via index */
			if b != 0 || !((*TTable)(unsafe.Pointer(pTab)).FtabFlags&libc.Uint32FromInt32(TF_WithoutRowid) == libc.Uint32FromInt32(0)) || (*TIndex)(unsafe.Pointer(pProbe)).FpPartIdxWhere != uintptr(0) || int32(*(*uint32)(unsafe.Pointer(pSrc + 12 + 4))&0x2>>1) != 0 || **(**TBitmask)(__ccgo_up(bp + 112)) == uint64(0) && int32(uint32(*(*uint16)(unsafe.Pointer(pProbe + 56))&0x4>>2)) == 0 && int32((*TIndex)(unsafe.Pointer(pProbe)).FszIdxRow) < int32((*TTable)(unsafe.Pointer(pTab)).FszTabRow) && libc.Int32FromUint16((*TWhereInfo)(unsafe.Pointer(pWInfo)).FwctrlFlags)&int32(WHERE_ONEPASS_DESIRED) == 0 && _sqlite3Config.FbUseCis != 0 && (*Tsqlite3)(unsafe.Pointer((*TParse)(unsafe.Pointer((*TWhereInfo)(unsafe.Pointer(pWInfo)).FpParse)).Fdb)).FdbOptFlags&libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_CoverIdxScan)) == uint32(0) {
				if b != 0 {
					v5 = iSortIdx
				} else {
					v5 = 0
				}
				(*TWhereLoop)(unsafe.Pointer(pNew)).FiSortIdx = libc.Uint8FromInt32(v5)
				/* The cost of visiting the index rows is N*K, where K is
				 ** between 1.1 and 3.0, depending on the relative sizes of the
				 ** index and table rows. */
				(*TWhereLoop)(unsafe.Pointer(pNew)).FrRun = int16(int32(rSize) + int32(1) + int32(15)*int32((*TIndex)(unsafe.Pointer(pProbe)).FszIdxRow)/int32((*TTable)(unsafe.Pointer(pTab)).FszTabRow))
				if **(**TBitmask)(__ccgo_up(bp + 112)) != uint64(0) {
					/* If this is a non-covering index scan, add in the cost of
					 ** doing table lookups.  The cost will be 3x the number of
					 ** lookups.  Take into account WHERE clause terms that can be
					 ** satisfied using just the index, and that do not require a
					 ** table lookup. */
					nLookup = int16(int32(rSize) + int32(16))
					iCur = (*TSrcItem)(unsafe.Pointer(pSrc)).FiCursor
					pWC2 = pWInfo + 76
					ii = 0
					for {
						if !(ii < (*TWhereClause)(unsafe.Pointer(pWC2)).FnTerm) {
							break
						}
						pTerm1 = (*TWhereClause)(unsafe.Pointer(pWC2)).Fa + uintptr(ii)*48
						if !(_sqlite3ExprCoveredByIndex(tls, (*TWhereTerm)(unsafe.Pointer(pTerm1)).FpExpr, iCur, pProbe) != 0) {
							break
						}
						/* pTerm can be evaluated using just the index.  So reduce
						 ** the expected number of table lookups accordingly */
						if int32((*TWhereTerm)(unsafe.Pointer(pTerm1)).FtruthProb) <= 0 {
							nLookup = int16(int32(nLookup) + int32((*TWhereTerm)(unsafe.Pointer(pTerm1)).FtruthProb))
						} else {
							nLookup = nLookup - 1
							if libc.Int32FromUint16((*TWhereTerm)(unsafe.Pointer(pTerm1)).FeOperator)&(libc.Int32FromInt32(WO_EQ)|libc.Int32FromInt32(WO_IS)) != 0 {
								nLookup = int16(int32(nLookup) - libc.Int32FromInt32(19))
							}
						}
						goto _7
					_7:
						;
						ii = ii + 1
					}
					(*TWhereLoop)(unsafe.Pointer(pNew)).FrRun = _sqlite3LogEstAdd(tls, (*TWhereLoop)(unsafe.Pointer(pNew)).FrRun, nLookup)
				}
				_whereLoopOutputAdjust(tls, pWC, pNew, rSize)
				if libc.Int32FromUint8((*TSrcItem)(unsafe.Pointer(pSrc)).Ffg.Fjointype)&int32(JT_RIGHT) != 0 && (*TIndex)(unsafe.Pointer(pProbe)).FaColExpr != 0 {
					/* Do not do an SCAN of a index-on-expression in a RIGHT JOIN
					 ** because the cursor used to access the index might not be
					 ** positioned to the correct row during the right-join no-match
					 ** loop. */
				} else {
					if int32(*(*uint32)(unsafe.Pointer(pSrc + 12 + 4))&0x40000>>18) != 0 {
						(*TWhereLoop)(unsafe.Pointer(pNew)).FnOut = 0
					}
					rc = _whereLoopInsert(tls, pBuilder, pNew)
				}
				(*TWhereLoop)(unsafe.Pointer(pNew)).FnOut = rSize
				if rc != 0 {
					break
				}
			}
		}
		(*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FbldFlags1 = uint8(0)
		rc = _whereLoopAddBtreeIndex(tls, pBuilder, pSrc, pProbe, 0)
		if libc.Int32FromUint8((*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FbldFlags1) == int32(SQLITE_BLDF1_INDEXED) {
			/* If a non-unique index is used, or if a prefix of the key for
			 ** unique index is used (making the index functionally non-unique)
			 ** then the sqlite_stat1 data becomes important for scoring the
			 ** plan */
			**(**Tu32)(__ccgo_up(pTab + 28)) |= uint32(TF_MaybeReanalyze)
		}
		_sqlite3Stat4ProbeFree(tls, (*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FpRec)
		(*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FnRecValid = 0
		(*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FpRec = uintptr(0)
		goto _4
	_4:
		;
		if int32(*(*uint32)(unsafe.Pointer(pSrc + 12 + 4))&0x2>>1) != 0 {
			v2 = uintptr(0)
		} else {
			v2 = (*TIndex)(unsafe.Pointer(pProbe)).FpNext
		}
		pProbe = v2
		iSortIdx = iSortIdx + 1
	}
	return rc
}

// C documentation
//
//	/*
//	** Add WhereLoop entries to handle OR terms.  This works for either
//	** btrees or virtual tables.
//	*/
func _whereLoopAddOr(tls *libc.TLS, pBuilder uintptr, mPrereq TBitmask, mUnusable TBitmask) (r int32) {
	bp := tls.Alloc(576)
	defer tls.Free(576)
	var i, iCur, j, once, rc int32
	var pItem, pNew, pOrTerm, pOrWC, pOrWCEnd, pTerm, pWC, pWCEnd, pWInfo uintptr
	var _ /* sCur at bp+484 */ TWhereOrSet
	var _ /* sPrev at bp+524 */ TWhereOrSet
	var _ /* sSubBuild at bp+412 */ TWhereLoopBuilder
	var _ /* sSum at bp+444 */ TWhereOrSet
	var _ /* tempWC at bp+0 */ TWhereClause
	_, _, _, _, _, _, _, _, _, _, _, _, _, _ = i, iCur, j, once, pItem, pNew, pOrTerm, pOrWC, pOrWCEnd, pTerm, pWC, pWCEnd, pWInfo, rc
	pWInfo = (*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FpWInfo
	rc = SQLITE_OK
	pWC = (*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FpWC
	pWCEnd = (*TWhereClause)(unsafe.Pointer(pWC)).Fa + uintptr((*TWhereClause)(unsafe.Pointer(pWC)).FnTerm)*48
	pNew = (*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FpNew
	libc.Xmemset(tls, bp+444, 0, uint32(40))
	pItem = (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpTabList + 8 + uintptr((*TWhereLoop)(unsafe.Pointer(pNew)).FiTab)*48
	iCur = (*TSrcItem)(unsafe.Pointer(pItem)).FiCursor
	/* The multi-index OR optimization does not work for RIGHT and FULL JOIN */
	if libc.Int32FromUint8((*TSrcItem)(unsafe.Pointer(pItem)).Ffg.Fjointype)&int32(JT_RIGHT) != 0 {
		return SQLITE_OK
	}
	pTerm = (*TWhereClause)(unsafe.Pointer(pWC)).Fa
	for {
		if !(pTerm < pWCEnd && rc == SQLITE_OK) {
			break
		}
		if libc.Int32FromUint16((*TWhereTerm)(unsafe.Pointer(pTerm)).FeOperator)&int32(WO_OR) != 0 && (*TWhereOrInfo)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(&(*TWhereTerm)(unsafe.Pointer(pTerm)).Fu)))).Findexable&(*TWhereLoop)(unsafe.Pointer(pNew)).FmaskSelf != uint64(0) {
			pOrWC = *(*uintptr)(unsafe.Pointer(&(*TWhereTerm)(unsafe.Pointer(pTerm)).Fu))
			pOrWCEnd = (*TWhereClause)(unsafe.Pointer(pOrWC)).Fa + uintptr((*TWhereClause)(unsafe.Pointer(pOrWC)).FnTerm)*48
			once = int32(1)
			**(**TWhereLoopBuilder)(__ccgo_up(bp + 412)) = **(**TWhereLoopBuilder)(__ccgo_up(pBuilder))
			(**(**TWhereLoopBuilder)(__ccgo_up(bp + 412))).FpOrSet = bp + 484
			pOrTerm = (*TWhereClause)(unsafe.Pointer(pOrWC)).Fa
			for {
				if !(pOrTerm < pOrWCEnd) {
					break
				}
				if libc.Int32FromUint16((*TWhereTerm)(unsafe.Pointer(pOrTerm)).FeOperator)&int32(WO_AND) != 0 {
					(**(**TWhereLoopBuilder)(__ccgo_up(bp + 412))).FpWC = *(*uintptr)(unsafe.Pointer(&(*TWhereTerm)(unsafe.Pointer(pOrTerm)).Fu))
				} else {
					if (*TWhereTerm)(unsafe.Pointer(pOrTerm)).FleftCursor == iCur {
						(**(**TWhereClause)(__ccgo_up(bp))).FpWInfo = (*TWhereClause)(unsafe.Pointer(pWC)).FpWInfo
						(**(**TWhereClause)(__ccgo_up(bp))).FpOuter = pWC
						(**(**TWhereClause)(__ccgo_up(bp))).Fop = uint8(TK_AND)
						(**(**TWhereClause)(__ccgo_up(bp))).FnTerm = int32(1)
						(**(**TWhereClause)(__ccgo_up(bp))).FnBase = int32(1)
						(**(**TWhereClause)(__ccgo_up(bp))).Fa = pOrTerm
						(**(**TWhereLoopBuilder)(__ccgo_up(bp + 412))).FpWC = bp
					} else {
						goto _2
					}
				}
				(**(**TWhereOrSet)(__ccgo_up(bp + 484))).Fn = uint16(0)
				if libc.Int32FromUint8((*TTable)(unsafe.Pointer((*TSrcItem)(unsafe.Pointer(pItem)).FpSTab)).FeTabType) == int32(TABTYP_VTAB) {
					rc = _whereLoopAddVirtual(tls, bp+412, mPrereq, mUnusable)
				} else {
					rc = _whereLoopAddBtree(tls, bp+412, mPrereq)
				}
				if rc == SQLITE_OK {
					rc = _whereLoopAddOr(tls, bp+412, mPrereq, mUnusable)
				}
				if libc.Int32FromUint16((**(**TWhereOrSet)(__ccgo_up(bp + 484))).Fn) == 0 {
					(**(**TWhereOrSet)(__ccgo_up(bp + 444))).Fn = uint16(0)
					break
				} else {
					if once != 0 {
						_whereOrMove(tls, bp+444, bp+484)
						once = 0
					} else {
						_whereOrMove(tls, bp+524, bp+444)
						(**(**TWhereOrSet)(__ccgo_up(bp + 444))).Fn = uint16(0)
						i = 0
						for {
							if !(i < libc.Int32FromUint16((**(**TWhereOrSet)(__ccgo_up(bp + 524))).Fn)) {
								break
							}
							j = 0
							for {
								if !(j < libc.Int32FromUint16((**(**TWhereOrSet)(__ccgo_up(bp + 484))).Fn)) {
									break
								}
								_whereOrInsert(tls, bp+444, (**(**TWhereOrCost)(__ccgo_up(bp + 524 + 4 + uintptr(i)*12))).Fprereq|(**(**TWhereOrCost)(__ccgo_up(bp + 484 + 4 + uintptr(j)*12))).Fprereq, _sqlite3LogEstAdd(tls, (**(**TWhereOrCost)(__ccgo_up(bp + 524 + 4 + uintptr(i)*12))).FrRun, (**(**TWhereOrCost)(__ccgo_up(bp + 484 + 4 + uintptr(j)*12))).FrRun), _sqlite3LogEstAdd(tls, (**(**TWhereOrCost)(__ccgo_up(bp + 524 + 4 + uintptr(i)*12))).FnOut, (**(**TWhereOrCost)(__ccgo_up(bp + 484 + 4 + uintptr(j)*12))).FnOut))
								goto _4
							_4:
								;
								j = j + 1
							}
							goto _3
						_3:
							;
							i = i + 1
						}
					}
				}
				goto _2
			_2:
				;
				pOrTerm += 48
			}
			(*TWhereLoop)(unsafe.Pointer(pNew)).FnLTerm = uint16(1)
			**(**uintptr)(__ccgo_up((*TWhereLoop)(unsafe.Pointer(pNew)).FaLTerm)) = pTerm
			(*TWhereLoop)(unsafe.Pointer(pNew)).FwsFlags = uint32(WHERE_MULTI_OR)
			(*TWhereLoop)(unsafe.Pointer(pNew)).FrSetup = 0
			(*TWhereLoop)(unsafe.Pointer(pNew)).FiSortIdx = uint8(0)
			libc.Xmemset(tls, pNew+24, 0, uint32(16))
			i = 0
			for {
				if !(rc == SQLITE_OK && i < libc.Int32FromUint16((**(**TWhereOrSet)(__ccgo_up(bp + 444))).Fn)) {
					break
				}
				/* TUNING: Currently sSum.a[i].rRun is set to the sum of the costs
				 ** of all sub-scans required by the OR-scan. However, due to rounding
				 ** errors, it may be that the cost of the OR-scan is equal to its
				 ** most expensive sub-scan. Add the smallest possible penalty
				 ** (equivalent to multiplying the cost by 1.07) to ensure that
				 ** this does not happen. Otherwise, for WHERE clauses such as the
				 ** following where there is an index on "y":
				 **
				 **     WHERE likelihood(x=?, 0.99) OR y=?
				 **
				 ** the planner may elect to "OR" together a full-table scan and an
				 ** index lookup. And other similarly odd results.  */
				(*TWhereLoop)(unsafe.Pointer(pNew)).FrRun = int16(int32((**(**TWhereOrCost)(__ccgo_up(bp + 444 + 4 + uintptr(i)*12))).FrRun) + int32(1))
				(*TWhereLoop)(unsafe.Pointer(pNew)).FnOut = (**(**TWhereOrCost)(__ccgo_up(bp + 444 + 4 + uintptr(i)*12))).FnOut
				(*TWhereLoop)(unsafe.Pointer(pNew)).Fprereq = (**(**TWhereOrCost)(__ccgo_up(bp + 444 + 4 + uintptr(i)*12))).Fprereq
				rc = _whereLoopInsert(tls, pBuilder, pNew)
				goto _5
			_5:
				;
				i = i + 1
			}
		}
		goto _1
	_1:
		;
		pTerm += 48
	}
	return rc
}

// C documentation
//
//	/* Attempt to omit tables from a join that do not affect the result.
//	** For a table to not affect the result, the following must be true:
//	**
//	**   1) The query must not be an aggregate.
//	**   2) The table must be the RHS of a LEFT JOIN.
//	**   3) Either the query must be DISTINCT, or else the ON or USING clause
//	**      must contain a constraint that limits the scan of the table to
//	**      at most a single row.
//	**   4) The table must not be referenced by any part of the query apart
//	**      from its own USING or ON clause.
//	**   5) The table must not have an inner-join ON or USING clause if there is
//	**      a RIGHT JOIN anywhere in the query.  Otherwise the ON/USING clause
//	**      might move from the right side to the left side of the RIGHT JOIN.
//	**      Note: Due to (2), this condition can only arise if the table is
//	**      the right-most table of a subquery that was flattened into the
//	**      main query and that subquery was the right-hand operand of an
//	**      inner join that held an ON or USING clause.
//	**   6) The ORDER BY clause has 63 or fewer terms
//	**   7) The omit-noop-join optimization is enabled.
//	**
//	** Items (1), (6), and (7) are checked by the caller.
//	**
//	** For example, given:
//	**
//	**     CREATE TABLE t1(ipk INTEGER PRIMARY KEY, v1);
//	**     CREATE TABLE t2(ipk INTEGER PRIMARY KEY, v2);
//	**     CREATE TABLE t3(ipk INTEGER PRIMARY KEY, v3);
//	**
//	** then table t2 can be omitted from the following:
//	**
//	**     SELECT v1, v3 FROM t1
//	**       LEFT JOIN t2 ON (t1.ipk=t2.ipk)
//	**       LEFT JOIN t3 ON (t1.ipk=t3.ipk)
//	**
//	** or from:
//	**
//	**     SELECT DISTINCT v1, v3 FROM t1
//	**       LEFT JOIN t2
//	**       LEFT JOIN t3 ON (t1.ipk=t3.ipk)
//	*/
func _whereOmitNoopJoin(tls *libc.TLS, pWInfo uintptr, notReady TBitmask) (r TBitmask) {
	var hasRightJoin, i, nByte int32
	var m1, tabUsed TBitmask
	var pEnd, pItem, pLoop, pTerm, v4 uintptr
	_, _, _, _, _, _, _, _, _, _ = hasRightJoin, i, m1, nByte, pEnd, pItem, pLoop, pTerm, tabUsed, v4
	/* Preconditions checked by the caller */
	/* These two preconditions checked by the caller combine to guarantee
	 ** condition (1) of the header comment */
	tabUsed = _sqlite3WhereExprListUsage(tls, pWInfo+488, (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpResultSet)
	if (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpOrderBy != 0 {
		tabUsed = tabUsed | _sqlite3WhereExprListUsage(tls, pWInfo+488, (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpOrderBy)
	}
	hasRightJoin = libc.BoolInt32(libc.Int32FromUint8((*(*TSrcItem)(unsafe.Pointer((*TWhereInfo)(unsafe.Pointer(pWInfo)).FpTabList + 8))).Ffg.Fjointype)&int32(JT_LTORJ) != 0)
	i = libc.Int32FromUint8((*TWhereInfo)(unsafe.Pointer(pWInfo)).FnLevel) - int32(1)
	for {
		if !(i >= int32(1)) {
			break
		}
		pLoop = (*(*TWhereLevel)(unsafe.Pointer(pWInfo + 752 + uintptr(i)*88))).FpWLoop
		pItem = (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpTabList + 8 + uintptr((*TWhereLoop)(unsafe.Pointer(pLoop)).FiTab)*48
		if libc.Int32FromUint8((*TSrcItem)(unsafe.Pointer(pItem)).Ffg.Fjointype)&(libc.Int32FromInt32(JT_LEFT)|libc.Int32FromInt32(JT_RIGHT)) != int32(JT_LEFT) {
			goto _1
		}
		if libc.Int32FromUint16((*TWhereInfo)(unsafe.Pointer(pWInfo)).FwctrlFlags)&int32(WHERE_WANT_DISTINCT) == 0 && (*TWhereLoop)(unsafe.Pointer(pLoop)).FwsFlags&uint32(WHERE_ONEROW) == uint32(0) {
			goto _1
		}
		if tabUsed&(*TWhereLoop)(unsafe.Pointer(pLoop)).FmaskSelf != uint64(0) {
			goto _1
		}
		pEnd = (*TWhereInfo)(unsafe.Pointer(pWInfo)).FsWC.Fa + uintptr((*TWhereInfo)(unsafe.Pointer(pWInfo)).FsWC.FnTerm)*48
		pTerm = (*TWhereInfo)(unsafe.Pointer(pWInfo)).FsWC.Fa
		for {
			if !(pTerm < pEnd) {
				break
			}
			if (*TWhereTerm)(unsafe.Pointer(pTerm)).FprereqAll&(*TWhereLoop)(unsafe.Pointer(pLoop)).FmaskSelf != uint64(0) {
				if !((*TExpr)(unsafe.Pointer((*TWhereTerm)(unsafe.Pointer(pTerm)).FpExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_OuterON)) != libc.Uint32FromInt32(0)) || *(*int32)(unsafe.Pointer((*TWhereTerm)(unsafe.Pointer(pTerm)).FpExpr + 36)) != (*TSrcItem)(unsafe.Pointer(pItem)).FiCursor {
					break
				}
			}
			if hasRightJoin != 0 && (*TExpr)(unsafe.Pointer((*TWhereTerm)(unsafe.Pointer(pTerm)).FpExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_InnerON)) != uint32(0) && *(*int32)(unsafe.Pointer((*TWhereTerm)(unsafe.Pointer(pTerm)).FpExpr + 36)) == (*TSrcItem)(unsafe.Pointer(pItem)).FiCursor {
				break /* restriction (5) */
			}
			goto _2
		_2:
			;
			pTerm += 48
		}
		if pTerm < pEnd {
			goto _1
		}
		m1 = libc.Uint64FromInt32(1)<<i - uint64(1)
		(*TWhereInfo)(unsafe.Pointer(pWInfo)).FrevMask = m1&(*TWhereInfo)(unsafe.Pointer(pWInfo)).FrevMask | (*TWhereInfo)(unsafe.Pointer(pWInfo)).FrevMask>>libc.Int32FromInt32(1) & ^m1
		notReady = notReady & ^(*TWhereLoop)(unsafe.Pointer(pLoop)).FmaskSelf
		pTerm = (*TWhereInfo)(unsafe.Pointer(pWInfo)).FsWC.Fa
		for {
			if !(pTerm < pEnd) {
				break
			}
			if (*TWhereTerm)(unsafe.Pointer(pTerm)).FprereqAll&(*TWhereLoop)(unsafe.Pointer(pLoop)).FmaskSelf != uint64(0) {
				v4 = pTerm + 10
				*(*Tu16)(unsafe.Pointer(v4)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v4))) | libc.Int32FromInt32(TERM_CODED))
				(*TWhereTerm)(unsafe.Pointer(pTerm)).FprereqAll = uint64(0)
			}
			goto _3
		_3:
			;
			pTerm += 48
		}
		if i != libc.Int32FromUint8((*TWhereInfo)(unsafe.Pointer(pWInfo)).FnLevel)-int32(1) {
			nByte = libc.Int32FromUint32(libc.Uint32FromInt32(libc.Int32FromUint8((*TWhereInfo)(unsafe.Pointer(pWInfo)).FnLevel)-libc.Int32FromInt32(1)-i) * uint32(88))
			libc.Xmemmove(tls, pWInfo+752+uintptr(i)*88, pWInfo+752+uintptr(i+int32(1))*88, libc.Uint32FromInt32(nByte))
		}
		(*TWhereInfo)(unsafe.Pointer(pWInfo)).FnLevel = (*TWhereInfo)(unsafe.Pointer(pWInfo)).FnLevel - 1
		goto _1
	_1:
		;
		i = i - 1
	}
	return notReady
}

// C documentation
//
//	/*
//	** Try to insert a new prerequisite/cost entry into the WhereOrSet pSet.
//	**
//	** The new entry might overwrite an existing entry, or it might be
//	** appended, or it might be discarded.  Do whatever is the right thing
//	** so that pSet keeps the N_OR_COST best entries seen so far.
//	*/
func _whereOrInsert(tls *libc.TLS, pSet uintptr, prereq TBitmask, rRun TLogEst, nOut TLogEst) (r int32) {
	var i, v2 Tu16
	var p, v3 uintptr
	_, _, _, _ = i, p, v2, v3
	i = (*TWhereOrSet)(unsafe.Pointer(pSet)).Fn
	p = pSet + 4
	for {
		if !(libc.Int32FromUint16(i) > 0) {
			break
		}
		if int32(rRun) <= int32((*TWhereOrCost)(unsafe.Pointer(p)).FrRun) && prereq&(*TWhereOrCost)(unsafe.Pointer(p)).Fprereq == prereq {
			goto whereOrInsert_done
		}
		if int32((*TWhereOrCost)(unsafe.Pointer(p)).FrRun) <= int32(rRun) && (*TWhereOrCost)(unsafe.Pointer(p)).Fprereq&prereq == (*TWhereOrCost)(unsafe.Pointer(p)).Fprereq {
			return 0
		}
		goto _1
	_1:
		;
		i = i - 1
		p += 12
	}
	if libc.Int32FromUint16((*TWhereOrSet)(unsafe.Pointer(pSet)).Fn) < int32(N_OR_COST) {
		v3 = pSet
		v2 = *(*Tu16)(unsafe.Pointer(v3))
		*(*Tu16)(unsafe.Pointer(v3)) = *(*Tu16)(unsafe.Pointer(v3)) + 1
		p = pSet + 4 + uintptr(v2)*12
		(*TWhereOrCost)(unsafe.Pointer(p)).FnOut = nOut
	} else {
		p = pSet + 4
		i = uint16(1)
		for {
			if !(libc.Int32FromUint16(i) < libc.Int32FromUint16((*TWhereOrSet)(unsafe.Pointer(pSet)).Fn)) {
				break
			}
			if int32((*TWhereOrCost)(unsafe.Pointer(p)).FrRun) > int32((**(**TWhereOrCost)(__ccgo_up(pSet + 4 + uintptr(i)*12))).FrRun) {
				p = pSet + 4 + uintptr(i)*12
			}
			goto _4
		_4:
			;
			i = i + 1
		}
		if int32((*TWhereOrCost)(unsafe.Pointer(p)).FrRun) <= int32(rRun) {
			return 0
		}
	}
	goto whereOrInsert_done
whereOrInsert_done:
	;
	(*TWhereOrCost)(unsafe.Pointer(p)).Fprereq = prereq
	(*TWhereOrCost)(unsafe.Pointer(p)).FrRun = rRun
	if int32((*TWhereOrCost)(unsafe.Pointer(p)).FnOut) > int32(nOut) {
		(*TWhereOrCost)(unsafe.Pointer(p)).FnOut = nOut
	}
	return int32(1)
}

// C documentation
//
//	/*
//	** Move the content of pSrc into pDest
//	*/
func _whereOrMove(tls *libc.TLS, pDest uintptr, pSrc uintptr) {
	(*TWhereOrSet)(unsafe.Pointer(pDest)).Fn = (*TWhereOrSet)(unsafe.Pointer(pSrc)).Fn
	libc.Xmemcpy(tls, pDest+4, pSrc+4, uint32((*TWhereOrSet)(unsafe.Pointer(pDest)).Fn)*uint32(12))
}

// C documentation
//
//	/*
//	** This function is called for a partial index - one with a WHERE clause - in
//	** two scenarios. In both cases, it determines whether or not the WHERE
//	** clause on the index implies that a column of the table may be safely
//	** replaced by a constant expression. For example, in the following
//	** SELECT:
//	**
//	**   CREATE INDEX i1 ON t1(b, c) WHERE a=<expr>;
//	**   SELECT a, b, c FROM t1 WHERE a=<expr> AND b=?;
//	**
//	** The "a" in the select-list may be replaced by <expr>, iff:
//	**
//	**    (a) <expr> is a constant expression, and
//	**    (b) The (a=<expr>) comparison uses the BINARY collation sequence, and
//	**    (c) Column "a" has an affinity other than NONE or BLOB.
//	**
//	** If argument pItem is NULL, then pMask must not be NULL. In this case this
//	** function is being called as part of determining whether or not pIdx
//	** is a covering index. This function clears any bits in (*pMask)
//	** corresponding to columns that may be replaced by constants as described
//	** above.
//	**
//	** Otherwise, if pItem is not NULL, then this function is being called
//	** as part of coding a loop that uses index pIdx. In this case, add entries
//	** to the Parse.pIdxPartExpr list for each column that can be replaced
//	** by a constant.
//	*/
func _wherePartIdxExpr(tls *libc.TLS, pParse uintptr, pIdx uintptr, pPart uintptr, pMask uintptr, iIdxCur int32, pItem uintptr) {
	var aff Tu8
	var bNullRow int32
	var db, p, pArg, pLeft, pRight uintptr
	_, _, _, _, _, _, _ = aff, bNullRow, db, p, pArg, pLeft, pRight
	if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pPart)).Fop) == int32(TK_AND) {
		_wherePartIdxExpr(tls, pParse, pIdx, (*TExpr)(unsafe.Pointer(pPart)).FpRight, pMask, iIdxCur, pItem)
		pPart = (*TExpr)(unsafe.Pointer(pPart)).FpLeft
	}
	if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pPart)).Fop) == int32(TK_EQ) || libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pPart)).Fop) == int32(TK_IS) {
		pLeft = (*TExpr)(unsafe.Pointer(pPart)).FpLeft
		pRight = (*TExpr)(unsafe.Pointer(pPart)).FpRight
		if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pLeft)).Fop) != int32(TK_COLUMN) {
			return
		}
		if !(_sqlite3ExprIsConstant(tls, uintptr(0), pRight) != 0) {
			return
		}
		if !(_sqlite3IsBinary(tls, _sqlite3ExprCompareCollSeq(tls, pParse, pPart)) != 0) {
			return
		}
		if int32((*TExpr)(unsafe.Pointer(pLeft)).FiColumn) < 0 {
			return
		}
		aff = libc.Uint8FromInt8((**(**TColumn)(__ccgo_up((*TTable)(unsafe.Pointer((*TIndex)(unsafe.Pointer(pIdx)).FpTable)).FaCol + uintptr((*TExpr)(unsafe.Pointer(pLeft)).FiColumn)*12))).Faffinity)
		if libc.Int32FromUint8(aff) >= int32(SQLITE_AFF_TEXT) {
			if pItem != 0 {
				db = (*TParse)(unsafe.Pointer(pParse)).Fdb
				p = _sqlite3DbMallocRaw(tls, db, uint64(24))
				if p != 0 {
					bNullRow = libc.BoolInt32(libc.Int32FromUint8((*TSrcItem)(unsafe.Pointer(pItem)).Ffg.Fjointype)&(libc.Int32FromInt32(JT_LEFT)|libc.Int32FromInt32(JT_LTORJ)) != 0)
					(*TIndexedExpr)(unsafe.Pointer(p)).FpExpr = _sqlite3ExprDup(tls, db, pRight, 0)
					(*TIndexedExpr)(unsafe.Pointer(p)).FiDataCur = (*TSrcItem)(unsafe.Pointer(pItem)).FiCursor
					(*TIndexedExpr)(unsafe.Pointer(p)).FiIdxCur = iIdxCur
					(*TIndexedExpr)(unsafe.Pointer(p)).FiIdxCol = int32((*TExpr)(unsafe.Pointer(pLeft)).FiColumn)
					(*TIndexedExpr)(unsafe.Pointer(p)).FbMaybeNullRow = libc.Uint8FromInt32(bNullRow)
					(*TIndexedExpr)(unsafe.Pointer(p)).FpIENext = (*TParse)(unsafe.Pointer(pParse)).FpIdxPartExpr
					(*TIndexedExpr)(unsafe.Pointer(p)).Faff = aff
					(*TParse)(unsafe.Pointer(pParse)).FpIdxPartExpr = p
					if (*TIndexedExpr)(unsafe.Pointer(p)).FpIENext == uintptr(0) {
						pArg = pParse + 80
						_sqlite3ParserAddCleanup(tls, pParse, __ccgo_fp(_whereIndexedExprCleanup), pArg)
					}
				}
			} else {
				if int32((*TExpr)(unsafe.Pointer(pLeft)).FiColumn) < libc.Int32FromUint32(libc.Uint32FromInt64(8)*libc.Uint32FromInt32(8))-libc.Int32FromInt32(1) {
					**(**TBitmask)(__ccgo_up(pMask)) &= ^(libc.Uint64FromInt32(1) << (*TExpr)(unsafe.Pointer(pLeft)).FiColumn)
				}
			}
		}
	}
}

// C documentation
//
//	/*
//	** Examine a WherePath (with the addition of the extra WhereLoop of the 6th
//	** parameters) to see if it outputs rows in the requested ORDER BY
//	** (or GROUP BY) without requiring a separate sort operation.  Return N:
//	**
//	**   N>0:   N terms of the ORDER BY clause are satisfied
//	**   N==0:  No terms of the ORDER BY clause are satisfied
//	**   N<0:   Unknown yet how many terms of ORDER BY might be satisfied.
//	**
//	** Note that processing for WHERE_GROUPBY and WHERE_DISTINCTBY is not as
//	** strict.  With GROUP BY and DISTINCT the only requirement is that
//	** equivalent rows appear immediately adjacent to one another.  GROUP BY
//	** and DISTINCT do not require rows to appear in any particular order as long
//	** as equivalent rows are grouped together.  Thus for GROUP BY and DISTINCT
//	** the pOrderBy terms can be matched in any order.  With ORDER BY, the
//	** pOrderBy terms must be matched in strict left-to-right order.
//	*/
func _wherePathSatisfiesOrderBy(tls *libc.TLS, pWInfo uintptr, pOrderBy uintptr, pPath uintptr, wctrlFlags Tu16, nLoop Tu16, pLast uintptr, pRevMask uintptr) (r Ti8) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var bOnce, distinctColumns, isMatch, isOrderDistinct, rev, revIdx, revSet, v5 Tu8
	var db, p, pColl, pColl1, pColl2, pIndex, pIxExpr, pLoop, pOBExpr, pParse, pTerm, pX, v4 uintptr
	var eOp, eqOpMask, nColumn, nKeyCol, nOrderBy Tu16
	var i, iColumn, iCur, iLoop, j int32
	var m, mTerm, obDone, orderDistinctMask, ready TBitmask
	var v11 uint64
	var _ /* obSat at bp+0 */ TBitmask
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = bOnce, db, distinctColumns, eOp, eqOpMask, i, iColumn, iCur, iLoop, isMatch, isOrderDistinct, j, m, mTerm, nColumn, nKeyCol, nOrderBy, obDone, orderDistinctMask, p, pColl, pColl1, pColl2, pIndex, pIxExpr, pLoop, pOBExpr, pParse, pTerm, pX, ready, rev, revIdx, revSet, v11, v4, v5 /* A column number within table iCur */
	pLoop = uintptr(0)                                                                                                                                                                                                                                                                                                                                                                                      /* The index associated with pLoop */
	db = (*TParse)(unsafe.Pointer((*TWhereInfo)(unsafe.Pointer(pWInfo)).FpParse)).Fdb                                                                                                                                                                                                                                                                                                                       /* Database connection */
	**(**TBitmask)(__ccgo_up(bp)) = uint64(0)                                                                                                                                                                                                                                                                                                                                                               /* Mask of inner loops */
	/*
	 ** We say the WhereLoop is "one-row" if it generates no more than one
	 ** row of output.  A WhereLoop is one-row if all of the following are true:
	 **  (a) All index columns match with WHERE_COLUMN_EQ.
	 **  (b) The index is unique
	 ** Any WhereLoop with an WHERE_COLUMN_EQ constraint on the rowid is one-row.
	 ** Every one-row WhereLoop will have the WHERE_ONEROW bit set in wsFlags.
	 **
	 ** We say the WhereLoop is "order-distinct" if the set of columns from
	 ** that WhereLoop that are in the ORDER BY clause are different for every
	 ** row of the WhereLoop.  Every one-row WhereLoop is automatically
	 ** order-distinct.   A WhereLoop that has no columns in the ORDER BY clause
	 ** is not order-distinct. To be order-distinct is not quite the same as being
	 ** UNIQUE since a UNIQUE column or index can have multiple rows that
	 ** are NULL and NULL values are equivalent for the purpose of order-distinct.
	 ** To be order-distinct, the columns must be UNIQUE and NOT NULL.
	 **
	 ** The rowid for a table is always UNIQUE and NOT NULL so whenever the
	 ** rowid appears in the ORDER BY clause, the corresponding WhereLoop is
	 ** automatically order-distinct.
	 */
	if nLoop != 0 && (*Tsqlite3)(unsafe.Pointer(db)).FdbOptFlags&libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_OrderByIdxJoin)) != uint32(0) {
		return 0
	}
	nOrderBy = libc.Uint16FromInt32((*TExprList)(unsafe.Pointer(pOrderBy)).FnExpr)
	if libc.Int32FromUint16(nOrderBy) > libc.Int32FromUint32(libc.Uint32FromInt64(8)*libc.Uint32FromInt32(8))-libc.Int32FromInt32(1) {
		return 0
	} /* Cannot optimize overly large ORDER BYs */
	isOrderDistinct = uint8(1)
	obDone = libc.Uint64FromInt32(1)<<nOrderBy - uint64(1)
	orderDistinctMask = uint64(0)
	ready = uint64(0)
	eqOpMask = libc.Uint16FromInt32(libc.Int32FromInt32(WO_EQ) | libc.Int32FromInt32(WO_IS) | libc.Int32FromInt32(WO_ISNULL))
	if libc.Int32FromUint16(wctrlFlags)&(libc.Int32FromInt32(WHERE_ORDERBY_LIMIT)|libc.Int32FromInt32(WHERE_ORDERBY_MAX)|libc.Int32FromInt32(WHERE_ORDERBY_MIN)) != 0 {
		eqOpMask = libc.Uint16FromInt32(int32(eqOpMask) | libc.Int32FromInt32(WO_IN))
	}
	iLoop = 0
	for {
		if !(isOrderDistinct != 0 && **(**TBitmask)(__ccgo_up(bp)) < obDone && iLoop <= libc.Int32FromUint16(nLoop)) {
			break
		}
		if iLoop > 0 {
			ready = ready | (*TWhereLoop)(unsafe.Pointer(pLoop)).FmaskSelf
		}
		if iLoop < libc.Int32FromUint16(nLoop) {
			pLoop = **(**uintptr)(__ccgo_up((*TWherePath)(unsafe.Pointer(pPath)).FaLoop + uintptr(iLoop)*4))
			if libc.Int32FromUint16(wctrlFlags)&int32(WHERE_ORDERBY_LIMIT) != 0 {
				goto _1
			}
		} else {
			pLoop = pLast
		}
		if (*TWhereLoop)(unsafe.Pointer(pLoop)).FwsFlags&uint32(WHERE_VIRTUALTABLE) != 0 {
			if (*(*struct {
				FidxNum    int32
				F__ccgo4   uint8
				FisOrdered Ti8
				FomitMask  Tu16
				FidxStr    uintptr
				FmHandleIn Tu32
			})(unsafe.Pointer(pLoop + 24))).FisOrdered != 0 && (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpOrderBy == pOrderBy {
				**(**TBitmask)(__ccgo_up(bp)) = obDone
			} else {
				/* No further ORDER BY terms may be matched. So this call should
				 ** return >=0, not -1. Clear isOrderDistinct to ensure it does so. */
				isOrderDistinct = uint8(0)
			}
			break
		}
		iCur = (*(*TSrcItem)(unsafe.Pointer((*TWhereInfo)(unsafe.Pointer(pWInfo)).FpTabList + 8 + uintptr((*TWhereLoop)(unsafe.Pointer(pLoop)).FiTab)*48))).FiCursor
		/* Mark off any ORDER BY term X that is a column in the table of
		 ** the current loop for which there is term in the WHERE
		 ** clause of the form X IS NULL or X=? that reference only outer
		 ** loops.
		 */
		i = 0
		for {
			if !(i < libc.Int32FromUint16(nOrderBy)) {
				break
			}
			if libc.Uint64FromInt32(1)<<i&**(**TBitmask)(__ccgo_up(bp)) != 0 {
				goto _2
			}
			pOBExpr = _sqlite3ExprSkipCollateAndLikely(tls, (*(*TExprList_item)(unsafe.Pointer(pOrderBy + 8 + uintptr(i)*20))).FpExpr)
			if pOBExpr == uintptr(0) {
				goto _2
			}
			if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pOBExpr)).Fop) != int32(TK_COLUMN) && libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pOBExpr)).Fop) != int32(TK_AGG_COLUMN) {
				goto _2
			}
			if (*TExpr)(unsafe.Pointer(pOBExpr)).FiTable != iCur {
				goto _2
			}
			pTerm = _sqlite3WhereFindTerm(tls, pWInfo+76, iCur, int32((*TExpr)(unsafe.Pointer(pOBExpr)).FiColumn), ^ready, uint32(eqOpMask), uintptr(0))
			if pTerm == uintptr(0) {
				goto _2
			}
			if libc.Int32FromUint16((*TWhereTerm)(unsafe.Pointer(pTerm)).FeOperator) == int32(WO_IN) {
				/* IN terms are only valid for sorting in the ORDER BY LIMIT
				 ** optimization, and then only if they are actually used
				 ** by the query plan */
				j = 0
				for {
					if !(j < libc.Int32FromUint16((*TWhereLoop)(unsafe.Pointer(pLoop)).FnLTerm) && pTerm != **(**uintptr)(__ccgo_up((*TWhereLoop)(unsafe.Pointer(pLoop)).FaLTerm + uintptr(j)*4))) {
						break
					}
					goto _3
				_3:
					;
					j = j + 1
				}
				if j >= libc.Int32FromUint16((*TWhereLoop)(unsafe.Pointer(pLoop)).FnLTerm) {
					goto _2
				}
			}
			if libc.Int32FromUint16((*TWhereTerm)(unsafe.Pointer(pTerm)).FeOperator)&(libc.Int32FromInt32(WO_EQ)|libc.Int32FromInt32(WO_IS)) != 0 && int32((*TExpr)(unsafe.Pointer(pOBExpr)).FiColumn) >= 0 {
				pParse = (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpParse
				pColl1 = _sqlite3ExprNNCollSeq(tls, pParse, (*(*TExprList_item)(unsafe.Pointer(pOrderBy + 8 + uintptr(i)*20))).FpExpr)
				pColl2 = _sqlite3ExprCompareCollSeq(tls, pParse, (*TWhereTerm)(unsafe.Pointer(pTerm)).FpExpr)
				if pColl2 == uintptr(0) || _sqlite3StrICmp(tls, (*TCollSeq)(unsafe.Pointer(pColl1)).FzName, (*TCollSeq)(unsafe.Pointer(pColl2)).FzName) != 0 {
					goto _2
				}
			}
			**(**TBitmask)(__ccgo_up(bp)) = **(**TBitmask)(__ccgo_up(bp)) | libc.Uint64FromInt32(1)<<i
			goto _2
		_2:
			;
			i = i + 1
		}
		if (*TWhereLoop)(unsafe.Pointer(pLoop)).FwsFlags&uint32(WHERE_ONEROW) == uint32(0) {
			if (*TWhereLoop)(unsafe.Pointer(pLoop)).FwsFlags&uint32(WHERE_IPK) != 0 {
				if (*(*struct {
					FnEq          Tu16
					FnBtm         Tu16
					FnTop         Tu16
					FnDistinctCol Tu16
					FpIndex       uintptr
					FpOrderBy     uintptr
				})(unsafe.Pointer(pLoop + 24))).FpOrderBy != 0 && (*Tsqlite3)(unsafe.Pointer(db)).FdbOptFlags&libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_OrderBySubq)) == uint32(0) && _wherePathMatchSubqueryOB(tls, pWInfo, pLoop, iLoop, iCur, pOrderBy, pRevMask, bp) != 0 {
					nColumn = uint16(0)
					isOrderDistinct = uint8(0)
				} else {
					nColumn = uint16(1)
				}
				pIndex = uintptr(0)
				nKeyCol = uint16(0)
			} else {
				v4 = (*(*struct {
					FnEq          Tu16
					FnBtm         Tu16
					FnTop         Tu16
					FnDistinctCol Tu16
					FpIndex       uintptr
					FpOrderBy     uintptr
				})(unsafe.Pointer(pLoop + 24))).FpIndex
				pIndex = v4
				if v4 == uintptr(0) || int32(uint32(*(*uint16)(unsafe.Pointer(pIndex + 56))&0x4>>2)) != 0 {
					return 0
				} else {
					nKeyCol = (*TIndex)(unsafe.Pointer(pIndex)).FnKeyCol
					nColumn = (*TIndex)(unsafe.Pointer(pIndex)).FnColumn
					/* All relevant terms of the index must also be non-NULL in order
					 ** for isOrderDistinct to be true.  So the isOrderDistinct value
					 ** computed here might be a false positive.  Corrections will be
					 ** made at tag-20210426-1 below */
					isOrderDistinct = libc.BoolUint8(libc.Int32FromUint8((*TIndex)(unsafe.Pointer(pIndex)).FonError) != OE_None && (*TWhereLoop)(unsafe.Pointer(pLoop)).FwsFlags&uint32(WHERE_SKIPSCAN) == uint32(0))
				}
			}
			/* Loop through all columns of the index and deal with the ones
			 ** that are not constrained by == or IN.
			 */
			v5 = libc.Uint8FromInt32(0)
			revSet = v5
			rev = v5
			distinctColumns = uint8(0)
			j = 0
			for {
				if !(j < libc.Int32FromUint16(nColumn)) {
					break
				}
				bOnce = uint8(1) /* True to run the ORDER BY search loop */
				if j < libc.Int32FromUint16((*(*struct {
					FnEq          Tu16
					FnBtm         Tu16
					FnTop         Tu16
					FnDistinctCol Tu16
					FpIndex       uintptr
					FpOrderBy     uintptr
				})(unsafe.Pointer(pLoop + 24))).FnEq) && j >= libc.Int32FromUint16((*TWhereLoop)(unsafe.Pointer(pLoop)).FnSkip) {
					eOp = (*TWhereTerm)(unsafe.Pointer(**(**uintptr)(__ccgo_up((*TWhereLoop)(unsafe.Pointer(pLoop)).FaLTerm + uintptr(j)*4)))).FeOperator
					/* Skip over == and IS and ISNULL terms.  (Also skip IN terms when
					 ** doing WHERE_ORDERBY_LIMIT processing).  Except, IS and ISNULL
					 ** terms imply that the index is not UNIQUE NOT NULL in which case
					 ** the loop need to be marked as not order-distinct because it can
					 ** have repeated NULL rows.
					 **
					 ** If the current term is a column of an ((?,?) IN (SELECT...))
					 ** expression for which the SELECT returns more than one column,
					 ** check that it is the only column used by this loop. Otherwise,
					 ** if it is one of two or more, none of the columns can be
					 ** considered to match an ORDER BY term.
					 */
					if libc.Int32FromUint16(eOp)&libc.Int32FromUint16(eqOpMask) != 0 {
						if libc.Int32FromUint16(eOp)&(libc.Int32FromInt32(WO_ISNULL)|libc.Int32FromInt32(WO_IS)) != 0 {
							isOrderDistinct = uint8(0)
						}
						goto _6
					} else {
						if libc.Int32FromUint16(eOp)&int32(WO_IN) != 0 {
							/* ALWAYS() justification: eOp is an equality operator due to the
							 ** j<pLoop->u.btree.nEq constraint above.  Any equality other
							 ** than WO_IN is captured by the previous "if".  So this one
							 ** always has to be WO_IN. */
							pX = (*TWhereTerm)(unsafe.Pointer(**(**uintptr)(__ccgo_up((*TWhereLoop)(unsafe.Pointer(pLoop)).FaLTerm + uintptr(j)*4)))).FpExpr
							i = j + int32(1)
							for {
								if !(i < libc.Int32FromUint16((*(*struct {
									FnEq          Tu16
									FnBtm         Tu16
									FnTop         Tu16
									FnDistinctCol Tu16
									FpIndex       uintptr
									FpOrderBy     uintptr
								})(unsafe.Pointer(pLoop + 24))).FnEq)) {
									break
								}
								if (*TWhereTerm)(unsafe.Pointer(**(**uintptr)(__ccgo_up((*TWhereLoop)(unsafe.Pointer(pLoop)).FaLTerm + uintptr(i)*4)))).FpExpr == pX {
									bOnce = uint8(0)
									break
								}
								goto _7
							_7:
								;
								i = i + 1
							}
						}
					}
				}
				/* Get the column number in the table (iColumn) and sort order
				 ** (revIdx) for the j-th column of the index.
				 */
				if pIndex != 0 {
					iColumn = int32(**(**Ti16)(__ccgo_up((*TIndex)(unsafe.Pointer(pIndex)).FaiColumn + uintptr(j)*2)))
					revIdx = libc.Uint8FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TIndex)(unsafe.Pointer(pIndex)).FaSortOrder + uintptr(j)))) & int32(KEYINFO_ORDER_DESC))
					if iColumn == int32((*TTable)(unsafe.Pointer((*TIndex)(unsafe.Pointer(pIndex)).FpTable)).FiPKey) {
						iColumn = -int32(1)
					}
				} else {
					iColumn = -int32(1)
					revIdx = uint8(0)
				}
				/* An unconstrained column that might be NULL means that this
				 ** WhereLoop is not well-ordered.  tag-20210426-1
				 */
				if isOrderDistinct != 0 {
					if iColumn >= 0 && j >= libc.Int32FromUint16((*(*struct {
						FnEq          Tu16
						FnBtm         Tu16
						FnTop         Tu16
						FnDistinctCol Tu16
						FpIndex       uintptr
						FpOrderBy     uintptr
					})(unsafe.Pointer(pLoop + 24))).FnEq) && int32(uint32(*(*uint8)(unsafe.Pointer((*TTable)(unsafe.Pointer((*TIndex)(unsafe.Pointer(pIndex)).FpTable)).FaCol + uintptr(iColumn)*12 + 4))&0xf>>0)) == 0 {
						isOrderDistinct = uint8(0)
					}
					if iColumn == -int32(2) {
						isOrderDistinct = uint8(0)
					}
				}
				/* Find the ORDER BY term that corresponds to the j-th column
				 ** of the index and mark that ORDER BY term having been satisfied.
				 */
				isMatch = uint8(0)
				i = 0
				for {
					if !(bOnce != 0 && i < libc.Int32FromUint16(nOrderBy)) {
						break
					}
					if libc.Uint64FromInt32(1)<<i&**(**TBitmask)(__ccgo_up(bp)) != 0 {
						goto _8
					}
					pOBExpr = _sqlite3ExprSkipCollateAndLikely(tls, (*(*TExprList_item)(unsafe.Pointer(pOrderBy + 8 + uintptr(i)*20))).FpExpr)
					if pOBExpr == uintptr(0) {
						goto _8
					}
					if libc.Int32FromUint16(wctrlFlags)&(libc.Int32FromInt32(WHERE_GROUPBY)|libc.Int32FromInt32(WHERE_DISTINCTBY)) == 0 {
						bOnce = uint8(0)
					}
					if iColumn >= -int32(1) {
						if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pOBExpr)).Fop) != int32(TK_COLUMN) && libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pOBExpr)).Fop) != int32(TK_AGG_COLUMN) {
							goto _8
						}
						if (*TExpr)(unsafe.Pointer(pOBExpr)).FiTable != iCur {
							goto _8
						}
						if int32((*TExpr)(unsafe.Pointer(pOBExpr)).FiColumn) != iColumn {
							goto _8
						}
					} else {
						pIxExpr = (*(*TExprList_item)(unsafe.Pointer((*TIndex)(unsafe.Pointer(pIndex)).FaColExpr + 8 + uintptr(j)*20))).FpExpr
						if _sqlite3ExprCompareSkip(tls, pOBExpr, pIxExpr, iCur) != 0 {
							goto _8
						}
					}
					if iColumn != -int32(1) {
						pColl = _sqlite3ExprNNCollSeq(tls, (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpParse, (*(*TExprList_item)(unsafe.Pointer(pOrderBy + 8 + uintptr(i)*20))).FpExpr)
						if _sqlite3StrICmp(tls, (*TCollSeq)(unsafe.Pointer(pColl)).FzName, **(**uintptr)(__ccgo_up((*TIndex)(unsafe.Pointer(pIndex)).FazColl + uintptr(j)*4))) != 0 {
							goto _8
						}
					}
					if libc.Int32FromUint16(wctrlFlags)&int32(WHERE_DISTINCTBY) != 0 {
						(*(*struct {
							FnEq          Tu16
							FnBtm         Tu16
							FnTop         Tu16
							FnDistinctCol Tu16
							FpIndex       uintptr
							FpOrderBy     uintptr
						})(unsafe.Pointer(pLoop + 24))).FnDistinctCol = libc.Uint16FromInt32(j + int32(1))
					}
					isMatch = uint8(1)
					break
					goto _8
				_8:
					;
					i = i + 1
				}
				if isMatch != 0 && libc.Int32FromUint16(wctrlFlags)&int32(WHERE_GROUPBY) == 0 {
					/* Make sure the sort order is compatible in an ORDER BY clause.
					 ** Sort order is irrelevant for a GROUP BY clause. */
					if revSet != 0 {
						if libc.Int32FromUint8(rev)^libc.Int32FromUint8(revIdx) != libc.Int32FromUint8((*(*TExprList_item)(unsafe.Pointer(pOrderBy + 8 + uintptr(i)*20))).Ffg.FsortFlags)&int32(KEYINFO_ORDER_DESC) {
							isMatch = uint8(0)
						}
					} else {
						rev = libc.Uint8FromInt32(libc.Int32FromUint8(revIdx) ^ libc.Int32FromUint8((*(*TExprList_item)(unsafe.Pointer(pOrderBy + 8 + uintptr(i)*20))).Ffg.FsortFlags)&int32(KEYINFO_ORDER_DESC))
						if rev != 0 {
							**(**TBitmask)(__ccgo_up(pRevMask)) |= libc.Uint64FromInt32(1) << iLoop
						}
						revSet = uint8(1)
					}
				}
				if isMatch != 0 && libc.Int32FromUint8((*(*TExprList_item)(unsafe.Pointer(pOrderBy + 8 + uintptr(i)*20))).Ffg.FsortFlags)&int32(KEYINFO_ORDER_BIGNULL) != 0 {
					if j == libc.Int32FromUint16((*(*struct {
						FnEq          Tu16
						FnBtm         Tu16
						FnTop         Tu16
						FnDistinctCol Tu16
						FpIndex       uintptr
						FpOrderBy     uintptr
					})(unsafe.Pointer(pLoop + 24))).FnEq) {
						**(**Tu32)(__ccgo_up(pLoop + 40)) |= uint32(WHERE_BIGNULL_SORT)
					} else {
						isMatch = uint8(0)
					}
				}
				if isMatch != 0 {
					if iColumn == -int32(1) {
						distinctColumns = uint8(1)
					}
					**(**TBitmask)(__ccgo_up(bp)) = **(**TBitmask)(__ccgo_up(bp)) | libc.Uint64FromInt32(1)<<i
				} else {
					/* No match found */
					if j == 0 || j < libc.Int32FromUint16(nKeyCol) {
						isOrderDistinct = uint8(0)
					}
					break
				}
				goto _6
			_6:
				;
				j = j + 1
			} /* end Loop over all index columns */
			if distinctColumns != 0 {
				isOrderDistinct = uint8(1)
			}
		} /* end-if not one-row */
		/* Mark off any other ORDER BY terms that reference pLoop */
		if isOrderDistinct != 0 {
			orderDistinctMask = orderDistinctMask | (*TWhereLoop)(unsafe.Pointer(pLoop)).FmaskSelf
			i = 0
			for {
				if !(i < libc.Int32FromUint16(nOrderBy)) {
					break
				}
				if libc.Uint64FromInt32(1)<<i&**(**TBitmask)(__ccgo_up(bp)) != 0 {
					goto _9
				}
				p = (*(*TExprList_item)(unsafe.Pointer(pOrderBy + 8 + uintptr(i)*20))).FpExpr
				mTerm = _sqlite3WhereExprUsage(tls, pWInfo+488, p)
				if mTerm == uint64(0) && !(_sqlite3ExprIsConstant(tls, uintptr(0), p) != 0) {
					goto _9
				}
				if mTerm & ^orderDistinctMask == uint64(0) {
					**(**TBitmask)(__ccgo_up(bp)) = **(**TBitmask)(__ccgo_up(bp)) | libc.Uint64FromInt32(1)<<i
				}
				goto _9
			_9:
				;
				i = i + 1
			}
		}
		goto _1
	_1:
		;
		iLoop = iLoop + 1
	} /* End the loop over all WhereLoops from outer-most down to inner-most */
	if **(**TBitmask)(__ccgo_up(bp)) == obDone {
		return libc.Int8FromUint16(nOrderBy)
	}
	if !(isOrderDistinct != 0) {
		i = libc.Int32FromUint16(nOrderBy) - int32(1)
		for {
			if !(i > 0) {
				break
			}
			if i < libc.Int32FromUint32(libc.Uint32FromInt64(8)*libc.Uint32FromInt32(8)) {
				v11 = libc.Uint64FromInt32(1)<<i - uint64(1)
			} else {
				v11 = uint64(0)
			}
			m = v11
			if **(**TBitmask)(__ccgo_up(bp))&m == m {
				return int8(i)
			}
			goto _10
		_10:
			;
			i = i - 1
		}
		return 0
	}
	return int8(-int32(1))
}

// C documentation
//
//	/*
//	** This function is used to estimate the number of rows that will be visited
//	** by scanning an index for a range of values. The range may have an upper
//	** bound, a lower bound, or both. The WHERE clause terms that set the upper
//	** and lower bounds are represented by pLower and pUpper respectively. For
//	** example, assuming that index p is on t1(a):
//	**
//	**   ... FROM t1 WHERE a > ? AND a < ? ...
//	**                    |_____|   |_____|
//	**                       |         |
//	**                     pLower    pUpper
//	**
//	** If either of the upper or lower bound is not present, then NULL is passed in
//	** place of the corresponding WhereTerm.
//	**
//	** The value in (pBuilder->pNew->u.btree.nEq) is the number of the index
//	** column subject to the range constraint. Or, equivalently, the number of
//	** equality constraints optimized by the proposed index scan. For example,
//	** assuming index p is on t1(a, b), and the SQL query is:
//	**
//	**   ... FROM t1 WHERE a = ? AND b > ? AND b < ? ...
//	**
//	** then nEq is set to 1 (as the range restricted column, b, is the second
//	** left-most column of the index). Or, if the query is:
//	**
//	**   ... FROM t1 WHERE a > ? AND a < ? ...
//	**
//	** then nEq is set to 0.
//	**
//	** When this function is called, *pnOut is set to the sqlite3LogEst() of the
//	** number of rows that the index scan is expected to visit without
//	** considering the range constraints. If nEq is 0, then *pnOut is the number of
//	** rows in the index. Assuming no error occurs, *pnOut is adjusted (reduced)
//	** to account for the range constraints pLower and pUpper.
//	**
//	** In the absence of sqlite_stat4 ANALYZE data, or if such data cannot be
//	** used, a single range inequality reduces the search space by a factor of 4.
//	** and a pair of constraints (x>? AND x<?) reduces the expected number of
//	** rows visited by a factor of 64.
//	*/
func _whereRangeScanEst(tls *libc.TLS, pParse uintptr, pBuilder uintptr, pLower uintptr, pUpper uintptr, pLoop uintptr) (r int32) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var iLower, iNew, iNew1, iUpper TtRowcnt
	var iLwrIdx, iUprIdx, nBtm, nEq, nOut, nTop, rc, t1 int32
	var mask, mask1 Tu16
	var nNew TLogEst
	var p, pExpr, pExpr1, t uintptr
	var v1 uint64
	var _ /* a at bp+4 */ [2]TtRowcnt
	var _ /* bDone at bp+28 */ int32
	var _ /* n at bp+20 */ int32
	var _ /* n at bp+24 */ int32
	var _ /* pRec at bp+0 */ uintptr
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = iLower, iLwrIdx, iNew, iNew1, iUpper, iUprIdx, mask, mask1, nBtm, nEq, nNew, nOut, nTop, p, pExpr, pExpr1, rc, t, t1, v1
	rc = SQLITE_OK
	nOut = int32((*TWhereLoop)(unsafe.Pointer(pLoop)).FnOut)
	p = (*(*struct {
		FnEq          Tu16
		FnBtm         Tu16
		FnTop         Tu16
		FnDistinctCol Tu16
		FpIndex       uintptr
		FpOrderBy     uintptr
	})(unsafe.Pointer(pLoop + 24))).FpIndex
	nEq = libc.Int32FromUint16((*(*struct {
		FnEq          Tu16
		FnBtm         Tu16
		FnTop         Tu16
		FnDistinctCol Tu16
		FpIndex       uintptr
		FpOrderBy     uintptr
	})(unsafe.Pointer(pLoop + 24))).FnEq)
	if (*TIndex)(unsafe.Pointer(p)).FnSample > 0 && nEq < (*TIndex)(unsafe.Pointer(p)).FnSampleCol && (*Tsqlite3)(unsafe.Pointer((*TParse)(unsafe.Pointer(pParse)).Fdb)).FdbOptFlags&libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_Stat4)) == uint32(0) {
		if nEq == (*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FnRecValid {
			**(**uintptr)(__ccgo_up(bp)) = (*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FpRec
			nBtm = libc.Int32FromUint16((*(*struct {
				FnEq          Tu16
				FnBtm         Tu16
				FnTop         Tu16
				FnDistinctCol Tu16
				FpIndex       uintptr
				FpOrderBy     uintptr
			})(unsafe.Pointer(pLoop + 24))).FnBtm)
			nTop = libc.Int32FromUint16((*(*struct {
				FnEq          Tu16
				FnBtm         Tu16
				FnTop         Tu16
				FnDistinctCol Tu16
				FpIndex       uintptr
				FpOrderBy     uintptr
			})(unsafe.Pointer(pLoop + 24))).FnTop) /* Rows less than the upper bound */
			iLwrIdx = -int32(2) /* aSample[] for the lower bound */
			iUprIdx = -int32(1) /* aSample[] for the upper bound */
			if **(**uintptr)(__ccgo_up(bp)) != 0 {
				(*TUnpackedRecord)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FnField = libc.Uint16FromInt32((*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FnRecValid)
			}
			/* Determine iLower and iUpper using ($P) only. */
			if nEq == 0 {
				iLower = uint64(0)
				iUpper = (*TIndex)(unsafe.Pointer(p)).FnRowEst0
			} else {
				/* Note: this call could be optimized away - since the same values must
				 ** have been requested when testing key $P in whereEqualScanEst().  */
				_whereKeyStats(tls, pParse, p, **(**uintptr)(__ccgo_up(bp)), 0, bp+4)
				iLower = (**(**[2]TtRowcnt)(__ccgo_up(bp + 4)))[0]
				iUpper = (**(**[2]TtRowcnt)(__ccgo_up(bp + 4)))[0] + (**(**[2]TtRowcnt)(__ccgo_up(bp + 4)))[int32(1)]
			}
			if **(**Tu8)(__ccgo_up((*TIndex)(unsafe.Pointer(p)).FaSortOrder + uintptr(nEq))) != 0 {
				/* The roles of pLower and pUpper are swapped for a DESC index */
				t = pLower
				pLower = pUpper
				pUpper = t
				t1 = nBtm
				nBtm = nTop
				nTop = t1
			}
			/* If possible, improve on the iLower estimate using ($P:$L). */
			if pLower != 0 { /* Values extracted from pExpr */
				pExpr = (*TExpr)(unsafe.Pointer((*TWhereTerm)(unsafe.Pointer(pLower)).FpExpr)).FpRight
				rc = _sqlite3Stat4ProbeSetValue(tls, pParse, p, bp, pExpr, nBtm, nEq, bp+20)
				if rc == SQLITE_OK && **(**int32)(__ccgo_up(bp + 20)) != 0 {
					mask = libc.Uint16FromInt32(libc.Int32FromInt32(WO_EQ)<<(libc.Int32FromInt32(TK_GT)-libc.Int32FromInt32(TK_EQ)) | libc.Int32FromInt32(WO_EQ)<<(libc.Int32FromInt32(TK_LE)-libc.Int32FromInt32(TK_EQ)))
					if _sqlite3ExprVectorSize(tls, pExpr) > **(**int32)(__ccgo_up(bp + 20)) {
						mask = libc.Uint16FromInt32(libc.Int32FromInt32(WO_EQ)<<(libc.Int32FromInt32(TK_LE)-libc.Int32FromInt32(TK_EQ)) | libc.Int32FromInt32(WO_EQ)<<(libc.Int32FromInt32(TK_LT)-libc.Int32FromInt32(TK_EQ)))
					}
					iLwrIdx = _whereKeyStats(tls, pParse, p, **(**uintptr)(__ccgo_up(bp)), 0, bp+4)
					if libc.Int32FromUint16((*TWhereTerm)(unsafe.Pointer(pLower)).FeOperator)&libc.Int32FromUint16(mask) != 0 {
						v1 = (**(**[2]TtRowcnt)(__ccgo_up(bp + 4)))[int32(1)]
					} else {
						v1 = uint64(0)
					}
					iNew = (**(**[2]TtRowcnt)(__ccgo_up(bp + 4)))[0] + v1
					if iNew > iLower {
						iLower = iNew
					}
					nOut = nOut - 1
					pLower = uintptr(0)
				}
			}
			/* If possible, improve on the iUpper estimate using ($P:$U). */
			if pUpper != 0 { /* Values extracted from pExpr */
				pExpr1 = (*TExpr)(unsafe.Pointer((*TWhereTerm)(unsafe.Pointer(pUpper)).FpExpr)).FpRight
				rc = _sqlite3Stat4ProbeSetValue(tls, pParse, p, bp, pExpr1, nTop, nEq, bp+24)
				if rc == SQLITE_OK && **(**int32)(__ccgo_up(bp + 24)) != 0 {
					mask1 = libc.Uint16FromInt32(libc.Int32FromInt32(WO_EQ)<<(libc.Int32FromInt32(TK_GT)-libc.Int32FromInt32(TK_EQ)) | libc.Int32FromInt32(WO_EQ)<<(libc.Int32FromInt32(TK_LE)-libc.Int32FromInt32(TK_EQ)))
					if _sqlite3ExprVectorSize(tls, pExpr1) > **(**int32)(__ccgo_up(bp + 24)) {
						mask1 = libc.Uint16FromInt32(libc.Int32FromInt32(WO_EQ)<<(libc.Int32FromInt32(TK_LE)-libc.Int32FromInt32(TK_EQ)) | libc.Int32FromInt32(WO_EQ)<<(libc.Int32FromInt32(TK_LT)-libc.Int32FromInt32(TK_EQ)))
					}
					iUprIdx = _whereKeyStats(tls, pParse, p, **(**uintptr)(__ccgo_up(bp)), int32(1), bp+4)
					if libc.Int32FromUint16((*TWhereTerm)(unsafe.Pointer(pUpper)).FeOperator)&libc.Int32FromUint16(mask1) != 0 {
						v1 = (**(**[2]TtRowcnt)(__ccgo_up(bp + 4)))[int32(1)]
					} else {
						v1 = uint64(0)
					}
					iNew1 = (**(**[2]TtRowcnt)(__ccgo_up(bp + 4)))[0] + v1
					if iNew1 < iUpper {
						iUpper = iNew1
					}
					nOut = nOut - 1
					pUpper = uintptr(0)
				}
			}
			(*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FpRec = **(**uintptr)(__ccgo_up(bp))
			if rc == SQLITE_OK {
				if iUpper > iLower {
					nNew = _sqlite3LogEst(tls, iUpper-iLower)
					/* TUNING:  If both iUpper and iLower are derived from the same
					 ** sample, then assume they are 4x more selective.  This brings
					 ** the estimated selectivity more in line with what it would be
					 ** if estimated without the use of STAT4 tables. */
					if iLwrIdx == iUprIdx {
						nNew = int16(int32(nNew) - libc.Int32FromInt32(20))
					}
				} else {
					nNew = int16(10)
				}
				if int32(nNew) < nOut {
					nOut = int32(nNew)
				}
			}
		} else {
			**(**int32)(__ccgo_up(bp + 28)) = 0
			rc = _whereRangeSkipScanEst(tls, pParse, pLower, pUpper, pLoop, bp+28)
			if **(**int32)(__ccgo_up(bp + 28)) != 0 {
				return rc
			}
		}
	}
	nNew = _whereRangeAdjust(tls, pLower, int16(nOut))
	nNew = _whereRangeAdjust(tls, pUpper, nNew)
	/* TUNING: If there is both an upper and lower limit and neither limit
	 ** has an application-defined likelihood(), assume the range is
	 ** reduced by an additional 75%. This means that, by default, an open-ended
	 ** range query (e.g. col > ?) is assumed to match 1/4 of the rows in the
	 ** index. While a closed range (e.g. col BETWEEN ? AND ?) is estimated to
	 ** match 1/64 of the index. */
	if pLower != 0 && int32((*TWhereTerm)(unsafe.Pointer(pLower)).FtruthProb) > 0 && pUpper != 0 && int32((*TWhereTerm)(unsafe.Pointer(pUpper)).FtruthProb) > 0 {
		nNew = int16(int32(nNew) - libc.Int32FromInt32(20))
	}
	nOut = nOut - (libc.BoolInt32(pLower != uintptr(0)) + libc.BoolInt32(pUpper != uintptr(0)))
	if int32(nNew) < int32(10) {
		nNew = int16(10)
	}
	if int32(nNew) < nOut {
		nOut = int32(nNew)
	}
	(*TWhereLoop)(unsafe.Pointer(pLoop)).FnOut = int16(nOut)
	return rc
}

// C documentation
//
//	/*
//	** This function is called to estimate the number of rows visited by a
//	** range-scan on a skip-scan index. For example:
//	**
//	**   CREATE INDEX i1 ON t1(a, b, c);
//	**   SELECT * FROM t1 WHERE a=? AND c BETWEEN ? AND ?;
//	**
//	** Value pLoop->nOut is currently set to the estimated number of rows
//	** visited for scanning (a=? AND b=?). This function reduces that estimate
//	** by some factor to account for the (c BETWEEN ? AND ?) expression based
//	** on the stat4 data for the index. this scan will be performed multiple
//	** times (once for each (a,b) combination that matches a=?) is dealt with
//	** by the caller.
//	**
//	** It does this by scanning through all stat4 samples, comparing values
//	** extracted from pLower and pUpper with the corresponding column in each
//	** sample. If L and U are the number of samples found to be less than or
//	** equal to the values extracted from pLower and pUpper respectively, and
//	** N is the total number of samples, the pLoop->nOut value is adjusted
//	** as follows:
//	**
//	**   nOut = nOut * ( min(U - L, 1) / N )
//	**
//	** If pLower is NULL, or a value cannot be extracted from the term, L is
//	** set to zero. If pUpper is NULL, or a value cannot be extracted from it,
//	** U is set to N.
//	**
//	** Normally, this function sets *pbDone to 1 before returning. However,
//	** if no value can be extracted from either pLower or pUpper (and so the
//	** estimate of the number of rows delivered remains unchanged), *pbDone
//	** is left as is.
//	**
//	** If an error occurs, an SQLite error code is returned. Otherwise,
//	** SQLITE_OK.
//	*/
func _whereRangeSkipScanEst(tls *libc.TLS, pParse uintptr, pLower uintptr, pUpper uintptr, pLoop uintptr, pbDone uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var aff Tu8
	var db, p, pColl, v3 uintptr
	var i, nAdjust, nDiff, nEq, nLower, nUpper, rc, res, res1, v1 int32
	var _ /* p1 at bp+0 */ uintptr
	var _ /* p2 at bp+4 */ uintptr
	var _ /* pVal at bp+8 */ uintptr
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = aff, db, i, nAdjust, nDiff, nEq, nLower, nUpper, p, pColl, rc, res, res1, v1, v3
	p = (*(*struct {
		FnEq          Tu16
		FnBtm         Tu16
		FnTop         Tu16
		FnDistinctCol Tu16
		FpIndex       uintptr
		FpOrderBy     uintptr
	})(unsafe.Pointer(pLoop + 24))).FpIndex
	nEq = libc.Int32FromUint16((*(*struct {
		FnEq          Tu16
		FnBtm         Tu16
		FnTop         Tu16
		FnDistinctCol Tu16
		FpIndex       uintptr
		FpOrderBy     uintptr
	})(unsafe.Pointer(pLoop + 24))).FnEq)
	db = (*TParse)(unsafe.Pointer(pParse)).Fdb
	nLower = -int32(1)
	nUpper = (*TIndex)(unsafe.Pointer(p)).FnSample + int32(1)
	rc = SQLITE_OK
	aff = libc.Uint8FromInt8(_sqlite3IndexColumnAffinity(tls, db, p, nEq))
	**(**uintptr)(__ccgo_up(bp)) = uintptr(0)     /* Value extracted from pLower */
	**(**uintptr)(__ccgo_up(bp + 4)) = uintptr(0) /* Value extracted from pUpper */
	**(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0) /* Value extracted from record */
	pColl = _sqlite3LocateCollSeq(tls, pParse, **(**uintptr)(__ccgo_up((*TIndex)(unsafe.Pointer(p)).FazColl + uintptr(nEq)*4)))
	if pLower != 0 {
		rc = _sqlite3Stat4ValueFromExpr(tls, pParse, (*TExpr)(unsafe.Pointer((*TWhereTerm)(unsafe.Pointer(pLower)).FpExpr)).FpRight, aff, bp)
		nLower = 0
	}
	if pUpper != 0 && rc == SQLITE_OK {
		rc = _sqlite3Stat4ValueFromExpr(tls, pParse, (*TExpr)(unsafe.Pointer((*TWhereTerm)(unsafe.Pointer(pUpper)).FpExpr)).FpRight, aff, bp+4)
		if **(**uintptr)(__ccgo_up(bp + 4)) != 0 {
			v1 = 0
		} else {
			v1 = (*TIndex)(unsafe.Pointer(p)).FnSample
		}
		nUpper = v1
	}
	if **(**uintptr)(__ccgo_up(bp)) != 0 || **(**uintptr)(__ccgo_up(bp + 4)) != 0 {
		i = 0
		for {
			if !(rc == SQLITE_OK && i < (*TIndex)(unsafe.Pointer(p)).FnSample) {
				break
			}
			rc = _sqlite3Stat4Column(tls, db, (**(**TIndexSample)(__ccgo_up((*TIndex)(unsafe.Pointer(p)).FaSample + uintptr(i)*20))).Fp, (**(**TIndexSample)(__ccgo_up((*TIndex)(unsafe.Pointer(p)).FaSample + uintptr(i)*20))).Fn, nEq, bp+8)
			if rc == SQLITE_OK && **(**uintptr)(__ccgo_up(bp)) != 0 {
				res = _sqlite3MemCompare(tls, **(**uintptr)(__ccgo_up(bp)), **(**uintptr)(__ccgo_up(bp + 8)), pColl)
				if res >= 0 {
					nLower = nLower + 1
				}
			}
			if rc == SQLITE_OK && **(**uintptr)(__ccgo_up(bp + 4)) != 0 {
				res1 = _sqlite3MemCompare(tls, **(**uintptr)(__ccgo_up(bp + 4)), **(**uintptr)(__ccgo_up(bp + 8)), pColl)
				if res1 >= 0 {
					nUpper = nUpper + 1
				}
			}
			goto _2
		_2:
			;
			i = i + 1
		}
		nDiff = nUpper - nLower
		if nDiff <= 0 {
			nDiff = int32(1)
		}
		/* If there is both an upper and lower bound specified, and the
		 ** comparisons indicate that they are close together, use the fallback
		 ** method (assume that the scan visits 1/64 of the rows) for estimating
		 ** the number of rows visited. Otherwise, estimate the number of rows
		 ** using the method described in the header comment for this function. */
		if nDiff != int32(1) || pUpper == uintptr(0) || pLower == uintptr(0) {
			nAdjust = int32(_sqlite3LogEst(tls, libc.Uint64FromInt32((*TIndex)(unsafe.Pointer(p)).FnSample))) - int32(_sqlite3LogEst(tls, libc.Uint64FromInt32(nDiff)))
			v3 = pLoop + 22
			*(*TLogEst)(unsafe.Pointer(v3)) = TLogEst(int32(*(*TLogEst)(unsafe.Pointer(v3))) - nAdjust)
			**(**int32)(__ccgo_up(pbDone)) = int32(1)
		}
	} else {
	}
	_sqlite3ValueFree(tls, **(**uintptr)(__ccgo_up(bp)))
	_sqlite3ValueFree(tls, **(**uintptr)(__ccgo_up(bp + 4)))
	_sqlite3ValueFree(tls, **(**uintptr)(__ccgo_up(bp + 8)))
	return rc
}

// C documentation
//
//	/*
//	** Term pTerm is a vector range comparison operation. The first comparison
//	** in the vector can be optimized using column nEq of the index. This
//	** function returns the total number of vector elements that can be used
//	** as part of the range comparison.
//	**
//	** For example, if the query is:
//	**
//	**   WHERE a = ? AND (b, c, d) > (?, ?, ?)
//	**
//	** and the index:
//	**
//	**   CREATE INDEX ... ON (a, b, c, d, e)
//	**
//	** then this function would be invoked with nEq=1. The value returned in
//	** this case is 3.
//	*/
func _whereRangeVectorLen(tls *libc.TLS, pParse uintptr, iCur int32, pIdx uintptr, nEq int32, pTerm uintptr) (r int32) {
	var aff, idxaff int8
	var i, nCmp, v1 int32
	var pColl, pLhs, pRhs, t uintptr
	_, _, _, _, _, _, _, _, _ = aff, i, idxaff, nCmp, pColl, pLhs, pRhs, t, v1
	nCmp = _sqlite3ExprVectorSize(tls, (*TExpr)(unsafe.Pointer((*TWhereTerm)(unsafe.Pointer(pTerm)).FpExpr)).FpLeft)
	if nCmp < libc.Int32FromUint16((*TIndex)(unsafe.Pointer(pIdx)).FnColumn)-nEq {
		v1 = nCmp
	} else {
		v1 = libc.Int32FromUint16((*TIndex)(unsafe.Pointer(pIdx)).FnColumn) - nEq
	}
	nCmp = v1
	i = int32(1)
	for {
		if !(i < nCmp) {
			break
		} /* Comparison affinity */
		idxaff = 0
		pLhs = (*(*TExprList_item)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer((*TExpr)(unsafe.Pointer((*TWhereTerm)(unsafe.Pointer(pTerm)).FpExpr)).FpLeft + 20)) + 8 + uintptr(i)*20))).FpExpr
		pRhs = (*TExpr)(unsafe.Pointer((*TWhereTerm)(unsafe.Pointer(pTerm)).FpExpr)).FpRight
		if (*TExpr)(unsafe.Pointer(pRhs)).Fflags&uint32(EP_xIsSelect) != uint32(0) {
			pRhs = (*(*TExprList_item)(unsafe.Pointer((*TSelect)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pRhs + 20)))).FpEList + 8 + uintptr(i)*20))).FpExpr
		} else {
			pRhs = (*(*TExprList_item)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pRhs + 20)) + 8 + uintptr(i)*20))).FpExpr
		}
		/* Check that the LHS of the comparison is a column reference to
		 ** the right column of the right source table. And that the sort
		 ** order of the index column is the same as the sort order of the
		 ** leftmost index column.  */
		if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pLhs)).Fop) != int32(TK_COLUMN) || (*TExpr)(unsafe.Pointer(pLhs)).FiTable != iCur || int32((*TExpr)(unsafe.Pointer(pLhs)).FiColumn) != int32(**(**Ti16)(__ccgo_up((*TIndex)(unsafe.Pointer(pIdx)).FaiColumn + uintptr(i+nEq)*2))) || libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TIndex)(unsafe.Pointer(pIdx)).FaSortOrder + uintptr(i+nEq)))) != libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TIndex)(unsafe.Pointer(pIdx)).FaSortOrder + uintptr(nEq)))) {
			break
		}
		aff = _sqlite3CompareAffinity(tls, pRhs, _sqlite3ExprAffinity(tls, pLhs))
		idxaff = _sqlite3TableColumnAffinity(tls, (*TIndex)(unsafe.Pointer(pIdx)).FpTable, int32((*TExpr)(unsafe.Pointer(pLhs)).FiColumn))
		if int32(aff) != int32(idxaff) {
			break
		}
		if (*TExpr)(unsafe.Pointer((*TWhereTerm)(unsafe.Pointer(pTerm)).FpExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_Commuted)) != uint32(0) {
			t = pRhs
			pRhs = pLhs
			pLhs = t
		}
		pColl = _sqlite3BinaryCompareCollSeq(tls, pParse, pLhs, pRhs)
		if pColl == uintptr(0) {
			break
		}
		if _sqlite3StrICmp(tls, (*TCollSeq)(unsafe.Pointer(pColl)).FzName, **(**uintptr)(__ccgo_up((*TIndex)(unsafe.Pointer(pIdx)).FazColl + uintptr(i+nEq)*4))) != 0 {
			break
		}
		goto _2
	_2:
		;
		i = i + 1
	}
	return i
}

/*
** Adjust the cost C by the costMult factor T.  This only occurs if
** compiled with -DSQLITE_ENABLE_COSTMULT
 */

// C documentation
//
//	/*
//	** Set the reverse-scan order mask to one for all tables in the query
//	** with the exception of MATERIALIZED common table expressions that have
//	** their own internal ORDER BY clauses.
//	**
//	** This implements the PRAGMA reverse_unordered_selects=ON setting.
//	** (Also SQLITE_DBCONFIG_REVERSE_SCANORDER).
//	*/
func _whereReverseScanOrder(tls *libc.TLS, pWInfo uintptr) {
	var ii int32
	var pItem uintptr
	_, _ = ii, pItem
	ii = 0
	for {
		if !(ii < (*TSrcList)(unsafe.Pointer((*TWhereInfo)(unsafe.Pointer(pWInfo)).FpTabList)).FnSrc) {
			break
		}
		pItem = (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpTabList + 8 + uintptr(ii)*48
		if !(int32(*(*uint32)(unsafe.Pointer(pItem + 12 + 4))&0x200>>9) != 0) || libc.Int32FromUint8((*TCteUse)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pItem + 36)))).FeM10d) != M10d_Yes || int32(*(*uint32)(unsafe.Pointer(pItem + 12 + 4))&0x4>>2) == 0 || (*TSelect)(unsafe.Pointer((*TSubquery)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pItem + 44)))).FpSelect)).FpOrderBy == uintptr(0) {
			**(**TBitmask)(__ccgo_up(pWInfo + 68)) |= libc.Uint64FromInt32(1) << ii
		}
		goto _1
	_1:
		;
		ii = ii + 1
	}
}

// C documentation
//
//	/*
//	** Advance to the next WhereTerm that matches according to the criteria
//	** established when the pScan object was initialized by whereScanInit().
//	** Return NULL if there are no more matching WhereTerms.
//	*/
func _whereScanNext(tls *libc.TLS, pScan uintptr) (r uintptr) {
	var iColumn Ti16
	var iCur, j, k int32
	var pColl, pParse, pTerm, pWC, pX, zCollName, v2 uintptr
	var v3 bool
	_, _, _, _, _, _, _, _, _, _, _, _ = iColumn, iCur, j, k, pColl, pParse, pTerm, pWC, pX, zCollName, v2, v3 /* The term being tested */
	k = (*TWhereScan)(unsafe.Pointer(pScan)).Fk                                                                /* Where to start scanning */
	pWC = (*TWhereScan)(unsafe.Pointer(pScan)).FpWC
	for int32(1) != 0 {
		iColumn = **(**Ti16)(__ccgo_up(pScan + 72 + uintptr(libc.Int32FromUint8((*TWhereScan)(unsafe.Pointer(pScan)).FiEquiv)-int32(1))*2))
		iCur = **(**int32)(__ccgo_up(pScan + 28 + uintptr(libc.Int32FromUint8((*TWhereScan)(unsafe.Pointer(pScan)).FiEquiv)-int32(1))*4))
		for cond := true; cond; cond = pWC != uintptr(0) {
			pTerm = (*TWhereClause)(unsafe.Pointer(pWC)).Fa + uintptr(k)*48
			for {
				if !(k < (*TWhereClause)(unsafe.Pointer(pWC)).FnTerm) {
					break
				}
				if (*TWhereTerm)(unsafe.Pointer(pTerm)).FleftCursor == iCur && (*(*struct {
					FleftColumn int32
					FiField     int32
				})(unsafe.Pointer(pTerm + 24))).FleftColumn == int32(iColumn) && (int32(iColumn) != -int32(2) || _sqlite3ExprCompareSkip(tls, (*TExpr)(unsafe.Pointer((*TWhereTerm)(unsafe.Pointer(pTerm)).FpExpr)).FpLeft, (*TWhereScan)(unsafe.Pointer(pScan)).FpIdxExpr, iCur) == 0) && (libc.Int32FromUint8((*TWhereScan)(unsafe.Pointer(pScan)).FiEquiv) <= int32(1) || !((*TExpr)(unsafe.Pointer((*TWhereTerm)(unsafe.Pointer(pTerm)).FpExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_OuterON)) != libc.Uint32FromInt32(0))) {
					if v3 = libc.Int32FromUint16((*TWhereTerm)(unsafe.Pointer(pTerm)).FeOperator)&int32(WO_EQUIV) != 0 && libc.Int32FromUint8((*TWhereScan)(unsafe.Pointer(pScan)).FnEquiv) < libc.Int32FromUint32(libc.Uint32FromInt64(44)/libc.Uint32FromInt64(4)); v3 {
						v2 = _whereRightSubexprIsColumn(tls, (*TWhereTerm)(unsafe.Pointer(pTerm)).FpExpr)
						pX = v2
					}
					if v3 && v2 != uintptr(0) {
						j = 0
						for {
							if !(j < libc.Int32FromUint8((*TWhereScan)(unsafe.Pointer(pScan)).FnEquiv)) {
								break
							}
							if **(**int32)(__ccgo_up(pScan + 28 + uintptr(j)*4)) == (*TExpr)(unsafe.Pointer(pX)).FiTable && int32(**(**Ti16)(__ccgo_up(pScan + 72 + uintptr(j)*2))) == int32((*TExpr)(unsafe.Pointer(pX)).FiColumn) {
								break
							}
							goto _4
						_4:
							;
							j = j + 1
						}
						if j == libc.Int32FromUint8((*TWhereScan)(unsafe.Pointer(pScan)).FnEquiv) {
							**(**int32)(__ccgo_up(pScan + 28 + uintptr(j)*4)) = (*TExpr)(unsafe.Pointer(pX)).FiTable
							**(**Ti16)(__ccgo_up(pScan + 72 + uintptr(j)*2)) = (*TExpr)(unsafe.Pointer(pX)).FiColumn
							(*TWhereScan)(unsafe.Pointer(pScan)).FnEquiv = (*TWhereScan)(unsafe.Pointer(pScan)).FnEquiv + 1
						}
					}
					if uint32((*TWhereTerm)(unsafe.Pointer(pTerm)).FeOperator)&(*TWhereScan)(unsafe.Pointer(pScan)).FopMask != uint32(0) {
						/* Verify the affinity and collating sequence match */
						if (*TWhereScan)(unsafe.Pointer(pScan)).FzCollName != 0 && libc.Int32FromUint16((*TWhereTerm)(unsafe.Pointer(pTerm)).FeOperator)&int32(WO_ISNULL) == 0 {
							pParse = (*TWhereInfo)(unsafe.Pointer((*TWhereClause)(unsafe.Pointer(pWC)).FpWInfo)).FpParse
							pX = (*TWhereTerm)(unsafe.Pointer(pTerm)).FpExpr
							if libc.Int32FromUint16((*TWhereTerm)(unsafe.Pointer(pTerm)).FeOperator)&int32(WO_IN) != 0 {
								zCollName = _indexInAffinityOk(tls, pParse, pTerm, libc.Uint8FromInt8((*TWhereScan)(unsafe.Pointer(pScan)).Fidxaff))
								if !(zCollName != 0) {
									goto _1
								}
							} else {
								if !(_sqlite3IndexAffinityOk(tls, pX, (*TWhereScan)(unsafe.Pointer(pScan)).Fidxaff) != 0) {
									goto _1
								}
								pColl = _sqlite3ExprCompareCollSeq(tls, pParse, pX)
								if pColl != 0 {
									v2 = (*TCollSeq)(unsafe.Pointer(pColl)).FzName
								} else {
									v2 = uintptr(unsafe.Pointer(&_sqlite3StrBINARY))
								}
								zCollName = v2
							}
							if _sqlite3StrICmp(tls, zCollName, (*TWhereScan)(unsafe.Pointer(pScan)).FzCollName) != 0 {
								goto _1
							}
						}
						if v3 = libc.Int32FromUint16((*TWhereTerm)(unsafe.Pointer(pTerm)).FeOperator)&(libc.Int32FromInt32(WO_EQ)|libc.Int32FromInt32(WO_IS)) != 0; v3 {
							pX = (*TExpr)(unsafe.Pointer((*TWhereTerm)(unsafe.Pointer(pTerm)).FpExpr)).FpRight
						}
						if v3 && pX != libc.UintptrFromInt32(0) && libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pX)).Fop) == int32(TK_COLUMN) && (*TExpr)(unsafe.Pointer(pX)).FiTable == **(**int32)(__ccgo_up(pScan + 28)) && int32((*TExpr)(unsafe.Pointer(pX)).FiColumn) == int32(**(**Ti16)(__ccgo_up(pScan + 72))) {
							goto _1
						}
						(*TWhereScan)(unsafe.Pointer(pScan)).FpWC = pWC
						(*TWhereScan)(unsafe.Pointer(pScan)).Fk = k + int32(1)
						return pTerm
					}
				}
				goto _1
			_1:
				;
				k = k + 1
				pTerm += 48
			}
			pWC = (*TWhereClause)(unsafe.Pointer(pWC)).FpOuter
			k = 0
		}
		if libc.Int32FromUint8((*TWhereScan)(unsafe.Pointer(pScan)).FiEquiv) >= libc.Int32FromUint8((*TWhereScan)(unsafe.Pointer(pScan)).FnEquiv) {
			break
		}
		pWC = (*TWhereScan)(unsafe.Pointer(pScan)).FpOrigWC
		k = 0
		(*TWhereScan)(unsafe.Pointer(pScan)).FiEquiv = (*TWhereScan)(unsafe.Pointer(pScan)).FiEquiv + 1
	}
	return uintptr(0)
}

// C documentation
//
//	/*
//	** Most queries use only a single table (they are not joins) and have
//	** simple == constraints against indexed fields.  This routine attempts
//	** to plan those simple cases using much less ceremony than the
//	** general-purpose query planner, and thereby yield faster sqlite3_prepare()
//	** times for the common case.
//	**
//	** Return non-zero on success, if this query can be handled by this
//	** no-frills query planner.  Return zero if this query needs the
//	** general-purpose query planner.
//	*/
func _whereShortCut(tls *libc.TLS, pBuilder uintptr) (r int32) {
	bp := tls.Alloc(96)
	defer tls.Free(96)
	var iCur, j, opMask, v2 int32
	var pIdx, pItem, pLoop, pTab, pTerm, pWC, pWInfo uintptr
	var _ /* scan at bp+0 */ TWhereScan
	_, _, _, _, _, _, _, _, _, _, _ = iCur, j, opMask, pIdx, pItem, pLoop, pTab, pTerm, pWC, pWInfo, v2
	pWInfo = (*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FpWInfo
	if libc.Int32FromUint16((*TWhereInfo)(unsafe.Pointer(pWInfo)).FwctrlFlags)&int32(WHERE_OR_SUBCLAUSE) != 0 {
		return 0
	}
	pItem = (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpTabList + 8
	pTab = (*TSrcItem)(unsafe.Pointer(pItem)).FpSTab
	if libc.Int32FromUint8((*TTable)(unsafe.Pointer(pTab)).FeTabType) == int32(TABTYP_VTAB) {
		return 0
	}
	if int32(*(*uint32)(unsafe.Pointer(pItem + 12 + 4))&0x2>>1) != 0 || int32(*(*uint32)(unsafe.Pointer(pItem + 12 + 4))&0x1>>0) != 0 {
		return 0
	}
	iCur = (*TSrcItem)(unsafe.Pointer(pItem)).FiCursor
	pWC = pWInfo + 76
	pLoop = (*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FpNew
	(*TWhereLoop)(unsafe.Pointer(pLoop)).FwsFlags = uint32(0)
	(*TWhereLoop)(unsafe.Pointer(pLoop)).FnSkip = uint16(0)
	pTerm = _whereScanInit(tls, bp, pWC, iCur, -int32(1), libc.Uint32FromInt32(libc.Int32FromInt32(WO_EQ)|libc.Int32FromInt32(WO_IS)), uintptr(0))
	for pTerm != 0 && (*TWhereTerm)(unsafe.Pointer(pTerm)).FprereqRight != 0 {
		pTerm = _whereScanNext(tls, bp)
	}
	if pTerm != 0 {
		(*TWhereLoop)(unsafe.Pointer(pLoop)).FwsFlags = libc.Uint32FromInt32(libc.Int32FromInt32(WHERE_COLUMN_EQ) | libc.Int32FromInt32(WHERE_IPK) | libc.Int32FromInt32(WHERE_ONEROW))
		**(**uintptr)(__ccgo_up((*TWhereLoop)(unsafe.Pointer(pLoop)).FaLTerm)) = pTerm
		(*TWhereLoop)(unsafe.Pointer(pLoop)).FnLTerm = uint16(1)
		(*(*struct {
			FnEq          Tu16
			FnBtm         Tu16
			FnTop         Tu16
			FnDistinctCol Tu16
			FpIndex       uintptr
			FpOrderBy     uintptr
		})(unsafe.Pointer(pLoop + 24))).FnEq = uint16(1)
		/* TUNING: Cost of a rowid lookup is 10 */
		(*TWhereLoop)(unsafe.Pointer(pLoop)).FrRun = int16(33) /* 33==sqlite3LogEst(10) */
	} else {
		pIdx = (*TTable)(unsafe.Pointer(pTab)).FpIndex
		for {
			if !(pIdx != 0) {
				break
			}
			if !(libc.Int32FromUint8((*TIndex)(unsafe.Pointer(pIdx)).FonError) != libc.Int32FromInt32(OE_None)) || (*TIndex)(unsafe.Pointer(pIdx)).FpPartIdxWhere != uintptr(0) || libc.Int32FromUint16((*TIndex)(unsafe.Pointer(pIdx)).FnKeyCol) > libc.Int32FromUint32(libc.Uint32FromInt64(12)/libc.Uint32FromInt64(4)) {
				goto _1
			}
			if int32(uint32(*(*uint16)(unsafe.Pointer(pIdx + 56))&0x8>>3)) != 0 {
				v2 = libc.Int32FromInt32(WO_EQ) | libc.Int32FromInt32(WO_IS)
			} else {
				v2 = int32(WO_EQ)
			}
			opMask = v2
			j = 0
			for {
				if !(j < libc.Int32FromUint16((*TIndex)(unsafe.Pointer(pIdx)).FnKeyCol)) {
					break
				}
				pTerm = _whereScanInit(tls, bp, pWC, iCur, j, libc.Uint32FromInt32(opMask), pIdx)
				for pTerm != 0 && (*TWhereTerm)(unsafe.Pointer(pTerm)).FprereqRight != 0 {
					pTerm = _whereScanNext(tls, bp)
				}
				if pTerm == uintptr(0) {
					break
				}
				**(**uintptr)(__ccgo_up((*TWhereLoop)(unsafe.Pointer(pLoop)).FaLTerm + uintptr(j)*4)) = pTerm
				goto _3
			_3:
				;
				j = j + 1
			}
			if j != libc.Int32FromUint16((*TIndex)(unsafe.Pointer(pIdx)).FnKeyCol) {
				goto _1
			}
			(*TWhereLoop)(unsafe.Pointer(pLoop)).FwsFlags = libc.Uint32FromInt32(libc.Int32FromInt32(WHERE_COLUMN_EQ) | libc.Int32FromInt32(WHERE_ONEROW) | libc.Int32FromInt32(WHERE_INDEXED))
			if int32(uint32(*(*uint16)(unsafe.Pointer(pIdx + 56))&0x20>>5)) != 0 || (*TSrcItem)(unsafe.Pointer(pItem)).FcolUsed&(*TIndex)(unsafe.Pointer(pIdx)).FcolNotIdxed == uint64(0) {
				**(**Tu32)(__ccgo_up(pLoop + 40)) |= uint32(WHERE_IDX_ONLY)
			}
			(*TWhereLoop)(unsafe.Pointer(pLoop)).FnLTerm = libc.Uint16FromInt32(j)
			(*(*struct {
				FnEq          Tu16
				FnBtm         Tu16
				FnTop         Tu16
				FnDistinctCol Tu16
				FpIndex       uintptr
				FpOrderBy     uintptr
			})(unsafe.Pointer(pLoop + 24))).FnEq = libc.Uint16FromInt32(j)
			(*(*struct {
				FnEq          Tu16
				FnBtm         Tu16
				FnTop         Tu16
				FnDistinctCol Tu16
				FpIndex       uintptr
				FpOrderBy     uintptr
			})(unsafe.Pointer(pLoop + 24))).FpIndex = pIdx
			/* TUNING: Cost of a unique index lookup is 15 */
			(*TWhereLoop)(unsafe.Pointer(pLoop)).FrRun = int16(39) /* 39==sqlite3LogEst(15) */
			break
			goto _1
		_1:
			;
			pIdx = (*TIndex)(unsafe.Pointer(pIdx)).FpNext
		}
	}
	if (*TWhereLoop)(unsafe.Pointer(pLoop)).FwsFlags != 0 {
		(*TWhereLoop)(unsafe.Pointer(pLoop)).FnOut = libc.Int16FromInt32(1)
		(*(*TWhereLevel)(unsafe.Pointer(pWInfo + 752))).FpWLoop = pLoop
		(*TWhereLoop)(unsafe.Pointer(pLoop)).FmaskSelf = uint64(1) /* sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur); */
		(*(*TWhereLevel)(unsafe.Pointer(pWInfo + 752))).FiTabCur = iCur
		(*TWhereInfo)(unsafe.Pointer(pWInfo)).FnRowOut = int16(1)
		if (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpOrderBy != 0 {
			(*TWhereInfo)(unsafe.Pointer(pWInfo)).FnOBSat = int8((*TExprList)(unsafe.Pointer((*TWhereInfo)(unsafe.Pointer(pWInfo)).FpOrderBy)).FnExpr)
		}
		if libc.Int32FromUint16((*TWhereInfo)(unsafe.Pointer(pWInfo)).FwctrlFlags)&int32(WHERE_WANT_DISTINCT) != 0 {
			(*TWhereInfo)(unsafe.Pointer(pWInfo)).FeDistinct = uint8(WHERE_DISTINCT_UNIQUE)
		}
		if libc.Int32FromUint8((**(**TWhereScan)(__ccgo_up(bp))).FiEquiv) > int32(1) {
			**(**Tu32)(__ccgo_up(pLoop + 40)) |= uint32(WHERE_TRANSCONS)
		}
		return int32(1)
	}
	return 0
}

// C documentation
//
//	/*
//	** The journal file must be open when this routine is called. A journal
//	** header (JOURNAL_HDR_SZ bytes) is written into the journal file at the
//	** current location.
//	**
//	** The format for the journal header is as follows:
//	** - 8 bytes: Magic identifying journal format.
//	** - 4 bytes: Number of records in journal, or -1 no-sync mode is on.
//	** - 4 bytes: Random number used for page hash.
//	** - 4 bytes: Initial database page count.
//	** - 4 bytes: Sector size used by the process that wrote this journal.
//	** - 4 bytes: Database page size.
//	**
//	** Followed by (JOURNAL_HDR_SZ - 28) bytes of unused space.
//	*/
func _writeJournalHdr(tls *libc.TLS, pPager uintptr) (r int32) {
	var ii, rc int32
	var nHeader, nWrite Tu32
	var zHeader uintptr
	var v2 Ti64
	_, _, _, _, _, _ = ii, nHeader, nWrite, rc, zHeader, v2
	rc = SQLITE_OK                                                              /* Return code */
	zHeader = (*TPager)(unsafe.Pointer(pPager)).FpTmpSpace                      /* Temporary space used to build header */
	nHeader = libc.Uint32FromInt64((*TPager)(unsafe.Pointer(pPager)).FpageSize) /* Loop counter */
	/* Journal file must be open. */
	if nHeader > (*TPager)(unsafe.Pointer(pPager)).FsectorSize {
		nHeader = (*TPager)(unsafe.Pointer(pPager)).FsectorSize
	}
	/* If there are active savepoints and any of them were created
	 ** since the most recent journal header was written, update the
	 ** PagerSavepoint.iHdrOffset fields now.
	 */
	ii = 0
	for {
		if !(ii < (*TPager)(unsafe.Pointer(pPager)).FnSavepoint) {
			break
		}
		if (**(**TPagerSavepoint)(__ccgo_up((*TPager)(unsafe.Pointer(pPager)).FaSavepoint + uintptr(ii)*48))).FiHdrOffset == 0 {
			(**(**TPagerSavepoint)(__ccgo_up((*TPager)(unsafe.Pointer(pPager)).FaSavepoint + uintptr(ii)*48))).FiHdrOffset = (*TPager)(unsafe.Pointer(pPager)).FjournalOff
		}
		goto _1
	_1:
		;
		ii = ii + 1
	}
	v2 = _journalHdrOffset(tls, pPager)
	(*TPager)(unsafe.Pointer(pPager)).FjournalOff = v2
	(*TPager)(unsafe.Pointer(pPager)).FjournalHdr = v2
	/*
	 ** Write the nRec Field - the number of page records that follow this
	 ** journal header. Normally, zero is written to this value at this time.
	 ** After the records are added to the journal (and the journal synced,
	 ** if in full-sync mode), the zero is overwritten with the true number
	 ** of records (see syncJournal()).
	 **
	 ** A faster alternative is to write 0xFFFFFFFF to the nRec field. When
	 ** reading the journal this value tells SQLite to assume that the
	 ** rest of the journal file contains valid page records. This assumption
	 ** is dangerous, as if a failure occurred whilst writing to the journal
	 ** file it may contain some garbage data. There are two scenarios
	 ** where this risk can be ignored:
	 **
	 **   * When the pager is in no-sync mode. Corruption can follow a
	 **     power failure in this case anyway.
	 **
	 **   * When the SQLITE_IOCAP_SAFE_APPEND flag is set. This guarantees
	 **     that garbage data is never appended to the journal file.
	 */
	if (*TPager)(unsafe.Pointer(pPager)).FnoSync != 0 || libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FjournalMode) == int32(PAGER_JOURNALMODE_MEMORY) || _sqlite3OsDeviceCharacteristics(tls, (*TPager)(unsafe.Pointer(pPager)).Ffd)&int32(SQLITE_IOCAP_SAFE_APPEND) != 0 {
		libc.Xmemcpy(tls, zHeader, uintptr(unsafe.Pointer(&_aJournalMagic)), uint32(8))
		_sqlite3Put4byte(tls, zHeader+uintptr(8), uint32(0xffffffff))
	} else {
		libc.Xmemset(tls, zHeader, 0, libc.Uint32FromInt64(8)+libc.Uint32FromInt32(4))
	}
	/* The random check-hash initializer */
	if libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FjournalMode) != int32(PAGER_JOURNALMODE_MEMORY) {
		Xsqlite3_randomness(tls, int32(4), pPager+52)
	}
	_sqlite3Put4byte(tls, zHeader+uintptr(libc.Uint32FromInt64(8)+libc.Uint32FromInt32(4)), (*TPager)(unsafe.Pointer(pPager)).FcksumInit)
	/* The initial database size */
	_sqlite3Put4byte(tls, zHeader+uintptr(libc.Uint32FromInt64(8)+libc.Uint32FromInt32(8)), (*TPager)(unsafe.Pointer(pPager)).FdbOrigSize)
	/* The assumed sector size for this process */
	_sqlite3Put4byte(tls, zHeader+uintptr(libc.Uint32FromInt64(8)+libc.Uint32FromInt32(12)), (*TPager)(unsafe.Pointer(pPager)).FsectorSize)
	/* The page size */
	_sqlite3Put4byte(tls, zHeader+uintptr(libc.Uint32FromInt64(8)+libc.Uint32FromInt32(16)), libc.Uint32FromInt64((*TPager)(unsafe.Pointer(pPager)).FpageSize))
	/* Initializing the tail of the buffer is not necessary.  Everything
	 ** works find if the following memset() is omitted.  But initializing
	 ** the memory prevents valgrind from complaining, so we are willing to
	 ** take the performance hit.
	 */
	libc.Xmemset(tls, zHeader+uintptr(libc.Uint32FromInt64(8)+libc.Uint32FromInt32(20)), 0, nHeader-(libc.Uint32FromInt64(8)+libc.Uint32FromInt32(20)))
	/* In theory, it is only necessary to write the 28 bytes that the
	 ** journal header consumes to the journal file here. Then increment the
	 ** Pager.journalOff variable by JOURNAL_HDR_SZ so that the next
	 ** record is written to the following sector (leaving a gap in the file
	 ** that will be implicitly filled in by the OS).
	 **
	 ** However it has been discovered that on some systems this pattern can
	 ** be significantly slower than contiguously writing data to the file,
	 ** even if that means explicitly writing data to the block of
	 ** (JOURNAL_HDR_SZ - 28) bytes that will not be used. So that is what
	 ** is done.
	 **
	 ** The loop is required here in case the sector-size is larger than the
	 ** database page size. Since the zHeader buffer is only Pager.pageSize
	 ** bytes in size, more than one call to sqlite3OsWrite() may be required
	 ** to populate the entire journal header sector.
	 */
	nWrite = uint32(0)
	for {
		if !(rc == SQLITE_OK && nWrite < (*TPager)(unsafe.Pointer(pPager)).FsectorSize) {
			break
		}
		rc = _sqlite3OsWrite(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd, zHeader, libc.Int32FromUint32(nHeader), (*TPager)(unsafe.Pointer(pPager)).FjournalOff)
		**(**Ti64)(__ccgo_up(pPager + 76)) += libc.Int64FromUint32(nHeader)
		goto _3
	_3:
		;
		nWrite = nWrite + nHeader
	}
	return rc
}

// C documentation
//
//	/*
//	** Write the supplied super-journal name into the journal file for pager
//	** pPager at the current location. The super-journal name must be the last
//	** thing written to a journal file. If the pager is in full-sync mode, the
//	** journal file descriptor is advanced to the next sector boundary before
//	** anything is written. The format is:
//	**
//	**   + 4 bytes: PAGER_SJ_PGNO.
//	**   + N bytes: super-journal filename in utf-8.
//	**   + 4 bytes: N (length of super-journal name in bytes, no nul-terminator).
//	**   + 4 bytes: super-journal name checksum.
//	**   + 8 bytes: aJournalMagic[].
//	**
//	** The super-journal page checksum is the sum of the bytes in the super-journal
//	** name, where each byte is interpreted as a signed 8-bit integer.
//	**
//	** If zSuper is a NULL pointer (occurs for a single database transaction),
//	** this call is a no-op.
//	*/
func _writeSuperJournal(tls *libc.TLS, pPager uintptr, zSuper uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var cksum Tu32
	var iHdrOff Ti64
	var nSuper, rc, v2, v3, v5, v7, v9 int32
	var v10, v4, v6, v8 bool
	var _ /* jrnlSize at bp+0 */ Ti64
	_, _, _, _, _, _, _, _, _, _, _, _, _ = cksum, iHdrOff, nSuper, rc, v10, v2, v3, v4, v5, v6, v7, v8, v9 /* Size of journal file on disk */
	cksum = uint32(0)                                                                                       /* Checksum of string zSuper */
	if !(zSuper != 0) || libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FjournalMode) == int32(PAGER_JOURNALMODE_MEMORY) || !((*Tsqlite3_file)(unsafe.Pointer((*TPager)(unsafe.Pointer(pPager)).Fjfd)).FpMethods != libc.UintptrFromInt32(0)) {
		return SQLITE_OK
	}
	(*TPager)(unsafe.Pointer(pPager)).FsetSuper = uint8(1)
	/* Calculate the length in bytes and the checksum of zSuper */
	nSuper = 0
	for {
		if !(**(**int8)(__ccgo_up(zSuper + uintptr(nSuper))) != 0) {
			break
		}
		cksum = cksum + libc.Uint32FromInt8(**(**int8)(__ccgo_up(zSuper + uintptr(nSuper))))
		goto _1
	_1:
		;
		nSuper = nSuper + 1
	}
	/* If in full-sync mode, advance to the next disk sector before writing
	 ** the super-journal name. This is in case the previous page written to
	 ** the journal has already been synced.
	 */
	if (*TPager)(unsafe.Pointer(pPager)).FfullSync != 0 {
		(*TPager)(unsafe.Pointer(pPager)).FjournalOff = _journalHdrOffset(tls, pPager)
	}
	iHdrOff = (*TPager)(unsafe.Pointer(pPager)).FjournalOff
	/* Write the super-journal data to the end of the journal file. If
	 ** an error occurs, return the error code to the caller.
	 */
	v2 = _write32bits(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd, iHdrOff, (*TPager)(unsafe.Pointer(pPager)).FlckPgno)
	rc = v2
	if v4 = 0 != v2; !v4 {
		v3 = _sqlite3OsWrite(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd, zSuper, nSuper, iHdrOff+int64(4))
		rc = v3
	}
	if v6 = v4 || 0 != v3; !v6 {
		v5 = _write32bits(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd, iHdrOff+int64(4)+int64(nSuper), libc.Uint32FromInt32(nSuper))
		rc = v5
	}
	if v8 = v6 || 0 != v5; !v8 {
		v7 = _write32bits(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd, iHdrOff+int64(4)+int64(nSuper)+int64(4), cksum)
		rc = v7
	}
	if v10 = v8 || 0 != v7; !v10 {
		v9 = _sqlite3OsWrite(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd, uintptr(unsafe.Pointer(&_aJournalMagic)), int32(8), iHdrOff+int64(4)+int64(nSuper)+int64(8))
		rc = v9
	}
	if v10 || 0 != v9 {
		return rc
	}
	**(**Ti64)(__ccgo_up(pPager + 76)) += int64(nSuper + libc.Int32FromInt32(20))
	/* If the pager is in persistent-journal mode, then the physical
	 ** journal-file may extend past the end of the super-journal name
	 ** and 8 bytes of magic data just written to the file. This is
	 ** dangerous because the code to rollback a hot-journal file
	 ** will not be able to find the super-journal name to determine
	 ** whether or not the journal is hot.
	 **
	 ** Easiest thing to do in this scenario is to truncate the journal
	 ** file to the required size.
	 */
	v2 = _sqlite3OsFileSize(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd, bp)
	rc = v2
	if SQLITE_OK == v2 && **(**Ti64)(__ccgo_up(bp)) > (*TPager)(unsafe.Pointer(pPager)).FjournalOff {
		rc = _sqlite3OsTruncate(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd, (*TPager)(unsafe.Pointer(pPager)).FjournalOff)
	}
	return rc
}

// C documentation
//
//	/*
//	** Attempt the transfer optimization on INSERTs of the form
//	**
//	**     INSERT INTO tab1 SELECT * FROM tab2;
//	**
//	** The xfer optimization transfers raw records from tab2 over to tab1.
//	** Columns are not decoded and reassembled, which greatly improves
//	** performance.  Raw index records are transferred in the same way.
//	**
//	** The xfer optimization is only attempted if tab1 and tab2 are compatible.
//	** There are lots of rules for determining compatibility - see comments
//	** embedded in the code for details.
//	**
//	** This routine returns TRUE if the optimization is guaranteed to be used.
//	** Sometimes the xfer optimization will only work if the destination table
//	** is empty - a factor that can only be determined at run-time.  In that
//	** case, this routine generates code for the xfer optimization but also
//	** does a test to see if the destination table is empty and jumps over the
//	** xfer optimization code if the test fails.  In that case, this routine
//	** returns FALSE so that the caller will know to go ahead and generate
//	** an unoptimized transfer.  This routine also returns FALSE if there
//	** is no chance that the xfer optimization can be applied.
//	**
//	** This optimization is particularly useful at making VACUUM run faster.
//	*/
func _xferOptimization(tls *libc.TLS, pParse uintptr, pDest uintptr, pSelect uintptr, onError int32, iDbDest int32) (r int32) {
	var addr1, addr2, destHasUniqueIdx, emptyDestTest, emptySrcTest, i, iDbSrc, iDest, iSrc, regAutoinc, regData, regRowid, v4 int32
	var db, pDestCol, pDestExpr, pDestIdx, pEList, pItem, pSrc, pSrcCol, pSrcExpr, pSrcIdx, v, zColl, v5 uintptr
	var idxInsFlags, insFlags Tu8
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = addr1, addr2, db, destHasUniqueIdx, emptyDestTest, emptySrcTest, i, iDbSrc, iDest, iSrc, idxInsFlags, insFlags, pDestCol, pDestExpr, pDestIdx, pEList, pItem, pSrc, pSrcCol, pSrcExpr, pSrcIdx, regAutoinc, regData, regRowid, v, zColl, v4, v5
	db = (*TParse)(unsafe.Pointer(pParse)).Fdb /* Loop addresses */
	emptyDestTest = 0                          /* Address of test for empty pDest */
	emptySrcTest = 0                           /* Memory register used by AUTOINC */
	destHasUniqueIdx = 0                       /* Registers holding data and rowid */
	if (*TParse)(unsafe.Pointer(pParse)).FpWith != 0 || (*TSelect)(unsafe.Pointer(pSelect)).FpWith != 0 {
		/* Do not attempt to process this query if there are an WITH clauses
		 ** attached to it. Proceeding may generate a false "no such table: xxx"
		 ** error if pSelect reads from a CTE named "xxx".  */
		return 0
	}
	if libc.Int32FromUint8((*TTable)(unsafe.Pointer(pDest)).FeTabType) == int32(TABTYP_VTAB) {
		return 0 /* tab1 must not be a virtual table */
	}
	if onError == int32(OE_Default) {
		if int32((*TTable)(unsafe.Pointer(pDest)).FiPKey) >= 0 {
			onError = libc.Int32FromUint8((*TTable)(unsafe.Pointer(pDest)).FkeyConf)
		}
		if onError == int32(OE_Default) {
			onError = int32(OE_Abort)
		}
	}
	/* allocated even if there is no FROM clause */
	if (*TSrcList)(unsafe.Pointer((*TSelect)(unsafe.Pointer(pSelect)).FpSrc)).FnSrc != int32(1) {
		return 0 /* FROM clause must have exactly one term */
	}
	if int32(*(*uint32)(unsafe.Pointer((*TSelect)(unsafe.Pointer(pSelect)).FpSrc + 8 + 12 + 4))&0x4>>2) != 0 {
		return 0 /* FROM clause cannot contain a subquery */
	}
	if (*TSelect)(unsafe.Pointer(pSelect)).FpWhere != 0 {
		return 0 /* SELECT may not have a WHERE clause */
	}
	if (*TSelect)(unsafe.Pointer(pSelect)).FpOrderBy != 0 {
		return 0 /* SELECT may not have an ORDER BY clause */
	}
	/* Do not need to test for a HAVING clause.  If HAVING is present but
	 ** there is no ORDER BY, we will get an error. */
	if (*TSelect)(unsafe.Pointer(pSelect)).FpGroupBy != 0 {
		return 0 /* SELECT may not have a GROUP BY clause */
	}
	if (*TSelect)(unsafe.Pointer(pSelect)).FpLimit != 0 {
		return 0 /* SELECT may not have a LIMIT clause */
	}
	if (*TSelect)(unsafe.Pointer(pSelect)).FpPrior != 0 {
		return 0 /* SELECT may not be a compound query */
	}
	if (*TSelect)(unsafe.Pointer(pSelect)).FselFlags&uint32(SF_Distinct) != 0 {
		return 0 /* SELECT may not be DISTINCT */
	}
	pEList = (*TSelect)(unsafe.Pointer(pSelect)).FpEList
	if (*TExprList)(unsafe.Pointer(pEList)).FnExpr != int32(1) {
		return 0 /* The result set must have exactly one column */
	}
	if libc.Int32FromUint8((*TExpr)(unsafe.Pointer((*(*TExprList_item)(unsafe.Pointer(pEList + 8))).FpExpr)).Fop) != int32(TK_ASTERISK) {
		return 0 /* The result set must be the special operator "*" */
	}
	/* At this point we have established that the statement is of the
	 ** correct syntactic form to participate in this optimization.  Now
	 ** we have to check the semantics.
	 */
	pItem = (*TSelect)(unsafe.Pointer(pSelect)).FpSrc + 8
	pSrc = _sqlite3LocateTableItem(tls, pParse, uint32(0), pItem)
	if pSrc == uintptr(0) {
		return 0 /* FROM clause does not contain a real table */
	}
	if (*TTable)(unsafe.Pointer(pSrc)).Ftnum == (*TTable)(unsafe.Pointer(pDest)).Ftnum && (*TTable)(unsafe.Pointer(pSrc)).FpSchema == (*TTable)(unsafe.Pointer(pDest)).FpSchema {
		/* Possible due to bad sqlite_schema.rootpage */
		return 0 /* tab1 and tab2 may not be the same table */
	}
	if libc.BoolInt32((*TTable)(unsafe.Pointer(pDest)).FtabFlags&uint32(TF_WithoutRowid) == uint32(0)) != libc.BoolInt32((*TTable)(unsafe.Pointer(pSrc)).FtabFlags&uint32(TF_WithoutRowid) == uint32(0)) {
		return 0 /* source and destination must both be WITHOUT ROWID or not */
	}
	if !(libc.Int32FromUint8((*TTable)(unsafe.Pointer(pSrc)).FeTabType) == libc.Int32FromInt32(TABTYP_NORM)) {
		return 0 /* tab2 may not be a view or virtual table */
	}
	if int32((*TTable)(unsafe.Pointer(pDest)).FnCol) != int32((*TTable)(unsafe.Pointer(pSrc)).FnCol) {
		return 0 /* Number of columns must be the same in tab1 and tab2 */
	}
	if int32((*TTable)(unsafe.Pointer(pDest)).FiPKey) != int32((*TTable)(unsafe.Pointer(pSrc)).FiPKey) {
		return 0 /* Both tables must have the same INTEGER PRIMARY KEY */
	}
	if (*TTable)(unsafe.Pointer(pDest)).FtabFlags&uint32(TF_Strict) != uint32(0) && (*TTable)(unsafe.Pointer(pSrc)).FtabFlags&uint32(TF_Strict) == uint32(0) {
		return 0 /* Cannot feed from a non-strict into a strict table */
	}
	i = 0
	for {
		if !(i < int32((*TTable)(unsafe.Pointer(pDest)).FnCol)) {
			break
		}
		pDestCol = (*TTable)(unsafe.Pointer(pDest)).FaCol + uintptr(i)*12
		pSrcCol = (*TTable)(unsafe.Pointer(pSrc)).FaCol + uintptr(i)*12
		/* Even if tables t1 and t2 have identical schemas, if they contain
		 ** generated columns, then this statement is semantically incorrect:
		 **
		 **     INSERT INTO t2 SELECT * FROM t1;
		 **
		 ** The reason is that generated column values are returned by the
		 ** the SELECT statement on the right but the INSERT statement on the
		 ** left wants them to be omitted.
		 **
		 ** Nevertheless, this is a useful notational shorthand to tell SQLite
		 ** to do a bulk transfer all of the content from t1 over to t2.
		 **
		 ** We could, in theory, disable this (except for internal use by the
		 ** VACUUM command where it is actually needed).  But why do that?  It
		 ** seems harmless enough, and provides a useful service.
		 */
		if libc.Int32FromUint16((*TColumn)(unsafe.Pointer(pDestCol)).FcolFlags)&int32(COLFLAG_GENERATED) != libc.Int32FromUint16((*TColumn)(unsafe.Pointer(pSrcCol)).FcolFlags)&int32(COLFLAG_GENERATED) {
			return 0 /* Both columns have the same generated-column type */
		}
		/* But the transfer is only allowed if both the source and destination
		 ** tables have the exact same expressions for generated columns.
		 ** This requirement could be relaxed for VIRTUAL columns, I suppose.
		 */
		if libc.Int32FromUint16((*TColumn)(unsafe.Pointer(pDestCol)).FcolFlags)&int32(COLFLAG_GENERATED) != 0 {
			if _sqlite3ExprCompare(tls, uintptr(0), _sqlite3ColumnExpr(tls, pSrc, pSrcCol), _sqlite3ColumnExpr(tls, pDest, pDestCol), -int32(1)) != 0 {
				return 0 /* Different generator expressions */
			}
		}
		if int32((*TColumn)(unsafe.Pointer(pDestCol)).Faffinity) != int32((*TColumn)(unsafe.Pointer(pSrcCol)).Faffinity) {
			return 0 /* Affinity must be the same on all columns */
		}
		if Xsqlite3_stricmp(tls, _sqlite3ColumnColl(tls, pDestCol), _sqlite3ColumnColl(tls, pSrcCol)) != 0 {
			return 0 /* Collating sequence must be the same on all columns */
		}
		if int32(uint32(*(*uint8)(unsafe.Pointer(pDestCol + 4))&0xf>>0)) != 0 && !(int32(uint32(*(*uint8)(unsafe.Pointer(pSrcCol + 4))&0xf>>0)) != 0) {
			return 0 /* tab2 must be NOT NULL if tab1 is */
		}
		/* Default values for second and subsequent columns need to match. */
		if libc.Int32FromUint16((*TColumn)(unsafe.Pointer(pDestCol)).FcolFlags)&int32(COLFLAG_GENERATED) == 0 && i > 0 {
			pDestExpr = _sqlite3ColumnExpr(tls, pDest, pDestCol)
			pSrcExpr = _sqlite3ColumnExpr(tls, pSrc, pSrcCol)
			if libc.BoolInt32(pDestExpr == uintptr(0)) != libc.BoolInt32(pSrcExpr == uintptr(0)) || pDestExpr != uintptr(0) && libc.Xstrcmp(tls, *(*uintptr)(unsafe.Pointer(pDestExpr + 8)), *(*uintptr)(unsafe.Pointer(pSrcExpr + 8))) != 0 {
				return 0 /* Default values must be the same for all columns */
			}
		}
		goto _1
	_1:
		;
		i = i + 1
	}
	pDestIdx = (*TTable)(unsafe.Pointer(pDest)).FpIndex
	for {
		if !(pDestIdx != 0) {
			break
		}
		if libc.Int32FromUint8((*TIndex)(unsafe.Pointer(pDestIdx)).FonError) != OE_None {
			destHasUniqueIdx = int32(1)
		}
		pSrcIdx = (*TTable)(unsafe.Pointer(pSrc)).FpIndex
		for {
			if !(pSrcIdx != 0) {
				break
			}
			if _xferCompatibleIndex(tls, pDestIdx, pSrcIdx) != 0 {
				break
			}
			goto _3
		_3:
			;
			pSrcIdx = (*TIndex)(unsafe.Pointer(pSrcIdx)).FpNext
		}
		if pSrcIdx == uintptr(0) {
			return 0 /* pDestIdx has no corresponding index in pSrc */
		}
		if (*TIndex)(unsafe.Pointer(pSrcIdx)).Ftnum == (*TIndex)(unsafe.Pointer(pDestIdx)).Ftnum && (*TTable)(unsafe.Pointer(pSrc)).FpSchema == (*TTable)(unsafe.Pointer(pDest)).FpSchema && _sqlite3FaultSim(tls, int32(411)) == SQLITE_OK {
			/* The sqlite3FaultSim() call allows this corruption test to be
			 ** bypassed during testing, in order to exercise other corruption tests
			 ** further downstream. */
			return 0 /* Corrupt schema - two indexes on the same btree */
		}
		goto _2
	_2:
		;
		pDestIdx = (*TIndex)(unsafe.Pointer(pDestIdx)).FpNext
	}
	if (*TTable)(unsafe.Pointer(pDest)).FpCheck != 0 && (*Tsqlite3)(unsafe.Pointer(db)).FmDbFlags&uint32(DBFLAG_Vacuum) == uint32(0) && _sqlite3ExprListCompare(tls, (*TTable)(unsafe.Pointer(pSrc)).FpCheck, (*TTable)(unsafe.Pointer(pDest)).FpCheck, -int32(1)) != 0 {
		return 0 /* Tables have different CHECK constraints.  Ticket #2252 */
	}
	/* Disallow the transfer optimization if the destination table contains
	 ** any foreign key constraints.  This is more restrictive than necessary.
	 ** But the main beneficiary of the transfer optimization is the VACUUM
	 ** command, and the VACUUM command disables foreign key constraints.  So
	 ** the extra complication to make this rule less restrictive is probably
	 ** not worth the effort.  Ticket [6284df89debdfa61db8073e062908af0c9b6118e]
	 */
	if (*Tsqlite3)(unsafe.Pointer(db)).Fflags&uint64(SQLITE_ForeignKeys) != uint64(0) && (*(*struct {
		FaddColOffset int32
		FpFKey        uintptr
		FpDfltList    uintptr
	})(unsafe.Pointer(pDest + 44))).FpFKey != uintptr(0) {
		return 0
	}
	if (*Tsqlite3)(unsafe.Pointer(db)).Fflags&(libc.Uint64FromInt32(libc.Int32FromInt32(0x00001))<<libc.Int32FromInt32(32)) != uint64(0) {
		return 0 /* xfer opt does not play well with PRAGMA count_changes */
	}
	/* If we get this far, it means that the xfer optimization is at
	 ** least a possibility, though it might only work if the destination
	 ** table (tab1) is initially empty.
	 */
	iDbSrc = _sqlite3SchemaToIndex(tls, db, (*TTable)(unsafe.Pointer(pSrc)).FpSchema)
	v = _sqlite3GetVdbe(tls, pParse)
	_sqlite3CodeVerifySchema(tls, pParse, iDbSrc)
	v5 = pParse + 44
	v4 = *(*int32)(unsafe.Pointer(v5))
	*(*int32)(unsafe.Pointer(v5)) = *(*int32)(unsafe.Pointer(v5)) + 1
	iSrc = v4
	v5 = pParse + 44
	v4 = *(*int32)(unsafe.Pointer(v5))
	*(*int32)(unsafe.Pointer(v5)) = *(*int32)(unsafe.Pointer(v5)) + 1
	iDest = v4
	regAutoinc = _autoIncBegin(tls, pParse, iDbDest, pDest)
	regData = _sqlite3GetTempReg(tls, pParse)
	_sqlite3VdbeAddOp2(tls, v, int32(OP_Null), 0, regData)
	regRowid = _sqlite3GetTempReg(tls, pParse)
	_sqlite3OpenTable(tls, pParse, iDest, iDbDest, pDest, int32(OP_OpenWrite))
	if (*Tsqlite3)(unsafe.Pointer(db)).FmDbFlags&uint32(DBFLAG_Vacuum) == uint32(0) && (int32((*TTable)(unsafe.Pointer(pDest)).FiPKey) < 0 && (*TTable)(unsafe.Pointer(pDest)).FpIndex != uintptr(0) || destHasUniqueIdx != 0 || onError != int32(OE_Abort) && onError != int32(OE_Rollback)) {
		/* In some circumstances, we are able to run the xfer optimization
		 ** only if the destination table is initially empty. Unless the
		 ** DBFLAG_Vacuum flag is set, this block generates code to make
		 ** that determination. If DBFLAG_Vacuum is set, then the destination
		 ** table is always empty.
		 **
		 ** Conditions under which the destination must be empty:
		 **
		 ** (1) There is no INTEGER PRIMARY KEY but there are indices.
		 **     (If the destination is not initially empty, the rowid fields
		 **     of index entries might need to change.)
		 **
		 ** (2) The destination has a unique index.  (The xfer optimization
		 **     is unable to test uniqueness.)
		 **
		 ** (3) onError is something other than OE_Abort and OE_Rollback.
		 */
		addr1 = _sqlite3VdbeAddOp2(tls, v, int32(OP_Rewind), iDest, 0)
		emptyDestTest = _sqlite3VdbeAddOp0(tls, v, int32(OP_Goto))
		_sqlite3VdbeJumpHere(tls, v, addr1)
	}
	if (*TTable)(unsafe.Pointer(pSrc)).FtabFlags&uint32(TF_WithoutRowid) == uint32(0) {
		_sqlite3OpenTable(tls, pParse, iSrc, iDbSrc, pSrc, int32(OP_OpenRead))
		emptySrcTest = _sqlite3VdbeAddOp2(tls, v, int32(OP_Rewind), iSrc, 0)
		if int32((*TTable)(unsafe.Pointer(pDest)).FiPKey) >= 0 {
			addr1 = _sqlite3VdbeAddOp2(tls, v, int32(OP_Rowid), iSrc, regRowid)
			if (*Tsqlite3)(unsafe.Pointer(db)).FmDbFlags&uint32(DBFLAG_Vacuum) == uint32(0) {
				addr2 = _sqlite3VdbeAddOp3(tls, v, int32(OP_NotExists), iDest, 0, regRowid)
				_sqlite3RowidConstraint(tls, pParse, onError, pDest)
				_sqlite3VdbeJumpHere(tls, v, addr2)
			}
			_autoIncStep(tls, pParse, regAutoinc, regRowid)
		} else {
			if (*TTable)(unsafe.Pointer(pDest)).FpIndex == uintptr(0) && !((*Tsqlite3)(unsafe.Pointer(db)).FmDbFlags&libc.Uint32FromInt32(DBFLAG_VacuumInto) != 0) {
				addr1 = _sqlite3VdbeAddOp2(tls, v, int32(OP_NewRowid), iDest, regRowid)
			} else {
				addr1 = _sqlite3VdbeAddOp2(tls, v, int32(OP_Rowid), iSrc, regRowid)
			}
		}
		if (*Tsqlite3)(unsafe.Pointer(db)).FmDbFlags&uint32(DBFLAG_Vacuum) != 0 {
			_sqlite3VdbeAddOp1(tls, v, int32(OP_SeekEnd), iDest)
			insFlags = libc.Uint8FromInt32(libc.Int32FromInt32(OPFLAG_APPEND) | libc.Int32FromInt32(OPFLAG_USESEEKRESULT) | libc.Int32FromInt32(OPFLAG_PREFORMAT))
		} else {
			insFlags = libc.Uint8FromInt32(libc.Int32FromInt32(OPFLAG_NCHANGE) | libc.Int32FromInt32(OPFLAG_LASTROWID) | libc.Int32FromInt32(OPFLAG_APPEND) | libc.Int32FromInt32(OPFLAG_PREFORMAT))
		}
		if (*Tsqlite3)(unsafe.Pointer(db)).FmDbFlags&uint32(DBFLAG_Vacuum) == uint32(0) {
			_sqlite3VdbeAddOp3(tls, v, int32(OP_RowData), iSrc, regData, int32(1))
			insFlags = libc.Uint8FromInt32(int32(insFlags) & ^libc.Int32FromInt32(OPFLAG_PREFORMAT))
		} else {
			_sqlite3VdbeAddOp3(tls, v, int32(OP_RowCell), iDest, iSrc, regRowid)
		}
		_sqlite3VdbeAddOp3(tls, v, int32(OP_Insert), iDest, regData, regRowid)
		if (*Tsqlite3)(unsafe.Pointer(db)).FmDbFlags&uint32(DBFLAG_Vacuum) == uint32(0) {
			_sqlite3VdbeChangeP4(tls, v, -int32(1), pDest, -int32(5))
		}
		_sqlite3VdbeChangeP5(tls, v, uint16(insFlags))
		_sqlite3VdbeAddOp2(tls, v, int32(OP_Next), iSrc, addr1)
		_sqlite3VdbeAddOp2(tls, v, int32(OP_Close), iSrc, 0)
		_sqlite3VdbeAddOp2(tls, v, int32(OP_Close), iDest, 0)
	} else {
		_sqlite3TableLock(tls, pParse, iDbDest, (*TTable)(unsafe.Pointer(pDest)).Ftnum, uint8(1), (*TTable)(unsafe.Pointer(pDest)).FzName)
		_sqlite3TableLock(tls, pParse, iDbSrc, (*TTable)(unsafe.Pointer(pSrc)).Ftnum, uint8(0), (*TTable)(unsafe.Pointer(pSrc)).FzName)
	}
	pDestIdx = (*TTable)(unsafe.Pointer(pDest)).FpIndex
	for {
		if !(pDestIdx != 0) {
			break
		}
		idxInsFlags = uint8(0)
		pSrcIdx = (*TTable)(unsafe.Pointer(pSrc)).FpIndex
		for {
			if !(pSrcIdx != 0) {
				break
			}
			if _xferCompatibleIndex(tls, pDestIdx, pSrcIdx) != 0 {
				break
			}
			goto _9
		_9:
			;
			pSrcIdx = (*TIndex)(unsafe.Pointer(pSrcIdx)).FpNext
		}
		_sqlite3VdbeAddOp3(tls, v, int32(OP_OpenRead), iSrc, libc.Int32FromUint32((*TIndex)(unsafe.Pointer(pSrcIdx)).Ftnum), iDbSrc)
		_sqlite3VdbeSetP4KeyInfo(tls, pParse, pSrcIdx)
		_sqlite3VdbeAddOp3(tls, v, int32(OP_OpenWrite), iDest, libc.Int32FromUint32((*TIndex)(unsafe.Pointer(pDestIdx)).Ftnum), iDbDest)
		_sqlite3VdbeSetP4KeyInfo(tls, pParse, pDestIdx)
		_sqlite3VdbeChangeP5(tls, v, uint16(OPFLAG_BULKCSR))
		addr1 = _sqlite3VdbeAddOp2(tls, v, int32(OP_Rewind), iSrc, 0)
		if (*Tsqlite3)(unsafe.Pointer(db)).FmDbFlags&uint32(DBFLAG_Vacuum) != 0 {
			/* This INSERT command is part of a VACUUM operation, which guarantees
			 ** that the destination table is empty. If all indexed columns use
			 ** collation sequence BINARY, then it can also be assumed that the
			 ** index will be populated by inserting keys in strictly sorted
			 ** order. In this case, instead of seeking within the b-tree as part
			 ** of every OP_IdxInsert opcode, an OP_SeekEnd is added before the
			 ** OP_IdxInsert to seek to the point within the b-tree where each key
			 ** should be inserted. This is faster.
			 **
			 ** If any of the indexed columns use a collation sequence other than
			 ** BINARY, this optimization is disabled. This is because the user
			 ** might change the definition of a collation sequence and then run
			 ** a VACUUM command. In that case keys may not be written in strictly
			 ** sorted order.  */
			i = 0
			for {
				if !(i < libc.Int32FromUint16((*TIndex)(unsafe.Pointer(pSrcIdx)).FnColumn)) {
					break
				}
				zColl = **(**uintptr)(__ccgo_up((*TIndex)(unsafe.Pointer(pSrcIdx)).FazColl + uintptr(i)*4))
				if Xsqlite3_stricmp(tls, uintptr(unsafe.Pointer(&_sqlite3StrBINARY)), zColl) != 0 {
					break
				}
				goto _10
			_10:
				;
				i = i + 1
			}
			if i == libc.Int32FromUint16((*TIndex)(unsafe.Pointer(pSrcIdx)).FnColumn) {
				idxInsFlags = libc.Uint8FromInt32(libc.Int32FromInt32(OPFLAG_USESEEKRESULT) | libc.Int32FromInt32(OPFLAG_PREFORMAT))
				_sqlite3VdbeAddOp1(tls, v, int32(OP_SeekEnd), iDest)
				_sqlite3VdbeAddOp2(tls, v, int32(OP_RowCell), iDest, iSrc)
			}
		} else {
			if !((*TTable)(unsafe.Pointer(pSrc)).FtabFlags&libc.Uint32FromInt32(TF_WithoutRowid) == libc.Uint32FromInt32(0)) && int32(uint32(*(*uint16)(unsafe.Pointer(pDestIdx + 56))&0x3>>0)) == int32(SQLITE_IDXTYPE_PRIMARYKEY) {
				idxInsFlags = libc.Uint8FromInt32(int32(idxInsFlags) | libc.Int32FromInt32(OPFLAG_NCHANGE))
			}
		}
		if libc.Int32FromUint8(idxInsFlags) != libc.Int32FromInt32(OPFLAG_USESEEKRESULT)|libc.Int32FromInt32(OPFLAG_PREFORMAT) {
			_sqlite3VdbeAddOp3(tls, v, int32(OP_RowData), iSrc, regData, int32(1))
			if (*Tsqlite3)(unsafe.Pointer(db)).FmDbFlags&uint32(DBFLAG_Vacuum) == uint32(0) && !((*TTable)(unsafe.Pointer(pDest)).FtabFlags&libc.Uint32FromInt32(TF_WithoutRowid) == libc.Uint32FromInt32(0)) && int32(uint32(*(*uint16)(unsafe.Pointer(pDestIdx + 56))&0x3>>0)) == int32(SQLITE_IDXTYPE_PRIMARYKEY) {
				_codeWithoutRowidPreupdate(tls, pParse, pDest, iDest, regData)
			}
		}
		_sqlite3VdbeAddOp2(tls, v, int32(OP_IdxInsert), iDest, regData)
		_sqlite3VdbeChangeP5(tls, v, libc.Uint16FromInt32(libc.Int32FromUint8(idxInsFlags)|int32(OPFLAG_APPEND)))
		_sqlite3VdbeAddOp2(tls, v, int32(OP_Next), iSrc, addr1+int32(1))
		_sqlite3VdbeJumpHere(tls, v, addr1)
		_sqlite3VdbeAddOp2(tls, v, int32(OP_Close), iSrc, 0)
		_sqlite3VdbeAddOp2(tls, v, int32(OP_Close), iDest, 0)
		goto _8
	_8:
		;
		pDestIdx = (*TIndex)(unsafe.Pointer(pDestIdx)).FpNext
	}
	if emptySrcTest != 0 {
		_sqlite3VdbeJumpHere(tls, v, emptySrcTest)
	}
	_sqlite3ReleaseTempReg(tls, pParse, regRowid)
	_sqlite3ReleaseTempReg(tls, pParse, regData)
	if emptyDestTest != 0 {
		_sqlite3AutoincrementEnd(tls, pParse)
		_sqlite3VdbeAddOp2(tls, v, int32(OP_Halt), SQLITE_OK, 0)
		_sqlite3VdbeJumpHere(tls, v, emptyDestTest)
		_sqlite3VdbeAddOp2(tls, v, int32(OP_Close), iDest, 0)
		return 0
	} else {
		return int32(1)
	}
	return r
}

// C documentation
//
//	/*
//	** Set up a raw page so that it looks like a database page holding
//	** no entries.
//	*/
func _zeroPage(tls *libc.TLS, pPage uintptr, flags int32) {
	var data, pBt uintptr
	var first, hdr, v1 int32
	_, _, _, _, _ = data, first, hdr, pBt, v1
	data = (*TMemPage)(unsafe.Pointer(pPage)).FaData
	pBt = (*TMemPage)(unsafe.Pointer(pPage)).FpBt
	hdr = libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pPage)).FhdrOffset)
	if libc.Int32FromUint16((*TBtShared)(unsafe.Pointer(pBt)).FbtsFlags)&int32(BTS_FAST_SECURE) != 0 {
		libc.Xmemset(tls, data+uintptr(hdr), 0, (*TBtShared)(unsafe.Pointer(pBt)).FusableSize-libc.Uint32FromInt32(hdr))
	}
	**(**uint8)(__ccgo_up(data + uintptr(hdr))) = libc.Uint8FromInt8(int8(flags))
	if flags&int32(PTF_LEAF) == 0 {
		v1 = int32(12)
	} else {
		v1 = int32(8)
	}
	first = hdr + v1
	libc.Xmemset(tls, data+uintptr(hdr+int32(1)), 0, uint32(4))
	**(**uint8)(__ccgo_up(data + uintptr(hdr+int32(7)))) = uint8(0)
	**(**uint8)(__ccgo_up(data + uintptr(hdr+int32(5)))) = uint8((*TBtShared)(unsafe.Pointer(pBt)).FusableSize >> libc.Int32FromInt32(8))
	**(**uint8)(__ccgo_up(data + uintptr(hdr+int32(5)) + 1)) = uint8((*TBtShared)(unsafe.Pointer(pBt)).FusableSize)
	(*TMemPage)(unsafe.Pointer(pPage)).FnFree = libc.Int32FromUint16(uint16((*TBtShared)(unsafe.Pointer(pBt)).FusableSize - libc.Uint32FromInt32(first)))
	_decodeFlags(tls, pPage, flags)
	(*TMemPage)(unsafe.Pointer(pPage)).FcellOffset = libc.Uint16FromInt32(first)
	(*TMemPage)(unsafe.Pointer(pPage)).FaDataEnd = data + uintptr((*TBtShared)(unsafe.Pointer(pBt)).FpageSize)
	(*TMemPage)(unsafe.Pointer(pPage)).FaCellIdx = data + uintptr(first)
	(*TMemPage)(unsafe.Pointer(pPage)).FaDataOfst = data + uintptr((*TMemPage)(unsafe.Pointer(pPage)).FchildPtrSize)
	(*TMemPage)(unsafe.Pointer(pPage)).FnOverflow = uint8(0)
	(*TMemPage)(unsafe.Pointer(pPage)).FmaskPage = uint16((*TBtShared)(unsafe.Pointer(pBt)).FpageSize - libc.Uint32FromInt32(1))
	(*TMemPage)(unsafe.Pointer(pPage)).FnCell = uint16(0)
	(*TMemPage)(unsafe.Pointer(pPage)).FisInit = uint8(1)
}
