summaryrefslogtreecommitdiff
path: root/src/test/regress/sql/expressions.sql
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2022-01-29 11:41:12 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2022-01-29 11:41:18 -0500
commit8e2e0f75869e47b3a429b1251b00b3d6d5861028 (patch)
tree7bbe23dc4b4177b9f1bd1244430ea7484d89fb39 /src/test/regress/sql/expressions.sql
parent5ecd0183fb6afa4a07aad71ea0e08c70f64a42a9 (diff)
downloadpostgresql-8e2e0f75869e47b3a429b1251b00b3d6d5861028.tar.gz
Fix failure to validate the result of select_common_type().
Although select_common_type() has a failure-return convention, an apparent successful return just provides a type OID that *might* work as a common supertype; we've not validated that the required casts actually exist. In the mainstream use-cases that doesn't matter, because we'll proceed to invoke coerce_to_common_type() on each input, which will fail appropriately if the proposed common type doesn't actually work. However, a few callers didn't read the (nonexistent) fine print, and thought that if they got back a nonzero OID then the coercions were sure to work. This affects in particular the recently-added "anycompatible" polymorphic types; we might think that a function/operator using such types matches cases it really doesn't. A likely end result of that is unexpected "ambiguous operator" errors, as for example in bug #17387 from James Inform. Another, much older, case is that the parser might try to transform an "x IN (list)" construct to a ScalarArrayOpExpr even when the list elements don't actually have a common supertype. It doesn't seem desirable to add more checking to select_common_type itself, as that'd just slow down the mainstream use-cases. Instead, write a separate function verify_common_type that performs the missing checks, and add a call to that where necessary. Likewise add verify_common_type_from_oids to go with select_common_type_from_oids. Back-patch to v13 where the "anycompatible" types came in. (The symptom complained of in bug #17387 doesn't appear till v14, but that's just because we didn't get around to converting || to use anycompatible till then.) In principle the "x IN (list)" fix could go back all the way, but I'm not currently convinced that it makes much difference in real-world cases, so I won't bother for now. Discussion: https://postgr.es/m/17387-5dfe54b988444963@postgresql.org
Diffstat (limited to 'src/test/regress/sql/expressions.sql')
-rw-r--r--src/test/regress/sql/expressions.sql16
1 files changed, 16 insertions, 0 deletions
diff --git a/src/test/regress/sql/expressions.sql b/src/test/regress/sql/expressions.sql
index 03b88bde7a..755370f358 100644
--- a/src/test/regress/sql/expressions.sql
+++ b/src/test/regress/sql/expressions.sql
@@ -104,6 +104,22 @@ rollback;
--
+-- Ordinarily, IN/NOT IN can be converted to a ScalarArrayOpExpr
+-- with a suitably-chosen array type.
+--
+explain (verbose, costs off)
+select random() IN (1, 4, 8.0);
+explain (verbose, costs off)
+select random()::int IN (1, 4, 8.0);
+-- However, if there's not a common supertype for the IN elements,
+-- we should instead try to produce "x = v1 OR x = v2 OR ...".
+-- In most cases that'll fail for lack of all the requisite = operators,
+-- but it can succeed sometimes. So this should complain about lack of
+-- an = operator, not about cast failure.
+select '(0,0)'::point in ('(0,0,0,0)'::box, point(0,0));
+
+
+--
-- Tests for ScalarArrayOpExpr with a hashfn
--