Subject: libpq via adt 13.6.

From: Wolf Guddat <[email-masked]>
Date: Tue, 13 Jul 93 11:40:14 MESZ

Hi developers,

perhaps you remember some questions which i sent to you in 
the last two weeks. The problem which i duscussed with you
was about making postqel-queries from inside of user defined
functions (in the following "userfunc").
resources: postgres4.1, ultrix4.3, decstation

I try to fix what was mentioned by you and me.
1.) LIBPQ is not accessible for userfuncs
    -- this is somehow logic and i expected it
2.) You told me to look at a function in postgres.c named pg_eval_dest
    -- I've done this and i've read the code around it too
       Although i didn't understand all of the code (how could i) i
       figured out that this would be a possible but very time-expensive
       way (for me) to get to my final aim.
       I've read also the code of dest.h and it surprised me to find
       the following comment-line:
       "a local portal buffer is the destination when a backend executes
       a user-defined function which calls PQexec()..."
       Ooops! Isn't this the way i'm looking for
       A unix "nm .../bin/postmaster showed me that there are some functions
       declared similar to the ones in the libpq. (e.g. PQexec, PQparray, ...)
       One function is missing (PQsetdb).
       I tried to use this functions.
3.) I wrote a userfunc calling the PQ*-functions i found
    This way seems to work. I created via monitor a class I
    > create I (i=int4)
    > define function connect .....
    I've done some appends like this
    > append I (i=2)
    Finally i made the following (critical call)
    > append I (i = connect(18))
    And magically it works! (with a small warning)
    Everytime when i execute one of these PQ*-functions inside of connect
    i get the monitor message:
    NOTICE:Jul 13 10:10:41:PortalHeapMemoryFree: 0x101a1a90 not in alloc set!
    I think this has some reason in freeing the memory of my Query-String, but
    i was not able to avoid this message.
I was totally confused about the things you wrote to me.
I know i didn't used the real libpq, but is there someone (== some code) who
cares about this?
Knowing that it's very dangerous to program outside of the documented user-
interface my fear is now that my way seems to be OK but in fact isn't.
I would be very glad if you could give me some statements on this problem.

PS:
One more question:
In the first PQexec call i submit a variable called QueryBuffer as an argument
  char *QueryBuffer;
  char *retval;
  QueryBuffer = (char *) palloc ( 128*sizeof(char) );
  sprintf (QueryBuffer, "begin");
  retval = (char *) PQexec ( (char *)QueryBuffer);
If i dont cast QueryBuffer to char* my monitor says:
Error: Unexpected identifier in process_portal:
If i cast it it says:
NOTICE:Jul 13 10:10:41:PortalHeapMemoryFree: 0x101a1a90 not in alloc set
The monitor is doing this everytime i call an PQ*-function
How can i turn off this Warning?

*****************************************************
**                                                 **
** Wolf Guddat, [email-masked]  **
**                                                 **
*****************************************************

*********************** CUT HERE FOR MY CODE: connect.c **************************

#include <stdio.h>
#include "postgres.h"
#include "palloc.h"
#include "builtins.h"
#include "pg_lobj.h"

#define EF "/user/sonst/wfguddat/XPR2PG/connect.err"

extern char *PQexec ();
extern PortalBuffer *PQparray ();
extern int PQntuplesGroup ();
extern int PQnfieldsGroup ();
extern char *PQfnameGroup ();
extern char *PQgetvalue ();

/******************************************************************************/
/*
                                 connect 

   erstellt:  1.7.93
   geaendert: 13.7.93
   Status:    in action

*/
/******************************************************************************/
int4 *connect (arg)
  int4 *arg;
{
  
  PortalBuffer *buffer;
  char *QueryBuffer;
  int n_groups;
  int n_tuples;
  int n_fields;
  int i, j, k;
  int t;
  char *retval;

FILE *ef;

ef = fopen (EF, "w");
fprintf (ef, "connect:\n");
fprintf (ef, "arg is [%d]\n", arg);
fclose (ef);

ef = fopen (EF, "a");

  /* See comment on these lines in the above message */
  QueryBuffer = (char *) palloc ( 128*sizeof(char) );
  sprintf (QueryBuffer, "begin");
  retval = (char *) PQexec ( (char *)QueryBuffer);
  fprintf (ef, "status for BEGIN [%s]\n", retval);

  sprintf (QueryBuffer, "retrieve portal eportal (I.all)");
  retval = (char *) PQexec ("retrieve portal eportal (I.all)");
  fprintf (ef, "status for RETRIEVE [%s]\n", retval);

  sprintf (QueryBuffer, "fetch all in eportal");
  retval = (char *) PQexec ("fetch all in eportal");
  fprintf (ef, "status for FETCH [%s]\n", retval);

  buffer = PQparray ("eportal"); n_groups = PQngroups (buffer);

  t = 0;
  for (k=0; k < n_groups; k++)
  {
    fprintf (ef, "new instance group number=(%d)\n", k);
    n_tuples = PQntuplesGroup (buffer, k);
    n_fields = PQnfieldsGroup (buffer, k);

    /* Print Att-Names */
    for (i=0; i < n_fields; i++)
    {
      fprintf (ef, "%-15s", PQfnameGroup (buffer, k, i) );
    }
    fprintf (ef, "\n");

    /* Print values */
    for (i=0; i< n_tuples; i++)
    {
      for (j=0; j < n_fields; j++)
      {
        fprintf (ef, "%-15s", PQgetvalue (buffer, t+i, j));
      }
      fprintf (ef, "\n");
    }
    t += n_tuples;
  }

  sprintf (QueryBuffer, "close eportal");
  retval = PQexec ("close eportal");
  fprintf (ef, "status for CLOSE EPORTAL [%s]\n", retval);

  sprintf (QueryBuffer, "end");
  retval = PQexec ("end");
  fprintf (ef, "status for END [%s]\n", retval);

fclose (ef);

END:

  return (arg);

} /* connect */

************************* these are my printfs **************************

connect:
arg is [18]
status for BEGIN [Enull PQexec result]
status for RETRIEVE [Pbe_169888_7]
status for FETCH [Peportal]
new instance group number=(0)
i              
2              
4              
7              
7              
8              
8              
10             
10             
11             
status for CLOSE EPORTAL [Enull PQexec result]
status for END [Enull PQexec result]