6c92f85d10
Bring the Nexus/Praxis/Hexis integration in line with MAVEN_ECOSYSTEM_ARCHITECTURE.md: - Praxis over HTTP: drop the in-process praxis.db open (praxisstore/ praxistools) and call praxisd's /api/v1/tools/* API via a new praxisClient. Honors the "no component reads another's DB" invariant (AC#12). PraxisConfig.DBPath -> URL. - Hexis confirmation gate: mutating capabilities (ReadOnly=false) now park a bound pendingHexis confirmation and require a spoken "да" before executing; read-only run immediately (AC#7, no auto attention->action). - Capability safety: >1 verb match is ambiguous -> ask instead of firing the first; ambiguous Nexus resolution asks for clarification (AC#2). - Correlation IDs on Hexis execute, recorded in the cross-service trace. - Bug: importance arrives as JSON float64 over HTTP, not int. - Tests: confirm-gate, decline, read-only, and ambiguity paths. Build: vendor/ bakes in the hexis client (replace-directed at a sibling repo outside the Docker context); Dockerfile builds from vendor and no longer `go mod download`s the unreachable replace paths. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
6528 lines
207 KiB
Go
6528 lines
207 KiB
Go
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
|
|
|
//go:build (freebsd && arm) || (linux && arm) || (windows && 386)
|
|
|
|
package sqlite3
|
|
|
|
import (
|
|
"unsafe"
|
|
|
|
"modernc.org/libc"
|
|
)
|
|
|
|
type TBtCursor = struct {
|
|
F__ccgo_align [0]uint32
|
|
FeState Tu8
|
|
FcurFlags Tu8
|
|
FcurPagerFlags Tu8
|
|
Fhints Tu8
|
|
FskipNext int32
|
|
FpBtree uintptr
|
|
FaOverflow uintptr
|
|
FpKey uintptr
|
|
FpBt uintptr
|
|
FpNext uintptr
|
|
F__ccgo_align10 [4]byte
|
|
Finfo TCellInfo
|
|
FnKey Ti64
|
|
FpgnoRoot TPgno
|
|
FiPage Ti8
|
|
FcurIntKey Tu8
|
|
Fix Tu16
|
|
FaiIdx [19]Tu16
|
|
FpKeyInfo uintptr
|
|
FpPage uintptr
|
|
FapPage [19]uintptr
|
|
F__ccgo_pad20 [4]byte
|
|
}
|
|
|
|
type TBtreePayload = struct {
|
|
F__ccgo_align [0]uint32
|
|
FpKey uintptr
|
|
F__ccgo_align1 [4]byte
|
|
FnKey Tsqlite3_int64
|
|
FpData uintptr
|
|
FaMem uintptr
|
|
FnMem Tu16
|
|
FnData int32
|
|
FnZero int32
|
|
F__ccgo_pad7 [4]byte
|
|
}
|
|
|
|
/*
|
|
** Context object type used by rank(), dense_rank(), percent_rank() and
|
|
** cume_dist().
|
|
*/
|
|
type TCallCount = struct {
|
|
F__ccgo_align [0]uint32
|
|
FnValue Ti64
|
|
FnStep Ti64
|
|
FnTotal Ti64
|
|
}
|
|
|
|
type TCellInfo = struct {
|
|
F__ccgo_align [0]uint32
|
|
FnKey Ti64
|
|
FpPayload uintptr
|
|
FnPayload Tu32
|
|
FnLocal Tu16
|
|
FnSize Tu16
|
|
F__ccgo_pad5 [4]byte
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** The following structure keeps track of state information for the
|
|
// ** count() aggregate function.
|
|
// */
|
|
type TCountCtx = struct {
|
|
F__ccgo_align [0]uint32
|
|
Fn Ti64
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Handle type for pages.
|
|
// */
|
|
type TDbPage = struct {
|
|
F__ccgo_align [0]uint32
|
|
FpPage uintptr
|
|
FpData uintptr
|
|
FpExtra uintptr
|
|
FpCache uintptr
|
|
FpDirty uintptr
|
|
FpPager uintptr
|
|
Fpgno TPgno
|
|
Fflags Tu16
|
|
F__ccgo_align8 [2]byte
|
|
FnRef Ti64
|
|
FpDirtyNext uintptr
|
|
FpDirtyPrev uintptr
|
|
}
|
|
|
|
type TFilePoint = struct {
|
|
F__ccgo_align [0]uint32
|
|
FiOffset Tsqlite3_int64
|
|
FpChunk uintptr
|
|
F__ccgo_pad2 [4]byte
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** The first time the bm25() function is called for a query, an instance
|
|
// ** of the following structure is allocated and populated.
|
|
// */
|
|
type TFts5Bm25Data = struct {
|
|
F__ccgo_align [0]uint32
|
|
FnPhrase int32
|
|
F__ccgo_align1 [4]byte
|
|
Favgdl float64
|
|
FaIDF uintptr
|
|
FaFreq uintptr
|
|
}
|
|
|
|
type TFts5Cursor = struct {
|
|
F__ccgo_align [0]uint32
|
|
Fbase Tsqlite3_vtab_cursor
|
|
FpNext uintptr
|
|
FaColumnSize uintptr
|
|
F__ccgo_align3 [4]byte
|
|
FiCsrId Ti64
|
|
FePlan int32
|
|
FbDesc int32
|
|
FiFirstRowid Ti64
|
|
FiLastRowid Ti64
|
|
FpStmt uintptr
|
|
FpExpr uintptr
|
|
FpSorter uintptr
|
|
Fcsrflags int32
|
|
FiSpecial Ti64
|
|
FzRank uintptr
|
|
FzRankArgs uintptr
|
|
FpRank uintptr
|
|
FnRankArg int32
|
|
FapRankArg uintptr
|
|
FpRankArgStmt uintptr
|
|
FpAux uintptr
|
|
FpAuxdata uintptr
|
|
FaInstIter uintptr
|
|
FnInstAlloc int32
|
|
FnInstCount int32
|
|
FaInst uintptr
|
|
}
|
|
|
|
type TFts5DlidxIter = struct {
|
|
F__ccgo_align [0]uint32
|
|
FnLvl int32
|
|
FiSegid int32
|
|
}
|
|
|
|
type TFts5DlidxLvl = struct {
|
|
F__ccgo_align [0]uint32
|
|
FpData uintptr
|
|
FiOff int32
|
|
FbEof int32
|
|
FiFirstOff int32
|
|
FiLeafPgno int32
|
|
F__ccgo_align5 [4]byte
|
|
FiRowid Ti64
|
|
}
|
|
|
|
type TFts5DlidxWriter = struct {
|
|
F__ccgo_align [0]uint32
|
|
Fpgno int32
|
|
FbPrevValid int32
|
|
FiPrev Ti64
|
|
Fbuf TFts5Buffer
|
|
F__ccgo_pad4 [4]byte
|
|
}
|
|
|
|
type TFts5DoclistIter = struct {
|
|
F__ccgo_align [0]uint32
|
|
FaEof uintptr
|
|
F__ccgo_align1 [4]byte
|
|
FiRowid Ti64
|
|
FaPoslist uintptr
|
|
FnPoslist int32
|
|
FnSize int32
|
|
F__ccgo_pad5 [4]byte
|
|
}
|
|
|
|
type TFts5ExprCtx = struct {
|
|
F__ccgo_align [0]uint32
|
|
FpExpr uintptr
|
|
FaPopulator uintptr
|
|
FiOff Ti64
|
|
}
|
|
|
|
type TFts5ExprNode = struct {
|
|
F__ccgo_align [0]uint32
|
|
FeType int32
|
|
FbEof int32
|
|
FbNomatch int32
|
|
FiHeight int32
|
|
FxNext uintptr
|
|
F__ccgo_align5 [4]byte
|
|
FiRowid Ti64
|
|
FpNear uintptr
|
|
FnChild int32
|
|
}
|
|
|
|
type TFts5FlushCtx = struct {
|
|
F__ccgo_align [0]uint32
|
|
FpIdx uintptr
|
|
F__ccgo_align1 [4]byte
|
|
Fwriter TFts5SegWriter
|
|
}
|
|
|
|
type TFts5Global = struct {
|
|
F__ccgo_align [0]uint32
|
|
Fapi Tfts5_api
|
|
Fdb uintptr
|
|
F__ccgo_align2 [4]byte
|
|
FiNextId Ti64
|
|
FpAux uintptr
|
|
FpTok uintptr
|
|
FpDfltTok uintptr
|
|
FpCsr uintptr
|
|
FaLocaleHdr [4]Tu32
|
|
}
|
|
|
|
type TFts5HashEntry = struct {
|
|
F__ccgo_align [0]uint32
|
|
FpHashNext uintptr
|
|
FpScanNext uintptr
|
|
FnAlloc int32
|
|
FiSzPoslist int32
|
|
FnData int32
|
|
FnKey int32
|
|
FbDel Tu8
|
|
FbContent Tu8
|
|
FiCol Ti16
|
|
FiPos int32
|
|
FiRowid Ti64
|
|
}
|
|
|
|
type TFts5Index = struct {
|
|
F__ccgo_align [0]uint32
|
|
FpConfig uintptr
|
|
FzDataTbl uintptr
|
|
FnWorkUnit int32
|
|
FpHash uintptr
|
|
FnPendingData int32
|
|
F__ccgo_align5 [4]byte
|
|
FiWriteRowid Ti64
|
|
FbDelete int32
|
|
FnContentlessDelete int32
|
|
FnPendingRow int32
|
|
Frc int32
|
|
FflushRc int32
|
|
FpReader uintptr
|
|
FpWriter uintptr
|
|
FpDeleter uintptr
|
|
FpIdxWriter uintptr
|
|
FpIdxDeleter uintptr
|
|
FpIdxSelect uintptr
|
|
FpIdxNextSelect uintptr
|
|
FnRead int32
|
|
FpDeleteFromIdx uintptr
|
|
FpDataVersion uintptr
|
|
F__ccgo_align21 [4]byte
|
|
FiStructVersion Ti64
|
|
FpStruct uintptr
|
|
F__ccgo_pad23 [4]byte
|
|
}
|
|
|
|
type TFts5IndexIter = struct {
|
|
F__ccgo_align [0]uint32
|
|
FiRowid Ti64
|
|
FpData uintptr
|
|
FnData int32
|
|
FbEof Tu8
|
|
F__ccgo_pad4 [7]byte
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Context object used by sqlite3Fts5StorageIntegrity().
|
|
// */
|
|
type TFts5IntegrityCtx = struct {
|
|
F__ccgo_align [0]uint32
|
|
FiRowid Ti64
|
|
FiCol int32
|
|
FszCol int32
|
|
Fcksum Tu64
|
|
FpTermset uintptr
|
|
FpConfig uintptr
|
|
}
|
|
|
|
type TFts5Iter = struct {
|
|
F__ccgo_align [0]uint32
|
|
Fbase TFts5IndexIter
|
|
FpTokenDataIter uintptr
|
|
FpIndex uintptr
|
|
Fposlist TFts5Buffer
|
|
FpColset uintptr
|
|
FxSetOutputs uintptr
|
|
FnSeg int32
|
|
FbRev int32
|
|
FbSkipEmpty Tu8
|
|
F__ccgo_align9 [3]byte
|
|
FiSwitchRowid Ti64
|
|
FaFirst uintptr
|
|
F__ccgo_pad12 [4]byte
|
|
}
|
|
|
|
type TFts5LookaheadReader = struct {
|
|
F__ccgo_align [0]uint32
|
|
Fa uintptr
|
|
Fn int32
|
|
Fi int32
|
|
F__ccgo_align3 [4]byte
|
|
FiPos Ti64
|
|
FiLookahead Ti64
|
|
}
|
|
|
|
type TFts5NearTrimmer = struct {
|
|
F__ccgo_align [0]uint32
|
|
Freader TFts5LookaheadReader
|
|
Fwriter TFts5PoslistWriter
|
|
FpOut uintptr
|
|
F__ccgo_pad3 [4]byte
|
|
}
|
|
|
|
type TFts5PoslistPopulator = struct {
|
|
F__ccgo_align [0]uint32
|
|
Fwriter TFts5PoslistWriter
|
|
FbOk int32
|
|
FbMiss int32
|
|
}
|
|
|
|
type TFts5PoslistReader = struct {
|
|
F__ccgo_align [0]uint32
|
|
Fa uintptr
|
|
Fn int32
|
|
Fi int32
|
|
FbFlag Tu8
|
|
FbEof Tu8
|
|
F__ccgo_align5 [2]byte
|
|
FiPos Ti64
|
|
}
|
|
|
|
type TFts5PoslistWriter = struct {
|
|
F__ccgo_align [0]uint32
|
|
FiPrev Ti64
|
|
}
|
|
|
|
type TFts5SegIter = struct {
|
|
F__ccgo_align [0]uint32
|
|
FpSeg uintptr
|
|
Fflags int32
|
|
FiLeafPgno int32
|
|
FpLeaf uintptr
|
|
FpNextLeaf uintptr
|
|
F__ccgo_align5 [4]byte
|
|
FiLeafOffset Ti64
|
|
FpTombArray uintptr
|
|
FxNext uintptr
|
|
FiTermLeafPgno int32
|
|
FiTermLeafOffset int32
|
|
FiPgidxOff int32
|
|
FiEndofDoclist int32
|
|
FiRowidOffset int32
|
|
FnRowidOffset int32
|
|
FaRowidOffset uintptr
|
|
FpDlidx uintptr
|
|
Fterm TFts5Buffer
|
|
F__ccgo_align17 [4]byte
|
|
FiRowid Ti64
|
|
FnPos int32
|
|
FbDel Tu8
|
|
F__ccgo_pad20 [3]byte
|
|
}
|
|
|
|
type TFts5SegWriter = struct {
|
|
F__ccgo_align [0]uint32
|
|
FiSegid int32
|
|
Fwriter TFts5PageWriter
|
|
FiPrevRowid Ti64
|
|
FbFirstRowidInDoclist Tu8
|
|
FbFirstRowidInPage Tu8
|
|
FbFirstTermInPage Tu8
|
|
FnLeafWritten int32
|
|
FnEmpty int32
|
|
FnDlidx int32
|
|
FaDlidx uintptr
|
|
Fbtterm TFts5Buffer
|
|
FiBtPage int32
|
|
F__ccgo_pad12 [4]byte
|
|
}
|
|
|
|
type TFts5Sorter = struct {
|
|
F__ccgo_align [0]uint32
|
|
FpStmt uintptr
|
|
F__ccgo_align1 [4]byte
|
|
FiRowid Ti64
|
|
FaPoslist uintptr
|
|
FnIdx int32
|
|
}
|
|
|
|
type TFts5Storage = struct {
|
|
F__ccgo_align [0]uint32
|
|
FpConfig uintptr
|
|
FpIndex uintptr
|
|
FbTotalsValid int32
|
|
F__ccgo_align3 [4]byte
|
|
FnTotalRow Ti64
|
|
FaTotalSize uintptr
|
|
FpSavedRow uintptr
|
|
FaStmt [12]uintptr
|
|
}
|
|
|
|
type TFts5Structure = struct {
|
|
F__ccgo_align [0]uint32
|
|
FnRef int32
|
|
F__ccgo_align1 [4]byte
|
|
FnWriteCounter Tu64
|
|
FnOriginCntr Tu64
|
|
FnSegment int32
|
|
FnLevel int32
|
|
}
|
|
|
|
type TFts5StructureSegment = struct {
|
|
F__ccgo_align [0]uint32
|
|
FiSegid int32
|
|
FpgnoFirst int32
|
|
FpgnoLast int32
|
|
F__ccgo_align3 [4]byte
|
|
FiOrigin1 Tu64
|
|
FiOrigin2 Tu64
|
|
FnPgTombstone int32
|
|
F__ccgo_align6 [4]byte
|
|
FnEntryTombstone Tu64
|
|
FnEntry Tu64
|
|
}
|
|
|
|
type TFts5TokenDataIter = struct {
|
|
F__ccgo_align [0]uint32
|
|
FnMapAlloc Ti64
|
|
FnMap Ti64
|
|
FaMap uintptr
|
|
Fterms TFts5Buffer
|
|
FnIter Ti64
|
|
FnIterAlloc Ti64
|
|
FaPoslistReader uintptr
|
|
FaPoslistToIter uintptr
|
|
}
|
|
|
|
type TFts5TokenDataMap = struct {
|
|
F__ccgo_align [0]uint32
|
|
FiRowid Ti64
|
|
FiPos Ti64
|
|
FiIter int32
|
|
FnByte int32
|
|
}
|
|
|
|
type TFts5VocabCursor = struct {
|
|
F__ccgo_align [0]uint32
|
|
Fbase Tsqlite3_vtab_cursor
|
|
FpStmt uintptr
|
|
FpFts5 uintptr
|
|
FbEof int32
|
|
FpIter uintptr
|
|
FpStruct uintptr
|
|
FnLeTerm int32
|
|
FzLeTerm uintptr
|
|
FcolUsed int32
|
|
FiCol int32
|
|
FaCnt uintptr
|
|
FaDoc uintptr
|
|
Frowid Ti64
|
|
Fterm TFts5Buffer
|
|
F__ccgo_align14 [4]byte
|
|
FiInstPos Ti64
|
|
FiInstOff int32
|
|
F__ccgo_pad16 [4]byte
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /* Objects used by the overlap algorithm. */
|
|
type TGeoEvent = struct {
|
|
F__ccgo_align [0]uint32
|
|
Fx float64
|
|
FeType int32
|
|
FpSeg uintptr
|
|
FpNext uintptr
|
|
F__ccgo_pad4 [4]byte
|
|
}
|
|
|
|
type TGeoSegment = struct {
|
|
F__ccgo_align [0]uint32
|
|
FC float64
|
|
FB float64
|
|
Fy float64
|
|
Fy0 float32
|
|
Fside uint8
|
|
Fidx uint32
|
|
FpNext uintptr
|
|
}
|
|
|
|
/* In-memory list of records */
|
|
type TIncrMerger = struct {
|
|
F__ccgo_align [0]uint32
|
|
FpTask uintptr
|
|
FpMerger uintptr
|
|
FiStartOff Ti64
|
|
FmxSz int32
|
|
FbEof int32
|
|
FbUseThread int32
|
|
F__ccgo_align6 [4]byte
|
|
FaFile [2]TSorterFile
|
|
}
|
|
|
|
type TIndex = struct {
|
|
F__ccgo_align [0]uint32
|
|
FzName uintptr
|
|
FaiColumn uintptr
|
|
FaiRowLogEst uintptr
|
|
FpTable uintptr
|
|
FzColAff uintptr
|
|
FpNext uintptr
|
|
FpSchema uintptr
|
|
FaSortOrder uintptr
|
|
FazColl uintptr
|
|
FpPartIdxWhere uintptr
|
|
FaColExpr uintptr
|
|
Ftnum TPgno
|
|
FszIdxRow TLogEst
|
|
FnKeyCol Tu16
|
|
FnColumn Tu16
|
|
FonError Tu8
|
|
F__ccgo56 uint16
|
|
FnSample int32
|
|
FmxSample int32
|
|
FnSampleCol int32
|
|
FaAvgEq uintptr
|
|
FaSample uintptr
|
|
FaiRowEst uintptr
|
|
F__ccgo_align33 [4]byte
|
|
FnRowEst0 TtRowcnt
|
|
FcolNotIdxed TBitmask
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This structure is passed around through all the PRAGMA integrity_check
|
|
// ** checking routines in order to keep track of some global state information.
|
|
// **
|
|
// ** The aRef[] array is allocated so that there is 1 bit for each page in
|
|
// ** the database. As the integrity-check proceeds, for each page used in
|
|
// ** the database the corresponding bit is set. This allows integrity-check to
|
|
// ** detect pages that are used twice and orphaned pages (both of which
|
|
// ** indicate corruption).
|
|
// */
|
|
type TIntegrityCk = struct {
|
|
F__ccgo_align [0]uint32
|
|
FpBt uintptr
|
|
FpPager uintptr
|
|
FaPgRef uintptr
|
|
FnCkPage TPgno
|
|
FmxErr int32
|
|
FnErr int32
|
|
Frc int32
|
|
FnStep Tu32
|
|
FzPfx uintptr
|
|
Fv0 TPgno
|
|
Fv1 TPgno
|
|
Fv2 int32
|
|
FerrMsg TStrAccum
|
|
Fheap uintptr
|
|
Fdb uintptr
|
|
FnRow Ti64
|
|
}
|
|
|
|
type TJsonEachCursor = struct {
|
|
F__ccgo_align [0]uint32
|
|
Fbase Tsqlite3_vtab_cursor
|
|
FiRowid Tu32
|
|
Fi Tu32
|
|
FiEnd Tu32
|
|
FnRoot Tu32
|
|
FeType Tu8
|
|
FbRecursive Tu8
|
|
FeMode Tu8
|
|
FnParent Tu32
|
|
FnParentAlloc Tu32
|
|
FaParent uintptr
|
|
Fdb uintptr
|
|
Fpath TJsonString
|
|
FsParse TJsonParse
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /****************************************************************************
|
|
// ** The json_each virtual table
|
|
// ****************************************************************************/
|
|
type TJsonParent = struct {
|
|
F__ccgo_align [0]uint32
|
|
FiHead Tu32
|
|
FiValue Tu32
|
|
FiEnd Tu32
|
|
FnPath Tu32
|
|
FiKey Ti64
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** The names of the following types declared in vdbeInt.h are required
|
|
// ** for the VdbeOp definition.
|
|
// */
|
|
type TMem = struct {
|
|
F__ccgo_align [0]uint32
|
|
Fu TMemValue
|
|
Fz uintptr
|
|
Fn int32
|
|
Fflags Tu16
|
|
Fenc Tu8
|
|
FeSubtype Tu8
|
|
Fdb uintptr
|
|
FszMalloc int32
|
|
FuTemp Tu32
|
|
FzMalloc uintptr
|
|
FxDel uintptr
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** State information local to the memory allocation subsystem.
|
|
// */
|
|
type TMem0Global = struct {
|
|
F__ccgo_align [0]uint32
|
|
Fmutex uintptr
|
|
F__ccgo_align1 [4]byte
|
|
FalarmThreshold Tsqlite3_int64
|
|
FhardLimit Tsqlite3_int64
|
|
FnearlyFull int32
|
|
F__ccgo_pad4 [4]byte
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /* Forward references to internal structures */
|
|
type TMemJournal = struct {
|
|
F__ccgo_align [0]uint32
|
|
FpMethod uintptr
|
|
FnChunkSize int32
|
|
FnSpill int32
|
|
FpFirst uintptr
|
|
Fendpoint TFilePoint
|
|
Freadpoint TFilePoint
|
|
Fflags int32
|
|
FpVfs uintptr
|
|
FzJournal uintptr
|
|
F__ccgo_pad9 [4]byte
|
|
}
|
|
|
|
type TMemStore = struct {
|
|
F__ccgo_align [0]uint32
|
|
Fsz Tsqlite3_int64
|
|
FszAlloc Tsqlite3_int64
|
|
FszMax Tsqlite3_int64
|
|
FaData uintptr
|
|
FpMutex uintptr
|
|
FnMmap int32
|
|
FmFlags uint32
|
|
FnRdLock int32
|
|
FnWrLock int32
|
|
FnRef int32
|
|
FzFName uintptr
|
|
}
|
|
|
|
type TMemValue = struct {
|
|
F__ccgo_align [0]uint32
|
|
Fi [0]int64
|
|
FnZero [0]int32
|
|
FzPType [0]uintptr
|
|
FpDef [0]uintptr
|
|
Fr float64
|
|
}
|
|
|
|
/*
|
|
** Implementation of built-in window function nth_value(). This
|
|
** implementation is used in "slow mode" only - when the EXCLUDE clause
|
|
** is not set to the default value "NO OTHERS".
|
|
*/
|
|
type TNthValueCtx = struct {
|
|
F__ccgo_align [0]uint32
|
|
FnStep Ti64
|
|
FpValue uintptr
|
|
F__ccgo_pad2 [4]byte
|
|
}
|
|
|
|
/*
|
|
** Context object for ntile() window function.
|
|
*/
|
|
type TNtileCtx = struct {
|
|
F__ccgo_align [0]uint32
|
|
FnTotal Ti64
|
|
FnParam Ti64
|
|
FiRow Ti64
|
|
}
|
|
|
|
type TPCache = struct {
|
|
F__ccgo_align [0]uint32
|
|
FpDirty uintptr
|
|
FpDirtyTail uintptr
|
|
FpSynced uintptr
|
|
F__ccgo_align3 [4]byte
|
|
FnRefSum Ti64
|
|
FszCache int32
|
|
FszSpill int32
|
|
FszPage int32
|
|
FszExtra int32
|
|
FbPurgeable Tu8
|
|
FeCreate Tu8
|
|
FxStress uintptr
|
|
FpStress uintptr
|
|
FpCache uintptr
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** An instance of the following structure is allocated for each active
|
|
// ** savepoint and statement transaction in the system. All such structures
|
|
// ** are stored in the Pager.aSavepoint[] array, which is allocated and
|
|
// ** resized using sqlite3Realloc().
|
|
// **
|
|
// ** When a savepoint is created, the PagerSavepoint.iHdrOffset field is
|
|
// ** set to 0. If a journal-header is written into the main journal while
|
|
// ** the savepoint is active, then iHdrOffset is set to the byte offset
|
|
// ** immediately following the last journal record written into the main
|
|
// ** journal before the journal-header. This is required during savepoint
|
|
// ** rollback (see pagerPlaybackSavepoint()).
|
|
// */
|
|
type TPagerSavepoint = struct {
|
|
F__ccgo_align [0]uint32
|
|
FiOffset Ti64
|
|
FiHdrOffset Ti64
|
|
FpInSavepoint uintptr
|
|
FnOrig TPgno
|
|
FiSubRec TPgno
|
|
FbTruncateOnRelease int32
|
|
FaWalData [4]Tu32
|
|
}
|
|
|
|
/* Merge PMAs together */
|
|
type TPmaReader = struct {
|
|
F__ccgo_align [0]uint32
|
|
FiReadOff Ti64
|
|
FiEof Ti64
|
|
FnAlloc int32
|
|
FnKey int32
|
|
FpFd uintptr
|
|
FaAlloc uintptr
|
|
FaKey uintptr
|
|
FaBuffer uintptr
|
|
FnBuffer int32
|
|
FaMap uintptr
|
|
FpIncr uintptr
|
|
F__ccgo_pad11 [4]byte
|
|
}
|
|
|
|
/* Incrementally read one PMA */
|
|
type TPmaWriter = struct {
|
|
F__ccgo_align [0]uint32
|
|
FeFWErr int32
|
|
FaBuffer uintptr
|
|
FnBuffer int32
|
|
FiBufStart int32
|
|
FiBufEnd int32
|
|
F__ccgo_align5 [4]byte
|
|
FiWriteOff Ti64
|
|
FpFd uintptr
|
|
F__ccgo_align7 [4]byte
|
|
FnPmaSpill Tu64
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /* Definitions of all built-in pragmas */
|
|
type TPragmaName = struct {
|
|
F__ccgo_align [0]uint32
|
|
FzName uintptr
|
|
FePragTyp Tu8
|
|
FmPragFlg Tu8
|
|
FiPragCName Tu8
|
|
FnPragCName Tu8
|
|
FiArg Tu64
|
|
}
|
|
|
|
type TPragmaVtabCursor = struct {
|
|
F__ccgo_align [0]uint32
|
|
Fbase Tsqlite3_vtab_cursor
|
|
FpPragma uintptr
|
|
FiRowid Tsqlite_int64
|
|
FazArg [2]uintptr
|
|
}
|
|
|
|
type TPreUpdate = struct {
|
|
F__ccgo_align [0]uint32
|
|
Fv uintptr
|
|
FpCsr uintptr
|
|
Fop int32
|
|
FaRecord uintptr
|
|
FpKeyinfo uintptr
|
|
FpUnpacked uintptr
|
|
FpNewUnpacked uintptr
|
|
FiNewReg int32
|
|
FiBlobWrite int32
|
|
F__ccgo_align9 [4]byte
|
|
FiKey1 Ti64
|
|
FiKey2 Ti64
|
|
Foldipk TMem
|
|
FaNew uintptr
|
|
FpTab uintptr
|
|
FpPk uintptr
|
|
FapDflt uintptr
|
|
FuKey struct {
|
|
FkeyinfoSpace [20]Tu8
|
|
}
|
|
F__ccgo_pad17 [4]byte
|
|
}
|
|
|
|
type TPrefixMerger = struct {
|
|
F__ccgo_align [0]uint32
|
|
Fiter TFts5DoclistIter
|
|
FiPos Ti64
|
|
FiOff int32
|
|
FaPos uintptr
|
|
FpNext uintptr
|
|
F__ccgo_pad5 [4]byte
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Context object passed by fts5SetupPrefixIter() to fts5VisitEntries().
|
|
// */
|
|
type TPrefixSetupCtx = struct {
|
|
F__ccgo_align [0]uint32
|
|
FxMerge uintptr
|
|
FxAppend uintptr
|
|
FiLastRowid Ti64
|
|
FnMerge int32
|
|
FaBuf uintptr
|
|
FnBuf int32
|
|
Fdoclist TFts5Buffer
|
|
FpTokendata uintptr
|
|
F__ccgo_pad8 [4]byte
|
|
}
|
|
|
|
type TRCStr = struct {
|
|
F__ccgo_align [0]uint32
|
|
FnRCRef Tu64
|
|
}
|
|
|
|
type TRbuState = struct {
|
|
F__ccgo_align [0]uint32
|
|
FeStage int32
|
|
FzTbl uintptr
|
|
FzDataTbl uintptr
|
|
FzIdx uintptr
|
|
FiWalCksum Ti64
|
|
FnRow int32
|
|
F__ccgo_align6 [4]byte
|
|
FnProgress Ti64
|
|
FiCookie Tu32
|
|
F__ccgo_align8 [4]byte
|
|
FiOalSz Ti64
|
|
FnPhaseOneStep Ti64
|
|
}
|
|
|
|
/* Structure used to pass information throughout the Walker in order to
|
|
** implement sqlite3ReferencesSrcList().
|
|
*/
|
|
type TRefSrcList = struct {
|
|
F__ccgo_align [0]uint32
|
|
Fdb uintptr
|
|
FpRef uintptr
|
|
FnExclude Ti64
|
|
FaiExclude uintptr
|
|
F__ccgo_pad4 [4]byte
|
|
}
|
|
|
|
/* An instance of this object describes bulk memory available for use
|
|
** by subcomponents of a prepared statement. Space is allocated out
|
|
** of a ReusableSpace object by the allocSpace() routine below.
|
|
*/
|
|
type TReusableSpace = struct {
|
|
F__ccgo_align [0]uint32
|
|
FpSpace uintptr
|
|
F__ccgo_align1 [4]byte
|
|
FnFree Tsqlite3_int64
|
|
FnNeeded Tsqlite3_int64
|
|
}
|
|
|
|
/*
|
|
** RowSetEntry objects are allocated in large chunks (instances of the
|
|
** following structure) to reduce memory allocation overhead. The
|
|
** chunks are kept on a linked list so that they can be deallocated
|
|
** when the RowSet is destroyed.
|
|
*/
|
|
type TRowSetChunk = struct {
|
|
F__ccgo_align [0]uint32
|
|
FpNextChunk uintptr
|
|
F__ccgo_align1 [4]byte
|
|
FaEntry [63]TRowSetEntry
|
|
}
|
|
|
|
/*
|
|
** Each entry in a RowSet is an instance of the following object.
|
|
**
|
|
** This same object is reused to store a linked list of trees of RowSetEntry
|
|
** objects. In that alternative use, pRight points to the next entry
|
|
** in the list, pLeft points to the tree, and v is unused. The
|
|
** RowSet.pForest value points to the head of this forest list.
|
|
*/
|
|
type TRowSetEntry = struct {
|
|
F__ccgo_align [0]uint32
|
|
Fv Ti64
|
|
FpRight uintptr
|
|
FpLeft uintptr
|
|
}
|
|
|
|
type TRtree = struct {
|
|
F__ccgo_align [0]uint32
|
|
Fbase Tsqlite3_vtab
|
|
Fdb uintptr
|
|
FiNodeSize int32
|
|
FnDim Tu8
|
|
FnDim2 Tu8
|
|
FeCoordType Tu8
|
|
FnBytesPerCell Tu8
|
|
FinWrTrans Tu8
|
|
FnAux Tu16
|
|
FnAuxNotNull Tu8
|
|
FiDepth int32
|
|
FzDb uintptr
|
|
FzName uintptr
|
|
FzNodeName uintptr
|
|
FnBusy Tu32
|
|
F__ccgo_align15 [4]byte
|
|
FnRowEst Ti64
|
|
FnCursor Tu32
|
|
FnNodeRef Tu32
|
|
FzReadAuxSql uintptr
|
|
FpDeleted uintptr
|
|
FpNodeBlob uintptr
|
|
FpWriteNode uintptr
|
|
FpDeleteNode uintptr
|
|
FpReadRowid uintptr
|
|
FpWriteRowid uintptr
|
|
FpDeleteRowid uintptr
|
|
FpReadParent uintptr
|
|
FpWriteParent uintptr
|
|
FpDeleteParent uintptr
|
|
FpWriteAux uintptr
|
|
FaHash [97]uintptr
|
|
F__ccgo_pad31 [4]byte
|
|
}
|
|
|
|
type TRtreeCell = struct {
|
|
F__ccgo_align [0]uint32
|
|
FiRowid Ti64
|
|
FaCoord [10]TRtreeCoord
|
|
}
|
|
|
|
type TRtreeConstraint = struct {
|
|
F__ccgo_align [0]uint32
|
|
FiCoord int32
|
|
Fop int32
|
|
Fu struct {
|
|
F__ccgo_align [0]uint32
|
|
FxGeom [0]uintptr
|
|
FxQueryFunc [0]uintptr
|
|
FrValue TRtreeDValue
|
|
}
|
|
FpInfo uintptr
|
|
F__ccgo_pad4 [4]byte
|
|
}
|
|
|
|
type TRtreeCursor = struct {
|
|
F__ccgo_align [0]uint32
|
|
Fbase Tsqlite3_vtab_cursor
|
|
FatEOF Tu8
|
|
FbPoint Tu8
|
|
FbAuxValid Tu8
|
|
FiStrategy int32
|
|
FnConstraint int32
|
|
FaConstraint uintptr
|
|
FnPointAlloc int32
|
|
FnPoint int32
|
|
FmxLevel int32
|
|
FaPoint uintptr
|
|
FpReadAux uintptr
|
|
FsPoint TRtreeSearchPoint
|
|
FaNode [5]uintptr
|
|
FanQueue [42]Tu32
|
|
F__ccgo_pad15 [4]byte
|
|
}
|
|
|
|
type TRtreeMatchArg = struct {
|
|
F__ccgo_align [0]uint32
|
|
FiSize Tu32
|
|
Fcb TRtreeGeomCallback
|
|
FnParam int32
|
|
FapSqlParam uintptr
|
|
F__ccgo_pad5 [4]byte
|
|
}
|
|
|
|
type TRtreeNode = struct {
|
|
F__ccgo_align [0]uint32
|
|
FpParent uintptr
|
|
F__ccgo_align1 [4]byte
|
|
FiNode Ti64
|
|
FnRef int32
|
|
FisDirty int32
|
|
FzData uintptr
|
|
FpNext uintptr
|
|
}
|
|
|
|
type TRtreeSearchPoint = struct {
|
|
F__ccgo_align [0]uint32
|
|
FrScore TRtreeDValue
|
|
Fid Tsqlite3_int64
|
|
FiLevel Tu8
|
|
FeWithin Tu8
|
|
FiCell Tu8
|
|
F__ccgo_pad5 [5]byte
|
|
}
|
|
|
|
type TSavepoint = struct {
|
|
F__ccgo_align [0]uint32
|
|
FzName uintptr
|
|
F__ccgo_align1 [4]byte
|
|
FnDeferredCons Ti64
|
|
FnDeferredImmCons Ti64
|
|
FpNext uintptr
|
|
F__ccgo_pad4 [4]byte
|
|
}
|
|
|
|
/* A record being sorted */
|
|
type TSortSubtask = struct {
|
|
F__ccgo_align [0]uint32
|
|
FpThread uintptr
|
|
FbDone int32
|
|
FnPMA int32
|
|
FpSorter uintptr
|
|
FpUnpacked uintptr
|
|
F__ccgo_align5 [4]byte
|
|
Flist TSorterList
|
|
FxCompare TSorterCompare
|
|
F__ccgo_align7 [4]byte
|
|
Ffile TSorterFile
|
|
Ffile2 TSorterFile
|
|
FnSpill Tu64
|
|
}
|
|
|
|
/* A sub-task in the sort process */
|
|
type TSorterFile = struct {
|
|
F__ccgo_align [0]uint32
|
|
FpFd uintptr
|
|
F__ccgo_align1 [4]byte
|
|
FiEof Ti64
|
|
}
|
|
|
|
/* Temporary file object wrapper */
|
|
type TSorterList = struct {
|
|
F__ccgo_align [0]uint32
|
|
FpList uintptr
|
|
FaMemory uintptr
|
|
FszPMA Ti64
|
|
}
|
|
|
|
/*
|
|
** Structure containing global configuration data for the SQLite library.
|
|
**
|
|
** This structure also contains some state information.
|
|
*/
|
|
type TSqlite3Config = struct {
|
|
F__ccgo_align [0]uint32
|
|
FbMemstat int32
|
|
FbCoreMutex Tu8
|
|
FbFullMutex Tu8
|
|
FbOpenUri Tu8
|
|
FbUseCis Tu8
|
|
FbSmallMalloc Tu8
|
|
FbExtraSchemaChecks Tu8
|
|
FmxStrlen int32
|
|
FneverCorrupt int32
|
|
FszLookaside int32
|
|
FnLookaside int32
|
|
FnStmtSpill int32
|
|
Fm Tsqlite3_mem_methods
|
|
Fmutex Tsqlite3_mutex_methods
|
|
Fpcache2 Tsqlite3_pcache_methods2
|
|
FpHeap uintptr
|
|
FnHeap int32
|
|
FmnReq int32
|
|
FmxReq int32
|
|
FszMmap Tsqlite3_int64
|
|
FmxMmap Tsqlite3_int64
|
|
FpPage uintptr
|
|
FszPage int32
|
|
FnPage int32
|
|
FmxParserStack int32
|
|
FsharedCacheEnabled int32
|
|
FszPma Tu32
|
|
FisInit int32
|
|
FinProgress int32
|
|
FisMutexInit int32
|
|
FisMallocInit int32
|
|
FisPCacheInit int32
|
|
FnRefInitMutex int32
|
|
FpInitMutex uintptr
|
|
FxLog uintptr
|
|
FpLogArg uintptr
|
|
F__ccgo_align36 [4]byte
|
|
FmxMemdbSize Tsqlite3_int64
|
|
FxTestCallback uintptr
|
|
FbLocaltimeFault int32
|
|
FxAltLocaltime uintptr
|
|
FiOnceResetThreshold int32
|
|
FszSorterRef Tu32
|
|
FiPrngSeed uint32
|
|
}
|
|
|
|
type TSrcItem = struct {
|
|
F__ccgo_align [0]uint32
|
|
FzName uintptr
|
|
FzAlias uintptr
|
|
FpSTab uintptr
|
|
Ffg struct {
|
|
Fjointype Tu8
|
|
F__ccgo4 uint32
|
|
}
|
|
FiCursor int32
|
|
FcolUsed TBitmask
|
|
Fu1 struct {
|
|
FpFuncArg [0]uintptr
|
|
FnRow [0]Tu32
|
|
FzIndexedBy uintptr
|
|
}
|
|
Fu2 struct {
|
|
FpCteUse [0]uintptr
|
|
FpIBIndex uintptr
|
|
}
|
|
Fu3 struct {
|
|
FpUsing [0]uintptr
|
|
FpOn uintptr
|
|
}
|
|
Fu4 struct {
|
|
FzDatabase [0]uintptr
|
|
FpSubq [0]uintptr
|
|
FpSchema uintptr
|
|
}
|
|
}
|
|
|
|
type TSrcList = struct {
|
|
F__ccgo_align [0]uint32
|
|
FnSrc int32
|
|
FnAlloc Tu32
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Three SQL functions - stat_init(), stat_push(), and stat_get() -
|
|
// ** share an instance of the following structure to hold their state
|
|
// ** information.
|
|
// */
|
|
type TStatAccum = struct {
|
|
F__ccgo_align [0]uint32
|
|
Fdb uintptr
|
|
F__ccgo_align1 [4]byte
|
|
FnEst TtRowcnt
|
|
FnRow TtRowcnt
|
|
FnLimit int32
|
|
FnCol int32
|
|
FnKeyCol int32
|
|
FnSkipAhead Tu8
|
|
F__ccgo_align7 [3]byte
|
|
Fcurrent TStatSample
|
|
FnPSample TtRowcnt
|
|
FmxSample int32
|
|
FiPrn Tu32
|
|
FaBest uintptr
|
|
FiMin int32
|
|
FnSample int32
|
|
FnMaxEqZero int32
|
|
FiGet int32
|
|
Fa uintptr
|
|
}
|
|
|
|
type TStatCursor = struct {
|
|
F__ccgo_align [0]uint32
|
|
Fbase Tsqlite3_vtab_cursor
|
|
FpStmt uintptr
|
|
FisEof Tu8
|
|
FisAgg Tu8
|
|
FiDb int32
|
|
FaPage [32]TStatPage
|
|
FiPage int32
|
|
FiPageno Tu32
|
|
FzName uintptr
|
|
FzPath uintptr
|
|
FzPagetype uintptr
|
|
FnPage int32
|
|
FnCell int32
|
|
FnMxPayload int32
|
|
FnUnused Ti64
|
|
FnPayload Ti64
|
|
FiOffset Ti64
|
|
FszPage Ti64
|
|
}
|
|
|
|
type TStatSample = struct {
|
|
F__ccgo_align [0]uint32
|
|
FanDLt uintptr
|
|
FanEq uintptr
|
|
FanLt uintptr
|
|
F__ccgo_align3 [4]byte
|
|
Fu struct {
|
|
F__ccgo_align [0]uint32
|
|
FaRowid [0]uintptr
|
|
FiRowid Ti64
|
|
}
|
|
FnRowid Tu32
|
|
FisPSample Tu8
|
|
FiCol int32
|
|
FiHash Tu32
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** An instance of the following structure holds the context of a
|
|
// ** sum() or avg() aggregate computation.
|
|
// */
|
|
type TSumCtx = struct {
|
|
F__ccgo_align [0]uint32
|
|
FrSum float64
|
|
FrErr float64
|
|
FiSum Ti64
|
|
Fcnt Ti64
|
|
Fapprox Tu8
|
|
Fovrfl Tu8
|
|
F__ccgo_pad6 [6]byte
|
|
}
|
|
|
|
type TUnpackedRecord = struct {
|
|
F__ccgo_align [0]uint32
|
|
FpKeyInfo uintptr
|
|
FaMem uintptr
|
|
Fu struct {
|
|
F__ccgo_align [0]uint32
|
|
Fi [0]Ti64
|
|
Fz uintptr
|
|
F__ccgo_pad2 [4]byte
|
|
}
|
|
Fn int32
|
|
FnField Tu16
|
|
Fdefault_rc Ti8
|
|
FerrCode Tu8
|
|
Fr1 Ti8
|
|
Fr2 Ti8
|
|
FeqSeen Tu8
|
|
F__ccgo_pad10 [5]byte
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** A single VDBE is an opaque structure named "Vdbe". Only routines
|
|
// ** in the source file sqliteVdbe.c are allowed to see the insides
|
|
// ** of this structure.
|
|
// */
|
|
type TVdbe = struct {
|
|
F__ccgo_align [0]uint32
|
|
Fdb uintptr
|
|
FppVPrev uintptr
|
|
FpVNext uintptr
|
|
FpParse uintptr
|
|
FnVar TynVar
|
|
FnMem int32
|
|
FnCursor int32
|
|
FcacheCtr Tu32
|
|
Fpc int32
|
|
Frc int32
|
|
FnChange Ti64
|
|
FiStatement int32
|
|
F__ccgo_align12 [4]byte
|
|
FiCurrentTime Ti64
|
|
FnFkConstraint Ti64
|
|
FnStmtDefCons Ti64
|
|
FnStmtDefImmCons Ti64
|
|
FaMem uintptr
|
|
FapArg uintptr
|
|
FapCsr uintptr
|
|
FaVar uintptr
|
|
FaOp uintptr
|
|
FnOp int32
|
|
FnOpAlloc int32
|
|
FaColName uintptr
|
|
FpResultRow uintptr
|
|
FzErrMsg uintptr
|
|
FpVList uintptr
|
|
F__ccgo_align27 [4]byte
|
|
FstartTime Ti64
|
|
FnResColumn Tu16
|
|
FnResAlloc Tu16
|
|
FerrorAction Tu8
|
|
FminWriteFileFormat Tu8
|
|
FprepFlags Tu8
|
|
FeVdbeState Tu8
|
|
F__ccgo152 uint16
|
|
FbtreeMask TyDbMask
|
|
FlockMask TyDbMask
|
|
FaCounter [9]Tu32
|
|
FzSql uintptr
|
|
FpFree uintptr
|
|
FpFrame uintptr
|
|
FpDelFrame uintptr
|
|
FnFrame int32
|
|
Fexpmask Tu32
|
|
FpProgram uintptr
|
|
FpAuxData uintptr
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** A VdbeCursor is an superclass (a wrapper) for various cursor objects:
|
|
// **
|
|
// ** * A b-tree cursor
|
|
// ** - In the main database or in an ephemeral database
|
|
// ** - On either an index or a table
|
|
// ** * A sorter
|
|
// ** * A virtual table
|
|
// ** * A one-row "pseudotable" stored in a single register
|
|
// */
|
|
type TVdbeCursor = struct {
|
|
F__ccgo_align [0]uint32
|
|
FeCurType Tu8
|
|
FiDb Ti8
|
|
FnullRow Tu8
|
|
FdeferredMoveto Tu8
|
|
FisTable Tu8
|
|
F__ccgo_align5 [3]byte
|
|
F__ccgo8 uint8
|
|
FseekHit Tu16
|
|
Fub struct {
|
|
FaAltMap [0]uintptr
|
|
FpBtx uintptr
|
|
}
|
|
FseqCount Ti64
|
|
FcacheStatus Tu32
|
|
FseekResult int32
|
|
FpAltCursor uintptr
|
|
Fuc struct {
|
|
FpVCur [0]uintptr
|
|
FpSorter [0]uintptr
|
|
FpCursor uintptr
|
|
}
|
|
FpKeyInfo uintptr
|
|
FiHdrOffset Tu32
|
|
FpgnoRoot TPgno
|
|
FnField Ti16
|
|
FnHdrParsed Tu16
|
|
FmovetoTarget Ti64
|
|
FaOffset uintptr
|
|
FaRow uintptr
|
|
FpayloadSize Tu32
|
|
FszRow Tu32
|
|
FpCache uintptr
|
|
F__ccgo_pad29 [4]byte
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** When a sub-program is executed (OP_Program), a structure of this type
|
|
// ** is allocated to store the current value of the program counter, as
|
|
// ** well as the current memory cell array and various other frame specific
|
|
// ** values stored in the Vdbe struct. When the sub-program is finished,
|
|
// ** these values are copied back to the Vdbe from the VdbeFrame structure,
|
|
// ** restoring the state of the VM to as it was before the sub-program
|
|
// ** began executing.
|
|
// **
|
|
// ** The memory for a VdbeFrame object is allocated and managed by a memory
|
|
// ** cell in the parent (calling) frame. When the memory cell is deleted or
|
|
// ** overwritten, the VdbeFrame object is not freed immediately. Instead, it
|
|
// ** is linked into the Vdbe.pDelFrame list. The contents of the Vdbe.pDelFrame
|
|
// ** list is deleted when the VM is reset in VdbeHalt(). The reason for doing
|
|
// ** this instead of deleting the VdbeFrame immediately is to avoid recursive
|
|
// ** calls to sqlite3VdbeMemRelease() when the memory cells belonging to the
|
|
// ** child frame are released.
|
|
// **
|
|
// ** The currently executing frame is stored in Vdbe.pFrame. Vdbe.pFrame is
|
|
// ** set to NULL if the currently executing frame is the main program.
|
|
// */
|
|
type TVdbeFrame = struct {
|
|
F__ccgo_align [0]uint32
|
|
Fv uintptr
|
|
FpParent uintptr
|
|
FaOp uintptr
|
|
FaMem uintptr
|
|
FapCsr uintptr
|
|
FaOnce uintptr
|
|
Ftoken uintptr
|
|
F__ccgo_align7 [4]byte
|
|
FlastRowid Ti64
|
|
FpAuxData uintptr
|
|
FnCursor int32
|
|
Fpc int32
|
|
FnOp int32
|
|
FnMem int32
|
|
FnChildMem int32
|
|
FnChildCsr int32
|
|
F__ccgo_align15 [4]byte
|
|
FnChange Ti64
|
|
FnDbChange Ti64
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /* Opaque type used by code in vdbesort.c */
|
|
type TVdbeSorter = struct {
|
|
F__ccgo_align [0]uint32
|
|
FmnPmaSize int32
|
|
FmxPmaSize int32
|
|
FmxKeysize int32
|
|
Fpgsz int32
|
|
FpReader uintptr
|
|
FpMerger uintptr
|
|
Fdb uintptr
|
|
FpKeyInfo uintptr
|
|
FpUnpacked uintptr
|
|
F__ccgo_align9 [4]byte
|
|
Flist TSorterList
|
|
FiMemory int32
|
|
FnMemory int32
|
|
FbUsePMA Tu8
|
|
FbUseThreads Tu8
|
|
FiPrev Tu8
|
|
FnTask Tu8
|
|
FtypeMask Tu8
|
|
F__ccgo_pad18 [3]byte
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /* A cache of large TEXT or BLOB values in a VdbeCursor */
|
|
type TVdbeTxtBlbCache = struct {
|
|
F__ccgo_align [0]uint32
|
|
FpCValue uintptr
|
|
F__ccgo_align1 [4]byte
|
|
FiOffset Ti64
|
|
FiCol int32
|
|
FcacheStatus Tu32
|
|
FcolCacheCtr Tu32
|
|
F__ccgo_pad5 [4]byte
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /* Connection to a write-ahead log (WAL) file.
|
|
// ** There is one object of this type for each pager.
|
|
// */
|
|
type TWal = struct {
|
|
F__ccgo_align [0]uint32
|
|
FpVfs uintptr
|
|
FpDbFd uintptr
|
|
FpWalFd uintptr
|
|
FiCallback Tu32
|
|
FmxWalSize Ti64
|
|
FnWiData int32
|
|
FszFirstBlock int32
|
|
FapWiData uintptr
|
|
FszPage Tu32
|
|
FreadLock Ti16
|
|
FsyncFlags Tu8
|
|
FexclusiveMode Tu8
|
|
FwriteLock Tu8
|
|
FckptLock Tu8
|
|
FreadOnly Tu8
|
|
FtruncateOnCommit Tu8
|
|
FsyncHeader Tu8
|
|
FpadToSectorBoundary Tu8
|
|
FbShmUnreliable Tu8
|
|
Fhdr TWalIndexHdr
|
|
FminFrame Tu32
|
|
FiReCksum Tu32
|
|
FzWalName uintptr
|
|
FnCkpt Tu32
|
|
FpSnapshot uintptr
|
|
FbGetSnapshot int32
|
|
F__ccgo_pad26 [4]byte
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Information about the current state of the WAL file and where
|
|
// ** the next fsync should occur - passed from sqlite3WalFrames() into
|
|
// ** walWriteToLog().
|
|
// */
|
|
type TWalWriter = struct {
|
|
F__ccgo_align [0]uint32
|
|
FpWal uintptr
|
|
FpFd uintptr
|
|
FiSyncPoint Tsqlite3_int64
|
|
FsyncFlags int32
|
|
FszPage int32
|
|
}
|
|
|
|
type TWhereAndInfo = struct {
|
|
F__ccgo_align [0]uint32
|
|
Fwc TWhereClause
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /* Forward references
|
|
// */
|
|
type TWhereClause = struct {
|
|
F__ccgo_align [0]uint32
|
|
FpWInfo uintptr
|
|
FpOuter uintptr
|
|
Fop Tu8
|
|
FhasOr Tu8
|
|
FnTerm int32
|
|
FnSlot int32
|
|
FnBase int32
|
|
Fa uintptr
|
|
F__ccgo_align8 [4]byte
|
|
FaStatic [8]TWhereTerm
|
|
}
|
|
|
|
type TWhereInfo = struct {
|
|
F__ccgo_align [0]uint32
|
|
FpParse uintptr
|
|
FpTabList uintptr
|
|
FpOrderBy uintptr
|
|
FpResultSet uintptr
|
|
FpSelect uintptr
|
|
FaiCurOnePass [2]int32
|
|
FiContinue int32
|
|
FiBreak int32
|
|
FsavedNQueryLoop int32
|
|
FwctrlFlags Tu16
|
|
FiLimit TLogEst
|
|
FnLevel Tu8
|
|
FnOBSat Ti8
|
|
FeOnePass Tu8
|
|
FeDistinct Tu8
|
|
F__ccgo48 uint8
|
|
FnRowOut TLogEst
|
|
FiTop int32
|
|
FiEndWhere int32
|
|
FpLoops uintptr
|
|
FpMemToFree uintptr
|
|
F__ccgo_align26 [4]byte
|
|
FrevMask TBitmask
|
|
FsWC TWhereClause
|
|
FsMaskSet TWhereMaskSet
|
|
}
|
|
|
|
type TWhereLevel = struct {
|
|
F__ccgo_align [0]uint32
|
|
FiLeftJoin int32
|
|
FiTabCur int32
|
|
FiIdxCur int32
|
|
FaddrBrk int32
|
|
FaddrHalt int32
|
|
FaddrNxt int32
|
|
FaddrSkip int32
|
|
FaddrCont int32
|
|
FaddrFirst int32
|
|
FaddrBody int32
|
|
FregBignull int32
|
|
FaddrBignull int32
|
|
FregFilter int32
|
|
FpRJ uintptr
|
|
FiFrom Tu8
|
|
Fop Tu8
|
|
Fp3 Tu8
|
|
Fp5 Tu8
|
|
Fp1 int32
|
|
Fp2 int32
|
|
Fu struct {
|
|
FpCoveringIdx [0]uintptr
|
|
Fin struct {
|
|
FnIn int32
|
|
FaInLoop uintptr
|
|
}
|
|
}
|
|
FpWLoop uintptr
|
|
FnotReady TBitmask
|
|
}
|
|
|
|
type TWhereLoop = struct {
|
|
F__ccgo_align [0]uint32
|
|
Fprereq TBitmask
|
|
FmaskSelf TBitmask
|
|
FiTab Tu8
|
|
FiSortIdx Tu8
|
|
FrSetup TLogEst
|
|
FrRun TLogEst
|
|
FnOut TLogEst
|
|
Fu struct {
|
|
Fvtab [0]struct {
|
|
FidxNum int32
|
|
F__ccgo4 uint8
|
|
FisOrdered Ti8
|
|
FomitMask Tu16
|
|
FidxStr uintptr
|
|
FmHandleIn Tu32
|
|
}
|
|
Fbtree struct {
|
|
FnEq Tu16
|
|
FnBtm Tu16
|
|
FnTop Tu16
|
|
FnDistinctCol Tu16
|
|
FpIndex uintptr
|
|
FpOrderBy uintptr
|
|
}
|
|
}
|
|
FwsFlags Tu32
|
|
FnLTerm Tu16
|
|
FnSkip Tu16
|
|
FnLSlot Tu16
|
|
FaLTerm uintptr
|
|
FpNextLoop uintptr
|
|
FaLTermSpace [3]uintptr
|
|
}
|
|
|
|
type TWhereMemBlock = struct {
|
|
F__ccgo_align [0]uint32
|
|
FpNext uintptr
|
|
F__ccgo_align1 [4]byte
|
|
Fsz Tu64
|
|
}
|
|
|
|
type TWhereOrCost = struct {
|
|
F__ccgo_align [0]uint32
|
|
Fprereq TBitmask
|
|
FrRun TLogEst
|
|
FnOut TLogEst
|
|
F__ccgo_pad3 [4]byte
|
|
}
|
|
|
|
type TWhereOrInfo = struct {
|
|
F__ccgo_align [0]uint32
|
|
Fwc TWhereClause
|
|
Findexable TBitmask
|
|
}
|
|
|
|
type TWhereOrSet = struct {
|
|
F__ccgo_align [0]uint32
|
|
Fn Tu16
|
|
F__ccgo_align1 [6]byte
|
|
Fa [3]TWhereOrCost
|
|
}
|
|
|
|
type TWherePath = struct {
|
|
F__ccgo_align [0]uint32
|
|
FmaskLoop TBitmask
|
|
FrevLoop TBitmask
|
|
FnRow TLogEst
|
|
FrCost TLogEst
|
|
FrUnsort TLogEst
|
|
FisOrdered Ti8
|
|
FaLoop uintptr
|
|
F__ccgo_pad7 [4]byte
|
|
}
|
|
|
|
type TWhereTerm = struct {
|
|
F__ccgo_align [0]uint32
|
|
FpExpr uintptr
|
|
FpWC uintptr
|
|
FtruthProb TLogEst
|
|
FwtFlags Tu16
|
|
FeOperator Tu16
|
|
FnChild Tu8
|
|
FeMatchOp Tu8
|
|
FiParent int32
|
|
FleftCursor int32
|
|
Fu struct {
|
|
FpOrInfo [0]uintptr
|
|
FpAndInfo [0]uintptr
|
|
Fx struct {
|
|
FleftColumn int32
|
|
FiField int32
|
|
}
|
|
}
|
|
FprereqRight TBitmask
|
|
FprereqAll TBitmask
|
|
}
|
|
|
|
type Tlldiv_t = struct {
|
|
F__ccgo_align [0]uint32
|
|
Fquot int64
|
|
Frem int64
|
|
}
|
|
|
|
type Trbu_file = struct {
|
|
F__ccgo_align [0]uint32
|
|
Fbase Tsqlite3_file
|
|
FpReal uintptr
|
|
FpRbuVfs uintptr
|
|
FpRbu uintptr
|
|
Fsz Ti64
|
|
FopenFlags int32
|
|
FiCookie Tu32
|
|
FiWriteVer Tu8
|
|
FbNolock Tu8
|
|
FnShm int32
|
|
FapShm uintptr
|
|
FzDel uintptr
|
|
FzWal uintptr
|
|
FpWalFd uintptr
|
|
FpMainNext uintptr
|
|
FpMainRbuNext uintptr
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** CAPI3REF: Database Connection Handle
|
|
// ** KEYWORDS: {database connection} {database connections}
|
|
// **
|
|
// ** Each open SQLite database is represented by a pointer to an instance of
|
|
// ** the opaque structure named "sqlite3". It is useful to think of an sqlite3
|
|
// ** pointer as an object. The [sqlite3_open()], [sqlite3_open16()], and
|
|
// ** [sqlite3_open_v2()] interfaces are its constructors, and [sqlite3_close()]
|
|
// ** and [sqlite3_close_v2()] are its destructors. There are many other
|
|
// ** interfaces (such as
|
|
// ** [sqlite3_prepare_v2()], [sqlite3_create_function()], and
|
|
// ** [sqlite3_busy_timeout()] to name but three) that are methods on an
|
|
// ** sqlite3 object.
|
|
// */
|
|
type Tsqlite3 = struct {
|
|
F__ccgo_align [0]uint32
|
|
FpVfs uintptr
|
|
FpVdbe uintptr
|
|
FpDfltColl uintptr
|
|
Fmutex uintptr
|
|
FaDb uintptr
|
|
FnDb int32
|
|
FmDbFlags Tu32
|
|
F__ccgo_align7 [4]byte
|
|
Fflags Tu64
|
|
FlastRowid Ti64
|
|
FszMmap Ti64
|
|
FnSchemaLock Tu32
|
|
FopenFlags uint32
|
|
FerrCode int32
|
|
FerrByteOffset int32
|
|
FerrMask int32
|
|
FiSysErrno int32
|
|
FdbOptFlags Tu32
|
|
Fenc Tu8
|
|
FautoCommit Tu8
|
|
Ftemp_store Tu8
|
|
FmallocFailed Tu8
|
|
FbBenignMalloc Tu8
|
|
FdfltLockMode Tu8
|
|
FnextAutovac int8
|
|
FsuppressErr Tu8
|
|
FvtabOnConflict Tu8
|
|
FisTransactionSavepoint Tu8
|
|
FmTrace Tu8
|
|
FnoSharedCache Tu8
|
|
FnSqlExec Tu8
|
|
FeOpenState Tu8
|
|
FnFpDigit Tu8
|
|
FnextPagesize int32
|
|
FnChange Ti64
|
|
FnTotalChange Ti64
|
|
FaLimit [13]int32
|
|
FnMaxSorterMmap int32
|
|
Finit1 Tsqlite3InitInfo
|
|
FnVdbeActive int32
|
|
FnVdbeRead int32
|
|
FnVdbeWrite int32
|
|
FnVdbeExec int32
|
|
FnVDestroy int32
|
|
FnExtension int32
|
|
FaExtension uintptr
|
|
Ftrace struct {
|
|
FxV2 [0]uintptr
|
|
FxLegacy uintptr
|
|
}
|
|
FpTraceArg uintptr
|
|
FxProfile uintptr
|
|
FpProfileArg uintptr
|
|
FpCommitArg uintptr
|
|
FxCommitCallback uintptr
|
|
FpRollbackArg uintptr
|
|
FxRollbackCallback uintptr
|
|
FpUpdateArg uintptr
|
|
FxUpdateCallback uintptr
|
|
FpAutovacPagesArg uintptr
|
|
FxAutovacDestr uintptr
|
|
FxAutovacPages uintptr
|
|
FpParse uintptr
|
|
FpPreUpdateArg uintptr
|
|
FxPreUpdateCallback uintptr
|
|
FpPreUpdate uintptr
|
|
FxWalCallback uintptr
|
|
FpWalArg uintptr
|
|
FxCollNeeded uintptr
|
|
FxCollNeeded16 uintptr
|
|
FpCollNeededArg uintptr
|
|
FpErr uintptr
|
|
Fu1 struct {
|
|
F__ccgo_align [0]uint32
|
|
FnotUsed1 [0]float64
|
|
FisInterrupted int32
|
|
F__ccgo_pad2 [4]byte
|
|
}
|
|
Flookaside TLookaside
|
|
FxAuth Tsqlite3_xauth
|
|
FpAuthArg uintptr
|
|
FxProgress uintptr
|
|
FpProgressArg uintptr
|
|
FnProgressOps uint32
|
|
FnVTrans int32
|
|
FaModule THash
|
|
FpVtabCtx uintptr
|
|
FaVTrans uintptr
|
|
FpDisconnect uintptr
|
|
FaFunc THash
|
|
FaCollSeq THash
|
|
FbusyHandler TBusyHandler
|
|
FaDbStatic [2]TDb
|
|
FpSavepoint uintptr
|
|
FnAnalysisLimit int32
|
|
FbusyTimeout int32
|
|
FnSavepoint int32
|
|
FnStatement int32
|
|
FnDeferredCons Ti64
|
|
FnDeferredImmCons Ti64
|
|
FpnBytesFreed uintptr
|
|
FpDbData uintptr
|
|
FnSpill Tu64
|
|
FpBlockingConnection uintptr
|
|
FpUnlockConnection uintptr
|
|
FpUnlockArg uintptr
|
|
FxUnlockNotify uintptr
|
|
FpNextBlocked uintptr
|
|
F__ccgo_pad99 [4]byte
|
|
}
|
|
|
|
type Tsqlite3_index_info = struct {
|
|
F__ccgo_align [0]uint32
|
|
FnConstraint int32
|
|
FaConstraint uintptr
|
|
FnOrderBy int32
|
|
FaOrderBy uintptr
|
|
FaConstraintUsage uintptr
|
|
FidxNum int32
|
|
FidxStr uintptr
|
|
FneedToFreeIdxStr int32
|
|
ForderByConsumed int32
|
|
F__ccgo_align9 [4]byte
|
|
FestimatedCost float64
|
|
FestimatedRows Tsqlite3_int64
|
|
FidxFlags int32
|
|
F__ccgo_align12 [4]byte
|
|
FcolUsed Tsqlite3_uint64
|
|
}
|
|
|
|
type Tsqlite3_rtree_query_info = struct {
|
|
F__ccgo_align [0]uint32
|
|
FpContext uintptr
|
|
FnParam int32
|
|
FaParam uintptr
|
|
FpUser uintptr
|
|
FxDelUser uintptr
|
|
FaCoord uintptr
|
|
FanQueue uintptr
|
|
FnCoord int32
|
|
FiLevel int32
|
|
FmxLevel int32
|
|
FiRowid Tsqlite3_int64
|
|
FrParentScore Tsqlite3_rtree_dbl
|
|
FeParentWithin int32
|
|
FeWithin int32
|
|
FrScore Tsqlite3_rtree_dbl
|
|
FapSqlParam uintptr
|
|
F__ccgo_pad16 [4]byte
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** CAPI3REF: Session Object Handle
|
|
// **
|
|
// ** An instance of this object is a [session] that can be used to
|
|
// ** record changes to a database.
|
|
// */
|
|
type Tsqlite3_session = struct {
|
|
F__ccgo_align [0]uint32
|
|
Fdb uintptr
|
|
FzDb uintptr
|
|
FbEnableSize int32
|
|
FbEnable int32
|
|
FbIndirect int32
|
|
FbAutoAttach int32
|
|
FbImplicitPK int32
|
|
Frc int32
|
|
FpFilterCtx uintptr
|
|
FxTableFilter uintptr
|
|
FnMalloc Ti64
|
|
FnMaxChangesetSize Ti64
|
|
FpZeroBlob uintptr
|
|
FpNext uintptr
|
|
FpTable uintptr
|
|
Fhook TSessionHook
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** CAPI3REF: Dynamically Typed Value Object
|
|
// ** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value}
|
|
// **
|
|
// ** SQLite uses the sqlite3_value object to represent all values
|
|
// ** that can be stored in a database table. SQLite uses dynamic typing
|
|
// ** for the values it stores. ^Values stored in sqlite3_value objects
|
|
// ** can be integers, floating point values, strings, BLOBs, or NULL.
|
|
// **
|
|
// ** An sqlite3_value object may be either "protected" or "unprotected".
|
|
// ** Some interfaces require a protected sqlite3_value. Other interfaces
|
|
// ** will accept either a protected or an unprotected sqlite3_value.
|
|
// ** Every interface that accepts sqlite3_value arguments specifies
|
|
// ** whether or not it requires a protected sqlite3_value. The
|
|
// ** [sqlite3_value_dup()] interface can be used to construct a new
|
|
// ** protected sqlite3_value from an unprotected sqlite3_value.
|
|
// **
|
|
// ** The terms "protected" and "unprotected" refer to whether or not
|
|
// ** a mutex is held. An internal mutex is held for a protected
|
|
// ** sqlite3_value object but no mutex is held for an unprotected
|
|
// ** sqlite3_value object. If SQLite is compiled to be single-threaded
|
|
// ** (with [SQLITE_THREADSAFE=0] and with [sqlite3_threadsafe()] returning 0)
|
|
// ** or if SQLite is run in one of reduced mutex modes
|
|
// ** [SQLITE_CONFIG_SINGLETHREAD] or [SQLITE_CONFIG_MULTITHREAD]
|
|
// ** then there is no distinction between protected and unprotected
|
|
// ** sqlite3_value objects and they can be used interchangeably. However,
|
|
// ** for maximum code portability it is recommended that applications
|
|
// ** still make the distinction between protected and unprotected
|
|
// ** sqlite3_value objects even when not strictly required.
|
|
// **
|
|
// ** ^The sqlite3_value objects that are passed as parameters into the
|
|
// ** implementation of [application-defined SQL functions] are protected.
|
|
// ** ^The sqlite3_value objects returned by [sqlite3_vtab_rhs_value()]
|
|
// ** are protected.
|
|
// ** ^The sqlite3_value object returned by
|
|
// ** [sqlite3_column_value()] is unprotected.
|
|
// ** Unprotected sqlite3_value objects may only be used as arguments
|
|
// ** to [sqlite3_result_value()], [sqlite3_bind_value()], and
|
|
// ** [sqlite3_value_dup()].
|
|
// ** The [sqlite3_value_blob | sqlite3_value_type()] family of
|
|
// ** interfaces require protected sqlite3_value objects.
|
|
// */
|
|
type Tsqlite3_value = struct {
|
|
F__ccgo_align [0]uint32
|
|
Fu TMemValue
|
|
Fz uintptr
|
|
Fn int32
|
|
Fflags Tu16
|
|
Fenc Tu8
|
|
FeSubtype Tu8
|
|
Fdb uintptr
|
|
FszMalloc int32
|
|
FuTemp Tu32
|
|
FzMalloc uintptr
|
|
FxDel uintptr
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Set all the parameters in the compiled SQL statement to NULL.
|
|
// */
|
|
func Xsqlite3_clear_bindings(tls *libc.TLS, pStmt uintptr) (r int32) {
|
|
var i, rc int32
|
|
var mutex, p uintptr
|
|
_, _, _, _ = i, mutex, p, rc
|
|
rc = SQLITE_OK
|
|
p = pStmt
|
|
mutex = (*Tsqlite3)(unsafe.Pointer((*TVdbe)(unsafe.Pointer(p)).Fdb)).Fmutex
|
|
Xsqlite3_mutex_enter(tls, mutex)
|
|
i = 0
|
|
for {
|
|
if !(i < int32((*TVdbe)(unsafe.Pointer(p)).FnVar)) {
|
|
break
|
|
}
|
|
_sqlite3VdbeMemRelease(tls, (*TVdbe)(unsafe.Pointer(p)).FaVar+uintptr(i)*40)
|
|
(**(**TMem)(__ccgo_up((*TVdbe)(unsafe.Pointer(p)).FaVar + uintptr(i)*40))).Fflags = uint16(MEM_Null)
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
if (*TVdbe)(unsafe.Pointer(p)).Fexpmask != 0 {
|
|
libc.SetBitFieldPtr16Uint32(p+152, libc.Uint32FromInt32(1), 0, 0x3)
|
|
}
|
|
Xsqlite3_mutex_leave(tls, mutex)
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** External API to drop all virtual-table modules, except those named
|
|
// ** on the azNames list.
|
|
// */
|
|
func Xsqlite3_drop_modules(tls *libc.TLS, db uintptr, azNames uintptr) (r int32) {
|
|
var ii int32
|
|
var pMod, pNext, pThis uintptr
|
|
_, _, _, _ = ii, pMod, pNext, pThis
|
|
Xsqlite3_mutex_enter(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
|
|
pThis = (*THash)(unsafe.Pointer(db + 404)).Ffirst
|
|
for {
|
|
if !(pThis != 0) {
|
|
break
|
|
}
|
|
pMod = (*THashElem)(unsafe.Pointer(pThis)).Fdata
|
|
pNext = (*THashElem)(unsafe.Pointer(pThis)).Fnext
|
|
if azNames != 0 {
|
|
ii = 0
|
|
for {
|
|
if !(**(**uintptr)(__ccgo_up(azNames + uintptr(ii)*4)) != uintptr(0) && libc.Xstrcmp(tls, **(**uintptr)(__ccgo_up(azNames + uintptr(ii)*4)), (*TModule)(unsafe.Pointer(pMod)).FzName) != 0) {
|
|
break
|
|
}
|
|
goto _2
|
|
_2:
|
|
;
|
|
ii = ii + 1
|
|
}
|
|
if **(**uintptr)(__ccgo_up(azNames + uintptr(ii)*4)) != uintptr(0) {
|
|
goto _1
|
|
}
|
|
}
|
|
_createModule(tls, db, (*TModule)(unsafe.Pointer(pMod)).FzName, uintptr(0), uintptr(0), uintptr(0))
|
|
goto _1
|
|
_1:
|
|
;
|
|
pThis = pNext
|
|
}
|
|
Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
|
|
return SQLITE_OK
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Return TRUE (non-zero) of the statement supplied as an argument needs
|
|
// ** to be recompiled. A statement needs to be recompiled whenever the
|
|
// ** execution environment changes in a way that would alter the program
|
|
// ** that sqlite3_prepare() generates. For example, if new functions or
|
|
// ** collating sequences are registered or if an authorizer function is
|
|
// ** added or changed.
|
|
// */
|
|
func Xsqlite3_expired(tls *libc.TLS, pStmt uintptr) (r int32) {
|
|
var iRet int32
|
|
var p uintptr
|
|
_, _ = iRet, p
|
|
iRet = int32(1)
|
|
if pStmt != 0 {
|
|
p = pStmt
|
|
Xsqlite3_mutex_enter(tls, (*Tsqlite3)(unsafe.Pointer((*TVdbe)(unsafe.Pointer(p)).Fdb)).Fmutex)
|
|
iRet = int32(Tbft(*(*uint16)(unsafe.Pointer(p + 152)) & 0x3 >> 0))
|
|
Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer((*TVdbe)(unsafe.Pointer(p)).Fdb)).Fmutex)
|
|
}
|
|
return iRet
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Cause any pending operation to stop at its earliest opportunity.
|
|
// */
|
|
func Xsqlite3_interrupt(tls *libc.TLS, db uintptr) {
|
|
libc.AtomicStoreNInt32(db+312, libc.Int32FromInt32(1), libc.Int32FromInt32(__ATOMIC_RELAXED))
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Return true or false depending on whether or not an interrupt is
|
|
// ** pending on connection db.
|
|
// */
|
|
func Xsqlite3_is_interrupted(tls *libc.TLS, db uintptr) (r int32) {
|
|
return libc.BoolInt32(libc.AtomicLoadNInt32(db+312, libc.Int32FromInt32(__ATOMIC_RELAXED)) != 0)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Change the value of a limit. Report the old value.
|
|
// ** If an invalid limit index is supplied, report -1.
|
|
// ** Make no changes but still report the old value if the
|
|
// ** new limit is negative.
|
|
// **
|
|
// ** A new lower limit does not shrink existing constructs.
|
|
// ** It merely prevents new constructs that exceed the limit
|
|
// ** from forming.
|
|
// */
|
|
func Xsqlite3_limit(tls *libc.TLS, db uintptr, limitId int32, newLimit int32) (r int32) {
|
|
var oldLimit int32
|
|
_ = oldLimit
|
|
/* EVIDENCE-OF: R-30189-54097 For each limit category SQLITE_LIMIT_NAME
|
|
** there is a hard upper bound set at compile-time by a C preprocessor
|
|
** macro called SQLITE_MAX_NAME. (The "_LIMIT_" in the name is changed to
|
|
** "_MAX_".)
|
|
*/
|
|
if limitId < 0 || limitId >= libc.Int32FromInt32(SQLITE_LIMIT_PARSER_DEPTH)+libc.Int32FromInt32(1) {
|
|
return -int32(1)
|
|
}
|
|
Xsqlite3_mutex_enter(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
|
|
oldLimit = **(**int32)(__ccgo_up(db + 120 + uintptr(limitId)*4))
|
|
if newLimit >= 0 { /* IMP: R-52476-28732 */
|
|
if newLimit > _aHardLimit[limitId] {
|
|
newLimit = _aHardLimit[limitId] /* IMP: R-51463-25634 */
|
|
} else {
|
|
if newLimit < int32(SQLITE_MIN_LENGTH) && limitId == SQLITE_LIMIT_LENGTH {
|
|
newLimit = int32(SQLITE_MIN_LENGTH)
|
|
}
|
|
}
|
|
**(**int32)(__ccgo_up(db + 120 + uintptr(limitId)*4)) = newLimit
|
|
}
|
|
Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
|
|
return oldLimit /* IMP: R-53341-35419 */
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Register a profile function. The pArg from the previously registered
|
|
// ** profile function is returned.
|
|
// **
|
|
// ** A NULL profile function means that no profiling is executes. A non-NULL
|
|
// ** profile is a pointer to a function that is invoked at the conclusion of
|
|
// ** each SQL statement that is run.
|
|
// */
|
|
func Xsqlite3_profile(tls *libc.TLS, db uintptr, __ccgo_fp_xProfile uintptr, pArg uintptr) (r uintptr) {
|
|
var pOld, v1 uintptr
|
|
_, _ = pOld, v1
|
|
Xsqlite3_mutex_enter(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
|
|
pOld = (*Tsqlite3)(unsafe.Pointer(db)).FpProfileArg
|
|
(*Tsqlite3)(unsafe.Pointer(db)).FxProfile = __ccgo_fp_xProfile
|
|
(*Tsqlite3)(unsafe.Pointer(db)).FpProfileArg = pArg
|
|
v1 = db + 94
|
|
*(*Tu8)(unsafe.Pointer(v1)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v1))) & libc.Int32FromInt32(SQLITE_TRACE_NONLEGACY_MASK))
|
|
if (*Tsqlite3)(unsafe.Pointer(db)).FxProfile != 0 {
|
|
v1 = db + 94
|
|
*(*Tu8)(unsafe.Pointer(v1)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v1))) | libc.Int32FromInt32(SQLITE_TRACE_XPROFILE))
|
|
}
|
|
Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
|
|
return pOld
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Add new client data to a database connection.
|
|
// */
|
|
func Xsqlite3_set_clientdata(tls *libc.TLS, db uintptr, zName uintptr, pData uintptr, __ccgo_fp_xDestructor uintptr) (r int32) {
|
|
var n Tsize_t
|
|
var p, pp uintptr
|
|
_, _, _ = n, p, pp
|
|
Xsqlite3_mutex_enter(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
|
|
pp = db + 548
|
|
p = (*Tsqlite3)(unsafe.Pointer(db)).FpDbData
|
|
for {
|
|
if !(p != 0 && libc.Xstrcmp(tls, p+12, zName) != 0) {
|
|
break
|
|
}
|
|
pp = p
|
|
goto _1
|
|
_1:
|
|
;
|
|
p = (*TDbClientData)(unsafe.Pointer(p)).FpNext
|
|
}
|
|
if p != 0 {
|
|
if (*TDbClientData)(unsafe.Pointer(p)).FxDestructor != 0 {
|
|
(*(*func(*libc.TLS, uintptr))(unsafe.Pointer(&struct{ uintptr }{(*TDbClientData)(unsafe.Pointer(p)).FxDestructor})))(tls, (*TDbClientData)(unsafe.Pointer(p)).FpData)
|
|
}
|
|
if pData == uintptr(0) {
|
|
**(**uintptr)(__ccgo_up(pp)) = (*TDbClientData)(unsafe.Pointer(p)).FpNext
|
|
Xsqlite3_free(tls, p)
|
|
Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
|
|
return SQLITE_OK
|
|
}
|
|
} else {
|
|
if pData == uintptr(0) {
|
|
Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
|
|
return SQLITE_OK
|
|
} else {
|
|
n = libc.Xstrlen(tls, zName)
|
|
p = Xsqlite3_malloc64(tls, uint64(uint32(libc.UintptrFromInt32(0)+12)+(n+libc.Uint32FromInt32(1))))
|
|
if p == uintptr(0) {
|
|
if __ccgo_fp_xDestructor != 0 {
|
|
(*(*func(*libc.TLS, uintptr))(unsafe.Pointer(&struct{ uintptr }{__ccgo_fp_xDestructor})))(tls, pData)
|
|
}
|
|
Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
|
|
return int32(SQLITE_NOMEM)
|
|
}
|
|
libc.Xmemcpy(tls, p+12, zName, n+uint32(1))
|
|
(*TDbClientData)(unsafe.Pointer(p)).FpNext = (*Tsqlite3)(unsafe.Pointer(db)).FpDbData
|
|
(*Tsqlite3)(unsafe.Pointer(db)).FpDbData = p
|
|
}
|
|
}
|
|
(*TDbClientData)(unsafe.Pointer(p)).FpData = pData
|
|
(*TDbClientData)(unsafe.Pointer(p)).FxDestructor = __ccgo_fp_xDestructor
|
|
Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
|
|
return SQLITE_OK
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Return 1 if the statement is an EXPLAIN and return 2 if the
|
|
// ** statement is an EXPLAIN QUERY PLAN
|
|
// */
|
|
func Xsqlite3_stmt_isexplain(tls *libc.TLS, pStmt uintptr) (r int32) {
|
|
var v1 int32
|
|
_ = v1
|
|
if pStmt != 0 {
|
|
v1 = int32(Tbft(*(*uint16)(unsafe.Pointer(pStmt + 152)) & 0xc >> 2))
|
|
} else {
|
|
v1 = 0
|
|
}
|
|
return v1
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Return true if the prepared statement is guaranteed to not modify the
|
|
// ** database.
|
|
// */
|
|
func Xsqlite3_stmt_readonly(tls *libc.TLS, pStmt uintptr) (r int32) {
|
|
var v1 int32
|
|
_ = v1
|
|
if pStmt != 0 {
|
|
v1 = int32(Tbft(*(*uint16)(unsafe.Pointer(pStmt + 152)) & 0x40 >> 6))
|
|
} else {
|
|
v1 = int32(1)
|
|
}
|
|
return v1
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /* Allocate and initialize a new dynamic string object */
|
|
func Xsqlite3_str_new(tls *libc.TLS, db uintptr) (r uintptr) {
|
|
var p uintptr
|
|
var v1 int32
|
|
_, _ = p, v1
|
|
p = Xsqlite3_malloc64(tls, uint64(24))
|
|
if p != 0 {
|
|
if db != 0 {
|
|
v1 = **(**int32)(__ccgo_up(db + 120))
|
|
} else {
|
|
v1 = int32(SQLITE_MAX_LENGTH)
|
|
}
|
|
_sqlite3StrAccumInit(tls, p, uintptr(0), uintptr(0), 0, v1)
|
|
} else {
|
|
p = uintptr(unsafe.Pointer(&_sqlite3OomStr))
|
|
}
|
|
return p
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /* Register a trace callback using the version-2 interface.
|
|
// */
|
|
func Xsqlite3_trace_v2(tls *libc.TLS, db uintptr, mTrace uint32, __ccgo_fp_xTrace uintptr, pArg uintptr) (r int32) {
|
|
Xsqlite3_mutex_enter(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
|
|
if mTrace == uint32(0) {
|
|
__ccgo_fp_xTrace = uintptr(0)
|
|
}
|
|
if __ccgo_fp_xTrace == uintptr(0) {
|
|
mTrace = uint32(0)
|
|
}
|
|
(*Tsqlite3)(unsafe.Pointer(db)).FmTrace = uint8(mTrace)
|
|
*(*uintptr)(unsafe.Pointer(db + 220)) = __ccgo_fp_xTrace
|
|
(*Tsqlite3)(unsafe.Pointer(db)).FpTraceArg = pArg
|
|
Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
|
|
return SQLITE_OK
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Deprecated external interface. Internal/core SQLite code
|
|
// ** should call sqlite3TransferBindings.
|
|
// **
|
|
// ** It is misuse to call this routine with statements from different
|
|
// ** database connections. But as this is a deprecated interface, we
|
|
// ** will not bother to check for that condition.
|
|
// **
|
|
// ** If the two statements contain a different number of bindings, then
|
|
// ** an SQLITE_ERROR is returned. Nothing else can go wrong, so otherwise
|
|
// ** SQLITE_OK is returned.
|
|
// */
|
|
func Xsqlite3_transfer_bindings(tls *libc.TLS, pFromStmt uintptr, pToStmt uintptr) (r int32) {
|
|
var pFrom, pTo uintptr
|
|
_, _ = pFrom, pTo
|
|
pFrom = pFromStmt
|
|
pTo = pToStmt
|
|
if int32((*TVdbe)(unsafe.Pointer(pFrom)).FnVar) != int32((*TVdbe)(unsafe.Pointer(pTo)).FnVar) {
|
|
return int32(SQLITE_ERROR)
|
|
}
|
|
if (*TVdbe)(unsafe.Pointer(pTo)).Fexpmask != 0 {
|
|
libc.SetBitFieldPtr16Uint32(pTo+152, libc.Uint32FromInt32(1), 0, 0x3)
|
|
}
|
|
if (*TVdbe)(unsafe.Pointer(pFrom)).Fexpmask != 0 {
|
|
libc.SetBitFieldPtr16Uint32(pFrom+152, libc.Uint32FromInt32(1), 0, 0x3)
|
|
}
|
|
return _sqlite3TransferBindings(tls, pFromStmt, pToStmt)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Return the collating sequence for a constraint passed into xBestIndex.
|
|
// **
|
|
// ** pIdxInfo must be an sqlite3_index_info structure passed into xBestIndex.
|
|
// ** This routine depends on there being a HiddenIndexInfo structure immediately
|
|
// ** following the sqlite3_index_info structure.
|
|
// **
|
|
// ** Return a pointer to the collation name:
|
|
// **
|
|
// ** 1. If there is an explicit COLLATE operator on the constraint, return it.
|
|
// **
|
|
// ** 2. Else, if the column has an alternative collation, return that.
|
|
// **
|
|
// ** 3. Otherwise, return "BINARY".
|
|
// */
|
|
func Xsqlite3_vtab_collation(tls *libc.TLS, pIdxInfo uintptr, iCons int32) (r uintptr) {
|
|
var iTerm int32
|
|
var pC, pHidden, pX, zRet, v1 uintptr
|
|
_, _, _, _, _, _ = iTerm, pC, pHidden, pX, zRet, v1
|
|
pHidden = pIdxInfo + 1*72
|
|
zRet = uintptr(0)
|
|
if iCons >= 0 && iCons < (*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FnConstraint {
|
|
pC = uintptr(0)
|
|
iTerm = (**(**Tsqlite3_index_constraint)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraint + uintptr(iCons)*12))).FiTermOffset
|
|
pX = (*TWhereTerm)(unsafe.Pointer(_termFromWhereClause(tls, (*THiddenIndexInfo)(unsafe.Pointer(pHidden)).FpWC, iTerm))).FpExpr
|
|
if (*TExpr)(unsafe.Pointer(pX)).FpLeft != 0 {
|
|
pC = _sqlite3ExprCompareCollSeq(tls, (*THiddenIndexInfo)(unsafe.Pointer(pHidden)).FpParse, pX)
|
|
}
|
|
if pC != 0 {
|
|
v1 = (*TCollSeq)(unsafe.Pointer(pC)).FzName
|
|
} else {
|
|
v1 = uintptr(unsafe.Pointer(&_sqlite3StrBINARY))
|
|
}
|
|
zRet = v1
|
|
}
|
|
return zRet
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Return true if ORDER BY clause may be handled as DISTINCT.
|
|
// */
|
|
func Xsqlite3_vtab_distinct(tls *libc.TLS, pIdxInfo uintptr) (r int32) {
|
|
var pHidden uintptr
|
|
_ = pHidden
|
|
pHidden = pIdxInfo + 1*72
|
|
return (*THiddenIndexInfo)(unsafe.Pointer(pHidden)).FeDistinct
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Return true if constraint iCons is really an IN(...) constraint, or
|
|
// ** false otherwise. If iCons is an IN(...) constraint, set (if bHandle!=0)
|
|
// ** or clear (if bHandle==0) the flag to handle it using an iterator.
|
|
// */
|
|
func Xsqlite3_vtab_in(tls *libc.TLS, pIdxInfo uintptr, iCons int32, bHandle int32) (r int32) {
|
|
var m Tu32
|
|
var pHidden uintptr
|
|
var v1 uint32
|
|
_, _, _ = m, pHidden, v1
|
|
pHidden = pIdxInfo + 1*72
|
|
if iCons <= int32(31) {
|
|
v1 = libc.Uint32FromInt32(1) << iCons
|
|
} else {
|
|
v1 = uint32(0)
|
|
}
|
|
m = v1
|
|
if m&(*THiddenIndexInfo)(unsafe.Pointer(pHidden)).FmIn != 0 {
|
|
if bHandle == 0 {
|
|
**(**Tu32)(__ccgo_up(pHidden + 16)) &= ^m
|
|
} else {
|
|
if bHandle > 0 {
|
|
**(**Tu32)(__ccgo_up(pHidden + 16)) |= m
|
|
}
|
|
}
|
|
return int32(1)
|
|
}
|
|
return 0
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This interface is callable from within the xBestIndex callback only.
|
|
// **
|
|
// ** If possible, set (*ppVal) to point to an object containing the value
|
|
// ** on the right-hand-side of constraint iCons.
|
|
// */
|
|
func Xsqlite3_vtab_rhs_value(tls *libc.TLS, pIdxInfo uintptr, iCons int32, ppVal uintptr) (r int32) {
|
|
var pH, pTerm, pVal uintptr
|
|
var rc int32
|
|
_, _, _, _ = pH, pTerm, pVal, rc
|
|
pH = pIdxInfo + 1*72
|
|
pVal = uintptr(0)
|
|
rc = SQLITE_OK
|
|
if iCons < 0 || iCons >= (*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FnConstraint {
|
|
rc = _sqlite3MisuseError(tls, int32(173448)) /* EV: R-30545-25046 */
|
|
} else {
|
|
if *(*uintptr)(unsafe.Pointer(pH + 20 + uintptr(iCons)*4)) == uintptr(0) {
|
|
pTerm = _termFromWhereClause(tls, (*THiddenIndexInfo)(unsafe.Pointer(pH)).FpWC, (**(**Tsqlite3_index_constraint)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraint + uintptr(iCons)*12))).FiTermOffset)
|
|
rc = _sqlite3ValueFromExpr(tls, (*TParse)(unsafe.Pointer((*THiddenIndexInfo)(unsafe.Pointer(pH)).FpParse)).Fdb, (*TExpr)(unsafe.Pointer((*TWhereTerm)(unsafe.Pointer(pTerm)).FpExpr)).FpRight, (*Tsqlite3)(unsafe.Pointer((*TParse)(unsafe.Pointer((*THiddenIndexInfo)(unsafe.Pointer(pH)).FpParse)).Fdb)).Fenc, uint8(SQLITE_AFF_BLOB), pH+20+uintptr(iCons)*4)
|
|
}
|
|
pVal = *(*uintptr)(unsafe.Pointer(pH + 20 + uintptr(iCons)*4))
|
|
}
|
|
**(**uintptr)(__ccgo_up(ppVal)) = pVal
|
|
if rc == SQLITE_OK && pVal == uintptr(0) { /* IMP: R-19933-32160 */
|
|
rc = int32(SQLITE_NOTFOUND) /* IMP: R-36424-56542 */
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Add connection db to the blocked connections list. It is assumed
|
|
// ** that it is not already a part of the list.
|
|
// */
|
|
func _addToBlockedList(tls *libc.TLS, db uintptr) {
|
|
var pp uintptr
|
|
_ = pp
|
|
pp = uintptr(unsafe.Pointer(&_sqlite3BlockedList))
|
|
for {
|
|
if !(**(**uintptr)(__ccgo_up(pp)) != 0 && (*Tsqlite3)(unsafe.Pointer(**(**uintptr)(__ccgo_up(pp)))).FxUnlockNotify != (*Tsqlite3)(unsafe.Pointer(db)).FxUnlockNotify) {
|
|
break
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
pp = **(**uintptr)(__ccgo_up(pp)) + 576
|
|
}
|
|
(*Tsqlite3)(unsafe.Pointer(db)).FpNextBlocked = **(**uintptr)(__ccgo_up(pp))
|
|
**(**uintptr)(__ccgo_up(pp)) = db
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Add the virtual table pVTab to the array sqlite3.aVTrans[]. Space should
|
|
// ** have already been reserved using growVTrans().
|
|
// */
|
|
func _addToVTrans(tls *libc.TLS, db uintptr, pVTab uintptr) {
|
|
var v1 int32
|
|
var v2 uintptr
|
|
_, _ = v1, v2
|
|
/* Add pVtab to the end of sqlite3.aVTrans */
|
|
v2 = db + 400
|
|
v1 = *(*int32)(unsafe.Pointer(v2))
|
|
*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1
|
|
**(**uintptr)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaVTrans + uintptr(v1)*4)) = pVTab
|
|
_sqlite3VtabLock(tls, pVTab)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /* Try to allocate nByte bytes of 8-byte aligned bulk memory for pBuf
|
|
// ** from the ReusableSpace object. Return a pointer to the allocated
|
|
// ** memory on success. If insufficient memory is available in the
|
|
// ** ReusableSpace object, increase the ReusableSpace.nNeeded
|
|
// ** value by the amount needed and return NULL.
|
|
// **
|
|
// ** If pBuf is not initially NULL, that means that the memory has already
|
|
// ** been allocated by a prior call to this routine, so just return a copy
|
|
// ** of pBuf and leave ReusableSpace unchanged.
|
|
// **
|
|
// ** This allocator is employed to repurpose unused slots at the end of the
|
|
// ** opcode array of prepared state for other memory needs of the prepared
|
|
// ** statement.
|
|
// */
|
|
func _allocSpace(tls *libc.TLS, p uintptr, pBuf uintptr, nByte Tsqlite3_int64) (r uintptr) {
|
|
if pBuf == uintptr(0) {
|
|
nByte = (nByte + libc.Int64FromInt32(7)) & int64(^libc.Int32FromInt32(7))
|
|
if nByte <= (*TReusableSpace)(unsafe.Pointer(p)).FnFree {
|
|
**(**Tsqlite3_int64)(__ccgo_up(p + 8)) -= nByte
|
|
pBuf = (*TReusableSpace)(unsafe.Pointer(p)).FpSpace + uintptr((*TReusableSpace)(unsafe.Pointer(p)).FnFree)
|
|
} else {
|
|
**(**Tsqlite3_int64)(__ccgo_up(p + 16)) += nByte
|
|
}
|
|
}
|
|
return pBuf
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Invoke the busy handler for a btree.
|
|
// */
|
|
func _btreeInvokeBusyHandler(tls *libc.TLS, pArg uintptr) (r int32) {
|
|
var pBt uintptr
|
|
_ = pBt
|
|
pBt = pArg
|
|
return _sqlite3InvokeBusyHandler(tls, (*TBtShared)(unsafe.Pointer(pBt)).Fdb+464)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Release all of the apPage[] pages for a cursor.
|
|
// */
|
|
func _btreeReleaseAllCursorPages(tls *libc.TLS, pCur uintptr) {
|
|
var i int32
|
|
_ = i
|
|
if int32((*TBtCursor)(unsafe.Pointer(pCur)).FiPage) >= 0 {
|
|
i = 0
|
|
for {
|
|
if !(i < int32((*TBtCursor)(unsafe.Pointer(pCur)).FiPage)) {
|
|
break
|
|
}
|
|
_releasePageNotNull(tls, **(**uintptr)(__ccgo_up(pCur + 120 + uintptr(i)*4)))
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
_releasePageNotNull(tls, (*TBtCursor)(unsafe.Pointer(pCur)).FpPage)
|
|
(*TBtCursor)(unsafe.Pointer(pCur)).FiPage = int8(-int32(1))
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Invoke the progress handler, if appropriate. Also check for an
|
|
// ** interrupt.
|
|
// */
|
|
func _checkProgress(tls *libc.TLS, pCheck uintptr) {
|
|
var db uintptr
|
|
_ = db
|
|
db = (*TIntegrityCk)(unsafe.Pointer(pCheck)).Fdb
|
|
if libc.AtomicLoadNInt32(db+312, libc.Int32FromInt32(__ATOMIC_RELAXED)) != 0 {
|
|
(*TIntegrityCk)(unsafe.Pointer(pCheck)).Frc = int32(SQLITE_INTERRUPT)
|
|
(*TIntegrityCk)(unsafe.Pointer(pCheck)).FnErr = (*TIntegrityCk)(unsafe.Pointer(pCheck)).FnErr + 1
|
|
(*TIntegrityCk)(unsafe.Pointer(pCheck)).FmxErr = 0
|
|
}
|
|
if (*Tsqlite3)(unsafe.Pointer(db)).FxProgress != 0 {
|
|
(*TIntegrityCk)(unsafe.Pointer(pCheck)).FnStep = (*TIntegrityCk)(unsafe.Pointer(pCheck)).FnStep + 1
|
|
if (*TIntegrityCk)(unsafe.Pointer(pCheck)).FnStep%(*Tsqlite3)(unsafe.Pointer(db)).FnProgressOps == uint32(0) && (*(*func(*libc.TLS, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*Tsqlite3)(unsafe.Pointer(db)).FxProgress})))(tls, (*Tsqlite3)(unsafe.Pointer(db)).FpProgressArg) != 0 {
|
|
(*TIntegrityCk)(unsafe.Pointer(pCheck)).Frc = int32(SQLITE_INTERRUPT)
|
|
(*TIntegrityCk)(unsafe.Pointer(pCheck)).FnErr = (*TIntegrityCk)(unsafe.Pointer(pCheck)).FnErr + 1
|
|
(*TIntegrityCk)(unsafe.Pointer(pCheck)).FmxErr = 0
|
|
}
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Close all cursors.
|
|
// **
|
|
// ** Also release any dynamic memory held by the VM in the Vdbe.aMem memory
|
|
// ** cell array. This is necessary as the memory cell array may contain
|
|
// ** pointers to VdbeFrame objects, which may in turn contain pointers to
|
|
// ** open cursors.
|
|
// */
|
|
func _closeAllCursors(tls *libc.TLS, p uintptr) {
|
|
var pDel, pFrame uintptr
|
|
_, _ = pDel, pFrame
|
|
if (*TVdbe)(unsafe.Pointer(p)).FpFrame != 0 {
|
|
pFrame = (*TVdbe)(unsafe.Pointer(p)).FpFrame
|
|
for {
|
|
if !((*TVdbeFrame)(unsafe.Pointer(pFrame)).FpParent != 0) {
|
|
break
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
pFrame = (*TVdbeFrame)(unsafe.Pointer(pFrame)).FpParent
|
|
}
|
|
_sqlite3VdbeFrameRestore(tls, pFrame)
|
|
(*TVdbe)(unsafe.Pointer(p)).FpFrame = uintptr(0)
|
|
(*TVdbe)(unsafe.Pointer(p)).FnFrame = 0
|
|
}
|
|
_closeCursorsInFrame(tls, p)
|
|
_releaseMemArray(tls, (*TVdbe)(unsafe.Pointer(p)).FaMem, (*TVdbe)(unsafe.Pointer(p)).FnMem)
|
|
for (*TVdbe)(unsafe.Pointer(p)).FpDelFrame != 0 {
|
|
pDel = (*TVdbe)(unsafe.Pointer(p)).FpDelFrame
|
|
(*TVdbe)(unsafe.Pointer(p)).FpDelFrame = (*TVdbeFrame)(unsafe.Pointer(pDel)).FpParent
|
|
_sqlite3VdbeFrameDelete(tls, pDel)
|
|
}
|
|
/* Delete any auxdata allocations made by the VM */
|
|
if (*TVdbe)(unsafe.Pointer(p)).FpAuxData != 0 {
|
|
_sqlite3VdbeDeleteAuxData(tls, (*TVdbe)(unsafe.Pointer(p)).Fdb, p+228, -int32(1), 0)
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Free an sqlite3_index_info structure allocated by allocateIndexInfo()
|
|
// ** and possibly modified by xBestIndex methods.
|
|
// */
|
|
func _freeIndexInfo(tls *libc.TLS, db uintptr, pIdxInfo uintptr) {
|
|
var i int32
|
|
var pHidden uintptr
|
|
_, _ = i, pHidden
|
|
pHidden = pIdxInfo + 1*72
|
|
i = 0
|
|
for {
|
|
if !(i < (*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FnConstraint) {
|
|
break
|
|
}
|
|
_sqlite3ValueFree(tls, *(*uintptr)(unsafe.Pointer(pHidden + 20 + uintptr(i)*4))) /* IMP: R-14553-25174 */
|
|
*(*uintptr)(unsafe.Pointer(pHidden + 20 + uintptr(i)*4)) = uintptr(0)
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
_freeIdxStr(tls, pIdxInfo)
|
|
_sqlite3DbFree(tls, db, pIdxInfo)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Allocate a new segment-id for the structure pStruct. The new segment
|
|
// ** id must be between 1 and 65335 inclusive, and must not be used by
|
|
// ** any currently existing segment. If a free segment id cannot be found,
|
|
// ** SQLITE_FULL is returned.
|
|
// **
|
|
// ** If an error has already occurred, this function is a no-op. 0 is
|
|
// ** returned in this case.
|
|
// */
|
|
func _fts5AllocateSegid(tls *libc.TLS, p uintptr, pStruct uintptr) (r int32) {
|
|
bp := tls.Alloc(256)
|
|
defer tls.Free(256)
|
|
var i, iId, iLvl, iSeg, iSegid int32
|
|
var mask Tu32
|
|
var _ /* aUsed at bp+0 */ [63]Tu32
|
|
_, _, _, _, _, _ = i, iId, iLvl, iSeg, iSegid, mask
|
|
iSegid = 0
|
|
if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
if (*TFts5Structure)(unsafe.Pointer(pStruct)).FnSegment >= int32(FTS5_MAX_SEGMENT) {
|
|
(*TFts5Index)(unsafe.Pointer(p)).Frc = int32(SQLITE_FULL)
|
|
} else {
|
|
libc.Xmemset(tls, bp, 0, uint32(252))
|
|
iLvl = 0
|
|
for {
|
|
if !(iLvl < (*TFts5Structure)(unsafe.Pointer(pStruct)).FnLevel) {
|
|
break
|
|
}
|
|
iSeg = 0
|
|
for {
|
|
if !(iSeg < (*(*TFts5StructureLevel)(unsafe.Pointer(pStruct + 32 + uintptr(iLvl)*12))).FnSeg) {
|
|
break
|
|
}
|
|
iId = (**(**TFts5StructureSegment)(__ccgo_up((*(*TFts5StructureLevel)(unsafe.Pointer(pStruct + 32 + uintptr(iLvl)*12))).FaSeg + uintptr(iSeg)*56))).FiSegid
|
|
if iId <= int32(FTS5_MAX_SEGMENT) && iId > 0 {
|
|
**(**Tu32)(__ccgo_up(bp + uintptr((iId-int32(1))/int32(32))*4)) |= libc.Uint32FromInt32(1) << ((iId - int32(1)) % int32(32))
|
|
}
|
|
goto _2
|
|
_2:
|
|
;
|
|
iSeg = iSeg + 1
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
iLvl = iLvl + 1
|
|
}
|
|
i = 0
|
|
for {
|
|
if !((**(**[63]Tu32)(__ccgo_up(bp)))[i] == uint32(0xFFFFFFFF)) {
|
|
break
|
|
}
|
|
goto _3
|
|
_3:
|
|
;
|
|
i = i + 1
|
|
}
|
|
mask = (**(**[63]Tu32)(__ccgo_up(bp)))[i]
|
|
iSegid = 0
|
|
for {
|
|
if !(mask&(libc.Uint32FromInt32(1)<<iSegid) != 0) {
|
|
break
|
|
}
|
|
goto _4
|
|
_4:
|
|
;
|
|
iSegid = iSegid + 1
|
|
}
|
|
iSegid = iSegid + (int32(1) + i*int32(32))
|
|
}
|
|
}
|
|
return iSegid
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Implementation of API function xQueryPhrase().
|
|
// */
|
|
func _fts5ApiQueryPhrase(tls *libc.TLS, pCtx uintptr, iPhrase int32, pUserData uintptr, __ccgo_fp_xCallback uintptr) (r int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var pCsr, pTab uintptr
|
|
var rc int32
|
|
var _ /* pNew at bp+0 */ uintptr
|
|
_, _, _ = pCsr, pTab, rc
|
|
pCsr = pCtx
|
|
pTab = (*TFts5Cursor)(unsafe.Pointer(pCsr)).Fbase.FpVtab
|
|
**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
|
|
rc = _fts5OpenMethod(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).Fbase.FpVtab, bp)
|
|
if rc == SQLITE_OK {
|
|
(*TFts5Cursor)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FePlan = int32(FTS5_PLAN_MATCH)
|
|
(*TFts5Cursor)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FiFirstRowid = int64(-libc.Int32FromInt32(1)) - (libc.Int64FromUint32(0xffffffff) | libc.Int64FromInt32(0x7fffffff)<<libc.Int32FromInt32(32))
|
|
(*TFts5Cursor)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FiLastRowid = libc.Int64FromUint32(0xffffffff) | libc.Int64FromInt32(0x7fffffff)<<libc.Int32FromInt32(32)
|
|
(*TFts5Cursor)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).Fbase.FpVtab = pTab
|
|
rc = _sqlite3Fts5ExprClonePhrase(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpExpr, iPhrase, **(**uintptr)(__ccgo_up(bp))+52)
|
|
}
|
|
if rc == SQLITE_OK {
|
|
rc = _fts5CursorFirst(tls, pTab, **(**uintptr)(__ccgo_up(bp)), 0)
|
|
for {
|
|
if !(rc == SQLITE_OK && (*TFts5Cursor)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).Fcsrflags&int32(FTS5CSR_EOF) == 0) {
|
|
break
|
|
}
|
|
rc = (*(*func(*libc.TLS, uintptr, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{__ccgo_fp_xCallback})))(tls, uintptr(unsafe.Pointer(&_sFts5Api)), **(**uintptr)(__ccgo_up(bp)), pUserData)
|
|
if rc != SQLITE_OK {
|
|
if rc == int32(SQLITE_DONE) {
|
|
rc = SQLITE_OK
|
|
}
|
|
break
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
rc = _fts5NextMethod(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
}
|
|
}
|
|
_fts5CloseMethod(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Close the cursor. For additional information see the documentation
|
|
// ** on the xClose method of the virtual table interface.
|
|
// */
|
|
func _fts5CloseMethod(tls *libc.TLS, pCursor uintptr) (r int32) {
|
|
var pCsr, pTab, pp uintptr
|
|
_, _, _ = pCsr, pTab, pp
|
|
if pCursor != 0 {
|
|
pTab = (*Tsqlite3_vtab_cursor)(unsafe.Pointer(pCursor)).FpVtab
|
|
pCsr = pCursor
|
|
_fts5FreeCursorComponents(tls, pCsr)
|
|
/* Remove the cursor from the Fts5Global.pCsr list */
|
|
pp = (*TFts5FullTable)(unsafe.Pointer(pTab)).FpGlobal + 52
|
|
for {
|
|
if !(**(**uintptr)(__ccgo_up(pp)) != pCsr) {
|
|
break
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
pp = **(**uintptr)(__ccgo_up(pp)) + 4
|
|
}
|
|
**(**uintptr)(__ccgo_up(pp)) = (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpNext
|
|
Xsqlite3_free(tls, pCsr)
|
|
}
|
|
return SQLITE_OK
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This function is called after the cursor passed as the only argument
|
|
// ** is moved to point at a different row. It clears all cached data
|
|
// ** specific to the previous row stored by the cursor object.
|
|
// */
|
|
func _fts5CsrNewrow(tls *libc.TLS, pCsr uintptr) {
|
|
**(**int32)(__ccgo_up(pCsr + 60)) |= libc.Int32FromInt32(FTS5CSR_REQUIRE_CONTENT) | libc.Int32FromInt32(FTS5CSR_REQUIRE_DOCSIZE) | libc.Int32FromInt32(FTS5CSR_REQUIRE_INST) | libc.Int32FromInt32(FTS5CSR_REQUIRE_POSLIST)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This is called by various API functions - xInst, xPhraseFirst,
|
|
// ** xPhraseFirstColumn etc. - to obtain the position list for phrase iPhrase
|
|
// ** of the current row. This function works for both detail=full tables (in
|
|
// ** which case the position-list was read from the fts index) or for other
|
|
// ** detail= modes if the row content is available.
|
|
// */
|
|
func _fts5CsrPoslist(tls *libc.TLS, pCsr uintptr, iPhrase int32, pa uintptr, pn uintptr) (r int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var aPopulator, pConfig, pSorter uintptr
|
|
var bLive, i, i1, rc, v2 int32
|
|
var _ /* n at bp+4 */ int32
|
|
var _ /* z at bp+0 */ uintptr
|
|
_, _, _, _, _, _, _, _ = aPopulator, bLive, i, i1, pConfig, pSorter, rc, v2
|
|
pConfig = (*TFts5Table)(unsafe.Pointer((*TFts5Cursor)(unsafe.Pointer(pCsr)).Fbase.FpVtab)).FpConfig
|
|
rc = SQLITE_OK
|
|
bLive = libc.BoolInt32((*TFts5Cursor)(unsafe.Pointer(pCsr)).FpSorter == uintptr(0))
|
|
if iPhrase < 0 || iPhrase >= _sqlite3Fts5ExprPhraseCount(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpExpr) {
|
|
rc = int32(SQLITE_RANGE)
|
|
} else {
|
|
if (*TFts5Config)(unsafe.Pointer(pConfig)).FeDetail != FTS5_DETAIL_FULL && _fts5IsContentless(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).Fbase.FpVtab, int32(1)) != 0 {
|
|
**(**uintptr)(__ccgo_up(pa)) = uintptr(0)
|
|
**(**int32)(__ccgo_up(pn)) = 0
|
|
return SQLITE_OK
|
|
} else {
|
|
if (*TFts5Cursor)(unsafe.Pointer(pCsr)).Fcsrflags&int32(FTS5CSR_REQUIRE_POSLIST) != 0 {
|
|
if (*TFts5Config)(unsafe.Pointer(pConfig)).FeDetail != FTS5_DETAIL_FULL {
|
|
aPopulator = _sqlite3Fts5ExprClearPoslists(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpExpr, bLive)
|
|
if aPopulator == uintptr(0) {
|
|
rc = int32(SQLITE_NOMEM)
|
|
}
|
|
if rc == SQLITE_OK {
|
|
rc = _fts5SeekCursor(tls, pCsr, 0)
|
|
}
|
|
i = 0
|
|
for {
|
|
if !(i < (*TFts5Config)(unsafe.Pointer(pConfig)).FnCol && rc == SQLITE_OK) {
|
|
break
|
|
}
|
|
**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
|
|
**(**int32)(__ccgo_up(bp + 4)) = 0
|
|
rc = _fts5TextFromStmt(tls, pConfig, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpStmt, i, bp, bp+4)
|
|
if rc == SQLITE_OK {
|
|
rc = _sqlite3Fts5ExprPopulatePoslists(tls, pConfig, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpExpr, aPopulator, i, **(**uintptr)(__ccgo_up(bp)), **(**int32)(__ccgo_up(bp + 4)))
|
|
}
|
|
_sqlite3Fts5ClearLocale(tls, pConfig)
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
Xsqlite3_free(tls, aPopulator)
|
|
if (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpSorter != 0 {
|
|
_sqlite3Fts5ExprCheckPoslists(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpExpr, (*TFts5Sorter)(unsafe.Pointer((*TFts5Cursor)(unsafe.Pointer(pCsr)).FpSorter)).FiRowid)
|
|
}
|
|
}
|
|
**(**int32)(__ccgo_up(pCsr + 60)) &= ^libc.Int32FromInt32(FTS5CSR_REQUIRE_POSLIST)
|
|
}
|
|
}
|
|
}
|
|
if rc == SQLITE_OK {
|
|
if (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpSorter != 0 && (*TFts5Config)(unsafe.Pointer(pConfig)).FeDetail == FTS5_DETAIL_FULL {
|
|
pSorter = (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpSorter
|
|
if iPhrase == 0 {
|
|
v2 = 0
|
|
} else {
|
|
v2 = *(*int32)(unsafe.Pointer(pSorter + 24 + uintptr(iPhrase-int32(1))*4))
|
|
}
|
|
i1 = v2
|
|
**(**int32)(__ccgo_up(pn)) = *(*int32)(unsafe.Pointer(pSorter + 24 + uintptr(iPhrase)*4)) - i1
|
|
**(**uintptr)(__ccgo_up(pa)) = (*TFts5Sorter)(unsafe.Pointer(pSorter)).FaPoslist + uintptr(i1)
|
|
} else {
|
|
**(**int32)(__ccgo_up(pn)) = _sqlite3Fts5ExprPoslist(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpExpr, iPhrase, pa)
|
|
}
|
|
} else {
|
|
**(**uintptr)(__ccgo_up(pa)) = uintptr(0)
|
|
**(**int32)(__ccgo_up(pn)) = 0
|
|
}
|
|
return rc
|
|
}
|
|
|
|
func _fts5CursorFirst(tls *libc.TLS, pTab uintptr, pCsr uintptr, bDesc int32) (r int32) {
|
|
var pExpr uintptr
|
|
var rc int32
|
|
_, _ = pExpr, rc
|
|
pExpr = (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpExpr
|
|
rc = _sqlite3Fts5ExprFirst(tls, pExpr, (*TFts5FullTable)(unsafe.Pointer(pTab)).Fp.FpIndex, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FiFirstRowid, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FiLastRowid, bDesc)
|
|
if _sqlite3Fts5ExprEof(tls, pExpr) != 0 {
|
|
**(**int32)(__ccgo_up(pCsr + 60)) |= int32(FTS5CSR_EOF)
|
|
}
|
|
_fts5CsrNewrow(tls, pCsr)
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** If the REQUIRE_RESEEK flag is set on the cursor passed as the first
|
|
// ** argument, close and reopen all Fts5IndexIter iterators that the cursor
|
|
// ** is using. Then attempt to move the cursor to a rowid equal to or laster
|
|
// ** (in the cursors sort order - ASC or DESC) than the current rowid.
|
|
// **
|
|
// ** If the new rowid is not equal to the old, set output parameter *pbSkip
|
|
// ** to 1 before returning. Otherwise, leave it unchanged.
|
|
// **
|
|
// ** Return SQLITE_OK if successful or if no reseek was required, or an
|
|
// ** error code if an error occurred.
|
|
// */
|
|
func _fts5CursorReseek(tls *libc.TLS, pCsr uintptr, pbSkip uintptr) (r int32) {
|
|
var bDesc, rc int32
|
|
var iRowid Ti64
|
|
var pTab uintptr
|
|
_, _, _, _ = bDesc, iRowid, pTab, rc
|
|
rc = SQLITE_OK
|
|
if (*TFts5Cursor)(unsafe.Pointer(pCsr)).Fcsrflags&int32(FTS5CSR_REQUIRE_RESEEK) != 0 {
|
|
pTab = (*TFts5Cursor)(unsafe.Pointer(pCsr)).Fbase.FpVtab
|
|
bDesc = (*TFts5Cursor)(unsafe.Pointer(pCsr)).FbDesc
|
|
iRowid = _sqlite3Fts5ExprRowid(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpExpr)
|
|
rc = _sqlite3Fts5ExprFirst(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpExpr, (*TFts5FullTable)(unsafe.Pointer(pTab)).Fp.FpIndex, iRowid, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FiLastRowid, bDesc)
|
|
if rc == SQLITE_OK && iRowid != _sqlite3Fts5ExprRowid(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpExpr) {
|
|
**(**int32)(__ccgo_up(pbSkip)) = int32(1)
|
|
}
|
|
**(**int32)(__ccgo_up(pCsr + 60)) &= ^libc.Int32FromInt32(FTS5CSR_REQUIRE_RESEEK)
|
|
_fts5CsrNewrow(tls, pCsr)
|
|
if _sqlite3Fts5ExprEof(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpExpr) != 0 {
|
|
**(**int32)(__ccgo_up(pCsr + 60)) |= int32(FTS5CSR_EOF)
|
|
**(**int32)(__ccgo_up(pbSkip)) = int32(1)
|
|
}
|
|
}
|
|
return rc
|
|
}
|
|
|
|
func _fts5DlidxIterLast(tls *libc.TLS, p uintptr, pIter uintptr) {
|
|
var i int32
|
|
var pChild, pLvl uintptr
|
|
_, _, _ = i, pChild, pLvl
|
|
/* Advance each level to the last entry on the last page */
|
|
i = (*TFts5DlidxIter)(unsafe.Pointer(pIter)).FnLvl - int32(1)
|
|
for {
|
|
if !((*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK && i >= 0) {
|
|
break
|
|
}
|
|
pLvl = pIter + 8 + uintptr(i)*32
|
|
for _fts5DlidxLvlNext(tls, pLvl) == 0 {
|
|
}
|
|
(*TFts5DlidxLvl)(unsafe.Pointer(pLvl)).FbEof = 0
|
|
if i > 0 {
|
|
pChild = pLvl + uintptr(-libc.Int32FromInt32(1))*32
|
|
_fts5DataRelease(tls, (*TFts5DlidxLvl)(unsafe.Pointer(pChild)).FpData)
|
|
libc.Xmemset(tls, pChild, 0, uint32(32))
|
|
(*TFts5DlidxLvl)(unsafe.Pointer(pChild)).FpData = _fts5DataRead(tls, p, int64((*TFts5DlidxIter)(unsafe.Pointer(pIter)).FiSegid)<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B)+libc.Int32FromInt32(FTS5_DATA_DLI_B))+int64(libc.Int32FromInt32(1))<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B))+int64(i-libc.Int32FromInt32(1))<<libc.Int32FromInt32(FTS5_DATA_PAGE_B)+int64((*TFts5DlidxLvl)(unsafe.Pointer(pLvl)).FiLeafPgno))
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i - 1
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Advance the iterator passed as the only argument.
|
|
// */
|
|
func _fts5DlidxIterNextR(tls *libc.TLS, p uintptr, pIter uintptr, iLvl int32) (r int32) {
|
|
var pLvl uintptr
|
|
_ = pLvl
|
|
pLvl = pIter + 8 + uintptr(iLvl)*32
|
|
if _fts5DlidxLvlNext(tls, pLvl) != 0 {
|
|
if iLvl+int32(1) < (*TFts5DlidxIter)(unsafe.Pointer(pIter)).FnLvl {
|
|
_fts5DlidxIterNextR(tls, p, pIter, iLvl+int32(1))
|
|
if (**(**TFts5DlidxLvl)(__ccgo_up(pLvl + 1*32))).FbEof == 0 {
|
|
_fts5DataRelease(tls, (*TFts5DlidxLvl)(unsafe.Pointer(pLvl)).FpData)
|
|
libc.Xmemset(tls, pLvl, 0, uint32(32))
|
|
(*TFts5DlidxLvl)(unsafe.Pointer(pLvl)).FpData = _fts5DataRead(tls, p, int64((*TFts5DlidxIter)(unsafe.Pointer(pIter)).FiSegid)<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B)+libc.Int32FromInt32(FTS5_DATA_DLI_B))+int64(libc.Int32FromInt32(1))<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B))+int64(iLvl)<<libc.Int32FromInt32(FTS5_DATA_PAGE_B)+int64((**(**TFts5DlidxLvl)(__ccgo_up(pLvl + 1*32))).FiLeafPgno))
|
|
if (*TFts5DlidxLvl)(unsafe.Pointer(pLvl)).FpData != 0 {
|
|
_fts5DlidxLvlNext(tls, pLvl)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return (*(*TFts5DlidxLvl)(unsafe.Pointer(pIter + 8))).FbEof
|
|
}
|
|
|
|
func _fts5DlidxIterPrevR(tls *libc.TLS, p uintptr, pIter uintptr, iLvl int32) (r int32) {
|
|
var pLvl uintptr
|
|
_ = pLvl
|
|
pLvl = pIter + 8 + uintptr(iLvl)*32
|
|
if _fts5DlidxLvlPrev(tls, pLvl) != 0 {
|
|
if iLvl+int32(1) < (*TFts5DlidxIter)(unsafe.Pointer(pIter)).FnLvl {
|
|
_fts5DlidxIterPrevR(tls, p, pIter, iLvl+int32(1))
|
|
if (**(**TFts5DlidxLvl)(__ccgo_up(pLvl + 1*32))).FbEof == 0 {
|
|
_fts5DataRelease(tls, (*TFts5DlidxLvl)(unsafe.Pointer(pLvl)).FpData)
|
|
libc.Xmemset(tls, pLvl, 0, uint32(32))
|
|
(*TFts5DlidxLvl)(unsafe.Pointer(pLvl)).FpData = _fts5DataRead(tls, p, int64((*TFts5DlidxIter)(unsafe.Pointer(pIter)).FiSegid)<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B)+libc.Int32FromInt32(FTS5_DATA_DLI_B))+int64(libc.Int32FromInt32(1))<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B))+int64(iLvl)<<libc.Int32FromInt32(FTS5_DATA_PAGE_B)+int64((**(**TFts5DlidxLvl)(__ccgo_up(pLvl + 1*32))).FiLeafPgno))
|
|
if (*TFts5DlidxLvl)(unsafe.Pointer(pLvl)).FpData != 0 {
|
|
for _fts5DlidxLvlNext(tls, pLvl) == 0 {
|
|
}
|
|
(*TFts5DlidxLvl)(unsafe.Pointer(pLvl)).FbEof = 0
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return (*(*TFts5DlidxLvl)(unsafe.Pointer(pIter + 8))).FbEof
|
|
}
|
|
|
|
func _fts5DoclistIterInit(tls *libc.TLS, pBuf uintptr, pIter uintptr) {
|
|
libc.Xmemset(tls, pIter, 0, uint32(32))
|
|
if (*TFts5Buffer)(unsafe.Pointer(pBuf)).Fn > 0 {
|
|
(*TFts5DoclistIter)(unsafe.Pointer(pIter)).FaPoslist = (*TFts5Buffer)(unsafe.Pointer(pBuf)).Fp
|
|
(*TFts5DoclistIter)(unsafe.Pointer(pIter)).FaEof = (*TFts5Buffer)(unsafe.Pointer(pBuf)).Fp + uintptr((*TFts5Buffer)(unsafe.Pointer(pBuf)).Fn)
|
|
_fts5DoclistIterNext(tls, pIter)
|
|
}
|
|
}
|
|
|
|
func _fts5ExprCheckPoslists(tls *libc.TLS, pNode uintptr, iRowid Ti64) (r int32) {
|
|
var bRet, i, i1 int32
|
|
_, _, _ = bRet, i, i1
|
|
(*TFts5ExprNode)(unsafe.Pointer(pNode)).FiRowid = iRowid
|
|
(*TFts5ExprNode)(unsafe.Pointer(pNode)).FbEof = 0
|
|
switch (*TFts5ExprNode)(unsafe.Pointer(pNode)).FeType {
|
|
case 0:
|
|
fallthrough
|
|
case int32(FTS5_TERM):
|
|
fallthrough
|
|
case int32(FTS5_STRING):
|
|
return libc.BoolInt32((*TFts5ExprPhrase)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer((*TFts5ExprNode)(unsafe.Pointer(pNode)).FpNear + 12)))).Fposlist.Fn > 0)
|
|
case int32(FTS5_AND):
|
|
i = 0
|
|
for {
|
|
if !(i < (*TFts5ExprNode)(unsafe.Pointer(pNode)).FnChild) {
|
|
break
|
|
}
|
|
if _fts5ExprCheckPoslists(tls, *(*uintptr)(unsafe.Pointer(pNode + 40 + uintptr(i)*4)), iRowid) == 0 {
|
|
_fts5ExprClearPoslists(tls, pNode)
|
|
return 0
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
case int32(FTS5_OR):
|
|
bRet = 0
|
|
i1 = 0
|
|
for {
|
|
if !(i1 < (*TFts5ExprNode)(unsafe.Pointer(pNode)).FnChild) {
|
|
break
|
|
}
|
|
if _fts5ExprCheckPoslists(tls, *(*uintptr)(unsafe.Pointer(pNode + 40 + uintptr(i1)*4)), iRowid) != 0 {
|
|
bRet = int32(1)
|
|
}
|
|
goto _2
|
|
_2:
|
|
;
|
|
i1 = i1 + 1
|
|
}
|
|
return bRet
|
|
default:
|
|
if 0 == _fts5ExprCheckPoslists(tls, *(*uintptr)(unsafe.Pointer(pNode + 40)), iRowid) || 0 != _fts5ExprCheckPoslists(tls, *(*uintptr)(unsafe.Pointer(pNode + 40 + 1*4)), iRowid) {
|
|
_fts5ExprClearPoslists(tls, pNode)
|
|
return 0
|
|
}
|
|
break
|
|
}
|
|
return int32(1)
|
|
}
|
|
|
|
func _fts5ExprClearPoslists(tls *libc.TLS, pNode uintptr) {
|
|
var i int32
|
|
_ = i
|
|
if (*TFts5ExprNode)(unsafe.Pointer(pNode)).FeType == int32(FTS5_TERM) || (*TFts5ExprNode)(unsafe.Pointer(pNode)).FeType == int32(FTS5_STRING) {
|
|
(*TFts5ExprPhrase)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer((*TFts5ExprNode)(unsafe.Pointer(pNode)).FpNear + 12)))).Fposlist.Fn = 0
|
|
} else {
|
|
i = 0
|
|
for {
|
|
if !(i < (*TFts5ExprNode)(unsafe.Pointer(pNode)).FnChild) {
|
|
break
|
|
}
|
|
_fts5ExprClearPoslists(tls, *(*uintptr)(unsafe.Pointer(pNode + 40 + uintptr(i)*4)))
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Set node pNode, which is part of expression pExpr, to point to the first
|
|
// ** match. If there are no matches, set the Node.bEof flag to indicate EOF.
|
|
// **
|
|
// ** Return an SQLite error code if an error occurs, or SQLITE_OK otherwise.
|
|
// ** It is not an error if there are no matches.
|
|
// */
|
|
func _fts5ExprNodeFirst(tls *libc.TLS, pExpr uintptr, pNode uintptr) (r int32) {
|
|
var i, nEof, rc int32
|
|
var pChild uintptr
|
|
_, _, _, _ = i, nEof, pChild, rc
|
|
rc = SQLITE_OK
|
|
(*TFts5ExprNode)(unsafe.Pointer(pNode)).FbEof = 0
|
|
(*TFts5ExprNode)(unsafe.Pointer(pNode)).FbNomatch = 0
|
|
if (*TFts5ExprNode)(unsafe.Pointer(pNode)).FeType == int32(FTS5_TERM) || (*TFts5ExprNode)(unsafe.Pointer(pNode)).FeType == int32(FTS5_STRING) {
|
|
/* Initialize all term iterators in the NEAR object. */
|
|
rc = _fts5ExprNearInitAll(tls, pExpr, pNode)
|
|
} else {
|
|
if (*TFts5ExprNode)(unsafe.Pointer(pNode)).FxNext == uintptr(0) {
|
|
(*TFts5ExprNode)(unsafe.Pointer(pNode)).FbEof = int32(1)
|
|
} else {
|
|
nEof = 0
|
|
i = 0
|
|
for {
|
|
if !(i < (*TFts5ExprNode)(unsafe.Pointer(pNode)).FnChild && rc == SQLITE_OK) {
|
|
break
|
|
}
|
|
pChild = *(*uintptr)(unsafe.Pointer(pNode + 40 + uintptr(i)*4))
|
|
rc = _fts5ExprNodeFirst(tls, pExpr, *(*uintptr)(unsafe.Pointer(pNode + 40 + uintptr(i)*4)))
|
|
nEof = nEof + (*TFts5ExprNode)(unsafe.Pointer(pChild)).FbEof
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
(*TFts5ExprNode)(unsafe.Pointer(pNode)).FiRowid = (*TFts5ExprNode)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pNode + 40)))).FiRowid
|
|
switch (*TFts5ExprNode)(unsafe.Pointer(pNode)).FeType {
|
|
case int32(FTS5_AND):
|
|
if nEof > 0 {
|
|
_fts5ExprSetEof(tls, pNode)
|
|
}
|
|
case int32(FTS5_OR):
|
|
if (*TFts5ExprNode)(unsafe.Pointer(pNode)).FnChild == nEof {
|
|
_fts5ExprSetEof(tls, pNode)
|
|
}
|
|
default:
|
|
(*TFts5ExprNode)(unsafe.Pointer(pNode)).FbEof = (*TFts5ExprNode)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pNode + 40)))).FbEof
|
|
break
|
|
}
|
|
}
|
|
}
|
|
if rc == SQLITE_OK {
|
|
rc = _fts5ExprNodeTest(tls, pExpr, pNode)
|
|
}
|
|
return rc
|
|
}
|
|
|
|
func _fts5ExprNodeNext_AND(tls *libc.TLS, pExpr uintptr, pNode uintptr, bFromValid int32, iFrom Ti64) (r int32) {
|
|
var rc int32
|
|
_ = rc
|
|
rc = (*(*func(*libc.TLS, uintptr, uintptr, int32, Ti64) int32)(unsafe.Pointer(&struct{ uintptr }{(*TFts5ExprNode)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pNode + 40)))).FxNext})))(tls, pExpr, *(*uintptr)(unsafe.Pointer(pNode + 40)), bFromValid, iFrom)
|
|
if rc == SQLITE_OK {
|
|
rc = _fts5ExprNodeTest_AND(tls, pExpr, pNode)
|
|
} else {
|
|
(*TFts5ExprNode)(unsafe.Pointer(pNode)).FbNomatch = 0
|
|
}
|
|
return rc
|
|
}
|
|
|
|
func _fts5ExprNodeNext_NOT(tls *libc.TLS, pExpr uintptr, pNode uintptr, bFromValid int32, iFrom Ti64) (r int32) {
|
|
var rc int32
|
|
_ = rc
|
|
rc = (*(*func(*libc.TLS, uintptr, uintptr, int32, Ti64) int32)(unsafe.Pointer(&struct{ uintptr }{(*TFts5ExprNode)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pNode + 40)))).FxNext})))(tls, pExpr, *(*uintptr)(unsafe.Pointer(pNode + 40)), bFromValid, iFrom)
|
|
if rc == SQLITE_OK {
|
|
rc = _fts5ExprNodeTest_NOT(tls, pExpr, pNode)
|
|
}
|
|
if rc != SQLITE_OK {
|
|
(*TFts5ExprNode)(unsafe.Pointer(pNode)).FbNomatch = 0
|
|
}
|
|
return rc
|
|
}
|
|
|
|
func _fts5ExprNodeNext_OR(tls *libc.TLS, pExpr uintptr, pNode uintptr, bFromValid int32, iFrom Ti64) (r int32) {
|
|
var i, rc int32
|
|
var iLast Ti64
|
|
var p1 uintptr
|
|
_, _, _, _ = i, iLast, p1, rc
|
|
iLast = (*TFts5ExprNode)(unsafe.Pointer(pNode)).FiRowid
|
|
i = 0
|
|
for {
|
|
if !(i < (*TFts5ExprNode)(unsafe.Pointer(pNode)).FnChild) {
|
|
break
|
|
}
|
|
p1 = *(*uintptr)(unsafe.Pointer(pNode + 40 + uintptr(i)*4))
|
|
if (*TFts5ExprNode)(unsafe.Pointer(p1)).FbEof == 0 {
|
|
if (*TFts5ExprNode)(unsafe.Pointer(p1)).FiRowid == iLast || bFromValid != 0 && _fts5RowidCmp(tls, pExpr, (*TFts5ExprNode)(unsafe.Pointer(p1)).FiRowid, iFrom) < 0 {
|
|
rc = (*(*func(*libc.TLS, uintptr, uintptr, int32, Ti64) int32)(unsafe.Pointer(&struct{ uintptr }{(*TFts5ExprNode)(unsafe.Pointer(p1)).FxNext})))(tls, pExpr, p1, bFromValid, iFrom)
|
|
if rc != SQLITE_OK {
|
|
(*TFts5ExprNode)(unsafe.Pointer(pNode)).FbNomatch = 0
|
|
return rc
|
|
}
|
|
}
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
_fts5ExprNodeTest_OR(tls, pExpr, pNode)
|
|
return SQLITE_OK
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Argument pNode is an FTS5_AND node.
|
|
// */
|
|
func _fts5ExprNodeTest_AND(tls *libc.TLS, pExpr uintptr, pAnd uintptr) (r int32) {
|
|
var bMatch, cmp, iChild, rc int32
|
|
var iLast Ti64
|
|
var pChild uintptr
|
|
_, _, _, _, _, _ = bMatch, cmp, iChild, iLast, pChild, rc
|
|
iLast = (*TFts5ExprNode)(unsafe.Pointer(pAnd)).FiRowid
|
|
rc = SQLITE_OK
|
|
for cond := true; cond; cond = bMatch == 0 {
|
|
(*TFts5ExprNode)(unsafe.Pointer(pAnd)).FbNomatch = 0
|
|
bMatch = int32(1)
|
|
iChild = 0
|
|
for {
|
|
if !(iChild < (*TFts5ExprNode)(unsafe.Pointer(pAnd)).FnChild) {
|
|
break
|
|
}
|
|
pChild = *(*uintptr)(unsafe.Pointer(pAnd + 40 + uintptr(iChild)*4))
|
|
cmp = _fts5RowidCmp(tls, pExpr, iLast, (*TFts5ExprNode)(unsafe.Pointer(pChild)).FiRowid)
|
|
if cmp > 0 {
|
|
/* Advance pChild until it points to iLast or laster */
|
|
rc = (*(*func(*libc.TLS, uintptr, uintptr, int32, Ti64) int32)(unsafe.Pointer(&struct{ uintptr }{(*TFts5ExprNode)(unsafe.Pointer(pChild)).FxNext})))(tls, pExpr, pChild, int32(1), iLast)
|
|
if rc != SQLITE_OK {
|
|
(*TFts5ExprNode)(unsafe.Pointer(pAnd)).FbNomatch = 0
|
|
return rc
|
|
}
|
|
}
|
|
/* If the child node is now at EOF, so is the parent AND node. Otherwise,
|
|
** the child node is guaranteed to have advanced at least as far as
|
|
** rowid iLast. So if it is not at exactly iLast, pChild->iRowid is the
|
|
** new lastest rowid seen so far. */
|
|
if (*TFts5ExprNode)(unsafe.Pointer(pChild)).FbEof != 0 {
|
|
_fts5ExprSetEof(tls, pAnd)
|
|
bMatch = int32(1)
|
|
break
|
|
} else {
|
|
if iLast != (*TFts5ExprNode)(unsafe.Pointer(pChild)).FiRowid {
|
|
bMatch = 0
|
|
iLast = (*TFts5ExprNode)(unsafe.Pointer(pChild)).FiRowid
|
|
}
|
|
}
|
|
if (*TFts5ExprNode)(unsafe.Pointer(pChild)).FbNomatch != 0 {
|
|
(*TFts5ExprNode)(unsafe.Pointer(pAnd)).FbNomatch = int32(1)
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
iChild = iChild + 1
|
|
}
|
|
}
|
|
if (*TFts5ExprNode)(unsafe.Pointer(pAnd)).FbNomatch != 0 && pAnd != (*TFts5Expr)(unsafe.Pointer(pExpr)).FpRoot {
|
|
_fts5ExprNodeZeroPoslist(tls, pAnd)
|
|
}
|
|
(*TFts5ExprNode)(unsafe.Pointer(pAnd)).FiRowid = iLast
|
|
return SQLITE_OK
|
|
}
|
|
|
|
func _fts5ExprNodeTest_NOT(tls *libc.TLS, pExpr uintptr, pNode uintptr) (r int32) {
|
|
var cmp, rc int32
|
|
var p1, p2 uintptr
|
|
_, _, _, _ = cmp, p1, p2, rc
|
|
rc = SQLITE_OK
|
|
p1 = *(*uintptr)(unsafe.Pointer(pNode + 40))
|
|
p2 = *(*uintptr)(unsafe.Pointer(pNode + 40 + 1*4))
|
|
for rc == SQLITE_OK && (*TFts5ExprNode)(unsafe.Pointer(p1)).FbEof == 0 {
|
|
cmp = _fts5NodeCompare(tls, pExpr, p1, p2)
|
|
if cmp > 0 {
|
|
rc = (*(*func(*libc.TLS, uintptr, uintptr, int32, Ti64) int32)(unsafe.Pointer(&struct{ uintptr }{(*TFts5ExprNode)(unsafe.Pointer(p2)).FxNext})))(tls, pExpr, p2, int32(1), (*TFts5ExprNode)(unsafe.Pointer(p1)).FiRowid)
|
|
cmp = _fts5NodeCompare(tls, pExpr, p1, p2)
|
|
}
|
|
if cmp != 0 || (*TFts5ExprNode)(unsafe.Pointer(p2)).FbNomatch != 0 {
|
|
break
|
|
}
|
|
rc = (*(*func(*libc.TLS, uintptr, uintptr, int32, Ti64) int32)(unsafe.Pointer(&struct{ uintptr }{(*TFts5ExprNode)(unsafe.Pointer(p1)).FxNext})))(tls, pExpr, p1, 0, int64(libc.Int32FromInt32(0)))
|
|
}
|
|
(*TFts5ExprNode)(unsafe.Pointer(pNode)).FbEof = (*TFts5ExprNode)(unsafe.Pointer(p1)).FbEof
|
|
(*TFts5ExprNode)(unsafe.Pointer(pNode)).FbNomatch = (*TFts5ExprNode)(unsafe.Pointer(p1)).FbNomatch
|
|
(*TFts5ExprNode)(unsafe.Pointer(pNode)).FiRowid = (*TFts5ExprNode)(unsafe.Pointer(p1)).FiRowid
|
|
if (*TFts5ExprNode)(unsafe.Pointer(p1)).FbEof != 0 {
|
|
_fts5ExprNodeZeroPoslist(tls, p2)
|
|
}
|
|
return rc
|
|
}
|
|
|
|
func _fts5ExprNodeTest_OR(tls *libc.TLS, pExpr uintptr, pNode uintptr) {
|
|
var cmp, i int32
|
|
var pChild, pNext uintptr
|
|
_, _, _, _ = cmp, i, pChild, pNext
|
|
pNext = *(*uintptr)(unsafe.Pointer(pNode + 40))
|
|
i = int32(1)
|
|
for {
|
|
if !(i < (*TFts5ExprNode)(unsafe.Pointer(pNode)).FnChild) {
|
|
break
|
|
}
|
|
pChild = *(*uintptr)(unsafe.Pointer(pNode + 40 + uintptr(i)*4))
|
|
cmp = _fts5NodeCompare(tls, pExpr, pNext, pChild)
|
|
if cmp > 0 || cmp == 0 && (*TFts5ExprNode)(unsafe.Pointer(pChild)).FbNomatch == 0 {
|
|
pNext = pChild
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
(*TFts5ExprNode)(unsafe.Pointer(pNode)).FiRowid = (*TFts5ExprNode)(unsafe.Pointer(pNext)).FiRowid
|
|
(*TFts5ExprNode)(unsafe.Pointer(pNode)).FbEof = (*TFts5ExprNode)(unsafe.Pointer(pNext)).FbEof
|
|
(*TFts5ExprNode)(unsafe.Pointer(pNode)).FbNomatch = (*TFts5ExprNode)(unsafe.Pointer(pNext)).FbNomatch
|
|
}
|
|
|
|
func _fts5ExprNodeZeroPoslist(tls *libc.TLS, pNode uintptr) {
|
|
var i, i1 int32
|
|
var pNear, pPhrase uintptr
|
|
_, _, _, _ = i, i1, pNear, pPhrase
|
|
if (*TFts5ExprNode)(unsafe.Pointer(pNode)).FeType == int32(FTS5_STRING) || (*TFts5ExprNode)(unsafe.Pointer(pNode)).FeType == int32(FTS5_TERM) {
|
|
pNear = (*TFts5ExprNode)(unsafe.Pointer(pNode)).FpNear
|
|
i = 0
|
|
for {
|
|
if !(i < (*TFts5ExprNearset)(unsafe.Pointer(pNear)).FnPhrase) {
|
|
break
|
|
}
|
|
pPhrase = *(*uintptr)(unsafe.Pointer(pNear + 12 + uintptr(i)*4))
|
|
(*TFts5ExprPhrase)(unsafe.Pointer(pPhrase)).Fposlist.Fn = 0
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
} else {
|
|
i1 = 0
|
|
for {
|
|
if !(i1 < (*TFts5ExprNode)(unsafe.Pointer(pNode)).FnChild) {
|
|
break
|
|
}
|
|
_fts5ExprNodeZeroPoslist(tls, *(*uintptr)(unsafe.Pointer(pNode + 40 + uintptr(i1)*4)))
|
|
goto _2
|
|
_2:
|
|
;
|
|
i1 = i1 + 1
|
|
}
|
|
}
|
|
}
|
|
|
|
func _fts5ExprSetEof(tls *libc.TLS, pNode uintptr) {
|
|
var i int32
|
|
_ = i
|
|
(*TFts5ExprNode)(unsafe.Pointer(pNode)).FbEof = int32(1)
|
|
(*TFts5ExprNode)(unsafe.Pointer(pNode)).FbNomatch = 0
|
|
i = 0
|
|
for {
|
|
if !(i < (*TFts5ExprNode)(unsafe.Pointer(pNode)).FnChild) {
|
|
break
|
|
}
|
|
_fts5ExprSetEof(tls, *(*uintptr)(unsafe.Pointer(pNode + 40 + uintptr(i)*4)))
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Allocate and return a buffer at least nByte bytes in size.
|
|
// **
|
|
// ** If an OOM error is encountered, return NULL and set the error code in
|
|
// ** the Fts5Index handle passed as the first argument.
|
|
// */
|
|
func _fts5IdxMalloc(tls *libc.TLS, p uintptr, nByte Tsqlite3_int64) (r uintptr) {
|
|
return _sqlite3Fts5MallocZero(tls, p+44, nByte)
|
|
}
|
|
|
|
/*
|
|
** Compare the contents of the pLeft buffer with the pRight/nRight blob.
|
|
**
|
|
** Return -ve if pLeft is smaller than pRight, 0 if they are equal or
|
|
** +ve if pRight is smaller than pLeft. In other words:
|
|
**
|
|
** res = *pLeft - *pRight
|
|
*/
|
|
|
|
func _fts5IndexCrisismerge(tls *libc.TLS, p uintptr, ppStruct uintptr) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var iLvl, nCrisis int32
|
|
var _ /* pStruct at bp+0 */ uintptr
|
|
_, _ = iLvl, nCrisis
|
|
nCrisis = (*TFts5Config)(unsafe.Pointer((*TFts5Index)(unsafe.Pointer(p)).FpConfig)).FnCrisisMerge
|
|
**(**uintptr)(__ccgo_up(bp)) = **(**uintptr)(__ccgo_up(ppStruct))
|
|
if **(**uintptr)(__ccgo_up(bp)) != 0 && (*TFts5Structure)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FnLevel > 0 {
|
|
iLvl = 0
|
|
for (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK && (*(*TFts5StructureLevel)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)) + 32 + uintptr(iLvl)*12))).FnSeg >= nCrisis {
|
|
_fts5IndexMergeLevel(tls, p, bp, iLvl, uintptr(0))
|
|
_fts5StructurePromote(tls, p, iLvl+int32(1), **(**uintptr)(__ccgo_up(bp)))
|
|
iLvl = iLvl + 1
|
|
}
|
|
**(**uintptr)(__ccgo_up(ppStruct)) = **(**uintptr)(__ccgo_up(bp))
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Do up to nPg pages of automerge work on the index.
|
|
// **
|
|
// ** Return true if any changes were actually made, or false otherwise.
|
|
// */
|
|
func _fts5IndexMerge(tls *libc.TLS, p uintptr, ppStruct uintptr, nPg int32, nMin int32) (r int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var bRet, iBestLvl, iLvl, nBest int32
|
|
var pLvl uintptr
|
|
var _ /* nRem at bp+0 */ int32
|
|
var _ /* pStruct at bp+4 */ uintptr
|
|
_, _, _, _, _ = bRet, iBestLvl, iLvl, nBest, pLvl
|
|
**(**int32)(__ccgo_up(bp)) = nPg
|
|
bRet = 0
|
|
**(**uintptr)(__ccgo_up(bp + 4)) = **(**uintptr)(__ccgo_up(ppStruct))
|
|
for **(**int32)(__ccgo_up(bp)) > 0 && (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK { /* To iterate through levels */
|
|
iBestLvl = 0 /* Level offering the most input segments */
|
|
nBest = 0 /* Number of input segments on best level */
|
|
/* Set iBestLvl to the level to read input segments from. Or to -1 if
|
|
** there is no level suitable to merge segments from. */
|
|
iLvl = 0
|
|
for {
|
|
if !(iLvl < (*TFts5Structure)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 4)))).FnLevel) {
|
|
break
|
|
}
|
|
pLvl = **(**uintptr)(__ccgo_up(bp + 4)) + 32 + uintptr(iLvl)*12
|
|
if (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnMerge != 0 {
|
|
if (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnMerge > nBest {
|
|
iBestLvl = iLvl
|
|
nBest = nMin
|
|
}
|
|
break
|
|
}
|
|
if (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnSeg > nBest {
|
|
nBest = (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnSeg
|
|
iBestLvl = iLvl
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
iLvl = iLvl + 1
|
|
}
|
|
if nBest < nMin {
|
|
iBestLvl = _fts5IndexFindDeleteMerge(tls, p, **(**uintptr)(__ccgo_up(bp + 4)))
|
|
}
|
|
if iBestLvl < 0 {
|
|
break
|
|
}
|
|
bRet = int32(1)
|
|
_fts5IndexMergeLevel(tls, p, bp+4, iBestLvl, bp)
|
|
if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK && (*(*TFts5StructureLevel)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 4)) + 32 + uintptr(iBestLvl)*12))).FnMerge == 0 {
|
|
_fts5StructurePromote(tls, p, iBestLvl+int32(1), **(**uintptr)(__ccgo_up(bp + 4)))
|
|
}
|
|
if nMin == int32(1) {
|
|
nMin = int32(2)
|
|
}
|
|
}
|
|
**(**uintptr)(__ccgo_up(ppStruct)) = **(**uintptr)(__ccgo_up(bp + 4))
|
|
return bRet
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** xSetOutputs callback used by detail=col when there is a column filter
|
|
// ** and there are 100 or more columns. Also called as a fallback from
|
|
// ** fts5IterSetOutputs_Col100 if the column-list spans more than one page.
|
|
// */
|
|
func _fts5IterSetOutputs_Col(tls *libc.TLS, pIter uintptr, pSeg uintptr) {
|
|
_sqlite3Fts5BufferZero(tls, pIter+32)
|
|
_fts5SegiterPoslist(tls, (*TFts5Iter)(unsafe.Pointer(pIter)).FpIndex, pSeg, (*TFts5Iter)(unsafe.Pointer(pIter)).FpColset, pIter+32)
|
|
(*TFts5Iter)(unsafe.Pointer(pIter)).Fbase.FiRowid = (*TFts5SegIter)(unsafe.Pointer(pSeg)).FiRowid
|
|
(*TFts5Iter)(unsafe.Pointer(pIter)).Fbase.FpData = (*TFts5Iter)(unsafe.Pointer(pIter)).Fposlist.Fp
|
|
(*TFts5Iter)(unsafe.Pointer(pIter)).Fbase.FnData = (*TFts5Iter)(unsafe.Pointer(pIter)).Fposlist.Fn
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** xSetOutputs callback used by detail=full when there is a column filter.
|
|
// */
|
|
func _fts5IterSetOutputs_Full(tls *libc.TLS, pIter uintptr, pSeg uintptr) {
|
|
var a, pColset, pRc uintptr
|
|
_, _, _ = a, pColset, pRc
|
|
pColset = (*TFts5Iter)(unsafe.Pointer(pIter)).FpColset
|
|
(*TFts5Iter)(unsafe.Pointer(pIter)).Fbase.FiRowid = (*TFts5SegIter)(unsafe.Pointer(pSeg)).FiRowid
|
|
if (*TFts5SegIter)(unsafe.Pointer(pSeg)).FiLeafOffset+int64((*TFts5SegIter)(unsafe.Pointer(pSeg)).FnPos) <= int64((*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pSeg)).FpLeaf)).FszLeaf) {
|
|
/* All data is stored on the current page. Populate the output
|
|
** variables to point into the body of the page object. */
|
|
a = (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pSeg)).FpLeaf)).Fp + uintptr((*TFts5SegIter)(unsafe.Pointer(pSeg)).FiLeafOffset)
|
|
pRc = (*TFts5Iter)(unsafe.Pointer(pIter)).FpIndex + 44
|
|
_sqlite3Fts5BufferZero(tls, pIter+32)
|
|
_fts5IndexExtractColset(tls, pRc, pColset, a, (*TFts5SegIter)(unsafe.Pointer(pSeg)).FnPos, pIter)
|
|
} else {
|
|
/* The data is distributed over two or more pages. Copy it into the
|
|
** Fts5Iter.poslist buffer and then set the output pointer to point
|
|
** to this buffer. */
|
|
_sqlite3Fts5BufferZero(tls, pIter+32)
|
|
_fts5SegiterPoslist(tls, (*TFts5Iter)(unsafe.Pointer(pIter)).FpIndex, pSeg, pColset, pIter+32)
|
|
(*TFts5Iter)(unsafe.Pointer(pIter)).Fbase.FpData = (*TFts5Iter)(unsafe.Pointer(pIter)).Fposlist.Fp
|
|
(*TFts5Iter)(unsafe.Pointer(pIter)).Fbase.FnData = (*TFts5Iter)(unsafe.Pointer(pIter)).Fposlist.Fn
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** xSetOutputs callback used by detail=full and detail=col tables when no
|
|
// ** column filters are specified.
|
|
// */
|
|
func _fts5IterSetOutputs_Nocolset(tls *libc.TLS, pIter uintptr, pSeg uintptr) {
|
|
(*TFts5Iter)(unsafe.Pointer(pIter)).Fbase.FiRowid = (*TFts5SegIter)(unsafe.Pointer(pSeg)).FiRowid
|
|
(*TFts5Iter)(unsafe.Pointer(pIter)).Fbase.FnData = (*TFts5SegIter)(unsafe.Pointer(pSeg)).FnPos
|
|
if (*TFts5SegIter)(unsafe.Pointer(pSeg)).FiLeafOffset+int64((*TFts5SegIter)(unsafe.Pointer(pSeg)).FnPos) <= int64((*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pSeg)).FpLeaf)).FszLeaf) {
|
|
/* All data is stored on the current page. Populate the output
|
|
** variables to point into the body of the page object. */
|
|
(*TFts5Iter)(unsafe.Pointer(pIter)).Fbase.FpData = (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pSeg)).FpLeaf)).Fp + uintptr((*TFts5SegIter)(unsafe.Pointer(pSeg)).FiLeafOffset)
|
|
} else {
|
|
/* The data is distributed over two or more pages. Copy it into the
|
|
** Fts5Iter.poslist buffer and then set the output pointer to point
|
|
** to this buffer. */
|
|
_sqlite3Fts5BufferZero(tls, pIter+32)
|
|
_fts5SegiterPoslist(tls, (*TFts5Iter)(unsafe.Pointer(pIter)).FpIndex, pSeg, uintptr(0), pIter+32)
|
|
(*TFts5Iter)(unsafe.Pointer(pIter)).Fbase.FpData = (*TFts5Iter)(unsafe.Pointer(pIter)).Fposlist.Fp
|
|
}
|
|
}
|
|
|
|
func _fts5LookaheadReaderInit(tls *libc.TLS, a uintptr, n int32, p uintptr) (r int32) {
|
|
libc.Xmemset(tls, p, 0, uint32(32))
|
|
(*TFts5LookaheadReader)(unsafe.Pointer(p)).Fa = a
|
|
(*TFts5LookaheadReader)(unsafe.Pointer(p)).Fn = n
|
|
_fts5LookaheadReaderNext(tls, p)
|
|
return _fts5LookaheadReaderNext(tls, p)
|
|
}
|
|
|
|
func _fts5LookaheadReaderNext(tls *libc.TLS, p uintptr) (r int32) {
|
|
(*TFts5LookaheadReader)(unsafe.Pointer(p)).FiPos = (*TFts5LookaheadReader)(unsafe.Pointer(p)).FiLookahead
|
|
if _sqlite3Fts5PoslistNext64(tls, (*TFts5LookaheadReader)(unsafe.Pointer(p)).Fa, (*TFts5LookaheadReader)(unsafe.Pointer(p)).Fn, p+8, p+24) != 0 {
|
|
(*TFts5LookaheadReader)(unsafe.Pointer(p)).FiLookahead = libc.Int64FromInt32(1) << libc.Int32FromInt32(62)
|
|
}
|
|
return libc.BoolInt32((*TFts5LookaheadReader)(unsafe.Pointer(p)).FiPos == libc.Int64FromInt32(1)<<libc.Int32FromInt32(62))
|
|
}
|
|
|
|
func _fts5MultiIterAdvanced(tls *libc.TLS, p uintptr, pIter uintptr, iChanged int32, iMinset int32) {
|
|
var i, iEq, v2 int32
|
|
var pSeg uintptr
|
|
_, _, _, _ = i, iEq, pSeg, v2
|
|
i = ((*TFts5Iter)(unsafe.Pointer(pIter)).FnSeg + iChanged) / int32(2)
|
|
for {
|
|
if !(i >= iMinset && (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK) {
|
|
break
|
|
}
|
|
v2 = _fts5MultiIterDoCompare(tls, pIter, i)
|
|
iEq = v2
|
|
if v2 != 0 {
|
|
pSeg = pIter + 80 + uintptr(iEq)*104
|
|
(*(*func(*libc.TLS, uintptr, uintptr, uintptr))(unsafe.Pointer(&struct{ uintptr }{(*TFts5SegIter)(unsafe.Pointer(pSeg)).FxNext})))(tls, p, pSeg, uintptr(0))
|
|
i = (*TFts5Iter)(unsafe.Pointer(pIter)).FnSeg + iEq
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i / int32(2)
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Free the iterator object passed as the second argument.
|
|
// */
|
|
func _fts5MultiIterFree(tls *libc.TLS, pIter uintptr) {
|
|
var i int32
|
|
_ = i
|
|
if pIter != 0 {
|
|
i = 0
|
|
for {
|
|
if !(i < (*TFts5Iter)(unsafe.Pointer(pIter)).FnSeg) {
|
|
break
|
|
}
|
|
_fts5SegIterClear(tls, pIter+80+uintptr(i)*104)
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
_sqlite3Fts5BufferFree(tls, pIter+32)
|
|
Xsqlite3_free(tls, pIter)
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Return true if the iterator passed as the second argument currently
|
|
// ** points to a delete marker. A delete marker is an entry with a 0 byte
|
|
// ** position-list.
|
|
// */
|
|
func _fts5MultiIterIsEmpty(tls *libc.TLS, p uintptr, pIter uintptr) (r int32) {
|
|
var pSeg uintptr
|
|
_ = pSeg
|
|
pSeg = pIter + 80 + uintptr((**(**TFts5CResult)(__ccgo_up((*TFts5Iter)(unsafe.Pointer(pIter)).FaFirst + 1*4))).FiFirst)*104
|
|
return libc.BoolInt32((*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK && (*TFts5SegIter)(unsafe.Pointer(pSeg)).FpLeaf != 0 && (*TFts5SegIter)(unsafe.Pointer(pSeg)).FnPos == 0)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Allocate a new Fts5Iter object.
|
|
// **
|
|
// ** The new object will be used to iterate through data in structure pStruct.
|
|
// ** If iLevel is -ve, then all data in all segments is merged. Or, if iLevel
|
|
// ** is zero or greater, data from the first nSegment segments on level iLevel
|
|
// ** is merged.
|
|
// **
|
|
// ** The iterator initially points to the first term/rowid entry in the
|
|
// ** iterated data.
|
|
// */
|
|
func _fts5MultiIterNew(tls *libc.TLS, p uintptr, pStruct uintptr, flags int32, pColset uintptr, pTerm uintptr, nTerm int32, iLevel int32, nSegment int32, ppOut uintptr) {
|
|
var iIter, iSeg, nSeg, v1 int32
|
|
var pEnd, pIter, pIter1, pLvl, pNew, pSeg, v2 uintptr
|
|
_, _, _, _, _, _, _, _, _, _, _ = iIter, iSeg, nSeg, pEnd, pIter, pIter1, pLvl, pNew, pSeg, v1, v2
|
|
nSeg = 0 /* Number of segment-iters in use */
|
|
iIter = 0
|
|
/* Allocate space for the new multi-seg-iterator. */
|
|
if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
if iLevel < 0 {
|
|
nSeg = (*TFts5Structure)(unsafe.Pointer(pStruct)).FnSegment
|
|
nSeg = nSeg + libc.BoolInt32((*TFts5Index)(unsafe.Pointer(p)).FpHash != 0 && 0 == flags&int32(FTS5INDEX_QUERY_SKIPHASH))
|
|
} else {
|
|
if (*(*TFts5StructureLevel)(unsafe.Pointer(pStruct + 32 + uintptr(iLevel)*12))).FnSeg < nSegment {
|
|
v1 = (*(*TFts5StructureLevel)(unsafe.Pointer(pStruct + 32 + uintptr(iLevel)*12))).FnSeg
|
|
} else {
|
|
v1 = nSegment
|
|
}
|
|
nSeg = v1
|
|
}
|
|
}
|
|
v2 = _fts5MultiIterAlloc(tls, p, nSeg)
|
|
pNew = v2
|
|
**(**uintptr)(__ccgo_up(ppOut)) = v2
|
|
if pNew == uintptr(0) {
|
|
goto fts5MultiIterNew_post_check
|
|
}
|
|
(*TFts5Iter)(unsafe.Pointer(pNew)).FbRev = libc.BoolInt32(0 != flags&int32(FTS5INDEX_QUERY_DESC))
|
|
(*TFts5Iter)(unsafe.Pointer(pNew)).FbSkipEmpty = libc.BoolUint8(libc.Int32FromInt32(0) != flags&libc.Int32FromInt32(FTS5INDEX_QUERY_SKIPEMPTY))
|
|
(*TFts5Iter)(unsafe.Pointer(pNew)).FpColset = pColset
|
|
if flags&int32(FTS5INDEX_QUERY_NOOUTPUT) == 0 {
|
|
_fts5IterSetOutputCb(tls, p+44, pNew)
|
|
}
|
|
/* Initialize each of the component segment iterators. */
|
|
if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
if iLevel < 0 {
|
|
pEnd = pStruct + 32 + uintptr((*TFts5Structure)(unsafe.Pointer(pStruct)).FnLevel)*12
|
|
if (*TFts5Index)(unsafe.Pointer(p)).FpHash != 0 && 0 == flags&int32(FTS5INDEX_QUERY_SKIPHASH) {
|
|
v1 = iIter
|
|
iIter = iIter + 1
|
|
/* Add a segment iterator for the current contents of the hash table. */
|
|
pIter = pNew + 80 + uintptr(v1)*104
|
|
_fts5SegIterHashInit(tls, p, pTerm, nTerm, flags, pIter)
|
|
}
|
|
pLvl = pStruct + 32
|
|
for {
|
|
if !(pLvl < pEnd) {
|
|
break
|
|
}
|
|
iSeg = (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnSeg - int32(1)
|
|
for {
|
|
if !(iSeg >= 0) {
|
|
break
|
|
}
|
|
pSeg = (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FaSeg + uintptr(iSeg)*56
|
|
v1 = iIter
|
|
iIter = iIter + 1
|
|
pIter1 = pNew + 80 + uintptr(v1)*104
|
|
if pTerm == uintptr(0) {
|
|
_fts5SegIterInit(tls, p, pSeg, pIter1)
|
|
} else {
|
|
_fts5SegIterSeekInit(tls, p, pTerm, nTerm, flags, pSeg, pIter1)
|
|
}
|
|
goto _5
|
|
_5:
|
|
;
|
|
iSeg = iSeg - 1
|
|
}
|
|
goto _4
|
|
_4:
|
|
;
|
|
pLvl += 12
|
|
}
|
|
} else {
|
|
pLvl = pStruct + 32 + uintptr(iLevel)*12
|
|
iSeg = nSeg - int32(1)
|
|
for {
|
|
if !(iSeg >= 0) {
|
|
break
|
|
}
|
|
v1 = iIter
|
|
iIter = iIter + 1
|
|
_fts5SegIterInit(tls, p, (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FaSeg+uintptr(iSeg)*56, pNew+80+uintptr(v1)*104)
|
|
goto _7
|
|
_7:
|
|
;
|
|
iSeg = iSeg - 1
|
|
}
|
|
}
|
|
}
|
|
/* If the above was successful, each component iterator now points
|
|
** to the first entry in its segment. In this case initialize the
|
|
** aFirst[] array. Or, if an error has occurred, free the iterator
|
|
** object and set the output variable to NULL. */
|
|
if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
_fts5MultiIterFinishSetup(tls, p, pNew)
|
|
} else {
|
|
_fts5MultiIterFree(tls, pNew)
|
|
**(**uintptr)(__ccgo_up(ppOut)) = uintptr(0)
|
|
}
|
|
goto fts5MultiIterNew_post_check
|
|
fts5MultiIterNew_post_check:
|
|
;
|
|
return
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Return the rowid of the entry that the iterator currently points
|
|
// ** to. If the iterator points to EOF when this function is called the
|
|
// ** results are undefined.
|
|
// */
|
|
func _fts5MultiIterRowid(tls *libc.TLS, pIter uintptr) (r Ti64) {
|
|
return (*(*TFts5SegIter)(unsafe.Pointer(pIter + 80 + uintptr((**(**TFts5CResult)(__ccgo_up((*TFts5Iter)(unsafe.Pointer(pIter)).FaFirst + 1*4))).FiFirst)*104))).FiRowid
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Set the pIter->bEof variable based on the state of the sub-iterators.
|
|
// */
|
|
func _fts5MultiIterSetEof(tls *libc.TLS, pIter uintptr) {
|
|
var pSeg uintptr
|
|
_ = pSeg
|
|
pSeg = pIter + 80 + uintptr((**(**TFts5CResult)(__ccgo_up((*TFts5Iter)(unsafe.Pointer(pIter)).FaFirst + 1*4))).FiFirst)*104
|
|
(*TFts5Iter)(unsafe.Pointer(pIter)).Fbase.FbEof = libc.BoolUint8((*TFts5SegIter)(unsafe.Pointer(pSeg)).FpLeaf == uintptr(0))
|
|
(*TFts5Iter)(unsafe.Pointer(pIter)).FiSwitchRowid = (*TFts5SegIter)(unsafe.Pointer(pSeg)).FiRowid
|
|
}
|
|
|
|
/*
|
|
** The argument to this macro must be an Fts5Data structure containing a
|
|
** tombstone hash page. This macro returns the key-size of the hash-page.
|
|
*/
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Return a pointer to a buffer containing the term associated with the
|
|
// ** entry that the iterator currently points to.
|
|
// */
|
|
func _fts5MultiIterTerm(tls *libc.TLS, pIter uintptr, pn uintptr) (r uintptr) {
|
|
var p uintptr
|
|
_ = p
|
|
p = pIter + 80 + uintptr((**(**TFts5CResult)(__ccgo_up((*TFts5Iter)(unsafe.Pointer(pIter)).FaFirst + 1*4))).FiFirst)*104
|
|
**(**int32)(__ccgo_up(pn)) = (*TFts5SegIter)(unsafe.Pointer(p)).Fterm.Fn
|
|
return (*TFts5SegIter)(unsafe.Pointer(p)).Fterm.Fp
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Recursively apply colset pColset to expression node pNode and all of
|
|
// ** its decendents. If (*ppFree) is not NULL, it contains a spare copy
|
|
// ** of pColset. This function may use the spare copy and set (*ppFree) to
|
|
// ** zero, or it may create copies of pColset using fts5CloneColset().
|
|
// */
|
|
func _fts5ParseSetColset(tls *libc.TLS, pParse uintptr, pNode uintptr, pColset uintptr, ppFree uintptr) {
|
|
var i int32
|
|
var pNear uintptr
|
|
_, _ = i, pNear
|
|
if (*TFts5Parse)(unsafe.Pointer(pParse)).Frc == SQLITE_OK {
|
|
if (*TFts5ExprNode)(unsafe.Pointer(pNode)).FeType == int32(FTS5_STRING) || (*TFts5ExprNode)(unsafe.Pointer(pNode)).FeType == int32(FTS5_TERM) {
|
|
pNear = (*TFts5ExprNode)(unsafe.Pointer(pNode)).FpNear
|
|
if (*TFts5ExprNearset)(unsafe.Pointer(pNear)).FpColset != 0 {
|
|
_fts5MergeColset(tls, (*TFts5ExprNearset)(unsafe.Pointer(pNear)).FpColset, pColset)
|
|
if (*TFts5Colset)(unsafe.Pointer((*TFts5ExprNearset)(unsafe.Pointer(pNear)).FpColset)).FnCol == 0 {
|
|
(*TFts5ExprNode)(unsafe.Pointer(pNode)).FeType = FTS5_EOF
|
|
(*TFts5ExprNode)(unsafe.Pointer(pNode)).FxNext = uintptr(0)
|
|
}
|
|
} else {
|
|
if **(**uintptr)(__ccgo_up(ppFree)) != 0 {
|
|
(*TFts5ExprNearset)(unsafe.Pointer(pNear)).FpColset = pColset
|
|
**(**uintptr)(__ccgo_up(ppFree)) = uintptr(0)
|
|
} else {
|
|
(*TFts5ExprNearset)(unsafe.Pointer(pNear)).FpColset = _fts5CloneColset(tls, pParse+8, pColset)
|
|
}
|
|
}
|
|
} else {
|
|
i = 0
|
|
for {
|
|
if !(i < (*TFts5ExprNode)(unsafe.Pointer(pNode)).FnChild) {
|
|
break
|
|
}
|
|
_fts5ParseSetColset(tls, pParse, *(*uintptr)(unsafe.Pointer(pNode + 40 + uintptr(i)*4)), pColset, ppFree)
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func _fts5PrefixMergerInsertByPosition(tls *libc.TLS, ppHead uintptr, p uintptr) {
|
|
var pp uintptr
|
|
_ = pp
|
|
if (*TPrefixMerger)(unsafe.Pointer(p)).FiPos >= 0 {
|
|
pp = ppHead
|
|
for **(**uintptr)(__ccgo_up(pp)) != 0 && (*TPrefixMerger)(unsafe.Pointer(p)).FiPos > (*TPrefixMerger)(unsafe.Pointer(**(**uintptr)(__ccgo_up(pp)))).FiPos {
|
|
pp = **(**uintptr)(__ccgo_up(pp)) + 48
|
|
}
|
|
(*TPrefixMerger)(unsafe.Pointer(p)).FpNext = **(**uintptr)(__ccgo_up(pp))
|
|
**(**uintptr)(__ccgo_up(pp)) = p
|
|
}
|
|
}
|
|
|
|
func _fts5PrefixMergerInsertByRowid(tls *libc.TLS, ppHead uintptr, p uintptr) {
|
|
var pp uintptr
|
|
_ = pp
|
|
if (*TPrefixMerger)(unsafe.Pointer(p)).Fiter.FaPoslist != 0 {
|
|
pp = ppHead
|
|
for **(**uintptr)(__ccgo_up(pp)) != 0 && (*TPrefixMerger)(unsafe.Pointer(p)).Fiter.FiRowid > (*TPrefixMerger)(unsafe.Pointer(**(**uintptr)(__ccgo_up(pp)))).Fiter.FiRowid {
|
|
pp = **(**uintptr)(__ccgo_up(pp)) + 48
|
|
}
|
|
(*TPrefixMerger)(unsafe.Pointer(p)).FpNext = **(**uintptr)(__ccgo_up(pp))
|
|
**(**uintptr)(__ccgo_up(pp)) = p
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Zero the iterator passed as the only argument.
|
|
// */
|
|
func _fts5SegIterClear(tls *libc.TLS, pIter uintptr) {
|
|
_sqlite3Fts5BufferFree(tls, pIter+72)
|
|
_fts5DataRelease(tls, (*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)
|
|
_fts5DataRelease(tls, (*TFts5SegIter)(unsafe.Pointer(pIter)).FpNextLeaf)
|
|
_fts5TombstoneArrayDelete(tls, (*TFts5SegIter)(unsafe.Pointer(pIter)).FpTombArray)
|
|
_fts5DlidxIterFree(tls, (*TFts5SegIter)(unsafe.Pointer(pIter)).FpDlidx)
|
|
Xsqlite3_free(tls, (*TFts5SegIter)(unsafe.Pointer(pIter)).FaRowidOffset)
|
|
libc.Xmemset(tls, pIter, 0, uint32(104))
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Initialize the iterator object pIter to iterate through the entries in
|
|
// ** segment pSeg. The iterator is left pointing to the first entry when
|
|
// ** this function returns.
|
|
// **
|
|
// ** If an error occurs, Fts5Index.rc is set to an appropriate error code. If
|
|
// ** an error has already occurred when this function is called, it is a no-op.
|
|
// */
|
|
func _fts5SegIterInit(tls *libc.TLS, p uintptr, pSeg uintptr, pIter uintptr) {
|
|
if (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FpgnoFirst == 0 {
|
|
/* This happens if the segment is being used as an input to an incremental
|
|
** merge and all data has already been "trimmed". See function
|
|
** fts5TrimSegments() for details. In this case leave the iterator empty.
|
|
** The caller will see the (pIter->pLeaf==0) and assume the iterator is
|
|
** at EOF already. */
|
|
return
|
|
}
|
|
if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
libc.Xmemset(tls, pIter, 0, uint32(104))
|
|
_fts5SegIterSetNext(tls, p, pIter)
|
|
(*TFts5SegIter)(unsafe.Pointer(pIter)).FpSeg = pSeg
|
|
(*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafPgno = (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FpgnoFirst - int32(1)
|
|
for cond := true; cond; cond = (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK && (*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf != 0 && (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).Fnn == int32(4) {
|
|
_fts5SegIterNextPage(tls, p, pIter)
|
|
}
|
|
}
|
|
if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK && (*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf != 0 {
|
|
(*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafOffset = int64(4)
|
|
(*TFts5SegIter)(unsafe.Pointer(pIter)).FiPgidxOff = (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).FszLeaf + int32(1)
|
|
_fts5SegIterLoadTerm(tls, p, pIter, 0)
|
|
_fts5SegIterLoadNPos(tls, p, pIter)
|
|
_fts5SegIterAllocTombstone(tls, p, pIter)
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This is similar to fts5SegIterSeekInit(), except that it initializes
|
|
// ** the segment iterator to point to the first term following the page
|
|
// ** with pToken/nToken on it.
|
|
// */
|
|
func _fts5SegIterNextInit(tls *libc.TLS, p uintptr, pTerm uintptr, nTerm int32, pSeg uintptr, pIter uintptr) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var a, pSel uintptr
|
|
var bDlidx, iPg int32
|
|
var val Ti64
|
|
var _ /* iTermOff at bp+0 */ int32
|
|
_, _, _, _, _ = a, bDlidx, iPg, pSel, val
|
|
iPg = -int32(1) /* Page of segment to open */
|
|
bDlidx = 0
|
|
pSel = uintptr(0) /* SELECT to find iPg */
|
|
pSel = _fts5IdxNextStmt(tls, p)
|
|
if pSel != 0 {
|
|
Xsqlite3_bind_int(tls, pSel, int32(1), (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FiSegid)
|
|
Xsqlite3_bind_blob(tls, pSel, int32(2), pTerm, nTerm, libc.UintptrFromInt32(0))
|
|
if Xsqlite3_step(tls, pSel) == int32(SQLITE_ROW) {
|
|
val = Xsqlite3_column_int64(tls, pSel, 0)
|
|
iPg = int32(val >> libc.Int32FromInt32(1))
|
|
bDlidx = int32(val & libc.Int64FromInt32(0x0001))
|
|
}
|
|
(*TFts5Index)(unsafe.Pointer(p)).Frc = Xsqlite3_reset(tls, pSel)
|
|
Xsqlite3_bind_null(tls, pSel, int32(2))
|
|
if (*TFts5Index)(unsafe.Pointer(p)).Frc != 0 {
|
|
return
|
|
}
|
|
}
|
|
libc.Xmemset(tls, pIter, 0, uint32(104))
|
|
(*TFts5SegIter)(unsafe.Pointer(pIter)).FpSeg = pSeg
|
|
**(**int32)(__ccgo_up(pIter + 4)) |= int32(FTS5_SEGITER_ONETERM)
|
|
if iPg >= 0 {
|
|
(*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafPgno = iPg - int32(1)
|
|
_fts5SegIterNextPage(tls, p, pIter)
|
|
_fts5SegIterSetNext(tls, p, pIter)
|
|
}
|
|
if (*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf != 0 {
|
|
a = (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).Fp
|
|
**(**int32)(__ccgo_up(bp)) = 0
|
|
(*TFts5SegIter)(unsafe.Pointer(pIter)).FiPgidxOff = (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).FszLeaf
|
|
**(**int32)(__ccgo_up(pIter + 48)) += _sqlite3Fts5GetVarint32(tls, a+uintptr((*TFts5SegIter)(unsafe.Pointer(pIter)).FiPgidxOff), bp)
|
|
(*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafOffset = int64(**(**int32)(__ccgo_up(bp)))
|
|
_fts5SegIterLoadTerm(tls, p, pIter, 0)
|
|
_fts5SegIterLoadNPos(tls, p, pIter)
|
|
if bDlidx != 0 {
|
|
_fts5SegIterLoadDlidx(tls, p, pIter)
|
|
}
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Load the next leaf page into the segment iterator.
|
|
// */
|
|
func _fts5SegIterNextPage(tls *libc.TLS, p uintptr, pIter uintptr) {
|
|
var pLeaf, pSeg uintptr
|
|
_, _ = pLeaf, pSeg
|
|
pSeg = (*TFts5SegIter)(unsafe.Pointer(pIter)).FpSeg
|
|
_fts5DataRelease(tls, (*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)
|
|
(*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafPgno = (*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafPgno + 1
|
|
if (*TFts5SegIter)(unsafe.Pointer(pIter)).FpNextLeaf != 0 {
|
|
(*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf = (*TFts5SegIter)(unsafe.Pointer(pIter)).FpNextLeaf
|
|
(*TFts5SegIter)(unsafe.Pointer(pIter)).FpNextLeaf = uintptr(0)
|
|
} else {
|
|
if (*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafPgno <= (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FpgnoLast {
|
|
(*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf = _fts5LeafRead(tls, p, int64((*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FiSegid)<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B)+libc.Int32FromInt32(FTS5_DATA_DLI_B))+int64(libc.Int32FromInt32(0))<<(libc.Int32FromInt32(FTS5_DATA_PAGE_B)+libc.Int32FromInt32(FTS5_DATA_HEIGHT_B))+int64(libc.Int32FromInt32(0))<<libc.Int32FromInt32(FTS5_DATA_PAGE_B)+int64((*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafPgno))
|
|
} else {
|
|
(*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf = uintptr(0)
|
|
}
|
|
}
|
|
pLeaf = (*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf
|
|
if pLeaf != 0 {
|
|
(*TFts5SegIter)(unsafe.Pointer(pIter)).FiPgidxOff = (*TFts5Data)(unsafe.Pointer(pLeaf)).FszLeaf
|
|
if (*TFts5Data)(unsafe.Pointer(pLeaf)).FszLeaf >= (*TFts5Data)(unsafe.Pointer(pLeaf)).Fnn {
|
|
(*TFts5SegIter)(unsafe.Pointer(pIter)).FiEndofDoclist = (*TFts5Data)(unsafe.Pointer(pLeaf)).Fnn + int32(1)
|
|
} else {
|
|
**(**int32)(__ccgo_up(pIter + 48)) += _sqlite3Fts5GetVarint32(tls, (*TFts5Data)(unsafe.Pointer(pLeaf)).Fp+uintptr((*TFts5SegIter)(unsafe.Pointer(pIter)).FiPgidxOff), pIter+52)
|
|
}
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Advance iterator pIter to the next entry.
|
|
// **
|
|
// ** This version of fts5SegIterNext() is only used by reverse iterators.
|
|
// */
|
|
func _fts5SegIterNext_Reverse(tls *libc.TLS, p uintptr, pIter uintptr, pbUnused uintptr) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var a, v1 uintptr
|
|
var iOff int32
|
|
var _ /* iDelta at bp+0 */ Tu64
|
|
_, _, _ = a, iOff, v1
|
|
_ = pbUnused
|
|
if (*TFts5SegIter)(unsafe.Pointer(pIter)).FiRowidOffset > 0 {
|
|
a = (*TFts5Data)(unsafe.Pointer((*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf)).Fp
|
|
(*TFts5SegIter)(unsafe.Pointer(pIter)).FiRowidOffset = (*TFts5SegIter)(unsafe.Pointer(pIter)).FiRowidOffset - 1
|
|
(*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafOffset = int64(**(**int32)(__ccgo_up((*TFts5SegIter)(unsafe.Pointer(pIter)).FaRowidOffset + uintptr((*TFts5SegIter)(unsafe.Pointer(pIter)).FiRowidOffset)*4)))
|
|
_fts5SegIterLoadNPos(tls, p, pIter)
|
|
iOff = int32((*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafOffset)
|
|
if (*TFts5Config)(unsafe.Pointer((*TFts5Index)(unsafe.Pointer(p)).FpConfig)).FeDetail != int32(FTS5_DETAIL_NONE) {
|
|
iOff = iOff + (*TFts5SegIter)(unsafe.Pointer(pIter)).FnPos
|
|
}
|
|
_sqlite3Fts5GetVarint(tls, a+uintptr(iOff), bp)
|
|
v1 = pIter + 88
|
|
*(*Ti64)(unsafe.Pointer(v1)) = Ti64(uint64(*(*Ti64)(unsafe.Pointer(v1))) - **(**Tu64)(__ccgo_up(bp)))
|
|
} else {
|
|
_fts5SegIterReverseNewPage(tls, p, pIter)
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Initialize the object pIter to point to term pTerm/nTerm within segment
|
|
// ** pSeg. If there is no such term in the index, the iterator is set to EOF.
|
|
// **
|
|
// ** If an error occurs, Fts5Index.rc is set to an appropriate error code. If
|
|
// ** an error has already occurred when this function is called, it is a no-op.
|
|
// */
|
|
func _fts5SegIterSeekInit(tls *libc.TLS, p uintptr, pTerm uintptr, nTerm int32, flags int32, pSeg uintptr, pIter uintptr) {
|
|
var bDlidx, bGe, iPg int32
|
|
var pIdxSelect uintptr
|
|
var val Ti64
|
|
_, _, _, _, _ = bDlidx, bGe, iPg, pIdxSelect, val
|
|
iPg = int32(1)
|
|
bGe = flags & int32(FTS5INDEX_QUERY_SCAN)
|
|
bDlidx = 0 /* True if there is a doclist-index */
|
|
pIdxSelect = uintptr(0)
|
|
libc.Xmemset(tls, pIter, 0, uint32(104))
|
|
(*TFts5SegIter)(unsafe.Pointer(pIter)).FpSeg = pSeg
|
|
/* This block sets stack variable iPg to the leaf page number that may
|
|
** contain term (pTerm/nTerm), if it is present in the segment. */
|
|
pIdxSelect = _fts5IdxSelectStmt(tls, p)
|
|
if (*TFts5Index)(unsafe.Pointer(p)).Frc != 0 {
|
|
return
|
|
}
|
|
Xsqlite3_bind_int(tls, pIdxSelect, int32(1), (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FiSegid)
|
|
Xsqlite3_bind_blob(tls, pIdxSelect, int32(2), pTerm, nTerm, libc.UintptrFromInt32(0))
|
|
if int32(SQLITE_ROW) == Xsqlite3_step(tls, pIdxSelect) {
|
|
val = int64(Xsqlite3_column_int(tls, pIdxSelect, 0))
|
|
iPg = int32(val >> libc.Int32FromInt32(1))
|
|
bDlidx = int32(val & libc.Int64FromInt32(0x0001))
|
|
}
|
|
(*TFts5Index)(unsafe.Pointer(p)).Frc = Xsqlite3_reset(tls, pIdxSelect)
|
|
Xsqlite3_bind_null(tls, pIdxSelect, int32(2))
|
|
if iPg < (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FpgnoFirst {
|
|
iPg = (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FpgnoFirst
|
|
bDlidx = 0
|
|
}
|
|
(*TFts5SegIter)(unsafe.Pointer(pIter)).FiLeafPgno = iPg - int32(1)
|
|
_fts5SegIterNextPage(tls, p, pIter)
|
|
if (*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf != 0 {
|
|
_fts5LeafSeek(tls, p, bGe, pIter, pTerm, nTerm)
|
|
}
|
|
if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK && (bGe == 0 || flags&int32(FTS5INDEX_QUERY_SCANONETERM) != 0) {
|
|
**(**int32)(__ccgo_up(pIter + 4)) |= int32(FTS5_SEGITER_ONETERM)
|
|
if (*TFts5SegIter)(unsafe.Pointer(pIter)).FpLeaf != 0 {
|
|
if flags&int32(FTS5INDEX_QUERY_DESC) != 0 {
|
|
**(**int32)(__ccgo_up(pIter + 4)) |= int32(FTS5_SEGITER_REVERSE)
|
|
}
|
|
if bDlidx != 0 {
|
|
_fts5SegIterLoadDlidx(tls, p, pIter)
|
|
}
|
|
if flags&int32(FTS5INDEX_QUERY_DESC) != 0 {
|
|
_fts5SegIterReverse(tls, p, pIter)
|
|
}
|
|
}
|
|
}
|
|
_fts5SegIterSetNext(tls, p, pIter)
|
|
if 0 == flags&int32(FTS5INDEX_QUERY_SCANONETERM) {
|
|
_fts5SegIterAllocTombstone(tls, p, pIter)
|
|
}
|
|
/* Either:
|
|
**
|
|
** 1) an error has occurred, or
|
|
** 2) the iterator points to EOF, or
|
|
** 3) the iterator points to an entry with term (pTerm/nTerm), or
|
|
** 4) the FTS5INDEX_QUERY_SCAN flag was set and the iterator points
|
|
** to an entry with a term greater than or equal to (pTerm/nTerm).
|
|
*/
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Set the SQLITE_INDEX_SCAN_UNIQUE flag in pIdxInfo->flags. Unless this
|
|
// ** extension is currently being used by a version of SQLite too old to
|
|
// ** support index-info flags. In that case this function is a no-op.
|
|
// */
|
|
func _fts5SetUniqueFlag(tls *libc.TLS, pIdxInfo uintptr) {
|
|
**(**int32)(__ccgo_up(pIdxInfo + 56)) |= int32(SQLITE_INDEX_SCAN_UNIQUE)
|
|
}
|
|
|
|
func _fts5SorterNext(tls *libc.TLS, pCsr uintptr) (r int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var a, aBlob, pSorter, v1 uintptr
|
|
var i, iOff, nBlob, rc int32
|
|
var _ /* iVal at bp+0 */ int32
|
|
_, _, _, _, _, _, _, _ = a, aBlob, i, iOff, nBlob, pSorter, rc, v1
|
|
pSorter = (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpSorter
|
|
rc = Xsqlite3_step(tls, (*TFts5Sorter)(unsafe.Pointer(pSorter)).FpStmt)
|
|
if rc == int32(SQLITE_DONE) {
|
|
rc = SQLITE_OK
|
|
**(**int32)(__ccgo_up(pCsr + 60)) |= libc.Int32FromInt32(FTS5CSR_EOF) | libc.Int32FromInt32(FTS5CSR_REQUIRE_CONTENT)
|
|
} else {
|
|
if rc == int32(SQLITE_ROW) {
|
|
iOff = 0
|
|
rc = SQLITE_OK
|
|
(*TFts5Sorter)(unsafe.Pointer(pSorter)).FiRowid = Xsqlite3_column_int64(tls, (*TFts5Sorter)(unsafe.Pointer(pSorter)).FpStmt, 0)
|
|
nBlob = Xsqlite3_column_bytes(tls, (*TFts5Sorter)(unsafe.Pointer(pSorter)).FpStmt, int32(1))
|
|
v1 = Xsqlite3_column_blob(tls, (*TFts5Sorter)(unsafe.Pointer(pSorter)).FpStmt, int32(1))
|
|
a = v1
|
|
aBlob = v1
|
|
/* nBlob==0 in detail=none mode. */
|
|
if nBlob > 0 {
|
|
i = 0
|
|
for {
|
|
if !(i < (*TFts5Sorter)(unsafe.Pointer(pSorter)).FnIdx-int32(1)) {
|
|
break
|
|
}
|
|
a = a + uintptr(_sqlite3Fts5GetVarint32(tls, a, bp))
|
|
iOff = iOff + **(**int32)(__ccgo_up(bp))
|
|
*(*int32)(unsafe.Pointer(pSorter + 24 + uintptr(i)*4)) = iOff
|
|
goto _2
|
|
_2:
|
|
;
|
|
i = i + 1
|
|
}
|
|
*(*int32)(unsafe.Pointer(pSorter + 24 + uintptr(i)*4)) = t__predefined_ptrdiff_t(aBlob+uintptr(nBlob)) - int32(a)
|
|
(*TFts5Sorter)(unsafe.Pointer(pSorter)).FaPoslist = a
|
|
}
|
|
_fts5CsrNewrow(tls, pCsr)
|
|
}
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Load the contents of the "averages" record from disk into the
|
|
// ** p->nTotalRow and p->aTotalSize[] variables. If successful, and if
|
|
// ** argument bCache is true, set the p->bTotalsValid flag to indicate
|
|
// ** that the contents of aTotalSize[] and nTotalRow are valid until
|
|
// ** further notice.
|
|
// **
|
|
// ** Return SQLITE_OK if successful, or an SQLite error code if an error
|
|
// ** occurs.
|
|
// */
|
|
func _fts5StorageLoadTotals(tls *libc.TLS, p uintptr, bCache int32) (r int32) {
|
|
var rc int32
|
|
_ = rc
|
|
rc = SQLITE_OK
|
|
if (*TFts5Storage)(unsafe.Pointer(p)).FbTotalsValid == 0 {
|
|
rc = _sqlite3Fts5IndexGetAverages(tls, (*TFts5Storage)(unsafe.Pointer(p)).FpIndex, p+16, (*TFts5Storage)(unsafe.Pointer(p)).FaTotalSize)
|
|
(*TFts5Storage)(unsafe.Pointer(p)).FbTotalsValid = bCache
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** A new segment has just been written to level iLvl of index structure
|
|
// ** pStruct. This function determines if any segments should be promoted
|
|
// ** as a result. Segments are promoted in two scenarios:
|
|
// **
|
|
// ** a) If the segment just written is smaller than one or more segments
|
|
// ** within the previous populated level, it is promoted to the previous
|
|
// ** populated level.
|
|
// **
|
|
// ** b) If the segment just written is larger than the newest segment on
|
|
// ** the next populated level, then that segment, and any other adjacent
|
|
// ** segments that are also smaller than the one just written, are
|
|
// ** promoted.
|
|
// **
|
|
// ** If one or more segments are promoted, the structure object is updated
|
|
// ** to reflect this.
|
|
// */
|
|
func _fts5StructurePromote(tls *libc.TLS, p uintptr, iLvl int32, pStruct uintptr) {
|
|
var i, iPromote, iTst, nSeg, sz, szMax, szPromote, szSeg int32
|
|
var pSeg, pTst uintptr
|
|
_, _, _, _, _, _, _, _, _, _ = i, iPromote, iTst, nSeg, pSeg, pTst, sz, szMax, szPromote, szSeg
|
|
if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
iPromote = -int32(1)
|
|
szPromote = 0 /* Size of segment just written */
|
|
nSeg = (*(*TFts5StructureLevel)(unsafe.Pointer(pStruct + 32 + uintptr(iLvl)*12))).FnSeg
|
|
if nSeg == 0 {
|
|
return
|
|
}
|
|
pSeg = (*(*TFts5StructureLevel)(unsafe.Pointer(pStruct + 32 + uintptr(iLvl)*12))).FaSeg + uintptr((*(*TFts5StructureLevel)(unsafe.Pointer(pStruct + 32 + uintptr(iLvl)*12))).FnSeg-int32(1))*56
|
|
szSeg = int32(1) + (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FpgnoLast - (*TFts5StructureSegment)(unsafe.Pointer(pSeg)).FpgnoFirst
|
|
/* Check for condition (a) */
|
|
iTst = iLvl - int32(1)
|
|
for {
|
|
if !(iTst >= 0 && (*(*TFts5StructureLevel)(unsafe.Pointer(pStruct + 32 + uintptr(iTst)*12))).FnSeg == 0) {
|
|
break
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
iTst = iTst - 1
|
|
}
|
|
if iTst >= 0 {
|
|
szMax = 0
|
|
pTst = pStruct + 32 + uintptr(iTst)*12
|
|
i = 0
|
|
for {
|
|
if !(i < (*TFts5StructureLevel)(unsafe.Pointer(pTst)).FnSeg) {
|
|
break
|
|
}
|
|
sz = (**(**TFts5StructureSegment)(__ccgo_up((*TFts5StructureLevel)(unsafe.Pointer(pTst)).FaSeg + uintptr(i)*56))).FpgnoLast - (**(**TFts5StructureSegment)(__ccgo_up((*TFts5StructureLevel)(unsafe.Pointer(pTst)).FaSeg + uintptr(i)*56))).FpgnoFirst + int32(1)
|
|
if sz > szMax {
|
|
szMax = sz
|
|
}
|
|
goto _2
|
|
_2:
|
|
;
|
|
i = i + 1
|
|
}
|
|
if szMax >= szSeg {
|
|
/* Condition (a) is true. Promote the newest segment on level
|
|
** iLvl to level iTst. */
|
|
iPromote = iTst
|
|
szPromote = szMax
|
|
}
|
|
}
|
|
/* If condition (a) is not met, assume (b) is true. StructurePromoteTo()
|
|
** is a no-op if it is not. */
|
|
if iPromote < 0 {
|
|
iPromote = iLvl
|
|
szPromote = szSeg
|
|
}
|
|
_fts5StructurePromoteTo(tls, p, iPromote, szPromote, pStruct)
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Return a copy of index structure pStruct. Except, promote as many
|
|
// ** segments as possible to level iPromote. If an OOM occurs, NULL is
|
|
// ** returned.
|
|
// */
|
|
func _fts5StructurePromoteTo(tls *libc.TLS, p uintptr, iPromote int32, szPromote int32, pStruct uintptr) {
|
|
var il, is, sz int32
|
|
var pLvl, pOut uintptr
|
|
_, _, _, _, _ = il, is, pLvl, pOut, sz
|
|
pOut = pStruct + 32 + uintptr(iPromote)*12
|
|
if (*TFts5StructureLevel)(unsafe.Pointer(pOut)).FnMerge == 0 {
|
|
il = iPromote + int32(1)
|
|
for {
|
|
if !(il < (*TFts5Structure)(unsafe.Pointer(pStruct)).FnLevel) {
|
|
break
|
|
}
|
|
pLvl = pStruct + 32 + uintptr(il)*12
|
|
if (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnMerge != 0 {
|
|
return
|
|
}
|
|
is = (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnSeg - int32(1)
|
|
for {
|
|
if !(is >= 0) {
|
|
break
|
|
}
|
|
sz = _fts5SegmentSize(tls, (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FaSeg+uintptr(is)*56)
|
|
if sz > szPromote {
|
|
return
|
|
}
|
|
_fts5StructureExtendLevel(tls, p+44, pStruct, iPromote, int32(1), int32(1))
|
|
if (*TFts5Index)(unsafe.Pointer(p)).Frc != 0 {
|
|
return
|
|
}
|
|
libc.Xmemcpy(tls, (*TFts5StructureLevel)(unsafe.Pointer(pOut)).FaSeg, (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FaSeg+uintptr(is)*56, uint32(56))
|
|
(*TFts5StructureLevel)(unsafe.Pointer(pOut)).FnSeg = (*TFts5StructureLevel)(unsafe.Pointer(pOut)).FnSeg + 1
|
|
(*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnSeg = (*TFts5StructureLevel)(unsafe.Pointer(pLvl)).FnSeg - 1
|
|
goto _2
|
|
_2:
|
|
;
|
|
is = is - 1
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
il = il + 1
|
|
}
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Release a reference to an Fts5Structure object returned by an earlier
|
|
// ** call to fts5StructureRead() or fts5StructureDecode().
|
|
// */
|
|
func _fts5StructureRelease(tls *libc.TLS, pStruct uintptr) {
|
|
var i, v1 int32
|
|
var v2 uintptr
|
|
var v3 bool
|
|
_, _, _, _ = i, v1, v2, v3
|
|
if v3 = pStruct != 0; v3 {
|
|
v2 = pStruct
|
|
*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) - 1
|
|
v1 = *(*int32)(unsafe.Pointer(v2))
|
|
}
|
|
if v3 && 0 >= v1 {
|
|
i = 0
|
|
for {
|
|
if !(i < (*TFts5Structure)(unsafe.Pointer(pStruct)).FnLevel) {
|
|
break
|
|
}
|
|
Xsqlite3_free(tls, (*(*TFts5StructureLevel)(unsafe.Pointer(pStruct + 32 + uintptr(i)*12))).FaSeg)
|
|
goto _4
|
|
_4:
|
|
;
|
|
i = i + 1
|
|
}
|
|
Xsqlite3_free(tls, pStruct)
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** If the segment-iterator passed as the first argument is at EOF, then
|
|
// ** set pIter->term to a copy of buffer pTerm.
|
|
// */
|
|
func _fts5TokendataSetTermIfEof(tls *libc.TLS, pIter uintptr, pTerm uintptr) {
|
|
if pIter != 0 && (*(*TFts5SegIter)(unsafe.Pointer(pIter + 80))).FpLeaf == uintptr(0) {
|
|
_sqlite3Fts5BufferSet(tls, (*TFts5Iter)(unsafe.Pointer(pIter)).FpIndex+44, pIter+80+72, (*TFts5Buffer)(unsafe.Pointer(pTerm)).Fn, (*TFts5Buffer)(unsafe.Pointer(pTerm)).Fp)
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Set the FTS5CSR_REQUIRE_RESEEK flag on all FTS5_PLAN_MATCH cursors
|
|
// ** open on table pTab.
|
|
// */
|
|
func _fts5TripCursors(tls *libc.TLS, pTab uintptr) {
|
|
var pCsr uintptr
|
|
_ = pCsr
|
|
pCsr = (*TFts5Global)(unsafe.Pointer((*TFts5FullTable)(unsafe.Pointer(pTab)).FpGlobal)).FpCsr
|
|
for {
|
|
if !(pCsr != 0) {
|
|
break
|
|
}
|
|
if (*TFts5Cursor)(unsafe.Pointer(pCsr)).FePlan == int32(FTS5_PLAN_MATCH) && (*TFts5Cursor)(unsafe.Pointer(pCsr)).Fbase.FpVtab == pTab {
|
|
**(**int32)(__ccgo_up(pCsr + 60)) |= int32(FTS5CSR_REQUIRE_RESEEK)
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
pCsr = (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpNext
|
|
}
|
|
}
|
|
|
|
func _fts5VocabInstanceNext(tls *libc.TLS, pCsr uintptr) (r int32) {
|
|
var eDetail, rc int32
|
|
var pIter, po, pp uintptr
|
|
_, _, _, _, _ = eDetail, pIter, po, pp, rc
|
|
eDetail = (*TFts5Config)(unsafe.Pointer((*TFts5Table)(unsafe.Pointer((*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FpFts5)).FpConfig)).FeDetail
|
|
rc = SQLITE_OK
|
|
pIter = (*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FpIter
|
|
pp = pCsr + 72
|
|
po = pCsr + 80
|
|
for eDetail == int32(FTS5_DETAIL_NONE) || _sqlite3Fts5PoslistNext64(tls, (*TFts5IndexIter)(unsafe.Pointer(pIter)).FpData, (*TFts5IndexIter)(unsafe.Pointer(pIter)).FnData, po, pp) != 0 {
|
|
(*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FiInstPos = 0
|
|
(*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FiInstOff = 0
|
|
rc = _sqlite3Fts5IterNextScan(tls, (*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FpIter)
|
|
if rc == SQLITE_OK {
|
|
rc = _fts5VocabInstanceNewTerm(tls, pCsr)
|
|
if (*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FbEof != 0 || eDetail == int32(FTS5_DETAIL_NONE) {
|
|
break
|
|
}
|
|
}
|
|
if rc != 0 {
|
|
(*TFts5VocabCursor)(unsafe.Pointer(pCsr)).FbEof = int32(1)
|
|
break
|
|
}
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This function is called when flushing a leaf page that contains no
|
|
// ** terms at all to disk.
|
|
// */
|
|
func _fts5WriteBtreeNoTerm(tls *libc.TLS, p uintptr, pWriter uintptr) {
|
|
var pDlidx uintptr
|
|
_ = pDlidx
|
|
/* If there were no rowids on the leaf page either and the doclist-index
|
|
** has already been started, append an 0x00 byte to it. */
|
|
if (*TFts5SegWriter)(unsafe.Pointer(pWriter)).FbFirstRowidInPage != 0 && (**(**TFts5DlidxWriter)(__ccgo_up((*TFts5SegWriter)(unsafe.Pointer(pWriter)).FaDlidx))).Fbuf.Fn > 0 {
|
|
pDlidx = (*TFts5SegWriter)(unsafe.Pointer(pWriter)).FaDlidx
|
|
_sqlite3Fts5BufferAppendVarint(tls, p+44, pDlidx+16, 0)
|
|
}
|
|
/* Increment the "number of sequential leaves without a term" counter. */
|
|
(*TFts5SegWriter)(unsafe.Pointer(pWriter)).FnEmpty = (*TFts5SegWriter)(unsafe.Pointer(pWriter)).FnEmpty + 1
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This is called once for each leaf page except the first that contains
|
|
// ** at least one term. Argument (nTerm/pTerm) is the split-key - a term that
|
|
// ** is larger than all terms written to earlier leaves, and equal to or
|
|
// ** smaller than the first term on the new leaf.
|
|
// **
|
|
// ** If an error occurs, an error code is left in Fts5Index.rc. If an error
|
|
// ** has already occurred when this function is called, it is a no-op.
|
|
// */
|
|
func _fts5WriteBtreeTerm(tls *libc.TLS, p uintptr, pWriter uintptr, nTerm int32, pTerm uintptr) {
|
|
_fts5WriteFlushBtree(tls, p, pWriter)
|
|
if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
_sqlite3Fts5BufferSet(tls, p+44, pWriter+76, nTerm, pTerm)
|
|
(*TFts5SegWriter)(unsafe.Pointer(pWriter)).FiBtPage = (*TFts5SegWriter)(unsafe.Pointer(pWriter)).Fwriter.Fpgno
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Flush any data cached by the writer object to the database. Free any
|
|
// ** allocations associated with the writer.
|
|
// */
|
|
func _fts5WriteFinish(tls *libc.TLS, p uintptr, pWriter uintptr, pnLeaf uintptr) {
|
|
var i int32
|
|
var pLeaf uintptr
|
|
_, _ = i, pLeaf
|
|
pLeaf = pWriter + 4
|
|
if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
|
if (*TFts5PageWriter)(unsafe.Pointer(pLeaf)).Fbuf.Fn > int32(4) {
|
|
_fts5WriteFlushLeaf(tls, p, pWriter)
|
|
}
|
|
**(**int32)(__ccgo_up(pnLeaf)) = (*TFts5PageWriter)(unsafe.Pointer(pLeaf)).Fpgno - int32(1)
|
|
if (*TFts5PageWriter)(unsafe.Pointer(pLeaf)).Fpgno > int32(1) {
|
|
_fts5WriteFlushBtree(tls, p, pWriter)
|
|
}
|
|
}
|
|
_sqlite3Fts5BufferFree(tls, pLeaf+32)
|
|
_sqlite3Fts5BufferFree(tls, pLeaf+8)
|
|
_sqlite3Fts5BufferFree(tls, pLeaf+20)
|
|
_sqlite3Fts5BufferFree(tls, pWriter+76)
|
|
i = 0
|
|
for {
|
|
if !(i < (*TFts5SegWriter)(unsafe.Pointer(pWriter)).FnDlidx) {
|
|
break
|
|
}
|
|
_sqlite3Fts5BufferFree(tls, (*TFts5SegWriter)(unsafe.Pointer(pWriter)).FaDlidx+uintptr(i)*32+16)
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
Xsqlite3_free(tls, (*TFts5SegWriter)(unsafe.Pointer(pWriter)).FaDlidx)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Add a single segment and its associated events.
|
|
// */
|
|
func _geopolyAddOneSegment(tls *libc.TLS, p uintptr, x0 TGeoCoord, y0 TGeoCoord, x1 TGeoCoord, y1 TGeoCoord, side uint8, idx uint32) {
|
|
var pEvent, pSeg uintptr
|
|
var t TGeoCoord
|
|
_, _, _ = pEvent, pSeg, t
|
|
if x0 == x1 {
|
|
return
|
|
} /* Ignore vertical segments */
|
|
if x0 > x1 {
|
|
t = x0
|
|
x0 = x1
|
|
x1 = t
|
|
t = y0
|
|
y0 = y1
|
|
y1 = t
|
|
}
|
|
pSeg = (*TGeoOverlap)(unsafe.Pointer(p)).FaSegment + uintptr((*TGeoOverlap)(unsafe.Pointer(p)).FnSegment)*40
|
|
(*TGeoOverlap)(unsafe.Pointer(p)).FnSegment = (*TGeoOverlap)(unsafe.Pointer(p)).FnSegment + 1
|
|
(*TGeoSegment)(unsafe.Pointer(pSeg)).FC = float64((y1 - y0) / (x1 - x0))
|
|
(*TGeoSegment)(unsafe.Pointer(pSeg)).FB = float64(y1) - float64(float64(x1)*(*TGeoSegment)(unsafe.Pointer(pSeg)).FC)
|
|
(*TGeoSegment)(unsafe.Pointer(pSeg)).Fy0 = y0
|
|
(*TGeoSegment)(unsafe.Pointer(pSeg)).Fside = side
|
|
(*TGeoSegment)(unsafe.Pointer(pSeg)).Fidx = idx
|
|
pEvent = (*TGeoOverlap)(unsafe.Pointer(p)).FaEvent + uintptr((*TGeoOverlap)(unsafe.Pointer(p)).FnEvent)*24
|
|
(*TGeoOverlap)(unsafe.Pointer(p)).FnEvent = (*TGeoOverlap)(unsafe.Pointer(p)).FnEvent + 1
|
|
(*TGeoEvent)(unsafe.Pointer(pEvent)).Fx = float64(x0)
|
|
(*TGeoEvent)(unsafe.Pointer(pEvent)).FeType = 0
|
|
(*TGeoEvent)(unsafe.Pointer(pEvent)).FpSeg = pSeg
|
|
pEvent = (*TGeoOverlap)(unsafe.Pointer(p)).FaEvent + uintptr((*TGeoOverlap)(unsafe.Pointer(p)).FnEvent)*24
|
|
(*TGeoOverlap)(unsafe.Pointer(p)).FnEvent = (*TGeoOverlap)(unsafe.Pointer(p)).FnEvent + 1
|
|
(*TGeoEvent)(unsafe.Pointer(pEvent)).Fx = float64(x1)
|
|
(*TGeoEvent)(unsafe.Pointer(pEvent)).FeType = int32(1)
|
|
(*TGeoEvent)(unsafe.Pointer(pEvent)).FpSeg = pSeg
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Sort an array of nEvent event objects into a list.
|
|
// */
|
|
func _geopolySortEventsByX(tls *libc.TLS, aEvent uintptr, nEvent int32) (r uintptr) {
|
|
var a [50]uintptr
|
|
var i, j, mx int32
|
|
var p uintptr
|
|
_, _, _, _, _ = a, i, j, mx, p
|
|
mx = 0
|
|
i = 0
|
|
for {
|
|
if !(i < nEvent) {
|
|
break
|
|
}
|
|
p = aEvent + uintptr(i)*24
|
|
(*TGeoEvent)(unsafe.Pointer(p)).FpNext = uintptr(0)
|
|
j = 0
|
|
for {
|
|
if !(j < mx && a[j] != 0) {
|
|
break
|
|
}
|
|
p = _geopolyEventMerge(tls, a[j], p)
|
|
a[j] = uintptr(0)
|
|
goto _2
|
|
_2:
|
|
;
|
|
j = j + 1
|
|
}
|
|
a[j] = p
|
|
if j >= mx {
|
|
mx = j + int32(1)
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
p = uintptr(0)
|
|
i = 0
|
|
for {
|
|
if !(i < mx) {
|
|
break
|
|
}
|
|
p = _geopolyEventMerge(tls, a[i], p)
|
|
goto _3
|
|
_3:
|
|
;
|
|
i = i + 1
|
|
}
|
|
return p
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Flush the contents of memory to a real file on disk.
|
|
// */
|
|
func _memjrnlCreateFile(tls *libc.TLS, p uintptr) (r int32) {
|
|
var copy1 TMemJournal
|
|
var iOff Ti64
|
|
var nChunk, rc int32
|
|
var pIter, pReal uintptr
|
|
_, _, _, _, _, _ = copy1, iOff, nChunk, pIter, pReal, rc
|
|
pReal = p
|
|
copy1 = **(**TMemJournal)(__ccgo_up(p))
|
|
libc.Xmemset(tls, p, 0, uint32(64))
|
|
rc = _sqlite3OsOpen(tls, copy1.FpVfs, copy1.FzJournal, pReal, copy1.Fflags, uintptr(0))
|
|
if rc == SQLITE_OK {
|
|
nChunk = copy1.FnChunkSize
|
|
iOff = 0
|
|
pIter = copy1.FpFirst
|
|
for {
|
|
if !(pIter != 0) {
|
|
break
|
|
}
|
|
if iOff+int64(nChunk) > copy1.Fendpoint.FiOffset {
|
|
nChunk = int32(copy1.Fendpoint.FiOffset - iOff)
|
|
}
|
|
rc = _sqlite3OsWrite(tls, pReal, pIter+4, nChunk, iOff)
|
|
if rc != 0 {
|
|
break
|
|
}
|
|
iOff = iOff + int64(nChunk)
|
|
goto _1
|
|
_1:
|
|
;
|
|
pIter = (*TFileChunk)(unsafe.Pointer(pIter)).FpNext
|
|
}
|
|
if rc == SQLITE_OK {
|
|
/* No error has occurred. Free the in-memory buffers. */
|
|
_memjrnlFreeChunks(tls, copy1.FpFirst)
|
|
}
|
|
}
|
|
if rc != SQLITE_OK {
|
|
/* If an error occurred while creating or writing to the file, restore
|
|
** the original before returning. This way, SQLite uses the in-memory
|
|
** journal data to roll back changes made to the internal page-cache
|
|
** before this function was called. */
|
|
_sqlite3OsClose(tls, pReal)
|
|
**(**TMemJournal)(__ccgo_up(p)) = copy1
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Move the cursor up to the parent page.
|
|
// **
|
|
// ** pCur->idx is set to the cell index that contains the pointer
|
|
// ** to the page we are coming from. If we are coming from the
|
|
// ** right-most child page then pCur->idx is set to one more than
|
|
// ** the largest cell index.
|
|
// */
|
|
func _moveToParent(tls *libc.TLS, pCur uintptr) {
|
|
var pLeaf, v1 uintptr
|
|
var v2 Ti8
|
|
_, _, _ = pLeaf, v1, v2
|
|
(*TBtCursor)(unsafe.Pointer(pCur)).Finfo.FnSize = uint16(0)
|
|
v1 = pCur + 1
|
|
*(*Tu8)(unsafe.Pointer(v1)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v1))) & ^(libc.Int32FromInt32(BTCF_ValidNKey) | libc.Int32FromInt32(BTCF_ValidOvfl)))
|
|
(*TBtCursor)(unsafe.Pointer(pCur)).Fix = **(**Tu16)(__ccgo_up(pCur + 72 + uintptr(int32((*TBtCursor)(unsafe.Pointer(pCur)).FiPage)-int32(1))*2))
|
|
pLeaf = (*TBtCursor)(unsafe.Pointer(pCur)).FpPage
|
|
v1 = pCur + 68
|
|
*(*Ti8)(unsafe.Pointer(v1)) = *(*Ti8)(unsafe.Pointer(v1)) - 1
|
|
v2 = *(*Ti8)(unsafe.Pointer(v1))
|
|
(*TBtCursor)(unsafe.Pointer(pCur)).FpPage = **(**uintptr)(__ccgo_up(pCur + 120 + uintptr(v2)*4))
|
|
_releasePageNotNull(tls, pLeaf)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Remove node pNode from the node hash table.
|
|
// */
|
|
func _nodeHashDelete(tls *libc.TLS, pRtree uintptr, pNode uintptr) {
|
|
var pp uintptr
|
|
_ = pp
|
|
if (*TRtreeNode)(unsafe.Pointer(pNode)).FiNode != 0 {
|
|
pp = pRtree + 120 + uintptr(_nodeHash(tls, (*TRtreeNode)(unsafe.Pointer(pNode)).FiNode))*4
|
|
for {
|
|
if !(**(**uintptr)(__ccgo_up(pp)) != pNode) {
|
|
break
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
pp = **(**uintptr)(__ccgo_up(pp)) + 28
|
|
}
|
|
**(**uintptr)(__ccgo_up(pp)) = (*TRtreeNode)(unsafe.Pointer(pNode)).FpNext
|
|
(*TRtreeNode)(unsafe.Pointer(pNode)).FpNext = uintptr(0)
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Search the node hash table for node iNode. If found, return a pointer
|
|
// ** to it. Otherwise, return 0.
|
|
// */
|
|
func _nodeHashLookup(tls *libc.TLS, pRtree uintptr, iNode Ti64) (r uintptr) {
|
|
var p uintptr
|
|
_ = p
|
|
p = **(**uintptr)(__ccgo_up(pRtree + 120 + uintptr(_nodeHash(tls, iNode))*4))
|
|
for {
|
|
if !(p != 0 && (*TRtreeNode)(unsafe.Pointer(p)).FiNode != iNode) {
|
|
break
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
p = (*TRtreeNode)(unsafe.Pointer(p)).FpNext
|
|
}
|
|
return p
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Write page pPg onto the end of the rollback journal.
|
|
// */
|
|
func _pagerAddPageToRollbackJournal(tls *libc.TLS, pPg uintptr) (r int32) {
|
|
var cksum Tu32
|
|
var iOff Ti64
|
|
var pData2, pPager, v1 uintptr
|
|
var rc int32
|
|
_, _, _, _, _, _ = cksum, iOff, pData2, pPager, rc, v1
|
|
pPager = (*TPgHdr)(unsafe.Pointer(pPg)).FpPager
|
|
iOff = (*TPager)(unsafe.Pointer(pPager)).FjournalOff
|
|
/* We should never write to the journal file the page that
|
|
** contains the database locks. The following assert verifies
|
|
** that we do not. */
|
|
pData2 = (*TPgHdr)(unsafe.Pointer(pPg)).FpData
|
|
cksum = _pager_cksum(tls, pPager, pData2)
|
|
/* Even if an IO or diskfull error occurs while journalling the
|
|
** page in the block above, set the need-sync flag for the page.
|
|
** Otherwise, when the transaction is rolled back, the logic in
|
|
** playback_one_page() will think that the page needs to be restored
|
|
** in the database file. And if an IO error occurs while doing so,
|
|
** then corruption may follow.
|
|
*/
|
|
v1 = pPg + 28
|
|
*(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) | libc.Int32FromInt32(PGHDR_NEED_SYNC))
|
|
rc = _write32bits(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd, iOff, (*TPgHdr)(unsafe.Pointer(pPg)).Fpgno)
|
|
if rc != SQLITE_OK {
|
|
return rc
|
|
}
|
|
rc = _sqlite3OsWrite(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd, pData2, int32((*TPager)(unsafe.Pointer(pPager)).FpageSize), iOff+int64(4))
|
|
if rc != SQLITE_OK {
|
|
return rc
|
|
}
|
|
rc = _write32bits(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd, iOff+(*TPager)(unsafe.Pointer(pPager)).FpageSize+int64(4), cksum)
|
|
if rc != SQLITE_OK {
|
|
return rc
|
|
}
|
|
**(**Ti64)(__ccgo_up(pPager + 80)) += int64(8) + (*TPager)(unsafe.Pointer(pPager)).FpageSize
|
|
(*TPager)(unsafe.Pointer(pPager)).FnRec = (*TPager)(unsafe.Pointer(pPager)).FnRec + 1
|
|
rc = _sqlite3BitvecSet(tls, (*TPager)(unsafe.Pointer(pPager)).FpInJournal, (*TPgHdr)(unsafe.Pointer(pPg)).Fpgno)
|
|
rc = rc | _addToSavepointBitvecs(tls, pPager, (*TPgHdr)(unsafe.Pointer(pPg)).Fpgno)
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This function is called before attempting a hot-journal rollback. It
|
|
// ** syncs the journal file to disk, then sets pPager->journalHdr to the
|
|
// ** size of the journal file so that the pager_playback() routine knows
|
|
// ** that the entire journal file has been synced.
|
|
// **
|
|
// ** Syncing a hot-journal to disk before attempting to roll it back ensures
|
|
// ** that if a power-failure occurs during the rollback, the process that
|
|
// ** attempts rollback following system recovery sees the same journal
|
|
// ** content as this process.
|
|
// **
|
|
// ** If everything goes as planned, SQLITE_OK is returned. Otherwise,
|
|
// ** an SQLite error code.
|
|
// */
|
|
func _pagerSyncHotJournal(tls *libc.TLS, pPager uintptr) (r int32) {
|
|
var rc int32
|
|
_ = rc
|
|
rc = SQLITE_OK
|
|
if !((*TPager)(unsafe.Pointer(pPager)).FnoSync != 0) {
|
|
rc = _sqlite3OsSync(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd, int32(SQLITE_SYNC_NORMAL))
|
|
}
|
|
if rc == SQLITE_OK {
|
|
rc = _sqlite3OsFileSize(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd, pPager+88)
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This routine is called to increment the value of the database file
|
|
// ** change-counter, stored as a 4-byte big-endian integer starting at
|
|
// ** byte offset 24 of the pager file. The secondary change counter at
|
|
// ** 92 is also updated, as is the SQLite version number at offset 96.
|
|
// **
|
|
// ** But this only happens if the pPager->changeCountDone flag is false.
|
|
// ** To avoid excess churning of page 1, the update only happens once.
|
|
// ** See also the pager_write_changecounter() routine that does an
|
|
// ** unconditional update of the change counters.
|
|
// **
|
|
// ** If the isDirectMode flag is zero, then this is done by calling
|
|
// ** sqlite3PagerWrite() on page 1, then modifying the contents of the
|
|
// ** page data. In this case the file will be updated when the current
|
|
// ** transaction is committed.
|
|
// **
|
|
// ** The isDirectMode flag may only be non-zero if the library was compiled
|
|
// ** with the SQLITE_ENABLE_ATOMIC_WRITE macro defined. In this case,
|
|
// ** if isDirect is non-zero, then the database file is updated directly
|
|
// ** by writing an updated version of page 1 using a call to the
|
|
// ** sqlite3OsWrite() function.
|
|
// */
|
|
func _pager_incr_changecounter(tls *libc.TLS, pPager uintptr, isDirectMode int32) (r int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var pCopy, zBuf uintptr
|
|
var rc int32
|
|
var _ /* pPgHdr at bp+0 */ uintptr
|
|
_, _, _ = pCopy, rc, zBuf
|
|
rc = SQLITE_OK
|
|
/* Declare and initialize constant integer 'isDirect'. If the
|
|
** atomic-write optimization is enabled in this build, then isDirect
|
|
** is initialized to the value passed as the isDirectMode parameter
|
|
** to this function. Otherwise, it is always set to zero.
|
|
**
|
|
** The idea is that if the atomic-write optimization is not
|
|
** enabled at compile time, the compiler can omit the tests of
|
|
** 'isDirect' below, as well as the block enclosed in the
|
|
** "if( isDirect )" condition.
|
|
*/
|
|
_ = isDirectMode
|
|
if !((*TPager)(unsafe.Pointer(pPager)).FchangeCountDone != 0) && (*TPager)(unsafe.Pointer(pPager)).FdbSize > uint32(0) { /* Reference to page 1 */
|
|
/* Open page 1 of the file for writing. */
|
|
rc = _sqlite3PagerGet(tls, pPager, uint32(1), bp, 0)
|
|
/* If page one was fetched successfully, and this function is not
|
|
** operating in direct-mode, make page 1 writable. When not in
|
|
** direct mode, page 1 is always held in cache and hence the PagerGet()
|
|
** above is always successful - hence the ALWAYS on rc==SQLITE_OK.
|
|
*/
|
|
if libc.Bool(!(libc.Int32FromInt32(DIRECT_MODE) != 0)) && rc == SQLITE_OK {
|
|
rc = _sqlite3PagerWrite(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
}
|
|
if rc == SQLITE_OK {
|
|
/* Actually do the update of the change counter */
|
|
_pager_write_changecounter(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
/* If running in direct mode, write the contents of page 1 to the file. */
|
|
if DIRECT_MODE != 0 {
|
|
zBuf = (*TPgHdr)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FpData
|
|
if rc == SQLITE_OK {
|
|
rc = _sqlite3OsWrite(tls, (*TPager)(unsafe.Pointer(pPager)).Ffd, zBuf, int32((*TPager)(unsafe.Pointer(pPager)).FpageSize), 0)
|
|
**(**Tu32)(__ccgo_up(pPager + 200 + 2*4)) = **(**Tu32)(__ccgo_up(pPager + 200 + 2*4)) + 1
|
|
}
|
|
if rc == SQLITE_OK {
|
|
/* Update the pager's copy of the change-counter. Otherwise, the
|
|
** next time a read transaction is opened the cache will be
|
|
** flushed (as the change-counter values will not match). */
|
|
pCopy = zBuf + 24
|
|
libc.Xmemcpy(tls, pPager+112, pCopy, uint32(16))
|
|
(*TPager)(unsafe.Pointer(pPager)).FchangeCountDone = uint8(1)
|
|
}
|
|
} else {
|
|
(*TPager)(unsafe.Pointer(pPager)).FchangeCountDone = uint8(1)
|
|
}
|
|
}
|
|
/* Release the page reference. */
|
|
_sqlite3PagerUnref(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Update the value of the change-counter at offsets 24 and 92 in
|
|
// ** the header and the sqlite version number at offset 96.
|
|
// **
|
|
// ** This is an unconditional update. See also the pager_incr_changecounter()
|
|
// ** routine which only updates the change-counter if the update is actually
|
|
// ** needed, as determined by the pPager->changeCountDone state variable.
|
|
// */
|
|
func _pager_write_changecounter(tls *libc.TLS, pPg uintptr) {
|
|
var change_counter Tu32
|
|
_ = change_counter
|
|
if pPg == uintptr(0) {
|
|
return
|
|
}
|
|
/* Increment the value just read and write it back to byte 24. */
|
|
change_counter = _sqlite3Get4byte(tls, (*TPgHdr)(unsafe.Pointer(pPg)).FpPager+112) + uint32(1)
|
|
_sqlite3Put4byte(tls, (*TPgHdr)(unsafe.Pointer(pPg)).FpData+uintptr(24), change_counter)
|
|
/* Also store the SQLite version number in bytes 96..99 and in
|
|
** bytes 92..95 store the change counter for which the version number
|
|
** is valid. */
|
|
_sqlite3Put4byte(tls, (*TPgHdr)(unsafe.Pointer(pPg)).FpData+uintptr(92), change_counter)
|
|
_sqlite3Put4byte(tls, (*TPgHdr)(unsafe.Pointer(pPg)).FpData+uintptr(96), uint32(SQLITE_VERSION_NUMBER))
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /* Return an integer that is the maximum allowed stack size */
|
|
func _parserStackSizeLimit(tls *libc.TLS, pParse uintptr) (r int32) {
|
|
return **(**int32)(__ccgo_up((*TParse)(unsafe.Pointer(pParse)).Fdb + 120 + 12*4))
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Allocate and return an RBU handle with all fields zeroed except for the
|
|
// ** error code, which is set to SQLITE_MISUSE.
|
|
// */
|
|
func _rbuMisuseError(tls *libc.TLS) (r uintptr) {
|
|
var pRet uintptr
|
|
_ = pRet
|
|
pRet = Xsqlite3_malloc64(tls, uint64(264))
|
|
if pRet != 0 {
|
|
libc.Xmemset(tls, pRet, 0, uint32(264))
|
|
(*Tsqlite3rbu)(unsafe.Pointer(pRet)).Frc = int32(SQLITE_MISUSE)
|
|
}
|
|
return pRet
|
|
}
|
|
|
|
func _rbuTmpInsertFunc(tls *libc.TLS, pCtx uintptr, nVal int32, apVal uintptr) {
|
|
var i, rc int32
|
|
var p uintptr
|
|
_, _, _ = i, p, rc
|
|
p = Xsqlite3_user_data(tls, pCtx)
|
|
rc = SQLITE_OK
|
|
if Xsqlite3_value_int(tls, **(**uintptr)(__ccgo_up(apVal))) != 0 {
|
|
**(**Ti64)(__ccgo_up(p + 184)) += int64((*Tsqlite3rbu)(unsafe.Pointer(p)).Fobjiter.FnIndex)
|
|
}
|
|
i = 0
|
|
for {
|
|
if !(rc == SQLITE_OK && i < nVal) {
|
|
break
|
|
}
|
|
rc = Xsqlite3_bind_value(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).Fobjiter.FpTmpInsert, i+int32(1), **(**uintptr)(__ccgo_up(apVal + uintptr(i)*4)))
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
if rc == SQLITE_OK {
|
|
Xsqlite3_step(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).Fobjiter.FpTmpInsert)
|
|
rc = Xsqlite3_reset(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).Fobjiter.FpTmpInsert)
|
|
}
|
|
if rc != SQLITE_OK {
|
|
Xsqlite3_result_error_code(tls, pCtx, rc)
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// */
|
|
func _rbuUpdateTempSize(tls *libc.TLS, pFd uintptr, nNew Tsqlite3_int64) (r int32) {
|
|
var nDiff Ti64
|
|
var pRbu uintptr
|
|
_, _ = nDiff, pRbu
|
|
pRbu = (*Trbu_file)(unsafe.Pointer(pFd)).FpRbu
|
|
nDiff = nNew - (*Trbu_file)(unsafe.Pointer(pFd)).Fsz
|
|
**(**Ti64)(__ccgo_up(pRbu + 240)) += nDiff
|
|
(*Trbu_file)(unsafe.Pointer(pFd)).Fsz = nNew
|
|
if (*Tsqlite3rbu)(unsafe.Pointer(pRbu)).FszTempLimit != 0 && (*Tsqlite3rbu)(unsafe.Pointer(pRbu)).FszTemp > (*Tsqlite3rbu)(unsafe.Pointer(pRbu)).FszTempLimit {
|
|
return int32(SQLITE_FULL)
|
|
}
|
|
return SQLITE_OK
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Remove connection db from the blocked connections list. If connection
|
|
// ** db is not currently a part of the list, this function is a no-op.
|
|
// */
|
|
func _removeFromBlockedList(tls *libc.TLS, db uintptr) {
|
|
var pp uintptr
|
|
_ = pp
|
|
pp = uintptr(unsafe.Pointer(&_sqlite3BlockedList))
|
|
for {
|
|
if !(**(**uintptr)(__ccgo_up(pp)) != 0) {
|
|
break
|
|
}
|
|
if **(**uintptr)(__ccgo_up(pp)) == db {
|
|
**(**uintptr)(__ccgo_up(pp)) = (*Tsqlite3)(unsafe.Pointer(**(**uintptr)(__ccgo_up(pp)))).FpNextBlocked
|
|
break
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
pp = **(**uintptr)(__ccgo_up(pp)) + 576
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Reset a cursor back to its initial state.
|
|
// */
|
|
func _resetCursor(tls *libc.TLS, pCsr uintptr) {
|
|
var i, ii int32
|
|
var pInfo, pRtree, pStmt uintptr
|
|
_, _, _, _, _ = i, ii, pInfo, pRtree, pStmt
|
|
pRtree = (*TRtreeCursor)(unsafe.Pointer(pCsr)).Fbase.FpVtab
|
|
if (*TRtreeCursor)(unsafe.Pointer(pCsr)).FaConstraint != 0 { /* Used to iterate through constraint array */
|
|
i = 0
|
|
for {
|
|
if !(i < (*TRtreeCursor)(unsafe.Pointer(pCsr)).FnConstraint) {
|
|
break
|
|
}
|
|
pInfo = (**(**TRtreeConstraint)(__ccgo_up((*TRtreeCursor)(unsafe.Pointer(pCsr)).FaConstraint + uintptr(i)*24))).FpInfo
|
|
if pInfo != 0 {
|
|
if (*Tsqlite3_rtree_query_info)(unsafe.Pointer(pInfo)).FxDelUser != 0 {
|
|
(*(*func(*libc.TLS, uintptr))(unsafe.Pointer(&struct{ uintptr }{(*Tsqlite3_rtree_query_info)(unsafe.Pointer(pInfo)).FxDelUser})))(tls, (*Tsqlite3_rtree_query_info)(unsafe.Pointer(pInfo)).FpUser)
|
|
}
|
|
Xsqlite3_free(tls, pInfo)
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
Xsqlite3_free(tls, (*TRtreeCursor)(unsafe.Pointer(pCsr)).FaConstraint)
|
|
(*TRtreeCursor)(unsafe.Pointer(pCsr)).FaConstraint = uintptr(0)
|
|
}
|
|
ii = 0
|
|
for {
|
|
if !(ii < int32(RTREE_CACHE_SZ)) {
|
|
break
|
|
}
|
|
_nodeRelease(tls, pRtree, **(**uintptr)(__ccgo_up(pCsr + 64 + uintptr(ii)*4)))
|
|
goto _2
|
|
_2:
|
|
;
|
|
ii = ii + 1
|
|
}
|
|
Xsqlite3_free(tls, (*TRtreeCursor)(unsafe.Pointer(pCsr)).FaPoint)
|
|
pStmt = (*TRtreeCursor)(unsafe.Pointer(pCsr)).FpReadAux
|
|
libc.Xmemset(tls, pCsr, 0, uint32(256))
|
|
(*TRtreeCursor)(unsafe.Pointer(pCsr)).Fbase.FpVtab = pRtree
|
|
(*TRtreeCursor)(unsafe.Pointer(pCsr)).FpReadAux = pStmt
|
|
/* The following will only fail if the previous sqlite3_step() call failed,
|
|
** in which case the error has already been caught. This statement never
|
|
** encounters an error within an sqlite3_column_xxx() function, as it
|
|
** calls sqlite3_column_value(), which does not use malloc(). So it is safe
|
|
** to ignore the error code here. */
|
|
Xsqlite3_reset(tls, pStmt)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Rtree virtual table module xOpen method.
|
|
// */
|
|
func _rtreeOpen(tls *libc.TLS, pVTab uintptr, ppCursor uintptr) (r int32) {
|
|
var pCsr, pRtree uintptr
|
|
var rc int32
|
|
_, _, _ = pCsr, pRtree, rc
|
|
rc = int32(SQLITE_NOMEM)
|
|
pRtree = pVTab
|
|
pCsr = Xsqlite3_malloc64(tls, uint64(256))
|
|
if pCsr != 0 {
|
|
libc.Xmemset(tls, pCsr, 0, uint32(256))
|
|
(*TRtreeCursor)(unsafe.Pointer(pCsr)).Fbase.FpVtab = pVTab
|
|
rc = SQLITE_OK
|
|
(*TRtree)(unsafe.Pointer(pRtree)).FnCursor = (*TRtree)(unsafe.Pointer(pRtree)).FnCursor + 1
|
|
}
|
|
**(**uintptr)(__ccgo_up(ppCursor)) = pCsr
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Decrement the r-tree reference count. When the reference count reaches
|
|
// ** zero the structure is deleted.
|
|
// */
|
|
func _rtreeRelease(tls *libc.TLS, pRtree uintptr) {
|
|
var i int32
|
|
var pNext uintptr
|
|
_, _ = i, pNext
|
|
(*TRtree)(unsafe.Pointer(pRtree)).FnBusy = (*TRtree)(unsafe.Pointer(pRtree)).FnBusy - 1
|
|
if (*TRtree)(unsafe.Pointer(pRtree)).FnBusy == uint32(0) {
|
|
(*TRtree)(unsafe.Pointer(pRtree)).FinWrTrans = uint8(0)
|
|
_nodeBlobReset(tls, pRtree)
|
|
if (*TRtree)(unsafe.Pointer(pRtree)).FnNodeRef != 0 {
|
|
i = 0
|
|
for {
|
|
if !(i < int32(HASHSIZE)) {
|
|
break
|
|
}
|
|
for **(**uintptr)(__ccgo_up(pRtree + 120 + uintptr(i)*4)) != 0 {
|
|
pNext = (*TRtreeNode)(unsafe.Pointer(**(**uintptr)(__ccgo_up(pRtree + 120 + uintptr(i)*4)))).FpNext
|
|
Xsqlite3_free(tls, **(**uintptr)(__ccgo_up(pRtree + 120 + uintptr(i)*4)))
|
|
**(**uintptr)(__ccgo_up(pRtree + 120 + uintptr(i)*4)) = pNext
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
}
|
|
Xsqlite3_finalize(tls, (*TRtree)(unsafe.Pointer(pRtree)).FpWriteNode)
|
|
Xsqlite3_finalize(tls, (*TRtree)(unsafe.Pointer(pRtree)).FpDeleteNode)
|
|
Xsqlite3_finalize(tls, (*TRtree)(unsafe.Pointer(pRtree)).FpReadRowid)
|
|
Xsqlite3_finalize(tls, (*TRtree)(unsafe.Pointer(pRtree)).FpWriteRowid)
|
|
Xsqlite3_finalize(tls, (*TRtree)(unsafe.Pointer(pRtree)).FpDeleteRowid)
|
|
Xsqlite3_finalize(tls, (*TRtree)(unsafe.Pointer(pRtree)).FpReadParent)
|
|
Xsqlite3_finalize(tls, (*TRtree)(unsafe.Pointer(pRtree)).FpWriteParent)
|
|
Xsqlite3_finalize(tls, (*TRtree)(unsafe.Pointer(pRtree)).FpDeleteParent)
|
|
Xsqlite3_finalize(tls, (*TRtree)(unsafe.Pointer(pRtree)).FpWriteAux)
|
|
Xsqlite3_free(tls, (*TRtree)(unsafe.Pointer(pRtree)).FzReadAuxSql)
|
|
Xsqlite3_free(tls, pRtree)
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Interchange two search points in a cursor.
|
|
// */
|
|
func _rtreeSearchPointSwap(tls *libc.TLS, p uintptr, i int32, j int32) {
|
|
var pTemp uintptr
|
|
var t TRtreeSearchPoint
|
|
_, _ = pTemp, t
|
|
t = **(**TRtreeSearchPoint)(__ccgo_up((*TRtreeCursor)(unsafe.Pointer(p)).FaPoint + uintptr(i)*24))
|
|
**(**TRtreeSearchPoint)(__ccgo_up((*TRtreeCursor)(unsafe.Pointer(p)).FaPoint + uintptr(i)*24)) = **(**TRtreeSearchPoint)(__ccgo_up((*TRtreeCursor)(unsafe.Pointer(p)).FaPoint + uintptr(j)*24))
|
|
**(**TRtreeSearchPoint)(__ccgo_up((*TRtreeCursor)(unsafe.Pointer(p)).FaPoint + uintptr(j)*24)) = t
|
|
i = i + 1
|
|
j = j + 1
|
|
if i < int32(RTREE_CACHE_SZ) {
|
|
if j >= int32(RTREE_CACHE_SZ) {
|
|
_nodeRelease(tls, (*TRtreeCursor)(unsafe.Pointer(p)).Fbase.FpVtab, **(**uintptr)(__ccgo_up(p + 64 + uintptr(i)*4)))
|
|
**(**uintptr)(__ccgo_up(p + 64 + uintptr(i)*4)) = uintptr(0)
|
|
} else {
|
|
pTemp = **(**uintptr)(__ccgo_up(p + 64 + uintptr(i)*4))
|
|
**(**uintptr)(__ccgo_up(p + 64 + uintptr(i)*4)) = **(**uintptr)(__ccgo_up(p + 64 + uintptr(j)*4))
|
|
**(**uintptr)(__ccgo_up(p + 64 + uintptr(j)*4)) = pTemp
|
|
}
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Field iChng of the index being scanned has changed. So at this point
|
|
// ** p->current contains a sample that reflects the previous row of the
|
|
// ** index. The value of anEq[iChng] and subsequent anEq[] elements are
|
|
// ** correct at this point.
|
|
// */
|
|
func _samplePushPrevious(tls *libc.TLS, p uintptr, iChng int32) {
|
|
var i, j, j1 int32
|
|
var pBest uintptr
|
|
_, _, _, _ = i, j, j1, pBest
|
|
/* Check if any samples from the aBest[] array should be pushed
|
|
** into IndexSample.a[] at this point. */
|
|
i = (*TStatAccum)(unsafe.Pointer(p)).FnCol - int32(2)
|
|
for {
|
|
if !(i >= iChng) {
|
|
break
|
|
}
|
|
pBest = (*TStatAccum)(unsafe.Pointer(p)).FaBest + uintptr(i)*40
|
|
**(**TtRowcnt)(__ccgo_up((*TStatSample)(unsafe.Pointer(pBest)).FanEq + uintptr(i)*8)) = **(**TtRowcnt)(__ccgo_up((*TStatAccum)(unsafe.Pointer(p)).Fcurrent.FanEq + uintptr(i)*8))
|
|
if (*TStatAccum)(unsafe.Pointer(p)).FnSample < (*TStatAccum)(unsafe.Pointer(p)).FmxSample || _sampleIsBetter(tls, p, pBest, (*TStatAccum)(unsafe.Pointer(p)).Fa+uintptr((*TStatAccum)(unsafe.Pointer(p)).FiMin)*40) != 0 {
|
|
_sampleInsert(tls, p, pBest, i)
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i - 1
|
|
}
|
|
/* Check that no sample contains an anEq[] entry with an index of
|
|
** p->nMaxEqZero or greater set to zero. */
|
|
i = (*TStatAccum)(unsafe.Pointer(p)).FnSample - int32(1)
|
|
for {
|
|
if !(i >= 0) {
|
|
break
|
|
}
|
|
j = (*TStatAccum)(unsafe.Pointer(p)).FnMaxEqZero
|
|
for {
|
|
if !(j < (*TStatAccum)(unsafe.Pointer(p)).FnCol) {
|
|
break
|
|
}
|
|
goto _3
|
|
_3:
|
|
;
|
|
j = j + 1
|
|
}
|
|
goto _2
|
|
_2:
|
|
;
|
|
i = i - 1
|
|
}
|
|
/* Update the anEq[] fields of any samples already collected. */
|
|
if iChng < (*TStatAccum)(unsafe.Pointer(p)).FnMaxEqZero {
|
|
i = (*TStatAccum)(unsafe.Pointer(p)).FnSample - int32(1)
|
|
for {
|
|
if !(i >= 0) {
|
|
break
|
|
}
|
|
j1 = iChng
|
|
for {
|
|
if !(j1 < (*TStatAccum)(unsafe.Pointer(p)).FnCol) {
|
|
break
|
|
}
|
|
if **(**TtRowcnt)(__ccgo_up((**(**TStatSample)(__ccgo_up((*TStatAccum)(unsafe.Pointer(p)).Fa + uintptr(i)*40))).FanEq + uintptr(j1)*8)) == uint64(0) {
|
|
**(**TtRowcnt)(__ccgo_up((**(**TStatSample)(__ccgo_up((*TStatAccum)(unsafe.Pointer(p)).Fa + uintptr(i)*40))).FanEq + uintptr(j1)*8)) = **(**TtRowcnt)(__ccgo_up((*TStatAccum)(unsafe.Pointer(p)).Fcurrent.FanEq + uintptr(j1)*8))
|
|
}
|
|
goto _5
|
|
_5:
|
|
;
|
|
j1 = j1 + 1
|
|
}
|
|
goto _4
|
|
_4:
|
|
;
|
|
i = i - 1
|
|
}
|
|
(*TStatAccum)(unsafe.Pointer(p)).FnMaxEqZero = iChng
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /* Initialize the INTEGER value of a ROWID.
|
|
// */
|
|
func _sampleSetRowidInt64(tls *libc.TLS, db uintptr, p uintptr, iRowid Ti64) {
|
|
if (*TStatSample)(unsafe.Pointer(p)).FnRowid != 0 {
|
|
_sqlite3DbFree(tls, db, *(*uintptr)(unsafe.Pointer(&(*TStatSample)(unsafe.Pointer(p)).Fu)))
|
|
}
|
|
(*TStatSample)(unsafe.Pointer(p)).FnRowid = uint32(0)
|
|
*(*Ti64)(unsafe.Pointer(p + 16)) = iRowid
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Look through the list of open database files in db->aDb[] and if
|
|
// ** any have been closed, remove them from the list. Reallocate the
|
|
// ** db->aDb[] structure to a smaller size, if possible.
|
|
// **
|
|
// ** Entry 0 (the "main" database) and entry 1 (the "temp" database)
|
|
// ** are never candidates for being collapsed.
|
|
// */
|
|
func _sqlite3CollapseDatabaseArray(tls *libc.TLS, db uintptr) {
|
|
var i, j, v2 int32
|
|
var pDb uintptr
|
|
_, _, _, _ = i, j, pDb, v2
|
|
v2 = libc.Int32FromInt32(2)
|
|
j = v2
|
|
i = v2
|
|
for {
|
|
if !(i < (*Tsqlite3)(unsafe.Pointer(db)).FnDb) {
|
|
break
|
|
}
|
|
pDb = (*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(i)*16
|
|
if (*TDb)(unsafe.Pointer(pDb)).FpBt == uintptr(0) {
|
|
_sqlite3DbFree(tls, db, (*TDb)(unsafe.Pointer(pDb)).FzDbSName)
|
|
(*TDb)(unsafe.Pointer(pDb)).FzDbSName = uintptr(0)
|
|
goto _1
|
|
}
|
|
if j < i {
|
|
**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(j)*16)) = **(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(i)*16))
|
|
}
|
|
j = j + 1
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
(*Tsqlite3)(unsafe.Pointer(db)).FnDb = j
|
|
if (*Tsqlite3)(unsafe.Pointer(db)).FnDb <= int32(2) && (*Tsqlite3)(unsafe.Pointer(db)).FaDb != db+476 {
|
|
libc.Xmemcpy(tls, db+476, (*Tsqlite3)(unsafe.Pointer(db)).FaDb, libc.Uint32FromInt32(2)*libc.Uint32FromInt64(16))
|
|
_sqlite3DbFree(tls, db, (*Tsqlite3)(unsafe.Pointer(db)).FaDb)
|
|
(*Tsqlite3)(unsafe.Pointer(db)).FaDb = db + 476
|
|
}
|
|
}
|
|
|
|
func _sqlite3DbMallocRawNN(tls *libc.TLS, db uintptr, n Tu64) (r uintptr) {
|
|
var pBuf, v1 uintptr
|
|
_, _ = pBuf, v1
|
|
if n > uint64((*Tsqlite3)(unsafe.Pointer(db)).Flookaside.Fsz) {
|
|
if !((*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FbDisable != 0) {
|
|
**(**Tu32)(__ccgo_up(db + 320 + 16 + 1*4)) = **(**Tu32)(__ccgo_up(db + 320 + 16 + 1*4)) + 1
|
|
} else {
|
|
if (*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0 {
|
|
return uintptr(0)
|
|
}
|
|
}
|
|
return _dbMallocRawFinish(tls, db, n)
|
|
}
|
|
if n <= uint64(LOOKASIDE_SMALL) {
|
|
v1 = (*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpSmallFree
|
|
pBuf = v1
|
|
if v1 != uintptr(0) {
|
|
(*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpSmallFree = (*TLookasideSlot)(unsafe.Pointer(pBuf)).FpNext
|
|
**(**Tu32)(__ccgo_up(db + 320 + 16)) = **(**Tu32)(__ccgo_up(db + 320 + 16)) + 1
|
|
return pBuf
|
|
} else {
|
|
v1 = (*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpSmallInit
|
|
pBuf = v1
|
|
if v1 != uintptr(0) {
|
|
(*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpSmallInit = (*TLookasideSlot)(unsafe.Pointer(pBuf)).FpNext
|
|
**(**Tu32)(__ccgo_up(db + 320 + 16)) = **(**Tu32)(__ccgo_up(db + 320 + 16)) + 1
|
|
return pBuf
|
|
}
|
|
}
|
|
}
|
|
v1 = (*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpFree
|
|
pBuf = v1
|
|
if v1 != uintptr(0) {
|
|
(*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpFree = (*TLookasideSlot)(unsafe.Pointer(pBuf)).FpNext
|
|
**(**Tu32)(__ccgo_up(db + 320 + 16)) = **(**Tu32)(__ccgo_up(db + 320 + 16)) + 1
|
|
return pBuf
|
|
} else {
|
|
v1 = (*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpInit
|
|
pBuf = v1
|
|
if v1 != uintptr(0) {
|
|
(*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FpInit = (*TLookasideSlot)(unsafe.Pointer(pBuf)).FpNext
|
|
**(**Tu32)(__ccgo_up(db + 320 + 16)) = **(**Tu32)(__ccgo_up(db + 320 + 16)) + 1
|
|
return pBuf
|
|
} else {
|
|
**(**Tu32)(__ccgo_up(db + 320 + 16 + 2*4)) = **(**Tu32)(__ccgo_up(db + 320 + 16 + 2*4)) + 1
|
|
}
|
|
}
|
|
return _dbMallocRawFinish(tls, db, n)
|
|
}
|
|
|
|
func _sqlite3Fts5IndexOptimize(tls *libc.TLS, p uintptr) (r int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var iLvl int32
|
|
var pStruct uintptr
|
|
var _ /* nRem at bp+4 */ int32
|
|
var _ /* pNew at bp+0 */ uintptr
|
|
_, _ = iLvl, pStruct
|
|
**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
|
|
_fts5IndexFlush(tls, p)
|
|
pStruct = _fts5StructureRead(tls, p)
|
|
_fts5StructureInvalidate(tls, p)
|
|
if pStruct != 0 {
|
|
**(**uintptr)(__ccgo_up(bp)) = _fts5IndexOptimizeStruct(tls, p, pStruct)
|
|
}
|
|
_fts5StructureRelease(tls, pStruct)
|
|
if **(**uintptr)(__ccgo_up(bp)) != 0 {
|
|
iLvl = 0
|
|
for {
|
|
if !((*(*TFts5StructureLevel)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)) + 32 + uintptr(iLvl)*12))).FnSeg == 0) {
|
|
break
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
iLvl = iLvl + 1
|
|
}
|
|
for (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK && (*(*TFts5StructureLevel)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)) + 32 + uintptr(iLvl)*12))).FnSeg > 0 {
|
|
**(**int32)(__ccgo_up(bp + 4)) = int32(FTS5_OPT_WORK_UNIT)
|
|
_fts5IndexMergeLevel(tls, p, bp, iLvl, bp+4)
|
|
}
|
|
_fts5StructureWrite(tls, p, **(**uintptr)(__ccgo_up(bp)))
|
|
_fts5StructureRelease(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
}
|
|
return _fts5IndexReturn(tls, p)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This is used by xInstToken() to access the token at offset iOff, column
|
|
// ** iCol of row iRowid. The token is returned via output variables *ppOut
|
|
// ** and *pnOut. The iterator passed as the first argument must be a tokendata=1
|
|
// ** iterator (pIter->pTokenDataIter!=0).
|
|
// **
|
|
// ** pToken/nToken:
|
|
// */
|
|
func _sqlite3Fts5IterToken(tls *libc.TLS, pIndexIter uintptr, pToken uintptr, nToken int32, iRowid Ti64, iCol int32, iOff int32, ppOut uintptr, pnOut uintptr) (r int32) {
|
|
var aMap, p, pIter, pMap, pT uintptr
|
|
var i1, i2, iTest, rc int32
|
|
var iPos Ti64
|
|
_, _, _, _, _, _, _, _, _, _ = aMap, i1, i2, iPos, iTest, p, pIter, pMap, pT, rc
|
|
pIter = pIndexIter
|
|
pT = (*TFts5Iter)(unsafe.Pointer(pIter)).FpTokenDataIter
|
|
iPos = int64(iCol)<<libc.Int32FromInt32(32) + int64(iOff)
|
|
aMap = uintptr(0)
|
|
i1 = 0
|
|
i2 = 0
|
|
iTest = 0
|
|
if pT == uintptr(0) {
|
|
rc = _fts5SetupPrefixIterTokendata(tls, pIter, pToken, nToken)
|
|
if rc != SQLITE_OK {
|
|
return rc
|
|
}
|
|
pT = (*TFts5Iter)(unsafe.Pointer(pIter)).FpTokenDataIter
|
|
}
|
|
i2 = int32((*TFts5TokenDataIter)(unsafe.Pointer(pT)).FnMap)
|
|
aMap = (*TFts5TokenDataIter)(unsafe.Pointer(pT)).FaMap
|
|
for i2 > i1 {
|
|
iTest = (i1 + i2) / int32(2)
|
|
if (**(**TFts5TokenDataMap)(__ccgo_up(aMap + uintptr(iTest)*24))).FiRowid < iRowid {
|
|
i1 = iTest + int32(1)
|
|
} else {
|
|
if (**(**TFts5TokenDataMap)(__ccgo_up(aMap + uintptr(iTest)*24))).FiRowid > iRowid {
|
|
i2 = iTest
|
|
} else {
|
|
if (**(**TFts5TokenDataMap)(__ccgo_up(aMap + uintptr(iTest)*24))).FiPos < iPos {
|
|
if (**(**TFts5TokenDataMap)(__ccgo_up(aMap + uintptr(iTest)*24))).FiPos < 0 {
|
|
break
|
|
}
|
|
i1 = iTest + int32(1)
|
|
} else {
|
|
if (**(**TFts5TokenDataMap)(__ccgo_up(aMap + uintptr(iTest)*24))).FiPos > iPos {
|
|
i2 = iTest
|
|
} else {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if i2 > i1 {
|
|
if (*TFts5Iter)(unsafe.Pointer(pIter)).FnSeg == 0 {
|
|
pMap = *(*uintptr)(unsafe.Pointer(pT + 56 + uintptr((**(**TFts5TokenDataMap)(__ccgo_up(aMap + uintptr(iTest)*24))).FiIter)*4))
|
|
**(**uintptr)(__ccgo_up(ppOut)) = (*(*TFts5SegIter)(unsafe.Pointer(pMap + 80))).Fterm.Fp + uintptr(1)
|
|
**(**int32)(__ccgo_up(pnOut)) = (*(*TFts5SegIter)(unsafe.Pointer(pMap + 80))).Fterm.Fn - int32(1)
|
|
} else {
|
|
p = aMap + uintptr(iTest)*24
|
|
**(**uintptr)(__ccgo_up(ppOut)) = (*TFts5TokenDataIter)(unsafe.Pointer(pT)).Fterms.Fp + uintptr((*TFts5TokenDataMap)(unsafe.Pointer(p)).FiIter)
|
|
**(**int32)(__ccgo_up(pnOut)) = (**(**TFts5TokenDataMap)(__ccgo_up(aMap + uintptr(iTest)*24))).FnByte
|
|
}
|
|
}
|
|
return SQLITE_OK
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Free the expression node object passed as the only argument.
|
|
// */
|
|
func _sqlite3Fts5ParseNodeFree(tls *libc.TLS, p uintptr) {
|
|
var i int32
|
|
_ = i
|
|
if p != 0 {
|
|
i = 0
|
|
for {
|
|
if !(i < (*TFts5ExprNode)(unsafe.Pointer(p)).FnChild) {
|
|
break
|
|
}
|
|
_sqlite3Fts5ParseNodeFree(tls, *(*uintptr)(unsafe.Pointer(p + 40 + uintptr(i)*4)))
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
_sqlite3Fts5ParseNearsetFree(tls, (*TFts5ExprNode)(unsafe.Pointer(p)).FpNear)
|
|
Xsqlite3_free(tls, p)
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Obtain an SQLite statement handle that may be used to read data from the
|
|
// ** %_content table.
|
|
// */
|
|
func _sqlite3Fts5StorageStmt(tls *libc.TLS, p uintptr, eStmt int32, pp uintptr, pzErrMsg uintptr) (r int32) {
|
|
var rc int32
|
|
_ = rc
|
|
rc = _fts5StorageGetStmt(tls, p, eStmt, pp, pzErrMsg)
|
|
if rc == SQLITE_OK {
|
|
**(**uintptr)(__ccgo_up(p + 32 + uintptr(eStmt)*4)) = uintptr(0)
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Release an SQLite statement handle obtained via an earlier call to
|
|
// ** sqlite3Fts5StorageStmt(). The eStmt parameter passed to this function
|
|
// ** must match that passed to the sqlite3Fts5StorageStmt() call.
|
|
// */
|
|
func _sqlite3Fts5StorageStmtRelease(tls *libc.TLS, p uintptr, eStmt int32, pStmt uintptr) {
|
|
if **(**uintptr)(__ccgo_up(p + 32 + uintptr(eStmt)*4)) == uintptr(0) {
|
|
Xsqlite3_reset(tls, pStmt)
|
|
**(**uintptr)(__ccgo_up(p + 32 + uintptr(eStmt)*4)) = pStmt
|
|
} else {
|
|
Xsqlite3_finalize(tls, pStmt)
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Return the number of bytes required to store a JournalFile that uses vfs
|
|
// ** pVfs to create the underlying on-disk files.
|
|
// */
|
|
func _sqlite3JournalSize(tls *libc.TLS, pVfs uintptr) (r int32) {
|
|
var v1 int32
|
|
_ = v1
|
|
if (*Tsqlite3_vfs)(unsafe.Pointer(pVfs)).FszOsFile > libc.Int32FromInt64(64) {
|
|
v1 = (*Tsqlite3_vfs)(unsafe.Pointer(pVfs)).FszOsFile
|
|
} else {
|
|
v1 = libc.Int32FromInt64(64)
|
|
}
|
|
return v1
|
|
}
|
|
|
|
/************** End of memjournal.c ******************************************/
|
|
/************** Begin file walker.c ******************************************/
|
|
/*
|
|
** 2008 August 16
|
|
**
|
|
** 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 routines used for walking the parser tree for
|
|
** an SQL statement.
|
|
*/
|
|
/* #include "sqliteInt.h" */
|
|
/* #include <stdlib.h> */
|
|
/* #include <string.h> */
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Deinitialize the memory allocation subsystem.
|
|
// */
|
|
func _sqlite3MallocEnd(tls *libc.TLS) {
|
|
if _sqlite3Config.Fm.FxShutdown != 0 {
|
|
(*(*func(*libc.TLS, uintptr))(unsafe.Pointer(&struct{ uintptr }{_sqlite3Config.Fm.FxShutdown})))(tls, _sqlite3Config.Fm.FpAppData)
|
|
}
|
|
libc.Xmemset(tls, uintptr(unsafe.Pointer(&_mem0)), 0, uint32(32))
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Initialize the memory allocation subsystem.
|
|
// */
|
|
func _sqlite3MallocInit(tls *libc.TLS) (r int32) {
|
|
var rc int32
|
|
_ = rc
|
|
if _sqlite3Config.Fm.FxMalloc == uintptr(0) {
|
|
_sqlite3MemSetDefault(tls)
|
|
}
|
|
_mem0.Fmutex = _sqlite3MutexAlloc(tls, int32(SQLITE_MUTEX_STATIC_MEM))
|
|
if _sqlite3Config.FpPage == uintptr(0) || _sqlite3Config.FszPage < int32(512) || _sqlite3Config.FnPage <= 0 {
|
|
_sqlite3Config.FpPage = uintptr(0)
|
|
_sqlite3Config.FszPage = 0
|
|
}
|
|
rc = (*(*func(*libc.TLS, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_sqlite3Config.Fm.FxInit})))(tls, _sqlite3Config.Fm.FpAppData)
|
|
if rc != SQLITE_OK {
|
|
libc.Xmemset(tls, uintptr(unsafe.Pointer(&_mem0)), 0, uint32(32))
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Return a pointer to the pPager->pBackup variable. The backup module
|
|
// ** in backup.c maintains the content of this variable. This module
|
|
// ** uses it opaquely as an argument to sqlite3BackupRestart() and
|
|
// ** sqlite3BackupUpdate() only.
|
|
// */
|
|
func _sqlite3PagerBackupPtr(tls *libc.TLS, pPager uintptr) (r uintptr) {
|
|
return pPager + 96
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Parameter eStat must be one of SQLITE_DBSTATUS_CACHE_HIT, _MISS, _WRITE,
|
|
// ** or _WRITE+1. The SQLITE_DBSTATUS_CACHE_WRITE+1 case is a translation
|
|
// ** of SQLITE_DBSTATUS_CACHE_SPILL. The _SPILL case is not contiguous because
|
|
// ** it was added later.
|
|
// **
|
|
// ** Before returning, *pnVal is incremented by the
|
|
// ** current cache hit or miss count, according to the value of eStat. If the
|
|
// ** reset parameter is non-zero, the cache hit or miss count is zeroed before
|
|
// ** returning.
|
|
// */
|
|
func _sqlite3PagerCacheStat(tls *libc.TLS, pPager uintptr, eStat int32, reset int32, pnVal uintptr) {
|
|
eStat = eStat - int32(SQLITE_DBSTATUS_CACHE_HIT)
|
|
**(**Tu64)(__ccgo_up(pnVal)) += uint64(**(**Tu32)(__ccgo_up(pPager + 200 + uintptr(eStat)*4)))
|
|
if reset != 0 {
|
|
**(**Tu32)(__ccgo_up(pPager + 200 + uintptr(eStat)*4)) = uint32(0)
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Set the busy handler function.
|
|
// **
|
|
// ** The pager invokes the busy-handler if sqlite3OsLock() returns
|
|
// ** SQLITE_BUSY when trying to upgrade from no-lock to a SHARED lock,
|
|
// ** or when trying to upgrade from a RESERVED lock to an EXCLUSIVE
|
|
// ** lock. It does *not* invoke the busy handler when upgrading from
|
|
// ** SHARED to RESERVED, or when upgrading from SHARED to EXCLUSIVE
|
|
// ** (which occurs during hot-journal rollback). Summary:
|
|
// **
|
|
// ** Transition | Invokes xBusyHandler
|
|
// ** --------------------------------------------------------
|
|
// ** NO_LOCK -> SHARED_LOCK | Yes
|
|
// ** SHARED_LOCK -> RESERVED_LOCK | No
|
|
// ** SHARED_LOCK -> EXCLUSIVE_LOCK | No
|
|
// ** RESERVED_LOCK -> EXCLUSIVE_LOCK | Yes
|
|
// **
|
|
// ** If the busy-handler callback returns non-zero, the lock is
|
|
// ** retried. If it returns zero, then the SQLITE_BUSY error is
|
|
// ** returned to the caller of the pager API function.
|
|
// */
|
|
func _sqlite3PagerSetBusyHandler(tls *libc.TLS, pPager uintptr, __ccgo_fp_xBusyHandler uintptr, pBusyHandlerArg uintptr) {
|
|
var ap uintptr
|
|
_ = ap
|
|
(*TPager)(unsafe.Pointer(pPager)).FxBusyHandler = __ccgo_fp_xBusyHandler
|
|
(*TPager)(unsafe.Pointer(pPager)).FpBusyHandlerArg = pBusyHandlerArg
|
|
ap = pPager + 192
|
|
_sqlite3OsFileControlHint(tls, (*TPager)(unsafe.Pointer(pPager)).Ffd, int32(SQLITE_FCNTL_BUSYHANDLER), ap)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Return the size in bytes of a PCache object.
|
|
// */
|
|
func _sqlite3PcacheSize(tls *libc.TLS) (r int32) {
|
|
return int32(56)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Check for interrupts and invoke progress callback.
|
|
// */
|
|
func _sqlite3ProgressCheck(tls *libc.TLS, p uintptr) {
|
|
var db, v2 uintptr
|
|
var v1 Tu32
|
|
_, _, _ = db, v1, v2
|
|
db = (*TParse)(unsafe.Pointer(p)).Fdb
|
|
if libc.AtomicLoadNInt32(db+312, libc.Int32FromInt32(__ATOMIC_RELAXED)) != 0 {
|
|
(*TParse)(unsafe.Pointer(p)).FnErr = (*TParse)(unsafe.Pointer(p)).FnErr + 1
|
|
(*TParse)(unsafe.Pointer(p)).Frc = int32(SQLITE_INTERRUPT)
|
|
}
|
|
if (*Tsqlite3)(unsafe.Pointer(db)).FxProgress != 0 {
|
|
if (*TParse)(unsafe.Pointer(p)).Frc == int32(SQLITE_INTERRUPT) {
|
|
(*TParse)(unsafe.Pointer(p)).FnProgressSteps = uint32(0)
|
|
} else {
|
|
v2 = p + 104
|
|
*(*Tu32)(unsafe.Pointer(v2)) = *(*Tu32)(unsafe.Pointer(v2)) + 1
|
|
v1 = *(*Tu32)(unsafe.Pointer(v2))
|
|
if v1 >= (*Tsqlite3)(unsafe.Pointer(db)).FnProgressOps {
|
|
if (*(*func(*libc.TLS, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*Tsqlite3)(unsafe.Pointer(db)).FxProgress})))(tls, (*Tsqlite3)(unsafe.Pointer(db)).FpProgressArg) != 0 {
|
|
(*TParse)(unsafe.Pointer(p)).FnErr = (*TParse)(unsafe.Pointer(p)).FnErr + 1
|
|
(*TParse)(unsafe.Pointer(p)).Frc = int32(SQLITE_INTERRUPT)
|
|
}
|
|
(*TParse)(unsafe.Pointer(p)).FnProgressSteps = uint32(0)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Resolve names in expressions that can only reference a single table
|
|
// ** or which cannot reference any tables at all. Examples:
|
|
// **
|
|
// ** "type" flag
|
|
// ** ------------
|
|
// ** (1) CHECK constraints NC_IsCheck
|
|
// ** (2) WHERE clauses on partial indices NC_PartIdx
|
|
// ** (3) Expressions in indexes on expressions NC_IdxExpr
|
|
// ** (4) Expression arguments to VACUUM INTO. 0
|
|
// ** (5) GENERATED ALWAYS as expressions NC_GenCol
|
|
// **
|
|
// ** In all cases except (4), the Expr.iTable value for Expr.op==TK_COLUMN
|
|
// ** nodes of the expression is set to -1 and the Expr.iColumn value is
|
|
// ** set to the column number. In case (4), TK_COLUMN nodes cause an error.
|
|
// **
|
|
// ** Any errors cause an error message to be set in pParse.
|
|
// */
|
|
func _sqlite3ResolveSelfReference(tls *libc.TLS, pParse uintptr, pTab uintptr, type1 int32, pExpr uintptr, pList uintptr) (r int32) {
|
|
bp := tls.Alloc(96)
|
|
defer tls.Free(96)
|
|
var pSrc uintptr
|
|
var rc, v1 int32
|
|
var _ /* sNC at bp+0 */ TNameContext
|
|
var _ /* uSrc at bp+40 */ struct {
|
|
F__ccgo_align [0]uint32
|
|
FsrcSpace [0][56]Tu8
|
|
FsSrc TSrcList
|
|
F__ccgo_pad2 [48]byte
|
|
}
|
|
_, _, _ = pSrc, rc, v1
|
|
libc.Xmemset(tls, bp, 0, uint32(36))
|
|
libc.Xmemset(tls, bp+40, 0, uint32(56))
|
|
pSrc = bp + 40
|
|
if pTab != 0 {
|
|
(*TSrcList)(unsafe.Pointer(pSrc)).FnSrc = int32(1)
|
|
(*(*TSrcItem)(unsafe.Pointer(pSrc + 8))).FzName = (*TTable)(unsafe.Pointer(pTab)).FzName
|
|
(*(*TSrcItem)(unsafe.Pointer(pSrc + 8))).FpSTab = pTab
|
|
(*(*TSrcItem)(unsafe.Pointer(pSrc + 8))).FiCursor = -int32(1)
|
|
if (*TTable)(unsafe.Pointer(pTab)).FpSchema != (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer((*TParse)(unsafe.Pointer(pParse)).Fdb)).FaDb + 1*16))).FpSchema {
|
|
/* Cause EP_FromDDL to be set on TK_FUNCTION nodes of non-TEMP
|
|
** schema elements */
|
|
type1 = type1 | int32(NC_FromDDL)
|
|
}
|
|
}
|
|
(**(**TNameContext)(__ccgo_up(bp))).FpParse = pParse
|
|
(**(**TNameContext)(__ccgo_up(bp))).FpSrcList = pSrc
|
|
(**(**TNameContext)(__ccgo_up(bp))).FncFlags = type1 | int32(NC_IsDDL)
|
|
v1 = _sqlite3ResolveExprNames(tls, bp, pExpr)
|
|
rc = v1
|
|
if v1 != SQLITE_OK {
|
|
return rc
|
|
}
|
|
if pList != 0 {
|
|
rc = _sqlite3ResolveExprListNames(tls, bp, pList)
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Return the current time for a statement. If the current time
|
|
// ** is requested more than once within the same run of a single prepared
|
|
// ** statement, the exact same time is returned for each invocation regardless
|
|
// ** of the amount of time that elapses between invocations. In other words,
|
|
// ** the time returned is always the time of the first call.
|
|
// */
|
|
func _sqlite3StmtCurrentTime(tls *libc.TLS, p uintptr) (r Tsqlite3_int64) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var piTime, v1 uintptr
|
|
var rc int32
|
|
var _ /* iTime at bp+0 */ Tsqlite3_int64
|
|
_, _, _ = piTime, rc, v1
|
|
**(**Tsqlite3_int64)(__ccgo_up(bp)) = 0
|
|
if (*Tsqlite3_context)(unsafe.Pointer(p)).FpVdbe != uintptr(0) {
|
|
v1 = (*Tsqlite3_context)(unsafe.Pointer(p)).FpVdbe + 56
|
|
} else {
|
|
v1 = bp
|
|
}
|
|
piTime = v1
|
|
if **(**Tsqlite3_int64)(__ccgo_up(piTime)) == 0 {
|
|
rc = _sqlite3OsCurrentTimeInt64(tls, (*Tsqlite3)(unsafe.Pointer((*TMem)(unsafe.Pointer((*Tsqlite3_context)(unsafe.Pointer(p)).FpOut)).Fdb)).FpVfs, piTime)
|
|
if rc != 0 {
|
|
**(**Tsqlite3_int64)(__ccgo_up(piTime)) = 0
|
|
}
|
|
}
|
|
return **(**Tsqlite3_int64)(__ccgo_up(piTime))
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Set a flag in the vdbe to update the change counter when it is finalised
|
|
// ** or reset.
|
|
// */
|
|
func _sqlite3VdbeCountChanges(tls *libc.TLS, v uintptr) {
|
|
libc.SetBitFieldPtr16Uint32(v+152, libc.Uint32FromInt32(1), 4, 0x10)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Create a new virtual database engine.
|
|
// */
|
|
func _sqlite3VdbeCreate(tls *libc.TLS, pParse uintptr) (r uintptr) {
|
|
var db, p uintptr
|
|
_, _ = db, p
|
|
db = (*TParse)(unsafe.Pointer(pParse)).Fdb
|
|
p = _sqlite3DbMallocRawNN(tls, db, uint64(232))
|
|
if p == uintptr(0) {
|
|
return uintptr(0)
|
|
}
|
|
libc.Xmemset(tls, p+104, 0, libc.Uint32FromInt64(232)-uint32(libc.UintptrFromInt32(0)+104))
|
|
(*TVdbe)(unsafe.Pointer(p)).Fdb = db
|
|
if (*Tsqlite3)(unsafe.Pointer(db)).FpVdbe != 0 {
|
|
(*TVdbe)(unsafe.Pointer((*Tsqlite3)(unsafe.Pointer(db)).FpVdbe)).FppVPrev = p + 8
|
|
}
|
|
(*TVdbe)(unsafe.Pointer(p)).FpVNext = (*Tsqlite3)(unsafe.Pointer(db)).FpVdbe
|
|
(*TVdbe)(unsafe.Pointer(p)).FppVPrev = db + 4
|
|
(*Tsqlite3)(unsafe.Pointer(db)).FpVdbe = p
|
|
(*TVdbe)(unsafe.Pointer(p)).FpParse = pParse
|
|
(*TParse)(unsafe.Pointer(pParse)).FpVdbe = p
|
|
_sqlite3VdbeAddOp2(tls, p, int32(OP_Init), 0, int32(1))
|
|
return p
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Copy the values stored in the VdbeFrame structure to its Vdbe. This
|
|
// ** is used, for example, when a trigger sub-program is halted to restore
|
|
// ** control to the main program.
|
|
// */
|
|
func _sqlite3VdbeFrameRestore(tls *libc.TLS, pFrame uintptr) (r int32) {
|
|
var v uintptr
|
|
_ = v
|
|
v = (*TVdbeFrame)(unsafe.Pointer(pFrame)).Fv
|
|
_closeCursorsInFrame(tls, v)
|
|
(*TVdbe)(unsafe.Pointer(v)).FaOp = (*TVdbeFrame)(unsafe.Pointer(pFrame)).FaOp
|
|
(*TVdbe)(unsafe.Pointer(v)).FnOp = (*TVdbeFrame)(unsafe.Pointer(pFrame)).FnOp
|
|
(*TVdbe)(unsafe.Pointer(v)).FaMem = (*TVdbeFrame)(unsafe.Pointer(pFrame)).FaMem
|
|
(*TVdbe)(unsafe.Pointer(v)).FnMem = (*TVdbeFrame)(unsafe.Pointer(pFrame)).FnMem
|
|
(*TVdbe)(unsafe.Pointer(v)).FapCsr = (*TVdbeFrame)(unsafe.Pointer(pFrame)).FapCsr
|
|
(*TVdbe)(unsafe.Pointer(v)).FnCursor = (*TVdbeFrame)(unsafe.Pointer(pFrame)).FnCursor
|
|
(*Tsqlite3)(unsafe.Pointer((*TVdbe)(unsafe.Pointer(v)).Fdb)).FlastRowid = (*TVdbeFrame)(unsafe.Pointer(pFrame)).FlastRowid
|
|
(*TVdbe)(unsafe.Pointer(v)).FnChange = (*TVdbeFrame)(unsafe.Pointer(pFrame)).FnChange
|
|
(*Tsqlite3)(unsafe.Pointer((*TVdbe)(unsafe.Pointer(v)).Fdb)).FnChange = (*TVdbeFrame)(unsafe.Pointer(pFrame)).FnDbChange
|
|
_sqlite3VdbeDeleteAuxData(tls, (*TVdbe)(unsafe.Pointer(v)).Fdb, v+228, -int32(1), 0)
|
|
(*TVdbe)(unsafe.Pointer(v)).FpAuxData = (*TVdbeFrame)(unsafe.Pointer(pFrame)).FpAuxData
|
|
(*TVdbeFrame)(unsafe.Pointer(pFrame)).FpAuxData = uintptr(0)
|
|
return (*TVdbeFrame)(unsafe.Pointer(pFrame)).Fpc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Memory cell pMem contains the context of an aggregate function.
|
|
// ** This routine calls the finalize method for that function. The
|
|
// ** result of the aggregate is stored back into pMem.
|
|
// **
|
|
// ** Return SQLITE_ERROR if the finalizer reports an error. SQLITE_OK
|
|
// ** otherwise.
|
|
// */
|
|
func _sqlite3VdbeMemFinalize(tls *libc.TLS, pMem uintptr, pFunc uintptr) (r int32) {
|
|
bp := tls.Alloc(80)
|
|
defer tls.Free(80)
|
|
var _ /* ctx at bp+0 */ Tsqlite3_context
|
|
var _ /* t at bp+32 */ TMem
|
|
libc.Xmemset(tls, bp, 0, uint32(28))
|
|
libc.Xmemset(tls, bp+32, 0, uint32(40))
|
|
(**(**TMem)(__ccgo_up(bp + 32))).Fflags = uint16(MEM_Null)
|
|
(**(**TMem)(__ccgo_up(bp + 32))).Fdb = (*TMem)(unsafe.Pointer(pMem)).Fdb
|
|
(**(**Tsqlite3_context)(__ccgo_up(bp))).FpOut = bp + 32
|
|
(**(**Tsqlite3_context)(__ccgo_up(bp))).FpMem = pMem
|
|
(**(**Tsqlite3_context)(__ccgo_up(bp))).FpFunc = pFunc
|
|
(**(**Tsqlite3_context)(__ccgo_up(bp))).Fenc = (*Tsqlite3)(unsafe.Pointer((**(**TMem)(__ccgo_up(bp + 32))).Fdb)).Fenc
|
|
(*(*func(*libc.TLS, uintptr))(unsafe.Pointer(&struct{ uintptr }{(*TFuncDef)(unsafe.Pointer(pFunc)).FxFinalize})))(tls, bp) /* IMP: R-24505-23230 */
|
|
if (*TMem)(unsafe.Pointer(pMem)).FszMalloc > 0 {
|
|
_sqlite3DbFreeNN(tls, (*TMem)(unsafe.Pointer(pMem)).Fdb, (*TMem)(unsafe.Pointer(pMem)).FzMalloc)
|
|
}
|
|
libc.Xmemcpy(tls, pMem, bp+32, uint32(40))
|
|
return (**(**Tsqlite3_context)(__ccgo_up(bp))).FisError
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This routine sets the value to be returned by subsequent calls to
|
|
// ** sqlite3_changes() on the database handle 'db'.
|
|
// */
|
|
func _sqlite3VdbeSetChanges(tls *libc.TLS, db uintptr, nChange Ti64) {
|
|
(*Tsqlite3)(unsafe.Pointer(db)).FnChange = nChange
|
|
**(**Ti64)(__ccgo_up(db + 112)) += nChange
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Configure SQL variable iVar so that binding a new value to it signals
|
|
// ** to sqlite3_reoptimize() that re-preparing the statement may result
|
|
// ** in a better query plan.
|
|
// */
|
|
func _sqlite3VdbeSetVarmask(tls *libc.TLS, v uintptr, iVar int32) {
|
|
if iVar >= int32(32) {
|
|
**(**Tu32)(__ccgo_up(v + 220)) |= uint32(0x80000000)
|
|
} else {
|
|
**(**Tu32)(__ccgo_up(v + 220)) |= libc.Uint32FromInt32(1) << (iVar - libc.Int32FromInt32(1))
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Swap byte-code between two VDBE structures.
|
|
// **
|
|
// ** This happens after pB was previously run and returned
|
|
// ** SQLITE_SCHEMA. The statement was then reprepared in pA.
|
|
// ** This routine transfers the new bytecode in pA over to pB
|
|
// ** so that pB can be run again. The old pB byte code is
|
|
// ** moved back to pA so that it will be cleaned up when pA is
|
|
// ** finalized.
|
|
// */
|
|
func _sqlite3VdbeSwap(tls *libc.TLS, pA uintptr, pB uintptr) {
|
|
var pTmp, ppTmp, zTmp uintptr
|
|
var tmp TVdbe
|
|
_, _, _, _ = pTmp, ppTmp, tmp, zTmp
|
|
tmp = **(**TVdbe)(__ccgo_up(pA))
|
|
**(**TVdbe)(__ccgo_up(pA)) = **(**TVdbe)(__ccgo_up(pB))
|
|
**(**TVdbe)(__ccgo_up(pB)) = tmp
|
|
pTmp = (*TVdbe)(unsafe.Pointer(pA)).FpVNext
|
|
(*TVdbe)(unsafe.Pointer(pA)).FpVNext = (*TVdbe)(unsafe.Pointer(pB)).FpVNext
|
|
(*TVdbe)(unsafe.Pointer(pB)).FpVNext = pTmp
|
|
ppTmp = (*TVdbe)(unsafe.Pointer(pA)).FppVPrev
|
|
(*TVdbe)(unsafe.Pointer(pA)).FppVPrev = (*TVdbe)(unsafe.Pointer(pB)).FppVPrev
|
|
(*TVdbe)(unsafe.Pointer(pB)).FppVPrev = ppTmp
|
|
zTmp = (*TVdbe)(unsafe.Pointer(pA)).FzSql
|
|
(*TVdbe)(unsafe.Pointer(pA)).FzSql = (*TVdbe)(unsafe.Pointer(pB)).FzSql
|
|
(*TVdbe)(unsafe.Pointer(pB)).FzSql = zTmp
|
|
(*TVdbe)(unsafe.Pointer(pB)).Fexpmask = (*TVdbe)(unsafe.Pointer(pA)).Fexpmask
|
|
(*TVdbe)(unsafe.Pointer(pB)).FprepFlags = (*TVdbe)(unsafe.Pointer(pA)).FprepFlags
|
|
libc.Xmemcpy(tls, pB+164, pA+164, uint32(36))
|
|
**(**Tu32)(__ccgo_up(pB + 164 + 5*4)) = **(**Tu32)(__ccgo_up(pB + 164 + 5*4)) + 1
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Declare to the Vdbe that the BTree object at db->aDb[i] is used.
|
|
// **
|
|
// ** The prepared statements need to know in advance the complete set of
|
|
// ** attached databases that will be use. A mask of these databases
|
|
// ** is maintained in p->btreeMask. The p->lockMask value is the subset of
|
|
// ** p->btreeMask of databases that will require a lock.
|
|
// */
|
|
func _sqlite3VdbeUsesBtree(tls *libc.TLS, p uintptr, i int32) {
|
|
**(**TyDbMask)(__ccgo_up(p + 156)) |= libc.Uint32FromInt32(1) << i
|
|
if i != int32(1) && _sqlite3BtreeSharable(tls, (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer((*TVdbe)(unsafe.Pointer(p)).Fdb)).FaDb + uintptr(i)*16))).FpBt) != 0 {
|
|
**(**TyDbMask)(__ccgo_up(p + 160)) |= libc.Uint32FromInt32(1) << i
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Invoke either the xSavepoint, xRollbackTo or xRelease method of all
|
|
// ** virtual tables that currently have an open transaction. Pass iSavepoint
|
|
// ** as the second argument to the virtual table method invoked.
|
|
// **
|
|
// ** If op is SAVEPOINT_BEGIN, the xSavepoint method is invoked. If it is
|
|
// ** SAVEPOINT_ROLLBACK, the xRollbackTo method. Otherwise, if op is
|
|
// ** SAVEPOINT_RELEASE, then the xRelease method of each virtual table with
|
|
// ** an open transaction is invoked.
|
|
// **
|
|
// ** If any virtual table method returns an error code other than SQLITE_OK,
|
|
// ** processing is abandoned and the error returned to the caller of this
|
|
// ** function immediately. If all calls to virtual table methods are successful,
|
|
// ** SQLITE_OK is returned.
|
|
// */
|
|
func _sqlite3VtabSavepoint(tls *libc.TLS, db uintptr, op int32, iSavepoint int32) (r int32) {
|
|
var i, rc int32
|
|
var pMod, pVTab, xMethod uintptr
|
|
var savedFlags Tu64
|
|
_, _, _, _, _, _ = i, pMod, pVTab, rc, savedFlags, xMethod
|
|
rc = SQLITE_OK
|
|
if (*Tsqlite3)(unsafe.Pointer(db)).FaVTrans != 0 {
|
|
i = 0
|
|
for {
|
|
if !(rc == SQLITE_OK && i < (*Tsqlite3)(unsafe.Pointer(db)).FnVTrans) {
|
|
break
|
|
}
|
|
pVTab = **(**uintptr)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaVTrans + uintptr(i)*4))
|
|
pMod = (*TModule)(unsafe.Pointer((*TVTable)(unsafe.Pointer(pVTab)).FpMod)).FpModule
|
|
if (*TVTable)(unsafe.Pointer(pVTab)).FpVtab != 0 && (*Tsqlite3_module)(unsafe.Pointer(pMod)).FiVersion >= int32(2) {
|
|
_sqlite3VtabLock(tls, pVTab)
|
|
switch op {
|
|
case SAVEPOINT_BEGIN:
|
|
xMethod = (*Tsqlite3_module)(unsafe.Pointer(pMod)).FxSavepoint
|
|
(*TVTable)(unsafe.Pointer(pVTab)).FiSavepoint = iSavepoint + int32(1)
|
|
case int32(SAVEPOINT_ROLLBACK):
|
|
xMethod = (*Tsqlite3_module)(unsafe.Pointer(pMod)).FxRollbackTo
|
|
default:
|
|
xMethod = (*Tsqlite3_module)(unsafe.Pointer(pMod)).FxRelease
|
|
break
|
|
}
|
|
if xMethod != 0 && (*TVTable)(unsafe.Pointer(pVTab)).FiSavepoint > iSavepoint {
|
|
savedFlags = (*Tsqlite3)(unsafe.Pointer(db)).Fflags & libc.Uint64FromInt32(SQLITE_Defensive)
|
|
**(**Tu64)(__ccgo_up(db + 32)) &= ^libc.Uint64FromInt32(SQLITE_Defensive)
|
|
rc = (*(*func(*libc.TLS, uintptr, int32) int32)(unsafe.Pointer(&struct{ uintptr }{xMethod})))(tls, (*TVTable)(unsafe.Pointer(pVTab)).FpVtab, iSavepoint)
|
|
**(**Tu64)(__ccgo_up(db + 32)) |= savedFlags
|
|
}
|
|
_sqlite3VtabUnlock(tls, pVTab)
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
}
|
|
return rc
|
|
}
|
|
|
|
func _sqlite3WhereRealloc(tls *libc.TLS, pWInfo uintptr, pOld uintptr, nByte Tu64) (r uintptr) {
|
|
var pNew, pOldBlk uintptr
|
|
_, _ = pNew, pOldBlk
|
|
pNew = _sqlite3WhereMalloc(tls, pWInfo, nByte)
|
|
if pNew != 0 && pOld != 0 {
|
|
pOldBlk = pOld
|
|
pOldBlk -= 16
|
|
libc.Xmemcpy(tls, pNew, pOld, uint32((*TWhereMemBlock)(unsafe.Pointer(pOldBlk)).Fsz))
|
|
}
|
|
return pNew
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Reclaim all memory of a StatAccum structure.
|
|
// */
|
|
func _statAccumDestructor(tls *libc.TLS, pOld uintptr) {
|
|
var i int32
|
|
var p uintptr
|
|
_, _ = i, p
|
|
p = pOld
|
|
if (*TStatAccum)(unsafe.Pointer(p)).FmxSample != 0 {
|
|
i = 0
|
|
for {
|
|
if !(i < (*TStatAccum)(unsafe.Pointer(p)).FnCol) {
|
|
break
|
|
}
|
|
_sampleClear(tls, (*TStatAccum)(unsafe.Pointer(p)).Fdb, (*TStatAccum)(unsafe.Pointer(p)).FaBest+uintptr(i)*40)
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
i = 0
|
|
for {
|
|
if !(i < (*TStatAccum)(unsafe.Pointer(p)).FmxSample) {
|
|
break
|
|
}
|
|
_sampleClear(tls, (*TStatAccum)(unsafe.Pointer(p)).Fdb, (*TStatAccum)(unsafe.Pointer(p)).Fa+uintptr(i)*40)
|
|
goto _2
|
|
_2:
|
|
;
|
|
i = i + 1
|
|
}
|
|
_sampleClear(tls, (*TStatAccum)(unsafe.Pointer(p)).Fdb, p+40)
|
|
}
|
|
_sqlite3DbFree(tls, (*TStatAccum)(unsafe.Pointer(p)).Fdb, p)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Free all resources associated with the IncrMerger object indicated by
|
|
// ** the first argument.
|
|
// */
|
|
func _vdbeIncrFree(tls *libc.TLS, pIncr uintptr) {
|
|
if pIncr != 0 {
|
|
if (*TIncrMerger)(unsafe.Pointer(pIncr)).FbUseThread != 0 {
|
|
_vdbeSorterJoinThread(tls, (*TIncrMerger)(unsafe.Pointer(pIncr)).FpTask)
|
|
if (**(**TSorterFile)(__ccgo_up(pIncr + 32))).FpFd != 0 {
|
|
_sqlite3OsCloseFree(tls, (**(**TSorterFile)(__ccgo_up(pIncr + 32))).FpFd)
|
|
}
|
|
if (**(**TSorterFile)(__ccgo_up(pIncr + 32 + 1*16))).FpFd != 0 {
|
|
_sqlite3OsCloseFree(tls, (**(**TSorterFile)(__ccgo_up(pIncr + 32 + 1*16))).FpFd)
|
|
}
|
|
}
|
|
_vdbeMergeEngineFree(tls, (*TIncrMerger)(unsafe.Pointer(pIncr)).FpMerger)
|
|
Xsqlite3_free(tls, pIncr)
|
|
}
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Allocate and return a new IncrMerger object to read data from pMerger.
|
|
// **
|
|
// ** If an OOM condition is encountered, return NULL. In this case free the
|
|
// ** pMerger argument before returning.
|
|
// */
|
|
func _vdbeIncrMergerNew(tls *libc.TLS, pTask uintptr, pMerger uintptr, ppOut uintptr) (r int32) {
|
|
var pIncr, v1, v2 uintptr
|
|
var rc, v3 int32
|
|
_, _, _, _, _ = pIncr, rc, v1, v2, v3
|
|
rc = SQLITE_OK
|
|
if _sqlite3FaultSim(tls, int32(100)) != 0 {
|
|
v2 = uintptr(0)
|
|
} else {
|
|
v2 = _sqlite3MallocZero(tls, uint64(64))
|
|
}
|
|
v1 = v2
|
|
**(**uintptr)(__ccgo_up(ppOut)) = v1
|
|
pIncr = v1
|
|
if pIncr != 0 {
|
|
(*TIncrMerger)(unsafe.Pointer(pIncr)).FpMerger = pMerger
|
|
(*TIncrMerger)(unsafe.Pointer(pIncr)).FpTask = pTask
|
|
if (*TVdbeSorter)(unsafe.Pointer((*TSortSubtask)(unsafe.Pointer(pTask)).FpSorter)).FmxKeysize+int32(9) > (*TVdbeSorter)(unsafe.Pointer((*TSortSubtask)(unsafe.Pointer(pTask)).FpSorter)).FmxPmaSize/int32(2) {
|
|
v3 = (*TVdbeSorter)(unsafe.Pointer((*TSortSubtask)(unsafe.Pointer(pTask)).FpSorter)).FmxKeysize + int32(9)
|
|
} else {
|
|
v3 = (*TVdbeSorter)(unsafe.Pointer((*TSortSubtask)(unsafe.Pointer(pTask)).FpSorter)).FmxPmaSize / int32(2)
|
|
}
|
|
(*TIncrMerger)(unsafe.Pointer(pIncr)).FmxSz = v3
|
|
(*TSortSubtask)(unsafe.Pointer(pTask)).Ffile2.FiEof += int64((*TIncrMerger)(unsafe.Pointer(pIncr)).FmxSz)
|
|
} else {
|
|
_vdbeMergeEngineFree(tls, pMerger)
|
|
rc = int32(SQLITE_NOMEM)
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** This function is called when the PmaReader corresponding to pIncr has
|
|
// ** finished reading the contents of aFile[0]. Its purpose is to "refill"
|
|
// ** aFile[0] such that the PmaReader should start rereading it from the
|
|
// ** beginning.
|
|
// **
|
|
// ** For single-threaded objects, this is accomplished by literally reading
|
|
// ** keys from pIncr->pMerger and repopulating aFile[0].
|
|
// **
|
|
// ** For multi-threaded objects, all that is required is to wait until the
|
|
// ** background thread is finished (if it is not already) and then swap
|
|
// ** aFile[0] and aFile[1] in place. If the contents of pMerger have not
|
|
// ** been exhausted, this function also launches a new background thread
|
|
// ** to populate the new aFile[1].
|
|
// **
|
|
// ** SQLITE_OK is returned on success, or an SQLite error code otherwise.
|
|
// */
|
|
func _vdbeIncrSwap(tls *libc.TLS, pIncr uintptr) (r int32) {
|
|
var f0 TSorterFile
|
|
var rc int32
|
|
_, _ = f0, rc
|
|
rc = SQLITE_OK
|
|
if (*TIncrMerger)(unsafe.Pointer(pIncr)).FbUseThread != 0 {
|
|
rc = _vdbeSorterJoinThread(tls, (*TIncrMerger)(unsafe.Pointer(pIncr)).FpTask)
|
|
if rc == SQLITE_OK {
|
|
f0 = **(**TSorterFile)(__ccgo_up(pIncr + 32))
|
|
**(**TSorterFile)(__ccgo_up(pIncr + 32)) = **(**TSorterFile)(__ccgo_up(pIncr + 32 + 1*16))
|
|
**(**TSorterFile)(__ccgo_up(pIncr + 32 + 1*16)) = f0
|
|
}
|
|
if rc == SQLITE_OK {
|
|
if (**(**TSorterFile)(__ccgo_up(pIncr + 32))).FiEof == (*TIncrMerger)(unsafe.Pointer(pIncr)).FiStartOff {
|
|
(*TIncrMerger)(unsafe.Pointer(pIncr)).FbEof = int32(1)
|
|
} else {
|
|
rc = _vdbeIncrBgPopulate(tls, pIncr)
|
|
}
|
|
}
|
|
} else {
|
|
rc = _vdbeIncrPopulate(tls, pIncr)
|
|
**(**TSorterFile)(__ccgo_up(pIncr + 32)) = **(**TSorterFile)(__ccgo_up(pIncr + 32 + 1*16))
|
|
if (**(**TSorterFile)(__ccgo_up(pIncr + 32))).FiEof == (*TIncrMerger)(unsafe.Pointer(pIncr)).FiStartOff {
|
|
(*TIncrMerger)(unsafe.Pointer(pIncr)).FbEof = int32(1)
|
|
}
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Recompute pMerger->aTree[iOut] by comparing the next keys on the
|
|
// ** two PmaReaders that feed that entry. Neither of the PmaReaders
|
|
// ** are advanced. This routine merely does the comparison.
|
|
// */
|
|
func _vdbeMergeEngineCompare(tls *libc.TLS, pMerger uintptr, iOut int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var i1, i2, iRes, res int32
|
|
var p1, p2, pTask uintptr
|
|
var _ /* bCached at bp+0 */ int32
|
|
_, _, _, _, _, _, _ = i1, i2, iRes, p1, p2, pTask, res
|
|
if iOut >= (*TMergeEngine)(unsafe.Pointer(pMerger)).FnTree/int32(2) {
|
|
i1 = (iOut - (*TMergeEngine)(unsafe.Pointer(pMerger)).FnTree/int32(2)) * int32(2)
|
|
i2 = i1 + int32(1)
|
|
} else {
|
|
i1 = **(**int32)(__ccgo_up((*TMergeEngine)(unsafe.Pointer(pMerger)).FaTree + uintptr(iOut*int32(2))*4))
|
|
i2 = **(**int32)(__ccgo_up((*TMergeEngine)(unsafe.Pointer(pMerger)).FaTree + uintptr(iOut*int32(2)+int32(1))*4))
|
|
}
|
|
p1 = (*TMergeEngine)(unsafe.Pointer(pMerger)).FaReadr + uintptr(i1)*56
|
|
p2 = (*TMergeEngine)(unsafe.Pointer(pMerger)).FaReadr + uintptr(i2)*56
|
|
if (*TPmaReader)(unsafe.Pointer(p1)).FpFd == uintptr(0) {
|
|
iRes = i2
|
|
} else {
|
|
if (*TPmaReader)(unsafe.Pointer(p2)).FpFd == uintptr(0) {
|
|
iRes = i1
|
|
} else {
|
|
pTask = (*TMergeEngine)(unsafe.Pointer(pMerger)).FpTask
|
|
**(**int32)(__ccgo_up(bp)) = 0
|
|
/* from vdbeSortSubtaskMain() */
|
|
res = (*(*func(*libc.TLS, uintptr, uintptr, uintptr, int32, uintptr, int32) int32)(unsafe.Pointer(&struct{ uintptr }{(*TSortSubtask)(unsafe.Pointer(pTask)).FxCompare})))(tls, pTask, bp, (*TPmaReader)(unsafe.Pointer(p1)).FaKey, (*TPmaReader)(unsafe.Pointer(p1)).FnKey, (*TPmaReader)(unsafe.Pointer(p2)).FaKey, (*TPmaReader)(unsafe.Pointer(p2)).FnKey)
|
|
if res <= 0 {
|
|
iRes = i1
|
|
} else {
|
|
iRes = i2
|
|
}
|
|
}
|
|
}
|
|
**(**int32)(__ccgo_up((*TMergeEngine)(unsafe.Pointer(pMerger)).FaTree + uintptr(iOut)*4)) = iRes
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Free the MergeEngine object passed as the only argument.
|
|
// */
|
|
func _vdbeMergeEngineFree(tls *libc.TLS, pMerger uintptr) {
|
|
var i int32
|
|
_ = i
|
|
if pMerger != 0 {
|
|
i = 0
|
|
for {
|
|
if !(i < (*TMergeEngine)(unsafe.Pointer(pMerger)).FnTree) {
|
|
break
|
|
}
|
|
_vdbePmaReaderClear(tls, (*TMergeEngine)(unsafe.Pointer(pMerger)).FaReadr+uintptr(i)*56)
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
}
|
|
Xsqlite3_free(tls, pMerger)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Allocate a new MergeEngine object to merge the contents of nPMA level-0
|
|
// ** PMAs from pTask->file. If no error occurs, set *ppOut to point to
|
|
// ** the new object and return SQLITE_OK. Or, if an error does occur, set *ppOut
|
|
// ** to NULL and return an SQLite error code.
|
|
// **
|
|
// ** When this function is called, *piOffset is set to the offset of the
|
|
// ** first PMA to read from pTask->file. Assuming no error occurs, it is
|
|
// ** set to the offset immediately following the last byte of the last
|
|
// ** PMA before returning. If an error does occur, then the final value of
|
|
// ** *piOffset is undefined.
|
|
// */
|
|
func _vdbeMergeEngineLevel0(tls *libc.TLS, pTask uintptr, nPMA int32, piOffset uintptr, ppOut uintptr) (r int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var i, rc int32
|
|
var iOff Ti64
|
|
var pNew, pReadr, v1 uintptr
|
|
var _ /* nDummy at bp+0 */ Ti64
|
|
_, _, _, _, _, _ = i, iOff, pNew, pReadr, rc, v1 /* Merge engine to return */
|
|
iOff = **(**Ti64)(__ccgo_up(piOffset))
|
|
rc = SQLITE_OK
|
|
v1 = _vdbeMergeEngineNew(tls, nPMA)
|
|
pNew = v1
|
|
**(**uintptr)(__ccgo_up(ppOut)) = v1
|
|
if pNew == uintptr(0) {
|
|
rc = int32(SQLITE_NOMEM)
|
|
}
|
|
i = 0
|
|
for {
|
|
if !(i < nPMA && rc == SQLITE_OK) {
|
|
break
|
|
}
|
|
**(**Ti64)(__ccgo_up(bp)) = 0
|
|
pReadr = (*TMergeEngine)(unsafe.Pointer(pNew)).FaReadr + uintptr(i)*56
|
|
rc = _vdbePmaReaderInit(tls, pTask, pTask+48, iOff, pReadr, bp)
|
|
iOff = (*TPmaReader)(unsafe.Pointer(pReadr)).FiEof
|
|
goto _2
|
|
_2:
|
|
;
|
|
i = i + 1
|
|
}
|
|
if rc != SQLITE_OK {
|
|
_vdbeMergeEngineFree(tls, pNew)
|
|
**(**uintptr)(__ccgo_up(ppOut)) = uintptr(0)
|
|
}
|
|
**(**Ti64)(__ccgo_up(piOffset)) = iOff
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Free all memory belonging to the PmaReader object passed as the
|
|
// ** argument. All structure fields are set to zero before returning.
|
|
// */
|
|
func _vdbePmaReaderClear(tls *libc.TLS, pReadr uintptr) {
|
|
Xsqlite3_free(tls, (*TPmaReader)(unsafe.Pointer(pReadr)).FaAlloc)
|
|
Xsqlite3_free(tls, (*TPmaReader)(unsafe.Pointer(pReadr)).FaBuffer)
|
|
if (*TPmaReader)(unsafe.Pointer(pReadr)).FaMap != 0 {
|
|
_sqlite3OsUnfetch(tls, (*TPmaReader)(unsafe.Pointer(pReadr)).FpFd, 0, (*TPmaReader)(unsafe.Pointer(pReadr)).FaMap)
|
|
}
|
|
_vdbeIncrFree(tls, (*TPmaReader)(unsafe.Pointer(pReadr)).FpIncr)
|
|
libc.Xmemset(tls, pReadr, 0, uint32(56))
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** The PmaReader passed as the first argument is guaranteed to be an
|
|
// ** incremental-reader (pReadr->pIncr!=0). This function serves to open
|
|
// ** and/or initialize the temp file related fields of the IncrMerge
|
|
// ** object at (pReadr->pIncr).
|
|
// **
|
|
// ** If argument eMode is set to INCRINIT_NORMAL, then all PmaReaders
|
|
// ** in the sub-tree headed by pReadr are also initialized. Data is then
|
|
// ** loaded into the buffers belonging to pReadr and it is set to point to
|
|
// ** the first key in its range.
|
|
// **
|
|
// ** If argument eMode is set to INCRINIT_TASK, then pReadr is guaranteed
|
|
// ** to be a multi-threaded PmaReader and this function is being called in a
|
|
// ** background thread. In this case all PmaReaders in the sub-tree are
|
|
// ** initialized as for INCRINIT_NORMAL and the aFile[1] buffer belonging to
|
|
// ** pReadr is populated. However, pReadr itself is not set up to point
|
|
// ** to its first key. A call to vdbePmaReaderNext() is still required to do
|
|
// ** that.
|
|
// **
|
|
// ** The reason this function does not call vdbePmaReaderNext() immediately
|
|
// ** in the INCRINIT_TASK case is that vdbePmaReaderNext() assumes that it has
|
|
// ** to block on thread (pTask->thread) before accessing aFile[1]. But, since
|
|
// ** this entire function is being run by thread (pTask->thread), that will
|
|
// ** lead to the current background thread attempting to join itself.
|
|
// **
|
|
// ** Finally, if argument eMode is set to INCRINIT_ROOT, it may be assumed
|
|
// ** that pReadr->pIncr is a multi-threaded IncrMerge objects, and that all
|
|
// ** child-trees have already been initialized using IncrInit(INCRINIT_TASK).
|
|
// ** In this case vdbePmaReaderNext() is called on all child PmaReaders and
|
|
// ** the current PmaReader set to point to the first key in its range.
|
|
// **
|
|
// ** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
|
|
// */
|
|
func _vdbePmaReaderIncrMergeInit(tls *libc.TLS, pReadr uintptr, eMode int32) (r int32) {
|
|
var db, pIncr, pTask uintptr
|
|
var mxSz, rc int32
|
|
_, _, _, _, _ = db, mxSz, pIncr, pTask, rc
|
|
rc = SQLITE_OK
|
|
pIncr = (*TPmaReader)(unsafe.Pointer(pReadr)).FpIncr
|
|
pTask = (*TIncrMerger)(unsafe.Pointer(pIncr)).FpTask
|
|
db = (*TVdbeSorter)(unsafe.Pointer((*TSortSubtask)(unsafe.Pointer(pTask)).FpSorter)).Fdb
|
|
/* eMode is always INCRINIT_NORMAL in single-threaded mode */
|
|
rc = _vdbeMergeEngineInit(tls, pTask, (*TIncrMerger)(unsafe.Pointer(pIncr)).FpMerger, eMode)
|
|
/* Set up the required files for pIncr. A multi-threaded IncrMerge object
|
|
** requires two temp files to itself, whereas a single-threaded object
|
|
** only requires a region of pTask->file2. */
|
|
if rc == SQLITE_OK {
|
|
mxSz = (*TIncrMerger)(unsafe.Pointer(pIncr)).FmxSz
|
|
if (*TIncrMerger)(unsafe.Pointer(pIncr)).FbUseThread != 0 {
|
|
rc = _vdbeSorterOpenTempFile(tls, db, int64(mxSz), pIncr+32)
|
|
if rc == SQLITE_OK {
|
|
rc = _vdbeSorterOpenTempFile(tls, db, int64(mxSz), pIncr+32+1*16)
|
|
}
|
|
} else {
|
|
/*if( !pIncr->bUseThread )*/
|
|
if (*TSortSubtask)(unsafe.Pointer(pTask)).Ffile2.FpFd == uintptr(0) {
|
|
rc = _vdbeSorterOpenTempFile(tls, db, (*TSortSubtask)(unsafe.Pointer(pTask)).Ffile2.FiEof, pTask+64)
|
|
(*TSortSubtask)(unsafe.Pointer(pTask)).Ffile2.FiEof = 0
|
|
}
|
|
if rc == SQLITE_OK {
|
|
(**(**TSorterFile)(__ccgo_up(pIncr + 32 + 1*16))).FpFd = (*TSortSubtask)(unsafe.Pointer(pTask)).Ffile2.FpFd
|
|
(*TIncrMerger)(unsafe.Pointer(pIncr)).FiStartOff = (*TSortSubtask)(unsafe.Pointer(pTask)).Ffile2.FiEof
|
|
(*TSortSubtask)(unsafe.Pointer(pTask)).Ffile2.FiEof += int64(mxSz)
|
|
}
|
|
}
|
|
}
|
|
if rc == SQLITE_OK && (*TIncrMerger)(unsafe.Pointer(pIncr)).FbUseThread != 0 {
|
|
/* Use the current thread to populate aFile[1], even though this
|
|
** PmaReader is multi-threaded. If this is an INCRINIT_TASK object,
|
|
** then this function is already running in background thread
|
|
** pIncr->pTask->thread.
|
|
**
|
|
** If this is the INCRINIT_ROOT object, then it is running in the
|
|
** main VDBE thread. But that is Ok, as that thread cannot return
|
|
** control to the VDBE or proceed with anything useful until the
|
|
** first results are ready from this merger object anyway.
|
|
*/
|
|
rc = _vdbeIncrPopulate(tls, pIncr)
|
|
}
|
|
if rc == SQLITE_OK && (libc.Bool(false) || eMode != int32(INCRINIT_TASK)) {
|
|
rc = _vdbePmaReaderNext(tls, pReadr)
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Free all resources owned by the object indicated by argument pTask. All
|
|
// ** fields of *pTask are zeroed before returning.
|
|
// */
|
|
func _vdbeSortSubtaskCleanup(tls *libc.TLS, db uintptr, pTask uintptr) {
|
|
_sqlite3DbFree(tls, db, (*TSortSubtask)(unsafe.Pointer(pTask)).FpUnpacked)
|
|
/* pTask->list.aMemory can only be non-zero if it was handed memory
|
|
** from the main thread. That only occurs SQLITE_MAX_WORKER_THREADS>0 */
|
|
if (*TSortSubtask)(unsafe.Pointer(pTask)).Flist.FaMemory != 0 {
|
|
Xsqlite3_free(tls, (*TSortSubtask)(unsafe.Pointer(pTask)).Flist.FaMemory)
|
|
} else {
|
|
_vdbeSorterRecordFree(tls, uintptr(0), (*TSortSubtask)(unsafe.Pointer(pTask)).Flist.FpList)
|
|
}
|
|
if (*TSortSubtask)(unsafe.Pointer(pTask)).Ffile.FpFd != 0 {
|
|
_sqlite3OsCloseFree(tls, (*TSortSubtask)(unsafe.Pointer(pTask)).Ffile.FpFd)
|
|
}
|
|
if (*TSortSubtask)(unsafe.Pointer(pTask)).Ffile2.FpFd != 0 {
|
|
_sqlite3OsCloseFree(tls, (*TSortSubtask)(unsafe.Pointer(pTask)).Ffile2.FpFd)
|
|
}
|
|
libc.Xmemset(tls, pTask, 0, uint32(88))
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** pRoot is the root of an incremental merge-tree with depth nDepth (according
|
|
// ** to vdbeSorterTreeDepth()). pLeaf is the iSeq'th leaf to be added to the
|
|
// ** tree, counting from zero. This function adds pLeaf to the tree.
|
|
// **
|
|
// ** If successful, SQLITE_OK is returned. If an error occurs, an SQLite error
|
|
// ** code is returned and pLeaf is freed.
|
|
// */
|
|
func _vdbeSorterAddToTree(tls *libc.TLS, pTask uintptr, nDepth int32, iSeq int32, pRoot uintptr, pLeaf uintptr) (r int32) {
|
|
bp := tls.Alloc(16)
|
|
defer tls.Free(16)
|
|
var i, iIter, nDiv, rc int32
|
|
var p, pNew, pReadr uintptr
|
|
var _ /* pIncr at bp+0 */ uintptr
|
|
_, _, _, _, _, _, _ = i, iIter, nDiv, p, pNew, pReadr, rc
|
|
rc = SQLITE_OK
|
|
nDiv = int32(1)
|
|
p = pRoot
|
|
rc = _vdbeIncrMergerNew(tls, pTask, pLeaf, bp)
|
|
i = int32(1)
|
|
for {
|
|
if !(i < nDepth) {
|
|
break
|
|
}
|
|
nDiv = nDiv * int32(SORTER_MAX_MERGE_COUNT)
|
|
goto _1
|
|
_1:
|
|
;
|
|
i = i + 1
|
|
}
|
|
i = int32(1)
|
|
for {
|
|
if !(i < nDepth && rc == SQLITE_OK) {
|
|
break
|
|
}
|
|
iIter = iSeq / nDiv % int32(SORTER_MAX_MERGE_COUNT)
|
|
pReadr = (*TMergeEngine)(unsafe.Pointer(p)).FaReadr + uintptr(iIter)*56
|
|
if (*TPmaReader)(unsafe.Pointer(pReadr)).FpIncr == uintptr(0) {
|
|
pNew = _vdbeMergeEngineNew(tls, int32(SORTER_MAX_MERGE_COUNT))
|
|
if pNew == uintptr(0) {
|
|
rc = int32(SQLITE_NOMEM)
|
|
} else {
|
|
rc = _vdbeIncrMergerNew(tls, pTask, pNew, pReadr+48)
|
|
}
|
|
}
|
|
if rc == SQLITE_OK {
|
|
p = (*TIncrMerger)(unsafe.Pointer((*TPmaReader)(unsafe.Pointer(pReadr)).FpIncr)).FpMerger
|
|
nDiv = nDiv / int32(SORTER_MAX_MERGE_COUNT)
|
|
}
|
|
goto _2
|
|
_2:
|
|
;
|
|
i = i + 1
|
|
}
|
|
if rc == SQLITE_OK {
|
|
(**(**TPmaReader)(__ccgo_up((*TMergeEngine)(unsafe.Pointer(p)).FaReadr + uintptr(iSeq%int32(SORTER_MAX_MERGE_COUNT))*56))).FpIncr = **(**uintptr)(__ccgo_up(bp))
|
|
} else {
|
|
_vdbeIncrFree(tls, **(**uintptr)(__ccgo_up(bp)))
|
|
}
|
|
return rc
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** The main routine for background threads that write level-0 PMAs.
|
|
// */
|
|
func _vdbeSorterFlushThread(tls *libc.TLS, pCtx uintptr) (r uintptr) {
|
|
var pTask uintptr
|
|
var rc int32
|
|
_, _ = pTask, rc
|
|
pTask = pCtx /* Return code */
|
|
rc = _vdbeSorterListToPMA(tls, pTask, pTask+24)
|
|
(*TSortSubtask)(unsafe.Pointer(pTask)).FbDone = int32(1)
|
|
return uintptr(rc)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Return a pointer to a buffer owned by the sorter that contains the
|
|
// ** current key.
|
|
// */
|
|
func _vdbeSorterRowkey(tls *libc.TLS, pSorter uintptr, pnKey uintptr) (r uintptr) {
|
|
var pKey, pReader uintptr
|
|
_, _ = pKey, pReader
|
|
if (*TVdbeSorter)(unsafe.Pointer(pSorter)).FbUsePMA != 0 {
|
|
if (*TVdbeSorter)(unsafe.Pointer(pSorter)).FbUseThreads != 0 {
|
|
pReader = (*TVdbeSorter)(unsafe.Pointer(pSorter)).FpReader
|
|
} else {
|
|
/*if( !pSorter->bUseThreads )*/
|
|
pReader = (*TMergeEngine)(unsafe.Pointer((*TVdbeSorter)(unsafe.Pointer(pSorter)).FpMerger)).FaReadr + uintptr(**(**int32)(__ccgo_up((*TMergeEngine)(unsafe.Pointer((*TVdbeSorter)(unsafe.Pointer(pSorter)).FpMerger)).FaTree + 1*4)))*56
|
|
}
|
|
**(**int32)(__ccgo_up(pnKey)) = (*TPmaReader)(unsafe.Pointer(pReader)).FnKey
|
|
pKey = (*TPmaReader)(unsafe.Pointer(pReader)).FaKey
|
|
} else {
|
|
**(**int32)(__ccgo_up(pnKey)) = (*TSorterRecord)(unsafe.Pointer((*TVdbeSorter)(unsafe.Pointer(pSorter)).Flist.FpList)).FnVal
|
|
pKey = (*TVdbeSorter)(unsafe.Pointer(pSorter)).Flist.FpList + libc.UintptrFromInt32(1)*8
|
|
}
|
|
return pKey
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Free a WhereInfo structure
|
|
// */
|
|
func _whereInfoFree(tls *libc.TLS, db uintptr, pWInfo uintptr) {
|
|
var p, pNext uintptr
|
|
_, _ = p, pNext
|
|
_sqlite3WhereClauseClear(tls, pWInfo+80)
|
|
for (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpLoops != 0 {
|
|
p = (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpLoops
|
|
(*TWhereInfo)(unsafe.Pointer(pWInfo)).FpLoops = (*TWhereLoop)(unsafe.Pointer(p)).FpNextLoop
|
|
_whereLoopDelete(tls, db, p)
|
|
}
|
|
for (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpMemToFree != 0 {
|
|
pNext = (*TWhereMemBlock)(unsafe.Pointer((*TWhereInfo)(unsafe.Pointer(pWInfo)).FpMemToFree)).FpNext
|
|
_sqlite3DbNNFreeNN(tls, db, (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpMemToFree)
|
|
(*TWhereInfo)(unsafe.Pointer(pWInfo)).FpMemToFree = pNext
|
|
}
|
|
_sqlite3DbNNFreeNN(tls, db, pWInfo)
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Move the content of pSrc into pDest
|
|
// */
|
|
func _whereOrMove(tls *libc.TLS, pDest uintptr, pSrc uintptr) {
|
|
(*TWhereOrSet)(unsafe.Pointer(pDest)).Fn = (*TWhereOrSet)(unsafe.Pointer(pSrc)).Fn
|
|
libc.Xmemcpy(tls, pDest+8, pSrc+8, uint32((*TWhereOrSet)(unsafe.Pointer(pDest)).Fn)*uint32(16))
|
|
}
|