Re: [HACKERS] functional indexes - Mailing list pgsql-hackers

From jwieck@debis.com (Jan Wieck)
Subject Re: [HACKERS] functional indexes
Date
Msg-id m0zP5NR-000EBQC@orion.SAPserv.Hamburg.dsh.de
Whole thread Raw
In response to Re: [HACKERS] functional indexes  (Bruce Momjian <maillist@candle.pha.pa.us>)
List pgsql-hackers
>
> Added to open 6.4 bugs list.

    Can be removed from the list.

>
>
> > With the current snapshot, there seems to be problem with functional indexes.
> > Example:
> >
> > CREATE TABLE timelog (loginname text, site varchar(16), start_time datetime,
> > elapsed timespan);
> > CREATE FUNCTION datetime_day (datetime ) RETURNS float8 AS 'select
> > date_part(''day'', $1)' LANGUAGE 'SQL';
> > INSERT INTO timelog values ('abc','varna','Thu 01 Jan 23:23:34 1998 EET','@ 10
> > mins');
> > INSERT INTO timelog values ('abc','sofia','Thu 01 Jan 23:23:34 1998 EET','@ 2
> > hours 10 mins');
> >
> > $ psql test
> > Welcome to the POSTGRESQL interactive sql monitor:
> >   Please read the file COPYRIGHT for copyright terms of POSTGRESQL
> >
> >    type \? for help on slash commands
> >    type \q to quit
> >    type \g or terminate with semicolon to execute query
> >  You are currently connected to the database: test
> >
> > test=> create index timelog_date_idx on timelog (datetime_day(start_time));
> > ERROR:  DefineIndex: (null) class not found
> > test=>
> >
> > Also, using date_part() directly in the index definition:
> >
> > test=> create index timelog_date_idx on timelog (datetime_part('day',
> > start_time));
> > ERROR:  parser: parse error at or near "'"
> >
> >
> > Can something be done about this before 6.4 is released?
> >
> > Daniel
> >
> >
> >
> >

    Problem 1:
        You must specify an operator class for the index.

    Solution:
        CREATE INDEX timelog_date_idx ON timelog
            (datetime_day(start_time) float8_ops);

        in the above case.

    Problem 2:
        Only  tuple  attributes  can  be  given  to  a functional
        indexes proc. This is  why  date_part('day',  start_time)
        cannot be used directly. There is no place in pg_index to
        store constant values.

    Solution:
        As you did with a wrapper function. But...

    Problem 3:
        You cannot use  SQL  language  functions  for  functional
        index    procs.     The   index   access   methods   call
        fmgr_array_args() to compute the functional index  value.
    And this cannot execute SQL language functions.

    Solution:
        Write  a  C  language function for it or use the PL/pgSQL
        function

        CREATE FUNCTION datetime_day(datetime) RETURNS float8 AS '
            BEGIN
                RETURN date_part(''day'', $1);
            END;'
            LANGUAGE 'plpgsql';

        after  installing  the  procedural   language   in   your
        database.  Did I tell that I like PL/pgSQL more and more?
    Think it was really time for it.

    Problem 4:
        The  isNull  flag used in access/index/indexam.c function
        GetIndexValue() is not initialized correctly.

    Solution:
        Apply the patch at the end.


Jan

--

#======================================================================#
# It's easier to get forgiveness for being wrong than for being right. #
# Let's break this rule - forgive me.                                  #
#======================================== jwieck@debis.com (Jan Wieck) #


*** indexam.c.orig    Fri Oct  2 15:16:49 1998
--- indexam.c    Fri Oct  2 15:17:24 1998
***************
*** 362,368 ****
                bool *attNull)
  {
      Datum        returnVal;
!     bool        isNull;

      if (PointerIsValid(fInfo) && FIgetProcOid(fInfo) != InvalidOid)
      {
--- 362,368 ----
                bool *attNull)
  {
      Datum        returnVal;
!     bool        isNull = FALSE;

      if (PointerIsValid(fInfo) && FIgetProcOid(fInfo) != InvalidOid)
      {
***************
*** 375,387 ****
                                        attrNums[i],
                                        hTupDesc,
                                        attNull);
          }
          returnVal = (Datum) fmgr_array_args(FIgetProcOid(fInfo),
                                              FIgetnArgs(fInfo),
                                              (char **) attData,
                                              &isNull);
          pfree(attData);
!         *attNull = FALSE;
      }
      else
          returnVal = heap_getattr(tuple, attrNums[attOff], hTupDesc, attNull);
--- 375,389 ----
                                        attrNums[i],
                                        hTupDesc,
                                        attNull);
+             if (*attNull)
+                 isNull = TRUE;
          }
          returnVal = (Datum) fmgr_array_args(FIgetProcOid(fInfo),
                                              FIgetnArgs(fInfo),
                                              (char **) attData,
                                              &isNull);
          pfree(attData);
!         *attNull = isNull;
      }
      else
          returnVal = heap_getattr(tuple, attrNums[attOff], hTupDesc, attNull);

pgsql-hackers by date:

Previous
From: "Matthew C. Aycock"
Date:
Subject: Re: [HACKERS] pg_dump
Next
From: Tom Lane
Date:
Subject: Re: [HACKERS] Names that suddenly include an OID