Index: doc/src/sgml/ref/initdb.sgml
===================================================================
RCS file: /a/pgsql/dev/anoncvs/pgsql/doc/src/sgml/ref/initdb.sgml,v
retrieving revision 1.43
diff -c -r1.43 initdb.sgml
*** doc/src/sgml/ref/initdb.sgml	26 Mar 2007 17:23:36 -0000	1.43
--- doc/src/sgml/ref/initdb.sgml	10 Aug 2008 01:04:06 -0000
***************
*** 175,180 ****
--- 175,191 ----
         </para>
        </listitem>
       </varlistentry>
+   
+        <varlistentry>
+         <term><option>-S <replaceable class="parameter">directory</replaceable></option></term>
+         <term><option>--statdir=<replaceable class="parameter">directory</replaceable></option></term>
+         <listitem>
+          <para>
+           This option specifies the directory where the temporary statistics
+           should be stored.
+          </para>
+         </listitem>
+        </varlistentry>
  
       <varlistentry>
        <term><option>-X <replaceable class="parameter">directory</replaceable></option></term>
Index: src/bin/initdb/initdb.c
===================================================================
RCS file: /a/pgsql/dev/anoncvs/pgsql/src/bin/initdb/initdb.c,v
retrieving revision 1.159
diff -c -r1.159 initdb.c
*** src/bin/initdb/initdb.c	5 Aug 2008 12:09:30 -0000	1.159
--- src/bin/initdb/initdb.c	8 Aug 2008 18:34:57 -0000
***************
*** 91,96 ****
--- 91,97 ----
  static bool noclean = false;
  static bool show_setting = false;
  static char *xlog_dir = "";
+ static char *tmp_stat_dir = "";
  
  
  /* internal vars */
***************
*** 111,116 ****
--- 112,119 ----
  static bool found_existing_pgdata = false;
  static bool made_new_xlogdir = false;
  static bool found_existing_xlogdir = false;
+ static bool made_new_tmpstatdir = false;
+ static bool found_existing_tmpstatdir = false;
  static char infoversion[100];
  static bool caught_signal = false;
  static bool output_failed = false;
***************
*** 628,633 ****
--- 631,654 ----
  				fprintf(stderr, _("%s: failed to remove contents of transaction log directory\n"),
  						progname);
  		}
+ 
+ 		if (made_new_tmpstatdir)
+ 		{
+ 			fprintf(stderr, _("%s: removing temporary statistics directory \"%s\"\n"),
+ 					progname, tmp_stat_dir);
+ 			if (!rmtree(tmp_stat_dir, true))
+ 				fprintf(stderr, _("%s: failed to remove temporary statistics directory\n"),
+ 						progname);
+ 		}
+ 		else if (found_existing_tmpstatdir)
+ 		{
+ 			fprintf(stderr,
+ 			_("%s: removing contents of temporary statistics directory \"%s\"\n"),
+ 					progname, tmp_stat_dir);
+ 			if (!rmtree(tmp_stat_dir, false))
+ 				fprintf(stderr, _("%s: failed to remove contents of temporary statistics directory\n"),
+ 						progname);
+ 		}
  		/* otherwise died during startup, do nothing! */
  	}
  	else
***************
*** 641,646 ****
--- 662,672 ----
  			fprintf(stderr,
  					_("%s: transaction log directory \"%s\" not removed at user's request\n"),
  					progname, xlog_dir);
+ 
+ 		if (made_new_tmpstatdir || found_existing_tmpstatdir)
+ 			fprintf(stderr,
+ 					_("%s: temporary statistics directory \"%s\" not removed at user's request\n"),
+ 					progname, tmp_stat_dir);
  	}
  
  	exit(1);
***************
*** 2387,2392 ****
--- 2413,2419 ----
  	printf(_("  --no-locale               equivalent to --locale=C\n"));
  	printf(_("  -T, --text-search-config=CFG\n"
  		 "                            default text search configuration\n"));
+ 	printf(_("  -S, --statdir=STATDIR     location for the temporary statistics directory\n"));
  	printf(_("  -X, --xlogdir=XLOGDIR     location for the transaction log directory\n"));
  	printf(_("  -A, --auth=METHOD         default authentication method for local connections\n"));
  	printf(_("  -U, --username=NAME       database superuser name\n"));
***************
*** 2433,2438 ****
--- 2460,2466 ----
  		{"show", no_argument, NULL, 's'},
  		{"noclean", no_argument, NULL, 'n'},
  		{"xlogdir", required_argument, NULL, 'X'},
+ 		{"statdir", required_argument, NULL, 'S'},
  		{NULL, 0, NULL, 0}
  	};
  
***************
*** 2484,2490 ****
  
  	/* process command-line options */
  
! 	while ((c = getopt_long(argc, argv, "dD:E:L:nU:WA:sT:X:", long_options, &option_index)) != -1)
  	{
  		switch (c)
  		{
--- 2512,2518 ----
  
  	/* process command-line options */
  
! 	while ((c = getopt_long(argc, argv, "dD:E:L:nU:WA:sS:T:X:", long_options, &option_index)) != -1)
  	{
  		switch (c)
  		{
***************
*** 2544,2549 ****
--- 2572,2580 ----
  			case 's':
  				show_setting = true;
  				break;
+ 			case 'S':
+ 				tmp_stat_dir = xstrdup(optarg);
+ 				break;
  			case 'T':
  				default_text_search_config = xstrdup(optarg);
  				break;
***************
*** 3095,3100 ****
--- 3126,3217 ----
  #endif
  	}
  
+ 	/* Create temporary statistics symlink, if required */
+ 	if (strcmp(tmp_stat_dir, "") != 0)
+ 	{
+ 		char	   *linkloc;
+ 
+ 		/* clean up temporary statistics directory name, check it's absolute */
+ 		canonicalize_path(tmp_stat_dir);
+ 		if (!is_absolute_path(tmp_stat_dir))
+ 		{
+ 			fprintf(stderr, _("%s: temporary statistics directory location must be an absolute path\n"), progname);
+ 			exit_nicely();
+ 		}
+ 
+ 		/* check if the specified tmp_stat directory is empty */
+ 		switch (check_data_dir(tmp_stat_dir))
+ 		{
+ 			case 0:
+ 				/* tmp_stat directory not there, must create it */
+ 				printf(_("creating directory %s ... "),
+ 					   tmp_stat_dir);
+ 				fflush(stdout);
+ 
+ 				if (mkdir_p(tmp_stat_dir, 0700) != 0)
+ 				{
+ 					fprintf(stderr, _("%s: could not create directory \"%s\": %s\n"),
+ 							progname, tmp_stat_dir, strerror(errno));
+ 					exit_nicely();
+ 				}
+ 				else
+ 					check_ok();
+ 
+ 				made_new_tmpstatdir = true;
+ 				break;
+ 			case 1:
+ 				/* Present but empty, fix permissions and use it */
+ 				printf(_("fixing permissions on existing directory %s ... "),
+ 					   tmp_stat_dir);
+ 				fflush(stdout);
+ 
+ 				if (chmod(tmp_stat_dir, 0700) != 0)
+ 				{
+ 					fprintf(stderr, _("%s: could not change permissions of directory \"%s\": %s\n"),
+ 							progname, tmp_stat_dir, strerror(errno));
+ 					exit_nicely();
+ 				}
+ 				else
+ 					check_ok();
+ 
+ 				found_existing_tmpstatdir = true;
+ 				break;
+ 			case 2:
+ 				/* Present and not empty */
+ 				fprintf(stderr,
+ 						_("%s: directory \"%s\" exists but is not empty\n"),
+ 						progname, tmp_stat_dir);
+ 				fprintf(stderr,
+ 						_("If you want to store the temporary statistics there, either\n"
+ 						  "remove or empty the directory \"%s\".\n"),
+ 						tmp_stat_dir);
+ 				exit_nicely();
+ 
+ 			default:
+ 				/* Trouble accessing directory */
+ 				fprintf(stderr, _("%s: could not access directory \"%s\": %s\n"),
+ 						progname, tmp_stat_dir, strerror(errno));
+ 				exit_nicely();
+ 		}
+ 
+ 		/* form name of the place where the symlink must go */
+ 		linkloc = (char *) pg_malloc(strlen(pg_data) + 12 + 1);
+ 		sprintf(linkloc, "%s/pg_stat_tmp", pg_data);
+ 
+ #ifdef HAVE_SYMLINK
+ 		if (symlink(tmp_stat_dir, linkloc) != 0)
+ 		{
+ 			fprintf(stderr, _("%s: could not create symbolic link \"%s\": %s\n"),
+ 					progname, linkloc, strerror(errno));
+ 			exit_nicely();
+ 		}
+ #else
+ 		fprintf(stderr, _("%s: symlinks are not supported on this platform"));
+ 		exit_nicely();
+ #endif
+ 	}
+ 
+ 
  	/* Create required subdirectories */
  	printf(_("creating subdirectories ... "));
  	fflush(stdout);
