* Check if expression is safe to execute remotely, and return true if so. * * In addition, *outer_cxt is updated with collation information. * * We must check that the expression contains only node types we can deparse, * that all types/functions/operators are safe to send (they are "shippable"), * and that all collations used in the expression derive from Vars of the * foreign table. Beca
| 297 | * currently considered here. |
| 298 | */ |
| 299 | static bool |
| 300 | foreign_expr_walker(Node *node, |
| 301 | foreign_glob_cxt *glob_cxt, |
| 302 | foreign_loc_cxt *outer_cxt) |
| 303 | { |
| 304 | bool check_type = true; |
| 305 | PgFdwRelationInfo *fpinfo; |
| 306 | foreign_loc_cxt inner_cxt; |
| 307 | Oid collation; |
| 308 | FDWCollateState state; |
| 309 | |
| 310 | /* Need do nothing for empty subexpressions */ |
| 311 | if (node == NULL) |
| 312 | return true; |
| 313 | |
| 314 | /* May need server info from baserel's fdw_private struct */ |
| 315 | fpinfo = (PgFdwRelationInfo *) (glob_cxt->foreignrel->fdw_private); |
| 316 | |
| 317 | /* Set up inner_cxt for possible recursion to child nodes */ |
| 318 | inner_cxt.collation = InvalidOid; |
| 319 | inner_cxt.state = FDW_COLLATE_NONE; |
| 320 | |
| 321 | switch (nodeTag(node)) |
| 322 | { |
| 323 | case T_Var: |
| 324 | { |
| 325 | Var *var = (Var *) node; |
| 326 | |
| 327 | /* |
| 328 | * If the Var is from the foreign table, we consider its |
| 329 | * collation (if any) safe to use. If it is from another |
| 330 | * table, we treat its collation the same way as we would a |
| 331 | * Param's collation, ie it's not safe for it to have a |
| 332 | * non-default collation. |
| 333 | */ |
| 334 | if (bms_is_member(var->varno, glob_cxt->relids) && |
| 335 | var->varlevelsup == 0) |
| 336 | { |
| 337 | /* Var belongs to foreign table */ |
| 338 | |
| 339 | /* |
| 340 | * System columns other than ctid should not be sent to |
| 341 | * the remote, since we don't make any effort to ensure |
| 342 | * that local and remote values match (tableoid, in |
| 343 | * particular, almost certainly doesn't match). |
| 344 | */ |
| 345 | if (var->varattno < 0 && |
| 346 | var->varattno != SelfItemPointerAttributeNumber) |
| 347 | return false; |
| 348 | |
| 349 | /* Else check the collation */ |
| 350 | collation = var->varcollid; |
| 351 | state = OidIsValid(collation) ? FDW_COLLATE_SAFE : FDW_COLLATE_NONE; |
| 352 | } |
| 353 | else |
| 354 | { |
| 355 | /* Var belongs to some other table */ |
| 356 | collation = var->varcollid; |
no test coverage detected