On Saturday, June 01, 2013 9:37 PM > Row type literals constructed with ROW() cause an error when used in an > IN > clause (string literals casted appropriately are allowed). This is > especially problematic since many client libraries use these literals > to > pass values of row-type arguments, hence making it impossible to use > them in > IN-clause queries. > > To wit: > divide=# create type the_row as (mfg text, id text); > CREATE TYPE > divide=# create table the_table (widget the_row); > > > CREATE TABLE > > > divide=# insert into the_table values(row('foo', 'bar')::the_row); > > > INSERT 0 1 > > > divide=# insert into the_table values('(bar,baz)'::the_row); > > > INSERT 0 1 > divide=# select * from the_table; > widget > ----------- > (foo,bar) > (bar,baz) > (2 rows) > > divide=# select * from the_table where widget in > ('(foo,bar)'::the_row); > widget > ----------- > (foo,bar) > (1 row) > > divide=# select * from the_table where widget in > (row('foo','bar')::the_row); > ERROR: arguments of row IN must all be row expressions > LINE 1: select * from the_table where widget in (row('foo','bar')::t...
The similar query for equal ('=') operator works fine. select * from the_table where widget = (row('foo','bar')::the_row); The reason for above is that in function transformAExprOp(..), it uses make_row_comparison_op() to operate on expressions only if both left and right are row expressions, else it will use make_op() to operate on expressions. Refer code below in function transformAExprOp() else if (lexpr && IsA(lexpr, RowExpr) && rexpr && IsA(rexpr, RowExpr)) { .... result = make_row_comparison_op(pstate, a->name, ((RowExpr *) lexpr)->args, ((RowExpr *) rexpr)->args, a->location); } else { .... result = (Node *) make_op(pstate, a->name, lexpr, rexpr, a->location); } However for IN clause, if any one expr (left or right) is RowExpr, then it will try to use make_row_comparison_op, which result in error. Refer below code of function transformAExprIn(): if (haveRowExpr) { if (!IsA(lexpr, RowExpr) || !IsA(rexpr, RowExpr)) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("arguments of row IN must all be row expressions"), parser_errposition(pstate, a->location))); cmp = make_row_comparison_op(pstate, a->name, (List *) copyObject(((RowExpr *) lexpr)->args), ((RowExpr *) rexpr)->args, a->location); } else cmp = (Node *) make_op(pstate, a->name, copyObject(lexpr), rexpr, a->location); Changing the functionality of transformAExprIn() similar to transformAExprOp() will fix this issue, but not sure if there is any other side effect of same. With Regards, Amit Kapila. -- Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-bugs