This patch makes the following changes

- emit a warning when an empty string is input to the float4, float8, and oid types, per earlier discussion on -hackers
- emit a warning when there is trailing whitespace in the input to the oid type, per suggestion from Tom (BTW, I couldn't see anything about this in the standard, although I may have been looking in the wrong place; in any case, rejecting trailing whitespace seems clearly correct behavior to me)
- update the regression tests


The first two changes are intended as a temporary measures for backward compatibility: 7.5 will emit warnings, but 7.6 will reject this input. That should hopefully avoid a similar situation to the pg_atoi() change.

I invented a new SQLSTATE code for these warnings, ERRCODE_WARNING_DEPRECATED_FEATURE. Did I do this correctly?

-Neil

Index: doc/src/sgml/errcodes.sgml
===================================================================
RCS file: /var/lib/cvs/pgsql-server/doc/src/sgml/errcodes.sgml,v
retrieving revision 1.2
diff -c -r1.2 errcodes.sgml
*** a/doc/src/sgml/errcodes.sgml	29 Nov 2003 19:51:37 -0000	1.2
--- b/doc/src/sgml/errcodes.sgml	4 Mar 2004 02:05:49 -0000
***************
*** 95,100 ****
--- 95,104 ----
  <entry>WARNING STRING DATA RIGHT TRUNCATION</entry>
  </row>
  
+ <row>
+ <entry><literal>01P01</literal></entry>
+ <entry>WARNING DEPRECATED FEATURE</entry>
+ </row>
  
  <row>
  <entry>Class 02</entry>
Index: src/backend/utils/adt/float.c
===================================================================
RCS file: /var/lib/cvs/pgsql-server/src/backend/utils/adt/float.c,v
retrieving revision 1.96
diff -c -r1.96 float.c
*** a/src/backend/utils/adt/float.c	29 Nov 2003 19:51:58 -0000	1.96
--- b/src/backend/utils/adt/float.c	4 Mar 2004 00:31:59 -0000
***************
*** 209,214 ****
--- 209,227 ----
  	}
  
  	/*
+ 	 * In releases prior to 7.5, we accepted an empty string as valid
+ 	 * input (yielding a float4 of 0). In 7.5, we accept empty
+ 	 * strings, but emit a warning noting that the feature is
+ 	 * deprecated. In 7.6+, the warning should be replaced by an error.
+ 	 */
+ 	if (num == endptr)
+ 		ereport(WARNING,
+ 				(errcode(ERRCODE_WARNING_DEPRECATED_FEATURE),
+ 				 errmsg("deprecated input syntax for type real: \"\""),
+ 				 errdetail("this input will be rejected in "
+ 						   "a future release of PostgreSQL")));
+ 
+ 	/*
  	 * if we get here, we have a legal double, still need to check to see
  	 * if it's a legal float
  	 */
***************
*** 309,314 ****
--- 322,340 ----
  					 errmsg("\"%s\" is out of range for type double precision", num)));
  	}
  
+ 	/*
+ 	 * In releases prior to 7.5, we accepted an empty string as valid
+ 	 * input (yielding a float8 of 0). In 7.5, we accept empty
+ 	 * strings, but emit a warning noting that the feature is
+ 	 * deprecated. In 7.6+, the warning should be replaced by an error.
+ 	 */
+ 	if (num == endptr)
+ 		ereport(WARNING,
+ 				(errcode(ERRCODE_WARNING_DEPRECATED_FEATURE),
+ 				 errmsg("deprecated input syntax for type double precision: \"\""),
+ 				 errdetail("this input will be rejected in "
+ 						   "a future release of PostgreSQL")));
+ 
  	CheckFloat8Val(val);
  
  	PG_RETURN_FLOAT8(val);
Index: src/backend/utils/adt/oid.c
===================================================================
RCS file: /var/lib/cvs/pgsql-server/src/backend/utils/adt/oid.c,v
retrieving revision 1.54
diff -c -r1.54 oid.c
*** a/src/backend/utils/adt/oid.c	18 Feb 2004 00:01:34 -0000	1.54
--- b/src/backend/utils/adt/oid.c	4 Mar 2004 00:56:48 -0000
***************
*** 40,54 ****
  	 * strtoul() normally only sets ERANGE.  On some systems it also may
  	 * set EINVAL, which simply means it couldn't parse the input string.
  	 * This is handled by the second "if" consistent across platforms.
- 	 * Note that for historical reasons we accept an empty string as
- 	 * meaning 0.
  	 */
  	if (errno && errno != ERANGE && errno != EINVAL)
  		ereport(ERROR,
  				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
  				 errmsg("invalid input syntax for type oid: \"%s\"",
  						s)));
! 	if (endptr == s && *endptr)
  		ereport(ERROR,
  				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
  				 errmsg("invalid input syntax for type oid: \"%s\"",
--- 40,66 ----
  	 * strtoul() normally only sets ERANGE.  On some systems it also may
  	 * set EINVAL, which simply means it couldn't parse the input string.
  	 * This is handled by the second "if" consistent across platforms.
  	 */
  	if (errno && errno != ERANGE && errno != EINVAL)
  		ereport(ERROR,
  				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
  				 errmsg("invalid input syntax for type oid: \"%s\"",
  						s)));
! 
! 	/*
! 	 * In releases prior to 7.5, we accepted an empty string as valid
! 	 * input (yielding an OID of 0). In 7.5, we accept empty strings,
! 	 * but emit a warning noting that the feature is deprecated. In
! 	 * 7.6+, the warning should be replaced by an error.
! 	 */
! 	if (*s == '\0')
! 		ereport(WARNING,
! 				(errcode(ERRCODE_WARNING_DEPRECATED_FEATURE),
! 				 errmsg("deprecated input syntax for type oid: \"\""),
! 				 errdetail("this input will be rejected in "
! 						   "a future release of PostgreSQL")));
! 
! 	if (endptr == s && *s)
  		ereport(ERROR,
  				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
  				 errmsg("invalid input syntax for type oid: \"%s\"",
***************
*** 66,79 ****
  	}
  	else
  	{
! 		/* allow only whitespace after number */
  		while (*endptr && isspace((unsigned char) *endptr))
  			endptr++;
  		if (*endptr)
  			ereport(ERROR,
  					(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
  					 errmsg("invalid input syntax for type oid: \"%s\"",
  							s)));
  	}
  
  	result = (Oid) cvt;
--- 78,111 ----
  	}
  	else
  	{
! 		bool seen_whitespace = false;
! 		/* allow only whitespace after number; see below */
  		while (*endptr && isspace((unsigned char) *endptr))
+ 		{
  			endptr++;
+ 			seen_whitespace = true;
+ 		}
+ 
  		if (*endptr)
  			ereport(ERROR,
  					(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
  					 errmsg("invalid input syntax for type oid: \"%s\"",
  							s)));
+ 
+ 		/*
+ 		 * In releases prior to 7.5, we allowed any number of trailing
+ 		 * whitespace characters following the numeric portion of the
+ 		 * OID. In 7.5, we still accept this kind of input, but issue
+ 		 * a warning that it is deprecated. In 7.6+, we will issue an
+ 		 * error rather than a warning.
+ 		 */
+ 		if (seen_whitespace)
+ 			ereport(WARNING,
+ 					(errcode(ERRCODE_WARNING_DEPRECATED_FEATURE),
+ 					 errmsg("deprecated input syntax for type oid: \"%s\"", s),
+ 					 errhint("trailing whitespace in this context has been deprecated"),
+ 					 errdetail("this input will be rejected in "
+ 							   "a future release of PostgreSQL")));
  	}
  
  	result = (Oid) cvt;
Index: src/include/utils/errcodes.h
===================================================================
RCS file: /var/lib/cvs/pgsql-server/src/include/utils/errcodes.h,v
retrieving revision 1.7
diff -c -r1.7 errcodes.h
*** a/src/include/utils/errcodes.h	29 Nov 2003 22:41:15 -0000	1.7
--- b/src/include/utils/errcodes.h	4 Mar 2004 02:05:04 -0000
***************
*** 44,49 ****
--- 44,50 ----
  #define ERRCODE_WARNING_IMPLICIT_ZERO_BIT_PADDING	MAKE_SQLSTATE('0','1', '0','0','8')
  #define ERRCODE_WARNING_NULL_VALUE_ELIMINATED_IN_SET_FUNCTION	MAKE_SQLSTATE('0','1', '0','0','3')
  #define ERRCODE_WARNING_STRING_DATA_RIGHT_TRUNCATION	MAKE_SQLSTATE('0','1', '0','0','4')
+ #define ERRCODE_WARNING_DEPRECATED_FEATURE	MAKE_SQLSTATE('0','1', 'P','0','1')
  
  /* Class 02 - No Data --- this is also a warning class per SQL99 */
  /* (do not use this class for failure conditions!) */
Index: src/test/regress/expected/oid.out
===================================================================
RCS file: /var/lib/cvs/pgsql-server/src/test/regress/expected/oid.out,v
retrieving revision 1.8
diff -c -r1.8 oid.out
*** a/src/test/regress/expected/oid.out	18 Feb 2004 00:01:34 -0000	1.8
--- b/src/test/regress/expected/oid.out	4 Mar 2004 00:35:57 -0000
***************
*** 7,13 ****
  INSERT INTO OID_TBL(f1) VALUES ('987');
  INSERT INTO OID_TBL(f1) VALUES ('-1040');
  INSERT INTO OID_TBL(f1) VALUES ('99999999');
- INSERT INTO OID_TBL(f1) VALUES ('');
  -- bad inputs 
  INSERT INTO OID_TBL(f1) VALUES ('asdfasd');
  ERROR:  invalid input syntax for type oid: "asdfasd"
--- 7,12 ----
***************
*** 21,28 ****
       |        987
       | 4294966256
       |   99999999
!      |          0
! (6 rows)
  
  SELECT '' AS one, o.* FROM OID_TBL o WHERE o.f1 = 1234;
   one |  f1  
--- 20,26 ----
       |        987
       | 4294966256
       |   99999999
! (5 rows)
  
  SELECT '' AS one, o.* FROM OID_TBL o WHERE o.f1 = 1234;
   one |  f1  
***************
*** 37,59 ****
        |        987
        | 4294966256
        |   99999999
!       |          0
! (5 rows)
  
  SELECT '' AS three, o.* FROM OID_TBL o WHERE o.f1 <= '1234';
   three |  f1  
  -------+------
         | 1234
         |  987
!        |    0
! (3 rows)
  
  SELECT '' AS two, o.* FROM OID_TBL o WHERE o.f1 < '1234';
   two | f1  
  -----+-----
       | 987
!      |   0
! (2 rows)
  
  SELECT '' AS four, o.* FROM OID_TBL o WHERE o.f1 >= '1234';
   four |     f1     
--- 35,54 ----
        |        987
        | 4294966256
        |   99999999
! (4 rows)
  
  SELECT '' AS three, o.* FROM OID_TBL o WHERE o.f1 <= '1234';
   three |  f1  
  -------+------
         | 1234
         |  987
! (2 rows)
  
  SELECT '' AS two, o.* FROM OID_TBL o WHERE o.f1 < '1234';
   two | f1  
  -----+-----
       | 987
! (1 row)
  
  SELECT '' AS four, o.* FROM OID_TBL o WHERE o.f1 >= '1234';
   four |     f1     
Index: src/test/regress/sql/oid.sql
===================================================================
RCS file: /var/lib/cvs/pgsql-server/src/test/regress/sql/oid.sql,v
retrieving revision 1.4
diff -c -r1.4 oid.sql
*** a/src/test/regress/sql/oid.sql	21 Nov 2000 03:23:21 -0000	1.4
--- b/src/test/regress/sql/oid.sql	4 Mar 2004 00:33:10 -0000
***************
*** 14,21 ****
  
  INSERT INTO OID_TBL(f1) VALUES ('99999999');
  
- INSERT INTO OID_TBL(f1) VALUES ('');
- 
  -- bad inputs 
  
  INSERT INTO OID_TBL(f1) VALUES ('asdfasd');
--- 14,19 ----
---------------------------(end of broadcast)---------------------------
TIP 8: explain analyze is your friend

Reply via email to