aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_coerce.c
diff options
context:
space:
mode:
authorPeter Eisentraut <peter@eisentraut.org>2020-10-27 17:39:23 +0100
committerPeter Eisentraut <peter@eisentraut.org>2020-10-27 18:10:42 +0100
commitf893e68d761adbee7f888109b1adf76151e3e17a (patch)
treefd4da3319cf385c87f23786edc24283fa25589cc /src/backend/parser/parse_coerce.c
parent59ab4ac32460a6a93b665f4e487d7ff64979ba4d (diff)
downloadpostgresql-f893e68d761adbee7f888109b1adf76151e3e17a.tar.gz
postgresql-f893e68d761adbee7f888109b1adf76151e3e17a.zip
Add select_common_typmod()
This accompanies select_common_type() and select_common_collation(). Typmods were previously combined using hand-coded logic in several places. The logic in select_common_typmod() isn't very exciting, but it makes the code more compact and readable in a few locations, and in the future we can perhaps do more complicated things if desired. As a small enhancement, the type unification of the direct and aggregate arguments of hypothetical-set aggregates now unifies the typmod as well using this new function, instead of just dropping it. Reviewed-by: Heikki Linnakangas <hlinnaka@iki.fi> Discussion: https://www.postgresql.org/message-id/flat/97df3af9-8b5e-fb7f-a029-3eb7e80d7af9@2ndquadrant.com
Diffstat (limited to 'src/backend/parser/parse_coerce.c')
-rw-r--r--src/backend/parser/parse_coerce.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/src/backend/parser/parse_coerce.c b/src/backend/parser/parse_coerce.c
index 2ffe47026b9..a2924e3d1ce 100644
--- a/src/backend/parser/parse_coerce.c
+++ b/src/backend/parser/parse_coerce.c
@@ -1523,6 +1523,43 @@ coerce_to_common_type(ParseState *pstate, Node *node,
}
/*
+ * select_common_typmod()
+ * Determine the common typmod of a list of input expressions.
+ *
+ * common_type is the selected common type of the expressions, typically
+ * computed using select_common_type().
+ */
+int32
+select_common_typmod(ParseState *pstate, List *exprs, Oid common_type)
+{
+ ListCell *lc;
+ bool first = true;
+ int32 result = -1;
+
+ foreach(lc, exprs)
+ {
+ Node *expr = (Node *) lfirst(lc);
+
+ /* Types must match */
+ if (exprType(expr) != common_type)
+ return -1;
+ else if (first)
+ {
+ result = exprTypmod(expr);
+ first = false;
+ }
+ else
+ {
+ /* As soon as we see a non-matching typmod, fall back to -1 */
+ if (result != exprTypmod(expr))
+ return -1;
+ }
+ }
+
+ return result;
+}
+
+/*
* check_generic_type_consistency()
* Are the actual arguments potentially compatible with a
* polymorphic function?