SQLite Forum

row value misuse
Login
I am not an expert or authority, but here is my understanding of the issue, as far as it goes. If I am wildly off target, someone will hopefully correct me.

- A comma-separated list of expressions in parenthesis usually signifies a row value, or tuple.
- A `VALUES` expression is a special [select statement](https://sqlite.org/syntax/select-stmt.html), and as such produces a *sequence* of rows. Even if that sequence contains precisely one row, it is something different from a row value.
- A row value can contain any of the [datatypes](https://sqlite.org/datatype3.html) allowed by SQLite. Note that a row value is not among these; hence `((1,2,),(3,4))` is illegal.

> The following seems to work in Postgres, but Sqlite is reporting "row value misused":
> 
> ```
> select * from kv
> where (key, val) in (('k1', 1), ('k3', 3));
> ```

That is not so clear-cut. What's on the right side of `WHERE … IN (…)` is not an expression but [a parenthesised list of expressions](https://sqlite.org/syntax/expr.html), so arguably, a list of row values *could* have been legitimate according to these rules. Perhaps it would be useful; but OTOH, the alternative to a list of expressions is a select statement, and `VALUES` is of course a select statement, so that will always work.

> Another thing I have seen done is to join on a list of values, which works well in Postgres, but Sqlite reports a syntax error near "(":
> 
> ```
> select * 
> from kv 
> inner join (values ('k1', 1), ('k3', 3)) as bar("k", "v")
>   on kv.key = bar.k and kv.val = bar.v;
> ```

I am not sure why that does not work in SQLite. The syntax diagrams seem to allow it.