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

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

package vec

import (
	"unsafe"

	"modernc.org/libc"
	libsqlite3 "modernc.org/sqlite/lib"
)

func Xnpy_token_next(tls *libc.TLS, start uintptr, end uintptr, out uintptr) (r int32) {
	var curr uint8
	var ptr, start1, start2, v1 uintptr
	_, _, _, _, _ = curr, ptr, start1, start2, v1
	ptr = start
	for ptr < end {
		curr = **(**uint8)(__ccgo_up(ptr))
		if Xis_whitespace(tls, curr) != 0 {
			ptr = ptr + 1
			continue
		} else {
			if libc.Int32FromUint8(curr) == int32('(') {
				v1 = ptr
				ptr = ptr + 1
				(*TNpyToken)(unsafe.Pointer(out)).Fstart = v1
				(*TNpyToken)(unsafe.Pointer(out)).Fend = ptr
				(*TNpyToken)(unsafe.Pointer(out)).Ftoken_type = int32(_NPY_TOKEN_TYPE_LPAREN)
				return int32(m_VEC0_TOKEN_RESULT_SOME)
			} else {
				if libc.Int32FromUint8(curr) == int32(')') {
					v1 = ptr
					ptr = ptr + 1
					(*TNpyToken)(unsafe.Pointer(out)).Fstart = v1
					(*TNpyToken)(unsafe.Pointer(out)).Fend = ptr
					(*TNpyToken)(unsafe.Pointer(out)).Ftoken_type = int32(_NPY_TOKEN_TYPE_RPAREN)
					return int32(m_VEC0_TOKEN_RESULT_SOME)
				} else {
					if libc.Int32FromUint8(curr) == int32('{') {
						v1 = ptr
						ptr = ptr + 1
						(*TNpyToken)(unsafe.Pointer(out)).Fstart = v1
						(*TNpyToken)(unsafe.Pointer(out)).Fend = ptr
						(*TNpyToken)(unsafe.Pointer(out)).Ftoken_type = int32(_NPY_TOKEN_TYPE_LBRACE)
						return int32(m_VEC0_TOKEN_RESULT_SOME)
					} else {
						if libc.Int32FromUint8(curr) == int32('}') {
							v1 = ptr
							ptr = ptr + 1
							(*TNpyToken)(unsafe.Pointer(out)).Fstart = v1
							(*TNpyToken)(unsafe.Pointer(out)).Fend = ptr
							(*TNpyToken)(unsafe.Pointer(out)).Ftoken_type = int32(_NPY_TOKEN_TYPE_RBRACE)
							return int32(m_VEC0_TOKEN_RESULT_SOME)
						} else {
							if libc.Int32FromUint8(curr) == int32(':') {
								v1 = ptr
								ptr = ptr + 1
								(*TNpyToken)(unsafe.Pointer(out)).Fstart = v1
								(*TNpyToken)(unsafe.Pointer(out)).Fend = ptr
								(*TNpyToken)(unsafe.Pointer(out)).Ftoken_type = int32(_NPY_TOKEN_TYPE_COLON)
								return int32(m_VEC0_TOKEN_RESULT_SOME)
							} else {
								if libc.Int32FromUint8(curr) == int32(',') {
									v1 = ptr
									ptr = ptr + 1
									(*TNpyToken)(unsafe.Pointer(out)).Fstart = v1
									(*TNpyToken)(unsafe.Pointer(out)).Fend = ptr
									(*TNpyToken)(unsafe.Pointer(out)).Ftoken_type = int32(_NPY_TOKEN_TYPE_COMMA)
									return int32(m_VEC0_TOKEN_RESULT_SOME)
								} else {
									if libc.Int32FromUint8(curr) == int32('\'') {
										start1 = ptr
										ptr = ptr + 1
										for ptr < end {
											if libc.Int32FromUint8(**(**uint8)(__ccgo_up(ptr))) == int32('\'') {
												break
											}
											ptr = ptr + 1
										}
										if ptr >= end || libc.Int32FromUint8(**(**uint8)(__ccgo_up(ptr))) != int32('\'') {
											return int32(m_VEC0_TOKEN_RESULT_ERROR)
										}
										(*TNpyToken)(unsafe.Pointer(out)).Fstart = start1
										ptr = ptr + 1
										v1 = ptr
										(*TNpyToken)(unsafe.Pointer(out)).Fend = v1
										(*TNpyToken)(unsafe.Pointer(out)).Ftoken_type = int32(_NPY_TOKEN_TYPE_STRING)
										return int32(m_VEC0_TOKEN_RESULT_SOME)
									} else {
										if libc.Int32FromUint8(curr) == int32('F') && libc.Xstrncmp(tls, ptr, __ccgo_ts+1916, libc.Xstrlen(tls, __ccgo_ts+1916)) == 0 {
											(*TNpyToken)(unsafe.Pointer(out)).Fstart = ptr
											(*TNpyToken)(unsafe.Pointer(out)).Fend = ptr + uintptr(libc.Int32FromUint64(libc.Xstrlen(tls, __ccgo_ts+1916)))
											ptr = (*TNpyToken)(unsafe.Pointer(out)).Fend
											(*TNpyToken)(unsafe.Pointer(out)).Ftoken_type = int32(_NPY_TOKEN_TYPE_FALSE)
											return int32(m_VEC0_TOKEN_RESULT_SOME)
										} else {
											if Xis_digit(tls, curr) != 0 {
												start2 = ptr
												for ptr < end && Xis_digit(tls, uint8(**(**uint8)(__ccgo_up(ptr)))) != 0 {
													ptr = ptr + 1
												}
												(*TNpyToken)(unsafe.Pointer(out)).Fstart = start2
												(*TNpyToken)(unsafe.Pointer(out)).Fend = ptr
												(*TNpyToken)(unsafe.Pointer(out)).Ftoken_type = int32(_NPY_TOKEN_TYPE_NUMBER)
												return int32(m_VEC0_TOKEN_RESULT_SOME)
											} else {
												return int32(m_VEC0_TOKEN_RESULT_ERROR)
											}
										}
									}
								}
							}
						}
					}
				}
			}
		}
	}
	return int32(m_VEC0_TOKEN_RESULT_ERROR)
}

func Xvec0Filter_knn(tls *libc.TLS, pCur uintptr, p uintptr, idxNum int32, idxStr uintptr, argc int32, argv uintptr) (r int32) {
	bp := tls.Alloc(208)
	defer tls.Free(208)
	var aMetadataIn, arrayRowidsIn, item2, knn_data, s, vector_column uintptr
	var entry3 TVec0MetadataInTextEntry
	var i, i1, k_idx, metadata_idx, n, query_idx, rc, rc1, rowid_in_idx, vectorColumnIdx int32
	var i2, j Tsize_t
	var k Ti64
	var _ /* dimensions at bp+16 */ Tsize_t
	var _ /* elementType at bp+24 */ _VectorElementType
	var _ /* entry at bp+104 */ uintptr
	var _ /* entry at bp+120 */ uintptr
	var _ /* entry at bp+128 */ TVec0MetadataInTextEntry
	var _ /* item at bp+48 */ uintptr
	var _ /* item at bp+64 */ TVec0MetadataIn
	var _ /* k_used at bp+160 */ Ti64
	var _ /* pzError at bp+40 */ uintptr
	var _ /* queryVector at bp+8 */ uintptr
	var _ /* queryVectorCleanup at bp+32 */ Tvector_cleanup
	var _ /* rowid at bp+56 */ Ti64
	var _ /* stmtChunks at bp+0 */ uintptr
	var _ /* topk_distances at bp+152 */ uintptr
	var _ /* topk_rowids at bp+144 */ uintptr
	var _ /* v at bp+112 */ Ti64
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = aMetadataIn, arrayRowidsIn, entry3, i, i1, i2, item2, j, k, k_idx, knn_data, metadata_idx, n, query_idx, rc, rc1, rowid_in_idx, s, vectorColumnIdx, vector_column
	vectorColumnIdx = idxNum
	vector_column = p + 608 + uintptr(vectorColumnIdx)*32
	arrayRowidsIn = libc.UintptrFromInt32(0)
	**(**uintptr)(__ccgo_up(bp)) = libc.UintptrFromInt32(0)
	**(**Tvector_cleanup)(__ccgo_up(bp + 32)) = __ccgo_fp(Xvector_cleanup_noop)
	knn_data = libsqlite3.Xsqlite3_malloc(tls, int32(40))
	if !(knn_data != 0) {
		return int32(m_SQLITE_NOMEM)
	}
	libc.Xmemset(tls, knn_data, 0, uint64(40))
	// array of `struct Vec0MetadataIn`, IF there are any `xxx in (...)` metadata constraints
	aMetadataIn = libc.UintptrFromInt32(0)
	query_idx = -int32(1)
	k_idx = -int32(1)
	rowid_in_idx = -int32(1)
	i = 0
	for {
		if !(i < argc) {
			break
		}
		if libc.Int32FromUint8(**(**uint8)(__ccgo_up(idxStr + uintptr(int32(1)+i*int32(4))))) == int32(_VEC0_IDXSTR_KIND_KNN_MATCH) {
			query_idx = i
		}
		if libc.Int32FromUint8(**(**uint8)(__ccgo_up(idxStr + uintptr(int32(1)+i*int32(4))))) == int32(_VEC0_IDXSTR_KIND_KNN_K) {
			k_idx = i
		}
		if libc.Int32FromUint8(**(**uint8)(__ccgo_up(idxStr + uintptr(int32(1)+i*int32(4))))) == int32(_VEC0_IDXSTR_KIND_KNN_ROWID_IN) {
			rowid_in_idx = i
		}
		goto _1
	_1:
		;
		i = i + 1
	}
	// make sure the query vector matches the vector column (type dimensions etc.)
	rc = Xvector_from_value(tls, **(**uintptr)(__ccgo_up(argv + uintptr(query_idx)*8)), bp+8, bp+16, bp+24, bp+32, bp+40)
	if rc != m_SQLITE_OK {
		Xvtab_set_error(tls, p, __ccgo_ts+10061, libc.VaList(bp+176, (*TVectorColumnDefinition)(unsafe.Pointer(vector_column)).Fname_length, (*TVectorColumnDefinition)(unsafe.Pointer(vector_column)).Fname, **(**uintptr)(__ccgo_up(bp + 40))))
		rc = int32(m_SQLITE_ERROR)
		goto cleanup
	}
	if **(**_VectorElementType)(__ccgo_up(bp + 24)) != (*TVectorColumnDefinition)(unsafe.Pointer(vector_column)).Felement_type {
		Xvtab_set_error(tls, p, __ccgo_ts+10110, libc.VaList(bp+176, (*TVectorColumnDefinition)(unsafe.Pointer(vector_column)).Fname_length, (*TVectorColumnDefinition)(unsafe.Pointer(vector_column)).Fname, Xvector_subtype_name(tls, (*TVectorColumnDefinition)(unsafe.Pointer(vector_column)).Felement_type), Xvector_subtype_name(tls, **(**_VectorElementType)(__ccgo_up(bp + 24)))))
		rc = int32(m_SQLITE_ERROR)
		goto cleanup
	}
	if **(**Tsize_t)(__ccgo_up(bp + 16)) != (*TVectorColumnDefinition)(unsafe.Pointer(vector_column)).Fdimensions {
		Xvtab_set_error(tls, p, __ccgo_ts+10205, libc.VaList(bp+176, (*TVectorColumnDefinition)(unsafe.Pointer(vector_column)).Fname_length, (*TVectorColumnDefinition)(unsafe.Pointer(vector_column)).Fname, (*TVectorColumnDefinition)(unsafe.Pointer(vector_column)).Fdimensions, **(**Tsize_t)(__ccgo_up(bp + 16))))
		rc = int32(m_SQLITE_ERROR)
		goto cleanup
	}
	k = libsqlite3.Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(argv + uintptr(k_idx)*8)))
	if k < 0 {
		Xvtab_set_error(tls, p, __ccgo_ts+10304, 0)
		rc = int32(m_SQLITE_ERROR)
		goto cleanup
	}
	if k > int64(m_SQLITE_VEC_VEC0_K_MAX) {
		Xvtab_set_error(tls, p, __ccgo_ts+10363, libc.VaList(bp+176, k, int32(m_SQLITE_VEC_VEC0_K_MAX)))
		rc = int32(m_SQLITE_ERROR)
		goto cleanup
	}
	if k == 0 {
		(*Tvec0_query_knn_data)(unsafe.Pointer(knn_data)).Fk = 0
		(*Tvec0_cursor)(unsafe.Pointer(pCur)).Fknn_data = knn_data
		(*Tvec0_cursor)(unsafe.Pointer(pCur)).Fquery_plan = int32(_VEC0_QUERY_PLAN_KNN)
		rc = m_SQLITE_OK
		goto cleanup
	}
	// handle when a `rowid in (...)` operation was provided
	// Array of all the rowids that appear in any `rowid in (...)` constraint.
	// NULL if none were provided, which means a "full" scan.
	if rowid_in_idx >= 0 {
		arrayRowidsIn = libsqlite3.Xsqlite3_malloc(tls, int32(32))
		if !(arrayRowidsIn != 0) {
			rc1 = int32(m_SQLITE_NOMEM)
			goto cleanup
		}
		libc.Xmemset(tls, arrayRowidsIn, 0, uint64(32))
		rc1 = Xarray_init(tls, arrayRowidsIn, uint64(8), uint64(32))
		if rc1 != m_SQLITE_OK {
			goto cleanup
		}
		rc1 = libsqlite3.Xsqlite3_vtab_in_first(tls, **(**uintptr)(__ccgo_up(argv + uintptr(rowid_in_idx)*8)), bp+48)
		for {
			if !(rc1 == m_SQLITE_OK && **(**uintptr)(__ccgo_up(bp + 48)) != 0) {
				break
			}
			if (*Tvec0_vtab)(unsafe.Pointer(p)).FpkIsText != 0 {
				rc1 = Xvec0_rowid_from_id(tls, p, **(**uintptr)(__ccgo_up(bp + 48)), bp+56)
				if rc1 != m_SQLITE_OK {
					goto cleanup
				}
			} else {
				**(**Ti64)(__ccgo_up(bp + 56)) = libsqlite3.Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(bp + 48)))
			}
			rc1 = Xarray_append(tls, arrayRowidsIn, bp+56)
			if rc1 != m_SQLITE_OK {
				goto cleanup
			}
			goto _2
		_2:
			;
			rc1 = libsqlite3.Xsqlite3_vtab_in_next(tls, **(**uintptr)(__ccgo_up(argv + uintptr(rowid_in_idx)*8)), bp+48)
		}
		if rc1 != int32(m_SQLITE_DONE) {
			Xvtab_set_error(tls, p, __ccgo_ts+10431, 0)
			goto cleanup
		}
		libc.Xqsort(tls, (*TArray)(unsafe.Pointer(arrayRowidsIn)).Fz, (*TArray)(unsafe.Pointer(arrayRowidsIn)).Flength, (*TArray)(unsafe.Pointer(arrayRowidsIn)).Felement_size, __ccgo_fp(X_cmp))
	}
	i1 = 0
	for {
		if !(i1 < argc) {
			break
		}
		if !(libc.Int32FromUint8(**(**uint8)(__ccgo_up(idxStr + uintptr(int32(1)+i1*int32(4))))) == int32(_VEC0_IDXSTR_KIND_METADATA_CONSTRAINT) && libc.Int32FromUint8(**(**uint8)(__ccgo_up(idxStr + uintptr(int32(1)+i1*int32(4)+int32(2))))) == int32(_VEC0_METADATA_OPERATOR_IN)) {
			goto _3
		}
		metadata_idx = libc.Int32FromUint8(**(**uint8)(__ccgo_up(idxStr + uintptr(int32(1)+i1*int32(4)+int32(1))))) - int32('A')
		if !(aMetadataIn != 0) {
			aMetadataIn = libsqlite3.Xsqlite3_malloc(tls, int32(32))
			if !(aMetadataIn != 0) {
				rc = int32(m_SQLITE_NOMEM)
				goto cleanup
			}
			libc.Xmemset(tls, aMetadataIn, 0, uint64(32))
			rc = Xarray_init(tls, aMetadataIn, uint64(40), uint64(8))
			if rc != m_SQLITE_OK {
				goto cleanup
			}
		}
		libc.Xmemset(tls, bp+64, 0, uint64(40))
		(**(**TVec0MetadataIn)(__ccgo_up(bp + 64))).Fmetadata_idx = metadata_idx
		(**(**TVec0MetadataIn)(__ccgo_up(bp + 64))).Fargv_idx = i1
		switch (**(**TVec0MetadataColumnDefinition)(__ccgo_up(p + 1600 + uintptr(metadata_idx)*24))).Fkind {
		case int32(_VEC0_METADATA_COLUMN_KIND_INTEGER):
			rc = Xarray_init(tls, bp+64+8, uint64(8), uint64(16))
			if rc != m_SQLITE_OK {
				goto cleanup
			}
			rc = libsqlite3.Xsqlite3_vtab_in_first(tls, **(**uintptr)(__ccgo_up(argv + uintptr(i1)*8)), bp+104)
			for {
				if !(rc == m_SQLITE_OK && **(**uintptr)(__ccgo_up(bp + 104)) != 0) {
					break
				}
				**(**Ti64)(__ccgo_up(bp + 112)) = libsqlite3.Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(bp + 104)))
				rc = Xarray_append(tls, bp+64+8, bp+112)
				if rc != m_SQLITE_OK {
					goto cleanup
				}
				goto _4
			_4:
				;
				rc = libsqlite3.Xsqlite3_vtab_in_next(tls, **(**uintptr)(__ccgo_up(argv + uintptr(i1)*8)), bp+104)
			}
			if rc != int32(m_SQLITE_DONE) {
				Xvtab_set_error(tls, p, __ccgo_ts+10469, 0)
				goto cleanup
			}
		case int32(_VEC0_METADATA_COLUMN_KIND_TEXT):
			rc = Xarray_init(tls, bp+64+8, uint64(16), uint64(16))
			if rc != m_SQLITE_OK {
				goto cleanup
			}
			rc = libsqlite3.Xsqlite3_vtab_in_first(tls, **(**uintptr)(__ccgo_up(argv + uintptr(i1)*8)), bp+120)
			for {
				if !(rc == m_SQLITE_OK && **(**uintptr)(__ccgo_up(bp + 120)) != 0) {
					break
				}
				s = libsqlite3.Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(bp + 120)))
				n = libsqlite3.Xsqlite3_value_bytes(tls, **(**uintptr)(__ccgo_up(bp + 120)))
				(**(**TVec0MetadataInTextEntry)(__ccgo_up(bp + 128))).FzString = libsqlite3.Xsqlite3_mprintf(tls, __ccgo_ts+1874, libc.VaList(bp+176, n, s))
				if !((**(**TVec0MetadataInTextEntry)(__ccgo_up(bp + 128))).FzString != 0) {
					rc = int32(m_SQLITE_NOMEM)
					goto cleanup
				}
				(**(**TVec0MetadataInTextEntry)(__ccgo_up(bp + 128))).Fn = n
				rc = Xarray_append(tls, bp+64+8, bp+128)
				if rc != m_SQLITE_OK {
					goto cleanup
				}
				goto _5
			_5:
				;
				rc = libsqlite3.Xsqlite3_vtab_in_next(tls, **(**uintptr)(__ccgo_up(argv + uintptr(i1)*8)), bp+120)
			}
			if rc != int32(m_SQLITE_DONE) {
				Xvtab_set_error(tls, p, __ccgo_ts+10530, 0)
				goto cleanup
			}
		default:
			Xvtab_set_error(tls, p, __ccgo_ts+10588, 0)
			goto cleanup
		}
		rc = Xarray_append(tls, aMetadataIn, bp+64)
		if rc != m_SQLITE_OK {
			goto cleanup
		}
		goto _3
	_3:
		;
		i1 = i1 + 1
	}
	rc = Xvec0_chunks_iter(tls, p, idxStr, argc, argv, bp)
	if rc != m_SQLITE_OK {
		// IMP: V06942_23781
		Xvtab_set_error(tls, p, __ccgo_ts+10614, libc.VaList(bp+176, libsqlite3.Xsqlite3_errmsg(tls, (*Tvec0_vtab)(unsafe.Pointer(p)).Fdb)))
		goto cleanup
	}
	**(**uintptr)(__ccgo_up(bp + 144)) = libc.UintptrFromInt32(0)
	**(**uintptr)(__ccgo_up(bp + 152)) = libc.UintptrFromInt32(0)
	**(**Ti64)(__ccgo_up(bp + 160)) = 0
	rc = Xvec0Filter_knn_chunks_iter(tls, p, **(**uintptr)(__ccgo_up(bp)), vector_column, vectorColumnIdx, arrayRowidsIn, aMetadataIn, idxStr, argc, argv, **(**uintptr)(__ccgo_up(bp + 8)), k, bp+144, bp+152, bp+160)
	if rc != m_SQLITE_OK {
		goto cleanup
	}
	(*Tvec0_query_knn_data)(unsafe.Pointer(knn_data)).Fcurrent_idx = 0
	(*Tvec0_query_knn_data)(unsafe.Pointer(knn_data)).Fk = k
	(*Tvec0_query_knn_data)(unsafe.Pointer(knn_data)).Frowids = **(**uintptr)(__ccgo_up(bp + 144))
	(*Tvec0_query_knn_data)(unsafe.Pointer(knn_data)).Fdistances = **(**uintptr)(__ccgo_up(bp + 152))
	(*Tvec0_query_knn_data)(unsafe.Pointer(knn_data)).Fk_used = **(**Ti64)(__ccgo_up(bp + 160))
	(*Tvec0_cursor)(unsafe.Pointer(pCur)).Fknn_data = knn_data
	(*Tvec0_cursor)(unsafe.Pointer(pCur)).Fquery_plan = int32(_VEC0_QUERY_PLAN_KNN)
	rc = m_SQLITE_OK
	goto cleanup
cleanup:
	;
	libsqlite3.Xsqlite3_finalize(tls, **(**uintptr)(__ccgo_up(bp)))
	Xarray_cleanup(tls, arrayRowidsIn)
	libsqlite3.Xsqlite3_free(tls, arrayRowidsIn)
	(*(*func(*libc.TLS, uintptr))(unsafe.Pointer(bp + 32)))(tls, **(**uintptr)(__ccgo_up(bp + 8)))
	if aMetadataIn != 0 {
		i2 = uint64(0)
		for {
			if !(i2 < (*TArray)(unsafe.Pointer(aMetadataIn)).Flength) {
				break
			}
			item2 = (*TArray)(unsafe.Pointer(aMetadataIn)).Fz + uintptr(i2)*40
			j = uint64(0)
			for {
				if !(j < (*TVec0MetadataIn)(unsafe.Pointer(item2)).Farray.Flength) {
					break
				}
				if (**(**TVec0MetadataColumnDefinition)(__ccgo_up(p + 1600 + uintptr((*TVec0MetadataIn)(unsafe.Pointer(item2)).Fmetadata_idx)*24))).Fkind == int32(_VEC0_METADATA_COLUMN_KIND_TEXT) {
					entry3 = **(**TVec0MetadataInTextEntry)(__ccgo_up((*TVec0MetadataIn)(unsafe.Pointer(item2)).Farray.Fz + uintptr(j)*16))
					libsqlite3.Xsqlite3_free(tls, entry3.FzString)
				}
				goto _7
			_7:
				;
				j = j + 1
			}
			Xarray_cleanup(tls, item2+8)
			goto _6
		_6:
			;
			i2 = i2 + 1
		}
		Xarray_cleanup(tls, aMetadataIn)
	}
	libsqlite3.Xsqlite3_free(tls, aMetadataIn)
	if rc != m_SQLITE_OK {
		libsqlite3.Xsqlite3_free(tls, knn_data)
	}
	return rc
}

// C documentation
//
//	/**
//	 * @brief Crete at "iterator" (sqlite3_stmt) of chunks with the given constraints
//	 *
//	 * Any VEC0_IDXSTR_KIND_KNN_PARTITON_CONSTRAINT values in idxStr/argv will be applied
//	 * as WHERE constraints in the underlying stmt SQL, and any consumer of the stmt
//	 * can freely step through the stmt with all constraints satisfied.
//	 *
//	 * @param p - vec0_vtab
//	 * @param idxStr - the xBestIndex/xFilter idxstr containing VEC0_IDXSTR values
//	 * @param argc - number of argv values from xFilter
//	 * @param argv - array of sqlite3_value from xFilter
//	 * @param outStmt - output sqlite3_stmt of chunks with all filters applied
//	 * @return int SQLITE_OK on success, error code otherwise
//	 */
func Xvec0_chunks_iter(tls *libc.TLS, p uintptr, idxStr uintptr, argc int32, argv uintptr, outStmt uintptr) (r int32) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var appendedWhere, i, i1, idx, idx1, idxStrLength, n, numValueEntries, operator, partition_idx, rc, v3 int32
	var kind, kind1 uint8
	var s, zSql, zSql1 uintptr
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = appendedWhere, i, i1, idx, idx1, idxStrLength, kind, kind1, n, numValueEntries, operator, partition_idx, rc, s, zSql, zSql1, v3
	// always null terminated, enforced by SQLite
	idxStrLength = libc.Int32FromUint64(libc.Xstrlen(tls, idxStr))
	// "1" refers to the initial vec0_query_plan char, 4 is the number of chars per "element"
	numValueEntries = (idxStrLength - int32(1)) / int32(4)
	s = libsqlite3.Xsqlite3_str_new(tls, libc.UintptrFromInt32(0))
	libsqlite3.Xsqlite3_str_appendf(tls, s, __ccgo_ts+9522, libc.VaList(bp+8, (*Tvec0_vtab)(unsafe.Pointer(p)).FschemaName, (*Tvec0_vtab)(unsafe.Pointer(p)).FtableName))
	appendedWhere = 0
	i = 0
	for {
		if !(i < numValueEntries) {
			break
		}
		idx = int32(1) + i*int32(4)
		kind = **(**uint8)(__ccgo_up(idxStr + uintptr(idx+0)))
		if libc.Int32FromUint8(kind) != int32(_VEC0_IDXSTR_KIND_KNN_PARTITON_CONSTRAINT) {
			goto _1
		}
		partition_idx = libc.Int32FromUint8(**(**uint8)(__ccgo_up(idxStr + uintptr(idx+int32(1))))) - int32('A')
		operator = libc.Int32FromUint8(**(**uint8)(__ccgo_up(idxStr + uintptr(idx+int32(2)))))
		// idxStr[idx + 3] is just null, a '_' placeholder
		if !(appendedWhere != 0) {
			libsqlite3.Xsqlite3_str_appendall(tls, s, __ccgo_ts+9579)
			appendedWhere = int32(1)
		} else {
			libsqlite3.Xsqlite3_str_appendall(tls, s, __ccgo_ts+4165)
		}
		switch operator {
		case int32(_VEC0_PARTITION_OPERATOR_EQ):
			libsqlite3.Xsqlite3_str_appendf(tls, s, __ccgo_ts+4171, libc.VaList(bp+8, partition_idx))
		case int32(_VEC0_PARTITION_OPERATOR_GT):
			libsqlite3.Xsqlite3_str_appendf(tls, s, __ccgo_ts+9587, libc.VaList(bp+8, partition_idx))
		case int32(_VEC0_PARTITION_OPERATOR_LE):
			libsqlite3.Xsqlite3_str_appendf(tls, s, __ccgo_ts+9607, libc.VaList(bp+8, partition_idx))
		case int32(_VEC0_PARTITION_OPERATOR_LT):
			libsqlite3.Xsqlite3_str_appendf(tls, s, __ccgo_ts+9628, libc.VaList(bp+8, partition_idx))
		case int32(_VEC0_PARTITION_OPERATOR_GE):
			libsqlite3.Xsqlite3_str_appendf(tls, s, __ccgo_ts+9648, libc.VaList(bp+8, partition_idx))
		case int32(_VEC0_PARTITION_OPERATOR_NE):
			libsqlite3.Xsqlite3_str_appendf(tls, s, __ccgo_ts+9669, libc.VaList(bp+8, partition_idx))
		default:
			zSql = libsqlite3.Xsqlite3_str_finish(tls, s)
			libsqlite3.Xsqlite3_free(tls, zSql)
			return int32(m_SQLITE_ERROR)
		}
		goto _1
	_1:
		;
		i = i + 1
	}
	zSql1 = libsqlite3.Xsqlite3_str_finish(tls, s)
	if !(zSql1 != 0) {
		return int32(m_SQLITE_NOMEM)
	}
	rc = libsqlite3.Xsqlite3_prepare_v2(tls, (*Tvec0_vtab)(unsafe.Pointer(p)).Fdb, zSql1, -int32(1), outStmt, libc.UintptrFromInt32(0))
	libsqlite3.Xsqlite3_free(tls, zSql1)
	if rc != m_SQLITE_OK {
		return rc
	}
	n = int32(1)
	i1 = 0
	for {
		if !(i1 < numValueEntries) {
			break
		}
		idx1 = int32(1) + i1*int32(4)
		kind1 = **(**uint8)(__ccgo_up(idxStr + uintptr(idx1+0)))
		if libc.Int32FromUint8(kind1) != int32(_VEC0_IDXSTR_KIND_KNN_PARTITON_CONSTRAINT) {
			goto _2
		}
		v3 = n
		n = n + 1
		libsqlite3.Xsqlite3_bind_value(tls, **(**uintptr)(__ccgo_up(outStmt)), v3, **(**uintptr)(__ccgo_up(argv + uintptr(i1)*8)))
		goto _2
	_2:
		;
		i1 = i1 + 1
	}
	return rc
}

func _vec0BestIndex(tls *libc.TLS, pVTab uintptr, pIdxInfo uintptr) (r int32) {
	var argvIndex, hasAuxConstraint, i, i1, i2, i3, iColumn, iColumn1, iColumn2, iColumn3, iKTerm, iLimitTerm, iMatchTerm, iMatchVectorTerm, iRowidInTerm, iRowidTerm, metadata_idx, op, op1, op2, op3, partition_idx, rc, vtabIn1, v2 int32
	var idxStr, p uintptr
	var value, value1, value2 uint8
	var vtabIn Tu8
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = argvIndex, hasAuxConstraint, i, i1, i2, i3, iColumn, iColumn1, iColumn2, iColumn3, iKTerm, iLimitTerm, iMatchTerm, iMatchVectorTerm, iRowidInTerm, iRowidTerm, idxStr, metadata_idx, op, op1, op2, op3, p, partition_idx, rc, value, value1, value2, vtabIn, vtabIn1, v2
	p = pVTab
	/**
	 * Possible query plans are:
	 * 1. KNN when:
	 *    a) An `MATCH` op on vector column
	 *    b) ORDER BY on distance column
	 *    c) LIMIT
	 *    d) rowid in (...) OPTIONAL
	 * 2. Point when:
	 *    a) An `EQ` op on rowid column
	 * 3. else: fullscan
	 *
	 */
	iMatchTerm = -int32(1)
	iMatchVectorTerm = -int32(1)
	iLimitTerm = -int32(1)
	iRowidTerm = -int32(1)
	iKTerm = -int32(1)
	iRowidInTerm = -int32(1)
	hasAuxConstraint = 0
	i = 0
	for {
		if !(i < (*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FnConstraint) {
			break
		}
		vtabIn = uint8(0)
		if libsqlite3.Xsqlite3_libversion_number(tls) >= int32(3038000) {
			vtabIn = libc.Uint8FromInt32(libsqlite3.Xsqlite3_vtab_in(tls, pIdxInfo, i, -int32(1)))
		}
		if !((**(**Tsqlite3_index_constraint)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraint + uintptr(i)*12))).Fusable != 0) {
			goto _1
		}
		iColumn = (**(**Tsqlite3_index_constraint)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraint + uintptr(i)*12))).FiColumn
		op = libc.Int32FromUint8((**(**Tsqlite3_index_constraint)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraint + uintptr(i)*12))).Fop)
		if op == int32(m_SQLITE_INDEX_CONSTRAINT_LIMIT) {
			iLimitTerm = i
		}
		if op == int32(m_SQLITE_INDEX_CONSTRAINT_MATCH) && Xvec0_column_idx_is_vector(tls, p, iColumn) != 0 {
			if iMatchTerm > -int32(1) {
				Xvtab_set_error(tls, pVTab, __ccgo_ts+8434, 0)
				return int32(m_SQLITE_ERROR)
			}
			iMatchTerm = i
			iMatchVectorTerm = Xvec0_column_idx_to_vector_idx(tls, p, iColumn)
		}
		if op == int32(m_SQLITE_INDEX_CONSTRAINT_EQ) && iColumn == m_VEC0_COLUMN_ID {
			if vtabIn != 0 {
				if iRowidInTerm != -int32(1) {
					Xvtab_set_error(tls, pVTab, __ccgo_ts+8490, 0)
					return int32(m_SQLITE_ERROR)
				}
				iRowidInTerm = i
			} else {
				iRowidTerm = i
			}
		}
		if op == int32(m_SQLITE_INDEX_CONSTRAINT_EQ) && iColumn == Xvec0_column_k_idx(tls, p) {
			iKTerm = i
		}
		if op != int32(m_SQLITE_INDEX_CONSTRAINT_LIMIT) && op != int32(m_SQLITE_INDEX_CONSTRAINT_OFFSET) && Xvec0_column_idx_is_auxiliary(tls, p, iColumn) != 0 {
			hasAuxConstraint = int32(1)
		}
		goto _1
	_1:
		;
		i = i + 1
	}
	idxStr = libsqlite3.Xsqlite3_str_new(tls, libc.UintptrFromInt32(0))
	if iMatchTerm >= 0 {
		if iLimitTerm < 0 && iKTerm < 0 {
			Xvtab_set_error(tls, pVTab, __ccgo_ts+8556, 0)
			rc = int32(m_SQLITE_ERROR)
			goto done
		}
		if iLimitTerm >= 0 && iKTerm >= 0 {
			Xvtab_set_error(tls, pVTab, __ccgo_ts+8619, 0)
			rc = int32(m_SQLITE_ERROR)
			goto done
		}
		if (*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FnOrderBy != 0 {
			if (*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FnOrderBy > int32(1) {
				Xvtab_set_error(tls, pVTab, __ccgo_ts+8666, 0)
				rc = int32(m_SQLITE_ERROR)
				goto done
			}
			if (**(**Tsqlite3_index_orderby)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaOrderBy))).FiColumn != Xvec0_column_distance_idx(tls, p) {
				Xvtab_set_error(tls, pVTab, __ccgo_ts+8738, 0)
				rc = int32(m_SQLITE_ERROR)
				goto done
			}
			if (**(**Tsqlite3_index_orderby)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaOrderBy))).Fdesc != 0 {
				Xvtab_set_error(tls, pVTab, __ccgo_ts+8832, 0)
				rc = int32(m_SQLITE_ERROR)
				goto done
			}
		}
		if hasAuxConstraint != 0 {
			// IMP: V25623_09693
			Xvtab_set_error(tls, pVTab, __ccgo_ts+8916, 0)
			rc = int32(m_SQLITE_ERROR)
			goto done
		}
		libsqlite3.Xsqlite3_str_appendchar(tls, idxStr, int32(1), uint8(_VEC0_QUERY_PLAN_KNN))
		argvIndex = int32(1)
		v2 = argvIndex
		argvIndex = argvIndex + 1
		(**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraintUsage + uintptr(iMatchTerm)*8))).FargvIndex = v2
		(**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraintUsage + uintptr(iMatchTerm)*8))).Fomit = uint8(1)
		libsqlite3.Xsqlite3_str_appendchar(tls, idxStr, int32(1), uint8(_VEC0_IDXSTR_KIND_KNN_MATCH))
		libsqlite3.Xsqlite3_str_appendchar(tls, idxStr, int32(3), uint8('_'))
		if iLimitTerm >= 0 {
			v2 = argvIndex
			argvIndex = argvIndex + 1
			(**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraintUsage + uintptr(iLimitTerm)*8))).FargvIndex = v2
			(**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraintUsage + uintptr(iLimitTerm)*8))).Fomit = uint8(1)
		} else {
			v2 = argvIndex
			argvIndex = argvIndex + 1
			(**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraintUsage + uintptr(iKTerm)*8))).FargvIndex = v2
			(**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraintUsage + uintptr(iKTerm)*8))).Fomit = uint8(1)
		}
		libsqlite3.Xsqlite3_str_appendchar(tls, idxStr, int32(1), uint8(_VEC0_IDXSTR_KIND_KNN_K))
		libsqlite3.Xsqlite3_str_appendchar(tls, idxStr, int32(3), uint8('_'))
		if iRowidInTerm >= 0 {
			// already validated as  >= SQLite 3.38 bc iRowidInTerm is only >= 0 when
			// vtabIn == 1
			libsqlite3.Xsqlite3_vtab_in(tls, pIdxInfo, iRowidInTerm, int32(1))
			v2 = argvIndex
			argvIndex = argvIndex + 1
			(**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraintUsage + uintptr(iRowidInTerm)*8))).FargvIndex = v2
			(**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraintUsage + uintptr(iRowidInTerm)*8))).Fomit = uint8(1)
			libsqlite3.Xsqlite3_str_appendchar(tls, idxStr, int32(1), uint8(_VEC0_IDXSTR_KIND_KNN_ROWID_IN))
			libsqlite3.Xsqlite3_str_appendchar(tls, idxStr, int32(3), uint8('_'))
		}
		// find any PARTITION KEY column constraints
		i1 = 0
		for {
			if !(i1 < (*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FnConstraint) {
				break
			}
			if !((**(**Tsqlite3_index_constraint)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraint + uintptr(i1)*12))).Fusable != 0) {
				goto _6
			}
			iColumn1 = (**(**Tsqlite3_index_constraint)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraint + uintptr(i1)*12))).FiColumn
			op1 = libc.Int32FromUint8((**(**Tsqlite3_index_constraint)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraint + uintptr(i1)*12))).Fop)
			if op1 == int32(m_SQLITE_INDEX_CONSTRAINT_LIMIT) || op1 == int32(m_SQLITE_INDEX_CONSTRAINT_OFFSET) {
				goto _6
			}
			if !(Xvec0_column_idx_is_partition(tls, p, iColumn1) != 0) {
				goto _6
			}
			partition_idx = Xvec0_column_idx_to_partition_idx(tls, p, iColumn1)
			value = uint8(0)
			switch op1 {
			case int32(m_SQLITE_INDEX_CONSTRAINT_EQ):
				value = uint8(_VEC0_PARTITION_OPERATOR_EQ)
			case int32(m_SQLITE_INDEX_CONSTRAINT_GT):
				value = uint8(_VEC0_PARTITION_OPERATOR_GT)
			case int32(m_SQLITE_INDEX_CONSTRAINT_LE):
				value = uint8(_VEC0_PARTITION_OPERATOR_LE)
			case int32(m_SQLITE_INDEX_CONSTRAINT_LT):
				value = uint8(_VEC0_PARTITION_OPERATOR_LT)
			case int32(m_SQLITE_INDEX_CONSTRAINT_GE):
				value = uint8(_VEC0_PARTITION_OPERATOR_GE)
			case int32(m_SQLITE_INDEX_CONSTRAINT_NE):
				value = uint8(_VEC0_PARTITION_OPERATOR_NE)
				break
			}
			if value != 0 {
				v2 = argvIndex
				argvIndex = argvIndex + 1
				(**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraintUsage + uintptr(i1)*8))).FargvIndex = v2
				(**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraintUsage + uintptr(i1)*8))).Fomit = uint8(1)
				libsqlite3.Xsqlite3_str_appendchar(tls, idxStr, int32(1), uint8(_VEC0_IDXSTR_KIND_KNN_PARTITON_CONSTRAINT))
				libsqlite3.Xsqlite3_str_appendchar(tls, idxStr, int32(1), libc.Uint8FromInt32(int32('A')+partition_idx))
				libsqlite3.Xsqlite3_str_appendchar(tls, idxStr, int32(1), value)
				libsqlite3.Xsqlite3_str_appendchar(tls, idxStr, int32(1), uint8('_'))
			}
			goto _6
		_6:
			;
			i1 = i1 + 1
		}
		// find any metadata column constraints
		i2 = 0
		for {
			if !(i2 < (*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FnConstraint) {
				break
			}
			if !((**(**Tsqlite3_index_constraint)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraint + uintptr(i2)*12))).Fusable != 0) {
				goto _8
			}
			iColumn2 = (**(**Tsqlite3_index_constraint)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraint + uintptr(i2)*12))).FiColumn
			op2 = libc.Int32FromUint8((**(**Tsqlite3_index_constraint)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraint + uintptr(i2)*12))).Fop)
			if op2 == int32(m_SQLITE_INDEX_CONSTRAINT_LIMIT) || op2 == int32(m_SQLITE_INDEX_CONSTRAINT_OFFSET) {
				goto _8
			}
			if !(Xvec0_column_idx_is_metadata(tls, p, iColumn2) != 0) {
				goto _8
			}
			metadata_idx = Xvec0_column_idx_to_metadata_idx(tls, p, iColumn2)
			value1 = uint8(0)
			switch op2 {
			case int32(m_SQLITE_INDEX_CONSTRAINT_EQ):
				vtabIn1 = 0
				if libsqlite3.Xsqlite3_libversion_number(tls) >= int32(3038000) {
					vtabIn1 = libsqlite3.Xsqlite3_vtab_in(tls, pIdxInfo, i2, -int32(1))
				}
				if vtabIn1 != 0 {
					switch (**(**TVec0MetadataColumnDefinition)(__ccgo_up(p + 1600 + uintptr(metadata_idx)*24))).Fkind {
					case int32(_VEC0_METADATA_COLUMN_KIND_FLOAT):
						fallthrough
					case int32(_VEC0_METADATA_COLUMN_KIND_BOOLEAN):
						// IMP: V15248_32086
						rc = int32(m_SQLITE_ERROR)
						Xvtab_set_error(tls, pVTab, __ccgo_ts+9000, 0)
						goto done
					case int32(_VEC0_METADATA_COLUMN_KIND_INTEGER):
						fallthrough
					case int32(_VEC0_METADATA_COLUMN_KIND_TEXT):
						break
					}
					value1 = uint8(_VEC0_METADATA_OPERATOR_IN)
					libsqlite3.Xsqlite3_vtab_in(tls, pIdxInfo, i2, int32(1))
				} else {
					value1 = uint8(_VEC0_PARTITION_OPERATOR_EQ)
				}
			case int32(m_SQLITE_INDEX_CONSTRAINT_GT):
				value1 = uint8(_VEC0_METADATA_OPERATOR_GT)
			case int32(m_SQLITE_INDEX_CONSTRAINT_LE):
				value1 = uint8(_VEC0_METADATA_OPERATOR_LE)
			case int32(m_SQLITE_INDEX_CONSTRAINT_LT):
				value1 = uint8(_VEC0_METADATA_OPERATOR_LT)
			case int32(m_SQLITE_INDEX_CONSTRAINT_GE):
				value1 = uint8(_VEC0_METADATA_OPERATOR_GE)
			case int32(m_SQLITE_INDEX_CONSTRAINT_NE):
				value1 = uint8(_VEC0_METADATA_OPERATOR_NE)
			default:
				// IMP: V16511_00582
				rc = int32(m_SQLITE_ERROR)
				Xvtab_set_error(tls, pVTab, __ccgo_ts+9070, 0)
				goto done
			}
			if (**(**TVec0MetadataColumnDefinition)(__ccgo_up(p + 1600 + uintptr(metadata_idx)*24))).Fkind == int32(_VEC0_METADATA_COLUMN_KIND_BOOLEAN) {
				if !(libc.Int32FromUint8(value1) == int32(_VEC0_METADATA_OPERATOR_EQ) || libc.Int32FromUint8(value1) == int32(_VEC0_METADATA_OPERATOR_NE)) {
					// IMP: V10145_26984
					rc = int32(m_SQLITE_ERROR)
					Xvtab_set_error(tls, pVTab, __ccgo_ts+9264, 0)
					goto done
				}
			}
			v2 = argvIndex
			argvIndex = argvIndex + 1
			(**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraintUsage + uintptr(i2)*8))).FargvIndex = v2
			(**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraintUsage + uintptr(i2)*8))).Fomit = uint8(1)
			libsqlite3.Xsqlite3_str_appendchar(tls, idxStr, int32(1), uint8(_VEC0_IDXSTR_KIND_METADATA_CONSTRAINT))
			libsqlite3.Xsqlite3_str_appendchar(tls, idxStr, int32(1), libc.Uint8FromInt32(int32('A')+metadata_idx))
			libsqlite3.Xsqlite3_str_appendchar(tls, idxStr, int32(1), value1)
			libsqlite3.Xsqlite3_str_appendchar(tls, idxStr, int32(1), uint8('_'))
			goto _8
		_8:
			;
			i2 = i2 + 1
		}
		// find any distance column constraints
		i3 = 0
		for {
			if !(i3 < (*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FnConstraint) {
				break
			}
			if !((**(**Tsqlite3_index_constraint)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraint + uintptr(i3)*12))).Fusable != 0) {
				goto _10
			}
			iColumn3 = (**(**Tsqlite3_index_constraint)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraint + uintptr(i3)*12))).FiColumn
			op3 = libc.Int32FromUint8((**(**Tsqlite3_index_constraint)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraint + uintptr(i3)*12))).Fop)
			if op3 == int32(m_SQLITE_INDEX_CONSTRAINT_LIMIT) || op3 == int32(m_SQLITE_INDEX_CONSTRAINT_OFFSET) {
				goto _10
			}
			if Xvec0_column_distance_idx(tls, p) != iColumn3 {
				goto _10
			}
			value2 = uint8(0)
			switch op3 {
			case int32(m_SQLITE_INDEX_CONSTRAINT_GT):
				value2 = uint8(_VEC0_DISTANCE_CONSTRAINT_GT)
			case int32(m_SQLITE_INDEX_CONSTRAINT_GE):
				value2 = uint8(_VEC0_DISTANCE_CONSTRAINT_GE)
			case int32(m_SQLITE_INDEX_CONSTRAINT_LT):
				value2 = uint8(_VEC0_DISTANCE_CONSTRAINT_LT)
			case int32(m_SQLITE_INDEX_CONSTRAINT_LE):
				value2 = uint8(_VEC0_DISTANCE_CONSTRAINT_LE)
			default:
				// IMP TODO
				rc = int32(m_SQLITE_ERROR)
				Xvtab_set_error(tls, pVTab, __ccgo_ts+9350, 0)
				goto done
			}
			v2 = argvIndex
			argvIndex = argvIndex + 1
			(**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraintUsage + uintptr(i3)*8))).FargvIndex = v2
			(**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraintUsage + uintptr(i3)*8))).Fomit = uint8(1)
			libsqlite3.Xsqlite3_str_appendchar(tls, idxStr, int32(1), uint8(_VEC0_IDXSTR_KIND_KNN_DISTANCE_CONSTRAINT))
			libsqlite3.Xsqlite3_str_appendchar(tls, idxStr, int32(1), value2)
			libsqlite3.Xsqlite3_str_appendchar(tls, idxStr, int32(1), uint8('_'))
			libsqlite3.Xsqlite3_str_appendchar(tls, idxStr, int32(1), uint8('_'))
			goto _10
		_10:
			;
			i3 = i3 + 1
		}
		(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FidxNum = iMatchVectorTerm
		(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FestimatedCost = float64(30)
		(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FestimatedRows = int64(10)
	} else {
		if iRowidTerm >= 0 {
			libsqlite3.Xsqlite3_str_appendchar(tls, idxStr, int32(1), uint8(_VEC0_QUERY_PLAN_POINT))
			(**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraintUsage + uintptr(iRowidTerm)*8))).FargvIndex = int32(1)
			(**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraintUsage + uintptr(iRowidTerm)*8))).Fomit = uint8(1)
			libsqlite3.Xsqlite3_str_appendchar(tls, idxStr, int32(1), uint8(_VEC0_IDXSTR_KIND_POINT_ID))
			libsqlite3.Xsqlite3_str_appendchar(tls, idxStr, int32(3), uint8('_'))
			(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FidxNum = libc.Int32FromUint64((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FcolUsed)
			(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FestimatedCost = float64(10)
			(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FestimatedRows = int64(1)
		} else {
			libsqlite3.Xsqlite3_str_appendchar(tls, idxStr, int32(1), uint8(_VEC0_QUERY_PLAN_FULLSCAN))
			(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FestimatedCost = float64(3e+06)
			(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FestimatedRows = int64(100000)
		}
	}
	(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FidxStr = libsqlite3.Xsqlite3_str_finish(tls, idxStr)
	idxStr = libc.UintptrFromInt32(0)
	if !((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FidxStr != 0) {
		rc = m_SQLITE_OK
		goto done
	}
	(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FneedToFreeIdxStr = int32(1)
	rc = m_SQLITE_OK
	goto done
done:
	;
	if idxStr != 0 {
		libsqlite3.Xsqlite3_str_finish(tls, idxStr)
	}
	return rc
}

func _vec0Filter(tls *libc.TLS, pVtabCursor uintptr, idxNum int32, idxStr uintptr, argc int32, argv uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var idxStrLength, numValueEntries int32
	var p, pCur uintptr
	var query_plan uint8
	_, _, _, _, _ = idxStrLength, numValueEntries, p, pCur, query_plan
	p = (*Tsqlite3_vtab_cursor)(unsafe.Pointer(pVtabCursor)).FpVtab
	pCur = pVtabCursor
	Xvec0_cursor_clear(tls, pCur)
	idxStrLength = libc.Int32FromUint64(libc.Xstrlen(tls, idxStr))
	if idxStrLength <= 0 {
		return int32(m_SQLITE_ERROR)
	}
	if (idxStrLength-int32(1))%int32(4) != 0 {
		return int32(m_SQLITE_ERROR)
	}
	numValueEntries = (idxStrLength - int32(1)) / int32(4)
	if numValueEntries != argc {
		return int32(m_SQLITE_ERROR)
	}
	query_plan = **(**uint8)(__ccgo_up(idxStr))
	switch libc.Int32FromUint8(query_plan) {
	case int32(_VEC0_QUERY_PLAN_FULLSCAN):
		return Xvec0Filter_fullscan(tls, p, pCur)
	case int32(_VEC0_QUERY_PLAN_KNN):
		return Xvec0Filter_knn(tls, pCur, p, idxNum, idxStr, argc, argv)
	case int32(_VEC0_QUERY_PLAN_POINT):
		return Xvec0Filter_point(tls, pCur, p, argc, argv)
	default:
		Xvtab_set_error(tls, (*Tsqlite3_vtab_cursor)(unsafe.Pointer(pVtabCursor)).FpVtab, __ccgo_ts+10745, libc.VaList(bp+8, idxStr))
		return int32(m_SQLITE_ERROR)
	}
	return r
}
