@@ -319,86 +319,6 @@ assign_collations_walker(Node *node, assign_collations_context *context)
319
319
}
320
320
}
321
321
break ;
322
- case T_CaseExpr :
323
- {
324
- /*
325
- * CaseExpr is a special case because we do not want to
326
- * recurse into the test expression (if any). It was already
327
- * marked with collations during transformCaseExpr, and
328
- * furthermore its collation is not relevant to the result of
329
- * the CASE --- only the output expressions are. So we can't
330
- * use expression_tree_walker here.
331
- */
332
- CaseExpr * expr = (CaseExpr * ) node ;
333
- Oid typcollation ;
334
- ListCell * lc ;
335
-
336
- foreach (lc , expr -> args )
337
- {
338
- CaseWhen * when = (CaseWhen * ) lfirst (lc );
339
-
340
- Assert (IsA (when , CaseWhen ));
341
-
342
- /*
343
- * The condition expressions mustn't affect the CASE's
344
- * result collation either; but since they are known to
345
- * yield boolean, it's safe to recurse directly on them
346
- * --- they won't change loccontext.
347
- */
348
- (void ) assign_collations_walker ((Node * ) when -> expr ,
349
- & loccontext );
350
- (void ) assign_collations_walker ((Node * ) when -> result ,
351
- & loccontext );
352
- }
353
- (void ) assign_collations_walker ((Node * ) expr -> defresult ,
354
- & loccontext );
355
-
356
- /*
357
- * Now determine the CASE's output collation. This is the
358
- * same as the general case below.
359
- */
360
- typcollation = get_typcollation (exprType (node ));
361
- if (OidIsValid (typcollation ))
362
- {
363
- /* Node's result is collatable; what about its input? */
364
- if (loccontext .strength > COLLATE_NONE )
365
- {
366
- /* Collation state bubbles up from children. */
367
- collation = loccontext .collation ;
368
- strength = loccontext .strength ;
369
- location = loccontext .location ;
370
- }
371
- else
372
- {
373
- /*
374
- * Collatable output produced without any collatable
375
- * input. Use the type's collation (which is usually
376
- * DEFAULT_COLLATION_OID, but might be different for a
377
- * domain).
378
- */
379
- collation = typcollation ;
380
- strength = COLLATE_IMPLICIT ;
381
- location = exprLocation (node );
382
- }
383
- }
384
- else
385
- {
386
- /* Node's result type isn't collatable. */
387
- collation = InvalidOid ;
388
- strength = COLLATE_NONE ;
389
- location = -1 ; /* won't be used */
390
- }
391
-
392
- /*
393
- * Save the state into the expression node. We know it
394
- * doesn't care about input collation.
395
- */
396
- if (strength == COLLATE_CONFLICT )
397
- exprSetCollation (node , InvalidOid );
398
- else
399
- exprSetCollation (node , collation );
400
- }
401
- break ;
402
322
case T_RowExpr :
403
323
{
404
324
/*
@@ -630,14 +550,103 @@ assign_collations_walker(Node *node, assign_collations_context *context)
630
550
{
631
551
/*
632
552
* General case for most expression nodes with children. First
633
- * recurse, then figure out what to assign here .
553
+ * recurse, then figure out what to assign to this node .
634
554
*/
635
555
Oid typcollation ;
636
556
637
- (void ) expression_tree_walker (node ,
638
- assign_collations_walker ,
639
- (void * ) & loccontext );
557
+ /*
558
+ * For most node types, we want to treat all the child
559
+ * expressions alike; but there are a few exceptions, hence
560
+ * this inner switch.
561
+ */
562
+ switch (nodeTag (node ))
563
+ {
564
+ case T_Aggref :
565
+ {
566
+ /*
567
+ * Aggref is a special case because expressions
568
+ * used only for ordering shouldn't be taken to
569
+ * conflict with each other or with regular args.
570
+ * So we apply assign_expr_collations() to them
571
+ * rather than passing down our loccontext.
572
+ *
573
+ * Note that we recurse to each TargetEntry, not
574
+ * directly to its contained expression, so that
575
+ * the case above for T_TargetEntry will apply
576
+ * appropriate checks to agg ORDER BY items.
577
+ *
578
+ * We need not recurse into the aggorder or
579
+ * aggdistinct lists, because those contain only
580
+ * SortGroupClause nodes which we need not
581
+ * process.
582
+ */
583
+ Aggref * aggref = (Aggref * ) node ;
584
+ ListCell * lc ;
585
+
586
+ foreach (lc , aggref -> args )
587
+ {
588
+ TargetEntry * tle = (TargetEntry * ) lfirst (lc );
589
+
590
+ Assert (IsA (tle , TargetEntry ));
591
+ if (tle -> resjunk )
592
+ assign_expr_collations (context -> pstate ,
593
+ (Node * ) tle );
594
+ else
595
+ (void ) assign_collations_walker ((Node * ) tle ,
596
+ & loccontext );
597
+ }
598
+ }
599
+ break ;
600
+ case T_CaseExpr :
601
+ {
602
+ /*
603
+ * CaseExpr is a special case because we do not
604
+ * want to recurse into the test expression (if
605
+ * any). It was already marked with collations
606
+ * during transformCaseExpr, and furthermore its
607
+ * collation is not relevant to the result of the
608
+ * CASE --- only the output expressions are.
609
+ */
610
+ CaseExpr * expr = (CaseExpr * ) node ;
611
+ ListCell * lc ;
612
+
613
+ foreach (lc , expr -> args )
614
+ {
615
+ CaseWhen * when = (CaseWhen * ) lfirst (lc );
616
+
617
+ Assert (IsA (when , CaseWhen ));
618
+
619
+ /*
620
+ * The condition expressions mustn't affect
621
+ * the CASE's result collation either; but
622
+ * since they are known to yield boolean, it's
623
+ * safe to recurse directly on them --- they
624
+ * won't change loccontext.
625
+ */
626
+ (void ) assign_collations_walker ((Node * ) when -> expr ,
627
+ & loccontext );
628
+ (void ) assign_collations_walker ((Node * ) when -> result ,
629
+ & loccontext );
630
+ }
631
+ (void ) assign_collations_walker ((Node * ) expr -> defresult ,
632
+ & loccontext );
633
+ }
634
+ break ;
635
+ default :
636
+
637
+ /*
638
+ * Normal case: all child expressions contribute
639
+ * equally to loccontext.
640
+ */
641
+ (void ) expression_tree_walker (node ,
642
+ assign_collations_walker ,
643
+ (void * ) & loccontext );
644
+ break ;
645
+ }
640
646
647
+ /*
648
+ * Now figure out what collation to assign to this node.
649
+ */
641
650
typcollation = get_typcollation (exprType (node ));
642
651
if (OidIsValid (typcollation ))
643
652
{
0 commit comments