diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2001-11-12 20:05:24 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2001-11-12 20:05:24 +0000 |
commit | d4d23852c17ea2f104a79fc0fdc6e02e8370cdc8 (patch) | |
tree | 6fd9f49ac3a5c3ec73212bd41237f4c3576829f8 /src/backend/parser/parse_expr.c | |
parent | e433bf5a5ed2f0a28c4a896658dd2fe40d8b026e (diff) | |
download | postgresql-d4d23852c17ea2f104a79fc0fdc6e02e8370cdc8.tar.gz postgresql-d4d23852c17ea2f104a79fc0fdc6e02e8370cdc8.zip |
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.
Diffstat (limited to 'src/backend/parser/parse_expr.c')
-rw-r--r-- | src/backend/parser/parse_expr.c | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c index 333333b0408..339999c0c63 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; } |