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

//go:build (darwin && amd64) || (darwin && arm64) || (linux && 386) || (linux && amd64) || (linux && arm) || (linux && arm64) || (linux && ppc64le) || (linux && riscv64) || (linux && s390x)

package sqlite3

import (
	"unsafe"

	"modernc.org/libc"
)

// C documentation
//
//	/*
//	** Move an existing blob handle to point to a different row of the same
//	** database table.
//	**
//	** If an error occurs, or if the specified row does not exist or does not
//	** contain a blob or text value, then an error code is returned and the
//	** database handle error code and message set. If this happens, then all
//	** subsequent calls to sqlite3_blob_xxx() functions (except blob_close())
//	** immediately return SQLITE_ABORT.
//	*/
func Xsqlite3_blob_reopen(tls *libc.TLS, pBlob uintptr, iRow Tsqlite3_int64) (r int32) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var db, p, v1 uintptr
	var rc int32
	var _ /* zErr at bp+0 */ uintptr
	_, _, _, _ = db, p, rc, v1
	p = pBlob
	if p == uintptr(0) {
		return _sqlite3MisuseError(tls, int32(106369))
	}
	db = (*TIncrblob)(unsafe.Pointer(p)).Fdb
	Xsqlite3_mutex_enter(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
	if (*TIncrblob)(unsafe.Pointer(p)).FpStmt == uintptr(0) {
		/* If there is no statement handle, then the blob-handle has
		 ** already been invalidated. Return SQLITE_ABORT in this case.
		 */
		rc = int32(SQLITE_ABORT)
	} else {
		(*TVdbe)(unsafe.Pointer((*TIncrblob)(unsafe.Pointer(p)).FpStmt)).Frc = SQLITE_OK
		rc = _blobSeekToRow(tls, p, iRow, bp)
		if rc != SQLITE_OK {
			if **(**uintptr)(__ccgo_up(bp)) != 0 {
				v1 = __ccgo_ts + 3944
			} else {
				v1 = libc.UintptrFromInt32(0)
			}
			_sqlite3ErrorWithMsg(tls, db, rc, v1, libc.VaList(bp+16, **(**uintptr)(__ccgo_up(bp))))
			_sqlite3DbFree(tls, db, **(**uintptr)(__ccgo_up(bp)))
		}
	}
	rc = _sqlite3ApiExit(tls, db, rc)
	Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
	return rc
}

/************** End of vdbeblob.c ********************************************/
/************** Begin file vdbesort.c ****************************************/
/*
** 2011-07-09
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code for the VdbeSorter object, used in concert with
** a VdbeCursor to sort large numbers of keys for CREATE INDEX statements
** or by SELECT statements with ORDER BY clauses that cannot be satisfied
** using indexes and without LIMIT clauses.
**
** The VdbeSorter object implements a multi-threaded external merge sort
** algorithm that is efficient even if the number of elements being sorted
** exceeds the available memory.
**
** Here is the (internal, non-API) interface between this module and the
** rest of the SQLite system:
**
**    sqlite3VdbeSorterInit()       Create a new VdbeSorter object.
**
**    sqlite3VdbeSorterWrite()      Add a single new row to the VdbeSorter
**                                  object.  The row is a binary blob in the
**                                  OP_MakeRecord format that contains both
**                                  the ORDER BY key columns and result columns
**                                  in the case of a SELECT w/ ORDER BY, or
**                                  the complete record for an index entry
**                                  in the case of a CREATE INDEX.
**
**    sqlite3VdbeSorterRewind()     Sort all content previously added.
**                                  Position the read cursor on the
**                                  first sorted element.
**
**    sqlite3VdbeSorterNext()       Advance the read cursor to the next sorted
**                                  element.
**
**    sqlite3VdbeSorterRowkey()     Return the complete binary blob for the
**                                  row currently under the read cursor.
**
**    sqlite3VdbeSorterCompare()    Compare the binary blob for the row
**                                  currently under the read cursor against
**                                  another binary blob X and report if
**                                  X is strictly less than the read cursor.
**                                  Used to enforce uniqueness in a
**                                  CREATE UNIQUE INDEX statement.
**
**    sqlite3VdbeSorterClose()      Close the VdbeSorter object and reclaim
**                                  all resources.
**
**    sqlite3VdbeSorterReset()      Refurbish the VdbeSorter for reuse.  This
**                                  is like Close() followed by Init() only
**                                  much faster.
**
** The interfaces above must be called in a particular order.  Write() can
** only occur in between Init()/Reset() and Rewind().  Next(), Rowkey(), and
** Compare() can only occur in between Rewind() and Close()/Reset(). i.e.
**
**   Init()
**   for each record: Write()
**   Rewind()
**     Rowkey()/Compare()
**   Next()
**   Close()
**
** Algorithm:
**
** Records passed to the sorter via calls to Write() are initially held
** unsorted in main memory. Assuming the amount of memory used never exceeds
** a threshold, when Rewind() is called the set of records is sorted using
** an in-memory merge sort. In this case, no temporary files are required
** and subsequent calls to Rowkey(), Next() and Compare() read records
** directly from main memory.
**
** If the amount of space used to store records in main memory exceeds the
** threshold, then the set of records currently in memory are sorted and
** written to a temporary file in "Packed Memory Array" (PMA) format.
** A PMA created at this point is known as a "level-0 PMA". Higher levels
** of PMAs may be created by merging existing PMAs together - for example
** merging two or more level-0 PMAs together creates a level-1 PMA.
**
** The threshold for the amount of main memory to use before flushing
** records to a PMA is roughly the same as the limit configured for the
** page-cache of the main database. Specifically, the threshold is set to
** the value returned by "PRAGMA main.page_size" multiplied by
** that returned by "PRAGMA main.cache_size", in bytes.
**
** If the sorter is running in single-threaded mode, then all PMAs generated
** are appended to a single temporary file. Or, if the sorter is running in
** multi-threaded mode then up to (N+1) temporary files may be opened, where
** N is the configured number of worker threads. In this case, instead of
** sorting the records and writing the PMA to a temporary file itself, the
** calling thread usually launches a worker thread to do so. Except, if
** there are already N worker threads running, the main thread does the work
** itself.
**
** The sorter is running in multi-threaded mode if (a) the library was built
** with pre-processor symbol SQLITE_MAX_WORKER_THREADS set to a value greater
** than zero, and (b) worker threads have been enabled at runtime by calling
** "PRAGMA threads=N" with some value of N greater than 0.
**
** When Rewind() is called, any data remaining in memory is flushed to a
** final PMA. So at this point the data is stored in some number of sorted
** PMAs within temporary files on disk.
**
** If there are fewer than SORTER_MAX_MERGE_COUNT PMAs in total and the
** sorter is running in single-threaded mode, then these PMAs are merged
** incrementally as keys are retrieved from the sorter by the VDBE.  The
** MergeEngine object, described in further detail below, performs this
** merge.
**
** Or, if running in multi-threaded mode, then a background thread is
** launched to merge the existing PMAs. Once the background thread has
** merged T bytes of data into a single sorted PMA, the main thread
** begins reading keys from that PMA while the background thread proceeds
** with merging the next T bytes of data. And so on.
**
** Parameter T is set to half the value of the memory threshold used
** by Write() above to determine when to create a new PMA.
**
** If there are more than SORTER_MAX_MERGE_COUNT PMAs in total when
** Rewind() is called, then a hierarchy of incremental-merges is used.
** First, T bytes of data from the first SORTER_MAX_MERGE_COUNT PMAs on
** disk are merged together. Then T bytes of data from the second set, and
** so on, such that no operation ever merges more than SORTER_MAX_MERGE_COUNT
** PMAs at a time. This done is to improve locality.
**
** If running in multi-threaded mode and there are more than
** SORTER_MAX_MERGE_COUNT PMAs on disk when Rewind() is called, then more
** than one background thread may be created. Specifically, there may be
** one background thread for each temporary file on disk, and one background
** thread to merge the output of each of the others to a single PMA for
** the main thread to read from.
 */
/* #include "sqliteInt.h" */
/* #include "vdbeInt.h" */

/*
** If SQLITE_DEBUG_SORTER_THREADS is defined, this module outputs various
** messages to stderr that may be helpful in understanding the performance
** characteristics of the sorter in multi-threaded mode.
 */

/*
** Hard-coded maximum amount of data to accumulate in memory before flushing
** to a level 0 PMA. The purpose of this limit is to prevent various integer
** overflows. 512MiB.
 */

// C documentation
//
//	/*
//	** Declare that a function has been overloaded by a virtual table.
//	**
//	** If the function already exists as a regular global function, then
//	** this routine is a no-op.  If the function does not exist, then create
//	** a new one that always throws a run-time error.
//	**
//	** When virtual tables intend to provide an overloaded function, they
//	** should call this routine to make sure the global function exists.
//	** A global function must exist in order for name resolution to work
//	** properly.
//	*/
func Xsqlite3_overload_function(tls *libc.TLS, db uintptr, zName uintptr, nArg int32) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var rc int32
	var zCopy uintptr
	_, _ = rc, zCopy
	Xsqlite3_mutex_enter(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
	rc = libc.BoolInt32(_sqlite3FindFunction(tls, db, zName, nArg, uint8(SQLITE_UTF8), uint8(0)) != uintptr(0))
	Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
	if rc != 0 {
		return SQLITE_OK
	}
	zCopy = Xsqlite3_mprintf(tls, __ccgo_ts+3944, libc.VaList(bp+8, zName))
	if zCopy == uintptr(0) {
		return int32(SQLITE_NOMEM)
	}
	return Xsqlite3_create_function_v2(tls, db, zName, nArg, int32(SQLITE_UTF8), zCopy, __ccgo_fp(_sqlite3InvalidFunction), uintptr(0), uintptr(0), __ccgo_fp(Xsqlite3_free))
}

// C documentation
//
//	/*
//	** Set the error code and error message associated with the database handle.
//	**
//	** This routine is intended to be called by outside extensions (ex: the
//	** Session extension). Internal logic should invoke sqlite3Error() or
//	** sqlite3ErrorWithMsg() directly.
//	*/
func Xsqlite3_set_errmsg(tls *libc.TLS, db uintptr, errcode int32, zMsg uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var rc int32
	_ = rc
	rc = SQLITE_OK
	if !(_sqlite3SafetyCheckOk(tls, db) != 0) {
		return _sqlite3MisuseError(tls, int32(189943))
	}
	Xsqlite3_mutex_enter(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
	if zMsg != 0 {
		_sqlite3ErrorWithMsg(tls, db, errcode, __ccgo_ts+3944, libc.VaList(bp+8, zMsg))
	} else {
		_sqlite3Error(tls, db, errcode)
	}
	rc = _sqlite3ApiExit(tls, db, rc)
	Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
	return rc
}

// C documentation
//
//	/*
//	** Provide a database schema to the changegroup object.
//	*/
func Xsqlite3changegroup_schema(tls *libc.TLS, pGrp uintptr, db uintptr, zDb uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var rc int32
	_ = rc
	rc = SQLITE_OK
	if (*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).FpList != 0 || (*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fdb != 0 {
		/* Cannot add a schema after one or more calls to sqlite3changegroup_add(),
		 ** or after sqlite3changegroup_schema() has already been called. */
		rc = int32(SQLITE_MISUSE)
	} else {
		(*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).FzDb = Xsqlite3_mprintf(tls, __ccgo_ts+3944, libc.VaList(bp+8, zDb))
		if (*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).FzDb == uintptr(0) {
			rc = int32(SQLITE_NOMEM)
		} else {
			(*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fdb = db
		}
	}
	return rc
}

func _fts5PrepareStatement(tls *libc.TLS, ppStmt uintptr, pConfig uintptr, zFmt uintptr, va uintptr) (r int32) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var ap Tva_list
	var rc int32
	var zSql uintptr
	var _ /* pRet at bp+0 */ uintptr
	_, _, _ = ap, rc, zSql
	**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
	ap = va
	zSql = Xsqlite3_vmprintf(tls, zFmt, ap)
	if zSql == uintptr(0) {
		rc = int32(SQLITE_NOMEM)
	} else {
		rc = Xsqlite3_prepare_v3(tls, (*TFts5Config)(unsafe.Pointer(pConfig)).Fdb, zSql, -int32(1), uint32(SQLITE_PREPARE_PERSISTENT), bp, uintptr(0))
		if rc != SQLITE_OK {
			_sqlite3Fts5ConfigErrmsg(tls, pConfig, __ccgo_ts+3944, libc.VaList(bp+16, Xsqlite3_errmsg(tls, (*TFts5Config)(unsafe.Pointer(pConfig)).Fdb)))
		}
		Xsqlite3_free(tls, zSql)
	}
	_ = ap
	**(**uintptr)(__ccgo_up(ppStmt)) = **(**uintptr)(__ccgo_up(bp))
	return rc
}

// C documentation
//
//	/*
//	** Populate buffer zOut with the full canonical pathname corresponding
//	** to the pathname in zPath. zOut is guaranteed to point to a buffer
//	** of at least (INST_MAX_PATHNAME+1) bytes.
//	*/
func _memdbFullPathname(tls *libc.TLS, pVfs uintptr, zPath uintptr, nOut int32, zOut uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	_ = pVfs
	Xsqlite3_snprintf(tls, nOut, zOut, __ccgo_ts+3944, libc.VaList(bp+8, zPath))
	return SQLITE_OK
}

// C documentation
//
//	/*
//	** Prepare the SQL statement in buffer zSql against database handle db.
//	** If successful, set *ppStmt to point to the new statement and return
//	** SQLITE_OK.
//	**
//	** Otherwise, if an error does occur, set *ppStmt to NULL and return
//	** an SQLite error code. Additionally, set output variable *pzErrmsg to
//	** point to a buffer containing an error message. It is the responsibility
//	** of the caller to (eventually) free this buffer using sqlite3_free().
//	*/
func _prepareAndCollectError(tls *libc.TLS, db uintptr, ppStmt uintptr, pzErrmsg uintptr, zSql uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var rc int32
	_ = rc
	rc = Xsqlite3_prepare_v2(tls, db, zSql, -int32(1), ppStmt, uintptr(0))
	if rc != SQLITE_OK {
		**(**uintptr)(__ccgo_up(pzErrmsg)) = Xsqlite3_mprintf(tls, __ccgo_ts+3944, libc.VaList(bp+8, Xsqlite3_errmsg(tls, db)))
		**(**uintptr)(__ccgo_up(ppStmt)) = uintptr(0)
	}
	return rc
}

// C documentation
//
//	/*
//	** Finalize the statement passed as the second argument.
//	**
//	** If the sqlite3_finalize() call indicates that an error occurs, and the
//	** rbu handle error code is not already set, set the error code and error
//	** message accordingly.
//	*/
func _rbuFinalize(tls *libc.TLS, p uintptr, pStmt uintptr) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var db uintptr
	var rc int32
	_, _ = db, rc
	db = Xsqlite3_db_handle(tls, pStmt)
	rc = Xsqlite3_finalize(tls, pStmt)
	if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK && rc != SQLITE_OK {
		(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = rc
		(*Tsqlite3rbu)(unsafe.Pointer(p)).FzErrmsg = Xsqlite3_mprintf(tls, __ccgo_ts+3944, libc.VaList(bp+8, Xsqlite3_errmsg(tls, db)))
	}
}

func _rbuOpenDbhandle(tls *libc.TLS, p uintptr, zName uintptr, bUseVfs int32) (r uintptr) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var flags int32
	var v1 uintptr
	var _ /* db at bp+0 */ uintptr
	_, _ = flags, v1
	**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
	if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
		flags = libc.Int32FromInt32(SQLITE_OPEN_READWRITE) | libc.Int32FromInt32(SQLITE_OPEN_CREATE) | libc.Int32FromInt32(SQLITE_OPEN_URI)
		if bUseVfs != 0 {
			v1 = (*Tsqlite3rbu)(unsafe.Pointer(p)).FzVfsName
		} else {
			v1 = uintptr(0)
		}
		(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = Xsqlite3_open_v2(tls, zName, bp, flags, v1)
		if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc != 0 {
			(*Tsqlite3rbu)(unsafe.Pointer(p)).FzErrmsg = Xsqlite3_mprintf(tls, __ccgo_ts+3944, libc.VaList(bp+16, Xsqlite3_errmsg(tls, **(**uintptr)(__ccgo_up(bp)))))
			Xsqlite3_close(tls, **(**uintptr)(__ccgo_up(bp)))
			**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
		}
	}
	return **(**uintptr)(__ccgo_up(bp))
}

// C documentation
//
//	/*
//	** Reset the SQL statement passed as the first argument. Return a copy
//	** of the value returned by sqlite3_reset().
//	**
//	** If an error has occurred, then set *pzErrmsg to point to a buffer
//	** containing an error message. It is the responsibility of the caller
//	** to eventually free this buffer using sqlite3_free().
//	*/
func _resetAndCollectError(tls *libc.TLS, pStmt uintptr, pzErrmsg uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var rc int32
	_ = rc
	rc = Xsqlite3_reset(tls, pStmt)
	if rc != SQLITE_OK {
		**(**uintptr)(__ccgo_up(pzErrmsg)) = Xsqlite3_mprintf(tls, __ccgo_ts+3944, libc.VaList(bp+8, Xsqlite3_errmsg(tls, Xsqlite3_db_handle(tls, pStmt))))
	}
	return rc
}

func _sessionPrepare(tls *libc.TLS, db uintptr, pp uintptr, pzErrmsg uintptr, zSql uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var rc int32
	_ = rc
	rc = Xsqlite3_prepare_v2(tls, db, zSql, -int32(1), pp, uintptr(0))
	if pzErrmsg != 0 && rc != SQLITE_OK {
		**(**uintptr)(__ccgo_up(pzErrmsg)) = Xsqlite3_mprintf(tls, __ccgo_ts+3944, libc.VaList(bp+8, Xsqlite3_errmsg(tls, db)))
	}
	return rc
}

// C documentation
//
//	/*
//	** SQLite calls this function immediately after a call to unixDlSym() or
//	** unixDlOpen() fails (returns a null pointer). If a more detailed error
//	** message is available, it is written to zBufOut. If no error message
//	** is available, zBufOut is left unmodified and SQLite uses a default
//	** error message.
//	*/
func _unixDlError(tls *libc.TLS, NotUsed uintptr, nBuf int32, zBufOut uintptr) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var zErr uintptr
	_ = zErr
	_ = NotUsed
	_unixEnterMutex(tls)
	zErr = libc.Xdlerror(tls)
	if zErr != 0 {
		Xsqlite3_snprintf(tls, nBuf, zBufOut, __ccgo_ts+3944, libc.VaList(bp+8, zErr))
	}
	_unixLeaveMutex(tls)
}
