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

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

package sqlite3

import (
	"unsafe"

	"modernc.org/libc"
)

type Ttimespec = struct {
	Ftv_sec  Ttime_t
	Ftv_nsec int64
}

// C documentation
//
//	/*
//	** Initialize the operating system interface.
//	**
//	** This routine registers all VFS implementations for unix-like operating
//	** systems.  This routine, and the sqlite3_os_end() routine that follows,
//	** should be the only routines in this file that are visible from other
//	** files.
//	**
//	** This routine is called once during SQLite initialization and by a
//	** single thread.  The memory allocation and mutex subsystems have not
//	** necessarily been initialized when this routine is called, and so they
//	** should not be used.
//	*/
func Xsqlite3_os_init(tls *libc.TLS) (r int32) {
	var i uint32
	_ = i
	/* Double-check that the aSyscall[] array has been constructed
	 ** correctly.  See ticket [bb3a86e890c8e96ab] */
	/* Register all VFSes defined in the aVfs[] array */
	i = uint32(0)
	for {
		if !(uint64(i) < libc.Uint64FromInt64(672)/libc.Uint64FromInt64(168)) {
			break
		}
		Xsqlite3_vfs_register(tls, uintptr(unsafe.Pointer(&_aVfs))+uintptr(i)*168, libc.BoolInt32(i == uint32(0)))
		goto _1
	_1:
		;
		i = i + 1
	}
	_unixBigLock = _sqlite3MutexAlloc(tls, int32(SQLITE_MUTEX_STATIC_VFS1))
	/* Validate lock assumptions */
	/* Number of available locks */
	/* Start of locking area */
	/* Locks:
	 **    WRITE       UNIX_SHM_BASE      120
	 **    CKPT        UNIX_SHM_BASE+1    121
	 **    RECOVER     UNIX_SHM_BASE+2    122
	 **    READ-0      UNIX_SHM_BASE+3    123
	 **    READ-1      UNIX_SHM_BASE+4    124
	 **    READ-2      UNIX_SHM_BASE+5    125
	 **    READ-3      UNIX_SHM_BASE+6    126
	 **    READ-4      UNIX_SHM_BASE+7    127
	 **    DMS         UNIX_SHM_BASE+8    128
	 */
	/* Byte offset of the deadman-switch */
	/* Initialize temp file dir array. */
	_unixTempFileInit(tls)
	return SQLITE_OK
}

/*
 ** The following macro defines an initializer for an sqlite3_vfs object.
 ** The name of the VFS is NAME.  The pAppData is a pointer to a pointer
 ** to the "finder" function.  (pAppData is a pointer to a pointer because
 ** silly C90 rules prohibit a void* from being cast to a function pointer
 ** and so we have to go through the intermediate pointer to avoid problems
 ** when compiling with -pedantic-errors on GCC.)
 **
 ** The FINDER parameter to this macro is the name of the pointer to the
 ** finder-function.  The finder-function returns a pointer to the
 ** sqlite_io_methods object that implements the desired locking
 ** behaviors.  See the division above that contains the IOMETHODS
 ** macro for addition information on finder-functions.
 **
 ** Most finders simply return a pointer to a fixed sqlite3_io_methods
 ** object.  But the "autolockIoFinder" available on MacOSX does a little
 ** more than that; it looks at the filesystem type that hosts the
 ** database file and tries to choose an locking method appropriate for
 ** that filesystem time.
 */

// C documentation
//
//	/*
//	** Return N random bytes.
//	*/
func Xsqlite3_randomness(tls *libc.TLS, N int32, pBuf uintptr) {
	var mutex, pVfs, zBuf, v1 uintptr
	_, _, _, _ = mutex, pVfs, zBuf, v1
	zBuf = pBuf
	if Xsqlite3_initialize(tls) != 0 {
		return
	}
	mutex = _sqlite3MutexAlloc(tls, int32(SQLITE_MUTEX_STATIC_PRNG))
	Xsqlite3_mutex_enter(tls, mutex)
	if N <= 0 || pBuf == uintptr(0) {
		**(**Tu32)(__ccgo_up(uintptr(unsafe.Pointer(&_sqlite3Prng)))) = uint32(0)
		Xsqlite3_mutex_leave(tls, mutex)
		return
	}
	/* Initialize the state of the random number generator once,
	 ** the first time this routine is called.
	 */
	if **(**Tu32)(__ccgo_up(uintptr(unsafe.Pointer(&_sqlite3Prng)))) == uint32(0) {
		pVfs = Xsqlite3_vfs_find(tls, uintptr(0))
		libc.Xmemcpy(tls, uintptr(unsafe.Pointer(&_sqlite3Prng)), uintptr(unsafe.Pointer(&_chacha20_init)), uint64(16))
		if pVfs == uintptr(0) {
			libc.Xmemset(tls, uintptr(unsafe.Pointer(&_sqlite3Prng))+4*4, 0, uint64(44))
		} else {
			_sqlite3OsRandomness(tls, pVfs, int32(44), uintptr(unsafe.Pointer(&_sqlite3Prng))+4*4)
		}
		**(**Tu32)(__ccgo_up(uintptr(unsafe.Pointer(&_sqlite3Prng)) + 15*4)) = **(**Tu32)(__ccgo_up(uintptr(unsafe.Pointer(&_sqlite3Prng)) + 12*4))
		**(**Tu32)(__ccgo_up(uintptr(unsafe.Pointer(&_sqlite3Prng)) + 12*4)) = uint32(0)
		_sqlite3Prng.Fn = uint8(0)
	}
	for int32(1) != 0 {
		if N <= libc.Int32FromUint8(_sqlite3Prng.Fn) {
			libc.Xmemcpy(tls, zBuf, uintptr(unsafe.Pointer(&_sqlite3Prng))+64+uintptr(libc.Int32FromUint8(_sqlite3Prng.Fn)-N), libc.Uint64FromInt32(N))
			v1 = uintptr(unsafe.Pointer(&_sqlite3Prng)) + 128
			*(*Tu8)(unsafe.Pointer(v1)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v1))) - N)
			break
		}
		if libc.Int32FromUint8(_sqlite3Prng.Fn) > 0 {
			libc.Xmemcpy(tls, zBuf, uintptr(unsafe.Pointer(&_sqlite3Prng))+64, uint64(_sqlite3Prng.Fn))
			N = N - libc.Int32FromUint8(_sqlite3Prng.Fn)
			zBuf = zBuf + uintptr(_sqlite3Prng.Fn)
		}
		**(**Tu32)(__ccgo_up(uintptr(unsafe.Pointer(&_sqlite3Prng)) + 12*4)) = **(**Tu32)(__ccgo_up(uintptr(unsafe.Pointer(&_sqlite3Prng)) + 12*4)) + 1
		_chacha_block(tls, uintptr(unsafe.Pointer(&_sqlite3Prng))+64, uintptr(unsafe.Pointer(&_sqlite3Prng)))
		_sqlite3Prng.Fn = uint8(64)
	}
	Xsqlite3_mutex_leave(tls, mutex)
}

// 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 + 808
	p = (*Tsqlite3)(unsafe.Pointer(db)).FpDbData
	for {
		if !(p != 0 && libc.Xstrcmp(tls, p+24, 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(uint64(libc.UintptrFromInt32(0)+24)+(n+libc.Uint64FromInt32(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+24, zName, n+uint64(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
//
//	/*
//	** Append N bytes of text from z to the StrAccum object.  Increase the
//	** size of the memory allocation for StrAccum if necessary.
//	*/
func Xsqlite3_str_append(tls *libc.TLS, p uintptr, z uintptr, N int32) {
	if (*Tsqlite3_str)(unsafe.Pointer(p)).FnChar+libc.Uint32FromInt32(N) >= (*Tsqlite3_str)(unsafe.Pointer(p)).FnAlloc {
		_enlargeAndAppend(tls, p, z, N)
	} else {
		if N != 0 {
			**(**Tu32)(__ccgo_up(p + 24)) += libc.Uint32FromInt32(N)
			libc.Xmemcpy(tls, (*Tsqlite3_str)(unsafe.Pointer(p)).FzText+uintptr((*Tsqlite3_str)(unsafe.Pointer(p)).FnChar-libc.Uint32FromInt32(N)), z, libc.Uint64FromInt32(N))
		}
	}
}

// C documentation
//
//	/* Make a copy of an sqlite3_value object
//	*/
func Xsqlite3_value_dup(tls *libc.TLS, pOrig uintptr) (r uintptr) {
	var pNew, v1 uintptr
	_, _ = pNew, v1
	if pOrig == uintptr(0) {
		return uintptr(0)
	}
	pNew = Xsqlite3_malloc(tls, int32(56))
	if pNew == uintptr(0) {
		return uintptr(0)
	}
	libc.Xmemset(tls, pNew, 0, uint64(56))
	libc.Xmemcpy(tls, pNew, pOrig, uint64(libc.UintptrFromInt32(0)+24))
	v1 = pNew + 20
	*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) & ^libc.Int32FromInt32(MEM_Dyn))
	(*Tsqlite3_value)(unsafe.Pointer(pNew)).Fdb = uintptr(0)
	if libc.Int32FromUint16((*Tsqlite3_value)(unsafe.Pointer(pNew)).Fflags)&(libc.Int32FromInt32(MEM_Str)|libc.Int32FromInt32(MEM_Blob)) != 0 {
		v1 = pNew + 20
		*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) & ^(libc.Int32FromInt32(MEM_Static) | libc.Int32FromInt32(MEM_Dyn)))
		v1 = pNew + 20
		*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) | libc.Int32FromInt32(MEM_Ephem))
		if _sqlite3VdbeMemMakeWriteable(tls, pNew) != SQLITE_OK {
			_sqlite3ValueFree(tls, pNew)
			pNew = uintptr(0)
		}
	} else {
		if libc.Int32FromUint16((*Tsqlite3_value)(unsafe.Pointer(pNew)).Fflags)&int32(MEM_Null) != 0 {
			/* Do not duplicate pointer values */
			v1 = pNew + 20
			*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) & ^(libc.Int32FromInt32(MEM_Term) | libc.Int32FromInt32(MEM_Subtype)))
		}
	}
	return pNew
}

// C documentation
//
//	/*
//	** Configure the change currently under construction with a blob value.
//	*/
func Xsqlite3changegroup_change_blob(tls *libc.TLS, pGrp uintptr, bNew int32, iCol int32, pVal uintptr, nVal int32) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var nByte Tsqlite3_int64
	var rc, v1 int32
	var _ /* pBuf at bp+0 */ uintptr
	_, _, _ = nByte, rc, v1
	nByte = int64(int32(1)+_sessionVarintLen(tls, nVal)) + int64(nVal)
	rc = SQLITE_OK
	**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
	v1 = _checkChangeParams(tls, pGrp, bNew, iCol, nByte, bp)
	rc = v1
	if SQLITE_OK != v1 {
		return rc
	}
	**(**Tu8)(__ccgo_up((*TSessionBuffer)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FaBuf)) = uint8(SQLITE_BLOB)
	(*TSessionBuffer)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FnBuf = int32(1) + _sessionVarintPut(tls, (*TSessionBuffer)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FaBuf+1, nVal)
	libc.Xmemcpy(tls, (*TSessionBuffer)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FaBuf+uintptr((*TSessionBuffer)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FnBuf), pVal, libc.Uint64FromInt32(nVal))
	**(**int32)(__ccgo_up(**(**uintptr)(__ccgo_up(bp)) + 8)) += nVal
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** Configure the change currently under construction with a text value.
//	*/
func Xsqlite3changegroup_change_text(tls *libc.TLS, pGrp uintptr, bNew int32, iCol int32, pVal uintptr, nVal int32) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var nByte Tsqlite3_int64
	var nText, rc, v2 int32
	var v1 uint64
	var _ /* pBuf at bp+0 */ uintptr
	_, _, _, _, _ = nByte, nText, rc, v1, v2
	if nVal >= 0 {
		v1 = libc.Uint64FromInt32(nVal)
	} else {
		v1 = libc.Xstrlen(tls, pVal)
	}
	nText = libc.Int32FromUint64(v1)
	nByte = int64(int32(1) + _sessionVarintLen(tls, nText) + nText)
	rc = SQLITE_OK
	**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
	v2 = _checkChangeParams(tls, pGrp, bNew, iCol, nByte, bp)
	rc = v2
	if SQLITE_OK != v2 {
		return rc
	}
	**(**Tu8)(__ccgo_up((*TSessionBuffer)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FaBuf)) = uint8(SQLITE_TEXT)
	(*TSessionBuffer)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FnBuf = int32(1) + _sessionVarintPut(tls, (*TSessionBuffer)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FaBuf+1, nText)
	libc.Xmemcpy(tls, (*TSessionBuffer)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FaBuf+uintptr((*TSessionBuffer)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FnBuf), pVal, libc.Uint64FromInt32(nText))
	**(**int32)(__ccgo_up(**(**uintptr)(__ccgo_up(bp)) + 8)) += nText
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** Create an RBU VFS named zName that accesses the underlying file-system
//	** via existing VFS zParent. The new object is registered as a non-default
//	** VFS with SQLite before returning.
//	*/
func Xsqlite3rbu_create_vfs(tls *libc.TLS, zName uintptr, zParent uintptr) (r int32) {
	var nByte, nName Tsize_t
	var pNew, pParent, zSpace, v1 uintptr
	var rc int32
	_, _, _, _, _, _, _ = nByte, nName, pNew, pParent, rc, zSpace, v1
	pNew = uintptr(0) /* Newly allocated VFS */
	rc = SQLITE_OK
	nName = libc.Xstrlen(tls, zName)
	nByte = uint64(208) + nName + uint64(1)
	pNew = Xsqlite3_malloc64(tls, nByte)
	if pNew == uintptr(0) {
		rc = int32(SQLITE_NOMEM)
	} else { /* Parent VFS */
		libc.Xmemset(tls, pNew, 0, nByte)
		pParent = Xsqlite3_vfs_find(tls, zParent)
		if pParent == uintptr(0) {
			rc = int32(SQLITE_NOTFOUND)
		} else {
			libc.Xmemcpy(tls, pNew, uintptr(unsafe.Pointer(&_vfs_template)), uint64(168))
			(*Trbu_vfs)(unsafe.Pointer(pNew)).Fbase.FmxPathname = (*Tsqlite3_vfs)(unsafe.Pointer(pParent)).FmxPathname
			(*Trbu_vfs)(unsafe.Pointer(pNew)).Fbase.FszOsFile = libc.Int32FromUint64(uint64(104) + libc.Uint64FromInt32((*Tsqlite3_vfs)(unsafe.Pointer(pParent)).FszOsFile))
			(*Trbu_vfs)(unsafe.Pointer(pNew)).FpRealVfs = pParent
			v1 = pNew + 1*208
			zSpace = v1
			(*Trbu_vfs)(unsafe.Pointer(pNew)).Fbase.FzName = v1
			libc.Xmemcpy(tls, zSpace, zName, nName)
			/* Allocate the mutex and register the new VFS (not as the default) */
			(*Trbu_vfs)(unsafe.Pointer(pNew)).Fmutex = Xsqlite3_mutex_alloc(tls, int32(SQLITE_MUTEX_RECURSIVE))
			if (*Trbu_vfs)(unsafe.Pointer(pNew)).Fmutex == uintptr(0) {
				rc = int32(SQLITE_NOMEM)
			} else {
				rc = Xsqlite3_vfs_register(tls, pNew, 0)
			}
		}
		if rc != SQLITE_OK {
			Xsqlite3_mutex_free(tls, (*Trbu_vfs)(unsafe.Pointer(pNew)).Fmutex)
			Xsqlite3_free(tls, pNew)
		}
	}
	return rc
}

// C documentation
//
//	/*
//	** Attach a table to a session. All subsequent changes made to the table
//	** while the session object is enabled will be recorded.
//	**
//	** Only tables that have a PRIMARY KEY defined may be attached. It does
//	** not matter if the PRIMARY KEY is an "INTEGER PRIMARY KEY" (rowid alias)
//	** or not.
//	*/
func Xsqlite3session_attach(tls *libc.TLS, pSession uintptr, zName uintptr) (r int32) {
	var nByte, nName, rc int32
	var pTab, ppTab uintptr
	_, _, _, _, _ = nByte, nName, pTab, ppTab, rc
	rc = SQLITE_OK
	Xsqlite3_mutex_enter(tls, Xsqlite3_db_mutex(tls, (*Tsqlite3_session)(unsafe.Pointer(pSession)).Fdb))
	if !(zName != 0) {
		(*Tsqlite3_session)(unsafe.Pointer(pSession)).FbAutoAttach = int32(1)
	} else { /* Number of bytes in string zName */
		/* First search for an existing entry. If one is found, this call is
		 ** a no-op. Return early. */
		nName = _sqlite3Strlen30(tls, zName)
		pTab = (*Tsqlite3_session)(unsafe.Pointer(pSession)).FpTable
		for {
			if !(pTab != 0) {
				break
			}
			if 0 == Xsqlite3_strnicmp(tls, (*TSessionTable)(unsafe.Pointer(pTab)).FzName, zName, nName+int32(1)) {
				break
			}
			goto _1
		_1:
			;
			pTab = (*TSessionTable)(unsafe.Pointer(pTab)).FpNext
		}
		if !(pTab != 0) {
			/* Allocate new SessionTable object. */
			nByte = libc.Int32FromUint64(uint64(88) + libc.Uint64FromInt32(nName) + uint64(1))
			pTab = _sessionMalloc64(tls, pSession, int64(nByte))
			if !(pTab != 0) {
				rc = int32(SQLITE_NOMEM)
			} else {
				libc.Xmemset(tls, pTab, 0, uint64(88))
				(*TSessionTable)(unsafe.Pointer(pTab)).FzName = pTab + 1*88
				libc.Xmemcpy(tls, (*TSessionTable)(unsafe.Pointer(pTab)).FzName, zName, libc.Uint64FromInt32(nName+int32(1)))
				ppTab = pSession + 88
				for {
					if !(**(**uintptr)(__ccgo_up(ppTab)) != 0) {
						break
					}
					goto _2
				_2:
					;
					ppTab = **(**uintptr)(__ccgo_up(ppTab))
				}
				**(**uintptr)(__ccgo_up(ppTab)) = pTab
			}
		}
	}
	Xsqlite3_mutex_leave(tls, Xsqlite3_db_mutex(tls, (*Tsqlite3_session)(unsafe.Pointer(pSession)).Fdb))
	return rc
}

// C documentation
//
//	/*
//	** Create a session object. This session object will record changes to
//	** database zDb attached to connection db.
//	*/
func Xsqlite3session_create(tls *libc.TLS, db uintptr, zDb uintptr, ppSession uintptr) (r int32) {
	var nDb int32
	var pNew, pOld uintptr
	_, _, _ = nDb, pNew, pOld        /* Session object already attached to db */
	nDb = _sqlite3Strlen30(tls, zDb) /* Length of zDb in bytes */
	/* Zero the output value in case an error occurs. */
	**(**uintptr)(__ccgo_up(ppSession)) = uintptr(0)
	/* Allocate and populate the new session object. */
	pNew = Xsqlite3_malloc64(tls, uint64(uint64(136)+libc.Uint64FromInt32(nDb)+uint64(1)))
	if !(pNew != 0) {
		return int32(SQLITE_NOMEM)
	}
	libc.Xmemset(tls, pNew, 0, uint64(136))
	(*Tsqlite3_session)(unsafe.Pointer(pNew)).Fdb = db
	(*Tsqlite3_session)(unsafe.Pointer(pNew)).FzDb = pNew + 1*136
	(*Tsqlite3_session)(unsafe.Pointer(pNew)).FbEnable = int32(1)
	libc.Xmemcpy(tls, (*Tsqlite3_session)(unsafe.Pointer(pNew)).FzDb, zDb, libc.Uint64FromInt32(nDb+int32(1)))
	_sessionPreupdateHooks(tls, pNew)
	/* Add the new session object to the linked list of session objects
	 ** attached to database handle $db. Do this under the cover of the db
	 ** handle mutex.  */
	Xsqlite3_mutex_enter(tls, Xsqlite3_db_mutex(tls, db))
	pOld = Xsqlite3_preupdate_hook(tls, db, __ccgo_fp(_xPreUpdate), pNew)
	(*Tsqlite3_session)(unsafe.Pointer(pNew)).FpNext = pOld
	Xsqlite3_mutex_leave(tls, Xsqlite3_db_mutex(tls, db))
	**(**uintptr)(__ccgo_up(ppSession)) = pNew
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** Arguments aIdx, aCell and aSpare all point to arrays of size
//	** nIdx. The aIdx array contains the set of integers from 0 to
//	** (nIdx-1) in no particular order. This function sorts the values
//	** in aIdx according to dimension iDim of the cells in aCell. The
//	** minimum value of dimension iDim is considered first, the
//	** maximum used to break ties.
//	**
//	** The aSpare array is used as temporary working space by the
//	** sorting algorithm.
//	*/
func _SortByDimension(tls *libc.TLS, pRtree uintptr, aIdx uintptr, nIdx int32, iDim int32, aCell uintptr, aSpare uintptr) {
	var aLeft, aRight uintptr
	var iLeft, iRight, nLeft, nRight int32
	var xleft1, xleft2, xright1, xright2 TRtreeDValue
	var v1, v2, v3, v4 float64
	_, _, _, _, _, _, _, _, _, _, _, _, _, _ = aLeft, aRight, iLeft, iRight, nLeft, nRight, xleft1, xleft2, xright1, xright2, v1, v2, v3, v4
	if nIdx > int32(1) {
		iLeft = 0
		iRight = 0
		nLeft = nIdx / int32(2)
		nRight = nIdx - nLeft
		aLeft = aIdx
		aRight = aIdx + uintptr(nLeft)*4
		_SortByDimension(tls, pRtree, aLeft, nLeft, iDim, aCell, aSpare)
		_SortByDimension(tls, pRtree, aRight, nRight, iDim, aCell, aSpare)
		libc.Xmemcpy(tls, aSpare, aLeft, uint64(4)*libc.Uint64FromInt32(nLeft))
		aLeft = aSpare
		for iLeft < nLeft || iRight < nRight {
			if libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FeCoordType) == RTREE_COORD_REAL32 {
				v1 = float64(*(*TRtreeValue)(unsafe.Pointer(aCell + uintptr(**(**int32)(__ccgo_up(aLeft + uintptr(iLeft)*4)))*48 + 8 + uintptr(iDim*int32(2))*4)))
			} else {
				v1 = float64(*(*int32)(unsafe.Pointer(aCell + uintptr(**(**int32)(__ccgo_up(aLeft + uintptr(iLeft)*4)))*48 + 8 + uintptr(iDim*int32(2))*4)))
			}
			xleft1 = v1
			if libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FeCoordType) == RTREE_COORD_REAL32 {
				v2 = float64(*(*TRtreeValue)(unsafe.Pointer(aCell + uintptr(**(**int32)(__ccgo_up(aLeft + uintptr(iLeft)*4)))*48 + 8 + uintptr(iDim*int32(2)+int32(1))*4)))
			} else {
				v2 = float64(*(*int32)(unsafe.Pointer(aCell + uintptr(**(**int32)(__ccgo_up(aLeft + uintptr(iLeft)*4)))*48 + 8 + uintptr(iDim*int32(2)+int32(1))*4)))
			}
			xleft2 = v2
			if libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FeCoordType) == RTREE_COORD_REAL32 {
				v3 = float64(*(*TRtreeValue)(unsafe.Pointer(aCell + uintptr(**(**int32)(__ccgo_up(aRight + uintptr(iRight)*4)))*48 + 8 + uintptr(iDim*int32(2))*4)))
			} else {
				v3 = float64(*(*int32)(unsafe.Pointer(aCell + uintptr(**(**int32)(__ccgo_up(aRight + uintptr(iRight)*4)))*48 + 8 + uintptr(iDim*int32(2))*4)))
			}
			xright1 = v3
			if libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FeCoordType) == RTREE_COORD_REAL32 {
				v4 = float64(*(*TRtreeValue)(unsafe.Pointer(aCell + uintptr(**(**int32)(__ccgo_up(aRight + uintptr(iRight)*4)))*48 + 8 + uintptr(iDim*int32(2)+int32(1))*4)))
			} else {
				v4 = float64(*(*int32)(unsafe.Pointer(aCell + uintptr(**(**int32)(__ccgo_up(aRight + uintptr(iRight)*4)))*48 + 8 + uintptr(iDim*int32(2)+int32(1))*4)))
			}
			xright2 = v4
			if iLeft != nLeft && (iRight == nRight || xleft1 < xright1 || xleft1 == xright1 && xleft2 < xright2) {
				**(**int32)(__ccgo_up(aIdx + uintptr(iLeft+iRight)*4)) = **(**int32)(__ccgo_up(aLeft + uintptr(iLeft)*4))
				iLeft = iLeft + 1
			} else {
				**(**int32)(__ccgo_up(aIdx + uintptr(iLeft+iRight)*4)) = **(**int32)(__ccgo_up(aRight + uintptr(iRight)*4))
				iRight = iRight + 1
			}
		}
	}
}

func _SplitNode(tls *libc.TLS, pRtree uintptr, pNode uintptr, pCell uintptr, iHeight int32) (r int32) {
	bp := tls.Alloc(112)
	defer tls.Free(112)
	var aCell, aiUsed, pLeft, pParent, pRight uintptr
	var i, nCell, newCellIsRight, rc, v2, v3 int32
	var iRowid, iRowid1 Ti64
	var v4, v5 bool
	var _ /* iCell at bp+96 */ int32
	var _ /* leftbbox at bp+0 */ TRtreeCell
	var _ /* rightbbox at bp+48 */ TRtreeCell
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = aCell, aiUsed, i, iRowid, iRowid1, nCell, newCellIsRight, pLeft, pParent, pRight, rc, v2, v3, v4, v5
	newCellIsRight = 0
	rc = SQLITE_OK
	nCell = _readInt16(tls, (*TRtreeNode)(unsafe.Pointer(pNode)).FzData+2)
	pLeft = uintptr(0)
	pRight = uintptr(0)
	/* Allocate an array and populate it with a copy of pCell and
	 ** all cells from node pLeft. Then zero the original node.
	 */
	aCell = Xsqlite3_malloc64(tls, uint64((libc.Uint64FromInt64(48)+libc.Uint64FromInt64(4))*libc.Uint64FromInt32(nCell+libc.Int32FromInt32(1))))
	if !(aCell != 0) {
		rc = int32(SQLITE_NOMEM)
		goto splitnode_out
	}
	aiUsed = aCell + uintptr(nCell+int32(1))*48
	libc.Xmemset(tls, aiUsed, 0, uint64(4)*libc.Uint64FromInt32(nCell+libc.Int32FromInt32(1)))
	i = 0
	for {
		if !(i < nCell) {
			break
		}
		_nodeGetCell(tls, pRtree, pNode, i, aCell+uintptr(i)*48)
		goto _1
	_1:
		;
		i = i + 1
	}
	_nodeZero(tls, pRtree, pNode)
	libc.Xmemcpy(tls, aCell+uintptr(nCell)*48, pCell, uint64(48))
	nCell = nCell + 1
	if (*TRtreeNode)(unsafe.Pointer(pNode)).FiNode == int64(1) {
		pRight = _nodeNew(tls, pRtree, pNode)
		pLeft = _nodeNew(tls, pRtree, pNode)
		(*TRtree)(unsafe.Pointer(pRtree)).FiDepth = (*TRtree)(unsafe.Pointer(pRtree)).FiDepth + 1
		(*TRtreeNode)(unsafe.Pointer(pNode)).FisDirty = int32(1)
		_writeInt16(tls, (*TRtreeNode)(unsafe.Pointer(pNode)).FzData, (*TRtree)(unsafe.Pointer(pRtree)).FiDepth)
	} else {
		pLeft = pNode
		pRight = _nodeNew(tls, pRtree, (*TRtreeNode)(unsafe.Pointer(pLeft)).FpParent)
		(*TRtreeNode)(unsafe.Pointer(pLeft)).FnRef = (*TRtreeNode)(unsafe.Pointer(pLeft)).FnRef + 1
	}
	if !(pLeft != 0) || !(pRight != 0) {
		rc = int32(SQLITE_NOMEM)
		goto splitnode_out
	}
	libc.Xmemset(tls, (*TRtreeNode)(unsafe.Pointer(pLeft)).FzData, 0, libc.Uint64FromInt32((*TRtree)(unsafe.Pointer(pRtree)).FiNodeSize))
	libc.Xmemset(tls, (*TRtreeNode)(unsafe.Pointer(pRight)).FzData, 0, libc.Uint64FromInt32((*TRtree)(unsafe.Pointer(pRtree)).FiNodeSize))
	rc = _splitNodeStartree(tls, pRtree, aCell, nCell, pLeft, pRight, bp, bp+48)
	if rc != SQLITE_OK {
		goto splitnode_out
	}
	/* Ensure both child nodes have node numbers assigned to them by calling
	 ** nodeWrite(). Node pRight always needs a node number, as it was created
	 ** by nodeNew() above. But node pLeft sometimes already has a node number.
	 ** In this case avoid the all to nodeWrite().
	 */
	v2 = _nodeWrite(tls, pRtree, pRight)
	rc = v2
	if v5 = SQLITE_OK != v2; !v5 {
		if v4 = 0 == (*TRtreeNode)(unsafe.Pointer(pLeft)).FiNode; v4 {
			v3 = _nodeWrite(tls, pRtree, pLeft)
			rc = v3
		}
	}
	if v5 || v4 && SQLITE_OK != v3 {
		goto splitnode_out
	}
	(**(**TRtreeCell)(__ccgo_up(bp + 48))).FiRowid = (*TRtreeNode)(unsafe.Pointer(pRight)).FiNode
	(**(**TRtreeCell)(__ccgo_up(bp))).FiRowid = (*TRtreeNode)(unsafe.Pointer(pLeft)).FiNode
	if (*TRtreeNode)(unsafe.Pointer(pNode)).FiNode == int64(1) {
		rc = _rtreeInsertCell(tls, pRtree, (*TRtreeNode)(unsafe.Pointer(pLeft)).FpParent, bp, iHeight+int32(1))
		if rc != SQLITE_OK {
			goto splitnode_out
		}
	} else {
		pParent = (*TRtreeNode)(unsafe.Pointer(pLeft)).FpParent
		rc = _nodeParentIndex(tls, pRtree, pLeft, bp+96)
		if rc == SQLITE_OK {
			_nodeOverwriteCell(tls, pRtree, pParent, bp, **(**int32)(__ccgo_up(bp + 96)))
			rc = _AdjustTree(tls, pRtree, pParent, bp)
		}
		if rc != SQLITE_OK {
			goto splitnode_out
		}
	}
	v2 = _rtreeInsertCell(tls, pRtree, (*TRtreeNode)(unsafe.Pointer(pRight)).FpParent, bp+48, iHeight+int32(1))
	rc = v2
	if v2 != 0 {
		goto splitnode_out
	}
	i = 0
	for {
		if !(i < _readInt16(tls, (*TRtreeNode)(unsafe.Pointer(pRight)).FzData+2)) {
			break
		}
		iRowid = _nodeGetRowid(tls, pRtree, pRight, i)
		rc = _updateMapping(tls, pRtree, iRowid, pRight, iHeight)
		if iRowid == (*TRtreeCell)(unsafe.Pointer(pCell)).FiRowid {
			newCellIsRight = int32(1)
		}
		if rc != SQLITE_OK {
			goto splitnode_out
		}
		goto _7
	_7:
		;
		i = i + 1
	}
	if (*TRtreeNode)(unsafe.Pointer(pNode)).FiNode == int64(1) {
		i = 0
		for {
			if !(i < _readInt16(tls, (*TRtreeNode)(unsafe.Pointer(pLeft)).FzData+2)) {
				break
			}
			iRowid1 = _nodeGetRowid(tls, pRtree, pLeft, i)
			rc = _updateMapping(tls, pRtree, iRowid1, pLeft, iHeight)
			if rc != SQLITE_OK {
				goto splitnode_out
			}
			goto _8
		_8:
			;
			i = i + 1
		}
	} else {
		if newCellIsRight == 0 {
			rc = _updateMapping(tls, pRtree, (*TRtreeCell)(unsafe.Pointer(pCell)).FiRowid, pLeft, iHeight)
		}
	}
	goto splitnode_out
splitnode_out:
	;
	_nodeRelease(tls, pRtree, pRight)
	_nodeRelease(tls, pRtree, pLeft)
	Xsqlite3_free(tls, aCell)
	return rc
}

// C documentation
//
//	/*
//	** This function is used to read or overwrite payload information
//	** for the entry that the pCur cursor is pointing to. The eOp
//	** argument is interpreted as follows:
//	**
//	**   0: The operation is a read. Populate the overflow cache.
//	**   1: The operation is a write. Populate the overflow cache.
//	**
//	** A total of "amt" bytes are read or written beginning at "offset".
//	** Data is read to or from the buffer pBuf.
//	**
//	** The content being read or written might appear on the main page
//	** or be scattered out on multiple overflow pages.
//	**
//	** If the current cursor entry uses one or more overflow pages
//	** this function may allocate space for and lazily populate
//	** the overflow page-list cache array (BtCursor.aOverflow).
//	** Subsequent calls use this cache to make seeking to the supplied offset
//	** more efficient.
//	**
//	** Once an overflow page-list cache has been allocated, it must be
//	** invalidated if some other cursor writes to the same table, or if
//	** the cursor is moved to a different row. Additionally, in auto-vacuum
//	** mode, the following events may invalidate an overflow page-list cache.
//	**
//	**   * An incremental vacuum,
//	**   * A commit in auto_vacuum="full" mode,
//	**   * Creating a table (may require moving an overflow page).
//	*/
func _accessPayload(tls *libc.TLS, pCur uintptr, offset Tu32, amt Tu32, pBuf uintptr, eOp int32) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var a, a1, iIdx, rc, v2 int32
	var aNew, aPayload, aWrite, fd, pBt, pBufStart, pPage, v1 uintptr
	var nOvfl Ti64
	var ovflSize Tu32
	var _ /* aSave at bp+4 */ [4]Tu8
	var _ /* nextPage at bp+0 */ TPgno
	var _ /* pDbPage at bp+8 */ uintptr
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = a, a1, aNew, aPayload, aWrite, fd, iIdx, nOvfl, ovflSize, pBt, pBufStart, pPage, rc, v1, v2
	rc = SQLITE_OK
	iIdx = 0
	pPage = (*TBtCursor)(unsafe.Pointer(pCur)).FpPage /* Btree page of current entry */
	pBt = (*TBtCursor)(unsafe.Pointer(pCur)).FpBt     /* Btree this cursor belongs to */
	pBufStart = pBuf                                  /* Start of original out buffer */
	if libc.Int32FromUint16((*TBtCursor)(unsafe.Pointer(pCur)).Fix) >= libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FnCell) {
		return _sqlite3CorruptError(tls, int32(78282))
	}
	_getCellInfo(tls, pCur)
	aPayload = (*TBtCursor)(unsafe.Pointer(pCur)).Finfo.FpPayload
	if libc.Uint64FromInt64(int64(aPayload)-int64((*TMemPage)(unsafe.Pointer(pPage)).FaData)) > uint64((*TBtShared)(unsafe.Pointer(pBt)).FusableSize-uint32((*TBtCursor)(unsafe.Pointer(pCur)).Finfo.FnLocal)) {
		/* Trying to read or write past the end of the data is an error.  The
		 ** conditional above is really:
		 **    &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize]
		 ** but is recast into its current form to avoid integer overflow problems
		 */
		return _sqlite3CorruptError(tls, int32(78297))
	}
	/* Check if data must be read/written to/from the btree page itself. */
	if offset < uint32((*TBtCursor)(unsafe.Pointer(pCur)).Finfo.FnLocal) {
		a = libc.Int32FromUint32(amt)
		if libc.Uint32FromInt32(a)+offset > uint32((*TBtCursor)(unsafe.Pointer(pCur)).Finfo.FnLocal) {
			a = libc.Int32FromUint32(uint32((*TBtCursor)(unsafe.Pointer(pCur)).Finfo.FnLocal) - offset)
		}
		rc = _copyPayload(tls, aPayload+uintptr(offset), pBuf, a, eOp, (*TMemPage)(unsafe.Pointer(pPage)).FpDbPage)
		offset = uint32(0)
		pBuf = pBuf + uintptr(a)
		amt = amt - libc.Uint32FromInt32(a)
	} else {
		offset = offset - uint32((*TBtCursor)(unsafe.Pointer(pCur)).Finfo.FnLocal)
	}
	if rc == SQLITE_OK && amt > uint32(0) {
		ovflSize = (*TBtShared)(unsafe.Pointer(pBt)).FusableSize - uint32(4)
		**(**TPgno)(__ccgo_up(bp)) = _sqlite3Get4byte(tls, aPayload+uintptr((*TBtCursor)(unsafe.Pointer(pCur)).Finfo.FnLocal))
		/* If the BtCursor.aOverflow[] has not been allocated, allocate it now.
		 **
		 ** The aOverflow[] array is sized at one entry for each overflow page
		 ** in the overflow chain. The page number of the first overflow page is
		 ** stored in aOverflow[0], etc. A value of 0 in the aOverflow[] array
		 ** means "not yet known" (the cache is lazily populated).
		 */
		if libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCur)).FcurFlags)&int32(BTCF_ValidOvfl) == 0 {
			nOvfl = libc.Int64FromUint32((*TBtCursor)(unsafe.Pointer(pCur)).Finfo.FnPayload)
			nOvfl = (nOvfl - libc.Int64FromUint16((*TBtCursor)(unsafe.Pointer(pCur)).Finfo.FnLocal) + libc.Int64FromUint32(ovflSize) - int64(1)) / libc.Int64FromUint32(ovflSize)
			if (*TBtCursor)(unsafe.Pointer(pCur)).FaOverflow == uintptr(0) || nOvfl*int64(libc.Int32FromInt64(4)) > int64(_sqlite3MallocSize(tls, (*TBtCursor)(unsafe.Pointer(pCur)).FaOverflow)) {
				if _sqlite3FaultSim(tls, int32(413)) != 0 {
					aNew = uintptr(0)
				} else {
					aNew = _sqlite3Realloc(tls, (*TBtCursor)(unsafe.Pointer(pCur)).FaOverflow, libc.Uint64FromInt64(nOvfl*int64(2))*uint64(4))
				}
				if aNew == uintptr(0) {
					return int32(SQLITE_NOMEM)
				} else {
					(*TBtCursor)(unsafe.Pointer(pCur)).FaOverflow = aNew
				}
			}
			libc.Xmemset(tls, (*TBtCursor)(unsafe.Pointer(pCur)).FaOverflow, 0, uint64(libc.Uint64FromInt64(nOvfl)*uint64(4)))
			v1 = pCur + 1
			*(*Tu8)(unsafe.Pointer(v1)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v1))) | libc.Int32FromInt32(BTCF_ValidOvfl))
		} else {
			/* Sanity check the validity of the overflow page cache */
			/* If the overflow page-list cache has been allocated and the
			 ** entry for the first required overflow page is valid, skip
			 ** directly to it.
			 */
			if **(**TPgno)(__ccgo_up((*TBtCursor)(unsafe.Pointer(pCur)).FaOverflow + uintptr(offset/ovflSize)*4)) != 0 {
				iIdx = libc.Int32FromUint32(offset / ovflSize)
				**(**TPgno)(__ccgo_up(bp)) = **(**TPgno)(__ccgo_up((*TBtCursor)(unsafe.Pointer(pCur)).FaOverflow + uintptr(iIdx)*4))
				offset = offset % ovflSize
			}
		}
		for **(**TPgno)(__ccgo_up(bp)) != 0 {
			/* If required, populate the overflow page-list cache. */
			if **(**TPgno)(__ccgo_up(bp)) > (*TBtShared)(unsafe.Pointer(pBt)).FnPage {
				return _sqlite3CorruptError(tls, int32(78370))
			}
			**(**TPgno)(__ccgo_up((*TBtCursor)(unsafe.Pointer(pCur)).FaOverflow + uintptr(iIdx)*4)) = **(**TPgno)(__ccgo_up(bp))
			if offset >= ovflSize {
				/* The only reason to read this page is to obtain the page
				 ** number for the next page in the overflow chain. The page
				 ** data is not required. So first try to lookup the overflow
				 ** page-list cache, if any, then fall back to the getOverflowPage()
				 ** function.
				 */
				if **(**TPgno)(__ccgo_up((*TBtCursor)(unsafe.Pointer(pCur)).FaOverflow + uintptr(iIdx+int32(1))*4)) != 0 {
					**(**TPgno)(__ccgo_up(bp)) = **(**TPgno)(__ccgo_up((*TBtCursor)(unsafe.Pointer(pCur)).FaOverflow + uintptr(iIdx+int32(1))*4))
				} else {
					rc = _getOverflowPage(tls, pBt, **(**TPgno)(__ccgo_up(bp)), uintptr(0), bp)
				}
				offset = offset - ovflSize
			} else {
				/* Need to read this page properly. It contains some of the
				 ** range of data that is being read (eOp==0) or written (eOp!=0).
				 */
				a1 = libc.Int32FromUint32(amt)
				if libc.Uint32FromInt32(a1)+offset > ovflSize {
					a1 = libc.Int32FromUint32(ovflSize - offset)
				}
				/* If all the following are true:
				 **
				 **   1) this is a read operation, and
				 **   2) data is required from the start of this overflow page, and
				 **   3) there are no dirty pages in the page-cache
				 **   4) the database is file-backed, and
				 **   5) the page is not in the WAL file
				 **   6) at least 4 bytes have already been read into the output buffer
				 **
				 ** then data can be read directly from the database file into the
				 ** output buffer, bypassing the page-cache altogether. This speeds
				 ** up loading large records that span many overflow pages.
				 */
				if eOp == 0 && offset == uint32(0) && _sqlite3PagerDirectReadOk(tls, (*TBtShared)(unsafe.Pointer(pBt)).FpPager, **(**TPgno)(__ccgo_up(bp))) != 0 && pBuf+uintptr(-libc.Int32FromInt32(4)) >= pBufStart {
					fd = _sqlite3PagerFile(tls, (*TBtShared)(unsafe.Pointer(pBt)).FpPager)
					aWrite = pBuf + uintptr(-libc.Int32FromInt32(4))
					/* due to (6) */
					libc.Xmemcpy(tls, bp+4, aWrite, uint64(4))
					rc = _sqlite3OsRead(tls, fd, aWrite, a1+int32(4), libc.Int64FromUint32((*TBtShared)(unsafe.Pointer(pBt)).FpageSize)*libc.Int64FromUint32(**(**TPgno)(__ccgo_up(bp))-libc.Uint32FromInt32(1)))
					**(**TPgno)(__ccgo_up(bp)) = _sqlite3Get4byte(tls, aWrite)
					libc.Xmemcpy(tls, aWrite, bp+4, uint64(4))
				} else {
					if eOp == 0 {
						v2 = int32(PAGER_GET_READONLY)
					} else {
						v2 = 0
					}
					rc = _sqlite3PagerGet(tls, (*TBtShared)(unsafe.Pointer(pBt)).FpPager, **(**TPgno)(__ccgo_up(bp)), bp+8, v2)
					if rc == SQLITE_OK {
						if eOp != 0 && (_sqlite3PagerPageRefcount(tls, **(**uintptr)(__ccgo_up(bp + 8))) != int32(1) || (*TMemPage)(unsafe.Pointer(_sqlite3PagerGetExtra(tls, **(**uintptr)(__ccgo_up(bp + 8))))).FisInit != 0) {
							_sqlite3PagerUnref(tls, **(**uintptr)(__ccgo_up(bp + 8)))
							return _sqlite3CorruptError(tls, int32(78440))
						}
						aPayload = _sqlite3PagerGetData(tls, **(**uintptr)(__ccgo_up(bp + 8)))
						**(**TPgno)(__ccgo_up(bp)) = _sqlite3Get4byte(tls, aPayload)
						rc = _copyPayload(tls, aPayload+uintptr(offset+uint32(4)), pBuf, a1, eOp, **(**uintptr)(__ccgo_up(bp + 8)))
						_sqlite3PagerUnref(tls, **(**uintptr)(__ccgo_up(bp + 8)))
						offset = uint32(0)
					}
				}
				amt = amt - libc.Uint32FromInt32(a1)
				if amt == uint32(0) {
					return rc
				}
				pBuf = pBuf + uintptr(a1)
			}
			if rc != 0 {
				break
			}
			iIdx = iIdx + 1
		}
	}
	if rc == SQLITE_OK && amt > uint32(0) {
		/* Overflow chain ends prematurely */
		return _sqlite3CorruptError(tls, int32(78460))
	}
	return rc
}

// C documentation
//
//	/*
//	** Allocate a new page from the database file.
//	**
//	** The new page is marked as dirty.  (In other words, sqlite3PagerWrite()
//	** has already been called on the new page.)  The new page has also
//	** been referenced and the calling routine is responsible for calling
//	** sqlite3PagerUnref() on the new page when it is done.
//	**
//	** SQLITE_OK is returned on success.  Any other return value indicates
//	** an error.  *ppPage is set to NULL in the event of an error.
//	**
//	** If the "nearby" parameter is not 0, then an effort is made to
//	** locate a page close to the page number "nearby".  This can be used in an
//	** attempt to keep related pages close to each other in the database file,
//	** which in turn can make database access faster.
//	**
//	** If the eMode parameter is BTALLOC_EXACT and the nearby page exists
//	** anywhere on the free-list, then it is guaranteed to be returned.  If
//	** eMode is BTALLOC_LT then the page returned will be less than or equal
//	** to nearby if any such page exists.  If eMode is BTALLOC_ANY then there
//	** are no restrictions on which page is returned.
//	*/
func _allocateBtreePage(tls *libc.TLS, pBt uintptr, ppPage uintptr, pPgno uintptr, nearby TPgno, eMode Tu8) (r int32) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var aData, pPage1, pPrevTrunk uintptr
	var bNoContent, d2, dist, noContent, rc, v5 int32
	var closest, i, k, n, nSearch, v1 Tu32
	var iNewTrunk, iPage, iTrunk, mxPage TPgno
	var searchList Tu8
	var v2 bool
	var _ /* eType at bp+8 */ Tu8
	var _ /* pNewTrunk at bp+16 */ uintptr
	var _ /* pPg at bp+24 */ uintptr
	var _ /* pTrunk at bp+0 */ uintptr
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = aData, bNoContent, closest, d2, dist, i, iNewTrunk, iPage, iTrunk, k, mxPage, n, nSearch, noContent, pPage1, pPrevTrunk, rc, searchList, v1, v2, v5 /* Number of leaves on the trunk of the freelist */
	**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
	pPrevTrunk = uintptr(0) /* Total size of the database file */
	pPage1 = (*TBtShared)(unsafe.Pointer(pBt)).FpPage1
	mxPage = _btreePagecount(tls, pBt)
	/* EVIDENCE-OF: R-21003-45125 The 4-byte big-endian integer at offset 36
	 ** stores the total number of pages on the freelist. */
	n = _sqlite3Get4byte(tls, (*TMemPage)(unsafe.Pointer(pPage1)).FaData+36)
	if n >= mxPage {
		return _sqlite3CorruptError(tls, int32(79672))
	}
	if n > uint32(0) {
		searchList = uint8(0) /* If the free-list must be searched for 'nearby' */
		nSearch = uint32(0)   /* Count of the number of search attempts */
		/* If eMode==BTALLOC_EXACT and a query of the pointer-map
		 ** shows that the page 'nearby' is somewhere on the free-list, then
		 ** the entire-list will be searched for that page.
		 */
		if libc.Int32FromUint8(eMode) == int32(BTALLOC_EXACT) {
			if nearby <= mxPage {
				rc = _ptrmapGet(tls, pBt, nearby, bp+8, uintptr(0))
				if rc != 0 {
					return rc
				}
				if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(bp + 8))) == int32(PTRMAP_FREEPAGE) {
					searchList = uint8(1)
				}
			}
		} else {
			if libc.Int32FromUint8(eMode) == int32(BTALLOC_LE) {
				searchList = uint8(1)
			}
		}
		/* Decrement the free-list count by 1. Set iTrunk to the index of the
		 ** first free-list trunk page. iPrevTrunk is initially 1.
		 */
		rc = _sqlite3PagerWrite(tls, (*TMemPage)(unsafe.Pointer(pPage1)).FpDbPage)
		if rc != 0 {
			return rc
		}
		_sqlite3Put4byte(tls, (*TMemPage)(unsafe.Pointer(pPage1)).FaData+36, n-uint32(1))
		/* The code within this loop is run only once if the 'searchList' variable
		 ** is not true. Otherwise, it runs once for each trunk-page on the
		 ** free-list until the page 'nearby' is located (eMode==BTALLOC_EXACT)
		 ** or until a page less than 'nearby' is located (eMode==BTALLOC_LT)
		 */
		for cond := true; cond; cond = searchList != 0 {
			pPrevTrunk = **(**uintptr)(__ccgo_up(bp))
			if pPrevTrunk != 0 {
				/* EVIDENCE-OF: R-01506-11053 The first integer on a freelist trunk page
				 ** is the page number of the next freelist trunk page in the list or
				 ** zero if this is the last freelist trunk page. */
				iTrunk = _sqlite3Get4byte(tls, (*TMemPage)(unsafe.Pointer(pPrevTrunk)).FaData)
			} else {
				/* EVIDENCE-OF: R-59841-13798 The 4-byte big-endian integer at offset 32
				 ** stores the page number of the first page of the freelist, or zero if
				 ** the freelist is empty. */
				iTrunk = _sqlite3Get4byte(tls, (*TMemPage)(unsafe.Pointer(pPage1)).FaData+32)
			}
			if v2 = iTrunk > mxPage; !v2 {
				v1 = nSearch
				nSearch = nSearch + 1
			}
			if v2 || v1 > n {
				rc = _sqlite3CorruptError(tls, int32(79728))
			} else {
				rc = _btreeGetUnusedPage(tls, pBt, iTrunk, bp, 0)
			}
			if rc != 0 {
				**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
				goto end_allocate_page
			}
			/* EVIDENCE-OF: R-13523-04394 The second integer on a freelist trunk page
			 ** is the number of leaf page pointers to follow. */
			k = _sqlite3Get4byte(tls, (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FaData+4)
			if k == uint32(0) && !(searchList != 0) {
				/* The trunk has no leaves and the list is not being searched.
				 ** So extract the trunk page itself and use it as the newly
				 ** allocated page */
				rc = _sqlite3PagerWrite(tls, (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FpDbPage)
				if rc != 0 {
					goto end_allocate_page
				}
				**(**TPgno)(__ccgo_up(pPgno)) = iTrunk
				libc.Xmemcpy(tls, (*TMemPage)(unsafe.Pointer(pPage1)).FaData+32, (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FaData, uint64(4))
				**(**uintptr)(__ccgo_up(ppPage)) = **(**uintptr)(__ccgo_up(bp))
				**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
			} else {
				if k > (*TBtShared)(unsafe.Pointer(pBt)).FusableSize/libc.Uint32FromInt32(4)-libc.Uint32FromInt32(2) {
					/* Value of k is out of range.  Database corruption */
					rc = _sqlite3CorruptError(tls, int32(79757))
					goto end_allocate_page
				} else {
					if searchList != 0 && (nearby == iTrunk || iTrunk < nearby && libc.Int32FromUint8(eMode) == int32(BTALLOC_LE)) {
						/* The list is being searched and this trunk page is the page
						 ** to allocate, regardless of whether it has leaves.
						 */
						**(**TPgno)(__ccgo_up(pPgno)) = iTrunk
						**(**uintptr)(__ccgo_up(ppPage)) = **(**uintptr)(__ccgo_up(bp))
						searchList = uint8(0)
						rc = _sqlite3PagerWrite(tls, (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FpDbPage)
						if rc != 0 {
							goto end_allocate_page
						}
						if k == uint32(0) {
							if !(pPrevTrunk != 0) {
								libc.Xmemcpy(tls, (*TMemPage)(unsafe.Pointer(pPage1)).FaData+32, (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FaData, uint64(4))
							} else {
								rc = _sqlite3PagerWrite(tls, (*TMemPage)(unsafe.Pointer(pPrevTrunk)).FpDbPage)
								if rc != SQLITE_OK {
									goto end_allocate_page
								}
								libc.Xmemcpy(tls, (*TMemPage)(unsafe.Pointer(pPrevTrunk)).FaData, (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FaData, uint64(4))
							}
						} else {
							iNewTrunk = _sqlite3Get4byte(tls, (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FaData+8)
							if iNewTrunk > mxPage {
								rc = _sqlite3CorruptError(tls, int32(79791))
								goto end_allocate_page
							}
							rc = _btreeGetUnusedPage(tls, pBt, iNewTrunk, bp+16, 0)
							if rc != SQLITE_OK {
								goto end_allocate_page
							}
							rc = _sqlite3PagerWrite(tls, (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 16)))).FpDbPage)
							if rc != SQLITE_OK {
								_releasePage(tls, **(**uintptr)(__ccgo_up(bp + 16)))
								goto end_allocate_page
							}
							libc.Xmemcpy(tls, (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 16)))).FaData, (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FaData, uint64(4))
							_sqlite3Put4byte(tls, (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 16)))).FaData+4, k-uint32(1))
							libc.Xmemcpy(tls, (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 16)))).FaData+8, (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FaData+12, uint64((k-uint32(1))*uint32(4)))
							_releasePage(tls, **(**uintptr)(__ccgo_up(bp + 16)))
							if !(pPrevTrunk != 0) {
								_sqlite3Put4byte(tls, (*TMemPage)(unsafe.Pointer(pPage1)).FaData+32, iNewTrunk)
							} else {
								rc = _sqlite3PagerWrite(tls, (*TMemPage)(unsafe.Pointer(pPrevTrunk)).FpDbPage)
								if rc != 0 {
									goto end_allocate_page
								}
								_sqlite3Put4byte(tls, (*TMemPage)(unsafe.Pointer(pPrevTrunk)).FaData, iNewTrunk)
							}
						}
						**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
					} else {
						if k > uint32(0) {
							aData = (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FaData
							if nearby > uint32(0) {
								closest = uint32(0)
								if libc.Int32FromUint8(eMode) == int32(BTALLOC_LE) {
									i = uint32(0)
									for {
										if !(i < k) {
											break
										}
										iPage = _sqlite3Get4byte(tls, aData+uintptr(uint32(8)+i*uint32(4)))
										if iPage <= nearby {
											closest = i
											break
										}
										goto _3
									_3:
										;
										i = i + 1
									}
								} else {
									dist = _sqlite3AbsInt32(tls, libc.Int32FromUint32(_sqlite3Get4byte(tls, aData+8)-nearby))
									i = uint32(1)
									for {
										if !(i < k) {
											break
										}
										d2 = _sqlite3AbsInt32(tls, libc.Int32FromUint32(_sqlite3Get4byte(tls, aData+uintptr(uint32(8)+i*uint32(4)))-nearby))
										if d2 < dist {
											closest = i
											dist = d2
										}
										goto _4
									_4:
										;
										i = i + 1
									}
								}
							} else {
								closest = uint32(0)
							}
							iPage = _sqlite3Get4byte(tls, aData+uintptr(uint32(8)+closest*uint32(4)))
							if iPage > mxPage || iPage < uint32(2) {
								rc = _sqlite3CorruptError(tls, int32(79856))
								goto end_allocate_page
							}
							if !(searchList != 0) || (iPage == nearby || iPage < nearby && libc.Int32FromUint8(eMode) == int32(BTALLOC_LE)) {
								**(**TPgno)(__ccgo_up(pPgno)) = iPage
								rc = _sqlite3PagerWrite(tls, (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FpDbPage)
								if rc != 0 {
									goto end_allocate_page
								}
								if closest < k-uint32(1) {
									libc.Xmemcpy(tls, aData+uintptr(uint32(8)+closest*uint32(4)), aData+uintptr(uint32(4)+k*uint32(4)), uint64(4))
								}
								_sqlite3Put4byte(tls, aData+4, k-uint32(1))
								if !(_btreeGetHasContent(tls, pBt, **(**TPgno)(__ccgo_up(pPgno))) != 0) {
									v5 = int32(PAGER_GET_NOCONTENT)
								} else {
									v5 = 0
								}
								noContent = v5
								rc = _btreeGetUnusedPage(tls, pBt, **(**TPgno)(__ccgo_up(pPgno)), ppPage, noContent)
								if rc == SQLITE_OK {
									rc = _sqlite3PagerWrite(tls, (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(ppPage)))).FpDbPage)
									if rc != SQLITE_OK {
										_releasePage(tls, **(**uintptr)(__ccgo_up(ppPage)))
										**(**uintptr)(__ccgo_up(ppPage)) = uintptr(0)
									}
								}
								searchList = uint8(0)
							}
						}
					}
				}
			}
			_releasePage(tls, pPrevTrunk)
			pPrevTrunk = uintptr(0)
		}
	} else {
		if 0 == libc.Int32FromUint8((*TBtShared)(unsafe.Pointer(pBt)).FbDoTruncate) {
			v5 = int32(PAGER_GET_NOCONTENT)
		} else {
			v5 = 0
		}
		/* There are no pages on the freelist, so append a new page to the
		 ** database image.
		 **
		 ** Normally, new pages allocated by this block can be requested from the
		 ** pager layer with the 'no-content' flag set. This prevents the pager
		 ** from trying to read the pages content from disk. However, if the
		 ** current transaction has already run one or more incremental-vacuum
		 ** steps, then the page we are about to allocate may contain content
		 ** that is required in the event of a rollback. In this case, do
		 ** not set the no-content flag. This causes the pager to load and journal
		 ** the current page content before overwriting it.
		 **
		 ** Note that the pager will not actually attempt to load or journal
		 ** content for any page that really does lie past the end of the database
		 ** file on disk. So the effects of disabling the no-content optimization
		 ** here are confined to those pages that lie between the end of the
		 ** database image and the end of the database file.
		 */
		bNoContent = v5
		rc = _sqlite3PagerWrite(tls, (*TMemPage)(unsafe.Pointer((*TBtShared)(unsafe.Pointer(pBt)).FpPage1)).FpDbPage)
		if rc != 0 {
			return rc
		}
		(*TBtShared)(unsafe.Pointer(pBt)).FnPage = (*TBtShared)(unsafe.Pointer(pBt)).FnPage + 1
		if (*TBtShared)(unsafe.Pointer(pBt)).FnPage == libc.Uint32FromInt32(_sqlite3PendingByte)/(*TBtShared)(unsafe.Pointer(pBt)).FpageSize+libc.Uint32FromInt32(1) {
			(*TBtShared)(unsafe.Pointer(pBt)).FnPage = (*TBtShared)(unsafe.Pointer(pBt)).FnPage + 1
		}
		if (*TBtShared)(unsafe.Pointer(pBt)).FautoVacuum != 0 && _ptrmapPageno(tls, pBt, (*TBtShared)(unsafe.Pointer(pBt)).FnPage) == (*TBtShared)(unsafe.Pointer(pBt)).FnPage {
			/* If *pPgno refers to a pointer-map page, allocate two new pages
			 ** at the end of the file instead of one. The first allocated page
			 ** becomes a new pointer-map page, the second is used by the caller.
			 */
			**(**uintptr)(__ccgo_up(bp + 24)) = uintptr(0)
			rc = _btreeGetUnusedPage(tls, pBt, (*TBtShared)(unsafe.Pointer(pBt)).FnPage, bp+24, bNoContent)
			if rc == SQLITE_OK {
				rc = _sqlite3PagerWrite(tls, (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 24)))).FpDbPage)
				_releasePage(tls, **(**uintptr)(__ccgo_up(bp + 24)))
			}
			if rc != 0 {
				return rc
			}
			(*TBtShared)(unsafe.Pointer(pBt)).FnPage = (*TBtShared)(unsafe.Pointer(pBt)).FnPage + 1
			if (*TBtShared)(unsafe.Pointer(pBt)).FnPage == libc.Uint32FromInt32(_sqlite3PendingByte)/(*TBtShared)(unsafe.Pointer(pBt)).FpageSize+libc.Uint32FromInt32(1) {
				(*TBtShared)(unsafe.Pointer(pBt)).FnPage = (*TBtShared)(unsafe.Pointer(pBt)).FnPage + 1
			}
		}
		_sqlite3Put4byte(tls, uintptr(28)+(*TMemPage)(unsafe.Pointer((*TBtShared)(unsafe.Pointer(pBt)).FpPage1)).FaData, (*TBtShared)(unsafe.Pointer(pBt)).FnPage)
		**(**TPgno)(__ccgo_up(pPgno)) = (*TBtShared)(unsafe.Pointer(pBt)).FnPage
		rc = _btreeGetUnusedPage(tls, pBt, **(**TPgno)(__ccgo_up(pPgno)), ppPage, bNoContent)
		if rc != 0 {
			return rc
		}
		rc = _sqlite3PagerWrite(tls, (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(ppPage)))).FpDbPage)
		if rc != SQLITE_OK {
			_releasePage(tls, **(**uintptr)(__ccgo_up(ppPage)))
			**(**uintptr)(__ccgo_up(ppPage)) = uintptr(0)
		}
	}
	goto end_allocate_page
end_allocate_page:
	;
	_releasePage(tls, **(**uintptr)(__ccgo_up(bp)))
	_releasePage(tls, pPrevTrunk)
	return rc
}

// C documentation
//
//	/*
//	** Allocate VdbeCursor number iCur.  Return a pointer to it.  Return NULL
//	** if we run out of memory.
//	*/
func _allocateCursor(tls *libc.TLS, p uintptr, iCur int32, nField int32, eCurType Tu8) (r uintptr) {
	var nByte Ti64
	var pCx, pMem, v1 uintptr
	_, _, _, _ = nByte, pCx, pMem, v1
	if iCur > 0 {
		v1 = (*TVdbe)(unsafe.Pointer(p)).FaMem + uintptr((*TVdbe)(unsafe.Pointer(p)).FnMem-iCur)*56
	} else {
		v1 = (*TVdbe)(unsafe.Pointer(p)).FaMem
	}
	/* Find the memory cell that will be used to store the blob of memory
	 ** required for this VdbeCursor structure. It is convenient to use a
	 ** vdbe memory cell to manage the memory allocation required for a
	 ** VdbeCursor structure for the following reasons:
	 **
	 **   * Sometimes cursor numbers are used for a couple of different
	 **     purposes in a vdbe program. The different uses might require
	 **     different sized allocations. Memory cells provide growable
	 **     allocations.
	 **
	 **   * When using ENABLE_MEMORY_MANAGEMENT, memory cell buffers can
	 **     be freed lazily via the sqlite3_release_memory() API. This
	 **     minimizes the number of malloc calls made by the system.
	 **
	 ** The memory cell for cursor 0 is aMem[0]. The rest are allocated from
	 ** the top of the register space.  Cursor 1 is at Mem[p->nMem-1].
	 ** Cursor 2 is at Mem[p->nMem-2]. And so forth.
	 */
	pMem = v1
	pCx = uintptr(0)
	nByte = libc.Int64FromUint64((uint64(libc.UintptrFromInt32(0)+120)+libc.Uint64FromInt32(7))&libc.Uint64FromInt32(^libc.Int32FromInt32(7)) + libc.Uint64FromInt32(nField+libc.Int32FromInt32(1))*libc.Uint64FromInt64(8))
	if libc.Int32FromUint8(eCurType) == CURTYPE_BTREE {
		nByte = nByte + int64(_sqlite3BtreeCursorSize(tls))
	}
	if **(**uintptr)(__ccgo_up((*TVdbe)(unsafe.Pointer(p)).FapCsr + uintptr(iCur)*8)) != 0 { /*OPTIMIZATION-IF-FALSE*/
		_sqlite3VdbeFreeCursorNN(tls, p, **(**uintptr)(__ccgo_up((*TVdbe)(unsafe.Pointer(p)).FapCsr + uintptr(iCur)*8)))
		**(**uintptr)(__ccgo_up((*TVdbe)(unsafe.Pointer(p)).FapCsr + uintptr(iCur)*8)) = uintptr(0)
	}
	/* There used to be a call to sqlite3VdbeMemClearAndResize() to make sure
	 ** the pMem used to hold space for the cursor has enough storage available
	 ** in pMem->zMalloc.  But for the special case of the aMem[] entries used
	 ** to hold cursors, it is faster to in-line the logic. */
	if int64((*TMem)(unsafe.Pointer(pMem)).FszMalloc) < nByte {
		if (*TMem)(unsafe.Pointer(pMem)).FszMalloc > 0 {
			_sqlite3DbFreeNN(tls, (*TMem)(unsafe.Pointer(pMem)).Fdb, (*TMem)(unsafe.Pointer(pMem)).FzMalloc)
		}
		v1 = _sqlite3DbMallocRaw(tls, (*TMem)(unsafe.Pointer(pMem)).Fdb, libc.Uint64FromInt64(nByte))
		(*TMem)(unsafe.Pointer(pMem)).FzMalloc = v1
		(*TMem)(unsafe.Pointer(pMem)).Fz = v1
		if (*TMem)(unsafe.Pointer(pMem)).FzMalloc == uintptr(0) {
			(*TMem)(unsafe.Pointer(pMem)).FszMalloc = 0
			return uintptr(0)
		}
		(*TMem)(unsafe.Pointer(pMem)).FszMalloc = int32(nByte)
	}
	v1 = (*TMem)(unsafe.Pointer(pMem)).FzMalloc
	pCx = v1
	**(**uintptr)(__ccgo_up((*TVdbe)(unsafe.Pointer(p)).FapCsr + uintptr(iCur)*8)) = v1
	libc.Xmemset(tls, pCx, 0, uint64(libc.UintptrFromInt32(0)+40))
	(*TVdbeCursor)(unsafe.Pointer(pCx)).FeCurType = eCurType
	(*TVdbeCursor)(unsafe.Pointer(pCx)).FnField = int16(nField)
	(*TVdbeCursor)(unsafe.Pointer(pCx)).FaOffset = pCx + 120 + uintptr(nField)*4
	if libc.Int32FromUint8(eCurType) == CURTYPE_BTREE {
		*(*uintptr)(unsafe.Pointer(pCx + 48)) = (*TMem)(unsafe.Pointer(pMem)).Fz + uintptr((uint64(libc.UintptrFromInt32(0)+120)+libc.Uint64FromInt32(7))&libc.Uint64FromInt32(^libc.Int32FromInt32(7))+libc.Uint64FromInt32(nField+libc.Int32FromInt32(1))*libc.Uint64FromInt64(8))
		_sqlite3BtreeCursorZero(tls, *(*uintptr)(unsafe.Pointer(pCx + 48)))
	}
	return pCx
}

// 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, uint64(296))
		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, uint64(8))
	**(**uintptr)(__ccgo_up(pBt + 136)) += uintptr(4)
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** Parameter zSrcData points to a buffer containing the data for
//	** page iSrcPg from the source database. Copy this data into the
//	** destination database.
//	*/
func _backupOnePage(tls *libc.TLS, p uintptr, iSrcPg TPgno, zSrcData uintptr, bUpdate int32) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var iDest TPgno
	var iEnd, iOff Ti64
	var nCopy, nDestPgsz, nSrcPgsz, rc, v1, v3 int32
	var pDestPager, zDestData, zIn, zOut uintptr
	var v5 bool
	var _ /* pDestPg at bp+0 */ uintptr
	_, _, _, _, _, _, _, _, _, _, _, _, _, _ = iDest, iEnd, iOff, nCopy, nDestPgsz, nSrcPgsz, pDestPager, rc, zDestData, zIn, zOut, v1, v3, v5
	pDestPager = _sqlite3BtreePager(tls, (*Tsqlite3_backup)(unsafe.Pointer(p)).FpDest)
	nSrcPgsz = _sqlite3BtreeGetPageSize(tls, (*Tsqlite3_backup)(unsafe.Pointer(p)).FpSrc)
	nDestPgsz = _sqlite3BtreeGetPageSize(tls, (*Tsqlite3_backup)(unsafe.Pointer(p)).FpDest)
	if nSrcPgsz < nDestPgsz {
		v1 = nSrcPgsz
	} else {
		v1 = nDestPgsz
	}
	nCopy = v1
	iEnd = libc.Int64FromUint32(iSrcPg) * int64(nSrcPgsz)
	rc = SQLITE_OK
	/* This loop runs once for each destination page spanned by the source
	 ** page. For each iteration, variable iOff is set to the byte offset
	 ** of the destination page.
	 */
	iOff = iEnd - int64(nSrcPgsz)
	for {
		if !(rc == SQLITE_OK && iOff < iEnd) {
			break
		}
		**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
		iDest = libc.Uint32FromInt64(iOff/int64(nDestPgsz)) + uint32(1)
		if iDest == libc.Uint32FromInt32(_sqlite3PendingByte)/(*TBtShared)(unsafe.Pointer((*TBtree)(unsafe.Pointer((*Tsqlite3_backup)(unsafe.Pointer(p)).FpDest)).FpBt)).FpageSize+libc.Uint32FromInt32(1) {
			goto _2
		}
		v1 = _sqlite3PagerGet(tls, pDestPager, iDest, bp, 0)
		rc = v1
		if v5 = SQLITE_OK == v1; v5 {
			v3 = _sqlite3PagerWrite(tls, **(**uintptr)(__ccgo_up(bp)))
			rc = v3
		}
		if v5 && SQLITE_OK == v3 {
			zIn = zSrcData + uintptr(iOff%int64(nSrcPgsz))
			zDestData = _sqlite3PagerGetData(tls, **(**uintptr)(__ccgo_up(bp)))
			zOut = zDestData + uintptr(iOff%int64(nDestPgsz))
			/* Copy the data from the source page into the destination page.
			 ** Then clear the Btree layer MemPage.isInit flag. Both this module
			 ** and the pager code use this trick (clearing the first byte
			 ** of the page 'extra' space to invalidate the Btree layers
			 ** cached parse of the page). MemPage.isInit is marked
			 ** "MUST BE FIRST" for this purpose.
			 */
			libc.Xmemcpy(tls, zOut, zIn, libc.Uint64FromInt32(nCopy))
			**(**Tu8)(__ccgo_up(_sqlite3PagerGetExtra(tls, **(**uintptr)(__ccgo_up(bp))))) = uint8(0)
			if iOff == 0 && bUpdate == 0 {
				_sqlite3Put4byte(tls, zOut+28, _sqlite3BtreeLastPage(tls, (*Tsqlite3_backup)(unsafe.Pointer(p)).FpSrc))
			}
		}
		_sqlite3PagerUnref(tls, **(**uintptr)(__ccgo_up(bp)))
		goto _2
	_2:
		;
		iOff = iOff + int64(nDestPgsz)
	}
	return rc
}

// C documentation
//
//	/*
//	** This function is called when the root page of a b-tree structure is
//	** overfull (has one or more overflow pages).
//	**
//	** A new child page is allocated and the contents of the current root
//	** page, including overflow cells, are copied into the child. The root
//	** page is then overwritten to make it an empty page with the right-child
//	** pointer pointing to the new page.
//	**
//	** Before returning, all pointer-map entries corresponding to pages
//	** that the new child-page now contains pointers to are updated. The
//	** entry corresponding to the new right-child pointer of the root
//	** page is also updated.
//	**
//	** If successful, *ppChild is set to contain a reference to the child
//	** page and SQLITE_OK is returned. In this case the caller is required
//	** to call releasePage() on *ppChild exactly once. If an error occurs,
//	** an error code is returned and *ppChild is set to 0.
//	*/
func _balance_deeper(tls *libc.TLS, pRoot uintptr, ppChild uintptr) (r int32) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var pBt uintptr
	var _ /* pChild at bp+8 */ uintptr
	var _ /* pgnoChild at bp+16 */ TPgno
	var _ /* rc at bp+0 */ int32
	_ = pBt                                       /* Return value from subprocedures */
	**(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0) /* Pointer to a new child page */
	**(**TPgno)(__ccgo_up(bp + 16)) = uint32(0)   /* Page number of the new child page */
	pBt = (*TMemPage)(unsafe.Pointer(pRoot)).FpBt /* The BTree */
	/* Make pRoot, the root page of the b-tree, writable. Allocate a new
	 ** page that will become the new right-child of pPage. Copy the contents
	 ** of the node stored on pRoot into the new child page.
	 */
	**(**int32)(__ccgo_up(bp)) = _sqlite3PagerWrite(tls, (*TMemPage)(unsafe.Pointer(pRoot)).FpDbPage)
	if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
		**(**int32)(__ccgo_up(bp)) = _allocateBtreePage(tls, pBt, bp+8, bp+16, (*TMemPage)(unsafe.Pointer(pRoot)).Fpgno, uint8(0))
		_copyNodeContent(tls, pRoot, **(**uintptr)(__ccgo_up(bp + 8)), bp)
		if (*TBtShared)(unsafe.Pointer(pBt)).FautoVacuum != 0 {
			_ptrmapPut(tls, pBt, **(**TPgno)(__ccgo_up(bp + 16)), uint8(PTRMAP_BTREE), (*TMemPage)(unsafe.Pointer(pRoot)).Fpgno, bp)
		}
	}
	if **(**int32)(__ccgo_up(bp)) != 0 {
		**(**uintptr)(__ccgo_up(ppChild)) = uintptr(0)
		_releasePage(tls, **(**uintptr)(__ccgo_up(bp + 8)))
		return **(**int32)(__ccgo_up(bp))
	}
	/* Copy the overflow cells from pRoot to pChild */
	libc.Xmemcpy(tls, **(**uintptr)(__ccgo_up(bp + 8))+28, pRoot+28, uint64((*TMemPage)(unsafe.Pointer(pRoot)).FnOverflow)*uint64(2))
	libc.Xmemcpy(tls, **(**uintptr)(__ccgo_up(bp + 8))+40, pRoot+40, uint64((*TMemPage)(unsafe.Pointer(pRoot)).FnOverflow)*uint64(8))
	(*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 8)))).FnOverflow = (*TMemPage)(unsafe.Pointer(pRoot)).FnOverflow
	/* Zero the contents of pRoot. Then install pChild as the right-child. */
	_zeroPage(tls, pRoot, libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 8)))).FaData))) & ^libc.Int32FromInt32(PTF_LEAF))
	_sqlite3Put4byte(tls, (*TMemPage)(unsafe.Pointer(pRoot)).FaData+uintptr(libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pRoot)).FhdrOffset)+int32(8)), **(**TPgno)(__ccgo_up(bp + 16)))
	**(**uintptr)(__ccgo_up(ppChild)) = **(**uintptr)(__ccgo_up(bp + 8))
	return SQLITE_OK
}

// C documentation
//
//	/* Overwrite content from pX into pDest.  Only do the write if the
//	** content is different from what is already there.
//	*/
func _btreeOverwriteContent(tls *libc.TLS, pPage uintptr, pDest uintptr, pX uintptr, iOffset int32, iAmt int32) (r int32) {
	var i, nData, rc, rc1, rc2 int32
	_, _, _, _, _ = i, nData, rc, rc1, rc2
	nData = (*TBtreePayload)(unsafe.Pointer(pX)).FnData - iOffset
	if nData <= 0 {
		i = 0
		for {
			if !(i < iAmt && libc.Int32FromUint8(**(**Tu8)(__ccgo_up(pDest + uintptr(i)))) == 0) {
				break
			}
			goto _1
		_1:
			;
			i = i + 1
		}
		if i < iAmt {
			rc = _sqlite3PagerWrite(tls, (*TMemPage)(unsafe.Pointer(pPage)).FpDbPage)
			if rc != 0 {
				return rc
			}
			libc.Xmemset(tls, pDest+uintptr(i), 0, libc.Uint64FromInt32(iAmt-i))
		}
	} else {
		if nData < iAmt {
			/* Mixed read data and zeros at the end.  Make a recursive call
			 ** to write the zeros then fall through to write the real data */
			rc1 = _btreeOverwriteContent(tls, pPage, pDest+uintptr(nData), pX, iOffset+nData, iAmt-nData)
			if rc1 != 0 {
				return rc1
			}
			iAmt = nData
		}
		if libc.Xmemcmp(tls, pDest, (*TBtreePayload)(unsafe.Pointer(pX)).FpData+uintptr(iOffset), libc.Uint64FromInt32(iAmt)) != 0 {
			rc2 = _sqlite3PagerWrite(tls, (*TMemPage)(unsafe.Pointer(pPage)).FpDbPage)
			if rc2 != 0 {
				return rc2
			}
			/* In a corrupt database, it is possible for the source and destination
			 ** buffers to overlap.  This is harmless since the database is already
			 ** corrupt but it does cause valgrind and ASAN warnings.  So use
			 ** memmove(). */
			libc.Xmemmove(tls, pDest, (*TBtreePayload)(unsafe.Pointer(pX)).FpData+uintptr(iOffset), libc.Uint64FromInt32(iAmt))
		}
	}
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** This procedure generates VDBE code for a single invocation of either the
//	** sqlite_detach() or sqlite_attach() SQL user functions.
//	*/
func _codeAttach(tls *libc.TLS, pParse uintptr, type1 int32, pFunc uintptr, pAuthArg uintptr, pFilename uintptr, pDbname uintptr, pKey uintptr) {
	bp := tls.Alloc(64)
	defer tls.Free(64)
	var db, v, zAuthArg uintptr
	var rc, regArgs int32
	var _ /* sName at bp+0 */ TNameContext
	_, _, _, _, _ = db, rc, regArgs, v, zAuthArg
	db = (*TParse)(unsafe.Pointer(pParse)).Fdb
	if SQLITE_OK != _sqlite3ReadSchema(tls, pParse) {
		goto attach_end
	}
	if (*TParse)(unsafe.Pointer(pParse)).FnErr != 0 {
		goto attach_end
	}
	libc.Xmemset(tls, bp, 0, uint64(56))
	(**(**TNameContext)(__ccgo_up(bp))).FpParse = pParse
	if SQLITE_OK != _resolveAttachExpr(tls, bp, pFilename) || SQLITE_OK != _resolveAttachExpr(tls, bp, pDbname) || SQLITE_OK != _resolveAttachExpr(tls, bp, pKey) {
		goto attach_end
	}
	if pAuthArg != 0 {
		if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pAuthArg)).Fop) == int32(TK_STRING) {
			zAuthArg = *(*uintptr)(unsafe.Pointer(pAuthArg + 8))
		} else {
			zAuthArg = uintptr(0)
		}
		rc = _sqlite3AuthCheck(tls, pParse, type1, zAuthArg, uintptr(0), uintptr(0))
		if rc != SQLITE_OK {
			goto attach_end
		}
	}
	v = _sqlite3GetVdbe(tls, pParse)
	regArgs = _sqlite3GetTempRange(tls, pParse, int32(4))
	_sqlite3ExprCode(tls, pParse, pFilename, regArgs)
	_sqlite3ExprCode(tls, pParse, pDbname, regArgs+int32(1))
	_sqlite3ExprCode(tls, pParse, pKey, regArgs+int32(2))
	if v != 0 {
		_sqlite3VdbeAddFunctionCall(tls, pParse, 0, regArgs+int32(3)-int32((*TFuncDef)(unsafe.Pointer(pFunc)).FnArg), regArgs+int32(3), int32((*TFuncDef)(unsafe.Pointer(pFunc)).FnArg), pFunc, 0)
		/* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this
		 ** statement only). For DETACH, set it to false (expire all existing
		 ** statements).
		 */
		_sqlite3VdbeAddOp1(tls, v, int32(OP_Expire), libc.BoolInt32(type1 == int32(SQLITE_ATTACH)))
	}
	goto attach_end
attach_end:
	;
	_sqlite3ExprDelete(tls, db, pFilename)
	_sqlite3ExprDelete(tls, db, pDbname)
	_sqlite3ExprDelete(tls, db, pKey)
}

// C documentation
//
//	/*
//	** Detect compound SELECT statements that use an ORDER BY clause with
//	** an alternative collating sequence.
//	**
//	**    SELECT ... FROM t1 EXCEPT SELECT ... FROM t2 ORDER BY .. COLLATE ...
//	**
//	** These are rewritten as a subquery:
//	**
//	**    SELECT * FROM (SELECT ... FROM t1 EXCEPT SELECT ... FROM t2)
//	**     ORDER BY ... COLLATE ...
//	**
//	** This transformation is necessary because the multiSelectByMerge() routine
//	** above that generates the code for a compound SELECT with an ORDER BY clause
//	** uses a merge algorithm that requires the same collating sequence on the
//	** result columns as on the ORDER BY clause.  See ticket
//	** http://sqlite.org/src/info/6709574d2a
//	**
//	** This transformation is only needed for EXCEPT, INTERSECT, and UNION.
//	** The UNION ALL operator works fine with multiSelectByMerge() even when
//	** there are COLLATE terms in the ORDER BY.
//	*/
func _convertCompoundSelectToSubquery(tls *libc.TLS, pWalker uintptr, p uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var a, db, pNew, pNewSrc, pParse, pX uintptr
	var i int32
	var _ /* dummy at bp+0 */ TToken
	_, _, _, _, _, _, _ = a, db, i, pNew, pNewSrc, pParse, pX
	if (*TSelect)(unsafe.Pointer(p)).FpPrior == uintptr(0) {
		return WRC_Continue
	}
	if (*TSelect)(unsafe.Pointer(p)).FpOrderBy == uintptr(0) {
		return WRC_Continue
	}
	pX = p
	for {
		if !(pX != 0 && (libc.Int32FromUint8((*TSelect)(unsafe.Pointer(pX)).Fop) == int32(TK_ALL) || libc.Int32FromUint8((*TSelect)(unsafe.Pointer(pX)).Fop) == int32(TK_SELECT))) {
			break
		}
		goto _1
	_1:
		;
		pX = (*TSelect)(unsafe.Pointer(pX)).FpPrior
	}
	if pX == uintptr(0) {
		return WRC_Continue
	}
	a = (*TSelect)(unsafe.Pointer(p)).FpOrderBy + 8
	/* If iOrderByCol is already non-zero, then it has already been matched
	 ** to a result column of the SELECT statement. This occurs when the
	 ** SELECT is rewritten for window-functions processing and then passed
	 ** to sqlite3SelectPrep() and similar a second time. The rewriting done
	 ** by this function is not required in this case. */
	if *(*Tu16)(unsafe.Pointer(a + 24)) != 0 {
		return WRC_Continue
	}
	i = (*TExprList)(unsafe.Pointer((*TSelect)(unsafe.Pointer(p)).FpOrderBy)).FnExpr - int32(1)
	for {
		if !(i >= 0) {
			break
		}
		if (*TExpr)(unsafe.Pointer((**(**TExprList_item)(__ccgo_up(a + uintptr(i)*32))).FpExpr)).Fflags&uint32(EP_Collate) != 0 {
			break
		}
		goto _2
	_2:
		;
		i = i - 1
	}
	if i < 0 {
		return WRC_Continue
	}
	/* If we reach this point, that means the transformation is required. */
	pParse = (*TWalker)(unsafe.Pointer(pWalker)).FpParse
	db = (*TParse)(unsafe.Pointer(pParse)).Fdb
	pNew = _sqlite3DbMallocZero(tls, db, uint64(120))
	if pNew == uintptr(0) {
		return int32(WRC_Abort)
	}
	libc.Xmemset(tls, bp, 0, uint64(16))
	pNewSrc = _sqlite3SrcListAppendFromTerm(tls, pParse, uintptr(0), uintptr(0), uintptr(0), bp, pNew, uintptr(0))
	if (*TParse)(unsafe.Pointer(pParse)).FnErr != 0 {
		_sqlite3SrcListDelete(tls, db, pNewSrc)
		return int32(WRC_Abort)
	}
	**(**TSelect)(__ccgo_up(pNew)) = **(**TSelect)(__ccgo_up(p))
	(*TSelect)(unsafe.Pointer(p)).FpSrc = pNewSrc
	(*TSelect)(unsafe.Pointer(p)).FpEList = _sqlite3ExprListAppend(tls, pParse, uintptr(0), _sqlite3Expr(tls, db, int32(TK_ASTERISK), uintptr(0)))
	(*TSelect)(unsafe.Pointer(p)).Fop = uint8(TK_SELECT)
	(*TSelect)(unsafe.Pointer(p)).FpWhere = uintptr(0)
	(*TSelect)(unsafe.Pointer(pNew)).FpGroupBy = uintptr(0)
	(*TSelect)(unsafe.Pointer(pNew)).FpHaving = uintptr(0)
	(*TSelect)(unsafe.Pointer(pNew)).FpOrderBy = uintptr(0)
	(*TSelect)(unsafe.Pointer(p)).FpPrior = uintptr(0)
	(*TSelect)(unsafe.Pointer(p)).FpNext = uintptr(0)
	(*TSelect)(unsafe.Pointer(p)).FpWith = uintptr(0)
	(*TSelect)(unsafe.Pointer(p)).FpWinDefn = uintptr(0)
	**(**Tu32)(__ccgo_up(p + 4)) &= ^libc.Uint32FromInt32(SF_Compound)
	**(**Tu32)(__ccgo_up(p + 4)) |= uint32(SF_Converted)
	(*TSelect)(unsafe.Pointer((*TSelect)(unsafe.Pointer(pNew)).FpPrior)).FpNext = pNew
	(*TSelect)(unsafe.Pointer(pNew)).FpLimit = uintptr(0)
	return WRC_Continue
}

// C documentation
//
//	/*
//	** This function is used to copy the contents of the b-tree node stored
//	** on page pFrom to page pTo. If page pFrom was not a leaf page, then
//	** the pointer-map entries for each child page are updated so that the
//	** parent page stored in the pointer map is page pTo. If pFrom contained
//	** any cells with overflow page pointers, then the corresponding pointer
//	** map entries are also updated so that the parent page is page pTo.
//	**
//	** If pFrom is currently carrying any overflow cells (entries in the
//	** MemPage.apOvfl[] array), they are not copied to pTo.
//	**
//	** Before returning, page pTo is reinitialized using btreeInitPage().
//	**
//	** The performance of this function is not critical. It is only used by
//	** the balance_shallower() and balance_deeper() procedures, neither of
//	** which are called often under normal circumstances.
//	*/
func _copyNodeContent(tls *libc.TLS, pFrom uintptr, pTo uintptr, pRC uintptr) {
	var aFrom, aTo, pBt uintptr
	var iData, iFromHdr, iToHdr, rc, v1 int32
	_, _, _, _, _, _, _, _ = aFrom, aTo, iData, iFromHdr, iToHdr, pBt, rc, v1
	if **(**int32)(__ccgo_up(pRC)) == SQLITE_OK {
		pBt = (*TMemPage)(unsafe.Pointer(pFrom)).FpBt
		aFrom = (*TMemPage)(unsafe.Pointer(pFrom)).FaData
		aTo = (*TMemPage)(unsafe.Pointer(pTo)).FaData
		iFromHdr = libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pFrom)).FhdrOffset)
		if (*TMemPage)(unsafe.Pointer(pTo)).Fpgno == uint32(1) {
			v1 = int32(100)
		} else {
			v1 = 0
		}
		iToHdr = v1
		/* Copy the b-tree node content from page pFrom to page pTo. */
		iData = libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aFrom + uintptr(iFromHdr+int32(5)))))<<int32(8) | libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aFrom + uintptr(iFromHdr+int32(5)) + 1)))
		libc.Xmemcpy(tls, aTo+uintptr(iData), aFrom+uintptr(iData), uint64((*TBtShared)(unsafe.Pointer(pBt)).FusableSize-libc.Uint32FromInt32(iData)))
		libc.Xmemcpy(tls, aTo+uintptr(iToHdr), aFrom+uintptr(iFromHdr), libc.Uint64FromInt32(libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pFrom)).FcellOffset)+int32(2)*libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pFrom)).FnCell)))
		/* Reinitialize page pTo so that the contents of the MemPage structure
		 ** match the new data. The initialization of pTo can actually fail under
		 ** fairly obscure circumstances, even though it is a copy of initialized
		 ** page pFrom.
		 */
		(*TMemPage)(unsafe.Pointer(pTo)).FisInit = uint8(0)
		rc = _btreeInitPage(tls, pTo)
		if rc == SQLITE_OK {
			rc = _btreeComputeFreeSpace(tls, pTo)
		}
		if rc != SQLITE_OK {
			**(**int32)(__ccgo_up(pRC)) = rc
			return
		}
		/* If this is an auto-vacuum database, update the pointer-map entries
		 ** for any b-tree or overflow pages that pTo now contains the pointers to.
		 */
		if (*TBtShared)(unsafe.Pointer(pBt)).FautoVacuum != 0 {
			**(**int32)(__ccgo_up(pRC)) = _setChildPtrmaps(tls, pTo)
		}
	}
}

// C documentation
//
//	/*
//	** Copy data from a buffer to a page, or from a page to a buffer.
//	**
//	** pPayload is a pointer to data stored on database page pDbPage.
//	** If argument eOp is false, then nByte bytes of data are copied
//	** from pPayload to the buffer pointed at by pBuf. If eOp is true,
//	** then sqlite3PagerWrite() is called on pDbPage and nByte bytes
//	** of data are copied from the buffer pBuf to pPayload.
//	**
//	** SQLITE_OK is returned on success, otherwise an error code.
//	*/
func _copyPayload(tls *libc.TLS, pPayload uintptr, pBuf uintptr, nByte int32, eOp int32, pDbPage uintptr) (r int32) {
	var rc int32
	_ = rc
	if eOp != 0 {
		/* Copy data from buffer to page (a write operation) */
		rc = _sqlite3PagerWrite(tls, pDbPage)
		if rc != SQLITE_OK {
			return rc
		}
		libc.Xmemcpy(tls, pPayload, pBuf, libc.Uint64FromInt32(nByte))
	} else {
		/* Copy data from page to buffer (a read operation) */
		libc.Xmemcpy(tls, pBuf, pPayload, libc.Uint64FromInt32(nByte))
	}
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** Create a new aggregate context for p and return a pointer to
//	** its pMem->z element.
//	*/
func _createAggContext(tls *libc.TLS, p uintptr, nByte int32) (r uintptr) {
	var pMem uintptr
	_ = pMem
	pMem = (*Tsqlite3_context)(unsafe.Pointer(p)).FpMem
	if nByte <= 0 {
		_sqlite3VdbeMemSetNull(tls, pMem)
		(*TMem)(unsafe.Pointer(pMem)).Fz = uintptr(0)
	} else {
		_sqlite3VdbeMemClearAndResize(tls, pMem, nByte)
		(*TMem)(unsafe.Pointer(pMem)).Fflags = uint16(MEM_Agg)
		*(*uintptr)(unsafe.Pointer(pMem)) = (*Tsqlite3_context)(unsafe.Pointer(p)).FpFunc
		if (*TMem)(unsafe.Pointer(pMem)).Fz != 0 {
			libc.Xmemset(tls, (*TMem)(unsafe.Pointer(pMem)).Fz, 0, libc.Uint64FromInt32(nByte))
		}
	}
	return (*TMem)(unsafe.Pointer(pMem)).Fz
}

func _dbReallocFinish(tls *libc.TLS, db uintptr, p uintptr, n Tu64) (r uintptr) {
	var pNew uintptr
	_ = pNew
	pNew = uintptr(0)
	if libc.Int32FromUint8((*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed) == 0 {
		if _isLookaside(tls, db, p) != 0 {
			pNew = _sqlite3DbMallocRawNN(tls, db, n)
			if pNew != 0 {
				libc.Xmemcpy(tls, pNew, p, libc.Uint64FromInt32(_lookasideMallocSize(tls, db, p)))
				_sqlite3DbFree(tls, db, p)
			}
		} else {
			pNew = _sqlite3Realloc(tls, p, n)
			if !(pNew != 0) {
				_sqlite3OomFault(tls, db)
			}
		}
	}
	return pNew
}

// C documentation
//
//	/*
//	** Defragment the page given. This routine reorganizes cells within the
//	** page so that there are no free-blocks on the free-block list.
//	**
//	** Parameter nMaxFrag is the maximum amount of fragmented space that may be
//	** present in the page after this routine returns.
//	**
//	** EVIDENCE-OF: R-44582-60138 SQLite may from time to time reorganize a
//	** b-tree page so that there are no freeblocks or fragment bytes, all
//	** unused bytes are contained in the unallocated space region, and all
//	** cells are packed tightly at the end of the page.
//	*/
func _defragmentPage(tls *libc.TLS, pPage uintptr, nMaxFrag int32) (r int32) {
	var cbrk, cellOffset, hdr, i, iCellFirst, iCellLast, iCellStart, iFree, iFree2, nCell, pc, size, sz, sz2, top, usableSize int32
	var data, pAddr, pAddr1, pEnd, src, temp uintptr
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = cbrk, cellOffset, data, hdr, i, iCellFirst, iCellLast, iCellStart, iFree, iFree2, nCell, pAddr, pAddr1, pEnd, pc, size, src, sz, sz2, temp, top, usableSize /* First cell offset in input */
	data = (*TMemPage)(unsafe.Pointer(pPage)).FaData
	hdr = libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pPage)).FhdrOffset)
	cellOffset = libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FcellOffset)
	nCell = libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FnCell)
	iCellFirst = cellOffset + int32(2)*nCell
	usableSize = libc.Int32FromUint32((*TBtShared)(unsafe.Pointer((*TMemPage)(unsafe.Pointer(pPage)).FpBt)).FusableSize)
	/* This block handles pages with two or fewer free blocks and nMaxFrag
	 ** or fewer fragmented bytes. In this case it is faster to move the
	 ** two (or one) blocks of cells using memmove() and add the required
	 ** offsets to each pointer in the cell-pointer array than it is to
	 ** reconstruct the entire page.  */
	if libc.Int32FromUint8(**(**uint8)(__ccgo_up(data + uintptr(hdr+int32(7))))) <= nMaxFrag {
		iFree = libc.Int32FromUint8(**(**uint8)(__ccgo_up(data + uintptr(hdr+int32(1)))))<<int32(8) | libc.Int32FromUint8(**(**uint8)(__ccgo_up(data + uintptr(hdr+int32(1)) + 1)))
		if iFree > usableSize-int32(4) {
			return _sqlite3CorruptError(tls, int32(74790))
		}
		if iFree != 0 {
			iFree2 = libc.Int32FromUint8(**(**uint8)(__ccgo_up(data + uintptr(iFree))))<<int32(8) | libc.Int32FromUint8(**(**uint8)(__ccgo_up(data + uintptr(iFree) + 1)))
			if iFree2 > usableSize-int32(4) {
				return _sqlite3CorruptError(tls, int32(74793))
			}
			if 0 == iFree2 || libc.Int32FromUint8(**(**uint8)(__ccgo_up(data + uintptr(iFree2)))) == 0 && libc.Int32FromUint8(**(**uint8)(__ccgo_up(data + uintptr(iFree2+int32(1))))) == 0 {
				pEnd = data + uintptr(cellOffset+nCell*int32(2))
				sz2 = 0
				sz = libc.Int32FromUint8(**(**uint8)(__ccgo_up(data + uintptr(iFree+int32(2)))))<<int32(8) | libc.Int32FromUint8(**(**uint8)(__ccgo_up(data + uintptr(iFree+int32(2)) + 1)))
				top = libc.Int32FromUint8(**(**uint8)(__ccgo_up(data + uintptr(hdr+int32(5)))))<<int32(8) | libc.Int32FromUint8(**(**uint8)(__ccgo_up(data + uintptr(hdr+int32(5)) + 1)))
				if top >= iFree {
					return _sqlite3CorruptError(tls, int32(74801))
				}
				if iFree2 != 0 {
					if iFree+sz > iFree2 {
						return _sqlite3CorruptError(tls, int32(74804))
					}
					sz2 = libc.Int32FromUint8(**(**uint8)(__ccgo_up(data + uintptr(iFree2+int32(2)))))<<int32(8) | libc.Int32FromUint8(**(**uint8)(__ccgo_up(data + uintptr(iFree2+int32(2)) + 1)))
					if iFree2+sz2 > usableSize {
						return _sqlite3CorruptError(tls, int32(74806))
					}
					libc.Xmemmove(tls, data+uintptr(iFree+sz+sz2), data+uintptr(iFree+sz), libc.Uint64FromInt32(iFree2-(iFree+sz)))
					sz = sz + sz2
				} else {
					if iFree+sz > usableSize {
						return _sqlite3CorruptError(tls, int32(74810))
					}
				}
				cbrk = top + sz
				libc.Xmemmove(tls, data+uintptr(cbrk), data+uintptr(top), libc.Uint64FromInt32(iFree-top))
				pAddr = data + uintptr(cellOffset)
				for {
					if !(pAddr < pEnd) {
						break
					}
					pc = libc.Int32FromUint8(**(**Tu8)(__ccgo_up(pAddr)))<<int32(8) | libc.Int32FromUint8(**(**Tu8)(__ccgo_up(pAddr + 1)))
					if pc < iFree {
						**(**Tu8)(__ccgo_up(pAddr)) = libc.Uint8FromInt32((pc + sz) >> libc.Int32FromInt32(8))
						**(**Tu8)(__ccgo_up(pAddr + 1)) = libc.Uint8FromInt32(pc + sz)
					} else {
						if pc < iFree2 {
							**(**Tu8)(__ccgo_up(pAddr)) = libc.Uint8FromInt32((pc + sz2) >> libc.Int32FromInt32(8))
							**(**Tu8)(__ccgo_up(pAddr + 1)) = libc.Uint8FromInt32(pc + sz2)
						}
					}
					goto _1
				_1:
					;
					pAddr = pAddr + uintptr(2)
				}
				goto defragment_out
			}
		}
	}
	cbrk = usableSize
	iCellLast = usableSize - int32(4)
	iCellStart = libc.Int32FromUint8(**(**uint8)(__ccgo_up(data + uintptr(hdr+int32(5)))))<<int32(8) | libc.Int32FromUint8(**(**uint8)(__ccgo_up(data + uintptr(hdr+int32(5)) + 1)))
	if nCell > 0 {
		temp = _sqlite3PagerTempSpace(tls, (*TBtShared)(unsafe.Pointer((*TMemPage)(unsafe.Pointer(pPage)).FpBt)).FpPager)
		libc.Xmemcpy(tls, temp, data, libc.Uint64FromInt32(usableSize))
		src = temp
		i = 0
		for {
			if !(i < nCell) {
				break
			} /* The i-th cell pointer */
			pAddr1 = data + uintptr(cellOffset+i*int32(2))
			pc = libc.Int32FromUint8(**(**Tu8)(__ccgo_up(pAddr1)))<<int32(8) | libc.Int32FromUint8(**(**Tu8)(__ccgo_up(pAddr1 + 1)))
			/* These conditions have already been verified in btreeInitPage()
			 ** if PRAGMA cell_size_check=ON.
			 */
			if pc > iCellLast {
				return _sqlite3CorruptError(tls, int32(74843))
			}
			size = libc.Int32FromUint16((*(*func(*libc.TLS, uintptr, uintptr) Tu16)(unsafe.Pointer(&struct{ uintptr }{(*TMemPage)(unsafe.Pointer(pPage)).FxCellSize})))(tls, pPage, src+uintptr(pc)))
			cbrk = cbrk - size
			if cbrk < iCellStart || pc+size > usableSize {
				return _sqlite3CorruptError(tls, int32(74849))
			}
			**(**Tu8)(__ccgo_up(pAddr1)) = libc.Uint8FromInt32(cbrk >> libc.Int32FromInt32(8))
			**(**Tu8)(__ccgo_up(pAddr1 + 1)) = libc.Uint8FromInt32(cbrk)
			libc.Xmemcpy(tls, data+uintptr(cbrk), src+uintptr(pc), libc.Uint64FromInt32(size))
			goto _2
		_2:
			;
			i = i + 1
		}
	}
	**(**uint8)(__ccgo_up(data + uintptr(hdr+int32(7)))) = uint8(0)
	goto defragment_out
defragment_out:
	;
	if libc.Int32FromUint8(**(**uint8)(__ccgo_up(data + uintptr(hdr+int32(7)))))+cbrk-iCellFirst != (*TMemPage)(unsafe.Pointer(pPage)).FnFree {
		return _sqlite3CorruptError(tls, int32(74863))
	}
	**(**uint8)(__ccgo_up(data + uintptr(hdr+int32(5)))) = libc.Uint8FromInt32(cbrk >> libc.Int32FromInt32(8))
	**(**uint8)(__ccgo_up(data + uintptr(hdr+int32(5)) + 1)) = libc.Uint8FromInt32(cbrk)
	**(**uint8)(__ccgo_up(data + uintptr(hdr+int32(1)))) = uint8(0)
	**(**uint8)(__ccgo_up(data + uintptr(hdr+int32(2)))) = uint8(0)
	libc.Xmemset(tls, data+uintptr(iCellFirst), 0, libc.Uint64FromInt32(cbrk-iCellFirst))
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** Remove the i-th cell from pPage.  This routine effects pPage only.
//	** The cell content is not freed or deallocated.  It is assumed that
//	** the cell content has been copied someplace else.  This routine just
//	** removes the reference to the cell from pPage.
//	**
//	** "sz" must be the number of bytes in the cell.
//	*/
func _dropCell(tls *libc.TLS, pPage uintptr, idx int32, sz int32, pRC uintptr) {
	var data, ptr uintptr
	var hdr, rc int32
	var pc Tu32
	_, _, _, _, _ = data, hdr, pc, ptr, rc /* Beginning of the header.  0 most pages.  100 page 1 */
	if **(**int32)(__ccgo_up(pRC)) != 0 {
		return
	}
	data = (*TMemPage)(unsafe.Pointer(pPage)).FaData
	ptr = (*TMemPage)(unsafe.Pointer(pPage)).FaCellIdx + uintptr(int32(2)*idx)
	pc = libc.Uint32FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up(ptr)))<<libc.Int32FromInt32(8) | libc.Int32FromUint8(**(**Tu8)(__ccgo_up(ptr + 1))))
	hdr = libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pPage)).FhdrOffset)
	if pc+libc.Uint32FromInt32(sz) > (*TBtShared)(unsafe.Pointer((*TMemPage)(unsafe.Pointer(pPage)).FpBt)).FusableSize {
		**(**int32)(__ccgo_up(pRC)) = _sqlite3CorruptError(tls, int32(80423))
		return
	}
	rc = _freeSpace(tls, pPage, libc.Int32FromUint32(pc), sz)
	if rc != 0 {
		**(**int32)(__ccgo_up(pRC)) = rc
		return
	}
	(*TMemPage)(unsafe.Pointer(pPage)).FnCell = (*TMemPage)(unsafe.Pointer(pPage)).FnCell - 1
	if libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FnCell) == 0 {
		libc.Xmemset(tls, data+uintptr(hdr+int32(1)), 0, uint64(4))
		**(**Tu8)(__ccgo_up(data + uintptr(hdr+int32(7)))) = uint8(0)
		**(**Tu8)(__ccgo_up(data + uintptr(hdr+int32(5)))) = uint8((*TBtShared)(unsafe.Pointer((*TMemPage)(unsafe.Pointer(pPage)).FpBt)).FusableSize >> libc.Int32FromInt32(8))
		**(**Tu8)(__ccgo_up(data + uintptr(hdr+int32(5)) + 1)) = uint8((*TBtShared)(unsafe.Pointer((*TMemPage)(unsafe.Pointer(pPage)).FpBt)).FusableSize)
		(*TMemPage)(unsafe.Pointer(pPage)).FnFree = libc.Int32FromUint32((*TBtShared)(unsafe.Pointer((*TMemPage)(unsafe.Pointer(pPage)).FpBt)).FusableSize - uint32((*TMemPage)(unsafe.Pointer(pPage)).FhdrOffset) - uint32((*TMemPage)(unsafe.Pointer(pPage)).FchildPtrSize) - uint32(8))
	} else {
		libc.Xmemmove(tls, ptr, ptr+uintptr(2), libc.Uint64FromInt32(int32(2)*(libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FnCell)-idx)))
		**(**Tu8)(__ccgo_up(data + uintptr(hdr+int32(3)))) = libc.Uint8FromInt32(libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FnCell) >> libc.Int32FromInt32(8))
		**(**Tu8)(__ccgo_up(data + uintptr(hdr+int32(3)) + 1)) = uint8((*TMemPage)(unsafe.Pointer(pPage)).FnCell)
		**(**int32)(__ccgo_up(pPage + 20)) += int32(2)
	}
}

// C documentation
//
//	/*
//	** pCArray contains pointers to and sizes of all cells in the page being
//	** balanced.  The current page, pPg, has pPg->nCell cells starting with
//	** pCArray->apCell[iOld].  After balancing, this page should hold nNew cells
//	** starting at apCell[iNew].
//	**
//	** This routine makes the necessary adjustments to pPg so that it contains
//	** the correct cells after being balanced.
//	**
//	** The pPg->nFree field is invalid when this function returns. It is the
//	** responsibility of the caller to set it correctly.
//	*/
func _editPage(tls *libc.TLS, pPg uintptr, iOld int32, iNew int32, nNew int32, pCArray uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var aData, pBegin, pCellptr uintptr
	var hdr, i, iCell, iNewEnd, iOldEnd, nAdd, nCell, nShift, nTail, v1 int32
	var _ /* pData at bp+0 */ uintptr
	_, _, _, _, _, _, _, _, _, _, _, _, _ = aData, hdr, i, iCell, iNewEnd, iOldEnd, nAdd, nCell, nShift, nTail, pBegin, pCellptr, v1
	aData = (*TMemPage)(unsafe.Pointer(pPg)).FaData
	hdr = libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pPg)).FhdrOffset)
	pBegin = (*TMemPage)(unsafe.Pointer(pPg)).FaCellIdx + uintptr(nNew*int32(2))
	nCell = libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPg)).FnCell)
	iOldEnd = iOld + libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPg)).FnCell) + libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pPg)).FnOverflow)
	iNewEnd = iNew + nNew
	/* Remove cells from the start and end of the page */
	if iOld < iNew {
		nShift = _pageFreeArray(tls, pPg, iOld, iNew-iOld, pCArray)
		if nShift > nCell {
			return _sqlite3CorruptError(tls, int32(81033))
		}
		libc.Xmemmove(tls, (*TMemPage)(unsafe.Pointer(pPg)).FaCellIdx, (*TMemPage)(unsafe.Pointer(pPg)).FaCellIdx+uintptr(nShift*int32(2)), libc.Uint64FromInt32(nCell*int32(2)))
		nCell = nCell - nShift
	}
	if iNewEnd < iOldEnd {
		nTail = _pageFreeArray(tls, pPg, iNewEnd, iOldEnd-iNewEnd, pCArray)
		nCell = nCell - nTail
	}
	**(**uintptr)(__ccgo_up(bp)) = aData + uintptr(libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aData + uintptr(hdr+int32(5)))))<<libc.Int32FromInt32(8)|libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aData + uintptr(hdr+int32(5)) + 1))))
	if **(**uintptr)(__ccgo_up(bp)) < pBegin {
		goto editpage_fail
	}
	if **(**uintptr)(__ccgo_up(bp)) > (*TMemPage)(unsafe.Pointer(pPg)).FaDataEnd {
		goto editpage_fail
	}
	/* Add cells to the start of the page */
	if iNew < iOld {
		if nNew < iOld-iNew {
			v1 = nNew
		} else {
			v1 = iOld - iNew
		}
		nAdd = v1
		pCellptr = (*TMemPage)(unsafe.Pointer(pPg)).FaCellIdx
		libc.Xmemmove(tls, pCellptr+uintptr(nAdd*int32(2)), pCellptr, libc.Uint64FromInt32(nCell*int32(2)))
		if _pageInsertArray(tls, pPg, pBegin, bp, pCellptr, iNew, nAdd, pCArray) != 0 {
			goto editpage_fail
		}
		nCell = nCell + nAdd
	}
	/* Add any overflow cells */
	i = 0
	for {
		if !(i < libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pPg)).FnOverflow)) {
			break
		}
		iCell = iOld + libc.Int32FromUint16(**(**Tu16)(__ccgo_up(pPg + 28 + uintptr(i)*2))) - iNew
		if iCell >= 0 && iCell < nNew {
			pCellptr = (*TMemPage)(unsafe.Pointer(pPg)).FaCellIdx + uintptr(iCell*int32(2))
			if nCell > iCell {
				libc.Xmemmove(tls, pCellptr+2, pCellptr, libc.Uint64FromInt32((nCell-iCell)*int32(2)))
			}
			nCell = nCell + 1
			_cachedCellSize(tls, pCArray, iCell+iNew)
			if _pageInsertArray(tls, pPg, pBegin, bp, pCellptr, iCell+iNew, int32(1), pCArray) != 0 {
				goto editpage_fail
			}
		}
		goto _2
	_2:
		;
		i = i + 1
	}
	/* Append cells to the end of the page */
	pCellptr = (*TMemPage)(unsafe.Pointer(pPg)).FaCellIdx + uintptr(nCell*int32(2))
	if _pageInsertArray(tls, pPg, pBegin, bp, pCellptr, iNew+nCell, nNew-nCell, pCArray) != 0 {
		goto editpage_fail
	}
	(*TMemPage)(unsafe.Pointer(pPg)).FnCell = libc.Uint16FromInt32(nNew)
	(*TMemPage)(unsafe.Pointer(pPg)).FnOverflow = uint8(0)
	**(**Tu8)(__ccgo_up(aData + uintptr(hdr+int32(3)))) = libc.Uint8FromInt32(libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPg)).FnCell) >> libc.Int32FromInt32(8))
	**(**Tu8)(__ccgo_up(aData + uintptr(hdr+int32(3)) + 1)) = uint8((*TMemPage)(unsafe.Pointer(pPg)).FnCell)
	**(**Tu8)(__ccgo_up(aData + uintptr(hdr+int32(5)))) = libc.Uint8FromInt64((int64(**(**uintptr)(__ccgo_up(bp))) - int64(aData)) >> libc.Int32FromInt32(8))
	**(**Tu8)(__ccgo_up(aData + uintptr(hdr+int32(5)) + 1)) = libc.Uint8FromInt64(int64(**(**uintptr)(__ccgo_up(bp))) - int64(aData))
	return SQLITE_OK
	goto editpage_fail
editpage_fail:
	;
	/* Unable to edit this page. Rebuild it from scratch instead. */
	if nNew < int32(1) {
		return _sqlite3CorruptError(tls, int32(81111))
	}
	_populateCellCache(tls, pCArray, iNew, nNew)
	return _rebuildPage(tls, pCArray, iNew, nNew, pPg)
}

// C documentation
//
//	/*
//	** The StrAccum "p" is not large enough to accept N new bytes of z[].
//	** So enlarge if first, then do the append.
//	**
//	** This is a helper routine to sqlite3_str_append() that does special-case
//	** work (enlarging the buffer) using tail recursion, so that the
//	** sqlite3_str_append() routine can use fast calling semantics.
//	*/
func _enlargeAndAppend(tls *libc.TLS, p uintptr, z uintptr, N int32) {
	N = _sqlite3StrAccumEnlarge(tls, p, int64(N))
	if N > 0 {
		libc.Xmemcpy(tls, (*TStrAccum)(unsafe.Pointer(p)).FzText+uintptr((*TStrAccum)(unsafe.Pointer(p)).FnChar), z, libc.Uint64FromInt32(N))
		**(**Tu32)(__ccgo_up(p + 24)) += libc.Uint32FromInt32(N)
	}
}

// C documentation
//
//	/*
//	** Argument pWhere is the WHERE clause belonging to SELECT statement p. This
//	** function attempts to transform expressions of the form:
//	**
//	**     EXISTS (SELECT ...)
//	**
//	** into joins. For example, given
//	**
//	**    CREATE TABLE sailors(sid INTEGER PRIMARY KEY, name TEXT);
//	**    CREATE TABLE reserves(sid INT, day DATE, PRIMARY KEY(sid, day));
//	**
//	**    SELECT name FROM sailors AS S WHERE EXISTS (
//	**      SELECT * FROM reserves AS R WHERE S.sid = R.sid AND R.day = '2022-10-25'
//	**    );
//	**
//	** the SELECT statement may be transformed as follows:
//	**
//	**    SELECT name FROM sailors AS S, reserves AS R
//	**      WHERE S.sid = R.sid AND R.day = '2022-10-25';
//	**
//	** **Approximately**.  Really, we have to ensure that the FROM-clause term
//	** that was formerly inside the EXISTS is only executed once.  This is handled
//	** by setting the SrcItem.fg.fromExists flag, which then causes code in
//	** the where.c file to exit the corresponding loop after the first successful
//	** match (if any).
//	*/
func _existsToJoin(tls *libc.TLS, pParse uintptr, p uintptr, pWhere uintptr) {
	var aCsrMap, db, pRight, pSub, pSubWhere uintptr
	_, _, _, _, _ = aCsrMap, db, pRight, pSub, pSubWhere
	if (*TParse)(unsafe.Pointer(pParse)).FnErr == 0 && pWhere != uintptr(0) && !((*TExpr)(unsafe.Pointer(pWhere)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_OuterON)|libc.Int32FromInt32(EP_InnerON)) != libc.Uint32FromInt32(0)) && (*TSelect)(unsafe.Pointer(p)).FpSrc != uintptr(0) && (*TSrcList)(unsafe.Pointer((*TSelect)(unsafe.Pointer(p)).FpSrc)).FnSrc < libc.Int32FromUint64(libc.Uint64FromInt64(8)*libc.Uint64FromInt32(8)) && ((*TSelect)(unsafe.Pointer(p)).FpLimit == uintptr(0) || (*TExpr)(unsafe.Pointer((*TSelect)(unsafe.Pointer(p)).FpLimit)).FpRight == uintptr(0)) {
		if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pWhere)).Fop) == int32(TK_AND) {
			pRight = (*TExpr)(unsafe.Pointer(pWhere)).FpRight
			_existsToJoin(tls, pParse, p, (*TExpr)(unsafe.Pointer(pWhere)).FpLeft)
			_existsToJoin(tls, pParse, p, pRight)
		} else {
			if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pWhere)).Fop) == int32(TK_EXISTS) {
				pSub = *(*uintptr)(unsafe.Pointer(pWhere + 32))
				pSubWhere = (*TSelect)(unsafe.Pointer(pSub)).FpWhere
				if (*TSrcList)(unsafe.Pointer((*TSelect)(unsafe.Pointer(pSub)).FpSrc)).FnSrc == int32(1) && (*TSelect)(unsafe.Pointer(pSub)).FselFlags&uint32(SF_Aggregate) == uint32(0) && !(int32(*(*uint32)(unsafe.Pointer((*TSelect)(unsafe.Pointer(pSub)).FpSrc + 8 + 24 + 4))&0x4>>2) != 0) && (*TSelect)(unsafe.Pointer(pSub)).FpLimit == uintptr(0) && (*TSelect)(unsafe.Pointer(pSub)).FpPrior == uintptr(0) {
					/* Before combining the sub-select with the parent, renumber the
					 ** cursor used by the subselect. This is because the EXISTS expression
					 ** might be a copy of another EXISTS expression from somewhere
					 ** else in the tree, and in this case it is important that it use
					 ** a unique cursor number.  */
					db = (*TParse)(unsafe.Pointer(pParse)).Fdb
					aCsrMap = _sqlite3DbMallocZero(tls, db, uint64(libc.Uint64FromInt32((*TParse)(unsafe.Pointer(pParse)).FnTab+libc.Int32FromInt32(2))*uint64(4)))
					if aCsrMap == uintptr(0) {
						return
					}
					**(**int32)(__ccgo_up(aCsrMap)) = (*TParse)(unsafe.Pointer(pParse)).FnTab + int32(1)
					_renumberCursors(tls, pParse, pSub, -int32(1), aCsrMap)
					_sqlite3DbFree(tls, db, aCsrMap)
					libc.Xmemset(tls, pWhere, 0, uint64(72))
					(*TExpr)(unsafe.Pointer(pWhere)).Fop = uint8(TK_INTEGER)
					*(*int32)(unsafe.Pointer(&(*TExpr)(unsafe.Pointer(pWhere)).Fu)) = int32(1)
					**(**Tu32)(__ccgo_up(pWhere + 4)) |= libc.Uint32FromInt32(libc.Int32FromInt32(EP_IntValue))
					libc.SetBitFieldPtr32Uint32((*TSelect)(unsafe.Pointer(pSub)).FpSrc+8+24+4, libc.Uint32FromInt32(1), 18, 0x40000)
					(*TSelect)(unsafe.Pointer(p)).FpSrc = _sqlite3SrcListAppendList(tls, pParse, (*TSelect)(unsafe.Pointer(p)).FpSrc, (*TSelect)(unsafe.Pointer(pSub)).FpSrc)
					if pSubWhere != 0 {
						(*TSelect)(unsafe.Pointer(p)).FpWhere = _sqlite3PExpr(tls, pParse, int32(TK_AND), (*TSelect)(unsafe.Pointer(p)).FpWhere, pSubWhere)
						(*TSelect)(unsafe.Pointer(pSub)).FpWhere = uintptr(0)
					}
					(*TSelect)(unsafe.Pointer(pSub)).FpSrc = uintptr(0)
					_sqlite3ParserAddCleanup(tls, pParse, __ccgo_fp(_sqlite3SelectDeleteGeneric), pSub)
				}
			}
		}
	}
}

// C documentation
//
//	/*
//	** Generate code for a BETWEEN operator.
//	**
//	**    x BETWEEN y AND z
//	**
//	** The above is equivalent to
//	**
//	**    x>=y AND x<=z
//	**
//	** Code it as such, taking care to do the common subexpression
//	** elimination of x.
//	**
//	** The xJumpIf parameter determines details:
//	**
//	**    NULL:                   Store the boolean result in reg[dest]
//	**    sqlite3ExprIfTrue:      Jump to dest if true
//	**    sqlite3ExprIfFalse:     Jump to dest if false
//	**
//	** The jumpIfNull parameter is ignored if xJumpIf is NULL.
//	*/
func _exprCodeBetween(tls *libc.TLS, pParse uintptr, pExpr uintptr, dest int32, __ccgo_fp_xJump uintptr, jumpIfNull int32) {
	bp := tls.Alloc(224)
	defer tls.Free(224)
	var db, pDel uintptr
	var _ /* compLeft at bp+72 */ TExpr
	var _ /* compRight at bp+144 */ TExpr
	var _ /* exprAnd at bp+0 */ TExpr
	var _ /* regFree1 at bp+216 */ int32
	_, _ = db, pDel                      /* The  x<=z  term */
	**(**int32)(__ccgo_up(bp + 216)) = 0 /* Temporary use register */
	pDel = uintptr(0)
	db = (*TParse)(unsafe.Pointer(pParse)).Fdb
	libc.Xmemset(tls, bp+72, 0, uint64(72))
	libc.Xmemset(tls, bp+144, 0, uint64(72))
	libc.Xmemset(tls, bp, 0, uint64(72))
	pDel = _sqlite3ExprDup(tls, db, (*TExpr)(unsafe.Pointer(pExpr)).FpLeft, 0)
	if libc.Int32FromUint8((*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed) == 0 {
		(**(**TExpr)(__ccgo_up(bp))).Fop = uint8(TK_AND)
		(**(**TExpr)(__ccgo_up(bp))).FpLeft = bp + 72
		(**(**TExpr)(__ccgo_up(bp))).FpRight = bp + 144
		(**(**TExpr)(__ccgo_up(bp + 72))).Fop = uint8(TK_GE)
		(**(**TExpr)(__ccgo_up(bp + 72))).FpLeft = pDel
		(**(**TExpr)(__ccgo_up(bp + 72))).FpRight = (*(*TExprList_item)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pExpr + 32)) + 8))).FpExpr
		(**(**TExpr)(__ccgo_up(bp + 144))).Fop = uint8(TK_LE)
		(**(**TExpr)(__ccgo_up(bp + 144))).FpLeft = pDel
		(**(**TExpr)(__ccgo_up(bp + 144))).FpRight = (*(*TExprList_item)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pExpr + 32)) + 8 + 1*32))).FpExpr
		_sqlite3ExprToRegister(tls, pDel, _exprCodeVector(tls, pParse, pDel, bp+216))
		if __ccgo_fp_xJump != 0 {
			(*(*func(*libc.TLS, uintptr, uintptr, int32, int32))(unsafe.Pointer(&struct{ uintptr }{__ccgo_fp_xJump})))(tls, pParse, bp, dest, jumpIfNull)
		} else {
			/* Mark the expression is being from the ON or USING clause of a join
			 ** so that the sqlite3ExprCodeTarget() routine will not attempt to move
			 ** it into the Parse.pConstExpr list.  We should use a new bit for this,
			 ** for clarity, but we are out of bits in the Expr.flags field so we
			 ** have to reuse the EP_OuterON bit.  Bummer. */
			**(**Tu32)(__ccgo_up(pDel + 4)) |= uint32(EP_OuterON)
			_sqlite3ExprCodeTarget(tls, pParse, bp, dest)
		}
		_sqlite3ReleaseTempReg(tls, pParse, **(**int32)(__ccgo_up(bp + 216)))
	}
	_sqlite3ExprDelete(tls, db, pDel)
	/* Ensure adequate test coverage */
}

// C documentation
//
//	/*
//	** This function is similar to sqlite3ExprDup(), except that if pEdupBuf
//	** is not NULL then it points to memory that can be used to store a copy
//	** of the input Expr p together with its p->u.zToken (if any).  pEdupBuf
//	** is updated with the new buffer tail prior to returning.
//	*/
func _exprDup(tls *libc.TLS, db uintptr, p uintptr, dupFlags int32, pEdupBuf uintptr) (r uintptr) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var nAlloc, nNewSize, nToken, v2 int32
	var nSize, staticFlag Tu32
	var nStructSize uint32
	var pNew, zToken, v1 uintptr
	var _ /* sEdupBuf at bp+0 */ TEdupBuf
	_, _, _, _, _, _, _, _, _, _ = nAlloc, nNewSize, nSize, nStructSize, nToken, pNew, staticFlag, zToken, v1, v2 /* EP_Static if space not obtained from malloc */
	nToken = -int32(1)                                                                                            /* Space needed for p->u.zToken.  -1 means unknown */
	/* Figure out where to write the new Expr structure. */
	if pEdupBuf != 0 {
		(**(**TEdupBuf)(__ccgo_up(bp))).FzAlloc = (*TEdupBuf)(unsafe.Pointer(pEdupBuf)).FzAlloc
		staticFlag = uint32(EP_Static)
	} else {
		if dupFlags != 0 {
			nAlloc = _dupedExprSize(tls, p)
		} else {
			if !((*TExpr)(unsafe.Pointer(p)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_IntValue)) != libc.Uint32FromInt32(0)) && *(*uintptr)(unsafe.Pointer(p + 8)) != 0 {
				nToken = libc.Int32FromUint64(libc.Xstrlen(tls, *(*uintptr)(unsafe.Pointer(p + 8)))&uint64(0x3fffffff) + uint64(1))
				nAlloc = libc.Int32FromUint64((libc.Uint64FromInt64(72) + libc.Uint64FromInt32(nToken) + libc.Uint64FromInt32(7)) & libc.Uint64FromInt32(^libc.Int32FromInt32(7)))
			} else {
				nToken = 0
				nAlloc = libc.Int32FromUint64((libc.Uint64FromInt64(72) + libc.Uint64FromInt32(7)) & libc.Uint64FromInt32(^libc.Int32FromInt32(7)))
			}
		}
		(**(**TEdupBuf)(__ccgo_up(bp))).FzAlloc = _sqlite3DbMallocRawNN(tls, db, libc.Uint64FromInt32(nAlloc))
		staticFlag = uint32(0)
	}
	pNew = (**(**TEdupBuf)(__ccgo_up(bp))).FzAlloc
	if pNew != 0 {
		/* Set nNewSize to the size allocated for the structure pointed to
		 ** by pNew. This is either EXPR_FULLSIZE, EXPR_REDUCEDSIZE or
		 ** EXPR_TOKENONLYSIZE. nToken is set to the number of bytes consumed
		 ** by the copy of the p->u.zToken string (if any).
		 */
		nStructSize = libc.Uint32FromInt32(_dupedExprStructSize(tls, p, dupFlags))
		nNewSize = libc.Int32FromUint32(nStructSize & uint32(0xfff))
		if nToken < 0 {
			if !((*TExpr)(unsafe.Pointer(p)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_IntValue)) != libc.Uint32FromInt32(0)) && *(*uintptr)(unsafe.Pointer(p + 8)) != 0 {
				nToken = _sqlite3Strlen30(tls, *(*uintptr)(unsafe.Pointer(p + 8))) + int32(1)
			} else {
				nToken = 0
			}
		}
		if dupFlags != 0 {
			libc.Xmemcpy(tls, (**(**TEdupBuf)(__ccgo_up(bp))).FzAlloc, p, libc.Uint64FromInt32(nNewSize))
		} else {
			nSize = libc.Uint32FromInt32(_exprStructSize(tls, p))
			libc.Xmemcpy(tls, (**(**TEdupBuf)(__ccgo_up(bp))).FzAlloc, p, uint64(nSize))
			if uint64(nSize) < uint64(72) {
				libc.Xmemset(tls, (**(**TEdupBuf)(__ccgo_up(bp))).FzAlloc+uintptr(nSize), 0, uint64(72)-uint64(nSize))
			}
			nNewSize = int32(72)
		}
		/* Set the EP_Reduced, EP_TokenOnly, and EP_Static flags appropriately. */
		**(**Tu32)(__ccgo_up(pNew + 4)) &= libc.Uint32FromInt32(^(libc.Int32FromInt32(EP_Reduced) | libc.Int32FromInt32(EP_TokenOnly) | libc.Int32FromInt32(EP_Static)))
		**(**Tu32)(__ccgo_up(pNew + 4)) |= nStructSize & libc.Uint32FromInt32(libc.Int32FromInt32(EP_Reduced)|libc.Int32FromInt32(EP_TokenOnly))
		**(**Tu32)(__ccgo_up(pNew + 4)) |= staticFlag
		if dupFlags != 0 {
		}
		/* Copy the p->u.zToken string, if any. */
		if nToken > 0 {
			v1 = (**(**TEdupBuf)(__ccgo_up(bp))).FzAlloc + uintptr(nNewSize)
			*(*uintptr)(unsafe.Pointer(pNew + 8)) = v1
			zToken = v1
			libc.Xmemcpy(tls, zToken, *(*uintptr)(unsafe.Pointer(p + 8)), libc.Uint64FromInt32(nToken))
			nNewSize = nNewSize + nToken
		}
		(**(**TEdupBuf)(__ccgo_up(bp))).FzAlloc += uintptr((nNewSize + libc.Int32FromInt32(7)) & ^libc.Int32FromInt32(7))
		if ((*TExpr)(unsafe.Pointer(p)).Fflags|(*TExpr)(unsafe.Pointer(pNew)).Fflags)&libc.Uint32FromInt32(libc.Int32FromInt32(EP_TokenOnly)|libc.Int32FromInt32(EP_Leaf)) == uint32(0) {
			/* Fill in the pNew->x.pSelect or pNew->x.pList member. */
			if (*TExpr)(unsafe.Pointer(p)).Fflags&uint32(EP_xIsSelect) != uint32(0) {
				*(*uintptr)(unsafe.Pointer(pNew + 32)) = _sqlite3SelectDup(tls, db, *(*uintptr)(unsafe.Pointer(p + 32)), dupFlags)
			} else {
				if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(p)).Fop) != int32(TK_ORDER) {
					v2 = dupFlags
				} else {
					v2 = 0
				}
				*(*uintptr)(unsafe.Pointer(pNew + 32)) = _sqlite3ExprListDup(tls, db, *(*uintptr)(unsafe.Pointer(p + 32)), v2)
			}
			if (*TExpr)(unsafe.Pointer(p)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_WinFunc)) != uint32(0) {
				*(*uintptr)(unsafe.Pointer(pNew + 64)) = _sqlite3WindowDup(tls, db, pNew, *(*uintptr)(unsafe.Pointer(p + 64)))
			}
			/* Fill in pNew->pLeft and pNew->pRight. */
			if dupFlags != 0 {
				if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(p)).Fop) == int32(TK_SELECT_COLUMN) {
					(*TExpr)(unsafe.Pointer(pNew)).FpLeft = (*TExpr)(unsafe.Pointer(p)).FpLeft
				} else {
					if (*TExpr)(unsafe.Pointer(p)).FpLeft != 0 {
						v1 = _exprDup(tls, db, (*TExpr)(unsafe.Pointer(p)).FpLeft, int32(EXPRDUP_REDUCE), bp)
					} else {
						v1 = uintptr(0)
					}
					(*TExpr)(unsafe.Pointer(pNew)).FpLeft = v1
				}
				if (*TExpr)(unsafe.Pointer(p)).FpRight != 0 {
					v1 = _exprDup(tls, db, (*TExpr)(unsafe.Pointer(p)).FpRight, int32(EXPRDUP_REDUCE), bp)
				} else {
					v1 = uintptr(0)
				}
				(*TExpr)(unsafe.Pointer(pNew)).FpRight = v1
			} else {
				if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(p)).Fop) == int32(TK_SELECT_COLUMN) {
					(*TExpr)(unsafe.Pointer(pNew)).FpLeft = (*TExpr)(unsafe.Pointer(p)).FpLeft
				} else {
					(*TExpr)(unsafe.Pointer(pNew)).FpLeft = _sqlite3ExprDup(tls, db, (*TExpr)(unsafe.Pointer(p)).FpLeft, 0)
				}
				(*TExpr)(unsafe.Pointer(pNew)).FpRight = _sqlite3ExprDup(tls, db, (*TExpr)(unsafe.Pointer(p)).FpRight, 0)
			}
		}
	}
	if pEdupBuf != 0 {
		libc.Xmemcpy(tls, pEdupBuf, bp, uint64(8))
	}
	return pNew
}

// C documentation
//
//	/*
//	** Return true if the expression contains no non-deterministic SQL
//	** functions. Do not consider non-deterministic SQL functions that are
//	** part of sub-select statements.
//	*/
func _exprIsDeterministic(tls *libc.TLS, p uintptr) (r int32) {
	bp := tls.Alloc(48)
	defer tls.Free(48)
	var _ /* w at bp+0 */ TWalker
	libc.Xmemset(tls, bp, 0, uint64(48))
	(**(**TWalker)(__ccgo_up(bp))).FeCode = uint16(1)
	(**(**TWalker)(__ccgo_up(bp))).FxExprCallback = __ccgo_fp(_exprNodeIsDeterministic)
	(**(**TWalker)(__ccgo_up(bp))).FxSelectCallback = __ccgo_fp(_sqlite3SelectWalkFail)
	_sqlite3WalkExpr(tls, bp, p)
	return libc.Int32FromUint16((**(**TWalker)(__ccgo_up(bp))).FeCode)
}

// 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 + 8)))
	} 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.Uint64FromInt32(nSrc))
		libc.Xmemset(tls, pPayload+uintptr(nSrc), 0, libc.Uint64FromInt32(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.Uint64FromInt32(n))
		} else {
			if nSrc > 0 {
				n = nSrc
				libc.Xmemcpy(tls, pPayload, pSrc, libc.Uint64FromInt32(n))
			} else {
				libc.Xmemset(tls, pPayload, 0, libc.Uint64FromInt32(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
//
//	/*
//	** 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+648, zName)
	if uintptr(0) == pColl && create != 0 {
		nName = _sqlite3Strlen30(tls, zName) + int32(1)
		pColl = _sqlite3DbMallocZero(tls, db, uint64(libc.Uint64FromInt32(3)*libc.Uint64FromInt64(40)+libc.Uint64FromInt32(nName)))
		if pColl != 0 {
			pDel = uintptr(0)
			(**(**TCollSeq)(__ccgo_up(pColl))).FzName = pColl + 3*40
			(**(**TCollSeq)(__ccgo_up(pColl))).Fenc = uint8(SQLITE_UTF8)
			(**(**TCollSeq)(__ccgo_up(pColl + 1*40))).FzName = pColl + 3*40
			(**(**TCollSeq)(__ccgo_up(pColl + 1*40))).Fenc = uint8(SQLITE_UTF16LE)
			(**(**TCollSeq)(__ccgo_up(pColl + 2*40))).FzName = pColl + 3*40
			(**(**TCollSeq)(__ccgo_up(pColl + 2*40))).Fenc = uint8(SQLITE_UTF16BE)
			libc.Xmemcpy(tls, (**(**TCollSeq)(__ccgo_up(pColl))).FzName, zName, libc.Uint64FromInt32(nName))
			pDel = _sqlite3HashInsert(tls, db+648, (**(**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
}

// C documentation
//
//	/*
//	** This function is called to generate code executed when a row is deleted
//	** from the parent table of foreign key constraint pFKey and, if pFKey is
//	** deferred, when a row is inserted into the same table. When generating
//	** code for an SQL UPDATE operation, this function may be called twice -
//	** once to "delete" the old row and once to "insert" the new row.
//	**
//	** Parameter nIncr is passed -1 when inserting a row (as this may decrease
//	** the number of FK violations in the db) or +1 when deleting one (as this
//	** may increase the number of FK constraint problems).
//	**
//	** The code generated by this function scans through the rows in the child
//	** table that correspond to the parent table row being deleted or inserted.
//	** For each child row found, one of the following actions is taken:
//	**
//	**   Operation | FK type   | Action taken
//	**   --------------------------------------------------------------------------
//	**   DELETE      immediate   Increment the "immediate constraint counter".
//	**
//	**   INSERT      immediate   Decrement the "immediate constraint counter".
//	**
//	**   DELETE      deferred    Increment the "deferred constraint counter".
//	**
//	**   INSERT      deferred    Decrement the "deferred constraint counter".
//	**
//	** These operations are identified in the comment at the top of this file
//	** (fkey.c) as "I.2" and "D.2".
//	*/
func _fkScanChildren(tls *libc.TLS, pParse uintptr, pSrc uintptr, pTab uintptr, pIdx uintptr, pFKey uintptr, aiCol uintptr, regData int32, nIncr int32) {
	bp := tls.Alloc(64)
	defer tls.Free(64)
	var db, pAll, pEq, pEq1, pLeft, pLeft1, pNe, pRight, pRight1, pWInfo, pWhere, v, zCol uintptr
	var i, iFkIfZero, v2 int32
	var iCol, iCol1 Ti16
	var _ /* sNameContext at bp+0 */ TNameContext
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = db, i, iCol, iCol1, iFkIfZero, pAll, pEq, pEq1, pLeft, pLeft1, pNe, pRight, pRight1, pWInfo, pWhere, v, zCol, v2
	db = (*TParse)(unsafe.Pointer(pParse)).Fdb /* Iterator variable */
	pWhere = uintptr(0)                        /* Context used by sqlite3WhereXXX() */
	iFkIfZero = 0                              /* Address of OP_FkIfZero */
	v = _sqlite3GetVdbe(tls, pParse)
	if nIncr < 0 {
		iFkIfZero = _sqlite3VdbeAddOp2(tls, v, int32(OP_FkIfZero), libc.Int32FromUint8((*TFKey)(unsafe.Pointer(pFKey)).FisDeferred), 0)
	}
	/* Create an Expr object representing an SQL expression like:
	 **
	 **   <parent-key1> = <child-key1> AND <parent-key2> = <child-key2> ...
	 **
	 ** The collation sequence used for the comparison should be that of
	 ** the parent key columns. The affinity of the parent key column should
	 ** be applied to each child key value before the comparison takes place.
	 */
	i = 0
	for {
		if !(i < (*TFKey)(unsafe.Pointer(pFKey)).FnCol) {
			break
		} /* Name of column in child table */
		if pIdx != 0 {
			v2 = int32(**(**Ti16)(__ccgo_up((*TIndex)(unsafe.Pointer(pIdx)).FaiColumn + uintptr(i)*2)))
		} else {
			v2 = -int32(1)
		}
		iCol = int16(v2)
		pLeft = _exprTableRegister(tls, pParse, pTab, regData, iCol)
		if aiCol != 0 {
			v2 = **(**int32)(__ccgo_up(aiCol + uintptr(i)*4))
		} else {
			v2 = (*(*TsColMap)(unsafe.Pointer(pFKey + 64))).FiFrom
		}
		iCol = int16(v2)
		zCol = (**(**TColumn)(__ccgo_up((*TTable)(unsafe.Pointer((*TFKey)(unsafe.Pointer(pFKey)).FpFrom)).FaCol + uintptr(iCol)*16))).FzCnName
		pRight = _sqlite3Expr(tls, db, int32(TK_ID), zCol)
		pEq = _sqlite3PExpr(tls, pParse, int32(TK_EQ), pLeft, pRight)
		pWhere = _sqlite3ExprAnd(tls, pParse, pWhere, pEq)
		goto _1
	_1:
		;
		i = i + 1
	}
	/* If the child table is the same as the parent table, then add terms
	 ** to the WHERE clause that prevent this entry from being scanned.
	 ** The added WHERE clause terms are like this:
	 **
	 **     $current_rowid!=rowid
	 **     NOT( $current_a==a AND $current_b==b AND ... )
	 **
	 ** The first form is used for rowid tables.  The second form is used
	 ** for WITHOUT ROWID tables. In the second form, the *parent* key is
	 ** (a,b,...). Either the parent or primary key could be used to
	 ** uniquely identify the current row, but the parent key is more convenient
	 ** as the required values have already been loaded into registers
	 ** by the caller.
	 */
	if pTab == (*TFKey)(unsafe.Pointer(pFKey)).FpFrom && nIncr > 0 { /* Column ref to child table */
		if (*TTable)(unsafe.Pointer(pTab)).FtabFlags&uint32(TF_WithoutRowid) == uint32(0) {
			pLeft1 = _exprTableRegister(tls, pParse, pTab, regData, int16(-int32(1)))
			pRight1 = _exprTableColumn(tls, db, pTab, (*(*TSrcItem)(unsafe.Pointer(pSrc + 8))).FiCursor, int16(-int32(1)))
			pNe = _sqlite3PExpr(tls, pParse, int32(TK_NE), pLeft1, pRight1)
		} else {
			pAll = uintptr(0)
			i = 0
			for {
				if !(i < libc.Int32FromUint16((*TIndex)(unsafe.Pointer(pIdx)).FnKeyCol)) {
					break
				}
				iCol1 = **(**Ti16)(__ccgo_up((*TIndex)(unsafe.Pointer(pIdx)).FaiColumn + uintptr(i)*2))
				pLeft1 = _exprTableRegister(tls, pParse, pTab, regData, iCol1)
				pRight1 = _sqlite3Expr(tls, db, int32(TK_ID), (**(**TColumn)(__ccgo_up((*TTable)(unsafe.Pointer(pTab)).FaCol + uintptr(iCol1)*16))).FzCnName)
				pEq1 = _sqlite3PExpr(tls, pParse, int32(TK_IS), pLeft1, pRight1)
				pAll = _sqlite3ExprAnd(tls, pParse, pAll, pEq1)
				goto _4
			_4:
				;
				i = i + 1
			}
			pNe = _sqlite3PExpr(tls, pParse, int32(TK_NOT), pAll, uintptr(0))
		}
		pWhere = _sqlite3ExprAnd(tls, pParse, pWhere, pNe)
	}
	/* Resolve the references in the WHERE clause. */
	libc.Xmemset(tls, bp, 0, uint64(56))
	(**(**TNameContext)(__ccgo_up(bp))).FpSrcList = pSrc
	(**(**TNameContext)(__ccgo_up(bp))).FpParse = pParse
	_sqlite3ResolveExprNames(tls, bp, pWhere)
	/* Create VDBE to loop through the entries in pSrc that match the WHERE
	 ** clause. For each row found, increment either the deferred or immediate
	 ** foreign key constraint counter. */
	if (*TParse)(unsafe.Pointer(pParse)).FnErr == 0 {
		pWInfo = _sqlite3WhereBegin(tls, pParse, pSrc, pWhere, uintptr(0), uintptr(0), uintptr(0), uint16(0), 0)
		_sqlite3VdbeAddOp2(tls, v, int32(OP_FkCounter), libc.Int32FromUint8((*TFKey)(unsafe.Pointer(pFKey)).FisDeferred), nIncr)
		if pWInfo != 0 {
			_sqlite3WhereEnd(tls, pWInfo)
		}
	}
	/* Clean up the WHERE clause constructed above. */
	_sqlite3ExprDelete(tls, db, pWhere)
	if iFkIfZero != 0 {
		_sqlite3VdbeJumpHereOrPopInst(tls, v, iFkIfZero)
	}
}

// C documentation
//
//	/*
//	** This routine attempts to flatten subqueries as a performance optimization.
//	** This routine returns 1 if it makes changes and 0 if no flattening occurs.
//	**
//	** To understand the concept of flattening, consider the following
//	** query:
//	**
//	**     SELECT a FROM (SELECT x+y AS a FROM t1 WHERE z<100) WHERE a>5
//	**
//	** The default way of implementing this query is to execute the
//	** subquery first and store the results in a temporary table, then
//	** run the outer query on that temporary table.  This requires two
//	** passes over the data.  Furthermore, because the temporary table
//	** has no indices, the WHERE clause on the outer query cannot be
//	** optimized.
//	**
//	** This routine attempts to rewrite queries such as the above into
//	** a single flat select, like this:
//	**
//	**     SELECT x+y AS a FROM t1 WHERE z<100 AND a>5
//	**
//	** The code generated for this simplification gives the same result
//	** but only has to scan the data once.  And because indices might
//	** exist on the table t1, a complete scan of the data might be
//	** avoided.
//	**
//	** Flattening is subject to the following constraints:
//	**
//	**  (**)  We no longer attempt to flatten aggregate subqueries. Was:
//	**        The subquery and the outer query cannot both be aggregates.
//	**
//	**  (**)  We no longer attempt to flatten aggregate subqueries. Was:
//	**        (2) If the subquery is an aggregate then
//	**        (2a) the outer query must not be a join and
//	**        (2b) the outer query must not use subqueries
//	**             other than the one FROM-clause subquery that is a candidate
//	**             for flattening.  (This is due to ticket [2f7170d73bf9abf80]
//	**             from 2015-02-09.)
//	**
//	**   (3)  If the subquery is the right operand of a LEFT JOIN then
//	**        (3a) the subquery may not be a join
//	**        (**) Was (3b): "the FROM clause of the subquery may not contain
//	**             a virtual table"
//	**        (**) Was: "The outer query may not have a GROUP BY." This case
//	**             is now managed correctly
//	**        (3d) the outer query may not be DISTINCT.
//	**        See also (26) for restrictions on RIGHT JOIN.
//	**
//	**   (4)  The subquery can not be DISTINCT.
//	**
//	**  (**)  At one point restrictions (4) and (5) defined a subset of DISTINCT
//	**        sub-queries that were excluded from this optimization. Restriction
//	**        (4) has since been expanded to exclude all DISTINCT subqueries.
//	**
//	**  (**)  We no longer attempt to flatten aggregate subqueries.  Was:
//	**        If the subquery is aggregate, the outer query may not be DISTINCT.
//	**
//	**   (7)  The subquery must have a FROM clause.  TODO:  For subqueries without
//	**        A FROM clause, consider adding a FROM clause with the special
//	**        table sqlite_once that consists of a single row containing a
//	**        single NULL.
//	**
//	**   (8)  If the subquery uses LIMIT then the outer query may not be a join.
//	**
//	**   (9)  If the subquery uses LIMIT then the outer query may not be aggregate.
//	**
//	**  (**)  Restriction (10) was removed from the code on 2005-02-05 but we
//	**        accidentally carried the comment forward until 2014-09-15.  Original
//	**        constraint: "If the subquery is aggregate then the outer query
//	**        may not use LIMIT."
//	**
//	**  (11)  The subquery and the outer query may not both have ORDER BY clauses.
//	**
//	**  (**)  Not implemented.  Subsumed into restriction (3).  Was previously
//	**        a separate restriction deriving from ticket #350.
//	**
//	**  (13)  The subquery and outer query may not both use LIMIT.
//	**
//	**  (14)  The subquery may not use OFFSET.
//	**
//	**  (15)  If the outer query is part of a compound select, then the
//	**        subquery may not use LIMIT.
//	**        (See ticket #2339 and ticket [02a8e81d44]).
//	**
//	**  (16)  If the outer query is aggregate, then the subquery may not
//	**        use ORDER BY.  (Ticket #2942)  This used to not matter
//	**        until we introduced the group_concat() function.
//	**
//	**  (17)  If the subquery is a compound select, then
//	**        (17a) all compound operators must be a UNION ALL, and
//	**        (17b) no terms within the subquery compound may be aggregate
//	**              or DISTINCT, and
//	**        (17c) every term within the subquery compound must have a FROM clause
//	**        (17d) the outer query may not be
//	**              (17d1) aggregate, or
//	**              (17d2) DISTINCT
//	**        (17e) the subquery may not contain window functions, and
//	**        (17f) the subquery must not be the RHS of a LEFT JOIN.
//	**        (17g) either the subquery is the first element of the outer
//	**              query or there are no RIGHT or FULL JOINs in any arm
//	**              of the subquery.  (This is a duplicate of condition (27b).)
//	**        (17h) The corresponding result set expressions in all arms of the
//	**              compound must have the same affinity.
//	**
//	**        The parent and sub-query may contain WHERE clauses. Subject to
//	**        rules (11), (13) and (14), they may also contain ORDER BY,
//	**        LIMIT and OFFSET clauses.  The subquery cannot use any compound
//	**        operator other than UNION ALL because all the other compound
//	**        operators have an implied DISTINCT which is disallowed by
//	**        restriction (4).
//	**
//	**        Also, each component of the sub-query must return the same number
//	**        of result columns. This is actually a requirement for any compound
//	**        SELECT statement, but all the code here does is make sure that no
//	**        such (illegal) sub-query is flattened. The caller will detect the
//	**        syntax error and return a detailed message.
//	**
//	**  (18)  If the sub-query is a compound select, then all terms of the
//	**        ORDER BY clause of the parent must be copies of a term returned
//	**        by the parent query.
//	**
//	**  (19)  If the subquery uses LIMIT then the outer query may not
//	**        have a WHERE clause.
//	**
//	**  (20)  If the sub-query is a compound select, then it must not use
//	**        an ORDER BY clause.  Ticket #3773.  We could relax this constraint
//	**        somewhat by saying that the terms of the ORDER BY clause must
//	**        appear as unmodified result columns in the outer query.  But we
//	**        have other optimizations in mind to deal with that case.
//	**
//	**  (21)  If the subquery uses LIMIT then the outer query may not be
//	**        DISTINCT.  (See ticket [752e1646fc]).
//	**
//	**  (22)  The subquery may not be a recursive CTE.
//	**
//	**  (23)  If the outer query is a recursive CTE, then the sub-query may not be
//	**        a compound query.  This restriction is because transforming the
//	**        parent to a compound query confuses the code that handles
//	**        recursive queries in multiSelect().
//	**
//	**  (**)  We no longer attempt to flatten aggregate subqueries.  Was:
//	**        The subquery may not be an aggregate that uses the built-in min() or
//	**        or max() functions.  (Without this restriction, a query like:
//	**        "SELECT x FROM (SELECT max(y), x FROM t1)" would not necessarily
//	**        return the value X for which Y was maximal.)
//	**
//	**  (25)  If either the subquery or the parent query contains a window
//	**        function in the select list or ORDER BY clause, flattening
//	**        is not attempted.
//	**
//	**  (26)  The subquery may not be the right operand of a RIGHT JOIN.
//	**        See also (3) for restrictions on LEFT JOIN.
//	**
//	**  (27)  The subquery may not contain a FULL or RIGHT JOIN unless it
//	**        is the first element of the parent query.  Two subcases:
//	**        (27a) the subquery is not a compound query.
//	**        (27b) the subquery is a compound query and the RIGHT JOIN occurs
//	**              in any arm of the compound query.  (See also (17g).)
//	**
//	**  (28)  The subquery is not a MATERIALIZED CTE.  (This is handled
//	**        in the caller before ever reaching this routine.)
//	**
//	**
//	** In this routine, the "p" parameter is a pointer to the outer query.
//	** The subquery is p->pSrc->a[iFrom].  isAgg is true if the outer query
//	** uses aggregates.
//	**
//	** If flattening is not attempted, this routine is a no-op and returns 0.
//	** If flattening is attempted this routine returns 1.
//	**
//	** All of the expression analysis must occur on both the outer query and
//	** the subquery before this routine runs.
//	*/
func _flattenSubquery(tls *libc.TLS, pParse uintptr, p uintptr, iFrom int32, isAgg int32) (r int32) {
	bp := tls.Alloc(96)
	defer tls.Free(96)
	var aCsrMap, db, pItem, pItemTab, pLimit, pNew, pOrderBy, pOrderBy1, pParent, pPrior, pSrc, pSub, pSub1, pSubSrc, pSubitem, pTabToDel, pToplevel, pWhere, zSavedAuthContext, v5 uintptr
	var i, iNewParent, iParent, ii, isOuterJoin, nSubSrc, v4 int32
	var jointype Tu8
	var _ /* w at bp+0 */ TWalker
	var _ /* x at bp+48 */ TSubstContext
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = aCsrMap, db, i, iNewParent, iParent, ii, isOuterJoin, jointype, nSubSrc, pItem, pItemTab, pLimit, pNew, pOrderBy, pOrderBy1, pParent, pPrior, pSrc, pSub, pSub1, pSubSrc, pSubitem, pTabToDel, pToplevel, pWhere, zSavedAuthContext, v4, v5
	zSavedAuthContext = (*TParse)(unsafe.Pointer(pParse)).FzAuthContext /* VDBE cursor number of the pSub result set temp table */
	iNewParent = -int32(1)                                              /* Replacement table for iParent */
	isOuterJoin = 0                                                     /* The subquery */
	db = (*TParse)(unsafe.Pointer(pParse)).Fdb                          /* Walker to persist agginfo data */
	aCsrMap = uintptr(0)
	/* Check to see if flattening is permitted.  Return 0 if not.
	 */
	if (*Tsqlite3)(unsafe.Pointer(db)).FdbOptFlags&libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_QueryFlattener)) != uint32(0) {
		return 0
	}
	pSrc = (*TSelect)(unsafe.Pointer(p)).FpSrc
	pSubitem = pSrc + 8 + uintptr(iFrom)*80
	iParent = (*TSrcItem)(unsafe.Pointer(pSubitem)).FiCursor
	pSub = (*TSubquery)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pSubitem + 72)))).FpSelect
	if (*TSelect)(unsafe.Pointer(p)).FpWin != 0 || (*TSelect)(unsafe.Pointer(pSub)).FpWin != 0 {
		return 0
	} /* Restriction (25) */
	pSubSrc = (*TSelect)(unsafe.Pointer(pSub)).FpSrc
	/* Prior to version 3.1.2, when LIMIT and OFFSET had to be simple constants,
	 ** not arbitrary expressions, we allowed some combining of LIMIT and OFFSET
	 ** because they could be computed at compile-time.  But when LIMIT and OFFSET
	 ** became arbitrary expressions, we were forced to add restrictions (13)
	 ** and (14). */
	if (*TSelect)(unsafe.Pointer(pSub)).FpLimit != 0 && (*TSelect)(unsafe.Pointer(p)).FpLimit != 0 {
		return 0
	} /* Restriction (13) */
	if (*TSelect)(unsafe.Pointer(pSub)).FpLimit != 0 && (*TExpr)(unsafe.Pointer((*TSelect)(unsafe.Pointer(pSub)).FpLimit)).FpRight != 0 {
		return 0
	} /* Restriction (14) */
	if (*TSelect)(unsafe.Pointer(p)).FselFlags&uint32(SF_Compound) != uint32(0) && (*TSelect)(unsafe.Pointer(pSub)).FpLimit != 0 {
		return 0 /* Restriction (15) */
	}
	if (*TSrcList)(unsafe.Pointer(pSubSrc)).FnSrc == 0 {
		return 0
	} /* Restriction (7)  */
	if (*TSelect)(unsafe.Pointer(pSub)).FselFlags&uint32(SF_Distinct) != 0 {
		return 0
	} /* Restriction (4)  */
	if (*TSelect)(unsafe.Pointer(pSub)).FpLimit != 0 && ((*TSrcList)(unsafe.Pointer(pSrc)).FnSrc > int32(1) || isAgg != 0) {
		return 0 /* Restrictions (8)(9) */
	}
	if (*TSelect)(unsafe.Pointer(p)).FpOrderBy != 0 && (*TSelect)(unsafe.Pointer(pSub)).FpOrderBy != 0 {
		return 0 /* Restriction (11) */
	}
	if isAgg != 0 && (*TSelect)(unsafe.Pointer(pSub)).FpOrderBy != 0 {
		return 0
	} /* Restriction (16) */
	if (*TSelect)(unsafe.Pointer(pSub)).FpLimit != 0 && (*TSelect)(unsafe.Pointer(p)).FpWhere != 0 {
		return 0
	} /* Restriction (19) */
	if (*TSelect)(unsafe.Pointer(pSub)).FpLimit != 0 && (*TSelect)(unsafe.Pointer(p)).FselFlags&uint32(SF_Distinct) != uint32(0) {
		return 0 /* Restriction (21) */
	}
	if (*TSelect)(unsafe.Pointer(pSub)).FselFlags&libc.Uint32FromInt32(libc.Int32FromInt32(SF_Recursive)) != 0 {
		return 0 /* Restrictions (22) */
	}
	/*
	 ** If the subquery is the right operand of a LEFT JOIN, then the
	 ** subquery may not be a join itself (3a). Example of why this is not
	 ** allowed:
	 **
	 **         t1 LEFT OUTER JOIN (t2 JOIN t3)
	 **
	 ** If we flatten the above, we would get
	 **
	 **         (t1 LEFT OUTER JOIN t2) JOIN t3
	 **
	 ** which is not at all the same thing.
	 **
	 ** See also tickets #306, #350, and #3300.
	 */
	if libc.Int32FromUint8((*TSrcItem)(unsafe.Pointer(pSubitem)).Ffg.Fjointype)&(libc.Int32FromInt32(JT_OUTER)|libc.Int32FromInt32(JT_LTORJ)) != 0 {
		if (*TSrcList)(unsafe.Pointer(pSubSrc)).FnSrc > int32(1) || (*TSelect)(unsafe.Pointer(p)).FselFlags&uint32(SF_Distinct) != uint32(0) || libc.Int32FromUint8((*TSrcItem)(unsafe.Pointer(pSubitem)).Ffg.Fjointype)&int32(JT_RIGHT) != 0 {
			return 0
		}
		isOuterJoin = int32(1)
	}
	/* True by restriction (7) */
	if iFrom > 0 && libc.Int32FromUint8((*(*TSrcItem)(unsafe.Pointer(pSubSrc + 8))).Ffg.Fjointype)&int32(JT_LTORJ) != 0 {
		return 0 /* Restriction (27a) */
	}
	/* Condition (28) is blocked by the caller */
	/* Restriction (17): If the sub-query is a compound SELECT, then it must
	 ** use only the UNION ALL operator. And none of the simple select queries
	 ** that make up the compound SELECT are allowed to be aggregate or distinct
	 ** queries.
	 */
	if (*TSelect)(unsafe.Pointer(pSub)).FpPrior != 0 {
		if (*TSelect)(unsafe.Pointer(pSub)).FpOrderBy != 0 {
			return 0 /* Restriction (20) */
		}
		if isAgg != 0 || (*TSelect)(unsafe.Pointer(p)).FselFlags&uint32(SF_Distinct) != uint32(0) || isOuterJoin > 0 {
			return 0 /* (17d1), (17d2), or (17f) */
		}
		pSub1 = pSub
		for {
			if !(pSub1 != 0) {
				break
			}
			if (*TSelect)(unsafe.Pointer(pSub1)).FselFlags&libc.Uint32FromInt32(libc.Int32FromInt32(SF_Distinct)|libc.Int32FromInt32(SF_Aggregate)) != uint32(0) || (*TSelect)(unsafe.Pointer(pSub1)).FpPrior != 0 && libc.Int32FromUint8((*TSelect)(unsafe.Pointer(pSub1)).Fop) != int32(TK_ALL) || (*TSrcList)(unsafe.Pointer((*TSelect)(unsafe.Pointer(pSub1)).FpSrc)).FnSrc < int32(1) || (*TSelect)(unsafe.Pointer(pSub1)).FpWin != 0 {
				return 0
			}
			if iFrom > 0 && libc.Int32FromUint8((*(*TSrcItem)(unsafe.Pointer((*TSelect)(unsafe.Pointer(pSub1)).FpSrc + 8))).Ffg.Fjointype)&int32(JT_LTORJ) != 0 {
				/* Without this restriction, the JT_LTORJ flag would end up being
				 ** omitted on left-hand tables of the right join that is being
				 ** flattened. */
				return 0 /* Restrictions (17g), (27b) */
			}
			goto _1
		_1:
			;
			pSub1 = (*TSelect)(unsafe.Pointer(pSub1)).FpPrior
		}
		/* Restriction (18). */
		if (*TSelect)(unsafe.Pointer(p)).FpOrderBy != 0 {
			ii = 0
			for {
				if !(ii < (*TExprList)(unsafe.Pointer((*TSelect)(unsafe.Pointer(p)).FpOrderBy)).FnExpr) {
					break
				}
				if libc.Int32FromUint16(*(*Tu16)(unsafe.Pointer((*TSelect)(unsafe.Pointer(p)).FpOrderBy + 8 + uintptr(ii)*32 + 24))) == 0 {
					return 0
				}
				goto _2
			_2:
				;
				ii = ii + 1
			}
		}
		/* Restriction (23) */
		if (*TSelect)(unsafe.Pointer(p)).FselFlags&uint32(SF_Recursive) != 0 {
			return 0
		}
		/* Restriction (17h) */
		if _compoundHasDifferentAffinities(tls, pSub) != 0 {
			return 0
		}
		if (*TSrcList)(unsafe.Pointer(pSrc)).FnSrc > int32(1) {
			if (*TParse)(unsafe.Pointer(pParse)).FnSelect > int32(500) {
				return 0
			}
			if (*Tsqlite3)(unsafe.Pointer(db)).FdbOptFlags&libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FlttnUnionAll)) != uint32(0) {
				return 0
			}
			aCsrMap = _sqlite3DbMallocZero(tls, db, libc.Uint64FromInt64(int64((*TParse)(unsafe.Pointer(pParse)).FnTab)+libc.Int64FromInt32(1))*uint64(4))
			if aCsrMap != 0 {
				**(**int32)(__ccgo_up(aCsrMap)) = (*TParse)(unsafe.Pointer(pParse)).FnTab
			}
		}
	}
	/***** If we reach this point, flattening is permitted. *****/
	/* Authorize the subquery */
	(*TParse)(unsafe.Pointer(pParse)).FzAuthContext = (*TSrcItem)(unsafe.Pointer(pSubitem)).FzName
	_sqlite3AuthCheck(tls, pParse, int32(SQLITE_SELECT), uintptr(0), uintptr(0), uintptr(0))
	(*TParse)(unsafe.Pointer(pParse)).FzAuthContext = zSavedAuthContext
	/* Delete the transient structures associated with the subquery */
	if int32(*(*uint32)(unsafe.Pointer(pSubitem + 24 + 4))&0x4>>2) != 0 {
		pSub1 = _sqlite3SubqueryDetach(tls, db, pSubitem)
	} else {
		pSub1 = uintptr(0)
	}
	_sqlite3DbFree(tls, db, (*TSrcItem)(unsafe.Pointer(pSubitem)).FzName)
	_sqlite3DbFree(tls, db, (*TSrcItem)(unsafe.Pointer(pSubitem)).FzAlias)
	(*TSrcItem)(unsafe.Pointer(pSubitem)).FzName = uintptr(0)
	(*TSrcItem)(unsafe.Pointer(pSubitem)).FzAlias = uintptr(0)
	/* If the sub-query is a compound SELECT statement, then (by restrictions
	 ** 17 and 18 above) it must be a UNION ALL and the parent query must
	 ** be of the form:
	 **
	 **     SELECT <expr-list> FROM (<sub-query>) <where-clause>
	 **
	 ** followed by any ORDER BY, LIMIT and/or OFFSET clauses. This block
	 ** creates N-1 copies of the parent query without any ORDER BY, LIMIT or
	 ** OFFSET clauses and joins them to the left-hand-side of the original
	 ** using UNION ALL operators. In this case N is the number of simple
	 ** select statements in the compound sub-query.
	 **
	 ** Example:
	 **
	 **     SELECT a+1 FROM (
	 **        SELECT x FROM tab
	 **        UNION ALL
	 **        SELECT y FROM tab
	 **        UNION ALL
	 **        SELECT abs(z*2) FROM tab2
	 **     ) WHERE a!=5 ORDER BY 1
	 **
	 ** Transformed into:
	 **
	 **     SELECT x+1 FROM tab WHERE x+1!=5
	 **     UNION ALL
	 **     SELECT y+1 FROM tab WHERE y+1!=5
	 **     UNION ALL
	 **     SELECT abs(z*2)+1 FROM tab2 WHERE abs(z*2)+1!=5
	 **     ORDER BY 1
	 **
	 ** We call this the "compound-subquery flattening".
	 */
	pSub = (*TSelect)(unsafe.Pointer(pSub)).FpPrior
	for {
		if !(pSub != 0) {
			break
		}
		pOrderBy = (*TSelect)(unsafe.Pointer(p)).FpOrderBy
		pLimit = (*TSelect)(unsafe.Pointer(p)).FpLimit
		pPrior = (*TSelect)(unsafe.Pointer(p)).FpPrior
		pItemTab = (*TSrcItem)(unsafe.Pointer(pSubitem)).FpSTab
		(*TSrcItem)(unsafe.Pointer(pSubitem)).FpSTab = uintptr(0)
		(*TSelect)(unsafe.Pointer(p)).FpOrderBy = uintptr(0)
		(*TSelect)(unsafe.Pointer(p)).FpPrior = uintptr(0)
		(*TSelect)(unsafe.Pointer(p)).FpLimit = uintptr(0)
		pNew = _sqlite3SelectDup(tls, db, p, 0)
		(*TSelect)(unsafe.Pointer(p)).FpLimit = pLimit
		(*TSelect)(unsafe.Pointer(p)).FpOrderBy = pOrderBy
		(*TSelect)(unsafe.Pointer(p)).Fop = uint8(TK_ALL)
		(*TSrcItem)(unsafe.Pointer(pSubitem)).FpSTab = pItemTab
		if pNew == uintptr(0) {
			(*TSelect)(unsafe.Pointer(p)).FpPrior = pPrior
		} else {
			v5 = pParse + 124
			*(*int32)(unsafe.Pointer(v5)) = *(*int32)(unsafe.Pointer(v5)) + 1
			v4 = *(*int32)(unsafe.Pointer(v5))
			(*TSelect)(unsafe.Pointer(pNew)).FselId = libc.Uint32FromInt32(v4)
			if aCsrMap != 0 && libc.Int32FromUint8((*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed) == 0 {
				_renumberCursors(tls, pParse, pNew, iFrom, aCsrMap)
			}
			(*TSelect)(unsafe.Pointer(pNew)).FpPrior = pPrior
			if pPrior != 0 {
				(*TSelect)(unsafe.Pointer(pPrior)).FpNext = pNew
			}
			(*TSelect)(unsafe.Pointer(pNew)).FpNext = p
			(*TSelect)(unsafe.Pointer(p)).FpPrior = pNew
		}
		goto _3
	_3:
		;
		pSub = (*TSelect)(unsafe.Pointer(pSub)).FpPrior
	}
	_sqlite3DbFree(tls, db, aCsrMap)
	if (*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0 {
		_sqlite3SrcItemAttachSubquery(tls, pParse, pSubitem, pSub1, 0)
		return int32(1)
	}
	/* Defer deleting the Table object associated with the
	 ** subquery until code generation is
	 ** complete, since there may still exist Expr.pTab entries that
	 ** refer to the subquery even after flattening.  Ticket #3346.
	 **
	 ** pSubitem->pSTab is always non-NULL by test restrictions and tests above.
	 */
	if (*TSrcItem)(unsafe.Pointer(pSubitem)).FpSTab != uintptr(0) {
		pTabToDel = (*TSrcItem)(unsafe.Pointer(pSubitem)).FpSTab
		if (*TTable)(unsafe.Pointer(pTabToDel)).FnTabRef == uint32(1) {
			if (*TParse)(unsafe.Pointer(pParse)).FpToplevel != 0 {
				v5 = (*TParse)(unsafe.Pointer(pParse)).FpToplevel
			} else {
				v5 = pParse
			}
			pToplevel = v5
			_sqlite3ParserAddCleanup(tls, pToplevel, __ccgo_fp(_sqlite3DeleteTableGeneric), pTabToDel)
		} else {
			(*TTable)(unsafe.Pointer(pTabToDel)).FnTabRef = (*TTable)(unsafe.Pointer(pTabToDel)).FnTabRef - 1
		}
		(*TSrcItem)(unsafe.Pointer(pSubitem)).FpSTab = uintptr(0)
	}
	/* The following loop runs once for each term in a compound-subquery
	 ** flattening (as described above).  If we are doing a different kind
	 ** of flattening - a flattening other than a compound-subquery flattening -
	 ** then this loop only runs once.
	 **
	 ** This loop moves all of the FROM elements of the subquery into the
	 ** the FROM clause of the outer query.  Before doing this, remember
	 ** the cursor number for the original outer query FROM element in
	 ** iParent.  The iParent cursor will never be used.  Subsequent code
	 ** will scan expressions looking for iParent references and replace
	 ** those references with expressions that resolve to the subquery FROM
	 ** elements we are now copying in.
	 */
	pSub = pSub1
	pParent = p
	for {
		if !(pParent != 0) {
			break
		}
		jointype = (*TSrcItem)(unsafe.Pointer(pSubitem)).Ffg.Fjointype
		pSubSrc = (*TSelect)(unsafe.Pointer(pSub)).FpSrc     /* FROM clause of subquery */
		nSubSrc = (*TSrcList)(unsafe.Pointer(pSubSrc)).FnSrc /* Number of terms in subquery FROM clause */
		pSrc = (*TSelect)(unsafe.Pointer(pParent)).FpSrc     /* FROM clause of the outer query */
		/* The subquery uses a single slot of the FROM clause of the outer
		 ** query.  If the subquery has more than one element in its FROM clause,
		 ** then expand the outer query to make space for it to hold all elements
		 ** of the subquery.
		 **
		 ** Example:
		 **
		 **    SELECT * FROM tabA, (SELECT * FROM sub1, sub2), tabB;
		 **
		 ** The outer query has 3 slots in its FROM clause.  One slot of the
		 ** outer query (the middle slot) is used by the subquery.  The next
		 ** block of code will expand the outer query FROM clause to 4 slots.
		 ** The middle slot is expanded to two slots in order to make space
		 ** for the two elements in the FROM clause of the subquery.
		 */
		if nSubSrc > int32(1) {
			pSrc = _sqlite3SrcListEnlarge(tls, pParse, pSrc, nSubSrc-int32(1), iFrom+int32(1))
			if pSrc == uintptr(0) {
				break
			}
			(*TSelect)(unsafe.Pointer(pParent)).FpSrc = pSrc
			pSubitem = pSrc + 8 + uintptr(iFrom)*80
		}
		/* Transfer the FROM clause terms from the subquery into the
		 ** outer query.
		 */
		iNewParent = (*(*TSrcItem)(unsafe.Pointer(pSubSrc + 8))).FiCursor
		i = 0
		for {
			if !(i < nSubSrc) {
				break
			}
			pItem = pSrc + 8 + uintptr(i+iFrom)*80
			if int32(*(*uint32)(unsafe.Pointer(pItem + 24 + 4))&0x800>>11) != 0 {
				_sqlite3IdListDelete(tls, db, *(*uintptr)(unsafe.Pointer(pItem + 64)))
			}
			**(**TSrcItem)(__ccgo_up(pItem)) = *(*TSrcItem)(unsafe.Pointer(pSubSrc + 8 + uintptr(i)*80))
			v5 = pItem + 24
			*(*Tu8)(unsafe.Pointer(v5)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v5))) | libc.Int32FromUint8(jointype)&libc.Int32FromInt32(JT_LTORJ))
			libc.Xmemset(tls, pSubSrc+8+uintptr(i)*80, 0, uint64(80))
			goto _8
		_8:
			;
			i = i + 1
		}
		v5 = pSubitem + 24
		*(*Tu8)(unsafe.Pointer(v5)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v5))) | libc.Int32FromUint8(jointype))
		/* Begin substituting subquery result set expressions for
		 ** references to the iParent in the outer query.
		 **
		 ** Example:
		 **
		 **   SELECT a+5, b*10 FROM (SELECT x*3 AS a, y+10 AS b FROM t1) WHERE a>b;
		 **   \                     \_____________ subquery __________/          /
		 **    \_____________________ outer query ______________________________/
		 **
		 ** We look at every expression in the outer query and every place we see
		 ** "a" we substitute "x*3" and every place we see "b" we substitute "y+10".
		 */
		if (*TSelect)(unsafe.Pointer(pSub)).FpOrderBy != 0 {
			/* At this point, any non-zero iOrderByCol values indicate that the
			 ** ORDER BY column expression is identical to the iOrderByCol'th
			 ** expression returned by SELECT statement pSub. Since these values
			 ** do not necessarily correspond to columns in SELECT statement pParent,
			 ** zero them before transferring the ORDER BY clause.
			 **
			 ** Not doing this may cause an error if a subsequent call to this
			 ** function attempts to flatten a compound sub-query into pParent.
			 ** See ticket [d11a6e908f].
			 */
			pOrderBy1 = (*TSelect)(unsafe.Pointer(pSub)).FpOrderBy
			i = 0
			for {
				if !(i < (*TExprList)(unsafe.Pointer(pOrderBy1)).FnExpr) {
					break
				}
				*(*Tu16)(unsafe.Pointer(pOrderBy1 + 8 + uintptr(i)*32 + 24)) = uint16(0)
				goto _11
			_11:
				;
				i = i + 1
			}
			(*TSelect)(unsafe.Pointer(pParent)).FpOrderBy = pOrderBy1
			(*TSelect)(unsafe.Pointer(pSub)).FpOrderBy = uintptr(0)
		}
		pWhere = (*TSelect)(unsafe.Pointer(pSub)).FpWhere
		(*TSelect)(unsafe.Pointer(pSub)).FpWhere = uintptr(0)
		if isOuterJoin > 0 {
			_sqlite3SetJoinExpr(tls, pWhere, iNewParent, uint32(EP_OuterON))
		}
		if pWhere != 0 {
			if (*TSelect)(unsafe.Pointer(pParent)).FpWhere != 0 {
				(*TSelect)(unsafe.Pointer(pParent)).FpWhere = _sqlite3PExpr(tls, pParse, int32(TK_AND), pWhere, (*TSelect)(unsafe.Pointer(pParent)).FpWhere)
			} else {
				(*TSelect)(unsafe.Pointer(pParent)).FpWhere = pWhere
			}
		}
		if libc.Int32FromUint8((*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed) == 0 {
			(**(**TSubstContext)(__ccgo_up(bp + 48))).FpParse = pParse
			(**(**TSubstContext)(__ccgo_up(bp + 48))).FiTable = iParent
			(**(**TSubstContext)(__ccgo_up(bp + 48))).FiNewTable = iNewParent
			(**(**TSubstContext)(__ccgo_up(bp + 48))).FisOuterJoin = isOuterJoin
			(**(**TSubstContext)(__ccgo_up(bp + 48))).FnSelDepth = 0
			(**(**TSubstContext)(__ccgo_up(bp + 48))).FpEList = (*TSelect)(unsafe.Pointer(pSub)).FpEList
			(**(**TSubstContext)(__ccgo_up(bp + 48))).FpCList = _findLeftmostExprlist(tls, pSub)
			_substSelect(tls, bp+48, pParent, 0)
		}
		/* The flattened query is a compound if either the inner or the
		 ** outer query is a compound. */
		**(**Tu32)(__ccgo_up(pParent + 4)) |= (*TSelect)(unsafe.Pointer(pSub)).FselFlags & uint32(SF_Compound)
		/* restriction (17b) */
		/*
		 ** SELECT ... FROM (SELECT ... LIMIT a OFFSET b) LIMIT x OFFSET y;
		 **
		 ** One is tempted to try to add a and b to combine the limits.  But this
		 ** does not work if either limit is negative.
		 */
		if (*TSelect)(unsafe.Pointer(pSub)).FpLimit != 0 {
			(*TSelect)(unsafe.Pointer(pParent)).FpLimit = (*TSelect)(unsafe.Pointer(pSub)).FpLimit
			(*TSelect)(unsafe.Pointer(pSub)).FpLimit = uintptr(0)
		}
		/* Recompute the SrcItem.colUsed masks for the flattened
		 ** tables. */
		i = 0
		for {
			if !(i < nSubSrc) {
				break
			}
			_recomputeColumnsUsed(tls, pParent, pSrc+8+uintptr(i+iFrom)*80)
			goto _12
		_12:
			;
			i = i + 1
		}
		goto _7
	_7:
		;
		pParent = (*TSelect)(unsafe.Pointer(pParent)).FpPrior
		pSub = (*TSelect)(unsafe.Pointer(pSub)).FpPrior
	}
	/* Finally, delete what is left of the subquery and return success.
	 */
	_sqlite3AggInfoPersistWalkerInit(tls, bp, pParse)
	_sqlite3WalkSelect(tls, bp, pSub1)
	_sqlite3SelectDelete(tls, db, pSub1)
	return int32(1)
}

// C documentation
//
//	/*
//	** This function is used to add page iPage to the database file free-list.
//	** It is assumed that the page is not already a part of the free-list.
//	**
//	** The value passed as the second argument to this function is optional.
//	** If the caller happens to have a pointer to the MemPage object
//	** corresponding to page iPage handy, it may pass it as the second value.
//	** Otherwise, it may pass NULL.
//	**
//	** If a pointer to a MemPage object is passed as the second argument,
//	** its reference count is not altered by this function.
//	*/
func _freePage2(tls *libc.TLS, pBt uintptr, pMemPage uintptr, iPage TPgno) (r int32) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var iTrunk TPgno
	var nFree, nLeaf Tu32
	var pPage1 uintptr
	var v1, v3 int32
	var v2, v4 bool
	var _ /* pPage at bp+8 */ uintptr
	var _ /* pTrunk at bp+0 */ uintptr
	var _ /* rc at bp+16 */ int32
	_, _, _, _, _, _, _, _ = iTrunk, nFree, nLeaf, pPage1, v1, v2, v3, v4
	**(**uintptr)(__ccgo_up(bp)) = uintptr(0)          /* Free-list trunk page */
	iTrunk = uint32(0)                                 /* Page number of free-list trunk page */
	pPage1 = (*TBtShared)(unsafe.Pointer(pBt)).FpPage1 /* Initial number of pages on free-list */
	if iPage < uint32(2) || iPage > (*TBtShared)(unsafe.Pointer(pBt)).FnPage {
		return _sqlite3CorruptError(tls, int32(79983))
	}
	if pMemPage != 0 {
		**(**uintptr)(__ccgo_up(bp + 8)) = pMemPage
		_sqlite3PagerRef(tls, (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 8)))).FpDbPage)
	} else {
		**(**uintptr)(__ccgo_up(bp + 8)) = _btreePageLookup(tls, pBt, iPage)
	}
	/* Increment the free page count on pPage1 */
	**(**int32)(__ccgo_up(bp + 16)) = _sqlite3PagerWrite(tls, (*TMemPage)(unsafe.Pointer(pPage1)).FpDbPage)
	if **(**int32)(__ccgo_up(bp + 16)) != 0 {
		goto freepage_out
	}
	nFree = _sqlite3Get4byte(tls, (*TMemPage)(unsafe.Pointer(pPage1)).FaData+36)
	_sqlite3Put4byte(tls, (*TMemPage)(unsafe.Pointer(pPage1)).FaData+36, nFree+uint32(1))
	if libc.Int32FromUint16((*TBtShared)(unsafe.Pointer(pBt)).FbtsFlags)&int32(BTS_SECURE_DELETE) != 0 {
		/* If the secure_delete option is enabled, then
		 ** always fully overwrite deleted information with zeros.
		 */
		if v2 = !(**(**uintptr)(__ccgo_up(bp + 8)) != 0); v2 {
			v1 = _btreeGetPage(tls, pBt, iPage, bp+8, 0)
			**(**int32)(__ccgo_up(bp + 16)) = v1
		}
		if v4 = v2 && v1 != 0; !v4 {
			v3 = _sqlite3PagerWrite(tls, (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 8)))).FpDbPage)
			**(**int32)(__ccgo_up(bp + 16)) = v3
		}
		if v4 || v3 != 0 {
			goto freepage_out
		}
		libc.Xmemset(tls, (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 8)))).FaData, 0, uint64((*TBtShared)(unsafe.Pointer((*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 8)))).FpBt)).FpageSize))
	}
	/* If the database supports auto-vacuum, write an entry in the pointer-map
	 ** to indicate that the page is free.
	 */
	if (*TBtShared)(unsafe.Pointer(pBt)).FautoVacuum != 0 {
		_ptrmapPut(tls, pBt, iPage, uint8(PTRMAP_FREEPAGE), uint32(0), bp+16)
		if **(**int32)(__ccgo_up(bp + 16)) != 0 {
			goto freepage_out
		}
	}
	/* Now manipulate the actual database free-list structure. There are two
	 ** possibilities. If the free-list is currently empty, or if the first
	 ** trunk page in the free-list is full, then this page will become a
	 ** new free-list trunk page. Otherwise, it will become a leaf of the
	 ** first trunk page in the current free-list. This block tests if it
	 ** is possible to add the page as a new free-list leaf.
	 */
	if nFree != uint32(0) { /* Initial number of leaf cells on trunk page */
		iTrunk = _sqlite3Get4byte(tls, (*TMemPage)(unsafe.Pointer(pPage1)).FaData+32)
		if iTrunk > _btreePagecount(tls, pBt) {
			**(**int32)(__ccgo_up(bp + 16)) = _sqlite3CorruptError(tls, int32(80030))
			goto freepage_out
		}
		**(**int32)(__ccgo_up(bp + 16)) = _btreeGetPage(tls, pBt, iTrunk, bp, 0)
		if **(**int32)(__ccgo_up(bp + 16)) != SQLITE_OK {
			goto freepage_out
		}
		nLeaf = _sqlite3Get4byte(tls, (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FaData+4)
		if nLeaf > (*TBtShared)(unsafe.Pointer(pBt)).FusableSize/uint32(4)-uint32(2) {
			**(**int32)(__ccgo_up(bp + 16)) = _sqlite3CorruptError(tls, int32(80041))
			goto freepage_out
		}
		if nLeaf < (*TBtShared)(unsafe.Pointer(pBt)).FusableSize/uint32(4)-uint32(8) {
			/* In this case there is room on the trunk page to insert the page
			 ** being freed as a new leaf.
			 **
			 ** Note that the trunk page is not really full until it contains
			 ** usableSize/4 - 2 entries, not usableSize/4 - 8 entries as we have
			 ** coded.  But due to a coding error in versions of SQLite prior to
			 ** 3.6.0, databases with freelist trunk pages holding more than
			 ** usableSize/4 - 8 entries will be reported as corrupt.  In order
			 ** to maintain backwards compatibility with older versions of SQLite,
			 ** we will continue to restrict the number of entries to usableSize/4 - 8
			 ** for now.  At some point in the future (once everyone has upgraded
			 ** to 3.6.0 or later) we should consider fixing the conditional above
			 ** to read "usableSize/4-2" instead of "usableSize/4-8".
			 **
			 ** EVIDENCE-OF: R-19920-11576 However, newer versions of SQLite still
			 ** avoid using the last six entries in the freelist trunk page array in
			 ** order that database files created by newer versions of SQLite can be
			 ** read by older versions of SQLite.
			 */
			**(**int32)(__ccgo_up(bp + 16)) = _sqlite3PagerWrite(tls, (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FpDbPage)
			if **(**int32)(__ccgo_up(bp + 16)) == SQLITE_OK {
				_sqlite3Put4byte(tls, (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FaData+4, nLeaf+uint32(1))
				_sqlite3Put4byte(tls, (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FaData+uintptr(uint32(8)+nLeaf*uint32(4)), iPage)
				if **(**uintptr)(__ccgo_up(bp + 8)) != 0 && libc.Int32FromUint16((*TBtShared)(unsafe.Pointer(pBt)).FbtsFlags)&int32(BTS_SECURE_DELETE) == 0 {
					_sqlite3PagerDontWrite(tls, (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 8)))).FpDbPage)
				}
				**(**int32)(__ccgo_up(bp + 16)) = _btreeSetHasContent(tls, pBt, iPage)
			}
			goto freepage_out
		}
	}
	/* If control flows to this point, then it was not possible to add the
	 ** the page being freed as a leaf page of the first trunk in the free-list.
	 ** Possibly because the free-list is empty, or possibly because the
	 ** first trunk in the free-list is full. Either way, the page being freed
	 ** will become the new first trunk page in the free-list.
	 */
	if v2 = **(**uintptr)(__ccgo_up(bp + 8)) == uintptr(0); v2 {
		v1 = _btreeGetPage(tls, pBt, iPage, bp+8, 0)
		**(**int32)(__ccgo_up(bp + 16)) = v1
	}
	if v2 && SQLITE_OK != v1 {
		goto freepage_out
	}
	**(**int32)(__ccgo_up(bp + 16)) = _sqlite3PagerWrite(tls, (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 8)))).FpDbPage)
	if **(**int32)(__ccgo_up(bp + 16)) != SQLITE_OK {
		goto freepage_out
	}
	_sqlite3Put4byte(tls, (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 8)))).FaData, iTrunk)
	_sqlite3Put4byte(tls, (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 8)))).FaData+4, uint32(0))
	_sqlite3Put4byte(tls, (*TMemPage)(unsafe.Pointer(pPage1)).FaData+32, iPage)
	goto freepage_out
freepage_out:
	;
	if **(**uintptr)(__ccgo_up(bp + 8)) != 0 {
		(*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 8)))).FisInit = uint8(0)
	}
	_releasePage(tls, **(**uintptr)(__ccgo_up(bp + 8)))
	_releasePage(tls, **(**uintptr)(__ccgo_up(bp)))
	return **(**int32)(__ccgo_up(bp + 16))
}

// C documentation
//
//	/*
//	** Return a section of the pPage->aData to the freelist.
//	** The first byte of the new free block is pPage->aData[iStart]
//	** and the size of the block is iSize bytes.
//	**
//	** Adjacent freeblocks are coalesced.
//	**
//	** Even though the freeblock list was checked by btreeComputeFreeSpace(),
//	** that routine will not detect overlap between cells or freeblocks.  Nor
//	** does it detect cells or freeblocks that encroach into the reserved bytes
//	** at the end of the page.  So do additional corruption checks inside this
//	** routine and return SQLITE_CORRUPT if any problems are found.
//	*/
func _freeSpace(tls *libc.TLS, pPage uintptr, iStart int32, iSize int32) (r int32) {
	var data, pTmp, v2 uintptr
	var hdr Tu8
	var iEnd, iFreeBlk, iOrigSize, iPtr, iPtrEnd, nFrag, x, v1 int32
	_, _, _, _, _, _, _, _, _, _, _, _ = data, hdr, iEnd, iFreeBlk, iOrigSize, iPtr, iPtrEnd, nFrag, pTmp, x, v1, v2 /* Page header size.  0 or 100 */
	nFrag = 0                                                                                                        /* Reduction in fragmentation */
	iOrigSize = iSize                                                                                                /* Offset to cell content area */
	iEnd = iStart + iSize                                                                                            /* First byte past the iStart buffer */
	data = (*TMemPage)(unsafe.Pointer(pPage)).FaData                                                                 /* Temporary ptr into data[] */
	/* Minimum cell size is 4 */
	/* The list of freeblocks must be in ascending order.  Find the
	 ** spot on the list where iStart should be inserted.
	 */
	hdr = (*TMemPage)(unsafe.Pointer(pPage)).FhdrOffset
	iPtr = libc.Int32FromUint8(hdr) + int32(1)
	if libc.Int32FromUint8(**(**uint8)(__ccgo_up(data + uintptr(iPtr+int32(1))))) == 0 && libc.Int32FromUint8(**(**uint8)(__ccgo_up(data + uintptr(iPtr)))) == 0 {
		iFreeBlk = 0 /* Shortcut for the case when the freelist is empty */
	} else {
		for {
			v1 = libc.Int32FromUint8(**(**uint8)(__ccgo_up(data + uintptr(iPtr))))<<libc.Int32FromInt32(8) | libc.Int32FromUint8(**(**uint8)(__ccgo_up(data + uintptr(iPtr) + 1)))
			iFreeBlk = v1
			if !(v1 < iStart) {
				break
			}
			if iFreeBlk <= iPtr {
				if iFreeBlk == 0 {
					break
				} /* TH3: corrupt082.100 */
				return _sqlite3CorruptError(tls, int32(75089))
			}
			iPtr = iFreeBlk
		}
		if iFreeBlk > libc.Int32FromUint32((*TBtShared)(unsafe.Pointer((*TMemPage)(unsafe.Pointer(pPage)).FpBt)).FusableSize)-int32(4) { /* TH3: corrupt081.100 */
			return _sqlite3CorruptError(tls, int32(75094))
		}
		/* At this point:
		 **    iFreeBlk:   First freeblock after iStart, or zero if none
		 **    iPtr:       The address of a pointer to iFreeBlk
		 **
		 ** Check to see if iFreeBlk should be coalesced onto the end of iStart.
		 */
		if iFreeBlk != 0 && iEnd+int32(3) >= iFreeBlk {
			nFrag = iFreeBlk - iEnd
			if iEnd > iFreeBlk {
				return _sqlite3CorruptError(tls, int32(75106))
			}
			iEnd = iFreeBlk + (libc.Int32FromUint8(**(**uint8)(__ccgo_up(data + uintptr(iFreeBlk+int32(2)))))<<int32(8) | libc.Int32FromUint8(**(**uint8)(__ccgo_up(data + uintptr(iFreeBlk+int32(2)) + 1))))
			if iEnd > libc.Int32FromUint32((*TBtShared)(unsafe.Pointer((*TMemPage)(unsafe.Pointer(pPage)).FpBt)).FusableSize) {
				return _sqlite3CorruptError(tls, int32(75109))
			}
			iSize = iEnd - iStart
			iFreeBlk = libc.Int32FromUint8(**(**uint8)(__ccgo_up(data + uintptr(iFreeBlk))))<<int32(8) | libc.Int32FromUint8(**(**uint8)(__ccgo_up(data + uintptr(iFreeBlk) + 1)))
		}
		/* If iPtr is another freeblock (that is, if iPtr is not the freelist
		 ** pointer in the page header) then check to see if iStart should be
		 ** coalesced onto the end of iPtr.
		 */
		if iPtr > libc.Int32FromUint8(hdr)+int32(1) {
			iPtrEnd = iPtr + (libc.Int32FromUint8(**(**uint8)(__ccgo_up(data + uintptr(iPtr+int32(2)))))<<int32(8) | libc.Int32FromUint8(**(**uint8)(__ccgo_up(data + uintptr(iPtr+int32(2)) + 1))))
			if iPtrEnd+int32(3) >= iStart {
				if iPtrEnd > iStart {
					return _sqlite3CorruptError(tls, int32(75122))
				}
				nFrag = nFrag + (iStart - iPtrEnd)
				iSize = iEnd - iPtr
				iStart = iPtr
			}
		}
		if nFrag > libc.Int32FromUint8(**(**uint8)(__ccgo_up(data + uintptr(libc.Int32FromUint8(hdr)+int32(7))))) {
			return _sqlite3CorruptError(tls, int32(75128))
		}
		v2 = data + uintptr(libc.Int32FromUint8(hdr)+int32(7))
		*(*uint8)(unsafe.Pointer(v2)) = uint8(int32(*(*uint8)(unsafe.Pointer(v2))) - libc.Int32FromUint8(libc.Uint8FromInt32(nFrag)))
	}
	pTmp = data + uintptr(libc.Int32FromUint8(hdr)+int32(5))
	x = libc.Int32FromUint8(**(**Tu8)(__ccgo_up(pTmp)))<<int32(8) | libc.Int32FromUint8(**(**Tu8)(__ccgo_up(pTmp + 1)))
	if libc.Int32FromUint16((*TBtShared)(unsafe.Pointer((*TMemPage)(unsafe.Pointer(pPage)).FpBt)).FbtsFlags)&int32(BTS_FAST_SECURE) != 0 {
		/* Overwrite deleted information with zeros when the secure_delete
		 ** option is enabled */
		libc.Xmemset(tls, data+uintptr(iStart), 0, libc.Uint64FromInt32(iSize))
	}
	if iStart <= x {
		/* The new freeblock is at the beginning of the cell content area,
		 ** so just extend the cell content area rather than create another
		 ** freelist entry */
		if iStart < x {
			return _sqlite3CorruptError(tls, int32(75142))
		}
		if iPtr != libc.Int32FromUint8(hdr)+int32(1) {
			return _sqlite3CorruptError(tls, int32(75143))
		}
		**(**uint8)(__ccgo_up(data + uintptr(libc.Int32FromUint8(hdr)+int32(1)))) = libc.Uint8FromInt32(iFreeBlk >> libc.Int32FromInt32(8))
		**(**uint8)(__ccgo_up(data + uintptr(libc.Int32FromUint8(hdr)+int32(1)) + 1)) = libc.Uint8FromInt32(iFreeBlk)
		**(**uint8)(__ccgo_up(data + uintptr(libc.Int32FromUint8(hdr)+int32(5)))) = libc.Uint8FromInt32(iEnd >> libc.Int32FromInt32(8))
		**(**uint8)(__ccgo_up(data + uintptr(libc.Int32FromUint8(hdr)+int32(5)) + 1)) = libc.Uint8FromInt32(iEnd)
	} else {
		/* Insert the new freeblock into the freelist */
		**(**uint8)(__ccgo_up(data + uintptr(iPtr))) = libc.Uint8FromInt32(iStart >> libc.Int32FromInt32(8))
		**(**uint8)(__ccgo_up(data + uintptr(iPtr) + 1)) = libc.Uint8FromInt32(iStart)
		**(**uint8)(__ccgo_up(data + uintptr(iStart))) = libc.Uint8FromInt32(iFreeBlk >> libc.Int32FromInt32(8))
		**(**uint8)(__ccgo_up(data + uintptr(iStart) + 1)) = libc.Uint8FromInt32(iFreeBlk)
		**(**uint8)(__ccgo_up(data + uintptr(iStart+int32(2)))) = libc.Uint8FromInt32(libc.Int32FromUint16(libc.Uint16FromInt32(iSize)) >> libc.Int32FromInt32(8))
		**(**uint8)(__ccgo_up(data + uintptr(iStart+int32(2)) + 1)) = uint8(libc.Uint16FromInt32(iSize))
	}
	**(**int32)(__ccgo_up(pPage + 20)) += iOrigSize
	return SQLITE_OK
}

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+60, pBuf, libc.Uint32FromInt32(nByte+(*TFts5Buffer)(unsafe.Pointer(pBuf)).Fn))
		}
	}
	if v2 && 0 == v1 {
		**(**int32)(__ccgo_up(pBuf + 8)) += _sqlite3Fts5PutVarint(tls, (*TFts5Buffer)(unsafe.Pointer(pBuf)).Fp+uintptr((*TFts5Buffer)(unsafe.Pointer(pBuf)).Fn), iDelta)
		**(**int32)(__ccgo_up(pBuf + 8)) += _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.Uint64FromInt32(nData))
		**(**int32)(__ccgo_up(pBuf + 8)) += nData
		libc.Xmemset(tls, (*TFts5Buffer)(unsafe.Pointer(pBuf)).Fp+uintptr((*TFts5Buffer)(unsafe.Pointer(pBuf)).Fn), 0, uint64(FTS5_DATA_ZERO_PADDING))
	}
}

// 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.Int64FromUint64(uint64(libc.UintptrFromInt32(0)+72) + libc.Uint64FromInt64(nAlloc+libc.Int64FromInt32(1))*libc.Uint64FromInt64(104))
			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.Uint64FromInt64(nByte))
				}
				pRet = pNew
				(*TFts5TokenDataIter)(unsafe.Pointer(pNew)).FnIterAlloc = nAlloc
			}
		}
	}
	if (*TFts5Index)(unsafe.Pointer(p)).Frc != 0 {
		_fts5IterClose(tls, pAppend)
	} else {
		v3 = pRet + 40
		v2 = *(*Ti64)(unsafe.Pointer(v3))
		*(*Ti64)(unsafe.Pointer(v3)) = *(*Ti64)(unsafe.Pointer(v3)) + 1
		*(*uintptr)(unsafe.Pointer(pRet + 72 + uintptr(v2)*8)) = 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.Int64FromUint64(uint64(32) + libc.Uint64FromInt32(nPhrase*int32(2))*uint64(8))
		p = Xsqlite3_malloc64(tls, libc.Uint64FromInt64(nByte))
		if p == uintptr(0) {
			rc = int32(SQLITE_NOMEM)
		} else {
			libc.Xmemset(tls, p, 0, libc.Uint64FromInt64(nByte))
			(*TFts5Bm25Data)(unsafe.Pointer(p)).FnPhrase = nPhrase
			(*TFts5Bm25Data)(unsafe.Pointer(p)).FaIDF = p + 1*32
			(*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
//
//	/*
//	** If argument pOrig is NULL, or if (*pRc) is set to anything other than
//	** SQLITE_OK when this function is called, NULL is returned.
//	**
//	** Otherwise, a copy of (*pOrig) is made into memory obtained from
//	** sqlite3Fts5MallocZero() and a pointer to it returned. If the allocation
//	** fails, (*pRc) is set to SQLITE_NOMEM and NULL is returned.
//	*/
func _fts5CloneColset(tls *libc.TLS, pRc uintptr, pOrig uintptr) (r uintptr) {
	var nByte Tsqlite3_int64
	var pRet uintptr
	_, _ = nByte, pRet
	if pOrig != 0 {
		nByte = libc.Int64FromUint64(libc.Uint64FromInt64(8) * libc.Uint64FromInt32(((*TFts5Colset)(unsafe.Pointer(pOrig)).FnCol+libc.Int32FromInt32(2))/libc.Int32FromInt32(2)))
		pRet = _sqlite3Fts5MallocZero(tls, pRc, nByte)
		if pRet != 0 {
			libc.Xmemcpy(tls, pRet, pOrig, libc.Uint64FromInt64(nByte))
		}
	} else {
		pRet = uintptr(0)
	}
	return pRet
}

// C documentation
//
//	/*
//	** Register a new auxiliary function with global context pGlobal.
//	*/
func _fts5CreateAux(tls *libc.TLS, pApi uintptr, zName uintptr, pUserData uintptr, __ccgo_fp_xFunc Tfts5_extension_function, __ccgo_fp_xDestroy uintptr) (r int32) {
	var nByte, nName Tsqlite3_int64
	var pAux, pGlobal uintptr
	var rc int32
	_, _, _, _, _ = nByte, nName, pAux, pGlobal, rc
	pGlobal = pApi
	rc = Xsqlite3_overload_function(tls, (*TFts5Global)(unsafe.Pointer(pGlobal)).Fdb, zName, -int32(1))
	if rc == SQLITE_OK { /* Bytes of space to allocate */
		nName = libc.Int64FromUint64(libc.Xstrlen(tls, zName) + uint64(1))
		nByte = libc.Int64FromUint64(uint64(48) + libc.Uint64FromInt64(nName))
		pAux = Xsqlite3_malloc64(tls, libc.Uint64FromInt64(nByte))
		if pAux != 0 {
			libc.Xmemset(tls, pAux, 0, libc.Uint64FromInt64(nByte))
			(*TFts5Auxiliary)(unsafe.Pointer(pAux)).FzFunc = pAux + 1*48
			libc.Xmemcpy(tls, (*TFts5Auxiliary)(unsafe.Pointer(pAux)).FzFunc, zName, libc.Uint64FromInt64(nName))
			(*TFts5Auxiliary)(unsafe.Pointer(pAux)).FpGlobal = pGlobal
			(*TFts5Auxiliary)(unsafe.Pointer(pAux)).FpUserData = pUserData
			(*TFts5Auxiliary)(unsafe.Pointer(pAux)).FxFunc = __ccgo_fp_xFunc
			(*TFts5Auxiliary)(unsafe.Pointer(pAux)).FxDestroy = __ccgo_fp_xDestroy
			(*TFts5Auxiliary)(unsafe.Pointer(pAux)).FpNext = (*TFts5Global)(unsafe.Pointer(pGlobal)).FpAux
			(*TFts5Global)(unsafe.Pointer(pGlobal)).FpAux = pAux
		} else {
			rc = int32(SQLITE_NOMEM)
		}
	}
	return rc
}

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.Int64FromUint64(uint64(libc.UintptrFromInt32(0)+8) + libc.Uint64FromInt32(i+libc.Int32FromInt32(1))*libc.Uint64FromInt64(32))
		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)*32
			pIter = pNew
			libc.Xmemset(tls, pLvl, 0, uint64(32))
			(*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
}

// 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+60, int64(nIdx)+int64(16))
	if (*TFts5Index)(unsafe.Pointer(p)).Frc != 0 {
		return
	}
	libc.Xmemcpy(tls, aIdx, aPg+uintptr(iPgIdx), libc.Uint64FromInt32(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))), uint64(**(**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), uint64(**(**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.Uint64FromInt32(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.Uint64FromInt32(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)
}

// 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.Int32FromUint64(uint64(8) * libc.Uint64FromInt32((*TFts5ExprNode)(unsafe.Pointer(pSub)).FnChild))
		libc.Xmemcpy(tls, p+48+uintptr((*TFts5ExprNode)(unsafe.Pointer(p)).FnChild)*8, pSub+48, libc.Uint64FromInt32(nByte))
		**(**int32)(__ccgo_up(p + 40)) += (*TFts5ExprNode)(unsafe.Pointer(pSub)).FnChild
		Xsqlite3_free(tls, pSub)
	} else {
		v2 = p + 40
		v1 = *(*int32)(unsafe.Pointer(v2))
		*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1
		*(*uintptr)(unsafe.Pointer(p + 48 + uintptr(v1)*8)) = pSub
	}
	for {
		if !(ii < (*TFts5ExprNode)(unsafe.Pointer(p)).FnChild) {
			break
		}
		if (*TFts5ExprNode)(unsafe.Pointer(p)).FiHeight > (*TFts5ExprNode)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(p + 48 + uintptr(ii)*8)))).FiHeight+int32(1) {
			v1 = (*TFts5ExprNode)(unsafe.Pointer(p)).FiHeight
		} else {
			v1 = (*TFts5ExprNode)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(p + 48 + uintptr(ii)*8)))).FiHeight + int32(1)
		}
		(*TFts5ExprNode)(unsafe.Pointer(p)).FiHeight = v1
		goto _3
	_3:
		;
		ii = ii + 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(208)
	defer tls.Free(208)
	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+192 */ int32
	_, _, _, _, _, _, _, _, _, _, _, _, _ = a, apPhrase, bMatch, bRet, i, iAdv, iMax, iMin, iPos, nByte, pPos, pPoslist, pWriter
	a = bp
	apPhrase = pNear + 24
	**(**int32)(__ccgo_up(bp + 192)) = **(**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.Int32FromUint64(libc.Uint64FromInt64(192)/libc.Uint64FromInt64(48)) {
		nByte = libc.Int64FromUint64(uint64(48) * libc.Uint64FromInt32((*TFts5ExprNearset)(unsafe.Pointer(pNear)).FnPhrase))
		a = _sqlite3Fts5MallocZero(tls, bp+192, nByte)
	} else {
		libc.Xmemset(tls, bp, 0, uint64(192))
	}
	if **(**int32)(__ccgo_up(bp + 192)) != SQLITE_OK {
		**(**int32)(__ccgo_up(pRc)) = **(**int32)(__ccgo_up(bp + 192))
		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)*8)) + 8
		_fts5LookaheadReaderInit(tls, (*TFts5Buffer)(unsafe.Pointer(pPoslist)).Fp, (*TFts5Buffer)(unsafe.Pointer(pPoslist)).Fn, a+uintptr(i)*48)
		(*TFts5Buffer)(unsafe.Pointer(pPoslist)).Fn = 0
		(**(**TFts5NearTrimmer)(__ccgo_up(a + uintptr(i)*48))).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)*48
				iMin = iMax - int64((*TFts5ExprPhrase)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pNear + 24 + uintptr(i)*8)))).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)*48))).Freader.FiPos
			pWriter = a + uintptr(i)*48 + 32
			if (*TFts5Buffer)(unsafe.Pointer((**(**TFts5NearTrimmer)(__ccgo_up(a + uintptr(i)*48))).FpOut)).Fn == 0 || iPos != (*TFts5PoslistWriter)(unsafe.Pointer(pWriter)).FiPrev {
				_sqlite3Fts5PoslistWriterAppend(tls, (**(**TFts5NearTrimmer)(__ccgo_up(a + uintptr(i)*48))).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)*48))).Freader.FiLookahead < iMin {
				iMin = (**(**TFts5NearTrimmer)(__ccgo_up(a + uintptr(i)*48))).Freader.FiLookahead
				iAdv = i
			}
			goto _4
		_4:
			;
			i = i + 1
		}
		if _fts5LookaheadReaderNext(tls, a+uintptr(iAdv)*48) != 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 + 192))
	if a != bp {
		Xsqlite3_free(tls, a)
	}
	return bRet
	return r
}

// C documentation
//
//	/*
//	** All individual term iterators in pPhrase are guaranteed to be valid and
//	** pointing to the same rowid when this function is called. This function
//	** checks if the current rowid really is a match, and if so populates
//	** the pPhrase->poslist buffer accordingly. Output parameter *pbMatch
//	** is set to true if this is really a match, or false otherwise.
//	**
//	** SQLITE_OK is returned if an error occurs, or an SQLite error code
//	** otherwise. It is not considered an error code if the current rowid is
//	** not a match.
//	*/
func _fts5ExprPhraseIsMatch(tls *libc.TLS, pNode uintptr, pPhrase uintptr, pbMatch uintptr) (r int32) {
	bp := tls.Alloc(176)
	defer tls.Free(176)
	var aIter, pPos, pTerm uintptr
	var bFirst, bFlag, bMatch, i, rc int32
	var iAdj, iPos Ti64
	var nByte Tsqlite3_int64
	var _ /* a at bp+144 */ uintptr
	var _ /* aStatic at bp+8 */ [4]TFts5PoslistReader
	var _ /* buf at bp+152 */ TFts5Buffer
	var _ /* n at bp+136 */ int32
	var _ /* writer at bp+0 */ TFts5PoslistWriter
	_, _, _, _, _, _, _, _, _, _, _ = aIter, bFirst, bFlag, bMatch, i, iAdj, iPos, nByte, pPos, pTerm, rc
	**(**TFts5PoslistWriter)(__ccgo_up(bp)) = TFts5PoslistWriter{}
	aIter = bp + 8
	rc = SQLITE_OK
	bFirst = libc.Int32FromUint8((*(*TFts5ExprTerm)(unsafe.Pointer(pPhrase + 32))).FbFirst)
	_sqlite3Fts5BufferZero(tls, pPhrase+8)
	/* If the aStatic[] array is not large enough, allocate a large array
	 ** using sqlite3_malloc(). This approach could be improved upon. */
	if (*TFts5ExprPhrase)(unsafe.Pointer(pPhrase)).FnTerm > libc.Int32FromUint64(libc.Uint64FromInt64(128)/libc.Uint64FromInt64(32)) {
		nByte = libc.Int64FromUint64(uint64(32) * libc.Uint64FromInt32((*TFts5ExprPhrase)(unsafe.Pointer(pPhrase)).FnTerm))
		aIter = Xsqlite3_malloc64(tls, libc.Uint64FromInt64(nByte))
		if !(aIter != 0) {
			return int32(SQLITE_NOMEM)
		}
	}
	libc.Xmemset(tls, aIter, 0, uint64(32)*libc.Uint64FromInt32((*TFts5ExprPhrase)(unsafe.Pointer(pPhrase)).FnTerm))
	/* Initialize a term iterator for each term in the phrase */
	i = 0
	for {
		if !(i < (*TFts5ExprPhrase)(unsafe.Pointer(pPhrase)).FnTerm) {
			break
		}
		pTerm = pPhrase + 32 + uintptr(i)*40
		**(**int32)(__ccgo_up(bp + 136)) = 0
		bFlag = 0
		**(**uintptr)(__ccgo_up(bp + 144)) = uintptr(0)
		if (*TFts5ExprTerm)(unsafe.Pointer(pTerm)).FpSynonym != 0 {
			**(**TFts5Buffer)(__ccgo_up(bp + 152)) = TFts5Buffer{}
			rc = _fts5ExprSynonymList(tls, pTerm, (*TFts5ExprNode)(unsafe.Pointer(pNode)).FiRowid, bp+152, bp+144, bp+136)
			if rc != 0 {
				Xsqlite3_free(tls, **(**uintptr)(__ccgo_up(bp + 144)))
				goto ismatch_out
			}
			if **(**uintptr)(__ccgo_up(bp + 144)) == (**(**TFts5Buffer)(__ccgo_up(bp + 152))).Fp {
				bFlag = int32(1)
			}
		} else {
			**(**uintptr)(__ccgo_up(bp + 144)) = (*TFts5IndexIter)(unsafe.Pointer((*TFts5ExprTerm)(unsafe.Pointer(pTerm)).FpIter)).FpData
			**(**int32)(__ccgo_up(bp + 136)) = (*TFts5IndexIter)(unsafe.Pointer((*TFts5ExprTerm)(unsafe.Pointer(pTerm)).FpIter)).FnData
		}
		_sqlite3Fts5PoslistReaderInit(tls, **(**uintptr)(__ccgo_up(bp + 144)), **(**int32)(__ccgo_up(bp + 136)), aIter+uintptr(i)*32)
		(**(**TFts5PoslistReader)(__ccgo_up(aIter + uintptr(i)*32))).FbFlag = libc.Uint8FromInt32(bFlag)
		if (**(**TFts5PoslistReader)(__ccgo_up(aIter + uintptr(i)*32))).FbEof != 0 {
			goto ismatch_out
		}
		goto _1
	_1:
		;
		i = i + 1
	}
	for int32(1) != 0 {
		iPos = (**(**TFts5PoslistReader)(__ccgo_up(aIter))).FiPos
		for cond := true; cond; cond = bMatch == 0 {
			bMatch = int32(1)
			i = 0
			for {
				if !(i < (*TFts5ExprPhrase)(unsafe.Pointer(pPhrase)).FnTerm) {
					break
				}
				pPos = aIter + uintptr(i)*32
				iAdj = iPos + int64(i)
				if (*TFts5PoslistReader)(unsafe.Pointer(pPos)).FiPos != iAdj {
					bMatch = 0
					for (*TFts5PoslistReader)(unsafe.Pointer(pPos)).FiPos < iAdj {
						if _sqlite3Fts5PoslistReaderNext(tls, pPos) != 0 {
							goto ismatch_out
						}
					}
					if (*TFts5PoslistReader)(unsafe.Pointer(pPos)).FiPos > iAdj {
						iPos = (*TFts5PoslistReader)(unsafe.Pointer(pPos)).FiPos - int64(i)
					}
				}
				goto _2
			_2:
				;
				i = i + 1
			}
		}
		/* Append position iPos to the output */
		if bFirst == 0 || int32(iPos&libc.Int64FromInt32(0x7FFFFFFF)) == 0 {
			rc = _sqlite3Fts5PoslistWriterAppend(tls, pPhrase+8, bp, iPos)
			if rc != SQLITE_OK {
				goto ismatch_out
			}
		}
		i = 0
		for {
			if !(i < (*TFts5ExprPhrase)(unsafe.Pointer(pPhrase)).FnTerm) {
				break
			}
			if _sqlite3Fts5PoslistReaderNext(tls, aIter+uintptr(i)*32) != 0 {
				goto ismatch_out
			}
			goto _3
		_3:
			;
			i = i + 1
		}
	}
	goto ismatch_out
ismatch_out:
	;
	**(**int32)(__ccgo_up(pbMatch)) = libc.BoolInt32((*TFts5ExprPhrase)(unsafe.Pointer(pPhrase)).Fposlist.Fn > 0)
	i = 0
	for {
		if !(i < (*TFts5ExprPhrase)(unsafe.Pointer(pPhrase)).FnTerm) {
			break
		}
		if (**(**TFts5PoslistReader)(__ccgo_up(aIter + uintptr(i)*32))).FbFlag != 0 {
			Xsqlite3_free(tls, (**(**TFts5PoslistReader)(__ccgo_up(aIter + uintptr(i)*32))).Fa)
		}
		goto _4
	_4:
		;
		i = i + 1
	}
	if aIter != bp+8 {
		Xsqlite3_free(tls, aIter)
	}
	return rc
}

// C documentation
//
//	/*
//	** Argument pTerm must be a synonym iterator.
//	*/
func _fts5ExprSynonymList(tls *libc.TLS, pTerm uintptr, iRowid Ti64, pBuf uintptr, pa uintptr, pn uintptr) (r int32) {
	bp := tls.Alloc(144)
	defer tls.Free(144)
	var aIter, aNew, p, pIter uintptr
	var i, nAlloc, nIter, rc int32
	var iMin, iPrev Ti64
	var nByte Tsqlite3_int64
	var _ /* aStatic at bp+0 */ [4]TFts5PoslistReader
	var _ /* writer at bp+128 */ TFts5PoslistWriter
	_, _, _, _, _, _, _, _, _, _, _ = aIter, aNew, i, iMin, iPrev, nAlloc, nByte, nIter, p, pIter, rc
	aIter = bp
	nIter = 0
	nAlloc = int32(4)
	rc = SQLITE_OK
	p = pTerm
	for {
		if !(p != 0) {
			break
		}
		pIter = (*TFts5ExprTerm)(unsafe.Pointer(p)).FpIter
		if libc.Int32FromUint8((*TFts5IndexIter)(unsafe.Pointer(pIter)).FbEof) == 0 && (*TFts5IndexIter)(unsafe.Pointer(pIter)).FiRowid == iRowid {
			if (*TFts5IndexIter)(unsafe.Pointer(pIter)).FnData == 0 {
				goto _1
			}
			if nIter == nAlloc {
				nByte = libc.Int64FromUint64(uint64(32) * libc.Uint64FromInt32(nAlloc) * uint64(2))
				aNew = Xsqlite3_malloc64(tls, libc.Uint64FromInt64(nByte))
				if aNew == uintptr(0) {
					rc = int32(SQLITE_NOMEM)
					goto synonym_poslist_out
				}
				libc.Xmemcpy(tls, aNew, aIter, uint64(32)*libc.Uint64FromInt32(nIter))
				nAlloc = nAlloc * int32(2)
				if aIter != bp {
					Xsqlite3_free(tls, aIter)
				}
				aIter = aNew
			}
			_sqlite3Fts5PoslistReaderInit(tls, (*TFts5IndexIter)(unsafe.Pointer(pIter)).FpData, (*TFts5IndexIter)(unsafe.Pointer(pIter)).FnData, aIter+uintptr(nIter)*32)
			nIter = nIter + 1
		}
		goto _1
	_1:
		;
		p = (*TFts5ExprTerm)(unsafe.Pointer(p)).FpSynonym
	}
	if nIter == int32(1) {
		**(**uintptr)(__ccgo_up(pa)) = (**(**TFts5PoslistReader)(__ccgo_up(aIter))).Fa
		**(**int32)(__ccgo_up(pn)) = (**(**TFts5PoslistReader)(__ccgo_up(aIter))).Fn
	} else {
		**(**TFts5PoslistWriter)(__ccgo_up(bp + 128)) = TFts5PoslistWriter{}
		iPrev = int64(-int32(1))
		_sqlite3Fts5BufferZero(tls, pBuf)
		for int32(1) != 0 {
			iMin = libc.Int64FromUint32(0xffffffff) | libc.Int64FromInt32(0x7fffffff)<<libc.Int32FromInt32(32)
			i = 0
			for {
				if !(i < nIter) {
					break
				}
				if libc.Int32FromUint8((**(**TFts5PoslistReader)(__ccgo_up(aIter + uintptr(i)*32))).FbEof) == 0 {
					if (**(**TFts5PoslistReader)(__ccgo_up(aIter + uintptr(i)*32))).FiPos == iPrev {
						if _sqlite3Fts5PoslistReaderNext(tls, aIter+uintptr(i)*32) != 0 {
							goto _2
						}
					}
					if (**(**TFts5PoslistReader)(__ccgo_up(aIter + uintptr(i)*32))).FiPos < iMin {
						iMin = (**(**TFts5PoslistReader)(__ccgo_up(aIter + uintptr(i)*32))).FiPos
					}
				}
				goto _2
			_2:
				;
				i = i + 1
			}
			if iMin == libc.Int64FromUint32(0xffffffff)|libc.Int64FromInt32(0x7fffffff)<<libc.Int32FromInt32(32) || rc != SQLITE_OK {
				break
			}
			rc = _sqlite3Fts5PoslistWriterAppend(tls, pBuf, bp+128, iMin)
			iPrev = iMin
		}
		if rc == SQLITE_OK {
			**(**uintptr)(__ccgo_up(pa)) = (*TFts5Buffer)(unsafe.Pointer(pBuf)).Fp
			**(**int32)(__ccgo_up(pn)) = (*TFts5Buffer)(unsafe.Pointer(pBuf)).Fn
		}
	}
	goto synonym_poslist_out
synonym_poslist_out:
	;
	if aIter != bp {
		Xsqlite3_free(tls, aIter)
	}
	return rc
}

// 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(192)
	defer tls.Free(192)
	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+176 */ int32
	var _ /* iDelta at bp+168 */ Tu64
	var _ /* nDoclist at bp+160 */ int32
	var _ /* nPos at bp+180 */ int32
	var _ /* nTerm at bp+144 */ int32
	var _ /* pDoclist at bp+152 */ uintptr
	var _ /* pStruct at bp+0 */ uintptr
	var _ /* pgnoLast at bp+8 */ int32
	var _ /* writer at bp+16 */ TFts5SegWriter
	var _ /* zTerm at bp+136 */ 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 + 8)) = 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+16, iSegid)
			pBuf = bp + 16 + 8 + 8
			pPgidx = bp + 16 + 8 + 24
			/* 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+136, bp+144, bp+152, bp+160)
				if bSecureDelete == 0 {
					_fts5WriteAppendTerm(tls, p, bp+16, **(**int32)(__ccgo_up(bp + 144)), **(**uintptr)(__ccgo_up(bp + 136)))
					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 + 160))+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 + 152)), libc.Uint64FromInt32(**(**int32)(__ccgo_up(bp + 160))))
					**(**int32)(__ccgo_up(pBuf + 8)) += **(**int32)(__ccgo_up(bp + 160))
				} 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 + 160)) {
						**(**Tu64)(__ccgo_up(bp + 168)) = uint64(0)
						iOff = iOff + libc.Int32FromUint8(_sqlite3Fts5GetVarint(tls, **(**uintptr)(__ccgo_up(bp + 152))+uintptr(iOff), bp+168))
						iRowid = libc.Int64FromUint64(uint64(iRowid) + **(**Tu64)(__ccgo_up(bp + 168)))
						/* 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 + 160)) && libc.Int32FromUint8(**(**Tu8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp + 152)) + uintptr(iOff)))) == 0x00 && !(_fts5FlushSecureDelete(tls, p, **(**uintptr)(__ccgo_up(bp)), **(**uintptr)(__ccgo_up(bp + 136)), **(**int32)(__ccgo_up(bp + 144)), iRowid) != 0) {
									iOff = iOff + 1
									if iOff < **(**int32)(__ccgo_up(bp + 160)) && libc.Int32FromUint8(**(**Tu8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp + 152)) + uintptr(iOff)))) == 0x00 {
										iOff = iOff + 1
										**(**int32)(__ccgo_up(bp + 160)) = 0
									} else {
										continue
									}
								}
							} else {
								if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp + 152)) + uintptr(iOff))))&int32(0x01) != 0 && !(_fts5FlushSecureDelete(tls, p, **(**uintptr)(__ccgo_up(bp)), **(**uintptr)(__ccgo_up(bp + 136)), **(**int32)(__ccgo_up(bp + 144)), iRowid) != 0) {
									if (*TFts5Index)(unsafe.Pointer(p)).Frc != SQLITE_OK || libc.Int32FromUint8(**(**Tu8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp + 152)) + uintptr(iOff)))) == int32(0x01) {
										iOff = iOff + 1
										continue
									}
								}
							}
						}
						if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK && bTermWritten == 0 {
							_fts5WriteAppendTerm(tls, p, bp+16, **(**int32)(__ccgo_up(bp + 144)), **(**uintptr)(__ccgo_up(bp + 136)))
							bTermWritten = int32(1)
						}
						if (**(**TFts5SegWriter)(__ccgo_up(bp + 16))).FbFirstRowidInPage != 0 {
							_fts5PutU16(tls, (*TFts5Buffer)(unsafe.Pointer(pBuf)).Fp, libc.Uint16FromInt32((*TFts5Buffer)(unsafe.Pointer(pBuf)).Fn)) /* first rowid on page */
							**(**int32)(__ccgo_up(pBuf + 8)) += _sqlite3Fts5PutVarint(tls, (*TFts5Buffer)(unsafe.Pointer(pBuf)).Fp+uintptr((*TFts5Buffer)(unsafe.Pointer(pBuf)).Fn), libc.Uint64FromInt64(iRowid))
							(**(**TFts5SegWriter)(__ccgo_up(bp + 16))).FbFirstRowidInPage = uint8(0)
							_fts5WriteDlidxAppend(tls, p, bp+16, iRowid)
						} else {
							iRowidDelta = libc.Uint64FromInt64(iRowid) - libc.Uint64FromInt64(iPrev)
							**(**int32)(__ccgo_up(pBuf + 8)) += _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 + 160)) && libc.Int32FromUint8(**(**Tu8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp + 152)) + uintptr(iOff)))) == 0 {
								v2 = pBuf + 8
								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 + 160)) && libc.Int32FromUint8(**(**Tu8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp + 152)) + uintptr(iOff)))) == 0 {
									v2 = pBuf + 8
									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+16)
							}
						} else {
							**(**int32)(__ccgo_up(bp + 176)) = 0
							**(**int32)(__ccgo_up(bp + 180)) = 0
							nCopy = _fts5GetPoslistSize(tls, **(**uintptr)(__ccgo_up(bp + 152))+uintptr(iOff), bp+180, bp+176)
							if **(**int32)(__ccgo_up(bp + 176)) != 0 && bSecureDelete != 0 {
								_sqlite3Fts5BufferAppendVarint(tls, p+60, pBuf, int64(**(**int32)(__ccgo_up(bp + 180)))*int64(2))
								iOff = iOff + nCopy
								nCopy = **(**int32)(__ccgo_up(bp + 180))
							} else {
								nCopy = nCopy + **(**int32)(__ccgo_up(bp + 180))
							}
							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 + 152))+uintptr(iOff), libc.Uint64FromInt32(nCopy))
								**(**int32)(__ccgo_up(pBuf + 8)) += 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 + 152)) + 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.Uint64FromInt32(n))
									**(**int32)(__ccgo_up(pBuf + 8)) += n
									iPos = iPos + n
									if (*TFts5Buffer)(unsafe.Pointer(pBuf)).Fn+(*TFts5Buffer)(unsafe.Pointer(pPgidx)).Fn >= pgsz {
										_fts5WriteFlushLeaf(tls, p, bp+16)
									}
									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+16, bp+8)
			if **(**int32)(__ccgo_up(bp + 8)) > 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+60, bp)
				}
				_fts5StructureExtendLevel(tls, p+60, **(**uintptr)(__ccgo_up(bp)), 0, int32(1), 0)
				if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
					v2 = **(**uintptr)(__ccgo_up(bp)) + 32 + 4
					v1 = *(*int32)(unsafe.Pointer(v2))
					*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1
					pSeg = (*(*TFts5StructureLevel)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)) + 32))).FaSeg + uintptr(v1)*56
					(*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FiSegid = iSegid
					(*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FpgnoFirst = int32(1)
					(*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FpgnoLast = **(**int32)(__ccgo_up(bp + 8))
					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 + 8))+(*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+32, 0, uint64(184)-libc.Uint64FromInt64(int64(pCsr+32)-int64(pCsr)))
}

func _fts5HashAddPoslistSize(tls *libc.TLS, pHash uintptr, p uintptr, p2 uintptr) (r int32) {
	var nByte, nData, nPos, nRet, nSz, v2 int32
	var pPtr, v1 uintptr
	_, _, _, _, _, _, _, _ = nByte, nData, nPos, nRet, nSz, pPtr, v1, v2
	nRet = 0
	if (*TFts5HashEntry)(unsafe.Pointer(p)).FiSzPoslist != 0 {
		if p2 != 0 {
			v1 = p2
		} else {
			v1 = p
		}
		pPtr = v1
		nData = (*TFts5HashEntry)(unsafe.Pointer(p)).FnData
		if (*TFts5Hash)(unsafe.Pointer(pHash)).FeDetail == int32(FTS5_DETAIL_NONE) {
			if (*TFts5HashEntry)(unsafe.Pointer(p)).FbDel != 0 {
				v2 = nData
				nData = nData + 1
				**(**Tu8)(__ccgo_up(pPtr + uintptr(v2))) = uint8(0x00)
				if (*TFts5HashEntry)(unsafe.Pointer(p)).FbContent != 0 {
					v2 = nData
					nData = nData + 1
					**(**Tu8)(__ccgo_up(pPtr + uintptr(v2))) = uint8(0x00)
				}
			}
		} else {
			nSz = nData - (*TFts5HashEntry)(unsafe.Pointer(p)).FiSzPoslist - int32(1)             /* Size in bytes */
			nPos = nSz*int32(2) + libc.Int32FromUint8((*TFts5HashEntry)(unsafe.Pointer(p)).FbDel) /* Value of nPos field */
			if nPos <= int32(127) {
				**(**Tu8)(__ccgo_up(pPtr + uintptr((*TFts5HashEntry)(unsafe.Pointer(p)).FiSzPoslist))) = libc.Uint8FromInt32(nPos)
			} else {
				nByte = _sqlite3Fts5GetVarintLen(tls, libc.Uint32FromInt32(nPos))
				libc.Xmemmove(tls, pPtr+uintptr((*TFts5HashEntry)(unsafe.Pointer(p)).FiSzPoslist+nByte), pPtr+uintptr((*TFts5HashEntry)(unsafe.Pointer(p)).FiSzPoslist+int32(1)), libc.Uint64FromInt32(nSz))
				_sqlite3Fts5PutVarint(tls, pPtr+uintptr((*TFts5HashEntry)(unsafe.Pointer(p)).FiSzPoslist), libc.Uint64FromInt32(nPos))
				nData = nData + (nByte - int32(1))
			}
		}
		nRet = nData - (*TFts5HashEntry)(unsafe.Pointer(p)).FnData
		if p2 == uintptr(0) {
			(*TFts5HashEntry)(unsafe.Pointer(p)).FiSzPoslist = 0
			(*TFts5HashEntry)(unsafe.Pointer(p)).FbDel = uint8(0)
			(*TFts5HashEntry)(unsafe.Pointer(p)).FbContent = uint8(0)
			(*TFts5HashEntry)(unsafe.Pointer(p)).FnData = nData
		}
	}
	return nRet
}

// C documentation
//
//	/*
//	** Link all tokens from hash table iHash into a list in sorted order. The
//	** tokens are not removed from the hash table.
//	*/
func _fts5HashEntrySort(tls *libc.TLS, pHash uintptr, pTerm uintptr, nTerm int32, ppSorted uintptr) (r int32) {
	var ap, pEntry, pIter, pList uintptr
	var i, iSlot, nMergeSlot int32
	_, _, _, _, _, _, _ = ap, i, iSlot, nMergeSlot, pEntry, pIter, pList
	nMergeSlot = int32(32)
	**(**uintptr)(__ccgo_up(ppSorted)) = uintptr(0)
	ap = Xsqlite3_malloc64(tls, uint64(uint64(8)*libc.Uint64FromInt32(nMergeSlot)))
	if !(ap != 0) {
		return int32(SQLITE_NOMEM)
	}
	libc.Xmemset(tls, ap, 0, uint64(8)*libc.Uint64FromInt32(nMergeSlot))
	iSlot = 0
	for {
		if !(iSlot < (*TFts5Hash)(unsafe.Pointer(pHash)).FnSlot) {
			break
		}
		pIter = **(**uintptr)(__ccgo_up((*TFts5Hash)(unsafe.Pointer(pHash)).FaSlot + uintptr(iSlot)*8))
		for {
			if !(pIter != 0) {
				break
			}
			if pTerm == uintptr(0) || (*TFts5HashEntry)(unsafe.Pointer(pIter)).FnKey >= nTerm && 0 == libc.Xmemcmp(tls, pIter+1*48, pTerm, libc.Uint64FromInt32(nTerm)) {
				pEntry = pIter
				(*TFts5HashEntry)(unsafe.Pointer(pEntry)).FpScanNext = uintptr(0)
				i = 0
				for {
					if !(**(**uintptr)(__ccgo_up(ap + uintptr(i)*8)) != 0) {
						break
					}
					pEntry = _fts5HashEntryMerge(tls, pEntry, **(**uintptr)(__ccgo_up(ap + uintptr(i)*8)))
					**(**uintptr)(__ccgo_up(ap + uintptr(i)*8)) = uintptr(0)
					goto _3
				_3:
					;
					i = i + 1
				}
				**(**uintptr)(__ccgo_up(ap + uintptr(i)*8)) = pEntry
			}
			goto _2
		_2:
			;
			pIter = (*TFts5HashEntry)(unsafe.Pointer(pIter)).FpHashNext
		}
		goto _1
	_1:
		;
		iSlot = iSlot + 1
	}
	pList = uintptr(0)
	i = 0
	for {
		if !(i < nMergeSlot) {
			break
		}
		pList = _fts5HashEntryMerge(tls, pList, **(**uintptr)(__ccgo_up(ap + uintptr(i)*8)))
		goto _4
	_4:
		;
		i = i + 1
	}
	Xsqlite3_free(tls, ap)
	**(**uintptr)(__ccgo_up(ppSorted)) = pList
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** Resize the hash table by doubling the number of slots.
//	*/
func _fts5HashResize(tls *libc.TLS, pHash uintptr) (r int32) {
	var apNew, apOld, p uintptr
	var i, nNew int32
	var iHash uint32
	_, _, _, _, _, _ = apNew, apOld, i, iHash, nNew, p
	nNew = (*TFts5Hash)(unsafe.Pointer(pHash)).FnSlot * int32(2)
	apOld = (*TFts5Hash)(unsafe.Pointer(pHash)).FaSlot
	apNew = Xsqlite3_malloc64(tls, uint64(libc.Uint64FromInt32(nNew)*uint64(8)))
	if !(apNew != 0) {
		return int32(SQLITE_NOMEM)
	}
	libc.Xmemset(tls, apNew, 0, libc.Uint64FromInt32(nNew)*uint64(8))
	i = 0
	for {
		if !(i < (*TFts5Hash)(unsafe.Pointer(pHash)).FnSlot) {
			break
		}
		for **(**uintptr)(__ccgo_up(apOld + uintptr(i)*8)) != 0 {
			p = **(**uintptr)(__ccgo_up(apOld + uintptr(i)*8))
			**(**uintptr)(__ccgo_up(apOld + uintptr(i)*8)) = (*TFts5HashEntry)(unsafe.Pointer(p)).FpHashNext
			iHash = _fts5HashKey(tls, nNew, p+1*48, (*TFts5HashEntry)(unsafe.Pointer(p)).FnKey)
			(*TFts5HashEntry)(unsafe.Pointer(p)).FpHashNext = **(**uintptr)(__ccgo_up(apNew + uintptr(iHash)*8))
			**(**uintptr)(__ccgo_up(apNew + uintptr(iHash)*8)) = p
		}
		goto _1
	_1:
		;
		i = i + 1
	}
	Xsqlite3_free(tls, apOld)
	(*TFts5Hash)(unsafe.Pointer(pHash)).FnSlot = nNew
	(*TFts5Hash)(unsafe.Pointer(pHash)).FaSlot = apNew
	return SQLITE_OK
}

// 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+40, 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(int64(p) - int64(aCopy))
					return
				}
				libc.Xmemcpy(tls, (*TFts5Buffer)(unsafe.Pointer(pIter+40)).Fp+uintptr((*TFts5Buffer)(unsafe.Pointer(pIter+40)).Fn), aCopy, libc.Uint64FromInt64(int64(p)-int64(aCopy)))
				v1 = pIter + 40 + 8
				*(*int32)(unsafe.Pointer(v1)) = int32(int64(*(*int32)(unsafe.Pointer(v1))) + (int64(p) - int64(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
//
//	/*
//	**
//	*/
func _fts5IndexMergeLevel(tls *libc.TLS, p uintptr, ppStruct uintptr, iLvl int32, pnRem uintptr) {
	bp := tls.Alloc(160)
	defer tls.Free(160)
	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+144 */ int32
	var _ /* pIter at bp+0 */ uintptr
	var _ /* term at bp+128 */ TFts5Buffer
	var _ /* writer at bp+8 */ 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 + 32 + uintptr(iLvl)*16
	**(**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+8, 0, uint64(120))
	libc.Xmemset(tls, bp+128, 0, uint64(16))
	if (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnMerge != 0 {
		pLvlOut = pStruct + 32 + uintptr(iLvl+int32(1))*16
		nInput = (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnMerge
		pSeg = (*TFts5StructureLevel)(unsafe.Pointer(pLvlOut)).FaSeg + uintptr((*TFts5StructureLevel)(unsafe.Pointer(pLvlOut)).FnSeg-int32(1))*56
		_fts5WriteInit(tls, p, bp+8, (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FiSegid)
		(**(**TFts5SegWriter)(__ccgo_up(bp + 8))).Fwriter.Fpgno = (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FpgnoLast + int32(1)
		(**(**TFts5SegWriter)(__ccgo_up(bp + 8))).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+60, ppStruct)
			pStruct = **(**uintptr)(__ccgo_up(ppStruct))
		}
		_fts5StructureExtendLevel(tls, p+60, pStruct, iLvl+int32(1), int32(1), 0)
		if (*TFts5Index)(unsafe.Pointer(p)).Frc != 0 {
			return
		}
		pLvl = pStruct + 32 + uintptr(iLvl)*16
		pLvlOut = pStruct + 32 + uintptr(iLvl+int32(1))*16
		_fts5WriteInit(tls, p, bp+8, iSegid)
		/* Add the new segment to the output level */
		pSeg = (*TFts5StructureLevel)(unsafe.Pointer(pLvlOut)).FaSeg + uintptr((*TFts5StructureLevel)(unsafe.Pointer(pLvlOut)).FnSeg)*56
		(*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))*56))).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)) + 104 + uintptr((**(**TFts5CResult)(__ccgo_up((*TFts5Iter)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FaFirst + 1*4))).FiFirst)*128
		pTerm = _fts5MultiIterTerm(tls, **(**uintptr)(__ccgo_up(bp)), bp+144)
		if v4 = **(**int32)(__ccgo_up(bp + 144)) != (**(**TFts5Buffer)(__ccgo_up(bp + 128))).Fn; !v4 {
			if **(**int32)(__ccgo_up(bp + 144)) <= 0 {
				v1 = 0
			} else {
				v1 = libc.Xmemcmp(tls, pTerm, (**(**TFts5Buffer)(__ccgo_up(bp + 128))).Fp, libc.Uint64FromInt32(**(**int32)(__ccgo_up(bp + 144))))
			}
		}
		if v4 || v1 != 0 {
			if pnRem != 0 && (**(**TFts5SegWriter)(__ccgo_up(bp + 8))).FnLeafWritten > nRem {
				break
			}
			_sqlite3Fts5BufferSet(tls, p+60, bp+128, **(**int32)(__ccgo_up(bp + 144)), 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+8, **(**int32)(__ccgo_up(bp + 144)), pTerm)
			bTermWritten = int32(1)
		}
		/* Append the rowid to the output */
		/* WRITEPOSLISTSIZE */
		_fts5WriteAppendRowid(tls, p, bp+8, _fts5MultiIterRowid(tls, **(**uintptr)(__ccgo_up(bp))))
		if eDetail == int32(FTS5_DETAIL_NONE) {
			if (*TFts5SegIter)(unsafe.Pointer(pSegIter)).FbDel != 0 {
				_sqlite3Fts5BufferAppendVarint(tls, p+60, bp+8+8+8, libc.Int64FromInt32(0))
				if (*TFts5SegIter)(unsafe.Pointer(pSegIter)).FnPos > 0 {
					_sqlite3Fts5BufferAppendVarint(tls, p+60, bp+8+8+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+60, bp+8+8+8, int64(nPos))
			_fts5ChunkIterate(tls, p, pSegIter, bp+8, __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+8, 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)*56
			**(**Tu64)(__ccgo_up(pSeg + 48)) += (*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.Int32FromUint64(libc.Uint64FromInt32((*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnSeg-nInput) * uint64(56))
			libc.Xmemmove(tls, (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FaSeg, (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FaSeg+uintptr(nInput)*56, libc.Uint64FromInt32(nMove))
		}
		**(**int32)(__ccgo_up(pStruct + 24)) -= 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+128)
	if pnRem != 0 {
		**(**int32)(__ccgo_up(pnRem)) -= (**(**TFts5SegWriter)(__ccgo_up(bp + 8))).FnLeafWritten
	}
}

// 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(1072)
	defer tls.Free(1072)
	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+1064 */ Ti64
	var _ /* out at bp+1032 */ TFts5Buffer
	var _ /* pHead at bp+1024 */ uintptr
	var _ /* tmp at bp+1048 */ TFts5Buffer
	_, _, _, _, _, _, _, _, _, _, _, _ = i, iLastRowid, nMerge, nOut, nTail, nTmp, pI, pNext, pSave, pThis, pThis1, pX
	**(**uintptr)(__ccgo_up(bp + 1024)) = uintptr(0)
	nOut = 0
	**(**TFts5Buffer)(__ccgo_up(bp + 1032)) = TFts5Buffer{}
	**(**TFts5Buffer)(__ccgo_up(bp + 1048)) = 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, uint64(64)*libc.Uint64FromInt32(nBuf+libc.Int32FromInt32(1)))
	**(**uintptr)(__ccgo_up(bp + 1024)) = bp + uintptr(nBuf)*64
	_fts5DoclistIterInit(tls, p1, **(**uintptr)(__ccgo_up(bp + 1024)))
	i = 0
	for {
		if !(i < nBuf) {
			break
		}
		_fts5DoclistIterInit(tls, aBuf+uintptr(i)*16, bp+uintptr(i)*64)
		_fts5PrefixMergerInsertByRowid(tls, bp+1024, bp+uintptr(i)*64)
		nOut = nOut + (**(**TFts5Buffer)(__ccgo_up(aBuf + uintptr(i)*16))).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+60, bp+1032, libc.Uint32FromInt32(nOut)) != 0 {
		return
	}
	for **(**uintptr)(__ccgo_up(bp + 1024)) != 0 {
		**(**int32)(__ccgo_up(bp + 1032 + 8)) += _sqlite3Fts5PutVarint(tls, (*TFts5Buffer)(unsafe.Pointer(bp+1032)).Fp+uintptr((*TFts5Buffer)(unsafe.Pointer(bp+1032)).Fn), libc.Uint64FromInt64((*TPrefixMerger)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 1024)))).Fiter.FiRowid)-libc.Uint64FromInt64(iLastRowid))
		iLastRowid = (*TPrefixMerger)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 1024)))).Fiter.FiRowid
		if (*TPrefixMerger)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 1024)))).FpNext != 0 && iLastRowid == (*TPrefixMerger)(unsafe.Pointer((*TPrefixMerger)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 1024)))).FpNext)).Fiter.FiRowid {
			/* Merge data from two or more poslists */
			**(**Ti64)(__ccgo_up(bp + 1064)) = 0
			nTmp = int32(FTS5_DATA_ZERO_PADDING)
			nMerge = 0
			pSave = **(**uintptr)(__ccgo_up(bp + 1024))
			pThis = uintptr(0)
			nTail = 0
			**(**uintptr)(__ccgo_up(bp + 1024)) = 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+40, pSave+32)
				nTmp = nTmp + ((*TPrefixMerger)(unsafe.Pointer(pSave)).Fiter.FnPoslist + int32(10))
				nMerge = nMerge + 1
				_fts5PrefixMergerInsertByPosition(tls, bp+1024, pSave)
				pSave = pNext
			}
			if **(**uintptr)(__ccgo_up(bp + 1024)) == uintptr(0) || (*TPrefixMerger)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 1024)))).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+60, bp+1048, libc.Uint32FromInt32(nTmp+nMerge*int32(10))) != 0 {
				break
			}
			_sqlite3Fts5BufferZero(tls, bp+1048)
			pThis = **(**uintptr)(__ccgo_up(bp + 1024))
			**(**uintptr)(__ccgo_up(bp + 1024)) = (*TPrefixMerger)(unsafe.Pointer(pThis)).FpNext
			_sqlite3Fts5PoslistSafeAppend(tls, bp+1048, bp+1064, (*TPrefixMerger)(unsafe.Pointer(pThis)).FiPos)
			_sqlite3Fts5PoslistNext64(tls, (*TPrefixMerger)(unsafe.Pointer(pThis)).FaPos, (*TPrefixMerger)(unsafe.Pointer(pThis)).Fiter.FnPoslist, pThis+40, pThis+32)
			_fts5PrefixMergerInsertByPosition(tls, bp+1024, pThis)
			for (*TPrefixMerger)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 1024)))).FpNext != 0 {
				pThis = **(**uintptr)(__ccgo_up(bp + 1024))
				if (*TPrefixMerger)(unsafe.Pointer(pThis)).FiPos != **(**Ti64)(__ccgo_up(bp + 1064)) {
					_sqlite3Fts5PoslistSafeAppend(tls, bp+1048, bp+1064, (*TPrefixMerger)(unsafe.Pointer(pThis)).FiPos)
				}
				_sqlite3Fts5PoslistNext64(tls, (*TPrefixMerger)(unsafe.Pointer(pThis)).FaPos, (*TPrefixMerger)(unsafe.Pointer(pThis)).Fiter.FnPoslist, pThis+40, pThis+32)
				**(**uintptr)(__ccgo_up(bp + 1024)) = (*TPrefixMerger)(unsafe.Pointer(pThis)).FpNext
				_fts5PrefixMergerInsertByPosition(tls, bp+1024, pThis)
			}
			if (*TPrefixMerger)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 1024)))).FiPos != **(**Ti64)(__ccgo_up(bp + 1064)) {
				_sqlite3Fts5PoslistSafeAppend(tls, bp+1048, bp+1064, (*TPrefixMerger)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 1024)))).FiPos)
			}
			nTail = (*TPrefixMerger)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 1024)))).Fiter.FnPoslist - (*TPrefixMerger)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 1024)))).FiOff
			/* WRITEPOSLISTSIZE */
			if (**(**TFts5Buffer)(__ccgo_up(bp + 1048))).Fn+nTail > nTmp-int32(FTS5_DATA_ZERO_PADDING) {
				if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
					_fts5IndexCorruptIdx(tls, p)
				}
				break
			}
			**(**int32)(__ccgo_up(bp + 1032 + 8)) += _sqlite3Fts5PutVarint(tls, (*TFts5Buffer)(unsafe.Pointer(bp+1032)).Fp+uintptr((*TFts5Buffer)(unsafe.Pointer(bp+1032)).Fn), libc.Uint64FromInt32(((**(**TFts5Buffer)(__ccgo_up(bp + 1048))).Fn+nTail)*libc.Int32FromInt32(2)))
			libc.Xmemcpy(tls, (*TFts5Buffer)(unsafe.Pointer(bp+1032)).Fp+uintptr((*TFts5Buffer)(unsafe.Pointer(bp+1032)).Fn), (**(**TFts5Buffer)(__ccgo_up(bp + 1048))).Fp, libc.Uint64FromInt32((**(**TFts5Buffer)(__ccgo_up(bp + 1048))).Fn))
			**(**int32)(__ccgo_up(bp + 1032 + 8)) += (**(**TFts5Buffer)(__ccgo_up(bp + 1048))).Fn
			if nTail > 0 {
				libc.Xmemcpy(tls, (*TFts5Buffer)(unsafe.Pointer(bp+1032)).Fp+uintptr((*TFts5Buffer)(unsafe.Pointer(bp+1032)).Fn), (*TPrefixMerger)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 1024)))).FaPos+uintptr((*TPrefixMerger)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 1024)))).FiOff), libc.Uint64FromInt32(nTail))
				**(**int32)(__ccgo_up(bp + 1032 + 8)) += nTail
			}
			**(**uintptr)(__ccgo_up(bp + 1024)) = pSave
			i = 0
			for {
				if !(i < nBuf+int32(1)) {
					break
				}
				pX = bp + uintptr(i)*64
				if (*TPrefixMerger)(unsafe.Pointer(pX)).Fiter.FaPoslist != 0 && (*TPrefixMerger)(unsafe.Pointer(pX)).Fiter.FiRowid == iLastRowid {
					_fts5DoclistIterNext(tls, pX)
					_fts5PrefixMergerInsertByRowid(tls, bp+1024, pX)
				}
				goto _2
			_2:
				;
				i = i + 1
			}
		} else {
			/* Copy poslist from pHead to output */
			pThis1 = **(**uintptr)(__ccgo_up(bp + 1024))
			pI = pThis1
			libc.Xmemcpy(tls, (*TFts5Buffer)(unsafe.Pointer(bp+1032)).Fp+uintptr((*TFts5Buffer)(unsafe.Pointer(bp+1032)).Fn), (*TFts5DoclistIter)(unsafe.Pointer(pI)).FaPoslist, libc.Uint64FromInt32((*TFts5DoclistIter)(unsafe.Pointer(pI)).FnPoslist+(*TFts5DoclistIter)(unsafe.Pointer(pI)).FnSize))
			**(**int32)(__ccgo_up(bp + 1032 + 8)) += (*TFts5DoclistIter)(unsafe.Pointer(pI)).FnPoslist + (*TFts5DoclistIter)(unsafe.Pointer(pI)).FnSize
			_fts5DoclistIterNext(tls, pI)
			**(**uintptr)(__ccgo_up(bp + 1024)) = (*TPrefixMerger)(unsafe.Pointer(pThis1)).FpNext
			_fts5PrefixMergerInsertByRowid(tls, bp+1024, pThis1)
		}
	}
	_sqlite3Fts5BufferFree(tls, p1)
	_sqlite3Fts5BufferFree(tls, bp+1048)
	libc.Xmemset(tls, (**(**TFts5Buffer)(__ccgo_up(bp + 1032))).Fp+uintptr((**(**TFts5Buffer)(__ccgo_up(bp + 1032))).Fn), 0, uint64(FTS5_DATA_ZERO_PADDING))
	**(**TFts5Buffer)(__ccgo_up(p1)) = **(**TFts5Buffer)(__ccgo_up(bp + 1032))
}

// 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, uint64(16))
	_sqlite3Fts5BufferSize(tls, p+60, 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 + 8)) += _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 + 8)) += _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
//
//	/*
//	** This function is used by xCreateTokenizer_v2() and xCreateTokenizer().
//	** It allocates and partially populates a new Fts5TokenizerModule object.
//	** The new object is already linked into the Fts5Global context before
//	** returning.
//	**
//	** If successful, SQLITE_OK is returned and a pointer to the new
//	** Fts5TokenizerModule object returned via output parameter (*ppNew). All
//	** that is required is for the caller to fill in the methods in
//	** Fts5TokenizerModule.x1 and x2, and to set Fts5TokenizerModule.bV2Native
//	** as appropriate.
//	**
//	** If an error occurs, an SQLite error code is returned and the final value
//	** of (*ppNew) undefined.
//	*/
func _fts5NewTokenizerModule(tls *libc.TLS, pGlobal uintptr, zName uintptr, pUserData uintptr, __ccgo_fp_xDestroy uintptr, ppNew uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var nByte, nName Tsqlite3_int64
	var pNew, v1 uintptr
	var _ /* rc at bp+0 */ int32
	_, _, _, _ = nByte, nName, pNew, v1
	**(**int32)(__ccgo_up(bp)) = SQLITE_OK /* Bytes of space to allocate */
	nName = libc.Int64FromUint64(libc.Xstrlen(tls, zName) + uint64(1))
	nByte = libc.Int64FromUint64(uint64(96) + libc.Uint64FromInt64(nName))
	v1 = _sqlite3Fts5MallocZero(tls, bp, nByte)
	pNew = v1
	**(**uintptr)(__ccgo_up(ppNew)) = v1
	if pNew != 0 {
		(*TFts5TokenizerModule)(unsafe.Pointer(pNew)).FzName = pNew + 1*96
		libc.Xmemcpy(tls, (*TFts5TokenizerModule)(unsafe.Pointer(pNew)).FzName, zName, libc.Uint64FromInt64(nName))
		(*TFts5TokenizerModule)(unsafe.Pointer(pNew)).FpUserData = pUserData
		(*TFts5TokenizerModule)(unsafe.Pointer(pNew)).FxDestroy = __ccgo_fp_xDestroy
		(*TFts5TokenizerModule)(unsafe.Pointer(pNew)).FpNext = (*TFts5Global)(unsafe.Pointer(pGlobal)).FpTok
		(*TFts5Global)(unsafe.Pointer(pGlobal)).FpTok = pNew
		if (*TFts5TokenizerModule)(unsafe.Pointer(pNew)).FpNext == uintptr(0) {
			(*TFts5Global)(unsafe.Pointer(pGlobal)).FpDfltTok = pNew
		}
	}
	return **(**int32)(__ccgo_up(bp))
}

// 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.Int64FromUint64(uint64(184) + libc.Uint64FromInt32((*TFts5Config)(unsafe.Pointer(pConfig)).FnCol)*uint64(4))
		pCsr = Xsqlite3_malloc64(tls, libc.Uint64FromInt64(nByte))
		if pCsr != 0 {
			pGlobal = (*TFts5FullTable)(unsafe.Pointer(pTab)).FpGlobal
			libc.Xmemset(tls, pCsr, 0, libc.Uint64FromInt64(nByte))
			(*TFts5Cursor)(unsafe.Pointer(pCsr)).FaColumnSize = pCsr + 1*184
			(*TFts5Cursor)(unsafe.Pointer(pCsr)).FpNext = (*TFts5Global)(unsafe.Pointer(pGlobal)).FpCsr
			(*TFts5Global)(unsafe.Pointer(pGlobal)).FpCsr = pCsr
			v2 = pGlobal + 56
			*(*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
//
//	/*
//	** Callback for tokenizing terms used by ParseTerm().
//	*/
func _fts5ParseTokenize(tls *libc.TLS, pContext uintptr, tflags int32, pToken uintptr, nToken int32, iUnused1 int32, iUnused2 int32) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var SZALLOC, nNew, v1 int32
	var nByte Tsqlite3_int64
	var pCtx, pNew, pPhrase, pSyn, pTerm, v3 uintptr
	var _ /* rc at bp+0 */ int32
	_, _, _, _, _, _, _, _, _, _ = SZALLOC, nByte, nNew, pCtx, pNew, pPhrase, pSyn, pTerm, v1, v3
	**(**int32)(__ccgo_up(bp)) = SQLITE_OK
	SZALLOC = int32(8)
	pCtx = pContext
	pPhrase = (*TTokenCtx)(unsafe.Pointer(pCtx)).FpPhrase
	_ = iUnused1
	_ = iUnused2
	/* If an error has already occurred, this is a no-op */
	if (*TTokenCtx)(unsafe.Pointer(pCtx)).Frc != SQLITE_OK {
		return (*TTokenCtx)(unsafe.Pointer(pCtx)).Frc
	}
	if nToken > int32(FTS5_MAX_TOKEN_SIZE) {
		nToken = int32(FTS5_MAX_TOKEN_SIZE)
	}
	if pPhrase != 0 && (*TFts5ExprPhrase)(unsafe.Pointer(pPhrase)).FnTerm > 0 && tflags&int32(FTS5_TOKEN_COLOCATED) != 0 {
		nByte = libc.Int64FromUint64(libc.Uint64FromInt64(40) + libc.Uint64FromInt64(16) + libc.Uint64FromInt32(nToken) + uint64(1))
		pSyn = Xsqlite3_malloc64(tls, libc.Uint64FromInt64(nByte))
		if pSyn == uintptr(0) {
			**(**int32)(__ccgo_up(bp)) = int32(SQLITE_NOMEM)
		} else {
			libc.Xmemset(tls, pSyn, 0, libc.Uint64FromInt64(nByte))
			(*TFts5ExprTerm)(unsafe.Pointer(pSyn)).FpTerm = pSyn + uintptr(40) + uintptr(16)
			v1 = nToken
			(*TFts5ExprTerm)(unsafe.Pointer(pSyn)).FnQueryTerm = v1
			(*TFts5ExprTerm)(unsafe.Pointer(pSyn)).FnFullTerm = v1
			if (*TFts5Config)(unsafe.Pointer((*TTokenCtx)(unsafe.Pointer(pCtx)).FpConfig)).FbTokendata != 0 {
				(*TFts5ExprTerm)(unsafe.Pointer(pSyn)).FnQueryTerm = libc.Int32FromUint64(libc.Xstrlen(tls, (*TFts5ExprTerm)(unsafe.Pointer(pSyn)).FpTerm))
			}
			libc.Xmemcpy(tls, (*TFts5ExprTerm)(unsafe.Pointer(pSyn)).FpTerm, pToken, libc.Uint64FromInt32(nToken))
			(*TFts5ExprTerm)(unsafe.Pointer(pSyn)).FpSynonym = (*(*TFts5ExprTerm)(unsafe.Pointer(pPhrase + 32 + uintptr((*TFts5ExprPhrase)(unsafe.Pointer(pPhrase)).FnTerm-int32(1))*40))).FpSynonym
			(*(*TFts5ExprTerm)(unsafe.Pointer(pPhrase + 32 + uintptr((*TFts5ExprPhrase)(unsafe.Pointer(pPhrase)).FnTerm-int32(1))*40))).FpSynonym = pSyn
		}
	} else {
		if pPhrase == uintptr(0) || (*TFts5ExprPhrase)(unsafe.Pointer(pPhrase)).FnTerm%SZALLOC == 0 {
			if pPhrase != 0 {
				v1 = (*TFts5ExprPhrase)(unsafe.Pointer(pPhrase)).FnTerm
			} else {
				v1 = 0
			}
			nNew = SZALLOC + v1
			pNew = Xsqlite3_realloc64(tls, pPhrase, uint64(uint64(libc.UintptrFromInt32(0)+32)+libc.Uint64FromInt32(nNew+libc.Int32FromInt32(1))*libc.Uint64FromInt64(40)))
			if pNew == uintptr(0) {
				**(**int32)(__ccgo_up(bp)) = int32(SQLITE_NOMEM)
			} else {
				if pPhrase == uintptr(0) {
					libc.Xmemset(tls, pNew, 0, uint64(libc.UintptrFromInt32(0)+32)+libc.Uint64FromInt32(libc.Int32FromInt32(1))*libc.Uint64FromInt64(40))
				}
				v3 = pNew
				pPhrase = v3
				(*TTokenCtx)(unsafe.Pointer(pCtx)).FpPhrase = v3
				(*TFts5ExprPhrase)(unsafe.Pointer(pNew)).FnTerm = nNew - SZALLOC
			}
		}
		if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
			v3 = pPhrase + 24
			v1 = *(*int32)(unsafe.Pointer(v3))
			*(*int32)(unsafe.Pointer(v3)) = *(*int32)(unsafe.Pointer(v3)) + 1
			pTerm = pPhrase + 32 + uintptr(v1)*40
			libc.Xmemset(tls, pTerm, 0, uint64(40))
			(*TFts5ExprTerm)(unsafe.Pointer(pTerm)).FpTerm = _sqlite3Fts5Strndup(tls, bp, pToken, nToken)
			v1 = nToken
			(*TFts5ExprTerm)(unsafe.Pointer(pTerm)).FnQueryTerm = v1
			(*TFts5ExprTerm)(unsafe.Pointer(pTerm)).FnFullTerm = v1
			if (*TFts5Config)(unsafe.Pointer((*TTokenCtx)(unsafe.Pointer(pCtx)).FpConfig)).FbTokendata != 0 && **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
				(*TFts5ExprTerm)(unsafe.Pointer(pTerm)).FnQueryTerm = libc.Int32FromUint64(libc.Xstrlen(tls, (*TFts5ExprTerm)(unsafe.Pointer(pTerm)).FpTerm))
			}
		}
	}
	(*TTokenCtx)(unsafe.Pointer(pCtx)).Frc = **(**int32)(__ccgo_up(bp))
	return **(**int32)(__ccgo_up(bp))
}

// C documentation
//
//	/*
//	** Return a "position-list blob" corresponding to the current position of
//	** cursor pCsr via sqlite3_result_blob(). A position-list blob contains
//	** the current position-list for each phrase in the query associated with
//	** cursor pCsr.
//	**
//	** A position-list blob begins with (nPhrase-1) varints, where nPhrase is
//	** the number of phrases in the query. Following the varints are the
//	** concatenated position lists for each phrase, in order.
//	**
//	** The first varint (if it exists) contains the size of the position list
//	** for phrase 0. The second (same disclaimer) contains the size of position
//	** list 1. And so on. There is no size field for the final position list,
//	** as it can be derived from the total size of the blob.
//	*/
func _fts5PoslistBlob(tls *libc.TLS, pCtx uintptr, pCsr uintptr) (r int32) {
	bp := tls.Alloc(80)
	defer tls.Free(80)
	var i, nByte, nPhrase, nPoslist int32
	var _ /* dummy at bp+24 */ uintptr
	var _ /* dummy at bp+40 */ uintptr
	var _ /* nByte at bp+48 */ int32
	var _ /* nPoslist at bp+64 */ int32
	var _ /* pPoslist at bp+32 */ uintptr
	var _ /* pPoslist at bp+56 */ uintptr
	var _ /* rc at bp+0 */ int32
	var _ /* val at bp+8 */ TFts5Buffer
	_, _, _, _ = i, nByte, nPhrase, nPoslist
	**(**int32)(__ccgo_up(bp)) = SQLITE_OK
	nPhrase = _sqlite3Fts5ExprPhraseCount(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpExpr)
	libc.Xmemset(tls, bp+8, 0, uint64(16))
	switch (*TFts5Config)(unsafe.Pointer((*TFts5Table)(unsafe.Pointer((*TFts5Cursor)(unsafe.Pointer(pCsr)).Fbase.FpVtab)).FpConfig)).FeDetail {
	case FTS5_DETAIL_FULL:
		goto _1
	case int32(FTS5_DETAIL_COLUMNS):
		goto _2
	default:
		goto _3
	}
	goto _4
_1:
	;
	/* Append the varints */
	i = 0
_7:
	;
	if !(i < nPhrase-int32(1)) {
		goto _5
	}
	nByte = _sqlite3Fts5ExprPoslist(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpExpr, i, bp+24)
	_sqlite3Fts5BufferAppendVarint(tls, bp, bp+8, int64(nByte))
	goto _6
_6:
	;
	i = i + 1
	goto _7
	goto _5
_5:
	;
	/* Append the position lists */
	i = 0
	for {
		if !(i < nPhrase) {
			break
		}
		nPoslist = _sqlite3Fts5ExprPoslist(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpExpr, i, bp+32)
		_sqlite3Fts5BufferAppendBlob(tls, bp, bp+8, libc.Uint32FromInt32(nPoslist), **(**uintptr)(__ccgo_up(bp + 32)))
		goto _8
	_8:
		;
		i = i + 1
	}
	goto _4
_2:
	;
	/* Append the varints */
	i = 0
	for {
		if !(**(**int32)(__ccgo_up(bp)) == SQLITE_OK && i < nPhrase-int32(1)) {
			break
		}
		**(**int32)(__ccgo_up(bp)) = _sqlite3Fts5ExprPhraseCollist(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpExpr, i, bp+40, bp+48)
		_sqlite3Fts5BufferAppendVarint(tls, bp, bp+8, int64(**(**int32)(__ccgo_up(bp + 48))))
		goto _9
	_9:
		;
		i = i + 1
	}
	/* Append the position lists */
	i = 0
	for {
		if !(**(**int32)(__ccgo_up(bp)) == SQLITE_OK && i < nPhrase) {
			break
		}
		**(**int32)(__ccgo_up(bp)) = _sqlite3Fts5ExprPhraseCollist(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpExpr, i, bp+56, bp+64)
		_sqlite3Fts5BufferAppendBlob(tls, bp, bp+8, libc.Uint32FromInt32(**(**int32)(__ccgo_up(bp + 64))), **(**uintptr)(__ccgo_up(bp + 56)))
		goto _10
	_10:
		;
		i = i + 1
	}
	goto _4
_3:
	;
	goto _4
_4:
	;
	Xsqlite3_result_blob(tls, pCtx, (**(**TFts5Buffer)(__ccgo_up(bp + 8))).Fp, (**(**TFts5Buffer)(__ccgo_up(bp + 8))).Fn, __ccgo_fp(Xsqlite3_free))
	return **(**int32)(__ccgo_up(bp))
}

func _fts5PoslistCallback(tls *libc.TLS, pUnused uintptr, pContext uintptr, pChunk uintptr, nChunk int32) {
	_ = pUnused
	if nChunk > 0 {
		libc.Xmemcpy(tls, (*TFts5Buffer)(unsafe.Pointer(pContext)).Fp+uintptr((*TFts5Buffer)(unsafe.Pointer(pContext)).Fn), pChunk, libc.Uint64FromInt32(nChunk))
		**(**int32)(__ccgo_up(pContext + 8)) += nChunk
	}
}

func _fts5PoslistFilterCallback(tls *libc.TLS, pUnused uintptr, pContext uintptr, pChunk uintptr, nChunk int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var i, iEnd, iStart, v1 int32
	var pCtx uintptr
	var _ /* iCol at bp+0 */ int32
	var _ /* iCol at bp+4 */ int32
	_, _, _, _, _ = i, iEnd, iStart, pCtx, v1
	pCtx = pContext
	_ = pUnused
	if nChunk > 0 {
		/* Search through to find the first varint with value 1. This is the
		 ** start of the next columns hits. */
		i = 0
		iStart = 0
		if (*TPoslistCallbackCtx)(unsafe.Pointer(pCtx)).FeState == int32(2) {
			v1 = i
			i = i + 1
			**(**int32)(__ccgo_up(bp)) = libc.Int32FromUint8(**(**Tu8)(__ccgo_up(pChunk + uintptr(v1))))
			if **(**int32)(__ccgo_up(bp))&int32(0x80) != 0 {
				i = i - 1
				i = i + _sqlite3Fts5GetVarint32(tls, pChunk+uintptr(i), bp)
			}
			if _fts5IndexColsetTest(tls, (*TPoslistCallbackCtx)(unsafe.Pointer(pCtx)).FpColset, **(**int32)(__ccgo_up(bp))) != 0 {
				(*TPoslistCallbackCtx)(unsafe.Pointer(pCtx)).FeState = int32(1)
				**(**int32)(__ccgo_up((*TPoslistCallbackCtx)(unsafe.Pointer(pCtx)).FpBuf + 8)) += _sqlite3Fts5PutVarint(tls, (*TFts5Buffer)(unsafe.Pointer((*TPoslistCallbackCtx)(unsafe.Pointer(pCtx)).FpBuf)).Fp+uintptr((*TFts5Buffer)(unsafe.Pointer((*TPoslistCallbackCtx)(unsafe.Pointer(pCtx)).FpBuf)).Fn), libc.Uint64FromInt32(libc.Int32FromInt32(1)))
			} else {
				(*TPoslistCallbackCtx)(unsafe.Pointer(pCtx)).FeState = 0
			}
		}
		for cond := true; cond; cond = i < nChunk {
			for i < nChunk && libc.Int32FromUint8(**(**Tu8)(__ccgo_up(pChunk + uintptr(i)))) != int32(0x01) {
				iEnd = i + int32(9)
				for {
					v1 = i
					i = i + 1
					if !(libc.Int32FromUint8(**(**Tu8)(__ccgo_up(pChunk + uintptr(v1))))&int32(0x80) != 0 && i < iEnd) {
						break
					}
				}
			}
			if (*TPoslistCallbackCtx)(unsafe.Pointer(pCtx)).FeState != 0 {
				libc.Xmemcpy(tls, (*TFts5Buffer)(unsafe.Pointer((*TPoslistCallbackCtx)(unsafe.Pointer(pCtx)).FpBuf)).Fp+uintptr((*TFts5Buffer)(unsafe.Pointer((*TPoslistCallbackCtx)(unsafe.Pointer(pCtx)).FpBuf)).Fn), pChunk+uintptr(iStart), libc.Uint64FromInt32(i-iStart))
				**(**int32)(__ccgo_up((*TPoslistCallbackCtx)(unsafe.Pointer(pCtx)).FpBuf + 8)) += i - iStart
			}
			if i < nChunk {
				iStart = i
				i = i + 1
				if i >= nChunk {
					(*TPoslistCallbackCtx)(unsafe.Pointer(pCtx)).FeState = int32(2)
				} else {
					v1 = i
					i = i + 1
					**(**int32)(__ccgo_up(bp + 4)) = libc.Int32FromUint8(**(**Tu8)(__ccgo_up(pChunk + uintptr(v1))))
					if **(**int32)(__ccgo_up(bp + 4))&int32(0x80) != 0 {
						i = i - 1
						i = i + _sqlite3Fts5GetVarint32(tls, pChunk+uintptr(i), bp+4)
					}
					(*TPoslistCallbackCtx)(unsafe.Pointer(pCtx)).FeState = _fts5IndexColsetTest(tls, (*TPoslistCallbackCtx)(unsafe.Pointer(pCtx)).FpColset, **(**int32)(__ccgo_up(bp + 4)))
					if (*TPoslistCallbackCtx)(unsafe.Pointer(pCtx)).FeState != 0 {
						libc.Xmemcpy(tls, (*TFts5Buffer)(unsafe.Pointer((*TPoslistCallbackCtx)(unsafe.Pointer(pCtx)).FpBuf)).Fp+uintptr((*TFts5Buffer)(unsafe.Pointer((*TPoslistCallbackCtx)(unsafe.Pointer(pCtx)).FpBuf)).Fn), pChunk+uintptr(iStart), libc.Uint64FromInt32(i-iStart))
						**(**int32)(__ccgo_up((*TPoslistCallbackCtx)(unsafe.Pointer(pCtx)).FpBuf + 8)) += i - iStart
						iStart = i
					}
				}
			}
		}
	}
}

// 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+60, 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.Uint64FromInt32((*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.Uint64FromInt32(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.Uint64FromInt32(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
//
//	/*
//	** 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(48)
	defer tls.Free(48)
	var v1 int32
	var _ /* sCtx at bp+0 */ TPoslistCallbackCtx
	var _ /* sCtx at bp+24 */ 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+60, 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, uint64(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+24, 0, uint64(24))
				(**(**TPoslistOffsetsCtx)(__ccgo_up(bp + 24))).FpBuf = pBuf
				(**(**TPoslistOffsetsCtx)(__ccgo_up(bp + 24))).FpColset = pColset
				_fts5ChunkIterate(tls, p, pSeg, bp+24, __ccgo_fp(_fts5PoslistOffsetsCallback))
			}
		}
	}
}

func _fts5SetupPrefixIter(tls *libc.TLS, p uintptr, bDesc int32, iIdx int32, pToken uintptr, nToken int32, pColset uintptr, ppIter uintptr) {
	bp := tls.Alloc(96)
	defer tls.Free(96)
	var i, iFree, v3 int32
	var pCtx, pData, pStruct uintptr
	var _ /* s at bp+0 */ TPrefixSetupCtx
	var _ /* s2 at bp+72 */ TTokendataSetupCtx
	_, _, _, _, _, _ = i, iFree, pCtx, pData, pStruct, v3
	libc.Xmemset(tls, bp, 0, uint64(72))
	libc.Xmemset(tls, bp+72, 0, uint64(16))
	(**(**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 + 72
		(**(**TTokendataSetupCtx)(__ccgo_up(bp + 72))).FpT = _fts5IdxMalloc(tls, p, libc.Int64FromUint64(uint64(libc.UintptrFromInt32(0)+72)+libc.Uint64FromInt32(libc.Int32FromInt32(1))*libc.Uint64FromInt64(104)))
	}
	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.Int64FromUint64(uint64(16)*libc.Uint64FromInt32((**(**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+48, (**(**TPrefixSetupCtx)(__ccgo_up(bp))).FnMerge, (**(**TPrefixSetupCtx)(__ccgo_up(bp))).FaBuf+uintptr(i)*16)
			}
			iFree = i
			for {
				if !(iFree < i+(**(**TPrefixSetupCtx)(__ccgo_up(bp))).FnMerge) {
					break
				}
				_sqlite3Fts5BufferFree(tls, (**(**TPrefixSetupCtx)(__ccgo_up(bp))).FaBuf+uintptr(iFree)*16)
				goto _2
			_2:
				;
				iFree = iFree + 1
			}
			goto _1
		_1:
			;
			i = i + (**(**TPrefixSetupCtx)(__ccgo_up(bp))).FnMerge
		}
		pData = _fts5IdxMalloc(tls, p, libc.Int64FromUint64(uint64(16)+libc.Uint64FromInt64(int64((**(**TPrefixSetupCtx)(__ccgo_up(bp))).Fdoclist.Fn))+uint64(FTS5_DATA_ZERO_PADDING)))
		if pData != 0 {
			(*TFts5Data)(unsafe.Pointer(pData)).Fp = pData + 1*16
			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.Uint64FromInt32((**(**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 + 72))).FpT)
			(*TFts5Iter)(unsafe.Pointer(**(**uintptr)(__ccgo_up(ppIter)))).FpTokenDataIter = (**(**TTokendataSetupCtx)(__ccgo_up(bp + 72))).FpT
			(**(**TTokendataSetupCtx)(__ccgo_up(bp + 72))).FpT = uintptr(0)
		}
	}
	_fts5TokendataIterDelete(tls, (**(**TTokendataSetupCtx)(__ccgo_up(bp + 72))).FpT)
	_sqlite3Fts5BufferFree(tls, bp+48)
	_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+16 */ TTokendataSetupCtx
	var _ /* token at bp+0 */ TFts5Buffer
	_ = p
	p = (*TFts5Iter)(unsafe.Pointer(pIter)).FpIndex
	**(**TFts5Buffer)(__ccgo_up(bp)) = TFts5Buffer{}
	libc.Xmemset(tls, bp+16, 0, uint64(16))
	if !(libc.Uint32FromInt32((*TFts5Buffer)(unsafe.Pointer(bp)).Fn)+libc.Uint32FromInt32(nToken+libc.Int32FromInt32(1)) <= libc.Uint32FromInt32((*TFts5Buffer)(unsafe.Pointer(bp)).FnSpace)) {
		_sqlite3Fts5BufferSize(tls, p+60, bp, libc.Uint32FromInt32(nToken+int32(1)+(*TFts5Buffer)(unsafe.Pointer(bp)).Fn))
	}
	(**(**TTokendataSetupCtx)(__ccgo_up(bp + 16))).FpT = _sqlite3Fts5MallocZero(tls, p+60, libc.Int64FromUint64(uint64(libc.UintptrFromInt32(0)+72)+libc.Uint64FromInt32(libc.Int32FromInt32(1))*libc.Uint64FromInt64(104)))
	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.Uint64FromInt32(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+16)
		_fts5TokendataIterSortMap(tls, p, (**(**TTokendataSetupCtx)(__ccgo_up(bp + 16))).FpT)
	}
	if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
		(*TFts5Iter)(unsafe.Pointer(pIter)).FpTokenDataIter = (**(**TTokendataSetupCtx)(__ccgo_up(bp + 16))).FpT
	} else {
		_fts5TokendataIterDelete(tls, (**(**TTokendataSetupCtx)(__ccgo_up(bp + 16))).FpT)
	}
	_sqlite3Fts5BufferFree(tls, bp)
	return _fts5IndexReturn(tls, p)
}

// 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.Int64FromUint64(uint64(libc.UintptrFromInt32(0)+32) + libc.Uint64FromInt32(nLevel+libc.Int32FromInt32(2))*libc.Uint64FromInt64(16))
		pStruct = Xsqlite3_realloc64(tls, pStruct, libc.Uint64FromInt64(nByte))
		if pStruct != 0 {
			libc.Xmemset(tls, pStruct+32+uintptr(nLevel)*16, 0, uint64(16))
			(*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 + 32 + uintptr(iLvl)*16
		nByte = libc.Int64FromUint64(libc.Uint64FromInt32((*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnSeg+nExtra) * uint64(56))
		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)*56, 0, uint64(56)*libc.Uint64FromInt32(nExtra))
			} else {
				nMove = libc.Int32FromUint64(libc.Uint64FromInt32((*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnSeg) * uint64(56))
				libc.Xmemmove(tls, aNew+uintptr(nExtra)*56, aNew, libc.Uint64FromInt32(nMove))
				libc.Xmemset(tls, aNew, 0, uint64(56)*libc.Uint64FromInt32(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.Int64FromUint64(uint64(libc.UintptrFromInt32(0)+32) + libc.Uint64FromInt32((*TFts5Structure)(unsafe.Pointer(p)).FnLevel)*libc.Uint64FromInt64(16))
		pNew = _sqlite3Fts5MallocZero(tls, pRc, nByte)
		if pNew != 0 {
			libc.Xmemcpy(tls, pNew, p, libc.Uint64FromInt64(nByte))
			i = 0
			for {
				if !(i < (*TFts5Structure)(unsafe.Pointer(p)).FnLevel) {
					break
				}
				(*(*TFts5StructureLevel)(unsafe.Pointer(pNew + 32 + uintptr(i)*16))).FaSeg = uintptr(0)
				goto _1
			_1:
				;
				i = i + 1
			}
			i = 0
			for {
				if !(i < (*TFts5Structure)(unsafe.Pointer(p)).FnLevel) {
					break
				}
				pLvl = pNew + 32 + uintptr(i)*16
				nByte = libc.Int64FromUint64(uint64(56) * libc.Uint64FromInt32((*(*TFts5StructureLevel)(unsafe.Pointer(pNew + 32 + uintptr(i)*16))).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 + 32 + uintptr(i)*16))).FaSeg)
						goto _3
					_3:
						;
						i = i + 1
					}
					Xsqlite3_free(tls, pNew)
					return
				}
				libc.Xmemcpy(tls, (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FaSeg, (*(*TFts5StructureLevel)(unsafe.Pointer(p + 32 + uintptr(i)*16))).FaSeg, libc.Uint64FromInt64(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
//
//	/*
//	** 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 = libc.Int64FromUint64(libc.Uint64FromInt64((*TFts5TokenDataIter)(unsafe.Pointer(pT)).FnMap) * uint64(24))
	aTmp = _sqlite3Fts5MallocZero(tls, p+60, 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, uint64(libc.Uint64FromInt64((*TFts5TokenDataIter)(unsafe.Pointer(pT)).FnMap)*uint64(24)))
		}
		Xsqlite3_free(tls, aTmp)
	}
}

// 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(32)
	defer tls.Free(32)
	var i, iId, iOff, nDiff int32
	var iLeafRowid Ti64
	var pData, pSeg uintptr
	var _ /* aHdr at bp+16 */ [4]Tu8
	var _ /* buf at bp+0 */ TFts5Buffer
	_, _, _, _, _, _, _ = i, iId, iLeafRowid, iOff, nDiff, pData, pSeg
	libc.Xmemset(tls, bp, 0, uint64(16))
	i = 0
	for {
		if !(i < (*TFts5Iter)(unsafe.Pointer(pIter)).FnSeg && (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK) {
			break
		}
		pSeg = pIter + 104 + uintptr(i)*128
		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 + 16)) = [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+60, bp, libc.Uint32FromInt32((*TFts5Data)(unsafe.Pointer(pData)).Fnn+(*TFts5Buffer)(unsafe.Pointer(bp)).Fn))
						}
						_sqlite3Fts5BufferAppendBlob(tls, p+60, bp, uint32(4), bp+16)
						_sqlite3Fts5BufferAppendVarint(tls, p+60, bp, int64((*TFts5SegIter)(unsafe.Pointer(pSeg)).Fterm.Fn))
						_sqlite3Fts5BufferAppendBlob(tls, p+60, bp, libc.Uint32FromInt32((*TFts5SegIter)(unsafe.Pointer(pSeg)).Fterm.Fn), (*TFts5SegIter)(unsafe.Pointer(pSeg)).Fterm.Fp)
						_sqlite3Fts5BufferAppendBlob(tls, p+60, 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+60, 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+60, bp, int64((**(**TFts5Buffer)(__ccgo_up(bp))).Fn)-int64(1)-int64(nDiff)-int64(4))
							_sqlite3Fts5BufferAppendBlob(tls, p+60, 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)
}

func _fts5UnicodeAddExceptions(tls *libc.TLS, p uintptr, z uintptr, bTokenChars int32) (r int32) {
	var aNew, zCsr, zTerm, v1 uintptr
	var bToken, i, n, nNew, rc int32
	var iCode Tu32
	_, _, _, _, _, _, _, _, _, _ = aNew, bToken, i, iCode, n, nNew, rc, zCsr, zTerm, v1
	rc = SQLITE_OK
	n = libc.Int32FromUint64(libc.Xstrlen(tls, z))
	if n > 0 {
		aNew = Xsqlite3_realloc64(tls, (*TUnicode61Tokenizer)(unsafe.Pointer(p)).FaiException, uint64(libc.Uint64FromInt32(n+(*TUnicode61Tokenizer)(unsafe.Pointer(p)).FnException)*uint64(4)))
		if aNew != 0 {
			nNew = (*TUnicode61Tokenizer)(unsafe.Pointer(p)).FnException
			zCsr = z
			zTerm = z + uintptr(n)
			for zCsr < zTerm {
				v1 = zCsr
				zCsr = zCsr + 1
				iCode = uint32(**(**uint8)(__ccgo_up(v1)))
				if iCode >= uint32(0xc0) {
					iCode = uint32(_sqlite3Utf8Trans1[iCode-uint32(0xc0)])
					for zCsr < zTerm && libc.Int32FromUint8(**(**uint8)(__ccgo_up(zCsr)))&int32(0xc0) == int32(0x80) {
						v1 = zCsr
						zCsr = zCsr + 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 iCode < uint32(128) {
					**(**uint8)(__ccgo_up(p + uintptr(iCode))) = libc.Uint8FromInt32(bTokenChars)
				} else {
					bToken = libc.Int32FromUint8(**(**uint8)(__ccgo_up(p + 160 + uintptr(_sqlite3Fts5UnicodeCategory(tls, iCode)))))
					if bToken != bTokenChars && _sqlite3Fts5UnicodeIsdiacritic(tls, libc.Int32FromUint32(iCode)) == 0 {
						i = 0
						for {
							if !(i < nNew) {
								break
							}
							if libc.Uint32FromInt32(**(**int32)(__ccgo_up(aNew + uintptr(i)*4))) > iCode {
								break
							}
							goto _3
						_3:
							;
							i = i + 1
						}
						libc.Xmemmove(tls, aNew+uintptr(i+int32(1))*4, aNew+uintptr(i)*4, libc.Uint64FromInt32(nNew-i)*uint64(4))
						**(**int32)(__ccgo_up(aNew + uintptr(i)*4)) = libc.Int32FromUint32(iCode)
						nNew = nNew + 1
					}
				}
			}
			(*TUnicode61Tokenizer)(unsafe.Pointer(p)).FaiException = aNew
			(*TUnicode61Tokenizer)(unsafe.Pointer(p)).FnException = nNew
		} else {
			rc = int32(SQLITE_NOMEM)
		}
	}
	return rc
}

// C documentation
//
//	/*
//	** Advance the cursor to the next row in the table.
//	*/
func _fts5VocabNextMethod(tls *libc.TLS, pCursor uintptr) (r int32) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var bCmp, eDetail, iCol, ii1, nCmp, nCol, nPos, v2 int32
	var pCsr, pPos, pTab, zTerm uintptr
	var v3 Ti64
	var _ /* iOff at bp+16 */ int32
	var _ /* iPos at bp+8 */ Ti64
	var _ /* ii at bp+20 */ Tu32
	var _ /* nTerm at bp+4 */ int32
	var _ /* rc at bp+0 */ int32
	_, _, _, _, _, _, _, _, _, _, _, _, _ = bCmp, eDetail, iCol, ii1, nCmp, nCol, nPos, pCsr, pPos, pTab, zTerm, v2, v3
	pCsr = pCursor
	pTab = (*Tsqlite3_vtab_cursor)(unsafe.Pointer(pCursor)).FpVtab
	nCol = (*TFts5Config)(unsafe.Pointer((*TFts5Table)(unsafe.Pointer((*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FpFts5)).FpConfig)).FnCol
	**(**int32)(__ccgo_up(bp)) = _sqlite3Fts5StructureTest(tls, (*TFts5Table)(unsafe.Pointer((*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FpFts5)).FpIndex, (*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FpStruct)
	if **(**int32)(__ccgo_up(bp)) != SQLITE_OK {
		return **(**int32)(__ccgo_up(bp))
	}
	(*TFts5VocabCursor)(unsafe.Pointer(pCsr)).Frowid = (*TFts5VocabCursor)(unsafe.Pointer(pCsr)).Frowid + 1
	if (*TFts5VocabTable)(unsafe.Pointer(pTab)).FeType == int32(FTS5_VOCAB_INSTANCE) {
		return _fts5VocabInstanceNext(tls, pCsr)
	}
	if (*TFts5VocabTable)(unsafe.Pointer(pTab)).FeType == FTS5_VOCAB_COL {
		(*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FiCol = (*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FiCol + 1
		for {
			if !((*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FiCol < nCol) {
				break
			}
			if **(**Ti64)(__ccgo_up((*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FaDoc + uintptr((*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FiCol)*8)) != 0 {
				break
			}
			goto _1
		_1:
			;
			(*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FiCol = (*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FiCol + 1
		}
	}
	if (*TFts5VocabTable)(unsafe.Pointer(pTab)).FeType != FTS5_VOCAB_COL || (*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FiCol >= nCol {
		if (*TFts5IndexIter)(unsafe.Pointer((*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FpIter)).FbEof != 0 {
			(*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FbEof = int32(1)
		} else {
			zTerm = _sqlite3Fts5IterTerm(tls, (*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FpIter, bp+4)
			if (*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FnLeTerm >= 0 {
				if **(**int32)(__ccgo_up(bp + 4)) < (*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FnLeTerm {
					v2 = **(**int32)(__ccgo_up(bp + 4))
				} else {
					v2 = (*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FnLeTerm
				}
				nCmp = v2
				bCmp = libc.Xmemcmp(tls, (*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FzLeTerm, zTerm, libc.Uint64FromInt32(nCmp))
				if bCmp < 0 || bCmp == 0 && (*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FnLeTerm < **(**int32)(__ccgo_up(bp + 4)) {
					(*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FbEof = int32(1)
					return SQLITE_OK
				}
			}
			_sqlite3Fts5BufferSet(tls, bp, pCsr+96, **(**int32)(__ccgo_up(bp + 4)), zTerm)
			libc.Xmemset(tls, (*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FaCnt, 0, libc.Uint64FromInt32(nCol)*uint64(8))
			libc.Xmemset(tls, (*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FaDoc, 0, libc.Uint64FromInt32(nCol)*uint64(8))
			(*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FiCol = 0
			for **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
				eDetail = (*TFts5Config)(unsafe.Pointer((*TFts5Table)(unsafe.Pointer((*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FpFts5)).FpConfig)).FeDetail /* Position list */
				**(**Ti64)(__ccgo_up(bp + 8)) = 0                                                                                                           /* 64-bit position read from poslist */
				**(**int32)(__ccgo_up(bp + 16)) = 0                                                                                                         /* Current offset within position list */
				pPos = (*TFts5IndexIter)(unsafe.Pointer((*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FpIter)).FpData
				nPos = (*TFts5IndexIter)(unsafe.Pointer((*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FpIter)).FnData
				switch (*TFts5VocabTable)(unsafe.Pointer(pTab)).FeType {
				case int32(FTS5_VOCAB_ROW):
					/* Do not bother counting the number of instances if the "cnt"
					 ** column is not being read (according to colUsed).  */
					if eDetail == FTS5_DETAIL_FULL && (*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FcolUsed&int32(0x04) != 0 {
						for **(**Ti64)(__ccgo_up(bp + 8)) < int64(nPos) {
							v3 = **(**Ti64)(__ccgo_up(bp + 8))
							**(**Ti64)(__ccgo_up(bp + 8)) = **(**Ti64)(__ccgo_up(bp + 8)) + 1
							**(**Tu32)(__ccgo_up(bp + 20)) = uint32(**(**Tu8)(__ccgo_up(pPos + uintptr(v3))))
							if **(**Tu32)(__ccgo_up(bp + 20))&uint32(0x80) != 0 {
								**(**Ti64)(__ccgo_up(bp + 8)) = **(**Ti64)(__ccgo_up(bp + 8)) - 1
								**(**Ti64)(__ccgo_up(bp + 8)) = **(**Ti64)(__ccgo_up(bp + 8)) + int64(_sqlite3Fts5GetVarint32(tls, pPos+uintptr(**(**Ti64)(__ccgo_up(bp + 8))), bp+20))
							}
							if **(**Tu32)(__ccgo_up(bp + 20)) == uint32(1) {
								/* New column in the position list */
								v3 = **(**Ti64)(__ccgo_up(bp + 8))
								**(**Ti64)(__ccgo_up(bp + 8)) = **(**Ti64)(__ccgo_up(bp + 8)) + 1
								**(**Tu32)(__ccgo_up(bp + 20)) = uint32(**(**Tu8)(__ccgo_up(pPos + uintptr(v3))))
								if **(**Tu32)(__ccgo_up(bp + 20))&uint32(0x80) != 0 {
									**(**Ti64)(__ccgo_up(bp + 8)) = **(**Ti64)(__ccgo_up(bp + 8)) - 1
									**(**Ti64)(__ccgo_up(bp + 8)) = **(**Ti64)(__ccgo_up(bp + 8)) + int64(_sqlite3Fts5GetVarint32(tls, pPos+uintptr(**(**Ti64)(__ccgo_up(bp + 8))), bp+20))
								}
							} else {
								/* An instance - increment pCsr->aCnt[] */
								**(**Ti64)(__ccgo_up((*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FaCnt)) = **(**Ti64)(__ccgo_up((*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FaCnt)) + 1
							}
						}
					}
					**(**Ti64)(__ccgo_up((*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FaDoc)) = **(**Ti64)(__ccgo_up((*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FaDoc)) + 1
				case FTS5_VOCAB_COL:
					if eDetail == FTS5_DETAIL_FULL {
						iCol = -int32(1)
						for 0 == _sqlite3Fts5PoslistNext64(tls, pPos, nPos, bp+16, bp+8) {
							ii1 = int32(**(**Ti64)(__ccgo_up(bp + 8)) >> libc.Int32FromInt32(32) & libc.Int64FromInt32(0x7FFFFFFF))
							if iCol != ii1 {
								if ii1 >= nCol {
									**(**int32)(__ccgo_up(bp)) = libc.Int32FromInt32(SQLITE_CORRUPT) | libc.Int32FromInt32(1)<<libc.Int32FromInt32(8)
									break
								}
								**(**Ti64)(__ccgo_up((*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FaDoc + uintptr(ii1)*8)) = **(**Ti64)(__ccgo_up((*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FaDoc + uintptr(ii1)*8)) + 1
								iCol = ii1
							}
							**(**Ti64)(__ccgo_up((*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FaCnt + uintptr(ii1)*8)) = **(**Ti64)(__ccgo_up((*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FaCnt + uintptr(ii1)*8)) + 1
						}
					} else {
						if eDetail == int32(FTS5_DETAIL_COLUMNS) {
							for 0 == _sqlite3Fts5PoslistNext64(tls, pPos, nPos, bp+16, bp+8) {
								if **(**Ti64)(__ccgo_up(bp + 8)) >= int64(nCol) {
									**(**int32)(__ccgo_up(bp)) = libc.Int32FromInt32(SQLITE_CORRUPT) | libc.Int32FromInt32(1)<<libc.Int32FromInt32(8)
									break
								}
								**(**Ti64)(__ccgo_up((*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FaDoc + uintptr(**(**Ti64)(__ccgo_up(bp + 8)))*8)) = **(**Ti64)(__ccgo_up((*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FaDoc + uintptr(**(**Ti64)(__ccgo_up(bp + 8)))*8)) + 1
							}
						} else {
							**(**Ti64)(__ccgo_up((*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FaDoc)) = **(**Ti64)(__ccgo_up((*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FaDoc)) + 1
						}
					}
				default:
					break
				}
				if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
					**(**int32)(__ccgo_up(bp)) = _sqlite3Fts5IterNextScan(tls, (*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FpIter)
				}
				if (*TFts5VocabTable)(unsafe.Pointer(pTab)).FeType == int32(FTS5_VOCAB_INSTANCE) {
					break
				}
				if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
					zTerm = _sqlite3Fts5IterTerm(tls, (*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FpIter, bp+4)
					if **(**int32)(__ccgo_up(bp + 4)) != (*TFts5VocabCursor)(unsafe.Pointer(pCsr)).Fterm.Fn || **(**int32)(__ccgo_up(bp + 4)) > 0 && libc.Xmemcmp(tls, zTerm, (*TFts5VocabCursor)(unsafe.Pointer(pCsr)).Fterm.Fp, libc.Uint64FromInt32(**(**int32)(__ccgo_up(bp + 4)))) != 0 {
						break
					}
					if (*TFts5IndexIter)(unsafe.Pointer((*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FpIter)).FbEof != 0 {
						break
					}
				}
			}
		}
	}
	if **(**int32)(__ccgo_up(bp)) == SQLITE_OK && (*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FbEof == 0 && (*TFts5VocabTable)(unsafe.Pointer(pTab)).FeType == FTS5_VOCAB_COL {
		for {
			if !((*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FiCol < nCol && **(**Ti64)(__ccgo_up((*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FaDoc + uintptr((*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FiCol)*8)) == 0) {
				break
			}
			goto _5
		_5:
			;
			(*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FiCol = (*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FiCol + 1
		}
		if (*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FiCol == nCol {
			**(**int32)(__ccgo_up(bp)) = libc.Int32FromInt32(SQLITE_CORRUPT) | libc.Int32FromInt32(1)<<libc.Int32FromInt32(8)
		}
	}
	return **(**int32)(__ccgo_up(bp))
}

// C documentation
//
//	/*
//	** Restore cursor pCsr to the state it was in immediately after being
//	** created by the xOpen() method.
//	*/
func _fts5VocabResetCursor(tls *libc.TLS, pCsr uintptr) {
	var nCol int32
	_ = nCol
	nCol = (*TFts5Config)(unsafe.Pointer((*TFts5Table)(unsafe.Pointer((*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FpFts5)).FpConfig)).FnCol
	(*TFts5VocabCursor)(unsafe.Pointer(pCsr)).Frowid = 0
	_sqlite3Fts5IterClose(tls, (*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FpIter)
	_sqlite3Fts5StructureRelease(tls, (*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FpStruct)
	(*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FpStruct = uintptr(0)
	(*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FpIter = uintptr(0)
	Xsqlite3_free(tls, (*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FzLeTerm)
	(*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FnLeTerm = -int32(1)
	(*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FzLeTerm = uintptr(0)
	(*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FbEof = 0
	(*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FiCol = 0
	(*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FiInstPos = 0
	(*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FiInstOff = 0
	(*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FcolUsed = 0
	libc.Xmemset(tls, (*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FaCnt, 0, uint64(8)*libc.Uint64FromInt32(nCol))
	libc.Xmemset(tls, (*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FaDoc, 0, uint64(8)*libc.Uint64FromInt32(nCol))
}

// 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(uint64(32)*libc.Uint64FromInt32(nLvl)))
		if aDlidx == uintptr(0) {
			(*TFts5Index)(unsafe.Pointer(p)).Frc = int32(SQLITE_NOMEM)
		} else {
			nByte = uint64(32) * libc.Uint64FromInt32(nLvl-(*TFts5SegWriter)(unsafe.Pointer(pWriter)).FnDlidx)
			libc.Xmemset(tls, aDlidx+uintptr((*TFts5SegWriter)(unsafe.Pointer(pWriter)).FnDlidx)*32, 0, nByte)
			(*TFts5SegWriter)(unsafe.Pointer(pWriter)).FaDlidx = aDlidx
			(*TFts5SegWriter)(unsafe.Pointer(pWriter)).FnDlidx = nLvl
		}
	}
	return (*TFts5Index)(unsafe.Pointer(p)).Frc
}

// C documentation
//
//	/*
//	** If pPoly is a polygon, compute its bounding box. Then:
//	**
//	**    (1) if aCoord!=0 store the bounding box in aCoord, returning NULL
//	**    (2) otherwise, compute a GeoPoly for the bounding box and return the
//	**        new GeoPoly
//	**
//	** If pPoly is NULL but aCoord is not NULL, then compute a new GeoPoly from
//	** the bounding box in aCoord and return a pointer to that GeoPoly.
//	*/
func _geopolyBBox(tls *libc.TLS, context uintptr, pPoly uintptr, aCoord uintptr, pRc uintptr) (r1 uintptr) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var mnX, mnY, mxX, mxY, v3 float32
	var p, pOut uintptr
	var r float64
	var _ /* ii at bp+0 */ int32
	_, _, _, _, _, _, _, _ = mnX, mnY, mxX, mxY, p, pOut, r, v3
	pOut = uintptr(0)
	if pPoly == uintptr(0) && aCoord != uintptr(0) {
		p = uintptr(0)
		mnX = *(*TRtreeValue)(unsafe.Pointer(aCoord))
		mxX = *(*TRtreeValue)(unsafe.Pointer(aCoord + 1*4))
		mnY = *(*TRtreeValue)(unsafe.Pointer(aCoord + 2*4))
		mxY = *(*TRtreeValue)(unsafe.Pointer(aCoord + 3*4))
		goto geopolyBboxFill
	} else {
		p = _geopolyFuncParam(tls, context, pPoly, pRc)
	}
	if !(p != 0) {
		goto _1
	}
	v3 = **(**TGeoCoord)(__ccgo_up(p + 8 + uintptr(libc.Int32FromInt32(0)*libc.Int32FromInt32(2))*4))
	mxX = v3
	mnX = v3
	v3 = **(**TGeoCoord)(__ccgo_up(p + 8 + uintptr(libc.Int32FromInt32(0)*libc.Int32FromInt32(2)+libc.Int32FromInt32(1))*4))
	mxY = v3
	mnY = v3
	**(**int32)(__ccgo_up(bp)) = int32(1)
	for {
		if !(**(**int32)(__ccgo_up(bp)) < (*TGeoPoly)(unsafe.Pointer(p)).FnVertex) {
			break
		}
		r = float64(**(**TGeoCoord)(__ccgo_up(p + 8 + uintptr(**(**int32)(__ccgo_up(bp))*int32(2))*4)))
		if r < float64(mnX) {
			mnX = float32(r)
		} else {
			if r > float64(mxX) {
				mxX = float32(r)
			}
		}
		r = float64(**(**TGeoCoord)(__ccgo_up(p + 8 + uintptr(**(**int32)(__ccgo_up(bp))*int32(2)+int32(1))*4)))
		if r < float64(mnY) {
			mnY = float32(r)
		} else {
			if r > float64(mxY) {
				mxY = float32(r)
			}
		}
		goto _5
	_5:
		;
		**(**int32)(__ccgo_up(bp)) = **(**int32)(__ccgo_up(bp)) + 1
	}
	if pRc != 0 {
		**(**int32)(__ccgo_up(pRc)) = SQLITE_OK
	}
	if !(aCoord == uintptr(0)) {
		goto _6
	}
	goto geopolyBboxFill
geopolyBboxFill:
	;
	pOut = Xsqlite3_realloc64(tls, p, uint64(libc.Uint64FromInt64(40)+libc.Uint64FromInt64(4)*libc.Uint64FromInt32(2)*libc.Uint64FromInt32(libc.Int32FromInt32(4)-libc.Int32FromInt32(4))))
	if pOut == uintptr(0) {
		Xsqlite3_free(tls, p)
		if context != 0 {
			Xsqlite3_result_error_nomem(tls, context)
		}
		if pRc != 0 {
			**(**int32)(__ccgo_up(pRc)) = int32(SQLITE_NOMEM)
		}
		return uintptr(0)
	}
	(*TGeoPoly)(unsafe.Pointer(pOut)).FnVertex = int32(4)
	**(**int32)(__ccgo_up(bp)) = int32(1)
	**(**uint8)(__ccgo_up(pOut + 4)) = **(**uint8)(__ccgo_up(bp))
	**(**uint8)(__ccgo_up(pOut + 4 + 1)) = uint8(0)
	**(**uint8)(__ccgo_up(pOut + 4 + 2)) = uint8(0)
	**(**uint8)(__ccgo_up(pOut + 4 + 3)) = uint8(4)
	**(**TGeoCoord)(__ccgo_up(pOut + 8 + uintptr(libc.Int32FromInt32(0)*libc.Int32FromInt32(2))*4)) = mnX
	**(**TGeoCoord)(__ccgo_up(pOut + 8 + uintptr(libc.Int32FromInt32(0)*libc.Int32FromInt32(2)+libc.Int32FromInt32(1))*4)) = mnY
	**(**TGeoCoord)(__ccgo_up(pOut + 8 + uintptr(libc.Int32FromInt32(1)*libc.Int32FromInt32(2))*4)) = mxX
	**(**TGeoCoord)(__ccgo_up(pOut + 8 + uintptr(libc.Int32FromInt32(1)*libc.Int32FromInt32(2)+libc.Int32FromInt32(1))*4)) = mnY
	**(**TGeoCoord)(__ccgo_up(pOut + 8 + uintptr(libc.Int32FromInt32(2)*libc.Int32FromInt32(2))*4)) = mxX
	**(**TGeoCoord)(__ccgo_up(pOut + 8 + uintptr(libc.Int32FromInt32(2)*libc.Int32FromInt32(2)+libc.Int32FromInt32(1))*4)) = mxY
	**(**TGeoCoord)(__ccgo_up(pOut + 8 + uintptr(libc.Int32FromInt32(3)*libc.Int32FromInt32(2))*4)) = mnX
	**(**TGeoCoord)(__ccgo_up(pOut + 8 + uintptr(libc.Int32FromInt32(3)*libc.Int32FromInt32(2)+libc.Int32FromInt32(1))*4)) = mxY
	goto _7
_6:
	;
	Xsqlite3_free(tls, p)
	*(*TRtreeValue)(unsafe.Pointer(aCoord)) = mnX
	*(*TRtreeValue)(unsafe.Pointer(aCoord + 1*4)) = mxX
	*(*TRtreeValue)(unsafe.Pointer(aCoord + 2*4)) = mnY
	*(*TRtreeValue)(unsafe.Pointer(aCoord + 3*4)) = mxY
_7:
	;
	goto _2
_1:
	;
	if aCoord != 0 {
		libc.Xmemset(tls, aCoord, 0, libc.Uint64FromInt64(4)*libc.Uint64FromInt32(4))
	}
_2:
	;
	return pOut
}

// 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+32 */ [4]TRtreeCoord
	var _ /* iCell at bp+12 */ int32
	var _ /* iNode at bp+24 */ Ti64
	var _ /* pLeaf at bp+16 */ uintptr
	var _ /* pRoot at bp+0 */ uintptr
	var _ /* rc at bp+8 */ 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 + 8)) = SQLITE_OK
	**(**int32)(__ccgo_up(bp + 12)) = 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 + 24)) = 0
		**(**int32)(__ccgo_up(bp + 8)) = _findLeafNode(tls, pRtree, iRowid, bp+16, bp+24)
		if **(**int32)(__ccgo_up(bp + 8)) == SQLITE_OK && **(**uintptr)(__ccgo_up(bp + 16)) != uintptr(0) {
			p = _rtreeSearchPointNew(tls, pCsr, float64(0), uint8(0))
			/* Always returns pCsr->sPoint */
			**(**uintptr)(__ccgo_up(pCsr + 88)) = **(**uintptr)(__ccgo_up(bp + 16))
			(*TRtreeSearchPoint)(unsafe.Pointer(p)).Fid = **(**Ti64)(__ccgo_up(bp + 24))
			(*TRtreeSearchPoint)(unsafe.Pointer(p)).FeWithin = uint8(PARTLY_WITHIN)
			**(**int32)(__ccgo_up(bp + 8)) = _nodeRowidIndex(tls, pRtree, **(**uintptr)(__ccgo_up(bp + 16)), iRowid, bp+12)
			(*TRtreeSearchPoint)(unsafe.Pointer(p)).FiCell = libc.Uint8FromInt32(**(**int32)(__ccgo_up(bp + 12)))
		} 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 + 8)) = _nodeAcquire(tls, pRtree, int64(1), uintptr(0), bp)
		if **(**int32)(__ccgo_up(bp + 8)) == SQLITE_OK && idxNum <= int32(3) {
			_geopolyBBox(tls, uintptr(0), **(**uintptr)(__ccgo_up(argv)), bp+32, bp+8)
			if **(**int32)(__ccgo_up(bp + 8)) != 0 {
				goto geopoly_filter_end
			}
			v1 = Xsqlite3_malloc(tls, libc.Int32FromUint64(libc.Uint64FromInt64(24)*libc.Uint64FromInt32(4)))
			p1 = v1
			(*TRtreeCursor)(unsafe.Pointer(pCsr)).FaConstraint = v1
			(*TRtreeCursor)(unsafe.Pointer(pCsr)).FnConstraint = int32(4)
			if p1 == uintptr(0) {
				**(**int32)(__ccgo_up(bp + 8)) = int32(SQLITE_NOMEM)
			} else {
				libc.Xmemset(tls, (*TRtreeCursor)(unsafe.Pointer(pCsr)).FaConstraint, 0, libc.Uint64FromInt64(24)*libc.Uint64FromInt32(4))
				libc.Xmemset(tls, pCsr+128, 0, uint64(4)*libc.Uint64FromInt32((*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 + 32 + 1*4)))
					p1 += 24
					(*TRtreeConstraint)(unsafe.Pointer(p1)).Fop = int32('D')
					(*TRtreeConstraint)(unsafe.Pointer(p1)).FiCoord = int32(1)
					*(*TRtreeDValue)(unsafe.Pointer(p1 + 8)) = float64(*(*TRtreeValue)(unsafe.Pointer(bp + 32)))
					p1 += 24
					(*TRtreeConstraint)(unsafe.Pointer(p1)).Fop = int32('B')
					(*TRtreeConstraint)(unsafe.Pointer(p1)).FiCoord = int32(2)
					*(*TRtreeDValue)(unsafe.Pointer(p1 + 8)) = float64(*(*TRtreeValue)(unsafe.Pointer(bp + 32 + 3*4)))
					p1 += 24
					(*TRtreeConstraint)(unsafe.Pointer(p1)).Fop = int32('D')
					(*TRtreeConstraint)(unsafe.Pointer(p1)).FiCoord = int32(3)
					*(*TRtreeDValue)(unsafe.Pointer(p1 + 8)) = float64(*(*TRtreeValue)(unsafe.Pointer(bp + 32 + 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 + 32)))
					p1 += 24
					(*TRtreeConstraint)(unsafe.Pointer(p1)).Fop = int32('B')
					(*TRtreeConstraint)(unsafe.Pointer(p1)).FiCoord = int32(1)
					*(*TRtreeDValue)(unsafe.Pointer(p1 + 8)) = float64(*(*TRtreeValue)(unsafe.Pointer(bp + 32 + 1*4)))
					p1 += 24
					(*TRtreeConstraint)(unsafe.Pointer(p1)).Fop = int32('D')
					(*TRtreeConstraint)(unsafe.Pointer(p1)).FiCoord = int32(2)
					*(*TRtreeDValue)(unsafe.Pointer(p1 + 8)) = float64(*(*TRtreeValue)(unsafe.Pointer(bp + 32 + 2*4)))
					p1 += 24
					(*TRtreeConstraint)(unsafe.Pointer(p1)).Fop = int32('B')
					(*TRtreeConstraint)(unsafe.Pointer(p1)).FiCoord = int32(3)
					*(*TRtreeDValue)(unsafe.Pointer(p1 + 8)) = float64(*(*TRtreeValue)(unsafe.Pointer(bp + 32 + 3*4)))
				}
			}
		}
		if **(**int32)(__ccgo_up(bp + 8)) == 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 + 8)) = 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 + 88)) = **(**uintptr)(__ccgo_up(bp))
			**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
			**(**int32)(__ccgo_up(bp + 8)) = _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 + 8))
}

// C documentation
//
//	/*
//	** Given a function parameter, try to interpret it as a polygon, either
//	** in the binary format or JSON text.  Compute a GeoPoly object and
//	** return a pointer to that object.  Or if the input is not a well-formed
//	** polygon, put an error message in sqlite3_context and return NULL.
//	*/
func _geopolyFuncParam(tls *libc.TLS, pCtx uintptr, pVal uintptr, pRc uintptr) (r uintptr) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var a, p, zJson, v4 uintptr
	var ii, nByte, nVertex, v1 int32
	var v2 bool
	var _ /* x at bp+0 */ int32
	_, _, _, _, _, _, _, _, _ = a, ii, nByte, nVertex, p, zJson, v1, v2, v4
	p = uintptr(0)
	if v2 = Xsqlite3_value_type(tls, pVal) == int32(SQLITE_BLOB); v2 {
		v1 = Xsqlite3_value_bytes(tls, pVal)
		nByte = v1
	}
	if v2 && v1 >= libc.Int32FromUint64(libc.Uint64FromInt32(4)+libc.Uint64FromInt32(6)*libc.Uint64FromInt64(4)) {
		a = Xsqlite3_value_blob(tls, pVal)
		if a == uintptr(0) {
			if pCtx != 0 {
				Xsqlite3_result_error_nomem(tls, pCtx)
			}
			return uintptr(0)
		}
		nVertex = libc.Int32FromUint8(**(**uint8)(__ccgo_up(a + 1)))<<int32(16) + libc.Int32FromUint8(**(**uint8)(__ccgo_up(a + 2)))<<int32(8) + libc.Int32FromUint8(**(**uint8)(__ccgo_up(a + 3)))
		if (libc.Int32FromUint8(**(**uint8)(__ccgo_up(a))) == 0 || libc.Int32FromUint8(**(**uint8)(__ccgo_up(a))) == int32(1)) && libc.Uint64FromInt32(nVertex*int32(2))*uint64(4)+uint64(4) == uint64(libc.Uint32FromInt32(nByte)) {
			p = Xsqlite3_malloc64(tls, uint64(uint64(40)+libc.Uint64FromInt32((nVertex-int32(1))*int32(2))*uint64(4)))
			if p == uintptr(0) {
				if pRc != 0 {
					**(**int32)(__ccgo_up(pRc)) = int32(SQLITE_NOMEM)
				}
				if pCtx != 0 {
					Xsqlite3_result_error_nomem(tls, pCtx)
				}
			} else {
				**(**int32)(__ccgo_up(bp)) = int32(1)
				(*TGeoPoly)(unsafe.Pointer(p)).FnVertex = nVertex
				libc.Xmemcpy(tls, p+4, a, libc.Uint64FromInt32(nByte))
				if libc.Int32FromUint8(**(**uint8)(__ccgo_up(a))) != libc.Int32FromUint8(**(**uint8)(__ccgo_up(bp))) {
					ii = 0
					for {
						if !(ii < nVertex) {
							break
						}
						_geopolySwab32(tls, p+8+uintptr(ii*int32(2))*4)
						_geopolySwab32(tls, p+8+uintptr(ii*int32(2)+int32(1))*4)
						goto _3
					_3:
						;
						ii = ii + 1
					}
					v4 = p + 4
					*(*uint8)(unsafe.Pointer(v4)) = uint8(int32(*(*uint8)(unsafe.Pointer(v4))) ^ libc.Int32FromInt32(1))
				}
			}
		}
		if pRc != 0 {
			**(**int32)(__ccgo_up(pRc)) = SQLITE_OK
		}
		return p
	} else {
		if Xsqlite3_value_type(tls, pVal) == int32(SQLITE_TEXT) {
			zJson = Xsqlite3_value_text(tls, pVal)
			if zJson == uintptr(0) {
				if pRc != 0 {
					**(**int32)(__ccgo_up(pRc)) = int32(SQLITE_NOMEM)
				}
				return uintptr(0)
			}
			return _geopolyParseJson(tls, zJson, pRc)
		} else {
			if pRc != 0 {
				**(**int32)(__ccgo_up(pRc)) = int32(SQLITE_ERROR)
			}
			return uintptr(0)
		}
	}
	return r
}

// 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 + 248)) = **(**Tu32)(__ccgo_up(pPager + 248)) + 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.Uint64FromInt64((*TPager)(unsafe.Pointer(pPager)).FpageSize))
		} else {
			**(**Tu32)(__ccgo_up(pPager + 248 + 1*4)) = **(**Tu32)(__ccgo_up(pPager + 248 + 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
}

func _groupConcatInverse(tls *libc.TLS, context uintptr, argc int32, argv uintptr) {
	var nVS int32
	var pGCC uintptr
	_, _ = nVS, pGCC
	_ = argc /* Suppress unused parameter warning */
	if Xsqlite3_value_type(tls, **(**uintptr)(__ccgo_up(argv))) == int32(SQLITE_NULL) {
		return
	}
	pGCC = Xsqlite3_aggregate_context(tls, context, int32(48))
	/* pGCC is always non-NULL since groupConcatStep() will have always
	 ** run first to initialize it */
	if pGCC != 0 { /* Number of characters to remove */
		/* Must call sqlite3_value_text() to convert the argument into text prior
		 ** to invoking sqlite3_value_bytes(), in case the text encoding is UTF16 */
		Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv)))
		nVS = Xsqlite3_value_bytes(tls, **(**uintptr)(__ccgo_up(argv)))
		**(**int32)(__ccgo_up(pGCC + 32)) -= int32(1)
		if (*TGroupConcatCtx)(unsafe.Pointer(pGCC)).FpnSepLengths != uintptr(0) {
			if (*TGroupConcatCtx)(unsafe.Pointer(pGCC)).FnAccum > 0 {
				nVS = nVS + **(**int32)(__ccgo_up((*TGroupConcatCtx)(unsafe.Pointer(pGCC)).FpnSepLengths))
				libc.Xmemmove(tls, (*TGroupConcatCtx)(unsafe.Pointer(pGCC)).FpnSepLengths, (*TGroupConcatCtx)(unsafe.Pointer(pGCC)).FpnSepLengths+uintptr(1)*4, libc.Uint64FromInt32((*TGroupConcatCtx)(unsafe.Pointer(pGCC)).FnAccum-libc.Int32FromInt32(1))*uint64(4))
			}
		} else {
			/* If removing single accumulated string, harmlessly over-do. */
			nVS = nVS + (*TGroupConcatCtx)(unsafe.Pointer(pGCC)).FnFirstSepLength
		}
		if nVS >= libc.Int32FromUint32((*TGroupConcatCtx)(unsafe.Pointer(pGCC)).Fstr.FnChar) {
			(*TGroupConcatCtx)(unsafe.Pointer(pGCC)).Fstr.FnChar = uint32(0)
		} else {
			(*TGroupConcatCtx)(unsafe.Pointer(pGCC)).Fstr.FnChar -= libc.Uint32FromInt32(nVS)
			libc.Xmemmove(tls, (*TGroupConcatCtx)(unsafe.Pointer(pGCC)).Fstr.FzText, (*TGroupConcatCtx)(unsafe.Pointer(pGCC)).Fstr.FzText+uintptr(nVS), uint64((*TGroupConcatCtx)(unsafe.Pointer(pGCC)).Fstr.FnChar))
		}
		if (*TGroupConcatCtx)(unsafe.Pointer(pGCC)).Fstr.FnChar == uint32(0) {
			(*TGroupConcatCtx)(unsafe.Pointer(pGCC)).Fstr.FmxAlloc = uint32(0)
			Xsqlite3_free(tls, (*TGroupConcatCtx)(unsafe.Pointer(pGCC)).FpnSepLengths)
			(*TGroupConcatCtx)(unsafe.Pointer(pGCC)).FpnSepLengths = uintptr(0)
		}
	}
}

// C documentation
//
//	/*
//	** Grow the db->aVTrans[] array so that there is room for at least one
//	** more v-table. Return SQLITE_NOMEM if a malloc fails, or SQLITE_OK otherwise.
//	*/
func _growVTrans(tls *libc.TLS, db uintptr) (r int32) {
	var ARRAY_INCR int32
	var aVTrans uintptr
	var nBytes Tsqlite3_int64
	_, _, _ = ARRAY_INCR, aVTrans, nBytes
	ARRAY_INCR = int32(5)
	/* Grow the sqlite3.aVTrans array if required */
	if (*Tsqlite3)(unsafe.Pointer(db)).FnVTrans%ARRAY_INCR == 0 {
		nBytes = libc.Int64FromUint64(uint64(8) * libc.Uint64FromInt64(int64((*Tsqlite3)(unsafe.Pointer(db)).FnVTrans)+int64(ARRAY_INCR)))
		aVTrans = _sqlite3DbRealloc(tls, db, (*Tsqlite3)(unsafe.Pointer(db)).FaVTrans, libc.Uint64FromInt64(nBytes))
		if !(aVTrans != 0) {
			return int32(SQLITE_NOMEM)
		}
		libc.Xmemset(tls, aVTrans+uintptr((*Tsqlite3)(unsafe.Pointer(db)).FnVTrans)*8, 0, uint64(8)*libc.Uint64FromInt32(ARRAY_INCR))
		(*Tsqlite3)(unsafe.Pointer(db)).FaVTrans = aVTrans
	}
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** Insert a new cell on pPage at cell index "i".  pCell points to the
//	** content of the cell.
//	**
//	** If the cell content will fit on the page, then put it there.  If it
//	** will not fit, then make a copy of the cell content into pTemp if
//	** pTemp is not null.  Regardless of pTemp, allocate a new entry
//	** in pPage->apOvfl[] and make it point to the cell content (either
//	** in pTemp or the original pCell) and also record its index.
//	** Allocating a new entry in pPage->aCell[] implies that
//	** pPage->nOverflow is incremented.
//	**
//	** The insertCellFast() routine below works exactly the same as
//	** insertCell() except that it lacks the pTemp and iChild parameters
//	** which are assumed zero.  Other than that, the two routines are the
//	** same.
//	**
//	** Fixes or enhancements to this routine should be reflected in
//	** insertCellFast()!
//	*/
func _insertCell(tls *libc.TLS, pPage uintptr, i int32, pCell uintptr, sz int32, pTemp uintptr, iChild TPgno) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var data, pIns, v2 uintptr
	var j, rc int32
	var v1 Tu8
	var _ /* idx at bp+0 */ int32
	var _ /* rc2 at bp+4 */ int32
	_, _, _, _, _, _ = data, j, pIns, rc, v1, v2
	**(**int32)(__ccgo_up(bp)) = 0 /* The point in pPage->aCellIdx[] where no cell inserted */
	if (*TMemPage)(unsafe.Pointer(pPage)).FnOverflow != 0 || sz+int32(2) > (*TMemPage)(unsafe.Pointer(pPage)).FnFree {
		if pTemp != 0 {
			libc.Xmemcpy(tls, pTemp, pCell, libc.Uint64FromInt32(sz))
			pCell = pTemp
		}
		_sqlite3Put4byte(tls, pCell, iChild)
		v2 = pPage + 12
		v1 = *(*Tu8)(unsafe.Pointer(v2))
		*(*Tu8)(unsafe.Pointer(v2)) = *(*Tu8)(unsafe.Pointer(v2)) + 1
		j = libc.Int32FromUint8(v1)
		/* Comparison against ArraySize-1 since we hold back one extra slot
		 ** as a contingency.  In other words, never need more than 3 overflow
		 ** slots but 4 are allocated, just to be safe. */
		**(**uintptr)(__ccgo_up(pPage + 40 + uintptr(j)*8)) = pCell
		**(**Tu16)(__ccgo_up(pPage + 28 + uintptr(j)*2)) = libc.Uint16FromInt32(i)
		/* When multiple overflows occur, they are always sequential and in
		 ** sorted order.  This invariants arise because multiple overflows can
		 ** only occur when inserting divider cells into the parent page during
		 ** balancing, and the dividers are adjacent and sorted.
		 */
		/* Overflows in sorted order */
		/* Overflows are sequential */
	} else {
		rc = _sqlite3PagerWrite(tls, (*TMemPage)(unsafe.Pointer(pPage)).FpDbPage)
		if rc != SQLITE_OK {
			return rc
		}
		data = (*TMemPage)(unsafe.Pointer(pPage)).FaData
		rc = _allocateSpace(tls, pPage, sz, bp)
		if rc != 0 {
			return rc
		}
		/* The allocateSpace() routine guarantees the following properties
		 ** if it returns successfully */
		**(**int32)(__ccgo_up(pPage + 20)) -= libc.Int32FromUint16(libc.Uint16FromInt32(libc.Int32FromInt32(2) + sz))
		/* In a corrupt database where an entry in the cell index section of
		 ** a btree page has a value of 3 or less, the pCell value might point
		 ** as many as 4 bytes in front of the start of the aData buffer for
		 ** the source page.  Make sure this does not cause problems by not
		 ** reading the first 4 bytes */
		libc.Xmemcpy(tls, data+uintptr(**(**int32)(__ccgo_up(bp))+int32(4)), pCell+uintptr(4), libc.Uint64FromInt32(sz-int32(4)))
		_sqlite3Put4byte(tls, data+uintptr(**(**int32)(__ccgo_up(bp))), iChild)
		pIns = (*TMemPage)(unsafe.Pointer(pPage)).FaCellIdx + uintptr(i*int32(2))
		libc.Xmemmove(tls, pIns+uintptr(2), pIns, libc.Uint64FromInt32(int32(2)*(libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FnCell)-i)))
		**(**Tu8)(__ccgo_up(pIns)) = libc.Uint8FromInt32(**(**int32)(__ccgo_up(bp)) >> libc.Int32FromInt32(8))
		**(**Tu8)(__ccgo_up(pIns + 1)) = libc.Uint8FromInt32(**(**int32)(__ccgo_up(bp)))
		(*TMemPage)(unsafe.Pointer(pPage)).FnCell = (*TMemPage)(unsafe.Pointer(pPage)).FnCell + 1
		/* increment the cell count */
		v2 = data + uintptr(libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pPage)).FhdrOffset)+int32(4))
		*(*Tu8)(unsafe.Pointer(v2)) = *(*Tu8)(unsafe.Pointer(v2)) + 1
		v1 = *(*Tu8)(unsafe.Pointer(v2))
		if libc.Int32FromUint8(v1) == 0 {
			**(**Tu8)(__ccgo_up(data + uintptr(libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pPage)).FhdrOffset)+int32(3)))) = **(**Tu8)(__ccgo_up(data + uintptr(libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pPage)).FhdrOffset)+int32(3)))) + 1
		}
		if (*TBtShared)(unsafe.Pointer((*TMemPage)(unsafe.Pointer(pPage)).FpBt)).FautoVacuum != 0 {
			**(**int32)(__ccgo_up(bp + 4)) = SQLITE_OK
			/* The cell may contain a pointer to an overflow page. If so, write
			 ** the entry for the overflow page into the pointer map.
			 */
			_ptrmapPutOvflPtr(tls, pPage, pPage, pCell, bp+4)
			if **(**int32)(__ccgo_up(bp + 4)) != 0 {
				return **(**int32)(__ccgo_up(bp + 4))
			}
		}
	}
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** This variant of insertCell() assumes that the pTemp and iChild
//	** parameters are both zero.  Use this variant in sqlite3BtreeInsert()
//	** for performance improvement, and also so that this variant is only
//	** called from that one place, and is thus inlined, and thus runs must
//	** faster.
//	**
//	** Fixes or enhancements to this routine should be reflected into
//	** the insertCell() routine.
//	*/
func _insertCellFast(tls *libc.TLS, pPage uintptr, i int32, pCell uintptr, sz int32) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var data, pIns, v2 uintptr
	var j, rc int32
	var v1 Tu8
	var _ /* idx at bp+0 */ int32
	var _ /* rc2 at bp+4 */ int32
	_, _, _, _, _, _ = data, j, pIns, rc, v1, v2
	**(**int32)(__ccgo_up(bp)) = 0 /* The point in pPage->aCellIdx[] where no cell inserted */
	if sz+int32(2) > (*TMemPage)(unsafe.Pointer(pPage)).FnFree {
		v2 = pPage + 12
		v1 = *(*Tu8)(unsafe.Pointer(v2))
		*(*Tu8)(unsafe.Pointer(v2)) = *(*Tu8)(unsafe.Pointer(v2)) + 1
		j = libc.Int32FromUint8(v1)
		/* Comparison against ArraySize-1 since we hold back one extra slot
		 ** as a contingency.  In other words, never need more than 3 overflow
		 ** slots but 4 are allocated, just to be safe. */
		**(**uintptr)(__ccgo_up(pPage + 40 + uintptr(j)*8)) = pCell
		**(**Tu16)(__ccgo_up(pPage + 28 + uintptr(j)*2)) = libc.Uint16FromInt32(i)
		/* When multiple overflows occur, they are always sequential and in
		 ** sorted order.  This invariants arise because multiple overflows can
		 ** only occur when inserting divider cells into the parent page during
		 ** balancing, and the dividers are adjacent and sorted.
		 */
		/* Overflows in sorted order */
		/* Overflows are sequential */
	} else {
		rc = _sqlite3PagerWrite(tls, (*TMemPage)(unsafe.Pointer(pPage)).FpDbPage)
		if rc != SQLITE_OK {
			return rc
		}
		data = (*TMemPage)(unsafe.Pointer(pPage)).FaData
		rc = _allocateSpace(tls, pPage, sz, bp)
		if rc != 0 {
			return rc
		}
		/* The allocateSpace() routine guarantees the following properties
		 ** if it returns successfully */
		**(**int32)(__ccgo_up(pPage + 20)) -= libc.Int32FromUint16(libc.Uint16FromInt32(libc.Int32FromInt32(2) + sz))
		libc.Xmemcpy(tls, data+uintptr(**(**int32)(__ccgo_up(bp))), pCell, libc.Uint64FromInt32(sz))
		pIns = (*TMemPage)(unsafe.Pointer(pPage)).FaCellIdx + uintptr(i*int32(2))
		libc.Xmemmove(tls, pIns+uintptr(2), pIns, libc.Uint64FromInt32(int32(2)*(libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FnCell)-i)))
		**(**Tu8)(__ccgo_up(pIns)) = libc.Uint8FromInt32(**(**int32)(__ccgo_up(bp)) >> libc.Int32FromInt32(8))
		**(**Tu8)(__ccgo_up(pIns + 1)) = libc.Uint8FromInt32(**(**int32)(__ccgo_up(bp)))
		(*TMemPage)(unsafe.Pointer(pPage)).FnCell = (*TMemPage)(unsafe.Pointer(pPage)).FnCell + 1
		/* increment the cell count */
		v2 = data + uintptr(libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pPage)).FhdrOffset)+int32(4))
		*(*Tu8)(unsafe.Pointer(v2)) = *(*Tu8)(unsafe.Pointer(v2)) + 1
		v1 = *(*Tu8)(unsafe.Pointer(v2))
		if libc.Int32FromUint8(v1) == 0 {
			**(**Tu8)(__ccgo_up(data + uintptr(libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pPage)).FhdrOffset)+int32(3)))) = **(**Tu8)(__ccgo_up(data + uintptr(libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pPage)).FhdrOffset)+int32(3)))) + 1
		}
		if (*TBtShared)(unsafe.Pointer((*TMemPage)(unsafe.Pointer(pPage)).FpBt)).FautoVacuum != 0 {
			**(**int32)(__ccgo_up(bp + 4)) = SQLITE_OK
			/* The cell may contain a pointer to an overflow page. If so, write
			 ** the entry for the overflow page into the pointer map.
			 */
			_ptrmapPutOvflPtr(tls, pPage, pPage, pCell, bp+4)
			if **(**int32)(__ccgo_up(bp + 4)) != 0 {
				return **(**int32)(__ccgo_up(bp + 4))
			}
		}
	}
	return SQLITE_OK
}

/*
** The following parameters determine how many adjacent pages get involved
** in a balancing operation.  NN is the number of neighbors on either side
** of the page that participate in the balancing operation.  NB is the
** total number of pages that participate, including the target page and
** NN neighbors on either side.
**
** The minimum value of NN is 1 (of course).  Increasing NN above 1
** (to 2 or 3) gives a modest improvement in SELECT and DELETE performance
** in exchange for a larger degradation in INSERT and UPDATE performance.
** The value of NN appears to give the best results overall.
**
** (Later:) The description above makes it seem as if these values are
** tunable - as if you could change them and recompile and it would all work.
** But that is unlikely.  NB has been 3 since the inception of SQLite and
** we have never tested any other value.
 */

// C documentation
//
//	/* Append a node type byte together with the payload size and
//	** possibly also the payload.
//	**
//	** If aPayload is not NULL, then it is a pointer to the payload which
//	** is also appended.  If aPayload is NULL, the pParse->aBlob[] array
//	** is resized (if necessary) so that it is big enough to hold the
//	** payload, but the payload is not appended and pParse->nBlob is left
//	** pointing to where the first byte of payload will eventually be.
//	*/
func _jsonBlobAppendNode(tls *libc.TLS, pParse uintptr, eType Tu8, szPayload Tu64, aPayload uintptr) {
	var a, v1 uintptr
	_, _ = a, v1
	if uint64((*TJsonParse)(unsafe.Pointer(pParse)).FnBlob)+szPayload+uint64(9) > uint64((*TJsonParse)(unsafe.Pointer(pParse)).FnBlobAlloc) {
		_jsonBlobExpandAndAppendNode(tls, pParse, eType, szPayload, aPayload)
		return
	}
	a = (*TJsonParse)(unsafe.Pointer(pParse)).FaBlob + uintptr((*TJsonParse)(unsafe.Pointer(pParse)).FnBlob)
	if szPayload <= uint64(11) {
		**(**Tu8)(__ccgo_up(a)) = uint8(uint64(eType) | szPayload<<libc.Int32FromInt32(4))
		**(**Tu32)(__ccgo_up(pParse + 8)) += uint32(1)
	} else {
		if szPayload <= uint64(0xff) {
			**(**Tu8)(__ccgo_up(a)) = libc.Uint8FromInt32(libc.Int32FromUint8(eType) | int32(0xc0))
			**(**Tu8)(__ccgo_up(a + 1)) = uint8(szPayload & uint64(0xff))
			**(**Tu32)(__ccgo_up(pParse + 8)) += uint32(2)
		} else {
			if szPayload <= uint64(0xffff) {
				**(**Tu8)(__ccgo_up(a)) = libc.Uint8FromInt32(libc.Int32FromUint8(eType) | int32(0xd0))
				**(**Tu8)(__ccgo_up(a + 1)) = uint8(szPayload >> libc.Int32FromInt32(8) & uint64(0xff))
				**(**Tu8)(__ccgo_up(a + 2)) = uint8(szPayload & uint64(0xff))
				**(**Tu32)(__ccgo_up(pParse + 8)) += uint32(3)
			} else {
				**(**Tu8)(__ccgo_up(a)) = libc.Uint8FromInt32(libc.Int32FromUint8(eType) | int32(0xe0))
				**(**Tu8)(__ccgo_up(a + 1)) = uint8(szPayload >> libc.Int32FromInt32(24) & uint64(0xff))
				**(**Tu8)(__ccgo_up(a + 2)) = uint8(szPayload >> libc.Int32FromInt32(16) & uint64(0xff))
				**(**Tu8)(__ccgo_up(a + 3)) = uint8(szPayload >> libc.Int32FromInt32(8) & uint64(0xff))
				**(**Tu8)(__ccgo_up(a + 4)) = uint8(szPayload & uint64(0xff))
				**(**Tu32)(__ccgo_up(pParse + 8)) += uint32(5)
			}
		}
	}
	if aPayload != 0 {
		v1 = pParse + 8
		*(*Tu32)(unsafe.Pointer(v1)) = Tu32(uint64(*(*Tu32)(unsafe.Pointer(v1))) + szPayload)
		libc.Xmemcpy(tls, (*TJsonParse)(unsafe.Pointer(pParse)).FaBlob+uintptr(uint64((*TJsonParse)(unsafe.Pointer(pParse)).FnBlob)-szPayload), aPayload, szPayload)
	}
}

// C documentation
//
//	/* Change the payload size for the node at index i to be szPayload.
//	*/
func _jsonBlobChangePayloadSize(tls *libc.TLS, pParse uintptr, i Tu32, szPayload Tu32) (r int32) {
	var a uintptr
	var delta int32
	var nExtra, nNeeded, szType Tu8
	var newSize Tu32
	_, _, _, _, _, _ = a, delta, nExtra, nNeeded, newSize, szType
	if (*TJsonParse)(unsafe.Pointer(pParse)).Foom != 0 {
		return 0
	}
	a = (*TJsonParse)(unsafe.Pointer(pParse)).FaBlob + uintptr(i)
	szType = libc.Uint8FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up(a))) >> int32(4))
	if libc.Int32FromUint8(szType) <= int32(11) {
		nExtra = uint8(0)
	} else {
		if libc.Int32FromUint8(szType) == int32(12) {
			nExtra = uint8(1)
		} else {
			if libc.Int32FromUint8(szType) == int32(13) {
				nExtra = uint8(2)
			} else {
				if libc.Int32FromUint8(szType) == int32(14) {
					nExtra = uint8(4)
				} else {
					nExtra = uint8(8)
				}
			}
		}
	}
	if szPayload <= uint32(11) {
		nNeeded = uint8(0)
	} else {
		if szPayload <= uint32(0xff) {
			nNeeded = uint8(1)
		} else {
			if szPayload <= uint32(0xffff) {
				nNeeded = uint8(2)
			} else {
				nNeeded = uint8(4)
			}
		}
	}
	delta = libc.Int32FromUint8(nNeeded) - libc.Int32FromUint8(nExtra)
	if delta != 0 {
		newSize = (*TJsonParse)(unsafe.Pointer(pParse)).FnBlob + libc.Uint32FromInt32(delta)
		if delta > 0 {
			if newSize > (*TJsonParse)(unsafe.Pointer(pParse)).FnBlobAlloc && _jsonBlobExpand(tls, pParse, newSize) != 0 {
				return 0 /* OOM error.  Error state recorded in pParse->oom. */
			}
			a = (*TJsonParse)(unsafe.Pointer(pParse)).FaBlob + uintptr(i)
			libc.Xmemmove(tls, a+uintptr(int32(1)+delta), a+1, uint64((*TJsonParse)(unsafe.Pointer(pParse)).FnBlob-(i+uint32(1))))
		} else {
			libc.Xmemmove(tls, a+1, a+uintptr(int32(1)-delta), uint64((*TJsonParse)(unsafe.Pointer(pParse)).FnBlob-(i+uint32(1)-libc.Uint32FromInt32(delta))))
		}
		(*TJsonParse)(unsafe.Pointer(pParse)).FnBlob = newSize
	}
	if libc.Int32FromUint8(nNeeded) == 0 {
		**(**Tu8)(__ccgo_up(a)) = uint8(libc.Uint32FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up(a)))&libc.Int32FromInt32(0x0f)) | szPayload<<libc.Int32FromInt32(4))
	} else {
		if libc.Int32FromUint8(nNeeded) == int32(1) {
			**(**Tu8)(__ccgo_up(a)) = libc.Uint8FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up(a)))&int32(0x0f) | int32(0xc0))
			**(**Tu8)(__ccgo_up(a + 1)) = uint8(szPayload & uint32(0xff))
		} else {
			if libc.Int32FromUint8(nNeeded) == int32(2) {
				**(**Tu8)(__ccgo_up(a)) = libc.Uint8FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up(a)))&int32(0x0f) | int32(0xd0))
				**(**Tu8)(__ccgo_up(a + 1)) = uint8(szPayload >> libc.Int32FromInt32(8) & uint32(0xff))
				**(**Tu8)(__ccgo_up(a + 2)) = uint8(szPayload & uint32(0xff))
			} else {
				**(**Tu8)(__ccgo_up(a)) = libc.Uint8FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up(a)))&int32(0x0f) | int32(0xe0))
				**(**Tu8)(__ccgo_up(a + 1)) = uint8(szPayload >> libc.Int32FromInt32(24) & uint32(0xff))
				**(**Tu8)(__ccgo_up(a + 2)) = uint8(szPayload >> libc.Int32FromInt32(16) & uint32(0xff))
				**(**Tu8)(__ccgo_up(a + 3)) = uint8(szPayload >> libc.Int32FromInt32(8) & uint32(0xff))
				**(**Tu8)(__ccgo_up(a + 4)) = uint8(szPayload & uint32(0xff))
			}
		}
	}
	return delta
}

// C documentation
//
//	/*
//	** Modify the JSONB blob at pParse->aBlob by removing nDel bytes of
//	** content beginning at iDel, and replacing them with nIns bytes of
//	** content given by aIns.
//	**
//	** nDel may be zero, in which case no bytes are removed.  But iDel is
//	** still important as new bytes will be insert beginning at iDel.
//	**
//	** aIns may be zero, in which case space is created to hold nIns bytes
//	** beginning at iDel, but that space is uninitialized.
//	**
//	** Set pParse->oom if an OOM occurs.
//	*/
func _jsonBlobEdit(tls *libc.TLS, pParse uintptr, iDel Tu32, nDel Tu32, aIns uintptr, nIns Tu32) {
	var d Ti64
	var v1 uintptr
	_, _ = d, v1
	d = libc.Int64FromUint32(nIns) - libc.Int64FromUint32(nDel)
	if d < 0 && d >= int64(-libc.Int32FromInt32(8)) && aIns != uintptr(0) && _jsonBlobOverwrite(tls, (*TJsonParse)(unsafe.Pointer(pParse)).FaBlob+uintptr(iDel), aIns, nIns, libc.Uint32FromInt32(int32(-d))) != 0 {
		return
	}
	if d != 0 {
		if libc.Int64FromUint32((*TJsonParse)(unsafe.Pointer(pParse)).FnBlob)+d > libc.Int64FromUint32((*TJsonParse)(unsafe.Pointer(pParse)).FnBlobAlloc) {
			_jsonBlobExpand(tls, pParse, libc.Uint32FromInt64(libc.Int64FromUint32((*TJsonParse)(unsafe.Pointer(pParse)).FnBlob)+d))
			if (*TJsonParse)(unsafe.Pointer(pParse)).Foom != 0 {
				return
			}
		}
		libc.Xmemmove(tls, (*TJsonParse)(unsafe.Pointer(pParse)).FaBlob+uintptr(iDel+nIns), (*TJsonParse)(unsafe.Pointer(pParse)).FaBlob+uintptr(iDel+nDel), uint64((*TJsonParse)(unsafe.Pointer(pParse)).FnBlob-(iDel+nDel)))
		v1 = pParse + 8
		*(*Tu32)(unsafe.Pointer(v1)) = Tu32(int64(*(*Tu32)(unsafe.Pointer(v1))) + d)
		v1 = pParse + 52
		*(*int32)(unsafe.Pointer(v1)) = int32(int64(*(*int32)(unsafe.Pointer(v1))) + d)
	}
	if nIns != 0 && aIns != 0 {
		libc.Xmemcpy(tls, (*TJsonParse)(unsafe.Pointer(pParse)).FaBlob+uintptr(iDel), aIns, uint64(nIns))
	}
}

// C documentation
//
//	/*
//	** If the JSONB at aIns[0..nIns-1] can be expanded (by denormalizing the
//	** size field) by d bytes, then write the expansion into aOut[] and
//	** return true.  In this way, an overwrite happens without changing the
//	** size of the JSONB, which reduces memcpy() operations and also make it
//	** faster and easier to update the B-Tree entry that contains the JSONB
//	** in the database.
//	**
//	** If the expansion of aIns[] by d bytes cannot be (easily) accomplished
//	** then return false.
//	**
//	** The d parameter is guaranteed to be between 1 and 8.
//	**
//	** This routine is an optimization.  A correct answer is obtained if it
//	** always leaves the output unchanged and returns false.
//	*/
func _jsonBlobOverwrite(tls *libc.TLS, aOut uintptr, aIns uintptr, nIns Tu32, d Tu32) (r int32) {
	var i, szPayload Tu32
	var szHdr Tu8
	_, _, _ = i, szHdr, szPayload /* Size of header before expansion */
	if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aIns)))&int32(0x0f) <= int32(2) {
		return 0
	} /* Cannot enlarge NULL, true, false */
	switch libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aIns))) >> libc.Int32FromInt32(4) {
	default: /* aIns[] header size 1 */
		if int32(1)<<d&int32(0x116) == 0 {
			return 0
		} /* d must be 1, 2, 4, or 8 */
		i = d + uint32(1) /* New hdr sz: 2, 3, 5, or 9 */
		szHdr = uint8(1)
	case int32(12): /* aIns[] header size is 2 */
		if int32(1)<<d&int32(0x8a) == 0 {
			return 0
		} /* d must be 1, 3, or 7 */
		i = d + uint32(2) /* New hdr sz: 2, 5, or 9 */
		szHdr = uint8(2)
	case int32(13): /* aIns[] header size is 3 */
		if d != uint32(2) && d != uint32(6) {
			return 0
		} /* d must be 2 or 6 */
		i = d + uint32(3) /* New hdr sz: 5 or 9 */
		szHdr = uint8(3)
	case int32(14): /* aIns[] header size is 5 */
		if d != uint32(4) {
			return 0
		} /* d must be 4 */
		i = uint32(9) /* New hdr sz: 9 */
		szHdr = uint8(5)
	case int32(15): /* aIns[] header size is 9 */
		return 0 /* No solution */
	}
	**(**Tu8)(__ccgo_up(aOut)) = libc.Uint8FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aIns)))&int32(0x0f) | libc.Int32FromUint8(_aType1[i-uint32(2)]))
	libc.Xmemcpy(tls, aOut+uintptr(i), aIns+uintptr(szHdr), uint64(nIns-uint32(szHdr)))
	szPayload = nIns - uint32(szHdr)
	for int32(1) != 0 {
		i = i - 1
		**(**Tu8)(__ccgo_up(aOut + uintptr(i))) = uint8(szPayload & uint32(0xff))
		if i == uint32(1) {
			break
		}
		szPayload = szPayload >> uint32(8)
	}
	return int32(1)
}

// C documentation
//
//	/*
//	** Insert a new entry into the cache.  If the cache is full, expel
//	** the least recently used entry.  Return SQLITE_OK on success or a
//	** result code otherwise.
//	**
//	** Cache entries are stored in age order, oldest first.
//	*/
func _jsonCacheInsert(tls *libc.TLS, ctx uintptr, pParse uintptr) (r int32) {
	var db, p uintptr
	_, _ = db, p
	p = Xsqlite3_get_auxdata(tls, ctx, -int32(429938))
	if p == uintptr(0) {
		db = Xsqlite3_context_db_handle(tls, ctx)
		p = _sqlite3DbMallocZero(tls, db, uint64(48))
		if p == uintptr(0) {
			return int32(SQLITE_NOMEM)
		}
		(*TJsonCache)(unsafe.Pointer(p)).Fdb = db
		Xsqlite3_set_auxdata(tls, ctx, -int32(429938), p, __ccgo_fp(_jsonCacheDeleteGeneric))
		p = Xsqlite3_get_auxdata(tls, ctx, -int32(429938))
		if p == uintptr(0) {
			return int32(SQLITE_NOMEM)
		}
	}
	if (*TJsonCache)(unsafe.Pointer(p)).FnUsed >= int32(JSON_CACHE_SIZE) {
		_jsonParseFree(tls, **(**uintptr)(__ccgo_up(p + 16)))
		libc.Xmemmove(tls, p+16, p+16+1*8, libc.Uint64FromInt32(libc.Int32FromInt32(JSON_CACHE_SIZE)-libc.Int32FromInt32(1))*libc.Uint64FromInt64(8))
		(*TJsonCache)(unsafe.Pointer(p)).FnUsed = libc.Int32FromInt32(JSON_CACHE_SIZE) - libc.Int32FromInt32(1)
	}
	(*TJsonParse)(unsafe.Pointer(pParse)).FeEdit = uint8(0)
	(*TJsonParse)(unsafe.Pointer(pParse)).FnJPRef = (*TJsonParse)(unsafe.Pointer(pParse)).FnJPRef + 1
	(*TJsonParse)(unsafe.Pointer(pParse)).FbReadOnly = uint8(1)
	**(**uintptr)(__ccgo_up(p + 16 + uintptr((*TJsonCache)(unsafe.Pointer(p)).FnUsed)*8)) = pParse
	(*TJsonCache)(unsafe.Pointer(p)).FnUsed = (*TJsonCache)(unsafe.Pointer(p)).FnUsed + 1
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** Search for a cached translation the json text supplied by pArg.  Return
//	** the JsonParse object if found.  Return NULL if not found.
//	**
//	** When a match if found, the matching entry is moved to become the
//	** most-recently used entry if it isn't so already.
//	**
//	** The JsonParse object returned still belongs to the Cache and might
//	** be deleted at any moment.  If the caller wants the JsonParse to
//	** linger, it needs to increment the nPJRef reference counter.
//	*/
func _jsonCacheSearch(tls *libc.TLS, ctx uintptr, pArg uintptr) (r uintptr) {
	var i, nJson int32
	var p, tmp, zJson uintptr
	_, _, _, _, _ = i, nJson, p, tmp, zJson
	if Xsqlite3_value_type(tls, pArg) != int32(SQLITE_TEXT) {
		return uintptr(0)
	}
	zJson = Xsqlite3_value_text(tls, pArg)
	if zJson == uintptr(0) {
		return uintptr(0)
	}
	nJson = Xsqlite3_value_bytes(tls, pArg)
	p = Xsqlite3_get_auxdata(tls, ctx, -int32(429938))
	if p == uintptr(0) {
		return uintptr(0)
	}
	i = 0
	for {
		if !(i < (*TJsonCache)(unsafe.Pointer(p)).FnUsed) {
			break
		}
		if (*TJsonParse)(unsafe.Pointer(**(**uintptr)(__ccgo_up(p + 16 + uintptr(i)*8)))).FzJson == zJson {
			break
		}
		goto _1
	_1:
		;
		i = i + 1
	}
	if i >= (*TJsonCache)(unsafe.Pointer(p)).FnUsed {
		i = 0
		for {
			if !(i < (*TJsonCache)(unsafe.Pointer(p)).FnUsed) {
				break
			}
			if (*TJsonParse)(unsafe.Pointer(**(**uintptr)(__ccgo_up(p + 16 + uintptr(i)*8)))).FnJson != nJson {
				goto _2
			}
			if libc.Xmemcmp(tls, (*TJsonParse)(unsafe.Pointer(**(**uintptr)(__ccgo_up(p + 16 + uintptr(i)*8)))).FzJson, zJson, libc.Uint64FromInt32(nJson)) == 0 {
				break
			}
			goto _2
		_2:
			;
			i = i + 1
		}
	}
	if i < (*TJsonCache)(unsafe.Pointer(p)).FnUsed {
		if i < (*TJsonCache)(unsafe.Pointer(p)).FnUsed-int32(1) {
			/* Make the matching entry the most recently used entry */
			tmp = **(**uintptr)(__ccgo_up(p + 16 + uintptr(i)*8))
			libc.Xmemmove(tls, p+16+uintptr(i)*8, p+16+uintptr(i+int32(1))*8, libc.Uint64FromInt32((*TJsonCache)(unsafe.Pointer(p)).FnUsed-i-libc.Int32FromInt32(1))*uint64(8))
			**(**uintptr)(__ccgo_up(p + 16 + uintptr((*TJsonCache)(unsafe.Pointer(p)).FnUsed-int32(1))*8)) = tmp
			i = (*TJsonCache)(unsafe.Pointer(p)).FnUsed - int32(1)
		}
		return **(**uintptr)(__ccgo_up(p + 16 + uintptr(i)*8))
	} else {
		return uintptr(0)
	}
	return r
}

/**************************************************************************
** Utility routines for dealing with JsonString objects
**************************************************************************/

// C documentation
//
//	/*
//	** RFC-7396 MergePatch for two JSONB blobs.
//	**
//	** pTarget is the target. pPatch is the patch.  The target is updated
//	** in place.  The patch is read-only.
//	**
//	** The original RFC-7396 algorithm is this:
//	**
//	**   define MergePatch(Target, Patch):
//	**     if Patch is an Object:
//	**       if Target is not an Object:
//	**         Target = {} # Ignore the contents and set it to an empty Object
//	**     for each Name/Value pair in Patch:
//	**         if Value is null:
//	**           if Name exists in Target:
//	**             remove the Name/Value pair from Target
//	**         else:
//	**           Target[Name] = MergePatch(Target[Name], Value)
//	**       return Target
//	**     else:
//	**       return Patch
//	**
//	** Here is an equivalent algorithm restructured to show the actual
//	** implementation:
//	**
//	** 01   define MergePatch(Target, Patch):
//	** 02      if Patch is not an Object:
//	** 03         return Patch
//	** 04      else: // if Patch is an Object
//	** 05         if Target is not an Object:
//	** 06            Target = {}
//	** 07      for each Name/Value pair in Patch:
//	** 08         if Name exists in Target:
//	** 09            if Value is null:
//	** 10               remove the Name/Value pair from Target
//	** 11            else
//	** 12               Target[name] = MergePatch(Target[Name], Value)
//	** 13         else if Value is not NULL:
//	** 14            if Value is not an Object:
//	** 15               Target[name] = Value
//	** 16            else:
//	** 17               Target[name] = MergePatch('{}',value)
//	** 18      return Target
//	**  |
//	**  ^---- Line numbers referenced in comments in the implementation
//	*/
func _jsonMergePatch(tls *libc.TLS, pTarget uintptr, iTarget Tu32, pPatch uintptr, iPatch Tu32, iDepth Tu32) (r int32) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var ePLabel, eTLabel, x Tu8
	var iPCursor, iPEnd, iPLabel, iPValue, iTCursor, iTEnd, iTEndBE, iTLabel, iTStart, iTValue, n, nPLabel, nPValue, nTLabel, nTValue, szNew, szPatch, szTarget Tu32
	var isEqual, rc, rc1, savedDelta, savedDelta1, v1 int32
	var _ /* sz at bp+0 */ Tu32
	var _ /* szPLabel at bp+12 */ Tu32
	var _ /* szPValue at bp+16 */ Tu32
	var _ /* szTLabel at bp+4 */ Tu32
	var _ /* szTValue at bp+8 */ Tu32
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = ePLabel, eTLabel, iPCursor, iPEnd, iPLabel, iPValue, iTCursor, iTEnd, iTEndBE, iTLabel, iTStart, iTValue, isEqual, n, nPLabel, nPValue, nTLabel, nTValue, rc, rc1, savedDelta, savedDelta1, szNew, szPatch, szTarget, x, v1
	**(**Tu32)(__ccgo_up(bp)) = uint32(0)     /* Node type of the target label */
	iTLabel = uint32(0)                       /* Index of the label */
	nTLabel = uint32(0)                       /* Header size in bytes for the target label */
	**(**Tu32)(__ccgo_up(bp + 4)) = uint32(0) /* Size of the target label payload */
	iTValue = uint32(0)                       /* Index of the target value */
	nTValue = uint32(0)                       /* Header size of the target value */
	**(**Tu32)(__ccgo_up(bp + 8)) = uint32(0) /* Payload size of the patch value */
	x = libc.Uint8FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TJsonParse)(unsafe.Pointer(pPatch)).FaBlob + uintptr(iPatch)))) & int32(0x0f))
	if libc.Int32FromUint8(x) != int32(JSONB_OBJECT) { /* Total size of the target, header+payload */
		n = _jsonbPayloadSize(tls, pPatch, iPatch, bp)
		szPatch = n + **(**Tu32)(__ccgo_up(bp))
		**(**Tu32)(__ccgo_up(bp)) = uint32(0)
		n = _jsonbPayloadSize(tls, pTarget, iTarget, bp)
		szTarget = n + **(**Tu32)(__ccgo_up(bp))
		_jsonBlobEdit(tls, pTarget, iTarget, szTarget, (*TJsonParse)(unsafe.Pointer(pPatch)).FaBlob+uintptr(iPatch), szPatch)
		if (*TJsonParse)(unsafe.Pointer(pTarget)).Foom != 0 {
			v1 = int32(JSON_MERGE_OOM)
		} else {
			v1 = JSON_MERGE_OK
		}
		return v1 /* Line 03 */
	}
	x = libc.Uint8FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TJsonParse)(unsafe.Pointer(pTarget)).FaBlob + uintptr(iTarget)))) & int32(0x0f))
	if libc.Int32FromUint8(x) != int32(JSONB_OBJECT) { /* Algorithm line 05 */
		n = _jsonbPayloadSize(tls, pTarget, iTarget, bp)
		_jsonBlobEdit(tls, pTarget, iTarget+n, **(**Tu32)(__ccgo_up(bp)), uintptr(0), uint32(0))
		x = **(**Tu8)(__ccgo_up((*TJsonParse)(unsafe.Pointer(pTarget)).FaBlob + uintptr(iTarget)))
		**(**Tu8)(__ccgo_up((*TJsonParse)(unsafe.Pointer(pTarget)).FaBlob + uintptr(iTarget))) = libc.Uint8FromInt32(libc.Int32FromUint8(x)&int32(0xf0) | int32(JSONB_OBJECT))
	}
	n = _jsonbPayloadSize(tls, pPatch, iPatch, bp)
	if n == uint32(0) {
		return int32(JSON_MERGE_BADPATCH)
	}
	iPCursor = iPatch + n
	iPEnd = iPCursor + **(**Tu32)(__ccgo_up(bp))
	n = _jsonbPayloadSize(tls, pTarget, iTarget, bp)
	if n == uint32(0) {
		return int32(JSON_MERGE_BADTARGET)
	}
	iTStart = iTarget + n
	iTEndBE = iTStart + **(**Tu32)(__ccgo_up(bp))
	for iPCursor < iPEnd { /* Algorithm line 07 */
		iPLabel = iPCursor
		ePLabel = libc.Uint8FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TJsonParse)(unsafe.Pointer(pPatch)).FaBlob + uintptr(iPCursor)))) & int32(0x0f))
		if libc.Int32FromUint8(ePLabel) < int32(JSONB_TEXT) || libc.Int32FromUint8(ePLabel) > int32(JSONB_TEXTRAW) {
			return int32(JSON_MERGE_BADPATCH)
		}
		nPLabel = _jsonbPayloadSize(tls, pPatch, iPCursor, bp+12)
		if nPLabel == uint32(0) {
			return int32(JSON_MERGE_BADPATCH)
		}
		iPValue = iPCursor + nPLabel + **(**Tu32)(__ccgo_up(bp + 12))
		if iPValue >= iPEnd {
			return int32(JSON_MERGE_BADPATCH)
		}
		nPValue = _jsonbPayloadSize(tls, pPatch, iPValue, bp+16)
		if nPValue == uint32(0) {
			return int32(JSON_MERGE_BADPATCH)
		}
		iPCursor = iPValue + nPValue + **(**Tu32)(__ccgo_up(bp + 16))
		if iPCursor > iPEnd {
			return int32(JSON_MERGE_BADPATCH)
		}
		iTCursor = iTStart
		iTEnd = iTEndBE + libc.Uint32FromInt32((*TJsonParse)(unsafe.Pointer(pTarget)).Fdelta)
		for iTCursor < iTEnd { /* true if the patch and target labels match */
			iTLabel = iTCursor
			eTLabel = libc.Uint8FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TJsonParse)(unsafe.Pointer(pTarget)).FaBlob + uintptr(iTCursor)))) & int32(0x0f))
			if libc.Int32FromUint8(eTLabel) < int32(JSONB_TEXT) || libc.Int32FromUint8(eTLabel) > int32(JSONB_TEXTRAW) {
				return int32(JSON_MERGE_BADTARGET)
			}
			nTLabel = _jsonbPayloadSize(tls, pTarget, iTCursor, bp+4)
			if nTLabel == uint32(0) {
				return int32(JSON_MERGE_BADTARGET)
			}
			iTValue = iTLabel + nTLabel + **(**Tu32)(__ccgo_up(bp + 4))
			if iTValue >= iTEnd {
				return int32(JSON_MERGE_BADTARGET)
			}
			nTValue = _jsonbPayloadSize(tls, pTarget, iTValue, bp+8)
			if nTValue == uint32(0) {
				return int32(JSON_MERGE_BADTARGET)
			}
			if iTValue+nTValue+**(**Tu32)(__ccgo_up(bp + 8)) > iTEnd {
				return int32(JSON_MERGE_BADTARGET)
			}
			isEqual = _jsonLabelCompare(tls, (*TJsonParse)(unsafe.Pointer(pPatch)).FaBlob+uintptr(iPLabel+nPLabel), **(**Tu32)(__ccgo_up(bp + 12)), libc.BoolInt32(libc.Int32FromUint8(ePLabel) == int32(JSONB_TEXT) || libc.Int32FromUint8(ePLabel) == int32(JSONB_TEXTRAW)), (*TJsonParse)(unsafe.Pointer(pTarget)).FaBlob+uintptr(iTLabel+nTLabel), **(**Tu32)(__ccgo_up(bp + 4)), libc.BoolInt32(libc.Int32FromUint8(eTLabel) == int32(JSONB_TEXT) || libc.Int32FromUint8(eTLabel) == int32(JSONB_TEXTRAW)))
			if isEqual != 0 {
				break
			}
			iTCursor = iTValue + nTValue + **(**Tu32)(__ccgo_up(bp + 8))
		}
		x = libc.Uint8FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TJsonParse)(unsafe.Pointer(pPatch)).FaBlob + uintptr(iPValue)))) & int32(0x0f))
		if iTCursor < iTEnd {
			/* A match was found.  Algorithm line 08 */
			if libc.Int32FromUint8(x) == 0 {
				/* Patch value is NULL.  Algorithm line 09 */
				_jsonBlobEdit(tls, pTarget, iTLabel, nTLabel+**(**Tu32)(__ccgo_up(bp + 4))+nTValue+**(**Tu32)(__ccgo_up(bp + 8)), uintptr(0), uint32(0))
				/*  vvvvvv----- No OOM on a delete-only edit */
				if (*TJsonParse)(unsafe.Pointer(pTarget)).Foom != 0 {
					return int32(JSON_MERGE_OOM)
				}
			} else {
				savedDelta = (*TJsonParse)(unsafe.Pointer(pTarget)).Fdelta
				(*TJsonParse)(unsafe.Pointer(pTarget)).Fdelta = 0
				if iDepth >= uint32(JSON_MAX_DEPTH) {
					return int32(JSON_MERGE_TOODEEP)
				}
				rc = _jsonMergePatch(tls, pTarget, iTValue, pPatch, iPValue, iDepth+uint32(1))
				if rc != 0 {
					return rc
				}
				**(**int32)(__ccgo_up(pTarget + 52)) += savedDelta
			}
		} else {
			if libc.Int32FromUint8(x) > 0 { /* Algorithm line 13 */
				/* No match and patch value is not NULL */
				szNew = **(**Tu32)(__ccgo_up(bp + 12)) + nPLabel
				if libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TJsonParse)(unsafe.Pointer(pPatch)).FaBlob + uintptr(iPValue))))&int32(0x0f) != int32(JSONB_OBJECT) { /* Line 14 */
					_jsonBlobEdit(tls, pTarget, iTEnd, uint32(0), uintptr(0), **(**Tu32)(__ccgo_up(bp + 16))+nPValue+szNew)
					if (*TJsonParse)(unsafe.Pointer(pTarget)).Foom != 0 {
						return int32(JSON_MERGE_OOM)
					}
					libc.Xmemcpy(tls, (*TJsonParse)(unsafe.Pointer(pTarget)).FaBlob+uintptr(iTEnd), (*TJsonParse)(unsafe.Pointer(pPatch)).FaBlob+uintptr(iPLabel), uint64(szNew))
					libc.Xmemcpy(tls, (*TJsonParse)(unsafe.Pointer(pTarget)).FaBlob+uintptr(iTEnd+szNew), (*TJsonParse)(unsafe.Pointer(pPatch)).FaBlob+uintptr(iPValue), uint64(**(**Tu32)(__ccgo_up(bp + 16))+nPValue))
				} else {
					_jsonBlobEdit(tls, pTarget, iTEnd, uint32(0), uintptr(0), szNew+uint32(1))
					if (*TJsonParse)(unsafe.Pointer(pTarget)).Foom != 0 {
						return int32(JSON_MERGE_OOM)
					}
					libc.Xmemcpy(tls, (*TJsonParse)(unsafe.Pointer(pTarget)).FaBlob+uintptr(iTEnd), (*TJsonParse)(unsafe.Pointer(pPatch)).FaBlob+uintptr(iPLabel), uint64(szNew))
					**(**Tu8)(__ccgo_up((*TJsonParse)(unsafe.Pointer(pTarget)).FaBlob + uintptr(iTEnd+szNew))) = uint8(0x00)
					savedDelta1 = (*TJsonParse)(unsafe.Pointer(pTarget)).Fdelta
					(*TJsonParse)(unsafe.Pointer(pTarget)).Fdelta = 0
					if iDepth >= uint32(JSON_MAX_DEPTH) {
						return int32(JSON_MERGE_TOODEEP)
					}
					rc1 = _jsonMergePatch(tls, pTarget, iTEnd+szNew, pPatch, iPValue, iDepth+uint32(1))
					if rc1 != 0 {
						return rc1
					}
					**(**int32)(__ccgo_up(pTarget + 52)) += savedDelta1
				}
			}
		}
	}
	if (*TJsonParse)(unsafe.Pointer(pTarget)).Fdelta != 0 {
		_jsonAfterEditSizeAdjust(tls, pTarget, iTarget)
	}
	if (*TJsonParse)(unsafe.Pointer(pTarget)).Foom != 0 {
		v1 = int32(JSON_MERGE_OOM)
	} else {
		v1 = JSON_MERGE_OK
	}
	return v1
}

// C documentation
//
//	/*
//	** The input string pStr is a well-formed JSON text string.  Convert
//	** this into the JSONB format and make it the return value of the
//	** SQL function.
//	*/
func _jsonReturnStringAsBlob(tls *libc.TLS, pStr uintptr) {
	bp := tls.Alloc(80)
	defer tls.Free(80)
	var _ /* px at bp+0 */ TJsonParse
	libc.Xmemset(tls, bp, 0, uint64(72))
	(**(**TJsonParse)(__ccgo_up(bp))).FzJson = (*TJsonString)(unsafe.Pointer(pStr)).FzBuf
	(**(**TJsonParse)(__ccgo_up(bp))).FnJson = libc.Int32FromUint64((*TJsonString)(unsafe.Pointer(pStr)).FnUsed)
	(**(**TJsonParse)(__ccgo_up(bp))).Fdb = Xsqlite3_context_db_handle(tls, (*TJsonString)(unsafe.Pointer(pStr)).FpCtx)
	_jsonTranslateTextToBlob(tls, bp, uint32(0))
	if (**(**TJsonParse)(__ccgo_up(bp))).Foom != 0 {
		_sqlite3DbFree(tls, (**(**TJsonParse)(__ccgo_up(bp))).Fdb, (**(**TJsonParse)(__ccgo_up(bp))).FaBlob)
		Xsqlite3_result_error_nomem(tls, (*TJsonString)(unsafe.Pointer(pStr)).FpCtx)
	} else {
		Xsqlite3_result_blob(tls, (*TJsonString)(unsafe.Pointer(pStr)).FpCtx, (**(**TJsonParse)(__ccgo_up(bp))).FaBlob, libc.Int32FromUint32((**(**TJsonParse)(__ccgo_up(bp))).FnBlob), __ccgo_fp(_sqlite3RowSetClear))
	}
}

// C documentation
//
//	/*
//	** Load the content from either the sqlite_stat4
//	** into the relevant Index.aSample[] arrays.
//	**
//	** Arguments zSql1 and zSql2 must point to SQL statements that return
//	** data equivalent to the following:
//	**
//	**    zSql1: SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx
//	**    zSql2: SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4
//	**
//	** where %Q is replaced with the database name before the SQL is executed.
//	*/
func _loadStatTbl(tls *libc.TLS, db uintptr, zSql1 uintptr, zSql2 uintptr, zDb uintptr) (r int32) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var i, nByte Ti64
	var nCol, nIdxCol, nSample, rc int32
	var pIdx, pIdx1, pPrevIdx, pPtr, pSample, pSpace, zIndex, zIndex1, zSql uintptr
	var _ /* pStmt at bp+0 */ uintptr
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = i, nByte, nCol, nIdxCol, nSample, pIdx, pIdx1, pPrevIdx, pPtr, pSample, pSpace, rc, zIndex, zIndex1, zSql /* Result codes from subroutines */
	**(**uintptr)(__ccgo_up(bp)) = uintptr(0)                                                                                                               /* Text of the SQL statement */
	pPrevIdx = uintptr(0)                                                                                                                                   /* A slot in pIdx->aSample[] */
	zSql = _sqlite3MPrintf(tls, db, zSql1, libc.VaList(bp+16, zDb))
	if !(zSql != 0) {
		return int32(SQLITE_NOMEM)
	}
	rc = Xsqlite3_prepare(tls, db, zSql, -int32(1), bp, uintptr(0))
	_sqlite3DbFree(tls, db, zSql)
	if rc != 0 {
		return rc
	}
	for Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp))) == int32(SQLITE_ROW) {
		nIdxCol = int32(1) /* Available memory as a u8 for easier manipulation */
		zIndex = Xsqlite3_column_text(tls, **(**uintptr)(__ccgo_up(bp)), 0)
		if zIndex == uintptr(0) {
			continue
		}
		nSample = Xsqlite3_column_int(tls, **(**uintptr)(__ccgo_up(bp)), int32(1))
		pIdx = _findIndexOrPrimaryKey(tls, db, zIndex, zDb)
		if pIdx == uintptr(0) {
			continue
		}
		if (*TIndex)(unsafe.Pointer(pIdx)).FaSample != uintptr(0) {
			/* The same index appears in sqlite_stat4 under multiple names */
			continue
		}
		if !((*TTable)(unsafe.Pointer((*TIndex)(unsafe.Pointer(pIdx)).FpTable)).FtabFlags&libc.Uint32FromInt32(TF_WithoutRowid) == libc.Uint32FromInt32(0)) && int32(uint32(*(*uint16)(unsafe.Pointer(pIdx + 100))&0x3>>0)) == int32(SQLITE_IDXTYPE_PRIMARYKEY) {
			nIdxCol = libc.Int32FromUint16((*TIndex)(unsafe.Pointer(pIdx)).FnKeyCol)
		} else {
			nIdxCol = libc.Int32FromUint16((*TIndex)(unsafe.Pointer(pIdx)).FnColumn)
		}
		(*TIndex)(unsafe.Pointer(pIdx)).FnSampleCol = nIdxCol
		(*TIndex)(unsafe.Pointer(pIdx)).FmxSample = nSample
		nByte = libc.Int64FromUint64((libc.Uint64FromInt64(40)*libc.Uint64FromInt32(nSample) + libc.Uint64FromInt32(7)) & libc.Uint64FromInt32(^libc.Int32FromInt32(7)))
		nByte = libc.Int64FromUint64(uint64(nByte) + uint64(libc.Uint64FromInt64(8)*libc.Uint64FromInt32(nIdxCol)*libc.Uint64FromInt32(3)*libc.Uint64FromInt32(nSample)))
		nByte = libc.Int64FromUint64(uint64(nByte) + uint64(libc.Uint64FromInt32(nIdxCol)*libc.Uint64FromInt64(8))) /* Space for Index.aAvgEq[] */
		(*TIndex)(unsafe.Pointer(pIdx)).FaSample = _sqlite3DbMallocZero(tls, db, libc.Uint64FromInt64(nByte))
		if (*TIndex)(unsafe.Pointer(pIdx)).FaSample == uintptr(0) {
			Xsqlite3_finalize(tls, **(**uintptr)(__ccgo_up(bp)))
			return int32(SQLITE_NOMEM)
		}
		pPtr = (*TIndex)(unsafe.Pointer(pIdx)).FaSample
		pPtr = pPtr + uintptr((libc.Uint64FromInt32(nSample)*libc.Uint64FromInt64(40)+libc.Uint64FromInt32(7))&libc.Uint64FromInt32(^libc.Int32FromInt32(7)))
		pSpace = pPtr
		(*TIndex)(unsafe.Pointer(pIdx)).FaAvgEq = pSpace
		pSpace = pSpace + uintptr(nIdxCol)*8
		**(**Tu32)(__ccgo_up((*TIndex)(unsafe.Pointer(pIdx)).FpTable + 48)) |= uint32(TF_HasStat4)
		i = 0
		for {
			if !(i < int64(nSample)) {
				break
			}
			(**(**TIndexSample)(__ccgo_up((*TIndex)(unsafe.Pointer(pIdx)).FaSample + uintptr(i)*40))).FanEq = pSpace
			pSpace = pSpace + uintptr(nIdxCol)*8
			(**(**TIndexSample)(__ccgo_up((*TIndex)(unsafe.Pointer(pIdx)).FaSample + uintptr(i)*40))).FanLt = pSpace
			pSpace = pSpace + uintptr(nIdxCol)*8
			(**(**TIndexSample)(__ccgo_up((*TIndex)(unsafe.Pointer(pIdx)).FaSample + uintptr(i)*40))).FanDLt = pSpace
			pSpace = pSpace + uintptr(nIdxCol)*8
			goto _1
		_1:
			;
			i = i + 1
		}
	}
	rc = Xsqlite3_finalize(tls, **(**uintptr)(__ccgo_up(bp)))
	if rc != 0 {
		return rc
	}
	zSql = _sqlite3MPrintf(tls, db, zSql2, libc.VaList(bp+16, zDb))
	if !(zSql != 0) {
		return int32(SQLITE_NOMEM)
	}
	rc = Xsqlite3_prepare(tls, db, zSql, -int32(1), bp, uintptr(0))
	_sqlite3DbFree(tls, db, zSql)
	if rc != 0 {
		return rc
	}
	for Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp))) == int32(SQLITE_ROW) { /* Pointer to the index object */
		nCol = int32(1) /* Number of columns in index */
		zIndex1 = Xsqlite3_column_text(tls, **(**uintptr)(__ccgo_up(bp)), 0)
		if zIndex1 == uintptr(0) {
			continue
		}
		pIdx1 = _findIndexOrPrimaryKey(tls, db, zIndex1, zDb)
		if pIdx1 == uintptr(0) {
			continue
		}
		if (*TIndex)(unsafe.Pointer(pIdx1)).FnSample >= (*TIndex)(unsafe.Pointer(pIdx1)).FmxSample {
			/* Too many slots used because the same index appears in
			 ** sqlite_stat4 using multiple names */
			continue
		}
		/* This next condition is true if data has already been loaded from
		 ** the sqlite_stat4 table. */
		nCol = (*TIndex)(unsafe.Pointer(pIdx1)).FnSampleCol
		if pIdx1 != pPrevIdx {
			_initAvgEq(tls, pPrevIdx)
			pPrevIdx = pIdx1
		}
		pSample = (*TIndex)(unsafe.Pointer(pIdx1)).FaSample + uintptr((*TIndex)(unsafe.Pointer(pIdx1)).FnSample)*40
		_decodeIntArray(tls, Xsqlite3_column_text(tls, **(**uintptr)(__ccgo_up(bp)), int32(1)), nCol, (*TIndexSample)(unsafe.Pointer(pSample)).FanEq, uintptr(0), uintptr(0))
		_decodeIntArray(tls, Xsqlite3_column_text(tls, **(**uintptr)(__ccgo_up(bp)), int32(2)), nCol, (*TIndexSample)(unsafe.Pointer(pSample)).FanLt, uintptr(0), uintptr(0))
		_decodeIntArray(tls, Xsqlite3_column_text(tls, **(**uintptr)(__ccgo_up(bp)), int32(3)), nCol, (*TIndexSample)(unsafe.Pointer(pSample)).FanDLt, uintptr(0), uintptr(0))
		/* Take a copy of the sample. Add 8 extra 0x00 bytes the end of the buffer.
		 ** This is in case the sample record is corrupted. In that case, the
		 ** sqlite3VdbeRecordCompare() may read up to two varints past the
		 ** end of the allocated buffer before it realizes it is dealing with
		 ** a corrupt record.  Or it might try to read a large integer from the
		 ** buffer.  In any case, eight 0x00 bytes prevents this from causing
		 ** a buffer overread.  */
		(*TIndexSample)(unsafe.Pointer(pSample)).Fn = Xsqlite3_column_bytes(tls, **(**uintptr)(__ccgo_up(bp)), int32(4))
		(*TIndexSample)(unsafe.Pointer(pSample)).Fp = _sqlite3DbMallocZero(tls, db, libc.Uint64FromInt32((*TIndexSample)(unsafe.Pointer(pSample)).Fn+int32(8)))
		if (*TIndexSample)(unsafe.Pointer(pSample)).Fp == uintptr(0) {
			Xsqlite3_finalize(tls, **(**uintptr)(__ccgo_up(bp)))
			return int32(SQLITE_NOMEM)
		}
		if (*TIndexSample)(unsafe.Pointer(pSample)).Fn != 0 {
			libc.Xmemcpy(tls, (*TIndexSample)(unsafe.Pointer(pSample)).Fp, Xsqlite3_column_blob(tls, **(**uintptr)(__ccgo_up(bp)), int32(4)), libc.Uint64FromInt32((*TIndexSample)(unsafe.Pointer(pSample)).Fn))
		}
		(*TIndex)(unsafe.Pointer(pIdx1)).FnSample = (*TIndex)(unsafe.Pointer(pIdx1)).FnSample + 1
	}
	rc = Xsqlite3_finalize(tls, **(**uintptr)(__ccgo_up(bp)))
	if rc == SQLITE_OK {
		_initAvgEq(tls, pPrevIdx)
	}
	return rc
}

// C documentation
//
//	/*
//	** Read data from an memdb-file.
//	*/
func _memdbRead(tls *libc.TLS, pFile uintptr, zBuf uintptr, iAmt int32, iOfst Tsqlite_int64) (r int32) {
	var p uintptr
	_ = p
	p = (*TMemFile)(unsafe.Pointer(pFile)).FpStore
	_memdbEnter(tls, p)
	if iOfst+int64(iAmt) > (*TMemStore)(unsafe.Pointer(p)).Fsz {
		libc.Xmemset(tls, zBuf, 0, libc.Uint64FromInt32(iAmt))
		if iOfst < (*TMemStore)(unsafe.Pointer(p)).Fsz {
			libc.Xmemcpy(tls, zBuf, (*TMemStore)(unsafe.Pointer(p)).FaData+uintptr(iOfst), libc.Uint64FromInt64((*TMemStore)(unsafe.Pointer(p)).Fsz-iOfst))
		}
		_memdbLeave(tls, p)
		return libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(2)<<libc.Int32FromInt32(8)
	}
	libc.Xmemcpy(tls, zBuf, (*TMemStore)(unsafe.Pointer(p)).FaData+uintptr(iOfst), libc.Uint64FromInt32(iAmt))
	_memdbLeave(tls, p)
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** Write data to an memdb-file.
//	*/
func _memdbWrite(tls *libc.TLS, pFile uintptr, z uintptr, iAmt int32, iOfst Tsqlite_int64) (r int32) {
	var p uintptr
	var rc, v1 int32
	var v2 bool
	_, _, _, _ = p, rc, v1, v2
	p = (*TMemFile)(unsafe.Pointer(pFile)).FpStore
	_memdbEnter(tls, p)
	if (*TMemStore)(unsafe.Pointer(p)).FmFlags&uint32(SQLITE_DESERIALIZE_READONLY) != 0 {
		/* Can't happen: memdbLock() will return SQLITE_READONLY before
		 ** reaching this point */
		_memdbLeave(tls, p)
		return libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(3)<<libc.Int32FromInt32(8)
	}
	if iOfst+int64(iAmt) > (*TMemStore)(unsafe.Pointer(p)).Fsz {
		if v2 = iOfst+int64(iAmt) > (*TMemStore)(unsafe.Pointer(p)).FszAlloc; v2 {
			v1 = _memdbEnlarge(tls, p, iOfst+int64(iAmt))
			rc = v1
		}
		if v2 && v1 != SQLITE_OK {
			_memdbLeave(tls, p)
			return rc
		}
		if iOfst > (*TMemStore)(unsafe.Pointer(p)).Fsz {
			libc.Xmemset(tls, (*TMemStore)(unsafe.Pointer(p)).FaData+uintptr((*TMemStore)(unsafe.Pointer(p)).Fsz), 0, libc.Uint64FromInt64(iOfst-(*TMemStore)(unsafe.Pointer(p)).Fsz))
		}
		(*TMemStore)(unsafe.Pointer(p)).Fsz = iOfst + int64(iAmt)
	}
	libc.Xmemcpy(tls, (*TMemStore)(unsafe.Pointer(p)).FaData+uintptr(iOfst), z, libc.Uint64FromInt32(iAmt))
	_memdbLeave(tls, p)
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** Read data from the in-memory journal file.  This is the implementation
//	** of the sqlite3_vfs.xRead method.
//	*/
func _memjrnlRead(tls *libc.TLS, pJfd uintptr, zBuf uintptr, iAmt int32, iOfst Tsqlite_int64) (r int32) {
	var iChunkOffset, iSpace, nCopy, nRead, v5 int32
	var iOff Tsqlite3_int64
	var p, pChunk, zOut, v2 uintptr
	var v3 bool
	var v6 int64
	_, _, _, _, _, _, _, _, _, _, _, _ = iChunkOffset, iOff, iSpace, nCopy, nRead, p, pChunk, zOut, v2, v3, v5, v6
	p = pJfd
	zOut = zBuf
	nRead = iAmt
	if int64(iAmt)+iOfst > (*TMemJournal)(unsafe.Pointer(p)).Fendpoint.FiOffset {
		return libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(2)<<libc.Int32FromInt32(8)
	}
	if (*TMemJournal)(unsafe.Pointer(p)).Freadpoint.FiOffset != iOfst || iOfst == 0 {
		iOff = 0
		pChunk = (*TMemJournal)(unsafe.Pointer(p)).FpFirst
		for {
			if !(pChunk != 0 && iOff+int64((*TMemJournal)(unsafe.Pointer(p)).FnChunkSize) <= iOfst) {
				break
			}
			iOff = iOff + int64((*TMemJournal)(unsafe.Pointer(p)).FnChunkSize)
			goto _1
		_1:
			;
			pChunk = (*TFileChunk)(unsafe.Pointer(pChunk)).FpNext
		}
	} else {
		pChunk = (*TMemJournal)(unsafe.Pointer(p)).Freadpoint.FpChunk
	}
	iChunkOffset = int32(iOfst % int64((*TMemJournal)(unsafe.Pointer(p)).FnChunkSize))
	for {
		iSpace = (*TMemJournal)(unsafe.Pointer(p)).FnChunkSize - iChunkOffset
		if nRead < (*TMemJournal)(unsafe.Pointer(p)).FnChunkSize-iChunkOffset {
			v5 = nRead
		} else {
			v5 = (*TMemJournal)(unsafe.Pointer(p)).FnChunkSize - iChunkOffset
		}
		nCopy = v5
		libc.Xmemcpy(tls, zOut, pChunk+8+uintptr(iChunkOffset), libc.Uint64FromInt32(nCopy))
		zOut = zOut + uintptr(nCopy)
		nRead = nRead - iSpace
		iChunkOffset = 0
		goto _4
	_4:
		;
		if v3 = nRead >= 0; v3 {
			v2 = (*TFileChunk)(unsafe.Pointer(pChunk)).FpNext
			pChunk = v2
		}
		if !(v3 && v2 != uintptr(0) && nRead > 0) {
			break
		}
	}
	if pChunk != 0 {
		v6 = iOfst + int64(iAmt)
	} else {
		v6 = 0
	}
	(*TMemJournal)(unsafe.Pointer(p)).Freadpoint.FiOffset = v6
	(*TMemJournal)(unsafe.Pointer(p)).Freadpoint.FpChunk = pChunk
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** Write data to the file.
//	*/
func _memjrnlWrite(tls *libc.TLS, pJfd uintptr, zBuf uintptr, iAmt int32, iOfst Tsqlite_int64) (r int32) {
	var iChunkOffset, iSpace, nWrite, rc, v1 int32
	var p, pChunk, pNew, zWrite, v2 uintptr
	_, _, _, _, _, _, _, _, _, _ = iChunkOffset, iSpace, nWrite, p, pChunk, pNew, rc, zWrite, v1, v2
	p = pJfd
	nWrite = iAmt
	zWrite = zBuf
	/* If the file should be created now, create it and write the new data
	 ** into the file on disk. */
	if (*TMemJournal)(unsafe.Pointer(p)).FnSpill > 0 && int64(iAmt)+iOfst > int64((*TMemJournal)(unsafe.Pointer(p)).FnSpill) {
		rc = _memjrnlCreateFile(tls, p)
		if rc == SQLITE_OK {
			rc = _sqlite3OsWrite(tls, pJfd, zBuf, iAmt, iOfst)
		}
		return rc
	} else {
		/* An in-memory journal file should only ever be appended to. Random
		 ** access writes are not required. The only exception to this is when
		 ** the in-memory journal is being used by a connection using the
		 ** atomic-write optimization. In this case the first 28 bytes of the
		 ** journal file may be written as part of committing the transaction. */
		if iOfst > 0 && iOfst != (*TMemJournal)(unsafe.Pointer(p)).Fendpoint.FiOffset {
			_memjrnlTruncate(tls, pJfd, iOfst)
		}
		if iOfst == 0 && (*TMemJournal)(unsafe.Pointer(p)).FpFirst != 0 {
			libc.Xmemcpy(tls, (*TMemJournal)(unsafe.Pointer(p)).FpFirst+8, zBuf, libc.Uint64FromInt32(iAmt))
		} else {
			for nWrite > 0 {
				pChunk = (*TMemJournal)(unsafe.Pointer(p)).Fendpoint.FpChunk
				iChunkOffset = int32((*TMemJournal)(unsafe.Pointer(p)).Fendpoint.FiOffset % int64((*TMemJournal)(unsafe.Pointer(p)).FnChunkSize))
				if nWrite < (*TMemJournal)(unsafe.Pointer(p)).FnChunkSize-iChunkOffset {
					v1 = nWrite
				} else {
					v1 = (*TMemJournal)(unsafe.Pointer(p)).FnChunkSize - iChunkOffset
				}
				iSpace = v1
				if iChunkOffset == 0 {
					/* New chunk is required to extend the file. */
					pNew = Xsqlite3_malloc(tls, libc.Int32FromUint64(libc.Uint64FromInt64(16)+libc.Uint64FromInt32((*TMemJournal)(unsafe.Pointer(p)).FnChunkSize-libc.Int32FromInt32(8))))
					if !(pNew != 0) {
						return libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(12)<<libc.Int32FromInt32(8)
					}
					(*TFileChunk)(unsafe.Pointer(pNew)).FpNext = uintptr(0)
					if pChunk != 0 {
						(*TFileChunk)(unsafe.Pointer(pChunk)).FpNext = pNew
					} else {
						(*TMemJournal)(unsafe.Pointer(p)).FpFirst = pNew
					}
					v2 = pNew
					(*TMemJournal)(unsafe.Pointer(p)).Fendpoint.FpChunk = v2
					pChunk = v2
				}
				libc.Xmemcpy(tls, pChunk+8+uintptr(iChunkOffset), zWrite, libc.Uint64FromInt32(iSpace))
				zWrite = zWrite + uintptr(iSpace)
				nWrite = nWrite - iSpace
				(*TMemJournal)(unsafe.Pointer(p)).Fendpoint.FiOffset += int64(iSpace)
			}
		}
	}
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** If pBt points to an empty file then convert that empty file
//	** into a new empty database by initializing the first page of
//	** the database.
//	*/
func _newDatabase(tls *libc.TLS, pBt uintptr) (r int32) {
	var data, pP1, v1 uintptr
	var rc int32
	_, _, _, _ = data, pP1, rc, v1
	if (*TBtShared)(unsafe.Pointer(pBt)).FnPage > uint32(0) {
		return SQLITE_OK
	}
	pP1 = (*TBtShared)(unsafe.Pointer(pBt)).FpPage1
	data = (*TMemPage)(unsafe.Pointer(pP1)).FaData
	rc = _sqlite3PagerWrite(tls, (*TMemPage)(unsafe.Pointer(pP1)).FpDbPage)
	if rc != 0 {
		return rc
	}
	libc.Xmemcpy(tls, data, uintptr(unsafe.Pointer(&_zMagicHeader)), uint64(16))
	**(**uint8)(__ccgo_up(data + 16)) = uint8((*TBtShared)(unsafe.Pointer(pBt)).FpageSize >> libc.Int32FromInt32(8) & libc.Uint32FromInt32(0xff))
	**(**uint8)(__ccgo_up(data + 17)) = uint8((*TBtShared)(unsafe.Pointer(pBt)).FpageSize >> libc.Int32FromInt32(16) & libc.Uint32FromInt32(0xff))
	**(**uint8)(__ccgo_up(data + 18)) = uint8(1)
	**(**uint8)(__ccgo_up(data + 19)) = uint8(1)
	**(**uint8)(__ccgo_up(data + 20)) = uint8((*TBtShared)(unsafe.Pointer(pBt)).FpageSize - (*TBtShared)(unsafe.Pointer(pBt)).FusableSize)
	**(**uint8)(__ccgo_up(data + 21)) = uint8(64)
	**(**uint8)(__ccgo_up(data + 22)) = uint8(32)
	**(**uint8)(__ccgo_up(data + 23)) = uint8(32)
	libc.Xmemset(tls, data+24, 0, libc.Uint64FromInt32(libc.Int32FromInt32(100)-libc.Int32FromInt32(24)))
	_zeroPage(tls, pP1, libc.Int32FromInt32(PTF_INTKEY)|libc.Int32FromInt32(PTF_LEAF)|libc.Int32FromInt32(PTF_LEAFDATA))
	v1 = pBt + 40
	*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) | libc.Int32FromInt32(BTS_PAGESIZE_FIXED))
	_sqlite3Put4byte(tls, data+uintptr(libc.Int32FromInt32(36)+libc.Int32FromInt32(4)*libc.Int32FromInt32(4)), uint32((*TBtShared)(unsafe.Pointer(pBt)).FautoVacuum))
	_sqlite3Put4byte(tls, data+uintptr(libc.Int32FromInt32(36)+libc.Int32FromInt32(7)*libc.Int32FromInt32(4)), uint32((*TBtShared)(unsafe.Pointer(pBt)).FincrVacuum))
	(*TBtShared)(unsafe.Pointer(pBt)).FnPage = uint32(1)
	**(**uint8)(__ccgo_up(data + 31)) = uint8(1)
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** Remove the cell with index iCell from node pNode.
//	*/
func _nodeDeleteCell(tls *libc.TLS, pRtree uintptr, pNode uintptr, iCell int32) {
	var nByte int32
	var pDst, pSrc uintptr
	_, _, _ = nByte, pDst, pSrc
	pDst = (*TRtreeNode)(unsafe.Pointer(pNode)).FzData + uintptr(int32(4)+libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FnBytesPerCell)*iCell)
	pSrc = pDst + uintptr((*TRtree)(unsafe.Pointer(pRtree)).FnBytesPerCell)
	nByte = (_readInt16(tls, (*TRtreeNode)(unsafe.Pointer(pNode)).FzData+2) - iCell - int32(1)) * libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FnBytesPerCell)
	libc.Xmemmove(tls, pDst, pSrc, libc.Uint64FromInt32(nByte))
	_writeInt16(tls, (*TRtreeNode)(unsafe.Pointer(pNode)).FzData+2, _readInt16(tls, (*TRtreeNode)(unsafe.Pointer(pNode)).FzData+2)-int32(1))
	(*TRtreeNode)(unsafe.Pointer(pNode)).FisDirty = int32(1)
}

// 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(uint64(40)+libc.Uint64FromInt32((*TRtree)(unsafe.Pointer(pRtree)).FiNodeSize)))
	if pNode != 0 {
		libc.Xmemset(tls, pNode, 0, uint64(40)+libc.Uint64FromInt32((*TRtree)(unsafe.Pointer(pRtree)).FiNodeSize))
		(*TRtreeNode)(unsafe.Pointer(pNode)).FzData = pNode + 1*40
		(*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
//
//	/*
//	** Clear the content of node p (set all bytes to 0x00).
//	*/
func _nodeZero(tls *libc.TLS, pRtree uintptr, p uintptr) {
	libc.Xmemset(tls, (*TRtreeNode)(unsafe.Pointer(p)).FzData+2, 0, libc.Uint64FromInt32((*TRtree)(unsafe.Pointer(pRtree)).FiNodeSize-int32(2)))
	(*TRtreeNode)(unsafe.Pointer(p)).FisDirty = int32(1)
}

// C documentation
//
//	/*
//	** Search the free-list on page pPg for space to store a cell nByte bytes in
//	** size. If one can be found, return a pointer to the space and remove it
//	** from the free-list.
//	**
//	** If no suitable space can be found on the free-list, return NULL.
//	**
//	** This function may detect corruption within pPg.  If corruption is
//	** detected then *pRc is set to SQLITE_CORRUPT and NULL is returned.
//	**
//	** Slots on the free list that are between 1 and 3 bytes larger than nByte
//	** will be ignored if adding the extra space to the fragmentation count
//	** causes the fragmentation count to exceed 60.
//	*/
func _pageFindSlot(tls *libc.TLS, pPg uintptr, nByte int32, pRc uintptr) (r uintptr) {
	var aData, pTmp, v2 uintptr
	var hdr, iAddr, maxPC, pc, size, x, v1 int32
	_, _, _, _, _, _, _, _, _, _ = aData, hdr, iAddr, maxPC, pTmp, pc, size, x, v1, v2
	hdr = libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pPg)).FhdrOffset)                                                                      /* Offset to page header */
	aData = (*TMemPage)(unsafe.Pointer(pPg)).FaData                                                                                             /* Page data */
	iAddr = hdr + int32(1)                                                                                                                      /* Address of ptr to pc */
	pTmp = aData + uintptr(iAddr)                                                                                                               /* Temporary ptr into aData[] */
	pc = libc.Int32FromUint8(**(**Tu8)(__ccgo_up(pTmp)))<<int32(8) | libc.Int32FromUint8(**(**Tu8)(__ccgo_up(pTmp + 1)))                        /* Excess size of the slot */
	maxPC = libc.Int32FromUint32((*TBtShared)(unsafe.Pointer((*TMemPage)(unsafe.Pointer(pPg)).FpBt)).FusableSize - libc.Uint32FromInt32(nByte)) /* Size of the free slot */
	for pc <= maxPC {
		/* EVIDENCE-OF: R-22710-53328 The third and fourth bytes of each
		 ** freeblock form a big-endian integer which is the size of the freeblock
		 ** in bytes, including the 4-byte header. */
		pTmp = aData + uintptr(pc+int32(2))
		size = libc.Int32FromUint8(**(**Tu8)(__ccgo_up(pTmp)))<<int32(8) | libc.Int32FromUint8(**(**Tu8)(__ccgo_up(pTmp + 1)))
		v1 = size - nByte
		x = v1
		if v1 >= 0 {
			if x < int32(4) {
				/* EVIDENCE-OF: R-11498-58022 In a well-formed b-tree page, the total
				 ** number of bytes in fragments may not exceed 60. */
				if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aData + uintptr(hdr+int32(7))))) > int32(57) {
					return uintptr(0)
				}
				/* Remove the slot from the free-list. Update the number of
				 ** fragmented bytes within the page. */
				libc.Xmemcpy(tls, aData+uintptr(iAddr), aData+uintptr(pc), uint64(2))
				v2 = aData + uintptr(hdr+int32(7))
				*(*Tu8)(unsafe.Pointer(v2)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v2))) + libc.Int32FromUint8(libc.Uint8FromInt32(x)))
				return aData + uintptr(pc)
			} else {
				if x+pc > maxPC {
					/* This slot extends off the end of the usable part of the page */
					**(**int32)(__ccgo_up(pRc)) = _sqlite3CorruptError(tls, int32(74920))
					return uintptr(0)
				} else {
					/* The slot remains on the free-list. Reduce its size to account
					 ** for the portion used by the new allocation. */
					**(**Tu8)(__ccgo_up(aData + uintptr(pc+int32(2)))) = libc.Uint8FromInt32(x >> libc.Int32FromInt32(8))
					**(**Tu8)(__ccgo_up(aData + uintptr(pc+int32(2)) + 1)) = libc.Uint8FromInt32(x)
				}
			}
			return aData + uintptr(pc+x)
		}
		iAddr = pc
		pTmp = aData + uintptr(pc)
		pc = libc.Int32FromUint8(**(**Tu8)(__ccgo_up(pTmp)))<<int32(8) | libc.Int32FromUint8(**(**Tu8)(__ccgo_up(pTmp + 1)))
		if pc <= iAddr {
			if pc != 0 {
				/* The next slot in the chain comes before the current slot */
				**(**int32)(__ccgo_up(pRc)) = _sqlite3CorruptError(tls, int32(74935))
			}
			return uintptr(0)
		}
	}
	if pc > maxPC+nByte-int32(4) {
		/* The free slot chain extends off the end of the page */
		**(**int32)(__ccgo_up(pRc)) = _sqlite3CorruptError(tls, int32(74942))
	}
	return uintptr(0)
}

// C documentation
//
//	/*
//	** The pCArray objects contains pointers to b-tree cells and the cell sizes.
//	** This function attempts to add the cells stored in the array to page pPg.
//	** If it cannot (because the page needs to be defragmented before the cells
//	** will fit), non-zero is returned. Otherwise, if the cells are added
//	** successfully, zero is returned.
//	**
//	** Argument pCellptr points to the first entry in the cell-pointer array
//	** (part of page pPg) to populate. After cell apCell[0] is written to the
//	** page body, a 16-bit offset is written to pCellptr. And so on, for each
//	** cell in the array. It is the responsibility of the caller to ensure
//	** that it is safe to overwrite this part of the cell-pointer array.
//	**
//	** When this function is called, *ppData points to the start of the
//	** content area on page pPg. If the size of the content area is extended,
//	** *ppData is updated to point to the new start of the content area
//	** before returning.
//	**
//	** Finally, argument pBegin points to the byte immediately following the
//	** end of the space required by this page for the cell-pointer area (for
//	** all cells - not just those inserted by the current call). If the content
//	** area must be extended to before this point in order to accommodate all
//	** cells in apCell[], then the cells do not fit and non-zero is returned.
//	*/
func _pageInsertArray(tls *libc.TLS, pPg uintptr, pBegin uintptr, ppData uintptr, pCellptr uintptr, iFirst int32, nCell int32, pCArray uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var aData, pData, pEnd, pSlot, v2 uintptr
	var i, iEnd, k, sz int32
	var v3 bool
	var _ /* rc at bp+0 */ int32
	_, _, _, _, _, _, _, _, _, _ = aData, i, iEnd, k, pData, pEnd, pSlot, sz, v2, v3
	i = iFirst                                      /* Loop counter - cell index to insert */
	aData = (*TMemPage)(unsafe.Pointer(pPg)).FaData /* Complete page */
	pData = **(**uintptr)(__ccgo_up(ppData))        /* Content area.  A subset of aData[] */
	iEnd = iFirst + nCell                           /* Maximum extent of cell data */
	/* Never called on page 1 */
	if iEnd <= iFirst {
		return 0
	}
	k = 0
	for {
		if !(**(**int32)(__ccgo_up(pCArray + 80 + uintptr(k)*4)) <= i) {
			break
		}
		goto _1
	_1:
		;
		k = k + 1
	}
	pEnd = **(**uintptr)(__ccgo_up(pCArray + 32 + uintptr(k)*8))
	for int32(1) != 0 {
		sz = libc.Int32FromUint16(**(**Tu16)(__ccgo_up((*TCellArray)(unsafe.Pointer(pCArray)).FszCell + uintptr(i)*2)))
		if v3 = libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aData + 1))) == 0 && libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aData + 2))) == 0; !v3 {
			v2 = _pageFindSlot(tls, pPg, sz, bp)
			pSlot = v2
		}
		if v3 || v2 == uintptr(0) {
			if int64(pData)-int64(pBegin) < int64(sz) {
				return int32(1)
			}
			pData = pData - uintptr(sz)
			pSlot = pData
		}
		/* pSlot and pCArray->apCell[i] will never overlap on a well-formed
		 ** database.  But they might for a corrupt database.  Hence use memmove()
		 ** since memcpy() sends SIGABORT with overlapping buffers on OpenBSD */
		if uint64(**(**uintptr)(__ccgo_up((*TCellArray)(unsafe.Pointer(pCArray)).FapCell + uintptr(i)*8))+uintptr(sz)) > uint64(pEnd) && uint64(**(**uintptr)(__ccgo_up((*TCellArray)(unsafe.Pointer(pCArray)).FapCell + uintptr(i)*8))) < uint64(pEnd) {
			_sqlite3CorruptError(tls, int32(80911))
			return int32(1)
		}
		libc.Xmemmove(tls, pSlot, **(**uintptr)(__ccgo_up((*TCellArray)(unsafe.Pointer(pCArray)).FapCell + uintptr(i)*8)), libc.Uint64FromInt32(sz))
		**(**Tu8)(__ccgo_up(pCellptr)) = libc.Uint8FromInt64((int64(pSlot) - int64(aData)) >> libc.Int32FromInt32(8))
		**(**Tu8)(__ccgo_up(pCellptr + 1)) = libc.Uint8FromInt64(int64(pSlot) - int64(aData))
		pCellptr = pCellptr + uintptr(2)
		i = i + 1
		if i >= iEnd {
			break
		}
		if **(**int32)(__ccgo_up(pCArray + 80 + uintptr(k)*4)) <= i {
			k = k + 1
			pEnd = **(**uintptr)(__ccgo_up(pCArray + 32 + uintptr(k)*8))
		}
	}
	**(**uintptr)(__ccgo_up(ppData)) = pData
	return 0
}

// C documentation
//
//	/*
//	** Check that there are at least nSavepoint savepoints open. If there are
//	** currently less than nSavepoints open, then open one or more savepoints
//	** to make up the difference. If the number of savepoints is already
//	** equal to nSavepoint, then this function is a no-op.
//	**
//	** If a memory allocation fails, SQLITE_NOMEM is returned. If an error
//	** occurs while opening the sub-journal file, then an IO error code is
//	** returned. Otherwise, SQLITE_OK.
//	*/
func _pagerOpenSavepoint(tls *libc.TLS, pPager uintptr, nSavepoint int32) (r int32) {
	var aNew uintptr
	var ii, nCurrent, rc int32
	_, _, _, _ = aNew, ii, nCurrent, rc
	rc = SQLITE_OK                                           /* Return code */
	nCurrent = (*TPager)(unsafe.Pointer(pPager)).FnSavepoint /* New Pager.aSavepoint array */
	/* Grow the Pager.aSavepoint array using realloc(). Return SQLITE_NOMEM
	 ** if the allocation fails. Otherwise, zero the new portion in case a
	 ** malloc failure occurs while populating it in the for(...) loop below.
	 */
	aNew = _sqlite3Realloc(tls, (*TPager)(unsafe.Pointer(pPager)).FaSavepoint, uint64(uint64(56)*libc.Uint64FromInt32(nSavepoint)))
	if !(aNew != 0) {
		return int32(SQLITE_NOMEM)
	}
	libc.Xmemset(tls, aNew+uintptr(nCurrent)*56, 0, libc.Uint64FromInt32(nSavepoint-nCurrent)*uint64(56))
	(*TPager)(unsafe.Pointer(pPager)).FaSavepoint = aNew
	/* Populate the PagerSavepoint structures just allocated. */
	ii = nCurrent
	for {
		if !(ii < nSavepoint) {
			break
		}
		(**(**TPagerSavepoint)(__ccgo_up(aNew + uintptr(ii)*56))).FnOrig = (*TPager)(unsafe.Pointer(pPager)).FdbSize
		if (*Tsqlite3_file)(unsafe.Pointer((*TPager)(unsafe.Pointer(pPager)).Fjfd)).FpMethods != uintptr(0) && (*TPager)(unsafe.Pointer(pPager)).FjournalOff > 0 {
			(**(**TPagerSavepoint)(__ccgo_up(aNew + uintptr(ii)*56))).FiOffset = (*TPager)(unsafe.Pointer(pPager)).FjournalOff
		} else {
			(**(**TPagerSavepoint)(__ccgo_up(aNew + uintptr(ii)*56))).FiOffset = libc.Int64FromUint32((*TPager)(unsafe.Pointer(pPager)).FsectorSize)
		}
		(**(**TPagerSavepoint)(__ccgo_up(aNew + uintptr(ii)*56))).FiSubRec = (*TPager)(unsafe.Pointer(pPager)).FnSubRec
		(**(**TPagerSavepoint)(__ccgo_up(aNew + uintptr(ii)*56))).FpInSavepoint = _sqlite3BitvecCreate(tls, (*TPager)(unsafe.Pointer(pPager)).FdbSize)
		(**(**TPagerSavepoint)(__ccgo_up(aNew + uintptr(ii)*56))).FbTruncateOnRelease = int32(1)
		if !((**(**TPagerSavepoint)(__ccgo_up(aNew + uintptr(ii)*56))).FpInSavepoint != 0) {
			return int32(SQLITE_NOMEM)
		}
		if (*TPager)(unsafe.Pointer(pPager)).FpWal != uintptr(0) {
			_sqlite3WalSavepoint(tls, (*TPager)(unsafe.Pointer(pPager)).FpWal, aNew+uintptr(ii)*56+36)
		}
		(*TPager)(unsafe.Pointer(pPager)).FnSavepoint = ii + int32(1)
		goto _1
	_1:
		;
		ii = ii + 1
	}
	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+12 */ Tu32
	var _ /* pPg at bp+0 */ uintptr
	var _ /* pgno at bp+8 */ 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+8)
	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 + 8)) == uint32(0) || **(**TPgno)(__ccgo_up(bp + 8)) == (*TPager)(unsafe.Pointer(pPager)).FlckPgno {
		return int32(SQLITE_DONE)
	}
	if **(**TPgno)(__ccgo_up(bp + 8)) > (*TPager)(unsafe.Pointer(pPager)).FdbSize || _sqlite3BitvecTest(tls, pDone, **(**TPgno)(__ccgo_up(bp + 8))) != 0 {
		return SQLITE_OK
	}
	if isMainJrnl != 0 {
		rc = _read32bits(tls, jfd, **(**Ti64)(__ccgo_up(pOffset))-int64(4), bp+12)
		if rc != 0 {
			return rc
		}
		if !(isSavepnt != 0) && _pager_cksum(tls, pPager, aData) != **(**Tu32)(__ccgo_up(bp + 12)) {
			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 + 8)))
		rc = v2
	}
	if v3 && v2 != SQLITE_OK {
		return rc
	}
	/* When playing back page 1, restore the nReserve setting
	 */
	if **(**TPgno)(__ccgo_up(bp + 8)) == 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 + 8)))
	}
	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 + 8))-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 + 8)) > (*TPager)(unsafe.Pointer(pPager)).FdbFileSize {
			(*TPager)(unsafe.Pointer(pPager)).FdbFileSize = **(**TPgno)(__ccgo_up(bp + 8))
		}
		if (*TPager)(unsafe.Pointer(pPager)).FpBackup != 0 {
			_sqlite3BackupUpdate(tls, (*TPager)(unsafe.Pointer(pPager)).FpBackup, **(**TPgno)(__ccgo_up(bp + 8)), 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 + 25
			*(*Tu8)(unsafe.Pointer(v1)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v1))) | libc.Int32FromInt32(SPILLFLAG_ROLLBACK))
			rc = _sqlite3PagerGet(tls, pPager, **(**TPgno)(__ccgo_up(bp + 8)), bp, int32(1))
			v1 = pPager + 25
			*(*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.Uint64FromInt64((*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 + 8)) == uint32(1) {
			libc.Xmemcpy(tls, pPager+136, pData+24, uint64(16))
		}
		_sqlite3PcacheRelease(tls, **(**uintptr)(__ccgo_up(bp)))
	}
	return rc
}

// C documentation
//
//	/*
//	** This function is used to change the actual size of the database
//	** file in the file-system. This only happens when committing a transaction,
//	** or rolling back a transaction (including rolling back a hot-journal).
//	**
//	** If the main database file is not open, or the pager is not in either
//	** DBMOD or OPEN state, this function is a no-op. Otherwise, the size
//	** of the file is changed to nPage pages (nPage*pPager->pageSize bytes).
//	** If the file on disk is currently larger than nPage pages, then use the VFS
//	** xTruncate() method to truncate it.
//	**
//	** Or, it might be the case that the file on disk is smaller than
//	** nPage pages. Some operating system implementations can get confused if
//	** you try to truncate a file to some size that is larger than it
//	** currently is, so detect this case and write a single zero byte to
//	** the end of the new file instead.
//	**
//	** If successful, return SQLITE_OK. If an IO error occurs while modifying
//	** the database file, return the error code to the caller.
//	*/
func _pager_truncate(tls *libc.TLS, pPager uintptr, nPage TPgno) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var pTmp uintptr
	var rc, szPage int32
	var _ /* currentSize at bp+0 */ Ti64
	var _ /* newSize at bp+8 */ Ti64
	_, _, _ = pTmp, rc, szPage
	rc = SQLITE_OK
	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) {
		szPage = int32((*TPager)(unsafe.Pointer(pPager)).FpageSize)
		/* TODO: Is it safe to use Pager.dbFileSize here? */
		rc = _sqlite3OsFileSize(tls, (*TPager)(unsafe.Pointer(pPager)).Ffd, bp)
		**(**Ti64)(__ccgo_up(bp + 8)) = int64(szPage) * libc.Int64FromUint32(nPage)
		if rc == SQLITE_OK && **(**Ti64)(__ccgo_up(bp)) != **(**Ti64)(__ccgo_up(bp + 8)) {
			if **(**Ti64)(__ccgo_up(bp)) > **(**Ti64)(__ccgo_up(bp + 8)) {
				rc = _sqlite3OsTruncate(tls, (*TPager)(unsafe.Pointer(pPager)).Ffd, **(**Ti64)(__ccgo_up(bp + 8)))
			} else {
				if **(**Ti64)(__ccgo_up(bp))+int64(szPage) <= **(**Ti64)(__ccgo_up(bp + 8)) {
					pTmp = (*TPager)(unsafe.Pointer(pPager)).FpTmpSpace
					libc.Xmemset(tls, pTmp, 0, libc.Uint64FromInt32(szPage))
					_sqlite3OsFileControlHint(tls, (*TPager)(unsafe.Pointer(pPager)).Ffd, int32(SQLITE_FCNTL_SIZE_HINT), bp+8)
					rc = _sqlite3OsWrite(tls, (*TPager)(unsafe.Pointer(pPager)).Ffd, pTmp, szPage, **(**Ti64)(__ccgo_up(bp + 8))-int64(szPage))
				}
			}
			if rc == SQLITE_OK {
				(*TPager)(unsafe.Pointer(pPager)).FdbFileSize = nPage
			}
		}
	}
	return rc
}

// 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+136, pData+24, uint64(16))
			}
			if pgno > (*TPager)(unsafe.Pointer(pPager)).FdbFileSize {
				(*TPager)(unsafe.Pointer(pPager)).FdbFileSize = pgno
			}
			**(**Tu32)(__ccgo_up(pPager + 248 + 2*4)) = **(**Tu32)(__ccgo_up(pPager + 248 + 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
//
//	/*
//	** Locate a pragma in the aPragmaName[] array.
//	*/
func _pragmaLocate(tls *libc.TLS, zName uintptr) (r uintptr) {
	var lwr, mid, rc, upr int32
	var v1 uintptr
	_, _, _, _, _ = lwr, mid, rc, upr, v1
	mid = 0
	lwr = 0
	upr = libc.Int32FromUint64(libc.Uint64FromInt64(1584)/libc.Uint64FromInt64(24)) - libc.Int32FromInt32(1)
	for lwr <= upr {
		mid = (lwr + upr) / int32(2)
		rc = Xsqlite3_stricmp(tls, zName, _aPragmaName[mid].FzName)
		if rc == 0 {
			break
		}
		if rc < 0 {
			upr = mid - int32(1)
		} else {
			lwr = mid + int32(1)
		}
	}
	if lwr > upr {
		v1 = uintptr(0)
	} else {
		v1 = uintptr(unsafe.Pointer(&_aPragmaName)) + uintptr(mid)*24
	}
	return v1
}

// 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(96)
	defer tls.Free(96)
	var nChng int32
	var _ /* w at bp+40 */ 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 + 103
	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+40, 0, uint64(48))
			(**(**TWalker)(__ccgo_up(bp + 40))).FpParse = pParse
			(**(**TWalker)(__ccgo_up(bp + 40))).FxExprCallback = __ccgo_fp(_propagateConstantExprRewrite)
			(**(**TWalker)(__ccgo_up(bp + 40))).FxSelectCallback = __ccgo_fp(_sqlite3SelectWalkNoop)
			(**(**TWalker)(__ccgo_up(bp + 40))).FxSelectCallback2 = uintptr(0)
			(**(**TWalker)(__ccgo_up(bp + 40))).FwalkerDepth = 0
			*(*uintptr)(unsafe.Pointer(bp + 40 + 40)) = bp
			_sqlite3WalkExpr(tls, bp+40, (*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
//
//	/*
//	** Generate code that will push the record in registers regData
//	** through regData+nData-1 onto the sorter.
//	*/
func _pushOntoSorter(tls *libc.TLS, pParse uintptr, pSort uintptr, pSelect uintptr, regData int32, regOrigData int32, nData int32, nPrefixReg int32) {
	var addrFirst, addrJmp, bSeq, iCsr, iLimit, iSkip, nBase, nExpr, nKey, nOBSat, op, regBase, regPrevKey, regRecord, v1 int32
	var pKI, pOp, v, v4 uintptr
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = addrFirst, addrJmp, bSeq, iCsr, iLimit, iSkip, nBase, nExpr, nKey, nOBSat, op, pKI, pOp, regBase, regPrevKey, regRecord, v, v1, v4
	v = (*TParse)(unsafe.Pointer(pParse)).FpVdbe /* Stmt under construction */
	bSeq = libc.BoolInt32(libc.Int32FromUint8((*TSortCtx)(unsafe.Pointer(pSort)).FsortFlags)&int32(SORTFLAG_UseSorter) == 0)
	nExpr = (*TExprList)(unsafe.Pointer((*TSortCtx)(unsafe.Pointer(pSort)).FpOrderBy)).FnExpr /* No. of ORDER BY terms */
	nBase = nExpr + bSeq + nData                                                              /* Regs for sorter record */
	regRecord = 0                                                                             /* Assembled sorter record */
	nOBSat = (*TSortCtx)(unsafe.Pointer(pSort)).FnOBSat                                       /* LIMIT counter */
	iSkip = 0                                                                                 /* End of the sorter insert loop */
	/* Three cases:
	 **   (1) The data to be sorted has already been packed into a Record
	 **       by a prior OP_MakeRecord.  In this case nData==1 and regData
	 **       will be completely unrelated to regOrigData.
	 **   (2) All output columns are included in the sort record.  In that
	 **       case regData==regOrigData.
	 **   (3) Some output columns are omitted from the sort record due to
	 **       the SQLITE_ENABLE_SORTER_REFERENCES optimization, or due to the
	 **       SQLITE_ECEL_OMITREF optimization, or due to the
	 **       SortCtx.pDeferredRowLoad optimization.  In any of these cases
	 **       regOrigData is 0 to prevent this routine from trying to copy
	 **       values that might not yet exist.
	 */
	if nPrefixReg != 0 {
		regBase = regData - nPrefixReg
	} else {
		regBase = (*TParse)(unsafe.Pointer(pParse)).FnMem + int32(1)
		**(**int32)(__ccgo_up(pParse + 60)) += nBase
	}
	if (*TSelect)(unsafe.Pointer(pSelect)).FiOffset != 0 {
		v1 = (*TSelect)(unsafe.Pointer(pSelect)).FiOffset + int32(1)
	} else {
		v1 = (*TSelect)(unsafe.Pointer(pSelect)).FiLimit
	}
	iLimit = v1
	(*TSortCtx)(unsafe.Pointer(pSort)).FlabelDone = _sqlite3VdbeMakeLabel(tls, pParse)
	if regOrigData != 0 {
		v1 = int32(SQLITE_ECEL_REF)
	} else {
		v1 = 0
	}
	_sqlite3ExprCodeExprList(tls, pParse, (*TSortCtx)(unsafe.Pointer(pSort)).FpOrderBy, regBase, regOrigData, libc.Uint8FromInt32(int32(SQLITE_ECEL_DUP)|v1))
	if bSeq != 0 {
		_sqlite3VdbeAddOp2(tls, v, int32(OP_Sequence), (*TSortCtx)(unsafe.Pointer(pSort)).FiECursor, regBase+nExpr)
	}
	if nPrefixReg == 0 && nData > 0 {
		_sqlite3ExprCodeMove(tls, pParse, regData, regBase+nExpr+bSeq, nData)
	}
	if nOBSat > 0 { /* Original KeyInfo on the sorter table */
		regRecord = _makeSorterRecord(tls, pParse, pSort, pSelect, regBase, nBase)
		regPrevKey = (*TParse)(unsafe.Pointer(pParse)).FnMem + int32(1)
		**(**int32)(__ccgo_up(pParse + 60)) += (*TSortCtx)(unsafe.Pointer(pSort)).FnOBSat
		nKey = nExpr - (*TSortCtx)(unsafe.Pointer(pSort)).FnOBSat + bSeq
		if bSeq != 0 {
			addrFirst = _sqlite3VdbeAddOp1(tls, v, int32(OP_IfNot), regBase+nExpr)
		} else {
			addrFirst = _sqlite3VdbeAddOp1(tls, v, int32(OP_SequenceTest), (*TSortCtx)(unsafe.Pointer(pSort)).FiECursor)
		}
		_sqlite3VdbeAddOp3(tls, v, int32(OP_Compare), regPrevKey, regBase, (*TSortCtx)(unsafe.Pointer(pSort)).FnOBSat)
		pOp = _sqlite3VdbeGetOp(tls, v, (*TSortCtx)(unsafe.Pointer(pSort)).FaddrSortIndex)
		if (*Tsqlite3)(unsafe.Pointer((*TParse)(unsafe.Pointer(pParse)).Fdb)).FmallocFailed != 0 {
			return
		}
		(*TVdbeOp)(unsafe.Pointer(pOp)).Fp2 = nKey + nData
		pKI = *(*uintptr)(unsafe.Pointer(pOp + 16))
		libc.Xmemset(tls, (*TKeyInfo)(unsafe.Pointer(pKI)).FaSortFlags, 0, uint64((*TKeyInfo)(unsafe.Pointer(pKI)).FnKeyField)) /* Makes OP_Jump testable */
		_sqlite3VdbeChangeP4(tls, v, -int32(1), pKI, -int32(9))
		*(*uintptr)(unsafe.Pointer(pOp + 16)) = _sqlite3KeyInfoFromExprList(tls, pParse, (*TSortCtx)(unsafe.Pointer(pSort)).FpOrderBy, nOBSat, libc.Int32FromUint16((*TKeyInfo)(unsafe.Pointer(pKI)).FnAllField)-libc.Int32FromUint16((*TKeyInfo)(unsafe.Pointer(pKI)).FnKeyField)-int32(1))
		pOp = uintptr(0) /* Ensure pOp not used after sqlite3VdbeAddOp3() */
		addrJmp = _sqlite3VdbeCurrentAddr(tls, v)
		_sqlite3VdbeAddOp3(tls, v, int32(OP_Jump), addrJmp+int32(1), 0, addrJmp+int32(1))
		(*TSortCtx)(unsafe.Pointer(pSort)).FlabelBkOut = _sqlite3VdbeMakeLabel(tls, pParse)
		v4 = pParse + 60
		*(*int32)(unsafe.Pointer(v4)) = *(*int32)(unsafe.Pointer(v4)) + 1
		v1 = *(*int32)(unsafe.Pointer(v4))
		(*TSortCtx)(unsafe.Pointer(pSort)).FregReturn = v1
		_sqlite3VdbeAddOp2(tls, v, int32(OP_Gosub), (*TSortCtx)(unsafe.Pointer(pSort)).FregReturn, (*TSortCtx)(unsafe.Pointer(pSort)).FlabelBkOut)
		_sqlite3VdbeAddOp1(tls, v, int32(OP_ResetSorter), (*TSortCtx)(unsafe.Pointer(pSort)).FiECursor)
		if iLimit != 0 {
			_sqlite3VdbeAddOp2(tls, v, int32(OP_IfNot), iLimit, (*TSortCtx)(unsafe.Pointer(pSort)).FlabelDone)
		}
		_sqlite3VdbeJumpHere(tls, v, addrFirst)
		_sqlite3ExprCodeMove(tls, pParse, regBase, regPrevKey, (*TSortCtx)(unsafe.Pointer(pSort)).FnOBSat)
		_sqlite3VdbeJumpHere(tls, v, addrJmp)
	}
	if iLimit != 0 {
		/* At this point the values for the new sorter entry are stored
		 ** in an array of registers. They need to be composed into a record
		 ** and inserted into the sorter if either (a) there are currently
		 ** less than LIMIT+OFFSET items or (b) the new record is smaller than
		 ** the largest record currently in the sorter. If (b) is true and there
		 ** are already LIMIT+OFFSET items in the sorter, delete the largest
		 ** entry before inserting the new one. This way there are never more
		 ** than LIMIT+OFFSET items in the sorter.
		 **
		 ** If the new record does not need to be inserted into the sorter,
		 ** jump to the next iteration of the loop. If the pSort->labelOBLopt
		 ** value is not zero, then it is a label of where to jump.  Otherwise,
		 ** just bypass the row insert logic.  See the header comment on the
		 ** sqlite3WhereOrderByLimitOptLabel() function for additional info.
		 */
		iCsr = (*TSortCtx)(unsafe.Pointer(pSort)).FiECursor
		_sqlite3VdbeAddOp2(tls, v, int32(OP_IfNotZero), iLimit, _sqlite3VdbeCurrentAddr(tls, v)+int32(4))
		_sqlite3VdbeAddOp2(tls, v, int32(OP_Last), iCsr, 0)
		iSkip = _sqlite3VdbeAddOp4Int(tls, v, int32(OP_IdxLE), iCsr, 0, regBase+nOBSat, nExpr-nOBSat)
		_sqlite3VdbeAddOp1(tls, v, int32(OP_Delete), iCsr)
	}
	if regRecord == 0 {
		regRecord = _makeSorterRecord(tls, pParse, pSort, pSelect, regBase, nBase)
	}
	if libc.Int32FromUint8((*TSortCtx)(unsafe.Pointer(pSort)).FsortFlags)&int32(SORTFLAG_UseSorter) != 0 {
		op = int32(OP_SorterInsert)
	} else {
		op = int32(OP_IdxInsert)
	}
	_sqlite3VdbeAddOp4Int(tls, v, op, (*TSortCtx)(unsafe.Pointer(pSort)).FiECursor, regRecord, regBase+nOBSat, nBase-nOBSat)
	if iSkip != 0 {
		if (*TSortCtx)(unsafe.Pointer(pSort)).FlabelOBLopt != 0 {
			v1 = (*TSortCtx)(unsafe.Pointer(pSort)).FlabelOBLopt
		} else {
			v1 = _sqlite3VdbeCurrentAddr(tls, v)
		}
		_sqlite3VdbeChangeP2(tls, v, iSkip, v1)
	}
}

// C documentation
//
//	/*
//	** Compare two constraint names.
//	**
//	** Summary:   *pRes := zQuote != zCmp
//	**
//	** Details:
//	** Compare the (possibly quoted) constraint name zQuote[0..nQuote-1]
//	** against zCmp[].  Write zero into *pRes if they are the same and
//	** non-zero if they differ.  Normally return SQLITE_OK, except if there
//	** is an OOM, set the OOM error condition on ctx and return SQLITE_NOMEM.
//	*/
func _quotedCompare(tls *libc.TLS, ctx uintptr, t int32, zQuote uintptr, nQuote int32, zCmp uintptr, pRes uintptr) (r int32) {
	var zCopy uintptr
	_ = zCopy
	zCopy = uintptr(0) /* De-quoted, zero-terminated copy of zQuote[] */
	if t == int32(TK_ILLEGAL) {
		**(**int32)(__ccgo_up(pRes)) = int32(1)
		return SQLITE_OK
	}
	zCopy = _sqlite3MallocZero(tls, libc.Uint64FromInt32(nQuote+int32(1)))
	if zCopy == uintptr(0) {
		Xsqlite3_result_error_nomem(tls, ctx)
		return int32(SQLITE_NOMEM)
	}
	libc.Xmemcpy(tls, zCopy, zQuote, libc.Uint64FromInt32(nQuote))
	_sqlite3Dequote(tls, zCopy)
	**(**int32)(__ccgo_up(pRes)) = Xsqlite3_stricmp(tls, zCopy, zCmp)
	Xsqlite3_free(tls, zCopy)
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** Attempt to allocate and return a pointer to a zeroed block of nByte
//	** bytes.
//	**
//	** If an error (i.e. an OOM condition) occurs, return NULL and leave an
//	** error code in the rbu handle passed as the first argument. Or, if an
//	** error has already occurred when this function is called, return NULL
//	** immediately without attempting the allocation or modifying the stored
//	** error code.
//	*/
func _rbuMalloc(tls *libc.TLS, p uintptr, nByte Tsqlite3_int64) (r uintptr) {
	var pRet uintptr
	_ = pRet
	pRet = uintptr(0)
	if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
		pRet = Xsqlite3_malloc64(tls, libc.Uint64FromInt64(nByte))
		if pRet == uintptr(0) {
			(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = int32(SQLITE_NOMEM)
		} else {
			libc.Xmemset(tls, pRet, 0, libc.Uint64FromInt64(nByte))
		}
	}
	return pRet
}

// C documentation
//
//	/*
//	** Read data from an rbuVfs-file.
//	*/
func _rbuVfsRead(tls *libc.TLS, pFile uintptr, zBuf uintptr, iAmt int32, iOfst Tsqlite_int64) (r int32) {
	var aBuf, p, pBuf, pFd, pRbu uintptr
	var iRoot Tu32
	var rc, v1 int32
	_, _, _, _, _, _, _, _ = aBuf, iRoot, p, pBuf, pFd, pRbu, rc, v1
	p = pFile
	pRbu = (*Trbu_file)(unsafe.Pointer(p)).FpRbu
	if pRbu != 0 && (*Tsqlite3rbu)(unsafe.Pointer(pRbu)).FeStage == int32(RBU_STAGE_CAPTURE) {
		rc = _rbuCaptureWalRead(tls, (*Trbu_file)(unsafe.Pointer(p)).FpRbu, iOfst, iAmt)
	} else {
		if pRbu != 0 && (*Tsqlite3rbu)(unsafe.Pointer(pRbu)).FeStage == int32(RBU_STAGE_OAL) && (*Trbu_file)(unsafe.Pointer(p)).FopenFlags&int32(SQLITE_OPEN_WAL) != 0 && iOfst >= (*Tsqlite3rbu)(unsafe.Pointer(pRbu)).FiOalSz {
			rc = SQLITE_OK
			libc.Xmemset(tls, zBuf, 0, libc.Uint64FromInt32(iAmt))
		} else {
			rc = (*(*func(*libc.TLS, uintptr, uintptr, int32, Tsqlite3_int64) int32)(unsafe.Pointer(&struct{ uintptr }{(*Tsqlite3_io_methods)(unsafe.Pointer((*Tsqlite3_file)(unsafe.Pointer((*Trbu_file)(unsafe.Pointer(p)).FpReal)).FpMethods)).FxRead})))(tls, (*Trbu_file)(unsafe.Pointer(p)).FpReal, zBuf, iAmt, iOfst)
			/* If this is being called to read the first page of the target
			 ** database as part of an rbu vacuum operation, synthesize the
			 ** contents of the first page if it does not yet exist. Otherwise,
			 ** SQLite will not check for a *-wal file.  */
			if pRbu != 0 && (*Tsqlite3rbu)(unsafe.Pointer(pRbu)).FzTarget == uintptr(0) && rc == libc.Int32FromInt32(SQLITE_IOERR)|libc.Int32FromInt32(2)<<libc.Int32FromInt32(8) && iOfst == 0 && (*Trbu_file)(unsafe.Pointer(p)).FopenFlags&int32(SQLITE_OPEN_MAIN_DB) != 0 && (*Tsqlite3rbu)(unsafe.Pointer(pRbu)).Frc == SQLITE_OK {
				pFd = (*Tsqlite3rbu)(unsafe.Pointer(pRbu)).FpRbuFd
				rc = (*(*func(*libc.TLS, uintptr, uintptr, int32, Tsqlite3_int64) int32)(unsafe.Pointer(&struct{ uintptr }{(*Tsqlite3_io_methods)(unsafe.Pointer((*Tsqlite3_file)(unsafe.Pointer(pFd)).FpMethods)).FxRead})))(tls, pFd, zBuf, iAmt, iOfst)
				if rc == SQLITE_OK {
					aBuf = zBuf
					if _rbuGetU32(tls, aBuf+52) != 0 {
						v1 = int32(1)
					} else {
						v1 = 0
					}
					iRoot = libc.Uint32FromInt32(v1)
					_rbuPutU32(tls, aBuf+52, iRoot)                                                                                         /* largest root page number */
					_rbuPutU32(tls, aBuf+36, uint32(0))                                                                                     /* number of free pages */
					_rbuPutU32(tls, aBuf+32, uint32(0))                                                                                     /* first page on free list trunk */
					_rbuPutU32(tls, aBuf+28, uint32(1))                                                                                     /* size of db file in pages */
					_rbuPutU32(tls, aBuf+24, (*Trbu_file)(unsafe.Pointer((*Tsqlite3rbu)(unsafe.Pointer(pRbu)).FpRbuFd)).FiCookie+uint32(1)) /* Change counter */
					if iAmt > int32(100) {
						libc.Xmemset(tls, aBuf+100, 0, libc.Uint64FromInt32(iAmt-int32(100)))
						_rbuPutU16(tls, aBuf+105, libc.Uint16FromInt32(iAmt&int32(0xFFFF)))
						**(**Tu8)(__ccgo_up(aBuf + 100)) = uint8(0x0D)
					}
				}
			}
		}
		if rc == SQLITE_OK && iOfst == 0 && (*Trbu_file)(unsafe.Pointer(p)).FopenFlags&int32(SQLITE_OPEN_MAIN_DB) != 0 {
			/* These look like magic numbers. But they are stable, as they are part
			 ** of the definition of the SQLite file format, which may not change. */
			pBuf = zBuf
			(*Trbu_file)(unsafe.Pointer(p)).FiCookie = _rbuGetU32(tls, pBuf+24)
			(*Trbu_file)(unsafe.Pointer(p)).FiWriteVer = **(**Tu8)(__ccgo_up(pBuf + 19))
		}
	}
	return rc
}

// C documentation
//
//	/*
//	** Obtain a pointer to a mapping of a single 32KiB page of the *-shm file.
//	*/
func _rbuVfsShmMap(tls *libc.TLS, pFile uintptr, iRegion int32, szRegion int32, isWrite int32, pp uintptr) (r int32) {
	var apNew, p, pNew uintptr
	var eStage, rc, v1 int32
	var nByte Tsqlite3_int64
	_, _, _, _, _, _, _ = apNew, eStage, nByte, p, pNew, rc, v1
	p = pFile
	rc = SQLITE_OK
	if (*Trbu_file)(unsafe.Pointer(p)).FpRbu != 0 {
		v1 = (*Tsqlite3rbu)(unsafe.Pointer((*Trbu_file)(unsafe.Pointer(p)).FpRbu)).FeStage
	} else {
		v1 = 0
	}
	eStage = v1
	/* If not in RBU_STAGE_OAL, allow this call to pass through. Or, if this
	 ** rbu is in the RBU_STAGE_OAL state, use heap memory for *-shm space
	 ** instead of a file on disk.  */
	if eStage == int32(RBU_STAGE_OAL) {
		nByte = libc.Int64FromUint64(libc.Uint64FromInt32(iRegion+libc.Int32FromInt32(1)) * uint64(8))
		apNew = Xsqlite3_realloc64(tls, (*Trbu_file)(unsafe.Pointer(p)).FapShm, libc.Uint64FromInt64(nByte))
		/* This is an RBU connection that uses its own heap memory for the
		 ** pages of the *-shm file. Since no other process can have run
		 ** recovery, the connection must request *-shm pages in order
		 ** from start to finish.  */
		if apNew == uintptr(0) {
			rc = int32(SQLITE_NOMEM)
		} else {
			libc.Xmemset(tls, apNew+uintptr((*Trbu_file)(unsafe.Pointer(p)).FnShm)*8, 0, uint64(8)*libc.Uint64FromInt32(libc.Int32FromInt32(1)+iRegion-(*Trbu_file)(unsafe.Pointer(p)).FnShm))
			(*Trbu_file)(unsafe.Pointer(p)).FapShm = apNew
			(*Trbu_file)(unsafe.Pointer(p)).FnShm = iRegion + int32(1)
		}
		if rc == SQLITE_OK {
			pNew = Xsqlite3_malloc64(tls, libc.Uint64FromInt32(szRegion))
			if pNew == uintptr(0) {
				rc = int32(SQLITE_NOMEM)
			} else {
				libc.Xmemset(tls, pNew, 0, libc.Uint64FromInt32(szRegion))
				**(**uintptr)(__ccgo_up((*Trbu_file)(unsafe.Pointer(p)).FapShm + uintptr(iRegion)*8)) = pNew
			}
		}
		if rc == SQLITE_OK {
			**(**uintptr)(__ccgo_up(pp)) = **(**uintptr)(__ccgo_up((*Trbu_file)(unsafe.Pointer(p)).FapShm + uintptr(iRegion)*8))
		} else {
			**(**uintptr)(__ccgo_up(pp)) = uintptr(0)
		}
	} else {
		rc = (*(*func(*libc.TLS, uintptr, int32, int32, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*Tsqlite3_io_methods)(unsafe.Pointer((*Tsqlite3_file)(unsafe.Pointer((*Trbu_file)(unsafe.Pointer(p)).FpReal)).FpMethods)).FxShmMap})))(tls, (*Trbu_file)(unsafe.Pointer(p)).FpReal, iRegion, szRegion, isWrite, pp)
	}
	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+136, int32(0xff), uint64(16))
		} else {
			dbFileVers = (*TPgHdr)(unsafe.Pointer(pPg)).FpData + 24
			libc.Xmemcpy(tls, pPager+136, dbFileVers, uint64(16))
		}
	}
	return rc
}

// C documentation
//
//	/*
//	** Array apCell[] contains pointers to nCell b-tree page cells. The
//	** szCell[] array contains the size in bytes of each cell. This function
//	** replaces the current contents of page pPg with the contents of the cell
//	** array.
//	**
//	** Some of the cells in apCell[] may currently be stored in pPg. This
//	** function works around problems caused by this by making a copy of any
//	** such cells before overwriting the page data.
//	**
//	** The MemPage.nFree field is invalidated by this function. It is the
//	** responsibility of the caller to set it correctly.
//	*/
func _rebuildPage(tls *libc.TLS, pCArray uintptr, iFirst int32, nCell int32, pPg uintptr) (r int32) {
	var aData, pCell, pCellptr, pData, pEnd, pSrcEnd, pTmp uintptr
	var hdr, i, iEnd, k, usableSize int32
	var j Tu32
	var sz Tu16
	_, _, _, _, _, _, _, _, _, _, _, _, _, _ = aData, hdr, i, iEnd, j, k, pCell, pCellptr, pData, pEnd, pSrcEnd, pTmp, sz, usableSize
	hdr = libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pPg)).FhdrOffset) /* Offset of header on pPg */
	aData = (*TMemPage)(unsafe.Pointer(pPg)).FaData                        /* Pointer to data for pPg */
	usableSize = libc.Int32FromUint32((*TBtShared)(unsafe.Pointer((*TMemPage)(unsafe.Pointer(pPg)).FpBt)).FusableSize)
	pEnd = aData + uintptr(usableSize)
	i = iFirst       /* Start of cell content area */
	iEnd = i + nCell /* Loop terminator */
	pCellptr = (*TMemPage)(unsafe.Pointer(pPg)).FaCellIdx
	pTmp = _sqlite3PagerTempSpace(tls, (*TBtShared)(unsafe.Pointer((*TMemPage)(unsafe.Pointer(pPg)).FpBt)).FpPager) /* Current pCArray->apEnd[k] value */
	j = libc.Uint32FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aData + uintptr(hdr+int32(5)))))<<libc.Int32FromInt32(8) | libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aData + uintptr(hdr+int32(5)) + 1))))
	if j > libc.Uint32FromInt32(usableSize) {
		j = uint32(0)
	}
	libc.Xmemcpy(tls, pTmp+uintptr(j), aData+uintptr(j), uint64(libc.Uint32FromInt32(usableSize)-j))
	k = 0
	for {
		if !(**(**int32)(__ccgo_up(pCArray + 80 + uintptr(k)*4)) <= i) {
			break
		}
		goto _1
	_1:
		;
		k = k + 1
	}
	pSrcEnd = **(**uintptr)(__ccgo_up(pCArray + 32 + uintptr(k)*8))
	pData = pEnd
	for int32(1) != 0 {
		pCell = **(**uintptr)(__ccgo_up((*TCellArray)(unsafe.Pointer(pCArray)).FapCell + uintptr(i)*8))
		sz = **(**Tu16)(__ccgo_up((*TCellArray)(unsafe.Pointer(pCArray)).FszCell + uintptr(i)*2))
		if uint64(pCell) >= uint64(aData+uintptr(j)) && uint64(pCell) < uint64(pEnd) {
			if uint64(pCell+uintptr(sz)) > uint64(pEnd) {
				return _sqlite3CorruptError(tls, int32(80813))
			}
			pCell = pTmp + uintptr(int64(pCell)-int64(aData))
		} else {
			if uint64(pCell+uintptr(sz)) > uint64(pSrcEnd) && uint64(pCell) < uint64(pSrcEnd) {
				return _sqlite3CorruptError(tls, int32(80818))
			}
		}
		pData = pData - uintptr(sz)
		**(**Tu8)(__ccgo_up(pCellptr)) = libc.Uint8FromInt64((int64(pData) - int64(aData)) >> libc.Int32FromInt32(8))
		**(**Tu8)(__ccgo_up(pCellptr + 1)) = libc.Uint8FromInt64(int64(pData) - int64(aData))
		pCellptr = pCellptr + uintptr(2)
		if pData < pCellptr {
			return _sqlite3CorruptError(tls, int32(80824))
		}
		libc.Xmemmove(tls, pData, pCell, uint64(sz))
		i = i + 1
		if i >= iEnd {
			break
		}
		if **(**int32)(__ccgo_up(pCArray + 80 + uintptr(k)*4)) <= i {
			k = k + 1
			pSrcEnd = **(**uintptr)(__ccgo_up(pCArray + 32 + uintptr(k)*8))
		}
	}
	/* The pPg->nFree field is now set incorrectly. The caller will fix it. */
	(*TMemPage)(unsafe.Pointer(pPg)).FnCell = libc.Uint16FromInt32(nCell)
	(*TMemPage)(unsafe.Pointer(pPg)).FnOverflow = uint8(0)
	**(**Tu8)(__ccgo_up(aData + uintptr(hdr+int32(1)))) = libc.Uint8FromInt32(libc.Int32FromInt32(0) >> libc.Int32FromInt32(8))
	**(**Tu8)(__ccgo_up(aData + uintptr(hdr+int32(1)) + 1)) = libc.Uint8FromInt32(libc.Int32FromInt32(0))
	**(**Tu8)(__ccgo_up(aData + uintptr(hdr+int32(3)))) = libc.Uint8FromInt32(libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPg)).FnCell) >> libc.Int32FromInt32(8))
	**(**Tu8)(__ccgo_up(aData + uintptr(hdr+int32(3)) + 1)) = uint8((*TMemPage)(unsafe.Pointer(pPg)).FnCell)
	**(**Tu8)(__ccgo_up(aData + uintptr(hdr+int32(5)))) = libc.Uint8FromInt64((int64(pData) - int64(aData)) >> libc.Int32FromInt32(8))
	**(**Tu8)(__ccgo_up(aData + uintptr(hdr+int32(5)) + 1)) = libc.Uint8FromInt64(int64(pData) - int64(aData))
	**(**Tu8)(__ccgo_up(aData + uintptr(hdr+int32(7)))) = uint8(0x00)
	return SQLITE_OK
}

// C documentation
//
//	/* Resize the hash table so that it contains "new_size" buckets.
//	**
//	** The hash table might fail to resize if sqlite3_malloc() fails or
//	** if the new size is the same as the prior size.
//	** Return TRUE if the resize occurs and false if not.
//	*/
func _rehash(tls *libc.TLS, pH uintptr, new_size uint32) (r int32) {
	var elem, new_ht, next_elem uintptr
	var v1 uint32
	_, _, _, _ = elem, new_ht, next_elem, v1 /* For looping over existing elements */
	if uint64(new_size)*uint64(16) > uint64(SQLITE_MALLOC_SOFT_LIMIT) {
		new_size = uint32(libc.Uint64FromInt32(SQLITE_MALLOC_SOFT_LIMIT) / libc.Uint64FromInt64(16))
	}
	if new_size == (*THash)(unsafe.Pointer(pH)).Fhtsize {
		return 0
	}
	/* The inability to allocates space for a larger hash table is
	 ** a performance hit but it is not a fatal error.  So mark the
	 ** allocation as a benign. Use sqlite3Malloc()/memset(0) instead of
	 ** sqlite3MallocZero() to make the allocation, as sqlite3MallocZero()
	 ** only zeroes the requested number of bytes whereas this module will
	 ** use the actual amount of space allocated for the hash table (which
	 ** may be larger than the requested amount).
	 */
	_sqlite3BeginBenignMalloc(tls)
	new_ht = _sqlite3Malloc(tls, uint64(new_size)*uint64(16))
	_sqlite3EndBenignMalloc(tls)
	if new_ht == uintptr(0) {
		return 0
	}
	Xsqlite3_free(tls, (*THash)(unsafe.Pointer(pH)).Fht)
	(*THash)(unsafe.Pointer(pH)).Fht = new_ht
	v1 = uint32(libc.Uint64FromInt32(_sqlite3MallocSize(tls, new_ht)) / libc.Uint64FromInt64(16))
	new_size = v1
	(*THash)(unsafe.Pointer(pH)).Fhtsize = v1
	libc.Xmemset(tls, new_ht, 0, uint64(new_size)*uint64(16))
	elem = (*THash)(unsafe.Pointer(pH)).Ffirst
	(*THash)(unsafe.Pointer(pH)).Ffirst = libc.UintptrFromInt32(0)
	for {
		if !(elem != 0) {
			break
		}
		next_elem = (*THashElem)(unsafe.Pointer(elem)).Fnext
		_insertElement(tls, pH, new_ht+uintptr((*THashElem)(unsafe.Pointer(elem)).Fh%new_size)*16, elem)
		goto _2
	_2:
		;
		elem = next_elem
	}
	return int32(1)
}

// C documentation
//
//	/* SQL function: sqlite_rename_quotefix(DB,SQL)
//	**
//	** Rewrite the DDL statement "SQL" so that any string literals that use
//	** double-quotes use single quotes instead.
//	**
//	** Two arguments must be passed:
//	**
//	**   0: Database name ("main", "temp" etc.).
//	**   1: SQL statement to edit.
//	**
//	** The returned value is the modified SQL statement. For example, given
//	** the database schema:
//	**
//	**   CREATE TABLE t1(a, b, c);
//	**
//	**   SELECT sqlite_rename_quotefix('main',
//	**       'CREATE VIEW v1 AS SELECT "a", "string" FROM t1'
//	**   );
//	**
//	** returns the string:
//	**
//	**   CREATE VIEW v1 AS SELECT "a", 'string' FROM t1
//	**
//	** If there is a error in the input SQL, then raise an error, except
//	** if PRAGMA writable_schema=ON, then just return the input string
//	** unmodified following an error.
//	*/
func _renameQuotefixFunc(tls *libc.TLS, context uintptr, NotUsed int32, argv uintptr) {
	bp := tls.Alloc(496)
	defer tls.Free(496)
	var db, pSelect, zDb, zInput uintptr
	var i, rc, v1 int32
	var xAuth Tsqlite3_xauth
	var _ /* sCtx at bp+416 */ TRenameCtx
	var _ /* sParse at bp+0 */ TParse
	var _ /* sWalker at bp+448 */ TWalker
	_, _, _, _, _, _, _, _ = db, i, pSelect, rc, xAuth, zDb, zInput, v1
	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*8)))
	xAuth = (*Tsqlite3)(unsafe.Pointer(db)).FxAuth
	(*Tsqlite3)(unsafe.Pointer(db)).FxAuth = uintptr(0)
	_sqlite3BtreeEnterAll(tls, db)
	_ = NotUsed
	if zDb != 0 && zInput != 0 {
		rc = _renameParseSql(tls, bp, zDb, db, zInput, 0)
		if rc == SQLITE_OK {
			/* Walker to find tokens that need to be replaced. */
			libc.Xmemset(tls, bp+416, 0, uint64(32))
			libc.Xmemset(tls, bp+448, 0, uint64(48))
			(**(**TWalker)(__ccgo_up(bp + 448))).FpParse = bp
			(**(**TWalker)(__ccgo_up(bp + 448))).FxExprCallback = __ccgo_fp(_renameQuotefixExprCb)
			(**(**TWalker)(__ccgo_up(bp + 448))).FxSelectCallback = __ccgo_fp(_renameColumnSelectCb)
			*(*uintptr)(unsafe.Pointer(bp + 448 + 40)) = bp + 416
			if (**(**TParse)(__ccgo_up(bp))).FpNewTable != 0 {
				if libc.Int32FromUint8((*TTable)(unsafe.Pointer((**(**TParse)(__ccgo_up(bp))).FpNewTable)).FeTabType) == int32(TABTYP_VIEW) {
					pSelect = (*(*struct {
						FpSelect uintptr
					})(unsafe.Pointer(&(*TTable)(unsafe.Pointer((**(**TParse)(__ccgo_up(bp))).FpNewTable)).Fu))).FpSelect
					**(**Tu32)(__ccgo_up(pSelect + 4)) &= ^libc.Uint32FromInt32(SF_View)
					(**(**TParse)(__ccgo_up(bp))).Frc = SQLITE_OK
					_sqlite3SelectPrep(tls, bp, pSelect, uintptr(0))
					if (*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0 {
						v1 = int32(SQLITE_NOMEM)
					} else {
						v1 = (**(**TParse)(__ccgo_up(bp))).Frc
					}
					rc = v1
					if rc == SQLITE_OK {
						_sqlite3WalkSelect(tls, bp+448, pSelect)
					}
				} else {
					_sqlite3WalkExprList(tls, bp+448, (*TTable)(unsafe.Pointer((**(**TParse)(__ccgo_up(bp))).FpNewTable)).FpCheck)
					i = 0
					for {
						if !(i < int32((*TTable)(unsafe.Pointer((**(**TParse)(__ccgo_up(bp))).FpNewTable)).FnCol)) {
							break
						}
						_sqlite3WalkExpr(tls, bp+448, _sqlite3ColumnExpr(tls, (**(**TParse)(__ccgo_up(bp))).FpNewTable, (*TTable)(unsafe.Pointer((**(**TParse)(__ccgo_up(bp))).FpNewTable)).FaCol+uintptr(i)*16))
						goto _2
					_2:
						;
						i = i + 1
					}
				}
			} else {
				if (**(**TParse)(__ccgo_up(bp))).FpNewIndex != 0 {
					_sqlite3WalkExprList(tls, bp+448, (*TIndex)(unsafe.Pointer((**(**TParse)(__ccgo_up(bp))).FpNewIndex)).FaColExpr)
					_sqlite3WalkExpr(tls, bp+448, (*TIndex)(unsafe.Pointer((**(**TParse)(__ccgo_up(bp))).FpNewIndex)).FpPartIdxWhere)
				} else {
					rc = _renameResolveTrigger(tls, bp)
					if rc == SQLITE_OK {
						_renameWalkTrigger(tls, bp+448, (**(**TParse)(__ccgo_up(bp))).FpNewTrigger)
					}
				}
			}
			if rc == SQLITE_OK {
				rc = _renameEditSql(tls, context, bp+416, zInput, uintptr(0), 0)
			}
			_renameTokenFree(tls, db, (**(**TRenameCtx)(__ccgo_up(bp + 416))).FpList)
		}
		if rc != SQLITE_OK {
			if _sqlite3WritableSchema(tls, db) != 0 && rc == int32(SQLITE_ERROR) {
				Xsqlite3_result_value(tls, context, **(**uintptr)(__ccgo_up(argv + 1*8)))
			} else {
				Xsqlite3_result_error_code(tls, context, rc)
			}
		}
		_renameParseCleanup(tls, bp)
	}
	(*Tsqlite3)(unsafe.Pointer(db)).FxAuth = xAuth
	_sqlite3BtreeLeaveAll(tls, db)
}

// 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(480)
	defer tls.Free(480)
	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+416 */ 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*8)))
	bTemp = Xsqlite3_value_int(tls, **(**uintptr)(__ccgo_up(argv + 4*8)))
	isLegacy = libc.Int32FromUint64((*Tsqlite3)(unsafe.Pointer(db)).Fflags & libc.Uint64FromInt32(SQLITE_LegacyAlter))
	zWhen = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv + 5*8)))
	bNoDQS = Xsqlite3_value_int(tls, **(**uintptr)(__ccgo_up(argv + 6*8)))
	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 + 48)) &= 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+416, 0, uint64(56))
				(**(**TNameContext)(__ccgo_up(bp + 416))).FpParse = bp
				_sqlite3SelectPrep(tls, bp, (*(*struct {
					FpSelect uintptr
				})(unsafe.Pointer(&(*TTable)(unsafe.Pointer((**(**TParse)(__ccgo_up(bp))).FpNewTable)).Fu))).FpSelect, bp+416)
				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*8)), **(**uintptr)(__ccgo_up(argv + 3*8)), 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*8)))
	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*8)))
	/* No encoding change */
	zRep = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv + 2*8)))
	if zRep == uintptr(0) {
		return
	}
	nRep = Xsqlite3_value_bytes(tls, **(**uintptr)(__ccgo_up(argv + 2*8)))
	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.Uint64FromInt32(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 + 136))) {
					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.Uint64FromInt32(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.Uint64FromInt32(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
//
//	/*
//	** Resize an Index object to hold N columns total.  Return SQLITE_OK
//	** on success and SQLITE_NOMEM on an OOM error.
//	*/
func _resizeIndexObject(tls *libc.TLS, pParse uintptr, pIdx uintptr, N int32) (r int32) {
	var db, zExtra uintptr
	var nByte Tu64
	_, _, _ = db, nByte, zExtra
	if libc.Int32FromUint16((*TIndex)(unsafe.Pointer(pIdx)).FnColumn) >= N {
		return SQLITE_OK
	}
	db = (*TParse)(unsafe.Pointer(pParse)).Fdb
	nByte = uint64(libc.Uint64FromInt64(8)+libc.Uint64FromInt64(2)+libc.Uint64FromInt64(2)+libc.Uint64FromInt32(1)) * libc.Uint64FromInt32(N)
	zExtra = _sqlite3DbMallocZero(tls, db, nByte)
	if zExtra == uintptr(0) {
		return int32(SQLITE_NOMEM)
	}
	libc.Xmemcpy(tls, zExtra, (*TIndex)(unsafe.Pointer(pIdx)).FazColl, uint64(8)*uint64((*TIndex)(unsafe.Pointer(pIdx)).FnColumn))
	(*TIndex)(unsafe.Pointer(pIdx)).FazColl = zExtra
	zExtra = zExtra + uintptr(uint64(8)*libc.Uint64FromInt32(N))
	libc.Xmemcpy(tls, zExtra, (*TIndex)(unsafe.Pointer(pIdx)).FaiRowLogEst, uint64(2)*libc.Uint64FromInt32(libc.Int32FromUint16((*TIndex)(unsafe.Pointer(pIdx)).FnKeyCol)+libc.Int32FromInt32(1)))
	(*TIndex)(unsafe.Pointer(pIdx)).FaiRowLogEst = zExtra
	zExtra = zExtra + uintptr(uint64(2)*libc.Uint64FromInt32(N))
	libc.Xmemcpy(tls, zExtra, (*TIndex)(unsafe.Pointer(pIdx)).FaiColumn, uint64(2)*uint64((*TIndex)(unsafe.Pointer(pIdx)).FnColumn))
	(*TIndex)(unsafe.Pointer(pIdx)).FaiColumn = zExtra
	zExtra = zExtra + uintptr(uint64(2)*libc.Uint64FromInt32(N))
	libc.Xmemcpy(tls, zExtra, (*TIndex)(unsafe.Pointer(pIdx)).FaSortOrder, uint64((*TIndex)(unsafe.Pointer(pIdx)).FnColumn))
	(*TIndex)(unsafe.Pointer(pIdx)).FaSortOrder = zExtra
	(*TIndex)(unsafe.Pointer(pIdx)).FnColumn = libc.Uint16FromInt32(N) /* See tag-20250221-1 above for proof of safety */
	libc.SetBitFieldPtr16Uint32(pIdx+100, libc.Uint32FromInt32(1), 4, 0x10)
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** Turn the pExpr expression into an alias for the iCol-th column of the
//	** result set in pEList.
//	**
//	** If the reference is followed by a COLLATE operator, then make sure
//	** the COLLATE operator is preserved.  For example:
//	**
//	**     SELECT a+b, c+d FROM t1 ORDER BY 1 COLLATE nocase;
//	**
//	** Should be transformed into:
//	**
//	**     SELECT a+b, c+d FROM t1 ORDER BY (a+b) COLLATE nocase;
//	**
//	** The nSubquery parameter specifies how many levels of subquery the
//	** alias is removed from the original expression.  The usual value is
//	** zero but it might be more if the alias is contained within a subquery
//	** of the original expression.  The Expr.op2 field of TK_AGG_FUNCTION
//	** structures must be increased by the nSubquery amount.
//	*/
func _resolveAlias(tls *libc.TLS, pParse uintptr, pEList uintptr, iCol int32, pExpr uintptr, nSubquery int32) {
	bp := tls.Alloc(80)
	defer tls.Free(80)
	var db, pDup, pOrig uintptr
	var _ /* temp at bp+0 */ TExpr
	_, _, _ = db, pDup, pOrig /* The database connection */
	pOrig = (*(*TExprList_item)(unsafe.Pointer(pEList + 8 + uintptr(iCol)*32))).FpExpr
	if (*TExpr)(unsafe.Pointer(pExpr)).FpAggInfo != 0 {
		return
	}
	db = (*TParse)(unsafe.Pointer(pParse)).Fdb
	pDup = _sqlite3ExprDup(tls, db, pOrig, 0)
	if (*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0 {
		_sqlite3ExprDelete(tls, db, pDup)
		pDup = uintptr(0)
	} else {
		_incrAggFunctionDepth(tls, pDup, nSubquery)
		if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) == int32(TK_COLLATE) {
			pDup = _sqlite3ExprAddCollateString(tls, pParse, pDup, *(*uintptr)(unsafe.Pointer(pExpr + 8)))
		}
		libc.Xmemcpy(tls, bp, pDup, uint64(72))
		libc.Xmemcpy(tls, pDup, pExpr, uint64(72))
		libc.Xmemcpy(tls, pExpr, bp, uint64(72))
		if (*TExpr)(unsafe.Pointer(pExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_WinFunc)) != uint32(0) {
			if *(*uintptr)(unsafe.Pointer(pExpr + 64)) != uintptr(0) {
				(*TWindow)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pExpr + 64)))).FpOwner = pExpr
			}
		}
		_sqlite3ExprDeferredDelete(tls, pParse, pDup)
	}
}

// C documentation
//
//	/*
//	** The xUpdate method for rtree module virtual tables.
//	*/
func _rtreeUpdate(tls *libc.TLS, pVtab uintptr, nData int32, aData uintptr, pRowid uintptr) (r int32) {
	bp := tls.Alloc(64)
	defer tls.Free(64)
	var bHaveRowid, ii, jj, nn, rc, rc2, steprc int32
	var pRtree, pUp uintptr
	var _ /* cell at bp+0 */ TRtreeCell
	var _ /* pLeaf at bp+48 */ uintptr
	_, _, _, _, _, _, _, _, _ = bHaveRowid, ii, jj, nn, pRtree, pUp, rc, rc2, steprc
	pRtree = pVtab
	rc = SQLITE_OK /* New cell to insert if nData>1 */
	bHaveRowid = 0 /* Set to 1 after new rowid is determined */
	if (*TRtree)(unsafe.Pointer(pRtree)).FnNodeRef != 0 {
		/* Unable to write to the btree while another cursor is reading from it,
		 ** since the write might do a rebalance which would disrupt the read
		 ** cursor. */
		return libc.Int32FromInt32(SQLITE_LOCKED) | libc.Int32FromInt32(2)<<libc.Int32FromInt32(8)
	}
	_rtreeReference(tls, pRtree)
	libc.Xmemset(tls, bp, 0, uint64(48))
	/* Constraint handling. A write operation on an r-tree table may return
	 ** SQLITE_CONSTRAINT for two reasons:
	 **
	 **   1. A duplicate rowid value, or
	 **   2. The supplied data violates the "x2>=x1" constraint.
	 **
	 ** In the first case, if the conflict-handling mode is REPLACE, then
	 ** the conflicting row can be removed before proceeding. In the second
	 ** case, SQLITE_CONSTRAINT must be returned regardless of the
	 ** conflict-handling mode specified by the user.
	 */
	if nData > int32(1) {
		nn = nData - int32(4)
		if nn > libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FnDim2) {
			nn = libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FnDim2)
		}
		/* Populate the cell.aCoord[] array. The first coordinate is aData[3].
		 **
		 ** NB: nData can only be less than nDim*2+3 if the rtree is mis-declared
		 ** with "column" that are interpreted as table constraints.
		 ** Example:  CREATE VIRTUAL TABLE bad USING rtree(x,y,CHECK(y>5));
		 ** This problem was discovered after years of use, so we silently ignore
		 ** these kinds of misdeclared tables to avoid breaking any legacy.
		 */
		if libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FeCoordType) == RTREE_COORD_REAL32 {
			ii = 0
			for {
				if !(ii < nn) {
					break
				}
				*(*TRtreeValue)(unsafe.Pointer(bp + 8 + uintptr(ii)*4)) = _rtreeValueDown(tls, **(**uintptr)(__ccgo_up(aData + uintptr(ii+int32(3))*8)))
				*(*TRtreeValue)(unsafe.Pointer(bp + 8 + uintptr(ii+int32(1))*4)) = _rtreeValueUp(tls, **(**uintptr)(__ccgo_up(aData + uintptr(ii+int32(4))*8)))
				if *(*TRtreeValue)(unsafe.Pointer(bp + 8 + uintptr(ii)*4)) > *(*TRtreeValue)(unsafe.Pointer(bp + 8 + uintptr(ii+int32(1))*4)) {
					rc = _rtreeConstraintError(tls, pRtree, ii+int32(1))
					goto constraint
				}
				goto _1
			_1:
				;
				ii = ii + int32(2)
			}
		} else {
			ii = 0
			for {
				if !(ii < nn) {
					break
				}
				*(*int32)(unsafe.Pointer(bp + 8 + uintptr(ii)*4)) = Xsqlite3_value_int(tls, **(**uintptr)(__ccgo_up(aData + uintptr(ii+int32(3))*8)))
				*(*int32)(unsafe.Pointer(bp + 8 + uintptr(ii+int32(1))*4)) = Xsqlite3_value_int(tls, **(**uintptr)(__ccgo_up(aData + uintptr(ii+int32(4))*8)))
				if *(*int32)(unsafe.Pointer(bp + 8 + uintptr(ii)*4)) > *(*int32)(unsafe.Pointer(bp + 8 + uintptr(ii+int32(1))*4)) {
					rc = _rtreeConstraintError(tls, pRtree, ii+int32(1))
					goto constraint
				}
				goto _2
			_2:
				;
				ii = ii + int32(2)
			}
		}
		/* If a rowid value was supplied, check if it is already present in
		 ** the table. If so, the constraint has failed. */
		if Xsqlite3_value_type(tls, **(**uintptr)(__ccgo_up(aData + 2*8))) != int32(SQLITE_NULL) {
			(**(**TRtreeCell)(__ccgo_up(bp))).FiRowid = Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(aData + 2*8)))
			if Xsqlite3_value_type(tls, **(**uintptr)(__ccgo_up(aData))) == int32(SQLITE_NULL) || Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(aData))) != (**(**TRtreeCell)(__ccgo_up(bp))).FiRowid {
				Xsqlite3_bind_int64(tls, (*TRtree)(unsafe.Pointer(pRtree)).FpReadRowid, int32(1), (**(**TRtreeCell)(__ccgo_up(bp))).FiRowid)
				steprc = Xsqlite3_step(tls, (*TRtree)(unsafe.Pointer(pRtree)).FpReadRowid)
				rc = Xsqlite3_reset(tls, (*TRtree)(unsafe.Pointer(pRtree)).FpReadRowid)
				if int32(SQLITE_ROW) == steprc {
					if Xsqlite3_vtab_on_conflict(tls, (*TRtree)(unsafe.Pointer(pRtree)).Fdb) == int32(SQLITE_REPLACE) {
						rc = _rtreeDeleteRowid(tls, pRtree, (**(**TRtreeCell)(__ccgo_up(bp))).FiRowid)
					} else {
						rc = _rtreeConstraintError(tls, pRtree, 0)
						goto constraint
					}
				}
			}
			bHaveRowid = int32(1)
		}
	}
	/* If aData[0] is not an SQL NULL value, it is the rowid of a
	 ** record to delete from the r-tree table. The following block does
	 ** just that.
	 */
	if Xsqlite3_value_type(tls, **(**uintptr)(__ccgo_up(aData))) != int32(SQLITE_NULL) {
		rc = _rtreeDeleteRowid(tls, pRtree, Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(aData))))
	}
	/* If the aData[] array contains more than one element, elements
	 ** (aData[2]..aData[argc-1]) contain a new record to insert into
	 ** the r-tree structure.
	 */
	if rc == SQLITE_OK && nData > int32(1) {
		/* Insert the new record into the r-tree */
		**(**uintptr)(__ccgo_up(bp + 48)) = uintptr(0)
		/* Figure out the rowid of the new row. */
		if bHaveRowid == 0 {
			rc = _rtreeNewRowid(tls, pRtree, bp)
		}
		**(**Tsqlite_int64)(__ccgo_up(pRowid)) = (**(**TRtreeCell)(__ccgo_up(bp))).FiRowid
		if rc == SQLITE_OK {
			rc = _ChooseLeaf(tls, pRtree, bp, 0, bp+48)
		}
		if rc == SQLITE_OK {
			rc = _rtreeInsertCell(tls, pRtree, **(**uintptr)(__ccgo_up(bp + 48)), bp, 0)
			rc2 = _nodeRelease(tls, pRtree, **(**uintptr)(__ccgo_up(bp + 48)))
			if rc == SQLITE_OK {
				rc = rc2
			}
		}
		if rc == SQLITE_OK && (*TRtree)(unsafe.Pointer(pRtree)).FnAux != 0 {
			pUp = (*TRtree)(unsafe.Pointer(pRtree)).FpWriteAux
			Xsqlite3_bind_int64(tls, pUp, int32(1), **(**Tsqlite_int64)(__ccgo_up(pRowid)))
			jj = 0
			for {
				if !(jj < libc.Int32FromUint16((*TRtree)(unsafe.Pointer(pRtree)).FnAux)) {
					break
				}
				Xsqlite3_bind_value(tls, pUp, jj+int32(2), **(**uintptr)(__ccgo_up(aData + uintptr(libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FnDim2)+int32(3)+jj)*8)))
				goto _3
			_3:
				;
				jj = jj + 1
			}
			Xsqlite3_step(tls, pUp)
			rc = Xsqlite3_reset(tls, pUp)
		}
	}
	goto constraint
constraint:
	;
	_rtreeRelease(tls, pRtree)
	return rc
}

// 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, uint64(8)*libc.Uint64FromInt32((*TStatAccum)(unsafe.Pointer(p)).FnCol))
	libc.Xmemcpy(tls, (*TStatSample)(unsafe.Pointer(pTo)).FanLt, (*TStatSample)(unsafe.Pointer(pFrom)).FanLt, uint64(8)*libc.Uint64FromInt32((*TStatAccum)(unsafe.Pointer(p)).FnCol))
	libc.Xmemcpy(tls, (*TStatSample)(unsafe.Pointer(pTo)).FanDLt, (*TStatSample)(unsafe.Pointer(pFrom)).FanDLt, uint64(8)*libc.Uint64FromInt32((*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(pFrom + 24)))
	} else {
		_sampleSetRowidInt64(tls, (*TStatAccum)(unsafe.Pointer(p)).Fdb, pTo, *(*Ti64)(unsafe.Pointer(pFrom + 24)))
	}
}

// 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)*48
			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)*48
		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*48, uint64(48)*libc.Uint64FromInt32((*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))*48
		(*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)*48
	_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, uint64(8)*libc.Uint64FromInt32(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)*48))).FisPSample != 0 {
				goto _2
			}
			if iMin < 0 || _sampleIsBetter(tls, p, (*TStatAccum)(unsafe.Pointer(p)).Fa+uintptr(iMin)*48, (*TStatAccum)(unsafe.Pointer(p)).Fa+uintptr(i)*48) != 0 {
				iMin = i
			}
			goto _2
		_2:
			;
			i = i + 1
		}
		(*TStatAccum)(unsafe.Pointer(p)).FiMin = iMin
	}
}

// C documentation
//
//	/* Initialize the BLOB value of a ROWID
//	*/
func _sampleSetRowid(tls *libc.TLS, db uintptr, p uintptr, n int32, pData uintptr) {
	if (*TStatSample)(unsafe.Pointer(p)).FnRowid != 0 {
		_sqlite3DbFree(tls, db, *(*uintptr)(unsafe.Pointer(p + 24)))
	}
	*(*uintptr)(unsafe.Pointer(p + 24)) = _sqlite3DbMallocRawNN(tls, db, libc.Uint64FromInt32(n))
	if *(*uintptr)(unsafe.Pointer(p + 24)) != 0 {
		(*TStatSample)(unsafe.Pointer(p)).FnRowid = libc.Uint32FromInt32(n)
		libc.Xmemcpy(tls, *(*uintptr)(unsafe.Pointer(p + 24)), pData, libc.Uint64FromInt32(n))
	} else {
		(*TStatSample)(unsafe.Pointer(p)).FnRowid = uint32(0)
	}
}

// C documentation
//
//	/*
//	** The cursor passed as the only argument must point to a valid entry
//	** when this function is called (i.e. have eState==CURSOR_VALID). This
//	** function saves the current cursor key in variables pCur->nKey and
//	** pCur->pKey. SQLITE_OK is returned if successful or an SQLite error
//	** code otherwise.
//	**
//	** If the cursor is open on an intkey table, then the integer key
//	** (the rowid) is stored in pCur->nKey and pCur->pKey is left set to
//	** NULL. If the cursor is open on a non-intkey table, then pCur->pKey is
//	** set to point to a malloced buffer pCur->nKey bytes in size containing
//	** the key.
//	*/
func _saveCursorKey(tls *libc.TLS, pCur uintptr) (r int32) {
	var pKey uintptr
	var rc int32
	_, _ = pKey, rc
	rc = SQLITE_OK
	if (*TBtCursor)(unsafe.Pointer(pCur)).FcurIntKey != 0 {
		/* Only the rowid is required for a table btree */
		(*TBtCursor)(unsafe.Pointer(pCur)).FnKey = _sqlite3BtreeIntegerKey(tls, pCur)
	} else {
		(*TBtCursor)(unsafe.Pointer(pCur)).FnKey = libc.Int64FromUint32(_sqlite3BtreePayloadSize(tls, pCur))
		pKey = _sqlite3Malloc(tls, libc.Uint64FromInt64((*TBtCursor)(unsafe.Pointer(pCur)).FnKey+int64(9)+int64(8)))
		if pKey != 0 {
			rc = _sqlite3BtreePayload(tls, pCur, uint32(0), libc.Uint32FromInt32(int32((*TBtCursor)(unsafe.Pointer(pCur)).FnKey)), pKey)
			if rc == SQLITE_OK {
				libc.Xmemset(tls, pKey+uintptr((*TBtCursor)(unsafe.Pointer(pCur)).FnKey), 0, libc.Uint64FromInt32(libc.Int32FromInt32(9)+libc.Int32FromInt32(8)))
				(*TBtCursor)(unsafe.Pointer(pCur)).FpKey = pKey
			} else {
				Xsqlite3_free(tls, pKey)
			}
		} else {
			rc = int32(SQLITE_NOMEM)
		}
	}
	return rc
}

// C documentation
//
//	/*
//	** The xSelect callback for the search of invalid ON clause terms.
//	*/
func _selectCheckOnClausesSelect(tls *libc.TLS, pWalker uintptr, pSelect uintptr) (r int32) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var pCtx uintptr
	var _ /* sCtx at bp+0 */ TCheckOnCtx
	_ = pCtx
	pCtx = *(*uintptr)(unsafe.Pointer(pWalker + 40))
	if (*TSelect)(unsafe.Pointer(pSelect)).FpSrc == (*TCheckOnCtx)(unsafe.Pointer(pCtx)).FpSrc || (*TSrcList)(unsafe.Pointer((*TSelect)(unsafe.Pointer(pSelect)).FpSrc)).FnSrc == 0 {
		return WRC_Continue
	} else {
		libc.Xmemset(tls, bp, 0, uint64(24))
		(**(**TCheckOnCtx)(__ccgo_up(bp))).FpSrc = (*TSelect)(unsafe.Pointer(pSelect)).FpSrc
		(**(**TCheckOnCtx)(__ccgo_up(bp))).FpParent = pCtx
		*(*uintptr)(unsafe.Pointer(pWalker + 40)) = bp
		_sqlite3WalkSelect(tls, pWalker, pSelect)
		*(*uintptr)(unsafe.Pointer(pWalker + 40)) = pCtx
		**(**Tu32)(__ccgo_up(pSelect + 4)) &= libc.Uint32FromInt32(^libc.Int32FromInt32(SF_OnToWhere))
		return int32(WRC_Prune)
	}
	return r
}

// C documentation
//
//	/*
//	** Callback function used by selectWindowRewriteEList(). If necessary,
//	** this function appends to the output expression-list and updates
//	** expression (*ppExpr) in place.
//	*/
func _selectWindowRewriteExprCb(tls *libc.TLS, pWalker uintptr, pExpr uintptr) (r int32) {
	var f, i, i1, iCol, nSrc, v4 int32
	var p, pDup, pParse, pWin uintptr
	_, _, _, _, _, _, _, _, _, _ = f, i, i1, iCol, nSrc, p, pDup, pParse, pWin, v4
	p = *(*uintptr)(unsafe.Pointer(pWalker + 40))
	pParse = (*TWalker)(unsafe.Pointer(pWalker)).FpParse
	/* If this function is being called from within a scalar sub-select
	 ** that used by the SELECT statement being processed, only process
	 ** TK_COLUMN expressions that refer to it (the outer SELECT). Do
	 ** not process aggregates or window functions at all, as they belong
	 ** to the scalar sub-select.  */
	if (*TWindowRewrite)(unsafe.Pointer(p)).FpSubSelect != 0 {
		if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) != int32(TK_COLUMN) {
			return WRC_Continue
		} else {
			nSrc = (*TSrcList)(unsafe.Pointer((*TWindowRewrite)(unsafe.Pointer(p)).FpSrc)).FnSrc
			i = 0
			for {
				if !(i < nSrc) {
					break
				}
				if (*TExpr)(unsafe.Pointer(pExpr)).FiTable == (*(*TSrcItem)(unsafe.Pointer((*TWindowRewrite)(unsafe.Pointer(p)).FpSrc + 8 + uintptr(i)*80))).FiCursor {
					break
				}
				goto _1
			_1:
				;
				i = i + 1
			}
			if i == nSrc {
				return WRC_Continue
			}
		}
	}
	switch libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) {
	case int32(TK_FUNCTION):
		if !((*TExpr)(unsafe.Pointer(pExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_WinFunc)) != libc.Uint32FromInt32(0)) {
			break
		} else {
			pWin = (*TWindowRewrite)(unsafe.Pointer(p)).FpWin
			for {
				if !(pWin != 0) {
					break
				}
				if *(*uintptr)(unsafe.Pointer(pExpr + 64)) == pWin {
					return int32(WRC_Prune)
				}
				goto _2
			_2:
				;
				pWin = (*TWindow)(unsafe.Pointer(pWin)).FpNextWin
			}
		}
		fallthrough
	case int32(TK_IF_NULL_ROW):
		fallthrough
	case int32(TK_AGG_FUNCTION):
		fallthrough
	case int32(TK_COLUMN):
		iCol = -int32(1)
		if (*Tsqlite3)(unsafe.Pointer((*TParse)(unsafe.Pointer(pParse)).Fdb)).FmallocFailed != 0 {
			return int32(WRC_Abort)
		}
		if (*TWindowRewrite)(unsafe.Pointer(p)).FpSub != 0 {
			i1 = 0
			for {
				if !(i1 < (*TExprList)(unsafe.Pointer((*TWindowRewrite)(unsafe.Pointer(p)).FpSub)).FnExpr) {
					break
				}
				if 0 == _sqlite3ExprCompare(tls, uintptr(0), (*(*TExprList_item)(unsafe.Pointer((*TWindowRewrite)(unsafe.Pointer(p)).FpSub + 8 + uintptr(i1)*32))).FpExpr, pExpr, -int32(1)) {
					iCol = i1
					break
				}
				goto _3
			_3:
				;
				i1 = i1 + 1
			}
		}
		if iCol < 0 {
			pDup = _sqlite3ExprDup(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, pExpr, 0)
			if pDup != 0 && libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pDup)).Fop) == int32(TK_AGG_FUNCTION) {
				(*TExpr)(unsafe.Pointer(pDup)).Fop = uint8(TK_FUNCTION)
			}
			(*TWindowRewrite)(unsafe.Pointer(p)).FpSub = _sqlite3ExprListAppend(tls, pParse, (*TWindowRewrite)(unsafe.Pointer(p)).FpSub, pDup)
		}
		if (*TWindowRewrite)(unsafe.Pointer(p)).FpSub != 0 {
			f = libc.Int32FromUint32((*TExpr)(unsafe.Pointer(pExpr)).Fflags & uint32(EP_Collate))
			**(**Tu32)(__ccgo_up(pExpr + 4)) |= libc.Uint32FromInt32(libc.Int32FromInt32(EP_Static))
			_sqlite3ExprDelete(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, pExpr)
			**(**Tu32)(__ccgo_up(pExpr + 4)) &= ^libc.Uint32FromInt32(libc.Int32FromInt32(EP_Static))
			libc.Xmemset(tls, pExpr, 0, uint64(72))
			(*TExpr)(unsafe.Pointer(pExpr)).Fop = uint8(TK_COLUMN)
			if iCol < 0 {
				v4 = (*TExprList)(unsafe.Pointer((*TWindowRewrite)(unsafe.Pointer(p)).FpSub)).FnExpr - int32(1)
			} else {
				v4 = iCol
			}
			(*TExpr)(unsafe.Pointer(pExpr)).FiColumn = int16(v4)
			(*TExpr)(unsafe.Pointer(pExpr)).FiTable = (*TWindow)(unsafe.Pointer((*TWindowRewrite)(unsafe.Pointer(p)).FpWin)).FiEphCsr
			*(*uintptr)(unsafe.Pointer(pExpr + 64)) = (*TWindowRewrite)(unsafe.Pointer(p)).FpTab
			(*TExpr)(unsafe.Pointer(pExpr)).Fflags = libc.Uint32FromInt32(f)
		}
		if (*Tsqlite3)(unsafe.Pointer((*TParse)(unsafe.Pointer(pParse)).Fdb)).FmallocFailed != 0 {
			return int32(WRC_Abort)
		}
	default: /* no-op */
		break
	}
	return WRC_Continue
}

// C documentation
//
//	/*
//	** Deserialize the data blob pointed to by buf as serial type serial_type
//	** and store the result in pMem.
//	**
//	** This function is implemented as two separate routines for performance.
//	** The few cases that require local variables are broken out into a separate
//	** routine so that in most cases the overhead of moving the stack pointer
//	** is avoided.
//	*/
func _serialGet(tls *libc.TLS, buf uintptr, serial_type Tu32, pMem uintptr) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var y Tu32
	var v1 int32
	var _ /* x at bp+0 */ Tu64
	_, _ = y, v1
	**(**Tu64)(__ccgo_up(bp)) = uint64(uint32(**(**uint8)(__ccgo_up(buf)))<<libc.Int32FromInt32(24) | libc.Uint32FromInt32(libc.Int32FromUint8(**(**uint8)(__ccgo_up(buf + 1)))<<libc.Int32FromInt32(16)) | libc.Uint32FromInt32(libc.Int32FromUint8(**(**uint8)(__ccgo_up(buf + 2)))<<libc.Int32FromInt32(8)) | uint32(**(**uint8)(__ccgo_up(buf + 3))))
	y = uint32(**(**uint8)(__ccgo_up(buf + libc.UintptrFromInt32(4))))<<libc.Int32FromInt32(24) | libc.Uint32FromInt32(libc.Int32FromUint8(**(**uint8)(__ccgo_up(buf + libc.UintptrFromInt32(4) + 1)))<<libc.Int32FromInt32(16)) | libc.Uint32FromInt32(libc.Int32FromUint8(**(**uint8)(__ccgo_up(buf + libc.UintptrFromInt32(4) + 2)))<<libc.Int32FromInt32(8)) | uint32(**(**uint8)(__ccgo_up(buf + libc.UintptrFromInt32(4) + 3)))
	**(**Tu64)(__ccgo_up(bp)) = **(**Tu64)(__ccgo_up(bp))<<libc.Int32FromInt32(32) + uint64(y)
	if serial_type == uint32(6) {
		/* EVIDENCE-OF: R-29851-52272 Value is a big-endian 64-bit
		 ** twos-complement integer. */
		*(*Ti64)(unsafe.Pointer(pMem)) = **(**Ti64)(__ccgo_up(bp))
		(*TMem)(unsafe.Pointer(pMem)).Fflags = uint16(MEM_Int)
	} else {
		/* EVIDENCE-OF: R-57343-49114 Value is a big-endian IEEE 754-2008 64-bit
		 ** floating point number. */
		libc.Xmemcpy(tls, pMem, bp, uint64(8))
		if **(**Tu64)(__ccgo_up(bp))&(libc.Uint64FromInt32(0x7ff)<<libc.Int32FromInt32(52)) == libc.Uint64FromInt32(0x7ff)<<libc.Int32FromInt32(52) && **(**Tu64)(__ccgo_up(bp))&(libc.Uint64FromInt32(1)<<libc.Int32FromInt32(52)-libc.Uint64FromInt32(1)) != uint64(0) {
			v1 = int32(MEM_Null)
		} else {
			v1 = int32(MEM_Real)
		}
		(*TMem)(unsafe.Pointer(pMem)).Fflags = libc.Uint16FromInt32(v1)
	}
}

func _serialGet7(tls *libc.TLS, buf uintptr, pMem uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var y Tu32
	var _ /* x at bp+0 */ Tu64
	_ = y
	**(**Tu64)(__ccgo_up(bp)) = uint64(uint32(**(**uint8)(__ccgo_up(buf)))<<libc.Int32FromInt32(24) | libc.Uint32FromInt32(libc.Int32FromUint8(**(**uint8)(__ccgo_up(buf + 1)))<<libc.Int32FromInt32(16)) | libc.Uint32FromInt32(libc.Int32FromUint8(**(**uint8)(__ccgo_up(buf + 2)))<<libc.Int32FromInt32(8)) | uint32(**(**uint8)(__ccgo_up(buf + 3))))
	y = uint32(**(**uint8)(__ccgo_up(buf + libc.UintptrFromInt32(4))))<<libc.Int32FromInt32(24) | libc.Uint32FromInt32(libc.Int32FromUint8(**(**uint8)(__ccgo_up(buf + libc.UintptrFromInt32(4) + 1)))<<libc.Int32FromInt32(16)) | libc.Uint32FromInt32(libc.Int32FromUint8(**(**uint8)(__ccgo_up(buf + libc.UintptrFromInt32(4) + 2)))<<libc.Int32FromInt32(8)) | uint32(**(**uint8)(__ccgo_up(buf + libc.UintptrFromInt32(4) + 3)))
	**(**Tu64)(__ccgo_up(bp)) = **(**Tu64)(__ccgo_up(bp))<<libc.Int32FromInt32(32) + uint64(y)
	libc.Xmemcpy(tls, pMem, bp, uint64(8))
	if **(**Tu64)(__ccgo_up(bp))&(libc.Uint64FromInt32(0x7ff)<<libc.Int32FromInt32(52)) == libc.Uint64FromInt32(0x7ff)<<libc.Int32FromInt32(52) && **(**Tu64)(__ccgo_up(bp))&(libc.Uint64FromInt32(1)<<libc.Int32FromInt32(52)-libc.Uint64FromInt32(1)) != uint64(0) {
		(*TMem)(unsafe.Pointer(pMem)).Fflags = uint16(MEM_Null)
		return int32(1)
	}
	(*TMem)(unsafe.Pointer(pMem)).Fflags = uint16(MEM_Real)
	return 0
}

// C documentation
//
//	/*
//	** This function is a no-op if *pRc is other than SQLITE_OK when it is
//	** called. Otherwise, append a blob of data to the buffer.
//	**
//	** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
//	** returning.
//	*/
func _sessionAppendBlob(tls *libc.TLS, p uintptr, aBlob uintptr, nBlob int32, pRc uintptr) {
	if nBlob > 0 && 0 == _sessionBufferGrow(tls, p, int64(nBlob), pRc) {
		libc.Xmemcpy(tls, (*TSessionBuffer)(unsafe.Pointer(p)).FaBuf+uintptr((*TSessionBuffer)(unsafe.Pointer(p)).FnBuf), aBlob, libc.Uint64FromInt32(nBlob))
		**(**int32)(__ccgo_up(p + 8)) += nBlob
	}
}

// C documentation
//
//	/*
//	** This function is called when rebasing a local UPDATE change against one
//	** or more remote UPDATE changes. The aRec/nRec buffer contains the current
//	** old.* and new.* records for the change. The rebase buffer (a single
//	** record) is in aChange/nChange. The rebased change is appended to buffer
//	** pBuf.
//	**
//	** Rebasing the UPDATE involves:
//	**
//	**   * Removing any changes to fields for which the corresponding field
//	**     in the rebase buffer is set to "replaced" (type 0xFF). If this
//	**     means the UPDATE change updates no fields, nothing is appended
//	**     to the output buffer.
//	**
//	**   * For each field modified by the local change for which the
//	**     corresponding field in the rebase buffer is not "undefined" (0x00)
//	**     or "replaced" (0xFF), the old.* value is replaced by the value
//	**     in the rebase buffer.
//	*/
func _sessionAppendPartialUpdate(tls *libc.TLS, pBuf uintptr, pIter uintptr, aRec uintptr, nRec int32, aChange uintptr, nChange int32, pRc uintptr) {
	var a1, a2, pOut, v1 uintptr
	var bData, i, n1, n11, n2, n21 int32
	_, _, _, _, _, _, _, _, _, _ = a1, a2, bData, i, n1, n11, n2, n21, pOut, v1
	_sessionBufferGrow(tls, pBuf, int64(int32(2)+nRec+nChange), pRc)
	if **(**int32)(__ccgo_up(pRc)) == SQLITE_OK {
		bData = 0
		pOut = (*TSessionBuffer)(unsafe.Pointer(pBuf)).FaBuf + uintptr((*TSessionBuffer)(unsafe.Pointer(pBuf)).FnBuf)
		a1 = aRec
		a2 = aChange
		v1 = pOut
		pOut = pOut + 1
		**(**Tu8)(__ccgo_up(v1)) = uint8(SQLITE_UPDATE)
		v1 = pOut
		pOut = pOut + 1
		**(**Tu8)(__ccgo_up(v1)) = libc.Uint8FromInt32((*Tsqlite3_changeset_iter)(unsafe.Pointer(pIter)).FbIndirect)
		i = 0
		for {
			if !(i < (*Tsqlite3_changeset_iter)(unsafe.Pointer(pIter)).FnCol) {
				break
			}
			n1 = _sessionSerialLen(tls, a1)
			n2 = _sessionSerialLen(tls, a2)
			if **(**Tu8)(__ccgo_up((*Tsqlite3_changeset_iter)(unsafe.Pointer(pIter)).FabPK + uintptr(i))) != 0 || libc.Int32FromUint8(**(**Tu8)(__ccgo_up(a2))) == 0 {
				if !(**(**Tu8)(__ccgo_up((*Tsqlite3_changeset_iter)(unsafe.Pointer(pIter)).FabPK + uintptr(i))) != 0) && **(**Tu8)(__ccgo_up(a1)) != 0 {
					bData = int32(1)
				}
				libc.Xmemcpy(tls, pOut, a1, libc.Uint64FromInt32(n1))
				pOut = pOut + uintptr(n1)
			} else {
				if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(a2))) != int32(0xFF) && **(**Tu8)(__ccgo_up(a1)) != 0 {
					bData = int32(1)
					libc.Xmemcpy(tls, pOut, a2, libc.Uint64FromInt32(n2))
					pOut = pOut + uintptr(n2)
				} else {
					v1 = pOut
					pOut = pOut + 1
					**(**Tu8)(__ccgo_up(v1)) = uint8('\000')
				}
			}
			a1 = a1 + uintptr(n1)
			a2 = a2 + uintptr(n2)
			goto _3
		_3:
			;
			i = i + 1
		}
		if bData != 0 {
			a2 = aChange
			i = 0
			for {
				if !(i < (*Tsqlite3_changeset_iter)(unsafe.Pointer(pIter)).FnCol) {
					break
				}
				n11 = _sessionSerialLen(tls, a1)
				n21 = _sessionSerialLen(tls, a2)
				if **(**Tu8)(__ccgo_up((*Tsqlite3_changeset_iter)(unsafe.Pointer(pIter)).FabPK + uintptr(i))) != 0 || libc.Int32FromUint8(**(**Tu8)(__ccgo_up(a2))) != int32(0xFF) {
					libc.Xmemcpy(tls, pOut, a1, libc.Uint64FromInt32(n11))
					pOut = pOut + uintptr(n11)
				} else {
					v1 = pOut
					pOut = pOut + 1
					**(**Tu8)(__ccgo_up(v1)) = uint8('\000')
				}
				a1 = a1 + uintptr(n11)
				a2 = a2 + uintptr(n21)
				goto _5
			_5:
				;
				i = i + 1
			}
			(*TSessionBuffer)(unsafe.Pointer(pBuf)).FnBuf = int32(int64(pOut) - int64((*TSessionBuffer)(unsafe.Pointer(pBuf)).FaBuf))
		}
	}
}

// C documentation
//
//	/*
//	** Buffers a1 and a2 must both contain a sessions module record nCol
//	** fields in size. This function appends an nCol sessions module
//	** record to buffer pBuf that is a copy of a1, except that for
//	** each field that is undefined in a1[], swap in the field from a2[].
//	*/
func _sessionAppendRecordMerge(tls *libc.TLS, pBuf uintptr, nCol int32, a1 uintptr, n1 int32, a2 uintptr, n2 int32, pRc uintptr) {
	var i, nn1, nn2 int32
	var pOut uintptr
	_, _, _, _ = i, nn1, nn2, pOut
	_sessionBufferGrow(tls, pBuf, int64(n1+n2), pRc)
	if **(**int32)(__ccgo_up(pRc)) == SQLITE_OK {
		pOut = (*TSessionBuffer)(unsafe.Pointer(pBuf)).FaBuf + uintptr((*TSessionBuffer)(unsafe.Pointer(pBuf)).FnBuf)
		i = 0
		for {
			if !(i < nCol) {
				break
			}
			nn1 = _sessionSerialLen(tls, a1)
			nn2 = _sessionSerialLen(tls, a2)
			if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(a1))) == 0 || libc.Int32FromUint8(**(**Tu8)(__ccgo_up(a1))) == int32(0xFF) {
				libc.Xmemcpy(tls, pOut, a2, libc.Uint64FromInt32(nn2))
				pOut = pOut + uintptr(nn2)
			} else {
				libc.Xmemcpy(tls, pOut, a1, libc.Uint64FromInt32(nn1))
				pOut = pOut + uintptr(nn1)
			}
			a1 = a1 + uintptr(nn1)
			a2 = a2 + uintptr(nn2)
			goto _1
		_1:
			;
			i = i + 1
		}
		(*TSessionBuffer)(unsafe.Pointer(pBuf)).FnBuf = int32(int64(pOut) - int64((*TSessionBuffer)(unsafe.Pointer(pBuf)).FaBuf))
	}
}

// C documentation
//
//	/*
//	** This function is a no-op if *pRc is other than SQLITE_OK when it is
//	** called. Otherwise, append a string to the buffer. All bytes in the string
//	** up to (but not including) the nul-terminator are written to the buffer.
//	**
//	** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
//	** returning.
//	*/
func _sessionAppendStr(tls *libc.TLS, p uintptr, zStr uintptr, pRc uintptr) {
	var nStr int32
	_ = nStr
	nStr = _sqlite3Strlen30(tls, zStr)
	if 0 == _sessionBufferGrow(tls, p, int64(nStr+int32(1)), pRc) {
		libc.Xmemcpy(tls, (*TSessionBuffer)(unsafe.Pointer(p)).FaBuf+uintptr((*TSessionBuffer)(unsafe.Pointer(p)).FnBuf), zStr, libc.Uint64FromInt32(nStr))
		**(**int32)(__ccgo_up(p + 8)) += nStr
		**(**Tu8)(__ccgo_up((*TSessionBuffer)(unsafe.Pointer(p)).FaBuf + uintptr((*TSessionBuffer)(unsafe.Pointer(p)).FnBuf))) = uint8(0x00)
	}
}

// C documentation
//
//	/*
//	**
//	** This function appends an update change to the buffer (see the comments
//	** under "CHANGESET FORMAT" at the top of the file). An update change
//	** consists of:
//	**
//	**   1 byte:  SQLITE_UPDATE (0x17)
//	**   n bytes: old.* record (see RECORD FORMAT)
//	**   m bytes: new.* record (see RECORD FORMAT)
//	**
//	** The SessionChange object passed as the third argument contains the
//	** values that were stored in the row when the session began (the old.*
//	** values). The statement handle passed as the second argument points
//	** at the current version of the row (the new.* values).
//	**
//	** If all of the old.* values are equal to their corresponding new.* value
//	** (i.e. nothing has changed), then no data at all is appended to the buffer.
//	**
//	** Otherwise, the old.* record contains all primary key values and the
//	** original values of any fields that have been modified. The new.* record
//	** contains the new values of only those fields that have been modified.
//	*/
func _sessionAppendUpdate(tls *libc.TLS, pBuf uintptr, bPatchset int32, pStmt uintptr, p uintptr, abPK uintptr) (r int32) {
	bp := tls.Alloc(48)
	defer tls.Free(48)
	var bChanged, bNoop, eType, i, nAdvance, nHdr, nRewind int32
	var pCsr uintptr
	var _ /* buf2 at bp+8 */ TSessionBuffer
	var _ /* dVal at bp+32 */ float64
	var _ /* iVal at bp+24 */ Tsqlite3_int64
	var _ /* n at bp+40 */ int32
	var _ /* rc at bp+0 */ int32
	_, _, _, _, _, _, _, _ = bChanged, bNoop, eType, i, nAdvance, nHdr, nRewind, pCsr
	**(**int32)(__ccgo_up(bp)) = SQLITE_OK
	**(**TSessionBuffer)(__ccgo_up(bp + 8)) = TSessionBuffer{} /* Buffer to accumulate new.* record in */
	bNoop = int32(1)                                           /* Set to zero if any values are modified */
	nRewind = (*TSessionBuffer)(unsafe.Pointer(pBuf)).FnBuf    /* Used to iterate through columns */
	pCsr = (*TSessionChange)(unsafe.Pointer(p)).FaRecord       /* Used to iterate through old.* values */
	_sessionAppendByte(tls, pBuf, uint8(SQLITE_UPDATE), bp)
	_sessionAppendByte(tls, pBuf, (*TSessionChange)(unsafe.Pointer(p)).FbIndirect, bp)
	i = 0
	for {
		if !(i < Xsqlite3_column_count(tls, pStmt)) {
			break
		}
		bChanged = 0
		eType = libc.Int32FromUint8(**(**Tu8)(__ccgo_up(pCsr)))
		switch eType {
		case int32(SQLITE_NULL):
			nAdvance = int32(1)
			if Xsqlite3_column_type(tls, pStmt, i) != int32(SQLITE_NULL) {
				bChanged = int32(1)
			}
		case int32(SQLITE_FLOAT):
			fallthrough
		case int32(SQLITE_INTEGER):
			nAdvance = int32(9)
			if eType == Xsqlite3_column_type(tls, pStmt, i) {
				**(**Tsqlite3_int64)(__ccgo_up(bp + 24)) = _sessionGetI64(tls, pCsr+1)
				if eType == int32(SQLITE_INTEGER) {
					if **(**Tsqlite3_int64)(__ccgo_up(bp + 24)) == Xsqlite3_column_int64(tls, pStmt, i) {
						break
					}
				} else {
					libc.Xmemcpy(tls, bp+32, bp+24, uint64(8))
					if **(**float64)(__ccgo_up(bp + 32)) == Xsqlite3_column_double(tls, pStmt, i) {
						break
					}
				}
			}
			bChanged = int32(1)
		default:
			nHdr = int32(1) + _sessionVarintGet(tls, pCsr+1, bp+40)
			nAdvance = nHdr + **(**int32)(__ccgo_up(bp + 40))
			if eType == Xsqlite3_column_type(tls, pStmt, i) && **(**int32)(__ccgo_up(bp + 40)) == Xsqlite3_column_bytes(tls, pStmt, i) && (**(**int32)(__ccgo_up(bp + 40)) == 0 || 0 == libc.Xmemcmp(tls, pCsr+uintptr(nHdr), Xsqlite3_column_blob(tls, pStmt, i), libc.Uint64FromInt32(**(**int32)(__ccgo_up(bp + 40))))) {
				break
			}
			bChanged = int32(1)
		}
		/* If at least one field has been modified, this is not a no-op. */
		if bChanged != 0 {
			bNoop = 0
		}
		/* Add a field to the old.* record. This is omitted if this module is
		 ** currently generating a patchset. */
		if bPatchset == 0 {
			if bChanged != 0 || **(**Tu8)(__ccgo_up(abPK + uintptr(i))) != 0 {
				_sessionAppendBlob(tls, pBuf, pCsr, nAdvance, bp)
			} else {
				_sessionAppendByte(tls, pBuf, uint8(0), bp)
			}
		}
		/* Add a field to the new.* record. Or the only record if currently
		 ** generating a patchset.  */
		if bChanged != 0 || bPatchset != 0 && **(**Tu8)(__ccgo_up(abPK + uintptr(i))) != 0 {
			_sessionAppendCol(tls, bp+8, pStmt, i, bp)
		} else {
			_sessionAppendByte(tls, bp+8, uint8(0), bp)
		}
		pCsr = pCsr + uintptr(nAdvance)
		goto _1
	_1:
		;
		i = i + 1
	}
	if bNoop != 0 {
		(*TSessionBuffer)(unsafe.Pointer(pBuf)).FnBuf = nRewind
	} else {
		_sessionAppendBlob(tls, pBuf, (**(**TSessionBuffer)(__ccgo_up(bp + 8))).FaBuf, (**(**TSessionBuffer)(__ccgo_up(bp + 8))).FnBuf, bp)
	}
	Xsqlite3_free(tls, (**(**TSessionBuffer)(__ccgo_up(bp + 8))).FaBuf)
	return **(**int32)(__ccgo_up(bp))
}

// C documentation
//
//	/*
//	** This function is called to merge two changes to the same row together as
//	** part of an sqlite3changeset_concat() operation. A new change object is
//	** allocated and a pointer to it stored in *ppNew.
//	**
//	** Because they have been vetted by sqlite3changegroup_add() or similar,
//	** both the aRec[] change and the pExist change are safe to use without
//	** checking for buffer overflows.
//	*/
func _sessionChangeMerge(tls *libc.TLS, pTab uintptr, bRebase int32, bPatchset int32, pExist uintptr, op2 int32, bIndirect int32, aRec uintptr, nRec int32, ppNew uintptr) (r int32) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var a1, a2, aExist, pIn, pNew, pOut, pOut1, v2 uintptr
	var i, i1, n1, n2, nIn, op1, rc int32
	var nByte, nByte1 Tsqlite3_int64
	var _ /* a1 at bp+16 */ uintptr
	var _ /* a1 at bp+8 */ uintptr
	var _ /* a2 at bp+24 */ uintptr
	var _ /* aCsr at bp+0 */ uintptr
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = a1, a2, aExist, i, i1, n1, n2, nByte, nByte1, nIn, op1, pIn, pNew, pOut, pOut1, rc, v2
	pNew = uintptr(0)
	rc = SQLITE_OK
	if !(pExist != 0) {
		pNew = Xsqlite3_malloc64(tls, uint64(uint64(32)+libc.Uint64FromInt32(nRec)))
		if !(pNew != 0) {
			return int32(SQLITE_NOMEM)
		}
		libc.Xmemset(tls, pNew, 0, uint64(32))
		(*TSessionChange)(unsafe.Pointer(pNew)).Fop = libc.Uint8FromInt32(op2)
		(*TSessionChange)(unsafe.Pointer(pNew)).FbIndirect = libc.Uint8FromInt32(bIndirect)
		(*TSessionChange)(unsafe.Pointer(pNew)).FaRecord = pNew + 1*32
		if bIndirect == 0 || bRebase == 0 {
			(*TSessionChange)(unsafe.Pointer(pNew)).FnRecord = nRec
			libc.Xmemcpy(tls, (*TSessionChange)(unsafe.Pointer(pNew)).FaRecord, aRec, libc.Uint64FromInt32(nRec))
		} else {
			pIn = aRec
			pOut = (*TSessionChange)(unsafe.Pointer(pNew)).FaRecord
			i = 0
			for {
				if !(i < (*TSessionTable)(unsafe.Pointer(pTab)).FnCol) {
					break
				}
				nIn = _sessionSerialLen(tls, pIn)
				if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(pIn))) == 0 {
					v2 = pOut
					pOut = pOut + 1
					**(**Tu8)(__ccgo_up(v2)) = uint8(0)
				} else {
					if libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TSessionTable)(unsafe.Pointer(pTab)).FabPK + uintptr(i)))) == 0 {
						v2 = pOut
						pOut = pOut + 1
						**(**Tu8)(__ccgo_up(v2)) = uint8(0xFF)
					} else {
						libc.Xmemcpy(tls, pOut, pIn, libc.Uint64FromInt32(nIn))
						pOut = pOut + uintptr(nIn)
					}
				}
				pIn = pIn + uintptr(nIn)
				goto _1
			_1:
				;
				i = i + 1
			}
			(*TSessionChange)(unsafe.Pointer(pNew)).FnRecord = int32(int64(pOut) - int64((*TSessionChange)(unsafe.Pointer(pNew)).FaRecord))
		}
	} else {
		if bRebase != 0 {
			if libc.Int32FromUint8((*TSessionChange)(unsafe.Pointer(pExist)).Fop) == int32(SQLITE_DELETE) && (*TSessionChange)(unsafe.Pointer(pExist)).FbIndirect != 0 {
				**(**uintptr)(__ccgo_up(ppNew)) = pExist
			} else {
				nByte = libc.Int64FromUint64(libc.Uint64FromInt32(nRec+(*TSessionChange)(unsafe.Pointer(pExist)).FnRecord) + uint64(32))
				pNew = Xsqlite3_malloc64(tls, libc.Uint64FromInt64(nByte))
				if pNew == uintptr(0) {
					rc = int32(SQLITE_NOMEM)
				} else {
					a1 = (*TSessionChange)(unsafe.Pointer(pExist)).FaRecord
					a2 = aRec
					libc.Xmemset(tls, pNew, 0, libc.Uint64FromInt64(nByte))
					(*TSessionChange)(unsafe.Pointer(pNew)).FbIndirect = libc.BoolUint8(bIndirect != 0 || (*TSessionChange)(unsafe.Pointer(pExist)).FbIndirect != 0)
					(*TSessionChange)(unsafe.Pointer(pNew)).Fop = libc.Uint8FromInt32(op2)
					v2 = pNew + 1*32
					(*TSessionChange)(unsafe.Pointer(pNew)).FaRecord = v2
					pOut1 = v2
					i1 = 0
					for {
						if !(i1 < (*TSessionTable)(unsafe.Pointer(pTab)).FnCol) {
							break
						}
						n1 = _sessionSerialLen(tls, a1)
						n2 = _sessionSerialLen(tls, a2)
						if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(a1))) == int32(0xFF) || libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TSessionTable)(unsafe.Pointer(pTab)).FabPK + uintptr(i1)))) == 0 && bIndirect != 0 {
							v2 = pOut1
							pOut1 = pOut1 + 1
							**(**Tu8)(__ccgo_up(v2)) = uint8(0xFF)
						} else {
							if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(a2))) == 0 {
								libc.Xmemcpy(tls, pOut1, a1, libc.Uint64FromInt32(n1))
								pOut1 = pOut1 + uintptr(n1)
							} else {
								libc.Xmemcpy(tls, pOut1, a2, libc.Uint64FromInt32(n2))
								pOut1 = pOut1 + uintptr(n2)
							}
						}
						a1 = a1 + uintptr(n1)
						a2 = a2 + uintptr(n2)
						goto _5
					_5:
						;
						i1 = i1 + 1
					}
					(*TSessionChange)(unsafe.Pointer(pNew)).FnRecord = int32(int64(pOut1) - int64((*TSessionChange)(unsafe.Pointer(pNew)).FaRecord))
				}
				Xsqlite3_free(tls, pExist)
			}
		} else {
			op1 = libc.Int32FromUint8((*TSessionChange)(unsafe.Pointer(pExist)).Fop)
			/*
			 **   op1=INSERT, op2=INSERT      ->      Unsupported. Discard op2.
			 **   op1=INSERT, op2=UPDATE      ->      INSERT.
			 **   op1=INSERT, op2=DELETE      ->      (none)
			 **
			 **   op1=UPDATE, op2=INSERT      ->      Unsupported. Discard op2.
			 **   op1=UPDATE, op2=UPDATE      ->      UPDATE.
			 **   op1=UPDATE, op2=DELETE      ->      DELETE.
			 **
			 **   op1=DELETE, op2=INSERT      ->      UPDATE.
			 **   op1=DELETE, op2=UPDATE      ->      Unsupported. Discard op2.
			 **   op1=DELETE, op2=DELETE      ->      Unsupported. Discard op2.
			 */
			if op1 == int32(SQLITE_INSERT) && op2 == int32(SQLITE_INSERT) || op1 == int32(SQLITE_UPDATE) && op2 == int32(SQLITE_INSERT) || op1 == int32(SQLITE_DELETE) && op2 == int32(SQLITE_UPDATE) || op1 == int32(SQLITE_DELETE) && op2 == int32(SQLITE_DELETE) {
				pNew = pExist
			} else {
				if op1 == int32(SQLITE_INSERT) && op2 == int32(SQLITE_DELETE) {
					Xsqlite3_free(tls, pExist)
				} else {
					aExist = (*TSessionChange)(unsafe.Pointer(pExist)).FaRecord
					/* Allocate a new SessionChange object. Ensure that the aRecord[]
					 ** buffer of the new object is large enough to hold any record that
					 ** may be generated by combining the input records.  */
					nByte1 = libc.Int64FromUint64(uint64(32) + libc.Uint64FromInt32((*TSessionChange)(unsafe.Pointer(pExist)).FnRecord) + libc.Uint64FromInt32(nRec))
					pNew = Xsqlite3_malloc64(tls, libc.Uint64FromInt64(nByte1))
					if !(pNew != 0) {
						Xsqlite3_free(tls, pExist)
						return int32(SQLITE_NOMEM)
					}
					libc.Xmemset(tls, pNew, 0, uint64(32))
					(*TSessionChange)(unsafe.Pointer(pNew)).FbIndirect = libc.BoolUint8(bIndirect != 0 && (*TSessionChange)(unsafe.Pointer(pExist)).FbIndirect != 0)
					v2 = pNew + 1*32
					(*TSessionChange)(unsafe.Pointer(pNew)).FaRecord = v2
					**(**uintptr)(__ccgo_up(bp)) = v2
					if op1 == int32(SQLITE_INSERT) { /* INSERT + UPDATE */
						**(**uintptr)(__ccgo_up(bp + 8)) = aRec
						(*TSessionChange)(unsafe.Pointer(pNew)).Fop = uint8(SQLITE_INSERT)
						if bPatchset == 0 {
							_sessionSkipRecord(tls, bp+8, (*TSessionTable)(unsafe.Pointer(pTab)).FnCol)
						}
						_sessionMergeRecord(tls, bp, (*TSessionTable)(unsafe.Pointer(pTab)).FnCol, aExist, **(**uintptr)(__ccgo_up(bp + 8)))
					} else {
						if op1 == int32(SQLITE_DELETE) { /* DELETE + INSERT */
							(*TSessionChange)(unsafe.Pointer(pNew)).Fop = uint8(SQLITE_UPDATE)
							if bPatchset != 0 {
								libc.Xmemcpy(tls, **(**uintptr)(__ccgo_up(bp)), aRec, libc.Uint64FromInt32(nRec))
								**(**uintptr)(__ccgo_up(bp)) = **(**uintptr)(__ccgo_up(bp)) + uintptr(nRec)
							} else {
								if 0 == _sessionMergeUpdate(tls, bp, pTab, bPatchset, aExist, uintptr(0), aRec, uintptr(0)) {
									Xsqlite3_free(tls, pNew)
									pNew = uintptr(0)
								}
							}
						} else {
							if op2 == int32(SQLITE_UPDATE) { /* UPDATE + UPDATE */
								**(**uintptr)(__ccgo_up(bp + 16)) = aExist
								**(**uintptr)(__ccgo_up(bp + 24)) = aRec
								if bPatchset == 0 {
									_sessionSkipRecord(tls, bp+16, (*TSessionTable)(unsafe.Pointer(pTab)).FnCol)
									_sessionSkipRecord(tls, bp+24, (*TSessionTable)(unsafe.Pointer(pTab)).FnCol)
								}
								(*TSessionChange)(unsafe.Pointer(pNew)).Fop = uint8(SQLITE_UPDATE)
								if 0 == _sessionMergeUpdate(tls, bp, pTab, bPatchset, aRec, aExist, **(**uintptr)(__ccgo_up(bp + 16)), **(**uintptr)(__ccgo_up(bp + 24))) {
									Xsqlite3_free(tls, pNew)
									pNew = uintptr(0)
								}
							} else { /* UPDATE + DELETE */
								(*TSessionChange)(unsafe.Pointer(pNew)).Fop = uint8(SQLITE_DELETE)
								if bPatchset != 0 {
									libc.Xmemcpy(tls, **(**uintptr)(__ccgo_up(bp)), aRec, libc.Uint64FromInt32(nRec))
									**(**uintptr)(__ccgo_up(bp)) = **(**uintptr)(__ccgo_up(bp)) + uintptr(nRec)
								} else {
									_sessionMergeRecord(tls, bp, (*TSessionTable)(unsafe.Pointer(pTab)).FnCol, aRec, aExist)
								}
							}
						}
					}
					if pNew != 0 {
						(*TSessionChange)(unsafe.Pointer(pNew)).FnRecord = int32(int64(**(**uintptr)(__ccgo_up(bp))) - int64((*TSessionChange)(unsafe.Pointer(pNew)).FaRecord))
					}
					Xsqlite3_free(tls, pExist)
				}
			}
		}
	}
	**(**uintptr)(__ccgo_up(ppNew)) = pNew
	return rc
}

// C documentation
//
//	/*
//	** Locate or create a SessionTable object that may be used to add the
//	** change currently pointed to by iterator pIter to changegroup pGrp.
//	** If successful, set output variable (*ppTab) to point to the table
//	** object and return SQLITE_OK. Otherwise, if some error occurs, return
//	** an SQLite error code and leave (*ppTab) set to NULL.
//	*/
func _sessionChangesetFindTable(tls *libc.TLS, pGrp uintptr, zTab uintptr, pIter uintptr, ppTab uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var nTab, rc int32
	var pTab, ppNew uintptr
	var _ /* abPK at bp+0 */ uintptr
	var _ /* nCol at bp+8 */ int32
	_, _, _, _ = nTab, pTab, ppNew, rc
	rc = SQLITE_OK
	pTab = uintptr(0)
	nTab = libc.Int32FromUint64(libc.Xstrlen(tls, zTab))
	**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
	**(**int32)(__ccgo_up(bp + 8)) = 0
	**(**uintptr)(__ccgo_up(ppTab)) = uintptr(0)
	/* Search the list for an existing table */
	pTab = (*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).FpList
	for {
		if !(pTab != 0) {
			break
		}
		if 0 == Xsqlite3_strnicmp(tls, (*TSessionTable)(unsafe.Pointer(pTab)).FzName, zTab, nTab+int32(1)) {
			break
		}
		goto _1
	_1:
		;
		pTab = (*TSessionTable)(unsafe.Pointer(pTab)).FpNext
	}
	if pIter != 0 {
		Xsqlite3changeset_pk(tls, pIter, bp, bp+8)
	} else {
		if !(pTab != 0) && !((*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fdb != 0) {
			return SQLITE_OK
		}
	}
	/* If one was not found above, create a new table now */
	if !(pTab != 0) {
		pTab = Xsqlite3_malloc64(tls, uint64(uint64(88)+libc.Uint64FromInt32(**(**int32)(__ccgo_up(bp + 8)))+libc.Uint64FromInt32(nTab)+uint64(1)))
		if !(pTab != 0) {
			return int32(SQLITE_NOMEM)
		}
		libc.Xmemset(tls, pTab, 0, uint64(88))
		(*TSessionTable)(unsafe.Pointer(pTab)).FnCol = **(**int32)(__ccgo_up(bp + 8))
		(*TSessionTable)(unsafe.Pointer(pTab)).FabPK = pTab + 1*88
		if **(**int32)(__ccgo_up(bp + 8)) > 0 {
			libc.Xmemcpy(tls, (*TSessionTable)(unsafe.Pointer(pTab)).FabPK, **(**uintptr)(__ccgo_up(bp)), libc.Uint64FromInt32(**(**int32)(__ccgo_up(bp + 8))))
		}
		(*TSessionTable)(unsafe.Pointer(pTab)).FzName = (*TSessionTable)(unsafe.Pointer(pTab)).FabPK + uintptr(**(**int32)(__ccgo_up(bp + 8)))
		libc.Xmemcpy(tls, (*TSessionTable)(unsafe.Pointer(pTab)).FzName, zTab, libc.Uint64FromInt32(nTab+int32(1)))
		if (*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fdb != 0 {
			(*TSessionTable)(unsafe.Pointer(pTab)).FnCol = 0
			rc = _sessionInitTable(tls, uintptr(0), pTab, (*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fdb, (*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).FzDb)
			if rc != 0 || (*TSessionTable)(unsafe.Pointer(pTab)).FnCol == 0 {
				Xsqlite3_free(tls, (*TSessionTable)(unsafe.Pointer(pTab)).FazCol)
				Xsqlite3_free(tls, pTab)
				return rc
			}
		}
		/* The new object must be linked on to the end of the list, not
		 ** simply added to the start of it. This is to ensure that the
		 ** tables within the output of sqlite3changegroup_output() are in
		 ** the right order.  */
		ppNew = pGrp + 8
		for {
			if !(**(**uintptr)(__ccgo_up(ppNew)) != 0) {
				break
			}
			goto _2
		_2:
			;
			ppNew = **(**uintptr)(__ccgo_up(ppNew))
		}
		**(**uintptr)(__ccgo_up(ppNew)) = pTab
	}
	/* Check that the table is compatible. */
	if pIter != 0 && !(_sessionChangesetCheckCompat(tls, pTab, **(**int32)(__ccgo_up(bp + 8)), **(**uintptr)(__ccgo_up(bp))) != 0) {
		rc = int32(SQLITE_SCHEMA)
	}
	**(**uintptr)(__ccgo_up(ppTab)) = pTab
	return rc
}

func _sessionChangesetInvert(tls *libc.TLS, pInput uintptr, __ccgo_fp_xOutput uintptr, pOut uintptr, pnInverted uintptr, ppInverted uintptr) (r int32) {
	bp := tls.Alloc(64)
	defer tls.Free(64)
	var abPK, apVal, pVal, pVal1, v7 uintptr
	var bIndirect, eType2, iCol, nVar, v1 int32
	var eType Tu8
	var _ /* nByte at bp+48 */ int32
	var _ /* nByte at bp+52 */ int32
	var _ /* nCol at bp+24 */ int32
	var _ /* rc at bp+0 */ int32
	var _ /* sOut at bp+8 */ TSessionBuffer
	var _ /* sPK at bp+32 */ TSessionBuffer
	_, _, _, _, _, _, _, _, _, _, _ = abPK, apVal, bIndirect, eType, eType2, iCol, nVar, pVal, pVal1, v1, v7
	**(**int32)(__ccgo_up(bp)) = SQLITE_OK                      /* Output buffer */
	**(**int32)(__ccgo_up(bp + 24)) = 0                         /* Number of cols in current table */
	abPK = uintptr(0)                                           /* PK array for current table */
	apVal = uintptr(0)                                          /* Space for values for UPDATE inversion */
	**(**TSessionBuffer)(__ccgo_up(bp + 32)) = TSessionBuffer{} /* PK array for current table */
	/* Initialize the output buffer */
	libc.Xmemset(tls, bp+8, 0, uint64(16))
	/* Zero the output variables in case an error occurs. */
	if ppInverted != 0 {
		**(**uintptr)(__ccgo_up(ppInverted)) = uintptr(0)
		**(**int32)(__ccgo_up(pnInverted)) = 0
	}
	for int32(1) != 0 {
		/* Test for EOF. */
		v1 = _sessionInputBuffer(tls, pInput, int32(2))
		**(**int32)(__ccgo_up(bp)) = v1
		if v1 != 0 {
			goto finished_invert
		}
		if (*TSessionInput)(unsafe.Pointer(pInput)).FiNext+int32(1) >= (*TSessionInput)(unsafe.Pointer(pInput)).FnData {
			if (*TSessionInput)(unsafe.Pointer(pInput)).FiNext != (*TSessionInput)(unsafe.Pointer(pInput)).FnData {
				**(**int32)(__ccgo_up(bp)) = _sqlite3CorruptError(tls, int32(237677))
				goto finished_invert
			}
			break
		}
		eType = **(**Tu8)(__ccgo_up((*TSessionInput)(unsafe.Pointer(pInput)).FaData + uintptr((*TSessionInput)(unsafe.Pointer(pInput)).FiNext)))
		switch libc.Int32FromUint8(eType) {
		case int32('T'):
			(*TSessionInput)(unsafe.Pointer(pInput)).FiNext = (*TSessionInput)(unsafe.Pointer(pInput)).FiNext + 1
			v1 = _sessionChangesetBufferTblhdr(tls, pInput, bp+48)
			**(**int32)(__ccgo_up(bp)) = v1
			if v1 != 0 {
				goto finished_invert
			}
			nVar = _sessionVarintGet(tls, (*TSessionInput)(unsafe.Pointer(pInput)).FaData+uintptr((*TSessionInput)(unsafe.Pointer(pInput)).FiNext), bp+24)
			(**(**TSessionBuffer)(__ccgo_up(bp + 32))).FnBuf = 0
			_sessionAppendBlob(tls, bp+32, (*TSessionInput)(unsafe.Pointer(pInput)).FaData+uintptr((*TSessionInput)(unsafe.Pointer(pInput)).FiNext+nVar), **(**int32)(__ccgo_up(bp + 24)), bp)
			_sessionAppendByte(tls, bp+8, eType, bp)
			_sessionAppendBlob(tls, bp+8, (*TSessionInput)(unsafe.Pointer(pInput)).FaData+uintptr((*TSessionInput)(unsafe.Pointer(pInput)).FiNext), **(**int32)(__ccgo_up(bp + 48)), bp)
			if **(**int32)(__ccgo_up(bp)) != 0 {
				goto finished_invert
			}
			**(**int32)(__ccgo_up(pInput + 8)) += **(**int32)(__ccgo_up(bp + 48))
			Xsqlite3_free(tls, apVal)
			apVal = uintptr(0)
			abPK = (**(**TSessionBuffer)(__ccgo_up(bp + 32))).FaBuf
		case int32(SQLITE_INSERT):
			fallthrough
		case int32(SQLITE_DELETE):
			bIndirect = libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TSessionInput)(unsafe.Pointer(pInput)).FaData + uintptr((*TSessionInput)(unsafe.Pointer(pInput)).FiNext+int32(1)))))
			if libc.Int32FromUint8(eType) == int32(SQLITE_DELETE) {
				v1 = int32(SQLITE_INSERT)
			} else {
				v1 = int32(SQLITE_DELETE)
			}
			eType2 = v1
			**(**int32)(__ccgo_up(pInput + 8)) += int32(2)
			**(**int32)(__ccgo_up(bp)) = _sessionChangesetBufferRecord(tls, pInput, **(**int32)(__ccgo_up(bp + 24)), bp+52)
			_sessionAppendByte(tls, bp+8, libc.Uint8FromInt32(eType2), bp)
			_sessionAppendByte(tls, bp+8, libc.Uint8FromInt32(bIndirect), bp)
			_sessionAppendBlob(tls, bp+8, (*TSessionInput)(unsafe.Pointer(pInput)).FaData+uintptr((*TSessionInput)(unsafe.Pointer(pInput)).FiNext), **(**int32)(__ccgo_up(bp + 52)), bp)
			**(**int32)(__ccgo_up(pInput + 8)) += **(**int32)(__ccgo_up(bp + 52))
			if **(**int32)(__ccgo_up(bp)) != 0 {
				goto finished_invert
			}
		case int32(SQLITE_UPDATE):
			if uintptr(0) == apVal {
				apVal = Xsqlite3_malloc64(tls, uint64(uint64(8)*libc.Uint64FromInt32(**(**int32)(__ccgo_up(bp + 24)))*uint64(2)))
				if uintptr(0) == apVal {
					**(**int32)(__ccgo_up(bp)) = int32(SQLITE_NOMEM)
					goto finished_invert
				}
				libc.Xmemset(tls, apVal, 0, uint64(8)*libc.Uint64FromInt32(**(**int32)(__ccgo_up(bp + 24)))*uint64(2))
			}
			/* Write the header for the new UPDATE change. Same as the original. */
			_sessionAppendByte(tls, bp+8, eType, bp)
			_sessionAppendByte(tls, bp+8, **(**Tu8)(__ccgo_up((*TSessionInput)(unsafe.Pointer(pInput)).FaData + uintptr((*TSessionInput)(unsafe.Pointer(pInput)).FiNext+int32(1)))), bp)
			/* Read the old.* and new.* records for the update change. */
			**(**int32)(__ccgo_up(pInput + 8)) += int32(2)
			**(**int32)(__ccgo_up(bp)) = _sessionReadRecord(tls, pInput, **(**int32)(__ccgo_up(bp + 24)), uintptr(0), apVal, uintptr(0))
			if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
				**(**int32)(__ccgo_up(bp)) = _sessionReadRecord(tls, pInput, **(**int32)(__ccgo_up(bp + 24)), uintptr(0), apVal+uintptr(**(**int32)(__ccgo_up(bp + 24)))*8, uintptr(0))
			}
			/* Write the new old.* record. Consists of the PK columns from the
			 ** original old.* record, and the other values from the original
			 ** new.* record. */
			iCol = 0
			for {
				if !(iCol < **(**int32)(__ccgo_up(bp + 24))) {
					break
				}
				if **(**Tu8)(__ccgo_up(abPK + uintptr(iCol))) != 0 {
					v1 = 0
				} else {
					v1 = **(**int32)(__ccgo_up(bp + 24))
				}
				pVal = **(**uintptr)(__ccgo_up(apVal + uintptr(iCol+v1)*8))
				_sessionAppendValue(tls, bp+8, pVal, bp)
				goto _4
			_4:
				;
				iCol = iCol + 1
			}
			/* Write the new new.* record. Consists of a copy of all values
			 ** from the original old.* record, except for the PK columns, which
			 ** are set to "undefined". */
			iCol = 0
			for {
				if !(iCol < **(**int32)(__ccgo_up(bp + 24))) {
					break
				}
				if **(**Tu8)(__ccgo_up(abPK + uintptr(iCol))) != 0 {
					v7 = uintptr(0)
				} else {
					v7 = **(**uintptr)(__ccgo_up(apVal + uintptr(iCol)*8))
				}
				pVal1 = v7
				_sessionAppendValue(tls, bp+8, pVal1, bp)
				goto _6
			_6:
				;
				iCol = iCol + 1
			}
			iCol = 0
			for {
				if !(iCol < **(**int32)(__ccgo_up(bp + 24))*int32(2)) {
					break
				}
				_sqlite3ValueFree(tls, **(**uintptr)(__ccgo_up(apVal + uintptr(iCol)*8)))
				goto _8
			_8:
				;
				iCol = iCol + 1
			}
			libc.Xmemset(tls, apVal, 0, uint64(8)*libc.Uint64FromInt32(**(**int32)(__ccgo_up(bp + 24)))*uint64(2))
			if **(**int32)(__ccgo_up(bp)) != SQLITE_OK {
				goto finished_invert
			}
		default:
			**(**int32)(__ccgo_up(bp)) = _sqlite3CorruptError(tls, int32(237780))
			goto finished_invert
		}
		if __ccgo_fp_xOutput != 0 && (**(**TSessionBuffer)(__ccgo_up(bp + 8))).FnBuf >= _sessions_strm_chunk_size {
			**(**int32)(__ccgo_up(bp)) = (*(*func(*libc.TLS, uintptr, uintptr, int32) int32)(unsafe.Pointer(&struct{ uintptr }{__ccgo_fp_xOutput})))(tls, pOut, (**(**TSessionBuffer)(__ccgo_up(bp + 8))).FaBuf, (**(**TSessionBuffer)(__ccgo_up(bp + 8))).FnBuf)
			(**(**TSessionBuffer)(__ccgo_up(bp + 8))).FnBuf = 0
			if **(**int32)(__ccgo_up(bp)) != SQLITE_OK {
				goto finished_invert
			}
		}
	}
	if pnInverted != 0 && ppInverted != 0 {
		**(**int32)(__ccgo_up(pnInverted)) = (**(**TSessionBuffer)(__ccgo_up(bp + 8))).FnBuf
		**(**uintptr)(__ccgo_up(ppInverted)) = (**(**TSessionBuffer)(__ccgo_up(bp + 8))).FaBuf
		(**(**TSessionBuffer)(__ccgo_up(bp + 8))).FaBuf = uintptr(0)
	} else {
		if (**(**TSessionBuffer)(__ccgo_up(bp + 8))).FnBuf > 0 && __ccgo_fp_xOutput != uintptr(0) {
			**(**int32)(__ccgo_up(bp)) = (*(*func(*libc.TLS, uintptr, uintptr, int32) int32)(unsafe.Pointer(&struct{ uintptr }{__ccgo_fp_xOutput})))(tls, pOut, (**(**TSessionBuffer)(__ccgo_up(bp + 8))).FaBuf, (**(**TSessionBuffer)(__ccgo_up(bp + 8))).FnBuf)
		}
	}
	goto finished_invert
finished_invert:
	;
	Xsqlite3_free(tls, (**(**TSessionBuffer)(__ccgo_up(bp + 8))).FaBuf)
	Xsqlite3_free(tls, apVal)
	Xsqlite3_free(tls, (**(**TSessionBuffer)(__ccgo_up(bp + 32))).FaBuf)
	return **(**int32)(__ccgo_up(bp))
}

// C documentation
//
//	/*
//	** Advance the changeset iterator to the next change. The differences between
//	** this function and sessionChangesetNext() are that
//	**
//	**   * If pbEmpty is not NULL and the change is a no-op UPDATE (an UPDATE
//	**     that modifies no columns), this function sets (*pbEmpty) to 1.
//	**
//	**   * If the iterator is configured to skip no-op UPDATEs,
//	**     sessionChangesetNext() does that. This function does not.
//	*/
func _sessionChangesetNextOne(tls *libc.TLS, p uintptr, paRec uintptr, pnRec uintptr, pbNew uintptr, pbEmpty uintptr) (r int32) {
	var abPK, apNew, apOld, v10, v3, v6 uintptr
	var i, nVal, v2 int32
	var op Tu8
	_, _, _, _, _, _, _, _, _, _ = abPK, apNew, apOld, i, nVal, op, v10, v2, v3, v6
	/* If the iterator is in the error-state, return immediately. */
	if (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Frc != SQLITE_OK {
		return (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Frc
	}
	/* Free the current contents of p->apValue[], if any. */
	if (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FapValue != 0 {
		i = 0
		for {
			if !(i < (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FnCol*int32(2)) {
				break
			}
			_sqlite3ValueFree(tls, **(**uintptr)(__ccgo_up((*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FapValue + uintptr(i)*8)))
			goto _1
		_1:
			;
			i = i + 1
		}
		libc.Xmemset(tls, (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FapValue, 0, uint64(8)*libc.Uint64FromInt32((*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FnCol)*uint64(2))
	}
	/* Make sure the buffer contains at least 2 bytes of input data, or all
	 ** remaining data if there are less than 2 bytes available. This is
	 ** sufficient either for the 'T' or 'P' byte that begins a new table,
	 ** or for the "op" and "bIndirect" single bytes otherwise. */
	(*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Frc = _sessionInputBuffer(tls, p, int32(2))
	if (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Frc != SQLITE_OK {
		return (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Frc
	}
	(*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Fin.FiCurrent = (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Fin.FiNext
	_sessionDiscardData(tls, p)
	/* If the iterator is already at the end of the changeset, return DONE. */
	if (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Fin.FiNext >= (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Fin.FnData {
		return int32(SQLITE_DONE)
	}
	v3 = p + 8
	v2 = *(*int32)(unsafe.Pointer(v3))
	*(*int32)(unsafe.Pointer(v3)) = *(*int32)(unsafe.Pointer(v3)) + 1
	op = **(**Tu8)(__ccgo_up((*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Fin.FaData + uintptr(v2)))
	for libc.Int32FromUint8(op) == int32('T') || libc.Int32FromUint8(op) == int32('P') {
		if pbNew != 0 {
			**(**int32)(__ccgo_up(pbNew)) = int32(1)
		}
		(*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FbPatchset = libc.BoolInt32(libc.Int32FromUint8(op) == int32('P'))
		if _sessionChangesetReadTblhdr(tls, p) != 0 {
			return (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Frc
		}
		v2 = _sessionInputBuffer(tls, p, int32(2))
		(*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Frc = v2
		if v2 != 0 {
			return (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Frc
		}
		(*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Fin.FiCurrent = (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Fin.FiNext
		if (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Fin.FiNext >= (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Fin.FnData {
			return int32(SQLITE_DONE)
		}
		v3 = p + 8
		v2 = *(*int32)(unsafe.Pointer(v3))
		*(*int32)(unsafe.Pointer(v3)) = *(*int32)(unsafe.Pointer(v3)) + 1
		op = **(**Tu8)(__ccgo_up((*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Fin.FaData + uintptr(v2)))
	}
	if (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FzTab == uintptr(0) || (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FbPatchset != 0 && (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FbInvert != 0 {
		/* The first record in the changeset is not a table header. Must be a
		 ** corrupt changeset. */
		v2 = _sqlite3CorruptError(tls, int32(237357))
		(*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Frc = v2
		return v2
	}
	if libc.Int32FromUint8(op) != int32(SQLITE_UPDATE) && libc.Int32FromUint8(op) != int32(SQLITE_DELETE) && libc.Int32FromUint8(op) != int32(SQLITE_INSERT) || (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Fin.FiNext >= (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Fin.FnData {
		v2 = _sqlite3CorruptError(tls, int32(237363))
		(*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Frc = v2
		return v2
	}
	(*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Fop = libc.Int32FromUint8(op)
	v3 = p + 8
	v2 = *(*int32)(unsafe.Pointer(v3))
	*(*int32)(unsafe.Pointer(v3)) = *(*int32)(unsafe.Pointer(v3)) + 1
	(*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FbIndirect = libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Fin.FaData + uintptr(v2))))
	if paRec != 0 { /* Number of values to buffer */
		if (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FbPatchset == 0 && libc.Int32FromUint8(op) == int32(SQLITE_UPDATE) {
			nVal = (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FnCol * int32(2)
		} else {
			if (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FbPatchset != 0 && libc.Int32FromUint8(op) == int32(SQLITE_DELETE) {
				nVal = 0
				i = 0
				for {
					if !(i < (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FnCol) {
						break
					}
					if **(**Tu8)(__ccgo_up((*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FabPK + uintptr(i))) != 0 {
						nVal = nVal + 1
					}
					goto _11
				_11:
					;
					i = i + 1
				}
			} else {
				nVal = (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FnCol
			}
		}
		(*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Frc = _sessionChangesetBufferRecord(tls, p, nVal, pnRec)
		if (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Frc != SQLITE_OK {
			return (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Frc
		}
		**(**uintptr)(__ccgo_up(paRec)) = (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Fin.FaData + uintptr((*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Fin.FiNext)
		(*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Fin.FiNext += **(**int32)(__ccgo_up(pnRec))
	} else {
		if (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FbInvert != 0 {
			v3 = (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FapValue + uintptr((*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FnCol)*8
		} else {
			v3 = (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FapValue
		}
		apOld = v3
		if (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FbInvert != 0 {
			v6 = (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FapValue
		} else {
			v6 = (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FapValue + uintptr((*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FnCol)*8
		}
		apNew = v6
		/* If this is an UPDATE or DELETE, read the old.* record. */
		if (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Fop != int32(SQLITE_INSERT) && ((*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FbPatchset == 0 || (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Fop == int32(SQLITE_DELETE)) {
			if (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FbPatchset != 0 {
				v10 = (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FabPK
			} else {
				v10 = uintptr(0)
			}
			abPK = v10
			(*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Frc = _sessionReadRecord(tls, p, (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FnCol, abPK, apOld, uintptr(0))
			if (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Frc != SQLITE_OK {
				return (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Frc
			}
		}
		/* If this is an INSERT or UPDATE, read the new.* record. */
		if (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Fop != int32(SQLITE_DELETE) {
			(*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Frc = _sessionReadRecord(tls, p, (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FnCol, uintptr(0), apNew, pbEmpty)
			if (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Frc != SQLITE_OK {
				return (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Frc
			}
		}
		if ((*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FbPatchset != 0 || (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FbInvert != 0) && (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Fop == int32(SQLITE_UPDATE) {
			/* If this is an UPDATE that is part of a patchset, then all PK and
			 ** modified fields are present in the new.* record. The old.* record
			 ** is currently completely empty. This block shifts the PK fields from
			 ** new.* to old.*, to accommodate the code that reads these arrays.  */
			i = 0
			for {
				if !(i < (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FnCol) {
					break
				}
				if **(**Tu8)(__ccgo_up((*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FabPK + uintptr(i))) != 0 {
					**(**uintptr)(__ccgo_up((*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FapValue + uintptr(i)*8)) = **(**uintptr)(__ccgo_up((*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FapValue + uintptr(i+(*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FnCol)*8))
					if **(**uintptr)(__ccgo_up((*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FapValue + uintptr(i)*8)) == uintptr(0) {
						v2 = _sqlite3CorruptError(tls, int32(237409))
						(*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Frc = v2
						return v2
					}
					**(**uintptr)(__ccgo_up((*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FapValue + uintptr(i+(*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FnCol)*8)) = uintptr(0)
				}
				goto _15
			_15:
				;
				i = i + 1
			}
		} else {
			if (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FbInvert != 0 {
				if (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Fop == int32(SQLITE_INSERT) {
					(*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Fop = int32(SQLITE_DELETE)
				} else {
					if (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Fop == int32(SQLITE_DELETE) {
						(*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Fop = int32(SQLITE_INSERT)
					}
				}
			}
		}
		/* If this is an UPDATE that is part of a changeset, then check that
		 ** there are no fields in the old.* record that are not (a) PK fields,
		 ** or (b) also present in the new.* record.
		 **
		 ** Such records are technically corrupt, but the rebaser was at one
		 ** point generating them. Under most circumstances this is benign, but
		 ** can cause spurious SQLITE_RANGE errors when applying the changeset. */
		if (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FbPatchset == 0 && (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Fop == int32(SQLITE_UPDATE) {
			i = 0
			for {
				if !(i < (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FnCol) {
					break
				}
				if libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FabPK + uintptr(i)))) == 0 && **(**uintptr)(__ccgo_up((*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FapValue + uintptr(i+(*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FnCol)*8)) == uintptr(0) {
					_sqlite3ValueFree(tls, **(**uintptr)(__ccgo_up((*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FapValue + uintptr(i)*8)))
					**(**uintptr)(__ccgo_up((*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FapValue + uintptr(i)*8)) = uintptr(0)
				}
				goto _17
			_17:
				;
				i = i + 1
			}
		}
	}
	return int32(SQLITE_ROW)
}

// C documentation
//
//	/*
//	** The input pointer currently points to the second byte of a table-header.
//	** Specifically, to the following:
//	**
//	**   + number of columns in table (varint)
//	**   + array of PK flags (1 byte per column),
//	**   + table name (nul terminated).
//	**
//	** This function decodes the table-header and populates the p->nCol,
//	** p->zTab and p->abPK[] variables accordingly. The p->apValue[] array is
//	** also allocated or resized according to the new value of p->nCol. The
//	** input pointer is left pointing to the byte following the table header.
//	**
//	** If successful, SQLITE_OK is returned. Otherwise, an SQLite error code
//	** is returned and the final values of the various fields enumerated above
//	** are undefined.
//	*/
func _sessionChangesetReadTblhdr(tls *libc.TLS, p uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var iPK Tsize_t
	var nByte, nVarint, v2 int32
	var v1 uintptr
	var _ /* nCopy at bp+4 */ int32
	var _ /* rc at bp+0 */ int32
	_, _, _, _, _ = iPK, nByte, nVarint, v1, v2
	**(**int32)(__ccgo_up(bp)) = _sessionChangesetBufferTblhdr(tls, p, bp+4)
	if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
		nVarint = _sessionVarintGet(tls, (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Fin.FaData+uintptr((*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Fin.FiNext), p+120)
		if (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FnCol > 0 {
			**(**int32)(__ccgo_up(bp + 4)) = **(**int32)(__ccgo_up(bp + 4)) - nVarint
			(*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Fin.FiNext += nVarint
			nByte = libc.Int32FromUint64(libc.Uint64FromInt32((*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FnCol)*uint64(8)*uint64(2) + libc.Uint64FromInt32(**(**int32)(__ccgo_up(bp + 4))))
			(*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Ftblhdr.FnBuf = 0
			_sessionBufferGrow(tls, p+72, int64(nByte), bp)
		} else {
			**(**int32)(__ccgo_up(bp)) = _sqlite3CorruptError(tls, int32(237271))
		}
	}
	if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
		iPK = uint64(8) * libc.Uint64FromInt32((*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FnCol) * uint64(2)
		libc.Xmemset(tls, (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Ftblhdr.FaBuf, 0, iPK)
		libc.Xmemcpy(tls, (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Ftblhdr.FaBuf+uintptr(iPK), (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Fin.FaData+uintptr((*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Fin.FiNext), libc.Uint64FromInt32(**(**int32)(__ccgo_up(bp + 4))))
		(*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Fin.FiNext += **(**int32)(__ccgo_up(bp + 4))
	}
	(*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FapValue = (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Ftblhdr.FaBuf
	if (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FapValue == uintptr(0) {
		(*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FabPK = uintptr(0)
		(*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FzTab = uintptr(0)
	} else {
		(*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FabPK = (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FapValue + uintptr((*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FnCol*int32(2))*8
		if (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FabPK != 0 {
			v1 = (*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FabPK + uintptr((*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FnCol)
		} else {
			v1 = uintptr(0)
		}
		(*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).FzTab = v1
	}
	v2 = **(**int32)(__ccgo_up(bp))
	(*Tsqlite3_changeset_iter)(unsafe.Pointer(p)).Frc = v2
	return v2
}

// C documentation
//
//	/*
//	** If the SessionInput object passed as the only argument is a streaming
//	** object and the buffer is full, discard some data to free up space.
//	*/
func _sessionDiscardData(tls *libc.TLS, pIn uintptr) {
	var nMove int32
	_ = nMove
	if (*TSessionInput)(unsafe.Pointer(pIn)).FxInput != 0 && (*TSessionInput)(unsafe.Pointer(pIn)).FiCurrent >= _sessions_strm_chunk_size {
		nMove = (*TSessionInput)(unsafe.Pointer(pIn)).Fbuf.FnBuf - (*TSessionInput)(unsafe.Pointer(pIn)).FiCurrent
		if nMove > 0 {
			libc.Xmemmove(tls, (*TSessionInput)(unsafe.Pointer(pIn)).Fbuf.FaBuf, (*TSessionInput)(unsafe.Pointer(pIn)).Fbuf.FaBuf+uintptr((*TSessionInput)(unsafe.Pointer(pIn)).FiCurrent), libc.Uint64FromInt32(nMove))
		}
		(*TSessionInput)(unsafe.Pointer(pIn)).Fbuf.FnBuf -= (*TSessionInput)(unsafe.Pointer(pIn)).FiCurrent
		**(**int32)(__ccgo_up(pIn + 8)) -= (*TSessionInput)(unsafe.Pointer(pIn)).FiCurrent
		(*TSessionInput)(unsafe.Pointer(pIn)).FiCurrent = 0
		(*TSessionInput)(unsafe.Pointer(pIn)).FnData = (*TSessionInput)(unsafe.Pointer(pIn)).Fbuf.FnBuf
	}
}

// C documentation
//
//	/*
//	** If required, grow the hash table used to store changes on table pTab
//	** (part of the session pSession). If a fatal OOM error occurs, set the
//	** session object to failed and return SQLITE_ERROR. Otherwise, return
//	** SQLITE_OK.
//	**
//	** It is possible that a non-fatal OOM error occurs in this function. In
//	** that case the hash-table does not grow, but SQLITE_OK is returned anyway.
//	** Growing the hash table in this case is a performance optimization only,
//	** it is not required for correct operation.
//	*/
func _sessionGrowHash(tls *libc.TLS, pSession uintptr, bPatchset int32, pTab uintptr) (r int32) {
	var apNew, p, pNext uintptr
	var bPkOnly, i, iHash, v1 int32
	var nNew Tsqlite3_int64
	_, _, _, _, _, _, _, _ = apNew, bPkOnly, i, iHash, nNew, p, pNext, v1
	if (*TSessionTable)(unsafe.Pointer(pTab)).FnChange == 0 || (*TSessionTable)(unsafe.Pointer(pTab)).FnEntry >= (*TSessionTable)(unsafe.Pointer(pTab)).FnChange/int32(2) {
		if (*TSessionTable)(unsafe.Pointer(pTab)).FnChange != 0 {
			v1 = (*TSessionTable)(unsafe.Pointer(pTab)).FnChange
		} else {
			v1 = int32(128)
		}
		nNew = int64(2) * int64(v1)
		apNew = _sessionMalloc64(tls, pSession, libc.Int64FromUint64(uint64(8)*libc.Uint64FromInt64(nNew)))
		if apNew == uintptr(0) {
			if (*TSessionTable)(unsafe.Pointer(pTab)).FnChange == 0 {
				return int32(SQLITE_ERROR)
			}
			return SQLITE_OK
		}
		libc.Xmemset(tls, apNew, 0, uint64(uint64(8)*libc.Uint64FromInt64(nNew)))
		i = 0
		for {
			if !(i < (*TSessionTable)(unsafe.Pointer(pTab)).FnChange) {
				break
			}
			p = **(**uintptr)(__ccgo_up((*TSessionTable)(unsafe.Pointer(pTab)).FapChange + uintptr(i)*8))
			for {
				if !(p != 0) {
					break
				}
				bPkOnly = libc.BoolInt32(libc.Int32FromUint8((*TSessionChange)(unsafe.Pointer(p)).Fop) == int32(SQLITE_DELETE) && bPatchset != 0)
				iHash = libc.Int32FromUint32(_sessionChangeHash(tls, pTab, bPkOnly, (*TSessionChange)(unsafe.Pointer(p)).FaRecord, int32(nNew)))
				pNext = (*TSessionChange)(unsafe.Pointer(p)).FpNext
				(*TSessionChange)(unsafe.Pointer(p)).FpNext = **(**uintptr)(__ccgo_up(apNew + uintptr(iHash)*8))
				**(**uintptr)(__ccgo_up(apNew + uintptr(iHash)*8)) = p
				goto _3
			_3:
				;
				p = pNext
			}
			goto _2
		_2:
			;
			i = i + 1
		}
		_sessionFree(tls, pSession, (*TSessionTable)(unsafe.Pointer(pTab)).FapChange)
		(*TSessionTable)(unsafe.Pointer(pTab)).FnChange = int32(nNew)
		(*TSessionTable)(unsafe.Pointer(pTab)).FapChange = apNew
	}
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** Arguments aLeft and aRight both point to buffers containing change
//	** records with nCol columns. This function "merges" the two records into
//	** a single records which is written to the buffer at *paOut. *paOut is
//	** then set to point to one byte after the last byte written before
//	** returning.
//	**
//	** The merging of records is done as follows: For each column, if the
//	** aRight record contains a value for the column, copy the value from
//	** their. Otherwise, if aLeft contains a value, copy it. If neither
//	** record contains a value for a given column, then neither does the
//	** output record.
//	*/
func _sessionMergeRecord(tls *libc.TLS, paOut uintptr, nCol int32, aLeft uintptr, aRight uintptr) {
	var a1, a2, aOut uintptr
	var iCol, n1, n2 int32
	_, _, _, _, _, _ = a1, a2, aOut, iCol, n1, n2
	a1 = aLeft                             /* Cursor used to iterate through aLeft */
	a2 = aRight                            /* Cursor used to iterate through aRight */
	aOut = **(**uintptr)(__ccgo_up(paOut)) /* Used to iterate from 0 to nCol */
	iCol = 0
	for {
		if !(iCol < nCol) {
			break
		}
		n1 = _sessionSerialLen(tls, a1)
		n2 = _sessionSerialLen(tls, a2)
		if **(**Tu8)(__ccgo_up(a2)) != 0 {
			libc.Xmemcpy(tls, aOut, a2, libc.Uint64FromInt32(n2))
			aOut = aOut + uintptr(n2)
		} else {
			libc.Xmemcpy(tls, aOut, a1, libc.Uint64FromInt32(n1))
			aOut = aOut + uintptr(n1)
		}
		a1 = a1 + uintptr(n1)
		a2 = a2 + uintptr(n2)
		goto _1
	_1:
		;
		iCol = iCol + 1
	}
	**(**uintptr)(__ccgo_up(paOut)) = aOut
}

// C documentation
//
//	/*
//	** This function is used by changeset_concat() to merge two UPDATE changes
//	** on the same row.
//	*/
func _sessionMergeUpdate(tls *libc.TLS, paOut uintptr, pTab uintptr, bPatchset int32, aOldRecord1 uintptr, aOldRecord2 uintptr, aNewRecord1 uintptr, aNewRecord2 uintptr) (r int32) {
	bp := tls.Alloc(48)
	defer tls.Free(48)
	var aNew, aNew1, aOld, aOld1, aOut, v2 uintptr
	var bRequired, i int32
	var _ /* aNew1 at bp+16 */ uintptr
	var _ /* aNew2 at bp+24 */ uintptr
	var _ /* aOld1 at bp+0 */ uintptr
	var _ /* aOld2 at bp+8 */ uintptr
	var _ /* nNew at bp+36 */ int32
	var _ /* nNew at bp+44 */ int32
	var _ /* nOld at bp+32 */ int32
	var _ /* nOld at bp+40 */ int32
	_, _, _, _, _, _, _, _ = aNew, aNew1, aOld, aOld1, aOut, bRequired, i, v2
	**(**uintptr)(__ccgo_up(bp)) = aOldRecord1
	**(**uintptr)(__ccgo_up(bp + 8)) = aOldRecord2
	**(**uintptr)(__ccgo_up(bp + 16)) = aNewRecord1
	**(**uintptr)(__ccgo_up(bp + 24)) = aNewRecord2
	aOut = **(**uintptr)(__ccgo_up(paOut))
	if bPatchset == 0 {
		bRequired = 0
		/* Write the old.* vector first. */
		i = 0
		for {
			if !(i < (*TSessionTable)(unsafe.Pointer(pTab)).FnCol) {
				break
			}
			aOld = _sessionMergeValue(tls, bp, bp+8, bp+32)
			aNew = _sessionMergeValue(tls, bp+16, bp+24, bp+36)
			if **(**Tu8)(__ccgo_up((*TSessionTable)(unsafe.Pointer(pTab)).FabPK + uintptr(i))) != 0 || **(**int32)(__ccgo_up(bp + 32)) != **(**int32)(__ccgo_up(bp + 36)) || libc.Xmemcmp(tls, aOld, aNew, libc.Uint64FromInt32(**(**int32)(__ccgo_up(bp + 36)))) != 0 {
				if libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TSessionTable)(unsafe.Pointer(pTab)).FabPK + uintptr(i)))) == 0 {
					bRequired = int32(1)
				}
				libc.Xmemcpy(tls, aOut, aOld, libc.Uint64FromInt32(**(**int32)(__ccgo_up(bp + 32))))
				aOut = aOut + uintptr(**(**int32)(__ccgo_up(bp + 32)))
			} else {
				v2 = aOut
				aOut = aOut + 1
				**(**Tu8)(__ccgo_up(v2)) = uint8('\000')
			}
			goto _1
		_1:
			;
			i = i + 1
		}
		if !(bRequired != 0) {
			return 0
		}
	}
	/* Write the new.* vector */
	**(**uintptr)(__ccgo_up(bp)) = aOldRecord1
	**(**uintptr)(__ccgo_up(bp + 8)) = aOldRecord2
	**(**uintptr)(__ccgo_up(bp + 16)) = aNewRecord1
	**(**uintptr)(__ccgo_up(bp + 24)) = aNewRecord2
	i = 0
	for {
		if !(i < (*TSessionTable)(unsafe.Pointer(pTab)).FnCol) {
			break
		}
		aOld1 = _sessionMergeValue(tls, bp, bp+8, bp+40)
		aNew1 = _sessionMergeValue(tls, bp+16, bp+24, bp+44)
		if bPatchset == 0 && (**(**Tu8)(__ccgo_up((*TSessionTable)(unsafe.Pointer(pTab)).FabPK + uintptr(i))) != 0 || **(**int32)(__ccgo_up(bp + 40)) == **(**int32)(__ccgo_up(bp + 44)) && 0 == libc.Xmemcmp(tls, aOld1, aNew1, libc.Uint64FromInt32(**(**int32)(__ccgo_up(bp + 44))))) {
			v2 = aOut
			aOut = aOut + 1
			**(**Tu8)(__ccgo_up(v2)) = uint8('\000')
		} else {
			libc.Xmemcpy(tls, aOut, aNew1, libc.Uint64FromInt32(**(**int32)(__ccgo_up(bp + 44))))
			aOut = aOut + uintptr(**(**int32)(__ccgo_up(bp + 44)))
		}
		goto _3
	_3:
		;
		i = i + 1
	}
	**(**uintptr)(__ccgo_up(paOut)) = aOut
	return int32(1)
}

// C documentation
//
//	/*
//	** This function is only called from within a pre-update-hook callback.
//	** It determines if the current pre-update-hook change affects the same row
//	** as the change stored in argument pChange. If so, it returns true. Otherwise
//	** if the pre-update-hook does not affect the same row as pChange, it returns
//	** false.
//	*/
func _sessionPreupdateEqual(tls *libc.TLS, pSession uintptr, iRowid Ti64, pTab uintptr, pChange uintptr, op int32) (r int32) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var a, z, v2 uintptr
	var eType, iCol, iIdx, rc int32
	var _ /* iVal at bp+8 */ Ti64
	var _ /* n at bp+24 */ int32
	var _ /* pVal at bp+0 */ uintptr
	var _ /* rVal at bp+16 */ float64
	_, _, _, _, _, _, _ = a, eType, iCol, iIdx, rc, z, v2   /* Used to iterate through columns */
	a = (*TSessionChange)(unsafe.Pointer(pChange)).FaRecord /* Cursor used to scan change record */
	if (*TSessionTable)(unsafe.Pointer(pTab)).FbRowid != 0 {
		if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(a))) != int32(SQLITE_INTEGER) {
			return 0
		}
		return libc.BoolInt32(_sessionGetI64(tls, a+1) == iRowid)
	}
	iCol = 0
	for {
		if !(iCol < (*TSessionTable)(unsafe.Pointer(pTab)).FnCol) {
			break
		}
		if !(**(**Tu8)(__ccgo_up((*TSessionTable)(unsafe.Pointer(pTab)).FabPK + uintptr(iCol))) != 0) {
			a = a + uintptr(_sessionSerialLen(tls, a))
		} else {
			v2 = a
			a = a + 1                                             /* Error code from preupdate_new/old */
			eType = libc.Int32FromUint8(**(**Tu8)(__ccgo_up(v2))) /* Type of value from change record */
			iIdx = **(**int32)(__ccgo_up((*TSessionTable)(unsafe.Pointer(pTab)).FaiIdx + uintptr(iCol)*4))
			/* The following calls to preupdate_new() and preupdate_old() can not
			 ** fail. This is because they cache their return values, and by the
			 ** time control flows to here they have already been called once from
			 ** within sessionPreupdateHash(). The first two asserts below verify
			 ** this (that the method has already been called). */
			if op == int32(SQLITE_INSERT) {
				/* assert( db->pPreUpdate->pNewUnpacked || db->pPreUpdate->aNew ); */
				rc = (*(*func(*libc.TLS, uintptr, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*Tsqlite3_session)(unsafe.Pointer(pSession)).Fhook.FxNew})))(tls, (*Tsqlite3_session)(unsafe.Pointer(pSession)).Fhook.FpCtx, iIdx, bp)
			} else {
				/* assert( db->pPreUpdate->pUnpacked ); */
				rc = (*(*func(*libc.TLS, uintptr, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*Tsqlite3_session)(unsafe.Pointer(pSession)).Fhook.FxOld})))(tls, (*Tsqlite3_session)(unsafe.Pointer(pSession)).Fhook.FpCtx, iIdx, bp)
			}
			_ = rc /* Suppress warning about unused variable */
			if Xsqlite3_value_type(tls, **(**uintptr)(__ccgo_up(bp))) != eType {
				return 0
			}
			/* A SessionChange object never has a NULL value in a PK column */
			if eType == int32(SQLITE_INTEGER) || eType == int32(SQLITE_FLOAT) {
				**(**Ti64)(__ccgo_up(bp + 8)) = _sessionGetI64(tls, a)
				a = a + uintptr(8)
				if eType == int32(SQLITE_INTEGER) {
					if Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(bp))) != **(**Ti64)(__ccgo_up(bp + 8)) {
						return 0
					}
				} else {
					libc.Xmemcpy(tls, bp+16, bp+8, uint64(8))
					if Xsqlite3_value_double(tls, **(**uintptr)(__ccgo_up(bp))) != **(**float64)(__ccgo_up(bp + 16)) {
						return 0
					}
				}
			} else {
				a = a + uintptr(_sessionVarintGet(tls, a, bp+24))
				if Xsqlite3_value_bytes(tls, **(**uintptr)(__ccgo_up(bp))) != **(**int32)(__ccgo_up(bp + 24)) {
					return 0
				}
				if eType == int32(SQLITE_TEXT) {
					z = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(bp)))
				} else {
					z = Xsqlite3_value_blob(tls, **(**uintptr)(__ccgo_up(bp)))
				}
				if **(**int32)(__ccgo_up(bp + 24)) > 0 && libc.Xmemcmp(tls, a, z, libc.Uint64FromInt32(**(**int32)(__ccgo_up(bp + 24)))) != 0 {
					return 0
				}
				a = a + uintptr(**(**int32)(__ccgo_up(bp + 24)))
			}
		}
		goto _1
	_1:
		;
		iCol = iCol + 1
	}
	return int32(1)
}

// C documentation
//
//	/*
//	** This function may only be called from within a pre-update callback.
//	** It calculates a hash based on the primary key values of the old.* or
//	** new.* row currently available and, assuming no error occurs, writes it to
//	** *piHash before returning. If the primary key contains one or more NULL
//	** values, *pbNullPK is set to true before returning.
//	**
//	** If an error occurs, an SQLite error code is returned and the final values
//	** of *piHash asn *pbNullPK are undefined. Otherwise, SQLITE_OK is returned
//	** and the output variables are set as described above.
//	*/
func _sessionPreupdateHash(tls *libc.TLS, pSession uintptr, iRowid Ti64, pTab uintptr, bNew int32, piHash uintptr, pbNullPK uintptr) (r int32) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var eType, i, iIdx, n, rc int32
	var h uint32
	var z uintptr
	var _ /* iVal at bp+8 */ Ti64
	var _ /* pVal at bp+0 */ uintptr
	var _ /* rVal at bp+16 */ float64
	_, _, _, _, _, _, _ = eType, h, i, iIdx, n, rc, z
	h = uint32(0) /* Used to iterate through columns */
	if (*TSessionTable)(unsafe.Pointer(pTab)).FbRowid != 0 {
		h = _sessionHashAppendI64(tls, h, iRowid)
	} else {
		i = 0
		for {
			if !(i < (*TSessionTable)(unsafe.Pointer(pTab)).FnCol) {
				break
			}
			if **(**Tu8)(__ccgo_up((*TSessionTable)(unsafe.Pointer(pTab)).FabPK + uintptr(i))) != 0 {
				iIdx = **(**int32)(__ccgo_up((*TSessionTable)(unsafe.Pointer(pTab)).FaiIdx + uintptr(i)*4))
				if bNew != 0 {
					rc = (*(*func(*libc.TLS, uintptr, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*Tsqlite3_session)(unsafe.Pointer(pSession)).Fhook.FxNew})))(tls, (*Tsqlite3_session)(unsafe.Pointer(pSession)).Fhook.FpCtx, iIdx, bp)
				} else {
					rc = (*(*func(*libc.TLS, uintptr, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*Tsqlite3_session)(unsafe.Pointer(pSession)).Fhook.FxOld})))(tls, (*Tsqlite3_session)(unsafe.Pointer(pSession)).Fhook.FpCtx, iIdx, bp)
				}
				if rc != SQLITE_OK {
					return rc
				}
				eType = Xsqlite3_value_type(tls, **(**uintptr)(__ccgo_up(bp)))
				h = _sessionHashAppendType(tls, h, eType)
				if eType == int32(SQLITE_INTEGER) || eType == int32(SQLITE_FLOAT) {
					if eType == int32(SQLITE_INTEGER) {
						**(**Ti64)(__ccgo_up(bp + 8)) = Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(bp)))
					} else {
						**(**float64)(__ccgo_up(bp + 16)) = Xsqlite3_value_double(tls, **(**uintptr)(__ccgo_up(bp)))
						libc.Xmemcpy(tls, bp+8, bp+16, uint64(8))
					}
					h = _sessionHashAppendI64(tls, h, **(**Ti64)(__ccgo_up(bp + 8)))
				} else {
					if eType == int32(SQLITE_TEXT) || eType == int32(SQLITE_BLOB) {
						if eType == int32(SQLITE_TEXT) {
							z = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(bp)))
						} else {
							z = Xsqlite3_value_blob(tls, **(**uintptr)(__ccgo_up(bp)))
						}
						n = Xsqlite3_value_bytes(tls, **(**uintptr)(__ccgo_up(bp)))
						if !(z != 0) && (eType != int32(SQLITE_BLOB) || n > 0) {
							return int32(SQLITE_NOMEM)
						}
						h = _sessionHashAppendBlob(tls, h, n, z)
					} else {
						**(**int32)(__ccgo_up(pbNullPK)) = int32(1)
					}
				}
			}
			goto _1
		_1:
			;
			i = i + 1
		}
	}
	**(**int32)(__ccgo_up(piHash)) = libc.Int32FromUint32(h % libc.Uint32FromInt32((*TSessionTable)(unsafe.Pointer(pTab)).FnChange))
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** Write a double value to the buffer aBuf[].
//	*/
func _sessionPutDouble(tls *libc.TLS, aBuf uintptr, _r float64) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	*(*float64)(unsafe.Pointer(bp)) = _r
	var _ /* i at bp+8 */ Tu64
	libc.Xmemcpy(tls, bp+8, bp, uint64(8))
	_sessionPutI64(tls, aBuf, libc.Int64FromUint64(**(**Tu64)(__ccgo_up(bp + 8))))
}

// C documentation
//
//	/*
//	** Deserialize a single record from a buffer in memory. See "RECORD FORMAT"
//	** for details.
//	**
//	** When this function is called, *paChange points to the start of the record
//	** to deserialize. Assuming no error occurs, *paChange is set to point to
//	** one byte after the end of the same record before this function returns.
//	** If the argument abPK is NULL, then the record contains nCol values. Or,
//	** if abPK is other than NULL, then the record contains only the PK fields
//	** (in other words, it is a patchset DELETE record).
//	**
//	** If successful, each element of the apOut[] array (allocated by the caller)
//	** is set to point to an sqlite3_value object containing the value read
//	** from the corresponding position in the record. If that value is not
//	** included in the record (i.e. because the record is part of an UPDATE change
//	** and the field was not modified), the corresponding element of apOut[] is
//	** set to NULL.
//	**
//	** It is the responsibility of the caller to free all sqlite_value structures
//	** using sqlite3_free().
//	**
//	** If an error occurs, an SQLite error code (e.g. SQLITE_NOMEM) is returned.
//	** The apOut[] array may have been partially populated in this case.
//	*/
func _sessionReadRecord(tls *libc.TLS, pIn uintptr, nCol int32, abPK uintptr, apOut uintptr, pbEmpty uintptr) (r int32) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var aVal, v3 uintptr
	var eType, i, nRem, rc, v2 int32
	var enc Tu8
	var _ /* d at bp+16 */ float64
	var _ /* nByte at bp+0 */ int32
	var _ /* v at bp+8 */ Tsqlite3_int64
	_, _, _, _, _, _, _, _ = aVal, eType, enc, i, nRem, rc, v2, v3 /* Used to iterate through columns */
	rc = SQLITE_OK
	if pbEmpty != 0 {
		**(**int32)(__ccgo_up(pbEmpty)) = int32(1)
	}
	i = 0
	for {
		if !(i < nCol && rc == SQLITE_OK) {
			break
		}
		eType = 0 /* Type of value (SQLITE_NULL, TEXT etc.) */
		if abPK != 0 && libc.Int32FromUint8(**(**Tu8)(__ccgo_up(abPK + uintptr(i)))) == 0 {
			goto _1
		}
		rc = _sessionInputBuffer(tls, pIn, int32(9))
		if rc == SQLITE_OK {
			if (*TSessionInput)(unsafe.Pointer(pIn)).FiNext >= (*TSessionInput)(unsafe.Pointer(pIn)).FnData {
				rc = _sqlite3CorruptError(tls, int32(237090))
			} else {
				v3 = pIn + 8
				v2 = *(*int32)(unsafe.Pointer(v3))
				*(*int32)(unsafe.Pointer(v3)) = *(*int32)(unsafe.Pointer(v3)) + 1
				eType = libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TSessionInput)(unsafe.Pointer(pIn)).FaData + uintptr(v2))))
				if eType != 0 {
					if pbEmpty != 0 {
						**(**int32)(__ccgo_up(pbEmpty)) = 0
					}
					**(**uintptr)(__ccgo_up(apOut + uintptr(i)*8)) = _sqlite3ValueNew(tls, uintptr(0))
					if !(**(**uintptr)(__ccgo_up(apOut + uintptr(i)*8)) != 0) {
						rc = int32(SQLITE_NOMEM)
					}
				}
			}
		}
		if rc == SQLITE_OK {
			aVal = (*TSessionInput)(unsafe.Pointer(pIn)).FaData + uintptr((*TSessionInput)(unsafe.Pointer(pIn)).FiNext)
			if eType == int32(SQLITE_TEXT) || eType == int32(SQLITE_BLOB) {
				nRem = (*TSessionInput)(unsafe.Pointer(pIn)).FnData - (*TSessionInput)(unsafe.Pointer(pIn)).FiNext
				**(**int32)(__ccgo_up(pIn + 8)) += _sessionVarintGetSafe(tls, aVal, nRem, bp)
				rc = _sessionInputBuffer(tls, pIn, **(**int32)(__ccgo_up(bp)))
				if rc == SQLITE_OK {
					if **(**int32)(__ccgo_up(bp)) < 0 || **(**int32)(__ccgo_up(bp)) > (*TSessionInput)(unsafe.Pointer(pIn)).FnData-(*TSessionInput)(unsafe.Pointer(pIn)).FiNext {
						rc = _sqlite3CorruptError(tls, int32(237111))
					} else {
						if eType == int32(SQLITE_TEXT) {
							v2 = int32(SQLITE_UTF8)
						} else {
							v2 = 0
						}
						enc = libc.Uint8FromInt32(v2)
						rc = _sessionValueSetStr(tls, **(**uintptr)(__ccgo_up(apOut + uintptr(i)*8)), (*TSessionInput)(unsafe.Pointer(pIn)).FaData+uintptr((*TSessionInput)(unsafe.Pointer(pIn)).FiNext), **(**int32)(__ccgo_up(bp)), enc)
						**(**int32)(__ccgo_up(pIn + 8)) += **(**int32)(__ccgo_up(bp))
					}
				}
			}
			if eType == int32(SQLITE_INTEGER) || eType == int32(SQLITE_FLOAT) {
				if (*TSessionInput)(unsafe.Pointer(pIn)).FnData-(*TSessionInput)(unsafe.Pointer(pIn)).FiNext < int32(8) {
					rc = _sqlite3CorruptError(tls, int32(237121))
				} else {
					**(**Tsqlite3_int64)(__ccgo_up(bp + 8)) = _sessionGetI64(tls, aVal)
					if eType == int32(SQLITE_INTEGER) {
						_sqlite3VdbeMemSetInt64(tls, **(**uintptr)(__ccgo_up(apOut + uintptr(i)*8)), **(**Tsqlite3_int64)(__ccgo_up(bp + 8)))
					} else {
						libc.Xmemcpy(tls, bp+16, bp+8, uint64(8))
						_sqlite3VdbeMemSetDouble(tls, **(**uintptr)(__ccgo_up(apOut + uintptr(i)*8)), **(**float64)(__ccgo_up(bp + 16)))
					}
					**(**int32)(__ccgo_up(pIn + 8)) += int32(8)
				}
			}
		}
		goto _1
	_1:
		;
		i = i + 1
	}
	return rc
}

// C documentation
//
//	/*
//	** pIter is configured to iterate through a changeset. This function rebases
//	** that changeset according to the current configuration of the rebaser
//	** object passed as the first argument. If no error occurs and argument xOutput
//	** is not NULL, then the changeset is returned to the caller by invoking
//	** xOutput zero or more times and SQLITE_OK returned. Or, if xOutput is NULL,
//	** then (*ppOut) is set to point to a buffer containing the rebased changeset
//	** before this function returns. In this case (*pnOut) is set to the size of
//	** the buffer in bytes.  It is the responsibility of the caller to eventually
//	** free the (*ppOut) buffer using sqlite3_free().
//	**
//	** If an error occurs, an SQLite error code is returned. If ppOut and
//	** pnOut are not NULL, then the two output parameters are set to 0 before
//	** returning.
//	*/
func _sessionRebase(tls *libc.TLS, p uintptr, pIter uintptr, __ccgo_fp_xOutput uintptr, pOut uintptr, pnOut uintptr, ppOut uintptr) (r int32) {
	bp := tls.Alloc(48)
	defer tls.Free(48)
	var bDone, iHash, v2 int32
	var pChange, pTab, zTab uintptr
	var _ /* aRec at bp+8 */ uintptr
	var _ /* bNew at bp+20 */ int32
	var _ /* nRec at bp+16 */ int32
	var _ /* pCsr at bp+40 */ uintptr
	var _ /* rc at bp+0 */ int32
	var _ /* sOut at bp+24 */ TSessionBuffer
	_, _, _, _, _, _ = bDone, iHash, pChange, pTab, zTab, v2
	**(**int32)(__ccgo_up(bp)) = SQLITE_OK
	**(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0)
	**(**int32)(__ccgo_up(bp + 16)) = 0
	**(**int32)(__ccgo_up(bp + 20)) = 0
	pTab = uintptr(0)
	**(**TSessionBuffer)(__ccgo_up(bp + 24)) = TSessionBuffer{}
	for int32(SQLITE_ROW) == _sessionChangesetNext(tls, pIter, bp+8, bp+16, bp+20) {
		pChange = uintptr(0)
		bDone = 0
		if **(**int32)(__ccgo_up(bp + 20)) != 0 {
			zTab = (*Tsqlite3_changeset_iter)(unsafe.Pointer(pIter)).FzTab
			pTab = (*Tsqlite3_rebaser)(unsafe.Pointer(p)).Fgrp.FpList
			for {
				if !(pTab != 0) {
					break
				}
				if 0 == Xsqlite3_stricmp(tls, (*TSessionTable)(unsafe.Pointer(pTab)).FzName, zTab) {
					break
				}
				goto _1
			_1:
				;
				pTab = (*TSessionTable)(unsafe.Pointer(pTab)).FpNext
			}
			**(**int32)(__ccgo_up(bp + 20)) = 0
			/* A patchset may not be rebased */
			if (*Tsqlite3_changeset_iter)(unsafe.Pointer(pIter)).FbPatchset != 0 {
				**(**int32)(__ccgo_up(bp)) = int32(SQLITE_ERROR)
			}
			/* Append a table header to the output for this new table */
			if (*Tsqlite3_changeset_iter)(unsafe.Pointer(pIter)).FbPatchset != 0 {
				v2 = int32('P')
			} else {
				v2 = int32('T')
			}
			_sessionAppendByte(tls, bp+24, libc.Uint8FromInt32(v2), bp)
			_sessionAppendVarint(tls, bp+24, (*Tsqlite3_changeset_iter)(unsafe.Pointer(pIter)).FnCol, bp)
			_sessionAppendBlob(tls, bp+24, (*Tsqlite3_changeset_iter)(unsafe.Pointer(pIter)).FabPK, (*Tsqlite3_changeset_iter)(unsafe.Pointer(pIter)).FnCol, bp)
			_sessionAppendBlob(tls, bp+24, (*Tsqlite3_changeset_iter)(unsafe.Pointer(pIter)).FzTab, libc.Int32FromUint64(libc.Xstrlen(tls, (*Tsqlite3_changeset_iter)(unsafe.Pointer(pIter)).FzTab))+int32(1), bp)
		}
		if pTab != 0 && **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
			iHash = libc.Int32FromUint32(_sessionChangeHash(tls, pTab, 0, **(**uintptr)(__ccgo_up(bp + 8)), (*TSessionTable)(unsafe.Pointer(pTab)).FnChange))
			pChange = **(**uintptr)(__ccgo_up((*TSessionTable)(unsafe.Pointer(pTab)).FapChange + uintptr(iHash)*8))
			for {
				if !(pChange != 0) {
					break
				}
				if _sessionChangeEqual(tls, pTab, 0, **(**uintptr)(__ccgo_up(bp + 8)), 0, (*TSessionChange)(unsafe.Pointer(pChange)).FaRecord) != 0 {
					break
				}
				goto _3
			_3:
				;
				pChange = (*TSessionChange)(unsafe.Pointer(pChange)).FpNext
			}
		}
		if pChange != 0 {
			switch (*Tsqlite3_changeset_iter)(unsafe.Pointer(pIter)).Fop {
			case int32(SQLITE_INSERT):
				if libc.Int32FromUint8((*TSessionChange)(unsafe.Pointer(pChange)).Fop) == int32(SQLITE_INSERT) {
					bDone = int32(1)
					if libc.Int32FromUint8((*TSessionChange)(unsafe.Pointer(pChange)).FbIndirect) == 0 {
						_sessionAppendByte(tls, bp+24, uint8(SQLITE_UPDATE), bp)
						_sessionAppendByte(tls, bp+24, libc.Uint8FromInt32((*Tsqlite3_changeset_iter)(unsafe.Pointer(pIter)).FbIndirect), bp)
						_sessionAppendBlob(tls, bp+24, (*TSessionChange)(unsafe.Pointer(pChange)).FaRecord, (*TSessionChange)(unsafe.Pointer(pChange)).FnRecord, bp)
						_sessionAppendBlob(tls, bp+24, **(**uintptr)(__ccgo_up(bp + 8)), **(**int32)(__ccgo_up(bp + 16)), bp)
					}
				}
			case int32(SQLITE_UPDATE):
				bDone = int32(1)
				if libc.Int32FromUint8((*TSessionChange)(unsafe.Pointer(pChange)).Fop) == int32(SQLITE_DELETE) {
					if libc.Int32FromUint8((*TSessionChange)(unsafe.Pointer(pChange)).FbIndirect) == 0 {
						**(**uintptr)(__ccgo_up(bp + 40)) = **(**uintptr)(__ccgo_up(bp + 8))
						_sessionSkipRecord(tls, bp+40, (*Tsqlite3_changeset_iter)(unsafe.Pointer(pIter)).FnCol)
						_sessionAppendByte(tls, bp+24, uint8(SQLITE_INSERT), bp)
						_sessionAppendByte(tls, bp+24, libc.Uint8FromInt32((*Tsqlite3_changeset_iter)(unsafe.Pointer(pIter)).FbIndirect), bp)
						_sessionAppendRecordMerge(tls, bp+24, (*Tsqlite3_changeset_iter)(unsafe.Pointer(pIter)).FnCol, **(**uintptr)(__ccgo_up(bp + 40)), int32(int64(**(**int32)(__ccgo_up(bp + 16)))-(int64(**(**uintptr)(__ccgo_up(bp + 40)))-int64(**(**uintptr)(__ccgo_up(bp + 8))))), (*TSessionChange)(unsafe.Pointer(pChange)).FaRecord, (*TSessionChange)(unsafe.Pointer(pChange)).FnRecord, bp)
					}
				} else {
					_sessionAppendPartialUpdate(tls, bp+24, pIter, **(**uintptr)(__ccgo_up(bp + 8)), **(**int32)(__ccgo_up(bp + 16)), (*TSessionChange)(unsafe.Pointer(pChange)).FaRecord, (*TSessionChange)(unsafe.Pointer(pChange)).FnRecord, bp)
				}
			default:
				bDone = int32(1)
				if libc.Int32FromUint8((*TSessionChange)(unsafe.Pointer(pChange)).Fop) == int32(SQLITE_INSERT) {
					_sessionAppendByte(tls, bp+24, uint8(SQLITE_DELETE), bp)
					_sessionAppendByte(tls, bp+24, libc.Uint8FromInt32((*Tsqlite3_changeset_iter)(unsafe.Pointer(pIter)).FbIndirect), bp)
					_sessionAppendRecordMerge(tls, bp+24, (*Tsqlite3_changeset_iter)(unsafe.Pointer(pIter)).FnCol, (*TSessionChange)(unsafe.Pointer(pChange)).FaRecord, (*TSessionChange)(unsafe.Pointer(pChange)).FnRecord, **(**uintptr)(__ccgo_up(bp + 8)), **(**int32)(__ccgo_up(bp + 16)), bp)
				}
				break
			}
		}
		if bDone == 0 {
			_sessionAppendByte(tls, bp+24, libc.Uint8FromInt32((*Tsqlite3_changeset_iter)(unsafe.Pointer(pIter)).Fop), bp)
			_sessionAppendByte(tls, bp+24, libc.Uint8FromInt32((*Tsqlite3_changeset_iter)(unsafe.Pointer(pIter)).FbIndirect), bp)
			_sessionAppendBlob(tls, bp+24, **(**uintptr)(__ccgo_up(bp + 8)), **(**int32)(__ccgo_up(bp + 16)), bp)
		}
		if **(**int32)(__ccgo_up(bp)) == SQLITE_OK && __ccgo_fp_xOutput != 0 && (**(**TSessionBuffer)(__ccgo_up(bp + 24))).FnBuf > _sessions_strm_chunk_size {
			**(**int32)(__ccgo_up(bp)) = (*(*func(*libc.TLS, uintptr, uintptr, int32) int32)(unsafe.Pointer(&struct{ uintptr }{__ccgo_fp_xOutput})))(tls, pOut, (**(**TSessionBuffer)(__ccgo_up(bp + 24))).FaBuf, (**(**TSessionBuffer)(__ccgo_up(bp + 24))).FnBuf)
			(**(**TSessionBuffer)(__ccgo_up(bp + 24))).FnBuf = 0
		}
		if **(**int32)(__ccgo_up(bp)) != 0 {
			break
		}
	}
	if **(**int32)(__ccgo_up(bp)) != SQLITE_OK {
		Xsqlite3_free(tls, (**(**TSessionBuffer)(__ccgo_up(bp + 24))).FaBuf)
		libc.Xmemset(tls, bp+24, 0, uint64(16))
	}
	if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
		if __ccgo_fp_xOutput != 0 {
			if (**(**TSessionBuffer)(__ccgo_up(bp + 24))).FnBuf > 0 {
				**(**int32)(__ccgo_up(bp)) = (*(*func(*libc.TLS, uintptr, uintptr, int32) int32)(unsafe.Pointer(&struct{ uintptr }{__ccgo_fp_xOutput})))(tls, pOut, (**(**TSessionBuffer)(__ccgo_up(bp + 24))).FaBuf, (**(**TSessionBuffer)(__ccgo_up(bp + 24))).FnBuf)
			}
		} else {
			if ppOut != 0 {
				**(**uintptr)(__ccgo_up(ppOut)) = (**(**TSessionBuffer)(__ccgo_up(bp + 24))).FaBuf
				**(**int32)(__ccgo_up(pnOut)) = (**(**TSessionBuffer)(__ccgo_up(bp + 24))).FnBuf
				(**(**TSessionBuffer)(__ccgo_up(bp + 24))).FaBuf = uintptr(0)
			}
		}
	}
	Xsqlite3_free(tls, (**(**TSessionBuffer)(__ccgo_up(bp + 24))).FaBuf)
	return **(**int32)(__ccgo_up(bp))
}

// C documentation
//
//	/*
//	** Create an iterator to iterate through the retry buffer pRetry.
//	*/
func _sessionRetryIterInit(tls *libc.TLS, pRetry uintptr, bPatchset int32, zTab uintptr, pApply uintptr, ppIter uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var nByte Tsize_t
	var _ /* pRet at bp+0 */ uintptr
	var _ /* rc at bp+8 */ int32
	_ = nByte
	**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
	**(**int32)(__ccgo_up(bp + 8)) = SQLITE_OK
	**(**int32)(__ccgo_up(bp + 8)) = _sessionChangesetStart(tls, bp, uintptr(0), uintptr(0), (*TSessionBuffer)(unsafe.Pointer(pRetry)).FnBuf, (*TSessionBuffer)(unsafe.Pointer(pRetry)).FaBuf, (*TSessionApplyCtx)(unsafe.Pointer(pApply)).FbInvertConstraints, int32(1))
	if **(**int32)(__ccgo_up(bp + 8)) == SQLITE_OK {
		nByte = libc.Uint64FromInt32(int32(2)*(*TSessionApplyCtx)(unsafe.Pointer(pApply)).FnCol) * uint64(8)
		(*Tsqlite3_changeset_iter)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FbPatchset = bPatchset
		(*Tsqlite3_changeset_iter)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FzTab = zTab
		(*Tsqlite3_changeset_iter)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FnCol = (*TSessionApplyCtx)(unsafe.Pointer(pApply)).FnCol
		(*Tsqlite3_changeset_iter)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FabPK = (*TSessionApplyCtx)(unsafe.Pointer(pApply)).FabPK
		_sessionBufferGrow(tls, **(**uintptr)(__ccgo_up(bp))+72, libc.Int64FromUint64(nByte), bp+8)
		(*Tsqlite3_changeset_iter)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FapValue = (*Tsqlite3_changeset_iter)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).Ftblhdr.FaBuf
		if **(**int32)(__ccgo_up(bp + 8)) == SQLITE_OK {
			libc.Xmemset(tls, (*Tsqlite3_changeset_iter)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FapValue, 0, nByte)
		} else {
			Xsqlite3changeset_finalize(tls, **(**uintptr)(__ccgo_up(bp)))
			**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
		}
	}
	**(**uintptr)(__ccgo_up(ppIter)) = **(**uintptr)(__ccgo_up(bp))
	return **(**int32)(__ccgo_up(bp + 8))
}

// C documentation
//
//	/*
//	** Bind the PRIMARY KEY values from the change passed in argument pChange
//	** to the SELECT statement passed as the first argument. The SELECT statement
//	** is as prepared by function sessionSelectStmt().
//	**
//	** Return SQLITE_OK if all PK values are successfully bound, or an SQLite
//	** error code (e.g. SQLITE_NOMEM) otherwise.
//	*/
func _sessionSelectBind(tls *libc.TLS, pSelect uintptr, nCol int32, abPK uintptr, pChange uintptr) (r int32) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var a, v2 uintptr
	var eType, i, rc int32
	var iVal Ti64
	var _ /* iVal at bp+8 */ Ti64
	var _ /* n at bp+16 */ int32
	var _ /* n at bp+20 */ int32
	var _ /* rVal at bp+0 */ float64
	_, _, _, _, _, _ = a, eType, i, iVal, rc, v2
	rc = SQLITE_OK
	a = (*TSessionChange)(unsafe.Pointer(pChange)).FaRecord
	i = 0
	for {
		if !(i < nCol && rc == SQLITE_OK) {
			break
		}
		v2 = a
		a = a + 1
		eType = libc.Int32FromUint8(**(**Tu8)(__ccgo_up(v2)))
		switch eType {
		case 0:
			fallthrough
		case int32(SQLITE_NULL):
		case int32(SQLITE_INTEGER):
			if **(**Tu8)(__ccgo_up(abPK + uintptr(i))) != 0 {
				iVal = _sessionGetI64(tls, a)
				rc = Xsqlite3_bind_int64(tls, pSelect, i+int32(1), iVal)
			}
			a = a + uintptr(8)
		case int32(SQLITE_FLOAT):
			if **(**Tu8)(__ccgo_up(abPK + uintptr(i))) != 0 {
				**(**Ti64)(__ccgo_up(bp + 8)) = _sessionGetI64(tls, a)
				libc.Xmemcpy(tls, bp, bp+8, uint64(8))
				rc = Xsqlite3_bind_double(tls, pSelect, i+int32(1), **(**float64)(__ccgo_up(bp)))
			}
			a = a + uintptr(8)
		case int32(SQLITE_TEXT):
			a = a + uintptr(_sessionVarintGet(tls, a, bp+16))
			if **(**Tu8)(__ccgo_up(abPK + uintptr(i))) != 0 {
				rc = Xsqlite3_bind_text(tls, pSelect, i+int32(1), a, **(**int32)(__ccgo_up(bp + 16)), uintptr(-libc.Int32FromInt32(1)))
			}
			a = a + uintptr(**(**int32)(__ccgo_up(bp + 16)))
		default:
			a = a + uintptr(_sessionVarintGet(tls, a, bp+20))
			if **(**Tu8)(__ccgo_up(abPK + uintptr(i))) != 0 {
				rc = Xsqlite3_bind_blob(tls, pSelect, i+int32(1), a, **(**int32)(__ccgo_up(bp + 20)), uintptr(-libc.Int32FromInt32(1)))
			}
			a = a + uintptr(**(**int32)(__ccgo_up(bp + 20)))
			break
		}
		goto _1
	_1:
		;
		i = i + 1
	}
	return rc
}

// C documentation
//
//	/*
//	** This function is used to serialize the contents of value pValue (see
//	** comment titled "RECORD FORMAT" above).
//	**
//	** If it is non-NULL, the serialized form of the value is written to
//	** buffer aBuf. *pnWrite is set to the number of bytes written before
//	** returning. Or, if aBuf is NULL, the only thing this function does is
//	** set *pnWrite.
//	**
//	** If no error occurs, SQLITE_OK is returned. Or, if an OOM error occurs
//	** within a call to sqlite3_value_text() (may fail if the db is utf-16))
//	** SQLITE_NOMEM is returned.
//	*/
func _sessionSerializeValue(tls *libc.TLS, aBuf uintptr, pValue uintptr, pnWrite uintptr) (r1 int32) {
	var eType, n, nByte, nVarint int32
	var i Tu64
	var r float64
	var z uintptr
	_, _, _, _, _, _, _ = eType, i, n, nByte, nVarint, r, z /* Size of serialized value in bytes */
	if pValue != 0 {                                        /* Value type (SQLITE_NULL, TEXT etc.) */
		eType = Xsqlite3_value_type(tls, pValue)
		if aBuf != 0 {
			**(**Tu8)(__ccgo_up(aBuf)) = libc.Uint8FromInt32(eType)
		}
		switch eType {
		case int32(SQLITE_NULL):
			nByte = int32(1)
		case int32(SQLITE_INTEGER):
			fallthrough
		case int32(SQLITE_FLOAT):
			if aBuf != 0 {
				/* TODO: SQLite does something special to deal with mixed-endian
				 ** floating point values (e.g. ARM7). This code probably should
				 ** too.  */
				if eType == int32(SQLITE_INTEGER) {
					i = libc.Uint64FromInt64(Xsqlite3_value_int64(tls, pValue))
					_sessionPutI64(tls, aBuf+1, libc.Int64FromUint64(i))
				} else {
					r = Xsqlite3_value_double(tls, pValue)
					_sessionPutDouble(tls, aBuf+1, r)
				}
			}
			nByte = int32(9)
		default:
			if eType == int32(SQLITE_TEXT) {
				z = Xsqlite3_value_text(tls, pValue)
			} else {
				z = Xsqlite3_value_blob(tls, pValue)
			}
			n = Xsqlite3_value_bytes(tls, pValue)
			if z == uintptr(0) && (eType != int32(SQLITE_BLOB) || n > 0) {
				return int32(SQLITE_NOMEM)
			}
			nVarint = _sessionVarintLen(tls, n)
			if aBuf != 0 {
				_sessionVarintPut(tls, aBuf+1, n)
				if n > 0 {
					libc.Xmemcpy(tls, aBuf+uintptr(nVarint+int32(1)), z, libc.Uint64FromInt32(n))
				}
			}
			nByte = int32(1) + nVarint + n
			break
		}
	} else {
		nByte = int32(1)
		if aBuf != 0 {
			**(**Tu8)(__ccgo_up(aBuf)) = uint8('\000')
		}
	}
	if pnWrite != 0 {
		**(**Tsqlite3_int64)(__ccgo_up(pnWrite)) += int64(nByte)
	}
	return SQLITE_OK
}

func _sessionUpdateMaxSize(tls *libc.TLS, op int32, pSession uintptr, pTab uintptr, pC uintptr) (r int32) {
	bp := tls.Alloc(48)
	defer tls.Free(48)
	var bChanged, eType, iIdx, ii, ii1, nIncr, nOld int32
	var pCsr, v3 uintptr
	var _ /* dVal at bp+32 */ float64
	var _ /* iVal at bp+24 */ Tsqlite3_int64
	var _ /* nByte at bp+40 */ int32
	var _ /* nNew at bp+0 */ Ti64
	var _ /* p at bp+16 */ uintptr
	var _ /* p at bp+8 */ uintptr
	_, _, _, _, _, _, _, _, _ = bChanged, eType, iIdx, ii, ii1, nIncr, nOld, pCsr, v3
	**(**Ti64)(__ccgo_up(bp)) = int64(2)
	if libc.Int32FromUint8((*TSessionChange)(unsafe.Pointer(pC)).Fop) == int32(SQLITE_INSERT) {
		if (*TSessionTable)(unsafe.Pointer(pTab)).FbRowid != 0 {
			**(**Ti64)(__ccgo_up(bp)) = **(**Ti64)(__ccgo_up(bp)) + int64(9)
		}
		if op != int32(SQLITE_DELETE) {
			ii = 0
			for {
				if !(ii < (*TSessionTable)(unsafe.Pointer(pTab)).FnCol) {
					break
				}
				**(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0)
				(*(*func(*libc.TLS, uintptr, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*Tsqlite3_session)(unsafe.Pointer(pSession)).Fhook.FxNew})))(tls, (*Tsqlite3_session)(unsafe.Pointer(pSession)).Fhook.FpCtx, **(**int32)(__ccgo_up((*TSessionTable)(unsafe.Pointer(pTab)).FaiIdx + uintptr(ii)*4)), bp+8)
				_sessionSerializeValue(tls, uintptr(0), **(**uintptr)(__ccgo_up(bp + 8)), bp)
				goto _1
			_1:
				;
				ii = ii + 1
			}
		}
	} else {
		if op == int32(SQLITE_DELETE) {
			**(**Ti64)(__ccgo_up(bp)) = **(**Ti64)(__ccgo_up(bp)) + int64((*TSessionChange)(unsafe.Pointer(pC)).FnRecord)
			if Xsqlite3_preupdate_blobwrite(tls, (*Tsqlite3_session)(unsafe.Pointer(pSession)).Fdb) >= 0 {
				**(**Ti64)(__ccgo_up(bp)) = **(**Ti64)(__ccgo_up(bp)) + int64((*TSessionChange)(unsafe.Pointer(pC)).FnRecord)
			}
		} else {
			pCsr = (*TSessionChange)(unsafe.Pointer(pC)).FaRecord
			if (*TSessionTable)(unsafe.Pointer(pTab)).FbRowid != 0 {
				**(**Ti64)(__ccgo_up(bp)) = **(**Ti64)(__ccgo_up(bp)) + int64(libc.Int32FromInt32(9)+libc.Int32FromInt32(1))
				pCsr = pCsr + uintptr(9)
			}
			ii1 = (*TSessionTable)(unsafe.Pointer(pTab)).FbRowid
			for {
				if !(ii1 < (*TSessionTable)(unsafe.Pointer(pTab)).FnCol) {
					break
				}
				bChanged = int32(1)
				nOld = 0
				iIdx = **(**int32)(__ccgo_up((*TSessionTable)(unsafe.Pointer(pTab)).FaiIdx + uintptr(ii1)*4))
				**(**uintptr)(__ccgo_up(bp + 16)) = uintptr(0)
				(*(*func(*libc.TLS, uintptr, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*Tsqlite3_session)(unsafe.Pointer(pSession)).Fhook.FxNew})))(tls, (*Tsqlite3_session)(unsafe.Pointer(pSession)).Fhook.FpCtx, iIdx, bp+16)
				if **(**uintptr)(__ccgo_up(bp + 16)) == uintptr(0) {
					return int32(SQLITE_NOMEM)
				}
				v3 = pCsr
				pCsr = pCsr + 1
				eType = libc.Int32FromUint8(**(**Tu8)(__ccgo_up(v3)))
				switch eType {
				case int32(SQLITE_NULL):
					bChanged = libc.BoolInt32(Xsqlite3_value_type(tls, **(**uintptr)(__ccgo_up(bp + 16))) != int32(SQLITE_NULL))
				case int32(SQLITE_FLOAT):
					fallthrough
				case int32(SQLITE_INTEGER):
					if eType == Xsqlite3_value_type(tls, **(**uintptr)(__ccgo_up(bp + 16))) {
						**(**Tsqlite3_int64)(__ccgo_up(bp + 24)) = _sessionGetI64(tls, pCsr)
						if eType == int32(SQLITE_INTEGER) {
							bChanged = libc.BoolInt32(**(**Tsqlite3_int64)(__ccgo_up(bp + 24)) != Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(bp + 16))))
						} else {
							libc.Xmemcpy(tls, bp+32, bp+24, uint64(8))
							bChanged = libc.BoolInt32(**(**float64)(__ccgo_up(bp + 32)) != Xsqlite3_value_double(tls, **(**uintptr)(__ccgo_up(bp + 16))))
						}
					}
					nOld = int32(8)
					pCsr = pCsr + uintptr(8)
				default:
					nOld = _sessionVarintGet(tls, pCsr, bp+40)
					pCsr = pCsr + uintptr(nOld)
					nOld = nOld + **(**int32)(__ccgo_up(bp + 40))
					if eType == Xsqlite3_value_type(tls, **(**uintptr)(__ccgo_up(bp + 16))) && **(**int32)(__ccgo_up(bp + 40)) == Xsqlite3_value_bytes(tls, **(**uintptr)(__ccgo_up(bp + 16))) && (**(**int32)(__ccgo_up(bp + 40)) == 0 || 0 == libc.Xmemcmp(tls, pCsr, Xsqlite3_value_blob(tls, **(**uintptr)(__ccgo_up(bp + 16))), libc.Uint64FromInt32(**(**int32)(__ccgo_up(bp + 40))))) {
						bChanged = 0
					}
					pCsr = pCsr + uintptr(**(**int32)(__ccgo_up(bp + 40)))
					break
				}
				if bChanged != 0 && **(**Tu8)(__ccgo_up((*TSessionTable)(unsafe.Pointer(pTab)).FabPK + uintptr(ii1))) != 0 {
					**(**Ti64)(__ccgo_up(bp)) = int64((*TSessionChange)(unsafe.Pointer(pC)).FnRecord + int32(2))
					break
				}
				if bChanged != 0 {
					**(**Ti64)(__ccgo_up(bp)) = **(**Ti64)(__ccgo_up(bp)) + int64(int32(1)+nOld)
					_sessionSerializeValue(tls, uintptr(0), **(**uintptr)(__ccgo_up(bp + 16)), bp)
				} else {
					if **(**Tu8)(__ccgo_up((*TSessionTable)(unsafe.Pointer(pTab)).FabPK + uintptr(ii1))) != 0 {
						**(**Ti64)(__ccgo_up(bp)) = **(**Ti64)(__ccgo_up(bp)) + int64(int32(2)+nOld)
					} else {
						**(**Ti64)(__ccgo_up(bp)) = **(**Ti64)(__ccgo_up(bp)) + int64(2)
					}
				}
				goto _2
			_2:
				;
				ii1 = ii1 + 1
			}
		}
	}
	if **(**Ti64)(__ccgo_up(bp)) > int64((*TSessionChange)(unsafe.Pointer(pC)).FnMaxSize) {
		nIncr = int32(**(**Ti64)(__ccgo_up(bp)) - int64((*TSessionChange)(unsafe.Pointer(pC)).FnMaxSize))
		(*TSessionChange)(unsafe.Pointer(pC)).FnMaxSize = int32(**(**Ti64)(__ccgo_up(bp)))
		**(**Ti64)(__ccgo_up(pSession + 64)) += int64(nIncr)
	}
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** Session-change object (*pp) contains an old.* record with fewer than
//	** nCol fields. This function updates it with the default values for
//	** the missing fields.
//	*/
func _sessionUpdateOneChange(tls *libc.TLS, pSession uintptr, pRc uintptr, pp uintptr, nCol int32, pDflt uintptr) {
	var eType, iField, n, n1, n2, nByte, nIncr, v1 int32
	var iVal Ti64
	var pNew, pOld, z, z1, v2 uintptr
	var rVal float64
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = eType, iField, iVal, n, n1, n2, nByte, nIncr, pNew, pOld, rVal, z, z1, v1, v2
	pOld = **(**uintptr)(__ccgo_up(pp))
	for libc.Int32FromUint16((*TSessionChange)(unsafe.Pointer(pOld)).FnRecordField) < nCol {
		pNew = uintptr(0)
		nByte = 0
		nIncr = 0
		iField = libc.Int32FromUint16((*TSessionChange)(unsafe.Pointer(pOld)).FnRecordField)
		eType = Xsqlite3_column_type(tls, pDflt, iField)
		switch eType {
		case int32(SQLITE_NULL):
			nIncr = int32(1)
		case int32(SQLITE_INTEGER):
			fallthrough
		case int32(SQLITE_FLOAT):
			nIncr = int32(9)
		default:
			n = Xsqlite3_column_bytes(tls, pDflt, iField)
			nIncr = int32(1) + _sessionVarintLen(tls, n) + n
			break
		}
		nByte = libc.Int32FromUint64(libc.Uint64FromInt32(nIncr) + (uint64(32) + libc.Uint64FromInt32((*TSessionChange)(unsafe.Pointer(pOld)).FnRecord)))
		pNew = _sessionMalloc64(tls, pSession, int64(nByte))
		if pNew == uintptr(0) {
			**(**int32)(__ccgo_up(pRc)) = int32(SQLITE_NOMEM)
			return
		} else {
			libc.Xmemcpy(tls, pNew, pOld, uint64(32))
			(*TSessionChange)(unsafe.Pointer(pNew)).FaRecord = pNew + 1*32
			libc.Xmemcpy(tls, (*TSessionChange)(unsafe.Pointer(pNew)).FaRecord, (*TSessionChange)(unsafe.Pointer(pOld)).FaRecord, libc.Uint64FromInt32((*TSessionChange)(unsafe.Pointer(pOld)).FnRecord))
			v2 = pNew + 8
			v1 = *(*int32)(unsafe.Pointer(v2))
			*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1
			**(**Tu8)(__ccgo_up((*TSessionChange)(unsafe.Pointer(pNew)).FaRecord + uintptr(v1))) = libc.Uint8FromInt32(eType)
			switch eType {
			case int32(SQLITE_INTEGER):
				iVal = Xsqlite3_column_int64(tls, pDflt, iField)
				_sessionPutI64(tls, (*TSessionChange)(unsafe.Pointer(pNew)).FaRecord+uintptr((*TSessionChange)(unsafe.Pointer(pNew)).FnRecord), iVal)
				**(**int32)(__ccgo_up(pNew + 8)) += int32(8)
			case int32(SQLITE_FLOAT):
				rVal = Xsqlite3_column_double(tls, pDflt, iField)
				_sessionPutDouble(tls, (*TSessionChange)(unsafe.Pointer(pNew)).FaRecord+uintptr((*TSessionChange)(unsafe.Pointer(pNew)).FnRecord), rVal)
				**(**int32)(__ccgo_up(pNew + 8)) += int32(8)
			case int32(SQLITE_TEXT):
				n1 = Xsqlite3_column_bytes(tls, pDflt, iField)
				z = Xsqlite3_column_text(tls, pDflt, iField)
				**(**int32)(__ccgo_up(pNew + 8)) += _sessionVarintPut(tls, (*TSessionChange)(unsafe.Pointer(pNew)).FaRecord+uintptr((*TSessionChange)(unsafe.Pointer(pNew)).FnRecord), n1)
				libc.Xmemcpy(tls, (*TSessionChange)(unsafe.Pointer(pNew)).FaRecord+uintptr((*TSessionChange)(unsafe.Pointer(pNew)).FnRecord), z, libc.Uint64FromInt32(n1))
				**(**int32)(__ccgo_up(pNew + 8)) += n1
			case int32(SQLITE_BLOB):
				n2 = Xsqlite3_column_bytes(tls, pDflt, iField)
				z1 = Xsqlite3_column_blob(tls, pDflt, iField)
				**(**int32)(__ccgo_up(pNew + 8)) += _sessionVarintPut(tls, (*TSessionChange)(unsafe.Pointer(pNew)).FaRecord+uintptr((*TSessionChange)(unsafe.Pointer(pNew)).FnRecord), n2)
				libc.Xmemcpy(tls, (*TSessionChange)(unsafe.Pointer(pNew)).FaRecord+uintptr((*TSessionChange)(unsafe.Pointer(pNew)).FnRecord), z1, libc.Uint64FromInt32(n2))
				**(**int32)(__ccgo_up(pNew + 8)) += n2
			default:
				break
			}
			_sessionFree(tls, pSession, pOld)
			v2 = pNew
			pOld = v2
			**(**uintptr)(__ccgo_up(pp)) = v2
			(*TSessionChange)(unsafe.Pointer(pNew)).FnRecordField = (*TSessionChange)(unsafe.Pointer(pNew)).FnRecordField + 1
			**(**int32)(__ccgo_up(pNew + 4)) += nIncr
			if pSession != 0 {
				**(**Ti64)(__ccgo_up(pSession + 64)) += int64(nIncr)
			}
		}
	}
}

// C documentation
//
//	/*
//	** This function sets the value of the sqlite3_value object passed as the
//	** first argument to a copy of the string or blob held in the aData[]
//	** buffer. SQLITE_OK is returned if successful, or SQLITE_NOMEM if an OOM
//	** error occurs.
//	*/
func _sessionValueSetStr(tls *libc.TLS, pVal uintptr, aData uintptr, nData int32, enc Tu8) (r int32) {
	var aCopy uintptr
	_ = aCopy
	/* In theory this code could just pass SQLITE_TRANSIENT as the final
	 ** argument to sqlite3ValueSetStr() and have the copy created
	 ** automatically. But doing so makes it difficult to detect any OOM
	 ** error. Hence the code to create the copy externally. */
	aCopy = Xsqlite3_malloc64(tls, libc.Uint64FromInt64(int64(nData)+int64(1)))
	if aCopy == uintptr(0) {
		return int32(SQLITE_NOMEM)
	}
	libc.Xmemcpy(tls, aCopy, aData, libc.Uint64FromInt32(nData))
	_sqlite3ValueSetStr(tls, pVal, nData, aCopy, enc, __ccgo_fp(Xsqlite3_free))
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** Read a varint value from buffer aBuf[], size nBuf bytes, into *piVal.
//	** Return the number of bytes read.
//	*/
func _sessionVarintGetSafe(tls *libc.TLS, aBuf uintptr, nBuf int32, piVal uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var aRead uintptr
	var v1 int32
	var _ /* aCopy at bp+0 */ [9]Tu8
	_, _ = aRead, v1
	aRead = aBuf
	libc.Xmemset(tls, bp, 0, uint64(9))
	if libc.Uint64FromInt32(nBuf) < uint64(9) {
		libc.Xmemcpy(tls, bp, aBuf, libc.Uint64FromInt32(nBuf))
		aRead = bp
	}
	if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aRead))) < libc.Int32FromUint8(libc.Uint8FromInt32(0x80)) {
		**(**int32)(__ccgo_up(piVal)) = libc.Int32FromUint32(uint32(**(**Tu8)(__ccgo_up(aRead))))
		v1 = libc.Int32FromInt32(1)
	} else {
		v1 = libc.Int32FromUint8(_sqlite3GetVarint32(tls, aRead, piVal))
	}
	return libc.Int32FromUint8(libc.Uint8FromInt32(v1))
}

/* Load an unaligned and unsigned 32-bit integer */

// C documentation
//
//	/*
//	** Implementation of the R*-tree variant of SplitNode from Beckman[1990].
//	*/
func _splitNodeStartree(tls *libc.TLS, pRtree uintptr, aCell uintptr, nCell int32, pLeft uintptr, pRight uintptr, pBboxLeft uintptr, pBboxRight uintptr) (r int32) {
	bp := tls.Alloc(96)
	defer tls.Free(96)
	var aSpare, aaSorted, pBbox, pCell, pTarget, v7, v8 uintptr
	var area, fBestArea, fBestMargin, fBestOverlap, margin, overlap TRtreeDValue
	var iBestDim, iBestLeft, iBestSplit, ii, jj, kk, nLeft int32
	var nByte Tsqlite3_int64
	var _ /* left at bp+0 */ TRtreeCell
	var _ /* right at bp+48 */ TRtreeCell
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = aSpare, aaSorted, area, fBestArea, fBestMargin, fBestOverlap, iBestDim, iBestLeft, iBestSplit, ii, jj, kk, margin, nByte, nLeft, overlap, pBbox, pCell, pTarget, v7, v8
	iBestDim = 0
	iBestSplit = 0
	fBestMargin = float64(0)
	nByte = libc.Int64FromUint64(libc.Uint64FromInt32(libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FnDim)+libc.Int32FromInt32(1)) * (uint64(8) + libc.Uint64FromInt32(nCell)*uint64(4)))
	aaSorted = Xsqlite3_malloc64(tls, libc.Uint64FromInt64(nByte))
	if !(aaSorted != 0) {
		return int32(SQLITE_NOMEM)
	}
	aSpare = aaSorted + uintptr((*TRtree)(unsafe.Pointer(pRtree)).FnDim)*8 + uintptr(libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FnDim)*nCell)*4
	libc.Xmemset(tls, aaSorted, 0, libc.Uint64FromInt64(nByte))
	ii = 0
	for {
		if !(ii < libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FnDim)) {
			break
		}
		**(**uintptr)(__ccgo_up(aaSorted + uintptr(ii)*8)) = aaSorted + uintptr((*TRtree)(unsafe.Pointer(pRtree)).FnDim)*8 + uintptr(ii*nCell)*4
		jj = 0
		for {
			if !(jj < nCell) {
				break
			}
			**(**int32)(__ccgo_up(**(**uintptr)(__ccgo_up(aaSorted + uintptr(ii)*8)) + uintptr(jj)*4)) = jj
			goto _2
		_2:
			;
			jj = jj + 1
		}
		_SortByDimension(tls, pRtree, **(**uintptr)(__ccgo_up(aaSorted + uintptr(ii)*8)), nCell, ii, aCell, aSpare)
		goto _1
	_1:
		;
		ii = ii + 1
	}
	ii = 0
	for {
		if !(ii < libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FnDim)) {
			break
		}
		margin = float64(0)
		fBestOverlap = float64(0)
		fBestArea = float64(0)
		iBestLeft = 0
		nLeft = ((*TRtree)(unsafe.Pointer(pRtree)).FiNodeSize - int32(4)) / libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FnBytesPerCell) / int32(3)
		for {
			if !(nLeft <= nCell-((*TRtree)(unsafe.Pointer(pRtree)).FiNodeSize-int32(4))/libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FnBytesPerCell)/int32(3)) {
				break
			}
			libc.Xmemcpy(tls, bp, aCell+uintptr(**(**int32)(__ccgo_up(**(**uintptr)(__ccgo_up(aaSorted + uintptr(ii)*8)))))*48, uint64(48))
			libc.Xmemcpy(tls, bp+48, aCell+uintptr(**(**int32)(__ccgo_up(**(**uintptr)(__ccgo_up(aaSorted + uintptr(ii)*8)) + uintptr(nCell-int32(1))*4)))*48, uint64(48))
			kk = int32(1)
			for {
				if !(kk < nCell-int32(1)) {
					break
				}
				if kk < nLeft {
					_cellUnion(tls, pRtree, bp, aCell+uintptr(**(**int32)(__ccgo_up(**(**uintptr)(__ccgo_up(aaSorted + uintptr(ii)*8)) + uintptr(kk)*4)))*48)
				} else {
					_cellUnion(tls, pRtree, bp+48, aCell+uintptr(**(**int32)(__ccgo_up(**(**uintptr)(__ccgo_up(aaSorted + uintptr(ii)*8)) + uintptr(kk)*4)))*48)
				}
				goto _5
			_5:
				;
				kk = kk + 1
			}
			margin = margin + _cellMargin(tls, pRtree, bp)
			margin = margin + _cellMargin(tls, pRtree, bp+48)
			overlap = _cellOverlap(tls, pRtree, bp, bp+48, int32(1))
			area = _cellArea(tls, pRtree, bp) + _cellArea(tls, pRtree, bp+48)
			if nLeft == ((*TRtree)(unsafe.Pointer(pRtree)).FiNodeSize-int32(4))/libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FnBytesPerCell)/int32(3) || overlap < fBestOverlap || overlap == fBestOverlap && area < fBestArea {
				iBestLeft = nLeft
				fBestOverlap = overlap
				fBestArea = area
			}
			goto _4
		_4:
			;
			nLeft = nLeft + 1
		}
		if ii == 0 || margin < fBestMargin {
			iBestDim = ii
			fBestMargin = margin
			iBestSplit = iBestLeft
		}
		goto _3
	_3:
		;
		ii = ii + 1
	}
	libc.Xmemcpy(tls, pBboxLeft, aCell+uintptr(**(**int32)(__ccgo_up(**(**uintptr)(__ccgo_up(aaSorted + uintptr(iBestDim)*8)))))*48, uint64(48))
	libc.Xmemcpy(tls, pBboxRight, aCell+uintptr(**(**int32)(__ccgo_up(**(**uintptr)(__ccgo_up(aaSorted + uintptr(iBestDim)*8)) + uintptr(iBestSplit)*4)))*48, uint64(48))
	ii = 0
	for {
		if !(ii < nCell) {
			break
		}
		if ii < iBestSplit {
			v7 = pLeft
		} else {
			v7 = pRight
		}
		pTarget = v7
		if ii < iBestSplit {
			v8 = pBboxLeft
		} else {
			v8 = pBboxRight
		}
		pBbox = v8
		pCell = aCell + uintptr(**(**int32)(__ccgo_up(**(**uintptr)(__ccgo_up(aaSorted + uintptr(iBestDim)*8)) + uintptr(ii)*4)))*48
		_nodeInsertCell(tls, pRtree, pTarget, pCell)
		_cellUnion(tls, pRtree, pBbox, pCell)
		goto _6
	_6:
		;
		ii = ii + 1
	}
	Xsqlite3_free(tls, aaSorted)
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** pArray is a pointer to an array of objects. Each object in the
//	** array is szEntry bytes in size. This routine uses sqlite3DbRealloc()
//	** to extend the array so that there is space for a new object at the end.
//	**
//	** When this function is called, *pnEntry contains the current size of
//	** the array (in entries - so the allocation is ((*pnEntry) * szEntry) bytes
//	** in total).
//	**
//	** If the realloc() is successful (i.e. if no OOM condition occurs), the
//	** space allocated for the new object is zeroed, *pnEntry updated to
//	** reflect the new size of the array and a pointer to the new allocation
//	** returned. *pIdx is set to the index of the new array entry in this case.
//	**
//	** Otherwise, if the realloc() fails, *pIdx is set to -1, *pnEntry remains
//	** unchanged and a copy of pArray returned.
//	*/
func _sqlite3ArrayAllocate(tls *libc.TLS, db uintptr, pArray uintptr, szEntry int32, pnEntry uintptr, pIdx uintptr) (r uintptr) {
	var n, sz Tsqlite3_int64
	var pNew, z uintptr
	var v1 int32
	var v2 int64
	_, _, _, _, _, _ = n, pNew, sz, z, v1, v2
	v1 = **(**int32)(__ccgo_up(pnEntry))
	**(**int32)(__ccgo_up(pIdx)) = v1
	n = int64(v1)
	if n&(n-int64(1)) == 0 {
		if n == 0 {
			v2 = int64(1)
		} else {
			v2 = int64(2) * n
		}
		sz = v2
		pNew = _sqlite3DbRealloc(tls, db, pArray, libc.Uint64FromInt64(sz*int64(szEntry)))
		if pNew == uintptr(0) {
			**(**int32)(__ccgo_up(pIdx)) = -int32(1)
			return pArray
		}
		pArray = pNew
	}
	z = pArray
	libc.Xmemset(tls, z+uintptr(n*int64(szEntry)), 0, libc.Uint64FromInt32(szEntry))
	**(**int32)(__ccgo_up(pnEntry)) = **(**int32)(__ccgo_up(pnEntry)) + 1
	return pArray
}

// C documentation
//
//	/*
//	** Clear the i-th bit.
//	**
//	** pBuf must be a pointer to at least BITVEC_SZ bytes of temporary storage
//	** that BitvecClear can use to rebuilt its hash table.
//	*/
func _sqlite3BitvecClear(tls *libc.TLS, p uintptr, i Tu32, pBuf uintptr) {
	var aiValues, v1 uintptr
	var bin, h Tu32
	var j uint32
	_, _, _, _, _ = aiValues, bin, h, j, v1
	if p == uintptr(0) {
		return
	}
	i = i - 1
	for (*TBitvec)(unsafe.Pointer(p)).FiDivisor != 0 {
		bin = i / (*TBitvec)(unsafe.Pointer(p)).FiDivisor
		i = i % (*TBitvec)(unsafe.Pointer(p)).FiDivisor
		p = **(**uintptr)(__ccgo_up(p + 16 + uintptr(bin)*8))
		if !(p != 0) {
			return
		}
	}
	if uint64((*TBitvec)(unsafe.Pointer(p)).FiSize) <= (libc.Uint64FromInt32(BITVEC_SZ)-libc.Uint64FromInt32(3)*libc.Uint64FromInt64(4))/libc.Uint64FromInt64(8)*libc.Uint64FromInt64(8)/libc.Uint64FromInt64(1)*libc.Uint64FromInt32(BITVEC_SZELEM) {
		v1 = p + 16 + uintptr(i/uint32(BITVEC_SZELEM))
		*(*Tu8)(unsafe.Pointer(v1)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v1))) & ^libc.Int32FromUint8(libc.Uint8FromInt32(libc.Int32FromInt32(1)<<(i&libc.Uint32FromInt32(libc.Int32FromInt32(BITVEC_SZELEM)-libc.Int32FromInt32(1))))))
	} else {
		aiValues = pBuf
		libc.Xmemcpy(tls, aiValues, p+16, uint64(496))
		libc.Xmemset(tls, p+16, 0, uint64(496))
		(*TBitvec)(unsafe.Pointer(p)).FnSet = uint32(0)
		j = uint32(0)
		for {
			if !(uint64(j) < (libc.Uint64FromInt32(BITVEC_SZ)-libc.Uint64FromInt32(3)*libc.Uint64FromInt64(4))/libc.Uint64FromInt64(8)*libc.Uint64FromInt64(8)/libc.Uint64FromInt64(4)) {
				break
			}
			if **(**Tu32)(__ccgo_up(aiValues + uintptr(j)*4)) != 0 && **(**Tu32)(__ccgo_up(aiValues + uintptr(j)*4)) != i+uint32(1) {
				h = uint32(uint64((**(**Tu32)(__ccgo_up(aiValues + uintptr(j)*4))-libc.Uint32FromInt32(1))*libc.Uint32FromInt32(1)) % ((libc.Uint64FromInt32(BITVEC_SZ) - libc.Uint64FromInt32(3)*libc.Uint64FromInt64(4)) / libc.Uint64FromInt64(8) * libc.Uint64FromInt64(8) / libc.Uint64FromInt64(4)))
				(*TBitvec)(unsafe.Pointer(p)).FnSet = (*TBitvec)(unsafe.Pointer(p)).FnSet + 1
				for **(**Tu32)(__ccgo_up(p + 16 + uintptr(h)*4)) != 0 {
					h = h + 1
					if uint64(h) >= (libc.Uint64FromInt32(BITVEC_SZ)-libc.Uint64FromInt32(3)*libc.Uint64FromInt64(4))/libc.Uint64FromInt64(8)*libc.Uint64FromInt64(8)/libc.Uint64FromInt64(4) {
						h = uint32(0)
					}
				}
				**(**Tu32)(__ccgo_up(p + 16 + uintptr(h)*4)) = **(**Tu32)(__ccgo_up(aiValues + uintptr(j)*4))
			}
			goto _2
		_2:
			;
			j = j + 1
		}
	}
}

// C documentation
//
//	/*
//	** Set the i-th bit.  Return 0 on success and an error code if
//	** anything goes wrong.
//	**
//	** This routine might cause sub-bitmaps to be allocated.  Failing
//	** to get the memory needed to hold the sub-bitmap is the only
//	** that can go wrong with an insert, assuming p and i are valid.
//	**
//	** The calling function must ensure that p is a valid Bitvec object
//	** and that the value for "i" is within range of the Bitvec object.
//	** Otherwise the behavior is undefined.
//	*/
func _sqlite3BitvecSet(tls *libc.TLS, p uintptr, i Tu32) (r int32) {
	var aiValues, v1 uintptr
	var bin, h, v2 Tu32
	var j uint32
	var rc int32
	_, _, _, _, _, _, _ = aiValues, bin, h, j, rc, v1, v2
	if p == uintptr(0) {
		return SQLITE_OK
	}
	i = i - 1
	for uint64((*TBitvec)(unsafe.Pointer(p)).FiSize) > (libc.Uint64FromInt32(BITVEC_SZ)-libc.Uint64FromInt32(3)*libc.Uint64FromInt64(4))/libc.Uint64FromInt64(8)*libc.Uint64FromInt64(8)/libc.Uint64FromInt64(1)*libc.Uint64FromInt32(BITVEC_SZELEM) && (*TBitvec)(unsafe.Pointer(p)).FiDivisor != 0 {
		bin = i / (*TBitvec)(unsafe.Pointer(p)).FiDivisor
		i = i % (*TBitvec)(unsafe.Pointer(p)).FiDivisor
		if **(**uintptr)(__ccgo_up(p + 16 + uintptr(bin)*8)) == uintptr(0) {
			**(**uintptr)(__ccgo_up(p + 16 + uintptr(bin)*8)) = _sqlite3BitvecCreate(tls, (*TBitvec)(unsafe.Pointer(p)).FiDivisor)
			if **(**uintptr)(__ccgo_up(p + 16 + uintptr(bin)*8)) == uintptr(0) {
				return int32(SQLITE_NOMEM)
			}
		}
		p = **(**uintptr)(__ccgo_up(p + 16 + uintptr(bin)*8))
	}
	if uint64((*TBitvec)(unsafe.Pointer(p)).FiSize) <= (libc.Uint64FromInt32(BITVEC_SZ)-libc.Uint64FromInt32(3)*libc.Uint64FromInt64(4))/libc.Uint64FromInt64(8)*libc.Uint64FromInt64(8)/libc.Uint64FromInt64(1)*libc.Uint64FromInt32(BITVEC_SZELEM) {
		v1 = p + 16 + uintptr(i/uint32(BITVEC_SZELEM))
		*(*Tu8)(unsafe.Pointer(v1)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v1))) | libc.Int32FromInt32(1)<<(i&libc.Uint32FromInt32(libc.Int32FromInt32(BITVEC_SZELEM)-libc.Int32FromInt32(1))))
		return SQLITE_OK
	}
	v2 = i
	i = i + 1
	h = uint32(uint64(v2*libc.Uint32FromInt32(1)) % ((libc.Uint64FromInt32(BITVEC_SZ) - libc.Uint64FromInt32(3)*libc.Uint64FromInt64(4)) / libc.Uint64FromInt64(8) * libc.Uint64FromInt64(8) / libc.Uint64FromInt64(4)))
	/* if there wasn't a hash collision, and this doesn't */
	/* completely fill the hash, then just add it without */
	/* worrying about sub-dividing and re-hashing. */
	if !(**(**Tu32)(__ccgo_up(p + 16 + uintptr(h)*4)) != 0) {
		if uint64((*TBitvec)(unsafe.Pointer(p)).FnSet) < (libc.Uint64FromInt32(BITVEC_SZ)-libc.Uint64FromInt32(3)*libc.Uint64FromInt64(4))/libc.Uint64FromInt64(8)*libc.Uint64FromInt64(8)/libc.Uint64FromInt64(4)-libc.Uint64FromInt32(1) {
			goto bitvec_set_end
		} else {
			goto bitvec_set_rehash
		}
	}
	/* there was a collision, check to see if it's already */
	/* in hash, if not, try to find a spot for it */
	for cond := true; cond; cond = **(**Tu32)(__ccgo_up(p + 16 + uintptr(h)*4)) != 0 {
		if **(**Tu32)(__ccgo_up(p + 16 + uintptr(h)*4)) == i {
			return SQLITE_OK
		}
		h = h + 1
		if uint64(h) >= (libc.Uint64FromInt32(BITVEC_SZ)-libc.Uint64FromInt32(3)*libc.Uint64FromInt64(4))/libc.Uint64FromInt64(8)*libc.Uint64FromInt64(8)/libc.Uint64FromInt64(4) {
			h = uint32(0)
		}
	}
	/* we didn't find it in the hash.  h points to the first */
	/* available free spot. check to see if this is going to */
	/* make our hash too "full".  */
	goto bitvec_set_rehash
bitvec_set_rehash:
	;
	if uint64((*TBitvec)(unsafe.Pointer(p)).FnSet) >= (libc.Uint64FromInt32(BITVEC_SZ)-libc.Uint64FromInt32(3)*libc.Uint64FromInt64(4))/libc.Uint64FromInt64(8)*libc.Uint64FromInt64(8)/libc.Uint64FromInt64(4)/libc.Uint64FromInt32(2) {
		aiValues = _sqlite3DbMallocRaw(tls, uintptr(0), uint64(496))
		if aiValues == uintptr(0) {
			return int32(SQLITE_NOMEM)
		} else {
			libc.Xmemcpy(tls, aiValues, p+16, uint64(496))
			libc.Xmemset(tls, p+16, 0, uint64(496))
			(*TBitvec)(unsafe.Pointer(p)).FiDivisor = (*TBitvec)(unsafe.Pointer(p)).FiSize / uint32((libc.Uint64FromInt32(BITVEC_SZ)-libc.Uint64FromInt32(3)*libc.Uint64FromInt64(4))/libc.Uint64FromInt64(8)*libc.Uint64FromInt64(8)/libc.Uint64FromInt64(8))
			if (*TBitvec)(unsafe.Pointer(p)).FiSize%uint32((libc.Uint64FromInt32(BITVEC_SZ)-libc.Uint64FromInt32(3)*libc.Uint64FromInt64(4))/libc.Uint64FromInt64(8)*libc.Uint64FromInt64(8)/libc.Uint64FromInt64(8)) != uint32(0) {
				(*TBitvec)(unsafe.Pointer(p)).FiDivisor = (*TBitvec)(unsafe.Pointer(p)).FiDivisor + 1
			}
			if uint64((*TBitvec)(unsafe.Pointer(p)).FiDivisor) < (libc.Uint64FromInt32(BITVEC_SZ)-libc.Uint64FromInt32(3)*libc.Uint64FromInt64(4))/libc.Uint64FromInt64(8)*libc.Uint64FromInt64(8)/libc.Uint64FromInt64(1)*libc.Uint64FromInt32(BITVEC_SZELEM) {
				(*TBitvec)(unsafe.Pointer(p)).FiDivisor = uint32((libc.Uint64FromInt32(BITVEC_SZ) - libc.Uint64FromInt32(3)*libc.Uint64FromInt64(4)) / libc.Uint64FromInt64(8) * libc.Uint64FromInt64(8) / libc.Uint64FromInt64(1) * libc.Uint64FromInt32(BITVEC_SZELEM))
			}
			rc = _sqlite3BitvecSet(tls, p, i)
			j = uint32(0)
			for {
				if !(uint64(j) < (libc.Uint64FromInt32(BITVEC_SZ)-libc.Uint64FromInt32(3)*libc.Uint64FromInt64(4))/libc.Uint64FromInt64(8)*libc.Uint64FromInt64(8)/libc.Uint64FromInt64(4)) {
					break
				}
				if **(**Tu32)(__ccgo_up(aiValues + uintptr(j)*4)) != 0 {
					rc = rc | _sqlite3BitvecSet(tls, p, **(**Tu32)(__ccgo_up(aiValues + uintptr(j)*4)))
				}
				goto _3
			_3:
				;
				j = j + 1
			}
			_sqlite3DbFree(tls, uintptr(0), aiValues)
			return rc
		}
	}
	goto bitvec_set_end
bitvec_set_end:
	;
	(*TBitvec)(unsafe.Pointer(p)).FnSet = (*TBitvec)(unsafe.Pointer(p)).FnSet + 1
	**(**Tu32)(__ccgo_up(p + 16 + uintptr(h)*4)) = i
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** Copy the complete content of pBtFrom into pBtTo.  A transaction
//	** must be active for both files.
//	**
//	** The size of file pTo may be reduced by this operation. If anything
//	** goes wrong, the transaction on pTo is rolled back. If successful, the
//	** transaction is committed before returning.
//	*/
func _sqlite3BtreeCopyFile(tls *libc.TLS, pTo uintptr, pFrom uintptr) (r int32) {
	bp := tls.Alloc(80)
	defer tls.Free(80)
	var pFd, v1 uintptr
	var rc int32
	var _ /* b at bp+0 */ Tsqlite3_backup
	var _ /* nByte at bp+72 */ Ti64
	_, _, _ = pFd, rc, v1
	_sqlite3BtreeEnter(tls, pTo)
	_sqlite3BtreeEnter(tls, pFrom)
	pFd = _sqlite3PagerFile(tls, _sqlite3BtreePager(tls, pTo))
	if (*Tsqlite3_file)(unsafe.Pointer(pFd)).FpMethods != 0 {
		**(**Ti64)(__ccgo_up(bp + 72)) = int64(_sqlite3BtreeGetPageSize(tls, pFrom)) * libc.Int64FromUint32(_sqlite3BtreeLastPage(tls, pFrom))
		rc = _sqlite3OsFileControl(tls, pFd, int32(SQLITE_FCNTL_OVERWRITE), bp+72)
		if rc == int32(SQLITE_NOTFOUND) {
			rc = SQLITE_OK
		}
		if rc != 0 {
			goto copy_finished
		}
	}
	/* Set up an sqlite3_backup object. sqlite3_backup.pDestDb must be set
	 ** to 0. This is used by the implementations of sqlite3_backup_step()
	 ** and sqlite3_backup_finish() to detect that they are being called
	 ** from this function, not directly by the user.
	 */
	libc.Xmemset(tls, bp, 0, uint64(72))
	(**(**Tsqlite3_backup)(__ccgo_up(bp))).FpSrcDb = (*TBtree)(unsafe.Pointer(pFrom)).Fdb
	(**(**Tsqlite3_backup)(__ccgo_up(bp))).FpSrc = pFrom
	(**(**Tsqlite3_backup)(__ccgo_up(bp))).FpDest = pTo
	(**(**Tsqlite3_backup)(__ccgo_up(bp))).FiNext = uint32(1)
	/* 0x7FFFFFFF is the hard limit for the number of pages in a database
	 ** file. By passing this as the number of pages to copy to
	 ** sqlite3_backup_step(), we can guarantee that the copy finishes
	 ** within a single call (unless an error occurs). The assert() statement
	 ** checks this assumption - (p->rc) should be set to either SQLITE_DONE
	 ** or an error code.  */
	Xsqlite3_backup_step(tls, bp, int32(0x7FFFFFFF))
	rc = Xsqlite3_backup_finish(tls, bp)
	if rc == SQLITE_OK {
		v1 = (*TBtree)(unsafe.Pointer(pTo)).FpBt + 40
		*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) & ^libc.Int32FromInt32(BTS_PAGESIZE_FIXED))
	} else {
		_sqlite3PagerClearCache(tls, _sqlite3BtreePager(tls, (**(**Tsqlite3_backup)(__ccgo_up(bp))).FpDest))
	}
	goto copy_finished
copy_finished:
	;
	_sqlite3BtreeLeave(tls, pFrom)
	_sqlite3BtreeLeave(tls, pTo)
	return rc
}

/************** End of backup.c **********************************************/
/************** Begin file vdbemem.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 manipulate "Mem" structure.  A "Mem"
** stores a single value in the VDBE.  Mem is an opaque structure visible
** only within the VDBE.  Interface routines refer to a Mem using the
** name sqlite_value
 */
/* #include "sqliteInt.h" */
/* #include "vdbeInt.h" */

/* True if X is a power of two.  0 is considered a power of two here.
** In other words, return true if X has at most one bit set.
 */

// C documentation
//
//	/*
//	** This function is used as part of copying the current row from cursor
//	** pSrc into cursor pDest. If the cursors are open on intkey tables, then
//	** parameter iKey is used as the rowid value when the record is copied
//	** into pDest. Otherwise, the record is copied verbatim.
//	**
//	** This function does not actually write the new value to cursor pDest.
//	** Instead, it creates and populates any required overflow pages and
//	** writes the data for the new cell into the BtShared.pTmpSpace buffer
//	** for the destination database. The size of the cell, in bytes, is left
//	** in BtShared.nPreformatSize. The caller completes the insertion by
//	** calling sqlite3BtreeInsert() with the BTREE_PREFORMAT flag specified.
//	**
//	** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
//	*/
func _sqlite3BtreeTransferRow(tls *libc.TLS, pDest uintptr, pSrc uintptr, iKey Ti64) (r int32) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var aIn, aOut, pBt, pPageOut, pPgnoOut, pSrcPager, v1 uintptr
	var nCopy int32
	var nIn, nOut, nRem Tu32
	var ovflIn TPgno
	var v2 uint32
	var _ /* pNew at bp+24 */ uintptr
	var _ /* pPageIn at bp+8 */ uintptr
	var _ /* pgnoNew at bp+16 */ TPgno
	var _ /* rc at bp+0 */ int32
	_, _, _, _, _, _, _, _, _, _, _, _, _ = aIn, aOut, nCopy, nIn, nOut, nRem, ovflIn, pBt, pPageOut, pPgnoOut, pSrcPager, v1, v2
	pBt = (*TBtCursor)(unsafe.Pointer(pDest)).FpBt
	aOut = (*TBtShared)(unsafe.Pointer(pBt)).FpTmpSpace /* Bytes of data still to copy */
	_getCellInfo(tls, pSrc)
	if (*TBtCursor)(unsafe.Pointer(pSrc)).Finfo.FnPayload < uint32(0x80) {
		v1 = aOut
		aOut = aOut + 1
		**(**Tu8)(__ccgo_up(v1)) = uint8((*TBtCursor)(unsafe.Pointer(pSrc)).Finfo.FnPayload)
	} else {
		aOut = aOut + uintptr(_sqlite3PutVarint(tls, aOut, uint64((*TBtCursor)(unsafe.Pointer(pSrc)).Finfo.FnPayload)))
	}
	if (*TBtCursor)(unsafe.Pointer(pDest)).FpKeyInfo == uintptr(0) {
		aOut = aOut + uintptr(_sqlite3PutVarint(tls, aOut, libc.Uint64FromInt64(iKey)))
	}
	nIn = uint32((*TBtCursor)(unsafe.Pointer(pSrc)).Finfo.FnLocal)
	aIn = (*TBtCursor)(unsafe.Pointer(pSrc)).Finfo.FpPayload
	if aIn+uintptr(nIn) > (*TMemPage)(unsafe.Pointer((*TBtCursor)(unsafe.Pointer(pSrc)).FpPage)).FaDataEnd {
		return _sqlite3CorruptError(tls, int32(82878))
	}
	nRem = (*TBtCursor)(unsafe.Pointer(pSrc)).Finfo.FnPayload
	if nIn == nRem && nIn < uint32((*TMemPage)(unsafe.Pointer((*TBtCursor)(unsafe.Pointer(pDest)).FpPage)).FmaxLocal) {
		libc.Xmemcpy(tls, aOut, aIn, uint64(nIn))
		(*TBtShared)(unsafe.Pointer(pBt)).FnPreformatSize = libc.Int32FromUint32(nIn + libc.Uint32FromInt32(int32(int64(aOut)-int64((*TBtShared)(unsafe.Pointer(pBt)).FpTmpSpace))))
		return SQLITE_OK
	} else {
		**(**int32)(__ccgo_up(bp)) = SQLITE_OK
		pSrcPager = (*TBtShared)(unsafe.Pointer((*TBtCursor)(unsafe.Pointer(pSrc)).FpBt)).FpPager
		pPgnoOut = uintptr(0)
		ovflIn = uint32(0)
		**(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0)
		pPageOut = uintptr(0) /* Size of output buffer aOut[] */
		nOut = libc.Uint32FromInt32(_btreePayloadToLocal(tls, (*TBtCursor)(unsafe.Pointer(pDest)).FpPage, libc.Int64FromUint32((*TBtCursor)(unsafe.Pointer(pSrc)).Finfo.FnPayload)))
		(*TBtShared)(unsafe.Pointer(pBt)).FnPreformatSize = libc.Int32FromUint32(nOut) + int32(int64(aOut)-int64((*TBtShared)(unsafe.Pointer(pBt)).FpTmpSpace))
		if nOut < (*TBtCursor)(unsafe.Pointer(pSrc)).Finfo.FnPayload {
			pPgnoOut = aOut + uintptr(nOut)
			**(**int32)(__ccgo_up(pBt + 144)) += int32(4)
		}
		if nRem > nIn {
			if aIn+uintptr(nIn)+uintptr(4) > (*TMemPage)(unsafe.Pointer((*TBtCursor)(unsafe.Pointer(pSrc)).FpPage)).FaDataEnd {
				return _sqlite3CorruptError(tls, int32(82903))
			}
			ovflIn = _sqlite3Get4byte(tls, (*TBtCursor)(unsafe.Pointer(pSrc)).Finfo.FpPayload+uintptr(nIn))
		}
		for cond := true; cond; cond = nRem > uint32(0) && **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
			nRem = nRem - nOut
			for cond := true; cond; cond = **(**int32)(__ccgo_up(bp)) == SQLITE_OK && nOut > uint32(0) {
				if nIn > uint32(0) {
					if nOut < nIn {
						v2 = nOut
					} else {
						v2 = nIn
					}
					nCopy = libc.Int32FromUint32(v2)
					libc.Xmemcpy(tls, aOut, aIn, libc.Uint64FromInt32(nCopy))
					nOut = nOut - libc.Uint32FromInt32(nCopy)
					nIn = nIn - libc.Uint32FromInt32(nCopy)
					aOut = aOut + uintptr(nCopy)
					aIn = aIn + uintptr(nCopy)
				}
				if nOut > uint32(0) {
					_sqlite3PagerUnref(tls, **(**uintptr)(__ccgo_up(bp + 8)))
					**(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0)
					**(**int32)(__ccgo_up(bp)) = _sqlite3PagerGet(tls, pSrcPager, ovflIn, bp+8, int32(PAGER_GET_READONLY))
					if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
						aIn = _sqlite3PagerGetData(tls, **(**uintptr)(__ccgo_up(bp + 8)))
						ovflIn = _sqlite3Get4byte(tls, aIn)
						aIn = aIn + uintptr(4)
						nIn = (*TBtShared)(unsafe.Pointer((*TBtCursor)(unsafe.Pointer(pSrc)).FpBt)).FusableSize - uint32(4)
					}
				}
			}
			if **(**int32)(__ccgo_up(bp)) == SQLITE_OK && nRem > uint32(0) && pPgnoOut != 0 {
				**(**TPgno)(__ccgo_up(bp + 16)) = uint32(0) /* Prevent harmless static-analyzer warning */
				**(**uintptr)(__ccgo_up(bp + 24)) = uintptr(0)
				**(**int32)(__ccgo_up(bp)) = _allocateBtreePage(tls, pBt, bp+24, bp+16, uint32(0), uint8(0))
				_sqlite3Put4byte(tls, pPgnoOut, **(**TPgno)(__ccgo_up(bp + 16)))
				if (*TBtShared)(unsafe.Pointer(pBt)).FautoVacuum != 0 && pPageOut != 0 {
					_ptrmapPut(tls, pBt, **(**TPgno)(__ccgo_up(bp + 16)), uint8(PTRMAP_OVERFLOW2), (*TMemPage)(unsafe.Pointer(pPageOut)).Fpgno, bp)
				}
				_releasePage(tls, pPageOut)
				pPageOut = **(**uintptr)(__ccgo_up(bp + 24))
				if pPageOut != 0 {
					pPgnoOut = (*TMemPage)(unsafe.Pointer(pPageOut)).FaData
					_sqlite3Put4byte(tls, pPgnoOut, uint32(0))
					aOut = pPgnoOut + 4
					if (*TBtShared)(unsafe.Pointer(pBt)).FusableSize-uint32(4) < nRem {
						v2 = (*TBtShared)(unsafe.Pointer(pBt)).FusableSize - uint32(4)
					} else {
						v2 = nRem
					}
					nOut = v2
				}
			}
		}
		_releasePage(tls, pPageOut)
		_sqlite3PagerUnref(tls, **(**uintptr)(__ccgo_up(bp + 8)))
		return **(**int32)(__ccgo_up(bp))
	}
	return r
}

// C documentation
//
//	/*
//	** Set the collating sequence name for a column.
//	*/
func _sqlite3ColumnSetColl(tls *libc.TLS, db uintptr, pCol uintptr, zColl uintptr) {
	var n, nColl Ti64
	var zNew, v1 uintptr
	_, _, _, _ = n, nColl, zNew, v1
	n = int64(_sqlite3Strlen30(tls, (*TColumn)(unsafe.Pointer(pCol)).FzCnName) + int32(1))
	if libc.Int32FromUint16((*TColumn)(unsafe.Pointer(pCol)).FcolFlags)&int32(COLFLAG_HASTYPE) != 0 {
		n = n + int64(_sqlite3Strlen30(tls, (*TColumn)(unsafe.Pointer(pCol)).FzCnName+uintptr(n))+int32(1))
	}
	nColl = int64(_sqlite3Strlen30(tls, zColl) + int32(1))
	zNew = _sqlite3DbRealloc(tls, db, (*TColumn)(unsafe.Pointer(pCol)).FzCnName, libc.Uint64FromInt64(nColl+n))
	if zNew != 0 {
		(*TColumn)(unsafe.Pointer(pCol)).FzCnName = zNew
		libc.Xmemcpy(tls, (*TColumn)(unsafe.Pointer(pCol)).FzCnName+uintptr(n), zColl, libc.Uint64FromInt64(nColl))
		v1 = pCol + 14
		*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) | libc.Int32FromInt32(COLFLAG_HASCOLL))
	}
}

// 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(128)
	defer tls.Free(128)
	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.Int32FromUint64(libc.Uint64FromInt64(128)/libc.Uint64FromInt64(8)) || aDyn != 0 && nArg == libc.Int32FromUint64(libc.Uint64FromInt32(_sqlite3MallocSize(tls, aDyn))/libc.Uint64FromInt64(8)) {
				/* The aArg[] array needs to grow. */
				pNew = _sqlite3Malloc(tls, uint64(libc.Uint64FromInt32(nArg)*uint64(8)*uint64(2)))
				if pNew != 0 {
					libc.Xmemcpy(tls, pNew, aArg, libc.Uint64FromInt32(nArg)*uint64(8))
					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)*8)) = (*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 + 856
		}
		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
//
//	/*
//	** Fill the Index.aiRowEst[] array with default information - information
//	** to be used when we have not run the ANALYZE command.
//	**
//	** aiRowEst[0] is supposed to contain the number of elements in the index.
//	** Since we do not know, guess 1 million.  aiRowEst[1] is an estimate of the
//	** number of rows in the table that match any particular value of the
//	** first column of the index.  aiRowEst[2] is an estimate of the number
//	** of rows that match any particular combination of the first 2 columns
//	** of the index.  And so forth.  It must always be the case that
//	*
//	**           aiRowEst[N]<=aiRowEst[N-1]
//	**           aiRowEst[N]>=1
//	**
//	** Apart from that, we have little to go on besides intuition as to
//	** how aiRowEst[] should be initialized.  The numbers generated here
//	** are based on typical values found in actual indices.
//	*/
func _sqlite3DefaultRowEst(tls *libc.TLS, pIdx uintptr) {
	var a uintptr
	var i, nCopy, v1 int32
	var x, v2 TLogEst
	_, _, _, _, _, _ = a, i, nCopy, x, v1, v2
	a = (*TIndex)(unsafe.Pointer(pIdx)).FaiRowLogEst
	if libc.Int32FromUint64(libc.Uint64FromInt64(10)/libc.Uint64FromInt64(2)) < libc.Int32FromUint16((*TIndex)(unsafe.Pointer(pIdx)).FnKeyCol) {
		v1 = libc.Int32FromUint64(libc.Uint64FromInt64(10) / libc.Uint64FromInt64(2))
	} else {
		v1 = libc.Int32FromUint16((*TIndex)(unsafe.Pointer(pIdx)).FnKeyCol)
	}
	nCopy = v1
	/* Indexes with default row estimates should not have stat1 data */
	/* Set the first entry (number of rows in the index) to the estimated
	 ** number of rows in the table, or half the number of rows in the table
	 ** for a partial index.
	 **
	 ** 2020-05-27:  If some of the stat data is coming from the sqlite_stat1
	 ** table but other parts we are having to guess at, then do not let the
	 ** estimated number of rows in the table be less than 1000 (LogEst 99).
	 ** Failure to do this can cause the indexes for which we do not have
	 ** stat1 data to be ignored by the query planner.
	 */
	x = (*TTable)(unsafe.Pointer((*TIndex)(unsafe.Pointer(pIdx)).FpTable)).FnRowLogEst
	if int32(x) < int32(99) {
		v2 = libc.Int16FromInt32(99)
		x = v2
		(*TTable)(unsafe.Pointer((*TIndex)(unsafe.Pointer(pIdx)).FpTable)).FnRowLogEst = v2
	}
	if (*TIndex)(unsafe.Pointer(pIdx)).FpPartIdxWhere != uintptr(0) {
		x = int16(int32(x) - libc.Int32FromInt32(10))
	}
	**(**TLogEst)(__ccgo_up(a)) = x
	/* Estimate that a[1] is 10, a[2] is 9, a[3] is 8, a[4] is 7, a[5] is
	 ** 6 and each subsequent value (if any) is 5.  */
	libc.Xmemcpy(tls, a+1*2, uintptr(unsafe.Pointer(&_aVal)), libc.Uint64FromInt32(nCopy)*uint64(2))
	i = nCopy + int32(1)
	for {
		if !(i <= libc.Int32FromUint16((*TIndex)(unsafe.Pointer(pIdx)).FnKeyCol)) {
			break
		}
		**(**TLogEst)(__ccgo_up(a + uintptr(i)*2)) = int16(23)
		goto _3
	_3:
		;
		i = i + 1
	}
	if libc.Int32FromUint8((*TIndex)(unsafe.Pointer(pIdx)).FonError) != OE_None {
		**(**TLogEst)(__ccgo_up(a + uintptr((*TIndex)(unsafe.Pointer(pIdx)).FnKeyCol)*2)) = 0
	}
}

// C documentation
//
//	/*
//	** Return TRUE if expression pExpr is able to return a subtype.
//	**
//	** A TRUE return does not guarantee that a subtype will be returned.
//	** It only indicates that a subtype return is possible.  False positives
//	** are acceptable as they only disable an optimization.  False negatives,
//	** on the other hand, can lead to incorrect answers.
//	*/
func _sqlite3ExprCanReturnSubtype(tls *libc.TLS, pParse uintptr, pExpr uintptr) (r int32) {
	bp := tls.Alloc(48)
	defer tls.Free(48)
	var _ /* w at bp+0 */ TWalker
	libc.Xmemset(tls, bp, 0, uint64(48))
	(**(**TWalker)(__ccgo_up(bp))).FpParse = pParse
	(**(**TWalker)(__ccgo_up(bp))).FxExprCallback = __ccgo_fp(_exprNodeCanReturnSubtype)
	_sqlite3WalkExpr(tls, bp, pExpr)
	return libc.Int32FromUint16((**(**TWalker)(__ccgo_up(bp))).FeCode)
}

// C documentation
//
//	/*
//	** Allocate an expression for a 32-bit signed integer literal.
//	*/
func _sqlite3ExprInt32(tls *libc.TLS, db uintptr, iVal int32) (r uintptr) {
	var pNew uintptr
	var v1 int32
	_, _ = pNew, v1
	pNew = _sqlite3DbMallocRawNN(tls, db, uint64(72))
	if pNew != 0 {
		libc.Xmemset(tls, pNew, 0, uint64(72))
		(*TExpr)(unsafe.Pointer(pNew)).Fop = uint8(TK_INTEGER)
		(*TExpr)(unsafe.Pointer(pNew)).FiAgg = int16(-int32(1))
		if iVal != 0 {
			v1 = int32(EP_IsTrue)
		} else {
			v1 = int32(EP_IsFalse)
		}
		(*TExpr)(unsafe.Pointer(pNew)).Fflags = libc.Uint32FromInt32(libc.Int32FromInt32(EP_IntValue) | libc.Int32FromInt32(EP_Leaf) | v1)
		*(*int32)(unsafe.Pointer(&(*TExpr)(unsafe.Pointer(pNew)).Fu)) = iVal
		(*TExpr)(unsafe.Pointer(pNew)).FnHeight = int32(1)
	}
	return pNew
}

// C documentation
//
//	/*
//	** Make arrangements to invoke OP_Null on a range of registers
//	** during initialization.
//	*/
func _sqlite3ExprNullRegisterRange(tls *libc.TLS, pParse uintptr, iReg int32, nReg int32) {
	bp := tls.Alloc(80)
	defer tls.Free(80)
	var okConstFactor Tu8
	var _ /* t at bp+0 */ TExpr
	_ = okConstFactor
	okConstFactor = libc.Uint8FromInt32(int32(Tbft(*(*uint16)(unsafe.Pointer(pParse + 40)) & 0x80 >> 7)))
	libc.Xmemset(tls, bp, 0, uint64(72))
	(**(**TExpr)(__ccgo_up(bp))).Fop = uint8(TK_NULLS)
	*(*int32)(unsafe.Pointer(bp + 64)) = nReg
	libc.SetBitFieldPtr16Uint32(pParse+40, libc.Uint32FromInt32(1), 7, 0x80)
	_sqlite3ExprCodeRunJustOnce(tls, pParse, bp, iReg)
	libc.SetBitFieldPtr16Uint32(pParse+40, uint32(okConstFactor), 7, 0x80)
}

// C documentation
//
//	/*
//	** pExpr is a CHECK constraint on a row that is being UPDATE-ed.  The
//	** only columns that are modified by the UPDATE are those for which
//	** aiChng[i]>=0, and also the ROWID is modified if chngRowid is true.
//	**
//	** Return true if CHECK constraint pExpr uses any of the
//	** changing columns (or the rowid if it is changing).  In other words,
//	** return true if this CHECK constraint must be validated for
//	** the new row in the UPDATE statement.
//	**
//	** 2018-09-15: pExpr might also be an expression for an index-on-expressions.
//	** The operation of this routine is the same - return true if an only if
//	** the expression uses one or more of columns identified by the second and
//	** third arguments.
//	*/
func _sqlite3ExprReferencesUpdatedColumn(tls *libc.TLS, pExpr uintptr, aiChng uintptr, chngRowid int32) (r int32) {
	bp := tls.Alloc(48)
	defer tls.Free(48)
	var v1 uintptr
	var _ /* w at bp+0 */ TWalker
	_ = v1
	libc.Xmemset(tls, bp, 0, uint64(48))
	(**(**TWalker)(__ccgo_up(bp))).FeCode = uint16(0)
	(**(**TWalker)(__ccgo_up(bp))).FxExprCallback = __ccgo_fp(_checkConstraintExprNode)
	*(*uintptr)(unsafe.Pointer(bp + 40)) = aiChng
	_sqlite3WalkExpr(tls, bp, pExpr)
	if !(chngRowid != 0) {
		v1 = bp + 36
		*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) & ^libc.Int32FromInt32(CKCNSTRNT_ROWID))
	}
	return libc.BoolInt32(libc.Int32FromUint16((**(**TWalker)(__ccgo_up(bp))).FeCode) != 0)
}

// C documentation
//
//	/*
//	** Return an IEEE754 floating point value that approximates d*pow(10,p).
//	**
//	** The (current) algorithm is adapted from the work of Ross Cox at
//	** https://github.com/rsc/fpfmt
//	*/
func _sqlite3Fp10Convert2(tls *libc.TLS, d Tu64, p int32) (r float64) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var adj, b, e, lp, s int32
	var hi, pwr10h, sticky, u, x Tu64
	var mid1, mid2 Tu32
	var _ /* lo at bp+8 */ Tu64
	var _ /* m at bp+16 */ Tu64
	var _ /* pwr10l at bp+0 */ Tu32
	var _ /* r at bp+24 */ float64
	_, _, _, _, _, _, _, _, _, _, _, _ = adj, b, e, hi, lp, mid1, mid2, pwr10h, s, sticky, u, x
	if p < -int32(348) {
		return float64(0)
	}
	if p > +libc.Int32FromInt32(347) {
		return float64(libc.X__builtin_inff(tls))
	}
	b = int32(64) - _countLeadingZeros(tls, d)
	lp = _pwr10to2(tls, p)
	e = int32(53) - b - lp
	if e > int32(1074) {
		if e >= int32(1130) {
			return float64(0)
		}
		e = int32(1074)
	}
	s = -(e - (int32(64) - b) + lp + int32(3))
	pwr10h = _powerOfTen(tls, p, bp)
	if **(**Tu32)(__ccgo_up(bp)) != uint32(0) {
		pwr10h = pwr10h + 1
		**(**Tu32)(__ccgo_up(bp)) = ^**(**Tu32)(__ccgo_up(bp))
	}
	x = d << (int32(64) - b)
	hi = _sqlite3Multiply128(tls, x, pwr10h, bp+8)
	mid1 = uint32(**(**Tu64)(__ccgo_up(bp + 8)) >> int32(32))
	sticky = uint64(1)
	if hi&(libc.Uint64FromInt32(1)<<s-uint64(1)) == uint64(0) {
		mid2 = uint32(_sqlite3Multiply128(tls, x, uint64(**(**Tu32)(__ccgo_up(bp)))<<int32(32), bp+8) >> int32(32))
		sticky = libc.BoolUint64(mid1-mid2 > libc.Uint32FromInt32(1))
		hi = hi - libc.BoolUint64(mid1 < mid2)
	}
	u = hi>>s | sticky
	adj = libc.BoolInt32(u >= libc.Uint64FromInt32(1)<<libc.Int32FromInt32(55)-libc.Uint64FromInt32(2))
	if adj != 0 {
		u = u>>adj | u&uint64(1)
		e = e - adj
	}
	**(**Tu64)(__ccgo_up(bp + 16)) = (u + uint64(1) + u>>libc.Int32FromInt32(2)&uint64(1)) >> int32(2)
	if e <= -int32(972) {
		return float64(libc.X__builtin_inff(tls))
	}
	if **(**Tu64)(__ccgo_up(bp + 16))&(libc.Uint64FromInt32(1)<<libc.Int32FromInt32(52)) != uint64(0) {
		**(**Tu64)(__ccgo_up(bp + 16)) = **(**Tu64)(__ccgo_up(bp + 16)) & ^(libc.Uint64FromInt32(1)<<libc.Int32FromInt32(52)) | libc.Uint64FromInt32(libc.Int32FromInt32(1075)-e)<<libc.Int32FromInt32(52)
	}
	libc.Xmemcpy(tls, bp+24, bp+16, uint64(8))
	return **(**float64)(__ccgo_up(bp + 24))
}

// C documentation
//
//	/*
//	** Append buffer nData/pData to buffer pBuf. If an OOM error occurs, set
//	** the error code in p. If an error has already occurred when this function
//	** is called, it is a no-op.
//	*/
func _sqlite3Fts5BufferAppendBlob(tls *libc.TLS, pRc uintptr, pBuf uintptr, nData Tu32, pData uintptr) {
	var v1 int32
	var v2 uintptr
	_, _ = v1, v2
	if nData != 0 {
		if libc.Uint32FromInt32((*TFts5Buffer)(unsafe.Pointer(pBuf)).Fn)+nData <= libc.Uint32FromInt32((*TFts5Buffer)(unsafe.Pointer(pBuf)).FnSpace) {
			v1 = 0
		} else {
			v1 = _sqlite3Fts5BufferSize(tls, pRc, pBuf, nData+libc.Uint32FromInt32((*TFts5Buffer)(unsafe.Pointer(pBuf)).Fn))
		}
		if v1 != 0 {
			return
		}
		libc.Xmemcpy(tls, (*TFts5Buffer)(unsafe.Pointer(pBuf)).Fp+uintptr((*TFts5Buffer)(unsafe.Pointer(pBuf)).Fn), pData, uint64(nData))
		v2 = pBuf + 8
		*(*int32)(unsafe.Pointer(v2)) = int32(uint32(*(*int32)(unsafe.Pointer(v2))) + nData)
	}
}

func _sqlite3Fts5ExprAnd(tls *libc.TLS, pp1 uintptr, p2 uintptr) (r int32) {
	bp := tls.Alloc(48)
	defer tls.Free(48)
	var ap, p1 uintptr
	var i, nPhrase int32
	var _ /* sParse at bp+0 */ TFts5Parse
	_, _, _, _ = ap, i, nPhrase, p1
	libc.Xmemset(tls, bp, 0, uint64(48))
	if **(**uintptr)(__ccgo_up(pp1)) != 0 && p2 != 0 {
		p1 = **(**uintptr)(__ccgo_up(pp1))
		nPhrase = (*TFts5Expr)(unsafe.Pointer(p1)).FnPhrase + (*TFts5Expr)(unsafe.Pointer(p2)).FnPhrase
		(*TFts5Expr)(unsafe.Pointer(p1)).FpRoot = _sqlite3Fts5ParseNode(tls, bp, int32(FTS5_AND), (*TFts5Expr)(unsafe.Pointer(p1)).FpRoot, (*TFts5Expr)(unsafe.Pointer(p2)).FpRoot, uintptr(0))
		(*TFts5Expr)(unsafe.Pointer(p2)).FpRoot = uintptr(0)
		if (**(**TFts5Parse)(__ccgo_up(bp))).Frc == SQLITE_OK {
			ap = Xsqlite3_realloc64(tls, (*TFts5Expr)(unsafe.Pointer(p1)).FapExprPhrase, uint64(libc.Uint64FromInt32(nPhrase)*uint64(8)))
			if ap == uintptr(0) {
				(**(**TFts5Parse)(__ccgo_up(bp))).Frc = int32(SQLITE_NOMEM)
			} else {
				libc.Xmemmove(tls, ap+uintptr((*TFts5Expr)(unsafe.Pointer(p2)).FnPhrase)*8, ap, libc.Uint64FromInt32((*TFts5Expr)(unsafe.Pointer(p1)).FnPhrase)*uint64(8))
				i = 0
				for {
					if !(i < (*TFts5Expr)(unsafe.Pointer(p2)).FnPhrase) {
						break
					}
					**(**uintptr)(__ccgo_up(ap + uintptr(i)*8)) = **(**uintptr)(__ccgo_up((*TFts5Expr)(unsafe.Pointer(p2)).FapExprPhrase + uintptr(i)*8))
					goto _1
				_1:
					;
					i = i + 1
				}
				(*TFts5Expr)(unsafe.Pointer(p1)).FnPhrase = nPhrase
				(*TFts5Expr)(unsafe.Pointer(p1)).FapExprPhrase = ap
			}
		}
		Xsqlite3_free(tls, (*TFts5Expr)(unsafe.Pointer(p2)).FapExprPhrase)
		Xsqlite3_free(tls, p2)
	} else {
		if p2 != 0 {
			**(**uintptr)(__ccgo_up(pp1)) = p2
		}
	}
	return (**(**TFts5Parse)(__ccgo_up(bp))).Frc
}

// C documentation
//
//	/*
//	** Clear the position lists associated with all phrases in the expression
//	** passed as the first argument. Argument bLive is true if the expression
//	** might be pointing to a real entry, otherwise it has just been reset.
//	**
//	** At present this function is only used for detail=col and detail=none
//	** fts5 tables. This implies that all phrases must be at most 1 token
//	** in size, as phrase matches are not supported without detail=full.
//	*/
func _sqlite3Fts5ExprClearPoslists(tls *libc.TLS, pExpr uintptr, bLive int32) (r uintptr) {
	var i int32
	var pBuf, pNode, pRet uintptr
	_, _, _, _ = i, pBuf, pNode, pRet
	pRet = Xsqlite3_malloc64(tls, uint64(uint64(16)*libc.Uint64FromInt32((*TFts5Expr)(unsafe.Pointer(pExpr)).FnPhrase)))
	if pRet != 0 {
		libc.Xmemset(tls, pRet, 0, uint64(16)*libc.Uint64FromInt32((*TFts5Expr)(unsafe.Pointer(pExpr)).FnPhrase))
		i = 0
		for {
			if !(i < (*TFts5Expr)(unsafe.Pointer(pExpr)).FnPhrase) {
				break
			}
			pBuf = **(**uintptr)(__ccgo_up((*TFts5Expr)(unsafe.Pointer(pExpr)).FapExprPhrase + uintptr(i)*8)) + 8
			pNode = (*TFts5ExprPhrase)(unsafe.Pointer(**(**uintptr)(__ccgo_up((*TFts5Expr)(unsafe.Pointer(pExpr)).FapExprPhrase + uintptr(i)*8)))).FpNode
			if bLive != 0 && ((*TFts5Buffer)(unsafe.Pointer(pBuf)).Fn == 0 || (*TFts5ExprNode)(unsafe.Pointer(pNode)).FiRowid != (*TFts5ExprNode)(unsafe.Pointer((*TFts5Expr)(unsafe.Pointer(pExpr)).FpRoot)).FiRowid || (*TFts5ExprNode)(unsafe.Pointer(pNode)).FbEof != 0) {
				(**(**TFts5PoslistPopulator)(__ccgo_up(pRet + uintptr(i)*16))).FbMiss = int32(1)
			} else {
				(*TFts5Buffer)(unsafe.Pointer(pBuf)).Fn = 0
			}
			goto _1
		_1:
			;
			i = i + 1
		}
	}
	return pRet
}

// 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(32)
	defer tls.Free(32)
	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+8 */ 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 + 8)) = 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)*8))
		pNew = _sqlite3Fts5MallocZero(tls, bp, int64(40))
	}
	if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
		(*TFts5Expr)(unsafe.Pointer(pNew)).FapExprPhrase = _sqlite3Fts5MallocZero(tls, bp, int64(8))
	}
	if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
		(*TFts5Expr)(unsafe.Pointer(pNew)).FpRoot = _sqlite3Fts5MallocZero(tls, bp, libc.Int64FromUint64(uint64(libc.UintptrFromInt32(0)+48)+libc.Uint64FromInt32(libc.Int32FromInt32(1))*libc.Uint64FromInt64(8)))
	}
	if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
		(*TFts5ExprNode)(unsafe.Pointer((*TFts5Expr)(unsafe.Pointer(pNew)).FpRoot)).FpNear = _sqlite3Fts5MallocZero(tls, bp, libc.Int64FromUint64(uint64(libc.UintptrFromInt32(0)+24)+libc.Uint64FromInt32(libc.Int32FromInt32(2))*libc.Uint64FromInt64(8)))
	}
	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.Int64FromUint64(libc.Uint64FromInt64(8) * libc.Uint64FromInt32(((*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.Uint64FromInt64(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 + 8))).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 + 32 + uintptr(i)*40
				for {
					if !(p != 0 && **(**int32)(__ccgo_up(bp)) == SQLITE_OK) {
						break
					}
					**(**int32)(__ccgo_up(bp)) = _fts5ParseTokenize(tls, bp+8, 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 + 8))).FpPhrase + 32 + uintptr(i)*40))).FbPrefix = (*(*TFts5ExprTerm)(unsafe.Pointer(pOrig + 32 + uintptr(i)*40))).FbPrefix
					(*(*TFts5ExprTerm)(unsafe.Pointer((**(**TTokenCtx)(__ccgo_up(bp + 8))).FpPhrase + 32 + uintptr(i)*40))).FbFirst = (*(*TFts5ExprTerm)(unsafe.Pointer(pOrig + 32 + uintptr(i)*40))).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 + 8))).FpPhrase = _sqlite3Fts5MallocZero(tls, bp, libc.Int64FromUint64(uint64(libc.UintptrFromInt32(0)+32)+libc.Uint64FromInt32(libc.Int32FromInt32(1))*libc.Uint64FromInt64(40)))
		}
	}
	if **(**int32)(__ccgo_up(bp)) == SQLITE_OK && (**(**TTokenCtx)(__ccgo_up(bp + 8))).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 + 8))).FpPhrase
		*(*uintptr)(unsafe.Pointer((*TFts5ExprNode)(unsafe.Pointer((*TFts5Expr)(unsafe.Pointer(pNew)).FpRoot)).FpNear + 24)) = (**(**TTokenCtx)(__ccgo_up(bp + 8))).FpPhrase
		(*TFts5ExprNearset)(unsafe.Pointer((*TFts5ExprNode)(unsafe.Pointer((*TFts5Expr)(unsafe.Pointer(pNew)).FpRoot)).FpNear)).FnPhrase = int32(1)
		(*TFts5ExprPhrase)(unsafe.Pointer((**(**TTokenCtx)(__ccgo_up(bp + 8))).FpPhrase)).FpNode = (*TFts5Expr)(unsafe.Pointer(pNew)).FpRoot
		if (*TFts5ExprPhrase)(unsafe.Pointer(pOrig)).FnTerm == int32(1) && (*(*TFts5ExprTerm)(unsafe.Pointer(pOrig + 32))).FpSynonym == uintptr(0) && libc.Int32FromUint8((*(*TFts5ExprTerm)(unsafe.Pointer(pOrig + 32))).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 + 8))).FpPhrase)
		pNew = uintptr(0)
	}
	**(**uintptr)(__ccgo_up(ppNew)) = pNew
	return **(**int32)(__ccgo_up(bp))
}

func _sqlite3Fts5ExprNew(tls *libc.TLS, pConfig uintptr, bPhraseToAnd int32, iCol int32, zExpr uintptr, ppNew uintptr, pzErr uintptr) (r int32) {
	bp := tls.Alloc(80)
	defer tls.Free(80)
	var n, t int32
	var pColset, pEngine, pNew, v1 uintptr
	var _ /* sParse at bp+0 */ TFts5Parse
	var _ /* token at bp+48 */ TFts5Token
	var _ /* z at bp+64 */ uintptr
	_, _, _, _, _, _ = n, pColset, pEngine, pNew, t, v1
	**(**uintptr)(__ccgo_up(bp + 64)) = zExpr
	**(**uintptr)(__ccgo_up(ppNew)) = uintptr(0)
	**(**uintptr)(__ccgo_up(pzErr)) = uintptr(0)
	libc.Xmemset(tls, bp, 0, uint64(48))
	(**(**TFts5Parse)(__ccgo_up(bp))).FbPhraseToAnd = bPhraseToAnd
	pEngine = _sqlite3Fts5ParserAlloc(tls, __ccgo_fp(_fts5ParseAlloc))
	if pEngine == uintptr(0) {
		return int32(SQLITE_NOMEM)
	}
	(**(**TFts5Parse)(__ccgo_up(bp))).FpConfig = pConfig
	for cond := true; cond; cond = (**(**TFts5Parse)(__ccgo_up(bp))).Frc == SQLITE_OK && t != FTS5_EOF {
		t = _fts5ExprGetToken(tls, bp, bp+64, bp+48)
		_sqlite3Fts5Parser(tls, pEngine, t, **(**TFts5Token)(__ccgo_up(bp + 48)), bp)
	}
	_sqlite3Fts5ParserFree(tls, pEngine, __ccgo_fp(_fts5ParseFree))
	/* If the LHS of the MATCH expression was a user column, apply the
	 ** implicit column-filter.  */
	if (**(**TFts5Parse)(__ccgo_up(bp))).Frc == SQLITE_OK && iCol < (*TFts5Config)(unsafe.Pointer(pConfig)).FnCol {
		n = libc.Int32FromUint64(libc.Uint64FromInt64(8) * libc.Uint64FromInt32((libc.Int32FromInt32(1)+libc.Int32FromInt32(2))/libc.Int32FromInt32(2)))
		pColset = _sqlite3Fts5MallocZero(tls, bp+16, int64(n))
		if pColset != 0 {
			(*TFts5Colset)(unsafe.Pointer(pColset)).FnCol = int32(1)
			*(*int32)(unsafe.Pointer(pColset + 4)) = iCol
			_sqlite3Fts5ParseSetColset(tls, bp, (**(**TFts5Parse)(__ccgo_up(bp))).FpExpr, pColset)
		}
	}
	if (**(**TFts5Parse)(__ccgo_up(bp))).Frc == SQLITE_OK {
		v1 = Xsqlite3_malloc64(tls, uint64(40))
		pNew = v1
		**(**uintptr)(__ccgo_up(ppNew)) = v1
		if pNew == uintptr(0) {
			(**(**TFts5Parse)(__ccgo_up(bp))).Frc = int32(SQLITE_NOMEM)
			_sqlite3Fts5ParseNodeFree(tls, (**(**TFts5Parse)(__ccgo_up(bp))).FpExpr)
		} else {
			(*TFts5Expr)(unsafe.Pointer(pNew)).FpRoot = (**(**TFts5Parse)(__ccgo_up(bp))).FpExpr
			(*TFts5Expr)(unsafe.Pointer(pNew)).FpIndex = uintptr(0)
			(*TFts5Expr)(unsafe.Pointer(pNew)).FpConfig = pConfig
			(*TFts5Expr)(unsafe.Pointer(pNew)).FapExprPhrase = (**(**TFts5Parse)(__ccgo_up(bp))).FapPhrase
			(*TFts5Expr)(unsafe.Pointer(pNew)).FnPhrase = (**(**TFts5Parse)(__ccgo_up(bp))).FnPhrase
			(*TFts5Expr)(unsafe.Pointer(pNew)).FbDesc = 0
			(**(**TFts5Parse)(__ccgo_up(bp))).FapPhrase = uintptr(0)
		}
	} else {
		_sqlite3Fts5ParseNodeFree(tls, (**(**TFts5Parse)(__ccgo_up(bp))).FpExpr)
	}
	Xsqlite3_free(tls, (**(**TFts5Parse)(__ccgo_up(bp))).FapPhrase)
	if uintptr(0) == **(**uintptr)(__ccgo_up(pzErr)) {
		**(**uintptr)(__ccgo_up(pzErr)) = (**(**TFts5Parse)(__ccgo_up(bp))).FzErr
	} else {
		Xsqlite3_free(tls, (**(**TFts5Parse)(__ccgo_up(bp))).FzErr)
	}
	return (**(**TFts5Parse)(__ccgo_up(bp))).Frc
}

// C documentation
//
//	/*
//	** Empty (but do not delete) a hash table.
//	*/
func _sqlite3Fts5HashClear(tls *libc.TLS, pHash uintptr) {
	var i int32
	var pNext, pSlot uintptr
	_, _, _ = i, pNext, pSlot
	i = 0
	for {
		if !(i < (*TFts5Hash)(unsafe.Pointer(pHash)).FnSlot) {
			break
		}
		pSlot = **(**uintptr)(__ccgo_up((*TFts5Hash)(unsafe.Pointer(pHash)).FaSlot + uintptr(i)*8))
		for {
			if !(pSlot != 0) {
				break
			}
			pNext = (*TFts5HashEntry)(unsafe.Pointer(pSlot)).FpHashNext
			Xsqlite3_free(tls, pSlot)
			goto _2
		_2:
			;
			pSlot = pNext
		}
		goto _1
	_1:
		;
		i = i + 1
	}
	libc.Xmemset(tls, (*TFts5Hash)(unsafe.Pointer(pHash)).FaSlot, 0, libc.Uint64FromInt32((*TFts5Hash)(unsafe.Pointer(pHash)).FnSlot)*uint64(8))
	(*TFts5Hash)(unsafe.Pointer(pHash)).FnEntry = 0
}

// C documentation
//
//	/*
//	** Allocate a new hash table.
//	*/
func _sqlite3Fts5HashNew(tls *libc.TLS, pConfig uintptr, ppNew uintptr, pnByte uintptr) (r int32) {
	var nByte Tsqlite3_int64
	var pNew, v1 uintptr
	var rc int32
	_, _, _, _ = nByte, pNew, rc, v1
	rc = SQLITE_OK
	v1 = Xsqlite3_malloc64(tls, uint64(40))
	pNew = v1
	**(**uintptr)(__ccgo_up(ppNew)) = v1
	if pNew == uintptr(0) {
		rc = int32(SQLITE_NOMEM)
	} else {
		libc.Xmemset(tls, pNew, 0, uint64(40))
		(*TFts5Hash)(unsafe.Pointer(pNew)).FpnByte = pnByte
		(*TFts5Hash)(unsafe.Pointer(pNew)).FeDetail = (*TFts5Config)(unsafe.Pointer(pConfig)).FeDetail
		(*TFts5Hash)(unsafe.Pointer(pNew)).FnSlot = int32(1024)
		nByte = libc.Int64FromUint64(uint64(8) * libc.Uint64FromInt32((*TFts5Hash)(unsafe.Pointer(pNew)).FnSlot))
		(*TFts5Hash)(unsafe.Pointer(pNew)).FaSlot = Xsqlite3_malloc64(tls, libc.Uint64FromInt64(nByte))
		if (*TFts5Hash)(unsafe.Pointer(pNew)).FaSlot == uintptr(0) {
			Xsqlite3_free(tls, pNew)
			**(**uintptr)(__ccgo_up(ppNew)) = uintptr(0)
			rc = int32(SQLITE_NOMEM)
		} else {
			libc.Xmemset(tls, (*TFts5Hash)(unsafe.Pointer(pNew)).FaSlot, 0, libc.Uint64FromInt64(nByte))
		}
	}
	return rc
}

// C documentation
//
//	/*
//	** Query the hash table for a doclist associated with term pTerm/nTerm.
//	*/
func _sqlite3Fts5HashQuery(tls *libc.TLS, pHash uintptr, nPre int32, pTerm uintptr, nTerm int32, ppOut uintptr, pnDoclist uintptr) (r int32) {
	var iHash uint32
	var nHashPre, nList int32
	var p, pFaux, pRet, zKey, v2 uintptr
	_, _, _, _, _, _, _, _ = iHash, nHashPre, nList, p, pFaux, pRet, zKey, v2
	iHash = _fts5HashKey(tls, (*TFts5Hash)(unsafe.Pointer(pHash)).FnSlot, pTerm, nTerm)
	zKey = uintptr(0)
	p = **(**uintptr)(__ccgo_up((*TFts5Hash)(unsafe.Pointer(pHash)).FaSlot + uintptr(iHash)*8))
	for {
		if !(p != 0) {
			break
		}
		zKey = p + 1*48
		if nTerm == (*TFts5HashEntry)(unsafe.Pointer(p)).FnKey && libc.Xmemcmp(tls, zKey, pTerm, libc.Uint64FromInt32(nTerm)) == 0 {
			break
		}
		goto _1
	_1:
		;
		p = (*TFts5HashEntry)(unsafe.Pointer(p)).FpHashNext
	}
	if p != 0 {
		nHashPre = libc.Int32FromUint64(uint64(48) + libc.Uint64FromInt32(nTerm))
		nList = (*TFts5HashEntry)(unsafe.Pointer(p)).FnData - nHashPre
		v2 = Xsqlite3_malloc64(tls, libc.Uint64FromInt32(nPre+nList+int32(10)))
		**(**uintptr)(__ccgo_up(ppOut)) = v2
		pRet = v2
		if pRet != 0 {
			pFaux = pRet + uintptr(nPre-nHashPre)
			libc.Xmemcpy(tls, pRet+uintptr(nPre), p+uintptr(nHashPre), libc.Uint64FromInt32(nList))
			nList = nList + _fts5HashAddPoslistSize(tls, pHash, p, pFaux)
			**(**int32)(__ccgo_up(pnDoclist)) = nList
		} else {
			**(**int32)(__ccgo_up(pnDoclist)) = 0
			return int32(SQLITE_NOMEM)
		}
	} else {
		**(**uintptr)(__ccgo_up(ppOut)) = uintptr(0)
		**(**int32)(__ccgo_up(pnDoclist)) = 0
	}
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** Read and decode the "averages" record from the database.
//	**
//	** Parameter anSize must point to an array of size nCol, where nCol is
//	** the number of user defined columns in the FTS table.
//	*/
func _sqlite3Fts5IndexGetAverages(tls *libc.TLS, p uintptr, pnRow uintptr, anSize uintptr) (r int32) {
	var i, iCol, nCol int32
	var pData uintptr
	_, _, _, _ = i, iCol, nCol, pData
	nCol = (*TFts5Config)(unsafe.Pointer((*TFts5Index)(unsafe.Pointer(p)).FpConfig)).FnCol
	**(**Ti64)(__ccgo_up(pnRow)) = 0
	libc.Xmemset(tls, anSize, 0, uint64(8)*libc.Uint64FromInt32(nCol))
	pData = _fts5DataRead(tls, p, int64(FTS5_AVERAGES_ROWID))
	if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK && (*TFts5Data)(unsafe.Pointer(pData)).Fnn != 0 {
		i = 0
		i = i + libc.Int32FromUint8(_sqlite3Fts5GetVarint(tls, (*TFts5Data)(unsafe.Pointer(pData)).Fp+uintptr(i), pnRow))
		iCol = 0
		for {
			if !(i < (*TFts5Data)(unsafe.Pointer(pData)).Fnn && iCol < nCol) {
				break
			}
			i = i + libc.Int32FromUint8(_sqlite3Fts5GetVarint(tls, (*TFts5Data)(unsafe.Pointer(pData)).Fp+uintptr(i), anSize+uintptr(iCol)*8))
			goto _1
		_1:
			;
			iCol = iCol + 1
		}
	}
	_fts5DataRelease(tls, pData)
	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(32)
	defer tls.Free(32)
	var bDesc, bTokendata, iIdx, iPrefixIdx, nChar, nIdxChar int32
	var pConfig, pSeg, pStruct uintptr
	var _ /* buf at bp+8 */ 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 + 8)) = TFts5Buffer{}
	/* If the QUERY_SCAN flag is set, all other flags must be clear. */
	if _sqlite3Fts5BufferSize(tls, p+60, bp+8, 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 + 8))).Fp+1, pToken, libc.Uint64FromInt32(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 + 8))).Fp)) = uint8('0')
			**(**uintptr)(__ccgo_up(bp)) = _fts5SetupTokendataIter(tls, p, (**(**TFts5Buffer)(__ccgo_up(bp + 8))).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 + 8))).Fp)) = libc.Uint8FromInt32(libc.Int32FromUint8('0') + iIdx)
				if pStruct != 0 {
					_fts5MultiIterNew(tls, p, pStruct, flags|int32(FTS5INDEX_QUERY_SKIPEMPTY), pColset, (**(**TFts5Buffer)(__ccgo_up(bp + 8))).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 + 8))).Fp, nToken+int32(1), pColset, bp)
				if **(**uintptr)(__ccgo_up(bp)) == uintptr(0) {
				} else {
					_fts5IterSetOutputCb(tls, p+60, **(**uintptr)(__ccgo_up(bp)))
					if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
						pSeg = **(**uintptr)(__ccgo_up(bp)) + 104 + uintptr((**(**TFts5CResult)(__ccgo_up((*TFts5Iter)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FaFirst + 1*4))).FiFirst)*128
						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+8)
	}
	return _fts5IndexReturn(tls, p)
}

func _sqlite3Fts5MallocZero(tls *libc.TLS, pRc uintptr, nByte Tsqlite3_int64) (r uintptr) {
	var pRet uintptr
	_ = pRet
	pRet = uintptr(0)
	if **(**int32)(__ccgo_up(pRc)) == SQLITE_OK {
		pRet = Xsqlite3_malloc64(tls, libc.Uint64FromInt64(nByte))
		if pRet == uintptr(0) {
			if nByte > 0 {
				**(**int32)(__ccgo_up(pRc)) = int32(SQLITE_NOMEM)
			}
		} else {
			libc.Xmemset(tls, pRet, 0, libc.Uint64FromInt64(nByte))
		}
	}
	return pRet
}

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 + 48 + uintptr((*TFts5ExprNode)(unsafe.Pointer(pLeft)).FnChild-int32(1))*8))
		} 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 + 48 + uintptr((*TFts5ExprNode)(unsafe.Pointer(pLeft)).FnChild-int32(1))*8)) = 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)*8
				libc.Xmemmove(tls, ap, ap+1*8, uint64(8)*libc.Uint64FromInt32((*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
//
//	/*
//	** If argument pNear is NULL, then a new Fts5ExprNearset object is allocated
//	** and populated with pPhrase. Or, if pNear is not NULL, phrase pPhrase is
//	** appended to it and the results returned.
//	**
//	** If an OOM error occurs, both the pNear and pPhrase objects are freed and
//	** NULL returned.
//	*/
func _sqlite3Fts5ParseNearset(tls *libc.TLS, pParse uintptr, pNear uintptr, pPhrase uintptr) (r uintptr) {
	var SZALLOC, nNew, v1 int32
	var nByte, nByte1 Tsqlite3_int64
	var pLast, pRet, v2 uintptr
	_, _, _, _, _, _, _, _ = SZALLOC, nByte, nByte1, nNew, pLast, pRet, v1, v2
	SZALLOC = int32(8)
	pRet = uintptr(0)
	if (*TFts5Parse)(unsafe.Pointer(pParse)).Frc == SQLITE_OK {
		if pNear == uintptr(0) {
			nByte = libc.Int64FromUint64(uint64(libc.UintptrFromInt32(0)+24) + libc.Uint64FromInt32(SZALLOC+libc.Int32FromInt32(1))*libc.Uint64FromInt64(8))
			pRet = Xsqlite3_malloc64(tls, libc.Uint64FromInt64(nByte))
			if pRet == uintptr(0) {
				(*TFts5Parse)(unsafe.Pointer(pParse)).Frc = int32(SQLITE_NOMEM)
			} else {
				libc.Xmemset(tls, pRet, 0, libc.Uint64FromInt64(nByte))
			}
		} else {
			if (*TFts5ExprNearset)(unsafe.Pointer(pNear)).FnPhrase%SZALLOC == 0 {
				nNew = (*TFts5ExprNearset)(unsafe.Pointer(pNear)).FnPhrase + SZALLOC
				nByte1 = libc.Int64FromUint64(uint64(libc.UintptrFromInt32(0)+24) + libc.Uint64FromInt32(nNew+libc.Int32FromInt32(1))*libc.Uint64FromInt64(8))
				pRet = Xsqlite3_realloc64(tls, pNear, libc.Uint64FromInt64(nByte1))
				if pRet == uintptr(0) {
					(*TFts5Parse)(unsafe.Pointer(pParse)).Frc = int32(SQLITE_NOMEM)
				}
			} else {
				pRet = pNear
			}
		}
	}
	if pRet == uintptr(0) {
		_sqlite3Fts5ParseNearsetFree(tls, pNear)
		_sqlite3Fts5ParsePhraseFree(tls, pPhrase)
	} else {
		if (*TFts5ExprNearset)(unsafe.Pointer(pRet)).FnPhrase > 0 {
			pLast = *(*uintptr)(unsafe.Pointer(pRet + 24 + uintptr((*TFts5ExprNearset)(unsafe.Pointer(pRet)).FnPhrase-int32(1))*8))
			if (*TFts5ExprPhrase)(unsafe.Pointer(pPhrase)).FnTerm == 0 {
				_fts5ExprPhraseFree(tls, pPhrase)
				(*TFts5ExprNearset)(unsafe.Pointer(pRet)).FnPhrase = (*TFts5ExprNearset)(unsafe.Pointer(pRet)).FnPhrase - 1
				(*TFts5Parse)(unsafe.Pointer(pParse)).FnPhrase = (*TFts5Parse)(unsafe.Pointer(pParse)).FnPhrase - 1
				pPhrase = pLast
			} else {
				if (*TFts5ExprPhrase)(unsafe.Pointer(pLast)).FnTerm == 0 {
					_fts5ExprPhraseFree(tls, pLast)
					**(**uintptr)(__ccgo_up((*TFts5Parse)(unsafe.Pointer(pParse)).FapPhrase + uintptr((*TFts5Parse)(unsafe.Pointer(pParse)).FnPhrase-int32(2))*8)) = pPhrase
					(*TFts5Parse)(unsafe.Pointer(pParse)).FnPhrase = (*TFts5Parse)(unsafe.Pointer(pParse)).FnPhrase - 1
					(*TFts5ExprNearset)(unsafe.Pointer(pRet)).FnPhrase = (*TFts5ExprNearset)(unsafe.Pointer(pRet)).FnPhrase - 1
				}
			}
		}
		v2 = pRet + 16
		v1 = *(*int32)(unsafe.Pointer(v2))
		*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1
		*(*uintptr)(unsafe.Pointer(pRet + 24 + uintptr(v1)*8)) = pPhrase
	}
	return pRet
}

// C documentation
//
//	/*
//	** This function is called by the parser to process a string token. The
//	** string may or may not be quoted. In any case it is tokenized and a
//	** phrase object consisting of all tokens returned.
//	*/
func _sqlite3Fts5ParseTerm(tls *libc.TLS, pParse uintptr, pAppend uintptr, pToken uintptr, bPrefix int32) (r uintptr) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var flags, n, rc, v1 int32
	var pConfig uintptr
	var v3 bool
	var _ /* sCtx at bp+0 */ TTokenCtx
	var _ /* z at bp+24 */ uintptr
	_, _, _, _, _, _ = flags, n, pConfig, rc, v1, v3
	pConfig = (*TFts5Parse)(unsafe.Pointer(pParse)).FpConfig /* Tokenize return code */
	**(**uintptr)(__ccgo_up(bp + 24)) = uintptr(0)
	libc.Xmemset(tls, bp, 0, uint64(24))
	(**(**TTokenCtx)(__ccgo_up(bp))).FpPhrase = pAppend
	(**(**TTokenCtx)(__ccgo_up(bp))).FpConfig = pConfig
	rc = _fts5ParseStringFromToken(tls, pToken, bp+24)
	if rc == SQLITE_OK {
		if bPrefix != 0 {
			v1 = int32(FTS5_TOKENIZE_PREFIX)
		} else {
			v1 = 0
		}
		flags = int32(FTS5_TOKENIZE_QUERY) | v1
		_sqlite3Fts5Dequote(tls, **(**uintptr)(__ccgo_up(bp + 24)))
		n = libc.Int32FromUint64(libc.Xstrlen(tls, **(**uintptr)(__ccgo_up(bp + 24))))
		rc = _sqlite3Fts5Tokenize(tls, pConfig, flags, **(**uintptr)(__ccgo_up(bp + 24)), n, bp, __ccgo_fp(_fts5ParseTokenize))
	}
	Xsqlite3_free(tls, **(**uintptr)(__ccgo_up(bp + 24)))
	if v3 = rc != 0; !v3 {
		v1 = (**(**TTokenCtx)(__ccgo_up(bp))).Frc
		rc = v1
	}
	if v3 || v1 != 0 {
		(*TFts5Parse)(unsafe.Pointer(pParse)).Frc = rc
		_fts5ExprPhraseFree(tls, (**(**TTokenCtx)(__ccgo_up(bp))).FpPhrase)
		(**(**TTokenCtx)(__ccgo_up(bp))).FpPhrase = uintptr(0)
	} else {
		if pAppend == uintptr(0) {
			if _parseGrowPhraseArray(tls, pParse) != 0 {
				_fts5ExprPhraseFree(tls, (**(**TTokenCtx)(__ccgo_up(bp))).FpPhrase)
				return uintptr(0)
			}
			(*TFts5Parse)(unsafe.Pointer(pParse)).FnPhrase = (*TFts5Parse)(unsafe.Pointer(pParse)).FnPhrase + 1
		}
		if (**(**TTokenCtx)(__ccgo_up(bp))).FpPhrase == uintptr(0) {
			/* This happens when parsing a token or quoted phrase that contains
			 ** no token characters at all. (e.g ... MATCH '""'). */
			(**(**TTokenCtx)(__ccgo_up(bp))).FpPhrase = _sqlite3Fts5MallocZero(tls, pParse+16, libc.Int64FromUint64(uint64(libc.UintptrFromInt32(0)+32)+libc.Uint64FromInt32(libc.Int32FromInt32(1))*libc.Uint64FromInt64(40)))
		} else {
			if (*TFts5ExprPhrase)(unsafe.Pointer((**(**TTokenCtx)(__ccgo_up(bp))).FpPhrase)).FnTerm != 0 {
				(*(*TFts5ExprTerm)(unsafe.Pointer((**(**TTokenCtx)(__ccgo_up(bp))).FpPhrase + 32 + uintptr((*TFts5ExprPhrase)(unsafe.Pointer((**(**TTokenCtx)(__ccgo_up(bp))).FpPhrase)).FnTerm-int32(1))*40))).FbPrefix = libc.Uint8FromInt32(bPrefix)
			}
		}
		**(**uintptr)(__ccgo_up((*TFts5Parse)(unsafe.Pointer(pParse)).FapPhrase + uintptr((*TFts5Parse)(unsafe.Pointer(pParse)).FnPhrase-int32(1))*8)) = (**(**TTokenCtx)(__ccgo_up(bp))).FpPhrase
	}
	return (**(**TTokenCtx)(__ccgo_up(bp))).FpPhrase
}

func _sqlite3Fts5PoslistReaderInit(tls *libc.TLS, a uintptr, n int32, pIter uintptr) (r int32) {
	libc.Xmemset(tls, pIter, 0, uint64(32))
	(*TFts5PoslistReader)(unsafe.Pointer(pIter)).Fa = a
	(*TFts5PoslistReader)(unsafe.Pointer(pIter)).Fn = n
	_sqlite3Fts5PoslistReaderNext(tls, pIter)
	return libc.Int32FromUint8((*TFts5PoslistReader)(unsafe.Pointer(pIter)).FbEof)
}

// C documentation
//
//	/*
//	** Insert new entries into the FTS index and %_docsize table.
//	*/
func _sqlite3Fts5StorageIndexInsert(tls *libc.TLS, p uintptr, apVal uintptr, iRowid Ti64) (r int32) {
	bp := tls.Alloc(80)
	defer tls.Free(80)
	var iCol int32
	var pConfig, pVal uintptr
	var _ /* buf at bp+24 */ TFts5Buffer
	var _ /* ctx at bp+8 */ TFts5InsertCtx
	var _ /* nLoc at bp+56 */ int32
	var _ /* nText at bp+40 */ int32
	var _ /* pLoc at bp+64 */ uintptr
	var _ /* pText at bp+48 */ uintptr
	var _ /* rc at bp+0 */ int32
	_, _, _ = iCol, pConfig, pVal
	pConfig = (*TFts5Storage)(unsafe.Pointer(p)).FpConfig
	**(**int32)(__ccgo_up(bp)) = SQLITE_OK /* Buffer used to build up %_docsize blob */
	libc.Xmemset(tls, bp+24, 0, uint64(16))
	(**(**TFts5InsertCtx)(__ccgo_up(bp + 8))).FpStorage = p
	**(**int32)(__ccgo_up(bp)) = _fts5StorageLoadTotals(tls, p, int32(1))
	if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
		**(**int32)(__ccgo_up(bp)) = _sqlite3Fts5IndexBeginWrite(tls, (*TFts5Storage)(unsafe.Pointer(p)).FpIndex, 0, iRowid)
	}
	(**(**TFts5InsertCtx)(__ccgo_up(bp + 8))).FiCol = 0
	for {
		if !(**(**int32)(__ccgo_up(bp)) == SQLITE_OK && (**(**TFts5InsertCtx)(__ccgo_up(bp + 8))).FiCol < (*TFts5Config)(unsafe.Pointer(pConfig)).FnCol) {
			break
		}
		(**(**TFts5InsertCtx)(__ccgo_up(bp + 8))).FszCol = 0
		if libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TFts5Config)(unsafe.Pointer(pConfig)).FabUnindexed + uintptr((**(**TFts5InsertCtx)(__ccgo_up(bp + 8))).FiCol)))) == 0 {
			**(**int32)(__ccgo_up(bp + 40)) = 0            /* Size of pText in bytes */
			**(**uintptr)(__ccgo_up(bp + 48)) = uintptr(0) /* Pointer to buffer containing text value */
			**(**int32)(__ccgo_up(bp + 56)) = 0            /* Size of pText in bytes */
			**(**uintptr)(__ccgo_up(bp + 64)) = uintptr(0) /* Pointer to buffer containing text value */
			pVal = **(**uintptr)(__ccgo_up(apVal + uintptr((**(**TFts5InsertCtx)(__ccgo_up(bp + 8))).FiCol+int32(2))*8))
			if (*TFts5Storage)(unsafe.Pointer(p)).FpSavedRow != 0 && Xsqlite3_value_nochange(tls, pVal) != 0 {
				pVal = Xsqlite3_column_value(tls, (*TFts5Storage)(unsafe.Pointer(p)).FpSavedRow, (**(**TFts5InsertCtx)(__ccgo_up(bp + 8))).FiCol+int32(1))
				if (*TFts5Config)(unsafe.Pointer(pConfig)).FeContent == FTS5_CONTENT_NORMAL && (*TFts5Config)(unsafe.Pointer(pConfig)).FbLocale != 0 {
					iCol = (**(**TFts5InsertCtx)(__ccgo_up(bp + 8))).FiCol + int32(1) + (*TFts5Config)(unsafe.Pointer(pConfig)).FnCol
					**(**uintptr)(__ccgo_up(bp + 64)) = Xsqlite3_column_text(tls, (*TFts5Storage)(unsafe.Pointer(p)).FpSavedRow, iCol)
					**(**int32)(__ccgo_up(bp + 56)) = Xsqlite3_column_bytes(tls, (*TFts5Storage)(unsafe.Pointer(p)).FpSavedRow, iCol)
				}
			} else {
				pVal = **(**uintptr)(__ccgo_up(apVal + uintptr((**(**TFts5InsertCtx)(__ccgo_up(bp + 8))).FiCol+int32(2))*8))
			}
			if (*TFts5Config)(unsafe.Pointer(pConfig)).FbLocale != 0 && _sqlite3Fts5IsLocaleValue(tls, pConfig, pVal) != 0 {
				**(**int32)(__ccgo_up(bp)) = _sqlite3Fts5DecodeLocaleValue(tls, pVal, bp+48, bp+40, bp+64, bp+56)
			} else {
				**(**uintptr)(__ccgo_up(bp + 48)) = Xsqlite3_value_text(tls, pVal)
				**(**int32)(__ccgo_up(bp + 40)) = Xsqlite3_value_bytes(tls, pVal)
			}
			if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
				_sqlite3Fts5SetLocale(tls, pConfig, **(**uintptr)(__ccgo_up(bp + 64)), **(**int32)(__ccgo_up(bp + 56)))
				**(**int32)(__ccgo_up(bp)) = _sqlite3Fts5Tokenize(tls, pConfig, int32(FTS5_TOKENIZE_DOCUMENT), **(**uintptr)(__ccgo_up(bp + 48)), **(**int32)(__ccgo_up(bp + 40)), bp+8, __ccgo_fp(_fts5StorageInsertCallback))
				_sqlite3Fts5ClearLocale(tls, pConfig)
			}
		}
		_sqlite3Fts5BufferAppendVarint(tls, bp, bp+24, int64((**(**TFts5InsertCtx)(__ccgo_up(bp + 8))).FszCol))
		**(**Ti64)(__ccgo_up((*TFts5Storage)(unsafe.Pointer(p)).FaTotalSize + uintptr((**(**TFts5InsertCtx)(__ccgo_up(bp + 8))).FiCol)*8)) += int64((**(**TFts5InsertCtx)(__ccgo_up(bp + 8))).FszCol)
		goto _1
	_1:
		;
		(**(**TFts5InsertCtx)(__ccgo_up(bp + 8))).FiCol = (**(**TFts5InsertCtx)(__ccgo_up(bp + 8))).FiCol + 1
	}
	(*TFts5Storage)(unsafe.Pointer(p)).FnTotalRow = (*TFts5Storage)(unsafe.Pointer(p)).FnTotalRow + 1
	/* Write the %_docsize record */
	if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
		**(**int32)(__ccgo_up(bp)) = _fts5StorageInsertDocsize(tls, p, iRowid, bp+24)
	}
	Xsqlite3_free(tls, (**(**TFts5Buffer)(__ccgo_up(bp + 24))).Fp)
	return **(**int32)(__ccgo_up(bp))
}

func _sqlite3Fts5StorageRebuild(tls *libc.TLS, p uintptr) (r int32) {
	bp := tls.Alloc(80)
	defer tls.Free(80)
	var iCol, rc2 int32
	var iRowid Ti64
	var pConfig, pVal uintptr
	var _ /* buf at bp+0 */ TFts5Buffer
	var _ /* ctx at bp+24 */ TFts5InsertCtx
	var _ /* nLoc at bp+56 */ int32
	var _ /* nText at bp+44 */ int32
	var _ /* pLoc at bp+64 */ uintptr
	var _ /* pScan at bp+16 */ uintptr
	var _ /* pText at bp+48 */ uintptr
	var _ /* rc at bp+40 */ int32
	_, _, _, _, _ = iCol, iRowid, pConfig, pVal, rc2
	**(**TFts5Buffer)(__ccgo_up(bp)) = TFts5Buffer{}
	pConfig = (*TFts5Storage)(unsafe.Pointer(p)).FpConfig
	**(**uintptr)(__ccgo_up(bp + 16)) = uintptr(0)
	libc.Xmemset(tls, bp+24, 0, uint64(16))
	(**(**TFts5InsertCtx)(__ccgo_up(bp + 24))).FpStorage = p
	**(**int32)(__ccgo_up(bp + 40)) = _sqlite3Fts5StorageDeleteAll(tls, p)
	if **(**int32)(__ccgo_up(bp + 40)) == SQLITE_OK {
		**(**int32)(__ccgo_up(bp + 40)) = _fts5StorageLoadTotals(tls, p, int32(1))
	}
	if **(**int32)(__ccgo_up(bp + 40)) == SQLITE_OK {
		**(**int32)(__ccgo_up(bp + 40)) = _fts5StorageGetStmt(tls, p, int32(FTS5_STMT_SCAN), bp+16, (*TFts5Config)(unsafe.Pointer(pConfig)).FpzErrmsg)
	}
	for **(**int32)(__ccgo_up(bp + 40)) == SQLITE_OK && int32(SQLITE_ROW) == Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp + 16))) {
		iRowid = Xsqlite3_column_int64(tls, **(**uintptr)(__ccgo_up(bp + 16)), 0)
		_sqlite3Fts5BufferZero(tls, bp)
		**(**int32)(__ccgo_up(bp + 40)) = _sqlite3Fts5IndexBeginWrite(tls, (*TFts5Storage)(unsafe.Pointer(p)).FpIndex, 0, iRowid)
		(**(**TFts5InsertCtx)(__ccgo_up(bp + 24))).FiCol = 0
		for {
			if !(**(**int32)(__ccgo_up(bp + 40)) == SQLITE_OK && (**(**TFts5InsertCtx)(__ccgo_up(bp + 24))).FiCol < (*TFts5Config)(unsafe.Pointer(pConfig)).FnCol) {
				break
			}
			(**(**TFts5InsertCtx)(__ccgo_up(bp + 24))).FszCol = 0
			if libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TFts5Config)(unsafe.Pointer(pConfig)).FabUnindexed + uintptr((**(**TFts5InsertCtx)(__ccgo_up(bp + 24))).FiCol)))) == 0 {
				**(**int32)(__ccgo_up(bp + 44)) = 0            /* Size of pText in bytes */
				**(**uintptr)(__ccgo_up(bp + 48)) = uintptr(0) /* Pointer to buffer containing text value */
				**(**int32)(__ccgo_up(bp + 56)) = 0            /* Size of pLoc in bytes */
				**(**uintptr)(__ccgo_up(bp + 64)) = uintptr(0) /* Pointer to buffer containing text value */
				pVal = Xsqlite3_column_value(tls, **(**uintptr)(__ccgo_up(bp + 16)), (**(**TFts5InsertCtx)(__ccgo_up(bp + 24))).FiCol+int32(1))
				if (*TFts5Config)(unsafe.Pointer(pConfig)).FeContent == int32(FTS5_CONTENT_EXTERNAL) && _sqlite3Fts5IsLocaleValue(tls, pConfig, pVal) != 0 {
					**(**int32)(__ccgo_up(bp + 40)) = _sqlite3Fts5DecodeLocaleValue(tls, pVal, bp+48, bp+44, bp+64, bp+56)
				} else {
					**(**uintptr)(__ccgo_up(bp + 48)) = Xsqlite3_value_text(tls, pVal)
					**(**int32)(__ccgo_up(bp + 44)) = Xsqlite3_value_bytes(tls, pVal)
					if (*TFts5Config)(unsafe.Pointer(pConfig)).FbLocale != 0 {
						iCol = (**(**TFts5InsertCtx)(__ccgo_up(bp + 24))).FiCol + int32(1) + (*TFts5Config)(unsafe.Pointer(pConfig)).FnCol
						**(**uintptr)(__ccgo_up(bp + 64)) = Xsqlite3_column_text(tls, **(**uintptr)(__ccgo_up(bp + 16)), iCol)
						**(**int32)(__ccgo_up(bp + 56)) = Xsqlite3_column_bytes(tls, **(**uintptr)(__ccgo_up(bp + 16)), iCol)
					}
				}
				if **(**int32)(__ccgo_up(bp + 40)) == SQLITE_OK {
					_sqlite3Fts5SetLocale(tls, pConfig, **(**uintptr)(__ccgo_up(bp + 64)), **(**int32)(__ccgo_up(bp + 56)))
					**(**int32)(__ccgo_up(bp + 40)) = _sqlite3Fts5Tokenize(tls, pConfig, int32(FTS5_TOKENIZE_DOCUMENT), **(**uintptr)(__ccgo_up(bp + 48)), **(**int32)(__ccgo_up(bp + 44)), bp+24, __ccgo_fp(_fts5StorageInsertCallback))
					_sqlite3Fts5ClearLocale(tls, pConfig)
				}
			}
			_sqlite3Fts5BufferAppendVarint(tls, bp+40, bp, int64((**(**TFts5InsertCtx)(__ccgo_up(bp + 24))).FszCol))
			**(**Ti64)(__ccgo_up((*TFts5Storage)(unsafe.Pointer(p)).FaTotalSize + uintptr((**(**TFts5InsertCtx)(__ccgo_up(bp + 24))).FiCol)*8)) += int64((**(**TFts5InsertCtx)(__ccgo_up(bp + 24))).FszCol)
			goto _1
		_1:
			;
			(**(**TFts5InsertCtx)(__ccgo_up(bp + 24))).FiCol = (**(**TFts5InsertCtx)(__ccgo_up(bp + 24))).FiCol + 1
		}
		(*TFts5Storage)(unsafe.Pointer(p)).FnTotalRow = (*TFts5Storage)(unsafe.Pointer(p)).FnTotalRow + 1
		if **(**int32)(__ccgo_up(bp + 40)) == SQLITE_OK {
			**(**int32)(__ccgo_up(bp + 40)) = _fts5StorageInsertDocsize(tls, p, iRowid, bp)
		}
	}
	Xsqlite3_free(tls, (**(**TFts5Buffer)(__ccgo_up(bp))).Fp)
	rc2 = Xsqlite3_reset(tls, **(**uintptr)(__ccgo_up(bp + 16)))
	if **(**int32)(__ccgo_up(bp + 40)) == SQLITE_OK {
		**(**int32)(__ccgo_up(bp + 40)) = rc2
	}
	/* Write the averages record */
	if **(**int32)(__ccgo_up(bp + 40)) == SQLITE_OK {
		**(**int32)(__ccgo_up(bp + 40)) = _fts5StorageSaveTotals(tls, p)
	}
	return **(**int32)(__ccgo_up(bp + 40))
}

// 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, uint64(80))
	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.Int32FromUint64(libc.Uint64FromInt32(libc.Int32FromInt32(8)+libc.Int32FromInt32(MEMJOURNAL_DFLT_FILECHUNKSIZE)) - libc.Uint64FromInt64(16))
	}
	(*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
//
//	/*
//	** Allocate a KeyInfo object sufficient for an index of N key columns and
//	** X extra columns.
//	*/
func _sqlite3KeyInfoAlloc(tls *libc.TLS, db uintptr, N int32, X int32) (r uintptr) {
	var nExtra int32
	var p uintptr
	_, _ = nExtra, p
	nExtra = libc.Int32FromUint64(libc.Uint64FromInt32(N+X) * (libc.Uint64FromInt64(8) + libc.Uint64FromInt32(1)))
	if N+X > int32(0xffff) {
		return _sqlite3OomFault(tls, db)
	}
	p = _sqlite3DbMallocRawNN(tls, db, uint64(uint64(libc.UintptrFromInt32(0)+32)+libc.Uint64FromInt32(libc.Int32FromInt32(0))*libc.Uint64FromInt64(8)+libc.Uint64FromInt32(nExtra)))
	if p != 0 {
		(*TKeyInfo)(unsafe.Pointer(p)).FaSortFlags = p + 32 + uintptr(N+X)*8
		(*TKeyInfo)(unsafe.Pointer(p)).FnKeyField = libc.Uint16FromInt32(N)
		(*TKeyInfo)(unsafe.Pointer(p)).FnAllField = libc.Uint16FromInt32(N + X)
		(*TKeyInfo)(unsafe.Pointer(p)).Fenc = (*Tsqlite3)(unsafe.Pointer(db)).Fenc
		(*TKeyInfo)(unsafe.Pointer(p)).Fdb = db
		(*TKeyInfo)(unsafe.Pointer(p)).FnRef = uint32(1)
		libc.Xmemset(tls, p+32, 0, libc.Uint64FromInt32(nExtra))
	} else {
		return _sqlite3OomFault(tls, db)
	}
	return p
}

// C documentation
//
//	/*
//	** Convert a double into a LogEst
//	** In other words, compute an approximation for 10*log2(x).
//	*/
func _sqlite3LogEstFromDouble(tls *libc.TLS, _x float64) (r TLogEst) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	*(*float64)(unsafe.Pointer(bp)) = _x
	var e TLogEst
	var _ /* a at bp+8 */ Tu64
	_ = e
	if **(**float64)(__ccgo_up(bp)) <= libc.Float64FromInt32(1) {
		return 0
	}
	if **(**float64)(__ccgo_up(bp)) <= libc.Float64FromInt32(2000000000) {
		return _sqlite3LogEst(tls, uint64(**(**float64)(__ccgo_up(bp))))
	}
	libc.Xmemcpy(tls, bp+8, bp, uint64(8))
	e = libc.Int16FromUint64(**(**Tu64)(__ccgo_up(bp + 8))>>libc.Int32FromInt32(52) - uint64(1022))
	return int16(int32(e) * int32(10))
}

func _sqlite3OsRandomness(tls *libc.TLS, pVfs uintptr, nByte int32, zBufOut uintptr) (r int32) {
	if _sqlite3Config.FiPrngSeed != 0 {
		libc.Xmemset(tls, zBufOut, 0, libc.Uint64FromInt32(nByte))
		if nByte > libc.Int32FromInt64(4) {
			nByte = int32(4)
		}
		libc.Xmemcpy(tls, zBufOut, uintptr(unsafe.Pointer(&_sqlite3Config))+432, libc.Uint64FromInt32(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
//
//	/*
//	** Allocate an Expr node which joins as many as two subtrees.
//	**
//	** One or both of the subtrees can be NULL.  Return a pointer to the new
//	** Expr node.  Or, if an OOM error occurs, set pParse->db->mallocFailed,
//	** free the subtrees and return NULL.
//	*/
func _sqlite3PExpr(tls *libc.TLS, pParse uintptr, op int32, pLeft uintptr, pRight uintptr) (r uintptr) {
	var p uintptr
	_ = p
	p = _sqlite3DbMallocRawNN(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, uint64(72))
	if p != 0 {
		libc.Xmemset(tls, p, 0, uint64(72))
		(*TExpr)(unsafe.Pointer(p)).Fop = libc.Uint8FromInt32(op & int32(0xff))
		(*TExpr)(unsafe.Pointer(p)).FiAgg = int16(-int32(1))
		_sqlite3ExprAttachSubtrees(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, p, pLeft, pRight)
		_sqlite3ExprCheckHeight(tls, pParse, (*TExpr)(unsafe.Pointer(p)).FnHeight)
	} else {
		_sqlite3ExprDelete(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, pLeft)
		_sqlite3ExprDelete(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, pRight)
	}
	return p
}

// C documentation
//
//	/*
//	** Read the first N bytes from the beginning of the file into memory
//	** that pDest points to.
//	**
//	** If the pager was opened on a transient file (zFilename==""), or
//	** opened on a file less than N bytes in size, the output buffer is
//	** zeroed and SQLITE_OK returned. The rationale for this is that this
//	** function is used to read database headers, and a new transient or
//	** zero sized database has a header than consists entirely of zeroes.
//	**
//	** If any IO error apart from SQLITE_IOERR_SHORT_READ is encountered,
//	** the error code is returned to the caller and the contents of the
//	** output buffer undefined.
//	*/
func _sqlite3PagerReadFileheader(tls *libc.TLS, pPager uintptr, N int32, pDest uintptr) (r int32) {
	var rc int32
	_ = rc
	rc = SQLITE_OK
	libc.Xmemset(tls, pDest, 0, libc.Uint64FromInt32(N))
	/* This routine is only called by btree immediately after creating
	 ** the Pager object.  There has not been an opportunity to transition
	 ** to WAL mode yet.
	 */
	if (*Tsqlite3_file)(unsafe.Pointer((*TPager)(unsafe.Pointer(pPager)).Ffd)).FpMethods != uintptr(0) {
		rc = _sqlite3OsRead(tls, (*TPager)(unsafe.Pointer(pPager)).Ffd, pDest, N, 0)
		if rc == libc.Int32FromInt32(SQLITE_IOERR)|libc.Int32FromInt32(2)<<libc.Int32FromInt32(8) {
			rc = SQLITE_OK
		}
	}
	return rc
}

// C documentation
//
//	/*
//	** Change the page size used by the Pager object. The new page size
//	** is passed in *pPageSize.
//	**
//	** If the pager is in the error state when this function is called, it
//	** is a no-op. The value returned is the error state error code (i.e.
//	** one of SQLITE_IOERR, an SQLITE_IOERR_xxx sub-code or SQLITE_FULL).
//	**
//	** Otherwise, if all of the following are true:
//	**
//	**   * the new page size (value of *pPageSize) is valid (a power
//	**     of two between 512 and SQLITE_MAX_PAGE_SIZE, inclusive), and
//	**
//	**   * there are no outstanding page references, and
//	**
//	**   * the database is either not an in-memory database or it is
//	**     an in-memory database that currently consists of zero pages.
//	**
//	** then the pager object page size is set to *pPageSize.
//	**
//	** If the page size is changed, then this function uses sqlite3PagerMalloc()
//	** to obtain a new Pager.pTmpSpace buffer. If this allocation attempt
//	** fails, SQLITE_NOMEM is returned and the page size remains unchanged.
//	** In all other cases, SQLITE_OK is returned.
//	**
//	** If the page size is not changed, either because one of the enumerated
//	** conditions above is not true, the pager was in error state when this
//	** function was called, or because the memory allocation attempt failed,
//	** then *pPageSize is set to the old, retained page size before returning.
//	*/
func _sqlite3PagerSetPagesize(tls *libc.TLS, pPager uintptr, pPageSize uintptr, nReserve int32) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var pNew uintptr
	var pageSize Tu32
	var rc int32
	var _ /* nByte at bp+0 */ Ti64
	_, _, _ = pNew, pageSize, rc
	rc = SQLITE_OK
	/* It is not possible to do a full assert_pager_state() here, as this
	 ** function may be called from within PagerOpen(), before the state
	 ** of the Pager object is internally consistent.
	 **
	 ** At one point this function returned an error if the pager was in
	 ** PAGER_ERROR state. But since PAGER_ERROR state guarantees that
	 ** there is at least one outstanding page reference, this function
	 ** is a no-op for that case anyhow.
	 */
	pageSize = **(**Tu32)(__ccgo_up(pPageSize))
	if (libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FmemDb) == 0 || (*TPager)(unsafe.Pointer(pPager)).FdbSize == uint32(0)) && _sqlite3PcacheRefCount(tls, (*TPager)(unsafe.Pointer(pPager)).FpPCache) == 0 && pageSize != 0 && pageSize != libc.Uint32FromInt64((*TPager)(unsafe.Pointer(pPager)).FpageSize) {
		pNew = libc.UintptrFromInt32(0) /* New temp space */
		**(**Ti64)(__ccgo_up(bp)) = 0
		if libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FeState) > PAGER_OPEN && (*Tsqlite3_file)(unsafe.Pointer((*TPager)(unsafe.Pointer(pPager)).Ffd)).FpMethods != uintptr(0) {
			rc = _sqlite3OsFileSize(tls, (*TPager)(unsafe.Pointer(pPager)).Ffd, bp)
		}
		if rc == SQLITE_OK {
			/* 8 bytes of zeroed overrun space is sufficient so that the b-tree
			 * cell header parser will never run off the end of the allocation */
			pNew = _sqlite3PageMalloc(tls, libc.Int32FromUint32(pageSize+uint32(8)))
			if !(pNew != 0) {
				rc = int32(SQLITE_NOMEM)
			} else {
				libc.Xmemset(tls, pNew+uintptr(pageSize), 0, uint64(8))
			}
		}
		if rc == SQLITE_OK {
			_pager_reset(tls, pPager)
			rc = _sqlite3PcacheSetPageSize(tls, (*TPager)(unsafe.Pointer(pPager)).FpPCache, libc.Int32FromUint32(pageSize))
		}
		if rc == SQLITE_OK {
			_sqlite3PageFree(tls, (*TPager)(unsafe.Pointer(pPager)).FpTmpSpace)
			(*TPager)(unsafe.Pointer(pPager)).FpTmpSpace = pNew
			(*TPager)(unsafe.Pointer(pPager)).FdbSize = libc.Uint32FromInt64((**(**Ti64)(__ccgo_up(bp)) + libc.Int64FromUint32(pageSize) - libc.Int64FromInt32(1)) / libc.Int64FromUint32(pageSize))
			(*TPager)(unsafe.Pointer(pPager)).FpageSize = libc.Int64FromUint32(pageSize)
			(*TPager)(unsafe.Pointer(pPager)).FlckPgno = libc.Uint32FromInt32(_sqlite3PendingByte)/pageSize + uint32(1)
		} else {
			_sqlite3PageFree(tls, pNew)
		}
	}
	**(**Tu32)(__ccgo_up(pPageSize)) = libc.Uint32FromInt64((*TPager)(unsafe.Pointer(pPager)).FpageSize)
	if rc == SQLITE_OK {
		if nReserve < 0 {
			nReserve = int32((*TPager)(unsafe.Pointer(pPager)).FnReserve)
		}
		(*TPager)(unsafe.Pointer(pPager)).FnReserve = int16(nReserve)
		_pagerFixMaplimit(tls, pPager)
	}
	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, uint64(80))
	(*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
//
//	/*
//	** Drop every cache entry whose page number is greater than "pgno". The
//	** caller must ensure that there are no outstanding references to any pages
//	** other than page 1 with a page number greater than pgno.
//	**
//	** If there is a reference to page 1 and the pgno parameter passed to this
//	** function is 0, then the data area associated with page 1 is zeroed, but
//	** the page object is not dropped.
//	*/
func _sqlite3PcacheTruncate(tls *libc.TLS, pCache uintptr, pgno TPgno) {
	var p, pNext, pPage1 uintptr
	_, _, _ = p, pNext, pPage1
	if (*TPCache)(unsafe.Pointer(pCache)).FpCache != 0 {
		p = (*TPCache)(unsafe.Pointer(pCache)).FpDirty
		for {
			if !(p != 0) {
				break
			}
			pNext = (*TPgHdr)(unsafe.Pointer(p)).FpDirtyNext
			/* This routine never gets call with a positive pgno except right
			 ** after sqlite3PcacheCleanAll().  So if there are dirty pages,
			 ** it must be that pgno==0.
			 */
			if (*TPgHdr)(unsafe.Pointer(p)).Fpgno > pgno {
				_sqlite3PcacheMakeClean(tls, p)
			}
			goto _1
		_1:
			;
			p = pNext
		}
		if pgno == uint32(0) && (*TPCache)(unsafe.Pointer(pCache)).FnRefSum != 0 {
			pPage1 = (*(*func(*libc.TLS, uintptr, uint32, int32) uintptr)(unsafe.Pointer(&struct{ uintptr }{_sqlite3Config.Fpcache2.FxFetch})))(tls, (*TPCache)(unsafe.Pointer(pCache)).FpCache, uint32(1), 0)
			if pPage1 != 0 { /* Page 1 is always available in cache, because
				 ** pCache->nRefSum>0 */
				libc.Xmemset(tls, (*Tsqlite3_pcache_page)(unsafe.Pointer(pPage1)).FpBuf, 0, libc.Uint64FromInt32((*TPCache)(unsafe.Pointer(pCache)).FszPage))
				pgno = uint32(1)
			}
		}
		(*(*func(*libc.TLS, uintptr, uint32))(unsafe.Pointer(&struct{ uintptr }{_sqlite3Config.Fpcache2.FxTruncate})))(tls, (*TPCache)(unsafe.Pointer(pCache)).FpCache, pgno+uint32(1))
	}
}

// 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(80)
	defer tls.Free(80)
	var _ /* w at bp+0 */ TWalker
	var _ /* x at bp+48 */ TRefSrcList
	libc.Xmemset(tls, bp, 0, uint64(48))
	libc.Xmemset(tls, bp+48, 0, uint64(32))
	(**(**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 + 40)) = bp + 48
	(**(**TRefSrcList)(__ccgo_up(bp + 48))).Fdb = (*TParse)(unsafe.Pointer(pParse)).Fdb
	(**(**TRefSrcList)(__ccgo_up(bp + 48))).FpRef = pSrcList
	_sqlite3WalkExprList(tls, bp, *(*uintptr)(unsafe.Pointer(pExpr + 32)))
	if (*TExpr)(unsafe.Pointer(pExpr)).FpLeft != 0 {
		_sqlite3WalkExprList(tls, bp, *(*uintptr)(unsafe.Pointer((*TExpr)(unsafe.Pointer(pExpr)).FpLeft + 32)))
	}
	if (*TExpr)(unsafe.Pointer(pExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_WinFunc)) != uint32(0) {
		_sqlite3WalkExpr(tls, bp, (*TWindow)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pExpr + 64)))).FpFilter)
	}
	if (**(**TRefSrcList)(__ccgo_up(bp + 48))).FaiExclude != 0 {
		_sqlite3DbNNFreeNN(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, (**(**TRefSrcList)(__ccgo_up(bp + 48))).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
//
//	/*
//	** 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(912)
	defer tls.Free(912)
	var pElem, pSchema, pTab, v3 uintptr
	var _ /* temp1 at bp+0 */ THash
	var _ /* temp2 at bp+24 */ THash
	var _ /* xdb at bp+48 */ Tsqlite3
	_, _, _, _ = pElem, pSchema, pTab, v3
	pSchema = p
	libc.Xmemset(tls, bp+48, 0, uint64(864))
	**(**THash)(__ccgo_up(bp)) = (*TSchema)(unsafe.Pointer(pSchema)).FtblHash
	**(**THash)(__ccgo_up(bp + 24)) = (*TSchema)(unsafe.Pointer(pSchema)).FtrigHash
	_sqlite3HashInit(tls, pSchema+56)
	_sqlite3HashClear(tls, pSchema+32)
	pElem = (*THash)(unsafe.Pointer(bp + 24)).Ffirst
	for {
		if !(pElem != 0) {
			break
		}
		_sqlite3DeleteTrigger(tls, bp+48, (*THashElem)(unsafe.Pointer(pElem)).Fdata)
		goto _1
	_1:
		;
		pElem = (*THashElem)(unsafe.Pointer(pElem)).Fnext
	}
	_sqlite3HashClear(tls, bp+24)
	_sqlite3HashInit(tls, pSchema+8)
	pElem = (*THash)(unsafe.Pointer(bp)).Ffirst
	for {
		if !(pElem != 0) {
			break
		}
		pTab = (*THashElem)(unsafe.Pointer(pElem)).Fdata
		_sqlite3DeleteTable(tls, bp+48, pTab)
		goto _2
	_2:
		;
		pElem = (*THashElem)(unsafe.Pointer(pElem)).Fnext
	}
	_sqlite3HashClear(tls, bp)
	_sqlite3HashClear(tls, pSchema+80)
	(*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 + 114
	*(*Tu16)(unsafe.Pointer(v3)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v3))) & ^(libc.Int32FromInt32(DB_SchemaLoaded) | libc.Int32FromInt32(DB_ResetWanted)))
}

// C documentation
//
//	/*
//	** Check all ON clauses in pSelect to verify that they do not reference
//	** columns to the right.
//	*/
func _sqlite3SelectCheckOnClauses(tls *libc.TLS, pParse uintptr, pSelect uintptr) {
	bp := tls.Alloc(80)
	defer tls.Free(80)
	var ii int32
	var pItem uintptr
	var _ /* sCtx at bp+48 */ TCheckOnCtx
	var _ /* w at bp+0 */ TWalker
	_, _ = ii, pItem
	libc.Xmemset(tls, bp, 0, uint64(48))
	(**(**TWalker)(__ccgo_up(bp))).FpParse = pParse
	(**(**TWalker)(__ccgo_up(bp))).FxExprCallback = __ccgo_fp(_selectCheckOnClausesExpr)
	(**(**TWalker)(__ccgo_up(bp))).FxSelectCallback = __ccgo_fp(_selectCheckOnClausesSelect)
	*(*uintptr)(unsafe.Pointer(bp + 40)) = bp + 48
	libc.Xmemset(tls, bp+48, 0, uint64(24))
	(**(**TCheckOnCtx)(__ccgo_up(bp + 48))).FpSrc = (*TSelect)(unsafe.Pointer(pSelect)).FpSrc
	_sqlite3WalkExpr(tls, bp, (*TSelect)(unsafe.Pointer(pSelect)).FpWhere)
	**(**Tu32)(__ccgo_up(pSelect + 4)) &= libc.Uint32FromInt32(^libc.Int32FromInt32(SF_OnToWhere))
	/* Check for any table-function args that are attached to virtual tables
	 ** on the RHS of an outer join. They are subject to the same constraints
	 ** as ON clauses. */
	(**(**TCheckOnCtx)(__ccgo_up(bp + 48))).FbFuncArg = int32(1)
	ii = 0
	for {
		if !(ii < (*TSrcList)(unsafe.Pointer((*TSelect)(unsafe.Pointer(pSelect)).FpSrc)).FnSrc) {
			break
		}
		pItem = (*TSelect)(unsafe.Pointer(pSelect)).FpSrc + 8 + uintptr(ii)*80
		if int32(*(*uint32)(unsafe.Pointer(pItem + 24 + 4))&0x8>>3) != 0 && libc.Int32FromUint8((*TSrcItem)(unsafe.Pointer(pItem)).Ffg.Fjointype)&int32(JT_OUTER) != 0 {
			(**(**TCheckOnCtx)(__ccgo_up(bp + 48))).FiJoin = (*TSrcItem)(unsafe.Pointer(pItem)).FiCursor
			_sqlite3WalkExprList(tls, bp, *(*uintptr)(unsafe.Pointer(pItem + 48)))
		}
		goto _1
	_1:
		;
		ii = ii + 1
	}
}

// C documentation
//
//	/*
//	** Append a new table name to the given SrcList.  Create a new SrcList if
//	** need be.  A new entry is created in the SrcList even if pTable is NULL.
//	**
//	** A SrcList is returned, or NULL if there is an OOM error or if the
//	** SrcList grows to large.  The returned
//	** SrcList might be the same as the SrcList that was input or it might be
//	** a new one.  If an OOM error does occurs, then the prior value of pList
//	** that is input to this routine is automatically freed.
//	**
//	** If pDatabase is not null, it means that the table has an optional
//	** database name prefix.  Like this:  "database.table".  The pDatabase
//	** points to the table name and the pTable points to the database name.
//	** The SrcList.a[].zName field is filled with the table name which might
//	** come from pTable (if pDatabase is NULL) or from pDatabase.
//	** SrcList.a[].zDatabase is filled with the database name from pTable,
//	** or with NULL if no database is specified.
//	**
//	** In other words, if call like this:
//	**
//	**         sqlite3SrcListAppend(D,A,B,0);
//	**
//	** Then B is a table name and the database name is unspecified.  If called
//	** like this:
//	**
//	**         sqlite3SrcListAppend(D,A,B,C);
//	**
//	** Then C is the table name and B is the database name.  If C is defined
//	** then so is B.  In other words, we never have a case where:
//	**
//	**         sqlite3SrcListAppend(D,A,0,C);
//	**
//	** Both pTable and pDatabase are assumed to be quoted.  They are dequoted
//	** before being added to the SrcList.
//	*/
func _sqlite3SrcListAppend(tls *libc.TLS, pParse uintptr, pList uintptr, pTable uintptr, pDatabase uintptr) (r uintptr) {
	var db, pItem, pNew uintptr
	_, _, _ = db, pItem, pNew
	/* Cannot have C without B */
	db = (*TParse)(unsafe.Pointer(pParse)).Fdb
	if pList == uintptr(0) {
		pList = _sqlite3DbMallocRawNN(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, uint64(uint64(libc.UintptrFromInt32(0)+8)+libc.Uint64FromInt32(libc.Int32FromInt32(1))*libc.Uint64FromInt64(80)))
		if pList == uintptr(0) {
			return uintptr(0)
		}
		(*TSrcList)(unsafe.Pointer(pList)).FnAlloc = uint32(1)
		(*TSrcList)(unsafe.Pointer(pList)).FnSrc = int32(1)
		libc.Xmemset(tls, pList+8, 0, uint64(80))
		(*(*TSrcItem)(unsafe.Pointer(pList + 8))).FiCursor = -int32(1)
	} else {
		pNew = _sqlite3SrcListEnlarge(tls, pParse, pList, int32(1), (*TSrcList)(unsafe.Pointer(pList)).FnSrc)
		if pNew == uintptr(0) {
			_sqlite3SrcListDelete(tls, db, pList)
			return uintptr(0)
		} else {
			pList = pNew
		}
	}
	pItem = pList + 8 + uintptr((*TSrcList)(unsafe.Pointer(pList)).FnSrc-int32(1))*80
	if pDatabase != 0 && (*TToken)(unsafe.Pointer(pDatabase)).Fz == uintptr(0) {
		pDatabase = uintptr(0)
	}
	if pDatabase != 0 {
		(*TSrcItem)(unsafe.Pointer(pItem)).FzName = _sqlite3NameFromToken(tls, db, pDatabase)
		*(*uintptr)(unsafe.Pointer(pItem + 72)) = _sqlite3NameFromToken(tls, db, pTable)
	} else {
		(*TSrcItem)(unsafe.Pointer(pItem)).FzName = _sqlite3NameFromToken(tls, db, pTable)
		*(*uintptr)(unsafe.Pointer(pItem + 72)) = uintptr(0)
	}
	return pList
}

// C documentation
//
//	/*
//	** Append the contents of SrcList p2 to SrcList p1 and return the resulting
//	** SrcList. Or, if an error occurs, return NULL. In all cases, p1 and p2
//	** are deleted by this function.
//	*/
func _sqlite3SrcListAppendList(tls *libc.TLS, pParse uintptr, p1 uintptr, p2 uintptr) (r uintptr) {
	var nOld int32
	var pNew, v1 uintptr
	_, _, _ = nOld, pNew, v1
	if p2 != 0 {
		nOld = (*TSrcList)(unsafe.Pointer(p1)).FnSrc
		pNew = _sqlite3SrcListEnlarge(tls, pParse, p1, (*TSrcList)(unsafe.Pointer(p2)).FnSrc, nOld)
		if pNew == uintptr(0) {
			_sqlite3SrcListDelete(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, p2)
		} else {
			p1 = pNew
			libc.Xmemcpy(tls, p1+8+uintptr(nOld)*80, p2+8, libc.Uint64FromInt32((*TSrcList)(unsafe.Pointer(p2)).FnSrc)*uint64(80))
			v1 = p1 + 8 + 24
			*(*Tu8)(unsafe.Pointer(v1)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v1))) | libc.Int32FromInt32(JT_LTORJ)&libc.Int32FromUint8((*(*TSrcItem)(unsafe.Pointer(p2 + 8))).Ffg.Fjointype))
			_sqlite3DbFree(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, p2)
		}
	}
	return p1
}

// C documentation
//
//	/*
//	** If cursors, triggers, views and subqueries are all omitted from
//	** the build, then none of the following routines, except for
//	** sqlite3SelectDup(), can be called. sqlite3SelectDup() is sometimes
//	** called with a NULL argument.
//	*/
func _sqlite3SrcListDup(tls *libc.TLS, db uintptr, p uintptr, flags int32) (r uintptr) {
	var i int32
	var pNew, pNewItem, pNewSubq, pOldItem, pTab, v3 uintptr
	var v1 Tu32
	_, _, _, _, _, _, _, _ = i, pNew, pNewItem, pNewSubq, pOldItem, pTab, v1, v3
	if p == uintptr(0) {
		return uintptr(0)
	}
	pNew = _sqlite3DbMallocRawNN(tls, db, uint64(uint64(libc.UintptrFromInt32(0)+8)+libc.Uint64FromInt32((*TSrcList)(unsafe.Pointer(p)).FnSrc)*libc.Uint64FromInt64(80)))
	if pNew == uintptr(0) {
		return uintptr(0)
	}
	v1 = libc.Uint32FromInt32((*TSrcList)(unsafe.Pointer(p)).FnSrc)
	(*TSrcList)(unsafe.Pointer(pNew)).FnAlloc = v1
	(*TSrcList)(unsafe.Pointer(pNew)).FnSrc = libc.Int32FromUint32(v1)
	i = 0
	for {
		if !(i < (*TSrcList)(unsafe.Pointer(p)).FnSrc) {
			break
		}
		pNewItem = pNew + 8 + uintptr(i)*80
		pOldItem = p + 8 + uintptr(i)*80
		(*TSrcItem)(unsafe.Pointer(pNewItem)).Ffg = (*TSrcItem)(unsafe.Pointer(pOldItem)).Ffg
		if int32(*(*uint32)(unsafe.Pointer(pOldItem + 24 + 4))&0x4>>2) != 0 {
			pNewSubq = _sqlite3DbMallocRaw(tls, db, uint64(24))
			if pNewSubq == uintptr(0) {
				libc.SetBitFieldPtr32Uint32(pNewItem+24+4, libc.Uint32FromInt32(0), 2, 0x4)
			} else {
				libc.Xmemcpy(tls, pNewSubq, *(*uintptr)(unsafe.Pointer(pOldItem + 72)), uint64(24))
				(*TSubquery)(unsafe.Pointer(pNewSubq)).FpSelect = _sqlite3SelectDup(tls, db, (*TSubquery)(unsafe.Pointer(pNewSubq)).FpSelect, flags)
				if (*TSubquery)(unsafe.Pointer(pNewSubq)).FpSelect == uintptr(0) {
					_sqlite3DbFree(tls, db, pNewSubq)
					pNewSubq = uintptr(0)
					libc.SetBitFieldPtr32Uint32(pNewItem+24+4, libc.Uint32FromInt32(0), 2, 0x4)
				}
			}
			*(*uintptr)(unsafe.Pointer(pNewItem + 72)) = pNewSubq
		} else {
			if int32(*(*uint32)(unsafe.Pointer(pOldItem + 24 + 4))&0x10000>>16) != 0 {
				*(*uintptr)(unsafe.Pointer(pNewItem + 72)) = *(*uintptr)(unsafe.Pointer(pOldItem + 72))
			} else {
				*(*uintptr)(unsafe.Pointer(pNewItem + 72)) = _sqlite3DbStrDup(tls, db, *(*uintptr)(unsafe.Pointer(pOldItem + 72)))
			}
		}
		(*TSrcItem)(unsafe.Pointer(pNewItem)).FzName = _sqlite3DbStrDup(tls, db, (*TSrcItem)(unsafe.Pointer(pOldItem)).FzName)
		(*TSrcItem)(unsafe.Pointer(pNewItem)).FzAlias = _sqlite3DbStrDup(tls, db, (*TSrcItem)(unsafe.Pointer(pOldItem)).FzAlias)
		(*TSrcItem)(unsafe.Pointer(pNewItem)).FiCursor = (*TSrcItem)(unsafe.Pointer(pOldItem)).FiCursor
		if int32(*(*uint32)(unsafe.Pointer(pNewItem + 24 + 4))&0x2>>1) != 0 {
			*(*uintptr)(unsafe.Pointer(pNewItem + 48)) = _sqlite3DbStrDup(tls, db, *(*uintptr)(unsafe.Pointer(pOldItem + 48)))
		} else {
			if int32(*(*uint32)(unsafe.Pointer(pNewItem + 24 + 4))&0x8>>3) != 0 {
				*(*uintptr)(unsafe.Pointer(pNewItem + 48)) = _sqlite3ExprListDup(tls, db, *(*uintptr)(unsafe.Pointer(pOldItem + 48)), flags)
			} else {
				*(*Tu32)(unsafe.Pointer(&(*TSrcItem)(unsafe.Pointer(pNewItem)).Fu1)) = *(*Tu32)(unsafe.Pointer(&(*TSrcItem)(unsafe.Pointer(pOldItem)).Fu1))
			}
		}
		(*TSrcItem)(unsafe.Pointer(pNewItem)).Fu2 = (*TSrcItem)(unsafe.Pointer(pOldItem)).Fu2
		if int32(*(*uint32)(unsafe.Pointer(pNewItem + 24 + 4))&0x200>>9) != 0 {
			(*TCteUse)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pNewItem + 56)))).FnUse = (*TCteUse)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pNewItem + 56)))).FnUse + 1
		}
		v3 = (*TSrcItem)(unsafe.Pointer(pOldItem)).FpSTab
		(*TSrcItem)(unsafe.Pointer(pNewItem)).FpSTab = v3
		pTab = v3
		if pTab != 0 {
			(*TTable)(unsafe.Pointer(pTab)).FnTabRef = (*TTable)(unsafe.Pointer(pTab)).FnTabRef + 1
		}
		if int32(*(*uint32)(unsafe.Pointer(pOldItem + 24 + 4))&0x800>>11) != 0 {
			*(*uintptr)(unsafe.Pointer(pNewItem + 64)) = _sqlite3IdListDup(tls, db, *(*uintptr)(unsafe.Pointer(pOldItem + 64)))
		} else {
			*(*uintptr)(unsafe.Pointer(pNewItem + 64)) = _sqlite3ExprDup(tls, db, *(*uintptr)(unsafe.Pointer(pOldItem + 64)), flags)
		}
		(*TSrcItem)(unsafe.Pointer(pNewItem)).FcolUsed = (*TSrcItem)(unsafe.Pointer(pOldItem)).FcolUsed
		goto _2
	_2:
		;
		i = i + 1
	}
	return pNew
}

// C documentation
//
//	/*
//	** Enlarge the memory allocation on a StrAccum object so that it is
//	** able to accept at least N more bytes of text.
//	**
//	** Return the number of bytes of text that StrAccum is able to accept
//	** after the attempted enlargement.  The value returned might be zero.
//	*/
func _sqlite3StrAccumEnlarge(tls *libc.TLS, p uintptr, N Ti64) (r int32) {
	var szNew Ti64
	var zNew, zOld, v1 uintptr
	_, _, _, _ = szNew, zNew, zOld, v1
	/* Only called if really needed */
	if (*TStrAccum)(unsafe.Pointer(p)).FaccError != 0 {
		return 0
	}
	if (*TStrAccum)(unsafe.Pointer(p)).FmxAlloc == uint32(0) {
		_sqlite3StrAccumSetError(tls, p, uint8(SQLITE_TOOBIG))
		return libc.Int32FromUint32((*TStrAccum)(unsafe.Pointer(p)).FnAlloc - (*TStrAccum)(unsafe.Pointer(p)).FnChar - uint32(1))
	} else {
		if libc.Int32FromUint8((*TStrAccum)(unsafe.Pointer(p)).FprintfFlags)&int32(SQLITE_PRINTF_MALLOCED) != 0 {
			v1 = (*TStrAccum)(unsafe.Pointer(p)).FzText
		} else {
			v1 = uintptr(0)
		}
		zOld = v1
		szNew = libc.Int64FromUint32((*TStrAccum)(unsafe.Pointer(p)).FnChar) + N + int64(1)
		if szNew+libc.Int64FromUint32((*TStrAccum)(unsafe.Pointer(p)).FnChar) <= libc.Int64FromUint32((*TStrAccum)(unsafe.Pointer(p)).FmxAlloc) {
			/* Force exponential buffer size growth as long as it does not overflow,
			 ** to avoid having to call this routine too often */
			szNew = szNew + libc.Int64FromUint32((*TStrAccum)(unsafe.Pointer(p)).FnChar)
		}
		if szNew > libc.Int64FromUint32((*TStrAccum)(unsafe.Pointer(p)).FmxAlloc) {
			Xsqlite3_str_reset(tls, p)
			_sqlite3StrAccumSetError(tls, p, uint8(SQLITE_TOOBIG))
			return 0
		} else {
			(*TStrAccum)(unsafe.Pointer(p)).FnAlloc = libc.Uint32FromInt32(int32(szNew))
		}
		if (*TStrAccum)(unsafe.Pointer(p)).Fdb != 0 {
			zNew = _sqlite3DbRealloc(tls, (*TStrAccum)(unsafe.Pointer(p)).Fdb, zOld, uint64((*TStrAccum)(unsafe.Pointer(p)).FnAlloc))
		} else {
			zNew = _sqlite3Realloc(tls, zOld, uint64((*TStrAccum)(unsafe.Pointer(p)).FnAlloc))
		}
		if zNew != 0 {
			if !(libc.Int32FromUint8((*TStrAccum)(unsafe.Pointer(p)).FprintfFlags)&libc.Int32FromInt32(SQLITE_PRINTF_MALLOCED) != libc.Int32FromInt32(0)) && (*TStrAccum)(unsafe.Pointer(p)).FnChar > uint32(0) {
				libc.Xmemcpy(tls, zNew, (*TStrAccum)(unsafe.Pointer(p)).FzText, uint64((*TStrAccum)(unsafe.Pointer(p)).FnChar))
			}
			(*TStrAccum)(unsafe.Pointer(p)).FzText = zNew
			(*TStrAccum)(unsafe.Pointer(p)).FnAlloc = libc.Uint32FromInt32(_sqlite3DbMallocSize(tls, (*TStrAccum)(unsafe.Pointer(p)).Fdb, zNew))
			v1 = p + 29
			*(*Tu8)(unsafe.Pointer(v1)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v1))) | libc.Int32FromInt32(SQLITE_PRINTF_MALLOCED))
		} else {
			Xsqlite3_str_reset(tls, p)
			_sqlite3StrAccumSetError(tls, p, uint8(SQLITE_NOMEM))
			return 0
		}
	}
	return int32(N)
}

// 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+8 */ 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.Int32FromUint64(libc.Uint64FromInt64(24) * libc.Uint64FromInt32((*TVdbe)(unsafe.Pointer(p)).FnOp))                            /* Bytes of opcode memory used */
	(**(**TReusableSpace)(__ccgo_up(bp + 8))).FpSpace = (*TVdbe)(unsafe.Pointer(p)).FaOp + uintptr(n)                                      /* Unused opcode memory */
	(**(**TReusableSpace)(__ccgo_up(bp + 8))).FnFree = int64(((*TParse)(unsafe.Pointer(pParse)).FszOpAlloc - n) & ^libc.Int32FromInt32(7)) /* Bytes of unused memory */
	_resolveP2Values(tls, p, bp)
	libc.SetBitFieldPtr16Uint32(p+200, uint32(libc.BoolUint8((*TParse)(unsafe.Pointer(pParse)).FisMultiWrite != 0 && int32(Tbft(*(*uint16)(unsafe.Pointer(pParse + 40))&0x2>>1)) != 0)), 5, 0x20)
	if (*TParse)(unsafe.Pointer(pParse)).Fexplain != 0 {
		if nMem < int32(10) {
			nMem = int32(10)
		}
		libc.SetBitFieldPtr16Uint32(p+200, 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 + 200))&0xc>>2)))
	}
	libc.SetBitFieldPtr16Uint32(p+200, 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 + 8))).FnNeeded = 0
	(*TVdbe)(unsafe.Pointer(p)).FaMem = _allocSpace(tls, bp+8, uintptr(0), libc.Int64FromUint64(libc.Uint64FromInt32(nMem)*uint64(56)))
	(*TVdbe)(unsafe.Pointer(p)).FaVar = _allocSpace(tls, bp+8, uintptr(0), libc.Int64FromUint64(libc.Uint64FromInt32(nVar)*uint64(56)))
	(*TVdbe)(unsafe.Pointer(p)).FapArg = _allocSpace(tls, bp+8, uintptr(0), libc.Int64FromUint64(libc.Uint64FromInt32(**(**int32)(__ccgo_up(bp)))*uint64(8)))
	(*TVdbe)(unsafe.Pointer(p)).FapCsr = _allocSpace(tls, bp+8, uintptr(0), libc.Int64FromUint64(libc.Uint64FromInt32(nCursor)*uint64(8)))
	if (**(**TReusableSpace)(__ccgo_up(bp + 8))).FnNeeded != 0 {
		v1 = _sqlite3DbMallocRawNN(tls, db, libc.Uint64FromInt64((**(**TReusableSpace)(__ccgo_up(bp + 8))).FnNeeded))
		(*TVdbe)(unsafe.Pointer(p)).FpFree = v1
		(**(**TReusableSpace)(__ccgo_up(bp + 8))).FpSpace = v1
		(**(**TReusableSpace)(__ccgo_up(bp + 8))).FnFree = (**(**TReusableSpace)(__ccgo_up(bp + 8))).FnNeeded
		if !((*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0) {
			(*TVdbe)(unsafe.Pointer(p)).FaMem = _allocSpace(tls, bp+8, (*TVdbe)(unsafe.Pointer(p)).FaMem, libc.Int64FromUint64(libc.Uint64FromInt32(nMem)*uint64(56)))
			(*TVdbe)(unsafe.Pointer(p)).FaVar = _allocSpace(tls, bp+8, (*TVdbe)(unsafe.Pointer(p)).FaVar, libc.Int64FromUint64(libc.Uint64FromInt32(nVar)*uint64(56)))
			(*TVdbe)(unsafe.Pointer(p)).FapArg = _allocSpace(tls, bp+8, (*TVdbe)(unsafe.Pointer(p)).FapArg, libc.Int64FromUint64(libc.Uint64FromInt32(**(**int32)(__ccgo_up(bp)))*uint64(8)))
			(*TVdbe)(unsafe.Pointer(p)).FapCsr = _allocSpace(tls, bp+8, (*TVdbe)(unsafe.Pointer(p)).FapCsr, libc.Int64FromUint64(libc.Uint64FromInt32(nCursor)*uint64(8)))
		}
	}
	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.Uint64FromInt32(nCursor)*uint64(8))
	}
	_sqlite3VdbeRewind(tls, p)
}

// C documentation
//
//	/*
//	** Make a full copy of pFrom into pTo.  Prior contents of pTo are
//	** freed before the copy is made.
//	*/
func _sqlite3VdbeMemCopy(tls *libc.TLS, pTo uintptr, pFrom uintptr) (r int32) {
	var rc int32
	var v1 uintptr
	_, _ = rc, v1
	rc = SQLITE_OK
	if libc.Int32FromUint16((*TMem)(unsafe.Pointer(pTo)).Fflags)&(libc.Int32FromInt32(MEM_Agg)|libc.Int32FromInt32(MEM_Dyn)) != 0 {
		_vdbeMemClearExternAndSetNull(tls, pTo)
	}
	libc.Xmemcpy(tls, pTo, pFrom, uint64(libc.UintptrFromInt32(0)+24))
	v1 = pTo + 20
	*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) & ^libc.Int32FromInt32(MEM_Dyn))
	if libc.Int32FromUint16((*TMem)(unsafe.Pointer(pTo)).Fflags)&(libc.Int32FromInt32(MEM_Str)|libc.Int32FromInt32(MEM_Blob)) != 0 {
		if 0 == libc.Int32FromUint16((*TMem)(unsafe.Pointer(pFrom)).Fflags)&int32(MEM_Static) {
			v1 = pTo + 20
			*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) | libc.Int32FromInt32(MEM_Ephem))
			rc = _sqlite3VdbeMemMakeWriteable(tls, pTo)
		}
	}
	return rc
}

// C documentation
//
//	/*
//	** If the given Mem* has a zero-filled tail, turn it into an ordinary
//	** blob stored in dynamically allocated space.
//	*/
func _sqlite3VdbeMemExpandBlob(tls *libc.TLS, pMem uintptr) (r int32) {
	var nByte int32
	var v1 uintptr
	_, _ = nByte, v1
	/* Set nByte to the number of bytes required to store the expanded blob. */
	nByte = (*TMem)(unsafe.Pointer(pMem)).Fn + *(*int32)(unsafe.Pointer(&(*TMem)(unsafe.Pointer(pMem)).Fu))
	if nByte <= 0 {
		if libc.Int32FromUint16((*TMem)(unsafe.Pointer(pMem)).Fflags)&int32(MEM_Blob) == 0 {
			return SQLITE_OK
		}
		nByte = int32(1)
	}
	if _sqlite3VdbeMemGrow(tls, pMem, nByte, int32(1)) != 0 {
		return int32(SQLITE_NOMEM)
	}
	libc.Xmemset(tls, (*TMem)(unsafe.Pointer(pMem)).Fz+uintptr((*TMem)(unsafe.Pointer(pMem)).Fn), 0, libc.Uint64FromInt32(*(*int32)(unsafe.Pointer(&(*TMem)(unsafe.Pointer(pMem)).Fu))))
	**(**int32)(__ccgo_up(pMem + 16)) += *(*int32)(unsafe.Pointer(&(*TMem)(unsafe.Pointer(pMem)).Fu))
	v1 = pMem + 20
	*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) & ^(libc.Int32FromInt32(MEM_Zero) | libc.Int32FromInt32(MEM_Term)))
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** Make sure pMem->z points to a writable allocation of at least n bytes.
//	**
//	** If the bPreserve argument is true, then copy of the content of
//	** pMem->z into the new allocation.  pMem must be either a string or
//	** blob if bPreserve is true.  If bPreserve is false, any prior content
//	** in pMem->z is discarded.
//	*/
func _sqlite3VdbeMemGrow(tls *libc.TLS, pMem uintptr, n int32, bPreserve int32) (r int32) {
	var v1 uintptr
	_ = v1
	/* If the bPreserve flag is set to true, then the memory cell must already
	 ** contain a valid string or blob value.  */
	if (*TMem)(unsafe.Pointer(pMem)).FszMalloc > 0 && bPreserve != 0 && (*TMem)(unsafe.Pointer(pMem)).Fz == (*TMem)(unsafe.Pointer(pMem)).FzMalloc {
		if (*TMem)(unsafe.Pointer(pMem)).Fdb != 0 {
			v1 = _sqlite3DbReallocOrFree(tls, (*TMem)(unsafe.Pointer(pMem)).Fdb, (*TMem)(unsafe.Pointer(pMem)).Fz, libc.Uint64FromInt32(n))
			(*TMem)(unsafe.Pointer(pMem)).FzMalloc = v1
			(*TMem)(unsafe.Pointer(pMem)).Fz = v1
		} else {
			(*TMem)(unsafe.Pointer(pMem)).FzMalloc = _sqlite3Realloc(tls, (*TMem)(unsafe.Pointer(pMem)).Fz, libc.Uint64FromInt32(n))
			if (*TMem)(unsafe.Pointer(pMem)).FzMalloc == uintptr(0) {
				Xsqlite3_free(tls, (*TMem)(unsafe.Pointer(pMem)).Fz)
			}
			(*TMem)(unsafe.Pointer(pMem)).Fz = (*TMem)(unsafe.Pointer(pMem)).FzMalloc
		}
		bPreserve = 0
	} else {
		if (*TMem)(unsafe.Pointer(pMem)).FszMalloc > 0 {
			_sqlite3DbFreeNN(tls, (*TMem)(unsafe.Pointer(pMem)).Fdb, (*TMem)(unsafe.Pointer(pMem)).FzMalloc)
		}
		(*TMem)(unsafe.Pointer(pMem)).FzMalloc = _sqlite3DbMallocRaw(tls, (*TMem)(unsafe.Pointer(pMem)).Fdb, libc.Uint64FromInt32(n))
	}
	if (*TMem)(unsafe.Pointer(pMem)).FzMalloc == uintptr(0) {
		_sqlite3VdbeMemSetNull(tls, pMem)
		(*TMem)(unsafe.Pointer(pMem)).Fz = uintptr(0)
		(*TMem)(unsafe.Pointer(pMem)).FszMalloc = 0
		return int32(SQLITE_NOMEM)
	} else {
		(*TMem)(unsafe.Pointer(pMem)).FszMalloc = _sqlite3DbMallocSize(tls, (*TMem)(unsafe.Pointer(pMem)).Fdb, (*TMem)(unsafe.Pointer(pMem)).FzMalloc)
	}
	if bPreserve != 0 && (*TMem)(unsafe.Pointer(pMem)).Fz != 0 {
		libc.Xmemcpy(tls, (*TMem)(unsafe.Pointer(pMem)).FzMalloc, (*TMem)(unsafe.Pointer(pMem)).Fz, libc.Uint64FromInt32((*TMem)(unsafe.Pointer(pMem)).Fn))
	}
	if libc.Int32FromUint16((*TMem)(unsafe.Pointer(pMem)).Fflags)&int32(MEM_Dyn) != 0 {
		(*(*func(*libc.TLS, uintptr))(unsafe.Pointer(&struct{ uintptr }{(*TMem)(unsafe.Pointer(pMem)).FxDel})))(tls, (*TMem)(unsafe.Pointer(pMem)).Fz)
	}
	(*TMem)(unsafe.Pointer(pMem)).Fz = (*TMem)(unsafe.Pointer(pMem)).FzMalloc
	v1 = pMem + 20
	*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) & ^(libc.Int32FromInt32(MEM_Dyn) | libc.Int32FromInt32(MEM_Ephem) | libc.Int32FromInt32(MEM_Static)))
	return SQLITE_OK
}

func _sqlite3VdbeMemShallowCopy(tls *libc.TLS, pTo uintptr, pFrom uintptr, srcType int32) {
	var v1 uintptr
	_ = v1
	if libc.Int32FromUint16((*TMem)(unsafe.Pointer(pTo)).Fflags)&(libc.Int32FromInt32(MEM_Agg)|libc.Int32FromInt32(MEM_Dyn)) != 0 {
		_vdbeClrCopy(tls, pTo, pFrom, srcType)
		return
	}
	libc.Xmemcpy(tls, pTo, pFrom, uint64(libc.UintptrFromInt32(0)+24))
	if libc.Int32FromUint16((*TMem)(unsafe.Pointer(pFrom)).Fflags)&int32(MEM_Static) == 0 {
		v1 = pTo + 20
		*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) & ^(libc.Int32FromInt32(MEM_Dyn) | libc.Int32FromInt32(MEM_Static) | libc.Int32FromInt32(MEM_Ephem)))
		v1 = pTo + 20
		*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) | srcType)
	}
}

// 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(208)
	defer tls.Free(208)
	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, uint64(200))
	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)*56))
		} 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 + 168
	(*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+80)
	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)*56)
			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)*8)))
			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
//
//	/*
//	** 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 + 136 + 11*4))
	}
	/* Do not allow the total number of threads (main thread + all workers)
	 ** to exceed the maximum merge count */
	szKeyInfo = libc.Int32FromUint64(uint64(libc.UintptrFromInt32(0)+32) + uint64((*TKeyInfo)(unsafe.Pointer((*TVdbeCursor)(unsafe.Pointer(pCsr)).FpKeyInfo)).FnAllField)*libc.Uint64FromInt64(8))
	sz = libc.Int64FromUint64(uint64(libc.UintptrFromInt32(0)+96) + libc.Uint64FromInt32(nWorker+libc.Int32FromInt32(1))*libc.Uint64FromInt64(104))
	pSorter = _sqlite3DbMallocZero(tls, db, libc.Uint64FromInt64(sz+int64(szKeyInfo)))
	*(*uintptr)(unsafe.Pointer(pCsr + 48)) = 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.Uint64FromInt32(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 + 96 + uintptr(i)*104
			(*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 + 32)) == uintptr(0) || *(*uintptr)(unsafe.Pointer(pKeyInfo + 32)) == (*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
//
//	/*
//	** Copy the current sorter key into the memory cell pOut.
//	*/
func _sqlite3VdbeSorterRowkey(tls *libc.TLS, pCsr uintptr, pOut uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var pKey, pSorter uintptr
	var _ /* nKey at bp+0 */ int32
	_, _ = pKey, pSorter /* Sorter key to copy into pOut */
	pSorter = *(*uintptr)(unsafe.Pointer(pCsr + 48))
	pKey = _vdbeSorterRowkey(tls, pSorter, bp)
	if _sqlite3VdbeMemClearAndResize(tls, pOut, **(**int32)(__ccgo_up(bp))) != 0 {
		return int32(SQLITE_NOMEM)
	}
	(*TMem)(unsafe.Pointer(pOut)).Fn = **(**int32)(__ccgo_up(bp))
	(*TMem)(unsafe.Pointer(pOut)).Fflags = libc.Uint16FromInt32(libc.Int32FromUint16((*TMem)(unsafe.Pointer(pOut)).Fflags) & ^(libc.Int32FromInt32(MEM_TypeMask)|libc.Int32FromInt32(MEM_Zero)) | int32(MEM_Blob))
	libc.Xmemcpy(tls, (*TMem)(unsafe.Pointer(pOut)).Fz, pKey, libc.Uint64FromInt32(**(**int32)(__ccgo_up(bp))))
	return SQLITE_OK
}

// 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 + 48))
	**(**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 + 92
		*(*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 + 92
			*(*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.Int64FromUint64(libc.Uint64FromInt32((*TMem)(unsafe.Pointer(pVal)).Fn) + uint64(16))
	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(int64((*TVdbeSorter)(unsafe.Pointer(pSorter)).Flist.FpList) - int64((*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 + 80
		*(*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(&(*TSorterRecord)(unsafe.Pointer(pNew)).Fu)) = int32(int64((*TVdbeSorter)(unsafe.Pointer(pSorter)).Flist.FpList) - int64((*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 + 8)) = (*TVdbeSorter)(unsafe.Pointer(pSorter)).Flist.FpList
	}
	libc.Xmemcpy(tls, pNew+libc.UintptrFromInt32(1)*16, (*TMem)(unsafe.Pointer(pVal)).Fz, libc.Uint64FromInt32((*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
//
//	/*
//	** 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(uint64(48)+libc.Uint64FromInt32(nName)+uint64(1)))
		if pMod == uintptr(0) {
			_sqlite3OomFault(tls, db)
			return uintptr(0)
		}
		zCopy = pMod + 1*48
		libc.Xmemcpy(tls, zCopy, zName, libc.Uint64FromInt32(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+576, 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
//
//	/*
//	** The first parameter (pDef) is a function implementation.  The
//	** second parameter (pExpr) is the first argument to this function.
//	** If pExpr is a column in a virtual table, then let the virtual
//	** table implementation have an opportunity to overload the function.
//	**
//	** This routine is used to allow virtual table implementations to
//	** overload MATCH, LIKE, GLOB, and REGEXP operators.
//	**
//	** Return either the pDef argument (indicating no change) or a
//	** new FuncDef structure that is marked as ephemeral using the
//	** SQLITE_FUNC_EPHEM flag.
//	*/
func _sqlite3VtabOverloadFunction(tls *libc.TLS, db uintptr, pDef uintptr, nArg int32, pExpr uintptr) (r uintptr) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var pMod, pNew, pTab, pVtab uintptr
	var rc int32
	var _ /* pArg at bp+8 */ uintptr
	var _ /* xSFunc at bp+0 */ uintptr
	_, _, _, _, _ = pMod, pNew, pTab, pVtab, rc
	**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
	**(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0)
	rc = 0
	/* Check to see the left operand is a column in a virtual table */
	if pExpr == uintptr(0) {
		return pDef
	}
	if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) != int32(TK_COLUMN) {
		return pDef
	}
	pTab = *(*uintptr)(unsafe.Pointer(pExpr + 64))
	if pTab == uintptr(0) {
		return pDef
	}
	if !(libc.Int32FromUint8((*TTable)(unsafe.Pointer(pTab)).FeTabType) == libc.Int32FromInt32(TABTYP_VTAB)) {
		return pDef
	}
	pVtab = (*TVTable)(unsafe.Pointer(_sqlite3GetVTable(tls, db, pTab))).FpVtab
	pMod = (*Tsqlite3_vtab)(unsafe.Pointer(pVtab)).FpModule
	if (*Tsqlite3_module)(unsafe.Pointer(pMod)).FxFindFunction == uintptr(0) {
		return pDef
	}
	/* Call the xFindFunction method on the virtual table implementation
	 ** to see if the implementation wants to overload this function.
	 **
	 ** Though undocumented, we have historically always invoked xFindFunction
	 ** with an all lower-case function name.  Continue in this tradition to
	 ** avoid any chance of an incompatibility.
	 */
	rc = (*(*func(*libc.TLS, uintptr, int32, uintptr, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*Tsqlite3_module)(unsafe.Pointer(pMod)).FxFindFunction})))(tls, pVtab, nArg, (*TFuncDef)(unsafe.Pointer(pDef)).FzName, bp, bp+8)
	if rc == 0 {
		return pDef
	}
	/* Create a new ephemeral function definition for the overloaded
	 ** function */
	pNew = _sqlite3DbMallocZero(tls, db, uint64(uint64(72)+libc.Uint64FromInt32(_sqlite3Strlen30(tls, (*TFuncDef)(unsafe.Pointer(pDef)).FzName))+uint64(1)))
	if pNew == uintptr(0) {
		return pDef
	}
	**(**TFuncDef)(__ccgo_up(pNew)) = **(**TFuncDef)(__ccgo_up(pDef))
	(*TFuncDef)(unsafe.Pointer(pNew)).FzName = pNew + 1*72
	libc.Xmemcpy(tls, pNew+1*72, (*TFuncDef)(unsafe.Pointer(pDef)).FzName, libc.Uint64FromInt32(_sqlite3Strlen30(tls, (*TFuncDef)(unsafe.Pointer(pDef)).FzName)+int32(1)))
	(*TFuncDef)(unsafe.Pointer(pNew)).FxSFunc = **(**uintptr)(__ccgo_up(bp))
	(*TFuncDef)(unsafe.Pointer(pNew)).FpUserData = **(**uintptr)(__ccgo_up(bp + 8))
	**(**Tu32)(__ccgo_up(pNew + 4)) |= uint32(SQLITE_FUNC_EPHEM)
	return pNew
}

// C documentation
//
//	/*
//	** This routine is called to implement sqlite3_wal_checkpoint() and
//	** related interfaces.
//	**
//	** Obtain a CHECKPOINT lock and then backfill as much information as
//	** we can from WAL into the database.
//	**
//	** If parameter xBusy is not NULL, it is a pointer to a busy-handler
//	** callback. In this case this function runs a blocking checkpoint.
//	*/
func _sqlite3WalCheckpoint(tls *libc.TLS, pWal uintptr, db uintptr, eMode int32, __ccgo_fp_xBusy uintptr, pBusyArg uintptr, sync_flags int32, nBuf int32, zBuf uintptr, pnLog uintptr, pnCkpt uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var eMode2, rc, v1 int32
	var xBusy2 uintptr
	var _ /* isChanged at bp+0 */ int32
	_, _, _, _ = eMode2, rc, xBusy2, v1 /* Return code */
	**(**int32)(__ccgo_up(bp)) = 0      /* True if a new wal-index header is loaded */
	eMode2 = eMode                      /* Mode to pass to walCheckpoint() */
	xBusy2 = __ccgo_fp_xBusy            /* Busy handler for eMode2 */
	/* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked
	 ** in the SQLITE_CHECKPOINT_PASSIVE mode. */
	if (*TWal)(unsafe.Pointer(pWal)).FreadOnly != 0 {
		return int32(SQLITE_READONLY)
	}
	/* Enable blocking locks, if possible. */
	if xBusy2 != 0 {
	}
	/* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive
	 ** "checkpoint" lock on the database file.
	 ** EVIDENCE-OF: R-10421-19736 If any other process is running a
	 ** checkpoint operation at the same time, the lock cannot be obtained and
	 ** SQLITE_BUSY is returned.
	 ** EVIDENCE-OF: R-53820-33897 Even if there is a busy-handler configured,
	 ** it will not be invoked in this case.
	 */
	if eMode != -int32(1) {
		rc = _walLockExclusive(tls, pWal, int32(WAL_CKPT_LOCK), int32(1))
		if rc == SQLITE_OK {
			(*TWal)(unsafe.Pointer(pWal)).FckptLock = uint8(1)
			/* IMPLEMENTATION-OF: R-59782-36818 The SQLITE_CHECKPOINT_FULL, RESTART
			 ** and TRUNCATE modes also obtain the exclusive "writer" lock on the
			 ** database file.
			 **
			 ** EVIDENCE-OF: R-60642-04082 If the writer lock cannot be obtained
			 ** immediately, and a busy-handler is configured, it is invoked and the
			 ** writer lock retried until either the busy-handler returns 0 or the
			 ** lock is successfully obtained.
			 */
			if eMode != SQLITE_CHECKPOINT_PASSIVE {
				rc = _walBusyLock(tls, pWal, xBusy2, pBusyArg, WAL_WRITE_LOCK, int32(1))
				if rc == SQLITE_OK {
					(*TWal)(unsafe.Pointer(pWal)).FwriteLock = uint8(1)
				} else {
					if rc == int32(SQLITE_BUSY) {
						eMode2 = SQLITE_CHECKPOINT_PASSIVE
						xBusy2 = uintptr(0)
						rc = SQLITE_OK
					}
				}
			}
		}
	} else {
		rc = SQLITE_OK
	}
	/* Read the wal-index header. */
	if rc == SQLITE_OK {
		/* For a passive checkpoint, do not re-enable blocking locks after
		 ** reading the wal-index header. A passive checkpoint should not block
		 ** or invoke the busy handler. The only lock such a checkpoint may
		 ** attempt to obtain is a lock on a read-slot, and it should give up
		 ** immediately and do a partial checkpoint if it cannot obtain it. */
		rc = _walIndexReadHdr(tls, pWal, bp)
		if eMode2 > SQLITE_CHECKPOINT_PASSIVE {
		}
		if **(**int32)(__ccgo_up(bp)) != 0 && (*Tsqlite3_io_methods)(unsafe.Pointer((*Tsqlite3_file)(unsafe.Pointer((*TWal)(unsafe.Pointer(pWal)).FpDbFd)).FpMethods)).FiVersion >= int32(3) {
			_sqlite3OsUnfetch(tls, (*TWal)(unsafe.Pointer(pWal)).FpDbFd, 0, uintptr(0))
		}
	}
	/* Copy data from the log to the database file. */
	if rc == SQLITE_OK {
		_sqlite3FaultSim(tls, int32(660))
		if (*TWal)(unsafe.Pointer(pWal)).Fhdr.FmxFrame != 0 && _walPagesize(tls, pWal) != nBuf {
			rc = _sqlite3CorruptError(tls, int32(71830))
		} else {
			if eMode2 != -int32(1) {
				rc = _walCheckpoint(tls, pWal, db, eMode2, xBusy2, pBusyArg, sync_flags, zBuf)
			}
		}
		/* If no error occurred, set the output variables. */
		if rc == SQLITE_OK || rc == int32(SQLITE_BUSY) {
			if pnLog != 0 {
				**(**int32)(__ccgo_up(pnLog)) = libc.Int32FromUint32((*TWal)(unsafe.Pointer(pWal)).Fhdr.FmxFrame)
			}
			if pnCkpt != 0 {
				**(**int32)(__ccgo_up(pnCkpt)) = libc.Int32FromUint32((*TWalCkptInfo)(unsafe.Pointer(_walCkptInfo(tls, pWal))).FnBackfill)
			}
		}
	}
	if **(**int32)(__ccgo_up(bp)) != 0 {
		/* If a new wal-index header was loaded before the checkpoint was
		 ** performed, then the pager-cache associated with pWal is now
		 ** out of date. So zero the cached wal-index header to ensure that
		 ** next time the pager opens a snapshot on this database it knows that
		 ** the cache needs to be reset.
		 */
		libc.Xmemset(tls, pWal+72, 0, uint64(48))
	}
	/* Release the locks. */
	_sqlite3WalEndWriteTransaction(tls, pWal)
	if (*TWal)(unsafe.Pointer(pWal)).FckptLock != 0 {
		_walUnlockExclusive(tls, pWal, int32(WAL_CKPT_LOCK), int32(1))
		(*TWal)(unsafe.Pointer(pWal)).FckptLock = uint8(0)
	}
	if rc == SQLITE_OK && eMode != eMode2 {
		v1 = int32(SQLITE_BUSY)
	} else {
		v1 = rc
	}
	return v1
}

// C documentation
//
//	/*
//	** Return ONEPASS_OFF (0) if an UPDATE or DELETE statement is unable to
//	** operate directly on the rowids returned by a WHERE clause.  Return
//	** ONEPASS_SINGLE (1) if the statement can operation directly because only
//	** a single row is to be changed.  Return ONEPASS_MULTI (2) if the one-pass
//	** optimization can be used on multiple
//	**
//	** If the ONEPASS optimization is used (if this routine returns true)
//	** then also write the indices of open cursors used by ONEPASS
//	** into aiCur[0] and aiCur[1].  iaCur[0] gets the cursor of the data
//	** table and iaCur[1] gets the cursor used by an auxiliary index.
//	** Either value may be -1, indicating that cursor is not used.
//	** Any cursors returned will have been opened for writing.
//	**
//	** aiCur[0] and aiCur[1] both get -1 if the where-clause logic is
//	** unable to use the ONEPASS optimization.
//	*/
func _sqlite3WhereOkOnePass(tls *libc.TLS, pWInfo uintptr, aiCur uintptr) (r int32) {
	libc.Xmemcpy(tls, aiCur, pWInfo+40, libc.Uint64FromInt64(4)*libc.Uint64FromInt32(2))
	return libc.Int32FromUint8((*TWhereInfo)(unsafe.Pointer(pWInfo)).FeOnePass)
}

// C documentation
//
//	/*
//	** sqlite3WhereBegin() has already been called for the SELECT statement
//	** passed as the second argument when this function is invoked. It generates
//	** code to populate the Window.regResult register for each window function
//	** and invoke the sub-routine at instruction addrGosub once for each row.
//	** sqlite3WhereEnd() is always called before returning.
//	**
//	** This function handles several different types of window frames, which
//	** require slightly different processing. The following pseudo code is
//	** used to implement window frames of the form:
//	**
//	**   ROWS BETWEEN <expr1> PRECEDING AND <expr2> FOLLOWING
//	**
//	** Other window frame types use variants of the following:
//	**
//	**     ... loop started by sqlite3WhereBegin() ...
//	**       if( new partition ){
//	**         Gosub flush
//	**       }
//	**       Insert new row into eph table.
//	**
//	**       if( first row of partition ){
//	**         // Rewind three cursors, all open on the eph table.
//	**         Rewind(csrEnd);
//	**         Rewind(csrStart);
//	**         Rewind(csrCurrent);
//	**
//	**         regEnd = <expr2>          // FOLLOWING expression
//	**         regStart = <expr1>        // PRECEDING expression
//	**       }else{
//	**         // First time this branch is taken, the eph table contains two
//	**         // rows. The first row in the partition, which all three cursors
//	**         // currently point to, and the following row.
//	**         AGGSTEP
//	**         if( (regEnd--)<=0 ){
//	**           RETURN_ROW
//	**           if( (regStart--)<=0 ){
//	**             AGGINVERSE
//	**           }
//	**         }
//	**       }
//	**     }
//	**     flush:
//	**       AGGSTEP
//	**       while( 1 ){
//	**         RETURN ROW
//	**         if( csrCurrent is EOF ) break;
//	**         if( (regStart--)<=0 ){
//	**           AggInverse(csrStart)
//	**           Next(csrStart)
//	**         }
//	**       }
//	**
//	** The pseudo-code above uses the following shorthand:
//	**
//	**   AGGSTEP:    invoke the aggregate xStep() function for each window function
//	**               with arguments read from the current row of cursor csrEnd, then
//	**               step cursor csrEnd forward one row (i.e. sqlite3BtreeNext()).
//	**
//	**   RETURN_ROW: return a row to the caller based on the contents of the
//	**               current row of csrCurrent and the current state of all
//	**               aggregates. Then step cursor csrCurrent forward one row.
//	**
//	**   AGGINVERSE: invoke the aggregate xInverse() function for each window
//	**               functions with arguments read from the current row of cursor
//	**               csrStart. Then step csrStart forward one row.
//	**
//	** There are two other ROWS window frames that are handled significantly
//	** differently from the above - "BETWEEN <expr> PRECEDING AND <expr> PRECEDING"
//	** and "BETWEEN <expr> FOLLOWING AND <expr> FOLLOWING". These are special
//	** cases because they change the order in which the three cursors (csrStart,
//	** csrCurrent and csrEnd) iterate through the ephemeral table. Cases that
//	** use UNBOUNDED or CURRENT ROW are much simpler variations on one of these
//	** three.
//	**
//	**   ROWS BETWEEN <expr1> PRECEDING AND <expr2> PRECEDING
//	**
//	**     ... loop started by sqlite3WhereBegin() ...
//	**       if( new partition ){
//	**         Gosub flush
//	**       }
//	**       Insert new row into eph table.
//	**       if( first row of partition ){
//	**         Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
//	**         regEnd = <expr2>
//	**         regStart = <expr1>
//	**       }else{
//	**         if( (regEnd--)<=0 ){
//	**           AGGSTEP
//	**         }
//	**         RETURN_ROW
//	**         if( (regStart--)<=0 ){
//	**           AGGINVERSE
//	**         }
//	**       }
//	**     }
//	**     flush:
//	**       if( (regEnd--)<=0 ){
//	**         AGGSTEP
//	**       }
//	**       RETURN_ROW
//	**
//	**
//	**   ROWS BETWEEN <expr1> FOLLOWING AND <expr2> FOLLOWING
//	**
//	**   ... loop started by sqlite3WhereBegin() ...
//	**     if( new partition ){
//	**       Gosub flush
//	**     }
//	**     Insert new row into eph table.
//	**     if( first row of partition ){
//	**       Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
//	**       regEnd = <expr2>
//	**       regStart = regEnd - <expr1>
//	**     }else{
//	**       AGGSTEP
//	**       if( (regEnd--)<=0 ){
//	**         RETURN_ROW
//	**       }
//	**       if( (regStart--)<=0 ){
//	**         AGGINVERSE
//	**       }
//	**     }
//	**   }
//	**   flush:
//	**     AGGSTEP
//	**     while( 1 ){
//	**       if( (regEnd--)<=0 ){
//	**         RETURN_ROW
//	**         if( eof ) break;
//	**       }
//	**       if( (regStart--)<=0 ){
//	**         AGGINVERSE
//	**         if( eof ) break
//	**       }
//	**     }
//	**     while( !eof csrCurrent ){
//	**       RETURN_ROW
//	**     }
//	**
//	** For the most part, the patterns above are adapted to support UNBOUNDED by
//	** assuming that it is equivalent to "infinity PRECEDING/FOLLOWING" and
//	** CURRENT ROW by assuming that it is equivalent to "0 PRECEDING/FOLLOWING".
//	** This is optimized of course - branches that will never be taken and
//	** conditions that are always true are omitted from the VM code. The only
//	** exceptional case is:
//	**
//	**   ROWS BETWEEN <expr1> FOLLOWING AND UNBOUNDED FOLLOWING
//	**
//	**     ... loop started by sqlite3WhereBegin() ...
//	**     if( new partition ){
//	**       Gosub flush
//	**     }
//	**     Insert new row into eph table.
//	**     if( first row of partition ){
//	**       Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
//	**       regStart = <expr1>
//	**     }else{
//	**       AGGSTEP
//	**     }
//	**   }
//	**   flush:
//	**     AGGSTEP
//	**     while( 1 ){
//	**       if( (regStart--)<=0 ){
//	**         AGGINVERSE
//	**         if( eof ) break
//	**       }
//	**       RETURN_ROW
//	**     }
//	**     while( !eof csrCurrent ){
//	**       RETURN_ROW
//	**     }
//	**
//	** Also requiring special handling are the cases:
//	**
//	**   ROWS BETWEEN <expr1> PRECEDING AND <expr2> PRECEDING
//	**   ROWS BETWEEN <expr1> FOLLOWING AND <expr2> FOLLOWING
//	**
//	** when (expr1 < expr2). This is detected at runtime, not by this function.
//	** To handle this case, the pseudo-code programs depicted above are modified
//	** slightly to be:
//	**
//	**     ... loop started by sqlite3WhereBegin() ...
//	**     if( new partition ){
//	**       Gosub flush
//	**     }
//	**     Insert new row into eph table.
//	**     if( first row of partition ){
//	**       Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
//	**       regEnd = <expr2>
//	**       regStart = <expr1>
//	**       if( regEnd < regStart ){
//	**         RETURN_ROW
//	**         delete eph table contents
//	**         continue
//	**       }
//	**     ...
//	**
//	** The new "continue" statement in the above jumps to the next iteration
//	** of the outer loop - the one started by sqlite3WhereBegin().
//	**
//	** The various GROUPS cases are implemented using the same patterns as
//	** ROWS. The VM code is modified slightly so that:
//	**
//	**   1. The else branch in the main loop is only taken if the row just
//	**      added to the ephemeral table is the start of a new group. In
//	**      other words, it becomes:
//	**
//	**         ... loop started by sqlite3WhereBegin() ...
//	**         if( new partition ){
//	**           Gosub flush
//	**         }
//	**         Insert new row into eph table.
//	**         if( first row of partition ){
//	**           Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
//	**           regEnd = <expr2>
//	**           regStart = <expr1>
//	**         }else if( new group ){
//	**           ...
//	**         }
//	**       }
//	**
//	**   2. Instead of processing a single row, each RETURN_ROW, AGGSTEP or
//	**      AGGINVERSE step processes the current row of the relevant cursor and
//	**      all subsequent rows belonging to the same group.
//	**
//	** RANGE window frames are a little different again. As for GROUPS, the
//	** main loop runs once per group only. And RETURN_ROW, AGGSTEP and AGGINVERSE
//	** deal in groups instead of rows. As for ROWS and GROUPS, there are three
//	** basic cases:
//	**
//	**   RANGE BETWEEN <expr1> PRECEDING AND <expr2> FOLLOWING
//	**
//	**     ... loop started by sqlite3WhereBegin() ...
//	**       if( new partition ){
//	**         Gosub flush
//	**       }
//	**       Insert new row into eph table.
//	**       if( first row of partition ){
//	**         Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
//	**         regEnd = <expr2>
//	**         regStart = <expr1>
//	**       }else{
//	**         AGGSTEP
//	**         while( (csrCurrent.key + regEnd) < csrEnd.key ){
//	**           RETURN_ROW
//	**           while( csrStart.key + regStart) < csrCurrent.key ){
//	**             AGGINVERSE
//	**           }
//	**         }
//	**       }
//	**     }
//	**     flush:
//	**       AGGSTEP
//	**       while( 1 ){
//	**         RETURN ROW
//	**         if( csrCurrent is EOF ) break;
//	**           while( csrStart.key + regStart) < csrCurrent.key ){
//	**             AGGINVERSE
//	**           }
//	**         }
//	**       }
//	**
//	** In the above notation, "csr.key" means the current value of the ORDER BY
//	** expression (there is only ever 1 for a RANGE that uses an <expr> FOLLOWING
//	** or <expr PRECEDING) read from cursor csr.
//	**
//	**   RANGE BETWEEN <expr1> PRECEDING AND <expr2> PRECEDING
//	**
//	**     ... loop started by sqlite3WhereBegin() ...
//	**       if( new partition ){
//	**         Gosub flush
//	**       }
//	**       Insert new row into eph table.
//	**       if( first row of partition ){
//	**         Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
//	**         regEnd = <expr2>
//	**         regStart = <expr1>
//	**       }else{
//	**         while( (csrEnd.key + regEnd) <= csrCurrent.key ){
//	**           AGGSTEP
//	**         }
//	**         while( (csrStart.key + regStart) < csrCurrent.key ){
//	**           AGGINVERSE
//	**         }
//	**         RETURN_ROW
//	**       }
//	**     }
//	**     flush:
//	**       while( (csrEnd.key + regEnd) <= csrCurrent.key ){
//	**         AGGSTEP
//	**       }
//	**       while( (csrStart.key + regStart) < csrCurrent.key ){
//	**         AGGINVERSE
//	**       }
//	**       RETURN_ROW
//	**
//	**   RANGE BETWEEN <expr1> FOLLOWING AND <expr2> FOLLOWING
//	**
//	**     ... loop started by sqlite3WhereBegin() ...
//	**       if( new partition ){
//	**         Gosub flush
//	**       }
//	**       Insert new row into eph table.
//	**       if( first row of partition ){
//	**         Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
//	**         regEnd = <expr2>
//	**         regStart = <expr1>
//	**       }else{
//	**         AGGSTEP
//	**         while( (csrCurrent.key + regEnd) < csrEnd.key ){
//	**           while( (csrCurrent.key + regStart) > csrStart.key ){
//	**             AGGINVERSE
//	**           }
//	**           RETURN_ROW
//	**         }
//	**       }
//	**     }
//	**     flush:
//	**       AGGSTEP
//	**       while( 1 ){
//	**         while( (csrCurrent.key + regStart) > csrStart.key ){
//	**           AGGINVERSE
//	**           if( eof ) break "while( 1 )" loop.
//	**         }
//	**         RETURN_ROW
//	**       }
//	**       while( !eof csrCurrent ){
//	**         RETURN_ROW
//	**       }
//	**
//	** The text above leaves out many details. Refer to the code and comments
//	** below for a more complete picture.
//	*/
func _sqlite3WindowCodeStep(tls *libc.TLS, pParse uintptr, p uintptr, pWInfo uintptr, regGosub int32, addrGosub int32) {
	bp := tls.Alloc(80)
	defer tls.Free(80)
	var addr, addr1, addrBreak, addrBreak1, addrBreak2, addrBreak3, addrEmpty, addrGe, addrGosubFlush, addrInteger, addrNe, addrNext, addrStart, addrStart1, bRPS, bRPS1, csrInput, csrWrite, iInput, lbl, lbl1, lblWhereEnd, nInput, nPart, nPeer, op, regEnd, regFlushPart, regNew, regNewPart, regNewPeer, regPeer, regRecord, regStart, v1 int32
	var pKeyInfo, pMWin, pOrderBy, pPart, v, v2 uintptr
	var _ /* s at bp+0 */ TWindowCodeArg
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = addr, addr1, addrBreak, addrBreak1, addrBreak2, addrBreak3, addrEmpty, addrGe, addrGosubFlush, addrInteger, addrNe, addrNext, addrStart, addrStart1, bRPS, bRPS1, csrInput, csrWrite, iInput, lbl, lbl1, lblWhereEnd, nInput, nPart, nPeer, op, pKeyInfo, pMWin, pOrderBy, pPart, regEnd, regFlushPart, regNew, regNewPart, regNewPeer, regPeer, regRecord, regStart, v, v1, v2
	pMWin = (*TSelect)(unsafe.Pointer(p)).FpWin
	pOrderBy = (*TWindow)(unsafe.Pointer(pMWin)).FpOrderBy
	v = _sqlite3GetVdbe(tls, pParse)                                                                                                /* Cursor used to write to eph. table */
	csrInput = (*(*TSrcItem)(unsafe.Pointer((*TSelect)(unsafe.Pointer(p)).FpSrc + 8))).FiCursor                                     /* Cursor of sub-select */
	nInput = int32((*TTable)(unsafe.Pointer((*(*TSrcItem)(unsafe.Pointer((*TSelect)(unsafe.Pointer(p)).FpSrc + 8))).FpSTab)).FnCol) /* Address of OP_Ne */
	addrGosubFlush = 0                                                                                                              /* Address of OP_Gosub to flush: */
	addrInteger = 0                                                                                                                 /* regNew array in record form */
	regNewPeer = 0                                                                                                                  /* Peer values for new row (part of regNew) */
	regPeer = 0                                                                                                                     /* Peer values for current row */
	regFlushPart = 0                                                                                                                /* Label just before sqlite3WhereEnd() code */
	regStart = 0                                                                                                                    /* Value of <expr> PRECEDING */
	regEnd = 0                                                                                                                      /* Value of <expr> FOLLOWING */
	lblWhereEnd = _sqlite3VdbeMakeLabel(tls, pParse)
	/* Fill in the context object */
	libc.Xmemset(tls, bp, 0, uint64(72))
	(**(**TWindowCodeArg)(__ccgo_up(bp))).FpParse = pParse
	(**(**TWindowCodeArg)(__ccgo_up(bp))).FpMWin = pMWin
	(**(**TWindowCodeArg)(__ccgo_up(bp))).FpVdbe = v
	(**(**TWindowCodeArg)(__ccgo_up(bp))).FregGosub = regGosub
	(**(**TWindowCodeArg)(__ccgo_up(bp))).FaddrGosub = addrGosub
	(**(**TWindowCodeArg)(__ccgo_up(bp))).Fcurrent.Fcsr = (*TWindow)(unsafe.Pointer(pMWin)).FiEphCsr
	csrWrite = (**(**TWindowCodeArg)(__ccgo_up(bp))).Fcurrent.Fcsr + int32(1)
	(**(**TWindowCodeArg)(__ccgo_up(bp))).Fstart.Fcsr = (**(**TWindowCodeArg)(__ccgo_up(bp))).Fcurrent.Fcsr + int32(2)
	(**(**TWindowCodeArg)(__ccgo_up(bp))).Fend.Fcsr = (**(**TWindowCodeArg)(__ccgo_up(bp))).Fcurrent.Fcsr + int32(3)
	/* Figure out when rows may be deleted from the ephemeral table. There
	 ** are four options - they may never be deleted (eDelete==0), they may
	 ** be deleted as soon as they are no longer part of the window frame
	 ** (eDelete==WINDOW_AGGINVERSE), they may be deleted as after the row
	 ** has been returned to the caller (WINDOW_RETURN_ROW), or they may
	 ** be deleted after they enter the frame (WINDOW_AGGSTEP). */
	switch libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeStart) {
	case int32(TK_FOLLOWING):
		if libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeFrmType) != int32(TK_RANGE) && _windowExprGtZero(tls, pParse, (*TWindow)(unsafe.Pointer(pMWin)).FpStart) != 0 {
			(**(**TWindowCodeArg)(__ccgo_up(bp))).FeDelete = int32(WINDOW_RETURN_ROW)
		}
	case int32(TK_UNBOUNDED):
		if _windowCacheFrame(tls, pMWin) == 0 {
			if libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeEnd) == int32(TK_PRECEDING) {
				if libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeFrmType) != int32(TK_RANGE) && _windowExprGtZero(tls, pParse, (*TWindow)(unsafe.Pointer(pMWin)).FpEnd) != 0 {
					(**(**TWindowCodeArg)(__ccgo_up(bp))).FeDelete = int32(WINDOW_AGGSTEP)
				}
			} else {
				(**(**TWindowCodeArg)(__ccgo_up(bp))).FeDelete = int32(WINDOW_RETURN_ROW)
			}
		}
	default:
		(**(**TWindowCodeArg)(__ccgo_up(bp))).FeDelete = int32(WINDOW_AGGINVERSE)
		break
	}
	/* Allocate registers for the array of values from the sub-query, the
	 ** same values in record form, and the rowid used to insert said record
	 ** into the ephemeral table.  */
	regNew = (*TParse)(unsafe.Pointer(pParse)).FnMem + int32(1)
	**(**int32)(__ccgo_up(pParse + 60)) += nInput
	v2 = pParse + 60
	*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1
	v1 = *(*int32)(unsafe.Pointer(v2))
	regRecord = v1
	v2 = pParse + 60
	*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1
	v1 = *(*int32)(unsafe.Pointer(v2))
	(**(**TWindowCodeArg)(__ccgo_up(bp))).FregRowid = v1
	/* If the window frame contains an "<expr> PRECEDING" or "<expr> FOLLOWING"
	 ** clause, allocate registers to store the results of evaluating each
	 ** <expr>.  */
	if libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeStart) == int32(TK_PRECEDING) || libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeStart) == int32(TK_FOLLOWING) {
		v2 = pParse + 60
		*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1
		v1 = *(*int32)(unsafe.Pointer(v2))
		regStart = v1
	}
	if libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeEnd) == int32(TK_PRECEDING) || libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeEnd) == int32(TK_FOLLOWING) {
		v2 = pParse + 60
		*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1
		v1 = *(*int32)(unsafe.Pointer(v2))
		regEnd = v1
	}
	/* If this is not a "ROWS BETWEEN ..." frame, then allocate arrays of
	 ** registers to store copies of the ORDER BY expressions (peer values)
	 ** for the main loop, and for each cursor (start, current and end). */
	if libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeFrmType) != int32(TK_ROWS) {
		if pOrderBy != 0 {
			v1 = (*TExprList)(unsafe.Pointer(pOrderBy)).FnExpr
		} else {
			v1 = 0
		}
		nPeer = v1
		regNewPeer = regNew + (*TWindow)(unsafe.Pointer(pMWin)).FnBufferCol
		if (*TWindow)(unsafe.Pointer(pMWin)).FpPartition != 0 {
			regNewPeer = regNewPeer + (*TExprList)(unsafe.Pointer((*TWindow)(unsafe.Pointer(pMWin)).FpPartition)).FnExpr
		}
		regPeer = (*TParse)(unsafe.Pointer(pParse)).FnMem + int32(1)
		**(**int32)(__ccgo_up(pParse + 60)) += nPeer
		(**(**TWindowCodeArg)(__ccgo_up(bp))).Fstart.Freg = (*TParse)(unsafe.Pointer(pParse)).FnMem + int32(1)
		**(**int32)(__ccgo_up(pParse + 60)) += nPeer
		(**(**TWindowCodeArg)(__ccgo_up(bp))).Fcurrent.Freg = (*TParse)(unsafe.Pointer(pParse)).FnMem + int32(1)
		**(**int32)(__ccgo_up(pParse + 60)) += nPeer
		(**(**TWindowCodeArg)(__ccgo_up(bp))).Fend.Freg = (*TParse)(unsafe.Pointer(pParse)).FnMem + int32(1)
		**(**int32)(__ccgo_up(pParse + 60)) += nPeer
	}
	/* Load the column values for the row returned by the sub-select
	 ** into an array of registers starting at regNew. Assemble them into
	 ** a record in register regRecord. */
	iInput = 0
	for {
		if !(iInput < nInput) {
			break
		}
		_sqlite3VdbeAddOp3(tls, v, int32(OP_Column), csrInput, iInput, regNew+iInput)
		goto _10
	_10:
		;
		iInput = iInput + 1
	}
	_sqlite3VdbeAddOp3(tls, v, int32(OP_MakeRecord), regNew, nInput, regRecord)
	/* An input row has just been read into an array of registers starting
	 ** at regNew. If the window has a PARTITION clause, this block generates
	 ** VM code to check if the input row is the start of a new partition.
	 ** If so, it does an OP_Gosub to an address to be filled in later. The
	 ** address of the OP_Gosub is stored in local variable addrGosubFlush. */
	if (*TWindow)(unsafe.Pointer(pMWin)).FpPartition != 0 {
		pPart = (*TWindow)(unsafe.Pointer(pMWin)).FpPartition
		nPart = (*TExprList)(unsafe.Pointer(pPart)).FnExpr
		regNewPart = regNew + (*TWindow)(unsafe.Pointer(pMWin)).FnBufferCol
		pKeyInfo = _sqlite3KeyInfoFromExprList(tls, pParse, pPart, 0, 0)
		v2 = pParse + 60
		*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1
		v1 = *(*int32)(unsafe.Pointer(v2))
		regFlushPart = v1
		addr = _sqlite3VdbeAddOp3(tls, v, int32(OP_Compare), regNewPart, (*TWindow)(unsafe.Pointer(pMWin)).FregPart, nPart)
		_sqlite3VdbeAppendP4(tls, v, pKeyInfo, -int32(9))
		_sqlite3VdbeAddOp3(tls, v, int32(OP_Jump), addr+int32(2), addr+int32(4), addr+int32(2))
		addrGosubFlush = _sqlite3VdbeAddOp1(tls, v, int32(OP_Gosub), regFlushPart)
		_sqlite3VdbeAddOp3(tls, v, int32(OP_Copy), regNewPart, (*TWindow)(unsafe.Pointer(pMWin)).FregPart, nPart-int32(1))
	}
	/* Insert the new row into the ephemeral table */
	_sqlite3VdbeAddOp2(tls, v, int32(OP_NewRowid), csrWrite, (**(**TWindowCodeArg)(__ccgo_up(bp))).FregRowid)
	_sqlite3VdbeAddOp3(tls, v, int32(OP_Insert), csrWrite, regRecord, (**(**TWindowCodeArg)(__ccgo_up(bp))).FregRowid)
	addrNe = _sqlite3VdbeAddOp3(tls, v, int32(OP_Ne), (*TWindow)(unsafe.Pointer(pMWin)).FregOne, 0, (**(**TWindowCodeArg)(__ccgo_up(bp))).FregRowid)
	/* This block is run for the first row of each partition */
	(**(**TWindowCodeArg)(__ccgo_up(bp))).FregArg = _windowInitAccum(tls, pParse, pMWin)
	if regStart != 0 {
		_sqlite3ExprCode(tls, pParse, (*TWindow)(unsafe.Pointer(pMWin)).FpStart, regStart)
		if libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeFrmType) == int32(TK_RANGE) {
			v1 = int32(3)
		} else {
			v1 = 0
		}
		_windowCheckValue(tls, pParse, regStart, 0+v1)
	}
	if regEnd != 0 {
		_sqlite3ExprCode(tls, pParse, (*TWindow)(unsafe.Pointer(pMWin)).FpEnd, regEnd)
		if libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeFrmType) == int32(TK_RANGE) {
			v1 = int32(3)
		} else {
			v1 = 0
		}
		_windowCheckValue(tls, pParse, regEnd, int32(1)+v1)
	}
	if libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeFrmType) != int32(TK_RANGE) && libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeStart) == libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeEnd) && regStart != 0 {
		if libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeStart) == int32(TK_FOLLOWING) {
			v1 = int32(OP_Ge)
		} else {
			v1 = int32(OP_Le)
		}
		op = v1
		addrGe = _sqlite3VdbeAddOp3(tls, v, op, regStart, 0, regEnd)
		/* NeverNull because bound <expr> */
		/*   values previously checked */
		_windowAggFinal(tls, bp, 0)
		_sqlite3VdbeAddOp1(tls, v, int32(OP_Rewind), (**(**TWindowCodeArg)(__ccgo_up(bp))).Fcurrent.Fcsr)
		_windowReturnOneRow(tls, bp)
		_sqlite3VdbeAddOp1(tls, v, int32(OP_ResetSorter), (**(**TWindowCodeArg)(__ccgo_up(bp))).Fcurrent.Fcsr)
		_sqlite3VdbeAddOp2(tls, v, int32(OP_Goto), 0, lblWhereEnd)
		_sqlite3VdbeJumpHere(tls, v, addrGe)
	}
	if libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeStart) == int32(TK_FOLLOWING) && libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeFrmType) != int32(TK_RANGE) && regEnd != 0 {
		_sqlite3VdbeAddOp3(tls, v, int32(OP_Subtract), regStart, regEnd, regStart)
	}
	if libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeStart) != int32(TK_UNBOUNDED) {
		_sqlite3VdbeAddOp1(tls, v, int32(OP_Rewind), (**(**TWindowCodeArg)(__ccgo_up(bp))).Fstart.Fcsr)
	}
	_sqlite3VdbeAddOp1(tls, v, int32(OP_Rewind), (**(**TWindowCodeArg)(__ccgo_up(bp))).Fcurrent.Fcsr)
	_sqlite3VdbeAddOp1(tls, v, int32(OP_Rewind), (**(**TWindowCodeArg)(__ccgo_up(bp))).Fend.Fcsr)
	if regPeer != 0 && pOrderBy != 0 {
		_sqlite3VdbeAddOp3(tls, v, int32(OP_Copy), regNewPeer, regPeer, (*TExprList)(unsafe.Pointer(pOrderBy)).FnExpr-int32(1))
		_sqlite3VdbeAddOp3(tls, v, int32(OP_Copy), regPeer, (**(**TWindowCodeArg)(__ccgo_up(bp))).Fstart.Freg, (*TExprList)(unsafe.Pointer(pOrderBy)).FnExpr-int32(1))
		_sqlite3VdbeAddOp3(tls, v, int32(OP_Copy), regPeer, (**(**TWindowCodeArg)(__ccgo_up(bp))).Fcurrent.Freg, (*TExprList)(unsafe.Pointer(pOrderBy)).FnExpr-int32(1))
		_sqlite3VdbeAddOp3(tls, v, int32(OP_Copy), regPeer, (**(**TWindowCodeArg)(__ccgo_up(bp))).Fend.Freg, (*TExprList)(unsafe.Pointer(pOrderBy)).FnExpr-int32(1))
	}
	_sqlite3VdbeAddOp2(tls, v, int32(OP_Goto), 0, lblWhereEnd)
	_sqlite3VdbeJumpHere(tls, v, addrNe)
	/* Beginning of the block executed for the second and subsequent rows. */
	if regPeer != 0 {
		_windowIfNewPeer(tls, pParse, pOrderBy, regNewPeer, regPeer, lblWhereEnd)
	}
	if libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeStart) == int32(TK_FOLLOWING) {
		_windowCodeOp(tls, bp, int32(WINDOW_AGGSTEP), 0, 0)
		if libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeEnd) != int32(TK_UNBOUNDED) {
			if libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeFrmType) == int32(TK_RANGE) {
				lbl = _sqlite3VdbeMakeLabel(tls, pParse)
				addrNext = _sqlite3VdbeCurrentAddr(tls, v)
				_windowCodeRangeTest(tls, bp, int32(OP_Ge), (**(**TWindowCodeArg)(__ccgo_up(bp))).Fcurrent.Fcsr, regEnd, (**(**TWindowCodeArg)(__ccgo_up(bp))).Fend.Fcsr, lbl)
				_windowCodeOp(tls, bp, int32(WINDOW_AGGINVERSE), regStart, 0)
				_windowCodeOp(tls, bp, int32(WINDOW_RETURN_ROW), 0, 0)
				_sqlite3VdbeAddOp2(tls, v, int32(OP_Goto), 0, addrNext)
				_sqlite3VdbeResolveLabel(tls, v, lbl)
			} else {
				_windowCodeOp(tls, bp, int32(WINDOW_RETURN_ROW), regEnd, 0)
				_windowCodeOp(tls, bp, int32(WINDOW_AGGINVERSE), regStart, 0)
			}
		}
	} else {
		if libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeEnd) == int32(TK_PRECEDING) {
			bRPS = libc.BoolInt32(libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeStart) == int32(TK_PRECEDING) && libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeFrmType) == int32(TK_RANGE))
			_windowCodeOp(tls, bp, int32(WINDOW_AGGSTEP), regEnd, 0)
			if bRPS != 0 {
				_windowCodeOp(tls, bp, int32(WINDOW_AGGINVERSE), regStart, 0)
			}
			_windowCodeOp(tls, bp, int32(WINDOW_RETURN_ROW), 0, 0)
			if !(bRPS != 0) {
				_windowCodeOp(tls, bp, int32(WINDOW_AGGINVERSE), regStart, 0)
			}
		} else {
			addr1 = 0
			_windowCodeOp(tls, bp, int32(WINDOW_AGGSTEP), 0, 0)
			if libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeEnd) != int32(TK_UNBOUNDED) {
				if libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeFrmType) == int32(TK_RANGE) {
					lbl1 = 0
					addr1 = _sqlite3VdbeCurrentAddr(tls, v)
					if regEnd != 0 {
						lbl1 = _sqlite3VdbeMakeLabel(tls, pParse)
						_windowCodeRangeTest(tls, bp, int32(OP_Ge), (**(**TWindowCodeArg)(__ccgo_up(bp))).Fcurrent.Fcsr, regEnd, (**(**TWindowCodeArg)(__ccgo_up(bp))).Fend.Fcsr, lbl1)
					}
					_windowCodeOp(tls, bp, int32(WINDOW_RETURN_ROW), 0, 0)
					_windowCodeOp(tls, bp, int32(WINDOW_AGGINVERSE), regStart, 0)
					if regEnd != 0 {
						_sqlite3VdbeAddOp2(tls, v, int32(OP_Goto), 0, addr1)
						_sqlite3VdbeResolveLabel(tls, v, lbl1)
					}
				} else {
					if regEnd != 0 {
						addr1 = _sqlite3VdbeAddOp3(tls, v, int32(OP_IfPos), regEnd, 0, int32(1))
					}
					_windowCodeOp(tls, bp, int32(WINDOW_RETURN_ROW), 0, 0)
					_windowCodeOp(tls, bp, int32(WINDOW_AGGINVERSE), regStart, 0)
					if regEnd != 0 {
						_sqlite3VdbeJumpHere(tls, v, addr1)
					}
				}
			}
		}
	}
	/* End of the main input loop */
	_sqlite3VdbeResolveLabel(tls, v, lblWhereEnd)
	_sqlite3WhereEnd(tls, pWInfo)
	/* Fall through */
	if (*TWindow)(unsafe.Pointer(pMWin)).FpPartition != 0 {
		addrInteger = _sqlite3VdbeAddOp2(tls, v, int32(OP_Integer), 0, regFlushPart)
		_sqlite3VdbeJumpHere(tls, v, addrGosubFlush)
	}
	(**(**TWindowCodeArg)(__ccgo_up(bp))).FregRowid = 0
	addrEmpty = _sqlite3VdbeAddOp1(tls, v, int32(OP_Rewind), csrWrite)
	if libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeEnd) == int32(TK_PRECEDING) {
		bRPS1 = libc.BoolInt32(libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeStart) == int32(TK_PRECEDING) && libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeFrmType) == int32(TK_RANGE))
		_windowCodeOp(tls, bp, int32(WINDOW_AGGSTEP), regEnd, 0)
		if bRPS1 != 0 {
			_windowCodeOp(tls, bp, int32(WINDOW_AGGINVERSE), regStart, 0)
		}
		_windowCodeOp(tls, bp, int32(WINDOW_RETURN_ROW), 0, 0)
	} else {
		if libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeStart) == int32(TK_FOLLOWING) {
			_windowCodeOp(tls, bp, int32(WINDOW_AGGSTEP), 0, 0)
			if libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeFrmType) == int32(TK_RANGE) {
				addrStart = _sqlite3VdbeCurrentAddr(tls, v)
				addrBreak2 = _windowCodeOp(tls, bp, int32(WINDOW_AGGINVERSE), regStart, int32(1))
				addrBreak1 = _windowCodeOp(tls, bp, int32(WINDOW_RETURN_ROW), 0, int32(1))
			} else {
				if libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeEnd) == int32(TK_UNBOUNDED) {
					addrStart = _sqlite3VdbeCurrentAddr(tls, v)
					addrBreak1 = _windowCodeOp(tls, bp, int32(WINDOW_RETURN_ROW), regStart, int32(1))
					addrBreak2 = _windowCodeOp(tls, bp, int32(WINDOW_AGGINVERSE), 0, int32(1))
				} else {
					/* assert( regStart>=0 );
					 ** regEnd = regEnd - regStart;
					 ** regStart = 0;   */
					_sqlite3VdbeAddOp3(tls, v, int32(OP_Subtract), regStart, regEnd, regEnd)
					_sqlite3VdbeAddOp2(tls, v, int32(OP_Integer), 0, regStart)
					addrStart = _sqlite3VdbeCurrentAddr(tls, v)
					addrBreak1 = _windowCodeOp(tls, bp, int32(WINDOW_RETURN_ROW), regEnd, int32(1))
					addrBreak2 = _windowCodeOp(tls, bp, int32(WINDOW_AGGINVERSE), regStart, int32(1))
				}
			}
			_sqlite3VdbeAddOp2(tls, v, int32(OP_Goto), 0, addrStart)
			_sqlite3VdbeJumpHere(tls, v, addrBreak2)
			addrStart = _sqlite3VdbeCurrentAddr(tls, v)
			addrBreak3 = _windowCodeOp(tls, bp, int32(WINDOW_RETURN_ROW), 0, int32(1))
			_sqlite3VdbeAddOp2(tls, v, int32(OP_Goto), 0, addrStart)
			_sqlite3VdbeJumpHere(tls, v, addrBreak1)
			_sqlite3VdbeJumpHere(tls, v, addrBreak3)
		} else {
			_windowCodeOp(tls, bp, int32(WINDOW_AGGSTEP), 0, 0)
			addrStart1 = _sqlite3VdbeCurrentAddr(tls, v)
			addrBreak = _windowCodeOp(tls, bp, int32(WINDOW_RETURN_ROW), 0, int32(1))
			_windowCodeOp(tls, bp, int32(WINDOW_AGGINVERSE), regStart, 0)
			_sqlite3VdbeAddOp2(tls, v, int32(OP_Goto), 0, addrStart1)
			_sqlite3VdbeJumpHere(tls, v, addrBreak)
		}
	}
	_sqlite3VdbeJumpHere(tls, v, addrEmpty)
	_sqlite3VdbeAddOp1(tls, v, int32(OP_ResetSorter), (**(**TWindowCodeArg)(__ccgo_up(bp))).Fcurrent.Fcsr)
	if (*TWindow)(unsafe.Pointer(pMWin)).FpPartition != 0 {
		if (*TWindow)(unsafe.Pointer(pMWin)).FregStartRowid != 0 {
			_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)
		}
		_sqlite3VdbeChangeP1(tls, v, addrInteger, _sqlite3VdbeCurrentAddr(tls, v))
		_sqlite3VdbeAddOp1(tls, v, int32(OP_Return), regFlushPart)
	}
}

/************** End of window.c **********************************************/
/************** Begin file parse.c *******************************************/
/* This file is automatically generated by Lemon from input grammar
** source file "parse.y".
 */
/*
** 2001-09-15
**
** 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 SQLite's SQL parser.
**
** The canonical source code to this file ("parse.y") is a Lemon grammar
** file that specifies the input grammar and actions to take while parsing.
** That input file is processed by Lemon to generate a C-language
** implementation of a parser for the given grammar.  You might be reading
** this comment as part of the translated C-code.  Edits should be made
** to the original parse.y sources.
 */

/* #include "sqliteInt.h" */

/*
** Verify that the pParse->isCreate field is set
 */

/*
** Disable all error recovery processing in the parser push-down
** automaton.
 */

/*
** Make yytestcase() the same as testcase()
 */

/*
** Indicate that sqlite3ParserFree() will never be called with a null
** pointer.
 */

/*
** In the amalgamation, the parse.c file generated by lemon and the
** tokenize.c file are concatenated.  In that case, sqlite3RunParser()
** has access to the the size of the yyParser object and so the parser
** engine can be allocated from stack.  In that case, only the
** sqlite3ParserInit() and sqlite3ParserFinalize() routines are invoked
** and the sqlite3ParserAlloc() and sqlite3ParserFree() routines can be
** omitted.
 */

/*
** Alternative datatype for the argument to the malloc() routine passed
** into sqlite3ParserAlloc().  The default is size_t.
 */

// C documentation
//
//	/* Populate the StatPage object with information about the all
//	** cells found on the page currently under analysis.
//	*/
func _statDecodePage(tls *libc.TLS, pBt uintptr, p uintptr) (r int32) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var aData, aHdr, pCell uintptr
	var i, iNext, iOff, isLeaf, j, nHdr, nLocal, nOvfl, nUnused, nUsable, rc, szPage, v1 int32
	var iPrev Tu32
	var v2 uint32
	var _ /* dummy at bp+8 */ Tu64
	var _ /* nPayload at bp+0 */ Tu32
	var _ /* pPg at bp+16 */ uintptr
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = aData, aHdr, i, iNext, iOff, iPrev, isLeaf, j, nHdr, nLocal, nOvfl, nUnused, nUsable, pCell, rc, szPage, v1, v2
	aData = (*TStatPage)(unsafe.Pointer(p)).FaPg
	if (*TStatPage)(unsafe.Pointer(p)).FiPgno == uint32(1) {
		v1 = int32(100)
	} else {
		v1 = 0
	}
	aHdr = aData + uintptr(v1)
	(*TStatPage)(unsafe.Pointer(p)).Fflags = **(**Tu8)(__ccgo_up(aHdr))
	if libc.Int32FromUint8((*TStatPage)(unsafe.Pointer(p)).Fflags) == int32(0x0A) || libc.Int32FromUint8((*TStatPage)(unsafe.Pointer(p)).Fflags) == int32(0x0D) {
		isLeaf = int32(1)
		nHdr = int32(8)
	} else {
		if libc.Int32FromUint8((*TStatPage)(unsafe.Pointer(p)).Fflags) == int32(0x05) || libc.Int32FromUint8((*TStatPage)(unsafe.Pointer(p)).Fflags) == int32(0x02) {
			isLeaf = 0
			nHdr = int32(12)
		} else {
			goto statPageIsCorrupt
		}
	}
	if (*TStatPage)(unsafe.Pointer(p)).FiPgno == uint32(1) {
		nHdr = nHdr + int32(100)
	}
	(*TStatPage)(unsafe.Pointer(p)).FnCell = libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aHdr + 3)))<<int32(8) | libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aHdr + 3 + 1)))
	(*TStatPage)(unsafe.Pointer(p)).FnMxPayload = 0
	szPage = _sqlite3BtreeGetPageSize(tls, pBt)
	nUnused = libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aHdr + 5)))<<int32(8) | libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aHdr + 5 + 1))) - nHdr - int32(2)*(*TStatPage)(unsafe.Pointer(p)).FnCell
	nUnused = nUnused + libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aHdr + 7)))
	iOff = libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aHdr + 1)))<<int32(8) | libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aHdr + 1 + 1)))
	for iOff != 0 {
		if iOff >= szPage {
			goto statPageIsCorrupt
		}
		nUnused = nUnused + (libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aData + uintptr(iOff+int32(2)))))<<int32(8) | libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aData + uintptr(iOff+int32(2)) + 1))))
		iNext = libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aData + uintptr(iOff))))<<int32(8) | libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aData + uintptr(iOff) + 1)))
		if iNext < iOff+int32(4) && iNext > 0 {
			goto statPageIsCorrupt
		}
		iOff = iNext
	}
	(*TStatPage)(unsafe.Pointer(p)).FnUnused = nUnused
	if isLeaf != 0 {
		v2 = uint32(0)
	} else {
		v2 = _sqlite3Get4byte(tls, aHdr+8)
	}
	(*TStatPage)(unsafe.Pointer(p)).FiRightChildPg = v2
	if (*TStatPage)(unsafe.Pointer(p)).FnCell != 0 { /* Usable bytes per page */
		_sqlite3BtreeEnter(tls, pBt)
		nUsable = szPage - _sqlite3BtreeGetReserveNoMutex(tls, pBt)
		_sqlite3BtreeLeave(tls, pBt)
		(*TStatPage)(unsafe.Pointer(p)).FaCell = Xsqlite3_malloc64(tls, uint64(libc.Uint64FromInt32((*TStatPage)(unsafe.Pointer(p)).FnCell+libc.Int32FromInt32(1))*uint64(32)))
		if (*TStatPage)(unsafe.Pointer(p)).FaCell == uintptr(0) {
			return int32(SQLITE_NOMEM)
		}
		libc.Xmemset(tls, (*TStatPage)(unsafe.Pointer(p)).FaCell, 0, libc.Uint64FromInt32((*TStatPage)(unsafe.Pointer(p)).FnCell+libc.Int32FromInt32(1))*uint64(32))
		i = 0
		for {
			if !(i < (*TStatPage)(unsafe.Pointer(p)).FnCell) {
				break
			}
			pCell = (*TStatPage)(unsafe.Pointer(p)).FaCell + uintptr(i)*32
			iOff = libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aData + uintptr(nHdr+i*int32(2)))))<<int32(8) | libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aData + uintptr(nHdr+i*int32(2)) + 1)))
			if iOff < nHdr || iOff >= szPage {
				goto statPageIsCorrupt
			}
			if !(isLeaf != 0) {
				(*TStatCell)(unsafe.Pointer(pCell)).FiChildPg = _sqlite3Get4byte(tls, aData+uintptr(iOff))
				iOff = iOff + int32(4)
			}
			if libc.Int32FromUint8((*TStatPage)(unsafe.Pointer(p)).Fflags) == int32(0x05) {
				/* A table interior node. nPayload==0. */
			} else { /* Bytes of payload stored locally */
				if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aData + uintptr(iOff)))) < libc.Int32FromUint8(libc.Uint8FromInt32(0x80)) {
					**(**Tu32)(__ccgo_up(bp)) = uint32(**(**Tu8)(__ccgo_up(aData + uintptr(iOff))))
					v1 = libc.Int32FromInt32(1)
				} else {
					v1 = libc.Int32FromUint8(_sqlite3GetVarint32(tls, aData+uintptr(iOff), bp))
				}
				iOff = iOff + libc.Int32FromUint8(libc.Uint8FromInt32(v1))
				if libc.Int32FromUint8((*TStatPage)(unsafe.Pointer(p)).Fflags) == int32(0x0D) {
					iOff = iOff + libc.Int32FromUint8(_sqlite3GetVarint(tls, aData+uintptr(iOff), bp+8))
				}
				if **(**Tu32)(__ccgo_up(bp)) > libc.Uint32FromInt32((*TStatPage)(unsafe.Pointer(p)).FnMxPayload) {
					(*TStatPage)(unsafe.Pointer(p)).FnMxPayload = libc.Int32FromUint32(**(**Tu32)(__ccgo_up(bp)))
				}
				nLocal = _getLocalPayload(tls, nUsable, (*TStatPage)(unsafe.Pointer(p)).Fflags, libc.Int32FromUint32(**(**Tu32)(__ccgo_up(bp))))
				if nLocal < 0 {
					goto statPageIsCorrupt
				}
				(*TStatCell)(unsafe.Pointer(pCell)).FnLocal = nLocal
				if **(**Tu32)(__ccgo_up(bp)) > libc.Uint32FromInt32(nLocal) {
					nOvfl = libc.Int32FromUint32((**(**Tu32)(__ccgo_up(bp)) - libc.Uint32FromInt32(nLocal) + libc.Uint32FromInt32(nUsable) - uint32(4) - uint32(1)) / libc.Uint32FromInt32(nUsable-libc.Int32FromInt32(4)))
					if iOff+nLocal+int32(4) > nUsable || **(**Tu32)(__ccgo_up(bp)) > uint32(0x7fffffff) {
						goto statPageIsCorrupt
					}
					(*TStatCell)(unsafe.Pointer(pCell)).FnLastOvfl = libc.Int32FromUint32(**(**Tu32)(__ccgo_up(bp)) - libc.Uint32FromInt32(nLocal) - libc.Uint32FromInt32((nOvfl-int32(1))*(nUsable-int32(4))))
					(*TStatCell)(unsafe.Pointer(pCell)).FnOvfl = nOvfl
					(*TStatCell)(unsafe.Pointer(pCell)).FaOvfl = Xsqlite3_malloc64(tls, uint64(uint64(4)*libc.Uint64FromInt32(nOvfl)))
					if (*TStatCell)(unsafe.Pointer(pCell)).FaOvfl == uintptr(0) {
						return int32(SQLITE_NOMEM)
					}
					**(**Tu32)(__ccgo_up((*TStatCell)(unsafe.Pointer(pCell)).FaOvfl)) = _sqlite3Get4byte(tls, aData+uintptr(iOff+nLocal))
					j = int32(1)
					for {
						if !(j < nOvfl) {
							break
						}
						iPrev = **(**Tu32)(__ccgo_up((*TStatCell)(unsafe.Pointer(pCell)).FaOvfl + uintptr(j-int32(1))*4))
						**(**uintptr)(__ccgo_up(bp + 16)) = uintptr(0)
						rc = _sqlite3PagerGet(tls, _sqlite3BtreePager(tls, pBt), iPrev, bp+16, 0)
						if rc != SQLITE_OK {
							return rc
						}
						**(**Tu32)(__ccgo_up((*TStatCell)(unsafe.Pointer(pCell)).FaOvfl + uintptr(j)*4)) = _sqlite3Get4byte(tls, _sqlite3PagerGetData(tls, **(**uintptr)(__ccgo_up(bp + 16))))
						_sqlite3PagerUnref(tls, **(**uintptr)(__ccgo_up(bp + 16)))
						goto _5
					_5:
						;
						j = j + 1
					}
				}
			}
			goto _3
		_3:
			;
			i = i + 1
		}
	}
	return SQLITE_OK
	goto statPageIsCorrupt
statPageIsCorrupt:
	;
	(*TStatPage)(unsafe.Pointer(p)).Fflags = uint8(0)
	_statClearCells(tls, p)
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** Load a copy of the page data for page iPg into the buffer belonging
//	** to page object pPg. Allocate the buffer if necessary. Return SQLITE_OK
//	** if successful, or an SQLite error code otherwise.
//	*/
func _statGetPage(tls *libc.TLS, pBt uintptr, iPg Tu32, pPg uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var a uintptr
	var pgsz, rc int32
	var _ /* pDbPage at bp+0 */ uintptr
	_, _, _ = a, pgsz, rc
	pgsz = _sqlite3BtreeGetPageSize(tls, pBt)
	**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
	if (*TStatPage)(unsafe.Pointer(pPg)).FaPg == uintptr(0) {
		(*TStatPage)(unsafe.Pointer(pPg)).FaPg = Xsqlite3_malloc(tls, pgsz+int32(DBSTAT_PAGE_PADDING_BYTES))
		if (*TStatPage)(unsafe.Pointer(pPg)).FaPg == uintptr(0) {
			return int32(SQLITE_NOMEM)
		}
		libc.Xmemset(tls, (*TStatPage)(unsafe.Pointer(pPg)).FaPg+uintptr(pgsz), 0, uint64(DBSTAT_PAGE_PADDING_BYTES))
	}
	rc = _sqlite3PagerGet(tls, _sqlite3BtreePager(tls, pBt), iPg, bp, 0)
	if rc == SQLITE_OK {
		a = _sqlite3PagerGetData(tls, **(**uintptr)(__ccgo_up(bp)))
		libc.Xmemcpy(tls, (*TStatPage)(unsafe.Pointer(pPg)).FaPg, a, libc.Uint64FromInt32(pgsz))
		_sqlite3PagerUnref(tls, **(**uintptr)(__ccgo_up(bp)))
	}
	return rc
}

// C documentation
//
//	/*
//	** Sync the journal. In other words, make sure all the pages that have
//	** been written to the journal have actually reached the surface of the
//	** disk and can be restored in the event of a hot-journal rollback.
//	**
//	** If the Pager.noSync flag is set, then this function is a no-op.
//	** Otherwise, the actions required depend on the journal-mode and the
//	** device characteristics of the file-system, as follows:
//	**
//	**   * If the journal file is an in-memory journal file, no action need
//	**     be taken.
//	**
//	**   * Otherwise, if the device does not support the SAFE_APPEND property,
//	**     then the nRec field of the most recently written journal header
//	**     is updated to contain the number of journal records that have
//	**     been written following it. If the pager is operating in full-sync
//	**     mode, then the journal file is synced before this field is updated.
//	**
//	**   * If the device does not support the SEQUENTIAL property, then
//	**     journal file is synced.
//	**
//	** Or, in pseudo-code:
//	**
//	**   if( NOT <in-memory journal> ){
//	**     if( NOT SAFE_APPEND ){
//	**       if( <full-sync mode> ) xSync(<journal file>);
//	**       <update nRec field>
//	**     }
//	**     if( NOT SEQUENTIAL ) xSync(<journal file>);
//	**   }
//	**
//	** If successful, this routine clears the PGHDR_NEED_SYNC flag of every
//	** page currently held in memory before returning SQLITE_OK. If an IO
//	** error is encountered, then the IO error code is returned to the caller.
//	*/
func _syncJournal(tls *libc.TLS, pPager uintptr, newHdr int32) (r int32) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var iDc, rc, v1 int32
	var iNextHdrOffset Ti64
	var _ /* aMagic at bp+0 */ [8]Tu8
	var _ /* zHeader at bp+8 */ [12]Tu8
	_, _, _, _ = iDc, iNextHdrOffset, rc, v1 /* Return code */
	rc = _sqlite3PagerExclusiveLock(tls, pPager)
	if rc != SQLITE_OK {
		return rc
	}
	if !((*TPager)(unsafe.Pointer(pPager)).FnoSync != 0) {
		if (*Tsqlite3_file)(unsafe.Pointer((*TPager)(unsafe.Pointer(pPager)).Fjfd)).FpMethods != uintptr(0) && libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FjournalMode) != int32(PAGER_JOURNALMODE_MEMORY) {
			iDc = _sqlite3OsDeviceCharacteristics(tls, (*TPager)(unsafe.Pointer(pPager)).Ffd)
			if 0 == iDc&int32(SQLITE_IOCAP_SAFE_APPEND) {
				libc.Xmemcpy(tls, bp+8, uintptr(unsafe.Pointer(&_aJournalMagic)), uint64(8))
				_sqlite3Put4byte(tls, bp+8+uintptr(8), libc.Uint32FromInt32((*TPager)(unsafe.Pointer(pPager)).FnRec))
				iNextHdrOffset = _journalHdrOffset(tls, pPager)
				rc = _sqlite3OsRead(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd, bp, int32(8), iNextHdrOffset)
				if rc == SQLITE_OK && 0 == libc.Xmemcmp(tls, bp, uintptr(unsafe.Pointer(&_aJournalMagic)), uint64(8)) {
					rc = _sqlite3OsWrite(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd, uintptr(unsafe.Pointer(&_zerobyte)), int32(1), iNextHdrOffset)
				}
				if rc != SQLITE_OK && rc != libc.Int32FromInt32(SQLITE_IOERR)|libc.Int32FromInt32(2)<<libc.Int32FromInt32(8) {
					return rc
				}
				/* Write the nRec value into the journal file header. If in
				 ** full-synchronous mode, sync the journal first. This ensures that
				 ** all data has really hit the disk before nRec is updated to mark
				 ** it as a candidate for rollback.
				 **
				 ** This is not required if the persistent media supports the
				 ** SAFE_APPEND property. Because in this case it is not possible
				 ** for garbage data to be appended to the file, the nRec field
				 ** is populated with 0xFFFFFFFF when the journal header is written
				 ** and never needs to be updated.
				 */
				if (*TPager)(unsafe.Pointer(pPager)).FfullSync != 0 && 0 == iDc&int32(SQLITE_IOCAP_SEQUENTIAL) {
					rc = _sqlite3OsSync(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd, libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FsyncFlags))
					if rc != SQLITE_OK {
						return rc
					}
				}
				rc = _sqlite3OsWrite(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd, bp+8, int32(12), (*TPager)(unsafe.Pointer(pPager)).FjournalHdr)
				if rc != SQLITE_OK {
					return rc
				}
			}
			if 0 == iDc&int32(SQLITE_IOCAP_SEQUENTIAL) {
				if libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FsyncFlags) == int32(SQLITE_SYNC_FULL) {
					v1 = int32(SQLITE_SYNC_DATAONLY)
				} else {
					v1 = 0
				}
				rc = _sqlite3OsSync(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd, libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FsyncFlags)|v1)
				if rc != SQLITE_OK {
					return rc
				}
			}
			(*TPager)(unsafe.Pointer(pPager)).FjournalHdr = (*TPager)(unsafe.Pointer(pPager)).FjournalOff
			if newHdr != 0 && 0 == iDc&int32(SQLITE_IOCAP_SAFE_APPEND) {
				(*TPager)(unsafe.Pointer(pPager)).FnRec = 0
				rc = _writeJournalHdr(tls, pPager)
				if rc != SQLITE_OK {
					return rc
				}
			}
		} else {
			(*TPager)(unsafe.Pointer(pPager)).FjournalHdr = (*TPager)(unsafe.Pointer(pPager)).FjournalOff
		}
	}
	/* Unless the pager is in noSync mode, the journal file was just
	 ** successfully synced. Either way, clear the PGHDR_NEED_SYNC flag on
	 ** all pages.
	 */
	_sqlite3PcacheClearSyncFlags(tls, (*TPager)(unsafe.Pointer(pPager)).FpPCache)
	(*TPager)(unsafe.Pointer(pPager)).FeState = uint8(PAGER_WRITER_DBMOD)
	return SQLITE_OK
}

// 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(80)
	defer tls.Free(80)
	var iOff, rc, v1 int32
	var pOut, pRhs, zBuf uintptr
	var sz Tu32
	var _ /* dummy at bp+0 */ int32
	var _ /* iSerial at bp+64 */ Tu32
	var _ /* sMem at bp+8 */ 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+8, 0, uint64(56))
		sz = _sqlite3BtreePayloadSize(tls, (*TValueList)(unsafe.Pointer(pRhs)).FpCsr)
		rc = _sqlite3VdbeMemFromBtreeZeroOffset(tls, (*TValueList)(unsafe.Pointer(pRhs)).FpCsr, sz, bp+8)
		if rc == SQLITE_OK {
			zBuf = (**(**TMem)(__ccgo_up(bp + 8))).Fz
			pOut = (*TValueList)(unsafe.Pointer(pRhs)).FpOut
			if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(zBuf + 1))) < libc.Int32FromUint8(libc.Uint8FromInt32(0x80)) {
				**(**Tu32)(__ccgo_up(bp + 64)) = uint32(**(**Tu8)(__ccgo_up(zBuf + 1)))
				v1 = libc.Int32FromInt32(1)
			} else {
				v1 = libc.Int32FromUint8(_sqlite3GetVarint32(tls, zBuf+1, bp+64))
			}
			iOff = int32(1) + libc.Int32FromUint8(libc.Uint8FromInt32(v1))
			_sqlite3VdbeSerialGet(tls, zBuf+uintptr(iOff), **(**Tu32)(__ccgo_up(bp + 64)), 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+8)
	}
	return rc
}

// C documentation
//
//	/*
//	** This function compares the unpacked record with the current key that
//	** cursor pCur points to. If bInt is false, all fields for which the
//	** corresponding bit in parameter "mask" is set are ignored. Or, if
//	** bInt is true, then a difference of BTREE_ULPDISTORTION or fewer ULPs
//	** in real values is overlooked for fields with the corresponding bit
//	** set in mask.
//	**
//	** Return the usual less than zero, zero, or greater than zero if the
//	** remaining fields of the cursor cursor key are less than, equal to or
//	** greater than those in (*p).
//	*/
func _vdbeIsMatchingIndexKey(tls *libc.TLS, pCur uintptr, bInt int32, mask TBitmask, p uintptr, piRes uintptr) (r int32) {
	bp := tls.Alloc(64)
	defer tls.Free(64)
	var aRec uintptr
	var idxHdr, idxRec, nRec Tu32
	var ii, nCol, nSerial, rc, res, v1 int32
	var _ /* iSerial at bp+60 */ Tu32
	var _ /* mem at bp+0 */ TMem
	var _ /* szHdr at bp+56 */ Tu32
	_, _, _, _, _, _, _, _, _, _ = aRec, idxHdr, idxRec, ii, nCol, nRec, nSerial, rc, res, v1
	aRec = uintptr(0)
	nRec = uint32(0)
	rc = SQLITE_OK
	libc.Xmemset(tls, bp, 0, uint64(56))
	(**(**TMem)(__ccgo_up(bp))).Fenc = (*TKeyInfo)(unsafe.Pointer((*TUnpackedRecord)(unsafe.Pointer(p)).FpKeyInfo)).Fenc
	(**(**TMem)(__ccgo_up(bp))).Fdb = (*TKeyInfo)(unsafe.Pointer((*TUnpackedRecord)(unsafe.Pointer(p)).FpKeyInfo)).Fdb
	nRec = _sqlite3BtreePayloadSize(tls, pCur)
	if nRec > uint32(0x7fffffff) {
		return _sqlite3CorruptError(tls, int32(93211))
	}
	/* Allocate 5 extra bytes at the end of the buffer. This allows the
	 ** getVarint32() call below to read slightly past the end of the buffer
	 ** if the record is corrupt. */
	aRec = _sqlite3MallocZero(tls, uint64(nRec+uint32(5)))
	if aRec == uintptr(0) {
		rc = int32(SQLITE_NOMEM)
	} else {
		rc = _sqlite3BtreePayload(tls, pCur, uint32(0), nRec, aRec)
	}
	if rc == SQLITE_OK {
		**(**Tu32)(__ccgo_up(bp + 56)) = uint32(0) /* Size of record header in bytes */
		idxHdr = uint32(0)                         /* Current index in header */
		if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aRec))) < libc.Int32FromUint8(libc.Uint8FromInt32(0x80)) {
			**(**Tu32)(__ccgo_up(bp + 56)) = uint32(**(**Tu8)(__ccgo_up(aRec)))
			v1 = libc.Int32FromInt32(1)
		} else {
			v1 = libc.Int32FromUint8(_sqlite3GetVarint32(tls, aRec, bp+56))
		}
		idxHdr = uint32(libc.Uint8FromInt32(v1))
		if **(**Tu32)(__ccgo_up(bp + 56)) > uint32(98307) {
			rc = int32(SQLITE_CORRUPT)
		} else {
			res = 0                                 /* Result of this function call */
			idxRec = **(**Tu32)(__ccgo_up(bp + 56)) /* Index of next field in record body */
			ii = 0                                  /* Iterator variable */
			nCol = libc.Int32FromUint16((*TKeyInfo)(unsafe.Pointer((*TUnpackedRecord)(unsafe.Pointer(p)).FpKeyInfo)).FnAllField)
			ii = 0
			for {
				if !(ii < nCol && rc == SQLITE_OK) {
					break
				}
				**(**Tu32)(__ccgo_up(bp + 60)) = uint32(0)
				nSerial = 0
				if idxHdr >= **(**Tu32)(__ccgo_up(bp + 56)) {
					rc = _sqlite3CorruptError(tls, int32(93242))
					break
				}
				if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aRec + uintptr(idxHdr)))) < libc.Int32FromUint8(libc.Uint8FromInt32(0x80)) {
					**(**Tu32)(__ccgo_up(bp + 60)) = uint32(**(**Tu8)(__ccgo_up(aRec + uintptr(idxHdr))))
					v1 = libc.Int32FromInt32(1)
				} else {
					v1 = libc.Int32FromUint8(_sqlite3GetVarint32(tls, aRec+uintptr(idxHdr), bp+60))
				}
				idxHdr = idxHdr + uint32(libc.Uint8FromInt32(v1))
				nSerial = libc.Int32FromUint32(_sqlite3VdbeSerialTypeLen(tls, **(**Tu32)(__ccgo_up(bp + 60))))
				if idxRec+libc.Uint32FromInt32(nSerial) > nRec {
					rc = _sqlite3CorruptError(tls, int32(93248))
				} else {
					_sqlite3VdbeSerialGet(tls, aRec+uintptr(idxRec), **(**Tu32)(__ccgo_up(bp + 60)), bp)
					if _vdbeSkipField(tls, mask, ii, (*TUnpackedRecord)(unsafe.Pointer(p)).FaMem+uintptr(ii)*56, bp, bInt) == 0 {
						res = _sqlite3MemCompare(tls, bp, (*TUnpackedRecord)(unsafe.Pointer(p)).FaMem+uintptr(ii)*56, *(*uintptr)(unsafe.Pointer((*TUnpackedRecord)(unsafe.Pointer(p)).FpKeyInfo + 32 + uintptr(ii)*8)))
						if res != 0 {
							break
						}
					}
				}
				idxRec = idxRec + _sqlite3VdbeSerialTypeLen(tls, **(**Tu32)(__ccgo_up(bp + 60)))
				goto _2
			_2:
				;
				ii = ii + 1
			}
			**(**int32)(__ccgo_up(piRes)) = res
		}
	}
	Xsqlite3_free(tls, aRec)
	return rc
}

// C documentation
//
//	/*
//	** Read the next nByte bytes of data from the PMA p.
//	** If successful, set *ppOut to point to a buffer containing the data
//	** and return SQLITE_OK. Otherwise, if an error occurs, return an SQLite
//	** error code.
//	**
//	** The buffer returned in *ppOut is only valid until the
//	** next call to this function.
//	*/
func _vdbePmaReadBlob(tls *libc.TLS, p uintptr, nByte int32, ppOut uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var aNew uintptr
	var iBuf, nAvail, nCopy, nRead, nRem, rc, rc1 int32
	var nNew Tsqlite3_int64
	var v1 int64
	var _ /* aNext at bp+0 */ uintptr
	_, _, _, _, _, _, _, _, _, _ = aNew, iBuf, nAvail, nCopy, nNew, nRead, nRem, rc, rc1, v1 /* Bytes of data available in buffer */
	if (*TPmaReader)(unsafe.Pointer(p)).FaMap != 0 {
		**(**uintptr)(__ccgo_up(ppOut)) = (*TPmaReader)(unsafe.Pointer(p)).FaMap + uintptr((*TPmaReader)(unsafe.Pointer(p)).FiReadOff)
		**(**Ti64)(__ccgo_up(p)) += int64(nByte)
		return SQLITE_OK
	}
	/* If there is no more data to be read from the buffer, read the next
	 ** p->nBuffer bytes of data from the file into it. Or, if there are less
	 ** than p->nBuffer bytes remaining in the PMA, read all remaining data.  */
	iBuf = int32((*TPmaReader)(unsafe.Pointer(p)).FiReadOff % int64((*TPmaReader)(unsafe.Pointer(p)).FnBuffer))
	if iBuf == 0 { /* sqlite3OsRead() return code */
		/* Determine how many bytes of data to read. */
		if (*TPmaReader)(unsafe.Pointer(p)).FiEof-(*TPmaReader)(unsafe.Pointer(p)).FiReadOff > int64((*TPmaReader)(unsafe.Pointer(p)).FnBuffer) {
			nRead = (*TPmaReader)(unsafe.Pointer(p)).FnBuffer
		} else {
			nRead = int32((*TPmaReader)(unsafe.Pointer(p)).FiEof - (*TPmaReader)(unsafe.Pointer(p)).FiReadOff)
		}
		/* Readr data from the file. Return early if an error occurs. */
		rc = _sqlite3OsRead(tls, (*TPmaReader)(unsafe.Pointer(p)).FpFd, (*TPmaReader)(unsafe.Pointer(p)).FaBuffer, nRead, (*TPmaReader)(unsafe.Pointer(p)).FiReadOff)
		if rc != SQLITE_OK {
			return rc
		}
	}
	nAvail = (*TPmaReader)(unsafe.Pointer(p)).FnBuffer - iBuf
	if nByte <= nAvail {
		/* The requested data is available in the in-memory buffer. In this
		 ** case there is no need to make a copy of the data, just return a
		 ** pointer into the buffer to the caller.  */
		**(**uintptr)(__ccgo_up(ppOut)) = (*TPmaReader)(unsafe.Pointer(p)).FaBuffer + uintptr(iBuf)
		**(**Ti64)(__ccgo_up(p)) += int64(nByte)
	} else { /* Bytes remaining to copy */
		/* Extend the p->aAlloc[] allocation if required. */
		if (*TPmaReader)(unsafe.Pointer(p)).FnAlloc < nByte {
			if int64(libc.Int32FromInt32(128)) > int64(2)*int64((*TPmaReader)(unsafe.Pointer(p)).FnAlloc) {
				v1 = int64(libc.Int32FromInt32(128))
			} else {
				v1 = int64(2) * int64((*TPmaReader)(unsafe.Pointer(p)).FnAlloc)
			}
			nNew = v1
			for int64(nByte) > nNew {
				nNew = nNew * int64(2)
			}
			aNew = _sqlite3Realloc(tls, (*TPmaReader)(unsafe.Pointer(p)).FaAlloc, libc.Uint64FromInt64(nNew))
			if !(aNew != 0) {
				return int32(SQLITE_NOMEM)
			}
			(*TPmaReader)(unsafe.Pointer(p)).FnAlloc = int32(nNew)
			(*TPmaReader)(unsafe.Pointer(p)).FaAlloc = aNew
		}
		/* Copy as much data as is available in the buffer into the start of
		 ** p->aAlloc[].  */
		libc.Xmemcpy(tls, (*TPmaReader)(unsafe.Pointer(p)).FaAlloc, (*TPmaReader)(unsafe.Pointer(p)).FaBuffer+uintptr(iBuf), libc.Uint64FromInt32(nAvail))
		**(**Ti64)(__ccgo_up(p)) += int64(nAvail)
		nRem = nByte - nAvail
		/* The following loop copies up to p->nBuffer bytes per iteration into
		 ** the p->aAlloc[] buffer.  */
		for nRem > 0 { /* Number of bytes to copy */
			**(**uintptr)(__ccgo_up(bp)) = uintptr(0) /* Pointer to buffer to copy data from */
			nCopy = nRem
			if nRem > (*TPmaReader)(unsafe.Pointer(p)).FnBuffer {
				nCopy = (*TPmaReader)(unsafe.Pointer(p)).FnBuffer
			}
			rc1 = _vdbePmaReadBlob(tls, p, nCopy, bp)
			if rc1 != SQLITE_OK {
				return rc1
			}
			libc.Xmemcpy(tls, (*TPmaReader)(unsafe.Pointer(p)).FaAlloc+uintptr(nByte-nRem), **(**uintptr)(__ccgo_up(bp)), libc.Uint64FromInt32(nCopy))
			nRem = nRem - nCopy
		}
		**(**uintptr)(__ccgo_up(ppOut)) = (*TPmaReader)(unsafe.Pointer(p)).FaAlloc
	}
	return SQLITE_OK
}

// 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.Uint64FromInt32(nCopy))
		**(**int32)(__ccgo_up(p + 24)) += 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 + 48)) += 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 + 32)) += 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 + 48)) += 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, uint64(56))
	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, uint64(56))
	(*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
//
//	/*
//	** Helper function for vdbeIsMatchingIndexKey(). Return true if column
//	** iCol should be ignored when comparing a record with a record from
//	** an index on disk. The field should be ignored if:
//	**
//	**   * the corresponding bit in mask is set, and
//	**   * either:
//	**       - bIntegrity is false, or
//	**       - the two Mem values are both real values that differ by
//	**         BTREE_ULPDISTORTION or fewer ULPs.
//	*/
func _vdbeSkipField(tls *libc.TLS, mask TBitmask, iCol int32, pMem1 uintptr, pMem2 uintptr, bIntegrity int32) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var v1 uint64
	var _ /* m1 at bp+0 */ Tu64
	var _ /* m2 at bp+8 */ Tu64
	_ = v1
	if iCol >= libc.Int32FromUint64(libc.Uint64FromInt64(8)*libc.Uint64FromInt32(8)) || mask&(libc.Uint64FromInt32(1)<<iCol) == uint64(0) {
		return 0
	}
	if bIntegrity == 0 {
		return int32(1)
	}
	if libc.Int32FromUint16((*TMem)(unsafe.Pointer(pMem1)).Fflags)&int32(MEM_Real) != 0 && libc.Int32FromUint16((*TMem)(unsafe.Pointer(pMem2)).Fflags)&int32(MEM_Real) != 0 {
		libc.Xmemcpy(tls, bp, pMem1, uint64(8))
		libc.Xmemcpy(tls, bp+8, pMem2, uint64(8))
		if **(**Tu64)(__ccgo_up(bp)) < **(**Tu64)(__ccgo_up(bp + 8)) {
			v1 = **(**Tu64)(__ccgo_up(bp + 8)) - **(**Tu64)(__ccgo_up(bp))
		} else {
			v1 = **(**Tu64)(__ccgo_up(bp)) - **(**Tu64)(__ccgo_up(bp + 8))
		}
		if v1 <= uint64(BTREE_ULPDISTORTION) {
			return int32(1)
		}
	}
	return 0
}

// C documentation
//
//	/*
//	** Sort the linked list of records headed at pTask->pList. Return
//	** SQLITE_OK if successful, or an SQLite error code (i.e. SQLITE_NOMEM) if
//	** an error occurs.
//	*/
func _vdbeSorterSort(tls *libc.TLS, pTask uintptr, pList uintptr) (r int32) {
	bp := tls.Alloc(512)
	defer tls.Free(512)
	var i, rc int32
	var p, pNext, v3 uintptr
	var _ /* aSlot at bp+0 */ [64]uintptr
	_, _, _, _, _ = i, p, pNext, rc, v3
	rc = _vdbeSortAllocUnpacked(tls, pTask)
	if rc != SQLITE_OK {
		return rc
	}
	p = (*TSorterList)(unsafe.Pointer(pList)).FpList
	(*TSortSubtask)(unsafe.Pointer(pTask)).FxCompare = _vdbeSorterGetCompare(tls, (*TSortSubtask)(unsafe.Pointer(pTask)).FpSorter)
	libc.Xmemset(tls, bp, 0, uint64(512))
	for p != 0 {
		if (*TSorterList)(unsafe.Pointer(pList)).FaMemory != 0 {
			if p == (*TSorterList)(unsafe.Pointer(pList)).FaMemory {
				pNext = uintptr(0)
			} else {
				pNext = (*TSorterList)(unsafe.Pointer(pList)).FaMemory + uintptr(*(*int32)(unsafe.Pointer(&(*TSorterRecord)(unsafe.Pointer(p)).Fu)))
			}
		} else {
			pNext = *(*uintptr)(unsafe.Pointer(p + 8))
		}
		*(*uintptr)(unsafe.Pointer(p + 8)) = uintptr(0)
		i = 0
		for {
			if !((**(**[64]uintptr)(__ccgo_up(bp)))[i] != 0) {
				break
			}
			p = _vdbeSorterMerge(tls, pTask, p, (**(**[64]uintptr)(__ccgo_up(bp)))[i])
			/* ,--Each aSlot[] holds twice as much as the previous. So we cannot use
			 ** |  up all 64 aSlots[] with only a 64-bit address space.
			 ** v                                                                */
			(**(**[64]uintptr)(__ccgo_up(bp)))[i] = uintptr(0)
			goto _1
		_1:
			;
			i = i + 1
		}
		(**(**[64]uintptr)(__ccgo_up(bp)))[i] = p
		p = pNext
	}
	p = uintptr(0)
	i = 0
	for {
		if !(i < libc.Int32FromUint64(libc.Uint64FromInt64(512)/libc.Uint64FromInt64(8))) {
			break
		}
		if (**(**[64]uintptr)(__ccgo_up(bp)))[i] == uintptr(0) {
			goto _2
		}
		if p != 0 {
			v3 = _vdbeSorterMerge(tls, pTask, p, (**(**[64]uintptr)(__ccgo_up(bp)))[i])
		} else {
			v3 = (**(**[64]uintptr)(__ccgo_up(bp)))[i]
		}
		p = v3
		goto _2
	_2:
		;
		i = i + 1
	}
	(*TSorterList)(unsafe.Pointer(pList)).FpList = p
	return libc.Int32FromUint8((*TUnpackedRecord)(unsafe.Pointer((*TSortSubtask)(unsafe.Pointer(pTask)).FpUnpacked)).FerrCode)
}

// C documentation
//
//	/*
//	** Allocate and populate an UnpackedRecord structure based on the serialized
//	** record in nKey/pKey. Return a pointer to the new UnpackedRecord structure
//	** if successful, or a NULL pointer if an OOM error is encountered.
//	*/
func _vdbeUnpackRecord(tls *libc.TLS, pKeyInfo uintptr, nKey int32, pKey uintptr) (r uintptr) {
	var pRet uintptr
	_ = pRet /* Return value */
	pRet = _sqlite3VdbeAllocUnpackedRecord(tls, pKeyInfo)
	if pRet != 0 {
		libc.Xmemset(tls, (*TUnpackedRecord)(unsafe.Pointer(pRet)).FaMem, 0, uint64(56)*libc.Uint64FromInt32(libc.Int32FromUint16((*TKeyInfo)(unsafe.Pointer(pKeyInfo)).FnKeyField)+libc.Int32FromInt32(1)))
		_sqlite3VdbeRecordUnpack(tls, nKey, pKey, pRet)
	}
	return pRet
}

// C documentation
//
//	/*
//	** Open a transaction in a connection where the shared-memory is read-only
//	** and where we cannot verify that there is a separate write-capable connection
//	** on hand to keep the shared-memory up-to-date with the WAL file.
//	**
//	** This can happen, for example, when the shared-memory is implemented by
//	** memory-mapping a *-shm file, where a prior writer has shut down and
//	** left the *-shm file on disk, and now the present connection is trying
//	** to use that database but lacks write permission on the *-shm file.
//	** Other scenarios are also possible, depending on the VFS implementation.
//	**
//	** Precondition:
//	**
//	**    The *-wal file has been read and an appropriate wal-index has been
//	**    constructed in pWal->apWiData[] using heap memory instead of shared
//	**    memory.
//	**
//	** If this function returns SQLITE_OK, then the read transaction has
//	** been successfully opened. In this case output variable (*pChanged)
//	** is set to true before returning if the caller should discard the
//	** contents of the page cache before proceeding. Or, if it returns
//	** WAL_RETRY, then the heap memory wal-index has been discarded and
//	** the caller should retry opening the read transaction from the
//	** beginning (including attempting to map the *-shm file).
//	**
//	** If an error occurs, an SQLite error code is returned.
//	*/
func _walBeginShmUnreliable(tls *libc.TLS, pWal uintptr, pChanged uintptr) (r int32) {
	bp := tls.Alloc(64)
	defer tls.Free(64)
	var aData, aFrame uintptr
	var aSaveCksum [2]Tu32
	var i, rc, szFrame, v1 int32
	var iOffset Ti64
	var _ /* aBuf at bp+8 */ [32]Tu8
	var _ /* nTruncate at bp+52 */ Tu32
	var _ /* pDummy at bp+40 */ uintptr
	var _ /* pgno at bp+48 */ Tu32
	var _ /* szWal at bp+0 */ Ti64
	_, _, _, _, _, _, _, _ = aData, aFrame, aSaveCksum, i, iOffset, rc, szFrame, v1 /* Buffer to load WAL header into */
	aFrame = uintptr(0)                                                             /* Saved copy of pWal->hdr.aFrameCksum */
	/* Take WAL_READ_LOCK(0). This has the effect of preventing any
	 ** writers from running a checkpoint, but does not stop them
	 ** from running recovery.  */
	rc = _walLockShared(tls, pWal, libc.Int32FromInt32(3)+libc.Int32FromInt32(0))
	if rc != SQLITE_OK {
		if rc == int32(SQLITE_BUSY) {
			rc = -int32(1)
		}
		goto begin_unreliable_shm_out
	}
	(*TWal)(unsafe.Pointer(pWal)).FreadLock = 0
	/* Check to see if a separate writer has attached to the shared-memory area,
	 ** thus making the shared-memory "reliable" again.  Do this by invoking
	 ** the xShmMap() routine of the VFS and looking to see if the return
	 ** is SQLITE_READONLY instead of SQLITE_READONLY_CANTINIT.
	 **
	 ** If the shared-memory is now "reliable" return WAL_RETRY, which will
	 ** cause the heap-memory WAL-index to be discarded and the actual
	 ** shared memory to be used in its place.
	 **
	 ** This step is important because, even though this connection is holding
	 ** the WAL_READ_LOCK(0) which prevents a checkpoint, a writer might
	 ** have already checkpointed the WAL file and, while the current
	 ** is active, wrap the WAL and start overwriting frames that this
	 ** process wants to use.
	 **
	 ** Once sqlite3OsShmMap() has been called for an sqlite3_file and has
	 ** returned any SQLITE_READONLY value, it must return only SQLITE_READONLY
	 ** or SQLITE_READONLY_CANTINIT or some error for all subsequent invocations,
	 ** even if some external agent does a "chmod" to make the shared-memory
	 ** writable by us, until sqlite3OsShmUnmap() has been called.
	 ** This is a requirement on the VFS implementation.
	 */
	rc = _sqlite3OsShmMap(tls, (*TWal)(unsafe.Pointer(pWal)).FpDbFd, 0, libc.Int32FromUint64(libc.Uint64FromInt64(2)*libc.Uint64FromInt32(libc.Int32FromInt32(HASHTABLE_NPAGE)*libc.Int32FromInt32(2))+libc.Uint64FromInt32(HASHTABLE_NPAGE)*libc.Uint64FromInt64(4)), 0, bp+40)
	/* SQLITE_OK not possible for read-only connection */
	if rc != libc.Int32FromInt32(SQLITE_READONLY)|libc.Int32FromInt32(5)<<libc.Int32FromInt32(8) {
		if rc == int32(SQLITE_READONLY) {
			v1 = -int32(1)
		} else {
			v1 = rc
		}
		rc = v1
		goto begin_unreliable_shm_out
	}
	/* We reach this point only if the real shared-memory is still unreliable.
	 ** Assume the in-memory WAL-index substitute is correct and load it
	 ** into pWal->hdr.
	 */
	libc.Xmemcpy(tls, pWal+72, _walIndexHdr(tls, pWal), uint64(48))
	/* Make sure some writer hasn't come in and changed the WAL file out
	 ** from under us, then disconnected, while we were not looking.
	 */
	rc = _sqlite3OsFileSize(tls, (*TWal)(unsafe.Pointer(pWal)).FpWalFd, bp)
	if rc != SQLITE_OK {
		goto begin_unreliable_shm_out
	}
	if **(**Ti64)(__ccgo_up(bp)) < int64(WAL_HDRSIZE) {
		/* If the wal file is too small to contain a wal-header and the
		 ** wal-index header has mxFrame==0, then it must be safe to proceed
		 ** reading the database file only. However, the page cache cannot
		 ** be trusted, as a read/write connection may have connected, written
		 ** the db, run a checkpoint, truncated the wal file and disconnected
		 ** since this client's last read transaction.  */
		**(**int32)(__ccgo_up(pChanged)) = int32(1)
		if (*TWal)(unsafe.Pointer(pWal)).Fhdr.FmxFrame == uint32(0) {
			v1 = SQLITE_OK
		} else {
			v1 = -int32(1)
		}
		rc = v1
		goto begin_unreliable_shm_out
	}
	/* Check the salt keys at the start of the wal file still match. */
	rc = _sqlite3OsRead(tls, (*TWal)(unsafe.Pointer(pWal)).FpWalFd, bp+8, int32(WAL_HDRSIZE), 0)
	if rc != SQLITE_OK {
		goto begin_unreliable_shm_out
	}
	if libc.Xmemcmp(tls, pWal+72+32, bp+8+16, uint64(8)) != 0 {
		/* Some writer has wrapped the WAL file while we were not looking.
		 ** Return WAL_RETRY which will cause the in-memory WAL-index to be
		 ** rebuilt. */
		rc = -int32(1)
		goto begin_unreliable_shm_out
	}
	/* Allocate a buffer to read frames into */
	szFrame = libc.Int32FromUint32((*TWal)(unsafe.Pointer(pWal)).FszPage + uint32(WAL_FRAME_HDRSIZE))
	aFrame = Xsqlite3_malloc64(tls, libc.Uint64FromInt32(szFrame))
	if aFrame == uintptr(0) {
		rc = int32(SQLITE_NOMEM)
		goto begin_unreliable_shm_out
	}
	aData = aFrame + 24
	/* Check to see if a complete transaction has been appended to the
	 ** wal file since the heap-memory wal-index was created. If so, the
	 ** heap-memory wal-index is discarded and WAL_RETRY returned to
	 ** the caller.  */
	aSaveCksum[0] = **(**Tu32)(__ccgo_up(pWal + 72 + 24))
	aSaveCksum[int32(1)] = **(**Tu32)(__ccgo_up(pWal + 72 + 24 + 1*4))
	iOffset = libc.Int64FromInt32(WAL_HDRSIZE) + libc.Int64FromUint32((*TWal)(unsafe.Pointer(pWal)).Fhdr.FmxFrame+libc.Uint32FromInt32(1)-libc.Uint32FromInt32(1))*libc.Int64FromUint32((*TWal)(unsafe.Pointer(pWal)).FszPage+libc.Uint32FromInt32(WAL_FRAME_HDRSIZE))
	for {
		if !(iOffset+int64(szFrame) <= **(**Ti64)(__ccgo_up(bp))) {
			break
		} /* dbsize field from frame header */
		/* Read and decode the next log frame. */
		rc = _sqlite3OsRead(tls, (*TWal)(unsafe.Pointer(pWal)).FpWalFd, aFrame, szFrame, iOffset)
		if rc != SQLITE_OK {
			break
		}
		if !(_walDecodeFrame(tls, pWal, bp+48, bp+52, aData, aFrame) != 0) {
			break
		}
		/* If nTruncate is non-zero, then a complete transaction has been
		 ** appended to this wal file. Set rc to WAL_RETRY and break out of
		 ** the loop.  */
		if **(**Tu32)(__ccgo_up(bp + 52)) != 0 {
			rc = -int32(1)
			break
		}
		goto _3
	_3:
		;
		iOffset = iOffset + int64(szFrame)
	}
	**(**Tu32)(__ccgo_up(pWal + 72 + 24)) = aSaveCksum[0]
	**(**Tu32)(__ccgo_up(pWal + 72 + 24 + 1*4)) = aSaveCksum[int32(1)]
	goto begin_unreliable_shm_out
begin_unreliable_shm_out:
	;
	Xsqlite3_free(tls, aFrame)
	if rc != SQLITE_OK {
		i = 0
		for {
			if !(i < (*TWal)(unsafe.Pointer(pWal)).FnWiData) {
				break
			}
			Xsqlite3_free(tls, **(**uintptr)(__ccgo_up((*TWal)(unsafe.Pointer(pWal)).FapWiData + uintptr(i)*8)))
			**(**uintptr)(__ccgo_up((*TWal)(unsafe.Pointer(pWal)).FapWiData + uintptr(i)*8)) = uintptr(0)
			goto _4
		_4:
			;
			i = i + 1
		}
		(*TWal)(unsafe.Pointer(pWal)).FbShmUnreliable = uint8(0)
		_sqlite3WalEndReadTransaction(tls, pWal)
		**(**int32)(__ccgo_up(pChanged)) = int32(1)
	}
	return rc
}

/*
** The final argument passed to walTryBeginRead() is of type (int*). The
** caller should invoke walTryBeginRead as follows:
**
**   int cnt = 0;
**   do {
**     rc = walTryBeginRead(..., &cnt);
**   }while( rc==WAL_RETRY );
**
** The final value of "cnt" is of no use to the caller. It is used by
** the implementation of walTryBeginRead() as follows:
**
**   + Each time walTryBeginRead() is called, it is incremented. Once
**     it reaches WAL_RETRY_PROTOCOL_LIMIT - indicating that walTryBeginRead()
**     has many times been invoked and failed with WAL_RETRY - walTryBeginRead()
**     returns SQLITE_PROTOCOL.
**
**   + If SQLITE_ENABLE_SETLK_TIMEOUT is defined and walTryBeginRead() failed
**     because a blocking lock timed out (SQLITE_BUSY_TIMEOUT from the OS
**     layer), the WAL_RETRY_BLOCKED_MASK bit is set in "cnt". In this case
**     the next invocation of walTryBeginRead() may omit an expected call to
**     sqlite3OsSleep(). There has already been a delay when the previous call
**     waited on a lock.
 */

// C documentation
//
//	/*
//	** Remove entries from the hash table that point to WAL slots greater
//	** than pWal->hdr.mxFrame.
//	**
//	** This function is called whenever pWal->hdr.mxFrame is decreased due
//	** to a rollback or savepoint.
//	**
//	** At most only the hash table containing pWal->hdr.mxFrame needs to be
//	** updated.  Any later hash tables will be automatically cleared when
//	** pWal->hdr.mxFrame advances to the point where those hash tables are
//	** actually needed.
//	*/
func _walCleanupHash(tls *libc.TLS, pWal uintptr) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var i, iLimit, nByte int32
	var _ /* sLoc at bp+0 */ TWalHashLoc
	_, _, _ = i, iLimit, nByte /* Hash table location */
	iLimit = 0                 /* Used to iterate through aHash[] */
	if (*TWal)(unsafe.Pointer(pWal)).Fhdr.FmxFrame == uint32(0) {
		return
	}
	/* Obtain pointers to the hash-table and page-number array containing
	 ** the entry that corresponds to frame pWal->hdr.mxFrame. It is guaranteed
	 ** that the page said hash-table and array reside on is already mapped.(1)
	 */
	i = _walHashGet(tls, pWal, _walFramePage(tls, (*TWal)(unsafe.Pointer(pWal)).Fhdr.FmxFrame), bp)
	if i != 0 {
		return
	} /* Defense-in-depth, in case (1) above is wrong */
	/* Zero all hash-table entries that correspond to frame numbers greater
	 ** than pWal->hdr.mxFrame.
	 */
	iLimit = libc.Int32FromUint32((*TWal)(unsafe.Pointer(pWal)).Fhdr.FmxFrame - (**(**TWalHashLoc)(__ccgo_up(bp))).FiZero)
	i = 0
	for {
		if !(i < libc.Int32FromInt32(HASHTABLE_NPAGE)*libc.Int32FromInt32(2)) {
			break
		}
		if libc.Int32FromUint16(**(**Tht_slot)(__ccgo_up((**(**TWalHashLoc)(__ccgo_up(bp))).FaHash + uintptr(i)*2))) > iLimit {
			**(**Tht_slot)(__ccgo_up((**(**TWalHashLoc)(__ccgo_up(bp))).FaHash + uintptr(i)*2)) = uint16(0)
		}
		goto _1
	_1:
		;
		i = i + 1
	}
	/* Zero the entries in the aPgno array that correspond to frames with
	 ** frame numbers greater than pWal->hdr.mxFrame.
	 */
	nByte = int32(int64((**(**TWalHashLoc)(__ccgo_up(bp))).FaHash) - int64((**(**TWalHashLoc)(__ccgo_up(bp))).FaPgno+uintptr(iLimit)*4))
	libc.Xmemset(tls, (**(**TWalHashLoc)(__ccgo_up(bp))).FaPgno+uintptr(iLimit)*4, 0, libc.Uint64FromInt32(nByte))
}

// C documentation
//
//	/*
//	** Write a set of frames to the log. The caller must hold the write-lock
//	** on the log file (obtained using sqlite3WalBeginWriteTransaction()).
//	*/
func _walFrames(tls *libc.TLS, pWal uintptr, szPage int32, pList uintptr, nTruncate TPgno, isCommit int32, sync_flags int32) (r int32) {
	bp := tls.Alloc(80)
	defer tls.Free(80)
	var bSync, nDbSize, nExtra, rc, sectorSize, szFrame, v1 int32
	var iFirst, iFrame Tu32
	var iOff, iOffset, sz Ti64
	var p, pData, pLast, pLive, v3 uintptr
	var v4 uint32
	var _ /* aCksum at bp+64 */ [2]Tu32
	var _ /* aWalHdr at bp+32 */ [32]Tu8
	var _ /* iWrite at bp+72 */ Tu32
	var _ /* w at bp+0 */ TWalWriter
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = bSync, iFirst, iFrame, iOff, iOffset, nDbSize, nExtra, p, pData, pLast, pLive, rc, sectorSize, sz, szFrame, v1, v3, v4 /* Iterator to run through pList with. */
	pLast = uintptr(0)                                                                                                                                                            /* Last frame in list */
	nExtra = 0                                                                                                                                                                    /* The writer */
	iFirst = uint32(0)                                                                                                                                                            /* Pointer to shared header */
	/* If this frame set completes a transaction, then nTruncate>0.  If
	 ** nTruncate==0 then this frame set does not complete the transaction. */
	pLive = _walIndexHdr(tls, pWal)
	if libc.Xmemcmp(tls, pWal+72, pLive, uint64(48)) != 0 {
		iFirst = (*TWalIndexHdr)(unsafe.Pointer(pLive)).FmxFrame + uint32(1)
	}
	/* See if it is possible to write these frames into the start of the
	 ** log file, instead of appending to it at pWal->hdr.mxFrame.
	 */
	v1 = _walRestartLog(tls, pWal)
	rc = v1
	if SQLITE_OK != v1 {
		return rc
	}
	/* If this is the first frame written into the log, write the WAL
	 ** header to the start of the WAL file. See comments at the top of
	 ** this source file for a description of the WAL header format.
	 */
	iFrame = (*TWal)(unsafe.Pointer(pWal)).Fhdr.FmxFrame
	if iFrame == uint32(0) { /* Checksum for wal-header */
		_sqlite3Put4byte(tls, bp+32, libc.Uint32FromInt32(libc.Int32FromInt32(WAL_MAGIC)|libc.Int32FromInt32(SQLITE_BIGENDIAN)))
		_sqlite3Put4byte(tls, bp+32+4, uint32(WAL_MAX_VERSION))
		_sqlite3Put4byte(tls, bp+32+8, libc.Uint32FromInt32(szPage))
		_sqlite3Put4byte(tls, bp+32+12, (*TWal)(unsafe.Pointer(pWal)).FnCkpt)
		if (*TWal)(unsafe.Pointer(pWal)).FnCkpt == uint32(0) {
			Xsqlite3_randomness(tls, int32(8), pWal+72+32)
		}
		libc.Xmemcpy(tls, bp+32+16, pWal+72+32, uint64(8))
		_walChecksumBytes(tls, int32(1), bp+32, libc.Int32FromInt32(WAL_HDRSIZE)-libc.Int32FromInt32(2)*libc.Int32FromInt32(4), uintptr(0), bp+64)
		_sqlite3Put4byte(tls, bp+32+24, (**(**[2]Tu32)(__ccgo_up(bp + 64)))[0])
		_sqlite3Put4byte(tls, bp+32+28, (**(**[2]Tu32)(__ccgo_up(bp + 64)))[int32(1)])
		(*TWal)(unsafe.Pointer(pWal)).FszPage = libc.Uint32FromInt32(szPage)
		(*TWal)(unsafe.Pointer(pWal)).Fhdr.FbigEndCksum = uint8(SQLITE_BIGENDIAN)
		**(**Tu32)(__ccgo_up(pWal + 72 + 24)) = (**(**[2]Tu32)(__ccgo_up(bp + 64)))[0]
		**(**Tu32)(__ccgo_up(pWal + 72 + 24 + 1*4)) = (**(**[2]Tu32)(__ccgo_up(bp + 64)))[int32(1)]
		(*TWal)(unsafe.Pointer(pWal)).FtruncateOnCommit = uint8(1)
		rc = _sqlite3OsWrite(tls, (*TWal)(unsafe.Pointer(pWal)).FpWalFd, bp+32, int32(32), 0)
		if rc != SQLITE_OK {
			return rc
		}
		/* Sync the header (unless SQLITE_IOCAP_SEQUENTIAL is true or unless
		 ** all syncing is turned off by PRAGMA synchronous=OFF).  Otherwise
		 ** an out-of-order write following a WAL restart could result in
		 ** database corruption.  See the ticket:
		 **
		 **     https://sqlite.org/src/info/ff5be73dee
		 */
		if (*TWal)(unsafe.Pointer(pWal)).FsyncHeader != 0 {
			rc = _sqlite3OsSync(tls, (*TWal)(unsafe.Pointer(pWal)).FpWalFd, sync_flags>>int32(2)&int32(0x03))
			if rc != 0 {
				return rc
			}
		}
	}
	if libc.Int32FromUint32((*TWal)(unsafe.Pointer(pWal)).FszPage) != szPage {
		return _sqlite3CorruptError(tls, int32(71564)) /* TH3 test case: cov1/corrupt155.test */
	}
	/* Setup information needed to write frames into the WAL */
	(**(**TWalWriter)(__ccgo_up(bp))).FpWal = pWal
	(**(**TWalWriter)(__ccgo_up(bp))).FpFd = (*TWal)(unsafe.Pointer(pWal)).FpWalFd
	(**(**TWalWriter)(__ccgo_up(bp))).FiSyncPoint = 0
	(**(**TWalWriter)(__ccgo_up(bp))).FsyncFlags = sync_flags
	(**(**TWalWriter)(__ccgo_up(bp))).FszPage = szPage
	iOffset = libc.Int64FromInt32(WAL_HDRSIZE) + libc.Int64FromUint32(iFrame+libc.Uint32FromInt32(1)-libc.Uint32FromInt32(1))*int64(szPage+libc.Int32FromInt32(WAL_FRAME_HDRSIZE))
	szFrame = szPage + int32(WAL_FRAME_HDRSIZE)
	/* Write all frames into the log file exactly once */
	p = pList
	for {
		if !(p != 0) {
			break
		} /* 0 normally.  Positive == commit flag */
		/* Check if this page has already been written into the wal file by
		 ** the current transaction. If so, overwrite the existing frame and
		 ** set Wal.writeLock to WAL_WRITELOCK_RECKSUM - indicating that
		 ** checksums must be recomputed when the transaction is committed.  */
		if iFirst != 0 && ((*TPgHdr)(unsafe.Pointer(p)).FpDirty != 0 || isCommit == 0) {
			**(**Tu32)(__ccgo_up(bp + 72)) = uint32(0)
			_walFindFrame(tls, pWal, (*TPgHdr)(unsafe.Pointer(p)).Fpgno, bp+72)
			if **(**Tu32)(__ccgo_up(bp + 72)) >= iFirst {
				iOff = int64(WAL_HDRSIZE) + libc.Int64FromUint32(**(**Tu32)(__ccgo_up(bp + 72))-libc.Uint32FromInt32(1))*int64(szPage+libc.Int32FromInt32(WAL_FRAME_HDRSIZE)) + int64(WAL_FRAME_HDRSIZE)
				if (*TWal)(unsafe.Pointer(pWal)).FiReCksum == uint32(0) || **(**Tu32)(__ccgo_up(bp + 72)) < (*TWal)(unsafe.Pointer(pWal)).FiReCksum {
					(*TWal)(unsafe.Pointer(pWal)).FiReCksum = **(**Tu32)(__ccgo_up(bp + 72))
				}
				pData = (*TPgHdr)(unsafe.Pointer(p)).FpData
				rc = _sqlite3OsWrite(tls, (*TWal)(unsafe.Pointer(pWal)).FpWalFd, pData, szPage, iOff)
				if rc != 0 {
					return rc
				}
				v3 = p + 52
				*(*Tu16)(unsafe.Pointer(v3)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v3))) & ^libc.Int32FromInt32(PGHDR_WAL_APPEND))
				goto _2
			}
		}
		iFrame = iFrame + 1
		if isCommit != 0 && (*TPgHdr)(unsafe.Pointer(p)).FpDirty == uintptr(0) {
			v4 = nTruncate
		} else {
			v4 = uint32(0)
		}
		nDbSize = libc.Int32FromUint32(v4)
		rc = _walWriteOneFrame(tls, bp, p, nDbSize, iOffset)
		if rc != 0 {
			return rc
		}
		pLast = p
		iOffset = iOffset + int64(szFrame)
		v3 = p + 52
		*(*Tu16)(unsafe.Pointer(v3)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v3))) | libc.Int32FromInt32(PGHDR_WAL_APPEND))
		goto _2
	_2:
		;
		p = (*TPgHdr)(unsafe.Pointer(p)).FpDirty
	}
	/* Recalculate checksums within the wal file if required. */
	if isCommit != 0 && (*TWal)(unsafe.Pointer(pWal)).FiReCksum != 0 {
		rc = _walRewriteChecksums(tls, pWal, iFrame)
		if rc != 0 {
			return rc
		}
	}
	/* If this is the end of a transaction, then we might need to pad
	 ** the transaction and/or sync the WAL file.
	 **
	 ** Padding and syncing only occur if this set of frames complete a
	 ** transaction and if PRAGMA synchronous=FULL.  If synchronous==NORMAL
	 ** or synchronous==OFF, then no padding or syncing are needed.
	 **
	 ** If SQLITE_IOCAP_POWERSAFE_OVERWRITE is defined, then padding is not
	 ** needed and only the sync is done.  If padding is needed, then the
	 ** final frame is repeated (with its commit mark) until the next sector
	 ** boundary is crossed.  Only the part of the WAL prior to the last
	 ** sector boundary is synced; the part of the last frame that extends
	 ** past the sector boundary is written after the sync.
	 */
	if isCommit != 0 && sync_flags&int32(0x03) != 0 {
		bSync = int32(1)
		if (*TWal)(unsafe.Pointer(pWal)).FpadToSectorBoundary != 0 {
			sectorSize = _sqlite3SectorSize(tls, (*TWal)(unsafe.Pointer(pWal)).FpWalFd)
			(**(**TWalWriter)(__ccgo_up(bp))).FiSyncPoint = (iOffset + int64(sectorSize) - int64(1)) / int64(sectorSize) * int64(sectorSize)
			bSync = libc.BoolInt32((**(**TWalWriter)(__ccgo_up(bp))).FiSyncPoint == iOffset)
			for iOffset < (**(**TWalWriter)(__ccgo_up(bp))).FiSyncPoint {
				rc = _walWriteOneFrame(tls, bp, pLast, libc.Int32FromUint32(nTruncate), iOffset)
				if rc != 0 {
					return rc
				}
				iOffset = iOffset + int64(szFrame)
				nExtra = nExtra + 1
			}
		}
		if bSync != 0 {
			rc = _sqlite3OsSync(tls, (**(**TWalWriter)(__ccgo_up(bp))).FpFd, sync_flags&int32(0x03))
		}
	}
	/* If this frame set completes the first transaction in the WAL and
	 ** if PRAGMA journal_size_limit is set, then truncate the WAL to the
	 ** journal size limit, if possible.
	 */
	if isCommit != 0 && (*TWal)(unsafe.Pointer(pWal)).FtruncateOnCommit != 0 && (*TWal)(unsafe.Pointer(pWal)).FmxWalSize >= 0 {
		sz = (*TWal)(unsafe.Pointer(pWal)).FmxWalSize
		if int64(WAL_HDRSIZE)+libc.Int64FromUint32(iFrame+libc.Uint32FromInt32(nExtra)+libc.Uint32FromInt32(1)-libc.Uint32FromInt32(1))*int64(szPage+libc.Int32FromInt32(WAL_FRAME_HDRSIZE)) > (*TWal)(unsafe.Pointer(pWal)).FmxWalSize {
			sz = libc.Int64FromInt32(WAL_HDRSIZE) + libc.Int64FromUint32(iFrame+libc.Uint32FromInt32(nExtra)+libc.Uint32FromInt32(1)-libc.Uint32FromInt32(1))*int64(szPage+libc.Int32FromInt32(WAL_FRAME_HDRSIZE))
		}
		_walLimitSize(tls, pWal, sz)
		(*TWal)(unsafe.Pointer(pWal)).FtruncateOnCommit = uint8(0)
	}
	/* Append data to the wal-index. It is not necessary to lock the
	 ** wal-index to do this as the SQLITE_SHM_WRITE lock held on the wal-index
	 ** guarantees that there are no other writers, and no data that may
	 ** be in use by existing readers is being overwritten.
	 */
	iFrame = (*TWal)(unsafe.Pointer(pWal)).Fhdr.FmxFrame
	p = pList
	for {
		if !(p != 0 && rc == SQLITE_OK) {
			break
		}
		if libc.Int32FromUint16((*TPgHdr)(unsafe.Pointer(p)).Fflags)&int32(PGHDR_WAL_APPEND) == 0 {
			goto _6
		}
		iFrame = iFrame + 1
		rc = _walIndexAppend(tls, pWal, iFrame, (*TPgHdr)(unsafe.Pointer(p)).Fpgno)
		goto _6
	_6:
		;
		p = (*TPgHdr)(unsafe.Pointer(p)).FpDirty
	}
	for rc == SQLITE_OK && nExtra > 0 {
		iFrame = iFrame + 1
		nExtra = nExtra - 1
		rc = _walIndexAppend(tls, pWal, iFrame, (*TPgHdr)(unsafe.Pointer(pLast)).Fpgno)
	}
	if rc == SQLITE_OK {
		/* Update the private copy of the header. */
		(*TWal)(unsafe.Pointer(pWal)).Fhdr.FszPage = libc.Uint16FromInt32(szPage&libc.Int32FromInt32(0xff00) | szPage>>libc.Int32FromInt32(16))
		(*TWal)(unsafe.Pointer(pWal)).Fhdr.FmxFrame = iFrame
		if isCommit != 0 {
			(*TWal)(unsafe.Pointer(pWal)).Fhdr.FiChange = (*TWal)(unsafe.Pointer(pWal)).Fhdr.FiChange + 1
			(*TWal)(unsafe.Pointer(pWal)).Fhdr.FnPage = nTruncate
		}
		/* If this is a commit, update the wal-index header too. */
		if isCommit != 0 {
			_walIndexWriteHdr(tls, pWal)
			(*TWal)(unsafe.Pointer(pWal)).FiCallback = iFrame
		}
	}
	return rc
}

// C documentation
//
//	/*
//	** Set an entry in the wal-index that will map database page number
//	** pPage into WAL frame iFrame.
//	*/
func _walIndexAppend(tls *libc.TLS, pWal uintptr, iFrame Tu32, iPage Tu32) (r int32) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var iKey, idx, nByte, nCollide, rc, v2 int32
	var _ /* sLoc at bp+0 */ TWalHashLoc
	_, _, _, _, _, _ = iKey, idx, nByte, nCollide, rc, v2 /* Wal-index hash table location */
	rc = _walHashGet(tls, pWal, _walFramePage(tls, iFrame), bp)
	/* Assuming the wal-index file was successfully mapped, populate the
	 ** page number array and hash table entry.
	 */
	if rc == SQLITE_OK { /* Number of hash collisions */
		idx = libc.Int32FromUint32(iFrame - (**(**TWalHashLoc)(__ccgo_up(bp))).FiZero)
		/* If this is the first entry to be added to this hash-table, zero the
		 ** entire hash table and aPgno[] array before proceeding.
		 */
		if idx == int32(1) {
			nByte = int32(int64((**(**TWalHashLoc)(__ccgo_up(bp))).FaHash+uintptr(libc.Int32FromInt32(HASHTABLE_NPAGE)*libc.Int32FromInt32(2))*2) - int64((**(**TWalHashLoc)(__ccgo_up(bp))).FaPgno))
			libc.Xmemset(tls, (**(**TWalHashLoc)(__ccgo_up(bp))).FaPgno, 0, libc.Uint64FromInt32(nByte))
		}
		/* If the entry in aPgno[] is already set, then the previous writer
		 ** must have exited unexpectedly in the middle of a transaction (after
		 ** writing one or more dirty pages to the WAL to free up memory).
		 ** Remove the remnants of that writers uncommitted transaction from
		 ** the hash-table before writing any new entries.
		 */
		if **(**Tu32)(__ccgo_up((**(**TWalHashLoc)(__ccgo_up(bp))).FaPgno + uintptr(idx-int32(1))*4)) != 0 {
			_walCleanupHash(tls, pWal)
		}
		/* Write the aPgno[] array entry and the hash-table slot. */
		nCollide = idx
		iKey = _walHash(tls, iPage)
		for {
			if !(**(**Tht_slot)(__ccgo_up((**(**TWalHashLoc)(__ccgo_up(bp))).FaHash + uintptr(iKey)*2)) != 0) {
				break
			}
			v2 = nCollide
			nCollide = nCollide - 1
			if v2 == 0 {
				return _sqlite3CorruptError(tls, int32(68778))
			}
			goto _1
		_1:
			;
			iKey = _walNextHash(tls, iKey)
		}
		**(**Tu32)(__ccgo_up((**(**TWalHashLoc)(__ccgo_up(bp))).FaPgno + uintptr((idx-int32(1))&(libc.Int32FromInt32(HASHTABLE_NPAGE)-libc.Int32FromInt32(1)))*4)) = iPage
		libc.AtomicStoreNUint16((**(**TWalHashLoc)(__ccgo_up(bp))).FaHash+uintptr(iKey)*2, libc.Uint16FromInt32(idx), libc.Int32FromInt32(__ATOMIC_RELAXED))
	}
	return rc
}

// C documentation
//
//	/*
//	** Obtain a pointer to the iPage'th page of the wal-index. The wal-index
//	** is broken into pages of WALINDEX_PGSZ bytes. Wal-index pages are
//	** numbered from zero.
//	**
//	** If the wal-index is currently smaller the iPage pages then the size
//	** of the wal-index might be increased, but only if it is safe to do
//	** so.  It is safe to enlarge the wal-index if pWal->writeLock is true
//	** or pWal->exclusiveMode==WAL_HEAPMEMORY_MODE.
//	**
//	** Three possible result scenarios:
//	**
//	**   (1)  rc==SQLITE_OK    and *ppPage==Requested-Wal-Index-Page
//	**   (2)  rc>=SQLITE_ERROR and *ppPage==NULL
//	**   (3)  rc==SQLITE_OK    and *ppPage==NULL  // only if iPage==0
//	**
//	** Scenario (3) can only occur when pWal->writeLock is false and iPage==0
//	*/
func _walIndexPageRealloc(tls *libc.TLS, pWal uintptr, iPage int32, ppPage uintptr) (r int32) {
	var apNew, v1 uintptr
	var nByte Tsqlite3_int64
	var rc int32
	_, _, _, _ = apNew, nByte, rc, v1
	rc = SQLITE_OK
	/* Enlarge the pWal->apWiData[] array if required */
	if (*TWal)(unsafe.Pointer(pWal)).FnWiData <= iPage {
		nByte = libc.Int64FromUint64(uint64(8) * libc.Uint64FromInt64(libc.Int64FromInt32(1)+int64(iPage)))
		apNew = _sqlite3Realloc(tls, (*TWal)(unsafe.Pointer(pWal)).FapWiData, libc.Uint64FromInt64(nByte))
		if !(apNew != 0) {
			**(**uintptr)(__ccgo_up(ppPage)) = uintptr(0)
			return int32(SQLITE_NOMEM)
		}
		libc.Xmemset(tls, apNew+uintptr((*TWal)(unsafe.Pointer(pWal)).FnWiData)*8, 0, uint64(8)*libc.Uint64FromInt32(iPage+libc.Int32FromInt32(1)-(*TWal)(unsafe.Pointer(pWal)).FnWiData))
		(*TWal)(unsafe.Pointer(pWal)).FapWiData = apNew
		(*TWal)(unsafe.Pointer(pWal)).FnWiData = iPage + int32(1)
	}
	/* Request a pointer to the required page from the VFS */
	if libc.Int32FromUint8((*TWal)(unsafe.Pointer(pWal)).FexclusiveMode) == int32(WAL_HEAPMEMORY_MODE) {
		**(**uintptr)(__ccgo_up((*TWal)(unsafe.Pointer(pWal)).FapWiData + uintptr(iPage)*8)) = _sqlite3MallocZero(tls, uint64(libc.Uint64FromInt64(2)*libc.Uint64FromInt32(libc.Int32FromInt32(HASHTABLE_NPAGE)*libc.Int32FromInt32(2))+libc.Uint64FromInt32(HASHTABLE_NPAGE)*libc.Uint64FromInt64(4)))
		if !(**(**uintptr)(__ccgo_up((*TWal)(unsafe.Pointer(pWal)).FapWiData + uintptr(iPage)*8)) != 0) {
			rc = int32(SQLITE_NOMEM)
		}
	} else {
		rc = _sqlite3OsShmMap(tls, (*TWal)(unsafe.Pointer(pWal)).FpDbFd, iPage, libc.Int32FromUint64(libc.Uint64FromInt64(2)*libc.Uint64FromInt32(libc.Int32FromInt32(HASHTABLE_NPAGE)*libc.Int32FromInt32(2))+libc.Uint64FromInt32(HASHTABLE_NPAGE)*libc.Uint64FromInt64(4)), libc.Int32FromUint8((*TWal)(unsafe.Pointer(pWal)).FwriteLock), (*TWal)(unsafe.Pointer(pWal)).FapWiData+uintptr(iPage)*8)
		if rc == SQLITE_OK {
			if iPage > 0 && _sqlite3FaultSim(tls, int32(600)) != 0 {
				rc = int32(SQLITE_NOMEM)
			}
		} else {
			if rc&int32(0xff) == int32(SQLITE_READONLY) {
				v1 = pWal + 66
				*(*Tu8)(unsafe.Pointer(v1)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v1))) | libc.Int32FromInt32(WAL_SHM_RDONLY))
				if rc == int32(SQLITE_READONLY) {
					rc = SQLITE_OK
				}
			}
		}
	}
	**(**uintptr)(__ccgo_up(ppPage)) = **(**uintptr)(__ccgo_up((*TWal)(unsafe.Pointer(pWal)).FapWiData + uintptr(iPage)*8))
	return rc
}

// C documentation
//
//	/*
//	** Try to read the wal-index header.  Return 0 on success and 1 if
//	** there is a problem.
//	**
//	** The wal-index is in shared memory.  Another thread or process might
//	** be writing the header at the same time this procedure is trying to
//	** read it, which might result in inconsistency.  A dirty read is detected
//	** by verifying that both copies of the header are the same and also by
//	** a checksum on the header.
//	**
//	** If and only if the read is consistent and the header is different from
//	** pWal->hdr, then pWal->hdr is updated to the content of the new header
//	** and *pChanged is set to 1.
//	**
//	** If the checksum cannot be verified return non-zero. If the header
//	** is read successfully and the checksum verified, return zero.
//	*/
func _walIndexTryHdr(tls *libc.TLS, pWal uintptr, pChanged uintptr) (r int32) {
	bp := tls.Alloc(112)
	defer tls.Free(112)
	var aHdr uintptr
	var _ /* aCksum at bp+0 */ [2]Tu32
	var _ /* h1 at bp+8 */ TWalIndexHdr
	var _ /* h2 at bp+56 */ TWalIndexHdr
	_ = aHdr /* Header in shared memory */
	/* The first page of the wal-index must be mapped at this point. */
	/* Read the header. This might happen concurrently with a write to the
	 ** same area of shared memory on a different CPU in a SMP,
	 ** meaning it is possible that an inconsistent snapshot is read
	 ** from the file. If this happens, return non-zero.
	 **
	 ** tag-20200519-1:
	 ** There are two copies of the header at the beginning of the wal-index.
	 ** When reading, read [0] first then [1].  Writes are in the reverse order.
	 ** Memory barriers are used to prevent the compiler or the hardware from
	 ** reordering the reads and writes.  TSAN and similar tools can sometimes
	 ** give false-positive warnings about these accesses because the tools do not
	 ** account for the double-read and the memory barrier. The use of mutexes
	 ** here would be problematic as the memory being accessed is potentially
	 ** shared among multiple processes and not all mutex implementations work
	 ** reliably in that environment.
	 */
	aHdr = _walIndexHdr(tls, pWal)
	libc.Xmemcpy(tls, bp+8, aHdr, uint64(48)) /* Possible TSAN false-positive */
	_walShmBarrier(tls, pWal)
	libc.Xmemcpy(tls, bp+56, aHdr+1*48, uint64(48))
	if libc.Xmemcmp(tls, bp+8, bp+56, uint64(48)) != 0 {
		return int32(1) /* Dirty read */
	}
	if libc.Int32FromUint8((**(**TWalIndexHdr)(__ccgo_up(bp + 8))).FisInit) == 0 {
		return int32(1) /* Malformed header - probably all zeros */
	}
	_walChecksumBytes(tls, int32(1), bp+8, libc.Int32FromUint64(libc.Uint64FromInt64(48)-libc.Uint64FromInt64(8)), uintptr(0), bp)
	if (**(**[2]Tu32)(__ccgo_up(bp)))[0] != **(**Tu32)(__ccgo_up(bp + 8 + 40)) || (**(**[2]Tu32)(__ccgo_up(bp)))[int32(1)] != **(**Tu32)(__ccgo_up(bp + 8 + 40 + 1*4)) {
		return int32(1) /* Checksum does not match */
	}
	if libc.Xmemcmp(tls, pWal+72, bp+8, uint64(48)) != 0 {
		**(**int32)(__ccgo_up(pChanged)) = int32(1)
		libc.Xmemcpy(tls, pWal+72, bp+8, uint64(48))
		(*TWal)(unsafe.Pointer(pWal)).FszPage = libc.Uint32FromInt32(libc.Int32FromUint16((*TWal)(unsafe.Pointer(pWal)).Fhdr.FszPage)&int32(0xfe00) + libc.Int32FromUint16((*TWal)(unsafe.Pointer(pWal)).Fhdr.FszPage)&int32(0x0001)<<int32(16))
	}
	/* The header was successfully read. Return zero. */
	return 0
}

/*
** This is the value that walTryBeginRead returns when it needs to
** be retried.
 */

// C documentation
//
//	/*
//	** Write the header information in pWal->hdr into the wal-index.
//	**
//	** The checksum on pWal->hdr is updated before it is written.
//	*/
func _walIndexWriteHdr(tls *libc.TLS, pWal uintptr) {
	var aHdr uintptr
	var nCksum int32
	_, _ = aHdr, nCksum
	aHdr = _walIndexHdr(tls, pWal)
	nCksum = libc.Int32FromUint64(uint64(libc.UintptrFromInt32(0) + 40))
	(*TWal)(unsafe.Pointer(pWal)).Fhdr.FisInit = uint8(1)
	(*TWal)(unsafe.Pointer(pWal)).Fhdr.FiVersion = uint32(WALINDEX_MAX_VERSION)
	_walChecksumBytes(tls, int32(1), pWal+72, nCksum, uintptr(0), pWal+72+40)
	/* Possible TSAN false-positive.  See tag-20200519-1 */
	libc.Xmemcpy(tls, aHdr+1*48, pWal+72, uint64(48))
	_walShmBarrier(tls, pWal)
	libc.Xmemcpy(tls, aHdr, pWal+72, uint64(48))
}

// C documentation
//
//	/*
//	** Construct a WalInterator object that can be used to loop over all
//	** pages in the WAL following frame nBackfill in ascending order. Frames
//	** nBackfill or earlier may be included - excluding them is an optimization
//	** only. The caller must hold the checkpoint lock.
//	**
//	** On success, make *pp point to the newly allocated WalInterator object
//	** return SQLITE_OK. Otherwise, return an error code. If this routine
//	** returns an error, the value of *pp is undefined.
//	**
//	** The calling routine should invoke walIteratorFree() to destroy the
//	** WalIterator object when it has finished with it.
//	*/
func _walIteratorInit(tls *libc.TLS, pWal uintptr, nBackfill Tu32, pp uintptr) (r int32) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var aIndex, aTmp, p uintptr
	var i, j, nSegment, rc int32
	var iLast Tu32
	var nByte Tsqlite3_int64
	var v1 uint32
	var _ /* nEntry at bp+24 */ int32
	var _ /* sLoc at bp+0 */ TWalHashLoc
	_, _, _, _, _, _, _, _, _, _ = aIndex, aTmp, i, iLast, j, nByte, nSegment, p, rc, v1 /* Temp space used by merge-sort */
	rc = SQLITE_OK                                                                       /* Return Code */
	/* This routine only runs while holding the checkpoint lock. And
	 ** it only runs if there is actually content in the log (mxFrame>0).
	 */
	iLast = (*TWal)(unsafe.Pointer(pWal)).Fhdr.FmxFrame
	/* Allocate space for the WalIterator object. */
	nSegment = _walFramePage(tls, iLast) + int32(1)
	nByte = libc.Int64FromUint64(uint64(libc.UintptrFromInt32(0)+8) + libc.Uint64FromInt32(nSegment)*uint64(32) + uint64(iLast)*uint64(2))
	if iLast > uint32(HASHTABLE_NPAGE) {
		v1 = uint32(HASHTABLE_NPAGE)
	} else {
		v1 = iLast
	}
	p = Xsqlite3_malloc64(tls, libc.Uint64FromInt64(nByte)+uint64(2)*uint64(v1))
	if !(p != 0) {
		return int32(SQLITE_NOMEM)
	}
	libc.Xmemset(tls, p, 0, libc.Uint64FromInt64(nByte))
	(*TWalIterator)(unsafe.Pointer(p)).FnSegment = nSegment
	aTmp = p + uintptr(nByte)
	i = _walFramePage(tls, nBackfill+uint32(1))
	for {
		if !(rc == SQLITE_OK && i < nSegment) {
			break
		}
		rc = _walHashGet(tls, pWal, i, bp)
		if rc == SQLITE_OK { /* Sorted index for this segment */
			if i+int32(1) == nSegment {
				**(**int32)(__ccgo_up(bp + 24)) = libc.Int32FromUint32(iLast - (**(**TWalHashLoc)(__ccgo_up(bp))).FiZero)
			} else {
				**(**int32)(__ccgo_up(bp + 24)) = int32((int64((**(**TWalHashLoc)(__ccgo_up(bp))).FaHash) - int64((**(**TWalHashLoc)(__ccgo_up(bp))).FaPgno)) / 4)
			}
			aIndex = p + 8 + uintptr((*TWalIterator)(unsafe.Pointer(p)).FnSegment)*32 + uintptr((**(**TWalHashLoc)(__ccgo_up(bp))).FiZero)*2
			(**(**TWalHashLoc)(__ccgo_up(bp))).FiZero = (**(**TWalHashLoc)(__ccgo_up(bp))).FiZero + 1
			j = 0
			for {
				if !(j < **(**int32)(__ccgo_up(bp + 24))) {
					break
				}
				**(**Tht_slot)(__ccgo_up(aIndex + uintptr(j)*2)) = libc.Uint16FromInt32(j)
				goto _3
			_3:
				;
				j = j + 1
			}
			_walMergesort(tls, (**(**TWalHashLoc)(__ccgo_up(bp))).FaPgno, aTmp, aIndex, bp+24)
			(*(*TWalSegment)(unsafe.Pointer(p + 8 + uintptr(i)*32))).FiZero = libc.Int32FromUint32((**(**TWalHashLoc)(__ccgo_up(bp))).FiZero)
			(*(*TWalSegment)(unsafe.Pointer(p + 8 + uintptr(i)*32))).FnEntry = **(**int32)(__ccgo_up(bp + 24))
			(*(*TWalSegment)(unsafe.Pointer(p + 8 + uintptr(i)*32))).FaIndex = aIndex
			(*(*TWalSegment)(unsafe.Pointer(p + 8 + uintptr(i)*32))).FaPgno = (**(**TWalHashLoc)(__ccgo_up(bp))).FaPgno
		}
		goto _2
	_2:
		;
		i = i + 1
	}
	if rc != SQLITE_OK {
		_walIteratorFree(tls, p)
		p = uintptr(0)
	}
	**(**uintptr)(__ccgo_up(pp)) = p
	return rc
}

// C documentation
//
//	/*
//	** This function merges two sorted lists into a single sorted list.
//	**
//	** aLeft[] and aRight[] are arrays of indices.  The sort key is
//	** aContent[aLeft[]] and aContent[aRight[]].  Upon entry, the following
//	** is guaranteed for all J<K:
//	**
//	**        aContent[aLeft[J]] < aContent[aLeft[K]]
//	**        aContent[aRight[J]] < aContent[aRight[K]]
//	**
//	** This routine overwrites aRight[] with a new (probably longer) sequence
//	** of indices such that the aRight[] contains every index that appears in
//	** either aLeft[] or the old aRight[] and such that the second condition
//	** above is still met.
//	**
//	** The aContent[aLeft[X]] values will be unique for all X.  And the
//	** aContent[aRight[X]] values will be unique too.  But there might be
//	** one or more combinations of X and Y such that
//	**
//	**      aLeft[X]!=aRight[Y]  &&  aContent[aLeft[X]] == aContent[aRight[Y]]
//	**
//	** When that happens, omit the aLeft[X] and use the aRight[Y] index.
//	*/
func _walMerge(tls *libc.TLS, aContent uintptr, aLeft uintptr, nLeft int32, paRight uintptr, pnRight uintptr, aTmp uintptr) {
	var aRight uintptr
	var dbpage TPgno
	var iLeft, iOut, iRight, nRight, v1 int32
	var logpage Tht_slot
	_, _, _, _, _, _, _, _ = aRight, dbpage, iLeft, iOut, iRight, logpage, nRight, v1
	iLeft = 0  /* Current index in aLeft */
	iRight = 0 /* Current index in aRight */
	iOut = 0   /* Current index in output buffer */
	nRight = **(**int32)(__ccgo_up(pnRight))
	aRight = **(**uintptr)(__ccgo_up(paRight))
	for iRight < nRight || iLeft < nLeft {
		if iLeft < nLeft && (iRight >= nRight || **(**Tu32)(__ccgo_up(aContent + uintptr(**(**Tht_slot)(__ccgo_up(aLeft + uintptr(iLeft)*2)))*4)) < **(**Tu32)(__ccgo_up(aContent + uintptr(**(**Tht_slot)(__ccgo_up(aRight + uintptr(iRight)*2)))*4))) {
			v1 = iLeft
			iLeft = iLeft + 1
			logpage = **(**Tht_slot)(__ccgo_up(aLeft + uintptr(v1)*2))
		} else {
			v1 = iRight
			iRight = iRight + 1
			logpage = **(**Tht_slot)(__ccgo_up(aRight + uintptr(v1)*2))
		}
		dbpage = **(**Tu32)(__ccgo_up(aContent + uintptr(logpage)*4))
		v1 = iOut
		iOut = iOut + 1
		**(**Tht_slot)(__ccgo_up(aTmp + uintptr(v1)*2)) = logpage
		if iLeft < nLeft && **(**Tu32)(__ccgo_up(aContent + uintptr(**(**Tht_slot)(__ccgo_up(aLeft + uintptr(iLeft)*2)))*4)) == dbpage {
			iLeft = iLeft + 1
		}
	}
	**(**uintptr)(__ccgo_up(paRight)) = aLeft
	**(**int32)(__ccgo_up(pnRight)) = iOut
	libc.Xmemcpy(tls, aLeft, aTmp, uint64(2)*libc.Uint64FromInt32(iOut))
}

// C documentation
//
//	/*
//	** Sort the elements in list aList using aContent[] as the sort key.
//	** Remove elements with duplicate keys, preferring to keep the
//	** larger aList[] values.
//	**
//	** The aList[] entries are indices into aContent[].  The values in
//	** aList[] are to be sorted so that for all J<K:
//	**
//	**      aContent[aList[J]] < aContent[aList[K]]
//	**
//	** For any X and Y such that
//	**
//	**      aContent[aList[X]] == aContent[aList[Y]]
//	**
//	** Keep the larger of the two values aList[X] and aList[Y] and discard
//	** the smaller.
//	*/
func _walMergesort(tls *libc.TLS, aContent uintptr, aBuffer uintptr, aList uintptr, pnList uintptr) {
	bp := tls.Alloc(224)
	defer tls.Free(224)
	var iList, nList int32
	var iSub Tu32
	var p, p1 uintptr
	var _ /* aMerge at bp+8 */ uintptr
	var _ /* aSub at bp+16 */ [13]struct {
		FnList int32
		FaList uintptr
	}
	var _ /* nMerge at bp+0 */ int32
	_, _, _, _, _ = iList, iSub, nList, p, p1
	nList = **(**int32)(__ccgo_up(pnList))        /* Size of input list */
	**(**int32)(__ccgo_up(bp)) = 0                /* Number of elements in list aMerge */
	**(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0) /* Index into input list */
	iSub = uint32(0)                              /* Array of sub-lists */
	libc.Xmemset(tls, bp+16, 0, uint64(208))
	iList = 0
	for {
		if !(iList < nList) {
			break
		}
		**(**int32)(__ccgo_up(bp)) = int32(1)
		**(**uintptr)(__ccgo_up(bp + 8)) = aList + uintptr(iList)*2
		iSub = uint32(0)
		for {
			if !(iList&(int32(1)<<iSub) != 0) {
				break
			}
			p = bp + 16 + uintptr(iSub)*16
			_walMerge(tls, aContent, (*struct {
				FnList int32
				FaList uintptr
			})(unsafe.Pointer(p)).FaList, (*struct {
				FnList int32
				FaList uintptr
			})(unsafe.Pointer(p)).FnList, bp+8, bp, aBuffer)
			goto _2
		_2:
			;
			iSub = iSub + 1
		}
		(**(**[13]struct {
			FnList int32
			FaList uintptr
		})(__ccgo_up(bp + 16)))[iSub].FaList = **(**uintptr)(__ccgo_up(bp + 8))
		(**(**[13]struct {
			FnList int32
			FaList uintptr
		})(__ccgo_up(bp + 16)))[iSub].FnList = **(**int32)(__ccgo_up(bp))
		goto _1
	_1:
		;
		iList = iList + 1
	}
	iSub = iSub + 1
	for {
		if !(iSub < libc.Uint32FromInt32(libc.Int32FromUint64(libc.Uint64FromInt64(208)/libc.Uint64FromInt64(16)))) {
			break
		}
		if nList&(int32(1)<<iSub) != 0 {
			p1 = bp + 16 + uintptr(iSub)*16
			_walMerge(tls, aContent, (*struct {
				FnList int32
				FaList uintptr
			})(unsafe.Pointer(p1)).FaList, (*struct {
				FnList int32
				FaList uintptr
			})(unsafe.Pointer(p1)).FnList, bp+8, bp, aBuffer)
		}
		goto _3
	_3:
		;
		iSub = iSub + 1
	}
	**(**int32)(__ccgo_up(pnList)) = **(**int32)(__ccgo_up(bp))
}

// C documentation
//
//	/*
//	** The following is guaranteed when this function is called:
//	**
//	**   a) the WRITER lock is held,
//	**   b) the entire log file has been checkpointed, and
//	**   c) any existing readers are reading exclusively from the database
//	**      file - there are no readers that may attempt to read a frame from
//	**      the log file.
//	**
//	** This function updates the shared-memory structures so that the next
//	** client to write to the database (which may be this one) does so by
//	** writing frames into the start of the log file.
//	**
//	** The value of parameter salt1 is used as the aSalt[1] value in the
//	** new wal-index header. It should be passed a pseudo-random value (i.e.
//	** one obtained from sqlite3_randomness()).
//	*/
func _walRestartHdr(tls *libc.TLS, pWal uintptr, _salt1 Tu32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	*(*Tu32)(unsafe.Pointer(bp)) = _salt1
	var aSalt, pInfo uintptr
	var i int32
	_, _, _ = aSalt, i, pInfo
	pInfo = _walCkptInfo(tls, pWal) /* Loop counter */
	aSalt = pWal + 72 + 32          /* Big-endian salt values */
	(*TWal)(unsafe.Pointer(pWal)).FnCkpt = (*TWal)(unsafe.Pointer(pWal)).FnCkpt + 1
	(*TWal)(unsafe.Pointer(pWal)).Fhdr.FmxFrame = uint32(0)
	_sqlite3Put4byte(tls, aSalt, uint32(1)+_sqlite3Get4byte(tls, aSalt))
	libc.Xmemcpy(tls, pWal+72+32+1*4, bp, uint64(4))
	_walIndexWriteHdr(tls, pWal)
	libc.AtomicStoreNUint32(pInfo, libc.Uint32FromInt32(libc.Int32FromInt32(0)), libc.Int32FromInt32(__ATOMIC_RELAXED))
	(*TWalCkptInfo)(unsafe.Pointer(pInfo)).FnBackfillAttempted = uint32(0)
	**(**Tu32)(__ccgo_up(pInfo + 4 + 1*4)) = uint32(0)
	i = int32(2)
	for {
		if !(i < libc.Int32FromInt32(SQLITE_SHM_NLOCK)-libc.Int32FromInt32(3)) {
			break
		}
		**(**Tu32)(__ccgo_up(pInfo + 4 + uintptr(i)*4)) = uint32(READMARK_NOT_USED)
		goto _1
	_1:
		;
		i = i + 1
	}
}

// C documentation
//
//	/*
//	** Add a single new WhereTerm entry to the WhereClause object pWC.
//	** The new WhereTerm object is constructed from Expr p and with wtFlags.
//	** The index in pWC->a[] of the new WhereTerm is returned on success.
//	** 0 is returned if the new WhereTerm could not be added due to a memory
//	** allocation error.  The memory allocation failure will be recorded in
//	** the db->mallocFailed flag so that higher-level functions can detect it.
//	**
//	** This routine will increase the size of the pWC->a[] array as necessary.
//	**
//	** If the wtFlags argument includes TERM_DYNAMIC, then responsibility
//	** for freeing the expression p is assumed by the WhereClause object pWC.
//	** This is true even if this routine fails to allocate a new WhereTerm.
//	**
//	** WARNING:  This routine might reallocate the space used to store
//	** WhereTerms.  All pointers to WhereTerms should be invalidated after
//	** calling this routine.  Such pointers may be reinitialized by referencing
//	** the pWC->a[] array.
//	*/
func _whereClauseInsert(tls *libc.TLS, pWC uintptr, p uintptr, wtFlags Tu16) (r int32) {
	var db, pOld, pTerm, v3 uintptr
	var idx, v1, v2 int32
	_, _, _, _, _, _, _ = db, idx, pOld, pTerm, v1, v2, v3
	if (*TWhereClause)(unsafe.Pointer(pWC)).FnTerm >= (*TWhereClause)(unsafe.Pointer(pWC)).FnSlot {
		pOld = (*TWhereClause)(unsafe.Pointer(pWC)).Fa
		db = (*TParse)(unsafe.Pointer((*TWhereInfo)(unsafe.Pointer((*TWhereClause)(unsafe.Pointer(pWC)).FpWInfo)).FpParse)).Fdb
		(*TWhereClause)(unsafe.Pointer(pWC)).Fa = _sqlite3WhereMalloc(tls, (*TWhereClause)(unsafe.Pointer(pWC)).FpWInfo, uint64(uint64(56)*libc.Uint64FromInt32((*TWhereClause)(unsafe.Pointer(pWC)).FnSlot)*uint64(2)))
		if (*TWhereClause)(unsafe.Pointer(pWC)).Fa == uintptr(0) {
			if libc.Int32FromUint16(wtFlags)&int32(TERM_DYNAMIC) != 0 {
				_sqlite3ExprDelete(tls, db, p)
			}
			(*TWhereClause)(unsafe.Pointer(pWC)).Fa = pOld
			return 0
		}
		libc.Xmemcpy(tls, (*TWhereClause)(unsafe.Pointer(pWC)).Fa, pOld, uint64(56)*libc.Uint64FromInt32((*TWhereClause)(unsafe.Pointer(pWC)).FnTerm))
		(*TWhereClause)(unsafe.Pointer(pWC)).FnSlot = (*TWhereClause)(unsafe.Pointer(pWC)).FnSlot * int32(2)
	}
	v3 = pWC + 20
	v2 = *(*int32)(unsafe.Pointer(v3))
	*(*int32)(unsafe.Pointer(v3)) = *(*int32)(unsafe.Pointer(v3)) + 1
	v1 = v2
	idx = v1
	pTerm = (*TWhereClause)(unsafe.Pointer(pWC)).Fa + uintptr(v1)*56
	if libc.Int32FromUint16(wtFlags)&int32(TERM_VIRTUAL) == 0 {
		(*TWhereClause)(unsafe.Pointer(pWC)).FnBase = (*TWhereClause)(unsafe.Pointer(pWC)).FnTerm
	}
	if p != 0 && (*TExpr)(unsafe.Pointer(p)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_Unlikely)) != uint32(0) {
		(*TWhereTerm)(unsafe.Pointer(pTerm)).FtruthProb = int16(int32(_sqlite3LogEst(tls, libc.Uint64FromInt32((*TExpr)(unsafe.Pointer(p)).FiTable))) - int32(270))
	} else {
		(*TWhereTerm)(unsafe.Pointer(pTerm)).FtruthProb = int16(1)
	}
	(*TWhereTerm)(unsafe.Pointer(pTerm)).FpExpr = _sqlite3ExprSkipCollateAndLikely(tls, p)
	(*TWhereTerm)(unsafe.Pointer(pTerm)).FwtFlags = wtFlags
	(*TWhereTerm)(unsafe.Pointer(pTerm)).FpWC = pWC
	(*TWhereTerm)(unsafe.Pointer(pTerm)).FiParent = -int32(1)
	libc.Xmemset(tls, pTerm+20, 0, libc.Uint64FromInt64(56)-uint64(libc.UintptrFromInt32(0)+20))
	return idx
}

// C documentation
//
//	/*
//	** pIdx is an index that covers all of the low-number columns used by
//	** pWInfo->pSelect (columns from 0 through 62) or an index that has
//	** expressions terms.  Hence, we cannot determine whether or not it is
//	** a covering index by using the colUsed bitmasks.  We have to do a search
//	** to see if the index is covering.  This routine does that search.
//	**
//	** The return value is one of these:
//	**
//	**      0                The index is definitely not a covering index
//	**
//	**      WHERE_IDX_ONLY   The index is definitely a covering index
//	**
//	**      WHERE_EXPRIDX    The index is likely a covering index, but it is
//	**                       difficult to determine precisely because of the
//	**                       expressions that are indexed.  Score it as a
//	**                       covering index, but still keep the main table open
//	**                       just in case we need it.
//	**
//	** This routine is an optimization.  It is always safe to return zero.
//	** But returning one of the other two values when zero should have been
//	** returned can lead to incorrect bytecode and assertion faults.
//	*/
func _whereIsCoveringIndex(tls *libc.TLS, pWInfo uintptr, pIdx uintptr, iTabCur int32) (r Tu32) {
	bp := tls.Alloc(64)
	defer tls.Free(64)
	var i, rc int32
	var _ /* ck at bp+0 */ TCoveringIndexCheck
	var _ /* w at bp+16 */ TWalker
	_, _ = i, rc
	if (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpSelect == uintptr(0) {
		/* We don't have access to the full query, so we cannot check to see
		 ** if pIdx is covering.  Assume it is not. */
		return uint32(0)
	}
	if int32(uint32(*(*uint16)(unsafe.Pointer(pIdx + 100))&0x800>>11)) == 0 {
		i = 0
		for {
			if !(i < libc.Int32FromUint16((*TIndex)(unsafe.Pointer(pIdx)).FnColumn)) {
				break
			}
			if int32(**(**Ti16)(__ccgo_up((*TIndex)(unsafe.Pointer(pIdx)).FaiColumn + uintptr(i)*2))) >= libc.Int32FromUint64(libc.Uint64FromInt64(8)*libc.Uint64FromInt32(8))-libc.Int32FromInt32(1) {
				break
			}
			goto _1
		_1:
			;
			i = i + 1
		}
		if i >= libc.Int32FromUint16((*TIndex)(unsafe.Pointer(pIdx)).FnColumn) {
			/* pIdx does not index any columns greater than 62, but we know from
			 ** colMask that columns greater than 62 are used, so this is not a
			 ** covering index */
			return uint32(0)
		}
	}
	(**(**TCoveringIndexCheck)(__ccgo_up(bp))).FpIdx = pIdx
	(**(**TCoveringIndexCheck)(__ccgo_up(bp))).FiTabCur = iTabCur
	(**(**TCoveringIndexCheck)(__ccgo_up(bp))).FbExpr = uint8(0)
	(**(**TCoveringIndexCheck)(__ccgo_up(bp))).FbUnidx = uint8(0)
	libc.Xmemset(tls, bp+16, 0, uint64(48))
	(**(**TWalker)(__ccgo_up(bp + 16))).FxExprCallback = __ccgo_fp(_whereIsCoveringIndexWalkCallback)
	(**(**TWalker)(__ccgo_up(bp + 16))).FxSelectCallback = __ccgo_fp(_sqlite3SelectWalkNoop)
	*(*uintptr)(unsafe.Pointer(bp + 16 + 40)) = bp
	_sqlite3WalkSelect(tls, bp+16, (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpSelect)
	if (**(**TCoveringIndexCheck)(__ccgo_up(bp))).FbUnidx != 0 {
		rc = 0
	} else {
		if (**(**TCoveringIndexCheck)(__ccgo_up(bp))).FbExpr != 0 {
			rc = int32(WHERE_EXPRIDX)
		} else {
			rc = int32(WHERE_IDX_ONLY)
		}
	}
	return libc.Uint32FromInt32(rc)
}

// 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(176)
	defer tls.Free(176)
	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+164 */ Ti16
	var _ /* aiRowEstPk at bp+160 */ [2]TLogEst
	var _ /* m at bp+168 */ 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 + 164)) = 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)*80
	pTab = (*TSrcItem)(unsafe.Pointer(pSrc)).FpSTab
	pWC = (*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FpWC
	if int32(*(*uint32)(unsafe.Pointer(pSrc + 24 + 4))&0x2>>1) != 0 {
		/* An INDEXED BY clause specifies a particular index to use */
		pProbe = *(*uintptr)(unsafe.Pointer(pSrc + 56))
	} 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, uint64(160))
			(**(**TIndex)(__ccgo_up(bp))).FnKeyCol = uint16(1)
			(**(**TIndex)(__ccgo_up(bp))).FnColumn = uint16(1)
			(**(**TIndex)(__ccgo_up(bp))).FaiColumn = bp + 164
			(**(**TIndex)(__ccgo_up(bp))).FaiRowLogEst = bp + 160
			(**(**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+100, libc.Uint32FromInt32(SQLITE_IDXTYPE_IPK), 0, 0x3)
			(**(**[2]TLogEst)(__ccgo_up(bp + 160)))[0] = (*TTable)(unsafe.Pointer(pTab)).FnRowLogEst
			(**(**[2]TLogEst)(__ccgo_up(bp + 160)))[int32(1)] = 0
			pFirst = (*TTable)(unsafe.Pointer((*TSrcItem)(unsafe.Pointer(pSrc)).FpSTab)).FpIndex
			if int32(*(*uint32)(unsafe.Pointer(pSrc + 24 + 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 + 24 + 4))&0x2>>1) != 0) && !(int32(*(*uint32)(unsafe.Pointer(pSrc + 24 + 4))&0x1>>0) != 0) && !(int32(*(*uint32)(unsafe.Pointer(pSrc + 24 + 4))&0x10>>4) != 0) && !(int32(*(*uint32)(unsafe.Pointer(pSrc + 24 + 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)*56
		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 += 56
		}
	}
	/* 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 + 100))&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 + 100))&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 + 24 + 4))&0x4>>2) != 0 {
				if int32(*(*uint32)(unsafe.Pointer(pSrc + 24 + 4))&0x40>>6) != 0 {
					**(**Tu32)(__ccgo_up(pNew + 48)) |= 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 + 72)))).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 + 72)))).FpSelect)).FpOrderBy
				}
			} else {
				if int32(*(*uint32)(unsafe.Pointer(pSrc + 24 + 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 + 100))&0x20>>5)) != 0 {
				**(**TBitmask)(__ccgo_up(bp + 168)) = uint64(0)
				(*TWhereLoop)(unsafe.Pointer(pNew)).FwsFlags = libc.Uint32FromInt32(libc.Int32FromInt32(WHERE_IDX_ONLY) | libc.Int32FromInt32(WHERE_INDEXED))
			} else {
				**(**TBitmask)(__ccgo_up(bp + 168)) = (*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+168, 0, uintptr(0))
				}
				(*TWhereLoop)(unsafe.Pointer(pNew)).FwsFlags = uint32(WHERE_INDEXED)
				if **(**TBitmask)(__ccgo_up(bp + 168)) == libc.Uint64FromInt32(1)<<(libc.Int32FromUint64(libc.Uint64FromInt64(8)*libc.Uint64FromInt32(8))-libc.Int32FromInt32(1)) || int32(uint32(*(*uint16)(unsafe.Pointer(pProbe + 100))&0x800>>11)) != 0 && !(int32(uint32(*(*uint16)(unsafe.Pointer(pProbe + 100))&0x400>>10)) != 0) && **(**TBitmask)(__ccgo_up(bp + 168)) != uint64(0) {
					isCov = _whereIsCoveringIndex(tls, pWInfo, pProbe, (*TSrcItem)(unsafe.Pointer(pSrc)).FiCursor)
					if isCov == uint32(0) {
					} else {
						**(**TBitmask)(__ccgo_up(bp + 168)) = uint64(0)
						**(**Tu32)(__ccgo_up(pNew + 48)) |= isCov
						if isCov&uint32(WHERE_IDX_ONLY) != 0 {
						} else {
						}
					}
				} else {
					if **(**TBitmask)(__ccgo_up(bp + 168)) == 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 + 24 + 4))&0x2>>1) != 0 || **(**TBitmask)(__ccgo_up(bp + 168)) == uint64(0) && int32(uint32(*(*uint16)(unsafe.Pointer(pProbe + 100))&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 + 168)) != 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 + 104
					ii = 0
					for {
						if !(ii < (*TWhereClause)(unsafe.Pointer(pWC2)).FnTerm) {
							break
						}
						pTerm1 = (*TWhereClause)(unsafe.Pointer(pWC2)).Fa + uintptr(ii)*56
						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 + 24 + 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 + 48)) |= 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 + 24 + 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(720)
	defer tls.Free(720)
	var i, iCur, j, once, rc int32
	var pItem, pNew, pOrTerm, pOrWC, pOrWCEnd, pTerm, pWC, pWCEnd, pWInfo uintptr
	var _ /* sCur at bp+600 */ TWhereOrSet
	var _ /* sPrev at bp+656 */ TWhereOrSet
	var _ /* sSubBuild at bp+488 */ TWhereLoopBuilder
	var _ /* sSum at bp+544 */ 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)*56
	pNew = (*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FpNew
	libc.Xmemset(tls, bp+544, 0, uint64(56))
	pItem = (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpTabList + 8 + uintptr((*TWhereLoop)(unsafe.Pointer(pNew)).FiTab)*80
	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(pTerm + 32)))).Findexable&(*TWhereLoop)(unsafe.Pointer(pNew)).FmaskSelf != uint64(0) {
			pOrWC = *(*uintptr)(unsafe.Pointer(pTerm + 32))
			pOrWCEnd = (*TWhereClause)(unsafe.Pointer(pOrWC)).Fa + uintptr((*TWhereClause)(unsafe.Pointer(pOrWC)).FnTerm)*56
			once = int32(1)
			**(**TWhereLoopBuilder)(__ccgo_up(bp + 488)) = **(**TWhereLoopBuilder)(__ccgo_up(pBuilder))
			(**(**TWhereLoopBuilder)(__ccgo_up(bp + 488))).FpOrSet = bp + 600
			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 + 488))).FpWC = *(*uintptr)(unsafe.Pointer(pOrTerm + 32))
				} 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 + 488))).FpWC = bp
					} else {
						goto _2
					}
				}
				(**(**TWhereOrSet)(__ccgo_up(bp + 600))).Fn = uint16(0)
				if libc.Int32FromUint8((*TTable)(unsafe.Pointer((*TSrcItem)(unsafe.Pointer(pItem)).FpSTab)).FeTabType) == int32(TABTYP_VTAB) {
					rc = _whereLoopAddVirtual(tls, bp+488, mPrereq, mUnusable)
				} else {
					rc = _whereLoopAddBtree(tls, bp+488, mPrereq)
				}
				if rc == SQLITE_OK {
					rc = _whereLoopAddOr(tls, bp+488, mPrereq, mUnusable)
				}
				if libc.Int32FromUint16((**(**TWhereOrSet)(__ccgo_up(bp + 600))).Fn) == 0 {
					(**(**TWhereOrSet)(__ccgo_up(bp + 544))).Fn = uint16(0)
					break
				} else {
					if once != 0 {
						_whereOrMove(tls, bp+544, bp+600)
						once = 0
					} else {
						_whereOrMove(tls, bp+656, bp+544)
						(**(**TWhereOrSet)(__ccgo_up(bp + 544))).Fn = uint16(0)
						i = 0
						for {
							if !(i < libc.Int32FromUint16((**(**TWhereOrSet)(__ccgo_up(bp + 656))).Fn)) {
								break
							}
							j = 0
							for {
								if !(j < libc.Int32FromUint16((**(**TWhereOrSet)(__ccgo_up(bp + 600))).Fn)) {
									break
								}
								_whereOrInsert(tls, bp+544, (**(**TWhereOrCost)(__ccgo_up(bp + 656 + 8 + uintptr(i)*16))).Fprereq|(**(**TWhereOrCost)(__ccgo_up(bp + 600 + 8 + uintptr(j)*16))).Fprereq, _sqlite3LogEstAdd(tls, (**(**TWhereOrCost)(__ccgo_up(bp + 656 + 8 + uintptr(i)*16))).FrRun, (**(**TWhereOrCost)(__ccgo_up(bp + 600 + 8 + uintptr(j)*16))).FrRun), _sqlite3LogEstAdd(tls, (**(**TWhereOrCost)(__ccgo_up(bp + 656 + 8 + uintptr(i)*16))).FnOut, (**(**TWhereOrCost)(__ccgo_up(bp + 600 + 8 + uintptr(j)*16))).FnOut))
								goto _4
							_4:
								;
								j = j + 1
							}
							goto _3
						_3:
							;
							i = i + 1
						}
					}
				}
				goto _2
			_2:
				;
				pOrTerm += 56
			}
			(*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, uint64(24))
			i = 0
			for {
				if !(rc == SQLITE_OK && i < libc.Int32FromUint16((**(**TWhereOrSet)(__ccgo_up(bp + 544))).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 + 544 + 8 + uintptr(i)*16))).FrRun) + int32(1))
				(*TWhereLoop)(unsafe.Pointer(pNew)).FnOut = (**(**TWhereOrCost)(__ccgo_up(bp + 544 + 8 + uintptr(i)*16))).FnOut
				(*TWhereLoop)(unsafe.Pointer(pNew)).Fprereq = (**(**TWhereOrCost)(__ccgo_up(bp + 544 + 8 + uintptr(i)*16))).Fprereq
				rc = _whereLoopInsert(tls, pBuilder, pNew)
				goto _5
			_5:
				;
				i = i + 1
			}
		}
		goto _1
	_1:
		;
		pTerm += 56
	}
	return rc
}

// C documentation
//
//	/*
//	** Increase the memory allocation for pLoop->aLTerm[] to be at least n.
//	*/
func _whereLoopResize(tls *libc.TLS, db uintptr, p uintptr, n int32) (r int32) {
	var paNew uintptr
	_ = paNew
	if libc.Int32FromUint16((*TWhereLoop)(unsafe.Pointer(p)).FnLSlot) >= n {
		return SQLITE_OK
	}
	n = (n + int32(7)) & ^libc.Int32FromInt32(7)
	paNew = _sqlite3DbMallocRawNN(tls, db, uint64(uint64(8)*libc.Uint64FromInt32(n)))
	if paNew == uintptr(0) {
		return int32(SQLITE_NOMEM)
	}
	libc.Xmemcpy(tls, paNew, (*TWhereLoop)(unsafe.Pointer(p)).FaLTerm, uint64(8)*uint64((*TWhereLoop)(unsafe.Pointer(p)).FnLSlot))
	if (*TWhereLoop)(unsafe.Pointer(p)).FaLTerm != p+80 {
		_sqlite3DbFreeNN(tls, db, (*TWhereLoop)(unsafe.Pointer(p)).FaLTerm)
	}
	(*TWhereLoop)(unsafe.Pointer(p)).FaLTerm = paNew
	(*TWhereLoop)(unsafe.Pointer(p)).FnLSlot = libc.Uint16FromInt32(n)
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** Transfer content from the second pLoop into the first.
//	*/
func _whereLoopXfer(tls *libc.TLS, db uintptr, pTo uintptr, pFrom uintptr) (r int32) {
	_whereLoopClearUnion(tls, db, pTo)
	if libc.Int32FromUint16((*TWhereLoop)(unsafe.Pointer(pFrom)).FnLTerm) > libc.Int32FromUint16((*TWhereLoop)(unsafe.Pointer(pTo)).FnLSlot) && _whereLoopResize(tls, db, pTo, libc.Int32FromUint16((*TWhereLoop)(unsafe.Pointer(pFrom)).FnLTerm)) != 0 {
		libc.Xmemset(tls, pTo, 0, uint64(libc.UintptrFromInt32(0)+56))
		return int32(SQLITE_NOMEM)
	}
	libc.Xmemcpy(tls, pTo, pFrom, uint64(libc.UintptrFromInt32(0)+56))
	libc.Xmemcpy(tls, (*TWhereLoop)(unsafe.Pointer(pTo)).FaLTerm, (*TWhereLoop)(unsafe.Pointer(pFrom)).FaLTerm, uint64((*TWhereLoop)(unsafe.Pointer(pTo)).FnLTerm)*uint64(8))
	if (*TWhereLoop)(unsafe.Pointer(pFrom)).FwsFlags&uint32(WHERE_VIRTUALTABLE) != 0 {
		libc.SetBitFieldPtr8Uint32(pFrom+24+4, libc.Uint32FromInt32(0), 0, 0x1)
	} else {
		if (*TWhereLoop)(unsafe.Pointer(pFrom)).FwsFlags&uint32(WHERE_AUTO_INDEX) != uint32(0) {
			(*(*struct {
				FnEq          Tu16
				FnBtm         Tu16
				FnTop         Tu16
				FnDistinctCol Tu16
				FpIndex       uintptr
				FpOrderBy     uintptr
			})(unsafe.Pointer(pFrom + 24))).FpIndex = uintptr(0)
		}
	}
	return SQLITE_OK
}

// 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+592, (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpResultSet)
	if (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpOrderBy != 0 {
		tabUsed = tabUsed | _sqlite3WhereExprListUsage(tls, pWInfo+592, (*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 + 856 + uintptr(i)*112))).FpWLoop
		pItem = (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpTabList + 8 + uintptr((*TWhereLoop)(unsafe.Pointer(pLoop)).FiTab)*80
		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)*56
		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 + 52)) != (*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 + 52)) == (*TSrcItem)(unsafe.Pointer(pItem)).FiCursor {
				break /* restriction (5) */
			}
			goto _2
		_2:
			;
			pTerm += 56
		}
		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 + 18
				*(*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 += 56
		}
		if i != libc.Int32FromUint8((*TWhereInfo)(unsafe.Pointer(pWInfo)).FnLevel)-int32(1) {
			nByte = libc.Int32FromUint64(libc.Uint64FromInt32(libc.Int32FromUint8((*TWhereInfo)(unsafe.Pointer(pWInfo)).FnLevel)-libc.Int32FromInt32(1)-i) * uint64(112))
			libc.Xmemmove(tls, pWInfo+856+uintptr(i)*112, pWInfo+856+uintptr(i+int32(1))*112, libc.Uint64FromInt32(nByte))
		}
		(*TWhereInfo)(unsafe.Pointer(pWInfo)).FnLevel = (*TWhereInfo)(unsafe.Pointer(pWInfo)).FnLevel - 1
		goto _1
	_1:
		;
		i = i - 1
	}
	return notReady
}

// 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)*56))).FiHdrOffset == 0 {
			(**(**TPagerSavepoint)(__ccgo_up((*TPager)(unsafe.Pointer(pPager)).FaSavepoint + uintptr(ii)*56))).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)), uint64(8))
		_sqlite3Put4byte(tls, zHeader+uintptr(8), uint32(0xffffffff))
	} else {
		libc.Xmemset(tls, zHeader, 0, libc.Uint64FromInt64(8)+libc.Uint64FromInt32(4))
	}
	/* The random check-hash initializer */
	if libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FjournalMode) != int32(PAGER_JOURNALMODE_MEMORY) {
		Xsqlite3_randomness(tls, int32(4), pPager+56)
	}
	_sqlite3Put4byte(tls, zHeader+uintptr(libc.Uint64FromInt64(8)+libc.Uint64FromInt32(4)), (*TPager)(unsafe.Pointer(pPager)).FcksumInit)
	/* The initial database size */
	_sqlite3Put4byte(tls, zHeader+uintptr(libc.Uint64FromInt64(8)+libc.Uint64FromInt32(8)), (*TPager)(unsafe.Pointer(pPager)).FdbOrigSize)
	/* The assumed sector size for this process */
	_sqlite3Put4byte(tls, zHeader+uintptr(libc.Uint64FromInt64(8)+libc.Uint64FromInt32(12)), (*TPager)(unsafe.Pointer(pPager)).FsectorSize)
	/* The page size */
	_sqlite3Put4byte(tls, zHeader+uintptr(libc.Uint64FromInt64(8)+libc.Uint64FromInt32(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.Uint64FromInt64(8)+libc.Uint64FromInt32(20)), 0, uint64(nHeader)-(libc.Uint64FromInt64(8)+libc.Uint64FromInt32(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 + 96)) += libc.Int64FromUint32(nHeader)
		goto _3
	_3:
		;
		nWrite = nWrite + nHeader
	}
	return rc
}

// C documentation
//
//	/*
//	** Try to increase the size of the parser stack.  Return the number
//	** of errors.  Return 0 on success.
//	*/
func _yyGrowStack(tls *libc.TLS, p uintptr) (r int32) {
	var idx, nLimit, newSize, oldSize int32
	var pNew uintptr
	_, _, _, _, _ = idx, nLimit, newSize, oldSize, pNew
	oldSize = int32(1) + int32((int64((*TyyParser)(unsafe.Pointer(p)).FyystackEnd)-int64((*TyyParser)(unsafe.Pointer(p)).Fyystack))/24)
	nLimit = _parserStackSizeLimit(tls, (*TyyParser)(unsafe.Pointer(p)).FpParse)
	newSize = oldSize*int32(2) + int32(100)
	if newSize > nLimit {
		newSize = nLimit
		if newSize <= oldSize {
			return int32(1)
		}
	}
	idx = int32((int64((*TyyParser)(unsafe.Pointer(p)).Fyytos) - int64((*TyyParser)(unsafe.Pointer(p)).Fyystack)) / 24)
	if (*TyyParser)(unsafe.Pointer(p)).Fyystack == p+32 {
		pNew = _parserStackRealloc(tls, uintptr(0), uint64(libc.Uint64FromInt32(newSize)*uint64(24)), (*TyyParser)(unsafe.Pointer(p)).FpParse)
		if pNew == uintptr(0) {
			return int32(1)
		}
		libc.Xmemcpy(tls, pNew, (*TyyParser)(unsafe.Pointer(p)).Fyystack, libc.Uint64FromInt32(oldSize)*uint64(24))
	} else {
		pNew = _parserStackRealloc(tls, (*TyyParser)(unsafe.Pointer(p)).Fyystack, uint64(libc.Uint64FromInt32(newSize)*uint64(24)), (*TyyParser)(unsafe.Pointer(p)).FpParse)
		if pNew == uintptr(0) {
			return int32(1)
		}
	}
	(*TyyParser)(unsafe.Pointer(p)).Fyystack = pNew
	(*TyyParser)(unsafe.Pointer(p)).Fyytos = (*TyyParser)(unsafe.Pointer(p)).Fyystack + uintptr(idx)*24
	(*TyyParser)(unsafe.Pointer(p)).FyystackEnd = (*TyyParser)(unsafe.Pointer(p)).Fyystack + uintptr(newSize-int32(1))*24
	return 0
}

/* Datatype of the argument to the memory allocated passed as the
** second argument to sqlite3ParserAlloc() below.  This can be changed by
** putting an appropriate #define in the %include section of the input
** grammar.
 */

func init() {
	p := unsafe.Pointer(&_aVfs)
	*(*uintptr)(unsafe.Add(p, 32)) = uintptr(unsafe.Pointer(&_posixIoFinder))
	*(*uintptr)(unsafe.Add(p, 40)) = __ccgo_fp(_unixOpen)
	*(*uintptr)(unsafe.Add(p, 48)) = __ccgo_fp(_unixDelete)
	*(*uintptr)(unsafe.Add(p, 56)) = __ccgo_fp(_unixAccess)
	*(*uintptr)(unsafe.Add(p, 64)) = __ccgo_fp(_unixFullPathname)
	*(*uintptr)(unsafe.Add(p, 72)) = __ccgo_fp(_unixDlOpen)
	*(*uintptr)(unsafe.Add(p, 80)) = __ccgo_fp(_unixDlError)
	*(*uintptr)(unsafe.Add(p, 88)) = __ccgo_fp(_unixDlSym)
	*(*uintptr)(unsafe.Add(p, 96)) = __ccgo_fp(_unixDlClose)
	*(*uintptr)(unsafe.Add(p, 104)) = __ccgo_fp(_unixRandomness)
	*(*uintptr)(unsafe.Add(p, 112)) = __ccgo_fp(_unixSleep)
	*(*uintptr)(unsafe.Add(p, 120)) = __ccgo_fp(_unixCurrentTime)
	*(*uintptr)(unsafe.Add(p, 128)) = __ccgo_fp(_unixGetLastError)
	*(*uintptr)(unsafe.Add(p, 136)) = __ccgo_fp(_unixCurrentTimeInt64)
	*(*uintptr)(unsafe.Add(p, 144)) = __ccgo_fp(_unixSetSystemCall)
	*(*uintptr)(unsafe.Add(p, 152)) = __ccgo_fp(_unixGetSystemCall)
	*(*uintptr)(unsafe.Add(p, 160)) = __ccgo_fp(_unixNextSystemCall)
	*(*uintptr)(unsafe.Add(p, 200)) = uintptr(unsafe.Pointer(&_nolockIoFinder))
	*(*uintptr)(unsafe.Add(p, 208)) = __ccgo_fp(_unixOpen)
	*(*uintptr)(unsafe.Add(p, 216)) = __ccgo_fp(_unixDelete)
	*(*uintptr)(unsafe.Add(p, 224)) = __ccgo_fp(_unixAccess)
	*(*uintptr)(unsafe.Add(p, 232)) = __ccgo_fp(_unixFullPathname)
	*(*uintptr)(unsafe.Add(p, 240)) = __ccgo_fp(_unixDlOpen)
	*(*uintptr)(unsafe.Add(p, 248)) = __ccgo_fp(_unixDlError)
	*(*uintptr)(unsafe.Add(p, 256)) = __ccgo_fp(_unixDlSym)
	*(*uintptr)(unsafe.Add(p, 264)) = __ccgo_fp(_unixDlClose)
	*(*uintptr)(unsafe.Add(p, 272)) = __ccgo_fp(_unixRandomness)
	*(*uintptr)(unsafe.Add(p, 280)) = __ccgo_fp(_unixSleep)
	*(*uintptr)(unsafe.Add(p, 288)) = __ccgo_fp(_unixCurrentTime)
	*(*uintptr)(unsafe.Add(p, 296)) = __ccgo_fp(_unixGetLastError)
	*(*uintptr)(unsafe.Add(p, 304)) = __ccgo_fp(_unixCurrentTimeInt64)
	*(*uintptr)(unsafe.Add(p, 312)) = __ccgo_fp(_unixSetSystemCall)
	*(*uintptr)(unsafe.Add(p, 320)) = __ccgo_fp(_unixGetSystemCall)
	*(*uintptr)(unsafe.Add(p, 328)) = __ccgo_fp(_unixNextSystemCall)
	*(*uintptr)(unsafe.Add(p, 368)) = uintptr(unsafe.Pointer(&_dotlockIoFinder))
	*(*uintptr)(unsafe.Add(p, 376)) = __ccgo_fp(_unixOpen)
	*(*uintptr)(unsafe.Add(p, 384)) = __ccgo_fp(_unixDelete)
	*(*uintptr)(unsafe.Add(p, 392)) = __ccgo_fp(_unixAccess)
	*(*uintptr)(unsafe.Add(p, 400)) = __ccgo_fp(_unixFullPathname)
	*(*uintptr)(unsafe.Add(p, 408)) = __ccgo_fp(_unixDlOpen)
	*(*uintptr)(unsafe.Add(p, 416)) = __ccgo_fp(_unixDlError)
	*(*uintptr)(unsafe.Add(p, 424)) = __ccgo_fp(_unixDlSym)
	*(*uintptr)(unsafe.Add(p, 432)) = __ccgo_fp(_unixDlClose)
	*(*uintptr)(unsafe.Add(p, 440)) = __ccgo_fp(_unixRandomness)
	*(*uintptr)(unsafe.Add(p, 448)) = __ccgo_fp(_unixSleep)
	*(*uintptr)(unsafe.Add(p, 456)) = __ccgo_fp(_unixCurrentTime)
	*(*uintptr)(unsafe.Add(p, 464)) = __ccgo_fp(_unixGetLastError)
	*(*uintptr)(unsafe.Add(p, 472)) = __ccgo_fp(_unixCurrentTimeInt64)
	*(*uintptr)(unsafe.Add(p, 480)) = __ccgo_fp(_unixSetSystemCall)
	*(*uintptr)(unsafe.Add(p, 488)) = __ccgo_fp(_unixGetSystemCall)
	*(*uintptr)(unsafe.Add(p, 496)) = __ccgo_fp(_unixNextSystemCall)
	*(*uintptr)(unsafe.Add(p, 536)) = uintptr(unsafe.Pointer(&_posixIoFinder))
	*(*uintptr)(unsafe.Add(p, 544)) = __ccgo_fp(_unixOpen)
	*(*uintptr)(unsafe.Add(p, 552)) = __ccgo_fp(_unixDelete)
	*(*uintptr)(unsafe.Add(p, 560)) = __ccgo_fp(_unixAccess)
	*(*uintptr)(unsafe.Add(p, 568)) = __ccgo_fp(_unixFullPathname)
	*(*uintptr)(unsafe.Add(p, 576)) = __ccgo_fp(_unixDlOpen)
	*(*uintptr)(unsafe.Add(p, 584)) = __ccgo_fp(_unixDlError)
	*(*uintptr)(unsafe.Add(p, 592)) = __ccgo_fp(_unixDlSym)
	*(*uintptr)(unsafe.Add(p, 600)) = __ccgo_fp(_unixDlClose)
	*(*uintptr)(unsafe.Add(p, 608)) = __ccgo_fp(_unixRandomness)
	*(*uintptr)(unsafe.Add(p, 616)) = __ccgo_fp(_unixSleep)
	*(*uintptr)(unsafe.Add(p, 624)) = __ccgo_fp(_unixCurrentTime)
	*(*uintptr)(unsafe.Add(p, 632)) = __ccgo_fp(_unixGetLastError)
	*(*uintptr)(unsafe.Add(p, 640)) = __ccgo_fp(_unixCurrentTimeInt64)
	*(*uintptr)(unsafe.Add(p, 648)) = __ccgo_fp(_unixSetSystemCall)
	*(*uintptr)(unsafe.Add(p, 656)) = __ccgo_fp(_unixGetSystemCall)
	*(*uintptr)(unsafe.Add(p, 664)) = __ccgo_fp(_unixNextSystemCall)
}
