xBestIndex 故障(将非文字参数传递给 table 值函数)

xBestIndex malfunction (passing non-literal parameters to table valued function)

我正在尝试实现 table 值函数(作为 SQLite 虚拟 table)。

这是一个函数,它接受一个字符串和 return 一个包含字符串中所有单词的 table。

如果我用如下文字值调用它,它工作正常。

SELECT word FROM splitstring("abc def ghi")

但是,如果我用另一个 table 的列调用它,它就不起作用:

SELECT a.Name, word FROM article a, splitstring(a.Text)

xBestIndex 方法被正确调用,但紧接着,我从 ExecuteReader 方法中得到一个异常。异常消息是 "xBestIndex malfunction"。由于异常,xFilter 方法未被调用。

我的 xBestIndex 实现很简单,它只是标记了参数,所以我可以在 xFilter 中看到它:

public override SQLiteErrorCode BestIndex(SQLiteVirtualTable table, SQLiteIndex index)
{
    index.Outputs.ConstraintUsages.ElementAt(0).argvIndex = 1;
    index.Outputs.ConstraintUsages.ElementAt(0).omit = 1;

    return SQLiteErrorCode.Ok;
}

我是不是做错了什么,或者无法将非文字参数传递给 table 值函数?

找到问题了!我正在使用具有 usable=0 的约束。 BestIndex 方法被 SQLite 多次调用,第二次带有不可用的约束。

这是 BestIndex 方法的固定主体。

public override SQLiteErrorCode BestIndex(SQLiteVirtualTable table, SQLiteIndex index)
{
    if (index.Inputs.Constraints.Count() != 2)
        throw new ArgumentException("The generate_series function requires two integer (long) parameters!");

    if (index.Inputs.Constraints.All(c=>c.usable == 1))
    {
        index.Outputs.ConstraintUsages.ElementAt(0).argvIndex = 1;
        index.Outputs.ConstraintUsages.ElementAt(0).omit = 1;
        index.Outputs.ConstraintUsages.ElementAt(1).argvIndex = 2;
        index.Outputs.ConstraintUsages.ElementAt(1).omit = 1;
    }
    else
    {
        index.Outputs.IndexNumber = -1;
        index.Outputs.EstimatedCost = double.MaxValue;
    }

    return SQLiteErrorCode.Ok;
}

现在我检查可用标志。当使用 usable=0 的约束调用 BestIndex 时,我会跳过它,即 return 该索引的估计成本很高,因此它不会被使用。