PostgreSQL Source Code git master
Loading...
Searching...
No Matches
parse_collate.c File Reference
Include dependency graph for parse_collate.c:

Go to the source code of this file.

Data Structures

struct  assign_collations_context
 

Enumerations

enum  CollateStrength { COLLATE_NONE , COLLATE_IMPLICIT , COLLATE_CONFLICT , COLLATE_EXPLICIT }
 

Functions

static bool assign_query_collations_walker (Node *node, ParseState *pstate)
 
static bool assign_collations_walker (Node *node, assign_collations_context *context)
 
static void merge_collation_state (Oid collation, CollateStrength strength, int location, Oid collation2, int location2, assign_collations_context *context)
 
static void assign_aggregate_collations (Aggref *aggref, assign_collations_context *loccontext)
 
static void assign_ordered_set_collations (Aggref *aggref, assign_collations_context *loccontext)
 
static void assign_hypothetical_collations (Aggref *aggref, assign_collations_context *loccontext)
 
void assign_query_collations (ParseState *pstate, Query *query)
 
void assign_list_collations (ParseState *pstate, List *exprs)
 
void assign_expr_collations (ParseState *pstate, Node *expr)
 
Oid select_common_collation (ParseState *pstate, List *exprs, bool none_ok)
 

Enumeration Type Documentation

◆ CollateStrength

Enumerator
COLLATE_NONE 
COLLATE_IMPLICIT 
COLLATE_CONFLICT 
COLLATE_EXPLICIT 

Definition at line 56 of file parse_collate.c.

57{
58 COLLATE_NONE, /* expression is of a noncollatable datatype */
59 COLLATE_IMPLICIT, /* collation was derived implicitly */
60 COLLATE_CONFLICT, /* we had a conflict of implicit collations */
61 COLLATE_EXPLICIT, /* collation was derived explicitly */
CollateStrength
@ COLLATE_IMPLICIT
@ COLLATE_NONE
@ COLLATE_CONFLICT
@ COLLATE_EXPLICIT

Function Documentation

◆ assign_aggregate_collations()

static void assign_aggregate_collations ( Aggref aggref,
assign_collations_context loccontext 
)
static

Definition at line 882 of file parse_collate.c.

884{
885 ListCell *lc;
886
887 /* Plain aggregates have no direct args */
888 Assert(aggref->aggdirectargs == NIL);
889
890 /* Process aggregated args, holding resjunk ones at arm's length */
891 foreach(lc, aggref->args)
892 {
894
895 if (tle->resjunk)
897 else
899 }
900}
#define Assert(condition)
Definition c.h:945
static bool assign_collations_walker(Node *node, assign_collations_context *context)
void assign_expr_collations(ParseState *pstate, Node *expr)
#define lfirst_node(type, lc)
Definition pg_list.h:176
#define NIL
Definition pg_list.h:68
static int fb(int x)
List * aggdirectargs
Definition primnodes.h:485
List * args
Definition primnodes.h:488
Definition nodes.h:135

References Aggref::aggdirectargs, Aggref::args, Assert, assign_collations_walker(), assign_expr_collations(), fb(), lfirst_node, and NIL.

Referenced by assign_collations_walker().

◆ assign_collations_walker()

static bool assign_collations_walker ( Node node,
assign_collations_context context 
)
static

Definition at line 255 of file parse_collate.c.

256{
258 Oid collation;
259 CollateStrength strength;
260 int location;
261
262 /* Need do nothing for empty subexpressions */
263 if (node == NULL)
264 return false;
265
266 /*
267 * Prepare for recursion. For most node types, though not all, the first
268 * thing we do is recurse to process all nodes below this one. Each level
269 * of the tree has its own local context.
270 */
271 loccontext.pstate = context->pstate;
272 loccontext.collation = InvalidOid;
273 loccontext.strength = COLLATE_NONE;
274 loccontext.location = -1;
275 /* Set these fields just to suppress uninitialized-value warnings: */
276 loccontext.collation2 = InvalidOid;
277 loccontext.location2 = -1;
278
279 /*
280 * Recurse if appropriate, then determine the collation for this node.
281 *
282 * Note: the general cases are at the bottom of the switch, after various
283 * special cases.
284 */
285 switch (nodeTag(node))
286 {
287 case T_CollateExpr:
288 {
289 /*
290 * COLLATE sets an explicitly derived collation, regardless of
291 * what the child state is. But we must recurse to set up
292 * collation info below here.
293 */
294 CollateExpr *expr = (CollateExpr *) node;
295
298 &loccontext);
299
300 collation = expr->collOid;
301 Assert(OidIsValid(collation));
302 strength = COLLATE_EXPLICIT;
303 location = expr->location;
304 }
305 break;
306 case T_FieldSelect:
307 {
308 /*
309 * For FieldSelect, the result has the field's declared
310 * collation, independently of what happened in the arguments.
311 * (The immediate argument must be composite and thus not
312 * collatable, anyhow.) The field's collation was already
313 * looked up and saved in the node.
314 */
315 FieldSelect *expr = (FieldSelect *) node;
316
317 /* ... but first, recurse */
320 &loccontext);
321
322 if (OidIsValid(expr->resultcollid))
323 {
324 /* Node's result type is collatable. */
325 /* Pass up field's collation as an implicit choice. */
326 collation = expr->resultcollid;
327 strength = COLLATE_IMPLICIT;
328 location = exprLocation(node);
329 }
330 else
331 {
332 /* Node's result type isn't collatable. */
333 collation = InvalidOid;
334 strength = COLLATE_NONE;
335 location = -1; /* won't be used */
336 }
337 }
338 break;
339 case T_RowExpr:
340 {
341 /*
342 * RowExpr is a special case because the subexpressions are
343 * independent: we don't want to complain if some of them have
344 * incompatible explicit collations.
345 */
346 RowExpr *expr = (RowExpr *) node;
347
348 assign_list_collations(context->pstate, expr->args);
349
350 /*
351 * Since the result is always composite and therefore never
352 * has a collation, we can just stop here: this node has no
353 * impact on the collation of its parent.
354 */
355 return false; /* done */
356 }
357 case T_RowCompareExpr:
358 {
359 /*
360 * For RowCompare, we have to find the common collation of
361 * each pair of input columns and build a list. If we can't
362 * find a common collation, we just put InvalidOid into the
363 * list, which may or may not cause an error at runtime.
364 */
365 RowCompareExpr *expr = (RowCompareExpr *) node;
366 List *colls = NIL;
367 ListCell *l;
368 ListCell *r;
369
370 forboth(l, expr->largs, r, expr->rargs)
371 {
372 Node *le = (Node *) lfirst(l);
373 Node *re = (Node *) lfirst(r);
374 Oid coll;
375
377 list_make2(le, re),
378 true);
380 }
381 expr->inputcollids = colls;
382
383 /*
384 * Since the result is always boolean and therefore never has
385 * a collation, we can just stop here: this node has no impact
386 * on the collation of its parent.
387 */
388 return false; /* done */
389 }
390 case T_CoerceToDomain:
391 {
392 /*
393 * If the domain declaration included a non-default COLLATE
394 * spec, then use that collation as the output collation of
395 * the coercion. Otherwise allow the input collation to
396 * bubble up. (The input should be of the domain's base type,
397 * therefore we don't need to worry about it not being
398 * collatable when the domain is.)
399 */
400 CoerceToDomain *expr = (CoerceToDomain *) node;
401 Oid typcollation = get_typcollation(expr->resulttype);
402
403 /* ... but first, recurse */
406 &loccontext);
407
408 if (OidIsValid(typcollation))
409 {
410 /* Node's result type is collatable. */
411 if (typcollation == DEFAULT_COLLATION_OID)
412 {
413 /* Collation state bubbles up from child. */
414 collation = loccontext.collation;
415 strength = loccontext.strength;
416 location = loccontext.location;
417 }
418 else
419 {
420 /* Use domain's collation as an implicit choice. */
421 collation = typcollation;
422 strength = COLLATE_IMPLICIT;
423 location = exprLocation(node);
424 }
425 }
426 else
427 {
428 /* Node's result type isn't collatable. */
429 collation = InvalidOid;
430 strength = COLLATE_NONE;
431 location = -1; /* won't be used */
432 }
433
434 /*
435 * Save the state into the expression node. We know it
436 * doesn't care about input collation.
437 */
438 if (strength == COLLATE_CONFLICT)
440 else
441 exprSetCollation(node, collation);
442 }
443 break;
444 case T_TargetEntry:
447 &loccontext);
448
449 /*
450 * TargetEntry can have only one child, and should bubble that
451 * state up to its parent. We can't use the general-case code
452 * below because exprType and friends don't work on TargetEntry.
453 */
454 collation = loccontext.collation;
455 strength = loccontext.strength;
456 location = loccontext.location;
457
458 /*
459 * Throw error if the collation is indeterminate for a TargetEntry
460 * that is a sort/group target. We prefer to do this now, instead
461 * of leaving the comparison functions to fail at runtime, because
462 * we can give a syntax error pointer to help locate the problem.
463 * There are some cases where there might not be a failure, for
464 * example if the planner chooses to use hash aggregation instead
465 * of sorting for grouping; but it seems better to predictably
466 * throw an error. (Compare transformSetOperationTree, which will
467 * throw error for indeterminate collation of set-op columns, even
468 * though the planner might be able to implement the set-op
469 * without sorting.)
470 */
471 if (strength == COLLATE_CONFLICT &&
472 ((TargetEntry *) node)->ressortgroupref != 0)
475 errmsg("collation mismatch between implicit collations \"%s\" and \"%s\"",
477 get_collation_name(loccontext.collation2)),
478 errhint("You can choose the collation by applying the COLLATE clause to one or both expressions."),
479 parser_errposition(context->pstate,
480 loccontext.location2)));
481 break;
482 case T_InferenceElem:
483 case T_RangeTblRef:
484 case T_JoinExpr:
485 case T_FromExpr:
486 case T_OnConflictExpr:
488 case T_MergeAction:
491 &loccontext);
492
493 /*
494 * When we're invoked on a query's jointree, we don't need to do
495 * anything with join nodes except recurse through them to process
496 * WHERE/ON expressions. So just stop here. Likewise, we don't
497 * need to do anything when invoked on sort/group lists.
498 */
499 return false;
500 case T_Query:
501 {
502 /*
503 * We get here when we're invoked on the Query belonging to a
504 * SubLink. Act as though the Query returns its first output
505 * column, which indeed is what it does for EXPR_SUBLINK and
506 * ARRAY_SUBLINK cases. In the cases where the SubLink
507 * returns boolean, this info will be ignored. Special case:
508 * in EXISTS, the Query might return no columns, in which case
509 * we need do nothing.
510 *
511 * We needn't recurse, since the Query is already processed.
512 */
513 Query *qtree = (Query *) node;
515
516 if (qtree->targetList == NIL)
517 return false;
518 tent = linitial_node(TargetEntry, qtree->targetList);
519 if (tent->resjunk)
520 return false;
521
522 collation = exprCollation((Node *) tent->expr);
523 /* collation doesn't change if it's converted to array */
524 strength = COLLATE_IMPLICIT;
525 location = exprLocation((Node *) tent->expr);
526 }
527 break;
528 case T_List:
531 &loccontext);
532
533 /*
534 * When processing a list, collation state just bubbles up from
535 * the list elements.
536 */
537 collation = loccontext.collation;
538 strength = loccontext.strength;
539 location = loccontext.location;
540 break;
541
542 case T_Var:
543 case T_Const:
544 case T_Param:
546 case T_CaseTestExpr:
547 case T_SetToDefault:
548 case T_CurrentOfExpr:
550
551 /*
552 * General case for childless expression nodes. These should
553 * already have a collation assigned; it is not this function's
554 * responsibility to look into the catalogs for base-case
555 * information.
556 */
557 collation = exprCollation(node);
558
559 /*
560 * Note: in most cases, there will be an assigned collation
561 * whenever type_is_collatable(exprType(node)); but an exception
562 * occurs for a Var referencing a subquery output column for which
563 * a unique collation was not determinable. That may lead to a
564 * runtime failure if a collation-sensitive function is applied to
565 * the Var.
566 */
567
568 if (OidIsValid(collation))
569 strength = COLLATE_IMPLICIT;
570 else
571 strength = COLLATE_NONE;
572 location = exprLocation(node);
573 break;
574
575 default:
576 {
577 /*
578 * General case for most expression nodes with children. First
579 * recurse, then figure out what to assign to this node.
580 */
581 Oid typcollation;
582
583 /*
584 * For most node types, we want to treat all the child
585 * expressions alike; but there are a few exceptions, hence
586 * this inner switch.
587 */
588 switch (nodeTag(node))
589 {
590 case T_Aggref:
591 {
592 /*
593 * Aggref is messy enough that we give it its own
594 * function, in fact three of them. The FILTER
595 * clause is independent of the rest of the
596 * aggregate, however, so it can be processed
597 * separately.
598 */
599 Aggref *aggref = (Aggref *) node;
600
601 switch (aggref->aggkind)
602 {
603 case AGGKIND_NORMAL:
605 &loccontext);
606 break;
609 &loccontext);
610 break;
613 &loccontext);
614 break;
615 default:
616 elog(ERROR, "unrecognized aggkind: %d",
617 (int) aggref->aggkind);
618 }
619
621 (Node *) aggref->aggfilter);
622 }
623 break;
624 case T_WindowFunc:
625 {
626 /*
627 * WindowFunc requires special processing only for
628 * its aggfilter clause, as for aggregates.
629 */
630 WindowFunc *wfunc = (WindowFunc *) node;
631
633 &loccontext);
634
636 (Node *) wfunc->aggfilter);
637 }
638 break;
639 case T_CaseExpr:
640 {
641 /*
642 * CaseExpr is a special case because we do not
643 * want to recurse into the test expression (if
644 * any). It was already marked with collations
645 * during transformCaseExpr, and furthermore its
646 * collation is not relevant to the result of the
647 * CASE --- only the output expressions are.
648 */
649 CaseExpr *expr = (CaseExpr *) node;
650 ListCell *lc;
651
652 foreach(lc, expr->args)
653 {
655
656 /*
657 * The condition expressions mustn't affect
658 * the CASE's result collation either; but
659 * since they are known to yield boolean, it's
660 * safe to recurse directly on them --- they
661 * won't change loccontext.
662 */
664 &loccontext);
666 &loccontext);
667 }
669 &loccontext);
670 }
671 break;
673 {
674 /*
675 * The subscripts are treated as independent
676 * expressions not contributing to the node's
677 * collation. Only the container, and the source
678 * expression if any, contribute. (This models
679 * the old behavior, in which the subscripts could
680 * be counted on to be integers and thus not
681 * contribute anything.)
682 */
683 SubscriptingRef *sbsref = (SubscriptingRef *) node;
684
686 (Node *) sbsref->refupperindexpr);
688 (Node *) sbsref->reflowerindexpr);
690 &loccontext);
692 &loccontext);
693 }
694 break;
695 default:
696
697 /*
698 * Normal case: all child expressions contribute
699 * equally to loccontext.
700 */
703 &loccontext);
704 break;
705 }
706
707 /*
708 * Now figure out what collation to assign to this node.
709 */
710 typcollation = get_typcollation(exprType(node));
711 if (OidIsValid(typcollation))
712 {
713 /* Node's result is collatable; what about its input? */
714 if (loccontext.strength > COLLATE_NONE)
715 {
716 /* Collation state bubbles up from children. */
717 collation = loccontext.collation;
718 strength = loccontext.strength;
719 location = loccontext.location;
720 }
721 else
722 {
723 /*
724 * Collatable output produced without any collatable
725 * input. Use the type's collation (which is usually
726 * DEFAULT_COLLATION_OID, but might be different for a
727 * domain).
728 */
729 collation = typcollation;
730 strength = COLLATE_IMPLICIT;
731 location = exprLocation(node);
732 }
733 }
734 else
735 {
736 /* Node's result type isn't collatable. */
737 collation = InvalidOid;
738 strength = COLLATE_NONE;
739 location = -1; /* won't be used */
740 }
741
742 /*
743 * Save the result collation into the expression node. If the
744 * state is COLLATE_CONFLICT, we'll set the collation to
745 * InvalidOid, which might result in an error at runtime.
746 */
747 if (strength == COLLATE_CONFLICT)
749 else
750 exprSetCollation(node, collation);
751
752 /*
753 * Likewise save the input collation, which is the one that
754 * any function called by this node should use.
755 */
756 if (loccontext.strength == COLLATE_CONFLICT)
758 else
759 exprSetInputCollation(node, loccontext.collation);
760 }
761 break;
762 }
763
764 /*
765 * Now, merge my information into my parent's state.
766 */
767 merge_collation_state(collation,
768 strength,
769 location,
770 loccontext.collation2,
771 loccontext.location2,
772 context);
773
774 return false;
775}
#define OidIsValid(objectId)
Definition c.h:860
int errcode(int sqlerrcode)
Definition elog.c:874
int errhint(const char *fmt,...) pg_attribute_printf(1
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
#define ereport(elevel,...)
Definition elog.h:150
List * lappend_oid(List *list, Oid datum)
Definition list.c:375
Oid get_typcollation(Oid typid)
Definition lsyscache.c:3278
char * get_collation_name(Oid colloid)
Definition lsyscache.c:1181
Oid exprType(const Node *expr)
Definition nodeFuncs.c:42
void exprSetCollation(Node *expr, Oid collation)
Definition nodeFuncs.c:1132
Oid exprCollation(const Node *expr)
Definition nodeFuncs.c:826
void exprSetInputCollation(Node *expr, Oid inputcollation)
Definition nodeFuncs.c:1328
int exprLocation(const Node *expr)
Definition nodeFuncs.c:1392
#define expression_tree_walker(n, w, c)
Definition nodeFuncs.h:153
#define nodeTag(nodeptr)
Definition nodes.h:139
static char * errmsg
void assign_list_collations(ParseState *pstate, List *exprs)
Oid select_common_collation(ParseState *pstate, List *exprs, bool none_ok)
static void assign_aggregate_collations(Aggref *aggref, assign_collations_context *loccontext)
static void merge_collation_state(Oid collation, CollateStrength strength, int location, Oid collation2, int location2, assign_collations_context *context)
static void assign_ordered_set_collations(Aggref *aggref, assign_collations_context *loccontext)
static void assign_hypothetical_collations(Aggref *aggref, assign_collations_context *loccontext)
int parser_errposition(ParseState *pstate, int location)
Definition parse_node.c:106
#define lfirst(lc)
Definition pg_list.h:172
#define linitial_node(type, l)
Definition pg_list.h:181
#define forboth(cell1, list1, cell2, list2)
Definition pg_list.h:518
#define list_make2(x1, x2)
Definition pg_list.h:214
#define InvalidOid
unsigned int Oid
Expr * aggfilter
Definition primnodes.h:497
Expr * defresult
Definition primnodes.h:1349
List * args
Definition primnodes.h:1348
ParseLoc location
Definition primnodes.h:1315
Definition pg_list.h:54
List * args
Definition primnodes.h:1449
Expr * refassgnexpr
Definition primnodes.h:736
List * refupperindexpr
Definition primnodes.h:726
List * reflowerindexpr
Definition primnodes.h:732
List * args
Definition primnodes.h:606
Expr * aggfilter
Definition primnodes.h:608
Definition type.h:89

References Aggref::aggfilter, WindowFunc::aggfilter, WindowFunc::args, CaseExpr::args, RowExpr::args, Assert, assign_aggregate_collations(), assign_collations_walker(), assign_expr_collations(), assign_hypothetical_collations(), assign_list_collations(), assign_ordered_set_collations(), COLLATE_CONFLICT, COLLATE_EXPLICIT, COLLATE_IMPLICIT, COLLATE_NONE, CollateExpr::collOid, CaseExpr::defresult, elog, ereport, errcode(), errhint(), errmsg, ERROR, exprCollation(), expression_tree_walker, exprLocation(), exprSetCollation(), exprSetInputCollation(), exprType(), fb(), forboth, get_collation_name(), get_typcollation(), InvalidOid, lappend_oid(), RowCompareExpr::largs, lfirst, lfirst_node, linitial_node, list_make2, CollateExpr::location, merge_collation_state(), NIL, nodeTag, OidIsValid, parser_errposition(), assign_collations_context::pstate, RowCompareExpr::rargs, SubscriptingRef::refassgnexpr, SubscriptingRef::refexpr, SubscriptingRef::reflowerindexpr, SubscriptingRef::refupperindexpr, CoerceToDomain::resulttype, and select_common_collation().

Referenced by assign_aggregate_collations(), assign_collations_walker(), assign_expr_collations(), assign_hypothetical_collations(), assign_ordered_set_collations(), and select_common_collation().

◆ assign_expr_collations()

void assign_expr_collations ( ParseState pstate,
Node expr 
)

Definition at line 177 of file parse_collate.c.

178{
180
181 /* initialize context for tree walk */
182 context.pstate = pstate;
183 context.collation = InvalidOid;
184 context.strength = COLLATE_NONE;
185 context.location = -1;
186
187 /* and away we go */
188 (void) assign_collations_walker(expr, &context);
189}

References assign_collations_walker(), COLLATE_NONE, assign_collations_context::collation, fb(), InvalidOid, assign_collations_context::location, assign_collations_context::pstate, and assign_collations_context::strength.

Referenced by AlterPolicy(), assign_aggregate_collations(), assign_collations_walker(), assign_list_collations(), assign_ordered_set_collations(), assign_query_collations_walker(), ATPrepAlterColumnType(), build_edge_vertex_link_quals(), buildMergedJoinVar(), coerce_fn_result_column(), cookConstraint(), cookDefault(), CreatePolicy(), CreateTriggerFiringOn(), DoCopy(), domainAddCheckConstraint(), EvaluateParams(), insert_property_records(), interpret_function_parameter_list(), test_rls_hooks_permissive(), test_rls_hooks_restrictive(), transformCallStmt(), transformCaseExpr(), transformGraphElementPattern(), transformGraphPattern(), transformIndexStmt(), transformJsonTableColumns(), transformPartitionBoundValue(), transformPartitionSpec(), TransformPubWhereClauses(), transformRangeTableFunc(), transformRangeTableSample(), transformRuleStmt(), and transformStatsStmt().

◆ assign_hypothetical_collations()

static void assign_hypothetical_collations ( Aggref aggref,
assign_collations_context loccontext 
)
static

Definition at line 956 of file parse_collate.c.

958{
960 ListCell *s_cell = list_head(aggref->args);
962 int extra_args;
963
964 /* Merge sort collations to parent only if there can be only one */
965 merge_sort_collations = (list_length(aggref->args) == 1 &&
967
968 /* Process any non-hypothetical direct args */
970 Assert(extra_args >= 0);
971 while (extra_args-- > 0)
972 {
974 h_cell = lnext(aggref->aggdirectargs, h_cell);
975 }
976
977 /* Scan hypothetical args and aggregated args in parallel */
978 while (h_cell && s_cell)
979 {
980 Node *h_arg = (Node *) lfirst(h_cell);
983
984 /*
985 * Assign collations internally in this pair of expressions, then
986 * choose a common collation for them. This should match
987 * select_common_collation(), but we can't use that function as-is
988 * because we need access to the whole collation state so we can
989 * bubble it up to the aggregate function's level.
990 */
991 paircontext.pstate = loccontext->pstate;
992 paircontext.collation = InvalidOid;
993 paircontext.strength = COLLATE_NONE;
994 paircontext.location = -1;
995 /* Set these fields just to suppress uninitialized-value warnings: */
996 paircontext.collation2 = InvalidOid;
997 paircontext.location2 = -1;
998
1001
1002 /* deal with collation conflict */
1003 if (paircontext.strength == COLLATE_CONFLICT)
1004 ereport(ERROR,
1006 errmsg("collation mismatch between implicit collations \"%s\" and \"%s\"",
1008 get_collation_name(paircontext.collation2)),
1009 errhint("You can choose the collation by applying the COLLATE clause to one or both expressions."),
1011 paircontext.location2)));
1012
1013 /*
1014 * At this point paircontext.collation can be InvalidOid only if the
1015 * type is not collatable; no need to do anything in that case. If we
1016 * do have to change the sort column's collation, do it by inserting a
1017 * RelabelType node into the sort column TLE.
1018 *
1019 * XXX This is pretty grotty for a couple of reasons:
1020 * assign_collations_walker isn't supposed to be changing the
1021 * expression structure like this, and a parse-time change of
1022 * collation ought to be signaled by a CollateExpr not a RelabelType
1023 * (the use of RelabelType for collation marking is supposed to be a
1024 * planner/executor thing only). But we have no better alternative.
1025 * In particular, injecting a CollateExpr could result in the
1026 * expression being interpreted differently after dump/reload, since
1027 * we might be effectively promoting an implicit collation to
1028 * explicit. This kluge is relying on ruleutils.c not printing a
1029 * COLLATE clause for a RelabelType, and probably on some other
1030 * fragile behaviors.
1031 */
1032 if (OidIsValid(paircontext.collation) &&
1033 paircontext.collation != exprCollation((Node *) s_tle->expr))
1034 {
1035 s_tle->expr = (Expr *)
1036 makeRelabelType(s_tle->expr,
1037 exprType((Node *) s_tle->expr),
1038 exprTypmod((Node *) s_tle->expr),
1039 paircontext.collation,
1041 }
1042
1043 /*
1044 * If appropriate, merge this column's collation state up to the
1045 * aggregate function.
1046 */
1049 paircontext.strength,
1050 paircontext.location,
1051 paircontext.collation2,
1052 paircontext.location2,
1053 loccontext);
1054
1055 h_cell = lnext(aggref->aggdirectargs, h_cell);
1056 s_cell = lnext(aggref->args, s_cell);
1057 }
1058 Assert(h_cell == NULL && s_cell == NULL);
1059}
Oid get_func_variadictype(Oid funcid)
Definition lsyscache.c:1943
RelabelType * makeRelabelType(Expr *arg, Oid rtype, int32 rtypmod, Oid rcollid, CoercionForm rformat)
Definition makefuncs.c:453
int32 exprTypmod(const Node *expr)
Definition nodeFuncs.c:304
static int list_length(const List *l)
Definition pg_list.h:152
static ListCell * list_head(const List *l)
Definition pg_list.h:128
static ListCell * lnext(const List *l, const ListCell *c)
Definition pg_list.h:343
@ COERCE_IMPLICIT_CAST
Definition primnodes.h:769
Oid aggfnoid
Definition primnodes.h:464

References Aggref::aggdirectargs, Aggref::aggfnoid, Aggref::args, Assert, assign_collations_walker(), COERCE_IMPLICIT_CAST, COLLATE_CONFLICT, COLLATE_NONE, ereport, errcode(), errhint(), errmsg, ERROR, exprCollation(), exprType(), exprTypmod(), fb(), get_collation_name(), get_func_variadictype(), InvalidOid, lfirst, list_head(), list_length(), lnext(), makeRelabelType(), merge_collation_state(), OidIsValid, parser_errposition(), and assign_collations_context::pstate.

Referenced by assign_collations_walker().

◆ assign_list_collations()

void assign_list_collations ( ParseState pstate,
List exprs 
)

Definition at line 155 of file parse_collate.c.

156{
157 ListCell *lc;
158
159 foreach(lc, exprs)
160 {
161 Node *node = (Node *) lfirst(lc);
162
163 assign_expr_collations(pstate, node);
164 }
165}

References assign_expr_collations(), fb(), and lfirst.

Referenced by assign_collations_walker(), assign_query_collations_walker(), transformInsertStmt(), and transformRangeFunction().

◆ assign_ordered_set_collations()

static void assign_ordered_set_collations ( Aggref aggref,
assign_collations_context loccontext 
)
static

Definition at line 920 of file parse_collate.c.

922{
924 ListCell *lc;
925
926 /* Merge sort collations to parent only if there can be only one */
927 merge_sort_collations = (list_length(aggref->args) == 1 &&
929
930 /* Direct args, if any, are normal children of the Aggref node */
932 loccontext);
933
934 /* Process aggregated args appropriately */
935 foreach(lc, aggref->args)
936 {
938
941 else
943 }
944}

References Aggref::aggdirectargs, Aggref::aggfnoid, Aggref::args, assign_collations_walker(), assign_expr_collations(), fb(), get_func_variadictype(), InvalidOid, lfirst_node, and list_length().

Referenced by assign_collations_walker().

◆ assign_query_collations()

void assign_query_collations ( ParseState pstate,
Query query 
)

Definition at line 101 of file parse_collate.c.

102{
103 /*
104 * We just use query_tree_walker() to visit all the contained expressions.
105 * We can skip the rangetable and CTE subqueries, though, since RTEs and
106 * subqueries had better have been processed already (else Vars referring
107 * to them would not get created with the right collation).
108 */
109 (void) query_tree_walker(query,
111 pstate,
114}
#define QTW_IGNORE_CTE_SUBQUERIES
Definition nodeFuncs.h:23
#define query_tree_walker(q, w, c, f)
Definition nodeFuncs.h:158
#define QTW_IGNORE_RANGE_TABLE
Definition nodeFuncs.h:26
static bool assign_query_collations_walker(Node *node, ParseState *pstate)

References assign_query_collations_walker(), fb(), QTW_IGNORE_CTE_SUBQUERIES, QTW_IGNORE_RANGE_TABLE, and query_tree_walker.

Referenced by transformDeleteStmt(), transformInsertStmt(), transformMergeStmt(), transformReturnStmt(), transformSelectStmt(), transformSetOperationStmt(), transformUpdateStmt(), and transformValuesClause().

◆ assign_query_collations_walker()

static bool assign_query_collations_walker ( Node node,
ParseState pstate 
)
static

Definition at line 126 of file parse_collate.c.

127{
128 /* Need do nothing for empty subexpressions */
129 if (node == NULL)
130 return false;
131
132 /*
133 * We don't want to recurse into a set-operations tree; it's already been
134 * fully processed in transformSetOperationStmt.
135 */
136 if (IsA(node, SetOperationStmt))
137 return false;
138
139 if (IsA(node, List))
140 assign_list_collations(pstate, (List *) node);
141 else
142 assign_expr_collations(pstate, node);
143
144 return false;
145}
#define IsA(nodeptr, _type_)
Definition nodes.h:164

References assign_expr_collations(), assign_list_collations(), fb(), and IsA.

Referenced by assign_query_collations().

◆ merge_collation_state()

static void merge_collation_state ( Oid  collation,
CollateStrength  strength,
int  location,
Oid  collation2,
int  location2,
assign_collations_context context 
)
static

Definition at line 781 of file parse_collate.c.

787{
788 /*
789 * If the collation strength for this node is different from what's
790 * already in *context, then this node either dominates or is dominated by
791 * earlier siblings.
792 */
793 if (strength > context->strength)
794 {
795 /* Override previous parent state */
796 context->collation = collation;
797 context->strength = strength;
798 context->location = location;
799 /* Bubble up error info if applicable */
800 if (strength == COLLATE_CONFLICT)
801 {
802 context->collation2 = collation2;
803 context->location2 = location2;
804 }
805 }
806 else if (strength == context->strength)
807 {
808 /* Merge, or detect error if there's a collation conflict */
809 switch (strength)
810 {
811 case COLLATE_NONE:
812 /* Nothing + nothing is still nothing */
813 break;
814 case COLLATE_IMPLICIT:
815 if (collation != context->collation)
816 {
817 /*
818 * Non-default implicit collation always beats default.
819 */
820 if (context->collation == DEFAULT_COLLATION_OID)
821 {
822 /* Override previous parent state */
823 context->collation = collation;
824 context->strength = strength;
825 context->location = location;
826 }
827 else if (collation != DEFAULT_COLLATION_OID)
828 {
829 /*
830 * Oops, we have a conflict. We cannot throw error
831 * here, since the conflict could be resolved by a
832 * later sibling CollateExpr, or the parent might not
833 * care about collation anyway. Return enough info to
834 * throw the error later, if needed.
835 */
836 context->strength = COLLATE_CONFLICT;
837 context->collation2 = collation;
838 context->location2 = location;
839 }
840 }
841 break;
842 case COLLATE_CONFLICT:
843 /* We're still conflicted ... */
844 break;
845 case COLLATE_EXPLICIT:
846 if (collation != context->collation)
847 {
848 /*
849 * Oops, we have a conflict of explicit COLLATE clauses.
850 * Here we choose to throw error immediately; that is what
851 * the SQL standard says to do, and there's no good reason
852 * to be less strict.
853 */
856 errmsg("collation mismatch between explicit collations \"%s\" and \"%s\"",
858 get_collation_name(collation)),
859 parser_errposition(context->pstate, location)));
860 }
861 break;
862 }
863 }
864}

References COLLATE_CONFLICT, COLLATE_EXPLICIT, COLLATE_IMPLICIT, COLLATE_NONE, assign_collations_context::collation, assign_collations_context::collation2, ereport, errcode(), errmsg, ERROR, fb(), get_collation_name(), assign_collations_context::location, assign_collations_context::location2, parser_errposition(), assign_collations_context::pstate, and assign_collations_context::strength.

Referenced by assign_collations_walker(), and assign_hypothetical_collations().

◆ select_common_collation()

Oid select_common_collation ( ParseState pstate,
List exprs,
bool  none_ok 
)

Definition at line 208 of file parse_collate.c.

209{
211
212 /* initialize context for tree walk */
213 context.pstate = pstate;
214 context.collation = InvalidOid;
215 context.strength = COLLATE_NONE;
216 context.location = -1;
217
218 /* and away we go */
219 (void) assign_collations_walker((Node *) exprs, &context);
220
221 /* deal with collation conflict */
222 if (context.strength == COLLATE_CONFLICT)
223 {
224 if (none_ok)
225 return InvalidOid;
228 errmsg("collation mismatch between implicit collations \"%s\" and \"%s\"",
231 errhint("You can choose the collation by applying the COLLATE clause to one or both expressions."),
232 parser_errposition(context.pstate, context.location2)));
233 }
234
235 /*
236 * Note: if strength is still COLLATE_NONE, we'll return InvalidOid, but
237 * that's okay because it must mean none of the expressions returned
238 * collatable datatypes.
239 */
240 return context.collation;
241}

References assign_collations_walker(), COLLATE_CONFLICT, COLLATE_NONE, assign_collations_context::collation, assign_collations_context::collation2, ereport, errcode(), errhint(), errmsg, ERROR, fb(), get_collation_name(), InvalidOid, assign_collations_context::location, assign_collations_context::location2, parser_errposition(), assign_collations_context::pstate, and assign_collations_context::strength.

Referenced by analyzeCTE(), assign_collations_walker(), constructSetOpTargetlist(), and transformValuesClause().