如何为 SQLite FTS 查询转义字符串

How to escape string for SQLite FTS query

我正在尝试使用不受信任的用户输入执行 SQLite FTS 查询。我不想让用户访问查询语法,也就是说他们将无法执行像 foo OR bar AND cats 这样的匹配查询。如果他们尝试使用该字符串进行查询,我想将其解释为更类似于 foo \OR bar \AND cats.

的内容

SQLite 似乎没有为此内置任何内容,所以我可能最终会构建自己的转义函数,但这看起来很危险且容易出错。有更好的方法吗?

好的,我已经进行了进一步调查,并且通过一些强大的魔法,您可以访问 SQLite 的 FTS 使用的实际分词器。 "simple" 分词器获取您的字符串,将其分隔为不在 [A-Za-z0-0] 中的任何字符,并将其余字符小写。如果您执行相同的操作,您将得到一个很好的 "escaped" 适合 FTS 的字符串。

您可以自己编写,但也可以访问 SQLite 的内部版本。有关详细信息,请参阅此问题:

FTS MATCH 语法是它自己的小语言。对于 FTS5,逐字字符串文字是 well defined:

Within an FTS expression a string may be specified in one of two ways:

  • By enclosing it in double quotes ("). Within a string, any embedded double quote characters may be escaped SQL-style - by adding a second double-quote character.

  • (redacted special case)

事实证明,为 FTS 查询正确转义字符串非常简单,可以完全可靠地实现:将 " 替换为 "" 并将结果包含在 " 中结束。

在我的例子中,当我将它放入准备好的语句(例如 SELECT stuff FROM fts_table WHERE fts_table MATCH ? 中时,它会完美地工作。然后我会 .bind(fts_escape(user_input)) 其中 fts_escape 是我上面描述的函数。