Currently, equal() does the following for List nodes:

case T_List:
{
        List       *la = (List *) a;
        List       *lb = (List *) b;
        List       *l;

        /*
         * Try to reject by length check before we grovel through
         * all the elements...
         */
        if (length(la) != length(lb))
                return false;
        foreach(l, la)
        {
                if (!equal(lfirst(l), lfirst(lb)))
                        return false;
                lb = lnext(lb);
        }
        retval = true;
}
break;

This code is inefficient, however: length() requires iterating through
the entire list, so this code scans both lists twice. The attached patch
improves this by implementing equal() with a single scan of both lists.

-Neil

Index: src/backend/nodes/equalfuncs.c
===================================================================
RCS file: /var/lib/cvs/pgsql-server/src/backend/nodes/equalfuncs.c,v
retrieving revision 1.209
diff -c -r1.209 equalfuncs.c
*** src/backend/nodes/equalfuncs.c	17 Aug 2003 23:43:26 -0000	1.209
--- src/backend/nodes/equalfuncs.c	3 Nov 2003 09:10:21 -0000
***************
*** 1779,1799 ****
  			{
  				List	   *la = (List *) a;
  				List	   *lb = (List *) b;
- 				List	   *l;
  
! 				/*
! 				 * Try to reject by length check before we grovel through
! 				 * all the elements...
! 				 */
! 				if (length(la) != length(lb))
! 					return false;
! 				foreach(l, la)
  				{
! 					if (!equal(lfirst(l), lfirst(lb)))
  						return false;
  					lb = lnext(lb);
  				}
! 				retval = true;
  			}
  			break;
  
--- 1779,1801 ----
  			{
  				List	   *la = (List *) a;
  				List	   *lb = (List *) b;
  
! 				while (la != NIL && lb != NIL)
  				{
! 					if (!equal(lfirst(la), lfirst(lb)))
  						return false;
+ 					la = lnext(la);
  					lb = lnext(lb);
  				}
! 
! 				/*
! 				 * If we ran out of elements in one list before the
! 				 * other, then the two lists cannot be equal
! 				 */
! 				if (la != NIL || lb != NIL)
! 					retval = false;
! 				else
! 					retval = true;
  			}
  			break;
  
---------------------------(end of broadcast)---------------------------
TIP 8: explain analyze is your friend

Reply via email to