From d4d23852c17ea2f104a79fc0fdc6e02e8370cdc8 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 12 Nov 2001 20:05:24 +0000 Subject: [PATCH] If the alternatives for a CASE construct all have the same typmod, use that typmod not -1 as the typmod of the CASE result. Part of response to bug#513. --- src/backend/parser/parse_expr.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c index 333333b040..339999c0c6 100644 --- a/src/backend/parser/parse_expr.c +++ b/src/backend/parser/parse_expr.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.104 2001/10/25 05:49:39 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.105 2001/11/12 20:05:24 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -806,6 +806,37 @@ exprTypmod(Node *expr) case T_RelabelType: return ((RelabelType *) expr)->resulttypmod; break; + case T_CaseExpr: + { + /* + * If all the alternatives agree on type/typmod, return + * that typmod, else use -1 + */ + CaseExpr *cexpr = (CaseExpr *) expr; + Oid casetype = cexpr->casetype; + int32 typmod; + List *arg; + + if (!cexpr->defresult) + return -1; + if (exprType(cexpr->defresult) != casetype) + return -1; + typmod = exprTypmod(cexpr->defresult); + if (typmod < 0) + return -1; /* no point in trying harder */ + foreach(arg, cexpr->args) + { + CaseWhen *w = (CaseWhen *) lfirst(arg); + + Assert(IsA(w, CaseWhen)); + if (exprType(w->result) != casetype) + return -1; + if (exprTypmod(w->result) != typmod) + return -1; + } + return typmod; + } + break; default: break; }