Files
Maven/vendor/modernc.org/sqlite/lib/sqlite_g_000000000001ffff.go
T
kami 6c92f85d10 feat(ecosystem): compliant Praxis/Hexis integration + vendored build
Bring the Nexus/Praxis/Hexis integration in line with
MAVEN_ECOSYSTEM_ARCHITECTURE.md:

- Praxis over HTTP: drop the in-process praxis.db open (praxisstore/
  praxistools) and call praxisd's /api/v1/tools/* API via a new praxisClient.
  Honors the "no component reads another's DB" invariant (AC#12).
  PraxisConfig.DBPath -> URL.
- Hexis confirmation gate: mutating capabilities (ReadOnly=false) now park a
  bound pendingHexis confirmation and require a spoken "да" before executing;
  read-only run immediately (AC#7, no auto attention->action).
- Capability safety: >1 verb match is ambiguous -> ask instead of firing the
  first; ambiguous Nexus resolution asks for clarification (AC#2).
- Correlation IDs on Hexis execute, recorded in the cross-service trace.
- Bug: importance arrives as JSON float64 over HTTP, not int.
- Tests: confirm-gate, decline, read-only, and ambiguity paths.

Build: vendor/ bakes in the hexis client (replace-directed at a sibling repo
outside the Docker context); Dockerfile builds from vendor and no longer
`go mod download`s the unreachable replace paths.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 20:24:33 +04:00

14237 lines
529 KiB
Go

// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
//go:build (darwin && amd64) || (darwin && arm64) || (freebsd && 386) || (freebsd && amd64) || (freebsd && arm) || (freebsd && arm64) || (linux && 386) || (linux && amd64) || (linux && arm) || (linux && arm64) || (linux && loong64) || (linux && ppc64le) || (linux && riscv64) || (linux && s390x) || (netbsd && amd64) || (openbsd && amd64) || (openbsd && arm64)
package sqlite3
import (
"unsafe"
"modernc.org/libc"
)
const BIG_ENDIAN = 4321
const BUFSIZ = 1024
const DOTLOCK_SUFFIX = ".lock"
type DbPath = TDbPath
type Dl_info = TDl_info
const ENOTBLK = 15
const ETXTBSY = 26
const FD_CLOEXEC = 1
const F_DUPFD = 0
const F_GETFD = 1
const F_GETFL = 3
const F_LOCK = 1
const F_OK = 0
const F_SETFD = 2
const F_SETFL = 4
const F_TEST = 3
const F_TLOCK = 2
const F_ULOCK = 0
const F_UNLCK = 2
const HAVE_FCHMOD = 1
const HAVE_GETHOSTUUID = 0
const INTERFACE = 1
const ITIMER_PROF = 2
const ITIMER_REAL = 0
const ITIMER_VIRTUAL = 1
const LITTLE_ENDIAN = 1234
const L_INCR = 1
const L_SET = 0
const L_XTND = 2
const MADV_DONTNEED = 4
const MADV_NORMAL = 0
const MADV_RANDOM = 1
const MADV_SEQUENTIAL = 2
const MADV_WILLNEED = 3
const MAP_FAILED = -1
const MAP_FILE = 0
const MAP_FIXED = 16
const MAP_PRIVATE = 2
const MAP_SHARED = 1
const MATH_ERREXCEPT = 2
const MATH_ERRNO = 1
const MAX_PATHNAME = 512
const MS_ASYNC = 1
const O_BINARY = 0
const O_RDONLY = 0
const O_RDWR = 2
const O_WRONLY = 1
const PDP_ENDIAN = 3412
const POSIX_MADV_DONTNEED = 4
const POSIX_MADV_NORMAL = 0
const POSIX_MADV_RANDOM = 1
const POSIX_MADV_SEQUENTIAL = 2
const POSIX_MADV_WILLNEED = 3
const PROT_EXEC = 4
const PROT_NONE = 0
const PROT_READ = 1
const PROT_WRITE = 2
const RAND_MAX = 2147483647
const RTLD_LAZY = 1
const RTLD_NEXT = -1
const RTLD_NOW = 2
const R_OK = 4
const SQLITE_DEFAULT_FILE_PERMISSIONS = 420
const SQLITE_DEFAULT_PROXYDIR_PERMISSIONS = 493
const SQLITE_FSFLAGS_IS_MSDOS = 1
const SQLITE_MAX_SYMLINKS = 100
const SQLITE_MINIMUM_FILE_DESCRIPTOR = 3
const SQLITE_OS_UNIX = 1
const S_IEXEC = 64
const S_IFBLK = 24576
const S_IFCHR = 8192
const S_IFDIR = 16384
const S_IFIFO = 4096
const S_IFLNK = 40960
const S_IFMT = 61440
const S_IFREG = 32768
const S_IFSOCK = 49152
const S_IREAD = 256
const S_IRGRP = 32
const S_IROTH = 4
const S_IRUSR = 256
const S_IRWXG = 56
const S_IRWXO = 7
const S_IRWXU = 448
const S_ISGID = 1024
const S_ISUID = 2048
const S_ISVTX = 512
const S_IWGRP = 16
const S_IWOTH = 2
const S_IWRITE = 128
const S_IWUSR = 128
const S_IXGRP = 8
const S_IXOTH = 1
const S_IXUSR = 64
// C documentation
//
// /*
// ** A pathname under construction
// */
type TDbPath = struct {
Frc int32
FnSymlink int32
FzOut uintptr
FnOut int32
FnUsed int32
}
type TDl_info = struct {
Fdli_fname uintptr
Fdli_fbase uintptr
Fdli_sname uintptr
Fdli_saddr uintptr
}
const TIME_UTC = 1
const TIOCM_CAR = 64
const TIOCM_CD = 64
const TIOCM_CTS = 32
const TIOCM_DSR = 256
const TIOCM_DTR = 2
const TIOCM_LE = 1
const TIOCM_RI = 128
const TIOCM_RNG = 128
const TIOCM_RTS = 4
const TIOCM_SR = 16
const TIOCM_ST = 8
const TIOCPKT_DATA = 0
const TIOCPKT_DOSTOP = 32
const TIOCPKT_FLUSHREAD = 1
const TIOCPKT_FLUSHWRITE = 2
const TIOCPKT_IOCTL = 64
const TIOCPKT_NOSTOP = 16
const TIOCPKT_START = 8
const TIOCPKT_STOP = 4
/* An i-node */
type TUnixUnusedFd = struct {
Ffd int32
Fflags int32
FpNext uintptr
}
type Tblkcnt_t = int64
type Tcaddr_t = uintptr
// C documentation
//
// /*
// ** An abstract type for a pointer to an IO method finder function:
// */
type Tfinder_type = uintptr
type Tgid_t = uint32
type Tino_t = uint64
type Tquad_t = int64
type Tu_int16_t = uint16
type Tu_int32_t = uint32
type Tu_int64_t = uint64
type Tu_int8_t = uint8
type Tu_quad_t = uint64
type Tuid_t = uint32
type Tuint = uint32
// C documentation
//
// /* Forward references */
type TunixShm = struct {
FpShmNode uintptr
FpNext uintptr
FhasMutex Tu8
Fid Tu8
FsharedMask Tu16
FexclMask Tu16
}
/* Connection shared memory */
type TunixShmNode = struct {
FpInode uintptr
FpShmMutex uintptr
FzFilename uintptr
FhShm int32
FszRegion int32
FnRegion Tu16
FisReadonly Tu8
FisUnlocked Tu8
FapRegion uintptr
FnRef int32
FpFirst uintptr
FaLock [8]int32
}
// C documentation
//
// /*
// ** Many system calls are accessed through pointer-to-functions so that
// ** they may be overridden at runtime to facilitate fault injection during
// ** testing and sandboxing. The following array holds the names and pointers
// ** to all overrideable system calls.
// */
type Tunix_syscall = struct {
FzName uintptr
FpCurrent Tsqlite3_syscall_ptr
FpDefault Tsqlite3_syscall_ptr
}
type Tushort = uint16
/******************************************************************************
****************** Begin Unique File ID Utility Used By VxWorks ***************
**
** On most versions of unix, we can get a unique ID for a file by concatenating
** the device number and the inode number. But this does not work on VxWorks.
** On VxWorks, a unique file id must be based on the canonical filename.
**
** A pointer to an instance of the following structure can be used as a
** unique file ID in VxWorks. Each instance of this structure contains
** a copy of the canonical filename. There is also a reference count.
** The structure is reclaimed when the number of pointers to it drops to
** zero.
**
** There are never very many files open at one time and lookups are not
** a performance-critical path, so it is sufficient to put these
** structures on a linked list.
*/
type TvxworksFileId = struct {
FpNext uintptr
FnRef int32
FnName int32
FzCanonicalName uintptr
}
type Twinsize = struct {
Fws_row uint16
Fws_col uint16
Fws_xpixel uint16
Fws_ypixel uint16
}
const UNIXFILE_DELETE = 32
const UNIXFILE_DIRSYNC = 8
const UNIXFILE_EXCL = 1
const UNIXFILE_NOLOCK = 128
const UNIXFILE_PERSIST_WAL = 4
const UNIXFILE_PSOW = 16
const UNIXFILE_RDONLY = 2
const UNIXFILE_URI = 64
const UNIX_SHM_BASE = 120
const UNIX_SHM_DMS = 128
type UnixUnusedFd = TUnixUnusedFd
const W_OK = 2
const X_OK = 1
// C documentation
//
// /*
// ** Allocate or return the aggregate context for a user function. A new
// ** context is allocated on the first call. Subsequent calls return the
// ** same context that was returned on prior calls.
// */
func Xsqlite3_aggregate_context(tls *libc.TLS, p uintptr, nByte int32) (r uintptr) {
if libc.Int32FromUint16((*TMem)(unsafe.Pointer((*Tsqlite3_context)(unsafe.Pointer(p)).FpMem)).Fflags)&int32(MEM_Agg) == 0 {
return _createAggContext(tls, p, nByte)
} else {
return (*TMem)(unsafe.Pointer((*Tsqlite3_context)(unsafe.Pointer(p)).FpMem)).Fz
}
return r
}
// C documentation
//
// /*
// ** Return the total number of pages in the source database as of the most
// ** recent call to sqlite3_backup_step().
// */
func Xsqlite3_backup_pagecount(tls *libc.TLS, p uintptr) (r int32) {
return libc.Int32FromUint32((*Tsqlite3_backup)(unsafe.Pointer(p)).FnPagecount)
}
// C documentation
//
// /*
// ** Return the number of pages still to be backed up as of the most recent
// ** call to sqlite3_backup_step().
// */
func Xsqlite3_backup_remaining(tls *libc.TLS, p uintptr) (r int32) {
return libc.Int32FromUint32((*Tsqlite3_backup)(unsafe.Pointer(p)).FnRemaining)
}
func Xsqlite3_bind_blob64(tls *libc.TLS, pStmt uintptr, i int32, zData uintptr, nData Tsqlite3_uint64, __ccgo_fp_xDel uintptr) (r int32) {
return _bindText(tls, pStmt, i, zData, libc.Int64FromUint64(nData), __ccgo_fp_xDel, uint8(0))
}
func Xsqlite3_bind_null(tls *libc.TLS, pStmt uintptr, i int32) (r int32) {
var p uintptr
var rc int32
_, _ = p, rc
p = pStmt
rc = _vdbeUnbind(tls, p, libc.Uint32FromInt32(i-libc.Int32FromInt32(1)))
if rc == SQLITE_OK {
/* tag-20240917-01 */
Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer((*TVdbe)(unsafe.Pointer(p)).Fdb)).Fmutex)
}
return rc
}
func Xsqlite3_bind_value(tls *libc.TLS, pStmt uintptr, i int32, pValue uintptr) (r int32) {
var rc int32
var v1 float64
_, _ = rc, v1
switch Xsqlite3_value_type(tls, pValue) {
case int32(SQLITE_INTEGER):
rc = Xsqlite3_bind_int64(tls, pStmt, i, *(*Ti64)(unsafe.Pointer(pValue)))
case int32(SQLITE_FLOAT):
if libc.Int32FromUint16((*Tsqlite3_value)(unsafe.Pointer(pValue)).Fflags)&int32(MEM_Real) != 0 {
v1 = *(*float64)(unsafe.Pointer(pValue))
} else {
v1 = float64(*(*Ti64)(unsafe.Pointer(pValue)))
}
rc = Xsqlite3_bind_double(tls, pStmt, i, v1)
case int32(SQLITE_BLOB):
if libc.Int32FromUint16((*Tsqlite3_value)(unsafe.Pointer(pValue)).Fflags)&int32(MEM_Zero) != 0 {
rc = Xsqlite3_bind_zeroblob(tls, pStmt, i, *(*int32)(unsafe.Pointer(&(*Tsqlite3_value)(unsafe.Pointer(pValue)).Fu)))
} else {
rc = Xsqlite3_bind_blob(tls, pStmt, i, (*Tsqlite3_value)(unsafe.Pointer(pValue)).Fz, (*Tsqlite3_value)(unsafe.Pointer(pValue)).Fn, uintptr(-libc.Int32FromInt32(1)))
}
case int32(SQLITE_TEXT):
rc = _bindText(tls, pStmt, i, (*Tsqlite3_value)(unsafe.Pointer(pValue)).Fz, int64((*Tsqlite3_value)(unsafe.Pointer(pValue)).Fn), uintptr(-libc.Int32FromInt32(1)), (*Tsqlite3_value)(unsafe.Pointer(pValue)).Fenc)
default:
rc = Xsqlite3_bind_null(tls, pStmt, i)
break
}
return rc
}
// C documentation
//
// /*
// ** Return the number of columns in the result set for the statement pStmt.
// */
func Xsqlite3_column_count(tls *libc.TLS, pStmt uintptr) (r int32) {
var pVm uintptr
_ = pVm
pVm = pStmt
if pVm == uintptr(0) {
return 0
}
return libc.Int32FromUint16((*TVdbe)(unsafe.Pointer(pVm)).FnResColumn)
}
// C documentation
//
// /*
// ** Register a new collation sequence with the database handle db.
// */
func Xsqlite3_create_collation_v2(tls *libc.TLS, db uintptr, zName uintptr, enc int32, pCtx uintptr, __ccgo_fp_xCompare uintptr, __ccgo_fp_xDel uintptr) (r int32) {
var rc int32
_ = rc
Xsqlite3_mutex_enter(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
rc = _createCollation(tls, db, zName, libc.Uint8FromInt32(enc), pCtx, __ccgo_fp_xCompare, __ccgo_fp_xDel)
rc = _sqlite3ApiExit(tls, db, rc)
Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
return rc
}
// C documentation
//
// /*
// ** Return the number of values available from the current row of the
// ** currently executing statement pStmt.
// */
func Xsqlite3_data_count(tls *libc.TLS, pStmt uintptr) (r int32) {
var pVm uintptr
_ = pVm
pVm = pStmt
if pVm == uintptr(0) || (*TVdbe)(unsafe.Pointer(pVm)).FpResultRow == uintptr(0) {
return 0
}
return libc.Int32FromUint16((*TVdbe)(unsafe.Pointer(pVm)).FnResColumn)
}
// C documentation
//
// /*
// ** Enable or disable the extended result codes.
// */
func Xsqlite3_extended_result_codes(tls *libc.TLS, db uintptr, onoff int32) (r int32) {
var v1 uint32
_ = v1
Xsqlite3_mutex_enter(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
if onoff != 0 {
v1 = uint32(0xffffffff)
} else {
v1 = uint32(0xff)
}
(*Tsqlite3)(unsafe.Pointer(db)).FerrMask = libc.Int32FromUint32(v1)
Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
return SQLITE_OK
}
// C documentation
//
// /*
// ** Test to see whether or not the database connection is in autocommit
// ** mode. Return TRUE if it is and FALSE if not. Autocommit mode is on
// ** by default. Autocommit is disabled by a BEGIN statement and reenabled
// ** by the next COMMIT or ROLLBACK.
// */
func Xsqlite3_get_autocommit(tls *libc.TLS, db uintptr) (r int32) {
var iRet int32
_ = iRet
Xsqlite3_mutex_enter(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
iRet = libc.Int32FromUint8((*Tsqlite3)(unsafe.Pointer(db)).FautoCommit)
Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
return iRet
}
func Xsqlite3_keyword_name(tls *libc.TLS, i int32, pzName uintptr, pnName uintptr) (r int32) {
if i < 0 || i >= int32(SQLITE_N_KEYWORD) {
return int32(SQLITE_ERROR)
}
i = i + 1
**(**uintptr)(__ccgo_up(pzName)) = uintptr(unsafe.Pointer(&_zKWText)) + uintptr(_aKWOffset[i])
**(**int32)(__ccgo_up(pnName)) = libc.Int32FromUint8(_aKWLen[i])
return SQLITE_OK
}
// C documentation
//
// /*
// ** This version of the memory allocation is for use by the application.
// ** First make sure the memory subsystem is initialized, then do the
// ** allocation.
// */
func Xsqlite3_malloc(tls *libc.TLS, n int32) (r uintptr) {
var v1 uintptr
_ = v1
if Xsqlite3_initialize(tls) != 0 {
return uintptr(0)
}
if n <= 0 {
v1 = uintptr(0)
} else {
v1 = _sqlite3Malloc(tls, libc.Uint64FromInt32(n))
}
return v1
}
func Xsqlite3_msize(tls *libc.TLS, p uintptr) (r Tsqlite3_uint64) {
var v1 int32
_ = v1
if p != 0 {
v1 = (*(*func(*libc.TLS, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_sqlite3Config.Fm.FxSize})))(tls, p)
} else {
v1 = 0
}
return libc.Uint64FromInt32(v1)
}
// C documentation
//
// /*
// ** Open a new database handle.
// */
func Xsqlite3_open(tls *libc.TLS, zFilename uintptr, ppDb uintptr) (r int32) {
return _openDatabase(tls, zFilename, ppDb, libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_OPEN_READWRITE)|libc.Int32FromInt32(SQLITE_OPEN_CREATE)), uintptr(0))
}
func Xsqlite3_open_v2(tls *libc.TLS, filename uintptr, ppDb uintptr, flags int32, zVfs uintptr) (r int32) {
return _openDatabase(tls, filename, ppDb, libc.Uint32FromInt32(flags), zVfs)
}
// C documentation
//
// /*
// ** Shutdown the operating system interface.
// **
// ** Some operating systems might need to do some cleanup in this routine,
// ** to release dynamically allocated objects. But not on unix.
// ** This routine is a no-op for unix.
// */
func Xsqlite3_os_end(tls *libc.TLS) (r int32) {
_unixBigLock = uintptr(0)
return SQLITE_OK
}
/************** End of os_unix.c *********************************************/
/************** Begin file os_win.c ******************************************/
/*
** 2004 May 22
**
** 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 that is specific to Windows.
*/
/* #include "sqliteInt.h" */
/************** End of os_win.c **********************************************/
/************** Begin file memdb.c *******************************************/
/*
** 2016-09-07
**
** 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 implements an in-memory VFS. A database is held as a contiguous
** block of memory.
**
** This file also implements interface sqlite3_serialize() and
** sqlite3_deserialize().
*/
/* #include "sqliteInt.h" */
// C documentation
//
// /*
// ** This function is called from within a pre-update callback to retrieve
// ** the number of columns in the row being updated, deleted or inserted.
// */
func Xsqlite3_preupdate_count(tls *libc.TLS, db uintptr) (r int32) {
var p uintptr
var v1 int32
_, _ = p, v1
p = (*Tsqlite3)(unsafe.Pointer(db)).FpPreUpdate
if p != 0 {
v1 = libc.Int32FromUint16((*TKeyInfo)(unsafe.Pointer((*TPreUpdate)(unsafe.Pointer(p)).FpKeyinfo)).FnKeyField)
} else {
v1 = 0
}
return v1
}
// C documentation
//
// /*
// ** This routine sets the progress callback for an Sqlite database to the
// ** given callback function with the given argument. The progress callback will
// ** be invoked every nOps opcodes.
// */
func Xsqlite3_progress_handler(tls *libc.TLS, db uintptr, nOps int32, __ccgo_fp_xProgress uintptr, pArg uintptr) {
Xsqlite3_mutex_enter(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
if nOps > 0 {
(*Tsqlite3)(unsafe.Pointer(db)).FxProgress = __ccgo_fp_xProgress
(*Tsqlite3)(unsafe.Pointer(db)).FnProgressOps = libc.Uint32FromInt32(nOps)
(*Tsqlite3)(unsafe.Pointer(db)).FpProgressArg = pArg
} else {
(*Tsqlite3)(unsafe.Pointer(db)).FxProgress = uintptr(0)
(*Tsqlite3)(unsafe.Pointer(db)).FnProgressOps = uint32(0)
(*Tsqlite3)(unsafe.Pointer(db)).FpProgressArg = uintptr(0)
}
Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
}
// C documentation
//
// /*
// ** The public interface to sqlite3Realloc. Make sure that the memory
// ** subsystem is initialized prior to invoking sqliteRealloc.
// */
func Xsqlite3_realloc(tls *libc.TLS, pOld uintptr, n int32) (r uintptr) {
if Xsqlite3_initialize(tls) != 0 {
return uintptr(0)
}
if n < 0 {
n = 0
} /* IMP: R-26507-47431 */
return _sqlite3Realloc(tls, pOld, libc.Uint64FromInt32(n))
}
func Xsqlite3_result_blob64(tls *libc.TLS, pCtx uintptr, z uintptr, n Tsqlite3_uint64, __ccgo_fp_xDel uintptr) {
if n > uint64(0x7fffffff) {
_invokeValueDestructor(tls, z, __ccgo_fp_xDel, pCtx)
} else {
_setResultStrOrError(tls, pCtx, z, libc.Int32FromUint64(n), uint8(0), __ccgo_fp_xDel)
}
}
func Xsqlite3_result_error_code(tls *libc.TLS, pCtx uintptr, errCode int32) {
var v1 int32
_ = v1
if errCode != 0 {
v1 = errCode
} else {
v1 = -int32(1)
}
(*Tsqlite3_context)(unsafe.Pointer(pCtx)).FisError = v1
if libc.Int32FromUint16((*TMem)(unsafe.Pointer((*Tsqlite3_context)(unsafe.Pointer(pCtx)).FpOut)).Fflags)&int32(MEM_Null) != 0 {
_setResultStrOrError(tls, pCtx, _sqlite3ErrStr(tls, errCode), -int32(1), uint8(SQLITE_UTF8), libc.UintptrFromInt32(0))
}
}
func Xsqlite3_result_text16be(tls *libc.TLS, pCtx uintptr, z uintptr, n int32, __ccgo_fp_xDel uintptr) {
_setResultStrOrError(tls, pCtx, z, libc.Int32FromUint64(libc.Uint64FromInt32(n) & ^libc.Uint64FromInt32(1)), uint8(SQLITE_UTF16BE), __ccgo_fp_xDel)
}
func Xsqlite3_result_text16le(tls *libc.TLS, pCtx uintptr, z uintptr, n int32, __ccgo_fp_xDel uintptr) {
_setResultStrOrError(tls, pCtx, z, libc.Int32FromUint64(libc.Uint64FromInt32(n) & ^libc.Uint64FromInt32(1)), uint8(SQLITE_UTF16LE), __ccgo_fp_xDel)
}
func Xsqlite3_result_value(tls *libc.TLS, pCtx uintptr, pValue uintptr) {
var pOut uintptr
_ = pOut
pOut = (*Tsqlite3_context)(unsafe.Pointer(pCtx)).FpOut
_sqlite3VdbeMemCopy(tls, pOut, pValue)
_sqlite3VdbeChangeEncoding(tls, pOut, libc.Int32FromUint8((*Tsqlite3_context)(unsafe.Pointer(pCtx)).Fenc))
if _sqlite3VdbeMemTooBig(tls, pOut) != 0 {
Xsqlite3_result_error_toobig(tls, pCtx)
}
}
func Xsqlite3_result_zeroblob(tls *libc.TLS, pCtx uintptr, n int32) {
var v1 int32
_ = v1
if n > 0 {
v1 = n
} else {
v1 = 0
}
Xsqlite3_result_zeroblob64(tls, pCtx, libc.Uint64FromInt32(v1))
}
// C documentation
//
// /*
// ** Return true if the prepared statement is in need of being reset.
// */
func Xsqlite3_stmt_busy(tls *libc.TLS, pStmt uintptr) (r int32) {
var v uintptr
_ = v
v = pStmt
return libc.BoolInt32(v != uintptr(0) && libc.Int32FromUint8((*TVdbe)(unsafe.Pointer(v)).FeVdbeState) == int32(VDBE_RUN_STATE))
}
// C documentation
//
// /* Return any error code associated with p */
func Xsqlite3_str_errcode(tls *libc.TLS, p uintptr) (r int32) {
var v1 int32
_ = v1
if p != 0 {
v1 = libc.Int32FromUint8((*Tsqlite3_str)(unsafe.Pointer(p)).FaccError)
} else {
v1 = int32(SQLITE_NOMEM)
}
return v1
}
// C documentation
//
// /* Return the current length of p in bytes */
func Xsqlite3_str_length(tls *libc.TLS, p uintptr) (r int32) {
var v1 uint32
_ = v1
if p != 0 {
v1 = (*Tsqlite3_str)(unsafe.Pointer(p)).FnChar
} else {
v1 = uint32(0)
}
return libc.Int32FromUint32(v1)
}
func Xsqlite3_strnicmp(tls *libc.TLS, zLeft uintptr, zRight uintptr, N int32) (r int32) {
var a, b uintptr
var v1 int32
_, _, _ = a, b, v1
if zLeft == uintptr(0) {
if zRight != 0 {
v1 = -int32(1)
} else {
v1 = 0
}
return v1
} else {
if zRight == uintptr(0) {
return int32(1)
}
}
a = zLeft
b = zRight
for {
v1 = N
N = N - 1
if !(v1 > 0 && libc.Int32FromUint8(**(**uint8)(__ccgo_up(a))) != 0 && libc.Int32FromUint8(_sqlite3UpperToLower[**(**uint8)(__ccgo_up(a))]) == libc.Int32FromUint8(_sqlite3UpperToLower[**(**uint8)(__ccgo_up(b))])) {
break
}
a = a + 1
b = b + 1
}
if N < 0 {
v1 = 0
} else {
v1 = libc.Int32FromUint8(_sqlite3UpperToLower[**(**uint8)(__ccgo_up(a))]) - libc.Int32FromUint8(_sqlite3UpperToLower[**(**uint8)(__ccgo_up(b))])
}
return v1
}
// C documentation
//
// /*
// ** Return a boolean value for a query parameter.
// */
func Xsqlite3_uri_boolean(tls *libc.TLS, zFilename uintptr, zParam uintptr, bDflt int32) (r int32) {
var z uintptr
var v1 int32
_, _ = z, v1
z = Xsqlite3_uri_parameter(tls, zFilename, zParam)
bDflt = libc.BoolInt32(bDflt != 0)
if z != 0 {
v1 = libc.Int32FromUint8(_sqlite3GetBoolean(tls, z, libc.Uint8FromInt32(bDflt)))
} else {
v1 = bDflt
}
return v1
}
func Xsqlite3_value_encoding(tls *libc.TLS, pVal uintptr) (r int32) {
return libc.Int32FromUint8((*Tsqlite3_value)(unsafe.Pointer(pVal)).Fenc)
}
// C documentation
//
// /* Return true if a parameter value originated from an sqlite3_bind() */
func Xsqlite3_value_frombind(tls *libc.TLS, pVal uintptr) (r int32) {
return libc.BoolInt32(libc.Int32FromUint16((*Tsqlite3_value)(unsafe.Pointer(pVal)).Fflags)&int32(MEM_FromBind) != 0)
}
// C documentation
//
// /* Return true if a parameter to xUpdate represents an unchanged column */
func Xsqlite3_value_nochange(tls *libc.TLS, pVal uintptr) (r int32) {
return libc.BoolInt32(libc.Int32FromUint16((*Tsqlite3_value)(unsafe.Pointer(pVal)).Fflags)&(libc.Int32FromInt32(MEM_Null)|libc.Int32FromInt32(MEM_Zero)) == libc.Int32FromInt32(MEM_Null)|libc.Int32FromInt32(MEM_Zero))
}
func Xsqlite3_value_subtype(tls *libc.TLS, pVal uintptr) (r uint32) {
var pMem uintptr
var v1 int32
_, _ = pMem, v1
pMem = pVal
if libc.Int32FromUint16((*TMem)(unsafe.Pointer(pMem)).Fflags)&int32(MEM_Subtype) != 0 {
v1 = libc.Int32FromUint8((*TMem)(unsafe.Pointer(pMem)).FeSubtype)
} else {
v1 = 0
}
return libc.Uint32FromInt32(v1)
}
// C documentation
//
// /* EVIDENCE-OF: R-12793-43283 Every value in SQLite has one of five
// ** fundamental datatypes: 64-bit signed integer 64-bit IEEE floating
// ** point number string BLOB NULL
// */
func Xsqlite3_value_type(tls *libc.TLS, pVal uintptr) (r int32) {
return libc.Int32FromUint8(_aType[libc.Int32FromUint16((*Tsqlite3_value)(unsafe.Pointer(pVal)).Fflags)&int32(MEM_AffMask)])
}
// C documentation
//
// /*
// ** Call from within the xCreate() or xConnect() methods to provide
// ** the SQLite core with additional information about the behavior
// ** of the virtual table being implemented.
// */
func Xsqlite3_vtab_config(tls *libc.TLS, db uintptr, op int32, va uintptr) (r int32) {
var ap Tva_list
var p uintptr
var rc int32
_, _, _ = ap, p, rc
rc = SQLITE_OK
Xsqlite3_mutex_enter(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
p = (*Tsqlite3)(unsafe.Pointer(db)).FpVtabCtx
if !(p != 0) {
rc = _sqlite3MisuseError(tls, int32(163230))
} else {
ap = va
switch op {
case int32(SQLITE_VTAB_CONSTRAINT_SUPPORT):
(*TVTable)(unsafe.Pointer((*TVtabCtx)(unsafe.Pointer(p)).FpVTable)).FbConstraint = libc.Uint8FromInt32(libc.VaInt32(&ap))
case int32(SQLITE_VTAB_INNOCUOUS):
(*TVTable)(unsafe.Pointer((*TVtabCtx)(unsafe.Pointer(p)).FpVTable)).FeVtabRisk = uint8(SQLITE_VTABRISK_Low)
case int32(SQLITE_VTAB_DIRECTONLY):
(*TVTable)(unsafe.Pointer((*TVtabCtx)(unsafe.Pointer(p)).FpVTable)).FeVtabRisk = uint8(SQLITE_VTABRISK_High)
case int32(SQLITE_VTAB_USES_ALL_SCHEMAS):
(*TVTable)(unsafe.Pointer((*TVtabCtx)(unsafe.Pointer(p)).FpVTable)).FbAllSchemas = uint8(1)
default:
rc = _sqlite3MisuseError(tls, int32(163252))
break
}
_ = ap
}
if rc != SQLITE_OK {
_sqlite3Error(tls, db, rc)
}
Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
return rc
}
/************** End of vtab.c ************************************************/
/************** Begin file wherecode.c ***************************************/
/*
** 2015-06-06
**
** 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 module contains C code that generates VDBE code used to process
** the WHERE clause of SQL statements.
**
** This file was split off from where.c on 2015-06-06 in order to reduce the
** size of where.c and make it easier to edit. This file contains the routines
** that actually generate the bulk of the WHERE loop code. The original where.c
** file retains the code that does query planning and analysis.
*/
/* #include "sqliteInt.h" */
/************** Include whereInt.h in the middle of wherecode.c **************/
/************** Begin file whereInt.h ****************************************/
/*
** 2013-11-12
**
** 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 structure and macro definitions for the query
** planner logic in "where.c". These definitions are broken out into
** a separate source file for easier editing.
*/
const _IOLBF = 1
const _IONBF = 2
const __SIZEOF_WCHAR_T__ = 4
const __SIZEOF_WINT_T__ = 4
const __WCHAR_WIDTH__ = 32
const __WINT_WIDTH__ = 32
const __restrict_arr = 0
/* EVIDENCE-OF: R-14606-31564 Value is a BLOB that is (N-12)/2 bytes in
** length.
** EVIDENCE-OF: R-28401-00140 Value is a string in the text encoding and
** (N-13)/2 bytes in length. */
var _aFlag = [2]Tu16{
0: libc.Uint16FromInt32(libc.Int32FromInt32(MEM_Blob) | libc.Int32FromInt32(MEM_Ephem)),
1: libc.Uint16FromInt32(libc.Int32FromInt32(MEM_Str) | libc.Int32FromInt32(MEM_Ephem)),
}
/* If the column value is a string, we need a persistent value, not
** a MEM_Ephem value. This branch is a fast short-cut that is equivalent
** to calling sqlite3VdbeSerialGet() and sqlite3VdbeDeephemeralize().
*/
var _aFlag1 = [2]Tu16{
0: uint16(MEM_Blob),
1: libc.Uint16FromInt32(libc.Int32FromInt32(MEM_Str) | libc.Int32FromInt32(MEM_Term)),
}
var _aKeyword = [7]struct {
Fi Tu8
FnChar Tu8
Fcode Tu8
}{
0: {
FnChar: uint8(7),
Fcode: uint8(JT_NATURAL),
},
1: {
Fi: uint8(6),
FnChar: uint8(4),
Fcode: libc.Uint8FromInt32(libc.Int32FromInt32(JT_LEFT) | libc.Int32FromInt32(JT_OUTER)),
},
2: {
Fi: uint8(10),
FnChar: uint8(5),
Fcode: uint8(JT_OUTER),
},
3: {
Fi: uint8(14),
FnChar: uint8(5),
Fcode: libc.Uint8FromInt32(libc.Int32FromInt32(JT_RIGHT) | libc.Int32FromInt32(JT_OUTER)),
},
4: {
Fi: uint8(19),
FnChar: uint8(4),
Fcode: libc.Uint8FromInt32(libc.Int32FromInt32(JT_LEFT) | libc.Int32FromInt32(JT_RIGHT) | libc.Int32FromInt32(JT_OUTER)),
},
5: {
Fi: uint8(23),
FnChar: uint8(5),
Fcode: uint8(JT_INNER),
},
6: {
Fi: uint8(28),
FnChar: uint8(5),
Fcode: libc.Uint8FromInt32(libc.Int32FromInt32(JT_INNER) | libc.Int32FromInt32(JT_CROSS)),
},
}
var _aWindowFuncs = [15]TFuncDef{
0: {
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(SQLITE_FUNC_WINDOW) | libc.Int32FromInt32(0)),
FzName: uintptr(unsafe.Pointer(&_row_numberName)),
},
1: {
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(SQLITE_FUNC_WINDOW) | libc.Int32FromInt32(0)),
FzName: uintptr(unsafe.Pointer(&_dense_rankName)),
},
2: {
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(SQLITE_FUNC_WINDOW) | libc.Int32FromInt32(0)),
FzName: uintptr(unsafe.Pointer(&_rankName)),
},
3: {
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(SQLITE_FUNC_WINDOW) | libc.Int32FromInt32(0)),
FzName: uintptr(unsafe.Pointer(&_percent_rankName)),
},
4: {
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(SQLITE_FUNC_WINDOW) | libc.Int32FromInt32(0)),
FzName: uintptr(unsafe.Pointer(&_cume_distName)),
},
5: {
FnArg: int16(1),
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(SQLITE_FUNC_WINDOW) | libc.Int32FromInt32(0)),
FzName: uintptr(unsafe.Pointer(&_ntileName)),
},
6: {
FnArg: int16(1),
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(SQLITE_FUNC_WINDOW) | libc.Int32FromInt32(0)),
FzName: uintptr(unsafe.Pointer(&_last_valueName)),
},
7: {
FnArg: int16(2),
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(SQLITE_FUNC_WINDOW) | libc.Int32FromInt32(0)),
FzName: uintptr(unsafe.Pointer(&_nth_valueName)),
},
8: {
FnArg: int16(1),
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(SQLITE_FUNC_WINDOW) | libc.Int32FromInt32(0)),
FzName: uintptr(unsafe.Pointer(&_first_valueName)),
},
9: {
FnArg: int16(1),
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(SQLITE_FUNC_WINDOW) | libc.Int32FromInt32(0)),
FzName: uintptr(unsafe.Pointer(&_leadName)),
},
10: {
FnArg: int16(2),
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(SQLITE_FUNC_WINDOW) | libc.Int32FromInt32(0)),
FzName: uintptr(unsafe.Pointer(&_leadName)),
},
11: {
FnArg: int16(3),
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(SQLITE_FUNC_WINDOW) | libc.Int32FromInt32(0)),
FzName: uintptr(unsafe.Pointer(&_leadName)),
},
12: {
FnArg: int16(1),
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(SQLITE_FUNC_WINDOW) | libc.Int32FromInt32(0)),
FzName: uintptr(unsafe.Pointer(&_lagName)),
},
13: {
FnArg: int16(2),
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(SQLITE_FUNC_WINDOW) | libc.Int32FromInt32(0)),
FzName: uintptr(unsafe.Pointer(&_lagName)),
},
14: {
FnArg: int16(3),
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(SQLITE_FUNC_WINDOW) | libc.Int32FromInt32(0)),
FzName: uintptr(unsafe.Pointer(&_lagName)),
},
}
// C documentation
//
// /*
// ** This variant of sqlite3BtreePayload() works even if the cursor has not
// ** in the CURSOR_VALID state. It is only used by the sqlite3_blob_read()
// ** interface.
// */
func _accessPayloadChecked(tls *libc.TLS, pCur uintptr, offset Tu32, amt Tu32, pBuf uintptr) (r int32) {
var rc, v1 int32
_, _ = rc, v1
if libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCur)).FeState) == int32(CURSOR_INVALID) {
return int32(SQLITE_ABORT)
}
rc = _btreeRestoreCursorPosition(tls, pCur)
if rc != 0 {
v1 = rc
} else {
v1 = _accessPayload(tls, pCur, offset, amt, pBuf, 0)
}
return v1
}
// C documentation
//
// /*
// ** This routine takes the module argument that has been accumulating
// ** in pParse->zArg[] and appends it to the list of arguments on the
// ** virtual table currently under construction in pParse->pTable.
// */
func _addArgumentToVtab(tls *libc.TLS, pParse uintptr) {
var db, z uintptr
var n int32
_, _, _ = db, n, z
if (*TParse)(unsafe.Pointer(pParse)).FsArg.Fz != 0 && (*TParse)(unsafe.Pointer(pParse)).FpNewTable != 0 {
z = (*TParse)(unsafe.Pointer(pParse)).FsArg.Fz
n = libc.Int32FromUint32((*TParse)(unsafe.Pointer(pParse)).FsArg.Fn)
db = (*TParse)(unsafe.Pointer(pParse)).Fdb
_addModuleArgument(tls, pParse, (*TParse)(unsafe.Pointer(pParse)).FpNewTable, _sqlite3DbStrNDup(tls, db, z, libc.Uint64FromInt32(n)))
}
}
// C documentation
//
// /*
// ** Return SQLITE_CORRUPT if any cursor other than pCur is currently valid
// ** on the same B-tree as pCur.
// **
// ** This can occur if a database is corrupt with two or more SQL tables
// ** pointing to the same b-tree. If an insert occurs on one SQL table
// ** and causes a BEFORE TRIGGER to do a secondary insert on the other SQL
// ** table linked to the same b-tree. If the secondary insert causes a
// ** rebalance, that can change content out from under the cursor on the
// ** first SQL table, violating invariants on the first insert.
// */
func _anotherValidCursor(tls *libc.TLS, pCur uintptr) (r int32) {
var pOther uintptr
_ = pOther
pOther = (*TBtShared)(unsafe.Pointer((*TBtCursor)(unsafe.Pointer(pCur)).FpBt)).FpCursor
for {
if !(pOther != 0) {
break
}
if pOther != pCur && libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pOther)).FeState) == CURSOR_VALID && (*TBtCursor)(unsafe.Pointer(pOther)).FpPage == (*TBtCursor)(unsafe.Pointer(pCur)).FpPage {
return _sqlite3CorruptError(tls, int32(82340))
}
goto _1
_1:
;
pOther = (*TBtCursor)(unsafe.Pointer(pOther)).FpNext
}
return SQLITE_OK
}
// C documentation
//
// /*
// ** Perform a read or write operation on a blob
// */
func _blobReadWrite(tls *libc.TLS, pBlob uintptr, z uintptr, n int32, iOffset int32, __ccgo_fp_xCall uintptr) (r int32) {
bp := tls.Alloc(16)
defer tls.Free(16)
var db, p, v uintptr
var iKey Tsqlite3_int64
var rc int32
var _ /* bDiff at bp+0 */ int32
_, _, _, _, _ = db, iKey, p, rc, v
rc = SQLITE_OK
p = pBlob
if p == uintptr(0) {
return _sqlite3MisuseError(tls, int32(106385))
}
db = (*TIncrblob)(unsafe.Pointer(p)).Fdb
Xsqlite3_mutex_enter(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
v = (*TIncrblob)(unsafe.Pointer(p)).FpStmt
if n < 0 || iOffset < 0 || int64(iOffset)+int64(n) > int64((*TIncrblob)(unsafe.Pointer(p)).FnByte) {
/* Request is out of range. Return a transient error. */
rc = int32(SQLITE_ERROR)
} else {
if v == 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 {
/* Call either BtreeData() or BtreePutData(). If SQLITE_ABORT is
** returned, clean-up the statement handle.
*/
_sqlite3BtreeEnterCursor(tls, (*TIncrblob)(unsafe.Pointer(p)).FpCsr)
if __ccgo_fp_xCall == __ccgo_fp(_sqlite3BtreePutData) && (*Tsqlite3)(unsafe.Pointer(db)).FxPreUpdateCallback != 0 {
/* If a pre-update hook is registered and this is a write cursor,
** invoke it here.
**
** TODO: The preupdate-hook is passed SQLITE_DELETE, even though this
** operation should really be an SQLITE_UPDATE. This is probably
** incorrect, but is convenient because at this point the new.* values
** are not easily obtainable. And for the sessions module, an
** SQLITE_UPDATE where the PK columns do not change is handled in the
** same way as an SQLITE_DELETE (the SQLITE_DELETE code is actually
** slightly more efficient). Since you cannot write to a PK column
** using the incremental-blob API, this works. For the sessions module
** anyhow.
*/
if _sqlite3BtreeCursorIsValidNN(tls, (*TIncrblob)(unsafe.Pointer(p)).FpCsr) == 0 {
/* If the cursor is not currently valid, try to reseek it. This
** always either fails or finds the correct row - the cursor will
** have been marked permanently CURSOR_INVALID if the open row has
** been deleted. */
**(**int32)(__ccgo_up(bp)) = 0
rc = _sqlite3BtreeCursorRestore(tls, (*TIncrblob)(unsafe.Pointer(p)).FpCsr, bp)
}
if _sqlite3BtreeCursorIsValidNN(tls, (*TIncrblob)(unsafe.Pointer(p)).FpCsr) != 0 {
iKey = _sqlite3BtreeIntegerKey(tls, (*TIncrblob)(unsafe.Pointer(p)).FpCsr)
_sqlite3VdbePreUpdateHook(tls, v, **(**uintptr)(__ccgo_up((*TVdbe)(unsafe.Pointer(v)).FapCsr)), int32(SQLITE_DELETE), (*TIncrblob)(unsafe.Pointer(p)).FzDb, (*TIncrblob)(unsafe.Pointer(p)).FpTab, iKey, -int32(1), libc.Int32FromUint16((*TIncrblob)(unsafe.Pointer(p)).FiCol))
}
}
if rc == SQLITE_OK {
rc = (*(*func(*libc.TLS, uintptr, Tu32, Tu32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{__ccgo_fp_xCall})))(tls, (*TIncrblob)(unsafe.Pointer(p)).FpCsr, libc.Uint32FromInt32(iOffset+(*TIncrblob)(unsafe.Pointer(p)).FiOffset), libc.Uint32FromInt32(n), z)
}
_sqlite3BtreeLeaveCursor(tls, (*TIncrblob)(unsafe.Pointer(p)).FpCsr)
if rc == int32(SQLITE_ABORT) {
_sqlite3VdbeFinalize(tls, v)
(*TIncrblob)(unsafe.Pointer(p)).FpStmt = uintptr(0)
} else {
(*TVdbe)(unsafe.Pointer(v)).Frc = rc
}
}
}
_sqlite3Error(tls, db, rc)
rc = _sqlite3ApiExit(tls, db, rc)
Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
return rc
}
// C documentation
//
// /* This is a helper function to impliesNotNullRow(). In this routine,
// ** set pWalker->eCode to one only if *both* of the input expressions
// ** separately have the implies-not-null-row property.
// */
func _bothImplyNotNullRow(tls *libc.TLS, pWalker uintptr, pE1 uintptr, pE2 uintptr) {
if libc.Int32FromUint16((*TWalker)(unsafe.Pointer(pWalker)).FeCode) == 0 {
_sqlite3WalkExpr(tls, pWalker, pE1)
if (*TWalker)(unsafe.Pointer(pWalker)).FeCode != 0 {
(*TWalker)(unsafe.Pointer(pWalker)).FeCode = uint16(0)
_sqlite3WalkExpr(tls, pWalker, pE2)
}
}
}
// C documentation
//
// /*
// ** Compute the amount of freespace on the page. In other words, fill
// ** in the pPage->nFree field.
// */
func _btreeComputeFreeSpace(tls *libc.TLS, pPage uintptr) (r int32) {
var data uintptr
var hdr Tu8
var iCellFirst, iCellLast, nFree, pc, top, usableSize int32
var next, size Tu32
_, _, _, _, _, _, _, _, _, _ = data, hdr, iCellFirst, iCellLast, nFree, next, pc, size, top, usableSize /* Last possible cell or freeblock offset */
usableSize = libc.Int32FromUint32((*TBtShared)(unsafe.Pointer((*TMemPage)(unsafe.Pointer(pPage)).FpBt)).FusableSize)
hdr = (*TMemPage)(unsafe.Pointer(pPage)).FhdrOffset
data = (*TMemPage)(unsafe.Pointer(pPage)).FaData
/* EVIDENCE-OF: R-58015-48175 The two-byte integer at offset 5 designates
** the start of the cell content area. A zero value for this integer is
** interpreted as 65536. */
top = (libc.Int32FromUint8(**(**Tu8)(__ccgo_up(data + uintptr(libc.Int32FromUint8(hdr)+int32(5)))))<<libc.Int32FromInt32(8)|libc.Int32FromUint8(**(**Tu8)(__ccgo_up(data + uintptr(libc.Int32FromUint8(hdr)+int32(5)) + 1)))-int32(1))&int32(0xffff) + int32(1)
iCellFirst = libc.Int32FromUint8(hdr) + int32(8) + libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pPage)).FchildPtrSize) + int32(2)*libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FnCell)
iCellLast = usableSize - int32(4)
/* Compute the total free space on the page
** EVIDENCE-OF: R-23588-34450 The two-byte integer at offset 1 gives the
** start of the first freeblock on the page, or is zero if there are no
** freeblocks. */
pc = libc.Int32FromUint8(**(**Tu8)(__ccgo_up(data + uintptr(libc.Int32FromUint8(hdr)+int32(1)))))<<int32(8) | libc.Int32FromUint8(**(**Tu8)(__ccgo_up(data + uintptr(libc.Int32FromUint8(hdr)+int32(1)) + 1)))
nFree = libc.Int32FromUint8(**(**Tu8)(__ccgo_up(data + uintptr(libc.Int32FromUint8(hdr)+int32(7))))) + top /* Init nFree to non-freeblock free space */
if pc > 0 {
if pc < top {
/* EVIDENCE-OF: R-55530-52930 In a well-formed b-tree page, there will
** always be at least one cell before the first freeblock.
*/
return _sqlite3CorruptError(tls, int32(75358))
}
for int32(1) != 0 {
if pc > iCellLast {
/* Freeblock off the end of the page */
return _sqlite3CorruptError(tls, int32(75363))
}
next = libc.Uint32FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up(data + uintptr(pc))))<<libc.Int32FromInt32(8) | libc.Int32FromUint8(**(**Tu8)(__ccgo_up(data + uintptr(pc) + 1))))
size = libc.Uint32FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up(data + uintptr(pc+int32(2)))))<<libc.Int32FromInt32(8) | libc.Int32FromUint8(**(**Tu8)(__ccgo_up(data + uintptr(pc+int32(2)) + 1))))
if size < uint32(4) {
/* Minimum freeblock size is 4 */
return _sqlite3CorruptError(tls, int32(75369))
}
nFree = libc.Int32FromUint32(libc.Uint32FromInt32(nFree) + size)
if next < libc.Uint32FromInt32(pc)+size+uint32(4) {
break
}
pc = libc.Int32FromUint32(next)
}
if next > uint32(0) {
/* Freeblock not in ascending order */
return _sqlite3CorruptError(tls, int32(75377))
}
if libc.Uint32FromInt32(pc)+size > libc.Uint32FromInt32(usableSize) {
/* Last freeblock extends past page end */
return _sqlite3CorruptError(tls, int32(75381))
}
}
/* At this point, nFree contains the sum of the offset to the start
** of the cell-content area plus the number of free bytes within
** the cell-content area. If this is greater than the usable-size
** of the page, then the page must be corrupted. This check also
** serves to verify that the offset to the start of the cell-content
** area, according to the page header, lies within the page.
*/
if nFree > usableSize || nFree < iCellFirst {
return _sqlite3CorruptError(tls, int32(75393))
}
(*TMemPage)(unsafe.Pointer(pPage)).FnFree = libc.Int32FromUint16(libc.Uint16FromInt32(nFree - iCellFirst))
return SQLITE_OK
}
// C documentation
//
// /*
// ** This function is called from both BtreeCommitPhaseTwo() and BtreeRollback()
// ** at the conclusion of a transaction.
// */
func _btreeEndTransaction(tls *libc.TLS, p uintptr) {
var db, pBt uintptr
_, _ = db, pBt
pBt = (*TBtree)(unsafe.Pointer(p)).FpBt
db = (*TBtree)(unsafe.Pointer(p)).Fdb
(*TBtShared)(unsafe.Pointer(pBt)).FbDoTruncate = uint8(0)
if libc.Int32FromUint8((*TBtree)(unsafe.Pointer(p)).FinTrans) > TRANS_NONE && (*Tsqlite3)(unsafe.Pointer(db)).FnVdbeRead > int32(1) {
/* If there are other active statements that belong to this database
** handle, downgrade to a read-only transaction. The other statements
** may still be reading from the database. */
_downgradeAllSharedCacheTableLocks(tls, p)
(*TBtree)(unsafe.Pointer(p)).FinTrans = uint8(TRANS_READ)
} else {
/* If the handle had any kind of transaction open, decrement the
** transaction count of the shared btree. If the transaction count
** reaches 0, set the shared state to TRANS_NONE. The unlockBtreeIfUnused()
** call below will unlock the pager. */
if libc.Int32FromUint8((*TBtree)(unsafe.Pointer(p)).FinTrans) != TRANS_NONE {
_clearAllSharedCacheTableLocks(tls, p)
(*TBtShared)(unsafe.Pointer(pBt)).FnTransaction = (*TBtShared)(unsafe.Pointer(pBt)).FnTransaction - 1
if 0 == (*TBtShared)(unsafe.Pointer(pBt)).FnTransaction {
(*TBtShared)(unsafe.Pointer(pBt)).FinTransaction = uint8(TRANS_NONE)
}
}
/* Set the current transaction state to TRANS_NONE and unlock the
** pager if this call closed the only read or write transaction. */
(*TBtree)(unsafe.Pointer(p)).FinTrans = uint8(TRANS_NONE)
_unlockBtreeIfUnused(tls, pBt)
}
}
// C documentation
//
// /*
// ** Initialize the auxiliary information for a disk block.
// **
// ** Return SQLITE_OK on success. If we see that the page does
// ** not contain a well-formed database page, then return
// ** SQLITE_CORRUPT. Note that a return of SQLITE_OK does not
// ** guarantee that the page is well-formed. It only shows that
// ** we failed to detect any corruption.
// */
func _btreeInitPage(tls *libc.TLS, pPage uintptr) (r int32) {
var data, pBt uintptr
_, _ = data, pBt /* The main btree structure */
pBt = (*TMemPage)(unsafe.Pointer(pPage)).FpBt
data = (*TMemPage)(unsafe.Pointer(pPage)).FaData + uintptr((*TMemPage)(unsafe.Pointer(pPage)).FhdrOffset)
/* EVIDENCE-OF: R-28594-02890 The one-byte flag at offset 0 indicating
** the b-tree page type. */
if _decodeFlags(tls, pPage, libc.Int32FromUint8(**(**Tu8)(__ccgo_up(data)))) != 0 {
return _sqlite3CorruptError(tls, int32(75461))
}
(*TMemPage)(unsafe.Pointer(pPage)).FmaskPage = uint16((*TBtShared)(unsafe.Pointer(pBt)).FpageSize - libc.Uint32FromInt32(1))
(*TMemPage)(unsafe.Pointer(pPage)).FnOverflow = uint8(0)
(*TMemPage)(unsafe.Pointer(pPage)).FcellOffset = libc.Uint16FromInt32(libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pPage)).FhdrOffset) + libc.Int32FromInt32(8) + libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pPage)).FchildPtrSize))
(*TMemPage)(unsafe.Pointer(pPage)).FaCellIdx = data + uintptr((*TMemPage)(unsafe.Pointer(pPage)).FchildPtrSize) + uintptr(8)
(*TMemPage)(unsafe.Pointer(pPage)).FaDataEnd = (*TMemPage)(unsafe.Pointer(pPage)).FaData + uintptr((*TBtShared)(unsafe.Pointer(pBt)).FpageSize)
(*TMemPage)(unsafe.Pointer(pPage)).FaDataOfst = (*TMemPage)(unsafe.Pointer(pPage)).FaData + uintptr((*TMemPage)(unsafe.Pointer(pPage)).FchildPtrSize)
/* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the
** number of cells on the page. */
(*TMemPage)(unsafe.Pointer(pPage)).FnCell = libc.Uint16FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up(data + 3)))<<libc.Int32FromInt32(8) | libc.Int32FromUint8(**(**Tu8)(__ccgo_up(data + 3 + 1))))
if uint32((*TMemPage)(unsafe.Pointer(pPage)).FnCell) > ((*TBtShared)(unsafe.Pointer(pBt)).FpageSize-uint32(8))/uint32(6) {
/* To many cells for a single page. The page must be corrupt */
return _sqlite3CorruptError(tls, int32(75475))
}
/* EVIDENCE-OF: R-24089-57979 If a page contains no cells (which is only
** possible for a root page of a table that contains no rows) then the
** offset to the cell content area will equal the page size minus the
** bytes of reserved space. */
(*TMemPage)(unsafe.Pointer(pPage)).FnFree = -int32(1) /* Indicate that this value is yet uncomputed */
(*TMemPage)(unsafe.Pointer(pPage)).FisInit = uint8(1)
if (*Tsqlite3)(unsafe.Pointer((*TBtShared)(unsafe.Pointer(pBt)).Fdb)).Fflags&uint64(SQLITE_CellSizeCk) != 0 {
return _btreeCellSizeCheck(tls, pPage)
}
return SQLITE_OK
}
// C documentation
//
// /*
// ** In this version of BtreeMoveto, pKey is a packed index record
// ** such as is generated by the OP_MakeRecord opcode. Unpack the
// ** record and then call sqlite3BtreeIndexMoveto() to do the work.
// */
func _btreeMoveto(tls *libc.TLS, pCur uintptr, pKey uintptr, nKey Ti64, bias int32, pRes uintptr) (r int32) {
var pIdxKey, pKeyInfo uintptr
var rc int32
_, _, _ = pIdxKey, pKeyInfo, rc /* Unpacked index key */
if pKey != 0 {
pKeyInfo = (*TBtCursor)(unsafe.Pointer(pCur)).FpKeyInfo
pIdxKey = _sqlite3VdbeAllocUnpackedRecord(tls, pKeyInfo)
if pIdxKey == uintptr(0) {
return int32(SQLITE_NOMEM)
}
_sqlite3VdbeRecordUnpack(tls, int32(nKey), pKey, pIdxKey)
if libc.Int32FromUint16((*TUnpackedRecord)(unsafe.Pointer(pIdxKey)).FnField) == 0 || libc.Int32FromUint16((*TUnpackedRecord)(unsafe.Pointer(pIdxKey)).FnField) > libc.Int32FromUint16((*TKeyInfo)(unsafe.Pointer(pKeyInfo)).FnAllField) {
rc = _sqlite3CorruptError(tls, int32(74103))
} else {
rc = _sqlite3BtreeIndexMoveto(tls, pCur, pIdxKey, pRes)
}
_sqlite3DbFree(tls, (*TKeyInfo)(unsafe.Pointer((*TBtCursor)(unsafe.Pointer(pCur)).FpKeyInfo)).Fdb, pIdxKey)
} else {
pIdxKey = uintptr(0)
rc = _sqlite3BtreeTableMoveto(tls, pCur, nKey, bias, pRes)
}
return rc
}
// C documentation
//
// /*
// ** Overwrite the cell that cursor pCur is pointing to with fresh content
// ** contained in pX.
// */
func _btreeOverwriteCell(tls *libc.TLS, pCur uintptr, pX uintptr) (r int32) {
var nTotal int32
var pPage uintptr
_, _ = nTotal, pPage
nTotal = (*TBtreePayload)(unsafe.Pointer(pX)).FnData + (*TBtreePayload)(unsafe.Pointer(pX)).FnZero /* Total bytes of to write */
pPage = (*TBtCursor)(unsafe.Pointer(pCur)).FpPage /* Page being written */
if (*TBtCursor)(unsafe.Pointer(pCur)).Finfo.FpPayload+uintptr((*TBtCursor)(unsafe.Pointer(pCur)).Finfo.FnLocal) > (*TMemPage)(unsafe.Pointer(pPage)).FaDataEnd || (*TBtCursor)(unsafe.Pointer(pCur)).Finfo.FpPayload < (*TMemPage)(unsafe.Pointer(pPage)).FaData+uintptr((*TMemPage)(unsafe.Pointer(pPage)).FcellOffset) {
return _sqlite3CorruptError(tls, int32(82592))
}
if libc.Int32FromUint16((*TBtCursor)(unsafe.Pointer(pCur)).Finfo.FnLocal) == nTotal {
/* The entire cell is local */
return _btreeOverwriteContent(tls, pPage, (*TBtCursor)(unsafe.Pointer(pCur)).Finfo.FpPayload, pX, 0, libc.Int32FromUint16((*TBtCursor)(unsafe.Pointer(pCur)).Finfo.FnLocal))
} else {
/* The cell contains overflow content */
return _btreeOverwriteOverflowCell(tls, pCur, pX)
}
return r
}
// C documentation
//
// /*
// ** Overwrite the cell that cursor pCur is pointing to with fresh content
// ** contained in pX. In this variant, pCur is pointing to an overflow
// ** cell.
// */
func _btreeOverwriteOverflowCell(tls *libc.TLS, pCur uintptr, pX uintptr) (r int32) {
bp := tls.Alloc(16)
defer tls.Free(16)
var iOffset, nTotal, rc int32
var ovflPageSize Tu32
var ovflPgno TPgno
var pBt uintptr
var _ /* pPage at bp+0 */ uintptr
_, _, _, _, _, _ = iOffset, nTotal, ovflPageSize, ovflPgno, pBt, rc /* Next byte of pX->pData to write */
nTotal = (*TBtreePayload)(unsafe.Pointer(pX)).FnData + (*TBtreePayload)(unsafe.Pointer(pX)).FnZero /* Return code */
**(**uintptr)(__ccgo_up(bp)) = (*TBtCursor)(unsafe.Pointer(pCur)).FpPage /* Size to write on overflow page */
/* pCur is an overflow cell */
/* Overwrite the local portion first */
rc = _btreeOverwriteContent(tls, **(**uintptr)(__ccgo_up(bp)), (*TBtCursor)(unsafe.Pointer(pCur)).Finfo.FpPayload, pX, 0, libc.Int32FromUint16((*TBtCursor)(unsafe.Pointer(pCur)).Finfo.FnLocal))
if rc != 0 {
return rc
}
/* Now overwrite the overflow pages */
iOffset = libc.Int32FromUint16((*TBtCursor)(unsafe.Pointer(pCur)).Finfo.FnLocal)
ovflPgno = _sqlite3Get4byte(tls, (*TBtCursor)(unsafe.Pointer(pCur)).Finfo.FpPayload+uintptr(iOffset))
pBt = (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FpBt
ovflPageSize = (*TBtShared)(unsafe.Pointer(pBt)).FusableSize - uint32(4)
for cond := true; cond; cond = iOffset < nTotal {
rc = _btreeGetPage(tls, pBt, ovflPgno, bp, 0)
if rc != 0 {
return rc
}
if _sqlite3PagerPageRefcount(tls, (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FpDbPage) != int32(1) || (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FisInit != 0 {
rc = _sqlite3CorruptError(tls, int32(82564))
} else {
if libc.Uint32FromInt32(iOffset)+ovflPageSize < libc.Uint32FromInt32(nTotal) {
ovflPgno = _sqlite3Get4byte(tls, (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FaData)
} else {
ovflPageSize = libc.Uint32FromInt32(nTotal - iOffset)
}
rc = _btreeOverwriteContent(tls, **(**uintptr)(__ccgo_up(bp)), (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FaData+uintptr(4), pX, iOffset, libc.Int32FromUint32(ovflPageSize))
}
_sqlite3PagerUnref(tls, (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FpDbPage)
if rc != 0 {
return rc
}
iOffset = libc.Int32FromUint32(uint32(iOffset) + ovflPageSize)
}
return SQLITE_OK
}
// C documentation
//
// /*
// ** Convert a DbPage obtained from the pager into a MemPage used by
// ** the btree layer.
// */
func _btreePageFromDbPage(tls *libc.TLS, pDbPage uintptr, pgno TPgno, pBt uintptr) (r uintptr) {
var pPage uintptr
var v1 int32
_, _ = pPage, v1
pPage = _sqlite3PagerGetExtra(tls, pDbPage)
if pgno != (*TMemPage)(unsafe.Pointer(pPage)).Fpgno {
(*TMemPage)(unsafe.Pointer(pPage)).FaData = _sqlite3PagerGetData(tls, pDbPage)
(*TMemPage)(unsafe.Pointer(pPage)).FpDbPage = pDbPage
(*TMemPage)(unsafe.Pointer(pPage)).FpBt = pBt
(*TMemPage)(unsafe.Pointer(pPage)).Fpgno = pgno
if pgno == uint32(1) {
v1 = int32(100)
} else {
v1 = 0
}
(*TMemPage)(unsafe.Pointer(pPage)).FhdrOffset = libc.Uint8FromInt32(v1)
}
return pPage
}
// C documentation
//
// /*
// ** The following routines are implementations of the MemPage.xParseCell()
// ** method.
// **
// ** Parse a cell content block and fill in the CellInfo structure.
// **
// ** btreeParseCellPtr() => table btree leaf nodes
// ** btreeParseCellNoPayload() => table btree internal nodes
// ** btreeParseCellPtrIndex() => index btree nodes
// **
// ** There is also a wrapper function btreeParseCell() that works for
// ** all MemPage types and that references the cell by index rather than
// ** by pointer.
// */
func _btreeParseCellPtrNoPayload(tls *libc.TLS, pPage uintptr, pCell uintptr, pInfo uintptr) {
_ = pPage
(*TCellInfo)(unsafe.Pointer(pInfo)).FnSize = libc.Uint16FromInt32(int32(4) + libc.Int32FromUint8(_sqlite3GetVarint(tls, pCell+4, pInfo)))
(*TCellInfo)(unsafe.Pointer(pInfo)).FnPayload = uint32(0)
(*TCellInfo)(unsafe.Pointer(pInfo)).FnLocal = uint16(0)
(*TCellInfo)(unsafe.Pointer(pInfo)).FpPayload = uintptr(0)
return
}
// C documentation
//
// /*
// ** Given a record with nPayload bytes of payload stored within btree
// ** page pPage, return the number of bytes of payload stored locally.
// */
func _btreePayloadToLocal(tls *libc.TLS, pPage uintptr, nPayload Ti64) (r int32) {
var maxLocal, minLocal, surplus, v1 int32
_, _, _, _ = maxLocal, minLocal, surplus, v1 /* Maximum amount of payload held locally */
maxLocal = libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FmaxLocal)
if nPayload <= int64(maxLocal) {
return int32(nPayload)
} else { /* Overflow payload available for local storage */
minLocal = libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FminLocal)
surplus = int32(int64(minLocal) + (nPayload-int64(minLocal))%libc.Int64FromUint32((*TBtShared)(unsafe.Pointer((*TMemPage)(unsafe.Pointer(pPage)).FpBt)).FusableSize-libc.Uint32FromInt32(4)))
if surplus <= maxLocal {
v1 = surplus
} else {
v1 = minLocal
}
return v1
}
return r
}
// C documentation
//
// /*
// ** Restore the cursor to the position it was in (or as close to as possible)
// ** when saveCursorPosition() was called. Note that this call deletes the
// ** saved position info stored by saveCursorPosition(), so there can be
// ** at most one effective restoreCursorPosition() call after each
// ** saveCursorPosition().
// */
func _btreeRestoreCursorPosition(tls *libc.TLS, pCur uintptr) (r int32) {
bp := tls.Alloc(16)
defer tls.Free(16)
var rc int32
var _ /* skipNext at bp+0 */ int32
_ = rc
**(**int32)(__ccgo_up(bp)) = 0
if libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCur)).FeState) == int32(CURSOR_FAULT) {
return (*TBtCursor)(unsafe.Pointer(pCur)).FskipNext
}
(*TBtCursor)(unsafe.Pointer(pCur)).FeState = uint8(CURSOR_INVALID)
if _sqlite3FaultSim(tls, int32(410)) != 0 {
rc = int32(SQLITE_IOERR)
} else {
rc = _btreeMoveto(tls, pCur, (*TBtCursor)(unsafe.Pointer(pCur)).FpKey, (*TBtCursor)(unsafe.Pointer(pCur)).FnKey, 0, bp)
}
if rc == SQLITE_OK {
Xsqlite3_free(tls, (*TBtCursor)(unsafe.Pointer(pCur)).FpKey)
(*TBtCursor)(unsafe.Pointer(pCur)).FpKey = uintptr(0)
if **(**int32)(__ccgo_up(bp)) != 0 {
(*TBtCursor)(unsafe.Pointer(pCur)).FskipNext = **(**int32)(__ccgo_up(bp))
}
if (*TBtCursor)(unsafe.Pointer(pCur)).FskipNext != 0 && libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCur)).FeState) == CURSOR_VALID {
(*TBtCursor)(unsafe.Pointer(pCur)).FeState = uint8(CURSOR_SKIPNEXT)
}
}
return rc
}
// C documentation
//
// /*
// ** Set the pBt->nPage field correctly, according to the current
// ** state of the database. Assume pBt->pPage1 is valid.
// */
func _btreeSetNPage(tls *libc.TLS, pBt uintptr, pPage1 uintptr) {
bp := tls.Alloc(16)
defer tls.Free(16)
var _ /* nPage at bp+0 */ int32
**(**int32)(__ccgo_up(bp)) = libc.Int32FromUint32(_sqlite3Get4byte(tls, (*TMemPage)(unsafe.Pointer(pPage1)).FaData+28))
if **(**int32)(__ccgo_up(bp)) == 0 {
_sqlite3PagerPagecount(tls, (*TBtShared)(unsafe.Pointer(pBt)).FpPager, bp)
}
(*TBtShared)(unsafe.Pointer(pBt)).FnPage = libc.Uint32FromInt32(**(**int32)(__ccgo_up(bp)))
}
// C documentation
//
// /*
// ** Implementation of the octet_length() function
// */
func _bytelengthFunc(tls *libc.TLS, context uintptr, argc int32, argv uintptr) {
var m Ti64
var v1 int32
_, _ = m, v1
_ = argc
switch Xsqlite3_value_type(tls, **(**uintptr)(__ccgo_up(argv))) {
case int32(SQLITE_BLOB):
Xsqlite3_result_int(tls, context, Xsqlite3_value_bytes(tls, **(**uintptr)(__ccgo_up(argv))))
case int32(SQLITE_INTEGER):
fallthrough
case int32(SQLITE_FLOAT):
if libc.Int32FromUint8((*Tsqlite3)(unsafe.Pointer(Xsqlite3_context_db_handle(tls, context))).Fenc) <= int32(SQLITE_UTF8) {
v1 = int32(1)
} else {
v1 = int32(2)
}
m = int64(v1)
Xsqlite3_result_int64(tls, context, int64(Xsqlite3_value_bytes(tls, **(**uintptr)(__ccgo_up(argv))))*m)
case int32(SQLITE_TEXT):
if Xsqlite3_value_encoding(tls, **(**uintptr)(__ccgo_up(argv))) <= int32(SQLITE_UTF8) {
Xsqlite3_result_int(tls, context, Xsqlite3_value_bytes(tls, **(**uintptr)(__ccgo_up(argv))))
} else {
Xsqlite3_result_int(tls, context, Xsqlite3_value_bytes16(tls, **(**uintptr)(__ccgo_up(argv))))
}
default:
Xsqlite3_result_null(tls, context)
break
}
}
// C documentation
//
// /*
// ** Return the N-dimensional volume of the cell stored in *p.
// */
func _cellArea(tls *libc.TLS, pRtree uintptr, p uintptr) (r TRtreeDValue) {
var area TRtreeDValue
_ = area
area = libc.Float64FromInt32(1)
if libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FeCoordType) == RTREE_COORD_REAL32 {
switch libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FnDim) {
case int32(5):
area = float64(*(*TRtreeValue)(unsafe.Pointer(p + 8 + 9*4)) - *(*TRtreeValue)(unsafe.Pointer(p + 8 + 8*4)))
fallthrough
case int32(4):
area = area * float64(*(*TRtreeValue)(unsafe.Pointer(p + 8 + 7*4))-*(*TRtreeValue)(unsafe.Pointer(p + 8 + 6*4)))
fallthrough
case int32(3):
area = area * float64(*(*TRtreeValue)(unsafe.Pointer(p + 8 + 5*4))-*(*TRtreeValue)(unsafe.Pointer(p + 8 + 4*4)))
fallthrough
case int32(2):
area = area * float64(*(*TRtreeValue)(unsafe.Pointer(p + 8 + 3*4))-*(*TRtreeValue)(unsafe.Pointer(p + 8 + 2*4)))
fallthrough
default:
area = area * float64(*(*TRtreeValue)(unsafe.Pointer(p + 8 + 1*4))-*(*TRtreeValue)(unsafe.Pointer(p + 8)))
}
} else {
switch libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FnDim) {
case int32(5):
area = float64(int64(*(*int32)(unsafe.Pointer(p + 8 + 9*4))) - int64(*(*int32)(unsafe.Pointer(p + 8 + 8*4))))
fallthrough
case int32(4):
area = area * float64(int64(*(*int32)(unsafe.Pointer(p + 8 + 7*4)))-int64(*(*int32)(unsafe.Pointer(p + 8 + 6*4))))
fallthrough
case int32(3):
area = area * float64(int64(*(*int32)(unsafe.Pointer(p + 8 + 5*4)))-int64(*(*int32)(unsafe.Pointer(p + 8 + 4*4))))
fallthrough
case int32(2):
area = area * float64(int64(*(*int32)(unsafe.Pointer(p + 8 + 3*4)))-int64(*(*int32)(unsafe.Pointer(p + 8 + 2*4))))
fallthrough
default:
area = area * float64(int64(*(*int32)(unsafe.Pointer(p + 8 + 1*4)))-int64(*(*int32)(unsafe.Pointer(p + 8))))
}
}
return area
}
// C documentation
//
// /*
// ** Return true if the area covered by p2 is a subset of the area covered
// ** by p1. False otherwise.
// */
func _cellContains(tls *libc.TLS, pRtree uintptr, p1 uintptr, p2 uintptr) (r int32) {
var a1, a11, a2, a21 uintptr
var ii int32
_, _, _, _, _ = a1, a11, a2, a21, ii
if libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FeCoordType) == int32(RTREE_COORD_INT32) {
ii = 0
for {
if !(ii < libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FnDim2)) {
break
}
a1 = p1 + 8 + uintptr(ii)*4
a2 = p2 + 8 + uintptr(ii)*4
if *(*int32)(unsafe.Pointer(a2)) < *(*int32)(unsafe.Pointer(a1)) || *(*int32)(unsafe.Pointer(a2 + 1*4)) > *(*int32)(unsafe.Pointer(a1 + 1*4)) {
return 0
}
goto _1
_1:
;
ii = ii + int32(2)
}
} else {
ii = 0
for {
if !(ii < libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FnDim2)) {
break
}
a11 = p1 + 8 + uintptr(ii)*4
a21 = p2 + 8 + uintptr(ii)*4
if *(*TRtreeValue)(unsafe.Pointer(a21)) < *(*TRtreeValue)(unsafe.Pointer(a11)) || *(*TRtreeValue)(unsafe.Pointer(a21 + 1*4)) > *(*TRtreeValue)(unsafe.Pointer(a11 + 1*4)) {
return 0
}
goto _2
_2:
;
ii = ii + int32(2)
}
}
return int32(1)
}
// C documentation
//
// /*
// ** Return the margin length of cell p. The margin length is the sum
// ** of the objects size in each dimension.
// */
func _cellMargin(tls *libc.TLS, pRtree uintptr, p uintptr) (r TRtreeDValue) {
var ii int32
var margin TRtreeDValue
var v1, v2 float64
_, _, _, _ = ii, margin, v1, v2
margin = libc.Float64FromInt32(0)
ii = libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FnDim2) - int32(2)
for cond := true; cond; cond = ii >= 0 {
if libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FeCoordType) == RTREE_COORD_REAL32 {
v1 = float64(*(*TRtreeValue)(unsafe.Pointer(p + 8 + uintptr(ii+int32(1))*4)))
} else {
v1 = float64(*(*int32)(unsafe.Pointer(p + 8 + uintptr(ii+int32(1))*4)))
}
if libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FeCoordType) == RTREE_COORD_REAL32 {
v2 = float64(*(*TRtreeValue)(unsafe.Pointer(p + 8 + uintptr(ii)*4)))
} else {
v2 = float64(*(*int32)(unsafe.Pointer(p + 8 + uintptr(ii)*4)))
}
margin = margin + (v1 - v2)
ii = ii - int32(2)
}
return margin
}
// C documentation
//
// /*
// ** Store the union of cells p1 and p2 in p1.
// */
func _cellUnion(tls *libc.TLS, pRtree uintptr, p1 uintptr, p2 uintptr) {
var ii, v3 int32
var v1 TRtreeValue
_, _, _ = ii, v1, v3
ii = 0
if libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FeCoordType) == RTREE_COORD_REAL32 {
for cond := true; cond; cond = ii < libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FnDim2) {
if *(*TRtreeValue)(unsafe.Pointer(p1 + 8 + uintptr(ii)*4)) < *(*TRtreeValue)(unsafe.Pointer(p2 + 8 + uintptr(ii)*4)) {
v1 = *(*TRtreeValue)(unsafe.Pointer(p1 + 8 + uintptr(ii)*4))
} else {
v1 = *(*TRtreeValue)(unsafe.Pointer(p2 + 8 + uintptr(ii)*4))
}
*(*TRtreeValue)(unsafe.Pointer(p1 + 8 + uintptr(ii)*4)) = v1
if *(*TRtreeValue)(unsafe.Pointer(p1 + 8 + uintptr(ii+int32(1))*4)) > *(*TRtreeValue)(unsafe.Pointer(p2 + 8 + uintptr(ii+int32(1))*4)) {
v1 = *(*TRtreeValue)(unsafe.Pointer(p1 + 8 + uintptr(ii+int32(1))*4))
} else {
v1 = *(*TRtreeValue)(unsafe.Pointer(p2 + 8 + uintptr(ii+int32(1))*4))
}
*(*TRtreeValue)(unsafe.Pointer(p1 + 8 + uintptr(ii+int32(1))*4)) = v1
ii = ii + int32(2)
}
} else {
for cond := true; cond; cond = ii < libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FnDim2) {
if *(*int32)(unsafe.Pointer(p1 + 8 + uintptr(ii)*4)) < *(*int32)(unsafe.Pointer(p2 + 8 + uintptr(ii)*4)) {
v3 = *(*int32)(unsafe.Pointer(p1 + 8 + uintptr(ii)*4))
} else {
v3 = *(*int32)(unsafe.Pointer(p2 + 8 + uintptr(ii)*4))
}
*(*int32)(unsafe.Pointer(p1 + 8 + uintptr(ii)*4)) = v3
if *(*int32)(unsafe.Pointer(p1 + 8 + uintptr(ii+int32(1))*4)) > *(*int32)(unsafe.Pointer(p2 + 8 + uintptr(ii+int32(1))*4)) {
v3 = *(*int32)(unsafe.Pointer(p1 + 8 + uintptr(ii+int32(1))*4))
} else {
v3 = *(*int32)(unsafe.Pointer(p2 + 8 + uintptr(ii+int32(1))*4))
}
*(*int32)(unsafe.Pointer(p1 + 8 + uintptr(ii+int32(1))*4)) = v3
ii = ii + int32(2)
}
}
}
// C documentation
//
// /*
// ** If the TEMP database is open, close it and mark the database schema
// ** as needing reloading. This must be done when using the SQLITE_TEMP_STORE
// ** or DEFAULT_TEMP_STORE pragmas.
// */
func _changeTempStorage(tls *libc.TLS, pParse uintptr, zStorageType uintptr) (r int32) {
var db uintptr
var ts int32
_, _ = db, ts
ts = _getTempStore(tls, zStorageType)
db = (*TParse)(unsafe.Pointer(pParse)).Fdb
if libc.Int32FromUint8((*Tsqlite3)(unsafe.Pointer(db)).Ftemp_store) == ts {
return SQLITE_OK
}
if _invalidateTempStorage(tls, pParse) != SQLITE_OK {
return int32(SQLITE_ERROR)
}
(*Tsqlite3)(unsafe.Pointer(db)).Ftemp_store = libc.Uint8FromInt32(ts)
return SQLITE_OK
}
// C documentation
//
// /*
// ** Close all file descriptors accumulated in the unixInodeInfo->pUnused list.
// */
func _closePendingFds(tls *libc.TLS, pFile uintptr) {
var p, pInode, pNext uintptr
_, _, _ = p, pInode, pNext
pInode = (*TunixFile)(unsafe.Pointer(pFile)).FpInode
p = (*TunixInodeInfo)(unsafe.Pointer(pInode)).FpUnused
for {
if !(p != 0) {
break
}
pNext = (*TUnixUnusedFd)(unsafe.Pointer(p)).FpNext
_robust_close(tls, pFile, (*TUnixUnusedFd)(unsafe.Pointer(p)).Ffd, int32(41675))
Xsqlite3_free(tls, p)
goto _1
_1:
;
p = pNext
}
(*TunixInodeInfo)(unsafe.Pointer(pInode)).FpUnused = uintptr(0)
}
// C documentation
//
// /*
// ** Generate code for a comparison operator.
// */
func _codeCompare(tls *libc.TLS, pParse uintptr, pLeft uintptr, pRight uintptr, opcode int32, in1 int32, in2 int32, dest int32, jumpIfNull int32, isCommuted int32) (r int32) {
var addr, p5 int32
var p4 uintptr
_, _, _ = addr, p4, p5
if (*TParse)(unsafe.Pointer(pParse)).FnErr != 0 {
return 0
}
if isCommuted != 0 {
p4 = _sqlite3BinaryCompareCollSeq(tls, pParse, pRight, pLeft)
} else {
p4 = _sqlite3BinaryCompareCollSeq(tls, pParse, pLeft, pRight)
}
p5 = libc.Int32FromUint8(_binaryCompareP5(tls, pLeft, pRight, jumpIfNull))
addr = _sqlite3VdbeAddOp4(tls, (*TParse)(unsafe.Pointer(pParse)).FpVdbe, opcode, in2, dest, in1, p4, -int32(2))
_sqlite3VdbeChangeP5(tls, (*TParse)(unsafe.Pointer(pParse)).FpVdbe, libc.Uint16FromInt32(p5))
return addr
}
// C documentation
//
// /*
// ** Generate code for a single equality term of the WHERE clause. An equality
// ** term can be either X=expr or X IN (...). pTerm is the term to be
// ** coded.
// **
// ** The current value for the constraint is left in a register, the index
// ** of which is returned. An attempt is made store the result in iTarget but
// ** this is only guaranteed for TK_ISNULL and TK_IN constraints. If the
// ** constraint is a TK_EQ or TK_IS, then the current value might be left in
// ** some other register and it is the caller's responsibility to compensate.
// **
// ** For a constraint of the form X=expr, the expression is evaluated in
// ** straight-line code. For constraints of the form X IN (...)
// ** this routine sets up a loop that will iterate over all values of X.
// */
func _codeEqualityTerm(tls *libc.TLS, pParse uintptr, pTerm uintptr, pLevel uintptr, iEq int32, bRev int32, iTarget int32) (r int32) {
var iReg int32
var pX uintptr
_, _ = iReg, pX
pX = (*TWhereTerm)(unsafe.Pointer(pTerm)).FpExpr /* Register holding results */
if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pX)).Fop) == int32(TK_EQ) || libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pX)).Fop) == int32(TK_IS) {
iReg = _sqlite3ExprCodeTarget(tls, pParse, (*TExpr)(unsafe.Pointer(pX)).FpRight, iTarget)
} else {
if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pX)).Fop) == int32(TK_ISNULL) {
iReg = iTarget
_sqlite3VdbeAddOp2(tls, (*TParse)(unsafe.Pointer(pParse)).FpVdbe, int32(OP_Null), 0, iReg)
} else {
iReg = iTarget
_codeINTerm(tls, pParse, pTerm, pLevel, iEq, bRev, iTarget)
}
}
/* As an optimization, try to disable the WHERE clause term that is
** driving the index as it will always be true. The correct answer is
** obtained regardless, but we might get the answer with fewer CPU cycles
** by omitting the term.
**
** But do not disable the term unless we are certain that the term is
** not a transitive constraint. For an example of where that does not
** work, see https://sqlite.org/forum/forumpost/eb8613976a (2021-05-04)
*/
if (*TWhereLoop)(unsafe.Pointer((*TWhereLevel)(unsafe.Pointer(pLevel)).FpWLoop)).FwsFlags&uint32(WHERE_TRANSCONS) == uint32(0) || libc.Int32FromUint16((*TWhereTerm)(unsafe.Pointer(pTerm)).FeOperator)&int32(WO_EQUIV) == 0 {
_disableTerm(tls, pLevel, pTerm)
}
return iReg
}
// C documentation
//
// /*
// ** pMem currently only holds a string type (or maybe a BLOB that we can
// ** interpret as a string if we want to). Compute its corresponding
// ** numeric type, if has one. Set the pMem->u.r and pMem->u.i fields
// ** accordingly.
// */
func _computeNumericType(tls *libc.TLS, pMem uintptr) (r Tu16) {
bp := tls.Alloc(16)
defer tls.Free(16)
var rc, v1 int32
var _ /* ix at bp+0 */ Tsqlite3_int64
_, _ = rc, v1
if libc.Int32FromUint16((*TMem)(unsafe.Pointer(pMem)).Fflags)&int32(MEM_Zero) != 0 {
v1 = _sqlite3VdbeMemExpandBlob(tls, pMem)
} else {
v1 = 0
}
if v1 != 0 {
*(*Ti64)(unsafe.Pointer(pMem)) = 0
return uint16(MEM_Int)
}
rc = _sqlite3MemRealValueRC(tls, pMem, pMem)
if rc <= 0 {
if rc&int32(2) == 0 && _sqlite3Atoi64(tls, (*TMem)(unsafe.Pointer(pMem)).Fz, bp, (*TMem)(unsafe.Pointer(pMem)).Fn, (*TMem)(unsafe.Pointer(pMem)).Fenc) <= int32(1) {
*(*Ti64)(unsafe.Pointer(pMem)) = **(**Tsqlite3_int64)(__ccgo_up(bp))
return uint16(MEM_Int)
} else {
return uint16(MEM_Real)
}
} else {
if rc&int32(2) == 0 && _sqlite3Atoi64(tls, (*TMem)(unsafe.Pointer(pMem)).Fz, bp, (*TMem)(unsafe.Pointer(pMem)).Fn, (*TMem)(unsafe.Pointer(pMem)).Fenc) == 0 {
*(*Ti64)(unsafe.Pointer(pMem)) = **(**Tsqlite3_int64)(__ccgo_up(bp))
return uint16(MEM_Int)
}
}
return uint16(MEM_Real)
}
// C documentation
//
// /*
// ** idxNum:
// **
// ** 0 schema=main, full table scan
// ** 1 schema=main, pgno=?1
// ** 2 schema=?1, full table scan
// ** 3 schema=?1, pgno=?2
// */
func _dbpageBestIndex(tls *libc.TLS, tab uintptr, pIdxInfo uintptr) (r int32) {
var i, iPlan, v3 int32
var p, p1 uintptr
_, _, _, _, _ = i, iPlan, p, p1, v3
iPlan = 0
_ = tab
/* If there is a schema= constraint, it must be honored. Report a
** ridiculously large estimated cost if the schema= constraint is
** unavailable
*/
i = 0
for {
if !(i < (*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FnConstraint) {
break
}
p = (*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraint + uintptr(i)*12
if (*Tsqlite3_index_constraint)(unsafe.Pointer(p)).FiColumn != int32(DBPAGE_COLUMN_SCHEMA) {
goto _1
}
if libc.Int32FromUint8((*Tsqlite3_index_constraint)(unsafe.Pointer(p)).Fop) != int32(SQLITE_INDEX_CONSTRAINT_EQ) {
goto _1
}
if !((*Tsqlite3_index_constraint)(unsafe.Pointer(p)).Fusable != 0) {
/* No solution. */
return int32(SQLITE_CONSTRAINT)
}
iPlan = int32(2)
(**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraintUsage + uintptr(i)*8))).FargvIndex = int32(1)
(**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraintUsage + uintptr(i)*8))).Fomit = uint8(1)
break
goto _1
_1:
;
i = i + 1
}
/* If we reach this point, it means that either there is no schema=
** constraint (in which case we use the "main" schema) or else the
** schema constraint was accepted. Lower the estimated cost accordingly
*/
(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FestimatedCost = float64(1e+06)
/* Check for constraints against pgno */
i = 0
for {
if !(i < (*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FnConstraint) {
break
}
p1 = (*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraint + uintptr(i)*12
if (*Tsqlite3_index_constraint)(unsafe.Pointer(p1)).Fusable != 0 && (*Tsqlite3_index_constraint)(unsafe.Pointer(p1)).FiColumn <= 0 && libc.Int32FromUint8((*Tsqlite3_index_constraint)(unsafe.Pointer(p1)).Fop) == int32(SQLITE_INDEX_CONSTRAINT_EQ) {
(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FestimatedRows = int64(1)
(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FidxFlags = int32(SQLITE_INDEX_SCAN_UNIQUE)
(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FestimatedCost = float64(1)
if iPlan != 0 {
v3 = int32(2)
} else {
v3 = int32(1)
}
(**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraintUsage + uintptr(i)*8))).FargvIndex = v3
(**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraintUsage + uintptr(i)*8))).Fomit = uint8(1)
iPlan = iPlan | int32(1)
break
}
goto _2
_2:
;
i = i + 1
}
(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FidxNum = iPlan
if (*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FnOrderBy >= int32(1) && (**(**Tsqlite3_index_orderby)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaOrderBy))).FiColumn <= 0 && libc.Int32FromUint8((**(**Tsqlite3_index_orderby)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaOrderBy))).Fdesc) == 0 {
(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).ForderByConsumed = int32(1)
}
return SQLITE_OK
}
func _dbpageRowid(tls *libc.TLS, pCursor uintptr, pRowid uintptr) (r int32) {
var pCsr uintptr
_ = pCsr
pCsr = pCursor
**(**Tsqlite_int64)(__ccgo_up(pRowid)) = libc.Int64FromUint32((*TDbpageCursor)(unsafe.Pointer(pCsr)).Fpgno)
return SQLITE_OK
}
// C documentation
//
// /*
// ** Delete the cell at index iCell of node pNode. After removing the
// ** cell, adjust the r-tree data structure if required.
// */
func _deleteCell(tls *libc.TLS, pRtree uintptr, pNode uintptr, iCell int32, iHeight int32) (r int32) {
var pParent uintptr
var rc, v1 int32
_, _, _ = pParent, rc, v1
v1 = _fixLeafParent(tls, pRtree, pNode)
rc = v1
if SQLITE_OK != v1 {
return rc
}
/* Remove the cell from the node. This call just moves bytes around
** the in-memory node image, so it cannot fail.
*/
_nodeDeleteCell(tls, pRtree, pNode, iCell)
/* If the node is not the tree root and now has less than the minimum
** number of cells, remove it from the tree. Otherwise, update the
** cell in the parent node so that it tightly contains the updated
** node.
*/
pParent = (*TRtreeNode)(unsafe.Pointer(pNode)).FpParent
if pParent != 0 {
if _readInt16(tls, (*TRtreeNode)(unsafe.Pointer(pNode)).FzData+2) < ((*TRtree)(unsafe.Pointer(pRtree)).FiNodeSize-int32(4))/libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FnBytesPerCell)/int32(3) {
rc = _removeNode(tls, pRtree, pNode, iHeight)
} else {
rc = _fixBoundingBox(tls, pRtree, pNode)
}
}
return rc
}
// C documentation
//
// /*
// ** Write VDBE code to erase table pTab and all associated indices on disk.
// ** Code to update the sqlite_schema tables and internal schema definitions
// ** in case a root-page belonging to another table is moved by the btree layer
// ** is also added (this can happen with an auto-vacuum database).
// */
func _destroyTable(tls *libc.TLS, pParse uintptr, pTab uintptr) {
var iDb int32
var iDestroyed, iIdx, iLargest, iTab TPgno
var pIdx uintptr
_, _, _, _, _, _ = iDb, iDestroyed, iIdx, iLargest, iTab, pIdx
/* If the database may be auto-vacuum capable (if SQLITE_OMIT_AUTOVACUUM
** is not defined), then it is important to call OP_Destroy on the
** table and index root-pages in order, starting with the numerically
** largest root-page number. This guarantees that none of the root-pages
** to be destroyed is relocated by an earlier OP_Destroy. i.e. if the
** following were coded:
**
** OP_Destroy 4 0
** ...
** OP_Destroy 5 0
**
** and root page 5 happened to be the largest root-page number in the
** database, then root page 5 would be moved to page 4 by the
** "OP_Destroy 4 0" opcode. The subsequent "OP_Destroy 5 0" would hit
** a free-list page.
*/
iTab = (*TTable)(unsafe.Pointer(pTab)).Ftnum
iDestroyed = uint32(0)
for int32(1) != 0 {
iLargest = uint32(0)
if iDestroyed == uint32(0) || iTab < iDestroyed {
iLargest = iTab
}
pIdx = (*TTable)(unsafe.Pointer(pTab)).FpIndex
for {
if !(pIdx != 0) {
break
}
iIdx = (*TIndex)(unsafe.Pointer(pIdx)).Ftnum
if (iDestroyed == uint32(0) || iIdx < iDestroyed) && iIdx > iLargest {
iLargest = iIdx
}
goto _1
_1:
;
pIdx = (*TIndex)(unsafe.Pointer(pIdx)).FpNext
}
if iLargest == uint32(0) {
return
} else {
iDb = _sqlite3SchemaToIndex(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, (*TTable)(unsafe.Pointer(pTab)).FpSchema)
_destroyRootPage(tls, pParse, libc.Int32FromUint32(iLargest), iDb)
iDestroyed = iLargest
}
}
}
// C documentation
//
// /*
// ** This routine checks if there is a RESERVED lock held on the specified
// ** file by this or any other process. If the caller holds a SHARED
// ** or greater lock when it is called, then it is assumed that no other
// ** client may hold RESERVED. Or, if the caller holds no lock, then it
// ** is assumed another client holds RESERVED if the lock-file exists.
// */
func _dotlockCheckReservedLock(tls *libc.TLS, id uintptr, pResOut uintptr) (r int32) {
var pFile uintptr
_ = pFile
pFile = id
if libc.Int32FromUint8((*TunixFile)(unsafe.Pointer(pFile)).FeFileLock) >= int32(SHARED_LOCK) {
**(**int32)(__ccgo_up(pResOut)) = 0
} else {
**(**int32)(__ccgo_up(pResOut)) = libc.BoolInt32((*(*func(*libc.TLS, uintptr, int32) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(2)].FpCurrent})))(tls, (*TunixFile)(unsafe.Pointer(pFile)).FlockingContext, 0) == 0)
}
return SQLITE_OK
}
var _dotlockIoFinder = uintptr(0)
func _dotlockIoFinderImpl(tls *libc.TLS, z uintptr, p uintptr) (r uintptr) {
_ = z
_ = p
return uintptr(unsafe.Pointer(&_dotlockIoMethods))
}
var _dotlockIoMethods = Tsqlite3_io_methods{
FiVersion: int32(1),
}
// C documentation
//
// /*
// ** Estimate the logarithm of the input value to base 2.
// */
func _estLog(tls *libc.TLS, N TLogEst) (r TLogEst) {
var v1 int32
_ = v1
if int32(N) <= int32(10) {
v1 = 0
} else {
v1 = int32(_sqlite3LogEst(tls, libc.Uint64FromInt16(N))) - int32(33)
}
return int16(v1)
}
// C documentation
//
// /*
// ** If expression pExpr is of type TK_SELECT, generate code to evaluate
// ** it. Return the register in which the result is stored (or, if the
// ** sub-select returns more than one column, the first in an array
// ** of registers in which the result is stored).
// **
// ** If pExpr is not a TK_SELECT expression, return 0.
// */
func _exprCodeSubselect(tls *libc.TLS, pParse uintptr, pExpr uintptr) (r int32) {
var reg int32
_ = reg
reg = 0
if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) == int32(TK_SELECT) {
reg = _sqlite3CodeSubselect(tls, pParse, pExpr)
}
return reg
}
// C documentation
//
// /*
// ** Generate code that evaluates an AND or OR operator leaving a
// ** boolean result in a register. pExpr is the AND/OR expression.
// ** Store the result in the "target" register. Use short-circuit
// ** evaluation to avoid computing both operands, if possible.
// **
// ** The code generated might require the use of a temporary register.
// ** If it does, then write the number of that temporary register
// ** into *pTmpReg. If not, leave *pTmpReg unchanged.
// */
func _exprCodeTargetAndOr(tls *libc.TLS, pParse uintptr, pExpr uintptr, target int32, pTmpReg uintptr) (r int32) {
var addrSkip, op, r1, r2, regSS, skipOp, v1 int32
var pAlt, v uintptr
_, _, _, _, _, _, _, _, _ = addrSkip, op, pAlt, r1, r2, regSS, skipOp, v, v1 /* Branch instruction that skips one of the operands */
regSS = 0 /* statement being coded */
op = libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop)
v = (*TParse)(unsafe.Pointer(pParse)).FpVdbe
pAlt = _sqlite3ExprSimplifiedAndOr(tls, pExpr)
if pAlt != pExpr {
r1 = _sqlite3ExprCodeTarget(tls, pParse, pAlt, target)
_sqlite3VdbeAddOp3(tls, v, int32(OP_And), r1, r1, target)
return target
}
if op == int32(TK_AND) {
v1 = int32(OP_IfNot)
} else {
v1 = int32(OP_If)
}
skipOp = v1
if _exprEvalRhsFirst(tls, pExpr) != 0 {
/* Compute the right operand first. Skip the computation of the left
** operand if the right operand fully determines the result */
v1 = _sqlite3ExprCodeTarget(tls, pParse, (*TExpr)(unsafe.Pointer(pExpr)).FpRight, target)
regSS = v1
r2 = v1
addrSkip = _sqlite3VdbeAddOp1(tls, v, skipOp, r2)
r1 = _sqlite3ExprCodeTemp(tls, pParse, (*TExpr)(unsafe.Pointer(pExpr)).FpLeft, pTmpReg)
} else {
/* Compute the left operand first */
r1 = _sqlite3ExprCodeTarget(tls, pParse, (*TExpr)(unsafe.Pointer(pExpr)).FpLeft, target)
if (*TExpr)(unsafe.Pointer((*TExpr)(unsafe.Pointer(pExpr)).FpRight)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_Subquery)) != uint32(0) {
/* Skip over the computation of the right operand if the right
** operand is a subquery and the left operand completely determines
** the result */
regSS = r1
addrSkip = _sqlite3VdbeAddOp1(tls, v, skipOp, r1)
} else {
v1 = libc.Int32FromInt32(0)
regSS = v1
addrSkip = v1
}
r2 = _sqlite3ExprCodeTemp(tls, pParse, (*TExpr)(unsafe.Pointer(pExpr)).FpRight, pTmpReg)
}
_sqlite3VdbeAddOp3(tls, v, op, r2, r1, target)
if addrSkip != 0 {
_sqlite3VdbeAddOp2(tls, v, int32(OP_Goto), 0, _sqlite3VdbeCurrentAddr(tls, v)+int32(2))
_sqlite3VdbeJumpHere(tls, v, addrSkip)
_sqlite3VdbeAddOp3(tls, v, int32(OP_Or), regSS, regSS, target)
}
return target
}
// C documentation
//
// /*
// ** Commute a comparison operator. Expressions of the form "X op Y"
// ** are converted into "Y op X".
// */
func _exprCommute(tls *libc.TLS, pParse uintptr, pExpr uintptr) (r Tu16) {
var t uintptr
_ = t
if libc.Int32FromUint8((*TExpr)(unsafe.Pointer((*TExpr)(unsafe.Pointer(pExpr)).FpLeft)).Fop) == int32(TK_VECTOR) || libc.Int32FromUint8((*TExpr)(unsafe.Pointer((*TExpr)(unsafe.Pointer(pExpr)).FpRight)).Fop) == int32(TK_VECTOR) || _sqlite3BinaryCompareCollSeq(tls, pParse, (*TExpr)(unsafe.Pointer(pExpr)).FpLeft, (*TExpr)(unsafe.Pointer(pExpr)).FpRight) != _sqlite3BinaryCompareCollSeq(tls, pParse, (*TExpr)(unsafe.Pointer(pExpr)).FpRight, (*TExpr)(unsafe.Pointer(pExpr)).FpLeft) {
**(**Tu32)(__ccgo_up(pExpr + 4)) ^= uint32(EP_Commuted)
}
t = (*TExpr)(unsafe.Pointer(pExpr)).FpRight
(*TExpr)(unsafe.Pointer(pExpr)).FpRight = (*TExpr)(unsafe.Pointer(pExpr)).FpLeft
(*TExpr)(unsafe.Pointer(pExpr)).FpLeft = t
if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) >= int32(TK_GT) {
(*TExpr)(unsafe.Pointer(pExpr)).Fop = libc.Uint8FromInt32(libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) - int32(TK_GT) ^ int32(2) + int32(TK_GT))
}
return uint16(0)
}
// C documentation
//
// /*
// ** Expression pVar is guaranteed to be an SQL variable. pExpr may be any
// ** type of expression.
// **
// ** If pExpr is a simple SQL value - an integer, real, string, blob
// ** or NULL value - then the VDBE currently being prepared is configured
// ** to re-prepare each time a new value is bound to variable pVar.
// **
// ** Additionally, if pExpr is a simple SQL value and the value is the
// ** same as that currently bound to variable pVar, non-zero is returned.
// ** Otherwise, if the values are not the same or if pExpr is not a simple
// ** SQL value, zero is returned.
// **
// ** If the SQLITE_EnableQPSG flag is set on the database connection, then
// ** this routine always returns false.
// */
func _exprCompareVariable(tls *libc.TLS, pParse uintptr, pVar uintptr, pExpr uintptr) (r int32) {
bp := tls.Alloc(16)
defer tls.Free(16)
var iVar, res, v1 int32
var pL uintptr
var _ /* pR at bp+0 */ uintptr
_, _, _, _ = iVar, pL, res, v1
res = int32(2)
**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) == int32(TK_VARIABLE) && int32((*TExpr)(unsafe.Pointer(pVar)).FiColumn) == int32((*TExpr)(unsafe.Pointer(pExpr)).FiColumn) {
return 0
}
if (*Tsqlite3)(unsafe.Pointer((*TParse)(unsafe.Pointer(pParse)).Fdb)).Fflags&uint64(SQLITE_EnableQPSG) != uint64(0) {
return int32(2)
}
_sqlite3ValueFromExpr(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, pExpr, uint8(SQLITE_UTF8), uint8(SQLITE_AFF_BLOB), bp)
if **(**uintptr)(__ccgo_up(bp)) != 0 {
iVar = int32((*TExpr)(unsafe.Pointer(pVar)).FiColumn)
_sqlite3VdbeSetVarmask(tls, (*TParse)(unsafe.Pointer(pParse)).FpVdbe, iVar)
pL = _sqlite3VdbeGetBoundValue(tls, (*TParse)(unsafe.Pointer(pParse)).FpReprepare, iVar, uint8(SQLITE_AFF_BLOB))
if pL != 0 {
if Xsqlite3_value_type(tls, pL) == int32(SQLITE_TEXT) {
Xsqlite3_value_text(tls, pL) /* Make sure the encoding is UTF-8 */
}
if _sqlite3MemCompare(tls, pL, **(**uintptr)(__ccgo_up(bp)), uintptr(0)) != 0 {
v1 = int32(2)
} else {
v1 = 0
}
res = v1
}
_sqlite3ValueFree(tls, **(**uintptr)(__ccgo_up(bp)))
_sqlite3ValueFree(tls, pL)
}
return res
}
// C documentation
//
// /*
// ** Compute the two operands of a binary operator.
// **
// ** If either operand contains a subquery, then the code strives to
// ** compute the operand containing the subquery second. If the other
// ** operand evalutes to NULL, then a jump is made. The address of the
// ** IsNull operand that does this jump is returned. The caller can use
// ** this to optimize the computation so as to avoid doing the potentially
// ** expensive subquery.
// **
// ** If no optimization opportunities exist, return 0.
// */
func _exprComputeOperands(tls *libc.TLS, pParse uintptr, pExpr uintptr, pR1 uintptr, pR2 uintptr, pFree1 uintptr, pFree2 uintptr) (r int32) {
var addrIsNull, r1, r2 int32
var v uintptr
_, _, _, _ = addrIsNull, r1, r2, v
v = (*TParse)(unsafe.Pointer(pParse)).FpVdbe
/*
** If the left operand contains a (possibly expensive) subquery and the
** right operand does not and the right operation might be NULL,
** then compute the right operand first and do an IsNull jump if the
** right operand evalutes to NULL.
*/
if _exprEvalRhsFirst(tls, pExpr) != 0 && _sqlite3ExprCanBeNull(tls, (*TExpr)(unsafe.Pointer(pExpr)).FpRight) != 0 {
r2 = _sqlite3ExprCodeTemp(tls, pParse, (*TExpr)(unsafe.Pointer(pExpr)).FpRight, pFree2)
addrIsNull = _sqlite3VdbeAddOp1(tls, v, int32(OP_IsNull), r2)
} else {
r2 = 0 /* Silence a false-positive uninit-var warning in MSVC */
addrIsNull = 0
}
r1 = _sqlite3ExprCodeTemp(tls, pParse, (*TExpr)(unsafe.Pointer(pExpr)).FpLeft, pFree1)
if addrIsNull == 0 {
/*
** If the right operand contains a subquery and the left operand does not
** and the left operand might be NULL, then do an IsNull check
** check on the left operand before computing the right operand.
*/
if (*TExpr)(unsafe.Pointer((*TExpr)(unsafe.Pointer(pExpr)).FpRight)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_Subquery)) != uint32(0) && _sqlite3ExprCanBeNull(tls, (*TExpr)(unsafe.Pointer(pExpr)).FpLeft) != 0 {
addrIsNull = _sqlite3VdbeAddOp1(tls, v, int32(OP_IsNull), r1)
}
r2 = _sqlite3ExprCodeTemp(tls, pParse, (*TExpr)(unsafe.Pointer(pExpr)).FpRight, pFree2)
}
**(**int32)(__ccgo_up(pR1)) = r1
**(**int32)(__ccgo_up(pR2)) = r2
return addrIsNull
}
// C documentation
//
// /*
// ** Return true if it might be advantageous to compute the right operand
// ** of expression pExpr first, before the left operand.
// **
// ** Normally the left operand is computed before the right operand. But if
// ** the left operand contains a subquery and the right does not, then it
// ** might be more efficient to compute the right operand first.
// */
func _exprEvalRhsFirst(tls *libc.TLS, pExpr uintptr) (r int32) {
if (*TExpr)(unsafe.Pointer((*TExpr)(unsafe.Pointer(pExpr)).FpLeft)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_Subquery)) != uint32(0) && !((*TExpr)(unsafe.Pointer((*TExpr)(unsafe.Pointer(pExpr)).FpRight)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_Subquery)) != libc.Uint32FromInt32(0)) {
return int32(1)
} else {
return 0
}
return r
}
// C documentation
//
// /*
// ** Helper function for exprIsDeterministic().
// */
func _exprNodeIsDeterministic(tls *libc.TLS, pWalker uintptr, pExpr uintptr) (r int32) {
if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) == int32(TK_FUNCTION) && libc.BoolInt32((*TExpr)(unsafe.Pointer(pExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_ConstFunc)) != uint32(0)) == 0 {
(*TWalker)(unsafe.Pointer(pWalker)).FeCode = uint16(0)
return int32(WRC_Abort)
}
return WRC_Continue
}
// C documentation
//
// /*
// ** The database opened by the first argument is an auto-vacuum database
// ** nOrig pages in size containing nFree free pages. Return the expected
// ** size of the database in pages following an auto-vacuum operation.
// */
func _finalDbSize(tls *libc.TLS, pBt uintptr, nOrig TPgno, nFree TPgno) (r TPgno) {
var nEntry int32
var nFin, nPtrmap TPgno
_, _, _ = nEntry, nFin, nPtrmap /* Return value */
nEntry = libc.Int32FromUint32((*TBtShared)(unsafe.Pointer(pBt)).FusableSize / uint32(5))
nPtrmap = (nFree - nOrig + _ptrmapPageno(tls, pBt, nOrig) + libc.Uint32FromInt32(nEntry)) / libc.Uint32FromInt32(nEntry)
nFin = nOrig - nFree - nPtrmap
if nOrig > libc.Uint32FromInt32(_sqlite3PendingByte)/(*TBtShared)(unsafe.Pointer(pBt)).FpageSize+libc.Uint32FromInt32(1) && nFin < libc.Uint32FromInt32(_sqlite3PendingByte)/(*TBtShared)(unsafe.Pointer(pBt)).FpageSize+libc.Uint32FromInt32(1) {
nFin = nFin - 1
}
for _ptrmapPageno(tls, pBt, nFin) == nFin || nFin == libc.Uint32FromInt32(_sqlite3PendingByte)/(*TBtShared)(unsafe.Pointer(pBt)).FpageSize+libc.Uint32FromInt32(1) {
nFin = nFin - 1
}
return nFin
}
// C documentation
//
// /*
// ** Find all terms of COLUMN=VALUE or VALUE=COLUMN in pExpr where VALUE
// ** is a constant expression and where the term must be true because it
// ** is part of the AND-connected terms of the expression. For each term
// ** found, add it to the pConst structure.
// */
func _findConstInWhere(tls *libc.TLS, pConst uintptr, pExpr uintptr) {
var pLeft, pRight uintptr
_, _ = pLeft, pRight
if pExpr == uintptr(0) {
return
}
if (*TExpr)(unsafe.Pointer(pExpr)).Fflags&(*TWhereConst)(unsafe.Pointer(pConst)).FmExcludeOn != uint32(0) {
return
}
if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) == int32(TK_AND) {
_findConstInWhere(tls, pConst, (*TExpr)(unsafe.Pointer(pExpr)).FpRight)
_findConstInWhere(tls, pConst, (*TExpr)(unsafe.Pointer(pExpr)).FpLeft)
return
}
if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) != int32(TK_EQ) {
return
}
pRight = (*TExpr)(unsafe.Pointer(pExpr)).FpRight
pLeft = (*TExpr)(unsafe.Pointer(pExpr)).FpLeft
if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pRight)).Fop) == int32(TK_COLUMN) && _sqlite3ExprIsConstant(tls, (*TWhereConst)(unsafe.Pointer(pConst)).FpParse, pLeft) != 0 {
_constInsert(tls, pConst, pRight, pLeft, pExpr)
}
if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pLeft)).Fop) == int32(TK_COLUMN) && _sqlite3ExprIsConstant(tls, (*TWhereConst)(unsafe.Pointer(pConst)).FpParse, pRight) != 0 {
_constInsert(tls, pConst, pLeft, pRight, pExpr)
}
}
// C documentation
//
// /*
// ** This routine runs after codeDistinct(). It makes necessary
// ** adjustments to the OP_OpenEphemeral opcode that the codeDistinct()
// ** routine made use of. This processing must be done separately since
// ** sometimes codeDistinct is called before the OP_OpenEphemeral is actually
// ** laid down.
// **
// ** WHERE_DISTINCT_NOOP:
// ** WHERE_DISTINCT_UNORDERED:
// **
// ** No adjustments necessary. This function is a no-op.
// **
// ** WHERE_DISTINCT_UNIQUE:
// **
// ** The ephemeral table is not needed. So change the
// ** OP_OpenEphemeral opcode into an OP_Noop.
// **
// ** WHERE_DISTINCT_ORDERED:
// **
// ** The ephemeral table is not needed. But we do need register
// ** iVal to be initialized to NULL. So change the OP_OpenEphemeral
// ** into an OP_Null on the iVal register.
// */
func _fixDistinctOpenEph(tls *libc.TLS, pParse uintptr, eTnctType int32, iVal int32, iOpenEphAddr int32) {
var pOp, v uintptr
_, _ = pOp, v
if (*TParse)(unsafe.Pointer(pParse)).FnErr == 0 && (eTnctType == int32(WHERE_DISTINCT_UNIQUE) || eTnctType == int32(WHERE_DISTINCT_ORDERED)) {
v = (*TParse)(unsafe.Pointer(pParse)).FpVdbe
_sqlite3VdbeChangeToNoop(tls, v, iOpenEphAddr)
if libc.Int32FromUint8((*TVdbeOp)(unsafe.Pointer(_sqlite3VdbeGetOp(tls, v, iOpenEphAddr+int32(1)))).Fopcode) == int32(OP_Explain) {
_sqlite3VdbeChangeToNoop(tls, v, iOpenEphAddr+int32(1))
}
if eTnctType == int32(WHERE_DISTINCT_ORDERED) {
/* Change the OP_OpenEphemeral to an OP_Null that sets the MEM_Cleared
** bit on the first register of the previous value. This will cause the
** OP_Ne added in codeDistinct() to always fail on the first iteration of
** the loop even if the first row is all NULLs. */
pOp = _sqlite3VdbeGetOp(tls, v, iOpenEphAddr)
(*TVdbeOp)(unsafe.Pointer(pOp)).Fopcode = uint8(OP_Null)
(*TVdbeOp)(unsafe.Pointer(pOp)).Fp1 = int32(1)
(*TVdbeOp)(unsafe.Pointer(pOp)).Fp2 = iVal
}
}
}
// C documentation
//
// /*
// ** This function is called when a row is inserted into or deleted from the
// ** child table of foreign key constraint pFKey. If an SQL UPDATE is executed
// ** on the child table of pFKey, this function is invoked twice for each row
// ** affected - once to "delete" the old row, and then again to "insert" the
// ** new row.
// **
// ** Each time it is called, this function generates VDBE code to locate the
// ** row in the parent table that corresponds to the row being inserted into
// ** or deleted from the child table. If the parent row can be found, no
// ** special action is taken. Otherwise, if the parent row can *not* be
// ** found in the parent table:
// **
// ** Operation | FK type | Action taken
// ** --------------------------------------------------------------------------
// ** INSERT immediate Increment the "immediate constraint counter".
// **
// ** DELETE immediate Decrement the "immediate constraint counter".
// **
// ** INSERT deferred Increment the "deferred constraint counter".
// **
// ** DELETE deferred Decrement the "deferred constraint counter".
// **
// ** These operations are identified in the comment at the top of this file
// ** (fkey.c) as "I.1" and "D.1".
// */
func _fkLookupParent(tls *libc.TLS, pParse uintptr, iDb int32, pTab uintptr, pIdx uintptr, pFKey uintptr, aiCol uintptr, regData int32, nIncr int32, isIgnore int32) {
var i, iChild, iCur, iJump, iMustBeInt, iOk, iParent, iReg, nCol, regTemp, regTemp1 int32
var v uintptr
_, _, _, _, _, _, _, _, _, _, _, _ = i, iChild, iCur, iJump, iMustBeInt, iOk, iParent, iReg, nCol, regTemp, regTemp1, v /* Iterator variable */
v = _sqlite3GetVdbe(tls, pParse) /* Vdbe to add code to */
iCur = (*TParse)(unsafe.Pointer(pParse)).FnTab - int32(1) /* Cursor number to use */
iOk = _sqlite3VdbeMakeLabel(tls, pParse) /* jump here if parent key found */
/* If nIncr is less than zero, then check at runtime if there are any
** outstanding constraints to resolve. If there are not, there is no need
** to check if deleting this row resolves any outstanding violations.
**
** Check if any of the key columns in the child table row are NULL. If
** any are, then the constraint is considered satisfied. No need to
** search for a matching row in the parent table. */
if nIncr < 0 {
_sqlite3VdbeAddOp2(tls, v, int32(OP_FkIfZero), libc.Int32FromUint8((*TFKey)(unsafe.Pointer(pFKey)).FisDeferred), iOk)
}
i = 0
for {
if !(i < (*TFKey)(unsafe.Pointer(pFKey)).FnCol) {
break
}
iReg = int32(_sqlite3TableColumnToStorage(tls, (*TFKey)(unsafe.Pointer(pFKey)).FpFrom, int16(**(**int32)(__ccgo_up(aiCol + uintptr(i)*4))))) + regData + int32(1)
_sqlite3VdbeAddOp2(tls, v, int32(OP_IsNull), iReg, iOk)
goto _1
_1:
;
i = i + 1
}
if isIgnore == 0 {
if pIdx == uintptr(0) { /* Address of MustBeInt instruction */
regTemp = _sqlite3GetTempReg(tls, pParse)
/* Invoke MustBeInt to coerce the child key value to an integer (i.e.
** apply the affinity of the parent key). If this fails, then there
** is no matching parent key. Before using MustBeInt, make a copy of
** the value. Otherwise, the value inserted into the child key column
** will have INTEGER affinity applied to it, which may not be correct. */
_sqlite3VdbeAddOp2(tls, v, int32(OP_SCopy), int32(_sqlite3TableColumnToStorage(tls, (*TFKey)(unsafe.Pointer(pFKey)).FpFrom, int16(**(**int32)(__ccgo_up(aiCol)))))+int32(1)+regData, regTemp)
iMustBeInt = _sqlite3VdbeAddOp2(tls, v, int32(OP_MustBeInt), regTemp, 0)
/* If the parent table is the same as the child table, and we are about
** to increment the constraint-counter (i.e. this is an INSERT operation),
** then check if the row being inserted matches itself. If so, do not
** increment the constraint-counter. */
if pTab == (*TFKey)(unsafe.Pointer(pFKey)).FpFrom && nIncr == int32(1) {
_sqlite3VdbeAddOp3(tls, v, int32(OP_Eq), regData, iOk, regTemp)
_sqlite3VdbeChangeP5(tls, v, uint16(SQLITE_NOTNULL))
}
_sqlite3OpenTable(tls, pParse, iCur, iDb, pTab, int32(OP_OpenRead))
_sqlite3VdbeAddOp3(tls, v, int32(OP_NotExists), iCur, 0, regTemp)
_sqlite3VdbeGoto(tls, v, iOk)
_sqlite3VdbeJumpHere(tls, v, _sqlite3VdbeCurrentAddr(tls, v)-int32(2))
_sqlite3VdbeJumpHere(tls, v, iMustBeInt)
_sqlite3ReleaseTempReg(tls, pParse, regTemp)
} else {
nCol = (*TFKey)(unsafe.Pointer(pFKey)).FnCol
regTemp1 = _sqlite3GetTempRange(tls, pParse, nCol)
_sqlite3VdbeAddOp3(tls, v, int32(OP_OpenRead), iCur, libc.Int32FromUint32((*TIndex)(unsafe.Pointer(pIdx)).Ftnum), iDb)
_sqlite3VdbeSetP4KeyInfo(tls, pParse, pIdx)
i = 0
for {
if !(i < nCol) {
break
}
_sqlite3VdbeAddOp2(tls, v, int32(OP_Copy), int32(_sqlite3TableColumnToStorage(tls, (*TFKey)(unsafe.Pointer(pFKey)).FpFrom, int16(**(**int32)(__ccgo_up(aiCol + uintptr(i)*4)))))+int32(1)+regData, regTemp1+i)
goto _2
_2:
;
i = i + 1
}
/* If the parent table is the same as the child table, and we are about
** to increment the constraint-counter (i.e. this is an INSERT operation),
** then check if the row being inserted matches itself. If so, do not
** increment the constraint-counter.
**
** If any of the parent-key values are NULL, then the row cannot match
** itself. So set JUMPIFNULL to make sure we do the OP_Found if any
** of the parent-key values are NULL (at this point it is known that
** none of the child key values are).
*/
if pTab == (*TFKey)(unsafe.Pointer(pFKey)).FpFrom && nIncr == int32(1) {
iJump = _sqlite3VdbeCurrentAddr(tls, v) + nCol + int32(1)
i = 0
for {
if !(i < nCol) {
break
}
iChild = int32(_sqlite3TableColumnToStorage(tls, (*TFKey)(unsafe.Pointer(pFKey)).FpFrom, int16(**(**int32)(__ccgo_up(aiCol + uintptr(i)*4))))) + int32(1) + regData
iParent = int32(1) + regData
iParent = iParent + int32(_sqlite3TableColumnToStorage(tls, (*TIndex)(unsafe.Pointer(pIdx)).FpTable, **(**Ti16)(__ccgo_up((*TIndex)(unsafe.Pointer(pIdx)).FaiColumn + uintptr(i)*2))))
if int32(**(**Ti16)(__ccgo_up((*TIndex)(unsafe.Pointer(pIdx)).FaiColumn + uintptr(i)*2))) == int32((*TTable)(unsafe.Pointer(pTab)).FiPKey) {
/* The parent key is a composite key that includes the IPK column */
iParent = regData
}
_sqlite3VdbeAddOp3(tls, v, int32(OP_Ne), iChild, iJump, iParent)
_sqlite3VdbeChangeP5(tls, v, uint16(SQLITE_JUMPIFNULL))
goto _3
_3:
;
i = i + 1
}
_sqlite3VdbeGoto(tls, v, iOk)
}
_sqlite3VdbeAddOp4(tls, v, int32(OP_Affinity), regTemp1, nCol, 0, _sqlite3IndexAffinityStr(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, pIdx), nCol)
_sqlite3VdbeAddOp4Int(tls, v, int32(OP_Found), iCur, iOk, regTemp1, nCol)
_sqlite3ReleaseTempRange(tls, pParse, regTemp1, nCol)
}
}
if !((*TFKey)(unsafe.Pointer(pFKey)).FisDeferred != 0) && !((*Tsqlite3)(unsafe.Pointer((*TParse)(unsafe.Pointer(pParse)).Fdb)).Fflags&libc.Uint64FromInt32(SQLITE_DeferFKs) != 0) && !((*TParse)(unsafe.Pointer(pParse)).FpToplevel != 0) && !((*TParse)(unsafe.Pointer(pParse)).FisMultiWrite != 0) {
/* Special case: If this is an INSERT statement that will insert exactly
** one row into the table, raise a constraint immediately instead of
** incrementing a counter. This is necessary as the VM code is being
** generated for will not open a statement transaction. */
_sqlite3HaltConstraint(tls, pParse, libc.Int32FromInt32(SQLITE_CONSTRAINT)|libc.Int32FromInt32(3)<<libc.Int32FromInt32(8), int32(OE_Abort), uintptr(0), int8(-libc.Int32FromInt32(1)), uint8(P5_ConstraintFK))
} else {
if nIncr > 0 && libc.Int32FromUint8((*TFKey)(unsafe.Pointer(pFKey)).FisDeferred) == 0 {
_sqlite3MayAbort(tls, pParse)
}
_sqlite3VdbeAddOp2(tls, v, int32(OP_FkCounter), libc.Int32FromUint8((*TFKey)(unsafe.Pointer(pFKey)).FisDeferred), nIncr)
}
_sqlite3VdbeResolveLabel(tls, v, iOk)
_sqlite3VdbeAddOp1(tls, v, int32(OP_Close), iCur)
}
func _fts5ApiPhraseNextColumn(tls *libc.TLS, pCtx uintptr, pIter uintptr, piCol uintptr) {
bp := tls.Alloc(16)
defer tls.Free(16)
var pConfig, pCsr uintptr
var _ /* dummy at bp+4 */ int32
var _ /* iIncr at bp+0 */ int32
_, _ = pConfig, pCsr
pCsr = pCtx
pConfig = (*TFts5Table)(unsafe.Pointer((*TFts5Cursor)(unsafe.Pointer(pCsr)).Fbase.FpVtab)).FpConfig
if (*TFts5Config)(unsafe.Pointer(pConfig)).FeDetail == int32(FTS5_DETAIL_COLUMNS) {
if (*TFts5PhraseIter)(unsafe.Pointer(pIter)).Fa >= (*TFts5PhraseIter)(unsafe.Pointer(pIter)).Fb {
**(**int32)(__ccgo_up(piCol)) = -int32(1)
} else {
**(**uintptr)(__ccgo_up(pIter)) += uintptr(_sqlite3Fts5GetVarint32(tls, (*TFts5PhraseIter)(unsafe.Pointer(pIter)).Fa, bp))
**(**int32)(__ccgo_up(piCol)) += **(**int32)(__ccgo_up(bp)) - int32(2)
}
} else {
for int32(1) != 0 {
if (*TFts5PhraseIter)(unsafe.Pointer(pIter)).Fa >= (*TFts5PhraseIter)(unsafe.Pointer(pIter)).Fb {
**(**int32)(__ccgo_up(piCol)) = -int32(1)
return
}
if libc.Int32FromUint8(**(**uint8)(__ccgo_up((*TFts5PhraseIter)(unsafe.Pointer(pIter)).Fa))) == int32(0x01) {
break
}
**(**uintptr)(__ccgo_up(pIter)) += uintptr(_sqlite3Fts5GetVarint32(tls, (*TFts5PhraseIter)(unsafe.Pointer(pIter)).Fa, bp+4))
}
**(**uintptr)(__ccgo_up(pIter)) += uintptr(int32(1) + _sqlite3Fts5GetVarint32(tls, (*TFts5PhraseIter)(unsafe.Pointer(pIter)).Fa+1, piCol))
}
}
func _fts5DlidxExtractFirstRowid(tls *libc.TLS, pBuf uintptr) (r Ti64) {
bp := tls.Alloc(16)
defer tls.Free(16)
var iOff int32
var _ /* iRowid at bp+0 */ Ti64
_ = iOff
iOff = int32(1) + libc.Int32FromUint8(_sqlite3Fts5GetVarint(tls, (*TFts5Buffer)(unsafe.Pointer(pBuf)).Fp+1, bp))
_sqlite3Fts5GetVarint(tls, (*TFts5Buffer)(unsafe.Pointer(pBuf)).Fp+uintptr(iOff), bp)
return **(**Ti64)(__ccgo_up(bp))
}
func _fts5ExprSynonymAdvanceto(tls *libc.TLS, pTerm uintptr, bDesc int32, piLast uintptr, pRc uintptr) (r int32) {
bp := tls.Alloc(16)
defer tls.Free(16)
var iLast, iRowid Ti64
var p uintptr
var rc int32
var _ /* bEof at bp+0 */ int32
_, _, _, _ = iLast, iRowid, p, rc
rc = SQLITE_OK
iLast = **(**Ti64)(__ccgo_up(piLast))
**(**int32)(__ccgo_up(bp)) = 0
p = pTerm
for {
if !(rc == SQLITE_OK && p != 0) {
break
}
if libc.Int32FromUint8((*TFts5IndexIter)(unsafe.Pointer((*TFts5ExprTerm)(unsafe.Pointer(p)).FpIter)).FbEof) == 0 {
iRowid = (*TFts5IndexIter)(unsafe.Pointer((*TFts5ExprTerm)(unsafe.Pointer(p)).FpIter)).FiRowid
if bDesc == 0 && iLast > iRowid || bDesc != 0 && iLast < iRowid {
rc = _sqlite3Fts5IterNextFrom(tls, (*TFts5ExprTerm)(unsafe.Pointer(p)).FpIter, iLast)
}
}
goto _1
_1:
;
p = (*TFts5ExprTerm)(unsafe.Pointer(p)).FpSynonym
}
if rc != SQLITE_OK {
**(**int32)(__ccgo_up(pRc)) = rc
**(**int32)(__ccgo_up(bp)) = int32(1)
} else {
**(**Ti64)(__ccgo_up(piLast)) = _fts5ExprSynonymRowid(tls, pTerm, bDesc, bp)
}
return **(**int32)(__ccgo_up(bp))
}
// C documentation
//
// /*
// ** Argument pTerm must be a synonym iterator. Return the current rowid
// ** that it points to.
// */
func _fts5ExprSynonymRowid(tls *libc.TLS, pTerm uintptr, bDesc int32, pbEof uintptr) (r Ti64) {
var bRetValid int32
var iRet, iRowid Ti64
var p uintptr
_, _, _, _ = bRetValid, iRet, iRowid, p
iRet = 0
bRetValid = 0
p = pTerm
for {
if !(p != 0) {
break
}
if 0 == libc.Int32FromUint8((*TFts5IndexIter)(unsafe.Pointer((*TFts5ExprTerm)(unsafe.Pointer(p)).FpIter)).FbEof) {
iRowid = (*TFts5IndexIter)(unsafe.Pointer((*TFts5ExprTerm)(unsafe.Pointer(p)).FpIter)).FiRowid
if bRetValid == 0 || bDesc != libc.BoolInt32(iRowid < iRet) {
iRet = iRowid
bRetValid = int32(1)
}
}
goto _1
_1:
;
p = (*TFts5ExprTerm)(unsafe.Pointer(p)).FpSynonym
}
if pbEof != 0 && bRetValid == 0 {
**(**int32)(__ccgo_up(pbEof)) = int32(1)
}
return iRet
}
// C documentation
//
// /*
// ** Argument p points to a buffer containing a varint to be interpreted as a
// ** position list size field. Read the varint and return the number of bytes
// ** read. Before returning, set *pnSz to the number of bytes in the position
// ** list, and *pbDel to true if the delete flag is set, or false otherwise.
// */
func _fts5GetPoslistSize(tls *libc.TLS, p uintptr, pnSz uintptr, pbDel uintptr) (r int32) {
bp := tls.Alloc(16)
defer tls.Free(16)
var n, v1 int32
var _ /* nSz at bp+0 */ int32
_, _ = n, v1
n = 0
v1 = n
n = n + 1
**(**int32)(__ccgo_up(bp)) = libc.Int32FromUint8(**(**Tu8)(__ccgo_up(p + uintptr(v1))))
if **(**int32)(__ccgo_up(bp))&int32(0x80) != 0 {
n = n - 1
n = n + _sqlite3Fts5GetVarint32(tls, p+uintptr(n), bp)
}
**(**int32)(__ccgo_up(pnSz)) = **(**int32)(__ccgo_up(bp)) / int32(2)
**(**int32)(__ccgo_up(pbDel)) = **(**int32)(__ccgo_up(bp)) & int32(0x0001)
return n
}
func _fts5GetU16(tls *libc.TLS, aIn uintptr) (r Tu16) {
return libc.Uint16FromInt32(libc.Int32FromUint16(uint16(**(**Tu8)(__ccgo_up(aIn))))<<int32(8) + libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aIn + 1))))
}
func _fts5HashKey(tls *libc.TLS, nSlot int32, p uintptr, n int32) (r uint32) {
var h uint32
var i int32
_, _ = h, i
h = uint32(13)
i = n - int32(1)
for {
if !(i >= 0) {
break
}
h = h<<int32(3) ^ h ^ uint32(**(**Tu8)(__ccgo_up(p + uintptr(i))))
goto _1
_1:
;
i = i - 1
}
return h % libc.Uint32FromInt32(nSlot)
}
func _fts5HashKey2(tls *libc.TLS, nSlot int32, b Tu8, p uintptr, n int32) (r uint32) {
var h uint32
var i int32
_, _ = h, i
h = uint32(13)
i = n - int32(1)
for {
if !(i >= 0) {
break
}
h = h<<int32(3) ^ h ^ uint32(**(**Tu8)(__ccgo_up(p + uintptr(i))))
goto _1
_1:
;
i = i - 1
}
h = h<<int32(3) ^ h ^ uint32(b)
return h % libc.Uint32FromInt32(nSlot)
}
// C documentation
//
// /*
// ** Check that:
// **
// ** 1) All leaves of pSeg between iFirst and iLast (inclusive) exist and
// ** contain zero terms.
// ** 2) All leaves of pSeg between iNoRowid and iLast (inclusive) exist and
// ** contain zero rowids.
// */
func _fts5IndexIntegrityCheckEmpty(tls *libc.TLS, p uintptr, pSeg uintptr, iFirst int32, iNoRowid int32, iLast int32) {
var i int32
var pLeaf uintptr
_, _ = i, pLeaf
/* Now check that the iter.nEmpty leaves following the current leaf
** (a) exist and (b) contain no terms. */
i = iFirst
for {
if !((*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK && i <= iLast) {
break
}
pLeaf = _fts5DataRead(tls, p, int64((*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FiSegid)<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B)+libc.Int32FromInt32(FTS5_DATA_DLI_B))+int64(libc.Int32FromInt32(0))<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B))+int64(libc.Int32FromInt32(0))<<libc.Int32FromInt32(FTS5_DATA_PAGE_B)+int64(i))
if pLeaf != 0 {
if !((*TFts5Data)(unsafe.Pointer(pLeaf)).FszLeaf >= (*TFts5Data)(unsafe.Pointer(pLeaf)).Fnn) || i >= iNoRowid && 0 != libc.Int32FromUint16(_fts5GetU16(tls, (*TFts5Data)(unsafe.Pointer(pLeaf)).Fp)) {
_fts5IndexCorruptRowid(tls, p, int64((*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FiSegid)<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B)+libc.Int32FromInt32(FTS5_DATA_DLI_B))+int64(libc.Int32FromInt32(0))<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B))+int64(libc.Int32FromInt32(0))<<libc.Int32FromInt32(FTS5_DATA_PAGE_B)+int64(i))
}
}
_fts5DataRelease(tls, pLeaf)
goto _1
_1:
;
i = i + 1
}
}
func _fts5IndexPrepareStmt(tls *libc.TLS, p uintptr, ppStmt uintptr, zSql uintptr) (r int32) {
var rc, v1 int32
_, _ = rc, v1
if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
if zSql != 0 {
rc = Xsqlite3_prepare_v3(tls, (*TFts5Config)(unsafe.Pointer((*TFts5Index)(unsafe.Pointer(p)).FpConfig)).Fdb, zSql, -int32(1), libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_PREPARE_PERSISTENT)|libc.Int32FromInt32(SQLITE_PREPARE_NO_VTAB)), ppStmt, uintptr(0))
/* If this prepare() call fails with SQLITE_ERROR, then one of the
** %_idx or %_data tables has been removed or modified. Call this
** corruption. */
if rc == int32(SQLITE_ERROR) {
v1 = int32(SQLITE_CORRUPT)
} else {
v1 = rc
}
(*TFts5Index)(unsafe.Pointer(p)).Frc = v1
} else {
(*TFts5Index)(unsafe.Pointer(p)).Frc = int32(SQLITE_NOMEM)
}
}
Xsqlite3_free(tls, zSql)
return (*TFts5Index)(unsafe.Pointer(p)).Frc
}
// C documentation
//
// /*
// ** Buffer pPg contains a page of a tombstone hash table - one of nPg pages
// ** associated with the same segment. This function adds rowid iRowid to
// ** the hash table. The caller is required to guarantee that there is at
// ** least one free slot on the page.
// **
// ** If parameter bForce is false and the hash table is deemed to be full
// ** (more than half of the slots are occupied), then non-zero is returned
// ** and iRowid not inserted. Or, if bForce is true or if the hash table page
// ** is not full, iRowid is inserted and zero returned.
// */
func _fts5IndexTombstoneAddToPage(tls *libc.TLS, pPg uintptr, bForce int32, nPg int32, iRowid Tu64) (r int32) {
var aSlot, aSlot1 uintptr
var iSlot, nCollide, nElem, nSlot, szKey, v1, v2, v3 int32
_, _, _, _, _, _, _, _, _, _ = aSlot, aSlot1, iSlot, nCollide, nElem, nSlot, szKey, v1, v2, v3
if libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TFts5Data)(unsafe.Pointer(pPg)).Fp))) == int32(4) {
v1 = int32(4)
} else {
v1 = int32(8)
}
szKey = v1
if (*TFts5Data)(unsafe.Pointer(pPg)).Fnn > int32(16) {
if libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TFts5Data)(unsafe.Pointer(pPg)).Fp))) == int32(4) {
v3 = int32(4)
} else {
v3 = int32(8)
}
v2 = ((*TFts5Data)(unsafe.Pointer(pPg)).Fnn - int32(8)) / v3
} else {
v2 = int32(1)
}
nSlot = v2
nElem = libc.Int32FromUint32(_fts5GetU32(tls, (*TFts5Data)(unsafe.Pointer(pPg)).Fp+4))
iSlot = libc.Int32FromUint64(iRowid / libc.Uint64FromInt32(nPg) % libc.Uint64FromInt32(nSlot))
nCollide = nSlot
if szKey == int32(4) && iRowid > uint64(0xFFFFFFFF) {
return int32(2)
}
if iRowid == uint64(0) {
**(**Tu8)(__ccgo_up((*TFts5Data)(unsafe.Pointer(pPg)).Fp + 1)) = uint8(0x01)
return 0
}
if bForce == 0 && nElem >= nSlot/int32(2) {
return int32(1)
}
_fts5PutU32(tls, (*TFts5Data)(unsafe.Pointer(pPg)).Fp+4, libc.Uint32FromInt32(nElem+int32(1)))
if szKey == int32(4) {
aSlot = (*TFts5Data)(unsafe.Pointer(pPg)).Fp + 8
for **(**Tu32)(__ccgo_up(aSlot + uintptr(iSlot)*4)) != 0 {
iSlot = (iSlot + int32(1)) % nSlot
v1 = nCollide
nCollide = nCollide - 1
if v1 == 0 {
return 0
}
}
_fts5PutU32(tls, aSlot+uintptr(iSlot)*4, uint32(iRowid))
} else {
aSlot1 = (*TFts5Data)(unsafe.Pointer(pPg)).Fp + 8
for **(**Tu64)(__ccgo_up(aSlot1 + uintptr(iSlot)*8)) != 0 {
iSlot = (iSlot + int32(1)) % nSlot
v1 = nCollide
nCollide = nCollide - 1
if v1 == 0 {
return 0
}
}
_fts5PutU64(tls, aSlot1+uintptr(iSlot)*8, iRowid)
}
return 0
}
// C documentation
//
// /*
// ** Query a single tombstone hash table for rowid iRowid. Return true if
// ** it is found or false otherwise. The tombstone hash table is one of
// ** nHashTable tables.
// */
func _fts5IndexTombstoneQuery(tls *libc.TLS, pHash uintptr, nHashTable int32, iRowid Tu64) (r int32) {
var aSlot, aSlot1 uintptr
var iSlot, nCollide, nSlot, szKey, v1, v2, v3 int32
_, _, _, _, _, _, _, _, _ = aSlot, aSlot1, iSlot, nCollide, nSlot, szKey, v1, v2, v3
if libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TFts5Data)(unsafe.Pointer(pHash)).Fp))) == int32(4) {
v1 = int32(4)
} else {
v1 = int32(8)
}
szKey = v1
if (*TFts5Data)(unsafe.Pointer(pHash)).Fnn > int32(16) {
if libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TFts5Data)(unsafe.Pointer(pHash)).Fp))) == int32(4) {
v3 = int32(4)
} else {
v3 = int32(8)
}
v2 = ((*TFts5Data)(unsafe.Pointer(pHash)).Fnn - int32(8)) / v3
} else {
v2 = int32(1)
}
nSlot = v2
iSlot = libc.Int32FromUint64(iRowid / libc.Uint64FromInt32(nHashTable) % libc.Uint64FromInt32(nSlot))
nCollide = nSlot
if iRowid == uint64(0) {
return libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TFts5Data)(unsafe.Pointer(pHash)).Fp + 1)))
} else {
if szKey == int32(4) {
aSlot = (*TFts5Data)(unsafe.Pointer(pHash)).Fp + 8
for **(**Tu32)(__ccgo_up(aSlot + uintptr(iSlot)*4)) != 0 {
if uint64(_fts5GetU32(tls, aSlot+uintptr(iSlot)*4)) == iRowid {
return int32(1)
}
v1 = nCollide
nCollide = nCollide - 1
if v1 == 0 {
break
}
iSlot = (iSlot + int32(1)) % nSlot
}
} else {
aSlot1 = (*TFts5Data)(unsafe.Pointer(pHash)).Fp + 8
for **(**Tu64)(__ccgo_up(aSlot1 + uintptr(iSlot)*8)) != 0 {
if _fts5GetU64(tls, aSlot1+uintptr(iSlot)*8) == iRowid {
return int32(1)
}
v1 = nCollide
nCollide = nCollide - 1
if v1 == 0 {
break
}
iSlot = (iSlot + int32(1)) % nSlot
}
}
}
return 0
}
func _fts5NextRowid(tls *libc.TLS, pBuf uintptr, piOff uintptr, piRowid uintptr) {
bp := tls.Alloc(16)
defer tls.Free(16)
var i int32
var v1 uintptr
var _ /* iVal at bp+0 */ Tu64
_, _ = i, v1
i = **(**int32)(__ccgo_up(piOff))
if i >= (*TFts5Buffer)(unsafe.Pointer(pBuf)).Fn {
**(**int32)(__ccgo_up(piOff)) = -int32(1)
} else {
**(**int32)(__ccgo_up(piOff)) = i + libc.Int32FromUint8(_sqlite3Fts5GetVarint(tls, (*TFts5Buffer)(unsafe.Pointer(pBuf)).Fp+uintptr(i), bp))
v1 = piRowid
*(*Ti64)(unsafe.Pointer(v1)) = Ti64(uint64(*(*Ti64)(unsafe.Pointer(v1))) + **(**Tu64)(__ccgo_up(bp)))
}
}
func _fts5ParseAlloc(tls *libc.TLS, t Tu64) (r uintptr) {
return Xsqlite3_malloc64(tls, libc.Uint64FromInt64(libc.Int64FromUint64(t)))
}
// C documentation
//
// /*
// ** Return the size of the prefix, in bytes, that buffer
// ** (pNew/<length-unknown>) shares with buffer (pOld/nOld).
// **
// ** Buffer (pNew/<length-unknown>) is guaranteed to be greater
// ** than buffer (pOld/nOld).
// */
func _fts5PrefixCompress(tls *libc.TLS, nOld int32, pOld uintptr, pNew uintptr) (r int32) {
var i int32
_ = i
i = 0
for {
if !(i < nOld) {
break
}
if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(pOld + uintptr(i)))) != libc.Int32FromUint8(**(**Tu8)(__ccgo_up(pNew + uintptr(i)))) {
break
}
goto _1
_1:
;
i = i + 1
}
return i
}
func _fts5PutU16(tls *libc.TLS, aOut uintptr, iVal Tu16) {
**(**Tu8)(__ccgo_up(aOut)) = libc.Uint8FromInt32(libc.Int32FromUint16(iVal) >> libc.Int32FromInt32(8))
**(**Tu8)(__ccgo_up(aOut + 1)) = libc.Uint8FromInt32(libc.Int32FromUint16(iVal) & libc.Int32FromInt32(0xFF))
}
// C documentation
//
// /*
// ** Fts5SegIter.iLeafOffset currently points to the first byte of a
// ** position-list size field. Read the value of the field and store it
// ** in the following variables:
// **
// ** Fts5SegIter.nPos
// ** Fts5SegIter.bDel
// **
// ** Leave Fts5SegIter.iLeafOffset pointing to the first byte of the
// ** position list content (if any).
// */
func _fts5SegIterLoadNPos(tls *libc.TLS, p uintptr, pIter uintptr) {
bp := tls.Alloc(16)
defer tls.Free(16)
var iEod, iOff, v1 int32
var _ /* nSz at bp+0 */ int32
_, _, _ = iEod, iOff, v1
if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
iOff = int32((*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafOffset) /* Offset to read at */
if (*TFts5Config)(unsafe.Pointer((*TFts5Index)(unsafe.Pointer(p)).FpConfig)).FeDetail == int32(FTS5_DETAIL_NONE) {
if (*TFts5SegIter)(unsafe.Pointer(pIter)).FiEndofDoclist < (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).FszLeaf {
v1 = (*TFts5SegIter)(unsafe.Pointer(pIter)).FiEndofDoclist
} else {
v1 = (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).FszLeaf
}
iEod = v1
(*TFts5SegIter)(unsafe.Pointer(pIter)).FbDel = uint8(0)
(*TFts5SegIter)(unsafe.Pointer(pIter)).FnPos = int32(1)
if iOff < iEod && libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).Fp + uintptr(iOff)))) == 0 {
(*TFts5SegIter)(unsafe.Pointer(pIter)).FbDel = uint8(1)
iOff = iOff + 1
if iOff < iEod && libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).Fp + uintptr(iOff)))) == 0 {
(*TFts5SegIter)(unsafe.Pointer(pIter)).FnPos = int32(1)
iOff = iOff + 1
} else {
(*TFts5SegIter)(unsafe.Pointer(pIter)).FnPos = 0
}
}
} else {
v1 = iOff
iOff = iOff + 1
**(**int32)(__ccgo_up(bp)) = libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).Fp + uintptr(v1))))
if **(**int32)(__ccgo_up(bp))&int32(0x80) != 0 {
iOff = iOff - 1
iOff = iOff + _sqlite3Fts5GetVarint32(tls, (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).Fp+uintptr(iOff), bp)
}
(*TFts5SegIter)(unsafe.Pointer(pIter)).FbDel = libc.Uint8FromInt32(**(**int32)(__ccgo_up(bp)) & libc.Int32FromInt32(0x0001))
(*TFts5SegIter)(unsafe.Pointer(pIter)).FnPos = **(**int32)(__ccgo_up(bp)) >> int32(1)
}
(*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafOffset = int64(iOff)
}
}
func _fts5UsePatternMatch(tls *libc.TLS, pConfig uintptr, p uintptr) (r int32) {
if (*TFts5Config)(unsafe.Pointer(pConfig)).Ft.FePattern == int32(FTS5_PATTERN_GLOB) && libc.Int32FromUint8((*Tsqlite3_index_constraint)(unsafe.Pointer(p)).Fop) == int32(FTS5_PATTERN_GLOB) {
return int32(1)
}
if (*TFts5Config)(unsafe.Pointer(pConfig)).Ft.FePattern == int32(FTS5_PATTERN_LIKE) && (libc.Int32FromUint8((*Tsqlite3_index_constraint)(unsafe.Pointer(p)).Fop) == int32(FTS5_PATTERN_LIKE) || libc.Int32FromUint8((*Tsqlite3_index_constraint)(unsafe.Pointer(p)).Fop) == int32(FTS5_PATTERN_GLOB)) {
return int32(1)
}
return 0
}
// C documentation
//
// /*
// ** Implementation of the xBestIndex method.
// **
// ** Only constraints of the form:
// **
// ** term <= ?
// ** term == ?
// ** term >= ?
// **
// ** are interpreted. Less-than and less-than-or-equal are treated
// ** identically, as are greater-than and greater-than-or-equal.
// */
func _fts5VocabBestIndexMethod(tls *libc.TLS, pUnused uintptr, pInfo uintptr) (r int32) {
var i, iTermEq, iTermGe, iTermLe, idxNum, nArg, v2 int32
var p uintptr
_, _, _, _, _, _, _, _ = i, iTermEq, iTermGe, iTermLe, idxNum, nArg, p, v2
iTermEq = -int32(1)
iTermGe = -int32(1)
iTermLe = -int32(1)
idxNum = libc.Int32FromUint64((*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FcolUsed)
nArg = 0
_ = pUnused
i = 0
for {
if !(i < (*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FnConstraint) {
break
}
p = (*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FaConstraint + uintptr(i)*12
if libc.Int32FromUint8((*Tsqlite3_index_constraint)(unsafe.Pointer(p)).Fusable) == 0 {
goto _1
}
if (*Tsqlite3_index_constraint)(unsafe.Pointer(p)).FiColumn == 0 { /* term column */
if libc.Int32FromUint8((*Tsqlite3_index_constraint)(unsafe.Pointer(p)).Fop) == int32(SQLITE_INDEX_CONSTRAINT_EQ) {
iTermEq = i
}
if libc.Int32FromUint8((*Tsqlite3_index_constraint)(unsafe.Pointer(p)).Fop) == int32(SQLITE_INDEX_CONSTRAINT_LE) {
iTermLe = i
}
if libc.Int32FromUint8((*Tsqlite3_index_constraint)(unsafe.Pointer(p)).Fop) == int32(SQLITE_INDEX_CONSTRAINT_LT) {
iTermLe = i
}
if libc.Int32FromUint8((*Tsqlite3_index_constraint)(unsafe.Pointer(p)).Fop) == int32(SQLITE_INDEX_CONSTRAINT_GE) {
iTermGe = i
}
if libc.Int32FromUint8((*Tsqlite3_index_constraint)(unsafe.Pointer(p)).Fop) == int32(SQLITE_INDEX_CONSTRAINT_GT) {
iTermGe = i
}
}
goto _1
_1:
;
i = i + 1
}
if iTermEq >= 0 {
idxNum = idxNum | int32(FTS5_VOCAB_TERM_EQ)
nArg = nArg + 1
v2 = nArg
(**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FaConstraintUsage + uintptr(iTermEq)*8))).FargvIndex = v2
(*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FestimatedCost = libc.Float64FromInt32(100)
} else {
(*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FestimatedCost = libc.Float64FromInt32(1000000)
if iTermGe >= 0 {
idxNum = idxNum | int32(FTS5_VOCAB_TERM_GE)
nArg = nArg + 1
v2 = nArg
(**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FaConstraintUsage + uintptr(iTermGe)*8))).FargvIndex = v2
(*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FestimatedCost = (*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FestimatedCost / libc.Float64FromInt32(2)
}
if iTermLe >= 0 {
idxNum = idxNum | int32(FTS5_VOCAB_TERM_LE)
nArg = nArg + 1
v2 = nArg
(**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FaConstraintUsage + uintptr(iTermLe)*8))).FargvIndex = v2
(*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FestimatedCost = (*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FestimatedCost / libc.Float64FromInt32(2)
}
}
/* This virtual table always delivers results in ascending order of
** the "term" column (column 0). So if the user has requested this
** specifically - "ORDER BY term" or "ORDER BY term ASC" - set the
** sqlite3_index_info.orderByConsumed flag to tell the core the results
** are already in sorted order. */
if (*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FnOrderBy == int32(1) && (**(**Tsqlite3_index_orderby)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FaOrderBy))).FiColumn == 0 && libc.Int32FromUint8((**(**Tsqlite3_index_orderby)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FaOrderBy))).Fdesc) == 0 {
(*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).ForderByConsumed = int32(1)
}
(*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FidxNum = idxNum
return SQLITE_OK
}
// C documentation
//
// /* The following function deletes the "minor type" or semantic value
// ** associated with a symbol. The symbol can be either a terminal
// ** or nonterminal. "fts5yymajor" is the symbol code, and "fts5yypminor" is
// ** a pointer to the value to be deleted. The code used to do the
// ** deletions is derived from the %destructor and/or %token_destructor
// ** directives of the input grammar.
// */
func _fts5yy_destructor(tls *libc.TLS, fts5yypParser uintptr, fts5yymajor uint8, fts5yypminor uintptr) {
var pParse uintptr
_ = pParse
pParse = (*Tfts5yyParser)(unsafe.Pointer(fts5yypParser)).FpParse
switch libc.Int32FromUint8(fts5yymajor) {
/* Here is inserted the actions which take place when a
** terminal or non-terminal is destroyed. This can happen
** when the symbol is popped from the stack during a
** reduce or during error processing or when a parser is
** being destroyed before it is finished parsing.
**
** Note: during a reduce, the only symbols destroyed are those
** which appear on the RHS of the rule, but which are *not* used
** inside the C code.
*/
/********* Begin destructor definitions ***************************************/
case int32(16): /* input */
_ = pParse
case int32(17): /* expr */
fallthrough
case int32(18): /* cnearset */
fallthrough
case int32(19): /* exprlist */
_sqlite3Fts5ParseNodeFree(tls, *(*uintptr)(unsafe.Pointer(fts5yypminor)))
case int32(20): /* colset */
fallthrough
case int32(21): /* colsetlist */
Xsqlite3_free(tls, *(*uintptr)(unsafe.Pointer(fts5yypminor)))
case int32(22): /* nearset */
fallthrough
case int32(23): /* nearphrases */
_sqlite3Fts5ParseNearsetFree(tls, *(*uintptr)(unsafe.Pointer(fts5yypminor)))
case int32(24): /* phrase */
_sqlite3Fts5ParsePhraseFree(tls, *(*uintptr)(unsafe.Pointer(fts5yypminor)))
break
/********* End destructor definitions *****************************************/
fallthrough
default:
break /* If no destructor action specified: do nothing */
}
}
// C documentation
//
// /*
// ** Find the appropriate action for a parser given the non-terminal
// ** look-ahead token iLookAhead.
// */
func _fts5yy_find_reduce_action(tls *libc.TLS, stateno uint8, iLookAhead uint8) (r uint8) {
var i int32
_ = i
i = int32(_fts5yy_reduce_ofst[stateno])
i = i + libc.Int32FromUint8(iLookAhead)
return _fts5yy_action[i]
}
// C documentation
//
// /*
// ** Find the appropriate action for a parser given the terminal
// ** look-ahead token iLookAhead.
// */
func _fts5yy_find_shift_action(tls *libc.TLS, iLookAhead uint8, stateno uint8) (r uint8) {
var i int32
_ = i
if libc.Int32FromUint8(stateno) > int32(fts5YY_MAX_SHIFT) {
return stateno
}
for cond := true; cond; cond = int32(1) != 0 {
i = libc.Int32FromUint8(_fts5yy_shift_ofst[stateno])
i = i + libc.Int32FromUint8(iLookAhead)
if libc.Int32FromUint8(_fts5yy_lookahead[i]) != libc.Int32FromUint8(iLookAhead) {
return _fts5yy_default[stateno]
} else {
return _fts5yy_action[i]
}
}
return r
}
// C documentation
//
// /*
// ** Insert all segments and events for polygon pPoly.
// */
func _geopolyAddSegments(tls *libc.TLS, p uintptr, pPoly uintptr, side uint8) {
var i uint32
var x uintptr
_, _ = i, x
i = uint32(0)
for {
if !(i < libc.Uint32FromInt32((*TGeoPoly)(unsafe.Pointer(pPoly)).FnVertex)-uint32(1)) {
break
}
x = pPoly + 8 + uintptr(i*uint32(2))*4
_geopolyAddOneSegment(tls, p, **(**TGeoCoord)(__ccgo_up(x)), **(**TGeoCoord)(__ccgo_up(x + 1*4)), **(**TGeoCoord)(__ccgo_up(x + 2*4)), **(**TGeoCoord)(__ccgo_up(x + 3*4)), side, i)
goto _1
_1:
;
i = i + 1
}
x = pPoly + 8 + uintptr(i*uint32(2))*4
_geopolyAddOneSegment(tls, p, **(**TGeoCoord)(__ccgo_up(x)), **(**TGeoCoord)(__ccgo_up(x + 1*4)), **(**TGeoCoord)(__ccgo_up(pPoly + 8)), **(**TGeoCoord)(__ccgo_up(pPoly + 8 + 1*4)), side, i)
}
// C documentation
//
// /*
// ** Get a page from the pager and initialize it.
// */
func _getAndInitPage(tls *libc.TLS, pBt uintptr, pgno TPgno, ppPage uintptr, bReadOnly int32) (r int32) {
bp := tls.Alloc(16)
defer tls.Free(16)
var pPage uintptr
var rc int32
var _ /* pDbPage at bp+0 */ uintptr
_, _ = pPage, rc
if pgno > _btreePagecount(tls, pBt) {
**(**uintptr)(__ccgo_up(ppPage)) = uintptr(0)
return _sqlite3CorruptError(tls, int32(75618))
}
rc = _sqlite3PagerGet(tls, (*TBtShared)(unsafe.Pointer(pBt)).FpPager, pgno, bp, bReadOnly)
if rc != 0 {
**(**uintptr)(__ccgo_up(ppPage)) = uintptr(0)
return rc
}
pPage = _sqlite3PagerGetExtra(tls, **(**uintptr)(__ccgo_up(bp)))
if libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pPage)).FisInit) == 0 {
_btreePageFromDbPage(tls, **(**uintptr)(__ccgo_up(bp)), pgno, pBt)
rc = _btreeInitPage(tls, pPage)
if rc != SQLITE_OK {
_releasePage(tls, pPage)
**(**uintptr)(__ccgo_up(ppPage)) = uintptr(0)
return rc
}
}
**(**uintptr)(__ccgo_up(ppPage)) = pPage
return SQLITE_OK
}
// C documentation
//
// /*
// ** For a single cell on a btree page, compute the number of bytes of
// ** content (payload) stored on that page. That is to say, compute the
// ** number of bytes of content not found on overflow pages.
// */
func _getLocalPayload(tls *libc.TLS, nUsable int32, flags Tu8, nTotal int32) (r int32) {
var nLocal, nMaxLocal, nMinLocal int32
_, _, _ = nLocal, nMaxLocal, nMinLocal
if libc.Int32FromUint8(flags) == int32(0x0D) { /* Table leaf node */
nMinLocal = (nUsable-int32(12))*int32(32)/int32(255) - int32(23)
nMaxLocal = nUsable - int32(35)
} else { /* Index interior and leaf nodes */
nMinLocal = (nUsable-int32(12))*int32(32)/int32(255) - int32(23)
nMaxLocal = (nUsable-int32(12))*int32(64)/int32(255) - int32(23)
}
nLocal = nMinLocal + (nTotal-nMinLocal)%(nUsable-int32(4))
if nLocal > nMaxLocal {
nLocal = nMinLocal
}
return nLocal
}
// C documentation
//
// /*
// ** Return non-zero if the bit in the IntegrityCk.aPgRef[] array that
// ** corresponds to page iPg is already set.
// */
func _getPageReferenced(tls *libc.TLS, pCheck uintptr, iPg TPgno) (r int32) {
return libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TIntegrityCk)(unsafe.Pointer(pCheck)).FaPgRef + uintptr(iPg/uint32(8))))) & (int32(1) << (iPg & uint32(0x07)))
}
// C documentation
//
// /*
// ** This function is called after transitioning from PAGER_UNLOCK to
// ** PAGER_SHARED state. It tests if there is a hot journal present in
// ** the file-system for the given pager. A hot journal is one that
// ** needs to be played back. According to this function, a hot-journal
// ** file exists if the following criteria are met:
// **
// ** * The journal file exists in the file system, and
// ** * No process holds a RESERVED or greater lock on the database file, and
// ** * The database file itself is greater than 0 bytes in size, and
// ** * The first byte of the journal file exists and is not 0x00.
// **
// ** If the current size of the database file is 0 but a journal file
// ** exists, that is probably an old journal left over from a prior
// ** database with the same name. In this case the journal file is
// ** just deleted using OsDelete, *pExists is set to 0 and SQLITE_OK
// ** is returned.
// **
// ** This routine does not check if there is a super-journal filename
// ** at the end of the file. If there is, and that super-journal file
// ** does not exist, then the journal file is not really hot. In this
// ** case this routine will return a false-positive. The pager_playback()
// ** routine will discover that the journal file is not really hot and
// ** will not roll it back.
// **
// ** If a hot-journal file is found to exist, *pExists is set to 1 and
// ** SQLITE_OK returned. If no hot-journal file is present, *pExists is
// ** set to 0 and SQLITE_OK returned. If an IO error occurs while trying
// ** to determine whether or not a hot-journal file exists, the IO error
// ** code is returned and the value of *pExists is undefined.
// */
func _hasHotJournal(tls *libc.TLS, pPager uintptr, pExists uintptr) (r int32) {
bp := tls.Alloc(32)
defer tls.Free(32)
var jrnlOpen, rc int32
var pVfs uintptr
var _ /* exists at bp+0 */ int32
var _ /* f at bp+12 */ int32
var _ /* first at bp+16 */ Tu8
var _ /* locked at bp+4 */ int32
var _ /* nPage at bp+8 */ TPgno
_, _, _ = jrnlOpen, pVfs, rc
pVfs = (*TPager)(unsafe.Pointer(pPager)).FpVfs
rc = SQLITE_OK /* Return code */
**(**int32)(__ccgo_up(bp)) = int32(1) /* True if a journal file is present */
jrnlOpen = libc.BoolInt32(!!((*Tsqlite3_file)(unsafe.Pointer((*TPager)(unsafe.Pointer(pPager)).Fjfd)).FpMethods != libc.UintptrFromInt32(0)))
**(**int32)(__ccgo_up(pExists)) = 0
if !(jrnlOpen != 0) {
rc = _sqlite3OsAccess(tls, pVfs, (*TPager)(unsafe.Pointer(pPager)).FzJournal, SQLITE_ACCESS_EXISTS, bp)
}
if rc == SQLITE_OK && **(**int32)(__ccgo_up(bp)) != 0 {
**(**int32)(__ccgo_up(bp + 4)) = 0 /* True if some process holds a RESERVED lock */
/* Race condition here: Another process might have been holding the
** the RESERVED lock and have a journal open at the sqlite3OsAccess()
** call above, but then delete the journal and drop the lock before
** we get to the following sqlite3OsCheckReservedLock() call. If that
** is the case, this routine might think there is a hot journal when
** in fact there is none. This results in a false-positive which will
** be dealt with by the playback routine. Ticket #3883.
*/
rc = _sqlite3OsCheckReservedLock(tls, (*TPager)(unsafe.Pointer(pPager)).Ffd, bp+4)
if rc == SQLITE_OK && !(**(**int32)(__ccgo_up(bp + 4)) != 0) { /* Number of pages in database file */
rc = _pagerPagecount(tls, pPager, bp+8)
if rc == SQLITE_OK {
/* If the database is zero pages in size, that means that either (1) the
** journal is a remnant from a prior database with the same name where
** the database file but not the journal was deleted, or (2) the initial
** transaction that populates a new database is being rolled back.
** In either case, the journal file can be deleted. However, take care
** not to delete the journal file if it is already open due to
** journal_mode=PERSIST.
*/
if **(**TPgno)(__ccgo_up(bp + 8)) == uint32(0) && !(jrnlOpen != 0) {
_sqlite3BeginBenignMalloc(tls)
if _pagerLockDb(tls, pPager, int32(RESERVED_LOCK)) == SQLITE_OK {
_sqlite3OsDelete(tls, pVfs, (*TPager)(unsafe.Pointer(pPager)).FzJournal, 0)
if !((*TPager)(unsafe.Pointer(pPager)).FexclusiveMode != 0) {
_pagerUnlockDb(tls, pPager, int32(SHARED_LOCK))
}
}
_sqlite3EndBenignMalloc(tls)
} else {
/* The journal file exists and no other connection has a reserved
** or greater lock on the database file. Now check that there is
** at least one non-zero bytes at the start of the journal file.
** If there is, then we consider this journal to be hot. If not,
** it can be ignored.
*/
if !(jrnlOpen != 0) {
**(**int32)(__ccgo_up(bp + 12)) = libc.Int32FromInt32(SQLITE_OPEN_READONLY) | libc.Int32FromInt32(SQLITE_OPEN_MAIN_JOURNAL)
rc = _sqlite3OsOpen(tls, pVfs, (*TPager)(unsafe.Pointer(pPager)).FzJournal, (*TPager)(unsafe.Pointer(pPager)).Fjfd, **(**int32)(__ccgo_up(bp + 12)), bp+12)
}
if rc == SQLITE_OK {
**(**Tu8)(__ccgo_up(bp + 16)) = uint8(0)
rc = _sqlite3OsRead(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd, bp+16, int32(1), 0)
if rc == libc.Int32FromInt32(SQLITE_IOERR)|libc.Int32FromInt32(2)<<libc.Int32FromInt32(8) {
rc = SQLITE_OK
}
if !(jrnlOpen != 0) {
_sqlite3OsClose(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd)
}
**(**int32)(__ccgo_up(pExists)) = libc.BoolInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up(bp + 16))) != 0)
} else {
if rc == int32(SQLITE_CANTOPEN) {
/* If we cannot open the rollback journal file in order to see if
** it has a zero header, that might be due to an I/O error, or
** it might be due to the race condition described above and in
** ticket #3883. Either way, assume that the journal is hot.
** This might be a false positive. But if it is, then the
** automatic journal playback and recovery mechanism will deal
** with it under an EXCLUSIVE lock where we do not need to
** worry so much with race conditions.
*/
**(**int32)(__ccgo_up(pExists)) = int32(1)
rc = SQLITE_OK
}
}
}
}
}
}
return rc
}
// C documentation
//
// /*
// ** A lists of all unixInodeInfo objects.
// **
// ** Must hold unixBigLock in order to read or write this variable.
// */
var _inodeList = uintptr(0)
// C documentation
//
// /*
// ** This function is called before modifying the contents of a table
// ** to invalidate any incrblob cursors that are open on the
// ** row or one of the rows being modified.
// **
// ** If argument isClearTable is true, then the entire contents of the
// ** table is about to be deleted. In this case invalidate all incrblob
// ** cursors open on any row within the table with root-page pgnoRoot.
// **
// ** Otherwise, if argument isClearTable is false, then the row with
// ** rowid iRow is being replaced or deleted. In this case invalidate
// ** only those incrblob cursors open on that specific row.
// */
func _invalidateIncrblobCursors(tls *libc.TLS, pBtree uintptr, pgnoRoot TPgno, iRow Ti64, isClearTable int32) {
var p uintptr
_ = p
(*TBtree)(unsafe.Pointer(pBtree)).FhasIncrblobCur = uint8(0)
p = (*TBtShared)(unsafe.Pointer((*TBtree)(unsafe.Pointer(pBtree)).FpBt)).FpCursor
for {
if !(p != 0) {
break
}
if libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(p)).FcurFlags)&int32(BTCF_Incrblob) != 0 {
(*TBtree)(unsafe.Pointer(pBtree)).FhasIncrblobCur = uint8(1)
if (*TBtCursor)(unsafe.Pointer(p)).FpgnoRoot == pgnoRoot && (isClearTable != 0 || (*TBtCursor)(unsafe.Pointer(p)).Finfo.FnKey == iRow) {
(*TBtCursor)(unsafe.Pointer(p)).FeState = uint8(CURSOR_INVALID)
}
}
goto _1
_1:
;
p = (*TBtCursor)(unsafe.Pointer(p)).FpNext
}
}
// C documentation
//
// /*
// ** Invoke the profile callback. This routine is only called if we already
// ** know that the profile callback is defined and needs to be invoked.
// */
func _invokeProfileCallback(tls *libc.TLS, db uintptr, p uintptr) {
bp := tls.Alloc(16)
defer tls.Free(16)
var _ /* iElapse at bp+8 */ Tsqlite3_int64
var _ /* iNow at bp+0 */ Tsqlite3_int64
_sqlite3OsCurrentTimeInt64(tls, (*Tsqlite3)(unsafe.Pointer(db)).FpVfs, bp)
**(**Tsqlite3_int64)(__ccgo_up(bp + 8)) = (**(**Tsqlite3_int64)(__ccgo_up(bp)) - (*TVdbe)(unsafe.Pointer(p)).FstartTime) * int64(1000000)
if (*Tsqlite3)(unsafe.Pointer(db)).FxProfile != 0 {
(*(*func(*libc.TLS, uintptr, uintptr, Tu64))(unsafe.Pointer(&struct{ uintptr }{(*Tsqlite3)(unsafe.Pointer(db)).FxProfile})))(tls, (*Tsqlite3)(unsafe.Pointer(db)).FpProfileArg, (*TVdbe)(unsafe.Pointer(p)).FzSql, libc.Uint64FromInt64(**(**Tsqlite3_int64)(__ccgo_up(bp + 8))))
}
if libc.Int32FromUint8((*Tsqlite3)(unsafe.Pointer(db)).FmTrace)&int32(SQLITE_TRACE_PROFILE) != 0 {
(*(*func(*libc.TLS, Tu32, uintptr, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{*(*uintptr)(unsafe.Pointer(&(*Tsqlite3)(unsafe.Pointer(db)).Ftrace))})))(tls, uint32(SQLITE_TRACE_PROFILE), (*Tsqlite3)(unsafe.Pointer(db)).FpTraceArg, p, bp+8)
}
(*TVdbe)(unsafe.Pointer(p)).FstartTime = 0
}
/*
** The checkProfileCallback(DB,P) macro checks to see if a profile callback
** is needed, and it invokes the callback if it is needed.
*/
// C documentation
//
// /*
// ** Return true if pTerm is a virtual table LIMIT or OFFSET term.
// */
func _isLimitTerm(tls *libc.TLS, pTerm uintptr) (r int32) {
return libc.BoolInt32(libc.Int32FromUint8((*TWhereTerm)(unsafe.Pointer(pTerm)).FeMatchOp) >= int32(SQLITE_INDEX_CONSTRAINT_LIMIT) && libc.Int32FromUint8((*TWhereTerm)(unsafe.Pointer(pTerm)).FeMatchOp) <= int32(SQLITE_INDEX_CONSTRAINT_OFFSET))
}
// C documentation
//
// /*
// ** Return the offset of the sector boundary at or immediately
// ** following the value in pPager->journalOff, assuming a sector
// ** size of pPager->sectorSize bytes.
// **
// ** i.e for a sector size of 512:
// **
// ** Pager.journalOff Return value
// ** ---------------------------------------
// ** 0 0
// ** 512 512
// ** 100 512
// ** 2000 2048
// **
// */
func _journalHdrOffset(tls *libc.TLS, pPager uintptr) (r Ti64) {
var c, offset Ti64
_, _ = c, offset
offset = 0
c = (*TPager)(unsafe.Pointer(pPager)).FjournalOff
if c != 0 {
offset = ((c-int64(1))/libc.Int64FromUint32((*TPager)(unsafe.Pointer(pPager)).FsectorSize) + int64(1)) * libc.Int64FromUint32((*TPager)(unsafe.Pointer(pPager)).FsectorSize)
}
return offset
}
// C documentation
//
// /*
// ** If pArg is a blob that seems like a JSONB blob, then initialize
// ** p to point to that JSONB and return TRUE. If pArg does not seem like
// ** a JSONB blob, then return FALSE.
// **
// ** For small BLOBs (having no more than 7 bytes of payload) a full
// ** validity check is done. So for small BLOBs this routine only returns
// ** true if the value is guaranteed to be a valid JSONB. For larger BLOBs
// ** (8 byte or more of payload) only the size of the outermost element is
// ** checked to verify that the BLOB is superficially valid JSONB.
// **
// ** A full JSONB validation is done on smaller BLOBs because those BLOBs might
// ** also be text JSON that has been incorrectly cast into a BLOB.
// ** (See tag-20240123-a and https://sqlite.org/forum/forumpost/012136abd5)
// ** If the BLOB is 9 bytes are larger, then it is not possible for the
// ** superficial size check done here to pass if the input is really text
// ** JSON so we do not need to look deeper in that case.
// **
// ** Why we only need to do full JSONB validation for smaller BLOBs:
// **
// ** The first byte of valid JSON text must be one of: '{', '[', '"', ' ', '\n',
// ** '\r', '\t', '-', or a digit '0' through '9'. Of these, only a subset
// ** can also be the first byte of JSONB: '{', '[', and digits '3'
// ** through '9'. In every one of those cases, the payload size is 7 bytes
// ** or less. So if we do full JSONB validation for every BLOB where the
// ** payload is less than 7 bytes, we will never get a false positive for
// ** JSONB on an input that is really text JSON.
// */
func _jsonArgIsJsonb(tls *libc.TLS, pArg uintptr, p uintptr) (r int32) {
bp := tls.Alloc(16)
defer tls.Free(16)
var c, v1 Tu8
var n, v3 Tu32
var v2, v4 bool
var _ /* sz at bp+0 */ Tu32
_, _, _, _, _, _ = c, n, v1, v2, v3, v4
**(**Tu32)(__ccgo_up(bp)) = uint32(0)
if Xsqlite3_value_type(tls, pArg) != int32(SQLITE_BLOB) {
return 0
}
(*TJsonParse)(unsafe.Pointer(p)).FaBlob = Xsqlite3_value_blob(tls, pArg)
(*TJsonParse)(unsafe.Pointer(p)).FnBlob = libc.Uint32FromInt32(Xsqlite3_value_bytes(tls, pArg))
if v2 = (*TJsonParse)(unsafe.Pointer(p)).FnBlob > uint32(0) && (*TJsonParse)(unsafe.Pointer(p)).FaBlob != uintptr(0); v2 {
v1 = **(**Tu8)(__ccgo_up((*TJsonParse)(unsafe.Pointer(p)).FaBlob))
c = v1
}
if v4 = v2 && libc.Int32FromUint8(v1)&int32(0x0f) <= int32(JSONB_OBJECT); v4 {
v3 = _jsonbPayloadSize(tls, p, uint32(0), bp)
n = v3
}
if v4 && v3 > uint32(0) && **(**Tu32)(__ccgo_up(bp))+n == (*TJsonParse)(unsafe.Pointer(p)).FnBlob && (libc.Int32FromUint8(c)&int32(0x0f) > int32(JSONB_FALSE) || **(**Tu32)(__ccgo_up(bp)) == uint32(0)) && (**(**Tu32)(__ccgo_up(bp)) > uint32(7) || libc.Int32FromUint8(c) != int32(0x7b) && libc.Int32FromUint8(c) != int32(0x5b) && !(libc.Int32FromUint8(_sqlite3CtypeMap[c])&libc.Int32FromInt32(0x04) != 0) || _jsonbValidityCheck(tls, p, uint32(0), (*TJsonParse)(unsafe.Pointer(p)).FnBlob, uint32(1)) == uint32(0)) {
return int32(1)
}
(*TJsonParse)(unsafe.Pointer(p)).FaBlob = uintptr(0)
(*TJsonParse)(unsafe.Pointer(p)).FnBlob = uint32(0)
return 0
}
// C documentation
//
// /* The query strategy is to look for an equality constraint on the json
// ** column. Without such a constraint, the table cannot operate. idxNum is
// ** 1 if the constraint is found, 3 if the constraint and zRoot are found,
// ** and 0 otherwise.
// */
func _jsonEachBestIndex(tls *libc.TLS, tab uintptr, pIdxInfo uintptr) (r int32) {
var aIdx [2]int32
var i, iCol, iMask, idxMask, unusableMask, v1 int32
var pConstraint uintptr
_, _, _, _, _, _, _, _ = aIdx, i, iCol, iMask, idxMask, pConstraint, unusableMask, v1 /* Index of constraints for JSON and ROOT */
unusableMask = 0 /* Mask of unusable JSON and ROOT constraints */
idxMask = 0
/* This implementation assumes that JSON and ROOT are the last two
** columns in the table */
_ = tab
v1 = -libc.Int32FromInt32(1)
aIdx[int32(1)] = v1
aIdx[0] = v1
pConstraint = (*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraint
i = 0
for {
if !(i < (*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FnConstraint) {
break
}
if (*Tsqlite3_index_constraint)(unsafe.Pointer(pConstraint)).FiColumn < int32(JEACH_JSON) {
goto _2
}
iCol = (*Tsqlite3_index_constraint)(unsafe.Pointer(pConstraint)).FiColumn - int32(JEACH_JSON)
iMask = int32(1) << iCol
if libc.Int32FromUint8((*Tsqlite3_index_constraint)(unsafe.Pointer(pConstraint)).Fusable) == 0 {
unusableMask = unusableMask | iMask
} else {
if libc.Int32FromUint8((*Tsqlite3_index_constraint)(unsafe.Pointer(pConstraint)).Fop) == int32(SQLITE_INDEX_CONSTRAINT_EQ) {
aIdx[iCol] = i
idxMask = idxMask | iMask
}
}
goto _2
_2:
;
i = i + 1
pConstraint += 12
}
if (*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FnOrderBy > 0 && (**(**Tsqlite3_index_orderby)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaOrderBy))).FiColumn < 0 && libc.Int32FromUint8((**(**Tsqlite3_index_orderby)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaOrderBy))).Fdesc) == 0 {
(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).ForderByConsumed = int32(1)
}
if unusableMask & ^idxMask != 0 {
/* If there are any unusable constraints on JSON or ROOT, then reject
** this entire plan */
return int32(SQLITE_CONSTRAINT)
}
if aIdx[0] < 0 {
/* No JSON input. Leave estimatedCost at the huge value that it was
** initialized to to discourage the query planner from selecting this
** plan. */
(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FidxNum = 0
} else {
(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FestimatedCost = float64(1)
i = aIdx[0]
(**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraintUsage + uintptr(i)*8))).FargvIndex = int32(1)
(**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraintUsage + uintptr(i)*8))).Fomit = uint8(1)
if aIdx[int32(1)] < 0 {
(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FidxNum = int32(1) /* Only JSON supplied. Plan 1 */
} else {
i = aIdx[int32(1)]
(**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraintUsage + uintptr(i)*8))).FargvIndex = int32(2)
(**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraintUsage + uintptr(i)*8))).Fomit = uint8(1)
(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FidxNum = int32(3) /* Both JSON and ROOT are supplied. Plan 3 */
}
}
return SQLITE_OK
}
// C documentation
//
// /* Return the current rowid value */
func _jsonEachRowid(tls *libc.TLS, cur uintptr, pRowid uintptr) (r int32) {
var p uintptr
_ = p
p = cur
**(**Tsqlite_int64)(__ccgo_up(pRowid)) = libc.Int64FromUint32((*TJsonEachCursor)(unsafe.Pointer(p)).FiRowid)
return SQLITE_OK
}
// C documentation
//
// /*
// ** Translate a single byte of Hex into an integer.
// ** This routine only gives a correct answer if h really is a valid hexadecimal
// ** character: 0..9a..fA..F. But unlike sqlite3HexToInt(), it does not
// ** assert() if the digit is not hex.
// */
func _jsonHexToInt(tls *libc.TLS, h int32) (r Tu8) {
h = h + int32(9)*(int32(1)&(h>>int32(6)))
return libc.Uint8FromInt32(h & libc.Int32FromInt32(0xf))
}
// C documentation
//
// /* Remove a single character from the end of the string
// */
func _jsonStringTrimOneChar(tls *libc.TLS, p uintptr) {
if libc.Int32FromUint8((*TJsonString)(unsafe.Pointer(p)).FeErr) == 0 {
(*TJsonString)(unsafe.Pointer(p)).FnUsed = (*TJsonString)(unsafe.Pointer(p)).FnUsed - 1
}
}
// C documentation
//
// /* The byte at index i is a node type-code. This routine
// ** determines the payload size for that node and writes that
// ** payload size in to *pSz. It returns the offset from i to the
// ** beginning of the payload. Return 0 on error.
// */
func _jsonbPayloadSize(tls *libc.TLS, pParse uintptr, i Tu32, pSz uintptr) (r Tu32) {
var n, sz Tu32
var x, v1 Tu8
_, _, _, _ = n, sz, x, v1
if i >= (*TJsonParse)(unsafe.Pointer(pParse)).FnBlob {
**(**Tu32)(__ccgo_up(pSz)) = uint32(0)
return uint32(0)
} else {
v1 = libc.Uint8FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TJsonParse)(unsafe.Pointer(pParse)).FaBlob + uintptr(i)))) >> libc.Int32FromInt32(4))
x = v1
if libc.Int32FromUint8(v1) <= int32(11) {
sz = uint32(x)
n = uint32(1)
} else {
if libc.Int32FromUint8(x) == int32(12) {
if i+uint32(1) >= (*TJsonParse)(unsafe.Pointer(pParse)).FnBlob {
**(**Tu32)(__ccgo_up(pSz)) = uint32(0)
return uint32(0)
}
sz = uint32(**(**Tu8)(__ccgo_up((*TJsonParse)(unsafe.Pointer(pParse)).FaBlob + uintptr(i+uint32(1)))))
n = uint32(2)
} else {
if libc.Int32FromUint8(x) == int32(13) {
if i+uint32(2) >= (*TJsonParse)(unsafe.Pointer(pParse)).FnBlob {
**(**Tu32)(__ccgo_up(pSz)) = uint32(0)
return uint32(0)
}
sz = libc.Uint32FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TJsonParse)(unsafe.Pointer(pParse)).FaBlob + uintptr(i+uint32(1)))))<<int32(8) + libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TJsonParse)(unsafe.Pointer(pParse)).FaBlob + uintptr(i+uint32(2))))))
n = uint32(3)
} else {
if libc.Int32FromUint8(x) == int32(14) {
if i+uint32(4) >= (*TJsonParse)(unsafe.Pointer(pParse)).FnBlob {
**(**Tu32)(__ccgo_up(pSz)) = uint32(0)
return uint32(0)
}
sz = uint32(**(**Tu8)(__ccgo_up((*TJsonParse)(unsafe.Pointer(pParse)).FaBlob + uintptr(i+uint32(1)))))<<libc.Int32FromInt32(24) + libc.Uint32FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TJsonParse)(unsafe.Pointer(pParse)).FaBlob + uintptr(i+uint32(2)))))<<libc.Int32FromInt32(16)) + libc.Uint32FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TJsonParse)(unsafe.Pointer(pParse)).FaBlob + uintptr(i+uint32(3)))))<<libc.Int32FromInt32(8)) + uint32(**(**Tu8)(__ccgo_up((*TJsonParse)(unsafe.Pointer(pParse)).FaBlob + uintptr(i+uint32(4)))))
n = uint32(5)
} else {
if i+uint32(8) >= (*TJsonParse)(unsafe.Pointer(pParse)).FnBlob || libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TJsonParse)(unsafe.Pointer(pParse)).FaBlob + uintptr(i+uint32(1))))) != 0 || libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TJsonParse)(unsafe.Pointer(pParse)).FaBlob + uintptr(i+uint32(2))))) != 0 || libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TJsonParse)(unsafe.Pointer(pParse)).FaBlob + uintptr(i+uint32(3))))) != 0 || libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TJsonParse)(unsafe.Pointer(pParse)).FaBlob + uintptr(i+uint32(4))))) != 0 {
**(**Tu32)(__ccgo_up(pSz)) = uint32(0)
return uint32(0)
}
sz = uint32(**(**Tu8)(__ccgo_up((*TJsonParse)(unsafe.Pointer(pParse)).FaBlob + uintptr(i+uint32(5)))))<<libc.Int32FromInt32(24) + libc.Uint32FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TJsonParse)(unsafe.Pointer(pParse)).FaBlob + uintptr(i+uint32(6)))))<<libc.Int32FromInt32(16)) + libc.Uint32FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TJsonParse)(unsafe.Pointer(pParse)).FaBlob + uintptr(i+uint32(7)))))<<libc.Int32FromInt32(8)) + uint32(**(**Tu8)(__ccgo_up((*TJsonParse)(unsafe.Pointer(pParse)).FaBlob + uintptr(i+uint32(8)))))
n = uint32(9)
}
}
}
}
}
if libc.Int64FromUint32(i)+libc.Int64FromUint32(sz)+libc.Int64FromUint32(n) > libc.Int64FromUint32((*TJsonParse)(unsafe.Pointer(pParse)).FnBlob) && libc.Int64FromUint32(i)+libc.Int64FromUint32(sz)+libc.Int64FromUint32(n) > libc.Int64FromUint32((*TJsonParse)(unsafe.Pointer(pParse)).FnBlob-libc.Uint32FromInt32((*TJsonParse)(unsafe.Pointer(pParse)).Fdelta)) {
**(**Tu32)(__ccgo_up(pSz)) = uint32(0)
return uint32(0)
}
**(**Tu32)(__ccgo_up(pSz)) = sz
return n
}
func _lookasideMallocSize(tls *libc.TLS, db uintptr, p uintptr) (r int32) {
var v1 int32
_ = v1
if p < (*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpMiddle {
v1 = libc.Int32FromUint16((*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FszTrue)
} else {
v1 = int32(LOOKASIDE_SMALL)
}
return v1
}
// C documentation
//
// /*
// ** Try to enlarge the memory allocation to hold at least sz bytes
// */
func _memdbEnlarge(tls *libc.TLS, p uintptr, newSz Tsqlite3_int64) (r int32) {
var pNew uintptr
_ = pNew
if (*TMemStore)(unsafe.Pointer(p)).FmFlags&uint32(SQLITE_DESERIALIZE_RESIZEABLE) == uint32(0) || (*TMemStore)(unsafe.Pointer(p)).FnMmap > 0 {
return int32(SQLITE_FULL)
}
if newSz > (*TMemStore)(unsafe.Pointer(p)).FszMax {
return int32(SQLITE_FULL)
}
newSz = newSz * int64(2)
if newSz > (*TMemStore)(unsafe.Pointer(p)).FszMax {
newSz = (*TMemStore)(unsafe.Pointer(p)).FszMax
}
pNew = _sqlite3Realloc(tls, (*TMemStore)(unsafe.Pointer(p)).FaData, libc.Uint64FromInt64(newSz))
if pNew == uintptr(0) {
return libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(12)<<libc.Int32FromInt32(8)
}
(*TMemStore)(unsafe.Pointer(p)).FaData = pNew
(*TMemStore)(unsafe.Pointer(p)).FszAlloc = newSz
return SQLITE_OK
}
// C documentation
//
// /*
// ** Move the cursor down to the right-most leaf entry beneath the
// ** page to which it is currently pointing. Notice the difference
// ** between moveToLeftmost() and moveToRightmost(). moveToLeftmost()
// ** finds the left-most entry beneath the *entry* whereas moveToRightmost()
// ** finds the right-most entry beneath the *page*.
// **
// ** The right-most entry is the one with the largest key - the last
// ** key in ascending order.
// */
func _moveToRightmost(tls *libc.TLS, pCur uintptr) (r int32) {
var pPage, v1 uintptr
var pgno TPgno
var rc int32
_, _, _, _ = pPage, pgno, rc, v1
rc = SQLITE_OK
pPage = uintptr(0)
for {
v1 = (*TBtCursor)(unsafe.Pointer(pCur)).FpPage
pPage = v1
if !!((*TMemPage)(unsafe.Pointer(v1)).Fleaf != 0) {
break
}
pgno = _sqlite3Get4byte(tls, (*TMemPage)(unsafe.Pointer(pPage)).FaData+uintptr(libc.Int32FromUint8((*TMemPage)(unsafe.Pointer(pPage)).FhdrOffset)+int32(8)))
(*TBtCursor)(unsafe.Pointer(pCur)).Fix = (*TMemPage)(unsafe.Pointer(pPage)).FnCell
rc = _moveToChild(tls, pCur, pgno)
if rc != 0 {
return rc
}
}
(*TBtCursor)(unsafe.Pointer(pCur)).Fix = libc.Uint16FromInt32(libc.Int32FromUint16((*TMemPage)(unsafe.Pointer(pPage)).FnCell) - int32(1))
return SQLITE_OK
}
// C documentation
//
// /*
// ** Deserialize cell iCell of node pNode. Populate the structure pointed
// ** to by pCell with the results.
// */
func _nodeGetCell(tls *libc.TLS, pRtree uintptr, pNode uintptr, iCell int32, pCell uintptr) {
var ii int32
var pCoord, pData uintptr
_, _, _ = ii, pCoord, pData
ii = 0
(*TRtreeCell)(unsafe.Pointer(pCell)).FiRowid = _nodeGetRowid(tls, pRtree, pNode, iCell)
pData = (*TRtreeNode)(unsafe.Pointer(pNode)).FzData + uintptr(libc.Int32FromInt32(12)+libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FnBytesPerCell)*iCell)
pCoord = pCell + 8
for cond := true; cond; cond = ii < libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FnDim2) {
_readCoord(tls, pData, pCoord+uintptr(ii)*4)
_readCoord(tls, pData+uintptr(4), pCoord+uintptr(ii+int32(1))*4)
pData = pData + uintptr(8)
ii = ii + int32(2)
}
}
// C documentation
//
// /*
// ** Return coordinate iCoord from cell iCell in node pNode.
// */
func _nodeGetCoord(tls *libc.TLS, pRtree uintptr, pNode uintptr, iCell int32, iCoord int32, pCoord uintptr) {
_readCoord(tls, (*TRtreeNode)(unsafe.Pointer(pNode)).FzData+uintptr(int32(12)+libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FnBytesPerCell)*iCell+int32(4)*iCoord), pCoord)
}
// C documentation
//
// /*
// ** Return the 64-bit integer value associated with cell iCell of
// ** node pNode. If pNode is a leaf node, this is a rowid. If it is
// ** an internal node, then the 64-bit integer is a child page number.
// */
func _nodeGetRowid(tls *libc.TLS, pRtree uintptr, pNode uintptr, iCell int32) (r Ti64) {
return _readInt64(tls, (*TRtreeNode)(unsafe.Pointer(pNode)).FzData+uintptr(int32(4)+libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FnBytesPerCell)*iCell))
}
// C documentation
//
// /*
// ** Given a node number iNode, return the corresponding key to use
// ** in the Rtree.aHash table.
// */
func _nodeHash(tls *libc.TLS, iNode Ti64) (r uint32) {
return libc.Uint32FromInt64(iNode) % uint32(HASHSIZE)
}
// C documentation
//
// /*
// ** Insert the contents of cell pCell into node pNode. If the insert
// ** is successful, return SQLITE_OK.
// **
// ** If there is not enough free space in pNode, return SQLITE_FULL.
// */
func _nodeInsertCell(tls *libc.TLS, pRtree uintptr, pNode uintptr, pCell uintptr) (r int32) {
var nCell, nMaxCell int32
_, _ = nCell, nMaxCell /* Maximum number of cells for pNode */
nMaxCell = ((*TRtree)(unsafe.Pointer(pRtree)).FiNodeSize - int32(4)) / libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FnBytesPerCell)
nCell = _readInt16(tls, (*TRtreeNode)(unsafe.Pointer(pNode)).FzData+2)
if nCell < nMaxCell {
_nodeOverwriteCell(tls, pRtree, pNode, pCell, nCell)
_writeInt16(tls, (*TRtreeNode)(unsafe.Pointer(pNode)).FzData+2, nCell+int32(1))
(*TRtreeNode)(unsafe.Pointer(pNode)).FisDirty = int32(1)
}
return libc.BoolInt32(nCell == nMaxCell)
}
// C documentation
//
// /*
// ** Overwrite cell iCell of node pNode with the contents of pCell.
// */
func _nodeOverwriteCell(tls *libc.TLS, pRtree uintptr, pNode uintptr, pCell uintptr, iCell int32) {
var ii int32
var p uintptr
_, _ = ii, p
p = (*TRtreeNode)(unsafe.Pointer(pNode)).FzData + uintptr(int32(4)+libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FnBytesPerCell)*iCell)
p = p + uintptr(_writeInt64(tls, p, (*TRtreeCell)(unsafe.Pointer(pCell)).FiRowid))
ii = 0
for {
if !(ii < libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FnDim2)) {
break
}
p = p + uintptr(_writeCoord(tls, p, pCell+8+uintptr(ii)*4))
goto _1
_1:
;
ii = ii + 1
}
(*TRtreeNode)(unsafe.Pointer(pNode)).FisDirty = int32(1)
}
func _nolockCheckReservedLock(tls *libc.TLS, NotUsed uintptr, pResOut uintptr) (r int32) {
_ = NotUsed
**(**int32)(__ccgo_up(pResOut)) = 0
return SQLITE_OK
}
// C documentation
//
// /*
// ** Close the file.
// */
func _nolockClose(tls *libc.TLS, id uintptr) (r int32) {
return _closeUnixFile(tls, id)
}
/******************* End of the no-op lock implementation *********************
******************************************************************************/
/******************************************************************************
************************* Begin dot-file Locking ******************************
**
** The dotfile locking implementation uses the existence of separate lock
** files (really a directory) to control access to the database. This works
** on just about every filesystem imaginable. But there are serious downsides:
**
** (1) There is zero concurrency. A single reader blocks all other
** connections from reading or writing the database.
**
** (2) An application crash or power loss can leave stale lock files
** sitting around that need to be cleared manually.
**
** Nevertheless, a dotlock is an appropriate locking mode for use if no
** other locking strategy is available.
**
** Dotfile locking works by creating a subdirectory in the same directory as
** the database and with the same name but with a ".lock" extension added.
** The existence of a lock directory implies an EXCLUSIVE lock. All other
** lock types (SHARED, RESERVED, PENDING) are mapped into EXCLUSIVE.
*/
/*
** The file suffix added to the data base filename in order to create the
** lock directory.
*/
var _nolockIoFinder = uintptr(0)
func _nolockIoFinderImpl(tls *libc.TLS, z uintptr, p uintptr) (r uintptr) {
_ = z
_ = p
return uintptr(unsafe.Pointer(&_nolockIoMethods))
}
var _nolockIoMethods = Tsqlite3_io_methods{
FiVersion: int32(3),
}
func _nolockLock(tls *libc.TLS, NotUsed uintptr, NotUsed2 int32) (r int32) {
_ = NotUsed
_ = NotUsed2
return SQLITE_OK
}
func _nolockUnlock(tls *libc.TLS, NotUsed uintptr, NotUsed2 int32) (r int32) {
_ = NotUsed
_ = NotUsed2
return SQLITE_OK
}
// C documentation
//
// /*
// ** Return the numeric type for pMem, either MEM_Int or MEM_Real or both or
// ** none.
// **
// ** Unlike applyNumericAffinity(), this routine does not modify pMem->flags.
// ** But it does set pMem->u.r and pMem->u.i appropriately.
// */
func _numericType(tls *libc.TLS, pMem uintptr) (r Tu16) {
if libc.Int32FromUint16((*TMem)(unsafe.Pointer(pMem)).Fflags)&(libc.Int32FromInt32(MEM_Int)|libc.Int32FromInt32(MEM_Real)|libc.Int32FromInt32(MEM_IntReal)|libc.Int32FromInt32(MEM_Null)) != 0 {
return libc.Uint16FromInt32(libc.Int32FromUint16((*TMem)(unsafe.Pointer(pMem)).Fflags) & (libc.Int32FromInt32(MEM_Int) | libc.Int32FromInt32(MEM_Real) | libc.Int32FromInt32(MEM_IntReal) | libc.Int32FromInt32(MEM_Null)))
}
return _computeNumericType(tls, pMem)
return uint16(0)
}
// C documentation
//
// /*
// ** Ensure that the sub-journal file is open. If it is already open, this
// ** function is a no-op.
// **
// ** SQLITE_OK is returned if everything goes according to plan. An
// ** SQLITE_IOERR_XXX error code is returned if a call to sqlite3OsOpen()
// ** fails.
// */
func _openSubJournal(tls *libc.TLS, pPager uintptr) (r int32) {
var flags, nStmtSpill, rc int32
_, _, _ = flags, nStmtSpill, rc
rc = SQLITE_OK
if !((*Tsqlite3_file)(unsafe.Pointer((*TPager)(unsafe.Pointer(pPager)).Fsjfd)).FpMethods != libc.UintptrFromInt32(0)) {
flags = libc.Int32FromInt32(SQLITE_OPEN_SUBJOURNAL) | libc.Int32FromInt32(SQLITE_OPEN_READWRITE) | libc.Int32FromInt32(SQLITE_OPEN_CREATE) | libc.Int32FromInt32(SQLITE_OPEN_EXCLUSIVE) | libc.Int32FromInt32(SQLITE_OPEN_DELETEONCLOSE)
nStmtSpill = _sqlite3Config.FnStmtSpill
if libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FjournalMode) == int32(PAGER_JOURNALMODE_MEMORY) || (*TPager)(unsafe.Pointer(pPager)).FsubjInMemory != 0 {
nStmtSpill = -int32(1)
}
rc = _sqlite3JournalOpen(tls, (*TPager)(unsafe.Pointer(pPager)).FpVfs, uintptr(0), (*TPager)(unsafe.Pointer(pPager)).Fsjfd, flags, nStmtSpill)
}
return rc
}
// C documentation
//
// /*
// ** Translate from TK_xx operator to WO_xx bitmask.
// */
func _operatorMask(tls *libc.TLS, op int32) (r Tu16) {
var c Tu16
_ = c
if op >= int32(TK_EQ) {
c = libc.Uint16FromInt32(libc.Int32FromInt32(WO_EQ) << (op - libc.Int32FromInt32(TK_EQ)))
} else {
if op == int32(TK_IN) {
c = uint16(WO_IN)
} else {
if op == int32(TK_ISNULL) {
c = uint16(WO_ISNULL)
} else {
c = uint16(WO_IS)
}
}
}
return c
}
// C documentation
//
// /*
// ** The following routine implements the rough equivalent of localtime_r()
// ** using whatever operating-system specific localtime facility that
// ** is available. This routine returns 0 on success and
// ** non-zero on any kind of error.
// **
// ** If the sqlite3GlobalConfig.bLocaltimeFault variable is non-zero then this
// ** routine will always fail. If bLocaltimeFault is nonzero and
// ** sqlite3GlobalConfig.xAltLocaltime is not NULL, then xAltLocaltime() is
// ** invoked in place of the OS-defined localtime() function.
// **
// ** EVIDENCE-OF: R-62172-00036 In this implementation, the standard C
// ** library function localtime_r() is used to assist in the calculation of
// ** local time.
// */
func _osLocaltime(tls *libc.TLS, t uintptr, pTm uintptr) (r int32) {
var mutex, pX uintptr
var rc int32
_, _, _ = mutex, pX, rc
mutex = _sqlite3MutexAlloc(tls, int32(SQLITE_MUTEX_STATIC_MAIN))
Xsqlite3_mutex_enter(tls, mutex)
pX = libc.Xlocaltime(tls, t)
if _sqlite3Config.FbLocaltimeFault != 0 {
if _sqlite3Config.FxAltLocaltime != uintptr(0) && 0 == (*(*func(*libc.TLS, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_sqlite3Config.FxAltLocaltime})))(tls, t, pTm) {
pX = pTm
} else {
pX = uintptr(0)
}
}
if pX != 0 {
**(**Ttm)(__ccgo_up(pTm)) = **(**Ttm)(__ccgo_up(pX))
}
Xsqlite3_mutex_leave(tls, mutex)
rc = libc.BoolInt32(pX == uintptr(0))
return rc
}
// C documentation
//
// /*
// ** Attempt to take an exclusive lock on the database file. If a PENDING lock
// ** is obtained instead, immediately release it.
// */
func _pagerExclusiveLock(tls *libc.TLS, pPager uintptr) (r int32) {
var eOrigLock Tu8
var rc int32
_, _ = eOrigLock, rc /* Original lock */
eOrigLock = (*TPager)(unsafe.Pointer(pPager)).FeLock
rc = _pagerLockDb(tls, pPager, int32(EXCLUSIVE_LOCK))
if rc != SQLITE_OK {
/* If the attempt to grab the exclusive lock failed, release the
** pending lock that may have been obtained instead. */
_pagerUnlockDb(tls, pPager, libc.Int32FromUint8(eOrigLock))
}
return rc
}
// C documentation
//
// /*
// ** The write transaction open on pPager is being committed (bCommit==1)
// ** or rolled back (bCommit==0).
// **
// ** Return TRUE if and only if all dirty pages should be flushed to disk.
// **
// ** Rules:
// **
// ** * For non-TEMP databases, always sync to disk. This is necessary
// ** for transactions to be durable.
// **
// ** * Sync TEMP database only on a COMMIT (not a ROLLBACK) when the backing
// ** file has been created already (via a spill on pagerStress()) and
// ** when the number of dirty pages in memory exceeds 25% of the total
// ** cache size.
// */
func _pagerFlushOnCommit(tls *libc.TLS, pPager uintptr, bCommit int32) (r int32) {
if libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FtempFile) == 0 {
return int32(1)
}
if !(bCommit != 0) {
return 0
}
if !((*Tsqlite3_file)(unsafe.Pointer((*TPager)(unsafe.Pointer(pPager)).Ffd)).FpMethods != libc.UintptrFromInt32(0)) {
return 0
}
return libc.BoolInt32(_sqlite3PCachePercentDirty(tls, (*TPager)(unsafe.Pointer(pPager)).FpPCache) >= int32(25))
}
// C documentation
//
// /*
// ** Lock the database file to level eLock, which must be either SHARED_LOCK,
// ** RESERVED_LOCK or EXCLUSIVE_LOCK. If the caller is successful, set the
// ** Pager.eLock variable to the new locking state.
// **
// ** Except, if Pager.eLock is set to UNKNOWN_LOCK when this function is
// ** called, do not modify it unless the new locking state is EXCLUSIVE_LOCK.
// ** See the comment above the #define of UNKNOWN_LOCK for an explanation
// ** of this.
// */
func _pagerLockDb(tls *libc.TLS, pPager uintptr, eLock int32) (r int32) {
var rc, v1 int32
_, _ = rc, v1
rc = SQLITE_OK
if libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FeLock) < eLock || libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FeLock) == libc.Int32FromInt32(EXCLUSIVE_LOCK)+libc.Int32FromInt32(1) {
if (*TPager)(unsafe.Pointer(pPager)).FnoLock != 0 {
v1 = SQLITE_OK
} else {
v1 = _sqlite3OsLock(tls, (*TPager)(unsafe.Pointer(pPager)).Ffd, eLock)
}
rc = v1
if rc == SQLITE_OK && (libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FeLock) != libc.Int32FromInt32(EXCLUSIVE_LOCK)+libc.Int32FromInt32(1) || eLock == int32(EXCLUSIVE_LOCK)) {
(*TPager)(unsafe.Pointer(pPager)).FeLock = libc.Uint8FromInt32(eLock)
}
}
return rc
}
// C documentation
//
// /*
// ** Check if the *-wal file that corresponds to the database opened by pPager
// ** exists if the database is not empty, or verify that the *-wal file does
// ** not exist (by deleting it) if the database file is empty.
// **
// ** If the database is not empty and the *-wal file exists, open the pager
// ** in WAL mode. If the database is empty or if no *-wal file exists and
// ** if no error occurs, make sure Pager.journalMode is not set to
// ** PAGER_JOURNALMODE_WAL.
// **
// ** Return SQLITE_OK or an error code.
// **
// ** The caller must hold a SHARED lock on the database file to call this
// ** function. Because an EXCLUSIVE lock on the db file is required to delete
// ** a WAL on a none-empty database, this ensures there is no race condition
// ** between the xAccess() below and an xDelete() being executed by some
// ** other connection.
// */
func _pagerOpenWalIfPresent(tls *libc.TLS, pPager uintptr) (r int32) {
bp := tls.Alloc(16)
defer tls.Free(16)
var rc int32
var _ /* isWal at bp+0 */ int32
var _ /* nPage at bp+4 */ TPgno
_ = rc
rc = SQLITE_OK
if !((*TPager)(unsafe.Pointer(pPager)).FtempFile != 0) { /* True if WAL file exists */
rc = _sqlite3OsAccess(tls, (*TPager)(unsafe.Pointer(pPager)).FpVfs, (*TPager)(unsafe.Pointer(pPager)).FzWal, SQLITE_ACCESS_EXISTS, bp)
if rc == SQLITE_OK {
if **(**int32)(__ccgo_up(bp)) != 0 { /* Size of the database file */
rc = _pagerPagecount(tls, pPager, bp+4)
if rc != 0 {
return rc
}
if **(**TPgno)(__ccgo_up(bp + 4)) == uint32(0) {
rc = _sqlite3OsDelete(tls, (*TPager)(unsafe.Pointer(pPager)).FpVfs, (*TPager)(unsafe.Pointer(pPager)).FzWal, 0)
} else {
rc = _sqlite3PagerOpenWal(tls, pPager, uintptr(0))
}
} else {
if libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FjournalMode) == int32(PAGER_JOURNALMODE_WAL) {
(*TPager)(unsafe.Pointer(pPager)).FjournalMode = uint8(PAGER_JOURNALMODE_DELETE)
}
}
}
}
return rc
}
// C documentation
//
// /*
// ** This function is called as part of the transition from PAGER_OPEN
// ** to PAGER_READER state to determine the size of the database file
// ** in pages (assuming the page size currently stored in Pager.pageSize).
// **
// ** If no error occurs, SQLITE_OK is returned and the size of the database
// ** in pages is stored in *pnPage. Otherwise, an error code (perhaps
// ** SQLITE_IOERR_FSTAT) is returned and *pnPage is left unmodified.
// */
func _pagerPagecount(tls *libc.TLS, pPager uintptr, pnPage uintptr) (r int32) {
bp := tls.Alloc(16)
defer tls.Free(16)
var nPage TPgno
var rc int32
var _ /* n at bp+0 */ Ti64
_, _ = nPage, rc /* Value to return via *pnPage */
/* Query the WAL sub-system for the database size. The WalDbsize()
** function returns zero if the WAL is not open (i.e. Pager.pWal==0), or
** if the database size is not available. The database size is not
** available from the WAL sub-system if the log file is empty or
** contains no valid committed transactions.
*/
nPage = _sqlite3WalDbsize(tls, (*TPager)(unsafe.Pointer(pPager)).FpWal)
/* If the number of pages in the database is not available from the
** WAL sub-system, determine the page count based on the size of
** the database file. If the size of the database file is not an
** integer multiple of the page-size, round up the result.
*/
if nPage == uint32(0) && (*Tsqlite3_file)(unsafe.Pointer((*TPager)(unsafe.Pointer(pPager)).Ffd)).FpMethods != uintptr(0) {
**(**Ti64)(__ccgo_up(bp)) = 0 /* Size of db file in bytes */
rc = _sqlite3OsFileSize(tls, (*TPager)(unsafe.Pointer(pPager)).Ffd, bp)
if rc != SQLITE_OK {
return rc
}
nPage = libc.Uint32FromInt64((**(**Ti64)(__ccgo_up(bp)) + (*TPager)(unsafe.Pointer(pPager)).FpageSize - libc.Int64FromInt32(1)) / (*TPager)(unsafe.Pointer(pPager)).FpageSize)
}
/* If the current number of pages in the file is greater than the
** configured maximum pager number, increase the allowed limit so
** that the file can be read.
*/
if nPage > (*TPager)(unsafe.Pointer(pPager)).FmxPgno {
(*TPager)(unsafe.Pointer(pPager)).FmxPgno = nPage
}
**(**TPgno)(__ccgo_up(pnPage)) = nPage
return SQLITE_OK
}
// C documentation
//
// /*
// ** Release a reference to page pPg. pPg must have been returned by an
// ** earlier call to pagerAcquireMapPage().
// */
func _pagerReleaseMapPage(tls *libc.TLS, pPg uintptr) {
var pPager uintptr
_ = pPager
pPager = (*TPgHdr)(unsafe.Pointer(pPg)).FpPager
(*TPager)(unsafe.Pointer(pPager)).FnMmapOut = (*TPager)(unsafe.Pointer(pPager)).FnMmapOut - 1
(*TPgHdr)(unsafe.Pointer(pPg)).FpDirty = (*TPager)(unsafe.Pointer(pPager)).FpMmapFreelist
(*TPager)(unsafe.Pointer(pPager)).FpMmapFreelist = pPg
_sqlite3OsUnfetch(tls, (*TPager)(unsafe.Pointer(pPager)).Ffd, libc.Int64FromUint32((*TPgHdr)(unsafe.Pointer(pPg)).Fpgno-libc.Uint32FromInt32(1))*(*TPager)(unsafe.Pointer(pPager)).FpageSize, (*TPgHdr)(unsafe.Pointer(pPg)).FpData)
}
// C documentation
//
// /*
// ** Execute a rollback if a transaction is active and unlock the
// ** database file.
// **
// ** If the pager has already entered the ERROR state, do not attempt
// ** the rollback at this time. Instead, pager_unlock() is called. The
// ** call to pager_unlock() will discard all in-memory pages, unlock
// ** the database file and move the pager back to OPEN state. If this
// ** means that there is a hot-journal left in the file-system, the next
// ** connection to obtain a shared lock on the pager (which may be this one)
// ** will roll it back.
// **
// ** If the pager has not already entered the ERROR state, but an IO or
// ** malloc error occurs during a rollback, then this will itself cause
// ** the pager to enter the ERROR state. Which will be cleared by the
// ** call to pager_unlock(), as described above.
// */
func _pagerUnlockAndRollback(tls *libc.TLS, pPager uintptr) {
var eLock Tu8
var errCode int32
_, _ = eLock, errCode
if libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FeState) != int32(PAGER_ERROR) && libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FeState) != PAGER_OPEN {
if libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FeState) >= int32(PAGER_WRITER_LOCKED) {
_sqlite3BeginBenignMalloc(tls)
_sqlite3PagerRollback(tls, pPager)
_sqlite3EndBenignMalloc(tls)
} else {
if !((*TPager)(unsafe.Pointer(pPager)).FexclusiveMode != 0) {
_pager_end_transaction(tls, pPager, 0, 0)
}
}
} else {
if libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FeState) == int32(PAGER_ERROR) && libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FjournalMode) == int32(PAGER_JOURNALMODE_MEMORY) && (*Tsqlite3_file)(unsafe.Pointer((*TPager)(unsafe.Pointer(pPager)).Fjfd)).FpMethods != uintptr(0) {
/* Special case for a ROLLBACK due to I/O error with an in-memory
** journal: We have to rollback immediately, before the journal is
** closed, because once it is closed, all content is forgotten. */
errCode = (*TPager)(unsafe.Pointer(pPager)).FerrCode
eLock = (*TPager)(unsafe.Pointer(pPager)).FeLock
(*TPager)(unsafe.Pointer(pPager)).FeState = uint8(PAGER_OPEN)
(*TPager)(unsafe.Pointer(pPager)).FerrCode = SQLITE_OK
(*TPager)(unsafe.Pointer(pPager)).FeLock = uint8(EXCLUSIVE_LOCK)
_pager_playback(tls, pPager, int32(1))
(*TPager)(unsafe.Pointer(pPager)).FerrCode = errCode
(*TPager)(unsafe.Pointer(pPager)).FeLock = eLock
}
}
_pager_unlock(tls, pPager)
}
// C documentation
//
// /*
// ** Unlock the database file to level eLock, which must be either NO_LOCK
// ** or SHARED_LOCK. Regardless of whether or not the call to xUnlock()
// ** succeeds, set the Pager.eLock variable to match the (attempted) new lock.
// **
// ** Except, if Pager.eLock is set to UNKNOWN_LOCK when this function is
// ** called, do not modify it. See the comment above the #define of
// ** UNKNOWN_LOCK for an explanation of this.
// */
func _pagerUnlockDb(tls *libc.TLS, pPager uintptr, eLock int32) (r int32) {
var rc, v1 int32
_, _ = rc, v1
rc = SQLITE_OK
if (*Tsqlite3_file)(unsafe.Pointer((*TPager)(unsafe.Pointer(pPager)).Ffd)).FpMethods != uintptr(0) {
if (*TPager)(unsafe.Pointer(pPager)).FnoLock != 0 {
v1 = SQLITE_OK
} else {
v1 = _sqlite3OsUnlock(tls, (*TPager)(unsafe.Pointer(pPager)).Ffd, eLock)
}
rc = v1
if libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FeLock) != libc.Int32FromInt32(EXCLUSIVE_LOCK)+libc.Int32FromInt32(1) {
(*TPager)(unsafe.Pointer(pPager)).FeLock = libc.Uint8FromInt32(eLock)
}
}
(*TPager)(unsafe.Pointer(pPager)).FchangeCountDone = (*TPager)(unsafe.Pointer(pPager)).FtempFile /* ticket fb3b3024ea238d5c */
return rc
}
// C documentation
//
// /*
// ** This routine ends a transaction. A transaction is usually ended by
// ** either a COMMIT or a ROLLBACK operation. This routine may be called
// ** after rollback of a hot-journal, or if an error occurs while opening
// ** the journal file or writing the very first journal-header of a
// ** database transaction.
// **
// ** This routine is never called in PAGER_ERROR state. If it is called
// ** in PAGER_NONE or PAGER_SHARED state and the lock held is less
// ** exclusive than a RESERVED lock, it is a no-op.
// **
// ** Otherwise, any active savepoints are released.
// **
// ** If the journal file is open, then it is "finalized". Once a journal
// ** file has been finalized it is not possible to use it to roll back a
// ** transaction. Nor will it be considered to be a hot-journal by this
// ** or any other database connection. Exactly how a journal is finalized
// ** depends on whether or not the pager is running in exclusive mode and
// ** the current journal-mode (Pager.journalMode value), as follows:
// **
// ** journalMode==MEMORY
// ** Journal file descriptor is simply closed. This destroys an
// ** in-memory journal.
// **
// ** journalMode==TRUNCATE
// ** Journal file is truncated to zero bytes in size.
// **
// ** journalMode==PERSIST
// ** The first 28 bytes of the journal file are zeroed. This invalidates
// ** the first journal header in the file, and hence the entire journal
// ** file. An invalid journal file cannot be rolled back.
// **
// ** journalMode==DELETE
// ** The journal file is closed and deleted using sqlite3OsDelete().
// **
// ** If the pager is running in exclusive mode, this method of finalizing
// ** the journal file is never used. Instead, if the journalMode is
// ** DELETE and the pager is in exclusive mode, the method described under
// ** journalMode==PERSIST is used instead.
// **
// ** After the journal is finalized, the pager moves to PAGER_READER state.
// ** If running in non-exclusive rollback mode, the lock on the file is
// ** downgraded to a SHARED_LOCK.
// **
// ** SQLITE_OK is returned if no error occurs. If an error occurs during
// ** any of the IO operations to finalize the journal file or unlock the
// ** database then the IO error code is returned to the user. If the
// ** operation to finalize the journal file fails, then the code still
// ** tries to unlock the database file if not in exclusive mode. If the
// ** unlock operation fails as well, then the first error code related
// ** to the first error encountered (the journal finalization one) is
// ** returned.
// */
func _pager_end_transaction(tls *libc.TLS, pPager uintptr, hasSuper int32, bCommit int32) (r int32) {
var bDelete, rc, rc2, v1 int32
_, _, _, _ = bDelete, rc, rc2, v1
rc = SQLITE_OK /* Error code from journal finalization operation */
rc2 = SQLITE_OK /* Error code from db file unlock operation */
/* Do nothing if the pager does not have an open write transaction
** or at least a RESERVED lock. This function may be called when there
** is no write-transaction active but a RESERVED or greater lock is
** held under two circumstances:
**
** 1. After a successful hot-journal rollback, it is called with
** eState==PAGER_NONE and eLock==EXCLUSIVE_LOCK.
**
** 2. If a connection with locking_mode=exclusive holding an EXCLUSIVE
** lock switches back to locking_mode=normal and then executes a
** read-transaction, this function is called with eState==PAGER_READER
** and eLock==EXCLUSIVE_LOCK when the read-transaction is closed.
*/
if libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FeState) < int32(PAGER_WRITER_LOCKED) && libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FeLock) < int32(RESERVED_LOCK) {
return SQLITE_OK
}
_releaseAllSavepoints(tls, pPager)
if (*Tsqlite3_file)(unsafe.Pointer((*TPager)(unsafe.Pointer(pPager)).Fjfd)).FpMethods != uintptr(0) {
/* Finalize the journal file. */
if _sqlite3JournalIsInMemory(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd) != 0 {
/* assert( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ); */
_sqlite3OsClose(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd)
} else {
if libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FjournalMode) == int32(PAGER_JOURNALMODE_TRUNCATE) {
if (*TPager)(unsafe.Pointer(pPager)).FjournalOff == 0 {
rc = SQLITE_OK
} else {
rc = _sqlite3OsTruncate(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd, 0)
if rc == SQLITE_OK && (*TPager)(unsafe.Pointer(pPager)).FfullSync != 0 {
/* Make sure the new file size is written into the inode right away.
** Otherwise the journal might resurrect following a power loss and
** cause the last transaction to roll back. See
** https://bugzilla.mozilla.org/show_bug.cgi?id=1072773
*/
rc = _sqlite3OsSync(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd, libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FsyncFlags))
}
}
(*TPager)(unsafe.Pointer(pPager)).FjournalOff = 0
} else {
if libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FjournalMode) == int32(PAGER_JOURNALMODE_PERSIST) || (*TPager)(unsafe.Pointer(pPager)).FexclusiveMode != 0 && libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FjournalMode) < int32(PAGER_JOURNALMODE_WAL) {
rc = _zeroJournalHdr(tls, pPager, libc.BoolInt32(hasSuper != 0 || (*TPager)(unsafe.Pointer(pPager)).FtempFile != 0))
(*TPager)(unsafe.Pointer(pPager)).FjournalOff = 0
} else {
/* This branch may be executed with Pager.journalMode==MEMORY if
** a hot-journal was just rolled back. In this case the journal
** file should be closed and deleted. If this connection writes to
** the database file, it will do so using an in-memory journal.
*/
bDelete = libc.BoolInt32(!((*TPager)(unsafe.Pointer(pPager)).FtempFile != 0))
_sqlite3OsClose(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd)
if bDelete != 0 {
rc = _sqlite3OsDelete(tls, (*TPager)(unsafe.Pointer(pPager)).FpVfs, (*TPager)(unsafe.Pointer(pPager)).FzJournal, libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FextraSync))
}
}
}
}
}
_sqlite3BitvecDestroy(tls, (*TPager)(unsafe.Pointer(pPager)).FpInJournal)
(*TPager)(unsafe.Pointer(pPager)).FpInJournal = uintptr(0)
(*TPager)(unsafe.Pointer(pPager)).FnRec = 0
if rc == SQLITE_OK {
if (*TPager)(unsafe.Pointer(pPager)).FmemDb != 0 || _pagerFlushOnCommit(tls, pPager, bCommit) != 0 {
_sqlite3PcacheCleanAll(tls, (*TPager)(unsafe.Pointer(pPager)).FpPCache)
} else {
_sqlite3PcacheClearWritable(tls, (*TPager)(unsafe.Pointer(pPager)).FpPCache)
}
_sqlite3PcacheTruncate(tls, (*TPager)(unsafe.Pointer(pPager)).FpPCache, (*TPager)(unsafe.Pointer(pPager)).FdbSize)
}
if (*TPager)(unsafe.Pointer(pPager)).FpWal != uintptr(0) {
/* Drop the WAL write-lock, if any. Also, if the connection was in
** locking_mode=exclusive mode but is no longer, drop the EXCLUSIVE
** lock held on the database file.
*/
rc2 = _sqlite3WalEndWriteTransaction(tls, (*TPager)(unsafe.Pointer(pPager)).FpWal)
} else {
if rc == SQLITE_OK && bCommit != 0 && (*TPager)(unsafe.Pointer(pPager)).FdbFileSize > (*TPager)(unsafe.Pointer(pPager)).FdbSize {
/* This branch is taken when committing a transaction in rollback-journal
** mode if the database file on disk is larger than the database image.
** At this point the journal has been finalized and the transaction
** successfully committed, but the EXCLUSIVE lock is still held on the
** file. So it is safe to truncate the database file to its minimum
** required size. */
rc = _pager_truncate(tls, pPager, (*TPager)(unsafe.Pointer(pPager)).FdbSize)
}
}
if rc == SQLITE_OK && bCommit != 0 {
rc = _sqlite3OsFileControl(tls, (*TPager)(unsafe.Pointer(pPager)).Ffd, int32(SQLITE_FCNTL_COMMIT_PHASETWO), uintptr(0))
if rc == int32(SQLITE_NOTFOUND) {
rc = SQLITE_OK
}
}
if !((*TPager)(unsafe.Pointer(pPager)).FexclusiveMode != 0) && (!((*TPager)(unsafe.Pointer(pPager)).FpWal != libc.UintptrFromInt32(0)) || _sqlite3WalExclusiveMode(tls, (*TPager)(unsafe.Pointer(pPager)).FpWal, 0) != 0) {
rc2 = _pagerUnlockDb(tls, pPager, int32(SHARED_LOCK))
}
(*TPager)(unsafe.Pointer(pPager)).FeState = uint8(PAGER_READER)
(*TPager)(unsafe.Pointer(pPager)).FsetSuper = uint8(0)
if rc == SQLITE_OK {
v1 = rc2
} else {
v1 = rc
}
return v1
}
// C documentation
//
// /*
// ** This function is called at the start of every write transaction.
// ** There must already be a RESERVED or EXCLUSIVE lock on the database
// ** file when this routine is called.
// **
// ** Open the journal file for pager pPager and write a journal header
// ** to the start of it. If there are active savepoints, open the sub-journal
// ** as well. This function is only used when the journal file is being
// ** opened to write a rollback log for a transaction. It is not used
// ** when opening a hot journal file to roll it back.
// **
// ** If the journal file is already open (as it may be in exclusive mode),
// ** then this function just writes a journal header to the start of the
// ** already open file.
// **
// ** Whether or not the journal file is opened by this function, the
// ** Pager.pInJournal bitvec structure is allocated.
// **
// ** Return SQLITE_OK if everything is successful. Otherwise, return
// ** SQLITE_NOMEM if the attempt to allocate Pager.pInJournal fails, or
// ** an IO error code if opening or writing the journal file fails.
// */
func _pager_open_journal(tls *libc.TLS, pPager uintptr) (r int32) {
var flags, nSpill, rc int32
var pVfs uintptr
_, _, _, _ = flags, nSpill, pVfs, rc
rc = SQLITE_OK /* Return code */
pVfs = (*TPager)(unsafe.Pointer(pPager)).FpVfs /* Local cache of vfs pointer */
/* If already in the error state, this function is a no-op. But on
** the other hand, this routine is never called if we are already in
** an error state. */
if (*TPager)(unsafe.Pointer(pPager)).FerrCode != 0 {
return (*TPager)(unsafe.Pointer(pPager)).FerrCode
}
if !((*TPager)(unsafe.Pointer(pPager)).FpWal != libc.UintptrFromInt32(0)) && libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FjournalMode) != int32(PAGER_JOURNALMODE_OFF) {
(*TPager)(unsafe.Pointer(pPager)).FpInJournal = _sqlite3BitvecCreate(tls, (*TPager)(unsafe.Pointer(pPager)).FdbSize)
if (*TPager)(unsafe.Pointer(pPager)).FpInJournal == uintptr(0) {
return int32(SQLITE_NOMEM)
}
/* Open the journal file if it is not already open. */
if !((*Tsqlite3_file)(unsafe.Pointer((*TPager)(unsafe.Pointer(pPager)).Fjfd)).FpMethods != libc.UintptrFromInt32(0)) {
if libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FjournalMode) == int32(PAGER_JOURNALMODE_MEMORY) {
_sqlite3MemJournalOpen(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd)
} else {
flags = libc.Int32FromInt32(SQLITE_OPEN_READWRITE) | libc.Int32FromInt32(SQLITE_OPEN_CREATE)
if (*TPager)(unsafe.Pointer(pPager)).FtempFile != 0 {
flags = flags | (libc.Int32FromInt32(SQLITE_OPEN_DELETEONCLOSE) | libc.Int32FromInt32(SQLITE_OPEN_TEMP_JOURNAL))
flags = flags | int32(SQLITE_OPEN_EXCLUSIVE)
nSpill = _sqlite3Config.FnStmtSpill
} else {
flags = flags | int32(SQLITE_OPEN_MAIN_JOURNAL)
nSpill = _jrnlBufferSize(tls, pPager)
}
/* Verify that the database still has the same name as it did when
** it was originally opened. */
rc = _databaseIsUnmoved(tls, pPager)
if rc == SQLITE_OK {
rc = _sqlite3JournalOpen(tls, pVfs, (*TPager)(unsafe.Pointer(pPager)).FzJournal, (*TPager)(unsafe.Pointer(pPager)).Fjfd, flags, nSpill)
}
}
}
/* Write the first journal header to the journal file and open
** the sub-journal if necessary.
*/
if rc == SQLITE_OK {
/* TODO: Check if all of these are really required. */
(*TPager)(unsafe.Pointer(pPager)).FnRec = 0
(*TPager)(unsafe.Pointer(pPager)).FjournalOff = 0
(*TPager)(unsafe.Pointer(pPager)).FsetSuper = uint8(0)
(*TPager)(unsafe.Pointer(pPager)).FjournalHdr = 0
rc = _writeJournalHdr(tls, pPager)
}
}
if rc != SQLITE_OK {
_sqlite3BitvecDestroy(tls, (*TPager)(unsafe.Pointer(pPager)).FpInJournal)
(*TPager)(unsafe.Pointer(pPager)).FpInJournal = uintptr(0)
(*TPager)(unsafe.Pointer(pPager)).FjournalOff = 0
} else {
(*TPager)(unsafe.Pointer(pPager)).FeState = uint8(PAGER_WRITER_CACHEMOD)
}
return rc
}
// C documentation
//
// /* Memory allocator for parser stack resizing. This is a thin wrapper around
// ** sqlite3_realloc() that includes a call to sqlite3FaultSim() to facilitate
// ** testing.
// */
func _parserStackRealloc(tls *libc.TLS, pOld uintptr, newSize Tsqlite3_uint64, pParse uintptr) (r uintptr) {
var p, v1 uintptr
_, _ = p, v1
if _sqlite3FaultSim(tls, int32(700)) != 0 {
v1 = uintptr(0)
} else {
v1 = Xsqlite3_realloc(tls, pOld, libc.Int32FromUint64(newSize))
}
p = v1
if p == uintptr(0) {
_sqlite3OomFault(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb)
}
return p
}
// C documentation
//
// /*
// ** If there are currently more than nMaxPage pages allocated, try
// ** to recycle pages to reduce the number allocated to nMaxPage.
// */
func _pcache1EnforceMaxPage(tls *libc.TLS, pCache uintptr) {
var p, pGroup, v1 uintptr
var v2 bool
_, _, _, _ = p, pGroup, v1, v2
pGroup = (*TPCache1)(unsafe.Pointer(pCache)).FpGroup
for {
if v2 = (*TPGroup)(unsafe.Pointer(pGroup)).FnPurgeable > (*TPGroup)(unsafe.Pointer(pGroup)).FnMaxPage; v2 {
v1 = (*TPGroup)(unsafe.Pointer(pGroup)).Flru.FpLruPrev
p = v1
}
if !(v2 && libc.Int32FromUint16((*TPgHdr1)(unsafe.Pointer(v1)).FisAnchor) == 0) {
break
}
_pcache1PinPage(tls, p)
_pcache1RemoveFromHash(tls, p, int32(1))
}
if (*TPCache1)(unsafe.Pointer(pCache)).FnPage == uint32(0) && (*TPCache1)(unsafe.Pointer(pCache)).FpBulk != 0 {
Xsqlite3_free(tls, (*TPCache1)(unsafe.Pointer(pCache)).FpBulk)
v1 = libc.UintptrFromInt32(0)
(*TPCache1)(unsafe.Pointer(pCache)).FpFree = v1
(*TPCache1)(unsafe.Pointer(pCache)).FpBulk = v1
}
}
// C documentation
//
// /*
// ** Implementation of the sqlite3_pcache.xPagecount method.
// */
func _pcache1Pagecount(tls *libc.TLS, p uintptr) (r int32) {
var n int32
var pCache uintptr
_, _ = n, pCache
pCache = p
Xsqlite3_mutex_enter(tls, (*TPGroup)(unsafe.Pointer((*TPCache1)(unsafe.Pointer(pCache)).FpGroup)).Fmutex)
n = libc.Int32FromUint32((*TPCache1)(unsafe.Pointer(pCache)).FnPage)
Xsqlite3_mutex_leave(tls, (*TPGroup)(unsafe.Pointer((*TPCache1)(unsafe.Pointer(pCache)).FpGroup)).Fmutex)
return n
}
// C documentation
//
// /*
// ** Manage pPage's participation on the dirty list. Bits of the addRemove
// ** argument determines what operation to do. The 0x01 bit means first
// ** remove pPage from the dirty list. The 0x02 means add pPage back to
// ** the dirty list. Doing both moves pPage to the front of the dirty list.
// */
func _pcacheManageDirtyList(tls *libc.TLS, pPage uintptr, addRemove Tu8) {
var p uintptr
_ = p
p = (*TPgHdr)(unsafe.Pointer(pPage)).FpCache
if libc.Int32FromUint8(addRemove)&int32(PCACHE_DIRTYLIST_REMOVE) != 0 {
/* Update the PCache1.pSynced variable if necessary. */
if (*TPCache)(unsafe.Pointer(p)).FpSynced == pPage {
(*TPCache)(unsafe.Pointer(p)).FpSynced = (*TPgHdr)(unsafe.Pointer(pPage)).FpDirtyPrev
}
if (*TPgHdr)(unsafe.Pointer(pPage)).FpDirtyNext != 0 {
(*TPgHdr)(unsafe.Pointer((*TPgHdr)(unsafe.Pointer(pPage)).FpDirtyNext)).FpDirtyPrev = (*TPgHdr)(unsafe.Pointer(pPage)).FpDirtyPrev
} else {
(*TPCache)(unsafe.Pointer(p)).FpDirtyTail = (*TPgHdr)(unsafe.Pointer(pPage)).FpDirtyPrev
}
if (*TPgHdr)(unsafe.Pointer(pPage)).FpDirtyPrev != 0 {
(*TPgHdr)(unsafe.Pointer((*TPgHdr)(unsafe.Pointer(pPage)).FpDirtyPrev)).FpDirtyNext = (*TPgHdr)(unsafe.Pointer(pPage)).FpDirtyNext
} else {
/* If there are now no dirty pages in the cache, set eCreate to 2.
** This is an optimization that allows sqlite3PcacheFetch() to skip
** searching for a dirty page to eject from the cache when it might
** otherwise have to. */
(*TPCache)(unsafe.Pointer(p)).FpDirty = (*TPgHdr)(unsafe.Pointer(pPage)).FpDirtyNext
if (*TPCache)(unsafe.Pointer(p)).FpDirty == uintptr(0) { /*OPTIMIZATION-IF-TRUE*/
(*TPCache)(unsafe.Pointer(p)).FeCreate = uint8(2)
}
}
}
if libc.Int32FromUint8(addRemove)&int32(PCACHE_DIRTYLIST_ADD) != 0 {
(*TPgHdr)(unsafe.Pointer(pPage)).FpDirtyPrev = uintptr(0)
(*TPgHdr)(unsafe.Pointer(pPage)).FpDirtyNext = (*TPCache)(unsafe.Pointer(p)).FpDirty
if (*TPgHdr)(unsafe.Pointer(pPage)).FpDirtyNext != 0 {
(*TPgHdr)(unsafe.Pointer((*TPgHdr)(unsafe.Pointer(pPage)).FpDirtyNext)).FpDirtyPrev = pPage
} else {
(*TPCache)(unsafe.Pointer(p)).FpDirtyTail = pPage
if (*TPCache)(unsafe.Pointer(p)).FbPurgeable != 0 {
(*TPCache)(unsafe.Pointer(p)).FeCreate = uint8(1)
}
}
(*TPCache)(unsafe.Pointer(p)).FpDirty = pPage
/* If pSynced is NULL and this page has a clear NEED_SYNC flag, set
** pSynced to point to it. Checking the NEED_SYNC flag is an
** optimization, as if pSynced points to a page with the NEED_SYNC
** flag set sqlite3PcacheFetchStress() searches through all newer
** entries of the dirty-list for a page with NEED_SYNC clear anyway. */
if !((*TPCache)(unsafe.Pointer(p)).FpSynced != 0) && 0 == libc.Int32FromUint16((*TPgHdr)(unsafe.Pointer(pPage)).Fflags)&int32(PGHDR_NEED_SYNC) {
(*TPCache)(unsafe.Pointer(p)).FpSynced = pPage
}
}
}
var _pgsz = int32(4096)
/*
** Check that the pShmNode->aLock[] array comports with the locking bitmasks
** held by each client. Return true if it does, or false otherwise. This
** is to be used in an assert(). e.g.
**
** assert( assertLockingArrayOk(pShmNode) );
*/
var _posixIoFinder = uintptr(0)
func _posixIoFinderImpl(tls *libc.TLS, z uintptr, p uintptr) (r uintptr) {
_ = z
_ = p
return uintptr(unsafe.Pointer(&_posixIoMethods))
}
// C documentation
//
// /*
// ** Here are all of the sqlite3_io_methods objects for each of the
// ** locking strategies. Functions that return pointers to these methods
// ** are also created.
// */
var _posixIoMethods = Tsqlite3_io_methods{
FiVersion: int32(3),
}
// C documentation
//
// /*
// ** Different Unix systems declare open() in different ways. Same use
// ** open(const char*,int,mode_t). Others use open(const char*,int,...).
// ** The difference is important when using a pointer to the function.
// **
// ** The safest way to deal with the problem is to always use this wrapper
// ** which always has the same well-defined interface.
// */
func _posixOpen(tls *libc.TLS, zFile uintptr, flags int32, mode int32) (r int32) {
bp := tls.Alloc(16)
defer tls.Free(16)
return libc.Xopen(tls, zFile, flags, libc.VaList(bp+8, mode))
}
// C documentation
//
// /* Figure out the best index to use to search a pragma virtual table.
// **
// ** There are not really any index choices. But we want to encourage the
// ** query planner to give == constraints on as many hidden parameters as
// ** possible, and especially on the first hidden parameter. So return a
// ** high cost if hidden parameters are unconstrained.
// */
func _pragmaVtabBestIndex(tls *libc.TLS, tab uintptr, pIdxInfo uintptr) (r int32) {
var i, j int32
var pConstraint, pTab uintptr
var seen [2]int32
_, _, _, _, _ = i, j, pConstraint, pTab, seen
pTab = tab
(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FestimatedCost = libc.Float64FromInt32(1)
if libc.Int32FromUint8((*TPragmaVtab)(unsafe.Pointer(pTab)).FnHidden) == 0 {
return SQLITE_OK
}
pConstraint = (*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraint
seen[0] = 0
seen[int32(1)] = 0
i = 0
for {
if !(i < (*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FnConstraint) {
break
}
if (*Tsqlite3_index_constraint)(unsafe.Pointer(pConstraint)).FiColumn < libc.Int32FromUint8((*TPragmaVtab)(unsafe.Pointer(pTab)).FiHidden) {
goto _1
}
if libc.Int32FromUint8((*Tsqlite3_index_constraint)(unsafe.Pointer(pConstraint)).Fop) != int32(SQLITE_INDEX_CONSTRAINT_EQ) {
goto _1
}
if libc.Int32FromUint8((*Tsqlite3_index_constraint)(unsafe.Pointer(pConstraint)).Fusable) == 0 {
return int32(SQLITE_CONSTRAINT)
}
j = (*Tsqlite3_index_constraint)(unsafe.Pointer(pConstraint)).FiColumn - libc.Int32FromUint8((*TPragmaVtab)(unsafe.Pointer(pTab)).FiHidden)
seen[j] = i + int32(1)
goto _1
_1:
;
i = i + 1
pConstraint += 12
}
if seen[0] == 0 {
(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FestimatedCost = libc.Float64FromInt32(2147483647)
(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FestimatedRows = int64(2147483647)
return SQLITE_OK
}
j = seen[0] - int32(1)
(**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraintUsage + uintptr(j)*8))).FargvIndex = int32(1)
(**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraintUsage + uintptr(j)*8))).Fomit = uint8(1)
(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FestimatedCost = libc.Float64FromInt32(20)
(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FestimatedRows = int64(20)
if seen[int32(1)] != 0 {
j = seen[int32(1)] - int32(1)
(**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraintUsage + uintptr(j)*8))).FargvIndex = int32(2)
(**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraintUsage + uintptr(j)*8))).Fomit = uint8(1)
}
return SQLITE_OK
}
// C documentation
//
// /*
// ** Allocate memory for a temporary buffer needed for printf rendering.
// **
// ** If the requested size of the temp buffer is larger than the size
// ** of the output buffer in pAccum, then cause an SQLITE_TOOBIG error.
// ** Do the size check before the memory allocation to prevent rogue
// ** SQL from requesting large allocations using the precision or width
// ** field of the printf() function.
// */
func _printfTempBuf(tls *libc.TLS, pAccum uintptr, n Tsqlite3_int64) (r uintptr) {
var z uintptr
_ = z
if (*Tsqlite3_str)(unsafe.Pointer(pAccum)).FaccError != 0 {
return uintptr(0)
}
if n > libc.Int64FromUint32((*Tsqlite3_str)(unsafe.Pointer(pAccum)).FnAlloc) && n > libc.Int64FromUint32((*Tsqlite3_str)(unsafe.Pointer(pAccum)).FmxAlloc) {
_sqlite3StrAccumSetError(tls, pAccum, uint8(SQLITE_TOOBIG))
return uintptr(0)
}
z = Xsqlite3_malloc(tls, int32(n))
if z == uintptr(0) {
_sqlite3StrAccumSetError(tls, pAccum, uint8(SQLITE_NOMEM))
}
return z
}
/*
** On machines with a small stack size, you can redefine the
** SQLITE_PRINT_BUF_SIZE to be something smaller, if desired.
*/
/*
** Hard limit on the precision of floating-point conversions.
*/
// C documentation
//
// /*
// ** Read an entry from the pointer map.
// **
// ** This routine retrieves the pointer map entry for page 'key', writing
// ** the type and parent page number to *pEType and *pPgno respectively.
// ** An error code is returned if something goes wrong, otherwise SQLITE_OK.
// */
func _ptrmapGet(tls *libc.TLS, pBt uintptr, key TPgno, pEType uintptr, pPgno uintptr) (r int32) {
bp := tls.Alloc(16)
defer tls.Free(16)
var iPtrmap, offset, rc int32
var pPtrmap uintptr
var _ /* pDbPage at bp+0 */ uintptr
_, _, _, _ = iPtrmap, offset, pPtrmap, rc
iPtrmap = libc.Int32FromUint32(_ptrmapPageno(tls, pBt, key))
rc = _sqlite3PagerGet(tls, (*TBtShared)(unsafe.Pointer(pBt)).FpPager, libc.Uint32FromInt32(iPtrmap), bp, 0)
if rc != 0 {
return rc
}
pPtrmap = _sqlite3PagerGetData(tls, **(**uintptr)(__ccgo_up(bp)))
offset = libc.Int32FromUint32(libc.Uint32FromInt32(5) * (key - libc.Uint32FromInt32(iPtrmap) - libc.Uint32FromInt32(1)))
if offset < 0 {
_sqlite3PagerUnref(tls, **(**uintptr)(__ccgo_up(bp)))
return _sqlite3CorruptError(tls, int32(74364))
}
**(**Tu8)(__ccgo_up(pEType)) = **(**Tu8)(__ccgo_up(pPtrmap + uintptr(offset)))
if pPgno != 0 {
**(**TPgno)(__ccgo_up(pPgno)) = _sqlite3Get4byte(tls, pPtrmap+uintptr(offset+int32(1)))
}
_sqlite3PagerUnref(tls, **(**uintptr)(__ccgo_up(bp)))
if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(pEType))) < int32(1) || libc.Int32FromUint8(**(**Tu8)(__ccgo_up(pEType))) > int32(5) {
return _sqlite3CorruptError(tls, int32(74372))
}
return SQLITE_OK
}
/*
** Given a btree page and a cell index (0 means the first cell on
** the page, 1 means the second cell, and so forth) return a pointer
** to the cell content.
**
** findCellPastPtr() does the same except it skips past the initial
** 4-byte child pointer found on interior pages, if there is one.
**
** This routine works only for pages that do not contain overflow cells.
*/
// C documentation
//
// /*
// ** Given a page number of a regular database page, return the page
// ** number for the pointer-map page that contains the entry for the
// ** input page number.
// **
// ** Return 0 (not a valid page) for pgno==1 since there is
// ** no pointer map associated with page 1. The integrity_check logic
// ** requires that ptrmapPageno(*,1)!=1.
// */
func _ptrmapPageno(tls *libc.TLS, pBt uintptr, pgno TPgno) (r TPgno) {
var iPtrMap, ret TPgno
var nPagesPerMapPage int32
_, _, _ = iPtrMap, nPagesPerMapPage, ret
if pgno < uint32(2) {
return uint32(0)
}
nPagesPerMapPage = libc.Int32FromUint32((*TBtShared)(unsafe.Pointer(pBt)).FusableSize/uint32(5) + uint32(1))
iPtrMap = (pgno - uint32(2)) / libc.Uint32FromInt32(nPagesPerMapPage)
ret = iPtrMap*libc.Uint32FromInt32(nPagesPerMapPage) + uint32(2)
if ret == libc.Uint32FromInt32(_sqlite3PendingByte)/(*TBtShared)(unsafe.Pointer(pBt)).FpageSize+libc.Uint32FromInt32(1) {
ret = ret + 1
}
return ret
}
// C documentation
//
// /*
// ** Called when a page of data is written to offset iOff of the database
// ** file while the rbu handle is in capture mode. Record the page number
// ** of the page being written in the aFrame[] array.
// */
func _rbuCaptureDbWrite(tls *libc.TLS, pRbu uintptr, iOff Ti64) (r int32) {
(**(**TRbuFrame)(__ccgo_up((*Tsqlite3rbu)(unsafe.Pointer(pRbu)).FaFrame + uintptr((*Tsqlite3rbu)(unsafe.Pointer(pRbu)).FnFrame-int32(1))*8))).FiDbPage = libc.Uint32FromInt64(iOff/int64((*Tsqlite3rbu)(unsafe.Pointer(pRbu)).Fpgsz)) + uint32(1)
return SQLITE_OK
}
// C documentation
//
// /*
// ** This is called as part of an incremental checkpoint operation. Copy
// ** a single frame of data from the wal file into the database file, as
// ** indicated by the RbuFrame object.
// */
func _rbuCheckpointFrame(tls *libc.TLS, p uintptr, pFrame uintptr) {
var iOff Ti64
var pDb, pWal uintptr
_, _, _ = iOff, pDb, pWal
pWal = (*Trbu_file)(unsafe.Pointer((*Trbu_file)(unsafe.Pointer((*Tsqlite3rbu)(unsafe.Pointer(p)).FpTargetFd)).FpWalFd)).FpReal
pDb = (*Trbu_file)(unsafe.Pointer((*Tsqlite3rbu)(unsafe.Pointer(p)).FpTargetFd)).FpReal
iOff = libc.Int64FromUint32((*TRbuFrame)(unsafe.Pointer(pFrame)).FiWalFrame-libc.Uint32FromInt32(1))*int64((*Tsqlite3rbu)(unsafe.Pointer(p)).Fpgsz+libc.Int32FromInt32(24)) + int64(32) + int64(24)
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = (*(*func(*libc.TLS, uintptr, uintptr, int32, Tsqlite3_int64) int32)(unsafe.Pointer(&struct{ uintptr }{(*Tsqlite3_io_methods)(unsafe.Pointer((*Tsqlite3_file)(unsafe.Pointer(pWal)).FpMethods)).FxRead})))(tls, pWal, (*Tsqlite3rbu)(unsafe.Pointer(p)).FaBuf, (*Tsqlite3rbu)(unsafe.Pointer(p)).Fpgsz, iOff)
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc != 0 {
return
}
iOff = libc.Int64FromUint32((*TRbuFrame)(unsafe.Pointer(pFrame)).FiDbPage-libc.Uint32FromInt32(1)) * int64((*Tsqlite3rbu)(unsafe.Pointer(p)).Fpgsz)
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = (*(*func(*libc.TLS, uintptr, uintptr, int32, Tsqlite3_int64) int32)(unsafe.Pointer(&struct{ uintptr }{(*Tsqlite3_io_methods)(unsafe.Pointer((*Tsqlite3_file)(unsafe.Pointer(pDb)).FpMethods)).FxWrite})))(tls, pDb, (*Tsqlite3rbu)(unsafe.Pointer(p)).FaBuf, (*Tsqlite3rbu)(unsafe.Pointer(p)).Fpgsz, iOff)
}
/*
** This value is copied from the definition of ZIPVFS_CTRL_FILE_POINTER
** in zipvfs.h.
*/
func _rbuPutU16(tls *libc.TLS, aBuf uintptr, iVal Tu16) {
**(**Tu8)(__ccgo_up(aBuf)) = libc.Uint8FromInt32(libc.Int32FromUint16(iVal) >> int32(8) & int32(0xFF))
**(**Tu8)(__ccgo_up(aBuf + 1)) = libc.Uint8FromInt32(libc.Int32FromUint16(iVal) >> 0 & int32(0xFF))
}
// C documentation
//
// /*
// ** Return the current wal-index header checksum for the target database
// ** as a 64-bit integer.
// **
// ** The checksum is store in the first page of xShmMap memory as an 8-byte
// ** blob starting at byte offset 40.
// */
func _rbuShmChecksum(tls *libc.TLS, p uintptr) (r Ti64) {
bp := tls.Alloc(16)
defer tls.Free(16)
var iRet Ti64
var pDb uintptr
var _ /* ptr at bp+0 */ uintptr
_, _ = iRet, pDb
iRet = 0
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
pDb = (*Trbu_file)(unsafe.Pointer((*Tsqlite3rbu)(unsafe.Pointer(p)).FpTargetFd)).FpReal
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = (*(*func(*libc.TLS, uintptr, int32, int32, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*Tsqlite3_io_methods)(unsafe.Pointer((*Tsqlite3_file)(unsafe.Pointer(pDb)).FpMethods)).FxShmMap})))(tls, pDb, 0, libc.Int32FromInt32(32)*libc.Int32FromInt32(1024), 0, bp)
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
iRet = libc.Int64FromUint64(uint64(libc.AtomicLoadPUint32(**(**uintptr)(__ccgo_up(bp))+libc.UintptrFromInt32(10)*4))<<libc.Int32FromInt32(32) + uint64(libc.AtomicLoadPUint32(**(**uintptr)(__ccgo_up(bp))+11*4)))
}
}
return iRet
}
func _rbuUnlockShm(tls *libc.TLS, p uintptr) {
var i int32
var xShmLock uintptr
_, _ = i, xShmLock
if (*Trbu_file)(unsafe.Pointer(p)).FpRbu != 0 {
xShmLock = (*Tsqlite3_io_methods)(unsafe.Pointer((*Tsqlite3_file)(unsafe.Pointer((*Trbu_file)(unsafe.Pointer(p)).FpReal)).FpMethods)).FxShmLock
i = 0
for {
if !(i < int32(SQLITE_SHM_NLOCK)) {
break
}
if libc.Uint32FromInt32(libc.Int32FromInt32(1)<<i)&(*Tsqlite3rbu)(unsafe.Pointer((*Trbu_file)(unsafe.Pointer(p)).FpRbu)).FmLock != 0 {
(*(*func(*libc.TLS, uintptr, int32, int32, int32) int32)(unsafe.Pointer(&struct{ uintptr }{xShmLock})))(tls, (*Trbu_file)(unsafe.Pointer(p)).FpReal, i, int32(1), libc.Int32FromInt32(SQLITE_SHM_UNLOCK)|libc.Int32FromInt32(SQLITE_SHM_EXCLUSIVE))
}
goto _1
_1:
;
i = i + 1
}
(*Tsqlite3rbu)(unsafe.Pointer((*Trbu_file)(unsafe.Pointer(p)).FpRbu)).FmLock = uint32(0)
}
}
// C documentation
//
// /*
// ** Functions to deserialize a 16 bit integer, 32 bit real number and
// ** 64 bit integer. The deserialized value is returned.
// */
func _readInt16(tls *libc.TLS, p uintptr) (r int32) {
return libc.Int32FromUint8(**(**Tu8)(__ccgo_up(p)))<<int32(8) + libc.Int32FromUint8(**(**Tu8)(__ccgo_up(p + 1)))
}
// C documentation
//
// /*
// ** Return non-zero if the table pTab in database iDb or any of its indices
// ** have been opened at any point in the VDBE program. This is used to see if
// ** a statement of the form "INSERT INTO <iDb, pTab> SELECT ..." can
// ** run without using a temporary table for the results of the SELECT.
// */
func _readsTable(tls *libc.TLS, p uintptr, iDb int32, pTab uintptr) (r int32) {
var i, iEnd int32
var pIndex, pOp, pVTab, v, v1 uintptr
var tnum TPgno
_, _, _, _, _, _, _, _ = i, iEnd, pIndex, pOp, pVTab, tnum, v, v1
v = _sqlite3GetVdbe(tls, p)
iEnd = _sqlite3VdbeCurrentAddr(tls, v)
if libc.Int32FromUint8((*TTable)(unsafe.Pointer(pTab)).FeTabType) == int32(TABTYP_VTAB) {
v1 = _sqlite3GetVTable(tls, (*TParse)(unsafe.Pointer(p)).Fdb, pTab)
} else {
v1 = uintptr(0)
}
pVTab = v1
i = int32(1)
for {
if !(i < iEnd) {
break
}
pOp = _sqlite3VdbeGetOp(tls, v, i)
if libc.Int32FromUint8((*TVdbeOp)(unsafe.Pointer(pOp)).Fopcode) == int32(OP_OpenRead) && (*TVdbeOp)(unsafe.Pointer(pOp)).Fp3 == iDb {
tnum = libc.Uint32FromInt32((*TVdbeOp)(unsafe.Pointer(pOp)).Fp2)
if tnum == (*TTable)(unsafe.Pointer(pTab)).Ftnum {
return int32(1)
}
pIndex = (*TTable)(unsafe.Pointer(pTab)).FpIndex
for {
if !(pIndex != 0) {
break
}
if tnum == (*TIndex)(unsafe.Pointer(pIndex)).Ftnum {
return int32(1)
}
goto _3
_3:
;
pIndex = (*TIndex)(unsafe.Pointer(pIndex)).FpNext
}
}
if libc.Int32FromUint8((*TVdbeOp)(unsafe.Pointer(pOp)).Fopcode) == int32(OP_VOpen) && *(*uintptr)(unsafe.Pointer(pOp + 16)) == pVTab {
return int32(1)
}
goto _2
_2:
;
i = i + 1
}
return 0
}
// C documentation
//
// /*
// ** Release a unixInodeInfo structure previously allocated by findInodeInfo().
// **
// ** The global mutex must be held when this routine is called, but the mutex
// ** on the inode being deleted must NOT be held.
// */
func _releaseInodeInfo(tls *libc.TLS, pFile uintptr) {
var pInode uintptr
_ = pInode
pInode = (*TunixFile)(unsafe.Pointer(pFile)).FpInode
if pInode != 0 {
(*TunixInodeInfo)(unsafe.Pointer(pInode)).FnRef = (*TunixInodeInfo)(unsafe.Pointer(pInode)).FnRef - 1
if (*TunixInodeInfo)(unsafe.Pointer(pInode)).FnRef == 0 {
Xsqlite3_mutex_enter(tls, (*TunixInodeInfo)(unsafe.Pointer(pInode)).FpLockMutex)
_closePendingFds(tls, pFile)
Xsqlite3_mutex_leave(tls, (*TunixInodeInfo)(unsafe.Pointer(pInode)).FpLockMutex)
if (*TunixInodeInfo)(unsafe.Pointer(pInode)).FpPrev != 0 {
(*TunixInodeInfo)(unsafe.Pointer((*TunixInodeInfo)(unsafe.Pointer(pInode)).FpPrev)).FpNext = (*TunixInodeInfo)(unsafe.Pointer(pInode)).FpNext
} else {
_inodeList = (*TunixInodeInfo)(unsafe.Pointer(pInode)).FpNext
}
if (*TunixInodeInfo)(unsafe.Pointer(pInode)).FpNext != 0 {
(*TunixInodeInfo)(unsafe.Pointer((*TunixInodeInfo)(unsafe.Pointer(pInode)).FpNext)).FpPrev = (*TunixInodeInfo)(unsafe.Pointer(pInode)).FpPrev
}
Xsqlite3_mutex_free(tls, (*TunixInodeInfo)(unsafe.Pointer(pInode)).FpLockMutex)
Xsqlite3_free(tls, pInode)
}
}
}
// C documentation
//
// /*
// ** This is a Walker select callback. It does nothing. It is only required
// ** because without a dummy callback, sqlite3WalkExpr() and similar do not
// ** descend into sub-select statements.
// */
func _renameColumnSelectCb(tls *libc.TLS, pWalker uintptr, p uintptr) (r int32) {
if (*TSelect)(unsafe.Pointer(p)).FselFlags&libc.Uint32FromInt32(libc.Int32FromInt32(SF_View)|libc.Int32FromInt32(SF_CopyCte)) != 0 {
return int32(WRC_Prune)
}
_renameWalkWith(tls, pWalker, p)
return WRC_Continue
}
// C documentation
//
// /*
// ** Resolve an expression that was part of an ATTACH or DETACH statement. This
// ** is slightly different from resolving a normal SQL expression, because simple
// ** identifiers are treated as strings, not possible column names or aliases.
// **
// ** i.e. if the parser sees:
// **
// ** ATTACH DATABASE abc AS def
// **
// ** it treats the two expressions as literal strings 'abc' and 'def' instead of
// ** looking for columns of the same name.
// **
// ** This only applies to the root node of pExpr, so the statement:
// **
// ** ATTACH DATABASE abc||def AS 'db2'
// **
// ** will fail because neither abc or def can be resolved.
// */
func _resolveAttachExpr(tls *libc.TLS, pName uintptr, pExpr uintptr) (r int32) {
var rc int32
_ = rc
rc = SQLITE_OK
if pExpr != 0 {
if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) != int32(TK_ID) {
rc = _sqlite3ResolveExprNames(tls, pName, pExpr)
} else {
(*TExpr)(unsafe.Pointer(pExpr)).Fop = uint8(TK_STRING)
}
}
return rc
}
// C documentation
//
// /*
// ** Rtree virtual table module xClose method.
// */
func _rtreeClose(tls *libc.TLS, cur uintptr) (r int32) {
var pCsr, pRtree uintptr
_, _ = pCsr, pRtree
pRtree = (*Tsqlite3_vtab_cursor)(unsafe.Pointer(cur)).FpVtab
pCsr = cur
_resetCursor(tls, pCsr)
Xsqlite3_finalize(tls, (*TRtreeCursor)(unsafe.Pointer(pCsr)).FpReadAux)
Xsqlite3_free(tls, pCsr)
(*TRtree)(unsafe.Pointer(pRtree)).FnCursor = (*TRtree)(unsafe.Pointer(pRtree)).FnCursor - 1
if (*TRtree)(unsafe.Pointer(pRtree)).FnCursor == uint32(0) && libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FinWrTrans) == 0 {
_nodeBlobReset(tls, pRtree)
}
return SQLITE_OK
}
// C documentation
//
// /*
// ** Rtree virtual table module xEof method.
// **
// ** Return non-zero if the cursor does not currently point to a valid
// ** record (i.e if the scan has finished), or zero otherwise.
// */
func _rtreeEof(tls *libc.TLS, cur uintptr) (r int32) {
var pCsr uintptr
_ = pCsr
pCsr = cur
return libc.Int32FromUint8((*TRtreeCursor)(unsafe.Pointer(pCsr)).FatEOF)
}
/*
** Convert raw bits from the on-disk RTree record into a coordinate value.
** The on-disk format is big-endian and needs to be converted for little-
** endian platforms. The on-disk record stores integer coordinates if
** eInt is true and it stores 32-bit floating point records if eInt is
** false. a[] is the four bytes of the on-disk record to be decoded.
** Store the results in "r".
**
** There are five versions of this macro. The last one is generic. The
** other four are various architectures-specific optimizations.
*/
// C documentation
//
// /*
// ** Rtree virtual table module xRowid method.
// */
func _rtreeRowid(tls *libc.TLS, pVtabCursor uintptr, pRowid uintptr) (r int32) {
bp := tls.Alloc(16)
defer tls.Free(16)
var p, pCsr, pNode uintptr
var _ /* rc at bp+0 */ int32
_, _, _ = p, pCsr, pNode
pCsr = pVtabCursor
p = _rtreeSearchPointFirst(tls, pCsr)
**(**int32)(__ccgo_up(bp)) = SQLITE_OK
pNode = _rtreeNodeOfFirstSearchPoint(tls, pCsr, bp)
if **(**int32)(__ccgo_up(bp)) == SQLITE_OK && p != 0 {
if libc.Int32FromUint8((*TRtreeSearchPoint)(unsafe.Pointer(p)).FiCell) >= _readInt16(tls, (*TRtreeNode)(unsafe.Pointer(pNode)).FzData+2) {
**(**int32)(__ccgo_up(bp)) = int32(SQLITE_ABORT)
} else {
**(**Tsqlite_int64)(__ccgo_up(pRowid)) = _nodeGetRowid(tls, (*TRtreeCursor)(unsafe.Pointer(pCsr)).Fbase.FpVtab, pNode, libc.Int32FromUint8((*TRtreeSearchPoint)(unsafe.Pointer(p)).FiCell))
}
}
return **(**int32)(__ccgo_up(bp))
}
// C documentation
//
// /*
// ** Compare two search points. Return negative, zero, or positive if the first
// ** is less than, equal to, or greater than the second.
// **
// ** The rScore is the primary key. Smaller rScore values come first.
// ** If the rScore is a tie, then use iLevel as the tie breaker with smaller
// ** iLevel values coming first. In this way, if rScore is the same for all
// ** SearchPoints, then iLevel becomes the deciding factor and the result
// ** is a depth-first search, which is the desired default behavior.
// */
func _rtreeSearchPointCompare(tls *libc.TLS, pA uintptr, pB uintptr) (r int32) {
if (*TRtreeSearchPoint)(unsafe.Pointer(pA)).FrScore < (*TRtreeSearchPoint)(unsafe.Pointer(pB)).FrScore {
return -int32(1)
}
if (*TRtreeSearchPoint)(unsafe.Pointer(pA)).FrScore > (*TRtreeSearchPoint)(unsafe.Pointer(pB)).FrScore {
return +libc.Int32FromInt32(1)
}
if libc.Int32FromUint8((*TRtreeSearchPoint)(unsafe.Pointer(pA)).FiLevel) < libc.Int32FromUint8((*TRtreeSearchPoint)(unsafe.Pointer(pB)).FiLevel) {
return -int32(1)
}
if libc.Int32FromUint8((*TRtreeSearchPoint)(unsafe.Pointer(pA)).FiLevel) > libc.Int32FromUint8((*TRtreeSearchPoint)(unsafe.Pointer(pB)).FiLevel) {
return +libc.Int32FromInt32(1)
}
return 0
}
// C documentation
//
// /*
// ** This is the collating function named "RTRIM" which is always
// ** available. Ignore trailing spaces.
// */
func _rtrimCollFunc(tls *libc.TLS, pUser uintptr, nKey1 int32, pKey1 uintptr, nKey2 int32, pKey2 uintptr) (r int32) {
var pK1, pK2 uintptr
_, _ = pK1, pK2
pK1 = pKey1
pK2 = pKey2
for nKey1 != 0 && libc.Int32FromUint8(**(**Tu8)(__ccgo_up(pK1 + uintptr(nKey1-int32(1))))) == int32(' ') {
nKey1 = nKey1 - 1
}
for nKey2 != 0 && libc.Int32FromUint8(**(**Tu8)(__ccgo_up(pK2 + uintptr(nKey2-int32(1))))) == int32(' ') {
nKey2 = nKey2 - 1
}
return _binCollFunc(tls, pUser, nKey1, pKey1, nKey2, pKey2)
}
// C documentation
//
// /*
// ** Save the current cursor position in the variables BtCursor.nKey
// ** and BtCursor.pKey. The cursor's state is set to CURSOR_REQUIRESEEK.
// **
// ** The caller must ensure that the cursor is valid (has eState==CURSOR_VALID)
// ** prior to calling this routine.
// */
func _saveCursorPosition(tls *libc.TLS, pCur uintptr) (r int32) {
var rc int32
var v1 uintptr
_, _ = rc, v1
if libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCur)).FcurFlags)&int32(BTCF_Pinned) != 0 {
return libc.Int32FromInt32(SQLITE_CONSTRAINT) | libc.Int32FromInt32(11)<<libc.Int32FromInt32(8)
}
if libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCur)).FeState) == int32(CURSOR_SKIPNEXT) {
(*TBtCursor)(unsafe.Pointer(pCur)).FeState = uint8(CURSOR_VALID)
} else {
(*TBtCursor)(unsafe.Pointer(pCur)).FskipNext = 0
}
rc = _saveCursorKey(tls, pCur)
if rc == SQLITE_OK {
_btreeReleaseAllCursorPages(tls, pCur)
(*TBtCursor)(unsafe.Pointer(pCur)).FeState = uint8(CURSOR_REQUIRESEEK)
}
v1 = pCur + 1
*(*Tu8)(unsafe.Pointer(v1)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v1))) & ^(libc.Int32FromInt32(BTCF_ValidNKey) | libc.Int32FromInt32(BTCF_ValidOvfl) | libc.Int32FromInt32(BTCF_AtLast)))
return rc
}
// C documentation
//
// /* This helper routine to saveAllCursors does the actual work of saving
// ** the cursors if and when a cursor is found that actually requires saving.
// ** The common case is that no cursors need to be saved, so this routine is
// ** broken out from its caller to avoid unnecessary stack pointer movement.
// */
func _saveCursorsOnList(tls *libc.TLS, p uintptr, iRoot TPgno, pExcept uintptr) (r int32) {
var rc int32
_ = rc
for cond := true; cond; cond = p != 0 {
if p != pExcept && (uint32(0) == iRoot || (*TBtCursor)(unsafe.Pointer(p)).FpgnoRoot == iRoot) {
if libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(p)).FeState) == CURSOR_VALID || libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(p)).FeState) == int32(CURSOR_SKIPNEXT) {
rc = _saveCursorPosition(tls, p)
if SQLITE_OK != rc {
return rc
}
} else {
_btreeReleaseAllCursorPages(tls, p)
}
}
p = (*TBtCursor)(unsafe.Pointer(p)).FpNext
}
return SQLITE_OK
}
// C documentation
//
// /*
// ** This function is a no-op if *pRc is other than SQLITE_OK when it is
// ** called. Otherwse, it appends the serialized version of the value stored
// ** in column iCol of the row that SQL statement pStmt currently points
// ** to to the buffer.
// */
func _sessionAppendCol(tls *libc.TLS, p uintptr, pStmt uintptr, iCol int32, pRc uintptr) {
bp := tls.Alloc(16)
defer tls.Free(16)
var eType, nByte int32
var i Tsqlite3_int64
var r float64
var z uintptr
var _ /* aBuf at bp+0 */ [8]Tu8
_, _, _, _, _ = eType, i, nByte, r, z
if **(**int32)(__ccgo_up(pRc)) == SQLITE_OK {
eType = Xsqlite3_column_type(tls, pStmt, iCol)
_sessionAppendByte(tls, p, libc.Uint8FromInt32(eType), pRc)
if eType == int32(SQLITE_INTEGER) || eType == int32(SQLITE_FLOAT) {
if eType == int32(SQLITE_INTEGER) {
i = Xsqlite3_column_int64(tls, pStmt, iCol)
_sessionPutI64(tls, bp, i)
} else {
r = Xsqlite3_column_double(tls, pStmt, iCol)
_sessionPutDouble(tls, bp, r)
}
_sessionAppendBlob(tls, p, bp, int32(8), pRc)
}
if eType == int32(SQLITE_BLOB) || eType == int32(SQLITE_TEXT) {
if eType == int32(SQLITE_BLOB) {
z = Xsqlite3_column_blob(tls, pStmt, iCol)
} else {
z = Xsqlite3_column_text(tls, pStmt, iCol)
}
nByte = Xsqlite3_column_bytes(tls, pStmt, iCol)
if z != 0 || eType == int32(SQLITE_BLOB) && nByte == 0 {
_sessionAppendVarint(tls, p, nByte, pRc)
_sessionAppendBlob(tls, p, z, nByte, pRc)
} else {
**(**int32)(__ccgo_up(pRc)) = int32(SQLITE_NOMEM)
}
}
}
}
// C documentation
//
// /*
// ** Ensure that there is room in the buffer to append nByte bytes of data.
// ** If not, use sqlite3_realloc() to grow the buffer so that there is.
// **
// ** If successful, return zero. Otherwise, if an OOM condition is encountered,
// ** set *pRc to SQLITE_NOMEM and return non-zero.
// */
func _sessionBufferGrow(tls *libc.TLS, p uintptr, nByte Ti64, pRc uintptr) (r int32) {
var aNew uintptr
var nNew, nReq Ti64
var v1 int32
_, _, _, _ = aNew, nNew, nReq, v1
nReq = int64((*TSessionBuffer)(unsafe.Pointer(p)).FnBuf) + nByte
if **(**int32)(__ccgo_up(pRc)) == SQLITE_OK && nReq > int64((*TSessionBuffer)(unsafe.Pointer(p)).FnAlloc) {
if (*TSessionBuffer)(unsafe.Pointer(p)).FnAlloc != 0 {
v1 = (*TSessionBuffer)(unsafe.Pointer(p)).FnAlloc
} else {
v1 = int32(128)
}
nNew = int64(v1)
for cond := true; cond; cond = nNew < nReq {
nNew = nNew * int64(2)
}
/* The value of SESSION_MAX_BUFFER_SZ is copied from the implementation
** of sqlite3_realloc64(). Allocations greater than this size in bytes
** always fail. It is used here to ensure that this routine can always
** allocate up to this limit - instead of up to the largest power of
** two smaller than the limit. */
if nNew > int64(libc.Int32FromInt32(0x7FFFFF00)-libc.Int32FromInt32(1)) {
nNew = int64(libc.Int32FromInt32(0x7FFFFF00) - libc.Int32FromInt32(1))
if nNew < nReq {
**(**int32)(__ccgo_up(pRc)) = int32(SQLITE_NOMEM)
return int32(1)
}
}
aNew = Xsqlite3_realloc64(tls, (*TSessionBuffer)(unsafe.Pointer(p)).FaBuf, libc.Uint64FromInt64(nNew))
if uintptr(0) == aNew {
**(**int32)(__ccgo_up(pRc)) = int32(SQLITE_NOMEM)
} else {
(*TSessionBuffer)(unsafe.Pointer(p)).FaBuf = aNew
(*TSessionBuffer)(unsafe.Pointer(p)).FnAlloc = int32(nNew)
}
}
return libc.BoolInt32(**(**int32)(__ccgo_up(pRc)) != SQLITE_OK)
}
// C documentation
//
// /*
// ** Based on the primary key values stored in change aRecord, calculate a
// ** hash key. Assume the has table has nBucket buckets. The hash keys
// ** calculated by this function are compatible with those calculated by
// ** sessionPreupdateHash().
// **
// ** The bPkOnly argument is non-zero if the record at aRecord[] is from
// ** a patchset DELETE. In this case the non-PK fields are omitted entirely.
// */
func _sessionChangeHash(tls *libc.TLS, pTab uintptr, bPkOnly int32, aRecord uintptr, nBucket int32) (r uint32) {
bp := tls.Alloc(16)
defer tls.Free(16)
var a, v2 uintptr
var eType, i, isPK int32
var h uint32
var _ /* n at bp+0 */ int32
_, _, _, _, _, _ = a, eType, h, i, isPK, v2
h = uint32(0) /* Used to iterate through columns */
a = aRecord /* Used to iterate through change record */
i = 0
for {
if !(i < (*TSessionTable)(unsafe.Pointer(pTab)).FnCol) {
break
}
isPK = libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TSessionTable)(unsafe.Pointer(pTab)).FabPK + uintptr(i))))
if bPkOnly != 0 && isPK == 0 {
goto _1
}
if isPK != 0 {
v2 = a
a = a + 1
eType = libc.Int32FromUint8(**(**Tu8)(__ccgo_up(v2)))
h = _sessionHashAppendType(tls, h, eType)
if eType == int32(SQLITE_INTEGER) || eType == int32(SQLITE_FLOAT) {
h = _sessionHashAppendI64(tls, h, _sessionGetI64(tls, a))
a = a + uintptr(8)
} else {
if eType == int32(SQLITE_TEXT) || eType == int32(SQLITE_BLOB) {
a = a + uintptr(_sessionVarintGet(tls, a, bp))
h = _sessionHashAppendBlob(tls, h, **(**int32)(__ccgo_up(bp)), a)
a = a + uintptr(**(**int32)(__ccgo_up(bp)))
}
}
/* It should not be possible for eType to be SQLITE_NULL or 0x00 here,
** as the session module does not record changes for rows with NULL
** values stored in primary key columns. But a corrupt changesets
** may contain such a value. */
} else {
a = a + uintptr(_sessionSerialLen(tls, a))
}
goto _1
_1:
;
i = i + 1
}
return h % libc.Uint32FromInt32(nBucket)
}
// C documentation
//
// /*
// ** The input pointer currently points to the first byte of the first field
// ** of a record consisting of nCol columns. This function ensures the entire
// ** record is buffered. It does not move the input pointer.
// **
// ** If successful, SQLITE_OK is returned and *pnByte is set to the size of
// ** the record in bytes. Otherwise, an SQLite error code is returned. The
// ** final value of *pnByte is undefined in this case.
// */
func _sessionChangesetBufferRecord(tls *libc.TLS, pIn uintptr, nCol int32, pnByte uintptr) (r int32) {
bp := tls.Alloc(16)
defer tls.Free(16)
var eType, i, nRem, rc int32
var nByte, v2 Ti64
var _ /* n at bp+0 */ int32
_, _, _, _, _, _ = eType, i, nByte, nRem, rc, v2
rc = SQLITE_OK
nByte = 0
i = 0
for {
if !(rc == SQLITE_OK && i < nCol) {
break
}
rc = _sessionInputBuffer(tls, pIn, int32(nByte+int64(10)))
if rc == SQLITE_OK {
v2 = nByte
nByte = nByte + 1
eType = libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TSessionInput)(unsafe.Pointer(pIn)).FaData + uintptr(int64((*TSessionInput)(unsafe.Pointer(pIn)).FiNext)+v2))))
if eType == int32(SQLITE_TEXT) || eType == int32(SQLITE_BLOB) {
nRem = int32(int64((*TSessionInput)(unsafe.Pointer(pIn)).FnData) - (int64((*TSessionInput)(unsafe.Pointer(pIn)).FiNext) + nByte))
nByte = nByte + int64(_sessionVarintGetSafe(tls, (*TSessionInput)(unsafe.Pointer(pIn)).FaData+uintptr(int64((*TSessionInput)(unsafe.Pointer(pIn)).FiNext)+nByte), nRem, bp))
nByte = nByte + int64(**(**int32)(__ccgo_up(bp)))
rc = _sessionInputBuffer(tls, pIn, int32(nByte))
} else {
if eType == int32(SQLITE_INTEGER) || eType == int32(SQLITE_FLOAT) {
nByte = nByte + int64(8)
} else {
if eType != 0 && eType != int32(SQLITE_NULL) {
rc = _sqlite3CorruptError(tls, int32(237456))
}
}
}
}
if rc == SQLITE_OK && int64((*TSessionInput)(unsafe.Pointer(pIn)).FiNext)+nByte > int64((*TSessionInput)(unsafe.Pointer(pIn)).FnData) {
rc = _sqlite3CorruptError(tls, int32(237460))
}
goto _1
_1:
;
i = i + 1
}
**(**int32)(__ccgo_up(pnByte)) = int32(nByte)
return rc
}
// C documentation
//
// /*
// ** Read a 64-bit big-endian integer value from buffer aRec[]. Return
// ** the value read.
// */
func _sessionGetI64(tls *libc.TLS, aRec uintptr) (r Tsqlite3_int64) {
var x Tu64
var y Tu32
_, _ = x, y
x = uint64(uint32(**(**Tu8)(__ccgo_up(aRec)))<<libc.Int32FromInt32(24) | libc.Uint32FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aRec + 1)))<<libc.Int32FromInt32(16)) | libc.Uint32FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aRec + 2)))<<libc.Int32FromInt32(8)) | uint32(**(**Tu8)(__ccgo_up(aRec + 3))))
y = uint32(**(**Tu8)(__ccgo_up(aRec + libc.UintptrFromInt32(4))))<<libc.Int32FromInt32(24) | libc.Uint32FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aRec + libc.UintptrFromInt32(4) + 1)))<<libc.Int32FromInt32(16)) | libc.Uint32FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aRec + libc.UintptrFromInt32(4) + 2)))<<libc.Int32FromInt32(8)) | uint32(**(**Tu8)(__ccgo_up(aRec + libc.UintptrFromInt32(4) + 3)))
x = x<<libc.Int32FromInt32(32) + uint64(y)
return libc.Int64FromUint64(x)
}
// C documentation
//
// /*
// ** Append the hash of the 64-bit integer passed as the second argument to the
// ** hash-key value passed as the first. Return the new hash-key value.
// */
func _sessionHashAppendI64(tls *libc.TLS, h uint32, i Ti64) (r uint32) {
h = h<<int32(3) ^ h ^ libc.Uint32FromInt64(i&libc.Int64FromUint32(0xFFFFFFFF))
return h<<int32(3) ^ h ^ libc.Uint32FromInt64(i>>libc.Int32FromInt32(32)&libc.Int64FromUint32(0xFFFFFFFF))
}
// C documentation
//
// /*
// ** Append the hash of the data type passed as the second argument to the
// ** hash-key value passed as the first. Return the new hash-key value.
// */
func _sessionHashAppendType(tls *libc.TLS, h uint32, eType int32) (r uint32) {
return h<<int32(3) ^ h ^ libc.Uint32FromInt32(eType)
}
// C documentation
//
// /*
// ** Write a 64-bit big-endian integer value to the buffer aBuf[].
// */
func _sessionPutI64(tls *libc.TLS, aBuf uintptr, i Tsqlite3_int64) {
**(**Tu8)(__ccgo_up(aBuf)) = libc.Uint8FromInt64(i >> libc.Int32FromInt32(56) & int64(0xFF))
**(**Tu8)(__ccgo_up(aBuf + 1)) = libc.Uint8FromInt64(i >> libc.Int32FromInt32(48) & int64(0xFF))
**(**Tu8)(__ccgo_up(aBuf + 2)) = libc.Uint8FromInt64(i >> libc.Int32FromInt32(40) & int64(0xFF))
**(**Tu8)(__ccgo_up(aBuf + 3)) = libc.Uint8FromInt64(i >> libc.Int32FromInt32(32) & int64(0xFF))
**(**Tu8)(__ccgo_up(aBuf + 4)) = libc.Uint8FromInt64(i >> libc.Int32FromInt32(24) & int64(0xFF))
**(**Tu8)(__ccgo_up(aBuf + 5)) = libc.Uint8FromInt64(i >> libc.Int32FromInt32(16) & int64(0xFF))
**(**Tu8)(__ccgo_up(aBuf + 6)) = libc.Uint8FromInt64(i >> libc.Int32FromInt32(8) & int64(0xFF))
**(**Tu8)(__ccgo_up(aBuf + 7)) = libc.Uint8FromInt64(i >> libc.Int32FromInt32(0) & int64(0xFF))
}
// C documentation
//
// /*
// ** The buffer that the argument points to contains a serialized SQL value.
// ** Return the number of bytes of space occupied by the value (including
// ** the type byte).
// */
func _sessionSerialLen(tls *libc.TLS, a uintptr) (r int32) {
bp := tls.Alloc(16)
defer tls.Free(16)
var e int32
var _ /* n at bp+0 */ int32
_ = e
e = libc.Int32FromUint8(**(**Tu8)(__ccgo_up(a)))
if e == int32(SQLITE_INTEGER) || e == int32(SQLITE_FLOAT) {
return int32(9)
}
if e == int32(SQLITE_TEXT) || e == int32(SQLITE_BLOB) {
return _sessionVarintGet(tls, a+1, bp) + int32(1) + **(**int32)(__ccgo_up(bp))
}
return int32(1)
}
// C documentation
//
// /*
// ** When this function is called, *ppRec points to the start of a record
// ** that contains nCol values. This function advances the pointer *ppRec
// ** until it points to the byte immediately following that record.
// */
func _sessionSkipRecord(tls *libc.TLS, ppRec uintptr, nCol int32) {
bp := tls.Alloc(16)
defer tls.Free(16)
var aRec, v2 uintptr
var eType, i int32
var _ /* nByte at bp+0 */ int32
_, _, _, _ = aRec, eType, i, v2
aRec = **(**uintptr)(__ccgo_up(ppRec))
i = 0
for {
if !(i < nCol) {
break
}
v2 = aRec
aRec = aRec + 1
eType = libc.Int32FromUint8(**(**Tu8)(__ccgo_up(v2)))
if eType == int32(SQLITE_TEXT) || eType == int32(SQLITE_BLOB) {
aRec = aRec + uintptr(_sessionVarintGet(tls, aRec, bp))
aRec = aRec + uintptr(**(**int32)(__ccgo_up(bp)))
} else {
if eType == int32(SQLITE_INTEGER) || eType == int32(SQLITE_FLOAT) {
aRec = aRec + uintptr(8)
}
}
goto _1
_1:
;
i = i + 1
}
**(**uintptr)(__ccgo_up(ppRec)) = aRec
}
// C documentation
//
// /*
// ** Read a varint value from aBuf[] into *piVal. Return the number of
// ** bytes read.
// */
func _sessionVarintGet(tls *libc.TLS, aBuf uintptr, piVal uintptr) (r int32) {
var v1 int32
_ = v1
if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aBuf))) < libc.Int32FromUint8(libc.Uint8FromInt32(0x80)) {
**(**int32)(__ccgo_up(piVal)) = libc.Int32FromUint32(uint32(**(**Tu8)(__ccgo_up(aBuf))))
v1 = libc.Int32FromInt32(1)
} else {
v1 = libc.Int32FromUint8(_sqlite3GetVarint32(tls, aBuf, piVal))
}
return libc.Int32FromUint8(libc.Uint8FromInt32(v1))
}
// C documentation
//
// /*
// ** Return the number of bytes required to store value iVal as a varint.
// */
func _sessionVarintLen(tls *libc.TLS, iVal int32) (r int32) {
return _sqlite3VarintLen(tls, libc.Uint64FromInt32(iVal))
}
// C documentation
//
// /*
// ** Write a varint with value iVal into the buffer at aBuf. Return the
// ** number of bytes written.
// */
func _sessionVarintPut(tls *libc.TLS, aBuf uintptr, iVal int32) (r int32) {
var v1 int32
_ = v1
if libc.Uint32FromInt32(iVal) < libc.Uint32FromInt32(0x80) {
**(**Tu8)(__ccgo_up(aBuf)) = libc.Uint8FromInt32(iVal)
v1 = libc.Int32FromInt32(1)
} else {
v1 = _sqlite3PutVarint(tls, aBuf, libc.Uint64FromInt32(iVal))
}
return libc.Int32FromUint8(libc.Uint8FromInt32(v1))
}
// C documentation
//
// /*
// ** If the last opcode is a OP_Copy, then set the do-not-merge flag (p5)
// ** so that a subsequent copy will not be merged into this one.
// */
func _setDoNotMergeFlagOnCopy(tls *libc.TLS, v uintptr) {
if libc.Int32FromUint8((*TVdbeOp)(unsafe.Pointer(_sqlite3VdbeGetLastOp(tls, v))).Fopcode) == int32(OP_Copy) {
_sqlite3VdbeChangeP5(tls, v, uint16(1)) /* Tag trailing OP_Copy as not mergeable */
}
}
// C documentation
//
// /*
// ** Add the file descriptor used by file handle pFile to the corresponding
// ** pUnused list.
// */
func _setPendingFd(tls *libc.TLS, pFile uintptr) {
var p, pInode uintptr
_, _ = p, pInode
pInode = (*TunixFile)(unsafe.Pointer(pFile)).FpInode
p = (*TunixFile)(unsafe.Pointer(pFile)).FpPreallocatedUnused
(*TUnixUnusedFd)(unsafe.Pointer(p)).FpNext = (*TunixInodeInfo)(unsafe.Pointer(pInode)).FpUnused
(*TunixInodeInfo)(unsafe.Pointer(pInode)).FpUnused = p
(*TunixFile)(unsafe.Pointer(pFile)).Fh = -int32(1)
(*TunixFile)(unsafe.Pointer(pFile)).FpPreallocatedUnused = uintptr(0)
}
// C documentation
//
// /*
// ** Set result column names for a pragma.
// */
func _setPragmaResultColumnNames(tls *libc.TLS, v uintptr, pPragma uintptr) {
var i, j, v1 int32
var n Tu8
_, _, _, _ = i, j, n, v1
n = (*TPragmaName)(unsafe.Pointer(pPragma)).FnPragCName
if libc.Int32FromUint8(n) == 0 {
v1 = int32(1)
} else {
v1 = libc.Int32FromUint8(n)
}
_sqlite3VdbeSetNumCols(tls, v, v1)
if libc.Int32FromUint8(n) == 0 {
_sqlite3VdbeSetColName(tls, v, 0, COLNAME_NAME, (*TPragmaName)(unsafe.Pointer(pPragma)).FzName, libc.UintptrFromInt32(0))
} else {
i = 0
j = libc.Int32FromUint8((*TPragmaName)(unsafe.Pointer(pPragma)).FiPragCName)
for {
if !(i < libc.Int32FromUint8(n)) {
break
}
_sqlite3VdbeSetColName(tls, v, i, COLNAME_NAME, _pragCName[j], libc.UintptrFromInt32(0))
goto _2
_2:
;
i = i + 1
j = j + 1
}
}
}
// C documentation
//
// /*
// ** Set the value of the Pager.sectorSize variable for the given
// ** pager based on the value returned by the xSectorSize method
// ** of the open database file. The sector size will be used
// ** to determine the size and alignment of journal header and
// ** super-journal pointers within created journal files.
// **
// ** For temporary files the effective sector size is always 512 bytes.
// **
// ** Otherwise, for non-temporary files, the effective sector size is
// ** the value returned by the xSectorSize() method rounded up to 32 if
// ** it is less than 32, or rounded down to MAX_SECTOR_SIZE if it
// ** is greater than MAX_SECTOR_SIZE.
// **
// ** If the file has the SQLITE_IOCAP_POWERSAFE_OVERWRITE property, then set
// ** the effective sector size to its minimum value (512). The purpose of
// ** pPager->sectorSize is to define the "blast radius" of bytes that
// ** might change if a crash occurs while writing to a single byte in
// ** that range. But with POWERSAFE_OVERWRITE, the blast radius is zero
// ** (that is what POWERSAFE_OVERWRITE means), so we minimize the sector
// ** size. For backwards compatibility of the rollback journal file format,
// ** we cannot reduce the effective sector size below 512.
// */
func _setSectorSize(tls *libc.TLS, pPager uintptr) {
if (*TPager)(unsafe.Pointer(pPager)).FtempFile != 0 || _sqlite3OsDeviceCharacteristics(tls, (*TPager)(unsafe.Pointer(pPager)).Ffd)&int32(SQLITE_IOCAP_POWERSAFE_OVERWRITE) != 0 {
/* Sector size doesn't matter for temporary files. Also, the file
** may not have been opened yet, in which case the OsSectorSize()
** call will segfault. */
(*TPager)(unsafe.Pointer(pPager)).FsectorSize = uint32(512)
} else {
(*TPager)(unsafe.Pointer(pPager)).FsectorSize = libc.Uint32FromInt32(_sqlite3SectorSize(tls, (*TPager)(unsafe.Pointer(pPager)).Ffd))
}
}
// C documentation
//
// /*
// ** The string z[] is an text representation of a real number.
// ** Convert this string to a double and write it into *pResult.
// **
// ** z[] must be UTF-8 and zero-terminated.
// **
// ** Return positive if the result is a valid real number (or integer) and
// ** zero or negative if the string is empty or contains extraneous text.
// ** Lower bits of the return value contain addition information about the
// ** parse:
// **
// ** bit 0 => Set if any prefix of the input is valid. Clear if
// ** there is no prefix of the input that can be seen as
// ** a valid floating point number.
// ** bit 1 => Set if the input contains a decimal point or eNNN
// ** clause. Zero if the input is an integer.
// ** bit 2 => The input is exactly 0.0, not an underflow from
// ** some value near zero.
// ** bit 3 => Set if there are more than about 19 significant
// ** digits in the input.
// **
// ** If the input contains a syntax error but begins with text that might
// ** be a valid number of some kind, then the result is negative. The
// ** result is only zero if no prefix of the input could be interpreted as
// ** a number.
// **
// ** Leading and trailing whitespace is ignored. Valid numbers are in
// ** one of the formats below:
// **
// ** [+-]digits[E[+-]digits]
// ** [+-]digits.[digits][E[+-]digits]
// ** [+-].digits[E[+-]digits]
// **
// ** Algorithm sketch: Compute an unsigned 64-bit integer s and a base-10
// ** exponent d such that the value encoding by the input is s*pow(10,d).
// ** Then invoke sqlite3Fp10Convert2() to calculated the closest possible
// ** IEEE754 double. The sign is added back afterwards, if the input string
// ** starts with a "-". The use of an unsigned 64-bit s mantissa means that
// ** only about the first 19 significant digits of the input can contribute
// ** to the result. This can result in suboptimal rounding decisions when
// ** correct rounding requires more than 19 input digits. For example,
// ** this routine renders "3500000000000000.2500001" as
// ** 3500000000000000.0 instead of 3500000000000000.5 because the decision
// ** to round up instead of using banker's rounding to round down is determined
// ** by the 23rd significant digit, which this routine ignores. It is not
// ** possible to do better without some kind of BigNum.
// */
func _sqlite3AtoF(tls *libc.TLS, zIn uintptr, pResult uintptr) (r int32) {
var d, esign, exp, mState, neg int32
var s Tu64
var v, v3, v4 uint32
var z, v7 uintptr
_, _, _, _, _, _, _, _, _, _, _ = d, esign, exp, mState, neg, s, v, z, v3, v4, v7
z = zIn
neg = 0 /* True for a negative value */
s = uint64(0) /* mantissa */
d = 0 /* Value is s * pow(10,d) */
mState = 0 /* Value of a single digit */
goto start_of_text
start_of_text:
;
v3 = uint32(**(**uint8)(__ccgo_up(z))) - libc.Uint32FromUint8('0')
v = v3
if !(v3 < uint32(10)) {
goto _1
}
goto parse_integer_part
parse_integer_part:
;
mState = int32(1)
s = uint64(v)
z = z + 1
for {
v3 = uint32(**(**uint8)(__ccgo_up(z))) - libc.Uint32FromUint8('0')
v = v3
if !(v3 < uint32(10)) {
break
}
s = s*uint64(10) + uint64(v)
z = z + 1
if s >= (libc.Uint64FromUint32(0xffffffff)|libc.Uint64FromUint32(0xffffffff)<<libc.Int32FromInt32(32)-libc.Uint64FromInt32(9))/libc.Uint64FromInt32(10) {
mState = int32(9)
for libc.Int32FromUint8(_sqlite3CtypeMap[**(**uint8)(__ccgo_up(z))])&int32(0x04) != 0 {
z = z + 1
d = d + 1
}
break
}
}
goto _2
_1:
;
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z))) == int32('-') {
neg = int32(1)
z = z + 1
v3 = uint32(**(**uint8)(__ccgo_up(z))) - libc.Uint32FromUint8('0')
v = v3
if v3 < uint32(10) {
goto parse_integer_part
}
} else {
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z))) == int32('+') {
z = z + 1
v3 = uint32(**(**uint8)(__ccgo_up(z))) - libc.Uint32FromUint8('0')
v = v3
if v3 < uint32(10) {
goto parse_integer_part
}
} else {
if libc.Int32FromUint8(_sqlite3CtypeMap[**(**uint8)(__ccgo_up(z))])&int32(0x01) != 0 {
for cond := true; cond; cond = libc.Int32FromUint8(_sqlite3CtypeMap[**(**uint8)(__ccgo_up(z))])&int32(0x01) != 0 {
z = z + 1
}
goto start_of_text
} else {
s = uint64(0)
}
}
}
_2:
;
/* if decimal point is present */
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z))) == int32('.') {
z = z + 1
if libc.Int32FromUint8(_sqlite3CtypeMap[**(**uint8)(__ccgo_up(z))])&int32(0x04) != 0 {
mState = mState | int32(1)
for {
if s < (libc.Uint64FromUint32(0xffffffff)|libc.Uint64FromUint32(0xffffffff)<<libc.Int32FromInt32(32)-libc.Uint64FromInt32(9))/libc.Uint64FromInt32(10) {
s = s*uint64(10) + uint64(**(**uint8)(__ccgo_up(z))) - uint64('0')
d = d - 1
} else {
mState = int32(11)
}
goto _8
_8:
;
z = z + 1
v7 = z
if !(libc.Int32FromUint8(_sqlite3CtypeMap[**(**uint8)(__ccgo_up(v7))])&int32(0x04) != 0) {
break
}
}
} else {
if mState == 0 {
**(**float64)(__ccgo_up(pResult)) = float64(0)
return 0
}
}
mState = mState | int32(2)
} else {
if mState == 0 {
**(**float64)(__ccgo_up(pResult)) = float64(0)
return 0
}
}
/* if exponent is present */
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z))) == int32('e') || libc.Int32FromUint8(**(**uint8)(__ccgo_up(z))) == int32('E') {
z = z + 1
/* get sign of exponent */
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z))) == int32('-') {
esign = -int32(1)
z = z + 1
} else {
esign = +libc.Int32FromInt32(1)
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z))) == int32('+') {
z = z + 1
}
}
/* copy digits to exponent */
v3 = uint32(**(**uint8)(__ccgo_up(z))) - libc.Uint32FromUint8('0')
v = v3
if v3 < uint32(10) {
exp = libc.Int32FromUint32(v)
z = z + 1
mState = mState | int32(2)
for {
v3 = uint32(**(**uint8)(__ccgo_up(z))) - libc.Uint32FromUint8('0')
v = v3
if !(v3 < uint32(10)) {
break
}
if exp < int32(10000) {
v4 = libc.Uint32FromInt32(exp*int32(10)) + v
} else {
v4 = uint32(10000)
}
exp = libc.Int32FromUint32(v4)
z = z + 1
}
d = d + esign*exp
} else {
z = z - 1 /* Leave z[0] at 'e' or '+' or '-',
** so that the return is 0 or -1 */
}
}
/* Convert s*pow(10,d) into real */
if s == uint64(0) {
**(**float64)(__ccgo_up(pResult)) = float64(0)
mState = mState | int32(4)
} else {
**(**float64)(__ccgo_up(pResult)) = _sqlite3Fp10Convert2(tls, s, d)
}
if neg != 0 {
**(**float64)(__ccgo_up(pResult)) = -**(**float64)(__ccgo_up(pResult))
}
/* return true if number and no extra non-whitespace characters after */
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z))) == 0 {
return mState
}
if libc.Int32FromUint8(_sqlite3CtypeMap[**(**uint8)(__ccgo_up(z))])&int32(0x01) != 0 {
for cond := true; cond; cond = libc.Int32FromUint8(_sqlite3CtypeMap[**(**uint8)(__ccgo_up(z))])&int32(0x01) != 0 {
z = z + 1
}
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z))) == 0 {
return mState
}
}
return libc.Int32FromUint32(uint32(0xfffffff0) | libc.Uint32FromInt32(mState))
}
// C documentation
//
// /*
// ** This routine runs an extensive test of the Bitvec code.
// **
// ** The input is an array of integers that acts as a program
// ** to test the Bitvec. The integers are opcodes followed
// ** by 0, 1, or 3 operands, depending on the opcode. Another
// ** opcode follows immediately after the last operand.
// **
// ** There are opcodes numbered starting with 0. 0 is the
// ** "halt" opcode and causes the test to end.
// **
// ** 0 Halt and return the number of errors
// ** 1 N S X Set N bits beginning with S and incrementing by X
// ** 2 N S X Clear N bits beginning with S and incrementing by X
// ** 3 N Set N randomly chosen bits
// ** 4 N Clear N randomly chosen bits
// ** 5 N S X Set N bits from S increment X in array only, not in bitvec
// ** 6 Invoice sqlite3ShowBitvec() on the Bitvec object so far
// ** 7 X Show compile-time parameters and the hash of X
// **
// ** The opcodes 1 through 4 perform set and clear operations are performed
// ** on both a Bitvec object and on a linear array of bits obtained from malloc.
// ** Opcode 5 works on the linear array only, not on the Bitvec.
// ** Opcode 5 is used to deliberately induce a fault in order to
// ** confirm that error detection works. Opcodes 6 and greater are
// ** state output opcodes. Opcodes 6 and greater are no-ops unless
// ** SQLite has been compiled with SQLITE_DEBUG.
// **
// ** At the conclusion of the test the linear array is compared
// ** against the Bitvec object. If there are any differences,
// ** an error is returned. If they are the same, zero is returned.
// **
// ** If a memory allocation error occurs, return -1.
// **
// ** sz is the size of the Bitvec. Or if sz is negative, make the size
// ** 2*(unsigned)(-sz) and disabled the linear vector check.
// */
func _sqlite3BitvecBuiltinTest(tls *libc.TLS, sz int32, aOp uintptr) (r int32) {
bp := tls.Alloc(16)
defer tls.Free(16)
var nx, op, pc, rc, v1 int32
var pBitvec, pTmpSpace, pV, v4 uintptr
var _ /* i at bp+0 */ int32
_, _, _, _, _, _, _, _, _ = nx, op, pBitvec, pTmpSpace, pV, pc, rc, v1, v4
pBitvec = uintptr(0)
pV = uintptr(0)
rc = -int32(1)
/* Allocate the Bitvec to be tested and a linear array of
** bits to act as the reference */
if sz <= 0 {
pBitvec = _sqlite3BitvecCreate(tls, uint32(2)*libc.Uint32FromInt32(-sz))
pV = uintptr(0)
} else {
pBitvec = _sqlite3BitvecCreate(tls, libc.Uint32FromInt32(sz))
pV = _sqlite3MallocZero(tls, libc.Uint64FromInt64((int64(7)+int64(sz))/int64(8)+int64(1)))
}
pTmpSpace = Xsqlite3_malloc64(tls, uint64(BITVEC_SZ))
if pBitvec == uintptr(0) || pTmpSpace == uintptr(0) || pV == uintptr(0) && sz > 0 {
goto bitvec_end
}
/* NULL pBitvec tests */
_sqlite3BitvecSet(tls, uintptr(0), uint32(1))
_sqlite3BitvecClear(tls, uintptr(0), uint32(1), pTmpSpace)
/* Run the program */
v1 = libc.Int32FromInt32(0)
**(**int32)(__ccgo_up(bp)) = v1
pc = v1
for {
v1 = **(**int32)(__ccgo_up(aOp + uintptr(pc)*4))
op = v1
if !(v1 != 0) {
break
}
if op >= int32(6) {
pc = pc + 1
continue
}
switch op {
case int32(1):
fallthrough
case int32(2):
fallthrough
case int32(5):
nx = int32(4)
**(**int32)(__ccgo_up(bp)) = **(**int32)(__ccgo_up(aOp + uintptr(pc+int32(2))*4)) - int32(1)
**(**int32)(__ccgo_up(aOp + uintptr(pc+int32(2))*4)) += **(**int32)(__ccgo_up(aOp + uintptr(pc+int32(3))*4))
case int32(3):
fallthrough
case int32(4):
fallthrough
default:
nx = int32(2)
Xsqlite3_randomness(tls, int32(4), bp)
break
}
v4 = aOp + uintptr(pc+int32(1))*4
*(*int32)(unsafe.Pointer(v4)) = *(*int32)(unsafe.Pointer(v4)) - 1
v1 = *(*int32)(unsafe.Pointer(v4))
if v1 > 0 {
nx = 0
}
pc = pc + nx
**(**int32)(__ccgo_up(bp)) = **(**int32)(__ccgo_up(bp)) & int32(0x7fffffff) % sz
if op&int32(1) != 0 {
if pV != 0 {
v4 = pV + uintptr((**(**int32)(__ccgo_up(bp))+int32(1))>>int32(3))
*(*uint8)(unsafe.Pointer(v4)) = uint8(int32(*(*uint8)(unsafe.Pointer(v4))) | libc.Int32FromInt32(1)<<((**(**int32)(__ccgo_up(bp))+libc.Int32FromInt32(1))&libc.Int32FromInt32(7)))
}
if op != int32(5) {
if _sqlite3BitvecSet(tls, pBitvec, libc.Uint32FromInt32(**(**int32)(__ccgo_up(bp))+int32(1))) != 0 {
goto bitvec_end
}
}
} else {
if pV != 0 {
v4 = pV + uintptr((**(**int32)(__ccgo_up(bp))+int32(1))>>int32(3))
*(*uint8)(unsafe.Pointer(v4)) = uint8(int32(*(*uint8)(unsafe.Pointer(v4))) & ^libc.Int32FromUint8(libc.Uint8FromInt32(libc.Int32FromInt32(1)<<((**(**int32)(__ccgo_up(bp))+libc.Int32FromInt32(1))&libc.Int32FromInt32(7)))))
}
_sqlite3BitvecClear(tls, pBitvec, libc.Uint32FromInt32(**(**int32)(__ccgo_up(bp))+int32(1)), pTmpSpace)
}
}
/* Test to make sure the linear array exactly matches the
** Bitvec object. Start with the assumption that they do
** match (rc==0). Change rc to non-zero if a discrepancy
** is found.
*/
if pV != 0 {
rc = libc.Int32FromUint32(libc.Uint32FromInt32(_sqlite3BitvecTest(tls, uintptr(0), uint32(0))+_sqlite3BitvecTest(tls, pBitvec, libc.Uint32FromInt32(sz+int32(1)))+_sqlite3BitvecTest(tls, pBitvec, uint32(0))) + (_sqlite3BitvecSize(tls, pBitvec) - libc.Uint32FromInt32(sz)))
**(**int32)(__ccgo_up(bp)) = int32(1)
for {
if !(**(**int32)(__ccgo_up(bp)) <= sz) {
break
}
if libc.BoolInt32(libc.Int32FromUint8(**(**uint8)(__ccgo_up(pV + uintptr(**(**int32)(__ccgo_up(bp))>>int32(3)))))&(int32(1)<<(**(**int32)(__ccgo_up(bp))&int32(7))) != 0) != _sqlite3BitvecTest(tls, pBitvec, libc.Uint32FromInt32(**(**int32)(__ccgo_up(bp)))) {
rc = **(**int32)(__ccgo_up(bp))
break
}
goto _7
_7:
;
**(**int32)(__ccgo_up(bp)) = **(**int32)(__ccgo_up(bp)) + 1
}
} else {
rc = 0
}
/* Free allocated structure */
goto bitvec_end
bitvec_end:
;
Xsqlite3_free(tls, pTmpSpace)
Xsqlite3_free(tls, pV)
_sqlite3BitvecDestroy(tls, pBitvec)
return rc
}
/********************************** Test and Debug Logic **********************/
/*
** Debug tracing macros. Enable by by changing the "0" to "1" and
** recompiling.
**
** When sqlite3PcacheTrace is 1, single line trace messages are issued.
** When sqlite3PcacheTrace is 2, a dump of the pcache showing all cache entries
** is displayed for many operations, resulting in a lot of output.
*/
/*
** Return 1 if pPg is on the dirty list for pCache. Return 0 if not.
** This routine runs inside of assert() statements only.
*/
/*
** Check invariants on a PgHdr entry. Return true if everything is OK.
** Return false if any invariant is violated.
**
** This routine is for use inside of assert() statements only. For
** example:
**
** assert( sqlite3PcachePageSanity(pPg) );
*/
/********************************** Linked List Management ********************/
/* Allowed values for second argument to pcacheManageDirtyList() */
func _sqlite3BtreeBeginTrans(tls *libc.TLS, p uintptr, wrflag int32, pSchemaVersion uintptr) (r int32) {
var pBt uintptr
_ = pBt
if (*TBtree)(unsafe.Pointer(p)).Fsharable != 0 || libc.Int32FromUint8((*TBtree)(unsafe.Pointer(p)).FinTrans) == TRANS_NONE || libc.Int32FromUint8((*TBtree)(unsafe.Pointer(p)).FinTrans) == int32(TRANS_READ) && wrflag != 0 {
return _btreeBeginTrans(tls, p, wrflag, pSchemaVersion)
}
pBt = (*TBtree)(unsafe.Pointer(p)).FpBt
if pSchemaVersion != 0 {
**(**int32)(__ccgo_up(pSchemaVersion)) = libc.Int32FromUint32(_sqlite3Get4byte(tls, (*TMemPage)(unsafe.Pointer((*TBtShared)(unsafe.Pointer(pBt)).FpPage1)).FaData+40))
}
if wrflag != 0 {
/* This call makes sure that the pager has the correct number of
** open savepoints. If the second parameter is greater than 0 and
** the sub-journal is not already open, then it will be opened here.
*/
return _sqlite3PagerOpenSavepoint(tls, (*TBtShared)(unsafe.Pointer(pBt)).FpPager, (*Tsqlite3)(unsafe.Pointer((*TBtree)(unsafe.Pointer(p)).Fdb)).FnSavepoint)
} else {
return SQLITE_OK
}
return r
}
// C documentation
//
// /*
// ** Run a checkpoint on the Btree passed as the first argument.
// **
// ** Return SQLITE_LOCKED if this or any other connection has an open
// ** transaction on the shared-cache the argument Btree is connected to.
// **
// ** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART.
// */
func _sqlite3BtreeCheckpoint(tls *libc.TLS, p uintptr, eMode int32, pnLog uintptr, pnCkpt uintptr) (r int32) {
var pBt uintptr
var rc int32
_, _ = pBt, rc
rc = SQLITE_OK
if p != 0 {
pBt = (*TBtree)(unsafe.Pointer(p)).FpBt
_sqlite3BtreeEnter(tls, p)
if libc.Int32FromUint8((*TBtShared)(unsafe.Pointer(pBt)).FinTransaction) != TRANS_NONE {
rc = int32(SQLITE_LOCKED)
} else {
rc = _sqlite3PagerCheckpoint(tls, (*TBtShared)(unsafe.Pointer(pBt)).FpPager, (*TBtree)(unsafe.Pointer(p)).Fdb, eMode, pnLog, pnCkpt)
}
_sqlite3BtreeLeave(tls, p)
}
return rc
}
// C documentation
//
// /*
// ** If no transaction is active and the database is not a temp-db, clear
// ** the in-memory pager cache.
// */
func _sqlite3BtreeClearCache(tls *libc.TLS, p uintptr) {
var pBt uintptr
_ = pBt
pBt = (*TBtree)(unsafe.Pointer(p)).FpBt
if libc.Int32FromUint8((*TBtShared)(unsafe.Pointer(pBt)).FinTransaction) == TRANS_NONE {
_sqlite3PagerClearCache(tls, (*TBtShared)(unsafe.Pointer(pBt)).FpPager)
}
}
// C documentation
//
// /*
// ** Delete all information from a single table in the database. iTable is
// ** the page number of the root of the table. After this routine returns,
// ** the root page is empty, but still exists.
// **
// ** This routine will fail with SQLITE_LOCKED if there are any open
// ** read cursors on the table. Open write cursors are moved to the
// ** root of the table.
// **
// ** If pnChange is not NULL, then the integer value pointed to by pnChange
// ** is incremented by the number of entries in the table.
// */
func _sqlite3BtreeClearTable(tls *libc.TLS, p uintptr, iTable int32, pnChange uintptr) (r int32) {
var pBt uintptr
var rc int32
_, _ = pBt, rc
pBt = (*TBtree)(unsafe.Pointer(p)).FpBt
_sqlite3BtreeEnter(tls, p)
rc = _saveAllCursors(tls, pBt, libc.Uint32FromInt32(iTable), uintptr(0))
if SQLITE_OK == rc {
/* Invalidate all incrblob cursors open on table iTable (assuming iTable
** is the root of a table b-tree - if it is not, the following call is
** a no-op). */
if (*TBtree)(unsafe.Pointer(p)).FhasIncrblobCur != 0 {
_invalidateIncrblobCursors(tls, p, libc.Uint32FromInt32(iTable), 0, int32(1))
}
rc = _clearDatabasePage(tls, pBt, libc.Uint32FromInt32(iTable), 0, pnChange)
}
_sqlite3BtreeLeave(tls, p)
return rc
}
// C documentation
//
// /*
// ** Delete all information from the single table that pCur is open on.
// **
// ** This routine only work for pCur on an ephemeral table.
// */
func _sqlite3BtreeClearTableOfCursor(tls *libc.TLS, pCur uintptr) (r int32) {
return _sqlite3BtreeClearTable(tls, (*TBtCursor)(unsafe.Pointer(pCur)).FpBtree, libc.Int32FromUint32((*TBtCursor)(unsafe.Pointer(pCur)).FpgnoRoot), uintptr(0))
}
// C documentation
//
// /*
// ** Close a cursor. The read lock on the database file is released
// ** when the last cursor is closed.
// */
func _sqlite3BtreeCloseCursor(tls *libc.TLS, pCur uintptr) (r int32) {
var pBt, pBtree, pPrev uintptr
_, _, _ = pBt, pBtree, pPrev
pBtree = (*TBtCursor)(unsafe.Pointer(pCur)).FpBtree
if pBtree != 0 {
pBt = (*TBtCursor)(unsafe.Pointer(pCur)).FpBt
_sqlite3BtreeEnter(tls, pBtree)
if (*TBtShared)(unsafe.Pointer(pBt)).FpCursor == pCur {
(*TBtShared)(unsafe.Pointer(pBt)).FpCursor = (*TBtCursor)(unsafe.Pointer(pCur)).FpNext
} else {
pPrev = (*TBtShared)(unsafe.Pointer(pBt)).FpCursor
for cond := true; cond; cond = pPrev != 0 {
if (*TBtCursor)(unsafe.Pointer(pPrev)).FpNext == pCur {
(*TBtCursor)(unsafe.Pointer(pPrev)).FpNext = (*TBtCursor)(unsafe.Pointer(pCur)).FpNext
break
}
pPrev = (*TBtCursor)(unsafe.Pointer(pPrev)).FpNext
}
}
_btreeReleaseAllCursorPages(tls, pCur)
_unlockBtreeIfUnused(tls, pBt)
Xsqlite3_free(tls, (*TBtCursor)(unsafe.Pointer(pCur)).FaOverflow)
Xsqlite3_free(tls, (*TBtCursor)(unsafe.Pointer(pCur)).FpKey)
if libc.Int32FromUint8((*TBtShared)(unsafe.Pointer(pBt)).FopenFlags)&int32(BTREE_SINGLE) != 0 && (*TBtShared)(unsafe.Pointer(pBt)).FpCursor == uintptr(0) {
/* Since the BtShared is not sharable, there is no need to
** worry about the missing sqlite3BtreeLeave() call here. */
_sqlite3BtreeClose(tls, pBtree)
} else {
_sqlite3BtreeLeave(tls, pBtree)
}
(*TBtCursor)(unsafe.Pointer(pCur)).FpBtree = uintptr(0)
}
return SQLITE_OK
}
// C documentation
//
// /*
// ** This routine does the first phase of a two-phase commit. This routine
// ** causes a rollback journal to be created (if it does not already exist)
// ** and populated with enough information so that if a power loss occurs
// ** the database can be restored to its original state by playing back
// ** the journal. Then the contents of the journal are flushed out to
// ** the disk. After the journal is safely on oxide, the changes to the
// ** database are written into the database file and flushed to oxide.
// ** At the end of this call, the rollback journal still exists on the
// ** disk and we are still holding all locks, so the transaction has not
// ** committed. See sqlite3BtreeCommitPhaseTwo() for the second phase of the
// ** commit process.
// **
// ** This call is a no-op if no write-transaction is currently active on pBt.
// **
// ** Otherwise, sync the database file for the btree pBt. zSuperJrnl points to
// ** the name of a super-journal file that should be written into the
// ** individual journal file, or is NULL, indicating no super-journal file
// ** (single database transaction).
// **
// ** When this is called, the super-journal should already have been
// ** created, populated with this journal pointer and synced to disk.
// **
// ** Once this is routine has returned, the only thing required to commit
// ** the write-transaction for this database file is to delete the journal.
// */
func _sqlite3BtreeCommitPhaseOne(tls *libc.TLS, p uintptr, zSuperJrnl uintptr) (r int32) {
var pBt uintptr
var rc int32
_, _ = pBt, rc
rc = SQLITE_OK
if libc.Int32FromUint8((*TBtree)(unsafe.Pointer(p)).FinTrans) == int32(TRANS_WRITE) {
pBt = (*TBtree)(unsafe.Pointer(p)).FpBt
_sqlite3BtreeEnter(tls, p)
if (*TBtShared)(unsafe.Pointer(pBt)).FautoVacuum != 0 {
rc = _autoVacuumCommit(tls, p)
if rc != SQLITE_OK {
_sqlite3BtreeLeave(tls, p)
return rc
}
}
if (*TBtShared)(unsafe.Pointer(pBt)).FbDoTruncate != 0 {
_sqlite3PagerTruncateImage(tls, (*TBtShared)(unsafe.Pointer(pBt)).FpPager, (*TBtShared)(unsafe.Pointer(pBt)).FnPage)
}
rc = _sqlite3PagerCommitPhaseOne(tls, (*TBtShared)(unsafe.Pointer(pBt)).FpPager, zSuperJrnl, 0)
_sqlite3BtreeLeave(tls, p)
}
return rc
}
// C documentation
//
// /*
// ** Commit the transaction currently in progress.
// **
// ** This routine implements the second phase of a 2-phase commit. The
// ** sqlite3BtreeCommitPhaseOne() routine does the first phase and should
// ** be invoked prior to calling this routine. The sqlite3BtreeCommitPhaseOne()
// ** routine did all the work of writing information out to disk and flushing the
// ** contents so that they are written onto the disk platter. All this
// ** routine has to do is delete or truncate or zero the header in the
// ** the rollback journal (which causes the transaction to commit) and
// ** drop locks.
// **
// ** Normally, if an error occurs while the pager layer is attempting to
// ** finalize the underlying journal file, this function returns an error and
// ** the upper layer will attempt a rollback. However, if the second argument
// ** is non-zero then this b-tree transaction is part of a multi-file
// ** transaction. In this case, the transaction has already been committed
// ** (by deleting a super-journal file) and the caller will ignore this
// ** functions return code. So, even if an error occurs in the pager layer,
// ** reset the b-tree objects internal state to indicate that the write
// ** transaction has been closed. This is quite safe, as the pager will have
// ** transitioned to the error state.
// **
// ** This will release the write lock on the database file. If there
// ** are no active cursors, it also releases the read lock.
// */
func _sqlite3BtreeCommitPhaseTwo(tls *libc.TLS, p uintptr, bCleanup int32) (r int32) {
var pBt uintptr
var rc int32
_, _ = pBt, rc
if libc.Int32FromUint8((*TBtree)(unsafe.Pointer(p)).FinTrans) == TRANS_NONE {
return SQLITE_OK
}
_sqlite3BtreeEnter(tls, p)
/* If the handle has a write-transaction open, commit the shared-btrees
** transaction and set the shared state to TRANS_READ.
*/
if libc.Int32FromUint8((*TBtree)(unsafe.Pointer(p)).FinTrans) == int32(TRANS_WRITE) {
pBt = (*TBtree)(unsafe.Pointer(p)).FpBt
rc = _sqlite3PagerCommitPhaseTwo(tls, (*TBtShared)(unsafe.Pointer(pBt)).FpPager)
if rc != SQLITE_OK && bCleanup == 0 {
_sqlite3BtreeLeave(tls, p)
return rc
}
(*TBtree)(unsafe.Pointer(p)).FiBDataVersion = (*TBtree)(unsafe.Pointer(p)).FiBDataVersion - 1 /* Compensate for pPager->iDataVersion++; */
(*TBtShared)(unsafe.Pointer(pBt)).FinTransaction = uint8(TRANS_READ)
_btreeClearHasContent(tls, pBt)
}
_btreeEndTransaction(tls, p)
_sqlite3BtreeLeave(tls, p)
return SQLITE_OK
}
// C documentation
//
// /*
// ** Determine whether or not a cursor has moved from the position where
// ** it was last placed, or has been invalidated for any other reason.
// ** Cursors can move when the row they are pointing at is deleted out
// ** from under them, for example. Cursor might also move if a btree
// ** is rebalanced.
// **
// ** Calling this routine with a NULL cursor pointer returns false.
// **
// ** Use the separate sqlite3BtreeCursorRestore() routine to restore a cursor
// ** back to where it ought to be if this routine returns true.
// */
func _sqlite3BtreeCursorHasMoved(tls *libc.TLS, pCur uintptr) (r int32) {
return libc.BoolInt32(CURSOR_VALID != libc.Int32FromUint8(**(**Tu8)(__ccgo_up(pCur))))
}
func _sqlite3BtreeCursorIsValidNN(tls *libc.TLS, pCur uintptr) (r int32) {
return libc.BoolInt32(libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCur)).FeState) == CURSOR_VALID)
}
// C documentation
//
// /*
// ** This routine restores a cursor back to its original position after it
// ** has been moved by some outside activity (such as a btree rebalance or
// ** a row having been deleted out from under the cursor).
// **
// ** On success, the *pDifferentRow parameter is false if the cursor is left
// ** pointing at exactly the same row. *pDifferntRow is the row the cursor
// ** was pointing to has been deleted, forcing the cursor to point to some
// ** nearby row.
// **
// ** This routine should only be called for a cursor that just returned
// ** TRUE from sqlite3BtreeCursorHasMoved().
// */
func _sqlite3BtreeCursorRestore(tls *libc.TLS, pCur uintptr, pDifferentRow uintptr) (r int32) {
var rc, v1 int32
_, _ = rc, v1
if libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCur)).FeState) >= int32(CURSOR_REQUIRESEEK) {
v1 = _btreeRestoreCursorPosition(tls, pCur)
} else {
v1 = SQLITE_OK
}
rc = v1
if rc != 0 {
**(**int32)(__ccgo_up(pDifferentRow)) = int32(1)
return rc
}
if libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCur)).FeState) != CURSOR_VALID {
**(**int32)(__ccgo_up(pDifferentRow)) = int32(1)
} else {
**(**int32)(__ccgo_up(pDifferentRow)) = 0
}
return SQLITE_OK
}
func _sqlite3BtreeDropTable(tls *libc.TLS, p uintptr, iTable int32, piMoved uintptr) (r int32) {
var rc int32
_ = rc
_sqlite3BtreeEnter(tls, p)
rc = _btreeDropTable(tls, p, libc.Uint32FromInt32(iTable), piMoved)
_sqlite3BtreeLeave(tls, p)
return rc
}
func _sqlite3BtreeEnterAll(tls *libc.TLS, db uintptr) {
if libc.Int32FromUint8((*Tsqlite3)(unsafe.Pointer(db)).FnoSharedCache) == 0 {
_btreeEnterAll(tls, db)
}
}
// C documentation
//
// /*
// ** Return TRUE if the cursor is not pointing at an entry of the table.
// **
// ** TRUE will be returned after a call to sqlite3BtreeNext() moves
// ** past the last entry in the table or sqlite3BtreePrev() moves past
// ** the first entry. TRUE is also returned if the table is empty.
// */
func _sqlite3BtreeEof(tls *libc.TLS, pCur uintptr) (r int32) {
/* TODO: What if the cursor is in CURSOR_REQUIRESEEK but all table entries
** have been deleted? This API will need to change to return an error code
** as well as the boolean result value.
*/
return libc.BoolInt32(CURSOR_VALID != libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCur)).FeState))
}
// C documentation
//
// /*
// ** Return the currently defined page size
// */
func _sqlite3BtreeGetPageSize(tls *libc.TLS, p uintptr) (r int32) {
return libc.Int32FromUint32((*TBtShared)(unsafe.Pointer((*TBtree)(unsafe.Pointer(p)).FpBt)).FpageSize)
}
// C documentation
//
// /*
// ** Return the number of bytes of space at the end of every page that
// ** are intentionally left unused. This is the "reserved" space that is
// ** sometimes used by extensions.
// **
// ** The value returned is the larger of the current reserve size and
// ** the latest reserve size requested by SQLITE_FILECTRL_RESERVE_BYTES.
// ** The amount of reserve can only grow - never shrink.
// */
func _sqlite3BtreeGetRequestedReserve(tls *libc.TLS, p uintptr) (r int32) {
var n1, n2, v1 int32
_, _, _ = n1, n2, v1
_sqlite3BtreeEnter(tls, p)
n1 = libc.Int32FromUint8((*TBtShared)(unsafe.Pointer((*TBtree)(unsafe.Pointer(p)).FpBt)).FnReserveWanted)
n2 = _sqlite3BtreeGetReserveNoMutex(tls, p)
_sqlite3BtreeLeave(tls, p)
if n1 > n2 {
v1 = n1
} else {
v1 = n2
}
return v1
}
// C documentation
//
// /*
// ** This function is similar to sqlite3BtreeGetReserve(), except that it
// ** may only be called if it is guaranteed that the b-tree mutex is already
// ** held.
// **
// ** This is useful in one special case in the backup API code where it is
// ** known that the shared b-tree mutex is held, but the mutex on the
// ** database handle that owns *p is not. In this case if sqlite3BtreeEnter()
// ** were to be called, it might collide with some other operation on the
// ** database handle that owns *p, causing undefined behavior.
// */
func _sqlite3BtreeGetReserveNoMutex(tls *libc.TLS, p uintptr) (r int32) {
var n int32
_ = n
n = libc.Int32FromUint32((*TBtShared)(unsafe.Pointer((*TBtree)(unsafe.Pointer(p)).FpBt)).FpageSize - (*TBtShared)(unsafe.Pointer((*TBtree)(unsafe.Pointer(p)).FpBt)).FusableSize)
return n
}
// C documentation
//
// /* Set *pRes to 1 (true) if the BTree pointed to by cursor pCur contains zero
// ** rows of content. Set *pRes to 0 (false) if the table contains content.
// ** Return SQLITE_OK on success or some error code (ex: SQLITE_NOMEM) if
// ** something goes wrong.
// */
func _sqlite3BtreeIsEmpty(tls *libc.TLS, pCur uintptr, pRes uintptr) (r int32) {
var rc int32
_ = rc
if libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCur)).FeState) == CURSOR_VALID {
**(**int32)(__ccgo_up(pRes)) = 0
return SQLITE_OK
}
rc = _moveToRoot(tls, pCur)
if rc == int32(SQLITE_EMPTY) {
**(**int32)(__ccgo_up(pRes)) = int32(1)
rc = SQLITE_OK
} else {
**(**int32)(__ccgo_up(pRes)) = 0
}
return rc
}
// C documentation
//
// /*
// ** Return true if the given Btree is read-only.
// */
func _sqlite3BtreeIsReadonly(tls *libc.TLS, p uintptr) (r int32) {
return libc.BoolInt32(libc.Int32FromUint16((*TBtShared)(unsafe.Pointer((*TBtree)(unsafe.Pointer(p)).FpBt)).FbtsFlags)&int32(BTS_READ_ONLY) != 0)
}
func _sqlite3BtreeLast(tls *libc.TLS, pCur uintptr, pRes uintptr) (r int32) {
/* If the cursor already points to the last entry, this is a no-op. */
if CURSOR_VALID == libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCur)).FeState) && libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCur)).FcurFlags)&int32(BTCF_AtLast) != 0 {
**(**int32)(__ccgo_up(pRes)) = 0
return SQLITE_OK
}
return _btreeLast(tls, pCur, pRes)
}
func _sqlite3BtreeLeaveAll(tls *libc.TLS, db uintptr) {
if libc.Int32FromUint8((*Tsqlite3)(unsafe.Pointer(db)).FnoSharedCache) == 0 {
_btreeLeaveAll(tls, db)
}
}
// C documentation
//
// /*
// ** Obtain a lock on the table whose root page is iTab. The
// ** lock is a write lock if isWritelock is true or a read lock
// ** if it is false.
// */
func _sqlite3BtreeLockTable(tls *libc.TLS, p uintptr, iTab int32, isWriteLock Tu8) (r int32) {
var lockType Tu8
var rc int32
_, _ = lockType, rc
rc = SQLITE_OK
if (*TBtree)(unsafe.Pointer(p)).Fsharable != 0 {
lockType = libc.Uint8FromInt32(int32(READ_LOCK) + libc.Int32FromUint8(isWriteLock))
_sqlite3BtreeEnter(tls, p)
rc = _querySharedCacheTableLock(tls, p, libc.Uint32FromInt32(iTab), lockType)
if rc == SQLITE_OK {
rc = _setSharedCacheTableLock(tls, p, libc.Uint32FromInt32(iTab), lockType)
}
_sqlite3BtreeLeave(tls, p)
}
return rc
}
// C documentation
//
// /*
// ** Return an upper bound on the size of any record for the table
// ** that the cursor is pointing into.
// **
// ** This is an optimization. Everything will still work if this
// ** routine always returns 2147483647 (which is the largest record
// ** that SQLite can handle) or more. But returning a smaller value might
// ** prevent large memory allocations when trying to interpret a
// ** corrupt database.
// **
// ** The current implementation merely returns the size of the underlying
// ** database file.
// */
func _sqlite3BtreeMaxRecordSize(tls *libc.TLS, pCur uintptr) (r Tsqlite3_int64) {
return libc.Int64FromUint32((*TBtShared)(unsafe.Pointer((*TBtCursor)(unsafe.Pointer(pCur)).FpBt)).FpageSize) * libc.Int64FromUint32((*TBtShared)(unsafe.Pointer((*TBtCursor)(unsafe.Pointer(pCur)).FpBt)).FnPage)
}
func _sqlite3BtreePayloadChecked(tls *libc.TLS, pCur uintptr, offset Tu32, amt Tu32, pBuf uintptr) (r int32) {
if libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCur)).FeState) == CURSOR_VALID {
return _accessPayload(tls, pCur, offset, amt, pBuf, 0)
} else {
return _accessPayloadChecked(tls, pCur, offset, amt, pBuf)
}
return r
}
func _sqlite3BtreePrevious(tls *libc.TLS, pCur uintptr, flags int32) (r int32) {
var v1 uintptr
_ = v1
_ = flags /* Used in COMDB2 but not native SQLite */
v1 = pCur + 1
*(*Tu8)(unsafe.Pointer(v1)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v1))) & ^(libc.Int32FromInt32(BTCF_AtLast) | libc.Int32FromInt32(BTCF_ValidOvfl) | libc.Int32FromInt32(BTCF_ValidNKey)))
(*TBtCursor)(unsafe.Pointer(pCur)).Finfo.FnSize = uint16(0)
if libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCur)).FeState) != CURSOR_VALID || libc.Int32FromUint16((*TBtCursor)(unsafe.Pointer(pCur)).Fix) == 0 || libc.Int32FromUint8((*TMemPage)(unsafe.Pointer((*TBtCursor)(unsafe.Pointer(pCur)).FpPage)).Fleaf) == 0 {
return _btreePrevious(tls, pCur)
}
(*TBtCursor)(unsafe.Pointer(pCur)).Fix = (*TBtCursor)(unsafe.Pointer(pCur)).Fix - 1
return SQLITE_OK
}
// C documentation
//
// /*
// ** Argument pCsr must be a cursor opened for writing on an
// ** INTKEY table currently pointing at a valid table entry.
// ** This function modifies the data stored as part of that entry.
// **
// ** Only the data content may only be modified, it is not possible to
// ** change the length of the data stored. If this function is called with
// ** parameters that attempt to write past the end of the existing data,
// ** no modifications are made and SQLITE_CORRUPT is returned.
// */
func _sqlite3BtreePutData(tls *libc.TLS, pCsr uintptr, offset Tu32, amt Tu32, z uintptr) (r int32) {
var rc, v1 int32
_, _ = rc, v1
if libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCsr)).FeState) >= int32(CURSOR_REQUIRESEEK) {
v1 = _btreeRestoreCursorPosition(tls, pCsr)
} else {
v1 = SQLITE_OK
}
rc = v1
if rc != SQLITE_OK {
return rc
}
if libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCsr)).FeState) != CURSOR_VALID {
return int32(SQLITE_ABORT)
}
/* Save the positions of all other cursors open on this table. This is
** required in case any of them are holding references to an xFetch
** version of the b-tree page modified by the accessPayload call below.
**
** Note that pCsr must be open on a INTKEY table and saveCursorPosition()
** and hence saveAllCursors() cannot fail on a BTREE_INTKEY table, hence
** saveAllCursors can only return SQLITE_OK.
*/
_saveAllCursors(tls, (*TBtCursor)(unsafe.Pointer(pCsr)).FpBt, (*TBtCursor)(unsafe.Pointer(pCsr)).FpgnoRoot, pCsr)
/* Check some assumptions:
** (a) the cursor is open for writing,
** (b) there is a read/write transaction open,
** (c) the connection holds a write-lock on the table (if required),
** (d) there are no conflicting read-locks, and
** (e) the cursor points at a valid row of an intKey table.
*/
if libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(pCsr)).FcurFlags)&int32(BTCF_WriteFlag) == 0 {
return int32(SQLITE_READONLY)
}
return _accessPayload(tls, pCsr, offset, amt, z, int32(1))
}
// C documentation
//
// /*
// ** Rollback the transaction in progress.
// **
// ** If tripCode is not SQLITE_OK then cursors will be invalidated (tripped).
// ** Only write cursors are tripped if writeOnly is true but all cursors are
// ** tripped if writeOnly is false. Any attempt to use
// ** a tripped cursor will result in an error.
// **
// ** This will release the write lock on the database file. If there
// ** are no active cursors, it also releases the read lock.
// */
func _sqlite3BtreeRollback(tls *libc.TLS, p uintptr, tripCode int32, writeOnly int32) (r int32) {
bp := tls.Alloc(16)
defer tls.Free(16)
var pBt uintptr
var rc, rc2, rc21, v1 int32
var _ /* pPage1 at bp+0 */ uintptr
_, _, _, _, _ = pBt, rc, rc2, rc21, v1
pBt = (*TBtree)(unsafe.Pointer(p)).FpBt
_sqlite3BtreeEnter(tls, p)
if tripCode == SQLITE_OK {
v1 = _saveAllCursors(tls, pBt, uint32(0), uintptr(0))
tripCode = v1
rc = v1
if rc != 0 {
writeOnly = 0
}
} else {
rc = SQLITE_OK
}
if tripCode != 0 {
rc2 = _sqlite3BtreeTripAllCursors(tls, p, tripCode, writeOnly)
if rc2 != SQLITE_OK {
rc = rc2
}
}
if libc.Int32FromUint8((*TBtree)(unsafe.Pointer(p)).FinTrans) == int32(TRANS_WRITE) {
rc21 = _sqlite3PagerRollback(tls, (*TBtShared)(unsafe.Pointer(pBt)).FpPager)
if rc21 != SQLITE_OK {
rc = rc21
}
/* The rollback may have destroyed the pPage1->aData value. So
** call btreeGetPage() on page 1 again to make
** sure pPage1->aData is set correctly. */
if _btreeGetPage(tls, pBt, uint32(1), bp, 0) == SQLITE_OK {
_btreeSetNPage(tls, pBt, **(**uintptr)(__ccgo_up(bp)))
_releasePageOne(tls, **(**uintptr)(__ccgo_up(bp)))
}
(*TBtShared)(unsafe.Pointer(pBt)).FinTransaction = uint8(TRANS_READ)
_btreeClearHasContent(tls, pBt)
}
_btreeEndTransaction(tls, p)
_sqlite3BtreeLeave(tls, p)
return rc
}
// C documentation
//
// /*
// ** The second argument to this function, op, is always SAVEPOINT_ROLLBACK
// ** or SAVEPOINT_RELEASE. This function either releases or rolls back the
// ** savepoint identified by parameter iSavepoint, depending on the value
// ** of op.
// **
// ** Normally, iSavepoint is greater than or equal to zero. However, if op is
// ** SAVEPOINT_ROLLBACK, then iSavepoint may also be -1. In this case the
// ** contents of the entire transaction are rolled back. This is different
// ** from a normal transaction rollback, as no locks are released and the
// ** transaction remains open.
// */
func _sqlite3BtreeSavepoint(tls *libc.TLS, p uintptr, op int32, iSavepoint int32) (r int32) {
var pBt uintptr
var rc int32
_, _ = pBt, rc
rc = SQLITE_OK
if p != 0 && libc.Int32FromUint8((*TBtree)(unsafe.Pointer(p)).FinTrans) == int32(TRANS_WRITE) {
pBt = (*TBtree)(unsafe.Pointer(p)).FpBt
_sqlite3BtreeEnter(tls, p)
if op == int32(SAVEPOINT_ROLLBACK) {
rc = _saveAllCursors(tls, pBt, uint32(0), uintptr(0))
}
if rc == SQLITE_OK {
rc = _sqlite3PagerSavepoint(tls, (*TBtShared)(unsafe.Pointer(pBt)).FpPager, op, iSavepoint)
}
if rc == SQLITE_OK {
if iSavepoint < 0 && libc.Int32FromUint16((*TBtShared)(unsafe.Pointer(pBt)).FbtsFlags)&int32(BTS_INITIALLY_EMPTY) != 0 {
(*TBtShared)(unsafe.Pointer(pBt)).FnPage = uint32(0)
}
rc = _newDatabase(tls, pBt)
_btreeSetNPage(tls, pBt, (*TBtShared)(unsafe.Pointer(pBt)).FpPage1)
/* pBt->nPage might be zero if the database was corrupt when
** the transaction was started. Otherwise, it must be at least 1. */
}
_sqlite3BtreeLeave(tls, p)
}
return rc
}
// C documentation
//
// /*
// ** This function returns a pointer to a blob of memory associated with
// ** a single shared-btree. The memory is used by client code for its own
// ** purposes (for example, to store a high-level schema associated with
// ** the shared-btree). The btree layer manages reference counting issues.
// **
// ** The first time this is called on a shared-btree, nBytes bytes of memory
// ** are allocated, zeroed, and returned to the caller. For each subsequent
// ** call the nBytes parameter is ignored and a pointer to the same blob
// ** of memory returned.
// **
// ** If the nBytes parameter is 0 and the blob of memory has not yet been
// ** allocated, a null pointer is returned. If the blob has already been
// ** allocated, it is returned as normal.
// **
// ** Just before the shared-btree is closed, the function passed as the
// ** xFree argument when the memory allocation was made is invoked on the
// ** blob of allocated memory. The xFree function should not call sqlite3_free()
// ** on the memory, the btree layer does that.
// */
func _sqlite3BtreeSchema(tls *libc.TLS, p uintptr, nBytes int32, __ccgo_fp_xFree uintptr) (r uintptr) {
var pBt uintptr
_ = pBt
pBt = (*TBtree)(unsafe.Pointer(p)).FpBt
_sqlite3BtreeEnter(tls, p)
if !((*TBtShared)(unsafe.Pointer(pBt)).FpSchema != 0) && nBytes != 0 {
(*TBtShared)(unsafe.Pointer(pBt)).FpSchema = _sqlite3DbMallocZero(tls, uintptr(0), libc.Uint64FromInt32(nBytes))
(*TBtShared)(unsafe.Pointer(pBt)).FxFreeSchema = __ccgo_fp_xFree
}
_sqlite3BtreeLeave(tls, p)
return (*TBtShared)(unsafe.Pointer(pBt)).FpSchema
}
// C documentation
//
// /*
// ** Change the 'auto-vacuum' property of the database. If the 'autoVacuum'
// ** parameter is non-zero, then auto-vacuum mode is enabled. If zero, it
// ** is disabled. The default value for the auto-vacuum property is
// ** determined by the SQLITE_DEFAULT_AUTOVACUUM macro.
// */
func _sqlite3BtreeSetAutoVacuum(tls *libc.TLS, p uintptr, autoVacuum int32) (r int32) {
var av Tu8
var pBt uintptr
var rc, v1 int32
var v2 bool
_, _, _, _, _ = av, pBt, rc, v1, v2
pBt = (*TBtree)(unsafe.Pointer(p)).FpBt
rc = SQLITE_OK
av = libc.Uint8FromInt32(autoVacuum)
_sqlite3BtreeEnter(tls, p)
if v2 = libc.Int32FromUint16((*TBtShared)(unsafe.Pointer(pBt)).FbtsFlags)&int32(BTS_PAGESIZE_FIXED) != 0; v2 {
if av != 0 {
v1 = int32(1)
} else {
v1 = 0
}
}
if v2 && v1 != libc.Int32FromUint8((*TBtShared)(unsafe.Pointer(pBt)).FautoVacuum) {
rc = int32(SQLITE_READONLY)
} else {
if av != 0 {
v1 = int32(1)
} else {
v1 = 0
}
(*TBtShared)(unsafe.Pointer(pBt)).FautoVacuum = libc.Uint8FromInt32(v1)
if libc.Int32FromUint8(av) == int32(2) {
v1 = int32(1)
} else {
v1 = 0
}
(*TBtShared)(unsafe.Pointer(pBt)).FincrVacuum = libc.Uint8FromInt32(v1)
}
_sqlite3BtreeLeave(tls, p)
return rc
}
// C documentation
//
// /*
// ** Return true if the Btree passed as the only argument is sharable.
// */
func _sqlite3BtreeSharable(tls *libc.TLS, p uintptr) (r int32) {
return libc.Int32FromUint8((*TBtree)(unsafe.Pointer(p)).Fsharable)
}
// C documentation
//
// /*
// ** This routine sets the state to CURSOR_FAULT and the error
// ** code to errCode for every cursor on any BtShared that pBtree
// ** references. Or if the writeOnly flag is set to 1, then only
// ** trip write cursors and leave read cursors unchanged.
// **
// ** Every cursor is a candidate to be tripped, including cursors
// ** that belong to other database connections that happen to be
// ** sharing the cache with pBtree.
// **
// ** This routine gets called when a rollback occurs. If the writeOnly
// ** flag is true, then only write-cursors need be tripped - read-only
// ** cursors save their current positions so that they may continue
// ** following the rollback. Or, if writeOnly is false, all cursors are
// ** tripped. In general, writeOnly is false if the transaction being
// ** rolled back modified the database schema. In this case b-tree root
// ** pages may be moved or deleted from the database altogether, making
// ** it unsafe for read cursors to continue.
// **
// ** If the writeOnly flag is true and an error is encountered while
// ** saving the current position of a read-only cursor, all cursors,
// ** including all read-cursors are tripped.
// **
// ** SQLITE_OK is returned if successful, or if an error occurs while
// ** saving a cursor position, an SQLite error code.
// */
func _sqlite3BtreeTripAllCursors(tls *libc.TLS, pBtree uintptr, errCode int32, writeOnly int32) (r int32) {
var p uintptr
var rc int32
_, _ = p, rc
rc = SQLITE_OK
if pBtree != 0 {
_sqlite3BtreeEnter(tls, pBtree)
p = (*TBtShared)(unsafe.Pointer((*TBtree)(unsafe.Pointer(pBtree)).FpBt)).FpCursor
for {
if !(p != 0) {
break
}
if writeOnly != 0 && libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(p)).FcurFlags)&int32(BTCF_WriteFlag) == 0 {
if libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(p)).FeState) == CURSOR_VALID || libc.Int32FromUint8((*TBtCursor)(unsafe.Pointer(p)).FeState) == int32(CURSOR_SKIPNEXT) {
rc = _saveCursorPosition(tls, p)
if rc != SQLITE_OK {
_sqlite3BtreeTripAllCursors(tls, pBtree, rc, 0)
break
}
}
} else {
_sqlite3BtreeClearCursor(tls, p)
(*TBtCursor)(unsafe.Pointer(p)).FeState = uint8(CURSOR_FAULT)
(*TBtCursor)(unsafe.Pointer(p)).FskipNext = errCode
}
_btreeReleaseAllCursorPages(tls, p)
goto _1
_1:
;
p = (*TBtCursor)(unsafe.Pointer(p)).FpNext
}
_sqlite3BtreeLeave(tls, pBtree)
}
return rc
}
// C documentation
//
// /*
// ** Return one of SQLITE_TXN_NONE, SQLITE_TXN_READ, or SQLITE_TXN_WRITE
// ** to describe the current transaction state of Btree p.
// */
func _sqlite3BtreeTxnState(tls *libc.TLS, p uintptr) (r int32) {
var v1 int32
_ = v1
if p != 0 {
v1 = libc.Int32FromUint8((*TBtree)(unsafe.Pointer(p)).FinTrans)
} else {
v1 = 0
}
return v1
}
// C documentation
//
// /*
// ** This is called to code the required FOR EACH ROW triggers for an operation
// ** on table pTab. The operation to code triggers for (INSERT, UPDATE or DELETE)
// ** is given by the op parameter. The tr_tm parameter determines whether the
// ** BEFORE or AFTER triggers are coded. If the operation is an UPDATE, then
// ** parameter pChanges is passed the list of columns being modified.
// **
// ** If there are no triggers that fire at the specified time for the specified
// ** operation on pTab, this function is a no-op.
// **
// ** The reg argument is the address of the first in an array of registers
// ** that contain the values substituted for the new.* and old.* references
// ** in the trigger program. If N is the number of columns in table pTab
// ** (a copy of pTab->nCol), then registers are populated as follows:
// **
// ** Register Contains
// ** ------------------------------------------------------
// ** reg+0 OLD.rowid
// ** reg+1 OLD.* value of left-most column of pTab
// ** ... ...
// ** reg+N OLD.* value of right-most column of pTab
// ** reg+N+1 NEW.rowid
// ** reg+N+2 NEW.* value of left-most column of pTab
// ** ... ...
// ** reg+N+N+1 NEW.* value of right-most column of pTab
// **
// ** For ON DELETE triggers, the registers containing the NEW.* values will
// ** never be accessed by the trigger program, so they are not allocated or
// ** populated by the caller (there is no data to populate them with anyway).
// ** Similarly, for ON INSERT triggers the values stored in the OLD.* registers
// ** are never accessed, and so are not allocated by the caller. So, for an
// ** ON INSERT trigger, the value passed to this function as parameter reg
// ** is not a readable register, although registers (reg+N) through
// ** (reg+N+N+1) are.
// **
// ** Parameter orconf is the default conflict resolution algorithm for the
// ** trigger program to use (REPLACE, IGNORE etc.). Parameter ignoreJump
// ** is the instruction that control should jump to if a trigger program
// ** raises an IGNORE exception.
// */
func _sqlite3CodeRowTrigger(tls *libc.TLS, pParse uintptr, pTrigger uintptr, op int32, pChanges uintptr, tr_tm int32, pTab uintptr, reg int32, orconf int32, ignoreJump int32) {
var p uintptr
_ = p /* Used to iterate through pTrigger list */
p = pTrigger
for {
if !(p != 0) {
break
}
/* Sanity checking: The schema for the trigger and for the table are
** always defined. The trigger must be in the same schema as the table
** or else it must be a TEMP trigger. */
/* Determine whether we should code this trigger. One of two choices:
** 1. The trigger is an exact match to the current DML statement
** 2. This is a RETURNING trigger for INSERT but we are currently
** doing the UPDATE part of an UPSERT.
*/
if (libc.Int32FromUint8((*TTrigger)(unsafe.Pointer(p)).Fop) == op || (*TTrigger)(unsafe.Pointer(p)).FbReturning != 0 && libc.Int32FromUint8((*TTrigger)(unsafe.Pointer(p)).Fop) == int32(TK_INSERT) && op == int32(TK_UPDATE)) && libc.Int32FromUint8((*TTrigger)(unsafe.Pointer(p)).Ftr_tm) == tr_tm && _checkColumnOverlap(tls, (*TTrigger)(unsafe.Pointer(p)).FpColumns, pChanges) != 0 {
if !((*TTrigger)(unsafe.Pointer(p)).FbReturning != 0) {
_sqlite3CodeRowTriggerDirect(tls, pParse, p, pTab, reg, orconf, ignoreJump)
} else {
if (*TParse)(unsafe.Pointer(pParse)).FpToplevel == uintptr(0) {
_codeReturningTrigger(tls, pParse, p, pTab, reg)
}
}
}
goto _1
_1:
;
p = (*TTrigger)(unsafe.Pointer(p)).FpNext
}
}
// C documentation
//
// /*
// ** Allocate a new expression node from a zero-terminated token that has
// ** already been dequoted.
// */
func _sqlite3Expr(tls *libc.TLS, db uintptr, op int32, zToken uintptr) (r uintptr) {
bp := tls.Alloc(16)
defer tls.Free(16)
var _ /* x at bp+0 */ TToken
(**(**TToken)(__ccgo_up(bp))).Fz = zToken
(**(**TToken)(__ccgo_up(bp))).Fn = libc.Uint32FromInt32(_sqlite3Strlen30(tls, zToken))
return _sqlite3ExprAlloc(tls, db, op, bp, 0)
}
// C documentation
//
// /*
// ** Set the collating sequence for expression pExpr to be the collating
// ** sequence named by pToken. Return a pointer to a new Expr node that
// ** implements the COLLATE operator.
// **
// ** If a memory allocation error occurs, that fact is recorded in pParse->db
// ** and the pExpr parameter is returned unchanged.
// */
func _sqlite3ExprAddCollateToken(tls *libc.TLS, pParse uintptr, pExpr uintptr, pCollName uintptr, dequote int32) (r uintptr) {
var pNew uintptr
_ = pNew
if (*TToken)(unsafe.Pointer(pCollName)).Fn > uint32(0) {
pNew = _sqlite3ExprAlloc(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, int32(TK_COLLATE), pCollName, dequote)
if pNew != 0 {
(*TExpr)(unsafe.Pointer(pNew)).FpLeft = pExpr
**(**Tu32)(__ccgo_up(pNew + 4)) |= libc.Uint32FromInt32(libc.Int32FromInt32(EP_Collate) | libc.Int32FromInt32(EP_Skip))
pExpr = pNew
}
}
return pExpr
}
// C documentation
//
// /*
// ** Join two expressions using an AND operator. If either expression is
// ** NULL, then just return the other expression.
// **
// ** If one side or the other of the AND is known to be false, and neither side
// ** is part of an ON clause, then instead of returning an AND expression,
// ** just return a constant expression with a value of false.
// */
func _sqlite3ExprAnd(tls *libc.TLS, pParse uintptr, pLeft uintptr, pRight uintptr) (r uintptr) {
var db uintptr
var f Tu32
_, _ = db, f
db = (*TParse)(unsafe.Pointer(pParse)).Fdb
if pLeft == uintptr(0) {
return pRight
} else {
if pRight == uintptr(0) {
return pLeft
} else {
f = (*TExpr)(unsafe.Pointer(pLeft)).Fflags | (*TExpr)(unsafe.Pointer(pRight)).Fflags
if f&libc.Uint32FromInt32(libc.Int32FromInt32(EP_OuterON)|libc.Int32FromInt32(EP_InnerON)|libc.Int32FromInt32(EP_IsFalse)|libc.Int32FromInt32(EP_HasFunc)) == uint32(EP_IsFalse) && !(libc.Int32FromUint8((*TParse)(unsafe.Pointer(pParse)).FeParseMode) >= libc.Int32FromInt32(PARSE_MODE_RENAME)) {
_sqlite3ExprDeferredDelete(tls, pParse, pLeft)
_sqlite3ExprDeferredDelete(tls, pParse, pRight)
return _sqlite3ExprInt32(tls, db, 0)
} else {
return _sqlite3PExpr(tls, pParse, int32(TK_AND), pLeft, pRight)
}
}
}
return r
}
// C documentation
//
// /*
// ** Attach subtrees pLeft and pRight to the Expr node pRoot.
// **
// ** If pRoot==NULL that means that a memory allocation error has occurred.
// ** In that case, delete the subtrees pLeft and pRight.
// */
func _sqlite3ExprAttachSubtrees(tls *libc.TLS, db uintptr, pRoot uintptr, pLeft uintptr, pRight uintptr) {
if pRoot == uintptr(0) {
_sqlite3ExprDelete(tls, db, pLeft)
_sqlite3ExprDelete(tls, db, pRight)
} else {
if pRight != 0 {
(*TExpr)(unsafe.Pointer(pRoot)).FpRight = pRight
**(**Tu32)(__ccgo_up(pRoot + 4)) |= libc.Uint32FromInt32(libc.Int32FromInt32(EP_Collate)|libc.Int32FromInt32(EP_Subquery)|libc.Int32FromInt32(EP_HasFunc)) & (*TExpr)(unsafe.Pointer(pRight)).Fflags
(*TExpr)(unsafe.Pointer(pRoot)).FnHeight = (*TExpr)(unsafe.Pointer(pRight)).FnHeight + int32(1)
} else {
(*TExpr)(unsafe.Pointer(pRoot)).FnHeight = int32(1)
}
if pLeft != 0 {
(*TExpr)(unsafe.Pointer(pRoot)).FpLeft = pLeft
**(**Tu32)(__ccgo_up(pRoot + 4)) |= libc.Uint32FromInt32(libc.Int32FromInt32(EP_Collate)|libc.Int32FromInt32(EP_Subquery)|libc.Int32FromInt32(EP_HasFunc)) & (*TExpr)(unsafe.Pointer(pLeft)).Fflags
if (*TExpr)(unsafe.Pointer(pLeft)).FnHeight >= (*TExpr)(unsafe.Pointer(pRoot)).FnHeight {
(*TExpr)(unsafe.Pointer(pRoot)).FnHeight = (*TExpr)(unsafe.Pointer(pLeft)).FnHeight + int32(1)
}
}
}
}
// 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.
// */
func _sqlite3ExprCode(tls *libc.TLS, pParse uintptr, pExpr uintptr, target int32) {
var inReg int32
var op Tu8
var pX uintptr
_, _, _ = inReg, op, pX
if (*TParse)(unsafe.Pointer(pParse)).FpVdbe == uintptr(0) {
return
}
inReg = _sqlite3ExprCodeTarget(tls, pParse, pExpr, target)
if inReg != target {
pX = _sqlite3ExprSkipCollateAndLikely(tls, pExpr)
if pX != 0 && ((*TExpr)(unsafe.Pointer(pX)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_Subquery)) != uint32(0) || libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pX)).Fop) == int32(TK_REGISTER)) {
op = uint8(OP_Copy)
} else {
op = uint8(OP_SCopy)
}
_sqlite3VdbeAddOp2(tls, (*TParse)(unsafe.Pointer(pParse)).FpVdbe, libc.Int32FromUint8(op), inReg, target)
}
}
// C documentation
//
// /*
// ** Generate code that will extract the iColumn-th column from
// ** table pTab and store the column value in register iReg.
// **
// ** There must be an open cursor to pTab in iTable when this routine
// ** is called. If iColumn<0 then code is generated that extracts the rowid.
// */
func _sqlite3ExprCodeGetColumn(tls *libc.TLS, pParse uintptr, pTab uintptr, iColumn int32, iTable int32, iReg int32, p5 Tu8) (r int32) {
var pOp uintptr
_ = pOp
_sqlite3ExprCodeGetColumnOfTable(tls, (*TParse)(unsafe.Pointer(pParse)).FpVdbe, pTab, iTable, iColumn, iReg)
if p5 != 0 {
pOp = _sqlite3VdbeGetLastOp(tls, (*TParse)(unsafe.Pointer(pParse)).FpVdbe)
if libc.Int32FromUint8((*TVdbeOp)(unsafe.Pointer(pOp)).Fopcode) == int32(OP_Column) {
(*TVdbeOp)(unsafe.Pointer(pOp)).Fp5 = uint16(p5)
}
if libc.Int32FromUint8((*TVdbeOp)(unsafe.Pointer(pOp)).Fopcode) == int32(OP_VColumn) {
(*TVdbeOp)(unsafe.Pointer(pOp)).Fp5 = libc.Uint16FromInt32(libc.Int32FromUint8(p5) & libc.Int32FromInt32(OPFLAG_NOCHNG))
}
}
return iReg
}
// C documentation
//
// /* Expression p is a comparison operator. Return a collation sequence
// ** appropriate for the comparison operator.
// **
// ** This is normally just a wrapper around sqlite3BinaryCompareCollSeq().
// ** However, if the OP_Commuted flag is set, then the order of the operands
// ** is reversed in the sqlite3BinaryCompareCollSeq() call so that the
// ** correct collating sequence is found.
// */
func _sqlite3ExprCompareCollSeq(tls *libc.TLS, pParse uintptr, p uintptr) (r uintptr) {
if (*TExpr)(unsafe.Pointer(p)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_Commuted)) != uint32(0) {
return _sqlite3BinaryCompareCollSeq(tls, pParse, (*TExpr)(unsafe.Pointer(p)).FpRight, (*TExpr)(unsafe.Pointer(p)).FpLeft)
} else {
return _sqlite3BinaryCompareCollSeq(tls, pParse, (*TExpr)(unsafe.Pointer(p)).FpLeft, (*TExpr)(unsafe.Pointer(p)).FpRight)
}
return r
}
// C documentation
//
// /*
// ** If the input expression is an ID with the name "true" or "false"
// ** then convert it into an TK_TRUEFALSE term. Return non-zero if
// ** the conversion happened, and zero if the expression is unaltered.
// */
func _sqlite3ExprIdToTrueFalse(tls *libc.TLS, pExpr uintptr) (r int32) {
var v, v1 Tu32
var v2 bool
_, _, _ = v, v1, v2
if v2 = !((*TExpr)(unsafe.Pointer(pExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_Quoted)|libc.Int32FromInt32(EP_IntValue)) != libc.Uint32FromInt32(0)); v2 {
v1 = _sqlite3IsTrueOrFalse(tls, *(*uintptr)(unsafe.Pointer(pExpr + 8)))
v = v1
}
if v2 && v1 != uint32(0) {
(*TExpr)(unsafe.Pointer(pExpr)).Fop = uint8(TK_TRUEFALSE)
**(**Tu32)(__ccgo_up(pExpr + 4)) |= v
return int32(1)
}
return 0
}
// C documentation
//
// /*
// ** Generate code for a boolean expression such that a jump is made
// ** to the label "dest" if the expression is false but execution
// ** continues straight thru if the expression is true.
// **
// ** If the expression evaluates to NULL (neither true nor false) then
// ** jump if jumpIfNull is SQLITE_JUMPIFNULL or fall through if jumpIfNull
// ** is 0.
// */
func _sqlite3ExprIfFalse(tls *libc.TLS, pParse uintptr, pExpr uintptr, dest int32, jumpIfNull int32) {
bp := tls.Alloc(16)
defer tls.Free(16)
var addrIsNull, d2, destIfNull, isNot, isTrue, op, v19 int32
var pAlt, pFirst, pSecond, v uintptr
var _ /* r1 at bp+8 */ int32
var _ /* r2 at bp+12 */ int32
var _ /* regFree1 at bp+0 */ int32
var _ /* regFree2 at bp+4 */ int32
_, _, _, _, _, _, _, _, _, _, _ = addrIsNull, d2, destIfNull, isNot, isTrue, op, pAlt, pFirst, pSecond, v, v19
v = (*TParse)(unsafe.Pointer(pParse)).FpVdbe
op = 0
**(**int32)(__ccgo_up(bp)) = 0
**(**int32)(__ccgo_up(bp + 4)) = 0
if v == uintptr(0) {
return
} /* Existence of VDBE checked by caller */
if pExpr == uintptr(0) {
return
}
/* The value of pExpr->op and op are related as follows:
**
** pExpr->op op
** --------- ----------
** TK_ISNULL OP_NotNull
** TK_NOTNULL OP_IsNull
** TK_NE OP_Eq
** TK_EQ OP_Ne
** TK_GT OP_Le
** TK_LE OP_Gt
** TK_GE OP_Lt
** TK_LT OP_Ge
**
** For other values of pExpr->op, op is undefined and unused.
** The value of TK_ and OP_ constants are arranged such that we
** can compute the mapping above using the following expression.
** Assert()s verify that the computation is correct.
*/
op = libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) + libc.Int32FromInt32(TK_ISNULL)&libc.Int32FromInt32(1) ^ int32(1) - libc.Int32FromInt32(TK_ISNULL)&libc.Int32FromInt32(1)
/* Verify correct alignment of TK_ and OP_ constants
*/
switch libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) {
case int32(TK_OR):
goto _1
case int32(TK_AND):
goto _2
case int32(TK_NOT):
goto _3
case int32(TK_TRUTH):
goto _4
case int32(TK_ISNOT):
goto _5
case int32(TK_IS):
goto _6
case int32(TK_EQ):
goto _7
case int32(TK_NE):
goto _8
case int32(TK_GE):
goto _9
case int32(TK_GT):
goto _10
case int32(TK_LE):
goto _11
case int32(TK_LT):
goto _12
case int32(TK_NOTNULL):
goto _13
case int32(TK_ISNULL):
goto _14
case int32(TK_BETWEEN):
goto _15
case int32(TK_IN):
goto _16
default:
goto _17
}
goto _18
_2:
;
_1:
;
pAlt = _sqlite3ExprSimplifiedAndOr(tls, pExpr)
if pAlt != pExpr {
_sqlite3ExprIfFalse(tls, pParse, pAlt, dest, jumpIfNull)
} else {
if _exprEvalRhsFirst(tls, pExpr) != 0 {
pFirst = (*TExpr)(unsafe.Pointer(pExpr)).FpRight
pSecond = (*TExpr)(unsafe.Pointer(pExpr)).FpLeft
} else {
pFirst = (*TExpr)(unsafe.Pointer(pExpr)).FpLeft
pSecond = (*TExpr)(unsafe.Pointer(pExpr)).FpRight
}
if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) == int32(TK_AND) {
_sqlite3ExprIfFalse(tls, pParse, pFirst, dest, jumpIfNull)
_sqlite3ExprIfFalse(tls, pParse, pSecond, dest, jumpIfNull)
} else {
d2 = _sqlite3VdbeMakeLabel(tls, pParse)
_sqlite3ExprIfTrue(tls, pParse, pFirst, d2, jumpIfNull^int32(SQLITE_JUMPIFNULL))
_sqlite3ExprIfFalse(tls, pParse, pSecond, dest, jumpIfNull)
_sqlite3VdbeResolveLabel(tls, v, d2)
}
}
goto _18
_3:
;
_sqlite3ExprIfTrue(tls, pParse, (*TExpr)(unsafe.Pointer(pExpr)).FpLeft, dest, jumpIfNull)
goto _18
_4:
; /* IS TRUE or IS NOT TRUE */
isNot = libc.BoolInt32(libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop2) == int32(TK_ISNOT))
isTrue = _sqlite3ExprTruthValue(tls, (*TExpr)(unsafe.Pointer(pExpr)).FpRight)
if isTrue^isNot != 0 {
/* IS TRUE and IS NOT FALSE */
if isNot != 0 {
v19 = 0
} else {
v19 = int32(SQLITE_JUMPIFNULL)
}
_sqlite3ExprIfFalse(tls, pParse, (*TExpr)(unsafe.Pointer(pExpr)).FpLeft, dest, v19)
} else {
/* IS FALSE and IS NOT TRUE */
if isNot != 0 {
v19 = 0
} else {
v19 = int32(SQLITE_JUMPIFNULL)
}
_sqlite3ExprIfTrue(tls, pParse, (*TExpr)(unsafe.Pointer(pExpr)).FpLeft, dest, v19)
}
goto _18
_6:
;
_5:
;
if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) == int32(TK_IS) {
v19 = int32(TK_NE)
} else {
v19 = int32(TK_EQ)
}
op = v19
jumpIfNull = int32(SQLITE_NULLEQ)
_12:
;
_11:
;
_10:
;
_9:
;
_8:
;
_7:
;
if _sqlite3ExprIsVector(tls, (*TExpr)(unsafe.Pointer(pExpr)).FpLeft) != 0 {
goto default_expr
}
if (*TExpr)(unsafe.Pointer(pExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_Subquery)) != uint32(0) && jumpIfNull != int32(SQLITE_NULLEQ) {
addrIsNull = _exprComputeOperands(tls, pParse, pExpr, bp+8, bp+12, bp, bp+4)
} else {
**(**int32)(__ccgo_up(bp + 8)) = _sqlite3ExprCodeTemp(tls, pParse, (*TExpr)(unsafe.Pointer(pExpr)).FpLeft, bp)
**(**int32)(__ccgo_up(bp + 12)) = _sqlite3ExprCodeTemp(tls, pParse, (*TExpr)(unsafe.Pointer(pExpr)).FpRight, bp+4)
addrIsNull = 0
}
_codeCompare(tls, pParse, (*TExpr)(unsafe.Pointer(pExpr)).FpLeft, (*TExpr)(unsafe.Pointer(pExpr)).FpRight, op, **(**int32)(__ccgo_up(bp + 8)), **(**int32)(__ccgo_up(bp + 12)), dest, jumpIfNull, libc.BoolInt32((*TExpr)(unsafe.Pointer(pExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_Commuted)) != uint32(0)))
if addrIsNull != 0 {
if jumpIfNull != 0 {
_sqlite3VdbeChangeP2(tls, v, addrIsNull, dest)
} else {
_sqlite3VdbeJumpHere(tls, v, addrIsNull)
}
}
goto _18
_14:
;
_13:
;
**(**int32)(__ccgo_up(bp + 8)) = _sqlite3ExprCodeTemp(tls, pParse, (*TExpr)(unsafe.Pointer(pExpr)).FpLeft, bp)
if **(**int32)(__ccgo_up(bp)) != 0 {
_sqlite3VdbeTypeofColumn(tls, v, **(**int32)(__ccgo_up(bp + 8)))
}
_sqlite3VdbeAddOp2(tls, v, op, **(**int32)(__ccgo_up(bp + 8)), dest)
goto _18
_15:
;
_exprCodeBetween(tls, pParse, pExpr, dest, __ccgo_fp(_sqlite3ExprIfFalse), jumpIfNull)
goto _18
_16:
;
if jumpIfNull != 0 {
_sqlite3ExprCodeIN(tls, pParse, pExpr, dest, dest)
} else {
destIfNull = _sqlite3VdbeMakeLabel(tls, pParse)
_sqlite3ExprCodeIN(tls, pParse, pExpr, dest, destIfNull)
_sqlite3VdbeResolveLabel(tls, v, destIfNull)
}
goto _18
_17:
;
goto default_expr
default_expr:
;
if (*TExpr)(unsafe.Pointer(pExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_OuterON)|libc.Int32FromInt32(EP_IsFalse)) == uint32(EP_IsFalse) {
_sqlite3VdbeGoto(tls, v, dest)
} else {
if (*TExpr)(unsafe.Pointer(pExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_OuterON)|libc.Int32FromInt32(EP_IsTrue)) == uint32(EP_IsTrue) {
/* no-op */
} else {
**(**int32)(__ccgo_up(bp + 8)) = _sqlite3ExprCodeTemp(tls, pParse, pExpr, bp)
_sqlite3VdbeAddOp3(tls, v, int32(OP_IfNot), **(**int32)(__ccgo_up(bp + 8)), dest, libc.BoolInt32(jumpIfNull != 0))
}
}
goto _18
_18:
;
_sqlite3ReleaseTempReg(tls, pParse, **(**int32)(__ccgo_up(bp)))
_sqlite3ReleaseTempReg(tls, pParse, **(**int32)(__ccgo_up(bp + 4)))
}
// C documentation
//
// /*
// ** Like sqlite3ExprIfFalse() except that a copy is made of pExpr before
// ** code generation, and that copy is deleted after code generation. This
// ** ensures that the original pExpr is unchanged.
// */
func _sqlite3ExprIfFalseDup(tls *libc.TLS, pParse uintptr, pExpr uintptr, dest int32, jumpIfNull int32) {
var db, pCopy uintptr
_, _ = db, pCopy
db = (*TParse)(unsafe.Pointer(pParse)).Fdb
pCopy = _sqlite3ExprDup(tls, db, pExpr, 0)
if libc.Int32FromUint8((*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed) == 0 {
_sqlite3ExprIfFalse(tls, pParse, pCopy, dest, jumpIfNull)
}
_sqlite3ExprDelete(tls, db, pCopy)
}
// C documentation
//
// /*
// ** Generate code for a boolean expression such that a jump is made
// ** to the label "dest" if the expression is true but execution
// ** continues straight thru if the expression is false.
// **
// ** If the expression evaluates to NULL (neither true nor false), then
// ** take the jump if the jumpIfNull flag is SQLITE_JUMPIFNULL.
// **
// ** This code depends on the fact that certain token values (ex: TK_EQ)
// ** are the same as opcode values (ex: OP_Eq) that implement the corresponding
// ** operation. Special comments in vdbe.c and the mkopcodeh.awk script in
// ** the make process cause these values to align. Assert()s in the code
// ** below verify that the numbers are aligned correctly.
// */
func _sqlite3ExprIfTrue(tls *libc.TLS, pParse uintptr, pExpr uintptr, dest int32, jumpIfNull int32) {
bp := tls.Alloc(16)
defer tls.Free(16)
var addrIsNull, d2, destIfFalse, destIfNull, isNot, isTrue, op, v19 int32
var pAlt, pFirst, pSecond, v uintptr
var _ /* r1 at bp+8 */ int32
var _ /* r2 at bp+12 */ int32
var _ /* regFree1 at bp+0 */ int32
var _ /* regFree2 at bp+4 */ int32
_, _, _, _, _, _, _, _, _, _, _, _ = addrIsNull, d2, destIfFalse, destIfNull, isNot, isTrue, op, pAlt, pFirst, pSecond, v, v19
v = (*TParse)(unsafe.Pointer(pParse)).FpVdbe
op = 0
**(**int32)(__ccgo_up(bp)) = 0
**(**int32)(__ccgo_up(bp + 4)) = 0
if v == uintptr(0) {
return
} /* Existence of VDBE checked by caller */
if pExpr == uintptr(0) {
return
} /* No way this can happen */
op = libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop)
switch op {
case int32(TK_OR):
goto _1
case int32(TK_AND):
goto _2
case int32(TK_NOT):
goto _3
case int32(TK_TRUTH):
goto _4
case int32(TK_ISNOT):
goto _5
case int32(TK_IS):
goto _6
case int32(TK_EQ):
goto _7
case int32(TK_NE):
goto _8
case int32(TK_GE):
goto _9
case int32(TK_GT):
goto _10
case int32(TK_LE):
goto _11
case int32(TK_LT):
goto _12
case int32(TK_NOTNULL):
goto _13
case int32(TK_ISNULL):
goto _14
case int32(TK_BETWEEN):
goto _15
case int32(TK_IN):
goto _16
default:
goto _17
}
goto _18
_2:
;
_1:
;
pAlt = _sqlite3ExprSimplifiedAndOr(tls, pExpr)
if pAlt != pExpr {
_sqlite3ExprIfTrue(tls, pParse, pAlt, dest, jumpIfNull)
} else {
if _exprEvalRhsFirst(tls, pExpr) != 0 {
pFirst = (*TExpr)(unsafe.Pointer(pExpr)).FpRight
pSecond = (*TExpr)(unsafe.Pointer(pExpr)).FpLeft
} else {
pFirst = (*TExpr)(unsafe.Pointer(pExpr)).FpLeft
pSecond = (*TExpr)(unsafe.Pointer(pExpr)).FpRight
}
if op == int32(TK_AND) {
d2 = _sqlite3VdbeMakeLabel(tls, pParse)
_sqlite3ExprIfFalse(tls, pParse, pFirst, d2, jumpIfNull^int32(SQLITE_JUMPIFNULL))
_sqlite3ExprIfTrue(tls, pParse, pSecond, dest, jumpIfNull)
_sqlite3VdbeResolveLabel(tls, v, d2)
} else {
_sqlite3ExprIfTrue(tls, pParse, pFirst, dest, jumpIfNull)
_sqlite3ExprIfTrue(tls, pParse, pSecond, dest, jumpIfNull)
}
}
goto _18
_3:
;
_sqlite3ExprIfFalse(tls, pParse, (*TExpr)(unsafe.Pointer(pExpr)).FpLeft, dest, jumpIfNull)
goto _18
_4:
; /* IS TRUE or IS NOT TRUE */
isNot = libc.BoolInt32(libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop2) == int32(TK_ISNOT))
isTrue = _sqlite3ExprTruthValue(tls, (*TExpr)(unsafe.Pointer(pExpr)).FpRight)
if isTrue^isNot != 0 {
if isNot != 0 {
v19 = int32(SQLITE_JUMPIFNULL)
} else {
v19 = 0
}
_sqlite3ExprIfTrue(tls, pParse, (*TExpr)(unsafe.Pointer(pExpr)).FpLeft, dest, v19)
} else {
if isNot != 0 {
v19 = int32(SQLITE_JUMPIFNULL)
} else {
v19 = 0
}
_sqlite3ExprIfFalse(tls, pParse, (*TExpr)(unsafe.Pointer(pExpr)).FpLeft, dest, v19)
}
goto _18
_6:
;
_5:
;
if op == int32(TK_IS) {
v19 = int32(TK_EQ)
} else {
v19 = int32(TK_NE)
}
op = v19
jumpIfNull = int32(SQLITE_NULLEQ)
_12:
;
_11:
;
_10:
;
_9:
;
_8:
;
_7:
;
if _sqlite3ExprIsVector(tls, (*TExpr)(unsafe.Pointer(pExpr)).FpLeft) != 0 {
goto default_expr
}
if (*TExpr)(unsafe.Pointer(pExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_Subquery)) != uint32(0) && jumpIfNull != int32(SQLITE_NULLEQ) {
addrIsNull = _exprComputeOperands(tls, pParse, pExpr, bp+8, bp+12, bp, bp+4)
} else {
**(**int32)(__ccgo_up(bp + 8)) = _sqlite3ExprCodeTemp(tls, pParse, (*TExpr)(unsafe.Pointer(pExpr)).FpLeft, bp)
**(**int32)(__ccgo_up(bp + 12)) = _sqlite3ExprCodeTemp(tls, pParse, (*TExpr)(unsafe.Pointer(pExpr)).FpRight, bp+4)
addrIsNull = 0
}
_codeCompare(tls, pParse, (*TExpr)(unsafe.Pointer(pExpr)).FpLeft, (*TExpr)(unsafe.Pointer(pExpr)).FpRight, op, **(**int32)(__ccgo_up(bp + 8)), **(**int32)(__ccgo_up(bp + 12)), dest, jumpIfNull, libc.BoolInt32((*TExpr)(unsafe.Pointer(pExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_Commuted)) != uint32(0)))
if addrIsNull != 0 {
if jumpIfNull != 0 {
_sqlite3VdbeChangeP2(tls, v, addrIsNull, dest)
} else {
_sqlite3VdbeJumpHere(tls, v, addrIsNull)
}
}
goto _18
_14:
;
_13:
;
**(**int32)(__ccgo_up(bp + 8)) = _sqlite3ExprCodeTemp(tls, pParse, (*TExpr)(unsafe.Pointer(pExpr)).FpLeft, bp)
if **(**int32)(__ccgo_up(bp)) != 0 {
_sqlite3VdbeTypeofColumn(tls, v, **(**int32)(__ccgo_up(bp + 8)))
}
_sqlite3VdbeAddOp2(tls, v, op, **(**int32)(__ccgo_up(bp + 8)), dest)
goto _18
_15:
;
_exprCodeBetween(tls, pParse, pExpr, dest, __ccgo_fp(_sqlite3ExprIfTrue), jumpIfNull)
goto _18
_16:
;
destIfFalse = _sqlite3VdbeMakeLabel(tls, pParse)
if jumpIfNull != 0 {
v19 = dest
} else {
v19 = destIfFalse
}
destIfNull = v19
_sqlite3ExprCodeIN(tls, pParse, pExpr, destIfFalse, destIfNull)
_sqlite3VdbeGoto(tls, v, dest)
_sqlite3VdbeResolveLabel(tls, v, destIfFalse)
goto _18
_17:
;
goto default_expr
default_expr:
;
if (*TExpr)(unsafe.Pointer(pExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_OuterON)|libc.Int32FromInt32(EP_IsTrue)) == uint32(EP_IsTrue) {
_sqlite3VdbeGoto(tls, v, dest)
} else {
if (*TExpr)(unsafe.Pointer(pExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_OuterON)|libc.Int32FromInt32(EP_IsFalse)) == uint32(EP_IsFalse) {
/* No-op */
} else {
**(**int32)(__ccgo_up(bp + 8)) = _sqlite3ExprCodeTemp(tls, pParse, pExpr, bp)
_sqlite3VdbeAddOp3(tls, v, int32(OP_If), **(**int32)(__ccgo_up(bp + 8)), dest, libc.BoolInt32(jumpIfNull != 0))
}
}
goto _18
_18:
;
_sqlite3ReleaseTempReg(tls, pParse, **(**int32)(__ccgo_up(bp)))
_sqlite3ReleaseTempReg(tls, pParse, **(**int32)(__ccgo_up(bp + 4)))
}
// C documentation
//
// /*
// ** Walk an expression tree for the DEFAULT field of a column definition
// ** in a CREATE TABLE statement. Return non-zero if the expression is
// ** acceptable for use as a DEFAULT. That is to say, return non-zero if
// ** the expression is constant or a function call with constant arguments.
// ** Return and 0 if there are any variables.
// **
// ** isInit is true when parsing from sqlite_schema. isInit is false when
// ** processing a new CREATE TABLE statement. When isInit is true, parameters
// ** (such as ? or $abc) in the expression are converted into NULL. When
// ** isInit is false, parameters raise an error. Parameters should not be
// ** allowed in a CREATE TABLE statement, but some legacy versions of SQLite
// ** allowed it, so we need to support it when reading sqlite_schema for
// ** backwards compatibility.
// **
// ** If isInit is true, set EP_FromDDL on every TK_FUNCTION node.
// **
// ** For the purposes of this function, a double-quoted string (ex: "abc")
// ** is considered a variable but a single-quoted string (ex: 'abc') is
// ** a constant.
// */
func _sqlite3ExprIsConstantOrFunction(tls *libc.TLS, p uintptr, isInit Tu8) (r int32) {
return _exprIsConst(tls, uintptr(0), p, int32(4)+libc.Int32FromUint8(isInit))
}
// C documentation
//
// /*
// ** Return true if the boolean value of the expression is always either
// ** FALSE or NULL.
// */
func _sqlite3ExprIsNotTrue(tls *libc.TLS, pExpr uintptr) (r int32) {
bp := tls.Alloc(16)
defer tls.Free(16)
var _ /* v at bp+0 */ int32
if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) == int32(TK_NULL) {
return int32(1)
}
if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) == int32(TK_TRUEFALSE) && _sqlite3ExprTruthValue(tls, pExpr) == 0 {
return int32(1)
}
**(**int32)(__ccgo_up(bp)) = int32(1)
if _sqlite3ExprIsInteger(tls, pExpr, bp, uintptr(0)) != 0 && **(**int32)(__ccgo_up(bp)) == 0 {
return int32(1)
}
return 0
}
// C documentation
//
// /*
// ** If pExpr is an AND or OR expression, try to simplify it by eliminating
// ** terms that are always true or false. Return the simplified expression.
// ** Or return the original expression if no simplification is possible.
// **
// ** Examples:
// **
// ** (x<10) AND true => (x<10)
// ** (x<10) AND false => false
// ** (x<10) AND (y=22 OR false) => (x<10) AND (y=22)
// ** (x<10) AND (y=22 OR true) => (x<10)
// ** (y=22) OR true => true
// */
func _sqlite3ExprSimplifiedAndOr(tls *libc.TLS, pExpr uintptr) (r uintptr) {
var pLeft, pRight, v1 uintptr
_, _, _ = pLeft, pRight, v1
if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) == int32(TK_AND) || libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) == int32(TK_OR) {
pRight = _sqlite3ExprSimplifiedAndOr(tls, (*TExpr)(unsafe.Pointer(pExpr)).FpRight)
pLeft = _sqlite3ExprSimplifiedAndOr(tls, (*TExpr)(unsafe.Pointer(pExpr)).FpLeft)
if (*TExpr)(unsafe.Pointer(pLeft)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_OuterON)|libc.Int32FromInt32(EP_IsTrue)) == uint32(EP_IsTrue) || (*TExpr)(unsafe.Pointer(pRight)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_OuterON)|libc.Int32FromInt32(EP_IsFalse)) == uint32(EP_IsFalse) {
if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) == int32(TK_AND) {
v1 = pRight
} else {
v1 = pLeft
}
pExpr = v1
} else {
if (*TExpr)(unsafe.Pointer(pRight)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_OuterON)|libc.Int32FromInt32(EP_IsTrue)) == uint32(EP_IsTrue) || (*TExpr)(unsafe.Pointer(pLeft)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_OuterON)|libc.Int32FromInt32(EP_IsFalse)) == uint32(EP_IsFalse) {
if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) == int32(TK_AND) {
v1 = pLeft
} else {
v1 = pRight
}
pExpr = v1
}
}
}
return pExpr
}
// C documentation
//
// /*
// ** Skip over any TK_COLLATE operators.
// */
func _sqlite3ExprSkipCollate(tls *libc.TLS, pExpr uintptr) (r uintptr) {
for pExpr != 0 && (*TExpr)(unsafe.Pointer(pExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_Skip)) != uint32(0) {
pExpr = (*TExpr)(unsafe.Pointer(pExpr)).FpLeft
}
return pExpr
}
// C documentation
//
// /*
// ** Convert a scalar expression node to a TK_REGISTER referencing
// ** register iReg. The caller must ensure that iReg already contains
// ** the correct value for the expression.
// */
func _sqlite3ExprToRegister(tls *libc.TLS, pExpr uintptr, iReg int32) {
var p uintptr
_ = p
p = _sqlite3ExprSkipCollateAndLikely(tls, pExpr)
if p == uintptr(0) {
return
}
if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(p)).Fop) == int32(TK_REGISTER) {
} else {
(*TExpr)(unsafe.Pointer(p)).Fop2 = (*TExpr)(unsafe.Pointer(p)).Fop
(*TExpr)(unsafe.Pointer(p)).Fop = uint8(TK_REGISTER)
(*TExpr)(unsafe.Pointer(p)).FiTable = iReg
**(**Tu32)(__ccgo_up(p + 4)) &= ^libc.Uint32FromInt32(libc.Int32FromInt32(EP_Skip))
}
}
// C documentation
//
// /* Invoke sqlite3RenameExprUnmap() and sqlite3ExprDelete() on the
// ** expression.
// */
func _sqlite3ExprUnmapAndDelete(tls *libc.TLS, pParse uintptr, p uintptr) {
if p != 0 {
if libc.Int32FromUint8((*TParse)(unsafe.Pointer(pParse)).FeParseMode) >= int32(PARSE_MODE_RENAME) {
_sqlite3RenameExprUnmap(tls, pParse, p)
}
_sqlite3ExprDeleteNN(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, p)
}
}
// C documentation
//
// /*
// ** Given m and e, which represent a quantity r == m*pow(2,e),
// ** return values *pD and *pP such that r == (*pD)*pow(10,*pP),
// ** approximately. *pD should contain at least n significant digits.
// **
// ** The input m is required to have its highest bit set. In other words,
// ** m should be left-shifted, and e decremented, to maximize the value of m.
// */
func _sqlite3Fp2Convert10(tls *libc.TLS, m Tu64, e int32, n int32, pD uintptr, pP uintptr) {
bp := tls.Alloc(16)
defer tls.Free(16)
var h Tu64
var p int32
var _ /* d1 at bp+0 */ Tu64
var _ /* d2 at bp+8 */ Tu32
_, _ = h, p
p = n - int32(1) - _pwr2to10(tls, e+int32(63))
h = _sqlite3Multiply128(tls, m, _powerOfTen(tls, p, bp+8), bp)
if n == int32(18) {
h = h >> libc.Uint64FromInt32(-(e + _pwr10to2(tls, p) + libc.Int32FromInt32(2)))
**(**Tu64)(__ccgo_up(pD)) = (h + h<<libc.Int32FromInt32(1)&uint64(2)) >> int32(1)
} else {
**(**Tu64)(__ccgo_up(pD)) = h >> -(e + _pwr10to2(tls, p) + int32(1))
}
**(**int32)(__ccgo_up(pP)) = -p
}
// C documentation
//
// /*
// ** Set the buffer to contain nData/pData. If an OOM error occurs, leave an
// ** the error code in p. If an error has already occurred when this function
// ** is called, it is a no-op.
// */
func _sqlite3Fts5BufferSet(tls *libc.TLS, pRc uintptr, pBuf uintptr, nData int32, pData uintptr) {
(*TFts5Buffer)(unsafe.Pointer(pBuf)).Fn = 0
_sqlite3Fts5BufferAppendBlob(tls, pRc, pBuf, libc.Uint32FromInt32(nData), pData)
}
func _sqlite3Fts5BufferSize(tls *libc.TLS, pRc uintptr, pBuf uintptr, nByte Tu32) (r int32) {
var nNew Tu64
var pNew uintptr
var v1 int32
_, _, _ = nNew, pNew, v1
if libc.Uint32FromInt32((*TFts5Buffer)(unsafe.Pointer(pBuf)).FnSpace) < nByte {
if (*TFts5Buffer)(unsafe.Pointer(pBuf)).FnSpace != 0 {
v1 = (*TFts5Buffer)(unsafe.Pointer(pBuf)).FnSpace
} else {
v1 = int32(64)
}
nNew = libc.Uint64FromInt32(v1)
for nNew < uint64(nByte) {
nNew = nNew * uint64(2)
}
pNew = Xsqlite3_realloc64(tls, (*TFts5Buffer)(unsafe.Pointer(pBuf)).Fp, nNew)
if pNew == uintptr(0) {
**(**int32)(__ccgo_up(pRc)) = int32(SQLITE_NOMEM)
return int32(1)
} else {
(*TFts5Buffer)(unsafe.Pointer(pBuf)).FnSpace = libc.Int32FromUint64(nNew)
(*TFts5Buffer)(unsafe.Pointer(pBuf)).Fp = pNew
}
}
return 0
}
func _sqlite3Fts5Get32(tls *libc.TLS, aBuf uintptr) (r int32) {
return libc.Int32FromUint32(uint32(**(**Tu8)(__ccgo_up(aBuf)))<<libc.Int32FromInt32(24) + libc.Uint32FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aBuf + 1)))<<libc.Int32FromInt32(16)) + libc.Uint32FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aBuf + 2)))<<libc.Int32FromInt32(8)) + uint32(**(**Tu8)(__ccgo_up(aBuf + 3))))
}
// C documentation
//
// /*
// ** This is a copy of the sqlite3GetVarint32() routine from the SQLite core.
// ** Except, this version does handle the single byte case that the core
// ** version depends on being handled before its function is called.
// */
func _sqlite3Fts5GetVarint32(tls *libc.TLS, p uintptr, v uintptr) (r int32) {
bp := tls.Alloc(16)
defer tls.Free(16)
var a, b Tu32
var n Tu8
var _ /* v64 at bp+0 */ Tu64
_, _, _ = a, b, n
/* The 1-byte case. Overwhelmingly the most common. */
a = uint32(**(**uint8)(__ccgo_up(p)))
/* a: p0 (unmasked) */
if !(a&libc.Uint32FromInt32(0x80) != 0) {
/* Values between 0 and 127 */
**(**Tu32)(__ccgo_up(v)) = a
return int32(1)
}
/* The 2-byte case */
p = p + 1
b = uint32(**(**uint8)(__ccgo_up(p)))
/* b: p1 (unmasked) */
if !(b&libc.Uint32FromInt32(0x80) != 0) {
/* Values between 128 and 16383 */
a = a & uint32(0x7f)
a = a << int32(7)
**(**Tu32)(__ccgo_up(v)) = a | b
return int32(2)
}
/* The 3-byte case */
p = p + 1
a = a << int32(14)
a = a | uint32(**(**uint8)(__ccgo_up(p)))
/* a: p0<<14 | p2 (unmasked) */
if !(a&libc.Uint32FromInt32(0x80) != 0) {
/* Values between 16384 and 2097151 */
a = a & libc.Uint32FromInt32(libc.Int32FromInt32(0x7f)<<libc.Int32FromInt32(14)|libc.Int32FromInt32(0x7f))
b = b & uint32(0x7f)
b = b << int32(7)
**(**Tu32)(__ccgo_up(v)) = a | b
return int32(3)
}
/* A 32-bit varint is used to store size information in btrees.
** Objects are rarely larger than 2MiB limit of a 3-byte varint.
** A 3-byte varint is sufficient, for example, to record the size
** of a 1048569-byte BLOB or string.
**
** We only unroll the first 1-, 2-, and 3- byte cases. The very
** rare larger cases can be handled by the slower 64-bit varint
** routine.
*/
p = p - uintptr(2)
n = _sqlite3Fts5GetVarint(tls, p, bp)
**(**Tu32)(__ccgo_up(v)) = uint32(**(**Tu64)(__ccgo_up(bp))) & uint32(0x7FFFFFFF)
return libc.Int32FromUint8(n)
return r
}
/*
** Bitmasks used by sqlite3GetVarint(). These precomputed constants
** are defined here rather than simply putting the constant expressions
** inline in order to work around bugs in the RVT compiler.
**
** SLOT_2_0 A mask for (0x7f<<14) | 0x7f
**
** SLOT_4_2_0 A mask for (0x7f<<28) | SLOT_2_0
*/
func _sqlite3Fts5GetVarintLen(tls *libc.TLS, iVal Tu32) (r int32) {
if iVal < libc.Uint32FromInt32(libc.Int32FromInt32(1)<<libc.Int32FromInt32(14)) {
return int32(2)
}
if iVal < libc.Uint32FromInt32(libc.Int32FromInt32(1)<<libc.Int32FromInt32(21)) {
return int32(3)
}
if iVal < libc.Uint32FromInt32(libc.Int32FromInt32(1)<<libc.Int32FromInt32(28)) {
return int32(4)
}
return int32(5)
}
/*
** 2015 May 08
**
** 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 is an SQLite virtual table module implementing direct access to an
** existing FTS5 index. The module may create several different types of
** tables:
**
** col:
** CREATE TABLE vocab(term, col, doc, cnt, PRIMARY KEY(term, col));
**
** One row for each term/column combination. The value of $doc is set to
** the number of fts5 rows that contain at least one instance of term
** $term within column $col. Field $cnt is set to the total number of
** instances of term $term in column $col (in any row of the fts5 table).
**
** row:
** CREATE TABLE vocab(term, doc, cnt, PRIMARY KEY(term));
**
** One row for each term in the database. The value of $doc is set to
** the number of fts5 rows that contain at least one instance of term
** $term. Field $cnt is set to the total number of instances of term
** $term in the database.
**
** instance:
** CREATE TABLE vocab(term, doc, col, offset, PRIMARY KEY(<all-fields>));
**
** One row for each term instance in the database.
*/
/* #include "fts5Int.h" */
// C documentation
//
// /*
// ** Retrieve the origin value that will be used for the segment currently
// ** being accumulated in the in-memory hash table when it is flushed to
// ** disk. If successful, SQLITE_OK is returned and (*piOrigin) set to
// ** the queried value. Or, if an error occurs, an error code is returned
// ** and the final value of (*piOrigin) is undefined.
// */
func _sqlite3Fts5IndexGetOrigin(tls *libc.TLS, p uintptr, piOrigin uintptr) (r int32) {
var pStruct uintptr
_ = pStruct
pStruct = _fts5StructureRead(tls, p)
if pStruct != 0 {
**(**Ti64)(__ccgo_up(piOrigin)) = libc.Int64FromUint64((*TFts5Structure)(unsafe.Pointer(pStruct)).FnOriginCntr)
_fts5StructureRelease(tls, pStruct)
}
return _fts5IndexReturn(tls, p)
}
func _sqlite3Fts5PoslistNext64(tls *libc.TLS, a uintptr, n int32, pi uintptr, piOff uintptr) (r int32) {
bp := tls.Alloc(16)
defer tls.Free(16)
var i, v1 int32
var iOff Ti64
var _ /* iVal at bp+0 */ Tu32
_, _, _ = i, iOff, v1
i = **(**int32)(__ccgo_up(pi))
if i >= n {
/* EOF */
**(**Ti64)(__ccgo_up(piOff)) = int64(-int32(1))
return int32(1)
} else {
iOff = **(**Ti64)(__ccgo_up(piOff))
v1 = i
i = i + 1
**(**Tu32)(__ccgo_up(bp)) = uint32(**(**Tu8)(__ccgo_up(a + uintptr(v1))))
if **(**Tu32)(__ccgo_up(bp))&uint32(0x80) != 0 {
i = i - 1
i = i + _sqlite3Fts5GetVarint32(tls, a+uintptr(i), bp)
}
if **(**Tu32)(__ccgo_up(bp)) <= uint32(1) {
if **(**Tu32)(__ccgo_up(bp)) == uint32(0) {
**(**int32)(__ccgo_up(pi)) = i
return 0
}
v1 = i
i = i + 1
**(**Tu32)(__ccgo_up(bp)) = uint32(**(**Tu8)(__ccgo_up(a + uintptr(v1))))
if **(**Tu32)(__ccgo_up(bp))&uint32(0x80) != 0 {
i = i - 1
i = i + _sqlite3Fts5GetVarint32(tls, a+uintptr(i), bp)
}
iOff = libc.Int64FromUint32(**(**Tu32)(__ccgo_up(bp))) << int32(32)
v1 = i
i = i + 1
**(**Tu32)(__ccgo_up(bp)) = uint32(**(**Tu8)(__ccgo_up(a + uintptr(v1))))
if **(**Tu32)(__ccgo_up(bp))&uint32(0x80) != 0 {
i = i - 1
i = i + _sqlite3Fts5GetVarint32(tls, a+uintptr(i), bp)
}
if **(**Tu32)(__ccgo_up(bp)) < uint32(2) {
/* This is a corrupt record. So stop parsing it here. */
**(**Ti64)(__ccgo_up(piOff)) = int64(-int32(1))
return int32(1)
}
**(**Ti64)(__ccgo_up(piOff)) = iOff + libc.Int64FromUint32((**(**Tu32)(__ccgo_up(bp))-libc.Uint32FromInt32(2))&libc.Uint32FromInt32(0x7FFFFFFF))
} else {
**(**Ti64)(__ccgo_up(piOff)) = iOff&(libc.Int64FromInt32(0x7FFFFFFF)<<libc.Int32FromInt32(32)) + (iOff+libc.Int64FromUint32(**(**Tu32)(__ccgo_up(bp))-libc.Uint32FromInt32(2)))&int64(0x7FFFFFFF)
}
**(**int32)(__ccgo_up(pi)) = i
return 0
}
return r
}
func _sqlite3Fts5PoslistWriterAppend(tls *libc.TLS, pBuf uintptr, pWriter uintptr, iPos Ti64) (r int32) {
bp := tls.Alloc(16)
defer tls.Free(16)
var v1 int32
var _ /* rc at bp+0 */ int32
_ = v1
**(**int32)(__ccgo_up(bp)) = 0 /* Initialized only to suppress erroneous warning from Clang */
if libc.Uint32FromInt32((*TFts5Buffer)(unsafe.Pointer(pBuf)).Fn)+libc.Uint32FromInt32(libc.Int32FromInt32(5)+libc.Int32FromInt32(5)+libc.Int32FromInt32(5)) <= libc.Uint32FromInt32((*TFts5Buffer)(unsafe.Pointer(pBuf)).FnSpace) {
v1 = 0
} else {
v1 = _sqlite3Fts5BufferSize(tls, bp, pBuf, libc.Uint32FromInt32(libc.Int32FromInt32(5)+libc.Int32FromInt32(5)+libc.Int32FromInt32(5)+(*TFts5Buffer)(unsafe.Pointer(pBuf)).Fn))
}
if v1 != 0 {
return **(**int32)(__ccgo_up(bp))
}
_sqlite3Fts5PoslistSafeAppend(tls, pBuf, pWriter, iPos)
return SQLITE_OK
}
func _sqlite3Fts5Put32(tls *libc.TLS, aBuf uintptr, iVal int32) {
**(**Tu8)(__ccgo_up(aBuf)) = libc.Uint8FromInt32(iVal >> int32(24) & int32(0x00FF))
**(**Tu8)(__ccgo_up(aBuf + 1)) = libc.Uint8FromInt32(iVal >> int32(16) & int32(0x00FF))
**(**Tu8)(__ccgo_up(aBuf + 2)) = libc.Uint8FromInt32(iVal >> int32(8) & int32(0x00FF))
**(**Tu8)(__ccgo_up(aBuf + 3)) = libc.Uint8FromInt32(iVal >> 0 & int32(0x00FF))
}
func _sqlite3Fts5UnicodeAscii(tls *libc.TLS, aArray uintptr, aAscii uintptr) {
var bToken, i, iTbl, n int32
_, _, _, _ = bToken, i, iTbl, n
i = 0
iTbl = 0
for i < int32(128) {
bToken = libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aArray + uintptr(libc.Int32FromUint16(_aFts5UnicodeData[iTbl])&int32(0x1F)))))
n = libc.Int32FromUint16(_aFts5UnicodeData[iTbl])>>int32(5) + i
for {
if !(i < int32(128) && i < n) {
break
}
**(**Tu8)(__ccgo_up(aAscii + uintptr(i))) = libc.Uint8FromInt32(bToken)
goto _1
_1:
;
i = i + 1
}
iTbl = iTbl + 1
}
**(**Tu8)(__ccgo_up(aAscii)) = uint8(0) /* 0x00 is never a token character */
}
/*
** 2015 May 30
**
** 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.
**
******************************************************************************
**
** Routines for varint serialization and deserialization.
*/
/* #include "fts5Int.h" */
func _sqlite3Fts5UnicodeCategory(tls *libc.TLS, iCode Tu32) (r int32) {
var iHi, iLo, iRes, iTest, ret, v1 int32
var iKey Tu16
_, _, _, _, _, _, _ = iHi, iKey, iLo, iRes, iTest, ret, v1
iRes = -int32(1)
if iCode >= libc.Uint32FromInt32(libc.Int32FromInt32(1)<<libc.Int32FromInt32(20)) {
return 0
}
iLo = libc.Int32FromUint16(_aFts5UnicodeBlock[iCode>>int32(16)])
iHi = libc.Int32FromUint16(_aFts5UnicodeBlock[uint32(1)+iCode>>libc.Int32FromInt32(16)])
iKey = uint16(iCode & libc.Uint32FromInt32(0xFFFF))
for iHi > iLo {
iTest = (iHi + iLo) / int32(2)
if libc.Int32FromUint16(iKey) >= libc.Int32FromUint16(_aFts5UnicodeMap[iTest]) {
iRes = iTest
iLo = iTest + int32(1)
} else {
iHi = iTest
}
}
if iRes < 0 {
return 0
}
if libc.Int32FromUint16(iKey) >= libc.Int32FromUint16(_aFts5UnicodeMap[iRes])+libc.Int32FromUint16(_aFts5UnicodeData[iRes])>>int32(5) {
return 0
}
ret = libc.Int32FromUint16(_aFts5UnicodeData[iRes]) & int32(0x1F)
if ret != int32(30) {
return ret
}
if (libc.Int32FromUint16(iKey)-libc.Int32FromUint16(_aFts5UnicodeMap[iRes]))&int32(0x01) != 0 {
v1 = int32(5)
} else {
v1 = int32(9)
}
return v1
}
// C documentation
//
// /*
// ** Return true if the argument interpreted as a unicode codepoint
// ** is a diacritical modifier character.
// */
func _sqlite3Fts5UnicodeIsdiacritic(tls *libc.TLS, c int32) (r int32) {
var mask0, mask1, v1 uint32
_, _, _ = mask0, mask1, v1
mask0 = uint32(0x08029FDF)
mask1 = uint32(0x000361F8)
if c < int32(768) || c > int32(817) {
return 0
}
if c < libc.Int32FromInt32(768)+libc.Int32FromInt32(32) {
v1 = mask0 & (libc.Uint32FromInt32(1) << (c - int32(768)))
} else {
v1 = mask1 & (libc.Uint32FromInt32(1) << (c - int32(768) - int32(32)))
}
return libc.Int32FromUint32(v1)
}
// C documentation
//
// /*
// ** Interpret the given string as a boolean value.
// */
func _sqlite3GetBoolean(tls *libc.TLS, z uintptr, dflt Tu8) (r Tu8) {
return libc.BoolUint8(libc.Int32FromUint8(_getSafetyLevel(tls, z, int32(1), dflt)) != 0)
}
/* The sqlite3GetBoolean() function is used by other modules but the
** remainder of this file is specific to PRAGMA processing. So omit
** the rest of the file if PRAGMAs are omitted from the build.
*/
// C documentation
//
// /*
// ** Return the length (in bytes) of the token that begins at z[0].
// ** Store the token type in *tokenType before returning.
// */
func _sqlite3GetToken(tls *libc.TLS, z uintptr, tokenType uintptr) (r Ti64) {
var c, delim, v3 int32
var i, n Ti64
var v6 bool
_, _, _, _, _, _ = c, delim, i, n, v3, v6
switch libc.Int32FromUint8(_aiClass[**(**uint8)(__ccgo_up(z))]) { /* Switch on the character-class of the first byte
** of the token. See the comment on the CC_ defines
** above. */
case int32(CC_SPACE):
i = int64(1)
for {
if !(libc.Int32FromUint8(_sqlite3CtypeMap[**(**uint8)(__ccgo_up(z + uintptr(i)))])&int32(0x01) != 0) {
break
}
goto _1
_1:
;
i = i + 1
}
**(**int32)(__ccgo_up(tokenType)) = int32(TK_SPACE)
return i
case int32(CC_MINUS):
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + 1))) == int32('-') {
i = int64(2)
for {
v3 = libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(i))))
c = v3
if !(v3 != 0 && c != int32('\n')) {
break
}
goto _2
_2:
;
i = i + 1
}
**(**int32)(__ccgo_up(tokenType)) = int32(TK_COMMENT)
return i
} else {
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + 1))) == int32('>') {
**(**int32)(__ccgo_up(tokenType)) = int32(TK_PTR)
return int64(int32(2) + libc.BoolInt32(libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + 2))) == int32('>')))
}
}
**(**int32)(__ccgo_up(tokenType)) = int32(TK_MINUS)
return int64(1)
case int32(CC_LP):
**(**int32)(__ccgo_up(tokenType)) = int32(TK_LP)
return int64(1)
case int32(CC_RP):
**(**int32)(__ccgo_up(tokenType)) = int32(TK_RP)
return int64(1)
case int32(CC_SEMI):
**(**int32)(__ccgo_up(tokenType)) = int32(TK_SEMI)
return int64(1)
case int32(CC_PLUS):
**(**int32)(__ccgo_up(tokenType)) = int32(TK_PLUS)
return int64(1)
case int32(CC_STAR):
**(**int32)(__ccgo_up(tokenType)) = int32(TK_STAR)
return int64(1)
case int32(CC_SLASH):
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + 1))) != int32('*') || libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + 2))) == 0 {
**(**int32)(__ccgo_up(tokenType)) = int32(TK_SLASH)
return int64(1)
}
i = int64(3)
c = libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + 2)))
for {
if v6 = c != int32('*') || libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(i)))) != int32('/'); v6 {
v3 = libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(i))))
c = v3
}
if !(v6 && v3 != 0) {
break
}
goto _4
_4:
;
i = i + 1
}
if c != 0 {
i = i + 1
}
**(**int32)(__ccgo_up(tokenType)) = int32(TK_COMMENT)
return i
case int32(CC_PERCENT):
**(**int32)(__ccgo_up(tokenType)) = int32(TK_REM)
return int64(1)
case int32(CC_EQ):
**(**int32)(__ccgo_up(tokenType)) = int32(TK_EQ)
return int64(int32(1) + libc.BoolInt32(libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + 1))) == int32('=')))
case int32(CC_LT):
v3 = libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + 1)))
c = v3
if v3 == int32('=') {
**(**int32)(__ccgo_up(tokenType)) = int32(TK_LE)
return int64(2)
} else {
if c == int32('>') {
**(**int32)(__ccgo_up(tokenType)) = int32(TK_NE)
return int64(2)
} else {
if c == int32('<') {
**(**int32)(__ccgo_up(tokenType)) = int32(TK_LSHIFT)
return int64(2)
} else {
**(**int32)(__ccgo_up(tokenType)) = int32(TK_LT)
return int64(1)
}
}
}
fallthrough
case int32(CC_GT):
v3 = libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + 1)))
c = v3
if v3 == int32('=') {
**(**int32)(__ccgo_up(tokenType)) = int32(TK_GE)
return int64(2)
} else {
if c == int32('>') {
**(**int32)(__ccgo_up(tokenType)) = int32(TK_RSHIFT)
return int64(2)
} else {
**(**int32)(__ccgo_up(tokenType)) = int32(TK_GT)
return int64(1)
}
}
fallthrough
case int32(CC_BANG):
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + 1))) != int32('=') {
**(**int32)(__ccgo_up(tokenType)) = int32(TK_ILLEGAL)
return int64(1)
} else {
**(**int32)(__ccgo_up(tokenType)) = int32(TK_NE)
return int64(2)
}
fallthrough
case int32(CC_PIPE):
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + 1))) != int32('|') {
**(**int32)(__ccgo_up(tokenType)) = int32(TK_BITOR)
return int64(1)
} else {
**(**int32)(__ccgo_up(tokenType)) = int32(TK_CONCAT)
return int64(2)
}
fallthrough
case int32(CC_COMMA):
**(**int32)(__ccgo_up(tokenType)) = int32(TK_COMMA)
return int64(1)
case int32(CC_AND):
**(**int32)(__ccgo_up(tokenType)) = int32(TK_BITAND)
return int64(1)
case int32(CC_TILDA):
**(**int32)(__ccgo_up(tokenType)) = int32(TK_BITNOT)
return int64(1)
case int32(CC_QUOTE):
delim = libc.Int32FromUint8(**(**uint8)(__ccgo_up(z)))
i = int64(1)
for {
v3 = libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(i))))
c = v3
if !(v3 != 0) {
break
}
if c == delim {
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(i+int64(1))))) == delim {
i = i + 1
} else {
break
}
}
goto _9
_9:
;
i = i + 1
}
if c == int32('\'') {
**(**int32)(__ccgo_up(tokenType)) = int32(TK_STRING)
return i + int64(1)
} else {
if c != 0 {
**(**int32)(__ccgo_up(tokenType)) = int32(TK_ID)
return i + int64(1)
} else {
**(**int32)(__ccgo_up(tokenType)) = int32(TK_ILLEGAL)
return i
}
}
fallthrough
case int32(CC_DOT):
if !(libc.Int32FromUint8(_sqlite3CtypeMap[**(**uint8)(__ccgo_up(z + 1))])&libc.Int32FromInt32(0x04) != 0) {
**(**int32)(__ccgo_up(tokenType)) = int32(TK_DOT)
return int64(1)
}
/* If the next character is a digit, this is a floating point
** number that begins with ".". Fall thru into the next case */
fallthrough
case int32(CC_DIGIT):
**(**int32)(__ccgo_up(tokenType)) = int32(TK_INTEGER)
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z))) == int32('0') && (libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + 1))) == int32('x') || libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + 1))) == int32('X')) && libc.Int32FromUint8(_sqlite3CtypeMap[**(**uint8)(__ccgo_up(z + 2))])&int32(0x08) != 0 {
i = int64(3)
for {
if !(int32(1) != 0) {
break
}
if libc.Int32FromUint8(_sqlite3CtypeMap[**(**uint8)(__ccgo_up(z + uintptr(i)))])&int32(0x08) == 0 {
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(i)))) == int32('_') {
**(**int32)(__ccgo_up(tokenType)) = int32(TK_QNUMBER)
} else {
break
}
}
goto _11
_11:
;
i = i + 1
}
} else {
i = 0
for {
if !(int32(1) != 0) {
break
}
if libc.Int32FromUint8(_sqlite3CtypeMap[**(**uint8)(__ccgo_up(z + uintptr(i)))])&int32(0x04) == 0 {
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(i)))) == int32('_') {
**(**int32)(__ccgo_up(tokenType)) = int32(TK_QNUMBER)
} else {
break
}
}
goto _12
_12:
;
i = i + 1
}
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(i)))) == int32('.') {
if **(**int32)(__ccgo_up(tokenType)) == int32(TK_INTEGER) {
**(**int32)(__ccgo_up(tokenType)) = int32(TK_FLOAT)
}
i = i + 1
for {
if !(int32(1) != 0) {
break
}
if libc.Int32FromUint8(_sqlite3CtypeMap[**(**uint8)(__ccgo_up(z + uintptr(i)))])&int32(0x04) == 0 {
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(i)))) == int32('_') {
**(**int32)(__ccgo_up(tokenType)) = int32(TK_QNUMBER)
} else {
break
}
}
goto _13
_13:
;
i = i + 1
}
}
if (libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(i)))) == int32('e') || libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(i)))) == int32('E')) && (libc.Int32FromUint8(_sqlite3CtypeMap[**(**uint8)(__ccgo_up(z + uintptr(i+int64(1))))])&int32(0x04) != 0 || (libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(i+int64(1))))) == int32('+') || libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(i+int64(1))))) == int32('-')) && libc.Int32FromUint8(_sqlite3CtypeMap[**(**uint8)(__ccgo_up(z + uintptr(i+int64(2))))])&int32(0x04) != 0) {
if **(**int32)(__ccgo_up(tokenType)) == int32(TK_INTEGER) {
**(**int32)(__ccgo_up(tokenType)) = int32(TK_FLOAT)
}
i = i + int64(2)
for {
if !(int32(1) != 0) {
break
}
if libc.Int32FromUint8(_sqlite3CtypeMap[**(**uint8)(__ccgo_up(z + uintptr(i)))])&int32(0x04) == 0 {
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(i)))) == int32('_') {
**(**int32)(__ccgo_up(tokenType)) = int32(TK_QNUMBER)
} else {
break
}
}
goto _14
_14:
;
i = i + 1
}
}
}
for libc.Int32FromUint8(_sqlite3CtypeMap[**(**uint8)(__ccgo_up(z + uintptr(i)))])&int32(0x46) != 0 {
**(**int32)(__ccgo_up(tokenType)) = int32(TK_ILLEGAL)
i = i + 1
}
return i
case int32(CC_QUOTE2):
i = int64(1)
c = libc.Int32FromUint8(**(**uint8)(__ccgo_up(z)))
for {
if v6 = c != int32(']'); v6 {
v3 = libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(i))))
c = v3
}
if !(v6 && v3 != 0) {
break
}
goto _15
_15:
;
i = i + 1
}
if c == int32(']') {
v3 = int32(TK_ID)
} else {
v3 = int32(TK_ILLEGAL)
}
**(**int32)(__ccgo_up(tokenType)) = v3
return i
case int32(CC_VARNUM):
**(**int32)(__ccgo_up(tokenType)) = int32(TK_VARIABLE)
i = int64(1)
for {
if !(libc.Int32FromUint8(_sqlite3CtypeMap[**(**uint8)(__ccgo_up(z + uintptr(i)))])&int32(0x04) != 0) {
break
}
goto _19
_19:
;
i = i + 1
}
return i
case int32(CC_DOLLAR):
fallthrough
case int32(CC_VARALPHA):
n = 0
**(**int32)(__ccgo_up(tokenType)) = int32(TK_VARIABLE)
i = int64(1)
for {
v3 = libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(i))))
c = v3
if !(v3 != 0) {
break
}
if libc.Int32FromUint8(_sqlite3CtypeMap[libc.Uint8FromInt32(c)])&int32(0x46) != 0 {
n = n + 1
} else {
if c == int32('(') && n > 0 {
for {
i = i + 1
goto _23
_23:
;
v3 = libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(i))))
c = v3
if !(v3 != 0 && !(libc.Int32FromUint8(_sqlite3CtypeMap[libc.Uint8FromInt32(c)])&libc.Int32FromInt32(0x01) != 0) && c != int32(')')) {
break
}
}
if c == int32(')') {
i = i + 1
} else {
**(**int32)(__ccgo_up(tokenType)) = int32(TK_ILLEGAL)
}
break
} else {
if c == int32(':') && libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(i+int64(1))))) == int32(':') {
i = i + 1
} else {
break
}
}
}
goto _20
_20:
;
i = i + 1
}
if n == 0 {
**(**int32)(__ccgo_up(tokenType)) = int32(TK_ILLEGAL)
}
return i
case int32(CC_KYWD0):
if libc.Int32FromUint8(_aiClass[**(**uint8)(__ccgo_up(z + 1))]) > int32(CC_KYWD) {
i = int64(1)
break
}
i = int64(2)
for {
if !(libc.Int32FromUint8(_aiClass[**(**uint8)(__ccgo_up(z + uintptr(i)))]) <= int32(CC_KYWD)) {
break
}
goto _24
_24:
;
i = i + 1
}
if libc.Int32FromUint8(_sqlite3CtypeMap[**(**uint8)(__ccgo_up(z + uintptr(i)))])&int32(0x46) != 0 {
/* This token started out using characters that can appear in keywords,
** but z[i] is a character not allowed within keywords, so this must
** be an identifier instead */
i = i + 1
break
}
**(**int32)(__ccgo_up(tokenType)) = int32(TK_ID)
return _keywordCode(tls, z, i, tokenType)
case CC_X:
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + 1))) == int32('\'') {
**(**int32)(__ccgo_up(tokenType)) = int32(TK_BLOB)
i = int64(2)
for {
if !(libc.Int32FromUint8(_sqlite3CtypeMap[**(**uint8)(__ccgo_up(z + uintptr(i)))])&int32(0x08) != 0) {
break
}
goto _25
_25:
;
i = i + 1
}
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(i)))) != int32('\'') || i%int64(2) != 0 {
**(**int32)(__ccgo_up(tokenType)) = int32(TK_ILLEGAL)
for **(**uint8)(__ccgo_up(z + uintptr(i))) != 0 && libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(i)))) != int32('\'') {
i = i + 1
}
}
if **(**uint8)(__ccgo_up(z + uintptr(i))) != 0 {
i = i + 1
}
return i
}
/* If it is not a BLOB literal, then it must be an ID, since no
** SQL keywords start with the letter 'x'. Fall through */
fallthrough
case int32(CC_KYWD):
fallthrough
case int32(CC_ID):
i = int64(1)
case int32(CC_BOM):
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + 1))) == int32(0xbb) && libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + 2))) == int32(0xbf) {
**(**int32)(__ccgo_up(tokenType)) = int32(TK_SPACE)
return int64(3)
}
i = int64(1)
case int32(CC_NUL):
**(**int32)(__ccgo_up(tokenType)) = int32(TK_ILLEGAL)
return 0
default:
**(**int32)(__ccgo_up(tokenType)) = int32(TK_ILLEGAL)
return int64(1)
}
for libc.Int32FromUint8(_sqlite3CtypeMap[**(**uint8)(__ccgo_up(z + uintptr(i)))])&int32(0x46) != 0 {
i = i + 1
}
**(**int32)(__ccgo_up(tokenType)) = int32(TK_ID)
return i
}
// C documentation
//
// /*
// ** Read a 64-bit variable-length integer from memory starting at p[0].
// ** Return the number of bytes read. The value is stored in *v.
// */
func _sqlite3GetVarint(tls *libc.TLS, p uintptr, v uintptr) (r Tu8) {
var a, b, s Tu32
_, _, _ = a, b, s
if int32(**(**int8)(__ccgo_up(p))) >= 0 {
**(**Tu64)(__ccgo_up(v)) = uint64(**(**uint8)(__ccgo_up(p)))
return uint8(1)
}
if int32(**(**int8)(__ccgo_up(p + 1))) >= 0 {
**(**Tu64)(__ccgo_up(v)) = uint64(libc.Uint32FromInt32(libc.Int32FromUint8(**(**uint8)(__ccgo_up(p)))&libc.Int32FromInt32(0x7f))<<libc.Int32FromInt32(7) | uint32(**(**uint8)(__ccgo_up(p + 1))))
return uint8(2)
}
/* Verify that constants are precomputed correctly */
a = uint32(**(**uint8)(__ccgo_up(p))) << int32(14)
b = uint32(**(**uint8)(__ccgo_up(p + 1)))
p = p + uintptr(2)
a = a | uint32(**(**uint8)(__ccgo_up(p)))
/* a: p0<<14 | p2 (unmasked) */
if !(a&libc.Uint32FromInt32(0x80) != 0) {
a = a & uint32(SLOT_2_0)
b = b & uint32(0x7f)
b = b << int32(7)
a = a | b
**(**Tu64)(__ccgo_up(v)) = uint64(a)
return uint8(3)
}
/* CSE1 from below */
a = a & uint32(SLOT_2_0)
p = p + 1
b = b << int32(14)
b = b | uint32(**(**uint8)(__ccgo_up(p)))
/* b: p1<<14 | p3 (unmasked) */
if !(b&libc.Uint32FromInt32(0x80) != 0) {
b = b & uint32(SLOT_2_0)
/* moved CSE1 up */
/* a &= (0x7f<<14)|(0x7f); */
a = a << int32(7)
a = a | b
**(**Tu64)(__ccgo_up(v)) = uint64(a)
return uint8(4)
}
/* a: p0<<14 | p2 (masked) */
/* b: p1<<14 | p3 (unmasked) */
/* 1:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */
/* moved CSE1 up */
/* a &= (0x7f<<14)|(0x7f); */
b = b & uint32(SLOT_2_0)
s = a
/* s: p0<<14 | p2 (masked) */
p = p + 1
a = a << int32(14)
a = a | uint32(**(**uint8)(__ccgo_up(p)))
/* a: p0<<28 | p2<<14 | p4 (unmasked) */
if !(a&libc.Uint32FromInt32(0x80) != 0) {
/* we can skip these cause they were (effectively) done above
** while calculating s */
/* a &= (0x7f<<28)|(0x7f<<14)|(0x7f); */
/* b &= (0x7f<<14)|(0x7f); */
b = b << int32(7)
a = a | b
s = s >> int32(18)
**(**Tu64)(__ccgo_up(v)) = uint64(s)<<int32(32) | uint64(a)
return uint8(5)
}
/* 2:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */
s = s << int32(7)
s = s | b
/* s: p0<<21 | p1<<14 | p2<<7 | p3 (masked) */
p = p + 1
b = b << int32(14)
b = b | uint32(**(**uint8)(__ccgo_up(p)))
/* b: p1<<28 | p3<<14 | p5 (unmasked) */
if !(b&libc.Uint32FromInt32(0x80) != 0) {
/* we can skip this cause it was (effectively) done above in calc'ing s */
/* b &= (0x7f<<28)|(0x7f<<14)|(0x7f); */
a = a & uint32(SLOT_2_0)
a = a << int32(7)
a = a | b
s = s >> int32(18)
**(**Tu64)(__ccgo_up(v)) = uint64(s)<<int32(32) | uint64(a)
return uint8(6)
}
p = p + 1
a = a << int32(14)
a = a | uint32(**(**uint8)(__ccgo_up(p)))
/* a: p2<<28 | p4<<14 | p6 (unmasked) */
if !(a&libc.Uint32FromInt32(0x80) != 0) {
a = a & uint32(SLOT_4_2_0)
b = b & uint32(SLOT_2_0)
b = b << int32(7)
a = a | b
s = s >> int32(11)
**(**Tu64)(__ccgo_up(v)) = uint64(s)<<int32(32) | uint64(a)
return uint8(7)
}
/* CSE2 from below */
a = a & uint32(SLOT_2_0)
p = p + 1
b = b << int32(14)
b = b | uint32(**(**uint8)(__ccgo_up(p)))
/* b: p3<<28 | p5<<14 | p7 (unmasked) */
if !(b&libc.Uint32FromInt32(0x80) != 0) {
b = b & uint32(SLOT_4_2_0)
/* moved CSE2 up */
/* a &= (0x7f<<14)|(0x7f); */
a = a << int32(7)
a = a | b
s = s >> int32(4)
**(**Tu64)(__ccgo_up(v)) = uint64(s)<<int32(32) | uint64(a)
return uint8(8)
}
p = p + 1
a = a << int32(15)
a = a | uint32(**(**uint8)(__ccgo_up(p)))
/* a: p4<<29 | p6<<15 | p8 (unmasked) */
/* moved CSE2 up */
/* a &= (0x7f<<29)|(0x7f<<15)|(0xff); */
b = b & uint32(SLOT_2_0)
b = b << int32(8)
a = a | b
s = s << int32(4)
b = uint32(**(**uint8)(__ccgo_up(p + uintptr(-libc.Int32FromInt32(4)))))
b = b & uint32(0x7f)
b = b >> int32(3)
s = s | b
**(**Tu64)(__ccgo_up(v)) = uint64(s)<<int32(32) | uint64(a)
return uint8(9)
}
// C documentation
//
// /*
// ** Read a 32-bit variable-length integer from memory starting at p[0].
// ** Return the number of bytes read. The value is stored in *v.
// **
// ** If the varint stored in p[0] is larger than can fit in a 32-bit unsigned
// ** integer, then set *v to 0xffffffff.
// **
// ** A MACRO version, getVarint32, is provided which inlines the
// ** single-byte case. All code should use the MACRO version as
// ** this function assumes the single-byte case has already been handled.
// */
func _sqlite3GetVarint32(tls *libc.TLS, p uintptr, v uintptr) (r Tu8) {
bp := tls.Alloc(16)
defer tls.Free(16)
var n Tu8
var _ /* v64 at bp+0 */ Tu64
_ = n
/* Assume that the single-byte case has already been handled by
** the getVarint32() macro */
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(p + 1)))&int32(0x80) == 0 {
/* This is the two-byte case */
**(**Tu32)(__ccgo_up(v)) = libc.Uint32FromInt32(libc.Int32FromUint8(**(**uint8)(__ccgo_up(p)))&int32(0x7f)<<int32(7) | libc.Int32FromUint8(**(**uint8)(__ccgo_up(p + 1))))
return uint8(2)
}
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(p + 2)))&int32(0x80) == 0 {
/* This is the three-byte case */
**(**Tu32)(__ccgo_up(v)) = libc.Uint32FromInt32(libc.Int32FromUint8(**(**uint8)(__ccgo_up(p)))&int32(0x7f)<<int32(14) | libc.Int32FromUint8(**(**uint8)(__ccgo_up(p + 1)))&int32(0x7f)<<int32(7) | libc.Int32FromUint8(**(**uint8)(__ccgo_up(p + 2))))
return uint8(3)
}
/* four or more bytes */
n = _sqlite3GetVarint(tls, p, bp)
if **(**Tu64)(__ccgo_up(bp))&(libc.Uint64FromInt32(1)<<libc.Int32FromInt32(32)-libc.Uint64FromInt32(1)) != **(**Tu64)(__ccgo_up(bp)) {
**(**Tu32)(__ccgo_up(v)) = uint32(0xffffffff)
} else {
**(**Tu32)(__ccgo_up(v)) = uint32(**(**Tu64)(__ccgo_up(bp)))
}
return n
}
// C documentation
//
// /*
// ** Translate a single byte of Hex into an integer.
// ** This routine only works if h really is a valid hexadecimal
// ** character: 0..9a..fA..F
// */
func _sqlite3HexToInt(tls *libc.TLS, h int32) (r Tu8) {
h = h + int32(9)*(int32(1)&(h>>int32(6)))
return libc.Uint8FromInt32(h & libc.Int32FromInt32(0xf))
}
// C documentation
//
// /* Make the IdChar function accessible from ctime.c and alter.c */
func _sqlite3IsIdChar(tls *libc.TLS, c Tu8) (r int32) {
return libc.BoolInt32(libc.Int32FromUint8(_sqlite3CtypeMap[c])&int32(0x46) != 0)
}
// C documentation
//
// /*
// ** This function returns the collation sequence for database native text
// ** encoding identified by the string zName.
// **
// ** If the requested collation sequence is not available, or not available
// ** in the database native encoding, the collation factory is invoked to
// ** request it. If the collation factory does not supply such a sequence,
// ** and the sequence is available in another text encoding, then that is
// ** returned instead.
// **
// ** If no versions of the requested collations sequence are available, or
// ** another error occurs, NULL is returned and an error message written into
// ** pParse.
// **
// ** This routine is a wrapper around sqlite3FindCollSeq(). This routine
// ** invokes the collation factory if the named collation cannot be found
// ** and generates an error message.
// **
// ** See also: sqlite3FindCollSeq(), sqlite3GetCollSeq()
// */
func _sqlite3LocateCollSeq(tls *libc.TLS, pParse uintptr, zName uintptr) (r uintptr) {
var db, pColl uintptr
var enc, initbusy Tu8
_, _, _, _ = db, enc, initbusy, pColl
db = (*TParse)(unsafe.Pointer(pParse)).Fdb
enc = (*Tsqlite3)(unsafe.Pointer(db)).Fenc
initbusy = (*Tsqlite3)(unsafe.Pointer(db)).Finit1.Fbusy
pColl = _sqlite3FindCollSeq(tls, db, enc, zName, libc.Int32FromUint8(initbusy))
if !(initbusy != 0) && (!(pColl != 0) || !((*TCollSeq)(unsafe.Pointer(pColl)).FxCmp != 0)) {
pColl = _sqlite3GetCollSeq(tls, pParse, enc, pColl, zName)
}
return pColl
}
// C documentation
//
// /*
// ** Find (an approximate) sum of two LogEst values. This computation is
// ** not a simple "+" operator because LogEst is stored as a logarithmic
// ** value.
// **
// */
func _sqlite3LogEstAdd(tls *libc.TLS, a TLogEst, b TLogEst) (r TLogEst) {
if int32(a) >= int32(b) {
if int32(a) > int32(b)+int32(49) {
return a
}
if int32(a) > int32(b)+int32(31) {
return int16(int32(a) + int32(1))
}
return int16(int32(a) + libc.Int32FromUint8(_x[int32(a)-int32(b)]))
} else {
if int32(b) > int32(a)+int32(49) {
return b
}
if int32(b) > int32(a)+int32(31) {
return int16(int32(b) + int32(1))
}
return int16(int32(b) + libc.Int32FromUint8(_x[int32(b)-int32(a)]))
}
return r
}
// C documentation
//
// /*
// ** Convert a LogEst into an integer.
// */
func _sqlite3LogEstToInt(tls *libc.TLS, x TLogEst) (r Tu64) {
var n Tu64
var v1 uint64
_, _ = n, v1
n = libc.Uint64FromInt32(int32(x) % int32(10))
x = int16(int32(x) / libc.Int32FromInt32(10))
if n >= uint64(5) {
n = n - uint64(2)
} else {
if n >= uint64(1) {
n = n - uint64(1)
}
}
if int32(x) > int32(60) {
return libc.Uint64FromInt64(libc.Int64FromUint32(0xffffffff) | libc.Int64FromInt32(0x7fffffff)<<libc.Int32FromInt32(32))
}
if int32(x) >= int32(3) {
v1 = (n + uint64(8)) << (int32(x) - int32(3))
} else {
v1 = (n + uint64(8)) >> (int32(3) - int32(x))
}
return v1
}
// C documentation
//
// /*
// ** Count the number of slots of lookaside memory that are outstanding
// */
func _sqlite3LookasideUsed(tls *libc.TLS, db uintptr, pHighwater uintptr) (r int32) {
var nFree, nInit Tu32
_, _ = nFree, nInit
nInit = _countLookasideSlots(tls, (*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpInit)
nFree = _countLookasideSlots(tls, (*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpFree)
nInit = nInit + _countLookasideSlots(tls, (*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpSmallInit)
nFree = nFree + _countLookasideSlots(tls, (*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpSmallFree)
if pHighwater != 0 {
**(**int32)(__ccgo_up(pHighwater)) = libc.Int32FromUint32((*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FnSlot - nInit)
}
return libc.Int32FromUint32((*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FnSlot - (nInit + nFree))
}
// C documentation
//
// /*
// ** Allocate memory. This routine is like sqlite3_malloc() except that it
// ** assumes the memory subsystem has already been initialized.
// */
func _sqlite3Malloc(tls *libc.TLS, n Tu64) (r uintptr) {
bp := tls.Alloc(16)
defer tls.Free(16)
var _ /* p at bp+0 */ uintptr
if n == uint64(0) || n > uint64(SQLITE_MAX_ALLOCATION_SIZE) {
**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
} else {
if _sqlite3Config.FbMemstat != 0 {
Xsqlite3_mutex_enter(tls, _mem0.Fmutex)
_mallocWithAlarm(tls, libc.Int32FromUint64(n), bp)
Xsqlite3_mutex_leave(tls, _mem0.Fmutex)
} else {
**(**uintptr)(__ccgo_up(bp)) = (*(*func(*libc.TLS, int32) uintptr)(unsafe.Pointer(&struct{ uintptr }{_sqlite3Config.Fm.FxMalloc})))(tls, libc.Int32FromUint64(n))
}
}
/* IMP: R-11148-40995 */
return **(**uintptr)(__ccgo_up(bp))
}
// C documentation
//
// /*
// ** Compare the values contained by the two memory cells, returning
// ** negative, zero or positive if pMem1 is less than, equal to, or greater
// ** than pMem2. Sorting order is NULL's first, followed by numbers (integers
// ** and reals) sorted numerically, followed by text ordered by the collating
// ** sequence pColl and finally blob's ordered by memcmp().
// **
// ** Two NULL values are considered equal by this function.
// */
func _sqlite3MemCompare(tls *libc.TLS, pMem1 uintptr, pMem2 uintptr, pColl uintptr) (r int32) {
var combined_flags, f1, f2 int32
_, _, _ = combined_flags, f1, f2
f1 = libc.Int32FromUint16((*TMem)(unsafe.Pointer(pMem1)).Fflags)
f2 = libc.Int32FromUint16((*TMem)(unsafe.Pointer(pMem2)).Fflags)
combined_flags = f1 | f2
/* If one value is NULL, it is less than the other. If both values
** are NULL, return 0.
*/
if combined_flags&int32(MEM_Null) != 0 {
return f2&int32(MEM_Null) - f1&int32(MEM_Null)
}
/* At least one of the two values is a number
*/
if combined_flags&(libc.Int32FromInt32(MEM_Int)|libc.Int32FromInt32(MEM_Real)|libc.Int32FromInt32(MEM_IntReal)) != 0 {
if f1&f2&(libc.Int32FromInt32(MEM_Int)|libc.Int32FromInt32(MEM_IntReal)) != 0 {
if *(*Ti64)(unsafe.Pointer(pMem1)) < *(*Ti64)(unsafe.Pointer(pMem2)) {
return -int32(1)
}
if *(*Ti64)(unsafe.Pointer(pMem1)) > *(*Ti64)(unsafe.Pointer(pMem2)) {
return +libc.Int32FromInt32(1)
}
return 0
}
if f1&f2&int32(MEM_Real) != 0 {
if *(*float64)(unsafe.Pointer(pMem1)) < *(*float64)(unsafe.Pointer(pMem2)) {
return -int32(1)
}
if *(*float64)(unsafe.Pointer(pMem1)) > *(*float64)(unsafe.Pointer(pMem2)) {
return +libc.Int32FromInt32(1)
}
return 0
}
if f1&(libc.Int32FromInt32(MEM_Int)|libc.Int32FromInt32(MEM_IntReal)) != 0 {
if f2&int32(MEM_Real) != 0 {
return _sqlite3IntFloatCompare(tls, *(*Ti64)(unsafe.Pointer(pMem1)), *(*float64)(unsafe.Pointer(pMem2)))
} else {
if f2&(libc.Int32FromInt32(MEM_Int)|libc.Int32FromInt32(MEM_IntReal)) != 0 {
if *(*Ti64)(unsafe.Pointer(pMem1)) < *(*Ti64)(unsafe.Pointer(pMem2)) {
return -int32(1)
}
if *(*Ti64)(unsafe.Pointer(pMem1)) > *(*Ti64)(unsafe.Pointer(pMem2)) {
return +libc.Int32FromInt32(1)
}
return 0
} else {
return -int32(1)
}
}
}
if f1&int32(MEM_Real) != 0 {
if f2&(libc.Int32FromInt32(MEM_Int)|libc.Int32FromInt32(MEM_IntReal)) != 0 {
return -_sqlite3IntFloatCompare(tls, *(*Ti64)(unsafe.Pointer(pMem2)), *(*float64)(unsafe.Pointer(pMem1)))
} else {
return -int32(1)
}
}
return +libc.Int32FromInt32(1)
}
/* If one value is a string and the other is a blob, the string is less.
** If both are strings, compare using the collating functions.
*/
if combined_flags&int32(MEM_Str) != 0 {
if f1&int32(MEM_Str) == 0 {
return int32(1)
}
if f2&int32(MEM_Str) == 0 {
return -int32(1)
}
/* The collation sequence must be defined at this point, even if
** the user deletes the collation sequence after the vdbe program is
** compiled (this was not always the case).
*/
if pColl != 0 {
return _vdbeCompareMemString(tls, pMem1, pMem2, pColl, uintptr(0))
}
/* If a NULL pointer was passed as the collate function, fall through
** to the blob case and use memcmp(). */
}
/* Both values must be blobs. Compare using memcmp(). */
return _sqlite3BlobCompare(tls, pMem1, pMem2)
}
// C documentation
//
// /*
// ** Invoke sqlite3AtoF() on the text value of pMem. Write the
// ** translation of the text input into *pValue.
// **
// ** The caller must ensure that pMem->db!=0 and that pMem is in
// ** mode MEM_Str or MEM_Blob.
// **
// ** Result code invariants:
// **
// ** rc==0 => ERROR: Input string not well-formed, or OOM
// ** rc<0 => Some prefix of the input is well-formed
// ** rc>0 => All of the input is well-formed
// ** (rc&2)==0 => The number is expressed as an integer, with no
// ** decimal point or eNNN suffix.
// */
func _sqlite3MemRealValueRC(tls *libc.TLS, pMem uintptr, pValue uintptr) (r int32) {
if (*TMem)(unsafe.Pointer(pMem)).Fz == uintptr(0) {
**(**float64)(__ccgo_up(pValue)) = float64(0)
return 0
} else {
if libc.Int32FromUint8((*TMem)(unsafe.Pointer(pMem)).Fenc) == int32(SQLITE_UTF8) && (libc.Int32FromUint16((*TMem)(unsafe.Pointer(pMem)).Fflags)&int32(MEM_Term) != 0 || _sqlite3VdbeMemZeroTerminateIfAble(tls, pMem) != 0) {
return _sqlite3AtoF(tls, (*TMem)(unsafe.Pointer(pMem)).Fz, pValue)
} else {
if (*TMem)(unsafe.Pointer(pMem)).Fn == 0 {
**(**float64)(__ccgo_up(pValue)) = float64(0)
return 0
} else {
return _sqlite3MemRealValueRCSlowPath(tls, pMem, pValue)
}
}
}
return r
}
// C documentation
//
// /*
// ** Generate code that will
// **
// ** (1) acquire a lock for table pTab then
// ** (2) open pTab as cursor iCur.
// **
// ** If pTab is a WITHOUT ROWID table, then it is the PRIMARY KEY index
// ** for that table that is actually opened.
// */
func _sqlite3OpenTable(tls *libc.TLS, pParse uintptr, iCur int32, iDb int32, pTab uintptr, opcode int32) {
var pPk, v uintptr
var v1 int32
_, _, _ = pPk, v, v1
v = (*TParse)(unsafe.Pointer(pParse)).FpVdbe
if !((*Tsqlite3)(unsafe.Pointer((*TParse)(unsafe.Pointer(pParse)).Fdb)).FnoSharedCache != 0) {
if opcode == int32(OP_OpenWrite) {
v1 = int32(1)
} else {
v1 = 0
}
_sqlite3TableLock(tls, pParse, iDb, (*TTable)(unsafe.Pointer(pTab)).Ftnum, libc.Uint8FromInt32(v1), (*TTable)(unsafe.Pointer(pTab)).FzName)
}
if (*TTable)(unsafe.Pointer(pTab)).FtabFlags&uint32(TF_WithoutRowid) == uint32(0) {
_sqlite3VdbeAddOp4Int(tls, v, opcode, iCur, libc.Int32FromUint32((*TTable)(unsafe.Pointer(pTab)).Ftnum), iDb, int32((*TTable)(unsafe.Pointer(pTab)).FnNVCol))
} else {
pPk = _sqlite3PrimaryKeyIndex(tls, pTab)
_sqlite3VdbeAddOp3(tls, v, opcode, iCur, libc.Int32FromUint32((*TIndex)(unsafe.Pointer(pPk)).Ftnum), iDb)
_sqlite3VdbeSetP4KeyInfo(tls, pParse, pPk)
}
}
func _sqlite3OsOpenMalloc(tls *libc.TLS, pVfs uintptr, zFile uintptr, ppFile uintptr, flags int32, pOutFlags uintptr) (r int32) {
var pFile uintptr
var rc int32
_, _ = pFile, rc
pFile = _sqlite3MallocZero(tls, libc.Uint64FromInt32((*Tsqlite3_vfs)(unsafe.Pointer(pVfs)).FszOsFile))
if pFile != 0 {
rc = _sqlite3OsOpen(tls, pVfs, zFile, pFile, flags, pOutFlags)
if rc != SQLITE_OK {
Xsqlite3_free(tls, pFile)
**(**uintptr)(__ccgo_up(ppFile)) = uintptr(0)
} else {
**(**uintptr)(__ccgo_up(ppFile)) = pFile
}
} else {
**(**uintptr)(__ccgo_up(ppFile)) = uintptr(0)
rc = int32(SQLITE_NOMEM)
}
return rc
}
// C documentation
//
// /* Create a TK_IS or TK_ISNOT operator, perhaps optimized to
// ** TK_ISNULL or TK_NOTNULL or TK_TRUEFALSE. */
func _sqlite3PExprIs(tls *libc.TLS, pParse uintptr, op int32, pLeft uintptr, pRight uintptr) (r uintptr) {
var v1 int32
_ = v1
if pRight != 0 && libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pRight)).Fop) == int32(TK_NULL) {
_sqlite3ExprDeferredDelete(tls, pParse, pRight)
if op == int32(TK_IS) {
v1 = int32(TK_ISNULL)
} else {
v1 = int32(TK_NOTNULL)
}
return _sqlite3PExprIsNull(tls, pParse, v1, pLeft)
}
return _sqlite3PExpr(tls, pParse, op, pLeft, pRight)
}
// C documentation
//
// /* Create a TK_ISNULL or TK_NOTNULL expression, perhaps optimized to
// ** to TK_TRUEFALSE, if possible */
func _sqlite3PExprIsNull(tls *libc.TLS, pParse uintptr, op int32, pLeft uintptr) (r uintptr) {
var p uintptr
_ = p
p = pLeft
for libc.Int32FromUint8((*TExpr)(unsafe.Pointer(p)).Fop) == int32(TK_UPLUS) || libc.Int32FromUint8((*TExpr)(unsafe.Pointer(p)).Fop) == int32(TK_UMINUS) {
p = (*TExpr)(unsafe.Pointer(p)).FpLeft
}
switch libc.Int32FromUint8((*TExpr)(unsafe.Pointer(p)).Fop) {
case int32(TK_INTEGER):
fallthrough
case int32(TK_STRING):
fallthrough
case int32(TK_FLOAT):
fallthrough
case int32(TK_BLOB):
_sqlite3ExprDeferredDelete(tls, pParse, pLeft)
return _sqlite3ExprInt32(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, libc.BoolInt32(op == int32(TK_NOTNULL)))
default:
break
}
return _sqlite3PExpr(tls, pParse, op, pLeft, uintptr(0))
}
// C documentation
//
// /*
// ** Begin a write-transaction on the specified pager object. If a
// ** write-transaction has already been opened, this function is a no-op.
// **
// ** If the exFlag argument is false, then acquire at least a RESERVED
// ** lock on the database file. If exFlag is true, then acquire at least
// ** an EXCLUSIVE lock. If such a lock is already held, no locking
// ** functions need be called.
// **
// ** If the subjInMemory argument is non-zero, then any sub-journal opened
// ** within this transaction will be opened as an in-memory file. This
// ** has no effect if the sub-journal is already opened (as it may be when
// ** running in exclusive mode) or if the transaction does not require a
// ** sub-journal. If the subjInMemory argument is zero, then any required
// ** sub-journal is implemented in-memory if pPager is an in-memory database,
// ** or using a temporary file otherwise.
// */
func _sqlite3PagerBegin(tls *libc.TLS, pPager uintptr, exFlag int32, subjInMemory int32) (r int32) {
var rc int32
_ = rc
rc = SQLITE_OK
if (*TPager)(unsafe.Pointer(pPager)).FerrCode != 0 {
return (*TPager)(unsafe.Pointer(pPager)).FerrCode
}
(*TPager)(unsafe.Pointer(pPager)).FsubjInMemory = libc.Uint8FromInt32(subjInMemory)
if libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FeState) == int32(PAGER_READER) {
if (*TPager)(unsafe.Pointer(pPager)).FpWal != uintptr(0) {
/* If the pager is configured to use locking_mode=exclusive, and an
** exclusive lock on the database is not already held, obtain it now.
*/
if (*TPager)(unsafe.Pointer(pPager)).FexclusiveMode != 0 && _sqlite3WalExclusiveMode(tls, (*TPager)(unsafe.Pointer(pPager)).FpWal, -int32(1)) != 0 {
rc = _pagerLockDb(tls, pPager, int32(EXCLUSIVE_LOCK))
if rc != SQLITE_OK {
return rc
}
_sqlite3WalExclusiveMode(tls, (*TPager)(unsafe.Pointer(pPager)).FpWal, int32(1))
}
/* Grab the write lock on the log file. If successful, upgrade to
** PAGER_RESERVED state. Otherwise, return an error code to the caller.
** The busy-handler is not invoked if another connection already
** holds the write-lock. If possible, the upper layer will call it.
*/
rc = _sqlite3WalBeginWriteTransaction(tls, (*TPager)(unsafe.Pointer(pPager)).FpWal)
} else {
/* Obtain a RESERVED lock on the database file. If the exFlag parameter
** is true, then immediately upgrade this to an EXCLUSIVE lock. The
** busy-handler callback can be used when upgrading to the EXCLUSIVE
** lock, but not when obtaining the RESERVED lock.
*/
rc = _pagerLockDb(tls, pPager, int32(RESERVED_LOCK))
if rc == SQLITE_OK && exFlag != 0 {
rc = _pager_wait_on_lock(tls, pPager, int32(EXCLUSIVE_LOCK))
}
}
if rc == SQLITE_OK {
/* Change to WRITER_LOCKED state.
**
** WAL mode sets Pager.eState to PAGER_WRITER_LOCKED or CACHEMOD
** when it has an open transaction, but never to DBMOD or FINISHED.
** This is because in those states the code to roll back savepoint
** transactions may copy data from the sub-journal into the database
** file as well as into the page cache. Which would be incorrect in
** WAL mode.
*/
(*TPager)(unsafe.Pointer(pPager)).FeState = uint8(PAGER_WRITER_LOCKED)
(*TPager)(unsafe.Pointer(pPager)).FdbHintSize = (*TPager)(unsafe.Pointer(pPager)).FdbSize
(*TPager)(unsafe.Pointer(pPager)).FdbFileSize = (*TPager)(unsafe.Pointer(pPager)).FdbSize
(*TPager)(unsafe.Pointer(pPager)).FdbOrigSize = (*TPager)(unsafe.Pointer(pPager)).FdbSize
(*TPager)(unsafe.Pointer(pPager)).FjournalOff = 0
}
}
return rc
}
// C documentation
//
// /*
// ** Unless this is an in-memory or temporary database, clear the pager cache.
// */
func _sqlite3PagerClearCache(tls *libc.TLS, pPager uintptr) {
if libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FtempFile) == 0 {
_pager_reset(tls, pPager)
}
}
// C documentation
//
// /*
// ** Shutdown the page cache. Free all memory and close all files.
// **
// ** If a transaction was in progress when this routine is called, that
// ** transaction is rolled back. All outstanding pages are invalidated
// ** and their memory is freed. Any attempt to use a page associated
// ** with this page cache after this function returns will likely
// ** result in a coredump.
// **
// ** This function always succeeds. If a transaction is active an attempt
// ** is made to roll it back. If an error occurs during the rollback
// ** a hot journal may be left in the filesystem but no error is returned
// ** to the caller.
// */
func _sqlite3PagerClose(tls *libc.TLS, pPager uintptr, db uintptr) (r int32) {
var a, pTmp uintptr
_, _ = a, pTmp
pTmp = (*TPager)(unsafe.Pointer(pPager)).FpTmpSpace
_sqlite3BeginBenignMalloc(tls)
_pagerFreeMapHdrs(tls, pPager)
/* pPager->errCode = 0; */
(*TPager)(unsafe.Pointer(pPager)).FexclusiveMode = uint8(0)
a = uintptr(0)
if db != 0 && uint64(0) == (*Tsqlite3)(unsafe.Pointer(db)).Fflags&uint64(SQLITE_NoCkptOnClose) && SQLITE_OK == _databaseIsUnmoved(tls, pPager) {
a = pTmp
}
_sqlite3WalClose(tls, (*TPager)(unsafe.Pointer(pPager)).FpWal, db, libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FwalSyncFlags), int32((*TPager)(unsafe.Pointer(pPager)).FpageSize), a)
(*TPager)(unsafe.Pointer(pPager)).FpWal = uintptr(0)
_pager_reset(tls, pPager)
if (*TPager)(unsafe.Pointer(pPager)).FmemDb != 0 {
_pager_unlock(tls, pPager)
} else {
/* If it is open, sync the journal file before calling UnlockAndRollback.
** If this is not done, then an unsynced portion of the open journal
** file may be played back into the database. If a power failure occurs
** while this is happening, the database could become corrupt.
**
** If an error occurs while trying to sync the journal, shift the pager
** into the ERROR state. This causes UnlockAndRollback to unlock the
** database and close the journal file without attempting to roll it
** back or finalize it. The next database user will have to do hot-journal
** rollback before accessing the database file.
*/
if (*Tsqlite3_file)(unsafe.Pointer((*TPager)(unsafe.Pointer(pPager)).Fjfd)).FpMethods != uintptr(0) {
_pager_error(tls, pPager, _pagerSyncHotJournal(tls, pPager))
}
_pagerUnlockAndRollback(tls, pPager)
}
_sqlite3EndBenignMalloc(tls)
_sqlite3OsClose(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd)
_sqlite3OsClose(tls, (*TPager)(unsafe.Pointer(pPager)).Ffd)
_sqlite3PageFree(tls, pTmp)
_sqlite3PcacheClose(tls, (*TPager)(unsafe.Pointer(pPager)).FpPCache)
Xsqlite3_free(tls, pPager)
return SQLITE_OK
}
// C documentation
//
// /*
// ** This function is called to close the connection to the log file prior
// ** to switching from WAL to rollback mode.
// **
// ** Before closing the log file, this function attempts to take an
// ** EXCLUSIVE lock on the database file. If this cannot be obtained, an
// ** error (SQLITE_BUSY) is returned and the log connection is not closed.
// ** If successful, the EXCLUSIVE lock is not released before returning.
// */
func _sqlite3PagerCloseWal(tls *libc.TLS, pPager uintptr, db uintptr) (r int32) {
bp := tls.Alloc(16)
defer tls.Free(16)
var rc int32
var _ /* logexists at bp+0 */ int32
_ = rc
rc = SQLITE_OK
/* If the log file is not already open, but does exist in the file-system,
** it may need to be checkpointed before the connection can switch to
** rollback mode. Open it now so this can happen.
*/
if !((*TPager)(unsafe.Pointer(pPager)).FpWal != 0) {
**(**int32)(__ccgo_up(bp)) = 0
rc = _pagerLockDb(tls, pPager, int32(SHARED_LOCK))
if rc == SQLITE_OK {
rc = _sqlite3OsAccess(tls, (*TPager)(unsafe.Pointer(pPager)).FpVfs, (*TPager)(unsafe.Pointer(pPager)).FzWal, SQLITE_ACCESS_EXISTS, bp)
}
if rc == SQLITE_OK && **(**int32)(__ccgo_up(bp)) != 0 {
rc = _pagerOpenWal(tls, pPager)
}
}
/* Checkpoint and close the log. Because an EXCLUSIVE lock is held on
** the database file, the log and log-summary files will be deleted.
*/
if rc == SQLITE_OK && (*TPager)(unsafe.Pointer(pPager)).FpWal != 0 {
rc = _pagerExclusiveLock(tls, pPager)
if rc == SQLITE_OK {
rc = _sqlite3WalClose(tls, (*TPager)(unsafe.Pointer(pPager)).FpWal, db, libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FwalSyncFlags), int32((*TPager)(unsafe.Pointer(pPager)).FpageSize), (*TPager)(unsafe.Pointer(pPager)).FpTmpSpace)
(*TPager)(unsafe.Pointer(pPager)).FpWal = uintptr(0)
_pagerFixMaplimit(tls, pPager)
if rc != 0 && !((*TPager)(unsafe.Pointer(pPager)).FexclusiveMode != 0) {
_pagerUnlockDb(tls, pPager, int32(SHARED_LOCK))
}
}
}
return rc
}
// C documentation
//
// /*
// ** Sync the database file for the pager pPager. zSuper points to the name
// ** of a super-journal file that should be written into the individual
// ** journal file. zSuper may be NULL, which is interpreted as no
// ** super-journal (a single database transaction).
// **
// ** This routine ensures that:
// **
// ** * The database file change-counter is updated,
// ** * the journal is synced (unless the atomic-write optimization is used),
// ** * all dirty pages are written to the database file,
// ** * the database file is truncated (if required), and
// ** * the database file synced.
// **
// ** The only thing that remains to commit the transaction is to finalize
// ** (delete, truncate or zero the first part of) the journal file (or
// ** delete the super-journal file if specified).
// **
// ** Note that if zSuper==NULL, this does not overwrite a previous value
// ** passed to an sqlite3PagerCommitPhaseOne() call.
// **
// ** If the final parameter - noSync - is true, then the database file itself
// ** is not synced. The caller must call sqlite3PagerSync() directly to
// ** sync the database file before calling CommitPhaseTwo() to delete the
// ** journal file in this case.
// */
func _sqlite3PagerCommitPhaseOne(tls *libc.TLS, pPager uintptr, zSuper uintptr, noSync int32) (r int32) {
bp := tls.Alloc(16)
defer tls.Free(16)
var nNew TPgno
var pList uintptr
var rc int32
var _ /* pPageOne at bp+0 */ uintptr
_, _, _ = nNew, pList, rc
rc = SQLITE_OK /* Return code */
/* If a prior error occurred, report that error again. */
if (*TPager)(unsafe.Pointer(pPager)).FerrCode != 0 {
return (*TPager)(unsafe.Pointer(pPager)).FerrCode
}
/* Provide the ability to easily simulate an I/O error during testing */
if _sqlite3FaultSim(tls, int32(400)) != 0 {
return int32(SQLITE_IOERR)
}
/* If no database changes have been made, return early. */
if libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FeState) < int32(PAGER_WRITER_CACHEMOD) {
return SQLITE_OK
}
if 0 == _pagerFlushOnCommit(tls, pPager, int32(1)) {
/* If this is an in-memory db, or no pages have been written to, or this
** function has already been called, it is mostly a no-op. However, any
** backup in progress needs to be restarted. */
_sqlite3BackupRestart(tls, (*TPager)(unsafe.Pointer(pPager)).FpBackup)
} else {
if (*TPager)(unsafe.Pointer(pPager)).FpWal != uintptr(0) {
**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
pList = _sqlite3PcacheDirtyList(tls, (*TPager)(unsafe.Pointer(pPager)).FpPCache)
if pList == uintptr(0) {
/* Must have at least one page for the WAL commit flag.
** Ticket [2d1a5c67dfc2363e44f29d9bbd57f] 2011-05-18 */
rc = _sqlite3PagerGet(tls, pPager, uint32(1), bp, 0)
pList = **(**uintptr)(__ccgo_up(bp))
(*TPgHdr)(unsafe.Pointer(pList)).FpDirty = uintptr(0)
}
if pList != 0 {
rc = _pagerWalFrames(tls, pPager, pList, (*TPager)(unsafe.Pointer(pPager)).FdbSize, int32(1))
}
_sqlite3PagerUnref(tls, **(**uintptr)(__ccgo_up(bp)))
if rc == SQLITE_OK {
_sqlite3PcacheCleanAll(tls, (*TPager)(unsafe.Pointer(pPager)).FpPCache)
}
} else {
/* The bBatch boolean is true if the batch-atomic-write commit method
** should be used. No rollback journal is created if batch-atomic-write
** is enabled.
*/
rc = _pager_incr_changecounter(tls, pPager, 0)
if rc != SQLITE_OK {
goto commit_phase_one_exit
}
/* Write the super-journal name into the journal file. If a
** super-journal file name has already been written to the journal file,
** or if zSuper is NULL (no super-journal), then this call is a no-op.
*/
rc = _writeSuperJournal(tls, pPager, zSuper)
if rc != SQLITE_OK {
goto commit_phase_one_exit
}
/* Sync the journal file and write all dirty pages to the database.
** If the atomic-update optimization is being used, this sync will not
** create the journal file or perform any real IO.
**
** Because the change-counter page was just modified, unless the
** atomic-update optimization is used it is almost certain that the
** journal requires a sync here. However, in locking_mode=exclusive
** on a system under memory pressure it is just possible that this is
** not the case. In this case it is likely enough that the redundant
** xSync() call will be changed to a no-op by the OS anyhow.
*/
rc = _syncJournal(tls, pPager, 0)
if rc != SQLITE_OK {
goto commit_phase_one_exit
}
pList = _sqlite3PcacheDirtyList(tls, (*TPager)(unsafe.Pointer(pPager)).FpPCache)
if true {
rc = _pager_write_pagelist(tls, pPager, pList)
}
if rc != SQLITE_OK {
goto commit_phase_one_exit
}
_sqlite3PcacheCleanAll(tls, (*TPager)(unsafe.Pointer(pPager)).FpPCache)
/* If the file on disk is smaller than the database image, use
** pager_truncate to grow the file here. This can happen if the database
** image was extended as part of the current transaction and then the
** last page in the db image moved to the free-list. In this case the
** last page is never written out to disk, leaving the database file
** undersized. Fix this now if it is the case. */
if (*TPager)(unsafe.Pointer(pPager)).FdbSize > (*TPager)(unsafe.Pointer(pPager)).FdbFileSize {
nNew = (*TPager)(unsafe.Pointer(pPager)).FdbSize - libc.BoolUint32((*TPager)(unsafe.Pointer(pPager)).FdbSize == (*TPager)(unsafe.Pointer(pPager)).FlckPgno)
rc = _pager_truncate(tls, pPager, nNew)
if rc != SQLITE_OK {
goto commit_phase_one_exit
}
}
/* Finally, sync the database file. */
if !(noSync != 0) {
rc = _sqlite3PagerSync(tls, pPager, zSuper)
}
}
}
goto commit_phase_one_exit
commit_phase_one_exit:
;
if rc == SQLITE_OK && !((*TPager)(unsafe.Pointer(pPager)).FpWal != libc.UintptrFromInt32(0)) {
(*TPager)(unsafe.Pointer(pPager)).FeState = uint8(PAGER_WRITER_FINISHED)
}
return rc
}
// C documentation
//
// /*
// ** When this function is called, the database file has been completely
// ** updated to reflect the changes made by the current transaction and
// ** synced to disk. The journal file still exists in the file-system
// ** though, and if a failure occurs at this point it will eventually
// ** be used as a hot-journal and the current transaction rolled back.
// **
// ** This function finalizes the journal file, either by deleting,
// ** truncating or partially zeroing it, so that it cannot be used
// ** for hot-journal rollback. Once this is done the transaction is
// ** irrevocably committed.
// **
// ** If an error occurs, an IO error code is returned and the pager
// ** moves into the error state. Otherwise, SQLITE_OK is returned.
// */
func _sqlite3PagerCommitPhaseTwo(tls *libc.TLS, pPager uintptr) (r int32) {
var rc int32
_ = rc
rc = SQLITE_OK /* Return code */
/* This routine should not be called if a prior error has occurred.
** But if (due to a coding error elsewhere in the system) it does get
** called, just return the same error code without doing anything. */
if (*TPager)(unsafe.Pointer(pPager)).FerrCode != 0 {
return (*TPager)(unsafe.Pointer(pPager)).FerrCode
}
(*TPager)(unsafe.Pointer(pPager)).FiDataVersion = (*TPager)(unsafe.Pointer(pPager)).FiDataVersion + 1
/* An optimization. If the database was not actually modified during
** this transaction, the pager is running in exclusive-mode and is
** using persistent journals, then this function is a no-op.
**
** The start of the journal file currently contains a single journal
** header with the nRec field set to 0. If such a journal is used as
** a hot-journal during hot-journal rollback, 0 changes will be made
** to the database file. So there is no need to zero the journal
** header. Since the pager is in exclusive mode, there is no need
** to drop any locks either.
*/
if libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FeState) == int32(PAGER_WRITER_LOCKED) && (*TPager)(unsafe.Pointer(pPager)).FexclusiveMode != 0 && libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FjournalMode) == int32(PAGER_JOURNALMODE_PERSIST) {
(*TPager)(unsafe.Pointer(pPager)).FeState = uint8(PAGER_READER)
return SQLITE_OK
}
rc = _pager_end_transaction(tls, pPager, libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FsetSuper), int32(1))
return _pager_error(tls, pPager, rc)
}
// C documentation
//
// /*
// ** Return the current journal mode.
// */
func _sqlite3PagerGetJournalMode(tls *libc.TLS, pPager uintptr) (r int32) {
return libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FjournalMode)
}
// C documentation
//
// /*
// ** Get/set the locking-mode for this pager. Parameter eMode must be one
// ** of PAGER_LOCKINGMODE_QUERY, PAGER_LOCKINGMODE_NORMAL or
// ** PAGER_LOCKINGMODE_EXCLUSIVE. If the parameter is not _QUERY, then
// ** the locking-mode is set to the value specified.
// **
// ** The returned value is either PAGER_LOCKINGMODE_NORMAL or
// ** PAGER_LOCKINGMODE_EXCLUSIVE, indicating the current (possibly updated)
// ** locking-mode.
// */
func _sqlite3PagerLockingMode(tls *libc.TLS, pPager uintptr, eMode int32) (r int32) {
if eMode >= 0 && !((*TPager)(unsafe.Pointer(pPager)).FtempFile != 0) && !(_sqlite3WalHeapMemory(tls, (*TPager)(unsafe.Pointer(pPager)).FpWal) != 0) {
(*TPager)(unsafe.Pointer(pPager)).FexclusiveMode = libc.Uint8FromInt32(eMode)
}
return libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FexclusiveMode)
}
// C documentation
//
// /*
// ** Return TRUE if the pager is in a state where it is OK to change the
// ** journalmode. Journalmode changes can only happen when the database
// ** is unmodified.
// */
func _sqlite3PagerOkToChangeJournalMode(tls *libc.TLS, pPager uintptr) (r int32) {
if libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FeState) >= int32(PAGER_WRITER_CACHEMOD) {
return 0
}
if (*Tsqlite3_file)(unsafe.Pointer((*TPager)(unsafe.Pointer(pPager)).Fjfd)).FpMethods != uintptr(0) && (*TPager)(unsafe.Pointer(pPager)).FjournalOff > 0 {
return 0
}
return int32(1)
}
// C documentation
//
// /*
// ** This function may only be called when a read-transaction is open on
// ** the pager. It returns the total number of pages in the database.
// **
// ** However, if the file is between 1 and <page-size> bytes in size, then
// ** this is considered a 1 page file.
// */
func _sqlite3PagerPagecount(tls *libc.TLS, pPager uintptr, pnPage uintptr) {
**(**int32)(__ccgo_up(pnPage)) = libc.Int32FromUint32((*TPager)(unsafe.Pointer(pPager)).FdbSize)
}
// C documentation
//
// /*
// ** If a write transaction is open, then all changes made within the
// ** transaction are reverted and the current write-transaction is closed.
// ** The pager falls back to PAGER_READER state if successful, or PAGER_ERROR
// ** state if an error occurs.
// **
// ** If the pager is already in PAGER_ERROR state when this function is called,
// ** it returns Pager.errCode immediately. No work is performed in this case.
// **
// ** Otherwise, in rollback mode, this function performs two functions:
// **
// ** 1) It rolls back the journal file, restoring all database file and
// ** in-memory cache pages to the state they were in when the transaction
// ** was opened, and
// **
// ** 2) It finalizes the journal file, so that it is not used for hot
// ** rollback at any point in the future.
// **
// ** Finalization of the journal file (task 2) is only performed if the
// ** rollback is successful.
// **
// ** In WAL mode, all cache-entries containing data modified within the
// ** current transaction are either expelled from the cache or reverted to
// ** their pre-transaction state by re-reading data from the database or
// ** WAL files. The WAL transaction is then closed.
// */
func _sqlite3PagerRollback(tls *libc.TLS, pPager uintptr) (r int32) {
var eState, rc, rc2 int32
_, _, _ = eState, rc, rc2
rc = SQLITE_OK /* Return code */
/* PagerRollback() is a no-op if called in READER or OPEN state. If
** the pager is already in the ERROR state, the rollback is not
** attempted here. Instead, the error code is returned to the caller.
*/
if libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FeState) == int32(PAGER_ERROR) {
return (*TPager)(unsafe.Pointer(pPager)).FerrCode
}
if libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FeState) <= int32(PAGER_READER) {
return SQLITE_OK
}
if (*TPager)(unsafe.Pointer(pPager)).FpWal != uintptr(0) {
rc = _sqlite3PagerSavepoint(tls, pPager, int32(SAVEPOINT_ROLLBACK), -int32(1))
rc2 = _pager_end_transaction(tls, pPager, libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FsetSuper), 0)
if rc == SQLITE_OK {
rc = rc2
}
} else {
if !((*Tsqlite3_file)(unsafe.Pointer((*TPager)(unsafe.Pointer(pPager)).Fjfd)).FpMethods != libc.UintptrFromInt32(0)) || libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FeState) == int32(PAGER_WRITER_LOCKED) {
eState = libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FeState)
rc = _pager_end_transaction(tls, pPager, 0, 0)
if !((*TPager)(unsafe.Pointer(pPager)).FmemDb != 0) && eState > int32(PAGER_WRITER_LOCKED) {
/* This can happen using journal_mode=off. Move the pager to the error
** state to indicate that the contents of the cache may not be trusted.
** Any active readers will get SQLITE_ABORT.
*/
(*TPager)(unsafe.Pointer(pPager)).FerrCode = int32(SQLITE_ABORT)
(*TPager)(unsafe.Pointer(pPager)).FeState = uint8(PAGER_ERROR)
_setGetterMethod(tls, pPager)
return rc
}
} else {
rc = _pager_playback(tls, pPager, 0)
}
}
/* If an error occurs during a ROLLBACK, we can no longer trust the pager
** cache. So call pager_error() on the way out to make any error persistent.
*/
return _pager_error(tls, pPager, rc)
}
// C documentation
//
// /*
// ** Set the journal-mode for this pager. Parameter eMode must be one of:
// **
// ** PAGER_JOURNALMODE_DELETE
// ** PAGER_JOURNALMODE_TRUNCATE
// ** PAGER_JOURNALMODE_PERSIST
// ** PAGER_JOURNALMODE_OFF
// ** PAGER_JOURNALMODE_MEMORY
// ** PAGER_JOURNALMODE_WAL
// **
// ** The journalmode is set to the value specified if the change is allowed.
// ** The change may be disallowed for the following reasons:
// **
// ** * An in-memory database can only have its journal_mode set to _OFF
// ** or _MEMORY.
// **
// ** * Temporary databases cannot have _WAL journalmode.
// **
// ** The returned indicate the current (possibly updated) journal-mode.
// */
func _sqlite3PagerSetJournalMode(tls *libc.TLS, pPager uintptr, eMode int32) (r int32) {
var eOld Tu8
var rc, state int32
_, _, _ = eOld, rc, state
eOld = (*TPager)(unsafe.Pointer(pPager)).FjournalMode /* Prior journalmode */
/* The eMode parameter is always valid */
/* This routine is only called from the OP_JournalMode opcode, and
** the logic there will never allow a temporary file to be changed
** to WAL mode.
*/
/* Do allow the journalmode of an in-memory database to be set to
** anything other than MEMORY or OFF
*/
if (*TPager)(unsafe.Pointer(pPager)).FmemDb != 0 {
if eMode != int32(PAGER_JOURNALMODE_MEMORY) && eMode != int32(PAGER_JOURNALMODE_OFF) {
eMode = libc.Int32FromUint8(eOld)
}
}
if eMode != libc.Int32FromUint8(eOld) {
/* Change the journal mode. */
(*TPager)(unsafe.Pointer(pPager)).FjournalMode = libc.Uint8FromInt32(eMode)
/* When transitioning from TRUNCATE or PERSIST to any other journal
** mode except WAL, unless the pager is in locking_mode=exclusive mode,
** delete the journal file.
*/
if !((*TPager)(unsafe.Pointer(pPager)).FexclusiveMode != 0) && libc.Int32FromUint8(eOld)&int32(5) == int32(1) && eMode&int32(1) == 0 {
/* In this case we would like to delete the journal file. If it is
** not possible, then that is not a problem. Deleting the journal file
** here is an optimization only.
**
** Before deleting the journal file, obtain a RESERVED lock on the
** database file. This ensures that the journal file is not deleted
** while it is in use by some other client.
*/
_sqlite3OsClose(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd)
if libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FeLock) >= int32(RESERVED_LOCK) {
_sqlite3OsDelete(tls, (*TPager)(unsafe.Pointer(pPager)).FpVfs, (*TPager)(unsafe.Pointer(pPager)).FzJournal, 0)
} else {
rc = SQLITE_OK
state = libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FeState)
if state == PAGER_OPEN {
rc = _sqlite3PagerSharedLock(tls, pPager)
}
if libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FeState) == int32(PAGER_READER) {
rc = _pagerLockDb(tls, pPager, int32(RESERVED_LOCK))
}
if rc == SQLITE_OK {
_sqlite3OsDelete(tls, (*TPager)(unsafe.Pointer(pPager)).FpVfs, (*TPager)(unsafe.Pointer(pPager)).FzJournal, 0)
}
if rc == SQLITE_OK && state == int32(PAGER_READER) {
_pagerUnlockDb(tls, pPager, int32(SHARED_LOCK))
} else {
if state == PAGER_OPEN {
_pager_unlock(tls, pPager)
}
}
}
} else {
if eMode == int32(PAGER_JOURNALMODE_OFF) || eMode == int32(PAGER_JOURNALMODE_MEMORY) {
_sqlite3OsClose(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd)
}
}
}
/* Return the new journal mode */
return libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FjournalMode)
}
// C documentation
//
// /*
// ** Sync the database file to disk. This is a no-op for in-memory databases
// ** or pages with the Pager.noSync flag set.
// **
// ** If successful, or if called on a pager for which it is a no-op, this
// ** function returns SQLITE_OK. Otherwise, an IO error code is returned.
// */
func _sqlite3PagerSync(tls *libc.TLS, pPager uintptr, zSuper uintptr) (r int32) {
var pArg uintptr
var rc int32
_, _ = pArg, rc
rc = SQLITE_OK
pArg = zSuper
rc = _sqlite3OsFileControl(tls, (*TPager)(unsafe.Pointer(pPager)).Ffd, int32(SQLITE_FCNTL_SYNC), pArg)
if rc == int32(SQLITE_NOTFOUND) {
rc = SQLITE_OK
}
if rc == SQLITE_OK && !((*TPager)(unsafe.Pointer(pPager)).FnoSync != 0) {
rc = _sqlite3OsSync(tls, (*TPager)(unsafe.Pointer(pPager)).Ffd, libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FsyncFlags))
}
return rc
}
// C documentation
//
// /*
// ** Release a page reference.
// **
// ** The sqlite3PagerUnref() and sqlite3PagerUnrefNotNull() may only be used
// ** if we know that the page being released is not the last reference to page1.
// ** The btree layer always holds page1 open until the end, so these first
// ** two routines can be used to release any page other than BtShared.pPage1.
// ** The assert() at tag-20230419-2 proves that this constraint is always
// ** honored.
// **
// ** Use sqlite3PagerUnrefPageOne() to release page1. This latter routine
// ** checks the total number of outstanding pages and if the number of
// ** pages reaches zero it drops the database lock.
// */
func _sqlite3PagerUnrefNotNull(tls *libc.TLS, pPg uintptr) {
if libc.Int32FromUint16((*TDbPage)(unsafe.Pointer(pPg)).Fflags)&int32(PGHDR_MMAP) != 0 {
/* Page1 is never memory mapped */
_pagerReleaseMapPage(tls, pPg)
} else {
_sqlite3PcacheRelease(tls, pPg)
}
/* Do not use this routine to release the last reference to page1 */
/* tag-20230419-2 */
}
// C documentation
//
// /*
// ** Mark a data page as writeable. This routine must be called before
// ** making changes to a page. The caller must check the return value
// ** of this function and be careful not to change any page data unless
// ** this routine returns SQLITE_OK.
// **
// ** The difference between this function and pager_write() is that this
// ** function also deals with the special case where 2 or more pages
// ** fit on a single disk sector. In this case all co-resident pages
// ** must have been written to the journal file before returning.
// **
// ** If an error occurs, SQLITE_NOMEM or an IO error code is returned
// ** as appropriate. Otherwise, SQLITE_OK.
// */
func _sqlite3PagerWrite(tls *libc.TLS, pPg uintptr) (r int32) {
var pPager uintptr
_ = pPager
pPager = (*TPgHdr)(unsafe.Pointer(pPg)).FpPager
if libc.Int32FromUint16((*TPgHdr)(unsafe.Pointer(pPg)).Fflags)&int32(PGHDR_WRITEABLE) != 0 && (*TPager)(unsafe.Pointer(pPager)).FdbSize >= (*TPgHdr)(unsafe.Pointer(pPg)).Fpgno {
if (*TPager)(unsafe.Pointer(pPager)).FnSavepoint != 0 {
return _subjournalPageIfRequired(tls, pPg)
}
return SQLITE_OK
} else {
if (*TPager)(unsafe.Pointer(pPager)).FerrCode != 0 {
return (*TPager)(unsafe.Pointer(pPager)).FerrCode
} else {
if (*TPager)(unsafe.Pointer(pPager)).FsectorSize > libc.Uint32FromInt64((*TPager)(unsafe.Pointer(pPager)).FpageSize) {
return _pagerWriteLargeSector(tls, pPg)
} else {
return _pager_write(tls, pPg)
}
}
}
return r
}
/*
** Return TRUE if the page given in the argument was previously passed
** to sqlite3PagerWrite(). In other words, return TRUE if it is ok
** to change the content of the page.
*/
// C documentation
//
// /*
// ** Free all memory allocations in the pParse object
// */
func _sqlite3ParseObjectReset(tls *libc.TLS, pParse uintptr) {
var db, pCleanup uintptr
var v1 int32
_, _, _ = db, pCleanup, v1
db = (*TParse)(unsafe.Pointer(pParse)).Fdb
if (*TParse)(unsafe.Pointer(pParse)).FaTableLock != 0 {
_sqlite3DbNNFreeNN(tls, db, (*TParse)(unsafe.Pointer(pParse)).FaTableLock)
}
for (*TParse)(unsafe.Pointer(pParse)).FpCleanup != 0 {
pCleanup = (*TParse)(unsafe.Pointer(pParse)).FpCleanup
(*TParse)(unsafe.Pointer(pParse)).FpCleanup = (*TParseCleanup)(unsafe.Pointer(pCleanup)).FpNext
(*(*func(*libc.TLS, uintptr, uintptr))(unsafe.Pointer(&struct{ uintptr }{(*TParseCleanup)(unsafe.Pointer(pCleanup)).FxCleanup})))(tls, db, (*TParseCleanup)(unsafe.Pointer(pCleanup)).FpPtr)
_sqlite3DbNNFreeNN(tls, db, pCleanup)
}
if (*TParse)(unsafe.Pointer(pParse)).FaLabel != 0 {
_sqlite3DbNNFreeNN(tls, db, (*TParse)(unsafe.Pointer(pParse)).FaLabel)
}
if (*TParse)(unsafe.Pointer(pParse)).FpConstExpr != 0 {
_sqlite3ExprListDelete(tls, db, (*TParse)(unsafe.Pointer(pParse)).FpConstExpr)
}
(*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FbDisable -= uint32((*TParse)(unsafe.Pointer(pParse)).FdisableLookaside)
if (*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FbDisable != 0 {
v1 = 0
} else {
v1 = libc.Int32FromUint16((*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FszTrue)
}
(*Tsqlite3)(unsafe.Pointer(db)).Flookaside.Fsz = libc.Uint16FromInt32(v1)
(*Tsqlite3)(unsafe.Pointer(db)).FpParse = (*TParse)(unsafe.Pointer(pParse)).FpOuterParse
}
// C documentation
//
// /*
// ** Return the fallback token corresponding to canonical token iToken, or
// ** 0 if iToken has no fallback.
// */
func _sqlite3ParserFallback(tls *libc.TLS, iToken int32) (r int32) {
return libc.Int32FromUint16(_yyFallback[iToken])
}
/************** End of parse.c ***********************************************/
/************** Begin file tokenize.c ****************************************/
/*
** 2001 September 15
**
** 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.
**
*************************************************************************
** An tokenizer for SQL
**
** This file contains C code that splits an SQL input string up into
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
*/
/* #include "sqliteInt.h" */
/* #include <stdlib.h> */
/* Character classes for tokenizing
**
** In the sqlite3GetToken() function, a switch() on aiClass[c] is implemented
** using a lookup table, whereas a switch() directly on c uses a binary search.
** The lookup table is much faster. To maximize speed, and to ensure that
** a lookup table is used, all of the classes need to be small integers and
** all of them need to be used within the switch.
*/
// C documentation
//
// /*
// ** Drop a page from the cache. There must be exactly one reference to the
// ** page. This function deletes that reference, so after it returns the
// ** page pointed to by p is invalid.
// */
func _sqlite3PcacheDrop(tls *libc.TLS, p uintptr) {
if libc.Int32FromUint16((*TPgHdr)(unsafe.Pointer(p)).Fflags)&int32(PGHDR_DIRTY) != 0 {
_pcacheManageDirtyList(tls, p, uint8(PCACHE_DIRTYLIST_REMOVE))
}
(*TPCache)(unsafe.Pointer((*TPgHdr)(unsafe.Pointer(p)).FpCache)).FnRefSum = (*TPCache)(unsafe.Pointer((*TPgHdr)(unsafe.Pointer(p)).FpCache)).FnRefSum - 1
(*(*func(*libc.TLS, uintptr, uintptr, int32))(unsafe.Pointer(&struct{ uintptr }{_sqlite3Config.Fpcache2.FxUnpin})))(tls, (*TPCache)(unsafe.Pointer((*TPgHdr)(unsafe.Pointer(p)).FpCache)).FpCache, (*TPgHdr)(unsafe.Pointer(p)).FpPage, int32(1))
}
// C documentation
//
// /*
// ** Try to obtain a page from the cache.
// **
// ** This routine returns a pointer to an sqlite3_pcache_page object if
// ** such an object is already in cache, or if a new one is created.
// ** This routine returns a NULL pointer if the object was not in cache
// ** and could not be created.
// **
// ** The createFlags should be 0 to check for existing pages and should
// ** be 3 (not 1, but 3) to try to create a new page.
// **
// ** If the createFlag is 0, then NULL is always returned if the page
// ** is not already in the cache. If createFlag is 1, then a new page
// ** is created only if that can be done without spilling dirty pages
// ** and without exceeding the cache size limit.
// **
// ** The caller needs to invoke sqlite3PcacheFetchFinish() to properly
// ** initialize the sqlite3_pcache_page object and convert it into a
// ** PgHdr object. The sqlite3PcacheFetch() and sqlite3PcacheFetchFinish()
// ** routines are split this way for performance reasons. When separated
// ** they can both (usually) operate without having to push values to
// ** the stack on entry and pop them back off on exit, which saves a
// ** lot of pushing and popping.
// */
func _sqlite3PcacheFetch(tls *libc.TLS, pCache uintptr, pgno TPgno, createFlag int32) (r uintptr) {
var eCreate int32
var pRes uintptr
_, _ = eCreate, pRes
/* eCreate defines what to do if the page does not exist.
** 0 Do not allocate a new page. (createFlag==0)
** 1 Allocate a new page if doing so is inexpensive.
** (createFlag==1 AND bPurgeable AND pDirty)
** 2 Allocate a new page even it doing so is difficult.
** (createFlag==1 AND !(bPurgeable AND pDirty)
*/
eCreate = createFlag & libc.Int32FromUint8((*TPCache)(unsafe.Pointer(pCache)).FeCreate)
pRes = (*(*func(*libc.TLS, uintptr, uint32, int32) uintptr)(unsafe.Pointer(&struct{ uintptr }{_sqlite3Config.Fpcache2.FxFetch})))(tls, (*TPCache)(unsafe.Pointer(pCache)).FpCache, pgno, eCreate)
return pRes
}
// C documentation
//
// /*
// ** If the sqlite3PcacheFetch() routine is unable to allocate a new
// ** page because no clean pages are available for reuse and the cache
// ** size limit has been reached, then this routine can be invoked to
// ** try harder to allocate a page. This routine might invoke the stress
// ** callback to spill dirty pages to the journal. It will then try to
// ** allocate the new page and will only fail to allocate a new page on
// ** an OOM error.
// **
// ** This routine should be invoked only after sqlite3PcacheFetch() fails.
// */
func _sqlite3PcacheFetchStress(tls *libc.TLS, pCache uintptr, pgno TPgno, ppPage uintptr) (r int32) {
var pPg uintptr
var rc, v3 int32
_, _, _ = pPg, rc, v3
if libc.Int32FromUint8((*TPCache)(unsafe.Pointer(pCache)).FeCreate) == int32(2) {
return 0
}
if _sqlite3PcachePagecount(tls, pCache) > (*TPCache)(unsafe.Pointer(pCache)).FszSpill {
/* Find a dirty page to write-out and recycle. First try to find a
** page that does not require a journal-sync (one with PGHDR_NEED_SYNC
** cleared), but if that is not possible settle for any other
** unreferenced dirty page.
**
** If the LRU page in the dirty list that has a clear PGHDR_NEED_SYNC
** flag is currently referenced, then the following may leave pSynced
** set incorrectly (pointing to other than the LRU page with NEED_SYNC
** cleared). This is Ok, as pSynced is just an optimization. */
pPg = (*TPCache)(unsafe.Pointer(pCache)).FpSynced
for {
if !(pPg != 0 && ((*TPgHdr)(unsafe.Pointer(pPg)).FnRef != 0 || libc.Int32FromUint16((*TPgHdr)(unsafe.Pointer(pPg)).Fflags)&int32(PGHDR_NEED_SYNC) != 0)) {
break
}
goto _1
_1:
;
pPg = (*TPgHdr)(unsafe.Pointer(pPg)).FpDirtyPrev
}
(*TPCache)(unsafe.Pointer(pCache)).FpSynced = pPg
if !(pPg != 0) {
pPg = (*TPCache)(unsafe.Pointer(pCache)).FpDirtyTail
for {
if !(pPg != 0 && (*TPgHdr)(unsafe.Pointer(pPg)).FnRef != 0) {
break
}
goto _2
_2:
;
pPg = (*TPgHdr)(unsafe.Pointer(pPg)).FpDirtyPrev
}
}
if pPg != 0 {
rc = (*(*func(*libc.TLS, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*TPCache)(unsafe.Pointer(pCache)).FxStress})))(tls, (*TPCache)(unsafe.Pointer(pCache)).FpStress, pPg)
if rc != SQLITE_OK && rc != int32(SQLITE_BUSY) {
return rc
}
}
}
**(**uintptr)(__ccgo_up(ppPage)) = (*(*func(*libc.TLS, uintptr, uint32, int32) uintptr)(unsafe.Pointer(&struct{ uintptr }{_sqlite3Config.Fpcache2.FxFetch})))(tls, (*TPCache)(unsafe.Pointer(pCache)).FpCache, pgno, int32(2))
if **(**uintptr)(__ccgo_up(ppPage)) == uintptr(0) {
v3 = int32(SQLITE_NOMEM)
} else {
v3 = SQLITE_OK
}
return v3
}
// C documentation
//
// /*
// ** Change the page number of page p to newPgno.
// */
func _sqlite3PcacheMove(tls *libc.TLS, p uintptr, newPgno TPgno) {
var pCache, pOther, pXPage uintptr
_, _, _ = pCache, pOther, pXPage
pCache = (*TPgHdr)(unsafe.Pointer(p)).FpCache
pOther = (*(*func(*libc.TLS, uintptr, uint32, int32) uintptr)(unsafe.Pointer(&struct{ uintptr }{_sqlite3Config.Fpcache2.FxFetch})))(tls, (*TPCache)(unsafe.Pointer(pCache)).FpCache, newPgno, 0)
if pOther != 0 {
pXPage = (*Tsqlite3_pcache_page)(unsafe.Pointer(pOther)).FpExtra
(*TPgHdr)(unsafe.Pointer(pXPage)).FnRef = (*TPgHdr)(unsafe.Pointer(pXPage)).FnRef + 1
(*TPCache)(unsafe.Pointer(pCache)).FnRefSum = (*TPCache)(unsafe.Pointer(pCache)).FnRefSum + 1
_sqlite3PcacheDrop(tls, pXPage)
}
(*(*func(*libc.TLS, uintptr, uintptr, uint32, uint32))(unsafe.Pointer(&struct{ uintptr }{_sqlite3Config.Fpcache2.FxRekey})))(tls, (*TPCache)(unsafe.Pointer(pCache)).FpCache, (*TPgHdr)(unsafe.Pointer(p)).FpPage, (*TPgHdr)(unsafe.Pointer(p)).Fpgno, newPgno)
(*TPgHdr)(unsafe.Pointer(p)).Fpgno = newPgno
if libc.Int32FromUint16((*TPgHdr)(unsafe.Pointer(p)).Fflags)&int32(PGHDR_DIRTY) != 0 && libc.Int32FromUint16((*TPgHdr)(unsafe.Pointer(p)).Fflags)&int32(PGHDR_NEED_SYNC) != 0 {
_pcacheManageDirtyList(tls, p, uint8(PCACHE_DIRTYLIST_FRONT))
}
}
// C documentation
//
// /*
// ** This function is called to free superfluous dynamically allocated memory
// ** held by the pager system. Memory in use by any SQLite pager allocated
// ** by the current thread may be sqlite3_free()ed.
// **
// ** nReq is the number of bytes of memory required. Once this much has
// ** been released, the function returns. The return value is the total number
// ** of bytes of memory released.
// */
func _sqlite3PcacheReleaseMemory(tls *libc.TLS, nReq int32) (r int32) {
var nFree int32
var p, v1 uintptr
var v2 bool
_, _, _, _ = nFree, p, v1, v2
nFree = 0
if _sqlite3Config.FpPage == uintptr(0) {
Xsqlite3_mutex_enter(tls, (*TPGroup)(unsafe.Pointer(uintptr(unsafe.Pointer(&_pcache1_g)))).Fmutex)
for {
if v2 = nReq < 0 || nFree < nReq; v2 {
v1 = _pcache1_g.Fgrp.Flru.FpLruPrev
p = v1
}
if !(v2 && v1 != uintptr(0) && libc.Int32FromUint16((*TPgHdr1)(unsafe.Pointer(p)).FisAnchor) == 0) {
break
}
nFree = nFree + _pcache1MemSize(tls, (*TPgHdr1)(unsafe.Pointer(p)).Fpage.FpBuf)
_pcache1PinPage(tls, p)
_pcache1RemoveFromHash(tls, p, int32(1))
}
Xsqlite3_mutex_leave(tls, (*TPGroup)(unsafe.Pointer(uintptr(unsafe.Pointer(&_pcache1_g)))).Fmutex)
}
return nFree
}
/************** End of pcache1.c *********************************************/
/************** Begin file rowset.c ******************************************/
/*
** 2008 December 3
**
** 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 module implements an object we call a "RowSet".
**
** The RowSet object is a collection of rowids. Rowids
** are inserted into the RowSet in an arbitrary order. Inserts
** can be intermixed with tests to see if a given rowid has been
** previously inserted into the RowSet.
**
** After all inserts are finished, it is possible to extract the
** elements of the RowSet in sorted order. Once this extraction
** process has started, no new elements may be inserted.
**
** Hence, the primitive operations for a RowSet are:
**
** CREATE
** INSERT
** TEST
** SMALLEST
** DESTROY
**
** The CREATE and DESTROY primitives are the constructor and destructor,
** obviously. The INSERT primitive adds a new element to the RowSet.
** TEST checks to see if an element is already in the RowSet. SMALLEST
** extracts the least value from the RowSet.
**
** The INSERT primitive might allocate additional memory. Memory is
** allocated in chunks so most INSERTs do no allocation. There is an
** upper bound on the size of allocated memory. No memory is freed
** until DESTROY.
**
** The TEST primitive includes a "batch" number. The TEST primitive
** will only see elements that were inserted before the last change
** in the batch number. In other words, if an INSERT occurs between
** two TESTs where the TESTs have the same batch number, then the
** value added by the INSERT will not be visible to the second TEST.
** The initial batch number is zero, so if the very first TEST contains
** a non-zero batch number, it will see all prior INSERTs.
**
** No INSERTs may occurs after a SMALLEST. An assertion will fail if
** that is attempted.
**
** The cost of an INSERT is roughly constant. (Sometimes new memory
** has to be allocated on an INSERT.) The cost of a TEST with a new
** batch number is O(NlogN) where N is the number of elements in the RowSet.
** The cost of a TEST using the same batch number is O(logN). The cost
** of the first SMALLEST is O(NlogN). Second and subsequent SMALLEST
** primitives are constant time. The cost of DESTROY is O(N).
**
** TEST and SMALLEST may not be used by the same RowSet. This used to
** be possible, but the feature was not used, so it was removed in order
** to simplify the code.
*/
/* #include "sqliteInt.h" */
/*
** Target size for allocation chunks.
*/
/*
** The number of rowset entries per allocation chunk.
*/
// C documentation
//
// /*
// ** Check to see if zTabName is really the name of a pragma. If it is,
// ** then register an eponymous virtual table for that pragma and return
// ** a pointer to the Module object for the new virtual table.
// */
func _sqlite3PragmaVtabRegister(tls *libc.TLS, db uintptr, zName uintptr) (r uintptr) {
var pName uintptr
_ = pName
pName = _pragmaLocate(tls, zName+uintptr(7))
if pName == uintptr(0) {
return uintptr(0)
}
if libc.Int32FromUint8((*TPragmaName)(unsafe.Pointer(pName)).FmPragFlg)&(libc.Int32FromInt32(PragFlg_Result0)|libc.Int32FromInt32(PragFlg_Result1)) == 0 {
return uintptr(0)
}
return _sqlite3VtabCreateModule(tls, db, zName, uintptr(unsafe.Pointer(&_pragmaVtabModule)), pName, uintptr(0))
}
/************** End of pragma.c **********************************************/
/************** Begin file prepare.c *****************************************/
/*
** 2005 May 25
**
** 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 the implementation of the sqlite3_prepare()
** interface, and routines that contribute to loading the database schema
** from disk.
*/
/* #include "sqliteInt.h" */
// C documentation
//
// /*
// ** Change the size of an existing memory allocation
// */
func _sqlite3Realloc(tls *libc.TLS, pOld uintptr, nBytes Tu64) (r uintptr) {
var nDiff, nNew, nOld int32
var nUsed, v1 Tsqlite3_int64
var pNew uintptr
var v2 bool
_, _, _, _, _, _, _ = nDiff, nNew, nOld, nUsed, pNew, v1, v2
if pOld == uintptr(0) {
return _sqlite3Malloc(tls, nBytes) /* IMP: R-04300-56712 */
}
if nBytes == uint64(0) {
Xsqlite3_free(tls, pOld) /* IMP: R-26507-47431 */
return uintptr(0)
}
if nBytes > uint64(SQLITE_MAX_ALLOCATION_SIZE) {
return uintptr(0)
}
nOld = _sqlite3MallocSize(tls, pOld)
/* IMPLEMENTATION-OF: R-46199-30249 SQLite guarantees that the second
** argument to xRealloc is always a value returned by a prior call to
** xRoundup. */
nNew = (*(*func(*libc.TLS, int32) int32)(unsafe.Pointer(&struct{ uintptr }{_sqlite3Config.Fm.FxRoundup})))(tls, libc.Int32FromUint64(nBytes))
if nOld == nNew {
pNew = pOld
} else {
if _sqlite3Config.FbMemstat != 0 {
Xsqlite3_mutex_enter(tls, _mem0.Fmutex)
_sqlite3StatusHighwater(tls, int32(SQLITE_STATUS_MALLOC_SIZE), libc.Int32FromUint64(nBytes))
nDiff = nNew - nOld
if v2 = nDiff > 0; v2 {
v1 = _sqlite3StatusValue(tls, SQLITE_STATUS_MEMORY_USED)
nUsed = v1
}
if v2 && v1 >= _mem0.FalarmThreshold-int64(nDiff) {
_sqlite3MallocAlarm(tls, nDiff)
if _mem0.FhardLimit > 0 && nUsed >= _mem0.FhardLimit-int64(nDiff) {
Xsqlite3_mutex_leave(tls, _mem0.Fmutex)
return uintptr(0)
}
}
pNew = (*(*func(*libc.TLS, uintptr, int32) uintptr)(unsafe.Pointer(&struct{ uintptr }{_sqlite3Config.Fm.FxRealloc})))(tls, pOld, nNew)
if pNew == uintptr(0) && _mem0.FalarmThreshold > 0 {
_sqlite3MallocAlarm(tls, libc.Int32FromUint64(nBytes))
pNew = (*(*func(*libc.TLS, uintptr, int32) uintptr)(unsafe.Pointer(&struct{ uintptr }{_sqlite3Config.Fm.FxRealloc})))(tls, pOld, nNew)
}
if pNew != 0 {
nNew = _sqlite3MallocSize(tls, pNew)
_sqlite3StatusUp(tls, SQLITE_STATUS_MEMORY_USED, nNew-nOld)
}
Xsqlite3_mutex_leave(tls, _mem0.Fmutex)
} else {
pNew = (*(*func(*libc.TLS, uintptr, int32) uintptr)(unsafe.Pointer(&struct{ uintptr }{_sqlite3Config.Fm.FxRealloc})))(tls, pOld, nNew)
}
}
/* IMP: R-11148-40995 */
return pNew
}
// C documentation
//
// /*
// ** Initialize a SelectDest structure.
// */
func _sqlite3SelectDestInit(tls *libc.TLS, pDest uintptr, eDest int32, iParm int32) {
(*TSelectDest)(unsafe.Pointer(pDest)).FeDest = libc.Uint8FromInt32(eDest)
(*TSelectDest)(unsafe.Pointer(pDest)).FiSDParm = iParm
(*TSelectDest)(unsafe.Pointer(pDest)).FiSDParm2 = 0
(*TSelectDest)(unsafe.Pointer(pDest)).FzAffSdst = uintptr(0)
(*TSelectDest)(unsafe.Pointer(pDest)).FiSdst = 0
(*TSelectDest)(unsafe.Pointer(pDest)).FnSdst = 0
}
// C documentation
//
// /*
// ** Extract the iCol-th column from the nRec-byte record in pRec. Write
// ** the column value into *ppVal. If *ppVal is initially NULL then a new
// ** sqlite3_value object is allocated.
// **
// ** If *ppVal is initially NULL then the caller is responsible for
// ** ensuring that the value written into *ppVal is eventually freed.
// **
// ** If the buffer does not contain a well-formed record, this routine may
// ** read several bytes past the end of the buffer. Callers must therefore
// ** ensure that any buffer which may contain a corrupt record is padded
// ** with at least 8 bytes of addressable memory.
// */
func _sqlite3Stat4Column(tls *libc.TLS, db uintptr, pRec uintptr, nRec int32, iCol int32, ppVal uintptr) (r int32) {
bp := tls.Alloc(16)
defer tls.Free(16)
var a, pMem, v4 uintptr
var i, v1 int32
var iField Ti64
var iHdr, szField Tu32
var _ /* nHdr at bp+4 */ Tu32
var _ /* t at bp+0 */ Tu32
_, _, _, _, _, _, _, _ = a, i, iField, iHdr, pMem, szField, v1, v4
**(**Tu32)(__ccgo_up(bp)) = uint32(0) /* Next unread data byte */
szField = uint32(0) /* Column index */
a = pRec /* Typecast byte array */
pMem = **(**uintptr)(__ccgo_up(ppVal)) /* Write result into this Mem object */
if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(a))) < libc.Int32FromUint8(libc.Uint8FromInt32(0x80)) {
**(**Tu32)(__ccgo_up(bp + 4)) = uint32(**(**Tu8)(__ccgo_up(a)))
v1 = libc.Int32FromInt32(1)
} else {
v1 = libc.Int32FromUint8(_sqlite3GetVarint32(tls, a, bp+4))
}
iHdr = uint32(libc.Uint8FromInt32(v1))
if **(**Tu32)(__ccgo_up(bp + 4)) > libc.Uint32FromInt32(nRec) || iHdr >= **(**Tu32)(__ccgo_up(bp + 4)) {
return _sqlite3CorruptError(tls, int32(87782))
}
iField = libc.Int64FromUint32(**(**Tu32)(__ccgo_up(bp + 4)))
i = 0
for {
if !(i <= iCol) {
break
}
if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(a + uintptr(iHdr)))) < libc.Int32FromUint8(libc.Uint8FromInt32(0x80)) {
**(**Tu32)(__ccgo_up(bp)) = uint32(**(**Tu8)(__ccgo_up(a + uintptr(iHdr))))
v1 = libc.Int32FromInt32(1)
} else {
v1 = libc.Int32FromUint8(_sqlite3GetVarint32(tls, a+uintptr(iHdr), bp))
}
iHdr = iHdr + uint32(libc.Uint8FromInt32(v1))
if iHdr > **(**Tu32)(__ccgo_up(bp + 4)) {
return _sqlite3CorruptError(tls, int32(87788))
}
szField = _sqlite3VdbeSerialTypeLen(tls, **(**Tu32)(__ccgo_up(bp)))
iField = iField + libc.Int64FromUint32(szField)
goto _2
_2:
;
i = i + 1
}
if iField > int64(nRec) {
return _sqlite3CorruptError(tls, int32(87794))
}
if pMem == uintptr(0) {
v4 = _sqlite3ValueNew(tls, db)
**(**uintptr)(__ccgo_up(ppVal)) = v4
pMem = v4
if pMem == uintptr(0) {
return int32(SQLITE_NOMEM)
}
}
_sqlite3VdbeSerialGet(tls, a+uintptr(iField-libc.Int64FromUint32(szField)), **(**Tu32)(__ccgo_up(bp)), pMem)
(*TMem)(unsafe.Pointer(pMem)).Fenc = (*Tsqlite3)(unsafe.Pointer(db)).Fenc
return SQLITE_OK
}
func _sqlite3StrAccumEnlargeIfNeeded(tls *libc.TLS, p uintptr, N Ti64) (r int32) {
if N+libc.Int64FromUint32((*TStrAccum)(unsafe.Pointer(p)).FnChar) >= libc.Int64FromUint32((*TStrAccum)(unsafe.Pointer(p)).FnAlloc) {
_sqlite3StrAccumEnlarge(tls, p, N)
}
return libc.Int32FromUint8((*TStrAccum)(unsafe.Pointer(p)).FaccError)
}
// C documentation
//
// /*
// ** Initialize a string accumulator.
// **
// ** p: The accumulator to be initialized.
// ** db: Pointer to a database connection. May be NULL. Lookaside
// ** memory is used if not NULL. db->mallocFailed is set appropriately
// ** when not NULL.
// ** zBase: An initial buffer. May be NULL in which case the initial buffer
// ** is malloced.
// ** n: Size of zBase in bytes. If total space requirements never exceed
// ** n then no memory allocations ever occur.
// ** mx: Maximum number of bytes to accumulate. If mx==0 then no memory
// ** allocations will ever occur.
// */
func _sqlite3StrAccumInit(tls *libc.TLS, p uintptr, db uintptr, zBase uintptr, n int32, mx int32) {
(*TStrAccum)(unsafe.Pointer(p)).FzText = zBase
(*TStrAccum)(unsafe.Pointer(p)).Fdb = db
(*TStrAccum)(unsafe.Pointer(p)).FnAlloc = libc.Uint32FromInt32(n)
(*TStrAccum)(unsafe.Pointer(p)).FmxAlloc = libc.Uint32FromInt32(mx)
(*TStrAccum)(unsafe.Pointer(p)).FnChar = uint32(0)
(*TStrAccum)(unsafe.Pointer(p)).FaccError = uint8(0)
(*TStrAccum)(unsafe.Pointer(p)).FprintfFlags = uint8(0)
}
// C documentation
//
// /*
// ** Set the StrAccum object to an error mode.
// */
func _sqlite3StrAccumSetError(tls *libc.TLS, p uintptr, eError Tu8) {
(*TStrAccum)(unsafe.Pointer(p)).FaccError = eError
if (*TStrAccum)(unsafe.Pointer(p)).FmxAlloc != 0 {
Xsqlite3_str_reset(tls, p)
}
if libc.Int32FromUint8(eError) == int32(SQLITE_TOOBIG) {
_sqlite3ErrorToParser(tls, (*TStrAccum)(unsafe.Pointer(p)).Fdb, libc.Int32FromUint8(eError))
}
}
func _sqlite3StrICmp(tls *libc.TLS, zLeft uintptr, zRight uintptr) (r int32) {
var a, b uintptr
var c, x int32
_, _, _, _ = a, b, c, x
a = zLeft
b = zRight
for {
c = libc.Int32FromUint8(**(**uint8)(__ccgo_up(a)))
x = libc.Int32FromUint8(**(**uint8)(__ccgo_up(b)))
if c == x {
if c == 0 {
break
}
} else {
c = libc.Int32FromUint8(_sqlite3UpperToLower[c]) - libc.Int32FromUint8(_sqlite3UpperToLower[x])
if c != 0 {
break
}
}
a = a + 1
b = b + 1
goto _1
_1:
}
return c
}
// C documentation
//
// /*
// ** Backwards Compatibility Hack:
// **
// ** Historical versions of SQLite accepted strings as column names in
// ** indexes and PRIMARY KEY constraints and in UNIQUE constraints. Example:
// **
// ** CREATE TABLE xyz(a,b,c,d,e,PRIMARY KEY('a'),UNIQUE('b','c' COLLATE trim)
// ** CREATE INDEX abc ON xyz('c','d' DESC,'e' COLLATE nocase DESC);
// **
// ** This is goofy. But to preserve backwards compatibility we continue to
// ** accept it. This routine does the necessary conversion. It converts
// ** the expression given in its argument from a TK_STRING into a TK_ID
// ** if the expression is just a TK_STRING with an optional COLLATE clause.
// ** If the expression is anything other than TK_STRING, the expression is
// ** unchanged.
// */
func _sqlite3StringToId(tls *libc.TLS, p uintptr) {
if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(p)).Fop) == int32(TK_STRING) {
(*TExpr)(unsafe.Pointer(p)).Fop = uint8(TK_ID)
} else {
if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(p)).Fop) == int32(TK_COLLATE) && libc.Int32FromUint8((*TExpr)(unsafe.Pointer((*TExpr)(unsafe.Pointer(p)).FpLeft)).Fop) == int32(TK_STRING) {
(*TExpr)(unsafe.Pointer((*TExpr)(unsafe.Pointer(p)).FpLeft)).Fop = uint8(TK_ID)
}
}
}
// C documentation
//
// /*
// ** Convert an table column number into a index column number. That is,
// ** for the column iCol in the table (as defined by the CREATE TABLE statement)
// ** find the (first) offset of that column in index pIdx. Or return -1
// ** if column iCol is not used in index pIdx.
// */
func _sqlite3TableColumnToIndex(tls *libc.TLS, pIdx uintptr, iCol int32) (r int32) {
var i int32
var iCol16 Ti16
_, _ = i, iCol16
iCol16 = int16(iCol)
i = 0
for {
if !(i < libc.Int32FromUint16((*TIndex)(unsafe.Pointer(pIdx)).FnColumn)) {
break
}
if int32(iCol16) == int32(**(**Ti16)(__ccgo_up((*TIndex)(unsafe.Pointer(pIdx)).FaiColumn + uintptr(i)*2))) {
return i
}
goto _1
_1:
;
i = i + 1
}
return -int32(1)
}
// C documentation
//
// /*
// ** This function returns true if main-memory should be used instead of
// ** a temporary file for transient pager files and statement journals.
// ** The value returned depends on the value of db->temp_store (runtime
// ** parameter) and the compile time value of SQLITE_TEMP_STORE. The
// ** following table describes the relationship between these two values
// ** and this functions return value.
// **
// ** SQLITE_TEMP_STORE db->temp_store Location of temporary database
// ** ----------------- -------------- ------------------------------
// ** 0 any file (return 0)
// ** 1 1 file (return 0)
// ** 1 2 memory (return 1)
// ** 1 0 file (return 0)
// ** 2 1 file (return 0)
// ** 2 2 memory (return 1)
// ** 2 0 memory (return 1)
// ** 3 any memory (return 1)
// */
func _sqlite3TempInMemory(tls *libc.TLS, db uintptr) (r int32) {
return libc.BoolInt32(libc.Int32FromUint8((*Tsqlite3)(unsafe.Pointer(db)).Ftemp_store) == int32(2))
}
// C documentation
//
// /*
// ** Generate a Token object from a string
// */
func _sqlite3TokenInit(tls *libc.TLS, p uintptr, z uintptr) {
(*TToken)(unsafe.Pointer(p)).Fz = z
(*TToken)(unsafe.Pointer(p)).Fn = libc.Uint32FromInt32(_sqlite3Strlen30(tls, z))
}
/* Convenient short-hand */
// C documentation
//
// /*
// ** Construct a trigger step that implements a DELETE statement and return
// ** a pointer to that trigger step. The parser calls this routine when it
// ** sees a DELETE statement inside the body of a CREATE TRIGGER.
// */
func _sqlite3TriggerDeleteStep(tls *libc.TLS, pParse uintptr, pTabList uintptr, pWhere uintptr, zStart uintptr, zEnd uintptr) (r uintptr) {
var db, pTriggerStep uintptr
_, _ = db, pTriggerStep
db = (*TParse)(unsafe.Pointer(pParse)).Fdb
pTriggerStep = _triggerStepAllocate(tls, pParse, uint8(TK_DELETE), pTabList, zStart, zEnd)
if pTriggerStep != 0 {
if libc.Int32FromUint8((*TParse)(unsafe.Pointer(pParse)).FeParseMode) >= int32(PARSE_MODE_RENAME) {
(*TTriggerStep)(unsafe.Pointer(pTriggerStep)).FpWhere = pWhere
pWhere = uintptr(0)
} else {
(*TTriggerStep)(unsafe.Pointer(pTriggerStep)).FpWhere = _sqlite3ExprDup(tls, db, pWhere, int32(EXPRDUP_REDUCE))
}
(*TTriggerStep)(unsafe.Pointer(pTriggerStep)).Forconf = uint8(OE_Default)
}
_sqlite3ExprDelete(tls, db, pWhere)
return pTriggerStep
}
// C documentation
//
// /*
// ** Build a trigger step out of an INSERT statement. Return a pointer
// ** to the new trigger step.
// **
// ** The parser calls this routine when it sees an INSERT inside the
// ** body of a trigger.
// */
func _sqlite3TriggerInsertStep(tls *libc.TLS, pParse uintptr, pTabList uintptr, pColumn uintptr, pSelect uintptr, orconf Tu8, pUpsert uintptr, zStart uintptr, zEnd uintptr) (r uintptr) {
var db, pTriggerStep uintptr
_, _ = db, pTriggerStep
db = (*TParse)(unsafe.Pointer(pParse)).Fdb
pTriggerStep = _triggerStepAllocate(tls, pParse, uint8(TK_INSERT), pTabList, zStart, zEnd)
if pTriggerStep != 0 {
if libc.Int32FromUint8((*TParse)(unsafe.Pointer(pParse)).FeParseMode) >= int32(PARSE_MODE_RENAME) {
(*TTriggerStep)(unsafe.Pointer(pTriggerStep)).FpSelect = pSelect
pSelect = uintptr(0)
} else {
(*TTriggerStep)(unsafe.Pointer(pTriggerStep)).FpSelect = _sqlite3SelectDup(tls, db, pSelect, int32(EXPRDUP_REDUCE))
}
(*TTriggerStep)(unsafe.Pointer(pTriggerStep)).FpIdList = pColumn
(*TTriggerStep)(unsafe.Pointer(pTriggerStep)).FpUpsert = pUpsert
(*TTriggerStep)(unsafe.Pointer(pTriggerStep)).Forconf = orconf
if pUpsert != 0 {
_sqlite3HasExplicitNulls(tls, pParse, (*TUpsert)(unsafe.Pointer(pUpsert)).FpUpsertTarget)
}
} else {
_sqlite3IdListDelete(tls, db, pColumn)
_sqlite3UpsertDelete(tls, db, pUpsert)
}
_sqlite3SelectDelete(tls, db, pSelect)
return pTriggerStep
}
// C documentation
//
// /*
// ** Construct a trigger step that implements an UPDATE statement and return
// ** a pointer to that trigger step. The parser calls this routine when it
// ** sees an UPDATE statement inside the body of a CREATE TRIGGER.
// */
func _sqlite3TriggerUpdateStep(tls *libc.TLS, pParse uintptr, pTabList uintptr, pFrom uintptr, pEList uintptr, pWhere uintptr, orconf Tu8, zStart uintptr, zEnd uintptr) (r uintptr) {
bp := tls.Alloc(16)
defer tls.Free(16)
var db, pFromDup, pSub, pTriggerStep uintptr
var _ /* as at bp+0 */ TToken
_, _, _, _ = db, pFromDup, pSub, pTriggerStep
db = (*TParse)(unsafe.Pointer(pParse)).Fdb
pTriggerStep = _triggerStepAllocate(tls, pParse, uint8(TK_UPDATE), pTabList, zStart, zEnd)
if pTriggerStep != 0 {
pFromDup = uintptr(0)
if libc.Int32FromUint8((*TParse)(unsafe.Pointer(pParse)).FeParseMode) >= int32(PARSE_MODE_RENAME) {
(*TTriggerStep)(unsafe.Pointer(pTriggerStep)).FpExprList = pEList
(*TTriggerStep)(unsafe.Pointer(pTriggerStep)).FpWhere = pWhere
pFromDup = pFrom
pEList = uintptr(0)
pWhere = uintptr(0)
pFrom = uintptr(0)
} else {
(*TTriggerStep)(unsafe.Pointer(pTriggerStep)).FpExprList = _sqlite3ExprListDup(tls, db, pEList, int32(EXPRDUP_REDUCE))
(*TTriggerStep)(unsafe.Pointer(pTriggerStep)).FpWhere = _sqlite3ExprDup(tls, db, pWhere, int32(EXPRDUP_REDUCE))
pFromDup = _sqlite3SrcListDup(tls, db, pFrom, int32(EXPRDUP_REDUCE))
}
(*TTriggerStep)(unsafe.Pointer(pTriggerStep)).Forconf = orconf
if pFromDup != 0 && !(libc.Int32FromUint8((*TParse)(unsafe.Pointer(pParse)).FeParseMode) >= libc.Int32FromInt32(PARSE_MODE_RENAME)) {
**(**TToken)(__ccgo_up(bp)) = TToken{}
pSub = _sqlite3SelectNew(tls, pParse, uintptr(0), pFromDup, uintptr(0), uintptr(0), uintptr(0), uintptr(0), uint32(SF_NestedFrom), uintptr(0))
pFromDup = _sqlite3SrcListAppendFromTerm(tls, pParse, uintptr(0), uintptr(0), uintptr(0), bp, pSub, uintptr(0))
}
if pFromDup != 0 && (*TTriggerStep)(unsafe.Pointer(pTriggerStep)).FpSrc != 0 {
(*TTriggerStep)(unsafe.Pointer(pTriggerStep)).FpSrc = _sqlite3SrcListAppendList(tls, pParse, (*TTriggerStep)(unsafe.Pointer(pTriggerStep)).FpSrc, pFromDup)
} else {
_sqlite3SrcListDelete(tls, db, pFromDup)
}
}
_sqlite3ExprListDelete(tls, db, pEList)
_sqlite3ExprDelete(tls, db, pWhere)
_sqlite3SrcListDelete(tls, db, pFrom)
return pTriggerStep
}
// C documentation
//
// /*
// ** pZ is a UTF-8 encoded unicode string. If nByte is less than zero,
// ** return the number of unicode characters in pZ up to (but not including)
// ** the first 0x00 byte. If nByte is not less than zero, return the
// ** number of unicode characters in the first nByte of pZ (or up to
// ** the first 0x00, whichever comes first).
// */
func _sqlite3Utf8CharLen(tls *libc.TLS, zIn uintptr, nByte int32) (r1 int32) {
var r int32
var z, zTerm, v1 uintptr
_, _, _, _ = r, z, zTerm, v1
r = 0
z = zIn
if nByte >= 0 {
zTerm = z + uintptr(nByte)
} else {
zTerm = uintptr(-libc.Int32FromInt32(1))
}
for libc.Int32FromUint8(**(**Tu8)(__ccgo_up(z))) != 0 && z < zTerm {
v1 = z
z = z + 1
if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(v1))) >= int32(0xc0) {
for libc.Int32FromUint8(**(**Tu8)(__ccgo_up(z)))&int32(0xc0) == int32(0x80) {
z = z + 1
}
}
r = r + 1
}
return r
}
/* This test function is not currently used by the automated test-suite.
** Hence it is only available in debug builds.
*/
// C documentation
//
// /*
// ** Translate a single UTF-8 character. Return the unicode value.
// **
// ** During translation, assume that the byte that zTerm points
// ** is a 0x00.
// **
// ** Write a pointer to the next unread byte back into *pzNext.
// **
// ** Notes On Invalid UTF-8:
// **
// ** * This routine never allows a 7-bit character (0x00 through 0x7f) to
// ** be encoded as a multi-byte character. Any multi-byte character that
// ** attempts to encode a value between 0x00 and 0x7f is rendered as 0xfffd.
// **
// ** * This routine never allows a UTF16 surrogate value to be encoded.
// ** If a multi-byte character attempts to encode a value between
// ** 0xd800 and 0xe000 then it is rendered as 0xfffd.
// **
// ** * Bytes in the range of 0x80 through 0xbf which occur as the first
// ** byte of a character are interpreted as single-byte characters
// ** and rendered as themselves even though they are technically
// ** invalid characters.
// **
// ** * This routine accepts over-length UTF8 encodings
// ** for unicode values 0x80 and greater. It does not change over-length
// ** encodings to 0xfffd as some systems recommend.
// */
func _sqlite3Utf8Read(tls *libc.TLS, pz uintptr) (r Tu32) {
var c uint32
var v1, v2 uintptr
_, _, _ = c, v1, v2
/* Same as READ_UTF8() above but without the zTerm parameter.
** For this routine, we assume the UTF8 string is always zero-terminated.
*/
v2 = pz
v1 = *(*uintptr)(unsafe.Pointer(v2))
*(*uintptr)(unsafe.Pointer(v2)) = *(*uintptr)(unsafe.Pointer(v2)) + 1
c = uint32(**(**uint8)(__ccgo_up(v1)))
if c >= uint32(0xc0) {
c = uint32(_sqlite3Utf8Trans1[c-uint32(0xc0)])
for libc.Int32FromUint8(**(**uint8)(__ccgo_up(**(**uintptr)(__ccgo_up(pz)))))&int32(0xc0) == int32(0x80) {
v2 = pz
v1 = *(*uintptr)(unsafe.Pointer(v2))
*(*uintptr)(unsafe.Pointer(v2)) = *(*uintptr)(unsafe.Pointer(v2)) + 1
c = c<<int32(6) + libc.Uint32FromInt32(libc.Int32FromInt32(0x3f)&libc.Int32FromUint8(**(**uint8)(__ccgo_up(v1))))
}
if c < uint32(0x80) || c&uint32(0xFFFFF800) == uint32(0xD800) || c&uint32(0xFFFFFFFE) == uint32(0xFFFE) {
c = uint32(0xFFFD)
}
}
return c
}
// C documentation
//
// /*
// ** Read a single UTF8 character out of buffer z[], but reading no
// ** more than n characters from the buffer. z[] is not zero-terminated.
// **
// ** Return the number of bytes used to construct the character.
// **
// ** Invalid UTF8 might generate a strange result. No effort is made
// ** to detect invalid UTF8.
// **
// ** At most 4 bytes will be read out of z[]. The return value will always
// ** be between 1 and 4.
// */
func _sqlite3Utf8ReadLimited(tls *libc.TLS, z uintptr, n int32, piOut uintptr) (r int32) {
var c Tu32
var i int32
_, _ = c, i
i = int32(1)
c = uint32(**(**Tu8)(__ccgo_up(z)))
if c >= uint32(0xc0) {
c = uint32(_sqlite3Utf8Trans1[c-uint32(0xc0)])
if n > int32(4) {
n = int32(4)
}
for i < n && libc.Int32FromUint8(**(**Tu8)(__ccgo_up(z + uintptr(i))))&int32(0xc0) == int32(0x80) {
c = c<<libc.Int32FromInt32(6) + libc.Uint32FromInt32(libc.Int32FromInt32(0x3f)&libc.Int32FromUint8(**(**Tu8)(__ccgo_up(z + uintptr(i)))))
i = i + 1
}
}
**(**Tu32)(__ccgo_up(piOut)) = c
return i
}
/*
** If the TRANSLATE_TRACE macro is defined, the value of each Mem is
** printed on stderr on the way into and out of sqlite3VdbeMemTranslate().
*/
/* #define TRANSLATE_TRACE 1 */
func _sqlite3ValueBytes(tls *libc.TLS, pVal uintptr, enc Tu8) (r int32) {
var p uintptr
_ = p
p = pVal
if libc.Int32FromUint16((*TMem)(unsafe.Pointer(p)).Fflags)&int32(MEM_Str) != 0 && libc.Int32FromUint8((*Tsqlite3_value)(unsafe.Pointer(pVal)).Fenc) == libc.Int32FromUint8(enc) {
return (*TMem)(unsafe.Pointer(p)).Fn
}
if libc.Int32FromUint16((*TMem)(unsafe.Pointer(p)).Fflags)&int32(MEM_Str) != 0 && libc.Int32FromUint8(enc) != int32(SQLITE_UTF8) && libc.Int32FromUint8((*Tsqlite3_value)(unsafe.Pointer(pVal)).Fenc) != int32(SQLITE_UTF8) {
return (*TMem)(unsafe.Pointer(p)).Fn
}
if libc.Int32FromUint16((*TMem)(unsafe.Pointer(p)).Fflags)&int32(MEM_Blob) != 0 {
if libc.Int32FromUint16((*TMem)(unsafe.Pointer(p)).Fflags)&int32(MEM_Zero) != 0 {
return (*TMem)(unsafe.Pointer(p)).Fn + *(*int32)(unsafe.Pointer(&(*TMem)(unsafe.Pointer(p)).Fu))
} else {
return (*TMem)(unsafe.Pointer(p)).Fn
}
}
if libc.Int32FromUint16((*TMem)(unsafe.Pointer(p)).Fflags)&int32(MEM_Null) != 0 {
return 0
}
return _valueBytes(tls, pVal, enc)
}
// C documentation
//
// /* Return true if sqlit3_value object pVal is a string or blob value
// ** that uses the destructor specified in the second argument.
// **
// ** TODO: Maybe someday promote this interface into a published API so
// ** that third-party extensions can get access to it?
// */
func _sqlite3ValueIsOfClass(tls *libc.TLS, pVal uintptr, __ccgo_fp_xFree uintptr) (r int32) {
if pVal != uintptr(0) && libc.Int32FromUint16((*Tsqlite3_value)(unsafe.Pointer(pVal)).Fflags)&(libc.Int32FromInt32(MEM_Str)|libc.Int32FromInt32(MEM_Blob)) != 0 && libc.Int32FromUint16((*Tsqlite3_value)(unsafe.Pointer(pVal)).Fflags)&int32(MEM_Dyn) != 0 && (*Tsqlite3_value)(unsafe.Pointer(pVal)).FxDel == __ccgo_fp_xFree {
return int32(1)
} else {
return 0
}
return r
}
// C documentation
//
// /* This function is only available internally, it is not part of the
// ** external API. It works in a similar way to sqlite3_value_text(),
// ** except the data returned is in the encoding specified by the second
// ** parameter, which must be one of SQLITE_UTF16BE, SQLITE_UTF16LE or
// ** SQLITE_UTF8.
// **
// ** (2006-02-16:) The enc value can be or-ed with SQLITE_UTF16_ALIGNED.
// ** If that is the case, then the result must be aligned on an even byte
// ** boundary.
// */
func _sqlite3ValueText(tls *libc.TLS, pVal uintptr, enc Tu8) (r uintptr) {
if !(pVal != 0) {
return uintptr(0)
}
if libc.Int32FromUint16((*Tsqlite3_value)(unsafe.Pointer(pVal)).Fflags)&(libc.Int32FromInt32(MEM_Str)|libc.Int32FromInt32(MEM_Term)) == libc.Int32FromInt32(MEM_Str)|libc.Int32FromInt32(MEM_Term) && libc.Int32FromUint8((*Tsqlite3_value)(unsafe.Pointer(pVal)).Fenc) == libc.Int32FromUint8(enc) {
return (*Tsqlite3_value)(unsafe.Pointer(pVal)).Fz
}
if libc.Int32FromUint16((*Tsqlite3_value)(unsafe.Pointer(pVal)).Fflags)&int32(MEM_Null) != 0 {
return uintptr(0)
}
return _valueToText(tls, pVal, enc)
}
// C documentation
//
// /*
// ** Return 1 if pMem represents true, and return 0 if pMem represents false.
// ** Return the value ifNull if pMem is NULL.
// */
func _sqlite3VdbeBooleanValue(tls *libc.TLS, pMem uintptr, ifNull int32) (r int32) {
if libc.Int32FromUint16((*TMem)(unsafe.Pointer(pMem)).Fflags)&(libc.Int32FromInt32(MEM_Int)|libc.Int32FromInt32(MEM_IntReal)) != 0 {
return libc.BoolInt32(*(*Ti64)(unsafe.Pointer(pMem)) != 0)
}
if libc.Int32FromUint16((*TMem)(unsafe.Pointer(pMem)).Fflags)&int32(MEM_Null) != 0 {
return ifNull
}
return libc.BoolInt32(_sqlite3VdbeRealValue(tls, pMem) != float64(0))
}
// C documentation
//
// /*
// ** If pMem is an object with a valid string representation, this routine
// ** ensures the internal encoding for the string representation is
// ** 'desiredEnc', one of SQLITE_UTF8, SQLITE_UTF16LE or SQLITE_UTF16BE.
// **
// ** If pMem is not a string object, or the encoding of the string
// ** representation is already stored using the requested encoding, then this
// ** routine is a no-op.
// **
// ** SQLITE_OK is returned if the conversion is successful (or not required).
// ** SQLITE_NOMEM may be returned if a malloc() fails during conversion
// ** between formats.
// */
func _sqlite3VdbeChangeEncoding(tls *libc.TLS, pMem uintptr, desiredEnc int32) (r int32) {
var rc int32
_ = rc
if !(libc.Int32FromUint16((*TMem)(unsafe.Pointer(pMem)).Fflags)&libc.Int32FromInt32(MEM_Str) != 0) {
(*TMem)(unsafe.Pointer(pMem)).Fenc = libc.Uint8FromInt32(desiredEnc)
return SQLITE_OK
}
if libc.Int32FromUint8((*TMem)(unsafe.Pointer(pMem)).Fenc) == desiredEnc {
return SQLITE_OK
}
/* MemTranslate() may return SQLITE_OK or SQLITE_NOMEM. If NOMEM is returned,
** then the encoding of the value may not have changed.
*/
rc = _sqlite3VdbeMemTranslate(tls, pMem, libc.Uint8FromInt32(desiredEnc))
return rc
}
// C documentation
//
// /*
// ** Free all memory associated with the Vdbe passed as the second argument,
// ** except for object itself, which is preserved.
// **
// ** The difference between this function and sqlite3VdbeDelete() is that
// ** VdbeDelete() also unlinks the Vdbe from the list of VMs associated with
// ** the database connection and frees the object itself.
// */
func _sqlite3VdbeClearObject(tls *libc.TLS, db uintptr, p uintptr) {
var pNext, pSub uintptr
_, _ = pNext, pSub
if (*TVdbe)(unsafe.Pointer(p)).FaColName != 0 {
_releaseMemArray(tls, (*TVdbe)(unsafe.Pointer(p)).FaColName, libc.Int32FromUint16((*TVdbe)(unsafe.Pointer(p)).FnResAlloc)*int32(COLNAME_N))
_sqlite3DbNNFreeNN(tls, db, (*TVdbe)(unsafe.Pointer(p)).FaColName)
}
pSub = (*TVdbe)(unsafe.Pointer(p)).FpProgram
for {
if !(pSub != 0) {
break
}
pNext = (*TSubProgram)(unsafe.Pointer(pSub)).FpNext
_vdbeFreeOpArray(tls, db, (*TSubProgram)(unsafe.Pointer(pSub)).FaOp, (*TSubProgram)(unsafe.Pointer(pSub)).FnOp)
_sqlite3DbFree(tls, db, pSub)
goto _1
_1:
;
pSub = pNext
}
if libc.Int32FromUint8((*TVdbe)(unsafe.Pointer(p)).FeVdbeState) != VDBE_INIT_STATE {
_releaseMemArray(tls, (*TVdbe)(unsafe.Pointer(p)).FaVar, int32((*TVdbe)(unsafe.Pointer(p)).FnVar))
if (*TVdbe)(unsafe.Pointer(p)).FpVList != 0 {
_sqlite3DbNNFreeNN(tls, db, (*TVdbe)(unsafe.Pointer(p)).FpVList)
}
if (*TVdbe)(unsafe.Pointer(p)).FpFree != 0 {
_sqlite3DbNNFreeNN(tls, db, (*TVdbe)(unsafe.Pointer(p)).FpFree)
}
}
_vdbeFreeOpArray(tls, db, (*TVdbe)(unsafe.Pointer(p)).FaOp, (*TVdbe)(unsafe.Pointer(p)).FnOp)
if (*TVdbe)(unsafe.Pointer(p)).FzSql != 0 {
_sqlite3DbNNFreeNN(tls, db, (*TVdbe)(unsafe.Pointer(p)).FzSql)
}
}
// C documentation
//
// /*
// ** Add a new OP_Explain opcode.
// **
// ** If the bPush flag is true, then make this opcode the parent for
// ** subsequent Explains until sqlite3VdbeExplainPop() is called.
// */
func _sqlite3VdbeExplain(tls *libc.TLS, pParse uintptr, bPush Tu8, zFmt uintptr, va uintptr) (r int32) {
var addr, iThis int32
var ap Tva_list
var v, zMsg uintptr
_, _, _, _, _ = addr, ap, iThis, v, zMsg
addr = 0
/* Always include the OP_Explain opcodes if SQLITE_DEBUG is defined.
** But omit them (for performance) during production builds */
if libc.Int32FromUint8((*TParse)(unsafe.Pointer(pParse)).Fexplain) == int32(2) || libc.Bool(0 != 0) {
ap = va
zMsg = _sqlite3VMPrintf(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, zFmt, ap)
_ = ap
v = (*TParse)(unsafe.Pointer(pParse)).FpVdbe
iThis = (*TVdbe)(unsafe.Pointer(v)).FnOp
addr = _sqlite3VdbeAddOp4(tls, v, int32(OP_Explain), iThis, (*TParse)(unsafe.Pointer(pParse)).FaddrExplain, 0, zMsg, -int32(7))
if bPush != 0 {
(*TParse)(unsafe.Pointer(pParse)).FaddrExplain = iThis
}
}
return addr
}
// C documentation
//
// /*
// ** Clean up and delete a VDBE after execution. Return an integer which is
// ** the result code. Write any error message text into *pzErrMsg.
// */
func _sqlite3VdbeFinalize(tls *libc.TLS, p uintptr) (r int32) {
var rc int32
_ = rc
rc = SQLITE_OK
if libc.Int32FromUint8((*TVdbe)(unsafe.Pointer(p)).FeVdbeState) >= int32(VDBE_READY_STATE) {
rc = _sqlite3VdbeReset(tls, p)
}
_sqlite3VdbeDelete(tls, p)
return rc
}
func _sqlite3VdbeIntValue(tls *libc.TLS, pMem uintptr) (r Ti64) {
var flags int32
_ = flags
flags = libc.Int32FromUint16((*TMem)(unsafe.Pointer(pMem)).Fflags)
if flags&(libc.Int32FromInt32(MEM_Int)|libc.Int32FromInt32(MEM_IntReal)) != 0 {
return *(*Ti64)(unsafe.Pointer(pMem))
} else {
if flags&int32(MEM_Real) != 0 {
return _sqlite3RealToI64(tls, *(*float64)(unsafe.Pointer(pMem)))
} else {
if flags&(libc.Int32FromInt32(MEM_Str)|libc.Int32FromInt32(MEM_Blob)) != 0 && (*TMem)(unsafe.Pointer(pMem)).Fz != uintptr(0) {
return _memIntValue(tls, pMem)
} else {
return 0
}
}
}
return r
}
// C documentation
//
// /*
// ** The MEM structure is already a MEM_Real or MEM_IntReal. Try to
// ** make it a MEM_Int if we can.
// */
func _sqlite3VdbeIntegerAffinity(tls *libc.TLS, pMem uintptr) {
var ix Ti64
_ = ix
if libc.Int32FromUint16((*TMem)(unsafe.Pointer(pMem)).Fflags)&int32(MEM_IntReal) != 0 {
(*TMem)(unsafe.Pointer(pMem)).Fflags = libc.Uint16FromInt32(libc.Int32FromUint16((*TMem)(unsafe.Pointer(pMem)).Fflags) & ^(libc.Int32FromInt32(MEM_TypeMask)|libc.Int32FromInt32(MEM_Zero)) | int32(MEM_Int))
} else {
ix = _sqlite3RealToI64(tls, *(*float64)(unsafe.Pointer(pMem)))
/* Only mark the value as an integer if
**
** (1) the round-trip conversion real->int->real is a no-op, and
** (2) The integer is neither the largest nor the smallest
** possible integer (ticket #3922)
**
** The second and third terms in the following conditional enforces
** the second condition under the assumption that addition overflow causes
** values to wrap around.
*/
if *(*float64)(unsafe.Pointer(pMem)) == float64(ix) && ix > int64(-libc.Int32FromInt32(1))-(libc.Int64FromUint32(0xffffffff)|libc.Int64FromInt32(0x7fffffff)<<libc.Int32FromInt32(32)) && ix < libc.Int64FromUint32(0xffffffff)|libc.Int64FromInt32(0x7fffffff)<<libc.Int32FromInt32(32) {
*(*Ti64)(unsafe.Pointer(pMem)) = ix
(*TMem)(unsafe.Pointer(pMem)).Fflags = libc.Uint16FromInt32(libc.Int32FromUint16((*TMem)(unsafe.Pointer(pMem)).Fflags) & ^(libc.Int32FromInt32(MEM_TypeMask)|libc.Int32FromInt32(MEM_Zero)) | int32(MEM_Int))
}
}
}
func _sqlite3VdbeMemFromBtreeZeroOffset(tls *libc.TLS, pCur uintptr, amt Tu32, pMem uintptr) (r int32) {
bp := tls.Alloc(16)
defer tls.Free(16)
var rc int32
var _ /* available at bp+0 */ Tu32
_ = rc
**(**Tu32)(__ccgo_up(bp)) = uint32(0) /* Number of bytes available on the local btree page */
rc = SQLITE_OK /* Return code */
/* Note: the calls to BtreeKeyFetch() and DataFetch() below assert()
** that both the BtShared and database handle mutexes are held. */
(*TMem)(unsafe.Pointer(pMem)).Fz = _sqlite3BtreePayloadFetch(tls, pCur, bp)
if amt <= **(**Tu32)(__ccgo_up(bp)) {
(*TMem)(unsafe.Pointer(pMem)).Fflags = libc.Uint16FromInt32(libc.Int32FromInt32(MEM_Blob) | libc.Int32FromInt32(MEM_Ephem))
(*TMem)(unsafe.Pointer(pMem)).Fn = libc.Int32FromUint32(amt)
} else {
rc = _sqlite3VdbeMemFromBtree(tls, pCur, uint32(0), amt, pMem)
}
return rc
}
// C documentation
//
// /*
// ** Convert pMem to type integer. Invalidate any prior representations.
// */
func _sqlite3VdbeMemIntegerify(tls *libc.TLS, pMem uintptr) (r int32) {
*(*Ti64)(unsafe.Pointer(pMem)) = _sqlite3VdbeIntValue(tls, pMem)
(*TMem)(unsafe.Pointer(pMem)).Fflags = libc.Uint16FromInt32(libc.Int32FromUint16((*TMem)(unsafe.Pointer(pMem)).Fflags) & ^(libc.Int32FromInt32(MEM_TypeMask)|libc.Int32FromInt32(MEM_Zero)) | int32(MEM_Int))
return SQLITE_OK
}
// C documentation
//
// /*
// ** Make sure the given Mem is \u0000 terminated.
// */
func _sqlite3VdbeMemNulTerminate(tls *libc.TLS, pMem uintptr) (r int32) {
if libc.Int32FromUint16((*TMem)(unsafe.Pointer(pMem)).Fflags)&(libc.Int32FromInt32(MEM_Term)|libc.Int32FromInt32(MEM_Str)) != int32(MEM_Str) {
return SQLITE_OK /* Nothing to do */
} else {
return _vdbeMemAddTerminator(tls, pMem)
}
return r
}
// C documentation
//
// /*
// ** Convert pMem so that it is of type MEM_Real.
// ** Invalidate any prior representations.
// */
func _sqlite3VdbeMemRealify(tls *libc.TLS, pMem uintptr) (r int32) {
*(*float64)(unsafe.Pointer(pMem)) = _sqlite3VdbeRealValue(tls, pMem)
(*TMem)(unsafe.Pointer(pMem)).Fflags = libc.Uint16FromInt32(libc.Int32FromUint16((*TMem)(unsafe.Pointer(pMem)).Fflags) & ^(libc.Int32FromInt32(MEM_TypeMask)|libc.Int32FromInt32(MEM_Zero)) | int32(MEM_Real))
return SQLITE_OK
}
// C documentation
//
// /*
// ** Release any memory resources held by the Mem. Both the memory that is
// ** free by Mem.xDel and the Mem.zMalloc allocation are freed.
// **
// ** Use this routine prior to clean up prior to abandoning a Mem, or to
// ** reset a Mem back to its minimum memory utilization.
// **
// ** Use sqlite3VdbeMemSetNull() to release just the Mem.xDel space
// ** prior to inserting new content into the Mem.
// */
func _sqlite3VdbeMemRelease(tls *libc.TLS, p uintptr) {
if libc.Int32FromUint16((*TMem)(unsafe.Pointer(p)).Fflags)&(libc.Int32FromInt32(MEM_Agg)|libc.Int32FromInt32(MEM_Dyn)) != 0 || (*TMem)(unsafe.Pointer(p)).FszMalloc != 0 {
_vdbeMemClear(tls, p)
}
}
// C documentation
//
// /*
// ** Delete any previous value and set the value stored in *pMem to val,
// ** manifest type INTEGER.
// */
func _sqlite3VdbeMemSetInt64(tls *libc.TLS, pMem uintptr, val Ti64) {
if libc.Int32FromUint16((*TMem)(unsafe.Pointer(pMem)).Fflags)&(libc.Int32FromInt32(MEM_Agg)|libc.Int32FromInt32(MEM_Dyn)) != 0 {
_vdbeReleaseAndSetInt64(tls, pMem, val)
} else {
*(*Ti64)(unsafe.Pointer(pMem)) = val
(*TMem)(unsafe.Pointer(pMem)).Fflags = uint16(MEM_Int)
}
}
// C documentation
//
// /*
// ** Delete any previous value and set the value stored in *pMem to NULL.
// **
// ** This routine calls the Mem.xDel destructor to dispose of values that
// ** require the destructor. But it preserves the Mem.zMalloc memory allocation.
// ** To free all resources, use sqlite3VdbeMemRelease(), which both calls this
// ** routine to invoke the destructor and deallocates Mem.zMalloc.
// **
// ** Use this routine to reset the Mem prior to insert a new value.
// **
// ** Use sqlite3VdbeMemRelease() to complete erase the Mem prior to abandoning it.
// */
func _sqlite3VdbeMemSetNull(tls *libc.TLS, pMem uintptr) {
if libc.Int32FromUint16((*TMem)(unsafe.Pointer(pMem)).Fflags)&(libc.Int32FromInt32(MEM_Agg)|libc.Int32FromInt32(MEM_Dyn)) != 0 {
_vdbeMemClearExternAndSetNull(tls, pMem)
} else {
(*TMem)(unsafe.Pointer(pMem)).Fflags = uint16(MEM_Null)
}
}
// C documentation
//
// /*
// ** Delete any previous value and set the value of pMem to be an
// ** empty boolean index.
// **
// ** Return SQLITE_OK on success and SQLITE_NOMEM if a memory allocation
// ** error occurs.
// */
func _sqlite3VdbeMemSetRowSet(tls *libc.TLS, pMem uintptr) (r int32) {
var db, p uintptr
_, _ = db, p
db = (*TMem)(unsafe.Pointer(pMem)).Fdb
_sqlite3VdbeMemRelease(tls, pMem)
p = _sqlite3RowSetInit(tls, db)
if p == uintptr(0) {
return int32(SQLITE_NOMEM)
}
(*TMem)(unsafe.Pointer(pMem)).Fz = p
(*TMem)(unsafe.Pointer(pMem)).Fflags = libc.Uint16FromInt32(libc.Int32FromInt32(MEM_Blob) | libc.Int32FromInt32(MEM_Dyn))
(*TMem)(unsafe.Pointer(pMem)).FxDel = __ccgo_fp(_sqlite3RowSetDelete)
return SQLITE_OK
}
// C documentation
//
// /*
// ** Delete any previous value and set the value to be a BLOB of length
// ** n containing all zeros.
// */
func _sqlite3VdbeMemSetZeroBlob(tls *libc.TLS, pMem uintptr, n int32) {
_sqlite3VdbeMemRelease(tls, pMem)
(*TMem)(unsafe.Pointer(pMem)).Fflags = libc.Uint16FromInt32(libc.Int32FromInt32(MEM_Blob) | libc.Int32FromInt32(MEM_Zero))
(*TMem)(unsafe.Pointer(pMem)).Fn = 0
if n < 0 {
n = 0
}
*(*int32)(unsafe.Pointer(&(*TMem)(unsafe.Pointer(pMem)).Fu)) = n
(*TMem)(unsafe.Pointer(pMem)).Fenc = uint8(SQLITE_UTF8)
(*TMem)(unsafe.Pointer(pMem)).Fz = uintptr(0)
}
// C documentation
//
// /*
// ** Return the best representation of pMem that we can get into a
// ** double. If pMem is already a double or an integer, return its
// ** value. If it is a string or blob, try to convert it to a double.
// ** If it is a NULL, return 0.0.
// */
func _sqlite3VdbeRealValue(tls *libc.TLS, pMem uintptr) (r float64) {
if libc.Int32FromUint16((*TMem)(unsafe.Pointer(pMem)).Fflags)&int32(MEM_Real) != 0 {
return *(*float64)(unsafe.Pointer(pMem))
} else {
if libc.Int32FromUint16((*TMem)(unsafe.Pointer(pMem)).Fflags)&(libc.Int32FromInt32(MEM_Int)|libc.Int32FromInt32(MEM_IntReal)) != 0 {
return float64(*(*Ti64)(unsafe.Pointer(pMem)))
} else {
if libc.Int32FromUint16((*TMem)(unsafe.Pointer(pMem)).Fflags)&(libc.Int32FromInt32(MEM_Str)|libc.Int32FromInt32(MEM_Blob)) != 0 {
return _sqlite3MemRealValueNoRC(tls, pMem)
} else {
/* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
return libc.Float64FromInt32(0)
}
}
}
return r
}
// C documentation
//
// /*
// ** Clean up a VDBE after execution but do not delete the VDBE just yet.
// ** Write any error messages into *pzErrMsg. Return the result code.
// **
// ** After this routine is run, the VDBE should be ready to be executed
// ** again.
// **
// ** To look at it another way, this routine resets the state of the
// ** virtual machine from VDBE_RUN_STATE or VDBE_HALT_STATE back to
// ** VDBE_READY_STATE.
// */
func _sqlite3VdbeReset(tls *libc.TLS, p uintptr) (r int32) {
var db uintptr
_ = db
db = (*TVdbe)(unsafe.Pointer(p)).Fdb
/* If the VM did not run to completion or if it encountered an
** error, then it might not have been halted properly. So halt
** it now.
*/
if libc.Int32FromUint8((*TVdbe)(unsafe.Pointer(p)).FeVdbeState) == int32(VDBE_RUN_STATE) {
_sqlite3VdbeHalt(tls, p)
}
/* If the VDBE has been run even partially, then transfer the error code
** and error message from the VDBE into the main database structure. But
** if the VDBE has just been set to run but has not actually executed any
** instructions yet, leave the main database error information unchanged.
*/
if (*TVdbe)(unsafe.Pointer(p)).Fpc >= 0 {
if (*Tsqlite3)(unsafe.Pointer(db)).FpErr != 0 || (*TVdbe)(unsafe.Pointer(p)).FzErrMsg != 0 {
_sqlite3VdbeTransferError(tls, p)
} else {
(*Tsqlite3)(unsafe.Pointer(db)).FerrCode = (*TVdbe)(unsafe.Pointer(p)).Frc
}
}
/* Reset register contents and reclaim error message memory.
*/
if (*TVdbe)(unsafe.Pointer(p)).FzErrMsg != 0 {
_sqlite3DbFree(tls, db, (*TVdbe)(unsafe.Pointer(p)).FzErrMsg)
(*TVdbe)(unsafe.Pointer(p)).FzErrMsg = uintptr(0)
}
(*TVdbe)(unsafe.Pointer(p)).FpResultRow = uintptr(0)
/* Save profiling information from this VDBE run.
*/
return (*TVdbe)(unsafe.Pointer(p)).Frc & (*Tsqlite3)(unsafe.Pointer(db)).FerrMask
}
func _sqlite3VdbeSerialGet(tls *libc.TLS, buf uintptr, serial_type Tu32, pMem uintptr) {
switch serial_type {
case uint32(10): /* Internal use only: NULL with virtual table
** UPDATE no-change flag set */
(*TMem)(unsafe.Pointer(pMem)).Fflags = libc.Uint16FromInt32(libc.Int32FromInt32(MEM_Null) | libc.Int32FromInt32(MEM_Zero))
(*TMem)(unsafe.Pointer(pMem)).Fn = 0
*(*int32)(unsafe.Pointer(&(*TMem)(unsafe.Pointer(pMem)).Fu)) = 0
return
case uint32(11): /* Reserved for future use */
fallthrough
case uint32(0): /* Null */
/* EVIDENCE-OF: R-24078-09375 Value is a NULL. */
(*TMem)(unsafe.Pointer(pMem)).Fflags = uint16(MEM_Null)
return
case uint32(1):
/* EVIDENCE-OF: R-44885-25196 Value is an 8-bit twos-complement
** integer. */
*(*Ti64)(unsafe.Pointer(pMem)) = int64(libc.Int8FromUint8(**(**uint8)(__ccgo_up(buf))))
(*TMem)(unsafe.Pointer(pMem)).Fflags = uint16(MEM_Int)
return
case uint32(2): /* 2-byte signed integer */
/* EVIDENCE-OF: R-49794-35026 Value is a big-endian 16-bit
** twos-complement integer. */
*(*Ti64)(unsafe.Pointer(pMem)) = int64(libc.Int32FromInt32(256)*int32(libc.Int8FromUint8(**(**uint8)(__ccgo_up(buf)))) | libc.Int32FromUint8(**(**uint8)(__ccgo_up(buf + 1))))
(*TMem)(unsafe.Pointer(pMem)).Fflags = uint16(MEM_Int)
return
case uint32(3): /* 3-byte signed integer */
/* EVIDENCE-OF: R-37839-54301 Value is a big-endian 24-bit
** twos-complement integer. */
*(*Ti64)(unsafe.Pointer(pMem)) = int64(libc.Int32FromInt32(65536)*int32(libc.Int8FromUint8(**(**uint8)(__ccgo_up(buf)))) | libc.Int32FromUint8(**(**uint8)(__ccgo_up(buf + 1)))<<libc.Int32FromInt32(8) | libc.Int32FromUint8(**(**uint8)(__ccgo_up(buf + 2))))
(*TMem)(unsafe.Pointer(pMem)).Fflags = uint16(MEM_Int)
return
case uint32(4): /* 4-byte signed integer */
/* EVIDENCE-OF: R-01849-26079 Value is a big-endian 32-bit
** twos-complement integer. */
*(*Ti64)(unsafe.Pointer(pMem)) = int64(libc.Int32FromInt32(16777216)*int32(libc.Int8FromUint8(**(**uint8)(__ccgo_up(buf)))) | libc.Int32FromUint8(**(**uint8)(__ccgo_up(buf + 1)))<<libc.Int32FromInt32(16) | libc.Int32FromUint8(**(**uint8)(__ccgo_up(buf + 2)))<<libc.Int32FromInt32(8) | libc.Int32FromUint8(**(**uint8)(__ccgo_up(buf + 3))))
(*TMem)(unsafe.Pointer(pMem)).Fflags = uint16(MEM_Int)
return
case uint32(5): /* 6-byte signed integer */
/* EVIDENCE-OF: R-50385-09674 Value is a big-endian 48-bit
** twos-complement integer. */
*(*Ti64)(unsafe.Pointer(pMem)) = libc.Int64FromUint32(uint32(**(**uint8)(__ccgo_up(buf + libc.UintptrFromInt32(2))))<<libc.Int32FromInt32(24)|libc.Uint32FromInt32(libc.Int32FromUint8(**(**uint8)(__ccgo_up(buf + libc.UintptrFromInt32(2) + 1)))<<libc.Int32FromInt32(16))|libc.Uint32FromInt32(libc.Int32FromUint8(**(**uint8)(__ccgo_up(buf + libc.UintptrFromInt32(2) + 2)))<<libc.Int32FromInt32(8))|uint32(**(**uint8)(__ccgo_up(buf + libc.UintptrFromInt32(2) + 3)))) + libc.Int64FromInt32(1)<<libc.Int32FromInt32(32)*int64(libc.Int32FromInt32(256)*int32(libc.Int8FromUint8(**(**uint8)(__ccgo_up(buf))))|libc.Int32FromUint8(**(**uint8)(__ccgo_up(buf + 1))))
(*TMem)(unsafe.Pointer(pMem)).Fflags = uint16(MEM_Int)
return
case uint32(6): /* 8-byte signed integer */
fallthrough
case uint32(7): /* IEEE floating point */
/* These use local variables, so do them in a separate routine
** to avoid having to move the frame pointer in the common case */
_serialGet(tls, buf, serial_type, pMem)
return
case uint32(8): /* Integer 0 */
fallthrough
case uint32(9): /* Integer 1 */
/* EVIDENCE-OF: R-12976-22893 Value is the integer 0. */
/* EVIDENCE-OF: R-18143-12121 Value is the integer 1. */
*(*Ti64)(unsafe.Pointer(pMem)) = libc.Int64FromUint32(serial_type - uint32(8))
(*TMem)(unsafe.Pointer(pMem)).Fflags = uint16(MEM_Int)
return
default:
(*TMem)(unsafe.Pointer(pMem)).Fz = buf
(*TMem)(unsafe.Pointer(pMem)).Fn = libc.Int32FromUint32((serial_type - uint32(12)) / uint32(2))
(*TMem)(unsafe.Pointer(pMem)).Fflags = _aFlag[serial_type&uint32(1)]
return
}
return
}
// C documentation
//
// /*
// ** Remember the SQL string for a prepared statement.
// */
func _sqlite3VdbeSetSql(tls *libc.TLS, p uintptr, z uintptr, n int32, prepFlags Tu8) {
if p == uintptr(0) {
return
}
(*TVdbe)(unsafe.Pointer(p)).FprepFlags = prepFlags
if libc.Int32FromUint8(prepFlags)&int32(SQLITE_PREPARE_SAVESQL) == 0 {
(*TVdbe)(unsafe.Pointer(p)).Fexpmask = uint32(0)
}
(*TVdbe)(unsafe.Pointer(p)).FzSql = _sqlite3DbStrNDup(tls, (*TVdbe)(unsafe.Pointer(p)).Fdb, z, libc.Uint64FromInt32(n))
}
// C documentation
//
// /*
// ** If the previous opcode is an OP_Column that delivers results
// ** into register iDest, then add the OPFLAG_TYPEOFARG flag to that
// ** opcode.
// */
func _sqlite3VdbeTypeofColumn(tls *libc.TLS, p uintptr, iDest int32) {
var pOp, v1 uintptr
_, _ = pOp, v1
pOp = _sqlite3VdbeGetLastOp(tls, p)
if (*TVdbeOp)(unsafe.Pointer(pOp)).Fp3 == iDest && libc.Int32FromUint8((*TVdbeOp)(unsafe.Pointer(pOp)).Fopcode) == int32(OP_Column) {
v1 = pOp + 2
*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) | libc.Int32FromInt32(OPFLAG_TYPEOFARG))
}
}
func _sqlite3ViewGetColumnNames(tls *libc.TLS, pParse uintptr, pTable uintptr) (r int32) {
if !(libc.Int32FromUint8((*TTable)(unsafe.Pointer(pTable)).FeTabType) == libc.Int32FromInt32(TABTYP_VTAB)) && int32((*TTable)(unsafe.Pointer(pTable)).FnCol) > 0 {
return 0
}
return _viewGetColumnNames(tls, pParse, pTable)
}
// C documentation
//
// /* Return the value to pass to a sqlite3_wal_hook callback, the
// ** number of frames in the WAL at the point of the last commit since
// ** sqlite3WalCallback() was called. If no commits have occurred since
// ** the last call, then return 0.
// */
func _sqlite3WalCallback(tls *libc.TLS, pWal uintptr) (r int32) {
var ret Tu32
_ = ret
ret = uint32(0)
if pWal != 0 {
ret = (*TWal)(unsafe.Pointer(pWal)).FiCallback
(*TWal)(unsafe.Pointer(pWal)).FiCallback = uint32(0)
}
return libc.Int32FromUint32(ret)
}
// C documentation
//
// /*
// ** Close a connection to a log file.
// */
func _sqlite3WalClose(tls *libc.TLS, pWal uintptr, db uintptr, sync_flags int32, nBuf int32, zBuf uintptr) (r int32) {
bp := tls.Alloc(16)
defer tls.Free(16)
var isDelete, rc, v1 int32
var v2 bool
var _ /* bPersist at bp+0 */ int32
_, _, _, _ = isDelete, rc, v1, v2
rc = SQLITE_OK
if pWal != 0 {
isDelete = 0 /* True to unlink wal and wal-index files */
/* If an EXCLUSIVE lock can be obtained on the database file (using the
** ordinary, rollback-mode locking methods, this guarantees that the
** connection associated with this log file is the only connection to
** the database. In this case checkpoint the database and unlink both
** the wal and wal-index files.
**
** The EXCLUSIVE lock is not released before returning.
*/
if v2 = zBuf != uintptr(0); v2 {
v1 = _sqlite3OsLock(tls, (*TWal)(unsafe.Pointer(pWal)).FpDbFd, int32(SQLITE_LOCK_EXCLUSIVE))
rc = v1
}
if v2 && SQLITE_OK == v1 {
if libc.Int32FromUint8((*TWal)(unsafe.Pointer(pWal)).FexclusiveMode) == WAL_NORMAL_MODE {
(*TWal)(unsafe.Pointer(pWal)).FexclusiveMode = uint8(WAL_EXCLUSIVE_MODE)
}
rc = _sqlite3WalCheckpoint(tls, pWal, db, SQLITE_CHECKPOINT_PASSIVE, uintptr(0), uintptr(0), sync_flags, nBuf, zBuf, uintptr(0), uintptr(0))
if rc == SQLITE_OK {
**(**int32)(__ccgo_up(bp)) = -int32(1)
_sqlite3OsFileControlHint(tls, (*TWal)(unsafe.Pointer(pWal)).FpDbFd, int32(SQLITE_FCNTL_PERSIST_WAL), bp)
if **(**int32)(__ccgo_up(bp)) != int32(1) {
/* Try to delete the WAL file if the checkpoint completed and
** fsynced (rc==SQLITE_OK) and if we are not in persistent-wal
** mode (!bPersist) */
isDelete = int32(1)
} else {
if (*TWal)(unsafe.Pointer(pWal)).FmxWalSize >= 0 {
/* Try to truncate the WAL file to zero bytes if the checkpoint
** completed and fsynced (rc==SQLITE_OK) and we are in persistent
** WAL mode (bPersist) and if the PRAGMA journal_size_limit is a
** non-negative value (pWal->mxWalSize>=0). Note that we truncate
** to zero bytes as truncating to the journal_size_limit might
** leave a corrupt WAL file on disk. */
_walLimitSize(tls, pWal, 0)
}
}
}
}
_walIndexClose(tls, pWal, isDelete)
_sqlite3OsClose(tls, (*TWal)(unsafe.Pointer(pWal)).FpWalFd)
if isDelete != 0 {
_sqlite3BeginBenignMalloc(tls)
_sqlite3OsDelete(tls, (*TWal)(unsafe.Pointer(pWal)).FpVfs, (*TWal)(unsafe.Pointer(pWal)).FzWalName, 0)
_sqlite3EndBenignMalloc(tls)
}
Xsqlite3_free(tls, (*TWal)(unsafe.Pointer(pWal)).FapWiData)
Xsqlite3_free(tls, pWal)
}
return rc
}
// C documentation
//
// /*
// ** This function is called to change the WAL subsystem into or out
// ** of locking_mode=EXCLUSIVE.
// **
// ** If op is zero, then attempt to change from locking_mode=EXCLUSIVE
// ** into locking_mode=NORMAL. This means that we must acquire a lock
// ** on the pWal->readLock byte. If the WAL is already in locking_mode=NORMAL
// ** or if the acquisition of the lock fails, then return 0. If the
// ** transition out of exclusive-mode is successful, return 1. This
// ** operation must occur while the pager is still holding the exclusive
// ** lock on the main database file.
// **
// ** If op is one, then change from locking_mode=NORMAL into
// ** locking_mode=EXCLUSIVE. This means that the pWal->readLock must
// ** be released. Return 1 if the transition is made and 0 if the
// ** WAL is already in exclusive-locking mode - meaning that this
// ** routine is a no-op. The pager must already hold the exclusive lock
// ** on the main database file before invoking this operation.
// **
// ** If op is negative, then do a dry-run of the op==1 case but do
// ** not actually change anything. The pager uses this to see if it
// ** should acquire the database exclusive lock prior to invoking
// ** the op==1 case.
// */
func _sqlite3WalExclusiveMode(tls *libc.TLS, pWal uintptr, op int32) (r int32) {
var rc int32
_ = rc
/* pWal->readLock is usually set, but might be -1 if there was a
** prior error while attempting to acquire are read-lock. This cannot
** happen if the connection is actually in exclusive mode (as no xShmLock
** locks are taken in this case). Nor should the pager attempt to
** upgrade to exclusive-mode following such an error.
*/
if op == 0 {
if libc.Int32FromUint8((*TWal)(unsafe.Pointer(pWal)).FexclusiveMode) != WAL_NORMAL_MODE {
(*TWal)(unsafe.Pointer(pWal)).FexclusiveMode = uint8(WAL_NORMAL_MODE)
if _walLockShared(tls, pWal, int32(3)+int32((*TWal)(unsafe.Pointer(pWal)).FreadLock)) != SQLITE_OK {
(*TWal)(unsafe.Pointer(pWal)).FexclusiveMode = uint8(WAL_EXCLUSIVE_MODE)
}
rc = libc.BoolInt32(libc.Int32FromUint8((*TWal)(unsafe.Pointer(pWal)).FexclusiveMode) == WAL_NORMAL_MODE)
} else {
/* Already in locking_mode=NORMAL */
rc = 0
}
} else {
if op > 0 {
_walUnlockShared(tls, pWal, int32(3)+int32((*TWal)(unsafe.Pointer(pWal)).FreadLock))
(*TWal)(unsafe.Pointer(pWal)).FexclusiveMode = uint8(WAL_EXCLUSIVE_MODE)
rc = int32(1)
} else {
rc = libc.BoolInt32(libc.Int32FromUint8((*TWal)(unsafe.Pointer(pWal)).FexclusiveMode) == WAL_NORMAL_MODE)
}
}
return rc
}
// C documentation
//
// /*
// ** Return true if the argument is non-NULL and the WAL module is using
// ** heap-memory for the wal-index. Otherwise, if the argument is NULL or the
// ** WAL module is using shared-memory, return false.
// */
func _sqlite3WalHeapMemory(tls *libc.TLS, pWal uintptr) (r int32) {
return libc.BoolInt32(pWal != 0 && libc.Int32FromUint8((*TWal)(unsafe.Pointer(pWal)).FexclusiveMode) == int32(WAL_HEAPMEMORY_MODE))
}
// C documentation
//
// /*
// ** Read the contents of frame iRead from the wal file into buffer pOut
// ** (which is nOut bytes in size). Return SQLITE_OK if successful, or an
// ** error code otherwise.
// */
func _sqlite3WalReadFrame(tls *libc.TLS, pWal uintptr, iRead Tu32, nOut int32, pOut uintptr) (r int32) {
var iOffset Ti64
var sz, v1 int32
_, _, _ = iOffset, sz, v1
sz = libc.Int32FromUint16((*TWal)(unsafe.Pointer(pWal)).Fhdr.FszPage)
sz = sz&int32(0xfe00) + sz&int32(0x0001)<<int32(16)
iOffset = int64(WAL_HDRSIZE) + libc.Int64FromUint32(iRead-libc.Uint32FromInt32(1))*int64(sz+libc.Int32FromInt32(WAL_FRAME_HDRSIZE)) + int64(WAL_FRAME_HDRSIZE)
/* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */
if nOut > sz {
v1 = sz
} else {
v1 = nOut
}
return _sqlite3OsRead(tls, (*TWal)(unsafe.Pointer(pWal)).FpWalFd, pOut, v1, iOffset)
}
// C documentation
//
// /*
// ** Attempt to reduce the value of the WalCkptInfo.nBackfillAttempted
// ** variable so that older snapshots can be accessed. To do this, loop
// ** through all wal frames from nBackfillAttempted to (nBackfill+1),
// ** comparing their content to the corresponding page with the database
// ** file, if any. Set nBackfillAttempted to the frame number of the
// ** first frame for which the wal file content matches the db file.
// **
// ** This is only really safe if the file-system is such that any page
// ** writes made by earlier checkpointers were atomic operations, which
// ** is not always true. It is also possible that nBackfillAttempted
// ** may be left set to a value larger than expected, if a wal frame
// ** contains content that duplicate of an earlier version of the same
// ** page.
// **
// ** SQLITE_OK is returned if successful, or an SQLite error code if an
// ** error occurs. It is not an error if nBackfillAttempted cannot be
// ** decreased at all.
// */
func _sqlite3WalSnapshotRecover(tls *libc.TLS, pWal uintptr) (r int32) {
var pBuf1, pBuf2 uintptr
var rc int32
_, _, _ = pBuf1, pBuf2, rc
rc = _walLockExclusive(tls, pWal, int32(WAL_CKPT_LOCK), int32(1))
if rc == SQLITE_OK {
pBuf1 = Xsqlite3_malloc(tls, libc.Int32FromUint32((*TWal)(unsafe.Pointer(pWal)).FszPage))
pBuf2 = Xsqlite3_malloc(tls, libc.Int32FromUint32((*TWal)(unsafe.Pointer(pWal)).FszPage))
if pBuf1 == uintptr(0) || pBuf2 == uintptr(0) {
rc = int32(SQLITE_NOMEM)
} else {
(*TWal)(unsafe.Pointer(pWal)).FckptLock = uint8(1)
rc = _walSnapshotRecover(tls, pWal, pBuf1, pBuf2)
(*TWal)(unsafe.Pointer(pWal)).FckptLock = uint8(0)
}
Xsqlite3_free(tls, pBuf1)
Xsqlite3_free(tls, pBuf2)
_walUnlockExclusive(tls, pWal, int32(WAL_CKPT_LOCK), int32(1))
}
return rc
}
// C documentation
//
// /*
// ** Walk all expressions associated with SELECT statement p. Do
// ** not invoke the SELECT callback on p, but do (of course) invoke
// ** any expr callbacks and SELECT callbacks that come from subqueries.
// ** Return WRC_Abort or WRC_Continue.
// */
func _sqlite3WalkSelectExpr(tls *libc.TLS, pWalker uintptr, p uintptr) (r int32) {
var pParse, v1 uintptr
var rc int32
var v2 bool
_, _, _, _ = pParse, rc, v1, v2
if _sqlite3WalkExprList(tls, pWalker, (*TSelect)(unsafe.Pointer(p)).FpEList) != 0 {
return int32(WRC_Abort)
}
if _sqlite3WalkExpr(tls, pWalker, (*TSelect)(unsafe.Pointer(p)).FpWhere) != 0 {
return int32(WRC_Abort)
}
if _sqlite3WalkExprList(tls, pWalker, (*TSelect)(unsafe.Pointer(p)).FpGroupBy) != 0 {
return int32(WRC_Abort)
}
if _sqlite3WalkExpr(tls, pWalker, (*TSelect)(unsafe.Pointer(p)).FpHaving) != 0 {
return int32(WRC_Abort)
}
if _sqlite3WalkExprList(tls, pWalker, (*TSelect)(unsafe.Pointer(p)).FpOrderBy) != 0 {
return int32(WRC_Abort)
}
if _sqlite3WalkExpr(tls, pWalker, (*TSelect)(unsafe.Pointer(p)).FpLimit) != 0 {
return int32(WRC_Abort)
}
if (*TSelect)(unsafe.Pointer(p)).FpWinDefn != 0 {
if v2 = (*TWalker)(unsafe.Pointer(pWalker)).FxSelectCallback2 == __ccgo_fp(_sqlite3WalkWinDefnDummyCallback); !v2 {
v1 = (*TWalker)(unsafe.Pointer(pWalker)).FpParse
pParse = v1
}
if v2 || v1 != uintptr(0) && libc.Int32FromUint8((*TParse)(unsafe.Pointer(pParse)).FeParseMode) >= int32(PARSE_MODE_RENAME) || (*TWalker)(unsafe.Pointer(pWalker)).FxSelectCallback2 == __ccgo_fp(_sqlite3SelectPopWith) {
/* The following may return WRC_Abort if there are unresolvable
** symbols (e.g. a table that does not exist) in a window definition. */
rc = _walkWindowList(tls, pWalker, (*TSelect)(unsafe.Pointer(p)).FpWinDefn, 0)
return rc
}
}
return WRC_Continue
}
// C documentation
//
// /*
// ** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN
// ** command, or if stmt_scanstatus_v2() stats are enabled, or if SQLITE_DEBUG
// ** was defined at compile-time. If it is not a no-op, a single OP_Explain
// ** opcode is added to the output to describe the table scan strategy in pLevel.
// **
// ** If an OP_Explain opcode is added to the VM, its address is returned.
// ** Otherwise, if no OP_Explain is coded, zero is returned.
// */
func _sqlite3WhereExplainOneScan(tls *libc.TLS, pParse uintptr, pTabList uintptr, pLevel uintptr, wctrlFlags Tu16) (r int32) {
var addr, ret int32
var v, v1 uintptr
_, _, _, _ = addr, ret, v, v1
ret = 0
if (*TParse)(unsafe.Pointer(pParse)).FpToplevel != 0 {
v1 = (*TParse)(unsafe.Pointer(pParse)).FpToplevel
} else {
v1 = pParse
}
if libc.Int32FromUint8((*TParse)(unsafe.Pointer(v1)).Fexplain) == int32(2) || libc.Bool(0 != 0) {
if (*TWhereLoop)(unsafe.Pointer((*TWhereLevel)(unsafe.Pointer(pLevel)).FpWLoop)).FwsFlags&uint32(WHERE_MULTI_OR) == uint32(0) && libc.Int32FromUint16(wctrlFlags)&int32(WHERE_OR_SUBCLAUSE) == 0 {
v = (*TParse)(unsafe.Pointer(pParse)).FpVdbe
addr = _sqlite3VdbeCurrentAddr(tls, v)
ret = _sqlite3VdbeAddOp3(tls, v, int32(OP_Explain), addr, (*TParse)(unsafe.Pointer(pParse)).FaddrExplain, int32((*TWhereLoop)(unsafe.Pointer((*TWhereLevel)(unsafe.Pointer(pLevel)).FpWLoop)).FrRun))
_sqlite3WhereAddExplainText(tls, pParse, addr, pTabList, pLevel, wctrlFlags)
}
}
return ret
}
func _sqlite3WhereExprUsageNN(tls *libc.TLS, pMaskSet uintptr, p uintptr) (r TBitmask) {
if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(p)).Fop) == int32(TK_COLUMN) && !((*TExpr)(unsafe.Pointer(p)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_FixedCol)) != libc.Uint32FromInt32(0)) {
return _sqlite3WhereGetMask(tls, pMaskSet, (*TExpr)(unsafe.Pointer(p)).FiTable)
} else {
if (*TExpr)(unsafe.Pointer(p)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_TokenOnly)|libc.Int32FromInt32(EP_Leaf)) != uint32(0) {
return uint64(0)
}
}
return _sqlite3WhereExprUsageFull(tls, pMaskSet, p)
}
// C documentation
//
// /*
// ** Return one of the WHERE_DISTINCT_xxxxx values to indicate how this
// ** WHERE clause returns outputs for DISTINCT processing.
// */
func _sqlite3WhereIsDistinct(tls *libc.TLS, pWInfo uintptr) (r int32) {
return libc.Int32FromUint8((*TWhereInfo)(unsafe.Pointer(pWInfo)).FeDistinct)
}
// C documentation
//
// /*
// ** This routine identifies subexpressions in the WHERE clause where
// ** each subexpression is separated by the AND operator or some other
// ** operator specified in the op parameter. The WhereClause structure
// ** is filled with pointers to subexpressions. For example:
// **
// ** WHERE a=='hello' AND coalesce(b,11)<10 AND (c+12!=d OR c==22)
// ** \________/ \_______________/ \________________/
// ** slot[0] slot[1] slot[2]
// **
// ** The original WHERE clause in pExpr is unaltered. All this routine
// ** does is make slot[] entries point to substructure within pExpr.
// **
// ** In the previous sentence and in the diagram, "slot[]" refers to
// ** the WhereClause.a[] array. The slot[] array grows as needed to contain
// ** all terms of the WHERE clause.
// */
func _sqlite3WhereSplit(tls *libc.TLS, pWC uintptr, pExpr uintptr, op Tu8) {
var pE2 uintptr
_ = pE2
pE2 = _sqlite3ExprSkipCollateAndLikely(tls, pExpr)
(*TWhereClause)(unsafe.Pointer(pWC)).Fop = op
if pE2 == uintptr(0) {
return
}
if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pE2)).Fop) != libc.Int32FromUint8(op) {
_whereClauseInsert(tls, pWC, pExpr, uint16(0))
} else {
_sqlite3WhereSplit(tls, pWC, (*TExpr)(unsafe.Pointer(pE2)).FpLeft, op)
_sqlite3WhereSplit(tls, pWC, (*TExpr)(unsafe.Pointer(pE2)).FpRight, op)
}
}
// C documentation
//
// /*
// ** Return 0 if the two window objects are identical, 1 if they are
// ** different, or 2 if it cannot be determined if the objects are identical
// ** or not. Identical window objects can be processed in a single scan.
// */
func _sqlite3WindowCompare(tls *libc.TLS, pParse uintptr, p1 uintptr, p2 uintptr, bFilter int32) (r int32) {
var res, v1 int32
_, _ = res, v1
if p1 == uintptr(0) || p2 == uintptr(0) {
return int32(1)
}
if libc.Int32FromUint8((*TWindow)(unsafe.Pointer(p1)).FeFrmType) != libc.Int32FromUint8((*TWindow)(unsafe.Pointer(p2)).FeFrmType) {
return int32(1)
}
if libc.Int32FromUint8((*TWindow)(unsafe.Pointer(p1)).FeStart) != libc.Int32FromUint8((*TWindow)(unsafe.Pointer(p2)).FeStart) {
return int32(1)
}
if libc.Int32FromUint8((*TWindow)(unsafe.Pointer(p1)).FeEnd) != libc.Int32FromUint8((*TWindow)(unsafe.Pointer(p2)).FeEnd) {
return int32(1)
}
if libc.Int32FromUint8((*TWindow)(unsafe.Pointer(p1)).FeExclude) != libc.Int32FromUint8((*TWindow)(unsafe.Pointer(p2)).FeExclude) {
return int32(1)
}
if _sqlite3ExprCompare(tls, pParse, (*TWindow)(unsafe.Pointer(p1)).FpStart, (*TWindow)(unsafe.Pointer(p2)).FpStart, -int32(1)) != 0 {
return int32(1)
}
if _sqlite3ExprCompare(tls, pParse, (*TWindow)(unsafe.Pointer(p1)).FpEnd, (*TWindow)(unsafe.Pointer(p2)).FpEnd, -int32(1)) != 0 {
return int32(1)
}
v1 = _sqlite3ExprListCompare(tls, (*TWindow)(unsafe.Pointer(p1)).FpPartition, (*TWindow)(unsafe.Pointer(p2)).FpPartition, -int32(1))
res = v1
if v1 != 0 {
return res
}
v1 = _sqlite3ExprListCompare(tls, (*TWindow)(unsafe.Pointer(p1)).FpOrderBy, (*TWindow)(unsafe.Pointer(p2)).FpOrderBy, -int32(1))
res = v1
if v1 != 0 {
return res
}
if bFilter != 0 {
v1 = _sqlite3ExprCompare(tls, pParse, (*TWindow)(unsafe.Pointer(p1)).FpFilter, (*TWindow)(unsafe.Pointer(p2)).FpFilter, -int32(1))
res = v1
if v1 != 0 {
return res
}
}
return 0
}
// C documentation
//
// /*
// ** When rewriting a query, if the new subquery in the FROM clause
// ** contains TK_AGG_FUNCTION nodes that refer to an outer query,
// ** then we have to increase the Expr->op2 values of those nodes
// ** due to the extra subquery layer that was added.
// **
// ** See also the incrAggDepth() routine in resolve.c
// */
func _sqlite3WindowExtraAggFuncDepth(tls *libc.TLS, pWalker uintptr, pExpr uintptr) (r int32) {
if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) == int32(TK_AGG_FUNCTION) && libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop2) >= (*TWalker)(unsafe.Pointer(pWalker)).FwalkerDepth {
(*TExpr)(unsafe.Pointer(pExpr)).Fop2 = (*TExpr)(unsafe.Pointer(pExpr)).Fop2 + 1
}
return WRC_Continue
}
// C documentation
//
// /*
// ** The argument expression is an PRECEDING or FOLLOWING offset. The
// ** value should be a non-negative integer. If the value is not a
// ** constant, change it to NULL. The fact that it is then a non-negative
// ** integer will be caught later. But it is important not to leave
// ** variable values in the expression tree.
// */
func _sqlite3WindowOffsetExpr(tls *libc.TLS, pParse uintptr, pExpr uintptr) (r uintptr) {
if 0 == _sqlite3ExprIsConstant(tls, uintptr(0), pExpr) {
if libc.Int32FromUint8((*TParse)(unsafe.Pointer(pParse)).FeParseMode) >= int32(PARSE_MODE_RENAME) {
_sqlite3RenameExprUnmap(tls, pParse, pExpr)
}
_sqlite3ExprDelete(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, pExpr)
pExpr = _sqlite3ExprAlloc(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, int32(TK_NULL), uintptr(0), 0)
}
return pExpr
}
// C documentation
//
// /*
// ** True if PRAGMA writable_schema is ON
// */
func _sqlite3WritableSchema(tls *libc.TLS, db uintptr) (r int32) {
return libc.BoolInt32((*Tsqlite3)(unsafe.Pointer(db)).Fflags&libc.Uint64FromInt32(libc.Int32FromInt32(SQLITE_WriteSchema)|libc.Int32FromInt32(SQLITE_Defensive)) == uint64(SQLITE_WriteSchema))
}
// C documentation
//
// /*
// ** This routine translates a standard POSIX errno code into something
// ** useful to the clients of the sqlite3 functions. Specifically, it is
// ** intended to translate a variety of "try again" errors into SQLITE_BUSY
// ** and a variety of "please close the file descriptor NOW" errors into
// ** SQLITE_IOERR
// **
// ** Errors during initialization of locks, or file system support for locks,
// ** should handle ENOLCK, ENOTSUP, EOPNOTSUPP separately.
// */
func _sqliteErrorFromPosixError(tls *libc.TLS, posixError int32, sqliteIOErr int32) (r int32) {
switch posixError {
case int32(EACCES):
fallthrough
case int32(EAGAIN):
fallthrough
case int32(ETIMEDOUT):
fallthrough
case int32(EBUSY):
fallthrough
case int32(EINTR):
fallthrough
case int32(ENOLCK):
/* random NFS retry error, unless during file system support
* introspection, in which it actually means what it says */
return int32(SQLITE_BUSY)
case int32(EPERM):
return int32(SQLITE_PERM)
default:
return sqliteIOErr
}
return r
}
func _statEof(tls *libc.TLS, pCursor uintptr) (r int32) {
var pCsr uintptr
_ = pCsr
pCsr = pCursor
return libc.Int32FromUint8((*TStatCursor)(unsafe.Pointer(pCsr)).FisEof)
}
func _statRowid(tls *libc.TLS, pCursor uintptr, pRowid uintptr) (r int32) {
var pCsr uintptr
_ = pCsr
pCsr = pCursor
**(**Tsqlite_int64)(__ccgo_up(pRowid)) = libc.Int64FromUint32((*TStatCursor)(unsafe.Pointer(pCsr)).FiPageno)
return SQLITE_OK
}
// C documentation
//
// /*
// ** Set the pFile->lastErrno. Do this in a subroutine as that provides
// ** a convenient place to set a breakpoint.
// */
func _storeLastErrno(tls *libc.TLS, pFile uintptr, error1 int32) {
(*TunixFile)(unsafe.Pointer(pFile)).FlastErrno = error1
}
// C documentation
//
// /*
// ** Buffer zStr contains nStr bytes of utf-8 encoded text. Return 1 if zStr
// ** contains character ch, or 0 if it does not.
// */
func _strContainsChar(tls *libc.TLS, zStr uintptr, nStr int32, ch Tu32) (r int32) {
bp := tls.Alloc(16)
defer tls.Free(16)
var tst Tu32
var zEnd, v2 uintptr
var v1 uint32
var _ /* z at bp+0 */ uintptr
_, _, _, _ = tst, zEnd, v1, v2
zEnd = zStr + uintptr(nStr)
**(**uintptr)(__ccgo_up(bp)) = zStr
for **(**uintptr)(__ccgo_up(bp)) < zEnd {
if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp))))) < int32(0x80) {
v2 = **(**uintptr)(__ccgo_up(bp))
**(**uintptr)(__ccgo_up(bp)) = **(**uintptr)(__ccgo_up(bp)) + 1
v1 = uint32(**(**Tu8)(__ccgo_up(v2)))
} else {
v1 = _sqlite3Utf8Read(tls, bp)
}
tst = v1
if tst == ch {
return int32(1)
}
}
return 0
}
// C documentation
//
// /*
// ** Append a record of the current state of page pPg to the sub-journal.
// **
// ** If successful, set the bit corresponding to pPg->pgno in the bitvecs
// ** for all open savepoints before returning.
// **
// ** This function returns SQLITE_OK if everything is successful, an IO
// ** error code if the attempt to write to the sub-journal fails, or
// ** SQLITE_NOMEM if a malloc fails while setting a bit in a savepoint
// ** bitvec.
// */
func _subjournalPage(tls *libc.TLS, pPg uintptr) (r int32) {
var offset Ti64
var pData, pData2, pPager uintptr
var rc int32
_, _, _, _, _ = offset, pData, pData2, pPager, rc
rc = SQLITE_OK
pPager = (*TPgHdr)(unsafe.Pointer(pPg)).FpPager
if libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FjournalMode) != int32(PAGER_JOURNALMODE_OFF) {
/* Open the sub-journal, if it has not already been opened */
rc = _openSubJournal(tls, pPager)
/* If the sub-journal was opened successfully (or was already open),
** write the journal record into the file. */
if rc == SQLITE_OK {
pData = (*TPgHdr)(unsafe.Pointer(pPg)).FpData
offset = libc.Int64FromUint32((*TPager)(unsafe.Pointer(pPager)).FnSubRec) * (int64(4) + (*TPager)(unsafe.Pointer(pPager)).FpageSize)
pData2 = pData
rc = _write32bits(tls, (*TPager)(unsafe.Pointer(pPager)).Fsjfd, offset, (*TPgHdr)(unsafe.Pointer(pPg)).Fpgno)
if rc == SQLITE_OK {
rc = _sqlite3OsWrite(tls, (*TPager)(unsafe.Pointer(pPager)).Fsjfd, pData2, int32((*TPager)(unsafe.Pointer(pPager)).FpageSize), offset+int64(4))
}
}
}
if rc == SQLITE_OK {
(*TPager)(unsafe.Pointer(pPager)).FnSubRec = (*TPager)(unsafe.Pointer(pPager)).FnSubRec + 1
rc = _addToSavepointBitvecs(tls, pPager, (*TPgHdr)(unsafe.Pointer(pPg)).Fpgno)
}
return rc
}
// C documentation
//
// /* subtype(X)
// **
// ** Return the subtype of X
// */
func _subtypeFunc(tls *libc.TLS, context uintptr, argc int32, argv uintptr) {
_ = argc
Xsqlite3_result_int(tls, context, libc.Int32FromUint32(Xsqlite3_value_subtype(tls, **(**uintptr)(__ccgo_up(argv)))))
}
func _tabIsReadOnly(tls *libc.TLS, pParse uintptr, pTab uintptr) (r int32) {
var db uintptr
_ = db
if libc.Int32FromUint8((*TTable)(unsafe.Pointer(pTab)).FeTabType) == int32(TABTYP_VTAB) {
return _vtabIsReadOnly(tls, pParse, pTab)
}
if (*TTable)(unsafe.Pointer(pTab)).FtabFlags&libc.Uint32FromInt32(libc.Int32FromInt32(TF_Readonly)|libc.Int32FromInt32(TF_Shadow)) == uint32(0) {
return 0
}
db = (*TParse)(unsafe.Pointer(pParse)).Fdb
if (*TTable)(unsafe.Pointer(pTab)).FtabFlags&uint32(TF_Readonly) != uint32(0) {
return libc.BoolInt32(_sqlite3WritableSchema(tls, db) == 0 && libc.Int32FromUint8((*TParse)(unsafe.Pointer(pParse)).Fnested) == 0)
}
return _sqlite3ReadOnlyShadowTables(tls, db)
}
// C documentation
//
// /*
// ** The unicode() function. Return the integer unicode code-point value
// ** for the first character of the input string.
// */
func _unicodeFunc(tls *libc.TLS, context uintptr, argc int32, argv uintptr) {
bp := tls.Alloc(16)
defer tls.Free(16)
var _ /* z at bp+0 */ uintptr
**(**uintptr)(__ccgo_up(bp)) = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv)))
_ = argc
if **(**uintptr)(__ccgo_up(bp)) != 0 && **(**uint8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp)))) != 0 {
Xsqlite3_result_int(tls, context, libc.Int32FromUint32(_sqlite3Utf8Read(tls, bp)))
}
}
// C documentation
//
// /*
// ** Helper functions to obtain and relinquish the global mutex. The
// ** global mutex is used to protect the unixInodeInfo objects used by
// ** this file, all of which may be shared by multiple threads.
// **
// ** Function unixMutexHeld() is used to assert() that the global mutex
// ** is held when required. This function is only used as part of assert()
// ** statements. e.g.
// **
// ** unixEnterMutex()
// ** assert( unixMutexHeld() );
// ** unixEnterLeave()
// **
// ** To prevent deadlock, the global unixBigLock must must be acquired
// ** before the unixInodeInfo.pLockMutex mutex, if both are held. It is
// ** OK to get the pLockMutex without holding unixBigLock first, but if
// ** that happens, the unixBigLock mutex must not be acquired until after
// ** pLockMutex is released.
// **
// ** OK: enter(unixBigLock), enter(pLockInfo)
// ** OK: enter(unixBigLock)
// ** OK: enter(pLockInfo)
// ** ERROR: enter(pLockInfo), enter(unixBigLock)
// */
var _unixBigLock = uintptr(0)
// C documentation
//
// /*
// ** Close a file.
// */
func _unixClose(tls *libc.TLS, id uintptr) (r int32) {
var pFile, pInode uintptr
var rc int32
_, _, _ = pFile, pInode, rc
rc = SQLITE_OK
pFile = id
pInode = (*TunixFile)(unsafe.Pointer(pFile)).FpInode
_verifyDbFile(tls, pFile)
_unixUnlock(tls, id, NO_LOCK)
_unixEnterMutex(tls)
/* unixFile.pInode is always valid here. Otherwise, a different close
** routine (e.g. nolockClose()) would be called instead.
*/
Xsqlite3_mutex_enter(tls, (*TunixInodeInfo)(unsafe.Pointer(pInode)).FpLockMutex)
if (*TunixInodeInfo)(unsafe.Pointer(pInode)).FnLock != 0 {
/* If there are outstanding locks, do not actually close the file just
** yet because that would clear those locks. Instead, add the file
** descriptor to pInode->pUnused list. It will be automatically closed
** when the last lock is cleared.
*/
_setPendingFd(tls, pFile)
}
Xsqlite3_mutex_leave(tls, (*TunixInodeInfo)(unsafe.Pointer(pInode)).FpLockMutex)
_releaseInodeInfo(tls, pFile)
rc = _closeUnixFile(tls, id)
_unixLeaveMutex(tls)
return rc
}
/************** End of the posix advisory lock implementation *****************
******************************************************************************/
/******************************************************************************
****************************** No-op Locking **********************************
**
** Of the various locking implementations available, this is by far the
** simplest: locking is ignored. No attempt is made to lock the database
** file for reading or writing.
**
** This locking mode is appropriate for use on read-only databases
** (ex: databases that are burned into CD-ROM, for example.) It can
** also be used if the application employs some external mechanism to
** prevent simultaneous access of the same database by two or more
** database connections. But there is a serious risk of database
** corruption if this locking mode is used in situations where multiple
** database connections are accessing the same database file at the same
** time and one or more of those connections are writing.
*/
// C documentation
//
// /*
// ** Find the current time (in Universal Coordinated Time). Write the
// ** current time and date as a Julian Day number into *prNow and
// ** return 0. Return 1 if the time and date cannot be found.
// */
func _unixCurrentTime(tls *libc.TLS, NotUsed uintptr, prNow uintptr) (r int32) {
bp := tls.Alloc(16)
defer tls.Free(16)
var rc int32
var _ /* i at bp+0 */ Tsqlite3_int64
_ = rc
**(**Tsqlite3_int64)(__ccgo_up(bp)) = 0
_ = NotUsed
rc = _unixCurrentTimeInt64(tls, uintptr(0), bp)
**(**float64)(__ccgo_up(prNow)) = float64(**(**Tsqlite3_int64)(__ccgo_up(bp))) / float64(8.64e+07)
return rc
}
// C documentation
//
// /*
// ** Return the device characteristics for the file.
// **
// ** This VFS is set up to return SQLITE_IOCAP_POWERSAFE_OVERWRITE by default.
// ** However, that choice is controversial since technically the underlying
// ** file system does not always provide powersafe overwrites. (In other
// ** words, after a power-loss event, parts of the file that were never
// ** written might end up being altered.) However, non-PSOW behavior is very,
// ** very rare. And asserting PSOW makes a large reduction in the amount
// ** of required I/O for journaling, since a lot of padding is eliminated.
// ** Hence, while POWERSAFE_OVERWRITE is on by default, there is a file-control
// ** available to turn it off and URI query parameter available to turn it off.
// */
func _unixDeviceCharacteristics(tls *libc.TLS, id uintptr) (r int32) {
var pFd uintptr
_ = pFd
pFd = id
_setDeviceCharacteristics(tls, pFd)
return (*TunixFile)(unsafe.Pointer(pFd)).FdeviceCharacteristics
}
func _unixDlClose(tls *libc.TLS, NotUsed uintptr, pHandle uintptr) {
_ = NotUsed
libc.Xdlclose(tls, pHandle)
}
func _unixDlOpen(tls *libc.TLS, NotUsed uintptr, zFilename uintptr) (r uintptr) {
_ = NotUsed
return libc.Xdlopen(tls, zFilename, libc.Int32FromInt32(RTLD_NOW)|libc.Int32FromInt32(RTLD_GLOBAL))
}
func _unixDlSym(tls *libc.TLS, NotUsed uintptr, p uintptr, zSym uintptr) (r uintptr) {
var x uintptr
_ = x
_ = NotUsed
x = __ccgo_fp(libc.Xdlsym)
return (*(*func(*libc.TLS, uintptr, uintptr) uintptr)(unsafe.Pointer(&struct{ uintptr }{x})))(tls, p, zSym)
}
func _unixEnterMutex(tls *libc.TLS) {
/* Not a recursive mutex */
Xsqlite3_mutex_enter(tls, _unixBigLock)
}
var _unixEpoch = libc.Int64FromInt32(24405875) * libc.Int64FromInt32(8640000)
func _unixLeaveMutex(tls *libc.TLS) {
Xsqlite3_mutex_leave(tls, _unixBigLock)
}
// C documentation
//
// /*
// ** Return the sector size in bytes of the underlying block device for
// ** the specified file. This is almost always 512 bytes, but may be
// ** larger for some devices.
// **
// ** SQLite code assumes this function cannot fail. It also assumes that
// ** if two files are created in the same file-system directory (i.e.
// ** a database and its journal file) that the sector size will be the
// ** same for both.
// */
func _unixSectorSize(tls *libc.TLS, id uintptr) (r int32) {
var pFd uintptr
_ = pFd
pFd = id
_setDeviceCharacteristics(tls, pFd)
return (*TunixFile)(unsafe.Pointer(pFd)).FsectorSize
}
// C documentation
//
// /*
// ** Return the minimum number of 32KB shm regions that should be mapped at
// ** a time, assuming that each mapping must be an integer multiple of the
// ** current system page-size.
// **
// ** Usually, this is 1. The exception seems to be systems that are configured
// ** to use 64KB pages - in this case each mapping must cover at least two
// ** shm regions.
// */
func _unixShmRegionPerMap(tls *libc.TLS) (r int32) {
var pgsz, shmsz int32
_, _ = pgsz, shmsz
shmsz = libc.Int32FromInt32(32) * libc.Int32FromInt32(1024) /* SHM region size */
pgsz = (*(*func(*libc.TLS) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(25)].FpCurrent})))(tls) /* System page size */
/* Page size must be a power of 2 */
if pgsz < shmsz {
return int32(1)
}
return pgsz / shmsz
}
// C documentation
//
// /*
// ** Lower the locking level on file descriptor pFile to eFileLock. eFileLock
// ** must be either NO_LOCK or SHARED_LOCK.
// **
// ** If the locking level of the file descriptor is already at or below
// ** the requested locking level, this routine is a no-op.
// */
func _unixUnlock(tls *libc.TLS, id uintptr, eFileLock int32) (r int32) {
return _posixUnlock(tls, id, eFileLock, 0)
}
// C documentation
//
// /*
// ** Write data from a buffer into a file. Return SQLITE_OK on success
// ** or some other error code on failure.
// */
func _unixWrite(tls *libc.TLS, id uintptr, pBuf uintptr, amt int32, offset Tsqlite3_int64) (r int32) {
var pFile uintptr
var wrote, v1 int32
_, _, _ = pFile, wrote, v1
pFile = id
wrote = 0
/* If this is a database file (not a journal, super-journal or temp
** file), the bytes in the locking range should never be read or written. */
for {
v1 = _seekAndWrite(tls, pFile, offset, pBuf, amt)
wrote = v1
if !(v1 < amt && wrote > 0) {
break
}
amt = amt - wrote
offset = offset + int64(wrote)
pBuf = pBuf + uintptr(wrote)
}
if amt > wrote {
if wrote < 0 && (*TunixFile)(unsafe.Pointer(pFile)).FlastErrno != int32(ENOSPC) {
/* lastErrno set by seekAndWrite */
return libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(3)<<libc.Int32FromInt32(8)
} else {
_storeLastErrno(tls, pFile, 0) /* not a system error */
return int32(SQLITE_FULL)
}
}
return SQLITE_OK
}
/*
** We do not trust systems to provide a working fdatasync(). Some do.
** Others do no. To be safe, we will stick with the (slightly slower)
** fsync(). If you know that your system does support fdatasync() correctly,
** then simply compile with -Dfdatasync=fdatasync or -DHAVE_FDATASYNC
*/
/*
** Define HAVE_FULLFSYNC to 0 or 1 depending on whether or not
** the F_FULLFSYNC macro is defined. F_FULLFSYNC is currently
** only available on Mac OS X. But that could change.
*/
// C documentation
//
// /*
// ** If there are no outstanding cursors and we are not in the middle
// ** of a transaction but there is a read lock on the database, then
// ** this routine unrefs the first page of the database file which
// ** has the effect of releasing the read lock.
// **
// ** If there is a transaction in progress, this routine is a no-op.
// */
func _unlockBtreeIfUnused(tls *libc.TLS, pBt uintptr) {
var pPage1 uintptr
_ = pPage1
if libc.Int32FromUint8((*TBtShared)(unsafe.Pointer(pBt)).FinTransaction) == TRANS_NONE && (*TBtShared)(unsafe.Pointer(pBt)).FpPage1 != uintptr(0) {
pPage1 = (*TBtShared)(unsafe.Pointer(pBt)).FpPage1
(*TBtShared)(unsafe.Pointer(pBt)).FpPage1 = uintptr(0)
_releasePageOne(tls, pPage1)
}
}
func _vdbeCompareMemString(tls *libc.TLS, pMem1 uintptr, pMem2 uintptr, pColl uintptr, prcErr uintptr) (r int32) {
if libc.Int32FromUint8((*TMem)(unsafe.Pointer(pMem1)).Fenc) == libc.Int32FromUint8((*TCollSeq)(unsafe.Pointer(pColl)).Fenc) {
/* The strings are already in the correct encoding. Call the
** comparison function directly */
return (*(*func(*libc.TLS, uintptr, int32, uintptr, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*TCollSeq)(unsafe.Pointer(pColl)).FxCmp})))(tls, (*TCollSeq)(unsafe.Pointer(pColl)).FpUser, (*TMem)(unsafe.Pointer(pMem1)).Fn, (*TMem)(unsafe.Pointer(pMem1)).Fz, (*TMem)(unsafe.Pointer(pMem2)).Fn, (*TMem)(unsafe.Pointer(pMem2)).Fz)
} else {
return _vdbeCompareMemStringWithEncodingChange(tls, pMem1, pMem2, pColl, prcErr)
}
return r
}
// C documentation
//
// /*
// ** Release memory held by the Mem p, both external memory cleared
// ** by p->xDel and memory in p->zMalloc.
// **
// ** This is a helper routine invoked by sqlite3VdbeMemRelease() in
// ** the unusual case where there really is memory in p that needs
// ** to be freed.
// */
func _vdbeMemClear(tls *libc.TLS, p uintptr) {
if libc.Int32FromUint16((*TMem)(unsafe.Pointer(p)).Fflags)&(libc.Int32FromInt32(MEM_Agg)|libc.Int32FromInt32(MEM_Dyn)) != 0 {
_vdbeMemClearExternAndSetNull(tls, p)
}
if (*TMem)(unsafe.Pointer(p)).FszMalloc != 0 {
_sqlite3DbFreeNN(tls, (*TMem)(unsafe.Pointer(p)).Fdb, (*TMem)(unsafe.Pointer(p)).FzMalloc)
(*TMem)(unsafe.Pointer(p)).FszMalloc = 0
}
(*TMem)(unsafe.Pointer(p)).Fz = uintptr(0)
}
// C documentation
//
// /*
// ** Read a varint from the stream of data accessed by p. Set *pnOut to
// ** the value read.
// */
func _vdbePmaReadVarint(tls *libc.TLS, p uintptr, pnOut uintptr) (r int32) {
bp := tls.Alloc(32)
defer tls.Free(32)
var i, iBuf, rc, v1 int32
var _ /* a at bp+16 */ uintptr
var _ /* aVarint at bp+0 */ [16]Tu8
_, _, _, _ = i, iBuf, rc, v1
if (*TPmaReader)(unsafe.Pointer(p)).FaMap != 0 {
**(**Ti64)(__ccgo_up(p)) += libc.Int64FromUint8(_sqlite3GetVarint(tls, (*TPmaReader)(unsafe.Pointer(p)).FaMap+uintptr((*TPmaReader)(unsafe.Pointer(p)).FiReadOff), pnOut))
} else {
iBuf = int32((*TPmaReader)(unsafe.Pointer(p)).FiReadOff % int64((*TPmaReader)(unsafe.Pointer(p)).FnBuffer))
if iBuf != 0 && (*TPmaReader)(unsafe.Pointer(p)).FnBuffer-iBuf >= int32(9) {
**(**Ti64)(__ccgo_up(p)) += libc.Int64FromUint8(_sqlite3GetVarint(tls, (*TPmaReader)(unsafe.Pointer(p)).FaBuffer+uintptr(iBuf), pnOut))
} else {
i = 0
for cond := true; cond; cond = libc.Int32FromUint8(**(**Tu8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp + 16)))))&int32(0x80) != 0 {
rc = _vdbePmaReadBlob(tls, p, int32(1), bp+16)
if rc != 0 {
return rc
}
v1 = i
i = i + 1
(**(**[16]Tu8)(__ccgo_up(bp)))[v1&int32(0xf)] = **(**Tu8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp + 16))))
}
_sqlite3GetVarint(tls, bp, pnOut)
}
}
return SQLITE_OK
}
// C documentation
//
// /*
// ** Initialize PmaReader pReadr to scan through the PMA stored in file pFile
// ** starting at offset iStart and ending at offset iEof-1. This function
// ** leaves the PmaReader pointing to the first key in the PMA (or EOF if the
// ** PMA is empty).
// **
// ** If the pnByte parameter is NULL, then it is assumed that the file
// ** contains a single PMA, and that that PMA omits the initial length varint.
// */
func _vdbePmaReaderInit(tls *libc.TLS, pTask uintptr, pFile uintptr, iStart Ti64, pReadr uintptr, pnByte uintptr) (r int32) {
bp := tls.Alloc(16)
defer tls.Free(16)
var rc int32
var v1 uintptr
var _ /* nByte at bp+0 */ Tu64
_, _ = rc, v1
rc = _vdbePmaReaderSeek(tls, pTask, pReadr, pFile, iStart)
if rc == SQLITE_OK {
**(**Tu64)(__ccgo_up(bp)) = uint64(0) /* Size of PMA in bytes */
rc = _vdbePmaReadVarint(tls, pReadr, bp)
(*TPmaReader)(unsafe.Pointer(pReadr)).FiEof = libc.Int64FromUint64(libc.Uint64FromInt64((*TPmaReader)(unsafe.Pointer(pReadr)).FiReadOff) + **(**Tu64)(__ccgo_up(bp)))
v1 = pnByte
*(*Ti64)(unsafe.Pointer(v1)) = Ti64(uint64(*(*Ti64)(unsafe.Pointer(v1))) + **(**Tu64)(__ccgo_up(bp)))
}
if rc == SQLITE_OK {
rc = _vdbePmaReaderNext(tls, pReadr)
}
return rc
}
// C documentation
//
// /*
// ** The first argument passed to this function is a serial-type that
// ** corresponds to an integer - all values between 1 and 9 inclusive
// ** except 7. The second points to a buffer containing an integer value
// ** serialized according to serial_type. This function deserializes
// ** and returns the value.
// */
func _vdbeRecordDecodeInt(tls *libc.TLS, serial_type Tu32, aKey uintptr) (r Ti64) {
bp := tls.Alloc(16)
defer tls.Free(16)
var _ /* x at bp+8 */ Tu64
var _ /* y at bp+0 */ Tu32
switch serial_type {
case uint32(0):
fallthrough
case uint32(1):
return int64(libc.Int8FromUint8(**(**Tu8)(__ccgo_up(aKey))))
case uint32(2):
return int64(libc.Int32FromInt32(256)*int32(libc.Int8FromUint8(**(**Tu8)(__ccgo_up(aKey)))) | libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aKey + 1))))
case uint32(3):
return int64(libc.Int32FromInt32(65536)*int32(libc.Int8FromUint8(**(**Tu8)(__ccgo_up(aKey)))) | libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aKey + 1)))<<libc.Int32FromInt32(8) | libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aKey + 2))))
case uint32(4):
**(**Tu32)(__ccgo_up(bp)) = uint32(**(**Tu8)(__ccgo_up(aKey)))<<libc.Int32FromInt32(24) | libc.Uint32FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aKey + 1)))<<libc.Int32FromInt32(16)) | libc.Uint32FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aKey + 2)))<<libc.Int32FromInt32(8)) | uint32(**(**Tu8)(__ccgo_up(aKey + 3)))
return int64(**(**int32)(__ccgo_up(bp)))
case uint32(5):
return libc.Int64FromUint32(uint32(**(**Tu8)(__ccgo_up(aKey + libc.UintptrFromInt32(2))))<<libc.Int32FromInt32(24)|libc.Uint32FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aKey + libc.UintptrFromInt32(2) + 1)))<<libc.Int32FromInt32(16))|libc.Uint32FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aKey + libc.UintptrFromInt32(2) + 2)))<<libc.Int32FromInt32(8))|uint32(**(**Tu8)(__ccgo_up(aKey + libc.UintptrFromInt32(2) + 3)))) + libc.Int64FromInt32(1)<<libc.Int32FromInt32(32)*int64(libc.Int32FromInt32(256)*int32(libc.Int8FromUint8(**(**Tu8)(__ccgo_up(aKey))))|libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aKey + 1))))
case uint32(6):
**(**Tu64)(__ccgo_up(bp + 8)) = uint64(uint32(**(**Tu8)(__ccgo_up(aKey)))<<libc.Int32FromInt32(24) | libc.Uint32FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aKey + 1)))<<libc.Int32FromInt32(16)) | libc.Uint32FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aKey + 2)))<<libc.Int32FromInt32(8)) | uint32(**(**Tu8)(__ccgo_up(aKey + 3))))
**(**Tu64)(__ccgo_up(bp + 8)) = **(**Tu64)(__ccgo_up(bp + 8))<<libc.Int32FromInt32(32) | uint64(uint32(**(**Tu8)(__ccgo_up(aKey + libc.UintptrFromInt32(4))))<<libc.Int32FromInt32(24)|libc.Uint32FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aKey + libc.UintptrFromInt32(4) + 1)))<<libc.Int32FromInt32(16))|libc.Uint32FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up(aKey + libc.UintptrFromInt32(4) + 2)))<<libc.Int32FromInt32(8))|uint32(**(**Tu8)(__ccgo_up(aKey + libc.UintptrFromInt32(4) + 3))))
return **(**Ti64)(__ccgo_up(bp + 8))
}
return libc.Int64FromUint32(serial_type - libc.Uint32FromInt32(8))
}
// C documentation
//
// /*
// ** A specially optimized version of vdbeSorterCompare() that assumes that
// ** the first field of each key is an INTEGER value.
// */
func _vdbeSorterCompareInt(tls *libc.TLS, pTask uintptr, pbKey2Cached uintptr, pKey1 uintptr, nKey1 int32, pKey2 uintptr, nKey2 int32) (r int32) {
var i, res, s1, s2, v21, v3 int32
var n Tu8
var p1, p2, v1, v2 uintptr
_, _, _, _, _, _, _, _, _, _, _ = i, n, p1, p2, res, s1, s2, v1, v2, v21, v3
p1 = pKey1
p2 = pKey2
s1 = libc.Int32FromUint8(**(**Tu8)(__ccgo_up(p1 + 1))) /* Left hand serial type */
s2 = libc.Int32FromUint8(**(**Tu8)(__ccgo_up(p2 + 1))) /* Right hand serial type */
v1 = p1 + uintptr(**(**Tu8)(__ccgo_up(p1))) /* Pointer to value 1 */
v2 = p2 + uintptr(**(**Tu8)(__ccgo_up(p2))) /* Return value */
if s1 == s2 {
n = _aLen[s1]
res = 0
i = 0
for {
if !(i < libc.Int32FromUint8(n)) {
break
}
v21 = libc.Int32FromUint8(**(**Tu8)(__ccgo_up(v1 + uintptr(i)))) - libc.Int32FromUint8(**(**Tu8)(__ccgo_up(v2 + uintptr(i))))
res = v21
if v21 != 0 {
if (libc.Int32FromUint8(**(**Tu8)(__ccgo_up(v1)))^libc.Int32FromUint8(**(**Tu8)(__ccgo_up(v2))))&int32(0x80) != 0 {
if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(v1)))&int32(0x80) != 0 {
v3 = -int32(1)
} else {
v3 = +libc.Int32FromInt32(1)
}
res = v3
}
break
}
goto _1
_1:
;
i = i + 1
}
} else {
if s1 > int32(7) && s2 > int32(7) {
res = s1 - s2
} else {
if s2 > int32(7) {
res = +libc.Int32FromInt32(1)
} else {
if s1 > int32(7) {
res = -int32(1)
} else {
res = s1 - s2
}
}
if res > 0 {
if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(v1)))&int32(0x80) != 0 {
res = -int32(1)
}
} else {
if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(v2)))&int32(0x80) != 0 {
res = +libc.Int32FromInt32(1)
}
}
}
}
if res == 0 {
if libc.Int32FromUint16((*TKeyInfo)(unsafe.Pointer((*TVdbeSorter)(unsafe.Pointer((*TSortSubtask)(unsafe.Pointer(pTask)).FpSorter)).FpKeyInfo)).FnKeyField) > int32(1) {
res = _vdbeSorterCompareTail(tls, pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2)
}
} else {
if **(**Tu8)(__ccgo_up((*TKeyInfo)(unsafe.Pointer((*TVdbeSorter)(unsafe.Pointer((*TSortSubtask)(unsafe.Pointer(pTask)).FpSorter)).FpKeyInfo)).FaSortFlags)) != 0 {
res = res * -int32(1)
}
}
return res
}
// C documentation
//
// /*
// ** Return the SorterCompare function to compare values collected by the
// ** sorter object passed as the only argument.
// */
func _vdbeSorterGetCompare(tls *libc.TLS, p uintptr) (r TSorterCompare) {
if libc.Int32FromUint8((*TVdbeSorter)(unsafe.Pointer(p)).FtypeMask) == int32(SORTER_TYPE_INTEGER) {
return __ccgo_fp(_vdbeSorterCompareInt)
} else {
if libc.Int32FromUint8((*TVdbeSorter)(unsafe.Pointer(p)).FtypeMask) == int32(SORTER_TYPE_TEXT) {
return __ccgo_fp(_vdbeSorterCompareText)
}
}
return __ccgo_fp(_vdbeSorterCompare)
}
// C documentation
//
// /*
// ** Compute a hash on a page number. The resulting hash value must land
// ** between 0 and (HASHTABLE_NSLOT-1). The walNextHash() function advances
// ** the hash to the next value in the event of a collision.
// */
func _walHash(tls *libc.TLS, iPage Tu32) (r int32) {
return libc.Int32FromUint32(iPage * uint32(HASHTABLE_HASH_1) & libc.Uint32FromInt32(libc.Int32FromInt32(HASHTABLE_NPAGE)*libc.Int32FromInt32(2)-libc.Int32FromInt32(1)))
}
// C documentation
//
// /*
// ** Read the wal-index header from the wal-index and into pWal->hdr.
// ** If the wal-header appears to be corrupt, try to reconstruct the
// ** wal-index from the WAL before returning.
// **
// ** Set *pChanged to 1 if the wal-index header value in pWal->hdr is
// ** changed by this operation. If pWal->hdr is unchanged, set *pChanged
// ** to 0.
// **
// ** If the wal-index header is successfully read, return SQLITE_OK.
// ** Otherwise an SQLite error code.
// */
func _walIndexReadHdr(tls *libc.TLS, pWal uintptr, pChanged uintptr) (r int32) {
bp := tls.Alloc(16)
defer tls.Free(16)
var bWriteLock, badHdr, rc, v1 int32
var v4 bool
var _ /* page0 at bp+0 */ uintptr
_, _, _, _, _ = bWriteLock, badHdr, rc, v1, v4 /* Chunk of wal-index containing header */
/* Ensure that page 0 of the wal-index (the page that contains the
** wal-index header) is mapped. Return early if an error occurs here.
*/
rc = _walIndexPage(tls, pWal, 0, bp)
if rc != SQLITE_OK {
/* READONLY changed to OK in walIndexPage */
if rc == libc.Int32FromInt32(SQLITE_READONLY)|libc.Int32FromInt32(5)<<libc.Int32FromInt32(8) {
/* The SQLITE_READONLY_CANTINIT return means that the shared-memory
** was openable but is not writable, and this thread is unable to
** confirm that another write-capable connection has the shared-memory
** open, and hence the content of the shared-memory is unreliable,
** since the shared-memory might be inconsistent with the WAL file
** and there is no writer on hand to fix it. */
(*TWal)(unsafe.Pointer(pWal)).FbShmUnreliable = uint8(1)
(*TWal)(unsafe.Pointer(pWal)).FexclusiveMode = uint8(WAL_HEAPMEMORY_MODE)
**(**int32)(__ccgo_up(pChanged)) = int32(1)
} else {
return rc /* Any other non-OK return is just an error */
}
} else {
/* page0 can be NULL if the SHM is zero bytes in size and pWal->writeLock
** is zero, which prevents the SHM from growing */
}
/* If the first page of the wal-index has been mapped, try to read the
** wal-index header immediately, without holding any lock. This usually
** works, but may fail if the wal-index header is corrupt or currently
** being modified by another thread or process.
*/
if **(**uintptr)(__ccgo_up(bp)) != 0 {
v1 = _walIndexTryHdr(tls, pWal, pChanged)
} else {
v1 = int32(1)
}
badHdr = v1
/* If the first attempt failed, it might have been due to a race
** with a writer. So get a WRITE lock and try again.
*/
if badHdr != 0 {
if libc.Int32FromUint8((*TWal)(unsafe.Pointer(pWal)).FbShmUnreliable) == 0 && libc.Int32FromUint8((*TWal)(unsafe.Pointer(pWal)).FreadOnly)&int32(WAL_SHM_RDONLY) != 0 {
v1 = _walLockShared(tls, pWal, WAL_WRITE_LOCK)
rc = v1
if SQLITE_OK == v1 {
_walUnlockShared(tls, pWal, WAL_WRITE_LOCK)
rc = libc.Int32FromInt32(SQLITE_READONLY) | libc.Int32FromInt32(1)<<libc.Int32FromInt32(8)
}
} else {
bWriteLock = libc.Int32FromUint8((*TWal)(unsafe.Pointer(pWal)).FwriteLock)
if v4 = bWriteLock != 0; !v4 {
v1 = _walLockExclusive(tls, pWal, WAL_WRITE_LOCK, int32(1))
rc = v1
}
if v4 || SQLITE_OK == v1 {
/* If the write-lock was just obtained, set writeLock to 2 instead of
** the usual 1. This causes walIndexPage() to behave as if the
** write-lock were held (so that it allocates new pages as required),
** and walHandleException() to unlock the write-lock if a SEH exception
** is thrown. */
if !(bWriteLock != 0) {
(*TWal)(unsafe.Pointer(pWal)).FwriteLock = uint8(2)
}
v1 = _walIndexPage(tls, pWal, 0, bp)
rc = v1
if SQLITE_OK == v1 {
badHdr = _walIndexTryHdr(tls, pWal, pChanged)
if badHdr != 0 {
/* If the wal-index header is still malformed even while holding
** a WRITE lock, it can only mean that the header is corrupted and
** needs to be reconstructed. So run recovery to do exactly that.
** Disable blocking locks first. */
rc = _walIndexRecover(tls, pWal)
**(**int32)(__ccgo_up(pChanged)) = int32(1)
}
}
if bWriteLock == 0 {
(*TWal)(unsafe.Pointer(pWal)).FwriteLock = uint8(0)
_walUnlockExclusive(tls, pWal, WAL_WRITE_LOCK, int32(1))
}
}
}
}
/* If the header is read successfully, check the version number to make
** sure the wal-index was not constructed with some future format that
** this version of SQLite cannot understand.
*/
if badHdr == 0 && (*TWal)(unsafe.Pointer(pWal)).Fhdr.FiVersion != uint32(WALINDEX_MAX_VERSION) {
rc = _sqlite3CantopenError(tls, int32(70266))
}
if (*TWal)(unsafe.Pointer(pWal)).FbShmUnreliable != 0 {
if rc != SQLITE_OK {
_walIndexClose(tls, pWal, 0)
(*TWal)(unsafe.Pointer(pWal)).FbShmUnreliable = uint8(0)
/* walIndexRecover() might have returned SHORT_READ if a concurrent
** writer truncated the WAL out from under it. If that happens, it
** indicates that a writer has fixed the SHM file for us, so retry */
if rc == libc.Int32FromInt32(SQLITE_IOERR)|libc.Int32FromInt32(2)<<libc.Int32FromInt32(8) {
rc = -int32(1)
}
}
(*TWal)(unsafe.Pointer(pWal)).FexclusiveMode = uint8(WAL_NORMAL_MODE)
}
return rc
}
// C documentation
//
// /*
// ** The cache of the wal-index header must be valid to call this function.
// ** Return the page-size in bytes used by the database.
// */
func _walPagesize(tls *libc.TLS, pWal uintptr) (r int32) {
return libc.Int32FromUint16((*TWal)(unsafe.Pointer(pWal)).Fhdr.FszPage)&int32(0xfe00) + libc.Int32FromUint16((*TWal)(unsafe.Pointer(pWal)).Fhdr.FszPage)&int32(0x0001)<<int32(16)
}
// C documentation
//
// /*
// ** If there is the possibility of concurrent access to the SHM file
// ** from multiple threads and/or processes, then do a memory barrier.
// */
func _walShmBarrier(tls *libc.TLS, pWal uintptr) {
if libc.Int32FromUint8((*TWal)(unsafe.Pointer(pWal)).FexclusiveMode) != int32(WAL_HEAPMEMORY_MODE) {
_sqlite3OsShmBarrier(tls, (*TWal)(unsafe.Pointer(pWal)).FpDbFd)
}
}
/*
** Add the SQLITE_NO_TSAN as part of the return-type of a function
** definition as a hint that the function contains constructs that
** might give false-positive TSAN warnings.
**
** See tag-20200519-1.
*/
// C documentation
//
// /*
// ** Subterms pOne and pTwo are contained within WHERE clause pWC. The
// ** two subterms are in disjunction - they are OR-ed together.
// **
// ** If these two terms are both of the form: "A op B" with the same
// ** A and B values but different operators and if the operators are
// ** compatible (if one is = and the other is <, for example) then
// ** add a new virtual AND term to pWC that is the combination of the
// ** two.
// **
// ** Some examples:
// **
// ** x<y OR x=y --> x<=y
// ** x=y OR x=y --> x=y
// ** x<=y OR x<y --> x<=y
// **
// ** The following is NOT generated:
// **
// ** x<y OR x>y --> x!=y
// */
func _whereCombineDisjuncts(tls *libc.TLS, pSrc uintptr, pWC uintptr, pOne uintptr, pTwo uintptr) {
var db, pA, pB, pNew uintptr
var eOp Tu16
var idxNew, op int32
_, _, _, _, _, _, _ = db, eOp, idxNew, op, pA, pB, pNew
eOp = libc.Uint16FromInt32(libc.Int32FromUint16((*TWhereTerm)(unsafe.Pointer(pOne)).FeOperator) | libc.Int32FromUint16((*TWhereTerm)(unsafe.Pointer(pTwo)).FeOperator)) /* Expressions associated with pOne and pTwo */
if (libc.Int32FromUint16((*TWhereTerm)(unsafe.Pointer(pOne)).FwtFlags)|libc.Int32FromUint16((*TWhereTerm)(unsafe.Pointer(pTwo)).FwtFlags))&int32(TERM_VNULL) != 0 {
return
}
if libc.Int32FromUint16((*TWhereTerm)(unsafe.Pointer(pOne)).FeOperator)&(libc.Int32FromInt32(WO_EQ)|libc.Int32FromInt32(WO_EQ)<<(libc.Int32FromInt32(TK_LT)-libc.Int32FromInt32(TK_EQ))|libc.Int32FromInt32(WO_EQ)<<(libc.Int32FromInt32(TK_LE)-libc.Int32FromInt32(TK_EQ))|libc.Int32FromInt32(WO_EQ)<<(libc.Int32FromInt32(TK_GT)-libc.Int32FromInt32(TK_EQ))|libc.Int32FromInt32(WO_EQ)<<(libc.Int32FromInt32(TK_GE)-libc.Int32FromInt32(TK_EQ))) == 0 {
return
}
if libc.Int32FromUint16((*TWhereTerm)(unsafe.Pointer(pTwo)).FeOperator)&(libc.Int32FromInt32(WO_EQ)|libc.Int32FromInt32(WO_EQ)<<(libc.Int32FromInt32(TK_LT)-libc.Int32FromInt32(TK_EQ))|libc.Int32FromInt32(WO_EQ)<<(libc.Int32FromInt32(TK_LE)-libc.Int32FromInt32(TK_EQ))|libc.Int32FromInt32(WO_EQ)<<(libc.Int32FromInt32(TK_GT)-libc.Int32FromInt32(TK_EQ))|libc.Int32FromInt32(WO_EQ)<<(libc.Int32FromInt32(TK_GE)-libc.Int32FromInt32(TK_EQ))) == 0 {
return
}
if libc.Int32FromUint16(eOp)&(libc.Int32FromInt32(WO_EQ)|libc.Int32FromInt32(WO_EQ)<<(libc.Int32FromInt32(TK_LT)-libc.Int32FromInt32(TK_EQ))|libc.Int32FromInt32(WO_EQ)<<(libc.Int32FromInt32(TK_LE)-libc.Int32FromInt32(TK_EQ))) != libc.Int32FromUint16(eOp) && libc.Int32FromUint16(eOp)&(libc.Int32FromInt32(WO_EQ)|libc.Int32FromInt32(WO_EQ)<<(libc.Int32FromInt32(TK_GT)-libc.Int32FromInt32(TK_EQ))|libc.Int32FromInt32(WO_EQ)<<(libc.Int32FromInt32(TK_GE)-libc.Int32FromInt32(TK_EQ))) != libc.Int32FromUint16(eOp) {
return
}
pA = (*TWhereTerm)(unsafe.Pointer(pOne)).FpExpr
pB = (*TWhereTerm)(unsafe.Pointer(pTwo)).FpExpr
if _sqlite3ExprCompare(tls, uintptr(0), (*TExpr)(unsafe.Pointer(pA)).FpLeft, (*TExpr)(unsafe.Pointer(pB)).FpLeft, -int32(1)) != 0 {
return
}
if _sqlite3ExprCompare(tls, uintptr(0), (*TExpr)(unsafe.Pointer(pA)).FpRight, (*TExpr)(unsafe.Pointer(pB)).FpRight, -int32(1)) != 0 {
return
}
if libc.BoolInt32((*TExpr)(unsafe.Pointer(pA)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_Commuted)) != uint32(0)) != libc.BoolInt32((*TExpr)(unsafe.Pointer(pB)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_Commuted)) != uint32(0)) {
return
}
/* If we reach this point, it means the two subterms can be combined */
if libc.Int32FromUint16(eOp)&(libc.Int32FromUint16(eOp)-int32(1)) != 0 {
if libc.Int32FromUint16(eOp)&(libc.Int32FromInt32(WO_EQ)<<(libc.Int32FromInt32(TK_LT)-libc.Int32FromInt32(TK_EQ))|libc.Int32FromInt32(WO_EQ)<<(libc.Int32FromInt32(TK_LE)-libc.Int32FromInt32(TK_EQ))) != 0 {
eOp = libc.Uint16FromInt32(libc.Int32FromInt32(WO_EQ) << (libc.Int32FromInt32(TK_LE) - libc.Int32FromInt32(TK_EQ)))
} else {
eOp = libc.Uint16FromInt32(libc.Int32FromInt32(WO_EQ) << (libc.Int32FromInt32(TK_GE) - libc.Int32FromInt32(TK_EQ)))
}
}
db = (*TParse)(unsafe.Pointer((*TWhereInfo)(unsafe.Pointer((*TWhereClause)(unsafe.Pointer(pWC)).FpWInfo)).FpParse)).Fdb
pNew = _sqlite3ExprDup(tls, db, pA, 0)
if pNew == uintptr(0) {
return
}
op = int32(TK_EQ)
for {
if !(libc.Int32FromUint16(eOp) != int32(WO_EQ)<<(op-int32(TK_EQ))) {
break
}
goto _1
_1:
;
op = op + 1
}
(*TExpr)(unsafe.Pointer(pNew)).Fop = libc.Uint8FromInt32(op)
idxNew = _whereClauseInsert(tls, pWC, pNew, libc.Uint16FromInt32(libc.Int32FromInt32(TERM_VIRTUAL)|libc.Int32FromInt32(TERM_DYNAMIC)))
_exprAnalyze(tls, pSrc, pWC, idxNew)
}
// C documentation
//
// /*
// ** Try to adjust the cost and number of output rows of WhereLoop pTemplate
// ** upwards or downwards so that:
// **
// ** (1) pTemplate costs less than any other WhereLoops that are a proper
// ** subset of pTemplate
// **
// ** (2) pTemplate costs more than any other WhereLoops for which pTemplate
// ** is a proper subset.
// **
// ** To say "WhereLoop X is a proper subset of Y" means that X uses fewer
// ** WHERE clause terms than Y and that every WHERE clause term used by X is
// ** also used by Y.
// */
func _whereLoopAdjustCost(tls *libc.TLS, p uintptr, pTemplate uintptr) {
var v2 int32
_ = v2
if (*TWhereLoop)(unsafe.Pointer(pTemplate)).FwsFlags&uint32(WHERE_INDEXED) == uint32(0) {
return
}
for {
if !(p != 0) {
break
}
if libc.Int32FromUint8((*TWhereLoop)(unsafe.Pointer(p)).FiTab) != libc.Int32FromUint8((*TWhereLoop)(unsafe.Pointer(pTemplate)).FiTab) {
goto _1
}
if (*TWhereLoop)(unsafe.Pointer(p)).FwsFlags&uint32(WHERE_INDEXED) == uint32(0) {
goto _1
}
if _whereLoopCheaperProperSubset(tls, p, pTemplate) != 0 {
/* Adjust pTemplate cost downward so that it is cheaper than its
** subset p. */
if int32((*TWhereLoop)(unsafe.Pointer(p)).FrRun) < int32((*TWhereLoop)(unsafe.Pointer(pTemplate)).FrRun) {
v2 = int32((*TWhereLoop)(unsafe.Pointer(p)).FrRun)
} else {
v2 = int32((*TWhereLoop)(unsafe.Pointer(pTemplate)).FrRun)
}
(*TWhereLoop)(unsafe.Pointer(pTemplate)).FrRun = int16(v2)
if int32((*TWhereLoop)(unsafe.Pointer(p)).FnOut)-int32(1) < int32((*TWhereLoop)(unsafe.Pointer(pTemplate)).FnOut) {
v2 = int32((*TWhereLoop)(unsafe.Pointer(p)).FnOut) - int32(1)
} else {
v2 = int32((*TWhereLoop)(unsafe.Pointer(pTemplate)).FnOut)
}
(*TWhereLoop)(unsafe.Pointer(pTemplate)).FnOut = int16(v2)
} else {
if _whereLoopCheaperProperSubset(tls, pTemplate, p) != 0 {
/* Adjust pTemplate cost upward so that it is costlier than p since
** pTemplate is a proper subset of p */
if int32((*TWhereLoop)(unsafe.Pointer(p)).FrRun) > int32((*TWhereLoop)(unsafe.Pointer(pTemplate)).FrRun) {
v2 = int32((*TWhereLoop)(unsafe.Pointer(p)).FrRun)
} else {
v2 = int32((*TWhereLoop)(unsafe.Pointer(pTemplate)).FrRun)
}
(*TWhereLoop)(unsafe.Pointer(pTemplate)).FrRun = int16(v2)
if int32((*TWhereLoop)(unsafe.Pointer(p)).FnOut)+int32(1) > int32((*TWhereLoop)(unsafe.Pointer(pTemplate)).FnOut) {
v2 = int32((*TWhereLoop)(unsafe.Pointer(p)).FnOut) + int32(1)
} else {
v2 = int32((*TWhereLoop)(unsafe.Pointer(pTemplate)).FnOut)
}
(*TWhereLoop)(unsafe.Pointer(pTemplate)).FnOut = int16(v2)
}
}
goto _1
_1:
;
p = (*TWhereLoop)(unsafe.Pointer(p)).FpNextLoop
}
}
// C documentation
//
// /*
// ** Clear the WhereLoop.u union. Leave WhereLoop.pLTerm intact.
// */
func _whereLoopClearUnion(tls *libc.TLS, db uintptr, p uintptr) {
if (*TWhereLoop)(unsafe.Pointer(p)).FwsFlags&libc.Uint32FromInt32(libc.Int32FromInt32(WHERE_VIRTUALTABLE)|libc.Int32FromInt32(WHERE_AUTO_INDEX)) != 0 {
if (*TWhereLoop)(unsafe.Pointer(p)).FwsFlags&uint32(WHERE_VIRTUALTABLE) != uint32(0) && int32(Tu32(*(*uint8)(unsafe.Pointer(p + 24 + 4))&0x1>>0)) != 0 {
Xsqlite3_free(tls, (*(*struct {
FidxNum int32
F__ccgo4 uint8
FisOrdered Ti8
FomitMask Tu16
FidxStr uintptr
FmHandleIn Tu32
})(unsafe.Pointer(p + 24))).FidxStr)
libc.SetBitFieldPtr8Uint32(p+24+4, libc.Uint32FromInt32(0), 0, 0x1)
(*(*struct {
FidxNum int32
F__ccgo4 uint8
FisOrdered Ti8
FomitMask Tu16
FidxStr uintptr
FmHandleIn Tu32
})(unsafe.Pointer(p + 24))).FidxStr = uintptr(0)
} else {
if (*TWhereLoop)(unsafe.Pointer(p)).FwsFlags&uint32(WHERE_AUTO_INDEX) != uint32(0) && (*(*struct {
FnEq Tu16
FnBtm Tu16
FnTop Tu16
FnDistinctCol Tu16
FpIndex uintptr
FpOrderBy uintptr
})(unsafe.Pointer(p + 24))).FpIndex != uintptr(0) {
_sqlite3DbFree(tls, db, (*TIndex)(unsafe.Pointer((*(*struct {
FnEq Tu16
FnBtm Tu16
FnTop Tu16
FnDistinctCol Tu16
FpIndex uintptr
FpOrderBy uintptr
})(unsafe.Pointer(p + 24))).FpIndex)).FzColAff)
_sqlite3DbFreeNN(tls, db, (*(*struct {
FnEq Tu16
FnBtm Tu16
FnTop Tu16
FnDistinctCol Tu16
FpIndex uintptr
FpOrderBy uintptr
})(unsafe.Pointer(p + 24))).FpIndex)
(*(*struct {
FnEq Tu16
FnBtm Tu16
FnTop Tu16
FnDistinctCol Tu16
FpIndex uintptr
FpOrderBy uintptr
})(unsafe.Pointer(p + 24))).FpIndex = uintptr(0)
}
}
}
}
// C documentation
//
// /*
// ** If it is not NULL, pTerm is a term that provides an upper or lower
// ** bound on a range scan. Without considering pTerm, it is estimated
// ** that the scan will visit nNew rows. This function returns the number
// ** estimated to be visited after taking pTerm into account.
// **
// ** If the user explicitly specified a likelihood() value for this term,
// ** then the return value is the likelihood multiplied by the number of
// ** input rows. Otherwise, this function assumes that an "IS NOT NULL" term
// ** has a likelihood of 0.50, and any other term a likelihood of 0.25.
// */
func _whereRangeAdjust(tls *libc.TLS, pTerm uintptr, nNew TLogEst) (r TLogEst) {
var nRet TLogEst
_ = nRet
nRet = nNew
if pTerm != 0 {
if int32((*TWhereTerm)(unsafe.Pointer(pTerm)).FtruthProb) <= 0 {
nRet = int16(int32(nRet) + int32((*TWhereTerm)(unsafe.Pointer(pTerm)).FtruthProb))
} else {
if libc.Int32FromUint16((*TWhereTerm)(unsafe.Pointer(pTerm)).FwtFlags)&int32(TERM_VNULL) == 0 {
nRet = int16(int32(nRet) - libc.Int32FromInt32(20))
}
}
}
return nRet
}
// C documentation
//
// /*
// ** If the right-hand branch of the expression is a TK_COLUMN, then return
// ** a pointer to the right-hand branch. Otherwise, return NULL.
// */
func _whereRightSubexprIsColumn(tls *libc.TLS, p uintptr) (r uintptr) {
p = _sqlite3ExprSkipCollateAndLikely(tls, (*TExpr)(unsafe.Pointer(p)).FpRight)
if p != uintptr(0) && libc.Int32FromUint8((*TExpr)(unsafe.Pointer(p)).Fop) == int32(TK_COLUMN) && !((*TExpr)(unsafe.Pointer(p)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_FixedCol)) != libc.Uint32FromInt32(0)) {
return p
}
return uintptr(0)
}
// C documentation
//
// /*
// ** Return the cost of sorting nRow rows, assuming that the keys have
// ** nOrderby columns and that the first nSorted columns are already in
// ** order.
// */
func _whereSortingCost(tls *libc.TLS, pWInfo uintptr, nRow TLogEst, nOrderBy int32, nSorted int32) (r TLogEst) {
var nCol, rSortCost TLogEst
_, _ = nCol, rSortCost
/* TUNING: sorting cost proportional to the number of output columns: */
nCol = _sqlite3LogEst(tls, libc.Uint64FromInt32(((*TExprList)(unsafe.Pointer((*TSelect)(unsafe.Pointer((*TWhereInfo)(unsafe.Pointer(pWInfo)).FpSelect)).FpEList)).FnExpr+int32(59))/int32(30)))
rSortCost = int16(int32(nRow) + int32(nCol))
if nSorted > 0 {
/* Scale the result by (Y/X) */
rSortCost = int16(int32(rSortCost) + (int32(_sqlite3LogEst(tls, libc.Uint64FromInt32((nOrderBy-nSorted)*int32(100)/nOrderBy))) - libc.Int32FromInt32(66)))
}
/* Multiple by log(M) where M is the number of output rows.
** Use the LIMIT for M if it is smaller. Or if this sort is for
** a DISTINCT operator, M will be the number of distinct output
** rows, so fudge it downwards a bit.
*/
if libc.Int32FromUint16((*TWhereInfo)(unsafe.Pointer(pWInfo)).FwctrlFlags)&int32(WHERE_USE_LIMIT) != 0 {
rSortCost = int16(int32(rSortCost) + libc.Int32FromInt32(10)) /* TUNING: Extra 2.0x if using LIMIT */
if nSorted != 0 {
rSortCost = int16(int32(rSortCost) + libc.Int32FromInt32(6)) /* TUNING: Extra 1.5x if also using partial sort */
}
if int32((*TWhereInfo)(unsafe.Pointer(pWInfo)).FiLimit) < int32(nRow) {
nRow = (*TWhereInfo)(unsafe.Pointer(pWInfo)).FiLimit
}
} else {
if libc.Int32FromUint16((*TWhereInfo)(unsafe.Pointer(pWInfo)).FwctrlFlags)&int32(WHERE_WANT_DISTINCT) != 0 {
/* TUNING: In the sort for a DISTINCT operator, assume that the DISTINCT
** reduces the number of output rows by a factor of 2 */
if int32(nRow) > int32(10) {
nRow = int16(int32(nRow) - libc.Int32FromInt32(10))
}
}
}
rSortCost = int16(int32(rSortCost) + int32(_estLog(tls, nRow)))
return rSortCost
}
// C documentation
//
// /*
// ** Generate VM code to invoke either xValue() (bFin==0) or xFinalize()
// ** (bFin==1) for each window function in the linked list starting at
// ** pMWin. Or, for built-in window-functions that do not use the standard
// ** API, generate the equivalent VM code.
// */
func _windowAggFinal(tls *libc.TLS, p uintptr, bFin int32) {
var nArg int32
var pMWin, pParse, pWin, v uintptr
_, _, _, _, _ = nArg, pMWin, pParse, pWin, v
pParse = (*TWindowCodeArg)(unsafe.Pointer(p)).FpParse
pMWin = (*TWindowCodeArg)(unsafe.Pointer(p)).FpMWin
v = _sqlite3GetVdbe(tls, pParse)
pWin = pMWin
for {
if !(pWin != 0) {
break
}
if (*TWindow)(unsafe.Pointer(pMWin)).FregStartRowid == 0 && (*TFuncDef)(unsafe.Pointer((*TWindow)(unsafe.Pointer(pWin)).FpWFunc)).FfuncFlags&uint32(SQLITE_FUNC_MINMAX) != 0 && libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pWin)).FeStart) != int32(TK_UNBOUNDED) {
_sqlite3VdbeAddOp2(tls, v, int32(OP_Null), 0, (*TWindow)(unsafe.Pointer(pWin)).FregResult)
_sqlite3VdbeAddOp1(tls, v, int32(OP_Last), (*TWindow)(unsafe.Pointer(pWin)).FcsrApp)
_sqlite3VdbeAddOp3(tls, v, int32(OP_Column), (*TWindow)(unsafe.Pointer(pWin)).FcsrApp, 0, (*TWindow)(unsafe.Pointer(pWin)).FregResult)
_sqlite3VdbeJumpHere(tls, v, _sqlite3VdbeCurrentAddr(tls, v)-int32(2))
} else {
if (*TWindow)(unsafe.Pointer(pWin)).FregApp != 0 {
} else {
nArg = _windowArgCount(tls, pWin)
if bFin != 0 {
_sqlite3VdbeAddOp2(tls, v, int32(OP_AggFinal), (*TWindow)(unsafe.Pointer(pWin)).FregAccum, nArg)
_sqlite3VdbeAppendP4(tls, v, (*TWindow)(unsafe.Pointer(pWin)).FpWFunc, -int32(8))
_sqlite3VdbeAddOp2(tls, v, int32(OP_Copy), (*TWindow)(unsafe.Pointer(pWin)).FregAccum, (*TWindow)(unsafe.Pointer(pWin)).FregResult)
_sqlite3VdbeAddOp2(tls, v, int32(OP_Null), 0, (*TWindow)(unsafe.Pointer(pWin)).FregAccum)
} else {
_sqlite3VdbeAddOp3(tls, v, int32(OP_AggValue), (*TWindow)(unsafe.Pointer(pWin)).FregAccum, nArg, (*TWindow)(unsafe.Pointer(pWin)).FregResult)
_sqlite3VdbeAppendP4(tls, v, (*TWindow)(unsafe.Pointer(pWin)).FpWFunc, -int32(8))
}
}
}
goto _1
_1:
;
pWin = (*TWindow)(unsafe.Pointer(pWin)).FpNextWin
}
}
// C documentation
//
// /*
// ** Helper function for sqlite3WindowCodeStep(). Each call to this function
// ** generates VM code for a single RETURN_ROW, AGGSTEP or AGGINVERSE
// ** operation. Refer to the header comment for sqlite3WindowCodeStep() for
// ** details.
// */
func _windowCodeOp(tls *libc.TLS, p uintptr, op int32, regCountdown int32, jumpOnEof int32) (r int32) {
var addrContinue, addrNextRange, bPeer, csr, lblDone, nReg, reg, regRowid1, regRowid2, regTmp, ret, v1, v2 int32
var pMWin, pParse, v uintptr
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = addrContinue, addrNextRange, bPeer, csr, lblDone, nReg, pMWin, pParse, reg, regRowid1, regRowid2, regTmp, ret, v, v1, v2
pParse = (*TWindowCodeArg)(unsafe.Pointer(p)).FpParse
pMWin = (*TWindowCodeArg)(unsafe.Pointer(p)).FpMWin
ret = 0
v = (*TWindowCodeArg)(unsafe.Pointer(p)).FpVdbe
addrContinue = 0
bPeer = libc.BoolInt32(libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeFrmType) != int32(TK_ROWS))
lblDone = _sqlite3VdbeMakeLabel(tls, pParse)
addrNextRange = 0
/* Special case - WINDOW_AGGINVERSE is always a no-op if the frame
** starts with UNBOUNDED PRECEDING. */
if op == int32(WINDOW_AGGINVERSE) && libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeStart) == int32(TK_UNBOUNDED) {
return 0
}
if regCountdown > 0 {
if libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeFrmType) == int32(TK_RANGE) {
addrNextRange = _sqlite3VdbeCurrentAddr(tls, v)
if op == int32(WINDOW_AGGINVERSE) {
if libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeStart) == int32(TK_FOLLOWING) {
_windowCodeRangeTest(tls, p, int32(OP_Le), (*TWindowCodeArg)(unsafe.Pointer(p)).Fcurrent.Fcsr, regCountdown, (*TWindowCodeArg)(unsafe.Pointer(p)).Fstart.Fcsr, lblDone)
} else {
_windowCodeRangeTest(tls, p, int32(OP_Ge), (*TWindowCodeArg)(unsafe.Pointer(p)).Fstart.Fcsr, regCountdown, (*TWindowCodeArg)(unsafe.Pointer(p)).Fcurrent.Fcsr, lblDone)
}
} else {
_windowCodeRangeTest(tls, p, int32(OP_Gt), (*TWindowCodeArg)(unsafe.Pointer(p)).Fend.Fcsr, regCountdown, (*TWindowCodeArg)(unsafe.Pointer(p)).Fcurrent.Fcsr, lblDone)
}
} else {
_sqlite3VdbeAddOp3(tls, v, int32(OP_IfPos), regCountdown, lblDone, int32(1))
}
}
if op == int32(WINDOW_RETURN_ROW) && (*TWindow)(unsafe.Pointer(pMWin)).FregStartRowid == 0 {
_windowAggFinal(tls, p, 0)
}
addrContinue = _sqlite3VdbeCurrentAddr(tls, v)
/* If this is a (RANGE BETWEEN a FOLLOWING AND b FOLLOWING) or
** (RANGE BETWEEN b PRECEDING AND a PRECEDING) frame, ensure the
** start cursor does not advance past the end cursor within the
** temporary table. It otherwise might, if (a>b). Also ensure that,
** if the input cursor is still finding new rows, that the end
** cursor does not go past it to EOF. */
if libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeStart) == libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeEnd) && regCountdown != 0 && libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeFrmType) == int32(TK_RANGE) {
regRowid1 = _sqlite3GetTempReg(tls, pParse)
regRowid2 = _sqlite3GetTempReg(tls, pParse)
if op == int32(WINDOW_AGGINVERSE) {
_sqlite3VdbeAddOp2(tls, v, int32(OP_Rowid), (*TWindowCodeArg)(unsafe.Pointer(p)).Fstart.Fcsr, regRowid1)
_sqlite3VdbeAddOp2(tls, v, int32(OP_Rowid), (*TWindowCodeArg)(unsafe.Pointer(p)).Fend.Fcsr, regRowid2)
_sqlite3VdbeAddOp3(tls, v, int32(OP_Ge), regRowid2, lblDone, regRowid1)
} else {
if (*TWindowCodeArg)(unsafe.Pointer(p)).FregRowid != 0 {
_sqlite3VdbeAddOp2(tls, v, int32(OP_Rowid), (*TWindowCodeArg)(unsafe.Pointer(p)).Fend.Fcsr, regRowid1)
_sqlite3VdbeAddOp3(tls, v, int32(OP_Ge), (*TWindowCodeArg)(unsafe.Pointer(p)).FregRowid, lblDone, regRowid1)
}
}
_sqlite3ReleaseTempReg(tls, pParse, regRowid1)
_sqlite3ReleaseTempReg(tls, pParse, regRowid2)
}
switch op {
case int32(WINDOW_RETURN_ROW):
csr = (*TWindowCodeArg)(unsafe.Pointer(p)).Fcurrent.Fcsr
reg = (*TWindowCodeArg)(unsafe.Pointer(p)).Fcurrent.Freg
_windowReturnOneRow(tls, p)
case int32(WINDOW_AGGINVERSE):
csr = (*TWindowCodeArg)(unsafe.Pointer(p)).Fstart.Fcsr
reg = (*TWindowCodeArg)(unsafe.Pointer(p)).Fstart.Freg
if (*TWindow)(unsafe.Pointer(pMWin)).FregStartRowid != 0 {
_sqlite3VdbeAddOp2(tls, v, int32(OP_AddImm), (*TWindow)(unsafe.Pointer(pMWin)).FregStartRowid, int32(1))
} else {
_windowAggStep(tls, p, pMWin, csr, int32(1), (*TWindowCodeArg)(unsafe.Pointer(p)).FregArg)
}
default:
csr = (*TWindowCodeArg)(unsafe.Pointer(p)).Fend.Fcsr
reg = (*TWindowCodeArg)(unsafe.Pointer(p)).Fend.Freg
if (*TWindow)(unsafe.Pointer(pMWin)).FregStartRowid != 0 {
_sqlite3VdbeAddOp2(tls, v, int32(OP_AddImm), (*TWindow)(unsafe.Pointer(pMWin)).FregEndRowid, int32(1))
} else {
_windowAggStep(tls, p, pMWin, csr, 0, (*TWindowCodeArg)(unsafe.Pointer(p)).FregArg)
}
break
}
if op == (*TWindowCodeArg)(unsafe.Pointer(p)).FeDelete {
_sqlite3VdbeAddOp1(tls, v, int32(OP_Delete), csr)
_sqlite3VdbeChangeP5(tls, v, uint16(OPFLAG_SAVEPOSITION))
}
if jumpOnEof != 0 {
_sqlite3VdbeAddOp2(tls, v, int32(OP_Next), csr, _sqlite3VdbeCurrentAddr(tls, v)+int32(2))
ret = _sqlite3VdbeAddOp0(tls, v, int32(OP_Goto))
} else {
_sqlite3VdbeAddOp2(tls, v, int32(OP_Next), csr, _sqlite3VdbeCurrentAddr(tls, v)+int32(1)+bPeer)
if bPeer != 0 {
_sqlite3VdbeAddOp2(tls, v, int32(OP_Goto), 0, lblDone)
}
}
if bPeer != 0 {
if (*TWindow)(unsafe.Pointer(pMWin)).FpOrderBy != 0 {
v1 = (*TExprList)(unsafe.Pointer((*TWindow)(unsafe.Pointer(pMWin)).FpOrderBy)).FnExpr
} else {
v1 = 0
}
nReg = v1
if nReg != 0 {
v2 = _sqlite3GetTempRange(tls, pParse, nReg)
} else {
v2 = 0
}
regTmp = v2
_windowReadPeerValues(tls, p, csr, regTmp)
_windowIfNewPeer(tls, pParse, (*TWindow)(unsafe.Pointer(pMWin)).FpOrderBy, regTmp, reg, addrContinue)
_sqlite3ReleaseTempRange(tls, pParse, regTmp, nReg)
}
if addrNextRange != 0 {
_sqlite3VdbeAddOp2(tls, v, int32(OP_Goto), 0, addrNextRange)
}
_sqlite3VdbeResolveLabel(tls, v, lblDone)
return ret
}
// C documentation
//
// /*
// ** Generate code to calculate the current values of all window functions in the
// ** p->pMWin list by doing a full scan of the current window frame. Store the
// ** results in the Window.regResult registers, ready to return the upper
// ** layer.
// */
func _windowFullScan(tls *libc.TLS, p uintptr) {
var addr, addrEq, addrNext, csr, lblBrk, lblNext, nPeer, regCPeer, regCRowid, regPeer, regRowid, v1 int32
var pKeyInfo, pMWin, pParse, pWin, v uintptr
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = addr, addrEq, addrNext, csr, lblBrk, lblNext, nPeer, pKeyInfo, pMWin, pParse, pWin, regCPeer, regCRowid, regPeer, regRowid, v, v1
pParse = (*TWindowCodeArg)(unsafe.Pointer(p)).FpParse
pMWin = (*TWindowCodeArg)(unsafe.Pointer(p)).FpMWin
v = (*TWindowCodeArg)(unsafe.Pointer(p)).FpVdbe
regCRowid = 0 /* Current rowid value */
regCPeer = 0 /* Current peer values */
regRowid = 0 /* AggStep rowid value */
regPeer = 0
csr = (*TWindow)(unsafe.Pointer(pMWin)).FcsrApp
if (*TWindow)(unsafe.Pointer(pMWin)).FpOrderBy != 0 {
v1 = (*TExprList)(unsafe.Pointer((*TWindow)(unsafe.Pointer(pMWin)).FpOrderBy)).FnExpr
} else {
v1 = 0
}
nPeer = v1
lblNext = _sqlite3VdbeMakeLabel(tls, pParse)
lblBrk = _sqlite3VdbeMakeLabel(tls, pParse)
regCRowid = _sqlite3GetTempReg(tls, pParse)
regRowid = _sqlite3GetTempReg(tls, pParse)
if nPeer != 0 {
regCPeer = _sqlite3GetTempRange(tls, pParse, nPeer)
regPeer = _sqlite3GetTempRange(tls, pParse, nPeer)
}
_sqlite3VdbeAddOp2(tls, v, int32(OP_Rowid), (*TWindow)(unsafe.Pointer(pMWin)).FiEphCsr, regCRowid)
_windowReadPeerValues(tls, p, (*TWindow)(unsafe.Pointer(pMWin)).FiEphCsr, regCPeer)
pWin = pMWin
for {
if !(pWin != 0) {
break
}
_sqlite3VdbeAddOp2(tls, v, int32(OP_Null), 0, (*TWindow)(unsafe.Pointer(pWin)).FregAccum)
goto _2
_2:
;
pWin = (*TWindow)(unsafe.Pointer(pWin)).FpNextWin
}
_sqlite3VdbeAddOp3(tls, v, int32(OP_SeekGE), csr, lblBrk, (*TWindow)(unsafe.Pointer(pMWin)).FregStartRowid)
addrNext = _sqlite3VdbeCurrentAddr(tls, v)
_sqlite3VdbeAddOp2(tls, v, int32(OP_Rowid), csr, regRowid)
_sqlite3VdbeAddOp3(tls, v, int32(OP_Gt), (*TWindow)(unsafe.Pointer(pMWin)).FregEndRowid, lblBrk, regRowid)
if libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeExclude) == int32(TK_CURRENT) {
_sqlite3VdbeAddOp3(tls, v, int32(OP_Eq), regCRowid, lblNext, regRowid)
} else {
if libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeExclude) != int32(TK_NO) {
addrEq = 0
pKeyInfo = uintptr(0)
if (*TWindow)(unsafe.Pointer(pMWin)).FpOrderBy != 0 {
pKeyInfo = _sqlite3KeyInfoFromExprList(tls, pParse, (*TWindow)(unsafe.Pointer(pMWin)).FpOrderBy, 0, 0)
}
if libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pMWin)).FeExclude) == int32(TK_TIES) {
addrEq = _sqlite3VdbeAddOp3(tls, v, int32(OP_Eq), regCRowid, 0, regRowid)
}
if pKeyInfo != 0 {
_windowReadPeerValues(tls, p, csr, regPeer)
_sqlite3VdbeAddOp3(tls, v, int32(OP_Compare), regPeer, regCPeer, nPeer)
_sqlite3VdbeAppendP4(tls, v, pKeyInfo, -int32(9))
addr = _sqlite3VdbeCurrentAddr(tls, v) + int32(1)
_sqlite3VdbeAddOp3(tls, v, int32(OP_Jump), addr, lblNext, addr)
} else {
_sqlite3VdbeAddOp2(tls, v, int32(OP_Goto), 0, lblNext)
}
if addrEq != 0 {
_sqlite3VdbeJumpHere(tls, v, addrEq)
}
}
}
_windowAggStep(tls, p, pMWin, csr, 0, (*TWindowCodeArg)(unsafe.Pointer(p)).FregArg)
_sqlite3VdbeResolveLabel(tls, v, lblNext)
_sqlite3VdbeAddOp2(tls, v, int32(OP_Next), csr, addrNext)
_sqlite3VdbeJumpHere(tls, v, addrNext-int32(1))
_sqlite3VdbeJumpHere(tls, v, addrNext+int32(1))
_sqlite3ReleaseTempReg(tls, pParse, regRowid)
_sqlite3ReleaseTempReg(tls, pParse, regCRowid)
if nPeer != 0 {
_sqlite3ReleaseTempRange(tls, pParse, regPeer, nPeer)
_sqlite3ReleaseTempRange(tls, pParse, regCPeer, nPeer)
}
_windowAggFinal(tls, p, int32(1))
}
// C documentation
//
// /*
// ** Functions to serialize a 16 bit integer, 32 bit real number and
// ** 64 bit integer. The value returned is the number of bytes written
// ** to the argument buffer (always 2, 4 and 8 respectively).
// */
func _writeInt16(tls *libc.TLS, p uintptr, i int32) {
**(**Tu8)(__ccgo_up(p)) = libc.Uint8FromInt32(i >> int32(8) & int32(0xFF))
**(**Tu8)(__ccgo_up(p + 1)) = libc.Uint8FromInt32(i >> 0 & int32(0xFF))
}
// C documentation
//
// /* The following function deletes the "minor type" or semantic value
// ** associated with a symbol. The symbol can be either a terminal
// ** or nonterminal. "yymajor" is the symbol code, and "yypminor" is
// ** a pointer to the value to be deleted. The code used to do the
// ** deletions is derived from the %destructor and/or %token_destructor
// ** directives of the input grammar.
// */
func _yy_destructor(tls *libc.TLS, yypParser uintptr, yymajor uint16, yypminor uintptr) {
var pParse uintptr
_ = pParse
pParse = (*TyyParser)(unsafe.Pointer(yypParser)).FpParse
switch libc.Int32FromUint16(yymajor) {
/* Here is inserted the actions which take place when a
** terminal or non-terminal is destroyed. This can happen
** when the symbol is popped from the stack during a
** reduce or during error processing or when a parser is
** being destroyed before it is finished parsing.
**
** Note: during a reduce, the only symbols destroyed are those
** which appear on the RHS of the rule, but which are *not* used
** inside the C code.
*/
/********* Begin destructor definitions ***************************************/
case int32(206): /* select */
fallthrough
case int32(241): /* selectnowith */
fallthrough
case int32(242): /* oneselect */
fallthrough
case int32(254): /* values */
fallthrough
case int32(256): /* mvalues */
_sqlite3SelectDelete(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, *(*uintptr)(unsafe.Pointer(yypminor)))
case int32(218): /* term */
fallthrough
case int32(219): /* expr */
fallthrough
case int32(248): /* where_opt */
fallthrough
case int32(250): /* having_opt */
fallthrough
case int32(270): /* where_opt_ret */
fallthrough
case int32(281): /* case_operand */
fallthrough
case int32(283): /* case_else */
fallthrough
case int32(286): /* vinto */
fallthrough
case int32(293): /* when_clause */
fallthrough
case int32(297): /* key_opt */
fallthrough
case int32(314): /* filter_clause */
_sqlite3ExprDelete(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, *(*uintptr)(unsafe.Pointer(yypminor)))
case int32(223): /* eidlist_opt */
fallthrough
case int32(233): /* sortlist */
fallthrough
case int32(234): /* eidlist */
fallthrough
case int32(246): /* selcollist */
fallthrough
case int32(249): /* groupby_opt */
fallthrough
case int32(251): /* orderby_opt */
fallthrough
case int32(255): /* nexprlist */
fallthrough
case int32(257): /* sclp */
fallthrough
case int32(264): /* exprlist */
fallthrough
case int32(271): /* setlist */
fallthrough
case int32(280): /* paren_exprlist */
fallthrough
case int32(282): /* case_exprlist */
fallthrough
case int32(313): /* part_opt */
_sqlite3ExprListDelete(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, *(*uintptr)(unsafe.Pointer(yypminor)))
case int32(240): /* fullname */
fallthrough
case int32(247): /* from */
fallthrough
case int32(259): /* seltablist */
fallthrough
case int32(260): /* stl_prefix */
fallthrough
case int32(265): /* xfullname */
_sqlite3SrcListDelete(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, *(*uintptr)(unsafe.Pointer(yypminor)))
case int32(243): /* wqlist */
_sqlite3WithDelete(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, *(*uintptr)(unsafe.Pointer(yypminor)))
case int32(253): /* window_clause */
fallthrough
case int32(309): /* windowdefn_list */
_sqlite3WindowListDelete(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, *(*uintptr)(unsafe.Pointer(yypminor)))
case int32(266): /* idlist */
fallthrough
case int32(273): /* idlist_opt */
_sqlite3IdListDelete(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, *(*uintptr)(unsafe.Pointer(yypminor)))
case int32(276): /* filter_over */
fallthrough
case int32(310): /* windowdefn */
fallthrough
case int32(311): /* window */
fallthrough
case int32(312): /* frame_opt */
fallthrough
case int32(315): /* over_clause */
_sqlite3WindowDelete(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, *(*uintptr)(unsafe.Pointer(yypminor)))
case int32(289): /* trigger_cmd_list */
fallthrough
case int32(294): /* trigger_cmd */
_sqlite3DeleteTriggerStep(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, *(*uintptr)(unsafe.Pointer(yypminor)))
case int32(291): /* trigger_event */
_sqlite3IdListDelete(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, (*(*TTrigEvent)(unsafe.Pointer(yypminor))).Fb)
case int32(317): /* frame_bound */
fallthrough
case int32(318): /* frame_bound_s */
fallthrough
case int32(319): /* frame_bound_e */
_sqlite3ExprDelete(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, (*(*TFrameBound)(unsafe.Pointer(yypminor))).FpExpr)
break
/********* End destructor definitions *****************************************/
fallthrough
default:
break /* If no destructor action specified: do nothing */
}
}
// C documentation
//
// /*
// ** Find the appropriate action for a parser given the non-terminal
// ** look-ahead token iLookAhead.
// */
func _yy_find_reduce_action(tls *libc.TLS, stateno uint16, iLookAhead uint16) (r uint16) {
var i int32
_ = i
i = int32(_yy_reduce_ofst[stateno])
i = i + libc.Int32FromUint16(iLookAhead)
return _yy_action[i]
}
// C documentation
//
// /*
// ** Find the appropriate action for a parser given the terminal
// ** look-ahead token iLookAhead.
// */
func _yy_find_shift_action(tls *libc.TLS, iLookAhead uint16, stateno uint16) (r uint16) {
var i, j int32
var iFallback uint16
_, _, _ = i, iFallback, j
if libc.Int32FromUint16(stateno) > int32(YY_MAX_SHIFT) {
return stateno
}
for cond := true; cond; cond = int32(1) != 0 {
i = libc.Int32FromUint16(_yy_shift_ofst[stateno])
i = i + libc.Int32FromUint16(iLookAhead)
if libc.Int32FromUint16(_yy_lookahead[i]) != libc.Int32FromUint16(iLookAhead) { /* Fallback token */
iFallback = _yyFallback[iLookAhead]
if libc.Int32FromUint16(iFallback) != 0 {
/* Fallback loop must terminate */
iLookAhead = iFallback
continue
}
j = i - libc.Int32FromUint16(iLookAhead) + int32(YYWILDCARD)
if libc.Int32FromUint16(_yy_lookahead[j]) == int32(YYWILDCARD) && libc.Int32FromUint16(iLookAhead) > 0 {
return _yy_action[j]
}
return _yy_default[stateno]
} else {
return _yy_action[i]
}
}
return r
}
// C documentation
//
// /*
// ** The journal file must be open when this function is called.
// **
// ** This function is a no-op if the journal file has not been written to
// ** within the current transaction (i.e. if Pager.journalOff==0).
// **
// ** If doTruncate is non-zero or the Pager.journalSizeLimit variable is
// ** set to 0, then truncate the journal file to zero bytes in size. Otherwise,
// ** zero the 28-byte header at the start of the journal file. In either case,
// ** if the pager is not in no-sync mode, sync the journal file immediately
// ** after writing or truncating it.
// **
// ** If Pager.journalSizeLimit is set to a positive, non-zero value, and
// ** following the truncation or zeroing described above the size of the
// ** journal file in bytes is larger than this value, then truncate the
// ** journal file to Pager.journalSizeLimit bytes. The journal file does
// ** not need to be synced following this operation.
// **
// ** If an IO error occurs, abandon processing and return the IO error code.
// ** Otherwise, return SQLITE_OK.
// */
func _zeroJournalHdr(tls *libc.TLS, pPager uintptr, doTruncate int32) (r int32) {
bp := tls.Alloc(16)
defer tls.Free(16)
var iLimit Ti64
var rc int32
var _ /* sz at bp+0 */ Ti64
_, _ = iLimit, rc
rc = SQLITE_OK /* Return code */
if (*TPager)(unsafe.Pointer(pPager)).FjournalOff != 0 {
iLimit = (*TPager)(unsafe.Pointer(pPager)).FjournalSizeLimit /* Local cache of jsl */
if doTruncate != 0 || iLimit == 0 {
rc = _sqlite3OsTruncate(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd, 0)
} else {
rc = _sqlite3OsWrite(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd, uintptr(unsafe.Pointer(&_zeroHdr)), int32(28), 0)
}
if rc == SQLITE_OK && !((*TPager)(unsafe.Pointer(pPager)).FnoSync != 0) {
rc = _sqlite3OsSync(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd, int32(SQLITE_SYNC_DATAONLY)|libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FsyncFlags))
}
/* At this point the transaction is committed but the write lock
** is still held on the file. If there is a size limit configured for
** the persistent journal and the journal file currently consumes more
** space than that limit allows for, truncate it now. There is no need
** to sync the file following this operation.
*/
if rc == SQLITE_OK && iLimit > 0 {
rc = _sqlite3OsFileSize(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd, bp)
if rc == SQLITE_OK && **(**Ti64)(__ccgo_up(bp)) > iLimit {
rc = _sqlite3OsTruncate(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd, iLimit)
}
}
}
return rc
}
// C documentation
//
// /*
// ** The zeroblob(N) function returns a zero-filled blob of size N bytes.
// */
func _zeroblobFunc(tls *libc.TLS, context uintptr, argc int32, argv uintptr) {
var n Ti64
var rc int32
_, _ = n, rc
_ = argc
n = Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(argv)))
if n < 0 {
n = 0
}
rc = Xsqlite3_result_zeroblob64(tls, context, libc.Uint64FromInt64(n)) /* IMP: R-00293-64994 */
if rc != 0 {
Xsqlite3_result_error_code(tls, context, rc)
}
}
type blkcnt_t = Tblkcnt_t
type blksize_t = Tblksize_t
type clockid_t = Tclockid_t
type double_t = Tdouble_t
const fdatasync = 0
type finder_type = Tfinder_type
/****************************************************************************
**************************** sqlite3_vfs methods ****************************
**
** This division contains the implementation of methods on the
** sqlite3_vfs object.
*/
type flock = Tflock
type id_t = Tid_t
func init() {
p := unsafe.Pointer(&_nolockIoFinder)
*(*uintptr)(unsafe.Add(p, 0)) = __ccgo_fp(_nolockIoFinderImpl)
}
func init() {
p := unsafe.Pointer(&_posixIoFinder)
*(*uintptr)(unsafe.Add(p, 0)) = __ccgo_fp(_posixIoFinderImpl)
}
type itimerval = Titimerval
type key_t = Tkey_t
type nlink_t = Tnlink_t
type quad_t = Tquad_t
type sigset_t = Tsigset_t
type stat = Tstat
const static_assert = 0
type suseconds_t = Tsuseconds_t
const threadid = 0
type u_int16_t = Tu_int16_t
type u_int32_t = Tu_int32_t
type u_int64_t = Tu_int64_t
type u_int8_t = Tu_int8_t
type u_quad_t = Tu_quad_t
type uint = Tuint
type unixFile = TunixFile
type unixFileId = TunixFileId
type unixInodeInfo = TunixInodeInfo
type unixShm = TunixShm
type unixShmNode = TunixShmNode
type unix_syscall = Tunix_syscall
type ushort = Tushort
type vxworksFileId = TvxworksFileId
/*************** End of Unique File ID Utility Used By VxWorks ****************
******************************************************************************/
/******************************************************************************
*************************** Posix Advisory Locking ****************************
**
** POSIX advisory locks are broken by design. ANSI STD 1003.1 (1996)
** section 6.5.2.2 lines 483 through 490 specify that when a process
** sets or clears a lock, that operation overrides any prior locks set
** by the same process. It does not explicitly say so, but this implies
** that it overrides locks set by the same process using a different
** file descriptor. Consider this test case:
**
** int fd1 = open("./file1", O_RDWR|O_CREAT, 0644);
** int fd2 = open("./file2", O_RDWR|O_CREAT, 0644);
**
** Suppose ./file1 and ./file2 are really the same file (because
** one is a hard or symbolic link to the other) then if you set
** an exclusive lock on fd1, then try to get an exclusive lock
** on fd2, it works. I would have expected the second lock to
** fail since there was already a lock on the file due to fd1.
** But not so. Since both locks came from the same process, the
** second overrides the first, even though they were on different
** file descriptors opened on different file names.
**
** This means that we cannot use POSIX locks to synchronize file access
** among competing threads of the same process. POSIX locks will work fine
** to synchronize access for threads in separate processes, but not
** threads within the same process.
**
** To work around the problem, SQLite has to manage file locks internally
** on its own. Whenever a new database is opened, we have to find the
** specific inode of the database file (the inode is determined by the
** st_dev and st_ino fields of the stat structure that fstat() fills in)
** and check for locks already existing on that inode. When locks are
** created or removed, we have to look at our own internal record of the
** locks to see if another thread has previously set a lock on that same
** inode.
**
** (Aside: The use of inode numbers as unique IDs does not work on VxWorks.
** For VxWorks, we have to use the alternative unique ID system based on
** canonical filename and implemented in the previous division.)
**
** The sqlite3_file structure for POSIX is no longer just an integer file
** descriptor. It is now a structure that holds the integer file
** descriptor and a pointer to a structure that describes the internal
** locks on the corresponding inode. There is one locking structure
** per inode, so if the same inode is opened twice, both unixFile structures
** point to the same locking structure. The locking structure keeps
** a reference count (so we will know when to delete it) and a "cnt"
** field that tells us its internal lock status. cnt==0 means the
** file is unlocked. cnt==-1 means the file has an exclusive lock.
** cnt>0 means there are cnt shared locks on the file.
**
** Any attempt to lock or unlock a file first checks the locking
** structure. The fcntl() system call is only invoked to set a
** POSIX lock if the internal lock structure transitions between
** a locked and an unlocked state.
**
** But wait: there are yet more problems with POSIX advisory locks.
**
** If you close a file descriptor that points to a file that has locks,
** all locks on that file that are owned by the current process are
** released. To work around this problem, each unixInodeInfo object
** maintains a count of the number of pending locks on the inode.
** When an attempt is made to close an unixFile, if there are
** other unixFile open on the same inode that are holding locks, the call
** to close() the file descriptor is deferred until all of the locks clear.
** The unixInodeInfo structure keeps a list of file descriptors that need to
** be closed and that list is walked (and cleared) when the last lock
** clears.
**
** Yet another problem: LinuxThreads do not play well with posix locks.
**
** Many older versions of linux use the LinuxThreads library which is
** not posix compliant. Under LinuxThreads, a lock created by thread
** A cannot be modified or overridden by a different thread B.
** Only thread A can modify the lock. Locking behavior is correct
** if the application uses the newer Native Posix Thread Library (NPTL)
** on linux - with NPTL a lock created by thread A can override locks
** in thread B. But there is no way to know at compile-time which
** threading library is being used. So there is no way to know at
** compile-time whether or not thread A can override locks on thread B.
** One has to do a run-time check to discover the behavior of the
** current process.
**
** SQLite used to support LinuxThreads. But support for LinuxThreads
** was dropped beginning with version 3.7.0. SQLite will still work with
** LinuxThreads provided that (1) there is no more than one connection
** per database file in the same process and (2) database connections
** do not move across threads.
*/
type winsize = Twinsize