Dixie is capped (max_inflight 2, queue_depth 8, queue_wait 20s) and never queued on llama-server. Streaming chat, thinking off, 45s fallback to clean. Digest and chunk-embedding caches are content-addressed SQLite (Honcho context is not cached). Recover uses the guarded Fetcher. guardian-star is refused in code.
20814 lines
882 KiB
Go
20814 lines
882 KiB
Go
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
|
|
|
//go:build (linux && amd64) || (linux && arm64) || (linux && loong64) || (linux && ppc64le) || (linux && riscv64) || (linux && s390x)
|
|
|
|
package sqlite3
|
|
|
|
import (
|
|
"unsafe"
|
|
|
|
"modernc.org/libc"
|
|
)
|
|
|
|
const F_GETLK = 5
|
|
|
|
const F_GETLK64 = 5
|
|
|
|
const F_SETLK = 6
|
|
|
|
const F_SETLK64 = 6
|
|
|
|
const F_SETLKW = 7
|
|
|
|
const F_SETLKW64 = 7
|
|
|
|
const SIOCGSTAMP = 35078
|
|
|
|
const SIOCGSTAMPNS = 35079
|
|
|
|
type Tcpu_set_t = struct {
|
|
F__bits [16]uint64
|
|
}
|
|
|
|
type Tfd_set = struct {
|
|
Ffds_bits [16]uint64
|
|
}
|
|
|
|
type Tpthread_attr_t = struct {
|
|
F__u struct {
|
|
F__vi [0][14]int32
|
|
F__s [0][7]uint64
|
|
F__i [14]int32
|
|
}
|
|
}
|
|
|
|
type Tpthread_barrier_t = struct {
|
|
F__u struct {
|
|
F__vi [0][8]int32
|
|
F__p [0][4]uintptr
|
|
F__i [8]int32
|
|
}
|
|
}
|
|
|
|
type Tpthread_cond_t = struct {
|
|
F__u struct {
|
|
F__vi [0][12]int32
|
|
F__p [0][6]uintptr
|
|
F__i [12]int32
|
|
}
|
|
}
|
|
|
|
type Tpthread_mutex_t = struct {
|
|
F__u struct {
|
|
F__vi [0][10]int32
|
|
F__p [0][5]uintptr
|
|
F__i [10]int32
|
|
}
|
|
}
|
|
|
|
type Tpthread_rwlock_t = struct {
|
|
F__u struct {
|
|
F__vi [0][14]int32
|
|
F__p [0][7]uintptr
|
|
F__i [14]int32
|
|
}
|
|
}
|
|
|
|
type Tsched_param = struct {
|
|
Fsched_priority int32
|
|
F__reserved1 int32
|
|
F__reserved2 [2]struct {
|
|
F__reserved1 Ttime_t
|
|
F__reserved2 int64
|
|
}
|
|
F__reserved3 int32
|
|
}
|
|
|
|
type Tsigset_t = struct {
|
|
F__bits [16]uint64
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Create an sqlite3_backup process to copy the contents of zSrcDb from
|
|
// ** connection handle pSrcDb to zDestDb in pDestDb. If successful, return
|
|
// ** a pointer to the new sqlite3_backup object.
|
|
// **
|
|
// ** If an error occurs, NULL is returned and an error code and error message
|
|
// ** stored in database handle pDestDb.
|
|
// */
|
|
func Xsqlite3_backup_init(tls *libc.TLS, pDestDb uintptr, zDestDb uintptr, pSrcDb uintptr, zSrcDb uintptr) (r uintptr) {
|
|
var nDest int32
|
|
var p, pDest uintptr
|
|
_, _, _ = nDest, p, pDest /* Value to return */
|
|
/* Lock the source database handle. The destination database
|
|
** handle is not locked in this routine, but it is locked in
|
|
** sqlite3_backup_step(). The user is required to ensure that no
|
|
** other thread accesses the destination handle for the duration
|
|
** of the backup operation. Any attempt to use the destination
|
|
** database connection while a backup is in progress may cause
|
|
** a malfunction or a deadlock.
|
|
*/
|
|
Xsqlite3_mutex_enter(tls, (*Tsqlite3)(unsafe.Pointer(pSrcDb)).Fmutex)
|
|
Xsqlite3_mutex_enter(tls, (*Tsqlite3)(unsafe.Pointer(pDestDb)).Fmutex)
|
|
if pSrcDb == pDestDb {
|
|
_sqlite3ErrorWithMsg(tls, pDestDb, int32(SQLITE_ERROR), __ccgo_ts+5204, 0)
|
|
p = uintptr(0)
|
|
} else {
|
|
nDest = _sqlite3Strlen30(tls, zDestDb)
|
|
/* Allocate space for a new sqlite3_backup object...
|
|
** EVIDENCE-OF: R-64852-21591 The sqlite3_backup object is created by a
|
|
** call to sqlite3_backup_init() and is destroyed by a call to
|
|
** sqlite3_backup_finish(). */
|
|
p = _sqlite3MallocZero(tls, uint64(uint64(80)+libc.Uint64FromInt32(nDest)+uint64(1)))
|
|
if !(p != 0) {
|
|
_sqlite3Error(tls, pDestDb, int32(SQLITE_NOMEM))
|
|
} else {
|
|
(*Tsqlite3_backup)(unsafe.Pointer(p)).FzDestDb = p + 1*80
|
|
libc.Xmemcpy(tls, (*Tsqlite3_backup)(unsafe.Pointer(p)).FzDestDb, zDestDb, libc.Uint64FromInt32(nDest))
|
|
}
|
|
}
|
|
/* If the allocation succeeded, populate the new object. */
|
|
if p != 0 {
|
|
/* Do not store the pointer to the destination b-tree at this point.
|
|
** This is because there is nothing preventing it from being detached
|
|
** or otherwise freed before the first call to sqlite3_backup_step()
|
|
** on this object. The source b-tree does not have this problem, as
|
|
** incrementing Btree.nBackup (see below) effectively locks the object. */
|
|
pDest = _findBtree(tls, pDestDb, pDestDb, zDestDb)
|
|
(*Tsqlite3_backup)(unsafe.Pointer(p)).FpSrc = _findBtree(tls, pDestDb, pSrcDb, zSrcDb)
|
|
(*Tsqlite3_backup)(unsafe.Pointer(p)).FpDestDb = pDestDb
|
|
(*Tsqlite3_backup)(unsafe.Pointer(p)).FpSrcDb = pSrcDb
|
|
(*Tsqlite3_backup)(unsafe.Pointer(p)).FiNext = uint32(1)
|
|
(*Tsqlite3_backup)(unsafe.Pointer(p)).FisAttached = 0
|
|
if uintptr(0) == (*Tsqlite3_backup)(unsafe.Pointer(p)).FpSrc || uintptr(0) == pDest || _checkReadTransaction(tls, pDestDb, pDest) != SQLITE_OK {
|
|
/* One (or both) of the named databases did not exist or an OOM
|
|
** error was hit. Or there is a transaction open on the destination
|
|
** database. The error has already been written into the pDestDb
|
|
** handle. All that is left to do here is free the sqlite3_backup
|
|
** structure. */
|
|
Xsqlite3_free(tls, p)
|
|
p = uintptr(0)
|
|
}
|
|
}
|
|
if p != 0 {
|
|
(*TBtree)(unsafe.Pointer((*Tsqlite3_backup)(unsafe.Pointer(p)).FpSrc)).FnBackup = (*TBtree)(unsafe.Pointer((*Tsqlite3_backup)(unsafe.Pointer(p)).FpSrc)).FnBackup + 1
|
|
}
|
|
Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer(pDestDb)).Fmutex)
|
|
Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer(pSrcDb)).Fmutex)
|
|
return p
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Open a blob handle.
|
|
// */
|
|
func Xsqlite3_blob_open(tls *libc.TLS, db uintptr, zDb uintptr, zTable uintptr, zColumn uintptr, iRow Tsqlite_int64, wrFlag int32, ppBlob uintptr) (r int32) {
|
|
bp := tls.Alloc(448)
|
|
defer tls.Free(448)
|
|
var aOp, pBlob, pFKey, pIdx, pTab, v, zFault, v8 uintptr
|
|
var iCol, iDb, j, j1, nAttempt, rc, v1 int32
|
|
var v2 bool
|
|
var _ /* sParse at bp+8 */ TParse
|
|
var _ /* zErr at bp+0 */ uintptr
|
|
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = aOp, iCol, iDb, j, j1, nAttempt, pBlob, pFKey, pIdx, pTab, rc, v, zFault, v1, v2, v8
|
|
nAttempt = 0 /* Index of zColumn in row-record */
|
|
rc = SQLITE_OK
|
|
**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
|
|
pBlob = uintptr(0)
|
|
**(**uintptr)(__ccgo_up(ppBlob)) = uintptr(0)
|
|
wrFlag = libc.BoolInt32(!!(wrFlag != 0)) /* wrFlag = (wrFlag ? 1 : 0); */
|
|
Xsqlite3_mutex_enter(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
|
|
pBlob = _sqlite3DbMallocZero(tls, db, uint64(56))
|
|
for int32(1) != 0 {
|
|
_sqlite3ParseObjectInit(tls, bp+8, db)
|
|
if !(pBlob != 0) {
|
|
goto blob_open_out
|
|
}
|
|
_sqlite3DbFree(tls, db, **(**uintptr)(__ccgo_up(bp)))
|
|
**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
|
|
_sqlite3BtreeEnterAll(tls, db)
|
|
pTab = _sqlite3LocateTable(tls, bp+8, uint32(0), zTable, zDb)
|
|
if pTab != 0 && libc.Int32FromUint8((*TTable)(unsafe.Pointer(pTab)).FeTabType) == int32(TABTYP_VTAB) {
|
|
pTab = uintptr(0)
|
|
_sqlite3ErrorMsg(tls, bp+8, __ccgo_ts+6577, libc.VaList(bp+440, zTable))
|
|
}
|
|
if pTab != 0 && !((*TTable)(unsafe.Pointer(pTab)).FtabFlags&libc.Uint32FromInt32(TF_WithoutRowid) == libc.Uint32FromInt32(0)) {
|
|
pTab = uintptr(0)
|
|
_sqlite3ErrorMsg(tls, bp+8, __ccgo_ts+6607, libc.VaList(bp+440, zTable))
|
|
}
|
|
if pTab != 0 && (*TTable)(unsafe.Pointer(pTab)).FtabFlags&uint32(TF_HasGenerated) != uint32(0) {
|
|
pTab = uintptr(0)
|
|
_sqlite3ErrorMsg(tls, bp+8, __ccgo_ts+6643, libc.VaList(bp+440, zTable))
|
|
}
|
|
if pTab != 0 && libc.Int32FromUint8((*TTable)(unsafe.Pointer(pTab)).FeTabType) == int32(TABTYP_VIEW) {
|
|
pTab = uintptr(0)
|
|
_sqlite3ErrorMsg(tls, bp+8, __ccgo_ts+6688, libc.VaList(bp+440, zTable))
|
|
}
|
|
if v2 = pTab == uintptr(0); !v2 {
|
|
v1 = _sqlite3SchemaToIndex(tls, db, (*TTable)(unsafe.Pointer(pTab)).FpSchema)
|
|
iDb = v1
|
|
}
|
|
if v2 || v1 == int32(1) && _sqlite3OpenTempDatabase(tls, bp+8) != 0 {
|
|
if (**(**TParse)(__ccgo_up(bp + 8))).FzErrMsg != 0 {
|
|
_sqlite3DbFree(tls, db, **(**uintptr)(__ccgo_up(bp)))
|
|
**(**uintptr)(__ccgo_up(bp)) = (**(**TParse)(__ccgo_up(bp + 8))).FzErrMsg
|
|
(**(**TParse)(__ccgo_up(bp + 8))).FzErrMsg = uintptr(0)
|
|
}
|
|
rc = int32(SQLITE_ERROR)
|
|
_sqlite3BtreeLeaveAll(tls, db)
|
|
goto blob_open_out
|
|
}
|
|
(*TIncrblob)(unsafe.Pointer(pBlob)).FpTab = pTab
|
|
(*TIncrblob)(unsafe.Pointer(pBlob)).FzDb = (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(iDb)*32))).FzDbSName
|
|
/* Now search pTab for the exact column. */
|
|
iCol = _sqlite3ColumnIndex(tls, pTab, zColumn)
|
|
if iCol < 0 {
|
|
_sqlite3DbFree(tls, db, **(**uintptr)(__ccgo_up(bp)))
|
|
**(**uintptr)(__ccgo_up(bp)) = _sqlite3MPrintf(tls, db, __ccgo_ts+6709, libc.VaList(bp+440, zColumn))
|
|
rc = int32(SQLITE_ERROR)
|
|
_sqlite3BtreeLeaveAll(tls, db)
|
|
goto blob_open_out
|
|
}
|
|
/* If the value is being opened for writing, check that the
|
|
** column is not indexed, and that it is not part of a foreign key.
|
|
*/
|
|
if wrFlag != 0 {
|
|
zFault = uintptr(0)
|
|
if (*Tsqlite3)(unsafe.Pointer(db)).Fflags&uint64(SQLITE_ForeignKeys) != 0 {
|
|
pFKey = (*(*struct {
|
|
FaddColOffset int32
|
|
FpFKey uintptr
|
|
FpDfltList uintptr
|
|
})(unsafe.Pointer(pTab + 64))).FpFKey
|
|
for {
|
|
if !(pFKey != 0) {
|
|
break
|
|
}
|
|
j = 0
|
|
for {
|
|
if !(j < (*TFKey)(unsafe.Pointer(pFKey)).FnCol) {
|
|
break
|
|
}
|
|
if (*(*TsColMap)(unsafe.Pointer(pFKey + 64 + uintptr(j)*16))).FiFrom == iCol {
|
|
zFault = __ccgo_ts + 6730
|
|
}
|
|
goto _4
|
|
_4:
|
|
;
|
|
j = j + 1
|
|
}
|
|
goto _3
|
|
_3:
|
|
;
|
|
pFKey = (*TFKey)(unsafe.Pointer(pFKey)).FpNextFrom
|
|
}
|
|
}
|
|
pIdx = (*TTable)(unsafe.Pointer(pTab)).FpIndex
|
|
for {
|
|
if !(pIdx != 0) {
|
|
break
|
|
}
|
|
j1 = 0
|
|
for {
|
|
if !(j1 < libc.Int32FromUint16((*TIndex)(unsafe.Pointer(pIdx)).FnKeyCol)) {
|
|
break
|
|
}
|
|
/* FIXME: Be smarter about indexes that use expressions */
|
|
if int32(**(**Ti16)(__ccgo_up((*TIndex)(unsafe.Pointer(pIdx)).FaiColumn + uintptr(j1)*2))) == iCol || int32(**(**Ti16)(__ccgo_up((*TIndex)(unsafe.Pointer(pIdx)).FaiColumn + uintptr(j1)*2))) == -int32(2) {
|
|
zFault = __ccgo_ts + 6742
|
|
}
|
|
goto _6
|
|
_6:
|
|
;
|
|
j1 = j1 + 1
|
|
}
|
|
goto _5
|
|
_5:
|
|
;
|
|
pIdx = (*TIndex)(unsafe.Pointer(pIdx)).FpNext
|
|
}
|
|
if zFault != 0 {
|
|
_sqlite3DbFree(tls, db, **(**uintptr)(__ccgo_up(bp)))
|
|
**(**uintptr)(__ccgo_up(bp)) = _sqlite3MPrintf(tls, db, __ccgo_ts+6750, libc.VaList(bp+440, zFault))
|
|
rc = int32(SQLITE_ERROR)
|
|
_sqlite3BtreeLeaveAll(tls, db)
|
|
goto blob_open_out
|
|
}
|
|
}
|
|
(*TIncrblob)(unsafe.Pointer(pBlob)).FpStmt = _sqlite3VdbeCreate(tls, bp+8)
|
|
if (*TIncrblob)(unsafe.Pointer(pBlob)).FpStmt != 0 {
|
|
v = (*TIncrblob)(unsafe.Pointer(pBlob)).FpStmt
|
|
_sqlite3VdbeAddOp4Int(tls, v, int32(OP_Transaction), iDb, wrFlag, (*TSchema)(unsafe.Pointer((*TTable)(unsafe.Pointer(pTab)).FpSchema)).Fschema_cookie, (*TSchema)(unsafe.Pointer((*TTable)(unsafe.Pointer(pTab)).FpSchema)).FiGeneration)
|
|
_sqlite3VdbeChangeP5(tls, v, uint16(1))
|
|
aOp = _sqlite3VdbeAddOpList(tls, v, libc.Int32FromUint64(libc.Uint64FromInt64(24)/libc.Uint64FromInt64(4)), uintptr(unsafe.Pointer(&_openBlob)), _iLn)
|
|
/* Make sure a mutex is held on the table to be accessed */
|
|
_sqlite3VdbeUsesBtree(tls, v, iDb)
|
|
if libc.Int32FromUint8((*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed) == 0 {
|
|
/* Configure the OP_TableLock instruction */
|
|
(**(**TVdbeOp)(__ccgo_up(aOp))).Fp1 = iDb
|
|
(**(**TVdbeOp)(__ccgo_up(aOp))).Fp2 = libc.Int32FromUint32((*TTable)(unsafe.Pointer(pTab)).Ftnum)
|
|
(**(**TVdbeOp)(__ccgo_up(aOp))).Fp3 = wrFlag
|
|
_sqlite3VdbeChangeP4(tls, v, int32(2), (*TTable)(unsafe.Pointer(pTab)).FzName, P4_TRANSIENT)
|
|
}
|
|
if libc.Int32FromUint8((*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed) == 0 {
|
|
/* Remove either the OP_OpenWrite or OpenRead. Set the P2
|
|
** parameter of the other to pTab->tnum. */
|
|
if wrFlag != 0 {
|
|
(**(**TVdbeOp)(__ccgo_up(aOp + 1*24))).Fopcode = uint8(OP_OpenWrite)
|
|
}
|
|
(**(**TVdbeOp)(__ccgo_up(aOp + 1*24))).Fp2 = libc.Int32FromUint32((*TTable)(unsafe.Pointer(pTab)).Ftnum)
|
|
(**(**TVdbeOp)(__ccgo_up(aOp + 1*24))).Fp3 = iDb
|
|
/* Configure the number of columns. Configure the cursor to
|
|
** think that the table has one more column than it really
|
|
** does. An OP_Column to retrieve this imaginary column will
|
|
** always return an SQL NULL. This is useful because it means
|
|
** we can invoke OP_Column to fill in the vdbe cursors type
|
|
** and offset cache without causing any IO.
|
|
*/
|
|
(**(**TVdbeOp)(__ccgo_up(aOp + 1*24))).Fp4type = int8(-libc.Int32FromInt32(3))
|
|
*(*int32)(unsafe.Pointer(aOp + 1*24 + 16)) = int32((*TTable)(unsafe.Pointer(pTab)).FnCol) + int32(1)
|
|
(**(**TVdbeOp)(__ccgo_up(aOp + 3*24))).Fp2 = int32((*TTable)(unsafe.Pointer(pTab)).FnCol)
|
|
(**(**TParse)(__ccgo_up(bp + 8))).FnVar = 0
|
|
(**(**TParse)(__ccgo_up(bp + 8))).FnMem = int32(1)
|
|
(**(**TParse)(__ccgo_up(bp + 8))).FnTab = int32(1)
|
|
_sqlite3VdbeMakeReady(tls, v, bp+8)
|
|
}
|
|
}
|
|
(*TIncrblob)(unsafe.Pointer(pBlob)).FiCol = libc.Uint16FromInt32(iCol)
|
|
(*TIncrblob)(unsafe.Pointer(pBlob)).Fdb = db
|
|
_sqlite3BtreeLeaveAll(tls, db)
|
|
if (*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0 {
|
|
goto blob_open_out
|
|
}
|
|
rc = _blobSeekToRow(tls, pBlob, iRow, bp)
|
|
nAttempt = nAttempt + 1
|
|
v1 = nAttempt
|
|
if v1 >= int32(SQLITE_MAX_SCHEMA_RETRY) || rc != int32(SQLITE_SCHEMA) {
|
|
break
|
|
}
|
|
_sqlite3ParseObjectReset(tls, bp+8)
|
|
}
|
|
goto blob_open_out
|
|
blob_open_out:
|
|
;
|
|
if rc == SQLITE_OK && libc.Int32FromUint8((*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed) == 0 {
|
|
**(**uintptr)(__ccgo_up(ppBlob)) = pBlob
|
|
} else {
|
|
if pBlob != 0 && (*TIncrblob)(unsafe.Pointer(pBlob)).FpStmt != 0 {
|
|
_sqlite3VdbeFinalize(tls, (*TIncrblob)(unsafe.Pointer(pBlob)).FpStmt)
|
|
}
|
|
_sqlite3DbFree(tls, db, pBlob)
|
|
}
|
|
if **(**uintptr)(__ccgo_up(bp)) != 0 {
|
|
v8 = __ccgo_ts + 3968
|
|
} else {
|
|
v8 = libc.UintptrFromInt32(0)
|
|
}
|
|
_sqlite3ErrorWithMsg(tls, db, rc, v8, libc.VaList(bp+440, **(**uintptr)(__ccgo_up(bp))))
|
|
_sqlite3DbFree(tls, db, **(**uintptr)(__ccgo_up(bp)))
|
|
_sqlite3ParseObjectReset(tls, bp+8)
|
|
rc = _sqlite3ApiExit(tls, db, rc)
|
|
Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Query the database. But instead of invoking a callback for each row,
|
|
// ** malloc() for space to hold the result and return the entire results
|
|
// ** at the conclusion of the call.
|
|
// **
|
|
// ** The result that is written to ***pazResult is held in memory obtained
|
|
// ** from malloc(). But the caller cannot free this memory directly.
|
|
// ** Instead, the entire table should be passed to sqlite3_free_table() when
|
|
// ** the calling procedure is finished using it.
|
|
// */
|
|
func Xsqlite3_get_table(tls *libc.TLS, db uintptr, zSql uintptr, pazResult uintptr, pnRow uintptr, pnColumn uintptr, pzErrMsg uintptr) (r int32) {
|
|
bp := tls.Alloc(64)
|
|
defer tls.Free(64)
|
|
var azNew uintptr
|
|
var rc int32
|
|
var _ /* res at bp+0 */ TTabResult
|
|
_, _ = azNew, rc
|
|
**(**uintptr)(__ccgo_up(pazResult)) = uintptr(0)
|
|
if pnColumn != 0 {
|
|
**(**int32)(__ccgo_up(pnColumn)) = 0
|
|
}
|
|
if pnRow != 0 {
|
|
**(**int32)(__ccgo_up(pnRow)) = 0
|
|
}
|
|
if pzErrMsg != 0 {
|
|
**(**uintptr)(__ccgo_up(pzErrMsg)) = uintptr(0)
|
|
}
|
|
(**(**TTabResult)(__ccgo_up(bp))).FzErrMsg = uintptr(0)
|
|
(**(**TTabResult)(__ccgo_up(bp))).FnRow = uint32(0)
|
|
(**(**TTabResult)(__ccgo_up(bp))).FnColumn = uint32(0)
|
|
(**(**TTabResult)(__ccgo_up(bp))).FnData = uint32(1)
|
|
(**(**TTabResult)(__ccgo_up(bp))).FnAlloc = uint32(20)
|
|
(**(**TTabResult)(__ccgo_up(bp))).Frc = SQLITE_OK
|
|
(**(**TTabResult)(__ccgo_up(bp))).FazResult = Xsqlite3_malloc64(tls, uint64(8)*uint64((**(**TTabResult)(__ccgo_up(bp))).FnAlloc))
|
|
if (**(**TTabResult)(__ccgo_up(bp))).FazResult == uintptr(0) {
|
|
(*Tsqlite3)(unsafe.Pointer(db)).FerrCode = int32(SQLITE_NOMEM)
|
|
return int32(SQLITE_NOMEM)
|
|
}
|
|
**(**uintptr)(__ccgo_up((**(**TTabResult)(__ccgo_up(bp))).FazResult)) = uintptr(0)
|
|
rc = Xsqlite3_exec(tls, db, zSql, __ccgo_fp(_sqlite3_get_table_cb), bp, pzErrMsg)
|
|
**(**uintptr)(__ccgo_up((**(**TTabResult)(__ccgo_up(bp))).FazResult)) = uintptr(libc.Int64FromUint32((**(**TTabResult)(__ccgo_up(bp))).FnData))
|
|
if rc&int32(0xff) == int32(SQLITE_ABORT) {
|
|
Xsqlite3_free_table(tls, (**(**TTabResult)(__ccgo_up(bp))).FazResult+1*8)
|
|
if (**(**TTabResult)(__ccgo_up(bp))).FzErrMsg != 0 {
|
|
if pzErrMsg != 0 {
|
|
Xsqlite3_free(tls, **(**uintptr)(__ccgo_up(pzErrMsg)))
|
|
**(**uintptr)(__ccgo_up(pzErrMsg)) = Xsqlite3_mprintf(tls, __ccgo_ts+3968, libc.VaList(bp+48, (**(**TTabResult)(__ccgo_up(bp))).FzErrMsg))
|
|
}
|
|
Xsqlite3_free(tls, (**(**TTabResult)(__ccgo_up(bp))).FzErrMsg)
|
|
}
|
|
(*Tsqlite3)(unsafe.Pointer(db)).FerrCode = (**(**TTabResult)(__ccgo_up(bp))).Frc /* Assume 32-bit assignment is atomic */
|
|
return (**(**TTabResult)(__ccgo_up(bp))).Frc
|
|
}
|
|
Xsqlite3_free(tls, (**(**TTabResult)(__ccgo_up(bp))).FzErrMsg)
|
|
if rc != SQLITE_OK {
|
|
Xsqlite3_free_table(tls, (**(**TTabResult)(__ccgo_up(bp))).FazResult+1*8)
|
|
return rc
|
|
}
|
|
if (**(**TTabResult)(__ccgo_up(bp))).FnAlloc > (**(**TTabResult)(__ccgo_up(bp))).FnData {
|
|
azNew = _sqlite3Realloc(tls, (**(**TTabResult)(__ccgo_up(bp))).FazResult, uint64(8)*uint64((**(**TTabResult)(__ccgo_up(bp))).FnData))
|
|
if azNew == uintptr(0) {
|
|
Xsqlite3_free_table(tls, (**(**TTabResult)(__ccgo_up(bp))).FazResult+1*8)
|
|
(*Tsqlite3)(unsafe.Pointer(db)).FerrCode = int32(SQLITE_NOMEM)
|
|
return int32(SQLITE_NOMEM)
|
|
}
|
|
(**(**TTabResult)(__ccgo_up(bp))).FazResult = azNew
|
|
}
|
|
**(**uintptr)(__ccgo_up(pazResult)) = (**(**TTabResult)(__ccgo_up(bp))).FazResult + 1*8
|
|
if pnColumn != 0 {
|
|
**(**int32)(__ccgo_up(pnColumn)) = libc.Int32FromUint32((**(**TTabResult)(__ccgo_up(bp))).FnColumn)
|
|
}
|
|
if pnRow != 0 {
|
|
**(**int32)(__ccgo_up(pnRow)) = libc.Int32FromUint32((**(**TTabResult)(__ccgo_up(bp))).FnRow)
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Initialize SQLite.
|
|
// **
|
|
// ** This routine must be called to initialize the memory allocation,
|
|
// ** VFS, and mutex subsystems prior to doing any serious work with
|
|
// ** SQLite. But as long as you do not compile with SQLITE_OMIT_AUTOINIT
|
|
// ** this routine will be called automatically by key routines such as
|
|
// ** sqlite3_open().
|
|
// **
|
|
// ** This routine is a no-op except on its very first call for the process,
|
|
// ** or for the first call after a call to sqlite3_shutdown.
|
|
// **
|
|
// ** The first thread to call this routine runs the initialization to
|
|
// ** completion. If subsequent threads call this routine before the first
|
|
// ** thread has finished the initialization process, then the subsequent
|
|
// ** threads must block until the first thread finishes with the initialization.
|
|
// **
|
|
// ** The first thread might call this routine recursively. Recursive
|
|
// ** calls to this routine should not block, of course. Otherwise the
|
|
// ** initialization process would never complete.
|
|
// **
|
|
// ** Let X be the first thread to enter this routine. Let Y be some other
|
|
// ** thread. Then while the initial invocation of this routine by X is
|
|
// ** incomplete, it is required that:
|
|
// **
|
|
// ** * Calls to this routine from Y must block until the outer-most
|
|
// ** call by X completes.
|
|
// **
|
|
// ** * Recursive calls to this routine from thread X return immediately
|
|
// ** without blocking.
|
|
// */
|
|
func Xsqlite3_initialize(tls *libc.TLS) (r int32) {
|
|
var pMainMtx uintptr
|
|
var rc int32
|
|
_, _ = pMainMtx, rc /* Result code */
|
|
/* If the following assert() fails on some obscure processor/compiler
|
|
** combination, the work-around is to set the correct pointer
|
|
** size at compile-time using -DSQLITE_PTRSIZE=n compile-time option */
|
|
/* If SQLite is already completely initialized, then this call
|
|
** to sqlite3_initialize() should be a no-op. But the initialization
|
|
** must be complete. So isInit must not be set until the very end
|
|
** of this routine.
|
|
*/
|
|
if libc.AtomicLoadPInt32(uintptr(unsafe.Pointer(&_sqlite3Config))+340) != 0 {
|
|
_sqlite3MemoryBarrier(tls)
|
|
return SQLITE_OK
|
|
}
|
|
/* Make sure the mutex subsystem is initialized. If unable to
|
|
** initialize the mutex subsystem, return early with the error.
|
|
** If the system is so sick that we are unable to allocate a mutex,
|
|
** there is not much SQLite is going to be able to do.
|
|
**
|
|
** The mutex subsystem must take care of serializing its own
|
|
** initialization.
|
|
*/
|
|
rc = _sqlite3MutexInit(tls)
|
|
if rc != 0 {
|
|
return rc
|
|
}
|
|
/* Initialize the malloc() system and the recursive pInitMutex mutex.
|
|
** This operation is protected by the STATIC_MAIN mutex. Note that
|
|
** MutexAlloc() is called for a static mutex prior to initializing the
|
|
** malloc subsystem - this implies that the allocation of a static
|
|
** mutex must not require support from the malloc subsystem.
|
|
*/
|
|
pMainMtx = _sqlite3MutexAlloc(tls, int32(SQLITE_MUTEX_STATIC_MAIN))
|
|
Xsqlite3_mutex_enter(tls, pMainMtx)
|
|
_sqlite3Config.FisMutexInit = int32(1)
|
|
if !(_sqlite3Config.FisMallocInit != 0) {
|
|
rc = _sqlite3MallocInit(tls)
|
|
}
|
|
if rc == SQLITE_OK {
|
|
_sqlite3Config.FisMallocInit = int32(1)
|
|
if !(_sqlite3Config.FpInitMutex != 0) {
|
|
_sqlite3Config.FpInitMutex = _sqlite3MutexAlloc(tls, int32(SQLITE_MUTEX_RECURSIVE))
|
|
if _sqlite3Config.FbCoreMutex != 0 && !(_sqlite3Config.FpInitMutex != 0) {
|
|
rc = int32(SQLITE_NOMEM)
|
|
}
|
|
}
|
|
}
|
|
if rc == SQLITE_OK {
|
|
_sqlite3Config.FnRefInitMutex = _sqlite3Config.FnRefInitMutex + 1
|
|
}
|
|
Xsqlite3_mutex_leave(tls, pMainMtx)
|
|
/* If rc is not SQLITE_OK at this point, then either the malloc
|
|
** subsystem could not be initialized or the system failed to allocate
|
|
** the pInitMutex mutex. Return an error in either case. */
|
|
if rc != SQLITE_OK {
|
|
return rc
|
|
}
|
|
/* Do the rest of the initialization under the recursive mutex so
|
|
** that we will be able to handle recursive calls into
|
|
** sqlite3_initialize(). The recursive calls normally come through
|
|
** sqlite3_os_init() when it invokes sqlite3_vfs_register(), but other
|
|
** recursive calls might also be possible.
|
|
**
|
|
** IMPLEMENTATION-OF: R-00140-37445 SQLite automatically serializes calls
|
|
** to the xInit method, so the xInit method need not be threadsafe.
|
|
**
|
|
** The following mutex is what serializes access to the appdef pcache xInit
|
|
** methods. The sqlite3_pcache_methods.xInit() all is embedded in the
|
|
** call to sqlite3PcacheInitialize().
|
|
*/
|
|
Xsqlite3_mutex_enter(tls, _sqlite3Config.FpInitMutex)
|
|
if libc.AtomicLoadPInt32(uintptr(unsafe.Pointer(&_sqlite3Config))+340) == 0 && _sqlite3Config.FinProgress == 0 {
|
|
_sqlite3Config.FinProgress = int32(1)
|
|
libc.Xmemset(tls, uintptr(unsafe.Pointer(&_sqlite3BuiltinFunctions)), 0, uint64(184))
|
|
_sqlite3RegisterBuiltinFunctions(tls)
|
|
if _sqlite3Config.FisPCacheInit == 0 {
|
|
rc = _sqlite3PcacheInitialize(tls)
|
|
}
|
|
if rc == SQLITE_OK {
|
|
_sqlite3Config.FisPCacheInit = int32(1)
|
|
rc = _sqlite3OsInit(tls)
|
|
}
|
|
if rc == SQLITE_OK {
|
|
rc = _sqlite3MemdbInit(tls)
|
|
}
|
|
if rc == SQLITE_OK {
|
|
_sqlite3PCacheBufferSetup(tls, _sqlite3Config.FpPage, _sqlite3Config.FszPage, _sqlite3Config.FnPage)
|
|
}
|
|
if rc == SQLITE_OK {
|
|
_sqlite3MemoryBarrier(tls)
|
|
libc.AtomicStorePInt32(uintptr(unsafe.Pointer(&_sqlite3Config))+340, int32(1))
|
|
}
|
|
_sqlite3Config.FinProgress = 0
|
|
}
|
|
Xsqlite3_mutex_leave(tls, _sqlite3Config.FpInitMutex)
|
|
/* Go back under the static mutex and clean up the recursive
|
|
** mutex to prevent a resource leak.
|
|
*/
|
|
Xsqlite3_mutex_enter(tls, pMainMtx)
|
|
_sqlite3Config.FnRefInitMutex = _sqlite3Config.FnRefInitMutex - 1
|
|
if _sqlite3Config.FnRefInitMutex <= 0 {
|
|
Xsqlite3_mutex_free(tls, _sqlite3Config.FpInitMutex)
|
|
_sqlite3Config.FpInitMutex = uintptr(0)
|
|
}
|
|
Xsqlite3_mutex_leave(tls, pMainMtx)
|
|
/* The following is just a sanity check to make sure SQLite has
|
|
** been compiled correctly. It is important to run this code, but
|
|
** we don't want to run it too often and soak up CPU cycles for no
|
|
** reason. So we run it once during initialization.
|
|
*/
|
|
/* Do extra initialization steps requested by the SQLITE_EXTRA_INIT
|
|
** compile-time option.
|
|
*/
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Initialize the operating system interface.
|
|
// **
|
|
// ** This routine registers all VFS implementations for unix-like operating
|
|
// ** systems. This routine, and the sqlite3_os_end() routine that follows,
|
|
// ** should be the only routines in this file that are visible from other
|
|
// ** files.
|
|
// **
|
|
// ** This routine is called once during SQLite initialization and by a
|
|
// ** single thread. The memory allocation and mutex subsystems have not
|
|
// ** necessarily been initialized when this routine is called, and so they
|
|
// ** should not be used.
|
|
// */
|
|
func Xsqlite3_os_init(tls *libc.TLS) (r int32) {
|
|
var i uint32
|
|
_ = i
|
|
/* Double-check that the aSyscall[] array has been constructed
|
|
** correctly. See ticket [bb3a86e890c8e96ab] */
|
|
/* Settle POSIX vs OFD locking before any file can be opened */
|
|
_ofdInitOnce(tls)
|
|
/* Register all VFSes defined in the aVfs[] array */
|
|
i = uint32(0)
|
|
for {
|
|
if !(uint64(i) < libc.Uint64FromInt64(672)/libc.Uint64FromInt64(168)) {
|
|
break
|
|
}
|
|
Xsqlite3_vfs_register(tls, uintptr(unsafe.Pointer(&_aVfs))+uintptr(i)*168, libc.BoolInt32(i == uint32(0)))
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
_unixBigLock = _sqlite3MutexAlloc(tls, int32(SQLITE_MUTEX_STATIC_VFS1))
|
|
/* Validate lock assumptions */
|
|
/* Number of available locks */
|
|
/* Start of locking area */
|
|
/* Locks:
|
|
** WRITE UNIX_SHM_BASE 120
|
|
** CKPT UNIX_SHM_BASE+1 121
|
|
** RECOVER UNIX_SHM_BASE+2 122
|
|
** READ-0 UNIX_SHM_BASE+3 123
|
|
** READ-1 UNIX_SHM_BASE+4 124
|
|
** READ-2 UNIX_SHM_BASE+5 125
|
|
** READ-3 UNIX_SHM_BASE+6 126
|
|
** READ-4 UNIX_SHM_BASE+7 127
|
|
** DMS UNIX_SHM_BASE+8 128
|
|
*/
|
|
/* Byte offset of the deadman-switch */
|
|
/* Initialize temp file dir array. */
|
|
_unixTempFileInit(tls)
|
|
return SQLITE_OK
|
|
}
|
|
|
|
/*
|
|
** The following macro defines an initializer for an sqlite3_vfs object.
|
|
** The name of the VFS is NAME. The pAppData is a pointer to a pointer
|
|
** to the "finder" function. (pAppData is a pointer to a pointer because
|
|
** silly C90 rules prohibit a void* from being cast to a function pointer
|
|
** and so we have to go through the intermediate pointer to avoid problems
|
|
** when compiling with -pedantic-errors on GCC.)
|
|
**
|
|
** The FINDER parameter to this macro is the name of the pointer to the
|
|
** finder-function. The finder-function returns a pointer to the
|
|
** sqlite_io_methods object that implements the desired locking
|
|
** behaviors. See the division above that contains the IOMETHODS
|
|
** macro for addition information on finder-functions.
|
|
**
|
|
** Most finders simply return a pointer to a fixed sqlite3_io_methods
|
|
** object. But the "autolockIoFinder" available on MacOSX does a little
|
|
** more than that; it looks at the filesystem type that hosts the
|
|
** database file and tries to choose an locking method appropriate for
|
|
** that filesystem time.
|
|
*/
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Return the serialization of a database
|
|
// */
|
|
func Xsqlite3_serialize(tls *libc.TLS, db uintptr, zSchema uintptr, piSize uintptr, mFlags uint32) (r uintptr) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var iDb, nPage, pgno, rc, szPage, v1 int32
|
|
var p, pBt, pOut, pPager, pStore, pTo, zSql uintptr
|
|
var sz Tsqlite3_int64
|
|
var _ /* pPage at bp+8 */ uintptr
|
|
var _ /* pStmt at bp+0 */ uintptr
|
|
_, _, _, _, _, _, _, _, _, _, _, _, _, _ = iDb, nPage, p, pBt, pOut, pPager, pStore, pTo, pgno, rc, sz, szPage, zSql, v1
|
|
szPage = 0
|
|
**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
|
|
pOut = uintptr(0)
|
|
Xsqlite3_mutex_enter(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
|
|
if zSchema == uintptr(0) {
|
|
zSchema = (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb))).FzDbSName
|
|
}
|
|
p = _memdbFromDbSchema(tls, db, zSchema)
|
|
iDb = _sqlite3FindDbName(tls, db, zSchema)
|
|
if piSize != 0 {
|
|
**(**Tsqlite3_int64)(__ccgo_up(piSize)) = int64(-int32(1))
|
|
}
|
|
if iDb < 0 {
|
|
goto serialize_out
|
|
}
|
|
if p != 0 {
|
|
pStore = (*TMemFile)(unsafe.Pointer(p)).FpStore
|
|
if piSize != 0 {
|
|
**(**Tsqlite3_int64)(__ccgo_up(piSize)) = (*TMemStore)(unsafe.Pointer(pStore)).Fsz
|
|
}
|
|
if mFlags&uint32(SQLITE_SERIALIZE_NOCOPY) != 0 {
|
|
pOut = (*TMemStore)(unsafe.Pointer(pStore)).FaData
|
|
} else {
|
|
pOut = Xsqlite3_malloc64(tls, libc.Uint64FromInt64((*TMemStore)(unsafe.Pointer(pStore)).Fsz))
|
|
if pOut != 0 {
|
|
libc.Xmemcpy(tls, pOut, (*TMemStore)(unsafe.Pointer(pStore)).FaData, libc.Uint64FromInt64((*TMemStore)(unsafe.Pointer(pStore)).Fsz))
|
|
}
|
|
}
|
|
goto serialize_out
|
|
}
|
|
pBt = (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(iDb)*32))).FpBt
|
|
if pBt == uintptr(0) {
|
|
goto serialize_out
|
|
}
|
|
szPage = _sqlite3BtreeGetPageSize(tls, pBt)
|
|
zSql = Xsqlite3_mprintf(tls, __ccgo_ts+4161, libc.VaList(bp+24, zSchema))
|
|
if zSql != 0 {
|
|
v1 = Xsqlite3_prepare_v2(tls, db, zSql, -int32(1), bp, uintptr(0))
|
|
} else {
|
|
v1 = int32(SQLITE_NOMEM)
|
|
}
|
|
rc = v1
|
|
Xsqlite3_free(tls, zSql)
|
|
if rc != 0 {
|
|
goto serialize_out
|
|
}
|
|
rc = Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
if rc == int32(SQLITE_ROW) {
|
|
sz = Xsqlite3_column_int64(tls, **(**uintptr)(__ccgo_up(bp)), 0) * int64(szPage)
|
|
if sz == 0 {
|
|
Xsqlite3_reset(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
Xsqlite3_exec(tls, db, __ccgo_ts+4184, uintptr(0), uintptr(0), uintptr(0))
|
|
rc = Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
if rc == int32(SQLITE_ROW) {
|
|
sz = Xsqlite3_column_int64(tls, **(**uintptr)(__ccgo_up(bp)), 0) * int64(szPage)
|
|
}
|
|
}
|
|
if piSize != 0 {
|
|
**(**Tsqlite3_int64)(__ccgo_up(piSize)) = sz
|
|
}
|
|
if mFlags&uint32(SQLITE_SERIALIZE_NOCOPY) != 0 {
|
|
pOut = uintptr(0)
|
|
} else {
|
|
pOut = Xsqlite3_malloc64(tls, libc.Uint64FromInt64(sz))
|
|
if pOut != 0 {
|
|
nPage = Xsqlite3_column_int(tls, **(**uintptr)(__ccgo_up(bp)), 0)
|
|
pPager = _sqlite3BtreePager(tls, pBt)
|
|
pgno = int32(1)
|
|
for {
|
|
if !(pgno <= nPage) {
|
|
break
|
|
}
|
|
**(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0)
|
|
pTo = pOut + uintptr(int64(szPage)*int64(pgno-libc.Int32FromInt32(1)))
|
|
rc = _sqlite3PagerGet(tls, pPager, libc.Uint32FromInt32(pgno), bp+8, 0)
|
|
if rc == SQLITE_OK {
|
|
libc.Xmemcpy(tls, pTo, _sqlite3PagerGetData(tls, **(**uintptr)(__ccgo_up(bp + 8))), libc.Uint64FromInt32(szPage))
|
|
} else {
|
|
libc.Xmemset(tls, pTo, 0, libc.Uint64FromInt32(szPage))
|
|
}
|
|
_sqlite3PagerUnref(tls, **(**uintptr)(__ccgo_up(bp + 8)))
|
|
goto _2
|
|
_2:
|
|
;
|
|
pgno = pgno + 1
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Xsqlite3_finalize(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
goto serialize_out
|
|
serialize_out:
|
|
;
|
|
Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
|
|
return pOut
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Begin adding a change to a changegroup object.
|
|
// */
|
|
func Xsqlite3changegroup_change_begin(tls *libc.TLS, pGrp uintptr, eOp int32, zTab uintptr, bIndirect int32, pzErr uintptr) (r int32) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var aBuf uintptr
|
|
var nReq, rc, v1 int32
|
|
var _ /* pTab at bp+0 */ uintptr
|
|
_, _, _, _ = aBuf, nReq, rc, v1
|
|
**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
|
|
rc = SQLITE_OK
|
|
if (*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fcd.FpTab != 0 {
|
|
rc = int32(SQLITE_MISUSE)
|
|
} else {
|
|
if eOp != int32(SQLITE_INSERT) && eOp != int32(SQLITE_UPDATE) && eOp != int32(SQLITE_DELETE) {
|
|
rc = int32(SQLITE_ERROR)
|
|
} else {
|
|
rc = _sessionChangesetFindTable(tls, pGrp, zTab, uintptr(0), bp)
|
|
}
|
|
}
|
|
if rc == SQLITE_OK {
|
|
if **(**uintptr)(__ccgo_up(bp)) == uintptr(0) {
|
|
if pzErr != 0 {
|
|
**(**uintptr)(__ccgo_up(pzErr)) = Xsqlite3_mprintf(tls, __ccgo_ts+21367, libc.VaList(bp+16, zTab))
|
|
}
|
|
rc = int32(SQLITE_ERROR)
|
|
} else {
|
|
if eOp == int32(SQLITE_UPDATE) {
|
|
v1 = int32(2)
|
|
} else {
|
|
v1 = int32(1)
|
|
}
|
|
nReq = (*TSessionTable)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FnCol * v1
|
|
(*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fcd.FpTab = **(**uintptr)(__ccgo_up(bp))
|
|
(*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fcd.FeOp = eOp
|
|
(*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fcd.FbIndirect = bIndirect
|
|
if (*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fcd.FnBufAlloc < nReq {
|
|
aBuf = Xsqlite3_realloc(tls, (*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fcd.FaBuf, libc.Int32FromUint64(libc.Uint64FromInt32(nReq)*uint64(16)))
|
|
if aBuf == uintptr(0) {
|
|
rc = int32(SQLITE_NOMEM)
|
|
} else {
|
|
libc.Xmemset(tls, aBuf+uintptr((*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fcd.FnBufAlloc)*16, 0, uint64(16)*libc.Uint64FromInt32(nReq-(*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fcd.FnBufAlloc))
|
|
(*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fcd.FaBuf = aBuf
|
|
(*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fcd.FnBufAlloc = nReq
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Finish any change currently being constructed by the changegroup object.
|
|
// */
|
|
func Xsqlite3changegroup_change_finish(tls *libc.TLS, pGrp uintptr, bDiscard int32, pzErr uintptr) (r int32) {
|
|
bp := tls.Alloc(48)
|
|
defer tls.Free(48)
|
|
var aBuf, p, v2, v3 uintptr
|
|
var eUndef Tu8
|
|
var ii, isPK, nBuf, nZero, v7 int32
|
|
var _ /* rc at bp+0 */ int32
|
|
_, _, _, _, _, _, _, _, _, _ = aBuf, eUndef, ii, isPK, nBuf, nZero, p, v2, v3, v7
|
|
**(**int32)(__ccgo_up(bp)) = SQLITE_OK
|
|
if (*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fcd.FpTab != 0 {
|
|
aBuf = (*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fcd.FaBuf
|
|
if bDiscard == 0 {
|
|
nBuf = (*TSessionTable)(unsafe.Pointer((*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fcd.FpTab)).FnCol
|
|
eUndef = uint8(SQLITE_NULL)
|
|
if (*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fcd.FeOp == int32(SQLITE_UPDATE) {
|
|
ii = 0
|
|
for {
|
|
if !(ii < nBuf) {
|
|
break
|
|
}
|
|
if **(**Tu8)(__ccgo_up((*TSessionTable)(unsafe.Pointer((*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fcd.FpTab)).FabPK + uintptr(ii))) != 0 {
|
|
if (**(**TSessionBuffer)(__ccgo_up(aBuf + uintptr(ii)*16))).FnBuf <= int32(1) {
|
|
if (**(**TSessionBuffer)(__ccgo_up(aBuf + uintptr(ii)*16))).FnBuf == int32(1) {
|
|
v2 = __ccgo_ts + 1690
|
|
} else {
|
|
v2 = __ccgo_ts + 36854
|
|
}
|
|
**(**uintptr)(__ccgo_up(pzErr)) = Xsqlite3_mprintf(tls, __ccgo_ts+36864, libc.VaList(bp+16, v2))
|
|
**(**int32)(__ccgo_up(bp)) = int32(SQLITE_ERROR)
|
|
break
|
|
} else {
|
|
if (**(**TSessionBuffer)(__ccgo_up(aBuf + uintptr(ii+nBuf)*16))).FnBuf > 0 {
|
|
**(**uintptr)(__ccgo_up(pzErr)) = Xsqlite3_mprintf(tls, __ccgo_ts+36911, 0)
|
|
**(**int32)(__ccgo_up(bp)) = int32(SQLITE_ERROR)
|
|
break
|
|
}
|
|
}
|
|
} else {
|
|
if (*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).FbPatch == 0 && libc.BoolInt32((**(**TSessionBuffer)(__ccgo_up(aBuf + uintptr(ii)*16))).FnBuf > 0) != libc.BoolInt32((**(**TSessionBuffer)(__ccgo_up(aBuf + uintptr(ii+nBuf)*16))).FnBuf > 0) {
|
|
if (**(**TSessionBuffer)(__ccgo_up(aBuf + uintptr(ii)*16))).FnBuf != 0 {
|
|
v2 = __ccgo_ts + 1704
|
|
} else {
|
|
v2 = __ccgo_ts + 36963
|
|
}
|
|
if (**(**TSessionBuffer)(__ccgo_up(aBuf + uintptr(ii+nBuf)*16))).FnBuf != 0 {
|
|
v3 = __ccgo_ts + 1704
|
|
} else {
|
|
v3 = __ccgo_ts + 36963
|
|
}
|
|
**(**uintptr)(__ccgo_up(pzErr)) = Xsqlite3_mprintf(tls, __ccgo_ts+36966, libc.VaList(bp+16, ii, v2, v3))
|
|
**(**int32)(__ccgo_up(bp)) = int32(SQLITE_ERROR)
|
|
break
|
|
}
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
ii = ii + 1
|
|
}
|
|
eUndef = uint8(0x00)
|
|
if (*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).FbPatch == 0 {
|
|
nBuf = nBuf * int32(2)
|
|
}
|
|
} else {
|
|
ii = 0
|
|
for {
|
|
if !(ii < nBuf) {
|
|
break
|
|
}
|
|
isPK = libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TSessionTable)(unsafe.Pointer((*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fcd.FpTab)).FabPK + uintptr(ii))))
|
|
if ((*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fcd.FeOp == int32(SQLITE_INSERT) || (*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).FbPatch == 0 || isPK != 0) && (**(**TSessionBuffer)(__ccgo_up(aBuf + uintptr(ii)*16))).FnBuf == 0 {
|
|
**(**uintptr)(__ccgo_up(pzErr)) = Xsqlite3_mprintf(tls, __ccgo_ts+37042, libc.VaList(bp+16, ii))
|
|
**(**int32)(__ccgo_up(bp)) = int32(SQLITE_ERROR)
|
|
break
|
|
}
|
|
if (**(**TSessionBuffer)(__ccgo_up(aBuf + uintptr(ii)*16))).FnBuf == int32(1) && isPK != 0 {
|
|
**(**uintptr)(__ccgo_up(pzErr)) = Xsqlite3_mprintf(tls, __ccgo_ts+37081, 0)
|
|
**(**int32)(__ccgo_up(bp)) = int32(SQLITE_ERROR)
|
|
break
|
|
}
|
|
goto _5
|
|
_5:
|
|
;
|
|
ii = ii + 1
|
|
}
|
|
}
|
|
(*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fcd.Frecord.FnBuf = 0
|
|
ii = 0
|
|
for {
|
|
if !(ii < nBuf) {
|
|
break
|
|
}
|
|
p = (*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fcd.FaBuf + uintptr(ii)*16
|
|
if (*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).FbPatch != 0 {
|
|
if libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TSessionTable)(unsafe.Pointer((*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fcd.FpTab)).FabPK + uintptr(ii)))) == 0 {
|
|
if (*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fcd.FeOp == int32(SQLITE_UPDATE) {
|
|
p = p + uintptr((*TSessionTable)(unsafe.Pointer((*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fcd.FpTab)).FnCol)*16
|
|
} else {
|
|
if (*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fcd.FeOp == int32(SQLITE_DELETE) {
|
|
goto _6
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (*TSessionBuffer)(unsafe.Pointer(p)).FnBuf != 0 {
|
|
v7 = (*TSessionBuffer)(unsafe.Pointer(p)).FnBuf
|
|
} else {
|
|
v7 = int32(1)
|
|
}
|
|
if 0 == _sessionBufferGrow(tls, pGrp+48+32, int64(v7), bp) {
|
|
if (*TSessionBuffer)(unsafe.Pointer(p)).FnBuf != 0 {
|
|
libc.Xmemcpy(tls, (*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fcd.Frecord.FaBuf+uintptr((*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fcd.Frecord.FnBuf), (*TSessionBuffer)(unsafe.Pointer(p)).FaBuf, libc.Uint64FromInt32((*TSessionBuffer)(unsafe.Pointer(p)).FnBuf))
|
|
(*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fcd.Frecord.FnBuf += (*TSessionBuffer)(unsafe.Pointer(p)).FnBuf
|
|
} else {
|
|
v2 = pGrp + 48 + 32 + 8
|
|
v7 = *(*int32)(unsafe.Pointer(v2))
|
|
*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1
|
|
**(**Tu8)(__ccgo_up((*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fcd.Frecord.FaBuf + uintptr(v7))) = eUndef
|
|
}
|
|
}
|
|
goto _6
|
|
_6:
|
|
;
|
|
ii = ii + 1
|
|
}
|
|
if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
|
|
**(**int32)(__ccgo_up(bp)) = _sessionOneChangeToHash(tls, pGrp, (*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fcd.FpTab, (*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fcd.FeOp, (*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fcd.FbIndirect, (*TSessionTable)(unsafe.Pointer((*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fcd.FpTab)).FnCol, (*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fcd.Frecord.FaBuf, (*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fcd.Frecord.FnBuf, 0)
|
|
}
|
|
}
|
|
/* Reset all aBuf[] entries to "undefined". */
|
|
nZero = (*TSessionTable)(unsafe.Pointer((*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fcd.FpTab)).FnCol
|
|
if (*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fcd.FeOp == int32(SQLITE_UPDATE) {
|
|
nZero = nZero + nZero
|
|
}
|
|
ii = 0
|
|
for {
|
|
if !(ii < nZero) {
|
|
break
|
|
}
|
|
(**(**TSessionBuffer)(__ccgo_up((*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fcd.FaBuf + uintptr(ii)*16))).FnBuf = 0
|
|
goto _10
|
|
_10:
|
|
;
|
|
ii = ii + 1
|
|
}
|
|
(*Tsqlite3_changegroup)(unsafe.Pointer(pGrp)).Fcd.FpTab = uintptr(0)
|
|
}
|
|
return **(**int32)(__ccgo_up(bp))
|
|
}
|
|
|
|
/************** End of sqlite3session.c **************************************/
|
|
/************** Begin file fts5.c ********************************************/
|
|
|
|
/*
|
|
** This, the "fts5.c" source file, is a composite file that is itself
|
|
** assembled from the following files:
|
|
**
|
|
** fts5.h
|
|
** fts5Int.h
|
|
** fts5parse.h <--- Generated from fts5parse.y by Lemon
|
|
** fts5parse.c <--- Generated from fts5parse.y by Lemon
|
|
** fts5_aux.c
|
|
** fts5_buffer.c
|
|
** fts5_config.c
|
|
** fts5_expr.c
|
|
** fts5_hash.c
|
|
** fts5_index.c
|
|
** fts5_main.c
|
|
** fts5_storage.c
|
|
** fts5_tokenize.c
|
|
** fts5_unicode2.c
|
|
** fts5_varint.c
|
|
** fts5_vocab.c
|
|
*/
|
|
|
|
/*
|
|
** 2014 May 31
|
|
**
|
|
** 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.
|
|
**
|
|
******************************************************************************
|
|
**
|
|
** Interfaces to extend FTS5. Using the interfaces defined in this file,
|
|
** FTS5 may be extended with:
|
|
**
|
|
** * custom tokenizers, and
|
|
** * custom auxiliary functions.
|
|
*/
|
|
|
|
/*
|
|
** 2014 May 31
|
|
**
|
|
** 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.
|
|
**
|
|
******************************************************************************
|
|
**
|
|
*/
|
|
|
|
/* #include "fts5.h" */
|
|
/* #include "sqlite3ext.h" */
|
|
|
|
/* #include <string.h> */
|
|
/* #include <assert.h> */
|
|
/* #include <stddef.h> */
|
|
|
|
/*
|
|
** Constants for the largest and smallest possible 32-bit signed integers.
|
|
*/
|
|
|
|
/* Truncate very long tokens to this many bytes. Hard limit is
|
|
** (65536-1-1-4-9)==65521 bytes. The limiting factor is the 16-bit offset
|
|
** field that occurs at the start of each leaf page (see fts5_index.c). */
|
|
|
|
/*
|
|
** Maximum number of prefix indexes on single FTS5 table. This must be
|
|
** less than 32. If it is set to anything large than that, an #error
|
|
** directive in fts5_index.c will cause the build to fail.
|
|
*/
|
|
|
|
/*
|
|
** Maximum segments permitted in a single index
|
|
*/
|
|
|
|
/* Name of rank and rowid columns */
|
|
|
|
/*
|
|
** The assert_nc() macro is similar to the assert() macro, except that it
|
|
** is used for assert() conditions that are true only if it can be
|
|
** guranteed that the database is not corrupt.
|
|
*/
|
|
|
|
/*
|
|
** A version of memcmp() that does not cause asan errors if one of the pointer
|
|
** parameters is NULL and the number of bytes to compare is zero.
|
|
*/
|
|
|
|
/* Mark a function parameter as unused, to suppress nuisance compiler
|
|
** warnings. */
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Close the RBU handle.
|
|
// */
|
|
func Xsqlite3rbu_close(tls *libc.TLS, p uintptr, pzErrmsg uintptr) (r int32) {
|
|
var pDb uintptr
|
|
var rc, rc2 int32
|
|
_, _, _ = pDb, rc, rc2
|
|
if p != 0 {
|
|
/* Commit the transaction to the *-oal file. */
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK && (*Tsqlite3rbu)(unsafe.Pointer(p)).FeStage == int32(RBU_STAGE_OAL) {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = Xsqlite3_exec(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, __ccgo_ts+16146, uintptr(0), uintptr(0), p+64)
|
|
}
|
|
/* Sync the db file if currently doing an incremental checkpoint */
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK && (*Tsqlite3rbu)(unsafe.Pointer(p)).FeStage == int32(RBU_STAGE_CKPT) {
|
|
pDb = (*Trbu_file)(unsafe.Pointer((*Tsqlite3rbu)(unsafe.Pointer(p)).FpTargetFd)).FpReal
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = (*(*func(*libc.TLS, uintptr, int32) int32)(unsafe.Pointer(&struct{ uintptr }{(*Tsqlite3_io_methods)(unsafe.Pointer((*Tsqlite3_file)(unsafe.Pointer(pDb)).FpMethods)).FxSync})))(tls, pDb, int32(SQLITE_SYNC_NORMAL))
|
|
}
|
|
_rbuSaveState(tls, p, (*Tsqlite3rbu)(unsafe.Pointer(p)).FeStage)
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK && (*Tsqlite3rbu)(unsafe.Pointer(p)).FeStage == int32(RBU_STAGE_OAL) {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = Xsqlite3_exec(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbRbu, __ccgo_ts+16146, uintptr(0), uintptr(0), p+64)
|
|
}
|
|
/* Close any open statement handles. */
|
|
_rbuObjIterFinalize(tls, p+88)
|
|
/* If this is an RBU vacuum handle and the vacuum has either finished
|
|
** successfully or encountered an error, delete the contents of the
|
|
** state table. This causes the next call to sqlite3rbu_vacuum()
|
|
** specifying the current target and state databases to start a new
|
|
** vacuum from scratch. */
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).FzTarget == uintptr(0) && (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc != SQLITE_OK && (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbRbu != 0 {
|
|
rc2 = Xsqlite3_exec(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbRbu, __ccgo_ts+34708, uintptr(0), uintptr(0), uintptr(0))
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == int32(SQLITE_DONE) && rc2 != SQLITE_OK {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = rc2
|
|
}
|
|
}
|
|
/* Close the open database handle and VFS object. */
|
|
Xsqlite3_close(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbRbu)
|
|
Xsqlite3_close(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain)
|
|
_rbuDeleteVfs(tls, p)
|
|
Xsqlite3_free(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FaBuf)
|
|
Xsqlite3_free(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FaFrame)
|
|
_rbuEditErrmsg(tls, p)
|
|
rc = (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc
|
|
if pzErrmsg != 0 {
|
|
**(**uintptr)(__ccgo_up(pzErrmsg)) = (*Tsqlite3rbu)(unsafe.Pointer(p)).FzErrmsg
|
|
} else {
|
|
Xsqlite3_free(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FzErrmsg)
|
|
}
|
|
Xsqlite3_free(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FzState)
|
|
Xsqlite3_free(tls, p)
|
|
} else {
|
|
rc = int32(SQLITE_NOMEM)
|
|
**(**uintptr)(__ccgo_up(pzErrmsg)) = uintptr(0)
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Step the RBU object.
|
|
// */
|
|
func Xsqlite3rbu_step(tls *libc.TLS, p uintptr) (r int32) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var iSector Tu32
|
|
var pDb, pFrame, pIter uintptr
|
|
var rc int32
|
|
var _ /* ptr at bp+0 */ uintptr
|
|
_, _, _, _, _ = iSector, pDb, pFrame, pIter, rc
|
|
if p != 0 {
|
|
switch (*Tsqlite3rbu)(unsafe.Pointer(p)).FeStage {
|
|
case int32(RBU_STAGE_OAL):
|
|
pIter = p + 88
|
|
/* If this is an RBU vacuum operation and the state table was empty
|
|
** when this handle was opened, create the target database schema. */
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).FzTarget == uintptr(0) && (*Tsqlite3rbu)(unsafe.Pointer(p)).FnProgress == 0 && (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
_rbuCreateTargetSchema(tls, p)
|
|
_rbuCopyPragma(tls, p, __ccgo_ts+18964)
|
|
_rbuCopyPragma(tls, p, __ccgo_ts+18075)
|
|
}
|
|
for (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK && (*TRbuObjIter)(unsafe.Pointer(pIter)).FzTbl != 0 {
|
|
if (*TRbuObjIter)(unsafe.Pointer(pIter)).FbCleanup != 0 {
|
|
/* Clean up the rbu_tmp_xxx table for the previous table. It
|
|
** cannot be dropped as there are currently active SQL statements.
|
|
** But the contents can be deleted. */
|
|
if libc.BoolInt32((*Tsqlite3rbu)(unsafe.Pointer(p)).FzTarget == uintptr(0)) == 0 && (*TRbuObjIter)(unsafe.Pointer(pIter)).FabIndexed != 0 {
|
|
_rbuMPrintfExec(tls, p, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbRbu, __ccgo_ts+34301, libc.VaList(bp+16, p+48, (*TRbuObjIter)(unsafe.Pointer(pIter)).FzDataTbl))
|
|
}
|
|
} else {
|
|
_rbuObjIterPrepareAll(tls, p, pIter, 0)
|
|
/* Advance to the next row to process. */
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
rc = Xsqlite3_step(tls, (*TRbuObjIter)(unsafe.Pointer(pIter)).FpSelect)
|
|
if rc == int32(SQLITE_ROW) {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).FnProgress = (*Tsqlite3rbu)(unsafe.Pointer(p)).FnProgress + 1
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).FnStep = (*Tsqlite3rbu)(unsafe.Pointer(p)).FnStep + 1
|
|
return _rbuStep(tls, p)
|
|
}
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = Xsqlite3_reset(tls, (*TRbuObjIter)(unsafe.Pointer(pIter)).FpSelect)
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).FnStep = 0
|
|
}
|
|
}
|
|
_rbuObjIterNext(tls, p, pIter)
|
|
}
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
_rbuSaveState(tls, p, int32(RBU_STAGE_MOVE))
|
|
_rbuIncrSchemaCookie(tls, p)
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = Xsqlite3_exec(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, __ccgo_ts+16146, uintptr(0), uintptr(0), p+64)
|
|
}
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = Xsqlite3_exec(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbRbu, __ccgo_ts+16146, uintptr(0), uintptr(0), p+64)
|
|
}
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).FeStage = int32(RBU_STAGE_MOVE)
|
|
}
|
|
case int32(RBU_STAGE_MOVE):
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
_rbuMoveOalFile(tls, p)
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).FnProgress = (*Tsqlite3rbu)(unsafe.Pointer(p)).FnProgress + 1
|
|
}
|
|
case int32(RBU_STAGE_CKPT):
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).FnStep >= (*Tsqlite3rbu)(unsafe.Pointer(p)).FnFrame {
|
|
pDb = (*Trbu_file)(unsafe.Pointer((*Tsqlite3rbu)(unsafe.Pointer(p)).FpTargetFd)).FpReal
|
|
/* Sync the db file */
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = (*(*func(*libc.TLS, uintptr, int32) int32)(unsafe.Pointer(&struct{ uintptr }{(*Tsqlite3_io_methods)(unsafe.Pointer((*Tsqlite3_file)(unsafe.Pointer(pDb)).FpMethods)).FxSync})))(tls, pDb, int32(SQLITE_SYNC_NORMAL))
|
|
/* Update nBackfill */
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
(*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 {
|
|
**(**Tu32)(__ccgo_up(**(**uintptr)(__ccgo_up(bp)) + 24*4)) = (*Tsqlite3rbu)(unsafe.Pointer(p)).FiMaxFrame
|
|
}
|
|
}
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).FeStage = int32(RBU_STAGE_DONE)
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = int32(SQLITE_DONE)
|
|
}
|
|
} else {
|
|
for cond := true; cond; cond = (*Tsqlite3rbu)(unsafe.Pointer(p)).FnStep < (*Tsqlite3rbu)(unsafe.Pointer(p)).FnFrame && iSector == ((**(**TRbuFrame)(__ccgo_up((*Tsqlite3rbu)(unsafe.Pointer(p)).FaFrame + uintptr((*Tsqlite3rbu)(unsafe.Pointer(p)).FnStep)*8))).FiDbPage-uint32(1))/libc.Uint32FromInt32((*Tsqlite3rbu)(unsafe.Pointer(p)).FnPagePerSector) && (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
pFrame = (*Tsqlite3rbu)(unsafe.Pointer(p)).FaFrame + uintptr((*Tsqlite3rbu)(unsafe.Pointer(p)).FnStep)*8
|
|
iSector = ((*TRbuFrame)(unsafe.Pointer(pFrame)).FiDbPage - uint32(1)) / libc.Uint32FromInt32((*Tsqlite3rbu)(unsafe.Pointer(p)).FnPagePerSector)
|
|
_rbuCheckpointFrame(tls, p, pFrame)
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).FnStep = (*Tsqlite3rbu)(unsafe.Pointer(p)).FnStep + 1
|
|
}
|
|
}
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).FnProgress = (*Tsqlite3rbu)(unsafe.Pointer(p)).FnProgress + 1
|
|
}
|
|
default:
|
|
break
|
|
}
|
|
return (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc
|
|
} else {
|
|
return int32(SQLITE_NOMEM)
|
|
}
|
|
return r
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Open a handle to begin or resume an RBU VACUUM operation.
|
|
// */
|
|
func Xsqlite3rbu_vacuum(tls *libc.TLS, zTarget uintptr, zState uintptr) (r uintptr) {
|
|
var n Tsize_t
|
|
_ = n
|
|
if zTarget == uintptr(0) {
|
|
return _rbuMisuseError(tls)
|
|
}
|
|
if zState != 0 {
|
|
n = libc.Xstrlen(tls, zState)
|
|
if n >= uint64(7) && 0 == libc.Xmemcmp(tls, __ccgo_ts+34700, zState+uintptr(n-uint64(7)), uint64(7)) {
|
|
return _rbuMisuseError(tls)
|
|
}
|
|
}
|
|
/* TODO: Check that both arguments are non-NULL */
|
|
return _openRbuHandle(tls, uintptr(0), zTarget, zState)
|
|
}
|
|
|
|
func Xsqlite3session_diff(tls *libc.TLS, pSession uintptr, zFrom uintptr, zTbl uintptr, pzErrMsg uintptr) (r int32) {
|
|
bp := tls.Alloc(80)
|
|
defer tls.Free(80)
|
|
var bHasPk, bMismatch, i, rc int32
|
|
var db, zDb, zDbExists, zExpr, v1 uintptr
|
|
var _ /* abPK at bp+32 */ uintptr
|
|
var _ /* azCol at bp+40 */ uintptr
|
|
var _ /* bRowid at bp+28 */ int32
|
|
var _ /* d at bp+0 */ TSessionDiffCtx
|
|
var _ /* nCol at bp+24 */ int32
|
|
var _ /* pDbExists at bp+48 */ uintptr
|
|
var _ /* pTo at bp+16 */ uintptr
|
|
_, _, _, _, _, _, _, _, _ = bHasPk, bMismatch, db, i, rc, zDb, zDbExists, zExpr, v1
|
|
zDb = (*Tsqlite3_session)(unsafe.Pointer(pSession)).FzDb
|
|
rc = (*Tsqlite3_session)(unsafe.Pointer(pSession)).Frc
|
|
libc.Xmemset(tls, bp, 0, uint64(16))
|
|
_sessionDiffHooks(tls, pSession, bp)
|
|
Xsqlite3_mutex_enter(tls, Xsqlite3_db_mutex(tls, (*Tsqlite3_session)(unsafe.Pointer(pSession)).Fdb))
|
|
if pzErrMsg != 0 {
|
|
**(**uintptr)(__ccgo_up(pzErrMsg)) = uintptr(0)
|
|
}
|
|
if rc == SQLITE_OK {
|
|
zExpr = uintptr(0)
|
|
db = (*Tsqlite3_session)(unsafe.Pointer(pSession)).Fdb /* Table zTbl */
|
|
/* Locate and if necessary initialize the target table object */
|
|
(*Tsqlite3_session)(unsafe.Pointer(pSession)).FbAutoAttach = (*Tsqlite3_session)(unsafe.Pointer(pSession)).FbAutoAttach + 1
|
|
rc = _sessionFindTable(tls, pSession, zTbl, bp+16)
|
|
(*Tsqlite3_session)(unsafe.Pointer(pSession)).FbAutoAttach = (*Tsqlite3_session)(unsafe.Pointer(pSession)).FbAutoAttach - 1
|
|
if **(**uintptr)(__ccgo_up(bp + 16)) == uintptr(0) {
|
|
goto diff_out
|
|
}
|
|
if _sessionInitTable(tls, pSession, **(**uintptr)(__ccgo_up(bp + 16)), (*Tsqlite3_session)(unsafe.Pointer(pSession)).Fdb, (*Tsqlite3_session)(unsafe.Pointer(pSession)).FzDb) != 0 {
|
|
rc = (*Tsqlite3_session)(unsafe.Pointer(pSession)).Frc
|
|
goto diff_out
|
|
}
|
|
/* Check the table schemas match */
|
|
if rc == SQLITE_OK {
|
|
bHasPk = 0
|
|
bMismatch = 0
|
|
**(**int32)(__ccgo_up(bp + 24)) = 0 /* Columns in zFrom.zTbl */
|
|
**(**int32)(__ccgo_up(bp + 28)) = 0
|
|
**(**uintptr)(__ccgo_up(bp + 32)) = uintptr(0)
|
|
**(**uintptr)(__ccgo_up(bp + 40)) = uintptr(0)
|
|
zDbExists = uintptr(0)
|
|
/* Check that database zFrom is attached. */
|
|
zDbExists = Xsqlite3_mprintf(tls, __ccgo_ts+35631, libc.VaList(bp+64, zFrom))
|
|
if zDbExists == uintptr(0) {
|
|
rc = int32(SQLITE_NOMEM)
|
|
} else {
|
|
**(**uintptr)(__ccgo_up(bp + 48)) = uintptr(0)
|
|
rc = Xsqlite3_prepare_v2(tls, db, zDbExists, -int32(1), bp+48, uintptr(0))
|
|
if rc == int32(SQLITE_ERROR) {
|
|
rc = SQLITE_OK
|
|
**(**int32)(__ccgo_up(bp + 24)) = -int32(1)
|
|
}
|
|
Xsqlite3_finalize(tls, **(**uintptr)(__ccgo_up(bp + 48)))
|
|
Xsqlite3_free(tls, zDbExists)
|
|
}
|
|
if rc == SQLITE_OK && **(**int32)(__ccgo_up(bp + 24)) == 0 {
|
|
if (*Tsqlite3_session)(unsafe.Pointer(pSession)).FbImplicitPK != 0 {
|
|
v1 = bp + 28
|
|
} else {
|
|
v1 = uintptr(0)
|
|
}
|
|
rc = _sessionTableInfo(tls, uintptr(0), db, zFrom, zTbl, bp+24, uintptr(0), uintptr(0), bp+40, uintptr(0), uintptr(0), bp+32, v1)
|
|
}
|
|
if rc == SQLITE_OK {
|
|
if (*TSessionTable)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 16)))).FnCol != **(**int32)(__ccgo_up(bp + 24)) {
|
|
if **(**int32)(__ccgo_up(bp + 24)) <= 0 {
|
|
rc = int32(SQLITE_SCHEMA)
|
|
if pzErrMsg != 0 {
|
|
**(**uintptr)(__ccgo_up(pzErrMsg)) = Xsqlite3_mprintf(tls, __ccgo_ts+35662, libc.VaList(bp+64, zFrom, zTbl))
|
|
}
|
|
} else {
|
|
bMismatch = int32(1)
|
|
}
|
|
} else {
|
|
i = 0
|
|
for {
|
|
if !(i < **(**int32)(__ccgo_up(bp + 24))) {
|
|
break
|
|
}
|
|
if libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TSessionTable)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 16)))).FabPK + uintptr(i)))) != libc.Int32FromUint8(**(**Tu8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp + 32)) + uintptr(i)))) {
|
|
bMismatch = int32(1)
|
|
}
|
|
if Xsqlite3_stricmp(tls, **(**uintptr)(__ccgo_up(**(**uintptr)(__ccgo_up(bp + 40)) + uintptr(i)*8)), **(**uintptr)(__ccgo_up((*TSessionTable)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 16)))).FazCol + uintptr(i)*8))) != 0 {
|
|
bMismatch = int32(1)
|
|
}
|
|
if **(**Tu8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp + 32)) + uintptr(i))) != 0 {
|
|
bHasPk = int32(1)
|
|
}
|
|
goto _2
|
|
_2:
|
|
;
|
|
i = i + 1
|
|
}
|
|
}
|
|
}
|
|
Xsqlite3_free(tls, **(**uintptr)(__ccgo_up(bp + 40)))
|
|
if bMismatch != 0 {
|
|
if pzErrMsg != 0 {
|
|
**(**uintptr)(__ccgo_up(pzErrMsg)) = Xsqlite3_mprintf(tls, __ccgo_ts+35683, 0)
|
|
}
|
|
rc = int32(SQLITE_SCHEMA)
|
|
}
|
|
if bHasPk == 0 {
|
|
/* Ignore tables with no primary keys */
|
|
goto diff_out
|
|
}
|
|
}
|
|
if rc == SQLITE_OK {
|
|
zExpr = _sessionExprComparePK(tls, (*TSessionTable)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 16)))).FnCol, zDb, zFrom, (*TSessionTable)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 16)))).FzName, (*TSessionTable)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 16)))).FazCol, (*TSessionTable)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 16)))).FabPK)
|
|
}
|
|
/* Find new rows */
|
|
if rc == SQLITE_OK {
|
|
rc = _sessionDiffFindNew(tls, int32(SQLITE_INSERT), pSession, **(**uintptr)(__ccgo_up(bp + 16)), zDb, zFrom, zExpr)
|
|
}
|
|
/* Find old rows */
|
|
if rc == SQLITE_OK {
|
|
rc = _sessionDiffFindNew(tls, int32(SQLITE_DELETE), pSession, **(**uintptr)(__ccgo_up(bp + 16)), zFrom, zDb, zExpr)
|
|
}
|
|
/* Find modified rows */
|
|
if rc == SQLITE_OK {
|
|
rc = _sessionDiffFindModified(tls, pSession, **(**uintptr)(__ccgo_up(bp + 16)), zFrom, zExpr)
|
|
}
|
|
Xsqlite3_free(tls, zExpr)
|
|
}
|
|
goto diff_out
|
|
diff_out:
|
|
;
|
|
_sessionPreupdateHooks(tls, pSession)
|
|
Xsqlite3_mutex_leave(tls, Xsqlite3_db_mutex(tls, (*Tsqlite3_session)(unsafe.Pointer(pSession)).Fdb))
|
|
return rc
|
|
}
|
|
|
|
const __INT_FAST16_MAX__ = 9223372036854775807
|
|
|
|
const __INT_FAST16_WIDTH__ = 64
|
|
|
|
const __INT_FAST32_MAX__ = 9223372036854775807
|
|
|
|
const __INT_FAST32_WIDTH__ = 64
|
|
|
|
const __UINT_FAST16_MAX__ = 18446744073709551615
|
|
|
|
const __UINT_FAST32_MAX__ = 18446744073709551615
|
|
|
|
/*
|
|
** The following array holds FuncDef structures for all of the functions
|
|
** defined in this file.
|
|
**
|
|
** The array cannot be constant since changes are made to the
|
|
** FuncDef.pHash elements at start-time. The elements of this array
|
|
** are read-only after initialization is complete.
|
|
**
|
|
** For peak efficiency, put the most frequently used function last.
|
|
*/
|
|
var _aBuiltinFunc = [106]TFuncDef{
|
|
0: {
|
|
FnArg: int16(2),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(SQLITE_FUNC_INTERNAL) | libc.Int32FromInt32(SQLITE_FUNC_TEST) | libc.Int32FromInt32(SQLITE_FUNC_INLINE) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(0)),
|
|
FpUserData: uintptr(int64(libc.Int32FromInt32(INLINEFUNC_implies_nonnull_row))),
|
|
FzName: __ccgo_ts + 16638,
|
|
},
|
|
1: {
|
|
FnArg: int16(2),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(SQLITE_FUNC_INTERNAL) | libc.Int32FromInt32(SQLITE_FUNC_TEST) | libc.Int32FromInt32(SQLITE_FUNC_INLINE) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(0)),
|
|
FpUserData: uintptr(int64(libc.Int32FromInt32(INLINEFUNC_expr_compare))),
|
|
FzName: __ccgo_ts + 16658,
|
|
},
|
|
2: {
|
|
FnArg: int16(2),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(SQLITE_FUNC_INTERNAL) | libc.Int32FromInt32(SQLITE_FUNC_TEST) | libc.Int32FromInt32(SQLITE_FUNC_INLINE) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(0)),
|
|
FpUserData: uintptr(int64(libc.Int32FromInt32(INLINEFUNC_expr_implies_expr))),
|
|
FzName: __ccgo_ts + 16671,
|
|
},
|
|
3: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(SQLITE_FUNC_INTERNAL) | libc.Int32FromInt32(SQLITE_FUNC_TEST) | libc.Int32FromInt32(SQLITE_FUNC_INLINE) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(0)),
|
|
FpUserData: uintptr(int64(libc.Int32FromInt32(INLINEFUNC_affinity))),
|
|
FzName: __ccgo_ts + 16689,
|
|
},
|
|
4: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FzName: __ccgo_ts + 16698,
|
|
},
|
|
5: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(SQLITE_DIRECTONLY) | libc.Int32FromInt32(SQLITE_FUNC_UNSAFE)),
|
|
FzName: __ccgo_ts + 16706,
|
|
},
|
|
6: {
|
|
FnArg: int16(2),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(SQLITE_DIRECTONLY) | libc.Int32FromInt32(SQLITE_FUNC_UNSAFE)),
|
|
FzName: __ccgo_ts + 16706,
|
|
},
|
|
7: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_SLOCHNG) | libc.Int32FromInt32(SQLITE_UTF8)),
|
|
FzName: __ccgo_ts + 16721,
|
|
},
|
|
8: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_SLOCHNG) | libc.Int32FromInt32(SQLITE_UTF8)),
|
|
FzName: __ccgo_ts + 16747,
|
|
},
|
|
9: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(SQLITE_FUNC_INLINE) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_FUNC_UNLIKELY)),
|
|
FpUserData: uintptr(int64(libc.Int32FromInt32(INLINEFUNC_unlikely))),
|
|
FzName: __ccgo_ts + 16772,
|
|
},
|
|
10: {
|
|
FnArg: int16(2),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(SQLITE_FUNC_INLINE) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_FUNC_UNLIKELY)),
|
|
FpUserData: uintptr(int64(libc.Int32FromInt32(INLINEFUNC_unlikely))),
|
|
FzName: __ccgo_ts + 16781,
|
|
},
|
|
11: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(SQLITE_FUNC_INLINE) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_FUNC_UNLIKELY)),
|
|
FpUserData: uintptr(int64(libc.Int32FromInt32(INLINEFUNC_unlikely))),
|
|
FzName: __ccgo_ts + 16792,
|
|
},
|
|
12: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(SQLITE_FUNC_INLINE) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(0)),
|
|
FpUserData: uintptr(int64(libc.Int32FromInt32(INLINEFUNC_sqlite_offset))),
|
|
FzName: __ccgo_ts + 16799,
|
|
},
|
|
13: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FpUserData: uintptr(int64(libc.Int32FromInt32(1))),
|
|
FzName: __ccgo_ts + 16813,
|
|
},
|
|
14: {
|
|
FnArg: int16(2),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FpUserData: uintptr(int64(libc.Int32FromInt32(1))),
|
|
FzName: __ccgo_ts + 16813,
|
|
},
|
|
15: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FpUserData: uintptr(int64(libc.Int32FromInt32(2))),
|
|
FzName: __ccgo_ts + 16819,
|
|
},
|
|
16: {
|
|
FnArg: int16(2),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FpUserData: uintptr(int64(libc.Int32FromInt32(2))),
|
|
FzName: __ccgo_ts + 16819,
|
|
},
|
|
17: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FpUserData: uintptr(int64(libc.Int32FromInt32(3))),
|
|
FzName: __ccgo_ts + 16825,
|
|
},
|
|
18: {
|
|
FnArg: int16(2),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FpUserData: uintptr(int64(libc.Int32FromInt32(3))),
|
|
FzName: __ccgo_ts + 16825,
|
|
},
|
|
19: {
|
|
FnArg: int16(-int32(3)),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FzName: __ccgo_ts + 16830,
|
|
},
|
|
20: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL) | libc.Int32FromInt32(SQLITE_FUNC_MINMAX) | libc.Int32FromInt32(SQLITE_FUNC_ANYORDER)),
|
|
FzName: __ccgo_ts + 16830,
|
|
},
|
|
21: {
|
|
FnArg: int16(-int32(3)),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FpUserData: uintptr(int64(libc.Int32FromInt32(1))),
|
|
FzName: __ccgo_ts + 16834,
|
|
},
|
|
22: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL) | libc.Int32FromInt32(SQLITE_FUNC_MINMAX) | libc.Int32FromInt32(SQLITE_FUNC_ANYORDER)),
|
|
FpUserData: uintptr(int64(libc.Int32FromInt32(1))),
|
|
FzName: __ccgo_ts + 16834,
|
|
},
|
|
23: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL) | libc.Int32FromInt32(SQLITE_FUNC_TYPEOF)),
|
|
FzName: __ccgo_ts + 16838,
|
|
},
|
|
24: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL) | libc.Int32FromInt32(SQLITE_FUNC_TYPEOF) | libc.Int32FromInt32(SQLITE_SUBTYPE)),
|
|
FzName: __ccgo_ts + 16845,
|
|
},
|
|
25: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL) | libc.Int32FromInt32(SQLITE_FUNC_LENGTH)),
|
|
FzName: __ccgo_ts + 16853,
|
|
},
|
|
26: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL) | libc.Int32FromInt32(SQLITE_FUNC_BYTELEN)),
|
|
FzName: __ccgo_ts + 16860,
|
|
},
|
|
27: {
|
|
FnArg: int16(2),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FzName: __ccgo_ts + 16873,
|
|
},
|
|
28: {
|
|
FnArg: int16(-int32(1)),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FzName: __ccgo_ts + 16879,
|
|
},
|
|
29: {
|
|
FnArg: int16(-int32(1)),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FzName: __ccgo_ts + 16886,
|
|
},
|
|
30: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FzName: __ccgo_ts + 16893,
|
|
},
|
|
31: {
|
|
FnArg: int16(-int32(1)),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FzName: __ccgo_ts + 16901,
|
|
},
|
|
32: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FzName: __ccgo_ts + 16906,
|
|
},
|
|
33: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FzName: __ccgo_ts + 16910,
|
|
},
|
|
34: {
|
|
FnArg: int16(2),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FzName: __ccgo_ts + 16910,
|
|
},
|
|
35: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FzName: __ccgo_ts + 16916,
|
|
},
|
|
36: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FzName: __ccgo_ts + 16922,
|
|
},
|
|
37: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FzName: __ccgo_ts + 16928,
|
|
},
|
|
38: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FzName: __ccgo_ts + 16932,
|
|
},
|
|
39: {
|
|
FnArg: int16(2),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FzName: __ccgo_ts + 16932,
|
|
},
|
|
40: {
|
|
FnArg: int16(-int32(3)),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FzName: __ccgo_ts + 16938,
|
|
},
|
|
41: {
|
|
FnArg: int16(-int32(4)),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FzName: __ccgo_ts + 16945,
|
|
},
|
|
42: {
|
|
FnArg: int16(2),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(SQLITE_FUNC_INLINE) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(0)),
|
|
FzName: __ccgo_ts + 16955,
|
|
},
|
|
43: {
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FzName: __ccgo_ts + 16962,
|
|
},
|
|
44: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FzName: __ccgo_ts + 16969,
|
|
},
|
|
45: {
|
|
FnArg: int16(2),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FzName: __ccgo_ts + 16980,
|
|
},
|
|
46: {
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_SLOCHNG) | libc.Int32FromInt32(SQLITE_UTF8)),
|
|
FzName: __ccgo_ts + 16987,
|
|
},
|
|
47: {
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_SLOCHNG) | libc.Int32FromInt32(SQLITE_UTF8)),
|
|
FzName: __ccgo_ts + 17002,
|
|
},
|
|
48: {
|
|
FnArg: int16(2),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FzName: __ccgo_ts + 17019,
|
|
},
|
|
49: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FzName: __ccgo_ts + 17030,
|
|
},
|
|
50: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FzName: __ccgo_ts + 17037,
|
|
},
|
|
51: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FpUserData: uintptr(int64(libc.Int32FromInt32(1))),
|
|
FzName: __ccgo_ts + 17043,
|
|
},
|
|
52: {
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FzName: __ccgo_ts + 17056,
|
|
},
|
|
53: {
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FzName: __ccgo_ts + 17074,
|
|
},
|
|
54: {
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FzName: __ccgo_ts + 17082,
|
|
},
|
|
55: {
|
|
FnArg: int16(3),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FzName: __ccgo_ts + 17096,
|
|
},
|
|
56: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FzName: __ccgo_ts + 17104,
|
|
},
|
|
57: {
|
|
FnArg: int16(2),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FzName: __ccgo_ts + 17113,
|
|
},
|
|
58: {
|
|
FnArg: int16(3),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FzName: __ccgo_ts + 17113,
|
|
},
|
|
59: {
|
|
FnArg: int16(2),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FzName: __ccgo_ts + 17120,
|
|
},
|
|
60: {
|
|
FnArg: int16(3),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FzName: __ccgo_ts + 17120,
|
|
},
|
|
61: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL) | libc.Int32FromInt32(0)),
|
|
FzName: __ccgo_ts + 17130,
|
|
},
|
|
62: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL) | libc.Int32FromInt32(0)),
|
|
FzName: __ccgo_ts + 17134,
|
|
},
|
|
63: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL) | libc.Int32FromInt32(0)),
|
|
FzName: __ccgo_ts + 17140,
|
|
},
|
|
64: {
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL) | libc.Int32FromInt32(SQLITE_FUNC_COUNT) | libc.Int32FromInt32(SQLITE_FUNC_ANYORDER)),
|
|
FzName: __ccgo_ts + 17144,
|
|
},
|
|
65: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL) | libc.Int32FromInt32(SQLITE_FUNC_ANYORDER)),
|
|
FzName: __ccgo_ts + 17144,
|
|
},
|
|
66: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL) | libc.Int32FromInt32(0)),
|
|
FzName: __ccgo_ts + 17150,
|
|
},
|
|
67: {
|
|
FnArg: int16(2),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL) | libc.Int32FromInt32(0)),
|
|
FzName: __ccgo_ts + 17150,
|
|
},
|
|
68: {
|
|
FnArg: int16(2),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL) | libc.Int32FromInt32(0)),
|
|
FzName: __ccgo_ts + 17163,
|
|
},
|
|
69: {
|
|
FnArg: int16(2),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(SQLITE_FUNC_LIKE) | libc.Int32FromInt32(SQLITE_FUNC_CASE)),
|
|
FpUserData: uintptr(unsafe.Pointer(&_globInfo)),
|
|
FzName: __ccgo_ts + 17174,
|
|
},
|
|
70: {
|
|
FnArg: int16(2),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(SQLITE_FUNC_LIKE)),
|
|
FpUserData: uintptr(unsafe.Pointer(&_likeInfoNorm)),
|
|
FzName: __ccgo_ts + 16633,
|
|
},
|
|
71: {
|
|
FnArg: int16(3),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(SQLITE_FUNC_LIKE)),
|
|
FpUserData: uintptr(unsafe.Pointer(&_likeInfoNorm)),
|
|
FzName: __ccgo_ts + 16633,
|
|
},
|
|
72: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8)),
|
|
FzName: __ccgo_ts + 17179,
|
|
},
|
|
73: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8)),
|
|
FzName: __ccgo_ts + 1277,
|
|
},
|
|
74: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8)),
|
|
FzName: __ccgo_ts + 1285,
|
|
},
|
|
75: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8)),
|
|
FzName: __ccgo_ts + 17184,
|
|
},
|
|
76: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FzName: __ccgo_ts + 17190,
|
|
},
|
|
77: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FpUserData: uintptr(int64(libc.Int32FromInt32(1))),
|
|
FzName: __ccgo_ts + 17193,
|
|
},
|
|
78: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FpUserData: uintptr(int64(libc.Int32FromInt32(1))),
|
|
FzName: __ccgo_ts + 17197,
|
|
},
|
|
79: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FpUserData: uintptr(int64(libc.Int32FromInt32(2))),
|
|
FzName: __ccgo_ts + 17203,
|
|
},
|
|
80: {
|
|
FnArg: int16(2),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FzName: __ccgo_ts + 17193,
|
|
},
|
|
81: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8)),
|
|
FzName: __ccgo_ts + 17208,
|
|
},
|
|
82: {
|
|
FnArg: int16(2),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8)),
|
|
FzName: __ccgo_ts + 17212,
|
|
},
|
|
83: {
|
|
FnArg: int16(2),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8)),
|
|
FzName: __ccgo_ts + 17216,
|
|
},
|
|
84: {
|
|
FnArg: int16(2),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8)),
|
|
FzName: __ccgo_ts + 17222,
|
|
},
|
|
85: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8)),
|
|
FzName: __ccgo_ts + 17226,
|
|
},
|
|
86: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8)),
|
|
FzName: __ccgo_ts + 17231,
|
|
},
|
|
87: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8)),
|
|
FzName: __ccgo_ts + 17236,
|
|
},
|
|
88: {
|
|
FnArg: int16(2),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8)),
|
|
FzName: __ccgo_ts + 17241,
|
|
},
|
|
89: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8)),
|
|
FzName: __ccgo_ts + 17247,
|
|
},
|
|
90: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8)),
|
|
FzName: __ccgo_ts + 17251,
|
|
},
|
|
91: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8)),
|
|
FzName: __ccgo_ts + 17255,
|
|
},
|
|
92: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8)),
|
|
FzName: __ccgo_ts + 17259,
|
|
},
|
|
93: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8)),
|
|
FzName: __ccgo_ts + 17264,
|
|
},
|
|
94: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8)),
|
|
FzName: __ccgo_ts + 17269,
|
|
},
|
|
95: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8)),
|
|
FzName: __ccgo_ts + 17274,
|
|
},
|
|
96: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8)),
|
|
FzName: __ccgo_ts + 17280,
|
|
},
|
|
97: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8)),
|
|
FzName: __ccgo_ts + 17286,
|
|
},
|
|
98: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8)),
|
|
FzName: __ccgo_ts + 17292,
|
|
},
|
|
99: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8)),
|
|
FzName: __ccgo_ts + 17297,
|
|
},
|
|
100: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8)),
|
|
FzName: __ccgo_ts + 17305,
|
|
},
|
|
101: {
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8)),
|
|
FzName: __ccgo_ts + 17313,
|
|
},
|
|
102: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)),
|
|
FzName: __ccgo_ts + 17316,
|
|
},
|
|
103: {
|
|
FnArg: int16(-int32(4)),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(SQLITE_FUNC_INLINE) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(0)),
|
|
FzName: __ccgo_ts + 6989,
|
|
},
|
|
104: {
|
|
FnArg: int16(-int32(4)),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(SQLITE_FUNC_INLINE) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(0)),
|
|
FpUserData: uintptr(int64(libc.Int32FromInt32(INLINEFUNC_iif))),
|
|
FzName: __ccgo_ts + 17321,
|
|
},
|
|
105: {
|
|
FnArg: int16(-int32(4)),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(SQLITE_FUNC_INLINE) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(0)),
|
|
FpUserData: uintptr(int64(libc.Int32FromInt32(INLINEFUNC_iif))),
|
|
FzName: __ccgo_ts + 17325,
|
|
},
|
|
}
|
|
|
|
var _aJsonFunc = [36]TFuncDef{
|
|
0: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_DETERMINISTIC) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_FUNC_RUNONLY) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_SUBTYPE) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_RESULT_SUBTYPE)),
|
|
FzName: __ccgo_ts + 13722,
|
|
},
|
|
1: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_DETERMINISTIC) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_FUNC_RUNONLY) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_SUBTYPE) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_RESULT_SUBTYPE)),
|
|
FpUserData: uintptr(int64(libc.Int32FromInt32(0) | libc.Int32FromInt32(1)*libc.Int32FromInt32(JSON_BLOB))),
|
|
FzName: __ccgo_ts + 26992,
|
|
},
|
|
2: {
|
|
FnArg: int16(-int32(1)),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_DETERMINISTIC) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_RUNONLY) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_SUBTYPE) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_RESULT_SUBTYPE)),
|
|
FzName: __ccgo_ts + 26998,
|
|
},
|
|
3: {
|
|
FnArg: int16(-int32(1)),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_DETERMINISTIC) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_RUNONLY) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_SUBTYPE) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_RESULT_SUBTYPE)),
|
|
FpUserData: uintptr(int64(libc.Int32FromInt32(0) | libc.Int32FromInt32(1)*libc.Int32FromInt32(JSON_BLOB))),
|
|
FzName: __ccgo_ts + 27009,
|
|
},
|
|
4: {
|
|
FnArg: int16(-int32(1)),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_DETERMINISTIC) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_FUNC_RUNONLY) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_SUBTYPE) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_RESULT_SUBTYPE)),
|
|
FpUserData: uintptr(int64(libc.Int32FromInt32(JSON_AINS) | libc.Int32FromInt32(0)*libc.Int32FromInt32(JSON_BLOB))),
|
|
FzName: __ccgo_ts + 27021,
|
|
},
|
|
5: {
|
|
FnArg: int16(-int32(1)),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_DETERMINISTIC) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_FUNC_RUNONLY) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_SUBTYPE) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_RESULT_SUBTYPE)),
|
|
FpUserData: uintptr(int64(libc.Int32FromInt32(JSON_AINS) | libc.Int32FromInt32(1)*libc.Int32FromInt32(JSON_BLOB))),
|
|
FzName: __ccgo_ts + 27039,
|
|
},
|
|
6: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_DETERMINISTIC) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_FUNC_RUNONLY) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_SUBTYPE) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_RESULT_SUBTYPE)),
|
|
FzName: __ccgo_ts + 27058,
|
|
},
|
|
7: {
|
|
FnArg: int16(2),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_DETERMINISTIC) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_FUNC_RUNONLY) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_SUBTYPE) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_RESULT_SUBTYPE)),
|
|
FzName: __ccgo_ts + 27058,
|
|
},
|
|
8: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_DETERMINISTIC) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_FUNC_RUNONLY) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_SUBTYPE) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_RESULT_SUBTYPE)),
|
|
FzName: __ccgo_ts + 27076,
|
|
},
|
|
9: {
|
|
FnArg: int16(-int32(1)),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_DETERMINISTIC) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_FUNC_RUNONLY) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_SUBTYPE) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_RESULT_SUBTYPE)),
|
|
FzName: __ccgo_ts + 27096,
|
|
},
|
|
10: {
|
|
FnArg: int16(-int32(1)),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_DETERMINISTIC) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_FUNC_RUNONLY) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_SUBTYPE) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_RESULT_SUBTYPE)),
|
|
FpUserData: uintptr(int64(libc.Int32FromInt32(0) | libc.Int32FromInt32(1)*libc.Int32FromInt32(JSON_BLOB))),
|
|
FzName: __ccgo_ts + 27109,
|
|
},
|
|
11: {
|
|
FnArg: int16(2),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_DETERMINISTIC) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_FUNC_RUNONLY) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_SUBTYPE) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_RESULT_SUBTYPE)),
|
|
FpUserData: uintptr(int64(libc.Int32FromInt32(JSON_JSON) | libc.Int32FromInt32(0)*libc.Int32FromInt32(JSON_BLOB))),
|
|
FzName: __ccgo_ts + 27123,
|
|
},
|
|
12: {
|
|
FnArg: int16(2),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_DETERMINISTIC) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_FUNC_RUNONLY) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_SUBTYPE) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_RESULT_SUBTYPE)),
|
|
FpUserData: uintptr(int64(libc.Int32FromInt32(JSON_SQL) | libc.Int32FromInt32(0)*libc.Int32FromInt32(JSON_BLOB))),
|
|
FzName: __ccgo_ts + 27126,
|
|
},
|
|
13: {
|
|
FnArg: int16(-int32(1)),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_DETERMINISTIC) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_FUNC_RUNONLY) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_SUBTYPE) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_RESULT_SUBTYPE)),
|
|
FzName: __ccgo_ts + 27130,
|
|
},
|
|
14: {
|
|
FnArg: int16(-int32(1)),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_DETERMINISTIC) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_FUNC_RUNONLY) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_SUBTYPE) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_RESULT_SUBTYPE)),
|
|
FpUserData: uintptr(int64(libc.Int32FromInt32(0) | libc.Int32FromInt32(1)*libc.Int32FromInt32(JSON_BLOB))),
|
|
FzName: __ccgo_ts + 27142,
|
|
},
|
|
15: {
|
|
FnArg: int16(-int32(1)),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_DETERMINISTIC) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_RUNONLY) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_SUBTYPE) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_RESULT_SUBTYPE)),
|
|
FzName: __ccgo_ts + 27155,
|
|
},
|
|
16: {
|
|
FnArg: int16(-int32(1)),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_DETERMINISTIC) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_RUNONLY) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_SUBTYPE) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_RESULT_SUBTYPE)),
|
|
FpUserData: uintptr(int64(libc.Int32FromInt32(0) | libc.Int32FromInt32(1)*libc.Int32FromInt32(JSON_BLOB))),
|
|
FzName: __ccgo_ts + 27167,
|
|
},
|
|
17: {
|
|
FnArg: int16(2),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_DETERMINISTIC) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_FUNC_RUNONLY) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_SUBTYPE) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_RESULT_SUBTYPE)),
|
|
FzName: __ccgo_ts + 27180,
|
|
},
|
|
18: {
|
|
FnArg: int16(2),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_DETERMINISTIC) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_FUNC_RUNONLY) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_SUBTYPE) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_RESULT_SUBTYPE)),
|
|
FpUserData: uintptr(int64(libc.Int32FromInt32(0) | libc.Int32FromInt32(1)*libc.Int32FromInt32(JSON_BLOB))),
|
|
FzName: __ccgo_ts + 27191,
|
|
},
|
|
19: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_DETERMINISTIC) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_FUNC_RUNONLY) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_SUBTYPE) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_RESULT_SUBTYPE)),
|
|
FzName: __ccgo_ts + 27203,
|
|
},
|
|
20: {
|
|
FnArg: int16(2),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_DETERMINISTIC) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_FUNC_RUNONLY) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_SUBTYPE) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_RESULT_SUBTYPE)),
|
|
FzName: __ccgo_ts + 27203,
|
|
},
|
|
21: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_DETERMINISTIC) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_RUNONLY) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_SUBTYPE) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_RESULT_SUBTYPE)),
|
|
FzName: __ccgo_ts + 27215,
|
|
},
|
|
22: {
|
|
FnArg: int16(-int32(1)),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_DETERMINISTIC) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_FUNC_RUNONLY) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_SUBTYPE) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_RESULT_SUBTYPE)),
|
|
FzName: __ccgo_ts + 27226,
|
|
},
|
|
23: {
|
|
FnArg: int16(-int32(1)),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_DETERMINISTIC) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_FUNC_RUNONLY) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_SUBTYPE) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_RESULT_SUBTYPE)),
|
|
FpUserData: uintptr(int64(libc.Int32FromInt32(0) | libc.Int32FromInt32(1)*libc.Int32FromInt32(JSON_BLOB))),
|
|
FzName: __ccgo_ts + 27238,
|
|
},
|
|
24: {
|
|
FnArg: int16(-int32(1)),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_DETERMINISTIC) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_FUNC_RUNONLY) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_SUBTYPE) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_RESULT_SUBTYPE)),
|
|
FzName: __ccgo_ts + 27251,
|
|
},
|
|
25: {
|
|
FnArg: int16(-int32(1)),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_DETERMINISTIC) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_FUNC_RUNONLY) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_SUBTYPE) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_RESULT_SUBTYPE)),
|
|
FpUserData: uintptr(int64(libc.Int32FromInt32(0) | libc.Int32FromInt32(1)*libc.Int32FromInt32(JSON_BLOB))),
|
|
FzName: __ccgo_ts + 27264,
|
|
},
|
|
26: {
|
|
FnArg: int16(-int32(1)),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_DETERMINISTIC) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_FUNC_RUNONLY) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_SUBTYPE) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_RESULT_SUBTYPE)),
|
|
FpUserData: uintptr(int64(libc.Int32FromInt32(JSON_ISSET) | libc.Int32FromInt32(0)*libc.Int32FromInt32(JSON_BLOB))),
|
|
FzName: __ccgo_ts + 27278,
|
|
},
|
|
27: {
|
|
FnArg: int16(-int32(1)),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_DETERMINISTIC) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_FUNC_RUNONLY) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_SUBTYPE) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_RESULT_SUBTYPE)),
|
|
FpUserData: uintptr(int64(libc.Int32FromInt32(JSON_ISSET) | libc.Int32FromInt32(1)*libc.Int32FromInt32(JSON_BLOB))),
|
|
FzName: __ccgo_ts + 27287,
|
|
},
|
|
28: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_DETERMINISTIC) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_FUNC_RUNONLY) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_SUBTYPE) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_RESULT_SUBTYPE)),
|
|
FzName: __ccgo_ts + 27297,
|
|
},
|
|
29: {
|
|
FnArg: int16(2),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_DETERMINISTIC) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_FUNC_RUNONLY) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_SUBTYPE) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_RESULT_SUBTYPE)),
|
|
FzName: __ccgo_ts + 27297,
|
|
},
|
|
30: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_DETERMINISTIC) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_FUNC_RUNONLY) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_SUBTYPE) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_RESULT_SUBTYPE)),
|
|
FzName: __ccgo_ts + 27307,
|
|
},
|
|
31: {
|
|
FnArg: int16(2),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_DETERMINISTIC) | libc.Int32FromInt32(SQLITE_FUNC_CONSTANT) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(1)*libc.Int32FromInt32(SQLITE_FUNC_RUNONLY) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_SUBTYPE) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_RESULT_SUBTYPE)),
|
|
FzName: __ccgo_ts + 27307,
|
|
},
|
|
32: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL) | libc.Int32FromInt32(SQLITE_SUBTYPE) | libc.Int32FromInt32(SQLITE_RESULT_SUBTYPE) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(SQLITE_DETERMINISTIC)),
|
|
FzName: __ccgo_ts + 27318,
|
|
},
|
|
33: {
|
|
FnArg: int16(1),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL) | libc.Int32FromInt32(SQLITE_SUBTYPE) | libc.Int32FromInt32(SQLITE_RESULT_SUBTYPE) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(SQLITE_DETERMINISTIC)),
|
|
FpUserData: uintptr(int64(libc.Int32FromInt32(JSON_BLOB))),
|
|
FzName: __ccgo_ts + 27335,
|
|
},
|
|
34: {
|
|
FnArg: int16(2),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL) | libc.Int32FromInt32(SQLITE_SUBTYPE) | libc.Int32FromInt32(SQLITE_RESULT_SUBTYPE) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(SQLITE_DETERMINISTIC)),
|
|
FzName: __ccgo_ts + 27353,
|
|
},
|
|
35: {
|
|
FnArg: int16(2),
|
|
FfuncFlags: libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_BUILTIN) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(0)*libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL) | libc.Int32FromInt32(SQLITE_SUBTYPE) | libc.Int32FromInt32(SQLITE_RESULT_SUBTYPE) | libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(SQLITE_DETERMINISTIC)),
|
|
FpUserData: uintptr(int64(libc.Int32FromInt32(JSON_BLOB))),
|
|
FzName: __ccgo_ts + 27371,
|
|
},
|
|
}
|
|
|
|
/*
|
|
** All default VFSes for unix are contained in the following array.
|
|
**
|
|
** Note that the sqlite3_vfs.pNext field of the VFS object is modified
|
|
** by the SQLite core when the VFS is registered. So the following
|
|
** array cannot be const.
|
|
*/
|
|
var _aVfs = [4]Tsqlite3_vfs{
|
|
0: {
|
|
FiVersion: int32(3),
|
|
FszOsFile: int32(120),
|
|
FmxPathname: int32(MAX_PATHNAME),
|
|
FzName: __ccgo_ts + 4112,
|
|
},
|
|
1: {
|
|
FiVersion: int32(3),
|
|
FszOsFile: int32(120),
|
|
FmxPathname: int32(MAX_PATHNAME),
|
|
FzName: __ccgo_ts + 4117,
|
|
},
|
|
2: {
|
|
FiVersion: int32(3),
|
|
FszOsFile: int32(120),
|
|
FmxPathname: int32(MAX_PATHNAME),
|
|
FzName: __ccgo_ts + 4127,
|
|
},
|
|
3: {
|
|
FiVersion: int32(3),
|
|
FszOsFile: int32(120),
|
|
FmxPathname: int32(MAX_PATHNAME),
|
|
FzName: __ccgo_ts + 4007,
|
|
},
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Internal SQL function:
|
|
// **
|
|
// ** sqlite_add_constraint(SQL, CONSTRAINT-TEXT, ICOL)
|
|
// **
|
|
// ** SQL is a CREATE TABLE statement. Return a modified version of
|
|
// ** SQL that adds CONSTRAINT-TEXT at the end of the ICOL-th column
|
|
// ** definition. (The left-most column defintion is 0.)
|
|
// */
|
|
func _addConstraintFunc(tls *libc.TLS, ctx uintptr, NotUsed int32, argv uintptr) {
|
|
bp := tls.Alloc(48)
|
|
defer tls.Free(48)
|
|
var db, zCons, zNew, zSql uintptr
|
|
var iCol, ii, nTok int32
|
|
var _ /* iOff at bp+0 */ int32
|
|
var _ /* t at bp+4 */ int32
|
|
_, _, _, _, _, _, _ = db, iCol, ii, nTok, zCons, zNew, zSql
|
|
zSql = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv)))
|
|
zCons = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv + 1*8)))
|
|
iCol = Xsqlite3_value_int(tls, **(**uintptr)(__ccgo_up(argv + 2*8)))
|
|
**(**int32)(__ccgo_up(bp)) = 0
|
|
zNew = uintptr(0)
|
|
**(**int32)(__ccgo_up(bp + 4)) = 0
|
|
_ = NotUsed
|
|
if _skipCreateTable(tls, ctx, zSql, bp) != 0 {
|
|
return
|
|
}
|
|
ii = 0
|
|
for {
|
|
if !(ii <= iCol || iCol < 0 && **(**int32)(__ccgo_up(bp + 4)) != int32(TK_RP)) {
|
|
break
|
|
}
|
|
**(**int32)(__ccgo_up(bp)) = **(**int32)(__ccgo_up(bp)) + _getConstraintToken(tls, zSql+uintptr(**(**int32)(__ccgo_up(bp))), bp+4)
|
|
for int32(1) != 0 {
|
|
nTok = _getConstraintToken(tls, zSql+uintptr(**(**int32)(__ccgo_up(bp))), bp+4)
|
|
if **(**int32)(__ccgo_up(bp + 4)) == int32(TK_COMMA) || **(**int32)(__ccgo_up(bp + 4)) == int32(TK_RP) {
|
|
break
|
|
}
|
|
if **(**int32)(__ccgo_up(bp + 4)) == int32(TK_ILLEGAL) {
|
|
Xsqlite3_result_error_code(tls, ctx, _sqlite3CorruptError(tls, int32(123384)))
|
|
return
|
|
}
|
|
**(**int32)(__ccgo_up(bp)) = **(**int32)(__ccgo_up(bp)) + nTok
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
ii = ii + 1
|
|
}
|
|
**(**int32)(__ccgo_up(bp)) = **(**int32)(__ccgo_up(bp)) + _getWhitespace(tls, zSql+uintptr(**(**int32)(__ccgo_up(bp))))
|
|
db = Xsqlite3_context_db_handle(tls, ctx)
|
|
if iCol < 0 {
|
|
zNew = _sqlite3MPrintf(tls, db, __ccgo_ts+11913, libc.VaList(bp+16, **(**int32)(__ccgo_up(bp)), zSql, zCons, zSql+uintptr(**(**int32)(__ccgo_up(bp)))))
|
|
} else {
|
|
zNew = _sqlite3MPrintf(tls, db, __ccgo_ts+11924, libc.VaList(bp+16, **(**int32)(__ccgo_up(bp)), zSql, zCons, zSql+uintptr(**(**int32)(__ccgo_up(bp)))))
|
|
}
|
|
Xsqlite3_result_text(tls, ctx, zNew, -int32(1), __ccgo_fp(_sqlite3RowSetClear))
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Add a new module argument to pTable->u.vtab.azArg[].
|
|
// ** The string is not copied - the pointer is stored. The
|
|
// ** string will be freed automatically when the table is
|
|
// ** deleted.
|
|
// */
|
|
func _addModuleArgument(tls *libc.TLS, pParse uintptr, pTable uintptr, zArg uintptr) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var azModuleArg, db, v2 uintptr
|
|
var i, v1 int32
|
|
var nBytes Tsqlite3_int64
|
|
_, _, _, _, _, _ = azModuleArg, db, i, nBytes, v1, v2
|
|
db = (*TParse)(unsafe.Pointer(pParse)).Fdb
|
|
nBytes = libc.Int64FromUint64(uint64(8) * libc.Uint64FromInt32(libc.Int32FromInt32(2)+(*(*struct {
|
|
FnArg int32
|
|
FazArg uintptr
|
|
Fp uintptr
|
|
})(unsafe.Pointer(pTable + 64))).FnArg))
|
|
if (*(*struct {
|
|
FnArg int32
|
|
FazArg uintptr
|
|
Fp uintptr
|
|
})(unsafe.Pointer(pTable + 64))).FnArg+int32(3) >= **(**int32)(__ccgo_up(db + 136 + 2*4)) {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+13984, libc.VaList(bp+8, (*TTable)(unsafe.Pointer(pTable)).FzName))
|
|
}
|
|
azModuleArg = _sqlite3DbRealloc(tls, db, (*(*struct {
|
|
FnArg int32
|
|
FazArg uintptr
|
|
Fp uintptr
|
|
})(unsafe.Pointer(pTable + 64))).FazArg, libc.Uint64FromInt64(nBytes))
|
|
if azModuleArg == uintptr(0) {
|
|
_sqlite3DbFree(tls, db, zArg)
|
|
} else {
|
|
v2 = pTable + 64
|
|
v1 = *(*int32)(unsafe.Pointer(v2))
|
|
*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1
|
|
i = v1
|
|
**(**uintptr)(__ccgo_up(azModuleArg + uintptr(i)*8)) = zArg
|
|
**(**uintptr)(__ccgo_up(azModuleArg + uintptr(i+int32(1))*8)) = uintptr(0)
|
|
(*(*struct {
|
|
FnArg int32
|
|
FazArg uintptr
|
|
Fp uintptr
|
|
})(unsafe.Pointer(pTable + 64))).FazArg = azModuleArg
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Find a column named pCol in table pTab. If successful, set output
|
|
// ** parameter *piCol to the index of the column in the table and return
|
|
// ** SQLITE_OK. Otherwise, set *piCol to -1 and return an SQLite error
|
|
// ** code.
|
|
// */
|
|
func _alterFindCol(tls *libc.TLS, pParse uintptr, pTab uintptr, pCol uintptr, piCol uintptr) (r int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var db, zCol, zDb, zName uintptr
|
|
var iCol, rc int32
|
|
_, _, _, _, _, _ = db, iCol, rc, zCol, zDb, zName
|
|
db = (*TParse)(unsafe.Pointer(pParse)).Fdb
|
|
zName = _sqlite3NameFromToken(tls, db, pCol)
|
|
rc = int32(SQLITE_NOMEM)
|
|
iCol = -int32(1)
|
|
if zName != 0 {
|
|
iCol = _sqlite3ColumnIndex(tls, pTab, zName)
|
|
if iCol < 0 {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+11934, libc.VaList(bp+8, zName))
|
|
rc = int32(SQLITE_ERROR)
|
|
} else {
|
|
rc = SQLITE_OK
|
|
}
|
|
}
|
|
if rc == SQLITE_OK {
|
|
zDb = (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(_sqlite3SchemaToIndex(tls, db, (*TTable)(unsafe.Pointer(pTab)).FpSchema))*32))).FzDbSName
|
|
zCol = (**(**TColumn)(__ccgo_up((*TTable)(unsafe.Pointer(pTab)).FaCol + uintptr(iCol)*16))).FzCnName
|
|
if _sqlite3AuthCheck(tls, pParse, int32(SQLITE_ALTER_TABLE), zDb, (*TTable)(unsafe.Pointer(pTab)).FzName, zCol) != 0 {
|
|
pTab = uintptr(0)
|
|
}
|
|
}
|
|
_sqlite3DbFree(tls, db, zName)
|
|
**(**int32)(__ccgo_up(piCol)) = iCol
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This is the xExprCallback for a tree walker. It is used to
|
|
// ** implement sqlite3ExprAnalyzeAggregates(). See sqlite3ExprAnalyzeAggregates
|
|
// ** for additional information.
|
|
// */
|
|
func _analyzeAggregate(tls *libc.TLS, pWalker uintptr, pExpr uintptr) (r int32) {
|
|
bp := tls.Alloc(96)
|
|
defer tls.Free(96)
|
|
var enc Tu8
|
|
var i, iDataCur, mxTerm, nArg, v5 int32
|
|
var pAggInfo, pIEpr, pItem, pItem1, pNC, pOBList, pParse, pSrcList, v7 uintptr
|
|
var _ /* tmp at bp+0 */ TExpr
|
|
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = enc, i, iDataCur, mxTerm, nArg, pAggInfo, pIEpr, pItem, pItem1, pNC, pOBList, pParse, pSrcList, v5, v7
|
|
pNC = *(*uintptr)(unsafe.Pointer(pWalker + 40))
|
|
pParse = (*TNameContext)(unsafe.Pointer(pNC)).FpParse
|
|
pSrcList = (*TNameContext)(unsafe.Pointer(pNC)).FpSrcList
|
|
pAggInfo = *(*uintptr)(unsafe.Pointer(pNC + 16))
|
|
switch libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) {
|
|
default:
|
|
if (*TNameContext)(unsafe.Pointer(pNC)).FncFlags&int32(NC_InAggFunc) == 0 {
|
|
break
|
|
}
|
|
if (*TParse)(unsafe.Pointer(pParse)).FpIdxEpr == uintptr(0) {
|
|
break
|
|
}
|
|
pIEpr = (*TParse)(unsafe.Pointer(pParse)).FpIdxEpr
|
|
for {
|
|
if !(pIEpr != 0) {
|
|
break
|
|
}
|
|
iDataCur = (*TIndexedExpr)(unsafe.Pointer(pIEpr)).FiDataCur
|
|
if iDataCur < 0 {
|
|
goto _1
|
|
}
|
|
if _sqlite3ExprCompare(tls, uintptr(0), pExpr, (*TIndexedExpr)(unsafe.Pointer(pIEpr)).FpExpr, iDataCur) == 0 {
|
|
break
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
pIEpr = (*TIndexedExpr)(unsafe.Pointer(pIEpr)).FpIENext
|
|
}
|
|
if pIEpr == uintptr(0) {
|
|
break
|
|
}
|
|
if !((*TExpr)(unsafe.Pointer(pExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_WinFunc)|libc.Int32FromInt32(EP_Subrtn)) == libc.Uint32FromInt32(0)) {
|
|
break
|
|
}
|
|
i = 0
|
|
for {
|
|
if !(i < (*TSrcList)(unsafe.Pointer(pSrcList)).FnSrc) {
|
|
break
|
|
}
|
|
if (*(*TSrcItem)(unsafe.Pointer(pSrcList + 8 + uintptr(i)*80))).FiCursor == (*TIndexedExpr)(unsafe.Pointer(pIEpr)).FiDataCur {
|
|
break
|
|
}
|
|
goto _2
|
|
_2:
|
|
;
|
|
i = i + 1
|
|
}
|
|
if i >= (*TSrcList)(unsafe.Pointer(pSrcList)).FnSrc {
|
|
break
|
|
}
|
|
if (*TExpr)(unsafe.Pointer(pExpr)).FpAggInfo != uintptr(0) {
|
|
break
|
|
} /* Resolved by outer context */
|
|
if (*TParse)(unsafe.Pointer(pParse)).FnErr != 0 {
|
|
return int32(WRC_Abort)
|
|
}
|
|
/* If we reach this point, it means that expression pExpr can be
|
|
** translated into a reference to an index column as described by
|
|
** pIEpr.
|
|
*/
|
|
libc.Xmemset(tls, bp, 0, uint64(72))
|
|
(**(**TExpr)(__ccgo_up(bp))).Fop = uint8(TK_AGG_COLUMN)
|
|
(**(**TExpr)(__ccgo_up(bp))).FiTable = (*TIndexedExpr)(unsafe.Pointer(pIEpr)).FiIdxCur
|
|
(**(**TExpr)(__ccgo_up(bp))).FiColumn = int16((*TIndexedExpr)(unsafe.Pointer(pIEpr)).FiIdxCol)
|
|
_findOrCreateAggInfoColumn(tls, pParse, pAggInfo, bp)
|
|
if (*TParse)(unsafe.Pointer(pParse)).FnErr != 0 {
|
|
return int32(WRC_Abort)
|
|
}
|
|
(**(**TAggInfo_col)(__ccgo_up((*TAggInfo)(unsafe.Pointer(pAggInfo)).FaCol + uintptr((**(**TExpr)(__ccgo_up(bp))).FiAgg)*32))).FpCExpr = pExpr
|
|
(*TExpr)(unsafe.Pointer(pExpr)).FpAggInfo = pAggInfo
|
|
(*TExpr)(unsafe.Pointer(pExpr)).FiAgg = (**(**TExpr)(__ccgo_up(bp))).FiAgg
|
|
return int32(WRC_Prune)
|
|
case int32(TK_IF_NULL_ROW):
|
|
fallthrough
|
|
case int32(TK_AGG_COLUMN):
|
|
fallthrough
|
|
case int32(TK_COLUMN):
|
|
/* Check to see if the column is in one of the tables in the FROM
|
|
** clause of the aggregate query */
|
|
if pSrcList != uintptr(0) {
|
|
pItem = pSrcList + 8
|
|
i = 0
|
|
for {
|
|
if !(i < (*TSrcList)(unsafe.Pointer(pSrcList)).FnSrc) {
|
|
break
|
|
}
|
|
if (*TExpr)(unsafe.Pointer(pExpr)).FiTable == (*TSrcItem)(unsafe.Pointer(pItem)).FiCursor {
|
|
_findOrCreateAggInfoColumn(tls, pParse, pAggInfo, pExpr)
|
|
break
|
|
} /* endif pExpr->iTable==pItem->iCursor */
|
|
goto _3
|
|
_3:
|
|
;
|
|
i = i + 1
|
|
pItem += 80
|
|
} /* end loop over pSrcList */
|
|
}
|
|
return WRC_Continue
|
|
case int32(TK_AGG_FUNCTION):
|
|
if (*TNameContext)(unsafe.Pointer(pNC)).FncFlags&int32(NC_InAggFunc) == 0 && (*TWalker)(unsafe.Pointer(pWalker)).FwalkerDepth == libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop2) && (*TExpr)(unsafe.Pointer(pExpr)).FpAggInfo == uintptr(0) {
|
|
/* Check to see if pExpr is a duplicate of another aggregate
|
|
** function that is already in the pAggInfo structure
|
|
*/
|
|
pItem1 = (*TAggInfo)(unsafe.Pointer(pAggInfo)).FaFunc
|
|
mxTerm = **(**int32)(__ccgo_up((*TParse)(unsafe.Pointer(pParse)).Fdb + 136 + 2*4))
|
|
i = 0
|
|
for {
|
|
if !(i < (*TAggInfo)(unsafe.Pointer(pAggInfo)).FnFunc) {
|
|
break
|
|
}
|
|
if (*TAggInfo_func)(unsafe.Pointer(pItem1)).FpFExpr == pExpr {
|
|
break
|
|
}
|
|
if _sqlite3ExprCompare(tls, uintptr(0), (*TAggInfo_func)(unsafe.Pointer(pItem1)).FpFExpr, pExpr, -int32(1)) == 0 {
|
|
break
|
|
}
|
|
goto _4
|
|
_4:
|
|
;
|
|
i = i + 1
|
|
pItem1 += 32
|
|
}
|
|
if i > mxTerm {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+8642, libc.VaList(bp+80, mxTerm))
|
|
i = mxTerm
|
|
} else {
|
|
if i >= (*TAggInfo)(unsafe.Pointer(pAggInfo)).FnFunc {
|
|
/* pExpr is original. Make a new entry in pAggInfo->aFunc[]
|
|
*/
|
|
enc = (*Tsqlite3)(unsafe.Pointer((*TParse)(unsafe.Pointer(pParse)).Fdb)).Fenc
|
|
i = _addAggInfoFunc(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, pAggInfo)
|
|
if i >= 0 {
|
|
pItem1 = (*TAggInfo)(unsafe.Pointer(pAggInfo)).FaFunc + uintptr(i)*32
|
|
(*TAggInfo_func)(unsafe.Pointer(pItem1)).FpFExpr = pExpr
|
|
if *(*uintptr)(unsafe.Pointer(pExpr + 32)) != 0 {
|
|
v5 = (*TExprList)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pExpr + 32)))).FnExpr
|
|
} else {
|
|
v5 = 0
|
|
}
|
|
nArg = v5
|
|
(*TAggInfo_func)(unsafe.Pointer(pItem1)).FpFunc = _sqlite3FindFunction(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, *(*uintptr)(unsafe.Pointer(pExpr + 8)), nArg, enc, uint8(0))
|
|
if (*TExpr)(unsafe.Pointer(pExpr)).FpLeft != 0 && (*TFuncDef)(unsafe.Pointer((*TAggInfo_func)(unsafe.Pointer(pItem1)).FpFunc)).FfuncFlags&uint32(SQLITE_FUNC_NEEDCOLL) == uint32(0) {
|
|
v7 = pParse + 56
|
|
v5 = *(*int32)(unsafe.Pointer(v7))
|
|
*(*int32)(unsafe.Pointer(v7)) = *(*int32)(unsafe.Pointer(v7)) + 1
|
|
(*TAggInfo_func)(unsafe.Pointer(pItem1)).FiOBTab = v5
|
|
pOBList = *(*uintptr)(unsafe.Pointer((*TExpr)(unsafe.Pointer(pExpr)).FpLeft + 32))
|
|
if (*TExprList)(unsafe.Pointer(pOBList)).FnExpr == int32(1) && nArg == int32(1) && _sqlite3ExprCompare(tls, uintptr(0), (*(*TExprList_item)(unsafe.Pointer(pOBList + 8))).FpExpr, (*(*TExprList_item)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pExpr + 32)) + 8))).FpExpr, 0) == 0 {
|
|
(*TAggInfo_func)(unsafe.Pointer(pItem1)).FbOBPayload = uint8(0)
|
|
(*TAggInfo_func)(unsafe.Pointer(pItem1)).FbOBUnique = libc.BoolUint8((*TExpr)(unsafe.Pointer(pExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_Distinct)) != libc.Uint32FromInt32(0))
|
|
} else {
|
|
(*TAggInfo_func)(unsafe.Pointer(pItem1)).FbOBPayload = uint8(1)
|
|
}
|
|
(*TAggInfo_func)(unsafe.Pointer(pItem1)).FbUseSubtype = libc.BoolUint8((*TFuncDef)(unsafe.Pointer((*TAggInfo_func)(unsafe.Pointer(pItem1)).FpFunc)).FfuncFlags&uint32(SQLITE_SUBTYPE) != uint32(0))
|
|
} else {
|
|
(*TAggInfo_func)(unsafe.Pointer(pItem1)).FiOBTab = -int32(1)
|
|
}
|
|
if (*TExpr)(unsafe.Pointer(pExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_Distinct)) != uint32(0) && !((*TAggInfo_func)(unsafe.Pointer(pItem1)).FbOBUnique != 0) {
|
|
v7 = pParse + 56
|
|
v5 = *(*int32)(unsafe.Pointer(v7))
|
|
*(*int32)(unsafe.Pointer(v7)) = *(*int32)(unsafe.Pointer(v7)) + 1
|
|
(*TAggInfo_func)(unsafe.Pointer(pItem1)).FiDistinct = v5
|
|
} else {
|
|
(*TAggInfo_func)(unsafe.Pointer(pItem1)).FiDistinct = -int32(1)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/* Make pExpr point to the appropriate pAggInfo->aFunc[] entry
|
|
*/
|
|
(*TExpr)(unsafe.Pointer(pExpr)).FiAgg = int16(i)
|
|
(*TExpr)(unsafe.Pointer(pExpr)).FpAggInfo = pAggInfo
|
|
return int32(WRC_Prune)
|
|
} else {
|
|
return WRC_Continue
|
|
}
|
|
}
|
|
return WRC_Continue
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Generate code that will do an analysis of a single table in
|
|
// ** a database. If pOnlyIdx is not NULL then it is a single index
|
|
// ** in pTab that should be analyzed.
|
|
// */
|
|
func _analyzeTable(tls *libc.TLS, pParse uintptr, pTab uintptr, pOnlyIdx uintptr) {
|
|
var iDb, iStatCur int32
|
|
_, _ = iDb, iStatCur
|
|
iDb = _sqlite3SchemaToIndex(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, (*TTable)(unsafe.Pointer(pTab)).FpSchema)
|
|
_sqlite3BeginWriteOperation(tls, pParse, 0, iDb)
|
|
iStatCur = (*TParse)(unsafe.Pointer(pParse)).FnTab
|
|
**(**int32)(__ccgo_up(pParse + 56)) += int32(3)
|
|
if pOnlyIdx != 0 {
|
|
_openStatTable(tls, pParse, iDb, iStatCur, (*TIndex)(unsafe.Pointer(pOnlyIdx)).FzName, __ccgo_ts+13072)
|
|
} else {
|
|
_openStatTable(tls, pParse, iDb, iStatCur, (*TTable)(unsafe.Pointer(pTab)).FzName, __ccgo_ts+13076)
|
|
}
|
|
_analyzeOneTable(tls, pParse, pTab, pOnlyIdx, iStatCur, (*TParse)(unsafe.Pointer(pParse)).FnMem+int32(1), (*TParse)(unsafe.Pointer(pParse)).FnTab)
|
|
_loadAnalysis(tls, pParse, iDb)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This function is used by both blob_open() and blob_reopen(). It seeks
|
|
// ** the b-tree cursor associated with blob handle p to point to row iRow.
|
|
// ** If successful, SQLITE_OK is returned and subsequent calls to
|
|
// ** sqlite3_blob_read() or sqlite3_blob_write() access the specified row.
|
|
// **
|
|
// ** If an error occurs, or if the specified row does not exist or does not
|
|
// ** contain a value of type TEXT or BLOB in the column nominated when the
|
|
// ** blob handle was opened, then an error code is returned and *pzErr may
|
|
// ** be set to point to a buffer containing an error message. It is the
|
|
// ** responsibility of the caller to free the error message buffer using
|
|
// ** sqlite3DbFree().
|
|
// **
|
|
// ** If an error does occur, then the b-tree cursor is closed. All subsequent
|
|
// ** calls to sqlite3_blob_read(), blob_write() or blob_reopen() will
|
|
// ** immediately return SQLITE_ABORT.
|
|
// */
|
|
func _blobSeekToRow(tls *libc.TLS, p uintptr, iRow Tsqlite3_int64, pzErr uintptr) (r int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var pC, v, zErr, v2, v3 uintptr
|
|
var rc int32
|
|
var type1 Tu32
|
|
var v1 uint32
|
|
_, _, _, _, _, _, _, _ = pC, rc, type1, v, zErr, v1, v2, v3 /* Error code */
|
|
zErr = uintptr(0) /* Error message */
|
|
v = (*TIncrblob)(unsafe.Pointer(p)).FpStmt
|
|
/* Set the value of register r[1] in the SQL statement to integer iRow.
|
|
** This is done directly as a performance optimization
|
|
*/
|
|
_sqlite3VdbeMemSetInt64(tls, (*TVdbe)(unsafe.Pointer(v)).FaMem+1*56, iRow)
|
|
/* If the statement has been run before (and is paused at the OP_ResultRow)
|
|
** then back it up to the point where it does the OP_NotExists. This could
|
|
** have been down with an extra OP_Goto, but simply setting the program
|
|
** counter is faster. */
|
|
if (*TVdbe)(unsafe.Pointer(v)).Fpc > int32(4) {
|
|
(*TVdbe)(unsafe.Pointer(v)).Fpc = int32(4)
|
|
rc = _sqlite3VdbeExec(tls, v)
|
|
} else {
|
|
rc = Xsqlite3_step(tls, (*TIncrblob)(unsafe.Pointer(p)).FpStmt)
|
|
}
|
|
if rc == int32(SQLITE_ROW) {
|
|
pC = **(**uintptr)(__ccgo_up((*TVdbe)(unsafe.Pointer(v)).FapCsr))
|
|
if libc.Int32FromUint16((*TVdbeCursor)(unsafe.Pointer(pC)).FnHdrParsed) > libc.Int32FromUint16((*TIncrblob)(unsafe.Pointer(p)).FiCol) {
|
|
v1 = *(*Tu32)(unsafe.Pointer(pC + 120 + uintptr((*TIncrblob)(unsafe.Pointer(p)).FiCol)*4))
|
|
} else {
|
|
v1 = uint32(0)
|
|
}
|
|
type1 = v1
|
|
if type1 < uint32(12) {
|
|
if type1 == uint32(0) {
|
|
v2 = __ccgo_ts + 1690
|
|
} else {
|
|
if type1 == uint32(7) {
|
|
v3 = __ccgo_ts + 6515
|
|
} else {
|
|
v3 = __ccgo_ts + 6520
|
|
}
|
|
v2 = v3
|
|
}
|
|
zErr = _sqlite3MPrintf(tls, (*TIncrblob)(unsafe.Pointer(p)).Fdb, __ccgo_ts+6528, libc.VaList(bp+8, v2))
|
|
rc = int32(SQLITE_ERROR)
|
|
Xsqlite3_finalize(tls, (*TIncrblob)(unsafe.Pointer(p)).FpStmt)
|
|
(*TIncrblob)(unsafe.Pointer(p)).FpStmt = uintptr(0)
|
|
} else {
|
|
(*TIncrblob)(unsafe.Pointer(p)).FiOffset = libc.Int32FromUint32(*(*Tu32)(unsafe.Pointer(pC + 120 + uintptr(libc.Int32FromUint16((*TIncrblob)(unsafe.Pointer(p)).FiCol)+int32((*TVdbeCursor)(unsafe.Pointer(pC)).FnField))*4)))
|
|
(*TIncrblob)(unsafe.Pointer(p)).FnByte = libc.Int32FromUint32(_sqlite3VdbeSerialTypeLen(tls, type1))
|
|
(*TIncrblob)(unsafe.Pointer(p)).FpCsr = *(*uintptr)(unsafe.Pointer(pC + 48))
|
|
_sqlite3BtreeIncrblobCursor(tls, (*TIncrblob)(unsafe.Pointer(p)).FpCsr)
|
|
}
|
|
}
|
|
if rc == int32(SQLITE_ROW) {
|
|
rc = SQLITE_OK
|
|
} else {
|
|
if (*TIncrblob)(unsafe.Pointer(p)).FpStmt != 0 {
|
|
rc = Xsqlite3_finalize(tls, (*TIncrblob)(unsafe.Pointer(p)).FpStmt)
|
|
(*TIncrblob)(unsafe.Pointer(p)).FpStmt = uintptr(0)
|
|
if rc == SQLITE_OK {
|
|
zErr = _sqlite3MPrintf(tls, (*TIncrblob)(unsafe.Pointer(p)).Fdb, __ccgo_ts+6557, libc.VaList(bp+8, iRow))
|
|
rc = int32(SQLITE_ERROR)
|
|
} else {
|
|
zErr = _sqlite3MPrintf(tls, (*TIncrblob)(unsafe.Pointer(p)).Fdb, __ccgo_ts+3968, libc.VaList(bp+8, Xsqlite3_errmsg(tls, (*TIncrblob)(unsafe.Pointer(p)).Fdb)))
|
|
}
|
|
}
|
|
}
|
|
**(**uintptr)(__ccgo_up(pzErr)) = zErr
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Append a message to the error message string.
|
|
// */
|
|
func _checkAppendMsg(tls *libc.TLS, pCheck uintptr, zFormat uintptr, va uintptr) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var ap Tva_list
|
|
_ = ap
|
|
_checkProgress(tls, pCheck)
|
|
if !((*TIntegrityCk)(unsafe.Pointer(pCheck)).FmxErr != 0) {
|
|
return
|
|
}
|
|
(*TIntegrityCk)(unsafe.Pointer(pCheck)).FmxErr = (*TIntegrityCk)(unsafe.Pointer(pCheck)).FmxErr - 1
|
|
(*TIntegrityCk)(unsafe.Pointer(pCheck)).FnErr = (*TIntegrityCk)(unsafe.Pointer(pCheck)).FnErr + 1
|
|
ap = va
|
|
if (*TIntegrityCk)(unsafe.Pointer(pCheck)).FerrMsg.FnChar != 0 {
|
|
Xsqlite3_str_append(tls, pCheck+72, __ccgo_ts+4380, int32(1))
|
|
}
|
|
if (*TIntegrityCk)(unsafe.Pointer(pCheck)).FzPfx != 0 {
|
|
Xsqlite3_str_appendf(tls, pCheck+72, (*TIntegrityCk)(unsafe.Pointer(pCheck)).FzPfx, libc.VaList(bp+8, (*TIntegrityCk)(unsafe.Pointer(pCheck)).Fv0, (*TIntegrityCk)(unsafe.Pointer(pCheck)).Fv1, (*TIntegrityCk)(unsafe.Pointer(pCheck)).Fv2))
|
|
}
|
|
Xsqlite3_str_vappendf(tls, pCheck+72, zFormat, ap)
|
|
_ = ap
|
|
if libc.Int32FromUint8((*TIntegrityCk)(unsafe.Pointer(pCheck)).FerrMsg.FaccError) == int32(SQLITE_NOMEM) {
|
|
_checkOom(tls, pCheck)
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Generate an instruction that will put the integer describe by
|
|
// ** text z[0..n-1] into register iMem.
|
|
// **
|
|
// ** Expr.u.zToken is always UTF8 and zero-terminated.
|
|
// */
|
|
func _codeInteger(tls *libc.TLS, pParse uintptr, pExpr uintptr, negFlag int32, iMem int32) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var c, i int32
|
|
var v, z, v1 uintptr
|
|
var v2 int64
|
|
var _ /* value at bp+0 */ Ti64
|
|
_, _, _, _, _, _ = c, i, v, z, v1, v2
|
|
v = (*TParse)(unsafe.Pointer(pParse)).FpVdbe
|
|
if (*TExpr)(unsafe.Pointer(pExpr)).Fflags&uint32(EP_IntValue) != 0 {
|
|
i = *(*int32)(unsafe.Pointer(&(*TExpr)(unsafe.Pointer(pExpr)).Fu))
|
|
if negFlag != 0 {
|
|
i = -i
|
|
}
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_Integer), i, iMem)
|
|
} else {
|
|
z = *(*uintptr)(unsafe.Pointer(pExpr + 8))
|
|
c = _sqlite3DecOrHexToI64(tls, z, bp)
|
|
if c == int32(3) && !(negFlag != 0) || c == int32(2) || negFlag != 0 && **(**Ti64)(__ccgo_up(bp)) == int64(-libc.Int32FromInt32(1))-(libc.Int64FromUint32(0xffffffff)|libc.Int64FromInt32(0x7fffffff)<<libc.Int32FromInt32(32)) {
|
|
if Xsqlite3_strnicmp(tls, z, __ccgo_ts+8450, int32(2)) == 0 {
|
|
if negFlag != 0 {
|
|
v1 = __ccgo_ts + 5253
|
|
} else {
|
|
v1 = __ccgo_ts + 1704
|
|
}
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+8453, libc.VaList(bp+16, v1, pExpr))
|
|
} else {
|
|
_codeReal(tls, v, z, negFlag, iMem)
|
|
}
|
|
} else {
|
|
if negFlag != 0 {
|
|
if c == int32(3) {
|
|
v2 = int64(-libc.Int32FromInt32(1)) - (libc.Int64FromUint32(0xffffffff) | libc.Int64FromInt32(0x7fffffff)<<libc.Int32FromInt32(32))
|
|
} else {
|
|
v2 = -**(**Ti64)(__ccgo_up(bp))
|
|
}
|
|
**(**Ti64)(__ccgo_up(bp)) = v2
|
|
}
|
|
_sqlite3VdbeAddOp4Dup8(tls, v, int32(OP_Int64), 0, iMem, 0, bp, -int32(14))
|
|
}
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Create and populate a new TriggerPrg object with a sub-program
|
|
// ** implementing trigger pTrigger with ON CONFLICT policy orconf.
|
|
// */
|
|
func _codeRowTrigger(tls *libc.TLS, pParse uintptr, pTrigger uintptr, pTab uintptr, orconf int32) (r uintptr) {
|
|
bp := tls.Alloc(496)
|
|
defer tls.Free(496)
|
|
var db, pPrg, pProgram, pTop, pWhen, v, v2 uintptr
|
|
var iEndTrigger, nDepth int32
|
|
var _ /* sNC at bp+0 */ TNameContext
|
|
var _ /* sSubParse at bp+56 */ TParse
|
|
_, _, _, _, _, _, _, _, _ = db, iEndTrigger, nDepth, pPrg, pProgram, pTop, pWhen, v, v2 /* Top level Parse object */
|
|
db = (*TParse)(unsafe.Pointer(pParse)).Fdb /* Value to return */
|
|
pWhen = uintptr(0) /* Name context for sub-vdbe */
|
|
pProgram = uintptr(0) /* Sub-vdbe for trigger program */
|
|
iEndTrigger = 0 /* Trigger depth */
|
|
/* Ensure that triggers are not chained too deep. This test is linear
|
|
** in the chaining depth, but sensible code ought not be chaining
|
|
** triggers excessively, so that shouldn't be a problem.
|
|
*/
|
|
pTop = pParse
|
|
nDepth = 0
|
|
for {
|
|
if !((*TParse)(unsafe.Pointer(pTop)).FpOuterParse != 0) {
|
|
break
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
pTop = (*TParse)(unsafe.Pointer(pTop)).FpOuterParse
|
|
nDepth = nDepth + 1
|
|
}
|
|
if nDepth >= **(**int32)(__ccgo_up(db + 136 + 10*4)) {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+22592, 0)
|
|
return uintptr(0)
|
|
}
|
|
if (*TParse)(unsafe.Pointer(pParse)).FpToplevel != 0 {
|
|
v2 = (*TParse)(unsafe.Pointer(pParse)).FpToplevel
|
|
} else {
|
|
v2 = pParse
|
|
}
|
|
pTop = v2
|
|
/* Allocate the TriggerPrg and SubProgram objects. To ensure that they
|
|
** are freed if an error occurs, link them into the Parse.pTriggerPrg
|
|
** list of the top-level Parse object sooner rather than later. */
|
|
pPrg = _sqlite3DbMallocZero(tls, db, uint64(40))
|
|
if !(pPrg != 0) {
|
|
return uintptr(0)
|
|
}
|
|
(*TTriggerPrg)(unsafe.Pointer(pPrg)).FpNext = (*TParse)(unsafe.Pointer(pTop)).FpTriggerPrg
|
|
(*TParse)(unsafe.Pointer(pTop)).FpTriggerPrg = pPrg
|
|
v2 = _sqlite3DbMallocZero(tls, db, uint64(48))
|
|
pProgram = v2
|
|
(*TTriggerPrg)(unsafe.Pointer(pPrg)).FpProgram = v2
|
|
if !(pProgram != 0) {
|
|
return uintptr(0)
|
|
}
|
|
_sqlite3VdbeLinkSubProgram(tls, (*TParse)(unsafe.Pointer(pTop)).FpVdbe, pProgram)
|
|
(*TTriggerPrg)(unsafe.Pointer(pPrg)).FpTrigger = pTrigger
|
|
(*TTriggerPrg)(unsafe.Pointer(pPrg)).Forconf = orconf
|
|
**(**Tu32)(__ccgo_up(pPrg + 28)) = uint32(0xffffffff)
|
|
**(**Tu32)(__ccgo_up(pPrg + 28 + 1*4)) = uint32(0xffffffff)
|
|
/* Allocate and populate a new Parse context to use for coding the
|
|
** trigger sub-program. */
|
|
_sqlite3ParseObjectInit(tls, bp+56, db)
|
|
libc.Xmemset(tls, bp, 0, uint64(56))
|
|
(**(**TNameContext)(__ccgo_up(bp))).FpParse = bp + 56
|
|
(**(**TParse)(__ccgo_up(bp + 56))).FpTriggerTab = pTab
|
|
(**(**TParse)(__ccgo_up(bp + 56))).FpToplevel = pTop
|
|
(**(**TParse)(__ccgo_up(bp + 56))).FzAuthContext = (*TTrigger)(unsafe.Pointer(pTrigger)).FzName
|
|
(**(**TParse)(__ccgo_up(bp + 56))).FeTriggerOp = (*TTrigger)(unsafe.Pointer(pTrigger)).Fop
|
|
(**(**TParse)(__ccgo_up(bp + 56))).FnQueryLoop = (*TParse)(unsafe.Pointer(pParse)).FnQueryLoop
|
|
(**(**TParse)(__ccgo_up(bp + 56))).FprepFlags = (*TParse)(unsafe.Pointer(pParse)).FprepFlags
|
|
(**(**TParse)(__ccgo_up(bp + 56))).Foldmask = uint32(0)
|
|
(**(**TParse)(__ccgo_up(bp + 56))).Fnewmask = uint32(0)
|
|
v = _sqlite3GetVdbe(tls, bp+56)
|
|
if v != 0 {
|
|
if (*TTrigger)(unsafe.Pointer(pTrigger)).FzName != 0 {
|
|
_sqlite3VdbeChangeP4(tls, v, -int32(1), _sqlite3MPrintf(tls, db, __ccgo_ts+22617, libc.VaList(bp+488, (*TTrigger)(unsafe.Pointer(pTrigger)).FzName)), -int32(7))
|
|
}
|
|
/* If one was specified, code the WHEN clause. If it evaluates to false
|
|
** (or NULL) the sub-vdbe is immediately halted by jumping to the
|
|
** OP_Halt inserted at the end of the program. */
|
|
if (*TTrigger)(unsafe.Pointer(pTrigger)).FpWhen != 0 {
|
|
pWhen = _sqlite3ExprDup(tls, db, (*TTrigger)(unsafe.Pointer(pTrigger)).FpWhen, 0)
|
|
if libc.Int32FromUint8((*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed) == 0 && SQLITE_OK == _sqlite3ResolveExprNames(tls, bp, pWhen) {
|
|
iEndTrigger = _sqlite3VdbeMakeLabel(tls, bp+56)
|
|
_sqlite3ExprIfFalse(tls, bp+56, pWhen, iEndTrigger, int32(SQLITE_JUMPIFNULL))
|
|
}
|
|
_sqlite3ExprDelete(tls, db, pWhen)
|
|
}
|
|
/* Code the trigger program into the sub-vdbe. */
|
|
_codeTriggerProgram(tls, bp+56, (*TTrigger)(unsafe.Pointer(pTrigger)).Fstep_list, orconf)
|
|
/* Insert an OP_Halt at the end of the sub-program. */
|
|
if iEndTrigger != 0 {
|
|
_sqlite3VdbeResolveLabel(tls, v, iEndTrigger)
|
|
}
|
|
_sqlite3VdbeAddOp0(tls, v, int32(OP_Halt))
|
|
_transferParseError(tls, pParse, bp+56)
|
|
if (*TParse)(unsafe.Pointer(pParse)).FnErr == 0 {
|
|
(*TSubProgram)(unsafe.Pointer(pProgram)).FaOp = _sqlite3VdbeTakeOpArray(tls, v, pProgram+8, pTop+128)
|
|
}
|
|
(*TSubProgram)(unsafe.Pointer(pProgram)).FnMem = (**(**TParse)(__ccgo_up(bp + 56))).FnMem
|
|
(*TSubProgram)(unsafe.Pointer(pProgram)).FnCsr = (**(**TParse)(__ccgo_up(bp + 56))).FnTab
|
|
(*TSubProgram)(unsafe.Pointer(pProgram)).Ftoken = pTrigger
|
|
**(**Tu32)(__ccgo_up(pPrg + 28)) = (**(**TParse)(__ccgo_up(bp + 56))).Foldmask
|
|
**(**Tu32)(__ccgo_up(pPrg + 28 + 1*4)) = (**(**TParse)(__ccgo_up(bp + 56))).Fnewmask
|
|
_sqlite3VdbeDelete(tls, v)
|
|
} else {
|
|
_transferParseError(tls, pParse, bp+56)
|
|
}
|
|
_sqlite3ParseObjectReset(tls, bp+56)
|
|
return pPrg
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Generate VDBE code for the statements inside the body of a single
|
|
// ** trigger.
|
|
// */
|
|
func _codeTriggerProgram(tls *libc.TLS, pParse uintptr, pStepList uintptr, orconf int32) (r int32) {
|
|
bp := tls.Alloc(64)
|
|
defer tls.Free(64)
|
|
var db, pSelect, pStep, v uintptr
|
|
var v2 int32
|
|
var _ /* sDest at bp+0 */ TSelectDest
|
|
_, _, _, _, _ = db, pSelect, pStep, v, v2
|
|
v = (*TParse)(unsafe.Pointer(pParse)).FpVdbe
|
|
db = (*TParse)(unsafe.Pointer(pParse)).Fdb
|
|
pStep = pStepList
|
|
for {
|
|
if !(pStep != 0) {
|
|
break
|
|
}
|
|
/* Figure out the ON CONFLICT policy that will be used for this step
|
|
** of the trigger program. If the statement that caused this trigger
|
|
** to fire had an explicit ON CONFLICT, then use it. Otherwise, use
|
|
** the ON CONFLICT policy that was specified as part of the trigger
|
|
** step statement. Example:
|
|
**
|
|
** CREATE TRIGGER AFTER INSERT ON t1 BEGIN;
|
|
** INSERT OR REPLACE INTO t2 VALUES(new.a, new.b);
|
|
** END;
|
|
**
|
|
** INSERT INTO t1 ... ; -- insert into t2 uses REPLACE policy
|
|
** INSERT OR IGNORE INTO t1 ... ; -- insert into t2 uses IGNORE policy
|
|
*/
|
|
if orconf == int32(OE_Default) {
|
|
v2 = libc.Int32FromUint8((*TTriggerStep)(unsafe.Pointer(pStep)).Forconf)
|
|
} else {
|
|
v2 = libc.Int32FromUint8(libc.Uint8FromInt32(orconf))
|
|
}
|
|
(*TParse)(unsafe.Pointer(pParse)).FeOrconf = libc.Uint8FromInt32(v2)
|
|
if (*TTriggerStep)(unsafe.Pointer(pStep)).FzSpan != 0 {
|
|
_sqlite3VdbeAddOp4(tls, v, int32(OP_Trace), int32(0x7fffffff), int32(1), 0, _sqlite3MPrintf(tls, db, __ccgo_ts+6509, libc.VaList(bp+48, (*TTriggerStep)(unsafe.Pointer(pStep)).FzSpan)), -int32(7))
|
|
}
|
|
switch libc.Int32FromUint8((*TTriggerStep)(unsafe.Pointer(pStep)).Fop) {
|
|
case int32(TK_UPDATE):
|
|
_sqlite3Update(tls, pParse, _sqlite3SrcListDup(tls, db, (*TTriggerStep)(unsafe.Pointer(pStep)).FpSrc, 0), _sqlite3ExprListDup(tls, db, (*TTriggerStep)(unsafe.Pointer(pStep)).FpExprList, 0), _sqlite3ExprDup(tls, db, (*TTriggerStep)(unsafe.Pointer(pStep)).FpWhere, 0), libc.Int32FromUint8((*TParse)(unsafe.Pointer(pParse)).FeOrconf), uintptr(0), uintptr(0), uintptr(0))
|
|
_sqlite3VdbeAddOp0(tls, v, int32(OP_ResetCount))
|
|
case int32(TK_INSERT):
|
|
_sqlite3Insert(tls, pParse, _sqlite3SrcListDup(tls, db, (*TTriggerStep)(unsafe.Pointer(pStep)).FpSrc, 0), _sqlite3SelectDup(tls, db, (*TTriggerStep)(unsafe.Pointer(pStep)).FpSelect, 0), _sqlite3IdListDup(tls, db, (*TTriggerStep)(unsafe.Pointer(pStep)).FpIdList), libc.Int32FromUint8((*TParse)(unsafe.Pointer(pParse)).FeOrconf), _sqlite3UpsertDup(tls, db, (*TTriggerStep)(unsafe.Pointer(pStep)).FpUpsert))
|
|
_sqlite3VdbeAddOp0(tls, v, int32(OP_ResetCount))
|
|
case int32(TK_DELETE):
|
|
_sqlite3DeleteFrom(tls, pParse, _sqlite3SrcListDup(tls, db, (*TTriggerStep)(unsafe.Pointer(pStep)).FpSrc, 0), _sqlite3ExprDup(tls, db, (*TTriggerStep)(unsafe.Pointer(pStep)).FpWhere, 0), uintptr(0), uintptr(0))
|
|
_sqlite3VdbeAddOp0(tls, v, int32(OP_ResetCount))
|
|
default:
|
|
pSelect = _sqlite3SelectDup(tls, db, (*TTriggerStep)(unsafe.Pointer(pStep)).FpSelect, 0)
|
|
_sqlite3SelectDestInit(tls, bp, int32(SRT_Discard), 0)
|
|
_sqlite3Select(tls, pParse, pSelect, bp)
|
|
_sqlite3SelectDelete(tls, db, pSelect)
|
|
break
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
pStep = (*TTriggerStep)(unsafe.Pointer(pStep)).FpNext
|
|
}
|
|
return 0
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Expression pExpr is a comparison between two vector values. Compute
|
|
// ** the result of the comparison (1, 0, or NULL) and write that
|
|
// ** result into register dest.
|
|
// **
|
|
// ** The caller must satisfy the following preconditions:
|
|
// **
|
|
// ** if pExpr->op==TK_IS: op==TK_EQ and p5==SQLITE_NULLEQ
|
|
// ** if pExpr->op==TK_ISNOT: op==TK_NE and p5==SQLITE_NULLEQ
|
|
// ** otherwise: op==pExpr->op and p5==0
|
|
// */
|
|
func _codeVectorCompare(tls *libc.TLS, pParse uintptr, pExpr uintptr, dest int32, op Tu8, p5 Tu8) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var addrCmp, addrDone, i, isCommuted, nLeft, r1, r2, regLeft, regRight int32
|
|
var opx Tu8
|
|
var pLeft, pRight, v uintptr
|
|
var _ /* pL at bp+8 */ uintptr
|
|
var _ /* pR at bp+16 */ uintptr
|
|
var _ /* regFree1 at bp+0 */ int32
|
|
var _ /* regFree2 at bp+4 */ int32
|
|
_, _, _, _, _, _, _, _, _, _, _, _, _ = addrCmp, addrDone, i, isCommuted, nLeft, opx, pLeft, pRight, r1, r2, regLeft, regRight, v
|
|
v = (*TParse)(unsafe.Pointer(pParse)).FpVdbe
|
|
pLeft = (*TExpr)(unsafe.Pointer(pExpr)).FpLeft
|
|
pRight = (*TExpr)(unsafe.Pointer(pExpr)).FpRight
|
|
nLeft = _sqlite3ExprVectorSize(tls, pLeft)
|
|
regLeft = 0
|
|
regRight = 0
|
|
opx = op
|
|
addrCmp = 0
|
|
addrDone = _sqlite3VdbeMakeLabel(tls, pParse)
|
|
isCommuted = libc.BoolInt32((*TExpr)(unsafe.Pointer(pExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_Commuted)) != uint32(0))
|
|
if (*TParse)(unsafe.Pointer(pParse)).FnErr != 0 {
|
|
return
|
|
}
|
|
if nLeft != _sqlite3ExprVectorSize(tls, pRight) {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+6936, 0)
|
|
return
|
|
}
|
|
if libc.Int32FromUint8(op) == int32(TK_LE) {
|
|
opx = uint8(TK_LT)
|
|
}
|
|
if libc.Int32FromUint8(op) == int32(TK_GE) {
|
|
opx = uint8(TK_GT)
|
|
}
|
|
if libc.Int32FromUint8(op) == int32(TK_NE) {
|
|
opx = uint8(TK_EQ)
|
|
}
|
|
regLeft = _exprCodeSubselect(tls, pParse, pLeft)
|
|
regRight = _exprCodeSubselect(tls, pParse, pRight)
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_Integer), int32(1), dest)
|
|
i = 0
|
|
for {
|
|
if !(int32(1) != 0) {
|
|
break
|
|
}
|
|
**(**int32)(__ccgo_up(bp)) = 0
|
|
**(**int32)(__ccgo_up(bp + 4)) = 0
|
|
**(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0)
|
|
**(**uintptr)(__ccgo_up(bp + 16)) = uintptr(0)
|
|
if addrCmp != 0 {
|
|
_sqlite3VdbeJumpHere(tls, v, addrCmp)
|
|
}
|
|
r1 = _exprVectorRegister(tls, pParse, pLeft, i, regLeft, bp+8, bp)
|
|
r2 = _exprVectorRegister(tls, pParse, pRight, i, regRight, bp+16, bp+4)
|
|
addrCmp = _sqlite3VdbeCurrentAddr(tls, v)
|
|
_codeCompare(tls, pParse, **(**uintptr)(__ccgo_up(bp + 8)), **(**uintptr)(__ccgo_up(bp + 16)), libc.Int32FromUint8(opx), r1, r2, addrDone, libc.Int32FromUint8(p5), isCommuted)
|
|
_sqlite3ReleaseTempReg(tls, pParse, **(**int32)(__ccgo_up(bp)))
|
|
_sqlite3ReleaseTempReg(tls, pParse, **(**int32)(__ccgo_up(bp + 4)))
|
|
if (libc.Int32FromUint8(opx) == int32(TK_LT) || libc.Int32FromUint8(opx) == int32(TK_GT)) && i < nLeft-int32(1) {
|
|
addrCmp = _sqlite3VdbeAddOp0(tls, v, int32(OP_ElseEq))
|
|
}
|
|
if libc.Int32FromUint8(p5) == int32(SQLITE_NULLEQ) {
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_Integer), 0, dest)
|
|
} else {
|
|
_sqlite3VdbeAddOp3(tls, v, int32(OP_ZeroOrNull), r1, dest, r2)
|
|
}
|
|
if i == nLeft-int32(1) {
|
|
break
|
|
}
|
|
if libc.Int32FromUint8(opx) == int32(TK_EQ) {
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_NotNull), dest, addrDone)
|
|
} else {
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_Goto), 0, addrDone)
|
|
if i == nLeft-int32(2) {
|
|
opx = op
|
|
}
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
_sqlite3VdbeJumpHere(tls, v, addrCmp)
|
|
_sqlite3VdbeResolveLabel(tls, v, addrDone)
|
|
if libc.Int32FromUint8(op) == int32(TK_NE) {
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_Not), dest, dest)
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Connect to or create a dbpagevfs virtual table.
|
|
// */
|
|
func _dbpageConnect(tls *libc.TLS, db uintptr, pAux uintptr, argc int32, argv uintptr, ppVtab uintptr, pzErr uintptr) (r int32) {
|
|
var pTab uintptr
|
|
var rc int32
|
|
_, _ = pTab, rc
|
|
pTab = uintptr(0)
|
|
rc = SQLITE_OK
|
|
_ = pAux
|
|
_ = argc
|
|
_ = argv
|
|
_ = pzErr
|
|
Xsqlite3_vtab_config(tls, db, int32(SQLITE_VTAB_DIRECTONLY), 0)
|
|
Xsqlite3_vtab_config(tls, db, int32(SQLITE_VTAB_USES_ALL_SCHEMAS), 0)
|
|
rc = Xsqlite3_declare_vtab(tls, db, __ccgo_ts+35026)
|
|
if rc == SQLITE_OK {
|
|
pTab = Xsqlite3_malloc64(tls, uint64(40))
|
|
if pTab == uintptr(0) {
|
|
rc = int32(SQLITE_NOMEM)
|
|
}
|
|
}
|
|
if rc == SQLITE_OK {
|
|
libc.Xmemset(tls, pTab, 0, uint64(40))
|
|
(*TDbpageTable)(unsafe.Pointer(pTab)).Fdb = db
|
|
}
|
|
**(**uintptr)(__ccgo_up(ppVtab)) = pTab
|
|
return rc
|
|
}
|
|
|
|
func _dbpageUpdate(tls *libc.TLS, pVtab uintptr, argc int32, argv uintptr, pRowid uintptr) (r int32) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var aPage, pBt, pData, pPager, pTab, zErr, zSchema uintptr
|
|
var iDb, isInsert, rc, szPage, v1 int32
|
|
var pgno TPgno
|
|
var _ /* pDbPage at bp+0 */ uintptr
|
|
_, _, _, _, _, _, _, _, _, _, _, _, _ = aPage, iDb, isInsert, pBt, pData, pPager, pTab, pgno, rc, szPage, zErr, zSchema, v1
|
|
pTab = pVtab
|
|
**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
|
|
rc = SQLITE_OK
|
|
zErr = uintptr(0)
|
|
_ = pRowid
|
|
if (*Tsqlite3)(unsafe.Pointer((*TDbpageTable)(unsafe.Pointer(pTab)).Fdb)).Fflags&uint64(SQLITE_Defensive) != 0 {
|
|
zErr = __ccgo_ts + 35093
|
|
goto update_fail
|
|
}
|
|
if argc == int32(1) {
|
|
zErr = __ccgo_ts + 35103
|
|
goto update_fail
|
|
}
|
|
if Xsqlite3_value_type(tls, **(**uintptr)(__ccgo_up(argv))) == int32(SQLITE_NULL) {
|
|
pgno = libc.Uint32FromInt64(Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(argv + 2*8))))
|
|
isInsert = int32(1)
|
|
} else {
|
|
pgno = libc.Uint32FromInt64(Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(argv))))
|
|
if libc.Uint32FromInt32(Xsqlite3_value_int(tls, **(**uintptr)(__ccgo_up(argv + 1*8)))) != pgno {
|
|
zErr = __ccgo_ts + 35117
|
|
goto update_fail
|
|
}
|
|
isInsert = 0
|
|
}
|
|
if Xsqlite3_value_type(tls, **(**uintptr)(__ccgo_up(argv + 4*8))) == int32(SQLITE_NULL) {
|
|
iDb = 0
|
|
} else {
|
|
zSchema = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv + 4*8)))
|
|
iDb = _sqlite3FindDbName(tls, (*TDbpageTable)(unsafe.Pointer(pTab)).Fdb, zSchema)
|
|
if iDb < 0 {
|
|
zErr = __ccgo_ts + 35131
|
|
goto update_fail
|
|
}
|
|
}
|
|
pBt = (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer((*TDbpageTable)(unsafe.Pointer(pTab)).Fdb)).FaDb + uintptr(iDb)*32))).FpBt
|
|
if pgno < uint32(1) || pBt == uintptr(0) {
|
|
zErr = __ccgo_ts + 35146
|
|
goto update_fail
|
|
}
|
|
szPage = _sqlite3BtreeGetPageSize(tls, pBt)
|
|
if Xsqlite3_value_type(tls, **(**uintptr)(__ccgo_up(argv + 3*8))) != int32(SQLITE_BLOB) || Xsqlite3_value_bytes(tls, **(**uintptr)(__ccgo_up(argv + 3*8))) != szPage {
|
|
if Xsqlite3_value_type(tls, **(**uintptr)(__ccgo_up(argv + 3*8))) == int32(SQLITE_NULL) && isInsert != 0 && pgno > uint32(1) {
|
|
/* "INSERT INTO dbpage($PGNO,NULL)" causes page number $PGNO and
|
|
** all subsequent pages to be deleted. */
|
|
(*TDbpageTable)(unsafe.Pointer(pTab)).FiDbTrunc = iDb
|
|
(*TDbpageTable)(unsafe.Pointer(pTab)).FpgnoTrunc = pgno - uint32(1)
|
|
pgno = uint32(1)
|
|
} else {
|
|
zErr = __ccgo_ts + 35162
|
|
goto update_fail
|
|
}
|
|
}
|
|
if _dbpageBeginTrans(tls, pTab) != SQLITE_OK {
|
|
zErr = __ccgo_ts + 35177
|
|
goto update_fail
|
|
}
|
|
pPager = _sqlite3BtreePager(tls, pBt)
|
|
rc = _sqlite3PagerGet(tls, pPager, pgno, bp, 0)
|
|
if rc == SQLITE_OK {
|
|
pData = Xsqlite3_value_blob(tls, **(**uintptr)(__ccgo_up(argv + 3*8)))
|
|
v1 = _sqlite3PagerWrite(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
rc = v1
|
|
if v1 == SQLITE_OK && pData != 0 {
|
|
aPage = _sqlite3PagerGetData(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
libc.Xmemcpy(tls, aPage, pData, libc.Uint64FromInt32(szPage))
|
|
(*TDbpageTable)(unsafe.Pointer(pTab)).FpgnoTrunc = uint32(0)
|
|
}
|
|
}
|
|
if rc != SQLITE_OK {
|
|
(*TDbpageTable)(unsafe.Pointer(pTab)).FpgnoTrunc = uint32(0)
|
|
}
|
|
_sqlite3PagerUnref(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
return rc
|
|
goto update_fail
|
|
update_fail:
|
|
;
|
|
(*TDbpageTable)(unsafe.Pointer(pTab)).FpgnoTrunc = uint32(0)
|
|
Xsqlite3_free(tls, (*Tsqlite3_vtab)(unsafe.Pointer(pVtab)).FzErrMsg)
|
|
(*Tsqlite3_vtab)(unsafe.Pointer(pVtab)).FzErrMsg = Xsqlite3_mprintf(tls, __ccgo_ts+3968, libc.VaList(bp+16, zErr))
|
|
return int32(SQLITE_ERROR)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This function is called to configure the RtreeConstraint object passed
|
|
// ** as the second argument for a MATCH constraint. The value passed as the
|
|
// ** first argument to this function is the right-hand operand to the MATCH
|
|
// ** operator.
|
|
// */
|
|
func _deserializeGeometry(tls *libc.TLS, pValue uintptr, pCons uintptr) (r int32) {
|
|
var pBlob, pInfo, pSrc uintptr
|
|
_, _, _ = pBlob, pInfo, pSrc /* Callback information */
|
|
pSrc = Xsqlite3_value_pointer(tls, pValue, __ccgo_ts+27519)
|
|
if pSrc == uintptr(0) {
|
|
return int32(SQLITE_ERROR)
|
|
}
|
|
pInfo = Xsqlite3_malloc64(tls, uint64(112)+uint64((*TRtreeMatchArg)(unsafe.Pointer(pSrc)).FiSize))
|
|
if !(pInfo != 0) {
|
|
return int32(SQLITE_NOMEM)
|
|
}
|
|
libc.Xmemset(tls, pInfo, 0, uint64(112))
|
|
pBlob = pInfo + 1*112
|
|
libc.Xmemcpy(tls, pBlob, pSrc, uint64((*TRtreeMatchArg)(unsafe.Pointer(pSrc)).FiSize))
|
|
(*Tsqlite3_rtree_query_info)(unsafe.Pointer(pInfo)).FpContext = (*TRtreeMatchArg)(unsafe.Pointer(pBlob)).Fcb.FpContext
|
|
(*Tsqlite3_rtree_query_info)(unsafe.Pointer(pInfo)).FnParam = (*TRtreeMatchArg)(unsafe.Pointer(pBlob)).FnParam
|
|
(*Tsqlite3_rtree_query_info)(unsafe.Pointer(pInfo)).FaParam = pBlob + 56
|
|
(*Tsqlite3_rtree_query_info)(unsafe.Pointer(pInfo)).FapSqlParam = (*TRtreeMatchArg)(unsafe.Pointer(pBlob)).FapSqlParam
|
|
if (*TRtreeMatchArg)(unsafe.Pointer(pBlob)).Fcb.FxGeom != 0 {
|
|
*(*uintptr)(unsafe.Pointer(pCons + 8)) = (*TRtreeMatchArg)(unsafe.Pointer(pBlob)).Fcb.FxGeom
|
|
} else {
|
|
(*TRtreeConstraint)(unsafe.Pointer(pCons)).Fop = int32(RTREE_QUERY)
|
|
*(*uintptr)(unsafe.Pointer(pCons + 8)) = (*TRtreeMatchArg)(unsafe.Pointer(pBlob)).Fcb.FxQueryFunc
|
|
}
|
|
(*TRtreeConstraint)(unsafe.Pointer(pCons)).FpInfo = pInfo
|
|
return SQLITE_OK
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Write code to erase the table with root-page iTable from database iDb.
|
|
// ** Also write code to modify the sqlite_schema table and internal schema
|
|
// ** if a root-page of another table is moved by the btree-layer whilst
|
|
// ** erasing iTable (this can happen with an auto-vacuum database).
|
|
// */
|
|
func _destroyRootPage(tls *libc.TLS, pParse uintptr, iTable int32, iDb int32) {
|
|
bp := tls.Alloc(48)
|
|
defer tls.Free(48)
|
|
var r1 int32
|
|
var v uintptr
|
|
_, _ = r1, v
|
|
v = _sqlite3GetVdbe(tls, pParse)
|
|
r1 = _sqlite3GetTempReg(tls, pParse)
|
|
if iTable < int32(2) {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+14897, 0)
|
|
}
|
|
_sqlite3VdbeAddOp3(tls, v, int32(OP_Destroy), iTable, r1, iDb)
|
|
_sqlite3MayAbort(tls, pParse)
|
|
/* OP_Destroy stores an in integer r1. If this integer
|
|
** is non-zero, then it is the root page number of a table moved to
|
|
** location iTable. The following code modifies the sqlite_schema table to
|
|
** reflect this.
|
|
**
|
|
** The "#NNN" in the SQL is a special constant that means whatever value
|
|
** is in register NNN. See grammar rules associated with the TK_REGISTER
|
|
** token for additional information.
|
|
*/
|
|
_sqlite3NestedParse(tls, pParse, __ccgo_ts+14912, libc.VaList(bp+8, (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer((*TParse)(unsafe.Pointer(pParse)).Fdb)).FaDb + uintptr(iDb)*32))).FzDbSName, iTable, r1, r1))
|
|
_sqlite3ReleaseTempReg(tls, pParse, r1)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** The implementation of internal UDF sqlite_drop_column().
|
|
// **
|
|
// ** Arguments:
|
|
// **
|
|
// ** argv[0]: An integer - the index of the schema containing the table
|
|
// ** argv[1]: CREATE TABLE statement to modify.
|
|
// ** argv[2]: An integer - the index of the column to remove.
|
|
// **
|
|
// ** The value returned is a string containing the CREATE TABLE statement
|
|
// ** with column argv[2] removed.
|
|
// */
|
|
func _dropColumnFunc(tls *libc.TLS, context uintptr, NotUsed int32, argv uintptr) {
|
|
bp := tls.Alloc(464)
|
|
defer tls.Free(464)
|
|
var db, pCol, pEnd, pTab, zDb, zEnd, zNew, zSql uintptr
|
|
var iCol, iSchema, rc int32
|
|
var xAuth Tsqlite3_xauth
|
|
var _ /* eTok at bp+424 */ int32
|
|
var _ /* sParse at bp+0 */ TParse
|
|
_, _, _, _, _, _, _, _, _, _, _, _ = db, iCol, iSchema, pCol, pEnd, pTab, rc, xAuth, zDb, zEnd, zNew, zSql
|
|
db = Xsqlite3_context_db_handle(tls, context)
|
|
iSchema = Xsqlite3_value_int(tls, **(**uintptr)(__ccgo_up(argv)))
|
|
zSql = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv + 1*8)))
|
|
iCol = Xsqlite3_value_int(tls, **(**uintptr)(__ccgo_up(argv + 2*8)))
|
|
zDb = (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(iSchema)*32))).FzDbSName
|
|
zNew = uintptr(0)
|
|
xAuth = (*Tsqlite3)(unsafe.Pointer(db)).FxAuth
|
|
(*Tsqlite3)(unsafe.Pointer(db)).FxAuth = uintptr(0)
|
|
_ = NotUsed
|
|
rc = _renameParseSql(tls, bp, zDb, db, zSql, libc.BoolInt32(iSchema == int32(1)))
|
|
if rc != SQLITE_OK {
|
|
goto drop_column_done
|
|
}
|
|
pTab = (**(**TParse)(__ccgo_up(bp))).FpNewTable
|
|
if pTab == uintptr(0) || int32((*TTable)(unsafe.Pointer(pTab)).FnCol) == int32(1) || iCol >= int32((*TTable)(unsafe.Pointer(pTab)).FnCol) {
|
|
/* This can happen if the sqlite_schema table is corrupt */
|
|
rc = _sqlite3CorruptError(tls, int32(122911))
|
|
goto drop_column_done
|
|
}
|
|
if iCol < int32((*TTable)(unsafe.Pointer(pTab)).FnCol)-int32(1) {
|
|
pCol = _renameTokenFind(tls, bp, uintptr(0), (**(**TColumn)(__ccgo_up((*TTable)(unsafe.Pointer(pTab)).FaCol + uintptr(iCol)*16))).FzCnName)
|
|
pEnd = _renameTokenFind(tls, bp, uintptr(0), (**(**TColumn)(__ccgo_up((*TTable)(unsafe.Pointer(pTab)).FaCol + uintptr(iCol+int32(1))*16))).FzCnName)
|
|
zEnd = (*TRenameToken)(unsafe.Pointer(pEnd)).Ft.Fz
|
|
} else {
|
|
/* Point pCol->t.z at the "," immediately preceding the definition of
|
|
** the column being dropped. To do this, start at the name of the
|
|
** previous column, and tokenize until the next ",". */
|
|
pCol = _renameTokenFind(tls, bp, uintptr(0), (**(**TColumn)(__ccgo_up((*TTable)(unsafe.Pointer(pTab)).FaCol + uintptr(iCol-int32(1))*16))).FzCnName)
|
|
for cond := true; cond; cond = **(**int32)(__ccgo_up(bp + 424)) != int32(TK_COMMA) {
|
|
(*TRenameToken)(unsafe.Pointer(pCol)).Ft.Fz += uintptr(_getConstraintToken(tls, (*TRenameToken)(unsafe.Pointer(pCol)).Ft.Fz, bp+424))
|
|
}
|
|
(*TRenameToken)(unsafe.Pointer(pCol)).Ft.Fz = (*TRenameToken)(unsafe.Pointer(pCol)).Ft.Fz - 1
|
|
zEnd = zSql + uintptr((*(*struct {
|
|
FaddColOffset int32
|
|
FpFKey uintptr
|
|
FpDfltList uintptr
|
|
})(unsafe.Pointer(pTab + 64))).FaddColOffset)
|
|
}
|
|
zNew = _sqlite3MPrintf(tls, db, __ccgo_ts+11613, libc.VaList(bp+440, int64((*TRenameToken)(unsafe.Pointer(pCol)).Ft.Fz)-int64(zSql), zSql, zEnd))
|
|
Xsqlite3_result_text(tls, context, zNew, -int32(1), uintptr(-libc.Int32FromInt32(1)))
|
|
Xsqlite3_free(tls, zNew)
|
|
goto drop_column_done
|
|
drop_column_done:
|
|
;
|
|
_renameParseCleanup(tls, bp)
|
|
(*Tsqlite3)(unsafe.Pointer(db)).FxAuth = xAuth
|
|
if rc != SQLITE_OK {
|
|
Xsqlite3_result_error_code(tls, context, rc)
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Internal SQL function sqlite3_drop_constraint(): Given an input
|
|
// ** CREATE TABLE statement, return a revised CREATE TABLE statement
|
|
// ** with a constraint removed. Two forms, depending on the datatype
|
|
// ** of argv[2]:
|
|
// **
|
|
// ** sqlite_drop_constraint(SQL, INT) -- Omit NOT NULL from the INT-th column
|
|
// ** sqlite_drop_constraint(SQL, TEXT) -- OMIT constraint with name TEXT
|
|
// **
|
|
// ** In the first case, the left-most column is 0.
|
|
// */
|
|
func _dropConstraintFunc(tls *libc.TLS, ctx uintptr, NotUsed int32, argv uintptr) {
|
|
bp := tls.Alloc(64)
|
|
defer tls.Free(64)
|
|
var db, zCons, zNew, zSpace, zSql uintptr
|
|
var iEnd, iNotNull, iStart, ii, nTok int32
|
|
var _ /* cmp at bp+8 */ int32
|
|
var _ /* iOff at bp+0 */ int32
|
|
var _ /* t at bp+4 */ int32
|
|
_, _, _, _, _, _, _, _, _, _ = db, iEnd, iNotNull, iStart, ii, nTok, zCons, zNew, zSpace, zSql
|
|
zSql = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv)))
|
|
zCons = uintptr(0)
|
|
iNotNull = -int32(1)
|
|
**(**int32)(__ccgo_up(bp)) = 0
|
|
iStart = 0
|
|
iEnd = 0
|
|
zNew = uintptr(0)
|
|
**(**int32)(__ccgo_up(bp + 4)) = 0
|
|
_ = NotUsed
|
|
if zSql == uintptr(0) {
|
|
return
|
|
}
|
|
/* Jump past the "CREATE TABLE" bit. */
|
|
if _skipCreateTable(tls, ctx, zSql, bp) != 0 {
|
|
return
|
|
}
|
|
if Xsqlite3_value_type(tls, **(**uintptr)(__ccgo_up(argv + 1*8))) == int32(SQLITE_INTEGER) {
|
|
iNotNull = Xsqlite3_value_int(tls, **(**uintptr)(__ccgo_up(argv + 1*8)))
|
|
} else {
|
|
zCons = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv + 1*8)))
|
|
}
|
|
/* Search for the named constraint within column definitions. */
|
|
ii = 0
|
|
for {
|
|
if !(iEnd == 0) {
|
|
break
|
|
}
|
|
/* Now parse the column or table constraint definition. Search
|
|
** for the token CONSTRAINT if this is a DROP CONSTRAINT command, or
|
|
** NOT in the right column if this is a DROP NOT NULL. */
|
|
for int32(1) != 0 {
|
|
iStart = **(**int32)(__ccgo_up(bp))
|
|
**(**int32)(__ccgo_up(bp)) = **(**int32)(__ccgo_up(bp)) + _getConstraintToken(tls, zSql+uintptr(**(**int32)(__ccgo_up(bp))), bp+4)
|
|
if **(**int32)(__ccgo_up(bp + 4)) == int32(TK_CONSTRAINT) && (zCons != 0 || iNotNull == ii) {
|
|
/* Check if this is the constraint we are searching for. */
|
|
nTok = 0
|
|
**(**int32)(__ccgo_up(bp + 8)) = int32(1)
|
|
/* Skip past any whitespace. */
|
|
**(**int32)(__ccgo_up(bp)) = **(**int32)(__ccgo_up(bp)) + _getWhitespace(tls, zSql+uintptr(**(**int32)(__ccgo_up(bp))))
|
|
/* Compare the next token - which may be quoted - with the name of
|
|
** the constraint being dropped. */
|
|
nTok = _getConstraintToken(tls, zSql+uintptr(**(**int32)(__ccgo_up(bp))), bp+4)
|
|
if zCons != 0 {
|
|
if _quotedCompare(tls, ctx, **(**int32)(__ccgo_up(bp + 4)), zSql+uintptr(**(**int32)(__ccgo_up(bp))), nTok, zCons, bp+8) != 0 {
|
|
return
|
|
}
|
|
}
|
|
**(**int32)(__ccgo_up(bp)) = **(**int32)(__ccgo_up(bp)) + nTok
|
|
/* The next token is usually the first token of the constraint
|
|
** definition. This is enough to tell the type of the constraint -
|
|
** TK_NOT means it is a NOT NULL, TK_CHECK a CHECK constraint etc.
|
|
**
|
|
** There is also the chance that the next token is TK_CONSTRAINT
|
|
** (or TK_DEFAULT or TK_COLLATE), for example if a table has been
|
|
** created as follows:
|
|
**
|
|
** CREATE TABLE t1(cols, CONSTRAINT one CONSTRAINT two NOT NULL);
|
|
**
|
|
** In this case, allow the "CONSTRAINT one" bit to be dropped by
|
|
** this command if that is what is requested, or to advance to
|
|
** the next iteration of the loop with &zSql[iOff] still pointing
|
|
** to the CONSTRAINT keyword. */
|
|
nTok = _getConstraintToken(tls, zSql+uintptr(**(**int32)(__ccgo_up(bp))), bp+4)
|
|
if **(**int32)(__ccgo_up(bp + 4)) == int32(TK_CONSTRAINT) || **(**int32)(__ccgo_up(bp + 4)) == int32(TK_DEFAULT) || **(**int32)(__ccgo_up(bp + 4)) == int32(TK_COLLATE) || **(**int32)(__ccgo_up(bp + 4)) == int32(TK_COMMA) || **(**int32)(__ccgo_up(bp + 4)) == int32(TK_RP) || **(**int32)(__ccgo_up(bp + 4)) == int32(TK_GENERATED) || **(**int32)(__ccgo_up(bp + 4)) == int32(TK_AS) {
|
|
**(**int32)(__ccgo_up(bp + 4)) = int32(TK_CHECK)
|
|
} else {
|
|
**(**int32)(__ccgo_up(bp)) = **(**int32)(__ccgo_up(bp)) + nTok
|
|
**(**int32)(__ccgo_up(bp)) = **(**int32)(__ccgo_up(bp)) + _getConstraint(tls, zSql+uintptr(**(**int32)(__ccgo_up(bp))))
|
|
}
|
|
if **(**int32)(__ccgo_up(bp + 8)) == 0 || iNotNull >= 0 && **(**int32)(__ccgo_up(bp + 4)) == int32(TK_NOT) {
|
|
if **(**int32)(__ccgo_up(bp + 4)) != int32(TK_NOT) && **(**int32)(__ccgo_up(bp + 4)) != int32(TK_CHECK) {
|
|
_errorMPrintf(tls, ctx, __ccgo_ts+11847, libc.VaList(bp+24, zCons))
|
|
return
|
|
}
|
|
iEnd = **(**int32)(__ccgo_up(bp))
|
|
break
|
|
}
|
|
} else {
|
|
if **(**int32)(__ccgo_up(bp + 4)) == int32(TK_NOT) && iNotNull == ii {
|
|
iEnd = **(**int32)(__ccgo_up(bp)) + _getConstraint(tls, zSql+uintptr(**(**int32)(__ccgo_up(bp))))
|
|
break
|
|
} else {
|
|
if **(**int32)(__ccgo_up(bp + 4)) == int32(TK_RP) || **(**int32)(__ccgo_up(bp + 4)) == int32(TK_ILLEGAL) {
|
|
iEnd = -int32(1)
|
|
break
|
|
} else {
|
|
if **(**int32)(__ccgo_up(bp + 4)) == int32(TK_COMMA) {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
ii = ii + 1
|
|
}
|
|
/* If the constraint has not been found it is an error. */
|
|
if iEnd <= 0 {
|
|
if zCons != 0 {
|
|
_errorMPrintf(tls, ctx, __ccgo_ts+11881, libc.VaList(bp+24, zCons))
|
|
} else {
|
|
/* SQLite follows postgres in that a DROP NOT NULL on a column that is
|
|
** not NOT NULL is not an error. So just return the original SQL here. */
|
|
Xsqlite3_result_text(tls, ctx, zSql, -int32(1), uintptr(-libc.Int32FromInt32(1)))
|
|
}
|
|
} else {
|
|
/* Figure out if an extra space should be inserted after the constraint
|
|
** is removed. And if an additional comma preceding the constraint
|
|
** should be removed. */
|
|
zSpace = __ccgo_ts + 11569
|
|
iEnd = iEnd + _getWhitespace(tls, zSql+uintptr(iEnd))
|
|
_sqlite3GetToken(tls, zSql+uintptr(iEnd), bp+4)
|
|
if **(**int32)(__ccgo_up(bp + 4)) == int32(TK_RP) || **(**int32)(__ccgo_up(bp + 4)) == int32(TK_COMMA) {
|
|
zSpace = __ccgo_ts + 1704
|
|
if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(zSql + uintptr(iStart-int32(1))))) == int32(',') {
|
|
iStart = iStart - 1
|
|
}
|
|
}
|
|
db = Xsqlite3_context_db_handle(tls, ctx)
|
|
zNew = _sqlite3MPrintf(tls, db, __ccgo_ts+11904, libc.VaList(bp+24, iStart, zSql, zSpace, zSql+uintptr(iEnd)))
|
|
Xsqlite3_result_text(tls, ctx, zNew, -int32(1), __ccgo_fp(_sqlite3RowSetClear))
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Implementation of the sqlite_log() function. This is a wrapper around
|
|
// ** sqlite3_log(). The return value is NULL. The function exists purely for
|
|
// ** its side-effects.
|
|
// */
|
|
func _errlogFunc(tls *libc.TLS, context uintptr, argc int32, argv uintptr) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
_ = argc
|
|
_ = context
|
|
Xsqlite3_log(tls, Xsqlite3_value_int(tls, **(**uintptr)(__ccgo_up(argv))), __ccgo_ts+3968, libc.VaList(bp+8, Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv + 1*8)))))
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Execute zSql on database db.
|
|
// **
|
|
// ** If zSql returns rows, then each row will have exactly one
|
|
// ** column. (This will only happen if zSql begins with "SELECT".)
|
|
// ** Take each row of result and call execSql() again recursively.
|
|
// **
|
|
// ** The execSqlF() routine does the same thing, except it accepts
|
|
// ** a format string as its third argument
|
|
// */
|
|
func _execSql(tls *libc.TLS, db uintptr, pzErrMsg uintptr, zSql uintptr) (r int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var rc, v1 int32
|
|
var zSubSql uintptr
|
|
var _ /* pStmt at bp+0 */ uintptr
|
|
_, _, _ = rc, zSubSql, v1
|
|
/* printf("SQL: [%s]\n", zSql); fflush(stdout); */
|
|
rc = Xsqlite3_prepare_v2(tls, db, zSql, -int32(1), bp, uintptr(0))
|
|
if rc != SQLITE_OK {
|
|
return rc
|
|
}
|
|
for {
|
|
v1 = Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
rc = v1
|
|
if !(int32(SQLITE_ROW) == v1) {
|
|
break
|
|
}
|
|
zSubSql = Xsqlite3_column_text(tls, **(**uintptr)(__ccgo_up(bp)), 0)
|
|
/* The secondary SQL must be one of CREATE TABLE, CREATE INDEX,
|
|
** or INSERT. Historically there have been attacks that first
|
|
** corrupt the sqlite_schema.sql field with other kinds of statements
|
|
** then run VACUUM to get those statements to execute at inappropriate
|
|
** times. */
|
|
if zSubSql != 0 && (libc.Xstrncmp(tls, zSubSql, __ccgo_ts+22757, uint64(3)) == 0 || libc.Xstrncmp(tls, zSubSql, __ccgo_ts+22761, uint64(3)) == 0) {
|
|
rc = _execSql(tls, db, pzErrMsg, zSubSql)
|
|
if rc != SQLITE_OK {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
if rc == int32(SQLITE_DONE) {
|
|
rc = SQLITE_OK
|
|
}
|
|
if rc != 0 {
|
|
_sqlite3SetString(tls, pzErrMsg, db, Xsqlite3_errmsg(tls, db))
|
|
}
|
|
Xsqlite3_finalize(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Return the name of the i-th column of the pIdx index.
|
|
// */
|
|
func _explainIndexColumnName(tls *libc.TLS, pIdx uintptr, i int32) (r uintptr) {
|
|
i = int32(**(**Ti16)(__ccgo_up((*TIndex)(unsafe.Pointer(pIdx)).FaiColumn + uintptr(i)*2)))
|
|
if i == -int32(2) {
|
|
return __ccgo_ts + 23646
|
|
}
|
|
if i == -int32(1) {
|
|
return __ccgo_ts + 17991
|
|
}
|
|
return (**(**TColumn)(__ccgo_up((*TTable)(unsafe.Pointer((*TIndex)(unsafe.Pointer(pIdx)).FpTable)).FaCol + uintptr(i)*16))).FzCnName
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Initialize the contents of the unixFile structure pointed to by pId.
|
|
// */
|
|
func _fillInUnixFile(tls *libc.TLS, pVfs uintptr, h int32, pId uintptr, zFilename uintptr, ctrlFlags int32) (r int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var nFilename, rc int32
|
|
var pLockingStyle, pNew, zLockFile, v1, v2 uintptr
|
|
_, _, _, _, _, _, _ = nFilename, pLockingStyle, pNew, rc, zLockFile, v1, v2
|
|
pNew = pId
|
|
rc = SQLITE_OK
|
|
/* No locking occurs in temporary files */
|
|
(*TunixFile)(unsafe.Pointer(pNew)).Fh = h
|
|
(*TunixFile)(unsafe.Pointer(pNew)).FpVfs = pVfs
|
|
(*TunixFile)(unsafe.Pointer(pNew)).FzPath = zFilename
|
|
(*TunixFile)(unsafe.Pointer(pNew)).FctrlFlags = uint16(libc.Uint8FromInt32(ctrlFlags))
|
|
(*TunixFile)(unsafe.Pointer(pNew)).FmmapSizeMax = _sqlite3Config.FszMmap
|
|
if ctrlFlags&int32(UNIXFILE_URI) != 0 {
|
|
v1 = zFilename
|
|
} else {
|
|
v1 = uintptr(0)
|
|
}
|
|
if Xsqlite3_uri_boolean(tls, v1, __ccgo_ts+4002, int32(SQLITE_POWERSAFE_OVERWRITE)) != 0 {
|
|
v2 = pNew + 30
|
|
*(*uint16)(unsafe.Pointer(v2)) = uint16(int32(*(*uint16)(unsafe.Pointer(v2))) | libc.Int32FromInt32(UNIXFILE_PSOW))
|
|
}
|
|
if libc.Xstrcmp(tls, (*Tsqlite3_vfs)(unsafe.Pointer(pVfs)).FzName, __ccgo_ts+4007) == 0 {
|
|
v1 = pNew + 30
|
|
*(*uint16)(unsafe.Pointer(v1)) = uint16(int32(*(*uint16)(unsafe.Pointer(v1))) | libc.Int32FromInt32(UNIXFILE_EXCL))
|
|
}
|
|
if ctrlFlags&int32(UNIXFILE_NOLOCK) != 0 {
|
|
pLockingStyle = uintptr(unsafe.Pointer(&_nolockIoMethods))
|
|
} else {
|
|
pLockingStyle = (*(*func(*libc.TLS, uintptr, uintptr) uintptr)(unsafe.Pointer(&struct{ uintptr }{*(*uintptr)(unsafe.Pointer((*Tsqlite3_vfs)(unsafe.Pointer(pVfs)).FpAppData))})))(tls, zFilename, pNew)
|
|
}
|
|
if pLockingStyle == uintptr(unsafe.Pointer(&_posixIoMethods)) {
|
|
_unixEnterMutex(tls)
|
|
rc = _findInodeInfo(tls, pNew, pNew+16)
|
|
if rc != SQLITE_OK {
|
|
/* If an error occurred in findInodeInfo(), close the file descriptor
|
|
** immediately, before releasing the mutex. findInodeInfo() may fail
|
|
** in two scenarios:
|
|
**
|
|
** (a) A call to fstat() failed.
|
|
** (b) A malloc failed.
|
|
**
|
|
** Scenario (b) may only occur if the process is holding no other
|
|
** file descriptors open on the same file. If there were other file
|
|
** descriptors on this file, then no malloc would be required by
|
|
** findInodeInfo(). If this is the case, it is quite safe to close
|
|
** handle h - as it is guaranteed that no posix locks will be released
|
|
** by doing so.
|
|
**
|
|
** If scenario (a) caused the error then things are not so safe. The
|
|
** implicit assumption here is that if fstat() fails, things are in
|
|
** such bad shape that dropping a lock or two doesn't matter much.
|
|
*/
|
|
_robust_close(tls, pNew, h, int32(46500))
|
|
h = -int32(1)
|
|
}
|
|
_unixLeaveMutex(tls)
|
|
} else {
|
|
if pLockingStyle == uintptr(unsafe.Pointer(&_dotlockIoMethods)) {
|
|
nFilename = libc.Int32FromUint64(libc.Xstrlen(tls, zFilename)) + int32(6)
|
|
zLockFile = Xsqlite3_malloc64(tls, libc.Uint64FromInt32(nFilename))
|
|
if zLockFile == uintptr(0) {
|
|
rc = int32(SQLITE_NOMEM)
|
|
} else {
|
|
Xsqlite3_snprintf(tls, nFilename, zLockFile, __ccgo_ts+4017, libc.VaList(bp+8, zFilename))
|
|
}
|
|
(*TunixFile)(unsafe.Pointer(pNew)).FlockingContext = zLockFile
|
|
}
|
|
}
|
|
_storeLastErrno(tls, pNew, 0)
|
|
if rc != SQLITE_OK {
|
|
if h >= 0 {
|
|
_robust_close(tls, pNew, h, int32(46592))
|
|
}
|
|
} else {
|
|
(*Tsqlite3_file)(unsafe.Pointer(pId)).FpMethods = pLockingStyle
|
|
_verifyDbFile(tls, pNew)
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Return a pointer corresponding to database zDb (i.e. "main", "temp")
|
|
// ** in connection handle pDb. If such a database cannot be found, return
|
|
// ** a NULL pointer and write an error message to pErrorDb.
|
|
// **
|
|
// ** If the "temp" database is requested, it may need to be opened by this
|
|
// ** function. If an error occurs while doing so, return 0 and write an
|
|
// ** error message to pErrorDb.
|
|
// */
|
|
func _findBtree(tls *libc.TLS, pErrorDb uintptr, pDb uintptr, zDb uintptr) (r uintptr) {
|
|
bp := tls.Alloc(448)
|
|
defer tls.Free(448)
|
|
var i, rc int32
|
|
var _ /* sParse at bp+0 */ TParse
|
|
_, _ = i, rc
|
|
i = _sqlite3FindDbName(tls, pDb, zDb)
|
|
if i == int32(1) {
|
|
rc = 0
|
|
_sqlite3ParseObjectInit(tls, bp, pDb)
|
|
if _sqlite3OpenTempDatabase(tls, bp) != 0 {
|
|
_sqlite3ErrorWithMsg(tls, pErrorDb, (**(**TParse)(__ccgo_up(bp))).Frc, __ccgo_ts+3968, libc.VaList(bp+432, (**(**TParse)(__ccgo_up(bp))).FzErrMsg))
|
|
rc = int32(SQLITE_ERROR)
|
|
}
|
|
_sqlite3DbFree(tls, pErrorDb, (**(**TParse)(__ccgo_up(bp))).FzErrMsg)
|
|
_sqlite3ParseObjectReset(tls, bp)
|
|
if rc != 0 {
|
|
return uintptr(0)
|
|
}
|
|
}
|
|
if i < 0 {
|
|
_sqlite3ErrorWithMsg(tls, pErrorDb, int32(SQLITE_ERROR), __ccgo_ts+5153, libc.VaList(bp+432, zDb))
|
|
return uintptr(0)
|
|
}
|
|
return (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(pDb)).FaDb + uintptr(i)*32))).FpBt
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Search the AggInfo object for an aCol[] entry that has iTable and iColumn.
|
|
// ** Return the index in aCol[] of the entry that describes that column.
|
|
// **
|
|
// ** If no prior entry is found, create a new one and return -1. The
|
|
// ** new column will have an index of pAggInfo->nColumn-1.
|
|
// */
|
|
func _findOrCreateAggInfoColumn(tls *libc.TLS, pParse uintptr, pAggInfo uintptr, pExpr uintptr) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var j, k, mxTerm, n int32
|
|
var pCol, pE, pGB, pTerm, v4 uintptr
|
|
var v3 Tu32
|
|
_, _, _, _, _, _, _, _, _, _ = j, k, mxTerm, n, pCol, pE, pGB, pTerm, v3, v4
|
|
mxTerm = **(**int32)(__ccgo_up((*TParse)(unsafe.Pointer(pParse)).Fdb + 136 + 2*4))
|
|
pCol = (*TAggInfo)(unsafe.Pointer(pAggInfo)).FaCol
|
|
k = 0
|
|
for {
|
|
if !(k < (*TAggInfo)(unsafe.Pointer(pAggInfo)).FnColumn) {
|
|
break
|
|
}
|
|
if (*TAggInfo_col)(unsafe.Pointer(pCol)).FpCExpr == pExpr {
|
|
return
|
|
}
|
|
if (*TAggInfo_col)(unsafe.Pointer(pCol)).FiTable == (*TExpr)(unsafe.Pointer(pExpr)).FiTable && (*TAggInfo_col)(unsafe.Pointer(pCol)).FiColumn == int32((*TExpr)(unsafe.Pointer(pExpr)).FiColumn) && libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) != int32(TK_IF_NULL_ROW) {
|
|
goto fix_up_expr
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
k = k + 1
|
|
pCol += 32
|
|
}
|
|
k = _addAggInfoColumn(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, pAggInfo)
|
|
if k < 0 {
|
|
/* OOM on resize */
|
|
return
|
|
}
|
|
if k > mxTerm {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+8642, libc.VaList(bp+8, mxTerm))
|
|
k = mxTerm
|
|
}
|
|
pCol = (*TAggInfo)(unsafe.Pointer(pAggInfo)).FaCol + uintptr(k)*32
|
|
(*TAggInfo_col)(unsafe.Pointer(pCol)).FpTab = *(*uintptr)(unsafe.Pointer(pExpr + 64))
|
|
(*TAggInfo_col)(unsafe.Pointer(pCol)).FiTable = (*TExpr)(unsafe.Pointer(pExpr)).FiTable
|
|
(*TAggInfo_col)(unsafe.Pointer(pCol)).FiColumn = int32((*TExpr)(unsafe.Pointer(pExpr)).FiColumn)
|
|
(*TAggInfo_col)(unsafe.Pointer(pCol)).FiSorterColumn = -int32(1)
|
|
(*TAggInfo_col)(unsafe.Pointer(pCol)).FpCExpr = pExpr
|
|
if (*TAggInfo)(unsafe.Pointer(pAggInfo)).FpGroupBy != 0 && libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) != int32(TK_IF_NULL_ROW) {
|
|
pGB = (*TAggInfo)(unsafe.Pointer(pAggInfo)).FpGroupBy
|
|
pTerm = pGB + 8
|
|
n = (*TExprList)(unsafe.Pointer(pGB)).FnExpr
|
|
j = 0
|
|
for {
|
|
if !(j < n) {
|
|
break
|
|
}
|
|
pE = (*TExprList_item)(unsafe.Pointer(pTerm)).FpExpr
|
|
if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pE)).Fop) == int32(TK_COLUMN) && (*TExpr)(unsafe.Pointer(pE)).FiTable == (*TExpr)(unsafe.Pointer(pExpr)).FiTable && int32((*TExpr)(unsafe.Pointer(pE)).FiColumn) == int32((*TExpr)(unsafe.Pointer(pExpr)).FiColumn) {
|
|
(*TAggInfo_col)(unsafe.Pointer(pCol)).FiSorterColumn = j
|
|
break
|
|
}
|
|
goto _2
|
|
_2:
|
|
;
|
|
j = j + 1
|
|
pTerm += 32
|
|
}
|
|
}
|
|
if (*TAggInfo_col)(unsafe.Pointer(pCol)).FiSorterColumn < 0 {
|
|
v4 = pAggInfo + 4
|
|
v3 = *(*Tu32)(unsafe.Pointer(v4))
|
|
*(*Tu32)(unsafe.Pointer(v4)) = *(*Tu32)(unsafe.Pointer(v4)) + 1
|
|
(*TAggInfo_col)(unsafe.Pointer(pCol)).FiSorterColumn = libc.Int32FromUint32(v3)
|
|
}
|
|
goto fix_up_expr
|
|
fix_up_expr:
|
|
;
|
|
(*TExpr)(unsafe.Pointer(pExpr)).FpAggInfo = pAggInfo
|
|
if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) == int32(TK_COLUMN) {
|
|
(*TExpr)(unsafe.Pointer(pExpr)).Fop = uint8(TK_AGG_COLUMN)
|
|
}
|
|
(*TExpr)(unsafe.Pointer(pExpr)).FiAgg = int16(k)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Expression callback used by sqlite3FixAAAA() routines.
|
|
// */
|
|
func _fixExprCb(tls *libc.TLS, p uintptr, pExpr uintptr) (r int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var pFix uintptr
|
|
_ = pFix
|
|
pFix = *(*uintptr)(unsafe.Pointer(p + 40))
|
|
if !((*TDbFixer)(unsafe.Pointer(pFix)).FbTemp != 0) {
|
|
**(**Tu32)(__ccgo_up(pExpr + 4)) |= libc.Uint32FromInt32(libc.Int32FromInt32(EP_FromDDL))
|
|
}
|
|
if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) == int32(TK_VARIABLE) {
|
|
if (*Tsqlite3)(unsafe.Pointer((*TParse)(unsafe.Pointer((*TDbFixer)(unsafe.Pointer(pFix)).FpParse)).Fdb)).Finit1.Fbusy != 0 {
|
|
(*TExpr)(unsafe.Pointer(pExpr)).Fop = uint8(TK_NULL)
|
|
} else {
|
|
_sqlite3ErrorMsg(tls, (*TDbFixer)(unsafe.Pointer(pFix)).FpParse, __ccgo_ts+13567, libc.VaList(bp+8, (*TDbFixer)(unsafe.Pointer(pFix)).FzType))
|
|
return int32(WRC_Abort)
|
|
}
|
|
}
|
|
return WRC_Continue
|
|
}
|
|
|
|
func _fts5ApiCallback(tls *libc.TLS, context uintptr, argc int32, argv uintptr) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var iCsrId Ti64
|
|
var pAux, pCsr, pTab uintptr
|
|
_, _, _, _ = iCsrId, pAux, pCsr, pTab
|
|
pAux = Xsqlite3_user_data(tls, context)
|
|
iCsrId = Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(argv)))
|
|
pCsr = _fts5CursorFromCsrid(tls, (*TFts5Auxiliary)(unsafe.Pointer(pAux)).FpGlobal, iCsrId)
|
|
if pCsr == uintptr(0) || ((*TFts5Cursor)(unsafe.Pointer(pCsr)).FePlan == 0 || (*TFts5Cursor)(unsafe.Pointer(pCsr)).FePlan == int32(FTS5_PLAN_SPECIAL)) {
|
|
_fts5ResultError(tls, context, __ccgo_ts+40446, libc.VaList(bp+8, iCsrId))
|
|
} else {
|
|
pTab = (*TFts5Cursor)(unsafe.Pointer(pCsr)).Fbase.FpVtab
|
|
_fts5ApiInvoke(tls, pAux, pCsr, context, argc-int32(1), argv+1*8)
|
|
Xsqlite3_free(tls, (*Tsqlite3_vtab)(unsafe.Pointer(pTab)).FzErrMsg)
|
|
(*Tsqlite3_vtab)(unsafe.Pointer(pTab)).FzErrMsg = uintptr(0)
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Create an "ascii" tokenizer.
|
|
// */
|
|
func _fts5AsciiCreate(tls *libc.TLS, pUnused uintptr, azArg uintptr, nArg int32, ppOut uintptr) (r int32) {
|
|
var i, rc int32
|
|
var p, zArg uintptr
|
|
_, _, _, _ = i, p, rc, zArg
|
|
rc = SQLITE_OK
|
|
p = uintptr(0)
|
|
_ = pUnused
|
|
if nArg%int32(2) != 0 {
|
|
rc = int32(SQLITE_ERROR)
|
|
} else {
|
|
p = Xsqlite3_malloc64(tls, uint64(128))
|
|
if p == uintptr(0) {
|
|
rc = int32(SQLITE_NOMEM)
|
|
} else {
|
|
libc.Xmemset(tls, p, 0, uint64(128))
|
|
libc.Xmemcpy(tls, p, uintptr(unsafe.Pointer(&_aAsciiTokenChar)), uint64(128))
|
|
i = 0
|
|
for {
|
|
if !(rc == SQLITE_OK && i < nArg) {
|
|
break
|
|
}
|
|
zArg = **(**uintptr)(__ccgo_up(azArg + uintptr(i+int32(1))*8))
|
|
if 0 == Xsqlite3_stricmp(tls, **(**uintptr)(__ccgo_up(azArg + uintptr(i)*8)), __ccgo_ts+41858) {
|
|
_fts5AsciiAddExceptions(tls, p, zArg, int32(1))
|
|
} else {
|
|
if 0 == Xsqlite3_stricmp(tls, **(**uintptr)(__ccgo_up(azArg + uintptr(i)*8)), __ccgo_ts+41869) {
|
|
_fts5AsciiAddExceptions(tls, p, zArg, 0)
|
|
} else {
|
|
rc = int32(SQLITE_ERROR)
|
|
}
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + int32(2)
|
|
}
|
|
if rc != SQLITE_OK {
|
|
_fts5AsciiDelete(tls, p)
|
|
p = uintptr(0)
|
|
}
|
|
}
|
|
}
|
|
**(**uintptr)(__ccgo_up(ppOut)) = p
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Populate the Fts5Config.zContentExprlist string.
|
|
// */
|
|
func _fts5ConfigMakeExprlist(tls *libc.TLS, p uintptr) (r int32) {
|
|
bp := tls.Alloc(48)
|
|
defer tls.Free(48)
|
|
var i int32
|
|
var _ /* buf at bp+8 */ TFts5Buffer
|
|
var _ /* rc at bp+0 */ int32
|
|
_ = i
|
|
**(**int32)(__ccgo_up(bp)) = SQLITE_OK
|
|
**(**TFts5Buffer)(__ccgo_up(bp + 8)) = TFts5Buffer{}
|
|
_sqlite3Fts5BufferAppendPrintf(tls, bp, bp+8, __ccgo_ts+38068, libc.VaList(bp+32, (*TFts5Config)(unsafe.Pointer(p)).FzContentRowid))
|
|
if (*TFts5Config)(unsafe.Pointer(p)).FeContent != int32(FTS5_CONTENT_NONE) {
|
|
i = 0
|
|
for {
|
|
if !(i < (*TFts5Config)(unsafe.Pointer(p)).FnCol) {
|
|
break
|
|
}
|
|
if (*TFts5Config)(unsafe.Pointer(p)).FeContent == int32(FTS5_CONTENT_EXTERNAL) {
|
|
_sqlite3Fts5BufferAppendPrintf(tls, bp, bp+8, __ccgo_ts+38073, libc.VaList(bp+32, **(**uintptr)(__ccgo_up((*TFts5Config)(unsafe.Pointer(p)).FazCol + uintptr(i)*8))))
|
|
} else {
|
|
if (*TFts5Config)(unsafe.Pointer(p)).FeContent == FTS5_CONTENT_NORMAL || **(**Tu8)(__ccgo_up((*TFts5Config)(unsafe.Pointer(p)).FabUnindexed + uintptr(i))) != 0 {
|
|
_sqlite3Fts5BufferAppendPrintf(tls, bp, bp+8, __ccgo_ts+38080, libc.VaList(bp+32, i))
|
|
} else {
|
|
_sqlite3Fts5BufferAppendPrintf(tls, bp, bp+8, __ccgo_ts+38088, 0)
|
|
}
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
}
|
|
if (*TFts5Config)(unsafe.Pointer(p)).FeContent == FTS5_CONTENT_NORMAL && (*TFts5Config)(unsafe.Pointer(p)).FbLocale != 0 {
|
|
i = 0
|
|
for {
|
|
if !(i < (*TFts5Config)(unsafe.Pointer(p)).FnCol) {
|
|
break
|
|
}
|
|
if libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TFts5Config)(unsafe.Pointer(p)).FabUnindexed + uintptr(i)))) == 0 {
|
|
_sqlite3Fts5BufferAppendPrintf(tls, bp, bp+8, __ccgo_ts+38095, libc.VaList(bp+32, i))
|
|
} else {
|
|
_sqlite3Fts5BufferAppendPrintf(tls, bp, bp+8, __ccgo_ts+38088, 0)
|
|
}
|
|
goto _2
|
|
_2:
|
|
;
|
|
i = i + 1
|
|
}
|
|
}
|
|
(*TFts5Config)(unsafe.Pointer(p)).FzContentExprlist = (**(**TFts5Buffer)(__ccgo_up(bp + 8))).Fp
|
|
return **(**int32)(__ccgo_up(bp))
|
|
}
|
|
|
|
func _fts5ConfigParseColumn(tls *libc.TLS, p uintptr, zCol uintptr, zArg uintptr, pzErr uintptr, pbUnindexed uintptr) (r int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var rc, v1 int32
|
|
var v2 uintptr
|
|
_, _, _ = rc, v1, v2
|
|
rc = SQLITE_OK
|
|
if 0 == Xsqlite3_stricmp(tls, zCol, __ccgo_ts+37992) || 0 == Xsqlite3_stricmp(tls, zCol, __ccgo_ts+17991) {
|
|
**(**uintptr)(__ccgo_up(pzErr)) = Xsqlite3_mprintf(tls, __ccgo_ts+37997, libc.VaList(bp+8, zCol))
|
|
rc = int32(SQLITE_ERROR)
|
|
} else {
|
|
if zArg != 0 {
|
|
if 0 == Xsqlite3_stricmp(tls, zArg, __ccgo_ts+38027) {
|
|
**(**Tu8)(__ccgo_up((*TFts5Config)(unsafe.Pointer(p)).FabUnindexed + uintptr((*TFts5Config)(unsafe.Pointer(p)).FnCol))) = uint8(1)
|
|
**(**int32)(__ccgo_up(pbUnindexed)) = int32(1)
|
|
} else {
|
|
**(**uintptr)(__ccgo_up(pzErr)) = Xsqlite3_mprintf(tls, __ccgo_ts+38037, libc.VaList(bp+8, zArg))
|
|
rc = int32(SQLITE_ERROR)
|
|
}
|
|
}
|
|
}
|
|
v2 = p + 32
|
|
v1 = *(*int32)(unsafe.Pointer(v2))
|
|
*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1
|
|
**(**uintptr)(__ccgo_up((*TFts5Config)(unsafe.Pointer(p)).FazCol + uintptr(v1)*8)) = zCol
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// **
|
|
// ** This function is called when the user attempts an UPDATE on a contentless
|
|
// ** table. Parameter bRowidModified is true if the UPDATE statement modifies
|
|
// ** the rowid value. Parameter apVal[] contains the new values for each user
|
|
// ** defined column of the fts5 table. pConfig is the configuration object of the
|
|
// ** table being updated (guaranteed to be contentless). The contentless_delete=1
|
|
// ** and contentless_unindexed=1 options may or may not be set.
|
|
// **
|
|
// ** This function returns SQLITE_OK if the UPDATE can go ahead, or an SQLite
|
|
// ** error code if it cannot. In this case an error message is also loaded into
|
|
// ** pConfig. Output parameter (*pbContent) is set to true if the caller should
|
|
// ** update the %_content table only - not the FTS index or any other shadow
|
|
// ** table. This occurs when an UPDATE modifies only UNINDEXED columns of the
|
|
// ** table.
|
|
// **
|
|
// ** An UPDATE may proceed if:
|
|
// **
|
|
// ** * The only columns modified are UNINDEXED columns, or
|
|
// **
|
|
// ** * The contentless_delete=1 option was specified and all of the indexed
|
|
// ** columns (not a subset) have been modified.
|
|
// */
|
|
func _fts5ContentlessUpdate(tls *libc.TLS, pConfig uintptr, apVal uintptr, bRowidModified int32, pbContent uintptr) (r int32) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var bSeenIndex, bSeenIndexNC, ii, rc int32
|
|
var v2 uintptr
|
|
_, _, _, _, _ = bSeenIndex, bSeenIndexNC, ii, rc, v2
|
|
bSeenIndex = 0 /* Have seen modified indexed column */
|
|
bSeenIndexNC = 0 /* Have seen unmodified indexed column */
|
|
rc = SQLITE_OK
|
|
ii = 0
|
|
for {
|
|
if !(ii < (*TFts5Config)(unsafe.Pointer(pConfig)).FnCol) {
|
|
break
|
|
}
|
|
if libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TFts5Config)(unsafe.Pointer(pConfig)).FabUnindexed + uintptr(ii)))) == 0 {
|
|
if Xsqlite3_value_nochange(tls, **(**uintptr)(__ccgo_up(apVal + uintptr(ii)*8))) != 0 {
|
|
bSeenIndexNC = bSeenIndexNC + 1
|
|
} else {
|
|
bSeenIndex = bSeenIndex + 1
|
|
}
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
ii = ii + 1
|
|
}
|
|
if bSeenIndex == 0 && bRowidModified == 0 {
|
|
**(**int32)(__ccgo_up(pbContent)) = int32(1)
|
|
} else {
|
|
if bSeenIndexNC != 0 || (*TFts5Config)(unsafe.Pointer(pConfig)).FbContentlessDelete == 0 {
|
|
rc = int32(SQLITE_ERROR)
|
|
if (*TFts5Config)(unsafe.Pointer(pConfig)).FbContentlessDelete != 0 {
|
|
v2 = __ccgo_ts + 40205
|
|
} else {
|
|
v2 = __ccgo_ts + 40265
|
|
}
|
|
_sqlite3Fts5ConfigErrmsg(tls, pConfig, v2, libc.VaList(bp+8, __ccgo_ts+40295, (*TFts5Config)(unsafe.Pointer(pConfig)).FzName))
|
|
}
|
|
}
|
|
return rc
|
|
}
|
|
|
|
func _fts5CursorFirstSorted(tls *libc.TLS, pTab uintptr, pCsr uintptr, bDesc int32) (r int32) {
|
|
bp := tls.Alloc(64)
|
|
defer tls.Free(64)
|
|
var nByte Tsqlite3_int64
|
|
var nPhrase, rc int32
|
|
var pConfig, pSorter, zRank, zRankArgs, v1, v2, v3 uintptr
|
|
_, _, _, _, _, _, _, _, _, _ = nByte, nPhrase, pConfig, pSorter, rc, zRank, zRankArgs, v1, v2, v3
|
|
pConfig = (*TFts5FullTable)(unsafe.Pointer(pTab)).Fp.FpConfig
|
|
zRank = (*TFts5Cursor)(unsafe.Pointer(pCsr)).FzRank
|
|
zRankArgs = (*TFts5Cursor)(unsafe.Pointer(pCsr)).FzRankArgs
|
|
nPhrase = _sqlite3Fts5ExprPhraseCount(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpExpr)
|
|
nByte = libc.Int64FromUint64(uint64(libc.UintptrFromInt32(0)+24) + libc.Uint64FromInt32((nPhrase+libc.Int32FromInt32(2))/libc.Int32FromInt32(2))*libc.Uint64FromInt64(8))
|
|
pSorter = Xsqlite3_malloc64(tls, libc.Uint64FromInt64(nByte))
|
|
if pSorter == uintptr(0) {
|
|
return int32(SQLITE_NOMEM)
|
|
}
|
|
libc.Xmemset(tls, pSorter, 0, libc.Uint64FromInt64(nByte))
|
|
(*TFts5Sorter)(unsafe.Pointer(pSorter)).FnIdx = nPhrase
|
|
/* TODO: It would be better to have some system for reusing statement
|
|
** handles here, rather than preparing a new one for each query. But that
|
|
** is not possible as SQLite reference counts the virtual table objects.
|
|
** And since the statement required here reads from this very virtual
|
|
** table, saving it creates a circular reference.
|
|
**
|
|
** If SQLite a built-in statement cache, this wouldn't be a problem. */
|
|
if zRankArgs != 0 {
|
|
v1 = __ccgo_ts + 16242
|
|
} else {
|
|
v1 = __ccgo_ts + 1704
|
|
}
|
|
if zRankArgs != 0 {
|
|
v2 = zRankArgs
|
|
} else {
|
|
v2 = __ccgo_ts + 1704
|
|
}
|
|
if bDesc != 0 {
|
|
v3 = __ccgo_ts + 39779
|
|
} else {
|
|
v3 = __ccgo_ts + 39784
|
|
}
|
|
rc = _fts5PrepareStatement(tls, pSorter, pConfig, __ccgo_ts+39788, libc.VaList(bp+8, (*TFts5Config)(unsafe.Pointer(pConfig)).FzDb, (*TFts5Config)(unsafe.Pointer(pConfig)).FzName, zRank, (*TFts5Config)(unsafe.Pointer(pConfig)).FzName, v1, v2, v3))
|
|
(*TFts5Cursor)(unsafe.Pointer(pCsr)).FpSorter = pSorter
|
|
if rc == SQLITE_OK {
|
|
(*TFts5FullTable)(unsafe.Pointer(pTab)).FpSortCsr = pCsr
|
|
rc = _fts5SorterNext(tls, pCsr)
|
|
(*TFts5FullTable)(unsafe.Pointer(pTab)).FpSortCsr = uintptr(0)
|
|
}
|
|
if rc != SQLITE_OK {
|
|
Xsqlite3_finalize(tls, (*TFts5Sorter)(unsafe.Pointer(pSorter)).FpStmt)
|
|
Xsqlite3_free(tls, pSorter)
|
|
(*TFts5Cursor)(unsafe.Pointer(pCsr)).FpSorter = uintptr(0)
|
|
}
|
|
return rc
|
|
}
|
|
|
|
func _fts5CursorParseRank(tls *libc.TLS, pConfig uintptr, pCsr uintptr, pRank uintptr) (r int32) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var rc int32
|
|
var z uintptr
|
|
var _ /* zRank at bp+0 */ uintptr
|
|
var _ /* zRankArgs at bp+8 */ uintptr
|
|
_, _ = rc, z
|
|
rc = SQLITE_OK
|
|
if pRank != 0 {
|
|
z = Xsqlite3_value_text(tls, pRank)
|
|
**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
|
|
**(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0)
|
|
if z == uintptr(0) {
|
|
if Xsqlite3_value_type(tls, pRank) == int32(SQLITE_NULL) {
|
|
rc = int32(SQLITE_ERROR)
|
|
}
|
|
} else {
|
|
rc = _sqlite3Fts5ConfigParseRank(tls, z, bp, bp+8)
|
|
}
|
|
if rc == SQLITE_OK {
|
|
(*TFts5Cursor)(unsafe.Pointer(pCsr)).FzRank = **(**uintptr)(__ccgo_up(bp))
|
|
(*TFts5Cursor)(unsafe.Pointer(pCsr)).FzRankArgs = **(**uintptr)(__ccgo_up(bp + 8))
|
|
**(**int32)(__ccgo_up(pCsr + 80)) |= int32(FTS5CSR_FREE_ZRANK)
|
|
} else {
|
|
if rc == int32(SQLITE_ERROR) {
|
|
(*Tsqlite3_vtab)(unsafe.Pointer((*TFts5Cursor)(unsafe.Pointer(pCsr)).Fbase.FpVtab)).FzErrMsg = Xsqlite3_mprintf(tls, __ccgo_ts+39908, libc.VaList(bp+24, z))
|
|
}
|
|
}
|
|
} else {
|
|
if (*TFts5Config)(unsafe.Pointer(pConfig)).FzRank != 0 {
|
|
(*TFts5Cursor)(unsafe.Pointer(pCsr)).FzRank = (*TFts5Config)(unsafe.Pointer(pConfig)).FzRank
|
|
(*TFts5Cursor)(unsafe.Pointer(pCsr)).FzRankArgs = (*TFts5Config)(unsafe.Pointer(pConfig)).FzRankArgs
|
|
} else {
|
|
(*TFts5Cursor)(unsafe.Pointer(pCsr)).FzRank = __ccgo_ts + 37410
|
|
(*TFts5Cursor)(unsafe.Pointer(pCsr)).FzRankArgs = uintptr(0)
|
|
}
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Execute the following SQL:
|
|
// **
|
|
// ** DELETE FROM %_data WHERE id BETWEEN $iFirst AND $iLast
|
|
// */
|
|
func _fts5DataDelete(tls *libc.TLS, p uintptr, iFirst Ti64, iLast Ti64) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var pConfig, zSql uintptr
|
|
_, _ = pConfig, zSql
|
|
if (*TFts5Index)(unsafe.Pointer(p)).Frc != SQLITE_OK {
|
|
return
|
|
}
|
|
if (*TFts5Index)(unsafe.Pointer(p)).FpDeleter == uintptr(0) {
|
|
pConfig = (*TFts5Index)(unsafe.Pointer(p)).FpConfig
|
|
zSql = Xsqlite3_mprintf(tls, __ccgo_ts+39023, libc.VaList(bp+8, (*TFts5Config)(unsafe.Pointer(pConfig)).FzDb, (*TFts5Config)(unsafe.Pointer(pConfig)).FzName))
|
|
if _fts5IndexPrepareStmt(tls, p, p+88, zSql) != 0 {
|
|
return
|
|
}
|
|
}
|
|
Xsqlite3_bind_int64(tls, (*TFts5Index)(unsafe.Pointer(p)).FpDeleter, int32(1), iFirst)
|
|
Xsqlite3_bind_int64(tls, (*TFts5Index)(unsafe.Pointer(p)).FpDeleter, int32(2), iLast)
|
|
Xsqlite3_step(tls, (*TFts5Index)(unsafe.Pointer(p)).FpDeleter)
|
|
(*TFts5Index)(unsafe.Pointer(p)).Frc = Xsqlite3_reset(tls, (*TFts5Index)(unsafe.Pointer(p)).FpDeleter)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Retrieve a record from the %_data table.
|
|
// **
|
|
// ** If an error occurs, NULL is returned and an error left in the
|
|
// ** Fts5Index object.
|
|
// */
|
|
func _fts5DataRead(tls *libc.TLS, p uintptr, iRowid Ti64) (r uintptr) {
|
|
var aOut, pBlob, pConfig, pRet, v1 uintptr
|
|
var nAlloc, nByte, szData Ti64
|
|
var rc int32
|
|
_, _, _, _, _, _, _, _, _ = aOut, nAlloc, nByte, pBlob, pConfig, pRet, rc, szData, v1
|
|
pRet = uintptr(0)
|
|
if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
rc = SQLITE_OK
|
|
if (*TFts5Index)(unsafe.Pointer(p)).FpReader != 0 {
|
|
/* This call may return SQLITE_ABORT if there has been a savepoint
|
|
** rollback since it was last used. In this case a new blob handle
|
|
** is required. */
|
|
pBlob = (*TFts5Index)(unsafe.Pointer(p)).FpReader
|
|
(*TFts5Index)(unsafe.Pointer(p)).FpReader = uintptr(0)
|
|
rc = Xsqlite3_blob_reopen(tls, pBlob, iRowid)
|
|
(*TFts5Index)(unsafe.Pointer(p)).FpReader = pBlob
|
|
if rc != SQLITE_OK {
|
|
_fts5IndexCloseReader(tls, p)
|
|
}
|
|
if rc == int32(SQLITE_ABORT) {
|
|
rc = SQLITE_OK
|
|
}
|
|
}
|
|
/* If the blob handle is not open at this point, open it and seek
|
|
** to the requested entry. */
|
|
if (*TFts5Index)(unsafe.Pointer(p)).FpReader == uintptr(0) && rc == SQLITE_OK {
|
|
pConfig = (*TFts5Index)(unsafe.Pointer(p)).FpConfig
|
|
rc = Xsqlite3_blob_open(tls, (*TFts5Config)(unsafe.Pointer(pConfig)).Fdb, (*TFts5Config)(unsafe.Pointer(pConfig)).FzDb, (*TFts5Index)(unsafe.Pointer(p)).FzDataTbl, __ccgo_ts+38966, iRowid, 0, p+72)
|
|
}
|
|
/* If either of the sqlite3_blob_open() or sqlite3_blob_reopen() calls
|
|
** above returned SQLITE_ERROR, return SQLITE_CORRUPT_VTAB instead.
|
|
** All the reasons those functions might return SQLITE_ERROR - missing
|
|
** table, missing row, non-blob/text in block column - indicate
|
|
** backing store corruption. */
|
|
if rc == int32(SQLITE_ERROR) {
|
|
rc = _fts5IndexCorruptRowid(tls, p, iRowid)
|
|
}
|
|
if rc == SQLITE_OK {
|
|
aOut = uintptr(0) /* Read blob data into this buffer */
|
|
nByte = int64(Xsqlite3_blob_bytes(tls, (*TFts5Index)(unsafe.Pointer(p)).FpReader))
|
|
szData = libc.Int64FromUint64((libc.Uint64FromInt64(16) + libc.Uint64FromInt32(7)) & libc.Uint64FromInt32(^libc.Int32FromInt32(7)))
|
|
nAlloc = szData + nByte + int64(FTS5_DATA_PADDING)
|
|
pRet = Xsqlite3_malloc64(tls, libc.Uint64FromInt64(nAlloc))
|
|
if pRet != 0 {
|
|
(*TFts5Data)(unsafe.Pointer(pRet)).Fnn = int32(nByte)
|
|
(*TFts5Data)(unsafe.Pointer(pRet)).FszLeaf = 0
|
|
v1 = pRet + uintptr(szData)
|
|
(*TFts5Data)(unsafe.Pointer(pRet)).Fp = v1
|
|
aOut = v1
|
|
} else {
|
|
rc = int32(SQLITE_NOMEM)
|
|
}
|
|
if rc == SQLITE_OK {
|
|
rc = Xsqlite3_blob_read(tls, (*TFts5Index)(unsafe.Pointer(p)).FpReader, aOut, int32(nByte), 0)
|
|
}
|
|
if rc != SQLITE_OK {
|
|
Xsqlite3_free(tls, pRet)
|
|
pRet = uintptr(0)
|
|
} else {
|
|
**(**Tu8)(__ccgo_up((*TFts5Data)(unsafe.Pointer(pRet)).Fp + uintptr(nByte))) = uint8(0x00)
|
|
**(**Tu8)(__ccgo_up((*TFts5Data)(unsafe.Pointer(pRet)).Fp + uintptr(nByte+int64(1)))) = uint8(0x00)
|
|
}
|
|
}
|
|
(*TFts5Index)(unsafe.Pointer(p)).Frc = rc
|
|
(*TFts5Index)(unsafe.Pointer(p)).FnRead = (*TFts5Index)(unsafe.Pointer(p)).FnRead + 1
|
|
}
|
|
return pRet
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Remove all records associated with segment iSegid.
|
|
// */
|
|
func _fts5DataRemoveSegment(tls *libc.TLS, p uintptr, pSeg uintptr) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var iFirst, iLast, iTomb1, iTomb2 Ti64
|
|
var iSegid int32
|
|
var pConfig uintptr
|
|
_, _, _, _, _, _ = iFirst, iLast, iSegid, iTomb1, iTomb2, pConfig
|
|
iSegid = (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FiSegid
|
|
iFirst = int64(iSegid)<<(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(libc.Int32FromInt32(0))
|
|
iLast = int64(iSegid+libc.Int32FromInt32(1))<<(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(libc.Int32FromInt32(0)) - int64(1)
|
|
_fts5DataDelete(tls, p, iFirst, iLast)
|
|
if (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FnPgTombstone != 0 {
|
|
iTomb1 = int64(iSegid+libc.Int32FromInt32(1)<<libc.Int32FromInt32(16))<<(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(libc.Int32FromInt32(0))
|
|
iTomb2 = int64(iSegid+libc.Int32FromInt32(1)<<libc.Int32FromInt32(16))<<(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((*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FnPgTombstone-libc.Int32FromInt32(1))
|
|
_fts5DataDelete(tls, p, iTomb1, iTomb2)
|
|
}
|
|
if (*TFts5Index)(unsafe.Pointer(p)).FpIdxDeleter == uintptr(0) {
|
|
pConfig = (*TFts5Index)(unsafe.Pointer(p)).FpConfig
|
|
_fts5IndexPrepareStmt(tls, p, p+104, Xsqlite3_mprintf(tls, __ccgo_ts+39072, libc.VaList(bp+8, (*TFts5Config)(unsafe.Pointer(pConfig)).FzDb, (*TFts5Config)(unsafe.Pointer(pConfig)).FzName)))
|
|
}
|
|
if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
Xsqlite3_bind_int(tls, (*TFts5Index)(unsafe.Pointer(p)).FpIdxDeleter, int32(1), iSegid)
|
|
Xsqlite3_step(tls, (*TFts5Index)(unsafe.Pointer(p)).FpIdxDeleter)
|
|
(*TFts5Index)(unsafe.Pointer(p)).Frc = Xsqlite3_reset(tls, (*TFts5Index)(unsafe.Pointer(p)).FpIdxDeleter)
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** INSERT OR REPLACE a record into the %_data table.
|
|
// */
|
|
func _fts5DataWrite(tls *libc.TLS, p uintptr, iRowid Ti64, pData uintptr, nData int32) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var pConfig uintptr
|
|
_ = pConfig
|
|
if (*TFts5Index)(unsafe.Pointer(p)).Frc != SQLITE_OK {
|
|
return
|
|
}
|
|
if (*TFts5Index)(unsafe.Pointer(p)).FpWriter == uintptr(0) {
|
|
pConfig = (*TFts5Index)(unsafe.Pointer(p)).FpConfig
|
|
_fts5IndexPrepareStmt(tls, p, p+80, Xsqlite3_mprintf(tls, __ccgo_ts+38972, libc.VaList(bp+8, (*TFts5Config)(unsafe.Pointer(pConfig)).FzDb, (*TFts5Config)(unsafe.Pointer(pConfig)).FzName)))
|
|
if (*TFts5Index)(unsafe.Pointer(p)).Frc != 0 {
|
|
return
|
|
}
|
|
}
|
|
Xsqlite3_bind_int64(tls, (*TFts5Index)(unsafe.Pointer(p)).FpWriter, int32(1), iRowid)
|
|
Xsqlite3_bind_blob(tls, (*TFts5Index)(unsafe.Pointer(p)).FpWriter, int32(2), pData, nData, libc.UintptrFromInt32(0))
|
|
Xsqlite3_step(tls, (*TFts5Index)(unsafe.Pointer(p)).FpWriter)
|
|
(*TFts5Index)(unsafe.Pointer(p)).Frc = Xsqlite3_reset(tls, (*TFts5Index)(unsafe.Pointer(p)).FpWriter)
|
|
Xsqlite3_bind_null(tls, (*TFts5Index)(unsafe.Pointer(p)).FpWriter, int32(2))
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Argument pVal is the text of a full-text search expression. It may or
|
|
// ** may not have been wrapped by fts5_locale(). This function extracts
|
|
// ** the text of the expression, and sets output variable (*pzText) to
|
|
// ** point to a nul-terminated buffer containing the expression.
|
|
// **
|
|
// ** If pVal was an fts5_locale() value, then sqlite3Fts5SetLocale() is called
|
|
// ** to set the tokenizer to use the specified locale.
|
|
// **
|
|
// ** If output variable (*pbFreeAndReset) is set to true, then the caller
|
|
// ** is required to (a) call sqlite3Fts5ClearLocale() to reset the tokenizer
|
|
// ** locale, and (b) call sqlite3_free() to free (*pzText).
|
|
// */
|
|
func _fts5ExtractExprText(tls *libc.TLS, pConfig uintptr, pVal uintptr, pzText uintptr, pbFreeAndReset uintptr) (r int32) {
|
|
bp := tls.Alloc(64)
|
|
defer tls.Free(64)
|
|
var _ /* nLoc at bp+32 */ int32
|
|
var _ /* nText at bp+16 */ int32
|
|
var _ /* pLoc at bp+24 */ uintptr
|
|
var _ /* pText at bp+8 */ uintptr
|
|
var _ /* rc at bp+0 */ int32
|
|
**(**int32)(__ccgo_up(bp)) = SQLITE_OK
|
|
if _sqlite3Fts5IsLocaleValue(tls, pConfig, pVal) != 0 {
|
|
**(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0)
|
|
**(**int32)(__ccgo_up(bp + 16)) = 0
|
|
**(**uintptr)(__ccgo_up(bp + 24)) = uintptr(0)
|
|
**(**int32)(__ccgo_up(bp + 32)) = 0
|
|
**(**int32)(__ccgo_up(bp)) = _sqlite3Fts5DecodeLocaleValue(tls, pVal, bp+8, bp+16, bp+24, bp+32)
|
|
**(**uintptr)(__ccgo_up(pzText)) = _sqlite3Fts5Mprintf(tls, bp, __ccgo_ts+12074, libc.VaList(bp+48, **(**int32)(__ccgo_up(bp + 16)), **(**uintptr)(__ccgo_up(bp + 8))))
|
|
if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
|
|
_sqlite3Fts5SetLocale(tls, pConfig, **(**uintptr)(__ccgo_up(bp + 24)), **(**int32)(__ccgo_up(bp + 32)))
|
|
}
|
|
**(**int32)(__ccgo_up(pbFreeAndReset)) = int32(1)
|
|
} else {
|
|
**(**uintptr)(__ccgo_up(pzText)) = Xsqlite3_value_text(tls, pVal)
|
|
**(**int32)(__ccgo_up(pbFreeAndReset)) = 0
|
|
}
|
|
return **(**int32)(__ccgo_up(bp))
|
|
}
|
|
|
|
func _fts5FindRankFunction(tls *libc.TLS, pCsr uintptr) (r int32) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var i int32
|
|
var nByte Tsqlite3_int64
|
|
var pAux, pConfig, pTab, zRank, zRankArgs, zSql uintptr
|
|
var _ /* pStmt at bp+8 */ uintptr
|
|
var _ /* rc at bp+0 */ int32
|
|
_, _, _, _, _, _, _, _ = i, nByte, pAux, pConfig, pTab, zRank, zRankArgs, zSql
|
|
pTab = (*TFts5Cursor)(unsafe.Pointer(pCsr)).Fbase.FpVtab
|
|
pConfig = (*TFts5FullTable)(unsafe.Pointer(pTab)).Fp.FpConfig
|
|
**(**int32)(__ccgo_up(bp)) = SQLITE_OK
|
|
pAux = uintptr(0)
|
|
zRank = (*TFts5Cursor)(unsafe.Pointer(pCsr)).FzRank
|
|
zRankArgs = (*TFts5Cursor)(unsafe.Pointer(pCsr)).FzRankArgs
|
|
if zRankArgs != 0 {
|
|
zSql = _sqlite3Fts5Mprintf(tls, bp, __ccgo_ts+39877, libc.VaList(bp+24, zRankArgs))
|
|
if zSql != 0 {
|
|
**(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0)
|
|
**(**int32)(__ccgo_up(bp)) = Xsqlite3_prepare_v3(tls, (*TFts5Config)(unsafe.Pointer(pConfig)).Fdb, zSql, -int32(1), uint32(SQLITE_PREPARE_PERSISTENT), bp+8, uintptr(0))
|
|
Xsqlite3_free(tls, zSql)
|
|
if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
|
|
if int32(SQLITE_ROW) == Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp + 8))) {
|
|
(*TFts5Cursor)(unsafe.Pointer(pCsr)).FnRankArg = Xsqlite3_column_count(tls, **(**uintptr)(__ccgo_up(bp + 8)))
|
|
nByte = libc.Int64FromUint64(uint64(8) * libc.Uint64FromInt32((*TFts5Cursor)(unsafe.Pointer(pCsr)).FnRankArg))
|
|
(*TFts5Cursor)(unsafe.Pointer(pCsr)).FapRankArg = _sqlite3Fts5MallocZero(tls, bp, nByte)
|
|
if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
|
|
i = 0
|
|
for {
|
|
if !(i < (*TFts5Cursor)(unsafe.Pointer(pCsr)).FnRankArg) {
|
|
break
|
|
}
|
|
**(**uintptr)(__ccgo_up((*TFts5Cursor)(unsafe.Pointer(pCsr)).FapRankArg + uintptr(i)*8)) = Xsqlite3_column_value(tls, **(**uintptr)(__ccgo_up(bp + 8)), i)
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
}
|
|
(*TFts5Cursor)(unsafe.Pointer(pCsr)).FpRankArgStmt = **(**uintptr)(__ccgo_up(bp + 8))
|
|
} else {
|
|
**(**int32)(__ccgo_up(bp)) = Xsqlite3_finalize(tls, **(**uintptr)(__ccgo_up(bp + 8)))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
|
|
pAux = _fts5FindAuxiliary(tls, pTab, zRank)
|
|
if pAux == uintptr(0) {
|
|
(*TFts5FullTable)(unsafe.Pointer(pTab)).Fp.Fbase.FzErrMsg = Xsqlite3_mprintf(tls, __ccgo_ts+39887, libc.VaList(bp+24, zRank))
|
|
**(**int32)(__ccgo_up(bp)) = int32(SQLITE_ERROR)
|
|
}
|
|
}
|
|
(*TFts5Cursor)(unsafe.Pointer(pCsr)).FpRank = pAux
|
|
return **(**int32)(__ccgo_up(bp))
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This is called as part of flushing a delete to disk in 'secure-delete'
|
|
// ** mode. It edits the segments within the database described by argument
|
|
// ** pStruct to remove the entries for term zTerm, rowid iRowid.
|
|
// **
|
|
// ** Return SQLITE_OK if successful, or an SQLite error code if an error
|
|
// ** has occurred. Any error code is also stored in the Fts5Index handle.
|
|
// */
|
|
func _fts5FlushSecureDelete(tls *libc.TLS, p uintptr, pStruct uintptr, zTerm uintptr, nTerm int32, iRowid Ti64) (r int32) {
|
|
bp := tls.Alloc(48)
|
|
defer tls.Free(48)
|
|
var f, rc int32
|
|
var iThis Ti64
|
|
var pConfig, pSeg uintptr
|
|
var _ /* pIter at bp+0 */ uintptr
|
|
var _ /* pStmt at bp+8 */ uintptr
|
|
_, _, _, _, _ = f, iThis, pConfig, pSeg, rc
|
|
f = int32(FTS5INDEX_QUERY_SKIPHASH)
|
|
**(**uintptr)(__ccgo_up(bp)) = uintptr(0) /* Used to find term instance */
|
|
/* If the version number has not been set to SECUREDELETE, do so now. */
|
|
if (*TFts5Config)(unsafe.Pointer((*TFts5Index)(unsafe.Pointer(p)).FpConfig)).FiVersion != int32(FTS5_CURRENT_VERSION_SECUREDELETE) {
|
|
pConfig = (*TFts5Index)(unsafe.Pointer(p)).FpConfig
|
|
**(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0)
|
|
_fts5IndexPrepareStmt(tls, p, bp+8, Xsqlite3_mprintf(tls, __ccgo_ts+39470, libc.VaList(bp+24, (*TFts5Config)(unsafe.Pointer(pConfig)).FzDb, (*TFts5Config)(unsafe.Pointer(pConfig)).FzName, int32(FTS5_CURRENT_VERSION_SECUREDELETE))))
|
|
if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp + 8)))
|
|
rc = Xsqlite3_finalize(tls, **(**uintptr)(__ccgo_up(bp + 8)))
|
|
if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
(*TFts5Index)(unsafe.Pointer(p)).Frc = rc
|
|
}
|
|
(*TFts5Config)(unsafe.Pointer(pConfig)).FiCookie = (*TFts5Config)(unsafe.Pointer(pConfig)).FiCookie + 1
|
|
(*TFts5Config)(unsafe.Pointer(pConfig)).FiVersion = int32(FTS5_CURRENT_VERSION_SECUREDELETE)
|
|
}
|
|
}
|
|
_fts5MultiIterNew(tls, p, pStruct, f, uintptr(0), zTerm, nTerm, -int32(1), 0, bp)
|
|
if _fts5MultiIterEof(tls, p, **(**uintptr)(__ccgo_up(bp))) == 0 {
|
|
iThis = _fts5MultiIterRowid(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
if iThis < iRowid {
|
|
_fts5MultiIterNextFrom(tls, p, **(**uintptr)(__ccgo_up(bp)), iRowid)
|
|
}
|
|
if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK && _fts5MultiIterEof(tls, p, **(**uintptr)(__ccgo_up(bp))) == 0 && iRowid == _fts5MultiIterRowid(tls, **(**uintptr)(__ccgo_up(bp))) {
|
|
pSeg = **(**uintptr)(__ccgo_up(bp)) + 104 + uintptr((**(**TFts5CResult)(__ccgo_up((*TFts5Iter)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FaFirst + 1*4))).FiFirst)*128
|
|
_fts5DoSecureDelete(tls, p, pSeg)
|
|
}
|
|
}
|
|
_fts5MultiIterFree(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
return (*TFts5Index)(unsafe.Pointer(p)).Frc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Implementation of fts5_get_locale() function.
|
|
// */
|
|
func _fts5GetLocaleFunction(tls *libc.TLS, pApi uintptr, pFts uintptr, pCtx uintptr, nVal int32, apVal uintptr) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var eType, iCol, rc int32
|
|
var z, z1 uintptr
|
|
var _ /* nLocale at bp+8 */ int32
|
|
var _ /* zLocale at bp+0 */ uintptr
|
|
_, _, _, _, _ = eType, iCol, rc, z, z1
|
|
iCol = 0
|
|
eType = 0
|
|
rc = SQLITE_OK
|
|
**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
|
|
**(**int32)(__ccgo_up(bp + 8)) = 0
|
|
/* xColumnLocale() must be available */
|
|
if nVal != int32(1) {
|
|
z = __ccgo_ts + 37278
|
|
Xsqlite3_result_error(tls, pCtx, z, -int32(1))
|
|
return
|
|
}
|
|
eType = Xsqlite3_value_numeric_type(tls, **(**uintptr)(__ccgo_up(apVal)))
|
|
if eType != int32(SQLITE_INTEGER) {
|
|
z1 = __ccgo_ts + 37334
|
|
Xsqlite3_result_error(tls, pCtx, z1, -int32(1))
|
|
return
|
|
}
|
|
iCol = Xsqlite3_value_int(tls, **(**uintptr)(__ccgo_up(apVal)))
|
|
if iCol < 0 || iCol >= (*(*func(*libc.TLS, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*TFts5ExtensionApi)(unsafe.Pointer(pApi)).FxColumnCount})))(tls, pFts) {
|
|
Xsqlite3_result_error_code(tls, pCtx, int32(SQLITE_RANGE))
|
|
return
|
|
}
|
|
rc = (*(*func(*libc.TLS, uintptr, int32, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*TFts5ExtensionApi)(unsafe.Pointer(pApi)).FxColumnLocale})))(tls, pFts, iCol, bp, bp+8)
|
|
if rc != SQLITE_OK {
|
|
Xsqlite3_result_error_code(tls, pCtx, rc)
|
|
return
|
|
}
|
|
Xsqlite3_result_text(tls, pCtx, **(**uintptr)(__ccgo_up(bp)), **(**int32)(__ccgo_up(bp + 8)), uintptr(-libc.Int32FromInt32(1)))
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Append text to the HighlightContext output string - p->zOut. Argument
|
|
// ** z points to a buffer containing n bytes of text to append. If n is
|
|
// ** negative, everything up until the first '\0' is appended to the output.
|
|
// **
|
|
// ** If *pRc is set to any value other than SQLITE_OK when this function is
|
|
// ** called, it is a no-op. If an error (i.e. an OOM condition) is encountered,
|
|
// ** *pRc is set to an error code before returning.
|
|
// */
|
|
func _fts5HighlightAppend(tls *libc.TLS, pRc uintptr, p uintptr, z uintptr, n int32) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
if **(**int32)(__ccgo_up(pRc)) == SQLITE_OK && z != 0 {
|
|
if n < 0 {
|
|
n = libc.Int32FromUint64(libc.Xstrlen(tls, z))
|
|
}
|
|
(*THighlightContext)(unsafe.Pointer(p)).FzOut = Xsqlite3_mprintf(tls, __ccgo_ts+37173, libc.VaList(bp+8, (*THighlightContext)(unsafe.Pointer(p)).FzOut, n, z))
|
|
if (*THighlightContext)(unsafe.Pointer(p)).FzOut == uintptr(0) {
|
|
**(**int32)(__ccgo_up(pRc)) = int32(SQLITE_NOMEM)
|
|
}
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Implementation of highlight() function.
|
|
// */
|
|
func _fts5HighlightFunction(tls *libc.TLS, pApi uintptr, pFts uintptr, pCtx uintptr, nVal int32, apVal uintptr) {
|
|
bp := tls.Alloc(128)
|
|
defer tls.Free(128)
|
|
var iCol int32
|
|
var zErr uintptr
|
|
var _ /* ctx at bp+0 */ THighlightContext
|
|
var _ /* nLoc at bp+120 */ int32
|
|
var _ /* pLoc at bp+112 */ uintptr
|
|
var _ /* rc at bp+104 */ int32
|
|
_, _ = iCol, zErr
|
|
if nVal != int32(3) {
|
|
zErr = __ccgo_ts + 37180
|
|
Xsqlite3_result_error(tls, pCtx, zErr, -int32(1))
|
|
return
|
|
}
|
|
iCol = Xsqlite3_value_int(tls, **(**uintptr)(__ccgo_up(apVal)))
|
|
libc.Xmemset(tls, bp, 0, uint64(104))
|
|
(**(**THighlightContext)(__ccgo_up(bp))).FzOpen = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(apVal + 1*8)))
|
|
(**(**THighlightContext)(__ccgo_up(bp))).FzClose = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(apVal + 2*8)))
|
|
(**(**THighlightContext)(__ccgo_up(bp))).FiRangeEnd = -int32(1)
|
|
**(**int32)(__ccgo_up(bp + 104)) = (*(*func(*libc.TLS, uintptr, int32, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*TFts5ExtensionApi)(unsafe.Pointer(pApi)).FxColumnText})))(tls, pFts, iCol, bp+24, bp+32)
|
|
if **(**int32)(__ccgo_up(bp + 104)) == int32(SQLITE_RANGE) {
|
|
Xsqlite3_result_text(tls, pCtx, __ccgo_ts+1704, -int32(1), libc.UintptrFromInt32(0))
|
|
**(**int32)(__ccgo_up(bp + 104)) = SQLITE_OK
|
|
} else {
|
|
if (**(**THighlightContext)(__ccgo_up(bp))).FzIn != 0 {
|
|
**(**uintptr)(__ccgo_up(bp + 112)) = uintptr(0) /* Locale of column iCol */
|
|
**(**int32)(__ccgo_up(bp + 120)) = 0 /* Size of pLoc in bytes */
|
|
if **(**int32)(__ccgo_up(bp + 104)) == SQLITE_OK {
|
|
**(**int32)(__ccgo_up(bp + 104)) = _fts5CInstIterInit(tls, pApi, pFts, iCol, bp+40)
|
|
}
|
|
if **(**int32)(__ccgo_up(bp + 104)) == SQLITE_OK {
|
|
**(**int32)(__ccgo_up(bp + 104)) = (*(*func(*libc.TLS, uintptr, int32, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*TFts5ExtensionApi)(unsafe.Pointer(pApi)).FxColumnLocale})))(tls, pFts, iCol, bp+112, bp+120)
|
|
}
|
|
if **(**int32)(__ccgo_up(bp + 104)) == SQLITE_OK {
|
|
**(**int32)(__ccgo_up(bp + 104)) = (*(*func(*libc.TLS, uintptr, uintptr, int32, uintptr, int32, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*TFts5ExtensionApi)(unsafe.Pointer(pApi)).FxTokenize_v2})))(tls, pFts, (**(**THighlightContext)(__ccgo_up(bp))).FzIn, (**(**THighlightContext)(__ccgo_up(bp))).FnIn, **(**uintptr)(__ccgo_up(bp + 112)), **(**int32)(__ccgo_up(bp + 120)), bp, __ccgo_fp(_fts5HighlightCb))
|
|
}
|
|
if (**(**THighlightContext)(__ccgo_up(bp))).FbOpen != 0 {
|
|
_fts5HighlightAppend(tls, bp+104, bp, (**(**THighlightContext)(__ccgo_up(bp))).FzClose, -int32(1))
|
|
}
|
|
_fts5HighlightAppend(tls, bp+104, bp, (**(**THighlightContext)(__ccgo_up(bp))).FzIn+uintptr((**(**THighlightContext)(__ccgo_up(bp))).FiOff), (**(**THighlightContext)(__ccgo_up(bp))).FnIn-(**(**THighlightContext)(__ccgo_up(bp))).FiOff)
|
|
if **(**int32)(__ccgo_up(bp + 104)) == SQLITE_OK {
|
|
Xsqlite3_result_text(tls, pCtx, (**(**THighlightContext)(__ccgo_up(bp))).FzOut, -int32(1), uintptr(-libc.Int32FromInt32(1)))
|
|
}
|
|
Xsqlite3_free(tls, (**(**THighlightContext)(__ccgo_up(bp))).FzOut)
|
|
}
|
|
}
|
|
if **(**int32)(__ccgo_up(bp + 104)) != SQLITE_OK {
|
|
Xsqlite3_result_error_code(tls, pCtx, **(**int32)(__ccgo_up(bp + 104)))
|
|
}
|
|
}
|
|
|
|
/*
|
|
** End of highlight() implementation.
|
|
**************************************************************************/
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** SQL used by fts5SegIterNextInit() to find the page to open.
|
|
// */
|
|
func _fts5IdxNextStmt(tls *libc.TLS, p uintptr) (r uintptr) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var pConfig uintptr
|
|
_ = pConfig
|
|
if (*TFts5Index)(unsafe.Pointer(p)).FpIdxNextSelect == uintptr(0) {
|
|
pConfig = (*TFts5Index)(unsafe.Pointer(p)).FpConfig
|
|
_fts5IndexPrepareStmt(tls, p, p+120, Xsqlite3_mprintf(tls, __ccgo_ts+39270, libc.VaList(bp+8, (*TFts5Config)(unsafe.Pointer(pConfig)).FzDb, (*TFts5Config)(unsafe.Pointer(pConfig)).FzName)))
|
|
}
|
|
return (*TFts5Index)(unsafe.Pointer(p)).FpIdxNextSelect
|
|
}
|
|
|
|
func _fts5IdxSelectStmt(tls *libc.TLS, p uintptr) (r uintptr) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var pConfig uintptr
|
|
_ = pConfig
|
|
if (*TFts5Index)(unsafe.Pointer(p)).FpIdxSelect == uintptr(0) {
|
|
pConfig = (*TFts5Index)(unsafe.Pointer(p)).FpConfig
|
|
_fts5IndexPrepareStmt(tls, p, p+112, Xsqlite3_mprintf(tls, __ccgo_ts+39186, libc.VaList(bp+8, (*TFts5Config)(unsafe.Pointer(pConfig)).FzDb, (*TFts5Config)(unsafe.Pointer(pConfig)).FzName)))
|
|
}
|
|
return (*TFts5Index)(unsafe.Pointer(p)).FpIdxSelect
|
|
}
|
|
|
|
func _fts5IndexDataVersion(tls *libc.TLS, p uintptr) (r Ti64) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var iVersion Ti64
|
|
_ = iVersion
|
|
iVersion = 0
|
|
if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
if (*TFts5Index)(unsafe.Pointer(p)).FpDataVersion == uintptr(0) {
|
|
(*TFts5Index)(unsafe.Pointer(p)).Frc = _fts5IndexPrepareStmt(tls, p, p+144, Xsqlite3_mprintf(tls, __ccgo_ts+39163, libc.VaList(bp+8, (*TFts5Config)(unsafe.Pointer((*TFts5Index)(unsafe.Pointer(p)).FpConfig)).FzDb)))
|
|
if (*TFts5Index)(unsafe.Pointer(p)).Frc != 0 {
|
|
return 0
|
|
}
|
|
}
|
|
if int32(SQLITE_ROW) == Xsqlite3_step(tls, (*TFts5Index)(unsafe.Pointer(p)).FpDataVersion) {
|
|
iVersion = Xsqlite3_column_int64(tls, (*TFts5Index)(unsafe.Pointer(p)).FpDataVersion, 0)
|
|
}
|
|
(*TFts5Index)(unsafe.Pointer(p)).Frc = Xsqlite3_reset(tls, (*TFts5Index)(unsafe.Pointer(p)).FpDataVersion)
|
|
}
|
|
return iVersion
|
|
}
|
|
|
|
func _fts5IndexIntegrityCheckSegment(tls *libc.TLS, p uintptr, pSeg uintptr) {
|
|
bp := tls.Alloc(64)
|
|
defer tls.Free(64)
|
|
var bIdxDlidx, bSecureDelete, iDlidxPrevLeaf, iIdxLeaf, iIdxPrevLeaf, iOff, iPg, iPrevLeaf, iRowidOff, iRowidOff1, iSegid, nIdxTerm, rc2, res, v1, v2, v3 int32
|
|
var iDlRowid, iKey, iRow Ti64
|
|
var pConfig, pDlidx, pLeaf, zIdxTerm uintptr
|
|
var _ /* iRowid at bp+16 */ Ti64
|
|
var _ /* nTerm at bp+8 */ int32
|
|
var _ /* pStmt at bp+0 */ uintptr
|
|
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = bIdxDlidx, bSecureDelete, iDlRowid, iDlidxPrevLeaf, iIdxLeaf, iIdxPrevLeaf, iKey, iOff, iPg, iPrevLeaf, iRow, iRowidOff, iRowidOff1, iSegid, nIdxTerm, pConfig, pDlidx, pLeaf, rc2, res, zIdxTerm, v1, v2, v3
|
|
pConfig = (*TFts5Index)(unsafe.Pointer(p)).FpConfig
|
|
bSecureDelete = libc.BoolInt32((*TFts5Config)(unsafe.Pointer(pConfig)).FiVersion == int32(FTS5_CURRENT_VERSION_SECUREDELETE))
|
|
**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
|
|
iIdxPrevLeaf = (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FpgnoFirst - int32(1)
|
|
iDlidxPrevLeaf = (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FpgnoLast
|
|
if (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FpgnoFirst == 0 {
|
|
return
|
|
}
|
|
_fts5IndexPrepareStmt(tls, p, bp, Xsqlite3_mprintf(tls, __ccgo_ts+39610, libc.VaList(bp+32, (*TFts5Config)(unsafe.Pointer(pConfig)).FzDb, (*TFts5Config)(unsafe.Pointer(pConfig)).FzName, (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FiSegid)))
|
|
/* Iterate through the b-tree hierarchy. */
|
|
for (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK && int32(SQLITE_ROW) == Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp))) { /* Data for this leaf */
|
|
zIdxTerm = Xsqlite3_column_blob(tls, **(**uintptr)(__ccgo_up(bp)), int32(1))
|
|
nIdxTerm = Xsqlite3_column_bytes(tls, **(**uintptr)(__ccgo_up(bp)), int32(1))
|
|
iIdxLeaf = Xsqlite3_column_int(tls, **(**uintptr)(__ccgo_up(bp)), int32(2))
|
|
bIdxDlidx = Xsqlite3_column_int(tls, **(**uintptr)(__ccgo_up(bp)), int32(3))
|
|
/* If the leaf in question has already been trimmed from the segment,
|
|
** ignore this b-tree entry. Otherwise, load it into memory. */
|
|
if iIdxLeaf < (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FpgnoFirst {
|
|
continue
|
|
}
|
|
iRow = 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(iIdxLeaf)
|
|
pLeaf = _fts5LeafRead(tls, p, iRow)
|
|
if pLeaf == uintptr(0) {
|
|
break
|
|
}
|
|
/* Check that the leaf contains at least one term, and that it is equal
|
|
** to or larger than the split-key in zIdxTerm. Also check that if there
|
|
** is also a rowid pointer within the leaf page header, it points to a
|
|
** location before the term. */
|
|
if (*TFts5Data)(unsafe.Pointer(pLeaf)).Fnn <= (*TFts5Data)(unsafe.Pointer(pLeaf)).FszLeaf {
|
|
if nIdxTerm == 0 && (*TFts5Config)(unsafe.Pointer(pConfig)).FiVersion == int32(FTS5_CURRENT_VERSION_SECUREDELETE) && (*TFts5Data)(unsafe.Pointer(pLeaf)).Fnn == (*TFts5Data)(unsafe.Pointer(pLeaf)).FszLeaf && (*TFts5Data)(unsafe.Pointer(pLeaf)).Fnn == int32(4) {
|
|
/* special case - the very first page in a segment keeps its %_idx
|
|
** entry even if all the terms are removed from it by secure-delete
|
|
** operations. */
|
|
} else {
|
|
_fts5IndexCorruptRowid(tls, p, iRow)
|
|
}
|
|
} else { /* Comparison of term and split-key */
|
|
iOff = _fts5LeafFirstTermOff(tls, pLeaf)
|
|
iRowidOff = libc.Int32FromUint16(_fts5GetU16(tls, (*TFts5Data)(unsafe.Pointer(pLeaf)).Fp))
|
|
if iRowidOff >= iOff || iOff >= (*TFts5Data)(unsafe.Pointer(pLeaf)).FszLeaf {
|
|
_fts5IndexCorruptRowid(tls, p, iRow)
|
|
} else {
|
|
iOff = iOff + _sqlite3Fts5GetVarint32(tls, (*TFts5Data)(unsafe.Pointer(pLeaf)).Fp+uintptr(iOff), bp+8)
|
|
if int64(iOff)+int64(**(**int32)(__ccgo_up(bp + 8))) > int64((*TFts5Data)(unsafe.Pointer(pLeaf)).FszLeaf) {
|
|
_fts5IndexCorruptRowid(tls, p, iRow)
|
|
} else {
|
|
if **(**int32)(__ccgo_up(bp + 8)) < nIdxTerm {
|
|
v2 = **(**int32)(__ccgo_up(bp + 8))
|
|
} else {
|
|
v2 = nIdxTerm
|
|
}
|
|
if v2 <= 0 {
|
|
v1 = 0
|
|
} else {
|
|
if **(**int32)(__ccgo_up(bp + 8)) < nIdxTerm {
|
|
v3 = **(**int32)(__ccgo_up(bp + 8))
|
|
} else {
|
|
v3 = nIdxTerm
|
|
}
|
|
v1 = libc.Xmemcmp(tls, (*TFts5Data)(unsafe.Pointer(pLeaf)).Fp+uintptr(iOff), zIdxTerm, libc.Uint64FromInt32(v3))
|
|
}
|
|
res = v1
|
|
if res == 0 {
|
|
res = **(**int32)(__ccgo_up(bp + 8)) - nIdxTerm
|
|
}
|
|
if res < 0 {
|
|
_fts5IndexCorruptRowid(tls, p, iRow)
|
|
}
|
|
}
|
|
}
|
|
_fts5IntegrityCheckPgidx(tls, p, iRow, pLeaf)
|
|
}
|
|
_fts5DataRelease(tls, pLeaf)
|
|
if (*TFts5Index)(unsafe.Pointer(p)).Frc != 0 {
|
|
break
|
|
}
|
|
/* Now check that the iter.nEmpty leaves following the current leaf
|
|
** (a) exist and (b) contain no terms. */
|
|
_fts5IndexIntegrityCheckEmpty(tls, p, pSeg, iIdxPrevLeaf+int32(1), iDlidxPrevLeaf+int32(1), iIdxLeaf-int32(1))
|
|
if (*TFts5Index)(unsafe.Pointer(p)).Frc != 0 {
|
|
break
|
|
}
|
|
/* If there is a doclist-index, check that it looks right. */
|
|
if bIdxDlidx != 0 {
|
|
pDlidx = uintptr(0) /* For iterating through doclist index */
|
|
iPrevLeaf = iIdxLeaf
|
|
iSegid = (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FiSegid
|
|
iPg = 0
|
|
pDlidx = _fts5DlidxIterInit(tls, p, 0, iSegid, iIdxLeaf)
|
|
for {
|
|
if !(_fts5DlidxIterEof(tls, p, pDlidx) == 0) {
|
|
break
|
|
}
|
|
/* Check any rowid-less pages that occur before the current leaf. */
|
|
iPg = iPrevLeaf + int32(1)
|
|
for {
|
|
if !(iPg < _fts5DlidxIterPgno(tls, pDlidx)) {
|
|
break
|
|
}
|
|
iKey = int64(iSegid)<<(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(iPg)
|
|
pLeaf = _fts5LeafRead(tls, p, iKey)
|
|
if pLeaf != 0 {
|
|
if libc.Int32FromUint16(_fts5GetU16(tls, (*TFts5Data)(unsafe.Pointer(pLeaf)).Fp)) != 0 {
|
|
_fts5IndexCorruptRowid(tls, p, iKey)
|
|
}
|
|
_fts5DataRelease(tls, pLeaf)
|
|
}
|
|
goto _5
|
|
_5:
|
|
;
|
|
iPg = iPg + 1
|
|
}
|
|
iPrevLeaf = _fts5DlidxIterPgno(tls, pDlidx)
|
|
/* Check that the leaf page indicated by the iterator really does
|
|
** contain the rowid suggested by the same. */
|
|
iKey = int64(iSegid)<<(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(iPrevLeaf)
|
|
pLeaf = _fts5LeafRead(tls, p, iKey)
|
|
if pLeaf != 0 {
|
|
iRowidOff1 = libc.Int32FromUint16(_fts5GetU16(tls, (*TFts5Data)(unsafe.Pointer(pLeaf)).Fp))
|
|
if iRowidOff1 >= (*TFts5Data)(unsafe.Pointer(pLeaf)).FszLeaf {
|
|
_fts5IndexCorruptRowid(tls, p, iKey)
|
|
} else {
|
|
if bSecureDelete == 0 || iRowidOff1 > 0 {
|
|
iDlRowid = _fts5DlidxIterRowid(tls, pDlidx)
|
|
_sqlite3Fts5GetVarint(tls, (*TFts5Data)(unsafe.Pointer(pLeaf)).Fp+uintptr(iRowidOff1), bp+16)
|
|
if **(**Ti64)(__ccgo_up(bp + 16)) < iDlRowid || bSecureDelete == 0 && **(**Ti64)(__ccgo_up(bp + 16)) != iDlRowid {
|
|
_fts5IndexCorruptRowid(tls, p, iKey)
|
|
}
|
|
}
|
|
}
|
|
_fts5DataRelease(tls, pLeaf)
|
|
}
|
|
goto _4
|
|
_4:
|
|
;
|
|
_fts5DlidxIterNext(tls, p, pDlidx)
|
|
}
|
|
iDlidxPrevLeaf = iPg
|
|
_fts5DlidxIterFree(tls, pDlidx)
|
|
} else {
|
|
iDlidxPrevLeaf = (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FpgnoLast
|
|
/* TODO: Check there is no doclist index */
|
|
}
|
|
iIdxPrevLeaf = iIdxLeaf
|
|
}
|
|
rc2 = Xsqlite3_finalize(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
(*TFts5Index)(unsafe.Pointer(p)).Frc = rc2
|
|
}
|
|
/* Page iter.iLeaf must now be the rightmost leaf-page in the segment */
|
|
}
|
|
|
|
func _fts5Init(tls *libc.TLS, db uintptr) (r int32) {
|
|
var p, pGlobal uintptr
|
|
var rc int32
|
|
_, _, _ = p, pGlobal, rc
|
|
pGlobal = uintptr(0)
|
|
pGlobal = Xsqlite3_malloc64(tls, uint64(112))
|
|
if pGlobal == uintptr(0) {
|
|
rc = int32(SQLITE_NOMEM)
|
|
} else {
|
|
p = pGlobal
|
|
libc.Xmemset(tls, pGlobal, 0, uint64(112))
|
|
(*TFts5Global)(unsafe.Pointer(pGlobal)).Fdb = db
|
|
(*TFts5Global)(unsafe.Pointer(pGlobal)).Fapi.FiVersion = int32(3)
|
|
(*TFts5Global)(unsafe.Pointer(pGlobal)).Fapi.FxCreateFunction = __ccgo_fp(_fts5CreateAux)
|
|
(*TFts5Global)(unsafe.Pointer(pGlobal)).Fapi.FxCreateTokenizer = __ccgo_fp(_fts5CreateTokenizer)
|
|
(*TFts5Global)(unsafe.Pointer(pGlobal)).Fapi.FxFindTokenizer = __ccgo_fp(_fts5FindTokenizer)
|
|
(*TFts5Global)(unsafe.Pointer(pGlobal)).Fapi.FxCreateTokenizer_v2 = __ccgo_fp(_fts5CreateTokenizer_v2)
|
|
(*TFts5Global)(unsafe.Pointer(pGlobal)).Fapi.FxFindTokenizer_v2 = __ccgo_fp(_fts5FindTokenizer_v2)
|
|
/* Initialize pGlobal->aLocaleHdr[] to a 128-bit pseudo-random vector.
|
|
** The constants below were generated randomly. */
|
|
Xsqlite3_randomness(tls, int32(16), pGlobal+96)
|
|
**(**Tu32)(__ccgo_up(pGlobal + 96)) ^= uint32(0xF924976D)
|
|
**(**Tu32)(__ccgo_up(pGlobal + 96 + 1*4)) ^= uint32(0x16596E13)
|
|
**(**Tu32)(__ccgo_up(pGlobal + 96 + 2*4)) ^= uint32(0x7C80BEAA)
|
|
**(**Tu32)(__ccgo_up(pGlobal + 96 + 3*4)) ^= uint32(0x9B03A67F)
|
|
rc = Xsqlite3_create_module_v2(tls, db, __ccgo_ts+40740, uintptr(unsafe.Pointer(&_fts5Mod)), p, __ccgo_fp(_fts5ModuleDestroy))
|
|
if rc == SQLITE_OK {
|
|
rc = _sqlite3Fts5IndexInit(tls, db)
|
|
}
|
|
if rc == SQLITE_OK {
|
|
rc = _sqlite3Fts5ExprInit(tls, pGlobal, db)
|
|
}
|
|
if rc == SQLITE_OK {
|
|
rc = _sqlite3Fts5AuxInit(tls, pGlobal)
|
|
}
|
|
if rc == SQLITE_OK {
|
|
rc = _sqlite3Fts5TokenizerInit(tls, pGlobal)
|
|
}
|
|
if rc == SQLITE_OK {
|
|
rc = _sqlite3Fts5VocabInit(tls, pGlobal, db)
|
|
}
|
|
if rc == SQLITE_OK {
|
|
rc = Xsqlite3_create_function(tls, db, __ccgo_ts+40740, int32(1), int32(SQLITE_UTF8), p, __ccgo_fp(_fts5Fts5Func), uintptr(0), uintptr(0))
|
|
}
|
|
if rc == SQLITE_OK {
|
|
rc = Xsqlite3_create_function(tls, db, __ccgo_ts+40745, 0, libc.Int32FromInt32(SQLITE_UTF8)|libc.Int32FromInt32(SQLITE_DETERMINISTIC)|libc.Int32FromInt32(SQLITE_INNOCUOUS), p, __ccgo_fp(_fts5SourceIdFunc), uintptr(0), uintptr(0))
|
|
}
|
|
if rc == SQLITE_OK {
|
|
rc = Xsqlite3_create_function(tls, db, __ccgo_ts+40760, int32(2), libc.Int32FromInt32(SQLITE_UTF8)|libc.Int32FromInt32(SQLITE_INNOCUOUS)|libc.Int32FromInt32(SQLITE_RESULT_SUBTYPE)|libc.Int32FromInt32(SQLITE_SUBTYPE), p, __ccgo_fp(_fts5LocaleFunc), uintptr(0), uintptr(0))
|
|
}
|
|
if rc == SQLITE_OK {
|
|
rc = Xsqlite3_create_function(tls, db, __ccgo_ts+40772, int32(1), libc.Int32FromInt32(SQLITE_UTF8)|libc.Int32FromInt32(SQLITE_INNOCUOUS)|libc.Int32FromInt32(SQLITE_RESULT_SUBTYPE), p, __ccgo_fp(_fts5InsttokenFunc), uintptr(0), uintptr(0))
|
|
}
|
|
}
|
|
/* If SQLITE_FTS5_ENABLE_TEST_MI is defined, assume that the file
|
|
** fts5_test_mi.c is compiled and linked into the executable. And call
|
|
** its entry point to enable the matchinfo() demo. */
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Advance the cursor to the next row in the table that matches the
|
|
// ** search criteria.
|
|
// **
|
|
// ** Return SQLITE_OK if nothing goes wrong. SQLITE_OK is returned
|
|
// ** even if we reach end-of-file. The fts5EofMethod() will be called
|
|
// ** subsequently to determine whether or not an EOF was hit.
|
|
// */
|
|
func _fts5NextMethod(tls *libc.TLS, pCursor uintptr) (r int32) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var pConfig, pCsr uintptr
|
|
var rc, v1 int32
|
|
var _ /* bSkip at bp+0 */ int32
|
|
_, _, _, _ = pConfig, pCsr, rc, v1
|
|
pCsr = pCursor
|
|
/* If this cursor uses FTS5_PLAN_MATCH and this is a tokendata=1 table,
|
|
** clear any token mappings accumulated at the fts5_index.c level. In
|
|
** other cases, specifically FTS5_PLAN_SOURCE and FTS5_PLAN_SORTED_MATCH,
|
|
** we need to retain the mappings for the entire query. */
|
|
if (*TFts5Cursor)(unsafe.Pointer(pCsr)).FePlan == int32(FTS5_PLAN_MATCH) && (*TFts5Config)(unsafe.Pointer((*TFts5Table)(unsafe.Pointer((*Tsqlite3_vtab_cursor)(unsafe.Pointer(pCursor)).FpVtab)).FpConfig)).FbTokendata != 0 {
|
|
_sqlite3Fts5ExprClearTokens(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpExpr)
|
|
}
|
|
if (*TFts5Cursor)(unsafe.Pointer(pCsr)).FePlan < int32(3) {
|
|
**(**int32)(__ccgo_up(bp)) = 0
|
|
v1 = _fts5CursorReseek(tls, pCsr, bp)
|
|
rc = v1
|
|
if v1 != 0 || **(**int32)(__ccgo_up(bp)) != 0 {
|
|
return rc
|
|
}
|
|
rc = _sqlite3Fts5ExprNext(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpExpr, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FiLastRowid)
|
|
**(**int32)(__ccgo_up(pCsr + 80)) |= _sqlite3Fts5ExprEof(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpExpr)
|
|
_fts5CsrNewrow(tls, pCsr)
|
|
} else {
|
|
switch (*TFts5Cursor)(unsafe.Pointer(pCsr)).FePlan {
|
|
case int32(FTS5_PLAN_SPECIAL):
|
|
**(**int32)(__ccgo_up(pCsr + 80)) |= int32(FTS5CSR_EOF)
|
|
rc = SQLITE_OK
|
|
case int32(FTS5_PLAN_SORTED_MATCH):
|
|
rc = _fts5SorterNext(tls, pCsr)
|
|
default:
|
|
pConfig = (*TFts5Table)(unsafe.Pointer((*Tsqlite3_vtab_cursor)(unsafe.Pointer(pCursor)).FpVtab)).FpConfig
|
|
(*TFts5Config)(unsafe.Pointer(pConfig)).FbLock = (*TFts5Config)(unsafe.Pointer(pConfig)).FbLock + 1
|
|
rc = Xsqlite3_step(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpStmt)
|
|
(*TFts5Config)(unsafe.Pointer(pConfig)).FbLock = (*TFts5Config)(unsafe.Pointer(pConfig)).FbLock - 1
|
|
if rc != int32(SQLITE_ROW) {
|
|
**(**int32)(__ccgo_up(pCsr + 80)) |= int32(FTS5CSR_EOF)
|
|
rc = Xsqlite3_reset(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpStmt)
|
|
if rc != SQLITE_OK {
|
|
(*Tsqlite3_vtab)(unsafe.Pointer((*Tsqlite3_vtab_cursor)(unsafe.Pointer(pCursor)).FpVtab)).FzErrMsg = Xsqlite3_mprintf(tls, __ccgo_ts+3968, libc.VaList(bp+16, Xsqlite3_errmsg(tls, (*TFts5Config)(unsafe.Pointer(pConfig)).Fdb)))
|
|
}
|
|
} else {
|
|
rc = SQLITE_OK
|
|
**(**int32)(__ccgo_up(pCsr + 80)) |= int32(FTS5CSR_REQUIRE_DOCSIZE)
|
|
}
|
|
break
|
|
}
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Create a "porter" tokenizer.
|
|
// */
|
|
func _fts5PorterCreate(tls *libc.TLS, pCtx uintptr, azArg uintptr, nArg int32, ppOut uintptr) (r int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var az2, pApi, pRet, zBase, v2 uintptr
|
|
var nArg2, rc, v1 int32
|
|
var _ /* pUserdata at bp+0 */ uintptr
|
|
var _ /* pV2 at bp+8 */ uintptr
|
|
_, _, _, _, _, _, _, _ = az2, nArg2, pApi, pRet, rc, zBase, v1, v2
|
|
pApi = pCtx
|
|
rc = SQLITE_OK
|
|
**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
|
|
zBase = __ccgo_ts + 41918
|
|
**(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0)
|
|
for nArg > 0 {
|
|
if Xsqlite3_stricmp(tls, **(**uintptr)(__ccgo_up(azArg)), __ccgo_ts+41928) == 0 {
|
|
nArg = nArg - 1
|
|
azArg += 8
|
|
} else {
|
|
zBase = **(**uintptr)(__ccgo_up(azArg))
|
|
break
|
|
}
|
|
}
|
|
pRet = Xsqlite3_malloc64(tls, uint64(168))
|
|
if pRet != 0 {
|
|
libc.Xmemset(tls, pRet, 0, uint64(168))
|
|
rc = (*(*func(*libc.TLS, uintptr, uintptr, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*Tfts5_api)(unsafe.Pointer(pApi)).FxFindTokenizer_v2})))(tls, pApi, zBase, bp, bp+8)
|
|
} else {
|
|
rc = int32(SQLITE_NOMEM)
|
|
}
|
|
if rc == SQLITE_OK {
|
|
if nArg > 0 {
|
|
v1 = nArg - int32(1)
|
|
} else {
|
|
v1 = 0
|
|
}
|
|
nArg2 = v1
|
|
if nArg2 != 0 {
|
|
v2 = azArg + 1*8
|
|
} else {
|
|
v2 = uintptr(0)
|
|
}
|
|
az2 = v2
|
|
libc.Xmemcpy(tls, pRet, **(**uintptr)(__ccgo_up(bp + 8)), uint64(32))
|
|
rc = (*(*func(*libc.TLS, uintptr, uintptr, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*TPorterTokenizer)(unsafe.Pointer(pRet)).Ftokenizer_v2.FxCreate})))(tls, **(**uintptr)(__ccgo_up(bp)), az2, nArg2, pRet+32)
|
|
}
|
|
if rc != SQLITE_OK {
|
|
_fts5PorterDelete(tls, pRet)
|
|
pRet = uintptr(0)
|
|
}
|
|
**(**uintptr)(__ccgo_up(ppOut)) = pRet
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Execute the SQL statement:
|
|
// **
|
|
// ** DELETE FROM %_idx WHERE (segid, (pgno/2)) = ($iSegid, $iPgno);
|
|
// **
|
|
// ** This is used when a secure-delete operation removes the last term
|
|
// ** from a segment leaf page. In that case the %_idx entry is removed
|
|
// ** too. This is done to ensure that if all instances of a token are
|
|
// ** removed from an fts5 database in secure-delete mode, no trace of
|
|
// ** the token itself remains in the database.
|
|
// */
|
|
func _fts5SecureDeleteIdxEntry(tls *libc.TLS, p uintptr, iSegid int32, iPgno int32) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
if iPgno != int32(1) {
|
|
if (*TFts5Index)(unsafe.Pointer(p)).FpDeleteFromIdx == uintptr(0) {
|
|
_fts5IndexPrepareStmt(tls, p, p+136, Xsqlite3_mprintf(tls, __ccgo_ts+39409, libc.VaList(bp+8, (*TFts5Config)(unsafe.Pointer((*TFts5Index)(unsafe.Pointer(p)).FpConfig)).FzDb, (*TFts5Config)(unsafe.Pointer((*TFts5Index)(unsafe.Pointer(p)).FpConfig)).FzName)))
|
|
}
|
|
if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
Xsqlite3_bind_int(tls, (*TFts5Index)(unsafe.Pointer(p)).FpDeleteFromIdx, int32(1), iSegid)
|
|
Xsqlite3_bind_int(tls, (*TFts5Index)(unsafe.Pointer(p)).FpDeleteFromIdx, int32(2), iPgno)
|
|
Xsqlite3_step(tls, (*TFts5Index)(unsafe.Pointer(p)).FpDeleteFromIdx)
|
|
(*TFts5Index)(unsafe.Pointer(p)).Frc = Xsqlite3_reset(tls, (*TFts5Index)(unsafe.Pointer(p)).FpDeleteFromIdx)
|
|
}
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** If the cursor requires seeking (bSeekRequired flag is set), seek it.
|
|
// ** Return SQLITE_OK if no error occurs, or an SQLite error code otherwise.
|
|
// **
|
|
// ** If argument bErrormsg is true and an error occurs, an error message may
|
|
// ** be left in sqlite3_vtab.zErrMsg.
|
|
// */
|
|
func _fts5SeekCursor(tls *libc.TLS, pCsr uintptr, bErrormsg int32) (r int32) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var eStmt, rc int32
|
|
var pTab, pTab1, v1 uintptr
|
|
_, _, _, _, _ = eStmt, pTab, pTab1, rc, v1
|
|
rc = SQLITE_OK
|
|
/* If the cursor does not yet have a statement handle, obtain one now. */
|
|
if (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpStmt == uintptr(0) {
|
|
pTab = (*TFts5Cursor)(unsafe.Pointer(pCsr)).Fbase.FpVtab
|
|
eStmt = _fts5StmtType(tls, pCsr)
|
|
if bErrormsg != 0 {
|
|
v1 = pTab + 16
|
|
} else {
|
|
v1 = uintptr(0)
|
|
}
|
|
rc = _sqlite3Fts5StorageStmt(tls, (*TFts5FullTable)(unsafe.Pointer(pTab)).FpStorage, eStmt, pCsr+56, v1)
|
|
}
|
|
if rc == SQLITE_OK && (*TFts5Cursor)(unsafe.Pointer(pCsr)).Fcsrflags&int32(FTS5CSR_REQUIRE_CONTENT) != 0 {
|
|
pTab1 = (*TFts5Cursor)(unsafe.Pointer(pCsr)).Fbase.FpVtab
|
|
Xsqlite3_reset(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpStmt)
|
|
Xsqlite3_bind_int64(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpStmt, int32(1), _fts5CursorRowid(tls, pCsr))
|
|
(*TFts5Config)(unsafe.Pointer((*TFts5Table)(unsafe.Pointer(pTab1)).FpConfig)).FbLock = (*TFts5Config)(unsafe.Pointer((*TFts5Table)(unsafe.Pointer(pTab1)).FpConfig)).FbLock + 1
|
|
rc = Xsqlite3_step(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpStmt)
|
|
(*TFts5Config)(unsafe.Pointer((*TFts5Table)(unsafe.Pointer(pTab1)).FpConfig)).FbLock = (*TFts5Config)(unsafe.Pointer((*TFts5Table)(unsafe.Pointer(pTab1)).FpConfig)).FbLock - 1
|
|
if rc == int32(SQLITE_ROW) {
|
|
rc = SQLITE_OK
|
|
**(**int32)(__ccgo_up(pCsr + 80)) &= ^libc.Int32FromInt32(FTS5CSR_REQUIRE_CONTENT)
|
|
} else {
|
|
rc = Xsqlite3_reset(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpStmt)
|
|
if rc == SQLITE_OK {
|
|
rc = libc.Int32FromInt32(SQLITE_CORRUPT) | libc.Int32FromInt32(1)<<libc.Int32FromInt32(8)
|
|
_fts5SetVtabError(tls, pTab1, __ccgo_ts+39977, libc.VaList(bp+8, _fts5CursorRowid(tls, pCsr), (*TFts5Config)(unsafe.Pointer((*TFts5Table)(unsafe.Pointer(pTab1)).FpConfig)).FzContent))
|
|
} else {
|
|
if (*TFts5Config)(unsafe.Pointer((*TFts5Table)(unsafe.Pointer(pTab1)).FpConfig)).FpzErrmsg != 0 {
|
|
_fts5SetVtabError(tls, pTab1, __ccgo_ts+3968, libc.VaList(bp+8, Xsqlite3_errmsg(tls, (*TFts5Config)(unsafe.Pointer((*TFts5Table)(unsafe.Pointer(pTab1)).FpConfig)).Fdb)))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This function sets up an iterator to use for a non-prefix query on a
|
|
// ** tokendata=1 table.
|
|
// */
|
|
func _fts5SetupTokendataIter(tls *libc.TLS, p uintptr, pToken uintptr, nToken int32, pColset uintptr) (r uintptr) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var bDone, flags, iLvl, iSeg, iSeg1, ii, ii1 int32
|
|
var pII, pIter, pNew, pNewIter, pPrev, pPrevIter, pRet, pSeg, pSet, pSmall, pStruct, v1 uintptr
|
|
var _ /* bSeek at bp+0 */ TFts5Buffer
|
|
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = bDone, flags, iLvl, iSeg, iSeg1, ii, ii1, pII, pIter, pNew, pNewIter, pPrev, pPrevIter, pRet, pSeg, pSet, pSmall, pStruct, v1
|
|
pRet = uintptr(0)
|
|
pSet = uintptr(0)
|
|
pStruct = uintptr(0)
|
|
flags = libc.Int32FromInt32(FTS5INDEX_QUERY_SCANONETERM) | libc.Int32FromInt32(FTS5INDEX_QUERY_SCAN)
|
|
**(**TFts5Buffer)(__ccgo_up(bp)) = TFts5Buffer{}
|
|
pSmall = uintptr(0)
|
|
_fts5IndexFlush(tls, p)
|
|
pStruct = _fts5StructureRead(tls, p)
|
|
for (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
if pSet != 0 {
|
|
v1 = *(*uintptr)(unsafe.Pointer(pSet + 72 + uintptr((*TFts5TokenDataIter)(unsafe.Pointer(pSet)).FnIter-int64(1))*8))
|
|
} else {
|
|
v1 = uintptr(0)
|
|
}
|
|
pPrev = v1
|
|
pNew = uintptr(0)
|
|
pNewIter = uintptr(0)
|
|
pPrevIter = uintptr(0)
|
|
pNew = _fts5MultiIterAlloc(tls, p, (*TFts5Structure)(unsafe.Pointer(pStruct)).FnSegment)
|
|
if pSmall != 0 {
|
|
_sqlite3Fts5BufferSet(tls, p+60, bp, (*TFts5Buffer)(unsafe.Pointer(pSmall)).Fn, (*TFts5Buffer)(unsafe.Pointer(pSmall)).Fp)
|
|
_sqlite3Fts5BufferAppendBlob(tls, p+60, bp, uint32(1), __ccgo_ts+39608)
|
|
} else {
|
|
_sqlite3Fts5BufferSet(tls, p+60, bp, nToken, pToken)
|
|
}
|
|
if (*TFts5Index)(unsafe.Pointer(p)).Frc != 0 {
|
|
_fts5IterClose(tls, pNew)
|
|
break
|
|
}
|
|
pNewIter = pNew + 104
|
|
if pPrev != 0 {
|
|
v1 = pPrev + 104
|
|
} else {
|
|
v1 = uintptr(0)
|
|
}
|
|
pPrevIter = v1
|
|
iLvl = 0
|
|
for {
|
|
if !(iLvl < (*TFts5Structure)(unsafe.Pointer(pStruct)).FnLevel) {
|
|
break
|
|
}
|
|
iSeg = (*(*TFts5StructureLevel)(unsafe.Pointer(pStruct + 32 + uintptr(iLvl)*16))).FnSeg - int32(1)
|
|
for {
|
|
if !(iSeg >= 0) {
|
|
break
|
|
}
|
|
pSeg = (*(*TFts5StructureLevel)(unsafe.Pointer(pStruct + 32 + uintptr(iLvl)*16))).FaSeg + uintptr(iSeg)*56
|
|
bDone = 0
|
|
if pPrevIter != 0 {
|
|
if _fts5BufferCompare(tls, pSmall, pPrevIter+96) != 0 {
|
|
libc.Xmemcpy(tls, pNewIter, pPrevIter, uint64(128))
|
|
libc.Xmemset(tls, pPrevIter, 0, uint64(128))
|
|
bDone = int32(1)
|
|
} else {
|
|
if (*TFts5SegIter)(unsafe.Pointer(pPrevIter)).FiEndofDoclist > (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pPrevIter)).FpLeaf)).FszLeaf {
|
|
_fts5SegIterNextInit(tls, p, (**(**TFts5Buffer)(__ccgo_up(bp))).Fp, (**(**TFts5Buffer)(__ccgo_up(bp))).Fn-int32(1), pSeg, pNewIter)
|
|
bDone = int32(1)
|
|
}
|
|
}
|
|
}
|
|
if bDone == 0 {
|
|
_fts5SegIterSeekInit(tls, p, (**(**TFts5Buffer)(__ccgo_up(bp))).Fp, (**(**TFts5Buffer)(__ccgo_up(bp))).Fn, flags, pSeg, pNewIter)
|
|
}
|
|
if pPrevIter != 0 {
|
|
if (*TFts5SegIter)(unsafe.Pointer(pPrevIter)).FpTombArray != 0 {
|
|
(*TFts5SegIter)(unsafe.Pointer(pNewIter)).FpTombArray = (*TFts5SegIter)(unsafe.Pointer(pPrevIter)).FpTombArray
|
|
(*TFts5TombstoneArray)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pNewIter)).FpTombArray)).FnRef = (*TFts5TombstoneArray)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pNewIter)).FpTombArray)).FnRef + 1
|
|
}
|
|
} else {
|
|
_fts5SegIterAllocTombstone(tls, p, pNewIter)
|
|
}
|
|
pNewIter += 128
|
|
if pPrevIter != 0 {
|
|
pPrevIter += 128
|
|
}
|
|
if (*TFts5Index)(unsafe.Pointer(p)).Frc != 0 {
|
|
break
|
|
}
|
|
goto _4
|
|
_4:
|
|
;
|
|
iSeg = iSeg - 1
|
|
}
|
|
goto _3
|
|
_3:
|
|
;
|
|
iLvl = iLvl + 1
|
|
}
|
|
_fts5TokendataSetTermIfEof(tls, pPrev, pSmall)
|
|
(*TFts5Iter)(unsafe.Pointer(pNew)).FbSkipEmpty = uint8(1)
|
|
(*TFts5Iter)(unsafe.Pointer(pNew)).FpColset = pColset
|
|
_fts5IterSetOutputCb(tls, p+60, pNew)
|
|
/* Loop through all segments in the new iterator. Find the smallest
|
|
** term that any segment-iterator points to. Iterator pNew will be
|
|
** used for this term. Also, set any iterator that points to a term that
|
|
** does not match pToken/nToken to point to EOF */
|
|
pSmall = uintptr(0)
|
|
ii = 0
|
|
for {
|
|
if !(ii < (*TFts5Iter)(unsafe.Pointer(pNew)).FnSeg) {
|
|
break
|
|
}
|
|
pII = pNew + 104 + uintptr(ii)*128
|
|
if 0 == _fts5IsTokendataPrefix(tls, pII+96, pToken, nToken) {
|
|
_fts5SegIterSetEOF(tls, pII)
|
|
}
|
|
if (*TFts5SegIter)(unsafe.Pointer(pII)).FpLeaf != 0 && (!(pSmall != 0) || _fts5BufferCompare(tls, pSmall, pII+96) > 0) {
|
|
pSmall = pII + 96
|
|
}
|
|
goto _5
|
|
_5:
|
|
;
|
|
ii = ii + 1
|
|
}
|
|
/* If pSmall is still NULL at this point, then the new iterator does
|
|
** not point to any terms that match the query. So delete it and break
|
|
** out of the loop - all required iterators have been collected. */
|
|
if pSmall == uintptr(0) {
|
|
_fts5IterClose(tls, pNew)
|
|
break
|
|
}
|
|
/* Append this iterator to the set and continue. */
|
|
pSet = _fts5AppendTokendataIter(tls, p, pSet, pNew)
|
|
}
|
|
if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK && pSet != 0 {
|
|
ii1 = 0
|
|
for {
|
|
if !(int64(ii1) < (*TFts5TokenDataIter)(unsafe.Pointer(pSet)).FnIter) {
|
|
break
|
|
}
|
|
pIter = *(*uintptr)(unsafe.Pointer(pSet + 72 + uintptr(ii1)*8))
|
|
iSeg1 = 0
|
|
for {
|
|
if !(iSeg1 < (*TFts5Iter)(unsafe.Pointer(pIter)).FnSeg) {
|
|
break
|
|
}
|
|
(*(*TFts5SegIter)(unsafe.Pointer(pIter + 104 + uintptr(iSeg1)*128))).Fflags |= int32(FTS5_SEGITER_ONETERM)
|
|
goto _7
|
|
_7:
|
|
;
|
|
iSeg1 = iSeg1 + 1
|
|
}
|
|
_fts5MultiIterFinishSetup(tls, p, pIter)
|
|
goto _6
|
|
_6:
|
|
;
|
|
ii1 = ii1 + 1
|
|
}
|
|
}
|
|
if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
pRet = _fts5MultiIterAlloc(tls, p, 0)
|
|
}
|
|
if pRet != 0 {
|
|
(*TFts5Iter)(unsafe.Pointer(pRet)).FnSeg = 0
|
|
(*TFts5Iter)(unsafe.Pointer(pRet)).FpTokenDataIter = pSet
|
|
if pSet != 0 {
|
|
_fts5IterSetOutputsTokendata(tls, pRet)
|
|
} else {
|
|
(*TFts5Iter)(unsafe.Pointer(pRet)).Fbase.FbEof = uint8(1)
|
|
}
|
|
} else {
|
|
_fts5TokendataIterDelete(tls, pSet)
|
|
}
|
|
_fts5StructureRelease(tls, pStruct)
|
|
_sqlite3Fts5BufferFree(tls, bp)
|
|
return pRet
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Implementation of snippet() function.
|
|
// */
|
|
func _fts5SnippetFunction(tls *libc.TLS, pApi uintptr, pFts uintptr, pCtx uintptr, nVal int32, apVal uintptr) {
|
|
bp := tls.Alloc(208)
|
|
defer tls.Free(208)
|
|
var aSeen, zEllips, zErr uintptr
|
|
var i, iBestCol, iBestStart, iCol, ii, jj, nBestScore, nCol, nPhrase, v4 int32
|
|
var nToken Ti64
|
|
var v1, v2, v3 int64
|
|
var _ /* ctx at bp+0 */ THighlightContext
|
|
var _ /* iAdj at bp+184 */ int32
|
|
var _ /* ic at bp+176 */ int32
|
|
var _ /* io at bp+180 */ int32
|
|
var _ /* ip at bp+172 */ int32
|
|
var _ /* nColSize at bp+112 */ int32
|
|
var _ /* nDoc at bp+164 */ int32
|
|
var _ /* nDocsize at bp+168 */ int32
|
|
var _ /* nInst at bp+108 */ int32
|
|
var _ /* nLoc at bp+160 */ int32
|
|
var _ /* nLoc at bp+200 */ int32
|
|
var _ /* nScore at bp+188 */ int32
|
|
var _ /* pLoc at bp+152 */ uintptr
|
|
var _ /* pLoc at bp+192 */ uintptr
|
|
var _ /* rc at bp+104 */ int32
|
|
var _ /* sFinder at bp+120 */ TFts5SFinder
|
|
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = aSeen, i, iBestCol, iBestStart, iCol, ii, jj, nBestScore, nCol, nPhrase, nToken, zEllips, zErr, v1, v2, v3, v4
|
|
**(**int32)(__ccgo_up(bp + 104)) = SQLITE_OK /* 5th argument to snippet() */
|
|
**(**int32)(__ccgo_up(bp + 108)) = 0 /* Column containing best snippet */
|
|
iBestStart = 0 /* First token of best snippet */
|
|
nBestScore = 0 /* Score of best snippet */
|
|
**(**int32)(__ccgo_up(bp + 112)) = 0
|
|
if nVal != int32(5) {
|
|
zErr = __ccgo_ts + 37230
|
|
Xsqlite3_result_error(tls, pCtx, zErr, -int32(1))
|
|
return
|
|
}
|
|
nCol = (*(*func(*libc.TLS, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*TFts5ExtensionApi)(unsafe.Pointer(pApi)).FxColumnCount})))(tls, pFts)
|
|
libc.Xmemset(tls, bp, 0, uint64(104))
|
|
iCol = Xsqlite3_value_int(tls, **(**uintptr)(__ccgo_up(apVal)))
|
|
(**(**THighlightContext)(__ccgo_up(bp))).FzOpen = _fts5ValueToText(tls, **(**uintptr)(__ccgo_up(apVal + 1*8)))
|
|
(**(**THighlightContext)(__ccgo_up(bp))).FzClose = _fts5ValueToText(tls, **(**uintptr)(__ccgo_up(apVal + 2*8)))
|
|
(**(**THighlightContext)(__ccgo_up(bp))).FiRangeEnd = -int32(1)
|
|
zEllips = _fts5ValueToText(tls, **(**uintptr)(__ccgo_up(apVal + 3*8)))
|
|
if Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(apVal + 4*8))) > int64(libc.Int32FromInt32(0)) {
|
|
v2 = Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(apVal + 4*8)))
|
|
} else {
|
|
v2 = int64(libc.Int32FromInt32(0))
|
|
}
|
|
if v2 < int64(libc.Int32FromInt32(64)) {
|
|
if Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(apVal + 4*8))) > int64(libc.Int32FromInt32(0)) {
|
|
v3 = Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(apVal + 4*8)))
|
|
} else {
|
|
v3 = int64(libc.Int32FromInt32(0))
|
|
}
|
|
v1 = v3
|
|
} else {
|
|
v1 = int64(libc.Int32FromInt32(64))
|
|
}
|
|
nToken = int64(int32(v1))
|
|
if iCol >= 0 {
|
|
v4 = iCol
|
|
} else {
|
|
v4 = 0
|
|
}
|
|
iBestCol = v4
|
|
nPhrase = (*(*func(*libc.TLS, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*TFts5ExtensionApi)(unsafe.Pointer(pApi)).FxPhraseCount})))(tls, pFts)
|
|
aSeen = Xsqlite3_malloc64(tls, libc.Uint64FromInt32(nPhrase))
|
|
if aSeen == uintptr(0) {
|
|
**(**int32)(__ccgo_up(bp + 104)) = int32(SQLITE_NOMEM)
|
|
}
|
|
if **(**int32)(__ccgo_up(bp + 104)) == SQLITE_OK {
|
|
**(**int32)(__ccgo_up(bp + 104)) = (*(*func(*libc.TLS, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*TFts5ExtensionApi)(unsafe.Pointer(pApi)).FxInstCount})))(tls, pFts, bp+108)
|
|
}
|
|
libc.Xmemset(tls, bp+120, 0, uint64(32))
|
|
i = 0
|
|
for {
|
|
if !(i < nCol) {
|
|
break
|
|
}
|
|
if iCol < 0 || iCol == i {
|
|
**(**uintptr)(__ccgo_up(bp + 152)) = uintptr(0) /* Locale of column iCol */
|
|
**(**int32)(__ccgo_up(bp + 160)) = 0
|
|
(**(**TFts5SFinder)(__ccgo_up(bp + 120))).FiPos = 0
|
|
(**(**TFts5SFinder)(__ccgo_up(bp + 120))).FnFirst = 0
|
|
**(**int32)(__ccgo_up(bp + 104)) = (*(*func(*libc.TLS, uintptr, int32, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*TFts5ExtensionApi)(unsafe.Pointer(pApi)).FxColumnText})))(tls, pFts, i, bp+120+24, bp+164)
|
|
if **(**int32)(__ccgo_up(bp + 104)) != SQLITE_OK {
|
|
break
|
|
}
|
|
**(**int32)(__ccgo_up(bp + 104)) = (*(*func(*libc.TLS, uintptr, int32, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*TFts5ExtensionApi)(unsafe.Pointer(pApi)).FxColumnLocale})))(tls, pFts, i, bp+152, bp+160)
|
|
if **(**int32)(__ccgo_up(bp + 104)) != SQLITE_OK {
|
|
break
|
|
}
|
|
**(**int32)(__ccgo_up(bp + 104)) = (*(*func(*libc.TLS, uintptr, uintptr, int32, uintptr, int32, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*TFts5ExtensionApi)(unsafe.Pointer(pApi)).FxTokenize_v2})))(tls, pFts, (**(**TFts5SFinder)(__ccgo_up(bp + 120))).FzDoc, **(**int32)(__ccgo_up(bp + 164)), **(**uintptr)(__ccgo_up(bp + 152)), **(**int32)(__ccgo_up(bp + 160)), bp+120, __ccgo_fp(_fts5SentenceFinderCb))
|
|
if **(**int32)(__ccgo_up(bp + 104)) != SQLITE_OK {
|
|
break
|
|
}
|
|
**(**int32)(__ccgo_up(bp + 104)) = (*(*func(*libc.TLS, uintptr, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*TFts5ExtensionApi)(unsafe.Pointer(pApi)).FxColumnSize})))(tls, pFts, i, bp+168)
|
|
if **(**int32)(__ccgo_up(bp + 104)) != SQLITE_OK {
|
|
break
|
|
}
|
|
ii = 0
|
|
for {
|
|
if !(**(**int32)(__ccgo_up(bp + 104)) == SQLITE_OK && ii < **(**int32)(__ccgo_up(bp + 108))) {
|
|
break
|
|
}
|
|
**(**int32)(__ccgo_up(bp + 104)) = (*(*func(*libc.TLS, uintptr, int32, uintptr, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*TFts5ExtensionApi)(unsafe.Pointer(pApi)).FxInst})))(tls, pFts, ii, bp+172, bp+176, bp+180)
|
|
if **(**int32)(__ccgo_up(bp + 176)) != i {
|
|
goto _6
|
|
}
|
|
if **(**int32)(__ccgo_up(bp + 180)) > **(**int32)(__ccgo_up(bp + 168)) {
|
|
**(**int32)(__ccgo_up(bp + 104)) = libc.Int32FromInt32(SQLITE_CORRUPT) | libc.Int32FromInt32(1)<<libc.Int32FromInt32(8)
|
|
}
|
|
if **(**int32)(__ccgo_up(bp + 104)) != SQLITE_OK {
|
|
goto _6
|
|
}
|
|
libc.Xmemset(tls, aSeen, 0, libc.Uint64FromInt32(nPhrase))
|
|
**(**int32)(__ccgo_up(bp + 104)) = _fts5SnippetScore(tls, pApi, pFts, **(**int32)(__ccgo_up(bp + 168)), aSeen, i, **(**int32)(__ccgo_up(bp + 180)), int32(nToken), bp+188, bp+184)
|
|
if **(**int32)(__ccgo_up(bp + 104)) == SQLITE_OK && **(**int32)(__ccgo_up(bp + 188)) > nBestScore {
|
|
nBestScore = **(**int32)(__ccgo_up(bp + 188))
|
|
iBestCol = i
|
|
iBestStart = **(**int32)(__ccgo_up(bp + 184))
|
|
**(**int32)(__ccgo_up(bp + 112)) = **(**int32)(__ccgo_up(bp + 168))
|
|
}
|
|
if **(**int32)(__ccgo_up(bp + 104)) == SQLITE_OK && (**(**TFts5SFinder)(__ccgo_up(bp + 120))).FnFirst != 0 && int64(**(**int32)(__ccgo_up(bp + 168))) > nToken {
|
|
jj = 0
|
|
for {
|
|
if !(jj < (**(**TFts5SFinder)(__ccgo_up(bp + 120))).FnFirst-int32(1)) {
|
|
break
|
|
}
|
|
if **(**int32)(__ccgo_up((**(**TFts5SFinder)(__ccgo_up(bp + 120))).FaFirst + uintptr(jj+int32(1))*4)) > **(**int32)(__ccgo_up(bp + 180)) {
|
|
break
|
|
}
|
|
goto _7
|
|
_7:
|
|
;
|
|
jj = jj + 1
|
|
}
|
|
if **(**int32)(__ccgo_up((**(**TFts5SFinder)(__ccgo_up(bp + 120))).FaFirst + uintptr(jj)*4)) < **(**int32)(__ccgo_up(bp + 180)) {
|
|
libc.Xmemset(tls, aSeen, 0, libc.Uint64FromInt32(nPhrase))
|
|
**(**int32)(__ccgo_up(bp + 104)) = _fts5SnippetScore(tls, pApi, pFts, **(**int32)(__ccgo_up(bp + 168)), aSeen, i, **(**int32)(__ccgo_up((**(**TFts5SFinder)(__ccgo_up(bp + 120))).FaFirst + uintptr(jj)*4)), int32(nToken), bp+188, uintptr(0))
|
|
if **(**int32)(__ccgo_up((**(**TFts5SFinder)(__ccgo_up(bp + 120))).FaFirst + uintptr(jj)*4)) == 0 {
|
|
v4 = int32(120)
|
|
} else {
|
|
v4 = int32(100)
|
|
}
|
|
**(**int32)(__ccgo_up(bp + 188)) = **(**int32)(__ccgo_up(bp + 188)) + v4
|
|
if **(**int32)(__ccgo_up(bp + 104)) == SQLITE_OK && **(**int32)(__ccgo_up(bp + 188)) > nBestScore {
|
|
nBestScore = **(**int32)(__ccgo_up(bp + 188))
|
|
iBestCol = i
|
|
iBestStart = **(**int32)(__ccgo_up((**(**TFts5SFinder)(__ccgo_up(bp + 120))).FaFirst + uintptr(jj)*4))
|
|
**(**int32)(__ccgo_up(bp + 112)) = **(**int32)(__ccgo_up(bp + 168))
|
|
}
|
|
}
|
|
}
|
|
goto _6
|
|
_6:
|
|
;
|
|
ii = ii + 1
|
|
}
|
|
}
|
|
goto _5
|
|
_5:
|
|
;
|
|
i = i + 1
|
|
}
|
|
if **(**int32)(__ccgo_up(bp + 104)) == SQLITE_OK {
|
|
**(**int32)(__ccgo_up(bp + 104)) = (*(*func(*libc.TLS, uintptr, int32, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*TFts5ExtensionApi)(unsafe.Pointer(pApi)).FxColumnText})))(tls, pFts, iBestCol, bp+24, bp+32)
|
|
}
|
|
if **(**int32)(__ccgo_up(bp + 104)) == SQLITE_OK && **(**int32)(__ccgo_up(bp + 112)) == 0 {
|
|
**(**int32)(__ccgo_up(bp + 104)) = (*(*func(*libc.TLS, uintptr, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*TFts5ExtensionApi)(unsafe.Pointer(pApi)).FxColumnSize})))(tls, pFts, iBestCol, bp+112)
|
|
}
|
|
if (**(**THighlightContext)(__ccgo_up(bp))).FzIn != 0 {
|
|
**(**uintptr)(__ccgo_up(bp + 192)) = uintptr(0) /* Locale of column iBestCol */
|
|
**(**int32)(__ccgo_up(bp + 200)) = 0 /* Bytes in pLoc */
|
|
if **(**int32)(__ccgo_up(bp + 104)) == SQLITE_OK {
|
|
**(**int32)(__ccgo_up(bp + 104)) = _fts5CInstIterInit(tls, pApi, pFts, iBestCol, bp+40)
|
|
}
|
|
(**(**THighlightContext)(__ccgo_up(bp))).FiRangeStart = iBestStart
|
|
(**(**THighlightContext)(__ccgo_up(bp))).FiRangeEnd = int32(int64(iBestStart) + nToken - int64(1))
|
|
if iBestStart > 0 {
|
|
_fts5HighlightAppend(tls, bp+104, bp, zEllips, -int32(1))
|
|
}
|
|
/* Advance iterator ctx.iter so that it points to the first coalesced
|
|
** phrase instance at or following position iBestStart. */
|
|
for (**(**THighlightContext)(__ccgo_up(bp))).Fiter.FiStart >= 0 && (**(**THighlightContext)(__ccgo_up(bp))).Fiter.FiStart < iBestStart && **(**int32)(__ccgo_up(bp + 104)) == SQLITE_OK {
|
|
**(**int32)(__ccgo_up(bp + 104)) = _fts5CInstIterNext(tls, bp+40)
|
|
}
|
|
if **(**int32)(__ccgo_up(bp + 104)) == SQLITE_OK {
|
|
**(**int32)(__ccgo_up(bp + 104)) = (*(*func(*libc.TLS, uintptr, int32, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*TFts5ExtensionApi)(unsafe.Pointer(pApi)).FxColumnLocale})))(tls, pFts, iBestCol, bp+192, bp+200)
|
|
}
|
|
if **(**int32)(__ccgo_up(bp + 104)) == SQLITE_OK {
|
|
**(**int32)(__ccgo_up(bp + 104)) = (*(*func(*libc.TLS, uintptr, uintptr, int32, uintptr, int32, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*TFts5ExtensionApi)(unsafe.Pointer(pApi)).FxTokenize_v2})))(tls, pFts, (**(**THighlightContext)(__ccgo_up(bp))).FzIn, (**(**THighlightContext)(__ccgo_up(bp))).FnIn, **(**uintptr)(__ccgo_up(bp + 192)), **(**int32)(__ccgo_up(bp + 200)), bp, __ccgo_fp(_fts5HighlightCb))
|
|
}
|
|
if (**(**THighlightContext)(__ccgo_up(bp))).FbOpen != 0 {
|
|
_fts5HighlightAppend(tls, bp+104, bp, (**(**THighlightContext)(__ccgo_up(bp))).FzClose, -int32(1))
|
|
}
|
|
if (**(**THighlightContext)(__ccgo_up(bp))).FiRangeEnd >= **(**int32)(__ccgo_up(bp + 112))-int32(1) {
|
|
_fts5HighlightAppend(tls, bp+104, bp, (**(**THighlightContext)(__ccgo_up(bp))).FzIn+uintptr((**(**THighlightContext)(__ccgo_up(bp))).FiOff), (**(**THighlightContext)(__ccgo_up(bp))).FnIn-(**(**THighlightContext)(__ccgo_up(bp))).FiOff)
|
|
} else {
|
|
_fts5HighlightAppend(tls, bp+104, bp, zEllips, -int32(1))
|
|
}
|
|
}
|
|
if **(**int32)(__ccgo_up(bp + 104)) == SQLITE_OK {
|
|
Xsqlite3_result_text(tls, pCtx, (**(**THighlightContext)(__ccgo_up(bp))).FzOut, -int32(1), uintptr(-libc.Int32FromInt32(1)))
|
|
} else {
|
|
Xsqlite3_result_error_code(tls, pCtx, **(**int32)(__ccgo_up(bp + 104)))
|
|
}
|
|
Xsqlite3_free(tls, (**(**THighlightContext)(__ccgo_up(bp))).FzOut)
|
|
Xsqlite3_free(tls, aSeen)
|
|
Xsqlite3_free(tls, (**(**TFts5SFinder)(__ccgo_up(bp + 120))).FaFirst)
|
|
}
|
|
|
|
/************************************************************************/
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Prepare the two insert statements - Fts5Storage.pInsertContent and
|
|
// ** Fts5Storage.pInsertDocsize - if they have not already been prepared.
|
|
// ** Return SQLITE_OK if successful, or an SQLite error code if an error
|
|
// ** occurs.
|
|
// */
|
|
func _fts5StorageGetStmt(tls *libc.TLS, p uintptr, eStmt int32, ppStmt uintptr, pzErrMsg uintptr) (r int32) {
|
|
bp := tls.Alloc(64)
|
|
defer tls.Free(64)
|
|
var azStmt [12]uintptr
|
|
var f, i int32
|
|
var pC, zBind, zSql, v2 uintptr
|
|
var _ /* rc at bp+0 */ int32
|
|
_, _, _, _, _, _, _ = azStmt, f, i, pC, zBind, zSql, v2
|
|
**(**int32)(__ccgo_up(bp)) = SQLITE_OK
|
|
/* If there is no %_docsize table, there should be no requests for
|
|
** statements to operate on it. */
|
|
if **(**uintptr)(__ccgo_up(p + 48 + uintptr(eStmt)*8)) == uintptr(0) {
|
|
azStmt = [12]uintptr{
|
|
0: __ccgo_ts + 40787,
|
|
1: __ccgo_ts + 40855,
|
|
2: __ccgo_ts + 40924,
|
|
3: __ccgo_ts + 40924,
|
|
4: __ccgo_ts + 40957,
|
|
5: __ccgo_ts + 40996,
|
|
6: __ccgo_ts + 41036,
|
|
7: __ccgo_ts + 41075,
|
|
8: __ccgo_ts + 41118,
|
|
9: __ccgo_ts + 41157,
|
|
10: __ccgo_ts + 41201,
|
|
11: __ccgo_ts + 41241,
|
|
}
|
|
pC = (*TFts5Storage)(unsafe.Pointer(p)).FpConfig
|
|
zSql = uintptr(0)
|
|
switch eStmt {
|
|
case int32(FTS5_STMT_SCAN):
|
|
zSql = Xsqlite3_mprintf(tls, azStmt[eStmt], libc.VaList(bp+16, (*TFts5Config)(unsafe.Pointer(pC)).FzContentExprlist, (*TFts5Config)(unsafe.Pointer(pC)).FzContent))
|
|
case FTS5_STMT_SCAN_ASC:
|
|
fallthrough
|
|
case int32(FTS5_STMT_SCAN_DESC):
|
|
zSql = Xsqlite3_mprintf(tls, azStmt[eStmt], libc.VaList(bp+16, (*TFts5Config)(unsafe.Pointer(pC)).FzContentExprlist, (*TFts5Config)(unsafe.Pointer(pC)).FzContent, (*TFts5Config)(unsafe.Pointer(pC)).FzContentRowid, (*TFts5Config)(unsafe.Pointer(pC)).FzContentRowid, (*TFts5Config)(unsafe.Pointer(pC)).FzContentRowid))
|
|
case int32(FTS5_STMT_LOOKUP):
|
|
fallthrough
|
|
case int32(FTS5_STMT_LOOKUP2):
|
|
zSql = Xsqlite3_mprintf(tls, azStmt[eStmt], libc.VaList(bp+16, (*TFts5Config)(unsafe.Pointer(pC)).FzContentExprlist, (*TFts5Config)(unsafe.Pointer(pC)).FzContent, (*TFts5Config)(unsafe.Pointer(pC)).FzContentRowid))
|
|
case int32(FTS5_STMT_INSERT_CONTENT):
|
|
fallthrough
|
|
case int32(FTS5_STMT_REPLACE_CONTENT):
|
|
zBind = uintptr(0)
|
|
/* Add bindings for the "c*" columns - those that store the actual
|
|
** table content. If eContent==NORMAL, then there is one binding
|
|
** for each column. Or, if eContent==UNINDEXED, then there are only
|
|
** bindings for the UNINDEXED columns. */
|
|
i = 0
|
|
for {
|
|
if !(**(**int32)(__ccgo_up(bp)) == SQLITE_OK && i < (*TFts5Config)(unsafe.Pointer(pC)).FnCol+int32(1)) {
|
|
break
|
|
}
|
|
if !(i != 0) || (*TFts5Config)(unsafe.Pointer(pC)).FeContent == FTS5_CONTENT_NORMAL || **(**Tu8)(__ccgo_up((*TFts5Config)(unsafe.Pointer(pC)).FabUnindexed + uintptr(i-int32(1)))) != 0 {
|
|
if zBind != 0 {
|
|
v2 = __ccgo_ts + 14374
|
|
} else {
|
|
v2 = __ccgo_ts + 1704
|
|
}
|
|
zBind = _sqlite3Fts5Mprintf(tls, bp, __ccgo_ts+41264, libc.VaList(bp+16, zBind, v2, i+int32(1)))
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
/* Add bindings for any "l*" columns. Only non-UNINDEXED columns
|
|
** require these. */
|
|
if (*TFts5Config)(unsafe.Pointer(pC)).FbLocale != 0 && (*TFts5Config)(unsafe.Pointer(pC)).FeContent == FTS5_CONTENT_NORMAL {
|
|
i = 0
|
|
for {
|
|
if !(**(**int32)(__ccgo_up(bp)) == SQLITE_OK && i < (*TFts5Config)(unsafe.Pointer(pC)).FnCol) {
|
|
break
|
|
}
|
|
if libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TFts5Config)(unsafe.Pointer(pC)).FabUnindexed + uintptr(i)))) == 0 {
|
|
zBind = _sqlite3Fts5Mprintf(tls, bp, __ccgo_ts+41272, libc.VaList(bp+16, zBind, (*TFts5Config)(unsafe.Pointer(pC)).FnCol+i+int32(2)))
|
|
}
|
|
goto _3
|
|
_3:
|
|
;
|
|
i = i + 1
|
|
}
|
|
}
|
|
zSql = _sqlite3Fts5Mprintf(tls, bp, azStmt[eStmt], libc.VaList(bp+16, (*TFts5Config)(unsafe.Pointer(pC)).FzDb, (*TFts5Config)(unsafe.Pointer(pC)).FzName, zBind))
|
|
Xsqlite3_free(tls, zBind)
|
|
case int32(FTS5_STMT_REPLACE_DOCSIZE):
|
|
if (*TFts5Config)(unsafe.Pointer(pC)).FbContentlessDelete != 0 {
|
|
v2 = __ccgo_ts + 41279
|
|
} else {
|
|
v2 = __ccgo_ts + 1704
|
|
}
|
|
zSql = Xsqlite3_mprintf(tls, azStmt[eStmt], libc.VaList(bp+16, (*TFts5Config)(unsafe.Pointer(pC)).FzDb, (*TFts5Config)(unsafe.Pointer(pC)).FzName, v2))
|
|
case int32(FTS5_STMT_LOOKUP_DOCSIZE):
|
|
if (*TFts5Config)(unsafe.Pointer(pC)).FbContentlessDelete != 0 {
|
|
v2 = __ccgo_ts + 41282
|
|
} else {
|
|
v2 = __ccgo_ts + 1704
|
|
}
|
|
zSql = Xsqlite3_mprintf(tls, azStmt[eStmt], libc.VaList(bp+16, v2, (*TFts5Config)(unsafe.Pointer(pC)).FzDb, (*TFts5Config)(unsafe.Pointer(pC)).FzName))
|
|
default:
|
|
zSql = Xsqlite3_mprintf(tls, azStmt[eStmt], libc.VaList(bp+16, (*TFts5Config)(unsafe.Pointer(pC)).FzDb, (*TFts5Config)(unsafe.Pointer(pC)).FzName))
|
|
break
|
|
}
|
|
if zSql == uintptr(0) {
|
|
**(**int32)(__ccgo_up(bp)) = int32(SQLITE_NOMEM)
|
|
} else {
|
|
f = int32(SQLITE_PREPARE_PERSISTENT)
|
|
if eStmt > int32(FTS5_STMT_LOOKUP2) {
|
|
f = f | int32(SQLITE_PREPARE_NO_VTAB)
|
|
}
|
|
(*TFts5Config)(unsafe.Pointer((*TFts5Storage)(unsafe.Pointer(p)).FpConfig)).FbLock = (*TFts5Config)(unsafe.Pointer((*TFts5Storage)(unsafe.Pointer(p)).FpConfig)).FbLock + 1
|
|
**(**int32)(__ccgo_up(bp)) = Xsqlite3_prepare_v3(tls, (*TFts5Config)(unsafe.Pointer(pC)).Fdb, zSql, -int32(1), libc.Uint32FromInt32(f), p+48+uintptr(eStmt)*8, uintptr(0))
|
|
(*TFts5Config)(unsafe.Pointer((*TFts5Storage)(unsafe.Pointer(p)).FpConfig)).FbLock = (*TFts5Config)(unsafe.Pointer((*TFts5Storage)(unsafe.Pointer(p)).FpConfig)).FbLock - 1
|
|
Xsqlite3_free(tls, zSql)
|
|
if **(**int32)(__ccgo_up(bp)) != SQLITE_OK && pzErrMsg != 0 {
|
|
**(**uintptr)(__ccgo_up(pzErrMsg)) = Xsqlite3_mprintf(tls, __ccgo_ts+3968, libc.VaList(bp+16, Xsqlite3_errmsg(tls, (*TFts5Config)(unsafe.Pointer(pC)).Fdb)))
|
|
}
|
|
if **(**int32)(__ccgo_up(bp)) == int32(SQLITE_ERROR) && eStmt > int32(FTS5_STMT_LOOKUP2) && eStmt < int32(FTS5_STMT_SCAN) {
|
|
/* One of the internal tables - not the %_content table - is missing.
|
|
** This counts as a corrupted table. */
|
|
**(**int32)(__ccgo_up(bp)) = int32(SQLITE_CORRUPT)
|
|
}
|
|
}
|
|
}
|
|
**(**uintptr)(__ccgo_up(ppStmt)) = **(**uintptr)(__ccgo_up(p + 48 + uintptr(eStmt)*8))
|
|
Xsqlite3_reset(tls, **(**uintptr)(__ccgo_up(ppStmt)))
|
|
return **(**int32)(__ccgo_up(bp))
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Deserialize and return the structure record currently stored in serialized
|
|
// ** form within buffer pData/nData.
|
|
// **
|
|
// ** The Fts5Structure.aLevel[] and each Fts5StructureLevel.aSeg[] array
|
|
// ** are over-allocated by one slot. This allows the structure contents
|
|
// ** to be more easily edited.
|
|
// **
|
|
// ** If an error occurs, *ppOut is set to NULL and an SQLite error code
|
|
// ** returned. Otherwise, *ppOut is set to point to the new object and
|
|
// ** SQLITE_OK returned.
|
|
// */
|
|
func _fts5StructureDecode(tls *libc.TLS, pData uintptr, nData int32, piCookie uintptr, ppOut uintptr) (r int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var bStructureV2, i, iLvl, iSeg int32
|
|
var nByte Tsqlite3_int64
|
|
var nOriginCntr Tu64
|
|
var pLvl, pRet, pSeg uintptr
|
|
var v3 uint64
|
|
var _ /* nLevel at bp+4 */ int32
|
|
var _ /* nSegment at bp+8 */ int32
|
|
var _ /* nTotal at bp+12 */ int32
|
|
var _ /* rc at bp+0 */ int32
|
|
_, _, _, _, _, _, _, _, _, _ = bStructureV2, i, iLvl, iSeg, nByte, nOriginCntr, pLvl, pRet, pSeg, v3
|
|
**(**int32)(__ccgo_up(bp)) = SQLITE_OK
|
|
i = 0
|
|
**(**int32)(__ccgo_up(bp + 4)) = 0
|
|
**(**int32)(__ccgo_up(bp + 8)) = 0 /* Bytes of space to allocate at pRet */
|
|
pRet = uintptr(0) /* Structure object to return */
|
|
bStructureV2 = 0 /* True for FTS5_STRUCTURE_V2 */
|
|
nOriginCntr = uint64(0) /* Largest origin value seen so far */
|
|
/* Grab the cookie value */
|
|
if piCookie != 0 {
|
|
**(**int32)(__ccgo_up(piCookie)) = _sqlite3Fts5Get32(tls, pData)
|
|
}
|
|
i = int32(4)
|
|
/* Check if this is a V2 structure record. Set bStructureV2 if it is. */
|
|
if 0 == libc.Xmemcmp(tls, pData+uintptr(i), __ccgo_ts+39112, uint64(4)) {
|
|
i = i + int32(4)
|
|
bStructureV2 = int32(1)
|
|
}
|
|
/* Read the total number of levels and segments from the start of the
|
|
** structure record. */
|
|
i = i + _sqlite3Fts5GetVarint32(tls, pData+uintptr(i), bp+4)
|
|
i = i + _sqlite3Fts5GetVarint32(tls, pData+uintptr(i), bp+8)
|
|
if **(**int32)(__ccgo_up(bp + 4)) > int32(FTS5_MAX_SEGMENT) || **(**int32)(__ccgo_up(bp + 4)) < 0 || **(**int32)(__ccgo_up(bp + 8)) > int32(FTS5_MAX_SEGMENT) || **(**int32)(__ccgo_up(bp + 8)) < 0 {
|
|
return libc.Int32FromInt32(SQLITE_CORRUPT) | libc.Int32FromInt32(1)<<libc.Int32FromInt32(8)
|
|
}
|
|
nByte = libc.Int64FromUint64(uint64(libc.UintptrFromInt32(0)+32) + libc.Uint64FromInt32(**(**int32)(__ccgo_up(bp + 4)))*libc.Uint64FromInt64(16))
|
|
pRet = _sqlite3Fts5MallocZero(tls, bp, nByte)
|
|
if pRet != 0 {
|
|
(*TFts5Structure)(unsafe.Pointer(pRet)).FnRef = int32(1)
|
|
(*TFts5Structure)(unsafe.Pointer(pRet)).FnLevel = **(**int32)(__ccgo_up(bp + 4))
|
|
(*TFts5Structure)(unsafe.Pointer(pRet)).FnSegment = **(**int32)(__ccgo_up(bp + 8))
|
|
i = i + libc.Int32FromUint8(_sqlite3Fts5GetVarint(tls, pData+uintptr(i), pRet+8))
|
|
iLvl = 0
|
|
for {
|
|
if !(**(**int32)(__ccgo_up(bp)) == SQLITE_OK && iLvl < **(**int32)(__ccgo_up(bp + 4))) {
|
|
break
|
|
}
|
|
pLvl = pRet + 32 + uintptr(iLvl)*16
|
|
**(**int32)(__ccgo_up(bp + 12)) = 0
|
|
if i >= nData {
|
|
**(**int32)(__ccgo_up(bp)) = libc.Int32FromInt32(SQLITE_CORRUPT) | libc.Int32FromInt32(1)<<libc.Int32FromInt32(8)
|
|
} else {
|
|
i = i + _sqlite3Fts5GetVarint32(tls, pData+uintptr(i), pLvl)
|
|
i = i + _sqlite3Fts5GetVarint32(tls, pData+uintptr(i), bp+12)
|
|
if **(**int32)(__ccgo_up(bp + 12)) < (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnMerge {
|
|
**(**int32)(__ccgo_up(bp)) = libc.Int32FromInt32(SQLITE_CORRUPT) | libc.Int32FromInt32(1)<<libc.Int32FromInt32(8)
|
|
}
|
|
(*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FaSeg = _sqlite3Fts5MallocZero(tls, bp, libc.Int64FromUint64(libc.Uint64FromInt64(int64(**(**int32)(__ccgo_up(bp + 12))))*uint64(56)))
|
|
**(**int32)(__ccgo_up(bp + 8)) = **(**int32)(__ccgo_up(bp + 8)) - **(**int32)(__ccgo_up(bp + 12))
|
|
}
|
|
if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
|
|
(*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnSeg = **(**int32)(__ccgo_up(bp + 12))
|
|
iSeg = 0
|
|
for {
|
|
if !(iSeg < **(**int32)(__ccgo_up(bp + 12))) {
|
|
break
|
|
}
|
|
pSeg = (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FaSeg + uintptr(iSeg)*56
|
|
if i >= nData {
|
|
**(**int32)(__ccgo_up(bp)) = libc.Int32FromInt32(SQLITE_CORRUPT) | libc.Int32FromInt32(1)<<libc.Int32FromInt32(8)
|
|
break
|
|
}
|
|
i = i + _sqlite3Fts5GetVarint32(tls, pData+uintptr(i), pSeg)
|
|
i = i + _sqlite3Fts5GetVarint32(tls, pData+uintptr(i), pSeg+4)
|
|
i = i + _sqlite3Fts5GetVarint32(tls, pData+uintptr(i), pSeg+8)
|
|
if bStructureV2 != 0 {
|
|
i = i + libc.Int32FromUint8(_sqlite3Fts5GetVarint(tls, pData+uintptr(i), pSeg+16))
|
|
i = i + libc.Int32FromUint8(_sqlite3Fts5GetVarint(tls, pData+uintptr(i), pSeg+24))
|
|
i = i + _sqlite3Fts5GetVarint32(tls, pData+uintptr(i), pSeg+32)
|
|
i = i + libc.Int32FromUint8(_sqlite3Fts5GetVarint(tls, pData+uintptr(i), pSeg+40))
|
|
i = i + libc.Int32FromUint8(_sqlite3Fts5GetVarint(tls, pData+uintptr(i), pSeg+48))
|
|
if nOriginCntr > (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FiOrigin2 {
|
|
v3 = nOriginCntr
|
|
} else {
|
|
v3 = (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FiOrigin2
|
|
}
|
|
nOriginCntr = v3
|
|
}
|
|
if (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FpgnoLast < (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FpgnoFirst {
|
|
**(**int32)(__ccgo_up(bp)) = libc.Int32FromInt32(SQLITE_CORRUPT) | libc.Int32FromInt32(1)<<libc.Int32FromInt32(8)
|
|
break
|
|
}
|
|
goto _2
|
|
_2:
|
|
;
|
|
iSeg = iSeg + 1
|
|
}
|
|
if iLvl > 0 && (**(**TFts5StructureLevel)(__ccgo_up(pLvl + uintptr(-libc.Int32FromInt32(1))*16))).FnMerge != 0 && **(**int32)(__ccgo_up(bp + 12)) == 0 {
|
|
**(**int32)(__ccgo_up(bp)) = libc.Int32FromInt32(SQLITE_CORRUPT) | libc.Int32FromInt32(1)<<libc.Int32FromInt32(8)
|
|
}
|
|
if iLvl == **(**int32)(__ccgo_up(bp + 4))-int32(1) && (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnMerge != 0 {
|
|
**(**int32)(__ccgo_up(bp)) = libc.Int32FromInt32(SQLITE_CORRUPT) | libc.Int32FromInt32(1)<<libc.Int32FromInt32(8)
|
|
}
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
iLvl = iLvl + 1
|
|
}
|
|
if **(**int32)(__ccgo_up(bp + 8)) != 0 && **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
|
|
**(**int32)(__ccgo_up(bp)) = libc.Int32FromInt32(SQLITE_CORRUPT) | libc.Int32FromInt32(1)<<libc.Int32FromInt32(8)
|
|
}
|
|
if bStructureV2 != 0 {
|
|
(*TFts5Structure)(unsafe.Pointer(pRet)).FnOriginCntr = nOriginCntr + uint64(1)
|
|
}
|
|
if **(**int32)(__ccgo_up(bp)) != SQLITE_OK {
|
|
_fts5StructureRelease(tls, pRet)
|
|
pRet = uintptr(0)
|
|
}
|
|
}
|
|
**(**uintptr)(__ccgo_up(ppOut)) = pRet
|
|
return **(**int32)(__ccgo_up(bp))
|
|
}
|
|
|
|
func _fts5StructureReadUncached(tls *libc.TLS, p uintptr) (r uintptr) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var pConfig, pData uintptr
|
|
var _ /* iCookie at bp+8 */ int32
|
|
var _ /* pRet at bp+0 */ uintptr
|
|
_, _ = pConfig, pData
|
|
**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
|
|
pConfig = (*TFts5Index)(unsafe.Pointer(p)).FpConfig
|
|
pData = _fts5DataRead(tls, p, int64(FTS5_STRUCTURE_ROWID))
|
|
if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
/* TODO: Do we need this if the leaf-index is appended? Probably... */
|
|
libc.Xmemset(tls, (*TFts5Data)(unsafe.Pointer(pData)).Fp+uintptr((*TFts5Data)(unsafe.Pointer(pData)).Fnn), 0, uint64(FTS5_DATA_PADDING))
|
|
(*TFts5Index)(unsafe.Pointer(p)).Frc = _fts5StructureDecode(tls, (*TFts5Data)(unsafe.Pointer(pData)).Fp, (*TFts5Data)(unsafe.Pointer(pData)).Fnn, bp+8, bp)
|
|
if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
if (*TFts5Config)(unsafe.Pointer(pConfig)).Fpgsz == 0 || (*TFts5Config)(unsafe.Pointer(pConfig)).FiCookie != **(**int32)(__ccgo_up(bp + 8)) {
|
|
(*TFts5Index)(unsafe.Pointer(p)).Frc = _sqlite3Fts5ConfigLoad(tls, pConfig, **(**int32)(__ccgo_up(bp + 8)))
|
|
}
|
|
} else {
|
|
if (*TFts5Index)(unsafe.Pointer(p)).Frc == libc.Int32FromInt32(SQLITE_CORRUPT)|libc.Int32FromInt32(1)<<libc.Int32FromInt32(8) {
|
|
_sqlite3Fts5ConfigErrmsg(tls, (*TFts5Index)(unsafe.Pointer(p)).FpConfig, __ccgo_ts+39117, libc.VaList(bp+24, (*TFts5Config)(unsafe.Pointer((*TFts5Index)(unsafe.Pointer(p)).FpConfig)).FzName))
|
|
}
|
|
}
|
|
_fts5DataRelease(tls, pData)
|
|
if (*TFts5Index)(unsafe.Pointer(p)).Frc != SQLITE_OK {
|
|
_fts5StructureRelease(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
|
|
}
|
|
}
|
|
return **(**uintptr)(__ccgo_up(bp))
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Serialize and store the "structure" record.
|
|
// **
|
|
// ** If an error occurs, leave an error code in the Fts5Index object. If an
|
|
// ** error has already occurred, this function is a no-op.
|
|
// */
|
|
func _fts5StructureWrite(tls *libc.TLS, p uintptr, pStruct uintptr) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var iCookie, iLvl, iSeg, nHdr, v1 int32
|
|
var pLvl, pSeg uintptr
|
|
var _ /* buf at bp+0 */ TFts5Buffer
|
|
_, _, _, _, _, _, _ = iCookie, iLvl, iSeg, nHdr, pLvl, pSeg, v1
|
|
if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
if (*TFts5Structure)(unsafe.Pointer(pStruct)).FnOriginCntr > uint64(0) {
|
|
v1 = libc.Int32FromInt32(4) + libc.Int32FromInt32(4) + libc.Int32FromInt32(9) + libc.Int32FromInt32(9) + libc.Int32FromInt32(9)
|
|
} else {
|
|
v1 = libc.Int32FromInt32(4) + libc.Int32FromInt32(9) + libc.Int32FromInt32(9)
|
|
} /* Cookie value to store */
|
|
nHdr = v1
|
|
libc.Xmemset(tls, bp, 0, uint64(16))
|
|
/* Append the current configuration cookie */
|
|
iCookie = (*TFts5Config)(unsafe.Pointer((*TFts5Index)(unsafe.Pointer(p)).FpConfig)).FiCookie
|
|
if iCookie < 0 {
|
|
iCookie = 0
|
|
}
|
|
if 0 == _sqlite3Fts5BufferSize(tls, p+60, bp, libc.Uint32FromInt32(nHdr)) {
|
|
_sqlite3Fts5Put32(tls, (**(**TFts5Buffer)(__ccgo_up(bp))).Fp, iCookie)
|
|
(**(**TFts5Buffer)(__ccgo_up(bp))).Fn = int32(4)
|
|
if (*TFts5Structure)(unsafe.Pointer(pStruct)).FnOriginCntr > uint64(0) {
|
|
libc.Xmemcpy(tls, (*TFts5Buffer)(unsafe.Pointer(bp)).Fp+uintptr((*TFts5Buffer)(unsafe.Pointer(bp)).Fn), __ccgo_ts+39112, uint64(4))
|
|
**(**int32)(__ccgo_up(bp + 8)) += int32(4)
|
|
}
|
|
**(**int32)(__ccgo_up(bp + 8)) += _sqlite3Fts5PutVarint(tls, (*TFts5Buffer)(unsafe.Pointer(bp)).Fp+uintptr((*TFts5Buffer)(unsafe.Pointer(bp)).Fn), libc.Uint64FromInt32((*TFts5Structure)(unsafe.Pointer(pStruct)).FnLevel))
|
|
**(**int32)(__ccgo_up(bp + 8)) += _sqlite3Fts5PutVarint(tls, (*TFts5Buffer)(unsafe.Pointer(bp)).Fp+uintptr((*TFts5Buffer)(unsafe.Pointer(bp)).Fn), libc.Uint64FromInt32((*TFts5Structure)(unsafe.Pointer(pStruct)).FnSegment))
|
|
**(**int32)(__ccgo_up(bp + 8)) += _sqlite3Fts5PutVarint(tls, (*TFts5Buffer)(unsafe.Pointer(bp)).Fp+uintptr((*TFts5Buffer)(unsafe.Pointer(bp)).Fn), libc.Uint64FromInt64(libc.Int64FromUint64((*TFts5Structure)(unsafe.Pointer(pStruct)).FnWriteCounter)))
|
|
}
|
|
iLvl = 0
|
|
for {
|
|
if !(iLvl < (*TFts5Structure)(unsafe.Pointer(pStruct)).FnLevel) {
|
|
break
|
|
} /* Used to iterate through segments */
|
|
pLvl = pStruct + 32 + uintptr(iLvl)*16
|
|
_sqlite3Fts5BufferAppendVarint(tls, p+60, bp, int64((*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnMerge))
|
|
_sqlite3Fts5BufferAppendVarint(tls, p+60, bp, int64((*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnSeg))
|
|
iSeg = 0
|
|
for {
|
|
if !(iSeg < (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnSeg) {
|
|
break
|
|
}
|
|
pSeg = (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FaSeg + uintptr(iSeg)*56
|
|
_sqlite3Fts5BufferAppendVarint(tls, p+60, bp, int64((*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FiSegid))
|
|
_sqlite3Fts5BufferAppendVarint(tls, p+60, bp, int64((*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FpgnoFirst))
|
|
_sqlite3Fts5BufferAppendVarint(tls, p+60, bp, int64((*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FpgnoLast))
|
|
if (*TFts5Structure)(unsafe.Pointer(pStruct)).FnOriginCntr > uint64(0) {
|
|
_sqlite3Fts5BufferAppendVarint(tls, p+60, bp, libc.Int64FromUint64((*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FiOrigin1))
|
|
_sqlite3Fts5BufferAppendVarint(tls, p+60, bp, libc.Int64FromUint64((*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FiOrigin2))
|
|
_sqlite3Fts5BufferAppendVarint(tls, p+60, bp, int64((*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FnPgTombstone))
|
|
_sqlite3Fts5BufferAppendVarint(tls, p+60, bp, libc.Int64FromUint64((*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FnEntryTombstone))
|
|
_sqlite3Fts5BufferAppendVarint(tls, p+60, bp, libc.Int64FromUint64((*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FnEntry))
|
|
}
|
|
goto _3
|
|
_3:
|
|
;
|
|
iSeg = iSeg + 1
|
|
}
|
|
goto _2
|
|
_2:
|
|
;
|
|
iLvl = iLvl + 1
|
|
}
|
|
_fts5DataWrite(tls, p, int64(FTS5_STRUCTURE_ROWID), (**(**TFts5Buffer)(__ccgo_up(bp))).Fp, (**(**TFts5Buffer)(__ccgo_up(bp))).Fn)
|
|
_sqlite3Fts5BufferFree(tls, bp)
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This function is the implementation of the xUpdate callback used by
|
|
// ** FTS3 virtual tables. It is invoked by SQLite each time a row is to be
|
|
// ** inserted, updated or deleted.
|
|
// **
|
|
// ** A delete specifies a single argument - the rowid of the row to remove.
|
|
// **
|
|
// ** Update and insert operations pass:
|
|
// **
|
|
// ** 1. The "old" rowid, or NULL.
|
|
// ** 2. The "new" rowid.
|
|
// ** 3. Values for each of the nCol matchable columns.
|
|
// ** 4. Values for the two hidden columns (<tablename> and "rank").
|
|
// */
|
|
func _fts5UpdateMethod(tls *libc.TLS, pVtab uintptr, nArg int32, apVal uintptr, pRowid uintptr) (r int32) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var eConflict, eType0, eType1, ii int32
|
|
var iDel, iNew, iNew1, iOld Ti64
|
|
var pConfig, pStorage, pTab, pVal, z uintptr
|
|
var _ /* bContent at bp+4 */ int32
|
|
var _ /* rc at bp+0 */ int32
|
|
_, _, _, _, _, _, _, _, _, _, _, _, _ = eConflict, eType0, eType1, iDel, iNew, iNew1, iOld, ii, pConfig, pStorage, pTab, pVal, z
|
|
pTab = pVtab
|
|
pConfig = (*TFts5FullTable)(unsafe.Pointer(pTab)).Fp.FpConfig /* value_type() of apVal[0] */
|
|
**(**int32)(__ccgo_up(bp)) = SQLITE_OK /* Return code */
|
|
/* A transaction must be open when this is called. */
|
|
if (*TFts5Config)(unsafe.Pointer(pConfig)).Fpgsz == 0 {
|
|
**(**int32)(__ccgo_up(bp)) = _sqlite3Fts5ConfigLoad(tls, (*TFts5FullTable)(unsafe.Pointer(pTab)).Fp.FpConfig, (*TFts5Config)(unsafe.Pointer((*TFts5FullTable)(unsafe.Pointer(pTab)).Fp.FpConfig)).FiCookie)
|
|
if **(**int32)(__ccgo_up(bp)) != SQLITE_OK {
|
|
return **(**int32)(__ccgo_up(bp))
|
|
}
|
|
}
|
|
(*TFts5Config)(unsafe.Pointer((*TFts5FullTable)(unsafe.Pointer(pTab)).Fp.FpConfig)).FpzErrmsg = pTab + 16
|
|
/* Put any active cursors into REQUIRE_SEEK state. */
|
|
_fts5TripCursors(tls, pTab)
|
|
eType0 = Xsqlite3_value_type(tls, **(**uintptr)(__ccgo_up(apVal)))
|
|
if eType0 == int32(SQLITE_NULL) && Xsqlite3_value_type(tls, **(**uintptr)(__ccgo_up(apVal + uintptr(int32(2)+(*TFts5Config)(unsafe.Pointer(pConfig)).FnCol)*8))) != int32(SQLITE_NULL) {
|
|
/* A "special" INSERT op. These are handled separately. */
|
|
z = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(apVal + uintptr(int32(2)+(*TFts5Config)(unsafe.Pointer(pConfig)).FnCol)*8)))
|
|
if (*TFts5Config)(unsafe.Pointer(pConfig)).FeContent != FTS5_CONTENT_NORMAL && 0 == Xsqlite3_stricmp(tls, __ccgo_ts+19178, z) {
|
|
if (*TFts5Config)(unsafe.Pointer(pConfig)).FbContentlessDelete != 0 {
|
|
_fts5SetVtabError(tls, pTab, __ccgo_ts+40309, 0)
|
|
**(**int32)(__ccgo_up(bp)) = int32(SQLITE_ERROR)
|
|
} else {
|
|
**(**int32)(__ccgo_up(bp)) = _fts5SpecialDelete(tls, pTab, apVal)
|
|
}
|
|
} else {
|
|
**(**int32)(__ccgo_up(bp)) = _fts5SpecialInsert(tls, pTab, z, **(**uintptr)(__ccgo_up(apVal + uintptr(int32(2)+(*TFts5Config)(unsafe.Pointer(pConfig)).FnCol+int32(1))*8)))
|
|
}
|
|
} else {
|
|
/* A regular INSERT, UPDATE or DELETE statement. The trick here is that
|
|
** any conflict on the rowid value must be detected before any
|
|
** modifications are made to the database file. There are 4 cases:
|
|
**
|
|
** 1) DELETE
|
|
** 2) UPDATE (rowid not modified)
|
|
** 3) UPDATE (rowid modified)
|
|
** 4) INSERT
|
|
**
|
|
** Cases 3 and 4 may violate the rowid constraint.
|
|
*/
|
|
eConflict = int32(SQLITE_ABORT)
|
|
if (*TFts5Config)(unsafe.Pointer(pConfig)).FeContent == FTS5_CONTENT_NORMAL || (*TFts5Config)(unsafe.Pointer(pConfig)).FbContentlessDelete != 0 {
|
|
eConflict = Xsqlite3_vtab_on_conflict(tls, (*TFts5Config)(unsafe.Pointer(pConfig)).Fdb)
|
|
}
|
|
/* DELETE */
|
|
if nArg == int32(1) {
|
|
/* It is only possible to DELETE from a contentless table if the
|
|
** contentless_delete=1 flag is set. */
|
|
if _fts5IsContentless(tls, pTab, int32(1)) != 0 && (*TFts5Config)(unsafe.Pointer(pConfig)).FbContentlessDelete == 0 {
|
|
_fts5SetVtabError(tls, pTab, __ccgo_ts+40368, libc.VaList(bp+16, (*TFts5Config)(unsafe.Pointer(pConfig)).FzName))
|
|
**(**int32)(__ccgo_up(bp)) = int32(SQLITE_ERROR)
|
|
} else {
|
|
iDel = Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(apVal))) /* Rowid to delete */
|
|
**(**int32)(__ccgo_up(bp)) = _sqlite3Fts5StorageDelete(tls, (*TFts5FullTable)(unsafe.Pointer(pTab)).FpStorage, iDel, uintptr(0), 0)
|
|
}
|
|
} else {
|
|
eType1 = Xsqlite3_value_numeric_type(tls, **(**uintptr)(__ccgo_up(apVal + 1*8)))
|
|
/* It is an error to write an fts5_locale() value to a table without
|
|
** the locale=1 option. */
|
|
if (*TFts5Config)(unsafe.Pointer(pConfig)).FbLocale == 0 {
|
|
ii = 0
|
|
for {
|
|
if !(ii < (*TFts5Config)(unsafe.Pointer(pConfig)).FnCol) {
|
|
break
|
|
}
|
|
pVal = **(**uintptr)(__ccgo_up(apVal + uintptr(ii+int32(2))*8))
|
|
if _sqlite3Fts5IsLocaleValue(tls, pConfig, pVal) != 0 {
|
|
_fts5SetVtabError(tls, pTab, __ccgo_ts+40414, 0)
|
|
**(**int32)(__ccgo_up(bp)) = int32(SQLITE_MISMATCH)
|
|
goto update_out
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
ii = ii + 1
|
|
}
|
|
}
|
|
if eType0 != int32(SQLITE_INTEGER) {
|
|
/* An INSERT statement. If the conflict-mode is REPLACE, first remove
|
|
** the current entry (if any). */
|
|
if eConflict == int32(SQLITE_REPLACE) && eType1 == int32(SQLITE_INTEGER) {
|
|
iNew = Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(apVal + 1*8))) /* Rowid to delete */
|
|
**(**int32)(__ccgo_up(bp)) = _sqlite3Fts5StorageDelete(tls, (*TFts5FullTable)(unsafe.Pointer(pTab)).FpStorage, iNew, uintptr(0), 0)
|
|
}
|
|
_fts5StorageInsert(tls, bp, pTab, apVal, pRowid)
|
|
} else {
|
|
pStorage = (*TFts5FullTable)(unsafe.Pointer(pTab)).FpStorage
|
|
iOld = Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(apVal))) /* Old rowid */
|
|
iNew1 = Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(apVal + 1*8))) /* New rowid */
|
|
**(**int32)(__ccgo_up(bp + 4)) = 0 /* Content only update */
|
|
/* If this is a contentless table (including contentless_unindexed=1
|
|
** tables), check if the UPDATE may proceed. */
|
|
if _fts5IsContentless(tls, pTab, int32(1)) != 0 {
|
|
**(**int32)(__ccgo_up(bp)) = _fts5ContentlessUpdate(tls, pConfig, apVal+2*8, libc.BoolInt32(iOld != iNew1), bp+4)
|
|
if **(**int32)(__ccgo_up(bp)) != SQLITE_OK {
|
|
goto update_out
|
|
}
|
|
}
|
|
if eType1 != int32(SQLITE_INTEGER) {
|
|
**(**int32)(__ccgo_up(bp)) = int32(SQLITE_MISMATCH)
|
|
} else {
|
|
if iOld != iNew1 {
|
|
if eConflict == int32(SQLITE_REPLACE) {
|
|
**(**int32)(__ccgo_up(bp)) = _sqlite3Fts5StorageDelete(tls, pStorage, iOld, uintptr(0), int32(1))
|
|
if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
|
|
**(**int32)(__ccgo_up(bp)) = _sqlite3Fts5StorageDelete(tls, pStorage, iNew1, uintptr(0), 0)
|
|
}
|
|
_fts5StorageInsert(tls, bp, pTab, apVal, pRowid)
|
|
} else {
|
|
**(**int32)(__ccgo_up(bp)) = _sqlite3Fts5StorageFindDeleteRow(tls, pStorage, iOld)
|
|
if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
|
|
**(**int32)(__ccgo_up(bp)) = _sqlite3Fts5StorageContentInsert(tls, pStorage, 0, apVal, pRowid)
|
|
}
|
|
if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
|
|
**(**int32)(__ccgo_up(bp)) = _sqlite3Fts5StorageDelete(tls, pStorage, iOld, uintptr(0), 0)
|
|
}
|
|
if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
|
|
**(**int32)(__ccgo_up(bp)) = _sqlite3Fts5StorageIndexInsert(tls, pStorage, apVal, **(**Tsqlite_int64)(__ccgo_up(pRowid)))
|
|
}
|
|
}
|
|
} else {
|
|
if **(**int32)(__ccgo_up(bp + 4)) != 0 {
|
|
/* This occurs when an UPDATE on a contentless table affects *only*
|
|
** UNINDEXED columns. This is a no-op for contentless_unindexed=0
|
|
** tables, or a write to the %_content table only for =1 tables. */
|
|
**(**int32)(__ccgo_up(bp)) = _sqlite3Fts5StorageFindDeleteRow(tls, pStorage, iOld)
|
|
if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
|
|
**(**int32)(__ccgo_up(bp)) = _sqlite3Fts5StorageContentInsert(tls, pStorage, int32(1), apVal, pRowid)
|
|
}
|
|
} else {
|
|
**(**int32)(__ccgo_up(bp)) = _sqlite3Fts5StorageDelete(tls, pStorage, iOld, uintptr(0), int32(1))
|
|
_fts5StorageInsert(tls, bp, pTab, apVal, pRowid)
|
|
}
|
|
}
|
|
}
|
|
_sqlite3Fts5StorageReleaseDeleteRow(tls, pStorage)
|
|
}
|
|
}
|
|
}
|
|
goto update_out
|
|
update_out:
|
|
;
|
|
_sqlite3Fts5IndexCloseReader(tls, (*TFts5FullTable)(unsafe.Pointer(pTab)).Fp.FpIndex)
|
|
(*TFts5Config)(unsafe.Pointer((*TFts5FullTable)(unsafe.Pointer(pTab)).Fp.FpConfig)).FpzErrmsg = uintptr(0)
|
|
return **(**int32)(__ccgo_up(bp))
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This is the xFilter implementation for the virtual table.
|
|
// */
|
|
func _fts5VocabFilterMethod(tls *libc.TLS, pCursor uintptr, idxNum int32, zUnused uintptr, nUnused int32, apVal uintptr) (r int32) {
|
|
var eType, f, iVal, nTerm, rc, v1 int32
|
|
var pCsr, pEq, pGe, pIndex, pLe, pTab, zCopy, zTerm uintptr
|
|
_, _, _, _, _, _, _, _, _, _, _, _, _, _ = eType, f, iVal, nTerm, pCsr, pEq, pGe, pIndex, pLe, pTab, rc, zCopy, zTerm, v1
|
|
pTab = (*Tsqlite3_vtab_cursor)(unsafe.Pointer(pCursor)).FpVtab
|
|
pCsr = pCursor
|
|
eType = (*TFts5VocabTable)(unsafe.Pointer(pTab)).FeType
|
|
rc = SQLITE_OK
|
|
iVal = 0
|
|
f = int32(FTS5INDEX_QUERY_SCAN)
|
|
zTerm = uintptr(0)
|
|
nTerm = 0
|
|
pEq = uintptr(0)
|
|
pGe = uintptr(0)
|
|
pLe = uintptr(0)
|
|
_ = zUnused
|
|
_ = nUnused
|
|
_fts5VocabResetCursor(tls, pCsr)
|
|
if idxNum&int32(FTS5_VOCAB_TERM_EQ) != 0 {
|
|
v1 = iVal
|
|
iVal = iVal + 1
|
|
pEq = **(**uintptr)(__ccgo_up(apVal + uintptr(v1)*8))
|
|
}
|
|
if idxNum&int32(FTS5_VOCAB_TERM_GE) != 0 {
|
|
v1 = iVal
|
|
iVal = iVal + 1
|
|
pGe = **(**uintptr)(__ccgo_up(apVal + uintptr(v1)*8))
|
|
}
|
|
if idxNum&int32(FTS5_VOCAB_TERM_LE) != 0 {
|
|
v1 = iVal
|
|
iVal = iVal + 1
|
|
pLe = **(**uintptr)(__ccgo_up(apVal + uintptr(v1)*8))
|
|
}
|
|
(*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FcolUsed = idxNum & int32(FTS5_VOCAB_COLUSED_MASK)
|
|
if pEq != 0 {
|
|
zTerm = Xsqlite3_value_text(tls, pEq)
|
|
nTerm = Xsqlite3_value_bytes(tls, pEq)
|
|
f = int32(FTS5INDEX_QUERY_NOTOKENDATA)
|
|
} else {
|
|
if pGe != 0 {
|
|
zTerm = Xsqlite3_value_text(tls, pGe)
|
|
nTerm = Xsqlite3_value_bytes(tls, pGe)
|
|
}
|
|
if pLe != 0 {
|
|
zCopy = Xsqlite3_value_text(tls, pLe)
|
|
if zCopy == uintptr(0) {
|
|
zCopy = __ccgo_ts + 1704
|
|
}
|
|
(*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FnLeTerm = Xsqlite3_value_bytes(tls, pLe)
|
|
(*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FzLeTerm = Xsqlite3_malloc64(tls, libc.Uint64FromInt64(int64((*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FnLeTerm)+int64(1)))
|
|
if (*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FzLeTerm == uintptr(0) {
|
|
rc = int32(SQLITE_NOMEM)
|
|
} else {
|
|
libc.Xmemcpy(tls, (*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FzLeTerm, zCopy, libc.Uint64FromInt32((*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FnLeTerm+int32(1)))
|
|
}
|
|
}
|
|
}
|
|
if rc == SQLITE_OK {
|
|
pIndex = (*TFts5Table)(unsafe.Pointer((*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FpFts5)).FpIndex
|
|
rc = _sqlite3Fts5IndexQuery(tls, pIndex, zTerm, nTerm, f, uintptr(0), pCsr+32)
|
|
if rc == SQLITE_OK {
|
|
(*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FpStruct = _sqlite3Fts5StructureRef(tls, pIndex)
|
|
}
|
|
}
|
|
if rc == SQLITE_OK && eType == int32(FTS5_VOCAB_INSTANCE) {
|
|
rc = _fts5VocabInstanceNewTerm(tls, pCsr)
|
|
}
|
|
if rc == SQLITE_OK && !((*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FbEof != 0) && (eType != int32(FTS5_VOCAB_INSTANCE) || (*TFts5Config)(unsafe.Pointer((*TFts5Table)(unsafe.Pointer((*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FpFts5)).FpConfig)).FeDetail != int32(FTS5_DETAIL_NONE)) {
|
|
rc = _fts5VocabNextMethod(tls, pCursor)
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This function is the implementation of both the xConnect and xCreate
|
|
// ** methods of the FTS3 virtual table.
|
|
// **
|
|
// ** The argv[] array contains the following:
|
|
// **
|
|
// ** argv[0] -> module name ("fts5vocab")
|
|
// ** argv[1] -> database name
|
|
// ** argv[2] -> table name
|
|
// **
|
|
// ** then:
|
|
// **
|
|
// ** argv[3] -> name of fts5 table
|
|
// ** argv[4] -> type of fts5vocab table
|
|
// **
|
|
// ** or, for tables in the TEMP schema only.
|
|
// **
|
|
// ** argv[3] -> name of fts5 tables database
|
|
// ** argv[4] -> name of fts5 table
|
|
// ** argv[5] -> type of fts5vocab table
|
|
// */
|
|
func _fts5VocabInitVtab(tls *libc.TLS, db uintptr, pAux uintptr, argc int32, argv uintptr, ppVTab uintptr, pzErr uintptr) (r int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var azSchema [3]uintptr
|
|
var bDb int32
|
|
var nByte, nDb, nTab Ti64
|
|
var pRet, zDb, zTab, zType, v1, v2, v3 uintptr
|
|
var _ /* eType at bp+4 */ int32
|
|
var _ /* rc at bp+0 */ int32
|
|
_, _, _, _, _, _, _, _, _, _, _, _ = azSchema, bDb, nByte, nDb, nTab, pRet, zDb, zTab, zType, v1, v2, v3
|
|
azSchema = [3]uintptr{
|
|
0: __ccgo_ts + 42294,
|
|
1: __ccgo_ts + 42334,
|
|
2: __ccgo_ts + 42369,
|
|
}
|
|
pRet = uintptr(0)
|
|
**(**int32)(__ccgo_up(bp)) = SQLITE_OK
|
|
bDb = libc.BoolInt32(argc == int32(6) && libc.Xstrlen(tls, **(**uintptr)(__ccgo_up(argv + 1*8))) == uint64(4) && libc.Xmemcmp(tls, __ccgo_ts+25288, **(**uintptr)(__ccgo_up(argv + 1*8)), uint64(4)) == 0)
|
|
if argc != int32(5) && bDb == 0 {
|
|
**(**uintptr)(__ccgo_up(pzErr)) = Xsqlite3_mprintf(tls, __ccgo_ts+42412, 0)
|
|
**(**int32)(__ccgo_up(bp)) = int32(SQLITE_ERROR)
|
|
} else {
|
|
if bDb != 0 {
|
|
v1 = **(**uintptr)(__ccgo_up(argv + 3*8))
|
|
} else {
|
|
v1 = **(**uintptr)(__ccgo_up(argv + 1*8))
|
|
} /* Bytes of space to allocate */
|
|
zDb = v1
|
|
if bDb != 0 {
|
|
v2 = **(**uintptr)(__ccgo_up(argv + 4*8))
|
|
} else {
|
|
v2 = **(**uintptr)(__ccgo_up(argv + 3*8))
|
|
}
|
|
zTab = v2
|
|
if bDb != 0 {
|
|
v3 = **(**uintptr)(__ccgo_up(argv + 5*8))
|
|
} else {
|
|
v3 = **(**uintptr)(__ccgo_up(argv + 4*8))
|
|
}
|
|
zType = v3
|
|
nDb = libc.Int64FromUint64(libc.Xstrlen(tls, zDb) + uint64(1))
|
|
nTab = libc.Int64FromUint64(libc.Xstrlen(tls, zTab) + uint64(1))
|
|
**(**int32)(__ccgo_up(bp + 4)) = 0
|
|
**(**int32)(__ccgo_up(bp)) = _fts5VocabTableType(tls, zType, pzErr, bp+4)
|
|
if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
|
|
**(**int32)(__ccgo_up(bp)) = Xsqlite3_declare_vtab(tls, db, azSchema[**(**int32)(__ccgo_up(bp + 4))])
|
|
}
|
|
nByte = libc.Int64FromUint64(uint64(64) + libc.Uint64FromInt64(nDb) + libc.Uint64FromInt64(nTab))
|
|
pRet = _sqlite3Fts5MallocZero(tls, bp, nByte)
|
|
if pRet != 0 {
|
|
(*TFts5VocabTable)(unsafe.Pointer(pRet)).FpGlobal = pAux
|
|
(*TFts5VocabTable)(unsafe.Pointer(pRet)).FeType = **(**int32)(__ccgo_up(bp + 4))
|
|
(*TFts5VocabTable)(unsafe.Pointer(pRet)).Fdb = db
|
|
(*TFts5VocabTable)(unsafe.Pointer(pRet)).FzFts5Tbl = pRet + 1*64
|
|
(*TFts5VocabTable)(unsafe.Pointer(pRet)).FzFts5Db = (*TFts5VocabTable)(unsafe.Pointer(pRet)).FzFts5Tbl + uintptr(nTab)
|
|
libc.Xmemcpy(tls, (*TFts5VocabTable)(unsafe.Pointer(pRet)).FzFts5Tbl, zTab, libc.Uint64FromInt64(nTab))
|
|
libc.Xmemcpy(tls, (*TFts5VocabTable)(unsafe.Pointer(pRet)).FzFts5Db, zDb, libc.Uint64FromInt64(nDb))
|
|
_sqlite3Fts5Dequote(tls, (*TFts5VocabTable)(unsafe.Pointer(pRet)).FzFts5Tbl)
|
|
_sqlite3Fts5Dequote(tls, (*TFts5VocabTable)(unsafe.Pointer(pRet)).FzFts5Db)
|
|
}
|
|
}
|
|
**(**uintptr)(__ccgo_up(ppVTab)) = pRet
|
|
return **(**int32)(__ccgo_up(bp))
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Implementation of xOpen method.
|
|
// */
|
|
func _fts5VocabOpenMethod(tls *libc.TLS, pVTab uintptr, ppCsr uintptr) (r int32) {
|
|
bp := tls.Alloc(64)
|
|
defer tls.Free(64)
|
|
var iId, nByte Ti64
|
|
var pCsr, pFts5, pTab, zSql uintptr
|
|
var _ /* pStmt at bp+8 */ uintptr
|
|
var _ /* rc at bp+0 */ int32
|
|
_, _, _, _, _, _ = iId, nByte, pCsr, pFts5, pTab, zSql
|
|
pTab = pVTab
|
|
pFts5 = uintptr(0)
|
|
pCsr = uintptr(0)
|
|
**(**int32)(__ccgo_up(bp)) = SQLITE_OK
|
|
**(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0)
|
|
zSql = uintptr(0)
|
|
if (*TFts5VocabTable)(unsafe.Pointer(pTab)).FbBusy != 0 {
|
|
(*Tsqlite3_vtab)(unsafe.Pointer(pVTab)).FzErrMsg = Xsqlite3_mprintf(tls, __ccgo_ts+42445, libc.VaList(bp+24, (*TFts5VocabTable)(unsafe.Pointer(pTab)).FzFts5Db, (*TFts5VocabTable)(unsafe.Pointer(pTab)).FzFts5Tbl))
|
|
return int32(SQLITE_ERROR)
|
|
}
|
|
zSql = _sqlite3Fts5Mprintf(tls, bp, __ccgo_ts+42476, libc.VaList(bp+24, (*TFts5VocabTable)(unsafe.Pointer(pTab)).FzFts5Tbl, (*TFts5VocabTable)(unsafe.Pointer(pTab)).FzFts5Db, (*TFts5VocabTable)(unsafe.Pointer(pTab)).FzFts5Tbl, (*TFts5VocabTable)(unsafe.Pointer(pTab)).FzFts5Tbl))
|
|
if zSql != 0 {
|
|
**(**int32)(__ccgo_up(bp)) = Xsqlite3_prepare_v2(tls, (*TFts5VocabTable)(unsafe.Pointer(pTab)).Fdb, zSql, -int32(1), bp+8, uintptr(0))
|
|
}
|
|
Xsqlite3_free(tls, zSql)
|
|
if **(**int32)(__ccgo_up(bp)) == int32(SQLITE_ERROR) {
|
|
**(**int32)(__ccgo_up(bp)) = SQLITE_OK
|
|
}
|
|
(*TFts5VocabTable)(unsafe.Pointer(pTab)).FbBusy = uint32(1)
|
|
if **(**uintptr)(__ccgo_up(bp + 8)) != 0 && Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp + 8))) == int32(SQLITE_ROW) {
|
|
iId = Xsqlite3_column_int64(tls, **(**uintptr)(__ccgo_up(bp + 8)), 0)
|
|
pFts5 = _sqlite3Fts5TableFromCsrid(tls, (*TFts5VocabTable)(unsafe.Pointer(pTab)).FpGlobal, iId)
|
|
}
|
|
(*TFts5VocabTable)(unsafe.Pointer(pTab)).FbBusy = uint32(0)
|
|
if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
|
|
if pFts5 == uintptr(0) {
|
|
**(**int32)(__ccgo_up(bp)) = Xsqlite3_finalize(tls, **(**uintptr)(__ccgo_up(bp + 8)))
|
|
**(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0)
|
|
if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
|
|
(*Tsqlite3_vtab)(unsafe.Pointer(pVTab)).FzErrMsg = Xsqlite3_mprintf(tls, __ccgo_ts+42527, libc.VaList(bp+24, (*TFts5VocabTable)(unsafe.Pointer(pTab)).FzFts5Db, (*TFts5VocabTable)(unsafe.Pointer(pTab)).FzFts5Tbl))
|
|
**(**int32)(__ccgo_up(bp)) = int32(SQLITE_ERROR)
|
|
}
|
|
} else {
|
|
**(**int32)(__ccgo_up(bp)) = _sqlite3Fts5FlushToDisk(tls, pFts5)
|
|
}
|
|
}
|
|
if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
|
|
nByte = libc.Int64FromUint64(libc.Uint64FromInt32((*TFts5Config)(unsafe.Pointer((*TFts5Table)(unsafe.Pointer(pFts5)).FpConfig)).FnCol)*uint64(8)*uint64(2) + uint64(128))
|
|
pCsr = _sqlite3Fts5MallocZero(tls, bp, nByte)
|
|
}
|
|
if pCsr != 0 {
|
|
(*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FpFts5 = pFts5
|
|
(*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FpStmt = **(**uintptr)(__ccgo_up(bp + 8))
|
|
(*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FaCnt = pCsr + 1*128
|
|
(*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FaDoc = (*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FaCnt + uintptr((*TFts5Config)(unsafe.Pointer((*TFts5Table)(unsafe.Pointer(pFts5)).FpConfig)).FnCol)*8
|
|
} else {
|
|
Xsqlite3_finalize(tls, **(**uintptr)(__ccgo_up(bp + 8)))
|
|
}
|
|
**(**uintptr)(__ccgo_up(ppCsr)) = pCsr
|
|
return **(**int32)(__ccgo_up(bp))
|
|
}
|
|
|
|
func _fts5WriteInit(tls *libc.TLS, p uintptr, pWriter uintptr, iSegid int32) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var nBuffer int32
|
|
var pConfig uintptr
|
|
_, _ = nBuffer, pConfig
|
|
nBuffer = (*TFts5Config)(unsafe.Pointer((*TFts5Index)(unsafe.Pointer(p)).FpConfig)).Fpgsz + int32(FTS5_DATA_PADDING)
|
|
libc.Xmemset(tls, pWriter, 0, uint64(120))
|
|
(*TFts5SegWriter)(unsafe.Pointer(pWriter)).FiSegid = iSegid
|
|
_fts5WriteDlidxGrow(tls, p, pWriter, int32(1))
|
|
(*TFts5SegWriter)(unsafe.Pointer(pWriter)).Fwriter.Fpgno = int32(1)
|
|
(*TFts5SegWriter)(unsafe.Pointer(pWriter)).FbFirstTermInPage = uint8(1)
|
|
(*TFts5SegWriter)(unsafe.Pointer(pWriter)).FiBtPage = int32(1)
|
|
/* Grow the two buffers to pgsz + padding bytes in size. */
|
|
_sqlite3Fts5BufferSize(tls, p+60, pWriter+8+24, libc.Uint32FromInt32(nBuffer))
|
|
_sqlite3Fts5BufferSize(tls, p+60, pWriter+8+8, libc.Uint32FromInt32(nBuffer))
|
|
if (*TFts5Index)(unsafe.Pointer(p)).FpIdxWriter == uintptr(0) {
|
|
pConfig = (*TFts5Index)(unsafe.Pointer(p)).FpConfig
|
|
_fts5IndexPrepareStmt(tls, p, p+96, Xsqlite3_mprintf(tls, __ccgo_ts+39352, libc.VaList(bp+8, (*TFts5Config)(unsafe.Pointer(pConfig)).FzDb, (*TFts5Config)(unsafe.Pointer(pConfig)).FzName)))
|
|
}
|
|
if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
/* Initialize the 4-byte leaf-page header to 0x00. */
|
|
libc.Xmemset(tls, (*TFts5SegWriter)(unsafe.Pointer(pWriter)).Fwriter.Fbuf.Fp, 0, uint64(4))
|
|
(*TFts5SegWriter)(unsafe.Pointer(pWriter)).Fwriter.Fbuf.Fn = int32(4)
|
|
/* Bind the current output segment id to the index-writer. This is an
|
|
** optimization over binding the same value over and over as rows are
|
|
** inserted into %_idx by the current writer. */
|
|
Xsqlite3_bind_int(tls, (*TFts5Index)(unsafe.Pointer(p)).FpIdxWriter, int32(1), (*TFts5SegWriter)(unsafe.Pointer(pWriter)).FiSegid)
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Code an output subroutine for a coroutine implementation of a
|
|
// ** SELECT statement.
|
|
// **
|
|
// ** The data to be output is contained in an array of pIn->nSdst registers
|
|
// ** starting at register pIn->iSdst. pDest is where the output should
|
|
// ** be sent.
|
|
// **
|
|
// ** regReturn is the number of the register holding the subroutine
|
|
// ** return address.
|
|
// **
|
|
// ** If regPrev>0 then it is the first register in a vector that
|
|
// ** records the previous output. mem[regPrev] is a flag that is false
|
|
// ** if there has been no previous output. If regPrev>0 then code is
|
|
// ** generated to suppress duplicates. pKeyInfo is used for comparing
|
|
// ** keys.
|
|
// **
|
|
// ** If the LIMIT found in p->iLimit is reached, jump immediately to
|
|
// ** iBreak.
|
|
// */
|
|
func _generateOutputSubroutine(tls *libc.TLS, pParse uintptr, p uintptr, pIn uintptr, pDest uintptr, regReturn int32, regPrev int32, pKeyInfo uintptr, iBreak int32) (r int32) {
|
|
var addr, addr1, addr2, iContinue, iParm, iParm1, ii, nKey, r1, r11, r12, r2, r21, r3 int32
|
|
var pSO, v uintptr
|
|
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = addr, addr1, addr2, iContinue, iParm, iParm1, ii, nKey, pSO, r1, r11, r12, r2, r21, r3, v
|
|
v = (*TParse)(unsafe.Pointer(pParse)).FpVdbe
|
|
addr = _sqlite3VdbeCurrentAddr(tls, v)
|
|
iContinue = _sqlite3VdbeMakeLabel(tls, pParse)
|
|
/* Suppress duplicates for UNION, EXCEPT, and INTERSECT
|
|
*/
|
|
if regPrev != 0 {
|
|
addr1 = _sqlite3VdbeAddOp1(tls, v, int32(OP_IfNot), regPrev)
|
|
addr2 = _sqlite3VdbeAddOp4(tls, v, int32(OP_Compare), (*TSelectDest)(unsafe.Pointer(pIn)).FiSdst, regPrev+int32(1), (*TSelectDest)(unsafe.Pointer(pIn)).FnSdst, _sqlite3KeyInfoRef(tls, pKeyInfo), -int32(9))
|
|
_sqlite3VdbeAddOp3(tls, v, int32(OP_Jump), addr2+int32(2), iContinue, addr2+int32(2))
|
|
_sqlite3VdbeJumpHere(tls, v, addr1)
|
|
_sqlite3VdbeAddOp3(tls, v, int32(OP_Copy), (*TSelectDest)(unsafe.Pointer(pIn)).FiSdst, regPrev+int32(1), (*TSelectDest)(unsafe.Pointer(pIn)).FnSdst-int32(1))
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_Integer), int32(1), regPrev)
|
|
}
|
|
if (*Tsqlite3)(unsafe.Pointer((*TParse)(unsafe.Pointer(pParse)).Fdb)).FmallocFailed != 0 {
|
|
return 0
|
|
}
|
|
/* Suppress the first OFFSET entries if there is an OFFSET clause
|
|
*/
|
|
_codeOffset(tls, v, (*TSelect)(unsafe.Pointer(p)).FiOffset, iContinue)
|
|
switch libc.Int32FromUint8((*TSelectDest)(unsafe.Pointer(pDest)).FeDest) {
|
|
/* Store the result as data using a unique key.
|
|
*/
|
|
case int32(SRT_Fifo):
|
|
fallthrough
|
|
case int32(SRT_DistFifo):
|
|
fallthrough
|
|
case int32(SRT_Table):
|
|
fallthrough
|
|
case int32(SRT_EphemTab):
|
|
r1 = _sqlite3GetTempReg(tls, pParse)
|
|
r2 = _sqlite3GetTempReg(tls, pParse)
|
|
iParm = (*TSelectDest)(unsafe.Pointer(pDest)).FiSDParm
|
|
_sqlite3VdbeAddOp3(tls, v, int32(OP_MakeRecord), (*TSelectDest)(unsafe.Pointer(pIn)).FiSdst, (*TSelectDest)(unsafe.Pointer(pIn)).FnSdst, r1)
|
|
if libc.Int32FromUint8((*TSelectDest)(unsafe.Pointer(pDest)).FeDest) == int32(SRT_DistFifo) {
|
|
/* If the destination is DistFifo, then cursor (iParm+1) is open
|
|
** on an ephemeral index that is used to enforce uniqueness on the
|
|
** total result. At this point, we are processing the setup portion
|
|
** of the recursive CTE using the merge algorithm, so the results are
|
|
** guaranteed to be unique anyhow. But we still need to populate the
|
|
** (iParm+1) cursor for use by the subsequent recursive phase.
|
|
*/
|
|
_sqlite3VdbeAddOp4Int(tls, v, int32(OP_IdxInsert), iParm+int32(1), r1, (*TSelectDest)(unsafe.Pointer(pIn)).FiSdst, (*TSelectDest)(unsafe.Pointer(pIn)).FnSdst)
|
|
}
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_NewRowid), iParm, r2)
|
|
_sqlite3VdbeAddOp3(tls, v, int32(OP_Insert), iParm, r1, r2)
|
|
_sqlite3VdbeChangeP5(tls, v, uint16(OPFLAG_APPEND))
|
|
_sqlite3ReleaseTempReg(tls, pParse, r2)
|
|
_sqlite3ReleaseTempReg(tls, pParse, r1)
|
|
break
|
|
/* If any row exist in the result set, record that fact and abort.
|
|
*/
|
|
fallthrough
|
|
case int32(SRT_Exists):
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_Integer), int32(1), (*TSelectDest)(unsafe.Pointer(pDest)).FiSDParm)
|
|
/* The LIMIT clause will terminate the loop for us */
|
|
break
|
|
/* If we are creating a set for an "expr IN (SELECT ...)".
|
|
*/
|
|
fallthrough
|
|
case int32(SRT_Set):
|
|
r11 = _sqlite3GetTempReg(tls, pParse)
|
|
_sqlite3VdbeAddOp4(tls, v, int32(OP_MakeRecord), (*TSelectDest)(unsafe.Pointer(pIn)).FiSdst, (*TSelectDest)(unsafe.Pointer(pIn)).FnSdst, r11, (*TSelectDest)(unsafe.Pointer(pDest)).FzAffSdst, (*TSelectDest)(unsafe.Pointer(pIn)).FnSdst)
|
|
_sqlite3VdbeAddOp4Int(tls, v, int32(OP_IdxInsert), (*TSelectDest)(unsafe.Pointer(pDest)).FiSDParm, r11, (*TSelectDest)(unsafe.Pointer(pIn)).FiSdst, (*TSelectDest)(unsafe.Pointer(pIn)).FnSdst)
|
|
if (*TSelectDest)(unsafe.Pointer(pDest)).FiSDParm2 > 0 {
|
|
_sqlite3VdbeAddOp4Int(tls, v, int32(OP_FilterAdd), (*TSelectDest)(unsafe.Pointer(pDest)).FiSDParm2, 0, (*TSelectDest)(unsafe.Pointer(pIn)).FiSdst, (*TSelectDest)(unsafe.Pointer(pIn)).FnSdst)
|
|
_sqlite3VdbeExplain(tls, pParse, uint8(0), __ccgo_ts+20493, 0)
|
|
}
|
|
_sqlite3ReleaseTempReg(tls, pParse, r11)
|
|
break
|
|
/* If this is a scalar select that is part of an expression, then
|
|
** store the results in the appropriate memory cell and break out
|
|
** of the scan loop. Note that the select might return multiple columns
|
|
** if it is the RHS of a row-value IN operator.
|
|
*/
|
|
fallthrough
|
|
case int32(SRT_Mem):
|
|
_sqlite3ExprCodeMove(tls, pParse, (*TSelectDest)(unsafe.Pointer(pIn)).FiSdst, (*TSelectDest)(unsafe.Pointer(pDest)).FiSDParm, (*TSelectDest)(unsafe.Pointer(pIn)).FnSdst)
|
|
/* The LIMIT clause will jump out of the loop for us */
|
|
break
|
|
/* The results are stored in a sequence of registers
|
|
** starting at pDest->iSdst. Then the co-routine yields.
|
|
*/
|
|
fallthrough
|
|
case int32(SRT_Coroutine):
|
|
if (*TSelectDest)(unsafe.Pointer(pDest)).FiSdst == 0 {
|
|
(*TSelectDest)(unsafe.Pointer(pDest)).FiSdst = _sqlite3GetTempRange(tls, pParse, (*TSelectDest)(unsafe.Pointer(pIn)).FnSdst)
|
|
(*TSelectDest)(unsafe.Pointer(pDest)).FnSdst = (*TSelectDest)(unsafe.Pointer(pIn)).FnSdst
|
|
}
|
|
_sqlite3ExprCodeMove(tls, pParse, (*TSelectDest)(unsafe.Pointer(pIn)).FiSdst, (*TSelectDest)(unsafe.Pointer(pDest)).FiSdst, (*TSelectDest)(unsafe.Pointer(pIn)).FnSdst)
|
|
_sqlite3VdbeAddOp1(tls, v, int32(OP_Yield), (*TSelectDest)(unsafe.Pointer(pDest)).FiSDParm)
|
|
break
|
|
/* Write the results into a priority queue that is order according to
|
|
** pDest->pOrderBy (in pSO). pDest->iSDParm (in iParm) is the cursor for an
|
|
** index with pSO->nExpr+2 columns. Build a key using pSO for the first
|
|
** pSO->nExpr columns, then make sure all keys are unique by adding a
|
|
** final OP_Sequence column. The last column is the record as a blob.
|
|
*/
|
|
fallthrough
|
|
case int32(SRT_DistQueue):
|
|
fallthrough
|
|
case int32(SRT_Queue):
|
|
iParm1 = (*TSelectDest)(unsafe.Pointer(pDest)).FiSDParm
|
|
pSO = (*TSelectDest)(unsafe.Pointer(pDest)).FpOrderBy
|
|
nKey = (*TExprList)(unsafe.Pointer(pSO)).FnExpr
|
|
r12 = _sqlite3GetTempReg(tls, pParse)
|
|
r21 = _sqlite3GetTempRange(tls, pParse, nKey+int32(2))
|
|
r3 = r21 + nKey + int32(1)
|
|
_sqlite3VdbeAddOp3(tls, v, int32(OP_MakeRecord), (*TSelectDest)(unsafe.Pointer(pIn)).FiSdst, (*TSelectDest)(unsafe.Pointer(pIn)).FnSdst, r3)
|
|
if libc.Int32FromUint8((*TSelectDest)(unsafe.Pointer(pDest)).FeDest) == int32(SRT_DistQueue) {
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_IdxInsert), iParm1+int32(1), r3)
|
|
}
|
|
ii = 0
|
|
for {
|
|
if !(ii < nKey) {
|
|
break
|
|
}
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_SCopy), (*TSelectDest)(unsafe.Pointer(pIn)).FiSdst+libc.Int32FromUint16(*(*Tu16)(unsafe.Pointer(pSO + 8 + uintptr(ii)*32 + 24)))-int32(1), r21+ii)
|
|
goto _1
|
|
_1:
|
|
;
|
|
ii = ii + 1
|
|
}
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_Sequence), iParm1, r21+nKey)
|
|
_sqlite3VdbeAddOp3(tls, v, int32(OP_MakeRecord), r21, nKey+int32(2), r12)
|
|
_sqlite3VdbeAddOp4Int(tls, v, int32(OP_IdxInsert), iParm1, r12, r21, nKey+int32(2))
|
|
_sqlite3ReleaseTempReg(tls, pParse, r12)
|
|
_sqlite3ReleaseTempRange(tls, pParse, r21, nKey+int32(2))
|
|
break
|
|
/* Ignore the output */
|
|
fallthrough
|
|
case int32(SRT_Discard):
|
|
break
|
|
/* If none of the above, then the result destination must be
|
|
** SRT_Output.
|
|
**
|
|
** For SRT_Output, results are stored in a sequence of registers.
|
|
** Then the OP_ResultRow opcode is used to cause sqlite3_step() to
|
|
** return the next row of result.
|
|
*/
|
|
fallthrough
|
|
default:
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_ResultRow), (*TSelectDest)(unsafe.Pointer(pIn)).FiSdst, (*TSelectDest)(unsafe.Pointer(pIn)).FnSdst)
|
|
break
|
|
}
|
|
/* Jump to the end of the loop if the LIMIT is reached.
|
|
*/
|
|
if (*TSelect)(unsafe.Pointer(p)).FiLimit != 0 {
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_DecrJumpZero), (*TSelect)(unsafe.Pointer(p)).FiLimit, iBreak)
|
|
}
|
|
/* Generate the subroutine return
|
|
*/
|
|
_sqlite3VdbeResolveLabel(tls, v, iContinue)
|
|
_sqlite3VdbeAddOp1(tls, v, int32(OP_Return), regReturn)
|
|
return addr
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** If the inner loop was generated using a non-null pOrderBy argument,
|
|
// ** then the results were placed in a sorter. After the loop is terminated
|
|
// ** we need to run the sorter and output the results. The following
|
|
// ** routine generates the code needed to do that.
|
|
// */
|
|
func _generateSortTail(tls *libc.TLS, pParse uintptr, p uintptr, pSort uintptr, nColumn int32, pDest uintptr) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var aOutEx, pOrderBy, v, v1, v3 uintptr
|
|
var addr, addrBreak, addrContinue, addrOnce, bSeq, eDest, i, i2, iCol, iParm, iRead, iSortTab, iTab, nKey, nRefKey, r1, regRow, regRowid, regSortOut, v2, v4 int32
|
|
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = aOutEx, addr, addrBreak, addrContinue, addrOnce, bSeq, eDest, i, i2, iCol, iParm, iRead, iSortTab, iTab, nKey, nRefKey, pOrderBy, r1, regRow, regRowid, regSortOut, v, v1, v2, v3, v4
|
|
v = (*TParse)(unsafe.Pointer(pParse)).FpVdbe /* The prepared statement */
|
|
addrBreak = (*TSortCtx)(unsafe.Pointer(pSort)).FlabelDone /* Jump here to exit loop */
|
|
addrContinue = _sqlite3VdbeMakeLabel(tls, pParse) /* Top of output loop. Jump for Next. */
|
|
addrOnce = 0
|
|
pOrderBy = (*TSortCtx)(unsafe.Pointer(pSort)).FpOrderBy
|
|
eDest = libc.Int32FromUint8((*TSelectDest)(unsafe.Pointer(pDest)).FeDest)
|
|
iParm = (*TSelectDest)(unsafe.Pointer(pDest)).FiSDParm /* True if sorter record includes seq. no. */
|
|
nRefKey = 0
|
|
aOutEx = (*TSelect)(unsafe.Pointer(p)).FpEList + 8
|
|
nKey = (*TExprList)(unsafe.Pointer(pOrderBy)).FnExpr - (*TSortCtx)(unsafe.Pointer(pSort)).FnOBSat
|
|
if (*TSortCtx)(unsafe.Pointer(pSort)).FnOBSat == 0 || nKey == int32(1) {
|
|
if (*TSortCtx)(unsafe.Pointer(pSort)).FnOBSat != 0 {
|
|
v1 = __ccgo_ts + 20569
|
|
} else {
|
|
v1 = __ccgo_ts + 1704
|
|
}
|
|
_sqlite3VdbeExplain(tls, pParse, uint8(0), __ccgo_ts+20583, libc.VaList(bp+8, v1))
|
|
} else {
|
|
_sqlite3VdbeExplain(tls, pParse, uint8(0), __ccgo_ts+20614, libc.VaList(bp+8, nKey))
|
|
}
|
|
if (*TSortCtx)(unsafe.Pointer(pSort)).FlabelBkOut != 0 {
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_Gosub), (*TSortCtx)(unsafe.Pointer(pSort)).FregReturn, (*TSortCtx)(unsafe.Pointer(pSort)).FlabelBkOut)
|
|
_sqlite3VdbeGoto(tls, v, addrBreak)
|
|
_sqlite3VdbeResolveLabel(tls, v, (*TSortCtx)(unsafe.Pointer(pSort)).FlabelBkOut)
|
|
}
|
|
iTab = (*TSortCtx)(unsafe.Pointer(pSort)).FiECursor
|
|
if eDest == int32(SRT_Output) || eDest == int32(SRT_Coroutine) || eDest == int32(SRT_Mem) {
|
|
if eDest == int32(SRT_Mem) && (*TSelect)(unsafe.Pointer(p)).FiOffset != 0 {
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_Null), 0, (*TSelectDest)(unsafe.Pointer(pDest)).FiSdst)
|
|
}
|
|
regRowid = 0
|
|
regRow = (*TSelectDest)(unsafe.Pointer(pDest)).FiSdst
|
|
} else {
|
|
regRowid = _sqlite3GetTempReg(tls, pParse)
|
|
if eDest == int32(SRT_EphemTab) || eDest == int32(SRT_Table) {
|
|
regRow = _sqlite3GetTempReg(tls, pParse)
|
|
nColumn = 0
|
|
} else {
|
|
regRow = _sqlite3GetTempRange(tls, pParse, nColumn)
|
|
}
|
|
}
|
|
if libc.Int32FromUint8((*TSortCtx)(unsafe.Pointer(pSort)).FsortFlags)&int32(SORTFLAG_UseSorter) != 0 {
|
|
v1 = pParse + 60
|
|
*(*int32)(unsafe.Pointer(v1)) = *(*int32)(unsafe.Pointer(v1)) + 1
|
|
v2 = *(*int32)(unsafe.Pointer(v1))
|
|
regSortOut = v2
|
|
v3 = pParse + 56
|
|
v4 = *(*int32)(unsafe.Pointer(v3))
|
|
*(*int32)(unsafe.Pointer(v3)) = *(*int32)(unsafe.Pointer(v3)) + 1
|
|
iSortTab = v4
|
|
if (*TSortCtx)(unsafe.Pointer(pSort)).FlabelBkOut != 0 {
|
|
addrOnce = _sqlite3VdbeAddOp0(tls, v, int32(OP_Once))
|
|
}
|
|
_sqlite3VdbeAddOp3(tls, v, int32(OP_OpenPseudo), iSortTab, regSortOut, nKey+int32(1)+nColumn+nRefKey)
|
|
if addrOnce != 0 {
|
|
_sqlite3VdbeJumpHere(tls, v, addrOnce)
|
|
}
|
|
addr = int32(1) + _sqlite3VdbeAddOp2(tls, v, int32(OP_SorterSort), iTab, addrBreak)
|
|
_sqlite3VdbeAddOp3(tls, v, int32(OP_SorterData), iTab, regSortOut, iSortTab)
|
|
bSeq = 0
|
|
} else {
|
|
addr = int32(1) + _sqlite3VdbeAddOp2(tls, v, int32(OP_Sort), iTab, addrBreak)
|
|
_codeOffset(tls, v, (*TSelect)(unsafe.Pointer(p)).FiOffset, addrContinue)
|
|
iSortTab = iTab
|
|
bSeq = int32(1)
|
|
if (*TSelect)(unsafe.Pointer(p)).FiOffset > 0 {
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_AddImm), (*TSelect)(unsafe.Pointer(p)).FiLimit, -int32(1))
|
|
}
|
|
}
|
|
i = 0
|
|
iCol = nKey + bSeq - libc.Int32FromInt32(1)
|
|
for {
|
|
if !(i < nColumn) {
|
|
break
|
|
}
|
|
if libc.Int32FromUint16(*(*Tu16)(unsafe.Pointer(aOutEx + uintptr(i)*32 + 24))) == 0 {
|
|
iCol = iCol + 1
|
|
}
|
|
goto _6
|
|
_6:
|
|
;
|
|
i = i + 1
|
|
}
|
|
i = nColumn - int32(1)
|
|
for {
|
|
if !(i >= 0) {
|
|
break
|
|
}
|
|
if *(*Tu16)(unsafe.Pointer(aOutEx + uintptr(i)*32 + 24)) != 0 {
|
|
iRead = libc.Int32FromUint16(*(*Tu16)(unsafe.Pointer(aOutEx + uintptr(i)*32 + 24))) - int32(1)
|
|
} else {
|
|
v2 = iCol
|
|
iCol = iCol - 1
|
|
iRead = v2
|
|
}
|
|
_sqlite3VdbeAddOp3(tls, v, int32(OP_Column), iSortTab, iRead, regRow+i)
|
|
goto _7
|
|
_7:
|
|
;
|
|
i = i - 1
|
|
}
|
|
switch eDest {
|
|
case int32(SRT_Table):
|
|
fallthrough
|
|
case int32(SRT_EphemTab):
|
|
_sqlite3VdbeAddOp3(tls, v, int32(OP_Column), iSortTab, nKey+bSeq, regRow)
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_NewRowid), iParm, regRowid)
|
|
_sqlite3VdbeAddOp3(tls, v, int32(OP_Insert), iParm, regRow, regRowid)
|
|
_sqlite3VdbeChangeP5(tls, v, uint16(OPFLAG_APPEND))
|
|
case int32(SRT_Set):
|
|
_sqlite3VdbeAddOp4(tls, v, int32(OP_MakeRecord), regRow, nColumn, regRowid, (*TSelectDest)(unsafe.Pointer(pDest)).FzAffSdst, nColumn)
|
|
_sqlite3VdbeAddOp4Int(tls, v, int32(OP_IdxInsert), iParm, regRowid, regRow, nColumn)
|
|
case int32(SRT_Mem):
|
|
/* The LIMIT clause will terminate the loop for us */
|
|
case int32(SRT_Upfrom):
|
|
i2 = (*TSelectDest)(unsafe.Pointer(pDest)).FiSDParm2
|
|
r1 = _sqlite3GetTempReg(tls, pParse)
|
|
_sqlite3VdbeAddOp3(tls, v, int32(OP_MakeRecord), regRow+libc.BoolInt32(i2 < 0), nColumn-libc.BoolInt32(i2 < 0), r1)
|
|
if i2 < 0 {
|
|
_sqlite3VdbeAddOp3(tls, v, int32(OP_Insert), iParm, r1, regRow)
|
|
} else {
|
|
_sqlite3VdbeAddOp4Int(tls, v, int32(OP_IdxInsert), iParm, r1, regRow, i2)
|
|
}
|
|
default:
|
|
if eDest == int32(SRT_Output) {
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_ResultRow), (*TSelectDest)(unsafe.Pointer(pDest)).FiSdst, nColumn)
|
|
} else {
|
|
_sqlite3VdbeAddOp1(tls, v, int32(OP_Yield), (*TSelectDest)(unsafe.Pointer(pDest)).FiSDParm)
|
|
}
|
|
break
|
|
}
|
|
if regRowid != 0 {
|
|
if eDest == int32(SRT_Set) {
|
|
_sqlite3ReleaseTempRange(tls, pParse, regRow, nColumn)
|
|
} else {
|
|
_sqlite3ReleaseTempReg(tls, pParse, regRow)
|
|
}
|
|
_sqlite3ReleaseTempReg(tls, pParse, regRowid)
|
|
}
|
|
/* The bottom of the loop
|
|
*/
|
|
_sqlite3VdbeResolveLabel(tls, v, addrContinue)
|
|
if libc.Int32FromUint8((*TSortCtx)(unsafe.Pointer(pSort)).FsortFlags)&int32(SORTFLAG_UseSorter) != 0 {
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_SorterNext), iTab, addr)
|
|
} else {
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_Next), iTab, addr)
|
|
}
|
|
if (*TSortCtx)(unsafe.Pointer(pSort)).FregReturn != 0 {
|
|
_sqlite3VdbeAddOp1(tls, v, int32(OP_Return), (*TSortCtx)(unsafe.Pointer(pSort)).FregReturn)
|
|
}
|
|
_sqlite3VdbeResolveLabel(tls, v, addrBreak)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Each call to sqlite3_rtree_geometry_callback() or
|
|
// ** sqlite3_rtree_query_callback() creates an ordinary SQLite
|
|
// ** scalar function that is implemented by this routine.
|
|
// **
|
|
// ** All this function does is construct an RtreeMatchArg object that
|
|
// ** contains the geometry-checking callback routines and a list of
|
|
// ** parameters to this function, then return that RtreeMatchArg object
|
|
// ** as a BLOB.
|
|
// **
|
|
// ** The R-Tree MATCH operator will read the returned BLOB, deserialize
|
|
// ** the RtreeMatchArg object, and use the RtreeMatchArg object to figure
|
|
// ** out which elements of the R-Tree should be returned by the query.
|
|
// */
|
|
func _geomCallback(tls *libc.TLS, ctx uintptr, nArg int32, aArg uintptr) {
|
|
var i, memErr int32
|
|
var nBlob Tsqlite3_int64
|
|
var pBlob, pGeomCtx uintptr
|
|
_, _, _, _, _ = i, memErr, nBlob, pBlob, pGeomCtx
|
|
pGeomCtx = Xsqlite3_user_data(tls, ctx)
|
|
memErr = 0
|
|
nBlob = libc.Int64FromUint64(uint64(libc.UintptrFromInt32(0)+56) + libc.Uint64FromInt32(nArg)*uint64(8) + libc.Uint64FromInt32(nArg)*uint64(8))
|
|
pBlob = Xsqlite3_malloc64(tls, libc.Uint64FromInt64(nBlob))
|
|
if !(pBlob != 0) {
|
|
Xsqlite3_result_error_nomem(tls, ctx)
|
|
} else {
|
|
(*TRtreeMatchArg)(unsafe.Pointer(pBlob)).FiSize = libc.Uint32FromInt64(nBlob)
|
|
(*TRtreeMatchArg)(unsafe.Pointer(pBlob)).Fcb = **(**TRtreeGeomCallback)(__ccgo_up(pGeomCtx))
|
|
(*TRtreeMatchArg)(unsafe.Pointer(pBlob)).FapSqlParam = pBlob + 56 + uintptr(nArg)*8
|
|
(*TRtreeMatchArg)(unsafe.Pointer(pBlob)).FnParam = nArg
|
|
i = 0
|
|
for {
|
|
if !(i < nArg) {
|
|
break
|
|
}
|
|
**(**uintptr)(__ccgo_up((*TRtreeMatchArg)(unsafe.Pointer(pBlob)).FapSqlParam + uintptr(i)*8)) = Xsqlite3_value_dup(tls, **(**uintptr)(__ccgo_up(aArg + uintptr(i)*8)))
|
|
if **(**uintptr)(__ccgo_up((*TRtreeMatchArg)(unsafe.Pointer(pBlob)).FapSqlParam + uintptr(i)*8)) == uintptr(0) {
|
|
memErr = int32(1)
|
|
}
|
|
*(*TRtreeDValue)(unsafe.Pointer(pBlob + 56 + uintptr(i)*8)) = Xsqlite3_value_double(tls, **(**uintptr)(__ccgo_up(aArg + uintptr(i)*8)))
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
if memErr != 0 {
|
|
Xsqlite3_result_error_nomem(tls, ctx)
|
|
_rtreeMatchArgFree(tls, pBlob)
|
|
} else {
|
|
Xsqlite3_result_pointer(tls, ctx, pBlob, __ccgo_ts+27519, __ccgo_fp(_rtreeMatchArgFree))
|
|
}
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This function is the implementation of both the xConnect and xCreate
|
|
// ** methods of the geopoly virtual table.
|
|
// **
|
|
// ** argv[0] -> module name
|
|
// ** argv[1] -> database name
|
|
// ** argv[2] -> table name
|
|
// ** argv[...] -> column names...
|
|
// */
|
|
func _geopolyInit(tls *libc.TLS, db uintptr, pAux uintptr, argc int32, argv uintptr, ppVtab uintptr, pzErr uintptr, isCreate int32) (r int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var ii, rc, v2 int32
|
|
var nDb, nName Tsqlite3_int64
|
|
var pRtree, pSql, zSql uintptr
|
|
_, _, _, _, _, _, _, _ = ii, nDb, nName, pRtree, pSql, rc, zSql, v2
|
|
rc = SQLITE_OK
|
|
_ = pAux
|
|
if argc >= libc.Int32FromInt32(RTREE_MAX_AUX_COLUMN)+libc.Int32FromInt32(4) {
|
|
**(**uintptr)(__ccgo_up(pzErr)) = Xsqlite3_mprintf(tls, __ccgo_ts+29934, 0)
|
|
return int32(SQLITE_ERROR)
|
|
}
|
|
Xsqlite3_vtab_config(tls, db, int32(SQLITE_VTAB_CONSTRAINT_SUPPORT), libc.VaList(bp+8, int32(1)))
|
|
Xsqlite3_vtab_config(tls, db, int32(SQLITE_VTAB_INNOCUOUS), 0)
|
|
/* Allocate the sqlite3_vtab structure */
|
|
nDb = libc.Int64FromUint64(libc.Xstrlen(tls, **(**uintptr)(__ccgo_up(argv + 1*8))))
|
|
nName = libc.Int64FromUint64(libc.Xstrlen(tls, **(**uintptr)(__ccgo_up(argv + 2*8))))
|
|
pRtree = Xsqlite3_malloc64(tls, uint64(976)+libc.Uint64FromInt64(nDb)+libc.Uint64FromInt64(nName*int64(2))+uint64(8))
|
|
if !(pRtree != 0) {
|
|
return int32(SQLITE_NOMEM)
|
|
}
|
|
libc.Xmemset(tls, pRtree, 0, uint64(uint64(976)+libc.Uint64FromInt64(nDb)+libc.Uint64FromInt64(nName*int64(2))+uint64(8)))
|
|
(*TRtree)(unsafe.Pointer(pRtree)).FnBusy = uint32(1)
|
|
(*TRtree)(unsafe.Pointer(pRtree)).Fbase.FpModule = uintptr(unsafe.Pointer(&_rtreeModule))
|
|
(*TRtree)(unsafe.Pointer(pRtree)).FzDb = pRtree + 1*976
|
|
(*TRtree)(unsafe.Pointer(pRtree)).FzName = (*TRtree)(unsafe.Pointer(pRtree)).FzDb + uintptr(nDb+int64(1))
|
|
(*TRtree)(unsafe.Pointer(pRtree)).FzNodeName = (*TRtree)(unsafe.Pointer(pRtree)).FzName + uintptr(nName+int64(1))
|
|
(*TRtree)(unsafe.Pointer(pRtree)).FeCoordType = uint8(RTREE_COORD_REAL32)
|
|
(*TRtree)(unsafe.Pointer(pRtree)).FnDim = uint8(2)
|
|
(*TRtree)(unsafe.Pointer(pRtree)).FnDim2 = uint8(4)
|
|
libc.Xmemcpy(tls, (*TRtree)(unsafe.Pointer(pRtree)).FzDb, **(**uintptr)(__ccgo_up(argv + 1*8)), libc.Uint64FromInt64(nDb))
|
|
libc.Xmemcpy(tls, (*TRtree)(unsafe.Pointer(pRtree)).FzName, **(**uintptr)(__ccgo_up(argv + 2*8)), libc.Uint64FromInt64(nName))
|
|
libc.Xmemcpy(tls, (*TRtree)(unsafe.Pointer(pRtree)).FzNodeName, **(**uintptr)(__ccgo_up(argv + 2*8)), libc.Uint64FromInt64(nName))
|
|
libc.Xmemcpy(tls, (*TRtree)(unsafe.Pointer(pRtree)).FzNodeName+uintptr(nName), __ccgo_ts+28976, uint64(6))
|
|
/* Create/Connect to the underlying relational database schema. If
|
|
** that is successful, call sqlite3_declare_vtab() to configure
|
|
** the r-tree table schema.
|
|
*/
|
|
pSql = Xsqlite3_str_new(tls, db)
|
|
Xsqlite3_str_appendf(tls, pSql, __ccgo_ts+29971, 0)
|
|
(*TRtree)(unsafe.Pointer(pRtree)).FnAux = uint16(1) /* Add one for _shape */
|
|
(*TRtree)(unsafe.Pointer(pRtree)).FnAuxNotNull = uint8(1) /* The _shape column is always not-null */
|
|
ii = int32(3)
|
|
for {
|
|
if !(ii < argc) {
|
|
break
|
|
}
|
|
(*TRtree)(unsafe.Pointer(pRtree)).FnAux = (*TRtree)(unsafe.Pointer(pRtree)).FnAux + 1
|
|
Xsqlite3_str_appendf(tls, pSql, __ccgo_ts+29993, libc.VaList(bp+8, **(**uintptr)(__ccgo_up(argv + uintptr(ii)*8))))
|
|
goto _1
|
|
_1:
|
|
;
|
|
ii = ii + 1
|
|
}
|
|
Xsqlite3_str_appendf(tls, pSql, __ccgo_ts+29033, 0)
|
|
zSql = Xsqlite3_str_finish(tls, pSql)
|
|
if !(zSql != 0) {
|
|
rc = int32(SQLITE_NOMEM)
|
|
} else {
|
|
v2 = Xsqlite3_declare_vtab(tls, db, zSql)
|
|
rc = v2
|
|
if SQLITE_OK != v2 {
|
|
**(**uintptr)(__ccgo_up(pzErr)) = Xsqlite3_mprintf(tls, __ccgo_ts+3968, libc.VaList(bp+8, Xsqlite3_errmsg(tls, db)))
|
|
}
|
|
}
|
|
Xsqlite3_free(tls, zSql)
|
|
if rc != 0 {
|
|
goto geopolyInit_fail
|
|
}
|
|
(*TRtree)(unsafe.Pointer(pRtree)).FnBytesPerCell = libc.Uint8FromInt32(int32(8) + libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FnDim2)*int32(4))
|
|
/* Figure out the node size to use. */
|
|
rc = _getNodeSize(tls, db, pRtree, isCreate, pzErr)
|
|
if rc != 0 {
|
|
goto geopolyInit_fail
|
|
}
|
|
rc = _rtreeSqlInit(tls, pRtree, db, **(**uintptr)(__ccgo_up(argv + 1*8)), **(**uintptr)(__ccgo_up(argv + 2*8)), isCreate)
|
|
if rc != 0 {
|
|
**(**uintptr)(__ccgo_up(pzErr)) = Xsqlite3_mprintf(tls, __ccgo_ts+3968, libc.VaList(bp+8, Xsqlite3_errmsg(tls, db)))
|
|
goto geopolyInit_fail
|
|
}
|
|
**(**uintptr)(__ccgo_up(ppVtab)) = pRtree
|
|
return SQLITE_OK
|
|
goto geopolyInit_fail
|
|
geopolyInit_fail:
|
|
;
|
|
if rc == SQLITE_OK {
|
|
rc = int32(SQLITE_ERROR)
|
|
}
|
|
_rtreeRelease(tls, pRtree)
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** The xUpdate method for GEOPOLY module virtual tables.
|
|
// **
|
|
// ** For DELETE:
|
|
// **
|
|
// ** argv[0] = the rowid to be deleted
|
|
// **
|
|
// ** For INSERT:
|
|
// **
|
|
// ** argv[0] = SQL NULL
|
|
// ** argv[1] = rowid to insert, or an SQL NULL to select automatically
|
|
// ** argv[2] = _shape column
|
|
// ** argv[3] = first application-defined column....
|
|
// **
|
|
// ** For UPDATE:
|
|
// **
|
|
// ** argv[0] = rowid to modify. Never NULL
|
|
// ** argv[1] = rowid after the change. Never NULL
|
|
// ** argv[2] = new value for _shape
|
|
// ** argv[3] = new value for first application-defined column....
|
|
// */
|
|
func _geopolyUpdate(tls *libc.TLS, pVtab uintptr, nData int32, aData uintptr, pRowid uintptr) (r int32) {
|
|
bp := tls.Alloc(64)
|
|
defer tls.Free(64)
|
|
var coordChange, jj, nChange, newRowidValid, oldRowidValid, rc2, steprc int32
|
|
var newRowid, oldRowid Ti64
|
|
var p, pRtree, pUp, v3 uintptr
|
|
var v1 int64
|
|
var v4 bool
|
|
var _ /* cell at bp+8 */ TRtreeCell
|
|
var _ /* pLeaf at bp+56 */ uintptr
|
|
var _ /* rc at bp+0 */ int32
|
|
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = coordChange, jj, nChange, newRowid, newRowidValid, oldRowid, oldRowidValid, p, pRtree, pUp, rc2, steprc, v1, v3, v4
|
|
pRtree = pVtab
|
|
**(**int32)(__ccgo_up(bp)) = SQLITE_OK /* True if newRowid is valid */
|
|
coordChange = 0 /* Change in coordinates */
|
|
if (*TRtree)(unsafe.Pointer(pRtree)).FnNodeRef != 0 {
|
|
/* Unable to write to the btree while another cursor is reading from it,
|
|
** since the write might do a rebalance which would disrupt the read
|
|
** cursor. */
|
|
return libc.Int32FromInt32(SQLITE_LOCKED) | libc.Int32FromInt32(2)<<libc.Int32FromInt32(8)
|
|
}
|
|
_rtreeReference(tls, pRtree)
|
|
oldRowidValid = libc.BoolInt32(Xsqlite3_value_type(tls, **(**uintptr)(__ccgo_up(aData))) != int32(SQLITE_NULL))
|
|
if oldRowidValid != 0 {
|
|
v1 = Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(aData)))
|
|
} else {
|
|
v1 = 0
|
|
}
|
|
oldRowid = v1
|
|
newRowidValid = libc.BoolInt32(nData > int32(1) && Xsqlite3_value_type(tls, **(**uintptr)(__ccgo_up(aData + 1*8))) != int32(SQLITE_NULL))
|
|
if newRowidValid != 0 {
|
|
v1 = Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(aData + 1*8)))
|
|
} else {
|
|
v1 = 0
|
|
}
|
|
newRowid = v1
|
|
(**(**TRtreeCell)(__ccgo_up(bp + 8))).FiRowid = newRowid
|
|
if nData > int32(1) && (!(oldRowidValid != 0) || !(Xsqlite3_value_nochange(tls, **(**uintptr)(__ccgo_up(aData + 2*8))) != 0) || oldRowid != newRowid) {
|
|
_geopolyBBox(tls, uintptr(0), **(**uintptr)(__ccgo_up(aData + 2*8)), bp+8+8, bp)
|
|
if **(**int32)(__ccgo_up(bp)) != 0 {
|
|
if **(**int32)(__ccgo_up(bp)) == int32(SQLITE_ERROR) {
|
|
(*Tsqlite3_vtab)(unsafe.Pointer(pVtab)).FzErrMsg = Xsqlite3_mprintf(tls, __ccgo_ts+30012, 0)
|
|
}
|
|
goto geopoly_update_end
|
|
}
|
|
coordChange = int32(1)
|
|
/* If a rowid value was supplied, check if it is already present in
|
|
** the table. If so, the constraint has failed. */
|
|
if newRowidValid != 0 && (!(oldRowidValid != 0) || oldRowid != newRowid) {
|
|
Xsqlite3_bind_int64(tls, (*TRtree)(unsafe.Pointer(pRtree)).FpReadRowid, int32(1), (**(**TRtreeCell)(__ccgo_up(bp + 8))).FiRowid)
|
|
steprc = Xsqlite3_step(tls, (*TRtree)(unsafe.Pointer(pRtree)).FpReadRowid)
|
|
**(**int32)(__ccgo_up(bp)) = Xsqlite3_reset(tls, (*TRtree)(unsafe.Pointer(pRtree)).FpReadRowid)
|
|
if int32(SQLITE_ROW) == steprc {
|
|
if Xsqlite3_vtab_on_conflict(tls, (*TRtree)(unsafe.Pointer(pRtree)).Fdb) == int32(SQLITE_REPLACE) {
|
|
**(**int32)(__ccgo_up(bp)) = _rtreeDeleteRowid(tls, pRtree, (**(**TRtreeCell)(__ccgo_up(bp + 8))).FiRowid)
|
|
} else {
|
|
**(**int32)(__ccgo_up(bp)) = _rtreeConstraintError(tls, pRtree, 0)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/* If aData[0] is not an SQL NULL value, it is the rowid of a
|
|
** record to delete from the r-tree table. The following block does
|
|
** just that.
|
|
*/
|
|
if **(**int32)(__ccgo_up(bp)) == SQLITE_OK && (nData == int32(1) || coordChange != 0 && oldRowidValid != 0) {
|
|
**(**int32)(__ccgo_up(bp)) = _rtreeDeleteRowid(tls, pRtree, oldRowid)
|
|
}
|
|
/* If the aData[] array contains more than one element, elements
|
|
** (aData[2]..aData[argc-1]) contain a new record to insert into
|
|
** the r-tree structure.
|
|
*/
|
|
if **(**int32)(__ccgo_up(bp)) == SQLITE_OK && nData > int32(1) && coordChange != 0 {
|
|
/* Insert the new record into the r-tree */
|
|
**(**uintptr)(__ccgo_up(bp + 56)) = uintptr(0)
|
|
if !(newRowidValid != 0) {
|
|
**(**int32)(__ccgo_up(bp)) = _rtreeNewRowid(tls, pRtree, bp+8)
|
|
}
|
|
**(**Tsqlite_int64)(__ccgo_up(pRowid)) = (**(**TRtreeCell)(__ccgo_up(bp + 8))).FiRowid
|
|
if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
|
|
**(**int32)(__ccgo_up(bp)) = _ChooseLeaf(tls, pRtree, bp+8, 0, bp+56)
|
|
}
|
|
if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
|
|
**(**int32)(__ccgo_up(bp)) = _rtreeInsertCell(tls, pRtree, **(**uintptr)(__ccgo_up(bp + 56)), bp+8, 0)
|
|
rc2 = _nodeRelease(tls, pRtree, **(**uintptr)(__ccgo_up(bp + 56)))
|
|
if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
|
|
**(**int32)(__ccgo_up(bp)) = rc2
|
|
}
|
|
}
|
|
}
|
|
/* Change the data */
|
|
if **(**int32)(__ccgo_up(bp)) == SQLITE_OK && nData > int32(1) {
|
|
pUp = (*TRtree)(unsafe.Pointer(pRtree)).FpWriteAux
|
|
nChange = 0
|
|
Xsqlite3_bind_int64(tls, pUp, int32(1), (**(**TRtreeCell)(__ccgo_up(bp + 8))).FiRowid)
|
|
if Xsqlite3_value_nochange(tls, **(**uintptr)(__ccgo_up(aData + 2*8))) != 0 {
|
|
Xsqlite3_bind_null(tls, pUp, int32(2))
|
|
} else {
|
|
p = uintptr(0)
|
|
if v4 = Xsqlite3_value_type(tls, **(**uintptr)(__ccgo_up(aData + 2*8))) == int32(SQLITE_TEXT); v4 {
|
|
v3 = _geopolyFuncParam(tls, uintptr(0), **(**uintptr)(__ccgo_up(aData + 2*8)), bp)
|
|
p = v3
|
|
}
|
|
if v4 && v3 != uintptr(0) && **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
|
|
Xsqlite3_bind_blob(tls, pUp, int32(2), p+4, int32(4)+int32(8)*(*TGeoPoly)(unsafe.Pointer(p)).FnVertex, uintptr(-libc.Int32FromInt32(1)))
|
|
} else {
|
|
Xsqlite3_bind_value(tls, pUp, int32(2), **(**uintptr)(__ccgo_up(aData + 2*8)))
|
|
}
|
|
Xsqlite3_free(tls, p)
|
|
nChange = int32(1)
|
|
}
|
|
jj = int32(1)
|
|
for {
|
|
if !(jj < nData-int32(2)) {
|
|
break
|
|
}
|
|
nChange = nChange + 1
|
|
Xsqlite3_bind_value(tls, pUp, jj+int32(2), **(**uintptr)(__ccgo_up(aData + uintptr(jj+int32(2))*8)))
|
|
goto _5
|
|
_5:
|
|
;
|
|
jj = jj + 1
|
|
}
|
|
if nChange != 0 {
|
|
Xsqlite3_step(tls, pUp)
|
|
**(**int32)(__ccgo_up(bp)) = Xsqlite3_reset(tls, pUp)
|
|
}
|
|
}
|
|
goto geopoly_update_end
|
|
geopoly_update_end:
|
|
;
|
|
_rtreeRelease(tls, pRtree)
|
|
return **(**int32)(__ccgo_up(bp))
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This function is called from within the xConnect() or xCreate() method to
|
|
// ** determine the node-size used by the rtree table being created or connected
|
|
// ** to. If successful, pRtree->iNodeSize is populated and SQLITE_OK returned.
|
|
// ** Otherwise, an SQLite error code is returned.
|
|
// **
|
|
// ** If this function is being called as part of an xConnect(), then the rtree
|
|
// ** table already exists. In this case the node-size is determined by inspecting
|
|
// ** the root node of the tree.
|
|
// **
|
|
// ** Otherwise, for an xCreate(), use 64 bytes less than the database page-size.
|
|
// ** This ensures that each node is stored on a single database page. If the
|
|
// ** database page-size is so large that more than RTREE_MAXCELLS entries
|
|
// ** would fit in a single node, use a smaller node-size.
|
|
// */
|
|
func _getNodeSize(tls *libc.TLS, db uintptr, pRtree uintptr, isCreate int32, pzErr uintptr) (r int32) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var rc int32
|
|
var zSql uintptr
|
|
var _ /* iPageSize at bp+0 */ int32
|
|
_, _ = rc, zSql
|
|
if isCreate != 0 {
|
|
**(**int32)(__ccgo_up(bp)) = 0
|
|
zSql = Xsqlite3_mprintf(tls, __ccgo_ts+28713, libc.VaList(bp+16, (*TRtree)(unsafe.Pointer(pRtree)).FzDb))
|
|
rc = _getIntFromStmt(tls, db, zSql, bp)
|
|
if rc == SQLITE_OK {
|
|
(*TRtree)(unsafe.Pointer(pRtree)).FiNodeSize = **(**int32)(__ccgo_up(bp)) - int32(64)
|
|
if int32(4)+libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FnBytesPerCell)*int32(RTREE_MAXCELLS) < (*TRtree)(unsafe.Pointer(pRtree)).FiNodeSize {
|
|
(*TRtree)(unsafe.Pointer(pRtree)).FiNodeSize = int32(4) + libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FnBytesPerCell)*int32(RTREE_MAXCELLS)
|
|
}
|
|
} else {
|
|
**(**uintptr)(__ccgo_up(pzErr)) = Xsqlite3_mprintf(tls, __ccgo_ts+3968, libc.VaList(bp+16, Xsqlite3_errmsg(tls, db)))
|
|
}
|
|
} else {
|
|
zSql = Xsqlite3_mprintf(tls, __ccgo_ts+28733, libc.VaList(bp+16, (*TRtree)(unsafe.Pointer(pRtree)).FzDb, (*TRtree)(unsafe.Pointer(pRtree)).FzName))
|
|
rc = _getIntFromStmt(tls, db, zSql, pRtree+32)
|
|
if rc != SQLITE_OK {
|
|
**(**uintptr)(__ccgo_up(pzErr)) = Xsqlite3_mprintf(tls, __ccgo_ts+3968, libc.VaList(bp+16, Xsqlite3_errmsg(tls, db)))
|
|
} else {
|
|
if (*TRtree)(unsafe.Pointer(pRtree)).FiNodeSize < libc.Int32FromInt32(512)-libc.Int32FromInt32(64) {
|
|
rc = libc.Int32FromInt32(SQLITE_CORRUPT) | libc.Int32FromInt32(1)<<libc.Int32FromInt32(8)
|
|
**(**uintptr)(__ccgo_up(pzErr)) = Xsqlite3_mprintf(tls, __ccgo_ts+28790, libc.VaList(bp+16, (*TRtree)(unsafe.Pointer(pRtree)).FzName))
|
|
}
|
|
}
|
|
}
|
|
Xsqlite3_free(tls, zSql)
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Invalidate temp storage, either when the temp storage is changed
|
|
// ** from default, or when 'file' and the temp_store_directory has changed
|
|
// */
|
|
func _invalidateTempStorage(tls *libc.TLS, pParse uintptr) (r int32) {
|
|
var db uintptr
|
|
_ = db
|
|
db = (*TParse)(unsafe.Pointer(pParse)).Fdb
|
|
if (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + 1*32))).FpBt != uintptr(0) {
|
|
if !((*Tsqlite3)(unsafe.Pointer(db)).FautoCommit != 0) || _sqlite3BtreeTxnState(tls, (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + 1*32))).FpBt) != SQLITE_TXN_NONE {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+19068, 0)
|
|
return int32(SQLITE_ERROR)
|
|
}
|
|
_sqlite3BtreeClose(tls, (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + 1*32))).FpBt)
|
|
(**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + 1*32))).FpBt = uintptr(0)
|
|
_sqlite3ResetAllSchemasOfConnection(tls, db)
|
|
}
|
|
return SQLITE_OK
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Append an sqlite3_value (such as a function parameter) to the JSON
|
|
// ** string under construction in p.
|
|
// */
|
|
func _jsonAppendSqlValue(tls *libc.TLS, p uintptr, pValue uintptr) {
|
|
bp := tls.Alloc(96)
|
|
defer tls.Free(96)
|
|
var n, n1 Tu32
|
|
var z, z1 uintptr
|
|
var _ /* px at bp+0 */ TJsonParse
|
|
_, _, _, _ = n, n1, z, z1
|
|
switch Xsqlite3_value_type(tls, pValue) {
|
|
case int32(SQLITE_NULL):
|
|
_jsonAppendRawNZ(tls, p, __ccgo_ts+1690, uint32(4))
|
|
case int32(SQLITE_FLOAT):
|
|
_jsonPrintf(tls, int32(100), p, __ccgo_ts+16587, libc.VaList(bp+80, Xsqlite3_value_double(tls, pValue)))
|
|
case int32(SQLITE_INTEGER):
|
|
z = Xsqlite3_value_text(tls, pValue)
|
|
n = libc.Uint32FromInt32(Xsqlite3_value_bytes(tls, pValue))
|
|
_jsonAppendRaw(tls, p, z, n)
|
|
case int32(SQLITE_TEXT):
|
|
z1 = Xsqlite3_value_text(tls, pValue)
|
|
n1 = libc.Uint32FromInt32(Xsqlite3_value_bytes(tls, pValue))
|
|
if Xsqlite3_value_subtype(tls, pValue) == uint32(JSON_SUBTYPE) {
|
|
_jsonAppendRaw(tls, p, z1, n1)
|
|
} else {
|
|
_jsonAppendString(tls, p, z1, n1)
|
|
}
|
|
default:
|
|
libc.Xmemset(tls, bp, 0, uint64(72))
|
|
if _jsonArgIsJsonb(tls, pValue, bp) != 0 {
|
|
_jsonTranslateBlobToText(tls, bp, uint32(0), p)
|
|
} else {
|
|
if libc.Int32FromUint8((*TJsonString)(unsafe.Pointer(p)).FeErr) == 0 {
|
|
Xsqlite3_result_error(tls, (*TJsonString)(unsafe.Pointer(p)).FpCtx, __ccgo_ts+26457, -int32(1))
|
|
(*TJsonString)(unsafe.Pointer(p)).FeErr = uint8(JSTRING_ERR)
|
|
_jsonStringReset(tls, p)
|
|
}
|
|
}
|
|
break
|
|
}
|
|
}
|
|
|
|
func _jsonArrayCompute(tls *libc.TLS, ctx uintptr, isFinal int32) {
|
|
var flags int32
|
|
var pStr uintptr
|
|
var v1 Tsqlite3_destructor_type
|
|
_, _, _ = flags, pStr, v1
|
|
flags = int32(int64(Xsqlite3_user_data(tls, ctx)))
|
|
pStr = Xsqlite3_aggregate_context(tls, ctx, 0)
|
|
if pStr != 0 {
|
|
(*TJsonString)(unsafe.Pointer(pStr)).FpCtx = ctx
|
|
_jsonAppendRawNZ(tls, pStr, __ccgo_ts+5340, uint32(2))
|
|
_jsonStringTrimOneChar(tls, pStr)
|
|
if (*TJsonString)(unsafe.Pointer(pStr)).FeErr != 0 {
|
|
_jsonReturnString(tls, pStr, uintptr(0), uintptr(0))
|
|
return
|
|
} else {
|
|
if flags&int32(JSON_BLOB) != 0 {
|
|
_jsonReturnStringAsBlob(tls, pStr)
|
|
if isFinal != 0 {
|
|
if !((*TJsonString)(unsafe.Pointer(pStr)).FbStatic != 0) {
|
|
_sqlite3RCStrUnref(tls, (*TJsonString)(unsafe.Pointer(pStr)).FzBuf)
|
|
}
|
|
} else {
|
|
_jsonStringTrimOneChar(tls, pStr)
|
|
}
|
|
return
|
|
} else {
|
|
if isFinal != 0 {
|
|
if (*TJsonString)(unsafe.Pointer(pStr)).FbStatic != 0 {
|
|
v1 = uintptr(-libc.Int32FromInt32(1))
|
|
} else {
|
|
v1 = __ccgo_fp(_sqlite3RCStrUnref)
|
|
}
|
|
Xsqlite3_result_text(tls, ctx, (*TJsonString)(unsafe.Pointer(pStr)).FzBuf, libc.Int32FromUint64((*TJsonString)(unsafe.Pointer(pStr)).FnUsed), v1)
|
|
(*TJsonString)(unsafe.Pointer(pStr)).FbStatic = uint8(1)
|
|
} else {
|
|
Xsqlite3_result_text(tls, ctx, (*TJsonString)(unsafe.Pointer(pStr)).FzBuf, libc.Int32FromUint64((*TJsonString)(unsafe.Pointer(pStr)).FnUsed), uintptr(-libc.Int32FromInt32(1)))
|
|
_jsonStringTrimOneChar(tls, pStr)
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
if flags&int32(JSON_BLOB) != 0 {
|
|
Xsqlite3_result_blob(tls, ctx, uintptr(unsafe.Pointer(&_emptyArray)), int32(1), libc.UintptrFromInt32(0))
|
|
} else {
|
|
Xsqlite3_result_text(tls, ctx, __ccgo_ts+26878, int32(2), libc.UintptrFromInt32(0))
|
|
}
|
|
}
|
|
Xsqlite3_result_subtype(tls, ctx, uint32(JSON_SUBTYPE))
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Implementation of the json_mergepatch(JSON1,JSON2) function. Return a JSON
|
|
// ** object that is the result of running the RFC 7396 MergePatch() algorithm
|
|
// ** on the two arguments.
|
|
// */
|
|
func _jsonPatchFunc(tls *libc.TLS, ctx uintptr, argc int32, argv uintptr) {
|
|
var pPatch, pTarget uintptr
|
|
var rc int32
|
|
_, _, _ = pPatch, pTarget, rc /* Result code */
|
|
_ = argc
|
|
pTarget = _jsonParseFuncArg(tls, ctx, **(**uintptr)(__ccgo_up(argv)), uint32(JSON_EDITABLE))
|
|
if pTarget == uintptr(0) {
|
|
return
|
|
}
|
|
pPatch = _jsonParseFuncArg(tls, ctx, **(**uintptr)(__ccgo_up(argv + 1*8)), uint32(0))
|
|
if pPatch != 0 {
|
|
rc = _jsonMergePatch(tls, pTarget, uint32(0), pPatch, uint32(0), uint32(0))
|
|
if rc == JSON_MERGE_OK {
|
|
_jsonReturnParse(tls, ctx, pTarget)
|
|
} else {
|
|
if rc == int32(JSON_MERGE_OOM) {
|
|
Xsqlite3_result_error_nomem(tls, ctx)
|
|
} else {
|
|
if rc == int32(JSON_MERGE_TOODEEP) {
|
|
Xsqlite3_result_error(tls, ctx, __ccgo_ts+26436, -int32(1))
|
|
} else {
|
|
Xsqlite3_result_error(tls, ctx, __ccgo_ts+26486, -int32(1))
|
|
}
|
|
}
|
|
}
|
|
_jsonParseFree(tls, pPatch)
|
|
}
|
|
_jsonParseFree(tls, pTarget)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** json_pretty(JSON)
|
|
// ** json_pretty(JSON, INDENT)
|
|
// **
|
|
// ** Return text that is a pretty-printed rendering of the input JSON.
|
|
// ** If the argument is not valid JSON, return NULL.
|
|
// **
|
|
// ** The INDENT argument is text that is used for indentation. If omitted,
|
|
// ** it defaults to four spaces (the same as PostgreSQL).
|
|
// */
|
|
func _jsonPrettyFunc(tls *libc.TLS, ctx uintptr, argc int32, argv uintptr) {
|
|
bp := tls.Alloc(176)
|
|
defer tls.Free(176)
|
|
var v1 uintptr
|
|
var v2 bool
|
|
var _ /* s at bp+0 */ TJsonString
|
|
var _ /* x at bp+136 */ TJsonPretty
|
|
_, _ = v1, v2 /* Pretty printing context */
|
|
libc.Xmemset(tls, bp+136, 0, uint64(32))
|
|
(**(**TJsonPretty)(__ccgo_up(bp + 136))).FpParse = _jsonParseFuncArg(tls, ctx, **(**uintptr)(__ccgo_up(argv)), uint32(0))
|
|
if (**(**TJsonPretty)(__ccgo_up(bp + 136))).FpParse == uintptr(0) {
|
|
return
|
|
}
|
|
(**(**TJsonPretty)(__ccgo_up(bp + 136))).FpOut = bp
|
|
_jsonStringInit(tls, bp, ctx)
|
|
if v2 = argc == int32(1); !v2 {
|
|
v1 = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv + 1*8)))
|
|
(**(**TJsonPretty)(__ccgo_up(bp + 136))).FzIndent = v1
|
|
}
|
|
if v2 || v1 == uintptr(0) {
|
|
(**(**TJsonPretty)(__ccgo_up(bp + 136))).FzIndent = __ccgo_ts + 26816
|
|
(**(**TJsonPretty)(__ccgo_up(bp + 136))).FszIndent = uint32(4)
|
|
} else {
|
|
(**(**TJsonPretty)(__ccgo_up(bp + 136))).FszIndent = uint32(libc.Xstrlen(tls, (**(**TJsonPretty)(__ccgo_up(bp + 136))).FzIndent))
|
|
}
|
|
_jsonTranslateBlobToPrettyText(tls, bp+136, uint32(0))
|
|
_jsonReturnString(tls, bp, uintptr(0), uintptr(0))
|
|
_jsonParseFree(tls, (**(**TJsonPretty)(__ccgo_up(bp + 136))).FpParse)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /* Make the text in p (which is probably a generated JSON text string)
|
|
// ** the result of the SQL function.
|
|
// **
|
|
// ** The JsonString is reset.
|
|
// **
|
|
// ** If pParse and ctx are both non-NULL, then the SQL string in p is
|
|
// ** loaded into the zJson field of the pParse object as a RCStr and the
|
|
// ** pParse is added to the cache.
|
|
// */
|
|
func _jsonReturnString(tls *libc.TLS, p uintptr, pParse uintptr, ctx uintptr) {
|
|
var flags, rc int32
|
|
_, _ = flags, rc
|
|
_jsonStringTerminate(tls, p)
|
|
if libc.Int32FromUint8((*TJsonString)(unsafe.Pointer(p)).FeErr) == 0 {
|
|
flags = int32(int64(Xsqlite3_user_data(tls, (*TJsonString)(unsafe.Pointer(p)).FpCtx)))
|
|
if flags&int32(JSON_BLOB) != 0 {
|
|
_jsonReturnStringAsBlob(tls, p)
|
|
} else {
|
|
if (*TJsonString)(unsafe.Pointer(p)).FbStatic != 0 {
|
|
Xsqlite3_result_text64(tls, (*TJsonString)(unsafe.Pointer(p)).FpCtx, (*TJsonString)(unsafe.Pointer(p)).FzBuf, (*TJsonString)(unsafe.Pointer(p)).FnUsed, uintptr(-libc.Int32FromInt32(1)), uint8(SQLITE_UTF8))
|
|
} else {
|
|
if pParse != 0 && libc.Int32FromUint8((*TJsonParse)(unsafe.Pointer(pParse)).FbJsonIsRCStr) == 0 && (*TJsonParse)(unsafe.Pointer(pParse)).FnBlobAlloc > uint32(0) {
|
|
(*TJsonParse)(unsafe.Pointer(pParse)).FzJson = _sqlite3RCStrRef(tls, (*TJsonString)(unsafe.Pointer(p)).FzBuf)
|
|
(*TJsonParse)(unsafe.Pointer(pParse)).FnJson = libc.Int32FromUint64((*TJsonString)(unsafe.Pointer(p)).FnUsed)
|
|
(*TJsonParse)(unsafe.Pointer(pParse)).FbJsonIsRCStr = uint8(1)
|
|
rc = _jsonCacheInsert(tls, ctx, pParse)
|
|
if rc == int32(SQLITE_NOMEM) {
|
|
Xsqlite3_result_error_nomem(tls, ctx)
|
|
_jsonStringReset(tls, p)
|
|
return
|
|
}
|
|
}
|
|
Xsqlite3_result_text64(tls, (*TJsonString)(unsafe.Pointer(p)).FpCtx, _sqlite3RCStrRef(tls, (*TJsonString)(unsafe.Pointer(p)).FzBuf), (*TJsonString)(unsafe.Pointer(p)).FnUsed, __ccgo_fp(_sqlite3RCStrUnref), uint8(SQLITE_UTF8))
|
|
}
|
|
}
|
|
} else {
|
|
if libc.Int32FromUint8((*TJsonString)(unsafe.Pointer(p)).FeErr)&int32(JSTRING_OOM) != 0 {
|
|
Xsqlite3_result_error_nomem(tls, (*TJsonString)(unsafe.Pointer(p)).FpCtx)
|
|
} else {
|
|
if libc.Int32FromUint8((*TJsonString)(unsafe.Pointer(p)).FeErr)&int32(JSTRING_TOODEEP) != 0 {
|
|
/* error already in p->pCtx */
|
|
} else {
|
|
if libc.Int32FromUint8((*TJsonString)(unsafe.Pointer(p)).FeErr)&int32(JSTRING_MALFORMED) != 0 {
|
|
Xsqlite3_result_error(tls, (*TJsonString)(unsafe.Pointer(p)).FpCtx, __ccgo_ts+26486, -int32(1))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
_jsonStringReset(tls, p)
|
|
}
|
|
|
|
/**************************************************************************
|
|
** Utility routines for dealing with JsonParse objects
|
|
**************************************************************************/
|
|
|
|
// C documentation
|
|
//
|
|
// /* Report JSON nested too deep
|
|
// */
|
|
func _jsonStringTooDeep(tls *libc.TLS, p uintptr) {
|
|
var v1 uintptr
|
|
_ = v1
|
|
v1 = p + 33
|
|
*(*Tu8)(unsafe.Pointer(v1)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v1))) | libc.Int32FromInt32(JSTRING_TOODEEP))
|
|
Xsqlite3_result_error(tls, (*TJsonString)(unsafe.Pointer(p)).FpCtx, __ccgo_ts+26436, -int32(1))
|
|
_jsonStringReset(tls, p)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** json_valid(JSON)
|
|
// ** json_valid(JSON, FLAGS)
|
|
// **
|
|
// ** Check the JSON argument to see if it is well-formed. The FLAGS argument
|
|
// ** encodes the various constraints on what is meant by "well-formed":
|
|
// **
|
|
// ** 0x01 Canonical RFC-8259 JSON text
|
|
// ** 0x02 JSON text with optional JSON-5 extensions
|
|
// ** 0x04 Superficially appears to be JSONB
|
|
// ** 0x08 Strictly well-formed JSONB
|
|
// **
|
|
// ** If the FLAGS argument is omitted, it defaults to 1. Useful values for
|
|
// ** FLAGS include:
|
|
// **
|
|
// ** 1 Strict canonical JSON text
|
|
// ** 2 JSON text perhaps with JSON-5 extensions
|
|
// ** 4 Superficially appears to be JSONB
|
|
// ** 5 Canonical JSON text or superficial JSONB
|
|
// ** 6 JSON-5 text or superficial JSONB
|
|
// ** 8 Strict JSONB
|
|
// ** 9 Canonical JSON text or strict JSONB
|
|
// ** 10 JSON-5 text or strict JSONB
|
|
// **
|
|
// ** Other flag combinations are redundant. For example, every canonical
|
|
// ** JSON text is also well-formed JSON-5 text, so FLAG values 2 and 3
|
|
// ** are the same. Similarly, any input that passes a strict JSONB validation
|
|
// ** will also pass the superficial validation so 12 through 15 are the same
|
|
// ** as 8 through 11 respectively.
|
|
// **
|
|
// ** This routine runs in linear time to validate text and when doing strict
|
|
// ** JSONB validation. Superficial JSONB validation is constant time,
|
|
// ** assuming the BLOB is already in memory. The performance advantage
|
|
// ** of superficial JSONB validation is why that option is provided.
|
|
// ** Application developers can choose to do fast superficial validation or
|
|
// ** slower strict validation, according to their specific needs.
|
|
// **
|
|
// ** Only the lower four bits of the FLAGS argument are currently used.
|
|
// ** Higher bits are reserved for future expansion. To facilitate
|
|
// ** compatibility, the current implementation raises an error if any bit
|
|
// ** in FLAGS is set other than the lower four bits.
|
|
// **
|
|
// ** The original circa 2015 implementation of the JSON routines in
|
|
// ** SQLite only supported canonical RFC-8259 JSON text and the json_valid()
|
|
// ** function only accepted one argument. That is why the default value
|
|
// ** for the FLAGS argument is 1, since FLAGS=1 causes this routine to only
|
|
// ** recognize canonical RFC-8259 JSON text as valid. The extra FLAGS
|
|
// ** argument was added when the JSON routines were extended to support
|
|
// ** JSON5-like extensions and binary JSONB stored in BLOBs.
|
|
// **
|
|
// ** Return Values:
|
|
// **
|
|
// ** * Raise an error if FLAGS is outside the range of 1 to 15.
|
|
// ** * Return NULL if the input is NULL
|
|
// ** * Return 1 if the input is well-formed.
|
|
// ** * Return 0 if the input is not well-formed.
|
|
// */
|
|
func _jsonValidFunc(tls *libc.TLS, ctx uintptr, argc int32, argv uintptr) {
|
|
bp := tls.Alloc(144)
|
|
defer tls.Free(144)
|
|
var f Ti64
|
|
var flags, res Tu8
|
|
var p uintptr
|
|
var _ /* px at bp+72 */ TJsonParse
|
|
var _ /* py at bp+0 */ TJsonParse
|
|
_, _, _, _ = f, flags, p, res /* The parse */
|
|
flags = uint8(1)
|
|
res = uint8(0)
|
|
if argc == int32(2) {
|
|
f = Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(argv + 1*8)))
|
|
if f < int64(1) || f > int64(15) {
|
|
Xsqlite3_result_error(tls, ctx, __ccgo_ts+26821, -int32(1))
|
|
return
|
|
}
|
|
flags = libc.Uint8FromInt64(f & int64(0x0f))
|
|
}
|
|
switch Xsqlite3_value_type(tls, **(**uintptr)(__ccgo_up(argv))) {
|
|
case int32(SQLITE_NULL):
|
|
return
|
|
case int32(SQLITE_BLOB):
|
|
libc.Xmemset(tls, bp, 0, uint64(72))
|
|
if _jsonArgIsJsonb(tls, **(**uintptr)(__ccgo_up(argv)), bp) != 0 {
|
|
if libc.Int32FromUint8(flags)&int32(0x04) != 0 {
|
|
/* Superficial checking only - accomplished by the
|
|
** jsonArgIsJsonb() call above. */
|
|
res = uint8(1)
|
|
} else {
|
|
if libc.Int32FromUint8(flags)&int32(0x08) != 0 {
|
|
/* Strict checking. Check by translating BLOB->TEXT->BLOB. If
|
|
** no errors occur, call that a "strict check". */
|
|
res = libc.BoolUint8(uint32(0) == _jsonbValidityCheck(tls, bp, uint32(0), (**(**TJsonParse)(__ccgo_up(bp))).FnBlob, uint32(1)))
|
|
}
|
|
}
|
|
break
|
|
}
|
|
/* Fall through into interpreting the input as text. See note
|
|
** above at tag-20240123-a. */
|
|
fallthrough
|
|
default:
|
|
if libc.Int32FromUint8(flags)&int32(0x3) == 0 {
|
|
break
|
|
}
|
|
libc.Xmemset(tls, bp+72, 0, uint64(72))
|
|
p = _jsonParseFuncArg(tls, ctx, **(**uintptr)(__ccgo_up(argv)), uint32(JSON_KEEPERROR))
|
|
if p != 0 {
|
|
if (*TJsonParse)(unsafe.Pointer(p)).Foom != 0 {
|
|
Xsqlite3_result_error_nomem(tls, ctx)
|
|
} else {
|
|
if (*TJsonParse)(unsafe.Pointer(p)).FnErr != 0 {
|
|
/* no-op */
|
|
} else {
|
|
if libc.Int32FromUint8(flags)&int32(0x02) != 0 || libc.Int32FromUint8((*TJsonParse)(unsafe.Pointer(p)).FhasNonstd) == 0 {
|
|
res = uint8(1)
|
|
}
|
|
}
|
|
}
|
|
_jsonParseFree(tls, p)
|
|
} else {
|
|
Xsqlite3_result_error_nomem(tls, ctx)
|
|
}
|
|
break
|
|
}
|
|
Xsqlite3_result_int(tls, ctx, libc.Int32FromUint8(res))
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Implementation of the like() SQL function. This function implements
|
|
// ** the built-in LIKE operator. The first argument to the function is the
|
|
// ** pattern and the second argument is the string. So, the SQL statements:
|
|
// **
|
|
// ** A LIKE B
|
|
// **
|
|
// ** is implemented as like(B,A).
|
|
// **
|
|
// ** This same function (with a different compareInfo structure) computes
|
|
// ** the GLOB operator.
|
|
// */
|
|
func _likeFunc(tls *libc.TLS, context uintptr, argc int32, argv uintptr) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var db, pInfo, zA, zB uintptr
|
|
var escape Tu32
|
|
var nPat int32
|
|
var _ /* backupInfo at bp+0 */ TcompareInfo
|
|
var _ /* zEsc at bp+8 */ uintptr
|
|
_, _, _, _, _, _ = db, escape, nPat, pInfo, zA, zB
|
|
db = Xsqlite3_context_db_handle(tls, context)
|
|
pInfo = Xsqlite3_user_data(tls, context)
|
|
if Xsqlite3_value_type(tls, **(**uintptr)(__ccgo_up(argv))) == int32(SQLITE_BLOB) || Xsqlite3_value_type(tls, **(**uintptr)(__ccgo_up(argv + 1*8))) == int32(SQLITE_BLOB) {
|
|
Xsqlite3_result_int(tls, context, 0)
|
|
return
|
|
}
|
|
/* Limit the length of the LIKE or GLOB pattern to avoid problems
|
|
** of deep recursion and N*N behavior in patternCompare().
|
|
*/
|
|
nPat = Xsqlite3_value_bytes(tls, **(**uintptr)(__ccgo_up(argv)))
|
|
if nPat > **(**int32)(__ccgo_up(db + 136 + 8*4)) {
|
|
Xsqlite3_result_error(tls, context, __ccgo_ts+16509, -int32(1))
|
|
return
|
|
}
|
|
if argc == int32(3) {
|
|
/* The escape character string must consist of a single UTF-8 character.
|
|
** Otherwise, return an error.
|
|
*/
|
|
**(**uintptr)(__ccgo_up(bp + 8)) = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv + 2*8)))
|
|
if **(**uintptr)(__ccgo_up(bp + 8)) == uintptr(0) {
|
|
return
|
|
}
|
|
if _sqlite3Utf8CharLen(tls, **(**uintptr)(__ccgo_up(bp + 8)), -int32(1)) != int32(1) {
|
|
Xsqlite3_result_error(tls, context, __ccgo_ts+16542, -int32(1))
|
|
return
|
|
}
|
|
escape = _sqlite3Utf8Read(tls, bp+8)
|
|
if escape == uint32((*TcompareInfo)(unsafe.Pointer(pInfo)).FmatchAll) || escape == uint32((*TcompareInfo)(unsafe.Pointer(pInfo)).FmatchOne) {
|
|
libc.Xmemcpy(tls, bp, pInfo, uint64(4))
|
|
pInfo = bp
|
|
if escape == uint32((*TcompareInfo)(unsafe.Pointer(pInfo)).FmatchAll) {
|
|
(*TcompareInfo)(unsafe.Pointer(pInfo)).FmatchAll = uint8(0)
|
|
}
|
|
if escape == uint32((*TcompareInfo)(unsafe.Pointer(pInfo)).FmatchOne) {
|
|
(*TcompareInfo)(unsafe.Pointer(pInfo)).FmatchOne = uint8(0)
|
|
}
|
|
}
|
|
} else {
|
|
escape = uint32((*TcompareInfo)(unsafe.Pointer(pInfo)).FmatchSet)
|
|
}
|
|
zB = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv)))
|
|
zA = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv + 1*8)))
|
|
if zA != 0 && zB != 0 {
|
|
Xsqlite3_result_int(tls, context, libc.BoolInt32(_patternCompare(tls, zB, zA, pInfo, escape) == SQLITE_MATCH))
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** A function that loads a shared-library extension then returns NULL.
|
|
// */
|
|
func _loadExt(tls *libc.TLS, context uintptr, argc int32, argv uintptr) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var db, zFile, zProc uintptr
|
|
var _ /* zErrMsg at bp+0 */ uintptr
|
|
_, _, _ = db, zFile, zProc
|
|
zFile = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv)))
|
|
db = Xsqlite3_context_db_handle(tls, context)
|
|
**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
|
|
/* Disallow the load_extension() SQL function unless the SQLITE_LoadExtFunc
|
|
** flag is set. See the sqlite3_enable_load_extension() API.
|
|
*/
|
|
if (*Tsqlite3)(unsafe.Pointer(db)).Fflags&uint64(SQLITE_LoadExtFunc) == uint64(0) {
|
|
Xsqlite3_result_error(tls, context, __ccgo_ts+13699, -int32(1))
|
|
return
|
|
}
|
|
if argc == int32(2) {
|
|
zProc = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv + 1*8)))
|
|
} else {
|
|
zProc = uintptr(0)
|
|
}
|
|
if zFile != 0 && Xsqlite3_load_extension(tls, db, zFile, zProc, bp) != 0 {
|
|
Xsqlite3_result_error(tls, context, **(**uintptr)(__ccgo_up(bp)), -int32(1))
|
|
Xsqlite3_free(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Get a reference to pPage1 of the database file. This will
|
|
// ** also acquire a readlock on that file.
|
|
// **
|
|
// ** SQLITE_OK is returned on success. If the file is not a
|
|
// ** well-formed database file, then SQLITE_CORRUPT is returned.
|
|
// ** SQLITE_BUSY is returned if the database is locked. SQLITE_NOMEM
|
|
// ** is returned if we run out of memory.
|
|
// */
|
|
func _lockBtree(tls *libc.TLS, pBt uintptr) (r int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var nPage, pageSize, usableSize Tu32
|
|
var page1, v1 uintptr
|
|
var rc, v4 int32
|
|
var _ /* isOpen at bp+12 */ int32
|
|
var _ /* nPageFile at bp+8 */ Tu32
|
|
var _ /* pPage1 at bp+0 */ uintptr
|
|
_, _, _, _, _, _, _ = nPage, page1, pageSize, rc, usableSize, v1, v4 /* Number of pages in the database */
|
|
**(**Tu32)(__ccgo_up(bp + 8)) = uint32(0) /* Number of pages in the database file */
|
|
rc = _sqlite3PagerSharedLock(tls, (*TBtShared)(unsafe.Pointer(pBt)).FpPager)
|
|
if rc != SQLITE_OK {
|
|
return rc
|
|
}
|
|
rc = _btreeGetPage(tls, pBt, uint32(1), bp, 0)
|
|
if rc != SQLITE_OK {
|
|
return rc
|
|
}
|
|
/* Do some checking to help insure the file we opened really is
|
|
** a valid database file.
|
|
*/
|
|
nPage = _sqlite3Get4byte(tls, uintptr(28)+(*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FaData)
|
|
_sqlite3PagerPagecount(tls, (*TBtShared)(unsafe.Pointer(pBt)).FpPager, bp+8)
|
|
if nPage == uint32(0) || libc.Xmemcmp(tls, uintptr(24)+(*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FaData, uintptr(92)+(*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FaData, uint64(4)) != 0 {
|
|
nPage = **(**Tu32)(__ccgo_up(bp + 8))
|
|
}
|
|
if (*Tsqlite3)(unsafe.Pointer((*TBtShared)(unsafe.Pointer(pBt)).Fdb)).Fflags&uint64(SQLITE_ResetDatabase) != uint64(0) {
|
|
nPage = uint32(0)
|
|
}
|
|
if nPage > uint32(0) {
|
|
page1 = (*TMemPage)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FaData
|
|
rc = int32(SQLITE_NOTADB)
|
|
/* EVIDENCE-OF: R-43737-39999 Every valid SQLite database file begins
|
|
** with the following 16 bytes (in hex): 53 51 4c 69 74 65 20 66 6f 72 6d
|
|
** 61 74 20 33 00. */
|
|
if libc.Xmemcmp(tls, page1, uintptr(unsafe.Pointer(&_zMagicHeader)), uint64(16)) != 0 {
|
|
goto page1_init_failed
|
|
}
|
|
if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(page1 + 18))) > int32(2) {
|
|
v1 = pBt + 40
|
|
*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) | libc.Int32FromInt32(BTS_READ_ONLY))
|
|
}
|
|
if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(page1 + 19))) > int32(2) {
|
|
goto page1_init_failed
|
|
}
|
|
/* If the read version is set to 2, this database should be accessed
|
|
** in WAL mode. If the log is not already open, open it now. Then
|
|
** return SQLITE_OK and return without populating BtShared.pPage1.
|
|
** The caller detects this and calls this function again. This is
|
|
** required as the version of page 1 currently in the page1 buffer
|
|
** may not be the latest version - there may be a newer one in the log
|
|
** file.
|
|
*/
|
|
if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(page1 + 19))) == int32(2) && libc.Int32FromUint16((*TBtShared)(unsafe.Pointer(pBt)).FbtsFlags)&int32(BTS_NO_WAL) == 0 {
|
|
**(**int32)(__ccgo_up(bp + 12)) = 0
|
|
rc = _sqlite3PagerOpenWal(tls, (*TBtShared)(unsafe.Pointer(pBt)).FpPager, bp+12)
|
|
if rc != SQLITE_OK {
|
|
goto page1_init_failed
|
|
} else {
|
|
if **(**int32)(__ccgo_up(bp + 12)) == 0 {
|
|
_releasePageOne(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
return SQLITE_OK
|
|
}
|
|
}
|
|
rc = int32(SQLITE_NOTADB)
|
|
} else {
|
|
}
|
|
/* EVIDENCE-OF: R-15465-20813 The maximum and minimum embedded payload
|
|
** fractions and the leaf payload fraction values must be 64, 32, and 32.
|
|
**
|
|
** The original design allowed these amounts to vary, but as of
|
|
** version 3.6.0, we require them to be fixed.
|
|
*/
|
|
if libc.Xmemcmp(tls, page1+21, __ccgo_ts+4376, uint64(3)) != 0 {
|
|
goto page1_init_failed
|
|
}
|
|
/* EVIDENCE-OF: R-51873-39618 The page size for a database file is
|
|
** determined by the 2-byte integer located at an offset of 16 bytes from
|
|
** the beginning of the database file. */
|
|
pageSize = libc.Uint32FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up(page1 + 16)))<<int32(8) | libc.Int32FromUint8(**(**Tu8)(__ccgo_up(page1 + 17)))<<int32(16))
|
|
/* EVIDENCE-OF: R-25008-21688 The size of a page is a power of two
|
|
** between 512 and 65536 inclusive. */
|
|
if (pageSize-uint32(1))&pageSize != uint32(0) || pageSize > uint32(SQLITE_MAX_PAGE_SIZE) || pageSize <= uint32(256) {
|
|
goto page1_init_failed
|
|
}
|
|
/* EVIDENCE-OF: R-59310-51205 The "reserved space" size in the 1-byte
|
|
** integer at offset 20 is the number of bytes of space at the end of
|
|
** each page to reserve for extensions.
|
|
**
|
|
** EVIDENCE-OF: R-37497-42412 The size of the reserved region is
|
|
** determined by the one-byte unsigned integer found at an offset of 20
|
|
** into the database file header. */
|
|
usableSize = pageSize - uint32(**(**Tu8)(__ccgo_up(page1 + 20)))
|
|
if pageSize != (*TBtShared)(unsafe.Pointer(pBt)).FpageSize {
|
|
/* After reading the first page of the database assuming a page size
|
|
** of BtShared.pageSize, we have discovered that the page-size is
|
|
** actually pageSize. Unlock the database, leave pBt->pPage1 at
|
|
** zero and return SQLITE_OK. The caller will call this function
|
|
** again with the correct page-size.
|
|
*/
|
|
_releasePageOne(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
(*TBtShared)(unsafe.Pointer(pBt)).FusableSize = usableSize
|
|
(*TBtShared)(unsafe.Pointer(pBt)).FpageSize = pageSize
|
|
v1 = pBt + 40
|
|
*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) | libc.Int32FromInt32(BTS_PAGESIZE_FIXED))
|
|
_freeTempSpace(tls, pBt)
|
|
rc = _sqlite3PagerSetPagesize(tls, (*TBtShared)(unsafe.Pointer(pBt)).FpPager, pBt+52, libc.Int32FromUint32(pageSize-usableSize))
|
|
return rc
|
|
}
|
|
if nPage > **(**Tu32)(__ccgo_up(bp + 8)) {
|
|
if _sqlite3WritableSchema(tls, (*TBtShared)(unsafe.Pointer(pBt)).Fdb) == 0 {
|
|
rc = _sqlite3CorruptError(tls, int32(76782))
|
|
goto page1_init_failed
|
|
} else {
|
|
nPage = **(**Tu32)(__ccgo_up(bp + 8))
|
|
}
|
|
}
|
|
/* EVIDENCE-OF: R-28312-64704 However, the usable size is not allowed to
|
|
** be less than 480. In other words, if the page size is 512, then the
|
|
** reserved space size cannot exceed 32. */
|
|
if usableSize < uint32(480) {
|
|
goto page1_init_failed
|
|
}
|
|
v1 = pBt + 40
|
|
*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) | libc.Int32FromInt32(BTS_PAGESIZE_FIXED))
|
|
(*TBtShared)(unsafe.Pointer(pBt)).FpageSize = pageSize
|
|
(*TBtShared)(unsafe.Pointer(pBt)).FusableSize = usableSize
|
|
if _sqlite3Get4byte(tls, page1+uintptr(libc.Int32FromInt32(36)+libc.Int32FromInt32(4)*libc.Int32FromInt32(4))) != 0 {
|
|
v4 = int32(1)
|
|
} else {
|
|
v4 = 0
|
|
}
|
|
(*TBtShared)(unsafe.Pointer(pBt)).FautoVacuum = libc.Uint8FromInt32(v4)
|
|
if _sqlite3Get4byte(tls, page1+uintptr(libc.Int32FromInt32(36)+libc.Int32FromInt32(7)*libc.Int32FromInt32(4))) != 0 {
|
|
v4 = int32(1)
|
|
} else {
|
|
v4 = 0
|
|
}
|
|
(*TBtShared)(unsafe.Pointer(pBt)).FincrVacuum = libc.Uint8FromInt32(v4)
|
|
}
|
|
/* maxLocal is the maximum amount of payload to store locally for
|
|
** a cell. Make sure it is small enough so that at least minFanout
|
|
** cells can will fit on one page. We assume a 10-byte page header.
|
|
** Besides the payload, the cell must store:
|
|
** 2-byte pointer to the cell
|
|
** 4-byte child pointer
|
|
** 9-byte nKey value
|
|
** 4-byte nData value
|
|
** 4-byte overflow page pointer
|
|
** So a cell consists of a 2-byte pointer, a header which is as much as
|
|
** 17 bytes long, 0 to N bytes of payload, and an optional 4 byte overflow
|
|
** page pointer.
|
|
*/
|
|
(*TBtShared)(unsafe.Pointer(pBt)).FmaxLocal = uint16(((*TBtShared)(unsafe.Pointer(pBt)).FusableSize-libc.Uint32FromInt32(12))*libc.Uint32FromInt32(64)/libc.Uint32FromInt32(255) - libc.Uint32FromInt32(23))
|
|
(*TBtShared)(unsafe.Pointer(pBt)).FminLocal = uint16(((*TBtShared)(unsafe.Pointer(pBt)).FusableSize-libc.Uint32FromInt32(12))*libc.Uint32FromInt32(32)/libc.Uint32FromInt32(255) - libc.Uint32FromInt32(23))
|
|
(*TBtShared)(unsafe.Pointer(pBt)).FmaxLeaf = uint16((*TBtShared)(unsafe.Pointer(pBt)).FusableSize - libc.Uint32FromInt32(35))
|
|
(*TBtShared)(unsafe.Pointer(pBt)).FminLeaf = uint16(((*TBtShared)(unsafe.Pointer(pBt)).FusableSize-libc.Uint32FromInt32(12))*libc.Uint32FromInt32(32)/libc.Uint32FromInt32(255) - libc.Uint32FromInt32(23))
|
|
if libc.Int32FromUint16((*TBtShared)(unsafe.Pointer(pBt)).FmaxLocal) > int32(127) {
|
|
(*TBtShared)(unsafe.Pointer(pBt)).Fmax1bytePayload = uint8(127)
|
|
} else {
|
|
(*TBtShared)(unsafe.Pointer(pBt)).Fmax1bytePayload = uint8((*TBtShared)(unsafe.Pointer(pBt)).FmaxLocal)
|
|
}
|
|
(*TBtShared)(unsafe.Pointer(pBt)).FpPage1 = **(**uintptr)(__ccgo_up(bp))
|
|
(*TBtShared)(unsafe.Pointer(pBt)).FnPage = nPage
|
|
return SQLITE_OK
|
|
goto page1_init_failed
|
|
page1_init_failed:
|
|
;
|
|
_releasePageOne(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
(*TBtShared)(unsafe.Pointer(pBt)).FpPage1 = uintptr(0)
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Tag the given column as being part of the PRIMARY KEY
|
|
// */
|
|
func _makeColumnPartOfPrimaryKey(tls *libc.TLS, pParse uintptr, pCol uintptr) {
|
|
var v1 uintptr
|
|
_ = v1
|
|
v1 = pCol + 14
|
|
*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) | libc.Int32FromInt32(COLFLAG_PRIMKEY))
|
|
if libc.Int32FromUint16((*TColumn)(unsafe.Pointer(pCol)).FcolFlags)&int32(COLFLAG_GENERATED) != 0 {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+14136, 0)
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** The pFunc is the only aggregate function in the query. Check to see
|
|
// ** if the query is a candidate for the min/max optimization.
|
|
// **
|
|
// ** If the query is a candidate for the min/max optimization, then set
|
|
// ** *ppMinMax to be an ORDER BY clause to be used for the optimization
|
|
// ** and return either WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX depending on
|
|
// ** whether pFunc is a min() or max() function.
|
|
// **
|
|
// ** If the query is not a candidate for the min/max optimization, return
|
|
// ** WHERE_ORDERBY_NORMAL (which must be zero).
|
|
// **
|
|
// ** This routine must be called after aggregate functions have been
|
|
// ** located but before their arguments have been subjected to aggregate
|
|
// ** analysis.
|
|
// */
|
|
func _minMaxQuery(tls *libc.TLS, db uintptr, pFunc uintptr, ppMinMax uintptr) (r Tu8) {
|
|
var eRet int32
|
|
var pEList, pOrderBy, zFunc, v1 uintptr
|
|
var sortFlags Tu8
|
|
_, _, _, _, _, _ = eRet, pEList, pOrderBy, sortFlags, zFunc, v1
|
|
eRet = WHERE_ORDERBY_NORMAL
|
|
sortFlags = uint8(0)
|
|
pEList = *(*uintptr)(unsafe.Pointer(pFunc + 32))
|
|
if pEList == uintptr(0) || (*TExprList)(unsafe.Pointer(pEList)).FnExpr != int32(1) || (*TExpr)(unsafe.Pointer(pFunc)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_WinFunc)) != uint32(0) || (*Tsqlite3)(unsafe.Pointer(db)).FdbOptFlags&libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_MinMaxOpt)) != uint32(0) {
|
|
return libc.Uint8FromInt32(eRet)
|
|
}
|
|
zFunc = *(*uintptr)(unsafe.Pointer(pFunc + 8))
|
|
if _sqlite3StrICmp(tls, zFunc, __ccgo_ts+16830) == 0 {
|
|
eRet = int32(WHERE_ORDERBY_MIN)
|
|
if _sqlite3ExprCanBeNull(tls, (*(*TExprList_item)(unsafe.Pointer(pEList + 8))).FpExpr) != 0 {
|
|
sortFlags = uint8(KEYINFO_ORDER_BIGNULL)
|
|
}
|
|
} else {
|
|
if _sqlite3StrICmp(tls, zFunc, __ccgo_ts+16834) == 0 {
|
|
eRet = int32(WHERE_ORDERBY_MAX)
|
|
sortFlags = uint8(KEYINFO_ORDER_DESC)
|
|
} else {
|
|
return libc.Uint8FromInt32(eRet)
|
|
}
|
|
}
|
|
v1 = _sqlite3ExprListDup(tls, db, pEList, 0)
|
|
pOrderBy = v1
|
|
**(**uintptr)(__ccgo_up(ppMinMax)) = v1
|
|
if pOrderBy != 0 {
|
|
(*(*TExprList_item)(unsafe.Pointer(pOrderBy + 8))).Ffg.FsortFlags = sortFlags
|
|
}
|
|
return libc.Uint8FromInt32(eRet)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This routine is called to process a compound query form from
|
|
// ** two or more separate queries using UNION, UNION ALL, EXCEPT, or
|
|
// ** INTERSECT
|
|
// **
|
|
// ** "p" points to the right-most of the two queries. the query on the
|
|
// ** left is p->pPrior. The left query could also be a compound query
|
|
// ** in which case this routine will be called recursively.
|
|
// **
|
|
// ** The results of the total query are to be written into a destination
|
|
// ** of type eDest with parameter iParm.
|
|
// **
|
|
// ** Example 1: Consider a three-way compound SQL statement.
|
|
// **
|
|
// ** SELECT a FROM t1 UNION SELECT b FROM t2 UNION SELECT c FROM t3
|
|
// **
|
|
// ** This statement is parsed up as follows:
|
|
// **
|
|
// ** SELECT c FROM t3
|
|
// ** |
|
|
// ** `-----> SELECT b FROM t2
|
|
// ** |
|
|
// ** `------> SELECT a FROM t1
|
|
// **
|
|
// ** The arrows in the diagram above represent the Select.pPrior pointer.
|
|
// ** So if this routine is called with p equal to the t3 query, then
|
|
// ** pPrior will be the t2 query. p->op will be TK_UNION in this case.
|
|
// **
|
|
// ** Notice that because of the way SQLite parses compound SELECTs, the
|
|
// ** individual selects always group from left to right.
|
|
// */
|
|
func _multiSelect(tls *libc.TLS, pParse uintptr, p uintptr, pDest uintptr) (r int32) {
|
|
bp := tls.Alloc(48)
|
|
defer tls.Free(48)
|
|
var addr, rc int32
|
|
var db, pDelete, pOne, pPrior, v uintptr
|
|
var _ /* dest at bp+0 */ TSelectDest
|
|
var _ /* nLimit at bp+40 */ int32
|
|
_, _, _, _, _, _, _ = addr, db, pDelete, pOne, pPrior, rc, v
|
|
rc = SQLITE_OK /* Alternative data destination */
|
|
pDelete = uintptr(0) /* Database connection */
|
|
/* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs. Only
|
|
** the last (right-most) SELECT in the series may have an ORDER BY or LIMIT.
|
|
*/
|
|
/* Calling function guarantees this much */
|
|
db = (*TParse)(unsafe.Pointer(pParse)).Fdb
|
|
pPrior = (*TSelect)(unsafe.Pointer(p)).FpPrior
|
|
**(**TSelectDest)(__ccgo_up(bp)) = **(**TSelectDest)(__ccgo_up(pDest))
|
|
v = _sqlite3GetVdbe(tls, pParse)
|
|
/* The VDBE already created by calling function */
|
|
/* Create the destination temporary table if necessary
|
|
*/
|
|
if libc.Int32FromUint8((**(**TSelectDest)(__ccgo_up(bp))).FeDest) == int32(SRT_EphemTab) {
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_OpenEphemeral), (**(**TSelectDest)(__ccgo_up(bp))).FiSDParm, (*TExprList)(unsafe.Pointer((*TSelect)(unsafe.Pointer(p)).FpEList)).FnExpr)
|
|
(**(**TSelectDest)(__ccgo_up(bp))).FeDest = uint8(SRT_Table)
|
|
}
|
|
/* Special handling for a compound-select that originates as a VALUES clause.
|
|
*/
|
|
if (*TSelect)(unsafe.Pointer(p)).FselFlags&uint32(SF_MultiValue) != 0 {
|
|
rc = _multiSelectValues(tls, pParse, p, bp)
|
|
if rc >= 0 {
|
|
goto multi_select_end
|
|
}
|
|
rc = SQLITE_OK
|
|
}
|
|
/* Make sure all SELECTs in the statement have the same number of elements
|
|
** in their result sets.
|
|
*/
|
|
if (*TSelect)(unsafe.Pointer(p)).FselFlags&uint32(SF_Recursive) != uint32(0) && _hasAnchor(tls, p) != 0 {
|
|
_generateWithRecursiveQuery(tls, pParse, p, bp)
|
|
} else {
|
|
if (*TSelect)(unsafe.Pointer(p)).FpOrderBy != 0 {
|
|
/* If the compound has an ORDER BY clause, then always use the merge
|
|
** algorithm. */
|
|
return _multiSelectByMerge(tls, pParse, p, pDest)
|
|
} else {
|
|
if libc.Int32FromUint8((*TSelect)(unsafe.Pointer(p)).Fop) != int32(TK_ALL) {
|
|
/* If the compound is EXCEPT, INTERSECT, or UNION (anything other than
|
|
** UNION ALL) then also always use the merge algorithm. However, the
|
|
** multiSelectByMerge() routine requires that the compound have an
|
|
** ORDER BY clause, and it doesn't right now. So invent one first. */
|
|
pOne = _sqlite3ExprInt32(tls, db, int32(1))
|
|
(*TSelect)(unsafe.Pointer(p)).FpOrderBy = _sqlite3ExprListAppend(tls, pParse, uintptr(0), pOne)
|
|
if (*TParse)(unsafe.Pointer(pParse)).FnErr != 0 {
|
|
goto multi_select_end
|
|
}
|
|
*(*Tu16)(unsafe.Pointer((*TSelect)(unsafe.Pointer(p)).FpOrderBy + 8 + 24)) = uint16(1)
|
|
return _multiSelectByMerge(tls, pParse, p, pDest)
|
|
} else {
|
|
/* For a UNION ALL compound without ORDER BY, simply run the left
|
|
** query, then run the right query */
|
|
addr = 0
|
|
**(**int32)(__ccgo_up(bp + 40)) = 0 /* Initialize to suppress harmless compiler warning */
|
|
if (*TSelect)(unsafe.Pointer(pPrior)).FpPrior == uintptr(0) {
|
|
_sqlite3VdbeExplain(tls, pParse, uint8(1), __ccgo_ts+20858, 0)
|
|
_sqlite3VdbeExplain(tls, pParse, uint8(1), __ccgo_ts+20873, 0)
|
|
}
|
|
(*TSelect)(unsafe.Pointer(pPrior)).FiLimit = (*TSelect)(unsafe.Pointer(p)).FiLimit
|
|
(*TSelect)(unsafe.Pointer(pPrior)).FiOffset = (*TSelect)(unsafe.Pointer(p)).FiOffset
|
|
(*TSelect)(unsafe.Pointer(pPrior)).FpLimit = _sqlite3ExprDup(tls, db, (*TSelect)(unsafe.Pointer(p)).FpLimit, 0)
|
|
rc = _sqlite3Select(tls, pParse, pPrior, bp)
|
|
_sqlite3ExprDelete(tls, db, (*TSelect)(unsafe.Pointer(pPrior)).FpLimit)
|
|
(*TSelect)(unsafe.Pointer(pPrior)).FpLimit = uintptr(0)
|
|
if rc != 0 {
|
|
goto multi_select_end
|
|
}
|
|
(*TSelect)(unsafe.Pointer(p)).FpPrior = uintptr(0)
|
|
(*TSelect)(unsafe.Pointer(p)).FiLimit = (*TSelect)(unsafe.Pointer(pPrior)).FiLimit
|
|
(*TSelect)(unsafe.Pointer(p)).FiOffset = (*TSelect)(unsafe.Pointer(pPrior)).FiOffset
|
|
if (*TSelect)(unsafe.Pointer(p)).FiLimit != 0 {
|
|
addr = _sqlite3VdbeAddOp1(tls, v, int32(OP_IfNot), (*TSelect)(unsafe.Pointer(p)).FiLimit)
|
|
if (*TSelect)(unsafe.Pointer(p)).FiOffset != 0 {
|
|
_sqlite3VdbeAddOp3(tls, v, int32(OP_OffsetLimit), (*TSelect)(unsafe.Pointer(p)).FiLimit, (*TSelect)(unsafe.Pointer(p)).FiOffset+int32(1), (*TSelect)(unsafe.Pointer(p)).FiOffset)
|
|
}
|
|
}
|
|
_sqlite3VdbeExplain(tls, pParse, uint8(1), __ccgo_ts+20513, 0)
|
|
rc = _sqlite3Select(tls, pParse, p, bp)
|
|
pDelete = (*TSelect)(unsafe.Pointer(p)).FpPrior
|
|
(*TSelect)(unsafe.Pointer(p)).FpPrior = pPrior
|
|
(*TSelect)(unsafe.Pointer(p)).FnSelectRow = _sqlite3LogEstAdd(tls, (*TSelect)(unsafe.Pointer(p)).FnSelectRow, (*TSelect)(unsafe.Pointer(pPrior)).FnSelectRow)
|
|
if (*TSelect)(unsafe.Pointer(p)).FpLimit != 0 && _sqlite3ExprIsInteger(tls, (*TExpr)(unsafe.Pointer((*TSelect)(unsafe.Pointer(p)).FpLimit)).FpLeft, bp+40, pParse) != 0 && **(**int32)(__ccgo_up(bp + 40)) > 0 && int32((*TSelect)(unsafe.Pointer(p)).FnSelectRow) > int32(_sqlite3LogEst(tls, libc.Uint64FromInt32(**(**int32)(__ccgo_up(bp + 40))))) {
|
|
(*TSelect)(unsafe.Pointer(p)).FnSelectRow = _sqlite3LogEst(tls, libc.Uint64FromInt32(**(**int32)(__ccgo_up(bp + 40))))
|
|
}
|
|
if addr != 0 {
|
|
_sqlite3VdbeJumpHere(tls, v, addr)
|
|
}
|
|
if (*TSelect)(unsafe.Pointer(p)).FpNext == uintptr(0) {
|
|
_sqlite3VdbeExplainPop(tls, pParse)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
goto multi_select_end
|
|
multi_select_end:
|
|
;
|
|
(*TSelectDest)(unsafe.Pointer(pDest)).FiSdst = (**(**TSelectDest)(__ccgo_up(bp))).FiSdst
|
|
(*TSelectDest)(unsafe.Pointer(pDest)).FnSdst = (**(**TSelectDest)(__ccgo_up(bp))).FnSdst
|
|
(*TSelectDest)(unsafe.Pointer(pDest)).FiSDParm2 = (**(**TSelectDest)(__ccgo_up(bp))).FiSDParm2
|
|
if pDelete != 0 {
|
|
_sqlite3ParserAddCleanup(tls, pParse, __ccgo_fp(_sqlite3SelectDeleteGeneric), pDelete)
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Generate code for a compound SELECT statement using a merge
|
|
// ** algorithm. The compound must have an ORDER BY clause for this
|
|
// ** to work.
|
|
// **
|
|
// ** We assume a query of the following form:
|
|
// **
|
|
// ** <selectA> <operator> <selectB> ORDER BY <orderbylist>
|
|
// **
|
|
// ** <operator> is one of UNION ALL, UNION, EXCEPT, or INTERSECT. The idea
|
|
// ** is to code both <selectA> and <selectB> with the ORDER BY clause as
|
|
// ** co-routines. Then run the co-routines in parallel and merge the results
|
|
// ** into the output. In addition to the two coroutines (called selectA and
|
|
// ** selectB) there are 7 subroutines:
|
|
// **
|
|
// ** outA: Move the output of the selectA coroutine into the output
|
|
// ** of the compound query.
|
|
// **
|
|
// ** outB: Move the output of the selectB coroutine into the output
|
|
// ** of the compound query. (Only generated for UNION and
|
|
// ** UNION ALL. EXCEPT and INTERSECT never output a row that
|
|
// ** appears only in B.)
|
|
// **
|
|
// ** AltB: Called when there is data from both coroutines and A<B.
|
|
// **
|
|
// ** AeqB: Called when there is data from both coroutines and A==B.
|
|
// **
|
|
// ** AgtB: Called when there is data from both coroutines and A>B.
|
|
// **
|
|
// ** EofA: Called when data is exhausted from selectA.
|
|
// **
|
|
// ** EofB: Called when data is exhausted from selectB.
|
|
// **
|
|
// ** The implementation of the latter five subroutines depend on which
|
|
// ** <operator> is used:
|
|
// **
|
|
// **
|
|
// ** UNION ALL UNION EXCEPT INTERSECT
|
|
// ** ------------- ----------------- -------------- -----------------
|
|
// ** AltB: outA, nextA outA, nextA outA, nextA nextA
|
|
// **
|
|
// ** AeqB: outA, nextA nextA nextA outA, nextA
|
|
// **
|
|
// ** AgtB: outB, nextB outB, nextB nextB nextB
|
|
// **
|
|
// ** EofA: outB, nextB outB, nextB halt halt
|
|
// **
|
|
// ** EofB: outA, nextA outA, nextA outA, nextA halt
|
|
// **
|
|
// ** In the AltB, AeqB, and AgtB subroutines, an EOF on A following nextA
|
|
// ** causes an immediate jump to EofA and an EOF on B following nextB causes
|
|
// ** an immediate jump to EofB. Within EofA and EofB, and EOF on entry or
|
|
// ** following nextX causes a jump to the end of the select processing.
|
|
// **
|
|
// ** Duplicate removal in the UNION, EXCEPT, and INTERSECT cases is handled
|
|
// ** within the output subroutine. The regPrev register set holds the previously
|
|
// ** output value. A comparison is made against this value and the output
|
|
// ** is skipped if the next results would be the same as the previous.
|
|
// **
|
|
// ** The implementation plan is to implement the two coroutines and seven
|
|
// ** subroutines first, then put the control logic at the bottom. Like this:
|
|
// **
|
|
// ** goto Init
|
|
// ** coA: coroutine for left query (A)
|
|
// ** coB: coroutine for right query (B)
|
|
// ** outA: output one row of A
|
|
// ** outB: output one row of B (UNION and UNION ALL only)
|
|
// ** EofA: ...
|
|
// ** EofB: ...
|
|
// ** AltB: ...
|
|
// ** AeqB: ...
|
|
// ** AgtB: ...
|
|
// ** Init: initialize coroutine registers
|
|
// ** yield coA, on eof goto EofA
|
|
// ** yield coB, on eof goto EofB
|
|
// ** Cmpr: Compare A, B
|
|
// ** Jump AltB, AeqB, AgtB
|
|
// ** End: ...
|
|
// **
|
|
// ** We call AltB, AeqB, AgtB, EofA, and EofB "subroutines" but they are not
|
|
// ** actually called using Gosub and they do not Return. EofA and EofB loop
|
|
// ** until all data is exhausted then jump to the "end" label. AltB, AeqB,
|
|
// ** and AgtB jump to either Cmpr or to one of EofA or EofB.
|
|
// */
|
|
func _multiSelectByMerge(tls *libc.TLS, pParse uintptr, p uintptr, pDest uintptr) (r int32) {
|
|
bp := tls.Alloc(96)
|
|
defer tls.Free(96)
|
|
var aPermute, db, pItem, pItem1, pKeyDup, pKeyMerge, pNew, pOrderBy, pPrior, pSplit, v, v3 uintptr
|
|
var addr1, addrAeqB, addrAgtB, addrAltB, addrEofA, addrEofA_noB, addrEofB, addrOutA, addrOutB, addrSelectA, addrSelectB, bKeep, i, j, labelCmpr, labelEnd, nExpr, nOrderBy, nSelect, op, regAddrA, regAddrB, regLimitA, regLimitB, regOutA, regOutB, regPrev, savedLimit, savedOffset, v4 int32
|
|
var _ /* destA at bp+0 */ TSelectDest
|
|
var _ /* destB at bp+40 */ TSelectDest
|
|
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = aPermute, addr1, addrAeqB, addrAgtB, addrAltB, addrEofA, addrEofA_noB, addrEofB, addrOutA, addrOutB, addrSelectA, addrSelectB, bKeep, db, i, j, labelCmpr, labelEnd, nExpr, nOrderBy, nSelect, op, pItem, pItem1, pKeyDup, pKeyMerge, pNew, pOrderBy, pPrior, pSplit, regAddrA, regAddrB, regLimitA, regLimitB, regOutA, regOutB, regPrev, savedLimit, savedOffset, v, v3, v4 /* Address of the output-A subroutine */
|
|
addrOutB = 0 /* One of TK_ALL, TK_UNION, TK_EXCEPT, TK_INTERSECT */
|
|
pKeyDup = uintptr(0) /* Mapping from ORDER BY terms to result set columns */
|
|
/* "Managed" code needs this. Ticket #3382. */
|
|
db = (*TParse)(unsafe.Pointer(pParse)).Fdb
|
|
v = (*TParse)(unsafe.Pointer(pParse)).FpVdbe
|
|
/* Already thrown the error if VDBE alloc failed */
|
|
labelEnd = _sqlite3VdbeMakeLabel(tls, pParse)
|
|
labelCmpr = _sqlite3VdbeMakeLabel(tls, pParse)
|
|
/* Patch up the ORDER BY clause
|
|
*/
|
|
op = libc.Int32FromUint8((*TSelect)(unsafe.Pointer(p)).Fop)
|
|
pOrderBy = (*TSelect)(unsafe.Pointer(p)).FpOrderBy
|
|
nOrderBy = (*TExprList)(unsafe.Pointer(pOrderBy)).FnExpr
|
|
/* For operators other than UNION ALL we have to make sure that
|
|
** the ORDER BY clause covers every term of the result set. Add
|
|
** terms to the ORDER BY clause as necessary.
|
|
*/
|
|
if op != int32(TK_ALL) {
|
|
i = int32(1)
|
|
for {
|
|
if !(libc.Int32FromUint8((*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed) == 0 && i <= (*TExprList)(unsafe.Pointer((*TSelect)(unsafe.Pointer(p)).FpEList)).FnExpr) {
|
|
break
|
|
}
|
|
j = 0
|
|
pItem = pOrderBy + 8
|
|
for {
|
|
if !(j < nOrderBy) {
|
|
break
|
|
}
|
|
if libc.Int32FromUint16((*(*struct {
|
|
FiOrderByCol Tu16
|
|
FiAlias Tu16
|
|
})(unsafe.Pointer(pItem + 24))).FiOrderByCol) == i {
|
|
break
|
|
}
|
|
goto _2
|
|
_2:
|
|
;
|
|
j = j + 1
|
|
pItem += 32
|
|
}
|
|
if j == nOrderBy {
|
|
pNew = _sqlite3ExprInt32(tls, db, i)
|
|
if pNew == uintptr(0) {
|
|
return int32(SQLITE_NOMEM)
|
|
}
|
|
v3 = _sqlite3ExprListAppend(tls, pParse, pOrderBy, pNew)
|
|
pOrderBy = v3
|
|
(*TSelect)(unsafe.Pointer(p)).FpOrderBy = v3
|
|
if pOrderBy != 0 {
|
|
v4 = nOrderBy
|
|
nOrderBy = nOrderBy + 1
|
|
*(*Tu16)(unsafe.Pointer(pOrderBy + 8 + uintptr(v4)*32 + 24)) = libc.Uint16FromInt32(i)
|
|
}
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
}
|
|
/* Compute the comparison permutation and keyinfo that is used with
|
|
** the permutation to determine if the next row of results comes
|
|
** from selectA or selectB. Also add literal collations to the
|
|
** ORDER BY clause terms so that when selectA and selectB are
|
|
** evaluated, they use the correct collation.
|
|
*/
|
|
aPermute = _sqlite3DbMallocRawNN(tls, db, uint64(uint64(4)*libc.Uint64FromInt32(nOrderBy+libc.Int32FromInt32(1))))
|
|
if aPermute != 0 {
|
|
bKeep = 0
|
|
**(**Tu32)(__ccgo_up(aPermute)) = libc.Uint32FromInt32(nOrderBy)
|
|
i = int32(1)
|
|
pItem1 = pOrderBy + 8
|
|
for {
|
|
if !(i <= nOrderBy) {
|
|
break
|
|
}
|
|
**(**Tu32)(__ccgo_up(aPermute + uintptr(i)*4)) = libc.Uint32FromInt32(libc.Int32FromUint16((*(*struct {
|
|
FiOrderByCol Tu16
|
|
FiAlias Tu16
|
|
})(unsafe.Pointer(pItem1 + 24))).FiOrderByCol) - int32(1))
|
|
if **(**Tu32)(__ccgo_up(aPermute + uintptr(i)*4)) != libc.Uint32FromInt32(i)-uint32(1) {
|
|
bKeep = int32(1)
|
|
}
|
|
goto _5
|
|
_5:
|
|
;
|
|
i = i + 1
|
|
pItem1 += 32
|
|
}
|
|
if bKeep == 0 {
|
|
_sqlite3DbFreeNN(tls, db, aPermute)
|
|
aPermute = uintptr(0)
|
|
}
|
|
}
|
|
pKeyMerge = _multiSelectByMergeKeyInfo(tls, pParse, p, int32(1))
|
|
/* Allocate a range of temporary registers and the KeyInfo needed
|
|
** for the logic that removes duplicate result rows when the
|
|
** operator is UNION, EXCEPT, or INTERSECT (but not UNION ALL).
|
|
*/
|
|
if op == int32(TK_ALL) {
|
|
regPrev = 0
|
|
} else {
|
|
nExpr = (*TExprList)(unsafe.Pointer((*TSelect)(unsafe.Pointer(p)).FpEList)).FnExpr
|
|
regPrev = (*TParse)(unsafe.Pointer(pParse)).FnMem + int32(1)
|
|
**(**int32)(__ccgo_up(pParse + 60)) += nExpr + int32(1)
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_Integer), 0, regPrev)
|
|
pKeyDup = _sqlite3KeyInfoAlloc(tls, db, nExpr, int32(1))
|
|
if pKeyDup != 0 {
|
|
i = 0
|
|
for {
|
|
if !(i < nExpr) {
|
|
break
|
|
}
|
|
*(*uintptr)(unsafe.Pointer(pKeyDup + 32 + uintptr(i)*8)) = _multiSelectCollSeq(tls, pParse, p, i)
|
|
**(**Tu8)(__ccgo_up((*TKeyInfo)(unsafe.Pointer(pKeyDup)).FaSortFlags + uintptr(i))) = uint8(0)
|
|
goto _6
|
|
_6:
|
|
;
|
|
i = i + 1
|
|
}
|
|
}
|
|
}
|
|
/* Separate the left and the right query from one another
|
|
*/
|
|
nSelect = int32(1)
|
|
if (op == int32(TK_ALL) || op == int32(TK_UNION)) && (*Tsqlite3)(unsafe.Pointer(db)).FdbOptFlags&libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_BalancedMerge)) == uint32(0) {
|
|
pSplit = p
|
|
for {
|
|
if !((*TSelect)(unsafe.Pointer(pSplit)).FpPrior != uintptr(0) && libc.Int32FromUint8((*TSelect)(unsafe.Pointer(pSplit)).Fop) == op) {
|
|
break
|
|
}
|
|
nSelect = nSelect + 1
|
|
goto _7
|
|
_7:
|
|
;
|
|
pSplit = (*TSelect)(unsafe.Pointer(pSplit)).FpPrior
|
|
}
|
|
}
|
|
if nSelect <= int32(3) {
|
|
pSplit = p
|
|
} else {
|
|
pSplit = p
|
|
i = int32(2)
|
|
for {
|
|
if !(i < nSelect) {
|
|
break
|
|
}
|
|
pSplit = (*TSelect)(unsafe.Pointer(pSplit)).FpPrior
|
|
goto _8
|
|
_8:
|
|
;
|
|
i = i + int32(2)
|
|
}
|
|
}
|
|
pPrior = (*TSelect)(unsafe.Pointer(pSplit)).FpPrior
|
|
(*TSelect)(unsafe.Pointer(pSplit)).FpPrior = uintptr(0)
|
|
(*TSelect)(unsafe.Pointer(pPrior)).FpNext = uintptr(0)
|
|
(*TSelect)(unsafe.Pointer(pPrior)).FpOrderBy = _sqlite3ExprListDup(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, pOrderBy, 0)
|
|
_sqlite3ResolveOrderGroupBy(tls, pParse, p, (*TSelect)(unsafe.Pointer(p)).FpOrderBy, __ccgo_ts+7687)
|
|
_sqlite3ResolveOrderGroupBy(tls, pParse, pPrior, (*TSelect)(unsafe.Pointer(pPrior)).FpOrderBy, __ccgo_ts+7687)
|
|
/* Compute the limit registers */
|
|
_computeLimitRegisters(tls, pParse, p, labelEnd)
|
|
if (*TSelect)(unsafe.Pointer(p)).FiLimit != 0 && op == int32(TK_ALL) {
|
|
v3 = pParse + 60
|
|
*(*int32)(unsafe.Pointer(v3)) = *(*int32)(unsafe.Pointer(v3)) + 1
|
|
v4 = *(*int32)(unsafe.Pointer(v3))
|
|
regLimitA = v4
|
|
v3 = pParse + 60
|
|
*(*int32)(unsafe.Pointer(v3)) = *(*int32)(unsafe.Pointer(v3)) + 1
|
|
v4 = *(*int32)(unsafe.Pointer(v3))
|
|
regLimitB = v4
|
|
if (*TSelect)(unsafe.Pointer(p)).FiOffset != 0 {
|
|
v4 = (*TSelect)(unsafe.Pointer(p)).FiOffset + int32(1)
|
|
} else {
|
|
v4 = (*TSelect)(unsafe.Pointer(p)).FiLimit
|
|
}
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_Copy), v4, regLimitA)
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_Copy), regLimitA, regLimitB)
|
|
} else {
|
|
v4 = libc.Int32FromInt32(0)
|
|
regLimitB = v4
|
|
regLimitA = v4
|
|
}
|
|
_sqlite3ExprDelete(tls, db, (*TSelect)(unsafe.Pointer(p)).FpLimit)
|
|
(*TSelect)(unsafe.Pointer(p)).FpLimit = uintptr(0)
|
|
v3 = pParse + 60
|
|
*(*int32)(unsafe.Pointer(v3)) = *(*int32)(unsafe.Pointer(v3)) + 1
|
|
v4 = *(*int32)(unsafe.Pointer(v3))
|
|
regAddrA = v4
|
|
v3 = pParse + 60
|
|
*(*int32)(unsafe.Pointer(v3)) = *(*int32)(unsafe.Pointer(v3)) + 1
|
|
v4 = *(*int32)(unsafe.Pointer(v3))
|
|
regAddrB = v4
|
|
v3 = pParse + 60
|
|
*(*int32)(unsafe.Pointer(v3)) = *(*int32)(unsafe.Pointer(v3)) + 1
|
|
v4 = *(*int32)(unsafe.Pointer(v3))
|
|
regOutA = v4
|
|
v3 = pParse + 60
|
|
*(*int32)(unsafe.Pointer(v3)) = *(*int32)(unsafe.Pointer(v3)) + 1
|
|
v4 = *(*int32)(unsafe.Pointer(v3))
|
|
regOutB = v4
|
|
_sqlite3SelectDestInit(tls, bp, int32(SRT_Coroutine), regAddrA)
|
|
_sqlite3SelectDestInit(tls, bp+40, int32(SRT_Coroutine), regAddrB)
|
|
_sqlite3VdbeExplain(tls, pParse, uint8(1), __ccgo_ts+21020, libc.VaList(bp+88, _sqlite3SelectOpName(tls, libc.Int32FromUint8((*TSelect)(unsafe.Pointer(p)).Fop))))
|
|
/* Generate a coroutine to evaluate the SELECT statement to the
|
|
** left of the compound operator - the "A" select.
|
|
*/
|
|
addrSelectA = _sqlite3VdbeCurrentAddr(tls, v) + int32(1)
|
|
addr1 = _sqlite3VdbeAddOp3(tls, v, int32(OP_InitCoroutine), regAddrA, 0, addrSelectA)
|
|
(*TSelect)(unsafe.Pointer(pPrior)).FiLimit = regLimitA
|
|
_sqlite3VdbeExplain(tls, pParse, uint8(1), __ccgo_ts+21031, 0)
|
|
_sqlite3Select(tls, pParse, pPrior, bp)
|
|
_sqlite3VdbeEndCoroutine(tls, v, regAddrA)
|
|
_sqlite3VdbeJumpHere(tls, v, addr1)
|
|
/* Generate a coroutine to evaluate the SELECT statement on
|
|
** the right - the "B" select
|
|
*/
|
|
addrSelectB = _sqlite3VdbeCurrentAddr(tls, v) + int32(1)
|
|
addr1 = _sqlite3VdbeAddOp3(tls, v, int32(OP_InitCoroutine), regAddrB, 0, addrSelectB)
|
|
savedLimit = (*TSelect)(unsafe.Pointer(p)).FiLimit
|
|
savedOffset = (*TSelect)(unsafe.Pointer(p)).FiOffset
|
|
(*TSelect)(unsafe.Pointer(p)).FiLimit = regLimitB
|
|
(*TSelect)(unsafe.Pointer(p)).FiOffset = 0
|
|
_sqlite3VdbeExplain(tls, pParse, uint8(1), __ccgo_ts+21036, 0)
|
|
_sqlite3Select(tls, pParse, p, bp+40)
|
|
(*TSelect)(unsafe.Pointer(p)).FiLimit = savedLimit
|
|
(*TSelect)(unsafe.Pointer(p)).FiOffset = savedOffset
|
|
_sqlite3VdbeEndCoroutine(tls, v, regAddrB)
|
|
/* Generate a subroutine that outputs the current row of the A
|
|
** select as the next output row of the compound select.
|
|
*/
|
|
addrOutA = _generateOutputSubroutine(tls, pParse, p, bp, pDest, regOutA, regPrev, pKeyDup, labelEnd)
|
|
/* Generate a subroutine that outputs the current row of the B
|
|
** select as the next output row of the compound select.
|
|
*/
|
|
if op == int32(TK_ALL) || op == int32(TK_UNION) {
|
|
addrOutB = _generateOutputSubroutine(tls, pParse, p, bp+40, pDest, regOutB, regPrev, pKeyDup, labelEnd)
|
|
}
|
|
_sqlite3KeyInfoUnref(tls, pKeyDup)
|
|
/* Generate a subroutine to run when the results from select A
|
|
** are exhausted and only data in select B remains.
|
|
*/
|
|
if op == int32(TK_EXCEPT) || op == int32(TK_INTERSECT) {
|
|
v4 = labelEnd
|
|
addrEofA = v4
|
|
addrEofA_noB = v4
|
|
} else {
|
|
addrEofA = _sqlite3VdbeAddOp2(tls, v, int32(OP_Gosub), regOutB, addrOutB)
|
|
addrEofA_noB = _sqlite3VdbeAddOp2(tls, v, int32(OP_Yield), regAddrB, labelEnd)
|
|
_sqlite3VdbeGoto(tls, v, addrEofA)
|
|
(*TSelect)(unsafe.Pointer(p)).FnSelectRow = _sqlite3LogEstAdd(tls, (*TSelect)(unsafe.Pointer(p)).FnSelectRow, (*TSelect)(unsafe.Pointer(pPrior)).FnSelectRow)
|
|
}
|
|
/* Generate a subroutine to run when the results from select B
|
|
** are exhausted and only data in select A remains.
|
|
*/
|
|
if op == int32(TK_INTERSECT) {
|
|
addrEofB = addrEofA
|
|
if int32((*TSelect)(unsafe.Pointer(p)).FnSelectRow) > int32((*TSelect)(unsafe.Pointer(pPrior)).FnSelectRow) {
|
|
(*TSelect)(unsafe.Pointer(p)).FnSelectRow = (*TSelect)(unsafe.Pointer(pPrior)).FnSelectRow
|
|
}
|
|
} else {
|
|
addrEofB = _sqlite3VdbeAddOp2(tls, v, int32(OP_Gosub), regOutA, addrOutA)
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_Yield), regAddrA, labelEnd)
|
|
_sqlite3VdbeGoto(tls, v, addrEofB)
|
|
}
|
|
/* Generate code to handle the case of A<B
|
|
*/
|
|
addrAltB = _sqlite3VdbeAddOp2(tls, v, int32(OP_Gosub), regOutA, addrOutA)
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_Yield), regAddrA, addrEofA)
|
|
_sqlite3VdbeGoto(tls, v, labelCmpr)
|
|
/* Generate code to handle the case of A==B
|
|
*/
|
|
if op == int32(TK_ALL) {
|
|
addrAeqB = addrAltB
|
|
} else {
|
|
if op == int32(TK_INTERSECT) {
|
|
addrAeqB = addrAltB
|
|
addrAltB = addrAltB + 1
|
|
} else {
|
|
addrAeqB = addrAltB + int32(1)
|
|
}
|
|
}
|
|
/* Generate code to handle the case of A>B
|
|
*/
|
|
addrAgtB = _sqlite3VdbeCurrentAddr(tls, v)
|
|
if op == int32(TK_ALL) || op == int32(TK_UNION) {
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_Gosub), regOutB, addrOutB)
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_Yield), regAddrB, addrEofB)
|
|
_sqlite3VdbeGoto(tls, v, labelCmpr)
|
|
} else {
|
|
addrAgtB = addrAgtB + 1 /* Just do next-B. Might as well use the next-B call
|
|
** in the next code block */
|
|
}
|
|
/* This code runs once to initialize everything.
|
|
*/
|
|
_sqlite3VdbeJumpHere(tls, v, addr1)
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_Yield), regAddrA, addrEofA_noB)
|
|
/* v--- Also the A>B case for EXCEPT and INTERSECT */
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_Yield), regAddrB, addrEofB)
|
|
/* Implement the main merge loop
|
|
*/
|
|
if aPermute != uintptr(0) {
|
|
_sqlite3VdbeAddOp4(tls, v, int32(OP_Permutation), 0, 0, 0, aPermute, -int32(15))
|
|
}
|
|
_sqlite3VdbeResolveLabel(tls, v, labelCmpr)
|
|
_sqlite3VdbeAddOp4(tls, v, int32(OP_Compare), (**(**TSelectDest)(__ccgo_up(bp))).FiSdst, (**(**TSelectDest)(__ccgo_up(bp + 40))).FiSdst, nOrderBy, pKeyMerge, -int32(9))
|
|
if aPermute != uintptr(0) {
|
|
_sqlite3VdbeChangeP5(tls, v, uint16(OPFLAG_PERMUTE))
|
|
}
|
|
_sqlite3VdbeAddOp3(tls, v, int32(OP_Jump), addrAltB, addrAeqB, addrAgtB)
|
|
/* Jump to the this point in order to terminate the query.
|
|
*/
|
|
_sqlite3VdbeResolveLabel(tls, v, labelEnd)
|
|
/* Make arrangements to free the 2nd and subsequent arms of the compound
|
|
** after the parse has finished */
|
|
if (*TSelect)(unsafe.Pointer(pSplit)).FpPrior != 0 {
|
|
_sqlite3ParserAddCleanup(tls, pParse, __ccgo_fp(_sqlite3SelectDeleteGeneric), (*TSelect)(unsafe.Pointer(pSplit)).FpPrior)
|
|
}
|
|
(*TSelect)(unsafe.Pointer(pSplit)).FpPrior = pPrior
|
|
(*TSelect)(unsafe.Pointer(pPrior)).FpNext = pSplit
|
|
_sqlite3ExprListDelete(tls, db, (*TSelect)(unsafe.Pointer(pPrior)).FpOrderBy)
|
|
(*TSelect)(unsafe.Pointer(pPrior)).FpOrderBy = uintptr(0)
|
|
/*** TBD: Insert subroutine calls to close cursors on incomplete
|
|
**** subqueries ****/
|
|
_sqlite3VdbeExplainPop(tls, pParse)
|
|
return libc.BoolInt32((*TParse)(unsafe.Pointer(pParse)).FnErr != 0)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Obtain a reference to an r-tree node.
|
|
// */
|
|
func _nodeAcquire(tls *libc.TLS, pRtree uintptr, iNode Ti64, pParent uintptr, ppNode uintptr) (r int32) {
|
|
var pBlob, pNode, v1 uintptr
|
|
var rc int32
|
|
_, _, _, _ = pBlob, pNode, rc, v1
|
|
rc = SQLITE_OK
|
|
pNode = uintptr(0)
|
|
/* Check if the requested node is already in the hash table. If so,
|
|
** increase its reference count and return it.
|
|
*/
|
|
v1 = _nodeHashLookup(tls, pRtree, iNode)
|
|
pNode = v1
|
|
if v1 != uintptr(0) {
|
|
if pParent != 0 && pParent != (*TRtreeNode)(unsafe.Pointer(pNode)).FpParent {
|
|
return libc.Int32FromInt32(SQLITE_CORRUPT) | libc.Int32FromInt32(1)<<libc.Int32FromInt32(8)
|
|
}
|
|
(*TRtreeNode)(unsafe.Pointer(pNode)).FnRef = (*TRtreeNode)(unsafe.Pointer(pNode)).FnRef + 1
|
|
**(**uintptr)(__ccgo_up(ppNode)) = pNode
|
|
return SQLITE_OK
|
|
}
|
|
if (*TRtree)(unsafe.Pointer(pRtree)).FpNodeBlob != 0 {
|
|
pBlob = (*TRtree)(unsafe.Pointer(pRtree)).FpNodeBlob
|
|
(*TRtree)(unsafe.Pointer(pRtree)).FpNodeBlob = uintptr(0)
|
|
rc = Xsqlite3_blob_reopen(tls, pBlob, iNode)
|
|
(*TRtree)(unsafe.Pointer(pRtree)).FpNodeBlob = pBlob
|
|
if rc != 0 {
|
|
_nodeBlobReset(tls, pRtree)
|
|
if rc == int32(SQLITE_NOMEM) {
|
|
return int32(SQLITE_NOMEM)
|
|
}
|
|
}
|
|
}
|
|
if (*TRtree)(unsafe.Pointer(pRtree)).FpNodeBlob == uintptr(0) {
|
|
rc = Xsqlite3_blob_open(tls, (*TRtree)(unsafe.Pointer(pRtree)).Fdb, (*TRtree)(unsafe.Pointer(pRtree)).FzDb, (*TRtree)(unsafe.Pointer(pRtree)).FzNodeName, __ccgo_ts+27432, iNode, 0, pRtree+120)
|
|
}
|
|
if rc != 0 {
|
|
**(**uintptr)(__ccgo_up(ppNode)) = uintptr(0)
|
|
/* If unable to open an sqlite3_blob on the desired row, that can only
|
|
** be because the shadow tables hold erroneous data. */
|
|
if rc == int32(SQLITE_ERROR) {
|
|
rc = libc.Int32FromInt32(SQLITE_CORRUPT) | libc.Int32FromInt32(1)<<libc.Int32FromInt32(8)
|
|
}
|
|
} else {
|
|
if iNode <= 0 {
|
|
rc = libc.Int32FromInt32(SQLITE_CORRUPT) | libc.Int32FromInt32(1)<<libc.Int32FromInt32(8)
|
|
} else {
|
|
if (*TRtree)(unsafe.Pointer(pRtree)).FiNodeSize == Xsqlite3_blob_bytes(tls, (*TRtree)(unsafe.Pointer(pRtree)).FpNodeBlob) {
|
|
pNode = Xsqlite3_malloc64(tls, uint64(uint64(40)+libc.Uint64FromInt32((*TRtree)(unsafe.Pointer(pRtree)).FiNodeSize)))
|
|
if !(pNode != 0) {
|
|
rc = int32(SQLITE_NOMEM)
|
|
} else {
|
|
(*TRtreeNode)(unsafe.Pointer(pNode)).FpParent = pParent
|
|
(*TRtreeNode)(unsafe.Pointer(pNode)).FzData = pNode + 1*40
|
|
(*TRtreeNode)(unsafe.Pointer(pNode)).FnRef = int32(1)
|
|
(*TRtree)(unsafe.Pointer(pRtree)).FnNodeRef = (*TRtree)(unsafe.Pointer(pRtree)).FnNodeRef + 1
|
|
(*TRtreeNode)(unsafe.Pointer(pNode)).FiNode = iNode
|
|
(*TRtreeNode)(unsafe.Pointer(pNode)).FisDirty = 0
|
|
(*TRtreeNode)(unsafe.Pointer(pNode)).FpNext = uintptr(0)
|
|
rc = Xsqlite3_blob_read(tls, (*TRtree)(unsafe.Pointer(pRtree)).FpNodeBlob, (*TRtreeNode)(unsafe.Pointer(pNode)).FzData, (*TRtree)(unsafe.Pointer(pRtree)).FiNodeSize, 0)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/* If the root node was just loaded, set pRtree->iDepth to the height
|
|
** of the r-tree structure. A height of zero means all data is stored on
|
|
** the root node. A height of one means the children of the root node
|
|
** are the leaves, and so on. If the depth as specified on the root node
|
|
** is greater than RTREE_MAX_DEPTH, the r-tree structure must be corrupt.
|
|
*/
|
|
if rc == SQLITE_OK && pNode != 0 && iNode == int64(1) {
|
|
(*TRtree)(unsafe.Pointer(pRtree)).FiDepth = _readInt16(tls, (*TRtreeNode)(unsafe.Pointer(pNode)).FzData)
|
|
if (*TRtree)(unsafe.Pointer(pRtree)).FiDepth >= int32(RTREE_MAX_DEPTH) {
|
|
rc = libc.Int32FromInt32(SQLITE_CORRUPT) | libc.Int32FromInt32(1)<<libc.Int32FromInt32(8)
|
|
}
|
|
}
|
|
/* If no error has occurred so far, check if the "number of entries"
|
|
** field on the node is too large. If so, set the return code to
|
|
** SQLITE_CORRUPT_VTAB.
|
|
*/
|
|
if pNode != 0 && rc == SQLITE_OK {
|
|
if _readInt16(tls, (*TRtreeNode)(unsafe.Pointer(pNode)).FzData+2) > ((*TRtree)(unsafe.Pointer(pRtree)).FiNodeSize-int32(4))/libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FnBytesPerCell) {
|
|
rc = libc.Int32FromInt32(SQLITE_CORRUPT) | libc.Int32FromInt32(1)<<libc.Int32FromInt32(8)
|
|
}
|
|
}
|
|
if rc == SQLITE_OK {
|
|
if pNode != uintptr(0) {
|
|
_nodeReference(tls, pParent)
|
|
_nodeHashInsert(tls, pRtree, pNode)
|
|
} else {
|
|
rc = libc.Int32FromInt32(SQLITE_CORRUPT) | libc.Int32FromInt32(1)<<libc.Int32FromInt32(8)
|
|
}
|
|
**(**uintptr)(__ccgo_up(ppNode)) = pNode
|
|
} else {
|
|
_nodeBlobReset(tls, pRtree)
|
|
if pNode != 0 {
|
|
(*TRtree)(unsafe.Pointer(pRtree)).FnNodeRef = (*TRtree)(unsafe.Pointer(pRtree)).FnNodeRef - 1
|
|
Xsqlite3_free(tls, pNode)
|
|
}
|
|
**(**uintptr)(__ccgo_up(ppNode)) = uintptr(0)
|
|
}
|
|
return rc
|
|
}
|
|
|
|
func _nth_valueStepFunc(tls *libc.TLS, pCtx uintptr, nArg int32, apArg uintptr) {
|
|
var fVal float64
|
|
var iVal Ti64
|
|
var p uintptr
|
|
_, _, _ = fVal, iVal, p
|
|
p = Xsqlite3_aggregate_context(tls, pCtx, int32(16))
|
|
if p != 0 {
|
|
switch Xsqlite3_value_numeric_type(tls, **(**uintptr)(__ccgo_up(apArg + 1*8))) {
|
|
case int32(SQLITE_INTEGER):
|
|
iVal = Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(apArg + 1*8)))
|
|
case int32(SQLITE_FLOAT):
|
|
fVal = Xsqlite3_value_double(tls, **(**uintptr)(__ccgo_up(apArg + 1*8)))
|
|
if float64(_sqlite3RealToI64(tls, fVal)) != fVal {
|
|
goto error_out
|
|
}
|
|
iVal = int64(fVal)
|
|
default:
|
|
goto error_out
|
|
}
|
|
if iVal <= 0 {
|
|
goto error_out
|
|
}
|
|
(*TNthValueCtx)(unsafe.Pointer(p)).FnStep = (*TNthValueCtx)(unsafe.Pointer(p)).FnStep + 1
|
|
if iVal == (*TNthValueCtx)(unsafe.Pointer(p)).FnStep {
|
|
(*TNthValueCtx)(unsafe.Pointer(p)).FpValue = Xsqlite3_value_dup(tls, **(**uintptr)(__ccgo_up(apArg)))
|
|
if !((*TNthValueCtx)(unsafe.Pointer(p)).FpValue != 0) {
|
|
Xsqlite3_result_error_nomem(tls, pCtx)
|
|
}
|
|
}
|
|
}
|
|
_ = nArg
|
|
_ = apArg
|
|
return
|
|
goto error_out
|
|
error_out:
|
|
;
|
|
Xsqlite3_result_error(tls, pCtx, __ccgo_ts+24203, -int32(1))
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This routine does the work of opening a database on behalf of
|
|
// ** sqlite3_open() and sqlite3_open16(). The database filename "zFilename"
|
|
// ** is UTF-8 encoded.
|
|
// */
|
|
func _openDatabase(tls *libc.TLS, zFilename uintptr, ppDb uintptr, _flags uint32, zVfs uintptr) (r int32) {
|
|
bp := tls.Alloc(48)
|
|
defer tls.Free(48)
|
|
*(*uint32)(unsafe.Pointer(bp)) = _flags
|
|
var db, v2 uintptr
|
|
var i, isThreadsafe, rc int32
|
|
var v1 uint32
|
|
var _ /* zErrMsg at bp+16 */ uintptr
|
|
var _ /* zOpen at bp+8 */ uintptr
|
|
_, _, _, _, _, _ = db, i, isThreadsafe, rc, v1, v2 /* True for threadsafe connections */
|
|
**(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0) /* Filename argument to pass to BtreeOpen() */
|
|
**(**uintptr)(__ccgo_up(bp + 16)) = uintptr(0) /* Loop counter */
|
|
**(**uintptr)(__ccgo_up(ppDb)) = uintptr(0)
|
|
rc = Xsqlite3_initialize(tls)
|
|
if rc != 0 {
|
|
return rc
|
|
}
|
|
if libc.Int32FromUint8(_sqlite3Config.FbCoreMutex) == 0 {
|
|
isThreadsafe = 0
|
|
} else {
|
|
if **(**uint32)(__ccgo_up(bp))&uint32(SQLITE_OPEN_NOMUTEX) != 0 {
|
|
isThreadsafe = 0
|
|
} else {
|
|
if **(**uint32)(__ccgo_up(bp))&uint32(SQLITE_OPEN_FULLMUTEX) != 0 {
|
|
isThreadsafe = int32(1)
|
|
} else {
|
|
isThreadsafe = libc.Int32FromUint8(_sqlite3Config.FbFullMutex)
|
|
}
|
|
}
|
|
}
|
|
if **(**uint32)(__ccgo_up(bp))&uint32(SQLITE_OPEN_PRIVATECACHE) != 0 {
|
|
**(**uint32)(__ccgo_up(bp)) = **(**uint32)(__ccgo_up(bp)) & libc.Uint32FromInt32(^libc.Int32FromInt32(SQLITE_OPEN_SHAREDCACHE))
|
|
} else {
|
|
if _sqlite3Config.FsharedCacheEnabled != 0 {
|
|
**(**uint32)(__ccgo_up(bp)) = **(**uint32)(__ccgo_up(bp)) | uint32(SQLITE_OPEN_SHAREDCACHE)
|
|
}
|
|
}
|
|
/* Remove harmful bits from the flags parameter
|
|
**
|
|
** The SQLITE_OPEN_NOMUTEX and SQLITE_OPEN_FULLMUTEX flags were
|
|
** dealt with in the previous code block. Besides these, the only
|
|
** valid input flags for sqlite3_open_v2() are SQLITE_OPEN_READONLY,
|
|
** SQLITE_OPEN_READWRITE, SQLITE_OPEN_CREATE, SQLITE_OPEN_SHAREDCACHE,
|
|
** SQLITE_OPEN_PRIVATECACHE, SQLITE_OPEN_EXRESCODE, and some reserved
|
|
** bits. Silently mask off all other flags.
|
|
*/
|
|
**(**uint32)(__ccgo_up(bp)) = **(**uint32)(__ccgo_up(bp)) & libc.Uint32FromInt32(^(libc.Int32FromInt32(SQLITE_OPEN_DELETEONCLOSE) | libc.Int32FromInt32(SQLITE_OPEN_EXCLUSIVE) | libc.Int32FromInt32(SQLITE_OPEN_MAIN_DB) | libc.Int32FromInt32(SQLITE_OPEN_TEMP_DB) | libc.Int32FromInt32(SQLITE_OPEN_TRANSIENT_DB) | libc.Int32FromInt32(SQLITE_OPEN_MAIN_JOURNAL) | libc.Int32FromInt32(SQLITE_OPEN_TEMP_JOURNAL) | libc.Int32FromInt32(SQLITE_OPEN_SUBJOURNAL) | libc.Int32FromInt32(SQLITE_OPEN_SUPER_JOURNAL) | libc.Int32FromInt32(SQLITE_OPEN_NOMUTEX) | libc.Int32FromInt32(SQLITE_OPEN_FULLMUTEX) | libc.Int32FromInt32(SQLITE_OPEN_WAL)))
|
|
/* Allocate the sqlite data structure */
|
|
db = _sqlite3MallocZero(tls, uint64(864))
|
|
if db == uintptr(0) {
|
|
goto opendb_out
|
|
}
|
|
if isThreadsafe != 0 {
|
|
(*Tsqlite3)(unsafe.Pointer(db)).Fmutex = _sqlite3MutexAlloc(tls, int32(SQLITE_MUTEX_RECURSIVE))
|
|
if (*Tsqlite3)(unsafe.Pointer(db)).Fmutex == uintptr(0) {
|
|
Xsqlite3_free(tls, db)
|
|
db = uintptr(0)
|
|
goto opendb_out
|
|
}
|
|
if isThreadsafe == 0 {
|
|
}
|
|
}
|
|
Xsqlite3_mutex_enter(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
|
|
if **(**uint32)(__ccgo_up(bp))&uint32(SQLITE_OPEN_EXRESCODE) != uint32(0) {
|
|
v1 = uint32(0xffffffff)
|
|
} else {
|
|
v1 = uint32(0xff)
|
|
}
|
|
(*Tsqlite3)(unsafe.Pointer(db)).FerrMask = libc.Int32FromUint32(v1)
|
|
(*Tsqlite3)(unsafe.Pointer(db)).FnDb = int32(2)
|
|
(*Tsqlite3)(unsafe.Pointer(db)).FeOpenState = uint8(SQLITE_STATE_BUSY)
|
|
(*Tsqlite3)(unsafe.Pointer(db)).FaDb = db + 696
|
|
(*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FbDisable = uint32(1)
|
|
(*Tsqlite3)(unsafe.Pointer(db)).Flookaside.Fsz = uint16(0)
|
|
(*Tsqlite3)(unsafe.Pointer(db)).FnFpDigit = uint8(17)
|
|
libc.Xmemcpy(tls, db+136, uintptr(unsafe.Pointer(&_aHardLimit)), uint64(52))
|
|
**(**int32)(__ccgo_up(db + 136 + 11*4)) = SQLITE_DEFAULT_WORKER_THREADS
|
|
(*Tsqlite3)(unsafe.Pointer(db)).FautoCommit = uint8(1)
|
|
(*Tsqlite3)(unsafe.Pointer(db)).FnextAutovac = int8(-int32(1))
|
|
(*Tsqlite3)(unsafe.Pointer(db)).FszMmap = _sqlite3Config.FszMmap
|
|
(*Tsqlite3)(unsafe.Pointer(db)).FnextPagesize = 0
|
|
(*Tsqlite3)(unsafe.Pointer(db)).Finit1.FazInit = uintptr(unsafe.Pointer(&_sqlite3StdType)) /* Any array of string ptrs will do */
|
|
**(**Tu64)(__ccgo_up(db + 48)) |= uint64(libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_ShortColNames)|libc.Int32FromInt32(SQLITE_EnableTrigger))|libc.Uint32FromUint32(SQLITE_EnableView)|libc.Uint32FromInt32(SQLITE_CacheSpill)) | libc.Uint64FromInt32(libc.Int32FromInt32(0x00010))<<libc.Int32FromInt32(32) | libc.Uint64FromInt32(libc.Int32FromInt32(0x00020))<<libc.Int32FromInt32(32) | libc.Uint64FromInt32(libc.Int32FromInt32(0x00040))<<libc.Int32FromInt32(32) | libc.Uint64FromInt32(SQLITE_TrustedSchema) | libc.Uint64FromInt32(SQLITE_DqsDML) | libc.Uint64FromInt32(SQLITE_DqsDDL) | libc.Uint64FromInt32(SQLITE_AutoIndex)
|
|
_sqlite3HashInit(tls, db+648)
|
|
_sqlite3HashInit(tls, db+576)
|
|
/* Add the default collation sequence BINARY. BINARY works for both UTF-8
|
|
** and UTF-16, so add a version for each to avoid any unnecessary
|
|
** conversions. The only error that can occur here is a malloc() failure.
|
|
**
|
|
** EVIDENCE-OF: R-52786-44878 SQLite defines three built-in collating
|
|
** functions:
|
|
*/
|
|
_createCollation(tls, db, uintptr(unsafe.Pointer(&_sqlite3StrBINARY)), uint8(SQLITE_UTF8), uintptr(0), __ccgo_fp(_binCollFunc), uintptr(0))
|
|
_createCollation(tls, db, uintptr(unsafe.Pointer(&_sqlite3StrBINARY)), uint8(SQLITE_UTF16BE), uintptr(0), __ccgo_fp(_binCollFunc), uintptr(0))
|
|
_createCollation(tls, db, uintptr(unsafe.Pointer(&_sqlite3StrBINARY)), uint8(SQLITE_UTF16LE), uintptr(0), __ccgo_fp(_binCollFunc), uintptr(0))
|
|
_createCollation(tls, db, __ccgo_ts+23969, uint8(SQLITE_UTF8), uintptr(0), __ccgo_fp(_nocaseCollatingFunc), uintptr(0))
|
|
_createCollation(tls, db, __ccgo_ts+26286, uint8(SQLITE_UTF8), uintptr(0), __ccgo_fp(_rtrimCollFunc), uintptr(0))
|
|
if (*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0 {
|
|
goto opendb_out
|
|
}
|
|
/* Parse the filename/URI argument
|
|
**
|
|
** Only allow sensible combinations of bits in the flags argument.
|
|
** Throw an error if any non-sense combination is used. If we
|
|
** do not block illegal combinations here, it could trigger
|
|
** assert() statements in deeper layers. Sensible combinations
|
|
** are:
|
|
**
|
|
** 1: SQLITE_OPEN_READONLY
|
|
** 2: SQLITE_OPEN_READWRITE
|
|
** 6: SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE
|
|
*/
|
|
(*Tsqlite3)(unsafe.Pointer(db)).FopenFlags = **(**uint32)(__ccgo_up(bp))
|
|
/* READONLY */
|
|
/* READWRITE */
|
|
/* READWRITE | CREATE */
|
|
if int32(1)<<(**(**uint32)(__ccgo_up(bp))&uint32(7))&int32(0x46) == 0 {
|
|
rc = _sqlite3MisuseError(tls, int32(191114)) /* IMP: R-18321-05872 */
|
|
} else {
|
|
if zFilename == uintptr(0) {
|
|
zFilename = __ccgo_ts + 4367
|
|
}
|
|
rc = _sqlite3ParseUri(tls, zVfs, zFilename, bp, db, bp+8, bp+16)
|
|
}
|
|
if rc != SQLITE_OK {
|
|
if rc == int32(SQLITE_NOMEM) {
|
|
_sqlite3OomFault(tls, db)
|
|
}
|
|
if **(**uintptr)(__ccgo_up(bp + 16)) != 0 {
|
|
v2 = __ccgo_ts + 3968
|
|
} else {
|
|
v2 = uintptr(0)
|
|
}
|
|
_sqlite3ErrorWithMsg(tls, db, rc, v2, libc.VaList(bp+32, **(**uintptr)(__ccgo_up(bp + 16))))
|
|
Xsqlite3_free(tls, **(**uintptr)(__ccgo_up(bp + 16)))
|
|
goto opendb_out
|
|
}
|
|
/* Open the backend database driver */
|
|
rc = _sqlite3BtreeOpen(tls, (*Tsqlite3)(unsafe.Pointer(db)).FpVfs, **(**uintptr)(__ccgo_up(bp + 8)), db, (*Tsqlite3)(unsafe.Pointer(db)).FaDb+8, 0, libc.Int32FromUint32(**(**uint32)(__ccgo_up(bp))|uint32(SQLITE_OPEN_MAIN_DB)))
|
|
if rc != SQLITE_OK {
|
|
if rc == libc.Int32FromInt32(SQLITE_IOERR)|libc.Int32FromInt32(12)<<libc.Int32FromInt32(8) {
|
|
rc = int32(SQLITE_NOMEM)
|
|
}
|
|
_sqlite3Error(tls, db, rc)
|
|
goto opendb_out
|
|
}
|
|
_sqlite3BtreeEnter(tls, (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb))).FpBt)
|
|
(**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb))).FpSchema = _sqlite3SchemaGet(tls, db, (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb))).FpBt)
|
|
if !((*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0) {
|
|
_sqlite3SetTextEncoding(tls, db, (*TSchema)(unsafe.Pointer((**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb))).FpSchema)).Fenc)
|
|
}
|
|
_sqlite3BtreeLeave(tls, (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb))).FpBt)
|
|
(**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + 1*32))).FpSchema = _sqlite3SchemaGet(tls, db, uintptr(0))
|
|
/* The default safety_level for the main database is FULL; for the temp
|
|
** database it is OFF. This matches the pager layer defaults.
|
|
*/
|
|
(**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb))).FzDbSName = __ccgo_ts + 6844
|
|
(**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb))).Fsafety_level = libc.Uint8FromInt32(libc.Int32FromInt32(SQLITE_DEFAULT_SYNCHRONOUS) + libc.Int32FromInt32(1))
|
|
(**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + 1*32))).FzDbSName = __ccgo_ts + 25288
|
|
(**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + 1*32))).Fsafety_level = uint8(PAGER_SYNCHRONOUS_OFF)
|
|
(*Tsqlite3)(unsafe.Pointer(db)).FeOpenState = uint8(SQLITE_STATE_OPEN)
|
|
if (*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0 {
|
|
goto opendb_out
|
|
}
|
|
/* Register all built-in functions, but do not attempt to read the
|
|
** database schema yet. This is delayed until the first time the database
|
|
** is accessed.
|
|
*/
|
|
_sqlite3Error(tls, db, SQLITE_OK)
|
|
_sqlite3RegisterPerConnectionBuiltinFunctions(tls, db)
|
|
rc = Xsqlite3_errcode(tls, db)
|
|
/* Load compiled-in extensions */
|
|
i = 0
|
|
for {
|
|
if !(rc == SQLITE_OK && i < libc.Int32FromUint64(libc.Uint64FromInt64(40)/libc.Uint64FromInt64(8))) {
|
|
break
|
|
}
|
|
rc = (*(*func(*libc.TLS, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_sqlite3BuiltinExtensions[i]})))(tls, db)
|
|
goto _3
|
|
_3:
|
|
;
|
|
i = i + 1
|
|
}
|
|
/* Load automatic extensions - extensions that have been registered
|
|
** using the sqlite3_automatic_extension() API.
|
|
*/
|
|
if rc == SQLITE_OK {
|
|
_sqlite3AutoLoadExtensions(tls, db)
|
|
rc = Xsqlite3_errcode(tls, db)
|
|
if rc != SQLITE_OK {
|
|
goto opendb_out
|
|
}
|
|
}
|
|
/* -DSQLITE_DEFAULT_LOCKING_MODE=1 makes EXCLUSIVE the default locking
|
|
** mode. -DSQLITE_DEFAULT_LOCKING_MODE=0 make NORMAL the default locking
|
|
** mode. Doing nothing at all also makes NORMAL the default.
|
|
*/
|
|
if rc != 0 {
|
|
_sqlite3Error(tls, db, rc)
|
|
}
|
|
/* Enable the lookaside-malloc subsystem */
|
|
_setupLookaside(tls, db, uintptr(0), _sqlite3Config.FszLookaside, _sqlite3Config.FnLookaside)
|
|
Xsqlite3_wal_autocheckpoint(tls, db, int32(SQLITE_DEFAULT_WAL_AUTOCHECKPOINT))
|
|
goto opendb_out
|
|
opendb_out:
|
|
;
|
|
if db != 0 {
|
|
Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
|
|
}
|
|
rc = Xsqlite3_errcode(tls, db)
|
|
if rc&int32(0xff) == int32(SQLITE_NOMEM) {
|
|
Xsqlite3_close(tls, db)
|
|
db = uintptr(0)
|
|
} else {
|
|
if rc != SQLITE_OK {
|
|
(*Tsqlite3)(unsafe.Pointer(db)).FeOpenState = uint8(SQLITE_STATE_SICK)
|
|
}
|
|
}
|
|
**(**uintptr)(__ccgo_up(ppDb)) = db
|
|
Xsqlite3_free_filename(tls, **(**uintptr)(__ccgo_up(bp + 8)))
|
|
return rc
|
|
}
|
|
|
|
func _openRbuHandle(tls *libc.TLS, zTarget uintptr, zRbu uintptr, zState uintptr) (r uintptr) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var db, p, pCsr, pFd, pState, v2 uintptr
|
|
var frc int32
|
|
var nByte, nRbu, nTarget Tsize_t
|
|
var v1 uint64
|
|
var _ /* bRetry at bp+0 */ int32
|
|
_, _, _, _, _, _, _, _, _, _, _ = db, frc, nByte, nRbu, nTarget, p, pCsr, pFd, pState, v1, v2
|
|
if zTarget != 0 {
|
|
v1 = libc.Xstrlen(tls, zTarget)
|
|
} else {
|
|
v1 = uint64(0)
|
|
}
|
|
nTarget = v1
|
|
nRbu = libc.Xstrlen(tls, zRbu)
|
|
nByte = uint64(416) + nTarget + uint64(1) + nRbu + uint64(1)
|
|
p = Xsqlite3_malloc64(tls, nByte)
|
|
if p != 0 {
|
|
pState = uintptr(0)
|
|
/* Create the custom VFS. */
|
|
libc.Xmemset(tls, p, 0, uint64(416))
|
|
Xsqlite3rbu_rename_handler(tls, p, uintptr(0), uintptr(0))
|
|
_rbuCreateVfs(tls, p)
|
|
/* Open the target, RBU and state databases */
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
pCsr = p + 1*416
|
|
**(**int32)(__ccgo_up(bp)) = 0
|
|
if zTarget != 0 {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).FzTarget = pCsr
|
|
libc.Xmemcpy(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FzTarget, zTarget, nTarget+uint64(1))
|
|
pCsr = pCsr + uintptr(nTarget+uint64(1))
|
|
}
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).FzRbu = pCsr
|
|
libc.Xmemcpy(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FzRbu, zRbu, nRbu+uint64(1))
|
|
pCsr = pCsr + uintptr(nRbu+uint64(1))
|
|
if zState != 0 {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).FzState = _rbuMPrintf(tls, p, __ccgo_ts+3968, libc.VaList(bp+16, zState))
|
|
}
|
|
/* If the first attempt to open the database file fails and the bRetry
|
|
** flag it set, this means that the db was not opened because it seemed
|
|
** to be a wal-mode db. But, this may have happened due to an earlier
|
|
** RBU vacuum operation leaving an old wal file in the directory.
|
|
** If this is the case, it will have been checkpointed and deleted
|
|
** when the handle was closed and a second attempt to open the
|
|
** database may succeed. */
|
|
_rbuOpenDatabase(tls, p, uintptr(0), bp)
|
|
if **(**int32)(__ccgo_up(bp)) != 0 {
|
|
_rbuOpenDatabase(tls, p, uintptr(0), uintptr(0))
|
|
}
|
|
}
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
pState = _rbuLoadState(tls, p)
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
if (*TRbuState)(unsafe.Pointer(pState)).FeStage == 0 {
|
|
_rbuDeleteOalFile(tls, p)
|
|
_rbuInitPhaseOneSteps(tls, p)
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).FeStage = int32(RBU_STAGE_OAL)
|
|
} else {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).FeStage = (*TRbuState)(unsafe.Pointer(pState)).FeStage
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).FnPhaseOneStep = (*TRbuState)(unsafe.Pointer(pState)).FnPhaseOneStep
|
|
}
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).FnProgress = (*TRbuState)(unsafe.Pointer(pState)).FnProgress
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).FiOalSz = (*TRbuState)(unsafe.Pointer(pState)).FiOalSz
|
|
}
|
|
}
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK && (*Trbu_file)(unsafe.Pointer((*Tsqlite3rbu)(unsafe.Pointer(p)).FpTargetFd)).FpWalFd != 0 {
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).FeStage == int32(RBU_STAGE_OAL) {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = int32(SQLITE_ERROR)
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).FzErrmsg = Xsqlite3_mprintf(tls, __ccgo_ts+34582, 0)
|
|
} else {
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).FeStage == int32(RBU_STAGE_MOVE) {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).FeStage = int32(RBU_STAGE_CKPT)
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).FnStep = 0
|
|
}
|
|
}
|
|
}
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK && ((*Tsqlite3rbu)(unsafe.Pointer(p)).FeStage == int32(RBU_STAGE_OAL) || (*Tsqlite3rbu)(unsafe.Pointer(p)).FeStage == int32(RBU_STAGE_MOVE)) && (*TRbuState)(unsafe.Pointer(pState)).FeStage != 0 {
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).FzTarget == uintptr(0) {
|
|
v2 = (*Tsqlite3rbu)(unsafe.Pointer(p)).FpRbuFd
|
|
} else {
|
|
v2 = (*Tsqlite3rbu)(unsafe.Pointer(p)).FpTargetFd
|
|
}
|
|
pFd = v2
|
|
if (*Trbu_file)(unsafe.Pointer(pFd)).FiCookie != (*TRbuState)(unsafe.Pointer(pState)).FiCookie {
|
|
/* At this point (pTargetFd->iCookie) contains the value of the
|
|
** change-counter cookie (the thing that gets incremented when a
|
|
** transaction is committed in rollback mode) currently stored on
|
|
** page 1 of the database file. */
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = int32(SQLITE_BUSY)
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).FzTarget == uintptr(0) {
|
|
v2 = __ccgo_ts + 34614
|
|
} else {
|
|
v2 = __ccgo_ts + 34621
|
|
}
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).FzErrmsg = Xsqlite3_mprintf(tls, __ccgo_ts+34628, libc.VaList(bp+16, v2))
|
|
}
|
|
}
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).FeStage == int32(RBU_STAGE_OAL) {
|
|
db = (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = Xsqlite3_exec(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbRbu, __ccgo_ts+16131, uintptr(0), uintptr(0), p+64)
|
|
/* Point the object iterator at the first object */
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = _rbuObjIterFirst(tls, p, p+88)
|
|
}
|
|
/* If the RBU database contains no data_xxx tables, declare the RBU
|
|
** update finished. */
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK && (*Tsqlite3rbu)(unsafe.Pointer(p)).Fobjiter.FzTbl == uintptr(0) {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = int32(SQLITE_DONE)
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).FeStage = int32(RBU_STAGE_DONE)
|
|
} else {
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK && (*TRbuState)(unsafe.Pointer(pState)).FeStage == 0 && (*Tsqlite3rbu)(unsafe.Pointer(p)).FzTarget == uintptr(0) {
|
|
_rbuCopyPragma(tls, p, __ccgo_ts+18678)
|
|
_rbuCopyPragma(tls, p, __ccgo_ts+18090)
|
|
}
|
|
/* Open transactions both databases. The *-oal file is opened or
|
|
** created at this point. */
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = Xsqlite3_exec(tls, db, __ccgo_ts+34660, uintptr(0), uintptr(0), p+64)
|
|
}
|
|
/* Check if the main database is a zipvfs db. If it is, set the upper
|
|
** level pager to use "journal_mode=off". This prevents it from
|
|
** generating a large journal using a temp file. */
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
frc = Xsqlite3_file_control(tls, db, __ccgo_ts+6844, int32(SQLITE_FCNTL_ZIPVFS), uintptr(0))
|
|
if frc == SQLITE_OK {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = Xsqlite3_exec(tls, db, __ccgo_ts+34676, uintptr(0), uintptr(0), p+64)
|
|
}
|
|
}
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
_rbuSetupOal(tls, p, pState)
|
|
}
|
|
}
|
|
} else {
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).FeStage == int32(RBU_STAGE_MOVE) {
|
|
/* no-op */
|
|
} else {
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).FeStage == int32(RBU_STAGE_CKPT) {
|
|
if !((*Tsqlite3rbu)(unsafe.Pointer(p)).FzTarget == libc.UintptrFromInt32(0)) && _rbuExclusiveCheckpoint(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain) != 0 {
|
|
/* If the rbu_exclusive_checkpoint=1 URI parameter was specified
|
|
** and an incremental checkpoint is being resumed, attempt an
|
|
** exclusive lock on the db file. If this fails, so be it. */
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).FeStage = int32(RBU_STAGE_DONE)
|
|
_rbuLockDatabase(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain)
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).FeStage = int32(RBU_STAGE_CKPT)
|
|
}
|
|
_rbuSetupCheckpoint(tls, p, pState)
|
|
} else {
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).FeStage == int32(RBU_STAGE_DONE) {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = int32(SQLITE_DONE)
|
|
} else {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = int32(SQLITE_CORRUPT)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
_rbuFreeState(tls, pState)
|
|
}
|
|
return p
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This routine generates code that opens the sqlite_statN tables.
|
|
// ** The sqlite_stat1 table is always relevant. sqlite_stat2 is now
|
|
// ** obsolete. sqlite_stat3 and sqlite_stat4 are only opened when
|
|
// ** appropriate compile-time options are provided.
|
|
// **
|
|
// ** If the sqlite_statN tables do not previously exist, it is created.
|
|
// **
|
|
// ** Argument zWhere may be a pointer to a buffer containing a table name,
|
|
// ** or it may be a NULL pointer. If it is not NULL, then all entries in
|
|
// ** the sqlite_statN tables associated with the named table are deleted.
|
|
// ** If zWhere==0, then code is generated to delete all stat table entries.
|
|
// */
|
|
func _openStatTable(tls *libc.TLS, pParse uintptr, iDb int32, iStatCur int32, zWhere uintptr, zWhereType uintptr) {
|
|
bp := tls.Alloc(48)
|
|
defer tls.Free(48)
|
|
var aCreateTbl [3]Tu8
|
|
var aRoot [3]Tu32
|
|
var db, pDb, pStat, v, zTab, v3 uintptr
|
|
var i, nToOpen, v1 int32
|
|
_, _, _, _, _, _, _, _, _, _, _ = aCreateTbl, aRoot, db, i, nToOpen, pDb, pStat, v, zTab, v1, v3
|
|
db = (*TParse)(unsafe.Pointer(pParse)).Fdb
|
|
v = _sqlite3GetVdbe(tls, pParse)
|
|
if (*Tsqlite3)(unsafe.Pointer(db)).FdbOptFlags&libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_Stat4)) == uint32(0) {
|
|
v1 = int32(2)
|
|
} else {
|
|
v1 = int32(1)
|
|
}
|
|
nToOpen = v1
|
|
if v == uintptr(0) {
|
|
return
|
|
}
|
|
pDb = (*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(iDb)*32
|
|
/* Create new statistic tables if they do not exist, or clear them
|
|
** if they do already exist.
|
|
*/
|
|
i = 0
|
|
for {
|
|
if !(i < libc.Int32FromUint64(libc.Uint64FromInt64(48)/libc.Uint64FromInt64(16))) {
|
|
break
|
|
}
|
|
zTab = _aTable[i].FzName
|
|
aCreateTbl[i] = uint8(0)
|
|
v3 = _sqlite3FindTable(tls, db, zTab, (*TDb)(unsafe.Pointer(pDb)).FzDbSName)
|
|
pStat = v3
|
|
if v3 == uintptr(0) {
|
|
if i < nToOpen {
|
|
/* The sqlite_statN table does not exist. Create it. Note that a
|
|
** side-effect of the CREATE TABLE statement is to leave the rootpage
|
|
** of the new table in register pParse->regRoot. This is important
|
|
** because the OpenWrite opcode below will be needing it. */
|
|
_sqlite3NestedParse(tls, pParse, __ccgo_ts+12941, libc.VaList(bp+8, (*TDb)(unsafe.Pointer(pDb)).FzDbSName, zTab, _aTable[i].FzCols))
|
|
aRoot[i] = libc.Uint32FromInt32((*(*struct {
|
|
FaddrCrTab int32
|
|
FregRowid int32
|
|
FregRoot int32
|
|
FconstraintName TToken
|
|
})(unsafe.Pointer(pParse + 256))).FregRoot)
|
|
aCreateTbl[i] = uint8(OPFLAG_P2ISREG)
|
|
}
|
|
} else {
|
|
/* The table already exists. If zWhere is not NULL, delete all entries
|
|
** associated with the table zWhere. If zWhere is NULL, delete the
|
|
** entire contents of the table. */
|
|
aRoot[i] = (*TTable)(unsafe.Pointer(pStat)).Ftnum
|
|
_sqlite3TableLock(tls, pParse, iDb, aRoot[i], uint8(1), zTab)
|
|
if zWhere != 0 {
|
|
_sqlite3NestedParse(tls, pParse, __ccgo_ts+12964, libc.VaList(bp+8, (*TDb)(unsafe.Pointer(pDb)).FzDbSName, zTab, zWhereType, zWhere))
|
|
} else {
|
|
if (*Tsqlite3)(unsafe.Pointer(db)).FxPreUpdateCallback != 0 {
|
|
_sqlite3NestedParse(tls, pParse, __ccgo_ts+12994, libc.VaList(bp+8, (*TDb)(unsafe.Pointer(pDb)).FzDbSName, zTab))
|
|
} else {
|
|
/* The sqlite_stat[134] table already exists. Delete all rows. */
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_Clear), libc.Int32FromUint32(aRoot[i]), iDb)
|
|
}
|
|
}
|
|
}
|
|
goto _2
|
|
_2:
|
|
;
|
|
i = i + 1
|
|
}
|
|
/* Open the sqlite_stat[134] tables for writing. */
|
|
i = 0
|
|
for {
|
|
if !(i < nToOpen) {
|
|
break
|
|
}
|
|
_sqlite3VdbeAddOp4Int(tls, v, int32(OP_OpenWrite), iStatCur+i, libc.Int32FromUint32(aRoot[i]), iDb, int32(3))
|
|
_sqlite3VdbeChangeP5(tls, v, uint16(aCreateTbl[i]))
|
|
goto _4
|
|
_4:
|
|
;
|
|
i = i + 1
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Playback the journal and thus restore the database file to
|
|
// ** the state it was in before we started making changes.
|
|
// **
|
|
// ** The journal file format is as follows:
|
|
// **
|
|
// ** (1) 8 byte prefix. A copy of aJournalMagic[].
|
|
// ** (2) 4 byte big-endian integer which is the number of valid page records
|
|
// ** in the journal. If this value is 0xffffffff, then compute the
|
|
// ** number of page records from the journal size.
|
|
// ** (3) 4 byte big-endian integer which is the initial value for the
|
|
// ** sanity checksum.
|
|
// ** (4) 4 byte integer which is the number of pages to truncate the
|
|
// ** database to during a rollback.
|
|
// ** (5) 4 byte big-endian integer which is the sector size. The header
|
|
// ** is this many bytes in size.
|
|
// ** (6) 4 byte big-endian integer which is the page size.
|
|
// ** (7) zero padding out to the next sector size.
|
|
// ** (8) Zero or more pages instances, each as follows:
|
|
// ** + 4 byte page number.
|
|
// ** + pPager->pageSize bytes of data.
|
|
// ** + 4 byte checksum
|
|
// **
|
|
// ** When we speak of the journal header, we mean the first 7 items above.
|
|
// ** Each entry in the journal is an instance of the 8th item.
|
|
// **
|
|
// ** Call the value from the second bullet "nRec". nRec is the number of
|
|
// ** valid page entries in the journal. In most cases, you can compute the
|
|
// ** value of nRec from the size of the journal file. But if a power
|
|
// ** failure occurred while the journal was being written, it could be the
|
|
// ** case that the size of the journal file had already been increased but
|
|
// ** the extra entries had not yet made it safely to disk. In such a case,
|
|
// ** the value of nRec computed from the file size would be too large. For
|
|
// ** that reason, we always use the nRec value in the header.
|
|
// **
|
|
// ** If the nRec value is 0xffffffff it means that nRec should be computed
|
|
// ** from the file size. This value is used when the user selects the
|
|
// ** no-sync option for the journal. A power failure could lead to corruption
|
|
// ** in this case. But for things like temporary table (which will be
|
|
// ** deleted when the power is restored) we don't care.
|
|
// **
|
|
// ** If the file opened as the journal file is not a well-formed
|
|
// ** journal file then all pages up to the first corrupted page are rolled
|
|
// ** back (or no pages if the journal header is corrupted). The journal file
|
|
// ** is then deleted and SQLITE_OK returned, just as if no corruption had
|
|
// ** been encountered.
|
|
// **
|
|
// ** If an I/O or malloc() error occurs, the journal-file is not deleted
|
|
// ** and an error code is returned.
|
|
// **
|
|
// ** The isHot parameter indicates that we are trying to rollback a journal
|
|
// ** that might be a hot journal. Or, it could be that the journal is
|
|
// ** preserved because of JOURNALMODE_PERSIST or JOURNALMODE_TRUNCATE.
|
|
// ** If the journal really is hot, reset the pager cache prior rolling
|
|
// ** back any content. If the journal is merely persistent, no reset is
|
|
// ** needed.
|
|
// */
|
|
func _pager_playback(tls *libc.TLS, pPager uintptr, isHot int32) (r int32) {
|
|
bp := tls.Alloc(64)
|
|
defer tls.Free(64)
|
|
var nPlayback, needPagerReset, rc int32
|
|
var pVfs uintptr
|
|
var u Tu32
|
|
var _ /* mxPg at bp+12 */ TPgno
|
|
var _ /* nRec at bp+8 */ Tu32
|
|
var _ /* res at bp+16 */ int32
|
|
var _ /* savedPageSize at bp+32 */ Tu32
|
|
var _ /* szJ at bp+0 */ Ti64
|
|
var _ /* zSuper at bp+24 */ uintptr
|
|
_, _, _, _, _ = nPlayback, needPagerReset, pVfs, rc, u
|
|
pVfs = (*TPager)(unsafe.Pointer(pPager)).FpVfs /* Unsigned loop counter */
|
|
**(**TPgno)(__ccgo_up(bp + 12)) = uint32(0) /* Result code of a subroutine */
|
|
**(**int32)(__ccgo_up(bp + 16)) = int32(1) /* Value returned by sqlite3OsAccess() */
|
|
**(**uintptr)(__ccgo_up(bp + 24)) = uintptr(0) /* True to reset page prior to first page rollback */
|
|
nPlayback = 0 /* Total number of pages restored from journal */
|
|
**(**Tu32)(__ccgo_up(bp + 32)) = libc.Uint32FromInt64((*TPager)(unsafe.Pointer(pPager)).FpageSize)
|
|
/* Figure out how many records are in the journal. Abort early if
|
|
** the journal is empty.
|
|
*/
|
|
rc = _sqlite3OsFileSize(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd, bp)
|
|
if rc != SQLITE_OK {
|
|
goto end_playback
|
|
}
|
|
/* Read the super-journal name from the journal, if it is present.
|
|
** If a super-journal file name is specified, but the file is not
|
|
** present on disk, then the journal is not hot and does not need to be
|
|
** played back.
|
|
*/
|
|
rc = _readSuperJournal(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd, libc.Uint64FromInt64(int64(1)+int64((*Tsqlite3_vfs)(unsafe.Pointer((*TPager)(unsafe.Pointer(pPager)).FpVfs)).FmxPathname)), bp+24)
|
|
if rc == SQLITE_OK && **(**uintptr)(__ccgo_up(bp + 24)) != 0 {
|
|
rc = _sqlite3OsAccess(tls, pVfs, **(**uintptr)(__ccgo_up(bp + 24)), SQLITE_ACCESS_EXISTS, bp+16)
|
|
}
|
|
if rc != SQLITE_OK || !(**(**int32)(__ccgo_up(bp + 16)) != 0) {
|
|
goto end_playback
|
|
}
|
|
(*TPager)(unsafe.Pointer(pPager)).FjournalOff = 0
|
|
needPagerReset = isHot
|
|
/* This loop terminates either when a readJournalHdr() or
|
|
** pager_playback_one_page() call returns SQLITE_DONE or an IO error
|
|
** occurs.
|
|
*/
|
|
for int32(1) != 0 {
|
|
/* Read the next journal header from the journal file. If there are
|
|
** not enough bytes left in the journal file for a complete header, or
|
|
** it is corrupted, then a process must have failed while writing it.
|
|
** This indicates nothing more needs to be rolled back.
|
|
*/
|
|
rc = _readJournalHdr(tls, pPager, isHot, **(**Ti64)(__ccgo_up(bp)), bp+8, bp+12)
|
|
if rc != SQLITE_OK {
|
|
if rc == int32(SQLITE_DONE) {
|
|
rc = SQLITE_OK
|
|
}
|
|
goto end_playback
|
|
}
|
|
/* If nRec is 0xffffffff, then this journal was created by a process
|
|
** working in no-sync mode. This means that the rest of the journal
|
|
** file consists of pages, there are no more journal headers. Compute
|
|
** the value of nRec based on this assumption.
|
|
*/
|
|
if **(**Tu32)(__ccgo_up(bp + 8)) == uint32(0xffffffff) {
|
|
**(**Tu32)(__ccgo_up(bp + 8)) = libc.Uint32FromInt32(int32((**(**Ti64)(__ccgo_up(bp)) - libc.Int64FromUint32((*TPager)(unsafe.Pointer(pPager)).FsectorSize)) / ((*TPager)(unsafe.Pointer(pPager)).FpageSize + libc.Int64FromInt32(8))))
|
|
}
|
|
/* If nRec is 0 and this rollback is of a transaction created by this
|
|
** process and if this is the final header in the journal, then it means
|
|
** that this part of the journal was being filled but has not yet been
|
|
** synced to disk. Compute the number of pages based on the remaining
|
|
** size of the file.
|
|
**
|
|
** The third term of the test was added to fix ticket #2565.
|
|
** When rolling back a hot journal, nRec==0 always means that the next
|
|
** chunk of the journal contains zero pages to be rolled back. But
|
|
** when doing a ROLLBACK and the nRec==0 chunk is the last chunk in
|
|
** the journal, it means that the journal might contain additional
|
|
** pages that need to be rolled back and that the number of pages
|
|
** should be computed based on the journal file size.
|
|
*/
|
|
if **(**Tu32)(__ccgo_up(bp + 8)) == uint32(0) && !(isHot != 0) && (*TPager)(unsafe.Pointer(pPager)).FjournalHdr+libc.Int64FromUint32((*TPager)(unsafe.Pointer(pPager)).FsectorSize) == (*TPager)(unsafe.Pointer(pPager)).FjournalOff {
|
|
**(**Tu32)(__ccgo_up(bp + 8)) = libc.Uint32FromInt32(int32((**(**Ti64)(__ccgo_up(bp)) - (*TPager)(unsafe.Pointer(pPager)).FjournalOff) / ((*TPager)(unsafe.Pointer(pPager)).FpageSize + libc.Int64FromInt32(8))))
|
|
}
|
|
/* If this is the first header read from the journal, truncate the
|
|
** database file back to its original size.
|
|
*/
|
|
if (*TPager)(unsafe.Pointer(pPager)).FjournalOff == libc.Int64FromUint32((*TPager)(unsafe.Pointer(pPager)).FsectorSize) {
|
|
rc = _pager_truncate(tls, pPager, **(**TPgno)(__ccgo_up(bp + 12)))
|
|
if rc != SQLITE_OK {
|
|
goto end_playback
|
|
}
|
|
(*TPager)(unsafe.Pointer(pPager)).FdbSize = **(**TPgno)(__ccgo_up(bp + 12))
|
|
if (*TPager)(unsafe.Pointer(pPager)).FmxPgno < **(**TPgno)(__ccgo_up(bp + 12)) {
|
|
(*TPager)(unsafe.Pointer(pPager)).FmxPgno = **(**TPgno)(__ccgo_up(bp + 12))
|
|
}
|
|
}
|
|
/* Copy original pages out of the journal and back into the
|
|
** database file and/or page cache.
|
|
*/
|
|
u = uint32(0)
|
|
for {
|
|
if !(u < **(**Tu32)(__ccgo_up(bp + 8))) {
|
|
break
|
|
}
|
|
if needPagerReset != 0 {
|
|
_pager_reset(tls, pPager)
|
|
needPagerReset = 0
|
|
}
|
|
rc = _pager_playback_one_page(tls, pPager, pPager+96, uintptr(0), int32(1), 0)
|
|
if rc == SQLITE_OK {
|
|
nPlayback = nPlayback + 1
|
|
} else {
|
|
if rc == int32(SQLITE_DONE) {
|
|
(*TPager)(unsafe.Pointer(pPager)).FjournalOff = **(**Ti64)(__ccgo_up(bp))
|
|
break
|
|
} else {
|
|
if rc == libc.Int32FromInt32(SQLITE_IOERR)|libc.Int32FromInt32(2)<<libc.Int32FromInt32(8) {
|
|
/* If the journal has been truncated, simply stop reading and
|
|
** processing the journal. This might happen if the journal was
|
|
** not completely written and synced prior to a crash. In that
|
|
** case, the database should have never been written in the
|
|
** first place so it is OK to simply abandon the rollback. */
|
|
rc = SQLITE_OK
|
|
goto end_playback
|
|
} else {
|
|
/* If we are unable to rollback, quit and return the error
|
|
** code. This will cause the pager to enter the error state
|
|
** so that no further harm will be done. Perhaps the next
|
|
** process to come along will be able to rollback the database.
|
|
*/
|
|
goto end_playback
|
|
}
|
|
}
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
u = u + 1
|
|
}
|
|
}
|
|
/*NOTREACHED*/
|
|
goto end_playback
|
|
end_playback:
|
|
;
|
|
if rc == SQLITE_OK {
|
|
rc = _sqlite3PagerSetPagesize(tls, pPager, bp+32, -int32(1))
|
|
}
|
|
/* Following a rollback, the database file should be back in its original
|
|
** state prior to the start of the transaction, so invoke the
|
|
** SQLITE_FCNTL_DB_UNCHANGED file-control method to disable the
|
|
** assertion that the transaction counter was modified.
|
|
*/
|
|
/* If this playback is happening automatically as a result of an IO or
|
|
** malloc error that occurred after the change-counter was updated but
|
|
** before the transaction was committed, then the change-counter
|
|
** modification may just have been reverted. If this happens in exclusive
|
|
** mode, then subsequent transactions performed by the connection will not
|
|
** update the change-counter at all. This may lead to cache inconsistency
|
|
** problems for other processes at some point in the future. So, just
|
|
** in case this has happened, clear the changeCountDone flag now.
|
|
*/
|
|
(*TPager)(unsafe.Pointer(pPager)).FchangeCountDone = (*TPager)(unsafe.Pointer(pPager)).FtempFile
|
|
if rc == SQLITE_OK && (libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FeState) >= int32(PAGER_WRITER_DBMOD) || libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FeState) == PAGER_OPEN) {
|
|
rc = _sqlite3PagerSync(tls, pPager, uintptr(0))
|
|
}
|
|
if rc == SQLITE_OK {
|
|
rc = _pager_end_transaction(tls, pPager, libc.BoolInt32(**(**uintptr)(__ccgo_up(bp + 24)) != uintptr(0)), 0)
|
|
}
|
|
if rc == SQLITE_OK && **(**uintptr)(__ccgo_up(bp + 24)) != 0 && **(**int32)(__ccgo_up(bp + 16)) != 0 {
|
|
/* If there was a super-journal and this routine will return success,
|
|
** see if it is possible to delete the super-journal.
|
|
*/
|
|
rc = _pager_delsuper(tls, pPager, **(**uintptr)(__ccgo_up(bp + 24)))
|
|
}
|
|
if isHot != 0 && nPlayback != 0 {
|
|
Xsqlite3_log(tls, libc.Int32FromInt32(SQLITE_NOTICE)|libc.Int32FromInt32(2)<<libc.Int32FromInt32(8), __ccgo_ts+4228, libc.VaList(bp+48, nPlayback, (*TPager)(unsafe.Pointer(pPager)).FzJournal))
|
|
}
|
|
/* The Pager.sectorSize variable may have been updated while rolling
|
|
** back a journal created by a process with a different sector size
|
|
** value. Reset it to the correct value for this process.
|
|
*/
|
|
_freeSuperJournal(tls, **(**uintptr)(__ccgo_up(bp + 24)))
|
|
_setSectorSize(tls, pPager)
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** For a compound SELECT statement, make sure p->pPrior->pNext==p for
|
|
// ** all elements in the list. And make sure list length does not exceed
|
|
// ** SQLITE_LIMIT_COMPOUND_SELECT.
|
|
// */
|
|
func _parserDoubleLinkSelect(tls *libc.TLS, pParse uintptr, p uintptr) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var cnt, mxSelect, v2 int32
|
|
var pLoop, pNext, v1 uintptr
|
|
var v3 bool
|
|
_, _, _, _, _, _, _ = cnt, mxSelect, pLoop, pNext, v1, v2, v3
|
|
if (*TSelect)(unsafe.Pointer(p)).FpPrior != 0 {
|
|
pNext = uintptr(0)
|
|
pLoop = p
|
|
cnt = int32(1)
|
|
for int32(1) != 0 {
|
|
(*TSelect)(unsafe.Pointer(pLoop)).FpNext = pNext
|
|
**(**Tu32)(__ccgo_up(pLoop + 4)) |= uint32(SF_Compound)
|
|
pNext = pLoop
|
|
pLoop = (*TSelect)(unsafe.Pointer(pLoop)).FpPrior
|
|
if pLoop == uintptr(0) {
|
|
break
|
|
}
|
|
cnt = cnt + 1
|
|
if (*TSelect)(unsafe.Pointer(pLoop)).FpOrderBy != 0 || (*TSelect)(unsafe.Pointer(pLoop)).FpLimit != 0 {
|
|
if (*TSelect)(unsafe.Pointer(pLoop)).FpOrderBy != uintptr(0) {
|
|
v1 = __ccgo_ts + 24878
|
|
} else {
|
|
v1 = __ccgo_ts + 24887
|
|
}
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+24893, libc.VaList(bp+8, v1, _sqlite3SelectOpName(tls, libc.Int32FromUint8((*TSelect)(unsafe.Pointer(pNext)).Fop))))
|
|
break
|
|
}
|
|
}
|
|
if v3 = (*TSelect)(unsafe.Pointer(p)).FselFlags&libc.Uint32FromInt32(libc.Int32FromInt32(SF_MultiValue)|libc.Int32FromInt32(SF_Values)) == uint32(0); v3 {
|
|
v2 = **(**int32)(__ccgo_up((*TParse)(unsafe.Pointer(pParse)).Fdb + 136 + 4*4))
|
|
mxSelect = v2
|
|
}
|
|
if v3 && v2 > 0 && cnt > mxSelect {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+24935, 0)
|
|
}
|
|
}
|
|
}
|
|
|
|
// 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.
|
|
// **
|
|
// ** If handleNFSUnlock is true, then on downgrading an EXCLUSIVE_LOCK to SHARED
|
|
// ** the byte range is divided into 2 parts and the first part is unlocked then
|
|
// ** set to a read lock, then the other part is simply unlocked. This works
|
|
// ** around a bug in BSD NFS lockd (also seen on MacOSX 10.3+) that fails to
|
|
// ** remove the write lock on a region when a read lock is set.
|
|
// */
|
|
func _posixUnlock(tls *libc.TLS, id uintptr, eFileLock int32, handleNFSUnlock int32) (r int32) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var pFile, pInode uintptr
|
|
var rc int32
|
|
var v1 Toff_t
|
|
var _ /* lock at bp+0 */ Tflock
|
|
_, _, _, _ = pFile, pInode, rc, v1
|
|
pFile = id
|
|
rc = SQLITE_OK
|
|
if libc.Int32FromUint8((*TunixFile)(unsafe.Pointer(pFile)).FeFileLock) <= eFileLock {
|
|
return SQLITE_OK
|
|
}
|
|
pInode = (*TunixFile)(unsafe.Pointer(pFile)).FpInode
|
|
Xsqlite3_mutex_enter(tls, (*TunixInodeInfo)(unsafe.Pointer(pInode)).FpLockMutex)
|
|
if libc.Int32FromUint8((*TunixFile)(unsafe.Pointer(pFile)).FeFileLock) > int32(SHARED_LOCK) {
|
|
/* downgrading to a shared lock on NFS involves clearing the write lock
|
|
** before establishing the readlock - to avoid a race condition we downgrade
|
|
** the lock in 2 blocks, so that part of the range will be covered by a
|
|
** write lock until the rest is covered by a read lock:
|
|
** 1: [WWWWW]
|
|
** 2: [....W]
|
|
** 3: [RRRRW]
|
|
** 4: [RRRR.]
|
|
*/
|
|
if eFileLock == int32(SHARED_LOCK) {
|
|
_ = handleNFSUnlock
|
|
(**(**Tflock)(__ccgo_up(bp))).Fl_type = F_RDLCK
|
|
(**(**Tflock)(__ccgo_up(bp))).Fl_whence = 0
|
|
(**(**Tflock)(__ccgo_up(bp))).Fl_start = int64(_sqlite3PendingByte + libc.Int32FromInt32(2))
|
|
(**(**Tflock)(__ccgo_up(bp))).Fl_len = int64(SHARED_SIZE)
|
|
if _unixFileLock(tls, pFile, bp) != 0 {
|
|
/* In theory, the call to unixFileLock() cannot fail because another
|
|
** process is holding an incompatible lock. If it does, this
|
|
** indicates that the other process is not following the locking
|
|
** protocol. If this happens, return SQLITE_IOERR_RDLOCK. Returning
|
|
** SQLITE_BUSY would confuse the upper layer (in practice it causes
|
|
** an assert to fail). */
|
|
rc = libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(9)<<libc.Int32FromInt32(8)
|
|
_storeLastErrno(tls, pFile, **(**int32)(__ccgo_up(libc.X__errno_location(tls))))
|
|
goto end_unlock
|
|
}
|
|
}
|
|
(**(**Tflock)(__ccgo_up(bp))).Fl_type = int16(F_UNLCK)
|
|
(**(**Tflock)(__ccgo_up(bp))).Fl_whence = 0
|
|
(**(**Tflock)(__ccgo_up(bp))).Fl_start = int64(_sqlite3PendingByte)
|
|
(**(**Tflock)(__ccgo_up(bp))).Fl_len = int64(2)
|
|
if _unixFileLock(tls, pFile, bp) == 0 {
|
|
(*TunixInodeInfo)(unsafe.Pointer(pInode)).FeFileLock = uint8(SHARED_LOCK)
|
|
} else {
|
|
rc = libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(8)<<libc.Int32FromInt32(8)
|
|
_storeLastErrno(tls, pFile, **(**int32)(__ccgo_up(libc.X__errno_location(tls))))
|
|
goto end_unlock
|
|
}
|
|
}
|
|
if eFileLock == NO_LOCK {
|
|
/* Decrement the shared lock counter. Release the lock using an
|
|
** OS call only when all threads in this same process have released
|
|
** the lock.
|
|
*/
|
|
(*TunixInodeInfo)(unsafe.Pointer(pInode)).FnShared = (*TunixInodeInfo)(unsafe.Pointer(pInode)).FnShared - 1
|
|
if (*TunixInodeInfo)(unsafe.Pointer(pInode)).FnShared == 0 {
|
|
(**(**Tflock)(__ccgo_up(bp))).Fl_type = int16(F_UNLCK)
|
|
(**(**Tflock)(__ccgo_up(bp))).Fl_whence = 0
|
|
v1 = libc.Int64FromInt64(0)
|
|
(**(**Tflock)(__ccgo_up(bp))).Fl_len = v1
|
|
(**(**Tflock)(__ccgo_up(bp))).Fl_start = v1
|
|
if _unixFileLock(tls, pFile, bp) == 0 {
|
|
(*TunixInodeInfo)(unsafe.Pointer(pInode)).FeFileLock = uint8(NO_LOCK)
|
|
} else {
|
|
rc = libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(8)<<libc.Int32FromInt32(8)
|
|
_storeLastErrno(tls, pFile, **(**int32)(__ccgo_up(libc.X__errno_location(tls))))
|
|
(*TunixInodeInfo)(unsafe.Pointer(pInode)).FeFileLock = uint8(NO_LOCK)
|
|
(*TunixFile)(unsafe.Pointer(pFile)).FeFileLock = uint8(NO_LOCK)
|
|
}
|
|
}
|
|
/* Decrement the count of locks against this same file. When the
|
|
** count reaches zero, close any other file descriptors whose close
|
|
** was deferred because of outstanding locks.
|
|
*/
|
|
(*TunixInodeInfo)(unsafe.Pointer(pInode)).FnLock = (*TunixInodeInfo)(unsafe.Pointer(pInode)).FnLock - 1
|
|
if (*TunixInodeInfo)(unsafe.Pointer(pInode)).FnLock == 0 {
|
|
(*TunixInodeInfo)(unsafe.Pointer(pInode)).FhLock = 0
|
|
(*TunixInodeInfo)(unsafe.Pointer(pInode)).FbLockIsReadOnly = uint8(0)
|
|
_closePendingFds(tls, pFile)
|
|
}
|
|
}
|
|
goto end_unlock
|
|
end_unlock:
|
|
;
|
|
Xsqlite3_mutex_leave(tls, (*TunixInodeInfo)(unsafe.Pointer(pInode)).FpLockMutex)
|
|
if rc == SQLITE_OK {
|
|
(*TunixFile)(unsafe.Pointer(pFile)).FeFileLock = libc.Uint8FromInt32(eFileLock)
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Pragma virtual table module xFilter method.
|
|
// */
|
|
func _pragmaVtabFilter(tls *libc.TLS, pVtabCursor uintptr, idxNum int32, idxStr uintptr, argc int32, argv uintptr) (r int32) {
|
|
bp := tls.Alloc(48)
|
|
defer tls.Free(48)
|
|
var i, j, rc, v1 int32
|
|
var pCsr, pTab, zSql, zText uintptr
|
|
var _ /* acc at bp+0 */ TStrAccum
|
|
_, _, _, _, _, _, _, _ = i, j, pCsr, pTab, rc, zSql, zText, v1
|
|
pCsr = pVtabCursor
|
|
pTab = (*Tsqlite3_vtab_cursor)(unsafe.Pointer(pVtabCursor)).FpVtab
|
|
_ = idxNum
|
|
_ = idxStr
|
|
_pragmaVtabCursorClear(tls, pCsr)
|
|
if libc.Int32FromUint8((*TPragmaName)(unsafe.Pointer((*TPragmaVtab)(unsafe.Pointer(pTab)).FpName)).FmPragFlg)&int32(PragFlg_Result1) != 0 {
|
|
v1 = 0
|
|
} else {
|
|
v1 = int32(1)
|
|
}
|
|
j = v1
|
|
i = 0
|
|
for {
|
|
if !(i < argc) {
|
|
break
|
|
}
|
|
zText = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv + uintptr(i)*8)))
|
|
if zText != 0 {
|
|
**(**uintptr)(__ccgo_up(pCsr + 24 + uintptr(j)*8)) = Xsqlite3_mprintf(tls, __ccgo_ts+3968, libc.VaList(bp+40, zText))
|
|
if **(**uintptr)(__ccgo_up(pCsr + 24 + uintptr(j)*8)) == uintptr(0) {
|
|
return int32(SQLITE_NOMEM)
|
|
}
|
|
}
|
|
goto _2
|
|
_2:
|
|
;
|
|
i = i + 1
|
|
j = j + 1
|
|
}
|
|
_sqlite3StrAccumInit(tls, bp, uintptr(0), uintptr(0), 0, **(**int32)(__ccgo_up((*TPragmaVtab)(unsafe.Pointer(pTab)).Fdb + 136 + 1*4)))
|
|
Xsqlite3_str_appendall(tls, bp, __ccgo_ts+19989)
|
|
if **(**uintptr)(__ccgo_up(pCsr + 24 + 1*8)) != 0 {
|
|
Xsqlite3_str_appendf(tls, bp, __ccgo_ts+19997, libc.VaList(bp+40, **(**uintptr)(__ccgo_up(pCsr + 24 + 1*8))))
|
|
}
|
|
Xsqlite3_str_appendall(tls, bp, (*TPragmaName)(unsafe.Pointer((*TPragmaVtab)(unsafe.Pointer(pTab)).FpName)).FzName)
|
|
if **(**uintptr)(__ccgo_up(pCsr + 24)) != 0 {
|
|
Xsqlite3_str_appendf(tls, bp, __ccgo_ts+20001, libc.VaList(bp+40, **(**uintptr)(__ccgo_up(pCsr + 24))))
|
|
}
|
|
zSql = _sqlite3StrAccumFinish(tls, bp)
|
|
if zSql == uintptr(0) {
|
|
return int32(SQLITE_NOMEM)
|
|
}
|
|
rc = Xsqlite3_prepare_v2(tls, (*TPragmaVtab)(unsafe.Pointer(pTab)).Fdb, zSql, -int32(1), pCsr+8, uintptr(0))
|
|
Xsqlite3_free(tls, zSql)
|
|
if rc != SQLITE_OK {
|
|
(*TPragmaVtab)(unsafe.Pointer(pTab)).Fbase.FzErrMsg = Xsqlite3_mprintf(tls, __ccgo_ts+3968, libc.VaList(bp+40, Xsqlite3_errmsg(tls, (*TPragmaVtab)(unsafe.Pointer(pTab)).Fdb)))
|
|
return rc
|
|
}
|
|
return _pragmaVtabNext(tls, pVtabCursor)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** The sqlite3_mutex_alloc() routine allocates a new
|
|
// ** mutex and returns a pointer to it. If it returns NULL
|
|
// ** that means that a mutex could not be allocated. SQLite
|
|
// ** will unwind its stack and return an error. The argument
|
|
// ** to sqlite3_mutex_alloc() is one of these integer constants:
|
|
// **
|
|
// ** <ul>
|
|
// ** <li> SQLITE_MUTEX_FAST
|
|
// ** <li> SQLITE_MUTEX_RECURSIVE
|
|
// ** <li> SQLITE_MUTEX_STATIC_MAIN
|
|
// ** <li> SQLITE_MUTEX_STATIC_MEM
|
|
// ** <li> SQLITE_MUTEX_STATIC_OPEN
|
|
// ** <li> SQLITE_MUTEX_STATIC_PRNG
|
|
// ** <li> SQLITE_MUTEX_STATIC_LRU
|
|
// ** <li> SQLITE_MUTEX_STATIC_PMEM
|
|
// ** <li> SQLITE_MUTEX_STATIC_APP1
|
|
// ** <li> SQLITE_MUTEX_STATIC_APP2
|
|
// ** <li> SQLITE_MUTEX_STATIC_APP3
|
|
// ** <li> SQLITE_MUTEX_STATIC_VFS1
|
|
// ** <li> SQLITE_MUTEX_STATIC_VFS2
|
|
// ** <li> SQLITE_MUTEX_STATIC_VFS3
|
|
// ** </ul>
|
|
// **
|
|
// ** The first two constants cause sqlite3_mutex_alloc() to create
|
|
// ** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
|
|
// ** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
|
|
// ** The mutex implementation does not need to make a distinction
|
|
// ** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
|
|
// ** not want to. But SQLite will only request a recursive mutex in
|
|
// ** cases where it really needs one. If a faster non-recursive mutex
|
|
// ** implementation is available on the host platform, the mutex subsystem
|
|
// ** might return such a mutex in response to SQLITE_MUTEX_FAST.
|
|
// **
|
|
// ** The other allowed parameters to sqlite3_mutex_alloc() each return
|
|
// ** a pointer to a static preexisting mutex. Six static mutexes are
|
|
// ** used by the current version of SQLite. Future versions of SQLite
|
|
// ** may add additional static mutexes. Static mutexes are for internal
|
|
// ** use by SQLite only. Applications that use SQLite mutexes should
|
|
// ** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
|
|
// ** SQLITE_MUTEX_RECURSIVE.
|
|
// **
|
|
// ** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
|
|
// ** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
|
|
// ** returns a different mutex on every call. But for the static
|
|
// ** mutex types, the same mutex is returned on every call that has
|
|
// ** the same type number.
|
|
// */
|
|
func _pthreadMutexAlloc(tls *libc.TLS, iType int32) (r uintptr) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var p uintptr
|
|
var _ /* recursiveAttr at bp+0 */ Tpthread_mutexattr_t
|
|
_ = p
|
|
switch iType {
|
|
case int32(SQLITE_MUTEX_RECURSIVE):
|
|
p = _sqlite3MallocZero(tls, uint64(40))
|
|
if p != 0 {
|
|
libc.Xpthread_mutexattr_init(tls, bp)
|
|
libc.Xpthread_mutexattr_settype(tls, bp, int32(PTHREAD_MUTEX_RECURSIVE))
|
|
libc.Xpthread_mutex_init(tls, p, bp)
|
|
libc.Xpthread_mutexattr_destroy(tls, bp)
|
|
}
|
|
case SQLITE_MUTEX_FAST:
|
|
p = _sqlite3MallocZero(tls, uint64(40))
|
|
if p != 0 {
|
|
libc.Xpthread_mutex_init(tls, p, uintptr(0))
|
|
}
|
|
default:
|
|
p = uintptr(unsafe.Pointer(&_staticMutexes)) + uintptr(iType-int32(2))*40
|
|
break
|
|
}
|
|
return p
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** The second argument passed to this function is the name of a PRAGMA
|
|
// ** setting - "page_size", "auto_vacuum", "user_version" or "application_id".
|
|
// ** This function executes the following on sqlite3rbu.dbRbu:
|
|
// **
|
|
// ** "PRAGMA main.$zPragma"
|
|
// **
|
|
// ** where $zPragma is the string passed as the second argument, then
|
|
// ** on sqlite3rbu.dbMain:
|
|
// **
|
|
// ** "PRAGMA main.$zPragma = $val"
|
|
// **
|
|
// ** where $val is the value returned by the first PRAGMA invocation.
|
|
// **
|
|
// ** In short, it copies the value of the specified PRAGMA setting from
|
|
// ** dbRbu to dbMain.
|
|
// */
|
|
func _rbuCopyPragma(tls *libc.TLS, p uintptr, zPragma uintptr) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var _ /* pPragma at bp+0 */ uintptr
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = _prepareFreeAndCollectError(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbRbu, bp, p+64, Xsqlite3_mprintf(tls, __ccgo_ts+33999, libc.VaList(bp+16, zPragma)))
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK && int32(SQLITE_ROW) == Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp))) {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = _rbuMPrintfExec(tls, p, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, __ccgo_ts+34014, libc.VaList(bp+16, zPragma, Xsqlite3_column_int(tls, **(**uintptr)(__ccgo_up(bp)), 0)))
|
|
}
|
|
_rbuFinalize(tls, p, **(**uintptr)(__ccgo_up(bp)))
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** If an error has already occurred when this function is called, it
|
|
// ** immediately returns zero (without doing any work). Or, if an error
|
|
// ** occurs during the execution of this function, it sets the error code
|
|
// ** in the sqlite3rbu object indicated by the first argument and returns
|
|
// ** zero.
|
|
// **
|
|
// ** The iterator passed as the second argument is guaranteed to point to
|
|
// ** a table (not an index) when this function is called. This function
|
|
// ** attempts to create any imposter table required to write to the main
|
|
// ** table b-tree of the table before returning. Non-zero is returned if
|
|
// ** an imposter table are created, or zero otherwise.
|
|
// **
|
|
// ** An imposter table is required in all cases except RBU_PK_VTAB. Only
|
|
// ** virtual tables are written to directly. The imposter table has the
|
|
// ** same schema as the actual target table (less any UNIQUE constraints).
|
|
// ** More precisely, the "same schema" means the same columns, types,
|
|
// ** collation sequences. For tables that do not have an external PRIMARY
|
|
// ** KEY, it also means the same PRIMARY KEY declaration.
|
|
// */
|
|
func _rbuCreateImposterTable(tls *libc.TLS, p uintptr, pIter uintptr) {
|
|
bp := tls.Alloc(80)
|
|
defer tls.Free(80)
|
|
var iCol, tnum int32
|
|
var zCol, zComma, zPk, zPk1, zSql, v2 uintptr
|
|
var _ /* zColl at bp+0 */ uintptr
|
|
_, _, _, _, _, _, _, _ = iCol, tnum, zCol, zComma, zPk, zPk1, zSql, v2
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK && (*TRbuObjIter)(unsafe.Pointer(pIter)).FeType != int32(RBU_PK_VTAB) {
|
|
tnum = (*TRbuObjIter)(unsafe.Pointer(pIter)).FiTnum
|
|
zComma = __ccgo_ts + 1704
|
|
zSql = uintptr(0)
|
|
Xsqlite3_test_control(tls, int32(SQLITE_TESTCTRL_IMPOSTER), libc.VaList(bp+16, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, __ccgo_ts+6844, 0, int32(1)))
|
|
iCol = 0
|
|
for {
|
|
if !((*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK && iCol < (*TRbuObjIter)(unsafe.Pointer(pIter)).FnTblCol) {
|
|
break
|
|
}
|
|
zPk = __ccgo_ts + 1704
|
|
zCol = **(**uintptr)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FazTblCol + uintptr(iCol)*8))
|
|
**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = Xsqlite3_table_column_metadata(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, __ccgo_ts+6844, (*TRbuObjIter)(unsafe.Pointer(pIter)).FzTbl, zCol, uintptr(0), bp, uintptr(0), uintptr(0), uintptr(0))
|
|
if (*TRbuObjIter)(unsafe.Pointer(pIter)).FeType == int32(RBU_PK_IPK) && **(**Tu8)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FabTblPk + uintptr(iCol))) != 0 {
|
|
/* If the target table column is an "INTEGER PRIMARY KEY", add
|
|
** "PRIMARY KEY" to the imposter table column declaration. */
|
|
zPk = __ccgo_ts + 32050
|
|
}
|
|
if **(**Tu8)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FabNotNull + uintptr(iCol))) != 0 {
|
|
v2 = __ccgo_ts + 32063
|
|
} else {
|
|
v2 = __ccgo_ts + 1704
|
|
}
|
|
zSql = _rbuMPrintf(tls, p, __ccgo_ts+32073, libc.VaList(bp+16, zSql, zComma, zCol, **(**uintptr)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FazTblType + uintptr(iCol)*8)), zPk, **(**uintptr)(__ccgo_up(bp)), v2))
|
|
zComma = __ccgo_ts + 16242
|
|
goto _1
|
|
_1:
|
|
;
|
|
iCol = iCol + 1
|
|
}
|
|
if (*TRbuObjIter)(unsafe.Pointer(pIter)).FeType == int32(RBU_PK_WITHOUT_ROWID) {
|
|
zPk1 = _rbuWithoutRowidPK(tls, p, pIter)
|
|
if zPk1 != 0 {
|
|
zSql = _rbuMPrintf(tls, p, __ccgo_ts+32100, libc.VaList(bp+16, zSql, zPk1))
|
|
}
|
|
}
|
|
Xsqlite3_test_control(tls, int32(SQLITE_TESTCTRL_IMPOSTER), libc.VaList(bp+16, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, __ccgo_ts+6844, int32(1), tnum))
|
|
if (*TRbuObjIter)(unsafe.Pointer(pIter)).FeType == int32(RBU_PK_WITHOUT_ROWID) {
|
|
v2 = __ccgo_ts + 32107
|
|
} else {
|
|
v2 = __ccgo_ts + 1704
|
|
}
|
|
_rbuMPrintfExec(tls, p, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, __ccgo_ts+32122, libc.VaList(bp+16, (*TRbuObjIter)(unsafe.Pointer(pIter)).FzTbl, zSql, v2))
|
|
Xsqlite3_test_control(tls, int32(SQLITE_TESTCTRL_IMPOSTER), libc.VaList(bp+16, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, __ccgo_ts+6844, 0, 0))
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This function creates the second imposter table used when writing to
|
|
// ** a table b-tree where the table has an external primary key. If the
|
|
// ** iterator passed as the second argument does not currently point to
|
|
// ** a table (not index) with an external primary key, this function is a
|
|
// ** no-op.
|
|
// **
|
|
// ** Assuming the iterator does point to a table with an external PK, this
|
|
// ** function creates a WITHOUT ROWID imposter table named "rbu_imposter2"
|
|
// ** used to access that PK index. For example, if the target table is
|
|
// ** declared as follows:
|
|
// **
|
|
// ** CREATE TABLE t1(a, b TEXT, c REAL, PRIMARY KEY(b, c));
|
|
// **
|
|
// ** then the imposter table schema is:
|
|
// **
|
|
// ** CREATE TABLE rbu_imposter2(c1 TEXT, c2 REAL, id INTEGER) WITHOUT ROWID;
|
|
// **
|
|
// */
|
|
func _rbuCreateImposterTable2(tls *libc.TLS, p uintptr, pIter uintptr) {
|
|
bp := tls.Alloc(64)
|
|
defer tls.Free(64)
|
|
var bDesc, bKey, iCid, tnum int32
|
|
var zCollate, zCols, zComma, zIdx, zPk, v1 uintptr
|
|
var _ /* pQuery at bp+0 */ uintptr
|
|
var _ /* pXInfo at bp+8 */ uintptr
|
|
_, _, _, _, _, _, _, _, _, _ = bDesc, bKey, iCid, tnum, zCollate, zCols, zComma, zIdx, zPk, v1
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK && (*TRbuObjIter)(unsafe.Pointer(pIter)).FeType == int32(RBU_PK_EXTERNAL) {
|
|
tnum = (*TRbuObjIter)(unsafe.Pointer(pIter)).FiPkTnum /* Root page of PK index */
|
|
**(**uintptr)(__ccgo_up(bp)) = uintptr(0) /* SELECT name ... WHERE rootpage = $tnum */
|
|
zIdx = uintptr(0) /* Name of PK index */
|
|
**(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0) /* PRAGMA main.index_xinfo = $zIdx */
|
|
zComma = __ccgo_ts + 1704
|
|
zCols = uintptr(0) /* Used to build up list of table cols */
|
|
zPk = uintptr(0) /* Used to build up table PK declaration */
|
|
/* Figure out the name of the primary key index for the current table.
|
|
** This is needed for the argument to "PRAGMA index_xinfo". Set
|
|
** zIdx to point to a nul-terminated string containing this name. */
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = _prepareAndCollectError(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, bp, p+64, __ccgo_ts+31891)
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
Xsqlite3_bind_int(tls, **(**uintptr)(__ccgo_up(bp)), int32(1), tnum)
|
|
if int32(SQLITE_ROW) == Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp))) {
|
|
zIdx = Xsqlite3_column_text(tls, **(**uintptr)(__ccgo_up(bp)), 0)
|
|
}
|
|
}
|
|
if zIdx != 0 {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = _prepareFreeAndCollectError(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, bp+8, p+64, Xsqlite3_mprintf(tls, __ccgo_ts+31043, libc.VaList(bp+24, zIdx)))
|
|
}
|
|
_rbuFinalize(tls, p, **(**uintptr)(__ccgo_up(bp)))
|
|
for (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK && int32(SQLITE_ROW) == Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp + 8))) {
|
|
bKey = Xsqlite3_column_int(tls, **(**uintptr)(__ccgo_up(bp + 8)), int32(5))
|
|
if bKey != 0 {
|
|
iCid = Xsqlite3_column_int(tls, **(**uintptr)(__ccgo_up(bp + 8)), int32(1))
|
|
bDesc = Xsqlite3_column_int(tls, **(**uintptr)(__ccgo_up(bp + 8)), int32(3))
|
|
zCollate = Xsqlite3_column_text(tls, **(**uintptr)(__ccgo_up(bp + 8)), int32(4))
|
|
zCols = _rbuMPrintf(tls, p, __ccgo_ts+31941, libc.VaList(bp+24, zCols, zComma, iCid, **(**uintptr)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FazTblType + uintptr(iCid)*8)), zCollate))
|
|
if bDesc != 0 {
|
|
v1 = __ccgo_ts + 31283
|
|
} else {
|
|
v1 = __ccgo_ts + 1704
|
|
}
|
|
zPk = _rbuMPrintf(tls, p, __ccgo_ts+31963, libc.VaList(bp+24, zPk, zComma, iCid, v1))
|
|
zComma = __ccgo_ts + 16242
|
|
}
|
|
}
|
|
zCols = _rbuMPrintf(tls, p, __ccgo_ts+31973, libc.VaList(bp+24, zCols))
|
|
_rbuFinalize(tls, p, **(**uintptr)(__ccgo_up(bp + 8)))
|
|
Xsqlite3_test_control(tls, int32(SQLITE_TESTCTRL_IMPOSTER), libc.VaList(bp+24, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, __ccgo_ts+6844, int32(1), tnum))
|
|
_rbuMPrintfExec(tls, p, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, __ccgo_ts+31988, libc.VaList(bp+24, zCols, zPk))
|
|
Xsqlite3_test_control(tls, int32(SQLITE_TESTCTRL_IMPOSTER), libc.VaList(bp+24, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, __ccgo_ts+6844, 0, 0))
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** The RBU handle passed as the only argument has just been opened and
|
|
// ** the state database is empty. If this RBU handle was opened for an
|
|
// ** RBU vacuum operation, create the schema in the target db.
|
|
// */
|
|
func _rbuCreateTargetSchema(tls *libc.TLS, p uintptr) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var i int32
|
|
var zSql uintptr
|
|
var _ /* pInsert at bp+8 */ uintptr
|
|
var _ /* pSql at bp+0 */ uintptr
|
|
_, _ = i, zSql
|
|
**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
|
|
**(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0)
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = Xsqlite3_exec(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, __ccgo_ts+34034, uintptr(0), uintptr(0), p+64)
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = _prepareAndCollectError(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbRbu, bp, p+64, __ccgo_ts+34059)
|
|
}
|
|
for (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK && Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp))) == int32(SQLITE_ROW) {
|
|
zSql = Xsqlite3_column_text(tls, **(**uintptr)(__ccgo_up(bp)), 0)
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = Xsqlite3_exec(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, zSql, uintptr(0), uintptr(0), p+64)
|
|
}
|
|
_rbuFinalize(tls, p, **(**uintptr)(__ccgo_up(bp)))
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc != SQLITE_OK {
|
|
return
|
|
}
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = _prepareAndCollectError(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbRbu, bp, p+64, __ccgo_ts+34167)
|
|
}
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = _prepareAndCollectError(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, bp+8, p+64, __ccgo_ts+34232)
|
|
}
|
|
for (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK && Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp))) == int32(SQLITE_ROW) {
|
|
i = 0
|
|
for {
|
|
if !(i < int32(5)) {
|
|
break
|
|
}
|
|
Xsqlite3_bind_value(tls, **(**uintptr)(__ccgo_up(bp + 8)), i+int32(1), Xsqlite3_column_value(tls, **(**uintptr)(__ccgo_up(bp)), i))
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp + 8)))
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = Xsqlite3_reset(tls, **(**uintptr)(__ccgo_up(bp + 8)))
|
|
}
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = Xsqlite3_exec(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, __ccgo_ts+34276, uintptr(0), uintptr(0), p+64)
|
|
}
|
|
_rbuFinalize(tls, p, **(**uintptr)(__ccgo_up(bp)))
|
|
_rbuFinalize(tls, p, **(**uintptr)(__ccgo_up(bp + 8)))
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Implementation of SQL scalar function rbu_fossil_delta().
|
|
// **
|
|
// ** This function applies a fossil delta patch to a blob. Exactly two
|
|
// ** arguments must be passed to this function. The first is the blob to
|
|
// ** patch and the second the patch to apply. If no error occurs, this
|
|
// ** function returns the patched blob.
|
|
// */
|
|
func _rbuFossilDeltaFunc(tls *libc.TLS, context uintptr, argc int32, argv uintptr) {
|
|
var aDelta, aOrig, aOut uintptr
|
|
var nDelta, nOrig, nOut, nOut2 int32
|
|
_, _, _, _, _, _, _ = aDelta, aOrig, aOut, nDelta, nOrig, nOut, nOut2
|
|
_ = argc
|
|
nOrig = Xsqlite3_value_bytes(tls, **(**uintptr)(__ccgo_up(argv)))
|
|
aOrig = Xsqlite3_value_blob(tls, **(**uintptr)(__ccgo_up(argv)))
|
|
nDelta = Xsqlite3_value_bytes(tls, **(**uintptr)(__ccgo_up(argv + 1*8)))
|
|
aDelta = Xsqlite3_value_blob(tls, **(**uintptr)(__ccgo_up(argv + 1*8)))
|
|
/* Figure out the size of the output */
|
|
nOut = _rbuDeltaOutputSize(tls, aDelta, nDelta)
|
|
if nOut < 0 {
|
|
Xsqlite3_result_error(tls, context, __ccgo_ts+30295, -int32(1))
|
|
return
|
|
}
|
|
aOut = Xsqlite3_malloc64(tls, libc.Uint64FromInt64(int64(nOut)+int64(1)))
|
|
if aOut == uintptr(0) {
|
|
Xsqlite3_result_error_nomem(tls, context)
|
|
} else {
|
|
nOut2 = _rbuDeltaApply(tls, aOrig, nOrig, aDelta, nDelta, aOut)
|
|
if nOut2 != nOut {
|
|
Xsqlite3_free(tls, aOut)
|
|
Xsqlite3_result_error(tls, context, __ccgo_ts+30295, -int32(1))
|
|
} else {
|
|
Xsqlite3_result_blob(tls, context, aOut, nOut, __ccgo_fp(Xsqlite3_free))
|
|
}
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Set output variable *ppStmt to point to an UPDATE statement that may
|
|
// ** be used to update the imposter table for the main table b-tree of the
|
|
// ** table object that pIter currently points to, assuming that the
|
|
// ** rbu_control column of the data_xyz table contains zMask.
|
|
// **
|
|
// ** If the zMask string does not specify any columns to update, then this
|
|
// ** is not an error. Output variable *ppStmt is set to NULL in this case.
|
|
// */
|
|
func _rbuGetUpdateStmt(tls *libc.TLS, p uintptr, pIter uintptr, zMask uintptr, ppStmt uintptr) (r int32) {
|
|
bp := tls.Alloc(48)
|
|
defer tls.Free(48)
|
|
var nUp int32
|
|
var pUp, pp, zPrefix, zSet, zUpdate, zWhere uintptr
|
|
_, _, _, _, _, _, _ = nUp, pUp, pp, zPrefix, zSet, zUpdate, zWhere
|
|
pUp = uintptr(0)
|
|
nUp = 0
|
|
/* In case an error occurs */
|
|
**(**uintptr)(__ccgo_up(ppStmt)) = uintptr(0)
|
|
/* Search for an existing statement. If one is found, shift it to the front
|
|
** of the LRU queue and return immediately. Otherwise, leave nUp pointing
|
|
** to the number of statements currently in the cache and pUp to the
|
|
** last object in the list. */
|
|
pp = pIter + 184
|
|
for {
|
|
if !(**(**uintptr)(__ccgo_up(pp)) != 0) {
|
|
break
|
|
}
|
|
pUp = **(**uintptr)(__ccgo_up(pp))
|
|
if libc.Xstrcmp(tls, (*TRbuUpdateStmt)(unsafe.Pointer(pUp)).FzMask, zMask) == 0 {
|
|
**(**uintptr)(__ccgo_up(pp)) = (*TRbuUpdateStmt)(unsafe.Pointer(pUp)).FpNext
|
|
(*TRbuUpdateStmt)(unsafe.Pointer(pUp)).FpNext = (*TRbuObjIter)(unsafe.Pointer(pIter)).FpRbuUpdate
|
|
(*TRbuObjIter)(unsafe.Pointer(pIter)).FpRbuUpdate = pUp
|
|
**(**uintptr)(__ccgo_up(ppStmt)) = (*TRbuUpdateStmt)(unsafe.Pointer(pUp)).FpUpdate
|
|
return SQLITE_OK
|
|
}
|
|
nUp = nUp + 1
|
|
goto _1
|
|
_1:
|
|
;
|
|
pp = **(**uintptr)(__ccgo_up(pp)) + 16
|
|
}
|
|
if nUp >= int32(SQLITE_RBU_UPDATE_CACHESIZE) {
|
|
pp = pIter + 184
|
|
for {
|
|
if !(**(**uintptr)(__ccgo_up(pp)) != pUp) {
|
|
break
|
|
}
|
|
goto _2
|
|
_2:
|
|
;
|
|
pp = **(**uintptr)(__ccgo_up(pp)) + 16
|
|
}
|
|
**(**uintptr)(__ccgo_up(pp)) = uintptr(0)
|
|
Xsqlite3_finalize(tls, (*TRbuUpdateStmt)(unsafe.Pointer(pUp)).FpUpdate)
|
|
(*TRbuUpdateStmt)(unsafe.Pointer(pUp)).FpUpdate = uintptr(0)
|
|
} else {
|
|
pUp = _rbuMalloc(tls, p, libc.Int64FromUint64(uint64(24)+libc.Uint64FromInt32((*TRbuObjIter)(unsafe.Pointer(pIter)).FnTblCol)+uint64(1)))
|
|
}
|
|
if pUp != 0 {
|
|
zWhere = _rbuObjIterGetWhere(tls, p, pIter)
|
|
zSet = _rbuObjIterGetSetlist(tls, p, pIter, zMask)
|
|
zUpdate = uintptr(0)
|
|
(*TRbuUpdateStmt)(unsafe.Pointer(pUp)).FzMask = pUp + 1*24
|
|
(*TRbuUpdateStmt)(unsafe.Pointer(pUp)).FpNext = (*TRbuObjIter)(unsafe.Pointer(pIter)).FpRbuUpdate
|
|
(*TRbuObjIter)(unsafe.Pointer(pIter)).FpRbuUpdate = pUp
|
|
if zSet != 0 {
|
|
zPrefix = __ccgo_ts + 1704
|
|
libc.Xmemcpy(tls, (*TRbuUpdateStmt)(unsafe.Pointer(pUp)).FzMask, zMask, libc.Uint64FromInt32((*TRbuObjIter)(unsafe.Pointer(pIter)).FnTblCol))
|
|
if (*TRbuObjIter)(unsafe.Pointer(pIter)).FeType != int32(RBU_PK_VTAB) {
|
|
zPrefix = __ccgo_ts + 32723
|
|
}
|
|
zUpdate = Xsqlite3_mprintf(tls, __ccgo_ts+33384, libc.VaList(bp+8, zPrefix, (*TRbuObjIter)(unsafe.Pointer(pIter)).FzTbl, zSet, zWhere))
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = _prepareFreeAndCollectError(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, pUp+8, p+64, zUpdate)
|
|
**(**uintptr)(__ccgo_up(ppStmt)) = (*TRbuUpdateStmt)(unsafe.Pointer(pUp)).FpUpdate
|
|
}
|
|
Xsqlite3_free(tls, zWhere)
|
|
Xsqlite3_free(tls, zSet)
|
|
}
|
|
return (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Increment the schema cookie of the main database opened by p->dbMain.
|
|
// **
|
|
// ** Or, if this is an RBU vacuum, set the schema cookie of the main db
|
|
// ** opened by p->dbMain to one more than the schema cookie of the main
|
|
// ** db opened by p->dbRbu.
|
|
// */
|
|
func _rbuIncrSchemaCookie(tls *libc.TLS, p uintptr) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var dbread, v1 uintptr
|
|
var iCookie int32
|
|
var _ /* pStmt at bp+0 */ uintptr
|
|
_, _, _ = dbread, iCookie, v1
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).FzTarget == uintptr(0) {
|
|
v1 = (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbRbu
|
|
} else {
|
|
v1 = (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain
|
|
}
|
|
dbread = v1
|
|
iCookie = int32(1000000)
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = _prepareAndCollectError(tls, dbread, bp, p+64, __ccgo_ts+33790)
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
/* Coverage: it may be that this sqlite3_step() cannot fail. There
|
|
** is already a transaction open, so the prepared statement cannot
|
|
** throw an SQLITE_SCHEMA exception. The only database page the
|
|
** statement reads is page 1, which is guaranteed to be in the cache.
|
|
** And no memory allocations are required. */
|
|
if int32(SQLITE_ROW) == Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp))) {
|
|
iCookie = Xsqlite3_column_int(tls, **(**uintptr)(__ccgo_up(bp)), 0)
|
|
}
|
|
_rbuFinalize(tls, p, **(**uintptr)(__ccgo_up(bp)))
|
|
}
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
_rbuMPrintfExec(tls, p, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, __ccgo_ts+33812, libc.VaList(bp+16, iCookie+int32(1)))
|
|
}
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This user-defined SQL function is invoked with a single argument - the
|
|
// ** name of a table expected to appear in the target database. It returns
|
|
// ** the number of auxilliary indexes on the table.
|
|
// */
|
|
func _rbuIndexCntFunc(tls *libc.TLS, pCtx uintptr, nVal int32, apVal uintptr) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var db, p, v1 uintptr
|
|
var nIndex, rc int32
|
|
var _ /* pStmt at bp+0 */ uintptr
|
|
var _ /* zErrmsg at bp+8 */ uintptr
|
|
_, _, _, _, _ = db, nIndex, p, rc, v1
|
|
p = Xsqlite3_user_data(tls, pCtx)
|
|
**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
|
|
**(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0)
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).FzTarget == uintptr(0) {
|
|
v1 = (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbRbu
|
|
} else {
|
|
v1 = (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain
|
|
}
|
|
db = v1
|
|
_ = nVal
|
|
rc = _prepareFreeAndCollectError(tls, db, bp, bp+8, Xsqlite3_mprintf(tls, __ccgo_ts+34365, libc.VaList(bp+24, Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(apVal))))))
|
|
if rc != SQLITE_OK {
|
|
Xsqlite3_result_error(tls, pCtx, **(**uintptr)(__ccgo_up(bp + 8)), -int32(1))
|
|
} else {
|
|
nIndex = 0
|
|
if int32(SQLITE_ROW) == Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp))) {
|
|
nIndex = Xsqlite3_column_int(tls, **(**uintptr)(__ccgo_up(bp)), 0)
|
|
}
|
|
rc = Xsqlite3_finalize(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
if rc == SQLITE_OK {
|
|
Xsqlite3_result_int(tls, pCtx, nIndex)
|
|
} else {
|
|
Xsqlite3_result_error(tls, pCtx, Xsqlite3_errmsg(tls, db), -int32(1))
|
|
}
|
|
}
|
|
Xsqlite3_free(tls, **(**uintptr)(__ccgo_up(bp + 8)))
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** If the RBU database contains the rbu_count table, use it to initialize
|
|
// ** the sqlite3rbu.nPhaseOneStep variable. The schema of the rbu_count table
|
|
// ** is assumed to contain the same columns as:
|
|
// **
|
|
// ** CREATE TABLE rbu_count(tbl TEXT PRIMARY KEY, cnt INTEGER) WITHOUT ROWID;
|
|
// **
|
|
// ** There should be one row in the table for each data_xxx table in the
|
|
// ** database. The 'tbl' column should contain the name of a data_xxx table,
|
|
// ** and the cnt column the number of rows it contains.
|
|
// **
|
|
// ** sqlite3rbu.nPhaseOneStep is initialized to the sum of (1 + nIndex) * cnt
|
|
// ** for all rows in the rbu_count table, where nIndex is the number of
|
|
// ** indexes on the corresponding target database table.
|
|
// */
|
|
func _rbuInitPhaseOneSteps(tls *libc.TLS, p uintptr) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var bExists int32
|
|
var _ /* pStmt at bp+0 */ uintptr
|
|
_ = bExists
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
|
|
bExists = 0 /* True if rbu_count exists */
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).FnPhaseOneStep = int64(-int32(1))
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = Xsqlite3_create_function(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbRbu, __ccgo_ts+34437, int32(1), int32(SQLITE_UTF8), p, __ccgo_fp(_rbuIndexCntFunc), uintptr(0), uintptr(0))
|
|
/* Check for the rbu_count table. If it does not exist, or if an error
|
|
** occurs, nPhaseOneStep will be left set to -1. */
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = _prepareAndCollectError(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbRbu, bp, p+64, __ccgo_ts+34451)
|
|
}
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
if int32(SQLITE_ROW) == Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp))) {
|
|
bExists = int32(1)
|
|
}
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = Xsqlite3_finalize(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
}
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK && bExists != 0 {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = _prepareAndCollectError(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbRbu, bp, p+64, __ccgo_ts+34508)
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
if int32(SQLITE_ROW) == Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp))) {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).FnPhaseOneStep = Xsqlite3_column_int64(tls, **(**uintptr)(__ccgo_up(bp)), 0)
|
|
}
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = Xsqlite3_finalize(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Allocate an RbuState object and load the contents of the rbu_state
|
|
// ** table into it. Return a pointer to the new object. It is the
|
|
// ** responsibility of the caller to eventually free the object using
|
|
// ** sqlite3_free().
|
|
// **
|
|
// ** If an error occurs, leave an error code and message in the rbu handle
|
|
// ** and return NULL.
|
|
// */
|
|
func _rbuLoadState(tls *libc.TLS, p uintptr) (r uintptr) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var pRet uintptr
|
|
var rc2 int32
|
|
var _ /* pStmt at bp+0 */ uintptr
|
|
var _ /* rc at bp+8 */ int32
|
|
_, _ = pRet, rc2
|
|
pRet = uintptr(0)
|
|
**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
|
|
pRet = _rbuMalloc(tls, p, int64(80))
|
|
if pRet == uintptr(0) {
|
|
return uintptr(0)
|
|
}
|
|
**(**int32)(__ccgo_up(bp + 8)) = _prepareFreeAndCollectError(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbRbu, bp, p+64, Xsqlite3_mprintf(tls, __ccgo_ts+33414, libc.VaList(bp+24, p+48)))
|
|
for **(**int32)(__ccgo_up(bp + 8)) == SQLITE_OK && int32(SQLITE_ROW) == Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp))) {
|
|
switch Xsqlite3_column_int(tls, **(**uintptr)(__ccgo_up(bp)), 0) {
|
|
case int32(RBU_STATE_STAGE):
|
|
(*TRbuState)(unsafe.Pointer(pRet)).FeStage = Xsqlite3_column_int(tls, **(**uintptr)(__ccgo_up(bp)), int32(1))
|
|
if (*TRbuState)(unsafe.Pointer(pRet)).FeStage != int32(RBU_STAGE_OAL) && (*TRbuState)(unsafe.Pointer(pRet)).FeStage != int32(RBU_STAGE_MOVE) && (*TRbuState)(unsafe.Pointer(pRet)).FeStage != int32(RBU_STAGE_CKPT) {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = int32(SQLITE_CORRUPT)
|
|
}
|
|
case int32(RBU_STATE_TBL):
|
|
(*TRbuState)(unsafe.Pointer(pRet)).FzTbl = _rbuStrndup(tls, Xsqlite3_column_text(tls, **(**uintptr)(__ccgo_up(bp)), int32(1)), bp+8)
|
|
case int32(RBU_STATE_IDX):
|
|
(*TRbuState)(unsafe.Pointer(pRet)).FzIdx = _rbuStrndup(tls, Xsqlite3_column_text(tls, **(**uintptr)(__ccgo_up(bp)), int32(1)), bp+8)
|
|
case int32(RBU_STATE_ROW):
|
|
(*TRbuState)(unsafe.Pointer(pRet)).FnRow = Xsqlite3_column_int(tls, **(**uintptr)(__ccgo_up(bp)), int32(1))
|
|
if (*TRbuState)(unsafe.Pointer(pRet)).FnRow < 0 {
|
|
**(**int32)(__ccgo_up(bp + 8)) = int32(SQLITE_CORRUPT)
|
|
}
|
|
case int32(RBU_STATE_PROGRESS):
|
|
(*TRbuState)(unsafe.Pointer(pRet)).FnProgress = Xsqlite3_column_int64(tls, **(**uintptr)(__ccgo_up(bp)), int32(1))
|
|
case int32(RBU_STATE_CKPT):
|
|
(*TRbuState)(unsafe.Pointer(pRet)).FiWalCksum = Xsqlite3_column_int64(tls, **(**uintptr)(__ccgo_up(bp)), int32(1))
|
|
case int32(RBU_STATE_COOKIE):
|
|
(*TRbuState)(unsafe.Pointer(pRet)).FiCookie = libc.Uint32FromInt64(Xsqlite3_column_int64(tls, **(**uintptr)(__ccgo_up(bp)), int32(1)))
|
|
case int32(RBU_STATE_OALSZ):
|
|
(*TRbuState)(unsafe.Pointer(pRet)).FiOalSz = Xsqlite3_column_int64(tls, **(**uintptr)(__ccgo_up(bp)), int32(1))
|
|
case int32(RBU_STATE_PHASEONESTEP):
|
|
(*TRbuState)(unsafe.Pointer(pRet)).FnPhaseOneStep = Xsqlite3_column_int64(tls, **(**uintptr)(__ccgo_up(bp)), int32(1))
|
|
case int32(RBU_STATE_DATATBL):
|
|
(*TRbuState)(unsafe.Pointer(pRet)).FzDataTbl = _rbuStrndup(tls, Xsqlite3_column_text(tls, **(**uintptr)(__ccgo_up(bp)), int32(1)), bp+8)
|
|
default:
|
|
**(**int32)(__ccgo_up(bp + 8)) = int32(SQLITE_CORRUPT)
|
|
break
|
|
}
|
|
}
|
|
rc2 = Xsqlite3_finalize(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
if **(**int32)(__ccgo_up(bp + 8)) == SQLITE_OK {
|
|
**(**int32)(__ccgo_up(bp + 8)) = rc2
|
|
}
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = **(**int32)(__ccgo_up(bp + 8))
|
|
return pRet
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** The RBU handle is currently in RBU_STAGE_OAL state, with a SHARED lock
|
|
// ** on the database file. This proc moves the *-oal file to the *-wal path,
|
|
// ** then reopens the database file (this time in vanilla, non-oal, WAL mode).
|
|
// ** If an error occurs, leave an error code and error message in the rbu
|
|
// ** handle.
|
|
// */
|
|
func _rbuMoveOalFile(tls *libc.TLS, p uintptr) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var dbMain, zBase, zMove, zOal, zWal uintptr
|
|
_, _, _, _, _ = dbMain, zBase, zMove, zOal, zWal
|
|
zBase = Xsqlite3_db_filename(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, __ccgo_ts+6844)
|
|
zMove = zBase
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).FzTarget == uintptr(0) {
|
|
zMove = Xsqlite3_db_filename(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbRbu, __ccgo_ts+6844)
|
|
}
|
|
zOal = Xsqlite3_mprintf(tls, __ccgo_ts+33776, libc.VaList(bp+8, zMove))
|
|
zWal = Xsqlite3_mprintf(tls, __ccgo_ts+33783, libc.VaList(bp+8, zMove))
|
|
if zWal == uintptr(0) || zOal == uintptr(0) {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = int32(SQLITE_NOMEM)
|
|
} else {
|
|
/* Move the *-oal file to *-wal. At this point connection p->db is
|
|
** holding a SHARED lock on the target database file (because it is
|
|
** in WAL mode). So no other connection may be writing the db.
|
|
**
|
|
** In order to ensure that there are no database readers, an EXCLUSIVE
|
|
** lock is obtained here before the *-oal is moved to *-wal.
|
|
*/
|
|
dbMain = uintptr(0)
|
|
_rbuFileSuffix3(tls, zBase, zWal)
|
|
_rbuFileSuffix3(tls, zBase, zOal)
|
|
/* Re-open the databases. */
|
|
_rbuObjIterFinalize(tls, p+88)
|
|
Xsqlite3_close(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbRbu)
|
|
Xsqlite3_close(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain)
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain = uintptr(0)
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).FdbRbu = uintptr(0)
|
|
dbMain = _rbuOpenDbhandle(tls, p, (*Tsqlite3rbu)(unsafe.Pointer(p)).FzTarget, int32(1))
|
|
if dbMain != 0 {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = _rbuLockDatabase(tls, dbMain)
|
|
}
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = (*(*func(*libc.TLS, uintptr, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*Tsqlite3rbu)(unsafe.Pointer(p)).FxRename})))(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FpRenameArg, zOal, zWal)
|
|
}
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc != SQLITE_OK || (*Tsqlite3rbu)(unsafe.Pointer(p)).FzTarget == uintptr(0) || _rbuExclusiveCheckpoint(tls, dbMain) == 0 {
|
|
Xsqlite3_close(tls, dbMain)
|
|
dbMain = uintptr(0)
|
|
}
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
_rbuOpenDatabase(tls, p, dbMain, uintptr(0))
|
|
_rbuSetupCheckpoint(tls, p, uintptr(0))
|
|
}
|
|
}
|
|
Xsqlite3_free(tls, zWal)
|
|
Xsqlite3_free(tls, zOal)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This is a helper function for rbuObjIterCacheTableInfo(). It populates
|
|
// ** the pIter->abIndexed[] array.
|
|
// */
|
|
func _rbuObjIterCacheIndexedCols(tls *libc.TLS, p uintptr, pIter uintptr) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var bIndex, bPartial, iCid int32
|
|
var zIdx uintptr
|
|
var _ /* pList at bp+0 */ uintptr
|
|
var _ /* pXInfo at bp+8 */ uintptr
|
|
_, _, _, _ = bIndex, bPartial, iCid, zIdx
|
|
**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
|
|
bIndex = 0
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
libc.Xmemcpy(tls, (*TRbuObjIter)(unsafe.Pointer(pIter)).FabIndexed, (*TRbuObjIter)(unsafe.Pointer(pIter)).FabTblPk, uint64(1)*libc.Uint64FromInt32((*TRbuObjIter)(unsafe.Pointer(pIter)).FnTblCol))
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = _prepareFreeAndCollectError(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, bp, p+64, Xsqlite3_mprintf(tls, __ccgo_ts+31015, libc.VaList(bp+24, (*TRbuObjIter)(unsafe.Pointer(pIter)).FzTbl)))
|
|
}
|
|
(*TRbuObjIter)(unsafe.Pointer(pIter)).FnIndex = 0
|
|
for (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK && int32(SQLITE_ROW) == Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp))) {
|
|
zIdx = Xsqlite3_column_text(tls, **(**uintptr)(__ccgo_up(bp)), int32(1))
|
|
bPartial = Xsqlite3_column_int(tls, **(**uintptr)(__ccgo_up(bp)), int32(4))
|
|
**(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0)
|
|
if zIdx == uintptr(0) {
|
|
break
|
|
}
|
|
if bPartial != 0 {
|
|
libc.Xmemset(tls, (*TRbuObjIter)(unsafe.Pointer(pIter)).FabIndexed, int32(0x01), uint64(1)*libc.Uint64FromInt32((*TRbuObjIter)(unsafe.Pointer(pIter)).FnTblCol))
|
|
}
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = _prepareFreeAndCollectError(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, bp+8, p+64, Xsqlite3_mprintf(tls, __ccgo_ts+31043, libc.VaList(bp+24, zIdx)))
|
|
for (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK && int32(SQLITE_ROW) == Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp + 8))) {
|
|
iCid = Xsqlite3_column_int(tls, **(**uintptr)(__ccgo_up(bp + 8)), int32(1))
|
|
if iCid >= 0 {
|
|
**(**Tu8)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FabIndexed + uintptr(iCid))) = uint8(1)
|
|
}
|
|
if iCid == -int32(2) {
|
|
libc.Xmemset(tls, (*TRbuObjIter)(unsafe.Pointer(pIter)).FabIndexed, int32(0x01), uint64(1)*libc.Uint64FromInt32((*TRbuObjIter)(unsafe.Pointer(pIter)).FnTblCol))
|
|
}
|
|
}
|
|
_rbuFinalize(tls, p, **(**uintptr)(__ccgo_up(bp + 8)))
|
|
bIndex = int32(1)
|
|
(*TRbuObjIter)(unsafe.Pointer(pIter)).FnIndex = (*TRbuObjIter)(unsafe.Pointer(pIter)).FnIndex + 1
|
|
}
|
|
if (*TRbuObjIter)(unsafe.Pointer(pIter)).FeType == int32(RBU_PK_WITHOUT_ROWID) {
|
|
/* "PRAGMA index_list" includes the main PK b-tree */
|
|
(*TRbuObjIter)(unsafe.Pointer(pIter)).FnIndex = (*TRbuObjIter)(unsafe.Pointer(pIter)).FnIndex - 1
|
|
}
|
|
_rbuFinalize(tls, p, **(**uintptr)(__ccgo_up(bp)))
|
|
if bIndex == 0 {
|
|
(*TRbuObjIter)(unsafe.Pointer(pIter)).FabIndexed = uintptr(0)
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** If they are not already populated, populate the pIter->azTblCol[],
|
|
// ** pIter->abTblPk[], pIter->nTblCol and pIter->bRowid variables according to
|
|
// ** the table (not index) that the iterator currently points to.
|
|
// **
|
|
// ** Return SQLITE_OK if successful, or an SQLite error code otherwise. If
|
|
// ** an error does occur, an error code and error message are also left in
|
|
// ** the RBU handle.
|
|
// */
|
|
func _rbuObjIterCacheTableInfo(tls *libc.TLS, p uintptr, pIter uintptr) (r int32) {
|
|
bp := tls.Alloc(48)
|
|
defer tls.Free(48)
|
|
var bNotNull, bRbuRowid, i, iOrder, iPk, nCol, t, v2 int32
|
|
var t1, zCopy, zName, zName1, zType, v3 uintptr
|
|
var _ /* iTnum at bp+8 */ int32
|
|
var _ /* pStmt at bp+0 */ uintptr
|
|
_, _, _, _, _, _, _, _, _, _, _, _, _, _ = bNotNull, bRbuRowid, i, iOrder, iPk, nCol, t, t1, zCopy, zName, zName1, zType, v2, v3
|
|
if (*TRbuObjIter)(unsafe.Pointer(pIter)).FazTblCol == uintptr(0) {
|
|
**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
|
|
nCol = 0 /* for() loop iterator variable */
|
|
bRbuRowid = 0 /* If input table has column "rbu_rowid" */
|
|
iOrder = 0
|
|
**(**int32)(__ccgo_up(bp + 8)) = 0
|
|
/* Figure out the type of table this step will deal with. */
|
|
_rbuTableType(tls, p, (*TRbuObjIter)(unsafe.Pointer(pIter)).FzTbl, pIter+72, bp+8, pIter+108)
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK && (*TRbuObjIter)(unsafe.Pointer(pIter)).FeType == RBU_PK_NOTABLE {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = int32(SQLITE_ERROR)
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).FzErrmsg = Xsqlite3_mprintf(tls, __ccgo_ts+21367, libc.VaList(bp+24, (*TRbuObjIter)(unsafe.Pointer(pIter)).FzTbl))
|
|
}
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc != 0 {
|
|
return (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc
|
|
}
|
|
if (*TRbuObjIter)(unsafe.Pointer(pIter)).FzIdx == uintptr(0) {
|
|
(*TRbuObjIter)(unsafe.Pointer(pIter)).FiTnum = **(**int32)(__ccgo_up(bp + 8))
|
|
}
|
|
/* Populate the azTblCol[] and nTblCol variables based on the columns
|
|
** of the input table. Ignore any input table columns that begin with
|
|
** "rbu_". */
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = _prepareFreeAndCollectError(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbRbu, bp, p+64, Xsqlite3_mprintf(tls, __ccgo_ts+31072, libc.VaList(bp+24, (*TRbuObjIter)(unsafe.Pointer(pIter)).FzDataTbl)))
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
nCol = Xsqlite3_column_count(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
_rbuAllocateIterArrays(tls, p, pIter, nCol)
|
|
}
|
|
i = 0
|
|
for {
|
|
if !((*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK && i < nCol) {
|
|
break
|
|
}
|
|
zName = Xsqlite3_column_name(tls, **(**uintptr)(__ccgo_up(bp)), i)
|
|
if Xsqlite3_strnicmp(tls, __ccgo_ts+31091, zName, int32(4)) != 0 {
|
|
zCopy = _rbuStrndup(tls, zName, p+56)
|
|
**(**int32)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FaiSrcOrder + uintptr((*TRbuObjIter)(unsafe.Pointer(pIter)).FnTblCol)*4)) = (*TRbuObjIter)(unsafe.Pointer(pIter)).FnTblCol
|
|
v3 = pIter + 16
|
|
v2 = *(*int32)(unsafe.Pointer(v3))
|
|
*(*int32)(unsafe.Pointer(v3)) = *(*int32)(unsafe.Pointer(v3)) + 1
|
|
**(**uintptr)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FazTblCol + uintptr(v2)*8)) = zCopy
|
|
} else {
|
|
if 0 == Xsqlite3_stricmp(tls, __ccgo_ts+31096, zName) {
|
|
bRbuRowid = int32(1)
|
|
}
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
Xsqlite3_finalize(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK && libc.BoolInt32((*Tsqlite3rbu)(unsafe.Pointer(p)).FzTarget == uintptr(0)) == 0 && bRbuRowid != libc.BoolInt32((*TRbuObjIter)(unsafe.Pointer(pIter)).FeType == int32(RBU_PK_VTAB) || (*TRbuObjIter)(unsafe.Pointer(pIter)).FeType == int32(RBU_PK_NONE)) {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = int32(SQLITE_ERROR)
|
|
if bRbuRowid != 0 {
|
|
v3 = __ccgo_ts + 31106
|
|
} else {
|
|
v3 = __ccgo_ts + 31119
|
|
}
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).FzErrmsg = Xsqlite3_mprintf(tls, __ccgo_ts+31128, libc.VaList(bp+24, (*TRbuObjIter)(unsafe.Pointer(pIter)).FzDataTbl, v3))
|
|
}
|
|
/* Check that all non-HIDDEN columns in the destination table are also
|
|
** present in the input table. Populate the abTblPk[], azTblType[] and
|
|
** aiTblOrder[] arrays at the same time. */
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = _prepareFreeAndCollectError(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, bp, p+64, Xsqlite3_mprintf(tls, __ccgo_ts+31157, libc.VaList(bp+24, (*TRbuObjIter)(unsafe.Pointer(pIter)).FzTbl)))
|
|
}
|
|
for (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK && int32(SQLITE_ROW) == Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp))) {
|
|
zName1 = Xsqlite3_column_text(tls, **(**uintptr)(__ccgo_up(bp)), int32(1))
|
|
if zName1 == uintptr(0) {
|
|
break
|
|
} /* An OOM - finalize() below returns S_NOMEM */
|
|
i = iOrder
|
|
for {
|
|
if !(i < (*TRbuObjIter)(unsafe.Pointer(pIter)).FnTblCol) {
|
|
break
|
|
}
|
|
if 0 == libc.Xstrcmp(tls, zName1, **(**uintptr)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FazTblCol + uintptr(i)*8))) {
|
|
break
|
|
}
|
|
goto _5
|
|
_5:
|
|
;
|
|
i = i + 1
|
|
}
|
|
if i == (*TRbuObjIter)(unsafe.Pointer(pIter)).FnTblCol {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = int32(SQLITE_ERROR)
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).FzErrmsg = Xsqlite3_mprintf(tls, __ccgo_ts+31179, libc.VaList(bp+24, (*TRbuObjIter)(unsafe.Pointer(pIter)).FzDataTbl, zName1))
|
|
} else {
|
|
iPk = Xsqlite3_column_int(tls, **(**uintptr)(__ccgo_up(bp)), int32(5))
|
|
bNotNull = Xsqlite3_column_int(tls, **(**uintptr)(__ccgo_up(bp)), int32(3))
|
|
zType = Xsqlite3_column_text(tls, **(**uintptr)(__ccgo_up(bp)), int32(2))
|
|
if i != iOrder {
|
|
t = **(**int32)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FaiSrcOrder + uintptr(i)*4))
|
|
**(**int32)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FaiSrcOrder + uintptr(i)*4)) = **(**int32)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FaiSrcOrder + uintptr(iOrder)*4))
|
|
**(**int32)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FaiSrcOrder + uintptr(iOrder)*4)) = t
|
|
t1 = **(**uintptr)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FazTblCol + uintptr(i)*8))
|
|
**(**uintptr)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FazTblCol + uintptr(i)*8)) = **(**uintptr)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FazTblCol + uintptr(iOrder)*8))
|
|
**(**uintptr)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FazTblCol + uintptr(iOrder)*8)) = t1
|
|
}
|
|
**(**uintptr)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FazTblType + uintptr(iOrder)*8)) = _rbuStrndup(tls, zType, p+56)
|
|
**(**Tu8)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FabTblPk + uintptr(iOrder))) = libc.Uint8FromInt32(iPk)
|
|
**(**Tu8)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FabNotNull + uintptr(iOrder))) = libc.BoolUint8(libc.Uint8FromInt32(bNotNull) != 0 || iPk != 0)
|
|
iOrder = iOrder + 1
|
|
}
|
|
}
|
|
_rbuFinalize(tls, p, **(**uintptr)(__ccgo_up(bp)))
|
|
_rbuObjIterCacheIndexedCols(tls, p, pIter)
|
|
}
|
|
return (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Initialize the iterator structure passed as the second argument.
|
|
// **
|
|
// ** If no error occurs, SQLITE_OK is returned and the iterator is left
|
|
// ** pointing to the first entry. Otherwise, an error code and message is
|
|
// ** left in the RBU handle passed as the first argument. A copy of the
|
|
// ** error code is returned.
|
|
// */
|
|
func _rbuObjIterFirst(tls *libc.TLS, p uintptr, pIter uintptr) (r int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var rc int32
|
|
var v1 uintptr
|
|
_, _ = rc, v1
|
|
libc.Xmemset(tls, pIter, 0, uint64(192))
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).FzTarget == uintptr(0) {
|
|
v1 = __ccgo_ts + 30487
|
|
} else {
|
|
v1 = __ccgo_ts + 1704
|
|
}
|
|
rc = _prepareFreeAndCollectError(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbRbu, pIter, p+64, Xsqlite3_mprintf(tls, __ccgo_ts+30528, libc.VaList(bp+8, v1)))
|
|
if rc == SQLITE_OK {
|
|
rc = _prepareAndCollectError(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, pIter+8, p+64, __ccgo_ts+30678)
|
|
}
|
|
(*TRbuObjIter)(unsafe.Pointer(pIter)).FbCleanup = int32(1)
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = rc
|
|
return _rbuObjIterNext(tls, p, pIter)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This function constructs and returns a pointer to a nul-terminated
|
|
// ** string containing some SQL clause or list based on one or more of the
|
|
// ** column names currently stored in the pIter->azTblCol[] array.
|
|
// */
|
|
func _rbuObjIterGetCollist(tls *libc.TLS, p uintptr, pIter uintptr) (r uintptr) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var i int32
|
|
var z, zList, zSep uintptr
|
|
_, _, _, _ = i, z, zList, zSep
|
|
zList = uintptr(0)
|
|
zSep = __ccgo_ts + 1704
|
|
i = 0
|
|
for {
|
|
if !(i < (*TRbuObjIter)(unsafe.Pointer(pIter)).FnTblCol) {
|
|
break
|
|
}
|
|
z = **(**uintptr)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FazTblCol + uintptr(i)*8))
|
|
zList = _rbuMPrintf(tls, p, __ccgo_ts+31206, libc.VaList(bp+8, zList, zSep, z))
|
|
zSep = __ccgo_ts + 16242
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
return zList
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This function is used to create a SELECT list (the list of SQL
|
|
// ** expressions that follows a SELECT keyword) for a SELECT statement
|
|
// ** used to read from an data_xxx or rbu_tmp_xxx table while updating the
|
|
// ** index object currently indicated by the iterator object passed as the
|
|
// ** second argument. A "PRAGMA index_xinfo = <idxname>" statement is used
|
|
// ** to obtain the required information.
|
|
// **
|
|
// ** If the index is of the following form:
|
|
// **
|
|
// ** CREATE INDEX i1 ON t1(c, b COLLATE nocase);
|
|
// **
|
|
// ** and "t1" is a table with an explicit INTEGER PRIMARY KEY column
|
|
// ** "ipk", the returned string is:
|
|
// **
|
|
// ** "`c` COLLATE 'BINARY', `b` COLLATE 'NOCASE', `ipk` COLLATE 'BINARY'"
|
|
// **
|
|
// ** As well as the returned string, three other malloc'd strings are
|
|
// ** returned via output parameters. As follows:
|
|
// **
|
|
// ** pzImposterCols: ...
|
|
// ** pzImposterPk: ...
|
|
// ** pzWhere: ...
|
|
// */
|
|
func _rbuObjIterGetIndexCols(tls *libc.TLS, p uintptr, pIter uintptr, pzImposterCols uintptr, pzImposterPk uintptr, pzWhere uintptr, pnBind uintptr) (r uintptr) {
|
|
bp := tls.Alloc(64)
|
|
defer tls.Free(64)
|
|
var bDesc, i, iCid, iSeq, nBind, rc, rc2 int32
|
|
var zAnd, zCol, zCollate, zCom, zImpCols, zImpPK, zOrder, zRet, zType, zWhere, v2 uintptr
|
|
var _ /* pXInfo at bp+0 */ uintptr
|
|
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = bDesc, i, iCid, iSeq, nBind, rc, rc2, zAnd, zCol, zCollate, zCom, zImpCols, zImpPK, zOrder, zRet, zType, zWhere, v2
|
|
rc = (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc /* sqlite3_finalize() return code */
|
|
zRet = uintptr(0) /* String to return */
|
|
zImpCols = uintptr(0) /* String to return via *pzImposterCols */
|
|
zImpPK = uintptr(0) /* String to return via *pzImposterPK */
|
|
zWhere = uintptr(0) /* String to return via *pzWhere */
|
|
nBind = 0 /* Value to return via *pnBind */
|
|
zCom = __ccgo_ts + 1704 /* Set to ", " later on */
|
|
zAnd = __ccgo_ts + 1704 /* Set to " AND " later on */
|
|
**(**uintptr)(__ccgo_up(bp)) = uintptr(0) /* PRAGMA index_xinfo = ? */
|
|
if rc == SQLITE_OK {
|
|
rc = _prepareFreeAndCollectError(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, bp, p+64, Xsqlite3_mprintf(tls, __ccgo_ts+31043, libc.VaList(bp+16, (*TRbuObjIter)(unsafe.Pointer(pIter)).FzIdx)))
|
|
}
|
|
for rc == SQLITE_OK && int32(SQLITE_ROW) == Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp))) {
|
|
iCid = Xsqlite3_column_int(tls, **(**uintptr)(__ccgo_up(bp)), int32(1))
|
|
bDesc = Xsqlite3_column_int(tls, **(**uintptr)(__ccgo_up(bp)), int32(3))
|
|
zCollate = Xsqlite3_column_text(tls, **(**uintptr)(__ccgo_up(bp)), int32(4))
|
|
zCol = uintptr(0)
|
|
if iCid == -int32(2) {
|
|
iSeq = Xsqlite3_column_int(tls, **(**uintptr)(__ccgo_up(bp)), 0)
|
|
zRet = Xsqlite3_mprintf(tls, __ccgo_ts+31525, libc.VaList(bp+16, zRet, zCom, (**(**TRbuSpan)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FaIdxCol + uintptr(iSeq)*16))).FnSpan, (**(**TRbuSpan)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FaIdxCol + uintptr(iSeq)*16))).FzSpan, zCollate))
|
|
zType = __ccgo_ts + 1704
|
|
} else {
|
|
if iCid < 0 {
|
|
/* An integer primary key. If the table has an explicit IPK, use
|
|
** its name. Otherwise, use "rbu_rowid". */
|
|
if (*TRbuObjIter)(unsafe.Pointer(pIter)).FeType == int32(RBU_PK_IPK) {
|
|
i = 0
|
|
for {
|
|
if !(libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FabTblPk + uintptr(i)))) == 0) {
|
|
break
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
zCol = **(**uintptr)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FazTblCol + uintptr(i)*8))
|
|
} else {
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).FzTarget == uintptr(0) {
|
|
zCol = __ccgo_ts + 31366
|
|
} else {
|
|
zCol = __ccgo_ts + 31096
|
|
}
|
|
}
|
|
zType = __ccgo_ts + 1178
|
|
} else {
|
|
zCol = **(**uintptr)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FazTblCol + uintptr(iCid)*8))
|
|
zType = **(**uintptr)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FazTblType + uintptr(iCid)*8))
|
|
}
|
|
zRet = Xsqlite3_mprintf(tls, __ccgo_ts+31547, libc.VaList(bp+16, zRet, zCom, zCol, zCollate))
|
|
}
|
|
if (*TRbuObjIter)(unsafe.Pointer(pIter)).FbUnique == 0 || Xsqlite3_column_int(tls, **(**uintptr)(__ccgo_up(bp)), int32(5)) != 0 {
|
|
if bDesc != 0 {
|
|
v2 = __ccgo_ts + 31283
|
|
} else {
|
|
v2 = __ccgo_ts + 1704
|
|
}
|
|
zOrder = v2
|
|
zImpPK = Xsqlite3_mprintf(tls, __ccgo_ts+31567, libc.VaList(bp+16, zImpPK, zCom, nBind, zCol, zOrder))
|
|
}
|
|
zImpCols = Xsqlite3_mprintf(tls, __ccgo_ts+31588, libc.VaList(bp+16, zImpCols, zCom, nBind, zCol, zType, zCollate))
|
|
zWhere = Xsqlite3_mprintf(tls, __ccgo_ts+31621, libc.VaList(bp+16, zWhere, zAnd, nBind, zCol))
|
|
if zRet == uintptr(0) || zImpPK == uintptr(0) || zImpCols == uintptr(0) || zWhere == uintptr(0) {
|
|
rc = int32(SQLITE_NOMEM)
|
|
}
|
|
zCom = __ccgo_ts + 16242
|
|
zAnd = __ccgo_ts + 23653
|
|
nBind = nBind + 1
|
|
}
|
|
rc2 = Xsqlite3_finalize(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
if rc == SQLITE_OK {
|
|
rc = rc2
|
|
}
|
|
if rc != SQLITE_OK {
|
|
Xsqlite3_free(tls, zRet)
|
|
Xsqlite3_free(tls, zImpCols)
|
|
Xsqlite3_free(tls, zImpPK)
|
|
Xsqlite3_free(tls, zWhere)
|
|
zRet = uintptr(0)
|
|
zImpCols = uintptr(0)
|
|
zImpPK = uintptr(0)
|
|
zWhere = uintptr(0)
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = rc
|
|
}
|
|
**(**uintptr)(__ccgo_up(pzImposterCols)) = zImpCols
|
|
**(**uintptr)(__ccgo_up(pzImposterPk)) = zImpPK
|
|
**(**uintptr)(__ccgo_up(pzWhere)) = zWhere
|
|
**(**int32)(__ccgo_up(pnBind)) = nBind
|
|
return zRet
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Assuming the current table columns are "a", "b" and "c", and the zObj
|
|
// ** paramter is passed "old", return a string of the form:
|
|
// **
|
|
// ** "old.a, old.b, old.b"
|
|
// **
|
|
// ** With the column names escaped.
|
|
// **
|
|
// ** For tables with implicit rowids - RBU_PK_EXTERNAL and RBU_PK_NONE, append
|
|
// ** the text ", old._rowid_" to the returned value.
|
|
// */
|
|
func _rbuObjIterGetOldlist(tls *libc.TLS, p uintptr, pIter uintptr, zObj uintptr) (r uintptr) {
|
|
bp := tls.Alloc(48)
|
|
defer tls.Free(48)
|
|
var i int32
|
|
var zCol, zList, zS uintptr
|
|
_, _, _, _ = i, zCol, zList, zS
|
|
zList = uintptr(0)
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK && (*TRbuObjIter)(unsafe.Pointer(pIter)).FabIndexed != 0 {
|
|
zS = __ccgo_ts + 1704
|
|
i = 0
|
|
for {
|
|
if !(i < (*TRbuObjIter)(unsafe.Pointer(pIter)).FnTblCol) {
|
|
break
|
|
}
|
|
if **(**Tu8)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FabIndexed + uintptr(i))) != 0 {
|
|
zCol = **(**uintptr)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FazTblCol + uintptr(i)*8))
|
|
zList = Xsqlite3_mprintf(tls, __ccgo_ts+31645, libc.VaList(bp+8, zList, zS, zObj, zCol))
|
|
} else {
|
|
zList = Xsqlite3_mprintf(tls, __ccgo_ts+31657, libc.VaList(bp+8, zList, zS))
|
|
}
|
|
zS = __ccgo_ts + 16242
|
|
if zList == uintptr(0) {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = int32(SQLITE_NOMEM)
|
|
break
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
/* For a table with implicit rowids, append "old._rowid_" to the list. */
|
|
if (*TRbuObjIter)(unsafe.Pointer(pIter)).FeType == int32(RBU_PK_EXTERNAL) || (*TRbuObjIter)(unsafe.Pointer(pIter)).FeType == int32(RBU_PK_NONE) {
|
|
zList = _rbuMPrintf(tls, p, __ccgo_ts+31666, libc.VaList(bp+8, zList, zObj))
|
|
}
|
|
}
|
|
return zList
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Return a comma separated list of the quoted PRIMARY KEY column names,
|
|
// ** in order, for the current table. Before each column name, add the text
|
|
// ** zPre. After each column name, add the zPost text. Use zSeparator as
|
|
// ** the separator text (usually ", ").
|
|
// */
|
|
func _rbuObjIterGetPkList(tls *libc.TLS, p uintptr, pIter uintptr, zPre uintptr, zSeparator uintptr, zPost uintptr) (r uintptr) {
|
|
bp := tls.Alloc(48)
|
|
defer tls.Free(48)
|
|
var i, iPk int32
|
|
var zCol, zRet, zSep uintptr
|
|
_, _, _, _, _ = i, iPk, zCol, zRet, zSep
|
|
iPk = int32(1)
|
|
zRet = uintptr(0)
|
|
zSep = __ccgo_ts + 1704
|
|
for int32(1) != 0 {
|
|
i = 0
|
|
for {
|
|
if !(i < (*TRbuObjIter)(unsafe.Pointer(pIter)).FnTblCol) {
|
|
break
|
|
}
|
|
if libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FabTblPk + uintptr(i)))) == iPk {
|
|
zCol = **(**uintptr)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FazTblCol + uintptr(i)*8))
|
|
zRet = _rbuMPrintf(tls, p, __ccgo_ts+31215, libc.VaList(bp+8, zRet, zSep, zPre, zCol, zPost))
|
|
zSep = zSeparator
|
|
break
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
if i == (*TRbuObjIter)(unsafe.Pointer(pIter)).FnTblCol {
|
|
break
|
|
}
|
|
iPk = iPk + 1
|
|
}
|
|
return zRet
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Return an expression that can be used in a WHERE clause to match the
|
|
// ** primary key of the current table. For example, if the table is:
|
|
// **
|
|
// ** CREATE TABLE t1(a, b, c, PRIMARY KEY(b, c));
|
|
// **
|
|
// ** Return the string:
|
|
// **
|
|
// ** "b = ?1 AND c = ?2"
|
|
// */
|
|
func _rbuObjIterGetWhere(tls *libc.TLS, p uintptr, pIter uintptr) (r uintptr) {
|
|
bp := tls.Alloc(48)
|
|
defer tls.Free(48)
|
|
var i, i1 int32
|
|
var zCol, zList, zSep, zSep1 uintptr
|
|
_, _, _, _, _, _ = i, i1, zCol, zList, zSep, zSep1
|
|
zList = uintptr(0)
|
|
if (*TRbuObjIter)(unsafe.Pointer(pIter)).FeType == int32(RBU_PK_VTAB) || (*TRbuObjIter)(unsafe.Pointer(pIter)).FeType == int32(RBU_PK_NONE) {
|
|
zList = _rbuMPrintf(tls, p, __ccgo_ts+31681, libc.VaList(bp+8, (*TRbuObjIter)(unsafe.Pointer(pIter)).FnTblCol+int32(1)))
|
|
} else {
|
|
if (*TRbuObjIter)(unsafe.Pointer(pIter)).FeType == int32(RBU_PK_EXTERNAL) {
|
|
zSep = __ccgo_ts + 1704
|
|
i = 0
|
|
for {
|
|
if !(i < (*TRbuObjIter)(unsafe.Pointer(pIter)).FnTblCol) {
|
|
break
|
|
}
|
|
if **(**Tu8)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FabTblPk + uintptr(i))) != 0 {
|
|
zList = _rbuMPrintf(tls, p, __ccgo_ts+31695, libc.VaList(bp+8, zList, zSep, i, i+int32(1)))
|
|
zSep = __ccgo_ts + 23653
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
zList = _rbuMPrintf(tls, p, __ccgo_ts+31707, libc.VaList(bp+8, zList))
|
|
} else {
|
|
zSep1 = __ccgo_ts + 1704
|
|
i1 = 0
|
|
for {
|
|
if !(i1 < (*TRbuObjIter)(unsafe.Pointer(pIter)).FnTblCol) {
|
|
break
|
|
}
|
|
if **(**Tu8)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FabTblPk + uintptr(i1))) != 0 {
|
|
zCol = **(**uintptr)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FazTblCol + uintptr(i1)*8))
|
|
zList = _rbuMPrintf(tls, p, __ccgo_ts+31757, libc.VaList(bp+8, zList, zSep1, zCol, i1+int32(1)))
|
|
zSep1 = __ccgo_ts + 23653
|
|
}
|
|
goto _2
|
|
_2:
|
|
;
|
|
i1 = i1 + 1
|
|
}
|
|
}
|
|
}
|
|
return zList
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Advance the iterator to the next position.
|
|
// **
|
|
// ** If no error occurs, SQLITE_OK is returned and the iterator is left
|
|
// ** pointing to the next entry. Otherwise, an error code and message is
|
|
// ** left in the RBU handle passed as the first argument. A copy of the
|
|
// ** error code is returned.
|
|
// */
|
|
func _rbuObjIterNext(tls *libc.TLS, p uintptr, pIter uintptr) (r int32) {
|
|
var pIdx uintptr
|
|
var rc, v1 int32
|
|
_, _, _ = pIdx, rc, v1
|
|
rc = (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc
|
|
if rc == SQLITE_OK {
|
|
/* Free any SQLite statements used while processing the previous object */
|
|
_rbuObjIterClearStatements(tls, pIter)
|
|
if (*TRbuObjIter)(unsafe.Pointer(pIter)).FzIdx == uintptr(0) {
|
|
rc = Xsqlite3_exec(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, __ccgo_ts+30316, uintptr(0), uintptr(0), p+64)
|
|
}
|
|
if rc == SQLITE_OK {
|
|
if (*TRbuObjIter)(unsafe.Pointer(pIter)).FbCleanup != 0 {
|
|
_rbuObjIterFreeCols(tls, pIter)
|
|
(*TRbuObjIter)(unsafe.Pointer(pIter)).FbCleanup = 0
|
|
rc = Xsqlite3_step(tls, (*TRbuObjIter)(unsafe.Pointer(pIter)).FpTblIter)
|
|
if rc != int32(SQLITE_ROW) {
|
|
rc = _resetAndCollectError(tls, (*TRbuObjIter)(unsafe.Pointer(pIter)).FpTblIter, p+64)
|
|
(*TRbuObjIter)(unsafe.Pointer(pIter)).FzTbl = uintptr(0)
|
|
(*TRbuObjIter)(unsafe.Pointer(pIter)).FzDataTbl = uintptr(0)
|
|
} else {
|
|
(*TRbuObjIter)(unsafe.Pointer(pIter)).FzTbl = Xsqlite3_column_text(tls, (*TRbuObjIter)(unsafe.Pointer(pIter)).FpTblIter, 0)
|
|
(*TRbuObjIter)(unsafe.Pointer(pIter)).FzDataTbl = Xsqlite3_column_text(tls, (*TRbuObjIter)(unsafe.Pointer(pIter)).FpTblIter, int32(1))
|
|
if (*TRbuObjIter)(unsafe.Pointer(pIter)).FzDataTbl != 0 && (*TRbuObjIter)(unsafe.Pointer(pIter)).FzTbl != 0 {
|
|
v1 = SQLITE_OK
|
|
} else {
|
|
v1 = int32(SQLITE_NOMEM)
|
|
}
|
|
rc = v1
|
|
}
|
|
} else {
|
|
if (*TRbuObjIter)(unsafe.Pointer(pIter)).FzIdx == uintptr(0) {
|
|
pIdx = (*TRbuObjIter)(unsafe.Pointer(pIter)).FpIdxIter
|
|
rc = Xsqlite3_bind_text(tls, pIdx, int32(1), (*TRbuObjIter)(unsafe.Pointer(pIter)).FzTbl, -int32(1), libc.UintptrFromInt32(0))
|
|
}
|
|
if rc == SQLITE_OK {
|
|
rc = Xsqlite3_step(tls, (*TRbuObjIter)(unsafe.Pointer(pIter)).FpIdxIter)
|
|
if rc != int32(SQLITE_ROW) {
|
|
rc = _resetAndCollectError(tls, (*TRbuObjIter)(unsafe.Pointer(pIter)).FpIdxIter, p+64)
|
|
(*TRbuObjIter)(unsafe.Pointer(pIter)).FbCleanup = int32(1)
|
|
(*TRbuObjIter)(unsafe.Pointer(pIter)).FzIdx = uintptr(0)
|
|
} else {
|
|
(*TRbuObjIter)(unsafe.Pointer(pIter)).FzIdx = Xsqlite3_column_text(tls, (*TRbuObjIter)(unsafe.Pointer(pIter)).FpIdxIter, 0)
|
|
(*TRbuObjIter)(unsafe.Pointer(pIter)).FiTnum = Xsqlite3_column_int(tls, (*TRbuObjIter)(unsafe.Pointer(pIter)).FpIdxIter, int32(1))
|
|
(*TRbuObjIter)(unsafe.Pointer(pIter)).FbUnique = Xsqlite3_column_int(tls, (*TRbuObjIter)(unsafe.Pointer(pIter)).FpIdxIter, int32(2))
|
|
if (*TRbuObjIter)(unsafe.Pointer(pIter)).FzIdx != 0 {
|
|
v1 = SQLITE_OK
|
|
} else {
|
|
v1 = int32(SQLITE_NOMEM)
|
|
}
|
|
rc = v1
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if rc != SQLITE_OK {
|
|
_rbuObjIterFinalize(tls, pIter)
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = rc
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Ensure that the SQLite statement handles required to update the
|
|
// ** target database object currently indicated by the iterator passed
|
|
// ** as the second argument are available.
|
|
// */
|
|
func _rbuObjIterPrepareAll(tls *libc.TLS, p uintptr, pIter uintptr, nOffset int32) (r int32) {
|
|
bp := tls.Alloc(128)
|
|
defer tls.Free(128)
|
|
var bRbuRowid, tnum int32
|
|
var pz, zBind, zBindings, zCollist, zIdx, zLimit, zNewlist, zOldlist, zOrder, zPart, zRbuRowid, zRbuRowid1, zSql, zStart, zStart1, zTbl, zTbl1, zWhere1, zWrite, v1, v2, v3 uintptr
|
|
var _ /* nBind at bp+24 */ int32
|
|
var _ /* zImposterCols at bp+0 */ uintptr
|
|
var _ /* zImposterPK at bp+8 */ uintptr
|
|
var _ /* zWhere at bp+16 */ uintptr
|
|
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = bRbuRowid, pz, tnum, zBind, zBindings, zCollist, zIdx, zLimit, zNewlist, zOldlist, zOrder, zPart, zRbuRowid, zRbuRowid1, zSql, zStart, zStart1, zTbl, zTbl1, zWhere1, zWrite, v1, v2, v3
|
|
if (*TRbuObjIter)(unsafe.Pointer(pIter)).FpSelect == uintptr(0) && _rbuObjIterCacheTableInfo(tls, p, pIter) == SQLITE_OK {
|
|
tnum = (*TRbuObjIter)(unsafe.Pointer(pIter)).FiTnum
|
|
zCollist = uintptr(0) /* List of indexed columns */
|
|
pz = p + 64
|
|
zIdx = (*TRbuObjIter)(unsafe.Pointer(pIter)).FzIdx
|
|
zLimit = uintptr(0)
|
|
if nOffset != 0 {
|
|
zLimit = Xsqlite3_mprintf(tls, __ccgo_ts+32277, libc.VaList(bp+40, nOffset))
|
|
if !(zLimit != 0) {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = int32(SQLITE_NOMEM)
|
|
}
|
|
}
|
|
if zIdx != 0 {
|
|
zTbl = (*TRbuObjIter)(unsafe.Pointer(pIter)).FzTbl
|
|
**(**uintptr)(__ccgo_up(bp)) = uintptr(0) /* Columns for imposter table */
|
|
**(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0) /* Primary key declaration for imposter */
|
|
**(**uintptr)(__ccgo_up(bp + 16)) = uintptr(0) /* WHERE clause on PK columns */
|
|
zBind = uintptr(0)
|
|
zPart = uintptr(0)
|
|
**(**int32)(__ccgo_up(bp + 24)) = 0
|
|
zPart = _rbuObjIterGetIndexWhere(tls, p, pIter)
|
|
zCollist = _rbuObjIterGetIndexCols(tls, p, pIter, bp, bp+8, bp+16, bp+24)
|
|
zBind = _rbuObjIterGetBindlist(tls, p, **(**int32)(__ccgo_up(bp + 24)))
|
|
/* Create the imposter table used to write to this index. */
|
|
Xsqlite3_test_control(tls, int32(SQLITE_TESTCTRL_IMPOSTER), libc.VaList(bp+40, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, __ccgo_ts+6844, 0, int32(1)))
|
|
Xsqlite3_test_control(tls, int32(SQLITE_TESTCTRL_IMPOSTER), libc.VaList(bp+40, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, __ccgo_ts+6844, int32(1), tnum))
|
|
_rbuMPrintfExec(tls, p, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, __ccgo_ts+32297, libc.VaList(bp+40, zTbl, **(**uintptr)(__ccgo_up(bp)), **(**uintptr)(__ccgo_up(bp + 8))))
|
|
Xsqlite3_test_control(tls, int32(SQLITE_TESTCTRL_IMPOSTER), libc.VaList(bp+40, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, __ccgo_ts+6844, 0, 0))
|
|
/* Create the statement to insert index entries */
|
|
(*TRbuObjIter)(unsafe.Pointer(pIter)).FnCol = **(**int32)(__ccgo_up(bp + 24))
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = _prepareFreeAndCollectError(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, pIter+136, p+64, Xsqlite3_mprintf(tls, __ccgo_ts+32362, libc.VaList(bp+40, zTbl, zBind)))
|
|
}
|
|
/* And to delete index entries */
|
|
if libc.BoolInt32((*Tsqlite3rbu)(unsafe.Pointer(p)).FzTarget == uintptr(0)) == 0 && (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = _prepareFreeAndCollectError(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, pIter+144, p+64, Xsqlite3_mprintf(tls, __ccgo_ts+32398, libc.VaList(bp+40, zTbl, **(**uintptr)(__ccgo_up(bp + 16)))))
|
|
}
|
|
/* Create the SELECT statement to read keys in sorted order */
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).FzTarget == uintptr(0) {
|
|
zStart = uintptr(0)
|
|
if nOffset != 0 {
|
|
zStart = _rbuVacuumIndexStart(tls, p, pIter)
|
|
if zStart != 0 {
|
|
Xsqlite3_free(tls, zLimit)
|
|
zLimit = uintptr(0)
|
|
}
|
|
}
|
|
if zStart != 0 {
|
|
if zPart != 0 {
|
|
v2 = __ccgo_ts + 32432
|
|
} else {
|
|
v2 = __ccgo_ts + 32436
|
|
}
|
|
v1 = v2
|
|
} else {
|
|
v1 = __ccgo_ts + 1704
|
|
}
|
|
zSql = Xsqlite3_mprintf(tls, __ccgo_ts+32442, libc.VaList(bp+40, zCollist, (*TRbuObjIter)(unsafe.Pointer(pIter)).FzDataTbl, zPart, v1, zStart, zCollist, zLimit))
|
|
Xsqlite3_free(tls, zStart)
|
|
} else {
|
|
if (*TRbuObjIter)(unsafe.Pointer(pIter)).FeType == int32(RBU_PK_EXTERNAL) || (*TRbuObjIter)(unsafe.Pointer(pIter)).FeType == int32(RBU_PK_NONE) {
|
|
zSql = Xsqlite3_mprintf(tls, __ccgo_ts+32503, libc.VaList(bp+40, zCollist, p+48, (*TRbuObjIter)(unsafe.Pointer(pIter)).FzDataTbl, zPart, zCollist, zLimit))
|
|
} else {
|
|
if zPart != 0 {
|
|
v1 = __ccgo_ts + 32432
|
|
} else {
|
|
v1 = __ccgo_ts + 32436
|
|
}
|
|
zSql = Xsqlite3_mprintf(tls, __ccgo_ts+32564, libc.VaList(bp+40, zCollist, p+48, (*TRbuObjIter)(unsafe.Pointer(pIter)).FzDataTbl, zPart, zCollist, (*TRbuObjIter)(unsafe.Pointer(pIter)).FzDataTbl, zPart, v1, zCollist, zLimit))
|
|
}
|
|
}
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = _prepareFreeAndCollectError(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbRbu, pIter+128, pz, zSql)
|
|
} else {
|
|
Xsqlite3_free(tls, zSql)
|
|
}
|
|
}
|
|
Xsqlite3_free(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
Xsqlite3_free(tls, **(**uintptr)(__ccgo_up(bp + 8)))
|
|
Xsqlite3_free(tls, **(**uintptr)(__ccgo_up(bp + 16)))
|
|
Xsqlite3_free(tls, zBind)
|
|
Xsqlite3_free(tls, zPart)
|
|
} else {
|
|
bRbuRowid = libc.BoolInt32((*TRbuObjIter)(unsafe.Pointer(pIter)).FeType == int32(RBU_PK_VTAB) || (*TRbuObjIter)(unsafe.Pointer(pIter)).FeType == int32(RBU_PK_NONE) || (*TRbuObjIter)(unsafe.Pointer(pIter)).FeType == int32(RBU_PK_EXTERNAL) && (*Tsqlite3rbu)(unsafe.Pointer(p)).FzTarget == uintptr(0))
|
|
zTbl1 = (*TRbuObjIter)(unsafe.Pointer(pIter)).FzTbl /* Imposter table name */
|
|
zBindings = _rbuObjIterGetBindlist(tls, p, (*TRbuObjIter)(unsafe.Pointer(pIter)).FnTblCol+bRbuRowid)
|
|
zWhere1 = _rbuObjIterGetWhere(tls, p, pIter)
|
|
zOldlist = _rbuObjIterGetOldlist(tls, p, pIter, __ccgo_ts+6855)
|
|
zNewlist = _rbuObjIterGetOldlist(tls, p, pIter, __ccgo_ts+6851)
|
|
zCollist = _rbuObjIterGetCollist(tls, p, pIter)
|
|
(*TRbuObjIter)(unsafe.Pointer(pIter)).FnCol = (*TRbuObjIter)(unsafe.Pointer(pIter)).FnTblCol
|
|
/* Create the imposter table or tables (if required). */
|
|
_rbuCreateImposterTable(tls, p, pIter)
|
|
_rbuCreateImposterTable2(tls, p, pIter)
|
|
if (*TRbuObjIter)(unsafe.Pointer(pIter)).FeType == int32(RBU_PK_VTAB) {
|
|
v1 = __ccgo_ts + 1704
|
|
} else {
|
|
v1 = __ccgo_ts + 32723
|
|
}
|
|
zWrite = v1
|
|
/* Create the INSERT statement to write to the target PK b-tree */
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
if bRbuRowid != 0 {
|
|
v1 = __ccgo_ts + 32732
|
|
} else {
|
|
v1 = __ccgo_ts + 1704
|
|
}
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = _prepareFreeAndCollectError(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, pIter+136, pz, Xsqlite3_mprintf(tls, __ccgo_ts+32742, libc.VaList(bp+40, zWrite, zTbl1, zCollist, v1, zBindings)))
|
|
}
|
|
/* Create the DELETE statement to write to the target PK b-tree.
|
|
** Because it only performs INSERT operations, this is not required for
|
|
** an rbu vacuum handle. */
|
|
if libc.BoolInt32((*Tsqlite3rbu)(unsafe.Pointer(p)).FzTarget == uintptr(0)) == 0 && (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = _prepareFreeAndCollectError(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, pIter+144, pz, Xsqlite3_mprintf(tls, __ccgo_ts+32778, libc.VaList(bp+40, zWrite, zTbl1, zWhere1)))
|
|
}
|
|
if libc.BoolInt32((*Tsqlite3rbu)(unsafe.Pointer(p)).FzTarget == uintptr(0)) == 0 && (*TRbuObjIter)(unsafe.Pointer(pIter)).FabIndexed != 0 {
|
|
zRbuRowid = __ccgo_ts + 1704
|
|
if (*TRbuObjIter)(unsafe.Pointer(pIter)).FeType == int32(RBU_PK_EXTERNAL) || (*TRbuObjIter)(unsafe.Pointer(pIter)).FeType == int32(RBU_PK_NONE) {
|
|
zRbuRowid = __ccgo_ts + 32806
|
|
}
|
|
/* Create the rbu_tmp_xxx table and the triggers to populate it. */
|
|
if (*TRbuObjIter)(unsafe.Pointer(pIter)).FeType == int32(RBU_PK_EXTERNAL) {
|
|
v1 = __ccgo_ts + 32818
|
|
} else {
|
|
v1 = __ccgo_ts + 1704
|
|
}
|
|
_rbuMPrintfExec(tls, p, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbRbu, __ccgo_ts+32835, libc.VaList(bp+40, p+48, (*TRbuObjIter)(unsafe.Pointer(pIter)).FzDataTbl, v1, (*TRbuObjIter)(unsafe.Pointer(pIter)).FzDataTbl))
|
|
_rbuMPrintfExec(tls, p, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, __ccgo_ts+32911, libc.VaList(bp+40, zWrite, zTbl1, zOldlist, zWrite, zTbl1, zOldlist, zWrite, zTbl1, zNewlist))
|
|
if (*TRbuObjIter)(unsafe.Pointer(pIter)).FeType == int32(RBU_PK_EXTERNAL) || (*TRbuObjIter)(unsafe.Pointer(pIter)).FeType == int32(RBU_PK_NONE) {
|
|
_rbuMPrintfExec(tls, p, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, __ccgo_ts+33210, libc.VaList(bp+40, zWrite, zTbl1, zNewlist))
|
|
}
|
|
_rbuObjIterPrepareTmpInsert(tls, p, pIter, zCollist, zRbuRowid)
|
|
}
|
|
/* Create the SELECT statement to read keys from data_xxx */
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
zRbuRowid1 = __ccgo_ts + 1704
|
|
zStart1 = uintptr(0)
|
|
zOrder = uintptr(0)
|
|
if bRbuRowid != 0 {
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).FzTarget == uintptr(0) {
|
|
v1 = __ccgo_ts + 33309
|
|
} else {
|
|
v1 = __ccgo_ts + 33319
|
|
}
|
|
zRbuRowid1 = v1
|
|
}
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).FzTarget == uintptr(0) {
|
|
if nOffset != 0 {
|
|
zStart1 = _rbuVacuumTableStart(tls, p, pIter, bRbuRowid, zWrite)
|
|
if zStart1 != 0 {
|
|
Xsqlite3_free(tls, zLimit)
|
|
zLimit = uintptr(0)
|
|
}
|
|
}
|
|
if bRbuRowid != 0 {
|
|
zOrder = _rbuMPrintf(tls, p, __ccgo_ts+31366, 0)
|
|
} else {
|
|
zOrder = _rbuObjIterGetPkList(tls, p, pIter, __ccgo_ts+1704, __ccgo_ts+16242, __ccgo_ts+1704)
|
|
}
|
|
}
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).FzTarget == uintptr(0) {
|
|
v1 = __ccgo_ts + 33330
|
|
} else {
|
|
v1 = __ccgo_ts + 1704
|
|
}
|
|
if zStart1 != 0 {
|
|
v2 = zStart1
|
|
} else {
|
|
v2 = __ccgo_ts + 1704
|
|
}
|
|
if zOrder != 0 {
|
|
v3 = __ccgo_ts + 24878
|
|
} else {
|
|
v3 = __ccgo_ts + 1704
|
|
}
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = _prepareFreeAndCollectError(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbRbu, pIter+128, pz, Xsqlite3_mprintf(tls, __ccgo_ts+33336, libc.VaList(bp+40, zCollist, v1, zRbuRowid1, (*TRbuObjIter)(unsafe.Pointer(pIter)).FzDataTbl, v2, v3, zOrder, zLimit)))
|
|
}
|
|
Xsqlite3_free(tls, zStart1)
|
|
Xsqlite3_free(tls, zOrder)
|
|
}
|
|
Xsqlite3_free(tls, zWhere1)
|
|
Xsqlite3_free(tls, zOldlist)
|
|
Xsqlite3_free(tls, zNewlist)
|
|
Xsqlite3_free(tls, zBindings)
|
|
}
|
|
Xsqlite3_free(tls, zCollist)
|
|
Xsqlite3_free(tls, zLimit)
|
|
}
|
|
return (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Prepare a statement used to insert rows into the "rbu_tmp_xxx" table.
|
|
// ** Specifically a statement of the form:
|
|
// **
|
|
// ** INSERT INTO rbu_tmp_xxx VALUES(?, ?, ? ...);
|
|
// **
|
|
// ** The number of bound variables is equal to the number of columns in
|
|
// ** the target table, plus one (for the rbu_control column), plus one more
|
|
// ** (for the rbu_rowid column) if the target table is an implicit IPK or
|
|
// ** virtual table.
|
|
// */
|
|
func _rbuObjIterPrepareTmpInsert(tls *libc.TLS, p uintptr, pIter uintptr, zCollist uintptr, zRbuRowid uintptr) {
|
|
bp := tls.Alloc(48)
|
|
defer tls.Free(48)
|
|
var bRbuRowid int32
|
|
var zBind uintptr
|
|
_, _ = bRbuRowid, zBind
|
|
bRbuRowid = libc.BoolInt32((*TRbuObjIter)(unsafe.Pointer(pIter)).FeType == int32(RBU_PK_EXTERNAL) || (*TRbuObjIter)(unsafe.Pointer(pIter)).FeType == int32(RBU_PK_NONE))
|
|
zBind = _rbuObjIterGetBindlist(tls, p, (*TRbuObjIter)(unsafe.Pointer(pIter)).FnTblCol+int32(1)+bRbuRowid)
|
|
if zBind != 0 {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = _prepareFreeAndCollectError(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbRbu, pIter+152, p+64, Xsqlite3_mprintf(tls, __ccgo_ts+32154, libc.VaList(bp+8, p+48, (*TRbuObjIter)(unsafe.Pointer(pIter)).FzDataTbl, zCollist, zRbuRowid, zBind)))
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Update the contents of the rbu_state table within the rbu database. The
|
|
// ** value stored in the RBU_STATE_STAGE column is eStage. All other values
|
|
// ** are determined by inspecting the rbu handle passed as the first argument.
|
|
// */
|
|
func _rbuSaveState(tls *libc.TLS, p uintptr, eStage int32) {
|
|
bp := tls.Alloc(192)
|
|
defer tls.Free(192)
|
|
var pFd, v1 uintptr
|
|
var rc int32
|
|
var _ /* pInsert at bp+0 */ uintptr
|
|
_, _, _ = pFd, rc, v1
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK || (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == int32(SQLITE_DONE) {
|
|
**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).FzTarget == uintptr(0) {
|
|
v1 = (*Tsqlite3rbu)(unsafe.Pointer(p)).FpRbuFd
|
|
} else {
|
|
v1 = (*Tsqlite3rbu)(unsafe.Pointer(p)).FpTargetFd
|
|
}
|
|
pFd = v1
|
|
rc = _prepareFreeAndCollectError(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbRbu, bp, p+64, Xsqlite3_mprintf(tls, __ccgo_ts+33839, libc.VaList(bp+16, p+48, int32(RBU_STATE_STAGE), eStage, int32(RBU_STATE_TBL), (*Tsqlite3rbu)(unsafe.Pointer(p)).Fobjiter.FzTbl, int32(RBU_STATE_IDX), (*Tsqlite3rbu)(unsafe.Pointer(p)).Fobjiter.FzIdx, int32(RBU_STATE_ROW), (*Tsqlite3rbu)(unsafe.Pointer(p)).FnStep, int32(RBU_STATE_PROGRESS), (*Tsqlite3rbu)(unsafe.Pointer(p)).FnProgress, int32(RBU_STATE_CKPT), (*Tsqlite3rbu)(unsafe.Pointer(p)).FiWalCksum, int32(RBU_STATE_COOKIE), libc.Int64FromUint32((*Trbu_file)(unsafe.Pointer(pFd)).FiCookie), int32(RBU_STATE_OALSZ), (*Tsqlite3rbu)(unsafe.Pointer(p)).FiOalSz, int32(RBU_STATE_PHASEONESTEP), (*Tsqlite3rbu)(unsafe.Pointer(p)).FnPhaseOneStep, int32(RBU_STATE_DATATBL), (*Tsqlite3rbu)(unsafe.Pointer(p)).Fobjiter.FzDataTbl)))
|
|
if rc == SQLITE_OK {
|
|
Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
rc = Xsqlite3_finalize(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
}
|
|
if rc != SQLITE_OK {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = rc
|
|
}
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This function is called as part of sqlite3rbu_open() when initializing
|
|
// ** an rbu handle in OAL stage. If the rbu update has not started (i.e.
|
|
// ** the rbu_state table was empty) it is a no-op. Otherwise, it arranges
|
|
// ** things so that the next call to sqlite3rbu_step() continues on from
|
|
// ** where the previous rbu handle left off.
|
|
// **
|
|
// ** If an error occurs, an error code and error message are left in the
|
|
// ** rbu handle passed as the first argument.
|
|
// */
|
|
func _rbuSetupOal(tls *libc.TLS, p uintptr, pState uintptr) {
|
|
var pIter uintptr
|
|
var rc int32
|
|
_, _ = pIter, rc
|
|
if (*TRbuState)(unsafe.Pointer(pState)).FzTbl != 0 {
|
|
pIter = p + 88
|
|
rc = SQLITE_OK
|
|
for rc == SQLITE_OK && (*TRbuObjIter)(unsafe.Pointer(pIter)).FzTbl != 0 && ((*TRbuObjIter)(unsafe.Pointer(pIter)).FbCleanup != 0 || _rbuStrCompare(tls, (*TRbuObjIter)(unsafe.Pointer(pIter)).FzIdx, (*TRbuState)(unsafe.Pointer(pState)).FzIdx) != 0 || (*TRbuState)(unsafe.Pointer(pState)).FzDataTbl == uintptr(0) && _rbuStrCompare(tls, (*TRbuObjIter)(unsafe.Pointer(pIter)).FzTbl, (*TRbuState)(unsafe.Pointer(pState)).FzTbl) != 0 || (*TRbuState)(unsafe.Pointer(pState)).FzDataTbl != 0 && _rbuStrCompare(tls, (*TRbuObjIter)(unsafe.Pointer(pIter)).FzDataTbl, (*TRbuState)(unsafe.Pointer(pState)).FzDataTbl) != 0) {
|
|
rc = _rbuObjIterNext(tls, p, pIter)
|
|
}
|
|
if rc == SQLITE_OK && !((*TRbuObjIter)(unsafe.Pointer(pIter)).FzTbl != 0) {
|
|
rc = int32(SQLITE_ERROR)
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).FzErrmsg = Xsqlite3_mprintf(tls, __ccgo_ts+34329, 0)
|
|
}
|
|
if rc == SQLITE_OK {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).FnStep = (*TRbuState)(unsafe.Pointer(pState)).FnRow
|
|
rc = _rbuObjIterPrepareAll(tls, p, p+88, (*Tsqlite3rbu)(unsafe.Pointer(p)).FnStep)
|
|
}
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = rc
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Argument eType must be one of RBU_INSERT, RBU_DELETE, RBU_IDX_INSERT or
|
|
// ** RBU_IDX_DELETE. This function performs the work of a single
|
|
// ** sqlite3rbu_step() call for the type of operation specified by eType.
|
|
// */
|
|
func _rbuStepOneOp(tls *libc.TLS, p uintptr, eType int32) {
|
|
var i int32
|
|
var pIter, pVal, pWriter uintptr
|
|
_, _, _, _ = i, pIter, pVal, pWriter
|
|
pIter = p + 88
|
|
/* If this is a delete, decrement nPhaseOneStep by nIndex. If the DELETE
|
|
** statement below does actually delete a row, nPhaseOneStep will be
|
|
** incremented by the same amount when SQL function rbu_tmp_insert()
|
|
** is invoked by the trigger. */
|
|
if eType == int32(RBU_DELETE) {
|
|
**(**Ti64)(__ccgo_up(p + 312)) -= int64((*Tsqlite3rbu)(unsafe.Pointer(p)).Fobjiter.FnIndex)
|
|
}
|
|
if eType == int32(RBU_IDX_DELETE) || eType == int32(RBU_DELETE) {
|
|
pWriter = (*TRbuObjIter)(unsafe.Pointer(pIter)).FpDelete
|
|
} else {
|
|
pWriter = (*TRbuObjIter)(unsafe.Pointer(pIter)).FpInsert
|
|
}
|
|
i = 0
|
|
for {
|
|
if !(i < (*TRbuObjIter)(unsafe.Pointer(pIter)).FnCol) {
|
|
break
|
|
}
|
|
/* If this is an INSERT into a table b-tree and the table has an
|
|
** explicit INTEGER PRIMARY KEY, check that this is not an attempt
|
|
** to write a NULL into the IPK column. That is not permitted. */
|
|
if eType == int32(RBU_INSERT) && (*TRbuObjIter)(unsafe.Pointer(pIter)).FzIdx == uintptr(0) && (*TRbuObjIter)(unsafe.Pointer(pIter)).FeType == int32(RBU_PK_IPK) && **(**Tu8)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FabTblPk + uintptr(i))) != 0 && Xsqlite3_column_type(tls, (*TRbuObjIter)(unsafe.Pointer(pIter)).FpSelect, i) == int32(SQLITE_NULL) {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = int32(SQLITE_MISMATCH)
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).FzErrmsg = Xsqlite3_mprintf(tls, __ccgo_ts+25699, 0)
|
|
return
|
|
}
|
|
if eType == int32(RBU_DELETE) && libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FabTblPk + uintptr(i)))) == 0 {
|
|
goto _1
|
|
}
|
|
pVal = Xsqlite3_column_value(tls, (*TRbuObjIter)(unsafe.Pointer(pIter)).FpSelect, i)
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = Xsqlite3_bind_value(tls, pWriter, i+int32(1), pVal)
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc != 0 {
|
|
return
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
if (*TRbuObjIter)(unsafe.Pointer(pIter)).FzIdx == uintptr(0) {
|
|
if (*TRbuObjIter)(unsafe.Pointer(pIter)).FeType == int32(RBU_PK_VTAB) || (*TRbuObjIter)(unsafe.Pointer(pIter)).FeType == int32(RBU_PK_NONE) || (*TRbuObjIter)(unsafe.Pointer(pIter)).FeType == int32(RBU_PK_EXTERNAL) && (*Tsqlite3rbu)(unsafe.Pointer(p)).FzTarget == uintptr(0) {
|
|
/* For a virtual table, or a table with no primary key, the
|
|
** SELECT statement is:
|
|
**
|
|
** SELECT <cols>, rbu_control, rbu_rowid FROM ....
|
|
**
|
|
** Hence column_value(pIter->nCol+1).
|
|
*/
|
|
pVal = Xsqlite3_column_value(tls, (*TRbuObjIter)(unsafe.Pointer(pIter)).FpSelect, (*TRbuObjIter)(unsafe.Pointer(pIter)).FnCol+int32(1))
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = Xsqlite3_bind_value(tls, pWriter, (*TRbuObjIter)(unsafe.Pointer(pIter)).FnCol+int32(1), pVal)
|
|
}
|
|
}
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
Xsqlite3_step(tls, pWriter)
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = _resetAndCollectError(tls, pWriter, p+64)
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /* Determine the type of a table.
|
|
// **
|
|
// ** peType is of type (int*), a pointer to an output parameter of type
|
|
// ** (int). This call sets the output parameter as follows, depending
|
|
// ** on the type of the table specified by parameters dbName and zTbl.
|
|
// **
|
|
// ** RBU_PK_NOTABLE: No such table.
|
|
// ** RBU_PK_NONE: Table has an implicit rowid.
|
|
// ** RBU_PK_IPK: Table has an explicit IPK column.
|
|
// ** RBU_PK_EXTERNAL: Table has an external PK index.
|
|
// ** RBU_PK_WITHOUT_ROWID: Table is WITHOUT ROWID.
|
|
// ** RBU_PK_VTAB: Table is a virtual table.
|
|
// **
|
|
// ** Argument *piPk is also of type (int*), and also points to an output
|
|
// ** parameter. Unless the table has an external primary key index
|
|
// ** (i.e. unless *peType is set to 3), then *piPk is set to zero. Or,
|
|
// ** if the table does have an external primary key index, then *piPk
|
|
// ** is set to the root page number of the primary key index before
|
|
// ** returning.
|
|
// **
|
|
// ** ALGORITHM:
|
|
// **
|
|
// ** if( no entry exists in sqlite_schema ){
|
|
// ** return RBU_PK_NOTABLE
|
|
// ** }else if( sql for the entry starts with "CREATE VIRTUAL" ){
|
|
// ** return RBU_PK_VTAB
|
|
// ** }else if( "PRAGMA index_list()" for the table contains a "pk" index ){
|
|
// ** if( the index that is the pk exists in sqlite_schema ){
|
|
// ** *piPK = rootpage of that index.
|
|
// ** return RBU_PK_EXTERNAL
|
|
// ** }else{
|
|
// ** return RBU_PK_WITHOUT_ROWID
|
|
// ** }
|
|
// ** }else if( "PRAGMA table_info()" lists one or more "pk" columns ){
|
|
// ** return RBU_PK_IPK
|
|
// ** }else{
|
|
// ** return RBU_PK_NONE
|
|
// ** }
|
|
// */
|
|
func _rbuTableType(tls *libc.TLS, p uintptr, zTab uintptr, peType uintptr, piTnum uintptr, piPk uintptr) {
|
|
bp := tls.Alloc(48)
|
|
defer tls.Free(48)
|
|
var i uint32
|
|
var zIdx, zOrig uintptr
|
|
var _ /* aStmt at bp+0 */ [4]uintptr
|
|
_, _, _ = i, zIdx, zOrig
|
|
/*
|
|
** 0) SELECT count(*) FROM sqlite_schema where name=%Q AND IsVirtual(%Q)
|
|
** 1) PRAGMA index_list = ?
|
|
** 2) SELECT count(*) FROM sqlite_schema where name=%Q
|
|
** 3) PRAGMA table_info = ?
|
|
*/
|
|
**(**[4]uintptr)(__ccgo_up(bp)) = [4]uintptr{}
|
|
**(**int32)(__ccgo_up(peType)) = RBU_PK_NOTABLE
|
|
**(**int32)(__ccgo_up(piPk)) = 0
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = _prepareFreeAndCollectError(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, bp, p+64, Xsqlite3_mprintf(tls, __ccgo_ts+30803, libc.VaList(bp+40, zTab)))
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc != SQLITE_OK || Xsqlite3_step(tls, (**(**[4]uintptr)(__ccgo_up(bp)))[0]) != int32(SQLITE_ROW) {
|
|
/* Either an error, or no such table. */
|
|
goto rbuTableType_end
|
|
}
|
|
if Xsqlite3_column_int(tls, (**(**[4]uintptr)(__ccgo_up(bp)))[0], 0) != 0 {
|
|
**(**int32)(__ccgo_up(peType)) = int32(RBU_PK_VTAB) /* virtual table */
|
|
goto rbuTableType_end
|
|
}
|
|
**(**int32)(__ccgo_up(piTnum)) = Xsqlite3_column_int(tls, (**(**[4]uintptr)(__ccgo_up(bp)))[0], int32(1))
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = _prepareFreeAndCollectError(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, bp+1*8, p+64, Xsqlite3_mprintf(tls, __ccgo_ts+30922, libc.VaList(bp+40, zTab)))
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc != 0 {
|
|
goto rbuTableType_end
|
|
}
|
|
for Xsqlite3_step(tls, (**(**[4]uintptr)(__ccgo_up(bp)))[int32(1)]) == int32(SQLITE_ROW) {
|
|
zOrig = Xsqlite3_column_text(tls, (**(**[4]uintptr)(__ccgo_up(bp)))[int32(1)], int32(3))
|
|
zIdx = Xsqlite3_column_text(tls, (**(**[4]uintptr)(__ccgo_up(bp)))[int32(1)], int32(1))
|
|
if zOrig != 0 && zIdx != 0 && libc.Int32FromUint8(**(**Tu8)(__ccgo_up(zOrig))) == int32('p') {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = _prepareFreeAndCollectError(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, bp+2*8, p+64, Xsqlite3_mprintf(tls, __ccgo_ts+30943, libc.VaList(bp+40, zIdx)))
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
if Xsqlite3_step(tls, (**(**[4]uintptr)(__ccgo_up(bp)))[int32(2)]) == int32(SQLITE_ROW) {
|
|
**(**int32)(__ccgo_up(piPk)) = Xsqlite3_column_int(tls, (**(**[4]uintptr)(__ccgo_up(bp)))[int32(2)], 0)
|
|
**(**int32)(__ccgo_up(peType)) = int32(RBU_PK_EXTERNAL)
|
|
} else {
|
|
**(**int32)(__ccgo_up(peType)) = int32(RBU_PK_WITHOUT_ROWID)
|
|
}
|
|
}
|
|
goto rbuTableType_end
|
|
}
|
|
}
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = _prepareFreeAndCollectError(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, bp+3*8, p+64, Xsqlite3_mprintf(tls, __ccgo_ts+30994, libc.VaList(bp+40, zTab)))
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
for Xsqlite3_step(tls, (**(**[4]uintptr)(__ccgo_up(bp)))[int32(3)]) == int32(SQLITE_ROW) {
|
|
if Xsqlite3_column_int(tls, (**(**[4]uintptr)(__ccgo_up(bp)))[int32(3)], int32(5)) > 0 {
|
|
**(**int32)(__ccgo_up(peType)) = int32(RBU_PK_IPK) /* explicit IPK column */
|
|
goto rbuTableType_end
|
|
}
|
|
}
|
|
**(**int32)(__ccgo_up(peType)) = int32(RBU_PK_NONE)
|
|
}
|
|
goto rbuTableType_end
|
|
rbuTableType_end:
|
|
;
|
|
i = uint32(0)
|
|
for {
|
|
if !(uint64(i) < libc.Uint64FromInt64(32)/libc.Uint64FromInt64(8)) {
|
|
break
|
|
}
|
|
_rbuFinalize(tls, p, (**(**[4]uintptr)(__ccgo_up(bp)))[i])
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This function is called as part of restarting an RBU vacuum within
|
|
// ** stage 1 of the process (while the *-oal file is being built) while
|
|
// ** updating a table (not an index). The table may be a rowid table or
|
|
// ** a WITHOUT ROWID table. It queries the target database to find the
|
|
// ** largest key that has already been written to the target table and
|
|
// ** constructs a WHERE clause that can be used to extract the remaining
|
|
// ** rows from the source table. For a rowid table, the WHERE clause
|
|
// ** is of the form:
|
|
// **
|
|
// ** "WHERE _rowid_ > ?"
|
|
// **
|
|
// ** and for WITHOUT ROWID tables:
|
|
// **
|
|
// ** "WHERE (key1, key2) > (?, ?)"
|
|
// **
|
|
// ** Instead of "?" placeholders, the actual WHERE clauses created by
|
|
// ** this function contain literal SQL values.
|
|
// */
|
|
func _rbuVacuumTableStart(tls *libc.TLS, p uintptr, pIter uintptr, bRowid int32, zWrite uintptr) (r uintptr) {
|
|
bp := tls.Alloc(48)
|
|
defer tls.Free(48)
|
|
var iMax Tsqlite3_int64
|
|
var zList, zOrder, zRet, zSelect, zVal uintptr
|
|
var _ /* pMax at bp+0 */ uintptr
|
|
_, _, _, _, _, _ = iMax, zList, zOrder, zRet, zSelect, zVal
|
|
**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
|
|
zRet = uintptr(0)
|
|
if bRowid != 0 {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = _prepareFreeAndCollectError(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, bp, p+64, Xsqlite3_mprintf(tls, __ccgo_ts+31228, libc.VaList(bp+16, zWrite, (*TRbuObjIter)(unsafe.Pointer(pIter)).FzTbl)))
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK && int32(SQLITE_ROW) == Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp))) {
|
|
iMax = Xsqlite3_column_int64(tls, **(**uintptr)(__ccgo_up(bp)), 0)
|
|
zRet = _rbuMPrintf(tls, p, __ccgo_ts+31260, libc.VaList(bp+16, iMax))
|
|
}
|
|
_rbuFinalize(tls, p, **(**uintptr)(__ccgo_up(bp)))
|
|
} else {
|
|
zOrder = _rbuObjIterGetPkList(tls, p, pIter, __ccgo_ts+1704, __ccgo_ts+16242, __ccgo_ts+31283)
|
|
zSelect = _rbuObjIterGetPkList(tls, p, pIter, __ccgo_ts+31289, __ccgo_ts+31296, __ccgo_ts+5285)
|
|
zList = _rbuObjIterGetPkList(tls, p, pIter, __ccgo_ts+1704, __ccgo_ts+16242, __ccgo_ts+1704)
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = _prepareFreeAndCollectError(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, bp, p+64, Xsqlite3_mprintf(tls, __ccgo_ts+31304, libc.VaList(bp+16, zSelect, zWrite, (*TRbuObjIter)(unsafe.Pointer(pIter)).FzTbl, zOrder)))
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK && int32(SQLITE_ROW) == Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp))) {
|
|
zVal = Xsqlite3_column_text(tls, **(**uintptr)(__ccgo_up(bp)), 0)
|
|
zRet = _rbuMPrintf(tls, p, __ccgo_ts+31346, libc.VaList(bp+16, zList, zVal))
|
|
}
|
|
_rbuFinalize(tls, p, **(**uintptr)(__ccgo_up(bp)))
|
|
}
|
|
Xsqlite3_free(tls, zOrder)
|
|
Xsqlite3_free(tls, zSelect)
|
|
Xsqlite3_free(tls, zList)
|
|
}
|
|
return zRet
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** The iterator currently points to a table (not index) of type
|
|
// ** RBU_PK_WITHOUT_ROWID. This function creates the PRIMARY KEY
|
|
// ** declaration for the corresponding imposter table. For example,
|
|
// ** if the iterator points to a table created as:
|
|
// **
|
|
// ** CREATE TABLE t1(a, b, c, PRIMARY KEY(b, a DESC)) WITHOUT ROWID
|
|
// **
|
|
// ** this function returns:
|
|
// **
|
|
// ** PRIMARY KEY("b", "a" DESC)
|
|
// */
|
|
func _rbuWithoutRowidPK(tls *libc.TLS, p uintptr, pIter uintptr) (r uintptr) {
|
|
bp := tls.Alloc(64)
|
|
defer tls.Free(64)
|
|
var z, zCol, zDesc, zIdx, zOrig, zSep, v1 uintptr
|
|
var _ /* pXInfo at bp+8 */ uintptr
|
|
var _ /* pXList at bp+0 */ uintptr
|
|
_, _, _, _, _, _, _ = z, zCol, zDesc, zIdx, zOrig, zSep, v1
|
|
z = uintptr(0)
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
zSep = __ccgo_ts + 31863
|
|
**(**uintptr)(__ccgo_up(bp)) = uintptr(0) /* PRAGMA index_list = (pIter->zTbl) */
|
|
**(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0) /* PRAGMA index_xinfo = <pk-index> */
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = _prepareFreeAndCollectError(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, bp, p+64, Xsqlite3_mprintf(tls, __ccgo_ts+31015, libc.VaList(bp+24, (*TRbuObjIter)(unsafe.Pointer(pIter)).FzTbl)))
|
|
for (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK && int32(SQLITE_ROW) == Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp))) {
|
|
zOrig = Xsqlite3_column_text(tls, **(**uintptr)(__ccgo_up(bp)), int32(3))
|
|
if zOrig != 0 && libc.Xstrcmp(tls, zOrig, __ccgo_ts+17879) == 0 {
|
|
zIdx = Xsqlite3_column_text(tls, **(**uintptr)(__ccgo_up(bp)), int32(1))
|
|
if zIdx != 0 {
|
|
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = _prepareFreeAndCollectError(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, bp+8, p+64, Xsqlite3_mprintf(tls, __ccgo_ts+31043, libc.VaList(bp+24, zIdx)))
|
|
}
|
|
break
|
|
}
|
|
}
|
|
_rbuFinalize(tls, p, **(**uintptr)(__ccgo_up(bp)))
|
|
for (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK && int32(SQLITE_ROW) == Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp + 8))) {
|
|
if Xsqlite3_column_int(tls, **(**uintptr)(__ccgo_up(bp + 8)), int32(5)) != 0 {
|
|
/* int iCid = sqlite3_column_int(pXInfo, 0); */
|
|
zCol = Xsqlite3_column_text(tls, **(**uintptr)(__ccgo_up(bp + 8)), int32(2))
|
|
if Xsqlite3_column_int(tls, **(**uintptr)(__ccgo_up(bp + 8)), int32(3)) != 0 {
|
|
v1 = __ccgo_ts + 31283
|
|
} else {
|
|
v1 = __ccgo_ts + 1704
|
|
}
|
|
zDesc = v1
|
|
z = _rbuMPrintf(tls, p, __ccgo_ts+31876, libc.VaList(bp+24, z, zSep, zCol, zDesc))
|
|
zSep = __ccgo_ts + 16242
|
|
}
|
|
}
|
|
z = _rbuMPrintf(tls, p, __ccgo_ts+31887, libc.VaList(bp+24, z))
|
|
_rbuFinalize(tls, p, **(**uintptr)(__ccgo_up(bp + 8)))
|
|
}
|
|
return z
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** SQL function:
|
|
// **
|
|
// ** sqlite_rename_column(SQL,TYPE,OBJ,DB,TABLE,COL,NEWNAME,QUOTE,TEMP)
|
|
// **
|
|
// ** 0. zSql: SQL statement to rewrite
|
|
// ** 1. type: Type of object ("table", "view" etc.)
|
|
// ** 2. object: Name of object
|
|
// ** 3. Database: Database name (e.g. "main")
|
|
// ** 4. Table: Table name
|
|
// ** 5. iCol: Index of column to rename
|
|
// ** 6. zNew: New column name
|
|
// ** 7. bQuote: Non-zero if the new column name should be quoted.
|
|
// ** 8. bTemp: True if zSql comes from temp schema
|
|
// **
|
|
// ** Do a column rename operation on the CREATE statement given in zSql.
|
|
// ** The iCol-th column (left-most is 0) of table zTable is renamed from zCol
|
|
// ** into zNew. The name should be quoted if bQuote is true.
|
|
// **
|
|
// ** This function is used internally by the ALTER TABLE RENAME COLUMN command.
|
|
// ** It is only accessible to SQL created using sqlite3NestedParse(). It is
|
|
// ** not reachable from ordinary SQL passed into sqlite3_prepare() unless the
|
|
// ** SQLITE_TESTCTRL_INTERNAL_FUNCTIONS test setting is enabled.
|
|
// */
|
|
func _renameColumnFunc(tls *libc.TLS, context uintptr, NotUsed int32, argv uintptr) {
|
|
bp := tls.Alloc(512)
|
|
defer tls.Free(512)
|
|
var bFKOnly, bQuote, bTemp, i, iCol, rc, v1 int32
|
|
var db, pExpr, pFKey, pIdx, pSelect, pStep, pTab, pTarget, pUpsertSet, zDb, zNew, zOld, zSql, zTable uintptr
|
|
var xAuth Tsqlite3_xauth
|
|
var _ /* sCtx at bp+0 */ TRenameCtx
|
|
var _ /* sParse at bp+32 */ TParse
|
|
var _ /* sWalker at bp+456 */ TWalker
|
|
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = bFKOnly, bQuote, bTemp, db, i, iCol, pExpr, pFKey, pIdx, pSelect, pStep, pTab, pTarget, pUpsertSet, rc, xAuth, zDb, zNew, zOld, zSql, zTable, v1
|
|
db = Xsqlite3_context_db_handle(tls, context)
|
|
zSql = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv)))
|
|
zDb = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv + 3*8)))
|
|
zTable = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv + 4*8)))
|
|
iCol = Xsqlite3_value_int(tls, **(**uintptr)(__ccgo_up(argv + 5*8)))
|
|
zNew = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv + 6*8)))
|
|
bQuote = Xsqlite3_value_int(tls, **(**uintptr)(__ccgo_up(argv + 7*8)))
|
|
bTemp = Xsqlite3_value_int(tls, **(**uintptr)(__ccgo_up(argv + 8*8)))
|
|
xAuth = (*Tsqlite3)(unsafe.Pointer(db)).FxAuth
|
|
_ = NotUsed
|
|
if zSql == uintptr(0) {
|
|
return
|
|
}
|
|
if zTable == uintptr(0) {
|
|
return
|
|
}
|
|
if zNew == uintptr(0) {
|
|
return
|
|
}
|
|
if iCol < 0 {
|
|
return
|
|
}
|
|
_sqlite3BtreeEnterAll(tls, db)
|
|
pTab = _sqlite3FindTable(tls, db, zTable, zDb)
|
|
if pTab == uintptr(0) || iCol >= int32((*TTable)(unsafe.Pointer(pTab)).FnCol) {
|
|
_sqlite3BtreeLeaveAll(tls, db)
|
|
return
|
|
}
|
|
zOld = (**(**TColumn)(__ccgo_up((*TTable)(unsafe.Pointer(pTab)).FaCol + uintptr(iCol)*16))).FzCnName
|
|
libc.Xmemset(tls, bp, 0, uint64(32))
|
|
if iCol == int32((*TTable)(unsafe.Pointer(pTab)).FiPKey) {
|
|
v1 = -int32(1)
|
|
} else {
|
|
v1 = iCol
|
|
}
|
|
(**(**TRenameCtx)(__ccgo_up(bp))).FiCol = v1
|
|
(*Tsqlite3)(unsafe.Pointer(db)).FxAuth = uintptr(0)
|
|
rc = _renameParseSql(tls, bp+32, zDb, db, zSql, bTemp)
|
|
/* Find tokens that need to be replaced. */
|
|
libc.Xmemset(tls, bp+456, 0, uint64(48))
|
|
(**(**TWalker)(__ccgo_up(bp + 456))).FpParse = bp + 32
|
|
(**(**TWalker)(__ccgo_up(bp + 456))).FxExprCallback = __ccgo_fp(_renameColumnExprCb)
|
|
(**(**TWalker)(__ccgo_up(bp + 456))).FxSelectCallback = __ccgo_fp(_renameColumnSelectCb)
|
|
*(*uintptr)(unsafe.Pointer(bp + 456 + 40)) = bp
|
|
(**(**TRenameCtx)(__ccgo_up(bp))).FpTab = pTab
|
|
if rc != SQLITE_OK {
|
|
goto renameColumnFunc_done
|
|
}
|
|
if (**(**TParse)(__ccgo_up(bp + 32))).FpNewTable != 0 {
|
|
if libc.Int32FromUint8((*TTable)(unsafe.Pointer((**(**TParse)(__ccgo_up(bp + 32))).FpNewTable)).FeTabType) == int32(TABTYP_VIEW) {
|
|
pSelect = (*(*struct {
|
|
FpSelect uintptr
|
|
})(unsafe.Pointer(&(*TTable)(unsafe.Pointer((**(**TParse)(__ccgo_up(bp + 32))).FpNewTable)).Fu))).FpSelect
|
|
**(**Tu32)(__ccgo_up(pSelect + 4)) &= ^libc.Uint32FromInt32(SF_View)
|
|
(**(**TParse)(__ccgo_up(bp + 32))).Frc = SQLITE_OK
|
|
_sqlite3SelectPrep(tls, bp+32, pSelect, uintptr(0))
|
|
if (*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0 {
|
|
v1 = int32(SQLITE_NOMEM)
|
|
} else {
|
|
v1 = (**(**TParse)(__ccgo_up(bp + 32))).Frc
|
|
}
|
|
rc = v1
|
|
if rc == SQLITE_OK {
|
|
_sqlite3WalkSelect(tls, bp+456, pSelect)
|
|
}
|
|
if rc != SQLITE_OK {
|
|
goto renameColumnFunc_done
|
|
}
|
|
} else {
|
|
if libc.Int32FromUint8((*TTable)(unsafe.Pointer((**(**TParse)(__ccgo_up(bp + 32))).FpNewTable)).FeTabType) == TABTYP_NORM {
|
|
/* A regular table */
|
|
bFKOnly = Xsqlite3_stricmp(tls, zTable, (*TTable)(unsafe.Pointer((**(**TParse)(__ccgo_up(bp + 32))).FpNewTable)).FzName)
|
|
(**(**TRenameCtx)(__ccgo_up(bp))).FpTab = (**(**TParse)(__ccgo_up(bp + 32))).FpNewTable
|
|
if bFKOnly == 0 {
|
|
if iCol < int32((*TTable)(unsafe.Pointer((**(**TParse)(__ccgo_up(bp + 32))).FpNewTable)).FnCol) {
|
|
_renameTokenFind(tls, bp+32, bp, (**(**TColumn)(__ccgo_up((*TTable)(unsafe.Pointer((**(**TParse)(__ccgo_up(bp + 32))).FpNewTable)).FaCol + uintptr(iCol)*16))).FzCnName)
|
|
}
|
|
if (**(**TRenameCtx)(__ccgo_up(bp))).FiCol < 0 {
|
|
_renameTokenFind(tls, bp+32, bp, (**(**TParse)(__ccgo_up(bp + 32))).FpNewTable+52)
|
|
}
|
|
_sqlite3WalkExprList(tls, bp+456, (*TTable)(unsafe.Pointer((**(**TParse)(__ccgo_up(bp + 32))).FpNewTable)).FpCheck)
|
|
pIdx = (*TTable)(unsafe.Pointer((**(**TParse)(__ccgo_up(bp + 32))).FpNewTable)).FpIndex
|
|
for {
|
|
if !(pIdx != 0) {
|
|
break
|
|
}
|
|
_sqlite3WalkExprList(tls, bp+456, (*TIndex)(unsafe.Pointer(pIdx)).FaColExpr)
|
|
goto _3
|
|
_3:
|
|
;
|
|
pIdx = (*TIndex)(unsafe.Pointer(pIdx)).FpNext
|
|
}
|
|
pIdx = (**(**TParse)(__ccgo_up(bp + 32))).FpNewIndex
|
|
for {
|
|
if !(pIdx != 0) {
|
|
break
|
|
}
|
|
_sqlite3WalkExprList(tls, bp+456, (*TIndex)(unsafe.Pointer(pIdx)).FaColExpr)
|
|
goto _4
|
|
_4:
|
|
;
|
|
pIdx = (*TIndex)(unsafe.Pointer(pIdx)).FpNext
|
|
}
|
|
i = 0
|
|
for {
|
|
if !(i < int32((*TTable)(unsafe.Pointer((**(**TParse)(__ccgo_up(bp + 32))).FpNewTable)).FnCol)) {
|
|
break
|
|
}
|
|
pExpr = _sqlite3ColumnExpr(tls, (**(**TParse)(__ccgo_up(bp + 32))).FpNewTable, (*TTable)(unsafe.Pointer((**(**TParse)(__ccgo_up(bp + 32))).FpNewTable)).FaCol+uintptr(i)*16)
|
|
_sqlite3WalkExpr(tls, bp+456, pExpr)
|
|
goto _5
|
|
_5:
|
|
;
|
|
i = i + 1
|
|
}
|
|
}
|
|
pFKey = (*(*struct {
|
|
FaddColOffset int32
|
|
FpFKey uintptr
|
|
FpDfltList uintptr
|
|
})(unsafe.Pointer((**(**TParse)(__ccgo_up(bp + 32))).FpNewTable + 64))).FpFKey
|
|
for {
|
|
if !(pFKey != 0) {
|
|
break
|
|
}
|
|
i = 0
|
|
for {
|
|
if !(i < (*TFKey)(unsafe.Pointer(pFKey)).FnCol) {
|
|
break
|
|
}
|
|
if bFKOnly == 0 && (*(*TsColMap)(unsafe.Pointer(pFKey + 64 + uintptr(i)*16))).FiFrom == iCol {
|
|
_renameTokenFind(tls, bp+32, bp, pFKey+64+uintptr(i)*16)
|
|
}
|
|
if 0 == Xsqlite3_stricmp(tls, (*TFKey)(unsafe.Pointer(pFKey)).FzTo, zTable) && 0 == Xsqlite3_stricmp(tls, (*(*TsColMap)(unsafe.Pointer(pFKey + 64 + uintptr(i)*16))).FzCol, zOld) {
|
|
_renameTokenFind(tls, bp+32, bp, (*(*TsColMap)(unsafe.Pointer(pFKey + 64 + uintptr(i)*16))).FzCol)
|
|
}
|
|
goto _7
|
|
_7:
|
|
;
|
|
i = i + 1
|
|
}
|
|
goto _6
|
|
_6:
|
|
;
|
|
pFKey = (*TFKey)(unsafe.Pointer(pFKey)).FpNextFrom
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
if (**(**TParse)(__ccgo_up(bp + 32))).FpNewIndex != 0 {
|
|
_sqlite3WalkExprList(tls, bp+456, (*TIndex)(unsafe.Pointer((**(**TParse)(__ccgo_up(bp + 32))).FpNewIndex)).FaColExpr)
|
|
_sqlite3WalkExpr(tls, bp+456, (*TIndex)(unsafe.Pointer((**(**TParse)(__ccgo_up(bp + 32))).FpNewIndex)).FpPartIdxWhere)
|
|
} else {
|
|
rc = _renameResolveTrigger(tls, bp+32)
|
|
if rc != SQLITE_OK {
|
|
goto renameColumnFunc_done
|
|
}
|
|
pStep = (*TTrigger)(unsafe.Pointer((**(**TParse)(__ccgo_up(bp + 32))).FpNewTrigger)).Fstep_list
|
|
for {
|
|
if !(pStep != 0) {
|
|
break
|
|
}
|
|
if (*TTriggerStep)(unsafe.Pointer(pStep)).FpSrc != 0 {
|
|
pTarget = _sqlite3LocateTableItem(tls, bp+32, uint32(0), (*TTriggerStep)(unsafe.Pointer(pStep)).FpSrc+8)
|
|
if pTarget == pTab {
|
|
if (*TTriggerStep)(unsafe.Pointer(pStep)).FpUpsert != 0 {
|
|
pUpsertSet = (*TUpsert)(unsafe.Pointer((*TTriggerStep)(unsafe.Pointer(pStep)).FpUpsert)).FpUpsertSet
|
|
_renameColumnElistNames(tls, bp+32, bp, pUpsertSet, zOld)
|
|
}
|
|
_renameColumnIdlistNames(tls, bp+32, bp, (*TTriggerStep)(unsafe.Pointer(pStep)).FpIdList, zOld)
|
|
_renameColumnElistNames(tls, bp+32, bp, (*TTriggerStep)(unsafe.Pointer(pStep)).FpExprList, zOld)
|
|
}
|
|
}
|
|
goto _8
|
|
_8:
|
|
;
|
|
pStep = (*TTriggerStep)(unsafe.Pointer(pStep)).FpNext
|
|
}
|
|
/* Find tokens to edit in UPDATE OF clause */
|
|
if (**(**TParse)(__ccgo_up(bp + 32))).FpTriggerTab == pTab {
|
|
_renameColumnIdlistNames(tls, bp+32, bp, (*TTrigger)(unsafe.Pointer((**(**TParse)(__ccgo_up(bp + 32))).FpNewTrigger)).FpColumns, zOld)
|
|
}
|
|
/* Find tokens to edit in various expressions and selects */
|
|
_renameWalkTrigger(tls, bp+456, (**(**TParse)(__ccgo_up(bp + 32))).FpNewTrigger)
|
|
}
|
|
}
|
|
rc = _renameEditSql(tls, context, bp, zSql, zNew, bQuote)
|
|
goto renameColumnFunc_done
|
|
renameColumnFunc_done:
|
|
;
|
|
if rc != SQLITE_OK {
|
|
if rc == int32(SQLITE_ERROR) && _sqlite3WritableSchema(tls, db) != 0 {
|
|
Xsqlite3_result_value(tls, context, **(**uintptr)(__ccgo_up(argv)))
|
|
} else {
|
|
if (**(**TParse)(__ccgo_up(bp + 32))).FzErrMsg != 0 {
|
|
_renameColumnParseError(tls, context, __ccgo_ts+1704, **(**uintptr)(__ccgo_up(argv + 1*8)), **(**uintptr)(__ccgo_up(argv + 2*8)), bp+32)
|
|
} else {
|
|
Xsqlite3_result_error_code(tls, context, rc)
|
|
}
|
|
}
|
|
}
|
|
_renameParseCleanup(tls, bp+32)
|
|
_renameTokenFree(tls, db, (**(**TRenameCtx)(__ccgo_up(bp))).FpList)
|
|
(*Tsqlite3)(unsafe.Pointer(db)).FxAuth = xAuth
|
|
_sqlite3BtreeLeaveAll(tls, db)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Parse the SQL statement zSql using Parse object (*p). The Parse object
|
|
// ** is initialized by this function before it is used.
|
|
// */
|
|
func _renameParseSql(tls *libc.TLS, p uintptr, zDb uintptr, db uintptr, zSql uintptr, bTemp int32) (r int32) {
|
|
var flags Tu64
|
|
var iDb, rc int32
|
|
_, _, _ = flags, iDb, rc
|
|
_sqlite3ParseObjectInit(tls, p, db)
|
|
if zSql == uintptr(0) {
|
|
return int32(SQLITE_NOMEM)
|
|
}
|
|
if Xsqlite3_strnicmp(tls, zSql, __ccgo_ts+11594, int32(7)) != 0 {
|
|
return _sqlite3CorruptError(tls, int32(121875))
|
|
}
|
|
if bTemp != 0 {
|
|
(*Tsqlite3)(unsafe.Pointer(db)).Finit1.FiDb = uint8(1)
|
|
} else {
|
|
iDb = _sqlite3FindDbName(tls, db, zDb)
|
|
(*Tsqlite3)(unsafe.Pointer(db)).Finit1.FiDb = libc.Uint8FromInt32(iDb)
|
|
}
|
|
(*TParse)(unsafe.Pointer(p)).FeParseMode = uint8(PARSE_MODE_RENAME)
|
|
(*TParse)(unsafe.Pointer(p)).Fdb = db
|
|
(*TParse)(unsafe.Pointer(p)).FnQueryLoop = int16(1)
|
|
flags = (*Tsqlite3)(unsafe.Pointer(db)).Fflags
|
|
**(**Tu64)(__ccgo_up(db + 48)) |= libc.Uint64FromInt32(libc.Int32FromInt32(0x00040)) << libc.Int32FromInt32(32)
|
|
rc = _sqlite3RunParser(tls, p, zSql)
|
|
(*Tsqlite3)(unsafe.Pointer(db)).Fflags = flags
|
|
if (*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0 {
|
|
rc = int32(SQLITE_NOMEM)
|
|
}
|
|
if rc == SQLITE_OK && ((*TParse)(unsafe.Pointer(p)).FpNewTable == uintptr(0) && (*TParse)(unsafe.Pointer(p)).FpNewIndex == uintptr(0) && (*TParse)(unsafe.Pointer(p)).FpNewTrigger == uintptr(0)) {
|
|
rc = _sqlite3CorruptError(tls, int32(121896))
|
|
}
|
|
(*Tsqlite3)(unsafe.Pointer(db)).Finit1.FiDb = uint8(0)
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This C function implements an SQL user function that is used by SQL code
|
|
// ** generated by the ALTER TABLE ... RENAME command to modify the definition
|
|
// ** of any foreign key constraints that use the table being renamed as the
|
|
// ** parent table. It is passed three arguments:
|
|
// **
|
|
// ** 0: The database containing the table being renamed.
|
|
// ** 1. type: Type of object ("table", "view" etc.)
|
|
// ** 2. object: Name of object
|
|
// ** 3: The complete text of the schema statement being modified,
|
|
// ** 4: The old name of the table being renamed, and
|
|
// ** 5: The new name of the table being renamed.
|
|
// ** 6: True if the schema statement comes from the temp db.
|
|
// **
|
|
// ** It returns the new schema statement. For example:
|
|
// **
|
|
// ** sqlite_rename_table('main', 'CREATE TABLE t1(a REFERENCES t2)','t2','t3',0)
|
|
// ** -> 'CREATE TABLE t1(a REFERENCES t3)'
|
|
// */
|
|
func _renameTableFunc(tls *libc.TLS, context uintptr, NotUsed int32, argv uintptr) {
|
|
bp := tls.Alloc(560)
|
|
defer tls.Free(560)
|
|
var bQuote, bTemp, i, isLegacy, rc int32
|
|
var db, pFKey, pItem, pSelect, pStep, pTab, pTrigger, zDb, zInput, zNew, zOld uintptr
|
|
var xAuth Tsqlite3_xauth
|
|
var _ /* sCtx at bp+424 */ TRenameCtx
|
|
var _ /* sNC at bp+504 */ TNameContext
|
|
var _ /* sParse at bp+0 */ TParse
|
|
var _ /* sWalker at bp+456 */ TWalker
|
|
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = bQuote, bTemp, db, i, isLegacy, pFKey, pItem, pSelect, pStep, pTab, pTrigger, rc, xAuth, zDb, zInput, zNew, zOld
|
|
db = Xsqlite3_context_db_handle(tls, context)
|
|
zDb = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv)))
|
|
zInput = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv + 3*8)))
|
|
zOld = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv + 4*8)))
|
|
zNew = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv + 5*8)))
|
|
bTemp = Xsqlite3_value_int(tls, **(**uintptr)(__ccgo_up(argv + 6*8)))
|
|
_ = NotUsed
|
|
if zInput != 0 && zOld != 0 && zNew != 0 {
|
|
bQuote = int32(1)
|
|
xAuth = (*Tsqlite3)(unsafe.Pointer(db)).FxAuth
|
|
(*Tsqlite3)(unsafe.Pointer(db)).FxAuth = uintptr(0)
|
|
_sqlite3BtreeEnterAll(tls, db)
|
|
libc.Xmemset(tls, bp+424, 0, uint64(32))
|
|
(**(**TRenameCtx)(__ccgo_up(bp + 424))).FpTab = _sqlite3FindTable(tls, db, zOld, zDb)
|
|
libc.Xmemset(tls, bp+456, 0, uint64(48))
|
|
(**(**TWalker)(__ccgo_up(bp + 456))).FpParse = bp
|
|
(**(**TWalker)(__ccgo_up(bp + 456))).FxExprCallback = __ccgo_fp(_renameTableExprCb)
|
|
(**(**TWalker)(__ccgo_up(bp + 456))).FxSelectCallback = __ccgo_fp(_renameTableSelectCb)
|
|
*(*uintptr)(unsafe.Pointer(bp + 456 + 40)) = bp + 424
|
|
rc = _renameParseSql(tls, bp, zDb, db, zInput, bTemp)
|
|
if rc == SQLITE_OK {
|
|
isLegacy = libc.Int32FromUint64((*Tsqlite3)(unsafe.Pointer(db)).Fflags & libc.Uint64FromInt32(SQLITE_LegacyAlter))
|
|
if (**(**TParse)(__ccgo_up(bp))).FpNewTable != 0 {
|
|
pTab = (**(**TParse)(__ccgo_up(bp))).FpNewTable
|
|
if libc.Int32FromUint8((*TTable)(unsafe.Pointer(pTab)).FeTabType) == int32(TABTYP_VIEW) {
|
|
if isLegacy == 0 {
|
|
pSelect = (*(*struct {
|
|
FpSelect uintptr
|
|
})(unsafe.Pointer(&(*TTable)(unsafe.Pointer(pTab)).Fu))).FpSelect
|
|
libc.Xmemset(tls, bp+504, 0, uint64(56))
|
|
(**(**TNameContext)(__ccgo_up(bp + 504))).FpParse = bp
|
|
**(**Tu32)(__ccgo_up(pSelect + 4)) &= ^libc.Uint32FromInt32(SF_View)
|
|
_sqlite3SelectPrep(tls, bp, (*(*struct {
|
|
FpSelect uintptr
|
|
})(unsafe.Pointer(&(*TTable)(unsafe.Pointer(pTab)).Fu))).FpSelect, bp+504)
|
|
if (**(**TParse)(__ccgo_up(bp))).FnErr != 0 {
|
|
rc = (**(**TParse)(__ccgo_up(bp))).Frc
|
|
} else {
|
|
_sqlite3WalkSelect(tls, bp+456, (*(*struct {
|
|
FpSelect uintptr
|
|
})(unsafe.Pointer(&(*TTable)(unsafe.Pointer(pTab)).Fu))).FpSelect)
|
|
}
|
|
}
|
|
} else {
|
|
/* Modify any FK definitions to point to the new table. */
|
|
if (isLegacy == 0 || (*Tsqlite3)(unsafe.Pointer(db)).Fflags&uint64(SQLITE_ForeignKeys) != 0) && !(libc.Int32FromUint8((*TTable)(unsafe.Pointer(pTab)).FeTabType) == libc.Int32FromInt32(TABTYP_VTAB)) {
|
|
pFKey = (*(*struct {
|
|
FaddColOffset int32
|
|
FpFKey uintptr
|
|
FpDfltList uintptr
|
|
})(unsafe.Pointer(pTab + 64))).FpFKey
|
|
for {
|
|
if !(pFKey != 0) {
|
|
break
|
|
}
|
|
if Xsqlite3_stricmp(tls, (*TFKey)(unsafe.Pointer(pFKey)).FzTo, zOld) == 0 {
|
|
_renameTokenFind(tls, bp, bp+424, (*TFKey)(unsafe.Pointer(pFKey)).FzTo)
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
pFKey = (*TFKey)(unsafe.Pointer(pFKey)).FpNextFrom
|
|
}
|
|
}
|
|
/* If this is the table being altered, fix any table refs in CHECK
|
|
** expressions. Also update the name that appears right after the
|
|
** "CREATE [VIRTUAL] TABLE" bit. */
|
|
if Xsqlite3_stricmp(tls, zOld, (*TTable)(unsafe.Pointer(pTab)).FzName) == 0 {
|
|
(**(**TRenameCtx)(__ccgo_up(bp + 424))).FpTab = pTab
|
|
if isLegacy == 0 {
|
|
_sqlite3WalkExprList(tls, bp+456, (*TTable)(unsafe.Pointer(pTab)).FpCheck)
|
|
}
|
|
_renameTokenFind(tls, bp, bp+424, (*TTable)(unsafe.Pointer(pTab)).FzName)
|
|
}
|
|
}
|
|
} else {
|
|
if (**(**TParse)(__ccgo_up(bp))).FpNewIndex != 0 {
|
|
_renameTokenFind(tls, bp, bp+424, (*TIndex)(unsafe.Pointer((**(**TParse)(__ccgo_up(bp))).FpNewIndex)).FzName)
|
|
if isLegacy == 0 {
|
|
_sqlite3WalkExpr(tls, bp+456, (*TIndex)(unsafe.Pointer((**(**TParse)(__ccgo_up(bp))).FpNewIndex)).FpPartIdxWhere)
|
|
}
|
|
} else {
|
|
pTrigger = (**(**TParse)(__ccgo_up(bp))).FpNewTrigger
|
|
if 0 == Xsqlite3_stricmp(tls, (*TTrigger)(unsafe.Pointer((**(**TParse)(__ccgo_up(bp))).FpNewTrigger)).Ftable, zOld) && (*TTable)(unsafe.Pointer((**(**TRenameCtx)(__ccgo_up(bp + 424))).FpTab)).FpSchema == (*TTrigger)(unsafe.Pointer(pTrigger)).FpTabSchema {
|
|
_renameTokenFind(tls, bp, bp+424, (*TTrigger)(unsafe.Pointer((**(**TParse)(__ccgo_up(bp))).FpNewTrigger)).Ftable)
|
|
}
|
|
if isLegacy == 0 {
|
|
rc = _renameResolveTrigger(tls, bp)
|
|
if rc == SQLITE_OK {
|
|
_renameWalkTrigger(tls, bp+456, pTrigger)
|
|
pStep = (*TTrigger)(unsafe.Pointer(pTrigger)).Fstep_list
|
|
for {
|
|
if !(pStep != 0) {
|
|
break
|
|
}
|
|
if (*TTriggerStep)(unsafe.Pointer(pStep)).FpSrc != 0 {
|
|
i = 0
|
|
for {
|
|
if !(i < (*TSrcList)(unsafe.Pointer((*TTriggerStep)(unsafe.Pointer(pStep)).FpSrc)).FnSrc) {
|
|
break
|
|
}
|
|
pItem = (*TTriggerStep)(unsafe.Pointer(pStep)).FpSrc + 8 + uintptr(i)*80
|
|
if 0 == Xsqlite3_stricmp(tls, (*TSrcItem)(unsafe.Pointer(pItem)).FzName, zOld) {
|
|
_renameTokenFind(tls, bp, bp+424, (*TSrcItem)(unsafe.Pointer(pItem)).FzName)
|
|
}
|
|
goto _3
|
|
_3:
|
|
;
|
|
i = i + 1
|
|
}
|
|
}
|
|
goto _2
|
|
_2:
|
|
;
|
|
pStep = (*TTriggerStep)(unsafe.Pointer(pStep)).FpNext
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if rc == SQLITE_OK {
|
|
rc = _renameEditSql(tls, context, bp+424, zInput, zNew, bQuote)
|
|
}
|
|
if rc != SQLITE_OK {
|
|
if rc == int32(SQLITE_ERROR) && _sqlite3WritableSchema(tls, db) != 0 {
|
|
Xsqlite3_result_value(tls, context, **(**uintptr)(__ccgo_up(argv + 3*8)))
|
|
} else {
|
|
if (**(**TParse)(__ccgo_up(bp))).FzErrMsg != 0 {
|
|
_renameColumnParseError(tls, context, __ccgo_ts+1704, **(**uintptr)(__ccgo_up(argv + 1*8)), **(**uintptr)(__ccgo_up(argv + 2*8)), bp)
|
|
} else {
|
|
Xsqlite3_result_error_code(tls, context, rc)
|
|
}
|
|
}
|
|
}
|
|
_renameParseCleanup(tls, bp)
|
|
_renameTokenFree(tls, db, (**(**TRenameCtx)(__ccgo_up(bp + 424))).FpList)
|
|
_sqlite3BtreeLeaveAll(tls, db)
|
|
(*Tsqlite3)(unsafe.Pointer(db)).FxAuth = xAuth
|
|
}
|
|
return
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Reset the aggregate accumulator.
|
|
// **
|
|
// ** The aggregate accumulator is a set of memory cells that hold
|
|
// ** intermediate results while calculating an aggregate. This
|
|
// ** routine generates code that stores NULLs in all of those memory
|
|
// ** cells.
|
|
// */
|
|
func _resetAccumulator(tls *libc.TLS, pParse uintptr, pAggInfo uintptr) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var i, nExtra, nReg int32
|
|
var pE, pFunc, pKeyInfo, pKeyInfo1, pOBList, v uintptr
|
|
_, _, _, _, _, _, _, _, _ = i, nExtra, nReg, pE, pFunc, pKeyInfo, pKeyInfo1, pOBList, v
|
|
v = (*TParse)(unsafe.Pointer(pParse)).FpVdbe
|
|
nReg = (*TAggInfo)(unsafe.Pointer(pAggInfo)).FnFunc + (*TAggInfo)(unsafe.Pointer(pAggInfo)).FnColumn
|
|
if nReg == 0 {
|
|
return
|
|
}
|
|
if (*TParse)(unsafe.Pointer(pParse)).FnErr != 0 {
|
|
return
|
|
}
|
|
_sqlite3VdbeAddOp3(tls, v, int32(OP_Null), 0, (*TAggInfo)(unsafe.Pointer(pAggInfo)).FiFirstReg, (*TAggInfo)(unsafe.Pointer(pAggInfo)).FiFirstReg+nReg-int32(1))
|
|
pFunc = (*TAggInfo)(unsafe.Pointer(pAggInfo)).FaFunc
|
|
i = libc.Int32FromInt32(0)
|
|
for {
|
|
if !(i < (*TAggInfo)(unsafe.Pointer(pAggInfo)).FnFunc) {
|
|
break
|
|
}
|
|
if (*TAggInfo_func)(unsafe.Pointer(pFunc)).FiDistinct >= 0 {
|
|
pE = (*TAggInfo_func)(unsafe.Pointer(pFunc)).FpFExpr
|
|
if *(*uintptr)(unsafe.Pointer(pE + 32)) == uintptr(0) || (*TExprList)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pE + 32)))).FnExpr != int32(1) {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+21436, 0)
|
|
(*TAggInfo_func)(unsafe.Pointer(pFunc)).FiDistinct = -int32(1)
|
|
} else {
|
|
pKeyInfo = _sqlite3KeyInfoFromExprList(tls, pParse, *(*uintptr)(unsafe.Pointer(pE + 32)), 0, 0)
|
|
(*TAggInfo_func)(unsafe.Pointer(pFunc)).FiDistAddr = _sqlite3VdbeAddOp4(tls, v, int32(OP_OpenEphemeral), (*TAggInfo_func)(unsafe.Pointer(pFunc)).FiDistinct, 0, 0, pKeyInfo, -int32(9))
|
|
_sqlite3VdbeExplain(tls, pParse, uint8(0), __ccgo_ts+21487, libc.VaList(bp+8, (*TFuncDef)(unsafe.Pointer((*TAggInfo_func)(unsafe.Pointer(pFunc)).FpFunc)).FzName))
|
|
}
|
|
}
|
|
if (*TAggInfo_func)(unsafe.Pointer(pFunc)).FiOBTab >= 0 {
|
|
nExtra = 0
|
|
pOBList = *(*uintptr)(unsafe.Pointer((*TExpr)(unsafe.Pointer((*TAggInfo_func)(unsafe.Pointer(pFunc)).FpFExpr)).FpLeft + 32))
|
|
if !((*TAggInfo_func)(unsafe.Pointer(pFunc)).FbOBUnique != 0) {
|
|
nExtra = nExtra + 1 /* One extra column for the OP_Sequence */
|
|
}
|
|
if (*TAggInfo_func)(unsafe.Pointer(pFunc)).FbOBPayload != 0 {
|
|
/* extra columns for the function arguments */
|
|
nExtra = nExtra + (*TExprList)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer((*TAggInfo_func)(unsafe.Pointer(pFunc)).FpFExpr + 32)))).FnExpr
|
|
}
|
|
if (*TAggInfo_func)(unsafe.Pointer(pFunc)).FbUseSubtype != 0 {
|
|
nExtra = nExtra + (*TExprList)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer((*TAggInfo_func)(unsafe.Pointer(pFunc)).FpFExpr + 32)))).FnExpr
|
|
}
|
|
pKeyInfo1 = _sqlite3KeyInfoFromExprList(tls, pParse, pOBList, 0, nExtra)
|
|
if !((*TAggInfo_func)(unsafe.Pointer(pFunc)).FbOBUnique != 0) && (*TParse)(unsafe.Pointer(pParse)).FnErr == 0 {
|
|
(*TKeyInfo)(unsafe.Pointer(pKeyInfo1)).FnKeyField = (*TKeyInfo)(unsafe.Pointer(pKeyInfo1)).FnKeyField + 1
|
|
}
|
|
_sqlite3VdbeAddOp4(tls, v, int32(OP_OpenEphemeral), (*TAggInfo_func)(unsafe.Pointer(pFunc)).FiOBTab, (*TExprList)(unsafe.Pointer(pOBList)).FnExpr+nExtra, 0, pKeyInfo1, -int32(9))
|
|
_sqlite3VdbeExplain(tls, pParse, uint8(0), __ccgo_ts+21520, libc.VaList(bp+8, (*TFuncDef)(unsafe.Pointer((*TAggInfo_func)(unsafe.Pointer(pFunc)).FpFunc)).FzName))
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
pFunc += 32
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Implementation of the round() function
|
|
// */
|
|
func _roundFunc(tls *libc.TLS, context uintptr, argc int32, argv uintptr) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var n Ti64
|
|
var zBuf uintptr
|
|
var v1 float64
|
|
var _ /* r at bp+0 */ float64
|
|
_, _, _ = n, zBuf, v1
|
|
n = 0
|
|
if argc == int32(2) {
|
|
if int32(SQLITE_NULL) == Xsqlite3_value_type(tls, **(**uintptr)(__ccgo_up(argv + 1*8))) {
|
|
return
|
|
}
|
|
n = Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(argv + 1*8)))
|
|
if n > int64(30) {
|
|
n = int64(30)
|
|
}
|
|
if n < 0 {
|
|
n = 0
|
|
}
|
|
}
|
|
if Xsqlite3_value_type(tls, **(**uintptr)(__ccgo_up(argv))) == int32(SQLITE_NULL) {
|
|
return
|
|
}
|
|
**(**float64)(__ccgo_up(bp)) = Xsqlite3_value_double(tls, **(**uintptr)(__ccgo_up(argv)))
|
|
/* If Y==0 and X will fit in a 64-bit int,
|
|
** handle the rounding directly,
|
|
** otherwise use printf.
|
|
*/
|
|
if **(**float64)(__ccgo_up(bp)) < -libc.Float64FromFloat64(4.503599627370496e+15) || **(**float64)(__ccgo_up(bp)) > +libc.Float64FromFloat64(4.503599627370496e+15) {
|
|
/* The value has no fractional part so there is nothing to round */
|
|
} else {
|
|
if n == 0 {
|
|
if **(**float64)(__ccgo_up(bp)) < libc.Float64FromInt32(0) {
|
|
v1 = -libc.Float64FromFloat64(0.5)
|
|
} else {
|
|
v1 = +libc.Float64FromFloat64(0.5)
|
|
}
|
|
**(**float64)(__ccgo_up(bp)) = float64(int64(**(**float64)(__ccgo_up(bp)) + v1))
|
|
} else {
|
|
zBuf = Xsqlite3_mprintf(tls, __ccgo_ts+16503, libc.VaList(bp+16, int32(n), **(**float64)(__ccgo_up(bp))))
|
|
if zBuf == uintptr(0) {
|
|
Xsqlite3_result_error_nomem(tls, context)
|
|
return
|
|
}
|
|
_sqlite3AtoF(tls, zBuf, bp)
|
|
Xsqlite3_free(tls, zBuf)
|
|
}
|
|
}
|
|
Xsqlite3_result_double(tls, context, **(**float64)(__ccgo_up(bp)))
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This function is a no-op if there is already an error code stored
|
|
// ** in the RtreeCheck object indicated by the first argument. NULL is
|
|
// ** returned in this case.
|
|
// **
|
|
// ** Otherwise, the contents of rtree table node iNode are loaded from
|
|
// ** the database and copied into a buffer obtained from sqlite3_malloc().
|
|
// ** If no error occurs, a pointer to the buffer is returned and (*pnNode)
|
|
// ** is set to the size of the buffer in bytes.
|
|
// **
|
|
// ** Or, if an error does occur, NULL is returned and an error code left
|
|
// ** in the RtreeCheck object. The final value of *pnNode is undefined in
|
|
// ** this case.
|
|
// */
|
|
func _rtreeCheckGetNode(tls *libc.TLS, pCheck uintptr, iNode Ti64, pnNode uintptr) (r uintptr) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var nNode int32
|
|
var pNode, pRet uintptr
|
|
_, _, _ = nNode, pNode, pRet
|
|
pRet = uintptr(0) /* Return value */
|
|
if (*TRtreeCheck)(unsafe.Pointer(pCheck)).Frc == SQLITE_OK && (*TRtreeCheck)(unsafe.Pointer(pCheck)).FpGetNode == uintptr(0) {
|
|
(*TRtreeCheck)(unsafe.Pointer(pCheck)).FpGetNode = _rtreeCheckPrepare(tls, pCheck, __ccgo_ts+29086, libc.VaList(bp+8, (*TRtreeCheck)(unsafe.Pointer(pCheck)).FzDb, (*TRtreeCheck)(unsafe.Pointer(pCheck)).FzTab))
|
|
}
|
|
if (*TRtreeCheck)(unsafe.Pointer(pCheck)).Frc == SQLITE_OK {
|
|
Xsqlite3_bind_int64(tls, (*TRtreeCheck)(unsafe.Pointer(pCheck)).FpGetNode, int32(1), iNode)
|
|
if Xsqlite3_step(tls, (*TRtreeCheck)(unsafe.Pointer(pCheck)).FpGetNode) == int32(SQLITE_ROW) {
|
|
nNode = Xsqlite3_column_bytes(tls, (*TRtreeCheck)(unsafe.Pointer(pCheck)).FpGetNode, 0)
|
|
pNode = Xsqlite3_column_blob(tls, (*TRtreeCheck)(unsafe.Pointer(pCheck)).FpGetNode, 0)
|
|
pRet = Xsqlite3_malloc64(tls, libc.Uint64FromInt32(nNode))
|
|
if pRet == uintptr(0) {
|
|
(*TRtreeCheck)(unsafe.Pointer(pCheck)).Frc = int32(SQLITE_NOMEM)
|
|
} else {
|
|
libc.Xmemcpy(tls, pRet, pNode, libc.Uint64FromInt32(nNode))
|
|
**(**int32)(__ccgo_up(pnNode)) = nNode
|
|
}
|
|
}
|
|
_rtreeCheckReset(tls, pCheck, (*TRtreeCheck)(unsafe.Pointer(pCheck)).FpGetNode)
|
|
if (*TRtreeCheck)(unsafe.Pointer(pCheck)).Frc == SQLITE_OK && pRet == uintptr(0) {
|
|
_rtreeCheckAppendMsg(tls, pCheck, __ccgo_ts+29131, libc.VaList(bp+8, iNode))
|
|
}
|
|
}
|
|
return pRet
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This function is used to check that the %_parent (if bLeaf==0) or %_rowid
|
|
// ** (if bLeaf==1) table contains a specified entry. The schemas of the
|
|
// ** two tables are:
|
|
// **
|
|
// ** CREATE TABLE %_parent(nodeno INTEGER PRIMARY KEY, parentnode INTEGER)
|
|
// ** CREATE TABLE %_rowid(rowid INTEGER PRIMARY KEY, nodeno INTEGER, ...)
|
|
// **
|
|
// ** In both cases, this function checks that there exists an entry with
|
|
// ** IPK value iKey and the second column set to iVal.
|
|
// **
|
|
// */
|
|
func _rtreeCheckMapping(tls *libc.TLS, pCheck uintptr, bLeaf int32, iKey Ti64, iVal Ti64) {
|
|
bp := tls.Alloc(48)
|
|
defer tls.Free(48)
|
|
var azSql [2]uintptr
|
|
var ii Ti64
|
|
var pStmt, v1 uintptr
|
|
var rc int32
|
|
_, _, _, _, _ = azSql, ii, pStmt, rc, v1
|
|
azSql = [2]uintptr{
|
|
0: __ccgo_ts + 29163,
|
|
1: __ccgo_ts + 29217,
|
|
}
|
|
if **(**uintptr)(__ccgo_up(pCheck + 40 + uintptr(bLeaf)*8)) == uintptr(0) {
|
|
**(**uintptr)(__ccgo_up(pCheck + 40 + uintptr(bLeaf)*8)) = _rtreeCheckPrepare(tls, pCheck, azSql[bLeaf], libc.VaList(bp+8, (*TRtreeCheck)(unsafe.Pointer(pCheck)).FzDb, (*TRtreeCheck)(unsafe.Pointer(pCheck)).FzTab))
|
|
}
|
|
if (*TRtreeCheck)(unsafe.Pointer(pCheck)).Frc != SQLITE_OK {
|
|
return
|
|
}
|
|
pStmt = **(**uintptr)(__ccgo_up(pCheck + 40 + uintptr(bLeaf)*8))
|
|
Xsqlite3_bind_int64(tls, pStmt, int32(1), iKey)
|
|
rc = Xsqlite3_step(tls, pStmt)
|
|
if rc == int32(SQLITE_DONE) {
|
|
if bLeaf != 0 {
|
|
v1 = __ccgo_ts + 29265
|
|
} else {
|
|
v1 = __ccgo_ts + 29273
|
|
}
|
|
_rtreeCheckAppendMsg(tls, pCheck, __ccgo_ts+29282, libc.VaList(bp+8, iKey, iVal, v1))
|
|
} else {
|
|
if rc == int32(SQLITE_ROW) {
|
|
ii = Xsqlite3_column_int64(tls, pStmt, 0)
|
|
if ii != iVal {
|
|
if bLeaf != 0 {
|
|
v1 = __ccgo_ts + 29265
|
|
} else {
|
|
v1 = __ccgo_ts + 29273
|
|
}
|
|
_rtreeCheckAppendMsg(tls, pCheck, __ccgo_ts+29327, libc.VaList(bp+8, iKey, ii, v1, iKey, iVal))
|
|
}
|
|
}
|
|
}
|
|
_rtreeCheckReset(tls, pCheck, pStmt)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This function does the bulk of the work for the rtree integrity-check.
|
|
// ** It is called by rtreecheck(), which is the SQL function implementation.
|
|
// */
|
|
func _rtreeCheckTable(tls *libc.TLS, db uintptr, zDb uintptr, zTab uintptr, pzReport uintptr) (r int32) {
|
|
bp := tls.Alloc(112)
|
|
defer tls.Free(112)
|
|
var nAux, rc int32
|
|
var pStmt uintptr
|
|
var _ /* check at bp+0 */ TRtreeCheck
|
|
_, _, _ = nAux, pStmt, rc /* Common context for various routines */
|
|
pStmt = uintptr(0) /* Used to find column count of rtree table */
|
|
nAux = 0 /* Number of extra columns. */
|
|
/* Initialize the context object */
|
|
libc.Xmemset(tls, bp, 0, uint64(88))
|
|
(**(**TRtreeCheck)(__ccgo_up(bp))).Fdb = db
|
|
(**(**TRtreeCheck)(__ccgo_up(bp))).FzDb = zDb
|
|
(**(**TRtreeCheck)(__ccgo_up(bp))).FzTab = zTab
|
|
/* Find the number of auxiliary columns */
|
|
pStmt = _rtreeCheckPrepare(tls, bp, __ccgo_ts+29717, libc.VaList(bp+96, zDb, zTab))
|
|
if pStmt != 0 {
|
|
nAux = Xsqlite3_column_count(tls, pStmt) - int32(2)
|
|
Xsqlite3_finalize(tls, pStmt)
|
|
} else {
|
|
if (**(**TRtreeCheck)(__ccgo_up(bp))).Frc != int32(SQLITE_NOMEM) {
|
|
(**(**TRtreeCheck)(__ccgo_up(bp))).Frc = SQLITE_OK
|
|
}
|
|
}
|
|
/* Find number of dimensions in the rtree table. */
|
|
pStmt = _rtreeCheckPrepare(tls, bp, __ccgo_ts+27533, libc.VaList(bp+96, zDb, zTab))
|
|
if pStmt != 0 {
|
|
(**(**TRtreeCheck)(__ccgo_up(bp))).FnDim = (Xsqlite3_column_count(tls, pStmt) - int32(1) - nAux) / int32(2)
|
|
if (**(**TRtreeCheck)(__ccgo_up(bp))).FnDim < int32(1) {
|
|
_rtreeCheckAppendMsg(tls, bp, __ccgo_ts+29745, 0)
|
|
} else {
|
|
if int32(SQLITE_ROW) == Xsqlite3_step(tls, pStmt) {
|
|
(**(**TRtreeCheck)(__ccgo_up(bp))).FbInt = libc.BoolInt32(Xsqlite3_column_type(tls, pStmt, int32(1)) == int32(SQLITE_INTEGER))
|
|
}
|
|
}
|
|
rc = Xsqlite3_finalize(tls, pStmt)
|
|
if rc != int32(SQLITE_CORRUPT) {
|
|
(**(**TRtreeCheck)(__ccgo_up(bp))).Frc = rc
|
|
}
|
|
}
|
|
/* Do the actual integrity-check */
|
|
if (**(**TRtreeCheck)(__ccgo_up(bp))).FnDim >= int32(1) {
|
|
if (**(**TRtreeCheck)(__ccgo_up(bp))).Frc == SQLITE_OK {
|
|
_rtreeCheckNode(tls, bp, 0, uintptr(0), int64(1))
|
|
}
|
|
_rtreeCheckCount(tls, bp, __ccgo_ts+29776, int64((**(**TRtreeCheck)(__ccgo_up(bp))).FnLeaf))
|
|
_rtreeCheckCount(tls, bp, __ccgo_ts+29783, int64((**(**TRtreeCheck)(__ccgo_up(bp))).FnNonLeaf))
|
|
}
|
|
/* Finalize SQL statements used by the integrity-check */
|
|
Xsqlite3_finalize(tls, (**(**TRtreeCheck)(__ccgo_up(bp))).FpGetNode)
|
|
Xsqlite3_finalize(tls, **(**uintptr)(__ccgo_up(bp + 40)))
|
|
Xsqlite3_finalize(tls, **(**uintptr)(__ccgo_up(bp + 40 + 1*8)))
|
|
**(**uintptr)(__ccgo_up(pzReport)) = (**(**TRtreeCheck)(__ccgo_up(bp))).FzReport
|
|
return (**(**TRtreeCheck)(__ccgo_up(bp))).Frc
|
|
}
|
|
|
|
func _rtreeSqlInit(tls *libc.TLS, pRtree uintptr, db uintptr, zDb uintptr, zPrefix uintptr, isCreate int32) (r int32) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var appStmt [8]uintptr
|
|
var f, i, ii, ii1, rc int32
|
|
var p, p1, zCreate, zFormat, zSql, zSql1 uintptr
|
|
_, _, _, _, _, _, _, _, _, _, _, _ = appStmt, f, i, ii, ii1, p, p1, rc, zCreate, zFormat, zSql, zSql1
|
|
rc = SQLITE_OK
|
|
f = libc.Int32FromInt32(SQLITE_PREPARE_PERSISTENT) | libc.Int32FromInt32(SQLITE_PREPARE_NO_VTAB)
|
|
(*TRtree)(unsafe.Pointer(pRtree)).Fdb = db
|
|
if isCreate != 0 {
|
|
p = Xsqlite3_str_new(tls, db)
|
|
Xsqlite3_str_appendf(tls, p, __ccgo_ts+28237, libc.VaList(bp+8, zDb, zPrefix))
|
|
ii = 0
|
|
for {
|
|
if !(ii < libc.Int32FromUint16((*TRtree)(unsafe.Pointer(pRtree)).FnAux)) {
|
|
break
|
|
}
|
|
Xsqlite3_str_appendf(tls, p, __ccgo_ts+28299, libc.VaList(bp+8, ii))
|
|
goto _1
|
|
_1:
|
|
;
|
|
ii = ii + 1
|
|
}
|
|
Xsqlite3_str_appendf(tls, p, __ccgo_ts+28304, libc.VaList(bp+8, zDb, zPrefix))
|
|
Xsqlite3_str_appendf(tls, p, __ccgo_ts+28368, libc.VaList(bp+8, zDb, zPrefix))
|
|
Xsqlite3_str_appendf(tls, p, __ccgo_ts+28438, libc.VaList(bp+8, zDb, zPrefix, (*TRtree)(unsafe.Pointer(pRtree)).FiNodeSize))
|
|
zCreate = Xsqlite3_str_finish(tls, p)
|
|
if !(zCreate != 0) {
|
|
return int32(SQLITE_NOMEM)
|
|
}
|
|
rc = Xsqlite3_exec(tls, db, zCreate, uintptr(0), uintptr(0), uintptr(0))
|
|
Xsqlite3_free(tls, zCreate)
|
|
if rc != SQLITE_OK {
|
|
return rc
|
|
}
|
|
}
|
|
appStmt[0] = pRtree + 128
|
|
appStmt[int32(1)] = pRtree + 136
|
|
appStmt[int32(2)] = pRtree + 144
|
|
appStmt[int32(3)] = pRtree + 152
|
|
appStmt[int32(4)] = pRtree + 160
|
|
appStmt[int32(5)] = pRtree + 168
|
|
appStmt[int32(6)] = pRtree + 176
|
|
appStmt[int32(7)] = pRtree + 184
|
|
rc = _rtreeQueryStat1(tls, db, pRtree)
|
|
i = 0
|
|
for {
|
|
if !(i < int32(N_STATEMENT) && rc == SQLITE_OK) {
|
|
break
|
|
}
|
|
if i != int32(3) || libc.Int32FromUint16((*TRtree)(unsafe.Pointer(pRtree)).FnAux) == 0 {
|
|
zFormat = _azSql[i]
|
|
} else {
|
|
/* An UPSERT is very slightly slower than REPLACE, but it is needed
|
|
** if there are auxiliary columns */
|
|
zFormat = __ccgo_ts + 28487
|
|
}
|
|
zSql = Xsqlite3_mprintf(tls, zFormat, libc.VaList(bp+8, zDb, zPrefix))
|
|
if zSql != 0 {
|
|
rc = Xsqlite3_prepare_v3(tls, db, zSql, -int32(1), libc.Uint32FromInt32(f), appStmt[i], uintptr(0))
|
|
} else {
|
|
rc = int32(SQLITE_NOMEM)
|
|
}
|
|
Xsqlite3_free(tls, zSql)
|
|
goto _2
|
|
_2:
|
|
;
|
|
i = i + 1
|
|
}
|
|
if (*TRtree)(unsafe.Pointer(pRtree)).FnAux != 0 && rc != int32(SQLITE_NOMEM) {
|
|
(*TRtree)(unsafe.Pointer(pRtree)).FzReadAuxSql = Xsqlite3_mprintf(tls, __ccgo_ts+28595, libc.VaList(bp+8, zDb, zPrefix))
|
|
if (*TRtree)(unsafe.Pointer(pRtree)).FzReadAuxSql == uintptr(0) {
|
|
rc = int32(SQLITE_NOMEM)
|
|
} else {
|
|
p1 = Xsqlite3_str_new(tls, db)
|
|
Xsqlite3_str_appendf(tls, p1, __ccgo_ts+28640, libc.VaList(bp+8, zDb, zPrefix))
|
|
ii1 = 0
|
|
for {
|
|
if !(ii1 < libc.Int32FromUint16((*TRtree)(unsafe.Pointer(pRtree)).FnAux)) {
|
|
break
|
|
}
|
|
if ii1 != 0 {
|
|
Xsqlite3_str_append(tls, p1, __ccgo_ts+14374, int32(1))
|
|
}
|
|
if ii1 < libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FnAuxNotNull) {
|
|
Xsqlite3_str_appendf(tls, p1, __ccgo_ts+28667, libc.VaList(bp+8, ii1, ii1+int32(2), ii1))
|
|
} else {
|
|
Xsqlite3_str_appendf(tls, p1, __ccgo_ts+28689, libc.VaList(bp+8, ii1, ii1+int32(2)))
|
|
}
|
|
goto _3
|
|
_3:
|
|
;
|
|
ii1 = ii1 + 1
|
|
}
|
|
Xsqlite3_str_appendf(tls, p1, __ccgo_ts+28697, 0)
|
|
zSql1 = Xsqlite3_str_finish(tls, p1)
|
|
if zSql1 == uintptr(0) {
|
|
rc = int32(SQLITE_NOMEM)
|
|
} else {
|
|
rc = Xsqlite3_prepare_v3(tls, db, zSql1, -int32(1), libc.Uint32FromInt32(f), pRtree+192, uintptr(0))
|
|
Xsqlite3_free(tls, zSql1)
|
|
}
|
|
}
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Usage:
|
|
// **
|
|
// ** rtreecheck(<rtree-table>);
|
|
// ** rtreecheck(<database>, <rtree-table>);
|
|
// **
|
|
// ** Invoking this SQL function runs an integrity-check on the named rtree
|
|
// ** table. The integrity-check verifies the following:
|
|
// **
|
|
// ** 1. For each cell in the r-tree structure (%_node table), that:
|
|
// **
|
|
// ** a) for each dimension, (coord1 <= coord2).
|
|
// **
|
|
// ** b) unless the cell is on the root node, that the cell is bounded
|
|
// ** by the parent cell on the parent node.
|
|
// **
|
|
// ** c) for leaf nodes, that there is an entry in the %_rowid
|
|
// ** table corresponding to the cell's rowid value that
|
|
// ** points to the correct node.
|
|
// **
|
|
// ** d) for cells on non-leaf nodes, that there is an entry in the
|
|
// ** %_parent table mapping from the cell's child node to the
|
|
// ** node that it resides on.
|
|
// **
|
|
// ** 2. That there are the same number of entries in the %_rowid table
|
|
// ** as there are leaf cells in the r-tree structure, and that there
|
|
// ** is a leaf cell that corresponds to each entry in the %_rowid table.
|
|
// **
|
|
// ** 3. That there are the same number of entries in the %_parent table
|
|
// ** as there are non-leaf cells in the r-tree structure, and that
|
|
// ** there is a non-leaf cell that corresponds to each entry in the
|
|
// ** %_parent table.
|
|
// */
|
|
func _rtreecheck(tls *libc.TLS, ctx uintptr, nArg int32, apArg uintptr) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var rc int32
|
|
var zDb, zTab, v1 uintptr
|
|
var _ /* zReport at bp+0 */ uintptr
|
|
_, _, _, _ = rc, zDb, zTab, v1
|
|
if nArg != int32(1) && nArg != int32(2) {
|
|
Xsqlite3_result_error(tls, ctx, __ccgo_ts+29810, -int32(1))
|
|
} else {
|
|
**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
|
|
zDb = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(apArg)))
|
|
if nArg == int32(1) {
|
|
zTab = zDb
|
|
zDb = __ccgo_ts + 6844
|
|
} else {
|
|
zTab = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(apArg + 1*8)))
|
|
}
|
|
rc = _rtreeCheckTable(tls, Xsqlite3_context_db_handle(tls, ctx), zDb, zTab, bp)
|
|
if rc == SQLITE_OK {
|
|
if **(**uintptr)(__ccgo_up(bp)) != 0 {
|
|
v1 = **(**uintptr)(__ccgo_up(bp))
|
|
} else {
|
|
v1 = __ccgo_ts + 19817
|
|
}
|
|
Xsqlite3_result_text(tls, ctx, v1, -int32(1), uintptr(-libc.Int32FromInt32(1)))
|
|
} else {
|
|
Xsqlite3_result_error_code(tls, ctx, rc)
|
|
}
|
|
Xsqlite3_free(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
}
|
|
}
|
|
|
|
/* Conditionally include the geopoly code */
|
|
/************** Include geopoly.c in the middle of rtree.c *******************/
|
|
/************** Begin file geopoly.c *****************************************/
|
|
/*
|
|
** 2018-05-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 implements an alternative R-Tree virtual table that
|
|
** uses polygons to express the boundaries of 2-dimensional objects.
|
|
**
|
|
** This file is #include-ed onto the end of "rtree.c" so that it has
|
|
** access to all of the R-Tree internals.
|
|
*/
|
|
/* #include <stdlib.h> */
|
|
|
|
/* Enable -DGEOPOLY_ENABLE_DEBUG for debugging facilities */
|
|
|
|
/* Character class routines */
|
|
/* Use the SQLite core versions if this routine is part of the
|
|
** SQLite amalgamation */
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Implementation of a scalar function that decodes r-tree nodes to
|
|
// ** human readable strings. This can be used for debugging and analysis.
|
|
// **
|
|
// ** The scalar function takes two arguments: (1) the number of dimensions
|
|
// ** to the rtree (between 1 and 5, inclusive) and (2) a blob of data containing
|
|
// ** an r-tree node. For a two-dimensional r-tree structure called "rt", to
|
|
// ** deserialize all nodes, a statement like:
|
|
// **
|
|
// ** SELECT rtreenode(2, data) FROM rt_node;
|
|
// **
|
|
// ** The human readable string takes the form of a Tcl list with one
|
|
// ** entry for each cell in the r-tree node. Each entry is itself a
|
|
// ** list, containing the 8-byte rowid/pageno followed by the
|
|
// ** <num-dimension>*2 coordinates.
|
|
// */
|
|
func _rtreenode(tls *libc.TLS, ctx uintptr, nArg int32, apArg uintptr) {
|
|
bp := tls.Alloc(1088)
|
|
defer tls.Free(1088)
|
|
var errCode, ii, jj, nData int32
|
|
var pOut uintptr
|
|
var _ /* cell at bp+1016 */ TRtreeCell
|
|
var _ /* node at bp+0 */ TRtreeNode
|
|
var _ /* tree at bp+40 */ TRtree
|
|
_, _, _, _, _ = errCode, ii, jj, nData, pOut
|
|
_ = nArg
|
|
libc.Xmemset(tls, bp, 0, uint64(40))
|
|
libc.Xmemset(tls, bp+40, 0, uint64(976))
|
|
(**(**TRtree)(__ccgo_up(bp + 40))).FnDim = libc.Uint8FromInt32(Xsqlite3_value_int(tls, **(**uintptr)(__ccgo_up(apArg))))
|
|
if libc.Int32FromUint8((**(**TRtree)(__ccgo_up(bp + 40))).FnDim) < int32(1) || libc.Int32FromUint8((**(**TRtree)(__ccgo_up(bp + 40))).FnDim) > int32(5) {
|
|
return
|
|
}
|
|
(**(**TRtree)(__ccgo_up(bp + 40))).FnDim2 = libc.Uint8FromInt32(libc.Int32FromUint8((**(**TRtree)(__ccgo_up(bp + 40))).FnDim) * int32(2))
|
|
(**(**TRtree)(__ccgo_up(bp + 40))).FnBytesPerCell = libc.Uint8FromInt32(int32(8) + int32(8)*libc.Int32FromUint8((**(**TRtree)(__ccgo_up(bp + 40))).FnDim))
|
|
(**(**TRtreeNode)(__ccgo_up(bp))).FzData = Xsqlite3_value_blob(tls, **(**uintptr)(__ccgo_up(apArg + 1*8)))
|
|
if (**(**TRtreeNode)(__ccgo_up(bp))).FzData == uintptr(0) {
|
|
return
|
|
}
|
|
nData = Xsqlite3_value_bytes(tls, **(**uintptr)(__ccgo_up(apArg + 1*8)))
|
|
if nData < int32(4) {
|
|
return
|
|
}
|
|
if nData < int32(4)+_readInt16(tls, (*TRtreeNode)(unsafe.Pointer(bp)).FzData+2)*libc.Int32FromUint8((**(**TRtree)(__ccgo_up(bp + 40))).FnBytesPerCell) {
|
|
return
|
|
}
|
|
pOut = Xsqlite3_str_new(tls, uintptr(0))
|
|
ii = 0
|
|
for {
|
|
if !(ii < _readInt16(tls, (*TRtreeNode)(unsafe.Pointer(bp)).FzData+2)) {
|
|
break
|
|
}
|
|
_nodeGetCell(tls, bp+40, bp, ii, bp+1016)
|
|
if ii > 0 {
|
|
Xsqlite3_str_append(tls, pOut, __ccgo_ts+11569, int32(1))
|
|
}
|
|
Xsqlite3_str_appendf(tls, pOut, __ccgo_ts+29036, libc.VaList(bp+1072, (**(**TRtreeCell)(__ccgo_up(bp + 1016))).FiRowid))
|
|
jj = 0
|
|
for {
|
|
if !(jj < libc.Int32FromUint8((**(**TRtree)(__ccgo_up(bp + 40))).FnDim2)) {
|
|
break
|
|
}
|
|
Xsqlite3_str_appendf(tls, pOut, __ccgo_ts+29042, libc.VaList(bp+1072, float64(*(*TRtreeValue)(unsafe.Pointer(bp + 1016 + 8 + uintptr(jj)*4)))))
|
|
goto _2
|
|
_2:
|
|
;
|
|
jj = jj + 1
|
|
}
|
|
Xsqlite3_str_append(tls, pOut, __ccgo_ts+26881, int32(1))
|
|
goto _1
|
|
_1:
|
|
;
|
|
ii = ii + 1
|
|
}
|
|
errCode = Xsqlite3_str_errcode(tls, pOut)
|
|
Xsqlite3_result_error_code(tls, ctx, errCode)
|
|
Xsqlite3_result_text(tls, ctx, Xsqlite3_str_finish(tls, pOut), -int32(1), __ccgo_fp(Xsqlite3_free))
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Seek to the offset passed as the second argument, then read cnt
|
|
// ** bytes into pBuf. Return the number of bytes actually read.
|
|
// **
|
|
// ** To avoid stomping the errno value on a failed read the lastErrno value
|
|
// ** is set before returning.
|
|
// */
|
|
func _seekAndRead(tls *libc.TLS, id uintptr, offset Tsqlite3_int64, pBuf uintptr, cnt int32) (r int32) {
|
|
var got, prior int32
|
|
_, _ = got, prior
|
|
prior = 0
|
|
for cond := true; cond; cond = got > 0 {
|
|
got = int32((*(*func(*libc.TLS, int32, uintptr, Tsize_t, Toff_t) Tssize_t)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(9)].FpCurrent})))(tls, (*TunixFile)(unsafe.Pointer(id)).Fh, pBuf, libc.Uint64FromInt32(cnt), offset))
|
|
if got == cnt {
|
|
break
|
|
}
|
|
if got < 0 {
|
|
if **(**int32)(__ccgo_up(libc.X__errno_location(tls))) == int32(EINTR) {
|
|
got = int32(1)
|
|
continue
|
|
}
|
|
prior = 0
|
|
_storeLastErrno(tls, id, **(**int32)(__ccgo_up(libc.X__errno_location(tls))))
|
|
break
|
|
} else {
|
|
if got > 0 {
|
|
cnt = cnt - got
|
|
offset = offset + int64(got)
|
|
prior = prior + got
|
|
pBuf = uintptr(got) + pBuf
|
|
}
|
|
}
|
|
}
|
|
return got + prior
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Attempt to seek the file-descriptor passed as the first argument to
|
|
// ** absolute offset iOff, then attempt to write nBuf bytes of data from
|
|
// ** pBuf to it. If an error occurs, return -1 and set *piErrno. Otherwise,
|
|
// ** return the actual number of bytes written (which may be less than
|
|
// ** nBuf).
|
|
// */
|
|
func _seekAndWriteFd(tls *libc.TLS, fd int32, iOff Ti64, pBuf uintptr, nBuf int32, piErrno uintptr) (r int32) {
|
|
var rc int32
|
|
_ = rc
|
|
rc = 0 /* Value returned by system call */
|
|
nBuf = nBuf & int32(0x1ffff)
|
|
for cond := true; cond; cond = rc < 0 && **(**int32)(__ccgo_up(libc.X__errno_location(tls))) == int32(EINTR) {
|
|
rc = int32((*(*func(*libc.TLS, int32, uintptr, Tsize_t, Toff_t) Tssize_t)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(12)].FpCurrent})))(tls, fd, pBuf, libc.Uint64FromInt32(nBuf), iOff))
|
|
}
|
|
if rc < 0 {
|
|
**(**int32)(__ccgo_up(piErrno)) = **(**int32)(__ccgo_up(libc.X__errno_location(tls)))
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** The xExpr callback for the search of invalid ON clause terms.
|
|
// */
|
|
func _selectCheckOnClausesExpr(tls *libc.TLS, pWalker uintptr, pExpr uintptr) (r int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var iTab, ii, nSrc int32
|
|
var pCtx, pSrc, v2 uintptr
|
|
_, _, _, _, _, _ = iTab, ii, nSrc, pCtx, pSrc, v2
|
|
pCtx = *(*uintptr)(unsafe.Pointer(pWalker + 40))
|
|
/* Check if pExpr is root or near-root of an ON clause constraint that needs
|
|
** to be checked to ensure that it does not refer to tables in its FROM
|
|
** clause to the right of itself. i.e. it is either:
|
|
**
|
|
** + an ON clause on an OUTER join, or
|
|
** + an ON clause on an INNER join within a FROM that features at
|
|
** least one RIGHT or FULL join.
|
|
*/
|
|
if (*TExpr)(unsafe.Pointer(pExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_OuterON)) != uint32(0) || (*TExpr)(unsafe.Pointer(pExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_InnerON)) != uint32(0) && libc.Int32FromUint8((*(*TSrcItem)(unsafe.Pointer((*TCheckOnCtx)(unsafe.Pointer(pCtx)).FpSrc + 8))).Ffg.Fjointype)&int32(JT_LTORJ) != 0 {
|
|
/* If CheckOnCtx.iJoin is already set, then fall through and process
|
|
** this expression node as normal. Or, if CheckOnCtx.iJoin is still 0,
|
|
** set it to the cursor number of the RHS of the join to which this
|
|
** ON expression was attached and then iterate through the entire
|
|
** expression. */
|
|
if (*TCheckOnCtx)(unsafe.Pointer(pCtx)).FiJoin == 0 {
|
|
(*TCheckOnCtx)(unsafe.Pointer(pCtx)).FiJoin = *(*int32)(unsafe.Pointer(pExpr + 52))
|
|
_sqlite3WalkExprNN(tls, pWalker, pExpr)
|
|
(*TCheckOnCtx)(unsafe.Pointer(pCtx)).FiJoin = 0
|
|
return int32(WRC_Prune)
|
|
}
|
|
}
|
|
if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) == int32(TK_COLUMN) {
|
|
/* A column expression. Find the SrcList (if any) to which it refers.
|
|
** Then, if CheckOnCtx.iJoin indicates that this expression is part of an
|
|
** ON clause from that SrcList (i.e. if iJoin is non-zero), check that it
|
|
** does not refer to a table to the right of CheckOnCtx.iJoin. */
|
|
for cond := true; cond; cond = pCtx != 0 {
|
|
pSrc = (*TCheckOnCtx)(unsafe.Pointer(pCtx)).FpSrc
|
|
nSrc = (*TSrcList)(unsafe.Pointer(pSrc)).FnSrc
|
|
iTab = (*TExpr)(unsafe.Pointer(pExpr)).FiTable
|
|
ii = 0
|
|
for {
|
|
if !(ii < nSrc && (*(*TSrcItem)(unsafe.Pointer(pSrc + 8 + uintptr(ii)*80))).FiCursor != iTab) {
|
|
break
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
ii = ii + 1
|
|
}
|
|
if ii < nSrc {
|
|
if (*TCheckOnCtx)(unsafe.Pointer(pCtx)).FiJoin != 0 && iTab > (*TCheckOnCtx)(unsafe.Pointer(pCtx)).FiJoin {
|
|
if (*TCheckOnCtx)(unsafe.Pointer(pCtx)).FbFuncArg != 0 {
|
|
v2 = __ccgo_ts + 21588
|
|
} else {
|
|
v2 = __ccgo_ts + 21612
|
|
}
|
|
_sqlite3ErrorMsg(tls, (*TWalker)(unsafe.Pointer(pWalker)).FpParse, __ccgo_ts+21622, libc.VaList(bp+8, v2))
|
|
return int32(WRC_Abort)
|
|
}
|
|
break
|
|
}
|
|
pCtx = (*TCheckOnCtx)(unsafe.Pointer(pCtx)).FpParent
|
|
}
|
|
}
|
|
return WRC_Continue
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This routine generates the code for the inside of the inner loop
|
|
// ** of a SELECT.
|
|
// **
|
|
// ** If srcTab is negative, then the p->pEList expressions
|
|
// ** are evaluated in order to get the data for this row. If srcTab is
|
|
// ** zero or more, then data is pulled from srcTab and p->pEList is used only
|
|
// ** to get the number of columns and the collation sequence for each column.
|
|
// */
|
|
func _selectInnerLoop(tls *libc.TLS, pParse uintptr, p uintptr, srcTab int32, pSort uintptr, pDistinct uintptr, pDest uintptr, iContinue int32, iBreak int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var addr, addrTest, eDest, eType, hasDistinct, i, i2, iParm, iTab, j, nKey, nPrefixReg, nResultCol, r1, r11, r12, r13, r2, r21, r3, regOrig, regResult, v1 int32
|
|
var ecelFlags Tu8
|
|
var pEList, pSO, v uintptr
|
|
var _ /* sRowLoadInfo at bp+0 */ TRowLoadInfo
|
|
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = addr, addrTest, eDest, eType, ecelFlags, hasDistinct, i, i2, iParm, iTab, j, nKey, nPrefixReg, nResultCol, pEList, pSO, r1, r11, r12, r13, r2, r21, r3, regOrig, regResult, v, v1
|
|
v = (*TParse)(unsafe.Pointer(pParse)).FpVdbe /* True if the DISTINCT keyword is present */
|
|
eDest = libc.Int32FromUint8((*TSelectDest)(unsafe.Pointer(pDest)).FeDest) /* How to dispose of results */
|
|
iParm = (*TSelectDest)(unsafe.Pointer(pDest)).FiSDParm /* Number of result columns */
|
|
nPrefixReg = 0 /* Start of memory holding full result (or 0) */
|
|
if pDistinct != 0 {
|
|
v1 = libc.Int32FromUint8((*TDistinctCtx)(unsafe.Pointer(pDistinct)).FeTnctType)
|
|
} else {
|
|
v1 = WHERE_DISTINCT_NOOP
|
|
}
|
|
hasDistinct = v1
|
|
if pSort != 0 && (*TSortCtx)(unsafe.Pointer(pSort)).FpOrderBy == uintptr(0) {
|
|
pSort = uintptr(0)
|
|
}
|
|
if pSort == uintptr(0) && !(hasDistinct != 0) {
|
|
_codeOffset(tls, v, (*TSelect)(unsafe.Pointer(p)).FiOffset, iContinue)
|
|
}
|
|
/* Pull the requested columns.
|
|
*/
|
|
nResultCol = (*TExprList)(unsafe.Pointer((*TSelect)(unsafe.Pointer(p)).FpEList)).FnExpr
|
|
if (*TSelectDest)(unsafe.Pointer(pDest)).FiSdst == 0 {
|
|
if pSort != 0 {
|
|
nPrefixReg = (*TExprList)(unsafe.Pointer((*TSortCtx)(unsafe.Pointer(pSort)).FpOrderBy)).FnExpr
|
|
if !(libc.Int32FromUint8((*TSortCtx)(unsafe.Pointer(pSort)).FsortFlags)&libc.Int32FromInt32(SORTFLAG_UseSorter) != 0) {
|
|
nPrefixReg = nPrefixReg + 1
|
|
}
|
|
**(**int32)(__ccgo_up(pParse + 60)) += nPrefixReg
|
|
}
|
|
(*TSelectDest)(unsafe.Pointer(pDest)).FiSdst = (*TParse)(unsafe.Pointer(pParse)).FnMem + int32(1)
|
|
**(**int32)(__ccgo_up(pParse + 60)) += nResultCol
|
|
} else {
|
|
if (*TSelectDest)(unsafe.Pointer(pDest)).FiSdst+nResultCol > (*TParse)(unsafe.Pointer(pParse)).FnMem {
|
|
/* This is an error condition that can result, for example, when a SELECT
|
|
** on the right-hand side of an INSERT contains more result columns than
|
|
** there are columns in the table on the left. The error will be caught
|
|
** and reported later. But we need to make sure enough memory is allocated
|
|
** to avoid other spurious errors in the meantime. */
|
|
**(**int32)(__ccgo_up(pParse + 60)) += nResultCol
|
|
}
|
|
}
|
|
(*TSelectDest)(unsafe.Pointer(pDest)).FnSdst = nResultCol
|
|
v1 = (*TSelectDest)(unsafe.Pointer(pDest)).FiSdst
|
|
regResult = v1
|
|
regOrig = v1
|
|
if srcTab >= 0 {
|
|
i = 0
|
|
for {
|
|
if !(i < nResultCol) {
|
|
break
|
|
}
|
|
_sqlite3VdbeAddOp3(tls, v, int32(OP_Column), srcTab, i, regResult+i)
|
|
goto _3
|
|
_3:
|
|
;
|
|
i = i + 1
|
|
}
|
|
} else {
|
|
if eDest != int32(SRT_Exists) {
|
|
if eDest == int32(SRT_Mem) || eDest == int32(SRT_Output) || eDest == int32(SRT_Coroutine) {
|
|
ecelFlags = uint8(SQLITE_ECEL_DUP)
|
|
} else {
|
|
ecelFlags = uint8(0)
|
|
}
|
|
if pSort != 0 && hasDistinct == 0 && eDest != int32(SRT_EphemTab) && eDest != int32(SRT_Table) {
|
|
/* For each expression in p->pEList that is a copy of an expression in
|
|
** the ORDER BY clause (pSort->pOrderBy), set the associated
|
|
** iOrderByCol value to one more than the index of the ORDER BY
|
|
** expression within the sort-key that pushOntoSorter() will generate.
|
|
** This allows the p->pEList field to be omitted from the sorted record,
|
|
** saving space and CPU cycles. */
|
|
ecelFlags = libc.Uint8FromInt32(int32(ecelFlags) | (libc.Int32FromInt32(SQLITE_ECEL_OMITREF) | libc.Int32FromInt32(SQLITE_ECEL_REF)))
|
|
i = (*TSortCtx)(unsafe.Pointer(pSort)).FnOBSat
|
|
for {
|
|
if !(i < (*TExprList)(unsafe.Pointer((*TSortCtx)(unsafe.Pointer(pSort)).FpOrderBy)).FnExpr) {
|
|
break
|
|
}
|
|
v1 = libc.Int32FromUint16(*(*Tu16)(unsafe.Pointer((*TSortCtx)(unsafe.Pointer(pSort)).FpOrderBy + 8 + uintptr(i)*32 + 24)))
|
|
j = v1
|
|
if v1 > 0 {
|
|
*(*Tu16)(unsafe.Pointer((*TSelect)(unsafe.Pointer(p)).FpEList + 8 + uintptr(j-int32(1))*32 + 24)) = libc.Uint16FromInt32(i + int32(1) - (*TSortCtx)(unsafe.Pointer(pSort)).FnOBSat)
|
|
}
|
|
goto _4
|
|
_4:
|
|
;
|
|
i = i + 1
|
|
}
|
|
/* Adjust nResultCol to account for columns that are omitted
|
|
** from the sorter by the optimizations in this branch */
|
|
pEList = (*TSelect)(unsafe.Pointer(p)).FpEList
|
|
i = 0
|
|
for {
|
|
if !(i < (*TExprList)(unsafe.Pointer(pEList)).FnExpr) {
|
|
break
|
|
}
|
|
if libc.Int32FromUint16(*(*Tu16)(unsafe.Pointer(pEList + 8 + uintptr(i)*32 + 24))) > 0 {
|
|
nResultCol = nResultCol - 1
|
|
regOrig = 0
|
|
}
|
|
goto _6
|
|
_6:
|
|
;
|
|
i = i + 1
|
|
}
|
|
}
|
|
(**(**TRowLoadInfo)(__ccgo_up(bp))).FregResult = regResult
|
|
(**(**TRowLoadInfo)(__ccgo_up(bp))).FecelFlags = ecelFlags
|
|
if (*TSelect)(unsafe.Pointer(p)).FiLimit != 0 && libc.Int32FromUint8(ecelFlags)&int32(SQLITE_ECEL_OMITREF) != 0 && nPrefixReg > 0 {
|
|
(*TSortCtx)(unsafe.Pointer(pSort)).FpDeferredRowLoad = bp
|
|
regOrig = 0
|
|
} else {
|
|
_innerLoopLoadRow(tls, pParse, p, bp)
|
|
}
|
|
}
|
|
}
|
|
/* If the DISTINCT keyword was present on the SELECT statement
|
|
** and this row has been seen before, then do not make this row
|
|
** part of the result.
|
|
*/
|
|
if hasDistinct != 0 {
|
|
eType = libc.Int32FromUint8((*TDistinctCtx)(unsafe.Pointer(pDistinct)).FeTnctType)
|
|
iTab = (*TDistinctCtx)(unsafe.Pointer(pDistinct)).FtabTnct
|
|
iTab = _codeDistinct(tls, pParse, eType, iTab, iContinue, (*TSelect)(unsafe.Pointer(p)).FpEList, regResult)
|
|
_fixDistinctOpenEph(tls, pParse, eType, iTab, (*TDistinctCtx)(unsafe.Pointer(pDistinct)).FaddrTnct)
|
|
if pSort == uintptr(0) {
|
|
_codeOffset(tls, v, (*TSelect)(unsafe.Pointer(p)).FiOffset, iContinue)
|
|
}
|
|
}
|
|
switch eDest {
|
|
/* Store the result as data using a unique key.
|
|
*/
|
|
case int32(SRT_Fifo):
|
|
fallthrough
|
|
case int32(SRT_DistFifo):
|
|
fallthrough
|
|
case int32(SRT_Table):
|
|
fallthrough
|
|
case int32(SRT_EphemTab):
|
|
r1 = _sqlite3GetTempRange(tls, pParse, nPrefixReg+int32(1))
|
|
_sqlite3VdbeAddOp3(tls, v, int32(OP_MakeRecord), regResult, nResultCol, r1+nPrefixReg)
|
|
if eDest == int32(SRT_DistFifo) {
|
|
/* If the destination is DistFifo, then cursor (iParm+1) is open
|
|
** on an ephemeral index. If the current row is already present
|
|
** in the index, do not write it to the output. If not, add the
|
|
** current row to the index and proceed with writing it to the
|
|
** output table as well. */
|
|
addr = _sqlite3VdbeCurrentAddr(tls, v) + int32(4)
|
|
_sqlite3VdbeAddOp4Int(tls, v, int32(OP_Found), iParm+int32(1), addr, r1, 0)
|
|
_sqlite3VdbeAddOp4Int(tls, v, int32(OP_IdxInsert), iParm+int32(1), r1, regResult, nResultCol)
|
|
}
|
|
if pSort != 0 {
|
|
_pushOntoSorter(tls, pParse, pSort, p, r1+nPrefixReg, regOrig, int32(1), nPrefixReg)
|
|
} else {
|
|
r2 = _sqlite3GetTempReg(tls, pParse)
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_NewRowid), iParm, r2)
|
|
_sqlite3VdbeAddOp3(tls, v, int32(OP_Insert), iParm, r1, r2)
|
|
_sqlite3VdbeChangeP5(tls, v, uint16(OPFLAG_APPEND))
|
|
_sqlite3ReleaseTempReg(tls, pParse, r2)
|
|
}
|
|
_sqlite3ReleaseTempRange(tls, pParse, r1, nPrefixReg+int32(1))
|
|
case int32(SRT_Upfrom):
|
|
if pSort != 0 {
|
|
_pushOntoSorter(tls, pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg)
|
|
} else {
|
|
i2 = (*TSelectDest)(unsafe.Pointer(pDest)).FiSDParm2
|
|
r11 = _sqlite3GetTempReg(tls, pParse)
|
|
/* If the UPDATE FROM join is an aggregate that matches no rows, it
|
|
** might still be trying to return one row, because that is what
|
|
** aggregates do. Don't record that empty row in the output table. */
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_IsNull), regResult, iBreak)
|
|
_sqlite3VdbeAddOp3(tls, v, int32(OP_MakeRecord), regResult+libc.BoolInt32(i2 < 0), nResultCol-libc.BoolInt32(i2 < 0), r11)
|
|
if i2 < 0 {
|
|
_sqlite3VdbeAddOp3(tls, v, int32(OP_Insert), iParm, r11, regResult)
|
|
} else {
|
|
_sqlite3VdbeAddOp4Int(tls, v, int32(OP_IdxInsert), iParm, r11, regResult, i2)
|
|
}
|
|
}
|
|
break
|
|
/* If we are creating a set for an "expr IN (SELECT ...)" construct,
|
|
** then there should be a single item on the stack. Write this
|
|
** item into the set table with bogus data.
|
|
*/
|
|
fallthrough
|
|
case int32(SRT_Set):
|
|
if pSort != 0 {
|
|
/* At first glance you would think we could optimize out the
|
|
** ORDER BY in this case since the order of entries in the set
|
|
** does not matter. But there might be a LIMIT clause, in which
|
|
** case the order does matter */
|
|
_pushOntoSorter(tls, pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg)
|
|
(*TSelectDest)(unsafe.Pointer(pDest)).FiSDParm2 = 0 /* Signal that any Bloom filter is unpopulated */
|
|
} else {
|
|
r12 = _sqlite3GetTempReg(tls, pParse)
|
|
_sqlite3VdbeAddOp4(tls, v, int32(OP_MakeRecord), regResult, nResultCol, r12, (*TSelectDest)(unsafe.Pointer(pDest)).FzAffSdst, nResultCol)
|
|
_sqlite3VdbeAddOp4Int(tls, v, int32(OP_IdxInsert), iParm, r12, regResult, nResultCol)
|
|
if (*TSelectDest)(unsafe.Pointer(pDest)).FiSDParm2 != 0 {
|
|
_sqlite3VdbeAddOp4Int(tls, v, int32(OP_FilterAdd), (*TSelectDest)(unsafe.Pointer(pDest)).FiSDParm2, 0, regResult, nResultCol)
|
|
_sqlite3VdbeExplain(tls, pParse, uint8(0), __ccgo_ts+20493, 0)
|
|
}
|
|
_sqlite3ReleaseTempReg(tls, pParse, r12)
|
|
}
|
|
break
|
|
/* If any row exist in the result set, record that fact and abort.
|
|
*/
|
|
fallthrough
|
|
case int32(SRT_Exists):
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_Integer), int32(1), iParm)
|
|
/* The LIMIT clause will terminate the loop for us */
|
|
break
|
|
/* If this is a scalar select that is part of an expression, then
|
|
** store the results in the appropriate memory cell or array of
|
|
** memory cells and break out of the scan loop.
|
|
*/
|
|
fallthrough
|
|
case int32(SRT_Mem):
|
|
if pSort != 0 {
|
|
_pushOntoSorter(tls, pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg)
|
|
(*TSelectDest)(unsafe.Pointer(pDest)).FiSDParm = regResult
|
|
} else {
|
|
if regResult != iParm {
|
|
/* This occurs in cases where the SELECT had both a DISTINCT and
|
|
** an OFFSET clause. */
|
|
_sqlite3VdbeAddOp3(tls, v, int32(OP_Copy), regResult, iParm, nResultCol-int32(1))
|
|
}
|
|
/* The LIMIT clause will jump out of the loop for us */
|
|
}
|
|
case int32(SRT_Coroutine): /* Send data to a co-routine */
|
|
fallthrough
|
|
case int32(SRT_Output): /* Return the results */
|
|
if pSort != 0 {
|
|
_pushOntoSorter(tls, pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg)
|
|
} else {
|
|
if eDest == int32(SRT_Coroutine) {
|
|
_sqlite3VdbeAddOp1(tls, v, int32(OP_Yield), (*TSelectDest)(unsafe.Pointer(pDest)).FiSDParm)
|
|
} else {
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_ResultRow), regResult, nResultCol)
|
|
}
|
|
}
|
|
break
|
|
/* Write the results into a priority queue that is order according to
|
|
** pDest->pOrderBy (in pSO). pDest->iSDParm (in iParm) is the cursor for an
|
|
** index with pSO->nExpr+2 columns. Build a key using pSO for the first
|
|
** pSO->nExpr columns, then make sure all keys are unique by adding a
|
|
** final OP_Sequence column. The last column is the record as a blob.
|
|
*/
|
|
fallthrough
|
|
case int32(SRT_DistQueue):
|
|
fallthrough
|
|
case int32(SRT_Queue):
|
|
addrTest = 0
|
|
pSO = (*TSelectDest)(unsafe.Pointer(pDest)).FpOrderBy
|
|
nKey = (*TExprList)(unsafe.Pointer(pSO)).FnExpr
|
|
r13 = _sqlite3GetTempReg(tls, pParse)
|
|
r21 = _sqlite3GetTempRange(tls, pParse, nKey+int32(2))
|
|
r3 = r21 + nKey + int32(1)
|
|
if eDest == int32(SRT_DistQueue) {
|
|
/* If the destination is DistQueue, then cursor (iParm+1) is open
|
|
** on a second ephemeral index that holds all values every previously
|
|
** added to the queue. */
|
|
addrTest = _sqlite3VdbeAddOp4Int(tls, v, int32(OP_Found), iParm+int32(1), 0, regResult, nResultCol)
|
|
}
|
|
_sqlite3VdbeAddOp3(tls, v, int32(OP_MakeRecord), regResult, nResultCol, r3)
|
|
if eDest == int32(SRT_DistQueue) {
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_IdxInsert), iParm+int32(1), r3)
|
|
_sqlite3VdbeChangeP5(tls, v, uint16(OPFLAG_USESEEKRESULT))
|
|
}
|
|
i = 0
|
|
for {
|
|
if !(i < nKey) {
|
|
break
|
|
}
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_SCopy), regResult+libc.Int32FromUint16(*(*Tu16)(unsafe.Pointer(pSO + 8 + uintptr(i)*32 + 24)))-int32(1), r21+i)
|
|
goto _7
|
|
_7:
|
|
;
|
|
i = i + 1
|
|
}
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_Sequence), iParm, r21+nKey)
|
|
_sqlite3VdbeAddOp3(tls, v, int32(OP_MakeRecord), r21, nKey+int32(2), r13)
|
|
_sqlite3VdbeAddOp4Int(tls, v, int32(OP_IdxInsert), iParm, r13, r21, nKey+int32(2))
|
|
if addrTest != 0 {
|
|
_sqlite3VdbeJumpHere(tls, v, addrTest)
|
|
}
|
|
_sqlite3ReleaseTempReg(tls, pParse, r13)
|
|
_sqlite3ReleaseTempRange(tls, pParse, r21, nKey+int32(2))
|
|
break
|
|
/* Discard the results. This is used for SELECT statements inside
|
|
** the body of a TRIGGER. The purpose of such selects is to call
|
|
** user-defined functions that have side effects. We do not care
|
|
** about the actual results of the select.
|
|
*/
|
|
fallthrough
|
|
default:
|
|
break
|
|
}
|
|
/* Jump to the end of the loop if the LIMIT is reached. Except, if
|
|
** there is a sorter, in which case the sorter has already limited
|
|
** the output for us.
|
|
*/
|
|
if pSort == uintptr(0) && (*TSelect)(unsafe.Pointer(p)).FiLimit != 0 {
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_DecrJumpZero), (*TSelect)(unsafe.Pointer(p)).FiLimit, iBreak)
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Return a comma-separated list of the fully-qualified (with both database
|
|
// ** and table name) column names from table pTab. e.g.
|
|
// **
|
|
// ** "main"."t1"."a", "main"."t1"."b", "main"."t1"."c"
|
|
// */
|
|
func _sessionAllCols(tls *libc.TLS, zDb uintptr, pTab uintptr) (r uintptr) {
|
|
bp := tls.Alloc(48)
|
|
defer tls.Free(48)
|
|
var ii int32
|
|
var zRet, v2 uintptr
|
|
_, _, _ = ii, zRet, v2
|
|
zRet = uintptr(0)
|
|
ii = 0
|
|
for {
|
|
if !(ii < (*TSessionTable)(unsafe.Pointer(pTab)).FnCol) {
|
|
break
|
|
}
|
|
if zRet != 0 {
|
|
v2 = __ccgo_ts + 16242
|
|
} else {
|
|
v2 = __ccgo_ts + 1704
|
|
}
|
|
zRet = Xsqlite3_mprintf(tls, __ccgo_ts+35555, libc.VaList(bp+8, zRet, v2, zDb, (*TSessionTable)(unsafe.Pointer(pTab)).FzName, **(**uintptr)(__ccgo_up((*TSessionTable)(unsafe.Pointer(pTab)).FazCol + uintptr(ii)*8))))
|
|
if !(zRet != 0) {
|
|
break
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
ii = ii + 1
|
|
}
|
|
return zRet
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Argument pIter is a changeset iterator that has been initialized, but
|
|
// ** not yet passed to sqlite3changeset_next(). This function applies the
|
|
// ** changeset to the main database attached to handle "db". The supplied
|
|
// ** conflict handler callback is invoked to resolve any conflicts encountered
|
|
// ** while applying the change.
|
|
// */
|
|
func _sessionChangesetApply(tls *libc.TLS, db uintptr, pIter uintptr, __ccgo_fp_xFilter uintptr, __ccgo_fp_xFilterIter uintptr, __ccgo_fp_xConflict uintptr, pCtx uintptr, ppRebase uintptr, pnRebase uintptr, flags int32) (r int32) {
|
|
bp := tls.Alloc(368)
|
|
defer tls.Free(368)
|
|
var bPatchset, i, nMinCol, nTab, rc, rc2, res, schemaMismatch, v2, v3, v4 int32
|
|
var savedFlag Tu64
|
|
var v5, v7 bool
|
|
var _ /* abPK at bp+160 */ uintptr
|
|
var _ /* nCol at bp+144 */ int32
|
|
var _ /* nFk at bp+168 */ int32
|
|
var _ /* notUsed at bp+172 */ int32
|
|
var _ /* op at bp+148 */ int32
|
|
var _ /* sApply at bp+8 */ TSessionApplyCtx
|
|
var _ /* sIter at bp+176 */ Tsqlite3_changeset_iter
|
|
var _ /* zNew at bp+152 */ uintptr
|
|
var _ /* zTab at bp+0 */ uintptr
|
|
_, _, _, _, _, _, _, _, _, _, _, _, _, _ = bPatchset, i, nMinCol, nTab, rc, rc2, res, savedFlag, schemaMismatch, v2, v3, v4, v5, v7
|
|
schemaMismatch = 0
|
|
rc = SQLITE_OK /* Return code */
|
|
**(**uintptr)(__ccgo_up(bp)) = uintptr(0) /* Name of current table */
|
|
nTab = 0
|
|
savedFlag = (*Tsqlite3)(unsafe.Pointer(db)).Fflags & (libc.Uint64FromInt32(libc.Int32FromInt32(0x00008)) << libc.Int32FromInt32(32))
|
|
Xsqlite3_mutex_enter(tls, Xsqlite3_db_mutex(tls, db))
|
|
if flags&int32(SQLITE_CHANGESETAPPLY_FKNOACTION) != 0 {
|
|
**(**Tu64)(__ccgo_up(db + 48)) |= libc.Uint64FromInt32(libc.Int32FromInt32(0x00008)) << libc.Int32FromInt32(32)
|
|
**(**int32)(__ccgo_up((**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb))).FpSchema)) -= int32(32)
|
|
}
|
|
(*Tsqlite3_changeset_iter)(unsafe.Pointer(pIter)).Fin.FbNoDiscard = int32(1)
|
|
libc.Xmemset(tls, bp+8, 0, uint64(136))
|
|
(**(**TSessionApplyCtx)(__ccgo_up(bp + 8))).FbRebase = libc.BoolUint8(ppRebase != 0 && pnRebase != 0)
|
|
(**(**TSessionApplyCtx)(__ccgo_up(bp + 8))).FbInvertConstraints = libc.BoolInt32(!!(flags&libc.Int32FromInt32(SQLITE_CHANGESETAPPLY_INVERT) != 0))
|
|
(**(**TSessionApplyCtx)(__ccgo_up(bp + 8))).FbIgnoreNoop = libc.BoolUint8(!!(flags&libc.Int32FromInt32(SQLITE_CHANGESETAPPLY_IGNORENOOP) != 0))
|
|
(**(**TSessionApplyCtx)(__ccgo_up(bp + 8))).FbNoUpdateLoop = libc.BoolUint8(!!(flags&libc.Int32FromInt32(SQLITE_CHANGESETAPPLY_NOUPDATELOOP) != 0))
|
|
if flags&int32(SQLITE_CHANGESETAPPLY_NOSAVEPOINT) == 0 {
|
|
rc = Xsqlite3_exec(tls, db, __ccgo_ts+36541, uintptr(0), uintptr(0), uintptr(0))
|
|
}
|
|
if rc == SQLITE_OK {
|
|
rc = Xsqlite3_exec(tls, db, __ccgo_ts+36567, uintptr(0), uintptr(0), uintptr(0))
|
|
}
|
|
for rc == SQLITE_OK && int32(SQLITE_ROW) == Xsqlite3changeset_next(tls, pIter) {
|
|
Xsqlite3changeset_op(tls, pIter, bp+152, bp+144, bp+148, uintptr(0))
|
|
if **(**uintptr)(__ccgo_up(bp)) == uintptr(0) || Xsqlite3_strnicmp(tls, **(**uintptr)(__ccgo_up(bp + 152)), **(**uintptr)(__ccgo_up(bp)), nTab+int32(1)) != 0 {
|
|
rc = _sessionRetryConstraints(tls, db, (*Tsqlite3_changeset_iter)(unsafe.Pointer(pIter)).FbPatchset, **(**uintptr)(__ccgo_up(bp)), bp+8, __ccgo_fp_xConflict, pCtx)
|
|
if rc != SQLITE_OK {
|
|
break
|
|
}
|
|
_sessionUpdateFree(tls, bp+8)
|
|
Xsqlite3_free(tls, (**(**TSessionApplyCtx)(__ccgo_up(bp + 8))).FazCol) /* cast works around VC++ bug */
|
|
Xsqlite3_finalize(tls, (**(**TSessionApplyCtx)(__ccgo_up(bp + 8))).FpDelete)
|
|
Xsqlite3_finalize(tls, (**(**TSessionApplyCtx)(__ccgo_up(bp + 8))).FpInsert)
|
|
Xsqlite3_finalize(tls, (**(**TSessionApplyCtx)(__ccgo_up(bp + 8))).FpSelect)
|
|
(**(**TSessionApplyCtx)(__ccgo_up(bp + 8))).Fdb = db
|
|
(**(**TSessionApplyCtx)(__ccgo_up(bp + 8))).FpDelete = uintptr(0)
|
|
(**(**TSessionApplyCtx)(__ccgo_up(bp + 8))).FpInsert = uintptr(0)
|
|
(**(**TSessionApplyCtx)(__ccgo_up(bp + 8))).FpSelect = uintptr(0)
|
|
(**(**TSessionApplyCtx)(__ccgo_up(bp + 8))).FnCol = 0
|
|
(**(**TSessionApplyCtx)(__ccgo_up(bp + 8))).FazCol = uintptr(0)
|
|
(**(**TSessionApplyCtx)(__ccgo_up(bp + 8))).FabPK = uintptr(0)
|
|
(**(**TSessionApplyCtx)(__ccgo_up(bp + 8))).FbStat1 = 0
|
|
(**(**TSessionApplyCtx)(__ccgo_up(bp + 8))).FbDeferConstraints = int32(1)
|
|
(**(**TSessionApplyCtx)(__ccgo_up(bp + 8))).FbRebaseStarted = uint8(0)
|
|
(**(**TSessionApplyCtx)(__ccgo_up(bp + 8))).FbRowid = 0
|
|
libc.Xmemset(tls, bp+8+88, 0, uint64(16))
|
|
/* If an xFilter() callback was specified, invoke it now. If the
|
|
** xFilter callback returns zero, skip this table. If it returns
|
|
** non-zero, proceed. */
|
|
schemaMismatch = libc.BoolInt32(__ccgo_fp_xFilter != 0 && 0 == (*(*func(*libc.TLS, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{__ccgo_fp_xFilter})))(tls, pCtx, **(**uintptr)(__ccgo_up(bp + 152))))
|
|
if schemaMismatch != 0 {
|
|
**(**uintptr)(__ccgo_up(bp)) = Xsqlite3_mprintf(tls, __ccgo_ts+3968, libc.VaList(bp+336, **(**uintptr)(__ccgo_up(bp + 152))))
|
|
if **(**uintptr)(__ccgo_up(bp)) == uintptr(0) {
|
|
rc = int32(SQLITE_NOMEM)
|
|
break
|
|
}
|
|
nTab = libc.Int32FromUint64(libc.Xstrlen(tls, **(**uintptr)(__ccgo_up(bp))))
|
|
(**(**TSessionApplyCtx)(__ccgo_up(bp + 8))).FazCol = **(**uintptr)(__ccgo_up(bp))
|
|
} else {
|
|
nMinCol = 0
|
|
Xsqlite3changeset_pk(tls, pIter, bp+160, uintptr(0))
|
|
rc = _sessionTableInfo(tls, uintptr(0), db, __ccgo_ts+6844, **(**uintptr)(__ccgo_up(bp + 152)), bp+8+32, uintptr(0), bp, bp+8+40, uintptr(0), uintptr(0), bp+8+48, bp+8+124)
|
|
if rc != SQLITE_OK {
|
|
break
|
|
}
|
|
i = 0
|
|
for {
|
|
if !(i < (**(**TSessionApplyCtx)(__ccgo_up(bp + 8))).FnCol) {
|
|
break
|
|
}
|
|
if **(**Tu8)(__ccgo_up((**(**TSessionApplyCtx)(__ccgo_up(bp + 8))).FabPK + uintptr(i))) != 0 {
|
|
nMinCol = i + int32(1)
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
if (**(**TSessionApplyCtx)(__ccgo_up(bp + 8))).FnCol == 0 {
|
|
schemaMismatch = int32(1)
|
|
Xsqlite3_log(tls, int32(SQLITE_SCHEMA), __ccgo_ts+36597, libc.VaList(bp+336, **(**uintptr)(__ccgo_up(bp))))
|
|
} else {
|
|
if (**(**TSessionApplyCtx)(__ccgo_up(bp + 8))).FnCol < **(**int32)(__ccgo_up(bp + 144)) {
|
|
schemaMismatch = int32(1)
|
|
Xsqlite3_log(tls, int32(SQLITE_SCHEMA), __ccgo_ts+36641, libc.VaList(bp+336, **(**uintptr)(__ccgo_up(bp)), (**(**TSessionApplyCtx)(__ccgo_up(bp + 8))).FnCol, **(**int32)(__ccgo_up(bp + 144))))
|
|
} else {
|
|
if **(**int32)(__ccgo_up(bp + 144)) < nMinCol || libc.Xmemcmp(tls, (**(**TSessionApplyCtx)(__ccgo_up(bp + 8))).FabPK, **(**uintptr)(__ccgo_up(bp + 160)), libc.Uint64FromInt32(**(**int32)(__ccgo_up(bp + 144)))) != 0 {
|
|
schemaMismatch = int32(1)
|
|
Xsqlite3_log(tls, int32(SQLITE_SCHEMA), __ccgo_ts+36712, libc.VaList(bp+336, **(**uintptr)(__ccgo_up(bp))))
|
|
} else {
|
|
(**(**TSessionApplyCtx)(__ccgo_up(bp + 8))).FnCol = **(**int32)(__ccgo_up(bp + 144))
|
|
if 0 == Xsqlite3_stricmp(tls, **(**uintptr)(__ccgo_up(bp)), __ccgo_ts+12861) {
|
|
v2 = _sessionStat1Sql(tls, db, bp+8)
|
|
rc = v2
|
|
if v2 != 0 {
|
|
break
|
|
}
|
|
(**(**TSessionApplyCtx)(__ccgo_up(bp + 8))).FbStat1 = int32(1)
|
|
} else {
|
|
v2 = _sessionSelectRow(tls, db, **(**uintptr)(__ccgo_up(bp)), bp+8)
|
|
rc = v2
|
|
if v5 = v2 != 0; !v5 {
|
|
v3 = _sessionDeleteRow(tls, db, **(**uintptr)(__ccgo_up(bp)), bp+8)
|
|
rc = v3
|
|
}
|
|
if v7 = v5 || v3 != 0; !v7 {
|
|
v4 = _sessionInsertRow(tls, db, **(**uintptr)(__ccgo_up(bp)), bp+8)
|
|
rc = v4
|
|
}
|
|
if v7 || v4 != 0 {
|
|
break
|
|
}
|
|
(**(**TSessionApplyCtx)(__ccgo_up(bp + 8))).FbStat1 = 0
|
|
}
|
|
}
|
|
}
|
|
}
|
|
nTab = _sqlite3Strlen30(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
}
|
|
}
|
|
/* If there is a schema mismatch on the current table, proceed to the
|
|
** next change. A log message has already been issued. */
|
|
if schemaMismatch != 0 {
|
|
continue
|
|
}
|
|
/* If this is a call to apply_v3(), invoke xFilterIter here. */
|
|
if __ccgo_fp_xFilterIter != 0 && 0 == (*(*func(*libc.TLS, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{__ccgo_fp_xFilterIter})))(tls, pCtx, pIter) {
|
|
continue
|
|
}
|
|
rc = _sessionApplyOneWithRetry(tls, db, pIter, bp+8, __ccgo_fp_xConflict, pCtx)
|
|
}
|
|
bPatchset = (*Tsqlite3_changeset_iter)(unsafe.Pointer(pIter)).FbPatchset
|
|
if rc == SQLITE_OK {
|
|
rc = Xsqlite3changeset_finalize(tls, pIter)
|
|
} else {
|
|
Xsqlite3changeset_finalize(tls, pIter)
|
|
}
|
|
if rc == SQLITE_OK {
|
|
rc = _sessionRetryConstraints(tls, db, bPatchset, **(**uintptr)(__ccgo_up(bp)), bp+8, __ccgo_fp_xConflict, pCtx)
|
|
}
|
|
if rc == SQLITE_OK {
|
|
Xsqlite3_db_status(tls, db, int32(SQLITE_DBSTATUS_DEFERRED_FKS), bp+168, bp+172, 0)
|
|
if **(**int32)(__ccgo_up(bp + 168)) != 0 {
|
|
res = int32(SQLITE_CHANGESET_ABORT)
|
|
libc.Xmemset(tls, bp+176, 0, uint64(152))
|
|
(**(**Tsqlite3_changeset_iter)(__ccgo_up(bp + 176))).FnCol = **(**int32)(__ccgo_up(bp + 168))
|
|
res = (*(*func(*libc.TLS, uintptr, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{__ccgo_fp_xConflict})))(tls, pCtx, int32(SQLITE_CHANGESET_FOREIGN_KEY), bp+176)
|
|
if res != SQLITE_CHANGESET_OMIT {
|
|
rc = int32(SQLITE_CONSTRAINT)
|
|
}
|
|
}
|
|
}
|
|
rc2 = Xsqlite3_exec(tls, db, __ccgo_ts+36772, uintptr(0), uintptr(0), uintptr(0))
|
|
if rc == SQLITE_OK {
|
|
rc = rc2
|
|
}
|
|
if flags&int32(SQLITE_CHANGESETAPPLY_NOSAVEPOINT) == 0 {
|
|
if rc == SQLITE_OK {
|
|
rc = Xsqlite3_exec(tls, db, __ccgo_ts+36802, uintptr(0), uintptr(0), uintptr(0))
|
|
}
|
|
if rc != SQLITE_OK {
|
|
Xsqlite3_exec(tls, db, __ccgo_ts+36826, uintptr(0), uintptr(0), uintptr(0))
|
|
Xsqlite3_exec(tls, db, __ccgo_ts+36802, uintptr(0), uintptr(0), uintptr(0))
|
|
}
|
|
}
|
|
if rc == SQLITE_OK && bPatchset == 0 && (**(**TSessionApplyCtx)(__ccgo_up(bp + 8))).FbRebase != 0 {
|
|
**(**uintptr)(__ccgo_up(ppRebase)) = (**(**TSessionApplyCtx)(__ccgo_up(bp + 8))).Frebase.FaBuf
|
|
**(**int32)(__ccgo_up(pnRebase)) = (**(**TSessionApplyCtx)(__ccgo_up(bp + 8))).Frebase.FnBuf
|
|
(**(**TSessionApplyCtx)(__ccgo_up(bp + 8))).Frebase.FaBuf = uintptr(0)
|
|
}
|
|
_sessionUpdateFree(tls, bp+8)
|
|
Xsqlite3_finalize(tls, (**(**TSessionApplyCtx)(__ccgo_up(bp + 8))).FpInsert)
|
|
Xsqlite3_finalize(tls, (**(**TSessionApplyCtx)(__ccgo_up(bp + 8))).FpDelete)
|
|
Xsqlite3_finalize(tls, (**(**TSessionApplyCtx)(__ccgo_up(bp + 8))).FpSelect)
|
|
Xsqlite3_free(tls, (**(**TSessionApplyCtx)(__ccgo_up(bp + 8))).FazCol) /* cast works around VC++ bug */
|
|
Xsqlite3_free(tls, (**(**TSessionApplyCtx)(__ccgo_up(bp + 8))).Fconstraints.FaBuf)
|
|
Xsqlite3_free(tls, (**(**TSessionApplyCtx)(__ccgo_up(bp + 8))).Frebase.FaBuf)
|
|
if flags&int32(SQLITE_CHANGESETAPPLY_FKNOACTION) != 0 && savedFlag == uint64(0) {
|
|
**(**Tu64)(__ccgo_up(db + 48)) &= ^(libc.Uint64FromInt32(libc.Int32FromInt32(0x00008)) << libc.Int32FromInt32(32))
|
|
**(**int32)(__ccgo_up((**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb))).FpSchema)) -= int32(32)
|
|
}
|
|
Xsqlite3_set_errmsg(tls, db, rc, (**(**TSessionApplyCtx)(__ccgo_up(bp + 8))).FzErr)
|
|
Xsqlite3_free(tls, (**(**TSessionApplyCtx)(__ccgo_up(bp + 8))).FzErr)
|
|
Xsqlite3_mutex_leave(tls, Xsqlite3_db_mutex(tls, db))
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Formulate a statement to DELETE a row from database db. Assuming a table
|
|
// ** structure like this:
|
|
// **
|
|
// ** CREATE TABLE x(a, b, c, d, PRIMARY KEY(a, c));
|
|
// **
|
|
// ** The DELETE statement looks like this:
|
|
// **
|
|
// ** DELETE FROM x WHERE a = :1 AND c = :3 AND (:5 OR b IS :2 AND d IS :4)
|
|
// **
|
|
// ** Variable :5 (nCol+1) is a boolean. It should be set to 0 if we require
|
|
// ** matching b and d values, or 1 otherwise. The second case comes up if the
|
|
// ** conflict handler is invoked with NOTFOUND and returns CHANGESET_REPLACE.
|
|
// **
|
|
// ** If successful, SQLITE_OK is returned and SessionApplyCtx.pDelete is left
|
|
// ** pointing to the prepared version of the SQL statement.
|
|
// */
|
|
func _sessionDeleteRow(tls *libc.TLS, db uintptr, zTab uintptr, p uintptr) (r int32) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var i, nPk int32
|
|
var zSep uintptr
|
|
var _ /* buf at bp+8 */ TSessionBuffer
|
|
var _ /* rc at bp+0 */ int32
|
|
_, _, _ = i, nPk, zSep
|
|
zSep = __ccgo_ts + 1704
|
|
**(**int32)(__ccgo_up(bp)) = SQLITE_OK
|
|
**(**TSessionBuffer)(__ccgo_up(bp + 8)) = TSessionBuffer{}
|
|
nPk = 0
|
|
_sessionAppendStr(tls, bp+8, __ccgo_ts+36030, bp)
|
|
_sessionAppendIdent(tls, bp+8, zTab, bp)
|
|
_sessionAppendStr(tls, bp+8, __ccgo_ts+35941, bp)
|
|
i = 0
|
|
for {
|
|
if !(i < (*TSessionApplyCtx)(unsafe.Pointer(p)).FnCol) {
|
|
break
|
|
}
|
|
if **(**Tu8)(__ccgo_up((*TSessionApplyCtx)(unsafe.Pointer(p)).FabPK + uintptr(i))) != 0 {
|
|
nPk = nPk + 1
|
|
_sessionAppendStr(tls, bp+8, zSep, bp)
|
|
_sessionAppendIdent(tls, bp+8, **(**uintptr)(__ccgo_up((*TSessionApplyCtx)(unsafe.Pointer(p)).FazCol + uintptr(i)*8)), bp)
|
|
_sessionAppendStr(tls, bp+8, __ccgo_ts+35936, bp)
|
|
_sessionAppendInteger(tls, bp+8, i+int32(1), bp)
|
|
zSep = __ccgo_ts + 23653
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
if nPk < (*TSessionApplyCtx)(unsafe.Pointer(p)).FnCol {
|
|
_sessionAppendStr(tls, bp+8, __ccgo_ts+36048, bp)
|
|
_sessionAppendInteger(tls, bp+8, (*TSessionApplyCtx)(unsafe.Pointer(p)).FnCol+int32(1), bp)
|
|
_sessionAppendStr(tls, bp+8, __ccgo_ts+35460, bp)
|
|
zSep = __ccgo_ts + 1704
|
|
i = 0
|
|
for {
|
|
if !(i < (*TSessionApplyCtx)(unsafe.Pointer(p)).FnCol) {
|
|
break
|
|
}
|
|
if !(**(**Tu8)(__ccgo_up((*TSessionApplyCtx)(unsafe.Pointer(p)).FabPK + uintptr(i))) != 0) {
|
|
_sessionAppendStr(tls, bp+8, zSep, bp)
|
|
_sessionAppendIdent(tls, bp+8, **(**uintptr)(__ccgo_up((*TSessionApplyCtx)(unsafe.Pointer(p)).FazCol + uintptr(i)*8)), bp)
|
|
_sessionAppendStr(tls, bp+8, __ccgo_ts+36024, bp)
|
|
_sessionAppendInteger(tls, bp+8, i+int32(1), bp)
|
|
zSep = __ccgo_ts + 36056
|
|
}
|
|
goto _2
|
|
_2:
|
|
;
|
|
i = i + 1
|
|
}
|
|
_sessionAppendStr(tls, bp+8, __ccgo_ts+5285, bp)
|
|
}
|
|
if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
|
|
**(**int32)(__ccgo_up(bp)) = _sessionPrepare(tls, db, p+8, p+128, (**(**TSessionBuffer)(__ccgo_up(bp + 8))).FaBuf)
|
|
}
|
|
Xsqlite3_free(tls, (**(**TSessionBuffer)(__ccgo_up(bp + 8))).FaBuf)
|
|
return **(**int32)(__ccgo_up(bp))
|
|
}
|
|
|
|
func _sessionExprCompareOther(tls *libc.TLS, nCol int32, zDb1 uintptr, zDb2 uintptr, zTab uintptr, azCol uintptr, abPK uintptr) (r uintptr) {
|
|
bp := tls.Alloc(80)
|
|
defer tls.Free(80)
|
|
var bHave, i int32
|
|
var zRet, zSep uintptr
|
|
_, _, _, _ = bHave, i, zRet, zSep
|
|
zSep = __ccgo_ts + 1704
|
|
zRet = uintptr(0)
|
|
bHave = 0
|
|
i = 0
|
|
for {
|
|
if !(i < nCol) {
|
|
break
|
|
}
|
|
if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(abPK + uintptr(i)))) == 0 {
|
|
bHave = int32(1)
|
|
zRet = Xsqlite3_mprintf(tls, __ccgo_ts+35419, libc.VaList(bp+8, zRet, zSep, zDb1, zTab, **(**uintptr)(__ccgo_up(azCol + uintptr(i)*8)), zDb2, zTab, **(**uintptr)(__ccgo_up(azCol + uintptr(i)*8))))
|
|
zSep = __ccgo_ts + 35460
|
|
if zRet == uintptr(0) {
|
|
break
|
|
}
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
if bHave == 0 {
|
|
zRet = Xsqlite3_mprintf(tls, __ccgo_ts+1850, 0)
|
|
}
|
|
return zRet
|
|
}
|
|
|
|
func _sessionExprComparePK(tls *libc.TLS, nCol int32, zDb1 uintptr, zDb2 uintptr, zTab uintptr, azCol uintptr, abPK uintptr) (r uintptr) {
|
|
bp := tls.Alloc(80)
|
|
defer tls.Free(80)
|
|
var i int32
|
|
var zRet, zSep uintptr
|
|
_, _, _ = i, zRet, zSep
|
|
zSep = __ccgo_ts + 1704
|
|
zRet = uintptr(0)
|
|
i = 0
|
|
for {
|
|
if !(i < nCol) {
|
|
break
|
|
}
|
|
if **(**Tu8)(__ccgo_up(abPK + uintptr(i))) != 0 {
|
|
zRet = Xsqlite3_mprintf(tls, __ccgo_ts+35385, libc.VaList(bp+8, zRet, zSep, zDb1, zTab, **(**uintptr)(__ccgo_up(azCol + uintptr(i)*8)), zDb2, zTab, **(**uintptr)(__ccgo_up(azCol + uintptr(i)*8))))
|
|
zSep = __ccgo_ts + 23653
|
|
if zRet == uintptr(0) {
|
|
break
|
|
}
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
return zRet
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Generate either a changeset (if argument bPatchset is zero) or a patchset
|
|
// ** (if it is non-zero) based on the current contents of the session object
|
|
// ** passed as the first argument.
|
|
// **
|
|
// ** If no error occurs, SQLITE_OK is returned and the new changeset/patchset
|
|
// ** stored in output variables *pnChangeset and *ppChangeset. Or, if an error
|
|
// ** occurs, an SQLite error code is returned and both output variables set
|
|
// ** to 0.
|
|
// */
|
|
func _sessionGenerateChangeset(tls *libc.TLS, pSession uintptr, bPatchset int32, __ccgo_fp_xOutput uintptr, pOut uintptr, pnChangeset uintptr, ppChangeset uintptr) (r int32) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var db, p, pTab, zName uintptr
|
|
var i, iCol, nNoop, nOldCol, nRewind int32
|
|
var _ /* buf at bp+0 */ TSessionBuffer
|
|
var _ /* pSel at bp+24 */ uintptr
|
|
var _ /* rc at bp+16 */ int32
|
|
_, _, _, _, _, _, _, _, _ = db, i, iCol, nNoop, nOldCol, nRewind, p, pTab, zName
|
|
db = (*Tsqlite3_session)(unsafe.Pointer(pSession)).Fdb /* Used to iterate through attached tables */
|
|
**(**TSessionBuffer)(__ccgo_up(bp)) = TSessionBuffer{} /* Return code */
|
|
/* Zero the output variables in case an error occurs. If this session
|
|
** object is already in the error state (sqlite3_session.rc != SQLITE_OK),
|
|
** this call will be a no-op. */
|
|
if __ccgo_fp_xOutput == uintptr(0) {
|
|
**(**int32)(__ccgo_up(pnChangeset)) = 0
|
|
**(**uintptr)(__ccgo_up(ppChangeset)) = uintptr(0)
|
|
}
|
|
if (*Tsqlite3_session)(unsafe.Pointer(pSession)).Frc != 0 {
|
|
return (*Tsqlite3_session)(unsafe.Pointer(pSession)).Frc
|
|
}
|
|
Xsqlite3_mutex_enter(tls, Xsqlite3_db_mutex(tls, db))
|
|
**(**int32)(__ccgo_up(bp + 16)) = Xsqlite3_exec(tls, (*Tsqlite3_session)(unsafe.Pointer(pSession)).Fdb, __ccgo_ts+35879, uintptr(0), uintptr(0), uintptr(0))
|
|
if **(**int32)(__ccgo_up(bp + 16)) != SQLITE_OK {
|
|
Xsqlite3_mutex_leave(tls, Xsqlite3_db_mutex(tls, db))
|
|
return **(**int32)(__ccgo_up(bp + 16))
|
|
}
|
|
pTab = (*Tsqlite3_session)(unsafe.Pointer(pSession)).FpTable
|
|
for {
|
|
if !(**(**int32)(__ccgo_up(bp + 16)) == SQLITE_OK && pTab != 0) {
|
|
break
|
|
}
|
|
if (*TSessionTable)(unsafe.Pointer(pTab)).FnEntry != 0 {
|
|
zName = (*TSessionTable)(unsafe.Pointer(pTab)).FzName /* Used to iterate through hash buckets */
|
|
**(**uintptr)(__ccgo_up(bp + 24)) = uintptr(0) /* SELECT statement to query table pTab */
|
|
nRewind = (**(**TSessionBuffer)(__ccgo_up(bp))).FnBuf /* Size of buffer after writing tbl header */
|
|
nOldCol = (*TSessionTable)(unsafe.Pointer(pTab)).FnCol
|
|
/* Check the table schema is still Ok. */
|
|
**(**int32)(__ccgo_up(bp + 16)) = _sessionReinitTable(tls, pSession, pTab)
|
|
if **(**int32)(__ccgo_up(bp + 16)) == SQLITE_OK && (*TSessionTable)(unsafe.Pointer(pTab)).FnCol != nOldCol {
|
|
**(**int32)(__ccgo_up(bp + 16)) = _sessionUpdateChanges(tls, pSession, pTab)
|
|
}
|
|
/* Write a table header */
|
|
_sessionAppendTableHdr(tls, bp, bPatchset, pTab, bp+16)
|
|
/* Build and compile a statement to execute: */
|
|
if **(**int32)(__ccgo_up(bp + 16)) == SQLITE_OK {
|
|
**(**int32)(__ccgo_up(bp + 16)) = _sessionSelectStmt(tls, db, 0, (*Tsqlite3_session)(unsafe.Pointer(pSession)).FzDb, zName, (*TSessionTable)(unsafe.Pointer(pTab)).FbRowid, (*TSessionTable)(unsafe.Pointer(pTab)).FnCol, (*TSessionTable)(unsafe.Pointer(pTab)).FazCol, (*TSessionTable)(unsafe.Pointer(pTab)).FabPK, bp+24, uintptr(0))
|
|
}
|
|
nNoop = (**(**TSessionBuffer)(__ccgo_up(bp))).FnBuf
|
|
i = 0
|
|
for {
|
|
if !(i < (*TSessionTable)(unsafe.Pointer(pTab)).FnChange && **(**int32)(__ccgo_up(bp + 16)) == SQLITE_OK) {
|
|
break
|
|
} /* Used to iterate through changes */
|
|
p = **(**uintptr)(__ccgo_up((*TSessionTable)(unsafe.Pointer(pTab)).FapChange + uintptr(i)*8))
|
|
for {
|
|
if !(**(**int32)(__ccgo_up(bp + 16)) == SQLITE_OK && p != 0) {
|
|
break
|
|
}
|
|
**(**int32)(__ccgo_up(bp + 16)) = _sessionSelectBind(tls, **(**uintptr)(__ccgo_up(bp + 24)), (*TSessionTable)(unsafe.Pointer(pTab)).FnCol, (*TSessionTable)(unsafe.Pointer(pTab)).FabPK, p)
|
|
if **(**int32)(__ccgo_up(bp + 16)) != SQLITE_OK {
|
|
goto _3
|
|
}
|
|
if Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp + 24))) == int32(SQLITE_ROW) {
|
|
if libc.Int32FromUint8((*TSessionChange)(unsafe.Pointer(p)).Fop) == int32(SQLITE_INSERT) {
|
|
_sessionAppendByte(tls, bp, uint8(SQLITE_INSERT), bp+16)
|
|
_sessionAppendByte(tls, bp, (*TSessionChange)(unsafe.Pointer(p)).FbIndirect, bp+16)
|
|
iCol = 0
|
|
for {
|
|
if !(iCol < (*TSessionTable)(unsafe.Pointer(pTab)).FnCol) {
|
|
break
|
|
}
|
|
_sessionAppendCol(tls, bp, **(**uintptr)(__ccgo_up(bp + 24)), iCol, bp+16)
|
|
goto _4
|
|
_4:
|
|
;
|
|
iCol = iCol + 1
|
|
}
|
|
} else {
|
|
**(**int32)(__ccgo_up(bp + 16)) = _sessionAppendUpdate(tls, bp, bPatchset, **(**uintptr)(__ccgo_up(bp + 24)), p, (*TSessionTable)(unsafe.Pointer(pTab)).FabPK)
|
|
}
|
|
} else {
|
|
if libc.Int32FromUint8((*TSessionChange)(unsafe.Pointer(p)).Fop) != int32(SQLITE_INSERT) {
|
|
**(**int32)(__ccgo_up(bp + 16)) = _sessionAppendDelete(tls, bp, bPatchset, p, (*TSessionTable)(unsafe.Pointer(pTab)).FnCol, (*TSessionTable)(unsafe.Pointer(pTab)).FabPK)
|
|
}
|
|
}
|
|
if **(**int32)(__ccgo_up(bp + 16)) == SQLITE_OK {
|
|
**(**int32)(__ccgo_up(bp + 16)) = Xsqlite3_reset(tls, **(**uintptr)(__ccgo_up(bp + 24)))
|
|
}
|
|
/* If the buffer is now larger than sessions_strm_chunk_size, pass
|
|
** its contents to the xOutput() callback. */
|
|
if __ccgo_fp_xOutput != 0 && **(**int32)(__ccgo_up(bp + 16)) == SQLITE_OK && (**(**TSessionBuffer)(__ccgo_up(bp))).FnBuf > nNoop && (**(**TSessionBuffer)(__ccgo_up(bp))).FnBuf > _sessions_strm_chunk_size {
|
|
**(**int32)(__ccgo_up(bp + 16)) = (*(*func(*libc.TLS, uintptr, uintptr, int32) int32)(unsafe.Pointer(&struct{ uintptr }{__ccgo_fp_xOutput})))(tls, pOut, (**(**TSessionBuffer)(__ccgo_up(bp))).FaBuf, (**(**TSessionBuffer)(__ccgo_up(bp))).FnBuf)
|
|
nNoop = -int32(1)
|
|
(**(**TSessionBuffer)(__ccgo_up(bp))).FnBuf = 0
|
|
}
|
|
goto _3
|
|
_3:
|
|
;
|
|
p = (*TSessionChange)(unsafe.Pointer(p)).FpNext
|
|
}
|
|
goto _2
|
|
_2:
|
|
;
|
|
i = i + 1
|
|
}
|
|
Xsqlite3_finalize(tls, **(**uintptr)(__ccgo_up(bp + 24)))
|
|
if (**(**TSessionBuffer)(__ccgo_up(bp))).FnBuf == nNoop {
|
|
(**(**TSessionBuffer)(__ccgo_up(bp))).FnBuf = nRewind
|
|
}
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
pTab = (*TSessionTable)(unsafe.Pointer(pTab)).FpNext
|
|
}
|
|
if **(**int32)(__ccgo_up(bp + 16)) == SQLITE_OK {
|
|
if __ccgo_fp_xOutput == uintptr(0) {
|
|
**(**int32)(__ccgo_up(pnChangeset)) = (**(**TSessionBuffer)(__ccgo_up(bp))).FnBuf
|
|
**(**uintptr)(__ccgo_up(ppChangeset)) = (**(**TSessionBuffer)(__ccgo_up(bp))).FaBuf
|
|
(**(**TSessionBuffer)(__ccgo_up(bp))).FaBuf = uintptr(0)
|
|
} else {
|
|
if (**(**TSessionBuffer)(__ccgo_up(bp))).FnBuf > 0 {
|
|
**(**int32)(__ccgo_up(bp + 16)) = (*(*func(*libc.TLS, uintptr, uintptr, int32) int32)(unsafe.Pointer(&struct{ uintptr }{__ccgo_fp_xOutput})))(tls, pOut, (**(**TSessionBuffer)(__ccgo_up(bp))).FaBuf, (**(**TSessionBuffer)(__ccgo_up(bp))).FnBuf)
|
|
}
|
|
}
|
|
}
|
|
Xsqlite3_free(tls, (**(**TSessionBuffer)(__ccgo_up(bp))).FaBuf)
|
|
Xsqlite3_exec(tls, db, __ccgo_ts+35899, uintptr(0), uintptr(0), uintptr(0))
|
|
Xsqlite3_mutex_leave(tls, Xsqlite3_db_mutex(tls, db))
|
|
return **(**int32)(__ccgo_up(bp + 16))
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This function is called to initialize the SessionTable.nCol, azCol[]
|
|
// ** abPK[] and azDflt[] members of SessionTable object pTab. If these
|
|
// ** fields are already initialized, this function is a no-op.
|
|
// **
|
|
// ** If an error occurs, an error code is stored in sqlite3_session.rc and
|
|
// ** non-zero returned. Or, if no error occurs but the table has no primary
|
|
// ** key, sqlite3_session.rc is left set to SQLITE_OK and non-zero returned to
|
|
// ** indicate that updates on this table should be ignored. SessionTable.abPK
|
|
// ** is set to NULL in this case.
|
|
// */
|
|
func _sessionInitTable(tls *libc.TLS, pSession uintptr, pTab uintptr, db uintptr, zDb uintptr) (r int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var i, rc int32
|
|
var v1 uintptr
|
|
var _ /* abPK at bp+0 */ uintptr
|
|
_, _, _ = i, rc, v1
|
|
rc = SQLITE_OK
|
|
if (*TSessionTable)(unsafe.Pointer(pTab)).FnCol == 0 {
|
|
Xsqlite3_free(tls, (*TSessionTable)(unsafe.Pointer(pTab)).FazCol)
|
|
(*TSessionTable)(unsafe.Pointer(pTab)).FabPK = uintptr(0)
|
|
if pSession == uintptr(0) || (*Tsqlite3_session)(unsafe.Pointer(pSession)).FbImplicitPK != 0 {
|
|
v1 = pTab + 28
|
|
} else {
|
|
v1 = uintptr(0)
|
|
}
|
|
rc = _sessionTableInfo(tls, pSession, db, zDb, (*TSessionTable)(unsafe.Pointer(pTab)).FzName, pTab+16, pTab+20, uintptr(0), pTab+32, pTab+40, pTab+48, bp, v1)
|
|
if rc == SQLITE_OK {
|
|
i = 0
|
|
for {
|
|
if !(i < (*TSessionTable)(unsafe.Pointer(pTab)).FnCol) {
|
|
break
|
|
}
|
|
if **(**Tu8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp)) + uintptr(i))) != 0 {
|
|
(*TSessionTable)(unsafe.Pointer(pTab)).FabPK = **(**uintptr)(__ccgo_up(bp))
|
|
break
|
|
}
|
|
goto _2
|
|
_2:
|
|
;
|
|
i = i + 1
|
|
}
|
|
if 0 == Xsqlite3_stricmp(tls, __ccgo_ts+12861, (*TSessionTable)(unsafe.Pointer(pTab)).FzName) {
|
|
(*TSessionTable)(unsafe.Pointer(pTab)).FbStat1 = int32(1)
|
|
}
|
|
if pSession != 0 && (*Tsqlite3_session)(unsafe.Pointer(pSession)).FbEnableSize != 0 {
|
|
v1 = pSession + 64
|
|
*(*Ti64)(unsafe.Pointer(v1)) = Ti64(uint64(*(*Ti64)(unsafe.Pointer(v1))) + uint64(libc.Uint64FromInt32(libc.Int32FromInt32(1)+_sessionVarintLen(tls, (*TSessionTable)(unsafe.Pointer(pTab)).FnCol)+(*TSessionTable)(unsafe.Pointer(pTab)).FnCol)+libc.Xstrlen(tls, (*TSessionTable)(unsafe.Pointer(pTab)).FzName)+libc.Uint64FromInt32(1)))
|
|
}
|
|
}
|
|
}
|
|
if pSession != 0 {
|
|
(*Tsqlite3_session)(unsafe.Pointer(pSession)).Frc = rc
|
|
return libc.BoolInt32(rc != 0 || (*TSessionTable)(unsafe.Pointer(pTab)).FabPK == uintptr(0))
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Formulate and prepare an INSERT statement to add a record to table zTab.
|
|
// ** For example:
|
|
// **
|
|
// ** INSERT INTO main."zTab" VALUES(?1, ?2, ?3 ...);
|
|
// **
|
|
// ** If successful, SQLITE_OK is returned and SessionApplyCtx.pInsert is left
|
|
// ** pointing to the prepared version of the SQL statement.
|
|
// */
|
|
func _sessionInsertRow(tls *libc.TLS, db uintptr, zTab uintptr, p uintptr) (r int32) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var i int32
|
|
var _ /* buf at bp+8 */ TSessionBuffer
|
|
var _ /* rc at bp+0 */ int32
|
|
_ = i
|
|
**(**int32)(__ccgo_up(bp)) = SQLITE_OK
|
|
**(**TSessionBuffer)(__ccgo_up(bp + 8)) = TSessionBuffer{}
|
|
_sessionAppendStr(tls, bp+8, __ccgo_ts+36061, bp)
|
|
_sessionAppendIdent(tls, bp+8, zTab, bp)
|
|
_sessionAppendStr(tls, bp+8, __ccgo_ts+23659, bp)
|
|
i = 0
|
|
for {
|
|
if !(i < (*TSessionApplyCtx)(unsafe.Pointer(p)).FnCol) {
|
|
break
|
|
}
|
|
if i != 0 {
|
|
_sessionAppendStr(tls, bp+8, __ccgo_ts+16242, bp)
|
|
}
|
|
_sessionAppendIdent(tls, bp+8, **(**uintptr)(__ccgo_up((*TSessionApplyCtx)(unsafe.Pointer(p)).FazCol + uintptr(i)*8)), bp)
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
_sessionAppendStr(tls, bp+8, __ccgo_ts+36079, bp)
|
|
i = int32(1)
|
|
for {
|
|
if !(i < (*TSessionApplyCtx)(unsafe.Pointer(p)).FnCol) {
|
|
break
|
|
}
|
|
_sessionAppendStr(tls, bp+8, __ccgo_ts+36090, bp)
|
|
goto _2
|
|
_2:
|
|
;
|
|
i = i + 1
|
|
}
|
|
_sessionAppendStr(tls, bp+8, __ccgo_ts+5285, bp)
|
|
if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
|
|
**(**int32)(__ccgo_up(bp)) = _sessionPrepare(tls, db, p+16, p+128, (**(**TSessionBuffer)(__ccgo_up(bp + 8))).FaBuf)
|
|
}
|
|
Xsqlite3_free(tls, (**(**TSessionBuffer)(__ccgo_up(bp + 8))).FaBuf)
|
|
return **(**int32)(__ccgo_up(bp))
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Prepare a statement against database handle db that SELECTs a single
|
|
// ** row containing the default values for each column in table pTab. For
|
|
// ** example, if pTab is declared as:
|
|
// **
|
|
// ** CREATE TABLE pTab(a PRIMARY KEY, b DEFAULT 123, c DEFAULT 'abcd');
|
|
// **
|
|
// ** Then this function prepares and returns the SQL statement:
|
|
// **
|
|
// ** SELECT NULL, 123, 'abcd';
|
|
// */
|
|
func _sessionPrepareDfltStmt(tls *libc.TLS, db uintptr, pTab uintptr, ppStmt uintptr) (r int32) {
|
|
bp := tls.Alloc(48)
|
|
defer tls.Free(48)
|
|
var ii int32
|
|
var zDflt, zSep, v2 uintptr
|
|
var _ /* rc at bp+16 */ int32
|
|
var _ /* sql at bp+0 */ TSessionBuffer
|
|
_, _, _, _ = ii, zDflt, zSep, v2
|
|
**(**TSessionBuffer)(__ccgo_up(bp)) = TSessionBuffer{}
|
|
**(**int32)(__ccgo_up(bp + 16)) = SQLITE_OK
|
|
zSep = __ccgo_ts + 11569
|
|
ii = 0
|
|
**(**uintptr)(__ccgo_up(ppStmt)) = uintptr(0)
|
|
_sessionAppendPrintf(tls, bp, bp+16, __ccgo_ts+35378, 0)
|
|
ii = 0
|
|
for {
|
|
if !(ii < (*TSessionTable)(unsafe.Pointer(pTab)).FnCol) {
|
|
break
|
|
}
|
|
if **(**uintptr)(__ccgo_up((*TSessionTable)(unsafe.Pointer(pTab)).FazDflt + uintptr(ii)*8)) != 0 {
|
|
v2 = **(**uintptr)(__ccgo_up((*TSessionTable)(unsafe.Pointer(pTab)).FazDflt + uintptr(ii)*8))
|
|
} else {
|
|
v2 = __ccgo_ts + 1705
|
|
}
|
|
zDflt = v2
|
|
_sessionAppendPrintf(tls, bp, bp+16, __ccgo_ts+5255, libc.VaList(bp+32, zSep, zDflt))
|
|
zSep = __ccgo_ts + 16242
|
|
goto _1
|
|
_1:
|
|
;
|
|
ii = ii + 1
|
|
}
|
|
if **(**int32)(__ccgo_up(bp + 16)) == SQLITE_OK {
|
|
**(**int32)(__ccgo_up(bp + 16)) = Xsqlite3_prepare_v2(tls, db, (**(**TSessionBuffer)(__ccgo_up(bp))).FaBuf, -int32(1), ppStmt, uintptr(0))
|
|
}
|
|
Xsqlite3_free(tls, (**(**TSessionBuffer)(__ccgo_up(bp))).FaBuf)
|
|
return **(**int32)(__ccgo_up(bp + 16))
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This function is only called from with a pre-update-hook reporting a
|
|
// ** change on table pTab (attached to session pSession). The type of change
|
|
// ** (UPDATE, INSERT, DELETE) is specified by the first argument.
|
|
// **
|
|
// ** Unless one is already present or an error occurs, an entry is added
|
|
// ** to the changed-rows hash table associated with table pTab.
|
|
// */
|
|
func _sessionPreupdateOneChange(tls *libc.TLS, op int32, iRowid Ti64, pSession uintptr, pTab uintptr) {
|
|
bp := tls.Alloc(80)
|
|
defer tls.Free(80)
|
|
var i, iIdx, iIdx1, nExpect, rc int32
|
|
var p, pC uintptr
|
|
var _ /* bNull at bp+4 */ int32
|
|
var _ /* iHash at bp+0 */ int32
|
|
var _ /* nByte at bp+56 */ Tsqlite3_int64
|
|
var _ /* p at bp+64 */ uintptr
|
|
var _ /* p at bp+72 */ uintptr
|
|
var _ /* stat1 at bp+8 */ TSessionStat1Ctx
|
|
_, _, _, _, _, _, _ = i, iIdx, iIdx1, nExpect, p, pC, rc
|
|
**(**int32)(__ccgo_up(bp + 4)) = 0
|
|
rc = SQLITE_OK
|
|
nExpect = 0
|
|
**(**TSessionStat1Ctx)(__ccgo_up(bp + 8)) = TSessionStat1Ctx{}
|
|
if (*Tsqlite3_session)(unsafe.Pointer(pSession)).Frc != 0 {
|
|
return
|
|
}
|
|
/* Load table details if required */
|
|
if _sessionInitTable(tls, pSession, pTab, (*Tsqlite3_session)(unsafe.Pointer(pSession)).Fdb, (*Tsqlite3_session)(unsafe.Pointer(pSession)).FzDb) != 0 {
|
|
return
|
|
}
|
|
/* Check the number of columns in this xPreUpdate call matches the
|
|
** number of columns in the table. */
|
|
nExpect = (*(*func(*libc.TLS, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*Tsqlite3_session)(unsafe.Pointer(pSession)).Fhook.FxCount})))(tls, (*Tsqlite3_session)(unsafe.Pointer(pSession)).Fhook.FpCtx)
|
|
if (*TSessionTable)(unsafe.Pointer(pTab)).FnTotalCol < nExpect {
|
|
if _sessionReinitTable(tls, pSession, pTab) != 0 {
|
|
return
|
|
}
|
|
if _sessionUpdateChanges(tls, pSession, pTab) != 0 {
|
|
return
|
|
}
|
|
}
|
|
if (*TSessionTable)(unsafe.Pointer(pTab)).FnTotalCol != nExpect {
|
|
(*Tsqlite3_session)(unsafe.Pointer(pSession)).Frc = int32(SQLITE_SCHEMA)
|
|
return
|
|
}
|
|
/* Grow the hash table if required */
|
|
if _sessionGrowHash(tls, pSession, 0, pTab) != 0 {
|
|
(*Tsqlite3_session)(unsafe.Pointer(pSession)).Frc = int32(SQLITE_NOMEM)
|
|
return
|
|
}
|
|
if (*TSessionTable)(unsafe.Pointer(pTab)).FbStat1 != 0 {
|
|
(**(**TSessionStat1Ctx)(__ccgo_up(bp + 8))).Fhook = (*Tsqlite3_session)(unsafe.Pointer(pSession)).Fhook
|
|
(**(**TSessionStat1Ctx)(__ccgo_up(bp + 8))).FpSession = pSession
|
|
(*Tsqlite3_session)(unsafe.Pointer(pSession)).Fhook.FpCtx = bp + 8
|
|
(*Tsqlite3_session)(unsafe.Pointer(pSession)).Fhook.FxNew = __ccgo_fp(_sessionStat1New)
|
|
(*Tsqlite3_session)(unsafe.Pointer(pSession)).Fhook.FxOld = __ccgo_fp(_sessionStat1Old)
|
|
(*Tsqlite3_session)(unsafe.Pointer(pSession)).Fhook.FxCount = __ccgo_fp(_sessionStat1Count)
|
|
(*Tsqlite3_session)(unsafe.Pointer(pSession)).Fhook.FxDepth = __ccgo_fp(_sessionStat1Depth)
|
|
if (*Tsqlite3_session)(unsafe.Pointer(pSession)).FpZeroBlob == uintptr(0) {
|
|
p = _sqlite3ValueNew(tls, uintptr(0))
|
|
if p == uintptr(0) {
|
|
rc = int32(SQLITE_NOMEM)
|
|
goto error_out
|
|
}
|
|
_sqlite3ValueSetStr(tls, p, 0, __ccgo_ts+1704, uint8(0), libc.UintptrFromInt32(0))
|
|
(*Tsqlite3_session)(unsafe.Pointer(pSession)).FpZeroBlob = p
|
|
}
|
|
}
|
|
/* Calculate the hash-key for this change. If the primary key of the row
|
|
** includes a NULL value, exit early. Such changes are ignored by the
|
|
** session module. */
|
|
rc = _sessionPreupdateHash(tls, pSession, iRowid, pTab, libc.BoolInt32(op == int32(SQLITE_INSERT)), bp, bp+4)
|
|
if rc != SQLITE_OK {
|
|
goto error_out
|
|
}
|
|
if **(**int32)(__ccgo_up(bp + 4)) == 0 {
|
|
pC = **(**uintptr)(__ccgo_up((*TSessionTable)(unsafe.Pointer(pTab)).FapChange + uintptr(**(**int32)(__ccgo_up(bp)))*8))
|
|
for {
|
|
if !(pC != 0) {
|
|
break
|
|
}
|
|
if _sessionPreupdateEqual(tls, pSession, iRowid, pTab, pC, op) != 0 {
|
|
break
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
pC = (*TSessionChange)(unsafe.Pointer(pC)).FpNext
|
|
}
|
|
if pC == uintptr(0) { /* Used to iterate through columns */
|
|
(*TSessionTable)(unsafe.Pointer(pTab)).FnEntry = (*TSessionTable)(unsafe.Pointer(pTab)).FnEntry + 1
|
|
/* Figure out how large an allocation is required */
|
|
**(**Tsqlite3_int64)(__ccgo_up(bp + 56)) = int64(32)
|
|
i = (*TSessionTable)(unsafe.Pointer(pTab)).FbRowid
|
|
for {
|
|
if !(i < (*TSessionTable)(unsafe.Pointer(pTab)).FnCol) {
|
|
break
|
|
}
|
|
iIdx = **(**int32)(__ccgo_up((*TSessionTable)(unsafe.Pointer(pTab)).FaiIdx + uintptr(i)*4))
|
|
**(**uintptr)(__ccgo_up(bp + 64)) = uintptr(0)
|
|
if op != int32(SQLITE_INSERT) {
|
|
/* This may fail if the column has a non-NULL default and was added
|
|
** using ALTER TABLE ADD COLUMN after this record was created. */
|
|
rc = (*(*func(*libc.TLS, uintptr, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*Tsqlite3_session)(unsafe.Pointer(pSession)).Fhook.FxOld})))(tls, (*Tsqlite3_session)(unsafe.Pointer(pSession)).Fhook.FpCtx, iIdx, bp+64)
|
|
} else {
|
|
if **(**Tu8)(__ccgo_up((*TSessionTable)(unsafe.Pointer(pTab)).FabPK + uintptr(i))) != 0 {
|
|
(*(*func(*libc.TLS, uintptr, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*Tsqlite3_session)(unsafe.Pointer(pSession)).Fhook.FxNew})))(tls, (*Tsqlite3_session)(unsafe.Pointer(pSession)).Fhook.FpCtx, iIdx, bp+64)
|
|
}
|
|
}
|
|
if rc == SQLITE_OK {
|
|
/* This may fail if SQLite value p contains a utf-16 string that must
|
|
** be converted to utf-8 and an OOM error occurs while doing so. */
|
|
rc = _sessionSerializeValue(tls, uintptr(0), **(**uintptr)(__ccgo_up(bp + 64)), bp+56)
|
|
}
|
|
if rc != SQLITE_OK {
|
|
goto error_out
|
|
}
|
|
goto _2
|
|
_2:
|
|
;
|
|
i = i + 1
|
|
}
|
|
if (*TSessionTable)(unsafe.Pointer(pTab)).FbRowid != 0 {
|
|
**(**Tsqlite3_int64)(__ccgo_up(bp + 56)) = **(**Tsqlite3_int64)(__ccgo_up(bp + 56)) + int64(9) /* Size of rowid field - an integer */
|
|
}
|
|
/* Allocate the change object */
|
|
pC = _sessionMalloc64(tls, pSession, **(**Tsqlite3_int64)(__ccgo_up(bp + 56)))
|
|
if !(pC != 0) {
|
|
rc = int32(SQLITE_NOMEM)
|
|
goto error_out
|
|
} else {
|
|
libc.Xmemset(tls, pC, 0, uint64(32))
|
|
(*TSessionChange)(unsafe.Pointer(pC)).FaRecord = pC + 1*32
|
|
}
|
|
/* Populate the change object. None of the preupdate_old(),
|
|
** preupdate_new() or SerializeValue() calls below may fail as all
|
|
** required values and encodings have already been cached in memory.
|
|
** It is not possible for an OOM to occur in this block. */
|
|
**(**Tsqlite3_int64)(__ccgo_up(bp + 56)) = 0
|
|
if (*TSessionTable)(unsafe.Pointer(pTab)).FbRowid != 0 {
|
|
**(**Tu8)(__ccgo_up((*TSessionChange)(unsafe.Pointer(pC)).FaRecord)) = uint8(SQLITE_INTEGER)
|
|
_sessionPutI64(tls, (*TSessionChange)(unsafe.Pointer(pC)).FaRecord+1, iRowid)
|
|
**(**Tsqlite3_int64)(__ccgo_up(bp + 56)) = int64(9)
|
|
}
|
|
i = (*TSessionTable)(unsafe.Pointer(pTab)).FbRowid
|
|
for {
|
|
if !(i < (*TSessionTable)(unsafe.Pointer(pTab)).FnCol) {
|
|
break
|
|
}
|
|
**(**uintptr)(__ccgo_up(bp + 72)) = uintptr(0)
|
|
iIdx1 = **(**int32)(__ccgo_up((*TSessionTable)(unsafe.Pointer(pTab)).FaiIdx + uintptr(i)*4))
|
|
if op != int32(SQLITE_INSERT) {
|
|
(*(*func(*libc.TLS, uintptr, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*Tsqlite3_session)(unsafe.Pointer(pSession)).Fhook.FxOld})))(tls, (*Tsqlite3_session)(unsafe.Pointer(pSession)).Fhook.FpCtx, iIdx1, bp+72)
|
|
} else {
|
|
if **(**Tu8)(__ccgo_up((*TSessionTable)(unsafe.Pointer(pTab)).FabPK + uintptr(i))) != 0 {
|
|
(*(*func(*libc.TLS, uintptr, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*Tsqlite3_session)(unsafe.Pointer(pSession)).Fhook.FxNew})))(tls, (*Tsqlite3_session)(unsafe.Pointer(pSession)).Fhook.FpCtx, iIdx1, bp+72)
|
|
}
|
|
}
|
|
_sessionSerializeValue(tls, (*TSessionChange)(unsafe.Pointer(pC)).FaRecord+uintptr(**(**Tsqlite3_int64)(__ccgo_up(bp + 56))), **(**uintptr)(__ccgo_up(bp + 72)), bp+56)
|
|
goto _3
|
|
_3:
|
|
;
|
|
i = i + 1
|
|
}
|
|
/* Add the change to the hash-table */
|
|
if (*Tsqlite3_session)(unsafe.Pointer(pSession)).FbIndirect != 0 || (*(*func(*libc.TLS, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*Tsqlite3_session)(unsafe.Pointer(pSession)).Fhook.FxDepth})))(tls, (*Tsqlite3_session)(unsafe.Pointer(pSession)).Fhook.FpCtx) != 0 {
|
|
(*TSessionChange)(unsafe.Pointer(pC)).FbIndirect = uint8(1)
|
|
}
|
|
(*TSessionChange)(unsafe.Pointer(pC)).FnRecordField = libc.Uint16FromInt32((*TSessionTable)(unsafe.Pointer(pTab)).FnCol)
|
|
(*TSessionChange)(unsafe.Pointer(pC)).FnRecord = int32(**(**Tsqlite3_int64)(__ccgo_up(bp + 56)))
|
|
(*TSessionChange)(unsafe.Pointer(pC)).Fop = libc.Uint8FromInt32(op)
|
|
(*TSessionChange)(unsafe.Pointer(pC)).FpNext = **(**uintptr)(__ccgo_up((*TSessionTable)(unsafe.Pointer(pTab)).FapChange + uintptr(**(**int32)(__ccgo_up(bp)))*8))
|
|
**(**uintptr)(__ccgo_up((*TSessionTable)(unsafe.Pointer(pTab)).FapChange + uintptr(**(**int32)(__ccgo_up(bp)))*8)) = pC
|
|
} else {
|
|
if (*TSessionChange)(unsafe.Pointer(pC)).FbIndirect != 0 {
|
|
/* If the existing change is considered "indirect", but this current
|
|
** change is "direct", mark the change object as direct. */
|
|
if (*(*func(*libc.TLS, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*Tsqlite3_session)(unsafe.Pointer(pSession)).Fhook.FxDepth})))(tls, (*Tsqlite3_session)(unsafe.Pointer(pSession)).Fhook.FpCtx) == 0 && (*Tsqlite3_session)(unsafe.Pointer(pSession)).FbIndirect == 0 {
|
|
(*TSessionChange)(unsafe.Pointer(pC)).FbIndirect = uint8(0)
|
|
}
|
|
}
|
|
}
|
|
if (*Tsqlite3_session)(unsafe.Pointer(pSession)).FbEnableSize != 0 {
|
|
rc = _sessionUpdateMaxSize(tls, op, pSession, pTab, pC)
|
|
}
|
|
}
|
|
/* If an error has occurred, mark the session object as failed. */
|
|
goto error_out
|
|
error_out:
|
|
;
|
|
if (*TSessionTable)(unsafe.Pointer(pTab)).FbStat1 != 0 {
|
|
(*Tsqlite3_session)(unsafe.Pointer(pSession)).Fhook = (**(**TSessionStat1Ctx)(__ccgo_up(bp + 8))).Fhook
|
|
}
|
|
if rc != SQLITE_OK {
|
|
(*Tsqlite3_session)(unsafe.Pointer(pSession)).Frc = rc
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Retry the changes accumulated in the pApply->constraints buffer. The
|
|
// ** pApply->constraints buffer contains all changes to table zTab that
|
|
// ** could not be applied due to SQLITE_CONSTRAINT errors. This function
|
|
// ** attempts to apply them as follows:
|
|
// **
|
|
// ** 1) It runs through the buffer and attempts to retry each change,
|
|
// ** removing any that are successfully applied from the buffer. This
|
|
// ** is repeated until no further progress can be made.
|
|
// **
|
|
// ** 2) For each UPDATE change in the buffer, try the following in a
|
|
// ** savepoint transaction:
|
|
// **
|
|
// ** a) DELETE the affected row,
|
|
// ** b) Attempt step (1) with remaining changes,
|
|
// ** c) Attempt to INSERT a row equivalent to the one that would be
|
|
// ** created by applying this UPDATE change.
|
|
// **
|
|
// ** If the INSERT in (c) succeeds, the savepoint is committed and all
|
|
// ** successfully applied changes are removed from the buffer. Step (2)
|
|
// ** is then repeated.
|
|
// **
|
|
// ** 3) Once step (2) has been attempted for each UPDATE in the change,
|
|
// ** a final attempt is made to apply each remaining change. This time,
|
|
// ** if an SQLITE_CONSTRAINT error is encountered, the conflict handler
|
|
// ** is invoked and the user has to decide whether to omit the change
|
|
// ** or rollback the entire _apply() operation.
|
|
// */
|
|
func _sessionRetryConstraints(tls *libc.TLS, db uintptr, bPatchset int32, zTab uintptr, pApply uintptr, __ccgo_fp_xConflict uintptr, pCtx uintptr) (r int32) {
|
|
bp := tls.Alloc(80)
|
|
defer tls.Free(80)
|
|
var iSkip, iThis, iUpdate, rc int32
|
|
var _ /* app at bp+48 */ TSessionBuffer
|
|
var _ /* cons at bp+0 */ TSessionBuffer
|
|
var _ /* cons at bp+16 */ TSessionBuffer
|
|
var _ /* cons at bp+64 */ TSessionBuffer
|
|
var _ /* pInsert at bp+40 */ uintptr
|
|
var _ /* pUp at bp+32 */ uintptr
|
|
_, _, _, _ = iSkip, iThis, iUpdate, rc
|
|
rc = SQLITE_OK
|
|
iUpdate = 0
|
|
/* Step (1) */
|
|
for (*TSessionApplyCtx)(unsafe.Pointer(pApply)).Fconstraints.FnBuf != 0 {
|
|
**(**TSessionBuffer)(__ccgo_up(bp)) = (*TSessionApplyCtx)(unsafe.Pointer(pApply)).Fconstraints
|
|
libc.Xmemset(tls, pApply+88, 0, uint64(16))
|
|
rc = _sessionApplyRetryBuffer(tls, bp, -int32(1), db, bPatchset, zTab, pApply, __ccgo_fp_xConflict, pCtx)
|
|
Xsqlite3_free(tls, (**(**TSessionBuffer)(__ccgo_up(bp))).FaBuf)
|
|
if rc != SQLITE_OK {
|
|
break
|
|
}
|
|
/* If no progress has been made this round, break out of the loop. */
|
|
if (*TSessionApplyCtx)(unsafe.Pointer(pApply)).Fconstraints.FnBuf >= (**(**TSessionBuffer)(__ccgo_up(bp))).FnBuf {
|
|
break
|
|
}
|
|
}
|
|
/* Step (2) */
|
|
for rc == SQLITE_OK && (*TSessionApplyCtx)(unsafe.Pointer(pApply)).Fconstraints.FnBuf != 0 && !((*TSessionApplyCtx)(unsafe.Pointer(pApply)).FbNoUpdateLoop != 0) {
|
|
**(**TSessionBuffer)(__ccgo_up(bp + 16)) = TSessionBuffer{}
|
|
**(**uintptr)(__ccgo_up(bp + 32)) = uintptr(0)
|
|
**(**uintptr)(__ccgo_up(bp + 40)) = uintptr(0)
|
|
iSkip = 0
|
|
rc = _sessionRetryIterInit(tls, pApply+88, bPatchset, zTab, pApply, bp+32)
|
|
if rc == SQLITE_OK {
|
|
iThis = -int32(1)
|
|
for int32(SQLITE_ROW) == Xsqlite3changeset_next(tls, **(**uintptr)(__ccgo_up(bp + 32))) {
|
|
if (*Tsqlite3_changeset_iter)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 32)))).Fop == int32(SQLITE_UPDATE) {
|
|
iThis = iThis + 1
|
|
}
|
|
if iThis == iUpdate {
|
|
break
|
|
}
|
|
iSkip = iSkip + 1
|
|
}
|
|
if iThis == iUpdate {
|
|
rc = Xsqlite3_exec(tls, db, __ccgo_ts+36481, uintptr(0), uintptr(0), uintptr(0))
|
|
if rc == SQLITE_OK {
|
|
rc = _sessionUpdateToDeleteInsert(tls, db, zTab, pApply, **(**uintptr)(__ccgo_up(bp + 32)), bp+40)
|
|
}
|
|
}
|
|
Xsqlite3changeset_finalize(tls, **(**uintptr)(__ccgo_up(bp + 32)))
|
|
if iThis != iUpdate {
|
|
break
|
|
}
|
|
}
|
|
if rc == SQLITE_OK {
|
|
**(**TSessionBuffer)(__ccgo_up(bp + 16)) = (*TSessionApplyCtx)(unsafe.Pointer(pApply)).Fconstraints
|
|
for rc == SQLITE_OK && (*TSessionApplyCtx)(unsafe.Pointer(pApply)).Fconstraints.FnBuf > 0 {
|
|
**(**TSessionBuffer)(__ccgo_up(bp + 48)) = (*TSessionApplyCtx)(unsafe.Pointer(pApply)).Fconstraints
|
|
libc.Xmemset(tls, pApply+88, 0, uint64(16))
|
|
rc = _sessionApplyRetryBuffer(tls, bp+48, iSkip, db, bPatchset, zTab, pApply, __ccgo_fp_xConflict, pCtx)
|
|
if (**(**TSessionBuffer)(__ccgo_up(bp + 48))).FaBuf != (**(**TSessionBuffer)(__ccgo_up(bp + 16))).FaBuf {
|
|
Xsqlite3_free(tls, (**(**TSessionBuffer)(__ccgo_up(bp + 48))).FaBuf)
|
|
}
|
|
if (*TSessionApplyCtx)(unsafe.Pointer(pApply)).Fconstraints.FnBuf >= (**(**TSessionBuffer)(__ccgo_up(bp + 48))).FnBuf {
|
|
break
|
|
}
|
|
iSkip = -int32(1)
|
|
}
|
|
}
|
|
iUpdate = iUpdate + 1
|
|
if rc == SQLITE_OK {
|
|
Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp + 40)))
|
|
rc = Xsqlite3_finalize(tls, **(**uintptr)(__ccgo_up(bp + 40)))
|
|
if rc == int32(SQLITE_CONSTRAINT) {
|
|
rc = Xsqlite3_exec(tls, db, __ccgo_ts+36501, uintptr(0), uintptr(0), uintptr(0))
|
|
Xsqlite3_free(tls, (*TSessionApplyCtx)(unsafe.Pointer(pApply)).Fconstraints.FaBuf)
|
|
(*TSessionApplyCtx)(unsafe.Pointer(pApply)).Fconstraints = **(**TSessionBuffer)(__ccgo_up(bp + 16))
|
|
libc.Xmemset(tls, bp+16, 0, uint64(16))
|
|
} else {
|
|
if rc == SQLITE_OK {
|
|
iUpdate = 0
|
|
}
|
|
}
|
|
if rc == SQLITE_OK {
|
|
rc = Xsqlite3_exec(tls, db, __ccgo_ts+36523, uintptr(0), uintptr(0), uintptr(0))
|
|
}
|
|
} else {
|
|
Xsqlite3_finalize(tls, **(**uintptr)(__ccgo_up(bp + 40)))
|
|
}
|
|
Xsqlite3_free(tls, (**(**TSessionBuffer)(__ccgo_up(bp + 16))).FaBuf)
|
|
}
|
|
/* Step (3) */
|
|
if rc == SQLITE_OK && (*TSessionApplyCtx)(unsafe.Pointer(pApply)).Fconstraints.FnBuf != 0 {
|
|
**(**TSessionBuffer)(__ccgo_up(bp + 64)) = (*TSessionApplyCtx)(unsafe.Pointer(pApply)).Fconstraints
|
|
libc.Xmemset(tls, pApply+88, 0, uint64(16))
|
|
(*TSessionApplyCtx)(unsafe.Pointer(pApply)).FbDeferConstraints = 0
|
|
rc = _sessionApplyRetryBuffer(tls, bp+64, -int32(1), db, bPatchset, zTab, pApply, __ccgo_fp_xConflict, pCtx)
|
|
Xsqlite3_free(tls, (**(**TSessionBuffer)(__ccgo_up(bp + 64))).FaBuf)
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Formulate and prepare an SQL statement to query table zTab by primary
|
|
// ** key. Assuming the following table structure:
|
|
// **
|
|
// ** CREATE TABLE x(a, b, c, d, PRIMARY KEY(a, c));
|
|
// **
|
|
// ** The SELECT statement looks like this:
|
|
// **
|
|
// ** SELECT * FROM x WHERE a = ?1 AND c = ?3
|
|
// **
|
|
// ** If successful, SQLITE_OK is returned and SessionApplyCtx.pSelect is left
|
|
// ** pointing to the prepared version of the SQL statement.
|
|
// */
|
|
func _sessionSelectRow(tls *libc.TLS, db uintptr, zTab uintptr, p uintptr) (r int32) {
|
|
/* TODO */
|
|
return _sessionSelectStmt(tls, db, libc.Int32FromUint8((*TSessionApplyCtx)(unsafe.Pointer(p)).FbIgnoreNoop), __ccgo_ts+6844, zTab, (*TSessionApplyCtx)(unsafe.Pointer(p)).FbRowid, (*TSessionApplyCtx)(unsafe.Pointer(p)).FnCol, (*TSessionApplyCtx)(unsafe.Pointer(p)).FazCol, (*TSessionApplyCtx)(unsafe.Pointer(p)).FabPK, p+24, p+128)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Formulate and prepare a SELECT statement to retrieve a row from table
|
|
// ** zTab in database zDb based on its primary key. i.e.
|
|
// **
|
|
// ** SELECT *, <noop-test> FROM zDb.zTab WHERE (pk1, pk2,...) IS (?1, ?2,...)
|
|
// **
|
|
// ** where <noop-test> is:
|
|
// **
|
|
// ** 1 AND (?A OR ?1 IS <column>) AND ...
|
|
// **
|
|
// ** for each non-pk <column>.
|
|
// */
|
|
func _sessionSelectStmt(tls *libc.TLS, db uintptr, bIgnoreNoop int32, zDb uintptr, zTab uintptr, bRowid int32, nCol int32, azCol uintptr, abPK uintptr, ppStmt uintptr, pzErrmsg uintptr) (r int32) {
|
|
bp := tls.Alloc(128)
|
|
defer tls.Free(128)
|
|
var i int32
|
|
var zSep, zSql, v2 uintptr
|
|
var _ /* cols at bp+8 */ TSessionBuffer
|
|
var _ /* nooptest at bp+24 */ TSessionBuffer
|
|
var _ /* pkfield at bp+40 */ TSessionBuffer
|
|
var _ /* pkvar at bp+56 */ TSessionBuffer
|
|
var _ /* rc at bp+0 */ int32
|
|
_, _, _, _ = i, zSep, zSql, v2
|
|
**(**int32)(__ccgo_up(bp)) = SQLITE_OK
|
|
zSql = uintptr(0)
|
|
zSep = __ccgo_ts + 1704
|
|
**(**TSessionBuffer)(__ccgo_up(bp + 8)) = TSessionBuffer{}
|
|
**(**TSessionBuffer)(__ccgo_up(bp + 24)) = TSessionBuffer{}
|
|
**(**TSessionBuffer)(__ccgo_up(bp + 40)) = TSessionBuffer{}
|
|
**(**TSessionBuffer)(__ccgo_up(bp + 56)) = TSessionBuffer{}
|
|
_sessionAppendStr(tls, bp+24, __ccgo_ts+35710, bp)
|
|
if 0 == Xsqlite3_stricmp(tls, __ccgo_ts+12861, zTab) {
|
|
_sessionAppendStr(tls, bp+24, __ccgo_ts+35714, bp)
|
|
_sessionAppendStr(tls, bp+40, __ccgo_ts+35738, bp)
|
|
_sessionAppendStr(tls, bp+56, __ccgo_ts+35747, bp)
|
|
_sessionAppendStr(tls, bp+8, __ccgo_ts+35792, bp)
|
|
} else {
|
|
i = 0
|
|
for {
|
|
if !(i < nCol) {
|
|
break
|
|
}
|
|
if (**(**TSessionBuffer)(__ccgo_up(bp + 8))).FnBuf != 0 {
|
|
_sessionAppendStr(tls, bp+8, __ccgo_ts+16242, bp)
|
|
}
|
|
_sessionAppendIdent(tls, bp+8, **(**uintptr)(__ccgo_up(azCol + uintptr(i)*8)), bp)
|
|
if **(**Tu8)(__ccgo_up(abPK + uintptr(i))) != 0 {
|
|
_sessionAppendStr(tls, bp+40, zSep, bp)
|
|
_sessionAppendStr(tls, bp+56, zSep, bp)
|
|
zSep = __ccgo_ts + 16242
|
|
_sessionAppendIdent(tls, bp+40, **(**uintptr)(__ccgo_up(azCol + uintptr(i)*8)), bp)
|
|
_sessionAppendPrintf(tls, bp+56, bp, __ccgo_ts+35806, libc.VaList(bp+80, i+int32(1)))
|
|
} else {
|
|
_sessionAppendPrintf(tls, bp+24, bp, __ccgo_ts+35810, libc.VaList(bp+80, i+int32(1)+nCol, i+int32(1), zTab, **(**uintptr)(__ccgo_up(azCol + uintptr(i)*8))))
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
}
|
|
if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
|
|
if bIgnoreNoop != 0 {
|
|
v2 = (**(**TSessionBuffer)(__ccgo_up(bp + 24))).FaBuf
|
|
} else {
|
|
v2 = __ccgo_ts + 1704
|
|
}
|
|
zSql = Xsqlite3_mprintf(tls, __ccgo_ts+35837, libc.VaList(bp+80, (**(**TSessionBuffer)(__ccgo_up(bp + 8))).FaBuf, v2, zDb, zTab, (**(**TSessionBuffer)(__ccgo_up(bp + 40))).FaBuf, (**(**TSessionBuffer)(__ccgo_up(bp + 56))).FaBuf))
|
|
if zSql == uintptr(0) {
|
|
**(**int32)(__ccgo_up(bp)) = int32(SQLITE_NOMEM)
|
|
}
|
|
}
|
|
if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
|
|
**(**int32)(__ccgo_up(bp)) = _sessionPrepare(tls, db, ppStmt, pzErrmsg, zSql)
|
|
}
|
|
Xsqlite3_free(tls, zSql)
|
|
Xsqlite3_free(tls, (**(**TSessionBuffer)(__ccgo_up(bp + 24))).FaBuf)
|
|
Xsqlite3_free(tls, (**(**TSessionBuffer)(__ccgo_up(bp + 40))).FaBuf)
|
|
Xsqlite3_free(tls, (**(**TSessionBuffer)(__ccgo_up(bp + 56))).FaBuf)
|
|
Xsqlite3_free(tls, (**(**TSessionBuffer)(__ccgo_up(bp + 8))).FaBuf)
|
|
return **(**int32)(__ccgo_up(bp))
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Prepare statements for applying changes to the sqlite_stat1 table.
|
|
// ** These are similar to those created by sessionSelectRow(),
|
|
// ** sessionInsertRow(), sessionUpdateRow() and sessionDeleteRow() for
|
|
// ** other tables.
|
|
// */
|
|
func _sessionStat1Sql(tls *libc.TLS, db uintptr, p uintptr) (r int32) {
|
|
var rc int32
|
|
_ = rc
|
|
rc = _sessionSelectRow(tls, db, __ccgo_ts+12861, p)
|
|
if rc == SQLITE_OK {
|
|
rc = _sessionPrepare(tls, db, p+16, uintptr(0), __ccgo_ts+36094)
|
|
}
|
|
if rc == SQLITE_OK {
|
|
rc = _sessionPrepare(tls, db, p+8, uintptr(0), __ccgo_ts+36207)
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This function queries the database for the names of the columns of table
|
|
// ** zThis, in schema zDb.
|
|
// **
|
|
// ** Otherwise, if they are not NULL, variable *pnCol is set to the number
|
|
// ** of columns in the database table and variable *pzTab is set to point to a
|
|
// ** nul-terminated copy of the table name. *pazCol (if not NULL) is set to
|
|
// ** point to an array of pointers to column names. And *pabPK (again, if not
|
|
// ** NULL) is set to point to an array of booleans - true if the corresponding
|
|
// ** column is part of the primary key.
|
|
// **
|
|
// ** For example, if the table is declared as:
|
|
// **
|
|
// ** CREATE TABLE tbl1(w, x DEFAULT 'abc', y, z, PRIMARY KEY(w, z));
|
|
// **
|
|
// ** Then the five output variables are populated as follows:
|
|
// **
|
|
// ** *pnCol = 4
|
|
// ** *pzTab = "tbl1"
|
|
// ** *pazCol = {"w", "x", "y", "z"}
|
|
// ** *pazDflt = {NULL, 'abc', NULL, NULL}
|
|
// ** *pabPK = {1, 0, 0, 1}
|
|
// **
|
|
// ** All returned buffers are part of the same single allocation, which must
|
|
// ** be freed using sqlite3_free() by the caller
|
|
// */
|
|
func _sessionTableInfo(tls *libc.TLS, pSession uintptr, db uintptr, zDb uintptr, zThis uintptr, pnCol uintptr, pnTotalCol uintptr, pzTab uintptr, pazCol uintptr, pazDflt uintptr, paiIdx uintptr, pabPK uintptr, pbRowid uintptr) (r int32) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var abPK, aiIdx, azCol, azDflt, pAlloc, zDflt, zName, zPragma uintptr
|
|
var bRowid, i, nDbCol, nDflt, nName1, nThis, rc int32
|
|
var nByte Tsqlite3_int64
|
|
var nName Tsize_t
|
|
var _ /* pStmt at bp+0 */ uintptr
|
|
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = abPK, aiIdx, azCol, azDflt, bRowid, i, nByte, nDbCol, nDflt, nName, nName1, nThis, pAlloc, rc, zDflt, zName, zPragma
|
|
nDbCol = 0
|
|
pAlloc = uintptr(0)
|
|
azCol = uintptr(0)
|
|
azDflt = uintptr(0)
|
|
abPK = uintptr(0)
|
|
aiIdx = uintptr(0)
|
|
bRowid = 0 /* Set to true to use rowid as PK */
|
|
**(**uintptr)(__ccgo_up(pazCol)) = uintptr(0)
|
|
**(**uintptr)(__ccgo_up(pabPK)) = uintptr(0)
|
|
**(**int32)(__ccgo_up(pnCol)) = 0
|
|
if pnTotalCol != 0 {
|
|
**(**int32)(__ccgo_up(pnTotalCol)) = 0
|
|
}
|
|
if paiIdx != 0 {
|
|
**(**uintptr)(__ccgo_up(paiIdx)) = uintptr(0)
|
|
}
|
|
if pzTab != 0 {
|
|
**(**uintptr)(__ccgo_up(pzTab)) = uintptr(0)
|
|
}
|
|
if pazDflt != 0 {
|
|
**(**uintptr)(__ccgo_up(pazDflt)) = uintptr(0)
|
|
}
|
|
nThis = _sqlite3Strlen30(tls, zThis)
|
|
if nThis == int32(12) && 0 == Xsqlite3_stricmp(tls, __ccgo_ts+12861, zThis) {
|
|
rc = Xsqlite3_table_column_metadata(tls, db, zDb, zThis, uintptr(0), uintptr(0), uintptr(0), uintptr(0), uintptr(0), uintptr(0))
|
|
if rc == SQLITE_OK {
|
|
/* For sqlite_stat1, pretend that (tbl,idx) is the PRIMARY KEY. */
|
|
zPragma = Xsqlite3_mprintf(tls, __ccgo_ts+35218, 0)
|
|
} else {
|
|
if rc == int32(SQLITE_ERROR) {
|
|
zPragma = Xsqlite3_mprintf(tls, __ccgo_ts+1704, 0)
|
|
} else {
|
|
return rc
|
|
}
|
|
}
|
|
} else {
|
|
zPragma = Xsqlite3_mprintf(tls, __ccgo_ts+35348, libc.VaList(bp+16, zDb, zThis))
|
|
}
|
|
if !(zPragma != 0) {
|
|
return int32(SQLITE_NOMEM)
|
|
}
|
|
rc = Xsqlite3_prepare_v2(tls, db, zPragma, -int32(1), bp, uintptr(0))
|
|
Xsqlite3_free(tls, zPragma)
|
|
if rc != SQLITE_OK {
|
|
return rc
|
|
}
|
|
nByte = int64(nThis + int32(1))
|
|
bRowid = libc.BoolInt32(pbRowid != uintptr(0))
|
|
for int32(SQLITE_ROW) == Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp))) {
|
|
nByte = nByte + int64(Xsqlite3_column_bytes(tls, **(**uintptr)(__ccgo_up(bp)), int32(1))) /* name */
|
|
nByte = nByte + int64(Xsqlite3_column_bytes(tls, **(**uintptr)(__ccgo_up(bp)), int32(4))) /* dflt_value */
|
|
if Xsqlite3_column_int(tls, **(**uintptr)(__ccgo_up(bp)), int32(6)) == 0 { /* !hidden */
|
|
nDbCol = nDbCol + 1
|
|
}
|
|
if Xsqlite3_column_int(tls, **(**uintptr)(__ccgo_up(bp)), int32(5)) != 0 {
|
|
bRowid = 0
|
|
} /* pk */
|
|
}
|
|
if nDbCol == 0 {
|
|
bRowid = 0
|
|
}
|
|
nDbCol = nDbCol + bRowid
|
|
nByte = libc.Int64FromUint64(uint64(nByte) + uint64(libc.Xstrlen(tls, __ccgo_ts+31366)))
|
|
rc = Xsqlite3_reset(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
if rc == SQLITE_OK {
|
|
nByte = libc.Int64FromUint64(uint64(nByte) + uint64(libc.Uint64FromInt32(nDbCol)*(libc.Uint64FromInt64(8)*libc.Uint64FromInt32(2)+libc.Uint64FromInt64(4)+libc.Uint64FromInt64(1)+libc.Uint64FromInt32(1)+libc.Uint64FromInt32(1))))
|
|
pAlloc = _sessionMalloc64(tls, pSession, nByte)
|
|
if pAlloc == uintptr(0) {
|
|
rc = int32(SQLITE_NOMEM)
|
|
} else {
|
|
libc.Xmemset(tls, pAlloc, 0, libc.Uint64FromInt64(nByte))
|
|
}
|
|
}
|
|
if rc == SQLITE_OK {
|
|
azCol = pAlloc
|
|
azDflt = azCol + uintptr(nDbCol)*8
|
|
aiIdx = azDflt + uintptr(nDbCol)*8
|
|
abPK = aiIdx + uintptr(nDbCol)*4
|
|
pAlloc = abPK + uintptr(nDbCol)
|
|
if pzTab != 0 {
|
|
libc.Xmemcpy(tls, pAlloc, zThis, libc.Uint64FromInt32(nThis+int32(1)))
|
|
**(**uintptr)(__ccgo_up(pzTab)) = pAlloc
|
|
pAlloc = pAlloc + uintptr(nThis+int32(1))
|
|
}
|
|
i = 0
|
|
if bRowid != 0 {
|
|
nName = libc.Xstrlen(tls, __ccgo_ts+31366)
|
|
libc.Xmemcpy(tls, pAlloc, __ccgo_ts+31366, nName+uint64(1))
|
|
**(**uintptr)(__ccgo_up(azCol + uintptr(i)*8)) = pAlloc
|
|
pAlloc = pAlloc + uintptr(nName+uint64(1))
|
|
**(**Tu8)(__ccgo_up(abPK + uintptr(i))) = uint8(1)
|
|
**(**int32)(__ccgo_up(aiIdx + uintptr(i)*4)) = -int32(1)
|
|
i = i + 1
|
|
}
|
|
for int32(SQLITE_ROW) == Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp))) {
|
|
if Xsqlite3_column_int(tls, **(**uintptr)(__ccgo_up(bp)), int32(6)) == 0 { /* !hidden */
|
|
nName1 = Xsqlite3_column_bytes(tls, **(**uintptr)(__ccgo_up(bp)), int32(1))
|
|
nDflt = Xsqlite3_column_bytes(tls, **(**uintptr)(__ccgo_up(bp)), int32(4))
|
|
zName = Xsqlite3_column_text(tls, **(**uintptr)(__ccgo_up(bp)), int32(1))
|
|
zDflt = Xsqlite3_column_text(tls, **(**uintptr)(__ccgo_up(bp)), int32(4))
|
|
if zName == uintptr(0) {
|
|
break
|
|
}
|
|
libc.Xmemcpy(tls, pAlloc, zName, libc.Uint64FromInt32(nName1+int32(1)))
|
|
**(**uintptr)(__ccgo_up(azCol + uintptr(i)*8)) = pAlloc
|
|
pAlloc = pAlloc + uintptr(nName1+int32(1))
|
|
if zDflt != 0 {
|
|
libc.Xmemcpy(tls, pAlloc, zDflt, libc.Uint64FromInt32(nDflt+int32(1)))
|
|
**(**uintptr)(__ccgo_up(azDflt + uintptr(i)*8)) = pAlloc
|
|
pAlloc = pAlloc + uintptr(nDflt+int32(1))
|
|
} else {
|
|
**(**uintptr)(__ccgo_up(azDflt + uintptr(i)*8)) = uintptr(0)
|
|
}
|
|
**(**Tu8)(__ccgo_up(abPK + uintptr(i))) = libc.Uint8FromInt32(Xsqlite3_column_int(tls, **(**uintptr)(__ccgo_up(bp)), int32(5)))
|
|
**(**int32)(__ccgo_up(aiIdx + uintptr(i)*4)) = Xsqlite3_column_int(tls, **(**uintptr)(__ccgo_up(bp)), 0)
|
|
i = i + 1
|
|
}
|
|
if pnTotalCol != 0 {
|
|
**(**int32)(__ccgo_up(pnTotalCol)) = **(**int32)(__ccgo_up(pnTotalCol)) + 1
|
|
}
|
|
}
|
|
rc = Xsqlite3_reset(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
}
|
|
/* If successful, populate the output variables. Otherwise, zero them and
|
|
** free any allocation made. An error code will be returned in this case.
|
|
*/
|
|
if rc == SQLITE_OK {
|
|
**(**uintptr)(__ccgo_up(pazCol)) = azCol
|
|
if pazDflt != 0 {
|
|
**(**uintptr)(__ccgo_up(pazDflt)) = azDflt
|
|
}
|
|
**(**uintptr)(__ccgo_up(pabPK)) = abPK
|
|
**(**int32)(__ccgo_up(pnCol)) = nDbCol
|
|
if paiIdx != 0 {
|
|
**(**uintptr)(__ccgo_up(paiIdx)) = aiIdx
|
|
}
|
|
} else {
|
|
_sessionFree(tls, pSession, azCol)
|
|
}
|
|
if pbRowid != 0 {
|
|
**(**int32)(__ccgo_up(pbRowid)) = bRowid
|
|
}
|
|
Xsqlite3_finalize(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Find a prepared UPDATE statement suitable for the UPDATE step currently
|
|
// ** being visited by the iterator. The UPDATE is of the form:
|
|
// **
|
|
// ** UPDATE tbl SET col = ?, col2 = ? WHERE pk1 IS ? AND pk2 IS ?
|
|
// */
|
|
func _sessionUpdateFind(tls *libc.TLS, pIter uintptr, p uintptr, bPatchset int32, ppStmt uintptr) (r int32) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var bStat1, ii, nByte, nCol, nU32, nUp int32
|
|
var pUp, pp, zSep, zSql uintptr
|
|
var _ /* buf at bp+8 */ TSessionBuffer
|
|
var _ /* rc at bp+0 */ int32
|
|
_, _, _, _, _, _, _, _, _, _ = bStat1, ii, nByte, nCol, nU32, nUp, pUp, pp, zSep, zSql
|
|
**(**int32)(__ccgo_up(bp)) = SQLITE_OK
|
|
pUp = uintptr(0)
|
|
nCol = (*Tsqlite3_changeset_iter)(unsafe.Pointer(pIter)).FnCol
|
|
nU32 = ((*Tsqlite3_changeset_iter)(unsafe.Pointer(pIter)).FnCol + int32(33)) / int32(32)
|
|
if (*TSessionApplyCtx)(unsafe.Pointer(p)).FaUpdateMask == uintptr(0) {
|
|
(*TSessionApplyCtx)(unsafe.Pointer(p)).FaUpdateMask = Xsqlite3_malloc(tls, libc.Int32FromUint64(libc.Uint64FromInt32(nU32)*uint64(4)))
|
|
if (*TSessionApplyCtx)(unsafe.Pointer(p)).FaUpdateMask == uintptr(0) {
|
|
**(**int32)(__ccgo_up(bp)) = int32(SQLITE_NOMEM)
|
|
}
|
|
}
|
|
if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
|
|
libc.Xmemset(tls, (*TSessionApplyCtx)(unsafe.Pointer(p)).FaUpdateMask, 0, libc.Uint64FromInt32(nU32)*uint64(4))
|
|
**(**int32)(__ccgo_up(bp)) = int32(SQLITE_CORRUPT)
|
|
ii = 0
|
|
for {
|
|
if !(ii < (*Tsqlite3_changeset_iter)(unsafe.Pointer(pIter)).FnCol) {
|
|
break
|
|
}
|
|
if **(**uintptr)(__ccgo_up((*Tsqlite3_changeset_iter)(unsafe.Pointer(pIter)).FapValue + uintptr((*Tsqlite3_changeset_iter)(unsafe.Pointer(pIter)).FnCol+ii)*8)) != 0 {
|
|
**(**Tu32)(__ccgo_up((*TSessionApplyCtx)(unsafe.Pointer(p)).FaUpdateMask + uintptr(ii/int32(32))*4)) |= libc.Uint32FromInt32(libc.Int32FromInt32(1) << (ii % libc.Int32FromInt32(32)))
|
|
**(**int32)(__ccgo_up(bp)) = SQLITE_OK
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
ii = ii + 1
|
|
}
|
|
}
|
|
if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
|
|
if bPatchset != 0 {
|
|
**(**Tu32)(__ccgo_up((*TSessionApplyCtx)(unsafe.Pointer(p)).FaUpdateMask + uintptr(nCol/int32(32))*4)) |= libc.Uint32FromInt32(libc.Int32FromInt32(1) << (nCol % libc.Int32FromInt32(32)))
|
|
}
|
|
if (*TSessionApplyCtx)(unsafe.Pointer(p)).FpUp != 0 {
|
|
nUp = 0
|
|
pp = p + 64
|
|
for int32(1) != 0 {
|
|
nUp = nUp + 1
|
|
if 0 == libc.Xmemcmp(tls, (*TSessionApplyCtx)(unsafe.Pointer(p)).FaUpdateMask, (*TSessionUpdate)(unsafe.Pointer(**(**uintptr)(__ccgo_up(pp)))).FaMask, libc.Uint64FromInt32(nU32)*uint64(4)) {
|
|
pUp = **(**uintptr)(__ccgo_up(pp))
|
|
**(**uintptr)(__ccgo_up(pp)) = (*TSessionUpdate)(unsafe.Pointer(pUp)).FpNext
|
|
(*TSessionUpdate)(unsafe.Pointer(pUp)).FpNext = (*TSessionApplyCtx)(unsafe.Pointer(p)).FpUp
|
|
(*TSessionApplyCtx)(unsafe.Pointer(p)).FpUp = pUp
|
|
break
|
|
}
|
|
if (*TSessionUpdate)(unsafe.Pointer(**(**uintptr)(__ccgo_up(pp)))).FpNext != 0 {
|
|
pp = **(**uintptr)(__ccgo_up(pp)) + 16
|
|
} else {
|
|
if nUp >= int32(SESSION_UPDATE_CACHE_SZ) {
|
|
Xsqlite3_finalize(tls, (*TSessionUpdate)(unsafe.Pointer(**(**uintptr)(__ccgo_up(pp)))).FpStmt)
|
|
Xsqlite3_free(tls, **(**uintptr)(__ccgo_up(pp)))
|
|
**(**uintptr)(__ccgo_up(pp)) = uintptr(0)
|
|
}
|
|
break
|
|
}
|
|
}
|
|
}
|
|
if pUp == uintptr(0) {
|
|
nByte = libc.Int32FromUint64(uint64(24) * libc.Uint64FromInt32(nU32) * uint64(4))
|
|
bStat1 = libc.BoolInt32(Xsqlite3_stricmp(tls, (*Tsqlite3_changeset_iter)(unsafe.Pointer(pIter)).FzTab, __ccgo_ts+12861) == 0)
|
|
pUp = Xsqlite3_malloc(tls, nByte)
|
|
if pUp == uintptr(0) {
|
|
**(**int32)(__ccgo_up(bp)) = int32(SQLITE_NOMEM)
|
|
} else {
|
|
zSep = __ccgo_ts + 1704
|
|
libc.Xmemset(tls, bp+8, 0, uint64(16))
|
|
(*TSessionUpdate)(unsafe.Pointer(pUp)).FaMask = pUp + 1*24
|
|
libc.Xmemcpy(tls, (*TSessionUpdate)(unsafe.Pointer(pUp)).FaMask, (*TSessionApplyCtx)(unsafe.Pointer(p)).FaUpdateMask, libc.Uint64FromInt32(nU32)*uint64(4))
|
|
_sessionAppendStr(tls, bp+8, __ccgo_ts+35917, bp)
|
|
_sessionAppendIdent(tls, bp+8, (*Tsqlite3_changeset_iter)(unsafe.Pointer(pIter)).FzTab, bp)
|
|
_sessionAppendStr(tls, bp+8, __ccgo_ts+35930, bp)
|
|
/* Create the assignments part of the UPDATE */
|
|
ii = 0
|
|
for {
|
|
if !(ii < (*Tsqlite3_changeset_iter)(unsafe.Pointer(pIter)).FnCol) {
|
|
break
|
|
}
|
|
if libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TSessionApplyCtx)(unsafe.Pointer(p)).FabPK + uintptr(ii)))) == 0 && **(**uintptr)(__ccgo_up((*Tsqlite3_changeset_iter)(unsafe.Pointer(pIter)).FapValue + uintptr((*Tsqlite3_changeset_iter)(unsafe.Pointer(pIter)).FnCol+ii)*8)) != 0 {
|
|
_sessionAppendStr(tls, bp+8, zSep, bp)
|
|
_sessionAppendIdent(tls, bp+8, **(**uintptr)(__ccgo_up((*TSessionApplyCtx)(unsafe.Pointer(p)).FazCol + uintptr(ii)*8)), bp)
|
|
_sessionAppendStr(tls, bp+8, __ccgo_ts+35936, bp)
|
|
_sessionAppendInteger(tls, bp+8, ii*int32(2)+int32(1), bp)
|
|
zSep = __ccgo_ts + 16242
|
|
}
|
|
goto _2
|
|
_2:
|
|
;
|
|
ii = ii + 1
|
|
}
|
|
/* Create the WHERE clause part of the UPDATE */
|
|
zSep = __ccgo_ts + 1704
|
|
_sessionAppendStr(tls, bp+8, __ccgo_ts+35941, bp)
|
|
ii = 0
|
|
for {
|
|
if !(ii < (*Tsqlite3_changeset_iter)(unsafe.Pointer(pIter)).FnCol) {
|
|
break
|
|
}
|
|
if **(**Tu8)(__ccgo_up((*TSessionApplyCtx)(unsafe.Pointer(p)).FabPK + uintptr(ii))) != 0 || bPatchset == 0 && **(**uintptr)(__ccgo_up((*Tsqlite3_changeset_iter)(unsafe.Pointer(pIter)).FapValue + uintptr(ii)*8)) != 0 {
|
|
_sessionAppendStr(tls, bp+8, zSep, bp)
|
|
if bStat1 != 0 && ii == int32(1) {
|
|
_sessionAppendStr(tls, bp+8, __ccgo_ts+35949, bp)
|
|
} else {
|
|
_sessionAppendIdent(tls, bp+8, **(**uintptr)(__ccgo_up((*TSessionApplyCtx)(unsafe.Pointer(p)).FazCol + uintptr(ii)*8)), bp)
|
|
_sessionAppendStr(tls, bp+8, __ccgo_ts+36024, bp)
|
|
_sessionAppendInteger(tls, bp+8, ii*int32(2)+int32(2), bp)
|
|
}
|
|
zSep = __ccgo_ts + 23653
|
|
}
|
|
goto _3
|
|
_3:
|
|
;
|
|
ii = ii + 1
|
|
}
|
|
if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
|
|
zSql = (**(**TSessionBuffer)(__ccgo_up(bp + 8))).FaBuf
|
|
**(**int32)(__ccgo_up(bp)) = Xsqlite3_prepare_v2(tls, (*TSessionApplyCtx)(unsafe.Pointer(p)).Fdb, zSql, (**(**TSessionBuffer)(__ccgo_up(bp + 8))).FnBuf, pUp, uintptr(0))
|
|
}
|
|
if **(**int32)(__ccgo_up(bp)) != SQLITE_OK {
|
|
Xsqlite3_free(tls, pUp)
|
|
pUp = uintptr(0)
|
|
} else {
|
|
(*TSessionUpdate)(unsafe.Pointer(pUp)).FpNext = (*TSessionApplyCtx)(unsafe.Pointer(p)).FpUp
|
|
(*TSessionApplyCtx)(unsafe.Pointer(p)).FpUp = pUp
|
|
}
|
|
Xsqlite3_free(tls, (**(**TSessionBuffer)(__ccgo_up(bp + 8))).FaBuf)
|
|
}
|
|
}
|
|
}
|
|
if pUp != 0 {
|
|
**(**uintptr)(__ccgo_up(ppStmt)) = (*TSessionUpdate)(unsafe.Pointer(pUp)).FpStmt
|
|
} else {
|
|
**(**uintptr)(__ccgo_up(ppStmt)) = uintptr(0)
|
|
}
|
|
return **(**int32)(__ccgo_up(bp))
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Iterator pUp points to an UPDATE change. This function deletes the
|
|
// ** affected row from the database and creates an INSERT statement that
|
|
// ** may be used to reinsert the row as it is after the UPDATE change
|
|
// ** has been applied.
|
|
// **
|
|
// ** If successful, SQLITE_OK is returned and output variable (*ppInsert)
|
|
// ** is left pointing to a prepared INSERT statement. It is the responsibility
|
|
// ** of the caller to eventually free this statement using sqlite3_finalize().
|
|
// ** Or, if an error occurs, an SQLite error code is returned and (*ppInsert)
|
|
// ** set to NULL. pApply->zErr may be set to an error message in this case.
|
|
// */
|
|
func _sessionUpdateToDeleteInsert(tls *libc.TLS, db uintptr, zTab uintptr, pApply uintptr, pUp uintptr, ppInsert uintptr) (r int32) {
|
|
bp := tls.Alloc(128)
|
|
defer tls.Free(128)
|
|
var iCol, ii int32
|
|
var pVal, zComma, zComma2, zInsert, zSelect uintptr
|
|
var _ /* bWR at bp+20 */ int32
|
|
var _ /* cols at bp+24 */ TSessionBuffer
|
|
var _ /* insbind at bp+40 */ TSessionBuffer
|
|
var _ /* pRet at bp+0 */ uintptr
|
|
var _ /* pSelect at bp+8 */ uintptr
|
|
var _ /* pkcols at bp+56 */ TSessionBuffer
|
|
var _ /* rc at bp+16 */ int32
|
|
var _ /* selbind at bp+72 */ TSessionBuffer
|
|
_, _, _, _, _, _, _ = iCol, ii, pVal, zComma, zComma2, zInsert, zSelect
|
|
**(**uintptr)(__ccgo_up(bp)) = uintptr(0) /* The INSERT statement */
|
|
**(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0) /* SELECT to read current values of row */
|
|
**(**int32)(__ccgo_up(bp + 16)) = SQLITE_OK
|
|
**(**int32)(__ccgo_up(bp + 20)) = 0
|
|
**(**int32)(__ccgo_up(bp + 16)) = _sessionTableIsWithoutRowid(tls, db, zTab, bp+20)
|
|
if **(**int32)(__ccgo_up(bp + 16)) == SQLITE_OK {
|
|
zSelect = uintptr(0)
|
|
zInsert = uintptr(0)
|
|
**(**TSessionBuffer)(__ccgo_up(bp + 24)) = TSessionBuffer{}
|
|
**(**TSessionBuffer)(__ccgo_up(bp + 40)) = TSessionBuffer{}
|
|
**(**TSessionBuffer)(__ccgo_up(bp + 56)) = TSessionBuffer{}
|
|
**(**TSessionBuffer)(__ccgo_up(bp + 72)) = TSessionBuffer{}
|
|
zComma = __ccgo_ts + 1704
|
|
zComma2 = __ccgo_ts + 1704
|
|
ii = 0
|
|
for {
|
|
if !(ii < (*TSessionApplyCtx)(unsafe.Pointer(pApply)).FnCol) {
|
|
break
|
|
}
|
|
_sessionAppendStr(tls, bp+24, zComma, bp+16)
|
|
_sessionAppendIdent(tls, bp+24, **(**uintptr)(__ccgo_up((*TSessionApplyCtx)(unsafe.Pointer(pApply)).FazCol + uintptr(ii)*8)), bp+16)
|
|
_sessionAppendStr(tls, bp+40, zComma, bp+16)
|
|
_sessionAppendStr(tls, bp+40, __ccgo_ts+5287, bp+16)
|
|
zComma = __ccgo_ts + 16242
|
|
if **(**Tu8)(__ccgo_up((*TSessionApplyCtx)(unsafe.Pointer(pApply)).FabPK + uintptr(ii))) != 0 {
|
|
_sessionAppendStr(tls, bp+56, zComma2, bp+16)
|
|
_sessionAppendIdent(tls, bp+56, **(**uintptr)(__ccgo_up((*TSessionApplyCtx)(unsafe.Pointer(pApply)).FazCol + uintptr(ii)*8)), bp+16)
|
|
_sessionAppendStr(tls, bp+72, zComma2, bp+16)
|
|
_sessionAppendPrintf(tls, bp+72, bp+16, __ccgo_ts+35806, libc.VaList(bp+96, ii+int32(1)))
|
|
zComma2 = __ccgo_ts + 16242
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
ii = ii + 1
|
|
}
|
|
if **(**int32)(__ccgo_up(bp + 20)) == 0 {
|
|
_sessionAppendStr(tls, bp+24, zComma, bp+16)
|
|
_sessionAppendStr(tls, bp+24, __ccgo_ts+31366, bp+16)
|
|
_sessionAppendStr(tls, bp+40, zComma, bp+16)
|
|
_sessionAppendStr(tls, bp+40, __ccgo_ts+5287, bp+16)
|
|
}
|
|
if **(**int32)(__ccgo_up(bp + 16)) == SQLITE_OK {
|
|
zSelect = Xsqlite3_mprintf(tls, __ccgo_ts+36414, libc.VaList(bp+96, (**(**TSessionBuffer)(__ccgo_up(bp + 24))).FaBuf, zTab, (**(**TSessionBuffer)(__ccgo_up(bp + 56))).FaBuf, (**(**TSessionBuffer)(__ccgo_up(bp + 72))).FaBuf))
|
|
if zSelect == uintptr(0) {
|
|
**(**int32)(__ccgo_up(bp + 16)) = int32(SQLITE_NOMEM)
|
|
}
|
|
}
|
|
if **(**int32)(__ccgo_up(bp + 16)) == SQLITE_OK {
|
|
zInsert = Xsqlite3_mprintf(tls, __ccgo_ts+36451, libc.VaList(bp+96, zTab, (**(**TSessionBuffer)(__ccgo_up(bp + 24))).FaBuf, (**(**TSessionBuffer)(__ccgo_up(bp + 40))).FaBuf))
|
|
if zInsert == uintptr(0) {
|
|
**(**int32)(__ccgo_up(bp + 16)) = int32(SQLITE_NOMEM)
|
|
}
|
|
}
|
|
if **(**int32)(__ccgo_up(bp + 16)) == SQLITE_OK {
|
|
**(**int32)(__ccgo_up(bp + 16)) = _sessionPrepare(tls, db, bp+8, pApply+128, zSelect)
|
|
}
|
|
if **(**int32)(__ccgo_up(bp + 16)) == SQLITE_OK {
|
|
**(**int32)(__ccgo_up(bp + 16)) = _sessionPrepare(tls, db, bp, pApply+128, zInsert)
|
|
}
|
|
Xsqlite3_free(tls, zSelect)
|
|
Xsqlite3_free(tls, zInsert)
|
|
Xsqlite3_free(tls, (**(**TSessionBuffer)(__ccgo_up(bp + 24))).FaBuf)
|
|
Xsqlite3_free(tls, (**(**TSessionBuffer)(__ccgo_up(bp + 40))).FaBuf)
|
|
Xsqlite3_free(tls, (**(**TSessionBuffer)(__ccgo_up(bp + 56))).FaBuf)
|
|
Xsqlite3_free(tls, (**(**TSessionBuffer)(__ccgo_up(bp + 72))).FaBuf)
|
|
}
|
|
if **(**int32)(__ccgo_up(bp + 16)) == SQLITE_OK {
|
|
**(**int32)(__ccgo_up(bp + 16)) = _sessionBindRow(tls, pUp, __ccgo_fp(Xsqlite3changeset_old), (*TSessionApplyCtx)(unsafe.Pointer(pApply)).FnCol, (*TSessionApplyCtx)(unsafe.Pointer(pApply)).FabPK, **(**uintptr)(__ccgo_up(bp + 8)))
|
|
}
|
|
if **(**int32)(__ccgo_up(bp + 16)) == SQLITE_OK && Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp + 8))) == int32(SQLITE_ROW) {
|
|
iCol = 0
|
|
for {
|
|
if !(iCol < (*TSessionApplyCtx)(unsafe.Pointer(pApply)).FnCol) {
|
|
break
|
|
}
|
|
pVal = **(**uintptr)(__ccgo_up((*Tsqlite3_changeset_iter)(unsafe.Pointer(pUp)).FapValue + uintptr(iCol+(*TSessionApplyCtx)(unsafe.Pointer(pApply)).FnCol)*8))
|
|
if pVal == uintptr(0) {
|
|
pVal = Xsqlite3_column_value(tls, **(**uintptr)(__ccgo_up(bp + 8)), iCol)
|
|
}
|
|
**(**int32)(__ccgo_up(bp + 16)) = Xsqlite3_bind_value(tls, **(**uintptr)(__ccgo_up(bp)), iCol+int32(1), pVal)
|
|
goto _2
|
|
_2:
|
|
;
|
|
iCol = iCol + 1
|
|
}
|
|
if **(**int32)(__ccgo_up(bp + 20)) == 0 {
|
|
Xsqlite3_bind_int64(tls, **(**uintptr)(__ccgo_up(bp)), iCol+int32(1), Xsqlite3_column_int64(tls, **(**uintptr)(__ccgo_up(bp + 8)), iCol))
|
|
}
|
|
}
|
|
_sessionFinalizeStmt(tls, **(**uintptr)(__ccgo_up(bp + 8)), bp+16)
|
|
/* Delete the row from the database. */
|
|
if **(**int32)(__ccgo_up(bp + 16)) == SQLITE_OK {
|
|
**(**int32)(__ccgo_up(bp + 16)) = _sessionBindRow(tls, pUp, __ccgo_fp(Xsqlite3changeset_old), (*TSessionApplyCtx)(unsafe.Pointer(pApply)).FnCol, (*TSessionApplyCtx)(unsafe.Pointer(pApply)).FabPK, (*TSessionApplyCtx)(unsafe.Pointer(pApply)).FpDelete)
|
|
Xsqlite3_bind_int(tls, (*TSessionApplyCtx)(unsafe.Pointer(pApply)).FpDelete, (*TSessionApplyCtx)(unsafe.Pointer(pApply)).FnCol+int32(1), int32(1))
|
|
}
|
|
if **(**int32)(__ccgo_up(bp + 16)) == SQLITE_OK {
|
|
Xsqlite3_step(tls, (*TSessionApplyCtx)(unsafe.Pointer(pApply)).FpDelete)
|
|
**(**int32)(__ccgo_up(bp + 16)) = Xsqlite3_reset(tls, (*TSessionApplyCtx)(unsafe.Pointer(pApply)).FpDelete)
|
|
}
|
|
if **(**int32)(__ccgo_up(bp + 16)) != SQLITE_OK {
|
|
Xsqlite3_finalize(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
|
|
}
|
|
**(**uintptr)(__ccgo_up(ppInsert)) = **(**uintptr)(__ccgo_up(bp))
|
|
return **(**int32)(__ccgo_up(bp + 16))
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** The expression is the default value for the most recently added column
|
|
// ** of the table currently under construction.
|
|
// **
|
|
// ** Default value expressions must be constant. Raise an exception if this
|
|
// ** is not the case.
|
|
// **
|
|
// ** This routine is called by the parser while in the middle of
|
|
// ** parsing a CREATE TABLE statement.
|
|
// */
|
|
func _sqlite3AddDefaultValue(tls *libc.TLS, pParse uintptr, pExpr uintptr, zStart uintptr, zEnd uintptr) {
|
|
bp := tls.Alloc(96)
|
|
defer tls.Free(96)
|
|
var db, p, pCol, pDfltExpr uintptr
|
|
var isInit int32
|
|
var _ /* x at bp+0 */ TExpr
|
|
_, _, _, _, _ = db, isInit, p, pCol, pDfltExpr
|
|
db = (*TParse)(unsafe.Pointer(pParse)).Fdb
|
|
p = (*TParse)(unsafe.Pointer(pParse)).FpNewTable
|
|
if p != uintptr(0) {
|
|
isInit = libc.BoolInt32((*Tsqlite3)(unsafe.Pointer(db)).Finit1.Fbusy != 0 && libc.Int32FromUint8((*Tsqlite3)(unsafe.Pointer(db)).Finit1.FiDb) != int32(1))
|
|
pCol = (*TTable)(unsafe.Pointer(p)).FaCol + uintptr(int32((*TTable)(unsafe.Pointer(p)).FnCol)-int32(1))*16
|
|
if !(_sqlite3ExprIsConstantOrFunction(tls, pExpr, libc.Uint8FromInt32(isInit)) != 0) {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+14050, libc.VaList(bp+80, (*TColumn)(unsafe.Pointer(pCol)).FzCnName))
|
|
} else {
|
|
if libc.Int32FromUint16((*TColumn)(unsafe.Pointer(pCol)).FcolFlags)&int32(COLFLAG_GENERATED) != 0 {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+14095, 0)
|
|
} else {
|
|
libc.Xmemset(tls, bp, 0, uint64(72))
|
|
(**(**TExpr)(__ccgo_up(bp))).Fop = uint8(TK_SPAN)
|
|
*(*uintptr)(unsafe.Pointer(bp + 8)) = _sqlite3DbSpanDup(tls, db, zStart, zEnd)
|
|
(**(**TExpr)(__ccgo_up(bp))).FpLeft = pExpr
|
|
(**(**TExpr)(__ccgo_up(bp))).Fflags = uint32(EP_Skip)
|
|
pDfltExpr = _sqlite3ExprDup(tls, db, bp, int32(EXPRDUP_REDUCE))
|
|
_sqlite3DbFree(tls, db, *(*uintptr)(unsafe.Pointer(bp + 8)))
|
|
_sqlite3ColumnSetExpr(tls, pParse, p, pCol, pDfltExpr)
|
|
}
|
|
}
|
|
}
|
|
if libc.Int32FromUint8((*TParse)(unsafe.Pointer(pParse)).FeParseMode) >= int32(PARSE_MODE_RENAME) {
|
|
_sqlite3RenameExprUnmap(tls, pParse, pExpr)
|
|
}
|
|
_sqlite3ExprDelete(tls, db, pExpr)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /* Change the most recently parsed column to be a GENERATED ALWAYS AS
|
|
// ** column.
|
|
// */
|
|
func _sqlite3AddGenerated(tls *libc.TLS, pParse uintptr, pExpr uintptr, pType uintptr) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var eType Tu8
|
|
var pCol, pTab, v1 uintptr
|
|
_, _, _, _ = eType, pCol, pTab, v1
|
|
eType = uint8(COLFLAG_VIRTUAL)
|
|
pTab = (*TParse)(unsafe.Pointer(pParse)).FpNewTable
|
|
if pTab == uintptr(0) {
|
|
/* generated column in an CREATE TABLE IF NOT EXISTS that already exists */
|
|
goto generated_done
|
|
}
|
|
pCol = (*TTable)(unsafe.Pointer(pTab)).FaCol + uintptr(int32((*TTable)(unsafe.Pointer(pTab)).FnCol)-int32(1))*16
|
|
if libc.Int32FromUint8((*TParse)(unsafe.Pointer(pParse)).FeParseMode) == int32(PARSE_MODE_DECLARE_VTAB) {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+14285, 0)
|
|
goto generated_done
|
|
}
|
|
if libc.Int32FromUint16((*TColumn)(unsafe.Pointer(pCol)).FiDflt) > 0 {
|
|
goto generated_error
|
|
}
|
|
if pType != 0 {
|
|
if (*TToken)(unsafe.Pointer(pType)).Fn == uint32(7) && Xsqlite3_strnicmp(tls, __ccgo_ts+14328, (*TToken)(unsafe.Pointer(pType)).Fz, int32(7)) == 0 {
|
|
/* no-op */
|
|
} else {
|
|
if (*TToken)(unsafe.Pointer(pType)).Fn == uint32(6) && Xsqlite3_strnicmp(tls, __ccgo_ts+14336, (*TToken)(unsafe.Pointer(pType)).Fz, int32(6)) == 0 {
|
|
eType = uint8(COLFLAG_STORED)
|
|
} else {
|
|
goto generated_error
|
|
}
|
|
}
|
|
}
|
|
if libc.Int32FromUint8(eType) == int32(COLFLAG_VIRTUAL) {
|
|
(*TTable)(unsafe.Pointer(pTab)).FnNVCol = (*TTable)(unsafe.Pointer(pTab)).FnNVCol - 1
|
|
}
|
|
v1 = pCol + 14
|
|
*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) | libc.Int32FromUint8(eType))
|
|
**(**Tu32)(__ccgo_up(pTab + 48)) |= uint32(eType)
|
|
if libc.Int32FromUint16((*TColumn)(unsafe.Pointer(pCol)).FcolFlags)&int32(COLFLAG_PRIMKEY) != 0 {
|
|
_makeColumnPartOfPrimaryKey(tls, pParse, pCol) /* For the error message */
|
|
}
|
|
if pExpr != 0 && libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) == int32(TK_ID) {
|
|
/* The value of a generated column needs to be a real expression, not
|
|
** just a reference to another column, in order for covering index
|
|
** optimizations to work correctly. So if the value is not an expression,
|
|
** turn it into one by adding a unary "+" operator. */
|
|
pExpr = _sqlite3PExpr(tls, pParse, int32(TK_UPLUS), pExpr, uintptr(0))
|
|
}
|
|
if pExpr != 0 && libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) != int32(TK_RAISE) {
|
|
(*TExpr)(unsafe.Pointer(pExpr)).FaffExpr = (*TColumn)(unsafe.Pointer(pCol)).Faffinity
|
|
}
|
|
_sqlite3ColumnSetExpr(tls, pParse, pTab, pCol, pExpr)
|
|
pExpr = uintptr(0)
|
|
goto generated_done
|
|
goto generated_error
|
|
generated_error:
|
|
;
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+14343, libc.VaList(bp+8, (*TColumn)(unsafe.Pointer(pCol)).FzCnName))
|
|
goto generated_done
|
|
generated_done:
|
|
;
|
|
_sqlite3ExprDelete(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, pExpr)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Generate bytecode to implement:
|
|
// **
|
|
// ** ALTER TABLE pSrc ADD [CONSTRAINT pName] CHECK(pExpr)
|
|
// **
|
|
// ** Any "ON CONFLICT" text that occurs after the "CHECK(...)", up
|
|
// ** until pParse->sLastToken, is included as part of the new constraint.
|
|
// */
|
|
func _sqlite3AlterAddConstraint(tls *libc.TLS, pParse uintptr, pSrc uintptr, pFirst uintptr, pName uintptr, zExpr uintptr, nExpr int32, pExpr uintptr) {
|
|
bp := tls.Alloc(64)
|
|
defer tls.Free(64)
|
|
var nCons, rc int32
|
|
var pCons, pTab, zName uintptr
|
|
var _ /* iDb at bp+0 */ int32
|
|
var _ /* zDb at bp+8 */ uintptr
|
|
_, _, _, _, _ = nCons, pCons, pTab, rc, zName
|
|
pTab = uintptr(0) /* Table identified by pSrc */
|
|
**(**int32)(__ccgo_up(bp)) = 0 /* Which schema does pTab live in */
|
|
**(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0) /* Name of the schema in which pTab lives */
|
|
pCons = uintptr(0) /* Result from error checking pExpr */
|
|
/* Look up the table being altered. */
|
|
pTab = _alterFindTable(tls, pParse, pSrc, bp, bp+8, int32(1))
|
|
if !(pTab != 0) {
|
|
_sqlite3ExprDelete(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, pExpr)
|
|
return
|
|
}
|
|
/* Verify that the new CHECK constraint does not contain any
|
|
** internal-use-only function. Forum post 2026-05-10T01:11:28Z
|
|
*/
|
|
rc = _sqlite3ResolveSelfReference(tls, pParse, pTab, int32(NC_IsCheck), pExpr, uintptr(0))
|
|
_sqlite3ExprDelete(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, pExpr)
|
|
if rc != 0 {
|
|
return
|
|
}
|
|
/* If this new constraint has a name, check that it is not a duplicate of
|
|
** an existing constraint. It is an error if it is. */
|
|
if pName != 0 {
|
|
zName = _sqlite3NameFromToken(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, pName)
|
|
_sqlite3NestedParse(tls, pParse, __ccgo_ts+12311, libc.VaList(bp+24, zName, int32(SQLITE_ERROR), **(**uintptr)(__ccgo_up(bp + 8)), (*TTable)(unsafe.Pointer(pTab)).FzName, zName))
|
|
_sqlite3DbFree(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, zName)
|
|
}
|
|
/* Search for a constraint violation. Throw an exception if one is found. */
|
|
_sqlite3NestedParse(tls, pParse, __ccgo_ts+12476, libc.VaList(bp+24, int32(SQLITE_CONSTRAINT), **(**uintptr)(__ccgo_up(bp + 8)), (*TTable)(unsafe.Pointer(pTab)).FzName, nExpr, zExpr))
|
|
/* Edit the SQL for the named table. */
|
|
pCons = (*TToken)(unsafe.Pointer(pFirst)).Fz
|
|
nCons = _alterRtrimConstraint(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, pCons, int32(int64((*TParse)(unsafe.Pointer(pParse)).FsLastToken.Fz)-int64(pCons)))
|
|
_sqlite3NestedParse(tls, pParse, __ccgo_ts+12556, libc.VaList(bp+24, **(**uintptr)(__ccgo_up(bp + 8)), nCons, pCons, (*TTable)(unsafe.Pointer(pTab)).FzName))
|
|
/* Finally, reload the database schema. */
|
|
_renameReloadSchema(tls, pParse, **(**int32)(__ccgo_up(bp)), uint16(INITFLAG_AlterDropCons))
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This function is called by the parser after the table-name in
|
|
// ** an "ALTER TABLE <table-name> ADD" statement is parsed. Argument
|
|
// ** pSrc is the full-name of the table being altered.
|
|
// **
|
|
// ** This routine makes a (partial) copy of the Table structure
|
|
// ** for the table being altered and sets Parse.pNewTable to point
|
|
// ** to it. Routines called by the parser as the column definition
|
|
// ** is parsed (i.e. sqlite3AddColumn()) add the new Column data to
|
|
// ** the copy. The copy of the Table structure is deleted by tokenize.c
|
|
// ** after parsing is finished.
|
|
// **
|
|
// ** Routine sqlite3AlterFinishAddColumn() will be called to complete
|
|
// ** coding the "ALTER TABLE ... ADD" statement.
|
|
// */
|
|
func _sqlite3AlterBeginAddColumn(tls *libc.TLS, pParse uintptr, pSrc uintptr) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var db, pCol, pNew, pTab uintptr
|
|
var i, iDb, nAlloc int32
|
|
_, _, _, _, _, _, _ = db, i, iDb, nAlloc, pCol, pNew, pTab
|
|
db = (*TParse)(unsafe.Pointer(pParse)).Fdb
|
|
/* Look up the table being altered. */
|
|
if (*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0 {
|
|
goto exit_begin_add_column
|
|
}
|
|
pTab = _sqlite3LocateTableItem(tls, pParse, uint32(0), pSrc+8)
|
|
if !(pTab != 0) {
|
|
goto exit_begin_add_column
|
|
}
|
|
if libc.Int32FromUint8((*TTable)(unsafe.Pointer(pTab)).FeTabType) == int32(TABTYP_VTAB) {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+11060, 0)
|
|
goto exit_begin_add_column
|
|
}
|
|
/* Make sure this is not an attempt to ALTER a view. */
|
|
if libc.Int32FromUint8((*TTable)(unsafe.Pointer(pTab)).FeTabType) == int32(TABTYP_VIEW) {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+11094, 0)
|
|
goto exit_begin_add_column
|
|
}
|
|
if SQLITE_OK != _isAlterableTable(tls, pParse, pTab) {
|
|
goto exit_begin_add_column
|
|
}
|
|
_sqlite3MayAbort(tls, pParse)
|
|
iDb = _sqlite3SchemaToIndex(tls, db, (*TTable)(unsafe.Pointer(pTab)).FpSchema)
|
|
/* Put a copy of the Table struct in Parse.pNewTable for the
|
|
** sqlite3AddColumn() function and friends to modify. But modify
|
|
** the name by adding an "sqlite_altertab_" prefix. By adding this
|
|
** prefix, we insure that the name will not collide with an existing
|
|
** table because user table are not allowed to have the "sqlite_"
|
|
** prefix on their name.
|
|
*/
|
|
pNew = _sqlite3DbMallocZero(tls, db, uint64(120))
|
|
if !(pNew != 0) {
|
|
goto exit_begin_add_column
|
|
}
|
|
(*TParse)(unsafe.Pointer(pParse)).FpNewTable = pNew
|
|
(*TTable)(unsafe.Pointer(pNew)).FnTabRef = uint32(1)
|
|
(*TTable)(unsafe.Pointer(pNew)).FnCol = (*TTable)(unsafe.Pointer(pTab)).FnCol
|
|
nAlloc = (int32((*TTable)(unsafe.Pointer(pNew)).FnCol)-int32(1))/int32(8)*int32(8) + int32(8)
|
|
(*TTable)(unsafe.Pointer(pNew)).FaCol = _sqlite3DbMallocZero(tls, db, uint64(16)*uint64(libc.Uint32FromInt32(nAlloc)))
|
|
(*TTable)(unsafe.Pointer(pNew)).FzName = _sqlite3MPrintf(tls, db, __ccgo_ts+11124, libc.VaList(bp+8, (*TTable)(unsafe.Pointer(pTab)).FzName))
|
|
if !((*TTable)(unsafe.Pointer(pNew)).FaCol != 0) || !((*TTable)(unsafe.Pointer(pNew)).FzName != 0) {
|
|
goto exit_begin_add_column
|
|
}
|
|
libc.Xmemcpy(tls, (*TTable)(unsafe.Pointer(pNew)).FaCol, (*TTable)(unsafe.Pointer(pTab)).FaCol, uint64(16)*libc.Uint64FromInt16((*TTable)(unsafe.Pointer(pNew)).FnCol))
|
|
i = 0
|
|
for {
|
|
if !(i < int32((*TTable)(unsafe.Pointer(pNew)).FnCol)) {
|
|
break
|
|
}
|
|
pCol = (*TTable)(unsafe.Pointer(pNew)).FaCol + uintptr(i)*16
|
|
(*TColumn)(unsafe.Pointer(pCol)).FzCnName = _sqlite3DbStrDup(tls, db, (*TColumn)(unsafe.Pointer(pCol)).FzCnName)
|
|
(*TColumn)(unsafe.Pointer(pCol)).FhName = _sqlite3StrIHash(tls, (*TColumn)(unsafe.Pointer(pCol)).FzCnName)
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
(*(*struct {
|
|
FaddColOffset int32
|
|
FpFKey uintptr
|
|
FpDfltList uintptr
|
|
})(unsafe.Pointer(pNew + 64))).FpDfltList = _sqlite3ExprListDup(tls, db, (*(*struct {
|
|
FaddColOffset int32
|
|
FpFKey uintptr
|
|
FpDfltList uintptr
|
|
})(unsafe.Pointer(pTab + 64))).FpDfltList, 0)
|
|
(*TTable)(unsafe.Pointer(pNew)).FpSchema = (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(iDb)*32))).FpSchema
|
|
(*(*struct {
|
|
FaddColOffset int32
|
|
FpFKey uintptr
|
|
FpDfltList uintptr
|
|
})(unsafe.Pointer(pNew + 64))).FaddColOffset = (*(*struct {
|
|
FaddColOffset int32
|
|
FpFKey uintptr
|
|
FpDfltList uintptr
|
|
})(unsafe.Pointer(pTab + 64))).FaddColOffset
|
|
goto exit_begin_add_column
|
|
exit_begin_add_column:
|
|
;
|
|
_sqlite3SrcListDelete(tls, db, pSrc)
|
|
return
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Generate bytecode for one of:
|
|
// **
|
|
// ** (1) ALTER TABLE pSrc DROP CONSTRAINT pCons
|
|
// ** (2) ALTER TABLE pSrc ALTER pCol DROP NOT NULL
|
|
// **
|
|
// ** One of pCons and pCol must be NULL and the other non-null.
|
|
// */
|
|
func _sqlite3AlterDropConstraint(tls *libc.TLS, pParse uintptr, pSrc uintptr, pCons uintptr, pCol uintptr) {
|
|
bp := tls.Alloc(64)
|
|
defer tls.Free(64)
|
|
var db, pTab, z, zArg uintptr
|
|
var _ /* iCol at bp+16 */ int32
|
|
var _ /* iDb at bp+0 */ int32
|
|
var _ /* zDb at bp+8 */ uintptr
|
|
_, _, _, _ = db, pTab, z, zArg
|
|
db = (*TParse)(unsafe.Pointer(pParse)).Fdb
|
|
pTab = uintptr(0)
|
|
**(**int32)(__ccgo_up(bp)) = 0
|
|
**(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0)
|
|
zArg = uintptr(0)
|
|
pTab = _alterFindTable(tls, pParse, pSrc, bp, bp+8, libc.BoolInt32(pCons != uintptr(0)))
|
|
if !(pTab != 0) {
|
|
return
|
|
}
|
|
if pCons != 0 {
|
|
z = _sqlite3NameFromToken(tls, db, pCons)
|
|
zArg = _sqlite3MPrintf(tls, db, __ccgo_ts+11953, libc.VaList(bp+32, z))
|
|
_sqlite3DbFree(tls, db, z)
|
|
} else {
|
|
if _alterFindCol(tls, pParse, pTab, pCol, bp+16) != 0 {
|
|
return
|
|
}
|
|
zArg = _sqlite3MPrintf(tls, db, __ccgo_ts+5317, libc.VaList(bp+32, **(**int32)(__ccgo_up(bp + 16))))
|
|
}
|
|
/* Edit the SQL for the named table. */
|
|
_sqlite3NestedParse(tls, pParse, __ccgo_ts+11956, libc.VaList(bp+32, **(**uintptr)(__ccgo_up(bp + 8)), zArg, (*TTable)(unsafe.Pointer(pTab)).FzName))
|
|
_sqlite3DbFree(tls, db, zArg)
|
|
/* Finally, reload the database schema. */
|
|
_renameReloadSchema(tls, pParse, **(**int32)(__ccgo_up(bp)), uint16(INITFLAG_AlterDropCons))
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Generate code to implement the "ALTER TABLE xxx RENAME TO yyy"
|
|
// ** command.
|
|
// */
|
|
func _sqlite3AlterRenameTable(tls *libc.TLS, pParse uintptr, pSrc uintptr, pName uintptr) {
|
|
bp := tls.Alloc(64)
|
|
defer tls.Free(64)
|
|
var db, pTab, pVTab, v, zDb, zName, zTabName, v2 uintptr
|
|
var i, iDb, nTabName, v1 int32
|
|
_, _, _, _, _, _, _, _, _, _, _, _ = db, i, iDb, nTabName, pTab, pVTab, v, zDb, zName, zTabName, v1, v2 /* Table being renamed */
|
|
zName = uintptr(0) /* NULL-terminated version of pName */
|
|
db = (*TParse)(unsafe.Pointer(pParse)).Fdb
|
|
pVTab = uintptr(0) /* Non-zero if this is a v-tab with an xRename() */
|
|
if (*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0 {
|
|
goto exit_rename_table
|
|
}
|
|
pTab = _sqlite3LocateTableItem(tls, pParse, uint32(0), pSrc+8)
|
|
if !(pTab != 0) {
|
|
goto exit_rename_table
|
|
}
|
|
iDb = _sqlite3SchemaToIndex(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, (*TTable)(unsafe.Pointer(pTab)).FpSchema)
|
|
zDb = (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(iDb)*32))).FzDbSName
|
|
/* Get a NULL terminated version of the new table name. */
|
|
zName = _sqlite3NameFromToken(tls, db, pName)
|
|
if !(zName != 0) {
|
|
goto exit_rename_table
|
|
}
|
|
/* Check that a table or index named 'zName' does not already exist
|
|
** in database iDb. If so, this is an error.
|
|
*/
|
|
if _sqlite3FindTable(tls, db, zName, zDb) != 0 || _sqlite3FindIndex(tls, db, zName, zDb) != 0 || _sqlite3IsShadowTableOf(tls, db, pTab, zName) != 0 {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+9346, libc.VaList(bp+8, zName))
|
|
goto exit_rename_table
|
|
}
|
|
/* Make sure it is not a system table being altered, or a reserved name
|
|
** that the table is being renamed to.
|
|
*/
|
|
if SQLITE_OK != _isAlterableTable(tls, pParse, pTab) {
|
|
goto exit_rename_table
|
|
}
|
|
if SQLITE_OK != _sqlite3CheckObjectName(tls, pParse, zName, __ccgo_ts+9405, zName) {
|
|
goto exit_rename_table
|
|
}
|
|
if libc.Int32FromUint8((*TTable)(unsafe.Pointer(pTab)).FeTabType) == int32(TABTYP_VIEW) {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+9411, libc.VaList(bp+8, (*TTable)(unsafe.Pointer(pTab)).FzName))
|
|
goto exit_rename_table
|
|
}
|
|
/* Invoke the authorization callback. */
|
|
if _sqlite3AuthCheck(tls, pParse, int32(SQLITE_ALTER_TABLE), zDb, (*TTable)(unsafe.Pointer(pTab)).FzName, uintptr(0)) != 0 {
|
|
goto exit_rename_table
|
|
}
|
|
if _sqlite3ViewGetColumnNames(tls, pParse, pTab) != 0 {
|
|
goto exit_rename_table
|
|
}
|
|
if libc.Int32FromUint8((*TTable)(unsafe.Pointer(pTab)).FeTabType) == int32(TABTYP_VTAB) {
|
|
pVTab = _sqlite3GetVTable(tls, db, pTab)
|
|
if (*Tsqlite3_module)(unsafe.Pointer((*Tsqlite3_vtab)(unsafe.Pointer((*TVTable)(unsafe.Pointer(pVTab)).FpVtab)).FpModule)).FxRename == uintptr(0) {
|
|
pVTab = uintptr(0)
|
|
}
|
|
}
|
|
/* Begin a transaction for database iDb. Then modify the schema cookie
|
|
** (since the ALTER TABLE modifies the schema). Call sqlite3MayAbort(),
|
|
** as the scalar functions (e.g. sqlite_rename_table()) invoked by the
|
|
** nested SQL may raise an exception. */
|
|
v = _sqlite3GetVdbe(tls, pParse)
|
|
if v == uintptr(0) {
|
|
goto exit_rename_table
|
|
}
|
|
_sqlite3MayAbort(tls, pParse)
|
|
/* figure out how many UTF-8 characters are in zName */
|
|
zTabName = (*TTable)(unsafe.Pointer(pTab)).FzName
|
|
nTabName = _sqlite3Utf8CharLen(tls, zTabName, -int32(1))
|
|
/* Rewrite all CREATE TABLE, INDEX, TRIGGER or VIEW statements in
|
|
** the schema to use the new table name. */
|
|
_sqlite3NestedParse(tls, pParse, __ccgo_ts+9438, libc.VaList(bp+8, zDb, zDb, zTabName, zName, libc.BoolInt32(iDb == int32(1)), zTabName))
|
|
/* Update the tbl_name and name columns of the sqlite_schema table
|
|
** as required. */
|
|
_sqlite3NestedParse(tls, pParse, __ccgo_ts+9622, libc.VaList(bp+8, zDb, zName, zName, zName, nTabName, zTabName))
|
|
/* If the sqlite_sequence table exists in this database, then update
|
|
** it with the new table name.
|
|
*/
|
|
if _sqlite3FindTable(tls, db, __ccgo_ts+9927, zDb) != 0 {
|
|
_sqlite3NestedParse(tls, pParse, __ccgo_ts+9943, libc.VaList(bp+8, zDb, zName, (*TTable)(unsafe.Pointer(pTab)).FzName))
|
|
}
|
|
/* If the table being renamed is not itself part of the temp database,
|
|
** edit view and trigger definitions within the temp database
|
|
** as required. */
|
|
if iDb != int32(1) {
|
|
_sqlite3NestedParse(tls, pParse, __ccgo_ts+10001, libc.VaList(bp+8, zDb, zTabName, zName, zTabName, zDb, zName))
|
|
}
|
|
/* If this is a virtual table, invoke the xRename() function if
|
|
** one is defined. The xRename() callback will modify the names
|
|
** of any resources used by the v-table implementation (including other
|
|
** SQLite tables) that are identified by the name of the virtual table.
|
|
*/
|
|
if pVTab != 0 {
|
|
v2 = pParse + 60
|
|
*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1
|
|
v1 = *(*int32)(unsafe.Pointer(v2))
|
|
i = v1
|
|
_sqlite3VdbeLoadString(tls, v, i, zName)
|
|
_sqlite3VdbeAddOp4(tls, v, int32(OP_VRename), i, 0, 0, pVTab, -int32(12))
|
|
}
|
|
_renameReloadSchema(tls, pParse, iDb, uint16(INITFLAG_AlterRename))
|
|
_renameTestSchema(tls, pParse, zDb, libc.BoolInt32(iDb == int32(1)), __ccgo_ts+10266, 0)
|
|
goto exit_rename_table
|
|
exit_rename_table:
|
|
;
|
|
_sqlite3SrcListDelete(tls, db, pSrc)
|
|
_sqlite3DbFree(tls, db, zName)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Prepare a statement of the form:
|
|
// **
|
|
// ** ALTER TABLE pSrc ALTER pCol SET NOT NULL
|
|
// */
|
|
func _sqlite3AlterSetNotNull(tls *libc.TLS, pParse uintptr, pSrc uintptr, pCol uintptr, pFirst uintptr) {
|
|
bp := tls.Alloc(80)
|
|
defer tls.Free(80)
|
|
var nCons int32
|
|
var pCons, pTab uintptr
|
|
var _ /* iCol at bp+0 */ int32
|
|
var _ /* iDb at bp+4 */ int32
|
|
var _ /* zDb at bp+8 */ uintptr
|
|
_, _, _ = nCons, pCons, pTab
|
|
pTab = uintptr(0)
|
|
**(**int32)(__ccgo_up(bp)) = 0
|
|
**(**int32)(__ccgo_up(bp + 4)) = 0
|
|
**(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0)
|
|
pCons = uintptr(0)
|
|
nCons = 0
|
|
/* Look up the table being altered. */
|
|
pTab = _alterFindTable(tls, pParse, pSrc, bp+4, bp+8, 0)
|
|
if !(pTab != 0) {
|
|
return
|
|
}
|
|
/* Find the column being altered. */
|
|
if _alterFindCol(tls, pParse, pTab, pCol, bp) != 0 {
|
|
return
|
|
}
|
|
/* Find the length in bytes of the constraint definition */
|
|
pCons = (*TToken)(unsafe.Pointer(pFirst)).Fz
|
|
nCons = _alterRtrimConstraint(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, pCons, int32(int64((*TParse)(unsafe.Pointer(pParse)).FsLastToken.Fz)-int64(pCons)))
|
|
/* Search for a constraint violation. Throw an exception if one is found. */
|
|
_sqlite3NestedParse(tls, pParse, __ccgo_ts+12079, libc.VaList(bp+24, int32(SQLITE_CONSTRAINT), **(**uintptr)(__ccgo_up(bp + 8)), (*TTable)(unsafe.Pointer(pTab)).FzName, libc.Int32FromUint32((*TToken)(unsafe.Pointer(pCol)).Fn), (*TToken)(unsafe.Pointer(pCol)).Fz))
|
|
/* Edit the SQL for the named table. */
|
|
_sqlite3NestedParse(tls, pParse, __ccgo_ts+12160, libc.VaList(bp+24, **(**uintptr)(__ccgo_up(bp + 8)), **(**int32)(__ccgo_up(bp)), nCons, pCons, **(**int32)(__ccgo_up(bp)), (*TTable)(unsafe.Pointer(pTab)).FzName))
|
|
/* Finally, reload the database schema. */
|
|
_renameReloadSchema(tls, pParse, **(**int32)(__ccgo_up(bp + 4)), uint16(INITFLAG_AlterDropCons))
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** The pExpr should be a TK_COLUMN expression. The table referred to
|
|
// ** is in pTabList or else it is the NEW or OLD table of a trigger.
|
|
// ** Check to see if it is OK to read this particular column.
|
|
// **
|
|
// ** If the auth function returns SQLITE_IGNORE, change the TK_COLUMN
|
|
// ** instruction into a TK_NULL. If the auth function returns SQLITE_DENY,
|
|
// ** then generate an error.
|
|
// */
|
|
func _sqlite3AuthRead(tls *libc.TLS, pParse uintptr, pExpr uintptr, pSchema uintptr, pTabList uintptr) {
|
|
var iCol, iDb, iSrc int32
|
|
var pTab, zCol uintptr
|
|
_, _, _, _, _ = iCol, iDb, iSrc, pTab, zCol
|
|
pTab = uintptr(0) /* Index of column in table */
|
|
iDb = _sqlite3SchemaToIndex(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, pSchema)
|
|
if iDb < 0 {
|
|
/* An attempt to read a column out of a subquery or other
|
|
** temporary table. */
|
|
return
|
|
}
|
|
if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) == int32(TK_TRIGGER) {
|
|
pTab = (*TParse)(unsafe.Pointer(pParse)).FpTriggerTab
|
|
} else {
|
|
iSrc = 0
|
|
for {
|
|
if !(iSrc < (*TSrcList)(unsafe.Pointer(pTabList)).FnSrc) {
|
|
break
|
|
}
|
|
if (*TExpr)(unsafe.Pointer(pExpr)).FiTable == (*(*TSrcItem)(unsafe.Pointer(pTabList + 8 + uintptr(iSrc)*80))).FiCursor {
|
|
pTab = (*(*TSrcItem)(unsafe.Pointer(pTabList + 8 + uintptr(iSrc)*80))).FpSTab
|
|
break
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
iSrc = iSrc + 1
|
|
}
|
|
}
|
|
iCol = int32((*TExpr)(unsafe.Pointer(pExpr)).FiColumn)
|
|
if pTab == uintptr(0) {
|
|
return
|
|
}
|
|
if iCol >= 0 {
|
|
zCol = (**(**TColumn)(__ccgo_up((*TTable)(unsafe.Pointer(pTab)).FaCol + uintptr(iCol)*16))).FzCnName
|
|
} else {
|
|
if int32((*TTable)(unsafe.Pointer(pTab)).FiPKey) >= 0 {
|
|
zCol = (**(**TColumn)(__ccgo_up((*TTable)(unsafe.Pointer(pTab)).FaCol + uintptr((*TTable)(unsafe.Pointer(pTab)).FiPKey)*16))).FzCnName
|
|
} else {
|
|
zCol = __ccgo_ts + 8225
|
|
}
|
|
}
|
|
if int32(SQLITE_IGNORE) == _sqlite3AuthReadCol(tls, pParse, (*TTable)(unsafe.Pointer(pTab)).FzName, zCol, iDb) {
|
|
(*TExpr)(unsafe.Pointer(pExpr)).Fop = uint8(TK_NULL)
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Invoke the authorization callback for permission to read column zCol from
|
|
// ** table zTab in database zDb. This function assumes that an authorization
|
|
// ** callback has been registered (i.e. that sqlite3.xAuth is not NULL).
|
|
// **
|
|
// ** If SQLITE_IGNORE is returned and pExpr is not NULL, then pExpr is changed
|
|
// ** to an SQL NULL expression. Otherwise, if pExpr is NULL, then SQLITE_IGNORE
|
|
// ** is treated as SQLITE_DENY. In this case an error is left in pParse.
|
|
// */
|
|
func _sqlite3AuthReadCol(tls *libc.TLS, pParse uintptr, zTab uintptr, zCol uintptr, iDb int32) (r int32) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var db, z, zDb uintptr
|
|
var rc int32
|
|
_, _, _, _ = db, rc, z, zDb
|
|
db = (*TParse)(unsafe.Pointer(pParse)).Fdb /* Database handle */
|
|
zDb = (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(iDb)*32))).FzDbSName /* Auth callback return code */
|
|
if (*Tsqlite3)(unsafe.Pointer(db)).Finit1.Fbusy != 0 {
|
|
return SQLITE_OK
|
|
}
|
|
rc = (*(*func(*libc.TLS, uintptr, int32, uintptr, uintptr, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*Tsqlite3)(unsafe.Pointer(db)).FxAuth})))(tls, (*Tsqlite3)(unsafe.Pointer(db)).FpAuthArg, int32(SQLITE_READ), zTab, zCol, zDb, (*TParse)(unsafe.Pointer(pParse)).FzAuthContext)
|
|
if rc == int32(SQLITE_DENY) {
|
|
z = Xsqlite3_mprintf(tls, __ccgo_ts+13660, libc.VaList(bp+8, zTab, zCol))
|
|
if (*Tsqlite3)(unsafe.Pointer(db)).FnDb > int32(2) || iDb != 0 {
|
|
z = Xsqlite3_mprintf(tls, __ccgo_ts+13666, libc.VaList(bp+8, zDb, z))
|
|
}
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+13672, libc.VaList(bp+8, z))
|
|
(*TParse)(unsafe.Pointer(pParse)).Frc = int32(SQLITE_AUTH)
|
|
} else {
|
|
if rc != int32(SQLITE_IGNORE) && rc != SQLITE_OK {
|
|
_sqliteAuthBadReturnCode(tls, pParse)
|
|
}
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Load all automatic extensions.
|
|
// **
|
|
// ** If anything goes wrong, set an error in the database connection.
|
|
// */
|
|
func _sqlite3AutoLoadExtensions(tls *libc.TLS, db uintptr) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var go1, rc, v2 int32
|
|
var i Tu32
|
|
var mutex, pThunk uintptr
|
|
var xInit Tsqlite3_loadext_entry
|
|
var v3 bool
|
|
var _ /* zErrmsg at bp+0 */ uintptr
|
|
_, _, _, _, _, _, _, _ = go1, i, mutex, pThunk, rc, xInit, v2, v3
|
|
go1 = int32(1)
|
|
if _sqlite3Autoext.FnExt == uint32(0) {
|
|
/* Common case: early out without every having to acquire a mutex */
|
|
return
|
|
}
|
|
i = uint32(0)
|
|
for {
|
|
if !(go1 != 0) {
|
|
break
|
|
}
|
|
mutex = _sqlite3MutexAlloc(tls, int32(SQLITE_MUTEX_STATIC_MAIN))
|
|
pThunk = uintptr(unsafe.Pointer(&_sqlite3Apis))
|
|
Xsqlite3_mutex_enter(tls, mutex)
|
|
if i >= _sqlite3Autoext.FnExt {
|
|
xInit = uintptr(0)
|
|
go1 = 0
|
|
} else {
|
|
xInit = **(**uintptr)(__ccgo_up(_sqlite3Autoext.FaExt + uintptr(i)*8))
|
|
}
|
|
Xsqlite3_mutex_leave(tls, mutex)
|
|
**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
|
|
if v3 = xInit != 0; v3 {
|
|
v2 = (*(*func(*libc.TLS, uintptr, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{xInit})))(tls, db, bp, pThunk)
|
|
rc = v2
|
|
}
|
|
if v3 && v2 != 0 {
|
|
_sqlite3ErrorWithMsg(tls, db, rc, __ccgo_ts+17769, libc.VaList(bp+16, **(**uintptr)(__ccgo_up(bp))))
|
|
go1 = 0
|
|
}
|
|
Xsqlite3_free(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
}
|
|
|
|
/************** End of loadext.c *********************************************/
|
|
/************** Begin file pragma.c ******************************************/
|
|
/*
|
|
** 2003 April 6
|
|
**
|
|
** 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 used to implement the PRAGMA command.
|
|
*/
|
|
/* #include "sqliteInt.h" */
|
|
|
|
/***************************************************************************
|
|
** The "pragma.h" include file is an automatically generated file that
|
|
** that includes the PragType_XXXX macro definitions and the aPragmaName[]
|
|
** object. This ensures that the aPragmaName[] table is arranged in
|
|
** lexicographical order to facility a binary search of the pragma name.
|
|
** Do not edit pragma.h directly. Edit and rerun the script in at
|
|
** ../tool/mkpragmatab.tcl. */
|
|
/************** Include pragma.h in the middle of pragma.c *******************/
|
|
/************** Begin file pragma.h ******************************************/
|
|
/* DO NOT EDIT!
|
|
** This file is automatically generated by the script at
|
|
** ../tool/mkpragmatab.tcl. To update the set of pragmas, edit
|
|
** that script and rerun it.
|
|
*/
|
|
|
|
/* The various pragma types */
|
|
|
|
/* Property flags associated with various pragma. */
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Generate VDBE code for a BEGIN statement.
|
|
// */
|
|
func _sqlite3BeginTransaction(tls *libc.TLS, pParse uintptr, type1 int32) {
|
|
var db, pBt, v uintptr
|
|
var eTxnType, i int32
|
|
_, _, _, _, _ = db, eTxnType, i, pBt, v
|
|
db = (*TParse)(unsafe.Pointer(pParse)).Fdb
|
|
if _sqlite3AuthCheck(tls, pParse, int32(SQLITE_TRANSACTION), __ccgo_ts+16131, uintptr(0), uintptr(0)) != 0 {
|
|
return
|
|
}
|
|
v = _sqlite3GetVdbe(tls, pParse)
|
|
if !(v != 0) {
|
|
return
|
|
}
|
|
if type1 != int32(TK_DEFERRED) {
|
|
i = 0
|
|
for {
|
|
if !(i < (*Tsqlite3)(unsafe.Pointer(db)).FnDb) {
|
|
break
|
|
}
|
|
pBt = (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(i)*32))).FpBt
|
|
if pBt != 0 && _sqlite3BtreeIsReadonly(tls, pBt) != 0 {
|
|
eTxnType = 0 /* Read txn */
|
|
} else {
|
|
if type1 == int32(TK_EXCLUSIVE) {
|
|
eTxnType = int32(2) /* Exclusive txn */
|
|
} else {
|
|
eTxnType = int32(1) /* Write txn */
|
|
}
|
|
}
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_Transaction), i, eTxnType)
|
|
_sqlite3VdbeUsesBtree(tls, v, i)
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
}
|
|
_sqlite3VdbeAddOp0(tls, v, int32(OP_AutoCommit))
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Generate code to drop a table.
|
|
// */
|
|
func _sqlite3CodeDropTable(tls *libc.TLS, pParse uintptr, pTab uintptr, iDb int32, isView int32) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var db, pDb, pTrigger, v uintptr
|
|
_, _, _, _ = db, pDb, pTrigger, v
|
|
db = (*TParse)(unsafe.Pointer(pParse)).Fdb
|
|
pDb = (*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(iDb)*32
|
|
v = _sqlite3GetVdbe(tls, pParse)
|
|
_sqlite3BeginWriteOperation(tls, pParse, int32(1), iDb)
|
|
if libc.Int32FromUint8((*TTable)(unsafe.Pointer(pTab)).FeTabType) == int32(TABTYP_VTAB) {
|
|
_sqlite3VdbeAddOp0(tls, v, int32(OP_VBegin))
|
|
}
|
|
/* Drop all triggers associated with the table being dropped. Code
|
|
** is generated to remove entries from sqlite_schema and/or
|
|
** sqlite_temp_schema if required.
|
|
*/
|
|
pTrigger = _sqlite3TriggerList(tls, pParse, pTab)
|
|
for pTrigger != 0 {
|
|
_sqlite3DropTriggerPtr(tls, pParse, pTrigger)
|
|
pTrigger = (*TTrigger)(unsafe.Pointer(pTrigger)).FpNext
|
|
}
|
|
/* Remove any entries of the sqlite_sequence table associated with
|
|
** the table being dropped. This is done before the table is dropped
|
|
** at the btree level, in case the sqlite_sequence table needs to
|
|
** move as a result of the drop (can happen in auto-vacuum mode).
|
|
*/
|
|
if (*TTable)(unsafe.Pointer(pTab)).FtabFlags&uint32(TF_Autoincrement) != 0 {
|
|
_sqlite3NestedParse(tls, pParse, __ccgo_ts+14993, libc.VaList(bp+8, (*TDb)(unsafe.Pointer(pDb)).FzDbSName, (*TTable)(unsafe.Pointer(pTab)).FzName))
|
|
}
|
|
/* Drop all entries in the schema table that refer to the
|
|
** table. The program name loops through the schema table and deletes
|
|
** every row that refers to a table of the same name as the one being
|
|
** dropped. Triggers are handled separately because a trigger can be
|
|
** created in the temp database that refers to a table in another
|
|
** database.
|
|
*/
|
|
_sqlite3NestedParse(tls, pParse, __ccgo_ts+15038, libc.VaList(bp+8, (*TDb)(unsafe.Pointer(pDb)).FzDbSName, (*TTable)(unsafe.Pointer(pTab)).FzName))
|
|
if !(isView != 0) && !(libc.Int32FromUint8((*TTable)(unsafe.Pointer(pTab)).FeTabType) == libc.Int32FromInt32(TABTYP_VTAB)) {
|
|
_destroyTable(tls, pParse, pTab)
|
|
}
|
|
/* Remove the table entry from SQLite's internal schema and modify
|
|
** the schema cookie.
|
|
*/
|
|
if libc.Int32FromUint8((*TTable)(unsafe.Pointer(pTab)).FeTabType) == int32(TABTYP_VTAB) {
|
|
_sqlite3VdbeAddOp4(tls, v, int32(OP_VDestroy), iDb, 0, 0, (*TTable)(unsafe.Pointer(pTab)).FzName, 0)
|
|
_sqlite3MayAbort(tls, pParse)
|
|
}
|
|
_sqlite3VdbeAddOp4(tls, v, int32(OP_DropTable), iDb, 0, 0, (*TTable)(unsafe.Pointer(pTab)).FzName, 0)
|
|
_sqlite3ChangeCookie(tls, pParse, iDb)
|
|
_sqliteViewResetAll(tls, db, iDb)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Return true if zName points to a name that may be used to refer to
|
|
// ** database iDb attached to handle db.
|
|
// */
|
|
func _sqlite3DbIsNamed(tls *libc.TLS, db uintptr, iDb int32, zName uintptr) (r int32) {
|
|
return libc.BoolInt32(_sqlite3StrICmp(tls, (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(iDb)*32))).FzDbSName, zName) == 0 || iDb == 0 && _sqlite3StrICmp(tls, __ccgo_ts+6844, zName) == 0)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This routine is called to do the work of a DROP TABLE statement.
|
|
// ** pName is the name of the table to be dropped.
|
|
// */
|
|
func _sqlite3DropTable(tls *libc.TLS, pParse uintptr, pName uintptr, isView int32, noErr int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var code, iDb int32
|
|
var db, pTab, v, zArg2, zDb, zTab, v1 uintptr
|
|
_, _, _, _, _, _, _, _, _ = code, db, iDb, pTab, v, zArg2, zDb, zTab, v1
|
|
db = (*TParse)(unsafe.Pointer(pParse)).Fdb
|
|
if (*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0 {
|
|
goto exit_drop_table
|
|
}
|
|
if _sqlite3ReadSchema(tls, pParse) != 0 {
|
|
goto exit_drop_table
|
|
}
|
|
if noErr != 0 {
|
|
(*Tsqlite3)(unsafe.Pointer(db)).FsuppressErr = (*Tsqlite3)(unsafe.Pointer(db)).FsuppressErr + 1
|
|
}
|
|
pTab = _sqlite3LocateTableItem(tls, pParse, libc.Uint32FromInt32(isView), pName+8)
|
|
if noErr != 0 {
|
|
(*Tsqlite3)(unsafe.Pointer(db)).FsuppressErr = (*Tsqlite3)(unsafe.Pointer(db)).FsuppressErr - 1
|
|
}
|
|
if pTab == uintptr(0) {
|
|
if noErr != 0 {
|
|
_sqlite3CodeVerifyNamedSchema(tls, pParse, *(*uintptr)(unsafe.Pointer(pName + 8 + 72)))
|
|
_sqlite3ForceNotReadOnly(tls, pParse)
|
|
}
|
|
goto exit_drop_table
|
|
}
|
|
iDb = _sqlite3SchemaToIndex(tls, db, (*TTable)(unsafe.Pointer(pTab)).FpSchema)
|
|
/* If pTab is a virtual table, call ViewGetColumnNames() to ensure
|
|
** it is initialized.
|
|
*/
|
|
if libc.Int32FromUint8((*TTable)(unsafe.Pointer(pTab)).FeTabType) == int32(TABTYP_VTAB) && _sqlite3ViewGetColumnNames(tls, pParse, pTab) != 0 {
|
|
goto exit_drop_table
|
|
}
|
|
if libc.Bool(!(libc.Int32FromInt32(OMIT_TEMPDB) != 0)) && iDb == int32(1) {
|
|
v1 = __ccgo_ts + 6792
|
|
} else {
|
|
v1 = __ccgo_ts + 6312
|
|
}
|
|
zTab = v1
|
|
zDb = (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(iDb)*32))).FzDbSName
|
|
zArg2 = uintptr(0)
|
|
if _sqlite3AuthCheck(tls, pParse, int32(SQLITE_DELETE), zTab, uintptr(0), zDb) != 0 {
|
|
goto exit_drop_table
|
|
}
|
|
if isView != 0 {
|
|
if libc.Bool(!(libc.Int32FromInt32(OMIT_TEMPDB) != 0)) && iDb == int32(1) {
|
|
code = int32(SQLITE_DROP_TEMP_VIEW)
|
|
} else {
|
|
code = int32(SQLITE_DROP_VIEW)
|
|
}
|
|
} else {
|
|
if libc.Int32FromUint8((*TTable)(unsafe.Pointer(pTab)).FeTabType) == int32(TABTYP_VTAB) {
|
|
code = int32(SQLITE_DROP_VTABLE)
|
|
zArg2 = (*TModule)(unsafe.Pointer((*TVTable)(unsafe.Pointer(_sqlite3GetVTable(tls, db, pTab))).FpMod)).FzName
|
|
} else {
|
|
if libc.Bool(!(libc.Int32FromInt32(OMIT_TEMPDB) != 0)) && iDb == int32(1) {
|
|
code = int32(SQLITE_DROP_TEMP_TABLE)
|
|
} else {
|
|
code = int32(SQLITE_DROP_TABLE)
|
|
}
|
|
}
|
|
}
|
|
if _sqlite3AuthCheck(tls, pParse, code, (*TTable)(unsafe.Pointer(pTab)).FzName, zArg2, zDb) != 0 {
|
|
goto exit_drop_table
|
|
}
|
|
if _sqlite3AuthCheck(tls, pParse, int32(SQLITE_DELETE), (*TTable)(unsafe.Pointer(pTab)).FzName, uintptr(0), zDb) != 0 {
|
|
goto exit_drop_table
|
|
}
|
|
if _tableMayNotBeDropped(tls, db, pTab) != 0 {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+15105, libc.VaList(bp+8, (*TTable)(unsafe.Pointer(pTab)).FzName))
|
|
goto exit_drop_table
|
|
}
|
|
/* Ensure DROP TABLE is not used on a view, and DROP VIEW is not used
|
|
** on a table.
|
|
*/
|
|
if isView != 0 && !(libc.Int32FromUint8((*TTable)(unsafe.Pointer(pTab)).FeTabType) == libc.Int32FromInt32(TABTYP_VIEW)) {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+15133, libc.VaList(bp+8, (*TTable)(unsafe.Pointer(pTab)).FzName))
|
|
goto exit_drop_table
|
|
}
|
|
if !(isView != 0) && libc.Int32FromUint8((*TTable)(unsafe.Pointer(pTab)).FeTabType) == int32(TABTYP_VIEW) {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+15167, libc.VaList(bp+8, (*TTable)(unsafe.Pointer(pTab)).FzName))
|
|
goto exit_drop_table
|
|
}
|
|
/* Generate code to remove the table from the schema table
|
|
** on disk.
|
|
*/
|
|
v = _sqlite3GetVdbe(tls, pParse)
|
|
if v != 0 {
|
|
_sqlite3BeginWriteOperation(tls, pParse, int32(1), iDb)
|
|
if !(isView != 0) {
|
|
_sqlite3ClearStatTables(tls, pParse, iDb, __ccgo_ts+13076, (*TTable)(unsafe.Pointer(pTab)).FzName)
|
|
_sqlite3FkDropTable(tls, pParse, pName, pTab)
|
|
}
|
|
_sqlite3CodeDropTable(tls, pParse, pTab, iDb, isView)
|
|
}
|
|
goto exit_drop_table
|
|
exit_drop_table:
|
|
;
|
|
_sqlite3SrcListDelete(tls, db, pName)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Drop a trigger given a pointer to that trigger.
|
|
// */
|
|
func _sqlite3DropTriggerPtr(tls *libc.TLS, pParse uintptr, pTrigger uintptr) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var code, iDb int32
|
|
var db, pTable, v, zDb, zTab, v1 uintptr
|
|
_, _, _, _, _, _, _, _ = code, db, iDb, pTable, v, zDb, zTab, v1
|
|
db = (*TParse)(unsafe.Pointer(pParse)).Fdb
|
|
iDb = _sqlite3SchemaToIndex(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, (*TTrigger)(unsafe.Pointer(pTrigger)).FpSchema)
|
|
pTable = _tableOfTrigger(tls, pTrigger)
|
|
if pTable != 0 {
|
|
code = int32(SQLITE_DROP_TRIGGER)
|
|
zDb = (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(iDb)*32))).FzDbSName
|
|
if libc.Bool(!(libc.Int32FromInt32(OMIT_TEMPDB) != 0)) && iDb == int32(1) {
|
|
v1 = __ccgo_ts + 6792
|
|
} else {
|
|
v1 = __ccgo_ts + 6312
|
|
}
|
|
zTab = v1
|
|
if iDb == int32(1) {
|
|
code = int32(SQLITE_DROP_TEMP_TRIGGER)
|
|
}
|
|
if _sqlite3AuthCheck(tls, pParse, code, (*TTrigger)(unsafe.Pointer(pTrigger)).FzName, (*TTable)(unsafe.Pointer(pTable)).FzName, zDb) != 0 || _sqlite3AuthCheck(tls, pParse, int32(SQLITE_DELETE), zTab, uintptr(0), zDb) != 0 {
|
|
return
|
|
}
|
|
}
|
|
/* Generate code to destroy the database record of the trigger.
|
|
*/
|
|
v1 = _sqlite3GetVdbe(tls, pParse)
|
|
v = v1
|
|
if v1 != uintptr(0) {
|
|
_sqlite3NestedParse(tls, pParse, __ccgo_ts+22426, libc.VaList(bp+8, (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(iDb)*32))).FzDbSName, (*TTrigger)(unsafe.Pointer(pTrigger)).FzName))
|
|
_sqlite3ChangeCookie(tls, pParse, iDb)
|
|
_sqlite3VdbeAddOp4(tls, v, int32(OP_DropTrigger), iDb, 0, 0, (*TTrigger)(unsafe.Pointer(pTrigger)).FzName, 0)
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Return a static string that describes the kind of error specified in the
|
|
// ** argument.
|
|
// */
|
|
func _sqlite3ErrStr(tls *libc.TLS, rc int32) (r uintptr) {
|
|
var zErr uintptr
|
|
_ = zErr
|
|
zErr = __ccgo_ts + 25858
|
|
switch rc {
|
|
case libc.Int32FromInt32(SQLITE_ABORT) | libc.Int32FromInt32(2)<<libc.Int32FromInt32(8):
|
|
zErr = __ccgo_ts + 25872
|
|
case int32(SQLITE_ROW):
|
|
zErr = __ccgo_ts + 25894
|
|
case int32(SQLITE_DONE):
|
|
zErr = __ccgo_ts + 25916
|
|
default:
|
|
rc = rc & int32(0xff)
|
|
if rc >= 0 && rc < libc.Int32FromUint64(libc.Uint64FromInt64(232)/libc.Uint64FromInt64(8)) && _aMsg[rc] != uintptr(0) {
|
|
zErr = _aMsg[rc]
|
|
}
|
|
break
|
|
}
|
|
return zErr
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** The SrcItem structure passed as the second argument represents a
|
|
// ** sub-query in the FROM clause of a SELECT statement. This function
|
|
// ** allocates and populates the SrcItem.pTab object. If successful,
|
|
// ** SQLITE_OK is returned. Otherwise, if an OOM error is encountered,
|
|
// ** SQLITE_NOMEM.
|
|
// */
|
|
func _sqlite3ExpandSubquery(tls *libc.TLS, pParse uintptr, pFrom uintptr) (r int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var pSel, pTab, v1 uintptr
|
|
var v2 int32
|
|
_, _, _, _ = pSel, pTab, v1, v2
|
|
pSel = (*TSubquery)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pFrom + 72)))).FpSelect
|
|
v1 = _sqlite3DbMallocZero(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, uint64(120))
|
|
pTab = v1
|
|
(*TSrcItem)(unsafe.Pointer(pFrom)).FpSTab = v1
|
|
if pTab == uintptr(0) {
|
|
return int32(SQLITE_NOMEM)
|
|
}
|
|
(*TTable)(unsafe.Pointer(pTab)).FnTabRef = uint32(1)
|
|
if (*TSrcItem)(unsafe.Pointer(pFrom)).FzAlias != 0 {
|
|
(*TTable)(unsafe.Pointer(pTab)).FzName = _sqlite3DbStrDup(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, (*TSrcItem)(unsafe.Pointer(pFrom)).FzAlias)
|
|
} else {
|
|
(*TTable)(unsafe.Pointer(pTab)).FzName = _sqlite3MPrintf(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, __ccgo_ts+21279, libc.VaList(bp+8, pFrom))
|
|
}
|
|
for (*TSelect)(unsafe.Pointer(pSel)).FpPrior != 0 {
|
|
pSel = (*TSelect)(unsafe.Pointer(pSel)).FpPrior
|
|
}
|
|
_sqlite3ColumnsFromExprList(tls, pParse, (*TSelect)(unsafe.Pointer(pSel)).FpEList, pTab+54, pTab+8)
|
|
(*TTable)(unsafe.Pointer(pTab)).FiPKey = int16(-int32(1))
|
|
(*TTable)(unsafe.Pointer(pTab)).FeTabType = uint8(TABTYP_VIEW)
|
|
(*TTable)(unsafe.Pointer(pTab)).FnRowLogEst = int16(200)
|
|
/* The usual case - do not allow ROWID on a subquery */
|
|
**(**Tu32)(__ccgo_up(pTab + 48)) |= libc.Uint32FromInt32(libc.Int32FromInt32(TF_Ephemeral) | libc.Int32FromInt32(TF_NoVisibleRowid))
|
|
if (*TParse)(unsafe.Pointer(pParse)).FnErr != 0 {
|
|
v2 = int32(SQLITE_ERROR)
|
|
} else {
|
|
v2 = SQLITE_OK
|
|
}
|
|
return v2
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Attach an ORDER BY clause to a function call.
|
|
// **
|
|
// ** functionname( arguments ORDER BY sortlist )
|
|
// ** \_____________________/ \______/
|
|
// ** pExpr pOrderBy
|
|
// **
|
|
// ** The ORDER BY clause is inserted into a new Expr node of type TK_ORDER
|
|
// ** and added to the Expr.pLeft field of the parent TK_FUNCTION node.
|
|
// */
|
|
func _sqlite3ExprAddFunctionOrderBy(tls *libc.TLS, pParse uintptr, pExpr uintptr, pOrderBy uintptr) {
|
|
var db, pOB uintptr
|
|
_, _ = db, pOB
|
|
db = (*TParse)(unsafe.Pointer(pParse)).Fdb
|
|
if pOrderBy == uintptr(0) {
|
|
return
|
|
}
|
|
if pExpr == uintptr(0) {
|
|
_sqlite3ExprListDelete(tls, db, pOrderBy)
|
|
return
|
|
}
|
|
if *(*uintptr)(unsafe.Pointer(pExpr + 32)) == uintptr(0) || (*TExprList)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pExpr + 32)))).FnExpr == 0 {
|
|
/* Ignore ORDER BY on zero-argument aggregates */
|
|
_sqlite3ParserAddCleanup(tls, pParse, __ccgo_fp(_sqlite3ExprListDeleteGeneric), pOrderBy)
|
|
return
|
|
}
|
|
if (*TExpr)(unsafe.Pointer(pExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_WinFunc)) != uint32(0) && libc.Int32FromUint8((*TWindow)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pExpr + 64)))).FeFrmType) != int32(TK_FILTER) {
|
|
_sqlite3ExprOrderByAggregateError(tls, pParse, pExpr)
|
|
_sqlite3ExprListDelete(tls, db, pOrderBy)
|
|
return
|
|
}
|
|
if (*TExprList)(unsafe.Pointer(pOrderBy)).FnExpr > **(**int32)(__ccgo_up(db + 136 + 2*4)) {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+7653, 0)
|
|
_sqlite3ExprListDelete(tls, db, pOrderBy)
|
|
return
|
|
}
|
|
pOB = _sqlite3ExprAlloc(tls, db, int32(TK_ORDER), uintptr(0), 0)
|
|
if pOB == uintptr(0) {
|
|
_sqlite3ExprListDelete(tls, db, pOrderBy)
|
|
return
|
|
}
|
|
*(*uintptr)(unsafe.Pointer(pOB + 32)) = pOrderBy
|
|
(*TExpr)(unsafe.Pointer(pExpr)).FpLeft = pOB
|
|
**(**Tu32)(__ccgo_up(pOB + 4)) |= libc.Uint32FromInt32(libc.Int32FromInt32(EP_FullSize))
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Check that argument nHeight is less than or equal to the maximum
|
|
// ** expression depth allowed. If it is not, leave an error message in
|
|
// ** pParse.
|
|
// */
|
|
func _sqlite3ExprCheckHeight(tls *libc.TLS, pParse uintptr, nHeight int32) (r int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var mxHeight, rc int32
|
|
_, _ = mxHeight, rc
|
|
rc = SQLITE_OK
|
|
mxHeight = **(**int32)(__ccgo_up((*TParse)(unsafe.Pointer(pParse)).Fdb + 136 + 3*4))
|
|
if nHeight > mxHeight {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+7889, libc.VaList(bp+8, mxHeight))
|
|
rc = int32(SQLITE_ERROR)
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Generate code to extract the value of the iCol-th column of a table.
|
|
// */
|
|
func _sqlite3ExprCodeGetColumnOfTable(tls *libc.TLS, v uintptr, pTab uintptr, iTabCur int32, iCol int32, regOut int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var op, savedSelfTab, x int32
|
|
var pCol, pParse, v1 uintptr
|
|
_, _, _, _, _, _ = op, pCol, pParse, savedSelfTab, x, v1
|
|
if iCol < 0 || iCol == int32((*TTable)(unsafe.Pointer(pTab)).FiPKey) {
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_Rowid), iTabCur, regOut)
|
|
} else {
|
|
if libc.Int32FromUint8((*TTable)(unsafe.Pointer(pTab)).FeTabType) == int32(TABTYP_VTAB) {
|
|
op = int32(OP_VColumn)
|
|
x = iCol
|
|
} else {
|
|
v1 = (*TTable)(unsafe.Pointer(pTab)).FaCol + uintptr(iCol)*16
|
|
pCol = v1
|
|
if libc.Int32FromUint16((*TColumn)(unsafe.Pointer(v1)).FcolFlags)&int32(COLFLAG_VIRTUAL) != 0 {
|
|
pParse = _sqlite3VdbeParser(tls, v)
|
|
if libc.Int32FromUint16((*TColumn)(unsafe.Pointer(pCol)).FcolFlags)&int32(COLFLAG_BUSY) != 0 {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+8480, libc.VaList(bp+8, (*TColumn)(unsafe.Pointer(pCol)).FzCnName))
|
|
} else {
|
|
savedSelfTab = (*TParse)(unsafe.Pointer(pParse)).FiSelfTab
|
|
v1 = pCol + 14
|
|
*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) | libc.Int32FromInt32(COLFLAG_BUSY))
|
|
(*TParse)(unsafe.Pointer(pParse)).FiSelfTab = iTabCur + int32(1)
|
|
_sqlite3ExprCodeGeneratedColumn(tls, pParse, pTab, pCol, regOut)
|
|
(*TParse)(unsafe.Pointer(pParse)).FiSelfTab = savedSelfTab
|
|
v1 = pCol + 14
|
|
*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) & ^libc.Int32FromInt32(COLFLAG_BUSY))
|
|
}
|
|
return
|
|
} else {
|
|
if !((*TTable)(unsafe.Pointer(pTab)).FtabFlags&libc.Uint32FromInt32(TF_WithoutRowid) == libc.Uint32FromInt32(0)) {
|
|
x = _sqlite3TableColumnToIndex(tls, _sqlite3PrimaryKeyIndex(tls, pTab), iCol)
|
|
op = int32(OP_Column)
|
|
} else {
|
|
x = int32(_sqlite3TableColumnToStorage(tls, pTab, int16(iCol)))
|
|
op = int32(OP_Column)
|
|
}
|
|
}
|
|
}
|
|
_sqlite3VdbeAddOp3(tls, v, op, iTabCur, x, regOut)
|
|
_sqlite3ColumnDefault(tls, v, pTab, iCol, regOut)
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Construct a new expression node for a function with multiple
|
|
// ** arguments.
|
|
// */
|
|
func _sqlite3ExprFunction(tls *libc.TLS, pParse uintptr, pList uintptr, pToken uintptr, eDistinct int32) (r uintptr) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var db, pNew uintptr
|
|
_, _ = db, pNew
|
|
db = (*TParse)(unsafe.Pointer(pParse)).Fdb
|
|
pNew = _sqlite3ExprAlloc(tls, db, int32(TK_FUNCTION), pToken, int32(1))
|
|
if pNew == uintptr(0) {
|
|
_sqlite3ExprListDelete(tls, db, pList) /* Avoid memory leak when malloc fails */
|
|
return uintptr(0)
|
|
}
|
|
*(*int32)(unsafe.Pointer(pNew + 52)) = int32(int64((*TToken)(unsafe.Pointer(pToken)).Fz) - int64((*TParse)(unsafe.Pointer(pParse)).FzTail))
|
|
if pList != 0 && (*TExprList)(unsafe.Pointer(pList)).FnExpr > **(**int32)(__ccgo_up((*TParse)(unsafe.Pointer(pParse)).Fdb + 136 + 6*4)) && !((*TParse)(unsafe.Pointer(pParse)).Fnested != 0) {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+7983, libc.VaList(bp+8, pToken))
|
|
}
|
|
*(*uintptr)(unsafe.Pointer(pNew + 32)) = pList
|
|
**(**Tu32)(__ccgo_up(pNew + 4)) |= libc.Uint32FromInt32(libc.Int32FromInt32(EP_HasFunc))
|
|
_sqlite3ExprSetHeightAndFlags(tls, pParse, pNew)
|
|
if eDistinct == int32(SF_Distinct) {
|
|
**(**Tu32)(__ccgo_up(pNew + 4)) |= libc.Uint32FromInt32(libc.Int32FromInt32(EP_Distinct))
|
|
}
|
|
return pNew
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** pColumns and pExpr form a vector assignment which is part of the SET
|
|
// ** clause of an UPDATE statement. Like this:
|
|
// **
|
|
// ** (a,b,c) = (expr1,expr2,expr3)
|
|
// ** Or: (a,b,c) = (SELECT x,y,z FROM ....)
|
|
// **
|
|
// ** For each term of the vector assignment, append new entries to the
|
|
// ** expression list pList. In the case of a subquery on the RHS, append
|
|
// ** TK_SELECT_COLUMN expressions.
|
|
// */
|
|
func _sqlite3ExprListAppendVector(tls *libc.TLS, pParse uintptr, pList uintptr, pColumns uintptr, pExpr uintptr) (r uintptr) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var db, pFirst, pSubExpr uintptr
|
|
var i, iFirst, n, v1 int32
|
|
var v3 bool
|
|
_, _, _, _, _, _, _, _ = db, i, iFirst, n, pFirst, pSubExpr, v1, v3
|
|
db = (*TParse)(unsafe.Pointer(pParse)).Fdb
|
|
if pList != 0 {
|
|
v1 = (*TExprList)(unsafe.Pointer(pList)).FnExpr
|
|
} else {
|
|
v1 = 0
|
|
}
|
|
iFirst = v1
|
|
/* pColumns can only be NULL due to an OOM but an OOM will cause an
|
|
** exit prior to this routine being invoked */
|
|
if pColumns == uintptr(0) {
|
|
goto vector_append_error
|
|
}
|
|
if pExpr == uintptr(0) {
|
|
goto vector_append_error
|
|
}
|
|
/* If the RHS is a vector, then we can immediately check to see that
|
|
** the size of the RHS and LHS match. But if the RHS is a SELECT,
|
|
** wildcards ("*") in the result set of the SELECT must be expanded before
|
|
** we can do the size check, so defer the size check until code generation.
|
|
*/
|
|
if v3 = libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) != int32(TK_SELECT); v3 {
|
|
v1 = _sqlite3ExprVectorSize(tls, pExpr)
|
|
n = v1
|
|
}
|
|
if v3 && (*TIdList)(unsafe.Pointer(pColumns)).FnId != v1 {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+8153, libc.VaList(bp+8, (*TIdList)(unsafe.Pointer(pColumns)).FnId, n))
|
|
goto vector_append_error
|
|
}
|
|
i = 0
|
|
for {
|
|
if !(i < (*TIdList)(unsafe.Pointer(pColumns)).FnId) {
|
|
break
|
|
}
|
|
pSubExpr = _sqlite3ExprForVectorField(tls, pParse, pExpr, i, (*TIdList)(unsafe.Pointer(pColumns)).FnId)
|
|
if pSubExpr == uintptr(0) {
|
|
goto _4
|
|
}
|
|
pList = _sqlite3ExprListAppend(tls, pParse, pList, pSubExpr)
|
|
if pList != 0 {
|
|
(*(*TExprList_item)(unsafe.Pointer(pList + 8 + uintptr((*TExprList)(unsafe.Pointer(pList)).FnExpr-int32(1))*32))).FzEName = (*(*TIdList_item)(unsafe.Pointer(pColumns + 8 + uintptr(i)*8))).FzName
|
|
(*(*TIdList_item)(unsafe.Pointer(pColumns + 8 + uintptr(i)*8))).FzName = uintptr(0)
|
|
}
|
|
goto _4
|
|
_4:
|
|
;
|
|
i = i + 1
|
|
}
|
|
if !((*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0) && libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) == int32(TK_SELECT) && pList != uintptr(0) {
|
|
pFirst = (*(*TExprList_item)(unsafe.Pointer(pList + 8 + uintptr(iFirst)*32))).FpExpr
|
|
/* Store the SELECT statement in pRight so it will be deleted when
|
|
** sqlite3ExprListDelete() is called */
|
|
(*TExpr)(unsafe.Pointer(pFirst)).FpRight = pExpr
|
|
pExpr = uintptr(0)
|
|
/* Remember the size of the LHS in iTable so that we can check that
|
|
** the RHS and LHS sizes match during code generation. */
|
|
(*TExpr)(unsafe.Pointer(pFirst)).FiTable = (*TIdList)(unsafe.Pointer(pColumns)).FnId
|
|
}
|
|
goto vector_append_error
|
|
vector_append_error:
|
|
;
|
|
_sqlite3ExprUnmapAndDelete(tls, pParse, pExpr)
|
|
_sqlite3IdListDelete(tls, db, pColumns)
|
|
return pList
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** If the expression list pEList contains more than iLimit elements,
|
|
// ** leave an error message in pParse.
|
|
// */
|
|
func _sqlite3ExprListCheckLength(tls *libc.TLS, pParse uintptr, pEList uintptr, zObject uintptr) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var mx int32
|
|
_ = mx
|
|
mx = **(**int32)(__ccgo_up((*TParse)(unsafe.Pointer(pParse)).Fdb + 136 + 2*4))
|
|
if pEList != 0 && (*TExprList)(unsafe.Pointer(pEList)).FnExpr > mx {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+8183, libc.VaList(bp+8, zObject))
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Expression list pEList is a list of vector values. This function
|
|
// ** converts the contents of pEList to a VALUES(...) Select statement
|
|
// ** returning 1 row for each element of the list. For example, the
|
|
// ** expression list:
|
|
// **
|
|
// ** ( (1,2), (3,4) (5,6) )
|
|
// **
|
|
// ** is translated to the equivalent of:
|
|
// **
|
|
// ** VALUES(1,2), (3,4), (5,6)
|
|
// **
|
|
// ** Each of the vector values in pEList must contain exactly nElem terms.
|
|
// ** If a list element that is not a vector or does not contain nElem terms,
|
|
// ** an error message is left in pParse.
|
|
// **
|
|
// ** This is used as part of processing IN(...) expressions with a list
|
|
// ** of vectors on the RHS. e.g. "... IN ((1,2), (3,4), (5,6))".
|
|
// */
|
|
func _sqlite3ExprListToValues(tls *libc.TLS, pParse uintptr, nElem int32, pEList uintptr) (r uintptr) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var ii, nExprElem int32
|
|
var pExpr, pRet, pSel, v2 uintptr
|
|
_, _, _, _, _, _ = ii, nExprElem, pExpr, pRet, pSel, v2
|
|
pRet = uintptr(0)
|
|
ii = 0
|
|
for {
|
|
if !(ii < (*TExprList)(unsafe.Pointer(pEList)).FnExpr) {
|
|
break
|
|
}
|
|
pExpr = (*(*TExprList_item)(unsafe.Pointer(pEList + 8 + uintptr(ii)*32))).FpExpr
|
|
if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) == int32(TK_VECTOR) {
|
|
nExprElem = (*TExprList)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pExpr + 32)))).FnExpr
|
|
} else {
|
|
nExprElem = int32(1)
|
|
}
|
|
if nExprElem != nElem {
|
|
if nExprElem > int32(1) {
|
|
v2 = __ccgo_ts + 7937
|
|
} else {
|
|
v2 = __ccgo_ts + 1704
|
|
}
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+7939, libc.VaList(bp+8, nExprElem, v2, nElem))
|
|
break
|
|
}
|
|
pSel = _sqlite3SelectNew(tls, pParse, *(*uintptr)(unsafe.Pointer(pExpr + 32)), uintptr(0), uintptr(0), uintptr(0), uintptr(0), uintptr(0), uint32(SF_Values), uintptr(0))
|
|
*(*uintptr)(unsafe.Pointer(pExpr + 32)) = uintptr(0)
|
|
if pSel != 0 {
|
|
if pRet != 0 {
|
|
(*TSelect)(unsafe.Pointer(pSel)).Fop = uint8(TK_ALL)
|
|
(*TSelect)(unsafe.Pointer(pSel)).FpPrior = pRet
|
|
}
|
|
pRet = pSel
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
ii = ii + 1
|
|
}
|
|
if pRet != 0 && (*TSelect)(unsafe.Pointer(pRet)).FpPrior != 0 {
|
|
**(**Tu32)(__ccgo_up(pRet + 4)) |= uint32(SF_MultiValue)
|
|
}
|
|
_sqlite3ExprListDelete(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, pEList)
|
|
return pRet
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Parameter zName points to a nul-terminated buffer containing the name
|
|
// ** of a database ("main", "temp" or the name of an attached db). This
|
|
// ** function returns the index of the named database in db->aDb[], or
|
|
// ** -1 if the named db cannot be found.
|
|
// */
|
|
func _sqlite3FindDbName(tls *libc.TLS, db uintptr, zName uintptr) (r int32) {
|
|
var i int32
|
|
var pDb uintptr
|
|
_, _ = i, pDb
|
|
i = -int32(1) /* Database number */
|
|
if zName != 0 {
|
|
i = (*Tsqlite3)(unsafe.Pointer(db)).FnDb - int32(1)
|
|
pDb = (*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(i)*32
|
|
for {
|
|
if !(i >= 0) {
|
|
break
|
|
}
|
|
if 0 == Xsqlite3_stricmp(tls, (*TDb)(unsafe.Pointer(pDb)).FzDbSName, zName) {
|
|
break
|
|
}
|
|
/* "main" is always an acceptable alias for the primary database
|
|
** even if it has been renamed using SQLITE_DBCONFIG_MAINDBNAME. */
|
|
if i == 0 && 0 == Xsqlite3_stricmp(tls, __ccgo_ts+6844, zName) {
|
|
break
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i - 1
|
|
pDb -= 32
|
|
}
|
|
}
|
|
return i
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Locate the in-memory structure that describes a particular database
|
|
// ** table given the name of that table and (optionally) the name of the
|
|
// ** database containing the table. Return NULL if not found.
|
|
// **
|
|
// ** If zDatabase is 0, all databases are searched for the table and the
|
|
// ** first matching table is returned. (No checking for duplicate table
|
|
// ** names is done.) The search order is TEMP first, then MAIN, then any
|
|
// ** auxiliary databases added using the ATTACH command.
|
|
// **
|
|
// ** See also sqlite3LocateTable().
|
|
// */
|
|
func _sqlite3FindTable(tls *libc.TLS, db uintptr, zName uintptr, zDatabase uintptr) (r uintptr) {
|
|
var i int32
|
|
var p uintptr
|
|
_, _ = i, p
|
|
p = uintptr(0)
|
|
/* All mutexes are required for schema access. Make sure we hold them. */
|
|
if zDatabase != 0 {
|
|
i = 0
|
|
for {
|
|
if !(i < (*Tsqlite3)(unsafe.Pointer(db)).FnDb) {
|
|
break
|
|
}
|
|
if _sqlite3StrICmp(tls, zDatabase, (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(i)*32))).FzDbSName) == 0 {
|
|
break
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
if i >= (*Tsqlite3)(unsafe.Pointer(db)).FnDb {
|
|
/* No match against the official names. But always match "main"
|
|
** to schema 0 as a legacy fallback. */
|
|
if _sqlite3StrICmp(tls, zDatabase, __ccgo_ts+6844) == 0 {
|
|
i = 0
|
|
} else {
|
|
return uintptr(0)
|
|
}
|
|
}
|
|
p = _sqlite3HashFind(tls, (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(i)*32))).FpSchema+8, zName)
|
|
if p == uintptr(0) && Xsqlite3_strnicmp(tls, zName, __ccgo_ts+6784, int32(7)) == 0 {
|
|
if i == int32(1) {
|
|
if _sqlite3StrICmp(tls, zName+uintptr(7), __ccgo_ts+6811+7) == 0 || _sqlite3StrICmp(tls, zName+uintptr(7), __ccgo_ts+6830+7) == 0 || _sqlite3StrICmp(tls, zName+uintptr(7), __ccgo_ts+6312+7) == 0 {
|
|
p = _sqlite3HashFind(tls, (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + 1*32))).FpSchema+8, __ccgo_ts+6792)
|
|
}
|
|
} else {
|
|
if _sqlite3StrICmp(tls, zName+uintptr(7), __ccgo_ts+6830+7) == 0 {
|
|
p = _sqlite3HashFind(tls, (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(i)*32))).FpSchema+8, __ccgo_ts+6312)
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
/* Match against TEMP first */
|
|
p = _sqlite3HashFind(tls, (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + 1*32))).FpSchema+8, zName)
|
|
if p != 0 {
|
|
return p
|
|
}
|
|
/* The main database is second */
|
|
p = _sqlite3HashFind(tls, (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb))).FpSchema+8, zName)
|
|
if p != 0 {
|
|
return p
|
|
}
|
|
/* Attached databases are in order of attachment */
|
|
i = int32(2)
|
|
for {
|
|
if !(i < (*Tsqlite3)(unsafe.Pointer(db)).FnDb) {
|
|
break
|
|
}
|
|
p = _sqlite3HashFind(tls, (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(i)*32))).FpSchema+8, zName)
|
|
if p != 0 {
|
|
break
|
|
}
|
|
goto _2
|
|
_2:
|
|
;
|
|
i = i + 1
|
|
}
|
|
if p == uintptr(0) && Xsqlite3_strnicmp(tls, zName, __ccgo_ts+6784, int32(7)) == 0 {
|
|
if _sqlite3StrICmp(tls, zName+uintptr(7), __ccgo_ts+6830+7) == 0 {
|
|
p = _sqlite3HashFind(tls, (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb))).FpSchema+8, __ccgo_ts+6312)
|
|
} else {
|
|
if _sqlite3StrICmp(tls, zName+uintptr(7), __ccgo_ts+6811+7) == 0 {
|
|
p = _sqlite3HashFind(tls, (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + 1*32))).FpSchema+8, __ccgo_ts+6792)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return p
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This routine is called after all of the trigger actions have been parsed
|
|
// ** in order to complete the process of building the trigger.
|
|
// */
|
|
func _sqlite3FinishTrigger(tls *libc.TLS, pParse uintptr, pStepList uintptr, pAll uintptr) {
|
|
bp := tls.Alloc(160)
|
|
defer tls.Free(160)
|
|
var db, pHash, pLink, pStep, pTab, pTrig, v, z, zName uintptr
|
|
var iDb int32
|
|
var _ /* nameToken at bp+96 */ TToken
|
|
var _ /* sFix at bp+0 */ TDbFixer
|
|
_, _, _, _, _, _, _, _, _, _ = db, iDb, pHash, pLink, pStep, pTab, pTrig, v, z, zName
|
|
pTrig = (*TParse)(unsafe.Pointer(pParse)).FpNewTrigger /* Name of trigger */
|
|
db = (*TParse)(unsafe.Pointer(pParse)).Fdb /* Trigger name for error reporting */
|
|
(*TParse)(unsafe.Pointer(pParse)).FpNewTrigger = uintptr(0)
|
|
if (*TParse)(unsafe.Pointer(pParse)).FnErr != 0 || !(pTrig != 0) {
|
|
goto triggerfinish_cleanup
|
|
}
|
|
zName = (*TTrigger)(unsafe.Pointer(pTrig)).FzName
|
|
iDb = _sqlite3SchemaToIndex(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, (*TTrigger)(unsafe.Pointer(pTrig)).FpSchema)
|
|
(*TTrigger)(unsafe.Pointer(pTrig)).Fstep_list = pStepList
|
|
for pStepList != 0 {
|
|
(*TTriggerStep)(unsafe.Pointer(pStepList)).FpTrig = pTrig
|
|
pStepList = (*TTriggerStep)(unsafe.Pointer(pStepList)).FpNext
|
|
}
|
|
_sqlite3TokenInit(tls, bp+96, (*TTrigger)(unsafe.Pointer(pTrig)).FzName)
|
|
_sqlite3FixInit(tls, bp, pParse, iDb, __ccgo_ts+21910, bp+96)
|
|
if _sqlite3FixTriggerStep(tls, bp, (*TTrigger)(unsafe.Pointer(pTrig)).Fstep_list) != 0 || _sqlite3FixExpr(tls, bp, (*TTrigger)(unsafe.Pointer(pTrig)).FpWhen) != 0 {
|
|
goto triggerfinish_cleanup
|
|
}
|
|
if libc.Int32FromUint8((*TParse)(unsafe.Pointer(pParse)).FeParseMode) >= int32(PARSE_MODE_RENAME) {
|
|
(*TParse)(unsafe.Pointer(pParse)).FpNewTrigger = pTrig
|
|
pTrig = uintptr(0)
|
|
} else {
|
|
/* if we are not initializing,
|
|
** build the sqlite_schema entry
|
|
*/
|
|
if !((*Tsqlite3)(unsafe.Pointer(db)).Finit1.Fbusy != 0) {
|
|
/* If this is a new CREATE TABLE statement, and if shadow tables
|
|
** are read-only, and the trigger makes a change to a shadow table,
|
|
** then raise an error - do not allow the trigger to be created. */
|
|
if _sqlite3ReadOnlyShadowTables(tls, db) != 0 {
|
|
pStep = (*TTrigger)(unsafe.Pointer(pTrig)).Fstep_list
|
|
for {
|
|
if !(pStep != 0) {
|
|
break
|
|
}
|
|
if (*TTriggerStep)(unsafe.Pointer(pStep)).FpSrc != uintptr(0) && _sqlite3ShadowTableName(tls, db, (*(*TSrcItem)(unsafe.Pointer((*TTriggerStep)(unsafe.Pointer(pStep)).FpSrc + 8))).FzName) != 0 {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+22159, libc.VaList(bp+120, (*TTrigger)(unsafe.Pointer(pTrig)).FzName, (*(*TSrcItem)(unsafe.Pointer((*TTriggerStep)(unsafe.Pointer(pStep)).FpSrc + 8))).FzName))
|
|
goto triggerfinish_cleanup
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
pStep = (*TTriggerStep)(unsafe.Pointer(pStep)).FpNext
|
|
}
|
|
}
|
|
/* Make an entry in the sqlite_schema table */
|
|
v = _sqlite3GetVdbe(tls, pParse)
|
|
if v == uintptr(0) {
|
|
goto triggerfinish_cleanup
|
|
}
|
|
_sqlite3BeginWriteOperation(tls, pParse, 0, iDb)
|
|
z = _sqlite3DbStrNDup(tls, db, (*TToken)(unsafe.Pointer(pAll)).Fz, uint64((*TToken)(unsafe.Pointer(pAll)).Fn))
|
|
_sqlite3NestedParse(tls, pParse, __ccgo_ts+22207, libc.VaList(bp+120, (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(iDb)*32))).FzDbSName, zName, (*TTrigger)(unsafe.Pointer(pTrig)).Ftable, z))
|
|
_sqlite3DbFree(tls, db, z)
|
|
_sqlite3ChangeCookie(tls, pParse, iDb)
|
|
_sqlite3VdbeAddParseSchemaOp(tls, v, iDb, _sqlite3MPrintf(tls, db, __ccgo_ts+22282, libc.VaList(bp+120, zName)), uint16(0))
|
|
}
|
|
}
|
|
if (*Tsqlite3)(unsafe.Pointer(db)).Finit1.Fbusy != 0 {
|
|
pLink = pTrig
|
|
pHash = (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(iDb)*32))).FpSchema + 56
|
|
pTrig = _sqlite3HashInsert(tls, pHash, zName, pTrig)
|
|
if pTrig != 0 {
|
|
_sqlite3OomFault(tls, db)
|
|
} else {
|
|
if (*TTrigger)(unsafe.Pointer(pLink)).FpSchema == (*TTrigger)(unsafe.Pointer(pLink)).FpTabSchema {
|
|
pTab = _sqlite3HashFind(tls, (*TTrigger)(unsafe.Pointer(pLink)).FpTabSchema+8, (*TTrigger)(unsafe.Pointer(pLink)).Ftable)
|
|
(*TTrigger)(unsafe.Pointer(pLink)).FpNext = (*TTable)(unsafe.Pointer(pTab)).FpTrigger
|
|
(*TTable)(unsafe.Pointer(pTab)).FpTrigger = pLink
|
|
}
|
|
}
|
|
}
|
|
goto triggerfinish_cleanup
|
|
triggerfinish_cleanup:
|
|
;
|
|
_sqlite3DeleteTrigger(tls, db, pTrig)
|
|
_sqlite3DeleteTriggerStep(tls, db, pStepList)
|
|
}
|
|
|
|
func _sqlite3Fts5AuxInit(tls *libc.TLS, pApi uintptr) (r int32) {
|
|
var aBuiltin [4]struct {
|
|
FzFunc uintptr
|
|
FpUserData uintptr
|
|
FxFunc Tfts5_extension_function
|
|
FxDestroy uintptr
|
|
}
|
|
var i, rc int32
|
|
_, _, _ = aBuiltin, i, rc
|
|
aBuiltin = [4]struct {
|
|
FzFunc uintptr
|
|
FpUserData uintptr
|
|
FxFunc Tfts5_extension_function
|
|
FxDestroy uintptr
|
|
}{
|
|
0: {
|
|
FzFunc: __ccgo_ts + 37392,
|
|
FxFunc: __ccgo_fp(_fts5SnippetFunction),
|
|
},
|
|
1: {
|
|
FzFunc: __ccgo_ts + 37400,
|
|
FxFunc: __ccgo_fp(_fts5HighlightFunction),
|
|
},
|
|
2: {
|
|
FzFunc: __ccgo_ts + 37410,
|
|
FxFunc: __ccgo_fp(_fts5Bm25Function),
|
|
},
|
|
3: {
|
|
FzFunc: __ccgo_ts + 37415,
|
|
FxFunc: __ccgo_fp(_fts5GetLocaleFunction),
|
|
},
|
|
}
|
|
rc = SQLITE_OK /* To iterate through builtin functions */
|
|
i = 0
|
|
for {
|
|
if !(rc == SQLITE_OK && i < libc.Int32FromUint64(libc.Uint64FromInt64(128)/libc.Uint64FromInt64(32))) {
|
|
break
|
|
}
|
|
rc = (*(*func(*libc.TLS, uintptr, uintptr, uintptr, Tfts5_extension_function, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*Tfts5_api)(unsafe.Pointer(pApi)).FxCreateFunction})))(tls, pApi, aBuiltin[i].FzFunc, aBuiltin[i].FpUserData, aBuiltin[i].FxFunc, aBuiltin[i].FxDestroy)
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
return rc
|
|
}
|
|
|
|
/*
|
|
** 2014 May 31
|
|
**
|
|
** 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.
|
|
**
|
|
******************************************************************************
|
|
*/
|
|
|
|
/* #include "fts5Int.h" */
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Call sqlite3_declare_vtab() based on the contents of the configuration
|
|
// ** object passed as the only argument. Return SQLITE_OK if successful, or
|
|
// ** an SQLite error code if an error occurs.
|
|
// */
|
|
func _sqlite3Fts5ConfigDeclareVtab(tls *libc.TLS, pConfig uintptr) (r int32) {
|
|
bp := tls.Alloc(48)
|
|
defer tls.Free(48)
|
|
var i int32
|
|
var zSep, zSql, v2 uintptr
|
|
var _ /* rc at bp+0 */ int32
|
|
_, _, _, _ = i, zSep, zSql, v2
|
|
**(**int32)(__ccgo_up(bp)) = SQLITE_OK
|
|
zSql = _sqlite3Fts5Mprintf(tls, bp, __ccgo_ts+38329, 0)
|
|
i = 0
|
|
for {
|
|
if !(zSql != 0 && i < (*TFts5Config)(unsafe.Pointer(pConfig)).FnCol) {
|
|
break
|
|
}
|
|
if i == 0 {
|
|
v2 = __ccgo_ts + 1704
|
|
} else {
|
|
v2 = __ccgo_ts + 16242
|
|
}
|
|
zSep = v2
|
|
zSql = _sqlite3Fts5Mprintf(tls, bp, __ccgo_ts+38345, libc.VaList(bp+16, zSql, zSep, **(**uintptr)(__ccgo_up((*TFts5Config)(unsafe.Pointer(pConfig)).FazCol + uintptr(i)*8))))
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
zSql = _sqlite3Fts5Mprintf(tls, bp, __ccgo_ts+38352, libc.VaList(bp+16, zSql, (*TFts5Config)(unsafe.Pointer(pConfig)).FzName, __ccgo_ts+37992))
|
|
if zSql != 0 {
|
|
**(**int32)(__ccgo_up(bp)) = Xsqlite3_declare_vtab(tls, (*TFts5Config)(unsafe.Pointer(pConfig)).Fdb, zSql)
|
|
Xsqlite3_free(tls, zSql)
|
|
}
|
|
return **(**int32)(__ccgo_up(bp))
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Load the contents of the %_config table into memory.
|
|
// */
|
|
func _sqlite3Fts5ConfigLoad(tls *libc.TLS, pConfig uintptr, iCookie int32) (r int32) {
|
|
bp := tls.Alloc(48)
|
|
defer tls.Free(48)
|
|
var iVersion int32
|
|
var pVal, zK, zSelect, zSql uintptr
|
|
var _ /* bDummy at bp+12 */ int32
|
|
var _ /* p at bp+0 */ uintptr
|
|
var _ /* rc at bp+8 */ int32
|
|
_, _, _, _, _ = iVersion, pVal, zK, zSelect, zSql
|
|
zSelect = __ccgo_ts + 38460
|
|
**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
|
|
**(**int32)(__ccgo_up(bp + 8)) = SQLITE_OK
|
|
iVersion = 0
|
|
/* Set default values */
|
|
(*TFts5Config)(unsafe.Pointer(pConfig)).Fpgsz = int32(FTS5_DEFAULT_PAGE_SIZE)
|
|
(*TFts5Config)(unsafe.Pointer(pConfig)).FnAutomerge = int32(FTS5_DEFAULT_AUTOMERGE)
|
|
(*TFts5Config)(unsafe.Pointer(pConfig)).FnUsermerge = int32(FTS5_DEFAULT_USERMERGE)
|
|
(*TFts5Config)(unsafe.Pointer(pConfig)).FnCrisisMerge = int32(FTS5_DEFAULT_CRISISMERGE)
|
|
(*TFts5Config)(unsafe.Pointer(pConfig)).FnHashSize = libc.Int32FromInt32(1024) * libc.Int32FromInt32(1024)
|
|
(*TFts5Config)(unsafe.Pointer(pConfig)).FnDeleteMerge = int32(FTS5_DEFAULT_DELETE_AUTOMERGE)
|
|
zSql = _sqlite3Fts5Mprintf(tls, bp+8, zSelect, libc.VaList(bp+24, (*TFts5Config)(unsafe.Pointer(pConfig)).FzDb, (*TFts5Config)(unsafe.Pointer(pConfig)).FzName))
|
|
if zSql != 0 {
|
|
**(**int32)(__ccgo_up(bp + 8)) = Xsqlite3_prepare_v2(tls, (*TFts5Config)(unsafe.Pointer(pConfig)).Fdb, zSql, -int32(1), bp, uintptr(0))
|
|
Xsqlite3_free(tls, zSql)
|
|
}
|
|
if **(**int32)(__ccgo_up(bp + 8)) == SQLITE_OK {
|
|
for int32(SQLITE_ROW) == Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp))) {
|
|
zK = Xsqlite3_column_text(tls, **(**uintptr)(__ccgo_up(bp)), 0)
|
|
pVal = Xsqlite3_column_value(tls, **(**uintptr)(__ccgo_up(bp)), int32(1))
|
|
if 0 == Xsqlite3_stricmp(tls, zK, __ccgo_ts+38492) {
|
|
iVersion = Xsqlite3_value_int(tls, pVal)
|
|
} else {
|
|
**(**int32)(__ccgo_up(bp + 12)) = 0
|
|
_sqlite3Fts5ConfigSetValue(tls, pConfig, zK, pVal, bp+12)
|
|
}
|
|
}
|
|
**(**int32)(__ccgo_up(bp + 8)) = Xsqlite3_finalize(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
}
|
|
if **(**int32)(__ccgo_up(bp + 8)) == SQLITE_OK && iVersion != int32(FTS5_CURRENT_VERSION) && iVersion != int32(FTS5_CURRENT_VERSION_SECUREDELETE) {
|
|
**(**int32)(__ccgo_up(bp + 8)) = int32(SQLITE_ERROR)
|
|
_sqlite3Fts5ConfigErrmsg(tls, pConfig, __ccgo_ts+38500, libc.VaList(bp+24, iVersion, int32(FTS5_CURRENT_VERSION), int32(FTS5_CURRENT_VERSION_SECUREDELETE)))
|
|
} else {
|
|
(*TFts5Config)(unsafe.Pointer(pConfig)).FiVersion = iVersion
|
|
}
|
|
if **(**int32)(__ccgo_up(bp + 8)) == SQLITE_OK {
|
|
(*TFts5Config)(unsafe.Pointer(pConfig)).FiCookie = iCookie
|
|
}
|
|
return **(**int32)(__ccgo_up(bp + 8))
|
|
}
|
|
|
|
func _sqlite3Fts5ConfigSetValue(tls *libc.TLS, pConfig uintptr, zKey uintptr, pVal uintptr, pbBadkey uintptr) (r int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var bVal, bVal1, nAutomerge, nCrisisMerge, nHashSize, nUsermerge, nVal, pgsz, rc, v1 int32
|
|
var zIn uintptr
|
|
var _ /* zRank at bp+0 */ uintptr
|
|
var _ /* zRankArgs at bp+8 */ uintptr
|
|
_, _, _, _, _, _, _, _, _, _, _ = bVal, bVal1, nAutomerge, nCrisisMerge, nHashSize, nUsermerge, nVal, pgsz, rc, zIn, v1
|
|
rc = SQLITE_OK
|
|
if 0 == Xsqlite3_stricmp(tls, zKey, __ccgo_ts+38378) {
|
|
pgsz = 0
|
|
if int32(SQLITE_INTEGER) == Xsqlite3_value_numeric_type(tls, pVal) {
|
|
pgsz = Xsqlite3_value_int(tls, pVal)
|
|
}
|
|
if pgsz < int32(32) || pgsz > libc.Int32FromInt32(64)*libc.Int32FromInt32(1024) {
|
|
**(**int32)(__ccgo_up(pbBadkey)) = int32(1)
|
|
} else {
|
|
(*TFts5Config)(unsafe.Pointer(pConfig)).Fpgsz = pgsz
|
|
}
|
|
} else {
|
|
if 0 == Xsqlite3_stricmp(tls, zKey, __ccgo_ts+38383) {
|
|
nHashSize = -int32(1)
|
|
if int32(SQLITE_INTEGER) == Xsqlite3_value_numeric_type(tls, pVal) {
|
|
nHashSize = Xsqlite3_value_int(tls, pVal)
|
|
}
|
|
if nHashSize <= 0 {
|
|
**(**int32)(__ccgo_up(pbBadkey)) = int32(1)
|
|
} else {
|
|
(*TFts5Config)(unsafe.Pointer(pConfig)).FnHashSize = nHashSize
|
|
}
|
|
} else {
|
|
if 0 == Xsqlite3_stricmp(tls, zKey, __ccgo_ts+38392) {
|
|
nAutomerge = -int32(1)
|
|
if int32(SQLITE_INTEGER) == Xsqlite3_value_numeric_type(tls, pVal) {
|
|
nAutomerge = Xsqlite3_value_int(tls, pVal)
|
|
}
|
|
if nAutomerge < 0 || nAutomerge > int32(64) {
|
|
**(**int32)(__ccgo_up(pbBadkey)) = int32(1)
|
|
} else {
|
|
if nAutomerge == int32(1) {
|
|
nAutomerge = int32(FTS5_DEFAULT_AUTOMERGE)
|
|
}
|
|
(*TFts5Config)(unsafe.Pointer(pConfig)).FnAutomerge = nAutomerge
|
|
}
|
|
} else {
|
|
if 0 == Xsqlite3_stricmp(tls, zKey, __ccgo_ts+38402) {
|
|
nUsermerge = -int32(1)
|
|
if int32(SQLITE_INTEGER) == Xsqlite3_value_numeric_type(tls, pVal) {
|
|
nUsermerge = Xsqlite3_value_int(tls, pVal)
|
|
}
|
|
if nUsermerge < int32(2) || nUsermerge > int32(16) {
|
|
**(**int32)(__ccgo_up(pbBadkey)) = int32(1)
|
|
} else {
|
|
(*TFts5Config)(unsafe.Pointer(pConfig)).FnUsermerge = nUsermerge
|
|
}
|
|
} else {
|
|
if 0 == Xsqlite3_stricmp(tls, zKey, __ccgo_ts+38412) {
|
|
nCrisisMerge = -int32(1)
|
|
if int32(SQLITE_INTEGER) == Xsqlite3_value_numeric_type(tls, pVal) {
|
|
nCrisisMerge = Xsqlite3_value_int(tls, pVal)
|
|
}
|
|
if nCrisisMerge < 0 {
|
|
**(**int32)(__ccgo_up(pbBadkey)) = int32(1)
|
|
} else {
|
|
if nCrisisMerge <= int32(1) {
|
|
nCrisisMerge = int32(FTS5_DEFAULT_CRISISMERGE)
|
|
}
|
|
if nCrisisMerge >= int32(FTS5_MAX_SEGMENT) {
|
|
nCrisisMerge = libc.Int32FromInt32(FTS5_MAX_SEGMENT) - libc.Int32FromInt32(1)
|
|
}
|
|
(*TFts5Config)(unsafe.Pointer(pConfig)).FnCrisisMerge = nCrisisMerge
|
|
}
|
|
} else {
|
|
if 0 == Xsqlite3_stricmp(tls, zKey, __ccgo_ts+38424) {
|
|
nVal = -int32(1)
|
|
if int32(SQLITE_INTEGER) == Xsqlite3_value_numeric_type(tls, pVal) {
|
|
nVal = Xsqlite3_value_int(tls, pVal)
|
|
} else {
|
|
**(**int32)(__ccgo_up(pbBadkey)) = int32(1)
|
|
}
|
|
if nVal < 0 {
|
|
nVal = int32(FTS5_DEFAULT_DELETE_AUTOMERGE)
|
|
}
|
|
if nVal > int32(100) {
|
|
nVal = 0
|
|
}
|
|
(*TFts5Config)(unsafe.Pointer(pConfig)).FnDeleteMerge = nVal
|
|
} else {
|
|
if 0 == Xsqlite3_stricmp(tls, zKey, __ccgo_ts+37992) {
|
|
zIn = Xsqlite3_value_text(tls, pVal)
|
|
rc = _sqlite3Fts5ConfigParseRank(tls, zIn, bp, bp+8)
|
|
if rc == SQLITE_OK {
|
|
Xsqlite3_free(tls, (*TFts5Config)(unsafe.Pointer(pConfig)).FzRank)
|
|
Xsqlite3_free(tls, (*TFts5Config)(unsafe.Pointer(pConfig)).FzRankArgs)
|
|
(*TFts5Config)(unsafe.Pointer(pConfig)).FzRank = **(**uintptr)(__ccgo_up(bp))
|
|
(*TFts5Config)(unsafe.Pointer(pConfig)).FzRankArgs = **(**uintptr)(__ccgo_up(bp + 8))
|
|
} else {
|
|
if rc == int32(SQLITE_ERROR) {
|
|
rc = SQLITE_OK
|
|
**(**int32)(__ccgo_up(pbBadkey)) = int32(1)
|
|
}
|
|
}
|
|
} else {
|
|
if 0 == Xsqlite3_stricmp(tls, zKey, __ccgo_ts+38436) {
|
|
bVal = -int32(1)
|
|
if int32(SQLITE_INTEGER) == Xsqlite3_value_numeric_type(tls, pVal) {
|
|
bVal = Xsqlite3_value_int(tls, pVal)
|
|
}
|
|
if bVal < 0 {
|
|
**(**int32)(__ccgo_up(pbBadkey)) = int32(1)
|
|
} else {
|
|
if bVal != 0 {
|
|
v1 = int32(1)
|
|
} else {
|
|
v1 = 0
|
|
}
|
|
(*TFts5Config)(unsafe.Pointer(pConfig)).FbSecureDelete = v1
|
|
}
|
|
} else {
|
|
if 0 == Xsqlite3_stricmp(tls, zKey, __ccgo_ts+38450) {
|
|
bVal1 = -int32(1)
|
|
if int32(SQLITE_INTEGER) == Xsqlite3_value_numeric_type(tls, pVal) {
|
|
bVal1 = Xsqlite3_value_int(tls, pVal)
|
|
}
|
|
if bVal1 < 0 {
|
|
**(**int32)(__ccgo_up(pbBadkey)) = int32(1)
|
|
} else {
|
|
if bVal1 != 0 {
|
|
v1 = int32(1)
|
|
} else {
|
|
v1 = 0
|
|
}
|
|
(*TFts5Config)(unsafe.Pointer(pConfig)).FbPrefixInsttoken = v1
|
|
}
|
|
} else {
|
|
**(**int32)(__ccgo_up(pbBadkey)) = int32(1)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Run internal checks to ensure that the FTS index (a) is internally
|
|
// ** consistent and (b) contains entries for which the XOR of the checksums
|
|
// ** as calculated by sqlite3Fts5IndexEntryCksum() is cksum.
|
|
// **
|
|
// ** Return SQLITE_CORRUPT if any of the internal checks fail, or if the
|
|
// ** checksum does not match. Return SQLITE_OK if all checks pass without
|
|
// ** error, or some other SQLite error code if another error (e.g. OOM)
|
|
// ** occurs.
|
|
// */
|
|
func _sqlite3Fts5IndexIntegrityCheck(tls *libc.TLS, p uintptr, cksum Tu64, bUseCksum int32) (r int32) {
|
|
bp := tls.Alloc(64)
|
|
defer tls.Free(64)
|
|
var cksum2 Tu64
|
|
var eDetail, flags, iCol, iLvl, iSeg, iTokOff int32
|
|
var iRowid Ti64
|
|
var pSeg, pStruct, z uintptr
|
|
var _ /* iOff at bp+40 */ int32
|
|
var _ /* iPos at bp+32 */ Ti64
|
|
var _ /* n at bp+24 */ int32
|
|
var _ /* pIter at bp+16 */ uintptr
|
|
var _ /* poslist at bp+0 */ TFts5Buffer
|
|
_, _, _, _, _, _, _, _, _, _, _ = cksum2, eDetail, flags, iCol, iLvl, iRowid, iSeg, iTokOff, pSeg, pStruct, z
|
|
eDetail = (*TFts5Config)(unsafe.Pointer((*TFts5Index)(unsafe.Pointer(p)).FpConfig)).FeDetail
|
|
cksum2 = uint64(0) /* Checksum based on contents of indexes */
|
|
**(**TFts5Buffer)(__ccgo_up(bp)) = TFts5Buffer{}
|
|
flags = int32(FTS5INDEX_QUERY_NOOUTPUT)
|
|
/* Load the FTS index structure */
|
|
pStruct = _fts5StructureRead(tls, p)
|
|
if pStruct == uintptr(0) {
|
|
return _fts5IndexReturn(tls, p)
|
|
}
|
|
/* Check that the internal nodes of each segment match the leaves */
|
|
iLvl = 0
|
|
for {
|
|
if !(iLvl < (*TFts5Structure)(unsafe.Pointer(pStruct)).FnLevel) {
|
|
break
|
|
}
|
|
iSeg = 0
|
|
for {
|
|
if !(iSeg < (*(*TFts5StructureLevel)(unsafe.Pointer(pStruct + 32 + uintptr(iLvl)*16))).FnSeg) {
|
|
break
|
|
}
|
|
pSeg = (*(*TFts5StructureLevel)(unsafe.Pointer(pStruct + 32 + uintptr(iLvl)*16))).FaSeg + uintptr(iSeg)*56
|
|
_fts5IndexIntegrityCheckSegment(tls, p, pSeg)
|
|
goto _2
|
|
_2:
|
|
;
|
|
iSeg = iSeg + 1
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
iLvl = iLvl + 1
|
|
}
|
|
/* The cksum argument passed to this function is a checksum calculated
|
|
** based on all expected entries in the FTS index (including prefix index
|
|
** entries). This block checks that a checksum calculated based on the
|
|
** actual contents of FTS index is identical.
|
|
**
|
|
** Two versions of the same checksum are calculated. The first (stack
|
|
** variable cksum2) based on entries extracted from the full-text index
|
|
** while doing a linear scan of each individual index in turn.
|
|
**
|
|
** As each term visited by the linear scans, a separate query for the
|
|
** same term is performed. cksum3 is calculated based on the entries
|
|
** extracted by these queries.
|
|
*/
|
|
_fts5MultiIterNew(tls, p, pStruct, flags, uintptr(0), uintptr(0), 0, -int32(1), 0, bp+16)
|
|
for {
|
|
if !(_fts5MultiIterEof(tls, p, **(**uintptr)(__ccgo_up(bp + 16))) == 0) {
|
|
break
|
|
} /* Size of term in bytes */
|
|
**(**Ti64)(__ccgo_up(bp + 32)) = 0 /* Position read from poslist */
|
|
**(**int32)(__ccgo_up(bp + 40)) = 0 /* Offset within poslist */
|
|
iRowid = _fts5MultiIterRowid(tls, **(**uintptr)(__ccgo_up(bp + 16)))
|
|
z = _fts5MultiIterTerm(tls, **(**uintptr)(__ccgo_up(bp + 16)), bp+24)
|
|
/* If this is a new term, query for it. Update cksum3 with the results. */
|
|
if (*TFts5Index)(unsafe.Pointer(p)).Frc != 0 {
|
|
break
|
|
}
|
|
if eDetail == int32(FTS5_DETAIL_NONE) {
|
|
if 0 == _fts5MultiIterIsEmpty(tls, p, **(**uintptr)(__ccgo_up(bp + 16))) {
|
|
cksum2 = cksum2 ^ _sqlite3Fts5IndexEntryCksum(tls, iRowid, 0, 0, -int32(1), z, **(**int32)(__ccgo_up(bp + 24)))
|
|
}
|
|
} else {
|
|
(**(**TFts5Buffer)(__ccgo_up(bp))).Fn = 0
|
|
_fts5SegiterPoslist(tls, p, **(**uintptr)(__ccgo_up(bp + 16))+104+uintptr((**(**TFts5CResult)(__ccgo_up((*TFts5Iter)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 16)))).FaFirst + 1*4))).FiFirst)*128, uintptr(0), bp)
|
|
_sqlite3Fts5BufferAppendBlob(tls, p+60, bp, uint32(4), __ccgo_ts+39696)
|
|
for 0 == _sqlite3Fts5PoslistNext64(tls, (**(**TFts5Buffer)(__ccgo_up(bp))).Fp, (**(**TFts5Buffer)(__ccgo_up(bp))).Fn, bp+40, bp+32) {
|
|
iCol = int32(**(**Ti64)(__ccgo_up(bp + 32)) >> libc.Int32FromInt32(32) & libc.Int64FromInt32(0x7FFFFFFF))
|
|
iTokOff = int32(**(**Ti64)(__ccgo_up(bp + 32)) & libc.Int64FromInt32(0x7FFFFFFF))
|
|
cksum2 = cksum2 ^ _sqlite3Fts5IndexEntryCksum(tls, iRowid, iCol, iTokOff, -int32(1), z, **(**int32)(__ccgo_up(bp + 24)))
|
|
}
|
|
}
|
|
goto _3
|
|
_3:
|
|
;
|
|
_fts5MultiIterNext(tls, p, **(**uintptr)(__ccgo_up(bp + 16)), 0, 0)
|
|
}
|
|
_fts5MultiIterFree(tls, **(**uintptr)(__ccgo_up(bp + 16)))
|
|
if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK && bUseCksum != 0 && cksum != cksum2 {
|
|
(*TFts5Index)(unsafe.Pointer(p)).Frc = libc.Int32FromInt32(SQLITE_CORRUPT) | libc.Int32FromInt32(1)<<libc.Int32FromInt32(8)
|
|
_sqlite3Fts5ConfigErrmsg(tls, (*TFts5Index)(unsafe.Pointer(p)).FpConfig, __ccgo_ts+39701, libc.VaList(bp+56, (*TFts5Config)(unsafe.Pointer((*TFts5Index)(unsafe.Pointer(p)).FpConfig)).FzName))
|
|
}
|
|
_fts5StructureRelease(tls, pStruct)
|
|
_sqlite3Fts5BufferFree(tls, bp)
|
|
return _fts5IndexReturn(tls, p)
|
|
}
|
|
|
|
/*************************************************************************
|
|
**************************************************************************
|
|
** Below this point is the implementation of the fts5_decode() scalar
|
|
** function only.
|
|
*/
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Open a new Fts5Index handle. If the bCreate argument is true, create
|
|
// ** and initialize the underlying %_data table.
|
|
// **
|
|
// ** If successful, set *pp to point to the new object and return SQLITE_OK.
|
|
// ** Otherwise, set *pp to NULL and return an SQLite error code.
|
|
// */
|
|
func _sqlite3Fts5IndexOpen(tls *libc.TLS, pConfig uintptr, bCreate int32, pp uintptr, pzErr uintptr) (r int32) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var p, v1 uintptr
|
|
var _ /* rc at bp+0 */ int32
|
|
_, _ = p, v1
|
|
**(**int32)(__ccgo_up(bp)) = SQLITE_OK /* New object */
|
|
v1 = _sqlite3Fts5MallocZero(tls, bp, int64(168))
|
|
p = v1
|
|
**(**uintptr)(__ccgo_up(pp)) = v1
|
|
if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
|
|
(*TFts5Index)(unsafe.Pointer(p)).FpConfig = pConfig
|
|
(*TFts5Index)(unsafe.Pointer(p)).FnWorkUnit = int32(FTS5_WORK_UNIT)
|
|
(*TFts5Index)(unsafe.Pointer(p)).FzDataTbl = _sqlite3Fts5Mprintf(tls, bp, __ccgo_ts+39521, libc.VaList(bp+16, (*TFts5Config)(unsafe.Pointer(pConfig)).FzName))
|
|
if (*TFts5Index)(unsafe.Pointer(p)).FzDataTbl != 0 && bCreate != 0 {
|
|
**(**int32)(__ccgo_up(bp)) = _sqlite3Fts5CreateTable(tls, pConfig, __ccgo_ts+27432, __ccgo_ts+39529, 0, pzErr)
|
|
if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
|
|
**(**int32)(__ccgo_up(bp)) = _sqlite3Fts5CreateTable(tls, pConfig, __ccgo_ts+13072, __ccgo_ts+39564, int32(1), pzErr)
|
|
}
|
|
if **(**int32)(__ccgo_up(bp)) == SQLITE_OK {
|
|
**(**int32)(__ccgo_up(bp)) = _sqlite3Fts5IndexReinit(tls, p)
|
|
}
|
|
}
|
|
}
|
|
if **(**int32)(__ccgo_up(bp)) != 0 {
|
|
_sqlite3Fts5IndexClose(tls, p)
|
|
**(**uintptr)(__ccgo_up(pp)) = uintptr(0)
|
|
}
|
|
return **(**int32)(__ccgo_up(bp))
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** The %_data table is completely empty when this function is called. This
|
|
// ** function populates it with the initial structure objects for each index,
|
|
// ** and the initial version of the "averages" record (a zero-byte blob).
|
|
// */
|
|
func _sqlite3Fts5IndexReinit(tls *libc.TLS, p uintptr) (r int32) {
|
|
bp := tls.Alloc(48)
|
|
defer tls.Free(48)
|
|
var pTmp uintptr
|
|
var _ /* uFts at bp+0 */ struct {
|
|
FtmpSpace [0][48]Tu8
|
|
FsFts TFts5Structure
|
|
F__ccgo_pad2 [16]byte
|
|
}
|
|
_ = pTmp
|
|
_fts5StructureInvalidate(tls, p)
|
|
_fts5IndexDiscardData(tls, p)
|
|
pTmp = bp
|
|
libc.Xmemset(tls, bp, 0, uint64(48))
|
|
if (*TFts5Config)(unsafe.Pointer((*TFts5Index)(unsafe.Pointer(p)).FpConfig)).FbContentlessDelete != 0 {
|
|
(*TFts5Structure)(unsafe.Pointer(pTmp)).FnOriginCntr = uint64(1)
|
|
}
|
|
_fts5DataWrite(tls, p, int64(FTS5_AVERAGES_ROWID), __ccgo_ts+1704, 0)
|
|
_fts5StructureWrite(tls, p, pTmp)
|
|
return _fts5IndexReturn(tls, p)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Set the 32-bit cookie value stored at the start of all structure
|
|
// ** records to the value passed as the second argument.
|
|
// **
|
|
// ** Return SQLITE_OK if successful, or an SQLite error code if an error
|
|
// ** occurs.
|
|
// */
|
|
func _sqlite3Fts5IndexSetCookie(tls *libc.TLS, p uintptr, iNew int32) (r int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var pConfig uintptr
|
|
var rc int32
|
|
var _ /* aCookie at bp+0 */ [4]Tu8
|
|
var _ /* pBlob at bp+8 */ uintptr
|
|
_, _ = pConfig, rc /* Return code */
|
|
pConfig = (*TFts5Index)(unsafe.Pointer(p)).FpConfig /* Binary representation of iNew */
|
|
**(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0)
|
|
_sqlite3Fts5Put32(tls, bp, iNew)
|
|
rc = Xsqlite3_blob_open(tls, (*TFts5Config)(unsafe.Pointer(pConfig)).Fdb, (*TFts5Config)(unsafe.Pointer(pConfig)).FzDb, (*TFts5Index)(unsafe.Pointer(p)).FzDataTbl, __ccgo_ts+38966, int64(FTS5_STRUCTURE_ROWID), int32(1), bp+8)
|
|
if rc == SQLITE_OK {
|
|
Xsqlite3_blob_write(tls, **(**uintptr)(__ccgo_up(bp + 8)), bp, int32(4), 0)
|
|
rc = Xsqlite3_blob_close(tls, **(**uintptr)(__ccgo_up(bp + 8)))
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Attempt to instantiate the tokenizer.
|
|
// */
|
|
func _sqlite3Fts5LoadTokenizer(tls *libc.TLS, pConfig uintptr) (r int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var azArg, pMod, xCreate, v1 uintptr
|
|
var nArg, rc, v3 int32
|
|
_, _, _, _, _, _, _ = azArg, nArg, pMod, rc, xCreate, v1, v3
|
|
azArg = (*TFts5Config)(unsafe.Pointer(pConfig)).Ft.FazArg
|
|
nArg = (*TFts5Config)(unsafe.Pointer(pConfig)).Ft.FnArg
|
|
pMod = uintptr(0)
|
|
rc = SQLITE_OK
|
|
if nArg == 0 {
|
|
v1 = uintptr(0)
|
|
} else {
|
|
v1 = **(**uintptr)(__ccgo_up(azArg))
|
|
}
|
|
pMod = _fts5LocateTokenizer(tls, (*TFts5Config)(unsafe.Pointer(pConfig)).FpGlobal, v1)
|
|
if pMod == uintptr(0) {
|
|
rc = int32(SQLITE_ERROR)
|
|
_sqlite3Fts5ConfigErrmsg(tls, pConfig, __ccgo_ts+40467, libc.VaList(bp+8, **(**uintptr)(__ccgo_up(azArg))))
|
|
} else {
|
|
xCreate = uintptr(0)
|
|
if (*TFts5TokenizerModule)(unsafe.Pointer(pMod)).FbV2Native != 0 {
|
|
xCreate = (*TFts5TokenizerModule)(unsafe.Pointer(pMod)).Fx2.FxCreate
|
|
(*TFts5Config)(unsafe.Pointer(pConfig)).Ft.FpApi2 = pMod + 48
|
|
} else {
|
|
(*TFts5Config)(unsafe.Pointer(pConfig)).Ft.FpApi1 = pMod + 24
|
|
xCreate = (*TFts5TokenizerModule)(unsafe.Pointer(pMod)).Fx1.FxCreate
|
|
}
|
|
if azArg != 0 {
|
|
v1 = azArg + 1*8
|
|
} else {
|
|
v1 = uintptr(0)
|
|
}
|
|
if nArg != 0 {
|
|
v3 = nArg - int32(1)
|
|
} else {
|
|
v3 = 0
|
|
}
|
|
rc = (*(*func(*libc.TLS, uintptr, uintptr, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{xCreate})))(tls, (*TFts5TokenizerModule)(unsafe.Pointer(pMod)).FpUserData, v1, v3, pConfig+128)
|
|
if rc != SQLITE_OK {
|
|
if rc != int32(SQLITE_NOMEM) {
|
|
_sqlite3Fts5ConfigErrmsg(tls, pConfig, __ccgo_ts+40489, 0)
|
|
}
|
|
} else {
|
|
if (*TFts5TokenizerModule)(unsafe.Pointer(pMod)).FbV2Native == 0 {
|
|
(*TFts5Config)(unsafe.Pointer(pConfig)).Ft.FePattern = _sqlite3Fts5TokenizerPattern(tls, (*TFts5TokenizerModule)(unsafe.Pointer(pMod)).Fx1.FxCreate, (*TFts5Config)(unsafe.Pointer(pConfig)).Ft.FpTok)
|
|
}
|
|
}
|
|
}
|
|
if rc != SQLITE_OK {
|
|
(*TFts5Config)(unsafe.Pointer(pConfig)).Ft.FpApi1 = uintptr(0)
|
|
(*TFts5Config)(unsafe.Pointer(pConfig)).Ft.FpApi2 = uintptr(0)
|
|
(*TFts5Config)(unsafe.Pointer(pConfig)).Ft.FpTok = uintptr(0)
|
|
}
|
|
return rc
|
|
}
|
|
|
|
func _sqlite3Fts5ParseColset(tls *libc.TLS, pParse uintptr, pColset uintptr, p uintptr) (r uintptr) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var iCol int32
|
|
var pConfig, pRet, z uintptr
|
|
_, _, _, _ = iCol, pConfig, pRet, z
|
|
pRet = uintptr(0) /* Dequoted copy of token p */
|
|
z = _sqlite3Fts5Strndup(tls, pParse+16, (*TFts5Token)(unsafe.Pointer(p)).Fp, (*TFts5Token)(unsafe.Pointer(p)).Fn)
|
|
if (*TFts5Parse)(unsafe.Pointer(pParse)).Frc == SQLITE_OK {
|
|
pConfig = (*TFts5Parse)(unsafe.Pointer(pParse)).FpConfig
|
|
_sqlite3Fts5Dequote(tls, z)
|
|
iCol = 0
|
|
for {
|
|
if !(iCol < (*TFts5Config)(unsafe.Pointer(pConfig)).FnCol) {
|
|
break
|
|
}
|
|
if 0 == Xsqlite3_stricmp(tls, **(**uintptr)(__ccgo_up((*TFts5Config)(unsafe.Pointer(pConfig)).FazCol + uintptr(iCol)*8)), z) {
|
|
break
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
iCol = iCol + 1
|
|
}
|
|
if iCol == (*TFts5Config)(unsafe.Pointer(pConfig)).FnCol {
|
|
_sqlite3Fts5ParseError(tls, pParse, __ccgo_ts+11934, libc.VaList(bp+8, z))
|
|
} else {
|
|
pRet = _fts5ParseColset(tls, pParse, pColset, iCol)
|
|
}
|
|
Xsqlite3_free(tls, z)
|
|
}
|
|
if pRet == uintptr(0) {
|
|
Xsqlite3_free(tls, pColset)
|
|
}
|
|
return pRet
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Token pTok has appeared in a MATCH expression where the NEAR operator
|
|
// ** is expected. If token pTok does not contain "NEAR", store an error
|
|
// ** in the pParse object.
|
|
// */
|
|
func _sqlite3Fts5ParseNear(tls *libc.TLS, pParse uintptr, pTok uintptr) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
if (*TFts5Token)(unsafe.Pointer(pTok)).Fn != int32(4) || libc.Xmemcmp(tls, __ccgo_ts+38629, (*TFts5Token)(unsafe.Pointer(pTok)).Fp, uint64(4)) != 0 {
|
|
_sqlite3Fts5ParseError(tls, pParse, __ccgo_ts+37142, libc.VaList(bp+8, (*TFts5Token)(unsafe.Pointer(pTok)).Fn, (*TFts5Token)(unsafe.Pointer(pTok)).Fp))
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Allocate and return a new expression object. If anything goes wrong (i.e.
|
|
// ** OOM error), leave an error code in pParse and return NULL.
|
|
// */
|
|
func _sqlite3Fts5ParseNode(tls *libc.TLS, pParse uintptr, eType int32, pLeft uintptr, pRight uintptr, pNear uintptr) (r uintptr) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var iPhrase, nChild int32
|
|
var nByte Tsqlite3_int64
|
|
var pPhrase, pRet, v2 uintptr
|
|
_, _, _, _, _, _ = iPhrase, nByte, nChild, pPhrase, pRet, v2
|
|
pRet = uintptr(0)
|
|
if (*TFts5Parse)(unsafe.Pointer(pParse)).Frc == SQLITE_OK {
|
|
nChild = 0 /* Bytes of space to allocate for this node */
|
|
if eType == int32(FTS5_STRING) && pNear == uintptr(0) {
|
|
return uintptr(0)
|
|
}
|
|
if eType != int32(FTS5_STRING) && pLeft == uintptr(0) {
|
|
return pRight
|
|
}
|
|
if eType != int32(FTS5_STRING) && pRight == uintptr(0) {
|
|
return pLeft
|
|
}
|
|
if eType == int32(FTS5_STRING) && (*TFts5Parse)(unsafe.Pointer(pParse)).FbPhraseToAnd != 0 && (*TFts5ExprPhrase)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pNear + 24)))).FnTerm > int32(1) {
|
|
pRet = _fts5ParsePhraseToAnd(tls, pParse, pNear)
|
|
} else {
|
|
if eType == int32(FTS5_NOT) {
|
|
nChild = int32(2)
|
|
} else {
|
|
if eType == int32(FTS5_AND) || eType == int32(FTS5_OR) {
|
|
nChild = int32(2)
|
|
if (*TFts5ExprNode)(unsafe.Pointer(pLeft)).FeType == eType {
|
|
nChild = nChild + ((*TFts5ExprNode)(unsafe.Pointer(pLeft)).FnChild - int32(1))
|
|
}
|
|
if (*TFts5ExprNode)(unsafe.Pointer(pRight)).FeType == eType {
|
|
nChild = nChild + ((*TFts5ExprNode)(unsafe.Pointer(pRight)).FnChild - int32(1))
|
|
}
|
|
}
|
|
}
|
|
nByte = libc.Int64FromUint64(uint64(libc.UintptrFromInt32(0)+48) + libc.Uint64FromInt32(nChild)*libc.Uint64FromInt64(8))
|
|
pRet = _sqlite3Fts5MallocZero(tls, pParse+16, nByte)
|
|
if pRet != 0 {
|
|
(*TFts5ExprNode)(unsafe.Pointer(pRet)).FeType = eType
|
|
(*TFts5ExprNode)(unsafe.Pointer(pRet)).FpNear = pNear
|
|
_fts5ExprAssignXNext(tls, pRet)
|
|
if eType == int32(FTS5_STRING) {
|
|
iPhrase = 0
|
|
for {
|
|
if !(iPhrase < (*TFts5ExprNearset)(unsafe.Pointer(pNear)).FnPhrase) {
|
|
break
|
|
}
|
|
(*TFts5ExprPhrase)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pNear + 24 + uintptr(iPhrase)*8)))).FpNode = pRet
|
|
if (*TFts5ExprPhrase)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pNear + 24 + uintptr(iPhrase)*8)))).FnTerm == 0 {
|
|
(*TFts5ExprNode)(unsafe.Pointer(pRet)).FxNext = uintptr(0)
|
|
(*TFts5ExprNode)(unsafe.Pointer(pRet)).FeType = FTS5_EOF
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
iPhrase = iPhrase + 1
|
|
}
|
|
if (*TFts5Config)(unsafe.Pointer((*TFts5Parse)(unsafe.Pointer(pParse)).FpConfig)).FeDetail != FTS5_DETAIL_FULL {
|
|
pPhrase = *(*uintptr)(unsafe.Pointer(pNear + 24))
|
|
if (*TFts5ExprNearset)(unsafe.Pointer(pNear)).FnPhrase != int32(1) || (*TFts5ExprPhrase)(unsafe.Pointer(pPhrase)).FnTerm > int32(1) || (*TFts5ExprPhrase)(unsafe.Pointer(pPhrase)).FnTerm > 0 && (*(*TFts5ExprTerm)(unsafe.Pointer(pPhrase + 32))).FbFirst != 0 {
|
|
if (*TFts5ExprNearset)(unsafe.Pointer(pNear)).FnPhrase == int32(1) {
|
|
v2 = __ccgo_ts + 38716
|
|
} else {
|
|
v2 = __ccgo_ts + 38629
|
|
}
|
|
_sqlite3Fts5ParseError(tls, pParse, __ccgo_ts+38723, libc.VaList(bp+8, v2))
|
|
_sqlite3Fts5ParseNodeFree(tls, pRet)
|
|
pRet = uintptr(0)
|
|
pNear = uintptr(0)
|
|
}
|
|
}
|
|
} else {
|
|
_fts5ExprAddChildren(tls, pRet, pLeft)
|
|
_fts5ExprAddChildren(tls, pRet, pRight)
|
|
v2 = libc.UintptrFromInt32(0)
|
|
pRight = v2
|
|
pLeft = v2
|
|
if (*TFts5ExprNode)(unsafe.Pointer(pRet)).FiHeight > int32(SQLITE_FTS5_MAX_EXPR_DEPTH) {
|
|
_sqlite3Fts5ParseError(tls, pParse, __ccgo_ts+38773, libc.VaList(bp+8, int32(SQLITE_FTS5_MAX_EXPR_DEPTH)))
|
|
_sqlite3Fts5ParseNodeFree(tls, pRet)
|
|
pRet = uintptr(0)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if pRet == uintptr(0) {
|
|
_sqlite3Fts5ParseNodeFree(tls, pLeft)
|
|
_sqlite3Fts5ParseNodeFree(tls, pRight)
|
|
_sqlite3Fts5ParseNearsetFree(tls, pNear)
|
|
}
|
|
return pRet
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Check that the contents of the FTS index match that of the %_content
|
|
// ** table. Return SQLITE_OK if they do, or SQLITE_CORRUPT if not. Return
|
|
// ** some other SQLite error code if an error occurs while attempting to
|
|
// ** determine this.
|
|
// */
|
|
func _sqlite3Fts5StorageIntegrity(tls *libc.TLS, p uintptr, iArg int32) (r int32) {
|
|
bp := tls.Alloc(96)
|
|
defer tls.Free(96)
|
|
var aColSize, aTotalSize, pConfig, pVal uintptr
|
|
var bUseCksum, i, i1, iCol, rc, rc2 int32
|
|
var _ /* ctx at bp+0 */ TFts5IntegrityCtx
|
|
var _ /* nLoc at bp+72 */ int32
|
|
var _ /* nRow at bp+80 */ Ti64
|
|
var _ /* nRow at bp+88 */ Ti64
|
|
var _ /* nText at bp+56 */ int32
|
|
var _ /* pLoc at bp+64 */ uintptr
|
|
var _ /* pScan at bp+40 */ uintptr
|
|
var _ /* pText at bp+48 */ uintptr
|
|
_, _, _, _, _, _, _, _, _, _ = aColSize, aTotalSize, bUseCksum, i, i1, iCol, pConfig, pVal, rc, rc2
|
|
pConfig = (*TFts5Storage)(unsafe.Pointer(p)).FpConfig
|
|
rc = SQLITE_OK
|
|
libc.Xmemset(tls, bp, 0, uint64(40))
|
|
(**(**TFts5IntegrityCtx)(__ccgo_up(bp))).FpConfig = (*TFts5Storage)(unsafe.Pointer(p)).FpConfig
|
|
aTotalSize = Xsqlite3_malloc64(tls, uint64(libc.Uint64FromInt32((*TFts5Config)(unsafe.Pointer(pConfig)).FnCol)*(libc.Uint64FromInt64(4)+libc.Uint64FromInt64(8))))
|
|
if !(aTotalSize != 0) {
|
|
return int32(SQLITE_NOMEM)
|
|
}
|
|
aColSize = aTotalSize + uintptr((*TFts5Config)(unsafe.Pointer(pConfig)).FnCol)*8
|
|
libc.Xmemset(tls, aTotalSize, 0, uint64(8)*libc.Uint64FromInt32((*TFts5Config)(unsafe.Pointer(pConfig)).FnCol))
|
|
bUseCksum = libc.BoolInt32((*TFts5Config)(unsafe.Pointer(pConfig)).FeContent == FTS5_CONTENT_NORMAL || (*TFts5Config)(unsafe.Pointer(pConfig)).FeContent == int32(FTS5_CONTENT_EXTERNAL) && iArg != 0)
|
|
if bUseCksum != 0 {
|
|
/* Generate the expected index checksum based on the contents of the
|
|
** %_content table. This block stores the checksum in ctx.cksum. */
|
|
rc = _fts5StorageGetStmt(tls, p, int32(FTS5_STMT_SCAN), bp+40, uintptr(0))
|
|
if rc == SQLITE_OK {
|
|
for int32(SQLITE_ROW) == Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp + 40))) {
|
|
(**(**TFts5IntegrityCtx)(__ccgo_up(bp))).FiRowid = Xsqlite3_column_int64(tls, **(**uintptr)(__ccgo_up(bp + 40)), 0)
|
|
(**(**TFts5IntegrityCtx)(__ccgo_up(bp))).FszCol = 0
|
|
if (*TFts5Config)(unsafe.Pointer(pConfig)).FbColumnsize != 0 {
|
|
rc = _sqlite3Fts5StorageDocsize(tls, p, (**(**TFts5IntegrityCtx)(__ccgo_up(bp))).FiRowid, aColSize)
|
|
}
|
|
if rc == SQLITE_OK && (*TFts5Config)(unsafe.Pointer(pConfig)).FeDetail == int32(FTS5_DETAIL_NONE) {
|
|
rc = _sqlite3Fts5TermsetNew(tls, bp+24)
|
|
}
|
|
i = 0
|
|
for {
|
|
if !(rc == SQLITE_OK && i < (*TFts5Config)(unsafe.Pointer(pConfig)).FnCol) {
|
|
break
|
|
}
|
|
if libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TFts5Config)(unsafe.Pointer(pConfig)).FabUnindexed + uintptr(i)))) == 0 {
|
|
**(**uintptr)(__ccgo_up(bp + 48)) = uintptr(0)
|
|
**(**int32)(__ccgo_up(bp + 56)) = 0
|
|
**(**uintptr)(__ccgo_up(bp + 64)) = uintptr(0)
|
|
**(**int32)(__ccgo_up(bp + 72)) = 0
|
|
pVal = Xsqlite3_column_value(tls, **(**uintptr)(__ccgo_up(bp + 40)), i+int32(1))
|
|
if (*TFts5Config)(unsafe.Pointer(pConfig)).FeContent == int32(FTS5_CONTENT_EXTERNAL) && _sqlite3Fts5IsLocaleValue(tls, pConfig, pVal) != 0 {
|
|
rc = _sqlite3Fts5DecodeLocaleValue(tls, pVal, bp+48, bp+56, bp+64, bp+72)
|
|
} else {
|
|
if (*TFts5Config)(unsafe.Pointer(pConfig)).FeContent == FTS5_CONTENT_NORMAL && (*TFts5Config)(unsafe.Pointer(pConfig)).FbLocale != 0 {
|
|
iCol = i + int32(1) + (*TFts5Config)(unsafe.Pointer(pConfig)).FnCol
|
|
**(**uintptr)(__ccgo_up(bp + 64)) = Xsqlite3_column_text(tls, **(**uintptr)(__ccgo_up(bp + 40)), iCol)
|
|
**(**int32)(__ccgo_up(bp + 72)) = Xsqlite3_column_bytes(tls, **(**uintptr)(__ccgo_up(bp + 40)), iCol)
|
|
}
|
|
**(**uintptr)(__ccgo_up(bp + 48)) = Xsqlite3_value_text(tls, pVal)
|
|
**(**int32)(__ccgo_up(bp + 56)) = Xsqlite3_value_bytes(tls, pVal)
|
|
}
|
|
(**(**TFts5IntegrityCtx)(__ccgo_up(bp))).FiCol = i
|
|
(**(**TFts5IntegrityCtx)(__ccgo_up(bp))).FszCol = 0
|
|
if rc == SQLITE_OK && (*TFts5Config)(unsafe.Pointer(pConfig)).FeDetail == int32(FTS5_DETAIL_COLUMNS) {
|
|
rc = _sqlite3Fts5TermsetNew(tls, bp+24)
|
|
}
|
|
if rc == SQLITE_OK {
|
|
_sqlite3Fts5SetLocale(tls, pConfig, **(**uintptr)(__ccgo_up(bp + 64)), **(**int32)(__ccgo_up(bp + 72)))
|
|
rc = _sqlite3Fts5Tokenize(tls, pConfig, int32(FTS5_TOKENIZE_DOCUMENT), **(**uintptr)(__ccgo_up(bp + 48)), **(**int32)(__ccgo_up(bp + 56)), bp, __ccgo_fp(_fts5StorageIntegrityCallback))
|
|
_sqlite3Fts5ClearLocale(tls, pConfig)
|
|
}
|
|
/* If this is not a columnsize=0 database, check that the number
|
|
** of tokens in the value matches the aColSize[] value read from
|
|
** the %_docsize table. */
|
|
if rc == SQLITE_OK && (*TFts5Config)(unsafe.Pointer(pConfig)).FbColumnsize != 0 && (**(**TFts5IntegrityCtx)(__ccgo_up(bp))).FszCol != **(**int32)(__ccgo_up(aColSize + uintptr(i)*4)) {
|
|
rc = libc.Int32FromInt32(SQLITE_CORRUPT) | libc.Int32FromInt32(1)<<libc.Int32FromInt32(8)
|
|
}
|
|
**(**Ti64)(__ccgo_up(aTotalSize + uintptr(i)*8)) += int64((**(**TFts5IntegrityCtx)(__ccgo_up(bp))).FszCol)
|
|
if (*TFts5Config)(unsafe.Pointer(pConfig)).FeDetail == int32(FTS5_DETAIL_COLUMNS) {
|
|
_sqlite3Fts5TermsetFree(tls, (**(**TFts5IntegrityCtx)(__ccgo_up(bp))).FpTermset)
|
|
(**(**TFts5IntegrityCtx)(__ccgo_up(bp))).FpTermset = uintptr(0)
|
|
}
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
_sqlite3Fts5TermsetFree(tls, (**(**TFts5IntegrityCtx)(__ccgo_up(bp))).FpTermset)
|
|
(**(**TFts5IntegrityCtx)(__ccgo_up(bp))).FpTermset = uintptr(0)
|
|
if rc != SQLITE_OK {
|
|
break
|
|
}
|
|
}
|
|
rc2 = Xsqlite3_reset(tls, **(**uintptr)(__ccgo_up(bp + 40)))
|
|
if rc == SQLITE_OK {
|
|
rc = rc2
|
|
}
|
|
}
|
|
/* Test that the "totals" (sometimes called "averages") record looks Ok */
|
|
if rc == SQLITE_OK {
|
|
rc = _fts5StorageLoadTotals(tls, p, 0)
|
|
i1 = 0
|
|
for {
|
|
if !(rc == SQLITE_OK && i1 < (*TFts5Config)(unsafe.Pointer(pConfig)).FnCol) {
|
|
break
|
|
}
|
|
if **(**Ti64)(__ccgo_up((*TFts5Storage)(unsafe.Pointer(p)).FaTotalSize + uintptr(i1)*8)) != **(**Ti64)(__ccgo_up(aTotalSize + uintptr(i1)*8)) {
|
|
rc = libc.Int32FromInt32(SQLITE_CORRUPT) | libc.Int32FromInt32(1)<<libc.Int32FromInt32(8)
|
|
}
|
|
goto _2
|
|
_2:
|
|
;
|
|
i1 = i1 + 1
|
|
}
|
|
}
|
|
/* Check that the %_docsize and %_content tables contain the expected
|
|
** number of rows. */
|
|
if rc == SQLITE_OK && (*TFts5Config)(unsafe.Pointer(pConfig)).FeContent == FTS5_CONTENT_NORMAL {
|
|
**(**Ti64)(__ccgo_up(bp + 80)) = 0
|
|
rc = _fts5StorageCount(tls, p, __ccgo_ts+37615, bp+80)
|
|
if rc == SQLITE_OK && **(**Ti64)(__ccgo_up(bp + 80)) != (*TFts5Storage)(unsafe.Pointer(p)).FnTotalRow {
|
|
rc = libc.Int32FromInt32(SQLITE_CORRUPT) | libc.Int32FromInt32(1)<<libc.Int32FromInt32(8)
|
|
}
|
|
}
|
|
if rc == SQLITE_OK && (*TFts5Config)(unsafe.Pointer(pConfig)).FbColumnsize != 0 {
|
|
**(**Ti64)(__ccgo_up(bp + 88)) = 0
|
|
rc = _fts5StorageCount(tls, p, __ccgo_ts+38310, bp+88)
|
|
if rc == SQLITE_OK && **(**Ti64)(__ccgo_up(bp + 88)) != (*TFts5Storage)(unsafe.Pointer(p)).FnTotalRow {
|
|
rc = libc.Int32FromInt32(SQLITE_CORRUPT) | libc.Int32FromInt32(1)<<libc.Int32FromInt32(8)
|
|
}
|
|
}
|
|
}
|
|
/* Pass the expected checksum down to the FTS index module. It will
|
|
** verify, amongst other things, that it matches the checksum generated by
|
|
** inspecting the index itself. */
|
|
if rc == SQLITE_OK {
|
|
rc = _sqlite3Fts5IndexIntegrityCheck(tls, (*TFts5Storage)(unsafe.Pointer(p)).FpIndex, (**(**TFts5IntegrityCtx)(__ccgo_up(bp))).Fcksum, bUseCksum)
|
|
}
|
|
Xsqlite3_free(tls, aTotalSize)
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Open a new Fts5Index handle. If the bCreate argument is true, create
|
|
// ** and initialize the underlying tables
|
|
// **
|
|
// ** If successful, set *pp to point to the new object and return SQLITE_OK.
|
|
// ** Otherwise, set *pp to NULL and return an SQLite error code.
|
|
// */
|
|
func _sqlite3Fts5StorageOpen(tls *libc.TLS, pConfig uintptr, pIndex uintptr, bCreate int32, pp uintptr, pzErr uintptr) (r int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var i, rc int32
|
|
var nByte Tsqlite3_int64
|
|
var p, pDefn, zCols, zDefn, v1 uintptr
|
|
_, _, _, _, _, _, _, _ = i, nByte, p, pDefn, rc, zCols, zDefn, v1
|
|
rc = SQLITE_OK /* Bytes of space to allocate */
|
|
nByte = libc.Int64FromUint64(uint64(144) + libc.Uint64FromInt32((*TFts5Config)(unsafe.Pointer(pConfig)).FnCol)*uint64(8)) /* Fts5Storage.aTotalSize[] */
|
|
v1 = Xsqlite3_malloc64(tls, libc.Uint64FromInt64(nByte))
|
|
p = v1
|
|
**(**uintptr)(__ccgo_up(pp)) = v1
|
|
if !(p != 0) {
|
|
return int32(SQLITE_NOMEM)
|
|
}
|
|
libc.Xmemset(tls, p, 0, libc.Uint64FromInt64(nByte))
|
|
(*TFts5Storage)(unsafe.Pointer(p)).FaTotalSize = p + 1*144
|
|
(*TFts5Storage)(unsafe.Pointer(p)).FpConfig = pConfig
|
|
(*TFts5Storage)(unsafe.Pointer(p)).FpIndex = pIndex
|
|
if bCreate != 0 {
|
|
if (*TFts5Config)(unsafe.Pointer(pConfig)).FeContent == FTS5_CONTENT_NORMAL || (*TFts5Config)(unsafe.Pointer(pConfig)).FeContent == int32(FTS5_CONTENT_UNINDEXED) {
|
|
i = 0
|
|
zDefn = uintptr(0)
|
|
pDefn = Xsqlite3_str_new(tls, (*TFts5Config)(unsafe.Pointer(pConfig)).Fdb)
|
|
Xsqlite3_str_appendf(tls, pDefn, __ccgo_ts+41586, 0)
|
|
i = 0
|
|
for {
|
|
if !(i < (*TFts5Config)(unsafe.Pointer(pConfig)).FnCol) {
|
|
break
|
|
}
|
|
if (*TFts5Config)(unsafe.Pointer(pConfig)).FeContent == FTS5_CONTENT_NORMAL || **(**Tu8)(__ccgo_up((*TFts5Config)(unsafe.Pointer(pConfig)).FabUnindexed + uintptr(i))) != 0 {
|
|
Xsqlite3_str_appendf(tls, pDefn, __ccgo_ts+41609, libc.VaList(bp+8, i))
|
|
}
|
|
goto _2
|
|
_2:
|
|
;
|
|
i = i + 1
|
|
}
|
|
if (*TFts5Config)(unsafe.Pointer(pConfig)).FbLocale != 0 {
|
|
i = 0
|
|
for {
|
|
if !(i < (*TFts5Config)(unsafe.Pointer(pConfig)).FnCol) {
|
|
break
|
|
}
|
|
if libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TFts5Config)(unsafe.Pointer(pConfig)).FabUnindexed + uintptr(i)))) == 0 {
|
|
Xsqlite3_str_appendf(tls, pDefn, __ccgo_ts+41615, libc.VaList(bp+8, i))
|
|
}
|
|
goto _3
|
|
_3:
|
|
;
|
|
i = i + 1
|
|
}
|
|
}
|
|
zDefn = Xsqlite3_str_finish(tls, pDefn)
|
|
if zDefn != 0 {
|
|
rc = _sqlite3Fts5CreateTable(tls, pConfig, __ccgo_ts+37615, zDefn, 0, pzErr)
|
|
Xsqlite3_free(tls, zDefn)
|
|
} else {
|
|
rc = int32(SQLITE_NOMEM)
|
|
}
|
|
}
|
|
if rc == SQLITE_OK && (*TFts5Config)(unsafe.Pointer(pConfig)).FbColumnsize != 0 {
|
|
zCols = __ccgo_ts + 41621
|
|
if (*TFts5Config)(unsafe.Pointer(pConfig)).FbContentlessDelete != 0 {
|
|
zCols = __ccgo_ts + 41653
|
|
}
|
|
rc = _sqlite3Fts5CreateTable(tls, pConfig, __ccgo_ts+38310, zCols, 0, pzErr)
|
|
}
|
|
if rc == SQLITE_OK {
|
|
rc = _sqlite3Fts5CreateTable(tls, pConfig, __ccgo_ts+40624, __ccgo_ts+41701, int32(1), pzErr)
|
|
}
|
|
if rc == SQLITE_OK {
|
|
rc = _sqlite3Fts5StorageConfigValue(tls, p, __ccgo_ts+38492, uintptr(0), int32(FTS5_CURRENT_VERSION))
|
|
}
|
|
}
|
|
if rc != 0 {
|
|
_sqlite3Fts5StorageClose(tls, p)
|
|
**(**uintptr)(__ccgo_up(pp)) = uintptr(0)
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Register all built-in tokenizers with FTS5.
|
|
// */
|
|
func _sqlite3Fts5TokenizerInit(tls *libc.TLS, pApi uintptr) (r int32) {
|
|
bp := tls.Alloc(128)
|
|
defer tls.Free(128)
|
|
var i, rc int32
|
|
var _ /* aBuiltin at bp+0 */ [3]struct {
|
|
FzName uintptr
|
|
Fx Tfts5_tokenizer
|
|
}
|
|
var _ /* sPorter at bp+96 */ Tfts5_tokenizer_v2
|
|
_, _ = i, rc
|
|
**(**[3]struct {
|
|
FzName uintptr
|
|
Fx Tfts5_tokenizer
|
|
})(__ccgo_up(bp)) = [3]struct {
|
|
FzName uintptr
|
|
Fx Tfts5_tokenizer
|
|
}{
|
|
0: {
|
|
FzName: __ccgo_ts + 41918,
|
|
Fx: Tfts5_tokenizer{
|
|
FxCreate: __ccgo_fp(_fts5UnicodeCreate),
|
|
FxDelete: __ccgo_fp(_fts5UnicodeDelete),
|
|
FxTokenize: __ccgo_fp(_fts5UnicodeTokenize),
|
|
},
|
|
},
|
|
1: {
|
|
FzName: __ccgo_ts + 42237,
|
|
Fx: Tfts5_tokenizer{
|
|
FxCreate: __ccgo_fp(_fts5AsciiCreate),
|
|
FxDelete: __ccgo_fp(_fts5AsciiDelete),
|
|
FxTokenize: __ccgo_fp(_fts5AsciiTokenize),
|
|
},
|
|
},
|
|
2: {
|
|
FzName: __ccgo_ts + 42229,
|
|
Fx: Tfts5_tokenizer{
|
|
FxCreate: __ccgo_fp(_fts5TriCreate),
|
|
FxDelete: __ccgo_fp(_fts5TriDelete),
|
|
FxTokenize: __ccgo_fp(_fts5TriTokenize),
|
|
},
|
|
},
|
|
}
|
|
rc = SQLITE_OK /* To iterate through builtin functions */
|
|
i = 0
|
|
for {
|
|
if !(rc == SQLITE_OK && i < libc.Int32FromUint64(libc.Uint64FromInt64(96)/libc.Uint64FromInt64(32))) {
|
|
break
|
|
}
|
|
rc = (*(*func(*libc.TLS, uintptr, uintptr, uintptr, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*Tfts5_api)(unsafe.Pointer(pApi)).FxCreateTokenizer})))(tls, pApi, (**(**[3]struct {
|
|
FzName uintptr
|
|
Fx Tfts5_tokenizer
|
|
})(__ccgo_up(bp)))[i].FzName, pApi, bp+uintptr(i)*32+8, uintptr(0))
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
if rc == SQLITE_OK {
|
|
**(**Tfts5_tokenizer_v2)(__ccgo_up(bp + 96)) = Tfts5_tokenizer_v2{
|
|
FiVersion: int32(2),
|
|
FxCreate: __ccgo_fp(_fts5PorterCreate),
|
|
FxDelete: __ccgo_fp(_fts5PorterDelete),
|
|
FxTokenize: __ccgo_fp(_fts5PorterTokenize),
|
|
}
|
|
rc = (*(*func(*libc.TLS, uintptr, uintptr, uintptr, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*Tfts5_api)(unsafe.Pointer(pApi)).FxCreateTokenizer_v2})))(tls, pApi, __ccgo_ts+41928, pApi, bp+96, uintptr(0))
|
|
}
|
|
return rc
|
|
}
|
|
|
|
/*
|
|
** 2012-05-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.
|
|
**
|
|
******************************************************************************
|
|
*/
|
|
|
|
/*
|
|
** DO NOT EDIT THIS MACHINE GENERATED FILE.
|
|
*/
|
|
|
|
/* #include <assert.h> */
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This routine generates VDBE code that causes a single row of a
|
|
// ** single table to be deleted. Both the original table entry and
|
|
// ** all indices are removed.
|
|
// **
|
|
// ** Preconditions:
|
|
// **
|
|
// ** 1. iDataCur is an open cursor on the btree that is the canonical data
|
|
// ** store for the table. (This will be either the table itself,
|
|
// ** in the case of a rowid table, or the PRIMARY KEY index in the case
|
|
// ** of a WITHOUT ROWID table.)
|
|
// **
|
|
// ** 2. Read/write cursors for all indices of pTab must be open as
|
|
// ** cursor number iIdxCur+i for the i-th index.
|
|
// **
|
|
// ** 3. The primary key for the row to be deleted must be stored in a
|
|
// ** sequence of nPk memory cells starting at iPk. If nPk==0 that means
|
|
// ** that a search record formed from OP_MakeRecord is contained in the
|
|
// ** single memory location iPk.
|
|
// **
|
|
// ** eMode:
|
|
// ** Parameter eMode may be passed either ONEPASS_OFF (0), ONEPASS_SINGLE, or
|
|
// ** ONEPASS_MULTI. If eMode is not ONEPASS_OFF, then the cursor
|
|
// ** iDataCur already points to the row to delete. If eMode is ONEPASS_OFF
|
|
// ** then this function must seek iDataCur to the entry identified by iPk
|
|
// ** and nPk before reading from it.
|
|
// **
|
|
// ** If eMode is ONEPASS_MULTI, then this call is being made as part
|
|
// ** of a ONEPASS delete that affects multiple rows. In this case, if
|
|
// ** iIdxNoSeek is a valid cursor number (>=0) and is not the same as
|
|
// ** iDataCur, then its position should be preserved following the delete
|
|
// ** operation. Or, if iIdxNoSeek is not a valid cursor number, the
|
|
// ** position of iDataCur should be preserved instead.
|
|
// **
|
|
// ** iIdxNoSeek:
|
|
// ** If iIdxNoSeek is a valid cursor number (>=0) not equal to iDataCur,
|
|
// ** then it identifies an index cursor (from within array of cursors
|
|
// ** starting at iIdxCur) that already points to the index entry to be deleted.
|
|
// ** Except, this optimization is disabled if there are BEFORE triggers since
|
|
// ** the trigger body might have moved the cursor.
|
|
// */
|
|
func _sqlite3GenerateRowDelete(tls *libc.TLS, pParse uintptr, pTab uintptr, pTrigger uintptr, iDataCur int32, iIdxCur int32, iPk int32, nPk Ti16, count Tu8, onconf Tu8, eMode Tu8, iIdxNoSeek int32) {
|
|
var addrStart, iCol, iLabel, iOld, kk, v1 int32
|
|
var mask Tu32
|
|
var opSeek, p5 Tu8
|
|
var v uintptr
|
|
_, _, _, _, _, _, _, _, _, _ = addrStart, iCol, iLabel, iOld, kk, mask, opSeek, p5, v, v1
|
|
v = (*TParse)(unsafe.Pointer(pParse)).FpVdbe /* Vdbe */
|
|
iOld = 0 /* Seek opcode */
|
|
/* Vdbe is guaranteed to have been allocated by this stage. */
|
|
/* Seek cursor iCur to the row to delete. If this row no longer exists
|
|
** (this can happen if a trigger program has already deleted it), do
|
|
** not attempt to delete it or fire any DELETE triggers. */
|
|
iLabel = _sqlite3VdbeMakeLabel(tls, pParse)
|
|
if (*TTable)(unsafe.Pointer(pTab)).FtabFlags&uint32(TF_WithoutRowid) == uint32(0) {
|
|
v1 = int32(OP_NotExists)
|
|
} else {
|
|
v1 = int32(OP_NotFound)
|
|
}
|
|
opSeek = libc.Uint8FromInt32(v1)
|
|
if libc.Int32FromUint8(eMode) == ONEPASS_OFF {
|
|
_sqlite3VdbeAddOp4Int(tls, v, libc.Int32FromUint8(opSeek), iDataCur, iLabel, iPk, int32(nPk))
|
|
}
|
|
/* If there are any triggers to fire, allocate a range of registers to
|
|
** use for the old.* references in the triggers. */
|
|
if _sqlite3FkRequired(tls, pParse, pTab, uintptr(0), 0) != 0 || pTrigger != 0 { /* Start of BEFORE trigger programs */
|
|
/* TODO: Could use temporary registers here. Also could attempt to
|
|
** avoid copying the contents of the rowid register. */
|
|
mask = _sqlite3TriggerColmask(tls, pParse, pTrigger, uintptr(0), 0, libc.Int32FromInt32(TRIGGER_BEFORE)|libc.Int32FromInt32(TRIGGER_AFTER), pTab, libc.Int32FromUint8(onconf))
|
|
mask = mask | _sqlite3FkOldmask(tls, pParse, pTab)
|
|
iOld = (*TParse)(unsafe.Pointer(pParse)).FnMem + int32(1)
|
|
**(**int32)(__ccgo_up(pParse + 60)) += int32(1) + int32((*TTable)(unsafe.Pointer(pTab)).FnCol)
|
|
/* Populate the OLD.* pseudo-table register array. These values will be
|
|
** used by any BEFORE and AFTER triggers that exist. */
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_Copy), iPk, iOld)
|
|
iCol = 0
|
|
for {
|
|
if !(iCol < int32((*TTable)(unsafe.Pointer(pTab)).FnCol)) {
|
|
break
|
|
}
|
|
if mask == uint32(0xffffffff) || iCol <= int32(31) && mask&(libc.Uint32FromInt32(1)<<iCol) != uint32(0) {
|
|
kk = int32(_sqlite3TableColumnToStorage(tls, pTab, int16(iCol)))
|
|
_sqlite3ExprCodeGetColumnOfTable(tls, v, pTab, iDataCur, iCol, iOld+kk+int32(1))
|
|
}
|
|
goto _2
|
|
_2:
|
|
;
|
|
iCol = iCol + 1
|
|
}
|
|
/* Invoke BEFORE DELETE trigger programs. */
|
|
addrStart = _sqlite3VdbeCurrentAddr(tls, v)
|
|
_sqlite3CodeRowTrigger(tls, pParse, pTrigger, int32(TK_DELETE), uintptr(0), int32(TRIGGER_BEFORE), pTab, iOld, libc.Int32FromUint8(onconf), iLabel)
|
|
/* If any BEFORE triggers were coded, then seek the cursor to the
|
|
** row to be deleted again. It may be that the BEFORE triggers moved
|
|
** the cursor or already deleted the row that the cursor was
|
|
** pointing to.
|
|
**
|
|
** Also disable the iIdxNoSeek optimization since the BEFORE trigger
|
|
** may have moved that cursor.
|
|
*/
|
|
if addrStart < _sqlite3VdbeCurrentAddr(tls, v) {
|
|
_sqlite3VdbeAddOp4Int(tls, v, libc.Int32FromUint8(opSeek), iDataCur, iLabel, iPk, int32(nPk))
|
|
iIdxNoSeek = -int32(1)
|
|
}
|
|
/* Do FK processing. This call checks that any FK constraints that
|
|
** refer to this table (i.e. constraints attached to other tables)
|
|
** are not violated by deleting this row. */
|
|
_sqlite3FkCheck(tls, pParse, pTab, iOld, 0, uintptr(0), 0)
|
|
}
|
|
/* Delete the index and table entries. Skip this step if pTab is really
|
|
** a view (in which case the only effect of the DELETE statement is to
|
|
** fire the INSTEAD OF triggers).
|
|
**
|
|
** If variable 'count' is non-zero, then this OP_Delete instruction should
|
|
** invoke the update-hook. The pre-update-hook, on the other hand should
|
|
** be invoked unless table pTab is a system table. The difference is that
|
|
** the update-hook is not invoked for rows removed by REPLACE, but the
|
|
** pre-update-hook is.
|
|
*/
|
|
if !(libc.Int32FromUint8((*TTable)(unsafe.Pointer(pTab)).FeTabType) == libc.Int32FromInt32(TABTYP_VIEW)) {
|
|
p5 = uint8(0)
|
|
_sqlite3GenerateRowIndexDelete(tls, pParse, pTab, iDataCur, iIdxCur, uintptr(0), iIdxNoSeek)
|
|
if count != 0 {
|
|
v1 = int32(OPFLAG_NCHANGE)
|
|
} else {
|
|
v1 = 0
|
|
}
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_Delete), iDataCur, v1)
|
|
if libc.Int32FromUint8((*TParse)(unsafe.Pointer(pParse)).Fnested) == 0 || 0 == Xsqlite3_stricmp(tls, (*TTable)(unsafe.Pointer(pTab)).FzName, __ccgo_ts+12861) {
|
|
_sqlite3VdbeAppendP4(tls, v, pTab, -int32(5))
|
|
}
|
|
if libc.Int32FromUint8(eMode) != ONEPASS_OFF {
|
|
_sqlite3VdbeChangeP5(tls, v, uint16(OPFLAG_AUXDELETE))
|
|
}
|
|
if iIdxNoSeek >= 0 && iIdxNoSeek != iDataCur {
|
|
_sqlite3VdbeAddOp1(tls, v, int32(OP_Delete), iIdxNoSeek)
|
|
}
|
|
if libc.Int32FromUint8(eMode) == int32(ONEPASS_MULTI) {
|
|
p5 = libc.Uint8FromInt32(int32(p5) | libc.Int32FromInt32(OPFLAG_SAVEPOSITION))
|
|
}
|
|
_sqlite3VdbeChangeP5(tls, v, uint16(p5))
|
|
}
|
|
/* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to
|
|
** handle rows (possibly in other tables) that refer via a foreign key
|
|
** to the row just deleted. */
|
|
_sqlite3FkActions(tls, pParse, pTab, uintptr(0), iOld, uintptr(0), 0)
|
|
/* Invoke AFTER DELETE trigger programs. */
|
|
if pTrigger != 0 {
|
|
_sqlite3CodeRowTrigger(tls, pParse, pTrigger, int32(TK_DELETE), uintptr(0), int32(TRIGGER_AFTER), pTab, iOld, libc.Int32FromUint8(onconf), iLabel)
|
|
}
|
|
/* Jump here if the row had already been deleted before any BEFORE
|
|
** trigger programs were invoked. Or if a trigger program throws a
|
|
** RAISE(IGNORE) exception. */
|
|
_sqlite3VdbeResolveLabel(tls, v, iLabel)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Attempt to read the database schema and initialize internal
|
|
// ** data structures for a single database file. The index of the
|
|
// ** database file is given by iDb. iDb==0 is used for the main
|
|
// ** database. iDb==1 should never be used. iDb>=2 is used for
|
|
// ** auxiliary databases. Return one of the SQLITE_ error codes to
|
|
// ** indicate success or failure.
|
|
// */
|
|
func _sqlite3InitOne(tls *libc.TLS, db uintptr, iDb int32, pzErrMsg uintptr, mFlags Tu32) (r int32) {
|
|
bp := tls.Alloc(144)
|
|
defer tls.Free(144)
|
|
var encoding Tu8
|
|
var i, mask, openedTransaction, rc, size int32
|
|
var pDb, zSchemaTabName, zSql, v1, v2 uintptr
|
|
var xAuth Tsqlite3_xauth
|
|
var _ /* azArg at bp+0 */ [6]uintptr
|
|
var _ /* initData at bp+72 */ TInitData
|
|
var _ /* meta at bp+48 */ [5]int32
|
|
_, _, _, _, _, _, _, _, _, _, _, _ = encoding, i, mask, openedTransaction, pDb, rc, size, xAuth, zSchemaTabName, zSql, v1, v2
|
|
openedTransaction = 0
|
|
mask = libc.Int32FromUint32((*Tsqlite3)(unsafe.Pointer(db)).FmDbFlags&libc.Uint32FromInt32(DBFLAG_EncodingFixed) | libc.Uint32FromInt32(^libc.Int32FromInt32(DBFLAG_EncodingFixed)))
|
|
(*Tsqlite3)(unsafe.Pointer(db)).Finit1.Fbusy = uint8(1)
|
|
/* Construct the in-memory representation schema tables (sqlite_schema or
|
|
** sqlite_temp_schema) by invoking the parser directly. The appropriate
|
|
** table name will be inserted automatically by the parser so we can just
|
|
** use the abbreviation "x" here. The parser will also automatically tag
|
|
** the schema table as read-only. */
|
|
(**(**[6]uintptr)(__ccgo_up(bp)))[0] = __ccgo_ts + 9405
|
|
if libc.Bool(!(libc.Int32FromInt32(OMIT_TEMPDB) != 0)) && iDb == int32(1) {
|
|
v2 = __ccgo_ts + 6792
|
|
} else {
|
|
v2 = __ccgo_ts + 6312
|
|
}
|
|
v1 = v2
|
|
zSchemaTabName = v1
|
|
(**(**[6]uintptr)(__ccgo_up(bp)))[int32(1)] = v1
|
|
(**(**[6]uintptr)(__ccgo_up(bp)))[int32(2)] = (**(**[6]uintptr)(__ccgo_up(bp)))[int32(1)]
|
|
(**(**[6]uintptr)(__ccgo_up(bp)))[int32(3)] = __ccgo_ts + 20131
|
|
(**(**[6]uintptr)(__ccgo_up(bp)))[int32(4)] = __ccgo_ts + 20133
|
|
(**(**[6]uintptr)(__ccgo_up(bp)))[int32(5)] = uintptr(0)
|
|
(**(**TInitData)(__ccgo_up(bp + 72))).Fdb = db
|
|
(**(**TInitData)(__ccgo_up(bp + 72))).FiDb = iDb
|
|
(**(**TInitData)(__ccgo_up(bp + 72))).Frc = SQLITE_OK
|
|
(**(**TInitData)(__ccgo_up(bp + 72))).FpzErrMsg = pzErrMsg
|
|
(**(**TInitData)(__ccgo_up(bp + 72))).FmInitFlags = mFlags
|
|
(**(**TInitData)(__ccgo_up(bp + 72))).FnInitRow = uint32(0)
|
|
(**(**TInitData)(__ccgo_up(bp + 72))).FmxPage = uint32(0)
|
|
_sqlite3InitCallback(tls, bp+72, int32(5), bp, uintptr(0))
|
|
**(**Tu32)(__ccgo_up(db + 44)) &= libc.Uint32FromInt32(mask)
|
|
if (**(**TInitData)(__ccgo_up(bp + 72))).Frc != 0 {
|
|
rc = (**(**TInitData)(__ccgo_up(bp + 72))).Frc
|
|
goto error_out
|
|
}
|
|
/* Create a cursor to hold the database open
|
|
*/
|
|
pDb = (*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(iDb)*32
|
|
if (*TDb)(unsafe.Pointer(pDb)).FpBt == uintptr(0) {
|
|
v1 = (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + 1*32))).FpSchema + 114
|
|
*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) | libc.Int32FromInt32(DB_SchemaLoaded))
|
|
rc = SQLITE_OK
|
|
goto error_out
|
|
}
|
|
/* If there is not already a read-only (or read-write) transaction opened
|
|
** on the b-tree database, open one now. If a transaction is opened, it
|
|
** will be closed before this function returns. */
|
|
_sqlite3BtreeEnter(tls, (*TDb)(unsafe.Pointer(pDb)).FpBt)
|
|
if _sqlite3BtreeTxnState(tls, (*TDb)(unsafe.Pointer(pDb)).FpBt) == SQLITE_TXN_NONE {
|
|
rc = _sqlite3BtreeBeginTrans(tls, (*TDb)(unsafe.Pointer(pDb)).FpBt, 0, uintptr(0))
|
|
if rc != SQLITE_OK {
|
|
_sqlite3SetString(tls, pzErrMsg, db, _sqlite3ErrStr(tls, rc))
|
|
goto initone_error_out
|
|
}
|
|
openedTransaction = int32(1)
|
|
}
|
|
/* Get the database meta information.
|
|
**
|
|
** Meta values are as follows:
|
|
** meta[0] Schema cookie. Changes with each schema change.
|
|
** meta[1] File format of schema layer.
|
|
** meta[2] Size of the page cache.
|
|
** meta[3] Largest rootpage (auto/incr_vacuum mode)
|
|
** meta[4] Db text encoding. 1:UTF-8 2:UTF-16LE 3:UTF-16BE
|
|
** meta[5] User version
|
|
** meta[6] Incremental vacuum mode
|
|
** meta[7] unused
|
|
** meta[8] unused
|
|
** meta[9] unused
|
|
**
|
|
** Note: The #defined SQLITE_UTF* symbols in sqliteInt.h correspond to
|
|
** the possible values of meta[4].
|
|
*/
|
|
i = 0
|
|
for {
|
|
if !(i < libc.Int32FromUint64(libc.Uint64FromInt64(20)/libc.Uint64FromInt64(4))) {
|
|
break
|
|
}
|
|
_sqlite3BtreeGetMeta(tls, (*TDb)(unsafe.Pointer(pDb)).FpBt, i+int32(1), bp+48+uintptr(i)*4)
|
|
goto _4
|
|
_4:
|
|
;
|
|
i = i + 1
|
|
}
|
|
if (*Tsqlite3)(unsafe.Pointer(db)).Fflags&uint64(SQLITE_ResetDatabase) != uint64(0) {
|
|
libc.Xmemset(tls, bp+48, 0, uint64(20))
|
|
}
|
|
(*TSchema)(unsafe.Pointer((*TDb)(unsafe.Pointer(pDb)).FpSchema)).Fschema_cookie = (**(**[5]int32)(__ccgo_up(bp + 48)))[libc.Int32FromInt32(BTREE_SCHEMA_VERSION)-libc.Int32FromInt32(1)]
|
|
/* If opening a non-empty database, check the text encoding. For the
|
|
** main database, set sqlite3.enc to the encoding of the main database.
|
|
** For an attached db, it is an error if the encoding is not the same
|
|
** as sqlite3.enc.
|
|
*/
|
|
if (**(**[5]int32)(__ccgo_up(bp + 48)))[libc.Int32FromInt32(BTREE_TEXT_ENCODING)-libc.Int32FromInt32(1)] != 0 { /* text encoding */
|
|
if iDb == 0 && (*Tsqlite3)(unsafe.Pointer(db)).FmDbFlags&uint32(DBFLAG_EncodingFixed) == uint32(0) {
|
|
/* If opening the main database, set ENC(db). */
|
|
encoding = libc.Uint8FromInt32(libc.Int32FromUint8(libc.Uint8FromInt32((**(**[5]int32)(__ccgo_up(bp + 48)))[libc.Int32FromInt32(BTREE_TEXT_ENCODING)-libc.Int32FromInt32(1)])) & int32(3))
|
|
if libc.Int32FromUint8(encoding) == 0 {
|
|
encoding = uint8(SQLITE_UTF8)
|
|
}
|
|
_sqlite3SetTextEncoding(tls, db, encoding)
|
|
} else {
|
|
/* If opening an attached database, the encoding much match ENC(db) */
|
|
if (**(**[5]int32)(__ccgo_up(bp + 48)))[libc.Int32FromInt32(BTREE_TEXT_ENCODING)-libc.Int32FromInt32(1)]&int32(3) != libc.Int32FromUint8((*Tsqlite3)(unsafe.Pointer(db)).Fenc) {
|
|
_sqlite3SetString(tls, pzErrMsg, db, __ccgo_ts+13374)
|
|
rc = int32(SQLITE_ERROR)
|
|
goto initone_error_out
|
|
}
|
|
}
|
|
}
|
|
(*TSchema)(unsafe.Pointer((*TDb)(unsafe.Pointer(pDb)).FpSchema)).Fenc = (*Tsqlite3)(unsafe.Pointer(db)).Fenc
|
|
if (*TSchema)(unsafe.Pointer((*TDb)(unsafe.Pointer(pDb)).FpSchema)).Fcache_size == 0 {
|
|
size = _sqlite3AbsInt32(tls, (**(**[5]int32)(__ccgo_up(bp + 48)))[libc.Int32FromInt32(BTREE_DEFAULT_CACHE_SIZE)-libc.Int32FromInt32(1)])
|
|
if size == 0 {
|
|
size = -int32(2000)
|
|
}
|
|
(*TSchema)(unsafe.Pointer((*TDb)(unsafe.Pointer(pDb)).FpSchema)).Fcache_size = size
|
|
_sqlite3BtreeSetCacheSize(tls, (*TDb)(unsafe.Pointer(pDb)).FpBt, (*TSchema)(unsafe.Pointer((*TDb)(unsafe.Pointer(pDb)).FpSchema)).Fcache_size)
|
|
}
|
|
/*
|
|
** file_format==1 Version 3.0.0.
|
|
** file_format==2 Version 3.1.3. // ALTER TABLE ADD COLUMN
|
|
** file_format==3 Version 3.1.4. // ditto but with non-NULL defaults
|
|
** file_format==4 Version 3.3.0. // DESC indices. Boolean constants
|
|
*/
|
|
(*TSchema)(unsafe.Pointer((*TDb)(unsafe.Pointer(pDb)).FpSchema)).Ffile_format = libc.Uint8FromInt32((**(**[5]int32)(__ccgo_up(bp + 48)))[libc.Int32FromInt32(BTREE_FILE_FORMAT)-libc.Int32FromInt32(1)])
|
|
if libc.Int32FromUint8((*TSchema)(unsafe.Pointer((*TDb)(unsafe.Pointer(pDb)).FpSchema)).Ffile_format) == 0 {
|
|
(*TSchema)(unsafe.Pointer((*TDb)(unsafe.Pointer(pDb)).FpSchema)).Ffile_format = uint8(1)
|
|
}
|
|
if libc.Int32FromUint8((*TSchema)(unsafe.Pointer((*TDb)(unsafe.Pointer(pDb)).FpSchema)).Ffile_format) > int32(SQLITE_MAX_FILE_FORMAT) {
|
|
_sqlite3SetString(tls, pzErrMsg, db, __ccgo_ts+20205)
|
|
rc = int32(SQLITE_ERROR)
|
|
goto initone_error_out
|
|
}
|
|
/* Ticket #2804: When we open a database in the newer file format,
|
|
** clear the legacy_file_format pragma flag so that a VACUUM will
|
|
** not downgrade the database and thus invalidate any descending
|
|
** indices that the user might have created.
|
|
*/
|
|
if iDb == 0 && (**(**[5]int32)(__ccgo_up(bp + 48)))[libc.Int32FromInt32(BTREE_FILE_FORMAT)-libc.Int32FromInt32(1)] >= int32(4) {
|
|
**(**Tu64)(__ccgo_up(db + 48)) &= ^libc.Uint64FromInt32(SQLITE_LegacyFileFmt)
|
|
}
|
|
/* Read the schema information out of the schema tables
|
|
*/
|
|
(**(**TInitData)(__ccgo_up(bp + 72))).FmxPage = _sqlite3BtreeLastPage(tls, (*TDb)(unsafe.Pointer(pDb)).FpBt)
|
|
zSql = _sqlite3MPrintf(tls, db, __ccgo_ts+20229, libc.VaList(bp+120, (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(iDb)*32))).FzDbSName, zSchemaTabName))
|
|
xAuth = (*Tsqlite3)(unsafe.Pointer(db)).FxAuth
|
|
(*Tsqlite3)(unsafe.Pointer(db)).FxAuth = uintptr(0)
|
|
rc = Xsqlite3_exec(tls, db, zSql, __ccgo_fp(_sqlite3InitCallback), bp+72, uintptr(0))
|
|
(*Tsqlite3)(unsafe.Pointer(db)).FxAuth = xAuth
|
|
if rc == SQLITE_OK {
|
|
rc = (**(**TInitData)(__ccgo_up(bp + 72))).Frc
|
|
}
|
|
_sqlite3DbFree(tls, db, zSql)
|
|
if rc == SQLITE_OK {
|
|
_sqlite3AnalysisLoad(tls, db, iDb)
|
|
}
|
|
if (*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0 {
|
|
rc = int32(SQLITE_NOMEM)
|
|
_sqlite3ResetAllSchemasOfConnection(tls, db)
|
|
pDb = (*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(iDb)*32
|
|
} else {
|
|
if rc == SQLITE_OK || (*Tsqlite3)(unsafe.Pointer(db)).Fflags&uint64(SQLITE_NoSchemaError) != 0 && rc != int32(SQLITE_NOMEM) {
|
|
/* Hack: If the SQLITE_NoSchemaError flag is set, then consider
|
|
** the schema loaded, even if errors (other than OOM) occurred. In
|
|
** this situation the current sqlite3_prepare() operation will fail,
|
|
** but the following one will attempt to compile the supplied statement
|
|
** against whatever subset of the schema was loaded before the error
|
|
** occurred.
|
|
**
|
|
** The primary purpose of this is to allow access to the sqlite_schema
|
|
** table even when its contents have been corrupted.
|
|
*/
|
|
v1 = (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(iDb)*32))).FpSchema + 114
|
|
*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) | libc.Int32FromInt32(DB_SchemaLoaded))
|
|
rc = SQLITE_OK
|
|
}
|
|
}
|
|
/* Jump here for an error that occurs after successfully allocating
|
|
** curMain and calling sqlite3BtreeEnter(). For an error that occurs
|
|
** before that point, jump to error_out.
|
|
*/
|
|
goto initone_error_out
|
|
initone_error_out:
|
|
;
|
|
if openedTransaction != 0 {
|
|
_sqlite3BtreeCommit(tls, (*TDb)(unsafe.Pointer(pDb)).FpBt)
|
|
}
|
|
_sqlite3BtreeLeave(tls, (*TDb)(unsafe.Pointer(pDb)).FpBt)
|
|
goto error_out
|
|
error_out:
|
|
;
|
|
if rc != 0 {
|
|
if rc == int32(SQLITE_NOMEM) || rc == libc.Int32FromInt32(SQLITE_IOERR)|libc.Int32FromInt32(12)<<libc.Int32FromInt32(8) {
|
|
_sqlite3OomFault(tls, db)
|
|
}
|
|
_sqlite3ResetOneSchema(tls, db, iDb)
|
|
}
|
|
(*Tsqlite3)(unsafe.Pointer(db)).Finit1.Fbusy = uint8(0)
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Given 1 to 3 identifiers preceding the JOIN keyword, determine the
|
|
// ** type of join. Return an integer constant that expresses that type
|
|
// ** in terms of the following bit values:
|
|
// **
|
|
// ** JT_INNER
|
|
// ** JT_CROSS
|
|
// ** JT_OUTER
|
|
// ** JT_NATURAL
|
|
// ** JT_LEFT
|
|
// ** JT_RIGHT
|
|
// **
|
|
// ** A full outer join is the combination of JT_LEFT and JT_RIGHT.
|
|
// **
|
|
// ** If an illegal or unsupported join type is seen, then still return
|
|
// ** a join type, but put an error in the pParse structure.
|
|
// **
|
|
// ** These are the valid join types:
|
|
// **
|
|
// **
|
|
// ** pA pB pC Return Value
|
|
// ** ------- ----- ----- ------------
|
|
// ** CROSS - - JT_CROSS
|
|
// ** INNER - - JT_INNER
|
|
// ** LEFT - - JT_LEFT|JT_OUTER
|
|
// ** LEFT OUTER - JT_LEFT|JT_OUTER
|
|
// ** RIGHT - - JT_RIGHT|JT_OUTER
|
|
// ** RIGHT OUTER - JT_RIGHT|JT_OUTER
|
|
// ** FULL - - JT_LEFT|JT_RIGHT|JT_OUTER
|
|
// ** FULL OUTER - JT_LEFT|JT_RIGHT|JT_OUTER
|
|
// ** NATURAL INNER - JT_NATURAL|JT_INNER
|
|
// ** NATURAL LEFT - JT_NATURAL|JT_LEFT|JT_OUTER
|
|
// ** NATURAL LEFT OUTER JT_NATURAL|JT_LEFT|JT_OUTER
|
|
// ** NATURAL RIGHT - JT_NATURAL|JT_RIGHT|JT_OUTER
|
|
// ** NATURAL RIGHT OUTER JT_NATURAL|JT_RIGHT|JT_OUTER
|
|
// ** NATURAL FULL - JT_NATURAL|JT_LEFT|JT_RIGHT
|
|
// ** NATURAL FULL OUTER JT_NATRUAL|JT_LEFT|JT_RIGHT
|
|
// **
|
|
// ** To preserve historical compatibly, SQLite also accepts a variety
|
|
// ** of other non-standard and in many cases nonsensical join types.
|
|
// ** This routine makes as much sense at it can from the nonsense join
|
|
// ** type and returns a result. Examples of accepted nonsense join types
|
|
// ** include but are not limited to:
|
|
// **
|
|
// ** INNER CROSS JOIN -> same as JOIN
|
|
// ** NATURAL CROSS JOIN -> same as NATURAL JOIN
|
|
// ** OUTER LEFT JOIN -> same as LEFT JOIN
|
|
// ** LEFT NATURAL JOIN -> same as NATURAL LEFT JOIN
|
|
// ** LEFT RIGHT JOIN -> same as FULL JOIN
|
|
// ** RIGHT OUTER FULL JOIN -> same as FULL JOIN
|
|
// ** CROSS CROSS CROSS JOIN -> same as JOIN
|
|
// **
|
|
// ** The only restrictions on the join type name are:
|
|
// **
|
|
// ** * "INNER" cannot appear together with "OUTER", "LEFT", "RIGHT",
|
|
// ** or "FULL".
|
|
// **
|
|
// ** * "CROSS" cannot appear together with "OUTER", "LEFT", "RIGHT,
|
|
// ** or "FULL".
|
|
// **
|
|
// ** * If "OUTER" is present then there must also be one of
|
|
// ** "LEFT", "RIGHT", or "FULL"
|
|
// */
|
|
func _sqlite3JoinType(tls *libc.TLS, pParse uintptr, pA uintptr, pB uintptr, pC uintptr) (r int32) {
|
|
bp := tls.Alloc(48)
|
|
defer tls.Free(48)
|
|
var apAll [3]uintptr
|
|
var i, j, jointype int32
|
|
var p, zSp1, zSp2 uintptr
|
|
_, _, _, _, _, _, _ = apAll, i, j, jointype, p, zSp1, zSp2
|
|
jointype = 0
|
|
apAll[0] = pA
|
|
apAll[int32(1)] = pB
|
|
apAll[int32(2)] = pC
|
|
i = 0
|
|
for {
|
|
if !(i < int32(3) && apAll[i] != 0) {
|
|
break
|
|
}
|
|
p = apAll[i]
|
|
j = 0
|
|
for {
|
|
if !(j < libc.Int32FromUint64(libc.Uint64FromInt64(21)/libc.Uint64FromInt64(3))) {
|
|
break
|
|
}
|
|
if (*TToken)(unsafe.Pointer(p)).Fn == uint32(_aKeyword[j].FnChar) && Xsqlite3_strnicmp(tls, (*TToken)(unsafe.Pointer(p)).Fz, uintptr(unsafe.Pointer(&_zKeyText))+uintptr(_aKeyword[j].Fi), libc.Int32FromUint32((*TToken)(unsafe.Pointer(p)).Fn)) == 0 {
|
|
jointype = jointype | libc.Int32FromUint8(_aKeyword[j].Fcode)
|
|
break
|
|
}
|
|
goto _2
|
|
_2:
|
|
;
|
|
j = j + 1
|
|
}
|
|
if j >= libc.Int32FromUint64(libc.Uint64FromInt64(21)/libc.Uint64FromInt64(3)) {
|
|
jointype = jointype | int32(JT_ERROR)
|
|
break
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
if jointype&(libc.Int32FromInt32(JT_INNER)|libc.Int32FromInt32(JT_OUTER)) == libc.Int32FromInt32(JT_INNER)|libc.Int32FromInt32(JT_OUTER) || jointype&int32(JT_ERROR) != 0 || jointype&(libc.Int32FromInt32(JT_OUTER)|libc.Int32FromInt32(JT_LEFT)|libc.Int32FromInt32(JT_RIGHT)) == int32(JT_OUTER) {
|
|
zSp1 = __ccgo_ts + 11569
|
|
zSp2 = __ccgo_ts + 11569
|
|
if pB == uintptr(0) {
|
|
zSp1 = zSp1 + 1
|
|
}
|
|
if pC == uintptr(0) {
|
|
zSp2 = zSp2 + 1
|
|
}
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+20312, libc.VaList(bp+8, pA, zSp1, pB, zSp2, pC))
|
|
jointype = int32(JT_INNER)
|
|
}
|
|
return jointype
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Like malloc(), but remember the size of the allocation
|
|
// ** so that we can find it later using sqlite3MemSize().
|
|
// **
|
|
// ** For this low-level routine, we are guaranteed that nByte>0 because
|
|
// ** cases of nByte<=0 will be intercepted and dealt with by higher level
|
|
// ** routines.
|
|
// */
|
|
func _sqlite3MemMalloc(tls *libc.TLS, nByte int32) (r uintptr) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var p uintptr
|
|
_ = p
|
|
p = libc.Xmalloc(tls, libc.Uint64FromInt32(nByte+int32(8)))
|
|
if p != 0 {
|
|
**(**Tsqlite3_int64)(__ccgo_up(p)) = int64(nByte)
|
|
p += 8
|
|
} else {
|
|
Xsqlite3_log(tls, int32(SQLITE_NOMEM), __ccgo_ts+1600, libc.VaList(bp+8, nByte))
|
|
}
|
|
return p
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Like realloc(). Resize an allocation previously obtained from
|
|
// ** sqlite3MemMalloc().
|
|
// **
|
|
// ** For this low-level interface, we know that pPrior!=0. Cases where
|
|
// ** pPrior==0 while have been intercepted by higher-level routine and
|
|
// ** redirected to xMalloc. Similarly, we know that nByte>0 because
|
|
// ** cases where nByte<=0 will have been intercepted by higher-level
|
|
// ** routines and redirected to xFree.
|
|
// */
|
|
func _sqlite3MemRealloc(tls *libc.TLS, pPrior uintptr, nByte int32) (r uintptr) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var p uintptr
|
|
_ = p
|
|
p = pPrior
|
|
/* EV: R-46199-30249 */
|
|
p -= 8
|
|
p = libc.Xrealloc(tls, p, libc.Uint64FromInt32(nByte+libc.Int32FromInt32(8)))
|
|
if p != 0 {
|
|
**(**Tsqlite3_int64)(__ccgo_up(p)) = int64(nByte)
|
|
p += 8
|
|
} else {
|
|
Xsqlite3_log(tls, int32(SQLITE_NOMEM), __ccgo_ts+1638, libc.VaList(bp+8, _sqlite3MemSize(tls, pPrior), nByte))
|
|
}
|
|
return p
|
|
}
|
|
|
|
func _sqlite3MutexInit(tls *libc.TLS) (r int32) {
|
|
mu.Lock()
|
|
defer mu.Unlock()
|
|
var pFrom, pTo uintptr
|
|
var rc int32
|
|
_, _, _ = pFrom, pTo, rc
|
|
rc = SQLITE_OK
|
|
if !(_sqlite3Config.Fmutex.FxMutexAlloc != 0) {
|
|
pTo = uintptr(unsafe.Pointer(&_sqlite3Config)) + 96
|
|
if _sqlite3Config.FbCoreMutex != 0 {
|
|
pFrom = _sqlite3DefaultMutex(tls)
|
|
} else {
|
|
pFrom = _sqlite3NoopMutex(tls)
|
|
}
|
|
(*Tsqlite3_mutex_methods)(unsafe.Pointer(pTo)).FxMutexInit = (*Tsqlite3_mutex_methods)(unsafe.Pointer(pFrom)).FxMutexInit
|
|
(*Tsqlite3_mutex_methods)(unsafe.Pointer(pTo)).FxMutexEnd = (*Tsqlite3_mutex_methods)(unsafe.Pointer(pFrom)).FxMutexEnd
|
|
(*Tsqlite3_mutex_methods)(unsafe.Pointer(pTo)).FxMutexFree = (*Tsqlite3_mutex_methods)(unsafe.Pointer(pFrom)).FxMutexFree
|
|
(*Tsqlite3_mutex_methods)(unsafe.Pointer(pTo)).FxMutexEnter = (*Tsqlite3_mutex_methods)(unsafe.Pointer(pFrom)).FxMutexEnter
|
|
(*Tsqlite3_mutex_methods)(unsafe.Pointer(pTo)).FxMutexTry = (*Tsqlite3_mutex_methods)(unsafe.Pointer(pFrom)).FxMutexTry
|
|
(*Tsqlite3_mutex_methods)(unsafe.Pointer(pTo)).FxMutexLeave = (*Tsqlite3_mutex_methods)(unsafe.Pointer(pFrom)).FxMutexLeave
|
|
(*Tsqlite3_mutex_methods)(unsafe.Pointer(pTo)).FxMutexHeld = (*Tsqlite3_mutex_methods)(unsafe.Pointer(pFrom)).FxMutexHeld
|
|
(*Tsqlite3_mutex_methods)(unsafe.Pointer(pTo)).FxMutexNotheld = (*Tsqlite3_mutex_methods)(unsafe.Pointer(pFrom)).FxMutexNotheld
|
|
_sqlite3MemoryBarrier(tls)
|
|
(*Tsqlite3_mutex_methods)(unsafe.Pointer(pTo)).FxMutexAlloc = (*Tsqlite3_mutex_methods)(unsafe.Pointer(pFrom)).FxMutexAlloc
|
|
}
|
|
rc = (*(*func(*libc.TLS) int32)(unsafe.Pointer(&struct{ uintptr }{_sqlite3Config.Fmutex.FxMutexInit})))(tls)
|
|
_sqlite3MemoryBarrier(tls)
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Cause a function to throw an error if it was call from OP_PureFunc
|
|
// ** rather than OP_Function.
|
|
// **
|
|
// ** OP_PureFunc means that the function must be deterministic, and should
|
|
// ** throw an error if it is given inputs that would make it non-deterministic.
|
|
// ** This routine is invoked by date/time functions that use non-deterministic
|
|
// ** features such as 'now'.
|
|
// */
|
|
func _sqlite3NotPureFunc(tls *libc.TLS, pCtx uintptr) (r int32) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var pOp, zContext, zMsg uintptr
|
|
_, _, _ = pOp, zContext, zMsg
|
|
if (*Tsqlite3_context)(unsafe.Pointer(pCtx)).FpVdbe == uintptr(0) {
|
|
return int32(1)
|
|
}
|
|
pOp = (*TVdbe)(unsafe.Pointer((*Tsqlite3_context)(unsafe.Pointer(pCtx)).FpVdbe)).FaOp + uintptr((*Tsqlite3_context)(unsafe.Pointer(pCtx)).FiOp)*24
|
|
if libc.Int32FromUint8((*TVdbeOp)(unsafe.Pointer(pOp)).Fopcode) == int32(OP_PureFunc) {
|
|
if libc.Int32FromUint16((*TVdbeOp)(unsafe.Pointer(pOp)).Fp5)&int32(NC_IsCheck) != 0 {
|
|
zContext = __ccgo_ts + 5450
|
|
} else {
|
|
if libc.Int32FromUint16((*TVdbeOp)(unsafe.Pointer(pOp)).Fp5)&int32(NC_GenCol) != 0 {
|
|
zContext = __ccgo_ts + 5469
|
|
} else {
|
|
zContext = __ccgo_ts + 5488
|
|
}
|
|
}
|
|
zMsg = Xsqlite3_mprintf(tls, __ccgo_ts+5497, libc.VaList(bp+8, (*TFuncDef)(unsafe.Pointer((*Tsqlite3_context)(unsafe.Pointer(pCtx)).FpFunc)).FzName, zContext))
|
|
Xsqlite3_result_error(tls, pCtx, zMsg, -int32(1))
|
|
Xsqlite3_free(tls, zMsg)
|
|
return 0
|
|
}
|
|
return int32(1)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Call this routine to record the fact that an OOM (out-of-memory) error
|
|
// ** has happened. This routine will set db->mallocFailed, and also
|
|
// ** temporarily disable the lookaside memory allocator and interrupt
|
|
// ** any running VDBEs.
|
|
// **
|
|
// ** Always return a NULL pointer so that this routine can be invoked using
|
|
// **
|
|
// ** return sqlite3OomFault(db);
|
|
// **
|
|
// ** and thereby avoid unnecessary stack frame allocations for the overwhelmingly
|
|
// ** common case where no OOM occurs.
|
|
// */
|
|
func _sqlite3OomFault(tls *libc.TLS, db uintptr) (r uintptr) {
|
|
var pParse uintptr
|
|
_ = pParse
|
|
if libc.Int32FromUint8((*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed) == 0 && libc.Int32FromUint8((*Tsqlite3)(unsafe.Pointer(db)).FbBenignMalloc) == 0 {
|
|
(*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed = uint8(1)
|
|
if (*Tsqlite3)(unsafe.Pointer(db)).FnVdbeExec > 0 {
|
|
libc.AtomicStoreNInt32(db+432, libc.Int32FromInt32(1), libc.Int32FromInt32(__ATOMIC_RELAXED))
|
|
}
|
|
(*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FbDisable = (*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FbDisable + 1
|
|
(*Tsqlite3)(unsafe.Pointer(db)).Flookaside.Fsz = uint16(0)
|
|
if (*Tsqlite3)(unsafe.Pointer(db)).FpParse != 0 {
|
|
_sqlite3ErrorMsg(tls, (*Tsqlite3)(unsafe.Pointer(db)).FpParse, __ccgo_ts+1674, 0)
|
|
(*TParse)(unsafe.Pointer((*Tsqlite3)(unsafe.Pointer(db)).FpParse)).Frc = int32(SQLITE_NOMEM)
|
|
pParse = (*TParse)(unsafe.Pointer((*Tsqlite3)(unsafe.Pointer(db)).FpParse)).FpOuterParse
|
|
for {
|
|
if !(pParse != 0) {
|
|
break
|
|
}
|
|
(*TParse)(unsafe.Pointer(pParse)).FnErr = (*TParse)(unsafe.Pointer(pParse)).FnErr + 1
|
|
(*TParse)(unsafe.Pointer(pParse)).Frc = int32(SQLITE_NOMEM)
|
|
goto _1
|
|
_1:
|
|
;
|
|
pParse = (*TParse)(unsafe.Pointer(pParse)).FpOuterParse
|
|
}
|
|
}
|
|
}
|
|
return uintptr(0)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Make sure the TEMP database is open and available for use. Return
|
|
// ** the number of errors. Leave any error messages in the pParse structure.
|
|
// */
|
|
func _sqlite3OpenTempDatabase(tls *libc.TLS, pParse uintptr) (r int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var db uintptr
|
|
var rc int32
|
|
var _ /* pBt at bp+0 */ uintptr
|
|
_, _ = db, rc
|
|
db = (*TParse)(unsafe.Pointer(pParse)).Fdb
|
|
if (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + 1*32))).FpBt == uintptr(0) && !((*TParse)(unsafe.Pointer(pParse)).Fexplain != 0) {
|
|
rc = _sqlite3BtreeOpen(tls, (*Tsqlite3)(unsafe.Pointer(db)).FpVfs, uintptr(0), db, bp, 0, _flags)
|
|
if rc != SQLITE_OK {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+16161, 0)
|
|
(*TParse)(unsafe.Pointer(pParse)).Frc = rc
|
|
return int32(1)
|
|
}
|
|
(**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + 1*32))).FpBt = **(**uintptr)(__ccgo_up(bp))
|
|
if int32(SQLITE_NOMEM) == _sqlite3BtreeSetPageSize(tls, **(**uintptr)(__ccgo_up(bp)), (*Tsqlite3)(unsafe.Pointer(db)).FnextPagesize, 0, 0) {
|
|
_sqlite3OomFault(tls, db)
|
|
return int32(1)
|
|
}
|
|
}
|
|
return 0
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Turn bulk memory into a valid Parse object and link that Parse object
|
|
// ** into database connection db.
|
|
// **
|
|
// ** Call sqlite3ParseObjectReset() to undo this operation.
|
|
// **
|
|
// ** Caution: Do not confuse this routine with sqlite3ParseObjectInit() which
|
|
// ** is generated by Lemon.
|
|
// */
|
|
func _sqlite3ParseObjectInit(tls *libc.TLS, pParse uintptr, db uintptr) {
|
|
libc.Xmemset(tls, pParse+uintptr(uint64(libc.UintptrFromInt32(0)+8)), 0, uint64(libc.UintptrFromInt32(0)+192)-uint64(libc.UintptrFromInt32(0)+8))
|
|
libc.Xmemset(tls, pParse+uintptr(uint64(libc.UintptrFromInt32(0)+288)), 0, libc.Uint64FromInt64(424)-uint64(libc.UintptrFromInt32(0)+288))
|
|
(*TParse)(unsafe.Pointer(pParse)).FpOuterParse = (*Tsqlite3)(unsafe.Pointer(db)).FpParse
|
|
(*Tsqlite3)(unsafe.Pointer(db)).FpParse = pParse
|
|
(*TParse)(unsafe.Pointer(pParse)).Fdb = db
|
|
if (*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0 {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+1674, 0)
|
|
}
|
|
}
|
|
|
|
/*
|
|
** Maximum number of times that we will try again to prepare a statement
|
|
** that returns SQLITE_ERROR_RETRY.
|
|
*/
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Check every term in the ORDER BY or GROUP BY clause pOrderBy of
|
|
// ** the SELECT statement pSelect. If any term is reference to a
|
|
// ** result set expression (as determined by the ExprList.a.u.x.iOrderByCol
|
|
// ** field) then convert that term into a copy of the corresponding result set
|
|
// ** column.
|
|
// **
|
|
// ** If any errors are detected, add an error message to pParse and
|
|
// ** return non-zero. Return zero if no errors are seen.
|
|
// */
|
|
func _sqlite3ResolveOrderGroupBy(tls *libc.TLS, pParse uintptr, pSelect uintptr, pOrderBy uintptr, zType uintptr) (r int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var db, pEList, pItem uintptr
|
|
var i int32
|
|
_, _, _, _ = db, i, pEList, pItem
|
|
db = (*TParse)(unsafe.Pointer(pParse)).Fdb
|
|
if pOrderBy == uintptr(0) || (*Tsqlite3)(unsafe.Pointer((*TParse)(unsafe.Pointer(pParse)).Fdb)).FmallocFailed != 0 || libc.Int32FromUint8((*TParse)(unsafe.Pointer(pParse)).FeParseMode) >= int32(PARSE_MODE_RENAME) {
|
|
return 0
|
|
}
|
|
if (*TExprList)(unsafe.Pointer(pOrderBy)).FnExpr > **(**int32)(__ccgo_up(db + 136 + 2*4)) {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+7754, libc.VaList(bp+8, zType))
|
|
return int32(1)
|
|
}
|
|
pEList = (*TSelect)(unsafe.Pointer(pSelect)).FpEList
|
|
/* sqlite3SelectNew() guarantees this */
|
|
i = 0
|
|
pItem = pOrderBy + 8
|
|
for {
|
|
if !(i < (*TExprList)(unsafe.Pointer(pOrderBy)).FnExpr) {
|
|
break
|
|
}
|
|
if (*(*struct {
|
|
FiOrderByCol Tu16
|
|
FiAlias Tu16
|
|
})(unsafe.Pointer(pItem + 24))).FiOrderByCol != 0 {
|
|
if libc.Int32FromUint16((*(*struct {
|
|
FiOrderByCol Tu16
|
|
FiAlias Tu16
|
|
})(unsafe.Pointer(pItem + 24))).FiOrderByCol) > (*TExprList)(unsafe.Pointer(pEList)).FnExpr {
|
|
_resolveOutOfRangeError(tls, pParse, zType, i+int32(1), (*TExprList)(unsafe.Pointer(pEList)).FnExpr, uintptr(0))
|
|
return int32(1)
|
|
}
|
|
_resolveAlias(tls, pParse, pEList, libc.Int32FromUint16((*(*struct {
|
|
FiOrderByCol Tu16
|
|
FiAlias Tu16
|
|
})(unsafe.Pointer(pItem + 24))).FiOrderByCol)-int32(1), (*TExprList_item)(unsafe.Pointer(pItem)).FpExpr, 0)
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
pItem += 32
|
|
}
|
|
return 0
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Return a pointer to a buffer containing a usable rowid alias for table
|
|
// ** pTab. An alias is usable if there is not an explicit user-defined column
|
|
// ** of the same name.
|
|
// */
|
|
func _sqlite3RowidAlias(tls *libc.TLS, pTab uintptr) (r uintptr) {
|
|
var azOpt [3]uintptr
|
|
var ii int32
|
|
_, _ = azOpt, ii
|
|
azOpt = [3]uintptr{
|
|
0: __ccgo_ts + 8217,
|
|
1: __ccgo_ts + 8225,
|
|
2: __ccgo_ts + 8231,
|
|
}
|
|
ii = 0
|
|
for {
|
|
if !(ii < libc.Int32FromUint64(libc.Uint64FromInt64(24)/libc.Uint64FromInt64(8))) {
|
|
break
|
|
}
|
|
if _sqlite3ColumnIndex(tls, pTab, azOpt[ii]) < 0 {
|
|
return azOpt[ii]
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
ii = ii + 1
|
|
}
|
|
return uintptr(0)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Code an OP_Halt due to non-unique rowid.
|
|
// */
|
|
func _sqlite3RowidConstraint(tls *libc.TLS, pParse uintptr, onError int32, pTab uintptr) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var rc int32
|
|
var zMsg uintptr
|
|
_, _ = rc, zMsg
|
|
if int32((*TTable)(unsafe.Pointer(pTab)).FiPKey) >= 0 {
|
|
zMsg = _sqlite3MPrintf(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, __ccgo_ts+13660, libc.VaList(bp+8, (*TTable)(unsafe.Pointer(pTab)).FzName, (**(**TColumn)(__ccgo_up((*TTable)(unsafe.Pointer(pTab)).FaCol + uintptr((*TTable)(unsafe.Pointer(pTab)).FiPKey)*16))).FzCnName))
|
|
rc = libc.Int32FromInt32(SQLITE_CONSTRAINT) | libc.Int32FromInt32(6)<<libc.Int32FromInt32(8)
|
|
} else {
|
|
zMsg = _sqlite3MPrintf(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, __ccgo_ts+16245, libc.VaList(bp+8, (*TTable)(unsafe.Pointer(pTab)).FzName))
|
|
rc = libc.Int32FromInt32(SQLITE_CONSTRAINT) | libc.Int32FromInt32(10)<<libc.Int32FromInt32(8)
|
|
}
|
|
_sqlite3HaltConstraint(tls, pParse, rc, onError, zMsg, int8(-libc.Int32FromInt32(7)), uint8(P5_ConstraintUnique))
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Expand the space allocated for the given SrcList object by
|
|
// ** creating nExtra new slots beginning at iStart. iStart is zero based.
|
|
// ** New slots are zeroed.
|
|
// **
|
|
// ** For example, suppose a SrcList initially contains two entries: A,B.
|
|
// ** To append 3 new entries onto the end, do this:
|
|
// **
|
|
// ** sqlite3SrcListEnlarge(db, pSrclist, 3, 2);
|
|
// **
|
|
// ** After the call above it would contain: A, B, nil, nil, nil.
|
|
// ** If the iStart argument had been 1 instead of 2, then the result
|
|
// ** would have been: A, nil, nil, nil, B. To prepend the new slots,
|
|
// ** the iStart value would be 0. The result then would
|
|
// ** be: nil, nil, nil, A, B.
|
|
// **
|
|
// ** If a memory allocation fails or the SrcList becomes too large, leave
|
|
// ** the original SrcList unchanged, return NULL, and leave an error message
|
|
// ** in pParse.
|
|
// */
|
|
func _sqlite3SrcListEnlarge(tls *libc.TLS, pParse uintptr, pSrc uintptr, nExtra int32, iStart int32) (r uintptr) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var db, pNew uintptr
|
|
var i int32
|
|
var nAlloc Tsqlite3_int64
|
|
_, _, _, _ = db, i, nAlloc, pNew
|
|
/* Sanity checking on calling parameters */
|
|
/* Allocate additional space if needed */
|
|
if libc.Uint32FromInt32((*TSrcList)(unsafe.Pointer(pSrc)).FnSrc)+libc.Uint32FromInt32(nExtra) > (*TSrcList)(unsafe.Pointer(pSrc)).FnAlloc {
|
|
nAlloc = int64(2)*int64((*TSrcList)(unsafe.Pointer(pSrc)).FnSrc) + int64(nExtra)
|
|
db = (*TParse)(unsafe.Pointer(pParse)).Fdb
|
|
if (*TSrcList)(unsafe.Pointer(pSrc)).FnSrc+nExtra >= int32(SQLITE_MAX_SRCLIST) {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+16050, libc.VaList(bp+8, int32(SQLITE_MAX_SRCLIST)))
|
|
return uintptr(0)
|
|
}
|
|
if nAlloc > int64(SQLITE_MAX_SRCLIST) {
|
|
nAlloc = int64(SQLITE_MAX_SRCLIST)
|
|
}
|
|
pNew = _sqlite3DbRealloc(tls, db, pSrc, uint64(libc.UintptrFromInt32(0)+8)+libc.Uint64FromInt64(nAlloc)*libc.Uint64FromInt64(80))
|
|
if pNew == uintptr(0) {
|
|
return uintptr(0)
|
|
}
|
|
pSrc = pNew
|
|
(*TSrcList)(unsafe.Pointer(pSrc)).FnAlloc = libc.Uint32FromInt64(nAlloc)
|
|
}
|
|
/* Move existing slots that come after the newly inserted slots
|
|
** out of the way */
|
|
i = (*TSrcList)(unsafe.Pointer(pSrc)).FnSrc - int32(1)
|
|
for {
|
|
if !(i >= iStart) {
|
|
break
|
|
}
|
|
*(*TSrcItem)(unsafe.Pointer(pSrc + 8 + uintptr(i+nExtra)*80)) = *(*TSrcItem)(unsafe.Pointer(pSrc + 8 + uintptr(i)*80))
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i - 1
|
|
}
|
|
**(**int32)(__ccgo_up(pSrc)) += nExtra
|
|
/* Zero the newly allocated slots */
|
|
libc.Xmemset(tls, pSrc+8+uintptr(iStart)*80, 0, uint64(80)*libc.Uint64FromInt32(nExtra))
|
|
i = iStart
|
|
for {
|
|
if !(i < iStart+nExtra) {
|
|
break
|
|
}
|
|
(*(*TSrcItem)(unsafe.Pointer(pSrc + 8 + uintptr(i)*80))).FiCursor = -int32(1)
|
|
goto _2
|
|
_2:
|
|
;
|
|
i = i + 1
|
|
}
|
|
/* Return a pointer to the enlarged SrcList */
|
|
return pSrc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /* Create a new thread */
|
|
func _sqlite3ThreadCreate(tls *libc.TLS, ppThread uintptr, __ccgo_fp_xTask uintptr, pIn uintptr) (r int32) {
|
|
var p uintptr
|
|
var rc int32
|
|
_, _ = p, rc
|
|
/* This routine is never used in single-threaded mode */
|
|
**(**uintptr)(__ccgo_up(ppThread)) = uintptr(0)
|
|
p = _sqlite3Malloc(tls, uint64(40))
|
|
if p == uintptr(0) {
|
|
return int32(SQLITE_NOMEM)
|
|
}
|
|
libc.Xmemset(tls, p, 0, uint64(40))
|
|
(*TSQLiteThread)(unsafe.Pointer(p)).FxTask = __ccgo_fp_xTask
|
|
(*TSQLiteThread)(unsafe.Pointer(p)).FpIn = pIn
|
|
/* If the SQLITE_TESTCTRL_FAULT_INSTALL callback is registered to a
|
|
** function that returns SQLITE_ERROR when passed the argument 200, that
|
|
** forces worker threads to run sequentially and deterministically
|
|
** for testing purposes. */
|
|
if _sqlite3FaultSim(tls, int32(200)) != 0 {
|
|
rc = int32(1)
|
|
} else {
|
|
rc = libc.Xpthread_create(tls, p, uintptr(0), __ccgo_fp_xTask, pIn)
|
|
}
|
|
if rc != 0 {
|
|
(*TSQLiteThread)(unsafe.Pointer(p)).Fdone = int32(1)
|
|
(*TSQLiteThread)(unsafe.Pointer(p)).FpOut = (*(*func(*libc.TLS, uintptr) uintptr)(unsafe.Pointer(&struct{ uintptr }{__ccgo_fp_xTask})))(tls, pIn)
|
|
}
|
|
**(**uintptr)(__ccgo_up(ppThread)) = p
|
|
return SQLITE_OK
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Compute a string that describes the P4 parameter for an opcode.
|
|
// ** Use zTemp for any required temporary buffer space.
|
|
// */
|
|
func _sqlite3VdbeDisplayP4(tls *libc.TLS, db uintptr, pOp uintptr) (r uintptr) {
|
|
bp := tls.Alloc(64)
|
|
defer tls.Free(64)
|
|
var ai, pColl, pColl1, pDef, pDef1, pKeyInfo, pMem, pSig, pVtab, zColl, zP4, v2, v3 uintptr
|
|
var i, n Tu32
|
|
var j, v6 int32
|
|
var _ /* x at bp+0 */ TStrAccum
|
|
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = ai, i, j, n, pColl, pColl1, pDef, pDef1, pKeyInfo, pMem, pSig, pVtab, zColl, zP4, v2, v3, v6
|
|
zP4 = uintptr(0)
|
|
_sqlite3StrAccumInit(tls, bp, uintptr(0), uintptr(0), 0, int32(SQLITE_MAX_LENGTH))
|
|
switch int32((*TOp)(unsafe.Pointer(pOp)).Fp4type) {
|
|
case -int32(9):
|
|
pKeyInfo = *(*uintptr)(unsafe.Pointer(pOp + 16))
|
|
Xsqlite3_str_appendf(tls, bp, __ccgo_ts+5260, libc.VaList(bp+40, libc.Int32FromUint16((*TKeyInfo)(unsafe.Pointer(pKeyInfo)).FnKeyField)))
|
|
j = 0
|
|
for {
|
|
if !(j < libc.Int32FromUint16((*TKeyInfo)(unsafe.Pointer(pKeyInfo)).FnKeyField)) {
|
|
break
|
|
}
|
|
pColl = *(*uintptr)(unsafe.Pointer(pKeyInfo + 32 + uintptr(j)*8))
|
|
if pColl != 0 {
|
|
v2 = (*TCollSeq)(unsafe.Pointer(pColl)).FzName
|
|
} else {
|
|
v2 = __ccgo_ts + 1704
|
|
}
|
|
zColl = v2
|
|
if libc.Xstrcmp(tls, zColl, __ccgo_ts+5265) == 0 {
|
|
zColl = __ccgo_ts + 5272
|
|
}
|
|
if libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TKeyInfo)(unsafe.Pointer(pKeyInfo)).FaSortFlags + uintptr(j))))&int32(KEYINFO_ORDER_DESC) != 0 {
|
|
v2 = __ccgo_ts + 5253
|
|
} else {
|
|
v2 = __ccgo_ts + 1704
|
|
}
|
|
if libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TKeyInfo)(unsafe.Pointer(pKeyInfo)).FaSortFlags + uintptr(j))))&int32(KEYINFO_ORDER_BIGNULL) != 0 {
|
|
v3 = __ccgo_ts + 5274
|
|
} else {
|
|
v3 = __ccgo_ts + 1704
|
|
}
|
|
Xsqlite3_str_appendf(tls, bp, __ccgo_ts+5277, libc.VaList(bp+40, v2, v3, zColl))
|
|
goto _1
|
|
_1:
|
|
;
|
|
j = j + 1
|
|
}
|
|
Xsqlite3_str_append(tls, bp, __ccgo_ts+5285, int32(1))
|
|
case -int32(2):
|
|
pColl1 = *(*uintptr)(unsafe.Pointer(pOp + 16))
|
|
Xsqlite3_str_appendf(tls, bp, __ccgo_ts+5301, libc.VaList(bp+40, (*TCollSeq)(unsafe.Pointer(pColl1)).FzName, _encnames[(*TCollSeq)(unsafe.Pointer(pColl1)).Fenc]))
|
|
case -int32(8):
|
|
pDef = *(*uintptr)(unsafe.Pointer(pOp + 16))
|
|
Xsqlite3_str_appendf(tls, bp, __ccgo_ts+5310, libc.VaList(bp+40, (*TFuncDef)(unsafe.Pointer(pDef)).FzName, int32((*TFuncDef)(unsafe.Pointer(pDef)).FnArg)))
|
|
case -int32(16):
|
|
pDef1 = (*Tsqlite3_context)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pOp + 16)))).FpFunc
|
|
Xsqlite3_str_appendf(tls, bp, __ccgo_ts+5310, libc.VaList(bp+40, (*TFuncDef)(unsafe.Pointer(pDef1)).FzName, int32((*TFuncDef)(unsafe.Pointer(pDef1)).FnArg)))
|
|
case -int32(14):
|
|
Xsqlite3_str_appendf(tls, bp, __ccgo_ts+1465, libc.VaList(bp+40, **(**Ti64)(__ccgo_up(*(*uintptr)(unsafe.Pointer(pOp + 16))))))
|
|
case -int32(3):
|
|
Xsqlite3_str_appendf(tls, bp, __ccgo_ts+5317, libc.VaList(bp+40, (*TOp)(unsafe.Pointer(pOp)).Fp4.Fi))
|
|
case -int32(13):
|
|
Xsqlite3_str_appendf(tls, bp, __ccgo_ts+1432, libc.VaList(bp+40, **(**float64)(__ccgo_up(*(*uintptr)(unsafe.Pointer(pOp + 16))))))
|
|
case -int32(11):
|
|
pMem = *(*uintptr)(unsafe.Pointer(pOp + 16))
|
|
if libc.Int32FromUint16((*TMem)(unsafe.Pointer(pMem)).Fflags)&int32(MEM_Str) != 0 {
|
|
zP4 = (*TMem)(unsafe.Pointer(pMem)).Fz
|
|
} else {
|
|
if libc.Int32FromUint16((*TMem)(unsafe.Pointer(pMem)).Fflags)&(libc.Int32FromInt32(MEM_Int)|libc.Int32FromInt32(MEM_IntReal)) != 0 {
|
|
Xsqlite3_str_appendf(tls, bp, __ccgo_ts+1465, libc.VaList(bp+40, *(*Ti64)(unsafe.Pointer(pMem))))
|
|
} else {
|
|
if libc.Int32FromUint16((*TMem)(unsafe.Pointer(pMem)).Fflags)&int32(MEM_Real) != 0 {
|
|
Xsqlite3_str_appendf(tls, bp, __ccgo_ts+1432, libc.VaList(bp+40, *(*float64)(unsafe.Pointer(pMem))))
|
|
} else {
|
|
if libc.Int32FromUint16((*TMem)(unsafe.Pointer(pMem)).Fflags)&int32(MEM_Null) != 0 {
|
|
zP4 = __ccgo_ts + 1705
|
|
} else {
|
|
zP4 = __ccgo_ts + 5320
|
|
}
|
|
}
|
|
}
|
|
}
|
|
case -int32(12):
|
|
pVtab = (*TVTable)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pOp + 16)))).FpVtab
|
|
Xsqlite3_str_appendf(tls, bp, __ccgo_ts+5327, libc.VaList(bp+40, pVtab))
|
|
case -int32(15):
|
|
ai = *(*uintptr)(unsafe.Pointer(pOp + 16))
|
|
n = **(**Tu32)(__ccgo_up(ai)) /* The first element of an INTARRAY is always the
|
|
** count of the number of elements to follow */
|
|
i = uint32(1)
|
|
for {
|
|
if !(i <= n) {
|
|
break
|
|
}
|
|
if i == uint32(1) {
|
|
v6 = int32('[')
|
|
} else {
|
|
v6 = int32(',')
|
|
}
|
|
Xsqlite3_str_appendf(tls, bp, __ccgo_ts+5335, libc.VaList(bp+40, v6, **(**Tu32)(__ccgo_up(ai + uintptr(i)*4))))
|
|
goto _5
|
|
_5:
|
|
;
|
|
i = i + 1
|
|
}
|
|
Xsqlite3_str_append(tls, bp, __ccgo_ts+5340, int32(1))
|
|
case -int32(4):
|
|
zP4 = __ccgo_ts + 5342
|
|
case -int32(5):
|
|
zP4 = (*TTable)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pOp + 16)))).FzName
|
|
case -int32(6):
|
|
zP4 = (*TIndex)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pOp + 16)))).FzName
|
|
case -int32(18):
|
|
pSig = *(*uintptr)(unsafe.Pointer(pOp + 16))
|
|
Xsqlite3_str_appendf(tls, bp, __ccgo_ts+5350, libc.VaList(bp+40, (*TSubrtnSig)(unsafe.Pointer(pSig)).FselId, (*TSubrtnSig)(unsafe.Pointer(pSig)).FzAff))
|
|
default:
|
|
zP4 = *(*uintptr)(unsafe.Pointer(pOp + 16))
|
|
}
|
|
if zP4 != 0 {
|
|
Xsqlite3_str_appendall(tls, bp, zP4)
|
|
}
|
|
if libc.Int32FromUint8((**(**TStrAccum)(__ccgo_up(bp))).FaccError)&int32(SQLITE_NOMEM) != 0 {
|
|
_sqlite3OomFault(tls, db)
|
|
}
|
|
return _sqlite3StrAccumFinish(tls, bp)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Set the value stored in *pMem should already be a NULL.
|
|
// ** Also store a pointer to go with it.
|
|
// */
|
|
func _sqlite3VdbeMemSetPointer(tls *libc.TLS, pMem uintptr, pPtr uintptr, zPType uintptr, __ccgo_fp_xDestructor uintptr) {
|
|
var v1 uintptr
|
|
_ = v1
|
|
_vdbeMemClear(tls, pMem)
|
|
if zPType != 0 {
|
|
v1 = zPType
|
|
} else {
|
|
v1 = __ccgo_ts + 1704
|
|
}
|
|
*(*uintptr)(unsafe.Pointer(pMem)) = v1
|
|
(*TMem)(unsafe.Pointer(pMem)).Fz = pPtr
|
|
(*TMem)(unsafe.Pointer(pMem)).Fflags = libc.Uint16FromInt32(libc.Int32FromInt32(MEM_Null) | libc.Int32FromInt32(MEM_Dyn) | libc.Int32FromInt32(MEM_Subtype) | libc.Int32FromInt32(MEM_Term))
|
|
(*TMem)(unsafe.Pointer(pMem)).FeSubtype = uint8('p')
|
|
if __ccgo_fp_xDestructor != 0 {
|
|
v1 = __ccgo_fp_xDestructor
|
|
} else {
|
|
v1 = __ccgo_fp(_sqlite3NoopDestructor)
|
|
}
|
|
(*TMem)(unsafe.Pointer(pMem)).FxDel = v1
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Expression pExpr is a vector that has been used in a context where
|
|
// ** it is not permitted. If pExpr is a sub-select vector, this routine
|
|
// ** loads the Parse object with a message of the form:
|
|
// **
|
|
// ** "sub-select returns N columns - expected 1"
|
|
// **
|
|
// ** Or, if it is a regular scalar vector:
|
|
// **
|
|
// ** "row value misused"
|
|
// */
|
|
func _sqlite3VectorErrorMsg(tls *libc.TLS, pParse uintptr, pExpr uintptr) {
|
|
if (*TExpr)(unsafe.Pointer(pExpr)).Fflags&uint32(EP_xIsSelect) != uint32(0) {
|
|
_sqlite3SubselectError(tls, pParse, (*TExprList)(unsafe.Pointer((*TSelect)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pExpr + 32)))).FpEList)).FnExpr, int32(1))
|
|
} else {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+6936, 0)
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This function is invoked by the parser to call the xConnect() method
|
|
// ** of the virtual table pTab. If an error occurs, an error code is returned
|
|
// ** and an error left in pParse.
|
|
// **
|
|
// ** This call is a no-op if table pTab is not a virtual table.
|
|
// */
|
|
func _sqlite3VtabCallConnect(tls *libc.TLS, pParse uintptr, pTab uintptr) (r int32) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var db, pMod, zMod, zModule uintptr
|
|
var rc int32
|
|
var _ /* zErr at bp+0 */ uintptr
|
|
_, _, _, _, _ = db, pMod, rc, zMod, zModule
|
|
db = (*TParse)(unsafe.Pointer(pParse)).Fdb
|
|
if _sqlite3GetVTable(tls, db, pTab) != 0 {
|
|
return SQLITE_OK
|
|
}
|
|
/* Locate the required virtual table module */
|
|
zMod = **(**uintptr)(__ccgo_up((*(*struct {
|
|
FnArg int32
|
|
FazArg uintptr
|
|
Fp uintptr
|
|
})(unsafe.Pointer(pTab + 64))).FazArg))
|
|
pMod = _sqlite3HashFind(tls, db+576, zMod)
|
|
if !(pMod != 0) {
|
|
zModule = **(**uintptr)(__ccgo_up((*(*struct {
|
|
FnArg int32
|
|
FazArg uintptr
|
|
Fp uintptr
|
|
})(unsafe.Pointer(pTab + 64))).FazArg))
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+23614, libc.VaList(bp+16, zModule))
|
|
rc = int32(SQLITE_ERROR)
|
|
} else {
|
|
**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
|
|
rc = _vtabCallConstructor(tls, db, pTab, pMod, (*Tsqlite3_module)(unsafe.Pointer((*TModule)(unsafe.Pointer(pMod)).FpModule)).FxConnect, bp)
|
|
if rc != SQLITE_OK {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+3968, libc.VaList(bp+16, **(**uintptr)(__ccgo_up(bp))))
|
|
(*TParse)(unsafe.Pointer(pParse)).Frc = rc
|
|
}
|
|
_sqlite3DbFree(tls, db, **(**uintptr)(__ccgo_up(bp)))
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This function is invoked by the vdbe to call the xCreate method
|
|
// ** of the virtual table named zTab in database iDb.
|
|
// **
|
|
// ** If an error occurs, *pzErr is set to point to an English language
|
|
// ** description of the error and an SQLITE_XXX error code is returned.
|
|
// ** In this case the caller must call sqlite3DbFree(db, ) on *pzErr.
|
|
// */
|
|
func _sqlite3VtabCallCreate(tls *libc.TLS, db uintptr, iDb int32, zTab uintptr, pzErr uintptr) (r int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var pMod, pTab, zMod uintptr
|
|
var rc int32
|
|
_, _, _, _ = pMod, pTab, rc, zMod
|
|
rc = SQLITE_OK
|
|
pTab = _sqlite3FindTable(tls, db, zTab, (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(iDb)*32))).FzDbSName)
|
|
/* Locate the required virtual table module */
|
|
zMod = **(**uintptr)(__ccgo_up((*(*struct {
|
|
FnArg int32
|
|
FazArg uintptr
|
|
Fp uintptr
|
|
})(unsafe.Pointer(pTab + 64))).FazArg))
|
|
pMod = _sqlite3HashFind(tls, db+576, zMod)
|
|
/* If the module has been registered and includes a Create method,
|
|
** invoke it now. If the module has not been registered, return an
|
|
** error. Otherwise, do nothing.
|
|
*/
|
|
if pMod == uintptr(0) || (*Tsqlite3_module)(unsafe.Pointer((*TModule)(unsafe.Pointer(pMod)).FpModule)).FxCreate == uintptr(0) || (*Tsqlite3_module)(unsafe.Pointer((*TModule)(unsafe.Pointer(pMod)).FpModule)).FxDestroy == uintptr(0) {
|
|
**(**uintptr)(__ccgo_up(pzErr)) = _sqlite3MPrintf(tls, db, __ccgo_ts+23614, libc.VaList(bp+8, zMod))
|
|
rc = int32(SQLITE_ERROR)
|
|
} else {
|
|
rc = _vtabCallConstructor(tls, db, pTab, pMod, (*Tsqlite3_module)(unsafe.Pointer((*TModule)(unsafe.Pointer(pMod)).FpModule)).FxCreate, pzErr)
|
|
}
|
|
/* Justification of ALWAYS(): The xConstructor method is required to
|
|
** create a valid sqlite3_vtab if it returns SQLITE_OK. */
|
|
if rc == SQLITE_OK && _sqlite3GetVTable(tls, db, pTab) != 0 {
|
|
rc = _growVTrans(tls, db)
|
|
if rc == SQLITE_OK {
|
|
_addToVTrans(tls, db, _sqlite3GetVTable(tls, db, pTab))
|
|
}
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Check to see if virtual table module pMod can be have an eponymous
|
|
// ** virtual table instance. If it can, create one if one does not already
|
|
// ** exist. Return non-zero if either the eponymous virtual table instance
|
|
// ** exists when this routine returns or if an attempt to create it failed
|
|
// ** and an error message was left in pParse.
|
|
// **
|
|
// ** An eponymous virtual table instance is one that is named after its
|
|
// ** module, and more importantly, does not require a CREATE VIRTUAL TABLE
|
|
// ** statement in order to come into existence. Eponymous virtual table
|
|
// ** instances always exist. They cannot be DROP-ed.
|
|
// **
|
|
// ** Any virtual table module for which xConnect and xCreate are the same
|
|
// ** method can have an eponymous virtual table instance.
|
|
// */
|
|
func _sqlite3VtabEponymousTableInit(tls *libc.TLS, pParse uintptr, pMod uintptr) (r int32) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var db, pModule, pTab uintptr
|
|
var rc int32
|
|
var _ /* zErr at bp+0 */ uintptr
|
|
_, _, _, _ = db, pModule, pTab, rc
|
|
pModule = (*TModule)(unsafe.Pointer(pMod)).FpModule
|
|
**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
|
|
db = (*TParse)(unsafe.Pointer(pParse)).Fdb
|
|
if (*TModule)(unsafe.Pointer(pMod)).FpEpoTab != 0 {
|
|
return int32(1)
|
|
}
|
|
if (*Tsqlite3_module)(unsafe.Pointer(pModule)).FxCreate != uintptr(0) && (*Tsqlite3_module)(unsafe.Pointer(pModule)).FxCreate != (*Tsqlite3_module)(unsafe.Pointer(pModule)).FxConnect {
|
|
return 0
|
|
}
|
|
pTab = _sqlite3DbMallocZero(tls, db, uint64(120))
|
|
if pTab == uintptr(0) {
|
|
return 0
|
|
}
|
|
(*TTable)(unsafe.Pointer(pTab)).FzName = _sqlite3DbStrDup(tls, db, (*TModule)(unsafe.Pointer(pMod)).FzName)
|
|
if (*TTable)(unsafe.Pointer(pTab)).FzName == uintptr(0) {
|
|
_sqlite3DbFree(tls, db, pTab)
|
|
return 0
|
|
}
|
|
(*TModule)(unsafe.Pointer(pMod)).FpEpoTab = pTab
|
|
(*TTable)(unsafe.Pointer(pTab)).FnTabRef = uint32(1)
|
|
(*TTable)(unsafe.Pointer(pTab)).FeTabType = uint8(TABTYP_VTAB)
|
|
(*TTable)(unsafe.Pointer(pTab)).FpSchema = (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb))).FpSchema
|
|
(*TTable)(unsafe.Pointer(pTab)).FiPKey = int16(-int32(1))
|
|
**(**Tu32)(__ccgo_up(pTab + 48)) |= uint32(TF_Eponymous)
|
|
_addModuleArgument(tls, pParse, pTab, _sqlite3DbStrDup(tls, db, (*TTable)(unsafe.Pointer(pTab)).FzName))
|
|
_addModuleArgument(tls, pParse, pTab, uintptr(0))
|
|
_addModuleArgument(tls, pParse, pTab, _sqlite3DbStrDup(tls, db, (*TTable)(unsafe.Pointer(pTab)).FzName))
|
|
(*Tsqlite3)(unsafe.Pointer(db)).FnSchemaLock = (*Tsqlite3)(unsafe.Pointer(db)).FnSchemaLock + 1
|
|
rc = _vtabCallConstructor(tls, db, pTab, pMod, (*Tsqlite3_module)(unsafe.Pointer(pModule)).FxConnect, bp)
|
|
(*Tsqlite3)(unsafe.Pointer(db)).FnSchemaLock = (*Tsqlite3)(unsafe.Pointer(db)).FnSchemaLock - 1
|
|
if rc != 0 {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+3968, libc.VaList(bp+16, **(**uintptr)(__ccgo_up(bp))))
|
|
(*TParse)(unsafe.Pointer(pParse)).Frc = rc
|
|
_sqlite3DbFree(tls, db, **(**uintptr)(__ccgo_up(bp)))
|
|
_sqlite3VtabEponymousTableClear(tls, db, pMod)
|
|
}
|
|
return int32(1)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** The parser calls this routine after the CREATE VIRTUAL TABLE statement
|
|
// ** has been completely parsed.
|
|
// */
|
|
func _sqlite3VtabFinishParse(tls *libc.TLS, pParse uintptr, pEnd uintptr) {
|
|
bp := tls.Alloc(48)
|
|
defer tls.Free(48)
|
|
var db, pOld, pSchema, pTab, v, zName, zStmt, zWhere, v2 uintptr
|
|
var iDb, iReg, v1 int32
|
|
_, _, _, _, _, _, _, _, _, _, _, _ = db, iDb, iReg, pOld, pSchema, pTab, v, zName, zStmt, zWhere, v1, v2
|
|
pTab = (*TParse)(unsafe.Pointer(pParse)).FpNewTable /* The table being constructed */
|
|
db = (*TParse)(unsafe.Pointer(pParse)).Fdb /* The database connection */
|
|
if pTab == uintptr(0) {
|
|
return
|
|
}
|
|
_addArgumentToVtab(tls, pParse)
|
|
(*TParse)(unsafe.Pointer(pParse)).FsArg.Fz = uintptr(0)
|
|
if (*(*struct {
|
|
FnArg int32
|
|
FazArg uintptr
|
|
Fp uintptr
|
|
})(unsafe.Pointer(pTab + 64))).FnArg < int32(1) {
|
|
return
|
|
}
|
|
/* If the CREATE VIRTUAL TABLE statement is being entered for the
|
|
** first time (in other words if the virtual table is actually being
|
|
** created now instead of just being read out of sqlite_schema) then
|
|
** do additional initialization work and store the statement text
|
|
** in the sqlite_schema table.
|
|
*/
|
|
if !((*Tsqlite3)(unsafe.Pointer(db)).Finit1.Fbusy != 0) {
|
|
_sqlite3MayAbort(tls, pParse)
|
|
/* Compute the complete text of the CREATE VIRTUAL TABLE statement */
|
|
if pEnd != 0 {
|
|
(*TParse)(unsafe.Pointer(pParse)).FsNameToken.Fn = libc.Uint32FromInt32(int32(int64((*TToken)(unsafe.Pointer(pEnd)).Fz)-int64((*TParse)(unsafe.Pointer(pParse)).FsNameToken.Fz))) + (*TToken)(unsafe.Pointer(pEnd)).Fn
|
|
}
|
|
zStmt = _sqlite3MPrintf(tls, db, __ccgo_ts+23354, libc.VaList(bp+8, pParse+232))
|
|
/* A slot for the record has already been allocated in the
|
|
** schema table. We just need to update that slot with all
|
|
** the information we've collected.
|
|
**
|
|
** The VM register number pParse->u1.cr.regRowid holds the rowid of an
|
|
** entry in the sqlite_schema table that was created for this vtab
|
|
** by sqlite3StartTable().
|
|
*/
|
|
iDb = _sqlite3SchemaToIndex(tls, db, (*TTable)(unsafe.Pointer(pTab)).FpSchema)
|
|
_sqlite3NestedParse(tls, pParse, __ccgo_ts+23378, libc.VaList(bp+8, (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(iDb)*32))).FzDbSName, (*TTable)(unsafe.Pointer(pTab)).FzName, (*TTable)(unsafe.Pointer(pTab)).FzName, zStmt, (*(*struct {
|
|
FaddrCrTab int32
|
|
FregRowid int32
|
|
FregRoot int32
|
|
FconstraintName TToken
|
|
})(unsafe.Pointer(pParse + 256))).FregRowid))
|
|
v = _sqlite3GetVdbe(tls, pParse)
|
|
_sqlite3ChangeCookie(tls, pParse, iDb)
|
|
_sqlite3VdbeAddOp0(tls, v, int32(OP_Expire))
|
|
zWhere = _sqlite3MPrintf(tls, db, __ccgo_ts+23477, libc.VaList(bp+8, (*TTable)(unsafe.Pointer(pTab)).FzName, zStmt))
|
|
_sqlite3VdbeAddParseSchemaOp(tls, v, iDb, zWhere, uint16(0))
|
|
_sqlite3DbFree(tls, db, zStmt)
|
|
v2 = pParse + 60
|
|
*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1
|
|
v1 = *(*int32)(unsafe.Pointer(v2))
|
|
iReg = v1
|
|
_sqlite3VdbeLoadString(tls, v, iReg, (*TTable)(unsafe.Pointer(pTab)).FzName)
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_VCreate), iDb, iReg)
|
|
} else {
|
|
pSchema = (*TTable)(unsafe.Pointer(pTab)).FpSchema
|
|
zName = (*TTable)(unsafe.Pointer(pTab)).FzName
|
|
_sqlite3MarkAllShadowTablesOf(tls, db, pTab)
|
|
pOld = _sqlite3HashInsert(tls, pSchema+8, zName, pTab)
|
|
if pOld != 0 {
|
|
_sqlite3OomFault(tls, db)
|
|
/* Malloc must have failed inside HashInsert() */
|
|
return
|
|
}
|
|
(*TParse)(unsafe.Pointer(pParse)).FpNewTable = uintptr(0)
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Allocate and return a new Window object describing a Window Definition.
|
|
// */
|
|
func _sqlite3WindowAlloc(tls *libc.TLS, pParse uintptr, eType int32, eStart int32, pStart uintptr, eEnd int32, pEnd uintptr, eExclude Tu8) (r uintptr) {
|
|
var bImplicitFrame int32
|
|
var pWin uintptr
|
|
_, _ = bImplicitFrame, pWin
|
|
pWin = uintptr(0)
|
|
bImplicitFrame = 0
|
|
/* Parser assures the following: */
|
|
if eType == 0 {
|
|
bImplicitFrame = int32(1)
|
|
eType = int32(TK_RANGE)
|
|
}
|
|
/* Additionally, the
|
|
** starting boundary type may not occur earlier in the following list than
|
|
** the ending boundary type:
|
|
**
|
|
** UNBOUNDED PRECEDING
|
|
** <expr> PRECEDING
|
|
** CURRENT ROW
|
|
** <expr> FOLLOWING
|
|
** UNBOUNDED FOLLOWING
|
|
**
|
|
** The parser ensures that "UNBOUNDED PRECEDING" cannot be used as an ending
|
|
** boundary, and than "UNBOUNDED FOLLOWING" cannot be used as a starting
|
|
** frame boundary.
|
|
*/
|
|
if eStart == int32(TK_CURRENT) && eEnd == int32(TK_PRECEDING) || eStart == int32(TK_FOLLOWING) && (eEnd == int32(TK_PRECEDING) || eEnd == int32(TK_CURRENT)) {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+24483, 0)
|
|
goto windowAllocErr
|
|
}
|
|
pWin = _sqlite3DbMallocZero(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, uint64(144))
|
|
if pWin == uintptr(0) {
|
|
goto windowAllocErr
|
|
}
|
|
(*TWindow)(unsafe.Pointer(pWin)).FeFrmType = libc.Uint8FromInt32(eType)
|
|
(*TWindow)(unsafe.Pointer(pWin)).FeStart = libc.Uint8FromInt32(eStart)
|
|
(*TWindow)(unsafe.Pointer(pWin)).FeEnd = libc.Uint8FromInt32(eEnd)
|
|
if libc.Int32FromUint8(eExclude) == 0 && (*Tsqlite3)(unsafe.Pointer((*TParse)(unsafe.Pointer(pParse)).Fdb)).FdbOptFlags&libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_WindowFunc)) != uint32(0) {
|
|
eExclude = uint8(TK_NO)
|
|
}
|
|
(*TWindow)(unsafe.Pointer(pWin)).FeExclude = eExclude
|
|
(*TWindow)(unsafe.Pointer(pWin)).FbImplicitFrame = libc.Uint8FromInt32(bImplicitFrame)
|
|
(*TWindow)(unsafe.Pointer(pWin)).FpEnd = _sqlite3WindowOffsetExpr(tls, pParse, pEnd)
|
|
(*TWindow)(unsafe.Pointer(pWin)).FpStart = _sqlite3WindowOffsetExpr(tls, pParse, pStart)
|
|
return pWin
|
|
goto windowAllocErr
|
|
windowAllocErr:
|
|
;
|
|
_sqlite3ExprDelete(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, pEnd)
|
|
_sqlite3ExprDelete(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, pStart)
|
|
return uintptr(0)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Attach window object pWin to expression p.
|
|
// */
|
|
func _sqlite3WindowAttach(tls *libc.TLS, pParse uintptr, p uintptr, pWin uintptr) {
|
|
if p != 0 {
|
|
*(*uintptr)(unsafe.Pointer(p + 64)) = pWin
|
|
**(**Tu32)(__ccgo_up(p + 4)) |= libc.Uint32FromInt32(libc.Int32FromInt32(EP_WinFunc) | libc.Int32FromInt32(EP_FullSize))
|
|
(*TWindow)(unsafe.Pointer(pWin)).FpOwner = p
|
|
if (*TExpr)(unsafe.Pointer(p)).Fflags&uint32(EP_Distinct) != 0 && libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pWin)).FeFrmType) != int32(TK_FILTER) {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+24601, 0)
|
|
}
|
|
} else {
|
|
_sqlite3WindowDelete(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, pWin)
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This function is called immediately after resolving the function name
|
|
// ** for a window function within a SELECT statement. Argument pList is a
|
|
// ** linked list of WINDOW definitions for the current SELECT statement.
|
|
// ** Argument pFunc is the function definition just resolved and pWin
|
|
// ** is the Window object representing the associated OVER clause. This
|
|
// ** function updates the contents of pWin as follows:
|
|
// **
|
|
// ** * If the OVER clause referred to a named window (as in "max(x) OVER win"),
|
|
// ** search list pList for a matching WINDOW definition, and update pWin
|
|
// ** accordingly. If no such WINDOW clause can be found, leave an error
|
|
// ** in pParse.
|
|
// **
|
|
// ** * If the function is a built-in window function that requires the
|
|
// ** window to be coerced (see "BUILT-IN WINDOW FUNCTIONS" at the top
|
|
// ** of this file), pWin is updated here.
|
|
// */
|
|
func _sqlite3WindowUpdate(tls *libc.TLS, pParse uintptr, pList uintptr, pWin uintptr, pFunc uintptr) {
|
|
var aUp [8]struct {
|
|
FzFunc uintptr
|
|
FeFrmType int32
|
|
FeStart int32
|
|
FeEnd int32
|
|
}
|
|
var db, p, v2 uintptr
|
|
var i int32
|
|
_, _, _, _, _ = aUp, db, i, p, v2
|
|
if (*TWindow)(unsafe.Pointer(pWin)).FzName != 0 && libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pWin)).FeFrmType) == 0 {
|
|
p = _windowFind(tls, pParse, pList, (*TWindow)(unsafe.Pointer(pWin)).FzName)
|
|
if p == uintptr(0) {
|
|
return
|
|
}
|
|
(*TWindow)(unsafe.Pointer(pWin)).FpPartition = _sqlite3ExprListDup(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, (*TWindow)(unsafe.Pointer(p)).FpPartition, 0)
|
|
(*TWindow)(unsafe.Pointer(pWin)).FpOrderBy = _sqlite3ExprListDup(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, (*TWindow)(unsafe.Pointer(p)).FpOrderBy, 0)
|
|
(*TWindow)(unsafe.Pointer(pWin)).FpStart = _sqlite3ExprDup(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, (*TWindow)(unsafe.Pointer(p)).FpStart, 0)
|
|
(*TWindow)(unsafe.Pointer(pWin)).FpEnd = _sqlite3ExprDup(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, (*TWindow)(unsafe.Pointer(p)).FpEnd, 0)
|
|
(*TWindow)(unsafe.Pointer(pWin)).FeStart = (*TWindow)(unsafe.Pointer(p)).FeStart
|
|
(*TWindow)(unsafe.Pointer(pWin)).FeEnd = (*TWindow)(unsafe.Pointer(p)).FeEnd
|
|
(*TWindow)(unsafe.Pointer(pWin)).FeFrmType = (*TWindow)(unsafe.Pointer(p)).FeFrmType
|
|
(*TWindow)(unsafe.Pointer(pWin)).FeExclude = (*TWindow)(unsafe.Pointer(p)).FeExclude
|
|
} else {
|
|
_sqlite3WindowChain(tls, pParse, pWin, pList)
|
|
}
|
|
if libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pWin)).FeFrmType) == int32(TK_RANGE) && ((*TWindow)(unsafe.Pointer(pWin)).FpStart != 0 || (*TWindow)(unsafe.Pointer(pWin)).FpEnd != 0) && ((*TWindow)(unsafe.Pointer(pWin)).FpOrderBy == uintptr(0) || (*TExprList)(unsafe.Pointer((*TWindow)(unsafe.Pointer(pWin)).FpOrderBy)).FnExpr != int32(1)) {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+24323, 0)
|
|
} else {
|
|
if (*TFuncDef)(unsafe.Pointer(pFunc)).FfuncFlags&uint32(SQLITE_FUNC_WINDOW) != 0 {
|
|
db = (*TParse)(unsafe.Pointer(pParse)).Fdb
|
|
if (*TWindow)(unsafe.Pointer(pWin)).FpFilter != 0 {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+24394, 0)
|
|
} else {
|
|
aUp = [8]struct {
|
|
FzFunc uintptr
|
|
FeFrmType int32
|
|
FeStart int32
|
|
FeEnd int32
|
|
}{
|
|
0: {
|
|
FzFunc: uintptr(unsafe.Pointer(&_row_numberName)),
|
|
FeFrmType: int32(TK_ROWS),
|
|
FeStart: int32(TK_UNBOUNDED),
|
|
FeEnd: int32(TK_CURRENT),
|
|
},
|
|
1: {
|
|
FzFunc: uintptr(unsafe.Pointer(&_dense_rankName)),
|
|
FeFrmType: int32(TK_RANGE),
|
|
FeStart: int32(TK_UNBOUNDED),
|
|
FeEnd: int32(TK_CURRENT),
|
|
},
|
|
2: {
|
|
FzFunc: uintptr(unsafe.Pointer(&_rankName)),
|
|
FeFrmType: int32(TK_RANGE),
|
|
FeStart: int32(TK_UNBOUNDED),
|
|
FeEnd: int32(TK_CURRENT),
|
|
},
|
|
3: {
|
|
FzFunc: uintptr(unsafe.Pointer(&_percent_rankName)),
|
|
FeFrmType: int32(TK_GROUPS),
|
|
FeStart: int32(TK_CURRENT),
|
|
FeEnd: int32(TK_UNBOUNDED),
|
|
},
|
|
4: {
|
|
FzFunc: uintptr(unsafe.Pointer(&_cume_distName)),
|
|
FeFrmType: int32(TK_GROUPS),
|
|
FeStart: int32(TK_FOLLOWING),
|
|
FeEnd: int32(TK_UNBOUNDED),
|
|
},
|
|
5: {
|
|
FzFunc: uintptr(unsafe.Pointer(&_ntileName)),
|
|
FeFrmType: int32(TK_ROWS),
|
|
FeStart: int32(TK_CURRENT),
|
|
FeEnd: int32(TK_UNBOUNDED),
|
|
},
|
|
6: {
|
|
FzFunc: uintptr(unsafe.Pointer(&_leadName)),
|
|
FeFrmType: int32(TK_ROWS),
|
|
FeStart: int32(TK_UNBOUNDED),
|
|
FeEnd: int32(TK_UNBOUNDED),
|
|
},
|
|
7: {
|
|
FzFunc: uintptr(unsafe.Pointer(&_lagName)),
|
|
FeFrmType: int32(TK_ROWS),
|
|
FeStart: int32(TK_UNBOUNDED),
|
|
FeEnd: int32(TK_CURRENT),
|
|
},
|
|
}
|
|
i = 0
|
|
for {
|
|
if !(i < libc.Int32FromUint64(libc.Uint64FromInt64(192)/libc.Uint64FromInt64(24))) {
|
|
break
|
|
}
|
|
if (*TFuncDef)(unsafe.Pointer(pFunc)).FzName == aUp[i].FzFunc {
|
|
_sqlite3ExprDelete(tls, db, (*TWindow)(unsafe.Pointer(pWin)).FpStart)
|
|
_sqlite3ExprDelete(tls, db, (*TWindow)(unsafe.Pointer(pWin)).FpEnd)
|
|
v2 = libc.UintptrFromInt32(0)
|
|
(*TWindow)(unsafe.Pointer(pWin)).FpStart = v2
|
|
(*TWindow)(unsafe.Pointer(pWin)).FpEnd = v2
|
|
(*TWindow)(unsafe.Pointer(pWin)).FeFrmType = libc.Uint8FromInt32(aUp[i].FeFrmType)
|
|
(*TWindow)(unsafe.Pointer(pWin)).FeStart = libc.Uint8FromInt32(aUp[i].FeStart)
|
|
(*TWindow)(unsafe.Pointer(pWin)).FeEnd = libc.Uint8FromInt32(aUp[i].FeEnd)
|
|
(*TWindow)(unsafe.Pointer(pWin)).FeExclude = uint8(0)
|
|
if libc.Int32FromUint8((*TWindow)(unsafe.Pointer(pWin)).FeStart) == int32(TK_FOLLOWING) {
|
|
(*TWindow)(unsafe.Pointer(pWin)).FpStart = _sqlite3ExprInt32(tls, db, int32(1))
|
|
}
|
|
break
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
}
|
|
}
|
|
}
|
|
(*TWindow)(unsafe.Pointer(pWin)).FpWFunc = pFunc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This routine is invoked once per CTE by the parser while parsing a
|
|
// ** WITH clause. The CTE described by the third argument is added to
|
|
// ** the WITH clause of the second argument. If the second argument is
|
|
// ** NULL, then a new WITH argument is created.
|
|
// */
|
|
func _sqlite3WithAdd(tls *libc.TLS, pParse uintptr, pWith uintptr, pCte uintptr) (r uintptr) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var db, pNew, zName, v3 uintptr
|
|
var i, v2 int32
|
|
_, _, _, _, _, _ = db, i, pNew, zName, v2, v3
|
|
db = (*TParse)(unsafe.Pointer(pParse)).Fdb
|
|
if pCte == uintptr(0) {
|
|
return pWith
|
|
}
|
|
/* Check that the CTE name is unique within this WITH clause. If
|
|
** not, store an error in the Parse structure. */
|
|
zName = (*TCte)(unsafe.Pointer(pCte)).FzName
|
|
if zName != 0 && pWith != 0 {
|
|
i = 0
|
|
for {
|
|
if !(i < (*TWith)(unsafe.Pointer(pWith)).FnCte) {
|
|
break
|
|
}
|
|
if _sqlite3StrICmp(tls, zName, (*(*TCte)(unsafe.Pointer(pWith + 16 + uintptr(i)*48))).FzName) == 0 {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+16312, libc.VaList(bp+8, zName))
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
}
|
|
if pWith != 0 {
|
|
pNew = _sqlite3DbRealloc(tls, db, pWith, uint64(uint64(libc.UintptrFromInt32(0)+16)+libc.Uint64FromInt32((*TWith)(unsafe.Pointer(pWith)).FnCte+libc.Int32FromInt32(1))*libc.Uint64FromInt64(48)))
|
|
} else {
|
|
pNew = _sqlite3DbMallocZero(tls, db, uint64(uint64(libc.UintptrFromInt32(0)+16)+libc.Uint64FromInt32(libc.Int32FromInt32(1))*libc.Uint64FromInt64(48)))
|
|
}
|
|
if (*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0 {
|
|
_sqlite3CteDelete(tls, db, pCte)
|
|
pNew = pWith
|
|
} else {
|
|
v3 = pNew
|
|
v2 = *(*int32)(unsafe.Pointer(v3))
|
|
*(*int32)(unsafe.Pointer(v3)) = *(*int32)(unsafe.Pointer(v3)) + 1
|
|
*(*TCte)(unsafe.Pointer(pNew + 16 + uintptr(v2)*48)) = **(**TCte)(__ccgo_up(pCte))
|
|
_sqlite3DbFree(tls, db, pCte)
|
|
}
|
|
return pNew
|
|
}
|
|
|
|
func _sqlite3_geopoly_init(tls *libc.TLS, db uintptr) (r int32) {
|
|
var enc, rc int32
|
|
var i uint32
|
|
_, _, _ = enc, i, rc
|
|
rc = SQLITE_OK
|
|
i = uint32(0)
|
|
for {
|
|
if !(uint64(i) < libc.Uint64FromInt64(288)/libc.Uint64FromInt64(24) && rc == SQLITE_OK) {
|
|
break
|
|
}
|
|
if _aFunc[i].FbPure != 0 {
|
|
enc = libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(SQLITE_DETERMINISTIC) | libc.Int32FromInt32(SQLITE_INNOCUOUS)
|
|
} else {
|
|
enc = libc.Int32FromInt32(SQLITE_UTF8) | libc.Int32FromInt32(SQLITE_DIRECTONLY)
|
|
}
|
|
rc = Xsqlite3_create_function(tls, db, _aFunc[i].FzName, int32(_aFunc[i].FnArg), enc, uintptr(0), _aFunc[i].FxFunc, uintptr(0), uintptr(0))
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
i = uint32(0)
|
|
for {
|
|
if !(uint64(i) < libc.Uint64FromInt64(24)/libc.Uint64FromInt64(24) && rc == SQLITE_OK) {
|
|
break
|
|
}
|
|
rc = Xsqlite3_create_function(tls, db, _aAgg[i].FzName, int32(1), libc.Int32FromInt32(SQLITE_UTF8)|libc.Int32FromInt32(SQLITE_DETERMINISTIC)|libc.Int32FromInt32(SQLITE_INNOCUOUS), uintptr(0), uintptr(0), _aAgg[i].FxStep, _aAgg[i].FxFinal)
|
|
goto _2
|
|
_2:
|
|
;
|
|
i = i + 1
|
|
}
|
|
if rc == SQLITE_OK {
|
|
rc = Xsqlite3_create_module_v2(tls, db, __ccgo_ts+30245, uintptr(unsafe.Pointer(&_geopolyModule)), uintptr(0), uintptr(0))
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This routine is called once for each row in the result table. Its job
|
|
// ** is to fill in the TabResult structure appropriately, allocating new
|
|
// ** memory as necessary.
|
|
// */
|
|
func _sqlite3_get_table_cb(tls *libc.TLS, pArg uintptr, nCol int32, argv uintptr, colv uintptr) (r int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var azNew, p, z, v3 uintptr
|
|
var i, n, need int32
|
|
var v2 Tu32
|
|
_, _, _, _, _, _, _, _ = azNew, i, n, need, p, z, v2, v3
|
|
p = pArg /* A single column of result */
|
|
/* Make sure there is enough space in p->azResult to hold everything
|
|
** we need to remember from this invocation of the callback.
|
|
*/
|
|
if (*TTabResult)(unsafe.Pointer(p)).FnRow == uint32(0) && argv != uintptr(0) {
|
|
need = nCol * int32(2)
|
|
} else {
|
|
need = nCol
|
|
}
|
|
if (*TTabResult)(unsafe.Pointer(p)).FnData+libc.Uint32FromInt32(need) > (*TTabResult)(unsafe.Pointer(p)).FnAlloc {
|
|
(*TTabResult)(unsafe.Pointer(p)).FnAlloc = (*TTabResult)(unsafe.Pointer(p)).FnAlloc*uint32(2) + libc.Uint32FromInt32(need)
|
|
azNew = _sqlite3Realloc(tls, (*TTabResult)(unsafe.Pointer(p)).FazResult, uint64(8)*uint64((*TTabResult)(unsafe.Pointer(p)).FnAlloc))
|
|
if azNew == uintptr(0) {
|
|
goto malloc_failed
|
|
}
|
|
(*TTabResult)(unsafe.Pointer(p)).FazResult = azNew
|
|
}
|
|
/* If this is the first row, then generate an extra row containing
|
|
** the names of all columns.
|
|
*/
|
|
if (*TTabResult)(unsafe.Pointer(p)).FnRow == uint32(0) {
|
|
(*TTabResult)(unsafe.Pointer(p)).FnColumn = libc.Uint32FromInt32(nCol)
|
|
i = 0
|
|
for {
|
|
if !(i < nCol) {
|
|
break
|
|
}
|
|
z = Xsqlite3_mprintf(tls, __ccgo_ts+3968, libc.VaList(bp+8, **(**uintptr)(__ccgo_up(colv + uintptr(i)*8))))
|
|
if z == uintptr(0) {
|
|
goto malloc_failed
|
|
}
|
|
v3 = p + 28
|
|
v2 = *(*Tu32)(unsafe.Pointer(v3))
|
|
*(*Tu32)(unsafe.Pointer(v3)) = *(*Tu32)(unsafe.Pointer(v3)) + 1
|
|
**(**uintptr)(__ccgo_up((*TTabResult)(unsafe.Pointer(p)).FazResult + uintptr(v2)*8)) = z
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
} else {
|
|
if libc.Int32FromUint32((*TTabResult)(unsafe.Pointer(p)).FnColumn) != nCol {
|
|
Xsqlite3_free(tls, (*TTabResult)(unsafe.Pointer(p)).FzErrMsg)
|
|
(*TTabResult)(unsafe.Pointer(p)).FzErrMsg = Xsqlite3_mprintf(tls, __ccgo_ts+21799, 0)
|
|
(*TTabResult)(unsafe.Pointer(p)).Frc = int32(SQLITE_ERROR)
|
|
return int32(1)
|
|
}
|
|
}
|
|
/* Copy over the row data
|
|
*/
|
|
if argv != uintptr(0) {
|
|
i = 0
|
|
for {
|
|
if !(i < nCol) {
|
|
break
|
|
}
|
|
if **(**uintptr)(__ccgo_up(argv + uintptr(i)*8)) == uintptr(0) {
|
|
z = uintptr(0)
|
|
} else {
|
|
n = _sqlite3Strlen30(tls, **(**uintptr)(__ccgo_up(argv + uintptr(i)*8))) + int32(1)
|
|
z = Xsqlite3_malloc64(tls, libc.Uint64FromInt32(n))
|
|
if z == uintptr(0) {
|
|
goto malloc_failed
|
|
}
|
|
libc.Xmemcpy(tls, z, **(**uintptr)(__ccgo_up(argv + uintptr(i)*8)), libc.Uint64FromInt32(n))
|
|
}
|
|
v3 = p + 28
|
|
v2 = *(*Tu32)(unsafe.Pointer(v3))
|
|
*(*Tu32)(unsafe.Pointer(v3)) = *(*Tu32)(unsafe.Pointer(v3)) + 1
|
|
**(**uintptr)(__ccgo_up((*TTabResult)(unsafe.Pointer(p)).FazResult + uintptr(v2)*8)) = z
|
|
goto _4
|
|
_4:
|
|
;
|
|
i = i + 1
|
|
}
|
|
(*TTabResult)(unsafe.Pointer(p)).FnRow = (*TTabResult)(unsafe.Pointer(p)).FnRow + 1
|
|
}
|
|
return 0
|
|
goto malloc_failed
|
|
malloc_failed:
|
|
;
|
|
(*TTabResult)(unsafe.Pointer(p)).Frc = int32(SQLITE_NOMEM)
|
|
return int32(1)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Connect to or create a new DBSTAT virtual table.
|
|
// */
|
|
func _statConnect(tls *libc.TLS, db uintptr, pAux uintptr, argc int32, argv uintptr, ppVtab uintptr, pzErr uintptr) (r int32) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var iDb, rc int32
|
|
var pTab uintptr
|
|
var _ /* nm at bp+0 */ TToken
|
|
_, _, _ = iDb, pTab, rc
|
|
pTab = uintptr(0)
|
|
rc = SQLITE_OK
|
|
_ = pAux
|
|
if argc >= int32(4) {
|
|
_sqlite3TokenInit(tls, bp, **(**uintptr)(__ccgo_up(argv + 3*8)))
|
|
iDb = _sqlite3FindDb(tls, db, bp)
|
|
if iDb < 0 {
|
|
**(**uintptr)(__ccgo_up(pzErr)) = Xsqlite3_mprintf(tls, __ccgo_ts+13470, libc.VaList(bp+24, **(**uintptr)(__ccgo_up(argv + 3*8))))
|
|
return int32(SQLITE_ERROR)
|
|
}
|
|
} else {
|
|
iDb = 0
|
|
}
|
|
Xsqlite3_vtab_config(tls, db, int32(SQLITE_VTAB_DIRECTONLY), 0)
|
|
rc = Xsqlite3_declare_vtab(tls, db, uintptr(unsafe.Pointer(&_zDbstatSchema)))
|
|
if rc == SQLITE_OK {
|
|
pTab = Xsqlite3_malloc64(tls, uint64(40))
|
|
if pTab == uintptr(0) {
|
|
rc = int32(SQLITE_NOMEM)
|
|
}
|
|
}
|
|
if rc == SQLITE_OK {
|
|
libc.Xmemset(tls, pTab, 0, uint64(40))
|
|
(*TStatTable)(unsafe.Pointer(pTab)).Fdb = db
|
|
(*TStatTable)(unsafe.Pointer(pTab)).FiDb = iDb
|
|
}
|
|
**(**uintptr)(__ccgo_up(ppVtab)) = pTab
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /* Initialize a cursor according to the query plan idxNum using the
|
|
// ** arguments in argv[0]. See statBestIndex() for a description of the
|
|
// ** meaning of the bits in idxNum.
|
|
// */
|
|
func _statFilter(tls *libc.TLS, pCursor uintptr, idxNum int32, idxStr uintptr, argc int32, argv uintptr) (r int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var iArg, rc, v1 int32
|
|
var pCsr, pSql, pTab, zDbase, zName, zSql uintptr
|
|
_, _, _, _, _, _, _, _, _ = iArg, pCsr, pSql, pTab, rc, zDbase, zName, zSql, v1
|
|
pCsr = pCursor
|
|
pTab = (*Tsqlite3_vtab_cursor)(unsafe.Pointer(pCursor)).FpVtab /* String value of pSql */
|
|
iArg = 0 /* Count of argv[] parameters used so far */
|
|
rc = SQLITE_OK /* Result of this operation */
|
|
zName = uintptr(0) /* Only provide analysis of this table */
|
|
_ = argc
|
|
_ = idxStr
|
|
_statResetCsr(tls, pCsr)
|
|
Xsqlite3_finalize(tls, (*TStatCursor)(unsafe.Pointer(pCsr)).FpStmt)
|
|
(*TStatCursor)(unsafe.Pointer(pCsr)).FpStmt = uintptr(0)
|
|
if idxNum&int32(0x01) != 0 {
|
|
v1 = iArg
|
|
iArg = iArg + 1
|
|
/* schema=? constraint is present. Get its value */
|
|
zDbase = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv + uintptr(v1)*8)))
|
|
(*TStatCursor)(unsafe.Pointer(pCsr)).FiDb = _sqlite3FindDbName(tls, (*TStatTable)(unsafe.Pointer(pTab)).Fdb, zDbase)
|
|
if (*TStatCursor)(unsafe.Pointer(pCsr)).FiDb < 0 {
|
|
(*TStatCursor)(unsafe.Pointer(pCsr)).FiDb = 0
|
|
(*TStatCursor)(unsafe.Pointer(pCsr)).FisEof = uint8(1)
|
|
return SQLITE_OK
|
|
}
|
|
} else {
|
|
(*TStatCursor)(unsafe.Pointer(pCsr)).FiDb = (*TStatTable)(unsafe.Pointer(pTab)).FiDb
|
|
}
|
|
if idxNum&int32(0x02) != 0 {
|
|
/* name=? constraint is present */
|
|
v1 = iArg
|
|
iArg = iArg + 1
|
|
zName = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv + uintptr(v1)*8)))
|
|
}
|
|
if idxNum&int32(0x04) != 0 {
|
|
/* aggregate=? constraint is present */
|
|
v1 = iArg
|
|
iArg = iArg + 1
|
|
(*TStatCursor)(unsafe.Pointer(pCsr)).FisAgg = libc.BoolUint8(Xsqlite3_value_double(tls, **(**uintptr)(__ccgo_up(argv + uintptr(v1)*8))) != float64(0))
|
|
} else {
|
|
(*TStatCursor)(unsafe.Pointer(pCsr)).FisAgg = uint8(0)
|
|
}
|
|
pSql = Xsqlite3_str_new(tls, (*TStatTable)(unsafe.Pointer(pTab)).Fdb)
|
|
Xsqlite3_str_appendf(tls, pSql, __ccgo_ts+34835, libc.VaList(bp+8, (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer((*TStatTable)(unsafe.Pointer(pTab)).Fdb)).FaDb + uintptr((*TStatCursor)(unsafe.Pointer(pCsr)).FiDb)*32))).FzDbSName))
|
|
if zName != 0 {
|
|
Xsqlite3_str_appendf(tls, pSql, __ccgo_ts+34990, libc.VaList(bp+8, zName))
|
|
}
|
|
if idxNum&int32(0x08) != 0 {
|
|
Xsqlite3_str_appendf(tls, pSql, __ccgo_ts+35004, 0)
|
|
}
|
|
zSql = Xsqlite3_str_finish(tls, pSql)
|
|
if zSql == uintptr(0) {
|
|
return int32(SQLITE_NOMEM)
|
|
} else {
|
|
rc = Xsqlite3_prepare_v2(tls, (*TStatTable)(unsafe.Pointer(pTab)).Fdb, zSql, -int32(1), pCsr+8, uintptr(0))
|
|
Xsqlite3_free(tls, zSql)
|
|
}
|
|
if rc == SQLITE_OK {
|
|
(*TStatCursor)(unsafe.Pointer(pCsr)).FiPage = -int32(1)
|
|
rc = _statNext(tls, pCursor)
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Implementation of the stat_get(P,J) SQL function. This routine is
|
|
// ** used to query statistical information that has been gathered into
|
|
// ** the StatAccum object by prior calls to stat_push(). The P parameter
|
|
// ** has type BLOB but it is really just a pointer to the StatAccum object.
|
|
// ** The content to returned is determined by the parameter J
|
|
// ** which is one of the STAT_GET_xxxx values defined above.
|
|
// **
|
|
// ** The stat_get(P,J) function is not available to generic SQL. It is
|
|
// ** inserted as part of a manually constructed bytecode program. (See
|
|
// ** the callStatGet() routine below.) It is guaranteed that the P
|
|
// ** parameter will always be a pointer to a StatAccum object, never a
|
|
// ** NULL.
|
|
// **
|
|
// ** If STAT4 is not enabled, then J is always
|
|
// ** STAT_GET_STAT1 and is hence omitted and this routine becomes
|
|
// ** a one-parameter function, stat_get(P), that always returns the
|
|
// ** stat1 table entry information.
|
|
// */
|
|
func _statGet(tls *libc.TLS, context uintptr, argc int32, argv uintptr) {
|
|
bp := tls.Alloc(80)
|
|
defer tls.Free(80)
|
|
var aCnt, p, pS uintptr
|
|
var eCall, i, i1 int32
|
|
var iVal, nDistinct Tu64
|
|
var v1 uint64
|
|
var _ /* sStat at bp+0 */ Tsqlite3_str
|
|
var _ /* sStat at bp+32 */ Tsqlite3_str
|
|
_, _, _, _, _, _, _, _, _ = aCnt, eCall, i, i1, iVal, nDistinct, p, pS, v1
|
|
p = Xsqlite3_value_blob(tls, **(**uintptr)(__ccgo_up(argv)))
|
|
/* STAT4 has a parameter on this routine. */
|
|
eCall = Xsqlite3_value_int(tls, **(**uintptr)(__ccgo_up(argv + 1*8)))
|
|
if eCall == STAT_GET_STAT1 {
|
|
/* Loop counter */
|
|
_sqlite3StrAccumInit(tls, bp, uintptr(0), uintptr(0), 0, ((*TStatAccum)(unsafe.Pointer(p)).FnKeyCol+int32(1))*int32(100))
|
|
if (*TStatAccum)(unsafe.Pointer(p)).FnSkipAhead != 0 {
|
|
v1 = (*TStatAccum)(unsafe.Pointer(p)).FnEst
|
|
} else {
|
|
v1 = (*TStatAccum)(unsafe.Pointer(p)).FnRow
|
|
}
|
|
Xsqlite3_str_appendf(tls, bp, __ccgo_ts+13032, libc.VaList(bp+72, v1))
|
|
i = 0
|
|
for {
|
|
if !(i < (*TStatAccum)(unsafe.Pointer(p)).FnKeyCol) {
|
|
break
|
|
}
|
|
nDistinct = **(**TtRowcnt)(__ccgo_up((*TStatAccum)(unsafe.Pointer(p)).Fcurrent.FanDLt + uintptr(i)*8)) + uint64(1)
|
|
iVal = ((*TStatAccum)(unsafe.Pointer(p)).FnRow + nDistinct - uint64(1)) / nDistinct
|
|
if iVal == uint64(2) && (*TStatAccum)(unsafe.Pointer(p)).FnRow*uint64(10) <= nDistinct*uint64(11) {
|
|
iVal = uint64(1)
|
|
}
|
|
Xsqlite3_str_appendf(tls, bp, __ccgo_ts+13037, libc.VaList(bp+72, iVal))
|
|
goto _2
|
|
_2:
|
|
;
|
|
i = i + 1
|
|
}
|
|
_sqlite3ResultStrAccum(tls, context, bp)
|
|
} else {
|
|
if eCall == int32(STAT_GET_ROWID) {
|
|
if (*TStatAccum)(unsafe.Pointer(p)).FiGet < 0 {
|
|
_samplePushPrevious(tls, p, 0)
|
|
(*TStatAccum)(unsafe.Pointer(p)).FiGet = 0
|
|
}
|
|
if (*TStatAccum)(unsafe.Pointer(p)).FiGet < (*TStatAccum)(unsafe.Pointer(p)).FnSample {
|
|
pS = (*TStatAccum)(unsafe.Pointer(p)).Fa + uintptr((*TStatAccum)(unsafe.Pointer(p)).FiGet)*48
|
|
if (*TStatSample)(unsafe.Pointer(pS)).FnRowid == uint32(0) {
|
|
Xsqlite3_result_int64(tls, context, *(*Ti64)(unsafe.Pointer(pS + 24)))
|
|
} else {
|
|
Xsqlite3_result_blob(tls, context, *(*uintptr)(unsafe.Pointer(pS + 24)), libc.Int32FromUint32((*TStatSample)(unsafe.Pointer(pS)).FnRowid), uintptr(-libc.Int32FromInt32(1)))
|
|
}
|
|
}
|
|
} else {
|
|
aCnt = uintptr(0)
|
|
switch eCall {
|
|
case int32(STAT_GET_NEQ):
|
|
aCnt = (**(**TStatSample)(__ccgo_up((*TStatAccum)(unsafe.Pointer(p)).Fa + uintptr((*TStatAccum)(unsafe.Pointer(p)).FiGet)*48))).FanEq
|
|
case int32(STAT_GET_NLT):
|
|
aCnt = (**(**TStatSample)(__ccgo_up((*TStatAccum)(unsafe.Pointer(p)).Fa + uintptr((*TStatAccum)(unsafe.Pointer(p)).FiGet)*48))).FanLt
|
|
default:
|
|
aCnt = (**(**TStatSample)(__ccgo_up((*TStatAccum)(unsafe.Pointer(p)).Fa + uintptr((*TStatAccum)(unsafe.Pointer(p)).FiGet)*48))).FanDLt
|
|
(*TStatAccum)(unsafe.Pointer(p)).FiGet = (*TStatAccum)(unsafe.Pointer(p)).FiGet + 1
|
|
break
|
|
}
|
|
_sqlite3StrAccumInit(tls, bp+32, uintptr(0), uintptr(0), 0, (*TStatAccum)(unsafe.Pointer(p)).FnCol*int32(100))
|
|
i1 = 0
|
|
for {
|
|
if !(i1 < (*TStatAccum)(unsafe.Pointer(p)).FnCol) {
|
|
break
|
|
}
|
|
Xsqlite3_str_appendf(tls, bp+32, __ccgo_ts+13043, libc.VaList(bp+72, **(**TtRowcnt)(__ccgo_up(aCnt + uintptr(i1)*8))))
|
|
goto _3
|
|
_3:
|
|
;
|
|
i1 = i1 + 1
|
|
}
|
|
if (**(**Tsqlite3_str)(__ccgo_up(bp + 32))).FnChar != 0 {
|
|
(**(**Tsqlite3_str)(__ccgo_up(bp + 32))).FnChar = (**(**Tsqlite3_str)(__ccgo_up(bp + 32))).FnChar - 1
|
|
}
|
|
_sqlite3ResultStrAccum(tls, context, bp+32)
|
|
}
|
|
}
|
|
_ = argc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Move a DBSTAT cursor to the next entry. Normally, the next
|
|
// ** entry will be the next page, but in aggregated mode (pCsr->isAgg!=0),
|
|
// ** the next entry is the next btree.
|
|
// */
|
|
func _statNext(tls *libc.TLS, pCursor uintptr) (r int32) {
|
|
bp := tls.Alloc(48)
|
|
defer tls.Free(48)
|
|
var i, iOvfl, nPayload, nUsable, rc, v3 int32
|
|
var iRoot Tu32
|
|
var p, p1, pBt, pCell, pCsr, pPager, pTab, z, v1 uintptr
|
|
var _ /* nPage at bp+0 */ int32
|
|
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = i, iOvfl, iRoot, nPayload, nUsable, p, p1, pBt, pCell, pCsr, pPager, pTab, rc, z, v1, v3
|
|
pCsr = pCursor
|
|
pTab = (*Tsqlite3_vtab_cursor)(unsafe.Pointer(pCursor)).FpVtab
|
|
pBt = (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer((*TStatTable)(unsafe.Pointer(pTab)).Fdb)).FaDb + uintptr((*TStatCursor)(unsafe.Pointer(pCsr)).FiDb)*32))).FpBt
|
|
pPager = _sqlite3BtreePager(tls, pBt)
|
|
Xsqlite3_free(tls, (*TStatCursor)(unsafe.Pointer(pCsr)).FzPath)
|
|
(*TStatCursor)(unsafe.Pointer(pCsr)).FzPath = uintptr(0)
|
|
goto statNextRestart
|
|
statNextRestart:
|
|
;
|
|
if (*TStatCursor)(unsafe.Pointer(pCsr)).FiPage < 0 {
|
|
/* Start measuring space on the next btree */
|
|
_statResetCounts(tls, pCsr)
|
|
rc = Xsqlite3_step(tls, (*TStatCursor)(unsafe.Pointer(pCsr)).FpStmt)
|
|
if rc == int32(SQLITE_ROW) {
|
|
iRoot = libc.Uint32FromInt64(Xsqlite3_column_int64(tls, (*TStatCursor)(unsafe.Pointer(pCsr)).FpStmt, int32(1)))
|
|
_sqlite3PagerPagecount(tls, pPager, bp)
|
|
if **(**int32)(__ccgo_up(bp)) == 0 {
|
|
(*TStatCursor)(unsafe.Pointer(pCsr)).FisEof = uint8(1)
|
|
return Xsqlite3_reset(tls, (*TStatCursor)(unsafe.Pointer(pCsr)).FpStmt)
|
|
}
|
|
rc = _statGetPage(tls, pBt, iRoot, pCsr+24)
|
|
(**(**TStatPage)(__ccgo_up(pCsr + 24))).FiPgno = iRoot
|
|
(**(**TStatPage)(__ccgo_up(pCsr + 24))).FiCell = 0
|
|
if !((*TStatCursor)(unsafe.Pointer(pCsr)).FisAgg != 0) {
|
|
v1 = Xsqlite3_mprintf(tls, __ccgo_ts+34780, 0)
|
|
z = v1
|
|
(**(**TStatPage)(__ccgo_up(pCsr + 24))).FzPath = v1
|
|
if z == uintptr(0) {
|
|
rc = int32(SQLITE_NOMEM)
|
|
}
|
|
}
|
|
(*TStatCursor)(unsafe.Pointer(pCsr)).FiPage = 0
|
|
(*TStatCursor)(unsafe.Pointer(pCsr)).FnPage = int32(1)
|
|
} else {
|
|
(*TStatCursor)(unsafe.Pointer(pCsr)).FisEof = uint8(1)
|
|
return Xsqlite3_reset(tls, (*TStatCursor)(unsafe.Pointer(pCsr)).FpStmt)
|
|
}
|
|
} else {
|
|
/* Continue analyzing the btree previously started */
|
|
p = pCsr + 24 + uintptr((*TStatCursor)(unsafe.Pointer(pCsr)).FiPage)*64
|
|
if !((*TStatCursor)(unsafe.Pointer(pCsr)).FisAgg != 0) {
|
|
_statResetCounts(tls, pCsr)
|
|
}
|
|
for (*TStatPage)(unsafe.Pointer(p)).FiCell < (*TStatPage)(unsafe.Pointer(p)).FnCell {
|
|
pCell = (*TStatPage)(unsafe.Pointer(p)).FaCell + uintptr((*TStatPage)(unsafe.Pointer(p)).FiCell)*32
|
|
for (*TStatCell)(unsafe.Pointer(pCell)).FiOvfl < (*TStatCell)(unsafe.Pointer(pCell)).FnOvfl {
|
|
_sqlite3BtreeEnter(tls, pBt)
|
|
nUsable = _sqlite3BtreeGetPageSize(tls, pBt) - _sqlite3BtreeGetReserveNoMutex(tls, pBt)
|
|
_sqlite3BtreeLeave(tls, pBt)
|
|
(*TStatCursor)(unsafe.Pointer(pCsr)).FnPage = (*TStatCursor)(unsafe.Pointer(pCsr)).FnPage + 1
|
|
_statSizeAndOffset(tls, pCsr)
|
|
if (*TStatCell)(unsafe.Pointer(pCell)).FiOvfl < (*TStatCell)(unsafe.Pointer(pCell)).FnOvfl-int32(1) {
|
|
**(**Ti64)(__ccgo_up(pCsr + 2128)) += int64(nUsable - int32(4))
|
|
} else {
|
|
**(**Ti64)(__ccgo_up(pCsr + 2128)) += int64((*TStatCell)(unsafe.Pointer(pCell)).FnLastOvfl)
|
|
**(**Ti64)(__ccgo_up(pCsr + 2120)) += int64(nUsable - int32(4) - (*TStatCell)(unsafe.Pointer(pCell)).FnLastOvfl)
|
|
}
|
|
iOvfl = (*TStatCell)(unsafe.Pointer(pCell)).FiOvfl
|
|
(*TStatCell)(unsafe.Pointer(pCell)).FiOvfl = (*TStatCell)(unsafe.Pointer(pCell)).FiOvfl + 1
|
|
if !((*TStatCursor)(unsafe.Pointer(pCsr)).FisAgg != 0) {
|
|
(*TStatCursor)(unsafe.Pointer(pCsr)).FzName = Xsqlite3_column_text(tls, (*TStatCursor)(unsafe.Pointer(pCsr)).FpStmt, 0)
|
|
(*TStatCursor)(unsafe.Pointer(pCsr)).FiPageno = **(**Tu32)(__ccgo_up((*TStatCell)(unsafe.Pointer(pCell)).FaOvfl + uintptr(iOvfl)*4))
|
|
(*TStatCursor)(unsafe.Pointer(pCsr)).FzPagetype = __ccgo_ts + 34782
|
|
v1 = Xsqlite3_mprintf(tls, __ccgo_ts+34791, libc.VaList(bp+16, (*TStatPage)(unsafe.Pointer(p)).FzPath, (*TStatPage)(unsafe.Pointer(p)).FiCell, iOvfl))
|
|
z = v1
|
|
(*TStatCursor)(unsafe.Pointer(pCsr)).FzPath = v1
|
|
if z == uintptr(0) {
|
|
v3 = int32(SQLITE_NOMEM)
|
|
} else {
|
|
v3 = SQLITE_OK
|
|
}
|
|
return v3
|
|
}
|
|
}
|
|
if (*TStatPage)(unsafe.Pointer(p)).FiRightChildPg != 0 {
|
|
break
|
|
}
|
|
(*TStatPage)(unsafe.Pointer(p)).FiCell = (*TStatPage)(unsafe.Pointer(p)).FiCell + 1
|
|
}
|
|
if !((*TStatPage)(unsafe.Pointer(p)).FiRightChildPg != 0) || (*TStatPage)(unsafe.Pointer(p)).FiCell > (*TStatPage)(unsafe.Pointer(p)).FnCell {
|
|
_statClearPage(tls, p)
|
|
(*TStatCursor)(unsafe.Pointer(pCsr)).FiPage = (*TStatCursor)(unsafe.Pointer(pCsr)).FiPage - 1
|
|
if (*TStatCursor)(unsafe.Pointer(pCsr)).FisAgg != 0 && (*TStatCursor)(unsafe.Pointer(pCsr)).FiPage < 0 {
|
|
/* label-statNext-done: When computing aggregate space usage over
|
|
** an entire btree, this is the exit point from this function */
|
|
return SQLITE_OK
|
|
}
|
|
goto statNextRestart /* Tail recursion */
|
|
}
|
|
(*TStatCursor)(unsafe.Pointer(pCsr)).FiPage = (*TStatCursor)(unsafe.Pointer(pCsr)).FiPage + 1
|
|
if (*TStatCursor)(unsafe.Pointer(pCsr)).FiPage >= libc.Int32FromUint64(libc.Uint64FromInt64(2048)/libc.Uint64FromInt64(64)) {
|
|
_statResetCsr(tls, pCsr)
|
|
return _sqlite3CorruptError(tls, int32(232585))
|
|
}
|
|
if (*TStatPage)(unsafe.Pointer(p)).FiCell == (*TStatPage)(unsafe.Pointer(p)).FnCell {
|
|
(**(**TStatPage)(__ccgo_up(p + 1*64))).FiPgno = (*TStatPage)(unsafe.Pointer(p)).FiRightChildPg
|
|
} else {
|
|
(**(**TStatPage)(__ccgo_up(p + 1*64))).FiPgno = (**(**TStatCell)(__ccgo_up((*TStatPage)(unsafe.Pointer(p)).FaCell + uintptr((*TStatPage)(unsafe.Pointer(p)).FiCell)*32))).FiChildPg
|
|
}
|
|
rc = _statGetPage(tls, pBt, (**(**TStatPage)(__ccgo_up(p + 1*64))).FiPgno, p+1*64)
|
|
(*TStatCursor)(unsafe.Pointer(pCsr)).FnPage = (*TStatCursor)(unsafe.Pointer(pCsr)).FnPage + 1
|
|
(**(**TStatPage)(__ccgo_up(p + 1*64))).FiCell = 0
|
|
if !((*TStatCursor)(unsafe.Pointer(pCsr)).FisAgg != 0) {
|
|
v1 = Xsqlite3_mprintf(tls, __ccgo_ts+34803, libc.VaList(bp+16, (*TStatPage)(unsafe.Pointer(p)).FzPath, (*TStatPage)(unsafe.Pointer(p)).FiCell))
|
|
z = v1
|
|
(**(**TStatPage)(__ccgo_up(p + 1*64))).FzPath = v1
|
|
if z == uintptr(0) {
|
|
rc = int32(SQLITE_NOMEM)
|
|
}
|
|
}
|
|
(*TStatPage)(unsafe.Pointer(p)).FiCell = (*TStatPage)(unsafe.Pointer(p)).FiCell + 1
|
|
}
|
|
/* Populate the StatCursor fields with the values to be returned
|
|
** by the xColumn() and xRowid() methods.
|
|
*/
|
|
if rc == SQLITE_OK {
|
|
p1 = pCsr + 24 + uintptr((*TStatCursor)(unsafe.Pointer(pCsr)).FiPage)*64
|
|
(*TStatCursor)(unsafe.Pointer(pCsr)).FzName = Xsqlite3_column_text(tls, (*TStatCursor)(unsafe.Pointer(pCsr)).FpStmt, 0)
|
|
(*TStatCursor)(unsafe.Pointer(pCsr)).FiPageno = (*TStatPage)(unsafe.Pointer(p1)).FiPgno
|
|
rc = _statDecodePage(tls, pBt, p1)
|
|
if rc == SQLITE_OK {
|
|
_statSizeAndOffset(tls, pCsr)
|
|
switch libc.Int32FromUint8((*TStatPage)(unsafe.Pointer(p1)).Fflags) {
|
|
case int32(0x05): /* table internal */
|
|
fallthrough
|
|
case int32(0x02): /* index internal */
|
|
(*TStatCursor)(unsafe.Pointer(pCsr)).FzPagetype = __ccgo_ts + 34811
|
|
case int32(0x0D): /* table leaf */
|
|
fallthrough
|
|
case int32(0x0A): /* index leaf */
|
|
(*TStatCursor)(unsafe.Pointer(pCsr)).FzPagetype = __ccgo_ts + 34820
|
|
default:
|
|
(*TStatCursor)(unsafe.Pointer(pCsr)).FzPagetype = __ccgo_ts + 34825
|
|
break
|
|
}
|
|
**(**int32)(__ccgo_up(pCsr + 2108)) += (*TStatPage)(unsafe.Pointer(p1)).FnCell
|
|
**(**Ti64)(__ccgo_up(pCsr + 2120)) += int64((*TStatPage)(unsafe.Pointer(p1)).FnUnused)
|
|
if (*TStatPage)(unsafe.Pointer(p1)).FnMxPayload > (*TStatCursor)(unsafe.Pointer(pCsr)).FnMxPayload {
|
|
(*TStatCursor)(unsafe.Pointer(pCsr)).FnMxPayload = (*TStatPage)(unsafe.Pointer(p1)).FnMxPayload
|
|
}
|
|
if !((*TStatCursor)(unsafe.Pointer(pCsr)).FisAgg != 0) {
|
|
v1 = Xsqlite3_mprintf(tls, __ccgo_ts+3968, libc.VaList(bp+16, (*TStatPage)(unsafe.Pointer(p1)).FzPath))
|
|
z = v1
|
|
(*TStatCursor)(unsafe.Pointer(pCsr)).FzPath = v1
|
|
if z == uintptr(0) {
|
|
rc = int32(SQLITE_NOMEM)
|
|
}
|
|
}
|
|
nPayload = 0
|
|
i = 0
|
|
for {
|
|
if !(i < (*TStatPage)(unsafe.Pointer(p1)).FnCell) {
|
|
break
|
|
}
|
|
nPayload = nPayload + (**(**TStatCell)(__ccgo_up((*TStatPage)(unsafe.Pointer(p1)).FaCell + uintptr(i)*32))).FnLocal
|
|
goto _6
|
|
_6:
|
|
;
|
|
i = i + 1
|
|
}
|
|
**(**Ti64)(__ccgo_up(pCsr + 2128)) += int64(nPayload)
|
|
/* If computing aggregate space usage by btree, continue with the
|
|
** next page. The loop will exit via the return at label-statNext-done
|
|
*/
|
|
if (*TStatCursor)(unsafe.Pointer(pCsr)).FisAgg != 0 {
|
|
goto statNextRestart
|
|
}
|
|
}
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Scan through the expression pExpr. Replace every reference to
|
|
// ** a column in table number iTable with a copy of the iColumn-th
|
|
// ** entry in pEList. (But leave references to the ROWID column
|
|
// ** unchanged.)
|
|
// **
|
|
// ** This routine is part of the flattening procedure. A subquery
|
|
// ** whose result set is defined by pEList appears as entry in the
|
|
// ** FROM clause of a SELECT such that the VDBE cursor assigned to that
|
|
// ** FORM clause entry is iTable. This routine makes the necessary
|
|
// ** changes to pExpr so that it refers directly to the source table
|
|
// ** of the subquery rather the result set of the subquery.
|
|
// */
|
|
func _substExpr(tls *libc.TLS, pSubst uintptr, pExpr uintptr) (r uintptr) {
|
|
bp := tls.Alloc(80)
|
|
defer tls.Free(80)
|
|
var db, pColl, pCopy, pNat, pNew, pWin, v1 uintptr
|
|
var iColumn int32
|
|
var _ /* ifNullRow at bp+0 */ TExpr
|
|
_, _, _, _, _, _, _, _ = db, iColumn, pColl, pCopy, pNat, pNew, pWin, v1
|
|
if pExpr == uintptr(0) {
|
|
return uintptr(0)
|
|
}
|
|
if (*TExpr)(unsafe.Pointer(pExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_OuterON)|libc.Int32FromInt32(EP_InnerON)) != uint32(0) && *(*int32)(unsafe.Pointer(pExpr + 52)) == (*TSubstContext)(unsafe.Pointer(pSubst)).FiTable {
|
|
*(*int32)(unsafe.Pointer(pExpr + 52)) = (*TSubstContext)(unsafe.Pointer(pSubst)).FiNewTable
|
|
}
|
|
if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) == int32(TK_COLUMN) && (*TExpr)(unsafe.Pointer(pExpr)).FiTable == (*TSubstContext)(unsafe.Pointer(pSubst)).FiTable && !((*TExpr)(unsafe.Pointer(pExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_FixedCol)) != libc.Uint32FromInt32(0)) {
|
|
iColumn = int32((*TExpr)(unsafe.Pointer(pExpr)).FiColumn)
|
|
pCopy = (*(*TExprList_item)(unsafe.Pointer((*TSubstContext)(unsafe.Pointer(pSubst)).FpEList + 8 + uintptr(iColumn)*32))).FpExpr
|
|
if _sqlite3ExprIsVector(tls, pCopy) != 0 {
|
|
_sqlite3VectorErrorMsg(tls, (*TSubstContext)(unsafe.Pointer(pSubst)).FpParse, pCopy)
|
|
} else {
|
|
db = (*TParse)(unsafe.Pointer((*TSubstContext)(unsafe.Pointer(pSubst)).FpParse)).Fdb
|
|
if (*TSubstContext)(unsafe.Pointer(pSubst)).FisOuterJoin != 0 && (libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pCopy)).Fop) != int32(TK_COLUMN) || (*TExpr)(unsafe.Pointer(pCopy)).FiTable != (*TSubstContext)(unsafe.Pointer(pSubst)).FiNewTable) {
|
|
libc.Xmemset(tls, bp, 0, uint64(72))
|
|
(**(**TExpr)(__ccgo_up(bp))).Fop = uint8(TK_IF_NULL_ROW)
|
|
(**(**TExpr)(__ccgo_up(bp))).FpLeft = pCopy
|
|
(**(**TExpr)(__ccgo_up(bp))).FiTable = (*TSubstContext)(unsafe.Pointer(pSubst)).FiNewTable
|
|
(**(**TExpr)(__ccgo_up(bp))).FiColumn = int16(-int32(99))
|
|
(**(**TExpr)(__ccgo_up(bp))).Fflags = uint32(EP_IfNullRow)
|
|
pCopy = bp
|
|
}
|
|
pNew = _sqlite3ExprDup(tls, db, pCopy, 0)
|
|
if (*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0 {
|
|
_sqlite3ExprDelete(tls, db, pNew)
|
|
return pExpr
|
|
}
|
|
if (*TSubstContext)(unsafe.Pointer(pSubst)).FisOuterJoin != 0 {
|
|
**(**Tu32)(__ccgo_up(pNew + 4)) |= libc.Uint32FromInt32(libc.Int32FromInt32(EP_CanBeNull))
|
|
}
|
|
if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pNew)).Fop) == int32(TK_TRUEFALSE) {
|
|
*(*int32)(unsafe.Pointer(&(*TExpr)(unsafe.Pointer(pNew)).Fu)) = _sqlite3ExprTruthValue(tls, pNew)
|
|
(*TExpr)(unsafe.Pointer(pNew)).Fop = uint8(TK_INTEGER)
|
|
**(**Tu32)(__ccgo_up(pNew + 4)) |= libc.Uint32FromInt32(libc.Int32FromInt32(EP_IntValue))
|
|
}
|
|
/* Ensure that the expression now has an implicit collation sequence,
|
|
** just as it did when it was a column of a view or sub-query. */
|
|
pNat = _sqlite3ExprCollSeq(tls, (*TSubstContext)(unsafe.Pointer(pSubst)).FpParse, pNew)
|
|
pColl = _sqlite3ExprCollSeq(tls, (*TSubstContext)(unsafe.Pointer(pSubst)).FpParse, (*(*TExprList_item)(unsafe.Pointer((*TSubstContext)(unsafe.Pointer(pSubst)).FpCList + 8 + uintptr(iColumn)*32))).FpExpr)
|
|
if pNat != pColl || libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pNew)).Fop) != int32(TK_COLUMN) && libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pNew)).Fop) != int32(TK_COLLATE) {
|
|
if pColl != 0 {
|
|
v1 = (*TCollSeq)(unsafe.Pointer(pColl)).FzName
|
|
} else {
|
|
v1 = __ccgo_ts + 5265
|
|
}
|
|
pNew = _sqlite3ExprAddCollateString(tls, (*TSubstContext)(unsafe.Pointer(pSubst)).FpParse, pNew, v1)
|
|
}
|
|
**(**Tu32)(__ccgo_up(pNew + 4)) &= ^libc.Uint32FromInt32(libc.Int32FromInt32(EP_Collate))
|
|
if (*TExpr)(unsafe.Pointer(pExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_OuterON)|libc.Int32FromInt32(EP_InnerON)) != uint32(0) {
|
|
_sqlite3SetJoinExpr(tls, pNew, *(*int32)(unsafe.Pointer(pExpr + 52)), (*TExpr)(unsafe.Pointer(pExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_OuterON)|libc.Int32FromInt32(EP_InnerON)))
|
|
}
|
|
_sqlite3ExprDelete(tls, db, pExpr)
|
|
pExpr = pNew
|
|
}
|
|
} else {
|
|
if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) == int32(TK_IF_NULL_ROW) && (*TExpr)(unsafe.Pointer(pExpr)).FiTable == (*TSubstContext)(unsafe.Pointer(pSubst)).FiTable {
|
|
(*TExpr)(unsafe.Pointer(pExpr)).FiTable = (*TSubstContext)(unsafe.Pointer(pSubst)).FiNewTable
|
|
}
|
|
if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) == int32(TK_AGG_FUNCTION) && libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop2) >= (*TSubstContext)(unsafe.Pointer(pSubst)).FnSelDepth {
|
|
(*TExpr)(unsafe.Pointer(pExpr)).Fop2 = (*TExpr)(unsafe.Pointer(pExpr)).Fop2 - 1
|
|
}
|
|
(*TExpr)(unsafe.Pointer(pExpr)).FpLeft = _substExpr(tls, pSubst, (*TExpr)(unsafe.Pointer(pExpr)).FpLeft)
|
|
(*TExpr)(unsafe.Pointer(pExpr)).FpRight = _substExpr(tls, pSubst, (*TExpr)(unsafe.Pointer(pExpr)).FpRight)
|
|
if (*TExpr)(unsafe.Pointer(pExpr)).Fflags&uint32(EP_xIsSelect) != uint32(0) {
|
|
_substSelect(tls, pSubst, *(*uintptr)(unsafe.Pointer(pExpr + 32)), int32(1))
|
|
} else {
|
|
_substExprList(tls, pSubst, *(*uintptr)(unsafe.Pointer(pExpr + 32)))
|
|
}
|
|
if (*TExpr)(unsafe.Pointer(pExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_WinFunc)) != uint32(0) {
|
|
pWin = *(*uintptr)(unsafe.Pointer(pExpr + 64))
|
|
(*TWindow)(unsafe.Pointer(pWin)).FpFilter = _substExpr(tls, pSubst, (*TWindow)(unsafe.Pointer(pWin)).FpFilter)
|
|
_substExprList(tls, pSubst, (*TWindow)(unsafe.Pointer(pWin)).FpPartition)
|
|
_substExprList(tls, pSubst, (*TWindow)(unsafe.Pointer(pWin)).FpOrderBy)
|
|
}
|
|
}
|
|
return pExpr
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Allocate space to hold a new trigger step. The allocated space
|
|
// ** holds both the TriggerStep object and the TriggerStep.target.z string.
|
|
// **
|
|
// ** If an OOM error occurs, NULL is returned and db->mallocFailed is set.
|
|
// */
|
|
func _triggerStepAllocate(tls *libc.TLS, pParse uintptr, op Tu8, pTabList uintptr, zStart uintptr, zEnd uintptr) (r uintptr) {
|
|
var db, pNew, pTriggerStep uintptr
|
|
_, _, _ = db, pNew, pTriggerStep
|
|
pNew = (*TParse)(unsafe.Pointer(pParse)).FpNewTrigger
|
|
db = (*TParse)(unsafe.Pointer(pParse)).Fdb
|
|
pTriggerStep = uintptr(0)
|
|
if (*TParse)(unsafe.Pointer(pParse)).FnErr == 0 {
|
|
if pNew != 0 && (*TTrigger)(unsafe.Pointer(pNew)).FpSchema != (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + 1*32))).FpSchema && *(*uintptr)(unsafe.Pointer(pTabList + 8 + 72)) != 0 {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+22311, 0)
|
|
} else {
|
|
pTriggerStep = _sqlite3DbMallocZero(tls, db, uint64(88))
|
|
if pTriggerStep != 0 {
|
|
(*TTriggerStep)(unsafe.Pointer(pTriggerStep)).FpSrc = _sqlite3SrcListDup(tls, db, pTabList, int32(EXPRDUP_REDUCE))
|
|
(*TTriggerStep)(unsafe.Pointer(pTriggerStep)).Fop = op
|
|
(*TTriggerStep)(unsafe.Pointer(pTriggerStep)).FzSpan = _triggerSpanDup(tls, db, zStart, zEnd)
|
|
if (*TTriggerStep)(unsafe.Pointer(pTriggerStep)).FpSrc != 0 && libc.Int32FromUint8((*TParse)(unsafe.Pointer(pParse)).FeParseMode) >= int32(PARSE_MODE_RENAME) {
|
|
_sqlite3RenameTokenRemap(tls, pParse, (*(*TSrcItem)(unsafe.Pointer((*TTriggerStep)(unsafe.Pointer(pTriggerStep)).FpSrc + 8))).FzName, (*(*TSrcItem)(unsafe.Pointer(pTabList + 8))).FzName)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
_sqlite3SrcListDelete(tls, db, pTabList)
|
|
return pTriggerStep
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** The unhex() function. This function may be invoked with either one or
|
|
// ** two arguments. In both cases the first argument is interpreted as text
|
|
// ** a text value containing a set of pairs of hexadecimal digits which are
|
|
// ** decoded and returned as a blob.
|
|
// **
|
|
// ** If there is only a single argument, then it must consist only of an
|
|
// ** even number of hexadecimal digits. Otherwise, return NULL.
|
|
// **
|
|
// ** Or, if there is a second argument, then any character that appears in
|
|
// ** the second argument is also allowed to appear between pairs of hexadecimal
|
|
// ** digits in the first argument. If any other character appears in the
|
|
// ** first argument, or if one of the allowed characters appears between
|
|
// ** two hexadecimal digits that make up a single byte, NULL is returned.
|
|
// **
|
|
// ** The following expressions are all true:
|
|
// **
|
|
// ** unhex('ABCD') IS x'ABCD'
|
|
// ** unhex('AB CD') IS NULL
|
|
// ** unhex('AB CD', ' ') IS x'ABCD'
|
|
// ** unhex('A BCD', ' ') IS NULL
|
|
// */
|
|
func _unhexFunc(tls *libc.TLS, pCtx uintptr, argc int32, argv uintptr) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var c, d, v2 Tu8
|
|
var ch Tu32
|
|
var nHex, nPass int32
|
|
var p, pBlob, zPass, v1 uintptr
|
|
var v3 uint32
|
|
var _ /* zHex at bp+0 */ uintptr
|
|
_, _, _, _, _, _, _, _, _, _, _ = c, ch, d, nHex, nPass, p, pBlob, zPass, v1, v2, v3
|
|
zPass = __ccgo_ts + 1704
|
|
nPass = 0
|
|
**(**uintptr)(__ccgo_up(bp)) = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv)))
|
|
nHex = Xsqlite3_value_bytes(tls, **(**uintptr)(__ccgo_up(argv)))
|
|
pBlob = uintptr(0)
|
|
p = uintptr(0)
|
|
if argc == int32(2) {
|
|
zPass = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv + 1*8)))
|
|
nPass = Xsqlite3_value_bytes(tls, **(**uintptr)(__ccgo_up(argv + 1*8)))
|
|
}
|
|
if !(**(**uintptr)(__ccgo_up(bp)) != 0) || !(zPass != 0) {
|
|
return
|
|
}
|
|
v1 = _contextMalloc(tls, pCtx, int64(nHex/int32(2)+int32(1)))
|
|
pBlob = v1
|
|
p = v1
|
|
if pBlob != 0 { /* Least significant digit of next byte */
|
|
for {
|
|
v2 = **(**Tu8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp))))
|
|
c = v2
|
|
if !(libc.Int32FromUint8(v2) != 0x00) {
|
|
break
|
|
}
|
|
for !(libc.Int32FromUint8(_sqlite3CtypeMap[c])&libc.Int32FromInt32(0x08) != 0) {
|
|
if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp))))) < int32(0x80) {
|
|
v1 = **(**uintptr)(__ccgo_up(bp))
|
|
**(**uintptr)(__ccgo_up(bp)) = **(**uintptr)(__ccgo_up(bp)) + 1
|
|
v3 = uint32(**(**Tu8)(__ccgo_up(v1)))
|
|
} else {
|
|
v3 = _sqlite3Utf8Read(tls, bp)
|
|
}
|
|
ch = v3
|
|
if !(_strContainsChar(tls, zPass, nPass, ch) != 0) {
|
|
goto unhex_null
|
|
}
|
|
c = **(**Tu8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp))))
|
|
if libc.Int32FromUint8(c) == 0x00 {
|
|
goto unhex_done
|
|
}
|
|
}
|
|
**(**uintptr)(__ccgo_up(bp)) = **(**uintptr)(__ccgo_up(bp)) + 1
|
|
v1 = **(**uintptr)(__ccgo_up(bp))
|
|
**(**uintptr)(__ccgo_up(bp)) = **(**uintptr)(__ccgo_up(bp)) + 1
|
|
d = **(**Tu8)(__ccgo_up(v1))
|
|
if !(libc.Int32FromUint8(_sqlite3CtypeMap[d])&libc.Int32FromInt32(0x08) != 0) {
|
|
goto unhex_null
|
|
}
|
|
v1 = p
|
|
p = p + 1
|
|
**(**Tu8)(__ccgo_up(v1)) = libc.Uint8FromInt32(libc.Int32FromUint8(_sqlite3HexToInt(tls, libc.Int32FromUint8(c)))<<int32(4) | libc.Int32FromUint8(_sqlite3HexToInt(tls, libc.Int32FromUint8(d))))
|
|
}
|
|
}
|
|
goto unhex_done
|
|
unhex_done:
|
|
;
|
|
Xsqlite3_result_blob(tls, pCtx, pBlob, int32(int64(p)-int64(pBlob)), __ccgo_fp(Xsqlite3_free))
|
|
return
|
|
goto unhex_null
|
|
unhex_null:
|
|
;
|
|
Xsqlite3_free(tls, pBlob)
|
|
return
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Use F_GETLK to check whether or not there are any readers with open
|
|
// ** wal-mode transactions in other processes on database file pFile. If
|
|
// ** no error occurs, return SQLITE_OK and set (*piOut) to 1 if there are
|
|
// ** such transactions, or 0 otherwise. If an error occurs, return an
|
|
// ** SQLite error code. The final value of *piOut is undefined in this
|
|
// ** case.
|
|
// */
|
|
func _unixFcntlExternalReader(tls *libc.TLS, pFile uintptr, piOut uintptr) (r int32) {
|
|
bp := tls.Alloc(48)
|
|
defer tls.Free(48)
|
|
var pShmNode uintptr
|
|
var rc int32
|
|
var _ /* f at bp+0 */ Tflock
|
|
_, _ = pShmNode, rc
|
|
rc = SQLITE_OK
|
|
**(**int32)(__ccgo_up(piOut)) = 0
|
|
if (*TunixFile)(unsafe.Pointer(pFile)).FpShm != 0 {
|
|
pShmNode = (*TunixShm)(unsafe.Pointer((*TunixFile)(unsafe.Pointer(pFile)).FpShm)).FpShmNode
|
|
libc.Xmemset(tls, bp, 0, uint64(32))
|
|
(**(**Tflock)(__ccgo_up(bp))).Fl_type = int16(F_WRLCK)
|
|
(**(**Tflock)(__ccgo_up(bp))).Fl_whence = 0
|
|
(**(**Tflock)(__ccgo_up(bp))).Fl_start = int64((libc.Int32FromInt32(22)+libc.Int32FromInt32(SQLITE_SHM_NLOCK))*libc.Int32FromInt32(4) + libc.Int32FromInt32(3))
|
|
(**(**Tflock)(__ccgo_up(bp))).Fl_len = int64(libc.Int32FromInt32(SQLITE_SHM_NLOCK) - libc.Int32FromInt32(3))
|
|
Xsqlite3_mutex_enter(tls, (*TunixShmNode)(unsafe.Pointer(pShmNode)).FpShmMutex)
|
|
if (*(*func(*libc.TLS, int32, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(7)].FpCurrent})))(tls, (*TunixShmNode)(unsafe.Pointer(pShmNode)).FhShm, int32(F_GETLK), libc.VaList(bp+40, bp)) < 0 {
|
|
rc = libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(15)<<libc.Int32FromInt32(8)
|
|
} else {
|
|
**(**int32)(__ccgo_up(piOut)) = libc.BoolInt32(int32((**(**Tflock)(__ccgo_up(bp))).Fl_type) != int32(F_UNLCK))
|
|
}
|
|
Xsqlite3_mutex_leave(tls, (*TunixShmNode)(unsafe.Pointer(pShmNode)).FpShmMutex)
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Information and control of an open file handle.
|
|
// */
|
|
func _unixFileControl(tls *libc.TLS, id uintptr, op int32, pArg uintptr) (r int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var newLimit Ti64
|
|
var pFile, zTFile uintptr
|
|
var rc, rc1 int32
|
|
_, _, _, _, _ = newLimit, pFile, rc, rc1, zTFile
|
|
pFile = id
|
|
switch op {
|
|
case int32(SQLITE_FCNTL_NULL_IO):
|
|
(*(*func(*libc.TLS, int32) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(1)].FpCurrent})))(tls, (*TunixFile)(unsafe.Pointer(pFile)).Fh)
|
|
(*TunixFile)(unsafe.Pointer(pFile)).Fh = -int32(1)
|
|
return SQLITE_OK
|
|
case int32(SQLITE_FCNTL_LOCKSTATE):
|
|
**(**int32)(__ccgo_up(pArg)) = libc.Int32FromUint8((*TunixFile)(unsafe.Pointer(pFile)).FeFileLock)
|
|
return SQLITE_OK
|
|
case int32(SQLITE_FCNTL_LAST_ERRNO):
|
|
**(**int32)(__ccgo_up(pArg)) = (*TunixFile)(unsafe.Pointer(pFile)).FlastErrno
|
|
return SQLITE_OK
|
|
case int32(SQLITE_FCNTL_CHUNK_SIZE):
|
|
(*TunixFile)(unsafe.Pointer(pFile)).FszChunk = **(**int32)(__ccgo_up(pArg))
|
|
return SQLITE_OK
|
|
case int32(SQLITE_FCNTL_SIZE_HINT):
|
|
rc = _fcntlSizeHint(tls, pFile, **(**Ti64)(__ccgo_up(pArg)))
|
|
return rc
|
|
case int32(SQLITE_FCNTL_PERSIST_WAL):
|
|
_unixModeBit(tls, pFile, uint8(UNIXFILE_PERSIST_WAL), pArg)
|
|
return SQLITE_OK
|
|
case int32(SQLITE_FCNTL_POWERSAFE_OVERWRITE):
|
|
_unixModeBit(tls, pFile, uint8(UNIXFILE_PSOW), pArg)
|
|
return SQLITE_OK
|
|
case int32(SQLITE_FCNTL_VFSNAME):
|
|
**(**uintptr)(__ccgo_up(pArg)) = Xsqlite3_mprintf(tls, __ccgo_ts+3968, libc.VaList(bp+8, (*Tsqlite3_vfs)(unsafe.Pointer((*TunixFile)(unsafe.Pointer(pFile)).FpVfs)).FzName))
|
|
return SQLITE_OK
|
|
case int32(SQLITE_FCNTL_TEMPFILENAME):
|
|
zTFile = Xsqlite3_malloc64(tls, libc.Uint64FromInt32((*Tsqlite3_vfs)(unsafe.Pointer((*TunixFile)(unsafe.Pointer(pFile)).FpVfs)).FmxPathname))
|
|
if zTFile != 0 {
|
|
_unixGetTempname(tls, (*Tsqlite3_vfs)(unsafe.Pointer((*TunixFile)(unsafe.Pointer(pFile)).FpVfs)).FmxPathname, zTFile)
|
|
**(**uintptr)(__ccgo_up(pArg)) = zTFile
|
|
}
|
|
return SQLITE_OK
|
|
case int32(SQLITE_FCNTL_HAS_MOVED):
|
|
**(**int32)(__ccgo_up(pArg)) = _fileHasMoved(tls, pFile)
|
|
return SQLITE_OK
|
|
case int32(SQLITE_FCNTL_MMAP_SIZE):
|
|
newLimit = **(**Ti64)(__ccgo_up(pArg))
|
|
rc1 = SQLITE_OK
|
|
if newLimit > _sqlite3Config.FmxMmap {
|
|
newLimit = _sqlite3Config.FmxMmap
|
|
}
|
|
/* The value of newLimit may be eventually cast to (size_t) and passed
|
|
** to mmap(). Restrict its value to 2GB if (size_t) is not at least a
|
|
** 64-bit type. */
|
|
if newLimit > 0 && libc.Bool(uint64(8) < uint64(8)) {
|
|
newLimit = newLimit & libc.Int64FromInt32(0x7FFFFFFF)
|
|
}
|
|
**(**Ti64)(__ccgo_up(pArg)) = (*TunixFile)(unsafe.Pointer(pFile)).FmmapSizeMax
|
|
if newLimit >= 0 && newLimit != (*TunixFile)(unsafe.Pointer(pFile)).FmmapSizeMax && (*TunixFile)(unsafe.Pointer(pFile)).FnFetchOut == 0 {
|
|
(*TunixFile)(unsafe.Pointer(pFile)).FmmapSizeMax = newLimit
|
|
if (*TunixFile)(unsafe.Pointer(pFile)).FmmapSize > 0 {
|
|
_unixUnmapfile(tls, pFile)
|
|
rc1 = _unixMapfile(tls, pFile, int64(-int32(1)))
|
|
}
|
|
}
|
|
return rc1
|
|
case int32(SQLITE_FCNTL_EXTERNAL_READER):
|
|
return _unixFcntlExternalReader(tls, id, pArg)
|
|
}
|
|
return int32(SQLITE_NOTFOUND)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** If pFile has a -shm file open and it is sharing that file with some
|
|
// ** other connection, either in the same process or in a separate process,
|
|
// ** then return true. Return false if either pFile does not have a -shm
|
|
// ** file open or if it is the only connection to that -shm file across the
|
|
// ** entire system.
|
|
// **
|
|
// ** This routine is not required for correct operation. It can always return
|
|
// ** false and SQLite will continue to operate according to spec. However,
|
|
// ** when this routine does its job, it adds extra robustness in cases
|
|
// ** where database file locks have been erroneously deleted in a WAL-mode
|
|
// ** database by doing close(open(DATABASE_PATHNAME)) or similar.
|
|
// **
|
|
// ** With false negatives, SQLite still operates to spec, though with less
|
|
// ** robustness. With false positives, the last database connection on a
|
|
// ** WAL-mode database will fail to unlink the -wal and -shm files, which
|
|
// ** is annoying but harmless. False positives will also prevent a database
|
|
// ** connection from running "PRAGMA journal_mode=DELETE" in order to take
|
|
// ** the database out of WAL mode, which is perhaps more serious, but is
|
|
// ** still not a disaster.
|
|
// */
|
|
func _unixIsSharingShmNode(tls *libc.TLS, pFile uintptr) (r int32) {
|
|
bp := tls.Alloc(48)
|
|
defer tls.Free(48)
|
|
var pShmNode uintptr
|
|
var _ /* lock at bp+0 */ Tflock
|
|
_ = pShmNode
|
|
if (*TunixFile)(unsafe.Pointer(pFile)).FpShm == uintptr(0) {
|
|
return 0
|
|
}
|
|
if libc.Int32FromUint16((*TunixFile)(unsafe.Pointer(pFile)).FctrlFlags)&int32(UNIXFILE_EXCL) != 0 {
|
|
return 0
|
|
}
|
|
pShmNode = (*TunixShm)(unsafe.Pointer((*TunixFile)(unsafe.Pointer(pFile)).FpShm)).FpShmNode
|
|
libc.Xmemset(tls, bp, 0, uint64(32))
|
|
(**(**Tflock)(__ccgo_up(bp))).Fl_whence = 0
|
|
(**(**Tflock)(__ccgo_up(bp))).Fl_start = int64((libc.Int32FromInt32(22)+libc.Int32FromInt32(SQLITE_SHM_NLOCK))*libc.Int32FromInt32(4) + libc.Int32FromInt32(SQLITE_SHM_NLOCK))
|
|
(**(**Tflock)(__ccgo_up(bp))).Fl_len = int64(1)
|
|
(**(**Tflock)(__ccgo_up(bp))).Fl_type = int16(F_WRLCK)
|
|
(*(*func(*libc.TLS, int32, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(7)].FpCurrent})))(tls, (*TunixShmNode)(unsafe.Pointer(pShmNode)).FhShm, int32(F_GETLK), libc.VaList(bp+40, bp))
|
|
return libc.BoolInt32(int32((**(**Tflock)(__ccgo_up(bp))).Fl_type) != int32(F_UNLCK))
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Lock the file with the lock specified by parameter eFileLock - one
|
|
// ** of the following:
|
|
// **
|
|
// ** (1) SHARED_LOCK
|
|
// ** (2) RESERVED_LOCK
|
|
// ** (3) PENDING_LOCK
|
|
// ** (4) EXCLUSIVE_LOCK
|
|
// **
|
|
// ** Sometimes when requesting one lock state, additional lock states
|
|
// ** are inserted in between. The locking might fail on one of the later
|
|
// ** transitions leaving the lock state different from what it started but
|
|
// ** still short of its goal. The following chart shows the allowed
|
|
// ** transitions and the inserted intermediate states:
|
|
// **
|
|
// ** UNLOCKED -> SHARED
|
|
// ** SHARED -> RESERVED
|
|
// ** SHARED -> EXCLUSIVE
|
|
// ** RESERVED -> (PENDING) -> EXCLUSIVE
|
|
// ** PENDING -> EXCLUSIVE
|
|
// **
|
|
// ** This routine will only increase a lock. Use the sqlite3OsUnlock()
|
|
// ** routine to lower a locking level.
|
|
// */
|
|
func _unixLock(tls *libc.TLS, id uintptr, eFileLock int32) (r int32) {
|
|
bp := tls.Alloc(32)
|
|
defer tls.Free(32)
|
|
var pFile, pInode uintptr
|
|
var rc, tErrno, v2 int32
|
|
var v1 Toff_t
|
|
var _ /* lock at bp+0 */ Tflock
|
|
_, _, _, _, _, _ = pFile, pInode, rc, tErrno, v1, v2
|
|
/* The following describes the implementation of the various locks and
|
|
** lock transitions in terms of the POSIX advisory shared and exclusive
|
|
** lock primitives (called read-locks and write-locks below, to avoid
|
|
** confusion with SQLite lock names). The algorithms are complicated
|
|
** slightly in order to be compatible with Windows95 systems simultaneously
|
|
** accessing the same database file, in case that is ever required.
|
|
**
|
|
** Symbols defined in os.h identify the 'pending byte' and the 'reserved
|
|
** byte', each single bytes at well known offsets, and the 'shared byte
|
|
** range', a range of 510 bytes at a well known offset.
|
|
**
|
|
** To obtain a SHARED lock, a read-lock is obtained on the 'pending
|
|
** byte'. If this is successful, 'shared byte range' is read-locked
|
|
** and the lock on the 'pending byte' released. (Legacy note: When
|
|
** SQLite was first developed, Windows95 systems were still very common,
|
|
** and Windows95 lacks a shared-lock capability. So on Windows95, a
|
|
** single randomly selected by from the 'shared byte range' is locked.
|
|
** Windows95 is now pretty much extinct, but this work-around for the
|
|
** lack of shared-locks on Windows95 lives on, for backwards
|
|
** compatibility.)
|
|
**
|
|
** A process may only obtain a RESERVED lock after it has a SHARED lock.
|
|
** A RESERVED lock is implemented by grabbing a write-lock on the
|
|
** 'reserved byte'.
|
|
**
|
|
** An EXCLUSIVE lock may only be requested after either a SHARED or
|
|
** RESERVED lock is held. An EXCLUSIVE lock is implemented by obtaining
|
|
** a write-lock on the entire 'shared byte range'. Since all other locks
|
|
** require a read-lock on one of the bytes within this range, this ensures
|
|
** that no other locks are held on the database.
|
|
**
|
|
** If a process that holds a RESERVED lock requests an EXCLUSIVE, then
|
|
** a PENDING lock is obtained first. A PENDING lock is implemented by
|
|
** obtaining a write-lock on the 'pending byte'. This ensures that no new
|
|
** SHARED locks can be obtained, but existing SHARED locks are allowed to
|
|
** persist. If the call to this function fails to obtain the EXCLUSIVE
|
|
** lock in this case, it holds the PENDING lock instead. The client may
|
|
** then re-attempt the EXCLUSIVE lock later on, after existing SHARED
|
|
** locks have cleared.
|
|
*/
|
|
rc = SQLITE_OK
|
|
pFile = id
|
|
tErrno = 0
|
|
/* If there is already a lock of this type or more restrictive on the
|
|
** unixFile, do nothing. Don't use the end_lock: exit path, as
|
|
** unixEnterMutex() hasn't been called yet.
|
|
*/
|
|
if libc.Int32FromUint8((*TunixFile)(unsafe.Pointer(pFile)).FeFileLock) >= eFileLock {
|
|
return SQLITE_OK
|
|
}
|
|
/* Make sure the locking sequence is correct.
|
|
** (1) We never move from unlocked to anything higher than shared lock.
|
|
** (2) SQLite never explicitly requests a pending lock.
|
|
** (3) A shared lock is always held when a reserve lock is requested.
|
|
*/
|
|
/* This mutex is needed because pFile->pInode is shared across threads
|
|
*/
|
|
pInode = (*TunixFile)(unsafe.Pointer(pFile)).FpInode
|
|
Xsqlite3_mutex_enter(tls, (*TunixInodeInfo)(unsafe.Pointer(pInode)).FpLockMutex)
|
|
/* If some thread using this PID has a lock via a different unixFile*
|
|
** handle that precludes the requested lock, return BUSY.
|
|
*/
|
|
if libc.Int32FromUint8((*TunixFile)(unsafe.Pointer(pFile)).FeFileLock) != libc.Int32FromUint8((*TunixInodeInfo)(unsafe.Pointer(pInode)).FeFileLock) && (libc.Int32FromUint8((*TunixInodeInfo)(unsafe.Pointer(pInode)).FeFileLock) >= int32(PENDING_LOCK) || eFileLock > int32(SHARED_LOCK)) {
|
|
rc = int32(SQLITE_BUSY)
|
|
goto end_lock
|
|
}
|
|
/* If a SHARED lock is requested, and some thread using this PID already
|
|
** has a SHARED or RESERVED lock, then increment reference counts and
|
|
** return SQLITE_OK.
|
|
*/
|
|
if eFileLock == int32(SHARED_LOCK) && (libc.Int32FromUint8((*TunixInodeInfo)(unsafe.Pointer(pInode)).FeFileLock) == int32(SHARED_LOCK) || libc.Int32FromUint8((*TunixInodeInfo)(unsafe.Pointer(pInode)).FeFileLock) == int32(RESERVED_LOCK)) {
|
|
/* If designated locking fd is read-only, migrate to this read-write fd */
|
|
if libc.AtomicLoadPInt32(uintptr(unsafe.Pointer(&_ofdEnabled))) != 0 && libc.AtomicLoadPInt32(uintptr(unsafe.Pointer(&_ofdSupported))) != 0 && (*TunixInodeInfo)(unsafe.Pointer(pInode)).FbLockIsReadOnly != 0 && libc.Int32FromUint16((*TunixFile)(unsafe.Pointer(pFile)).FctrlFlags)&int32(UNIXFILE_RDONLY) == 0 {
|
|
(**(**Tflock)(__ccgo_up(bp))).Fl_type = F_RDLCK
|
|
(**(**Tflock)(__ccgo_up(bp))).Fl_whence = 0
|
|
(**(**Tflock)(__ccgo_up(bp))).Fl_start = int64(_sqlite3PendingByte + libc.Int32FromInt32(2))
|
|
(**(**Tflock)(__ccgo_up(bp))).Fl_len = int64(SHARED_SIZE)
|
|
if _osFcntlOfd(tls, (*TunixFile)(unsafe.Pointer(pFile)).Fh, int32(F_SETLK), bp) == 0 {
|
|
(**(**Tflock)(__ccgo_up(bp))).Fl_type = int16(F_UNLCK)
|
|
v1 = libc.Int64FromInt64(0)
|
|
(**(**Tflock)(__ccgo_up(bp))).Fl_len = v1
|
|
(**(**Tflock)(__ccgo_up(bp))).Fl_start = v1
|
|
_osFcntlOfd(tls, (*TunixInodeInfo)(unsafe.Pointer(pInode)).FhLock, int32(F_SETLK), bp)
|
|
(*TunixInodeInfo)(unsafe.Pointer(pInode)).FhLock = (*TunixFile)(unsafe.Pointer(pFile)).Fh
|
|
(*TunixInodeInfo)(unsafe.Pointer(pInode)).FbLockIsReadOnly = uint8(0)
|
|
}
|
|
}
|
|
(*TunixFile)(unsafe.Pointer(pFile)).FeFileLock = uint8(SHARED_LOCK)
|
|
(*TunixInodeInfo)(unsafe.Pointer(pInode)).FnShared = (*TunixInodeInfo)(unsafe.Pointer(pInode)).FnShared + 1
|
|
(*TunixInodeInfo)(unsafe.Pointer(pInode)).FnLock = (*TunixInodeInfo)(unsafe.Pointer(pInode)).FnLock + 1
|
|
goto end_lock
|
|
}
|
|
/* A PENDING lock is needed before acquiring a SHARED lock and before
|
|
** acquiring an EXCLUSIVE lock. For the SHARED lock, the PENDING will
|
|
** be released.
|
|
*/
|
|
(**(**Tflock)(__ccgo_up(bp))).Fl_len = int64(1)
|
|
(**(**Tflock)(__ccgo_up(bp))).Fl_whence = 0
|
|
if eFileLock == int32(SHARED_LOCK) || eFileLock == int32(EXCLUSIVE_LOCK) && libc.Int32FromUint8((*TunixFile)(unsafe.Pointer(pFile)).FeFileLock) == int32(RESERVED_LOCK) {
|
|
if eFileLock == int32(SHARED_LOCK) {
|
|
v2 = F_RDLCK
|
|
} else {
|
|
v2 = int32(F_WRLCK)
|
|
}
|
|
(**(**Tflock)(__ccgo_up(bp))).Fl_type = int16(v2)
|
|
(**(**Tflock)(__ccgo_up(bp))).Fl_start = int64(_sqlite3PendingByte)
|
|
if _unixFileLock(tls, pFile, bp) != 0 {
|
|
tErrno = **(**int32)(__ccgo_up(libc.X__errno_location(tls)))
|
|
rc = _sqliteErrorFromPosixError(tls, tErrno, libc.Int32FromInt32(SQLITE_IOERR)|libc.Int32FromInt32(15)<<libc.Int32FromInt32(8))
|
|
if rc != int32(SQLITE_BUSY) {
|
|
_storeLastErrno(tls, pFile, tErrno)
|
|
}
|
|
goto end_lock
|
|
} else {
|
|
if eFileLock == int32(EXCLUSIVE_LOCK) {
|
|
(*TunixFile)(unsafe.Pointer(pFile)).FeFileLock = uint8(PENDING_LOCK)
|
|
(*TunixInodeInfo)(unsafe.Pointer(pInode)).FeFileLock = uint8(PENDING_LOCK)
|
|
}
|
|
}
|
|
}
|
|
/* If control gets to this point, then actually go ahead and make
|
|
** operating system calls for the specified lock.
|
|
*/
|
|
if eFileLock == int32(SHARED_LOCK) {
|
|
/* Now get the read-lock */
|
|
(**(**Tflock)(__ccgo_up(bp))).Fl_start = int64(_sqlite3PendingByte + libc.Int32FromInt32(2))
|
|
(**(**Tflock)(__ccgo_up(bp))).Fl_len = int64(SHARED_SIZE)
|
|
if _unixFileLock(tls, pFile, bp) != 0 {
|
|
tErrno = **(**int32)(__ccgo_up(libc.X__errno_location(tls)))
|
|
rc = _sqliteErrorFromPosixError(tls, tErrno, libc.Int32FromInt32(SQLITE_IOERR)|libc.Int32FromInt32(15)<<libc.Int32FromInt32(8))
|
|
}
|
|
/* Drop the temporary PENDING lock */
|
|
(**(**Tflock)(__ccgo_up(bp))).Fl_start = int64(_sqlite3PendingByte)
|
|
(**(**Tflock)(__ccgo_up(bp))).Fl_len = int64(1)
|
|
(**(**Tflock)(__ccgo_up(bp))).Fl_type = int16(F_UNLCK)
|
|
if _unixFileLock(tls, pFile, bp) != 0 && rc == SQLITE_OK {
|
|
/* This could happen with a network mount */
|
|
tErrno = **(**int32)(__ccgo_up(libc.X__errno_location(tls)))
|
|
rc = libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(8)<<libc.Int32FromInt32(8)
|
|
}
|
|
if rc != 0 {
|
|
if rc != int32(SQLITE_BUSY) {
|
|
_storeLastErrno(tls, pFile, tErrno)
|
|
}
|
|
goto end_lock
|
|
} else {
|
|
(*TunixFile)(unsafe.Pointer(pFile)).FeFileLock = uint8(SHARED_LOCK)
|
|
(*TunixInodeInfo)(unsafe.Pointer(pInode)).FnLock = (*TunixInodeInfo)(unsafe.Pointer(pInode)).FnLock + 1
|
|
(*TunixInodeInfo)(unsafe.Pointer(pInode)).FnShared = int32(1)
|
|
if (*TunixInodeInfo)(unsafe.Pointer(pInode)).FhLock == 0 {
|
|
/* First lock on this inode: pFile->h now holds the kernel locks */
|
|
(*TunixInodeInfo)(unsafe.Pointer(pInode)).FhLock = (*TunixFile)(unsafe.Pointer(pFile)).Fh
|
|
(*TunixInodeInfo)(unsafe.Pointer(pInode)).FbLockIsReadOnly = libc.BoolUint8(libc.Int32FromUint16((*TunixFile)(unsafe.Pointer(pFile)).FctrlFlags)&int32(UNIXFILE_RDONLY) != 0)
|
|
}
|
|
}
|
|
} else {
|
|
if eFileLock == int32(EXCLUSIVE_LOCK) && (*TunixInodeInfo)(unsafe.Pointer(pInode)).FnShared > int32(1) {
|
|
/* We are trying for an exclusive lock but another thread in this
|
|
** same process is still holding a shared lock. */
|
|
rc = int32(SQLITE_BUSY)
|
|
} else {
|
|
if _unixIsSharingShmNode(tls, pFile) != 0 {
|
|
/* We are in WAL mode and attempting to delete the SHM and WAL
|
|
** files due to closing the connection or changing out of WAL mode,
|
|
** but another process still holds locks on the SHM file, thus
|
|
** indicating that database locks have been broken, perhaps due
|
|
** to a rogue close(open(dbFile)) or similar.
|
|
*/
|
|
rc = int32(SQLITE_BUSY)
|
|
} else {
|
|
/* The request was for a RESERVED or EXCLUSIVE lock. It is
|
|
** assumed that there is a SHARED or greater lock on the file
|
|
** already.
|
|
*/
|
|
(**(**Tflock)(__ccgo_up(bp))).Fl_type = int16(F_WRLCK)
|
|
if eFileLock == int32(RESERVED_LOCK) {
|
|
(**(**Tflock)(__ccgo_up(bp))).Fl_start = int64(_sqlite3PendingByte + libc.Int32FromInt32(1))
|
|
(**(**Tflock)(__ccgo_up(bp))).Fl_len = int64(1)
|
|
} else {
|
|
(**(**Tflock)(__ccgo_up(bp))).Fl_start = int64(_sqlite3PendingByte + libc.Int32FromInt32(2))
|
|
(**(**Tflock)(__ccgo_up(bp))).Fl_len = int64(SHARED_SIZE)
|
|
}
|
|
if _unixFileLock(tls, pFile, bp) != 0 {
|
|
tErrno = **(**int32)(__ccgo_up(libc.X__errno_location(tls)))
|
|
rc = _sqliteErrorFromPosixError(tls, tErrno, libc.Int32FromInt32(SQLITE_IOERR)|libc.Int32FromInt32(15)<<libc.Int32FromInt32(8))
|
|
if rc != int32(SQLITE_BUSY) {
|
|
_storeLastErrno(tls, pFile, tErrno)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if rc == SQLITE_OK {
|
|
(*TunixFile)(unsafe.Pointer(pFile)).FeFileLock = libc.Uint8FromInt32(eFileLock)
|
|
(*TunixInodeInfo)(unsafe.Pointer(pInode)).FeFileLock = libc.Uint8FromInt32(eFileLock)
|
|
}
|
|
goto end_lock
|
|
end_lock:
|
|
;
|
|
Xsqlite3_mutex_leave(tls, (*TunixInodeInfo)(unsafe.Pointer(pInode)).FpLockMutex)
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Write nBuf bytes of random data to the supplied buffer zBuf.
|
|
// */
|
|
func _unixRandomness(tls *libc.TLS, NotUsed uintptr, nBuf int32, zBuf uintptr) (r int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var fd, got int32
|
|
var _ /* rp at bp+8 */ Tpid_t
|
|
var _ /* t at bp+0 */ Ttime_t
|
|
_, _ = fd, got
|
|
_ = NotUsed
|
|
/* We have to initialize zBuf to prevent valgrind from reporting
|
|
** errors. The reports issued by valgrind are incorrect - we would
|
|
** prefer that the randomness be increased by making use of the
|
|
** uninitialized space in zBuf - but valgrind errors tend to worry
|
|
** some users. Rather than argue, it seems easier just to initialize
|
|
** the whole array and silence valgrind, even if that means less randomness
|
|
** in the random seed.
|
|
**
|
|
** When testing, initializing zBuf[] to zero is all we do. That means
|
|
** that we always use the same random number sequence. This makes the
|
|
** tests repeatable.
|
|
*/
|
|
libc.Xmemset(tls, zBuf, 0, libc.Uint64FromInt32(nBuf))
|
|
libc.AtomicStorePInt32(uintptr(unsafe.Pointer(&_randomnessPid)), libc.Xgetpid(tls))
|
|
fd = _robust_open(tls, __ccgo_ts+4099, O_RDONLY, uint32(0))
|
|
if fd < 0 {
|
|
libc.Xtime(tls, bp)
|
|
libc.Xmemcpy(tls, zBuf, bp, uint64(8))
|
|
**(**Tpid_t)(__ccgo_up(bp + 8)) = libc.AtomicLoadPInt32(uintptr(unsafe.Pointer(&_randomnessPid)))
|
|
libc.Xmemcpy(tls, zBuf+uintptr(8), bp+8, uint64(4))
|
|
nBuf = libc.Int32FromUint64(libc.Uint64FromInt64(8) + libc.Uint64FromInt64(4))
|
|
} else {
|
|
for cond := true; cond; cond = got < 0 && **(**int32)(__ccgo_up(libc.X__errno_location(tls))) == int32(EINTR) {
|
|
got = int32((*(*func(*libc.TLS, int32, uintptr, Tsize_t) Tssize_t)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(8)].FpCurrent})))(tls, fd, zBuf, libc.Uint64FromInt32(nBuf)))
|
|
}
|
|
_robust_close(tls, uintptr(0), fd, int32(47474))
|
|
}
|
|
return nBuf
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Attempt to set the size of the memory mapping maintained by file
|
|
// ** descriptor pFd to nNew bytes. Any existing mapping is discarded.
|
|
// **
|
|
// ** If successful, this function sets the following variables:
|
|
// **
|
|
// ** unixFile.pMapRegion
|
|
// ** unixFile.mmapSize
|
|
// ** unixFile.mmapSizeActual
|
|
// **
|
|
// ** If unsuccessful, an error message is logged via sqlite3_log() and
|
|
// ** the three variables above are zeroed. In this case SQLite should
|
|
// ** continue accessing the database using the xRead() and xWrite()
|
|
// ** methods.
|
|
// */
|
|
func _unixRemapfile(tls *libc.TLS, pFd uintptr, nNew Ti64) {
|
|
var flags, h int32
|
|
var nOrig, nReuse Ti64
|
|
var pNew, pOrig, pReq, zErr uintptr
|
|
var v1 Tsqlite3_int64
|
|
_, _, _, _, _, _, _, _, _ = flags, h, nOrig, nReuse, pNew, pOrig, pReq, zErr, v1
|
|
zErr = __ccgo_ts + 3700
|
|
h = (*TunixFile)(unsafe.Pointer(pFd)).Fh /* File descriptor open on db file */
|
|
pOrig = (*TunixFile)(unsafe.Pointer(pFd)).FpMapRegion /* Pointer to current file mapping */
|
|
nOrig = (*TunixFile)(unsafe.Pointer(pFd)).FmmapSizeActual /* Size of pOrig region in bytes */
|
|
pNew = uintptr(0) /* Location of new mapping */
|
|
flags = int32(PROT_READ) /* Flags to pass to mmap() */
|
|
if pOrig != 0 {
|
|
nReuse = (*TunixFile)(unsafe.Pointer(pFd)).FmmapSize
|
|
pReq = pOrig + uintptr(nReuse)
|
|
/* Unmap any pages of the existing mapping that cannot be reused. */
|
|
if nReuse != nOrig {
|
|
(*(*func(*libc.TLS, uintptr, Tsize_t) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(23)].FpCurrent})))(tls, pReq, libc.Uint64FromInt64(nOrig-nReuse))
|
|
}
|
|
pNew = (*(*func(*libc.TLS, uintptr, Tsize_t, Tsize_t, int32, uintptr) uintptr)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(24)].FpCurrent})))(tls, pOrig, libc.Uint64FromInt64(nReuse), libc.Uint64FromInt64(nNew), int32(MREMAP_MAYMOVE), 0)
|
|
zErr = __ccgo_ts + 3712
|
|
/* The attempt to extend the existing mapping failed. Free it. */
|
|
if pNew == uintptr(-libc.Int32FromInt32(1)) || pNew == uintptr(0) {
|
|
(*(*func(*libc.TLS, uintptr, Tsize_t) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(23)].FpCurrent})))(tls, pOrig, libc.Uint64FromInt64(nReuse))
|
|
}
|
|
}
|
|
/* If pNew is still NULL, try to create an entirely new mapping. */
|
|
if pNew == uintptr(0) {
|
|
pNew = (*(*func(*libc.TLS, uintptr, Tsize_t, int32, int32, int32, Toff_t) uintptr)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(22)].FpCurrent})))(tls, uintptr(0), libc.Uint64FromInt64(nNew), flags, int32(MAP_SHARED), h, 0)
|
|
}
|
|
if pNew == uintptr(-libc.Int32FromInt32(1)) {
|
|
pNew = uintptr(0)
|
|
nNew = 0
|
|
_unixLogErrorAtLine(tls, SQLITE_OK, zErr, (*TunixFile)(unsafe.Pointer(pFd)).FzPath, int32(45992))
|
|
/* If the mmap() above failed, assume that all subsequent mmap() calls
|
|
** will probably fail too. Fall back to using xRead/xWrite exclusively
|
|
** in this case. */
|
|
(*TunixFile)(unsafe.Pointer(pFd)).FmmapSizeMax = 0
|
|
}
|
|
(*TunixFile)(unsafe.Pointer(pFd)).FpMapRegion = pNew
|
|
v1 = nNew
|
|
(*TunixFile)(unsafe.Pointer(pFd)).FmmapSizeActual = v1
|
|
(*TunixFile)(unsafe.Pointer(pFd)).FmmapSize = v1
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Change the lock state for a shared-memory segment.
|
|
// **
|
|
// ** Note that the relationship between SHARED and EXCLUSIVE locks is a little
|
|
// ** different here than in posix. In xShmLock(), one can go from unlocked
|
|
// ** to shared and back or from unlocked to exclusive and back. But one may
|
|
// ** not go from shared to exclusive or from exclusive to shared.
|
|
// */
|
|
func _unixShmLock(tls *libc.TLS, fd uintptr, ofst int32, n int32, flags int32) (r int32) {
|
|
var aLock, p, pDbFd, pShmNode, v1 uintptr
|
|
var bUnlock, ii, rc int32
|
|
var mask Tu16
|
|
_, _, _, _, _, _, _, _, _ = aLock, bUnlock, ii, mask, p, pDbFd, pShmNode, rc, v1
|
|
pDbFd = fd /* The underlying file iNode */
|
|
rc = SQLITE_OK /* Result code */
|
|
mask = libc.Uint16FromInt32(int32(1)<<(ofst+n) - int32(1)<<ofst)
|
|
p = (*TunixFile)(unsafe.Pointer(pDbFd)).FpShm
|
|
if p == uintptr(0) {
|
|
return libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(20)<<libc.Int32FromInt32(8)
|
|
}
|
|
pShmNode = (*TunixShm)(unsafe.Pointer(p)).FpShmNode
|
|
if pShmNode == uintptr(0) {
|
|
return libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(20)<<libc.Int32FromInt32(8)
|
|
}
|
|
aLock = pShmNode + 64
|
|
/* Check that, if this to be a blocking lock, no locks that occur later
|
|
** in the following list than the lock being obtained are already held:
|
|
**
|
|
** 1. Recovery lock (ofst==2).
|
|
** 2. Checkpointer lock (ofst==1).
|
|
** 3. Write lock (ofst==0).
|
|
** 4. Read locks (ofst>=3 && ofst<SQLITE_SHM_NLOCK).
|
|
**
|
|
** In other words, if this is a blocking lock, none of the locks that
|
|
** occur later in the above list than the lock being obtained may be
|
|
** held.
|
|
*/
|
|
/* Check if there is any work to do. There are three cases:
|
|
**
|
|
** a) An unlock operation where there are locks to unlock,
|
|
** b) An shared lock where the requested lock is not already held
|
|
** c) An exclusive lock where the requested lock is not already held
|
|
**
|
|
** The SQLite core never requests an exclusive lock that it already holds.
|
|
** This is assert()ed below.
|
|
*/
|
|
if flags&int32(SQLITE_SHM_UNLOCK) != 0 && (libc.Int32FromUint16((*TunixShm)(unsafe.Pointer(p)).FexclMask)|libc.Int32FromUint16((*TunixShm)(unsafe.Pointer(p)).FsharedMask))&libc.Int32FromUint16(mask) != 0 || flags == libc.Int32FromInt32(SQLITE_SHM_SHARED)|libc.Int32FromInt32(SQLITE_SHM_LOCK) && 0 == libc.Int32FromUint16((*TunixShm)(unsafe.Pointer(p)).FsharedMask)&libc.Int32FromUint16(mask) || flags == libc.Int32FromInt32(SQLITE_SHM_EXCLUSIVE)|libc.Int32FromInt32(SQLITE_SHM_LOCK) {
|
|
/* Take the required mutexes. In SETLK_TIMEOUT mode (blocking locks), if
|
|
** this is an attempt on an exclusive lock use sqlite3_mutex_try(). If any
|
|
** other thread is holding this mutex, then it is either holding or about
|
|
** to hold a lock exclusive to the one being requested, and we may
|
|
** therefore return SQLITE_BUSY to the caller.
|
|
**
|
|
** Doing this prevents some deadlock scenarios. For example, thread 1 may
|
|
** be a checkpointer blocked waiting on the WRITER lock. And thread 2
|
|
** may be a normal SQL client upgrading to a write transaction. In this
|
|
** case thread 2 does a non-blocking request for the WRITER lock. But -
|
|
** if it were to use sqlite3_mutex_enter() then it would effectively
|
|
** become a (doomed) blocking request, as thread 2 would block until thread
|
|
** 1 obtained WRITER and released the mutex. Since thread 2 already holds
|
|
** a lock on a read-locking slot at this point, this breaks the
|
|
** anti-deadlock rules (see above). */
|
|
Xsqlite3_mutex_enter(tls, (*TunixShmNode)(unsafe.Pointer(pShmNode)).FpShmMutex)
|
|
if rc == SQLITE_OK {
|
|
if flags&int32(SQLITE_SHM_UNLOCK) != 0 {
|
|
/* Case (a) - unlock. */
|
|
bUnlock = int32(1)
|
|
/* If this is a SHARED lock being unlocked, it is possible that other
|
|
** clients within this process are holding the same SHARED lock. In
|
|
** this case, set bUnlock to 0 so that the posix lock is not removed
|
|
** from the file-descriptor below. */
|
|
if flags&int32(SQLITE_SHM_SHARED) != 0 {
|
|
if **(**int32)(__ccgo_up(aLock + uintptr(ofst)*4)) > int32(1) {
|
|
bUnlock = 0
|
|
**(**int32)(__ccgo_up(aLock + uintptr(ofst)*4)) = **(**int32)(__ccgo_up(aLock + uintptr(ofst)*4)) - 1
|
|
v1 = p + 18
|
|
*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) & ^libc.Int32FromUint16(mask))
|
|
}
|
|
}
|
|
if bUnlock != 0 {
|
|
rc = _unixShmSystemLock(tls, pDbFd, int32(F_UNLCK), ofst+(libc.Int32FromInt32(22)+libc.Int32FromInt32(SQLITE_SHM_NLOCK))*libc.Int32FromInt32(4), n)
|
|
if rc == SQLITE_OK {
|
|
libc.Xmemset(tls, aLock+uintptr(ofst)*4, 0, uint64(4)*libc.Uint64FromInt32(n))
|
|
v1 = p + 18
|
|
*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) & ^libc.Int32FromUint16(mask))
|
|
v1 = p + 20
|
|
*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) & ^libc.Int32FromUint16(mask))
|
|
}
|
|
}
|
|
} else {
|
|
if flags&int32(SQLITE_SHM_SHARED) != 0 {
|
|
/* Case (b) - a shared lock. */
|
|
if **(**int32)(__ccgo_up(aLock + uintptr(ofst)*4)) < 0 {
|
|
/* An exclusive lock is held by some other connection. BUSY. */
|
|
rc = int32(SQLITE_BUSY)
|
|
} else {
|
|
if **(**int32)(__ccgo_up(aLock + uintptr(ofst)*4)) == 0 {
|
|
rc = _unixShmSystemLock(tls, pDbFd, F_RDLCK, ofst+(libc.Int32FromInt32(22)+libc.Int32FromInt32(SQLITE_SHM_NLOCK))*libc.Int32FromInt32(4), n)
|
|
}
|
|
}
|
|
/* Get the local shared locks */
|
|
if rc == SQLITE_OK {
|
|
v1 = p + 18
|
|
*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) | libc.Int32FromUint16(mask))
|
|
**(**int32)(__ccgo_up(aLock + uintptr(ofst)*4)) = **(**int32)(__ccgo_up(aLock + uintptr(ofst)*4)) + 1
|
|
}
|
|
} else {
|
|
/* Make sure no sibling connections hold locks that will block this
|
|
** lock. If any do, return SQLITE_BUSY right away. */
|
|
ii = ofst
|
|
for {
|
|
if !(ii < ofst+n) {
|
|
break
|
|
}
|
|
if **(**int32)(__ccgo_up(aLock + uintptr(ii)*4)) != 0 {
|
|
rc = int32(SQLITE_BUSY)
|
|
break
|
|
}
|
|
goto _5
|
|
_5:
|
|
;
|
|
ii = ii + 1
|
|
}
|
|
/* Get the exclusive locks at the system level. Then if successful
|
|
** also update the in-memory values. */
|
|
if rc == SQLITE_OK {
|
|
rc = _unixShmSystemLock(tls, pDbFd, int32(F_WRLCK), ofst+(libc.Int32FromInt32(22)+libc.Int32FromInt32(SQLITE_SHM_NLOCK))*libc.Int32FromInt32(4), n)
|
|
if rc == SQLITE_OK {
|
|
v1 = p + 20
|
|
*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) | libc.Int32FromUint16(mask))
|
|
ii = ofst
|
|
for {
|
|
if !(ii < ofst+n) {
|
|
break
|
|
}
|
|
**(**int32)(__ccgo_up(aLock + uintptr(ii)*4)) = -int32(1)
|
|
goto _7
|
|
_7:
|
|
;
|
|
ii = ii + 1
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/* Drop the mutexes acquired above. */
|
|
Xsqlite3_mutex_leave(tls, (*TunixShmNode)(unsafe.Pointer(pShmNode)).FpShmMutex)
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Make sure all writes to a particular file are committed to disk.
|
|
// **
|
|
// ** If dataOnly==0 then both the file itself and its metadata (file
|
|
// ** size, access time, etc) are synced. If dataOnly!=0 then only the
|
|
// ** file data is synced.
|
|
// **
|
|
// ** Under Unix, also make sure that the directory entry for the file
|
|
// ** has been created by fsync-ing the directory that contains the file.
|
|
// ** If we do not do this and we encounter a power failure, the directory
|
|
// ** entry for the journal might not exist after we reboot. The next
|
|
// ** SQLite to access the file will not know that the journal exists (because
|
|
// ** the directory entry for the journal was never created) and the transaction
|
|
// ** will not roll back - possibly leading to database corruption.
|
|
// */
|
|
func _unixSync(tls *libc.TLS, id uintptr, flags int32) (r int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var isDataOnly, isFullsync, rc int32
|
|
var pFile, v1 uintptr
|
|
var _ /* dirfd at bp+0 */ int32
|
|
_, _, _, _, _ = isDataOnly, isFullsync, pFile, rc, v1
|
|
pFile = id
|
|
isDataOnly = flags & int32(SQLITE_SYNC_DATAONLY)
|
|
isFullsync = libc.BoolInt32(flags&int32(0x0F) == int32(SQLITE_SYNC_FULL))
|
|
/* Check that one of SQLITE_SYNC_NORMAL or FULL was passed */
|
|
/* Unix cannot, but some systems may return SQLITE_FULL from here. This
|
|
** line is to test that doing so does not cause any problems.
|
|
*/
|
|
rc = _full_fsync(tls, (*TunixFile)(unsafe.Pointer(pFile)).Fh, isFullsync, isDataOnly)
|
|
if rc != 0 {
|
|
_storeLastErrno(tls, pFile, **(**int32)(__ccgo_up(libc.X__errno_location(tls))))
|
|
return _unixLogErrorAtLine(tls, libc.Int32FromInt32(SQLITE_IOERR)|libc.Int32FromInt32(4)<<libc.Int32FromInt32(8), __ccgo_ts+3971, (*TunixFile)(unsafe.Pointer(pFile)).FzPath, int32(44276))
|
|
}
|
|
/* Also fsync the directory containing the file if the DIRSYNC flag
|
|
** is set. This is a one-time occurrence. Many systems (examples: AIX)
|
|
** are unable to fsync a directory, so ignore errors on the fsync.
|
|
*/
|
|
if libc.Int32FromUint16((*TunixFile)(unsafe.Pointer(pFile)).FctrlFlags)&int32(UNIXFILE_DIRSYNC) != 0 {
|
|
rc = (*(*func(*libc.TLS, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(17)].FpCurrent})))(tls, (*TunixFile)(unsafe.Pointer(pFile)).FzPath, bp)
|
|
if rc == SQLITE_OK {
|
|
_full_fsync(tls, **(**int32)(__ccgo_up(bp)), 0, 0)
|
|
_robust_close(tls, pFile, **(**int32)(__ccgo_up(bp)), int32(44290))
|
|
} else {
|
|
rc = SQLITE_OK
|
|
}
|
|
v1 = pFile + 30
|
|
*(*uint16)(unsafe.Pointer(v1)) = uint16(int32(*(*uint16)(unsafe.Pointer(v1))) & ^libc.Int32FromInt32(UNIXFILE_DIRSYNC))
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** The expression object indicated by the second argument is guaranteed
|
|
// ** to be a scalar SQL function. If
|
|
// **
|
|
// ** * all function arguments are SQL literals,
|
|
// ** * one of the SQLITE_FUNC_CONSTANT or _SLOCHNG function flags is set, and
|
|
// ** * the SQLITE_FUNC_NEEDCOLL function flag is not set,
|
|
// **
|
|
// ** then this routine attempts to invoke the SQL function. Assuming no
|
|
// ** error occurs, output parameter (*ppVal) is set to point to a value
|
|
// ** object containing the result before returning SQLITE_OK.
|
|
// **
|
|
// ** Affinity aff is applied to the result of the function before returning.
|
|
// ** If the result is a text value, the sqlite3_value object uses encoding
|
|
// ** enc.
|
|
// **
|
|
// ** If the conditions above are not met, this function returns SQLITE_OK
|
|
// ** and sets (*ppVal) to NULL. Or, if an error occurs, (*ppVal) is set to
|
|
// ** NULL and an SQLite error code returned.
|
|
// */
|
|
func _valueFromFunction(tls *libc.TLS, db uintptr, p uintptr, enc Tu8, aff Tu8, ppVal uintptr, pCtx uintptr) (r int32) {
|
|
bp := tls.Alloc(64)
|
|
defer tls.Free(64)
|
|
var apVal, pFunc, pList, pVal uintptr
|
|
var i, nVal, rc int32
|
|
var _ /* ctx at bp+0 */ Tsqlite3_context
|
|
_, _, _, _, _, _, _ = apVal, i, nVal, pFunc, pList, pVal, rc /* Context object for function invocation */
|
|
apVal = uintptr(0) /* Function arguments */
|
|
nVal = 0 /* Number of function arguments */
|
|
pFunc = uintptr(0) /* Function definition */
|
|
pVal = uintptr(0) /* New value */
|
|
rc = SQLITE_OK /* Return code */
|
|
pList = uintptr(0) /* Iterator variable */
|
|
pList = *(*uintptr)(unsafe.Pointer(p + 32))
|
|
if pList != 0 {
|
|
nVal = (*TExprList)(unsafe.Pointer(pList)).FnExpr
|
|
}
|
|
pFunc = _sqlite3FindFunction(tls, db, *(*uintptr)(unsafe.Pointer(p + 8)), nVal, enc, uint8(0))
|
|
if (*TFuncDef)(unsafe.Pointer(pFunc)).FfuncFlags&libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_CONSTANT)|libc.Int32FromInt32(SQLITE_FUNC_SLOCHNG)) == uint32(0) || (*TFuncDef)(unsafe.Pointer(pFunc)).FfuncFlags&libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_FUNC_NEEDCOLL)|libc.Int32FromInt32(SQLITE_FUNC_RUNONLY)) != uint32(0) {
|
|
return SQLITE_OK
|
|
}
|
|
if pList != 0 {
|
|
apVal = _sqlite3DbMallocZero(tls, db, uint64(uint64(8)*libc.Uint64FromInt32(nVal)))
|
|
if apVal == uintptr(0) {
|
|
rc = int32(SQLITE_NOMEM)
|
|
goto value_from_function_out
|
|
}
|
|
i = 0
|
|
for {
|
|
if !(i < nVal) {
|
|
break
|
|
}
|
|
rc = _sqlite3Stat4ValueFromExpr(tls, (*TValueNewStat4Ctx)(unsafe.Pointer(pCtx)).FpParse, (*(*TExprList_item)(unsafe.Pointer(pList + 8 + uintptr(i)*32))).FpExpr, aff, apVal+uintptr(i)*8)
|
|
if **(**uintptr)(__ccgo_up(apVal + uintptr(i)*8)) == uintptr(0) || rc != SQLITE_OK {
|
|
goto value_from_function_out
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
}
|
|
pVal = _valueNew(tls, db, pCtx)
|
|
if pVal == uintptr(0) {
|
|
rc = int32(SQLITE_NOMEM)
|
|
goto value_from_function_out
|
|
}
|
|
libc.Xmemset(tls, bp, 0, uint64(48))
|
|
(**(**Tsqlite3_context)(__ccgo_up(bp))).FpOut = pVal
|
|
(**(**Tsqlite3_context)(__ccgo_up(bp))).FpFunc = pFunc
|
|
(**(**Tsqlite3_context)(__ccgo_up(bp))).Fenc = (*Tsqlite3)(unsafe.Pointer(db)).Fenc
|
|
(*(*func(*libc.TLS, uintptr, int32, uintptr))(unsafe.Pointer(&struct{ uintptr }{(*TFuncDef)(unsafe.Pointer(pFunc)).FxSFunc})))(tls, bp, nVal, apVal)
|
|
if (**(**Tsqlite3_context)(__ccgo_up(bp))).FisError != 0 {
|
|
rc = (**(**Tsqlite3_context)(__ccgo_up(bp))).FisError
|
|
_sqlite3ErrorMsg(tls, (*TValueNewStat4Ctx)(unsafe.Pointer(pCtx)).FpParse, __ccgo_ts+3968, libc.VaList(bp+56, Xsqlite3_value_text(tls, pVal)))
|
|
} else {
|
|
_sqlite3ValueApplyAffinity(tls, pVal, aff, uint8(SQLITE_UTF8))
|
|
rc = _sqlite3VdbeChangeEncoding(tls, pVal, libc.Int32FromUint8(enc))
|
|
if rc == SQLITE_OK && _sqlite3VdbeMemTooBig(tls, pVal) != 0 {
|
|
rc = int32(SQLITE_TOOBIG)
|
|
(*TParse)(unsafe.Pointer((*TValueNewStat4Ctx)(unsafe.Pointer(pCtx)).FpParse)).FnErr = (*TParse)(unsafe.Pointer((*TValueNewStat4Ctx)(unsafe.Pointer(pCtx)).FpParse)).FnErr + 1
|
|
}
|
|
}
|
|
goto value_from_function_out
|
|
value_from_function_out:
|
|
;
|
|
if rc != SQLITE_OK {
|
|
pVal = uintptr(0)
|
|
(*TParse)(unsafe.Pointer((*TValueNewStat4Ctx)(unsafe.Pointer(pCtx)).FpParse)).Frc = rc
|
|
}
|
|
if apVal != 0 {
|
|
i = 0
|
|
for {
|
|
if !(i < nVal) {
|
|
break
|
|
}
|
|
_sqlite3ValueFree(tls, **(**uintptr)(__ccgo_up(apVal + uintptr(i)*8)))
|
|
goto _2
|
|
_2:
|
|
;
|
|
i = i + 1
|
|
}
|
|
_sqlite3DbFreeNN(tls, db, apVal)
|
|
}
|
|
**(**uintptr)(__ccgo_up(ppVal)) = pVal
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** A read or write transaction may or may not be active on database handle
|
|
// ** db. If a transaction is active, commit it. If there is a
|
|
// ** write-transaction spanning more than one database file, this routine
|
|
// ** takes care of the super-journal trickery.
|
|
// */
|
|
func _vdbeCommit(tls *libc.TLS, db uintptr, p uintptr) (r int32) {
|
|
bp := tls.Alloc(48)
|
|
defer tls.Free(48)
|
|
var i, nMainFile, nTrans, needXcommit, rc, retryCount, txn, v5 int32
|
|
var offset Ti64
|
|
var pBt, pBt1, pBt2, pBt3, pBt4, pBt5, pPager, pVfs, zFile, zMainFile, zSuper uintptr
|
|
var v6 bool
|
|
var _ /* iRandom at bp+12 */ Tu32
|
|
var _ /* pSuperJrnl at bp+0 */ uintptr
|
|
var _ /* res at bp+8 */ int32
|
|
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = i, nMainFile, nTrans, needXcommit, offset, pBt, pBt1, pBt2, pBt3, pBt4, pBt5, pPager, pVfs, rc, retryCount, txn, zFile, zMainFile, zSuper, v5, v6
|
|
nTrans = 0 /* Number of databases with an active write-transaction
|
|
** that are candidates for a two-phase commit using a
|
|
** super-journal */
|
|
rc = SQLITE_OK
|
|
needXcommit = 0
|
|
/* Before doing anything else, call the xSync() callback for any
|
|
** virtual module tables written in this transaction. This has to
|
|
** be done before determining whether a super-journal file is
|
|
** required, as an xSync() callback may add an attached database
|
|
** to the transaction.
|
|
*/
|
|
rc = _sqlite3VtabSync(tls, db, p)
|
|
/* This loop determines (a) if the commit hook should be invoked and
|
|
** (b) how many database files have open write transactions, not
|
|
** including the temp database. (b) is important because if more than
|
|
** one database file has an open write transaction, a super-journal
|
|
** file is required for an atomic commit.
|
|
*/
|
|
i = 0
|
|
for {
|
|
if !(rc == SQLITE_OK && i < (*Tsqlite3)(unsafe.Pointer(db)).FnDb) {
|
|
break
|
|
}
|
|
pBt = (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(i)*32))).FpBt
|
|
if _sqlite3BtreeTxnState(tls, pBt) == int32(SQLITE_TXN_WRITE) {
|
|
needXcommit = int32(1)
|
|
_sqlite3BtreeEnter(tls, pBt)
|
|
pPager = _sqlite3BtreePager(tls, pBt)
|
|
if libc.Int32FromUint8((**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(i)*32))).Fsafety_level) != int32(PAGER_SYNCHRONOUS_OFF) && _aMJNeeded[_sqlite3PagerGetJournalMode(tls, pPager)] != 0 && _sqlite3PagerIsMemdb(tls, pPager) == 0 {
|
|
nTrans = nTrans + 1
|
|
}
|
|
rc = _sqlite3PagerExclusiveLock(tls, pPager)
|
|
_sqlite3BtreeLeave(tls, pBt)
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
if rc != SQLITE_OK {
|
|
return rc
|
|
}
|
|
/* If there are any write-transactions at all, invoke the commit hook */
|
|
if needXcommit != 0 && (*Tsqlite3)(unsafe.Pointer(db)).FxCommitCallback != 0 {
|
|
rc = (*(*func(*libc.TLS, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*Tsqlite3)(unsafe.Pointer(db)).FxCommitCallback})))(tls, (*Tsqlite3)(unsafe.Pointer(db)).FpCommitArg)
|
|
if rc != 0 {
|
|
return libc.Int32FromInt32(SQLITE_CONSTRAINT) | libc.Int32FromInt32(2)<<libc.Int32FromInt32(8)
|
|
}
|
|
}
|
|
/* The simple case - no more than one database file (not counting the
|
|
** TEMP database) has a transaction active. There is no need for the
|
|
** super-journal.
|
|
**
|
|
** If the return value of sqlite3BtreeGetFilename() is a zero length
|
|
** string, it means the main database is :memory: or a temp file. In
|
|
** that case we do not support atomic multi-file commits, so use the
|
|
** simple case then too.
|
|
*/
|
|
if 0 == _sqlite3Strlen30(tls, _sqlite3BtreeGetFilename(tls, (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb))).FpBt)) || nTrans <= int32(1) {
|
|
if needXcommit != 0 {
|
|
i = 0
|
|
for {
|
|
if !(rc == SQLITE_OK && i < (*Tsqlite3)(unsafe.Pointer(db)).FnDb) {
|
|
break
|
|
}
|
|
pBt1 = (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(i)*32))).FpBt
|
|
if _sqlite3BtreeTxnState(tls, pBt1) >= int32(SQLITE_TXN_WRITE) {
|
|
rc = _sqlite3BtreeCommitPhaseOne(tls, pBt1, uintptr(0))
|
|
}
|
|
goto _2
|
|
_2:
|
|
;
|
|
i = i + 1
|
|
}
|
|
}
|
|
/* Do the commit only if all databases successfully complete phase 1.
|
|
** If one of the BtreeCommitPhaseOne() calls fails, this indicates an
|
|
** IO error while deleting or truncating a journal file. It is unlikely,
|
|
** but could happen. In this case abandon processing and return the error.
|
|
*/
|
|
i = 0
|
|
for {
|
|
if !(rc == SQLITE_OK && i < (*Tsqlite3)(unsafe.Pointer(db)).FnDb) {
|
|
break
|
|
}
|
|
pBt2 = (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(i)*32))).FpBt
|
|
txn = _sqlite3BtreeTxnState(tls, pBt2)
|
|
if txn != SQLITE_TXN_NONE {
|
|
rc = _sqlite3BtreeCommitPhaseTwo(tls, pBt2, 0)
|
|
}
|
|
goto _3
|
|
_3:
|
|
;
|
|
i = i + 1
|
|
}
|
|
if rc == SQLITE_OK {
|
|
_sqlite3VtabCommit(tls, db)
|
|
}
|
|
} else {
|
|
pVfs = (*Tsqlite3)(unsafe.Pointer(db)).FpVfs
|
|
zSuper = uintptr(0) /* File-name for the super-journal */
|
|
zMainFile = _sqlite3BtreeGetFilename(tls, (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb))).FpBt)
|
|
**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
|
|
offset = 0
|
|
retryCount = 0
|
|
/* Select a super-journal file name */
|
|
nMainFile = _sqlite3Strlen30(tls, zMainFile)
|
|
zSuper = _sqlite3MPrintf(tls, db, __ccgo_ts+5366, libc.VaList(bp+24, 0, zMainFile, 0))
|
|
if zSuper == uintptr(0) {
|
|
return int32(SQLITE_NOMEM)
|
|
}
|
|
zSuper = zSuper + uintptr(4)
|
|
for cond := true; cond; cond = rc == SQLITE_OK && **(**int32)(__ccgo_up(bp + 8)) != 0 {
|
|
if retryCount != 0 {
|
|
if retryCount > int32(100) {
|
|
Xsqlite3_log(tls, int32(SQLITE_FULL), __ccgo_ts+5378, libc.VaList(bp+24, zSuper))
|
|
_sqlite3OsDelete(tls, pVfs, zSuper, 0)
|
|
break
|
|
} else {
|
|
if retryCount == int32(1) {
|
|
Xsqlite3_log(tls, int32(SQLITE_FULL), __ccgo_ts+5392, libc.VaList(bp+24, zSuper))
|
|
}
|
|
}
|
|
}
|
|
retryCount = retryCount + 1
|
|
Xsqlite3_randomness(tls, int32(4), bp+12)
|
|
Xsqlite3_snprintf(tls, int32(13), zSuper+uintptr(nMainFile), __ccgo_ts+5407, libc.VaList(bp+24, **(**Tu32)(__ccgo_up(bp + 12))>>libc.Int32FromInt32(8)&uint32(0xffffff), **(**Tu32)(__ccgo_up(bp + 12))&uint32(0xff)))
|
|
/* The antipenultimate character of the super-journal name must
|
|
** be "9" to avoid name collisions when using 8+3 filenames. */
|
|
rc = _sqlite3OsAccess(tls, pVfs, zSuper, SQLITE_ACCESS_EXISTS, bp+8)
|
|
}
|
|
if rc == SQLITE_OK {
|
|
/* Open the super-journal. */
|
|
rc = _sqlite3OsOpenMalloc(tls, pVfs, zSuper, bp, libc.Int32FromInt32(SQLITE_OPEN_READWRITE)|libc.Int32FromInt32(SQLITE_OPEN_CREATE)|libc.Int32FromInt32(SQLITE_OPEN_EXCLUSIVE)|libc.Int32FromInt32(SQLITE_OPEN_SUPER_JOURNAL), uintptr(0))
|
|
}
|
|
if rc != SQLITE_OK {
|
|
_sqlite3DbFree(tls, db, zSuper-uintptr(4))
|
|
return rc
|
|
}
|
|
/* Write the name of each database file in the transaction into the new
|
|
** super-journal file. If an error occurs at this point close
|
|
** and delete the super-journal file. All the individual journal files
|
|
** still have 'null' as the super-journal pointer, so they will roll
|
|
** back independently if a failure occurs.
|
|
*/
|
|
i = 0
|
|
for {
|
|
if !(i < (*Tsqlite3)(unsafe.Pointer(db)).FnDb) {
|
|
break
|
|
}
|
|
pBt3 = (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(i)*32))).FpBt
|
|
if _sqlite3BtreeTxnState(tls, pBt3) == int32(SQLITE_TXN_WRITE) {
|
|
zFile = _sqlite3BtreeGetJournalname(tls, pBt3)
|
|
if zFile == uintptr(0) {
|
|
goto _4 /* Ignore TEMP and :memory: databases */
|
|
}
|
|
rc = _sqlite3OsWrite(tls, **(**uintptr)(__ccgo_up(bp)), zFile, _sqlite3Strlen30(tls, zFile)+int32(1), offset)
|
|
offset = offset + int64(_sqlite3Strlen30(tls, zFile)+int32(1))
|
|
if rc != SQLITE_OK {
|
|
_sqlite3OsCloseFree(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
_sqlite3OsDelete(tls, pVfs, zSuper, 0)
|
|
_sqlite3DbFree(tls, db, zSuper-uintptr(4))
|
|
return rc
|
|
}
|
|
}
|
|
goto _4
|
|
_4:
|
|
;
|
|
i = i + 1
|
|
}
|
|
/* Sync the super-journal file. If the IOCAP_SEQUENTIAL device
|
|
** flag is set this is not required.
|
|
*/
|
|
if v6 = 0 == _sqlite3OsDeviceCharacteristics(tls, **(**uintptr)(__ccgo_up(bp)))&int32(SQLITE_IOCAP_SEQUENTIAL); v6 {
|
|
v5 = _sqlite3OsSync(tls, **(**uintptr)(__ccgo_up(bp)), int32(SQLITE_SYNC_NORMAL))
|
|
rc = v5
|
|
}
|
|
if v6 && SQLITE_OK != v5 {
|
|
_sqlite3OsCloseFree(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
_sqlite3OsDelete(tls, pVfs, zSuper, 0)
|
|
_sqlite3DbFree(tls, db, zSuper-uintptr(4))
|
|
return rc
|
|
}
|
|
/* Sync all the db files involved in the transaction. The same call
|
|
** sets the super-journal pointer in each individual journal. If
|
|
** an error occurs here, do not delete the super-journal file.
|
|
**
|
|
** If the error occurs during the first call to
|
|
** sqlite3BtreeCommitPhaseOne(), then there is a chance that the
|
|
** super-journal file will be orphaned. But we cannot delete it,
|
|
** in case the super-journal file name was written into the journal
|
|
** file before the failure occurred.
|
|
*/
|
|
i = 0
|
|
for {
|
|
if !(rc == SQLITE_OK && i < (*Tsqlite3)(unsafe.Pointer(db)).FnDb) {
|
|
break
|
|
}
|
|
pBt4 = (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(i)*32))).FpBt
|
|
if pBt4 != 0 {
|
|
rc = _sqlite3BtreeCommitPhaseOne(tls, pBt4, zSuper)
|
|
}
|
|
goto _7
|
|
_7:
|
|
;
|
|
i = i + 1
|
|
}
|
|
_sqlite3OsCloseFree(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
if rc != SQLITE_OK {
|
|
_sqlite3DbFree(tls, db, zSuper-uintptr(4))
|
|
return rc
|
|
}
|
|
/* Delete the super-journal file. This commits the transaction. After
|
|
** doing this the directory is synced again before any individual
|
|
** transaction files are deleted.
|
|
*/
|
|
rc = _sqlite3OsDelete(tls, pVfs, zSuper, int32(1))
|
|
_sqlite3DbFree(tls, db, zSuper-uintptr(4))
|
|
zSuper = uintptr(0)
|
|
if rc != 0 {
|
|
return rc
|
|
}
|
|
/* All files and directories have already been synced, so the following
|
|
** calls to sqlite3BtreeCommitPhaseTwo() are only closing files and
|
|
** deleting or truncating journals. If something goes wrong while
|
|
** this is happening we don't really care. The integrity of the
|
|
** transaction is already guaranteed, but some stray 'cold' journals
|
|
** may be lying around. Returning an error code won't help matters.
|
|
*/
|
|
_sqlite3BeginBenignMalloc(tls)
|
|
i = 0
|
|
for {
|
|
if !(i < (*Tsqlite3)(unsafe.Pointer(db)).FnDb) {
|
|
break
|
|
}
|
|
pBt5 = (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(i)*32))).FpBt
|
|
if pBt5 != 0 {
|
|
_sqlite3BtreeCommitPhaseTwo(tls, pBt5, int32(1))
|
|
}
|
|
goto _8
|
|
_8:
|
|
;
|
|
i = i + 1
|
|
}
|
|
_sqlite3EndBenignMalloc(tls)
|
|
_sqlite3VtabCommit(tls, db)
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** The table object reference passed as the second argument to this function
|
|
// ** must represent a virtual table. This function invokes the xBestIndex()
|
|
// ** method of the virtual table with the sqlite3_index_info object that
|
|
// ** comes in as the 3rd argument to this function.
|
|
// **
|
|
// ** If an error occurs, pParse is populated with an error message and an
|
|
// ** appropriate error code is returned. A return of SQLITE_CONSTRAINT from
|
|
// ** xBestIndex is not considered an error. SQLITE_CONSTRAINT indicates that
|
|
// ** the current configuration of "unusable" flags in sqlite3_index_info can
|
|
// ** not result in a valid plan.
|
|
// **
|
|
// ** Whether or not an error is returned, it is the responsibility of the
|
|
// ** caller to eventually free p->idxStr if p->needToFreeIdxStr indicates
|
|
// ** that this is required.
|
|
// */
|
|
func _vtabBestIndex(tls *libc.TLS, pParse uintptr, pTab uintptr, p uintptr) (r int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var pVtab uintptr
|
|
var rc int32
|
|
_, _ = pVtab, rc
|
|
pVtab = (*TVTable)(unsafe.Pointer(_sqlite3GetVTable(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, pTab))).FpVtab
|
|
(*Tsqlite3)(unsafe.Pointer((*TParse)(unsafe.Pointer(pParse)).Fdb)).FnSchemaLock = (*Tsqlite3)(unsafe.Pointer((*TParse)(unsafe.Pointer(pParse)).Fdb)).FnSchemaLock + 1
|
|
rc = (*(*func(*libc.TLS, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*Tsqlite3_module)(unsafe.Pointer((*Tsqlite3_vtab)(unsafe.Pointer(pVtab)).FpModule)).FxBestIndex})))(tls, pVtab, p)
|
|
(*Tsqlite3)(unsafe.Pointer((*TParse)(unsafe.Pointer(pParse)).Fdb)).FnSchemaLock = (*Tsqlite3)(unsafe.Pointer((*TParse)(unsafe.Pointer(pParse)).Fdb)).FnSchemaLock - 1
|
|
if rc != SQLITE_OK && rc != int32(SQLITE_CONSTRAINT) {
|
|
if rc == int32(SQLITE_NOMEM) {
|
|
_sqlite3OomFault(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb)
|
|
} else {
|
|
if !((*Tsqlite3_vtab)(unsafe.Pointer(pVtab)).FzErrMsg != 0) {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+3968, libc.VaList(bp+8, _sqlite3ErrStr(tls, rc)))
|
|
} else {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+3968, libc.VaList(bp+8, (*Tsqlite3_vtab)(unsafe.Pointer(pVtab)).FzErrMsg))
|
|
}
|
|
}
|
|
}
|
|
if (*TVTable)(unsafe.Pointer((*(*struct {
|
|
FnArg int32
|
|
FazArg uintptr
|
|
Fp uintptr
|
|
})(unsafe.Pointer(pTab + 64))).Fp)).FbAllSchemas != 0 {
|
|
_sqlite3VtabUsesAllSchemas(tls, pParse)
|
|
}
|
|
Xsqlite3_free(tls, (*Tsqlite3_vtab)(unsafe.Pointer(pVtab)).FzErrMsg)
|
|
(*Tsqlite3_vtab)(unsafe.Pointer(pVtab)).FzErrMsg = uintptr(0)
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /* Return true if table pTab is read-only.
|
|
// **
|
|
// ** A table is read-only if any of the following are true:
|
|
// **
|
|
// ** 1) It is a virtual table and no implementation of the xUpdate method
|
|
// ** has been provided
|
|
// **
|
|
// ** 2) A trigger is currently being coded and the table is a virtual table
|
|
// ** that is SQLITE_VTAB_DIRECTONLY or if PRAGMA trusted_schema=OFF and
|
|
// ** the table is not SQLITE_VTAB_INNOCUOUS.
|
|
// **
|
|
// ** 3) It is a system table (i.e. sqlite_schema), this call is not
|
|
// ** part of a nested parse and writable_schema pragma has not
|
|
// ** been specified
|
|
// **
|
|
// ** 4) The table is a shadow table, the database connection is in
|
|
// ** defensive mode, and the current sqlite3_prepare()
|
|
// ** is for a top-level SQL statement.
|
|
// */
|
|
func _vtabIsReadOnly(tls *libc.TLS, pParse uintptr, pTab uintptr) (r int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
if (*Tsqlite3_module)(unsafe.Pointer((*TModule)(unsafe.Pointer((*TVTable)(unsafe.Pointer(_sqlite3GetVTable(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, pTab))).FpMod)).FpModule)).FxUpdate == uintptr(0) {
|
|
return int32(1)
|
|
}
|
|
/* Within triggers:
|
|
** * Do not allow DELETE, INSERT, or UPDATE of SQLITE_VTAB_DIRECTONLY
|
|
** virtual tables
|
|
** * Only allow DELETE, INSERT, or UPDATE of non-SQLITE_VTAB_INNOCUOUS
|
|
** virtual tables if PRAGMA trusted_schema=ON.
|
|
*/
|
|
if ((*TParse)(unsafe.Pointer(pParse)).FpToplevel != uintptr(0) || libc.Int32FromUint8((*TParse)(unsafe.Pointer(pParse)).FprepFlags)&int32(SQLITE_PREPARE_FROM_DDL) != 0) && libc.Int32FromUint8((*TVTable)(unsafe.Pointer((*(*struct {
|
|
FnArg int32
|
|
FazArg uintptr
|
|
Fp uintptr
|
|
})(unsafe.Pointer(pTab + 64))).Fp)).FeVtabRisk) > libc.BoolInt32((*Tsqlite3)(unsafe.Pointer((*TParse)(unsafe.Pointer(pParse)).Fdb)).Fflags&uint64(SQLITE_TrustedSchema) != uint64(0)) {
|
|
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+16373, libc.VaList(bp+8, (*TTable)(unsafe.Pointer(pTab)).FzName))
|
|
}
|
|
return 0
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This function is called as part of generating VM programs for RANGE
|
|
// ** offset PRECEDING/FOLLOWING frame boundaries. Assuming "ASC" order for
|
|
// ** the ORDER BY term in the window, and that argument op is OP_Ge, it generates
|
|
// ** code equivalent to:
|
|
// **
|
|
// ** if( csr1.peerVal + regVal >= csr2.peerVal ) goto lbl;
|
|
// **
|
|
// ** The value of parameter op may also be OP_Gt or OP_Le. In these cases the
|
|
// ** operator in the above pseudo-code is replaced with ">" or "<=", respectively.
|
|
// **
|
|
// ** If the sort-order for the ORDER BY term in the window is DESC, then the
|
|
// ** comparison is reversed. Instead of adding regVal to csr1.peerVal, it is
|
|
// ** subtracted. And the comparison operator is inverted to - ">=" becomes "<=",
|
|
// ** ">" becomes "<", and so on. So, with DESC sort order, if the argument op
|
|
// ** is OP_Ge, the generated code is equivalent to:
|
|
// **
|
|
// ** if( csr1.peerVal - regVal <= csr2.peerVal ) goto lbl;
|
|
// **
|
|
// ** A special type of arithmetic is used such that if csr1.peerVal is not
|
|
// ** a numeric type (real or integer), then the result of the addition
|
|
// ** or subtraction is a a copy of csr1.peerVal.
|
|
// */
|
|
func _windowCodeRangeTest(tls *libc.TLS, p uintptr, op int32, csr1 int32, regVal int32, csr2 int32, lbl int32) {
|
|
var addr, addrDone, addrGe, arith, reg1, reg2, regString, v1 int32
|
|
var pColl, pOrderBy, pParse, v, v2 uintptr
|
|
_, _, _, _, _, _, _, _, _, _, _, _, _ = addr, addrDone, addrGe, arith, pColl, pOrderBy, pParse, reg1, reg2, regString, v, v1, v2
|
|
pParse = (*TWindowCodeArg)(unsafe.Pointer(p)).FpParse
|
|
v = _sqlite3GetVdbe(tls, pParse)
|
|
pOrderBy = (*TWindow)(unsafe.Pointer((*TWindowCodeArg)(unsafe.Pointer(p)).FpMWin)).FpOrderBy /* ORDER BY clause for window */
|
|
reg1 = _sqlite3GetTempReg(tls, pParse) /* Reg. for csr1.peerVal+regVal */
|
|
reg2 = _sqlite3GetTempReg(tls, pParse)
|
|
v2 = pParse + 60
|
|
*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1
|
|
v1 = *(*int32)(unsafe.Pointer(v2)) /* Reg. for csr2.peerVal */
|
|
regString = v1 /* Reg. for constant value '' */
|
|
arith = int32(OP_Add) /* Jump destination */
|
|
addrDone = _sqlite3VdbeMakeLabel(tls, pParse)
|
|
/* Read the peer-value from each cursor into a register */
|
|
_windowReadPeerValues(tls, p, csr1, reg1)
|
|
_windowReadPeerValues(tls, p, csr2, reg2)
|
|
if libc.Int32FromUint8((*(*TExprList_item)(unsafe.Pointer(pOrderBy + 8))).Ffg.FsortFlags)&int32(KEYINFO_ORDER_DESC) != 0 {
|
|
switch op {
|
|
case int32(OP_Ge):
|
|
op = int32(OP_Le)
|
|
case int32(OP_Gt):
|
|
op = int32(OP_Lt)
|
|
default:
|
|
op = int32(OP_Ge)
|
|
break
|
|
}
|
|
arith = int32(OP_Subtract)
|
|
}
|
|
/* If the BIGNULL flag is set for the ORDER BY, then it is required to
|
|
** consider NULL values to be larger than all other values, instead of
|
|
** the usual smaller. The VDBE opcodes OP_Ge and so on do not handle this
|
|
** (and adding that capability causes a performance regression), so
|
|
** instead if the BIGNULL flag is set then cases where either reg1 or
|
|
** reg2 are NULL are handled separately in the following block. The code
|
|
** generated is equivalent to:
|
|
**
|
|
** if( reg1 IS NULL ){
|
|
** if( op==OP_Ge ) goto lbl;
|
|
** if( op==OP_Gt && reg2 IS NOT NULL ) goto lbl;
|
|
** if( op==OP_Le && reg2 IS NULL ) goto lbl;
|
|
** }else if( reg2 IS NULL ){
|
|
** if( op==OP_Le ) goto lbl;
|
|
** }
|
|
**
|
|
** Additionally, if either reg1 or reg2 are NULL but the jump to lbl is
|
|
** not taken, control jumps over the comparison operator coded below this
|
|
** block. */
|
|
if libc.Int32FromUint8((*(*TExprList_item)(unsafe.Pointer(pOrderBy + 8))).Ffg.FsortFlags)&int32(KEYINFO_ORDER_BIGNULL) != 0 {
|
|
/* This block runs if reg1 contains a NULL. */
|
|
addr = _sqlite3VdbeAddOp1(tls, v, int32(OP_NotNull), reg1)
|
|
switch op {
|
|
case int32(OP_Ge):
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_Goto), 0, lbl)
|
|
case int32(OP_Gt):
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_NotNull), reg2, lbl)
|
|
case int32(OP_Le):
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_IsNull), reg2, lbl)
|
|
default: /* no-op */
|
|
break
|
|
}
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_Goto), 0, addrDone)
|
|
/* This block runs if reg1 is not NULL, but reg2 is. */
|
|
_sqlite3VdbeJumpHere(tls, v, addr)
|
|
if op == int32(OP_Gt) || op == int32(OP_Ge) {
|
|
v1 = addrDone
|
|
} else {
|
|
v1 = lbl
|
|
}
|
|
_sqlite3VdbeAddOp2(tls, v, int32(OP_IsNull), reg2, v1)
|
|
}
|
|
/* Register reg1 currently contains csr1.peerVal (the peer-value from csr1).
|
|
** This block adds (or subtracts for DESC) the numeric value in regVal
|
|
** from it. Or, if reg1 is not numeric (it is a NULL, a text value or a blob),
|
|
** then leave reg1 as it is. In pseudo-code, this is implemented as:
|
|
**
|
|
** if( reg1>='' ) goto addrGe;
|
|
** reg1 = reg1 +/- regVal
|
|
** addrGe:
|
|
**
|
|
** Since all strings and blobs are greater-than-or-equal-to an empty string,
|
|
** the add/subtract is skipped for these, as required. If reg1 is a NULL,
|
|
** then the arithmetic is performed, but since adding or subtracting from
|
|
** NULL is always NULL anyway, this case is handled as required too. */
|
|
_sqlite3VdbeAddOp4(tls, v, int32(OP_String8), 0, regString, 0, __ccgo_ts+1704, -int32(1))
|
|
addrGe = _sqlite3VdbeAddOp3(tls, v, int32(OP_Ge), regString, 0, reg1)
|
|
if op == int32(OP_Ge) && arith == int32(OP_Add) || op == int32(OP_Le) && arith == int32(OP_Subtract) {
|
|
_sqlite3VdbeAddOp3(tls, v, op, reg2, lbl, reg1)
|
|
}
|
|
_sqlite3VdbeAddOp3(tls, v, arith, regVal, reg1, reg1)
|
|
_sqlite3VdbeJumpHere(tls, v, addrGe)
|
|
/* Compare registers reg2 and reg1, taking the jump if required. Note that
|
|
** control skips over this test if the BIGNULL flag is set and either
|
|
** reg1 or reg2 contain a NULL value. */
|
|
_sqlite3VdbeAddOp3(tls, v, op, reg2, lbl, reg1)
|
|
pColl = _sqlite3ExprNNCollSeq(tls, pParse, (*(*TExprList_item)(unsafe.Pointer(pOrderBy + 8))).FpExpr)
|
|
_sqlite3VdbeAppendP4(tls, v, pColl, -int32(2))
|
|
_sqlite3VdbeChangeP5(tls, v, uint16(SQLITE_NULLEQ))
|
|
_sqlite3VdbeResolveLabel(tls, v, addrDone)
|
|
_sqlite3ReleaseTempReg(tls, pParse, reg1)
|
|
_sqlite3ReleaseTempReg(tls, pParse, reg2)
|
|
}
|
|
|
|
func init() {
|
|
p := unsafe.Pointer(&_aSyscall)
|
|
*(*uintptr)(unsafe.Add(p, 8)) = __ccgo_fp(_posixOpen)
|
|
*(*uintptr)(unsafe.Add(p, 32)) = __ccgo_fp(libc.Xclose)
|
|
*(*uintptr)(unsafe.Add(p, 56)) = __ccgo_fp(libc.Xaccess)
|
|
*(*uintptr)(unsafe.Add(p, 80)) = __ccgo_fp(libc.Xgetcwd)
|
|
*(*uintptr)(unsafe.Add(p, 104)) = __ccgo_fp(libc.Xstat)
|
|
*(*uintptr)(unsafe.Add(p, 128)) = __ccgo_fp(libc.Xfstat)
|
|
*(*uintptr)(unsafe.Add(p, 152)) = __ccgo_fp(libc.Xftruncate)
|
|
*(*uintptr)(unsafe.Add(p, 176)) = __ccgo_fp(libc.Xfcntl)
|
|
*(*uintptr)(unsafe.Add(p, 200)) = __ccgo_fp(libc.Xread)
|
|
*(*uintptr)(unsafe.Add(p, 224)) = __ccgo_fp(libc.Xpread)
|
|
*(*uintptr)(unsafe.Add(p, 272)) = __ccgo_fp(libc.Xwrite)
|
|
*(*uintptr)(unsafe.Add(p, 296)) = __ccgo_fp(libc.Xpwrite)
|
|
*(*uintptr)(unsafe.Add(p, 344)) = __ccgo_fp(libc.Xfchmod)
|
|
*(*uintptr)(unsafe.Add(p, 392)) = __ccgo_fp(libc.Xunlink)
|
|
*(*uintptr)(unsafe.Add(p, 416)) = __ccgo_fp(_openDirectory)
|
|
*(*uintptr)(unsafe.Add(p, 440)) = __ccgo_fp(libc.Xmkdir)
|
|
*(*uintptr)(unsafe.Add(p, 464)) = __ccgo_fp(libc.Xrmdir)
|
|
*(*uintptr)(unsafe.Add(p, 488)) = __ccgo_fp(libc.Xfchown)
|
|
*(*uintptr)(unsafe.Add(p, 512)) = __ccgo_fp(libc.Xgeteuid)
|
|
*(*uintptr)(unsafe.Add(p, 536)) = __ccgo_fp(libc.Xmmap)
|
|
*(*uintptr)(unsafe.Add(p, 560)) = __ccgo_fp(libc.Xmunmap)
|
|
*(*uintptr)(unsafe.Add(p, 584)) = __ccgo_fp(libc.Xmremap)
|
|
*(*uintptr)(unsafe.Add(p, 608)) = __ccgo_fp(_unixGetpagesize)
|
|
*(*uintptr)(unsafe.Add(p, 632)) = __ccgo_fp(libc.Xreadlink)
|
|
*(*uintptr)(unsafe.Add(p, 656)) = __ccgo_fp(libc.Xlstat)
|
|
}
|
|
|
|
/* End of the overrideable system calls */
|
|
|
|
func init() {
|
|
p := unsafe.Pointer(&_sMutex1)
|
|
*(*uintptr)(unsafe.Add(p, 0)) = __ccgo_fp(_pthreadMutexInit)
|
|
*(*uintptr)(unsafe.Add(p, 8)) = __ccgo_fp(_pthreadMutexEnd)
|
|
*(*uintptr)(unsafe.Add(p, 16)) = __ccgo_fp(_pthreadMutexAlloc)
|
|
*(*uintptr)(unsafe.Add(p, 24)) = __ccgo_fp(_pthreadMutexFree)
|
|
*(*uintptr)(unsafe.Add(p, 32)) = __ccgo_fp(_pthreadMutexEnter)
|
|
*(*uintptr)(unsafe.Add(p, 40)) = __ccgo_fp(_pthreadMutexTry)
|
|
*(*uintptr)(unsafe.Add(p, 48)) = __ccgo_fp(_pthreadMutexLeave)
|
|
}
|
|
|
|
/************** End of mutex_unix.c ******************************************/
|
|
/************** Begin file mutex_w32.c ***************************************/
|
|
/*
|
|
** 2007 August 14
|
|
**
|
|
** 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 C functions that implement mutexes for Win32.
|
|
*/
|
|
/* #include "sqliteInt.h" */
|
|
|
|
/*
|
|
** The code in this file is only used if we are compiling multithreaded
|
|
** on a Win32 system.
|
|
*/
|
|
|
|
/************** End of mutex_w32.c *******************************************/
|
|
/************** Begin file malloc.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.
|
|
**
|
|
*************************************************************************
|
|
**
|
|
** Memory allocation functions used throughout sqlite.
|
|
*/
|
|
/* #include "sqliteInt.h" */
|
|
/* #include <stdarg.h> */
|