| Line | Hits | Source | Commit |
| 255 |
- |
assign_collations_walker(Node *node, assign_collations_context *context) |
- |
| 256 |
- |
{ |
- |
| 257 |
- |
assign_collations_context loccontext; |
- |
| 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 |
- |
|
- |
| 296 |
- |
(void) expression_tree_walker(node, |
- |
| 297 |
- |
assign_collations_walker, |
- |
| 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 */ |
- |
| 318 |
- |
(void) expression_tree_walker(node, |
- |
| 319 |
- |
assign_collations_walker, |
- |
| 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 |
- |
|
- |
| 376 |
- |
coll = select_common_collation(context->pstate, |
- |
| 377 |
- |
list_make2(le, re), |
- |
| 378 |
- |
true); |
- |
| 379 |
- |
colls = lappend_oid(colls, coll); |
- |
| 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 */ |
- |
| 404 |
- |
(void) expression_tree_walker(node, |
- |
| 405 |
- |
assign_collations_walker, |
- |
| 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) |
- |
| 439 |
- |
exprSetCollation(node, InvalidOid); |
- |
| 440 |
- |
else |
- |
| 441 |
- |
exprSetCollation(node, collation); |
- |
| 442 |
- |
} |
- |
| 443 |
- |
break; |
- |
| 444 |
- |
case T_TargetEntry: |
- |
| 445 |
- |
(void) expression_tree_walker(node, |
- |
| 446 |
- |
assign_collations_walker, |
- |
| 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) |
- |
| 473 |
- |
ereport(ERROR, |
- |
| 474 |
- |
(errcode(ERRCODE_COLLATION_MISMATCH), |
- |
| 475 |
- |
errmsg("collation mismatch between implicit collations \"%s\" and \"%s\"", |
- |
| 476 |
- |
get_collation_name(loccontext.collation), |
- |
| 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: |
- |
| 487 |
- |
case T_SortGroupClause: |
- |
| 488 |
- |
case T_MergeAction: |
- |
| 489 |
- |
(void) expression_tree_walker(node, |
- |
| 490 |
- |
assign_collations_walker, |
- |
| 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; |
- |
| 514 |
- |
TargetEntry *tent; |
- |
| 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: |
- |
| 529 |
- |
(void) expression_tree_walker(node, |
- |
| 530 |
- |
assign_collations_walker, |
- |
| 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: |
- |
| 545 |
- |
case T_CoerceToDomainValue: |
- |
| 546 |
- |
case T_CaseTestExpr: |
- |
| 547 |
- |
case T_SetToDefault: |
- |
| 548 |
- |
case T_CurrentOfExpr: |
- |
| 549 |
- |
case T_GraphPropertyRef: |
86c14eaWIP: SQL Property Graph Queries (SQL/PGQ) |
| 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: |
- |
| 604 |
- |
assign_aggregate_collations(aggref, |
- |
| 605 |
- |
&loccontext); |
- |
| 606 |
- |
break; |
- |
| 607 |
- |
case AGGKIND_ORDERED_SET: |
- |
| 608 |
- |
assign_ordered_set_collations(aggref, |
- |
| 609 |
- |
&loccontext); |
- |
| 610 |
- |
break; |
- |
| 611 |
- |
case AGGKIND_HYPOTHETICAL: |
- |
| 612 |
- |
assign_hypothetical_collations(aggref, |
- |
| 613 |
- |
&loccontext); |
- |
| 614 |
- |
break; |
- |
| 615 |
- |
default: |
- |
| 616 |
- |
elog(ERROR, "unrecognized aggkind: %d", |
- |
| 617 |
- |
(int) aggref->aggkind); |
- |
| 618 |
- |
} |
- |
| 619 |
- |
|
- |
| 620 |
- |
assign_expr_collations(context->pstate, |
- |
| 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 |
- |
|
- |
| 632 |
- |
(void) assign_collations_walker((Node *) wfunc->args, |
- |
| 633 |
- |
&loccontext); |
- |
| 634 |
- |
|
- |
| 635 |
- |
assign_expr_collations(context->pstate, |
- |
| 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 |
- |
{ |
- |
| 654 |
- |
CaseWhen *when = lfirst_node(CaseWhen, lc); |
- |
| 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 |
- |
*/ |
- |
| 663 |
- |
(void) assign_collations_walker((Node *) when->expr, |
- |
| 664 |
- |
&loccontext); |
- |
| 665 |
- |
(void) assign_collations_walker((Node *) when->result, |
- |
| 666 |
- |
&loccontext); |
- |
| 667 |
- |
} |
- |
| 668 |
- |
(void) assign_collations_walker((Node *) expr->defresult, |
- |
| 669 |
- |
&loccontext); |
- |
| 670 |
- |
} |
- |
| 671 |
- |
break; |
- |
| 672 |
- |
case T_SubscriptingRef: |
- |
| 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 |
- |
|
- |
| 685 |
- |
assign_expr_collations(context->pstate, |
- |
| 686 |
- |
(Node *) sbsref->refupperindexpr); |
- |
| 687 |
- |
assign_expr_collations(context->pstate, |
- |
| 688 |
- |
(Node *) sbsref->reflowerindexpr); |
- |
| 689 |
- |
(void) assign_collations_walker((Node *) sbsref->refexpr, |
- |
| 690 |
- |
&loccontext); |
- |
| 691 |
- |
(void) assign_collations_walker((Node *) sbsref->refassgnexpr, |
- |
| 692 |
- |
&loccontext); |
- |
| 693 |
- |
} |
- |
| 694 |
- |
break; |
- |
| 695 |
- |
default: |
- |
| 696 |
- |
|
- |
| 697 |
- |
/* |
- |
| 698 |
- |
* Normal case: all child expressions contribute |
- |
| 699 |
- |
* equally to loccontext. |
- |
| 700 |
- |
*/ |
- |
| 701 |
- |
(void) expression_tree_walker(node, |
- |
| 702 |
- |
assign_collations_walker, |
- |
| 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) |
- |
| 748 |
- |
exprSetCollation(node, InvalidOid); |
- |
| 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) |
- |
| 757 |
- |
exprSetInputCollation(node, InvalidOid); |
- |
| 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 |
- |
} |
- |