Re: SRF patch (was Re: [HACKERS] troubleshooting pointers)

Поиск
Список
Период
Сортировка
От Joe Conway
Тема Re: SRF patch (was Re: [HACKERS] troubleshooting pointers)
Дата
Msg-id 3CE343F9.5080208@joeconway.com
обсуждение исходный текст
Ответ на SRF patch (was Re: [HACKERS] troubleshooting pointers)  (Joe Conway <mail@joeconway.com>)
Список pgsql-patches
Joe Conway wrote:
 >>
 >
 > Attached patch takes care of this case. It also passes my previous
 > test

Sorry, I just noticed that I did not finish modifying the comments that
were cut-and-pasted from elsewhere. This patch includes better comments.

Joe

Index: src/backend/parser/parse_clause.c
===================================================================
RCS file: /opt/src/cvs/pgsql/src/backend/parser/parse_clause.c,v
retrieving revision 1.92
diff -c -r1.92 parse_clause.c
*** src/backend/parser/parse_clause.c    12 May 2002 23:43:03 -0000    1.92
--- src/backend/parser/parse_clause.c    15 May 2002 22:55:37 -0000
***************
*** 61,67 ****
  static List *addTargetToSortList(TargetEntry *tle, List *sortlist,
                      List *targetlist, List *opname);
  static bool exprIsInSortList(Node *expr, List *sortList, List *targetList);
!

  /*
   * transformFromClause -
--- 61,70 ----
  static List *addTargetToSortList(TargetEntry *tle, List *sortlist,
                      List *targetlist, List *opname);
  static bool exprIsInSortList(Node *expr, List *sortList, List *targetList);
! static void checkParameterVisibility(ParseState *pstate,
!                                 RangeTblRef *rtr,
!                                 RangeFunction *rangefunc,
!                                 List *containedRels);

  /*
   * transformFromClause -
***************
*** 545,550 ****
--- 548,559 ----

          rtr = transformRangeFunction(pstate, (RangeFunction *) n);
          *containedRels = makeListi1(rtr->rtindex);
+
+         /*
+          * Make sure we've only been given valid parameters, i.e.
+          * we should not see vars from sibling FROM nodes.
+          */
+         checkParameterVisibility(pstate, rtr, (RangeFunction *) n, *containedRels);
          return (Node *) rtr;
      }
      else if (IsA(n, JoinExpr))
***************
*** 1377,1380 ****
--- 1386,1445 ----
              return true;
      }
      return false;
+ }
+
+ /* checkParameterVisibility()
+  *      Make sure we don't try to access vars from
+  *      sibling FROM nodes as RangeFunction parameters.
+  */
+ static void
+ checkParameterVisibility(ParseState *pstate, RangeTblRef *rtr, RangeFunction *rangefunc, List *containedRels)
+ {
+     FuncCall       *funccallnode = (FuncCall *) rangefunc->funccallnode;
+     List           *args = funccallnode->args;
+     List           *save_namespace;
+     List           *clause_varnos,
+                    *l;
+
+     /*
+      * This is a tad tricky, for two reasons.  First, the namespace that
+      * the function expression should see is just the any outer references
+      * from upper pstate levels. So, temporarily set this pstate's namespace
+      * accordingly.  (We need not check for refname conflicts, because
+      * transformFromClauseItem() already did.) NOTE: this code is OK only
+      * because a RangeFunction can't legally alter the namespace by causing
+      * implicit relation refs to be added.
+      */
+     save_namespace = pstate->p_namespace;
+     pstate->p_namespace = makeList1(rtr);
+
+     /* transform the list of arguments */
+     foreach(args, funccallnode->args)
+     {
+         lfirst(args) = transformExpr(pstate, (Node *) lfirst(args));
+
+         /*
+          * Second, we need to check that the function parameters don't refer
+          * to any other rels.  It could do that despite our hack on the namespace
+          * if it uses fully-qualified names. So, grovel through the transformed
+          * clause and make sure there are no bogus references.  (Outer references
+          * are OK, and are ignored here.)
+          *
+          */
+
+         clause_varnos = pull_varnos(lfirst(args));
+         foreach(l, clause_varnos)
+         {
+             int            varno = lfirsti(l);
+
+             if (!intMember(varno, containedRels))
+             {
+                 elog(ERROR, "Function relation in FROM clause may not refer to other relation, \"%s\"",
+                      rt_fetch(varno, pstate->p_rtable)->eref->aliasname);
+             }
+         }
+         freeList(clause_varnos);
+
+     }
+     pstate->p_namespace = save_namespace;
  }

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

Предыдущее
От: Joe Conway
Дата:
Сообщение: Re: SRF patch (was Re: [HACKERS] troubleshooting pointers)
Следующее
От: Bear Giles
Дата:
Сообщение: more verbose SSL session info for psql