* assign_collations_walker() * Recursive guts of collation processing. * * Nodes with no children (eg, Vars, Consts, Params) must have been marked * when built. All upper-level nodes are marked here. * * Note: if this is invoked directly on a List, it will attempt to infer a * common collation for all the list members. In particular, it will throw * error if there are conflicting explic
| 255 | * error if there are conflicting explicit collations for different members. |
| 256 | */ |
| 257 | static bool |
| 258 | assign_collations_walker(Node *node, assign_collations_context *context) |
| 259 | { |
| 260 | assign_collations_context loccontext; |
| 261 | Oid collation; |
| 262 | CollateStrength strength; |
| 263 | int location; |
| 264 | |
| 265 | /* Need do nothing for empty subexpressions */ |
| 266 | if (node == NULL) |
| 267 | return false; |
| 268 | |
| 269 | /* |
| 270 | * Prepare for recursion. For most node types, though not all, the first |
| 271 | * thing we do is recurse to process all nodes below this one. Each level |
| 272 | * of the tree has its own local context. |
| 273 | */ |
| 274 | loccontext.pstate = context->pstate; |
| 275 | loccontext.collation = InvalidOid; |
| 276 | loccontext.strength = COLLATE_NONE; |
| 277 | loccontext.location = -1; |
| 278 | /* Set these fields just to suppress uninitialized-value warnings: */ |
| 279 | loccontext.collation2 = InvalidOid; |
| 280 | loccontext.location2 = -1; |
| 281 | |
| 282 | /* |
| 283 | * Recurse if appropriate, then determine the collation for this node. |
| 284 | * |
| 285 | * Note: the general cases are at the bottom of the switch, after various |
| 286 | * special cases. |
| 287 | */ |
| 288 | switch (nodeTag(node)) |
| 289 | { |
| 290 | case T_CollateExpr: |
| 291 | { |
| 292 | /* |
| 293 | * COLLATE sets an explicitly derived collation, regardless of |
| 294 | * what the child state is. But we must recurse to set up |
| 295 | * collation info below here. |
| 296 | */ |
| 297 | CollateExpr *expr = (CollateExpr *) node; |
| 298 | |
| 299 | (void) expression_tree_walker(node, |
| 300 | assign_collations_walker, |
| 301 | (void *) &loccontext); |
| 302 | |
| 303 | collation = expr->collOid; |
| 304 | Assert(OidIsValid(collation)); |
| 305 | strength = COLLATE_EXPLICIT; |
| 306 | location = expr->location; |
| 307 | } |
| 308 | break; |
| 309 | case T_FieldSelect: |
| 310 | { |
| 311 | /* |
| 312 | * For FieldSelect, the result has the field's declared |
| 313 | * collation, independently of what happened in the arguments. |
| 314 | * (The immediate argument must be composite and thus not |
no test coverage detected