Thread: output branches before infinite recursion using connectby()?

output branches before infinite recursion using connectby()?

From
Zhenchang Xing
Date:
hi,

is it possible to output the branches before the detection of infinite 
recursion when using connectby()? My work is about software evolution 
analysis. One of the questions i am interested in is class usage. For 
example, class A uses B, B uses C, C uses D, and finally D uses A. I know 
connectby() can detect infinite recursion, but it does not output 
anything if such recursion is detected. Furthermore, to avoid infinite 
recursion, the depth can be given in advance. But in the real world, I 
cannot know in advance the the depth of such usage. It would be very helpful
if connectby() can output the branches before the detection of infinite 
recursion. Take the above example, output: A uses B, B uses C, C uses D, 
and stop when detecting D uses A.

thanks so much.
zhenchang



Re: output branches before infinite recursion using connectby()?

From
Joe Conway
Date:
Zhenchang Xing wrote:
> is it possible to output the branches before the detection of infinite
> recursion when using connectby()?

It is possible if you patch the distributed source ;-)

Not heavily tested, but the attached patch against 7.4 seems to do the
trick for me. I'm not really sure I'd want this in the distribution
though -- anyone else with opinions?

Joe
Index: tablefunc.c
===================================================================
RCS file: /cvsroot/pgsql-server/contrib/tablefunc/tablefunc.c,v
retrieving revision 1.25.2.2
diff -c -r1.25.2.2 tablefunc.c
*** tablefunc.c    11 Aug 2004 01:02:07 -0000    1.25.2.2
--- tablefunc.c    30 Sep 2004 22:51:42 -0000
***************
*** 1416,1421 ****
--- 1416,1423 ----

          for (i = 0; i < proc; i++)
          {
+             bool    recursion_detected = false;
+
              /* initialize branch for this pass */
              appendStringInfo(branchstr, "%s", branch);
              appendStringInfo(chk_branchstr, "%s%s%s", branch_delim, branch, branch_delim);
***************
*** 1433,1439 ****

              /* check to see if this key is also an ancestor */
              if (strstr(chk_branchstr->data, chk_current_key->data))
!                 elog(ERROR, "infinite recursion detected");

              /* OK, extend the branch */
              appendStringInfo(branchstr, "%s%s", branch_delim, current_key);
--- 1435,1444 ----

              /* check to see if this key is also an ancestor */
              if (strstr(chk_branchstr->data, chk_current_key->data))
!             {
!                 elog(NOTICE, "infinite recursion detected");
!                 recursion_detected = true;
!             }

              /* OK, extend the branch */
              appendStringInfo(branchstr, "%s%s", branch_delim, current_key);
***************
*** 1471,1477 ****
              heap_freetuple(tuple);

              /* recurse using current_key_parent as the new start_with */
!             tupstore = build_tuplestore_recursively(key_fld,
                                                      parent_key_fld,
                                                      relname,
                                                      orderby_fld,
--- 1476,1483 ----
              heap_freetuple(tuple);

              /* recurse using current_key_parent as the new start_with */
!             if (!recursion_detected)
!                 tupstore = build_tuplestore_recursively(key_fld,
                                                      parent_key_fld,
                                                      relname,
                                                      orderby_fld,