struct sqlite3_index_info { /* Inputs */ int nConstraint; /* Number of entries in aConstraint */ struct sqlite3_index_constraint { int iColumn; /* Column constrained. -1 for ROWID */ unsigned char op; /* Constraint operator */ unsigned char usable; /* True if this constraint is usable */ int iTermOffset; /* Used internally - xBestIndex should ignore */ } *aConstraint; /* Table of WHERE clause constraints */ int nOrderBy; /* Number of terms in the ORDER BY clause */ struct sqlite3_index_orderby { int iColumn; /* Column number */ unsigned char desc; /* True for DESC. False for ASC. */ } *aOrderBy; /* The ORDER BY clause */ /* Outputs */ struct sqlite3_index_constraint_usage { int argvIndex; /* if >0, constraint is part of argv to xFilter */ unsigned char omit; /* Do not code a test for this constraint */ } *aConstraintUsage; int idxNum; /* Number used to identify the index */ char *idxStr; /* String, possibly obtained from sqlite3_malloc */ int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */ int orderByConsumed; /* True if output is already ordered */ double estimatedCost; /* Estimated cost of using this index */ /* Fields below are only available in SQLite 3.8.2 and later */ sqlite3_int64 estimatedRows; /* Estimated number of rows returned */ /* Fields below are only available in SQLite 3.9.0 and later */ int idxFlags; /* Mask of SQLITE_INDEX_SCAN_* flags */ /* Fields below are only available in SQLite 3.10.0 and later */ sqlite3_uint64 colUsed; /* Input: Mask of columns used by statement */ };
sqlite3_index_info 结构及其子结构用作 虚拟表 接口的一部分,用于将信息传递到 xBestIndex 方法,以及接收 虚拟表模块 的回复。**输入** 下面的字段是 xBestIndex 的输入,并且是只读的。xBestIndex 将其结果插入 **输出** 字段中。
aConstraint[] 数组记录形式为
column OP expr
的 WHERE 子句约束,其中 OP 是 =、<、<=、> 或 >=。特定操作符存储在 aConstraint[].op 中,使用 SQLITE_INDEX_CONSTRAINT_ 值 之一。列的索引存储在 aConstraint[].iColumn 中。aConstraint[].usable 为 TRUE 如果右边的 expr 可以被评估(因此约束是可用的),否则为 false。
优化器会自动反转 "expr OP column" 形式的项,并对 WHERE 子句进行其他简化,试图将尽可能多的 WHERE 子句项转换为上面显示的格式。aConstraint[] 数组只报告与正在查询的特定虚拟表相关的 WHERE 子句项。
有关 ORDER BY 子句的信息存储在 aOrderBy[] 中。aOrderBy 的每个项记录 ORDER BY 子句的一列。
colUsed 字段指示当前扫描可能需要虚拟表的哪些列。虚拟表列从零开始编号,顺序与它们在传递给 sqlite3_declare_vtab() 的 CREATE TABLE 语句中出现的顺序相同。对于前 63 列(列 0-62),如果列可能被 SQLite 需要,则在 colUsed 掩码中设置相应的位。如果表至少有 64 列,并且前 63 列中的任何列都是必需的,那么 colUsed 的第 63 位也被设置。换句话说,如果表达式 (colUsed & ((sqlite3_uint64)1 << (iCol>=63 ? 63 : iCol))) 的值为非零,则列 iCol 可能是必需的。
xBestIndex 方法必须使用有关要传递给 xFilter 的参数的信息来填充 aConstraintUsage[]。如果 argvIndex>0,则评估相应的 aConstraint[] 的右侧,并成为 argv 中的第 argvIndex 个条目。如果 aConstraintUsage[].omit 为 true,则假定约束由虚拟表完全处理,并且可能不会由字节码再次检查。aConstraintUsage[].omit 标志是一个优化提示。当 omit 标志保留在它的默认设置 false 时,约束将始终在字节码中单独检查。如果 omit 标志更改为 true,则约束可能在字节码中被检查,也可能不被检查。换句话说,当 omit 标志为 true 时,不能保证约束不会使用字节码再次被检查。
idxNum 和 idxStr 值被记录并传递到 xFilter 方法中。仅当 needToFreeIdxStr 为 true 时,才使用 sqlite3_free() 释放 idxStr。
orderByConsumed 意味着来自 xFilter/xNext 的输出将按满足 ORDER BY 子句的正确顺序出现,因此不需要单独的排序步骤。
estimatedCost 值是对特定策略成本的估计。成本为 N 表示策略的成本类似于对具有 N 行的 SQLite 表进行线性扫描。成本为 log(N) 表示操作的开销类似于对具有 N 行的 SQLite 表的唯一索引字段进行二进制搜索。
estimatedRows 值是对策略将返回的行数的估计。
xBestIndex 方法可以选择使用 SQLITE_INDEX_SCAN_* 标志的掩码来填充 idxFlags 字段。目前只有一个这样的标志 - SQLITE_INDEX_SCAN_UNIQUE。如果 xBestIndex 方法设置了此标志,SQLite 假设该策略最多可以访问一行。
此外,如果 xBestIndex 设置了 SQLITE_INDEX_SCAN_UNIQUE 标志,那么 SQLite 还假设如果作为同一语句的一部分对虚拟表行进行删除或更新时调用了 xUpdate() 方法,并且实现返回了 SQLITE_CONSTRAINT,那么就不需要回滚任何数据库更改。换句话说,如果 xUpdate() 返回 SQLITE_CONSTRAINT,则数据库内容必须与调用 xUpdate 之前的状态完全相同。相反,如果未设置 SQLITE_INDEX_SCAN_UNIQUE 并且 xUpdate 返回 SQLITE_CONSTRAINT,则 SQLite 会自动回滚 xUpdate 方法所做的任何数据库更改。
重要:estimatedRows 字段是在 SQLite 版本 3.8.2(2013-12-06)中添加到 sqlite3_index_info 结构的。如果虚拟表扩展与早于 3.8.2 的 SQLite 版本一起使用,尝试读取或写入 estimatedRows 字段的结果是未定义的(但可能会导致应用程序崩溃)。因此,estimatedRows 字段应仅在 sqlite3_libversion_number() 返回大于或等于 3008002 的值时使用。类似地,idxFlags 字段是在 版本 3.9.0(2015-10-14)中添加的。因此,它只能在 sqlite3_libversion_number() 返回大于或等于 3009000 的值时使用。
使用此对象的 3 种方法:sqlite3_vtab_collation()、sqlite3_vtab_distinct()、sqlite3_vtab_rhs_value()