// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT. //go:build (linux && arm64) || (linux && ppc64le) || (linux && riscv64) || (linux && s390x) package sqlite3 import ( "unsafe" "modernc.org/libc" ) type Tfpos_t = struct { F__lldata [0]int64 F__align [0]float64 F__opaque [16]uint8 } // C documentation // // /* // ** Given the name of a compile-time option, return true if that option // ** was used and false if not. // ** // ** The name can optionally begin with "SQLITE_" but the "SQLITE_" prefix // ** is not required for a match. // */ func Xsqlite3_compileoption_used(tls *libc.TLS, zOptName uintptr) (r int32) { bp := tls.Alloc(16) defer tls.Free(16) var azCompileOpt uintptr var i, n int32 var _ /* nOpt at bp+0 */ int32 _, _, _ = azCompileOpt, i, n azCompileOpt = _sqlite3CompileOptions(tls, bp) if Xsqlite3_strnicmp(tls, zOptName, __ccgo_ts+26392, int32(7)) == 0 { zOptName = zOptName + uintptr(7) } n = _sqlite3Strlen30(tls, zOptName) /* Since nOpt is normally in single digits, a linear search is ** adequate. No need for a binary search. */ i = 0 for { if !(i < **(**int32)(__ccgo_up(bp))) { break } if Xsqlite3_strnicmp(tls, zOptName, **(**uintptr)(__ccgo_up(azCompileOpt + uintptr(i)*8)), n) == 0 && _sqlite3IsIdChar(tls, uint8(**(**uint8)(__ccgo_up(**(**uintptr)(__ccgo_up(azCompileOpt + uintptr(i)*8)) + uintptr(n))))) == 0 { return int32(1) } goto _1 _1: ; i = i + 1 } return 0 } // C documentation // // /* // ** Execute SQL code. Return one of the SQLITE_ success/failure // ** codes. Also write an error message into memory obtained from // ** malloc() and make *pzErrMsg point to that message. // ** // ** If the SQL is a query, then for each row in the query result // ** the xCallback() function is called. pArg becomes the first // ** argument to xCallback(). If xCallback=NULL then no callback // ** is invoked, even for queries. // */ func Xsqlite3_exec(tls *libc.TLS, db uintptr, zSql uintptr, __ccgo_fp_xCallback Tsqlite3_callback, pArg uintptr, pzErrMsg uintptr) (r int32) { bp := tls.Alloc(16) defer tls.Free(16) var azCols, azVals uintptr var callbackIsInit, i, nCol, rc int32 var _ /* pStmt at bp+8 */ uintptr var _ /* zLeftover at bp+0 */ uintptr _, _, _, _, _, _ = azCols, azVals, callbackIsInit, i, nCol, rc rc = SQLITE_OK /* Tail of unprocessed SQL */ **(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0) /* The current SQL statement */ azCols = uintptr(0) /* True if callback data is initialized */ if !(_sqlite3SafetyCheckOk(tls, db) != 0) { return _sqlite3MisuseError(tls, int32(142492)) } if zSql == uintptr(0) { zSql = __ccgo_ts + 1704 } Xsqlite3_mutex_enter(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex) _sqlite3Error(tls, db, SQLITE_OK) for rc == SQLITE_OK && **(**uint8)(__ccgo_up(zSql)) != 0 { nCol = 0 azVals = uintptr(0) **(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0) rc = Xsqlite3_prepare_v2(tls, db, zSql, -int32(1), bp+8, bp) if rc != SQLITE_OK { continue } if !(**(**uintptr)(__ccgo_up(bp + 8)) != 0) { /* this happens for a comment or white-space */ zSql = **(**uintptr)(__ccgo_up(bp)) continue } callbackIsInit = 0 for int32(1) != 0 { rc = Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp + 8))) /* Invoke the callback function if required */ if __ccgo_fp_xCallback != 0 && (int32(SQLITE_ROW) == rc || int32(SQLITE_DONE) == rc && !(callbackIsInit != 0) && (*Tsqlite3)(unsafe.Pointer(db)).Fflags&uint64(SQLITE_NullCallback) != 0) { if !(callbackIsInit != 0) { nCol = Xsqlite3_column_count(tls, **(**uintptr)(__ccgo_up(bp + 8))) azCols = _sqlite3DbMallocRaw(tls, db, uint64(libc.Uint64FromInt32(libc.Int32FromInt32(2)*nCol+libc.Int32FromInt32(1))*uint64(8))) if azCols == uintptr(0) { goto exec_out } i = 0 for { if !(i < nCol) { break } **(**uintptr)(__ccgo_up(azCols + uintptr(i)*8)) = Xsqlite3_column_name(tls, **(**uintptr)(__ccgo_up(bp + 8)), i) /* sqlite3VdbeSetColName() installs column names as UTF8 ** strings so there is no way for sqlite3_column_name() to fail. */ goto _1 _1: ; i = i + 1 } callbackIsInit = int32(1) } if rc == int32(SQLITE_ROW) { azVals = azCols + uintptr(nCol)*8 i = 0 for { if !(i < nCol) { break } **(**uintptr)(__ccgo_up(azVals + uintptr(i)*8)) = Xsqlite3_column_text(tls, **(**uintptr)(__ccgo_up(bp + 8)), i) if !(**(**uintptr)(__ccgo_up(azVals + uintptr(i)*8)) != 0) && Xsqlite3_column_type(tls, **(**uintptr)(__ccgo_up(bp + 8)), i) != int32(SQLITE_NULL) { _sqlite3OomFault(tls, db) goto exec_out } goto _2 _2: ; i = i + 1 } **(**uintptr)(__ccgo_up(azVals + uintptr(i)*8)) = uintptr(0) } if (*(*func(*libc.TLS, uintptr, int32, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{__ccgo_fp_xCallback})))(tls, pArg, nCol, azVals, azCols) != 0 { /* EVIDENCE-OF: R-38229-40159 If the callback function to ** sqlite3_exec() returns non-zero, then sqlite3_exec() will ** return SQLITE_ABORT. */ rc = int32(SQLITE_ABORT) _sqlite3VdbeFinalize(tls, **(**uintptr)(__ccgo_up(bp + 8))) **(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0) _sqlite3Error(tls, db, int32(SQLITE_ABORT)) goto exec_out } } if rc != int32(SQLITE_ROW) { rc = _sqlite3VdbeFinalize(tls, **(**uintptr)(__ccgo_up(bp + 8))) **(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0) zSql = **(**uintptr)(__ccgo_up(bp)) for libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(zSql)))])&int32(0x01) != 0 { zSql = zSql + 1 } break } } _sqlite3DbFree(tls, db, azCols) azCols = uintptr(0) } goto exec_out exec_out: ; if **(**uintptr)(__ccgo_up(bp + 8)) != 0 { _sqlite3VdbeFinalize(tls, **(**uintptr)(__ccgo_up(bp + 8))) } _sqlite3DbFree(tls, db, azCols) rc = _sqlite3ApiExit(tls, db, rc) if rc != SQLITE_OK && pzErrMsg != 0 { **(**uintptr)(__ccgo_up(pzErrMsg)) = _sqlite3DbStrDup(tls, uintptr(0), Xsqlite3_errmsg(tls, db)) if **(**uintptr)(__ccgo_up(pzErrMsg)) == uintptr(0) { rc = int32(SQLITE_NOMEM) _sqlite3Error(tls, db, int32(SQLITE_NOMEM)) } } else { if pzErrMsg != 0 { **(**uintptr)(__ccgo_up(pzErrMsg)) = uintptr(0) } } Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex) return rc } // C documentation // // /* // ** Checkpoint database zDb. // */ func Xsqlite3_wal_checkpoint_v2(tls *libc.TLS, db uintptr, zDb uintptr, eMode int32, pnLog uintptr, pnCkpt uintptr) (r int32) { bp := tls.Alloc(16) defer tls.Free(16) var iDb, rc int32 _, _ = iDb, rc /* Schema to checkpoint */ /* Initialize the output variables to -1 in case an error occurs. */ if pnLog != 0 { **(**int32)(__ccgo_up(pnLog)) = -int32(1) } if pnCkpt != 0 { **(**int32)(__ccgo_up(pnCkpt)) = -int32(1) } if eMode < -int32(1) || eMode > int32(SQLITE_CHECKPOINT_TRUNCATE) { /* EVIDENCE-OF: R-03996-12088 The M parameter must be a valid checkpoint ** mode: */ return _sqlite3MisuseError(tls, int32(190116)) } Xsqlite3_mutex_enter(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex) if zDb != 0 && **(**uint8)(__ccgo_up(zDb)) != 0 { iDb = _sqlite3FindDbName(tls, db, zDb) } else { iDb = libc.Int32FromInt32(SQLITE_MAX_ATTACHED) + libc.Int32FromInt32(2) /* This means process all schemas */ } if iDb < 0 { rc = int32(SQLITE_ERROR) _sqlite3ErrorWithMsg(tls, db, int32(SQLITE_ERROR), __ccgo_ts+26053, libc.VaList(bp+8, zDb)) } else { (*Tsqlite3)(unsafe.Pointer(db)).FbusyHandler.FnBusy = 0 rc = _sqlite3Checkpoint(tls, db, iDb, eMode, pnLog, pnCkpt) _sqlite3Error(tls, db, rc) } rc = _sqlite3ApiExit(tls, db, rc) /* If there are no active statements, clear the interrupt flag at this ** point. */ if (*Tsqlite3)(unsafe.Pointer(db)).FnVdbeActive == 0 { libc.AtomicStoreNInt32(db+432, libc.Int32FromInt32(0), libc.Int32FromInt32(__ATOMIC_RELAXED)) } Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex) return rc } // C documentation // // /* // ** Fill the InitData structure with an error message that indicates // ** that the database is corrupt. // */ func _corruptSchema(tls *libc.TLS, pData uintptr, azObj uintptr, zExtra uintptr) { bp := tls.Alloc(48) defer tls.Free(48) var db, z, zObj, v1 uintptr _, _, _, _ = db, z, zObj, v1 db = (*TInitData)(unsafe.Pointer(pData)).Fdb if (*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0 { (*TInitData)(unsafe.Pointer(pData)).Frc = int32(SQLITE_NOMEM) } else { if **(**uintptr)(__ccgo_up((*TInitData)(unsafe.Pointer(pData)).FpzErrMsg)) != uintptr(0) { /* A error message has already been generated. Do not overwrite it */ } else { if (*TInitData)(unsafe.Pointer(pData)).FmInitFlags&libc.Uint32FromInt32(libc.Int32FromInt32(INITFLAG_AlterMask)) != 0 { **(**uintptr)(__ccgo_up((*TInitData)(unsafe.Pointer(pData)).FpzErrMsg)) = _sqlite3MPrintf(tls, db, __ccgo_ts+20051, libc.VaList(bp+8, **(**uintptr)(__ccgo_up(azObj)), **(**uintptr)(__ccgo_up(azObj + 1*8)), _azAlterType[(*TInitData)(unsafe.Pointer(pData)).FmInitFlags&uint32(INITFLAG_AlterMask)-uint32(1)], zExtra)) (*TInitData)(unsafe.Pointer(pData)).Frc = int32(SQLITE_ERROR) } else { if (*Tsqlite3)(unsafe.Pointer(db)).Fflags&uint64(SQLITE_WriteSchema) != 0 { (*TInitData)(unsafe.Pointer(pData)).Frc = _sqlite3CorruptError(tls, int32(148102)) } else { if **(**uintptr)(__ccgo_up(azObj + 1*8)) != 0 { v1 = **(**uintptr)(__ccgo_up(azObj + 1*8)) } else { v1 = __ccgo_ts + 5287 } zObj = v1 z = _sqlite3MPrintf(tls, db, __ccgo_ts+20079, libc.VaList(bp+8, zObj)) if zExtra != 0 && **(**uint8)(__ccgo_up(zExtra)) != 0 { z = _sqlite3MPrintf(tls, db, __ccgo_ts+20110, libc.VaList(bp+8, z, zExtra)) } **(**uintptr)(__ccgo_up((*TInitData)(unsafe.Pointer(pData)).FpzErrMsg)) = z (*TInitData)(unsafe.Pointer(pData)).Frc = _sqlite3CorruptError(tls, int32(148109)) } } } } } // C documentation // // /* // ** Generate a CREATE TABLE statement appropriate for the given // ** table. Memory to hold the text of the statement is obtained // ** from sqliteMalloc() and must be freed by the calling function. // */ func _createTableStmt(tls *libc.TLS, db uintptr, p uintptr) (r uintptr) { bp := tls.Alloc(16) defer tls.Free(16) var i, len1, v2 int32 var n Ti64 var pCol, zEnd, zSep, zSep2, zStmt, zType uintptr var _ /* k at bp+0 */ int32 _, _, _, _, _, _, _, _, _, _ = i, len1, n, pCol, zEnd, zSep, zSep2, zStmt, zType, v2 n = 0 pCol = (*TTable)(unsafe.Pointer(p)).FaCol i = libc.Int32FromInt32(0) for { if !(i < int32((*TTable)(unsafe.Pointer(p)).FnCol)) { break } n = n + (_identLength(tls, (*TColumn)(unsafe.Pointer(pCol)).FzCnName) + int64(5)) goto _1 _1: ; i = i + 1 pCol += 16 } n = n + _identLength(tls, (*TTable)(unsafe.Pointer(p)).FzName) if n < int64(50) { zSep = __ccgo_ts + 1704 zSep2 = __ccgo_ts + 14374 zEnd = __ccgo_ts + 5285 } else { zSep = __ccgo_ts + 14376 zSep2 = __ccgo_ts + 14380 zEnd = __ccgo_ts + 14385 } n = n + int64(int32(35)+int32(6)*int32((*TTable)(unsafe.Pointer(p)).FnCol)) zStmt = _sqlite3DbMallocRaw(tls, uintptr(0), libc.Uint64FromInt64(n)) if zStmt == uintptr(0) { _sqlite3OomFault(tls, db) return uintptr(0) } libc.Xmemcpy(tls, zStmt, __ccgo_ts+14388, uint64(13)) **(**int32)(__ccgo_up(bp)) = int32(13) _identPut(tls, zStmt, bp, (*TTable)(unsafe.Pointer(p)).FzName) v2 = **(**int32)(__ccgo_up(bp)) **(**int32)(__ccgo_up(bp)) = **(**int32)(__ccgo_up(bp)) + 1 **(**uint8)(__ccgo_up(zStmt + uintptr(v2))) = uint8('(') pCol = (*TTable)(unsafe.Pointer(p)).FaCol i = libc.Int32FromInt32(0) for { if !(i < int32((*TTable)(unsafe.Pointer(p)).FnCol)) { break } len1 = _sqlite3Strlen30(tls, zSep) libc.Xmemcpy(tls, zStmt+uintptr(**(**int32)(__ccgo_up(bp))), zSep, libc.Uint64FromInt32(len1)) **(**int32)(__ccgo_up(bp)) = **(**int32)(__ccgo_up(bp)) + len1 zSep = zSep2 _identPut(tls, zStmt, bp, (*TColumn)(unsafe.Pointer(pCol)).FzCnName) zType = _azType1[libc.Int32FromUint8((*TColumn)(unsafe.Pointer(pCol)).Faffinity)-int32(SQLITE_AFF_BLOB)] len1 = _sqlite3Strlen30(tls, zType) libc.Xmemcpy(tls, zStmt+uintptr(**(**int32)(__ccgo_up(bp))), zType, libc.Uint64FromInt32(len1)) **(**int32)(__ccgo_up(bp)) = **(**int32)(__ccgo_up(bp)) + len1 goto _3 _3: ; i = i + 1 pCol += 16 } len1 = _sqlite3Strlen30(tls, zEnd) libc.Xmemcpy(tls, zStmt+uintptr(**(**int32)(__ccgo_up(bp))), zEnd, libc.Uint64FromInt32(len1+int32(1))) return zStmt } // C documentation // // /* // ** An SQL user-function registered to do the work of an DETACH statement. The // ** three arguments to the function come directly from a detach statement: // ** // ** DETACH DATABASE x // ** // ** SELECT sqlite_detach(x) // */ func _detachFunc(tls *libc.TLS, context uintptr, NotUsed int32, argv uintptr) { bp := tls.Alloc(144) defer tls.Free(144) var db, pDb, pEntry, pTrig, zName uintptr var i int32 var _ /* zErr at bp+0 */ [128]uint8 _, _, _, _, _, _ = db, i, pDb, pEntry, pTrig, zName zName = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv))) db = Xsqlite3_context_db_handle(tls, context) pDb = uintptr(0) _ = NotUsed if zName == uintptr(0) { zName = __ccgo_ts + 1704 } i = 0 for { if !(i < (*Tsqlite3)(unsafe.Pointer(db)).FnDb) { break } pDb = (*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(i)*32 if (*TDb)(unsafe.Pointer(pDb)).FpBt == uintptr(0) { goto _1 } if _sqlite3DbIsNamed(tls, db, i, zName) != 0 { break } goto _1 _1: ; i = i + 1 } if i >= (*Tsqlite3)(unsafe.Pointer(db)).FnDb { Xsqlite3_snprintf(tls, int32(128), bp, __ccgo_ts+13470, libc.VaList(bp+136, zName)) goto detach_error } if i < int32(2) { Xsqlite3_snprintf(tls, int32(128), bp, __ccgo_ts+13491, libc.VaList(bp+136, zName)) goto detach_error } if _sqlite3BtreeTxnState(tls, (*TDb)(unsafe.Pointer(pDb)).FpBt) != SQLITE_TXN_NONE || _sqlite3BtreeIsInBackup(tls, (*TDb)(unsafe.Pointer(pDb)).FpBt) != 0 { Xsqlite3_snprintf(tls, int32(128), bp, __ccgo_ts+13517, libc.VaList(bp+136, zName)) goto detach_error } /* If any TEMP triggers reference the schema being detached, move those ** triggers to reference the TEMP schema itself. */ pEntry = (*THash)(unsafe.Pointer((**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + 1*32))).FpSchema + 56)).Ffirst for pEntry != 0 { pTrig = (*THashElem)(unsafe.Pointer(pEntry)).Fdata if (*TTrigger)(unsafe.Pointer(pTrig)).FpTabSchema == (*TDb)(unsafe.Pointer(pDb)).FpSchema { (*TTrigger)(unsafe.Pointer(pTrig)).FpTabSchema = (*TTrigger)(unsafe.Pointer(pTrig)).FpSchema } pEntry = (*THashElem)(unsafe.Pointer(pEntry)).Fnext } _sqlite3BtreeClose(tls, (*TDb)(unsafe.Pointer(pDb)).FpBt) (*TDb)(unsafe.Pointer(pDb)).FpBt = uintptr(0) (*TDb)(unsafe.Pointer(pDb)).FpSchema = uintptr(0) _sqlite3CollapseDatabaseArray(tls, db) return goto detach_error detach_error: ; Xsqlite3_result_error(tls, context, bp, -int32(1)) } // C documentation // // /* // ** The input to this routine is an WhereTerm structure with only the // ** "pExpr" field filled in. The job of this routine is to analyze the // ** subexpression and populate all the other fields of the WhereTerm // ** structure. // ** // ** If the expression is of the form " X" it gets commuted // ** to the standard form of "X ". // ** // ** If the expression is of the form "X Y" where both X and Y are // ** columns, then the original expression is unchanged and a new virtual // ** term of the form "Y X" is added to the WHERE clause and // ** analyzed separately. The original term is marked with TERM_COPIED // ** and the new term is marked with TERM_DYNAMIC (because it's pExpr // ** needs to be freed with the WhereClause) and TERM_VIRTUAL (because it // ** is a commuted copy of a prior term.) The original term has nChild=1 // ** and the copy has idxParent set to the index of the original term. // */ func _exprAnalyze(tls *libc.TLS, pSrc uintptr, pWC uintptr, idxTerm int32) { bp := tls.Alloc(48) defer tls.Free(48) var c, v12 uint8 var db, pC, pDup, pExpr, pLeft, pLeft1, pLeft2, pLeft3, pList, pMaskSet, pNew, pNew1, pNewExpr, pNewExpr1, pNewExpr11, pNewExpr2, pNewExpr21, pNewTerm, pNewTerm1, pParse, pRight, pRight1, pStr2, pTerm, pWInfo, t, zCollSeqName, v1 uintptr var eExtraOp, opMask, wtFlags Tu16 var extraRight, prereqAll, prereqColumn, prereqExpr, prereqLeft, x TBitmask var i, i1, i2, i3, idxNew, idxNew1, idxNew11, idxNew2, idxNew21, idxNew3, idxNew4, idxNew5, nLeft, op, res, v2 int32 var v15 bool var _ /* aiCurCol at bp+24 */ [2]int32 var _ /* eOp2 at bp+16 */ uint8 var _ /* isComplete at bp+8 */ int32 var _ /* noCase at bp+12 */ int32 var _ /* pLeft at bp+40 */ uintptr var _ /* pRight at bp+32 */ uintptr var _ /* pStr1 at bp+0 */ uintptr _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = c, db, eExtraOp, extraRight, i, i1, i2, i3, idxNew, idxNew1, idxNew11, idxNew2, idxNew21, idxNew3, idxNew4, idxNew5, nLeft, op, opMask, pC, pDup, pExpr, pLeft, pLeft1, pLeft2, pLeft3, pList, pMaskSet, pNew, pNew1, pNewExpr, pNewExpr1, pNewExpr11, pNewExpr2, pNewExpr21, pNewTerm, pNewTerm1, pParse, pRight, pRight1, pStr2, pTerm, pWInfo, prereqAll, prereqColumn, prereqExpr, prereqLeft, res, t, wtFlags, x, zCollSeqName, v1, v12, v15, v2 pWInfo = (*TWhereClause)(unsafe.Pointer(pWC)).FpWInfo /* Prerequisites of pExpr */ extraRight = uint64(0) /* Extra dependencies on LEFT JOIN */ **(**uintptr)(__ccgo_up(bp)) = uintptr(0) /* RHS of LIKE/GLOB operator */ **(**int32)(__ccgo_up(bp + 8)) = 0 /* RHS of LIKE/GLOB ends with wildcard */ **(**int32)(__ccgo_up(bp + 12)) = 0 /* Top-level operator. pExpr->op */ pParse = (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpParse /* Parsing context */ db = (*TParse)(unsafe.Pointer(pParse)).Fdb /* Database connection */ **(**uint8)(__ccgo_up(bp + 16)) = uint8(0) /* Number of elements on left side vector */ if (*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0 { return } pTerm = (*TWhereClause)(unsafe.Pointer(pWC)).Fa + uintptr(idxTerm)*56 pMaskSet = pWInfo + 592 pExpr = (*TWhereTerm)(unsafe.Pointer(pTerm)).FpExpr /* Because malloc() has not failed */ (*TWhereMaskSet)(unsafe.Pointer(pMaskSet)).FbVarSelect = 0 prereqLeft = _sqlite3WhereExprUsage(tls, pMaskSet, (*TExpr)(unsafe.Pointer(pExpr)).FpLeft) op = libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) if op == int32(TK_IN) { if _sqlite3ExprCheckIN(tls, pParse, pExpr) != 0 { return } if (*TExpr)(unsafe.Pointer(pExpr)).Fflags&uint32(EP_xIsSelect) != uint32(0) { (*TWhereTerm)(unsafe.Pointer(pTerm)).FprereqRight = _exprSelectUsage(tls, pMaskSet, *(*uintptr)(unsafe.Pointer(pExpr + 32))) } else { (*TWhereTerm)(unsafe.Pointer(pTerm)).FprereqRight = _sqlite3WhereExprListUsage(tls, pMaskSet, *(*uintptr)(unsafe.Pointer(pExpr + 32))) } prereqAll = prereqLeft | (*TWhereTerm)(unsafe.Pointer(pTerm)).FprereqRight } else { (*TWhereTerm)(unsafe.Pointer(pTerm)).FprereqRight = _sqlite3WhereExprUsage(tls, pMaskSet, (*TExpr)(unsafe.Pointer(pExpr)).FpRight) if (*TExpr)(unsafe.Pointer(pExpr)).FpLeft == uintptr(0) || (*TExpr)(unsafe.Pointer(pExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_xIsSelect)|libc.Int32FromInt32(EP_IfNullRow)) != uint32(0) || *(*uintptr)(unsafe.Pointer(pExpr + 32)) != uintptr(0) { prereqAll = _sqlite3WhereExprUsageNN(tls, pMaskSet, pExpr) } else { prereqAll = prereqLeft | (*TWhereTerm)(unsafe.Pointer(pTerm)).FprereqRight } } if (*TWhereMaskSet)(unsafe.Pointer(pMaskSet)).FbVarSelect != 0 { v1 = pTerm + 18 *(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) | libc.Int32FromInt32(TERM_VARSELECT)) } if (*TExpr)(unsafe.Pointer(pExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_OuterON)|libc.Int32FromInt32(EP_InnerON)) != uint32(0) { x = _sqlite3WhereGetMask(tls, pMaskSet, *(*int32)(unsafe.Pointer(pExpr + 52))) if (*TExpr)(unsafe.Pointer(pExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_OuterON)) != uint32(0) { prereqAll = prereqAll | x extraRight = x - uint64(1) /* ON clause terms may not be used with an index ** on left table of a LEFT JOIN. Ticket #3015 */ } else { if prereqAll>>libc.Int32FromInt32(1) >= x { **(**Tu32)(__ccgo_up(pExpr + 4)) &= ^libc.Uint32FromInt32(libc.Int32FromInt32(EP_InnerON)) } } } (*TWhereTerm)(unsafe.Pointer(pTerm)).FprereqAll = prereqAll (*TWhereTerm)(unsafe.Pointer(pTerm)).FleftCursor = -int32(1) (*TWhereTerm)(unsafe.Pointer(pTerm)).FiParent = -int32(1) (*TWhereTerm)(unsafe.Pointer(pTerm)).FeOperator = uint16(0) if _allowedOp(tls, op) != 0 { pLeft = _sqlite3ExprSkipCollate(tls, (*TExpr)(unsafe.Pointer(pExpr)).FpLeft) pRight = _sqlite3ExprSkipCollate(tls, (*TExpr)(unsafe.Pointer(pExpr)).FpRight) if (*TWhereTerm)(unsafe.Pointer(pTerm)).FprereqRight&prereqLeft == uint64(0) { v2 = int32(WO_ALL) } else { v2 = int32(WO_EQUIV) } opMask = libc.Uint16FromInt32(v2) if (*(*struct { FleftColumn int32 FiField int32 })(unsafe.Pointer(pTerm + 32))).FiField > 0 { pLeft = (*(*TExprList_item)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pLeft + 32)) + 8 + uintptr((*(*struct { FleftColumn int32 FiField int32 })(unsafe.Pointer(pTerm + 32))).FiField-int32(1))*32))).FpExpr } if _exprMightBeIndexed(tls, pSrc, bp+24, pLeft, op) != 0 { (*TWhereTerm)(unsafe.Pointer(pTerm)).FleftCursor = (**(**[2]int32)(__ccgo_up(bp + 24)))[0] (*(*struct { FleftColumn int32 FiField int32 })(unsafe.Pointer(pTerm + 32))).FleftColumn = (**(**[2]int32)(__ccgo_up(bp + 24)))[int32(1)] (*TWhereTerm)(unsafe.Pointer(pTerm)).FeOperator = libc.Uint16FromInt32(libc.Int32FromUint16(_operatorMask(tls, op)) & libc.Int32FromUint16(opMask)) } if op == int32(TK_IS) { v1 = pTerm + 18 *(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) | libc.Int32FromInt32(TERM_IS)) } if pRight != 0 && _exprMightBeIndexed(tls, pSrc, bp+24, pRight, op) != 0 && !((*TExpr)(unsafe.Pointer(pRight)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_FixedCol)) != libc.Uint32FromInt32(0)) { eExtraOp = uint16(0) /* Extra bits for pNew->eOperator */ if (*TWhereTerm)(unsafe.Pointer(pTerm)).FleftCursor >= 0 { pDup = _sqlite3ExprDup(tls, db, pExpr, 0) if (*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0 { _sqlite3ExprDelete(tls, db, pDup) return } idxNew = _whereClauseInsert(tls, pWC, pDup, libc.Uint16FromInt32(libc.Int32FromInt32(TERM_VIRTUAL)|libc.Int32FromInt32(TERM_DYNAMIC))) if idxNew == 0 { return } pNew = (*TWhereClause)(unsafe.Pointer(pWC)).Fa + uintptr(idxNew)*56 _markTermAsChild(tls, pWC, idxNew, idxTerm) if op == int32(TK_IS) { v1 = pNew + 18 *(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) | libc.Int32FromInt32(TERM_IS)) } pTerm = (*TWhereClause)(unsafe.Pointer(pWC)).Fa + uintptr(idxTerm)*56 v1 = pTerm + 18 *(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) | libc.Int32FromInt32(TERM_COPIED)) if _termIsEquivalence(tls, pParse, pDup, (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpTabList) != 0 { v1 = pTerm + 20 *(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) | libc.Int32FromInt32(WO_EQUIV)) eExtraOp = uint16(WO_EQUIV) } } else { pDup = pExpr pNew = pTerm } v1 = pNew + 18 *(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) | libc.Int32FromUint16(_exprCommute(tls, pParse, pDup))) (*TWhereTerm)(unsafe.Pointer(pNew)).FleftCursor = (**(**[2]int32)(__ccgo_up(bp + 24)))[0] (*(*struct { FleftColumn int32 FiField int32 })(unsafe.Pointer(pNew + 32))).FleftColumn = (**(**[2]int32)(__ccgo_up(bp + 24)))[int32(1)] (*TWhereTerm)(unsafe.Pointer(pNew)).FprereqRight = prereqLeft | extraRight (*TWhereTerm)(unsafe.Pointer(pNew)).FprereqAll = prereqAll (*TWhereTerm)(unsafe.Pointer(pNew)).FeOperator = libc.Uint16FromInt32((libc.Int32FromUint16(_operatorMask(tls, libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pDup)).Fop))) + libc.Int32FromUint16(eExtraOp)) & libc.Int32FromUint16(opMask)) } else { if op == int32(TK_ISNULL) && !((*TExpr)(unsafe.Pointer(pExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_OuterON)) != libc.Uint32FromInt32(0)) && 0 == _sqlite3ExprCanBeNull(tls, pLeft) { (*TExpr)(unsafe.Pointer(pExpr)).Fop = uint8(TK_TRUEFALSE) /* See tag-20230504-1 */ *(*uintptr)(unsafe.Pointer(pExpr + 8)) = __ccgo_ts + 8211 **(**Tu32)(__ccgo_up(pExpr + 4)) |= libc.Uint32FromInt32(libc.Int32FromInt32(EP_IsFalse)) (*TWhereTerm)(unsafe.Pointer(pTerm)).FprereqAll = uint64(0) (*TWhereTerm)(unsafe.Pointer(pTerm)).FeOperator = uint16(0) } } } else { if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) == int32(TK_BETWEEN) && libc.Int32FromUint8((*TWhereClause)(unsafe.Pointer(pWC)).Fop) == int32(TK_AND) { pList = *(*uintptr)(unsafe.Pointer(pExpr + 32)) i = 0 for { if !(i < int32(2)) { break } pNewExpr = _sqlite3PExpr(tls, pParse, libc.Int32FromUint8(_ops[i]), _sqlite3ExprDup(tls, db, (*TExpr)(unsafe.Pointer(pExpr)).FpLeft, 0), _sqlite3ExprDup(tls, db, (*(*TExprList_item)(unsafe.Pointer(pList + 8 + uintptr(i)*32))).FpExpr, 0)) _transferJoinMarkings(tls, pNewExpr, pExpr) idxNew1 = _whereClauseInsert(tls, pWC, pNewExpr, libc.Uint16FromInt32(libc.Int32FromInt32(TERM_VIRTUAL)|libc.Int32FromInt32(TERM_DYNAMIC))) _exprAnalyze(tls, pSrc, pWC, idxNew1) pTerm = (*TWhereClause)(unsafe.Pointer(pWC)).Fa + uintptr(idxTerm)*56 _markTermAsChild(tls, pWC, idxNew1, idxTerm) goto _8 _8: ; i = i + 1 } } else { if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) == int32(TK_OR) && !((*TExpr)(unsafe.Pointer(pExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_Collate)) != libc.Uint32FromInt32(0)) { _exprAnalyzeOrTerm(tls, pSrc, pWC, idxTerm) pTerm = (*TWhereClause)(unsafe.Pointer(pWC)).Fa + uintptr(idxTerm)*56 } else { if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) == int32(TK_NOTNULL) { if libc.Int32FromUint8((*TExpr)(unsafe.Pointer((*TExpr)(unsafe.Pointer(pExpr)).FpLeft)).Fop) == int32(TK_COLUMN) && int32((*TExpr)(unsafe.Pointer((*TExpr)(unsafe.Pointer(pExpr)).FpLeft)).FiColumn) >= 0 && !((*TExpr)(unsafe.Pointer(pExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_OuterON)) != libc.Uint32FromInt32(0)) { pLeft1 = (*TExpr)(unsafe.Pointer(pExpr)).FpLeft pNewExpr1 = _sqlite3PExpr(tls, pParse, int32(TK_GT), _sqlite3ExprDup(tls, db, pLeft1, 0), _sqlite3ExprAlloc(tls, db, int32(TK_NULL), uintptr(0), 0)) idxNew2 = _whereClauseInsert(tls, pWC, pNewExpr1, libc.Uint16FromInt32(libc.Int32FromInt32(TERM_VIRTUAL)|libc.Int32FromInt32(TERM_DYNAMIC)|libc.Int32FromInt32(TERM_VNULL))) if idxNew2 != 0 { pNewTerm = (*TWhereClause)(unsafe.Pointer(pWC)).Fa + uintptr(idxNew2)*56 (*TWhereTerm)(unsafe.Pointer(pNewTerm)).FprereqRight = uint64(0) (*TWhereTerm)(unsafe.Pointer(pNewTerm)).FleftCursor = (*TExpr)(unsafe.Pointer(pLeft1)).FiTable (*(*struct { FleftColumn int32 FiField int32 })(unsafe.Pointer(pNewTerm + 32))).FleftColumn = int32((*TExpr)(unsafe.Pointer(pLeft1)).FiColumn) (*TWhereTerm)(unsafe.Pointer(pNewTerm)).FeOperator = libc.Uint16FromInt32(libc.Int32FromInt32(WO_EQ) << (libc.Int32FromInt32(TK_GT) - libc.Int32FromInt32(TK_EQ))) _markTermAsChild(tls, pWC, idxNew2, idxTerm) pTerm = (*TWhereClause)(unsafe.Pointer(pWC)).Fa + uintptr(idxTerm)*56 v1 = pTerm + 18 *(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) | libc.Int32FromInt32(TERM_COPIED)) (*TWhereTerm)(unsafe.Pointer(pNewTerm)).FprereqAll = (*TWhereTerm)(unsafe.Pointer(pTerm)).FprereqAll } } } else { if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) == int32(TK_FUNCTION) && libc.Int32FromUint8((*TWhereClause)(unsafe.Pointer(pWC)).Fop) == int32(TK_AND) && _isLikeOrGlob(tls, pParse, pExpr, bp, bp+8, bp+12) != 0 { /* Name of collating sequence */ wtFlags = libc.Uint16FromInt32(libc.Int32FromInt32(TERM_LIKEOPT) | libc.Int32FromInt32(TERM_VIRTUAL) | libc.Int32FromInt32(TERM_DYNAMIC)) pLeft2 = (*(*TExprList_item)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pExpr + 32)) + 8 + 1*32))).FpExpr pStr2 = _sqlite3ExprDup(tls, db, **(**uintptr)(__ccgo_up(bp)), 0) /* Convert the lower bound to upper-case and the upper bound to ** lower-case (upper-case is less than lower-case in ASCII) so that ** the range constraints also work for BLOBs */ if **(**int32)(__ccgo_up(bp + 12)) != 0 && !((*Tsqlite3)(unsafe.Pointer((*TParse)(unsafe.Pointer(pParse)).Fdb)).FmallocFailed != 0) { v1 = pTerm + 18 *(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) | libc.Int32FromInt32(TERM_LIKE)) i1 = 0 for { v12 = **(**uint8)(__ccgo_up(*(*uintptr)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)) + 8)) + uintptr(i1))) c = v12 if !(libc.Int32FromUint8(v12) != 0) { break } **(**uint8)(__ccgo_up(*(*uintptr)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)) + 8)) + uintptr(i1))) = libc.Uint8FromInt32(libc.Int32FromUint8(c) & ^(libc.Int32FromUint8(_sqlite3CtypeMap[c]) & libc.Int32FromInt32(0x20))) **(**uint8)(__ccgo_up(*(*uintptr)(unsafe.Pointer(pStr2 + 8)) + uintptr(i1))) = _sqlite3UpperToLower[c] goto _11 _11: ; i1 = i1 + 1 } } if !((*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0) { /* Last character before the first wildcard */ pC = *(*uintptr)(unsafe.Pointer(pStr2 + 8)) + uintptr(_sqlite3Strlen30(tls, *(*uintptr)(unsafe.Pointer(pStr2 + 8)))-int32(1)) if **(**int32)(__ccgo_up(bp + 12)) != 0 { /* The point is to increment the last character before the first ** wildcard. But if we increment '@', that will push it into the ** alphabetic range where case conversions will mess up the ** inequality. To avoid this, make sure to also run the full ** LIKE on all candidate expressions by clearing the isComplete flag */ if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(pC))) == libc.Int32FromUint8('A')-libc.Int32FromInt32(1) { **(**int32)(__ccgo_up(bp + 8)) = 0 } **(**Tu8)(__ccgo_up(pC)) = _sqlite3UpperToLower[**(**Tu8)(__ccgo_up(pC))] } /* Increment the value of the last utf8 character in the prefix. */ for libc.Int32FromUint8(**(**Tu8)(__ccgo_up(pC))) == int32(0xBF) && pC > *(*uintptr)(unsafe.Pointer(pStr2 + 8)) { **(**Tu8)(__ccgo_up(pC)) = uint8(0x80) pC = pC - 1 } /* isLikeOrGlob() guarantees this */ **(**Tu8)(__ccgo_up(pC)) = **(**Tu8)(__ccgo_up(pC)) + 1 } if **(**int32)(__ccgo_up(bp + 12)) != 0 { v1 = __ccgo_ts + 23969 } else { v1 = uintptr(unsafe.Pointer(&_sqlite3StrBINARY)) } zCollSeqName = v1 pNewExpr11 = _sqlite3ExprDup(tls, db, pLeft2, 0) pNewExpr11 = _sqlite3PExpr(tls, pParse, int32(TK_GE), _sqlite3ExprAddCollateString(tls, pParse, pNewExpr11, zCollSeqName), **(**uintptr)(__ccgo_up(bp))) _transferJoinMarkings(tls, pNewExpr11, pExpr) idxNew11 = _whereClauseInsert(tls, pWC, pNewExpr11, wtFlags) pNewExpr21 = _sqlite3ExprDup(tls, db, pLeft2, 0) pNewExpr21 = _sqlite3PExpr(tls, pParse, int32(TK_LT), _sqlite3ExprAddCollateString(tls, pParse, pNewExpr21, zCollSeqName), pStr2) _transferJoinMarkings(tls, pNewExpr21, pExpr) idxNew21 = _whereClauseInsert(tls, pWC, pNewExpr21, wtFlags) _exprAnalyze(tls, pSrc, pWC, idxNew11) _exprAnalyze(tls, pSrc, pWC, idxNew21) pTerm = (*TWhereClause)(unsafe.Pointer(pWC)).Fa + uintptr(idxTerm)*56 if **(**int32)(__ccgo_up(bp + 8)) != 0 { _markTermAsChild(tls, pWC, idxNew11, idxTerm) _markTermAsChild(tls, pWC, idxNew21, idxTerm) } } } } } } /* If there is a vector == or IS term - e.g. "(a, b) == (?, ?)" - create ** new terms for each component comparison - "a = ?" and "b = ?". The ** new terms completely replace the original vector comparison, which is ** no longer used. ** ** This is only required if at least one side of the comparison operation ** is not a sub-select. ** ** tag-20220128a */ if v15 = libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) == int32(TK_EQ) || libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) == int32(TK_IS); v15 { v2 = _sqlite3ExprVectorSize(tls, (*TExpr)(unsafe.Pointer(pExpr)).FpLeft) nLeft = v2 } if v15 && v2 > int32(1) && _sqlite3ExprVectorSize(tls, (*TExpr)(unsafe.Pointer(pExpr)).FpRight) == nLeft && ((*TExpr)(unsafe.Pointer((*TExpr)(unsafe.Pointer(pExpr)).FpLeft)).Fflags&uint32(EP_xIsSelect) == uint32(0) || (*TExpr)(unsafe.Pointer((*TExpr)(unsafe.Pointer(pExpr)).FpRight)).Fflags&uint32(EP_xIsSelect) == uint32(0)) && libc.Int32FromUint8((*TWhereClause)(unsafe.Pointer(pWC)).Fop) == int32(TK_AND) { i2 = 0 for { if !(i2 < nLeft) { break } pLeft3 = _sqlite3ExprForVectorField(tls, pParse, (*TExpr)(unsafe.Pointer(pExpr)).FpLeft, i2, nLeft) pRight1 = _sqlite3ExprForVectorField(tls, pParse, (*TExpr)(unsafe.Pointer(pExpr)).FpRight, i2, nLeft) pNew1 = _sqlite3PExpr(tls, pParse, libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop), pLeft3, pRight1) _transferJoinMarkings(tls, pNew1, pExpr) idxNew3 = _whereClauseInsert(tls, pWC, pNew1, libc.Uint16FromInt32(libc.Int32FromInt32(TERM_DYNAMIC)|libc.Int32FromInt32(TERM_SLICE))) _exprAnalyze(tls, pSrc, pWC, idxNew3) goto _16 _16: ; i2 = i2 + 1 } pTerm = (*TWhereClause)(unsafe.Pointer(pWC)).Fa + uintptr(idxTerm)*56 v1 = pTerm + 18 *(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) | (libc.Int32FromInt32(TERM_CODED) | libc.Int32FromInt32(TERM_VIRTUAL))) /* Disable the original */ (*TWhereTerm)(unsafe.Pointer(pTerm)).FeOperator = uint16(WO_ROWVAL) } else { if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) == int32(TK_IN) && (*(*struct { FleftColumn int32 FiField int32 })(unsafe.Pointer(pTerm + 32))).FiField == 0 && libc.Int32FromUint8((*TExpr)(unsafe.Pointer((*TExpr)(unsafe.Pointer(pExpr)).FpLeft)).Fop) == int32(TK_VECTOR) && (*TExpr)(unsafe.Pointer(pExpr)).Fflags&uint32(EP_xIsSelect) != uint32(0) && ((*TSelect)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pExpr + 32)))).FpPrior == uintptr(0) || (*TSelect)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pExpr + 32)))).FselFlags&uint32(SF_Values) != 0) && (*TSelect)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pExpr + 32)))).FpWin == uintptr(0) && libc.Int32FromUint8((*TWhereClause)(unsafe.Pointer(pWC)).Fop) == int32(TK_AND) && int64((*TExprList)(unsafe.Pointer((*TSelect)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pExpr + 32)))).FpEList)).FnExpr) <= libc.Int64FromInt32(1)<<(libc.Uint64FromInt64(1)*libc.Uint64FromInt32(8))-libc.Int64FromInt32(1) { i3 = 0 for { if !(i3 < _sqlite3ExprVectorSize(tls, (*TExpr)(unsafe.Pointer(pExpr)).FpLeft)) { break } idxNew4 = _whereClauseInsert(tls, pWC, pExpr, libc.Uint16FromInt32(libc.Int32FromInt32(TERM_VIRTUAL)|libc.Int32FromInt32(TERM_SLICE))) *(*int32)(unsafe.Pointer((*TWhereClause)(unsafe.Pointer(pWC)).Fa + uintptr(idxNew4)*56 + 32 + 4)) = i3 + int32(1) _exprAnalyze(tls, pSrc, pWC, idxNew4) _markTermAsChild(tls, pWC, idxNew4, idxTerm) goto _18 _18: ; i3 = i3 + 1 } } else { if libc.Int32FromUint8((*TWhereClause)(unsafe.Pointer(pWC)).Fop) == int32(TK_AND) { **(**uintptr)(__ccgo_up(bp + 32)) = uintptr(0) **(**uintptr)(__ccgo_up(bp + 40)) = uintptr(0) res = _isAuxiliaryVtabOperator(tls, db, pExpr, bp+16, bp+40, bp+32) for { v2 = res res = res - 1 if !(v2 > 0) { break } prereqExpr = _sqlite3WhereExprUsage(tls, pMaskSet, **(**uintptr)(__ccgo_up(bp + 32))) prereqColumn = _sqlite3WhereExprUsage(tls, pMaskSet, **(**uintptr)(__ccgo_up(bp + 40))) if prereqExpr&prereqColumn == uint64(0) { pNewExpr2 = _sqlite3PExpr(tls, pParse, int32(TK_MATCH), uintptr(0), _sqlite3ExprDup(tls, db, **(**uintptr)(__ccgo_up(bp + 32)), 0)) if (*TExpr)(unsafe.Pointer(pExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_OuterON)) != uint32(0) && pNewExpr2 != 0 { **(**Tu32)(__ccgo_up(pNewExpr2 + 4)) |= libc.Uint32FromInt32(libc.Int32FromInt32(EP_OuterON)) *(*int32)(unsafe.Pointer(pNewExpr2 + 52)) = *(*int32)(unsafe.Pointer(pExpr + 52)) } idxNew5 = _whereClauseInsert(tls, pWC, pNewExpr2, libc.Uint16FromInt32(libc.Int32FromInt32(TERM_VIRTUAL)|libc.Int32FromInt32(TERM_DYNAMIC))) pNewTerm1 = (*TWhereClause)(unsafe.Pointer(pWC)).Fa + uintptr(idxNew5)*56 (*TWhereTerm)(unsafe.Pointer(pNewTerm1)).FprereqRight = prereqExpr | extraRight (*TWhereTerm)(unsafe.Pointer(pNewTerm1)).FleftCursor = (*TExpr)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 40)))).FiTable (*(*struct { FleftColumn int32 FiField int32 })(unsafe.Pointer(pNewTerm1 + 32))).FleftColumn = int32((*TExpr)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp + 40)))).FiColumn) (*TWhereTerm)(unsafe.Pointer(pNewTerm1)).FeOperator = uint16(WO_AUX) (*TWhereTerm)(unsafe.Pointer(pNewTerm1)).FeMatchOp = **(**uint8)(__ccgo_up(bp + 16)) _markTermAsChild(tls, pWC, idxNew5, idxTerm) pTerm = (*TWhereClause)(unsafe.Pointer(pWC)).Fa + uintptr(idxTerm)*56 v1 = pTerm + 18 *(*Tu16)(unsafe.Pointer(v1)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v1))) | libc.Int32FromInt32(TERM_COPIED)) (*TWhereTerm)(unsafe.Pointer(pNewTerm1)).FprereqAll = (*TWhereTerm)(unsafe.Pointer(pTerm)).FprereqAll } t = **(**uintptr)(__ccgo_up(bp + 40)) **(**uintptr)(__ccgo_up(bp + 40)) = **(**uintptr)(__ccgo_up(bp + 32)) **(**uintptr)(__ccgo_up(bp + 32)) = t } } } } /* Prevent ON clause terms of a LEFT JOIN from being used to drive ** an index for tables to the left of the join. */ pTerm = (*TWhereClause)(unsafe.Pointer(pWC)).Fa + uintptr(idxTerm)*56 **(**TBitmask)(__ccgo_up(pTerm + 40)) |= extraRight } // C documentation // // /* // ** Generate code to implement special SQL functions that are implemented // ** in-line rather than by using the usual callbacks. // */ func _exprCodeInlineFunction(tls *libc.TLS, pParse uintptr, pFarg uintptr, iFuncId int32, target int32) (r int32) { bp := tls.Alloc(80) defer tls.Free(80) var aff uint8 var azAff [6]uintptr var endCoalesce, i, nFarg int32 var pA1, pArg, v, v2 uintptr var _ /* caseExpr at bp+0 */ TExpr _, _, _, _, _, _, _, _, _ = aff, azAff, endCoalesce, i, nFarg, pA1, pArg, v, v2 v = (*TParse)(unsafe.Pointer(pParse)).FpVdbe nFarg = (*TExprList)(unsafe.Pointer(pFarg)).FnExpr /* All in-line functions have at least one argument */ switch iFuncId { case INLINEFUNC_coalesce: /* Attempt a direct implementation of the built-in COALESCE() and ** IFNULL() functions. This avoids unnecessary evaluation of ** arguments past the first non-NULL argument. */ endCoalesce = _sqlite3VdbeMakeLabel(tls, pParse) _sqlite3ExprCode(tls, pParse, (*(*TExprList_item)(unsafe.Pointer(pFarg + 8))).FpExpr, target) i = int32(1) for { if !(i < nFarg) { break } _sqlite3VdbeAddOp2(tls, v, int32(OP_NotNull), target, endCoalesce) _sqlite3ExprCode(tls, pParse, (*(*TExprList_item)(unsafe.Pointer(pFarg + 8 + uintptr(i)*32))).FpExpr, target) goto _1 _1: ; i = i + 1 } _setDoNotMergeFlagOnCopy(tls, v) _sqlite3VdbeResolveLabel(tls, v, endCoalesce) case int32(INLINEFUNC_iif): libc.Xmemset(tls, bp, 0, uint64(72)) (**(**TExpr)(__ccgo_up(bp))).Fop = uint8(TK_CASE) *(*uintptr)(unsafe.Pointer(bp + 32)) = pFarg return _sqlite3ExprCodeTarget(tls, pParse, bp, target) case int32(INLINEFUNC_sqlite_offset): pArg = (*(*TExprList_item)(unsafe.Pointer(pFarg + 8))).FpExpr if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pArg)).Fop) == int32(TK_COLUMN) && (*TExpr)(unsafe.Pointer(pArg)).FiTable >= 0 { _sqlite3VdbeAddOp3(tls, v, int32(OP_Offset), (*TExpr)(unsafe.Pointer(pArg)).FiTable, int32((*TExpr)(unsafe.Pointer(pArg)).FiColumn), target) } else { _sqlite3VdbeAddOp2(tls, v, int32(OP_Null), 0, target) } default: /* The UNLIKELY() function is a no-op. The result is the value ** of the first argument. */ target = _sqlite3ExprCodeTarget(tls, pParse, (*(*TExprList_item)(unsafe.Pointer(pFarg + 8))).FpExpr, target) break /*********************************************************************** ** Test-only SQL functions that are only usable if enabled ** via SQLITE_TESTCTRL_INTERNAL_FUNCTIONS */ fallthrough case int32(INLINEFUNC_expr_compare): /* Compare two expressions using sqlite3ExprCompare() */ _sqlite3VdbeAddOp2(tls, v, int32(OP_Integer), _sqlite3ExprCompare(tls, uintptr(0), (*(*TExprList_item)(unsafe.Pointer(pFarg + 8))).FpExpr, (*(*TExprList_item)(unsafe.Pointer(pFarg + 8 + 1*32))).FpExpr, -int32(1)), target) case int32(INLINEFUNC_expr_implies_expr): /* Compare two expressions using sqlite3ExprImpliesExpr() */ _sqlite3VdbeAddOp2(tls, v, int32(OP_Integer), _sqlite3ExprImpliesExpr(tls, pParse, (*(*TExprList_item)(unsafe.Pointer(pFarg + 8))).FpExpr, (*(*TExprList_item)(unsafe.Pointer(pFarg + 8 + 1*32))).FpExpr, -int32(1)), target) case int32(INLINEFUNC_implies_nonnull_row): pA1 = (*(*TExprList_item)(unsafe.Pointer(pFarg + 8 + 1*32))).FpExpr if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pA1)).Fop) == int32(TK_COLUMN) { _sqlite3VdbeAddOp2(tls, v, int32(OP_Integer), _sqlite3ExprImpliesNonNullRow(tls, (*(*TExprList_item)(unsafe.Pointer(pFarg + 8))).FpExpr, (*TExpr)(unsafe.Pointer(pA1)).FiTable, int32(1)), target) } else { _sqlite3VdbeAddOp2(tls, v, int32(OP_Null), 0, target) } case int32(INLINEFUNC_affinity): /* The AFFINITY() function evaluates to a string that describes ** the type affinity of the argument. This is used for testing of ** the SQLite type logic. */ azAff = [6]uintptr{ 0: __ccgo_ts + 8510, 1: __ccgo_ts + 8515, 2: __ccgo_ts + 8520, 3: __ccgo_ts + 6520, 4: __ccgo_ts + 6515, 5: __ccgo_ts + 8528, } aff = _sqlite3ExprAffinity(tls, (*(*TExprList_item)(unsafe.Pointer(pFarg + 8))).FpExpr) if libc.Int32FromUint8(aff) <= int32(SQLITE_AFF_NONE) { v2 = __ccgo_ts + 8536 } else { v2 = azAff[libc.Int32FromUint8(aff)-int32(SQLITE_AFF_BLOB)] } _sqlite3VdbeLoadString(tls, v, target, v2) break } return target } // C documentation // // /* // ** This function is called by unixOpen() to determine the unix permissions // ** to create new files with. If no error occurs, then SQLITE_OK is returned // ** and a value suitable for passing as the third argument to open(2) is // ** written to *pMode. If an IO error occurs, an SQLite error code is // ** returned and the value of *pMode is not modified. // ** // ** In most cases, this routine sets *pMode to 0, which will become // ** an indication to robust_open() to create the file using // ** SQLITE_DEFAULT_FILE_PERMISSIONS adjusted by the umask. // ** But if the file being opened is a WAL or regular journal file, then // ** this function queries the file-system for the permissions on the // ** corresponding database file and sets *pMode to this value. Whenever // ** possible, WAL and journal files are created using the same permissions // ** as the associated database file. // ** // ** If the SQLITE_ENABLE_8_3_NAMES option is enabled, then the // ** original filename is unavailable. But 8_3_NAMES is only used for // ** FAT filesystems and permissions do not matter there, so just use // ** the default permissions. In 8_3_NAMES mode, leave *pMode set to zero. // */ func _findCreateFileMode(tls *libc.TLS, zPath uintptr, flags int32, pMode uintptr, pUid uintptr, pGid uintptr) (r int32) { bp := tls.Alloc(528) defer tls.Free(528) var nDb, rc int32 var z uintptr var _ /* zDb at bp+0 */ [513]uint8 _, _, _ = nDb, rc, z rc = SQLITE_OK /* Return Code */ **(**Tmode_t)(__ccgo_up(pMode)) = uint32(0) **(**Tuid_t)(__ccgo_up(pUid)) = uint32(0) **(**Tgid_t)(__ccgo_up(pGid)) = uint32(0) if flags&(libc.Int32FromInt32(SQLITE_OPEN_WAL)|libc.Int32FromInt32(SQLITE_OPEN_MAIN_JOURNAL)) != 0 { /* Number of valid bytes in zDb */ /* zPath is a path to a WAL or journal file. The following block derives ** the path to the associated database file from zPath. This block handles ** the following naming conventions: ** ** "-journal" ** "-wal" ** "-journalNN" ** "-walNN" ** ** where NN is a decimal number. The NN naming schemes are ** used by the test_multiplex.c module. ** ** In normal operation, the journal file name will always contain ** a '-' character. However in 8+3 filename mode, or if a corrupt ** rollback journal specifies a super-journal with a goofy name, then ** the '-' might be missing or the '-' might be the first character in ** the filename. In that case, just return SQLITE_OK with *pMode==0. */ nDb = _sqlite3Strlen30(tls, zPath) - int32(1) for nDb > 0 && libc.Int32FromUint8(**(**uint8)(__ccgo_up(zPath + uintptr(nDb)))) != int32('.') { if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zPath + uintptr(nDb)))) == int32('-') { libc.Xmemcpy(tls, bp, zPath, libc.Uint64FromInt32(nDb)) (**(**[513]uint8)(__ccgo_up(bp)))[nDb] = uint8('\000') rc = _getFileMode(tls, bp, pMode, pUid, pGid) break } nDb = nDb - 1 } } else { if flags&int32(SQLITE_OPEN_DELETEONCLOSE) != 0 { **(**Tmode_t)(__ccgo_up(pMode)) = uint32(0600) } else { if flags&int32(SQLITE_OPEN_URI) != 0 { /* If this is a main database file and the file was opened using a URI ** filename, check for the "modeof" parameter. If present, interpret ** its value as a filename and try to copy the mode, uid and gid from ** that file. */ z = Xsqlite3_uri_parameter(tls, zPath, __ccgo_ts+4086) if z != 0 { rc = _getFileMode(tls, z, pMode, pUid, pGid) } } } } return rc } // C documentation // // /* // ** Implementation of the xBestIndex method for FTS5 tables. Within the // ** WHERE constraint, it searches for the following: // ** // ** 1. A MATCH constraint against the table column. // ** 2. A MATCH constraint against the "rank" column. // ** 3. A MATCH constraint against some other column. // ** 4. An == constraint against the rowid column. // ** 5. A < or <= constraint against the rowid column. // ** 6. A > or >= constraint against the rowid column. // ** // ** Within the ORDER BY, the following are supported: // ** // ** 5. ORDER BY rank [ASC|DESC] // ** 6. ORDER BY rowid [ASC|DESC] // ** // ** Information for the xFilter call is passed via both the idxNum and // ** idxStr variables. Specifically, idxNum is a bitmask of the following // ** flags used to encode the ORDER BY clause: // ** // ** FTS5_BI_ORDER_RANK // ** FTS5_BI_ORDER_ROWID // ** FTS5_BI_ORDER_DESC // ** // ** idxStr is used to encode data from the WHERE clause. For each argument // ** passed to the xFilter method, the following is appended to idxStr: // ** // ** Match against table column: "m" // ** Match against rank column: "r" // ** Match against other column: "M" // ** LIKE against other column: "L" // ** GLOB against other column: "G" // ** Equality constraint against the rowid: "=" // ** A < or <= against the rowid: "<" // ** A > or >= against the rowid: ">" // ** // ** This function ensures that there is at most one "r" or "=". And that if // ** there exists an "=" then there is no "<" or ">". // ** // ** If an unusable MATCH operator is present in the WHERE clause, then // ** SQLITE_CONSTRAINT is returned. // ** // ** Costs are assigned as follows: // ** // ** a) If a MATCH operator is present, the cost depends on the other // ** constraints also present. As follows: // ** // ** * No other constraints: cost=50000.0 // ** * One rowid range constraint: cost=37500.0 // ** * Both rowid range constraints: cost=30000.0 // ** * An == rowid constraint: cost=25000.0 // ** // ** b) Otherwise, if there is no MATCH: // ** // ** * No other constraints: cost=3000000.0 // ** * One rowid range constraints: cost=2250000.0 // ** * Both rowid range constraint: cost=750000.0 // ** * An == rowid constraint: cost=25.0 // ** // ** Costs are not modified by the ORDER BY clause. // ** // ** The ratios used in case (a) are based on informal results obtained from // ** the tool/fts5cost.tcl script. The "MATCH and ==" combination has the // ** cost set quite high because the query may be a prefix query. Unless // ** there is a prefix index, prefix queries with rowid constraints are much // ** more expensive than non-prefix queries with rowid constraints. // ** // ** The estimated rows returned is set to the cost/40. For simple queries, // ** experimental results show that cost/4 might be about right. But for // ** more complex queries that use multiple terms the number of rows might // ** be far fewer than this. So we compromise and use cost/40. // */ func _fts5BestIndexMethod(tls *libc.TLS, pVTab uintptr, pInfo uintptr) (r int32) { bp := tls.Alloc(16) defer tls.Free(16) var bSeenEq, bSeenGt, bSeenLt, bSeenRank, i, iCol, iCons, iIdxStr, iSort, idxFlags, nCol, nSeenMatch, op, v2, v3 int32 var idxStr, p, p1, pConfig, pTab uintptr var nEstRows Ti64 var v15 float64 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = bSeenEq, bSeenGt, bSeenLt, bSeenRank, i, iCol, iCons, iIdxStr, iSort, idxFlags, idxStr, nCol, nEstRows, nSeenMatch, op, p, p1, pConfig, pTab, v15, v2, v3 pTab = pVTab pConfig = (*TFts5Table)(unsafe.Pointer(pTab)).FpConfig nCol = (*TFts5Config)(unsafe.Pointer(pConfig)).FnCol idxFlags = 0 iIdxStr = 0 iCons = 0 bSeenEq = 0 bSeenGt = 0 bSeenLt = 0 nSeenMatch = 0 bSeenRank = 0 if (*TFts5Config)(unsafe.Pointer(pConfig)).FbLock != 0 { (*TFts5Table)(unsafe.Pointer(pTab)).Fbase.FzErrMsg = Xsqlite3_mprintf(tls, __ccgo_ts+39740, 0) return int32(SQLITE_ERROR) } idxStr = Xsqlite3_malloc64(tls, libc.Uint64FromInt64(int64((*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FnConstraint)*int64(8)+int64(1))) if idxStr == uintptr(0) { return int32(SQLITE_NOMEM) } (*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FidxStr = idxStr (*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FneedToFreeIdxStr = int32(1) i = 0 for { if !(i < (*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FnConstraint) { break } p = (*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FaConstraint + uintptr(i)*12 iCol = (*Tsqlite3_index_constraint)(unsafe.Pointer(p)).FiColumn if libc.Int32FromUint8((*Tsqlite3_index_constraint)(unsafe.Pointer(p)).Fop) == int32(SQLITE_INDEX_CONSTRAINT_MATCH) || libc.Int32FromUint8((*Tsqlite3_index_constraint)(unsafe.Pointer(p)).Fop) == int32(SQLITE_INDEX_CONSTRAINT_EQ) && iCol >= nCol { /* A MATCH operator or equivalent */ if libc.Int32FromUint8((*Tsqlite3_index_constraint)(unsafe.Pointer(p)).Fusable) == 0 || iCol < 0 { /* As there exists an unusable MATCH constraint this is an ** unusable plan. Return SQLITE_CONSTRAINT. */ **(**uint8)(__ccgo_up(idxStr + uintptr(iIdxStr))) = uint8(0) return int32(SQLITE_CONSTRAINT) } else { if iCol == nCol+int32(1) { if bSeenRank != 0 { goto _1 } v2 = iIdxStr iIdxStr = iIdxStr + 1 **(**uint8)(__ccgo_up(idxStr + uintptr(v2))) = uint8('r') bSeenRank = int32(1) } else { nSeenMatch = nSeenMatch + 1 v2 = iIdxStr iIdxStr = iIdxStr + 1 **(**uint8)(__ccgo_up(idxStr + uintptr(v2))) = uint8('M') Xsqlite3_snprintf(tls, int32(6), idxStr+uintptr(iIdxStr), __ccgo_ts+5317, libc.VaList(bp+8, iCol)) iIdxStr = iIdxStr + libc.Int32FromUint64(libc.Xstrlen(tls, idxStr+uintptr(iIdxStr))) } iCons = iCons + 1 v2 = iCons (**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FaConstraintUsage + uintptr(i)*8))).FargvIndex = v2 (**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FaConstraintUsage + uintptr(i)*8))).Fomit = uint8(1) } } else { if (*Tsqlite3_index_constraint)(unsafe.Pointer(p)).Fusable != 0 { if iCol >= 0 && iCol < nCol && _fts5UsePatternMatch(tls, pConfig, p) != 0 { v2 = iIdxStr iIdxStr = iIdxStr + 1 if libc.Int32FromUint8((*Tsqlite3_index_constraint)(unsafe.Pointer(p)).Fop) == int32(FTS5_PATTERN_LIKE) { v3 = int32('L') } else { v3 = int32('G') } **(**uint8)(__ccgo_up(idxStr + uintptr(v2))) = libc.Uint8FromInt32(v3) Xsqlite3_snprintf(tls, int32(6), idxStr+uintptr(iIdxStr), __ccgo_ts+5317, libc.VaList(bp+8, iCol)) idxStr = idxStr + uintptr(libc.Xstrlen(tls, idxStr+uintptr(iIdxStr))) iCons = iCons + 1 v2 = iCons (**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FaConstraintUsage + uintptr(i)*8))).FargvIndex = v2 nSeenMatch = nSeenMatch + 1 } else { if bSeenEq == 0 && libc.Int32FromUint8((*Tsqlite3_index_constraint)(unsafe.Pointer(p)).Fop) == int32(SQLITE_INDEX_CONSTRAINT_EQ) && iCol < 0 { v2 = iIdxStr iIdxStr = iIdxStr + 1 **(**uint8)(__ccgo_up(idxStr + uintptr(v2))) = uint8('=') bSeenEq = int32(1) iCons = iCons + 1 v2 = iCons (**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FaConstraintUsage + uintptr(i)*8))).FargvIndex = v2 (**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FaConstraintUsage + uintptr(i)*8))).Fomit = uint8(1) } } } } goto _1 _1: ; i = i + 1 } if bSeenEq == 0 { i = 0 for { if !(i < (*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FnConstraint) { break } p1 = (*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FaConstraint + uintptr(i)*12 if (*Tsqlite3_index_constraint)(unsafe.Pointer(p1)).FiColumn < 0 && (*Tsqlite3_index_constraint)(unsafe.Pointer(p1)).Fusable != 0 { op = libc.Int32FromUint8((*Tsqlite3_index_constraint)(unsafe.Pointer(p1)).Fop) if op == int32(SQLITE_INDEX_CONSTRAINT_LT) || op == int32(SQLITE_INDEX_CONSTRAINT_LE) { if bSeenLt != 0 { goto _10 } v2 = iIdxStr iIdxStr = iIdxStr + 1 **(**uint8)(__ccgo_up(idxStr + uintptr(v2))) = uint8('<') iCons = iCons + 1 v2 = iCons (**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FaConstraintUsage + uintptr(i)*8))).FargvIndex = v2 bSeenLt = int32(1) } else { if op == int32(SQLITE_INDEX_CONSTRAINT_GT) || op == int32(SQLITE_INDEX_CONSTRAINT_GE) { if bSeenGt != 0 { goto _10 } v2 = iIdxStr iIdxStr = iIdxStr + 1 **(**uint8)(__ccgo_up(idxStr + uintptr(v2))) = uint8('>') iCons = iCons + 1 v2 = iCons (**(**Tsqlite3_index_constraint_usage)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FaConstraintUsage + uintptr(i)*8))).FargvIndex = v2 bSeenGt = int32(1) } } } goto _10 _10: ; i = i + 1 } } **(**uint8)(__ccgo_up(idxStr + uintptr(iIdxStr))) = uint8('\000') /* Set idxFlags flags for the ORDER BY clause ** ** Note that tokendata=1 tables cannot currently handle "ORDER BY rowid DESC". */ if (*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FnOrderBy == int32(1) { iSort = (**(**Tsqlite3_index_orderby)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FaOrderBy))).FiColumn if iSort == (*TFts5Config)(unsafe.Pointer(pConfig)).FnCol+int32(1) && nSeenMatch > 0 { idxFlags = idxFlags | int32(FTS5_BI_ORDER_RANK) } else { if iSort == -int32(1) && (!((**(**Tsqlite3_index_orderby)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FaOrderBy))).Fdesc != 0) || !((*TFts5Config)(unsafe.Pointer(pConfig)).FbTokendata != 0)) { idxFlags = idxFlags | int32(FTS5_BI_ORDER_ROWID) } } if idxFlags&(libc.Int32FromInt32(FTS5_BI_ORDER_RANK)|libc.Int32FromInt32(FTS5_BI_ORDER_ROWID)) != 0 { (*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).ForderByConsumed = int32(1) if (**(**Tsqlite3_index_orderby)(__ccgo_up((*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FaOrderBy))).Fdesc != 0 { idxFlags = idxFlags | int32(FTS5_BI_ORDER_DESC) } } } /* Calculate the estimated cost based on the flags set in idxFlags. */ if bSeenEq != 0 { if nSeenMatch != 0 { v15 = float64(25000) } else { v15 = float64(25) } (*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FestimatedCost = v15 _fts5SetEstimatedRows(tls, pInfo, int64(1)) _fts5SetUniqueFlag(tls, pInfo) } else { if nSeenMatch != 0 { if bSeenLt != 0 && bSeenGt != 0 { (*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FestimatedCost = float64(50000) } else { if bSeenLt != 0 || bSeenGt != 0 { (*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FestimatedCost = float64(37500) } else { (*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FestimatedCost = float64(50000) } } nEstRows = int64((*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FestimatedCost / libc.Float64FromFloat64(40)) i = int32(1) for { if !(i < nSeenMatch) { break } **(**float64)(__ccgo_up(pInfo + 64)) *= float64(2.5) nEstRows = nEstRows / int64(2) goto _16 _16: ; i = i + 1 } } else { if bSeenLt != 0 && bSeenGt != 0 { (*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FestimatedCost = float64(750000) } else { if bSeenLt != 0 || bSeenGt != 0 { (*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FestimatedCost = float64(2.25e+06) } else { (*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FestimatedCost = float64(3e+06) } } nEstRows = int64((*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FestimatedCost / libc.Float64FromFloat64(4)) } _fts5SetEstimatedRows(tls, pInfo, nEstRows) } (*Tsqlite3_index_info)(unsafe.Pointer(pInfo)).FidxNum = idxFlags return SQLITE_OK } // C documentation // // /* // ** Parse a "special" CREATE VIRTUAL TABLE directive and update // ** configuration object pConfig as appropriate. // ** // ** If successful, object pConfig is updated and SQLITE_OK returned. If // ** an error occurs, an SQLite error code is returned and an error message // ** may be left in *pzErr. It is the responsibility of the caller to // ** eventually free any such error message using sqlite3_free(). // */ func _fts5ConfigParseSpecial(tls *libc.TLS, pConfig uintptr, zCmd uintptr, zArg uintptr, pzErr uintptr) (r int32) { bp := tls.Alloc(96) defer tls.Free(96) var azArg, p, p1, p2, pSpace uintptr var bFirst, nByte, nCmd, nPre, v2 int32 var nArg Tsqlite3_int64 var _ /* aDetail at bp+8 */ [4]TFts5Enum var _ /* rc at bp+0 */ int32 _, _, _, _, _, _, _, _, _, _, _ = azArg, bFirst, nArg, nByte, nCmd, nPre, p, p1, p2, pSpace, v2 **(**int32)(__ccgo_up(bp)) = SQLITE_OK nCmd = libc.Int32FromUint64(libc.Xstrlen(tls, zCmd)) if Xsqlite3_strnicmp(tls, __ccgo_ts+37431, zCmd, nCmd) == 0 { nByte = libc.Int32FromUint64(libc.Uint64FromInt64(4) * libc.Uint64FromInt32(FTS5_MAX_PREFIX_INDEXES)) bFirst = int32(1) if (*TFts5Config)(unsafe.Pointer(pConfig)).FaPrefix == uintptr(0) { (*TFts5Config)(unsafe.Pointer(pConfig)).FaPrefix = _sqlite3Fts5MallocZero(tls, bp, int64(nByte)) if **(**int32)(__ccgo_up(bp)) != 0 { return **(**int32)(__ccgo_up(bp)) } } p = zArg for int32(1) != 0 { nPre = 0 for libc.Int32FromUint8(**(**uint8)(__ccgo_up(p))) == int32(' ') { p = p + 1 } if bFirst == 0 && libc.Int32FromUint8(**(**uint8)(__ccgo_up(p))) == int32(',') { p = p + 1 for libc.Int32FromUint8(**(**uint8)(__ccgo_up(p))) == int32(' ') { p = p + 1 } } else { if libc.Int32FromUint8(**(**uint8)(__ccgo_up(p))) == int32('\000') { break } } if libc.Int32FromUint8(**(**uint8)(__ccgo_up(p))) < int32('0') || libc.Int32FromUint8(**(**uint8)(__ccgo_up(p))) > int32('9') { **(**uintptr)(__ccgo_up(pzErr)) = Xsqlite3_mprintf(tls, __ccgo_ts+37438, 0) **(**int32)(__ccgo_up(bp)) = int32(SQLITE_ERROR) break } if (*TFts5Config)(unsafe.Pointer(pConfig)).FnPrefix == int32(FTS5_MAX_PREFIX_INDEXES) { **(**uintptr)(__ccgo_up(pzErr)) = Xsqlite3_mprintf(tls, __ccgo_ts+37469, libc.VaList(bp+80, int32(FTS5_MAX_PREFIX_INDEXES))) **(**int32)(__ccgo_up(bp)) = int32(SQLITE_ERROR) break } for libc.Int32FromUint8(**(**uint8)(__ccgo_up(p))) >= int32('0') && libc.Int32FromUint8(**(**uint8)(__ccgo_up(p))) <= int32('9') && nPre < int32(1000) { nPre = nPre*int32(10) + (libc.Int32FromUint8(**(**uint8)(__ccgo_up(p))) - int32('0')) p = p + 1 } if nPre <= 0 || nPre >= int32(1000) { **(**uintptr)(__ccgo_up(pzErr)) = Xsqlite3_mprintf(tls, __ccgo_ts+37502, 0) **(**int32)(__ccgo_up(bp)) = int32(SQLITE_ERROR) break } **(**int32)(__ccgo_up((*TFts5Config)(unsafe.Pointer(pConfig)).FaPrefix + uintptr((*TFts5Config)(unsafe.Pointer(pConfig)).FnPrefix)*4)) = nPre (*TFts5Config)(unsafe.Pointer(pConfig)).FnPrefix = (*TFts5Config)(unsafe.Pointer(pConfig)).FnPrefix + 1 bFirst = 0 } return **(**int32)(__ccgo_up(bp)) } if Xsqlite3_strnicmp(tls, __ccgo_ts+37539, zCmd, nCmd) == 0 { p1 = zArg nArg = libc.Int64FromUint64(libc.Xstrlen(tls, zArg) + uint64(1)) azArg = _sqlite3Fts5MallocZero(tls, bp, libc.Int64FromUint64(uint64(libc.Uint64FromInt64(8)+libc.Uint64FromInt32(2))*libc.Uint64FromInt64(nArg))) if azArg != 0 { pSpace = azArg + uintptr(nArg)*8 if (*TFts5Config)(unsafe.Pointer(pConfig)).Ft.FazArg != 0 { **(**uintptr)(__ccgo_up(pzErr)) = Xsqlite3_mprintf(tls, __ccgo_ts+37548, 0) **(**int32)(__ccgo_up(bp)) = int32(SQLITE_ERROR) } else { nArg = 0 for { if !(p1 != 0 && **(**uint8)(__ccgo_up(p1)) != 0) { break } p2 = _fts5ConfigSkipWhitespace(tls, p1) if libc.Int32FromUint8(**(**uint8)(__ccgo_up(p2))) == int32('\'') { p1 = _fts5ConfigSkipLiteral(tls, p2) } else { p1 = _fts5ConfigSkipBareword(tls, p2) } if p1 != 0 { libc.Xmemcpy(tls, pSpace, p2, libc.Uint64FromInt64(int64(p1)-int64(p2))) **(**uintptr)(__ccgo_up(azArg + uintptr(nArg)*8)) = pSpace _sqlite3Fts5Dequote(tls, pSpace) pSpace = pSpace + uintptr(int64(p1)-int64(p2)+int64(1)) p1 = _fts5ConfigSkipWhitespace(tls, p1) } goto _1 _1: ; nArg = nArg + 1 } if p1 == uintptr(0) { **(**uintptr)(__ccgo_up(pzErr)) = Xsqlite3_mprintf(tls, __ccgo_ts+37581, 0) **(**int32)(__ccgo_up(bp)) = int32(SQLITE_ERROR) } else { (*TFts5Config)(unsafe.Pointer(pConfig)).Ft.FazArg = azArg (*TFts5Config)(unsafe.Pointer(pConfig)).Ft.FnArg = int32(nArg) azArg = uintptr(0) } } } Xsqlite3_free(tls, azArg) return **(**int32)(__ccgo_up(bp)) } if Xsqlite3_strnicmp(tls, __ccgo_ts+37615, zCmd, nCmd) == 0 { if (*TFts5Config)(unsafe.Pointer(pConfig)).FeContent != FTS5_CONTENT_NORMAL { **(**uintptr)(__ccgo_up(pzErr)) = Xsqlite3_mprintf(tls, __ccgo_ts+37623, 0) **(**int32)(__ccgo_up(bp)) = int32(SQLITE_ERROR) } else { if **(**uint8)(__ccgo_up(zArg)) != 0 { (*TFts5Config)(unsafe.Pointer(pConfig)).FeContent = int32(FTS5_CONTENT_EXTERNAL) (*TFts5Config)(unsafe.Pointer(pConfig)).FzContent = _sqlite3Fts5Mprintf(tls, bp, __ccgo_ts+37655, libc.VaList(bp+80, (*TFts5Config)(unsafe.Pointer(pConfig)).FzDb, zArg)) } else { (*TFts5Config)(unsafe.Pointer(pConfig)).FeContent = int32(FTS5_CONTENT_NONE) } } return **(**int32)(__ccgo_up(bp)) } if Xsqlite3_strnicmp(tls, __ccgo_ts+37661, zCmd, nCmd) == 0 { if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zArg))) != int32('0') && libc.Int32FromUint8(**(**uint8)(__ccgo_up(zArg))) != int32('1') || libc.Int32FromUint8(**(**uint8)(__ccgo_up(zArg + 1))) != int32('\000') { **(**uintptr)(__ccgo_up(pzErr)) = Xsqlite3_mprintf(tls, __ccgo_ts+37680, 0) **(**int32)(__ccgo_up(bp)) = int32(SQLITE_ERROR) } else { (*TFts5Config)(unsafe.Pointer(pConfig)).FbContentlessDelete = libc.BoolInt32(libc.Int32FromUint8(**(**uint8)(__ccgo_up(zArg))) == int32('1')) } return **(**int32)(__ccgo_up(bp)) } if Xsqlite3_strnicmp(tls, __ccgo_ts+37723, zCmd, nCmd) == 0 { if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zArg))) != int32('0') && libc.Int32FromUint8(**(**uint8)(__ccgo_up(zArg))) != int32('1') || libc.Int32FromUint8(**(**uint8)(__ccgo_up(zArg + 1))) != int32('\000') { **(**uintptr)(__ccgo_up(pzErr)) = Xsqlite3_mprintf(tls, __ccgo_ts+37680, 0) **(**int32)(__ccgo_up(bp)) = int32(SQLITE_ERROR) } else { (*TFts5Config)(unsafe.Pointer(pConfig)).FbContentlessUnindexed = libc.BoolInt32(libc.Int32FromUint8(**(**uint8)(__ccgo_up(zArg))) == int32('1')) } return **(**int32)(__ccgo_up(bp)) } if Xsqlite3_strnicmp(tls, __ccgo_ts+37745, zCmd, nCmd) == 0 { if (*TFts5Config)(unsafe.Pointer(pConfig)).FzContentRowid != 0 { **(**uintptr)(__ccgo_up(pzErr)) = Xsqlite3_mprintf(tls, __ccgo_ts+37759, 0) **(**int32)(__ccgo_up(bp)) = int32(SQLITE_ERROR) } else { (*TFts5Config)(unsafe.Pointer(pConfig)).FzContentRowid = _sqlite3Fts5Strndup(tls, bp, zArg, -int32(1)) } return **(**int32)(__ccgo_up(bp)) } if Xsqlite3_strnicmp(tls, __ccgo_ts+37797, zCmd, nCmd) == 0 { if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zArg))) != int32('0') && libc.Int32FromUint8(**(**uint8)(__ccgo_up(zArg))) != int32('1') || libc.Int32FromUint8(**(**uint8)(__ccgo_up(zArg + 1))) != int32('\000') { **(**uintptr)(__ccgo_up(pzErr)) = Xsqlite3_mprintf(tls, __ccgo_ts+37808, 0) **(**int32)(__ccgo_up(bp)) = int32(SQLITE_ERROR) } else { (*TFts5Config)(unsafe.Pointer(pConfig)).FbColumnsize = libc.BoolInt32(libc.Int32FromUint8(**(**uint8)(__ccgo_up(zArg))) == int32('1')) } return **(**int32)(__ccgo_up(bp)) } if Xsqlite3_strnicmp(tls, __ccgo_ts+37843, zCmd, nCmd) == 0 { if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zArg))) != int32('0') && libc.Int32FromUint8(**(**uint8)(__ccgo_up(zArg))) != int32('1') || libc.Int32FromUint8(**(**uint8)(__ccgo_up(zArg + 1))) != int32('\000') { **(**uintptr)(__ccgo_up(pzErr)) = Xsqlite3_mprintf(tls, __ccgo_ts+37850, 0) **(**int32)(__ccgo_up(bp)) = int32(SQLITE_ERROR) } else { (*TFts5Config)(unsafe.Pointer(pConfig)).FbLocale = libc.BoolInt32(libc.Int32FromUint8(**(**uint8)(__ccgo_up(zArg))) == int32('1')) } return **(**int32)(__ccgo_up(bp)) } if Xsqlite3_strnicmp(tls, __ccgo_ts+5694, zCmd, nCmd) == 0 { **(**[4]TFts5Enum)(__ccgo_up(bp + 8)) = [4]TFts5Enum{ 0: { FzName: __ccgo_ts + 8536, FeVal: int32(FTS5_DETAIL_NONE), }, 1: { FzName: __ccgo_ts + 19044, }, 2: { FzName: __ccgo_ts + 37881, FeVal: int32(FTS5_DETAIL_COLUMNS), }, 3: {}, } v2 = _fts5ConfigSetEnum(tls, bp+8, zArg, pConfig+116) **(**int32)(__ccgo_up(bp)) = v2 if v2 != 0 { **(**uintptr)(__ccgo_up(pzErr)) = Xsqlite3_mprintf(tls, __ccgo_ts+37889, 0) } return **(**int32)(__ccgo_up(bp)) } if Xsqlite3_strnicmp(tls, __ccgo_ts+37920, zCmd, nCmd) == 0 { if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zArg))) != int32('0') && libc.Int32FromUint8(**(**uint8)(__ccgo_up(zArg))) != int32('1') || libc.Int32FromUint8(**(**uint8)(__ccgo_up(zArg + 1))) != int32('\000') { **(**uintptr)(__ccgo_up(pzErr)) = Xsqlite3_mprintf(tls, __ccgo_ts+37930, 0) **(**int32)(__ccgo_up(bp)) = int32(SQLITE_ERROR) } else { (*TFts5Config)(unsafe.Pointer(pConfig)).FbTokendata = libc.BoolInt32(libc.Int32FromUint8(**(**uint8)(__ccgo_up(zArg))) == int32('1')) } return **(**int32)(__ccgo_up(bp)) } **(**uintptr)(__ccgo_up(pzErr)) = Xsqlite3_mprintf(tls, __ccgo_ts+37964, libc.VaList(bp+80, nCmd, zCmd)) return int32(SQLITE_ERROR) } func _fts5ConfigSkipLiteral(tls *libc.TLS, pIn uintptr) (r uintptr) { var p uintptr _ = p p = pIn switch libc.Int32FromUint8(**(**uint8)(__ccgo_up(p))) { case int32('n'): fallthrough case int32('N'): if Xsqlite3_strnicmp(tls, __ccgo_ts+1690, p, int32(4)) == 0 { p = p + 4 } else { p = uintptr(0) } case int32('x'): fallthrough case int32('X'): p = p + 1 if libc.Int32FromUint8(**(**uint8)(__ccgo_up(p))) == int32('\'') { p = p + 1 for libc.Int32FromUint8(**(**uint8)(__ccgo_up(p))) >= int32('a') && libc.Int32FromUint8(**(**uint8)(__ccgo_up(p))) <= int32('f') || libc.Int32FromUint8(**(**uint8)(__ccgo_up(p))) >= int32('A') && libc.Int32FromUint8(**(**uint8)(__ccgo_up(p))) <= int32('F') || libc.Int32FromUint8(**(**uint8)(__ccgo_up(p))) >= int32('0') && libc.Int32FromUint8(**(**uint8)(__ccgo_up(p))) <= int32('9') { p = p + 1 } if libc.Int32FromUint8(**(**uint8)(__ccgo_up(p))) == int32('\'') && 0 == (int64(p)-int64(pIn))%int64(2) { p = p + 1 } else { p = uintptr(0) } } else { p = uintptr(0) } case int32('\''): p = p + 1 for p != 0 { if libc.Int32FromUint8(**(**uint8)(__ccgo_up(p))) == int32('\'') { p = p + 1 if libc.Int32FromUint8(**(**uint8)(__ccgo_up(p))) != int32('\'') { break } } p = p + 1 if libc.Int32FromUint8(**(**uint8)(__ccgo_up(p))) == 0 { p = uintptr(0) } } default: /* maybe a number */ if libc.Int32FromUint8(**(**uint8)(__ccgo_up(p))) == int32('+') || libc.Int32FromUint8(**(**uint8)(__ccgo_up(p))) == int32('-') { p = p + 1 } for _fts5_isdigit(tls, **(**uint8)(__ccgo_up(p))) != 0 { p = p + 1 } /* At this point, if the literal was an integer, the parse is ** finished. Or, if it is a floating point value, it may continue ** with either a decimal point or an 'E' character. */ if libc.Int32FromUint8(**(**uint8)(__ccgo_up(p))) == int32('.') && _fts5_isdigit(tls, **(**uint8)(__ccgo_up(p + 1))) != 0 { p = p + uintptr(2) for _fts5_isdigit(tls, **(**uint8)(__ccgo_up(p))) != 0 { p = p + 1 } } if p == pIn { p = uintptr(0) } break } return p } // C documentation // // /* // ** Read the first token from the nul-terminated string at *pz. // */ func _fts5ExprGetToken(tls *libc.TLS, pParse uintptr, pz uintptr, pToken uintptr) (r int32) { bp := tls.Alloc(16) defer tls.Free(16) var tok int32 var z, z2, z21 uintptr _, _, _, _ = tok, z, z2, z21 z = **(**uintptr)(__ccgo_up(pz)) /* Skip past any whitespace */ for _fts5ExprIsspace(tls, **(**uint8)(__ccgo_up(z))) != 0 { z = z + 1 } (*TFts5Token)(unsafe.Pointer(pToken)).Fp = z (*TFts5Token)(unsafe.Pointer(pToken)).Fn = int32(1) switch libc.Int32FromUint8(**(**uint8)(__ccgo_up(z))) { case int32('('): tok = int32(FTS5_LP) case int32(')'): tok = int32(FTS5_RP) case int32('{'): tok = int32(FTS5_LCP) case int32('}'): tok = int32(FTS5_RCP) case int32(':'): tok = int32(FTS5_COLON) case int32(','): tok = int32(FTS5_COMMA) case int32('+'): tok = int32(FTS5_PLUS) case int32('*'): tok = int32(FTS5_STAR) case int32('-'): tok = int32(FTS5_MINUS) case int32('^'): tok = int32(FTS5_CARET) case int32('\000'): tok = FTS5_EOF case int32('"'): tok = int32(FTS5_STRING) z2 = z + 1 for { if !(int32(1) != 0) { break } if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z2))) == int32('"') { z2 = z2 + 1 if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z2))) != int32('"') { break } } if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z2))) == int32('\000') { _sqlite3Fts5ParseError(tls, pParse, __ccgo_ts+38571, 0) return FTS5_EOF } goto _1 _1: ; z2 = z2 + 1 } (*TFts5Token)(unsafe.Pointer(pToken)).Fn = int32(int64(z2) - int64(z)) default: if _sqlite3Fts5IsBareword(tls, **(**uint8)(__ccgo_up(z))) == 0 { _sqlite3Fts5ParseError(tls, pParse, __ccgo_ts+38591, libc.VaList(bp+8, z)) return FTS5_EOF } tok = int32(FTS5_STRING) z21 = z + 1 for { if !(_sqlite3Fts5IsBareword(tls, **(**uint8)(__ccgo_up(z21))) != 0) { break } goto _2 _2: ; z21 = z21 + 1 } (*TFts5Token)(unsafe.Pointer(pToken)).Fn = int32(int64(z21) - int64(z)) if (*TFts5Token)(unsafe.Pointer(pToken)).Fn == int32(2) && libc.Xmemcmp(tls, (*TFts5Token)(unsafe.Pointer(pToken)).Fp, __ccgo_ts+38622, uint64(2)) == 0 { tok = int32(FTS5_OR) } if (*TFts5Token)(unsafe.Pointer(pToken)).Fn == int32(3) && libc.Xmemcmp(tls, (*TFts5Token)(unsafe.Pointer(pToken)).Fp, __ccgo_ts+38625, uint64(3)) == 0 { tok = int32(FTS5_NOT) } if (*TFts5Token)(unsafe.Pointer(pToken)).Fn == int32(3) && libc.Xmemcmp(tls, (*TFts5Token)(unsafe.Pointer(pToken)).Fp, __ccgo_ts+32432, uint64(3)) == 0 { tok = int32(FTS5_AND) } break } **(**uintptr)(__ccgo_up(pz)) = (*TFts5Token)(unsafe.Pointer(pToken)).Fp + uintptr((*TFts5Token)(unsafe.Pointer(pToken)).Fn) return tok } // C documentation // // /* // ** This is the xFilter interface for the virtual table. See // ** the virtual table xFilter method documentation for additional // ** information. // ** // ** There are three possible query strategies: // ** // ** 1. Full-text search using a MATCH operator. // ** 2. A by-rowid lookup. // ** 3. A full-table scan. // */ func _fts5FilterMethod(tls *libc.TLS, pCursor uintptr, idxNum int32, idxStr uintptr, nVal int32, apVal uintptr) (r int32) { bp := tls.Alloc(48) defer tls.Free(48) var bDesc, bGlob, bInternal, bOrderByRank, bPrefixInsttoken, i, iCol, iIdxStr, rc, v2, v3 int32 var pConfig, pCsr, pRank, pRowidEq, pRowidGe, pRowidLe, pTab, pzErr, pzErrmsg, zText1, v6 uintptr var _ /* bFreeAndReset at bp+16 */ int32 var _ /* pExpr at bp+0 */ uintptr var _ /* zText at bp+8 */ uintptr _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = bDesc, bGlob, bInternal, bOrderByRank, bPrefixInsttoken, i, iCol, iIdxStr, pConfig, pCsr, pRank, pRowidEq, pRowidGe, pRowidLe, pTab, pzErr, pzErrmsg, rc, zText1, v2, v3, v6 pTab = (*Tsqlite3_vtab_cursor)(unsafe.Pointer(pCursor)).FpVtab pConfig = (*TFts5FullTable)(unsafe.Pointer(pTab)).Fp.FpConfig pCsr = pCursor rc = SQLITE_OK /* True if ORDER BY rank */ pRank = uintptr(0) /* rank MATCH ? expression (or NULL) */ pRowidEq = uintptr(0) /* rowid = ? expression (or NULL) */ pRowidLe = uintptr(0) /* rowid <= ? expression (or NULL) */ pRowidGe = uintptr(0) /* Column on LHS of MATCH operator */ pzErrmsg = (*TFts5Config)(unsafe.Pointer(pConfig)).FpzErrmsg bPrefixInsttoken = (*TFts5Config)(unsafe.Pointer(pConfig)).FbPrefixInsttoken iIdxStr = 0 **(**uintptr)(__ccgo_up(bp)) = uintptr(0) if (*TFts5Cursor)(unsafe.Pointer(pCsr)).FePlan != 0 { _fts5FreeCursorComponents(tls, pCsr) libc.Xmemset(tls, pCsr+32, 0, uint64(184)-libc.Uint64FromInt64(int64(pCsr+32)-int64(pCsr))) } (*TFts5Config)(unsafe.Pointer(pConfig)).FpzErrmsg = pTab + 16 /* Decode the arguments passed through to this function. */ i = 0 for { if !(i < nVal) { break } v2 = iIdxStr iIdxStr = iIdxStr + 1 switch libc.Int32FromUint8(**(**uint8)(__ccgo_up(idxStr + uintptr(v2)))) { case int32('r'): pRank = **(**uintptr)(__ccgo_up(apVal + uintptr(i)*8)) case int32('M'): **(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0) **(**int32)(__ccgo_up(bp + 16)) = 0 bInternal = 0 rc = _fts5ExtractExprText(tls, pConfig, **(**uintptr)(__ccgo_up(apVal + uintptr(i)*8)), bp+8, bp+16) if rc != SQLITE_OK { goto filter_out } if **(**uintptr)(__ccgo_up(bp + 8)) == uintptr(0) { **(**uintptr)(__ccgo_up(bp + 8)) = __ccgo_ts + 1704 } if Xsqlite3_value_subtype(tls, **(**uintptr)(__ccgo_up(apVal + uintptr(i)*8))) == uint32(FTS5_INSTTOKEN_SUBTYPE) { (*TFts5Config)(unsafe.Pointer(pConfig)).FbPrefixInsttoken = int32(1) } iCol = 0 for cond := true; cond; cond = libc.Int32FromUint8(**(**uint8)(__ccgo_up(idxStr + uintptr(iIdxStr)))) >= int32('0') && libc.Int32FromUint8(**(**uint8)(__ccgo_up(idxStr + uintptr(iIdxStr)))) <= int32('9') { iCol = iCol*int32(10) + (libc.Int32FromUint8(**(**uint8)(__ccgo_up(idxStr + uintptr(iIdxStr)))) - int32('0')) iIdxStr = iIdxStr + 1 } if libc.Int32FromUint8(**(**uint8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp + 8))))) == int32('*') { /* The user has issued a query of the form "MATCH '*...'". This ** indicates that the MATCH expression is not a full text query, ** but a request for an internal parameter. */ rc = _fts5SpecialMatch(tls, pTab, pCsr, **(**uintptr)(__ccgo_up(bp + 8))+1) bInternal = int32(1) } else { pzErr = pTab + 16 rc = _sqlite3Fts5ExprNew(tls, pConfig, 0, iCol, **(**uintptr)(__ccgo_up(bp + 8)), bp, pzErr) if rc == SQLITE_OK { rc = _sqlite3Fts5ExprAnd(tls, pCsr+64, **(**uintptr)(__ccgo_up(bp))) **(**uintptr)(__ccgo_up(bp)) = uintptr(0) } } if **(**int32)(__ccgo_up(bp + 16)) != 0 { Xsqlite3_free(tls, **(**uintptr)(__ccgo_up(bp + 8))) _sqlite3Fts5ClearLocale(tls, pConfig) } if bInternal != 0 || rc != SQLITE_OK { goto filter_out } case int32('L'): fallthrough case int32('G'): bGlob = libc.BoolInt32(libc.Int32FromUint8(**(**uint8)(__ccgo_up(idxStr + uintptr(iIdxStr-int32(1))))) == int32('G')) zText1 = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(apVal + uintptr(i)*8))) iCol = 0 for cond := true; cond; cond = libc.Int32FromUint8(**(**uint8)(__ccgo_up(idxStr + uintptr(iIdxStr)))) >= int32('0') && libc.Int32FromUint8(**(**uint8)(__ccgo_up(idxStr + uintptr(iIdxStr)))) <= int32('9') { iCol = iCol*int32(10) + (libc.Int32FromUint8(**(**uint8)(__ccgo_up(idxStr + uintptr(iIdxStr)))) - int32('0')) iIdxStr = iIdxStr + 1 } if zText1 != 0 { rc = _sqlite3Fts5ExprPattern(tls, pConfig, bGlob, iCol, zText1, bp) } if rc == SQLITE_OK { rc = _sqlite3Fts5ExprAnd(tls, pCsr+64, **(**uintptr)(__ccgo_up(bp))) **(**uintptr)(__ccgo_up(bp)) = uintptr(0) } if rc != SQLITE_OK { goto filter_out } case int32('='): pRowidEq = **(**uintptr)(__ccgo_up(apVal + uintptr(i)*8)) case int32('<'): pRowidLe = **(**uintptr)(__ccgo_up(apVal + uintptr(i)*8)) default: pRowidGe = **(**uintptr)(__ccgo_up(apVal + uintptr(i)*8)) break } goto _1 _1: ; i = i + 1 } if idxNum&int32(FTS5_BI_ORDER_RANK) != 0 { v2 = int32(1) } else { v2 = 0 } bOrderByRank = v2 if idxNum&int32(FTS5_BI_ORDER_DESC) != 0 { v3 = int32(1) } else { v3 = 0 } v2 = v3 bDesc = v2 (*TFts5Cursor)(unsafe.Pointer(pCsr)).FbDesc = v2 /* Set the cursor upper and lower rowid limits. Only some strategies ** actually use them. This is ok, as the xBestIndex() method leaves the ** sqlite3_index_constraint.omit flag clear for range constraints ** on the rowid field. */ if pRowidEq != 0 { v6 = pRowidEq pRowidGe = v6 pRowidLe = v6 } if bDesc != 0 { (*TFts5Cursor)(unsafe.Pointer(pCsr)).FiFirstRowid = _fts5GetRowidLimit(tls, pRowidLe, libc.Int64FromUint32(0xffffffff)|libc.Int64FromInt32(0x7fffffff)< ORDER BY rank" query (ePlan is ** set to FTS5_PLAN_SORTED_MATCH). pSortCsr is the cursor that will ** return results to the user for this query. The current cursor ** (pCursor) is used to execute the query issued by function ** fts5CursorFirstSorted() above. */ if (*TFts5Cursor)(unsafe.Pointer((*TFts5FullTable)(unsafe.Pointer(pTab)).FpSortCsr)).FbDesc != 0 { (*TFts5Cursor)(unsafe.Pointer(pCsr)).FiLastRowid = (*TFts5Cursor)(unsafe.Pointer((*TFts5FullTable)(unsafe.Pointer(pTab)).FpSortCsr)).FiFirstRowid (*TFts5Cursor)(unsafe.Pointer(pCsr)).FiFirstRowid = (*TFts5Cursor)(unsafe.Pointer((*TFts5FullTable)(unsafe.Pointer(pTab)).FpSortCsr)).FiLastRowid } else { (*TFts5Cursor)(unsafe.Pointer(pCsr)).FiLastRowid = (*TFts5Cursor)(unsafe.Pointer((*TFts5FullTable)(unsafe.Pointer(pTab)).FpSortCsr)).FiLastRowid (*TFts5Cursor)(unsafe.Pointer(pCsr)).FiFirstRowid = (*TFts5Cursor)(unsafe.Pointer((*TFts5FullTable)(unsafe.Pointer(pTab)).FpSortCsr)).FiFirstRowid } (*TFts5Cursor)(unsafe.Pointer(pCsr)).FePlan = int32(FTS5_PLAN_SOURCE) (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpExpr = (*TFts5Cursor)(unsafe.Pointer((*TFts5FullTable)(unsafe.Pointer(pTab)).FpSortCsr)).FpExpr rc = _fts5CursorFirst(tls, pTab, pCsr, bDesc) } else { if (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpExpr != 0 { rc = _fts5CursorParseRank(tls, pConfig, pCsr, pRank) if rc == SQLITE_OK { if bOrderByRank != 0 { (*TFts5Cursor)(unsafe.Pointer(pCsr)).FePlan = int32(FTS5_PLAN_SORTED_MATCH) rc = _fts5CursorFirstSorted(tls, pTab, pCsr, bDesc) } else { (*TFts5Cursor)(unsafe.Pointer(pCsr)).FePlan = int32(FTS5_PLAN_MATCH) rc = _fts5CursorFirst(tls, pTab, pCsr, bDesc) } } } else { if (*TFts5Config)(unsafe.Pointer(pConfig)).FzContent == uintptr(0) { _fts5SetVtabError(tls, pTab, __ccgo_ts+39941, libc.VaList(bp+32, (*TFts5Config)(unsafe.Pointer(pConfig)).FzName)) rc = int32(SQLITE_ERROR) } else { /* This is either a full-table scan (ePlan==FTS5_PLAN_SCAN) or a lookup ** by rowid (ePlan==FTS5_PLAN_ROWID). */ if pRowidEq != 0 { v2 = int32(FTS5_PLAN_ROWID) } else { v2 = int32(FTS5_PLAN_SCAN) } (*TFts5Cursor)(unsafe.Pointer(pCsr)).FePlan = v2 rc = _sqlite3Fts5StorageStmt(tls, (*TFts5FullTable)(unsafe.Pointer(pTab)).FpStorage, _fts5StmtType(tls, pCsr), pCsr+56, pTab+16) if rc == SQLITE_OK { if pRowidEq != uintptr(0) { Xsqlite3_bind_value(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpStmt, int32(1), pRowidEq) } else { Xsqlite3_bind_int64(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpStmt, int32(1), (*TFts5Cursor)(unsafe.Pointer(pCsr)).FiFirstRowid) Xsqlite3_bind_int64(tls, (*TFts5Cursor)(unsafe.Pointer(pCsr)).FpStmt, int32(2), (*TFts5Cursor)(unsafe.Pointer(pCsr)).FiLastRowid) } rc = _fts5NextMethod(tls, pCursor) } } } } goto filter_out filter_out: ; _sqlite3Fts5ExprFree(tls, **(**uintptr)(__ccgo_up(bp))) (*TFts5Config)(unsafe.Pointer(pConfig)).FpzErrmsg = pzErrmsg (*TFts5Config)(unsafe.Pointer(pConfig)).FbPrefixInsttoken = bPrefixInsttoken return rc } func _fts5PorterStep1B(tls *libc.TLS, aBuf uintptr, pnBuf uintptr) (r int32) { var nBuf, ret int32 _, _ = nBuf, ret ret = 0 nBuf = **(**int32)(__ccgo_up(pnBuf)) switch libc.Int32FromUint8(**(**uint8)(__ccgo_up(aBuf + uintptr(nBuf-int32(2))))) { case int32('e'): if nBuf > int32(3) && 0 == libc.Xmemcmp(tls, __ccgo_ts+42200, aBuf+uintptr(nBuf-int32(3)), uint64(3)) { if _fts5Porter_MGt0(tls, aBuf, nBuf-int32(3)) != 0 { libc.Xmemcpy(tls, aBuf+uintptr(nBuf-int32(3)), __ccgo_ts+42204, uint64(2)) **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(3) + int32(2) } } else { if nBuf > int32(2) && 0 == libc.Xmemcmp(tls, __ccgo_ts+42207, aBuf+uintptr(nBuf-int32(2)), uint64(2)) { if _fts5Porter_Vowel(tls, aBuf, nBuf-int32(2)) != 0 { **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(2) ret = int32(1) } } } case int32('n'): if nBuf > int32(3) && 0 == libc.Xmemcmp(tls, __ccgo_ts+42210, aBuf+uintptr(nBuf-int32(3)), uint64(3)) { if _fts5Porter_Vowel(tls, aBuf, nBuf-int32(3)) != 0 { **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(3) ret = int32(1) } } break } return ret } /* ** GENERATED CODE ENDS HERE (mkportersteps.tcl) *************************************************************************** **************************************************************************/ func _fts5PorterStep1B2(tls *libc.TLS, aBuf uintptr, pnBuf uintptr) (r int32) { var nBuf, ret int32 _, _ = nBuf, ret ret = 0 nBuf = **(**int32)(__ccgo_up(pnBuf)) switch libc.Int32FromUint8(**(**uint8)(__ccgo_up(aBuf + uintptr(nBuf-int32(2))))) { case int32('a'): if nBuf > int32(2) && 0 == libc.Xmemcmp(tls, __ccgo_ts+42014, aBuf+uintptr(nBuf-int32(2)), uint64(2)) { libc.Xmemcpy(tls, aBuf+uintptr(nBuf-int32(2)), __ccgo_ts+41994, uint64(3)) **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(2) + int32(3) ret = int32(1) } case int32('b'): if nBuf > int32(2) && 0 == libc.Xmemcmp(tls, __ccgo_ts+42017, aBuf+uintptr(nBuf-int32(2)), uint64(2)) { libc.Xmemcpy(tls, aBuf+uintptr(nBuf-int32(2)), __ccgo_ts+42020, uint64(3)) **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(2) + int32(3) ret = int32(1) } case int32('i'): if nBuf > int32(2) && 0 == libc.Xmemcmp(tls, __ccgo_ts+42024, aBuf+uintptr(nBuf-int32(2)), uint64(2)) { libc.Xmemcpy(tls, aBuf+uintptr(nBuf-int32(2)), __ccgo_ts+42010, uint64(3)) **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(2) + int32(3) ret = int32(1) } break } return ret } func _fts5PorterStep2(tls *libc.TLS, aBuf uintptr, pnBuf uintptr) (r int32) { var nBuf, ret int32 _, _ = nBuf, ret ret = 0 nBuf = **(**int32)(__ccgo_up(pnBuf)) switch libc.Int32FromUint8(**(**uint8)(__ccgo_up(aBuf + uintptr(nBuf-int32(2))))) { case int32('a'): if nBuf > int32(7) && 0 == libc.Xmemcmp(tls, __ccgo_ts+42027, aBuf+uintptr(nBuf-int32(7)), uint64(7)) { if _fts5Porter_MGt0(tls, aBuf, nBuf-int32(7)) != 0 { libc.Xmemcpy(tls, aBuf+uintptr(nBuf-int32(7)), __ccgo_ts+41994, uint64(3)) **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(7) + int32(3) } } else { if nBuf > int32(6) && 0 == libc.Xmemcmp(tls, __ccgo_ts+42035, aBuf+uintptr(nBuf-int32(6)), uint64(6)) { if _fts5Porter_MGt0(tls, aBuf, nBuf-int32(6)) != 0 { libc.Xmemcpy(tls, aBuf+uintptr(nBuf-int32(6)), __ccgo_ts+42042, uint64(4)) **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(6) + int32(4) } } } case int32('c'): if nBuf > int32(4) && 0 == libc.Xmemcmp(tls, __ccgo_ts+42047, aBuf+uintptr(nBuf-int32(4)), uint64(4)) { if _fts5Porter_MGt0(tls, aBuf, nBuf-int32(4)) != 0 { libc.Xmemcpy(tls, aBuf+uintptr(nBuf-int32(4)), __ccgo_ts+41943, uint64(4)) **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(4) + int32(4) } } else { if nBuf > int32(4) && 0 == libc.Xmemcmp(tls, __ccgo_ts+42052, aBuf+uintptr(nBuf-int32(4)), uint64(4)) { if _fts5Porter_MGt0(tls, aBuf, nBuf-int32(4)) != 0 { libc.Xmemcpy(tls, aBuf+uintptr(nBuf-int32(4)), __ccgo_ts+41938, uint64(4)) **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(4) + int32(4) } } } case int32('e'): if nBuf > int32(4) && 0 == libc.Xmemcmp(tls, __ccgo_ts+42057, aBuf+uintptr(nBuf-int32(4)), uint64(4)) { if _fts5Porter_MGt0(tls, aBuf, nBuf-int32(4)) != 0 { libc.Xmemcpy(tls, aBuf+uintptr(nBuf-int32(4)), __ccgo_ts+42010, uint64(3)) **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(4) + int32(3) } } case int32('g'): if nBuf > int32(4) && 0 == libc.Xmemcmp(tls, __ccgo_ts+42062, aBuf+uintptr(nBuf-int32(4)), uint64(4)) { if _fts5Porter_MGt0(tls, aBuf, nBuf-int32(4)) != 0 { libc.Xmemcpy(tls, aBuf+uintptr(nBuf-int32(4)), __ccgo_ts+17193, uint64(3)) **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(4) + int32(3) } } case int32('l'): if nBuf > int32(3) && 0 == libc.Xmemcmp(tls, __ccgo_ts+42067, aBuf+uintptr(nBuf-int32(3)), uint64(3)) { if _fts5Porter_MGt0(tls, aBuf, nBuf-int32(3)) != 0 { libc.Xmemcpy(tls, aBuf+uintptr(nBuf-int32(3)), __ccgo_ts+42020, uint64(3)) **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(3) + int32(3) } } else { if nBuf > int32(4) && 0 == libc.Xmemcmp(tls, __ccgo_ts+42071, aBuf+uintptr(nBuf-int32(4)), uint64(4)) { if _fts5Porter_MGt0(tls, aBuf, nBuf-int32(4)) != 0 { libc.Xmemcpy(tls, aBuf+uintptr(nBuf-int32(4)), __ccgo_ts+41935, uint64(2)) **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(4) + int32(2) } } else { if nBuf > int32(5) && 0 == libc.Xmemcmp(tls, __ccgo_ts+42076, aBuf+uintptr(nBuf-int32(5)), uint64(5)) { if _fts5Porter_MGt0(tls, aBuf, nBuf-int32(5)) != 0 { libc.Xmemcpy(tls, aBuf+uintptr(nBuf-int32(5)), __ccgo_ts+41979, uint64(3)) **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(5) + int32(3) } } else { if nBuf > int32(3) && 0 == libc.Xmemcmp(tls, __ccgo_ts+42082, aBuf+uintptr(nBuf-int32(3)), uint64(3)) { if _fts5Porter_MGt0(tls, aBuf, nBuf-int32(3)) != 0 { libc.Xmemcpy(tls, aBuf+uintptr(nBuf-int32(3)), __ccgo_ts+42086, uint64(1)) **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(3) + int32(1) } } else { if nBuf > int32(5) && 0 == libc.Xmemcmp(tls, __ccgo_ts+42088, aBuf+uintptr(nBuf-int32(5)), uint64(5)) { if _fts5Porter_MGt0(tls, aBuf, nBuf-int32(5)) != 0 { libc.Xmemcpy(tls, aBuf+uintptr(nBuf-int32(5)), __ccgo_ts+42002, uint64(3)) **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(5) + int32(3) } } } } } } case int32('o'): if nBuf > int32(7) && 0 == libc.Xmemcmp(tls, __ccgo_ts+42094, aBuf+uintptr(nBuf-int32(7)), uint64(7)) { if _fts5Porter_MGt0(tls, aBuf, nBuf-int32(7)) != 0 { libc.Xmemcpy(tls, aBuf+uintptr(nBuf-int32(7)), __ccgo_ts+42010, uint64(3)) **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(7) + int32(3) } } else { if nBuf > int32(5) && 0 == libc.Xmemcmp(tls, __ccgo_ts+42102, aBuf+uintptr(nBuf-int32(5)), uint64(5)) { if _fts5Porter_MGt0(tls, aBuf, nBuf-int32(5)) != 0 { libc.Xmemcpy(tls, aBuf+uintptr(nBuf-int32(5)), __ccgo_ts+41994, uint64(3)) **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(5) + int32(3) } } else { if nBuf > int32(4) && 0 == libc.Xmemcmp(tls, __ccgo_ts+42108, aBuf+uintptr(nBuf-int32(4)), uint64(4)) { if _fts5Porter_MGt0(tls, aBuf, nBuf-int32(4)) != 0 { libc.Xmemcpy(tls, aBuf+uintptr(nBuf-int32(4)), __ccgo_ts+41994, uint64(3)) **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(4) + int32(3) } } } } case int32('s'): if nBuf > int32(5) && 0 == libc.Xmemcmp(tls, __ccgo_ts+42113, aBuf+uintptr(nBuf-int32(5)), uint64(5)) { if _fts5Porter_MGt0(tls, aBuf, nBuf-int32(5)) != 0 { libc.Xmemcpy(tls, aBuf+uintptr(nBuf-int32(5)), __ccgo_ts+41935, uint64(2)) **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(5) + int32(2) } } else { if nBuf > int32(7) && 0 == libc.Xmemcmp(tls, __ccgo_ts+42119, aBuf+uintptr(nBuf-int32(7)), uint64(7)) { if _fts5Porter_MGt0(tls, aBuf, nBuf-int32(7)) != 0 { libc.Xmemcpy(tls, aBuf+uintptr(nBuf-int32(7)), __ccgo_ts+42006, uint64(3)) **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(7) + int32(3) } } else { if nBuf > int32(7) && 0 == libc.Xmemcmp(tls, __ccgo_ts+42127, aBuf+uintptr(nBuf-int32(7)), uint64(7)) { if _fts5Porter_MGt0(tls, aBuf, nBuf-int32(7)) != 0 { libc.Xmemcpy(tls, aBuf+uintptr(nBuf-int32(7)), __ccgo_ts+42135, uint64(3)) **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(7) + int32(3) } } else { if nBuf > int32(7) && 0 == libc.Xmemcmp(tls, __ccgo_ts+42139, aBuf+uintptr(nBuf-int32(7)), uint64(7)) { if _fts5Porter_MGt0(tls, aBuf, nBuf-int32(7)) != 0 { libc.Xmemcpy(tls, aBuf+uintptr(nBuf-int32(7)), __ccgo_ts+42002, uint64(3)) **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(7) + int32(3) } } } } } case int32('t'): if nBuf > int32(5) && 0 == libc.Xmemcmp(tls, __ccgo_ts+42147, aBuf+uintptr(nBuf-int32(5)), uint64(5)) { if _fts5Porter_MGt0(tls, aBuf, nBuf-int32(5)) != 0 { libc.Xmemcpy(tls, aBuf+uintptr(nBuf-int32(5)), __ccgo_ts+41935, uint64(2)) **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(5) + int32(2) } } else { if nBuf > int32(5) && 0 == libc.Xmemcmp(tls, __ccgo_ts+42153, aBuf+uintptr(nBuf-int32(5)), uint64(5)) { if _fts5Porter_MGt0(tls, aBuf, nBuf-int32(5)) != 0 { libc.Xmemcpy(tls, aBuf+uintptr(nBuf-int32(5)), __ccgo_ts+42006, uint64(3)) **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(5) + int32(3) } } else { if nBuf > int32(6) && 0 == libc.Xmemcmp(tls, __ccgo_ts+42159, aBuf+uintptr(nBuf-int32(6)), uint64(6)) { if _fts5Porter_MGt0(tls, aBuf, nBuf-int32(6)) != 0 { libc.Xmemcpy(tls, aBuf+uintptr(nBuf-int32(6)), __ccgo_ts+42020, uint64(3)) **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(6) + int32(3) } } } } break } return ret } func _fts5PorterStep3(tls *libc.TLS, aBuf uintptr, pnBuf uintptr) (r int32) { var nBuf, ret int32 _, _ = nBuf, ret ret = 0 nBuf = **(**int32)(__ccgo_up(pnBuf)) switch libc.Int32FromUint8(**(**uint8)(__ccgo_up(aBuf + uintptr(nBuf-int32(2))))) { case int32('a'): if nBuf > int32(4) && 0 == libc.Xmemcmp(tls, __ccgo_ts+42166, aBuf+uintptr(nBuf-int32(4)), uint64(4)) { if _fts5Porter_MGt0(tls, aBuf, nBuf-int32(4)) != 0 { libc.Xmemcpy(tls, aBuf+uintptr(nBuf-int32(4)), __ccgo_ts+41951, uint64(2)) **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(4) + int32(2) } } case int32('s'): if nBuf > int32(4) && 0 == libc.Xmemcmp(tls, __ccgo_ts+42171, aBuf+uintptr(nBuf-int32(4)), uint64(4)) { if _fts5Porter_MGt0(tls, aBuf, nBuf-int32(4)) != 0 { **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(4) } } case int32('t'): if nBuf > int32(5) && 0 == libc.Xmemcmp(tls, __ccgo_ts+42176, aBuf+uintptr(nBuf-int32(5)), uint64(5)) { if _fts5Porter_MGt0(tls, aBuf, nBuf-int32(5)) != 0 { libc.Xmemcpy(tls, aBuf+uintptr(nBuf-int32(5)), __ccgo_ts+41951, uint64(2)) **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(5) + int32(2) } } else { if nBuf > int32(5) && 0 == libc.Xmemcmp(tls, __ccgo_ts+42182, aBuf+uintptr(nBuf-int32(5)), uint64(5)) { if _fts5Porter_MGt0(tls, aBuf, nBuf-int32(5)) != 0 { libc.Xmemcpy(tls, aBuf+uintptr(nBuf-int32(5)), __ccgo_ts+41951, uint64(2)) **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(5) + int32(2) } } } case int32('u'): if nBuf > int32(3) && 0 == libc.Xmemcmp(tls, __ccgo_ts+42135, aBuf+uintptr(nBuf-int32(3)), uint64(3)) { if _fts5Porter_MGt0(tls, aBuf, nBuf-int32(3)) != 0 { **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(3) } } case int32('v'): if nBuf > int32(5) && 0 == libc.Xmemcmp(tls, __ccgo_ts+42188, aBuf+uintptr(nBuf-int32(5)), uint64(5)) { if _fts5Porter_MGt0(tls, aBuf, nBuf-int32(5)) != 0 { **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(5) } } case int32('z'): if nBuf > int32(5) && 0 == libc.Xmemcmp(tls, __ccgo_ts+42194, aBuf+uintptr(nBuf-int32(5)), uint64(5)) { if _fts5Porter_MGt0(tls, aBuf, nBuf-int32(5)) != 0 { libc.Xmemcpy(tls, aBuf+uintptr(nBuf-int32(5)), __ccgo_ts+41935, uint64(2)) **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(5) + int32(2) } } break } return ret } func _fts5PorterStep4(tls *libc.TLS, aBuf uintptr, pnBuf uintptr) (r int32) { var nBuf, ret int32 _, _ = nBuf, ret ret = 0 nBuf = **(**int32)(__ccgo_up(pnBuf)) switch libc.Int32FromUint8(**(**uint8)(__ccgo_up(aBuf + uintptr(nBuf-int32(2))))) { case int32('a'): if nBuf > int32(2) && 0 == libc.Xmemcmp(tls, __ccgo_ts+41935, aBuf+uintptr(nBuf-int32(2)), uint64(2)) { if _fts5Porter_MGt1(tls, aBuf, nBuf-int32(2)) != 0 { **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(2) } } case int32('c'): if nBuf > int32(4) && 0 == libc.Xmemcmp(tls, __ccgo_ts+41938, aBuf+uintptr(nBuf-int32(4)), uint64(4)) { if _fts5Porter_MGt1(tls, aBuf, nBuf-int32(4)) != 0 { **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(4) } } else { if nBuf > int32(4) && 0 == libc.Xmemcmp(tls, __ccgo_ts+41943, aBuf+uintptr(nBuf-int32(4)), uint64(4)) { if _fts5Porter_MGt1(tls, aBuf, nBuf-int32(4)) != 0 { **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(4) } } } case int32('e'): if nBuf > int32(2) && 0 == libc.Xmemcmp(tls, __ccgo_ts+41948, aBuf+uintptr(nBuf-int32(2)), uint64(2)) { if _fts5Porter_MGt1(tls, aBuf, nBuf-int32(2)) != 0 { **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(2) } } case int32('i'): if nBuf > int32(2) && 0 == libc.Xmemcmp(tls, __ccgo_ts+41951, aBuf+uintptr(nBuf-int32(2)), uint64(2)) { if _fts5Porter_MGt1(tls, aBuf, nBuf-int32(2)) != 0 { **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(2) } } case int32('l'): if nBuf > int32(4) && 0 == libc.Xmemcmp(tls, __ccgo_ts+41954, aBuf+uintptr(nBuf-int32(4)), uint64(4)) { if _fts5Porter_MGt1(tls, aBuf, nBuf-int32(4)) != 0 { **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(4) } } else { if nBuf > int32(4) && 0 == libc.Xmemcmp(tls, __ccgo_ts+41959, aBuf+uintptr(nBuf-int32(4)), uint64(4)) { if _fts5Porter_MGt1(tls, aBuf, nBuf-int32(4)) != 0 { **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(4) } } } case int32('n'): if nBuf > int32(3) && 0 == libc.Xmemcmp(tls, __ccgo_ts+41964, aBuf+uintptr(nBuf-int32(3)), uint64(3)) { if _fts5Porter_MGt1(tls, aBuf, nBuf-int32(3)) != 0 { **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(3) } } else { if nBuf > int32(5) && 0 == libc.Xmemcmp(tls, __ccgo_ts+41968, aBuf+uintptr(nBuf-int32(5)), uint64(5)) { if _fts5Porter_MGt1(tls, aBuf, nBuf-int32(5)) != 0 { **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(5) } } else { if nBuf > int32(4) && 0 == libc.Xmemcmp(tls, __ccgo_ts+41974, aBuf+uintptr(nBuf-int32(4)), uint64(4)) { if _fts5Porter_MGt1(tls, aBuf, nBuf-int32(4)) != 0 { **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(4) } } else { if nBuf > int32(3) && 0 == libc.Xmemcmp(tls, __ccgo_ts+41979, aBuf+uintptr(nBuf-int32(3)), uint64(3)) { if _fts5Porter_MGt1(tls, aBuf, nBuf-int32(3)) != 0 { **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(3) } } } } } case int32('o'): if nBuf > int32(3) && 0 == libc.Xmemcmp(tls, __ccgo_ts+41983, aBuf+uintptr(nBuf-int32(3)), uint64(3)) { if _fts5Porter_MGt1_and_S_or_T(tls, aBuf, nBuf-int32(3)) != 0 { **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(3) } } else { if nBuf > int32(2) && 0 == libc.Xmemcmp(tls, __ccgo_ts+41987, aBuf+uintptr(nBuf-int32(2)), uint64(2)) { if _fts5Porter_MGt1(tls, aBuf, nBuf-int32(2)) != 0 { **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(2) } } } case int32('s'): if nBuf > int32(3) && 0 == libc.Xmemcmp(tls, __ccgo_ts+41990, aBuf+uintptr(nBuf-int32(3)), uint64(3)) { if _fts5Porter_MGt1(tls, aBuf, nBuf-int32(3)) != 0 { **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(3) } } case int32('t'): if nBuf > int32(3) && 0 == libc.Xmemcmp(tls, __ccgo_ts+41994, aBuf+uintptr(nBuf-int32(3)), uint64(3)) { if _fts5Porter_MGt1(tls, aBuf, nBuf-int32(3)) != 0 { **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(3) } } else { if nBuf > int32(3) && 0 == libc.Xmemcmp(tls, __ccgo_ts+41998, aBuf+uintptr(nBuf-int32(3)), uint64(3)) { if _fts5Porter_MGt1(tls, aBuf, nBuf-int32(3)) != 0 { **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(3) } } } case int32('u'): if nBuf > int32(3) && 0 == libc.Xmemcmp(tls, __ccgo_ts+42002, aBuf+uintptr(nBuf-int32(3)), uint64(3)) { if _fts5Porter_MGt1(tls, aBuf, nBuf-int32(3)) != 0 { **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(3) } } case int32('v'): if nBuf > int32(3) && 0 == libc.Xmemcmp(tls, __ccgo_ts+42006, aBuf+uintptr(nBuf-int32(3)), uint64(3)) { if _fts5Porter_MGt1(tls, aBuf, nBuf-int32(3)) != 0 { **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(3) } } case int32('z'): if nBuf > int32(3) && 0 == libc.Xmemcmp(tls, __ccgo_ts+42010, aBuf+uintptr(nBuf-int32(3)), uint64(3)) { if _fts5Porter_MGt1(tls, aBuf, nBuf-int32(3)) != 0 { **(**int32)(__ccgo_up(pnBuf)) = nBuf - int32(3) } } break } return ret } // C documentation // // /* // ** Allocate a trigram tokenizer. // */ func _fts5TriCreate(tls *libc.TLS, pUnused uintptr, azArg uintptr, nArg int32, ppOut uintptr) (r int32) { var i, rc, v2 int32 var pNew, zArg uintptr _, _, _, _, _ = i, pNew, rc, zArg, v2 rc = SQLITE_OK pNew = uintptr(0) _ = pUnused if nArg%int32(2) != 0 { rc = int32(SQLITE_ERROR) } else { pNew = Xsqlite3_malloc64(tls, uint64(8)) if pNew == uintptr(0) { rc = int32(SQLITE_NOMEM) } else { (*TTrigramTokenizer)(unsafe.Pointer(pNew)).FbFold = int32(1) (*TTrigramTokenizer)(unsafe.Pointer(pNew)).FiFoldParam = 0 i = 0 for { if !(rc == SQLITE_OK && i < nArg) { break } zArg = **(**uintptr)(__ccgo_up(azArg + uintptr(i+int32(1))*8)) if 0 == Xsqlite3_stricmp(tls, **(**uintptr)(__ccgo_up(azArg + uintptr(i)*8)), __ccgo_ts+42214) { if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zArg))) != int32('0') && libc.Int32FromUint8(**(**uint8)(__ccgo_up(zArg))) != int32('1') || **(**uint8)(__ccgo_up(zArg + 1)) != 0 { rc = int32(SQLITE_ERROR) } else { (*TTrigramTokenizer)(unsafe.Pointer(pNew)).FbFold = libc.BoolInt32(libc.Int32FromUint8(**(**uint8)(__ccgo_up(zArg))) == int32('0')) } } else { if 0 == Xsqlite3_stricmp(tls, **(**uintptr)(__ccgo_up(azArg + uintptr(i)*8)), __ccgo_ts+41900) { if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zArg))) != int32('0') && libc.Int32FromUint8(**(**uint8)(__ccgo_up(zArg))) != int32('1') && libc.Int32FromUint8(**(**uint8)(__ccgo_up(zArg))) != int32('2') || **(**uint8)(__ccgo_up(zArg + 1)) != 0 { rc = int32(SQLITE_ERROR) } else { if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zArg))) != int32('0') { v2 = int32(2) } else { v2 = 0 } (*TTrigramTokenizer)(unsafe.Pointer(pNew)).FiFoldParam = v2 } } else { rc = int32(SQLITE_ERROR) } } goto _1 _1: ; i = i + int32(2) } if (*TTrigramTokenizer)(unsafe.Pointer(pNew)).FiFoldParam != 0 && (*TTrigramTokenizer)(unsafe.Pointer(pNew)).FbFold == 0 { rc = int32(SQLITE_ERROR) } if rc != SQLITE_OK { _fts5TriDelete(tls, pNew) pNew = uintptr(0) } } } **(**uintptr)(__ccgo_up(ppOut)) = pNew return rc } // C documentation // // /* // ** Create a "unicode61" tokenizer. // */ func _fts5UnicodeCreate(tls *libc.TLS, pUnused uintptr, azArg uintptr, nArg int32, ppOut uintptr) (r int32) { var i, rc int32 var p, zArg, zCat uintptr _, _, _, _, _ = i, p, rc, zArg, zCat rc = SQLITE_OK /* Return code */ p = uintptr(0) /* New tokenizer object */ _ = pUnused if nArg%int32(2) != 0 { rc = int32(SQLITE_ERROR) } else { p = Xsqlite3_malloc64(tls, uint64(192)) if p != 0 { zCat = __ccgo_ts + 41880 libc.Xmemset(tls, p, 0, uint64(192)) (*TUnicode61Tokenizer)(unsafe.Pointer(p)).FeRemoveDiacritic = int32(FTS5_REMOVE_DIACRITICS_SIMPLE) (*TUnicode61Tokenizer)(unsafe.Pointer(p)).FnFold = int32(64) (*TUnicode61Tokenizer)(unsafe.Pointer(p)).FaFold = Xsqlite3_malloc64(tls, uint64(libc.Uint64FromInt32((*TUnicode61Tokenizer)(unsafe.Pointer(p)).FnFold)*uint64(1))) if (*TUnicode61Tokenizer)(unsafe.Pointer(p)).FaFold == uintptr(0) { rc = int32(SQLITE_NOMEM) } /* Search for a "categories" argument */ i = 0 for { if !(rc == SQLITE_OK && i < nArg) { break } if 0 == Xsqlite3_stricmp(tls, **(**uintptr)(__ccgo_up(azArg + uintptr(i)*8)), __ccgo_ts+41889) { zCat = **(**uintptr)(__ccgo_up(azArg + uintptr(i+int32(1))*8)) } goto _1 _1: ; i = i + int32(2) } if rc == SQLITE_OK { rc = _unicodeSetCategories(tls, p, zCat) } i = 0 for { if !(rc == SQLITE_OK && i < nArg) { break } zArg = **(**uintptr)(__ccgo_up(azArg + uintptr(i+int32(1))*8)) if 0 == Xsqlite3_stricmp(tls, **(**uintptr)(__ccgo_up(azArg + uintptr(i)*8)), __ccgo_ts+41900) { if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zArg))) != int32('0') && libc.Int32FromUint8(**(**uint8)(__ccgo_up(zArg))) != int32('1') && libc.Int32FromUint8(**(**uint8)(__ccgo_up(zArg))) != int32('2') || **(**uint8)(__ccgo_up(zArg + 1)) != 0 { rc = int32(SQLITE_ERROR) } else { (*TUnicode61Tokenizer)(unsafe.Pointer(p)).FeRemoveDiacritic = libc.Int32FromUint8(**(**uint8)(__ccgo_up(zArg))) - int32('0') } } else { if 0 == Xsqlite3_stricmp(tls, **(**uintptr)(__ccgo_up(azArg + uintptr(i)*8)), __ccgo_ts+41858) { rc = _fts5UnicodeAddExceptions(tls, p, zArg, int32(1)) } else { if 0 == Xsqlite3_stricmp(tls, **(**uintptr)(__ccgo_up(azArg + uintptr(i)*8)), __ccgo_ts+41869) { rc = _fts5UnicodeAddExceptions(tls, p, zArg, 0) } else { if 0 == Xsqlite3_stricmp(tls, **(**uintptr)(__ccgo_up(azArg + uintptr(i)*8)), __ccgo_ts+41889) { /* no-op */ } else { rc = int32(SQLITE_ERROR) } } } } goto _2 _2: ; i = i + int32(2) } } else { rc = int32(SQLITE_NOMEM) } if rc != SQLITE_OK { _fts5UnicodeDelete(tls, p) p = uintptr(0) } **(**uintptr)(__ccgo_up(ppOut)) = p } return rc } // C documentation // // /* // ** SQL function: geopoly_svg(X, ....) // ** // ** Interpret X as a polygon and render it as a SVG . // ** Additional arguments are added as attributes to the . // */ func _geopolySvgFunc(tls *libc.TLS, context uintptr, argc int32, argv uintptr) { bp := tls.Alloc(32) defer tls.Free(32) var cSep uint8 var db, p, x, z uintptr var i int32 _, _, _, _, _, _ = cSep, db, i, p, x, z if argc < int32(1) { return } p = _geopolyFuncParam(tls, context, **(**uintptr)(__ccgo_up(argv)), uintptr(0)) if p != 0 { db = Xsqlite3_context_db_handle(tls, context) x = Xsqlite3_str_new(tls, db) cSep = uint8('\'') Xsqlite3_str_appendf(tls, x, __ccgo_ts+29883, 0) i = 0 for { if !(i < (*TGeoPoly)(unsafe.Pointer(p)).FnVertex) { break } Xsqlite3_str_appendf(tls, x, __ccgo_ts+29901, libc.VaList(bp+8, libc.Int32FromUint8(cSep), float64(**(**TGeoCoord)(__ccgo_up(p + 8 + uintptr(i*int32(2))*4))), float64(**(**TGeoCoord)(__ccgo_up(p + 8 + uintptr(i*int32(2)+int32(1))*4))))) cSep = uint8(' ') goto _1 _1: ; i = i + 1 } Xsqlite3_str_appendf(tls, x, __ccgo_ts+29909, libc.VaList(bp+8, float64(**(**TGeoCoord)(__ccgo_up(p + 8 + uintptr(libc.Int32FromInt32(0)*libc.Int32FromInt32(2))*4))), float64(**(**TGeoCoord)(__ccgo_up(p + 8 + uintptr(libc.Int32FromInt32(0)*libc.Int32FromInt32(2)+libc.Int32FromInt32(1))*4))))) i = int32(1) for { if !(i < argc) { break } z = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv + uintptr(i)*8))) if z != 0 && **(**uint8)(__ccgo_up(z)) != 0 { Xsqlite3_str_appendf(tls, x, __ccgo_ts+29917, libc.VaList(bp+8, z)) } goto _2 _2: ; i = i + 1 } Xsqlite3_str_appendf(tls, x, __ccgo_ts+29921, 0) Xsqlite3_result_text(tls, context, Xsqlite3_str_finish(tls, x), -int32(1), __ccgo_fp(Xsqlite3_free)) Xsqlite3_free(tls, p) } } // C documentation // // /* c is a control character. Append the canonical JSON representation // ** of that control character to p. // ** // ** This routine assumes that the output buffer has already been enlarged // ** sufficiently to hold the worst-case encoding plus a nul terminator. // */ func _jsonAppendControlChar(tls *libc.TLS, p uintptr, c Tu8) { if _aSpecial[c] != 0 { **(**uint8)(__ccgo_up((*TJsonString)(unsafe.Pointer(p)).FzBuf + uintptr((*TJsonString)(unsafe.Pointer(p)).FnUsed))) = uint8('\\') **(**uint8)(__ccgo_up((*TJsonString)(unsafe.Pointer(p)).FzBuf + uintptr((*TJsonString)(unsafe.Pointer(p)).FnUsed+uint64(1)))) = _aSpecial[c] **(**Tu64)(__ccgo_up(p + 24)) += uint64(2) } else { **(**uint8)(__ccgo_up((*TJsonString)(unsafe.Pointer(p)).FzBuf + uintptr((*TJsonString)(unsafe.Pointer(p)).FnUsed))) = uint8('\\') **(**uint8)(__ccgo_up((*TJsonString)(unsafe.Pointer(p)).FzBuf + uintptr((*TJsonString)(unsafe.Pointer(p)).FnUsed+uint64(1)))) = uint8('u') **(**uint8)(__ccgo_up((*TJsonString)(unsafe.Pointer(p)).FzBuf + uintptr((*TJsonString)(unsafe.Pointer(p)).FnUsed+uint64(2)))) = uint8('0') **(**uint8)(__ccgo_up((*TJsonString)(unsafe.Pointer(p)).FzBuf + uintptr((*TJsonString)(unsafe.Pointer(p)).FnUsed+uint64(3)))) = uint8('0') **(**uint8)(__ccgo_up((*TJsonString)(unsafe.Pointer(p)).FzBuf + uintptr((*TJsonString)(unsafe.Pointer(p)).FnUsed+uint64(4)))) = **(**uint8)(__ccgo_up(__ccgo_ts + 1726 + uintptr(libc.Int32FromUint8(c)>>int32(4)))) **(**uint8)(__ccgo_up((*TJsonString)(unsafe.Pointer(p)).FzBuf + uintptr((*TJsonString)(unsafe.Pointer(p)).FnUsed+uint64(5)))) = **(**uint8)(__ccgo_up(__ccgo_ts + 1726 + uintptr(libc.Int32FromUint8(c)&int32(0xf)))) **(**Tu64)(__ccgo_up(p + 24)) += uint64(6) } } // C documentation // // /* // ** Append the path name for the current element. // */ func _jsonAppendPathName(tls *libc.TLS, p uintptr) { bp := tls.Alloc(32) defer tls.Free(32) var i, k, n Tu32 var needQuote int32 var z uintptr var _ /* sz at bp+0 */ Tu32 _, _, _, _, _ = i, k, n, needQuote, z if libc.Int32FromUint8((*TJsonEachCursor)(unsafe.Pointer(p)).FeType) == int32(JSONB_ARRAY) { _jsonPrintf(tls, int32(30), p+56, __ccgo_ts+26969, libc.VaList(bp+16, (**(**TJsonParent)(__ccgo_up((*TJsonEachCursor)(unsafe.Pointer(p)).FaParent + uintptr((*TJsonEachCursor)(unsafe.Pointer(p)).FnParent-uint32(1))*24))).FiKey)) } else { **(**Tu32)(__ccgo_up(bp)) = uint32(0) needQuote = 0 n = _jsonbPayloadSize(tls, p+192, (*TJsonEachCursor)(unsafe.Pointer(p)).Fi, bp) k = (*TJsonEachCursor)(unsafe.Pointer(p)).Fi + n z = (*TJsonEachCursor)(unsafe.Pointer(p)).FsParse.FaBlob + uintptr(k) if **(**Tu32)(__ccgo_up(bp)) == uint32(0) || !(libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(z)))])&libc.Int32FromInt32(0x02) != 0) { needQuote = int32(1) } else { i = uint32(0) for { if !(i < **(**Tu32)(__ccgo_up(bp))) { break } if !(libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(z + uintptr(i))))])&libc.Int32FromInt32(0x06) != 0) { needQuote = int32(1) break } goto _1 _1: ; i = i + 1 } } if needQuote != 0 { _jsonPrintf(tls, libc.Int32FromUint32(**(**Tu32)(__ccgo_up(bp))+uint32(4)), p+56, __ccgo_ts+26976, libc.VaList(bp+16, **(**Tu32)(__ccgo_up(bp)), z)) } else { _jsonPrintf(tls, libc.Int32FromUint32(**(**Tu32)(__ccgo_up(bp))+uint32(2)), p+56, __ccgo_ts+26984, libc.VaList(bp+16, **(**Tu32)(__ccgo_up(bp)), z)) } } } // C documentation // // /* // ** json_array_length(JSON) // ** json_array_length(JSON, PATH) // ** // ** Return the number of elements in the top-level JSON array. // ** Return 0 if the input is not a well-formed JSON array. // */ func _jsonArrayLengthFunc(tls *libc.TLS, ctx uintptr, argc int32, argv uintptr) { var cnt Tsqlite3_int64 var eErr Tu8 var i Tu32 var p, zPath, v1 uintptr _, _, _, _, _, _ = cnt, eErr, i, p, zPath, v1 /* The parse */ cnt = 0 eErr = uint8(0) p = _jsonParseFuncArg(tls, ctx, **(**uintptr)(__ccgo_up(argv)), uint32(0)) if p == uintptr(0) { return } if argc == int32(2) { zPath = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv + 1*8))) if zPath == uintptr(0) { _jsonParseFree(tls, p) return } if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zPath))) == int32('$') { v1 = zPath + uintptr(1) } else { v1 = __ccgo_ts + 26696 } i = _jsonLookupStep(tls, p, uint32(0), v1, uint32(0)) if i >= uint32(JSON_LOOKUP_PATHERROR) { if i == uint32(JSON_LOOKUP_NOTFOUND) { /* no-op */ } else { _jsonBadPathError(tls, ctx, zPath, libc.Int32FromUint32(i)) } eErr = uint8(1) i = uint32(0) } } else { i = uint32(0) } if libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TJsonParse)(unsafe.Pointer(p)).FaBlob + uintptr(i))))&int32(0x0f) == int32(JSONB_ARRAY) { cnt = libc.Int64FromUint32(_jsonbArrayCount(tls, p, i)) } if !(eErr != 0) { Xsqlite3_result_int64(tls, ctx, cnt) } _jsonParseFree(tls, p) } // C documentation // // /* Constructor for the json_each virtual table */ func _jsonEachConnect(tls *libc.TLS, db uintptr, pAux uintptr, argc int32, argv uintptr, ppVtab uintptr, pzErr uintptr) (r int32) { var pNew uintptr var rc, v1 int32 _, _, _ = pNew, rc, v1 /* Column numbers */ /* The xBestIndex method assumes that the JSON and ROOT columns are ** the last two columns in the table. Should this ever changes, be ** sure to update the xBestIndex method. */ _ = pzErr _ = argv _ = argc _ = pAux rc = Xsqlite3_declare_vtab(tls, db, __ccgo_ts+26886) if rc == SQLITE_OK { pNew = _sqlite3DbMallocZero(tls, db, uint64(40)) **(**uintptr)(__ccgo_up(ppVtab)) = pNew if pNew == uintptr(0) { return int32(SQLITE_NOMEM) } Xsqlite3_vtab_config(tls, db, int32(SQLITE_VTAB_INNOCUOUS), 0) (*TJsonEachConnection)(unsafe.Pointer(pNew)).Fdb = db if libc.Int32FromUint8(**(**uint8)(__ccgo_up(**(**uintptr)(__ccgo_up(argv)) + 4))) == int32('b') { v1 = int32(2) } else { v1 = int32(1) } (*TJsonEachConnection)(unsafe.Pointer(pNew)).FeMode = libc.Uint8FromInt32(v1) (*TJsonEachConnection)(unsafe.Pointer(pNew)).FbRecursive = libc.BoolUint8(libc.Int32FromUint8(**(**uint8)(__ccgo_up(**(**uintptr)(__ccgo_up(argv)) + uintptr(int32(4)+libc.Int32FromUint8((*TJsonEachConnection)(unsafe.Pointer(pNew)).FeMode))))) == int32('t')) } return rc } // C documentation // // /* Start a search on a new JSON string */ func _jsonEachFilter(tls *libc.TLS, cur uintptr, idxNum int32, idxStr uintptr, argc int32, argv uintptr) (r int32) { bp := tls.Alloc(16) defer tls.Free(16) var i, n, v1 Tu32 var p, zRoot uintptr var v2 int32 var _ /* sz at bp+0 */ Tu32 _, _, _, _, _, _ = i, n, p, zRoot, v1, v2 p = cur zRoot = uintptr(0) _ = idxStr _ = argc _jsonEachCursorReset(tls, p) if idxNum == 0 { return SQLITE_OK } libc.Xmemset(tls, p+192, 0, uint64(72)) (*TJsonEachCursor)(unsafe.Pointer(p)).FsParse.FnJPRef = uint32(1) (*TJsonEachCursor)(unsafe.Pointer(p)).FsParse.Fdb = (*TJsonEachCursor)(unsafe.Pointer(p)).Fdb if _jsonArgIsJsonb(tls, **(**uintptr)(__ccgo_up(argv)), p+192) != 0 { /* We have JSONB */ } else { (*TJsonEachCursor)(unsafe.Pointer(p)).FsParse.FzJson = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv))) (*TJsonEachCursor)(unsafe.Pointer(p)).FsParse.FnJson = Xsqlite3_value_bytes(tls, **(**uintptr)(__ccgo_up(argv))) if (*TJsonEachCursor)(unsafe.Pointer(p)).FsParse.FzJson == uintptr(0) { v1 = libc.Uint32FromInt32(0) (*TJsonEachCursor)(unsafe.Pointer(p)).FiEnd = v1 (*TJsonEachCursor)(unsafe.Pointer(p)).Fi = v1 return SQLITE_OK } if _jsonConvertTextToBlob(tls, p+192, uintptr(0)) != 0 { if (*TJsonEachCursor)(unsafe.Pointer(p)).FsParse.Foom != 0 { return int32(SQLITE_NOMEM) } goto json_each_malformed_input } } if idxNum == int32(3) { zRoot = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv + 1*8))) if zRoot == uintptr(0) { return SQLITE_OK } if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zRoot))) != int32('$') { Xsqlite3_free(tls, (*Tsqlite3_vtab)(unsafe.Pointer((*Tsqlite3_vtab_cursor)(unsafe.Pointer(cur)).FpVtab)).FzErrMsg) (*Tsqlite3_vtab)(unsafe.Pointer((*Tsqlite3_vtab_cursor)(unsafe.Pointer(cur)).FpVtab)).FzErrMsg = _jsonBadPathError(tls, uintptr(0), zRoot, 0) _jsonEachCursorReset(tls, p) if (*Tsqlite3_vtab)(unsafe.Pointer((*Tsqlite3_vtab_cursor)(unsafe.Pointer(cur)).FpVtab)).FzErrMsg != 0 { v2 = int32(SQLITE_ERROR) } else { v2 = int32(SQLITE_NOMEM) } return v2 } (*TJsonEachCursor)(unsafe.Pointer(p)).FnRoot = libc.Uint32FromInt32(_sqlite3Strlen30(tls, zRoot)) if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zRoot + 1))) == 0 { v1 = libc.Uint32FromInt32(0) (*TJsonEachCursor)(unsafe.Pointer(p)).Fi = v1 i = v1 (*TJsonEachCursor)(unsafe.Pointer(p)).FeType = uint8(0) } else { i = _jsonLookupStep(tls, p+192, uint32(0), zRoot+uintptr(1), uint32(0)) if i >= uint32(JSON_LOOKUP_PATHERROR) { if i == uint32(JSON_LOOKUP_NOTFOUND) { (*TJsonEachCursor)(unsafe.Pointer(p)).Fi = uint32(0) (*TJsonEachCursor)(unsafe.Pointer(p)).FeType = uint8(0) (*TJsonEachCursor)(unsafe.Pointer(p)).FiEnd = uint32(0) return SQLITE_OK } Xsqlite3_free(tls, (*Tsqlite3_vtab)(unsafe.Pointer((*Tsqlite3_vtab_cursor)(unsafe.Pointer(cur)).FpVtab)).FzErrMsg) (*Tsqlite3_vtab)(unsafe.Pointer((*Tsqlite3_vtab_cursor)(unsafe.Pointer(cur)).FpVtab)).FzErrMsg = _jsonBadPathError(tls, uintptr(0), zRoot, 0) _jsonEachCursorReset(tls, p) if (*Tsqlite3_vtab)(unsafe.Pointer((*Tsqlite3_vtab_cursor)(unsafe.Pointer(cur)).FpVtab)).FzErrMsg != 0 { v2 = int32(SQLITE_ERROR) } else { v2 = int32(SQLITE_NOMEM) } return v2 } if (*TJsonEachCursor)(unsafe.Pointer(p)).FsParse.FiLabel != 0 { (*TJsonEachCursor)(unsafe.Pointer(p)).Fi = (*TJsonEachCursor)(unsafe.Pointer(p)).FsParse.FiLabel (*TJsonEachCursor)(unsafe.Pointer(p)).FeType = uint8(JSONB_OBJECT) } else { (*TJsonEachCursor)(unsafe.Pointer(p)).Fi = i (*TJsonEachCursor)(unsafe.Pointer(p)).FeType = uint8(JSONB_ARRAY) } } _jsonAppendRaw(tls, p+56, zRoot, (*TJsonEachCursor)(unsafe.Pointer(p)).FnRoot) } else { v1 = libc.Uint32FromInt32(0) (*TJsonEachCursor)(unsafe.Pointer(p)).Fi = v1 i = v1 (*TJsonEachCursor)(unsafe.Pointer(p)).FeType = uint8(0) (*TJsonEachCursor)(unsafe.Pointer(p)).FnRoot = uint32(1) _jsonAppendRaw(tls, p+56, __ccgo_ts+26990, uint32(1)) } (*TJsonEachCursor)(unsafe.Pointer(p)).FnParent = uint32(0) n = _jsonbPayloadSize(tls, p+192, i, bp) (*TJsonEachCursor)(unsafe.Pointer(p)).FiEnd = i + n + **(**Tu32)(__ccgo_up(bp)) if libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TJsonEachCursor)(unsafe.Pointer(p)).FsParse.FaBlob + uintptr(i))))&int32(0x0f) >= int32(JSONB_ARRAY) && !((*TJsonEachCursor)(unsafe.Pointer(p)).FbRecursive != 0) { (*TJsonEachCursor)(unsafe.Pointer(p)).Fi = i + n (*TJsonEachCursor)(unsafe.Pointer(p)).FeType = libc.Uint8FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TJsonEachCursor)(unsafe.Pointer(p)).FsParse.FaBlob + uintptr(i)))) & int32(0x0f)) (*TJsonEachCursor)(unsafe.Pointer(p)).FaParent = _sqlite3DbMallocZero(tls, (*TJsonEachCursor)(unsafe.Pointer(p)).Fdb, uint64(24)) if (*TJsonEachCursor)(unsafe.Pointer(p)).FaParent == uintptr(0) { return int32(SQLITE_NOMEM) } (*TJsonEachCursor)(unsafe.Pointer(p)).FnParent = uint32(1) (*TJsonEachCursor)(unsafe.Pointer(p)).FnParentAlloc = uint32(1) (**(**TJsonParent)(__ccgo_up((*TJsonEachCursor)(unsafe.Pointer(p)).FaParent))).FiKey = 0 (**(**TJsonParent)(__ccgo_up((*TJsonEachCursor)(unsafe.Pointer(p)).FaParent))).FiEnd = (*TJsonEachCursor)(unsafe.Pointer(p)).FiEnd (**(**TJsonParent)(__ccgo_up((*TJsonEachCursor)(unsafe.Pointer(p)).FaParent))).FiHead = (*TJsonEachCursor)(unsafe.Pointer(p)).Fi (**(**TJsonParent)(__ccgo_up((*TJsonEachCursor)(unsafe.Pointer(p)).FaParent))).FiValue = i } return SQLITE_OK goto json_each_malformed_input json_each_malformed_input: ; Xsqlite3_free(tls, (*Tsqlite3_vtab)(unsafe.Pointer((*Tsqlite3_vtab_cursor)(unsafe.Pointer(cur)).FpVtab)).FzErrMsg) (*Tsqlite3_vtab)(unsafe.Pointer((*Tsqlite3_vtab_cursor)(unsafe.Pointer(cur)).FpVtab)).FzErrMsg = Xsqlite3_mprintf(tls, __ccgo_ts+26486, 0) _jsonEachCursorReset(tls, p) if (*Tsqlite3_vtab)(unsafe.Pointer((*Tsqlite3_vtab_cursor)(unsafe.Pointer(cur)).FpVtab)).FzErrMsg != 0 { v2 = int32(SQLITE_ERROR) } else { v2 = int32(SQLITE_NOMEM) } return v2 } // C documentation // // /* // ** json_extract(JSON, PATH, ...) // ** "->"(JSON,PATH) // ** "->>"(JSON,PATH) // ** // ** Return the element described by PATH. Return NULL if that PATH element // ** is not found. // ** // ** If JSON_JSON is set or if more that one PATH argument is supplied then // ** always return a JSON representation of the result. If JSON_SQL is set, // ** then always return an SQL representation of the result. If neither flag // ** is present and argc==2, then return JSON for objects and arrays and SQL // ** for all other values. // ** // ** When multiple PATH arguments are supplied, the result is a JSON array // ** containing the result of each PATH. // ** // ** Abbreviated JSON path expressions are allows if JSON_ABPATH, for // ** compatibility with PG. // */ func _jsonExtractFunc(tls *libc.TLS, ctx uintptr, argc int32, argv uintptr) { bp := tls.Alloc(144) defer tls.Free(144) var flags, i, nPath int32 var j Tu32 var p, zPath uintptr var _ /* jx at bp+0 */ TJsonString _, _, _, _, _, _ = flags, i, j, nPath, p, zPath p = uintptr(0) /* String for array result */ if argc < int32(2) { return } p = _jsonParseFuncArg(tls, ctx, **(**uintptr)(__ccgo_up(argv)), uint32(0)) if p == uintptr(0) { return } flags = int32(int64(Xsqlite3_user_data(tls, ctx))) _jsonStringInit(tls, bp, ctx) if argc > int32(2) { _jsonAppendChar(tls, bp, uint8('[')) } i = int32(1) for { if !(i < argc) { break } /* With a single PATH argument */ zPath = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv + uintptr(i)*8))) if zPath == uintptr(0) { goto json_extract_error } nPath = _sqlite3Strlen30(tls, zPath) if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zPath))) == int32('$') { j = _jsonLookupStep(tls, p, uint32(0), zPath+uintptr(1), uint32(0)) } else { if flags&int32(JSON_ABPATH) != 0 { /* The -> and ->> operators accept abbreviated PATH arguments. This ** is mostly for compatibility with PostgreSQL, but also for ** convenience. ** ** NUMBER ==> $[NUMBER] // PG compatible ** LABEL ==> $.LABEL // PG compatible ** [NUMBER] ==> $[NUMBER] // Not PG. Purely for convenience ** ** Updated 2024-05-27: If the NUMBER is negative, then PG counts from ** the right of the array. Hence for negative NUMBER: ** ** NUMBER ==> $[#NUMBER] // PG compatible */ _jsonStringInit(tls, bp, ctx) if Xsqlite3_value_type(tls, **(**uintptr)(__ccgo_up(argv + uintptr(i)*8))) == int32(SQLITE_INTEGER) { _jsonAppendRawNZ(tls, bp, __ccgo_ts+26698, uint32(1)) if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zPath))) == int32('-') { _jsonAppendRawNZ(tls, bp, __ccgo_ts+26700, uint32(1)) } _jsonAppendRaw(tls, bp, zPath, libc.Uint32FromInt32(nPath)) _jsonAppendRawNZ(tls, bp, __ccgo_ts+5340, uint32(2)) } else { if _jsonAllAlphanum(tls, zPath, nPath) != 0 { _jsonAppendRawNZ(tls, bp, __ccgo_ts+1743, uint32(1)) _jsonAppendRaw(tls, bp, zPath, libc.Uint32FromInt32(nPath)) } else { if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zPath))) == int32('[') && nPath >= int32(3) && libc.Int32FromUint8(**(**uint8)(__ccgo_up(zPath + uintptr(nPath-int32(1))))) == int32(']') { _jsonAppendRaw(tls, bp, zPath, libc.Uint32FromInt32(nPath)) } else { _jsonAppendRawNZ(tls, bp, __ccgo_ts+26702, uint32(2)) _jsonAppendRaw(tls, bp, zPath, libc.Uint32FromInt32(nPath)) _jsonAppendRawNZ(tls, bp, __ccgo_ts+26705, uint32(1)) } } } _jsonStringTerminate(tls, bp) j = _jsonLookupStep(tls, p, uint32(0), (**(**TJsonString)(__ccgo_up(bp))).FzBuf, uint32(0)) _jsonStringReset(tls, bp) } else { _jsonBadPathError(tls, ctx, zPath, 0) goto json_extract_error } } if j < (*TJsonParse)(unsafe.Pointer(p)).FnBlob { if argc == int32(2) { if flags&int32(JSON_JSON) != 0 { _jsonStringInit(tls, bp, ctx) _jsonTranslateBlobToText(tls, p, j, bp) _jsonReturnString(tls, bp, uintptr(0), uintptr(0)) _jsonStringReset(tls, bp) Xsqlite3_result_subtype(tls, ctx, uint32(JSON_SUBTYPE)) } else { _jsonReturnFromBlob(tls, p, j, ctx, 0) if flags&(libc.Int32FromInt32(JSON_SQL)|libc.Int32FromInt32(JSON_BLOB)) == 0 && libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TJsonParse)(unsafe.Pointer(p)).FaBlob + uintptr(j))))&int32(0x0f) >= int32(JSONB_ARRAY) { Xsqlite3_result_subtype(tls, ctx, uint32(JSON_SUBTYPE)) } } } else { _jsonAppendSeparator(tls, bp) _jsonTranslateBlobToText(tls, p, j, bp) } } else { if j == uint32(JSON_LOOKUP_NOTFOUND) { if argc == int32(2) { goto json_extract_error /* Return NULL if not found */ } else { _jsonAppendSeparator(tls, bp) _jsonAppendRawNZ(tls, bp, __ccgo_ts+1690, uint32(4)) } } else { _jsonBadPathError(tls, ctx, zPath, libc.Int32FromUint32(j)) goto json_extract_error } } goto _1 _1: ; i = i + 1 } if argc > int32(2) { _jsonAppendChar(tls, bp, uint8(']')) _jsonReturnString(tls, bp, uintptr(0), uintptr(0)) if flags&int32(JSON_BLOB) == 0 { Xsqlite3_result_subtype(tls, ctx, uint32(JSON_SUBTYPE)) } } goto json_extract_error json_extract_error: ; _jsonStringReset(tls, bp) _jsonParseFree(tls, p) return } /* ** Return codes for jsonMergePatch() */ // C documentation // // /* // ** pArg is a function argument that might be an SQL value or a JSON // ** value. Figure out what it is and encode it as a JSONB blob. // ** Return the results in pParse. // ** // ** pParse is uninitialized upon entry. This routine will handle the // ** initialization of pParse. The result will be contained in // ** pParse->aBlob and pParse->nBlob. pParse->aBlob might be dynamically // ** allocated (if pParse->nBlobAlloc is greater than zero) in which case // ** the caller is responsible for freeing the space allocated to pParse->aBlob // ** when it has finished with it. Or pParse->aBlob might be a static string // ** or a value obtained from sqlite3_value_blob(pArg). // ** // ** If the argument is a BLOB that is clearly not a JSONB, then this // ** function might set an error message in ctx and return non-zero. // ** It might also set an error message and return non-zero on an OOM error. // */ func _jsonFunctionArgToBlob(tls *libc.TLS, ctx uintptr, pArg uintptr, pParse uintptr) (r1 int32) { var eType, n, n1, nJson int32 var r float64 var z, z1, zJson uintptr _, _, _, _, _, _, _, _ = eType, n, n1, nJson, r, z, z1, zJson eType = Xsqlite3_value_type(tls, pArg) libc.Xmemset(tls, pParse, 0, uint64(72)) (*TJsonParse)(unsafe.Pointer(pParse)).Fdb = Xsqlite3_context_db_handle(tls, ctx) switch eType { default: (*TJsonParse)(unsafe.Pointer(pParse)).FaBlob = uintptr(unsafe.Pointer(&_aNull)) (*TJsonParse)(unsafe.Pointer(pParse)).FnBlob = uint32(1) return 0 case int32(SQLITE_BLOB): if !(_jsonArgIsJsonb(tls, pArg, pParse) != 0) { Xsqlite3_result_error(tls, ctx, __ccgo_ts+26457, -int32(1)) return int32(1) } case int32(SQLITE_TEXT): zJson = Xsqlite3_value_text(tls, pArg) nJson = Xsqlite3_value_bytes(tls, pArg) if zJson == uintptr(0) { return int32(1) } if Xsqlite3_value_subtype(tls, pArg) == uint32(JSON_SUBTYPE) { (*TJsonParse)(unsafe.Pointer(pParse)).FzJson = zJson (*TJsonParse)(unsafe.Pointer(pParse)).FnJson = nJson if _jsonConvertTextToBlob(tls, pParse, ctx) != 0 { Xsqlite3_result_error(tls, ctx, __ccgo_ts+26486, -int32(1)) _sqlite3DbFree(tls, (*TJsonParse)(unsafe.Pointer(pParse)).Fdb, (*TJsonParse)(unsafe.Pointer(pParse)).FaBlob) libc.Xmemset(tls, pParse, 0, uint64(72)) return int32(1) } } else { _jsonBlobAppendNode(tls, pParse, uint8(JSONB_TEXTRAW), libc.Uint64FromInt32(nJson), zJson) } case int32(SQLITE_FLOAT): r = Xsqlite3_value_double(tls, pArg) if _sqlite3IsNaN(tls, r) != 0 { _jsonBlobAppendNode(tls, pParse, uint8(JSONB_NULL), uint64(0), uintptr(0)) } else { n = Xsqlite3_value_bytes(tls, pArg) z = Xsqlite3_value_text(tls, pArg) if z == uintptr(0) { return int32(1) } if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z))) == int32('I') { _jsonBlobAppendNode(tls, pParse, uint8(JSONB_FLOAT), uint64(5), __ccgo_ts+26591) } else { if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z))) == int32('-') && libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + 1))) == int32('I') { _jsonBlobAppendNode(tls, pParse, uint8(JSONB_FLOAT), uint64(6), __ccgo_ts+26584) } else { _jsonBlobAppendNode(tls, pParse, uint8(JSONB_FLOAT), libc.Uint64FromInt32(n), z) } } } case int32(SQLITE_INTEGER): n1 = Xsqlite3_value_bytes(tls, pArg) z1 = Xsqlite3_value_text(tls, pArg) if z1 == uintptr(0) { return int32(1) } _jsonBlobAppendNode(tls, pParse, uint8(JSONB_INT), libc.Uint64FromInt32(n1), z1) break } if (*TJsonParse)(unsafe.Pointer(pParse)).Foom != 0 { Xsqlite3_result_error_nomem(tls, ctx) return int32(1) } else { return 0 } return r1 } // C documentation // // /* // ** Search along zPath to find the Json element specified. Return an // ** index into pParse->aBlob[] for the start of that element's value. // ** // ** If the value found by this routine is the value half of label/value pair // ** within an object, then set pPath->iLabel to the start of the corresponding // ** label, before returning. // ** // ** Return one of the JSON_LOOKUP error codes if problems are seen. // ** // ** This routine will also modify the blob. If pParse->eEdit is one of // ** JEDIT_DEL, JEDIT_REPL, JEDIT_INS, JEDIT_SET, or JEDIT_AINS, then changes // ** might be made to the selected value. If an edit is performed, then the // ** return value does not necessarily point to the select element. If an edit // ** is performed, the return value is only useful for detecting error // ** conditions. // */ func _jsonLookupStep(tls *libc.TLS, pParse uintptr, iRoot Tu32, zPath uintptr, iLabel Tu32) (r Tu32) { bp := tls.Alloc(224) defer tls.Free(224) var i, iEnd, j, k, n, nIns, nKey, rc, v Tu32 var kk, nn Tu64 var rawKey, rawLabel, v5 int32 var x Tu8 var zKey, zLabel, v4 uintptr var v3 Tu16 var _ /* ix at bp+80 */ TJsonParse var _ /* sz at bp+0 */ Tu32 var _ /* v at bp+152 */ TJsonParse var _ /* v at bp+8 */ TJsonParse _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = i, iEnd, j, k, kk, n, nIns, nKey, nn, rawKey, rawLabel, rc, v, x, zKey, zLabel, v3, v4, v5 if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zPath))) == 0 { if (*TJsonParse)(unsafe.Pointer(pParse)).FeEdit != 0 && _jsonBlobMakeEditable(tls, pParse, (*TJsonParse)(unsafe.Pointer(pParse)).FnIns) != 0 { n = _jsonbPayloadSize(tls, pParse, iRoot, bp) **(**Tu32)(__ccgo_up(bp)) = **(**Tu32)(__ccgo_up(bp)) + n if libc.Int32FromUint8((*TJsonParse)(unsafe.Pointer(pParse)).FeEdit) == int32(JEDIT_DEL) { if iLabel > uint32(0) { **(**Tu32)(__ccgo_up(bp)) = **(**Tu32)(__ccgo_up(bp)) + (iRoot - iLabel) iRoot = iLabel } _jsonBlobEdit(tls, pParse, iRoot, **(**Tu32)(__ccgo_up(bp)), uintptr(0), uint32(0)) } else { if libc.Int32FromUint8((*TJsonParse)(unsafe.Pointer(pParse)).FeEdit) == int32(JEDIT_INS) { /* Already exists, so json_insert() is a no-op */ } else { if libc.Int32FromUint8((*TJsonParse)(unsafe.Pointer(pParse)).FeEdit) == int32(JEDIT_AINS) { /* json_array_insert() */ if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zPath + uintptr(-libc.Int32FromInt32(1))))) != int32(']') { return uint32(JSON_LOOKUP_NOTARRAY) } else { _jsonBlobEdit(tls, pParse, iRoot, uint32(0), (*TJsonParse)(unsafe.Pointer(pParse)).FaIns, (*TJsonParse)(unsafe.Pointer(pParse)).FnIns) } } else { /* json_set() or json_replace() */ _jsonBlobEdit(tls, pParse, iRoot, **(**Tu32)(__ccgo_up(bp)), (*TJsonParse)(unsafe.Pointer(pParse)).FaIns, (*TJsonParse)(unsafe.Pointer(pParse)).FnIns) } } } } (*TJsonParse)(unsafe.Pointer(pParse)).FiLabel = iLabel return iRoot } if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zPath))) == int32('.') { rawKey = int32(1) x = **(**Tu8)(__ccgo_up((*TJsonParse)(unsafe.Pointer(pParse)).FaBlob + uintptr(iRoot))) zPath = zPath + 1 if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zPath))) == int32('"') { zKey = zPath + uintptr(1) i = uint32(1) for { if !(**(**uint8)(__ccgo_up(zPath + uintptr(i))) != 0 && libc.Int32FromUint8(**(**uint8)(__ccgo_up(zPath + uintptr(i)))) != int32('"')) { break } if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zPath + uintptr(i)))) == int32('\\') && libc.Int32FromUint8(**(**uint8)(__ccgo_up(zPath + uintptr(i+uint32(1))))) != 0 { i = i + 1 } goto _1 _1: ; i = i + 1 } nKey = i - uint32(1) if **(**uint8)(__ccgo_up(zPath + uintptr(i))) != 0 { i = i + 1 } else { return uint32(JSON_LOOKUP_PATHERROR) } rawKey = libc.BoolInt32(libc.Xmemchr(tls, zKey, int32('\\'), uint64(nKey)) == uintptr(0)) } else { zKey = zPath i = uint32(0) for { if !(**(**uint8)(__ccgo_up(zPath + uintptr(i))) != 0 && libc.Int32FromUint8(**(**uint8)(__ccgo_up(zPath + uintptr(i)))) != int32('.') && libc.Int32FromUint8(**(**uint8)(__ccgo_up(zPath + uintptr(i)))) != int32('[')) { break } goto _2 _2: ; i = i + 1 } nKey = i if nKey == uint32(0) { return uint32(JSON_LOOKUP_PATHERROR) } } if libc.Int32FromUint8(x)&int32(0x0f) != int32(JSONB_OBJECT) { return uint32(JSON_LOOKUP_NOTFOUND) } n = _jsonbPayloadSize(tls, pParse, iRoot, bp) j = iRoot + n /* j is the index of a label */ iEnd = j + **(**Tu32)(__ccgo_up(bp)) for j < iEnd { x = libc.Uint8FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TJsonParse)(unsafe.Pointer(pParse)).FaBlob + uintptr(j)))) & int32(0x0f)) if libc.Int32FromUint8(x) < int32(JSONB_TEXT) || libc.Int32FromUint8(x) > int32(JSONB_TEXTRAW) { return uint32(JSON_LOOKUP_ERROR) } n = _jsonbPayloadSize(tls, pParse, j, bp) if n == uint32(0) { return uint32(JSON_LOOKUP_ERROR) } k = j + n /* k is the index of the label text */ if k+**(**Tu32)(__ccgo_up(bp)) >= iEnd { return uint32(JSON_LOOKUP_ERROR) } zLabel = (*TJsonParse)(unsafe.Pointer(pParse)).FaBlob + uintptr(k) rawLabel = libc.BoolInt32(libc.Int32FromUint8(x) == int32(JSONB_TEXT) || libc.Int32FromUint8(x) == int32(JSONB_TEXTRAW)) if _jsonLabelCompare(tls, zKey, nKey, rawKey, zLabel, **(**Tu32)(__ccgo_up(bp)), rawLabel) != 0 { v = k + **(**Tu32)(__ccgo_up(bp)) /* v is the index of the value */ if libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TJsonParse)(unsafe.Pointer(pParse)).FaBlob + uintptr(v))))&int32(0x0f) > int32(JSONB_OBJECT) { return uint32(JSON_LOOKUP_ERROR) } n = _jsonbPayloadSize(tls, pParse, v, bp) if n == uint32(0) || v+n+**(**Tu32)(__ccgo_up(bp)) > iEnd { return uint32(JSON_LOOKUP_ERROR) } v4 = pParse + 44 *(*Tu16)(unsafe.Pointer(v4)) = *(*Tu16)(unsafe.Pointer(v4)) + 1 v3 = *(*Tu16)(unsafe.Pointer(v4)) if libc.Int32FromUint16(v3) >= int32(JSON_MAX_DEPTH) { return uint32(JSON_LOOKUP_TOODEEP) } rc = _jsonLookupStep(tls, pParse, v, zPath+uintptr(i), j) (*TJsonParse)(unsafe.Pointer(pParse)).FiDepth = (*TJsonParse)(unsafe.Pointer(pParse)).FiDepth - 1 if (*TJsonParse)(unsafe.Pointer(pParse)).Fdelta != 0 { _jsonAfterEditSizeAdjust(tls, pParse, iRoot) } return rc } j = k + **(**Tu32)(__ccgo_up(bp)) if libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TJsonParse)(unsafe.Pointer(pParse)).FaBlob + uintptr(j))))&int32(0x0f) > int32(JSONB_OBJECT) { return uint32(JSON_LOOKUP_ERROR) } n = _jsonbPayloadSize(tls, pParse, j, bp) if n == uint32(0) { return uint32(JSON_LOOKUP_ERROR) } j = j + (n + **(**Tu32)(__ccgo_up(bp))) } if j > iEnd { return uint32(JSON_LOOKUP_ERROR) } if libc.Int32FromUint8((*TJsonParse)(unsafe.Pointer(pParse)).FeEdit) >= int32(JEDIT_INS) { /* Header of the label to be inserted */ if libc.Int32FromUint8((*TJsonParse)(unsafe.Pointer(pParse)).FeEdit) == int32(JEDIT_AINS) && Xsqlite3_strglob(tls, __ccgo_ts+26631, zPath+uintptr(i)) != 0 { return uint32(JSON_LOOKUP_NOTARRAY) } libc.Xmemset(tls, bp+80, 0, uint64(72)) (**(**TJsonParse)(__ccgo_up(bp + 80))).Fdb = (*TJsonParse)(unsafe.Pointer(pParse)).Fdb if rawKey != 0 { v5 = int32(JSONB_TEXTRAW) } else { v5 = int32(JSONB_TEXT5) } _jsonBlobAppendNode(tls, bp+80, libc.Uint8FromInt32(v5), uint64(nKey), uintptr(0)) v4 = pParse + 47 *(*Tu8)(unsafe.Pointer(v4)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v4))) | libc.Int32FromUint8((**(**TJsonParse)(__ccgo_up(bp + 80))).Foom)) rc = _jsonCreateEditSubstructure(tls, pParse, bp+8, zPath+uintptr(i)) if !(rc >= libc.Uint32FromUint32(JSON_LOOKUP_PATHERROR)) && _jsonBlobMakeEditable(tls, pParse, (**(**TJsonParse)(__ccgo_up(bp + 80))).FnBlob+nKey+(**(**TJsonParse)(__ccgo_up(bp + 8))).FnBlob) != 0 { nIns = (**(**TJsonParse)(__ccgo_up(bp + 80))).FnBlob + nKey + (**(**TJsonParse)(__ccgo_up(bp + 8))).FnBlob _jsonBlobEdit(tls, pParse, j, uint32(0), uintptr(0), nIns) if !((*TJsonParse)(unsafe.Pointer(pParse)).Foom != 0) { /* Because pParse->oom!=0 */ /* Because pPasre->oom!=0 */ libc.Xmemcpy(tls, (*TJsonParse)(unsafe.Pointer(pParse)).FaBlob+uintptr(j), (**(**TJsonParse)(__ccgo_up(bp + 80))).FaBlob, uint64((**(**TJsonParse)(__ccgo_up(bp + 80))).FnBlob)) k = j + (**(**TJsonParse)(__ccgo_up(bp + 80))).FnBlob libc.Xmemcpy(tls, (*TJsonParse)(unsafe.Pointer(pParse)).FaBlob+uintptr(k), zKey, uint64(nKey)) k = k + nKey libc.Xmemcpy(tls, (*TJsonParse)(unsafe.Pointer(pParse)).FaBlob+uintptr(k), (**(**TJsonParse)(__ccgo_up(bp + 8))).FaBlob, uint64((**(**TJsonParse)(__ccgo_up(bp + 8))).FnBlob)) if (*TJsonParse)(unsafe.Pointer(pParse)).Fdelta != 0 { _jsonAfterEditSizeAdjust(tls, pParse, iRoot) } } } _jsonParseReset(tls, bp+8) _jsonParseReset(tls, bp+80) return rc } } else { if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zPath))) == int32('[') { kk = uint64(0) x = libc.Uint8FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TJsonParse)(unsafe.Pointer(pParse)).FaBlob + uintptr(iRoot)))) & int32(0x0f)) if libc.Int32FromUint8(x) != int32(JSONB_ARRAY) { return uint32(JSON_LOOKUP_NOTFOUND) } n = _jsonbPayloadSize(tls, pParse, iRoot, bp) i = uint32(1) for libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(zPath + uintptr(i))))])&int32(0x04) != 0 { if kk < uint64(0xffffffff) { kk = kk*uint64(10) + uint64(**(**uint8)(__ccgo_up(zPath + uintptr(i)))) - uint64('0') } /* ^^^^^^^^^^--- Allow kk to be bigger than any JSON array so that ** we get NOTFOUND instead of PATHERROR, without overflowing kk. */ i = i + 1 } if i < uint32(2) || libc.Int32FromUint8(**(**uint8)(__ccgo_up(zPath + uintptr(i)))) != int32(']') { if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zPath + 1))) == int32('#') { kk = uint64(_jsonbArrayCount(tls, pParse, iRoot)) i = uint32(2) if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zPath + 2))) == int32('-') && libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(zPath + 3)))])&int32(0x04) != 0 { nn = uint64(0) i = uint32(3) for cond := true; cond; cond = libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(zPath + uintptr(i))))])&int32(0x04) != 0 { if nn < uint64(0xffffffff) { nn = nn*uint64(10) + uint64(**(**uint8)(__ccgo_up(zPath + uintptr(i)))) - uint64('0') } /* ^^^^^^^^^^--- Allow nn to be bigger than any JSON array to ** get NOTFOUND instead of PATHERROR, without overflowing nn. */ i = i + 1 } if nn > kk { return uint32(JSON_LOOKUP_NOTFOUND) } kk = kk - nn } if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zPath + uintptr(i)))) != int32(']') { return uint32(JSON_LOOKUP_PATHERROR) } } else { return uint32(JSON_LOOKUP_PATHERROR) } } j = iRoot + n iEnd = j + **(**Tu32)(__ccgo_up(bp)) for j < iEnd { if kk == uint64(0) { v4 = pParse + 44 *(*Tu16)(unsafe.Pointer(v4)) = *(*Tu16)(unsafe.Pointer(v4)) + 1 v3 = *(*Tu16)(unsafe.Pointer(v4)) if libc.Int32FromUint16(v3) >= int32(JSON_MAX_DEPTH) { return uint32(JSON_LOOKUP_TOODEEP) } rc = _jsonLookupStep(tls, pParse, j, zPath+uintptr(i+uint32(1)), uint32(0)) (*TJsonParse)(unsafe.Pointer(pParse)).FiDepth = (*TJsonParse)(unsafe.Pointer(pParse)).FiDepth - 1 if (*TJsonParse)(unsafe.Pointer(pParse)).Fdelta != 0 { _jsonAfterEditSizeAdjust(tls, pParse, iRoot) } return rc } kk = kk - 1 n = _jsonbPayloadSize(tls, pParse, j, bp) if n == uint32(0) { return uint32(JSON_LOOKUP_ERROR) } j = j + (n + **(**Tu32)(__ccgo_up(bp))) } if j > iEnd { return uint32(JSON_LOOKUP_ERROR) } if kk > uint64(0) { return uint32(JSON_LOOKUP_NOTFOUND) } if libc.Int32FromUint8((*TJsonParse)(unsafe.Pointer(pParse)).FeEdit) >= int32(JEDIT_INS) { rc = _jsonCreateEditSubstructure(tls, pParse, bp+152, zPath+uintptr(i+uint32(1))) if !(rc >= libc.Uint32FromUint32(JSON_LOOKUP_PATHERROR)) && _jsonBlobMakeEditable(tls, pParse, (**(**TJsonParse)(__ccgo_up(bp + 152))).FnBlob) != 0 { _jsonBlobEdit(tls, pParse, j, uint32(0), (**(**TJsonParse)(__ccgo_up(bp + 152))).FaBlob, (**(**TJsonParse)(__ccgo_up(bp + 152))).FnBlob) } _jsonParseReset(tls, bp+152) if (*TJsonParse)(unsafe.Pointer(pParse)).Fdelta != 0 { _jsonAfterEditSizeAdjust(tls, pParse, iRoot) } return rc } } else { return uint32(JSON_LOOKUP_PATHERROR) } } return uint32(JSON_LOOKUP_NOTFOUND) } func _jsonObjectCompute(tls *libc.TLS, ctx uintptr, isFinal int32) { bp := tls.Alloc(144) defer tls.Free(144) var c uint8 var flags, inStr int32 var i, j, v2, v3 Tu64 var pOgStr, pStr uintptr var v8 Tsqlite3_destructor_type var _ /* tmpStr at bp+0 */ TJsonString _, _, _, _, _, _, _, _, _, _ = c, flags, i, inStr, j, pOgStr, pStr, v2, v3, v8 flags = int32(int64(Xsqlite3_user_data(tls, ctx))) pStr = Xsqlite3_aggregate_context(tls, ctx, 0) if pStr != 0 { pOgStr = pStr _jsonAppendRawNZ(tls, pOgStr, __ccgo_ts+26881, uint32(2)) /* Ensure it is zero-terminated */ _jsonStringTrimOneChar(tls, pOgStr) /* Remove the zero terminator */ (*TJsonString)(unsafe.Pointer(pStr)).FpCtx = ctx if (*TJsonString)(unsafe.Pointer(pStr)).FeErr != 0 { _jsonReturnString(tls, pStr, uintptr(0), uintptr(0)) return } if libc.Int32FromUint8(**(**uint8)(__ccgo_up((*TJsonString)(unsafe.Pointer(pStr)).FzBuf))) != int32('{') { inStr = 0 if !(isFinal != 0) { /* Work with a temporary copy of the string if this is not the ** final result */ _jsonStringInit(tls, bp, ctx) _jsonAppendRawNZ(tls, bp, (*TJsonString)(unsafe.Pointer(pStr)).FzBuf, uint32((*TJsonString)(unsafe.Pointer(pStr)).FnUsed+uint64(1))) pStr = bp if (*TJsonString)(unsafe.Pointer(pStr)).FeErr != 0 { _jsonReturnString(tls, pStr, uintptr(0), uintptr(0)) return } _jsonStringTrimOneChar(tls, pStr) /* Remove zero terminator */ } /* Fix up the string by changing the initial "@" flag back to ** to "{" and removing all subsequence "@" entries, with their ** associated comma delimeters. */ **(**uint8)(__ccgo_up((*TJsonString)(unsafe.Pointer(pStr)).FzBuf)) = uint8('{') v2 = libc.Uint64FromInt32(1) j = v2 i = v2 for { if !(i < (*TJsonString)(unsafe.Pointer(pStr)).FnUsed) { break } c = **(**uint8)(__ccgo_up((*TJsonString)(unsafe.Pointer(pStr)).FzBuf + uintptr(i))) if libc.Int32FromUint8(c) == int32('"') { inStr = libc.BoolInt32(!(inStr != 0)) v2 = j j = j + 1 **(**uint8)(__ccgo_up((*TJsonString)(unsafe.Pointer(pStr)).FzBuf + uintptr(v2))) = uint8('"') } else { if libc.Int32FromUint8(c) == int32('\\') { v2 = j j = j + 1 **(**uint8)(__ccgo_up((*TJsonString)(unsafe.Pointer(pStr)).FzBuf + uintptr(v2))) = uint8('\\') v2 = j j = j + 1 i = i + 1 v3 = i **(**uint8)(__ccgo_up((*TJsonString)(unsafe.Pointer(pStr)).FzBuf + uintptr(v2))) = **(**uint8)(__ccgo_up((*TJsonString)(unsafe.Pointer(pStr)).FzBuf + uintptr(v3))) } else { if libc.Int32FromUint8(c) == int32('@') && !(inStr != 0) { if libc.Int32FromUint8(**(**uint8)(__ccgo_up((*TJsonString)(unsafe.Pointer(pStr)).FzBuf + uintptr(i+uint64(1))))) == int32(',') { i = i + 1 } else { if libc.Int32FromUint8(**(**uint8)(__ccgo_up((*TJsonString)(unsafe.Pointer(pStr)).FzBuf + uintptr(j-uint64(1))))) == int32(',') { j = j - 1 } } } else { v2 = j j = j + 1 **(**uint8)(__ccgo_up((*TJsonString)(unsafe.Pointer(pStr)).FzBuf + uintptr(v2))) = c } } } goto _1 _1: ; i = i + 1 } **(**uint8)(__ccgo_up((*TJsonString)(unsafe.Pointer(pStr)).FzBuf + uintptr(j))) = uint8(0) /* Restore zero terminator */ (*TJsonString)(unsafe.Pointer(pStr)).FnUsed = j /* Truncate the string */ } if flags&int32(JSON_BLOB) != 0 { _jsonReturnStringAsBlob(tls, pStr) if isFinal != 0 { if !((*TJsonString)(unsafe.Pointer(pStr)).FbStatic != 0) { _sqlite3RCStrUnref(tls, (*TJsonString)(unsafe.Pointer(pStr)).FzBuf) } } else { _jsonStringTrimOneChar(tls, pOgStr) } } else { if isFinal != 0 { if (*TJsonString)(unsafe.Pointer(pStr)).FbStatic != 0 { v8 = uintptr(-libc.Int32FromInt32(1)) } else { v8 = __ccgo_fp(_sqlite3RCStrUnref) } Xsqlite3_result_text(tls, ctx, (*TJsonString)(unsafe.Pointer(pStr)).FzBuf, libc.Int32FromUint64((*TJsonString)(unsafe.Pointer(pStr)).FnUsed), v8) (*TJsonString)(unsafe.Pointer(pStr)).FbStatic = uint8(1) } else { Xsqlite3_result_text(tls, ctx, (*TJsonString)(unsafe.Pointer(pStr)).FzBuf, libc.Int32FromUint64((*TJsonString)(unsafe.Pointer(pStr)).FnUsed), uintptr(-libc.Int32FromInt32(1))) _jsonStringTrimOneChar(tls, pOgStr) } } if pStr != pOgStr { _jsonStringReset(tls, pStr) } } else { if flags&int32(JSON_BLOB) != 0 { Xsqlite3_result_blob(tls, ctx, uintptr(unsafe.Pointer(&_emptyObject1)), int32(1), libc.UintptrFromInt32(0)) } else { Xsqlite3_result_text(tls, ctx, __ccgo_ts+26883, int32(2), libc.UintptrFromInt32(0)) } } Xsqlite3_result_subtype(tls, ctx, uint32(JSON_SUBTYPE)) } // C documentation // // /* // ** Implementation of the json_object(NAME,VALUE,...) function. Return a JSON // ** object that contains all name/value given in arguments. Or if any name // ** is not a string or if any value is a BLOB, throw an error. // */ func _jsonObjectFunc(tls *libc.TLS, ctx uintptr, argc int32, argv uintptr) { bp := tls.Alloc(144) defer tls.Free(144) var i int32 var n Tu32 var z uintptr var _ /* jx at bp+0 */ TJsonString _, _, _ = i, n, z if argc&int32(1) != 0 { Xsqlite3_result_error(tls, ctx, __ccgo_ts+26707, -int32(1)) return } _jsonStringInit(tls, bp, ctx) _jsonAppendChar(tls, bp, uint8('{')) i = 0 for { if !(i < argc) { break } if Xsqlite3_value_type(tls, **(**uintptr)(__ccgo_up(argv + uintptr(i)*8))) != int32(SQLITE_TEXT) { Xsqlite3_result_error(tls, ctx, __ccgo_ts+26758, -int32(1)) _jsonStringReset(tls, bp) return } _jsonAppendSeparator(tls, bp) z = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv + uintptr(i)*8))) n = libc.Uint32FromInt32(Xsqlite3_value_bytes(tls, **(**uintptr)(__ccgo_up(argv + uintptr(i)*8)))) _jsonAppendString(tls, bp, z, n) _jsonAppendChar(tls, bp, uint8(':')) _jsonAppendSqlValue(tls, bp, **(**uintptr)(__ccgo_up(argv + uintptr(i+int32(1))*8))) goto _1 _1: ; i = i + int32(2) } _jsonAppendChar(tls, bp, uint8('}')) _jsonReturnString(tls, bp, uintptr(0), uintptr(0)) Xsqlite3_result_subtype(tls, ctx, uint32(JSON_SUBTYPE)) } // C documentation // // /* // ** json_group_obj(NAME,VALUE) // ** // ** Return a JSON object composed of all names and values in the aggregate. // ** // ** Rows for which NAME is NULL do not result in a new entry. However, we // ** do initially insert a "@" entry into the growing string for each null entry // ** and change the first character of the string to "@" to signal that the // ** string contains null entries. The "@" markers are needed in order to // ** correctly process xInverse() requests. The initial "@" is converted // ** back into "{" and the "@" null values are removed by jsonObjectCompute(). // */ func _jsonObjectStep(tls *libc.TLS, ctx uintptr, argc int32, argv uintptr) { var n Tu32 var pStr, z uintptr _, _, _ = n, pStr, z _ = argc pStr = Xsqlite3_aggregate_context(tls, ctx, int32(136)) if pStr != 0 { z = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv))) n = libc.Uint32FromInt32(_sqlite3Strlen30(tls, z)) if (*TJsonString)(unsafe.Pointer(pStr)).FzBuf == uintptr(0) { _jsonStringInit(tls, pStr, ctx) _jsonAppendChar(tls, pStr, uint8('{')) } else { if (*TJsonString)(unsafe.Pointer(pStr)).FnUsed > uint64(1) { _jsonAppendChar(tls, pStr, uint8(',')) } } (*TJsonString)(unsafe.Pointer(pStr)).FpCtx = ctx if z != uintptr(0) { _jsonAppendString(tls, pStr, z, n) _jsonAppendChar(tls, pStr, uint8(':')) _jsonAppendSqlValue(tls, pStr, **(**uintptr)(__ccgo_up(argv + 1*8))) } else { **(**uint8)(__ccgo_up((*TJsonString)(unsafe.Pointer(pStr)).FzBuf)) = uint8('@') _jsonAppendRawNZ(tls, pStr, __ccgo_ts+26696, uint32(1)) } } } // C documentation // // /* // ** Generate a JsonParse object, containing valid JSONB in aBlob and nBlob, // ** from the SQL function argument pArg. Return a pointer to the new // ** JsonParse object. // ** // ** Ownership of the new JsonParse object is passed to the caller. The // ** caller should invoke jsonParseFree() on the return value when it // ** has finished using it. // ** // ** If any errors are detected, an appropriate error messages is set // ** using sqlite3_result_error() or the equivalent and this routine // ** returns NULL. This routine also returns NULL if the pArg argument // ** is an SQL NULL value, but no error message is set in that case. This // ** is so that SQL functions that are given NULL arguments will return // ** a NULL value. // */ func _jsonParseFuncArg(tls *libc.TLS, ctx uintptr, pArg uintptr, flgs Tu32) (r uintptr) { var db, p, pFromCache, zNew, v2 uintptr var eType, isRCStr, rc int32 var nBlob, v1 Tu32 _, _, _, _, _, _, _, _, _, _ = db, eType, isRCStr, nBlob, p, pFromCache, rc, zNew, v1, v2 /* Datatype of pArg */ p = uintptr(0) /* Value to be returned */ pFromCache = uintptr(0) /* The database connection */ eType = Xsqlite3_value_type(tls, pArg) if eType == int32(SQLITE_NULL) { return uintptr(0) } pFromCache = _jsonCacheSearch(tls, ctx, pArg) if pFromCache != 0 { (*TJsonParse)(unsafe.Pointer(pFromCache)).FnJPRef = (*TJsonParse)(unsafe.Pointer(pFromCache)).FnJPRef + 1 if flgs&uint32(JSON_EDITABLE) == uint32(0) { return pFromCache } } db = Xsqlite3_context_db_handle(tls, ctx) goto rebuild_from_cache rebuild_from_cache: ; p = _sqlite3DbMallocZero(tls, db, uint64(72)) if p == uintptr(0) { goto json_pfa_oom } libc.Xmemset(tls, p, 0, uint64(72)) (*TJsonParse)(unsafe.Pointer(p)).Fdb = db (*TJsonParse)(unsafe.Pointer(p)).FnJPRef = uint32(1) if pFromCache != uintptr(0) { nBlob = (*TJsonParse)(unsafe.Pointer(pFromCache)).FnBlob (*TJsonParse)(unsafe.Pointer(p)).FaBlob = _sqlite3DbMallocRaw(tls, db, uint64(nBlob)) if (*TJsonParse)(unsafe.Pointer(p)).FaBlob == uintptr(0) { goto json_pfa_oom } libc.Xmemcpy(tls, (*TJsonParse)(unsafe.Pointer(p)).FaBlob, (*TJsonParse)(unsafe.Pointer(pFromCache)).FaBlob, uint64(nBlob)) v1 = nBlob (*TJsonParse)(unsafe.Pointer(p)).FnBlob = v1 (*TJsonParse)(unsafe.Pointer(p)).FnBlobAlloc = v1 (*TJsonParse)(unsafe.Pointer(p)).FhasNonstd = (*TJsonParse)(unsafe.Pointer(pFromCache)).FhasNonstd _jsonParseFree(tls, pFromCache) return p } if eType == int32(SQLITE_BLOB) { if _jsonArgIsJsonb(tls, pArg, p) != 0 { if flgs&uint32(JSON_EDITABLE) != uint32(0) && _jsonBlobMakeEditable(tls, p, uint32(0)) == 0 { goto json_pfa_oom } return p } /* If the blob is not valid JSONB, fall through into trying to cast ** the blob into text which is then interpreted as JSON. (tag-20240123-a) ** ** This goes against all historical documentation about how the SQLite ** JSON functions were suppose to work. From the beginning, blob was ** reserved for expansion and a blob value should have raised an error. ** But it did not, due to a bug. And many applications came to depend ** upon this buggy behavior, especially when using the CLI and reading ** JSON text using readfile(), which returns a blob. For this reason ** we will continue to support the bug moving forward. ** See for example https://sqlite.org/forum/forumpost/012136abd5292b8d */ } (*TJsonParse)(unsafe.Pointer(p)).FzJson = Xsqlite3_value_text(tls, pArg) (*TJsonParse)(unsafe.Pointer(p)).FnJson = Xsqlite3_value_bytes(tls, pArg) if (*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0 { goto json_pfa_oom } if (*TJsonParse)(unsafe.Pointer(p)).FnJson == 0 { goto json_pfa_malformed } if flgs&uint32(JSON_KEEPERROR) != 0 { v2 = uintptr(0) } else { v2 = ctx } if _jsonConvertTextToBlob(tls, p, v2) != 0 { if flgs&uint32(JSON_KEEPERROR) != 0 { (*TJsonParse)(unsafe.Pointer(p)).FnErr = uint8(1) return p } else { _jsonParseFree(tls, p) return uintptr(0) } } else { isRCStr = _sqlite3ValueIsOfClass(tls, pArg, __ccgo_fp(_sqlite3RCStrUnref)) if !(isRCStr != 0) { zNew = _sqlite3RCStrNew(tls, libc.Uint64FromInt32((*TJsonParse)(unsafe.Pointer(p)).FnJson)) if zNew == uintptr(0) { goto json_pfa_oom } libc.Xmemcpy(tls, zNew, (*TJsonParse)(unsafe.Pointer(p)).FzJson, libc.Uint64FromInt32((*TJsonParse)(unsafe.Pointer(p)).FnJson)) (*TJsonParse)(unsafe.Pointer(p)).FzJson = zNew **(**uint8)(__ccgo_up((*TJsonParse)(unsafe.Pointer(p)).FzJson + uintptr((*TJsonParse)(unsafe.Pointer(p)).FnJson))) = uint8(0) } else { _sqlite3RCStrRef(tls, (*TJsonParse)(unsafe.Pointer(p)).FzJson) } (*TJsonParse)(unsafe.Pointer(p)).FbJsonIsRCStr = uint8(1) rc = _jsonCacheInsert(tls, ctx, p) if rc == int32(SQLITE_NOMEM) { goto json_pfa_oom } if flgs&uint32(JSON_EDITABLE) != 0 { pFromCache = p p = uintptr(0) goto rebuild_from_cache } } return p goto json_pfa_malformed json_pfa_malformed: ; if flgs&uint32(JSON_KEEPERROR) != 0 { (*TJsonParse)(unsafe.Pointer(p)).FnErr = uint8(1) return p } else { _jsonParseFree(tls, p) Xsqlite3_result_error(tls, ctx, __ccgo_ts+26486, -int32(1)) return uintptr(0) } goto json_pfa_oom json_pfa_oom: ; _jsonParseFree(tls, pFromCache) _jsonParseFree(tls, p) Xsqlite3_result_error_nomem(tls, ctx) return uintptr(0) } // C documentation // // /* // ** Return the value of the BLOB node at index i. // ** // ** If the value is a primitive, return it as an SQL value. // ** If the value is an array or object, return it as either // ** JSON text or the BLOB encoding, depending on the eMode flag // ** as follows: // ** // ** eMode==0 JSONB if the JSON_B flag is set in userdata or // ** text if the JSON_B flag is omitted from userdata. // ** // ** eMode==1 Text // ** // ** eMode==2 JSONB // */ func _jsonReturnFromBlob(tls *libc.TLS, pParse uintptr, i Tu32, pCtx uintptr, eMode int32) { bp := tls.Alloc(32) defer tls.Free(32) var bNeg, rc int32 var c, x uint8 var db, z, z1, z2, zOut uintptr var iIn, iOut, n, nOut, szEscape, v19, v20 Tu32 var r, v16 float64 var v17 int64 var _ /* iRes at bp+8 */ Tsqlite3_int64 var _ /* r at bp+16 */ float64 var _ /* sz at bp+0 */ Tu32 var _ /* v at bp+24 */ Tu32 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = bNeg, c, db, iIn, iOut, n, nOut, r, rc, szEscape, x, z, z1, z2, zOut, v16, v17, v19, v20 db = Xsqlite3_context_db_handle(tls, pCtx) n = _jsonbPayloadSize(tls, pParse, i, bp) if n == uint32(0) { Xsqlite3_result_error(tls, pCtx, __ccgo_ts+26486, -int32(1)) return } switch libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TJsonParse)(unsafe.Pointer(pParse)).FaBlob + uintptr(i)))) & libc.Int32FromInt32(0x0f) { case JSONB_NULL: goto _1 case int32(JSONB_TRUE): goto _2 case int32(JSONB_FALSE): goto _3 case int32(JSONB_INT): goto _4 case int32(JSONB_INT5): goto _5 case int32(JSONB_FLOAT): goto _6 case int32(JSONB_FLOAT5): goto _7 case int32(JSONB_TEXT): goto _8 case int32(JSONB_TEXTRAW): goto _9 case int32(JSONB_TEXTJ): goto _10 case int32(JSONB_TEXT5): goto _11 case int32(JSONB_OBJECT): goto _12 case int32(JSONB_ARRAY): goto _13 default: goto _14 } goto _15 _1: ; if **(**Tu32)(__ccgo_up(bp)) != 0 { goto returnfromblob_malformed } Xsqlite3_result_null(tls, pCtx) goto _15 _2: ; if **(**Tu32)(__ccgo_up(bp)) != 0 { goto returnfromblob_malformed } Xsqlite3_result_int(tls, pCtx, int32(1)) goto _15 _3: ; if **(**Tu32)(__ccgo_up(bp)) != 0 { goto returnfromblob_malformed } Xsqlite3_result_int(tls, pCtx, 0) goto _15 _5: ; _4: ; **(**Tsqlite3_int64)(__ccgo_up(bp + 8)) = 0 bNeg = 0 if **(**Tu32)(__ccgo_up(bp)) == uint32(0) { goto returnfromblob_malformed } x = uint8(**(**Tu8)(__ccgo_up((*TJsonParse)(unsafe.Pointer(pParse)).FaBlob + uintptr(i+n)))) if libc.Int32FromUint8(x) == int32('-') { if **(**Tu32)(__ccgo_up(bp)) < uint32(2) { goto returnfromblob_malformed } n = n + 1 **(**Tu32)(__ccgo_up(bp)) = **(**Tu32)(__ccgo_up(bp)) - 1 bNeg = int32(1) } z = _sqlite3DbStrNDup(tls, db, (*TJsonParse)(unsafe.Pointer(pParse)).FaBlob+uintptr(i+n), libc.Uint64FromInt32(libc.Int32FromUint32(**(**Tu32)(__ccgo_up(bp))))) if z == uintptr(0) { goto returnfromblob_oom } rc = _sqlite3DecOrHexToI64(tls, z, bp+8) _sqlite3DbFree(tls, db, z) if rc == 0 { if **(**Tsqlite3_int64)(__ccgo_up(bp + 8)) < 0 { r = float64(**(**Tsqlite3_uint64)(__ccgo_up(bp + 8))) if bNeg != 0 { v16 = -r } else { v16 = r } Xsqlite3_result_double(tls, pCtx, v16) } else { if bNeg != 0 { v17 = -**(**Tsqlite3_int64)(__ccgo_up(bp + 8)) } else { v17 = **(**Tsqlite3_int64)(__ccgo_up(bp + 8)) } Xsqlite3_result_int64(tls, pCtx, v17) } } else { if rc == int32(3) && bNeg != 0 { Xsqlite3_result_int64(tls, pCtx, int64(-libc.Int32FromInt32(1))-(libc.Int64FromUint32(0xffffffff)|libc.Int64FromInt32(0x7fffffff)<>libc.Int32FromInt32(6)) v19 = iOut iOut = iOut + 1 **(**uint8)(__ccgo_up(zOut + uintptr(v19))) = uint8(uint32(0x80) | **(**Tu32)(__ccgo_up(bp + 24))&uint32(0x3f)) } else { if **(**Tu32)(__ccgo_up(bp + 24)) < uint32(0x10000) { v19 = iOut iOut = iOut + 1 **(**uint8)(__ccgo_up(zOut + uintptr(v19))) = uint8(uint32(0xe0) | **(**Tu32)(__ccgo_up(bp + 24))>>libc.Int32FromInt32(12)) v19 = iOut iOut = iOut + 1 **(**uint8)(__ccgo_up(zOut + uintptr(v19))) = uint8(uint32(0x80) | **(**Tu32)(__ccgo_up(bp + 24))>>libc.Int32FromInt32(6)&uint32(0x3f)) v19 = iOut iOut = iOut + 1 **(**uint8)(__ccgo_up(zOut + uintptr(v19))) = uint8(uint32(0x80) | **(**Tu32)(__ccgo_up(bp + 24))&uint32(0x3f)) } else { if **(**Tu32)(__ccgo_up(bp + 24)) == uint32(JSON_INVALID_CHAR) { /* Silently ignore illegal unicode */ } else { v19 = iOut iOut = iOut + 1 **(**uint8)(__ccgo_up(zOut + uintptr(v19))) = uint8(uint32(0xf0) | **(**Tu32)(__ccgo_up(bp + 24))>>libc.Int32FromInt32(18)) v19 = iOut iOut = iOut + 1 **(**uint8)(__ccgo_up(zOut + uintptr(v19))) = uint8(uint32(0x80) | **(**Tu32)(__ccgo_up(bp + 24))>>libc.Int32FromInt32(12)&uint32(0x3f)) v19 = iOut iOut = iOut + 1 **(**uint8)(__ccgo_up(zOut + uintptr(v19))) = uint8(uint32(0x80) | **(**Tu32)(__ccgo_up(bp + 24))>>libc.Int32FromInt32(6)&uint32(0x3f)) v19 = iOut iOut = iOut + 1 **(**uint8)(__ccgo_up(zOut + uintptr(v19))) = uint8(uint32(0x80) | **(**Tu32)(__ccgo_up(bp + 24))&uint32(0x3f)) } } } } iIn = iIn + (szEscape - uint32(1)) } else { v19 = iOut iOut = iOut + 1 **(**uint8)(__ccgo_up(zOut + uintptr(v19))) = c } goto _18 _18: ; iIn = iIn + 1 } /* end for() */ **(**uint8)(__ccgo_up(zOut + uintptr(iOut))) = uint8(0) Xsqlite3_result_text(tls, pCtx, zOut, libc.Int32FromUint32(iOut), __ccgo_fp(_sqlite3RowSetClear)) goto _15 _13: ; _12: ; if eMode == 0 { if int32(int64(Xsqlite3_user_data(tls, pCtx)))&int32(JSON_BLOB) != 0 { eMode = int32(2) } else { eMode = int32(1) } } if eMode == int32(2) { Xsqlite3_result_blob(tls, pCtx, (*TJsonParse)(unsafe.Pointer(pParse)).FaBlob+uintptr(i), libc.Int32FromUint32(**(**Tu32)(__ccgo_up(bp))+n), uintptr(-libc.Int32FromInt32(1))) } else { _jsonReturnTextJsonFromBlob(tls, pCtx, (*TJsonParse)(unsafe.Pointer(pParse)).FaBlob+uintptr(i), **(**Tu32)(__ccgo_up(bp))+n) } goto _15 _14: ; goto returnfromblob_malformed _15: ; return goto returnfromblob_oom returnfromblob_oom: ; Xsqlite3_result_error_nomem(tls, pCtx) return goto returnfromblob_malformed returnfromblob_malformed: ; Xsqlite3_result_error(tls, pCtx, __ccgo_ts+26486, -int32(1)) return } // C documentation // // /* // ** Translate the binary JSONB representation of JSON beginning at // ** pParse->aBlob[i] into a JSON text string. Append the JSON // ** text onto the end of pOut. Return the index in pParse->aBlob[] // ** of the first byte past the end of the element that is translated. // ** // ** This is a variant of jsonTranslateBlobToText() that "pretty-prints" // ** the output. Extra whitespace is inserted to make the JSON easier // ** for humans to read. // ** // ** If an error is detected in the BLOB input, the pOut->eErr flag // ** might get set to JSTRING_MALFORMED. But not all BLOB input errors // ** are detected. So a malformed JSONB input might either result // ** in an error, or in incorrect JSON. // ** // ** The pOut->eErr JSTRING_OOM flag is set on a OOM. // */ func _jsonTranslateBlobToPrettyText(tls *libc.TLS, pPretty uintptr, i Tu32) (r Tu32) { bp := tls.Alloc(16) defer tls.Free(16) var iEnd, j, n Tu32 var pOut, pParse, v1 uintptr var _ /* sz at bp+0 */ Tu32 _, _, _, _, _, _ = iEnd, j, n, pOut, pParse, v1 pParse = (*TJsonPretty)(unsafe.Pointer(pPretty)).FpParse pOut = (*TJsonPretty)(unsafe.Pointer(pPretty)).FpOut n = _jsonbPayloadSize(tls, pParse, i, bp) if n == uint32(0) { v1 = pOut + 33 *(*Tu8)(unsafe.Pointer(v1)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v1))) | libc.Int32FromInt32(JSTRING_MALFORMED)) return (*TJsonParse)(unsafe.Pointer(pParse)).FnBlob + uint32(1) } switch libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TJsonParse)(unsafe.Pointer(pParse)).FaBlob + uintptr(i)))) & libc.Int32FromInt32(0x0f) { case int32(JSONB_ARRAY): j = i + n iEnd = j + **(**Tu32)(__ccgo_up(bp)) _jsonAppendChar(tls, pOut, uint8('[')) if j < iEnd { _jsonAppendChar(tls, pOut, uint8('\n')) (*TJsonPretty)(unsafe.Pointer(pPretty)).FnIndent = (*TJsonPretty)(unsafe.Pointer(pPretty)).FnIndent + 1 if (*TJsonPretty)(unsafe.Pointer(pPretty)).FnIndent >= uint32(JSON_MAX_DEPTH) { _jsonStringTooDeep(tls, pOut) } for libc.Int32FromUint8((*TJsonString)(unsafe.Pointer(pOut)).FeErr) == 0 { _jsonPrettyIndent(tls, pPretty) j = _jsonTranslateBlobToPrettyText(tls, pPretty, j) if j >= iEnd { break } _jsonAppendRawNZ(tls, pOut, __ccgo_ts+26625, uint32(2)) } _jsonAppendChar(tls, pOut, uint8('\n')) (*TJsonPretty)(unsafe.Pointer(pPretty)).FnIndent = (*TJsonPretty)(unsafe.Pointer(pPretty)).FnIndent - 1 _jsonPrettyIndent(tls, pPretty) } _jsonAppendChar(tls, pOut, uint8(']')) i = iEnd case int32(JSONB_OBJECT): j = i + n iEnd = j + **(**Tu32)(__ccgo_up(bp)) _jsonAppendChar(tls, pOut, uint8('{')) if j < iEnd { _jsonAppendChar(tls, pOut, uint8('\n')) (*TJsonPretty)(unsafe.Pointer(pPretty)).FnIndent = (*TJsonPretty)(unsafe.Pointer(pPretty)).FnIndent + 1 if (*TJsonPretty)(unsafe.Pointer(pPretty)).FnIndent >= uint32(JSON_MAX_DEPTH) { _jsonStringTooDeep(tls, pOut) } (*TJsonParse)(unsafe.Pointer(pParse)).FiDepth = uint16((*TJsonPretty)(unsafe.Pointer(pPretty)).FnIndent) for libc.Int32FromUint8((*TJsonString)(unsafe.Pointer(pOut)).FeErr) == 0 { _jsonPrettyIndent(tls, pPretty) j = _jsonTranslateBlobToText(tls, pParse, j, pOut) if j > iEnd { v1 = pOut + 33 *(*Tu8)(unsafe.Pointer(v1)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v1))) | libc.Int32FromInt32(JSTRING_MALFORMED)) break } _jsonAppendRawNZ(tls, pOut, __ccgo_ts+26628, uint32(2)) j = _jsonTranslateBlobToPrettyText(tls, pPretty, j) if j >= iEnd { break } _jsonAppendRawNZ(tls, pOut, __ccgo_ts+26625, uint32(2)) } _jsonAppendChar(tls, pOut, uint8('\n')) (*TJsonPretty)(unsafe.Pointer(pPretty)).FnIndent = (*TJsonPretty)(unsafe.Pointer(pPretty)).FnIndent - 1 _jsonPrettyIndent(tls, pPretty) } _jsonAppendChar(tls, pOut, uint8('}')) i = iEnd default: i = _jsonTranslateBlobToText(tls, pParse, i, pOut) break } return i } // C documentation // // /* // ** Translate the binary JSONB representation of JSON beginning at // ** pParse->aBlob[i] into a JSON text string. Append the JSON // ** text onto the end of pOut. Return the index in pParse->aBlob[] // ** of the first byte past the end of the element that is translated. // ** // ** If an error is detected in the BLOB input, the pOut->eErr flag // ** might get set to JSTRING_MALFORMED. But not all BLOB input errors // ** are detected. So a malformed JSONB input might either result // ** in an error, or in incorrect JSON. // ** // ** The pOut->eErr JSTRING_OOM flag is set on a OOM. // */ func _jsonTranslateBlobToText(tls *libc.TLS, pParse uintptr, i Tu32, pOut uintptr) (r Tu32) { bp := tls.Alloc(32) defer tls.Free(32) var bOverflow, x, v30, v31 int32 var iEnd, j, k, k1, k2, n, sz2 Tu32 var u Tsqlite3_uint64 var zIn, zIn1, zIn2, v1 uintptr var v25 Tu16 var _ /* sz at bp+0 */ Tu32 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = bOverflow, iEnd, j, k, k1, k2, n, sz2, u, x, zIn, zIn1, zIn2, v1, v25, v30, v31 n = _jsonbPayloadSize(tls, pParse, i, bp) if n == uint32(0) { v1 = pOut + 33 *(*Tu8)(unsafe.Pointer(v1)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v1))) | libc.Int32FromInt32(JSTRING_MALFORMED)) return (*TJsonParse)(unsafe.Pointer(pParse)).FnBlob + uint32(1) } switch libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TJsonParse)(unsafe.Pointer(pParse)).FaBlob + uintptr(i)))) & libc.Int32FromInt32(0x0f) { case JSONB_NULL: goto _2 case int32(JSONB_TRUE): goto _3 case int32(JSONB_FALSE): goto _4 case int32(JSONB_FLOAT): goto _5 case int32(JSONB_INT): goto _6 case int32(JSONB_INT5): goto _7 case int32(JSONB_FLOAT5): goto _8 case int32(JSONB_TEXTJ): goto _9 case int32(JSONB_TEXT): goto _10 case int32(JSONB_TEXT5): goto _11 case int32(JSONB_TEXTRAW): goto _12 case int32(JSONB_ARRAY): goto _13 case int32(JSONB_OBJECT): goto _14 default: goto _15 } goto _16 _2: ; _jsonAppendRawNZ(tls, pOut, __ccgo_ts+1690, uint32(4)) return i + uint32(1) _3: ; _jsonAppendRawNZ(tls, pOut, __ccgo_ts+8206, uint32(4)) return i + uint32(1) _4: ; _jsonAppendRawNZ(tls, pOut, __ccgo_ts+8211, uint32(5)) return i + uint32(1) _6: ; _5: ; if **(**Tu32)(__ccgo_up(bp)) == uint32(0) { goto malformed_jsonb } _jsonAppendRaw(tls, pOut, (*TJsonParse)(unsafe.Pointer(pParse)).FaBlob+uintptr(i+n), **(**Tu32)(__ccgo_up(bp))) goto _16 _7: ; /* Integer literal in hexadecimal notation */ k = uint32(2) u = uint64(0) zIn = (*TJsonParse)(unsafe.Pointer(pParse)).FaBlob + uintptr(i+n) bOverflow = 0 if **(**Tu32)(__ccgo_up(bp)) == uint32(0) { goto malformed_jsonb } if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zIn))) == int32('-') { _jsonAppendChar(tls, pOut, uint8('-')) k = k + 1 } else { if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zIn))) == int32('+') { k = k + 1 } } for { if !(k < **(**Tu32)(__ccgo_up(bp))) { break } if !(libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(zIn + uintptr(k))))])&libc.Int32FromInt32(0x08) != 0) { v1 = pOut + 33 *(*Tu8)(unsafe.Pointer(v1)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v1))) | libc.Int32FromInt32(JSTRING_MALFORMED)) break } else { if u>>libc.Int32FromInt32(60) != uint64(0) { bOverflow = int32(1) } else { u = u*uint64(16) + uint64(_sqlite3HexToInt(tls, libc.Int32FromUint8(**(**uint8)(__ccgo_up(zIn + uintptr(k)))))) } } goto _17 _17: ; k = k + 1 } if bOverflow != 0 { v1 = __ccgo_ts + 26505 } else { v1 = __ccgo_ts + 13032 } _jsonPrintf(tls, int32(100), pOut, v1, libc.VaList(bp+16, u)) goto _16 _8: ; /* Float literal missing digits beside "." */ k1 = uint32(0) zIn1 = (*TJsonParse)(unsafe.Pointer(pParse)).FaBlob + uintptr(i+n) if **(**Tu32)(__ccgo_up(bp)) == uint32(0) { goto malformed_jsonb } if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zIn1))) == int32('-') { _jsonAppendChar(tls, pOut, uint8('-')) if **(**Tu32)(__ccgo_up(bp)) <= uint32(1) { goto malformed_jsonb } k1 = uint32(1) } if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zIn1 + uintptr(k1)))) == int32('.') { _jsonAppendChar(tls, pOut, uint8('0')) } for { if !(k1 < **(**Tu32)(__ccgo_up(bp))) { break } _jsonAppendChar(tls, pOut, **(**uint8)(__ccgo_up(zIn1 + uintptr(k1)))) if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zIn1 + uintptr(k1)))) == int32('.') && (k1+uint32(1) == **(**Tu32)(__ccgo_up(bp)) || !(libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(zIn1 + uintptr(k1+uint32(1)))))])&libc.Int32FromInt32(0x04) != 0)) { _jsonAppendChar(tls, pOut, uint8('0')) } goto _20 _20: ; k1 = k1 + 1 } goto _16 _10: ; _9: ; if (*TJsonString)(unsafe.Pointer(pOut)).FnUsed+uint64(**(**Tu32)(__ccgo_up(bp)))+uint64(2) <= (*TJsonString)(unsafe.Pointer(pOut)).FnAlloc || _jsonStringGrow(tls, pOut, **(**Tu32)(__ccgo_up(bp))+uint32(2)) == 0 { **(**uint8)(__ccgo_up((*TJsonString)(unsafe.Pointer(pOut)).FzBuf + uintptr((*TJsonString)(unsafe.Pointer(pOut)).FnUsed))) = uint8('"') libc.Xmemcpy(tls, (*TJsonString)(unsafe.Pointer(pOut)).FzBuf+uintptr((*TJsonString)(unsafe.Pointer(pOut)).FnUsed)+uintptr(1), (*TJsonParse)(unsafe.Pointer(pParse)).FaBlob+uintptr(i+n), uint64(**(**Tu32)(__ccgo_up(bp)))) **(**uint8)(__ccgo_up((*TJsonString)(unsafe.Pointer(pOut)).FzBuf + uintptr((*TJsonString)(unsafe.Pointer(pOut)).FnUsed+uint64(**(**Tu32)(__ccgo_up(bp)))+uint64(1)))) = uint8('"') **(**Tu64)(__ccgo_up(pOut + 24)) += uint64(**(**Tu32)(__ccgo_up(bp)) + uint32(2)) } goto _16 _11: ; sz2 = **(**Tu32)(__ccgo_up(bp)) zIn2 = (*TJsonParse)(unsafe.Pointer(pParse)).FaBlob + uintptr(i+n) _jsonAppendChar(tls, pOut, uint8('"')) for sz2 > uint32(0) { k2 = uint32(0) for { if !(k2 < sz2 && (_jsonIsOk[uint8(**(**uint8)(__ccgo_up(zIn2 + uintptr(k2))))] != 0 || libc.Int32FromUint8(**(**uint8)(__ccgo_up(zIn2 + uintptr(k2)))) == int32('\''))) { break } goto _21 _21: ; k2 = k2 + 1 } if k2 > uint32(0) { _jsonAppendRawNZ(tls, pOut, zIn2, k2) if k2 >= sz2 { break } zIn2 = zIn2 + uintptr(k2) sz2 = sz2 - k2 } if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zIn2))) == int32('"') { _jsonAppendRawNZ(tls, pOut, __ccgo_ts+26603, uint32(2)) zIn2 = zIn2 + 1 sz2 = sz2 - 1 continue } if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zIn2))) <= int32(0x1f) { if (*TJsonString)(unsafe.Pointer(pOut)).FnUsed+uint64(7) > (*TJsonString)(unsafe.Pointer(pOut)).FnAlloc && _jsonStringGrow(tls, pOut, uint32(7)) != 0 { break } _jsonAppendControlChar(tls, pOut, uint8(**(**uint8)(__ccgo_up(zIn2)))) zIn2 = zIn2 + 1 sz2 = sz2 - 1 continue } if sz2 < uint32(2) { v1 = pOut + 33 *(*Tu8)(unsafe.Pointer(v1)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v1))) | libc.Int32FromInt32(JSTRING_MALFORMED)) break } switch libc.Int32FromUint8(uint8(**(**uint8)(__ccgo_up(zIn2 + 1)))) { case int32('\''): _jsonAppendChar(tls, pOut, uint8('\'')) case int32('v'): _jsonAppendRawNZ(tls, pOut, __ccgo_ts+26606, uint32(6)) case int32('x'): if sz2 < uint32(4) { v1 = pOut + 33 *(*Tu8)(unsafe.Pointer(v1)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v1))) | libc.Int32FromInt32(JSTRING_MALFORMED)) sz2 = uint32(2) break } _jsonAppendRawNZ(tls, pOut, __ccgo_ts+26613, uint32(4)) _jsonAppendRawNZ(tls, pOut, zIn2+2, uint32(2)) zIn2 = zIn2 + uintptr(2) sz2 = sz2 - uint32(2) case int32('0'): _jsonAppendRawNZ(tls, pOut, __ccgo_ts+26618, uint32(6)) case int32('\r'): if sz2 > uint32(2) && libc.Int32FromUint8(**(**uint8)(__ccgo_up(zIn2 + 2))) == int32('\n') { zIn2 = zIn2 + 1 sz2 = sz2 - 1 } case int32('\n'): case int32(0xe2): /* '\' followed by either U+2028 or U+2029 is ignored as ** whitespace. Not that in UTF8, U+2028 is 0xe2 0x80 0x29. ** U+2029 is the same except for the last byte */ if sz2 < uint32(4) || int32(0x80) != libc.Int32FromUint8(uint8(**(**uint8)(__ccgo_up(zIn2 + 2)))) || int32(0xa8) != libc.Int32FromUint8(uint8(**(**uint8)(__ccgo_up(zIn2 + 3)))) && int32(0xa9) != libc.Int32FromUint8(uint8(**(**uint8)(__ccgo_up(zIn2 + 3)))) { v1 = pOut + 33 *(*Tu8)(unsafe.Pointer(v1)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v1))) | libc.Int32FromInt32(JSTRING_MALFORMED)) sz2 = uint32(2) break } zIn2 = zIn2 + uintptr(2) sz2 = sz2 - uint32(2) default: _jsonAppendRawNZ(tls, pOut, zIn2, uint32(2)) break } zIn2 = zIn2 + uintptr(2) sz2 = sz2 - uint32(2) } _jsonAppendChar(tls, pOut, uint8('"')) goto _16 _12: ; _jsonAppendString(tls, pOut, (*TJsonParse)(unsafe.Pointer(pParse)).FaBlob+uintptr(i+n), **(**Tu32)(__ccgo_up(bp))) goto _16 _13: ; _jsonAppendChar(tls, pOut, uint8('[')) j = i + n iEnd = j + **(**Tu32)(__ccgo_up(bp)) v1 = pParse + 44 *(*Tu16)(unsafe.Pointer(v1)) = *(*Tu16)(unsafe.Pointer(v1)) + 1 v25 = *(*Tu16)(unsafe.Pointer(v1)) if libc.Int32FromUint16(v25) > int32(JSON_MAX_DEPTH) { _jsonStringTooDeep(tls, pOut) } for j < iEnd && libc.Int32FromUint8((*TJsonString)(unsafe.Pointer(pOut)).FeErr) == 0 { j = _jsonTranslateBlobToText(tls, pParse, j, pOut) _jsonAppendChar(tls, pOut, uint8(',')) } (*TJsonParse)(unsafe.Pointer(pParse)).FiDepth = (*TJsonParse)(unsafe.Pointer(pParse)).FiDepth - 1 if j > iEnd { v1 = pOut + 33 *(*Tu8)(unsafe.Pointer(v1)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v1))) | libc.Int32FromInt32(JSTRING_MALFORMED)) } if **(**Tu32)(__ccgo_up(bp)) > uint32(0) { _jsonStringTrimOneChar(tls, pOut) } _jsonAppendChar(tls, pOut, uint8(']')) goto _16 _14: ; x = 0 _jsonAppendChar(tls, pOut, uint8('{')) j = i + n iEnd = j + **(**Tu32)(__ccgo_up(bp)) v1 = pParse + 44 *(*Tu16)(unsafe.Pointer(v1)) = *(*Tu16)(unsafe.Pointer(v1)) + 1 v25 = *(*Tu16)(unsafe.Pointer(v1)) if libc.Int32FromUint16(v25) > int32(JSON_MAX_DEPTH) { _jsonStringTooDeep(tls, pOut) } for j < iEnd && libc.Int32FromUint8((*TJsonString)(unsafe.Pointer(pOut)).FeErr) == 0 { j = _jsonTranslateBlobToText(tls, pParse, j, pOut) v31 = x x = x + 1 if v31&int32(1) != 0 { v30 = int32(',') } else { v30 = int32(':') } _jsonAppendChar(tls, pOut, libc.Uint8FromInt32(v30)) } (*TJsonParse)(unsafe.Pointer(pParse)).FiDepth = (*TJsonParse)(unsafe.Pointer(pParse)).FiDepth - 1 if x&int32(1) != 0 || j > iEnd { v1 = pOut + 33 *(*Tu8)(unsafe.Pointer(v1)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v1))) | libc.Int32FromInt32(JSTRING_MALFORMED)) } if **(**Tu32)(__ccgo_up(bp)) > uint32(0) { _jsonStringTrimOneChar(tls, pOut) } _jsonAppendChar(tls, pOut, uint8('}')) goto _16 _15: ; goto malformed_jsonb malformed_jsonb: ; v1 = pOut + 33 *(*Tu8)(unsafe.Pointer(v1)) = Tu8(int32(*(*Tu8)(unsafe.Pointer(v1))) | libc.Int32FromInt32(JSTRING_MALFORMED)) goto _16 _16: ; return i + n + **(**Tu32)(__ccgo_up(bp)) } // C documentation // // /* // ** Translate a single element of JSON text at pParse->zJson[i] into // ** its equivalent binary JSONB representation. Append the translation into // ** pParse->aBlob[] beginning at pParse->nBlob. The size of // ** pParse->aBlob[] is increased as necessary. // ** // ** Return the index of the first character past the end of the element parsed, // ** or one of the following special result codes: // ** // ** 0 End of input // ** -1 Syntax error or OOM // ** -2 '}' seen ** -3 ']' seen \___ For these returns, pParse->iErr is set to // ** -4 ',' seen / the index in zJson[] of the seen character // ** -5 ':' seen / // */ func _jsonTranslateTextToBlob(tls *libc.TLS, pParse uintptr, i Tu32) (r int32) { bp := tls.Alloc(16) defer tls.Free(16) var c, cDelim uint8 var iBlob, iStart, iThis, j, k1, v46 Tu32 var k, nn, x, v48 int32 var opcode, seenE, t Tu8 var z, v41 uintptr var v40 Tu16 var _ /* op at bp+0 */ int32 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = c, cDelim, iBlob, iStart, iThis, j, k, k1, nn, opcode, seenE, t, x, z, v40, v41, v46, v48 z = (*TJsonParse)(unsafe.Pointer(pParse)).FzJson goto json_parse_restart json_parse_restart: ; switch libc.Int32FromUint8(uint8(**(**uint8)(__ccgo_up(z + uintptr(i))))) { case int32('{'): goto _1 case int32('['): goto _2 case int32('"'): goto _3 case int32('\''): goto _4 case int32('t'): goto _5 case int32('f'): goto _6 case int32('.'): goto _7 case int32('9'): goto _8 case int32('8'): goto _9 case int32('7'): goto _10 case int32('6'): goto _11 case int32('5'): goto _12 case int32('4'): goto _13 case int32('3'): goto _14 case int32('2'): goto _15 case int32('1'): goto _16 case int32('0'): goto _17 case int32('-'): goto _18 case int32('+'): goto _19 case int32('}'): goto _20 case int32(']'): goto _21 case int32(','): goto _22 case int32(':'): goto _23 case 0: goto _24 case int32(0x20): goto _25 case int32(0x0d): goto _26 case int32(0x0a): goto _27 case int32(0x09): goto _28 case int32(0xef): goto _29 case int32(0xe3): goto _30 case int32(0xe2): goto _31 case int32(0xe1): goto _32 case int32(0xc2): goto _33 case int32('/'): goto _34 case int32(0x0c): goto _35 case int32(0x0b): goto _36 case int32('n'): goto _37 default: goto _38 } goto _39 _1: ; /* Parse object */ iThis = (*TJsonParse)(unsafe.Pointer(pParse)).FnBlob _jsonBlobAppendNode(tls, pParse, uint8(JSONB_OBJECT), uint64(libc.Uint32FromInt32((*TJsonParse)(unsafe.Pointer(pParse)).FnJson)-i), uintptr(0)) v41 = pParse + 44 *(*Tu16)(unsafe.Pointer(v41)) = *(*Tu16)(unsafe.Pointer(v41)) + 1 v40 = *(*Tu16)(unsafe.Pointer(v41)) if libc.Int32FromUint16(v40) > int32(JSON_MAX_DEPTH) { (*TJsonParse)(unsafe.Pointer(pParse)).FiErr = i return -int32(1) } iStart = (*TJsonParse)(unsafe.Pointer(pParse)).FnBlob j = i + uint32(1) for { iBlob = (*TJsonParse)(unsafe.Pointer(pParse)).FnBlob x = _jsonTranslateTextToBlob(tls, pParse, j) if x <= 0 { if x == -int32(2) { j = (*TJsonParse)(unsafe.Pointer(pParse)).FiErr if (*TJsonParse)(unsafe.Pointer(pParse)).FnBlob != iStart { (*TJsonParse)(unsafe.Pointer(pParse)).FhasNonstd = uint8(1) } break } j = j + libc.Uint32FromInt32(_json5Whitespace(tls, z+uintptr(j))) **(**int32)(__ccgo_up(bp)) = int32(JSONB_TEXT) if libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(z + uintptr(j))))])&int32(0x42) != 0 || libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(j)))) == int32('\\') && _jsonIs4HexB(tls, z+uintptr(j+uint32(1)), bp) != 0 { k = libc.Int32FromUint32(j + uint32(1)) for libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(z + uintptr(k))))])&int32(0x46) != 0 && _json5Whitespace(tls, z+uintptr(k)) == 0 || libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(k)))) == int32('\\') && _jsonIs4HexB(tls, z+uintptr(k+int32(1)), bp) != 0 { k = k + 1 } _jsonBlobAppendNode(tls, pParse, libc.Uint8FromInt32(**(**int32)(__ccgo_up(bp))), uint64(libc.Uint32FromInt32(k)-j), z+uintptr(j)) (*TJsonParse)(unsafe.Pointer(pParse)).FhasNonstd = uint8(1) x = k } else { if x != -int32(1) { (*TJsonParse)(unsafe.Pointer(pParse)).FiErr = j } return -int32(1) } } if (*TJsonParse)(unsafe.Pointer(pParse)).Foom != 0 { return -int32(1) } t = libc.Uint8FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TJsonParse)(unsafe.Pointer(pParse)).FaBlob + uintptr(iBlob)))) & int32(0x0f)) if libc.Int32FromUint8(t) < int32(JSONB_TEXT) || libc.Int32FromUint8(t) > int32(JSONB_TEXTRAW) { (*TJsonParse)(unsafe.Pointer(pParse)).FiErr = j return -int32(1) } j = libc.Uint32FromInt32(x) if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(j)))) == int32(':') { j = j + 1 } else { if _jsonIsSpace[uint8(**(**uint8)(__ccgo_up(z + uintptr(j))))] != 0 { /* strspn() is not helpful here */ for cond := true; cond; cond = _jsonIsSpace[uint8(**(**uint8)(__ccgo_up(z + uintptr(j))))] != 0 { j = j + 1 } if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(j)))) == int32(':') { j = j + 1 goto parse_object_value } } x = _jsonTranslateTextToBlob(tls, pParse, j) if x != -int32(5) { if x != -int32(1) { (*TJsonParse)(unsafe.Pointer(pParse)).FiErr = j } return -int32(1) } j = (*TJsonParse)(unsafe.Pointer(pParse)).FiErr + uint32(1) } goto parse_object_value parse_object_value: ; x = _jsonTranslateTextToBlob(tls, pParse, j) if x <= 0 { if x != -int32(1) { (*TJsonParse)(unsafe.Pointer(pParse)).FiErr = j } return -int32(1) } j = libc.Uint32FromInt32(x) if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(j)))) == int32(',') { goto _42 } else { if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(j)))) == int32('}') { break } else { if _jsonIsSpace[uint8(**(**uint8)(__ccgo_up(z + uintptr(j))))] != 0 { j = j + (uint32(1) + uint32(libc.Xstrspn(tls, z+uintptr(j+uint32(1)), uintptr(unsafe.Pointer(&_jsonSpaces))))) if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(j)))) == int32(',') { goto _42 } else { if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(j)))) == int32('}') { break } } } x = _jsonTranslateTextToBlob(tls, pParse, j) if x == -int32(4) { j = (*TJsonParse)(unsafe.Pointer(pParse)).FiErr goto _42 } if x == -int32(2) { j = (*TJsonParse)(unsafe.Pointer(pParse)).FiErr break } } } (*TJsonParse)(unsafe.Pointer(pParse)).FiErr = j return -int32(1) goto _42 _42: ; j = j + 1 } _jsonBlobChangePayloadSize(tls, pParse, iThis, (*TJsonParse)(unsafe.Pointer(pParse)).FnBlob-iStart) (*TJsonParse)(unsafe.Pointer(pParse)).FiDepth = (*TJsonParse)(unsafe.Pointer(pParse)).FiDepth - 1 return libc.Int32FromUint32(j + uint32(1)) _2: ; /* Parse array */ iThis = (*TJsonParse)(unsafe.Pointer(pParse)).FnBlob _jsonBlobAppendNode(tls, pParse, uint8(JSONB_ARRAY), uint64(libc.Uint32FromInt32((*TJsonParse)(unsafe.Pointer(pParse)).FnJson)-i), uintptr(0)) iStart = (*TJsonParse)(unsafe.Pointer(pParse)).FnBlob if (*TJsonParse)(unsafe.Pointer(pParse)).Foom != 0 { return -int32(1) } v41 = pParse + 44 *(*Tu16)(unsafe.Pointer(v41)) = *(*Tu16)(unsafe.Pointer(v41)) + 1 v40 = *(*Tu16)(unsafe.Pointer(v41)) if libc.Int32FromUint16(v40) > int32(JSON_MAX_DEPTH) { (*TJsonParse)(unsafe.Pointer(pParse)).FiErr = i return -int32(1) } j = i + uint32(1) for { x = _jsonTranslateTextToBlob(tls, pParse, j) if x <= 0 { if x == -int32(3) { j = (*TJsonParse)(unsafe.Pointer(pParse)).FiErr if (*TJsonParse)(unsafe.Pointer(pParse)).FnBlob != iStart { (*TJsonParse)(unsafe.Pointer(pParse)).FhasNonstd = uint8(1) } break } if x != -int32(1) { (*TJsonParse)(unsafe.Pointer(pParse)).FiErr = j } return -int32(1) } j = libc.Uint32FromInt32(x) if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(j)))) == int32(',') { goto _45 } else { if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(j)))) == int32(']') { break } else { if _jsonIsSpace[uint8(**(**uint8)(__ccgo_up(z + uintptr(j))))] != 0 { j = j + (uint32(1) + uint32(libc.Xstrspn(tls, z+uintptr(j+uint32(1)), uintptr(unsafe.Pointer(&_jsonSpaces))))) if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(j)))) == int32(',') { goto _45 } else { if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(j)))) == int32(']') { break } } } x = _jsonTranslateTextToBlob(tls, pParse, j) if x == -int32(4) { j = (*TJsonParse)(unsafe.Pointer(pParse)).FiErr goto _45 } if x == -int32(3) { j = (*TJsonParse)(unsafe.Pointer(pParse)).FiErr break } } } (*TJsonParse)(unsafe.Pointer(pParse)).FiErr = j return -int32(1) goto _45 _45: ; j = j + 1 } _jsonBlobChangePayloadSize(tls, pParse, iThis, (*TJsonParse)(unsafe.Pointer(pParse)).FnBlob-iStart) (*TJsonParse)(unsafe.Pointer(pParse)).FiDepth = (*TJsonParse)(unsafe.Pointer(pParse)).FiDepth - 1 return libc.Int32FromUint32(j + uint32(1)) _4: ; (*TJsonParse)(unsafe.Pointer(pParse)).FhasNonstd = uint8(1) opcode = uint8(JSONB_TEXT) goto parse_string _3: ; /* Parse string */ opcode = uint8(JSONB_TEXT) goto parse_string parse_string: ; cDelim = **(**uint8)(__ccgo_up(z + uintptr(i))) j = i + uint32(1) for int32(1) != 0 { if _jsonIsOk[uint8(**(**uint8)(__ccgo_up(z + uintptr(j))))] != 0 { if !(_jsonIsOk[uint8(**(**uint8)(__ccgo_up(z + uintptr(j+uint32(1)))))] != 0) { j = j + uint32(1) } else { if !(_jsonIsOk[uint8(**(**uint8)(__ccgo_up(z + uintptr(j+uint32(2)))))] != 0) { j = j + uint32(2) } else { j = j + uint32(3) continue } } } c = **(**uint8)(__ccgo_up(z + uintptr(j))) if libc.Int32FromUint8(c) == libc.Int32FromUint8(cDelim) { break } else { if libc.Int32FromUint8(c) == int32('\\') { j = j + 1 v46 = j c = **(**uint8)(__ccgo_up(z + uintptr(v46))) if libc.Int32FromUint8(c) == int32('"') || libc.Int32FromUint8(c) == int32('\\') || libc.Int32FromUint8(c) == int32('/') || libc.Int32FromUint8(c) == int32('b') || libc.Int32FromUint8(c) == int32('f') || libc.Int32FromUint8(c) == int32('n') || libc.Int32FromUint8(c) == int32('r') || libc.Int32FromUint8(c) == int32('t') || libc.Int32FromUint8(c) == int32('u') && _jsonIs4Hex(tls, z+uintptr(j+uint32(1))) != 0 { if libc.Int32FromUint8(opcode) == int32(JSONB_TEXT) { opcode = uint8(JSONB_TEXTJ) } } else { if libc.Int32FromUint8(c) == int32('\'') || libc.Int32FromUint8(c) == int32('v') || libc.Int32FromUint8(c) == int32('\n') || libc.Int32FromUint8(c) == int32('0') && !(libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(z + uintptr(j+uint32(1)))))])&libc.Int32FromInt32(0x04) != 0) || int32(0xe2) == libc.Int32FromUint8(c) && int32(0x80) == libc.Int32FromUint8(uint8(**(**uint8)(__ccgo_up(z + uintptr(j+uint32(1)))))) && (int32(0xa8) == libc.Int32FromUint8(uint8(**(**uint8)(__ccgo_up(z + uintptr(j+uint32(2)))))) || int32(0xa9) == libc.Int32FromUint8(uint8(**(**uint8)(__ccgo_up(z + uintptr(j+uint32(2))))))) || libc.Int32FromUint8(c) == int32('x') && _jsonIs2Hex(tls, z+uintptr(j+uint32(1))) != 0 { opcode = uint8(JSONB_TEXT5) (*TJsonParse)(unsafe.Pointer(pParse)).FhasNonstd = uint8(1) } else { if libc.Int32FromUint8(c) == int32('\r') { if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(j+uint32(1))))) == int32('\n') { j = j + 1 } opcode = uint8(JSONB_TEXT5) (*TJsonParse)(unsafe.Pointer(pParse)).FhasNonstd = uint8(1) } else { (*TJsonParse)(unsafe.Pointer(pParse)).FiErr = j return -int32(1) } } } } else { if libc.Int32FromUint8(c) <= int32(0x1f) { if libc.Int32FromUint8(c) == 0 { (*TJsonParse)(unsafe.Pointer(pParse)).FiErr = j return -int32(1) } /* Control characters are not allowed in canonical JSON string ** literals, but are allowed in JSON5 string literals. */ opcode = uint8(JSONB_TEXT5) (*TJsonParse)(unsafe.Pointer(pParse)).FhasNonstd = uint8(1) } else { if libc.Int32FromUint8(c) == int32('"') { opcode = uint8(JSONB_TEXT5) } } } } j = j + 1 } _jsonBlobAppendNode(tls, pParse, opcode, uint64(j-uint32(1)-i), z+uintptr(i+uint32(1))) return libc.Int32FromUint32(j + uint32(1)) _5: ; if libc.Xstrncmp(tls, z+uintptr(i), __ccgo_ts+8206, uint64(4)) == 0 && !(libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(z + uintptr(i+uint32(4)))))])&libc.Int32FromInt32(0x06) != 0) { _jsonBlobAppendOneByte(tls, pParse, uint8(JSONB_TRUE)) return libc.Int32FromUint32(i + uint32(4)) } (*TJsonParse)(unsafe.Pointer(pParse)).FiErr = i return -int32(1) _6: ; if libc.Xstrncmp(tls, z+uintptr(i), __ccgo_ts+8211, uint64(5)) == 0 && !(libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(z + uintptr(i+uint32(5)))))])&libc.Int32FromInt32(0x06) != 0) { _jsonBlobAppendOneByte(tls, pParse, uint8(JSONB_FALSE)) return libc.Int32FromUint32(i + uint32(5)) } (*TJsonParse)(unsafe.Pointer(pParse)).FiErr = i return -int32(1) _19: ; (*TJsonParse)(unsafe.Pointer(pParse)).FhasNonstd = uint8(1) t = uint8(0x00) /* Bit 0x01: JSON5. Bit 0x02: FLOAT */ goto parse_number _7: ; if libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(z + uintptr(i+uint32(1)))))])&int32(0x04) != 0 { (*TJsonParse)(unsafe.Pointer(pParse)).FhasNonstd = uint8(1) t = uint8(0x03) /* Bit 0x01: JSON5. Bit 0x02: FLOAT */ seenE = uint8(0) goto parse_number_2 } (*TJsonParse)(unsafe.Pointer(pParse)).FiErr = i return -int32(1) _18: ; _17: ; _16: ; _15: ; _14: ; _13: ; _12: ; _11: ; _10: ; _9: ; _8: ; /* Parse number */ t = uint8(0x00) /* Bit 0x01: JSON5. Bit 0x02: FLOAT */ goto parse_number parse_number: ; seenE = uint8(0) c = **(**uint8)(__ccgo_up(z + uintptr(i))) if libc.Int32FromUint8(c) <= int32('0') { if libc.Int32FromUint8(c) == int32('0') { if (libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(i+uint32(1))))) == int32('x') || libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(i+uint32(1))))) == int32('X')) && libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(z + uintptr(i+uint32(2)))))])&int32(0x08) != 0 { (*TJsonParse)(unsafe.Pointer(pParse)).FhasNonstd = uint8(1) t = uint8(0x01) j = i + uint32(3) for { if !(libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(z + uintptr(j))))])&int32(0x08) != 0) { break } goto _47 _47: ; j = j + 1 } goto parse_number_finish } else { if libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(z + uintptr(i+uint32(1)))))])&int32(0x04) != 0 { (*TJsonParse)(unsafe.Pointer(pParse)).FiErr = i + uint32(1) return -int32(1) } } } else { if !(libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(z + uintptr(i+uint32(1)))))])&libc.Int32FromInt32(0x04) != 0) { /* JSON5 allows for "+Infinity" and "-Infinity" using exactly ** that case. SQLite also allows these in any case and it allows ** "+inf" and "-inf". */ if (libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(i+uint32(1))))) == int32('I') || libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(i+uint32(1))))) == int32('i')) && Xsqlite3_strnicmp(tls, z+uintptr(i+uint32(1)), __ccgo_ts+26501, int32(3)) == 0 { (*TJsonParse)(unsafe.Pointer(pParse)).FhasNonstd = uint8(1) if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(i)))) == int32('-') { _jsonBlobAppendNode(tls, pParse, uint8(JSONB_FLOAT), uint64(6), __ccgo_ts+26584) } else { _jsonBlobAppendNode(tls, pParse, uint8(JSONB_FLOAT), uint64(5), __ccgo_ts+26591) } if Xsqlite3_strnicmp(tls, z+uintptr(i+uint32(4)), __ccgo_ts+26597, int32(5)) == 0 { v48 = int32(9) } else { v48 = int32(4) } return libc.Int32FromUint32(i + libc.Uint32FromInt32(v48)) } if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(i+uint32(1))))) == int32('.') { (*TJsonParse)(unsafe.Pointer(pParse)).FhasNonstd = uint8(1) t = libc.Uint8FromInt32(int32(t) | libc.Int32FromInt32(0x01)) goto parse_number_2 } (*TJsonParse)(unsafe.Pointer(pParse)).FiErr = i return -int32(1) } if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(i+uint32(1))))) == int32('0') { if libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(z + uintptr(i+uint32(2)))))])&int32(0x04) != 0 { (*TJsonParse)(unsafe.Pointer(pParse)).FiErr = i + uint32(1) return -int32(1) } else { if (libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(i+uint32(2))))) == int32('x') || libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(i+uint32(2))))) == int32('X')) && libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(z + uintptr(i+uint32(3)))))])&int32(0x08) != 0 { (*TJsonParse)(unsafe.Pointer(pParse)).FhasNonstd = uint8(1) t = libc.Uint8FromInt32(int32(t) | libc.Int32FromInt32(0x01)) j = i + uint32(4) for { if !(libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(z + uintptr(j))))])&int32(0x08) != 0) { break } goto _49 _49: ; j = j + 1 } goto parse_number_finish } } } } } goto parse_number_2 parse_number_2: ; j = i + uint32(1) for { c = **(**uint8)(__ccgo_up(z + uintptr(j))) if libc.Int32FromUint8(_sqlite3CtypeMap[c])&int32(0x04) != 0 { goto _50 } if libc.Int32FromUint8(c) == int32('.') { if libc.Int32FromUint8(t)&int32(0x02) != 0 { (*TJsonParse)(unsafe.Pointer(pParse)).FiErr = j return -int32(1) } t = libc.Uint8FromInt32(int32(t) | libc.Int32FromInt32(0x02)) goto _50 } if libc.Int32FromUint8(c) == int32('e') || libc.Int32FromUint8(c) == int32('E') { if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(j-uint32(1))))) < int32('0') { if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(j-uint32(1))))) == int32('.') && j-uint32(2) >= i && libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(z + uintptr(j-uint32(2)))))])&int32(0x04) != 0 { (*TJsonParse)(unsafe.Pointer(pParse)).FhasNonstd = uint8(1) t = libc.Uint8FromInt32(int32(t) | libc.Int32FromInt32(0x01)) } else { (*TJsonParse)(unsafe.Pointer(pParse)).FiErr = j return -int32(1) } } if seenE != 0 { (*TJsonParse)(unsafe.Pointer(pParse)).FiErr = j return -int32(1) } t = libc.Uint8FromInt32(int32(t) | libc.Int32FromInt32(0x02)) seenE = uint8(1) c = **(**uint8)(__ccgo_up(z + uintptr(j+uint32(1)))) if libc.Int32FromUint8(c) == int32('+') || libc.Int32FromUint8(c) == int32('-') { j = j + 1 c = **(**uint8)(__ccgo_up(z + uintptr(j+uint32(1)))) } if libc.Int32FromUint8(c) < int32('0') || libc.Int32FromUint8(c) > int32('9') { (*TJsonParse)(unsafe.Pointer(pParse)).FiErr = j return -int32(1) } goto _50 } break goto _50 _50: ; j = j + 1 } if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(j-uint32(1))))) < int32('0') { if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(j-uint32(1))))) == int32('.') && j-uint32(2) >= i && libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(z + uintptr(j-uint32(2)))))])&int32(0x04) != 0 { (*TJsonParse)(unsafe.Pointer(pParse)).FhasNonstd = uint8(1) t = libc.Uint8FromInt32(int32(t) | libc.Int32FromInt32(0x01)) } else { (*TJsonParse)(unsafe.Pointer(pParse)).FiErr = j return -int32(1) } } goto parse_number_finish parse_number_finish: ; if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(i)))) == int32('+') { i = i + 1 } _jsonBlobAppendNode(tls, pParse, libc.Uint8FromInt32(int32(JSONB_INT)+libc.Int32FromUint8(t)), uint64(j-i), z+uintptr(i)) return libc.Int32FromUint32(j) _20: ; (*TJsonParse)(unsafe.Pointer(pParse)).FiErr = i return -int32(2) /* End of {...} */ _21: ; (*TJsonParse)(unsafe.Pointer(pParse)).FiErr = i return -int32(3) /* End of [...] */ _22: ; (*TJsonParse)(unsafe.Pointer(pParse)).FiErr = i return -int32(4) /* List separator */ _23: ; (*TJsonParse)(unsafe.Pointer(pParse)).FiErr = i return -int32(5) /* Object label/value separator */ _24: ; return 0 /* End of file */ _28: ; _27: ; _26: ; _25: ; i = i + (uint32(1) + uint32(libc.Xstrspn(tls, z+uintptr(i+uint32(1)), uintptr(unsafe.Pointer(&_jsonSpaces))))) goto json_parse_restart _36: ; _35: ; _34: ; _33: ; _32: ; _31: ; _30: ; _29: ; j = libc.Uint32FromInt32(_json5Whitespace(tls, z+uintptr(i))) if j > uint32(0) { i = i + j (*TJsonParse)(unsafe.Pointer(pParse)).FhasNonstd = uint8(1) goto json_parse_restart } (*TJsonParse)(unsafe.Pointer(pParse)).FiErr = i return -int32(1) _37: ; if libc.Xstrncmp(tls, z+uintptr(i), __ccgo_ts+1690, uint64(4)) == 0 && !(libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(z + uintptr(i+uint32(4)))))])&libc.Int32FromInt32(0x06) != 0) { _jsonBlobAppendOneByte(tls, pParse, uint8(JSONB_NULL)) return libc.Int32FromUint32(i + uint32(4)) } /* fall-through into the default case that checks for NaN */ _38: ; c = **(**uint8)(__ccgo_up(z + uintptr(i))) k1 = uint32(0) for { if !(uint64(k1) < libc.Uint64FromInt64(120)/libc.Uint64FromInt64(24)) { break } if libc.Int32FromUint8(c) != libc.Int32FromUint8(_aNanInfName[k1].Fc1) && libc.Int32FromUint8(c) != libc.Int32FromUint8(_aNanInfName[k1].Fc2) { goto _51 } nn = libc.Int32FromUint8(_aNanInfName[k1].Fn) if Xsqlite3_strnicmp(tls, z+uintptr(i), _aNanInfName[k1].FzMatch, nn) != 0 { goto _51 } if libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(z + uintptr(i+libc.Uint32FromInt32(nn)))))])&int32(0x06) != 0 { goto _51 } if libc.Int32FromUint8(_aNanInfName[k1].FeType) == int32(JSONB_FLOAT) { _jsonBlobAppendNode(tls, pParse, uint8(JSONB_FLOAT), uint64(5), __ccgo_ts+26591) } else { _jsonBlobAppendOneByte(tls, pParse, uint8(JSONB_NULL)) } (*TJsonParse)(unsafe.Pointer(pParse)).FhasNonstd = uint8(1) return libc.Int32FromUint32(i + libc.Uint32FromInt32(nn)) goto _51 _51: ; k1 = k1 + 1 } (*TJsonParse)(unsafe.Pointer(pParse)).FiErr = i return -int32(1) /* Syntax error */ _39: ; /* End switch(z[i]) */ return r } // C documentation // // /* // ** Open a file descriptor to the directory containing file zFilename. // ** If successful, *pFd is set to the opened file descriptor and // ** SQLITE_OK is returned. If an error occurs, either SQLITE_NOMEM // ** or SQLITE_CANTOPEN is returned and *pFd is set to an undefined // ** value. // ** // ** The directory file descriptor is used for only one thing - to // ** fsync() a directory to make sure file creation and deletion events // ** are flushed to disk. Such fsyncs are not needed on newer // ** journaling filesystems, but are required on older filesystems. // ** // ** This routine can be overridden using the xSetSysCall interface. // ** The ability to override this routine was added in support of the // ** chromium sandbox. Opening a directory is a security risk (we are // ** told) so making it overrideable allows the chromium sandbox to // ** replace this routine with a harmless no-op. To make this routine // ** a no-op, replace it with a stub that returns SQLITE_OK but leaves // ** *pFd set to a negative number. // ** // ** If SQLITE_OK is returned, the caller is responsible for closing // ** the file descriptor *pFd using close(). // */ func _openDirectory(tls *libc.TLS, zFilename uintptr, pFd uintptr) (r int32) { bp := tls.Alloc(544) defer tls.Free(544) var fd, ii int32 var _ /* zDirname at bp+0 */ [513]uint8 _, _ = fd, ii fd = -int32(1) Xsqlite3_snprintf(tls, int32(MAX_PATHNAME), bp, __ccgo_ts+3968, libc.VaList(bp+528, zFilename)) ii = libc.Int32FromUint64(libc.Xstrlen(tls, bp)) for { if !(ii > 0 && libc.Int32FromUint8((**(**[513]uint8)(__ccgo_up(bp)))[ii]) != int32('/')) { break } goto _1 _1: ; ii = ii - 1 } if ii > 0 { (**(**[513]uint8)(__ccgo_up(bp)))[ii] = uint8('\000') } else { if libc.Int32FromUint8((**(**[513]uint8)(__ccgo_up(bp)))[0]) != int32('/') { (**(**[513]uint8)(__ccgo_up(bp)))[0] = uint8('.') } (**(**[513]uint8)(__ccgo_up(bp)))[int32(1)] = uint8(0) } fd = _robust_open(tls, bp, libc.Int32FromInt32(O_RDONLY)|libc.Int32FromInt32(O_BINARY), uint32(0)) if fd >= 0 { } **(**int32)(__ccgo_up(pFd)) = fd if fd >= 0 { return SQLITE_OK } return _unixLogErrorAtLine(tls, _sqlite3CantopenError(tls, int32(44235)), __ccgo_ts+3659, bp, int32(44235)) } // C documentation // // /* // ** Check if zSuper is a valid super-journal name. There are two valid // ** formats: // ** // ** + The 3rd and 4th last bytes of the filename are ".9", and the // ** following 2 bytes are hex digits. This is a file created in 8.3 // ** filenames mode. // ** // ** + The 3rd last byte of the filename is "9" and the filename // ** contains the string "-mj" starting at the 12th last byte. // ** All bytes following the "-mj" are hex digits. // ** // ** If the filename matches either of these patterns, return non-zero. // ** Otherwise, return zero. // */ func _pagerIsSuperJrnlName(tls *libc.TLS, zSuper uintptr) (r int32) { var ii, nSuper int32 _, _ = ii, nSuper nSuper = _sqlite3Strlen30(tls, zSuper) if nSuper < int32(4) { return 0 } if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zSuper + uintptr(nSuper-int32(3))))) != int32('9') { return 0 } if nSuper < int32(12) { return 0 } if libc.Xmemcmp(tls, zSuper+uintptr(nSuper-int32(12)), __ccgo_ts+4224, uint64(3)) != 0 { return 0 } ii = nSuper - int32(9) for { if !(ii < nSuper) { break } if libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(zSuper + uintptr(ii))))])&int32(0x08) == 0 { return 0 } goto _1 _1: ; ii = ii + 1 } return int32(1) } // C documentation // // /* // ** Pragma virtual table module xConnect method. // */ func _pragmaVtabConnect(tls *libc.TLS, db uintptr, pAux uintptr, argc int32, argv uintptr, ppVtab uintptr, pzErr uintptr) (r int32) { bp := tls.Alloc(256) defer tls.Free(256) var cSep uint8 var i, j, rc int32 var pPragma, pTab uintptr var _ /* acc at bp+0 */ TStrAccum var _ /* zBuf at bp+32 */ [200]uint8 _, _, _, _, _, _ = cSep, i, j, pPragma, pTab, rc pPragma = pAux pTab = uintptr(0) cSep = uint8('(') _ = argc _ = argv _sqlite3StrAccumInit(tls, bp, uintptr(0), bp+32, int32(200), 0) Xsqlite3_str_appendall(tls, bp, __ccgo_ts+19934) i = 0 j = libc.Int32FromUint8((*TPragmaName)(unsafe.Pointer(pPragma)).FiPragCName) for { if !(i < libc.Int32FromUint8((*TPragmaName)(unsafe.Pointer(pPragma)).FnPragCName)) { break } Xsqlite3_str_appendf(tls, bp, __ccgo_ts+19949, libc.VaList(bp+240, libc.Int32FromUint8(cSep), _pragCName[j])) cSep = uint8(',') goto _1 _1: ; i = i + 1 j = j + 1 } if i == 0 { Xsqlite3_str_appendf(tls, bp, __ccgo_ts+19956, libc.VaList(bp+240, (*TPragmaName)(unsafe.Pointer(pPragma)).FzName)) i = i + 1 } j = 0 if libc.Int32FromUint8((*TPragmaName)(unsafe.Pointer(pPragma)).FmPragFlg)&int32(PragFlg_Result1) != 0 { Xsqlite3_str_appendall(tls, bp, __ccgo_ts+19962) j = j + 1 } if libc.Int32FromUint8((*TPragmaName)(unsafe.Pointer(pPragma)).FmPragFlg)&(libc.Int32FromInt32(PragFlg_SchemaOpt)|libc.Int32FromInt32(PragFlg_SchemaReq)) != 0 { Xsqlite3_str_appendall(tls, bp, __ccgo_ts+19974) j = j + 1 } Xsqlite3_str_append(tls, bp, __ccgo_ts+5285, int32(1)) _sqlite3StrAccumFinish(tls, bp) rc = Xsqlite3_declare_vtab(tls, db, bp+32) if rc == SQLITE_OK { pTab = Xsqlite3_malloc(tls, int32(48)) if pTab == uintptr(0) { rc = int32(SQLITE_NOMEM) } else { libc.Xmemset(tls, pTab, 0, uint64(48)) (*TPragmaVtab)(unsafe.Pointer(pTab)).FpName = pPragma (*TPragmaVtab)(unsafe.Pointer(pTab)).Fdb = db (*TPragmaVtab)(unsafe.Pointer(pTab)).FiHidden = libc.Uint8FromInt32(i) (*TPragmaVtab)(unsafe.Pointer(pTab)).FnHidden = libc.Uint8FromInt32(j) } } else { **(**uintptr)(__ccgo_up(pzErr)) = Xsqlite3_mprintf(tls, __ccgo_ts+3968, libc.VaList(bp+240, Xsqlite3_errmsg(tls, db))) } **(**uintptr)(__ccgo_up(ppVtab)) = pTab return rc } // C documentation // // /* // ** If the error code currently stored in the RBU handle is SQLITE_CONSTRAINT, // ** then edit any error message string so as to remove all occurrences of // ** the pattern "rbu_imp_[0-9]*". // */ func _rbuEditErrmsg(tls *libc.TLS, p uintptr) { var i uint32 var nDel int32 var nErrmsg Tsize_t _, _, _ = i, nDel, nErrmsg if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == int32(SQLITE_CONSTRAINT) && (*Tsqlite3rbu)(unsafe.Pointer(p)).FzErrmsg != 0 { nErrmsg = libc.Xstrlen(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FzErrmsg) i = uint32(0) for { if !(uint64(i) < nErrmsg-uint64(8)) { break } if libc.Xmemcmp(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FzErrmsg+uintptr(i), __ccgo_ts+32723, uint64(8)) == 0 { nDel = int32(8) for libc.Int32FromUint8(**(**uint8)(__ccgo_up((*Tsqlite3rbu)(unsafe.Pointer(p)).FzErrmsg + uintptr(i+libc.Uint32FromInt32(nDel))))) >= int32('0') && libc.Int32FromUint8(**(**uint8)(__ccgo_up((*Tsqlite3rbu)(unsafe.Pointer(p)).FzErrmsg + uintptr(i+libc.Uint32FromInt32(nDel))))) <= int32('9') { nDel = nDel + 1 } libc.Xmemmove(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FzErrmsg+uintptr(i), (*Tsqlite3rbu)(unsafe.Pointer(p)).FzErrmsg+uintptr(i+libc.Uint32FromInt32(nDel)), nErrmsg+uint64(1)-uint64(i)-libc.Uint64FromInt32(nDel)) nErrmsg = nErrmsg - libc.Uint64FromInt32(nDel) } goto _1 _1: ; i = i + 1 } } } func _rbuObjIterGetIndexWhere(tls *libc.TLS, p uintptr, pIter uintptr) (r uintptr) { bp := tls.Alloc(16) defer tls.Free(16) var aIdxCol, zRet, zSql, v1 uintptr var c uint8 var i, iIdxCol, nIdxAlloc, nParen, nSpan, nSpan1, rc2, v3 int32 var _ /* pStmt at bp+0 */ uintptr var _ /* rc at bp+8 */ int32 _, _, _, _, _, _, _, _, _, _, _, _, _ = aIdxCol, c, i, iIdxCol, nIdxAlloc, nParen, nSpan, nSpan1, rc2, zRet, zSql, v1, v3 **(**uintptr)(__ccgo_up(bp)) = uintptr(0) **(**int32)(__ccgo_up(bp + 8)) = (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc zRet = uintptr(0) if **(**int32)(__ccgo_up(bp + 8)) == SQLITE_OK { **(**int32)(__ccgo_up(bp + 8)) = _prepareAndCollectError(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, bp, p+64, __ccgo_ts+32211) } if **(**int32)(__ccgo_up(bp + 8)) == SQLITE_OK { **(**int32)(__ccgo_up(bp + 8)) = Xsqlite3_bind_text(tls, **(**uintptr)(__ccgo_up(bp)), int32(1), (*TRbuObjIter)(unsafe.Pointer(pIter)).FzIdx, -int32(1), libc.UintptrFromInt32(0)) if **(**int32)(__ccgo_up(bp + 8)) == SQLITE_OK && int32(SQLITE_ROW) == Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp))) { zSql = Xsqlite3_column_text(tls, **(**uintptr)(__ccgo_up(bp)), 0) if zSql != 0 { v1 = _rbuStrndup(tls, zSql, bp+8) zSql = v1 (*TRbuObjIter)(unsafe.Pointer(pIter)).FzIdxSql = v1 } if zSql != 0 { nParen = 0 iIdxCol = 0 nIdxAlloc = 0 i = 0 for { if !(**(**uint8)(__ccgo_up(zSql + uintptr(i))) != 0) { break } c = **(**uint8)(__ccgo_up(zSql + uintptr(i))) /* If necessary, grow the pIter->aIdxCol[] array */ if iIdxCol == nIdxAlloc { aIdxCol = Xsqlite3_realloc64(tls, (*TRbuObjIter)(unsafe.Pointer(pIter)).FaIdxCol, uint64(libc.Uint64FromInt32(nIdxAlloc)*uint64(16)+libc.Uint64FromInt32(16)*libc.Uint64FromInt64(16))) if aIdxCol == uintptr(0) { **(**int32)(__ccgo_up(bp + 8)) = int32(SQLITE_NOMEM) break } (*TRbuObjIter)(unsafe.Pointer(pIter)).FaIdxCol = aIdxCol nIdxAlloc = nIdxAlloc + int32(16) } if libc.Int32FromUint8(c) == int32('(') { if nParen == 0 { (**(**TRbuSpan)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FaIdxCol))).FzSpan = zSql + uintptr(i+int32(1)) } nParen = nParen + 1 } else { if libc.Int32FromUint8(c) == int32(')') { nParen = nParen - 1 if nParen == 0 { nSpan = int32(t__predefined_ptrdiff_t(zSql+uintptr(i)) - int64((**(**TRbuSpan)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FaIdxCol + uintptr(iIdxCol)*16))).FzSpan)) v3 = iIdxCol iIdxCol = iIdxCol + 1 (**(**TRbuSpan)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FaIdxCol + uintptr(v3)*16))).FnSpan = nSpan i = i + 1 break } } else { if libc.Int32FromUint8(c) == int32(',') && nParen == int32(1) { nSpan1 = int32(t__predefined_ptrdiff_t(zSql+uintptr(i)) - int64((**(**TRbuSpan)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FaIdxCol + uintptr(iIdxCol)*16))).FzSpan)) v3 = iIdxCol iIdxCol = iIdxCol + 1 (**(**TRbuSpan)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FaIdxCol + uintptr(v3)*16))).FnSpan = nSpan1 (**(**TRbuSpan)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FaIdxCol + uintptr(iIdxCol)*16))).FzSpan = zSql + uintptr(i+int32(1)) } else { if libc.Int32FromUint8(c) == int32('"') || libc.Int32FromUint8(c) == int32('\'') || libc.Int32FromUint8(c) == int32('`') { i = i + 1 for { if !(int32(1) != 0) { break } if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zSql + uintptr(i)))) == libc.Int32FromUint8(c) { if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zSql + uintptr(i+int32(1))))) != libc.Int32FromUint8(c) { break } i = i + 1 } goto _5 _5: ; i = i + 1 } } else { if libc.Int32FromUint8(c) == int32('[') { i = i + 1 for { if !(int32(1) != 0) { break } if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zSql + uintptr(i)))) == int32(']') { break } goto _6 _6: ; i = i + 1 } } else { if libc.Int32FromUint8(c) == int32('-') && libc.Int32FromUint8(**(**uint8)(__ccgo_up(zSql + uintptr(i+int32(1))))) == int32('-') { i = i + int32(2) for { if !(**(**uint8)(__ccgo_up(zSql + uintptr(i))) != 0 && libc.Int32FromUint8(**(**uint8)(__ccgo_up(zSql + uintptr(i)))) != int32('\n')) { break } goto _7 _7: ; i = i + 1 } if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zSql + uintptr(i)))) == int32('\000') { break } } else { if libc.Int32FromUint8(c) == int32('/') && libc.Int32FromUint8(**(**uint8)(__ccgo_up(zSql + uintptr(i+int32(1))))) == int32('*') { i = i + int32(2) for { if !(**(**uint8)(__ccgo_up(zSql + uintptr(i))) != 0 && (libc.Int32FromUint8(**(**uint8)(__ccgo_up(zSql + uintptr(i)))) != int32('*') || libc.Int32FromUint8(**(**uint8)(__ccgo_up(zSql + uintptr(i+int32(1))))) != int32('/'))) { break } goto _8 _8: ; i = i + 1 } if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zSql + uintptr(i)))) == int32('\000') { break } i = i + 1 } } } } } } } goto _2 _2: ; i = i + 1 } if **(**uint8)(__ccgo_up(zSql + uintptr(i))) != 0 { zRet = _rbuStrndup(tls, zSql+uintptr(i), bp+8) } (*TRbuObjIter)(unsafe.Pointer(pIter)).FnIdxCol = iIdxCol } } rc2 = Xsqlite3_finalize(tls, **(**uintptr)(__ccgo_up(bp))) if **(**int32)(__ccgo_up(bp + 8)) == SQLITE_OK { **(**int32)(__ccgo_up(bp + 8)) = rc2 } } (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = **(**int32)(__ccgo_up(bp + 8)) return zRet } // C documentation // // /* // ** Return a nul-terminated string containing the comma separated list of // ** assignments that should be included following the "SET" keyword of // ** an UPDATE statement used to update the table object that the iterator // ** passed as the second argument currently points to if the rbu_control // ** column of the data_xxx table entry is set to zMask. // ** // ** The memory for the returned string is obtained from sqlite3_malloc(). // ** It is the responsibility of the caller to eventually free it using // ** sqlite3_free(). // ** // ** If an OOM error is encountered when allocating space for the new // ** string, an error code is left in the rbu handle passed as the first // ** argument and NULL is returned. Or, if an error has already occurred // ** when this function is called, NULL is returned immediately, without // ** attempting the allocation or modifying the stored error code. // */ func _rbuObjIterGetSetlist(tls *libc.TLS, p uintptr, pIter uintptr, zMask uintptr) (r uintptr) { bp := tls.Alloc(48) defer tls.Free(48) var c uint8 var i int32 var zList, zSep uintptr _, _, _, _ = c, i, zList, zSep zList = uintptr(0) if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK { if libc.Int32FromUint64(libc.Xstrlen(tls, zMask)) != (*TRbuObjIter)(unsafe.Pointer(pIter)).FnTblCol { _rbuBadControlError(tls, p) } else { zSep = __ccgo_ts + 1704 i = 0 for { if !(i < (*TRbuObjIter)(unsafe.Pointer(pIter)).FnTblCol) { break } c = **(**uint8)(__ccgo_up(zMask + uintptr(**(**int32)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FaiSrcOrder + uintptr(i)*4))))) if libc.Int32FromUint8(c) == int32('x') { zList = _rbuMPrintf(tls, p, __ccgo_ts+31757, libc.VaList(bp+8, zList, zSep, **(**uintptr)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FazTblCol + uintptr(i)*8)), i+int32(1))) zSep = __ccgo_ts + 16242 } else { if libc.Int32FromUint8(c) == int32('d') { zList = _rbuMPrintf(tls, p, __ccgo_ts+31796, libc.VaList(bp+8, zList, zSep, **(**uintptr)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FazTblCol + uintptr(i)*8)), **(**uintptr)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FazTblCol + uintptr(i)*8)), i+int32(1))) zSep = __ccgo_ts + 16242 } else { if libc.Int32FromUint8(c) == int32('f') { zList = _rbuMPrintf(tls, p, __ccgo_ts+31826, libc.VaList(bp+8, zList, zSep, **(**uintptr)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FazTblCol + uintptr(i)*8)), **(**uintptr)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FazTblCol + uintptr(i)*8)), i+int32(1))) zSep = __ccgo_ts + 16242 } } } goto _1 _1: ; i = i + 1 } } } return zList } // C documentation // // /* // ** Open the database handle and attach the RBU database as "rbu". If an // ** error occurs, leave an error code and message in the RBU handle. // ** // ** If argument dbMain is not NULL, then it is a database handle already // ** open on the target database. Use this handle instead of opening a new // ** one. // */ func _rbuOpenDatabase(tls *libc.TLS, p uintptr, dbMain uintptr, pbRetry uintptr) { bp := tls.Alloc(32) defer tls.Free(32) var bOpen, rc int32 var pState, zExtra, zFile, zTarget, v1, v2 uintptr _, _, _, _, _, _, _, _ = bOpen, pState, rc, zExtra, zFile, zTarget, v1, v2 /* Open the RBU database */ (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbRbu = _rbuOpenDbhandle(tls, p, (*Tsqlite3rbu)(unsafe.Pointer(p)).FzRbu, int32(1)) (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain = dbMain if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK && (*Tsqlite3rbu)(unsafe.Pointer(p)).FzTarget == uintptr(0) { Xsqlite3_file_control(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbRbu, __ccgo_ts+6844, int32(SQLITE_FCNTL_RBUCNT), p) if (*Tsqlite3rbu)(unsafe.Pointer(p)).FzState == uintptr(0) { zFile = Xsqlite3_db_filename(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbRbu, __ccgo_ts+6844) (*Tsqlite3rbu)(unsafe.Pointer(p)).FzState = _rbuMPrintf(tls, p, __ccgo_ts+33444, libc.VaList(bp+8, zFile, zFile)) } } /* If using separate RBU and state databases, attach the state database to ** the RBU db handle now. */ if (*Tsqlite3rbu)(unsafe.Pointer(p)).FzState != 0 { _rbuMPrintfExec(tls, p, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbRbu, __ccgo_ts+33472, libc.VaList(bp+8, (*Tsqlite3rbu)(unsafe.Pointer(p)).FzState)) libc.Xmemcpy(tls, p+48, __ccgo_ts+3567, uint64(4)) } else { libc.Xmemcpy(tls, p+48, __ccgo_ts+6844, uint64(4)) } /* If it has not already been created, create the rbu_state table */ _rbuMPrintfExec(tls, p, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbRbu, __ccgo_ts+33490, libc.VaList(bp+8, p+48)) if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK && (*Tsqlite3rbu)(unsafe.Pointer(p)).FzTarget == uintptr(0) { bOpen = 0 (*Tsqlite3rbu)(unsafe.Pointer(p)).FnRbu = 0 (*Tsqlite3rbu)(unsafe.Pointer(p)).FpRbuFd = uintptr(0) rc = Xsqlite3_file_control(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbRbu, __ccgo_ts+6844, int32(SQLITE_FCNTL_RBUCNT), p) if rc != int32(SQLITE_NOTFOUND) { (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = rc } if (*Tsqlite3rbu)(unsafe.Pointer(p)).FeStage >= int32(RBU_STAGE_MOVE) { bOpen = int32(1) } else { pState = _rbuLoadState(tls, p) if pState != 0 { bOpen = libc.BoolInt32((*TRbuState)(unsafe.Pointer(pState)).FeStage >= int32(RBU_STAGE_MOVE)) _rbuFreeState(tls, pState) } } if bOpen != 0 { (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain = _rbuOpenDbhandle(tls, p, (*Tsqlite3rbu)(unsafe.Pointer(p)).FzRbu, libc.BoolInt32((*Tsqlite3rbu)(unsafe.Pointer(p)).FnRbu <= int32(1))) } } (*Tsqlite3rbu)(unsafe.Pointer(p)).FeStage = 0 if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK && (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain == uintptr(0) { if !((*Tsqlite3rbu)(unsafe.Pointer(p)).FzTarget == libc.UintptrFromInt32(0)) { (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain = _rbuOpenDbhandle(tls, p, (*Tsqlite3rbu)(unsafe.Pointer(p)).FzTarget, int32(1)) } else { if (*Trbu_file)(unsafe.Pointer((*Tsqlite3rbu)(unsafe.Pointer(p)).FpRbuFd)).FpWalFd != 0 { if pbRetry != 0 { (*Trbu_file)(unsafe.Pointer((*Tsqlite3rbu)(unsafe.Pointer(p)).FpRbuFd)).FbNolock = uint8(0) Xsqlite3_close(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbRbu) Xsqlite3_close(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain) (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain = uintptr(0) (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbRbu = uintptr(0) **(**int32)(__ccgo_up(pbRetry)) = int32(1) return } (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = int32(SQLITE_ERROR) (*Tsqlite3rbu)(unsafe.Pointer(p)).FzErrmsg = Xsqlite3_mprintf(tls, __ccgo_ts+33556, 0) } else { zExtra = uintptr(0) if libc.Xstrlen(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FzRbu) >= uint64(5) && 0 == libc.Xmemcmp(tls, __ccgo_ts+26142, (*Tsqlite3rbu)(unsafe.Pointer(p)).FzRbu, uint64(5)) { zExtra = (*Tsqlite3rbu)(unsafe.Pointer(p)).FzRbu + 5 for **(**uint8)(__ccgo_up(zExtra)) != 0 { v1 = zExtra zExtra = zExtra + 1 if libc.Int32FromUint8(**(**uint8)(__ccgo_up(v1))) == int32('?') { break } } if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zExtra))) == int32('\000') { zExtra = uintptr(0) } } if zExtra == uintptr(0) { v1 = __ccgo_ts + 1704 } else { v1 = __ccgo_ts + 33588 } if zExtra == uintptr(0) { v2 = __ccgo_ts + 1704 } else { v2 = zExtra } zTarget = Xsqlite3_mprintf(tls, __ccgo_ts+33590, libc.VaList(bp+8, Xsqlite3_db_filename(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbRbu, __ccgo_ts+6844), v1, v2)) if zTarget == uintptr(0) { (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = int32(SQLITE_NOMEM) return } (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain = _rbuOpenDbhandle(tls, p, zTarget, libc.BoolInt32((*Tsqlite3rbu)(unsafe.Pointer(p)).FnRbu <= int32(1))) Xsqlite3_free(tls, zTarget) } } } if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK { (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = Xsqlite3_create_function(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, __ccgo_ts+33622, -int32(1), int32(SQLITE_UTF8), p, __ccgo_fp(_rbuTmpInsertFunc), uintptr(0), uintptr(0)) } if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK { (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = Xsqlite3_create_function(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, __ccgo_ts+33637, int32(2), int32(SQLITE_UTF8), uintptr(0), __ccgo_fp(_rbuFossilDeltaFunc), uintptr(0), uintptr(0)) } if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK { (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = Xsqlite3_create_function(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbRbu, __ccgo_ts+33654, -int32(1), int32(SQLITE_UTF8), p, __ccgo_fp(_rbuTargetNameFunc), uintptr(0), uintptr(0)) } if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK { (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = Xsqlite3_file_control(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, __ccgo_ts+6844, int32(SQLITE_FCNTL_RBU), p) } _rbuMPrintfExec(tls, p, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, __ccgo_ts+33670, 0) /* Mark the database file just opened as an RBU target database. If ** this call returns SQLITE_NOTFOUND, then the RBU vfs is not in use. ** This is an error. */ if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK { (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = Xsqlite3_file_control(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, __ccgo_ts+6844, int32(SQLITE_FCNTL_RBU), p) } if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == int32(SQLITE_NOTFOUND) { (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = int32(SQLITE_ERROR) (*Tsqlite3rbu)(unsafe.Pointer(p)).FzErrmsg = Xsqlite3_mprintf(tls, __ccgo_ts+33698, 0) } } // C documentation // // /* // ** The implementation of the rbu_target_name() SQL function. This function // ** accepts one or two arguments. The first argument is the name of a table - // ** the name of a table in the RBU database. The second, if it is present, is 1 // ** for a view or 0 for a table. // ** // ** For a non-vacuum RBU handle, if the table name matches the pattern: // ** // ** data[0-9]_ // ** // ** where is any sequence of 1 or more characters, is returned. // ** Otherwise, if the only argument does not match the above pattern, an SQL // ** NULL is returned. // ** // ** "data_t1" -> "t1" // ** "data0123_t2" -> "t2" // ** "dataAB_t3" -> NULL // ** // ** For an rbu vacuum handle, a copy of the first argument is returned if // ** the second argument is either missing or 0 (not a view). // */ func _rbuTargetNameFunc(tls *libc.TLS, pCtx uintptr, argc int32, argv uintptr) { var i int32 var p, zIn uintptr _, _, _ = i, p, zIn p = Xsqlite3_user_data(tls, pCtx) zIn = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv))) if zIn != 0 { if (*Tsqlite3rbu)(unsafe.Pointer(p)).FzTarget == uintptr(0) { if argc == int32(1) || 0 == Xsqlite3_value_int(tls, **(**uintptr)(__ccgo_up(argv + 1*8))) { Xsqlite3_result_text(tls, pCtx, zIn, -int32(1), libc.UintptrFromInt32(0)) } } else { if libc.Xstrlen(tls, zIn) > uint64(4) && libc.Xmemcmp(tls, __ccgo_ts+27432, zIn, uint64(4)) == 0 { i = int32(4) for { if !(libc.Int32FromUint8(**(**uint8)(__ccgo_up(zIn + uintptr(i)))) >= int32('0') && libc.Int32FromUint8(**(**uint8)(__ccgo_up(zIn + uintptr(i)))) <= int32('9')) { break } goto _1 _1: ; i = i + 1 } if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zIn + uintptr(i)))) == int32('_') && **(**uint8)(__ccgo_up(zIn + uintptr(i+int32(1)))) != 0 { Xsqlite3_result_text(tls, pCtx, zIn+uintptr(i+int32(1)), -int32(1), libc.UintptrFromInt32(0)) } } } } } // C documentation // // /* // ** This function is called as part of restating an RBU vacuum when the // ** current operation is writing content to an index. If possible, it // ** queries the target index b-tree for the largest key already written to // ** it, then composes and returns an expression that can be used in a WHERE // ** clause to select the remaining required rows from the source table. // ** It is only possible to return such an expression if: // ** // ** * The index contains no DESC columns, and // ** * The last key written to the index before the operation was // ** suspended does not contain any NULL values. // ** // ** The expression is of the form: // ** // ** (index-field1, index-field2, ...) > (?, ?, ...) // ** // ** except that the "?" placeholders are replaced with literal values. // ** // ** If the expression cannot be created, NULL is returned. In this case, // ** the caller has to use an OFFSET clause to extract only the required // ** rows from the sourct table, just as it does for an RBU update operation. // */ func _rbuVacuumIndexStart(tls *libc.TLS, p uintptr, pIter uintptr) (r uintptr) { bp := tls.Alloc(64) defer tls.Free(64) var bFailed, i, iCid, iCol int32 var zCol, zCollate, zLhs, zOrder, zQuoted, zRet, zSelect, zSep, zVector uintptr var _ /* pSel at bp+8 */ uintptr var _ /* pXInfo at bp+0 */ uintptr _, _, _, _, _, _, _, _, _, _, _, _, _ = bFailed, i, iCid, iCol, zCol, zCollate, zLhs, zOrder, zQuoted, zRet, zSelect, zSep, zVector zOrder = uintptr(0) zLhs = uintptr(0) zSelect = uintptr(0) zVector = uintptr(0) zRet = uintptr(0) bFailed = 0 zSep = __ccgo_ts + 1704 iCol = 0 **(**uintptr)(__ccgo_up(bp)) = uintptr(0) (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = _prepareFreeAndCollectError(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, bp, p+64, Xsqlite3_mprintf(tls, __ccgo_ts+31043, libc.VaList(bp+24, (*TRbuObjIter)(unsafe.Pointer(pIter)).FzIdx))) for (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK && int32(SQLITE_ROW) == Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp))) { iCid = Xsqlite3_column_int(tls, **(**uintptr)(__ccgo_up(bp)), int32(1)) zCollate = Xsqlite3_column_text(tls, **(**uintptr)(__ccgo_up(bp)), int32(4)) if Xsqlite3_column_int(tls, **(**uintptr)(__ccgo_up(bp)), int32(3)) != 0 { bFailed = int32(1) break } if iCid < 0 { if (*TRbuObjIter)(unsafe.Pointer(pIter)).FeType == int32(RBU_PK_IPK) { i = 0 for { if !(libc.Int32FromUint8(**(**Tu8)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FabTblPk + uintptr(i)))) == 0) { break } goto _1 _1: ; i = i + 1 } zCol = **(**uintptr)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FazTblCol + uintptr(i)*8)) } else { zCol = __ccgo_ts + 31366 } } else { zCol = **(**uintptr)(__ccgo_up((*TRbuObjIter)(unsafe.Pointer(pIter)).FazTblCol + uintptr(iCid)*8)) } zLhs = _rbuMPrintf(tls, p, __ccgo_ts+31374, libc.VaList(bp+24, zLhs, zSep, zCol, zCollate)) zOrder = _rbuMPrintf(tls, p, __ccgo_ts+31395, libc.VaList(bp+24, zOrder, zSep, iCol, zCol, zCollate)) zSelect = _rbuMPrintf(tls, p, __ccgo_ts+31431, libc.VaList(bp+24, zSelect, zSep, iCol, zCol)) zSep = __ccgo_ts + 16242 iCol = iCol + 1 } _rbuFinalize(tls, p, **(**uintptr)(__ccgo_up(bp))) if bFailed != 0 { goto index_start_out } if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK { **(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0) (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = _prepareFreeAndCollectError(tls, (*Tsqlite3rbu)(unsafe.Pointer(p)).FdbMain, bp+8, p+64, Xsqlite3_mprintf(tls, __ccgo_ts+31458, libc.VaList(bp+24, zSelect, (*TRbuObjIter)(unsafe.Pointer(pIter)).FzTbl, zOrder))) if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK && int32(SQLITE_ROW) == Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp + 8))) { zSep = __ccgo_ts + 1704 iCol = 0 for { if !(iCol < (*TRbuObjIter)(unsafe.Pointer(pIter)).FnCol) { break } zQuoted = Xsqlite3_column_text(tls, **(**uintptr)(__ccgo_up(bp + 8)), iCol) if zQuoted == uintptr(0) { (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = int32(SQLITE_NOMEM) } else { if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zQuoted))) == int32('N') { bFailed = int32(1) break } } zVector = _rbuMPrintf(tls, p, __ccgo_ts+31506, libc.VaList(bp+24, zVector, zSep, zQuoted)) zSep = __ccgo_ts + 16242 goto _2 _2: ; iCol = iCol + 1 } if !(bFailed != 0) { zRet = _rbuMPrintf(tls, p, __ccgo_ts+31513, libc.VaList(bp+24, zLhs, zVector)) } } _rbuFinalize(tls, p, **(**uintptr)(__ccgo_up(bp + 8))) } goto index_start_out index_start_out: ; Xsqlite3_free(tls, zOrder) Xsqlite3_free(tls, zSelect) Xsqlite3_free(tls, zVector) Xsqlite3_free(tls, zLhs) return zRet } // C documentation // // /* // ** Open an rbu file handle. // */ func _rbuVfsOpen(tls *libc.TLS, pVfs uintptr, zName uintptr, pFile uintptr, flags int32, pOutFlags uintptr) (r int32) { var nOpen Tsize_t var oflags, rc int32 var pDb, pFd, pMeth, pRbuVfs, pRealVfs, zOpen uintptr _, _, _, _, _, _, _, _, _ = nOpen, oflags, pDb, pFd, pMeth, pRbuVfs, pRealVfs, rc, zOpen pRbuVfs = pVfs pRealVfs = (*Trbu_vfs)(unsafe.Pointer(pRbuVfs)).FpRealVfs pFd = pFile rc = SQLITE_OK zOpen = zName oflags = flags libc.Xmemset(tls, pFd, 0, uint64(104)) (*Trbu_file)(unsafe.Pointer(pFd)).FpReal = pFd + 1*104 (*Trbu_file)(unsafe.Pointer(pFd)).FpRbuVfs = pRbuVfs (*Trbu_file)(unsafe.Pointer(pFd)).FopenFlags = flags if zName != 0 { if flags&int32(SQLITE_OPEN_MAIN_DB) != 0 { /* A main database has just been opened. The following block sets ** (pFd->zWal) to point to a buffer owned by SQLite that contains ** the name of the *-wal file this db connection will use. SQLite ** happens to pass a pointer to this buffer when using xAccess() ** or xOpen() to operate on the *-wal file. */ (*Trbu_file)(unsafe.Pointer(pFd)).FzWal = Xsqlite3_filename_wal(tls, zName) } else { if flags&int32(SQLITE_OPEN_WAL) != 0 { pDb = _rbuFindMaindb(tls, pRbuVfs, zName, 0) if pDb != 0 { if (*Trbu_file)(unsafe.Pointer(pDb)).FpRbu != 0 && (*Tsqlite3rbu)(unsafe.Pointer((*Trbu_file)(unsafe.Pointer(pDb)).FpRbu)).FeStage == int32(RBU_STAGE_OAL) { if (*Tsqlite3rbu)(unsafe.Pointer((*Trbu_file)(unsafe.Pointer(pDb)).FpRbu)).FzTarget == uintptr(0) { zOpen = Xsqlite3_db_filename(tls, (*Tsqlite3rbu)(unsafe.Pointer((*Trbu_file)(unsafe.Pointer(pDb)).FpRbu)).FdbRbu, __ccgo_ts+6844) zOpen = Xsqlite3_filename_wal(tls, zOpen) } nOpen = libc.Xstrlen(tls, zOpen) **(**uint8)(__ccgo_up(zOpen + uintptr(nOpen-uint64(3)))) = uint8('o') (*Trbu_file)(unsafe.Pointer(pFd)).FpRbu = (*Trbu_file)(unsafe.Pointer(pDb)).FpRbu } (*Trbu_file)(unsafe.Pointer(pDb)).FpWalFd = pFd } } } } else { (*Trbu_file)(unsafe.Pointer(pFd)).FpRbu = (*Trbu_vfs)(unsafe.Pointer(pRbuVfs)).FpRbu } if oflags&int32(SQLITE_OPEN_MAIN_DB) != 0 && Xsqlite3_uri_boolean(tls, zName, __ccgo_ts+34769, 0) != 0 { oflags = libc.Int32FromInt32(SQLITE_OPEN_TEMP_DB) | libc.Int32FromInt32(SQLITE_OPEN_READWRITE) | libc.Int32FromInt32(SQLITE_OPEN_CREATE) | libc.Int32FromInt32(SQLITE_OPEN_EXCLUSIVE) | libc.Int32FromInt32(SQLITE_OPEN_DELETEONCLOSE) zOpen = uintptr(0) } if rc == SQLITE_OK { rc = (*(*func(*libc.TLS, uintptr, Tsqlite3_filename, uintptr, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*Tsqlite3_vfs)(unsafe.Pointer(pRealVfs)).FxOpen})))(tls, pRealVfs, zOpen, (*Trbu_file)(unsafe.Pointer(pFd)).FpReal, oflags, pOutFlags) } if (*Tsqlite3_file)(unsafe.Pointer((*Trbu_file)(unsafe.Pointer(pFd)).FpReal)).FpMethods != 0 { pMeth = (*Tsqlite3_file)(unsafe.Pointer((*Trbu_file)(unsafe.Pointer(pFd)).FpReal)).FpMethods /* The xOpen() operation has succeeded. Set the sqlite3_file.pMethods ** pointer and, if the file is a main database file, link it into the ** mutex protected linked list of all such files. */ if (*Tsqlite3_io_methods)(unsafe.Pointer(pMeth)).FiVersion < int32(2) || (*Tsqlite3_io_methods)(unsafe.Pointer(pMeth)).FxShmLock == uintptr(0) { (*Tsqlite3_file)(unsafe.Pointer(pFile)).FpMethods = uintptr(unsafe.Pointer(&_rbuvfs_io_methods1)) } else { (*Tsqlite3_file)(unsafe.Pointer(pFile)).FpMethods = uintptr(unsafe.Pointer(&_rbuvfs_io_methods)) } if flags&int32(SQLITE_OPEN_MAIN_DB) != 0 { _rbuMainlistAdd(tls, pFd) } } else { Xsqlite3_free(tls, (*Trbu_file)(unsafe.Pointer(pFd)).FzDel) } return rc } // C documentation // // /* // ** This function edits SQL statement zSql, replacing each token identified // ** by the linked list pRename with the text of zNew. If argument bQuote is // ** true, then zNew is always quoted first. If no error occurs, the result // ** is loaded into context object pCtx as the result. // ** // ** Or, if an error occurs (i.e. an OOM condition), an error is left in // ** pCtx and an SQLite error code returned. // */ func _renameEditSql(tls *libc.TLS, pCtx uintptr, pRename uintptr, zSql uintptr, zNew uintptr, bQuote int32) (r int32) { bp := tls.Alloc(32) defer tls.Free(32) var db, pBest, zBuf1, zBuf2, zOut, zQuot, zReplace, v1 uintptr var iOff, rc int32 var nNew, nOut, nQuot, nReplace, nSql Ti64 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = db, iOff, nNew, nOut, nQuot, nReplace, nSql, pBest, rc, zBuf1, zBuf2, zOut, zQuot, zReplace, v1 nNew = int64(_sqlite3Strlen30(tls, zNew)) nSql = int64(_sqlite3Strlen30(tls, zSql)) db = Xsqlite3_context_db_handle(tls, pCtx) rc = SQLITE_OK zQuot = uintptr(0) nQuot = 0 zBuf1 = uintptr(0) zBuf2 = uintptr(0) if zNew != 0 { /* Set zQuot to point to a buffer containing a quoted copy of the ** identifier zNew. If the corresponding identifier in the original ** ALTER TABLE statement was quoted (bQuote==1), then set zNew to ** point to zQuot so that all substitutions are made using the ** quoted version of the new column name. */ zQuot = _sqlite3MPrintf(tls, db, __ccgo_ts+11602, libc.VaList(bp+8, zNew)) if zQuot == uintptr(0) { return int32(SQLITE_NOMEM) } else { nQuot = int64(_sqlite3Strlen30(tls, zQuot) - int32(1)) } zOut = _sqlite3DbMallocZero(tls, db, libc.Uint64FromInt64(nSql)+libc.Uint64FromInt32((*TRenameCtx)(unsafe.Pointer(pRename)).FnList)*libc.Uint64FromInt64(nQuot)+uint64(1)) } else { zOut = _sqlite3DbMallocZero(tls, db, (uint64(2)*libc.Uint64FromInt64(nSql)+uint64(1))*uint64(3)) if zOut != 0 { zBuf1 = zOut + uintptr(nSql*int64(2)+int64(1)) zBuf2 = zOut + uintptr(nSql*int64(4)+int64(2)) } } /* At this point pRename->pList contains a list of RenameToken objects ** corresponding to all tokens in the input SQL that must be replaced ** with the new column name, or with single-quoted versions of themselves. ** All that remains is to construct and return the edited SQL string. */ if zOut != 0 { nOut = nSql libc.Xmemcpy(tls, zOut, zSql, libc.Uint64FromInt64(nSql)) for (*TRenameCtx)(unsafe.Pointer(pRename)).FpList != 0 { pBest = _renameColumnTokenNext(tls, pRename) if zNew != 0 { if bQuote == 0 && _sqlite3IsIdChar(tls, **(**Tu8)(__ccgo_up((*TRenameToken)(unsafe.Pointer(pBest)).Ft.Fz))) != 0 { nReplace = nNew zReplace = zNew } else { nReplace = nQuot zReplace = zQuot if libc.Int32FromUint8(**(**uint8)(__ccgo_up((*TRenameToken)(unsafe.Pointer(pBest)).Ft.Fz + uintptr((*TRenameToken)(unsafe.Pointer(pBest)).Ft.Fn)))) == int32('"') { nReplace = nReplace + 1 } } } else { /* Dequote the double-quoted token. Then requote it again, this time ** using single quotes. If the character immediately following the ** original token within the input SQL was a single quote ('), then ** add another space after the new, single-quoted version of the ** token. This is so that (SELECT "string"'alias') maps to ** (SELECT 'string' 'alias'), and not (SELECT 'string''alias'). */ libc.Xmemcpy(tls, zBuf1, (*TRenameToken)(unsafe.Pointer(pBest)).Ft.Fz, uint64((*TRenameToken)(unsafe.Pointer(pBest)).Ft.Fn)) **(**uint8)(__ccgo_up(zBuf1 + uintptr((*TRenameToken)(unsafe.Pointer(pBest)).Ft.Fn))) = uint8(0) _sqlite3Dequote(tls, zBuf1) if libc.Int32FromUint8(**(**uint8)(__ccgo_up((*TRenameToken)(unsafe.Pointer(pBest)).Ft.Fz + uintptr((*TRenameToken)(unsafe.Pointer(pBest)).Ft.Fn)))) == int32('\'') { v1 = __ccgo_ts + 11569 } else { v1 = __ccgo_ts + 1704 } Xsqlite3_snprintf(tls, int32(nSql*libc.Int64FromInt32(2)), zBuf2, __ccgo_ts+11608, libc.VaList(bp+8, zBuf1, v1)) zReplace = zBuf2 nReplace = int64(_sqlite3Strlen30(tls, zReplace)) } iOff = int32(int64((*TRenameToken)(unsafe.Pointer(pBest)).Ft.Fz) - int64(zSql)) if libc.Int64FromUint32((*TRenameToken)(unsafe.Pointer(pBest)).Ft.Fn) != nReplace { libc.Xmemmove(tls, zOut+uintptr(int64(iOff)+nReplace), zOut+uintptr(libc.Uint32FromInt32(iOff)+(*TRenameToken)(unsafe.Pointer(pBest)).Ft.Fn), libc.Uint64FromInt64(nOut-libc.Int64FromUint32(libc.Uint32FromInt32(iOff)+(*TRenameToken)(unsafe.Pointer(pBest)).Ft.Fn))) nOut = nOut + (nReplace - libc.Int64FromUint32((*TRenameToken)(unsafe.Pointer(pBest)).Ft.Fn)) **(**uint8)(__ccgo_up(zOut + uintptr(nOut))) = uint8('\000') } libc.Xmemcpy(tls, zOut+uintptr(iOff), zReplace, libc.Uint64FromInt64(nReplace)) _sqlite3DbFree(tls, db, pBest) } Xsqlite3_result_text(tls, pCtx, zOut, -int32(1), uintptr(-libc.Int32FromInt32(1))) _sqlite3DbFree(tls, db, zOut) } else { rc = int32(SQLITE_NOMEM) } Xsqlite3_free(tls, zQuot) return rc } // C documentation // // /* // ** This function is the implementation of both the xConnect and xCreate // ** methods of the r-tree virtual table. // ** // ** argv[0] -> module name // ** argv[1] -> database name // ** argv[2] -> table name // ** argv[...] -> column names... // */ func _rtreeInit(tls *libc.TLS, db uintptr, pAux uintptr, argc int32, argv uintptr, ppVtab uintptr, pzErr uintptr, isCreate int32) (r int32) { bp := tls.Alloc(32) defer tls.Free(32) var aErrMsg [5]uintptr var eCoordType, iErr, ii, nDb, nName, rc, v1 int32 var pRtree, pSql, zArg, zSql uintptr _, _, _, _, _, _, _, _, _, _, _, _ = aErrMsg, eCoordType, iErr, ii, nDb, nName, pRtree, pSql, rc, zArg, zSql, v1 rc = SQLITE_OK if pAux != 0 { v1 = int32(RTREE_COORD_INT32) } else { v1 = RTREE_COORD_REAL32 } /* Length of string argv[2] */ eCoordType = v1 ii = int32(4) aErrMsg = [5]uintptr{ 1: __ccgo_ts + 28825, 2: __ccgo_ts + 28868, 3: __ccgo_ts + 28903, 4: __ccgo_ts + 28939, } if argc < int32(6) || argc > libc.Int32FromInt32(RTREE_MAX_AUX_COLUMN)+libc.Int32FromInt32(3) { **(**uintptr)(__ccgo_up(pzErr)) = Xsqlite3_mprintf(tls, __ccgo_ts+3968, libc.VaList(bp+8, aErrMsg[int32(2)+libc.BoolInt32(argc >= int32(6))])) return int32(SQLITE_ERROR) } Xsqlite3_vtab_config(tls, db, int32(SQLITE_VTAB_CONSTRAINT_SUPPORT), libc.VaList(bp+8, int32(1))) Xsqlite3_vtab_config(tls, db, int32(SQLITE_VTAB_INNOCUOUS), 0) /* Allocate the sqlite3_vtab structure */ nDb = libc.Int32FromUint64(libc.Xstrlen(tls, **(**uintptr)(__ccgo_up(argv + 1*8)))) nName = libc.Int32FromUint64(libc.Xstrlen(tls, **(**uintptr)(__ccgo_up(argv + 2*8)))) pRtree = Xsqlite3_malloc64(tls, uint64(uint64(976)+libc.Uint64FromInt32(nDb)+libc.Uint64FromInt32(nName*int32(2))+uint64(8))) if !(pRtree != 0) { return int32(SQLITE_NOMEM) } libc.Xmemset(tls, pRtree, 0, uint64(976)+libc.Uint64FromInt32(nDb)+libc.Uint64FromInt32(nName*int32(2))+uint64(8)) (*TRtree)(unsafe.Pointer(pRtree)).FnBusy = uint32(1) (*TRtree)(unsafe.Pointer(pRtree)).Fbase.FpModule = uintptr(unsafe.Pointer(&_rtreeModule)) (*TRtree)(unsafe.Pointer(pRtree)).FzDb = pRtree + 1*976 (*TRtree)(unsafe.Pointer(pRtree)).FzName = (*TRtree)(unsafe.Pointer(pRtree)).FzDb + uintptr(nDb+int32(1)) (*TRtree)(unsafe.Pointer(pRtree)).FzNodeName = (*TRtree)(unsafe.Pointer(pRtree)).FzName + uintptr(nName+int32(1)) (*TRtree)(unsafe.Pointer(pRtree)).FeCoordType = libc.Uint8FromInt32(eCoordType) libc.Xmemcpy(tls, (*TRtree)(unsafe.Pointer(pRtree)).FzDb, **(**uintptr)(__ccgo_up(argv + 1*8)), libc.Uint64FromInt32(nDb)) libc.Xmemcpy(tls, (*TRtree)(unsafe.Pointer(pRtree)).FzName, **(**uintptr)(__ccgo_up(argv + 2*8)), libc.Uint64FromInt32(nName)) libc.Xmemcpy(tls, (*TRtree)(unsafe.Pointer(pRtree)).FzNodeName, **(**uintptr)(__ccgo_up(argv + 2*8)), libc.Uint64FromInt32(nName)) libc.Xmemcpy(tls, (*TRtree)(unsafe.Pointer(pRtree)).FzNodeName+uintptr(nName), __ccgo_ts+28976, uint64(6)) /* Create/Connect to the underlying relational database schema. If ** that is successful, call sqlite3_declare_vtab() to configure ** the r-tree table schema. */ pSql = Xsqlite3_str_new(tls, db) Xsqlite3_str_appendf(tls, pSql, __ccgo_ts+28982, libc.VaList(bp+8, _rtreeTokenLength(tls, **(**uintptr)(__ccgo_up(argv + 3*8))), **(**uintptr)(__ccgo_up(argv + 3*8)))) ii = int32(4) for { if !(ii < argc) { break } zArg = **(**uintptr)(__ccgo_up(argv + uintptr(ii)*8)) if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zArg))) == int32('+') { (*TRtree)(unsafe.Pointer(pRtree)).FnAux = (*TRtree)(unsafe.Pointer(pRtree)).FnAux + 1 Xsqlite3_str_appendf(tls, pSql, __ccgo_ts+29006, libc.VaList(bp+8, _rtreeTokenLength(tls, zArg+uintptr(1)), zArg+uintptr(1))) } else { if libc.Int32FromUint16((*TRtree)(unsafe.Pointer(pRtree)).FnAux) > 0 { break } else { (*TRtree)(unsafe.Pointer(pRtree)).FnDim2 = (*TRtree)(unsafe.Pointer(pRtree)).FnDim2 + 1 Xsqlite3_str_appendf(tls, pSql, _azFormat[eCoordType], libc.VaList(bp+8, _rtreeTokenLength(tls, zArg), zArg)) } } goto _2 _2: ; ii = ii + 1 } Xsqlite3_str_appendf(tls, pSql, __ccgo_ts+29033, 0) zSql = Xsqlite3_str_finish(tls, pSql) if !(zSql != 0) { rc = int32(SQLITE_NOMEM) } else { if ii < argc { **(**uintptr)(__ccgo_up(pzErr)) = Xsqlite3_mprintf(tls, __ccgo_ts+3968, libc.VaList(bp+8, aErrMsg[int32(4)])) rc = int32(SQLITE_ERROR) } else { v1 = Xsqlite3_declare_vtab(tls, db, zSql) rc = v1 if SQLITE_OK != v1 { **(**uintptr)(__ccgo_up(pzErr)) = Xsqlite3_mprintf(tls, __ccgo_ts+3968, libc.VaList(bp+8, Xsqlite3_errmsg(tls, db))) } } } Xsqlite3_free(tls, zSql) if rc != 0 { goto rtreeInit_fail } (*TRtree)(unsafe.Pointer(pRtree)).FnDim = libc.Uint8FromInt32(libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FnDim2) / int32(2)) if libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FnDim) < int32(1) { iErr = int32(2) } else { if libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FnDim2) > libc.Int32FromInt32(RTREE_MAX_DIMENSIONS)*libc.Int32FromInt32(2) { iErr = int32(3) } else { if libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FnDim2)%int32(2) != 0 { iErr = int32(1) } else { iErr = 0 } } } if iErr != 0 { **(**uintptr)(__ccgo_up(pzErr)) = Xsqlite3_mprintf(tls, __ccgo_ts+3968, libc.VaList(bp+8, aErrMsg[iErr])) goto rtreeInit_fail } (*TRtree)(unsafe.Pointer(pRtree)).FnBytesPerCell = libc.Uint8FromInt32(int32(8) + libc.Int32FromUint8((*TRtree)(unsafe.Pointer(pRtree)).FnDim2)*int32(4)) /* Figure out the node size to use. */ rc = _getNodeSize(tls, db, pRtree, isCreate, pzErr) if rc != 0 { goto rtreeInit_fail } rc = _rtreeSqlInit(tls, pRtree, db, **(**uintptr)(__ccgo_up(argv + 1*8)), **(**uintptr)(__ccgo_up(argv + 2*8)), isCreate) if rc != 0 { **(**uintptr)(__ccgo_up(pzErr)) = Xsqlite3_mprintf(tls, __ccgo_ts+3968, libc.VaList(bp+8, Xsqlite3_errmsg(tls, db))) goto rtreeInit_fail } **(**uintptr)(__ccgo_up(ppVtab)) = pRtree return SQLITE_OK goto rtreeInit_fail rtreeInit_fail: ; if rc == SQLITE_OK { rc = int32(SQLITE_ERROR) } _rtreeRelease(tls, pRtree) return rc } // C documentation // // /* // ** This function is a no-op if *pRc is other than SQLITE_OK when it is // ** called. Otherwise, append the string representation of integer iVal // ** to the buffer. No nul-terminator is written. // ** // ** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before // ** returning. // */ func _sessionAppendInteger(tls *libc.TLS, p uintptr, iVal int32, pRc uintptr) { bp := tls.Alloc(48) defer tls.Free(48) var _ /* aBuf at bp+0 */ [24]uint8 Xsqlite3_snprintf(tls, libc.Int32FromUint64(libc.Uint64FromInt64(24)-libc.Uint64FromInt32(1)), bp, __ccgo_ts+5317, libc.VaList(bp+32, iVal)) _sessionAppendStr(tls, p, bp, pRc) } // C documentation // // /* // ** This function is called by the parser upon parsing an // ** // ** ALTER TABLE pSrc DROP COLUMN pName // ** // ** statement. Argument pSrc contains the possibly qualified name of the // ** table being edited, and token pName the name of the column to drop. // */ func _sqlite3AlterDropColumn(tls *libc.TLS, pParse uintptr, pSrc uintptr, pName uintptr) { bp := tls.Alloc(48) defer tls.Free(48) var addr, i, iCol, iColPos, iCur, iDb, iPos, nField, reg, regOut, regRec, v2 int32 var aff uint8 var db, pPk, pTab, v, zCol, zDb, v1 uintptr _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = addr, aff, db, i, iCol, iColPos, iCur, iDb, iPos, nField, pPk, pTab, reg, regOut, regRec, v, zCol, zDb, v1, v2 db = (*TParse)(unsafe.Pointer(pParse)).Fdb /* Database containing pTab ("main" etc.) */ zCol = uintptr(0) /* Index of column zCol in pTab->aCol[] */ /* Look up the table being altered. */ if (*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0 { goto exit_drop_column } pTab = _sqlite3LocateTableItem(tls, pParse, uint32(0), pSrc+8) if !(pTab != 0) { goto exit_drop_column } /* Make sure this is not an attempt to ALTER a view, virtual table or ** system table. */ if SQLITE_OK != _isAlterableTable(tls, pParse, pTab) { goto exit_drop_column } if SQLITE_OK != _isRealTable(tls, pParse, pTab, int32(1)) { goto exit_drop_column } /* Find the index of the column being dropped. */ zCol = _sqlite3NameFromToken(tls, db, pName) if zCol == uintptr(0) { goto exit_drop_column } iCol = _sqlite3ColumnIndex(tls, pTab, zCol) if iCol < 0 { _sqlite3ErrorMsg(tls, pParse, __ccgo_ts+11235, libc.VaList(bp+8, pName)) goto exit_drop_column } /* Do not allow the user to drop a PRIMARY KEY column or a column ** constrained by a UNIQUE constraint. */ if libc.Int32FromUint16((**(**TColumn)(__ccgo_up((*TTable)(unsafe.Pointer(pTab)).FaCol + uintptr(iCol)*16))).FcolFlags)&(libc.Int32FromInt32(COLFLAG_PRIMKEY)|libc.Int32FromInt32(COLFLAG_UNIQUE)) != 0 { if libc.Int32FromUint16((**(**TColumn)(__ccgo_up((*TTable)(unsafe.Pointer(pTab)).FaCol + uintptr(iCol)*16))).FcolFlags)&int32(COLFLAG_PRIMKEY) != 0 { v1 = __ccgo_ts + 11620 } else { v1 = __ccgo_ts + 5859 } _sqlite3ErrorMsg(tls, pParse, __ccgo_ts+11632, libc.VaList(bp+8, v1, zCol)) goto exit_drop_column } /* Do not allow the number of columns to go to zero */ if int32((*TTable)(unsafe.Pointer(pTab)).FnCol) <= int32(1) { _sqlite3ErrorMsg(tls, pParse, __ccgo_ts+11660, libc.VaList(bp+8, zCol)) goto exit_drop_column } /* Edit the sqlite_schema table */ iDb = _sqlite3SchemaToIndex(tls, db, (*TTable)(unsafe.Pointer(pTab)).FpSchema) zDb = (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(iDb)*32))).FzDbSName /* Invoke the authorization callback. */ if _sqlite3AuthCheck(tls, pParse, int32(SQLITE_ALTER_TABLE), zDb, (*TTable)(unsafe.Pointer(pTab)).FzName, zCol) != 0 { goto exit_drop_column } _renameTestSchema(tls, pParse, zDb, libc.BoolInt32(iDb == int32(1)), __ccgo_ts+1704, 0) _renameFixQuotes(tls, pParse, zDb, libc.BoolInt32(iDb == int32(1))) _sqlite3NestedParse(tls, pParse, __ccgo_ts+11708, libc.VaList(bp+8, zDb, iDb, iCol, (*TTable)(unsafe.Pointer(pTab)).FzName)) /* Drop and reload the database schema. */ _renameReloadSchema(tls, pParse, iDb, uint16(INITFLAG_AlterDrop)) _renameTestSchema(tls, pParse, zDb, libc.BoolInt32(iDb == int32(1)), __ccgo_ts+11829, int32(1)) /* Edit rows of table on disk */ if (*TParse)(unsafe.Pointer(pParse)).FnErr == 0 && libc.Int32FromUint16((**(**TColumn)(__ccgo_up((*TTable)(unsafe.Pointer(pTab)).FaCol + uintptr(iCol)*16))).FcolFlags)&int32(COLFLAG_VIRTUAL) == 0 { pPk = uintptr(0) nField = 0 v = _sqlite3GetVdbe(tls, pParse) v1 = pParse + 56 v2 = *(*int32)(unsafe.Pointer(v1)) *(*int32)(unsafe.Pointer(v1)) = *(*int32)(unsafe.Pointer(v1)) + 1 iCur = v2 _sqlite3OpenTable(tls, pParse, iCur, iDb, pTab, int32(OP_OpenWrite)) addr = _sqlite3VdbeAddOp1(tls, v, int32(OP_Rewind), iCur) v1 = pParse + 60 *(*int32)(unsafe.Pointer(v1)) = *(*int32)(unsafe.Pointer(v1)) + 1 v2 = *(*int32)(unsafe.Pointer(v1)) reg = v2 if (*TTable)(unsafe.Pointer(pTab)).FtabFlags&uint32(TF_WithoutRowid) == uint32(0) { _sqlite3VdbeAddOp2(tls, v, int32(OP_Rowid), iCur, reg) **(**int32)(__ccgo_up(pParse + 60)) += int32((*TTable)(unsafe.Pointer(pTab)).FnCol) } else { pPk = _sqlite3PrimaryKeyIndex(tls, pTab) **(**int32)(__ccgo_up(pParse + 60)) += libc.Int32FromUint16((*TIndex)(unsafe.Pointer(pPk)).FnColumn) i = 0 for { if !(i < libc.Int32FromUint16((*TIndex)(unsafe.Pointer(pPk)).FnKeyCol)) { break } _sqlite3VdbeAddOp3(tls, v, int32(OP_Column), iCur, i, reg+i+int32(1)) goto _6 _6: ; i = i + 1 } nField = libc.Int32FromUint16((*TIndex)(unsafe.Pointer(pPk)).FnKeyCol) } v1 = pParse + 60 *(*int32)(unsafe.Pointer(v1)) = *(*int32)(unsafe.Pointer(v1)) + 1 v2 = *(*int32)(unsafe.Pointer(v1)) regRec = v2 i = 0 for { if !(i < int32((*TTable)(unsafe.Pointer(pTab)).FnCol)) { break } if i != iCol && libc.Int32FromUint16((**(**TColumn)(__ccgo_up((*TTable)(unsafe.Pointer(pTab)).FaCol + uintptr(i)*16))).FcolFlags)&int32(COLFLAG_VIRTUAL) == 0 { if pPk != 0 { iPos = _sqlite3TableColumnToIndex(tls, pPk, i) iColPos = _sqlite3TableColumnToIndex(tls, pPk, iCol) if iPos < libc.Int32FromUint16((*TIndex)(unsafe.Pointer(pPk)).FnKeyCol) { goto _9 } regOut = reg + int32(1) + iPos - libc.BoolInt32(iPos > iColPos) } else { regOut = reg + int32(1) + nField } if i == int32((*TTable)(unsafe.Pointer(pTab)).FiPKey) { _sqlite3VdbeAddOp2(tls, v, int32(OP_Null), 0, regOut) } else { aff = (**(**TColumn)(__ccgo_up((*TTable)(unsafe.Pointer(pTab)).FaCol + uintptr(i)*16))).Faffinity if libc.Int32FromUint8(aff) == int32(SQLITE_AFF_REAL) { (**(**TColumn)(__ccgo_up((*TTable)(unsafe.Pointer(pTab)).FaCol + uintptr(i)*16))).Faffinity = uint8(SQLITE_AFF_NUMERIC) } _sqlite3ExprCodeGetColumnOfTable(tls, v, pTab, iCur, i, regOut) (**(**TColumn)(__ccgo_up((*TTable)(unsafe.Pointer(pTab)).FaCol + uintptr(i)*16))).Faffinity = aff } nField = nField + 1 } goto _9 _9: ; i = i + 1 } if nField == 0 { /* dbsqlfuzz 5f09e7bcc78b4954d06bf9f2400d7715f48d1fef */ (*TParse)(unsafe.Pointer(pParse)).FnMem = (*TParse)(unsafe.Pointer(pParse)).FnMem + 1 _sqlite3VdbeAddOp2(tls, v, int32(OP_Null), 0, reg+int32(1)) nField = int32(1) } _sqlite3VdbeAddOp3(tls, v, int32(OP_MakeRecord), reg+int32(1), nField, regRec) if pPk != 0 { _sqlite3VdbeAddOp4Int(tls, v, int32(OP_IdxInsert), iCur, regRec, reg+int32(1), libc.Int32FromUint16((*TIndex)(unsafe.Pointer(pPk)).FnKeyCol)) } else { _sqlite3VdbeAddOp3(tls, v, int32(OP_Insert), iCur, regRec, reg) } _sqlite3VdbeChangeP5(tls, v, uint16(OPFLAG_SAVEPOSITION)) _sqlite3VdbeAddOp2(tls, v, int32(OP_Next), iCur, addr+int32(1)) _sqlite3VdbeJumpHere(tls, v, addr) } goto exit_drop_column exit_drop_column: ; _sqlite3DbFree(tls, db, zCol) _sqlite3SrcListDelete(tls, db, pSrc) } // C documentation // // /* // ** Handles the following parser reduction: // ** // ** cmd ::= ALTER TABLE pSrc RENAME COLUMN pOld TO pNew // */ func _sqlite3AlterRenameColumn(tls *libc.TLS, pParse uintptr, pSrc uintptr, pOld uintptr, pNew uintptr) { bp := tls.Alloc(80) defer tls.Free(80) var bQuote, iCol, iSchema int32 var db, pTab, zDb, zNew, zOld uintptr _, _, _, _, _, _, _, _ = bQuote, db, iCol, iSchema, pTab, zDb, zNew, zOld db = (*TParse)(unsafe.Pointer(pParse)).Fdb /* Index of column being renamed */ zOld = uintptr(0) /* Old column name */ zNew = uintptr(0) /* True to quote the new name */ /* Locate the table to be altered */ pTab = _sqlite3LocateTableItem(tls, pParse, uint32(0), pSrc+8) if !(pTab != 0) { goto exit_rename_column } /* Cannot alter a system table */ if SQLITE_OK != _isAlterableTable(tls, pParse, pTab) { goto exit_rename_column } if SQLITE_OK != _isRealTable(tls, pParse, pTab, 0) { goto exit_rename_column } /* Which schema holds the table to be altered */ iSchema = _sqlite3SchemaToIndex(tls, db, (*TTable)(unsafe.Pointer(pTab)).FpSchema) zDb = (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(iSchema)*32))).FzDbSName /* Invoke the authorization callback. */ if _sqlite3AuthCheck(tls, pParse, int32(SQLITE_ALTER_TABLE), zDb, (*TTable)(unsafe.Pointer(pTab)).FzName, uintptr(0)) != 0 { goto exit_rename_column } /* Make sure the old name really is a column name in the table to be ** altered. Set iCol to be the index of the column being renamed */ zOld = _sqlite3NameFromToken(tls, db, pOld) if !(zOld != 0) { goto exit_rename_column } iCol = _sqlite3ColumnIndex(tls, pTab, zOld) if iCol < 0 { _sqlite3ErrorMsg(tls, pParse, __ccgo_ts+11235, libc.VaList(bp+8, pOld)) goto exit_rename_column } /* Ensure the schema contains no double-quoted strings */ _renameTestSchema(tls, pParse, zDb, libc.BoolInt32(iSchema == int32(1)), __ccgo_ts+1704, 0) _renameFixQuotes(tls, pParse, zDb, libc.BoolInt32(iSchema == int32(1))) /* Do the rename operation using a recursive UPDATE statement that ** uses the sqlite_rename_column() SQL function to compute the new ** CREATE statement text for the sqlite_schema table. */ _sqlite3MayAbort(tls, pParse) zNew = _sqlite3NameFromToken(tls, db, pNew) if !(zNew != 0) { goto exit_rename_column } bQuote = libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up((*TToken)(unsafe.Pointer(pNew)).Fz)))]) & int32(0x80) _sqlite3NestedParse(tls, pParse, __ccgo_ts+11256, libc.VaList(bp+8, zDb, zDb, (*TTable)(unsafe.Pointer(pTab)).FzName, iCol, zNew, bQuote, libc.BoolInt32(iSchema == int32(1)), (*TTable)(unsafe.Pointer(pTab)).FzName)) _sqlite3NestedParse(tls, pParse, __ccgo_ts+11438, libc.VaList(bp+8, zDb, (*TTable)(unsafe.Pointer(pTab)).FzName, iCol, zNew, bQuote)) /* Drop and reload the database schema. */ _renameReloadSchema(tls, pParse, iSchema, uint16(INITFLAG_AlterRename)) _renameTestSchema(tls, pParse, zDb, libc.BoolInt32(iSchema == int32(1)), __ccgo_ts+10266, int32(1)) goto exit_rename_column exit_rename_column: ; _sqlite3SrcListDelete(tls, db, pSrc) _sqlite3DbFree(tls, db, zOld) _sqlite3DbFree(tls, db, zNew) return } // C documentation // // /* // ** This routine does a complete check of the given BTree file. aRoot[] is // ** an array of pages numbers were each page number is the root page of // ** a table. nRoot is the number of entries in aRoot. // ** // ** A read-only or read-write transaction must be opened before calling // ** this function. // ** // ** Write the number of error seen in *pnErr. Except for some memory // ** allocation errors, an error message held in memory obtained from // ** malloc is returned if *pnErr is non-zero. If *pnErr==0 then NULL is // ** returned. If a memory allocation error occurs, NULL is returned. // ** // ** If the first entry in aRoot[] is 0, that indicates that the list of // ** root pages is incomplete. This is a "partial integrity-check". This // ** happens when performing an integrity check on a single table. The // ** zero is skipped, of course. But in addition, the freelist checks // ** and the checks to make sure every page is referenced are also skipped, // ** since obviously it is not possible to know which pages are covered by // ** the unverified btrees. Except, if aRoot[1] is 1, then the freelist // ** checks are still performed. // */ func _sqlite3BtreeIntegrityCheck(tls *libc.TLS, db uintptr, p uintptr, aRoot uintptr, aCnt uintptr, nRoot int32, mxErr int32, pnErr uintptr, pzOut uintptr) (r int32) { bp := tls.Alloc(272) defer tls.Free(272) var bCkFreelist, bPartial int32 var i, mx, mxInHdr TPgno var pBt uintptr var savedDbFlags Tu64 var _ /* notUsed at bp+232 */ Ti64 var _ /* sCheck at bp+0 */ TIntegrityCk var _ /* zErr at bp+128 */ [100]uint8 _, _, _, _, _, _, _ = bCkFreelist, bPartial, i, mx, mxInHdr, pBt, savedDbFlags pBt = (*TBtree)(unsafe.Pointer(p)).FpBt savedDbFlags = (*Tsqlite3)(unsafe.Pointer((*TBtShared)(unsafe.Pointer(pBt)).Fdb)).Fflags bPartial = 0 /* True if not checking all btrees */ bCkFreelist = int32(1) /* True to scan the freelist */ /* aRoot[0]==0 means this is a partial check */ if **(**TPgno)(__ccgo_up(aRoot)) == uint32(0) { bPartial = int32(1) if **(**TPgno)(__ccgo_up(aRoot + 1*4)) != uint32(1) { bCkFreelist = 0 } } _sqlite3BtreeEnter(tls, p) libc.Xmemset(tls, bp, 0, uint64(128)) (**(**TIntegrityCk)(__ccgo_up(bp))).Fdb = db (**(**TIntegrityCk)(__ccgo_up(bp))).FpBt = pBt (**(**TIntegrityCk)(__ccgo_up(bp))).FpPager = (*TBtShared)(unsafe.Pointer(pBt)).FpPager (**(**TIntegrityCk)(__ccgo_up(bp))).FnCkPage = _btreePagecount(tls, (**(**TIntegrityCk)(__ccgo_up(bp))).FpBt) (**(**TIntegrityCk)(__ccgo_up(bp))).FmxErr = mxErr _sqlite3StrAccumInit(tls, bp+72, uintptr(0), bp+128, int32(100), int32(SQLITE_MAX_LENGTH)) (**(**TIntegrityCk)(__ccgo_up(bp))).FerrMsg.FprintfFlags = uint8(SQLITE_PRINTF_INTERNAL) if (**(**TIntegrityCk)(__ccgo_up(bp))).FnCkPage == uint32(0) { goto integrity_ck_cleanup } (**(**TIntegrityCk)(__ccgo_up(bp))).FaPgRef = _sqlite3MallocZero(tls, uint64((**(**TIntegrityCk)(__ccgo_up(bp))).FnCkPage/uint32(8)+uint32(1))) if !((**(**TIntegrityCk)(__ccgo_up(bp))).FaPgRef != 0) { _checkOom(tls, bp) goto integrity_ck_cleanup } (**(**TIntegrityCk)(__ccgo_up(bp))).Fheap = _sqlite3PageMalloc(tls, libc.Int32FromUint32((*TBtShared)(unsafe.Pointer(pBt)).FpageSize)) if (**(**TIntegrityCk)(__ccgo_up(bp))).Fheap == uintptr(0) { _checkOom(tls, bp) goto integrity_ck_cleanup } i = libc.Uint32FromInt32(_sqlite3PendingByte)/(*TBtShared)(unsafe.Pointer(pBt)).FpageSize + libc.Uint32FromInt32(1) if i <= (**(**TIntegrityCk)(__ccgo_up(bp))).FnCkPage { _setPageReferenced(tls, bp, i) } /* Check the integrity of the freelist */ if bCkFreelist != 0 { (**(**TIntegrityCk)(__ccgo_up(bp))).FzPfx = __ccgo_ts + 4990 _checkList(tls, bp, int32(1), _sqlite3Get4byte(tls, (*TMemPage)(unsafe.Pointer((*TBtShared)(unsafe.Pointer(pBt)).FpPage1)).FaData+32), _sqlite3Get4byte(tls, (*TMemPage)(unsafe.Pointer((*TBtShared)(unsafe.Pointer(pBt)).FpPage1)).FaData+36)) (**(**TIntegrityCk)(__ccgo_up(bp))).FzPfx = uintptr(0) } /* Check all the tables. */ if !(bPartial != 0) { if (*TBtShared)(unsafe.Pointer(pBt)).FautoVacuum != 0 { mx = uint32(0) i = uint32(0) for { if !(libc.Int32FromUint32(i) < nRoot) { break } if mx < **(**TPgno)(__ccgo_up(aRoot + uintptr(i)*4)) { mx = **(**TPgno)(__ccgo_up(aRoot + uintptr(i)*4)) } goto _1 _1: ; i = i + 1 } mxInHdr = _sqlite3Get4byte(tls, (*TMemPage)(unsafe.Pointer((*TBtShared)(unsafe.Pointer(pBt)).FpPage1)).FaData+52) if mx != mxInHdr { _checkAppendMsg(tls, bp, __ccgo_ts+5001, libc.VaList(bp+248, mx, mxInHdr)) } } else { if _sqlite3Get4byte(tls, (*TMemPage)(unsafe.Pointer((*TBtShared)(unsafe.Pointer(pBt)).FpPage1)).FaData+64) != uint32(0) { _checkAppendMsg(tls, bp, __ccgo_ts+5046, 0) } } } **(**Tu64)(__ccgo_up((*TBtShared)(unsafe.Pointer(pBt)).Fdb + 48)) &= ^libc.Uint64FromInt32(SQLITE_CellSizeCk) i = uint32(0) for { if !(libc.Int32FromUint32(i) < nRoot && (**(**TIntegrityCk)(__ccgo_up(bp))).FmxErr != 0) { break } (**(**TIntegrityCk)(__ccgo_up(bp))).FnRow = 0 if **(**TPgno)(__ccgo_up(aRoot + uintptr(i)*4)) != 0 { if (*TBtShared)(unsafe.Pointer(pBt)).FautoVacuum != 0 && **(**TPgno)(__ccgo_up(aRoot + uintptr(i)*4)) > uint32(1) && !(bPartial != 0) { _checkPtrmap(tls, bp, **(**TPgno)(__ccgo_up(aRoot + uintptr(i)*4)), uint8(PTRMAP_ROOTPAGE), uint32(0)) } (**(**TIntegrityCk)(__ccgo_up(bp))).Fv0 = **(**TPgno)(__ccgo_up(aRoot + uintptr(i)*4)) _checkTreePage(tls, bp, **(**TPgno)(__ccgo_up(aRoot + uintptr(i)*4)), bp+232, libc.Int64FromUint32(0xffffffff)|libc.Int64FromInt32(0x7fffffff)< nFilename { v1 = nFullPathname } else { v1 = nFilename } zFullPathname = _sqlite3Malloc(tls, libc.Uint64FromInt32(v1)) (*TBtree)(unsafe.Pointer(p)).Fsharable = uint8(1) if !(zFullPathname != 0) { Xsqlite3_free(tls, p) return int32(SQLITE_NOMEM) } if isMemdb != 0 { libc.Xmemcpy(tls, zFullPathname, zFilename, libc.Uint64FromInt32(nFilename)) } else { rc = _sqlite3OsFullPathname(tls, pVfs, zFilename, nFullPathname, zFullPathname) if rc != 0 { if rc == libc.Int32FromInt32(SQLITE_OK)|libc.Int32FromInt32(2)<= 0) { break } pExisting = (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(iDb)*32))).FpBt if pExisting != 0 && (*TBtree)(unsafe.Pointer(pExisting)).FpBt == pBt { Xsqlite3_mutex_leave(tls, mutexShared) Xsqlite3_mutex_leave(tls, mutexOpen) Xsqlite3_free(tls, zFullPathname) Xsqlite3_free(tls, p) return int32(SQLITE_CONSTRAINT) } goto _3 _3: ; iDb = iDb - 1 } (*TBtree)(unsafe.Pointer(p)).FpBt = pBt (*TBtShared)(unsafe.Pointer(pBt)).FnRef = (*TBtShared)(unsafe.Pointer(pBt)).FnRef + 1 break } goto _2 _2: ; pBt = (*TBtShared)(unsafe.Pointer(pBt)).FpNext } Xsqlite3_mutex_leave(tls, mutexShared) Xsqlite3_free(tls, zFullPathname) } } if pBt == uintptr(0) { /* ** The following asserts make sure that structures used by the btree are ** the right size. This is to guard against size changes that result ** when compiling on a different architecture. */ /* Suppress false-positive compiler warning from PVS-Studio */ libc.Xmemset(tls, bp+16, 0, uint64(8)) pBt = _sqlite3MallocZero(tls, uint64(152)) if pBt == uintptr(0) { rc = int32(SQLITE_NOMEM) goto btree_open_out } rc = _sqlite3PagerOpen(tls, pVfs, pBt, zFilename, int32(136), flags, vfsFlags, __ccgo_fp(_pageReinit)) if rc == SQLITE_OK { _sqlite3PagerSetMmapLimit(tls, (*TBtShared)(unsafe.Pointer(pBt)).FpPager, (*Tsqlite3)(unsafe.Pointer(db)).FszMmap) rc = _sqlite3PagerReadFileheader(tls, (*TBtShared)(unsafe.Pointer(pBt)).FpPager, int32(100), bp) } if rc != SQLITE_OK { goto btree_open_out } (*TBtShared)(unsafe.Pointer(pBt)).FopenFlags = libc.Uint8FromInt32(flags) (*TBtShared)(unsafe.Pointer(pBt)).Fdb = db _sqlite3PagerSetBusyHandler(tls, (*TBtShared)(unsafe.Pointer(pBt)).FpPager, __ccgo_fp(_btreeInvokeBusyHandler), pBt) (*TBtree)(unsafe.Pointer(p)).FpBt = pBt (*TBtShared)(unsafe.Pointer(pBt)).FpCursor = uintptr(0) (*TBtShared)(unsafe.Pointer(pBt)).FpPage1 = uintptr(0) if _sqlite3PagerIsreadonly(tls, (*TBtShared)(unsafe.Pointer(pBt)).FpPager) != 0 { v4 = pBt + 40 *(*Tu16)(unsafe.Pointer(v4)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v4))) | libc.Int32FromInt32(BTS_READ_ONLY)) } /* EVIDENCE-OF: R-51873-39618 The page size for a database file is ** determined by the 2-byte integer located at an offset of 16 bytes from ** the beginning of the database file. */ (*TBtShared)(unsafe.Pointer(pBt)).FpageSize = libc.Uint32FromInt32(libc.Int32FromUint8((**(**[100]uint8)(__ccgo_up(bp)))[int32(16)])< uint32(SQLITE_MAX_PAGE_SIZE) || ((*TBtShared)(unsafe.Pointer(pBt)).FpageSize-uint32(1))&(*TBtShared)(unsafe.Pointer(pBt)).FpageSize != uint32(0) { (*TBtShared)(unsafe.Pointer(pBt)).FpageSize = uint32(0) /* If the magic name ":memory:" will create an in-memory database, then ** leave the autoVacuum mode at 0 (do not auto-vacuum), even if ** SQLITE_DEFAULT_AUTOVACUUM is true. On the other hand, if ** SQLITE_OMIT_MEMORYDB has been defined, then ":memory:" is just a ** regular file-name. In this case the auto-vacuum applies as per normal. */ if zFilename != 0 && !(isMemdb != 0) { (*TBtShared)(unsafe.Pointer(pBt)).FautoVacuum = libc.Uint8FromInt32(libc.Int32FromInt32(0)) (*TBtShared)(unsafe.Pointer(pBt)).FincrVacuum = libc.Uint8FromInt32(libc.Int32FromInt32(0)) } nReserve = uint8(0) } else { /* EVIDENCE-OF: R-37497-42412 The size of the reserved region is ** determined by the one-byte unsigned integer found at an offset of 20 ** into the database file header. */ nReserve = (**(**[100]uint8)(__ccgo_up(bp)))[int32(20)] v4 = pBt + 40 *(*Tu16)(unsafe.Pointer(v4)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v4))) | libc.Int32FromInt32(BTS_PAGESIZE_FIXED)) if _sqlite3Get4byte(tls, bp+uintptr(libc.Int32FromInt32(36)+libc.Int32FromInt32(4)*libc.Int32FromInt32(4))) != 0 { v1 = int32(1) } else { v1 = 0 } (*TBtShared)(unsafe.Pointer(pBt)).FautoVacuum = libc.Uint8FromInt32(v1) if _sqlite3Get4byte(tls, bp+uintptr(libc.Int32FromInt32(36)+libc.Int32FromInt32(7)*libc.Int32FromInt32(4))) != 0 { v1 = int32(1) } else { v1 = 0 } (*TBtShared)(unsafe.Pointer(pBt)).FincrVacuum = libc.Uint8FromInt32(v1) } rc = _sqlite3PagerSetPagesize(tls, (*TBtShared)(unsafe.Pointer(pBt)).FpPager, pBt+52, libc.Int32FromUint8(nReserve)) if rc != 0 { goto btree_open_out } (*TBtShared)(unsafe.Pointer(pBt)).FusableSize = (*TBtShared)(unsafe.Pointer(pBt)).FpageSize - uint32(nReserve) /* 8-byte alignment of pageSize */ /* Add the new BtShared object to the linked list sharable BtShareds. */ (*TBtShared)(unsafe.Pointer(pBt)).FnRef = int32(1) if (*TBtree)(unsafe.Pointer(p)).Fsharable != 0 { mutexShared1 = _sqlite3MutexAlloc(tls, int32(SQLITE_MUTEX_STATIC_MAIN)) if libc.Bool(int32(SQLITE_THREADSAFE) != 0) && _sqlite3Config.FbCoreMutex != 0 { (*TBtShared)(unsafe.Pointer(pBt)).Fmutex = _sqlite3MutexAlloc(tls, SQLITE_MUTEX_FAST) if (*TBtShared)(unsafe.Pointer(pBt)).Fmutex == uintptr(0) { rc = int32(SQLITE_NOMEM) goto btree_open_out } } Xsqlite3_mutex_enter(tls, mutexShared1) (*TBtShared)(unsafe.Pointer(pBt)).FpNext = _sqlite3SharedCacheList _sqlite3SharedCacheList = pBt Xsqlite3_mutex_leave(tls, mutexShared1) } } /* If the new Btree uses a sharable pBtShared, then link the new ** Btree into the list of all sharable Btrees for the same connection. ** The list is kept in ascending order by pBt address. */ if (*TBtree)(unsafe.Pointer(p)).Fsharable != 0 { i = 0 for { if !(i < (*Tsqlite3)(unsafe.Pointer(db)).FnDb) { break } v4 = (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(i)*32))).FpBt pSib = v4 if v4 != uintptr(0) && (*TBtree)(unsafe.Pointer(pSib)).Fsharable != 0 { for (*TBtree)(unsafe.Pointer(pSib)).FpPrev != 0 { pSib = (*TBtree)(unsafe.Pointer(pSib)).FpPrev } if uint64((*TBtree)(unsafe.Pointer(p)).FpBt) < uint64((*TBtree)(unsafe.Pointer(pSib)).FpBt) { (*TBtree)(unsafe.Pointer(p)).FpNext = pSib (*TBtree)(unsafe.Pointer(p)).FpPrev = uintptr(0) (*TBtree)(unsafe.Pointer(pSib)).FpPrev = p } else { for (*TBtree)(unsafe.Pointer(pSib)).FpNext != 0 && uint64((*TBtree)(unsafe.Pointer((*TBtree)(unsafe.Pointer(pSib)).FpNext)).FpBt) < uint64((*TBtree)(unsafe.Pointer(p)).FpBt) { pSib = (*TBtree)(unsafe.Pointer(pSib)).FpNext } (*TBtree)(unsafe.Pointer(p)).FpNext = (*TBtree)(unsafe.Pointer(pSib)).FpNext (*TBtree)(unsafe.Pointer(p)).FpPrev = pSib if (*TBtree)(unsafe.Pointer(p)).FpNext != 0 { (*TBtree)(unsafe.Pointer((*TBtree)(unsafe.Pointer(p)).FpNext)).FpPrev = p } (*TBtree)(unsafe.Pointer(pSib)).FpNext = p } break } goto _8 _8: ; i = i + 1 } } **(**uintptr)(__ccgo_up(ppBtree)) = p goto btree_open_out btree_open_out: ; if rc != SQLITE_OK { if pBt != 0 && (*TBtShared)(unsafe.Pointer(pBt)).FpPager != 0 { _sqlite3PagerClose(tls, (*TBtShared)(unsafe.Pointer(pBt)).FpPager, uintptr(0)) } Xsqlite3_free(tls, pBt) Xsqlite3_free(tls, p) **(**uintptr)(__ccgo_up(ppBtree)) = uintptr(0) } else { /* If the B-Tree was successfully opened, set the pager-cache size to the ** default value. Except, when opening on an existing shared pager-cache, ** do not change the pager-cache size. */ if _sqlite3BtreeSchema(tls, p, 0, uintptr(0)) == uintptr(0) { _sqlite3BtreeSetCacheSize(tls, p, -int32(2000)) } pFile = _sqlite3PagerFile(tls, (*TBtShared)(unsafe.Pointer(pBt)).FpPager) if (*Tsqlite3_file)(unsafe.Pointer(pFile)).FpMethods != 0 { _sqlite3OsFileControlHint(tls, pFile, int32(SQLITE_FCNTL_PDB), pBt+8) } } if mutexOpen != 0 { Xsqlite3_mutex_leave(tls, mutexOpen) } return rc } // C documentation // // /* // ** Remove entries from the sqlite_statN tables (for N in (1,2,3)) // ** after a DROP INDEX or DROP TABLE command. // */ func _sqlite3ClearStatTables(tls *libc.TLS, pParse uintptr, iDb int32, zType uintptr, zName uintptr) { bp := tls.Alloc(64) defer tls.Free(64) var i int32 var zDbName uintptr var _ /* zTab at bp+0 */ [24]uint8 _, _ = i, zDbName zDbName = (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer((*TParse)(unsafe.Pointer(pParse)).Fdb)).FaDb + uintptr(iDb)*32))).FzDbSName i = int32(1) for { if !(i <= int32(4)) { break } Xsqlite3_snprintf(tls, int32(24), bp, __ccgo_ts+14979, libc.VaList(bp+32, i)) if _sqlite3FindTable(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, bp, zDbName) != 0 { _sqlite3NestedParse(tls, pParse, __ccgo_ts+12964, libc.VaList(bp+32, zDbName, bp, zType, zName)) } goto _1 _1: ; i = i + 1 } } // C documentation // // /* // ** Generate code that will construct an ephemeral table containing all terms // ** in the RHS of an IN operator. The IN operator can be in either of two // ** forms: // ** // ** x IN (4,5,11) -- IN operator with list on right-hand side // ** x IN (SELECT a FROM b) -- IN operator with subquery on the right // ** // ** The pExpr parameter is the IN operator. The cursor number for the // ** constructed ephemeral table is returned. The first time the ephemeral // ** table is computed, the cursor number is also stored in pExpr->iTable, // ** however the cursor number returned might not be the same, as it might // ** have been duplicated using OP_OpenDup. // ** // ** If the LHS expression ("x" in the examples) is a column value, or // ** the SELECT statement returns a column value, then the affinity of that // ** column is used to build the index keys. If both 'x' and the // ** SELECT... statement are columns, then numeric affinity is used // ** if either column has NUMERIC or INTEGER affinity. If neither // ** 'x' nor the SELECT... statement are columns, then numeric affinity // ** is used. // */ func _sqlite3CodeRhsOfIN(tls *libc.TLS, pParse uintptr, pExpr uintptr, iTab int32, allowBloom int32) { bp := tls.Alloc(80) defer tls.Free(80) var addr, addrBloom, addrOnce, i, i1, nVal, r1, r2, rc, regBloom, v1 int32 var p, pCopy, pE2, pEList, pItem, pKeyInfo, pLeft, pList, pSelect, pSig, v, v2 uintptr var _ /* affinity at bp+40 */ uint8 var _ /* dest at bp+0 */ TSelectDest _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = addr, addrBloom, addrOnce, i, i1, nVal, p, pCopy, pE2, pEList, pItem, pKeyInfo, pLeft, pList, pSelect, pSig, r1, r2, rc, regBloom, v, v1, v2 addrOnce = 0 /* the LHS of the IN operator */ pKeyInfo = uintptr(0) /* The prepared statement under construction */ pSig = uintptr(0) /* Signature for this subroutine */ v = (*TParse)(unsafe.Pointer(pParse)).FpVdbe /* The evaluation of the IN must be repeated every time it ** is encountered if any of the following is true: ** ** * The right-hand side is a correlated subquery ** * The right-hand side is an expression list containing variables ** * We are inside a trigger ** ** If all of the above are false, then we can compute the RHS just once ** and reuse it many names. */ if !((*TExpr)(unsafe.Pointer(pExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_VarSelect)) != libc.Uint32FromInt32(0)) && (*TParse)(unsafe.Pointer(pParse)).FiSelfTab == 0 { /* Reuse of the RHS is allowed ** ** Compute a signature for the RHS of the IN operator to facility ** finding and reusing prior instances of the same IN operator. */ if (*TExpr)(unsafe.Pointer(pExpr)).Fflags&uint32(EP_xIsSelect) != uint32(0) && (*TSelect)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pExpr + 32)))).FselFlags&uint32(SF_All) == uint32(0) { pSig = _sqlite3DbMallocRawNN(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, uint64(32)) if pSig != 0 { (*TSubrtnSig)(unsafe.Pointer(pSig)).FselId = libc.Int32FromUint32((*TSelect)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pExpr + 32)))).FselId) (*TSubrtnSig)(unsafe.Pointer(pSig)).FzAff = _exprINAffinity(tls, pParse, pExpr) } } /* Check to see if there is a prior materialization of the RHS of ** this IN operator. If there is, then make use of that prior ** materialization rather than recomputing it. */ if (*TExpr)(unsafe.Pointer(pExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_Subrtn)) != uint32(0) || _findCompatibleInRhsSubrtn(tls, pParse, pExpr, pSig) != 0 { addrOnce = _sqlite3VdbeAddOp0(tls, v, int32(OP_Once)) if (*TExpr)(unsafe.Pointer(pExpr)).Fflags&uint32(EP_xIsSelect) != uint32(0) { _sqlite3VdbeExplain(tls, pParse, uint8(0), __ccgo_ts+8357, libc.VaList(bp+56, (*TSelect)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pExpr + 32)))).FselId)) } _sqlite3VdbeAddOp2(tls, v, int32(OP_Gosub), (*(*struct { FiAddr int32 FregReturn int32 })(unsafe.Pointer(pExpr + 64))).FregReturn, (*(*struct { FiAddr int32 FregReturn int32 })(unsafe.Pointer(pExpr + 64))).FiAddr) _sqlite3VdbeAddOp2(tls, v, int32(OP_OpenDup), iTab, (*TExpr)(unsafe.Pointer(pExpr)).FiTable) _sqlite3VdbeJumpHere(tls, v, addrOnce) if pSig != 0 { _sqlite3DbFree(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, (*TSubrtnSig)(unsafe.Pointer(pSig)).FzAff) _sqlite3DbFree(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, pSig) } return } /* Begin coding the subroutine */ **(**Tu32)(__ccgo_up(pExpr + 4)) |= libc.Uint32FromInt32(libc.Int32FromInt32(EP_Subrtn)) v2 = pParse + 60 *(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1 v1 = *(*int32)(unsafe.Pointer(v2)) (*(*struct { FiAddr int32 FregReturn int32 })(unsafe.Pointer(pExpr + 64))).FregReturn = v1 (*(*struct { FiAddr int32 FregReturn int32 })(unsafe.Pointer(pExpr + 64))).FiAddr = _sqlite3VdbeAddOp2(tls, v, int32(OP_BeginSubrtn), 0, (*(*struct { FiAddr int32 FregReturn int32 })(unsafe.Pointer(pExpr + 64))).FregReturn) + int32(1) if pSig != 0 { (*TSubrtnSig)(unsafe.Pointer(pSig)).FbComplete = uint8(0) (*TSubrtnSig)(unsafe.Pointer(pSig)).FiAddr = (*(*struct { FiAddr int32 FregReturn int32 })(unsafe.Pointer(pExpr + 64))).FiAddr (*TSubrtnSig)(unsafe.Pointer(pSig)).FregReturn = (*(*struct { FiAddr int32 FregReturn int32 })(unsafe.Pointer(pExpr + 64))).FregReturn (*TSubrtnSig)(unsafe.Pointer(pSig)).FiTable = iTab (*TParse)(unsafe.Pointer(pParse)).FmSubrtnSig = libc.Uint8FromInt32(int32(1) << ((*TSubrtnSig)(unsafe.Pointer(pSig)).FselId & int32(7))) _sqlite3VdbeChangeP4(tls, v, -int32(1), pSig, -int32(18)) } addrOnce = _sqlite3VdbeAddOp0(tls, v, int32(OP_Once)) } /* Check to see if this is a vector IN operator */ pLeft = (*TExpr)(unsafe.Pointer(pExpr)).FpLeft nVal = _sqlite3ExprVectorSize(tls, pLeft) /* Construct the ephemeral table that will contain the content of ** RHS of the IN operator. */ (*TExpr)(unsafe.Pointer(pExpr)).FiTable = iTab addr = _sqlite3VdbeAddOp2(tls, v, int32(OP_OpenEphemeral), (*TExpr)(unsafe.Pointer(pExpr)).FiTable, nVal) pKeyInfo = _sqlite3KeyInfoAlloc(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, nVal, int32(1)) if (*TExpr)(unsafe.Pointer(pExpr)).Fflags&uint32(EP_xIsSelect) != uint32(0) { /* Case 1: expr IN (SELECT ...) ** ** Generate code to write the results of the select into the temporary ** table allocated and opened above. */ pSelect = *(*uintptr)(unsafe.Pointer(pExpr + 32)) pEList = (*TSelect)(unsafe.Pointer(pSelect)).FpEList if addrOnce != 0 { v2 = __ccgo_ts + 1704 } else { v2 = __ccgo_ts + 8380 } _sqlite3VdbeExplain(tls, pParse, uint8(1), __ccgo_ts+8392, libc.VaList(bp+56, v2, (*TSelect)(unsafe.Pointer(pSelect)).FselId)) /* If the LHS and RHS of the IN operator do not match, that ** error will have been caught long before we reach this point. */ if (*TExprList)(unsafe.Pointer(pEList)).FnExpr == nVal { addrBloom = 0 _sqlite3SelectDestInit(tls, bp, int32(SRT_Set), iTab) (**(**TSelectDest)(__ccgo_up(bp))).FzAffSdst = _exprINAffinity(tls, pParse, pExpr) (*TSelect)(unsafe.Pointer(pSelect)).FiLimit = 0 if addrOnce != 0 && allowBloom != 0 && (*Tsqlite3)(unsafe.Pointer((*TParse)(unsafe.Pointer(pParse)).Fdb)).FdbOptFlags&libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_BloomFilter)) == uint32(0) { v2 = pParse + 60 *(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1 v1 = *(*int32)(unsafe.Pointer(v2)) regBloom = v1 addrBloom = _sqlite3VdbeAddOp2(tls, v, int32(OP_Blob), int32(10000), regBloom) (**(**TSelectDest)(__ccgo_up(bp))).FiSDParm2 = regBloom } /* Caused by OOM in sqlite3KeyInfoAlloc() */ pCopy = _sqlite3SelectDup(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, pSelect, 0) if (*Tsqlite3)(unsafe.Pointer((*TParse)(unsafe.Pointer(pParse)).Fdb)).FmallocFailed != 0 { v1 = int32(1) } else { v1 = _sqlite3Select(tls, pParse, pCopy, bp) } rc = v1 _sqlite3SelectDelete(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, pCopy) _sqlite3DbFree(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, (**(**TSelectDest)(__ccgo_up(bp))).FzAffSdst) if addrBloom != 0 { /* Remember that location of the Bloom filter in the P3 operand ** of the OP_Once that began this subroutine. tag-202407032019 */ (*TVdbeOp)(unsafe.Pointer(_sqlite3VdbeGetOp(tls, v, addrOnce))).Fp3 = (**(**TSelectDest)(__ccgo_up(bp))).FiSDParm2 if (**(**TSelectDest)(__ccgo_up(bp))).FiSDParm2 == 0 { /* If the Bloom filter won't actually be used, keep it small */ (*TVdbeOp)(unsafe.Pointer(_sqlite3VdbeGetOp(tls, v, addrBloom))).Fp1 = int32(10) } } if rc != 0 { _sqlite3KeyInfoUnref(tls, pKeyInfo) return } /* OOM will cause exit after sqlite3Select() */ i = 0 for { if !(i < nVal) { break } p = _sqlite3VectorFieldSubexpr(tls, pLeft, i) *(*uintptr)(unsafe.Pointer(pKeyInfo + 32 + uintptr(i)*8)) = _sqlite3BinaryCompareCollSeq(tls, pParse, p, (*(*TExprList_item)(unsafe.Pointer(pEList + 8 + uintptr(i)*32))).FpExpr) goto _7 _7: ; i = i + 1 } } } else { if *(*uintptr)(unsafe.Pointer(pExpr + 32)) != uintptr(0) { pList = *(*uintptr)(unsafe.Pointer(pExpr + 32)) **(**uint8)(__ccgo_up(bp + 40)) = _sqlite3ExprAffinity(tls, pLeft) if libc.Int32FromUint8(**(**uint8)(__ccgo_up(bp + 40))) <= int32(SQLITE_AFF_NONE) { **(**uint8)(__ccgo_up(bp + 40)) = uint8(SQLITE_AFF_BLOB) } else { if libc.Int32FromUint8(**(**uint8)(__ccgo_up(bp + 40))) == int32(SQLITE_AFF_REAL) { **(**uint8)(__ccgo_up(bp + 40)) = uint8(SQLITE_AFF_NUMERIC) } } if pKeyInfo != 0 { *(*uintptr)(unsafe.Pointer(pKeyInfo + 32)) = _sqlite3ExprCollSeq(tls, pParse, (*TExpr)(unsafe.Pointer(pExpr)).FpLeft) } /* Loop through each expression in . */ r1 = _sqlite3GetTempReg(tls, pParse) r2 = _sqlite3GetTempReg(tls, pParse) i1 = (*TExprList)(unsafe.Pointer(pList)).FnExpr pItem = pList + 8 for { if !(i1 > 0) { break } pE2 = (*TExprList_item)(unsafe.Pointer(pItem)).FpExpr /* If the expression is not constant then we will need to ** disable the test that was generated above that makes sure ** this code only executes once. Because for a non-constant ** expression we need to rerun this code each time. */ if addrOnce != 0 && !(_sqlite3ExprIsConstant(tls, pParse, pE2) != 0) { _sqlite3VdbeChangeToNoop(tls, v, addrOnce-int32(1)) _sqlite3VdbeChangeToNoop(tls, v, addrOnce) **(**Tu32)(__ccgo_up(pExpr + 4)) &= ^libc.Uint32FromInt32(libc.Int32FromInt32(EP_Subrtn)) addrOnce = 0 } /* Evaluate the expression and insert it into the temp table */ _sqlite3ExprCode(tls, pParse, pE2, r1) _sqlite3VdbeAddOp4(tls, v, int32(OP_MakeRecord), r1, int32(1), r2, bp+40, int32(1)) _sqlite3VdbeAddOp4Int(tls, v, int32(OP_IdxInsert), iTab, r2, r1, int32(1)) goto _8 _8: ; i1 = i1 - 1 pItem += 32 } _sqlite3ReleaseTempReg(tls, pParse, r1) _sqlite3ReleaseTempReg(tls, pParse, r2) } } if pSig != 0 { (*TSubrtnSig)(unsafe.Pointer(pSig)).FbComplete = uint8(1) } if pKeyInfo != 0 { _sqlite3VdbeChangeP4(tls, v, addr, pKeyInfo, -int32(9)) } if addrOnce != 0 { _sqlite3VdbeAddOp1(tls, v, int32(OP_NullRow), iTab) _sqlite3VdbeJumpHere(tls, v, addrOnce) /* Subroutine return */ _sqlite3VdbeAddOp3(tls, v, int32(OP_Return), (*(*struct { FiAddr int32 FregReturn int32 })(unsafe.Pointer(pExpr + 64))).FregReturn, (*(*struct { FiAddr int32 FregReturn int32 })(unsafe.Pointer(pExpr + 64))).FiAddr, int32(1)) _sqlite3ClearTempRegCache(tls, pParse) } } // C documentation // // /* // ** Generate code for scalar subqueries used as a subquery expression // ** or EXISTS operator: // ** // ** (SELECT a FROM b) -- subquery // ** EXISTS (SELECT a FROM b) -- EXISTS subquery // ** // ** The pExpr parameter is the SELECT or EXISTS operator to be coded. // ** // ** Return the register that holds the result. For a multi-column SELECT, // ** the result is stored in a contiguous array of registers and the // ** return value is the register of the left-most result column. // ** Return 0 if an error occurs. // */ func _sqlite3CodeSubselect(tls *libc.TLS, pParse uintptr, pExpr uintptr) (r int32) { bp := tls.Alloc(64) defer tls.Free(64) var addrOnce, nReg, rReg, v1 int32 var db, pLeft, pLimit, pSel, v, v2 uintptr var _ /* dest at bp+0 */ TSelectDest _, _, _, _, _, _, _, _, _, _ = addrOnce, db, nReg, pLeft, pLimit, pSel, rReg, v, v1, v2 addrOnce = 0 /* Address of OP_Once at top of subroutine */ rReg = 0 /* New limit expression */ v = (*TParse)(unsafe.Pointer(pParse)).FpVdbe if (*TParse)(unsafe.Pointer(pParse)).FnErr != 0 { return 0 } pSel = *(*uintptr)(unsafe.Pointer(pExpr + 32)) /* If this routine has already been coded, then invoke it as a ** subroutine. */ if (*TExpr)(unsafe.Pointer(pExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_Subrtn)) != uint32(0) { _sqlite3VdbeExplain(tls, pParse, uint8(0), __ccgo_ts+8411, libc.VaList(bp+48, (*TSelect)(unsafe.Pointer(pSel)).FselId)) _sqlite3VdbeAddOp2(tls, v, int32(OP_Gosub), (*(*struct { FiAddr int32 FregReturn int32 })(unsafe.Pointer(pExpr + 64))).FregReturn, (*(*struct { FiAddr int32 FregReturn int32 })(unsafe.Pointer(pExpr + 64))).FiAddr) return (*TExpr)(unsafe.Pointer(pExpr)).FiTable } /* Begin coding the subroutine */ **(**Tu32)(__ccgo_up(pExpr + 4)) |= libc.Uint32FromInt32(libc.Int32FromInt32(EP_Subrtn)) v2 = pParse + 60 *(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1 v1 = *(*int32)(unsafe.Pointer(v2)) (*(*struct { FiAddr int32 FregReturn int32 })(unsafe.Pointer(pExpr + 64))).FregReturn = v1 (*(*struct { FiAddr int32 FregReturn int32 })(unsafe.Pointer(pExpr + 64))).FiAddr = _sqlite3VdbeAddOp2(tls, v, int32(OP_BeginSubrtn), 0, (*(*struct { FiAddr int32 FregReturn int32 })(unsafe.Pointer(pExpr + 64))).FregReturn) + int32(1) /* The evaluation of the EXISTS/SELECT must be repeated every time it ** is encountered if any of the following is true: ** ** * The right-hand side is a correlated subquery ** * The right-hand side is an expression list containing variables ** * We are inside a trigger ** ** If all of the above are false, then we can run this code just once ** save the results, and reuse the same result on subsequent invocations. */ if !((*TExpr)(unsafe.Pointer(pExpr)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_VarSelect)) != libc.Uint32FromInt32(0)) { addrOnce = _sqlite3VdbeAddOp0(tls, v, int32(OP_Once)) } /* For a SELECT, generate code to put the values for all columns of ** the first row into an array of registers and return the index of ** the first register. ** ** If this is an EXISTS, write an integer 0 (not exists) or 1 (exists) ** into a register and return that register number. ** ** In both cases, the query is augmented with "LIMIT 1". Any ** preexisting limit is discarded in place of the new LIMIT 1. */ if addrOnce != 0 { v2 = __ccgo_ts + 1704 } else { v2 = __ccgo_ts + 8380 } _sqlite3VdbeExplain(tls, pParse, uint8(1), __ccgo_ts+8429, libc.VaList(bp+48, v2, (*TSelect)(unsafe.Pointer(pSel)).FselId)) if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) == int32(TK_SELECT) { v1 = (*TExprList)(unsafe.Pointer((*TSelect)(unsafe.Pointer(pSel)).FpEList)).FnExpr } else { v1 = int32(1) } nReg = v1 _sqlite3SelectDestInit(tls, bp, 0, (*TParse)(unsafe.Pointer(pParse)).FnMem+int32(1)) **(**int32)(__ccgo_up(pParse + 60)) += nReg if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) == int32(TK_SELECT) { (**(**TSelectDest)(__ccgo_up(bp))).FeDest = uint8(SRT_Mem) if (*TSelect)(unsafe.Pointer(pSel)).FselFlags&uint32(SF_Distinct) != 0 && (*TSelect)(unsafe.Pointer(pSel)).FpLimit != 0 && (*TExpr)(unsafe.Pointer((*TSelect)(unsafe.Pointer(pSel)).FpLimit)).FpRight != 0 { /* If there is both a DISTINCT and an OFFSET clause, then allocate ** a separate dest.iSdst array for sqlite3Select() and other ** routines to populate. In this case results will be copied over ** into the dest.iSDParm array only after OFFSET processing. This ** ensures that in the case where OFFSET excludes all rows, the ** dest.iSDParm array is not left populated with the contents of the ** last row visited - it should be all NULLs if all rows were ** excluded by OFFSET. */ (**(**TSelectDest)(__ccgo_up(bp))).FiSdst = (*TParse)(unsafe.Pointer(pParse)).FnMem + int32(1) **(**int32)(__ccgo_up(pParse + 60)) += nReg } else { (**(**TSelectDest)(__ccgo_up(bp))).FiSdst = (**(**TSelectDest)(__ccgo_up(bp))).FiSDParm } (**(**TSelectDest)(__ccgo_up(bp))).FnSdst = nReg _sqlite3VdbeAddOp3(tls, v, int32(OP_Null), 0, (**(**TSelectDest)(__ccgo_up(bp))).FiSDParm, (*TParse)(unsafe.Pointer(pParse)).FnMem) } else { (**(**TSelectDest)(__ccgo_up(bp))).FeDest = uint8(SRT_Exists) _sqlite3VdbeAddOp2(tls, v, int32(OP_Integer), 0, (**(**TSelectDest)(__ccgo_up(bp))).FiSDParm) } if (*TSelect)(unsafe.Pointer(pSel)).FpLimit != 0 { /* The subquery already has a limit. If the pre-existing limit X is ** not already integer value 1 or 0, then make the new limit X<>0 so that ** the new limit is either 1 or 0 */ pLeft = (*TExpr)(unsafe.Pointer((*TSelect)(unsafe.Pointer(pSel)).FpLimit)).FpLeft if libc.BoolInt32((*TExpr)(unsafe.Pointer(pLeft)).Fflags&libc.Uint32FromInt32(libc.Int32FromInt32(EP_IntValue)) != uint32(0)) == 0 || *(*int32)(unsafe.Pointer(&(*TExpr)(unsafe.Pointer(pLeft)).Fu)) != int32(1) && *(*int32)(unsafe.Pointer(&(*TExpr)(unsafe.Pointer(pLeft)).Fu)) != 0 { db = (*TParse)(unsafe.Pointer(pParse)).Fdb pLimit = _sqlite3ExprInt32(tls, db, 0) if pLimit != 0 { (*TExpr)(unsafe.Pointer(pLimit)).FaffExpr = uint8(SQLITE_AFF_NUMERIC) pLimit = _sqlite3PExpr(tls, pParse, int32(TK_NE), _sqlite3ExprDup(tls, db, pLeft, 0), pLimit) } _sqlite3ExprDeferredDelete(tls, pParse, pLeft) (*TExpr)(unsafe.Pointer((*TSelect)(unsafe.Pointer(pSel)).FpLimit)).FpLeft = pLimit } } else { /* If there is no pre-existing limit add a limit of 1 */ pLimit = _sqlite3ExprInt32(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, int32(1)) (*TSelect)(unsafe.Pointer(pSel)).FpLimit = _sqlite3PExpr(tls, pParse, int32(TK_LIMIT), pLimit, uintptr(0)) } (*TSelect)(unsafe.Pointer(pSel)).FiLimit = 0 if _sqlite3Select(tls, pParse, pSel, bp) != 0 { (*TExpr)(unsafe.Pointer(pExpr)).Fop2 = (*TExpr)(unsafe.Pointer(pExpr)).Fop (*TExpr)(unsafe.Pointer(pExpr)).Fop = uint8(TK_ERROR) return 0 } v1 = (**(**TSelectDest)(__ccgo_up(bp))).FiSDParm rReg = v1 (*TExpr)(unsafe.Pointer(pExpr)).FiTable = v1 if addrOnce != 0 { _sqlite3VdbeJumpHere(tls, v, addrOnce) } /* Subroutine return */ _sqlite3VdbeAddOp3(tls, v, int32(OP_Return), (*(*struct { FiAddr int32 FregReturn int32 })(unsafe.Pointer(pExpr + 64))).FregReturn, (*(*struct { FiAddr int32 FregReturn int32 })(unsafe.Pointer(pExpr + 64))).FiAddr, int32(1)) _sqlite3ClearTempRegCache(tls, pParse) return rReg } // C documentation // // /* // ** All regular columns for table pTab have been puts into registers // ** starting with iRegStore. The registers that correspond to STORED // ** or VIRTUAL columns have not yet been initialized. This routine goes // ** back and computes the values for those columns based on the previously // ** computed normal columns. // */ func _sqlite3ComputeGeneratedColumns(tls *libc.TLS, pParse uintptr, iRegStore int32, pTab uintptr) { bp := tls.Alloc(64) defer tls.Free(64) var eProgress, i, ii, jj, x, v2 int32 var pCol, pOp, pRedo, zP4, v4 uintptr var _ /* w at bp+0 */ TWalker _, _, _, _, _, _, _, _, _, _, _ = eProgress, i, ii, jj, pCol, pOp, pRedo, x, zP4, v2, v4 /* Before computing generated columns, first go through and make sure ** that appropriate affinity has been applied to the regular columns */ _sqlite3TableAffinity(tls, (*TParse)(unsafe.Pointer(pParse)).FpVdbe, pTab, iRegStore) if (*TTable)(unsafe.Pointer(pTab)).FtabFlags&uint32(TF_HasStored) != uint32(0) { pOp = _sqlite3VdbeGetLastOp(tls, (*TParse)(unsafe.Pointer(pParse)).FpVdbe) if libc.Int32FromUint8((*TVdbeOp)(unsafe.Pointer(pOp)).Fopcode) == int32(OP_Affinity) { zP4 = *(*uintptr)(unsafe.Pointer(pOp + 16)) v2 = libc.Int32FromInt32(0) jj = v2 ii = v2 for { if !(**(**uint8)(__ccgo_up(zP4 + uintptr(jj))) != 0) { break } if libc.Int32FromUint16((**(**TColumn)(__ccgo_up((*TTable)(unsafe.Pointer(pTab)).FaCol + uintptr(ii)*16))).FcolFlags)&int32(COLFLAG_VIRTUAL) != 0 { goto _1 } if libc.Int32FromUint16((**(**TColumn)(__ccgo_up((*TTable)(unsafe.Pointer(pTab)).FaCol + uintptr(ii)*16))).FcolFlags)&int32(COLFLAG_STORED) != 0 { **(**uint8)(__ccgo_up(zP4 + uintptr(jj))) = uint8(SQLITE_AFF_NONE) } jj = jj + 1 goto _1 _1: ; ii = ii + 1 } } else { if libc.Int32FromUint8((*TVdbeOp)(unsafe.Pointer(pOp)).Fopcode) == int32(OP_TypeCheck) { /* If an OP_TypeCheck was generated because the table is STRICT, ** then set the P3 operand to indicate that generated columns should ** not be checked */ (*TVdbeOp)(unsafe.Pointer(pOp)).Fp3 = int32(1) } } } /* Because there can be multiple generated columns that refer to one another, ** this is a two-pass algorithm. On the first pass, mark all generated ** columns as "not available". */ i = 0 for { if !(i < int32((*TTable)(unsafe.Pointer(pTab)).FnCol)) { break } if libc.Int32FromUint16((**(**TColumn)(__ccgo_up((*TTable)(unsafe.Pointer(pTab)).FaCol + uintptr(i)*16))).FcolFlags)&int32(COLFLAG_GENERATED) != 0 { v4 = (*TTable)(unsafe.Pointer(pTab)).FaCol + uintptr(i)*16 + 14 *(*Tu16)(unsafe.Pointer(v4)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v4))) | libc.Int32FromInt32(COLFLAG_NOTAVAIL)) } goto _3 _3: ; i = i + 1 } *(*uintptr)(unsafe.Pointer(bp + 40)) = pTab (**(**TWalker)(__ccgo_up(bp))).FxExprCallback = __ccgo_fp(_exprColumnFlagUnion) (**(**TWalker)(__ccgo_up(bp))).FxSelectCallback = uintptr(0) (**(**TWalker)(__ccgo_up(bp))).FxSelectCallback2 = uintptr(0) /* On the second pass, compute the value of each NOT-AVAILABLE column. ** Companion code in the TK_COLUMN case of sqlite3ExprCodeTarget() will ** compute dependencies and mark remove the COLSPAN_NOTAVAIL mark, as ** they are needed. */ (*TParse)(unsafe.Pointer(pParse)).FiSelfTab = -iRegStore for cond := true; cond; cond = pRedo != 0 && eProgress != 0 { eProgress = 0 pRedo = uintptr(0) i = 0 for { if !(i < int32((*TTable)(unsafe.Pointer(pTab)).FnCol)) { break } pCol = (*TTable)(unsafe.Pointer(pTab)).FaCol + uintptr(i)*16 if libc.Int32FromUint16((*TColumn)(unsafe.Pointer(pCol)).FcolFlags)&int32(COLFLAG_NOTAVAIL) != 0 { v4 = pCol + 14 *(*Tu16)(unsafe.Pointer(v4)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v4))) | libc.Int32FromInt32(COLFLAG_BUSY)) (**(**TWalker)(__ccgo_up(bp))).FeCode = uint16(0) _sqlite3WalkExpr(tls, bp, _sqlite3ColumnExpr(tls, pTab, pCol)) v4 = pCol + 14 *(*Tu16)(unsafe.Pointer(v4)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v4))) & ^libc.Int32FromInt32(COLFLAG_BUSY)) if libc.Int32FromUint16((**(**TWalker)(__ccgo_up(bp))).FeCode)&int32(COLFLAG_NOTAVAIL) != 0 { pRedo = pCol goto _5 } eProgress = int32(1) x = int32(_sqlite3TableColumnToStorage(tls, pTab, int16(i))) + iRegStore _sqlite3ExprCodeGeneratedColumn(tls, pParse, pTab, pCol, x) v4 = pCol + 14 *(*Tu16)(unsafe.Pointer(v4)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v4))) & ^libc.Int32FromInt32(COLFLAG_NOTAVAIL)) } goto _5 _5: ; i = i + 1 } } if pRedo != 0 { _sqlite3ErrorMsg(tls, pParse, __ccgo_ts+8480, libc.VaList(bp+56, (*TColumn)(unsafe.Pointer(pRedo)).FzCnName)) } (*TParse)(unsafe.Pointer(pParse)).FiSelfTab = 0 } // C documentation // // /* // ** This routine is called to create a new foreign key on the table // ** currently under construction. pFromCol determines which columns // ** in the current table point to the foreign key. If pFromCol==0 then // ** connect the key to the last column inserted. pTo is the name of // ** the table referred to (a.k.a the "parent" table). pToCol is a list // ** of tables in the parent pTo table. flags contains all // ** information about the conflict resolution algorithms specified // ** in the ON DELETE, ON UPDATE and ON INSERT clauses. // ** // ** An FKey structure is created and added to the table currently // ** under construction in the pParse->pNewTable field. // ** // ** The foreign key is set for IMMEDIATE processing. A subsequent call // ** to sqlite3DeferForeignKey() might change this to DEFERRED. // */ func _sqlite3CreateForeignKey(tls *libc.TLS, pParse uintptr, pFromCol uintptr, pTo uintptr, pToCol uintptr, flags int32) { bp := tls.Alloc(32) defer tls.Free(32) var db, p, pFKey, pNextTo, z uintptr var i, iCol, j, n, nCol int32 var nByte Ti64 _, _, _, _, _, _, _, _, _, _, _ = db, i, iCol, j, n, nByte, nCol, p, pFKey, pNextTo, z db = (*TParse)(unsafe.Pointer(pParse)).Fdb pFKey = uintptr(0) p = (*TParse)(unsafe.Pointer(pParse)).FpNewTable if p == uintptr(0) || libc.Int32FromUint8((*TParse)(unsafe.Pointer(pParse)).FeParseMode) == int32(PARSE_MODE_DECLARE_VTAB) { goto fk_end } if pFromCol == uintptr(0) { iCol = int32((*TTable)(unsafe.Pointer(p)).FnCol) - int32(1) if iCol < 0 { goto fk_end } if pToCol != 0 && (*TExprList)(unsafe.Pointer(pToCol)).FnExpr != int32(1) { _sqlite3ErrorMsg(tls, pParse, __ccgo_ts+15199, libc.VaList(bp+8, (**(**TColumn)(__ccgo_up((*TTable)(unsafe.Pointer(p)).FaCol + uintptr(iCol)*16))).FzCnName, pTo)) goto fk_end } nCol = int32(1) } else { if pToCol != 0 && (*TExprList)(unsafe.Pointer(pToCol)).FnExpr != (*TExprList)(unsafe.Pointer(pFromCol)).FnExpr { _sqlite3ErrorMsg(tls, pParse, __ccgo_ts+15262, 0) goto fk_end } else { nCol = (*TExprList)(unsafe.Pointer(pFromCol)).FnExpr } } nByte = libc.Int64FromUint64(uint64(libc.UintptrFromInt32(0)+64) + libc.Uint64FromInt32(nCol)*uint64(16) + uint64((*TToken)(unsafe.Pointer(pTo)).Fn) + uint64(1)) if pToCol != 0 { i = 0 for { if !(i < (*TExprList)(unsafe.Pointer(pToCol)).FnExpr) { break } nByte = nByte + int64(_sqlite3Strlen30(tls, (*(*TExprList_item)(unsafe.Pointer(pToCol + 8 + uintptr(i)*32))).FzEName)+int32(1)) goto _1 _1: ; i = i + 1 } } pFKey = _sqlite3DbMallocZero(tls, db, libc.Uint64FromInt64(nByte)) if pFKey == uintptr(0) { goto fk_end } (*TFKey)(unsafe.Pointer(pFKey)).FpFrom = p (*TFKey)(unsafe.Pointer(pFKey)).FpNextFrom = (*(*struct { FaddColOffset int32 FpFKey uintptr FpDfltList uintptr })(unsafe.Pointer(p + 64))).FpFKey z = pFKey + 64 + uintptr(nCol)*16 (*TFKey)(unsafe.Pointer(pFKey)).FzTo = z if libc.Int32FromUint8((*TParse)(unsafe.Pointer(pParse)).FeParseMode) >= int32(PARSE_MODE_RENAME) { _sqlite3RenameTokenMap(tls, pParse, z, pTo) } libc.Xmemcpy(tls, z, (*TToken)(unsafe.Pointer(pTo)).Fz, uint64((*TToken)(unsafe.Pointer(pTo)).Fn)) **(**uint8)(__ccgo_up(z + uintptr((*TToken)(unsafe.Pointer(pTo)).Fn))) = uint8(0) _sqlite3Dequote(tls, z) z = z + uintptr((*TToken)(unsafe.Pointer(pTo)).Fn+uint32(1)) (*TFKey)(unsafe.Pointer(pFKey)).FnCol = nCol if pFromCol == uintptr(0) { (*(*TsColMap)(unsafe.Pointer(pFKey + 64))).FiFrom = int32((*TTable)(unsafe.Pointer(p)).FnCol) - int32(1) } else { i = 0 for { if !(i < nCol) { break } j = 0 for { if !(j < int32((*TTable)(unsafe.Pointer(p)).FnCol)) { break } if _sqlite3StrICmp(tls, (**(**TColumn)(__ccgo_up((*TTable)(unsafe.Pointer(p)).FaCol + uintptr(j)*16))).FzCnName, (*(*TExprList_item)(unsafe.Pointer(pFromCol + 8 + uintptr(i)*32))).FzEName) == 0 { (*(*TsColMap)(unsafe.Pointer(pFKey + 64 + uintptr(i)*16))).FiFrom = j break } goto _3 _3: ; j = j + 1 } if j >= int32((*TTable)(unsafe.Pointer(p)).FnCol) { _sqlite3ErrorMsg(tls, pParse, __ccgo_ts+15356, libc.VaList(bp+8, (*(*TExprList_item)(unsafe.Pointer(pFromCol + 8 + uintptr(i)*32))).FzEName)) goto fk_end } if libc.Int32FromUint8((*TParse)(unsafe.Pointer(pParse)).FeParseMode) >= int32(PARSE_MODE_RENAME) { _sqlite3RenameTokenRemap(tls, pParse, pFKey+64+uintptr(i)*16, (*(*TExprList_item)(unsafe.Pointer(pFromCol + 8 + uintptr(i)*32))).FzEName) } goto _2 _2: ; i = i + 1 } } if pToCol != 0 { i = 0 for { if !(i < nCol) { break } n = _sqlite3Strlen30(tls, (*(*TExprList_item)(unsafe.Pointer(pToCol + 8 + uintptr(i)*32))).FzEName) (*(*TsColMap)(unsafe.Pointer(pFKey + 64 + uintptr(i)*16))).FzCol = z if libc.Int32FromUint8((*TParse)(unsafe.Pointer(pParse)).FeParseMode) >= int32(PARSE_MODE_RENAME) { _sqlite3RenameTokenRemap(tls, pParse, z, (*(*TExprList_item)(unsafe.Pointer(pToCol + 8 + uintptr(i)*32))).FzEName) } libc.Xmemcpy(tls, z, (*(*TExprList_item)(unsafe.Pointer(pToCol + 8 + uintptr(i)*32))).FzEName, libc.Uint64FromInt32(n)) **(**uint8)(__ccgo_up(z + uintptr(n))) = uint8(0) z = z + uintptr(n+int32(1)) goto _4 _4: ; i = i + 1 } } (*TFKey)(unsafe.Pointer(pFKey)).FisDeferred = uint8(0) **(**Tu8)(__ccgo_up(pFKey + 45)) = libc.Uint8FromInt32(flags & libc.Int32FromInt32(0xff)) /* ON DELETE action */ **(**Tu8)(__ccgo_up(pFKey + 45 + 1)) = libc.Uint8FromInt32(flags >> libc.Int32FromInt32(8) & libc.Int32FromInt32(0xff)) /* ON UPDATE action */ pNextTo = _sqlite3HashInsert(tls, (*TTable)(unsafe.Pointer(p)).FpSchema+80, (*TFKey)(unsafe.Pointer(pFKey)).FzTo, pFKey) if pNextTo == pFKey { _sqlite3OomFault(tls, db) goto fk_end } if pNextTo != 0 { (*TFKey)(unsafe.Pointer(pFKey)).FpNextTo = pNextTo (*TFKey)(unsafe.Pointer(pNextTo)).FpPrevTo = pFKey } /* Link the foreign key to the table as the last step. */ (*(*struct { FaddColOffset int32 FpFKey uintptr FpDfltList uintptr })(unsafe.Pointer(p + 64))).FpFKey = pFKey pFKey = uintptr(0) goto fk_end fk_end: ; _sqlite3DbFree(tls, db, pFKey) _sqlite3ExprListDelete(tls, db, pFromCol) _sqlite3ExprListDelete(tls, db, pToCol) } // C documentation // // /* // ** The parser calls this routine in order to create a new VIEW // */ func _sqlite3CreateView(tls *libc.TLS, pParse uintptr, pBegin uintptr, pName1 uintptr, pName2 uintptr, pCNames uintptr, pSelect uintptr, isTemp int32, noErr int32) { bp := tls.Alloc(128) defer tls.Free(128) var db, p, z uintptr var iDb, n int32 var _ /* pName at bp+112 */ uintptr var _ /* sEnd at bp+0 */ TToken var _ /* sFix at bp+16 */ TDbFixer _, _, _, _, _ = db, iDb, n, p, z **(**uintptr)(__ccgo_up(bp + 112)) = uintptr(0) db = (*TParse)(unsafe.Pointer(pParse)).Fdb if int32((*TParse)(unsafe.Pointer(pParse)).FnVar) > 0 { _sqlite3ErrorMsg(tls, pParse, __ccgo_ts+14831, 0) goto create_view_fail } _sqlite3StartTable(tls, pParse, pName1, pName2, isTemp, int32(1), 0, noErr) p = (*TParse)(unsafe.Pointer(pParse)).FpNewTable if p == uintptr(0) || (*TParse)(unsafe.Pointer(pParse)).FnErr != 0 { goto create_view_fail } /* Legacy versions of SQLite allowed the use of the magic "rowid" column ** on a view, even though views do not have rowids. The following flag ** setting fixes this problem. But the fix can be disabled by compiling ** with -DSQLITE_ALLOW_ROWID_IN_VIEW in case there are legacy apps that ** depend upon the old buggy behavior. The ability can also be toggled ** using sqlite3_config(SQLITE_CONFIG_ROWID_IN_VIEW,...) */ **(**Tu32)(__ccgo_up(p + 48)) |= uint32(TF_NoVisibleRowid) /* Never allow rowid in view */ _sqlite3TwoPartName(tls, pParse, pName1, pName2, bp+112) iDb = _sqlite3SchemaToIndex(tls, db, (*TTable)(unsafe.Pointer(p)).FpSchema) _sqlite3FixInit(tls, bp+16, pParse, iDb, __ccgo_ts+11143, **(**uintptr)(__ccgo_up(bp + 112))) if _sqlite3FixSelect(tls, bp+16, pSelect) != 0 { goto create_view_fail } /* Make a copy of the entire SELECT statement that defines the view. ** This will force all the Expr.token.z values to be dynamically ** allocated rather than point to the input string - which means that ** they will persist after the current sqlite3_exec() call returns. */ **(**Tu32)(__ccgo_up(pSelect + 4)) |= uint32(SF_View) if libc.Int32FromUint8((*TParse)(unsafe.Pointer(pParse)).FeParseMode) >= int32(PARSE_MODE_RENAME) { (*(*struct { FpSelect uintptr })(unsafe.Pointer(&(*TTable)(unsafe.Pointer(p)).Fu))).FpSelect = pSelect pSelect = uintptr(0) } else { (*(*struct { FpSelect uintptr })(unsafe.Pointer(&(*TTable)(unsafe.Pointer(p)).Fu))).FpSelect = _sqlite3SelectDup(tls, db, pSelect, int32(EXPRDUP_REDUCE)) } (*TTable)(unsafe.Pointer(p)).FpCheck = _sqlite3ExprListDup(tls, db, pCNames, int32(EXPRDUP_REDUCE)) (*TTable)(unsafe.Pointer(p)).FeTabType = uint8(TABTYP_VIEW) if (*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0 { goto create_view_fail } /* Locate the end of the CREATE VIEW statement. Make sEnd point to ** the end. */ **(**TToken)(__ccgo_up(bp)) = (*TParse)(unsafe.Pointer(pParse)).FsLastToken if libc.Int32FromUint8(**(**uint8)(__ccgo_up((**(**TToken)(__ccgo_up(bp))).Fz))) != int32(';') { (**(**TToken)(__ccgo_up(bp))).Fz += uintptr((**(**TToken)(__ccgo_up(bp))).Fn) } (**(**TToken)(__ccgo_up(bp))).Fn = uint32(0) n = int32(int64((**(**TToken)(__ccgo_up(bp))).Fz) - int64((*TToken)(unsafe.Pointer(pBegin)).Fz)) z = (*TToken)(unsafe.Pointer(pBegin)).Fz for libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(z + uintptr(n-int32(1)))))])&int32(0x01) != 0 { n = n - 1 } (**(**TToken)(__ccgo_up(bp))).Fz = z + uintptr(n-int32(1)) (**(**TToken)(__ccgo_up(bp))).Fn = uint32(1) /* Use sqlite3EndTable() to add the view to the schema table */ _sqlite3EndTable(tls, pParse, uintptr(0), bp, uint32(0), uintptr(0)) goto create_view_fail create_view_fail: ; _sqlite3SelectDelete(tls, db, pSelect) if libc.Int32FromUint8((*TParse)(unsafe.Pointer(pParse)).FeParseMode) >= int32(PARSE_MODE_RENAME) { _sqlite3RenameExprlistUnmap(tls, pParse, pCNames) } _sqlite3ExprListDelete(tls, db, pCNames) return } // C documentation // // /* // ** Transform a UTF-8 integer literal, in either decimal or hexadecimal, // ** into a 64-bit signed integer. This routine accepts hexadecimal literals, // ** whereas sqlite3Atoi64() does not. // ** // ** Returns: // ** // ** 0 Successful transformation. Fits in a 64-bit signed integer. // ** 1 Excess text after the integer value // ** 2 Integer too large for a 64-bit signed integer or is malformed // ** 3 Special case of 9223372036854775808 // */ func _sqlite3DecOrHexToI64(tls *libc.TLS, z uintptr, pOut uintptr) (r int32) { bp := tls.Alloc(16) defer tls.Free(16) var i, k, n int32 var _ /* u at bp+0 */ Tu64 _, _, _ = i, k, n if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z))) == int32('0') && (libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + 1))) == int32('x') || libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + 1))) == int32('X')) { **(**Tu64)(__ccgo_up(bp)) = uint64(0) i = int32(2) for { if !(libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(i)))) == int32('0')) { break } goto _1 _1: ; i = i + 1 } k = i for { if !(libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(z + uintptr(k))))])&int32(0x08) != 0) { break } **(**Tu64)(__ccgo_up(bp)) = **(**Tu64)(__ccgo_up(bp))*uint64(16) + uint64(_sqlite3HexToInt(tls, libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(k)))))) goto _2 _2: ; k = k + 1 } libc.Xmemcpy(tls, pOut, bp, uint64(8)) if k-i > int32(16) { return int32(2) } if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(k)))) != 0 { return int32(1) } return 0 } else { n = libc.Int32FromUint64(libc.Uint64FromInt32(0x3fffffff) & libc.Xstrspn(tls, z, __ccgo_ts+1834)) if **(**uint8)(__ccgo_up(z + uintptr(n))) != 0 { n = n + 1 } return _sqlite3Atoi64(tls, z, pOut, n, uint8(SQLITE_UTF8)) } return r } // C documentation // // /* // ** Expression p is a QNUMBER (quoted number). Dequote the value in p->u.zToken // ** and set the type to INTEGER or FLOAT. "Quoted" integers or floats are those // ** that contain '_' characters that must be removed before further processing. // */ func _sqlite3DequoteNumber(tls *libc.TLS, pParse uintptr, p uintptr) { bp := tls.Alloc(32) defer tls.Free(32) var bHex int32 var pIn, pOut, v1, v3 uintptr var _ /* iValue at bp+0 */ int32 _, _, _, _, _ = bHex, pIn, pOut, v1, v3 if p != 0 { pIn = *(*uintptr)(unsafe.Pointer(p + 8)) pOut = *(*uintptr)(unsafe.Pointer(p + 8)) bHex = libc.BoolInt32(libc.Int32FromUint8(**(**uint8)(__ccgo_up(pIn))) == int32('0') && (libc.Int32FromUint8(**(**uint8)(__ccgo_up(pIn + 1))) == int32('x') || libc.Int32FromUint8(**(**uint8)(__ccgo_up(pIn + 1))) == int32('X'))) (*TExpr)(unsafe.Pointer(p)).Fop = uint8(TK_INTEGER) for { if libc.Int32FromUint8(**(**uint8)(__ccgo_up(pIn))) != int32('_') { v3 = pOut pOut = pOut + 1 **(**uint8)(__ccgo_up(v3)) = **(**uint8)(__ccgo_up(pIn)) if libc.Int32FromUint8(**(**uint8)(__ccgo_up(pIn))) == int32('e') || libc.Int32FromUint8(**(**uint8)(__ccgo_up(pIn))) == int32('E') || libc.Int32FromUint8(**(**uint8)(__ccgo_up(pIn))) == int32('.') { (*TExpr)(unsafe.Pointer(p)).Fop = uint8(TK_FLOAT) } } else { if bHex == 0 && (!(libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(pIn + uintptr(-libc.Int32FromInt32(1)))))])&libc.Int32FromInt32(0x04) != 0) || !(libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(pIn + 1)))])&libc.Int32FromInt32(0x04) != 0)) || bHex == int32(1) && (!(libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(pIn + uintptr(-libc.Int32FromInt32(1)))))])&libc.Int32FromInt32(0x08) != 0) || !(libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(pIn + 1)))])&libc.Int32FromInt32(0x08) != 0)) { _sqlite3ErrorMsg(tls, pParse, __ccgo_ts+1790, libc.VaList(bp+16, *(*uintptr)(unsafe.Pointer(p + 8)))) } } goto _2 _2: ; v1 = pIn pIn = pIn + 1 if !(**(**uint8)(__ccgo_up(v1)) != 0) { break } } if bHex != 0 { (*TExpr)(unsafe.Pointer(p)).Fop = uint8(TK_INTEGER) } /* tag-20240227-a: If after dequoting, the number is an integer that ** fits in 32 bits, then it must be converted into EP_IntValue. Other ** parts of the code expect this. See also tag-20240227-b. */ if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(p)).Fop) == int32(TK_INTEGER) && _sqlite3GetInt32(tls, *(*uintptr)(unsafe.Pointer(p + 8)), bp) != 0 { *(*int32)(unsafe.Pointer(&(*TExpr)(unsafe.Pointer(p)).Fu)) = **(**int32)(__ccgo_up(bp)) **(**Tu32)(__ccgo_up(p + 4)) |= uint32(EP_IntValue) } } } // C documentation // // /* // ** Assign a variable number to an expression that encodes a wildcard // ** in the original SQL statement. // ** // ** Wildcards consisting of a single "?" are assigned the next sequential // ** variable number. // ** // ** Wildcards of the form "?nnn" are assigned the number "nnn". We make // ** sure "nnn" is not too big to avoid a denial of service attack when // ** the SQL statement comes from an external source. // ** // ** Wildcards of the form ":aaa", "@aaa", or "$aaa" are assigned the same number // ** as the previous instance of the same wildcard. Or if this is the first // ** instance of the wildcard, the next sequential variable number is // ** assigned. // */ func _sqlite3ExprAssignVarNumber(tls *libc.TLS, pParse uintptr, pExpr uintptr, n Tu32) { bp := tls.Alloc(32) defer tls.Free(32) var bOk, doAdd int32 var db, z, v2 uintptr var x, v1 TynVar var _ /* i at bp+0 */ Ti64 _, _, _, _, _, _, _ = bOk, db, doAdd, x, z, v1, v2 db = (*TParse)(unsafe.Pointer(pParse)).Fdb if pExpr == uintptr(0) { return } z = *(*uintptr)(unsafe.Pointer(pExpr + 8)) if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + 1))) == 0 { /* Wildcard of the form "?". Assign the next variable number */ v2 = pParse + 304 *(*TynVar)(unsafe.Pointer(v2)) = *(*TynVar)(unsafe.Pointer(v2)) + 1 v1 = *(*TynVar)(unsafe.Pointer(v2)) x = v1 } else { doAdd = 0 if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z))) == int32('?') { if n == uint32(2) { /*OPTIMIZATION-IF-TRUE*/ **(**Ti64)(__ccgo_up(bp)) = int64(libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + 1))) - int32('0')) /* The common case of ?N for a single digit N */ bOk = int32(1) } else { bOk = libc.BoolInt32(0 == _sqlite3Atoi64(tls, z+1, bp, libc.Int32FromUint32(n-uint32(1)), uint8(SQLITE_UTF8))) } if bOk == 0 || **(**Ti64)(__ccgo_up(bp)) < int64(1) || **(**Ti64)(__ccgo_up(bp)) > int64(**(**int32)(__ccgo_up(db + 136 + 9*4))) { _sqlite3ErrorMsg(tls, pParse, __ccgo_ts+8087, libc.VaList(bp+16, **(**int32)(__ccgo_up(db + 136 + 9*4)))) _sqlite3RecordErrorOffsetOfExpr(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, pExpr) return } x = int16(**(**Ti64)(__ccgo_up(bp))) if int32(x) > int32((*TParse)(unsafe.Pointer(pParse)).FnVar) { (*TParse)(unsafe.Pointer(pParse)).FnVar = int16(int32(x)) doAdd = int32(1) } else { if _sqlite3VListNumToName(tls, (*TParse)(unsafe.Pointer(pParse)).FpVList, int32(x)) == uintptr(0) { doAdd = int32(1) } } } else { /* Wildcards like ":aaa", "$aaa" or "@aaa". Reuse the same variable ** number as the prior appearance of the same name, or if the name ** has never appeared before, reuse the same variable number */ x = int16(_sqlite3VListNameToNum(tls, (*TParse)(unsafe.Pointer(pParse)).FpVList, z, libc.Int32FromUint32(n))) if int32(x) == 0 { v2 = pParse + 304 *(*TynVar)(unsafe.Pointer(v2)) = *(*TynVar)(unsafe.Pointer(v2)) + 1 v1 = *(*TynVar)(unsafe.Pointer(v2)) x = v1 doAdd = int32(1) } } if doAdd != 0 { (*TParse)(unsafe.Pointer(pParse)).FpVList = _sqlite3VListAdd(tls, db, (*TParse)(unsafe.Pointer(pParse)).FpVList, z, libc.Int32FromUint32(n), int32(x)) } } (*TExpr)(unsafe.Pointer(pExpr)).FiColumn = x if int32(x) > **(**int32)(__ccgo_up(db + 136 + 9*4)) { _sqlite3ErrorMsg(tls, pParse, __ccgo_ts+8130, 0) _sqlite3RecordErrorOffsetOfExpr(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, pExpr) } } // C documentation // // /* // ** This function is used by the implementation of the IN (...) operator. // ** The pX parameter is the expression on the RHS of the IN operator, which // ** might be either a list of expressions or a subquery. // ** // ** The job of this routine is to find or create a b-tree object that can // ** be used either to test for membership in the RHS set or to iterate through // ** all members of the RHS set, skipping duplicates. // ** // ** A cursor is opened on the b-tree object that is the RHS of the IN operator // ** and the *piTab parameter is set to the index of that cursor. // ** // ** The returned value of this function indicates the b-tree type, as follows: // ** // ** IN_INDEX_ROWID - The cursor was opened on a database table. // ** IN_INDEX_INDEX_ASC - The cursor was opened on an ascending index. // ** IN_INDEX_INDEX_DESC - The cursor was opened on a descending index. // ** IN_INDEX_EPH - The cursor was opened on a specially created and // ** populated ephemeral table. // ** IN_INDEX_NOOP - No cursor was allocated. The IN operator must be // ** implemented as a sequence of comparisons. // ** // ** An existing b-tree might be used if the RHS expression pX is a simple // ** subquery such as: // ** // ** SELECT , ... FROM // ** // ** If the RHS of the IN operator is a list or a more complex subquery, then // ** an ephemeral table might need to be generated from the RHS and then // ** pX->iTable made to point to the ephemeral table instead of an // ** existing table. In this case, the creation and initialization of the // ** ephemeral table might be put inside of a subroutine, the EP_Subrtn flag // ** will be set on pX and the pX->y.sub fields will be set to show where // ** the subroutine is coded. // ** // ** The inFlags parameter must contain, at a minimum, one of the bits // ** IN_INDEX_MEMBERSHIP or IN_INDEX_LOOP but not both. If inFlags contains // ** IN_INDEX_MEMBERSHIP, then the generated table will be used for a fast // ** membership test. When the IN_INDEX_LOOP bit is set, the IN index will // ** be used to loop over all values of the RHS of the IN operator. // ** // ** When IN_INDEX_LOOP is used (and the b-tree will be used to iterate // ** through the set members) then the b-tree must not contain duplicates. // ** An ephemeral table will be created unless the selected columns are guaranteed // ** to be unique - either because it is an INTEGER PRIMARY KEY or due to // ** a UNIQUE constraint or index. // ** // ** When IN_INDEX_MEMBERSHIP is used (and the b-tree will be used // ** for fast set membership tests) then an ephemeral table must // ** be used unless is a single INTEGER PRIMARY KEY column or an // ** index can be found with the specified as its left-most. // ** // ** If the IN_INDEX_NOOP_OK and IN_INDEX_MEMBERSHIP are both set and // ** if the RHS of the IN operator is a list (not a subquery) then this // ** routine might decide that creating an ephemeral b-tree for membership // ** testing is too expensive and return IN_INDEX_NOOP. In that case, the // ** calling routine should implement the IN operator using a sequence // ** of Eq or Ne comparison operations. // ** // ** When the b-tree is being used for membership tests, the calling function // ** might need to know whether or not the RHS side of the IN operator // ** contains a NULL. If prRhsHasNull is not a NULL pointer and // ** if there is any chance that the (...) might contain a NULL value at // ** runtime, then a register is allocated and the register number written // ** to *prRhsHasNull. If there is no chance that the (...) contains a // ** NULL value, then *prRhsHasNull is left unchanged. // ** // ** If a register is allocated and its location stored in *prRhsHasNull, then // ** the value in that register will be NULL if the b-tree contains one or more // ** NULL values, and it will be some non-NULL value if the b-tree contains no // ** NULL values. // ** // ** If the aiMap parameter is not NULL, it must point to an array containing // ** one element for each column returned by the SELECT statement on the RHS // ** of the IN(...) operator. The i'th entry of the array is populated with the // ** offset of the index column that matches the i'th column returned by the // ** SELECT. For example, if the expression and selected index are: // ** // ** (?,?,?) IN (SELECT a, b, c FROM t1) // ** CREATE INDEX i1 ON t1(b, c, a); // ** // ** then aiMap[] is populated with {2, 0, 1}. // */ func _sqlite3FindInIndex(tls *libc.TLS, pParse uintptr, pX uintptr, inFlags Tu32, prRhsHasNull uintptr, aiMap uintptr, piTab uintptr) (r int32) { bp := tls.Alloc(16) defer tls.Free(16) var affinity_ok, bloomOk, eType, i, i1, i2, iAddr, iAddr1, iCol, iDb, iTab, j, mustBeUnique, n, nExpr, rMayHaveNull, v1, v10 int32 var cmpaff, idxaff uint8 var colUsed, mCol TBitmask var db, p, pEList, pEList1, pIdx, pLhs, pLhs1, pReq, pRhs, pTab, v, v2 uintptr var savedNQueryLoop Tu32 var v5 bool _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = affinity_ok, bloomOk, cmpaff, colUsed, db, eType, i, i1, i2, iAddr, iAddr1, iCol, iDb, iTab, idxaff, j, mCol, mustBeUnique, n, nExpr, p, pEList, pEList1, pIdx, pLhs, pLhs1, pReq, pRhs, pTab, rMayHaveNull, savedNQueryLoop, v, v1, v10, v2, v5 /* SELECT to the right of IN operator */ eType = 0 /* True if RHS must be unique */ v = _sqlite3GetVdbe(tls, pParse) /* Virtual machine being coded */ mustBeUnique = libc.BoolInt32(inFlags&uint32(IN_INDEX_LOOP) != uint32(0)) v2 = pParse + 56 v1 = *(*int32)(unsafe.Pointer(v2)) *(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1 iTab = v1 /* If the RHS of this IN(...) operator is a SELECT, and if it matters ** whether or not the SELECT result contains NULL values, check whether ** or not NULL is actually possible (it may not be, for example, due ** to NOT NULL constraints in the schema). If no NULL values are possible, ** set prRhsHasNull to 0 before continuing. */ if prRhsHasNull != 0 && (*TExpr)(unsafe.Pointer(pX)).Fflags&uint32(EP_xIsSelect) != uint32(0) { pEList = (*TSelect)(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(pX + 32)))).FpEList i = 0 for { if !(i < (*TExprList)(unsafe.Pointer(pEList)).FnExpr) { break } if _sqlite3ExprCanBeNull(tls, (*(*TExprList_item)(unsafe.Pointer(pEList + 8 + uintptr(i)*32))).FpExpr) != 0 { break } goto _3 _3: ; i = i + 1 } if i == (*TExprList)(unsafe.Pointer(pEList)).FnExpr { prRhsHasNull = uintptr(0) } } /* Check to see if an existing table or index can be used to ** satisfy the query. This is preferable to generating a new ** ephemeral table. */ if v5 = (*TParse)(unsafe.Pointer(pParse)).FnErr == 0; v5 { v2 = _isCandidateForInOpt(tls, pX) p = v2 } if v5 && v2 != uintptr(0) { db = (*TParse)(unsafe.Pointer(pParse)).Fdb /* Database idx for pTab */ pEList1 = (*TSelect)(unsafe.Pointer(p)).FpEList nExpr = (*TExprList)(unsafe.Pointer(pEList1)).FnExpr /* Because of isCandidateForInOpt(p) */ /* Because of isCandidateForInOpt(p) */ /* Because of isCandidateForInOpt(p) */ pTab = (*(*TSrcItem)(unsafe.Pointer((*TSelect)(unsafe.Pointer(p)).FpSrc + 8))).FpSTab /* Code an OP_Transaction and OP_TableLock for
. */ iDb = _sqlite3SchemaToIndex(tls, db, (*TTable)(unsafe.Pointer(pTab)).FpSchema) _sqlite3CodeVerifySchema(tls, pParse, iDb) _sqlite3TableLock(tls, pParse, iDb, (*TTable)(unsafe.Pointer(pTab)).Ftnum, uint8(0), (*TTable)(unsafe.Pointer(pTab)).FzName) /* sqlite3GetVdbe() has always been previously called */ if nExpr == int32(1) && int32((*TExpr)(unsafe.Pointer((*(*TExprList_item)(unsafe.Pointer(pEList1 + 8))).FpExpr)).FiColumn) < 0 { /* The "x IN (SELECT rowid FROM table)" case */ iAddr = _sqlite3VdbeAddOp0(tls, v, int32(OP_Once)) _sqlite3OpenTable(tls, pParse, iTab, iDb, pTab, int32(OP_OpenRead)) eType = int32(IN_INDEX_ROWID) _sqlite3VdbeExplain(tls, pParse, uint8(0), __ccgo_ts+8235, libc.VaList(bp+8, (*TTable)(unsafe.Pointer(pTab)).FzName)) _sqlite3VdbeJumpHere(tls, v, iAddr) } else { /* Iterator variable */ affinity_ok = int32(1) /* Check that the affinity that will be used to perform each ** comparison is the same as the affinity of each column in table ** on the RHS of the IN operator. If it not, it is not possible to ** use any index of the RHS table. */ i1 = 0 for { if !(i1 < nExpr && affinity_ok != 0) { break } pLhs = _sqlite3VectorFieldSubexpr(tls, (*TExpr)(unsafe.Pointer(pX)).FpLeft, i1) iCol = int32((*TExpr)(unsafe.Pointer((*(*TExprList_item)(unsafe.Pointer(pEList1 + 8 + uintptr(i1)*32))).FpExpr)).FiColumn) idxaff = _sqlite3TableColumnAffinity(tls, pTab, iCol) /* RHS table */ cmpaff = _sqlite3CompareAffinity(tls, pLhs, idxaff) switch libc.Int32FromUint8(cmpaff) { case int32(SQLITE_AFF_BLOB): case int32(SQLITE_AFF_TEXT): /* sqlite3CompareAffinity() only returns TEXT if one side or the ** other has no affinity and the other side is TEXT. Hence, ** the only way for cmpaff to be TEXT is for idxaff to be TEXT ** and for the term on the LHS of the IN to have no affinity. */ default: affinity_ok = libc.BoolInt32(libc.Int32FromUint8(idxaff) >= int32(SQLITE_AFF_NUMERIC)) } goto _6 _6: ; i1 = i1 + 1 } if affinity_ok != 0 { /* Search for an existing index that will work for this IN operator */ pIdx = (*TTable)(unsafe.Pointer(pTab)).FpIndex for { if !(pIdx != 0 && eType == 0) { break } /* Mask for the current column */ if libc.Int32FromUint16((*TIndex)(unsafe.Pointer(pIdx)).FnColumn) < nExpr { goto _7 } if (*TIndex)(unsafe.Pointer(pIdx)).FpPartIdxWhere != uintptr(0) { goto _7 } /* Maximum nColumn is BMS-2, not BMS-1, so that we can compute ** BITMASK(nExpr) without overflowing */ if libc.Int32FromUint16((*TIndex)(unsafe.Pointer(pIdx)).FnColumn) >= libc.Int32FromUint64(libc.Uint64FromInt64(8)*libc.Uint64FromInt32(8))-libc.Int32FromInt32(1) { goto _7 } if mustBeUnique != 0 { if libc.Int32FromUint16((*TIndex)(unsafe.Pointer(pIdx)).FnKeyCol) > nExpr || libc.Int32FromUint16((*TIndex)(unsafe.Pointer(pIdx)).FnColumn) > nExpr && !(libc.Int32FromUint8((*TIndex)(unsafe.Pointer(pIdx)).FonError) != libc.Int32FromInt32(OE_None)) { goto _7 /* This index is not unique over the IN RHS columns */ } } colUsed = uint64(0) /* Columns of index used so far */ i1 = 0 for { if !(i1 < nExpr) { break } pLhs1 = _sqlite3VectorFieldSubexpr(tls, (*TExpr)(unsafe.Pointer(pX)).FpLeft, i1) pRhs = (*(*TExprList_item)(unsafe.Pointer(pEList1 + 8 + uintptr(i1)*32))).FpExpr pReq = _sqlite3BinaryCompareCollSeq(tls, pParse, pLhs1, pRhs) j = 0 for { if !(j < nExpr) { break } if int32(**(**Ti16)(__ccgo_up((*TIndex)(unsafe.Pointer(pIdx)).FaiColumn + uintptr(j)*2))) != int32((*TExpr)(unsafe.Pointer(pRhs)).FiColumn) { goto _9 } if pReq != uintptr(0) && _sqlite3StrICmp(tls, (*TCollSeq)(unsafe.Pointer(pReq)).FzName, **(**uintptr)(__ccgo_up((*TIndex)(unsafe.Pointer(pIdx)).FazColl + uintptr(j)*8))) != 0 { goto _9 } break goto _9 _9: ; j = j + 1 } if j == nExpr { break } mCol = libc.Uint64FromInt32(1) << j if mCol&colUsed != 0 { break } /* Each column used only once */ colUsed = colUsed | mCol if aiMap != 0 { **(**int32)(__ccgo_up(aiMap + uintptr(i1)*4)) = j } goto _8 _8: ; i1 = i1 + 1 } if colUsed == libc.Uint64FromInt32(1)<0 round to min(iRound,mxRound) significant digits total. // ** // ** mxRound must be positive. // ** // ** The significant digits of the decimal representation are // ** stored in p->z[] which is a often (but not always) a pointer // ** into the middle of p->zBuf[]. There are p->n significant digits. // ** The p->z[] array is *not* zero-terminated. // */ func _sqlite3FpDecode(tls *libc.TLS, p uintptr, _r float64, iRound int32, mxRound int32) { bp := tls.Alloc(32) defer tls.Free(32) *(*float64)(unsafe.Pointer(bp)) = _r var e, i, j, jj, jj1, kk, kk1, kk2, n, nn, v1 int32 var v2, v21 Tu64 var z, zBuf uintptr var _ /* exp at bp+16 */ int32 var _ /* v at bp+8 */ Tu64 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = e, i, j, jj, jj1, kk, kk1, kk2, n, nn, v2, v21, z, zBuf, v1 **(**int32)(__ccgo_up(bp + 16)) = 0 /* Local alias for p->z */ (*TFpDecode)(unsafe.Pointer(p)).FisSpecial = uint8(0) /* Convert negative numbers to positive. Deal with Infinity, 0.0, and ** NaN. */ if **(**float64)(__ccgo_up(bp)) < float64(0) { (*TFpDecode)(unsafe.Pointer(p)).Fsign = uint8('-') **(**float64)(__ccgo_up(bp)) = -**(**float64)(__ccgo_up(bp)) } else { if **(**float64)(__ccgo_up(bp)) == float64(0) { (*TFpDecode)(unsafe.Pointer(p)).Fsign = uint8('+') (*TFpDecode)(unsafe.Pointer(p)).Fn = int32(1) (*TFpDecode)(unsafe.Pointer(p)).FiDP = int32(1) (*TFpDecode)(unsafe.Pointer(p)).Fz = __ccgo_ts + 1850 return } else { (*TFpDecode)(unsafe.Pointer(p)).Fsign = uint8('+') } } libc.Xmemcpy(tls, bp+8, bp, uint64(8)) e = libc.Int32FromUint64(**(**Tu64)(__ccgo_up(bp + 8)) >> libc.Int32FromInt32(52) & uint64(0x7ff)) if e == int32(0x7ff) { (*TFpDecode)(unsafe.Pointer(p)).FisSpecial = libc.Uint8FromInt32(int32(1) + libc.BoolInt32(**(**Tu64)(__ccgo_up(bp + 8)) != uint64(0x7ff0000000000000))) (*TFpDecode)(unsafe.Pointer(p)).Fn = 0 (*TFpDecode)(unsafe.Pointer(p)).FiDP = 0 (*TFpDecode)(unsafe.Pointer(p)).Fz = p + 16 return } **(**Tu64)(__ccgo_up(bp + 8)) = **(**Tu64)(__ccgo_up(bp + 8)) & uint64(0x000fffffffffffff) if e == 0 { nn = _countLeadingZeros(tls, **(**Tu64)(__ccgo_up(bp + 8))) **(**Tu64)(__ccgo_up(bp + 8)) = **(**Tu64)(__ccgo_up(bp + 8)) << libc.Uint64FromInt32(nn) e = -int32(1074) - nn } else { **(**Tu64)(__ccgo_up(bp + 8)) = **(**Tu64)(__ccgo_up(bp + 8))<= int32(18) { v1 = int32(18) } else { v1 = iRound + int32(1) } _sqlite3Fp2Convert10(tls, **(**Tu64)(__ccgo_up(bp + 8)), e, v1, bp+8, bp+16) /* Extract significant digits, start at the right-most slot in p->zBuf ** and working back to the right. "i" keeps track of the next slot in ** which to store a digit. */ zBuf = p + 16 i = int32(SQLITE_U64_DIGITS) for **(**Tu64)(__ccgo_up(bp + 8)) >= uint64(10) { kk = libc.Int32FromUint64(**(**Tu64)(__ccgo_up(bp + 8)) % uint64(100) * uint64(2)) **(**Tu16)(__ccgo_up(zBuf + uintptr(i-int32(2)))) = **(**Tu16)(__ccgo_up(uintptr(unsafe.Pointer(&_sqlite3DigitPairs)) + uintptr(kk))) i = i - int32(2) **(**Tu64)(__ccgo_up(bp + 8)) = **(**Tu64)(__ccgo_up(bp + 8)) / uint64(100) } if **(**Tu64)(__ccgo_up(bp + 8)) != 0 { i = i - 1 v1 = i **(**uint8)(__ccgo_up(zBuf + uintptr(v1))) = uint8(**(**Tu64)(__ccgo_up(bp + 8)) + uint64('0')) } n = int32(SQLITE_U64_DIGITS) - i /* Total number of digits extracted */ (*TFpDecode)(unsafe.Pointer(p)).FiDP = n + **(**int32)(__ccgo_up(bp + 16)) if iRound <= 0 { iRound = (*TFpDecode)(unsafe.Pointer(p)).FiDP - iRound if iRound == 0 && libc.Int32FromUint8(**(**uint8)(__ccgo_up(zBuf + uintptr(i)))) >= int32('5') { iRound = int32(1) i = i - 1 v1 = i **(**uint8)(__ccgo_up(zBuf + uintptr(v1))) = uint8('0') n = n + 1 (*TFpDecode)(unsafe.Pointer(p)).FiDP = (*TFpDecode)(unsafe.Pointer(p)).FiDP + 1 } } z = zBuf + uintptr(i) /* z points to the first digit */ if iRound > 0 && (iRound < n || n > mxRound) { if iRound > mxRound { iRound = mxRound } if iRound == int32(17) { /* If the precision is exactly 17, which only happens with the "!" ** flag (ex: "%!.17g") then try to reduce the precision if that ** yields text that will round-trip to the original floating-point. ** value. Thus, for exaple, 49.47 will render as 49.47, rather than ** as 49.469999999999999. */ if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + 15))) == int32('9') && libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + 14))) == int32('9') { jj = int32(14) for { if !(jj > 0 && libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(jj-int32(1))))) == int32('9')) { break } goto _4 _4: ; jj = jj - 1 } if jj == 0 { v2 = uint64(1) } else { v2 = libc.Uint64FromInt32(libc.Int32FromUint8(**(**uint8)(__ccgo_up(z))) - int32('0')) kk1 = int32(1) for { if !(kk1 < jj) { break } v2 = v2*uint64(10) + uint64(**(**uint8)(__ccgo_up(z + uintptr(kk1)))) - uint64('0') goto _5 _5: ; kk1 = kk1 + 1 } v2 = v2 + 1 } if **(**float64)(__ccgo_up(bp)) == _sqlite3Fp10Convert2(tls, v2, **(**int32)(__ccgo_up(bp + 16))+n-jj) { iRound = jj + int32(1) } } else { if (*TFpDecode)(unsafe.Pointer(p)).FiDP >= n || libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + 15))) == int32('0') && libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + 14))) == int32('0') && libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + 13))) == int32('0') { jj1 = int32(13) for { if !(libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(jj1-int32(1))))) == int32('0')) { break } goto _6 _6: ; jj1 = jj1 - 1 } v21 = libc.Uint64FromInt32(libc.Int32FromUint8(**(**uint8)(__ccgo_up(z))) - int32('0')) kk2 = int32(1) for { if !(kk2 < jj1) { break } v21 = v21*uint64(10) + uint64(**(**uint8)(__ccgo_up(z + uintptr(kk2)))) - uint64('0') goto _7 _7: ; kk2 = kk2 + 1 } if **(**float64)(__ccgo_up(bp)) == _sqlite3Fp10Convert2(tls, v21, **(**int32)(__ccgo_up(bp + 16))+n-jj1) { iRound = jj1 + int32(1) } } } } n = iRound if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(iRound)))) >= int32('5') { j = iRound - int32(1) for int32(1) != 0 { **(**uint8)(__ccgo_up(z + uintptr(j))) = **(**uint8)(__ccgo_up(z + uintptr(j))) + 1 if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(j)))) <= int32('9') { break } **(**uint8)(__ccgo_up(z + uintptr(j))) = uint8('0') if j == 0 { z = z - 1 **(**uint8)(__ccgo_up(z)) = uint8('1') n = n + 1 (*TFpDecode)(unsafe.Pointer(p)).FiDP = (*TFpDecode)(unsafe.Pointer(p)).FiDP + 1 break } else { j = j - 1 } } } } for libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(n-int32(1))))) == int32('0') { n = n - 1 } (*TFpDecode)(unsafe.Pointer(p)).Fn = n (*TFpDecode)(unsafe.Pointer(p)).Fz = z } // C documentation // // /* // ** Arguments nArg/azArg contain the string arguments passed to the xCreate // ** or xConnect method of the virtual table. This function attempts to // ** allocate an instance of Fts5Config containing the results of parsing // ** those arguments. // ** // ** If successful, SQLITE_OK is returned and *ppOut is set to point to the // ** new Fts5Config object. If an error occurs, an SQLite error code is // ** returned, *ppOut is set to NULL and an error message may be left in // ** *pzErr. It is the responsibility of the caller to eventually free any // ** such error message using sqlite3_free(). // */ func _sqlite3Fts5ConfigParse(tls *libc.TLS, pGlobal uintptr, db uintptr, nArg int32, azArg uintptr, ppOut uintptr, pzErr uintptr) (r int32) { bp := tls.Alloc(64) defer tls.Free(64) var bOption, i int32 var nByte Tsqlite3_int64 var pRet, z, zOrig, zTail, v1, v2 uintptr var _ /* bDummy at bp+28 */ int32 var _ /* bMustBeCol at bp+24 */ int32 var _ /* bUnindexed at bp+4 */ int32 var _ /* rc at bp+0 */ int32 var _ /* zOne at bp+8 */ uintptr var _ /* zTwo at bp+16 */ uintptr _, _, _, _, _, _, _, _, _ = bOption, i, nByte, pRet, z, zOrig, zTail, v1, v2 **(**int32)(__ccgo_up(bp)) = SQLITE_OK **(**int32)(__ccgo_up(bp + 4)) = 0 /* True if there are one or more UNINDEXED */ v1 = Xsqlite3_malloc64(tls, uint64(256)) pRet = v1 **(**uintptr)(__ccgo_up(ppOut)) = v1 if pRet == uintptr(0) { return int32(SQLITE_NOMEM) } libc.Xmemset(tls, pRet, 0, uint64(256)) (*TFts5Config)(unsafe.Pointer(pRet)).FpGlobal = pGlobal (*TFts5Config)(unsafe.Pointer(pRet)).Fdb = db (*TFts5Config)(unsafe.Pointer(pRet)).FiCookie = -int32(1) nByte = libc.Int64FromUint64(libc.Uint64FromInt32(nArg) * (libc.Uint64FromInt64(8) + libc.Uint64FromInt64(1))) (*TFts5Config)(unsafe.Pointer(pRet)).FazCol = _sqlite3Fts5MallocZero(tls, bp, nByte) if (*TFts5Config)(unsafe.Pointer(pRet)).FazCol != 0 { v1 = (*TFts5Config)(unsafe.Pointer(pRet)).FazCol + uintptr(nArg)*8 } else { v1 = uintptr(0) } (*TFts5Config)(unsafe.Pointer(pRet)).FabUnindexed = v1 (*TFts5Config)(unsafe.Pointer(pRet)).FzDb = _sqlite3Fts5Strndup(tls, bp, **(**uintptr)(__ccgo_up(azArg + 1*8)), -int32(1)) (*TFts5Config)(unsafe.Pointer(pRet)).FzName = _sqlite3Fts5Strndup(tls, bp, **(**uintptr)(__ccgo_up(azArg + 2*8)), -int32(1)) (*TFts5Config)(unsafe.Pointer(pRet)).FbColumnsize = int32(1) (*TFts5Config)(unsafe.Pointer(pRet)).FeDetail = FTS5_DETAIL_FULL if **(**int32)(__ccgo_up(bp)) == SQLITE_OK && Xsqlite3_stricmp(tls, (*TFts5Config)(unsafe.Pointer(pRet)).FzName, __ccgo_ts+37992) == 0 { **(**uintptr)(__ccgo_up(pzErr)) = Xsqlite3_mprintf(tls, __ccgo_ts+38103, libc.VaList(bp+40, (*TFts5Config)(unsafe.Pointer(pRet)).FzName)) **(**int32)(__ccgo_up(bp)) = int32(SQLITE_ERROR) } i = int32(3) for { if !(**(**int32)(__ccgo_up(bp)) == SQLITE_OK && i < nArg) { break } zOrig = **(**uintptr)(__ccgo_up(azArg + uintptr(i)*8)) **(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0) **(**uintptr)(__ccgo_up(bp + 16)) = uintptr(0) bOption = 0 **(**int32)(__ccgo_up(bp + 24)) = 0 z = _fts5ConfigGobbleWord(tls, bp, zOrig, bp+8, bp+24) z = _fts5ConfigSkipWhitespace(tls, z) if z != 0 && libc.Int32FromUint8(**(**uint8)(__ccgo_up(z))) == int32('=') { bOption = int32(1) z = z + 1 if **(**int32)(__ccgo_up(bp + 24)) != 0 { z = uintptr(0) } } z = _fts5ConfigSkipWhitespace(tls, z) if z != 0 && **(**uint8)(__ccgo_up(z)) != 0 { z = _fts5ConfigGobbleWord(tls, bp, z, bp+16, bp+28) if z != 0 && **(**uint8)(__ccgo_up(z)) != 0 { z = uintptr(0) } } if **(**int32)(__ccgo_up(bp)) == SQLITE_OK { if z == uintptr(0) { **(**uintptr)(__ccgo_up(pzErr)) = Xsqlite3_mprintf(tls, __ccgo_ts+38132, libc.VaList(bp+40, zOrig)) **(**int32)(__ccgo_up(bp)) = int32(SQLITE_ERROR) } else { if bOption != 0 { if **(**uintptr)(__ccgo_up(bp + 8)) != 0 { v1 = **(**uintptr)(__ccgo_up(bp + 8)) } else { v1 = __ccgo_ts + 1704 } if **(**uintptr)(__ccgo_up(bp + 16)) != 0 { v2 = **(**uintptr)(__ccgo_up(bp + 16)) } else { v2 = __ccgo_ts + 1704 } **(**int32)(__ccgo_up(bp)) = _fts5ConfigParseSpecial(tls, pRet, v1, v2, pzErr) } else { **(**int32)(__ccgo_up(bp)) = _fts5ConfigParseColumn(tls, pRet, **(**uintptr)(__ccgo_up(bp + 8)), **(**uintptr)(__ccgo_up(bp + 16)), pzErr, bp+4) **(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0) } } } Xsqlite3_free(tls, **(**uintptr)(__ccgo_up(bp + 8))) Xsqlite3_free(tls, **(**uintptr)(__ccgo_up(bp + 16))) goto _3 _3: ; i = i + 1 } /* We only allow contentless_delete=1 if the table is indeed contentless. */ if **(**int32)(__ccgo_up(bp)) == SQLITE_OK && (*TFts5Config)(unsafe.Pointer(pRet)).FbContentlessDelete != 0 && (*TFts5Config)(unsafe.Pointer(pRet)).FeContent != int32(FTS5_CONTENT_NONE) { **(**uintptr)(__ccgo_up(pzErr)) = Xsqlite3_mprintf(tls, __ccgo_ts+38152, 0) **(**int32)(__ccgo_up(bp)) = int32(SQLITE_ERROR) } /* We only allow contentless_delete=1 if columnsize=0 is not present. ** ** This restriction may be removed at some point. */ if **(**int32)(__ccgo_up(bp)) == SQLITE_OK && (*TFts5Config)(unsafe.Pointer(pRet)).FbContentlessDelete != 0 && (*TFts5Config)(unsafe.Pointer(pRet)).FbColumnsize == 0 { **(**uintptr)(__ccgo_up(pzErr)) = Xsqlite3_mprintf(tls, __ccgo_ts+38202, 0) **(**int32)(__ccgo_up(bp)) = int32(SQLITE_ERROR) } /* We only allow contentless_unindexed=1 if the table is actually a ** contentless one. */ if **(**int32)(__ccgo_up(bp)) == SQLITE_OK && (*TFts5Config)(unsafe.Pointer(pRet)).FbContentlessUnindexed != 0 && (*TFts5Config)(unsafe.Pointer(pRet)).FeContent != int32(FTS5_CONTENT_NONE) { **(**uintptr)(__ccgo_up(pzErr)) = Xsqlite3_mprintf(tls, __ccgo_ts+38257, 0) **(**int32)(__ccgo_up(bp)) = int32(SQLITE_ERROR) } /* If no zContent option was specified, fill in the default values. */ if **(**int32)(__ccgo_up(bp)) == SQLITE_OK && (*TFts5Config)(unsafe.Pointer(pRet)).FzContent == uintptr(0) { zTail = uintptr(0) if (*TFts5Config)(unsafe.Pointer(pRet)).FeContent == FTS5_CONTENT_NORMAL { zTail = __ccgo_ts + 37615 } else { if **(**int32)(__ccgo_up(bp + 4)) != 0 && (*TFts5Config)(unsafe.Pointer(pRet)).FbContentlessUnindexed != 0 { (*TFts5Config)(unsafe.Pointer(pRet)).FeContent = int32(FTS5_CONTENT_UNINDEXED) zTail = __ccgo_ts + 37615 } else { if (*TFts5Config)(unsafe.Pointer(pRet)).FbColumnsize != 0 { zTail = __ccgo_ts + 38310 } } } if zTail != 0 { (*TFts5Config)(unsafe.Pointer(pRet)).FzContent = _sqlite3Fts5Mprintf(tls, bp, __ccgo_ts+38318, libc.VaList(bp+40, (*TFts5Config)(unsafe.Pointer(pRet)).FzDb, (*TFts5Config)(unsafe.Pointer(pRet)).FzName, zTail)) } } if **(**int32)(__ccgo_up(bp)) == SQLITE_OK && (*TFts5Config)(unsafe.Pointer(pRet)).FzContentRowid == uintptr(0) { (*TFts5Config)(unsafe.Pointer(pRet)).FzContentRowid = _sqlite3Fts5Strndup(tls, bp, __ccgo_ts+17991, -int32(1)) } /* Formulate the zContentExprlist text */ if **(**int32)(__ccgo_up(bp)) == SQLITE_OK { **(**int32)(__ccgo_up(bp)) = _fts5ConfigMakeExprlist(tls, pRet) } if **(**int32)(__ccgo_up(bp)) != SQLITE_OK { _sqlite3Fts5ConfigFree(tls, pRet) **(**uintptr)(__ccgo_up(ppOut)) = uintptr(0) } return **(**int32)(__ccgo_up(bp)) } // C documentation // // /* // ** Attempt to load an SQLite extension library contained in the file // ** zFile. The entry point is zProc. zProc may be 0 in which case a // ** default entry point name (sqlite3_extension_init) is used. Use // ** of the default name is recommended. // ** // ** Return SQLITE_OK on success and SQLITE_ERROR if something goes wrong. // ** // ** If an error occurs and pzErrMsg is not 0, then fill *pzErrMsg with // ** error message text. The calling function should free this memory // ** by calling sqlite3DbFree(db, ). // */ func _sqlite3LoadExtension(tls *libc.TLS, db uintptr, zFile uintptr, zProc uintptr, pzErrMsg uintptr) (r int32) { bp := tls.Alloc(32) defer tls.Free(32) var aHandle, handle, pVfs, zAltEntry, zAltFile, zEntry, v1 uintptr var c, cnt, iEntry, iFile, ii, ncFile, rc, v3, v8 int32 var nMsg Tu64 var xInit Tsqlite3_loadext_entry var v4 bool var _ /* zErrmsg at bp+0 */ uintptr _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = aHandle, c, cnt, handle, iEntry, iFile, ii, nMsg, ncFile, pVfs, rc, xInit, zAltEntry, zAltFile, zEntry, v1, v3, v4, v8 pVfs = (*Tsqlite3)(unsafe.Pointer(db)).FpVfs **(**uintptr)(__ccgo_up(bp)) = uintptr(0) zAltEntry = uintptr(0) nMsg = uint64(libc.Xstrlen(tls, zFile)) if pzErrMsg != 0 { **(**uintptr)(__ccgo_up(pzErrMsg)) = uintptr(0) } /* Ticket #1863. To avoid a creating security problems for older ** applications that relink against newer versions of SQLite, the ** ability to run load_extension is turned off by default. One ** must call either sqlite3_enable_load_extension(db) or ** sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, 1, 0) ** to turn on extension loading. */ if (*Tsqlite3)(unsafe.Pointer(db)).Fflags&uint64(SQLITE_LoadExtension) == uint64(0) { if pzErrMsg != 0 { **(**uintptr)(__ccgo_up(pzErrMsg)) = Xsqlite3_mprintf(tls, __ccgo_ts+13699, 0) } return int32(SQLITE_ERROR) } if zProc != 0 { v1 = zProc } else { v1 = __ccgo_ts + 17615 } zEntry = v1 /* tag-20210611-1. Some dlopen() implementations will segfault if given ** an oversize filename. Most filesystems have a pathname limit of 4K, ** so limit the extension filename length to about twice that. ** https://sqlite.org/forum/forumpost/08a0d6d9bf ** ** Later (2023-03-25): Save an extra 6 bytes for the filename suffix. ** See https://sqlite.org/forum/forumpost/24083b579d. */ if nMsg > uint64(FILENAME_MAX) { goto extension_not_found } /* Do not allow sqlite3_load_extension() to link to a copy of the ** running application, by passing in an empty filename. */ if nMsg == uint64(0) { goto extension_not_found } handle = _sqlite3OsDlOpen(tls, pVfs, zFile) ii = 0 for { if !(ii < libc.Int32FromUint64(libc.Uint64FromInt64(8)/libc.Uint64FromInt64(8)) && handle == uintptr(0)) { break } zAltFile = Xsqlite3_mprintf(tls, __ccgo_ts+13660, libc.VaList(bp+16, zFile, _azEndings[ii])) if zAltFile == uintptr(0) { return int32(SQLITE_NOMEM) } if nMsg+uint64(libc.Xstrlen(tls, _azEndings[ii]))+uint64(1) <= uint64(FILENAME_MAX) { handle = _sqlite3OsDlOpen(tls, pVfs, zAltFile) } Xsqlite3_free(tls, zAltFile) goto _2 _2: ; ii = ii + 1 } if handle == uintptr(0) { goto extension_not_found } xInit = _sqlite3OsDlSym(tls, pVfs, handle, zEntry) /* If no entry point was specified and the default legacy ** entry point name "sqlite3_extension_init" was not found, then ** construct an entry point name "sqlite3_X_init" where the X is ** replaced by the lowercase value of every ASCII alphabetic ** character in the filename after the last "/" up to the first ".", ** and skipping the first three characters if they are "lib". ** Examples: ** ** /usr/local/lib/libExample5.4.3.so ==> sqlite3_example_init ** C:/lib/mathfuncs.dll ==> sqlite3_mathfuncs_init ** ** If that still finds no entry point, repeat a second time but this ** time include both alphabetic and numeric characters up to the first ** ".". Example: ** ** /usr/local/lib/libExample5.4.3.so ==> sqlite3_example5_init */ if xInit == uintptr(0) && zProc == uintptr(0) { ncFile = _sqlite3Strlen30(tls, zFile) cnt = 0 zAltEntry = Xsqlite3_malloc64(tls, libc.Uint64FromInt32(ncFile+int32(30))) if zAltEntry == uintptr(0) { _sqlite3OsDlClose(tls, pVfs, handle) return int32(SQLITE_NOMEM) } for { libc.Xmemcpy(tls, zAltEntry, __ccgo_ts+17638, uint64(8)) iFile = ncFile - int32(1) for { if !(iFile >= 0 && !(libc.Int32FromUint8(**(**uint8)(__ccgo_up(zFile + uintptr(iFile)))) == libc.Int32FromUint8('/'))) { break } goto _6 _6: ; iFile = iFile - 1 } iFile = iFile + 1 if Xsqlite3_strnicmp(tls, zFile+uintptr(iFile), __ccgo_ts+17647, int32(3)) == 0 { iFile = iFile + int32(3) } iEntry = int32(8) for { v3 = libc.Int32FromUint8(**(**uint8)(__ccgo_up(zFile + uintptr(iFile)))) c = v3 if !(v3 != 0 && c != int32('.')) { break } if libc.Int32FromUint8(_sqlite3CtypeMap[libc.Uint8FromInt32(c)])&int32(0x02) != 0 || cnt != 0 && libc.Int32FromUint8(_sqlite3CtypeMap[libc.Uint8FromInt32(c)])&int32(0x04) != 0 { v8 = iEntry iEntry = iEntry + 1 **(**uint8)(__ccgo_up(zAltEntry + uintptr(v8))) = _sqlite3UpperToLower[libc.Uint32FromInt32(c)] } goto _7 _7: ; iFile = iFile + 1 } libc.Xmemcpy(tls, zAltEntry+uintptr(iEntry), __ccgo_ts+17651, uint64(6)) zEntry = zAltEntry xInit = _sqlite3OsDlSym(tls, pVfs, handle, zEntry) goto _5 _5: ; if v4 = xInit == uintptr(0); v4 { cnt = cnt + 1 v3 = cnt } if !(v4 && v3 < int32(2)) { break } } } if xInit == uintptr(0) { if pzErrMsg != 0 { nMsg = nMsg + uint64(libc.Xstrlen(tls, zEntry)+uint64(300)) v1 = Xsqlite3_malloc64(tls, nMsg) **(**uintptr)(__ccgo_up(bp)) = v1 **(**uintptr)(__ccgo_up(pzErrMsg)) = v1 if **(**uintptr)(__ccgo_up(bp)) != 0 { /* zErrmsg would be NULL if not so */ Xsqlite3_snprintf(tls, libc.Int32FromUint64(nMsg), **(**uintptr)(__ccgo_up(bp)), __ccgo_ts+17657, libc.VaList(bp+16, zEntry, zFile)) _sqlite3OsDlError(tls, pVfs, libc.Int32FromUint64(nMsg-uint64(1)), **(**uintptr)(__ccgo_up(bp))) } } _sqlite3OsDlClose(tls, pVfs, handle) Xsqlite3_free(tls, zAltEntry) return int32(SQLITE_ERROR) } Xsqlite3_free(tls, zAltEntry) rc = (*(*func(*libc.TLS, uintptr, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{xInit})))(tls, db, bp, uintptr(unsafe.Pointer(&_sqlite3Apis))) if rc != 0 { if rc == libc.Int32FromInt32(SQLITE_OK)|libc.Int32FromInt32(1)<aExtension array. */ aHandle = _sqlite3DbMallocZero(tls, db, uint64(uint64(8)*libc.Uint64FromInt32((*Tsqlite3)(unsafe.Pointer(db)).FnExtension+libc.Int32FromInt32(1)))) if aHandle == uintptr(0) { return int32(SQLITE_NOMEM) } if (*Tsqlite3)(unsafe.Pointer(db)).FnExtension > 0 { libc.Xmemcpy(tls, aHandle, (*Tsqlite3)(unsafe.Pointer(db)).FaExtension, uint64(8)*libc.Uint64FromInt32((*Tsqlite3)(unsafe.Pointer(db)).FnExtension)) } _sqlite3DbFree(tls, db, (*Tsqlite3)(unsafe.Pointer(db)).FaExtension) (*Tsqlite3)(unsafe.Pointer(db)).FaExtension = aHandle v1 = db + 236 v3 = *(*int32)(unsafe.Pointer(v1)) *(*int32)(unsafe.Pointer(v1)) = *(*int32)(unsafe.Pointer(v1)) + 1 **(**uintptr)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaExtension + uintptr(v3)*8)) = handle return SQLITE_OK goto extension_not_found extension_not_found: ; if pzErrMsg != 0 { nMsg = nMsg + uint64(300) v1 = Xsqlite3_malloc64(tls, nMsg) **(**uintptr)(__ccgo_up(bp)) = v1 **(**uintptr)(__ccgo_up(pzErrMsg)) = v1 if **(**uintptr)(__ccgo_up(bp)) != 0 { /* zErrmsg would be NULL if not so */ Xsqlite3_snprintf(tls, libc.Int32FromUint64(nMsg), **(**uintptr)(__ccgo_up(bp)), __ccgo_ts+17732, libc.VaList(bp+16, int32(FILENAME_MAX), zFile)) _sqlite3OsDlError(tls, pVfs, libc.Int32FromUint64(nMsg-uint64(1)), **(**uintptr)(__ccgo_up(bp))) } } return int32(SQLITE_ERROR) } // C documentation // // /* // ** Allocate and initialize a new Pager object and put a pointer to it // ** in *ppPager. The pager should eventually be freed by passing it // ** to sqlite3PagerClose(). // ** // ** The zFilename argument is the path to the database file to open. // ** If zFilename is NULL then a randomly-named temporary file is created // ** and used as the file to be cached. Temporary files are be deleted // ** automatically when they are closed. If zFilename is ":memory:" then // ** all information is held in cache. It is never written to disk. // ** This can be used to implement an in-memory database. // ** // ** The nExtra parameter specifies the number of bytes of space allocated // ** along with each page reference. This space is available to the user // ** via the sqlite3PagerGetExtra() API. When a new page is allocated, the // ** first 8 bytes of this space are zeroed but the remainder is uninitialized. // ** (The extra space is used by btree as the MemPage object.) // ** // ** The flags argument is used to specify properties that affect the // ** operation of the pager. It should be passed some bitwise combination // ** of the PAGER_* flags. // ** // ** The vfsFlags parameter is a bitmask to pass to the flags parameter // ** of the xOpen() method of the supplied VFS when opening files. // ** // ** If the pager object is allocated and the specified file opened // ** successfully, SQLITE_OK is returned and *ppPager set to point to // ** the new pager object. If an error occurs, *ppPager is set to NULL // ** and error code returned. This function may return SQLITE_NOMEM // ** (sqlite3Malloc() is used to allocate memory), SQLITE_CANTOPEN or // ** various SQLITE_IO_XXX errors. // */ func _sqlite3PagerOpen(tls *libc.TLS, pVfs uintptr, ppPager uintptr, zFilename uintptr, nExtra int32, flags int32, vfsFlags int32, __ccgo_fp_xReinit uintptr) (r int32) { bp := tls.Alloc(16) defer tls.Free(16) var iDc, journalFileSize, memDb, memJM, nPathname, nUriByte, pcacheSize, rc, readOnly, tempFile, useJournal, v4 int32 var pPtr, z, zPathname, zUri, v1 uintptr var _ /* fout at bp+12 */ int32 var _ /* pPager at bp+0 */ uintptr var _ /* szPageDflt at bp+8 */ Tu32 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = iDc, journalFileSize, memDb, memJM, nPathname, nUriByte, pPtr, pcacheSize, rc, readOnly, tempFile, useJournal, z, zPathname, zUri, v1, v4 **(**uintptr)(__ccgo_up(bp)) = uintptr(0) /* Pager object to allocate and return */ rc = SQLITE_OK /* Return code */ tempFile = 0 /* True for temp files (incl. in-memory files) */ memDb = 0 /* True if this is an in-memory file */ memJM = 0 /* Memory journal mode */ readOnly = 0 /* Bytes to allocate for each journal fd */ zPathname = uintptr(0) /* Full path to database file */ nPathname = 0 /* Number of bytes in zPathname */ useJournal = libc.BoolInt32(flags&int32(PAGER_OMIT_JOURNAL) == 0) /* False to omit journal */ pcacheSize = _sqlite3PcacheSize(tls) /* Bytes to allocate for PCache */ **(**Tu32)(__ccgo_up(bp + 8)) = uint32(SQLITE_DEFAULT_PAGE_SIZE) /* Default page size */ zUri = uintptr(0) /* URI args to copy */ nUriByte = int32(1) /* Number of bytes of URI args at *zUri */ /* Figure out how much space is required for each journal file-handle ** (there are two of them, the main journal and the sub-journal). */ journalFileSize = (_sqlite3JournalSize(tls, pVfs) + int32(7)) & ^libc.Int32FromInt32(7) /* Set the output variable to NULL in case an error occurs. */ **(**uintptr)(__ccgo_up(ppPager)) = uintptr(0) if flags&int32(PAGER_MEMORY) != 0 { memDb = int32(1) if zFilename != 0 && **(**uint8)(__ccgo_up(zFilename)) != 0 { zPathname = _sqlite3DbStrDup(tls, uintptr(0), zFilename) if zPathname == uintptr(0) { return int32(SQLITE_NOMEM) } nPathname = _sqlite3Strlen30(tls, zPathname) zFilename = uintptr(0) } } /* Compute and store the full pathname in an allocated buffer pointed ** to by zPathname, length nPathname. Or, if this is a temporary file, ** leave both nPathname and zPathname set to 0. */ if zFilename != 0 && **(**uint8)(__ccgo_up(zFilename)) != 0 { nPathname = (*Tsqlite3_vfs)(unsafe.Pointer(pVfs)).FmxPathname + int32(1) zPathname = _sqlite3DbMallocRaw(tls, uintptr(0), libc.Uint64FromInt64(int64(2)*int64(nPathname))) if zPathname == uintptr(0) { return int32(SQLITE_NOMEM) } **(**uint8)(__ccgo_up(zPathname)) = uint8(0) /* Make sure initialized even if FullPathname() fails */ rc = _sqlite3OsFullPathname(tls, pVfs, zFilename, nPathname, zPathname) if rc != SQLITE_OK { if rc == libc.Int32FromInt32(SQLITE_OK)|libc.Int32FromInt32(2)< (*Tsqlite3_vfs)(unsafe.Pointer(pVfs)).FmxPathname { /* This branch is taken when the journal path required by ** the database being opened will be more than pVfs->mxPathname ** bytes in length. This means the database cannot be opened, ** as it will not be possible to open the journal file or even ** check for a hot-journal before reading. */ rc = _sqlite3CantopenError(tls, int32(64648)) } if rc != SQLITE_OK { _sqlite3DbFree(tls, uintptr(0), zPathname) return rc } } /* Allocate memory for the Pager structure, PCache object, the ** three file descriptors, the database file name and the journal ** file name. The layout in memory is as follows: ** ** Pager object (sizeof(Pager) bytes) ** PCache object (sqlite3PcacheSize() bytes) ** Database file handle (pVfs->szOsFile bytes) ** Sub-journal file handle (journalFileSize bytes) ** Main journal file handle (journalFileSize bytes) ** Ptr back to the Pager (sizeof(Pager*) bytes) ** \0\0\0\0 database prefix (4 bytes) ** Database file name (nPathname+1 bytes) ** URI query parameters (nUriByte bytes) ** Journal filename (nPathname+8+1 bytes) ** WAL filename (nPathname+4+1 bytes) ** \0\0\0 terminator (3 bytes) ** ** Some 3rd-party software, over which we have no control, depends on ** the specific order of the filenames and the \0 separators between them ** so that it can (for example) find the database filename given the WAL ** filename without using the sqlite3_filename_database() API. This is a ** misuse of SQLite and a bug in the 3rd-party software, but the 3rd-party ** software is in widespread use, so we try to avoid changing the filename ** order and formatting if possible. In particular, the details of the ** filename format expected by 3rd-party software should be as follows: ** ** - Main Database Path ** - \0 ** - Multiple URI components consisting of: ** - Key ** - \0 ** - Value ** - \0 ** - \0 ** - Journal Path ** - \0 ** - WAL Path (zWALName) ** - \0 ** ** The sqlite3_create_filename() interface and the databaseFilename() utility ** that is used by sqlite3_filename_database() and kin also depend on the ** specific formatting and order of the various filenames, so if the format ** changes here, be sure to change it there as well. */ pPtr = _sqlite3MallocZero(tls, uint64((libc.Uint64FromInt64(312)+libc.Uint64FromInt32(7))&libc.Uint64FromInt32(^libc.Int32FromInt32(7))+libc.Uint64FromInt32((pcacheSize+libc.Int32FromInt32(7)) & ^libc.Int32FromInt32(7))+libc.Uint64FromInt32(((*Tsqlite3_vfs)(unsafe.Pointer(pVfs)).FszOsFile+libc.Int32FromInt32(7)) & ^libc.Int32FromInt32(7)))+libc.Uint64FromInt32(journalFileSize)*uint64(2)+uint64(__SIZEOF_POINTER__)+uint64(4)+libc.Uint64FromInt32(nPathname)+uint64(1)+libc.Uint64FromInt32(nUriByte)+libc.Uint64FromInt32(nPathname)+uint64(8)+uint64(1)+libc.Uint64FromInt32(nPathname)+uint64(4)+uint64(1)+uint64(3)) if !(pPtr != 0) { _sqlite3DbFree(tls, uintptr(0), zPathname) return int32(SQLITE_NOMEM) } **(**uintptr)(__ccgo_up(bp)) = pPtr pPtr = pPtr + uintptr((libc.Uint64FromInt64(312)+libc.Uint64FromInt32(7))&libc.Uint64FromInt32(^libc.Int32FromInt32(7))) (*TPager)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FpPCache = pPtr pPtr = pPtr + uintptr((pcacheSize+libc.Int32FromInt32(7)) & ^libc.Int32FromInt32(7)) (*TPager)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).Ffd = pPtr pPtr = pPtr + uintptr(((*Tsqlite3_vfs)(unsafe.Pointer(pVfs)).FszOsFile+libc.Int32FromInt32(7)) & ^libc.Int32FromInt32(7)) (*TPager)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).Fsjfd = pPtr pPtr = pPtr + uintptr(journalFileSize) (*TPager)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).Fjfd = pPtr pPtr = pPtr + uintptr(journalFileSize) libc.Xmemcpy(tls, pPtr, bp, uint64(__SIZEOF_POINTER__)) pPtr = pPtr + uintptr(__SIZEOF_POINTER__) /* Fill in the Pager.zFilename and pPager.zQueryParam fields */ pPtr = pPtr + uintptr(4) /* Skip zero prefix */ (*TPager)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FzFilename = pPtr if nPathname > 0 { libc.Xmemcpy(tls, pPtr, zPathname, libc.Uint64FromInt32(nPathname)) pPtr = pPtr + uintptr(nPathname+int32(1)) if zUri != 0 { libc.Xmemcpy(tls, pPtr, zUri, libc.Uint64FromInt32(nUriByte)) pPtr = pPtr + uintptr(nUriByte) } else { pPtr = pPtr + 1 } } /* Fill in Pager.zJournal */ if nPathname > 0 { (*TPager)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FzJournal = pPtr libc.Xmemcpy(tls, pPtr, zPathname, libc.Uint64FromInt32(nPathname)) pPtr = pPtr + uintptr(nPathname) libc.Xmemcpy(tls, pPtr, __ccgo_ts+4255, uint64(8)) pPtr = pPtr + uintptr(libc.Int32FromInt32(8)+libc.Int32FromInt32(1)) } else { (*TPager)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FzJournal = uintptr(0) } /* Fill in Pager.zWal */ if nPathname > 0 { (*TPager)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FzWal = pPtr libc.Xmemcpy(tls, pPtr, zPathname, libc.Uint64FromInt32(nPathname)) pPtr = pPtr + uintptr(nPathname) libc.Xmemcpy(tls, pPtr, __ccgo_ts+4264, uint64(4)) pPtr = pPtr + uintptr(libc.Int32FromInt32(4)+libc.Int32FromInt32(1)) } else { (*TPager)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FzWal = uintptr(0) } _ = pPtr /* Suppress warning about unused pPtr value */ if nPathname != 0 { _sqlite3DbFree(tls, uintptr(0), zPathname) } (*TPager)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FpVfs = pVfs (*TPager)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FvfsFlags = libc.Uint32FromInt32(vfsFlags) /* Open the pager file. */ if !(zFilename != 0 && **(**uint8)(__ccgo_up(zFilename)) != 0) { goto _2 } **(**int32)(__ccgo_up(bp + 12)) = 0 /* VFS flags returned by xOpen() */ rc = _sqlite3OsOpen(tls, pVfs, (*TPager)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FzFilename, (*TPager)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).Ffd, vfsFlags, bp+12) v4 = libc.BoolInt32(**(**int32)(__ccgo_up(bp + 12))&libc.Int32FromInt32(SQLITE_OPEN_MEMORY) != libc.Int32FromInt32(0)) memJM = v4 (*TPager)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FmemVfs = libc.Uint8FromInt32(v4) readOnly = libc.BoolInt32(**(**int32)(__ccgo_up(bp + 12))&int32(SQLITE_OPEN_READONLY) != 0) /* If the file was successfully opened for read/write access, ** choose a default page size in case we have to create the ** database file. The default page size is the maximum of: ** ** + SQLITE_DEFAULT_PAGE_SIZE, ** + The value returned by sqlite3OsSectorSize() ** + The largest page size that can be written atomically. */ if rc == SQLITE_OK { iDc = _sqlite3OsDeviceCharacteristics(tls, (*TPager)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).Ffd) if !(readOnly != 0) { _setSectorSize(tls, **(**uintptr)(__ccgo_up(bp))) if **(**Tu32)(__ccgo_up(bp + 8)) < (*TPager)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FsectorSize { if (*TPager)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FsectorSize > uint32(SQLITE_MAX_DEFAULT_PAGE_SIZE) { **(**Tu32)(__ccgo_up(bp + 8)) = uint32(SQLITE_MAX_DEFAULT_PAGE_SIZE) } else { **(**Tu32)(__ccgo_up(bp + 8)) = (*TPager)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FsectorSize } } } (*TPager)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FnoLock = libc.Uint8FromInt32(Xsqlite3_uri_boolean(tls, (*TPager)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FzFilename, __ccgo_ts+4269, 0)) if iDc&int32(SQLITE_IOCAP_IMMUTABLE) != 0 || Xsqlite3_uri_boolean(tls, (*TPager)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FzFilename, __ccgo_ts+4276, 0) != 0 { vfsFlags = vfsFlags | int32(SQLITE_OPEN_READONLY) goto act_like_temp_file } } goto _3 _2: ; /* If a temporary file is requested, it is not opened immediately. ** In this case we accept the default page size and delay actually ** opening the file until the first call to OsWrite(). ** ** This branch is also run for an in-memory database. An in-memory ** database is the same as a temp-file that is never written out to ** disk and uses an in-memory rollback journal. ** ** This branch also runs for files marked as immutable. */ goto act_like_temp_file act_like_temp_file: ; tempFile = int32(1) (*TPager)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FeState = uint8(PAGER_READER) /* Pretend we already have a lock */ (*TPager)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FeLock = uint8(EXCLUSIVE_LOCK) /* Pretend we are in EXCLUSIVE mode */ (*TPager)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FnoLock = uint8(1) /* Do no locking */ readOnly = vfsFlags & int32(SQLITE_OPEN_READONLY) _3: ; /* The following call to PagerSetPagesize() serves to set the value of ** Pager.pageSize and to allocate the Pager.pTmpSpace buffer. */ if rc == SQLITE_OK { rc = _sqlite3PagerSetPagesize(tls, **(**uintptr)(__ccgo_up(bp)), bp+8, -int32(1)) } /* Initialize the PCache object. */ if rc == SQLITE_OK { nExtra = (nExtra + int32(7)) & ^libc.Int32FromInt32(7) if !(memDb != 0) { v1 = __ccgo_fp(_pagerStress) } else { v1 = uintptr(0) } rc = _sqlite3PcacheOpen(tls, libc.Int32FromUint32(**(**Tu32)(__ccgo_up(bp + 8))), nExtra, libc.BoolInt32(!(memDb != 0)), v1, **(**uintptr)(__ccgo_up(bp)), (*TPager)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FpPCache) } /* If an error occurred above, free the Pager structure and close the file. */ if rc != SQLITE_OK { _sqlite3OsClose(tls, (*TPager)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).Ffd) _sqlite3PageFree(tls, (*TPager)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FpTmpSpace) Xsqlite3_free(tls, **(**uintptr)(__ccgo_up(bp))) return rc } (*TPager)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FuseJournal = libc.Uint8FromInt32(useJournal) /* pPager->stmtOpen = 0; */ /* pPager->stmtInUse = 0; */ /* pPager->nRef = 0; */ /* pPager->stmtSize = 0; */ /* pPager->stmtJSize = 0; */ /* pPager->nPage = 0; */ (*TPager)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FmxPgno = uint32(SQLITE_MAX_PAGE_COUNT) /* pPager->state = PAGER_UNLOCK; */ /* pPager->errMask = 0; */ (*TPager)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FtempFile = libc.Uint8FromInt32(tempFile) (*TPager)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FexclusiveMode = libc.Uint8FromInt32(tempFile) (*TPager)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FchangeCountDone = (*TPager)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FtempFile (*TPager)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FmemDb = libc.Uint8FromInt32(memDb) (*TPager)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FreadOnly = libc.Uint8FromInt32(readOnly) _sqlite3PagerSetFlags(tls, **(**uintptr)(__ccgo_up(bp)), libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_DEFAULT_SYNCHRONOUS)+libc.Int32FromInt32(1)|libc.Int32FromInt32(PAGER_CACHESPILL))) /* pPager->pFirst = 0; */ /* pPager->pFirstSynced = 0; */ /* pPager->pLast = 0; */ (*TPager)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FnExtra = libc.Uint16FromInt32(nExtra) (*TPager)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FjournalSizeLimit = int64(-int32(1)) _setSectorSize(tls, **(**uintptr)(__ccgo_up(bp))) if !(useJournal != 0) { (*TPager)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FjournalMode = uint8(PAGER_JOURNALMODE_OFF) } else { if memDb != 0 || memJM != 0 { (*TPager)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FjournalMode = uint8(PAGER_JOURNALMODE_MEMORY) } } /* pPager->xBusyHandler = 0; */ /* pPager->pBusyHandlerArg = 0; */ (*TPager)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FxReiniter = __ccgo_fp_xReinit _setGetterMethod(tls, **(**uintptr)(__ccgo_up(bp))) /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */ /* pPager->szMmap = SQLITE_DEFAULT_MMAP_SIZE // will be set by btree.c */ **(**uintptr)(__ccgo_up(ppPager)) = **(**uintptr)(__ccgo_up(bp)) return SQLITE_OK } // C documentation // // /* // ** This function is used to parse both URIs and non-URI filenames passed by the // ** user to API functions sqlite3_open() or sqlite3_open_v2(), and for database // ** URIs specified as part of ATTACH statements. // ** // ** The first argument to this function is the name of the VFS to use (or // ** a NULL to signify the default VFS) if the URI does not contain a "vfs=xxx" // ** query parameter. The second argument contains the URI (or non-URI filename) // ** itself. When this function is called the *pFlags variable should contain // ** the default flags to open the database handle with. The value stored in // ** *pFlags may be updated before returning if the URI filename contains // ** "cache=xxx" or "mode=xxx" query parameters. // ** // ** If successful, SQLITE_OK is returned. In this case *ppVfs is set to point to // ** the VFS that should be used to open the database file. *pzFile is set to // ** point to a buffer containing the name of the file to open. The value // ** stored in *pzFile is a database name acceptable to sqlite3_uri_parameter() // ** and is in the same format as names created using sqlite3_create_filename(). // ** The caller must invoke sqlite3_free_filename() (not sqlite3_free()!) on // ** the value returned in *pzFile to avoid a memory leak. // ** // ** If an error occurs, then an SQLite error code is returned and *pzErrMsg // ** may be set to point to a buffer containing an English language error // ** message. It is the responsibility of the caller to eventually release // ** this buffer by calling sqlite3_free(). // */ func _sqlite3ParseUri(tls *libc.TLS, zDefaultVfs uintptr, zUri uintptr, pFlags uintptr, ppVfs uintptr, pzFile uintptr, pzErrMsg uintptr) (r int32) { bp := tls.Alloc(32) defer tls.Free(32) var aMode, z, zFile, zModeType, zOpt, zVal, zVfs uintptr var c, v2 uint8 var eState, i, limit, mask, mode, octet, rc int32 var flags uint32 var iIn, iOut, nOpt, nUri, nVal, v3, v4 Ti64 var nByte Tu64 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = aMode, c, eState, flags, i, iIn, iOut, limit, mask, mode, nByte, nOpt, nUri, nVal, octet, rc, z, zFile, zModeType, zOpt, zVal, zVfs, v2, v3, v4 rc = SQLITE_OK flags = **(**uint32)(__ccgo_up(pFlags)) zVfs = zDefaultVfs nUri = libc.Int64FromUint64(libc.Xstrlen(tls, zUri)) if (flags&uint32(SQLITE_OPEN_URI) != 0 || libc.AtomicLoadNUint8(uintptr(unsafe.Pointer(&_sqlite3Config))+6, libc.Int32FromInt32(__ATOMIC_RELAXED)) != 0) && nUri >= int64(5) && libc.Xmemcmp(tls, zUri, __ccgo_ts+26142, uint64(5)) == 0 { /* Input character index */ iOut = 0 /* Output character index */ nByte = libc.Uint64FromInt64(nUri + int64(8)) /* Bytes of space to allocate */ /* Make sure the SQLITE_OPEN_URI flag is set to indicate to the VFS xOpen ** method that there may be extra parameters following the file-name. */ flags = flags | uint32(SQLITE_OPEN_URI) iIn = 0 for { if !(iIn < nUri) { break } nByte = nByte + libc.BoolUint64(libc.Int32FromUint8(**(**uint8)(__ccgo_up(zUri + uintptr(iIn)))) == libc.Int32FromUint8('&')) goto _1 _1: ; iIn = iIn + 1 } zFile = Xsqlite3_malloc64(tls, nByte) if !(zFile != 0) { return int32(SQLITE_NOMEM) } libc.Xmemset(tls, zFile, 0, uint64(4)) /* 4-byte of 0x00 is the start of DB name marker */ zFile = zFile + uintptr(4) iIn = int64(5) /* Discard the scheme and authority segments of the URI. */ if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zUri + 5))) == int32('/') && libc.Int32FromUint8(**(**uint8)(__ccgo_up(zUri + 6))) == int32('/') { iIn = int64(7) for **(**uint8)(__ccgo_up(zUri + uintptr(iIn))) != 0 && libc.Int32FromUint8(**(**uint8)(__ccgo_up(zUri + uintptr(iIn)))) != int32('/') { iIn = iIn + 1 } if iIn != int64(7) && (iIn != int64(16) || libc.Xmemcmp(tls, __ccgo_ts+26148, zUri+7, uint64(9)) != 0) { **(**uintptr)(__ccgo_up(pzErrMsg)) = Xsqlite3_mprintf(tls, __ccgo_ts+26158, libc.VaList(bp+8, int32(iIn-libc.Int64FromInt32(7)), zUri+7)) rc = int32(SQLITE_ERROR) goto parse_uri_out } } /* Copy the filename and any query parameters into the zFile buffer. ** Decode %HH escape codes along the way. ** ** Within this loop, variable eState may be set to 0, 1 or 2, depending ** on the parsing context. As follows: ** ** 0: Parsing file-name. ** 1: Parsing name section of a name=value query parameter. ** 2: Parsing value section of a name=value query parameter. */ eState = 0 for { v2 = **(**uint8)(__ccgo_up(zUri + uintptr(iIn))) c = v2 if !(libc.Int32FromUint8(v2) != 0 && libc.Int32FromUint8(c) != int32('#')) { break } iIn = iIn + 1 if libc.Int32FromUint8(c) == int32('%') && libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(zUri + uintptr(iIn))))])&int32(0x08) != 0 && libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(zUri + uintptr(iIn+int64(1)))))])&int32(0x08) != 0 { v3 = iIn iIn = iIn + 1 octet = libc.Int32FromUint8(_sqlite3HexToInt(tls, libc.Int32FromUint8(**(**uint8)(__ccgo_up(zUri + uintptr(v3)))))) << int32(4) v4 = iIn iIn = iIn + 1 octet = octet + libc.Int32FromUint8(_sqlite3HexToInt(tls, libc.Int32FromUint8(**(**uint8)(__ccgo_up(zUri + uintptr(v4)))))) if octet == 0 { /* This branch is taken when "%00" appears within the URI. In this ** case we ignore all text in the remainder of the path, name or ** value currently being parsed. So ignore the current character ** and skip to the next "?", "=" or "&", as appropriate. */ for { v2 = **(**uint8)(__ccgo_up(zUri + uintptr(iIn))) c = v2 if !(libc.Int32FromUint8(v2) != 0 && libc.Int32FromUint8(c) != int32('#') && (eState != 0 || libc.Int32FromUint8(c) != int32('?')) && (eState != int32(1) || libc.Int32FromUint8(c) != int32('=') && libc.Int32FromUint8(c) != int32('&')) && (eState != int32(2) || libc.Int32FromUint8(c) != int32('&'))) { break } iIn = iIn + 1 } continue } c = libc.Uint8FromInt32(octet) } else { if eState == int32(1) && (libc.Int32FromUint8(c) == int32('&') || libc.Int32FromUint8(c) == int32('=')) { if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zFile + uintptr(iOut-int64(1))))) == 0 { /* An empty option name. Ignore this option altogether. */ for **(**uint8)(__ccgo_up(zUri + uintptr(iIn))) != 0 && libc.Int32FromUint8(**(**uint8)(__ccgo_up(zUri + uintptr(iIn)))) != int32('#') && libc.Int32FromUint8(**(**uint8)(__ccgo_up(zUri + uintptr(iIn-int64(1))))) != int32('&') { iIn = iIn + 1 } continue } if libc.Int32FromUint8(c) == int32('&') { v3 = iOut iOut = iOut + 1 **(**uint8)(__ccgo_up(zFile + uintptr(v3))) = uint8('\000') } else { eState = int32(2) } c = uint8(0) } else { if eState == 0 && libc.Int32FromUint8(c) == int32('?') || eState == int32(2) && libc.Int32FromUint8(c) == int32('&') { c = uint8(0) eState = int32(1) } } } v3 = iOut iOut = iOut + 1 **(**uint8)(__ccgo_up(zFile + uintptr(v3))) = c } if eState == int32(1) { v3 = iOut iOut = iOut + 1 **(**uint8)(__ccgo_up(zFile + uintptr(v3))) = uint8('\000') } libc.Xmemset(tls, zFile+uintptr(iOut), 0, uint64(4)) /* end-of-options + empty journal filenames */ /* Check if there were any options specified that should be interpreted ** here. Options that are interpreted here include "vfs" and those that ** correspond to flags that may be passed to the sqlite3_open_v2() ** method. */ zOpt = zFile + uintptr(libc.Xstrlen(tls, zFile)+uint64(1)) for **(**uint8)(__ccgo_up(zOpt)) != 0 { nOpt = libc.Int64FromUint64(libc.Xstrlen(tls, zOpt)) zVal = zOpt + uintptr(nOpt+int64(1)) nVal = libc.Int64FromUint64(libc.Xstrlen(tls, zVal)) if nOpt == int64(3) && libc.Xmemcmp(tls, __ccgo_ts+26186, zOpt, uint64(3)) == 0 { zVfs = zVal } else { aMode = uintptr(0) zModeType = uintptr(0) mask = 0 limit = 0 if nOpt == int64(5) && libc.Xmemcmp(tls, __ccgo_ts+26190, zOpt, uint64(5)) == 0 { mask = libc.Int32FromInt32(SQLITE_OPEN_SHAREDCACHE) | libc.Int32FromInt32(SQLITE_OPEN_PRIVATECACHE) aMode = uintptr(unsafe.Pointer(&_aCacheMode)) limit = mask zModeType = __ccgo_ts + 26190 } if nOpt == int64(4) && libc.Xmemcmp(tls, __ccgo_ts+26211, zOpt, uint64(4)) == 0 { mask = libc.Int32FromInt32(SQLITE_OPEN_READONLY) | libc.Int32FromInt32(SQLITE_OPEN_READWRITE) | libc.Int32FromInt32(SQLITE_OPEN_CREATE) | libc.Int32FromInt32(SQLITE_OPEN_MEMORY) aMode = uintptr(unsafe.Pointer(&_aOpenMode)) limit = libc.Int32FromUint32(libc.Uint32FromInt32(mask) & flags) zModeType = __ccgo_ts + 3553 } if aMode != 0 { mode = 0 i = 0 for { if !((**(**struct { Fz uintptr Fmode int32 })(__ccgo_up(aMode + uintptr(i)*16))).Fz != 0) { break } z = (**(**struct { Fz uintptr Fmode int32 })(__ccgo_up(aMode + uintptr(i)*16))).Fz if nVal == libc.Int64FromUint64(libc.Xstrlen(tls, z)) && 0 == libc.Xmemcmp(tls, zVal, z, libc.Uint64FromInt64(nVal)) { mode = (**(**struct { Fz uintptr Fmode int32 })(__ccgo_up(aMode + uintptr(i)*16))).Fmode break } goto _9 _9: ; i = i + 1 } if mode == 0 { **(**uintptr)(__ccgo_up(pzErrMsg)) = Xsqlite3_mprintf(tls, __ccgo_ts+26226, libc.VaList(bp+8, zModeType, zVal)) rc = int32(SQLITE_ERROR) goto parse_uri_out } if mode & ^libc.Int32FromInt32(SQLITE_OPEN_MEMORY) > limit { **(**uintptr)(__ccgo_up(pzErrMsg)) = Xsqlite3_mprintf(tls, __ccgo_ts+26246, libc.VaList(bp+8, zModeType, zVal)) rc = int32(SQLITE_PERM) goto parse_uri_out } flags = flags&libc.Uint32FromInt32(^mask) | libc.Uint32FromInt32(mode) } } zOpt = zVal + uintptr(nVal+int64(1)) } } else { zFile = Xsqlite3_malloc64(tls, libc.Uint64FromInt64(nUri+int64(8))) if !(zFile != 0) { return int32(SQLITE_NOMEM) } libc.Xmemset(tls, zFile, 0, uint64(4)) zFile = zFile + uintptr(4) if nUri != 0 { libc.Xmemcpy(tls, zFile, zUri, libc.Uint64FromInt64(nUri)) } libc.Xmemset(tls, zFile+uintptr(nUri), 0, uint64(4)) flags = flags & libc.Uint32FromInt32(^libc.Int32FromInt32(SQLITE_OPEN_URI)) } **(**uintptr)(__ccgo_up(ppVfs)) = Xsqlite3_vfs_find(tls, zVfs) if **(**uintptr)(__ccgo_up(ppVfs)) == uintptr(0) { **(**uintptr)(__ccgo_up(pzErrMsg)) = Xsqlite3_mprintf(tls, __ccgo_ts+26270, libc.VaList(bp+8, zVfs)) rc = int32(SQLITE_ERROR) } goto parse_uri_out parse_uri_out: ; if rc != SQLITE_OK { Xsqlite3_free_filename(tls, zFile) zFile = uintptr(0) } **(**uint32)(__ccgo_up(pFlags)) = flags **(**uintptr)(__ccgo_up(pzFile)) = zFile return rc } // C documentation // // /* // ** Given a SELECT statement, generate a Table structure that describes // ** the result set of that SELECT. // */ func _sqlite3ResultSetOfSelect(tls *libc.TLS, pParse uintptr, pSelect uintptr, aff uint8) (r uintptr) { var db, pTab uintptr var savedFlags Tu64 _, _, _ = db, pTab, savedFlags db = (*TParse)(unsafe.Pointer(pParse)).Fdb (*TParse)(unsafe.Pointer(pParse)).FnNestSel = (*TParse)(unsafe.Pointer(pParse)).FnNestSel + 1 if (*TParse)(unsafe.Pointer(pParse)).FnNestSel >= **(**int32)(__ccgo_up(db + 136 + 3*4)) { _sqlite3ErrorMsg(tls, pParse, __ccgo_ts+20681, 0) return uintptr(0) } savedFlags = (*Tsqlite3)(unsafe.Pointer(db)).Fflags **(**Tu64)(__ccgo_up(db + 48)) &= ^libc.Uint64FromInt32(SQLITE_FullColNames) **(**Tu64)(__ccgo_up(db + 48)) |= uint64(SQLITE_ShortColNames) _sqlite3SelectPrep(tls, pParse, pSelect, uintptr(0)) (*Tsqlite3)(unsafe.Pointer(db)).Fflags = savedFlags if (*TParse)(unsafe.Pointer(pParse)).FnErr != 0 { return uintptr(0) } for (*TSelect)(unsafe.Pointer(pSelect)).FpPrior != 0 { pSelect = (*TSelect)(unsafe.Pointer(pSelect)).FpPrior } pTab = _sqlite3DbMallocZero(tls, db, uint64(120)) if pTab == uintptr(0) { return uintptr(0) } (*TTable)(unsafe.Pointer(pTab)).FnTabRef = uint32(1) (*TTable)(unsafe.Pointer(pTab)).FzName = uintptr(0) (*TTable)(unsafe.Pointer(pTab)).FnRowLogEst = int16(200) _sqlite3ColumnsFromExprList(tls, pParse, (*TSelect)(unsafe.Pointer(pSelect)).FpEList, pTab+54, pTab+8) _sqlite3SubqueryColumnTypes(tls, pParse, pTab, pSelect, aff) (*TTable)(unsafe.Pointer(pTab)).FiPKey = int16(-int32(1)) if (*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0 { _sqlite3DeleteTable(tls, db, pTab) return uintptr(0) } (*TParse)(unsafe.Pointer(pParse)).FnNestSel = (*TParse)(unsafe.Pointer(pParse)).FnNestSel - 1 return pTab } // C documentation // // /* // ** Run the parser on the given SQL string. // */ func _sqlite3RunParser(tls *libc.TLS, pParse uintptr, zSql uintptr) (r int32) { bp := tls.Alloc(1280) defer tls.Free(1280) var db, pEngine, pParentParse uintptr var lastTokenParsed, nErr int32 var mxSqlLen, n Ti64 var _ /* sEngine at bp+8 */ TyyParser var _ /* tokenType at bp+0 */ int32 var _ /* x at bp+1240 */ TToken _, _, _, _, _, _, _ = db, lastTokenParsed, mxSqlLen, n, nErr, pEngine, pParentParse nErr = 0 /* The LEMON-generated LALR(1) parser */ n = 0 /* type of the next token */ lastTokenParsed = -int32(1) /* type of the previous token */ db = (*TParse)(unsafe.Pointer(pParse)).Fdb /* Max length of an SQL string */ pParentParse = uintptr(0) /* Space to hold the Lemon-generated Parser object */ mxSqlLen = int64(**(**int32)(__ccgo_up(db + 136 + 1*4))) if (*Tsqlite3)(unsafe.Pointer(db)).FnVdbeActive == 0 { libc.AtomicStoreNInt32(db+432, libc.Int32FromInt32(0), libc.Int32FromInt32(__ATOMIC_RELAXED)) } (*TParse)(unsafe.Pointer(pParse)).Frc = SQLITE_OK (*TParse)(unsafe.Pointer(pParse)).FzTail = zSql pEngine = bp + 8 _sqlite3ParserInit(tls, pEngine, pParse) pParentParse = (*Tsqlite3)(unsafe.Pointer(db)).FpParse (*Tsqlite3)(unsafe.Pointer(db)).FpParse = pParse for int32(1) != 0 { n = _sqlite3GetToken(tls, zSql, bp) mxSqlLen = mxSqlLen - n if mxSqlLen < 0 { (*TParse)(unsafe.Pointer(pParse)).Frc = int32(SQLITE_TOOBIG) (*TParse)(unsafe.Pointer(pParse)).FnErr = (*TParse)(unsafe.Pointer(pParse)).FnErr + 1 break } if **(**int32)(__ccgo_up(bp)) >= int32(TK_WINDOW) { if libc.AtomicLoadNInt32(db+432, libc.Int32FromInt32(__ATOMIC_RELAXED)) != 0 { (*TParse)(unsafe.Pointer(pParse)).Frc = int32(SQLITE_INTERRUPT) (*TParse)(unsafe.Pointer(pParse)).FnErr = (*TParse)(unsafe.Pointer(pParse)).FnErr + 1 break } if **(**int32)(__ccgo_up(bp)) == int32(TK_SPACE) { zSql = zSql + uintptr(n) continue } if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zSql))) == 0 { /* Upon reaching the end of input, call the parser two more times ** with tokens TK_SEMI and 0, in that order. */ if lastTokenParsed == int32(TK_SEMI) { **(**int32)(__ccgo_up(bp)) = 0 } else { if lastTokenParsed == 0 { break } else { **(**int32)(__ccgo_up(bp)) = int32(TK_SEMI) } } n = 0 } else { if **(**int32)(__ccgo_up(bp)) == int32(TK_WINDOW) { **(**int32)(__ccgo_up(bp)) = _analyzeWindowKeyword(tls, zSql+6) } else { if **(**int32)(__ccgo_up(bp)) == int32(TK_OVER) { **(**int32)(__ccgo_up(bp)) = _analyzeOverKeyword(tls, zSql+4, lastTokenParsed) } else { if **(**int32)(__ccgo_up(bp)) == int32(TK_FILTER) { **(**int32)(__ccgo_up(bp)) = _analyzeFilterKeyword(tls, zSql+6, lastTokenParsed) } else { if **(**int32)(__ccgo_up(bp)) == int32(TK_COMMENT) && ((*Tsqlite3)(unsafe.Pointer(db)).Finit1.Fbusy != 0 || (*Tsqlite3)(unsafe.Pointer(db)).Fflags&(libc.Uint64FromInt32(libc.Int32FromInt32(0x00040))<declareVtab flag is set, do not delete any table ** structure built up in pParse->pNewTable. The calling code (see vtab.c) ** will take responsibility for freeing the Table structure. */ _sqlite3DeleteTable(tls, db, (*TParse)(unsafe.Pointer(pParse)).FpNewTable) } if (*TParse)(unsafe.Pointer(pParse)).FpNewTrigger != 0 && !(libc.Int32FromUint8((*TParse)(unsafe.Pointer(pParse)).FeParseMode) >= libc.Int32FromInt32(PARSE_MODE_RENAME)) { _sqlite3DeleteTrigger(tls, db, (*TParse)(unsafe.Pointer(pParse)).FpNewTrigger) } if (*TParse)(unsafe.Pointer(pParse)).FpVList != 0 { _sqlite3DbNNFreeNN(tls, db, (*TParse)(unsafe.Pointer(pParse)).FpVList) } (*Tsqlite3)(unsafe.Pointer(db)).FpParse = pParentParse return nErr } /************** End of tokenize.c ********************************************/ /************** Begin file complete.c ****************************************/ /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** An tokenizer for SQL ** ** This file contains C code that implements the sqlite3_complete() API. ** This code used to be part of the tokenizer.c source file. But by ** separating it out, the code will be automatically omitted from ** static links that do not use it. */ /* #include "sqliteInt.h" */ /* ** This is defined in tokenize.c. We just have to import the definition. */ /* ** Token types used by the sqlite3_complete() routine. See the header ** comments on that procedure for additional information. */ // C documentation // // /* // ** This routine implements the OP_Vacuum opcode of the VDBE. // */ func _sqlite3RunVacuum(tls *libc.TLS, pzErrMsg uintptr, db uintptr, iDb int32, pOut uintptr) (r int32) { bp := tls.Alloc(112) defer tls.Free(112) var i, isMemDb, nDb, nNew, nRes, rc, v1 int32 var id, pDb, pMain, pTemp, zDbMain, zFilename, zOut uintptr var pgflags, saved_mDbFlags, saved_openFlags Tu32 var saved_flags Tu64 var saved_mTrace Tu8 var saved_nChange, saved_nTotalChange Ti64 var _ /* iRandom at bp+0 */ Tu64 var _ /* meta at bp+64 */ Tu32 var _ /* sz at bp+56 */ Ti64 var _ /* zDbVacuum at bp+8 */ [42]uint8 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = i, id, isMemDb, nDb, nNew, nRes, pDb, pMain, pTemp, pgflags, rc, saved_flags, saved_mDbFlags, saved_mTrace, saved_nChange, saved_nTotalChange, saved_openFlags, zDbMain, zFilename, zOut, v1 rc = SQLITE_OK /* Saved trace settings */ pDb = uintptr(0) /* Name of output file */ pgflags = uint32(PAGER_SYNCHRONOUS_OFF) /* Name of the ATTACH-ed database used for vacuum */ if !((*Tsqlite3)(unsafe.Pointer(db)).FautoCommit != 0) { _sqlite3SetString(tls, pzErrMsg, db, __ccgo_ts+22765) return int32(SQLITE_ERROR) /* IMP: R-12218-18073 */ } if (*Tsqlite3)(unsafe.Pointer(db)).FnVdbeActive > int32(1) { _sqlite3SetString(tls, pzErrMsg, db, __ccgo_ts+22805) return int32(SQLITE_ERROR) /* IMP: R-15610-35227 */ } saved_openFlags = (*Tsqlite3)(unsafe.Pointer(db)).FopenFlags if pOut != 0 { if Xsqlite3_value_type(tls, pOut) != int32(SQLITE_TEXT) { _sqlite3SetString(tls, pzErrMsg, db, __ccgo_ts+22848) return int32(SQLITE_ERROR) } zOut = Xsqlite3_value_text(tls, pOut) **(**uint32)(__ccgo_up(db + 76)) &= libc.Uint32FromInt32(^libc.Int32FromInt32(SQLITE_OPEN_READONLY)) **(**uint32)(__ccgo_up(db + 76)) |= libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_OPEN_CREATE) | libc.Int32FromInt32(SQLITE_OPEN_READWRITE)) } else { zOut = __ccgo_ts + 1704 } /* Save the current value of the database flags so that it can be ** restored before returning. Then set the writable-schema flag, and ** disable CHECK and foreign key constraints. */ saved_flags = (*Tsqlite3)(unsafe.Pointer(db)).Fflags saved_mDbFlags = (*Tsqlite3)(unsafe.Pointer(db)).FmDbFlags saved_nChange = (*Tsqlite3)(unsafe.Pointer(db)).FnChange saved_nTotalChange = (*Tsqlite3)(unsafe.Pointer(db)).FnTotalChange saved_mTrace = (*Tsqlite3)(unsafe.Pointer(db)).FmTrace **(**Tu64)(__ccgo_up(db + 48)) |= libc.Uint64FromInt32(libc.Int32FromInt32(SQLITE_WriteSchema)|libc.Int32FromInt32(SQLITE_IgnoreChecks)) | libc.Uint64FromInt32(libc.Int32FromInt32(0x00040))< 0) { rc = int32(SQLITE_ERROR) _sqlite3SetString(tls, pzErrMsg, db, __ccgo_ts+22897) goto end_of_vacuum } **(**Tu32)(__ccgo_up(db + 44)) |= uint32(DBFLAG_VacuumInto) /* For a VACUUM INTO, the pager-flags are set to the same values as ** they are for the database being vacuumed, except that PAGER_CACHESPILL ** is always set. */ pgflags = uint32(uint64((**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(iDb)*32))).Fsafety_level) | (*Tsqlite3)(unsafe.Pointer(db)).Fflags&uint64(PAGER_FLAGS_MASK)) /* If the VACUUM INTO target file is a URI filename and if the ** "reserve=N" query parameter is present, reset the reserve to the ** amount specified, if the amount is within range */ zFilename = _sqlite3BtreeGetFilename(tls, pTemp) if zFilename != 0 { nNew = int32(Xsqlite3_uri_int64(tls, zFilename, __ccgo_ts+22924, int64(nRes))) if nNew >= 0 && nNew <= int32(255) { nRes = nNew } } } _sqlite3BtreeSetCacheSize(tls, pTemp, (*TSchema)(unsafe.Pointer((**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(iDb)*32))).FpSchema)).Fcache_size) _sqlite3BtreeSetSpillSize(tls, pTemp, _sqlite3BtreeSetSpillSize(tls, pMain, 0)) _sqlite3BtreeSetPagerFlags(tls, pTemp, pgflags|uint32(PAGER_CACHESPILL)) /* Begin a transaction and take an exclusive lock on the main database ** file. This is done before the sqlite3BtreeGetPageSize(pMain) call below, ** to ensure that we do not try to change the page-size on a WAL database. */ rc = _execSql(tls, db, pzErrMsg, __ccgo_ts+16131) if rc != SQLITE_OK { goto end_of_vacuum } if pOut == uintptr(0) { v1 = int32(2) } else { v1 = 0 } rc = _sqlite3BtreeBeginTrans(tls, pMain, v1, uintptr(0)) if rc != SQLITE_OK { goto end_of_vacuum } /* Do not attempt to change the page size for a WAL database */ if _sqlite3PagerGetJournalMode(tls, _sqlite3BtreePager(tls, pMain)) == int32(PAGER_JOURNALMODE_WAL) && pOut == uintptr(0) { (*Tsqlite3)(unsafe.Pointer(db)).FnextPagesize = 0 } if _sqlite3BtreeSetPageSize(tls, pTemp, _sqlite3BtreeGetPageSize(tls, pMain), nRes, 0) != 0 || !(isMemDb != 0) && _sqlite3BtreeSetPageSize(tls, pTemp, (*Tsqlite3)(unsafe.Pointer(db)).FnextPagesize, nRes, 0) != 0 || (*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0 { rc = int32(SQLITE_NOMEM) goto end_of_vacuum } if int32((*Tsqlite3)(unsafe.Pointer(db)).FnextAutovac) >= 0 { v1 = int32((*Tsqlite3)(unsafe.Pointer(db)).FnextAutovac) } else { v1 = _sqlite3BtreeGetAutoVacuum(tls, pMain) } _sqlite3BtreeSetAutoVacuum(tls, pTemp, v1) /* Query the schema of the main database. Create a mirror schema ** in the temporary database. */ (*Tsqlite3)(unsafe.Pointer(db)).Finit1.FiDb = libc.Uint8FromInt32(nDb) /* force new CREATE statements into vacuum_db */ rc = _execSqlF(tls, db, pzErrMsg, __ccgo_ts+22932, libc.VaList(bp+80, zDbMain)) if rc != SQLITE_OK { goto end_of_vacuum } rc = _execSqlF(tls, db, pzErrMsg, __ccgo_ts+23040, libc.VaList(bp+80, zDbMain)) if rc != SQLITE_OK { goto end_of_vacuum } (*Tsqlite3)(unsafe.Pointer(db)).Finit1.FiDb = uint8(0) /* Loop through the tables in the main database. For each, do ** an "INSERT INTO vacuum_db.xxx SELECT * FROM main.xxx;" to copy ** the contents to the temporary database. */ rc = _execSqlF(tls, db, pzErrMsg, __ccgo_ts+23094, libc.VaList(bp+80, bp+8, zDbMain, bp+8)) **(**Tu32)(__ccgo_up(db + 44)) &= libc.Uint32FromInt32(^libc.Int32FromInt32(DBFLAG_Vacuum)) if rc != SQLITE_OK { goto end_of_vacuum } /* Copy the triggers, views, and virtual tables from the main database ** over to the temporary database. None of these objects has any ** associated storage, so all we have to do is copy their entries ** from the schema table. */ rc = _execSqlF(tls, db, pzErrMsg, __ccgo_ts+23231, libc.VaList(bp+80, bp+8, zDbMain)) if rc != 0 { goto end_of_vacuum } /* Copy Btree meta values */ i = 0 for { if !(i < libc.Int32FromUint64(libc.Uint64FromInt64(10)/libc.Uint64FromInt64(1))) { break } /* GetMeta() and UpdateMeta() cannot fail in this context because ** we already have page 1 loaded into cache and marked dirty. */ _sqlite3BtreeGetMeta(tls, pMain, libc.Int32FromUint8(_aCopy[i]), bp+64) rc = _sqlite3BtreeUpdateMeta(tls, pTemp, libc.Int32FromUint8(_aCopy[i]), **(**Tu32)(__ccgo_up(bp + 64))+uint32(_aCopy[i+int32(1)])) if rc != SQLITE_OK { goto end_of_vacuum } goto _3 _3: ; i = i + int32(2) } if pOut == uintptr(0) { rc = _sqlite3BtreeCopyFile(tls, pMain, pTemp) } if rc != SQLITE_OK { goto end_of_vacuum } rc = _sqlite3BtreeCommit(tls, pTemp) if rc != SQLITE_OK { goto end_of_vacuum } if pOut == uintptr(0) { _sqlite3BtreeSetAutoVacuum(tls, pMain, _sqlite3BtreeGetAutoVacuum(tls, pTemp)) } if pOut == uintptr(0) { nRes = _sqlite3BtreeGetRequestedReserve(tls, pTemp) rc = _sqlite3BtreeSetPageSize(tls, pMain, _sqlite3BtreeGetPageSize(tls, pTemp), nRes, int32(1)) } goto end_of_vacuum end_of_vacuum: ; /* Restore the original value of db->flags */ (*Tsqlite3)(unsafe.Pointer(db)).Finit1.FiDb = uint8(0) (*Tsqlite3)(unsafe.Pointer(db)).FmDbFlags = saved_mDbFlags (*Tsqlite3)(unsafe.Pointer(db)).Fflags = saved_flags (*Tsqlite3)(unsafe.Pointer(db)).FnChange = saved_nChange (*Tsqlite3)(unsafe.Pointer(db)).FnTotalChange = saved_nTotalChange (*Tsqlite3)(unsafe.Pointer(db)).FmTrace = saved_mTrace _sqlite3BtreeSetPageSize(tls, pMain, -int32(1), 0, int32(1)) /* Currently there is an SQL level transaction open on the vacuum ** database. No locks are held on any other files (since the main file ** was committed at the btree level). So it safe to end the transaction ** by manually setting the autoCommit flag to true and detaching the ** vacuum database. The vacuum_db journal file is deleted when the pager ** is closed by the DETACH. */ (*Tsqlite3)(unsafe.Pointer(db)).FautoCommit = uint8(1) if pDb != 0 { _sqlite3BtreeClose(tls, (*TDb)(unsafe.Pointer(pDb)).FpBt) (*TDb)(unsafe.Pointer(pDb)).FpBt = uintptr(0) (*TDb)(unsafe.Pointer(pDb)).FpSchema = uintptr(0) } /* This both clears the schemas and reduces the size of the db->aDb[] ** array. */ _sqlite3ResetAllSchemasOfConnection(tls, db) return rc } /* At this point, there is a write transaction open on both the ** vacuum database and the main database. Assuming no error occurs, ** both transactions are closed by this block - the main database ** transaction by sqlite3BtreeCopyFile() and the other by an explicit ** call to sqlite3BtreeCommit(). */ // C documentation // // /* // ** pTab is a transient Table object that represents a subquery of some // ** kind (maybe a parenthesized subquery in the FROM clause of a larger // ** query, or a VIEW, or a CTE). This routine computes type information // ** for that Table object based on the Select object that implements the // ** subquery. For the purposes of this routine, "type information" means: // ** // ** * The datatype name, as it might appear in a CREATE TABLE statement // ** * Which collating sequence to use for the column // ** * The affinity of the column // */ func _sqlite3SubqueryColumnTypes(tls *libc.TLS, pParse uintptr, pTab uintptr, pSelect uintptr, aff uint8) { bp := tls.Alloc(64) defer tls.Free(64) var a, db, p, pCol, pColl, pS2, zType, v4 uintptr var i, j, m int32 var k, n Ti64 var _ /* sNC at bp+0 */ TNameContext _, _, _, _, _, _, _, _, _, _, _, _, _ = a, db, i, j, k, m, n, p, pCol, pColl, pS2, zType, v4 db = (*TParse)(unsafe.Pointer(pParse)).Fdb if (*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0 || libc.Int32FromUint8((*TParse)(unsafe.Pointer(pParse)).FeParseMode) >= int32(PARSE_MODE_RENAME) { return } for (*TSelect)(unsafe.Pointer(pSelect)).FpPrior != 0 { pSelect = (*TSelect)(unsafe.Pointer(pSelect)).FpPrior } a = (*TSelect)(unsafe.Pointer(pSelect)).FpEList + 8 libc.Xmemset(tls, bp, 0, uint64(56)) (**(**TNameContext)(__ccgo_up(bp))).FpSrcList = (*TSelect)(unsafe.Pointer(pSelect)).FpSrc i = 0 pCol = (*TTable)(unsafe.Pointer(pTab)).FaCol for { if !(i < int32((*TTable)(unsafe.Pointer(pTab)).FnCol)) { break } m = 0 pS2 = pSelect **(**Tu32)(__ccgo_up(pTab + 48)) |= libc.Uint32FromInt32(libc.Int32FromUint16((*TColumn)(unsafe.Pointer(pCol)).FcolFlags) & libc.Int32FromInt32(COLFLAG_NOINSERT)) p = (**(**TExprList_item)(__ccgo_up(a + uintptr(i)*32))).FpExpr /* pCol->szEst = ... // Column size est for SELECT tables never used */ (*TColumn)(unsafe.Pointer(pCol)).Faffinity = _sqlite3ExprAffinity(tls, p) for libc.Int32FromUint8((*TColumn)(unsafe.Pointer(pCol)).Faffinity) <= int32(SQLITE_AFF_NONE) && (*TSelect)(unsafe.Pointer(pS2)).FpNext != uintptr(0) { m = m | _sqlite3ExprDataType(tls, (*(*TExprList_item)(unsafe.Pointer((*TSelect)(unsafe.Pointer(pS2)).FpEList + 8 + uintptr(i)*32))).FpExpr) pS2 = (*TSelect)(unsafe.Pointer(pS2)).FpNext (*TColumn)(unsafe.Pointer(pCol)).Faffinity = _sqlite3ExprAffinity(tls, (*(*TExprList_item)(unsafe.Pointer((*TSelect)(unsafe.Pointer(pS2)).FpEList + 8 + uintptr(i)*32))).FpExpr) } if libc.Int32FromUint8((*TColumn)(unsafe.Pointer(pCol)).Faffinity) <= int32(SQLITE_AFF_NONE) { (*TColumn)(unsafe.Pointer(pCol)).Faffinity = aff } if libc.Int32FromUint8((*TColumn)(unsafe.Pointer(pCol)).Faffinity) >= int32(SQLITE_AFF_TEXT) && ((*TSelect)(unsafe.Pointer(pS2)).FpNext != 0 || pS2 != pSelect) { pS2 = (*TSelect)(unsafe.Pointer(pS2)).FpNext for { if !(pS2 != 0) { break } m = m | _sqlite3ExprDataType(tls, (*(*TExprList_item)(unsafe.Pointer((*TSelect)(unsafe.Pointer(pS2)).FpEList + 8 + uintptr(i)*32))).FpExpr) goto _2 _2: ; pS2 = (*TSelect)(unsafe.Pointer(pS2)).FpNext } if libc.Int32FromUint8((*TColumn)(unsafe.Pointer(pCol)).Faffinity) == int32(SQLITE_AFF_TEXT) && m&int32(0x01) != 0 { (*TColumn)(unsafe.Pointer(pCol)).Faffinity = uint8(SQLITE_AFF_BLOB) } else { if libc.Int32FromUint8((*TColumn)(unsafe.Pointer(pCol)).Faffinity) >= int32(SQLITE_AFF_NUMERIC) && m&int32(0x02) != 0 { (*TColumn)(unsafe.Pointer(pCol)).Faffinity = uint8(SQLITE_AFF_BLOB) } } if libc.Int32FromUint8((*TColumn)(unsafe.Pointer(pCol)).Faffinity) >= int32(SQLITE_AFF_NUMERIC) && libc.Int32FromUint8((*TExpr)(unsafe.Pointer(p)).Fop) == int32(TK_CAST) { (*TColumn)(unsafe.Pointer(pCol)).Faffinity = uint8(SQLITE_AFF_FLEXNUM) } } zType = _columnTypeImpl(tls, bp, p, uintptr(0), uintptr(0), uintptr(0)) if zType == uintptr(0) || libc.Int32FromUint8((*TColumn)(unsafe.Pointer(pCol)).Faffinity) != libc.Int32FromUint8(_sqlite3AffinityType(tls, zType, uintptr(0))) { if libc.Int32FromUint8((*TColumn)(unsafe.Pointer(pCol)).Faffinity) == int32(SQLITE_AFF_NUMERIC) || libc.Int32FromUint8((*TColumn)(unsafe.Pointer(pCol)).Faffinity) == int32(SQLITE_AFF_FLEXNUM) { zType = __ccgo_ts + 20677 } else { zType = uintptr(0) j = int32(1) for { if !(j < int32(SQLITE_N_STDTYPE)) { break } if libc.Int32FromUint8(_sqlite3StdTypeAffinity[j]) == libc.Int32FromUint8((*TColumn)(unsafe.Pointer(pCol)).Faffinity) { zType = _sqlite3StdType[j] break } goto _3 _3: ; j = j + 1 } } } if zType != 0 { k = libc.Int64FromUint64(libc.Xstrlen(tls, zType)) n = libc.Int64FromUint64(libc.Xstrlen(tls, (*TColumn)(unsafe.Pointer(pCol)).FzCnName)) (*TColumn)(unsafe.Pointer(pCol)).FzCnName = _sqlite3DbReallocOrFree(tls, db, (*TColumn)(unsafe.Pointer(pCol)).FzCnName, libc.Uint64FromInt64(n+k+int64(2))) v4 = pCol + 14 *(*Tu16)(unsafe.Pointer(v4)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v4))) & ^(libc.Int32FromInt32(COLFLAG_HASTYPE) | libc.Int32FromInt32(COLFLAG_HASCOLL))) if (*TColumn)(unsafe.Pointer(pCol)).FzCnName != 0 { libc.Xmemcpy(tls, (*TColumn)(unsafe.Pointer(pCol)).FzCnName+uintptr(n+int64(1)), zType, libc.Uint64FromInt64(k+int64(1))) v4 = pCol + 14 *(*Tu16)(unsafe.Pointer(v4)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v4))) | libc.Int32FromInt32(COLFLAG_HASTYPE)) } } pColl = _sqlite3ExprCollSeq(tls, pParse, p) if pColl != 0 { _sqlite3ColumnSetColl(tls, db, pCol, (*TCollSeq)(unsafe.Pointer(pColl)).FzName) } goto _1 _1: ; i = i + 1 pCol += 16 } (*TTable)(unsafe.Pointer(pTab)).FszTabRow = int16(1) /* Any non-zero value works */ } // C documentation // // /* // ** Analyze the ON CONFLICT clause described by pUpsert. Resolve all // ** symbols in the conflict-target. // ** // ** Return SQLITE_OK if everything works, or an error code is something // ** is wrong. // */ func _sqlite3UpsertAnalyzeTarget(tls *libc.TLS, pParse uintptr, pTabList uintptr, pUpsert uintptr, pAll uintptr) (r int32) { bp := tls.Alloc(240) defer tls.Free(240) var iCursor, ii, jj, nClause, nn, rc int32 var pExpr, pIdx, pTab, pTarget, pTerm, v2 uintptr var v3 bool var _ /* sCol at bp+56 */ [2]TExpr var _ /* sNC at bp+0 */ TNameContext var _ /* zWhich at bp+200 */ [16]uint8 _, _, _, _, _, _, _, _, _, _, _, _, _ = iCursor, ii, jj, nClause, nn, pExpr, pIdx, pTab, pTarget, pTerm, rc, v2, v3 /* Index column converted into an Expr */ nClause = 0 /* Counter of ON CONFLICT clauses */ /* Resolve all symbolic names in the conflict-target clause, which ** includes both the list of columns and the optional partial-index ** WHERE clause. */ libc.Xmemset(tls, bp, 0, uint64(56)) (**(**TNameContext)(__ccgo_up(bp))).FpParse = pParse (**(**TNameContext)(__ccgo_up(bp))).FpSrcList = pTabList for { if !(pUpsert != 0 && (*TUpsert)(unsafe.Pointer(pUpsert)).FpUpsertTarget != 0) { break } rc = _sqlite3ResolveExprListNames(tls, bp, (*TUpsert)(unsafe.Pointer(pUpsert)).FpUpsertTarget) if rc != 0 { return rc } rc = _sqlite3ResolveExprNames(tls, bp, (*TUpsert)(unsafe.Pointer(pUpsert)).FpUpsertTargetWhere) if rc != 0 { return rc } /* Check to see if the conflict target matches the rowid. */ pTab = (*(*TSrcItem)(unsafe.Pointer(pTabList + 8))).FpSTab pTarget = (*TUpsert)(unsafe.Pointer(pUpsert)).FpUpsertTarget iCursor = (*(*TSrcItem)(unsafe.Pointer(pTabList + 8))).FiCursor if v3 = (*TTable)(unsafe.Pointer(pTab)).FtabFlags&uint32(TF_WithoutRowid) == uint32(0) && (*TExprList)(unsafe.Pointer(pTarget)).FnExpr == int32(1); v3 { v2 = (*(*TExprList_item)(unsafe.Pointer(pTarget + 8))).FpExpr pTerm = v2 } if v3 && libc.Int32FromUint8((*TExpr)(unsafe.Pointer(v2)).Fop) == int32(TK_COLUMN) && int32((*TExpr)(unsafe.Pointer(pTerm)).FiColumn) == -int32(1) { /* The conflict-target is the rowid of the primary table */ goto _1 } /* Initialize sCol[0..1] to be an expression parse tree for a ** single column of an index. The sCol[0] node will be the TK_COLLATE ** operator and sCol[1] will be the TK_COLUMN operator. Code below ** will populate the specific collation and column number values ** prior to comparing against the conflict-target expression. */ libc.Xmemset(tls, bp+56, 0, uint64(144)) (**(**[2]TExpr)(__ccgo_up(bp + 56)))[0].Fop = uint8(TK_COLLATE) (**(**[2]TExpr)(__ccgo_up(bp + 56)))[0].FpLeft = bp + 56 + 1*72 (**(**[2]TExpr)(__ccgo_up(bp + 56)))[int32(1)].Fop = uint8(TK_COLUMN) (**(**[2]TExpr)(__ccgo_up(bp + 56)))[int32(1)].FiTable = (*(*TSrcItem)(unsafe.Pointer(pTabList + 8))).FiCursor /* Check for matches against other indexes */ pIdx = (*TTable)(unsafe.Pointer(pTab)).FpIndex for { if !(pIdx != 0) { break } if !(libc.Int32FromUint8((*TIndex)(unsafe.Pointer(pIdx)).FonError) != libc.Int32FromInt32(OE_None)) { goto _4 } if (*TExprList)(unsafe.Pointer(pTarget)).FnExpr != libc.Int32FromUint16((*TIndex)(unsafe.Pointer(pIdx)).FnKeyCol) { goto _4 } if (*TIndex)(unsafe.Pointer(pIdx)).FpPartIdxWhere != 0 { if (*TUpsert)(unsafe.Pointer(pUpsert)).FpUpsertTargetWhere == uintptr(0) { goto _4 } if _sqlite3ExprCompare(tls, pParse, (*TUpsert)(unsafe.Pointer(pUpsert)).FpUpsertTargetWhere, (*TIndex)(unsafe.Pointer(pIdx)).FpPartIdxWhere, iCursor) != 0 { goto _4 } } nn = libc.Int32FromUint16((*TIndex)(unsafe.Pointer(pIdx)).FnKeyCol) ii = 0 for { if !(ii < nn) { break } *(*uintptr)(unsafe.Pointer(bp + 56 + 8)) = **(**uintptr)(__ccgo_up((*TIndex)(unsafe.Pointer(pIdx)).FazColl + uintptr(ii)*8)) if int32(**(**Ti16)(__ccgo_up((*TIndex)(unsafe.Pointer(pIdx)).FaiColumn + uintptr(ii)*2))) == -int32(2) { pExpr = (*(*TExprList_item)(unsafe.Pointer((*TIndex)(unsafe.Pointer(pIdx)).FaColExpr + 8 + uintptr(ii)*32))).FpExpr if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) != int32(TK_COLLATE) { (**(**[2]TExpr)(__ccgo_up(bp + 56)))[0].FpLeft = pExpr pExpr = bp + 56 } } else { (**(**[2]TExpr)(__ccgo_up(bp + 56)))[0].FpLeft = bp + 56 + 1*72 (**(**[2]TExpr)(__ccgo_up(bp + 56)))[int32(1)].FiColumn = **(**Ti16)(__ccgo_up((*TIndex)(unsafe.Pointer(pIdx)).FaiColumn + uintptr(ii)*2)) pExpr = bp + 56 } jj = 0 for { if !(jj < nn) { break } if _sqlite3ExprCompare(tls, uintptr(0), (*(*TExprList_item)(unsafe.Pointer(pTarget + 8 + uintptr(jj)*32))).FpExpr, pExpr, iCursor) < int32(2) { break /* Column ii of the index matches column jj of target */ } goto _6 _6: ; jj = jj + 1 } if jj >= nn { /* The target contains no match for column jj of the index */ break } goto _5 _5: ; ii = ii + 1 } if ii < nn { /* Column ii of the index did not match any term of the conflict target. ** Continue the search with the next index. */ goto _4 } (*TUpsert)(unsafe.Pointer(pUpsert)).FpUpsertIdx = pIdx if _sqlite3UpsertOfIndex(tls, pAll, pIdx) != pUpsert { /* Really this should be an error. The isDup ON CONFLICT clause will ** never fire. But this problem was not discovered until three years ** after multi-CONFLICT upsert was added, and so we silently ignore ** the problem to prevent breaking applications that might actually ** have redundant ON CONFLICT clauses. */ (*TUpsert)(unsafe.Pointer(pUpsert)).FisDup = uint8(1) } break goto _4 _4: ; pIdx = (*TIndex)(unsafe.Pointer(pIdx)).FpNext } if (*TUpsert)(unsafe.Pointer(pUpsert)).FpUpsertIdx == uintptr(0) { if nClause == 0 && (*TUpsert)(unsafe.Pointer(pUpsert)).FpNextUpsert == uintptr(0) { (**(**[16]uint8)(__ccgo_up(bp + 200)))[0] = uint8(0) } else { Xsqlite3_snprintf(tls, int32(16), bp+200, __ccgo_ts+22680, libc.VaList(bp+224, nClause+int32(1))) } _sqlite3ErrorMsg(tls, pParse, __ccgo_ts+22684, libc.VaList(bp+224, bp+200)) return int32(SQLITE_ERROR) } goto _1 _1: ; pUpsert = (*TUpsert)(unsafe.Pointer(pUpsert)).FpNextUpsert nClause = nClause + 1 } return SQLITE_OK } // C documentation // // /* // ** Generate bytecode that does an UPDATE as part of an upsert. // ** // ** If pIdx is NULL, then the UNIQUE constraint that failed was the IPK. // ** In this case parameter iCur is a cursor open on the table b-tree that // ** currently points to the conflicting table row. Otherwise, if pIdx // ** is not NULL, then pIdx is the constraint that failed and iCur is a // ** cursor points to the conflicting row. // */ func _sqlite3UpsertDoUpdate(tls *libc.TLS, pParse uintptr, pUpsert uintptr, pTab uintptr, pIdx uintptr, iCur int32) { var db, pPk, pSrc, pTop, v uintptr var i, iDataCur, iPk, iStorage, k, nPk, regRowid int32 _, _, _, _, _, _, _, _, _, _, _, _ = db, i, iDataCur, iPk, iStorage, k, nPk, pPk, pSrc, pTop, regRowid, v v = (*TParse)(unsafe.Pointer(pParse)).FpVdbe db = (*TParse)(unsafe.Pointer(pParse)).Fdb pTop = pUpsert iDataCur = (*TUpsert)(unsafe.Pointer(pUpsert)).FiDataCur pUpsert = _sqlite3UpsertOfIndex(tls, pTop, pIdx) if pIdx != 0 && iCur != iDataCur { if (*TTable)(unsafe.Pointer(pTab)).FtabFlags&uint32(TF_WithoutRowid) == uint32(0) { regRowid = _sqlite3GetTempReg(tls, pParse) _sqlite3VdbeAddOp2(tls, v, int32(OP_IdxRowid), iCur, regRowid) _sqlite3VdbeAddOp3(tls, v, int32(OP_SeekRowid), iDataCur, 0, regRowid) _sqlite3ReleaseTempReg(tls, pParse, regRowid) } else { pPk = _sqlite3PrimaryKeyIndex(tls, pTab) nPk = libc.Int32FromUint16((*TIndex)(unsafe.Pointer(pPk)).FnKeyCol) iPk = (*TParse)(unsafe.Pointer(pParse)).FnMem + int32(1) **(**int32)(__ccgo_up(pParse + 60)) += nPk i = 0 for { if !(i < nPk) { break } k = _sqlite3TableColumnToIndex(tls, pIdx, int32(**(**Ti16)(__ccgo_up((*TIndex)(unsafe.Pointer(pPk)).FaiColumn + uintptr(i)*2)))) _sqlite3VdbeAddOp3(tls, v, int32(OP_Column), iCur, k, iPk+i) goto _1 _1: ; i = i + 1 } i = _sqlite3VdbeAddOp4Int(tls, v, int32(OP_Found), iDataCur, 0, iPk, nPk) _sqlite3VdbeAddOp4(tls, v, int32(OP_Halt), int32(SQLITE_CORRUPT), int32(OE_Abort), 0, __ccgo_ts+13754, -int32(1)) _sqlite3MayAbort(tls, pParse) _sqlite3VdbeJumpHere(tls, v, i) } } /* pUpsert does not own pTop->pUpsertSrc - the outer INSERT statement does. ** So we have to make a copy before passing it down into sqlite3Update() */ pSrc = _sqlite3SrcListDup(tls, db, (*TUpsert)(unsafe.Pointer(pTop)).FpUpsertSrc, 0) /* excluded.* columns of type REAL need to be converted to a hard real */ i = 0 for { if !(i < int32((*TTable)(unsafe.Pointer(pTab)).FnCol)) { break } if libc.Int32FromUint8((**(**TColumn)(__ccgo_up((*TTable)(unsafe.Pointer(pTab)).FaCol + uintptr(i)*16))).Faffinity) == int32(SQLITE_AFF_REAL) { iStorage = (*TUpsert)(unsafe.Pointer(pTop)).FregData + int32(_sqlite3TableColumnToStorage(tls, pTab, int16(i))) _sqlite3VdbeAddOp1(tls, v, int32(OP_RealAffinity), iStorage) } goto _2 _2: ; i = i + 1 } _sqlite3Update(tls, pParse, pSrc, _sqlite3ExprListDup(tls, db, (*TUpsert)(unsafe.Pointer(pUpsert)).FpUpsertSet, 0), _sqlite3ExprDup(tls, db, (*TUpsert)(unsafe.Pointer(pUpsert)).FpUpsertWhere, 0), int32(OE_Abort), uintptr(0), uintptr(0), pUpsert) } /************** End of upsert.c **********************************************/ /************** Begin file vacuum.c ******************************************/ /* ** 2003 April 6 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to implement the VACUUM command. ** ** Most of the code in this file may be omitted by defining the ** SQLITE_OMIT_VACUUM macro. */ /* #include "sqliteInt.h" */ /* #include "vdbeInt.h" */ // C documentation // // /* // ** This function returns a pointer to a nul-terminated string in memory // ** obtained from sqlite3DbMalloc(). If sqlite3.nVdbeExec is 1, then the // ** string contains a copy of zRawSql but with host parameters expanded to // ** their current bindings. Or, if sqlite3.nVdbeExec is greater than 1, // ** then the returned string holds a copy of zRawSql with "-- " prepended // ** to each line of text. // ** // ** If the SQLITE_TRACE_SIZE_LIMIT macro is defined to an integer, then // ** then long strings and blobs are truncated to that many bytes. This // ** can be used to prevent unreasonably large trace strings when dealing // ** with large (multi-megabyte) strings and blobs. // ** // ** The calling function is responsible for making sure the memory returned // ** is eventually freed. // ** // ** ALGORITHM: Scan the input string looking for host parameters in any of // ** these forms: ?, ?N, $A, @A, :A. Take care to avoid text within // ** string literals, quoted identifier names, and comments. For text forms, // ** the host parameter index is found by scanning the prepared // ** statement for the corresponding OP_Variable opcode. Once the host // ** parameter index is known, locate the value in p->aVar[]. Then render // ** the value as a literal in place of the host parameter name. // */ func _sqlite3VdbeExpandSql(tls *libc.TLS, p uintptr, zRawSql uintptr) (r uintptr) { bp := tls.Alloc(128) defer tls.Free(128) var db, pVar, zStart, v1 uintptr var enc Tu8 var i, nOut, nOut1, nextIndex, v2 int32 var n Ti64 var _ /* idx at bp+0 */ int32 var _ /* nToken at bp+8 */ Ti64 var _ /* out at bp+16 */ TStrAccum var _ /* utf8 at bp+48 */ TMem _, _, _, _, _, _, _, _, _, _, _ = db, enc, i, n, nOut, nOut1, nextIndex, pVar, zStart, v1, v2 /* The database connection */ **(**int32)(__ccgo_up(bp)) = 0 /* Index of a host parameter */ nextIndex = int32(1) /* Used to convert UTF16 into UTF8 for display */ db = (*TVdbe)(unsafe.Pointer(p)).Fdb _sqlite3StrAccumInit(tls, bp+16, uintptr(0), uintptr(0), 0, **(**int32)(__ccgo_up(db + 136))) if (*Tsqlite3)(unsafe.Pointer(db)).FnVdbeExec > int32(1) { for **(**uint8)(__ccgo_up(zRawSql)) != 0 { zStart = zRawSql for { v1 = zRawSql zRawSql = zRawSql + 1 if !(libc.Int32FromUint8(**(**uint8)(__ccgo_up(v1))) != int32('\n') && **(**uint8)(__ccgo_up(zRawSql)) != 0) { break } } Xsqlite3_str_append(tls, bp+16, __ccgo_ts+5741, int32(3)) Xsqlite3_str_append(tls, bp+16, zStart, int32(int64(zRawSql)-int64(zStart))) } } else { if int32((*TVdbe)(unsafe.Pointer(p)).FnVar) == 0 { Xsqlite3_str_append(tls, bp+16, zRawSql, _sqlite3Strlen30(tls, zRawSql)) } else { for **(**uint8)(__ccgo_up(zRawSql)) != 0 { n = _findNextHostParameter(tls, zRawSql, bp+8) Xsqlite3_str_append(tls, bp+16, zRawSql, int32(n)) zRawSql = zRawSql + uintptr(n) if **(**Ti64)(__ccgo_up(bp + 8)) == 0 { break } if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zRawSql))) == int32('?') { if **(**Ti64)(__ccgo_up(bp + 8)) > int64(1) { _sqlite3GetInt32(tls, zRawSql+1, bp) } else { **(**int32)(__ccgo_up(bp)) = nextIndex } } else { **(**int32)(__ccgo_up(bp)) = _sqlite3VdbeParameterIndex(tls, p, zRawSql, int32(**(**Ti64)(__ccgo_up(bp + 8)))) } zRawSql = zRawSql + uintptr(**(**Ti64)(__ccgo_up(bp + 8))) if **(**int32)(__ccgo_up(bp))+int32(1) > nextIndex { v2 = **(**int32)(__ccgo_up(bp)) + int32(1) } else { v2 = nextIndex } nextIndex = v2 pVar = (*TVdbe)(unsafe.Pointer(p)).FaVar + uintptr(**(**int32)(__ccgo_up(bp))-int32(1))*56 if libc.Int32FromUint16((*TMem)(unsafe.Pointer(pVar)).Fflags)&int32(MEM_Null) != 0 { Xsqlite3_str_append(tls, bp+16, __ccgo_ts+1705, int32(4)) } else { if libc.Int32FromUint16((*TMem)(unsafe.Pointer(pVar)).Fflags)&(libc.Int32FromInt32(MEM_Int)|libc.Int32FromInt32(MEM_IntReal)) != 0 { Xsqlite3_str_appendf(tls, bp+16, __ccgo_ts+1465, libc.VaList(bp+112, *(*Ti64)(unsafe.Pointer(pVar)))) } else { if libc.Int32FromUint16((*TMem)(unsafe.Pointer(pVar)).Fflags)&int32(MEM_Real) != 0 { Xsqlite3_str_appendf(tls, bp+16, __ccgo_ts+5745, libc.VaList(bp+112, *(*float64)(unsafe.Pointer(pVar)))) } else { if libc.Int32FromUint16((*TMem)(unsafe.Pointer(pVar)).Fflags)&int32(MEM_Str) != 0 { /* Number of bytes of the string text to include in output */ enc = (*Tsqlite3)(unsafe.Pointer(db)).Fenc if libc.Int32FromUint8(enc) != int32(SQLITE_UTF8) { libc.Xmemset(tls, bp+48, 0, uint64(56)) (**(**TMem)(__ccgo_up(bp + 48))).Fdb = db _sqlite3VdbeMemSetStr(tls, bp+48, (*TMem)(unsafe.Pointer(pVar)).Fz, int64((*TMem)(unsafe.Pointer(pVar)).Fn), enc, libc.UintptrFromInt32(0)) if int32(SQLITE_NOMEM) == _sqlite3VdbeChangeEncoding(tls, bp+48, int32(SQLITE_UTF8)) { (**(**TStrAccum)(__ccgo_up(bp + 16))).FaccError = uint8(SQLITE_NOMEM) (**(**TStrAccum)(__ccgo_up(bp + 16))).FnAlloc = uint32(0) } pVar = bp + 48 } nOut = (*TMem)(unsafe.Pointer(pVar)).Fn Xsqlite3_str_appendf(tls, bp+16, __ccgo_ts+5752, libc.VaList(bp+112, nOut, (*TMem)(unsafe.Pointer(pVar)).Fz)) if libc.Int32FromUint8(enc) != int32(SQLITE_UTF8) { _sqlite3VdbeMemRelease(tls, bp+48) } } else { if libc.Int32FromUint16((*TMem)(unsafe.Pointer(pVar)).Fflags)&int32(MEM_Zero) != 0 { Xsqlite3_str_appendf(tls, bp+16, __ccgo_ts+5759, libc.VaList(bp+112, *(*int32)(unsafe.Pointer(&(*TMem)(unsafe.Pointer(pVar)).Fu)))) } else { /* Number of bytes of the blob to include in output */ Xsqlite3_str_append(tls, bp+16, __ccgo_ts+5772, int32(2)) nOut1 = (*TMem)(unsafe.Pointer(pVar)).Fn i = 0 for { if !(i < nOut1) { break } Xsqlite3_str_appendf(tls, bp+16, __ccgo_ts+5775, libc.VaList(bp+112, libc.Int32FromUint8(**(**uint8)(__ccgo_up((*TMem)(unsafe.Pointer(pVar)).Fz + uintptr(i))))&int32(0xff))) goto _3 _3: ; i = i + 1 } Xsqlite3_str_append(tls, bp+16, __ccgo_ts+5780, int32(1)) } } } } } } } } if (**(**TStrAccum)(__ccgo_up(bp + 16))).FaccError != 0 { Xsqlite3_str_reset(tls, bp+16) } return _sqlite3StrAccumFinish(tls, bp+16) } /************** End of vdbetrace.c *******************************************/ /************** Begin file vdbe.c ********************************************/ /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** The code in this file implements the function that runs the ** bytecode of a prepared statement. ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. */ /* #include "sqliteInt.h" */ /* #include "vdbeInt.h" */ /* ** High-resolution hardware timer used for debugging and testing only. */ /* ** Invoke this macro on memory cells just prior to changing the ** value of the cell. This macro verifies that shallow copies are ** not misused. A shallow copy of a string or blob just copies a ** pointer to the string or blob, not the content. If the original ** is changed while the copy is still in use, the string or blob might ** be changed out from under the copy. This macro verifies that nothing ** like that ever happens. */ /* ** The following global variable is incremented every time a cursor ** moves, either by the OP_SeekXX, OP_Next, or OP_Prev opcodes. The test ** procedures use this information to make sure that indices are ** working correctly. This variable has no function other than to ** help verify the correct operation of the library. */ /* ** When this global variable is positive, it gets decremented once before ** each instruction in the VDBE. When it reaches zero, the u1.isInterrupted ** field of the sqlite3 structure is set in order to simulate an interrupt. ** ** This facility is used for testing purposes only. It does not function ** in an ordinary build. */ /* ** The next global variable is incremented each type the OP_Sort opcode ** is executed. The test procedures use this information to make sure that ** sorting is occurring or not occurring at appropriate times. This variable ** has no function other than to help verify the correct operation of the ** library. */ /* ** The next global variable records the size of the largest MEM_Blob ** or MEM_Str that has been used by a VDBE opcode. The test procedures ** use this information to make sure that the zero-blob functionality ** is working correctly. This variable has no function other than to ** help verify the correct operation of the library. */ /* ** This macro evaluates to true if either the update hook or the preupdate ** hook are enabled for database connect DB. */ /* ** The next global variable is incremented each time the OP_Found opcode ** is executed. This is used to test whether or not the foreign key ** operation implemented using OP_FkIsZero is working. This variable ** has no function other than to help verify the correct operation of the ** library. */ /* ** Test a register to see if it exceeds the current maximum blob size. ** If it does, record the new maximum blob size. */ /* ** Invoke the VDBE coverage callback, if that callback is defined. This ** feature is used for test suite validation only and does not appear an ** production builds. ** ** M is the type of branch. I is the direction taken for this instance of ** the branch. ** ** M: 2 - two-way branch (I=0: fall-thru 1: jump ) ** 3 - two-way + NULL (I=0: fall-thru 1: jump 2: NULL ) ** 4 - OP_Jump (I=0: jump p1 1: jump p2 2: jump p3) ** ** In other words, if M is 2, then I is either 0 (for fall-through) or ** 1 (for when the branch is taken). If M is 3, the I is 0 for an ** ordinary fall-through, I is 1 if the branch was taken, and I is 2 ** if the result of comparison is NULL. For M=3, I=2 the jump may or ** may not be taken, depending on the SQLITE_JUMPIFNULL flags in p5. ** When M is 4, that means that an OP_Jump is being run. I is 0, 1, or 2 ** depending on if the operands are less than, equal, or greater than. ** ** iSrcLine is the source code line (from the __LINE__ macro) that ** generated the VDBE instruction combined with flag bits. The source ** code line number is in the lower 24 bits of iSrcLine and the upper ** 8 bytes are flags. The lower three bits of the flags indicate ** values for I that should never occur. For example, if the branch is ** always taken, the flags should be 0x05 since the fall-through and ** alternate branch are never taken. If a branch is never taken then ** flags should be 0x06 since only the fall-through approach is allowed. ** ** Bit 0x08 of the flags indicates an OP_Jump opcode that is only ** interested in equal or not-equal. In other words, I==0 and I==2 ** should be treated as equivalent ** ** Since only a line number is retained, not the filename, this macro ** only works for amalgamation builds. But that is ok, since these macros ** should be no-ops except for special builds used to measure test coverage. */ /* ** An ephemeral string value (signified by the MEM_Ephem flag) contains ** a pointer to a dynamically allocated string where some other entity ** is responsible for deallocating that string. Because the register ** does not control the string, it might be deleted without the register ** knowing it. ** ** This routine converts an ephemeral string into a dynamically allocated ** string that the register itself controls. In other words, it ** converts an MEM_Ephem string into a string with P.z==P.zMalloc. */ /* Return true if the cursor was opened using the OP_OpenSorter opcode. */ // C documentation // // /* // ** Send a "statement aborts" message to the error log. // */ func _sqlite3VdbeLogAbort(tls *libc.TLS, p uintptr, rc int32, pOp uintptr, aOp uintptr) { bp := tls.Alloc(144) defer tls.Free(144) var pc int32 var zPrefix, zSql uintptr var _ /* zXtra at bp+0 */ [100]uint8 _, _, _ = pc, zPrefix, zSql zSql = (*TVdbe)(unsafe.Pointer(p)).FzSql /* Original SQL text */ zPrefix = __ccgo_ts + 1704 /* Buffer space to store zPrefix */ if (*TVdbe)(unsafe.Pointer(p)).FpFrame != 0 { if *(*uintptr)(unsafe.Pointer(aOp + 16)) != uintptr(0) { Xsqlite3_snprintf(tls, int32(100), bp, __ccgo_ts+5782, libc.VaList(bp+112, *(*uintptr)(unsafe.Pointer(aOp + 16))+uintptr(3))) zPrefix = bp } else { zPrefix = __ccgo_ts + 5792 } } pc = int32((int64(pOp) - int64(aOp)) / 24) Xsqlite3_log(tls, rc, __ccgo_ts+5815, libc.VaList(bp+112, pc, (*TVdbe)(unsafe.Pointer(p)).FzErrMsg, zPrefix, zSql)) } // C documentation // // /* // ** Add a single OP_Explain opcode that describes a Bloom filter. // ** // ** Or if not processing EXPLAIN QUERY PLAN and not in a SQLITE_DEBUG and/or // ** SQLITE_ENABLE_STMT_SCANSTATUS build, then OP_Explain opcodes are not // ** required and this routine is a no-op. // ** // ** If an OP_Explain opcode is added to the VM, its address is returned. // ** Otherwise, if no OP_Explain is coded, zero is returned. // */ func _sqlite3WhereExplainBloomFilter(tls *libc.TLS, pParse uintptr, pWInfo uintptr, pLevel uintptr) (r int32) { bp := tls.Alloc(160) defer tls.Free(160) var db, pItem, pLoop, pTab, v, z, zMsg uintptr var i, ret int32 var _ /* str at bp+0 */ TStrAccum var _ /* zBuf at bp+32 */ [100]uint8 _, _, _, _, _, _, _, _, _ = db, i, pItem, pLoop, pTab, ret, v, z, zMsg ret = 0 pItem = (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpTabList + 8 + uintptr((*TWhereLevel)(unsafe.Pointer(pLevel)).FiFrom)*80 v = (*TParse)(unsafe.Pointer(pParse)).FpVdbe /* VM being constructed */ db = (*TParse)(unsafe.Pointer(pParse)).Fdb /* Initial space for EQP output string */ _sqlite3StrAccumInit(tls, bp, db, bp+32, int32(100), int32(SQLITE_MAX_LENGTH)) (**(**TStrAccum)(__ccgo_up(bp))).FprintfFlags = uint8(SQLITE_PRINTF_INTERNAL) Xsqlite3_str_appendf(tls, bp, __ccgo_ts+23895, libc.VaList(bp+144, pItem)) pLoop = (*TWhereLevel)(unsafe.Pointer(pLevel)).FpWLoop if (*TWhereLoop)(unsafe.Pointer(pLoop)).FwsFlags&uint32(WHERE_IPK) != 0 { pTab = (*TSrcItem)(unsafe.Pointer(pItem)).FpSTab if int32((*TTable)(unsafe.Pointer(pTab)).FiPKey) >= 0 { Xsqlite3_str_appendf(tls, bp, __ccgo_ts+23664, libc.VaList(bp+144, (**(**TColumn)(__ccgo_up((*TTable)(unsafe.Pointer(pTab)).FaCol + uintptr((*TTable)(unsafe.Pointer(pTab)).FiPKey)*16))).FzCnName)) } else { Xsqlite3_str_appendf(tls, bp, __ccgo_ts+23916, 0) } } else { i = libc.Int32FromUint16((*TWhereLoop)(unsafe.Pointer(pLoop)).FnSkip) for { if !(i < libc.Int32FromUint16((*(*struct { FnEq Tu16 FnBtm Tu16 FnTop Tu16 FnDistinctCol Tu16 FpIndex uintptr FpOrderBy uintptr })(unsafe.Pointer(pLoop + 24))).FnEq)) { break } z = _explainIndexColumnName(tls, (*(*struct { FnEq Tu16 FnBtm Tu16 FnTop Tu16 FnDistinctCol Tu16 FpIndex uintptr FpOrderBy uintptr })(unsafe.Pointer(pLoop + 24))).FpIndex, i) if i > libc.Int32FromUint16((*TWhereLoop)(unsafe.Pointer(pLoop)).FnSkip) { Xsqlite3_str_append(tls, bp, __ccgo_ts+23653, int32(5)) } Xsqlite3_str_appendf(tls, bp, __ccgo_ts+23664, libc.VaList(bp+144, z)) goto _1 _1: ; i = i + 1 } } Xsqlite3_str_append(tls, bp, __ccgo_ts+5285, int32(1)) zMsg = _sqlite3StrAccumFinish(tls, bp) ret = _sqlite3VdbeAddOp4(tls, v, int32(OP_Explain), _sqlite3VdbeCurrentAddr(tls, v), (*TParse)(unsafe.Pointer(pParse)).FaddrExplain, 0, zMsg, -int32(7)) return ret } // C documentation // // /* // ** timediff(DATE1, DATE2) // ** // ** Return the amount of time that must be added to DATE2 in order to // ** convert it into DATE2. The time difference format is: // ** // ** +YYYY-MM-DD HH:MM:SS.SSS // ** // ** The initial "+" becomes "-" if DATE1 occurs before DATE2. For // ** date/time values A and B, the following invariant should hold: // ** // ** datetime(A) == (datetime(B, timediff(A,B)) // ** // ** Both DATE arguments must be either a julian day number, or an // ** ISO-8601 string. The unix timestamps are not supported by this // ** routine. // */ func _timediffFunc(tls *libc.TLS, context uintptr, NotUsed1 int32, argv uintptr) { bp := tls.Alloc(192) defer tls.Free(192) var M, Y int32 var sign uint8 var v1 uintptr var _ /* d1 at bp+0 */ TDateTime var _ /* d2 at bp+48 */ TDateTime var _ /* sRes at bp+96 */ Tsqlite3_str _, _, _, _ = M, Y, sign, v1 _ = NotUsed1 if _isDate(tls, context, int32(1), argv, bp) != 0 { return } if _isDate(tls, context, int32(1), argv+1*8, bp+48) != 0 { return } _computeYMD_HMS(tls, bp) _computeYMD_HMS(tls, bp+48) if (**(**TDateTime)(__ccgo_up(bp))).FiJD >= (**(**TDateTime)(__ccgo_up(bp + 48))).FiJD { sign = uint8('+') Y = (**(**TDateTime)(__ccgo_up(bp))).FY - (**(**TDateTime)(__ccgo_up(bp + 48))).FY if Y != 0 { (**(**TDateTime)(__ccgo_up(bp + 48))).FY = (**(**TDateTime)(__ccgo_up(bp))).FY (**(**TDateTime)(__ccgo_up(bp + 48))).FvalidJD = uint8(0) _computeJD(tls, bp+48) } M = (**(**TDateTime)(__ccgo_up(bp))).FM - (**(**TDateTime)(__ccgo_up(bp + 48))).FM if M < 0 { Y = Y - 1 M = M + int32(12) } if M != 0 { (**(**TDateTime)(__ccgo_up(bp + 48))).FM = (**(**TDateTime)(__ccgo_up(bp))).FM (**(**TDateTime)(__ccgo_up(bp + 48))).FvalidJD = uint8(0) _computeJD(tls, bp+48) } for (**(**TDateTime)(__ccgo_up(bp))).FiJD < (**(**TDateTime)(__ccgo_up(bp + 48))).FiJD { M = M - 1 if M < 0 { M = int32(11) Y = Y - 1 } (**(**TDateTime)(__ccgo_up(bp + 48))).FM = (**(**TDateTime)(__ccgo_up(bp + 48))).FM - 1 if (**(**TDateTime)(__ccgo_up(bp + 48))).FM < int32(1) { (**(**TDateTime)(__ccgo_up(bp + 48))).FM = int32(12) (**(**TDateTime)(__ccgo_up(bp + 48))).FY = (**(**TDateTime)(__ccgo_up(bp + 48))).FY - 1 } (**(**TDateTime)(__ccgo_up(bp + 48))).FvalidJD = uint8(0) _computeJD(tls, bp+48) } (**(**TDateTime)(__ccgo_up(bp))).FiJD -= (**(**TDateTime)(__ccgo_up(bp + 48))).FiJD v1 = bp *(*Tsqlite3_int64)(unsafe.Pointer(v1)) = Tsqlite3_int64(uint64(*(*Tsqlite3_int64)(unsafe.Pointer(v1))) + libc.Uint64FromInt32(1486995408)*libc.Uint64FromInt32(100000)) } else { /* d1 (**(**TDateTime)(__ccgo_up(bp + 48))).FiJD { M = M - 1 if M < 0 { M = int32(11) Y = Y - 1 } (**(**TDateTime)(__ccgo_up(bp + 48))).FM = (**(**TDateTime)(__ccgo_up(bp + 48))).FM + 1 if (**(**TDateTime)(__ccgo_up(bp + 48))).FM > int32(12) { (**(**TDateTime)(__ccgo_up(bp + 48))).FM = int32(1) (**(**TDateTime)(__ccgo_up(bp + 48))).FY = (**(**TDateTime)(__ccgo_up(bp + 48))).FY + 1 } (**(**TDateTime)(__ccgo_up(bp + 48))).FvalidJD = uint8(0) _computeJD(tls, bp+48) } (**(**TDateTime)(__ccgo_up(bp))).FiJD = (**(**TDateTime)(__ccgo_up(bp + 48))).FiJD - (**(**TDateTime)(__ccgo_up(bp))).FiJD v1 = bp *(*Tsqlite3_int64)(unsafe.Pointer(v1)) = Tsqlite3_int64(uint64(*(*Tsqlite3_int64)(unsafe.Pointer(v1))) + libc.Uint64FromInt32(1486995408)*libc.Uint64FromInt32(100000)) } _clearYMD_HMS_TZ(tls, bp) _computeYMD_HMS(tls, bp) _sqlite3StrAccumInit(tls, bp+96, uintptr(0), uintptr(0), 0, int32(100)) Xsqlite3_str_appendf(tls, bp+96, __ccgo_ts+1485, libc.VaList(bp+136, libc.Int32FromUint8(sign), Y, M, (**(**TDateTime)(__ccgo_up(bp))).FD-int32(1), (**(**TDateTime)(__ccgo_up(bp))).Fh, (**(**TDateTime)(__ccgo_up(bp))).Fm, (**(**TDateTime)(__ccgo_up(bp))).Fs)) _sqlite3ResultStrAccum(tls, context, bp+96) } // C documentation // // /* // ** Implementation of the UNISTR() function. // ** // ** This is intended to be a work-alike of the UNISTR() function in // ** PostgreSQL. Quoting from the PG documentation (PostgreSQL 17 - // ** scraped on 2025-02-22): // ** // ** Evaluate escaped Unicode characters in the argument. Unicode // ** characters can be specified as \XXXX (4 hexadecimal digits), // ** \+XXXXXX (6 hexadecimal digits), \uXXXX (4 hexadecimal digits), // ** or \UXXXXXXXX (8 hexadecimal digits). To specify a backslash, // ** write two backslashes. All other characters are taken literally. // */ func _unistrFunc(tls *libc.TLS, context uintptr, argc int32, argv uintptr) { bp := tls.Alloc(16) defer tls.Free(16) var i, j, n, nIn, v1 int32 var z, zIn, zOut uintptr var _ /* v at bp+0 */ Tu32 _, _, _, _, _, _, _, _ = i, j, n, nIn, z, zIn, zOut, v1 _ = argc zIn = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv))) if zIn == uintptr(0) { return } nIn = Xsqlite3_value_bytes(tls, **(**uintptr)(__ccgo_up(argv))) zOut = Xsqlite3_malloc64(tls, libc.Uint64FromInt32(nIn+int32(1))) if zOut == uintptr(0) { Xsqlite3_result_error_nomem(tls, context) return } v1 = libc.Int32FromInt32(0) j = v1 i = v1 for i < nIn { z = libc.Xstrchr(tls, zIn+uintptr(i), int32('\\')) if z == uintptr(0) { n = nIn - i libc.Xmemmove(tls, zOut+uintptr(j), zIn+uintptr(i), libc.Uint64FromInt32(n)) j = j + n break } n = int32(int64(z) - t__predefined_ptrdiff_t(zIn+uintptr(i))) if n > 0 { libc.Xmemmove(tls, zOut+uintptr(j), zIn+uintptr(i), libc.Uint64FromInt32(n)) j = j + n i = i + n } if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zIn + uintptr(i+int32(1))))) == int32('\\') { i = i + int32(2) v1 = j j = j + 1 **(**uint8)(__ccgo_up(zOut + uintptr(v1))) = uint8('\\') } else { if libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(zIn + uintptr(i+int32(1)))))])&int32(0x08) != 0 { if !(_isNHex(tls, zIn+uintptr(i+int32(1)), int32(4), bp) != 0) { goto unistr_error } i = i + int32(5) j = j + _sqlite3AppendOneUtf8Character(tls, zOut+uintptr(j), **(**Tu32)(__ccgo_up(bp))) } else { if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zIn + uintptr(i+int32(1))))) == int32('+') { if !(_isNHex(tls, zIn+uintptr(i+int32(2)), int32(6), bp) != 0) { goto unistr_error } i = i + int32(8) j = j + _sqlite3AppendOneUtf8Character(tls, zOut+uintptr(j), **(**Tu32)(__ccgo_up(bp))) } else { if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zIn + uintptr(i+int32(1))))) == int32('u') { if !(_isNHex(tls, zIn+uintptr(i+int32(2)), int32(4), bp) != 0) { goto unistr_error } i = i + int32(6) j = j + _sqlite3AppendOneUtf8Character(tls, zOut+uintptr(j), **(**Tu32)(__ccgo_up(bp))) } else { if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zIn + uintptr(i+int32(1))))) == int32('U') { if !(_isNHex(tls, zIn+uintptr(i+int32(2)), int32(8), bp) != 0) { goto unistr_error } i = i + int32(10) j = j + _sqlite3AppendOneUtf8Character(tls, zOut+uintptr(j), **(**Tu32)(__ccgo_up(bp))) } else { goto unistr_error } } } } } } **(**uint8)(__ccgo_up(zOut + uintptr(j))) = uint8(0) Xsqlite3_result_text64(tls, context, zOut, libc.Uint64FromInt32(j), __ccgo_fp(Xsqlite3_free), uint8(SQLITE_UTF8_ZT)) return goto unistr_error unistr_error: ; Xsqlite3_free(tls, zOut) Xsqlite3_result_error(tls, context, __ccgo_ts+16599, -int32(1)) return } // C documentation // // /* // ** Turn a relative pathname into a full pathname. The relative path // ** is stored as a nul-terminated string in the buffer pointed to by // ** zPath. // ** // ** zOut points to a buffer of at least sqlite3_vfs.mxPathname bytes // ** (in this case, MAX_PATHNAME bytes). The full-path is written to // ** this buffer before returning. // */ func _unixFullPathname(tls *libc.TLS, pVfs uintptr, zPath uintptr, nOut int32, zOut uintptr) (r int32) { bp := tls.Alloc(4128) defer tls.Free(4128) var _ /* path at bp+0 */ TDbPath var _ /* zPwd at bp+24 */ [4098]uint8 _ = pVfs (**(**TDbPath)(__ccgo_up(bp))).Frc = 0 (**(**TDbPath)(__ccgo_up(bp))).FnUsed = 0 (**(**TDbPath)(__ccgo_up(bp))).FnSymlink = 0 (**(**TDbPath)(__ccgo_up(bp))).FnOut = nOut (**(**TDbPath)(__ccgo_up(bp))).FzOut = zOut if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zPath))) != int32('/') { if (*(*func(*libc.TLS, uintptr, Tsize_t) uintptr)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(3)].FpCurrent})))(tls, bp+24, libc.Uint64FromInt64(4098)-libc.Uint64FromInt32(2)) == uintptr(0) { return _unixLogErrorAtLine(tls, _sqlite3CantopenError(tls, int32(47366)), __ccgo_ts+3560, zPath, int32(47366)) } _appendAllPathElements(tls, bp, bp+24) } _appendAllPathElements(tls, bp, zPath) **(**uint8)(__ccgo_up(zOut + uintptr((**(**TDbPath)(__ccgo_up(bp))).FnUsed))) = uint8(0) if (**(**TDbPath)(__ccgo_up(bp))).Frc != 0 || (**(**TDbPath)(__ccgo_up(bp))).FnUsed < int32(2) { return _sqlite3CantopenError(tls, int32(47372)) } if (**(**TDbPath)(__ccgo_up(bp))).FnSymlink != 0 { return libc.Int32FromInt32(SQLITE_OK) | libc.Int32FromInt32(2)< (READWRITE | CREATE) // ** ReadOnly() -> (READONLY) // ** OpenExclusive() -> (READWRITE | CREATE | EXCLUSIVE) // ** // ** The old OpenExclusive() accepted a boolean argument - "delFlag". If // ** true, the file was configured to be automatically deleted when the // ** file handle closed. To achieve the same effect using this new // ** interface, add the DELETEONCLOSE flag to those specified above for // ** OpenExclusive(). // */ func _unixOpen(tls *libc.TLS, pVfs uintptr, zPath uintptr, pFile uintptr, flags int32, pOutFlags uintptr) (r int32) { bp := tls.Alloc(528) defer tls.Free(528) var ctrlFlags, eType, fd, isCreate, isDelete, isExclusive, isNewJrnl, isReadWrite, isReadonly, noLock, openFlags, rc, rc2 int32 var p, pReadonly, pUnused, zName uintptr var _ /* gid at bp+524 */ Tgid_t var _ /* openMode at bp+516 */ Tmode_t var _ /* uid at bp+520 */ Tuid_t var _ /* zTmpname at bp+0 */ [514]uint8 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = ctrlFlags, eType, fd, isCreate, isDelete, isExclusive, isNewJrnl, isReadWrite, isReadonly, noLock, openFlags, p, pReadonly, pUnused, rc, rc2, zName p = pFile fd = -int32(1) /* File descriptor returned by open() */ openFlags = 0 /* Flags to pass to open() */ eType = flags & int32(0x0FFF00) /* True to omit locking primitives */ rc = SQLITE_OK /* Function Return Code */ ctrlFlags = 0 /* UNIXFILE_* flags */ isExclusive = flags & int32(SQLITE_OPEN_EXCLUSIVE) isDelete = flags & int32(SQLITE_OPEN_DELETEONCLOSE) isCreate = flags & int32(SQLITE_OPEN_CREATE) isReadonly = flags & int32(SQLITE_OPEN_READONLY) isReadWrite = flags & int32(SQLITE_OPEN_READWRITE) /* If creating a super- or main-file journal, this function will open ** a file-descriptor on the directory too. The first time unixSync() ** is called the directory file descriptor will be fsync()ed and close()d. */ isNewJrnl = libc.BoolInt32(isCreate != 0 && (eType == int32(SQLITE_OPEN_SUPER_JOURNAL) || eType == int32(SQLITE_OPEN_MAIN_JOURNAL) || eType == int32(SQLITE_OPEN_WAL))) zName = zPath /* Check the following statements are true: ** ** (a) Exactly one of the READWRITE and READONLY flags must be set, and ** (b) if CREATE is set, then READWRITE must also be set, and ** (c) if EXCLUSIVE is set, then CREATE must also be set. ** (d) if DELETEONCLOSE is set, then CREATE must also be set. */ /* The main DB, main journal, WAL file and super-journal are never ** automatically deleted. Nor are they ever temporary files. */ /* Assert that the upper layer has set one of the "file-type" flags. */ /* Detect a pid change and reset the PRNG. There is a race condition ** here such that two or more threads all trying to open databases at ** the same instant might all reset the PRNG. But multiple resets ** are harmless. */ if libc.AtomicLoadPInt32(uintptr(unsafe.Pointer(&_randomnessPid))) != libc.Xgetpid(tls) { libc.AtomicStorePInt32(uintptr(unsafe.Pointer(&_randomnessPid)), libc.Xgetpid(tls)) Xsqlite3_randomness(tls, 0, uintptr(0)) } libc.Xmemset(tls, p, 0, uint64(120)) if eType == int32(SQLITE_OPEN_MAIN_DB) { pUnused = _findReusableFd(tls, zName, flags) if pUnused != 0 { fd = (*TUnixUnusedFd)(unsafe.Pointer(pUnused)).Ffd } else { pUnused = Xsqlite3_malloc64(tls, uint64(16)) if !(pUnused != 0) { return int32(SQLITE_NOMEM) } } (*TunixFile)(unsafe.Pointer(p)).FpPreallocatedUnused = pUnused /* Database filenames are double-zero terminated if they are not ** URIs with parameters. Hence, they can always be passed into ** sqlite3_uri_parameter(). */ } else { if !(zName != 0) { /* If zName is NULL, the upper layer is requesting a temp file. */ rc = _unixGetTempname(tls, (*Tsqlite3_vfs)(unsafe.Pointer(pVfs)).FmxPathname, bp) if rc != SQLITE_OK { return rc } zName = bp /* Generated temporary filenames are always double-zero terminated ** for use by sqlite3_uri_parameter(). */ } } /* Determine the value of the flags parameter passed to POSIX function ** open(). These must be calculated even if open() is not called, as ** they may be stored as part of the file handle and used by the ** 'conch file' locking functions later on. */ if isReadonly != 0 { openFlags = openFlags | O_RDONLY } if isReadWrite != 0 { openFlags = openFlags | int32(O_RDWR) } if isCreate != 0 { openFlags = openFlags | int32(O_CREAT) } if isExclusive != 0 { openFlags = openFlags | (libc.Int32FromInt32(O_EXCL) | libc.Int32FromInt32(O_NOFOLLOW)) } openFlags = openFlags | (libc.Int32FromInt32(O_LARGEFILE) | libc.Int32FromInt32(O_BINARY) | libc.Int32FromInt32(O_NOFOLLOW)) if fd < 0 { /* Groupid for the file */ rc = _findCreateFileMode(tls, zName, flags, bp+516, bp+520, bp+524) if rc != SQLITE_OK { return rc } fd = _robust_open(tls, zName, openFlags, **(**Tmode_t)(__ccgo_up(bp + 516))) if fd < 0 { if isNewJrnl != 0 && **(**int32)(__ccgo_up(libc.X__errno_location(tls))) == int32(EACCES) && (*(*func(*libc.TLS, uintptr, int32) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(2)].FpCurrent})))(tls, zName, F_OK) != 0 { /* If unable to create a journal because the directory is not ** writable, change the error code to indicate that. */ rc = libc.Int32FromInt32(SQLITE_READONLY) | libc.Int32FromInt32(6)<zErrMsg. // */ func _viewGetColumnNames(tls *libc.TLS, pParse uintptr, pTable uintptr) (r int32) { bp := tls.Alloc(16) defer tls.Free(16) var db, pSel, pSelTab, v2 uintptr var eParseMode Tu8 var nErr, nSelect, nTab, rc, v1 int32 var xAuth Tsqlite3_xauth _, _, _, _, _, _, _, _, _, _, _ = db, eParseMode, nErr, nSelect, nTab, pSel, pSelTab, rc, xAuth, v1, v2 /* Copy of the SELECT that implements the view */ nErr = 0 /* Number of errors encountered */ db = (*TParse)(unsafe.Pointer(pParse)).Fdb /* Saved xAuth pointer */ if libc.Int32FromUint8((*TTable)(unsafe.Pointer(pTable)).FeTabType) == int32(TABTYP_VTAB) { (*Tsqlite3)(unsafe.Pointer(db)).FnSchemaLock = (*Tsqlite3)(unsafe.Pointer(db)).FnSchemaLock + 1 rc = _sqlite3VtabCallConnect(tls, pParse, pTable) (*Tsqlite3)(unsafe.Pointer(db)).FnSchemaLock = (*Tsqlite3)(unsafe.Pointer(db)).FnSchemaLock - 1 return rc } /* A positive nCol means the columns names for this view are ** already known. This routine is not called unless either the ** table is virtual or nCol is zero. */ /* A negative nCol is a special marker meaning that we are currently ** trying to compute the column names. If we enter this routine with ** a negative nCol, it means two or more views form a loop, like this: ** ** CREATE VIEW one AS SELECT * FROM two; ** CREATE VIEW two AS SELECT * FROM one; ** ** Actually, the error above is now caught prior to reaching this point. ** But the following test is still important as it does come up ** in the following: ** ** CREATE TABLE main.ex1(a); ** CREATE TEMP VIEW ex1 AS SELECT a FROM ex1; ** SELECT * FROM temp.ex1; */ if int32((*TTable)(unsafe.Pointer(pTable)).FnCol) < 0 { _sqlite3ErrorMsg(tls, pParse, __ccgo_ts+14867, libc.VaList(bp+8, (*TTable)(unsafe.Pointer(pTable)).FzName)) return int32(1) } /* If we get this far, it means we need to compute the table names. ** Note that the call to sqlite3ResultSetOfSelect() will expand any ** "*" elements in the results set of the view and will assign cursors ** to the elements of the FROM clause. But we do not want these changes ** to be permanent. So the computation is done on a copy of the SELECT ** statement that defines the view. */ pSel = _sqlite3SelectDup(tls, db, (*(*struct { FpSelect uintptr })(unsafe.Pointer(&(*TTable)(unsafe.Pointer(pTable)).Fu))).FpSelect, 0) if pSel != 0 { eParseMode = (*TParse)(unsafe.Pointer(pParse)).FeParseMode nTab = (*TParse)(unsafe.Pointer(pParse)).FnTab nSelect = (*TParse)(unsafe.Pointer(pParse)).FnSelect (*TParse)(unsafe.Pointer(pParse)).FeParseMode = uint8(PARSE_MODE_NORMAL) _sqlite3SrcListAssignCursors(tls, pParse, (*TSelect)(unsafe.Pointer(pSel)).FpSrc) (*TTable)(unsafe.Pointer(pTable)).FnCol = int16(-int32(1)) (*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FbDisable = (*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FbDisable + 1 (*Tsqlite3)(unsafe.Pointer(db)).Flookaside.Fsz = uint16(0) xAuth = (*Tsqlite3)(unsafe.Pointer(db)).FxAuth (*Tsqlite3)(unsafe.Pointer(db)).FxAuth = uintptr(0) pSelTab = _sqlite3ResultSetOfSelect(tls, pParse, pSel, uint8(SQLITE_AFF_NONE)) (*Tsqlite3)(unsafe.Pointer(db)).FxAuth = xAuth (*TParse)(unsafe.Pointer(pParse)).FnTab = nTab (*TParse)(unsafe.Pointer(pParse)).FnSelect = nSelect if pSelTab == uintptr(0) { (*TTable)(unsafe.Pointer(pTable)).FnCol = 0 nErr = nErr + 1 } else { if (*TTable)(unsafe.Pointer(pTable)).FpCheck != 0 { /* CREATE VIEW name(arglist) AS ... ** The names of the columns in the table are taken from ** arglist which is stored in pTable->pCheck. The pCheck field ** normally holds CHECK constraints on an ordinary table, but for ** a VIEW it holds the list of column names. */ _sqlite3ColumnsFromExprList(tls, pParse, (*TTable)(unsafe.Pointer(pTable)).FpCheck, pTable+54, pTable+8) if (*TParse)(unsafe.Pointer(pParse)).FnErr == 0 && int32((*TTable)(unsafe.Pointer(pTable)).FnCol) == (*TExprList)(unsafe.Pointer((*TSelect)(unsafe.Pointer(pSel)).FpEList)).FnExpr { _sqlite3SubqueryColumnTypes(tls, pParse, pTable, pSel, uint8(SQLITE_AFF_NONE)) } } else { /* CREATE VIEW name AS... without an argument list. Construct ** the column names from the SELECT statement that defines the view. */ (*TTable)(unsafe.Pointer(pTable)).FnCol = (*TTable)(unsafe.Pointer(pSelTab)).FnCol (*TTable)(unsafe.Pointer(pTable)).FaCol = (*TTable)(unsafe.Pointer(pSelTab)).FaCol **(**Tu32)(__ccgo_up(pTable + 48)) |= (*TTable)(unsafe.Pointer(pSelTab)).FtabFlags & uint32(COLFLAG_NOINSERT) (*TTable)(unsafe.Pointer(pSelTab)).FnCol = 0 (*TTable)(unsafe.Pointer(pSelTab)).FaCol = uintptr(0) } } (*TTable)(unsafe.Pointer(pTable)).FnNVCol = (*TTable)(unsafe.Pointer(pTable)).FnCol _sqlite3DeleteTable(tls, db, pSelTab) _sqlite3SelectDelete(tls, db, pSel) (*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FbDisable = (*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FbDisable - 1 if (*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FbDisable != 0 { v1 = 0 } else { v1 = libc.Int32FromUint16((*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FszTrue) } (*Tsqlite3)(unsafe.Pointer(db)).Flookaside.Fsz = libc.Uint16FromInt32(v1) (*TParse)(unsafe.Pointer(pParse)).FeParseMode = eParseMode } else { nErr = nErr + 1 } v2 = (*TTable)(unsafe.Pointer(pTable)).FpSchema + 114 *(*Tu16)(unsafe.Pointer(v2)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v2))) | libc.Int32FromInt32(DB_UnresetViews)) if (*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed != 0 { _sqlite3DeleteColumnNames(tls, db, pTable) } return nErr + (*TParse)(unsafe.Pointer(pParse)).FnErr } // C documentation // // /* // ** Invoke a virtual table constructor (either xCreate or xConnect). The // ** pointer to the function to invoke is passed as the fourth parameter // ** to this procedure. // */ func _vtabCallConstructor(tls *libc.TLS, db uintptr, pTab uintptr, pMod uintptr, __ccgo_fp_xConstruct uintptr, pzErr uintptr) (r int32) { bp := tls.Alloc(64) defer tls.Free(64) var azArg, pCtx, pVTable, zFormat, zModuleName, zType, v6 uintptr var i, iCol, iDb, j, nArg, nDel, nType, rc, v4 int32 var oooHidden Tu16 var _ /* sCtx at bp+0 */ TVtabCtx var _ /* zErr at bp+32 */ uintptr _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = azArg, i, iCol, iDb, j, nArg, nDel, nType, oooHidden, pCtx, pVTable, rc, zFormat, zModuleName, zType, v4, v6 nArg = (*(*struct { FnArg int32 FazArg uintptr Fp uintptr })(unsafe.Pointer(pTab + 64))).FnArg **(**uintptr)(__ccgo_up(bp + 32)) = uintptr(0) azArg = (*(*struct { FnArg int32 FazArg uintptr Fp uintptr })(unsafe.Pointer(pTab + 64))).FazArg /* Check that the virtual-table is not already being initialized */ pCtx = (*Tsqlite3)(unsafe.Pointer(db)).FpVtabCtx for { if !(pCtx != 0) { break } if (*TVtabCtx)(unsafe.Pointer(pCtx)).FpTab == pTab { **(**uintptr)(__ccgo_up(pzErr)) = _sqlite3MPrintf(tls, db, __ccgo_ts+23496, libc.VaList(bp+48, (*TTable)(unsafe.Pointer(pTab)).FzName)) return int32(SQLITE_LOCKED) } goto _1 _1: ; pCtx = (*TVtabCtx)(unsafe.Pointer(pCtx)).FpPrior } zModuleName = _sqlite3DbStrDup(tls, db, (*TTable)(unsafe.Pointer(pTab)).FzName) if !(zModuleName != 0) { return int32(SQLITE_NOMEM) } pVTable = _sqlite3MallocZero(tls, uint64(48)) if !(pVTable != 0) { _sqlite3OomFault(tls, db) _sqlite3DbFree(tls, db, zModuleName) return int32(SQLITE_NOMEM) } (*TVTable)(unsafe.Pointer(pVTable)).Fdb = db (*TVTable)(unsafe.Pointer(pVTable)).FpMod = pMod (*TVTable)(unsafe.Pointer(pVTable)).FeVtabRisk = uint8(SQLITE_VTABRISK_Normal) iDb = _sqlite3SchemaToIndex(tls, db, (*TTable)(unsafe.Pointer(pTab)).FpSchema) **(**uintptr)(__ccgo_up((*(*struct { FnArg int32 FazArg uintptr Fp uintptr })(unsafe.Pointer(pTab + 64))).FazArg + 1*8)) = (**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(db)).FaDb + uintptr(iDb)*32))).FzDbSName /* Invoke the virtual table constructor */ (**(**TVtabCtx)(__ccgo_up(bp))).FpTab = pTab (**(**TVtabCtx)(__ccgo_up(bp))).FpVTable = pVTable (**(**TVtabCtx)(__ccgo_up(bp))).FpPrior = (*Tsqlite3)(unsafe.Pointer(db)).FpVtabCtx (**(**TVtabCtx)(__ccgo_up(bp))).FbDeclared = 0 (*Tsqlite3)(unsafe.Pointer(db)).FpVtabCtx = bp (*TTable)(unsafe.Pointer(pTab)).FnTabRef = (*TTable)(unsafe.Pointer(pTab)).FnTabRef + 1 rc = (*(*func(*libc.TLS, uintptr, uintptr, int32, uintptr, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{__ccgo_fp_xConstruct})))(tls, db, (*TModule)(unsafe.Pointer(pMod)).FpAux, nArg, azArg, pVTable+16, bp+32) _sqlite3DeleteTable(tls, db, pTab) (*Tsqlite3)(unsafe.Pointer(db)).FpVtabCtx = (**(**TVtabCtx)(__ccgo_up(bp))).FpPrior if rc == int32(SQLITE_NOMEM) { _sqlite3OomFault(tls, db) } if SQLITE_OK != rc { if **(**uintptr)(__ccgo_up(bp + 32)) == uintptr(0) { **(**uintptr)(__ccgo_up(pzErr)) = _sqlite3MPrintf(tls, db, __ccgo_ts+23538, libc.VaList(bp+48, zModuleName)) } else { **(**uintptr)(__ccgo_up(pzErr)) = _sqlite3MPrintf(tls, db, __ccgo_ts+3968, libc.VaList(bp+48, **(**uintptr)(__ccgo_up(bp + 32)))) Xsqlite3_free(tls, **(**uintptr)(__ccgo_up(bp + 32))) } _sqlite3DbFree(tls, db, pVTable) } else { if (*TVTable)(unsafe.Pointer(pVTable)).FpVtab != 0 { /* Justification of ALWAYS(): A correct vtab constructor must allocate ** the sqlite3_vtab object if successful. */ libc.Xmemset(tls, (*TVTable)(unsafe.Pointer(pVTable)).FpVtab, 0, uint64(24)) (*Tsqlite3_vtab)(unsafe.Pointer((*TVTable)(unsafe.Pointer(pVTable)).FpVtab)).FpModule = (*TModule)(unsafe.Pointer(pMod)).FpModule (*TModule)(unsafe.Pointer(pMod)).FnRefModule = (*TModule)(unsafe.Pointer(pMod)).FnRefModule + 1 (*TVTable)(unsafe.Pointer(pVTable)).FnRef = int32(1) if (**(**TVtabCtx)(__ccgo_up(bp))).FbDeclared == 0 { zFormat = __ccgo_ts + 23568 **(**uintptr)(__ccgo_up(pzErr)) = _sqlite3MPrintf(tls, db, zFormat, libc.VaList(bp+48, zModuleName)) _sqlite3VtabUnlock(tls, pVTable) rc = int32(SQLITE_ERROR) } else { oooHidden = uint16(0) /* If everything went according to plan, link the new VTable structure ** into the linked list headed by pTab->u.vtab.p. Then loop through the ** columns of the table to see if any of them contain the token "hidden". ** If so, set the Column COLFLAG_HIDDEN flag and remove the token from ** the type string. */ (*TVTable)(unsafe.Pointer(pVTable)).FpNext = (*(*struct { FnArg int32 FazArg uintptr Fp uintptr })(unsafe.Pointer(pTab + 64))).Fp (*(*struct { FnArg int32 FazArg uintptr Fp uintptr })(unsafe.Pointer(pTab + 64))).Fp = pVTable iCol = 0 for { if !(iCol < int32((*TTable)(unsafe.Pointer(pTab)).FnCol)) { break } zType = _sqlite3ColumnType(tls, (*TTable)(unsafe.Pointer(pTab)).FaCol+uintptr(iCol)*16, __ccgo_ts+1704) i = 0 nType = _sqlite3Strlen30(tls, zType) i = 0 for { if !(i < nType) { break } if 0 == Xsqlite3_strnicmp(tls, __ccgo_ts+17882, zType+uintptr(i), int32(6)) && (i == 0 || libc.Int32FromUint8(**(**uint8)(__ccgo_up(zType + uintptr(i-int32(1))))) == int32(' ')) && (libc.Int32FromUint8(**(**uint8)(__ccgo_up(zType + uintptr(i+int32(6))))) == int32('\000') || libc.Int32FromUint8(**(**uint8)(__ccgo_up(zType + uintptr(i+int32(6))))) == int32(' ')) { break } goto _3 _3: ; i = i + 1 } if i < nType { if **(**uint8)(__ccgo_up(zType + uintptr(i+int32(6)))) != 0 { v4 = int32(1) } else { v4 = 0 } nDel = int32(6) + v4 j = i for { if !(j+nDel <= nType) { break } **(**uint8)(__ccgo_up(zType + uintptr(j))) = **(**uint8)(__ccgo_up(zType + uintptr(j+nDel))) goto _5 _5: ; j = j + 1 } if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zType + uintptr(i)))) == int32('\000') && i > 0 { **(**uint8)(__ccgo_up(zType + uintptr(i-int32(1)))) = uint8('\000') } v6 = (*TTable)(unsafe.Pointer(pTab)).FaCol + uintptr(iCol)*16 + 14 *(*Tu16)(unsafe.Pointer(v6)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v6))) | libc.Int32FromInt32(COLFLAG_HIDDEN)) **(**Tu32)(__ccgo_up(pTab + 48)) |= uint32(TF_HasHidden) oooHidden = uint16(TF_OOOHidden) } else { **(**Tu32)(__ccgo_up(pTab + 48)) |= uint32(oooHidden) } goto _2 _2: ; iCol = iCol + 1 } } } } _sqlite3DbFree(tls, db, zModuleName) return rc }