SQLite C 接口
识别和处理 xBestIndex 中的 IN 约束
int sqlite3_vtab_in(sqlite3_index_info*, int iCons, int bHandle);
此接口只能在 虚拟表实现的xBestIndex() 方法中使用。从任何其他上下文调用此接口的结果是未定义的并且可能是有害的。
对形式为“ column IN (...) ”的虚拟表的约束作为 SQLITE_INDEX_CONSTRAINT_EQ约束传递给 xBestIndex 方法。如果 xBestIndex 想要使用这个约束,它必须将相应的 aConstraintUsage[].argvIndex 设置为一个正整数。然后,在处理 IN 运算符的通常模式下,SQLite 生成字节码,为 IN 运算符右侧的每个值 调用一次xFilter() 方法。因此,虚拟表一次只能从 IN 运算符的右侧看到一个值。
然而,在某些情况下,虚拟表同时查看 IN 运算符右侧的所有值是有利的。sqlite3_vtab_in() 接口以两种方式促进了这一点:
当且仅当P->aConstraint [N] 约束是一个可以同时处理的IN 运算符时, 对 sqlite3_vtab_in(P,N,-1) 的调用将返回 true(非零) 。换句话说,第三个参数为 -1 的 sqlite3_vtab_in() 是一种机制,虚拟表可以通过这种机制询问 SQLite 是否可以一次性处理 IN 运算符。
使用 F==1 或 F==0 调用 sqlite3_vtab_in(P,N,F) 向 SQLite 表明虚拟表是否希望同时处理 IN 运算符。因此,当第三个参数 (F) 为非负数时,此接口是虚拟表告诉 SQLite 它希望如何处理 IN 运算符的机制。
可以在同一个 xBestIndex 方法调用中多次调用 sqlite3_vtab_in(P,N,F) 接口。对于任何给定的 P,N 对,sqlite3_vtab_in(P,N,F) 的返回值在同一个 xBestIndex 调用中将始终相同。如果接口返回 true(非零),则意味着约束是一个 IN 运算符,可以一次处理所有操作。如果约束不是 IN 运算符或不能一次处理所有,则接口返回 false。
如果同时满足以下两个条件,则选择 IN 运算符的一次性处理:
P->aConstraintUsage[N].argvIndex 值设置为正整数。这就是虚拟表告诉 SQLite 它要使用第 N 个约束的方式。
F 为非负的最后一次调用 sqlite3_vtab_in(P,N,F) 时 F>=1。
如果上述条件之一或两个都为假,则 SQLite 对 IN 约束使用传统的一次一个处理策略。如果两个条件都为真,那么 xFilter 方法的第 argvIndex 参数将是一个sqlite3_value,它看起来是 NULL,但它可以传递给sqlite3_vtab_in_first()和 sqlite3_vtab_in_next()以找到右侧的所有值IN 约束。