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

//go:build (linux && arm64) || (linux && ppc64le) || (linux && riscv64) || (linux && s390x) || (openbsd && arm64)

package sqlite3

import (
	"unsafe"

	"modernc.org/libc"
)

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