SQLite Forum

Usage of indexes and subqueries
Login
This is a problem with [type affinity][1].

[1]: https://www.sqlite.org/datatype3.html#type_affinity

The constant 1 has a type affinity of 'none'.
The subquery '(SELECT rowid FROM ...)' has a type affinity of 'integer'.
The t.dict1 has a type affinity of 'blob'.

You can drive an index that has type affinity 'blob' with a value that
has a type affinity of 'none', but not one that has a type affinity
of 'integer'.  The reason you cannot drive a blob index with an integer
value is that the index (or column t.dict1 in this case) might contain
a string value that looks like a integer:  '1' instead of 1.  But there
is no way to check for that efficiently using the index.

Two possible solutions:

  1.  Specify an INT type on the t.dict column.

  2.  Add a "+" sign before the "rowid" on the subquery, or before the
      subquery itself, to force the expression to use affinity 'none'.

So either:

~~~~~
CREATE TABLE dict(field1);
CREATE TABLE t(field1,dict1 INT REFERENCES dict(rowid),dict2, UNIQUE(dict1,dict2));
                    --------^^^
EXPLAIN QUERY PLAN
UPDATE t SET field1=1 WHERE dict1=(SELECT rowid FROM dict WHERE field1='z') AND dict2=2;
~~~~~

Or this:

~~~~~
CREATE TABLE dict(field1);
CREATE TABLE t(field1,dict1 INT REFERENCES dict(rowid),dict2, UNIQUE(dict1,dict2));
EXPLAIN QUERY PLAN
UPDATE t SET field1=1 WHERE dict1=(SELECT +rowid FROM dict WHERE field1='z') AND dict2=2;
                                      ----^
~~~~~
Or this:

~~~~~
CREATE TABLE dict(field1);
CREATE TABLE t(field1,dict1 INT REFERENCES dict(rowid),dict2, UNIQUE(dict1,dict2));
EXPLAIN QUERY PLAN
UPDATE t SET field1=1 WHERE dict1=+(SELECT rowid FROM dict WHERE field1='z') AND dict2=2;
                              ----^
~~~~~