Re: [PATCHES] dollar quoting and pg_dump

2004-03-23 Thread Andrew Dunstan




Tom Lane wrote:

  Andrew Dunstan <[EMAIL PROTECTED]> writes:
  
  
Here's my attempt, as discussed earlier today. As always, comments 
welcome.  I did provide (and use) a fallback mechanism after all, for 
the case of a function with a non-empty probin.

  
  
Applied with light editorializing ("fallback" seemed a weird description
of what that function was doing, for instance).

At this point I think we are done with the coding part of this project,
and it's time to get to work on the documentation ...

  


It is being worked on.

cheers

andrew




Re: [PATCHES] dollar quoting and pg_dump

2004-03-23 Thread Tom Lane
Andrew Dunstan <[EMAIL PROTECTED]> writes:
> Here's my attempt, as discussed earlier today. As always, comments 
> welcome.  I did provide (and use) a fallback mechanism after all, for 
> the case of a function with a non-empty probin.

Applied with light editorializing ("fallback" seemed a weird description
of what that function was doing, for instance).

At this point I think we are done with the coding part of this project,
and it's time to get to work on the documentation ...

regards, tom lane

---(end of broadcast)---
TIP 6: Have you searched our list archives?

   http://archives.postgresql.org


[PATCHES] dollar quoting and pg_dump

2004-03-23 Thread Andrew Dunstan


Here's my attempt, as discussed earlier today. As always, comments 
welcome.  I did provide (and use) a fallback mechanism after all, for 
the case of a function with a non-empty probin. A few examples from a 
dump of the regression db:

--
-- Name: tg_hub_adjustslots(character, integer, integer); Type: 
FUNCTION; Schema
: public; Owner: andrew
--

CREATE FUNCTION tg_hub_adjustslots(character, integer, integer) RETURNS 
integer
   AS $_$
declare
   hname   alias for $1;
   oldnslots   alias for $2;
   newnslots   alias for $3;
begin
   if newnslots = oldnslots then
   return 0;
   end if;
   if newnslots < oldnslots then
   delete from HSlot where hubname = hname and slotno > newnslots;
   return 0;
   end if;
   for i in oldnslots + 1 .. newnslots loop
   insert into HSlot (slotname, hubname, slotno, slotlink)
   values ('HS.dummy', hname, i, '');
   end loop;
   return 0;
end;
$_$
   LANGUAGE plpgsql;

--
-- Name: ttdummy(); Type: FUNCTION; Schema: public; Owner: andrew
--
CREATE FUNCTION ttdummy() RETURNS "trigger"
   AS '/home/andrew/pgwork/tip/pgsql/src/test/regress/regress.so', 
'ttdummy'
   LANGUAGE c;

--
-- Name: user_relns(); Type: FUNCTION; Schema: public; Owner: andrew
--
CREATE FUNCTION user_relns() RETURNS SETOF name
   AS $$select relname
  from pg_class c, pg_namespace n
  where relnamespace = n.oid and
(nspname !~ 'pg_.*' and nspname <> 'information_schema') and
relkind <> 'i' $$
   LANGUAGE sql;


cheers

andrew


Index: doc/src/sgml/ref/pg_dump.sgml
===
RCS file: /projects/cvsroot/pgsql-server/doc/src/sgml/ref/pg_dump.sgml,v
retrieving revision 1.68
diff -c -r1.68 pg_dump.sgml
*** doc/src/sgml/ref/pg_dump.sgml   1 Dec 2003 22:07:58 -   1.68
--- doc/src/sgml/ref/pg_dump.sgml   23 Mar 2004 19:30:59 -
***
*** 461,466 
--- 461,477 
   
  
   
+   -X disable-dollar-quoting
+   --disable-dollar-quoting
+   
+
+ This option disables the use of dollar quoting for function bodies,
+ and forces them to be quoted using SQL standard strings.
+
+  
+ 
+ 
+  
-Z 0..9
--compress=0..9

Index: src/bin/pg_dump/dumputils.c
===
RCS file: /projects/cvsroot/pgsql-server/src/bin/pg_dump/dumputils.c,v
retrieving revision 1.11
diff -c -r1.11 dumputils.c
*** src/bin/pg_dump/dumputils.c 7 Jan 2004 00:44:21 -   1.11
--- src/bin/pg_dump/dumputils.c 23 Mar 2004 19:30:59 -
***
*** 143,148 
--- 143,205 
  
  
  /*
+  * Convert a string value to a dollar quoted literal and append it to
+  * the given buffer. If the dqprefix parameter is not NULL then the 
+  * dollar quote delimiter will begin with that (after the opening $).
+  *
+  * No escaping is done at all on str, in compliance with the rules
+  * for parsing dollar quoted strings.
+  */
+ void
+ appendStringLiteralDQ(PQExpBuffer buf, const char *str, const char *dqprefix)
+ {
+   static char suffixes[] = "_";
+   int nextchar = 0;
+   PQExpBuffer delimBuf = createPQExpBuffer();
+ 
+   /* start with $ + dqprefix if not NULL */
+   appendPQExpBufferChar(delimBuf, '$');
+   if (dqprefix)
+   appendPQExpBuffer(delimBuf, dqprefix);
+ 
+   /* 
+* make sure we have a delimiter which (without the trailing $)
+* is not preent in the string being quoted. We don't check with the
+* trailing $ so that a string ending in $foo is not quoted with
+* $foo$.
+*/
+   while (strstr(str, delimBuf->data) != NULL)
+   {
+   appendPQExpBufferChar(delimBuf, suffixes[nextchar++]);
+   nextchar %= sizeof(suffixes)-1;
+   }
+ 
+   /* add trailing $ */
+   appendPQExpBufferChar(delimBuf, '$');
+ 
+   /* quote it and we are all done */
+   appendPQExpBuffer(buf,"%s%s%s",delimBuf->data,str,delimBuf->data);
+   destroyPQExpBuffer(delimBuf);
+   
+ }
+ 
+ /*
+  * use dollar quoting if the string to be quoted contains ' or \,
+  * otherwise use standard quoting.
+  */
+ 
+ 
+ void appendStringLiteralDQFallback(PQExpBuffer buf, const char *str, 
+   bool escapeAll, const char *dqprefix)
+ {
+   if (strchr(str,'\'') == NULL && strchr(str,'\\') == NULL)
+   appendStringLiteral(buf,str,escapeAll);
+   else
+   appendStringLiteralDQ(buf,str,dqprefix);
+ }
+ 
+ 
+ /*
   * Convert backend's version string into a number.
   */
  int
Index: src/bin/pg_dump/dumputils.h
===
RCS file: /projects/cvsroot/pgsql-server/src/bin/pg_dump/dumputils.h,v
retrieving revision 1.10
diff -c -r1.10 dumputils.h
*** src/bin/pg_dump/dumputils.h 7 Jan 2004 00:44:21 -   1.10
--- src/bin/pg_dump/dumputils.h 23 Mar 2004 19