* Display a Var appropriately. * * In some cases (currently only when recursing into an unnamed join) * the Var's varlevelsup has to be interpreted with respect to a context * above the current one; levelsup indicates the offset. * * If istoplevel is true, the Var is at the top level of a SELECT's * targetlist, which means we need special treatment of whole-row Vars. * Instead of the norma
| 7106 | * it is a whole-row Var or a subplan output reference). |
| 7107 | */ |
| 7108 | static char * |
| 7109 | get_variable(Var *var, int levelsup, bool istoplevel, deparse_context *context) |
| 7110 | { |
| 7111 | StringInfo buf = context->buf; |
| 7112 | RangeTblEntry *rte; |
| 7113 | AttrNumber attnum; |
| 7114 | int netlevelsup; |
| 7115 | deparse_namespace *dpns; |
| 7116 | Index varno; |
| 7117 | AttrNumber varattno; |
| 7118 | deparse_columns *colinfo; |
| 7119 | char *refname; |
| 7120 | char *attname; |
| 7121 | |
| 7122 | /* Find appropriate nesting depth */ |
| 7123 | netlevelsup = var->varlevelsup + levelsup; |
| 7124 | if (netlevelsup >= list_length(context->namespaces)) |
| 7125 | elog(ERROR, "bogus varlevelsup: %d offset %d", |
| 7126 | var->varlevelsup, levelsup); |
| 7127 | dpns = (deparse_namespace *) list_nth(context->namespaces, |
| 7128 | netlevelsup); |
| 7129 | |
| 7130 | /* |
| 7131 | * If we have a syntactic referent for the Var, and we're working from a |
| 7132 | * parse tree, prefer to use the syntactic referent. Otherwise, fall back |
| 7133 | * on the semantic referent. (Forcing use of the semantic referent when |
| 7134 | * printing plan trees is a design choice that's perhaps more motivated by |
| 7135 | * backwards compatibility than anything else. But it does have the |
| 7136 | * advantage of making plans more explicit.) |
| 7137 | */ |
| 7138 | if (var->varnosyn > 0 && dpns->plan == NULL) |
| 7139 | { |
| 7140 | varno = var->varnosyn; |
| 7141 | varattno = var->varattnosyn; |
| 7142 | } |
| 7143 | else |
| 7144 | { |
| 7145 | varno = var->varno; |
| 7146 | varattno = var->varattno; |
| 7147 | } |
| 7148 | |
| 7149 | /* |
| 7150 | * Try to find the relevant RTE in this rtable. In a plan tree, it's |
| 7151 | * likely that varno is OUTER_VAR or INNER_VAR, in which case we must dig |
| 7152 | * down into the subplans, or INDEX_VAR, which is resolved similarly. Also |
| 7153 | * find the aliases previously assigned for this RTE. |
| 7154 | */ |
| 7155 | if (varno >= 1 && varno <= list_length(dpns->rtable)) |
| 7156 | { |
| 7157 | /* |
| 7158 | * We might have been asked to map child Vars to some parent relation. |
| 7159 | */ |
| 7160 | if (context->appendparents && dpns->appendrels) |
| 7161 | { |
| 7162 | Index pvarno = varno; |
| 7163 | AttrNumber pvarattno = varattno; |
| 7164 | AppendRelInfo *appinfo = dpns->appendrels[pvarno]; |
| 7165 | bool found = false; |
no test coverage detected