Ron Mayer wrote:
> Tom Lane wrote:
>> In fact, given that we are now
>> somewhat SQL-compliant on interval input, a GUC that selected
>> PG traditional, SQL-standard, or ISO 8601 interval output format seems
>> like it could be a good idea.

Attached are updated versions of the Interval patches (SQL-standard interval
output, ISO8601 intervals, and interval rounding) I posted earlier upthread.
I mostly brought it up-to-date with HEAD, cleaned up comments and regression
tests, and fixed a couple bugs.  [Sorry if people get this twice.  I tried
attaching all 4 patches earlier today, but didn't notice it on the
list perhaps because of the combined size.]

# Patch 1: "stdintervaloutput.patch"
   SQL Standard Interval Literal Output

   Description: This patch adds an IntervalStyle GUC to control
   the style of intervals. Previously the interval style was a
   side-effect of the DateStyle GUC. IntervalStyle can be set to
   "sql_standard" to output SQL Standard Interval Literals.

   Reason for the patch: Now that we support SQL-standard interval
   inputs, it's nice to be able to output intervals in that style as well.

During the commit-fest I'll post versions of these that are regularly
synced with CVS HEAD here:  http://0ape.com/postgres_interval_patches/

*** a/doc/src/sgml/config.sgml
--- b/doc/src/sgml/config.sgml
***************
*** 4016,4021 **** SET XML OPTION { DOCUMENT | CONTENT };
--- 4016,4043 ----
        </listitem>
       </varlistentry>
  
+      <varlistentry id="guc-intervalstyle" xreflabel="IntervalStyle">
+       <term><varname>IntervalStyle</varname> (<type>string</type>)</term>
+       <indexterm>
+        <primary><varname>IntervalStyle</> configuration parameter</primary>
+       </indexterm>
+       <listitem>
+        <para>
+         Sets the display format for interval values. 
+         The value <literal>sql_standard</> will output SQL Standard
+         strings when given intervals that conform to the SQL
+         standard (either year-month only or date-time only; and no
+         mixing of positive and negative components).
+         The value <literal>postgres</> will output intervals in
+         a format that matches what old releases had output when
+         the DateStyle was set to <literal>'ISO'</>.
+         The value <literal>postgres_verbose</> will output intervals in
+         a format that matches what old releases had output when
+         the DateStyle was set to <literal>'SQL'</>.
+        </para>
+       </listitem>
+      </varlistentry>
+ 
       <varlistentry id="guc-timezone" xreflabel="timezone">
        <term><varname>timezone</varname> (<type>string</type>)</term>
        <indexterm>
*** a/doc/src/sgml/datatype.sgml
--- b/doc/src/sgml/datatype.sgml
***************
*** 2213,2218 **** January 8 04:05:06 1999 PST
--- 2213,2305 ----
      </para>
     </sect2>
  
+    <sect2 id="interval-output">
+     <title>Interval Output</title>
+ 
+     <indexterm>
+      <primary>interval</primary>
+      <secondary>output format</secondary>
+      <seealso>formatting</seealso>
+     </indexterm>
+ 
+     <para>
+      The output format of the interval types can be set to one of the
+      three styles <literal>sql_standard</>, 
+      <literal>postgres</>, or <literal>postgres_verbose</>.
+      The default is the <literal>postgres</> format.  
+      <xref
+      linkend="interval-style-output-table"> shows examples of each
+      output style.
+     </para>
+ 
+     <para>
+      The <literal>sql_standard</> style will output SQL standard
+      interval literal strings where the value of the interval
+      value consists of only a year-month component or a datetime
+      component (as required by the sql standard).   For an interval
+      containing both a year-month and a datetime component, the
+      output will be a SQL Standard unquoted year-month literal
+      string joined to a SQL Standard unquoted datetime literal
+      string with a space in between.
+     </para>
+ 
+     <para>
+      The <literal>postgres</> style will output intervals that match
+      the style PostgreSQL 8.3 outputed when the <xref linkend="guc-datestyle">
+      parameter was set to <literal>ISO</>.
+     </para>
+ 
+     <para>
+      The <literal>postgres_verbose</> style will output intervals that match
+      the style PostgreSQL 8.3 outputed when the <xref linkend="guc-datestyle">
+      parameter was set to <literal>SQL</>.
+     </para>
+ 
+      <table id="interval-style-output-table">
+ 	   <title>Interval Style Example</title>
+ 	   <tgroup cols="2">
+ 		<thead>
+ 		 <row>
+ 		  <entry>Style Specification</entry>
+ 		  <entry>Year-Month Interval</entry>
+ 		  <entry>DateTime Interval</entry>
+ 		  <entry>Nonstandardrd Extended Interval</entry>
+ 		 </row>
+ 		</thead>
+ 		<tbody>
+ 		 <row>
+ 		  <entry>sql_standard</entry>
+ 		  <entry>1-2</entry>
+ 		  <entry>3 4:05:06</entry>
+ 		  <entry>-1-2 +3 -4:05:06</entry>
+ 		 </row>
+ 		 <row>
+ 		  <entry>postgres</entry>
+ 		  <entry>1 year 2 mons</entry>
+ 		  <entry>3 days 04:05:06</entry>
+ 		  <entry>-1 year -2 mons +3 days -04:05:06</entry>
+ 		 </row>
+ 		 <row>
+ 		  <entry>postgres_verbose</entry>
+ 		  <entry>@ 1 year 2 mons</entry>
+ 		  <entry>@ 3 days 4 hours 5 mins 6 secs</entry>
+ 		  <entry>@ 1 year 2 mons -3 days 4 hours 5 mins 6 secs ago</entry>
+ 		 </row>
+ 		</tbody>
+ 	     </tgroup>
+ 	</table>
+ 
+      <para>
+      Note that <literal>sql_standard</> style will only produce strictly 
+      standards-conforming interval literals when given a strictly SQL-standard
+      interval value - meaning that it needs to be a pure year-month or datetime
+      interval and not mix positive and negative components.
+      </para>
+ 
+    </sect2>
+ 
+ 
+ 
     <sect2 id="datatype-timezones">
      <title>Time Zones</title>
  
*** a/src/backend/commands/variable.c
--- b/src/backend/commands/variable.c
***************
*** 229,234 **** assign_datestyle(const char *value, bool doit, GucSource source)
--- 229,271 ----
  
  
  /*
+  * assign_intervalstyle: GUC assign_hook for datestyle
+  */
+ const char *
+ assign_intervalstyle(const char *value, bool doit, GucSource source)
+ {
+ 	int	newIntervalStyle = IntervalStyle;
+ 	char *	result = (char *) malloc(32);
+ 	if (pg_strcasecmp(value, "postgres") == 0)
+ 	{
+ 		newIntervalStyle = INTSTYLE_POSTGRES;
+ 	}
+ 	else if (pg_strcasecmp(value, "postgres_verbose") == 0)
+ 	{
+ 		newIntervalStyle = INTSTYLE_POSTGRES_VERBOSE;
+ 	}
+ 	else if (pg_strcasecmp(value, "sql_standard") == 0)
+ 	{
+ 		newIntervalStyle = INTSTYLE_SQL_STANDARD;
+ 	}
+ 	else
+ 	{
+ 		ereport(GUC_complaint_elevel(source),
+ 				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ 				 errmsg("unrecognized \"intervalstyle\" key word: \"%s\"",
+ 							value)));
+ 		return NULL;
+ 	}
+ 	if (doit)
+ 	{
+ 		IntervalStyle = newIntervalStyle;
+ 		strcpy(result, value);
+ 	}
+ 	return result;
+ }
+ 
+ 
+ /*
   * TIMEZONE
   */
  
*** a/src/backend/utils/adt/datetime.c
--- b/src/backend/utils/adt/datetime.c
***************
*** 2766,2771 **** DecodeInterval(char **field, int *ftype, int nf, int range,
--- 2766,2787 ----
  			case DTK_TIME:
  				dterr = DecodeTime(field[i], fmask, range,
  								   &tmask, tm, fsec);
+ 				if (IntervalStyle == INTSTYLE_SQL_STANDARD &&
+ 					field[0][0] == '-' && i == 1 &&
+ 					field[i][0] != '-' && field[i][0] != '+')
+ 				{
+ 					/* 
+ 					 * The SQL Standard defines the interval literal
+ 					 *   '-1 1:00:00'
+ 					 * to mean "negative 1 days and negative one hours"
+ 					 * while Postgres traditionally treated this as 
+ 					 * to mean "negative 1 days and positive one hours"
+ 					 */
+ 					tm->tm_hour = -tm->tm_hour;
+ 					tm->tm_min = -tm->tm_min;
+ 					tm->tm_sec = -tm->tm_sec;
+ 					*fsec = - *fsec;
+ 				}
  				if (dterr)
  					return dterr;
  				type = DTK_DAY;
***************
*** 3605,3610 **** EncodeDateTime(struct pg_tm * tm, fsec_t fsec, int *tzp, char **tzn, int style,
--- 3621,3647 ----
  	return TRUE;
  }
  
+ /*
+  * Small helper funciton to avoid copy&paste in EncodeInterval below
+  */
+ static void
+ AppendSeconds(char * cp,int sec, fsec_t fsec)
+ {
+ 	if (fsec==0) 
+ 	{
+ 		sprintf(cp, "%02d", abs(sec));
+ 	}
+ 	else
+ 	{
+ #ifdef HAVE_INT64_TIMESTAMP
+ 		sprintf(cp, "%02d.%06d", sec, Abs(fsec));
+ #else
+ 		sprintf(cp, "%012.9f", fabs(sec + fsec));
+ #endif
+ 		TrimTrailingZeros(cp);
+ 	}
+ }
+ 
  
  /* EncodeInterval()
   * Interpret time structure as a delta time and convert to string.
***************
*** 3613,3618 **** EncodeDateTime(struct pg_tm * tm, fsec_t fsec, int *tzp, char **tzn, int style,
--- 3650,3666 ----
   * Actually, afaik ISO does not address time interval formatting,
   *	but this looks similar to the spec for absolute date/time.
   * - thomas 1998-04-30
+  * 
+  * Actually, afaik, ISO 8601 does specify formats for "time
+  * intervals...[of the]...format with time-unit designators", which
+  * are pretty ugly.  The format looks something like
+  *     P1Y1M1DT1H1M1.12345S
+  * but useful for exchanging data with computers instead of humans.
+  * - ron 2003-07-14
+  * 
+  * And ISO's SQL 2008 standard specifies standards for
+  * "year-month literal"s (that look like '2-3') and 
+  * "day-time literal"s (that look like ('4 5:6:7')
   */
  int
  EncodeInterval(struct pg_tm * tm, fsec_t fsec, int style, char *str)
***************
*** 3621,3626 **** EncodeInterval(struct pg_tm * tm, fsec_t fsec, int style, char *str)
--- 3669,3681 ----
  	bool		is_nonzero = FALSE;
  	char	   *cp = str;
  
+     int year  = tm->tm_year;
+     int mon   = tm->tm_mon;
+     int mday  = tm->tm_mday;
+     int hour  = tm->tm_hour;
+     int min   = tm->tm_min;
+     int sec   = tm->tm_sec;
+ 
  	/*
  	 * The sign of year and month are guaranteed to match, since they are
  	 * stored internally as "month". But we'll need to check for is_before and
***************
*** 3628,3635 **** EncodeInterval(struct pg_tm * tm, fsec_t fsec, int style, char *str)
  	 */
  	switch (style)
  	{
! 			/* compatible with ISO date formats */
! 		case USE_ISO_DATES:
  			if (tm->tm_year != 0)
  			{
  				sprintf(cp, "%d year%s",
--- 3683,3760 ----
  	 */
  	switch (style)
  	{
! 	    /* SQL Standard interval literals */
! 		case INTSTYLE_SQL_STANDARD:
! 		{
! 			bool has_negative = (year < 0) || (mon  < 0) ||
! 			                    (mday < 0) || (hour < 0) ||
! 			                    (min  < 0) || (sec  < 0) || (fsec<0);
! 			bool has_positive = (year > 0) || (mon  > 0) ||
! 			                    (mday > 0) || (hour > 0) ||
! 			                    (min  > 0) || (sec > 0) || (fsec>0);
! 			bool has_year_month = (year != 0) || (mon != 0);
! 			bool has_datetime   = (hour != 0) || (min != 0) ||
! 			                      (sec  != 0) || (fsec!= 0) || (mday != 0);
! 			bool has_day        = (mday != 0);
! 			bool sql_standard_value = (!(has_negative && has_positive)) && 
! 			                          (!(has_year_month && has_datetime));
! 			/*
! 			 * SQL Standard wants only 1 "<sign>" preceeding the whole
! 			 * interval.
! 			 */
! 			if (has_negative && sql_standard_value)
! 			{
! 				sprintf(cp,"-");
! 				cp++;
! 				year = -year;
! 				mon  = -mon;
! 				mday = -mday;
! 				hour = -hour;
! 				min  = -min;
! 				sec  = -sec;
! 				fsec = -fsec;
! 			}
! 			if (!has_negative && !has_positive)
! 			{
! 				sprintf(cp,"0");
! 			}
! 			else if (!sql_standard_value)
! 			{
! 			    /*
! 				 * For non sql-standard interval values, 
! 				 * force outputting the signs to avoid
! 				 * ambiguities with intervals with mixed
! 				 * sign components.
! 				 */
! 			    char year_sign = (year<0 || mon<0) ? '-' : '+';
! 			    char day_sign = (mday<0) ? '-' : '+';
! 			    char sec_sign = (hour<0 || min<0 || sec<0 || fsec<0)
! 			                    ? '-' : '+';
! 				cp += sprintf(cp,"%c%d-%d %c%d %c%d:%02d:",
! 				        year_sign,abs(year),abs(mon),
! 				        day_sign,abs(mday),
! 						sec_sign,abs(hour),abs(min));
! 				AppendSeconds(cp,sec,fsec);
! 			}
! 			else if (has_year_month)
! 			{
! 				sprintf(cp,"%d-%d",year,mon);
! 			}
! 			else if (has_day)
! 			{
! 				cp += sprintf(cp,"%d %d:%02d:",mday,hour,min);
! 				AppendSeconds(cp,sec,fsec);
! 			}
! 			else
! 			{
! 				cp += sprintf(cp,"%d:%02d:",hour,min);
! 				AppendSeconds(cp,sec,fsec);
! 			}
! 			break;
! 		}
! 
! 		/* compatible with postgresql 8.3 when DateStyle = 'iso' */
! 		case INTSTYLE_POSTGRES:
  			if (tm->tm_year != 0)
  			{
  				sprintf(cp, "%d year%s",
***************
*** 3692,3700 **** EncodeInterval(struct pg_tm * tm, fsec_t fsec, int style, char *str)
  					cp += strlen(cp);
  				}
  			}
  			break;
  
! 		case USE_POSTGRES_DATES:
  		default:
  			strcpy(cp, "@ ");
  			cp += strlen(cp);
--- 3817,3831 ----
  					cp += strlen(cp);
  				}
  			}
+ 			if (!is_nonzero)
+ 			{
+ 				strcat(cp, "0");
+ 				cp += strlen(cp);
+ 			}
  			break;
  
! 		/* compatible with postgresql 8.3 when DateStyle = 'sql' */
! 		case INTSTYLE_POSTGRES_VERBOSE:
  		default:
  			strcpy(cp, "@ ");
  			cp += strlen(cp);
***************
*** 3821,3842 **** EncodeInterval(struct pg_tm * tm, fsec_t fsec, int style, char *str)
  					is_before = (tm->tm_sec < 0);
  				is_nonzero = TRUE;
  			}
  			break;
  	}
  
- 	/* identically zero? then put in a unitless zero... */
- 	if (!is_nonzero)
- 	{
- 		strcat(cp, "0");
- 		cp += strlen(cp);
- 	}
- 
- 	if (is_before && (style != USE_ISO_DATES))
- 	{
- 		strcat(cp, " ago");
- 		cp += strlen(cp);
- 	}
- 
  	return 0;
  }	/* EncodeInterval() */
  
--- 3952,3970 ----
  					is_before = (tm->tm_sec < 0);
  				is_nonzero = TRUE;
  			}
+ 			if (!is_nonzero)
+ 			{
+ 				strcat(cp, "0");
+ 				cp += strlen(cp);
+ 			}
+ 			if (is_before)
+ 			{
+ 				strcat(cp, " ago");
+ 				cp += strlen(cp);
+ 			}
  			break;
  	}
  
  	return 0;
  }	/* EncodeInterval() */
  
*** a/src/backend/utils/adt/nabstime.c
--- b/src/backend/utils/adt/nabstime.c
***************
*** 671,677 **** reltimeout(PG_FUNCTION_ARGS)
  	char		buf[MAXDATELEN + 1];
  
  	reltime2tm(time, tm);
! 	EncodeInterval(tm, 0, DateStyle, buf);
  
  	result = pstrdup(buf);
  	PG_RETURN_CSTRING(result);
--- 671,677 ----
  	char		buf[MAXDATELEN + 1];
  
  	reltime2tm(time, tm);
! 	EncodeInterval(tm, 0, IntervalStyle, buf);
  
  	result = pstrdup(buf);
  	PG_RETURN_CSTRING(result);
*** a/src/backend/utils/adt/timestamp.c
--- b/src/backend/utils/adt/timestamp.c
***************
*** 677,683 **** interval_out(PG_FUNCTION_ARGS)
  	if (interval2tm(*span, tm, &fsec) != 0)
  		elog(ERROR, "could not convert interval to tm");
  
! 	if (EncodeInterval(tm, fsec, DateStyle, buf) != 0)
  		elog(ERROR, "could not format interval");
  
  	result = pstrdup(buf);
--- 677,683 ----
  	if (interval2tm(*span, tm, &fsec) != 0)
  		elog(ERROR, "could not convert interval to tm");
  
! 	if (EncodeInterval(tm, fsec, IntervalStyle, buf) != 0)
  		elog(ERROR, "could not format interval");
  
  	result = pstrdup(buf);
*** a/src/backend/utils/init/globals.c
--- b/src/backend/utils/init/globals.c
***************
*** 88,93 **** bool		ExitOnAnyError = false;
--- 88,94 ----
  
  int			DateStyle = USE_ISO_DATES;
  int			DateOrder = DATEORDER_MDY;
+ int			IntervalStyle = INTSTYLE_POSTGRES;
  bool		HasCTZSet = false;
  int			CTimeZone = 0;
  
*** a/src/backend/utils/misc/guc.c
--- b/src/backend/utils/misc/guc.c
***************
*** 366,371 **** static bool session_auth_is_superuser;
--- 366,372 ----
  static double phony_random_seed;
  static char *client_encoding_string;
  static char *datestyle_string;
+ static char *intervalstyle_string;
  static char *locale_collate;
  static char *locale_ctype;
  static char *server_encoding_string;
***************
*** 2078,2083 **** static struct config_string ConfigureNamesString[] =
--- 2079,2094 ----
  		"ISO, MDY", assign_datestyle, NULL
  	},
  
+  	{
+ 		{"IntervalStyle", PGC_USERSET, CLIENT_CONN_LOCALE,
+ 			gettext_noop("Sets the display format for interval values."),
+ 			gettext_noop(""),
+ 			GUC_REPORT
+ 		},
+ 		&intervalstyle_string,
+ 		"postgres", assign_intervalstyle, NULL
+ 	},
+ 
  	{
  		{"default_tablespace", PGC_USERSET, CLIENT_CONN_STATEMENT,
  			gettext_noop("Sets the default tablespace to create tables and indexes in."),
*** a/src/backend/utils/misc/postgresql.conf.sample
--- b/src/backend/utils/misc/postgresql.conf.sample
***************
*** 419,424 ****
--- 419,425 ----
  # - Locale and Formatting -
  
  #datestyle = 'iso, mdy'
+ #intervalstyle = 'postgres'
  #timezone = unknown			# actually, defaults to TZ environment
  					# setting
  #timezone_abbreviations = 'Default'     # Select the set of available time zone
*** a/src/bin/psql/tab-complete.c
--- b/src/bin/psql/tab-complete.c
***************
*** 1953,1958 **** psql_completion(char *text, int start, int end)
--- 1953,1965 ----
  
  			COMPLETE_WITH_LIST(my_list);
  		}
+ 		else if (pg_strcasecmp(prev2_wd, "IntervalStyle") == 0)
+ 		{
+ 			static const char *const my_list[] =
+ 			{"postgres","postgres_verbose", "sql_standard", NULL};
+ 
+ 			COMPLETE_WITH_LIST(my_list);
+ 		}
  		else if (pg_strcasecmp(prev2_wd, "GEQO") == 0)
  		{
  			static const char *const my_list[] =
*** a/src/include/commands/variable.h
--- b/src/include/commands/variable.h
***************
*** 15,20 ****
--- 15,22 ----
  
  extern const char *assign_datestyle(const char *value,
  				 bool doit, GucSource source);
+ extern const char *assign_intervalstyle(const char *value,
+ 				 bool doit, GucSource source);
  extern const char *assign_timezone(const char *value,
  				bool doit, GucSource source);
  extern const char *show_timezone(void);
*** a/src/include/miscadmin.h
--- b/src/include/miscadmin.h
***************
*** 191,196 **** extern PGDLLIMPORT Oid MyDatabaseTableSpace;
--- 191,208 ----
  
  extern int	DateStyle;
  extern int	DateOrder;
+  
+ /*
+  * IntervalStyles
+  *   INTSTYLE_POSTGRES             Like Postgres8.3 when DateStyle = 'iso'
+  *   INTSTYLE_POSTGRES_VERBOSE     Like Postgres8.3 when DateStyle = 'sql'
+  *   INTSTYLE_SQL_STANDARD         SQL standard interval literals
+  */
+ #define INTSTYLE_POSTGRES             0
+ #define INTSTYLE_POSTGRES_VERBOSE     1
+ #define INTSTYLE_SQL_STANDARD         2
+ 
+ extern int	IntervalStyle;
  
  /*
   * HasCTZSet is true if user has set timezone as a numeric offset from UTC.
*** a/src/interfaces/libpq/fe-connect.c
--- b/src/interfaces/libpq/fe-connect.c
***************
*** 209,214 **** static const PQEnvironmentOption EnvironmentOptions[] =
--- 209,217 ----
  		"PGDATESTYLE", "datestyle"
  	},
  	{
+ 		"PGINTERVALSTYLE", "intervalstyle"
+ 	},
+ 	{
  		"PGTZ", "timezone"
  	},
  	{
*** a/src/test/regress/expected/interval.out
--- b/src/test/regress/expected/interval.out
***************
*** 2,7 ****
--- 2,8 ----
  -- INTERVAL
  --
  SET DATESTYLE = 'ISO';
+ SET IntervalStyle to postgres;
  -- check acceptance of "time zone style"
  SELECT INTERVAL '01:00' AS "One hour";
   One hour 
***************
*** 273,278 **** FROM INTERVAL_MULDIV_TBL;
--- 274,280 ----
  
  DROP TABLE INTERVAL_MULDIV_TBL;
  SET DATESTYLE = 'postgres';
+ SET IntervalStyle to postgres_verbose;
  SELECT '' AS ten, * FROM INTERVAL_TBL;
   ten |              f1               
  -----+-------------------------------
***************
*** 326,331 **** SELECT justify_interval(interval '1 month -1 hour') as "1 month -1 hour";
--- 328,334 ----
  
  -- test fractional second input, and detection of duplicate units
  SET DATESTYLE = 'ISO';
+ SET IntervalStyle TO postgres;
  SELECT '1 millisecond'::interval, '1 microsecond'::interval,
         '500 seconds 99 milliseconds 51 microseconds'::interval;
     interval   |    interval     |    interval     
***************
*** 609,611 **** SELECT interval '1 2:03:04.5678' minute to second(2);
--- 612,634 ----
   00:03:04.57
  (1 row)
  
+ -- test outputting SQL standard interval literals
+ SET IntervalStyle TO sql_standard;
+ SELECT  interval '0'                       AS "zero",
+         interval '1-2' year to month       AS "year-month",
+         interval '1 2:03:04' day to second AS "day-time",
+         - interval '1-2'                   AS "negative year-month",
+         - interval '1 2:03:04'             AS "negative day-time";
+  zero | year-month | day-time  | negative year-month | negative day-time 
+ ------+------------+-----------+---------------------+-------------------
+  0    | 1-2        | 1 2:03:04 | -1-2                | -1 2:03:04
+ (1 row)
+ 
+ -- test a couple non-standard interval values too
+ SELECT  interval '1 years 2 months -3 days 4 hours 5 minutes 6.789 seconds',
+         - interval '1 years 2 months -3 days 4 hours 5 minutes 6.789 seconds';
+        interval       |       ?column?       
+ ----------------------+----------------------
+  +1-2 -3 +4:05:06.789 | -1-2 +3 -4:05:06.789
+ (1 row)
+ 
*** a/src/test/regress/pg_regress.c
--- b/src/test/regress/pg_regress.c
***************
*** 708,713 **** initialize_environment(void)
--- 708,714 ----
  	 */
  	putenv("PGTZ=PST8PDT");
  	putenv("PGDATESTYLE=Postgres, MDY");
+ 	putenv("PGINTERVALSTYLE=postgres_verbose");
  
  	if (temp_install)
  	{
*** a/src/test/regress/sql/interval.sql
--- b/src/test/regress/sql/interval.sql
***************
*** 3,8 ****
--- 3,9 ----
  --
  
  SET DATESTYLE = 'ISO';
+ SET IntervalStyle to postgres;
  
  -- check acceptance of "time zone style"
  SELECT INTERVAL '01:00' AS "One hour";
***************
*** 94,99 **** FROM INTERVAL_MULDIV_TBL;
--- 95,101 ----
  DROP TABLE INTERVAL_MULDIV_TBL;
  
  SET DATESTYLE = 'postgres';
+ SET IntervalStyle to postgres_verbose;
  
  SELECT '' AS ten, * FROM INTERVAL_TBL;
  
***************
*** 118,123 **** SELECT justify_interval(interval '1 month -1 hour') as "1 month -1 hour";
--- 120,127 ----
  
  -- test fractional second input, and detection of duplicate units
  SET DATESTYLE = 'ISO';
+ SET IntervalStyle TO postgres;
+ 
  SELECT '1 millisecond'::interval, '1 microsecond'::interval,
         '500 seconds 99 milliseconds 51 microseconds'::interval;
  SELECT '3 days 5 milliseconds'::interval;
***************
*** 174,176 **** SELECT interval '1 2:03:04.5678' hour to second(2);
--- 178,192 ----
  SELECT interval '1 2.3456' minute to second(2);
  SELECT interval '1 2:03.5678' minute to second(2);
  SELECT interval '1 2:03:04.5678' minute to second(2);
+ 
+ -- test outputting SQL standard interval literals
+ SET IntervalStyle TO sql_standard;
+ SELECT  interval '0'                       AS "zero",
+         interval '1-2' year to month       AS "year-month",
+         interval '1 2:03:04' day to second AS "day-time",
+         - interval '1-2'                   AS "negative year-month",
+         - interval '1 2:03:04'             AS "negative day-time";
+ 
+ -- test a couple non-standard interval values too
+ SELECT  interval '1 years 2 months -3 days 4 hours 5 minutes 6.789 seconds',
+         - interval '1 years 2 months -3 days 4 hours 5 minutes 6.789 seconds';
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to