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

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

package sqlite3

import (
	"unsafe"

	"modernc.org/libc"
)

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

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

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

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

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

// C documentation
//
//	/*
//	** Recursively walk the expressions of a SELECT statement and generate
//	** a bitmask indicating which tables are used in that expression
//	** tree.
//	*/
func _exprSelectUsage(tls *libc.TLS, pMaskSet uintptr, pS uintptr) (r TBitmask) {
	var i int32
	var mask TBitmask
	var pSrc uintptr
	_, _, _ = i, mask, pSrc
	mask = uint64(0)
	for pS != 0 {
		pSrc = (*TSelect)(unsafe.Pointer(pS)).FpSrc
		mask = mask | _sqlite3WhereExprListUsage(tls, pMaskSet, (*TSelect)(unsafe.Pointer(pS)).FpEList)
		mask = mask | _sqlite3WhereExprListUsage(tls, pMaskSet, (*TSelect)(unsafe.Pointer(pS)).FpGroupBy)
		mask = mask | _sqlite3WhereExprListUsage(tls, pMaskSet, (*TSelect)(unsafe.Pointer(pS)).FpOrderBy)
		mask = mask | _sqlite3WhereExprUsage(tls, pMaskSet, (*TSelect)(unsafe.Pointer(pS)).FpWhere)
		mask = mask | _sqlite3WhereExprUsage(tls, pMaskSet, (*TSelect)(unsafe.Pointer(pS)).FpHaving)
		if pSrc != uintptr(0) {
			i = 0
			for {
				if !(i < (*TSrcList)(unsafe.Pointer(pSrc)).FnSrc) {
					break
				}
				if int32(*(*uint32)(unsafe.Pointer(pSrc + 8 + uintptr(i)*80 + 24 + 4))&0x4>>2) != 0 {
					mask = mask | _exprSelectUsage(tls, pMaskSet, (*TSubquery)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pSrc + 8 + uintptr(i)*80 + 72)))).FpSelect)
				}
				if int32(*(*uint32)(unsafe.Pointer(pSrc + 8 + uintptr(i)*80 + 24 + 4))&0x800>>11) == 0 {
					mask = mask | _sqlite3WhereExprUsage(tls, pMaskSet, *(*uintptr)(unsafe.Pointer(pSrc + 8 + uintptr(i)*80 + 64)))
				}
				if int32(*(*uint32)(unsafe.Pointer(pSrc + 8 + uintptr(i)*80 + 24 + 4))&0x8>>3) != 0 {
					mask = mask | _sqlite3WhereExprListUsage(tls, pMaskSet, *(*uintptr)(unsafe.Pointer(pSrc + 8 + uintptr(i)*80 + 48)))
				}
				goto _1
			_1:
				;
				i = i + 1
			}
		}
		pS = (*TSelect)(unsafe.Pointer(pS)).FpPrior
	}
	return mask
}

// C documentation
//
//	/*
//	** Check the N SrcItem objects to the right of pBase.  (N might be zero!)
//	** If any of those SrcItem objects have a USING clause containing zName
//	** then return true.
//	**
//	** If N is zero, or none of the N SrcItem objects to the right of pBase
//	** contains a USING clause, or if none of the USING clauses contain zName,
//	** then return false.
//	*/
func _inAnyUsingClause(tls *libc.TLS, zName uintptr, pBase uintptr, N int32) (r int32) {
	for N > 0 {
		N = N - 1
		pBase += 80
		if int32(*(*uint32)(unsafe.Pointer(pBase + 24 + 4))&0x800>>11) == 0 {
			continue
		}
		if *(*uintptr)(unsafe.Pointer(pBase + 64)) == uintptr(0) {
			continue
		}
		if _sqlite3IdListIndex(tls, *(*uintptr)(unsafe.Pointer(pBase + 64)), zName) >= 0 {
			return int32(1)
		}
	}
	return 0
}

// C documentation
//
//	/*
//	** Return TRUE if the iCol-th column of index pIdx is NOT NULL
//	*/
func _indexColumnNotNull(tls *libc.TLS, pIdx uintptr, iCol int32) (r int32) {
	var j int32
	_ = j
	j = int32(**(**Ti16)(__ccgo_up((*TIndex)(unsafe.Pointer(pIdx)).FaiColumn + uintptr(iCol)*2)))
	if j >= 0 {
		return int32(uint32(*(*uint8)(unsafe.Pointer((*TTable)(unsafe.Pointer((*TIndex)(unsafe.Pointer(pIdx)).FpTable)).FaCol + uintptr(j)*16 + 8)) & 0xf >> 0))
	} else {
		if j == -int32(1) {
			return int32(1)
		} else {
			return 0 /* Assume an indexed expression can always yield a NULL */
		}
	}
	return r
}

// C documentation
//
//	/*
//	** Check to see if the pThis entry of pTabList is a self-join of another view.
//	** Search FROM-clause entries in the range of iFirst..iEnd, including iFirst
//	** but stopping before iEnd.
//	**
//	** If pThis is a self-join, then return the SrcItem for the first other
//	** instance of that view found.  If pThis is not a self-join then return 0.
//	*/
func _isSelfJoinView(tls *libc.TLS, pTabList uintptr, pThis uintptr, iFirst int32, iEnd int32) (r uintptr) {
	var pItem, pS1, pSel uintptr
	var v1 int32
	_, _, _, _ = pItem, pS1, pSel, v1
	pSel = (*TSubquery)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pThis + 72)))).FpSelect
	if (*TSelect)(unsafe.Pointer(pSel)).FselFlags&uint32(SF_PushDown) != 0 {
		return uintptr(0)
	}
	for iFirst < iEnd {
		v1 = iFirst
		iFirst = iFirst + 1
		pItem = pTabList + 8 + uintptr(v1)*80
		if !(int32(*(*uint32)(unsafe.Pointer(pItem + 24 + 4))&0x4>>2) != 0) {
			continue
		}
		if int32(*(*uint32)(unsafe.Pointer(pItem + 24 + 4))&0x40>>6) != 0 {
			continue
		}
		if (*TSrcItem)(unsafe.Pointer(pItem)).FzName == uintptr(0) {
			continue
		}
		if (*TTable)(unsafe.Pointer((*TSrcItem)(unsafe.Pointer(pItem)).FpSTab)).FpSchema != (*TTable)(unsafe.Pointer((*TSrcItem)(unsafe.Pointer(pThis)).FpSTab)).FpSchema {
			continue
		}
		if Xsqlite3_stricmp(tls, (*TSrcItem)(unsafe.Pointer(pItem)).FzName, (*TSrcItem)(unsafe.Pointer(pThis)).FzName) != 0 {
			continue
		}
		pS1 = (*TSubquery)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pItem + 72)))).FpSelect
		if (*TTable)(unsafe.Pointer((*TSrcItem)(unsafe.Pointer(pItem)).FpSTab)).FpSchema == uintptr(0) && (*TSelect)(unsafe.Pointer(pSel)).FselId != (*TSelect)(unsafe.Pointer(pS1)).FselId {
			/* The query flattener left two different CTE tables with identical
			 ** names in the same FROM clause. */
			continue
		}
		if (*TSelect)(unsafe.Pointer(pS1)).FselFlags&uint32(SF_PushDown) != 0 {
			/* The view was modified by some other optimization such as
			 ** pushDownWhereTerms() */
			continue
		}
		return pItem
	}
	return uintptr(0)
}

// C documentation
//
//	/*
//	** For each name in the the expression-list pEList (i.e. each
//	** pEList->a[i].zName) that matches the string in zOld, extract the
//	** corresponding rename-token from Parse object pParse and add it
//	** to the RenameCtx pCtx.
//	*/
func _renameColumnElistNames(tls *libc.TLS, pParse uintptr, pCtx uintptr, pEList uintptr, zOld uintptr) {
	var i int32
	var zName uintptr
	_, _ = i, zName
	if pEList != 0 {
		i = 0
		for {
			if !(i < (*TExprList)(unsafe.Pointer(pEList)).FnExpr) {
				break
			}
			zName = (*(*TExprList_item)(unsafe.Pointer(pEList + 8 + uintptr(i)*32))).FzEName
			if int32(uint32(*(*uint16)(unsafe.Pointer(pEList + 8 + uintptr(i)*32 + 16 + 4))&0x3>>0)) == ENAME_NAME && zName != uintptr(0) && 0 == Xsqlite3_stricmp(tls, zName, zOld) {
				_renameTokenFind(tls, pParse, pCtx, zName)
			}
			goto _1
		_1:
			;
			i = i + 1
		}
	}
}

// C documentation
//
//	/*
//	** Invoke sqlite3WalkExpr() or sqlite3WalkSelect() on all Select or Expr
//	** objects that are part of the trigger passed as the second argument.
//	*/
func _renameWalkTrigger(tls *libc.TLS, pWalker uintptr, pTrigger uintptr) {
	var i int32
	var pSrc, pStep, pUpsert uintptr
	_, _, _, _ = i, pSrc, pStep, pUpsert
	/* Find tokens to edit in WHEN clause */
	_sqlite3WalkExpr(tls, pWalker, (*TTrigger)(unsafe.Pointer(pTrigger)).FpWhen)
	/* Find tokens to edit in trigger steps */
	pStep = (*TTrigger)(unsafe.Pointer(pTrigger)).Fstep_list
	for {
		if !(pStep != 0) {
			break
		}
		_sqlite3WalkSelect(tls, pWalker, (*TTriggerStep)(unsafe.Pointer(pStep)).FpSelect)
		_sqlite3WalkExpr(tls, pWalker, (*TTriggerStep)(unsafe.Pointer(pStep)).FpWhere)
		_sqlite3WalkExprList(tls, pWalker, (*TTriggerStep)(unsafe.Pointer(pStep)).FpExprList)
		if (*TTriggerStep)(unsafe.Pointer(pStep)).FpUpsert != 0 {
			pUpsert = (*TTriggerStep)(unsafe.Pointer(pStep)).FpUpsert
			_sqlite3WalkExprList(tls, pWalker, (*TUpsert)(unsafe.Pointer(pUpsert)).FpUpsertTarget)
			_sqlite3WalkExprList(tls, pWalker, (*TUpsert)(unsafe.Pointer(pUpsert)).FpUpsertSet)
			_sqlite3WalkExpr(tls, pWalker, (*TUpsert)(unsafe.Pointer(pUpsert)).FpUpsertWhere)
			_sqlite3WalkExpr(tls, pWalker, (*TUpsert)(unsafe.Pointer(pUpsert)).FpUpsertTargetWhere)
		}
		if (*TTriggerStep)(unsafe.Pointer(pStep)).FpSrc != 0 {
			pSrc = (*TTriggerStep)(unsafe.Pointer(pStep)).FpSrc
			i = 0
			for {
				if !(i < (*TSrcList)(unsafe.Pointer(pSrc)).FnSrc) {
					break
				}
				if int32(*(*uint32)(unsafe.Pointer(pSrc + 8 + uintptr(i)*80 + 24 + 4))&0x4>>2) != 0 {
					_sqlite3WalkSelect(tls, pWalker, (*TSubquery)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pSrc + 8 + uintptr(i)*80 + 72)))).FpSelect)
				}
				goto _2
			_2:
				;
				i = i + 1
			}
		}
		goto _1
	_1:
		;
		pStep = (*TTriggerStep)(unsafe.Pointer(pStep)).FpNext
	}
}

// C documentation
//
//	/*
//	** If any term of pSrc, or any SF_NestedFrom sub-query, is not the same
//	** as pSrcItem but has the same alias as p0, then return true.
//	** Otherwise return false.
//	*/
func _sameSrcAlias(tls *libc.TLS, p0 uintptr, pSrc uintptr) (r int32) {
	var i int32
	var p1 uintptr
	_, _ = i, p1
	i = 0
	for {
		if !(i < (*TSrcList)(unsafe.Pointer(pSrc)).FnSrc) {
			break
		}
		p1 = pSrc + 8 + uintptr(i)*80
		if p1 == p0 {
			goto _1
		}
		if (*TSrcItem)(unsafe.Pointer(p0)).FpSTab == (*TSrcItem)(unsafe.Pointer(p1)).FpSTab && 0 == Xsqlite3_stricmp(tls, (*TSrcItem)(unsafe.Pointer(p0)).FzAlias, (*TSrcItem)(unsafe.Pointer(p1)).FzAlias) {
			return int32(1)
		}
		if int32(*(*uint32)(unsafe.Pointer(p1 + 24 + 4))&0x4>>2) != 0 && (*TSelect)(unsafe.Pointer((*TSubquery)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(p1 + 72)))).FpSelect)).FselFlags&uint32(SF_NestedFrom) != uint32(0) && _sameSrcAlias(tls, p0, (*TSelect)(unsafe.Pointer((*TSubquery)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(p1 + 72)))).FpSelect)).FpSrc) != 0 {
			return int32(1)
		}
		goto _1
	_1:
		;
		i = i + 1
	}
	return 0
}

// C documentation
//
//	/*
//	** Generate code that will evaluate expression pExpr and store the
//	** results in register target.  The results are guaranteed to appear
//	** in register target.  If the expression is constant, then this routine
//	** might choose to code the expression at initialization time.
//	*/
func _sqlite3ExprCodeFactorable(tls *libc.TLS, pParse uintptr, pExpr uintptr, target int32) {
	if int32(Tbft(*(*uint16)(unsafe.Pointer(pParse + 40))&0x80>>7)) != 0 && _sqlite3ExprIsConstantNotJoin(tls, pParse, pExpr) != 0 {
		_sqlite3ExprCodeRunJustOnce(tls, pParse, pExpr, target)
	} else {
		_sqlite3ExprCodeCopy(tls, pParse, pExpr, target)
	}
}

// C documentation
//
//	/*
//	** Set the ExprList.a[].zSpan element of the most recently added item
//	** on the expression list.
//	**
//	** pList might be NULL following an OOM error.  But pSpan should never be
//	** NULL.  If a memory allocation fails, the pParse->db->mallocFailed flag
//	** is set.
//	*/
func _sqlite3ExprListSetSpan(tls *libc.TLS, pParse uintptr, pList uintptr, zStart uintptr, zEnd uintptr) {
	var db, pItem uintptr
	_, _ = db, pItem
	db = (*TParse)(unsafe.Pointer(pParse)).Fdb
	if pList != 0 {
		pItem = pList + 8 + uintptr((*TExprList)(unsafe.Pointer(pList)).FnExpr-int32(1))*32
		if (*TExprList_item)(unsafe.Pointer(pItem)).FzEName == uintptr(0) {
			(*TExprList_item)(unsafe.Pointer(pItem)).FzEName = _sqlite3DbSpanDup(tls, db, zStart, zEnd)
			libc.SetBitFieldPtr16Uint32(pItem+16+4, libc.Uint32FromInt32(ENAME_SPAN), 0, 0x3)
		}
	}
}

// C documentation
//
//	/*
//	** Reclaim the memory used by an index
//	*/
func _sqlite3FreeIndex(tls *libc.TLS, db uintptr, p uintptr) {
	_sqlite3DeleteIndexSamples(tls, db, p)
	_sqlite3ExprDelete(tls, db, (*TIndex)(unsafe.Pointer(p)).FpPartIdxWhere)
	_sqlite3ExprListDelete(tls, db, (*TIndex)(unsafe.Pointer(p)).FaColExpr)
	_sqlite3DbFree(tls, db, (*TIndex)(unsafe.Pointer(p)).FzColAff)
	if int32(uint32(*(*uint16)(unsafe.Pointer(p + 100))&0x10>>4)) != 0 {
		_sqlite3DbFree(tls, db, (*TIndex)(unsafe.Pointer(p)).FazColl)
	}
	Xsqlite3_free(tls, (*TIndex)(unsafe.Pointer(p)).FaiRowEst)
	_sqlite3DbFree(tls, db, p)
}

// C documentation
//
//	/*
//	** Locate the table identified by *p.
//	**
//	** This is a wrapper around sqlite3LocateTable(). The difference between
//	** sqlite3LocateTable() and this function is that this function restricts
//	** the search to schema (p->pSchema) if it is not NULL. p->pSchema may be
//	** non-NULL if it is part of a view or trigger program definition. See
//	** sqlite3FixSrcList() for details.
//	*/
func _sqlite3LocateTableItem(tls *libc.TLS, pParse uintptr, flags Tu32, p uintptr) (r uintptr) {
	var iDb int32
	var zDb uintptr
	_, _ = iDb, zDb
	if int32(*(*uint32)(unsafe.Pointer(p + 24 + 4))&0x10000>>16) != 0 {
		iDb = _sqlite3SchemaToIndex(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, *(*uintptr)(unsafe.Pointer(p + 72)))
		zDb = (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer((*TParse)(unsafe.Pointer(pParse)).Fdb)).FaDb + uintptr(iDb)*32))).FzDbSName
	} else {
		zDb = *(*uintptr)(unsafe.Pointer(p + 72))
	}
	return _sqlite3LocateTable(tls, pParse, flags, (*TSrcItem)(unsafe.Pointer(p)).FzName, zDb)
}

// C documentation
//
//	/*
//	** The code generator calls this routine if is discovers that it is
//	** possible to abort a statement prior to completion.  In order to
//	** perform this abort without corrupting the database, we need to make
//	** sure that the statement is protected by a statement transaction.
//	**
//	** Technically, we only need to set the mayAbort flag if the
//	** isMultiWrite flag was previously set.  There is a time dependency
//	** such that the abort must occur after the multiwrite.  This makes
//	** some statements involving the REPLACE conflict resolution algorithm
//	** go a little faster.  But taking advantage of this time dependency
//	** makes it more difficult to prove that the code is correct (in
//	** particular, it prevents us from writing an effective
//	** implementation of sqlite3AssertMayAbort()) and so we have chosen
//	** to take the safe route and skip the optimization.
//	*/
func _sqlite3MayAbort(tls *libc.TLS, pParse uintptr) {
	var pToplevel, v1 uintptr
	_, _ = pToplevel, v1
	if (*TParse)(unsafe.Pointer(pParse)).FpToplevel != 0 {
		v1 = (*TParse)(unsafe.Pointer(pParse)).FpToplevel
	} else {
		v1 = pParse
	}
	pToplevel = v1
	libc.SetBitFieldPtr16Uint32(pToplevel+40, libc.Uint32FromInt32(1), 1, 0x2)
}

// C documentation
//
//	/*
//	** If argument pVal is a Select object returned by an sqlite3MultiValues()
//	** that was able to use the co-routine optimization, finish coding the
//	** co-routine.
//	*/
func _sqlite3MultiValuesEnd(tls *libc.TLS, pParse uintptr, pVal uintptr) {
	var pItem uintptr
	_ = pItem
	if pVal != 0 && (*TSrcList)(unsafe.Pointer((*TSelect)(unsafe.Pointer(pVal)).FpSrc)).FnSrc > 0 {
		pItem = (*TSelect)(unsafe.Pointer(pVal)).FpSrc + 8
		if int32(*(*uint32)(unsafe.Pointer(pItem + 24 + 4))&0x4>>2) != 0 {
			_sqlite3VdbeEndCoroutine(tls, (*TParse)(unsafe.Pointer(pParse)).FpVdbe, (*TSubquery)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pItem + 72)))).FregReturn)
			_sqlite3VdbeJumpHere(tls, (*TParse)(unsafe.Pointer(pParse)).FpVdbe, (*TSubquery)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pItem + 72)))).FaddrFillSub-int32(1))
		}
	}
}

// C documentation
//
//	/*
//	** Return the PRIMARY KEY index of a table
//	*/
func _sqlite3PrimaryKeyIndex(tls *libc.TLS, pTab uintptr) (r uintptr) {
	var p uintptr
	_ = p
	p = (*TTable)(unsafe.Pointer(pTab)).FpIndex
	for {
		if !(p != 0 && !(int32(uint32(*(*uint16)(unsafe.Pointer(p + 100))&0x3>>0)) == libc.Int32FromInt32(SQLITE_IDXTYPE_PRIMARYKEY))) {
			break
		}
		goto _1
	_1:
		;
		p = (*TIndex)(unsafe.Pointer(p)).FpNext
	}
	return p
}

// C documentation
//
//	/*
//	** This routine "expands" a SELECT statement and all of its subqueries.
//	** For additional information on what it means to "expand" a SELECT
//	** statement, see the comment on the selectExpand worker callback above.
//	**
//	** Expanding a SELECT statement is the first step in processing a
//	** SELECT statement.  The SELECT statement must be expanded before
//	** name resolution is performed.
//	**
//	** If anything goes wrong, an error message is written into pParse.
//	** The calling function can detect the problem by looking at pParse->nErr
//	** and/or pParse->db->mallocFailed.
//	*/
func _sqlite3SelectExpand(tls *libc.TLS, pParse uintptr, pSelect uintptr) {
	bp := tls.Alloc(48)
	defer tls.Free(48)
	var _ /* w at bp+0 */ TWalker
	(**(**TWalker)(__ccgo_up(bp))).FxExprCallback = __ccgo_fp(_sqlite3ExprWalkNoop)
	(**(**TWalker)(__ccgo_up(bp))).FpParse = pParse
	if int32(Tbft(*(*uint16)(unsafe.Pointer(pParse + 40))&0x4>>2)) != 0 {
		(**(**TWalker)(__ccgo_up(bp))).FxSelectCallback = __ccgo_fp(_convertCompoundSelectToSubquery)
		(**(**TWalker)(__ccgo_up(bp))).FxSelectCallback2 = uintptr(0)
		_sqlite3WalkSelect(tls, bp, pSelect)
	}
	(**(**TWalker)(__ccgo_up(bp))).FxSelectCallback = __ccgo_fp(_selectExpander)
	(**(**TWalker)(__ccgo_up(bp))).FxSelectCallback2 = __ccgo_fp(_sqlite3SelectPopWith)
	(**(**TWalker)(__ccgo_up(bp))).FeCode = uint16(0)
	_sqlite3WalkSelect(tls, bp, pSelect)
}

// C documentation
//
//	/*
//	** Mark a subquery result column as having been used.
//	*/
func _sqlite3SrcItemColumnUsed(tls *libc.TLS, pItem uintptr, iCol int32) {
	var pResults uintptr
	_ = pResults
	if int32(*(*uint32)(unsafe.Pointer(pItem + 24 + 4))&0x4000>>14) != 0 {
		pResults = (*TSelect)(unsafe.Pointer((*TSubquery)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pItem + 72)))).FpSelect)).FpEList
		libc.SetBitFieldPtr16Uint32(pResults+8+uintptr(iCol)*32+16+4, libc.Uint32FromInt32(1), 6, 0x40)
	}
}

// C documentation
//
//	/*
//	** Assign VdbeCursor index numbers to all tables in a SrcList
//	*/
func _sqlite3SrcListAssignCursors(tls *libc.TLS, pParse uintptr, pList uintptr) {
	var i, v2 int32
	var pItem, v3 uintptr
	_, _, _, _ = i, pItem, v2, v3
	if pList != 0 {
		i = 0
		pItem = pList + 8
		for {
			if !(i < (*TSrcList)(unsafe.Pointer(pList)).FnSrc) {
				break
			}
			if (*TSrcItem)(unsafe.Pointer(pItem)).FiCursor >= 0 {
				goto _1
			}
			v3 = pParse + 56
			v2 = *(*int32)(unsafe.Pointer(v3))
			*(*int32)(unsafe.Pointer(v3)) = *(*int32)(unsafe.Pointer(v3)) + 1
			(*TSrcItem)(unsafe.Pointer(pItem)).FiCursor = v2
			if int32(*(*uint32)(unsafe.Pointer(pItem + 24 + 4))&0x4>>2) != 0 {
				_sqlite3SrcListAssignCursors(tls, pParse, (*TSelect)(unsafe.Pointer((*TSubquery)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pItem + 72)))).FpSelect)).FpSrc)
			}
			goto _1
		_1:
			;
			i = i + 1
			pItem += 80
		}
	}
}

// C documentation
//
//	/*
//	** Delete an entire SrcList including all its substructure.
//	*/
func _sqlite3SrcListDelete(tls *libc.TLS, db uintptr, pList uintptr) {
	var i int32
	var pItem uintptr
	_, _ = i, pItem
	if pList == uintptr(0) {
		return
	}
	pItem = pList + 8
	i = libc.Int32FromInt32(0)
	for {
		if !(i < (*TSrcList)(unsafe.Pointer(pList)).FnSrc) {
			break
		}
		/* Check invariants on SrcItem */
		if (*TSrcItem)(unsafe.Pointer(pItem)).FzName != 0 {
			_sqlite3DbNNFreeNN(tls, db, (*TSrcItem)(unsafe.Pointer(pItem)).FzName)
		}
		if (*TSrcItem)(unsafe.Pointer(pItem)).FzAlias != 0 {
			_sqlite3DbNNFreeNN(tls, db, (*TSrcItem)(unsafe.Pointer(pItem)).FzAlias)
		}
		if int32(*(*uint32)(unsafe.Pointer(pItem + 24 + 4))&0x4>>2) != 0 {
			_sqlite3SubqueryDelete(tls, db, *(*uintptr)(unsafe.Pointer(pItem + 72)))
		} else {
			if int32(*(*uint32)(unsafe.Pointer(pItem + 24 + 4))&0x10000>>16) == 0 && *(*uintptr)(unsafe.Pointer(pItem + 72)) != uintptr(0) {
				_sqlite3DbNNFreeNN(tls, db, *(*uintptr)(unsafe.Pointer(pItem + 72)))
			}
		}
		if int32(*(*uint32)(unsafe.Pointer(pItem + 24 + 4))&0x2>>1) != 0 {
			_sqlite3DbFree(tls, db, *(*uintptr)(unsafe.Pointer(pItem + 48)))
		}
		if int32(*(*uint32)(unsafe.Pointer(pItem + 24 + 4))&0x8>>3) != 0 {
			_sqlite3ExprListDelete(tls, db, *(*uintptr)(unsafe.Pointer(pItem + 48)))
		}
		_sqlite3DeleteTable(tls, db, (*TSrcItem)(unsafe.Pointer(pItem)).FpSTab)
		if int32(*(*uint32)(unsafe.Pointer(pItem + 24 + 4))&0x800>>11) != 0 {
			_sqlite3IdListDelete(tls, db, *(*uintptr)(unsafe.Pointer(pItem + 64)))
		} else {
			if *(*uintptr)(unsafe.Pointer(pItem + 64)) != 0 {
				_sqlite3ExprDelete(tls, db, *(*uintptr)(unsafe.Pointer(pItem + 64)))
			}
		}
		goto _1
	_1:
		;
		i = i + 1
		pItem += 80
	}
	_sqlite3DbNNFreeNN(tls, db, pList)
}

// C documentation
//
//	/*
//	** Add the list of function arguments to the SrcList entry for a
//	** table-valued-function.
//	*/
func _sqlite3SrcListFuncArgs(tls *libc.TLS, pParse uintptr, p uintptr, pList uintptr) {
	var pItem uintptr
	_ = pItem
	if p != 0 {
		pItem = p + 8 + uintptr((*TSrcList)(unsafe.Pointer(p)).FnSrc-int32(1))*80
		*(*uintptr)(unsafe.Pointer(pItem + 48)) = pList
		libc.SetBitFieldPtr32Uint32(pItem+24+4, libc.Uint32FromInt32(1), 3, 0x8)
	} else {
		_sqlite3ExprListDelete(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, pList)
	}
}

// C documentation
//
//	/*
//	** Add an INDEXED BY or NOT INDEXED clause to the most recently added
//	** element of the source-list passed as the second argument.
//	*/
func _sqlite3SrcListIndexedBy(tls *libc.TLS, pParse uintptr, p uintptr, pIndexedBy uintptr) {
	var pItem uintptr
	_ = pItem
	if p != 0 && (*TToken)(unsafe.Pointer(pIndexedBy)).Fn > uint32(0) {
		pItem = p + 8 + uintptr((*TSrcList)(unsafe.Pointer(p)).FnSrc-int32(1))*80
		if (*TToken)(unsafe.Pointer(pIndexedBy)).Fn == uint32(1) && !((*TToken)(unsafe.Pointer(pIndexedBy)).Fz != 0) {
			/* A "NOT INDEXED" clause was supplied. See parse.y
			 ** construct "indexed_opt" for details. */
			libc.SetBitFieldPtr32Uint32(pItem+24+4, libc.Uint32FromInt32(1), 0, 0x1)
		} else {
			*(*uintptr)(unsafe.Pointer(pItem + 48)) = _sqlite3NameFromToken(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, pIndexedBy)
			libc.SetBitFieldPtr32Uint32(pItem+24+4, libc.Uint32FromInt32(1), 1, 0x2)
			/* No collision on union u2 */
		}
	}
}

// C documentation
//
//	/*
//	** While a SrcList can in general represent multiple tables and subqueries
//	** (as in the FROM clause of a SELECT statement) in this case it contains
//	** the name of a single table, as one might find in an INSERT, DELETE,
//	** or UPDATE statement.  Look up that table in the symbol table and
//	** return a pointer.  Set an error message and return NULL if the table
//	** name is not found or if any other error occurs.
//	**
//	** The following fields are initialized appropriate in pSrc:
//	**
//	**    pSrc->a[0].spTab        Pointer to the Table object
//	**    pSrc->a[0].u2.pIBIndex  Pointer to the INDEXED BY index, if there is one
//	**
//	*/
func _sqlite3SrcListLookup(tls *libc.TLS, pParse uintptr, pSrc uintptr) (r uintptr) {
	var pItem, pTab uintptr
	_, _ = pItem, pTab
	pItem = pSrc + 8
	pTab = _sqlite3LocateTableItem(tls, pParse, uint32(0), pItem)
	if (*TSrcItem)(unsafe.Pointer(pItem)).FpSTab != 0 {
		_sqlite3DeleteTable(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, (*TSrcItem)(unsafe.Pointer(pItem)).FpSTab)
	}
	(*TSrcItem)(unsafe.Pointer(pItem)).FpSTab = pTab
	libc.SetBitFieldPtr32Uint32(pItem+24+4, libc.Uint32FromInt32(1), 10, 0x400)
	if pTab != 0 {
		(*TTable)(unsafe.Pointer(pTab)).FnTabRef = (*TTable)(unsafe.Pointer(pTab)).FnTabRef + 1
		if int32(*(*uint32)(unsafe.Pointer(pItem + 24 + 4))&0x2>>1) != 0 && _sqlite3IndexedByLookup(tls, pParse, pItem) != 0 {
			pTab = uintptr(0)
		}
	}
	return pTab
}

// C documentation
//
//	/*
//	** Remove a Subquery from a SrcItem.  Return the associated Select object.
//	** The returned Select becomes the responsibility of the caller.
//	*/
func _sqlite3SubqueryDetach(tls *libc.TLS, db uintptr, pItem uintptr) (r uintptr) {
	var pSel uintptr
	_ = pSel
	pSel = (*TSubquery)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pItem + 72)))).FpSelect
	_sqlite3DbFree(tls, db, *(*uintptr)(unsafe.Pointer(pItem + 72)))
	*(*uintptr)(unsafe.Pointer(pItem + 72)) = uintptr(0)
	libc.SetBitFieldPtr32Uint32(pItem+24+4, libc.Uint32FromInt32(0), 2, 0x4)
	return pSel
}

func _sqlite3TriggersExist(tls *libc.TLS, pParse uintptr, pTab uintptr, op int32, pChanges uintptr, pMask uintptr) (r uintptr) {
	if (*TTable)(unsafe.Pointer(pTab)).FpTrigger == uintptr(0) && !(_tempTriggersExist(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb) != 0) || int32(Tbft(*(*uint16)(unsafe.Pointer(pParse + 40))&0x1>>0)) != 0 {
		if pMask != 0 {
			**(**int32)(__ccgo_up(pMask)) = 0
		}
		return uintptr(0)
	}
	return _triggersReallyExist(tls, pParse, pTab, op, pChanges, pMask)
}

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

// C documentation
//
//	/*
//	** Walk the parse trees associated with all subqueries in the
//	** FROM clause of SELECT statement p.  Do not invoke the select
//	** callback on p, but do invoke it on each FROM clause subquery
//	** and on any subqueries further down in the tree.  Return
//	** WRC_Abort or WRC_Continue;
//	*/
func _sqlite3WalkSelectFrom(tls *libc.TLS, pWalker uintptr, p uintptr) (r int32) {
	var i int32
	var pItem, pSrc uintptr
	_, _, _ = i, pItem, pSrc
	pSrc = (*TSelect)(unsafe.Pointer(p)).FpSrc
	if pSrc != 0 {
		i = (*TSrcList)(unsafe.Pointer(pSrc)).FnSrc
		pItem = pSrc + 8
		for {
			if !(i > 0) {
				break
			}
			if int32(*(*uint32)(unsafe.Pointer(pItem + 24 + 4))&0x4>>2) != 0 && _sqlite3WalkSelect(tls, pWalker, (*TSubquery)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pItem + 72)))).FpSelect) != 0 {
				return int32(WRC_Abort)
			}
			if int32(*(*uint32)(unsafe.Pointer(pItem + 24 + 4))&0x8>>3) != 0 && _sqlite3WalkExprList(tls, pWalker, *(*uintptr)(unsafe.Pointer(pItem + 48))) != 0 {
				return int32(WRC_Abort)
			}
			goto _1
		_1:
			;
			i = i - 1
			pItem += 80
		}
	}
	return WRC_Continue
}

// C documentation
//
//	/*
//	** If the WHERE_GROUPBY flag is set in the mask passed to sqlite3WhereBegin(),
//	** the planner assumes that the specified pOrderBy list is actually a GROUP
//	** BY clause - and so any order that groups rows as required satisfies the
//	** request.
//	**
//	** Normally, in this case it is not possible for the caller to determine
//	** whether or not the rows are really being delivered in sorted order, or
//	** just in some other order that provides the required grouping. However,
//	** if the WHERE_SORTBYGROUP flag is also passed to sqlite3WhereBegin(), then
//	** this function may be called on the returned WhereInfo object. It returns
//	** true if the rows really will be sorted in the specified order, or false
//	** otherwise.
//	**
//	** For example, assuming:
//	**
//	**   CREATE INDEX i1 ON t1(x, Y);
//	**
//	** then
//	**
//	**   SELECT * FROM t1 GROUP BY x,y ORDER BY x,y;   -- IsSorted()==1
//	**   SELECT * FROM t1 GROUP BY y,x ORDER BY y,x;   -- IsSorted()==0
//	*/
func _sqlite3WhereIsSorted(tls *libc.TLS, pWInfo uintptr) (r int32) {
	return int32(uint32(*(*uint8)(unsafe.Pointer(pWInfo + 68)) & 0x8 >> 3))
}

// C documentation
//
//	/*
//	** Return TRUE if the WHERE loop uses the OP_DeferredSeek opcode to move
//	** the data cursor to the row selected by the index cursor.
//	*/
func _sqlite3WhereUsesDeferredSeek(tls *libc.TLS, pWInfo uintptr) (r int32) {
	return int32(uint32(*(*uint8)(unsafe.Pointer(pWInfo + 68)) & 0x1 >> 0))
}

// C documentation
//
//	/*
//	** Assign new cursor numbers to each of the items in pSrc. For each
//	** new cursor number assigned, set an entry in the aCsrMap[] array
//	** to map the old cursor number to the new:
//	**
//	**     aCsrMap[iOld+1] = iNew;
//	**
//	** The array is guaranteed by the caller to be large enough for all
//	** existing cursor numbers in pSrc.  aCsrMap[0] is the array size.
//	**
//	** If pSrc contains any sub-selects, call this routine recursively
//	** on the FROM clause of each such sub-select, with iExcept set to -1.
//	*/
func _srclistRenumberCursors(tls *libc.TLS, pParse uintptr, aCsrMap uintptr, pSrc uintptr, iExcept int32) {
	var i, v2 int32
	var p, pItem, v3 uintptr
	_, _, _, _, _ = i, p, pItem, v2, v3
	i = 0
	pItem = pSrc + 8
	for {
		if !(i < (*TSrcList)(unsafe.Pointer(pSrc)).FnSrc) {
			break
		}
		if i != iExcept {
			if !(int32(*(*uint32)(unsafe.Pointer(pItem + 24 + 4))&0x80>>7) != 0) || **(**int32)(__ccgo_up(aCsrMap + uintptr((*TSrcItem)(unsafe.Pointer(pItem)).FiCursor+int32(1))*4)) == 0 {
				v3 = pParse + 56
				v2 = *(*int32)(unsafe.Pointer(v3))
				*(*int32)(unsafe.Pointer(v3)) = *(*int32)(unsafe.Pointer(v3)) + 1
				**(**int32)(__ccgo_up(aCsrMap + uintptr((*TSrcItem)(unsafe.Pointer(pItem)).FiCursor+int32(1))*4)) = v2
			}
			(*TSrcItem)(unsafe.Pointer(pItem)).FiCursor = **(**int32)(__ccgo_up(aCsrMap + uintptr((*TSrcItem)(unsafe.Pointer(pItem)).FiCursor+int32(1))*4))
			if int32(*(*uint32)(unsafe.Pointer(pItem + 24 + 4))&0x4>>2) != 0 {
				p = (*TSubquery)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pItem + 72)))).FpSelect
				for {
					if !(p != 0) {
						break
					}
					_srclistRenumberCursors(tls, pParse, aCsrMap, (*TSelect)(unsafe.Pointer(p)).FpSrc, -int32(1))
					goto _4
				_4:
					;
					p = (*TSelect)(unsafe.Pointer(p)).FpPrior
				}
			}
		}
		goto _1
	_1:
		;
		i = i + 1
		pItem += 80
	}
}

func _substSelect(tls *libc.TLS, pSubst uintptr, p uintptr, doPrior int32) {
	var i int32
	var pItem, pSrc, v1 uintptr
	var v2 bool
	_, _, _, _, _ = i, pItem, pSrc, v1, v2
	if !(p != 0) {
		return
	}
	(*TSubstContext)(unsafe.Pointer(pSubst)).FnSelDepth = (*TSubstContext)(unsafe.Pointer(pSubst)).FnSelDepth + 1
	for {
		_substExprList(tls, pSubst, (*TSelect)(unsafe.Pointer(p)).FpEList)
		_substExprList(tls, pSubst, (*TSelect)(unsafe.Pointer(p)).FpGroupBy)
		_substExprList(tls, pSubst, (*TSelect)(unsafe.Pointer(p)).FpOrderBy)
		(*TSelect)(unsafe.Pointer(p)).FpHaving = _substExpr(tls, pSubst, (*TSelect)(unsafe.Pointer(p)).FpHaving)
		(*TSelect)(unsafe.Pointer(p)).FpWhere = _substExpr(tls, pSubst, (*TSelect)(unsafe.Pointer(p)).FpWhere)
		pSrc = (*TSelect)(unsafe.Pointer(p)).FpSrc
		i = (*TSrcList)(unsafe.Pointer(pSrc)).FnSrc
		pItem = pSrc + 8
		for {
			if !(i > 0) {
				break
			}
			if int32(*(*uint32)(unsafe.Pointer(pItem + 24 + 4))&0x4>>2) != 0 {
				_substSelect(tls, pSubst, (*TSubquery)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pItem + 72)))).FpSelect, int32(1))
			}
			if int32(*(*uint32)(unsafe.Pointer(pItem + 24 + 4))&0x8>>3) != 0 {
				_substExprList(tls, pSubst, *(*uintptr)(unsafe.Pointer(pItem + 48)))
			}
			goto _4
		_4:
			;
			i = i - 1
			pItem += 80
		}
		goto _3
	_3:
		;
		if v2 = doPrior != 0; v2 {
			v1 = (*TSelect)(unsafe.Pointer(p)).FpPrior
			p = v1
		}
		if !(v2 && v1 != uintptr(0)) {
			break
		}
	}
	(*TSubstContext)(unsafe.Pointer(pSubst)).FnSelDepth = (*TSubstContext)(unsafe.Pointer(pSubst)).FnSelDepth - 1
}

// C documentation
//
//	/*
//	** Insert or replace a WhereLoop entry using the template supplied.
//	**
//	** An existing WhereLoop entry might be overwritten if the new template
//	** is better and has fewer dependencies.  Or the template will be ignored
//	** and no insert will occur if an existing WhereLoop is faster and has
//	** fewer dependencies than the template.  Otherwise a new WhereLoop is
//	** added based on the template.
//	**
//	** If pBuilder->pOrSet is not NULL then we care about only the
//	** prerequisites and rRun and nOut costs of the N best loops.  That
//	** information is gathered in the pBuilder->pOrSet object.  This special
//	** processing mode is used only for OR clause processing.
//	**
//	** When accumulating multiple loops (when pBuilder->pOrSet is NULL) we
//	** still might overwrite similar loops with the new template if the
//	** new template is better.  Loops may be overwritten if the following
//	** conditions are met:
//	**
//	**    (1)  They have the same iTab.
//	**    (2)  They have the same iSortIdx.
//	**    (3)  The template has same or fewer dependencies than the current loop
//	**    (4)  The template has the same or lower cost than the current loop
//	*/
func _whereLoopInsert(tls *libc.TLS, pBuilder uintptr, pTemplate uintptr) (r int32) {
	var db, p, pIndex, pToDel, pWInfo, ppPrev, ppTail, v1 uintptr
	var rc int32
	_, _, _, _, _, _, _, _, _ = db, p, pIndex, pToDel, pWInfo, ppPrev, ppTail, rc, v1
	pWInfo = (*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FpWInfo
	db = (*TParse)(unsafe.Pointer((*TWhereInfo)(unsafe.Pointer(pWInfo)).FpParse)).Fdb
	/* Stop the search once we hit the query planner search limit */
	if (*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FiPlanLimit == uint32(0) {
		if (*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FpOrSet != 0 {
			(*TWhereOrSet)(unsafe.Pointer((*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FpOrSet)).Fn = uint16(0)
		}
		return int32(SQLITE_DONE)
	}
	(*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FiPlanLimit = (*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FiPlanLimit - 1
	_whereLoopAdjustCost(tls, (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpLoops, pTemplate)
	/* If pBuilder->pOrSet is defined, then only keep track of the costs
	 ** and prereqs.
	 */
	if (*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FpOrSet != uintptr(0) {
		if (*TWhereLoop)(unsafe.Pointer(pTemplate)).FnLTerm != 0 {
			_whereOrInsert(tls, (*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FpOrSet, (*TWhereLoop)(unsafe.Pointer(pTemplate)).Fprereq, (*TWhereLoop)(unsafe.Pointer(pTemplate)).FrRun, (*TWhereLoop)(unsafe.Pointer(pTemplate)).FnOut)
		}
		return SQLITE_OK
	}
	/* Look for an existing WhereLoop to replace with pTemplate
	 */
	ppPrev = _whereLoopFindLesser(tls, pWInfo+80, pTemplate)
	if ppPrev == uintptr(0) {
		/* There already exists a WhereLoop on the list that is better
		 ** than pTemplate, so just ignore pTemplate */
		return SQLITE_OK
	} else {
		p = **(**uintptr)(__ccgo_up(ppPrev))
	}
	/* If we reach this point it means that either p[] should be overwritten
	 ** with pTemplate[] if p[] exists, or if p==NULL then allocate a new
	 ** WhereLoop and insert it.
	 */
	if p == uintptr(0) {
		/* Allocate a new WhereLoop to add to the end of the list */
		v1 = _sqlite3DbMallocRawNN(tls, db, uint64(104))
		p = v1
		**(**uintptr)(__ccgo_up(ppPrev)) = v1
		if p == uintptr(0) {
			return int32(SQLITE_NOMEM)
		}
		_whereLoopInit(tls, p)
		(*TWhereLoop)(unsafe.Pointer(p)).FpNextLoop = uintptr(0)
	} else {
		/* We will be overwriting WhereLoop p[].  But before we do, first
		 ** go through the rest of the list and delete any other entries besides
		 ** p[] that are also supplanted by pTemplate */
		ppTail = p + 72
		for **(**uintptr)(__ccgo_up(ppTail)) != 0 {
			ppTail = _whereLoopFindLesser(tls, ppTail, pTemplate)
			if ppTail == uintptr(0) {
				break
			}
			pToDel = **(**uintptr)(__ccgo_up(ppTail))
			if pToDel == uintptr(0) {
				break
			}
			**(**uintptr)(__ccgo_up(ppTail)) = (*TWhereLoop)(unsafe.Pointer(pToDel)).FpNextLoop
			_whereLoopDelete(tls, db, pToDel)
		}
	}
	rc = _whereLoopXfer(tls, db, p, pTemplate)
	if (*TWhereLoop)(unsafe.Pointer(p)).FwsFlags&uint32(WHERE_VIRTUALTABLE) == uint32(0) {
		pIndex = (*(*struct {
			FnEq          Tu16
			FnBtm         Tu16
			FnTop         Tu16
			FnDistinctCol Tu16
			FpIndex       uintptr
			FpOrderBy     uintptr
		})(unsafe.Pointer(p + 24))).FpIndex
		if pIndex != 0 && int32(uint32(*(*uint16)(unsafe.Pointer(pIndex + 100))&0x3>>0)) == int32(SQLITE_IDXTYPE_IPK) {
			(*(*struct {
				FnEq          Tu16
				FnBtm         Tu16
				FnTop         Tu16
				FnDistinctCol Tu16
				FpIndex       uintptr
				FpOrderBy     uintptr
			})(unsafe.Pointer(p + 24))).FpIndex = uintptr(0)
		}
	}
	return rc
}
