Index: doc/src/sgml/ref/pg_restore.sgml
===================================================================
RCS file: /cvsroot/pgsql/doc/src/sgml/ref/pg_restore.sgml,v
retrieving revision 1.25
diff -c -r1.25 pg_restore.sgml
*** doc/src/sgml/ref/pg_restore.sgml	10 May 2002 22:36:26 -0000	1.25
--- doc/src/sgml/ref/pg_restore.sgml	4 Jul 2002 02:56:19 -0000
***************
*** 33,39 ****
     <arg> -L <replaceable class="parameter">contents-file</replaceable> </arg>
     <group> <arg> -N </arg> <arg> -o </arg> <arg> -r </arg> </group>
     <arg> -O </arg>
!    <arg> -P <replaceable class="parameter">function-name</replaceable> </arg>
     <arg> -R </arg>
     <arg> -s </arg>
     <arg> -S </arg>
--- 33,39 ----
     <arg> -L <replaceable class="parameter">contents-file</replaceable> </arg>
     <group> <arg> -N </arg> <arg> -o </arg> <arg> -r </arg> </group>
     <arg> -O </arg>
!    <arg> -P <replaceable class="parameter">function-name(argtype [, ...])</replaceable> </arg>
     <arg> -R </arg>
     <arg> -s </arg>
     <arg> -S </arg>
***************
*** 276,283 ****
       </varlistentry>
  
       <varlistentry>
!       <term><option>-P <replaceable class="parameter">function-name</replaceable></option></term>
!       <term><option>--function=<replaceable class="parameter">function-name</replaceable></option></term>
        <listitem>
         <para>
          Specify a procedure or function to be restored.
--- 276,283 ----
       </varlistentry>
  
       <varlistentry>
!       <term><option>-P <replaceable class="parameter">function-name(argtype [, ...])</replaceable></option></term>
!       <term><option>--function=<replaceable class="parameter">function-name(argtype [, ...])</replaceable></option></term>
        <listitem>
         <para>
          Specify a procedure or function to be restored.
Index: src/bin/pg_dump/pg_backup_archiver.c
===================================================================
RCS file: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.c,v
retrieving revision 1.50
diff -c -r1.50 pg_backup_archiver.c
*** src/bin/pg_dump/pg_backup_archiver.c	2 Jul 2002 05:49:51 -0000	1.50
--- src/bin/pg_dump/pg_backup_archiver.c	4 Jul 2002 02:56:21 -0000
***************
*** 191,196 ****
--- 191,197 ----
  	 * initially connected to, not the one we will create, which is very
  	 * bad...
  	 */
+ 
  	if (ropt->create && ropt->noReconnect)
  		die_horribly(AH, modulename, "-C and -R are incompatible options\n");
  
Index: src/bin/pg_dump/pg_dump.c
===================================================================
RCS file: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v
retrieving revision 1.268
diff -c -r1.268 pg_dump.c
*** src/bin/pg_dump/pg_dump.c	2 Jul 2002 05:49:51 -0000	1.268
--- src/bin/pg_dump/pg_dump.c	4 Jul 2002 02:56:24 -0000
***************
*** 104,117 ****
  static void dumpFuncACL(Archive *fout, FuncInfo *finfo);
  static void dumpAggACL(Archive *fout, AggInfo *finfo);
  static void dumpACL(Archive *fout, const char *type, const char *name,
! 					const char *nspname, const char *usename,
! 					const char *acl, const char *objoid);
  
  static void dumpTriggers(Archive *fout, TableInfo *tblinfo, int numTables);
  static void dumpRules(Archive *fout, TableInfo *tblinfo, int numTables);
  static void formatStringLiteral(PQExpBuffer buf, const char *str,
  								const formatLiteralOptions opts);
! static char *format_function_signature(FuncInfo *finfo);
  static void dumpOneFunc(Archive *fout, FuncInfo *finfo);
  static void dumpOneOpr(Archive *fout, OprInfo *oprinfo,
  					   OprInfo *g_oprinfo, int numOperators);
--- 104,117 ----
  static void dumpFuncACL(Archive *fout, FuncInfo *finfo);
  static void dumpAggACL(Archive *fout, AggInfo *finfo);
  static void dumpACL(Archive *fout, const char *type, const char *name,
! 					const char *name_noquotes, const char *nspname,
! 					const char *usename, const char *acl, const char *objoid);
  
  static void dumpTriggers(Archive *fout, TableInfo *tblinfo, int numTables);
  static void dumpRules(Archive *fout, TableInfo *tblinfo, int numTables);
  static void formatStringLiteral(PQExpBuffer buf, const char *str,
  								const formatLiteralOptions opts);
! static char *format_function_signature(FuncInfo *finfo, bool honor_quotes);
  static void dumpOneFunc(Archive *fout, FuncInfo *finfo);
  static void dumpOneOpr(Archive *fout, OprInfo *oprinfo,
  					   OprInfo *g_oprinfo, int numOperators);
***************
*** 2721,2727 ****
  		if (strcmp(nspinfo->nspname, "public") == 0)
  		{
  			if (!aclsSkip && strcmp(nspinfo->nspacl, "{=UC}") != 0)
! 				dumpACL(fout, "SCHEMA", qnspname, NULL,
  						nspinfo->usename, nspinfo->nspacl,
  						nspinfo->oid);
  		}
--- 2721,2727 ----
  		if (strcmp(nspinfo->nspname, "public") == 0)
  		{
  			if (!aclsSkip && strcmp(nspinfo->nspacl, "{=UC}") != 0)
! 				dumpACL(fout, "SCHEMA", qnspname, nspinfo->nspname, NULL,
  						nspinfo->usename, nspinfo->nspacl,
  						nspinfo->oid);
  		}
***************
*** 2747,2753 ****
  						nspinfo->oid, "pg_namespace", 0, NULL);
  
  			if (!aclsSkip)
! 				dumpACL(fout, "SCHEMA", qnspname, NULL,
  						nspinfo->usename, nspinfo->nspacl,
  						nspinfo->oid);
  		}
--- 2747,2753 ----
  						nspinfo->oid, "pg_namespace", 0, NULL);
  
  			if (!aclsSkip)
! 				dumpACL(fout, "SCHEMA", qnspname, nspinfo->nspname, NULL,
  						nspinfo->usename, nspinfo->nspacl,
  						nspinfo->oid);
  		}
***************
*** 3291,3298 ****
  
  		if (!aclsSkip)
  		{
! 			char * tmp = strdup(fmtId(lanname, force_quotes));
! 			dumpACL(fout, "LANGUAGE", tmp, finfo[fidx].pronamespace->nspname,
  					NULL, lanacl, lanoid);
  			free(tmp);
  		}
--- 3291,3299 ----
  
  		if (!aclsSkip)
  		{
! 			char *tmp = strdup(fmtId(lanname, force_quotes));
! 			dumpACL(fout, "LANGUAGE", tmp, lanname,
! 					finfo[fidx].pronamespace->nspname,
  					NULL, lanacl, lanoid);
  			free(tmp);
  		}
***************
*** 3333,3345 ****
   * is never qualified.
   */
  static char *
! format_function_signature(FuncInfo *finfo)
  {
  	PQExpBufferData fn;
  	int			j;
  
  	initPQExpBuffer(&fn);
! 	appendPQExpBuffer(&fn, "%s (", fmtId(finfo->proname, force_quotes));
  	for (j = 0; j < finfo->nargs; j++)
  	{
  		char	   *typname;
--- 3334,3349 ----
   * is never qualified.
   */
  static char *
! format_function_signature(FuncInfo *finfo, bool honor_quotes)
  {
  	PQExpBufferData fn;
  	int			j;
  
  	initPQExpBuffer(&fn);
! 	if (honor_quotes)
! 		appendPQExpBuffer(&fn, "%s(", fmtId(finfo->proname, force_quotes));
! 	else
! 		appendPQExpBuffer(&fn, "%s(", finfo->proname);
  	for (j = 0; j < finfo->nargs; j++)
  	{
  		char	   *typname;
***************
*** 3358,3369 ****
  static void
  dumpFuncACL(Archive *fout, FuncInfo *finfo)
  {
! 	char *funcsig;
  
! 	funcsig = format_function_signature(finfo);
! 	dumpACL(fout, "FUNCTION", funcsig, finfo->pronamespace->nspname,
  			finfo->usename, finfo->proacl, finfo->oid);
  	free(funcsig);
  }
  
  
--- 3362,3376 ----
  static void
  dumpFuncACL(Archive *fout, FuncInfo *finfo)
  {
! 	char *funcsig, *funcsig_noquotes;
  
! 	funcsig = format_function_signature(finfo, true);
! 	funcsig_noquotes = format_function_signature(finfo, false);
! 	dumpACL(fout, "FUNCTION", funcsig, funcsig_noquotes,
! 			finfo->pronamespace->nspname,
  			finfo->usename, finfo->proacl, finfo->oid);
  	free(funcsig);
+ 	free(funcsig_noquotes);
  }
  
  
***************
*** 3380,3385 ****
--- 3387,3393 ----
  	PQExpBuffer asPart = createPQExpBuffer();
  	PGresult   *res = NULL;
  	char	   *funcsig = NULL;
+ 	char	   *funcsig_noquotes = NULL;
  	int			ntups;
  	char	   *proretset;
  	char	   *prosrc;
***************
*** 3487,3493 ****
  		}
  	}
  
! 	funcsig = format_function_signature(finfo);
  
  	/* DROP must be fully qualified in case same name appears in pg_catalog */
  	appendPQExpBuffer(delqry, "DROP FUNCTION %s.%s;\n",
--- 3495,3502 ----
  		}
  	}
  
! 	funcsig = format_function_signature(finfo, true);
! 	funcsig_noquotes = format_function_signature(finfo, false);
  
  	/* DROP must be fully qualified in case same name appears in pg_catalog */
  	appendPQExpBuffer(delqry, "DROP FUNCTION %s.%s;\n",
***************
*** 3517,3523 ****
  					  finfo->proname);
  			exit_nicely();
  		}
! 	}	
  
  	if (proimplicit[0] == 't')
  		appendPQExpBuffer(q, " IMPLICIT CAST");
--- 3526,3532 ----
  					  finfo->proname);
  			exit_nicely();
  		}
! 	}
  
  	if (proimplicit[0] == 't')
  		appendPQExpBuffer(q, " IMPLICIT CAST");
***************
*** 3530,3536 ****
  
  	appendPQExpBuffer(q, ";\n");
  
! 	ArchiveEntry(fout, finfo->oid, funcsig, finfo->pronamespace->nspname,
  				 finfo->usename, "FUNCTION", NULL,
  				 q->data, delqry->data,
  				 NULL, NULL, NULL);
--- 3539,3546 ----
  
  	appendPQExpBuffer(q, ";\n");
  
! 	ArchiveEntry(fout, finfo->oid, funcsig_noquotes,
! 				 finfo->pronamespace->nspname,
  				 finfo->usename, "FUNCTION", NULL,
  				 q->data, delqry->data,
  				 NULL, NULL, NULL);
***************
*** 3551,3556 ****
--- 3561,3567 ----
  	destroyPQExpBuffer(delqry);
  	destroyPQExpBuffer(asPart);
  	free(funcsig);
+ 	free(funcsig_noquotes);
  }
  
  /*
***************
*** 3939,3952 ****
   * is never qualified.
   */
  static char *
! format_aggregate_signature(AggInfo *agginfo, Archive *fout)
  {
  	PQExpBufferData buf;
  	bool anybasetype;
  
  	initPQExpBuffer(&buf);
! 	appendPQExpBuffer(&buf, "%s",
  					  fmtId(agginfo->aggname, force_quotes));
  
  	anybasetype = (strcmp(agginfo->aggbasetype, "0") == 0);
  
--- 3950,3966 ----
   * is never qualified.
   */
  static char *
! format_aggregate_signature(AggInfo *agginfo, Archive *fout, bool honor_quotes)
  {
  	PQExpBufferData buf;
  	bool anybasetype;
  
  	initPQExpBuffer(&buf);
! 	if (honor_quotes)
! 		appendPQExpBuffer(&buf, "%s",
  					  fmtId(agginfo->aggname, force_quotes));
+ 	else
+ 		appendPQExpBuffer(&buf, "%s", agginfo->aggname);
  
  	anybasetype = (strcmp(agginfo->aggbasetype, "0") == 0);
  
***************
*** 3974,3985 ****
  static void
  dumpAggACL(Archive *fout, AggInfo *finfo)
  {
! 	char *aggsig;
  
! 	aggsig = format_aggregate_signature(finfo, fout);
! 	dumpACL(fout, "FUNCTION", aggsig, finfo->aggnamespace->nspname,
  			finfo->usename, finfo->aggacl, finfo->oid);
  	free(aggsig);
  }
  
  
--- 3988,4002 ----
  static void
  dumpAggACL(Archive *fout, AggInfo *finfo)
  {
! 	char *aggsig, *aggsig_noquotes;
  
! 	aggsig = format_aggregate_signature(finfo, fout, true);
! 	aggsig_noquotes = format_aggregate_signature(finfo, fout, false);
! 	dumpACL(fout, "FUNCTION", aggsig, aggsig_noquotes,
! 			finfo->aggnamespace->nspname,
  			finfo->usename, finfo->aggacl, finfo->oid);
  	free(aggsig);
+ 	free(aggsig_noquotes);
  }
  
  
***************
*** 3994,4000 ****
  	PQExpBuffer q = createPQExpBuffer();
  	PQExpBuffer delq = createPQExpBuffer();
  	PQExpBuffer details = createPQExpBuffer();
! 	char	   *aggSig;
  	PGresult   *res;
  	int			ntups;
  	int			i_aggtransfn;
--- 4011,4018 ----
  	PQExpBuffer q = createPQExpBuffer();
  	PQExpBuffer delq = createPQExpBuffer();
  	PQExpBuffer details = createPQExpBuffer();
! 	char	   *aggsig;
! 	char	   *aggsig_noquotes;
  	PGresult   *res;
  	int			ntups;
  	int			i_aggtransfn;
***************
*** 4084,4099 ****
  	agginfo->fmtbasetype = strdup(PQgetvalue(res, 0, i_fmtbasetype));
  	convertok = (PQgetvalue(res, 0, i_convertok)[0] == 't');
  
! 	aggSig = format_aggregate_signature(agginfo, g_fout);
  
  	if (!convertok)
  	{
  		write_msg(NULL, "WARNING: aggregate function %s could not be dumped correctly for this database version; ignored\n",
! 				  aggSig);
  
  		appendPQExpBuffer(q, "-- WARNING: aggregate function %s could not be dumped correctly for this database version; ignored\n",
! 						  aggSig);
! 		ArchiveEntry(fout, agginfo->oid, aggSig,
  					 agginfo->aggnamespace->nspname, agginfo->usename,
  					 "WARNING", NULL,
  					 q->data, "" /* Del */ ,
--- 4102,4118 ----
  	agginfo->fmtbasetype = strdup(PQgetvalue(res, 0, i_fmtbasetype));
  	convertok = (PQgetvalue(res, 0, i_convertok)[0] == 't');
  
! 	aggsig = format_aggregate_signature(agginfo, g_fout, true);
!  	aggsig_noquotes = format_aggregate_signature(agginfo, g_fout, false);
  
  	if (!convertok)
  	{
  		write_msg(NULL, "WARNING: aggregate function %s could not be dumped correctly for this database version; ignored\n",
! 				  aggsig);
  
  		appendPQExpBuffer(q, "-- WARNING: aggregate function %s could not be dumped correctly for this database version; ignored\n",
! 						  aggsig);
! 		ArchiveEntry(fout, agginfo->oid, aggsig_noquotes,
  					 agginfo->aggnamespace->nspname, agginfo->usename,
  					 "WARNING", NULL,
  					 q->data, "" /* Del */ ,
***************
*** 4146,4158 ****
  	/* DROP must be fully qualified in case same name appears in pg_catalog */
  	appendPQExpBuffer(delq, "DROP AGGREGATE %s.%s;\n",
  					  fmtId(agginfo->aggnamespace->nspname, force_quotes),
! 					  aggSig);
  
  	appendPQExpBuffer(q, "CREATE AGGREGATE %s ( %s );\n",
  					  fmtId(agginfo->aggname, force_quotes),
  					  details->data);
  
! 	ArchiveEntry(fout, agginfo->oid, aggSig,
  				 agginfo->aggnamespace->nspname, agginfo->usename,
  				 "AGGREGATE", NULL,
  				 q->data, delq->data,
--- 4165,4177 ----
  	/* DROP must be fully qualified in case same name appears in pg_catalog */
  	appendPQExpBuffer(delq, "DROP AGGREGATE %s.%s;\n",
  					  fmtId(agginfo->aggnamespace->nspname, force_quotes),
! 					  aggsig);
  
  	appendPQExpBuffer(q, "CREATE AGGREGATE %s ( %s );\n",
  					  fmtId(agginfo->aggname, force_quotes),
  					  details->data);
  
! 	ArchiveEntry(fout, agginfo->oid, aggsig_noquotes,
  				 agginfo->aggnamespace->nspname, agginfo->usename,
  				 "AGGREGATE", NULL,
  				 q->data, delq->data,
***************
*** 4161,4167 ****
  	/*** Dump Aggregate Comments ***/
  
  	resetPQExpBuffer(q);
! 	appendPQExpBuffer(q, "AGGREGATE %s", aggSig);
  	if (g_fout->remoteVersion >= 70300)
  		dumpComment(fout, q->data,
  					agginfo->aggnamespace->nspname, agginfo->usename,
--- 4180,4186 ----
  	/*** Dump Aggregate Comments ***/
  
  	resetPQExpBuffer(q);
! 	appendPQExpBuffer(q, "AGGREGATE %s", aggsig);
  	if (g_fout->remoteVersion >= 70300)
  		dumpComment(fout, q->data,
  					agginfo->aggnamespace->nspname, agginfo->usename,
***************
*** 4177,4183 ****
  	destroyPQExpBuffer(q);
  	destroyPQExpBuffer(delq);
  	destroyPQExpBuffer(details);
! 	free(aggSig);
  }
  
  
--- 4196,4203 ----
  	destroyPQExpBuffer(q);
  	destroyPQExpBuffer(delq);
  	destroyPQExpBuffer(details);
! 	free(aggsig);
! 	free(aggsig_noquotes);
  }
  
  
***************
*** 4276,4282 ****
   */
  static void
  dumpACL(Archive *fout, const char *type, const char *name,
! 		const char *nspname, const char *usename,
  		const char *acls, const char *objoid)
  {
  	char	   *aclbuf,
--- 4296,4302 ----
   */
  static void
  dumpACL(Archive *fout, const char *type, const char *name,
! 		const char *name_noquotes, const char *nspname, const char *usename,
  		const char *acls, const char *objoid)
  {
  	char	   *aclbuf,
***************
*** 4390,4396 ****
  		appendPQExpBuffer(sql, "%s;\n", fmtId(usename, force_quotes));
  	}
  
! 	ArchiveEntry(fout, objoid, name, nspname, usename ? usename : "",
  				 "ACL", NULL, sql->data, "", NULL, NULL, NULL);
  
  	free(aclbuf);
--- 4410,4416 ----
  		appendPQExpBuffer(sql, "%s;\n", fmtId(usename, force_quotes));
  	}
  
! 	ArchiveEntry(fout, objoid, name_noquotes, nspname, usename ? usename : "",
  				 "ACL", NULL, sql->data, "", NULL, NULL, NULL);
  
  	free(aclbuf);
***************
*** 4401,4409 ****
  static void
  dumpTableACL(Archive *fout, TableInfo *tbinfo)
  {
! 	char * tmp = strdup( fmtId(tbinfo->relname, force_quotes) );
! 	dumpACL(fout, "TABLE", tmp, tbinfo->relnamespace->nspname,
! 			tbinfo->usename, tbinfo->relacl,
  			tbinfo->viewoid != NULL ? tbinfo->viewoid : tbinfo->oid);
  	free(tmp);
  }
--- 4421,4429 ----
  static void
  dumpTableACL(Archive *fout, TableInfo *tbinfo)
  {
! 	char *tmp = strdup(fmtId(tbinfo->relname, force_quotes));
! 	dumpACL(fout, "TABLE", tmp, tbinfo->relname,
! 			tbinfo->relnamespace->nspname, tbinfo->usename, tbinfo->relacl,
  			tbinfo->viewoid != NULL ? tbinfo->viewoid : tbinfo->oid);
  	free(tmp);
  }
***************
*** 5793,5812 ****
  							  precision, scale);
  		}
  	}
- 
  	/*
  	 * char is an internal single-byte data type; Let's make sure we force
  	 * it through with quotes. - thomas 1998-12-13
  	 */
  	else if (!strcmp(typname, "char"))
  	{
! 		appendPQExpBuffer(buf, "%s",
! 						  fmtId(typname, true));
  	}
  	else
  	{
! 		appendPQExpBuffer(buf, "%s",
! 						  fmtId(typname, false));
  	}
  
  	result = strdup(buf->data);
--- 5813,5829 ----
  							  precision, scale);
  		}
  	}
  	/*
  	 * char is an internal single-byte data type; Let's make sure we force
  	 * it through with quotes. - thomas 1998-12-13
  	 */
  	else if (!strcmp(typname, "char"))
  	{
! 		appendPQExpBuffer(buf, "%s", fmtId(typname, true));
  	}
  	else
  	{
! 		appendPQExpBuffer(buf, "%s", fmtId(typname, false));
  	}
  
  	result = strdup(buf->data);
Index: src/bin/pg_dump/pg_restore.c
===================================================================
RCS file: /cvsroot/pgsql/src/bin/pg_dump/pg_restore.c,v
retrieving revision 1.34
diff -c -r1.34 pg_restore.c
*** src/bin/pg_dump/pg_restore.c	10 May 2002 22:36:27 -0000	1.34
--- src/bin/pg_dump/pg_restore.c	4 Jul 2002 02:56:25 -0000
***************
*** 65,70 ****
--- 65,71 ----
  /* Forward decls */
  static void usage(const char *progname);
  static char *_cleanupName(char *name);
+ static char *_cleanupFuncName(char *name);
  
  typedef struct option optType;
  
***************
*** 220,226 ****
  			case 'P':			/* Function */
  				opts->selTypes = 1;
  				opts->selFunction = 1;
! 				opts->functionNames = optarg ? strdup(optarg) : NULL;
  				break;
  			case 'I':			/* Index */
  				opts->selTypes = 1;
--- 221,227 ----
  			case 'P':			/* Function */
  				opts->selTypes = 1;
  				opts->selFunction = 1;
! 				opts->functionNames = _cleanupFuncName(optarg);
  				break;
  			case 'I':			/* Index */
  				opts->selTypes = 1;
***************
*** 392,398 ****
  		"  -O, --no-owner           do not reconnect to database to match\n"
  		"                           object owner\n"
  		"  -p, --port=PORT          server port number\n"
! 		"  -P, --function=NAME      restore named function\n"
  		"  -r, --rearrange          rearrange output to put indexes etc. at end\n"
  		"  -R, --no-reconnect       disallow ALL reconnections to the database\n"
  		"  -s, --schema-only        restore only the schema, no data\n"
--- 393,399 ----
  		"  -O, --no-owner           do not reconnect to database to match\n"
  		"                           object owner\n"
  		"  -p, --port=PORT          server port number\n"
! 		"  -P, --function=NAME(args)restore named function\n"
  		"  -r, --rearrange          rearrange output to put indexes etc. at end\n"
  		"  -R, --no-reconnect       disallow ALL reconnections to the database\n"
  		"  -s, --schema-only        restore only the schema, no data\n"
***************
*** 430,436 ****
  		"  -O                       do not reconnect to database to match\n"
  		"                           object owner\n"
  		"  -p PORT                  server port number\n"
! 		"  -P NAME                  restore named function\n"
  		"  -r                       rearrange output to put indexes etc. at end\n"
  		"  -R                       disallow ALL reconnections to the database\n"
  		"  -s                       restore only the schema, no data\n"
--- 431,437 ----
  		"  -O                       do not reconnect to database to match\n"
  		"                           object owner\n"
  		"  -p PORT                  server port number\n"
! 		"  -P NAME(args)            restore named function\n"
  		"  -r                       rearrange output to put indexes etc. at end\n"
  		"  -R                       disallow ALL reconnections to the database\n"
  		"  -s                       restore only the schema, no data\n"
***************
*** 476,480 ****
--- 477,529 ----
  			if (isupper((unsigned char) name[i]))
  				name[i] = tolower((unsigned char) name[i]);
  	}
+ 	return name;
+ }
+ 
+ 
+ static char *
+ _cleanupFuncName(char *name)
+ {
+ 	int			i;
+ 	char		*ch;
+ 	
+ 	if (!name || !name[0])
+ 		return NULL;
+ 
+ 	name = strdup(name);
+ 
+ 	if (name[0] == '"')
+ 	{
+ 		strcpy(name, &name[1]);
+ 		if (strchr(name, '"') != NULL)
+ 			strcpy(strchr(name, '"'), strchr(name, '"')+1);
+ 	}
+ 	/* otherwise, convert function name to lowercase... */
+ 	else
+ 	{
+ 		for (i = 0; name[i]; i++)
+ 			if (isupper((unsigned char) name[i]))
+ 				name[i] = tolower((unsigned char) name[i]);
+ 	}
+ 
+ 	/* strip out any space before paren */
+ 	ch = strchr(name,'(');
+ 	while (ch && ch > name && *(ch-1) == ' ')
+ 	{
+ 		strcpy(ch - 1, ch);
+ 		ch--;
+ 	}
+ 
+ 	/*
+ 	 *	Strip out spaces after commas in parameter list.
+ 	 * 	We can't remove all spaces because some types, like
+ 	 *	'double precision' have spaces.
+ 	 */
+ 	if ((ch = strchr(name,'(')) != NULL)
+ 	{
+ 		while ((ch = strstr(ch,", ")) != NULL)
+ 			strcpy(ch + 1, ch + 2);
+ 	}
+ 
  	return name;
  }
