Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 5935890

Browse files
committed
A long time ago, Peter pointed out that ruleutils.c didn't dump simple
constant ORDER/GROUP BY entries properly: http://archives.postgresql.org/pgsql-hackers/2001-04/msg00457.php The original solution to that was in fact no good, as demonstrated by today's report from Martin Pitt: http://archives.postgresql.org/pgsql-bugs/2008-01/msg00027.php We can't use the column-number-reference format for a constant that is a resjunk targetlist entry, a case that was unfortunately not thought of in the original discussion. What we can do instead (which did not work at the time, but does work in 7.3 and up) is to emit the constant with explicit ::typename decoration, even if it otherwise wouldn't need it. This is sufficient to keep the parser from thinking it's a column number reference, and indeed is probably what the user must have done to get such a thing into the querytree in the first place.
1 parent 99749f3 commit 5935890

File tree

1 file changed

+25
-18
lines changed

1 file changed

+25
-18
lines changed

src/backend/utils/adt/ruleutils.c

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.268 2008/01/01 19:45:52 momjian Exp $
12+
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.269 2008/01/06 01:03:16 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -175,7 +175,7 @@ static void get_coercion_expr(Node *arg, deparse_context *context,
175175
Oid resulttype, int32 resulttypmod,
176176
Node *parentNode);
177177
static void get_const_expr(Const *constval, deparse_context *context,
178-
bool showtype);
178+
int showtype);
179179
static void get_sublink_expr(SubLink *sublink, deparse_context *context);
180180
static void get_from_clause(Query *query, const char *prefix,
181181
deparse_context *context);
@@ -2258,15 +2258,20 @@ get_rule_sortgroupclause(SortClause *srt, List *tlist, bool force_colno,
22582258
expr = (Node *) tle->expr;
22592259

22602260
/*
2261-
* Use column-number form if requested by caller or if expression is a
2262-
* constant --- a constant is ambiguous (and will be misinterpreted by
2263-
* findTargetlistEntry()) if we dump it explicitly.
2261+
* Use column-number form if requested by caller. Otherwise, if
2262+
* expression is a constant, force it to be dumped with an explicit
2263+
* cast as decoration --- this is because a simple integer constant
2264+
* is ambiguous (and will be misinterpreted by findTargetlistEntry())
2265+
* if we dump it without any decoration. Otherwise, just dump the
2266+
* expression normally.
22642267
*/
2265-
if (force_colno || (expr && IsA(expr, Const)))
2268+
if (force_colno)
22662269
{
22672270
Assert(!tle->resjunk);
22682271
appendStringInfo(buf, "%d", tle->resno);
22692272
}
2273+
else if (expr && IsA(expr, Const))
2274+
get_const_expr((Const *) expr, context, 1);
22702275
else
22712276
get_rule_expr(expr, context, true);
22722277

@@ -3409,7 +3414,7 @@ get_rule_expr(Node *node, deparse_context *context,
34093414
break;
34103415

34113416
case T_Const:
3412-
get_const_expr((Const *) node, context, true);
3417+
get_const_expr((Const *) node, context, 0);
34133418
break;
34143419

34153420
case T_Param:
@@ -4388,7 +4393,7 @@ get_coercion_expr(Node *arg, deparse_context *context,
43884393
((Const *) arg)->consttypmod == -1)
43894394
{
43904395
/* Show the constant without normal ::typename decoration */
4391-
get_const_expr((Const *) arg, context, false);
4396+
get_const_expr((Const *) arg, context, -1);
43924397
}
43934398
else
43944399
{
@@ -4407,13 +4412,13 @@ get_coercion_expr(Node *arg, deparse_context *context,
44074412
*
44084413
* Make a string representation of a Const
44094414
*
4410-
* Note: if showtype is false, the Const is the direct argument of a coercion
4411-
* operation with the same target type, and so we should suppress "::typename"
4412-
* to avoid redundant output.
4415+
* showtype can be -1 to never show "::typename" decoration, or +1 to always
4416+
* show it, or 0 to show it only if the constant wouldn't be assumed to be
4417+
* the right type by default.
44134418
* ----------
44144419
*/
44154420
static void
4416-
get_const_expr(Const *constval, deparse_context *context, bool showtype)
4421+
get_const_expr(Const *constval, deparse_context *context, int showtype)
44174422
{
44184423
StringInfo buf = context->buf;
44194424
Oid typoutput;
@@ -4430,7 +4435,7 @@ get_const_expr(Const *constval, deparse_context *context, bool showtype)
44304435
* about type when reparsing.
44314436
*/
44324437
appendStringInfo(buf, "NULL");
4433-
if (showtype)
4438+
if (showtype >= 0)
44344439
appendStringInfo(buf, "::%s",
44354440
format_type_with_typemod(constval->consttype,
44364441
constval->consttypmod));
@@ -4506,13 +4511,15 @@ get_const_expr(Const *constval, deparse_context *context, bool showtype)
45064511

45074512
pfree(extval);
45084513

4509-
if (!showtype)
4514+
if (showtype < 0)
45104515
return;
45114516

45124517
/*
4513-
* Append ::typename unless the constant will be implicitly typed as the
4514-
* right type when it is read in. XXX this code has to be kept in sync
4515-
* with the behavior of the parser, especially make_const.
4518+
* For showtype == 0, append ::typename unless the constant will be
4519+
* implicitly typed as the right type when it is read in.
4520+
*
4521+
* XXX this code has to be kept in sync with the behavior of the parser,
4522+
* especially make_const.
45164523
*/
45174524
switch (constval->consttype)
45184525
{
@@ -4534,7 +4541,7 @@ get_const_expr(Const *constval, deparse_context *context, bool showtype)
45344541
needlabel = true;
45354542
break;
45364543
}
4537-
if (needlabel)
4544+
if (needlabel || showtype > 0)
45384545
appendStringInfo(buf, "::%s",
45394546
format_type_with_typemod(constval->consttype,
45404547
constval->consttypmod));

0 commit comments

Comments
 (0)