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

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

package vec

import (
	"unsafe"

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

type Tfloat_t = float64

func Xvec0Filter_knn(tls *libc.TLS, pCur uintptr, p uintptr, idxNum int32, idxStr uintptr, argc int32, argv uintptr) (r int32) {
	bp := tls.Alloc(160)
	defer tls.Free(160)
	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+8 */ Tsize_t
	var _ /* elementType at bp+12 */ _VectorElementType
	var _ /* entry at bp+64 */ uintptr
	var _ /* entry at bp+80 */ uintptr
	var _ /* entry at bp+88 */ TVec0MetadataInTextEntry
	var _ /* item at bp+24 */ uintptr
	var _ /* item at bp+40 */ TVec0MetadataIn
	var _ /* k_used at bp+104 */ Ti64
	var _ /* pzError at bp+20 */ uintptr
	var _ /* queryVector at bp+4 */ uintptr
	var _ /* queryVectorCleanup at bp+16 */ Tvector_cleanup
	var _ /* rowid at bp+32 */ Ti64
	var _ /* stmtChunks at bp+0 */ uintptr
	var _ /* topk_distances at bp+100 */ uintptr
	var _ /* topk_rowids at bp+96 */ uintptr
	var _ /* v at bp+72 */ 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 + 440 + uintptr(vectorColumnIdx)*20
	arrayRowidsIn = libc.UintptrFromInt32(0)
	**(**uintptr)(__ccgo_up(bp)) = libc.UintptrFromInt32(0)
	**(**Tvector_cleanup)(__ccgo_up(bp + 16)) = __ccgo_fp(Xvector_cleanup_noop)
	knn_data = libsqlite3.Xsqlite3_malloc(tls, int32(32))
	if !(knn_data != 0) {
		return int32(m_SQLITE_NOMEM)
	}
	libc.Xmemset(tls, knn_data, 0, uint32(32))
	// 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 int32(**(**int8)(__ccgo_up(idxStr + uintptr(int32(1)+i*int32(4))))) == int32(_VEC0_IDXSTR_KIND_KNN_MATCH) {
			query_idx = i
		}
		if int32(**(**int8)(__ccgo_up(idxStr + uintptr(int32(1)+i*int32(4))))) == int32(_VEC0_IDXSTR_KIND_KNN_K) {
			k_idx = i
		}
		if int32(**(**int8)(__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)*4)), bp+4, bp+8, bp+12, bp+16, bp+20)
	if rc != m_SQLITE_OK {
		Xvtab_set_error(tls, p, __ccgo_ts+10061, libc.VaList(bp+120, (*TVectorColumnDefinition)(unsafe.Pointer(vector_column)).Fname_length, (*TVectorColumnDefinition)(unsafe.Pointer(vector_column)).Fname, **(**uintptr)(__ccgo_up(bp + 20))))
		rc = int32(m_SQLITE_ERROR)
		goto cleanup
	}
	if **(**_VectorElementType)(__ccgo_up(bp + 12)) != (*TVectorColumnDefinition)(unsafe.Pointer(vector_column)).Felement_type {
		Xvtab_set_error(tls, p, __ccgo_ts+10110, libc.VaList(bp+120, (*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 + 12)))))
		rc = int32(m_SQLITE_ERROR)
		goto cleanup
	}
	if **(**Tsize_t)(__ccgo_up(bp + 8)) != (*TVectorColumnDefinition)(unsafe.Pointer(vector_column)).Fdimensions {
		Xvtab_set_error(tls, p, __ccgo_ts+10205, libc.VaList(bp+120, (*TVectorColumnDefinition)(unsafe.Pointer(vector_column)).Fname_length, (*TVectorColumnDefinition)(unsafe.Pointer(vector_column)).Fname, (*TVectorColumnDefinition)(unsafe.Pointer(vector_column)).Fdimensions, **(**Tsize_t)(__ccgo_up(bp + 8))))
		rc = int32(m_SQLITE_ERROR)
		goto cleanup
	}
	k = libsqlite3.Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(argv + uintptr(k_idx)*4)))
	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+120, 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(16))
		if !(arrayRowidsIn != 0) {
			rc1 = int32(m_SQLITE_NOMEM)
			goto cleanup
		}
		libc.Xmemset(tls, arrayRowidsIn, 0, uint32(16))
		rc1 = Xarray_init(tls, arrayRowidsIn, uint32(8), uint32(32))
		if rc1 != m_SQLITE_OK {
			goto cleanup
		}
		rc1 = libsqlite3.Xsqlite3_vtab_in_first(tls, **(**uintptr)(__ccgo_up(argv + uintptr(rowid_in_idx)*4)), bp+24)
		for {
			if !(rc1 == m_SQLITE_OK && **(**uintptr)(__ccgo_up(bp + 24)) != 0) {
				break
			}
			if (*Tvec0_vtab)(unsafe.Pointer(p)).FpkIsText != 0 {
				rc1 = Xvec0_rowid_from_id(tls, p, **(**uintptr)(__ccgo_up(bp + 24)), bp+32)
				if rc1 != m_SQLITE_OK {
					goto cleanup
				}
			} else {
				**(**Ti64)(__ccgo_up(bp + 32)) = libsqlite3.Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(bp + 24)))
			}
			rc1 = Xarray_append(tls, arrayRowidsIn, bp+32)
			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)*4)), bp+24)
		}
		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 !(int32(**(**int8)(__ccgo_up(idxStr + uintptr(int32(1)+i1*int32(4))))) == int32(_VEC0_IDXSTR_KIND_METADATA_CONSTRAINT) && int32(**(**int8)(__ccgo_up(idxStr + uintptr(int32(1)+i1*int32(4)+int32(2))))) == int32(_VEC0_METADATA_OPERATOR_IN)) {
			goto _3
		}
		metadata_idx = int32(**(**int8)(__ccgo_up(idxStr + uintptr(int32(1)+i1*int32(4)+int32(1))))) - int32('A')
		if !(aMetadataIn != 0) {
			aMetadataIn = libsqlite3.Xsqlite3_malloc(tls, int32(16))
			if !(aMetadataIn != 0) {
				rc = int32(m_SQLITE_NOMEM)
				goto cleanup
			}
			libc.Xmemset(tls, aMetadataIn, 0, uint32(16))
			rc = Xarray_init(tls, aMetadataIn, uint32(24), uint32(8))
			if rc != m_SQLITE_OK {
				goto cleanup
			}
		}
		libc.Xmemset(tls, bp+40, 0, uint32(24))
		(**(**TVec0MetadataIn)(__ccgo_up(bp + 40))).Fmetadata_idx = metadata_idx
		(**(**TVec0MetadataIn)(__ccgo_up(bp + 40))).Fargv_idx = i1
		switch (**(**TVec0MetadataColumnDefinition)(__ccgo_up(p + 1000 + uintptr(metadata_idx)*12))).Fkind {
		case int32(_VEC0_METADATA_COLUMN_KIND_INTEGER):
			rc = Xarray_init(tls, bp+40+8, uint32(8), uint32(16))
			if rc != m_SQLITE_OK {
				goto cleanup
			}
			rc = libsqlite3.Xsqlite3_vtab_in_first(tls, **(**uintptr)(__ccgo_up(argv + uintptr(i1)*4)), bp+64)
			for {
				if !(rc == m_SQLITE_OK && **(**uintptr)(__ccgo_up(bp + 64)) != 0) {
					break
				}
				**(**Ti64)(__ccgo_up(bp + 72)) = libsqlite3.Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(bp + 64)))
				rc = Xarray_append(tls, bp+40+8, bp+72)
				if rc != m_SQLITE_OK {
					goto cleanup
				}
				goto _4
			_4:
				;
				rc = libsqlite3.Xsqlite3_vtab_in_next(tls, **(**uintptr)(__ccgo_up(argv + uintptr(i1)*4)), bp+64)
			}
			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+40+8, uint32(8), uint32(16))
			if rc != m_SQLITE_OK {
				goto cleanup
			}
			rc = libsqlite3.Xsqlite3_vtab_in_first(tls, **(**uintptr)(__ccgo_up(argv + uintptr(i1)*4)), bp+80)
			for {
				if !(rc == m_SQLITE_OK && **(**uintptr)(__ccgo_up(bp + 80)) != 0) {
					break
				}
				s = libsqlite3.Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(bp + 80)))
				n = libsqlite3.Xsqlite3_value_bytes(tls, **(**uintptr)(__ccgo_up(bp + 80)))
				(**(**TVec0MetadataInTextEntry)(__ccgo_up(bp + 88))).FzString = libsqlite3.Xsqlite3_mprintf(tls, __ccgo_ts+1874, libc.VaList(bp+120, n, s))
				if !((**(**TVec0MetadataInTextEntry)(__ccgo_up(bp + 88))).FzString != 0) {
					rc = int32(m_SQLITE_NOMEM)
					goto cleanup
				}
				(**(**TVec0MetadataInTextEntry)(__ccgo_up(bp + 88))).Fn = n
				rc = Xarray_append(tls, bp+40+8, bp+88)
				if rc != m_SQLITE_OK {
					goto cleanup
				}
				goto _5
			_5:
				;
				rc = libsqlite3.Xsqlite3_vtab_in_next(tls, **(**uintptr)(__ccgo_up(argv + uintptr(i1)*4)), bp+80)
			}
			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+40)
		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+120, libsqlite3.Xsqlite3_errmsg(tls, (*Tvec0_vtab)(unsafe.Pointer(p)).Fdb)))
		goto cleanup
	}
	**(**uintptr)(__ccgo_up(bp + 96)) = libc.UintptrFromInt32(0)
	**(**uintptr)(__ccgo_up(bp + 100)) = libc.UintptrFromInt32(0)
	**(**Ti64)(__ccgo_up(bp + 104)) = 0
	rc = Xvec0Filter_knn_chunks_iter(tls, p, **(**uintptr)(__ccgo_up(bp)), vector_column, vectorColumnIdx, arrayRowidsIn, aMetadataIn, idxStr, argc, argv, **(**uintptr)(__ccgo_up(bp + 4)), k, bp+96, bp+100, bp+104)
	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 + 96))
	(*Tvec0_query_knn_data)(unsafe.Pointer(knn_data)).Fdistances = **(**uintptr)(__ccgo_up(bp + 100))
	(*Tvec0_query_knn_data)(unsafe.Pointer(knn_data)).Fk_used = **(**Ti64)(__ccgo_up(bp + 104))
	(*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 + 16)))(tls, **(**uintptr)(__ccgo_up(bp + 4)))
	if aMetadataIn != 0 {
		i2 = uint32(0)
		for {
			if !(i2 < (*TArray)(unsafe.Pointer(aMetadataIn)).Flength) {
				break
			}
			item2 = (*TArray)(unsafe.Pointer(aMetadataIn)).Fz + uintptr(i2)*24
			j = uint32(0)
			for {
				if !(j < (*TVec0MetadataIn)(unsafe.Pointer(item2)).Farray.Flength) {
					break
				}
				if (**(**TVec0MetadataColumnDefinition)(__ccgo_up(p + 1000 + uintptr((*TVec0MetadataIn)(unsafe.Pointer(item2)).Fmetadata_idx)*12))).Fkind == int32(_VEC0_METADATA_COLUMN_KIND_TEXT) {
					entry3 = **(**TVec0MetadataInTextEntry)(__ccgo_up((*TVec0MetadataIn)(unsafe.Pointer(item2)).Farray.Fz + uintptr(j)*8))
					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
}

const m___i386 = 1

const m___i386__ = 1

const m___i686 = 1

const m___i686__ = 1

const m___pentiumpro = 1

const m___pentiumpro__ = 1

const m_i386 = 1
