aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2008-10-05 22:50:55 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2008-10-05 22:50:55 +0000
commit1e4b03847c95287a81d531ab2a249ad07081c767 (patch)
tree8d6bb560129d18e278a3c2d9748ed8e5160fe446 /src/backend/parser
parent08142504743bc79feb233f42ae24246273102813 (diff)
downloadpostgresql-1e4b03847c95287a81d531ab2a249ad07081c767.tar.gz
postgresql-1e4b03847c95287a81d531ab2a249ad07081c767.zip
Improve behavior of WITH RECURSIVE with an untyped literal in the
non-recursive term. Per an example from Dickson S. Guedes.
Diffstat (limited to 'src/backend/parser')
-rw-r--r--src/backend/parser/parse_cte.c26
1 files changed, 21 insertions, 5 deletions
diff --git a/src/backend/parser/parse_cte.c b/src/backend/parser/parse_cte.c
index 64f5e51c28f..29111acb968 100644
--- a/src/backend/parser/parse_cte.c
+++ b/src/backend/parser/parse_cte.c
@@ -8,12 +8,13 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_cte.c,v 2.1 2008/10/04 21:56:54 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_cte.c,v 2.2 2008/10/05 22:50:55 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
+#include "catalog/pg_type.h"
#include "nodes/nodeFuncs.h"
#include "parser/analyze.h"
#include "parser/parse_cte.h"
@@ -339,6 +340,8 @@ analyzeCTETargetList(ParseState *pstate, CommonTableExpr *cte, List *tlist)
foreach(tlistitem, tlist)
{
TargetEntry *te = (TargetEntry *) lfirst(tlistitem);
+ Oid coltype;
+ int32 coltypmod;
if (te->resjunk)
continue;
@@ -351,10 +354,23 @@ analyzeCTETargetList(ParseState *pstate, CommonTableExpr *cte, List *tlist)
attrname = pstrdup(te->resname);
cte->ctecolnames = lappend(cte->ctecolnames, makeString(attrname));
}
- cte->ctecoltypes = lappend_oid(cte->ctecoltypes,
- exprType((Node *) te->expr));
- cte->ctecoltypmods = lappend_int(cte->ctecoltypmods,
- exprTypmod((Node *) te->expr));
+ coltype = exprType((Node *) te->expr);
+ coltypmod = exprTypmod((Node *) te->expr);
+ /*
+ * If the CTE is recursive, force the exposed column type of any
+ * "unknown" column to "text". This corresponds to the fact that
+ * SELECT 'foo' UNION SELECT 'bar' will ultimately produce text.
+ * We might see "unknown" as a result of an untyped literal in
+ * the non-recursive term's select list, and if we don't convert
+ * to text then we'll have a mismatch against the UNION result.
+ */
+ if (cte->cterecursive && coltype == UNKNOWNOID)
+ {
+ coltype = TEXTOID;
+ coltypmod = -1; /* should be -1 already, but be sure */
+ }
+ cte->ctecoltypes = lappend_oid(cte->ctecoltypes, coltype);
+ cte->ctecoltypmods = lappend_int(cte->ctecoltypmods, coltypmod);
}
if (varattno < numaliases)
ereport(ERROR,