Bruce Momjian wrote:
> Tom Lane wrote:
> > Oliver Jowett <[EMAIL PROTECTED]> writes:
> > > A 50-parameter query could be .. interesting ..
> > 
> > > I realize that you need this level of output to reflect what is 
> > > happening at the protocol level, but seeing all the protocol detail is 
> > > not really what you expect when you turn on basic statement logging, is 
> > > it?
> > 
> > Well, we've certainly been beat up often enough about the lack of
> > logging bind parameter values --- I don't think there's any question
> > about the importance of printing them.  I agree that the proposed format
> > is much too verbose though.  In particular, a separate LOG message per
> > parameter is NOT what I had in mind; I want them in DETAIL lines of the
> > bind log message.  (This'd perhaps also address Oliver's issue, since
> > if you didn't want to see the values you could turn down
> > log_error_verbosity.)
> 
> OK, I will continue in that direction.  Will post a new patch.

Updated patch attached.  It prints the text bind parameters on a single
detail line.  I still have not seen portal names generated by libpq.

-- 
  Bruce Momjian   [EMAIL PROTECTED]
  EnterpriseDB    http://www.enterprisedb.com

  + If your life is a hard drive, Christ can be your backup. +
Index: doc/src/sgml/config.sgml
===================================================================
RCS file: /cvsroot/pgsql/doc/src/sgml/config.sgml,v
retrieving revision 1.71
diff -c -c -r1.71 config.sgml
*** doc/src/sgml/config.sgml    27 Jul 2006 08:30:41 -0000      1.71
--- doc/src/sgml/config.sgml    7 Aug 2006 03:44:47 -0000
***************
*** 2808,2814 ****
          <literal>UPDATE</>, <literal>DELETE</>, <literal>TRUNCATE</>,
          and <literal>COPY FROM</>. <literal>PREPARE</> and
          <literal>EXPLAIN ANALYZE</> statements are also logged if their
!         contained command is of an appropriate type.
         </para>
         <para>
          The default is <literal>none</>. Only superusers can change this
--- 2808,2818 ----
          <literal>UPDATE</>, <literal>DELETE</>, <literal>TRUNCATE</>,
          and <literal>COPY FROM</>. <literal>PREPARE</> and
          <literal>EXPLAIN ANALYZE</> statements are also logged if their
!         contained command is of an appropriate type.  Protocol-level
!         prepare, bind, and execute commands are logged only if
!         <varname>log_statement</> is <literal>all</>.  Bind parameter 
!         values are also logged if they are supplied in <literal>text</>
!         format.
         </para>
         <para>
          The default is <literal>none</>. Only superusers can change this
Index: src/backend/commands/portalcmds.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/commands/portalcmds.c,v
retrieving revision 1.48
diff -c -c -r1.48 portalcmds.c
*** src/backend/commands/portalcmds.c   13 Jul 2006 16:49:14 -0000      1.48
--- src/backend/commands/portalcmds.c   7 Aug 2006 03:44:47 -0000
***************
*** 112,117 ****
--- 112,118 ----
         * submitted more than one semicolon delimited queries.
         */
        PortalDefineQuery(portal,
+                                         NULL,
                                          pstrdup(debug_query_string),
                                          "SELECT", /* cursor's query is always 
a SELECT */
                                          list_make1(query),
Index: src/backend/commands/prepare.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/commands/prepare.c,v
retrieving revision 1.58
diff -c -c -r1.58 prepare.c
*** src/backend/commands/prepare.c      14 Jul 2006 14:52:18 -0000      1.58
--- src/backend/commands/prepare.c      7 Aug 2006 03:44:47 -0000
***************
*** 201,206 ****
--- 201,207 ----
        }
  
        PortalDefineQuery(portal,
+                                         NULL,
                                          query_string,
                                          entry->commandTag,
                                          query_list,
Index: src/backend/executor/spi.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/executor/spi.c,v
retrieving revision 1.152
diff -c -c -r1.152 spi.c
*** src/backend/executor/spi.c  14 Jul 2006 14:52:19 -0000      1.152
--- src/backend/executor/spi.c  7 Aug 2006 03:44:48 -0000
***************
*** 919,924 ****
--- 919,925 ----
         * Set up the portal.
         */
        PortalDefineQuery(portal,
+                                         NULL,
                                          spiplan->query,
                                          "SELECT", /* don't have the raw parse 
tree... */
                                          list_make1(queryTree),
Index: src/backend/tcop/postgres.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/tcop/postgres.c,v
retrieving revision 1.495
diff -c -c -r1.495 postgres.c
*** src/backend/tcop/postgres.c 6 Aug 2006 02:00:52 -0000       1.495
--- src/backend/tcop/postgres.c 7 Aug 2006 03:44:49 -0000
***************
*** 955,960 ****
--- 955,961 ----
                portal->visible = false;
  
                PortalDefineQuery(portal,
+                                                 NULL,
                                                  query_string,
                                                  commandTag,
                                                  querytree_list,
***************
*** 1146,1152 ****
  
        if (log_statement == LOGSTMT_ALL)
                ereport(LOG,
!                               (errmsg("statement: <protocol> PREPARE %s AS 
%s",
                                                *stmt_name ? stmt_name : 
"<unnamed>",
                                                query_string)));
  
--- 1147,1153 ----
  
        if (log_statement == LOGSTMT_ALL)
                ereport(LOG,
!                               (errmsg("prepare %s:  %s",
                                                *stmt_name ? stmt_name : 
"<unnamed>",
                                                query_string)));
  
***************
*** 1367,1372 ****
--- 1368,1374 ----
        PreparedStatement *pstmt;
        Portal          portal;
        ParamListInfo params;
+       StringInfoData str;
  
        pgstat_report_activity("<BIND>");
  
***************
*** 1382,1387 ****
--- 1384,1392 ----
        /* Switch back to message context */
        MemoryContextSwitchTo(MessageContext);
  
+       if (log_statement == LOGSTMT_ALL)
+               initStringInfo(&str);
+ 
        /* Get the fixed part of the message */
        portal_name = pq_getmsgstring(input_message);
        stmt_name = pq_getmsgstring(input_message);
***************
*** 1450,1462 ****
        else
                portal = CreatePortal(portal_name, false, false);
  
-       /* We need to output the parameter values someday */
-       if (log_statement == LOGSTMT_ALL)
-               ereport(LOG,
-                               (errmsg("statement: <protocol> <BIND> %s  
[PREPARE:  %s]",
-                                               *portal_name ? portal_name : 
"<unnamed>",
-                                               portal->sourceText ? 
portal->sourceText : "")));
- 
        /*
         * Fetch parameters, if any, and store in the portal's memory context.
         */
--- 1455,1460 ----
***************
*** 1519,1525 ****
                        else
                                pformat = 0;    /* default = text */
  
!                       if (pformat == 0)
                        {
                                Oid                     typinput;
                                Oid                     typioparam;
--- 1517,1523 ----
                        else
                                pformat = 0;    /* default = text */
  
!                       if (pformat == 0)       /* text mode */
                        {
                                Oid                     typinput;
                                Oid                     typioparam;
***************
*** 1540,1550 ****
                                                                                
                                           pstring,
                                                                                
                                           typioparam,
                                                                                
                                           -1);
                                /* Free result of encoding conversion, if any */
                                if (pstring && pstring != pbuf.data)
                                        pfree(pstring);
                        }
!                       else if (pformat == 1)
                        {
                                Oid                     typreceive;
                                Oid                     typioparam;
--- 1538,1553 ----
                                                                                
                                           pstring,
                                                                                
                                           typioparam,
                                                                                
                                           -1);
+ 
+                               if (log_statement == LOGSTMT_ALL)
+                                       appendStringInfo(&str, "%s$%d = \"%s\"",
+                                               *str.data ? ", " : "", paramno 
+ 1, pstring);
+ 
                                /* Free result of encoding conversion, if any */
                                if (pstring && pstring != pbuf.data)
                                        pfree(pstring);
                        }
!                       else if (pformat == 1)  /* binary mode */
                        {
                                Oid                     typreceive;
                                Oid                     typioparam;
***************
*** 1595,1600 ****
--- 1598,1623 ----
        else
                params = NULL;
  
+       if (log_statement == LOGSTMT_ALL)
+       {
+               if (*str.data)
+                       ereport(LOG,
+                                       (errmsg("bind %s%s%s:  %s",
+                                                       *stmt_name ? stmt_name 
: "<unnamed>",
+                                                       *portal->name ? "/" : 
"",
+                               *portal->name ? portal->name : "",
+                                                       pstmt->query_string ? 
pstmt->query_string : ""),
+                                        errdetail(str.data)));
+               else
+                       ereport(LOG,
+                                       (errmsg("bind %s%s%s:  %s",
+                                                       *stmt_name ? stmt_name 
: "<unnamed>",
+                                                       *portal->name ? "/" : 
"",
+                               *portal->name ? portal->name : "",
+                                                       pstmt->query_string ? 
pstmt->query_string : "")));
+               pfree(str.data);
+       }
+ 
        /* Get the result format codes */
        numRFormats = pq_getmsgint(input_message, 2);
        if (numRFormats > 0)
***************
*** 1628,1633 ****
--- 1651,1657 ----
         * Define portal and start execution.
         */
        PortalDefineQuery(portal,
+                                         *stmt_name ? pstrdup(stmt_name) : 
NULL,
                                          pstmt->query_string,
                                          pstmt->commandTag,
                                          pstmt->query_list,
***************
*** 1724,1732 ****
        if (log_statement == LOGSTMT_ALL)
                /* We have the portal, so output the source query. */
                ereport(LOG,
!                               (errmsg("statement: <protocol> %sEXECUTE %s  
[PREPARE:  %s]",
!                                               execute_is_fetch ? "FETCH from 
" : "",
!                                               *portal_name ? portal_name : 
"<unnamed>",
                                                portal->sourceText ? 
portal->sourceText : "")));
  
        BeginCommand(portal->commandTag, dest);
--- 1748,1758 ----
        if (log_statement == LOGSTMT_ALL)
                /* We have the portal, so output the source query. */
                ereport(LOG,
!                               (errmsg("execute %s%s%s%s:  %s",
!                                               execute_is_fetch ? "fetch from 
" : "",
!                                               portal->prepStmtName ? 
portal->prepStmtName : "<unnamed>",
!                                               *portal->name ? "/" : "",
!                         *portal->name ? portal->name : "",
                                                portal->sourceText ? 
portal->sourceText : "")));
  
        BeginCommand(portal->commandTag, dest);
***************
*** 1832,1841 ****
                                                                secs, msecs)));
                        else
                                ereport(LOG,
!                                               (errmsg("duration: %ld.%03d ms  
statement: <protocol> %sEXECUTE %s  [PREPARE:  %s]",
                                                                secs, msecs,
!                                                               
execute_is_fetch ? "FETCH from " : "",
!                                                               *portal_name ? 
portal_name : "<unnamed>",
                                                                
portal->sourceText ? portal->sourceText : "")));
                }
        }
--- 1858,1869 ----
                                                                secs, msecs)));
                        else
                                ereport(LOG,
!                                               (errmsg("duration: %ld.%03d ms  
execute %s%s%s%s:  %s",
                                                                secs, msecs,
!                                                               
execute_is_fetch ? "fetch from " : "",
!                                                               
portal->prepStmtName ? portal->prepStmtName : "<unnamed>",
!                                                               *portal->name ? 
"/" : "",
!                                   *portal->name ? portal->name : "",
                                                                
portal->sourceText ? portal->sourceText : "")));
                }
        }
Index: src/backend/utils/mmgr/portalmem.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/utils/mmgr/portalmem.c,v
retrieving revision 1.90
diff -c -c -r1.90 portalmem.c
*** src/backend/utils/mmgr/portalmem.c  14 Jul 2006 14:52:25 -0000      1.90
--- src/backend/utils/mmgr/portalmem.c  7 Aug 2006 03:44:49 -0000
***************
*** 244,249 ****
--- 244,250 ----
   */
  void
  PortalDefineQuery(Portal portal,
+                                 const char *prepStmtName,
                                  const char *sourceText,
                                  const char *commandTag,
                                  List *parseTrees,
***************
*** 257,262 ****
--- 258,264 ----
  
        Assert(commandTag != NULL || parseTrees == NIL);
  
+       portal->prepStmtName = prepStmtName;
        portal->sourceText = sourceText;
        portal->commandTag = commandTag;
        portal->parseTrees = parseTrees;
Index: src/include/utils/portal.h
===================================================================
RCS file: /cvsroot/pgsql/src/include/utils/portal.h,v
retrieving revision 1.63
diff -c -c -r1.63 portal.h
*** src/include/utils/portal.h  13 Jul 2006 18:01:02 -0000      1.63
--- src/include/utils/portal.h  7 Aug 2006 03:44:50 -0000
***************
*** 100,105 ****
--- 100,106 ----
  {
        /* Bookkeeping data */
        const char *name;                       /* portal's name */
+       const char *prepStmtName;       /* protocol prepare name */
        MemoryContext heap;                     /* subsidiary memory for portal 
*/
        ResourceOwner resowner;         /* resources owned by portal */
        void            (*cleanup) (Portal portal);             /* cleanup hook 
*/
***************
*** 202,207 ****
--- 203,209 ----
  extern void DropDependentPortals(MemoryContext queryContext);
  extern Portal GetPortalByName(const char *name);
  extern void PortalDefineQuery(Portal portal,
+                                 const char *prepStmtName,
                                  const char *sourceText,
                                  const char *commandTag,
                                  List *parseTrees,
---------------------------(end of broadcast)---------------------------
TIP 2: Don't 'kill -9' the postmaster

Reply via email to