// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT. //go:build (darwin && amd64) || (darwin && arm64) || (freebsd && amd64) || (freebsd && arm) || (freebsd && arm64) || (linux && amd64) || (linux && arm) || (linux && arm64) || (linux && loong64) || (linux && ppc64le) || (linux && riscv64) || (linux && s390x) || (netbsd && amd64) || (openbsd && amd64) || (openbsd && arm64) package sqlite3 import ( "unsafe" "modernc.org/libc" ) func _fts5DoclistIterNext(tls *libc.TLS, pIter uintptr) { bp := tls.Alloc(16) defer tls.Free(16) var p uintptr var _ /* iDelta at bp+0 */ Ti64 var _ /* nPos at bp+8 */ int32 _ = p p = (*TFts5DoclistIter)(unsafe.Pointer(pIter)).FaPoslist + uintptr((*TFts5DoclistIter)(unsafe.Pointer(pIter)).FnSize) + uintptr((*TFts5DoclistIter)(unsafe.Pointer(pIter)).FnPoslist) if p >= (*TFts5DoclistIter)(unsafe.Pointer(pIter)).FaEof { (*TFts5DoclistIter)(unsafe.Pointer(pIter)).FaPoslist = uintptr(0) } else { p = p + uintptr(_sqlite3Fts5GetVarint(tls, p, bp)) **(**Ti64)(__ccgo_up(pIter + 8)) += **(**Ti64)(__ccgo_up(bp)) /* Read position list size */ if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(p)))&int32(0x80) != 0 { (*TFts5DoclistIter)(unsafe.Pointer(pIter)).FnSize = _sqlite3Fts5GetVarint32(tls, p, bp+8) (*TFts5DoclistIter)(unsafe.Pointer(pIter)).FnPoslist = **(**int32)(__ccgo_up(bp + 8)) >> int32(1) } else { (*TFts5DoclistIter)(unsafe.Pointer(pIter)).FnPoslist = libc.Int32FromUint8(**(**Tu8)(__ccgo_up(p))) >> int32(1) (*TFts5DoclistIter)(unsafe.Pointer(pIter)).FnSize = int32(1) } (*TFts5DoclistIter)(unsafe.Pointer(pIter)).FaPoslist = p if (*TFts5DoclistIter)(unsafe.Pointer(pIter)).FaPoslist+uintptr((*TFts5DoclistIter)(unsafe.Pointer(pIter)).FnPoslist) > (*TFts5DoclistIter)(unsafe.Pointer(pIter)).FaEof { (*TFts5DoclistIter)(unsafe.Pointer(pIter)).FaPoslist = uintptr(0) } } } // C documentation // // /* // ** A total of nLeaf leaf pages of data has just been flushed to a level-0 // ** segment. This function updates the write-counter accordingly and, if // ** necessary, performs incremental merge work. // ** // ** If an error occurs, set the Fts5Index.rc error code. If an error has // ** already occurred, this function is a no-op. // */ func _fts5IndexAutomerge(tls *libc.TLS, p uintptr, ppStruct uintptr, nLeaf int32) { var nRem, nWork int32 var nWrite Tu64 var pStruct uintptr _, _, _, _ = nRem, nWork, nWrite, pStruct if (*TFts5Index)(unsafe.Pointer(p)).Frc == SQLITE_OK && (*TFts5Config)(unsafe.Pointer((*TFts5Index)(unsafe.Pointer(p)).FpConfig)).FnAutomerge > 0 && **(**uintptr)(__ccgo_up(ppStruct)) != uintptr(0) { pStruct = **(**uintptr)(__ccgo_up(ppStruct)) /* Number of leaf pages left to write */ /* Update the write-counter. While doing so, set nWork. */ nWrite = (*TFts5Structure)(unsafe.Pointer(pStruct)).FnWriteCounter nWork = libc.Int32FromUint64((nWrite+libc.Uint64FromInt32(nLeaf))/libc.Uint64FromInt32((*TFts5Index)(unsafe.Pointer(p)).FnWorkUnit) - nWrite/libc.Uint64FromInt32((*TFts5Index)(unsafe.Pointer(p)).FnWorkUnit)) **(**Tu64)(__ccgo_up(pStruct + 8)) += libc.Uint64FromInt32(nLeaf) nRem = (*TFts5Index)(unsafe.Pointer(p)).FnWorkUnit * nWork * (*TFts5Structure)(unsafe.Pointer(pStruct)).FnLevel _fts5IndexMerge(tls, p, ppStruct, nRem, (*TFts5Config)(unsafe.Pointer((*TFts5Index)(unsafe.Pointer(p)).FpConfig)).FnAutomerge) } } // C documentation // // /* // ** Check the RTree node or entry given by pCellData and p against the MATCH // ** constraint pConstraint. // */ func _rtreeCallbackConstraint(tls *libc.TLS, pConstraint uintptr, eInt int32, pCellData uintptr, pSearch uintptr, prScore uintptr, peWithin uintptr) (r int32) { bp := tls.Alloc(96) defer tls.Free(96) var nCoord, rc, v2 int32 var pInfo uintptr var v1 Tsqlite3_rtree_dbl var _ /* aCoord at bp+8 */ [10]Tsqlite3_rtree_dbl var _ /* c at bp+0 */ TRtreeCoord var _ /* eWithin at bp+88 */ int32 _, _, _, _, _ = nCoord, pInfo, rc, v1, v2 pInfo = (*TRtreeConstraint)(unsafe.Pointer(pConstraint)).FpInfo /* Callback info */ nCoord = (*Tsqlite3_rtree_query_info)(unsafe.Pointer(pInfo)).FnCoord /* Decoded coordinates */ if (*TRtreeConstraint)(unsafe.Pointer(pConstraint)).Fop == int32(RTREE_QUERY) && libc.Int32FromUint8((*TRtreeSearchPoint)(unsafe.Pointer(pSearch)).FiLevel) == int32(1) { (*Tsqlite3_rtree_query_info)(unsafe.Pointer(pInfo)).FiRowid = _readInt64(tls, pCellData) } pCellData = pCellData + uintptr(8) if eInt == 0 { switch nCoord { case int32(10): _readCoord(tls, pCellData+uintptr(36), bp) (**(**[10]Tsqlite3_rtree_dbl)(__ccgo_up(bp + 8)))[int32(9)] = float64(*(*TRtreeValue)(unsafe.Pointer(bp))) _readCoord(tls, pCellData+uintptr(32), bp) (**(**[10]Tsqlite3_rtree_dbl)(__ccgo_up(bp + 8)))[int32(8)] = float64(*(*TRtreeValue)(unsafe.Pointer(bp))) fallthrough case int32(8): _readCoord(tls, pCellData+uintptr(28), bp) (**(**[10]Tsqlite3_rtree_dbl)(__ccgo_up(bp + 8)))[int32(7)] = float64(*(*TRtreeValue)(unsafe.Pointer(bp))) _readCoord(tls, pCellData+uintptr(24), bp) (**(**[10]Tsqlite3_rtree_dbl)(__ccgo_up(bp + 8)))[int32(6)] = float64(*(*TRtreeValue)(unsafe.Pointer(bp))) fallthrough case int32(6): _readCoord(tls, pCellData+uintptr(20), bp) (**(**[10]Tsqlite3_rtree_dbl)(__ccgo_up(bp + 8)))[int32(5)] = float64(*(*TRtreeValue)(unsafe.Pointer(bp))) _readCoord(tls, pCellData+uintptr(16), bp) (**(**[10]Tsqlite3_rtree_dbl)(__ccgo_up(bp + 8)))[int32(4)] = float64(*(*TRtreeValue)(unsafe.Pointer(bp))) fallthrough case int32(4): _readCoord(tls, pCellData+uintptr(12), bp) (**(**[10]Tsqlite3_rtree_dbl)(__ccgo_up(bp + 8)))[int32(3)] = float64(*(*TRtreeValue)(unsafe.Pointer(bp))) _readCoord(tls, pCellData+uintptr(8), bp) (**(**[10]Tsqlite3_rtree_dbl)(__ccgo_up(bp + 8)))[int32(2)] = float64(*(*TRtreeValue)(unsafe.Pointer(bp))) fallthrough default: _readCoord(tls, pCellData+uintptr(4), bp) (**(**[10]Tsqlite3_rtree_dbl)(__ccgo_up(bp + 8)))[int32(1)] = float64(*(*TRtreeValue)(unsafe.Pointer(bp))) _readCoord(tls, pCellData, bp) (**(**[10]Tsqlite3_rtree_dbl)(__ccgo_up(bp + 8)))[0] = float64(*(*TRtreeValue)(unsafe.Pointer(bp))) } } else { switch nCoord { case int32(10): _readCoord(tls, pCellData+uintptr(36), bp) (**(**[10]Tsqlite3_rtree_dbl)(__ccgo_up(bp + 8)))[int32(9)] = float64(*(*int32)(unsafe.Pointer(bp))) _readCoord(tls, pCellData+uintptr(32), bp) (**(**[10]Tsqlite3_rtree_dbl)(__ccgo_up(bp + 8)))[int32(8)] = float64(*(*int32)(unsafe.Pointer(bp))) fallthrough case int32(8): _readCoord(tls, pCellData+uintptr(28), bp) (**(**[10]Tsqlite3_rtree_dbl)(__ccgo_up(bp + 8)))[int32(7)] = float64(*(*int32)(unsafe.Pointer(bp))) _readCoord(tls, pCellData+uintptr(24), bp) (**(**[10]Tsqlite3_rtree_dbl)(__ccgo_up(bp + 8)))[int32(6)] = float64(*(*int32)(unsafe.Pointer(bp))) fallthrough case int32(6): _readCoord(tls, pCellData+uintptr(20), bp) (**(**[10]Tsqlite3_rtree_dbl)(__ccgo_up(bp + 8)))[int32(5)] = float64(*(*int32)(unsafe.Pointer(bp))) _readCoord(tls, pCellData+uintptr(16), bp) (**(**[10]Tsqlite3_rtree_dbl)(__ccgo_up(bp + 8)))[int32(4)] = float64(*(*int32)(unsafe.Pointer(bp))) fallthrough case int32(4): _readCoord(tls, pCellData+uintptr(12), bp) (**(**[10]Tsqlite3_rtree_dbl)(__ccgo_up(bp + 8)))[int32(3)] = float64(*(*int32)(unsafe.Pointer(bp))) _readCoord(tls, pCellData+uintptr(8), bp) (**(**[10]Tsqlite3_rtree_dbl)(__ccgo_up(bp + 8)))[int32(2)] = float64(*(*int32)(unsafe.Pointer(bp))) fallthrough default: _readCoord(tls, pCellData+uintptr(4), bp) (**(**[10]Tsqlite3_rtree_dbl)(__ccgo_up(bp + 8)))[int32(1)] = float64(*(*int32)(unsafe.Pointer(bp))) _readCoord(tls, pCellData, bp) (**(**[10]Tsqlite3_rtree_dbl)(__ccgo_up(bp + 8)))[0] = float64(*(*int32)(unsafe.Pointer(bp))) } } if (*TRtreeConstraint)(unsafe.Pointer(pConstraint)).Fop == int32(RTREE_MATCH) { **(**int32)(__ccgo_up(bp + 88)) = 0 rc = (*(*func(*libc.TLS, uintptr, int32, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{*(*uintptr)(unsafe.Pointer(&(*TRtreeConstraint)(unsafe.Pointer(pConstraint)).Fu))})))(tls, pInfo, nCoord, bp+8, bp+88) if **(**int32)(__ccgo_up(bp + 88)) == 0 { **(**int32)(__ccgo_up(peWithin)) = NOT_WITHIN } **(**Tsqlite3_rtree_dbl)(__ccgo_up(prScore)) = float64(0) } else { (*Tsqlite3_rtree_query_info)(unsafe.Pointer(pInfo)).FaCoord = bp + 8 (*Tsqlite3_rtree_query_info)(unsafe.Pointer(pInfo)).FiLevel = libc.Int32FromUint8((*TRtreeSearchPoint)(unsafe.Pointer(pSearch)).FiLevel) - int32(1) v1 = (*TRtreeSearchPoint)(unsafe.Pointer(pSearch)).FrScore (*Tsqlite3_rtree_query_info)(unsafe.Pointer(pInfo)).FrParentScore = v1 (*Tsqlite3_rtree_query_info)(unsafe.Pointer(pInfo)).FrScore = v1 v2 = libc.Int32FromUint8((*TRtreeSearchPoint)(unsafe.Pointer(pSearch)).FeWithin) (*Tsqlite3_rtree_query_info)(unsafe.Pointer(pInfo)).FeParentWithin = v2 (*Tsqlite3_rtree_query_info)(unsafe.Pointer(pInfo)).FeWithin = v2 rc = (*(*func(*libc.TLS, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{*(*uintptr)(unsafe.Pointer(&(*TRtreeConstraint)(unsafe.Pointer(pConstraint)).Fu))})))(tls, pInfo) if (*Tsqlite3_rtree_query_info)(unsafe.Pointer(pInfo)).FeWithin < **(**int32)(__ccgo_up(peWithin)) { **(**int32)(__ccgo_up(peWithin)) = (*Tsqlite3_rtree_query_info)(unsafe.Pointer(pInfo)).FeWithin } if (*Tsqlite3_rtree_query_info)(unsafe.Pointer(pInfo)).FrScore < **(**Tsqlite3_rtree_dbl)(__ccgo_up(prScore)) || **(**Tsqlite3_rtree_dbl)(__ccgo_up(prScore)) < float64(0) { **(**Tsqlite3_rtree_dbl)(__ccgo_up(prScore)) = (*Tsqlite3_rtree_query_info)(unsafe.Pointer(pInfo)).FrScore } } return rc } // C documentation // // /* // ** Continue the search on cursor pCur until the front of the queue // ** contains an entry suitable for returning as a result-set row, // ** or until the RtreeSearchPoint queue is empty, indicating that the // ** query has completed. // */ func _rtreeStepToLeaf(tls *libc.TLS, pCur uintptr) (r int32) { bp := tls.Alloc(16) defer tls.Free(16) var eInt, ii, nCell, nConstraint int32 var p, pCellData, pConstraint, pNode, pRtree, v1 uintptr var x TRtreeSearchPoint var _ /* eWithin at bp+0 */ int32 var _ /* rScore at bp+8 */ Tsqlite3_rtree_dbl var _ /* rc at bp+4 */ int32 _, _, _, _, _, _, _, _, _, _, _ = eInt, ii, nCell, nConstraint, p, pCellData, pConstraint, pNode, pRtree, x, v1 pRtree = (*TRtreeCursor)(unsafe.Pointer(pCur)).Fbase.FpVtab **(**int32)(__ccgo_up(bp + 4)) = SQLITE_OK nConstraint = (*TRtreeCursor)(unsafe.Pointer(pCur)).FnConstraint eInt = libc.BoolInt32(libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FeCoordType) == int32(RTREE_COORD_INT32)) for { v1 = _rtreeSearchPointFirst(tls, pCur) p = v1 if !(v1 != uintptr(0) && libc.Int32FromUint8((*TRtreeSearchPoint)(unsafe.Pointer(p)).FiLevel) > 0) { break } pNode = _rtreeNodeOfFirstSearchPoint(tls, pCur, bp+4) if **(**int32)(__ccgo_up(bp + 4)) != 0 { return **(**int32)(__ccgo_up(bp + 4)) } nCell = _readInt16(tls, (*TRtreeNode)(unsafe.Pointer(pNode)).FzData+2) if nCell > int32(RTREE_MAXCELLS) { return libc.Int32FromInt32(SQLITE_CORRUPT) | libc.Int32FromInt32(1)<= int32(RTREE_MATCH) { **(**int32)(__ccgo_up(bp + 4)) = _rtreeCallbackConstraint(tls, pConstraint, eInt, pCellData, p, bp+8, bp) if **(**int32)(__ccgo_up(bp + 4)) != 0 { return **(**int32)(__ccgo_up(bp + 4)) } } else { if libc.Int32FromUint8((*TRtreeSearchPoint)(unsafe.Pointer(p)).FiLevel) == int32(1) { _rtreeLeafConstraint(tls, pConstraint, eInt, pCellData, bp) } else { _rtreeNonleafConstraint(tls, pConstraint, eInt, pCellData, bp) } } if **(**int32)(__ccgo_up(bp)) == NOT_WITHIN { (*TRtreeSearchPoint)(unsafe.Pointer(p)).FiCell = (*TRtreeSearchPoint)(unsafe.Pointer(p)).FiCell + 1 pCellData = pCellData + uintptr((*TRtree)(unsafe.Pointer(pRtree)).FnBytesPerCell) break } goto _2 _2: ; ii = ii + 1 } if **(**int32)(__ccgo_up(bp)) == NOT_WITHIN { continue } (*TRtreeSearchPoint)(unsafe.Pointer(p)).FiCell = (*TRtreeSearchPoint)(unsafe.Pointer(p)).FiCell + 1 x.FiLevel = libc.Uint8FromInt32(libc.Int32FromUint8((*TRtreeSearchPoint)(unsafe.Pointer(p)).FiLevel) - int32(1)) if x.FiLevel != 0 { x.Fid = _readInt64(tls, pCellData) ii = 0 for { if !(ii < (*TRtreeCursor)(unsafe.Pointer(pCur)).FnPoint) { break } if (**(**TRtreeSearchPoint)(__ccgo_up((*TRtreeCursor)(unsafe.Pointer(pCur)).FaPoint + uintptr(ii)*24))).Fid == x.Fid { return libc.Int32FromInt32(SQLITE_CORRUPT) | libc.Int32FromInt32(1)<= nCell { _rtreeSearchPointPop(tls, pCur) } if **(**Tsqlite3_rtree_dbl)(__ccgo_up(bp + 8)) < float64(0) { **(**Tsqlite3_rtree_dbl)(__ccgo_up(bp + 8)) = float64(0) } p = _rtreeSearchPointNew(tls, pCur, **(**Tsqlite3_rtree_dbl)(__ccgo_up(bp + 8)), x.FiLevel) if p == uintptr(0) { return int32(SQLITE_NOMEM) } (*TRtreeSearchPoint)(unsafe.Pointer(p)).FeWithin = libc.Uint8FromInt32(**(**int32)(__ccgo_up(bp))) (*TRtreeSearchPoint)(unsafe.Pointer(p)).Fid = x.Fid (*TRtreeSearchPoint)(unsafe.Pointer(p)).FiCell = x.FiCell break } if libc.Int32FromUint8((*TRtreeSearchPoint)(unsafe.Pointer(p)).FiCell) >= nCell { _rtreeSearchPointPop(tls, pCur) } } (*TRtreeCursor)(unsafe.Pointer(pCur)).FatEOF = libc.BoolUint8(p == uintptr(0)) return SQLITE_OK } // C documentation // // /* // ** Routines used to compute the sum, average, and total. // ** // ** The SUM() function follows the (broken) SQL standard which means // ** that it returns NULL if it sums over no inputs. TOTAL returns // ** 0.0 in that case. In addition, TOTAL always returns a float where // ** SUM might return an integer if it never encounters a floating point // ** value. TOTAL never fails, but SUM might throw an exception if // ** it overflows an integer. // */ func _sumStep(tls *libc.TLS, context uintptr, argc int32, argv uintptr) { bp := tls.Alloc(16) defer tls.Free(16) var p uintptr var type1 int32 var _ /* x at bp+0 */ Ti64 _, _ = p, type1 _ = argc p = Xsqlite3_aggregate_context(tls, context, int32(40)) type1 = Xsqlite3_value_numeric_type(tls, **(**uintptr)(__ccgo_up(argv))) if p != 0 && type1 != int32(SQLITE_NULL) { (*TSumCtx)(unsafe.Pointer(p)).Fcnt = (*TSumCtx)(unsafe.Pointer(p)).Fcnt + 1 if libc.Int32FromUint8((*TSumCtx)(unsafe.Pointer(p)).Fapprox) == 0 { if type1 != int32(SQLITE_INTEGER) { _kahanBabuskaNeumaierInit(tls, p, (*TSumCtx)(unsafe.Pointer(p)).FiSum) (*TSumCtx)(unsafe.Pointer(p)).Fapprox = uint8(1) _kahanBabuskaNeumaierStep(tls, p, Xsqlite3_value_double(tls, **(**uintptr)(__ccgo_up(argv)))) } else { **(**Ti64)(__ccgo_up(bp)) = (*TSumCtx)(unsafe.Pointer(p)).FiSum if _sqlite3AddInt64(tls, bp, Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(argv)))) == 0 { (*TSumCtx)(unsafe.Pointer(p)).FiSum = **(**Ti64)(__ccgo_up(bp)) } else { (*TSumCtx)(unsafe.Pointer(p)).Fovrfl = uint8(1) _kahanBabuskaNeumaierInit(tls, p, (*TSumCtx)(unsafe.Pointer(p)).FiSum) (*TSumCtx)(unsafe.Pointer(p)).Fapprox = uint8(1) _kahanBabuskaNeumaierStepInt64(tls, p, Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(argv)))) } } } else { if type1 == int32(SQLITE_INTEGER) { _kahanBabuskaNeumaierStepInt64(tls, p, Xsqlite3_value_int64(tls, **(**uintptr)(__ccgo_up(argv)))) } else { (*TSumCtx)(unsafe.Pointer(p)).Fovrfl = uint8(0) _kahanBabuskaNeumaierStep(tls, p, Xsqlite3_value_double(tls, **(**uintptr)(__ccgo_up(argv)))) } } } } // C documentation // // /* // ** Estimate the number of rows that will be returned based on // ** an equality constraint x=VALUE and where that VALUE occurs in // ** the histogram data. This only works when x is the left-most // ** column of an index and sqlite_stat4 histogram data is available // ** for that index. When pExpr==NULL that means the constraint is // ** "x IS NULL" instead of "x=VALUE". // ** // ** Write the estimated row count into *pnRow and return SQLITE_OK. // ** If unable to make an estimate, leave *pnRow unchanged and return // ** non-zero. // ** // ** This routine can fail if it is unable to load a collating sequence // ** required for string comparison, or if unable to allocate memory // ** for a UTF conversion required for comparison. The error is stored // ** in the pParse structure. // */ func _whereEqualScanEst(tls *libc.TLS, pParse uintptr, pBuilder uintptr, pExpr uintptr, pnRow uintptr) (r int32) { bp := tls.Alloc(32) defer tls.Free(32) var nEq, rc int32 var p uintptr var _ /* a at bp+8 */ [2]TtRowcnt var _ /* bOk at bp+24 */ int32 var _ /* pRec at bp+0 */ uintptr _, _, _ = nEq, p, rc p = (*(*struct { FnEq Tu16 FnBtm Tu16 FnTop Tu16 FnDistinctCol Tu16 FpIndex uintptr FpOrderBy uintptr })(unsafe.Pointer((*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FpNew + 24))).FpIndex nEq = libc.Int32FromUint16((*(*struct { FnEq Tu16 FnBtm Tu16 FnTop Tu16 FnDistinctCol Tu16 FpIndex uintptr FpOrderBy uintptr })(unsafe.Pointer((*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FpNew + 24))).FnEq) **(**uintptr)(__ccgo_up(bp)) = (*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FpRec /* If values are not available for all fields of the index to the left ** of this one, no estimate can be made. Return SQLITE_NOTFOUND. */ if (*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FnRecValid < nEq-int32(1) { return int32(SQLITE_NOTFOUND) } /* This is an optimization only. The call to sqlite3Stat4ProbeSetValue() ** below would return the same value. */ if nEq >= libc.Int32FromUint16((*TIndex)(unsafe.Pointer(p)).FnColumn) { **(**TtRowcnt)(__ccgo_up(pnRow)) = uint64(1) return SQLITE_OK } rc = _sqlite3Stat4ProbeSetValue(tls, pParse, p, bp, pExpr, int32(1), nEq-int32(1), bp+24) (*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FpRec = **(**uintptr)(__ccgo_up(bp)) if rc != SQLITE_OK { return rc } if **(**int32)(__ccgo_up(bp + 24)) == 0 { return int32(SQLITE_NOTFOUND) } (*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FnRecValid = nEq _whereKeyStats(tls, pParse, p, **(**uintptr)(__ccgo_up(bp)), 0, bp+8) **(**TtRowcnt)(__ccgo_up(pnRow)) = (**(**[2]TtRowcnt)(__ccgo_up(bp + 8)))[int32(1)] return rc } // C documentation // // /* // ** Try to insert a new prerequisite/cost entry into the WhereOrSet pSet. // ** // ** The new entry might overwrite an existing entry, or it might be // ** appended, or it might be discarded. Do whatever is the right thing // ** so that pSet keeps the N_OR_COST best entries seen so far. // */ func _whereOrInsert(tls *libc.TLS, pSet uintptr, prereq TBitmask, rRun TLogEst, nOut TLogEst) (r int32) { var i, v2 Tu16 var p, v3 uintptr _, _, _, _ = i, p, v2, v3 i = (*TWhereOrSet)(unsafe.Pointer(pSet)).Fn p = pSet + 8 for { if !(libc.Int32FromUint16(i) > 0) { break } if int32(rRun) <= int32((*TWhereOrCost)(unsafe.Pointer(p)).FrRun) && prereq&(*TWhereOrCost)(unsafe.Pointer(p)).Fprereq == prereq { goto whereOrInsert_done } if int32((*TWhereOrCost)(unsafe.Pointer(p)).FrRun) <= int32(rRun) && (*TWhereOrCost)(unsafe.Pointer(p)).Fprereq&prereq == (*TWhereOrCost)(unsafe.Pointer(p)).Fprereq { return 0 } goto _1 _1: ; i = i - 1 p += 16 } if libc.Int32FromUint16((*TWhereOrSet)(unsafe.Pointer(pSet)).Fn) < int32(N_OR_COST) { v3 = pSet v2 = *(*Tu16)(unsafe.Pointer(v3)) *(*Tu16)(unsafe.Pointer(v3)) = *(*Tu16)(unsafe.Pointer(v3)) + 1 p = pSet + 8 + uintptr(v2)*16 (*TWhereOrCost)(unsafe.Pointer(p)).FnOut = nOut } else { p = pSet + 8 i = uint16(1) for { if !(libc.Int32FromUint16(i) < libc.Int32FromUint16((*TWhereOrSet)(unsafe.Pointer(pSet)).Fn)) { break } if int32((*TWhereOrCost)(unsafe.Pointer(p)).FrRun) > int32((**(**TWhereOrCost)(__ccgo_up(pSet + 8 + uintptr(i)*16))).FrRun) { p = pSet + 8 + uintptr(i)*16 } goto _4 _4: ; i = i + 1 } if int32((*TWhereOrCost)(unsafe.Pointer(p)).FrRun) <= int32(rRun) { return 0 } } goto whereOrInsert_done whereOrInsert_done: ; (*TWhereOrCost)(unsafe.Pointer(p)).Fprereq = prereq (*TWhereOrCost)(unsafe.Pointer(p)).FrRun = rRun if int32((*TWhereOrCost)(unsafe.Pointer(p)).FnOut) > int32(nOut) { (*TWhereOrCost)(unsafe.Pointer(p)).FnOut = nOut } return int32(1) } // C documentation // // /* // ** This function is used to estimate the number of rows that will be visited // ** by scanning an index for a range of values. The range may have an upper // ** bound, a lower bound, or both. The WHERE clause terms that set the upper // ** and lower bounds are represented by pLower and pUpper respectively. For // ** example, assuming that index p is on t1(a): // ** // ** ... FROM t1 WHERE a > ? AND a < ? ... // ** |_____| |_____| // ** | | // ** pLower pUpper // ** // ** If either of the upper or lower bound is not present, then NULL is passed in // ** place of the corresponding WhereTerm. // ** // ** The value in (pBuilder->pNew->u.btree.nEq) is the number of the index // ** column subject to the range constraint. Or, equivalently, the number of // ** equality constraints optimized by the proposed index scan. For example, // ** assuming index p is on t1(a, b), and the SQL query is: // ** // ** ... FROM t1 WHERE a = ? AND b > ? AND b < ? ... // ** // ** then nEq is set to 1 (as the range restricted column, b, is the second // ** left-most column of the index). Or, if the query is: // ** // ** ... FROM t1 WHERE a > ? AND a < ? ... // ** // ** then nEq is set to 0. // ** // ** When this function is called, *pnOut is set to the sqlite3LogEst() of the // ** number of rows that the index scan is expected to visit without // ** considering the range constraints. If nEq is 0, then *pnOut is the number of // ** rows in the index. Assuming no error occurs, *pnOut is adjusted (reduced) // ** to account for the range constraints pLower and pUpper. // ** // ** In the absence of sqlite_stat4 ANALYZE data, or if such data cannot be // ** used, a single range inequality reduces the search space by a factor of 4. // ** and a pair of constraints (x>? AND x 0 && nEq < (*TIndex)(unsafe.Pointer(p)).FnSampleCol && (*Tsqlite3)(unsafe.Pointer((*TParse)(unsafe.Pointer(pParse)).Fdb)).FdbOptFlags&libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_Stat4)) == uint32(0) { if nEq == (*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FnRecValid { **(**uintptr)(__ccgo_up(bp)) = (*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FpRec nBtm = libc.Int32FromUint16((*(*struct { FnEq Tu16 FnBtm Tu16 FnTop Tu16 FnDistinctCol Tu16 FpIndex uintptr FpOrderBy uintptr })(unsafe.Pointer(pLoop + 24))).FnBtm) nTop = libc.Int32FromUint16((*(*struct { FnEq Tu16 FnBtm Tu16 FnTop Tu16 FnDistinctCol Tu16 FpIndex uintptr FpOrderBy uintptr })(unsafe.Pointer(pLoop + 24))).FnTop) /* Rows less than the upper bound */ iLwrIdx = -int32(2) /* aSample[] for the lower bound */ iUprIdx = -int32(1) /* aSample[] for the upper bound */ if **(**uintptr)(__ccgo_up(bp)) != 0 { (*TUnpackedRecord)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FnField = libc.Uint16FromInt32((*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FnRecValid) } /* Determine iLower and iUpper using ($P) only. */ if nEq == 0 { iLower = uint64(0) iUpper = (*TIndex)(unsafe.Pointer(p)).FnRowEst0 } else { /* Note: this call could be optimized away - since the same values must ** have been requested when testing key $P in whereEqualScanEst(). */ _whereKeyStats(tls, pParse, p, **(**uintptr)(__ccgo_up(bp)), 0, bp+8) iLower = (**(**[2]TtRowcnt)(__ccgo_up(bp + 8)))[0] iUpper = (**(**[2]TtRowcnt)(__ccgo_up(bp + 8)))[0] + (**(**[2]TtRowcnt)(__ccgo_up(bp + 8)))[int32(1)] } if **(**Tu8)(__ccgo_up((*TIndex)(unsafe.Pointer(p)).FaSortOrder + uintptr(nEq))) != 0 { /* The roles of pLower and pUpper are swapped for a DESC index */ t = pLower pLower = pUpper pUpper = t t1 = nBtm nBtm = nTop nTop = t1 } /* If possible, improve on the iLower estimate using ($P:$L). */ if pLower != 0 { /* Values extracted from pExpr */ pExpr = (*TExpr)(unsafe.Pointer((*TWhereTerm)(unsafe.Pointer(pLower)).FpExpr)).FpRight rc = _sqlite3Stat4ProbeSetValue(tls, pParse, p, bp, pExpr, nBtm, nEq, bp+24) if rc == SQLITE_OK && **(**int32)(__ccgo_up(bp + 24)) != 0 { mask = libc.Uint16FromInt32(libc.Int32FromInt32(WO_EQ)<<(libc.Int32FromInt32(TK_GT)-libc.Int32FromInt32(TK_EQ)) | libc.Int32FromInt32(WO_EQ)<<(libc.Int32FromInt32(TK_LE)-libc.Int32FromInt32(TK_EQ))) if _sqlite3ExprVectorSize(tls, pExpr) > **(**int32)(__ccgo_up(bp + 24)) { mask = libc.Uint16FromInt32(libc.Int32FromInt32(WO_EQ)<<(libc.Int32FromInt32(TK_LE)-libc.Int32FromInt32(TK_EQ)) | libc.Int32FromInt32(WO_EQ)<<(libc.Int32FromInt32(TK_LT)-libc.Int32FromInt32(TK_EQ))) } iLwrIdx = _whereKeyStats(tls, pParse, p, **(**uintptr)(__ccgo_up(bp)), 0, bp+8) if libc.Int32FromUint16((*TWhereTerm)(unsafe.Pointer(pLower)).FeOperator)&libc.Int32FromUint16(mask) != 0 { v1 = (**(**[2]TtRowcnt)(__ccgo_up(bp + 8)))[int32(1)] } else { v1 = uint64(0) } iNew = (**(**[2]TtRowcnt)(__ccgo_up(bp + 8)))[0] + v1 if iNew > iLower { iLower = iNew } nOut = nOut - 1 pLower = uintptr(0) } } /* If possible, improve on the iUpper estimate using ($P:$U). */ if pUpper != 0 { /* Values extracted from pExpr */ pExpr1 = (*TExpr)(unsafe.Pointer((*TWhereTerm)(unsafe.Pointer(pUpper)).FpExpr)).FpRight rc = _sqlite3Stat4ProbeSetValue(tls, pParse, p, bp, pExpr1, nTop, nEq, bp+28) if rc == SQLITE_OK && **(**int32)(__ccgo_up(bp + 28)) != 0 { mask1 = libc.Uint16FromInt32(libc.Int32FromInt32(WO_EQ)<<(libc.Int32FromInt32(TK_GT)-libc.Int32FromInt32(TK_EQ)) | libc.Int32FromInt32(WO_EQ)<<(libc.Int32FromInt32(TK_LE)-libc.Int32FromInt32(TK_EQ))) if _sqlite3ExprVectorSize(tls, pExpr1) > **(**int32)(__ccgo_up(bp + 28)) { mask1 = libc.Uint16FromInt32(libc.Int32FromInt32(WO_EQ)<<(libc.Int32FromInt32(TK_LE)-libc.Int32FromInt32(TK_EQ)) | libc.Int32FromInt32(WO_EQ)<<(libc.Int32FromInt32(TK_LT)-libc.Int32FromInt32(TK_EQ))) } iUprIdx = _whereKeyStats(tls, pParse, p, **(**uintptr)(__ccgo_up(bp)), int32(1), bp+8) if libc.Int32FromUint16((*TWhereTerm)(unsafe.Pointer(pUpper)).FeOperator)&libc.Int32FromUint16(mask1) != 0 { v1 = (**(**[2]TtRowcnt)(__ccgo_up(bp + 8)))[int32(1)] } else { v1 = uint64(0) } iNew1 = (**(**[2]TtRowcnt)(__ccgo_up(bp + 8)))[0] + v1 if iNew1 < iUpper { iUpper = iNew1 } nOut = nOut - 1 pUpper = uintptr(0) } } (*TWhereLoopBuilder)(unsafe.Pointer(pBuilder)).FpRec = **(**uintptr)(__ccgo_up(bp)) if rc == SQLITE_OK { if iUpper > iLower { nNew = _sqlite3LogEst(tls, iUpper-iLower) /* TUNING: If both iUpper and iLower are derived from the same ** sample, then assume they are 4x more selective. This brings ** the estimated selectivity more in line with what it would be ** if estimated without the use of STAT4 tables. */ if iLwrIdx == iUprIdx { nNew = int16(int32(nNew) - libc.Int32FromInt32(20)) } } else { nNew = int16(10) } if int32(nNew) < nOut { nOut = int32(nNew) } } } else { **(**int32)(__ccgo_up(bp + 32)) = 0 rc = _whereRangeSkipScanEst(tls, pParse, pLower, pUpper, pLoop, bp+32) if **(**int32)(__ccgo_up(bp + 32)) != 0 { return rc } } } nNew = _whereRangeAdjust(tls, pLower, int16(nOut)) nNew = _whereRangeAdjust(tls, pUpper, nNew) /* TUNING: If there is both an upper and lower limit and neither limit ** has an application-defined likelihood(), assume the range is ** reduced by an additional 75%. This means that, by default, an open-ended ** range query (e.g. col > ?) is assumed to match 1/4 of the rows in the ** index. While a closed range (e.g. col BETWEEN ? AND ?) is estimated to ** match 1/64 of the index. */ if pLower != 0 && int32((*TWhereTerm)(unsafe.Pointer(pLower)).FtruthProb) > 0 && pUpper != 0 && int32((*TWhereTerm)(unsafe.Pointer(pUpper)).FtruthProb) > 0 { nNew = int16(int32(nNew) - libc.Int32FromInt32(20)) } nOut = nOut - (libc.BoolInt32(pLower != uintptr(0)) + libc.BoolInt32(pUpper != uintptr(0))) if int32(nNew) < int32(10) { nNew = int16(10) } if int32(nNew) < nOut { nOut = int32(nNew) } (*TWhereLoop)(unsafe.Pointer(pLoop)).FnOut = int16(nOut) return rc }