postgresql.diffs

text/plain

Filename: postgresql.diffs
Type: text/plain
Part: 0
Message: Re: [GENERAL] Some questions on user defined types and functions.
*** src/backend/commands/define.c.orig	Wed Jul 26 11:50:40 2000
--- src/backend/commands/define.c	Thu Jul 27 10:50:59 2000
***************
*** 182,194 ****
--- 182,204 ----
  interpret_AS_clause(const char *languageName, const List *as,
  					char **prosrc_str_p, char **probin_str_p)
  {
+ #if 0
  	struct stat stat_buf;
+ #endif
  
  	Assert(as != NIL);
  
  	if (strcmp(languageName, "C") == 0)
  	{
  
+ #if 0
+ 		/*
+ 		 * It seems like you should be able to use a file that doesn't currently
+ 		 * exist yet.  It only matters if the file exists when it is used.
+ 		 * Also, if there is an environment variable in the pathname, doing the
+ 		 * stat early might prevent the path from being inserted.
+ 		 */
+ 
  		/*
  		 * For "C" language, store the file name in probin and, when
  		 * given, the link symbol name in prosrc. But first, stat the
***************
*** 197,203 ****
  		
  		if (stat(strVal(lfirst(as)), &stat_buf) == -1)
  				elog(ERROR, "stat failed on file '%s': %m", strVal(lfirst(as)));
! 
  		*probin_str_p = strVal(lfirst(as));
  
  		if (lnext(as) == NULL)
--- 207,213 ----
  		
  		if (stat(strVal(lfirst(as)), &stat_buf) == -1)
  				elog(ERROR, "stat failed on file '%s': %m", strVal(lfirst(as)));
! #endif
  		*probin_str_p = strVal(lfirst(as));
  
  		if (lnext(as) == NULL)
*** src/backend/utils/fmgr/dfmgr.c.orig	Wed Apr 12 13:15:57 2000
--- src/backend/utils/fmgr/dfmgr.c	Thu Jul 27 10:28:49 2000
***************
*** 36,41 ****
--- 36,42 ----
  static int	pronargs_save;
  static func_ptr user_fn_save = (func_ptr) NULL;
  static func_ptr handle_load(char *filename, char *funcname);
+ static int expand_filename(char *orig, char *new, int size);
  
  func_ptr
  fmgr_dynamic(Oid procedureId, int *pronargs)
***************
*** 51,56 ****
--- 52,59 ----
  	func_ptr	user_fn;
  	Relation	rel;
  	bool		isnull;
+ 	char		filebuf[PATH_MAX];
+ 	char		*file_p;
  
  	/* Implement simple one-element cache for function lookups */
  	if (procedureId == procedureId_save)
***************
*** 120,126 ****
  
  	heap_close(rel, AccessShareLock);
  
! 	user_fn = handle_load(probinstring, linksymbol);
  
  	pfree(probinstring);
  	if (prosrcstring)
--- 123,138 ----
  
  	heap_close(rel, AccessShareLock);
  
! 	/* Expand any environment variables in the file name. */
! 	if (strchr(probinstring, '$') != NULL) {
! 		if (!expand_filename(probinstring, filebuf, sizeof(filebuf)))
! 			elog(ERROR, "LOAD: could not expand file '%s': %m", probinstring);
! 		file_p = filebuf;
! 	}
! 	else
! 		file_p = probinstring;
! 
! 	user_fn = handle_load(file_p, linksymbol);
  
  	pfree(probinstring);
  	if (prosrcstring)
***************
*** 252,266 ****
  {
  	DynamicFileList *file_scanner,
  			   *p;
  	struct stat stat_buf;
  	int			done = 0;
  
  	/*
  	 * We need to do stat() in order to determine whether this is the same
  	 * file as a previously loaded file; it's also handy so as to give a
  	 * good error message if bogus file name given.
  	 */
! 	if (stat(filename, &stat_buf) == -1)
  		elog(ERROR, "LOAD: could not open file '%s': %m", filename);
  
  	if (file_list != (DynamicFileList *) NULL
--- 264,290 ----
  {
  	DynamicFileList *file_scanner,
  			   *p;
+ 	char		filebuf[PATH_MAX];
+ 	char		*file_p;
  	struct stat stat_buf;
  	int			done = 0;
  
+ 	/* Expand any environment variables in the file name. */
+ 	if (strchr(filename, '$') != NULL) {
+ 		if (!expand_filename(filename, filebuf, sizeof(filebuf)))
+ 			elog(ERROR, "LOAD: could not expand file '%s': %m", filename);
+ 		file_p = filebuf;
+ 		elog(NOTICE, "Expanded [%s] to [%s]", filename, file_p);
+ 	}
+ 	else
+ 		file_p = filename;
+ 
  	/*
  	 * We need to do stat() in order to determine whether this is the same
  	 * file as a previously loaded file; it's also handy so as to give a
  	 * good error message if bogus file name given.
  	 */
! 	if (stat(file_p, &stat_buf) == -1)
  		elog(ERROR, "LOAD: could not open file '%s': %m", filename);
  
  	if (file_list != (DynamicFileList *) NULL
***************
*** 292,298 ****
  			free((char *) p);
  		}
  	}
! 	handle_load(filename, (char *) NULL);
  }
  
  /* Is this used? bjm 1998/10/08   No. tgl 1999/02/07 */
--- 316,322 ----
  			free((char *) p);
  		}
  	}
! 	handle_load(file_p, (char *) NULL);
  }
  
  /* Is this used? bjm 1998/10/08   No. tgl 1999/02/07 */
***************
*** 308,310 ****
--- 332,411 ----
  }
  
  #endif
+ 
+ /*
+  * The filename has one or more environment variables.  Attempt to expand all
+  * of the environment variables to build an absolute path.
+  */
+ 
+ static int
+ expand_filename(char *orig, char *new, int size)
+ {
+ 	char	*copy;
+ 	char	*start;
+ 	char	*env_ptr;
+ 	char	env_var[MAXPGPATH];
+ 	char	*env_setting;
+ 	int		i;
+ 
+ 	/* Clear the 'new' pathname. */
+ 	*new = '\0';
+ 
+ 	/* Copy the string so it can be safely hacked */
+ 	copy = pstrdup(orig);
+ 
+ 	/* Walk the path while expanding the environment variables. */
+ 	start = copy;
+ 	while (strlen(start) > 0) {
+ 
+ 		/* Find the start of the next environment variable in the path. */
+ 		if ((env_ptr = strchr(start, '$')) != NULL) {
+ 			*env_ptr = '\0';
+ 
+ 			/* Append everything before the environment variable. */
+ 			if ((strlen(new) + strlen(start) + 1) > size) {
+ 				pfree(copy);
+ 				return(0);
+ 			}
+ 			strcat(new, start);
+ 			
+ 			/* Copy the environment variable to its own string. */
+ 			env_ptr++;
+ 			i = 0;
+ 			while (*env_ptr != '\0' && *env_ptr != '/') {
+ 				env_var[i] = *env_ptr;
+ 				env_ptr++;
+ 				i++;
+ 			}
+ 			env_var[i] = '\0';
+ 			start = env_ptr;
+ 
+ 			/* Translate the environment variable. */
+ 			if ((env_setting = getenv(env_var)) == NULL) {
+ 				pfree(copy);
+ 				return(0);
+ 			}
+ 
+ 			/* Add the environment variable to the path. */
+ 			if ((strlen(new) + strlen(env_setting) + 1) > size) {
+ 				pfree(copy);
+ 				return(0);
+ 			}
+ 			strcat(new, env_setting);
+ 		}
+ 
+ 		/*
+ 		 * No environment variables left in the path.  So append the rest of
+ 		 * the path and exit the loop.
+ 		 */
+ 		else {
+ 			if ((strlen(new) + strlen(start) + 1) > size) {
+ 				pfree(copy);
+ 				return(0);
+ 			}
+ 			strcat(new, start);
+ 			break;
+ 		}
+ 	}
+ 	return(1);
+ }
*** doc/src/sgml/dfunc.sgml.orig	Thu Jul 27 10:32:36 2000
--- doc/src/sgml/dfunc.sgml	Thu Jul 27 10:40:25 2000
***************
*** 96,105 ****
     <itemizedlist>
      <listitem>
       <para>
!       Paths  given  to the create function command must be
        absolute paths (i.e., start with "/") that refer  to
        directories  visible  on  the  machine  on which the
        <productname>Postgres</productname> server is running.
  
        <tip>
         <para>
--- 96,113 ----
     <itemizedlist>
      <listitem>
       <para>
!       Paths  given  to the create function command must expand to
        absolute paths (i.e., start with "/") that refer  to
        directories  visible  on  the  machine  on which the
        <productname>Postgres</productname> server is running.
+ 	  </para>
+ 	 <para>
+ 	  Environment variables in the path will be expanded by the
+ 	  <productname>Postgres</productname> server.  The environment
+ 	  variables are interpreted in the context of the server, so make
+ 	  sure the server has the appropriate environment variables set
+ 	  correctly.
+ 	  </para>
  
        <tip>
         <para>
*** doc/src/sgml/ref/create_function.sgml.orig	Thu Jul 27 10:40:56 2000
--- doc/src/sgml/ref/create_function.sgml	Thu Jul 27 10:49:32 2000
***************
*** 117,123 ****
  	containing the dynamically loadable object, and <replaceable
  	class="parameter">link_symbol</replaceable>, is the object's link
  	symbol which is the same as the name of the function in the C
! 	language source code.
         </para>
        </listitem>
       </varlistentry>
--- 117,126 ----
  	containing the dynamically loadable object, and <replaceable
  	class="parameter">link_symbol</replaceable>, is the object's link
  	symbol which is the same as the name of the function in the C
! 	language source code. <productname>Postgres</productname> will
! 	automatically expand environment variables in <replaceable
! 	class="parameter">obj_file</replaceable>.  The expansion is done using
! 	the <productname>Postgres</productname> server's environment.
         </para>
        </listitem>
       </varlistentry>