Re: varattno remapping

Поиск
Список
Период
Сортировка
От Craig Ringer
Тема Re: varattno remapping
Дата
Msg-id 52B97A33.9080303@2ndquadrant.com
обсуждение исходный текст
Ответ на Re: varattno remapping  (Abbas Butt <abbas.butt@enterprisedb.com>)
Ответы Re: varattno remapping
Список pgsql-hackers
On 12/24/2013 03:21 PM, Abbas Butt wrote:

> Could you please explain a little bit more how would you solve the posed
> problem using map_variable_attnos?

It actually turns out to be even simpler, and easy to do in one pass,
when using ReplaceVarsFromTargetList .

You just generate a temporary new list of TargetEntry, with resnos
matching the attribute numbers of the view. Each contained Var points to
the remapped varno and varattno.

Then you let ReplaceVarsFromTargetList substitute Vars recursively
through the expression tree with ones in the replacement tlist you supply.

The more I've thought about it, the shorter this code has got. Currently:




/** Scan the passed view target list, whose members must consist solely* of Var nodes with a varno equal to the passed
targetvarno,and* produce a targetlist of Var nodes with the corresponding varno and* varattno of the base relation
'targetvarno'.**This tlist is used when remapping Vars that point to a view so they* point to the base relation of the
viewinstead. It is entirely* newly allocated. The result tlist is not in resno order.** Must not be called with a
targetlistcontaining non-Var entries.*/
 
static List *
gen_view_base_attr_map(List *viewtlist, int targetvarno, int newvarno)
{   ListCell    *lc;   TargetEntry *te, *newte;   Var         *tev, *newvar;   int         l_viewtlist =
list_length(viewtlist);  List        *newtlist = NIL;
 
   foreach(lc, viewtlist)   {       te = (TargetEntry*) lfirst(lc);       /* Could relax this in future and map only
thevar entries,        * ignoring everything else, but currently pointless since we        * are only interested in
simpleviews. */       Assert(IsA(te->expr, Var));       tev = (Var*) te->expr;       Assert(tev->varno == targetvarno);
     Assert(te->resno - 1 < l_viewtlist);
 
       /* Construct the new Var with the remapped attno and varno */       newvar = (Var*) palloc(sizeof(Var));
*newvar= *tev;       newvar->varno = newvarno;       newvar->varattno = tev->varattno;
 
       /* and wrap it in a new tle to cons to the list */       newte = flatCopyTargetEntry(te);       newte->expr =
(Expr*)newvar;       newtlist = lcons(newte, newtlist);   }
 
   return newtlist;
}




and invocation:

   /*    * We need to adjust any RETURNING clause entries to point to the new    * target RTE instead of the old one so
thatwe see the effects of    * BEFORE triggers. Varattnos must be remapped so that the new Var    * points to the
correctcol of the base rel, since the view will    * usually have a different set of columns / column order.    *    *
Aspart of this pass any whole-row references to the view are    * expanded into ROW(...) expressions to ensure we don't
expose   * columns that are not visible through the view, and to make sure    * the client gets the result type it
expected.   */
 
   List * remap_tlist = gen_view_base_attr_map(       viewquery->targetList, rtr->rtindex, new_result_rt_index);
   parsetree->returningList = ReplaceVarsFromTargetList(           (Node*) parsetree->returningList,
old_result_rt_index,0 /*sublevels_up*/,           view_rte,           remap_tlist,           REPLACEVARS_REPORT_ERROR,
0/*nomatch_varno, unused */,           NULL /* outer_hasSubLinks, unused */   );
 





-- Craig Ringer                   http://www.2ndQuadrant.com/PostgreSQL Development, 24x7 Support, Training & Services



В списке pgsql-hackers по дате отправления:

Предыдущее
От: Andres Freund
Дата:
Сообщение: Re: INSERT...ON DUPLICATE KEY LOCK FOR UPDATE
Следующее
От: Andres Freund
Дата:
Сообщение: Re: Assertion failure in base backup code path