Make char(n) and varchar(n) types raise an error if the inserted string is
authorPeter Eisentraut
Mon, 21 May 2001 16:54:46 +0000 (16:54 +0000)
committerPeter Eisentraut
Mon, 21 May 2001 16:54:46 +0000 (16:54 +0000)
too long.  While I was adjusting the regression tests I moved the array
things all into array.sql, to make things more manageable.

14 files changed:
doc/src/sgml/datatype.sgml
src/backend/utils/adt/varchar.c
src/test/regress/expected/arrays.out
src/test/regress/expected/char.out
src/test/regress/expected/create_misc.out
src/test/regress/expected/create_table.out
src/test/regress/expected/strings.out
src/test/regress/expected/varchar.out
src/test/regress/sql/arrays.sql
src/test/regress/sql/char.sql
src/test/regress/sql/create_misc.sql
src/test/regress/sql/create_table.sql
src/test/regress/sql/strings.sql
src/test/regress/sql/varchar.sql

index 93f733e50fd38dab93905927496a1b46a48773f3..bbbc85197bb725b4df47fc3b9e85460d0918f80c 100644 (file)
@@ -1,5 +1,5 @@
 
 
  
@@ -550,31 +550,13 @@ CREATE TABLE tablename (
     character strings
    
 
-   
-    SQL defines two primary character types:
-    character and character varying
-    Postgres supports these types, in
-    addition to the more general text type, 
-    which unlike character varying
-    does not require an explicit declared upper
-    limit on the size of the field.
-   
-
-   
-    Refer to  for information about
-    the syntax of string literals, and to 
-    for information about available operators and functions.
-   
-
-   
     
      Character Types
-     4">
+     3">
       
        
    Type Name
    Storage
-   Recommendation
    Description
        
       
@@ -582,33 +564,115 @@ CREATE TABLE tablename (
        
    character(n), char(n)
    (4+n) bytes
-   SQL-compatible
    Fixed-length blank padded
        
        
    character varying(n), varchar(n)
    (4+n) bytes
-   SQL-compatible
    Variable-length with limit
        
        
    text
    (4+n) bytes
-   Most flexible
    Variable unlimited length
        
       
      
     
 
-    
-     
-      Although the type text is not SQL-compliant, many
-      other RDBMS packages have it as well.
-     
-    
+   
+    SQL defines two primary character types:
+    character(n) and character
+    varying(n), where n is a
+    positive integer.  Both of these types can store strings up to
+    n characters in length.  An attempt to store a
+    longer string into a column of these types will result in an
+    error, unless the excess characters are all spaces, in which case
+    the string will be truncated to the maximum length.  (This
+    somewhat bizarre exception is required by the SQL standard.)  If
+    the string to be stored is shorter than the declared length,
+    values of type character will be space-padded; values
+    of type character varying will simply store the
+    shorter string.
+   
+
+   
+    
+     Prior to PostgreSQL 7.2, strings that were too long were silently
+     truncated, no error was raised.
+    
+   
+
+   
+    The notations char(n) and
+    varchar(n) are aliases for
+    character(n) and character
+    varying(n),
+    respectively. character without length specifier is
+    equivalent to character(1); if character
+    varying is used without length specifier, the type accepts
+    strings of any size.  The latter is a PostgreSQL extension.
    
 
+   
+    In addition, PostgreSQL supports the
+    more general text type, which stores strings of any
+    length.  Unlike character varyingtext
+    does not require an explicit declared upper limit on the size of
+    the string.  Although the type text is not in the SQL
+    standard, many other RDBMS packages have it as well.
+   
+
+   
+    Refer to  for information about
+    the syntax of string literals, and to 
+    for information about available operators and functions.
+   
+
+   
+    
+     There are no performance differences between these three types,
+     apart from the increased storage size when using the blank-padded
+     type.
+    
+   
+
+   
+    Using the character types
+
+
+CREATE TABLE test1 (a character(4));
+INSERT INTO test1 VALUES ('ok');
+SELECT a, char_length(a) FROM test1; -- 
+
+  a   | char_length
+------+-------------
+ ok   |           4
+
+
+CREATE TABLE test2 (b varchar(5));
+INSERT INTO test2 VALUES ('ok');
+INSERT INTO test2 VALUES ('good      ');
+INSERT INTO test2 VALUES ('too long');
+ERROR:  value too long for type character varying(5)
+SELECT b, char_length(b) FROM test2;
+
+   b   | char_length
+-------+-------------
+ ok    |           2
+ good  |           5
+
+
+    
+     
+      
+       The char_length function is discussed in
+       .
+      
+     
+    
+   
+
    
     There are two other fixed-length character types in
     Postgres.  The name type
@@ -625,7 +689,6 @@ CREATE TABLE tablename (
     enumeration type.
    
 
-   
     
      Specialty Character Type
      
@@ -650,7 +713,6 @@ CREATE TABLE tablename (
       
      
     
-   
 
   
 
index 588c735ca10faa6f703b719dbf80d1f062d9f17e..467a5cf7de3975223533af95ce35804d539949ac 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.77 2001/05/03 19:00:36 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.78 2001/05/21 16:54:46 petere Exp $
  *
  *-------------------------------------------------------------------------
  */
  *****************************************************************************/
 
 /*
- * bpcharin -
- *   converts a string of char() type to the internal representation.
- *   len is the length specified in () plus VARHDRSZ bytes.
+ * Convert a C string to CHARACTER internal representation.  atttypmod
+ * is the declared length of the type plus VARHDRSZ.
+ *
+ * If the C string is too long, raise an error, unless the extra
+ * characters are spaces, in which case they're truncated.  (per SQL)
  */
 Datum
 bpcharin(PG_FUNCTION_ARGS)
@@ -71,30 +73,33 @@ bpcharin(PG_FUNCTION_ARGS)
    int32       atttypmod = PG_GETARG_INT32(2);
    BpChar     *result;
    char       *r;
-   int         len;
+   size_t      len, maxlen;
    int         i;
 
-   if (atttypmod < (int32) VARHDRSZ)
+   len = strlen(s);
+   maxlen = atttypmod - VARHDRSZ;
+
+   if (atttypmod >= (int32) VARHDRSZ && len > maxlen)
    {
-       /* If typmod is -1 (or invalid), use the actual string length */
-       len = strlen(s);
-       atttypmod = len + VARHDRSZ;
-   }
-   else
 #ifdef MULTIBYTE
-   {
+       size_t mbmaxlen = pg_mbcliplen(s, len, maxlen);
 
-       /*
-        * truncate multi-byte string preserving multi-byte boundary
-        */
-       len = pg_mbcliplen(s, atttypmod - VARHDRSZ, atttypmod - VARHDRSZ);
-   }
+       if (strspn(s + mbmaxlen, " ") == len - mbmaxlen)
+           len = mbmaxlen;
 #else
-       len = atttypmod - VARHDRSZ;
+       if (strspn(s + maxlen, " ") == len - maxlen)
+           /* clip extra spaces */
+           len = maxlen;
 #endif
+       else
+           elog(ERROR, "value too long for type character(%d)", maxlen);
+   }
+   else
+       /* If typmod is -1 (or invalid), use the actual string length */
+       maxlen = len;
 
-   result = (BpChar *) palloc(atttypmod);
-   VARATT_SIZEP(result) = atttypmod;
+   result = palloc(maxlen + VARHDRSZ);
+   VARATT_SIZEP(result) = maxlen + VARHDRSZ;
    r = VARDATA(result);
    for (i = 0; i < len; i++, r++, s++)
    {
@@ -108,16 +113,16 @@ bpcharin(PG_FUNCTION_ARGS)
 #endif
 
    /* blank pad the string if necessary */
-#ifdef MULTIBYTE
-   for (; i < atttypmod - VARHDRSZ; i++)
-#else
-   for (; i < len; i++)
-#endif
+   for (; i < maxlen; i++)
        *r++ = ' ';
 
    PG_RETURN_BPCHAR_P(result);
 }
 
+
+/*
+ * Convert a CHARACTER value to a C string.
+ */
 Datum
 bpcharout(PG_FUNCTION_ARGS)
 {
@@ -138,75 +143,70 @@ bpcharout(PG_FUNCTION_ARGS)
    PG_RETURN_CSTRING(result);
 }
 
-/* bpchar()
- * Converts a char() type to a specific internal length.
- * len is the length specified in () plus VARHDRSZ bytes.
+
+/*
+ * Converts a CHARACTER type to the specified size.  maxlen is the new
+ * declared length plus VARHDRSZ bytes.  Truncation
+ * rules see bpcharin() above.
  */
 Datum
 bpchar(PG_FUNCTION_ARGS)
 {
-   BpChar     *str = PG_GETARG_BPCHAR_P(0);
-   int32       len = PG_GETARG_INT32(1);
+   BpChar     *source = PG_GETARG_BPCHAR_P(0);
+   int32       maxlen = PG_GETARG_INT32(1);
    BpChar     *result;
-   char       *r,
-              *s;
-   int         rlen,
-               slen;
+   int32       len;
+   char       *r;
+   char       *s;
    int         i;
 
+   len = VARSIZE(source);
    /* No work if typmod is invalid or supplied data matches it already */
-   if (len < (int32) VARHDRSZ || len == VARSIZE(str))
-       PG_RETURN_BPCHAR_P(str);
+   if (len < (int32) VARHDRSZ || len == maxlen)
+       PG_RETURN_BPCHAR_P(source);
 
-   rlen = len - VARHDRSZ;
-
-#ifdef STRINGDEBUG
-   printf("bpchar- convert string length %d (%d) ->%d (%d)\n",
-          VARSIZE(str) - VARHDRSZ, VARSIZE(str), rlen, len);
-#endif
+   if (len > maxlen)
+   {
+#ifdef MULTIBYTE
+       size_t      maxmblen;
 
-   result = (BpChar *) palloc(len);
-   VARATT_SIZEP(result) = len;
-   r = VARDATA(result);
+       maxmblen = pg_mbcliplen(VARDATA(source), len - VARHDRSZ,
+                               maxlen - VARHDRSZ) + VARHDRSZ;
 
-#ifdef MULTIBYTE
+       for (i = maxmblen - VARHDRSZ; i < len - VARHDRSZ; i++)
+           if (*(VARDATA(source) + i) != ' ')
+               elog(ERROR, "value too long for type character(%d)",
+                    maxlen - VARHDRSZ);
 
-   /*
-    * truncate multi-byte string in a way not to break multi-byte
-    * boundary
-    */
-   if (VARSIZE(str) > len)
-       slen = pg_mbcliplen(VARDATA(str), VARSIZE(str) - VARHDRSZ, rlen);
-   else
-       slen = VARSIZE(str) - VARHDRSZ;
+       len = maxmblen;
 #else
-   slen = VARSIZE(str) - VARHDRSZ;
-#endif
-   s = VARDATA(str);
+       for (i = maxlen - VARHDRSZ; i < len - VARHDRSZ; i++)
+           if (*(VARDATA(source) + i) != ' ')
+               elog(ERROR, "value too long for type character(%d)",
+                    maxlen - VARHDRSZ);
 
-#ifdef STRINGDEBUG
-   printf("bpchar- string is '");
+       /* clip extra spaces */
+       len = maxlen;
 #endif
-
-   for (i = 0; (i < rlen) && (i < slen); i++)
-   {
-#ifdef STRINGDEBUG
-       printf("%c", *s);
-#endif
-       *r++ = *s++;
    }
 
-#ifdef STRINGDEBUG
-   printf("'\n");
-#endif
+   s = VARDATA(source);
+
+   result = palloc(maxlen);
+   VARATT_SIZEP(result) = maxlen;
+   r = VARDATA(result);
+
+   for (i = 0; (i < maxlen - VARHDRSZ) && (i < len - VARHDRSZ); i++)
+       *r++ = *s++;
 
    /* blank pad the string if necessary */
-   for (; i < rlen; i++)
+   for (; i < maxlen - VARHDRSZ; i++)
        *r++ = ' ';
 
    PG_RETURN_BPCHAR_P(result);
 }
 
+
 /* _bpchar()
  * Converts an array of char() elements to a specific internal length.
  * len is the length specified in () plus VARHDRSZ bytes.
@@ -330,9 +330,11 @@ name_bpchar(PG_FUNCTION_ARGS)
  *****************************************************************************/
 
 /*
- * varcharin -
- *   converts a string of varchar() type to the internal representation.
- *   len is the length specified in () plus VARHDRSZ bytes.
+ * Convert a C string to VARCHAR internal representation.  atttypmod
+ * is the declared length of the type plus VARHDRSZ.
+ *
+ * If the C string is too long, raise an error, unless the extra
+ * characters are spaces, in which case they're truncated.  (per SQL)
  */
 Datum
 varcharin(PG_FUNCTION_ARGS)
@@ -345,37 +347,52 @@ varcharin(PG_FUNCTION_ARGS)
 #endif
    int32       atttypmod = PG_GETARG_INT32(2);
    VarChar    *result;
-   int         len;
+   size_t      len, maxlen;
+
+   len = strlen(s);
+   maxlen = atttypmod - VARHDRSZ;
 
-   len = strlen(s) + VARHDRSZ;
-   if (atttypmod >= (int32) VARHDRSZ && len > atttypmod)
+   if (atttypmod >= (int32) VARHDRSZ && len > maxlen)
+   {
 #ifdef MULTIBYTE
-       len = pg_mbcliplen(s, len - VARHDRSZ, atttypmod - VARHDRSZ) + VARHDRSZ;
+       size_t mbmaxlen = pg_mbcliplen(s, len, maxlen);
+
+       if (strspn(s + mbmaxlen, " ") == len - mbmaxlen)
+           len = mbmaxlen;
 #else
-       len = atttypmod;        /* clip the string at max length */
+       if (strspn(s + maxlen, " ") == len - maxlen)
+           /* clip extra spaces */
+           len = maxlen;
 #endif
+       else
+           elog(ERROR, "value too long for type character varying(%d)", maxlen);
+   }
 
-   result = (VarChar *) palloc(len);
-   VARATT_SIZEP(result) = len;
-   memcpy(VARDATA(result), s, len - VARHDRSZ);
+   result = palloc(len + VARHDRSZ);
+   VARATT_SIZEP(result) = len + VARHDRSZ;
+   memcpy(VARDATA(result), s, len);
 
 #ifdef CYR_RECODE
-   convertstr(VARDATA(result), len - VARHDRSZ, 0);
+   convertstr(VARDATA(result), len, 0);
 #endif
 
    PG_RETURN_VARCHAR_P(result);
 }
 
+
+/*
+ * Convert a VARCHAR value to a C string.
+ */
 Datum
 varcharout(PG_FUNCTION_ARGS)
 {
    VarChar    *s = PG_GETARG_VARCHAR_P(0);
    char       *result;
-   int         len;
+   int32       len;
 
    /* copy and add null term */
    len = VARSIZE(s) - VARHDRSZ;
-   result = (char *) palloc(len + 1);
+   result = palloc(len + 1);
    memcpy(result, VARDATA(s), len);
    result[len] = '\0';
 
@@ -386,42 +403,60 @@ varcharout(PG_FUNCTION_ARGS)
    PG_RETURN_CSTRING(result);
 }
 
-/* varchar()
- * Converts a varchar() type to the specified size.
- * slen is the length specified in () plus VARHDRSZ bytes.
+
+/*
+ * Converts a VARCHAR type to the specified size.  maxlen is the new
+ * declared length plus VARHDRSZ bytes.  Truncation
+ * rules see varcharin() above.
  */
 Datum
 varchar(PG_FUNCTION_ARGS)
 {
-   VarChar    *s = PG_GETARG_VARCHAR_P(0);
-   int32       slen = PG_GETARG_INT32(1);
+   VarChar    *source = PG_GETARG_VARCHAR_P(0);
+   int32       maxlen = PG_GETARG_INT32(1);
    VarChar    *result;
-   int         len;
+   int32       len;
+   int         i;
 
-   len = VARSIZE(s);
-   if (slen < (int32) VARHDRSZ || len <= slen)
-       PG_RETURN_VARCHAR_P(s);
+   len = VARSIZE(source);
+   if (maxlen < (int32) VARHDRSZ || len <= maxlen)
+       PG_RETURN_VARCHAR_P(source);
 
-   /* only reach here if we need to truncate string... */
+   /* only reach here if string is too long... */
 
 #ifdef MULTIBYTE
+   {
+       size_t      maxmblen;
 
-   /*
-    * truncate multi-byte string preserving multi-byte boundary
-    */
-   len = pg_mbcliplen(VARDATA(s), slen - VARHDRSZ, slen - VARHDRSZ);
-   slen = len + VARHDRSZ;
+       /* truncate multi-byte string preserving multi-byte boundary */
+       maxmblen = pg_mbcliplen(VARDATA(source), len - VARHDRSZ,
+                               maxlen - VARHDRSZ) + VARHDRSZ;
+
+       for (i = maxmblen - VARHDRSZ; i < len - VARHDRSZ; i++)
+           if (*(VARDATA(source) + i) != ' ')
+               elog(ERROR, "value too long for type character varying(%d)",
+                    maxlen - VARHDRSZ);
+
+       len = maxmblen;
+   }
 #else
-   len = slen - VARHDRSZ;
+   for (i = maxlen - VARHDRSZ; i < len - VARHDRSZ; i++)
+       if (*(VARDATA(source) + i) != ' ')
+           elog(ERROR, "value too long for type character varying(%d)",
+                maxlen - VARHDRSZ);
+
+   /* clip extra spaces */
+   len = maxlen;
 #endif
 
-   result = (VarChar *) palloc(slen);
-   VARATT_SIZEP(result) = slen;
-   memcpy(VARDATA(result), VARDATA(s), len);
+   result = palloc(len);
+   VARATT_SIZEP(result) = len;
+   memcpy(VARDATA(result), VARDATA(source), len - VARHDRSZ);
 
    PG_RETURN_VARCHAR_P(result);
 }
 
+
 /* _varchar()
  * Converts an array of varchar() elements to the specified size.
  * len is the length specified in () plus VARHDRSZ bytes.
@@ -452,6 +487,12 @@ _varchar(PG_FUNCTION_ARGS)
    return array_map(&locfcinfo, VARCHAROID, VARCHAROID);
 }
 
+
+
+/*****************************************************************************
+ * Exported functions
+ *****************************************************************************/
+
 /* "True" length (not counting trailing blanks) of a BpChar */
 static int
 bcTruelen(BpChar *arg)
index b68783806402aed6a04cc6de7b54b63056d77fe7..74c1008d907582c812530250cb9b8a46104cc467 100644 (file)
@@ -1,6 +1,32 @@
 --
 -- ARRAYS
 --
+CREATE TABLE arrtest (
+   a           int2[],
+   b           int4[][][],
+   c           name[],
+   d           text[][], 
+   e           float8[],
+   f           char(5)[],
+   g           varchar(5)[]
+);
+--
+-- only this array as a 0-based 'e', the others are 1-based.
+-- 'e' is also a large object.
+--
+INSERT INTO arrtest (a[5], b[2][1][2], c, d, f, g)
+   VALUES ('{1,2,3,4,5}', '{{{},{1,2}}}', '{}', '{}', '{}', '{}');
+UPDATE arrtest SET e[0] = '1.1';
+UPDATE arrtest SET e[1] = '2.2';
+INSERT INTO arrtest (f)
+   VALUES ('{"too long"}');
+ERROR:  value too long for type character(5)
+INSERT INTO arrtest (a, b[2][2][1], c, d, e, f, g)
+   VALUES ('{11,12,23}', '{{3,4},{4,5}}', '{"foobar"}', 
+           '{{"elt1", "elt2"}}', '{"3.4", "6.7"}',
+           '{"abc","abcde"}', '{"abc","abcde"}');
+INSERT INTO arrtest (a, b[1][2][2], c, d[2][1])
+   VALUES ('{}', '{3,4}', '{foo,bar}', '{bar,foo}');
 SELECT * FROM arrtest;
       a      |        b        |       c       |         d         |       e       |         f         |        g        
 -------------+-----------------+---------------+-------------------+---------------+-------------------+-----------------
@@ -75,8 +101,8 @@ SELECT a,b,c FROM arrtest;
        a       |           b           |           c           
 ---------------+-----------------------+-----------------------
  {16,25,3,4,5} | {{{113,142},{1,147}}} | {}
- {16,25,23}    | {{3,4},{4,5}}         | {"foobar","new_word"}
  {}            | {3,4}                 | {"foo","new_word"}
+ {16,25,23}    | {{3,4},{4,5}}         | {"foobar","new_word"}
 (3 rows)
 
 SELECT a[1:3],
@@ -87,7 +113,7 @@ SELECT a[1:3],
      a      |           b           |           c           |     d      
 ------------+-----------------------+-----------------------+------------
  {16,25,3}  | {{{113,142},{1,147}}} |                       | 
- {16,25,23} |                       | {"foobar","new_word"} | {{"elt2"}}
             |                       | {"foo","new_word"}    | 
+ {16,25,23} |                       | {"foobar","new_word"} | {{"elt2"}}
 (3 rows)
 
index 63606fba2d254545829fd0398fec1b6221954709..0c46e07976233fc0c6e7e3f947b5c1c490111189 100644 (file)
@@ -1,6 +1,5 @@
 --
 -- CHAR
--- all inputs are SILENTLY truncated at 1 character
 --
 -- fixed-length by value
 -- internally passed by value if <= 4 bytes in storage
@@ -24,6 +23,8 @@ INSERT INTO CHAR_TBL (f1) VALUES ('3');
 INSERT INTO CHAR_TBL (f1) VALUES ('');
 -- try char's of greater than 1 length 
 INSERT INTO CHAR_TBL (f1) VALUES ('cd');
+ERROR:  value too long for type character(1)
+INSERT INTO CHAR_TBL (f1) VALUES ('c     ');
 SELECT '' AS seven, CHAR_TBL.*;
  seven | f1 
 -------+----
@@ -108,6 +109,8 @@ INSERT INTO CHAR_TBL (f1) VALUES ('a');
 INSERT INTO CHAR_TBL (f1) VALUES ('ab');
 INSERT INTO CHAR_TBL (f1) VALUES ('abcd');
 INSERT INTO CHAR_TBL (f1) VALUES ('abcde');
+ERROR:  value too long for type character(4)
+INSERT INTO CHAR_TBL (f1) VALUES ('abcd    ');
 SELECT '' AS four, CHAR_TBL.*;
  four |  f1  
 ------+------
index add55bc767afd1b57fe409bd0a93f07222f0a20f..c7600fd13ff0d329bcc4130d7f6da13760d3de2e 100644 (file)
@@ -121,23 +121,6 @@ INSERT INTO f_star (class, f)
    VALUES ('f', '(11111111,33333333),(22222222,44444444)'::polygon);
 INSERT INTO f_star (class) VALUES ('f');
 --
--- ARRAYS
---
---
--- only this array as a 0-based 'e', the others are 1-based.
--- 'e' is also a large object.
---
-INSERT INTO arrtest (a[5], b[2][1][2], c, d, f, g)
-   VALUES ('{1,2,3,4,5}', '{{{},{1,2}}}', '{}', '{}', '{}', '{}');
-UPDATE arrtest SET e[0] = '1.1';
-UPDATE arrtest SET e[1] = '2.2';
-INSERT INTO arrtest (a, b[2][2][1], c, d, e, f, g)
-   VALUES ('{11,12,23}', '{{3,4},{4,5}}', '{"foobar"}', 
-           '{{"elt1", "elt2"}}', '{"3.4", "6.7"}',
-           '{"abc","abcdefgh"}', '{"abc","abcdefgh"}');
-INSERT INTO arrtest (a, b[1][2][2], c, d[2][1])
-   VALUES ('{}', '{3,4}', '{foo,bar}', '{bar,foo}');
---
 -- for internal portal (cursor) tests
 --
 CREATE TABLE iportaltest (
index a0ddd5ef609a3367d567673255ea75877381b1e7..3734960691d848c966748ed2d23c2cc32b0ec74e 100644 (file)
@@ -147,15 +147,6 @@ CREATE TABLE aggtest (
    a           int2,
    b           float4
 );
-CREATE TABLE arrtest (
-   a           int2[],
-   b           int4[][][],
-   c           name[],
-   d           text[][], 
-   e           float8[],
-   f           char(5)[],
-   g           varchar(5)[]
-);
 CREATE TABLE hash_i4_heap (
    seqno       int4,
    random      int4
index e59ba8e1df5f8494f7884339319af1098b17635f..7562a25fdca5399ae0c4b745243c76a38b4e1afe 100644 (file)
@@ -45,11 +45,13 @@ SELECT CAST(name 'namefield' AS text) AS "text(name)";
  namefield
 (1 row)
 
-SELECT CAST(f1 AS char(10)) AS "char(text)" FROM TEXT_TBL;
- char(text) 
-------------
- doh!      
- hi de ho n
+SELECT CAST(f1 AS char(10)) AS "char(text)" FROM TEXT_TBL; -- fail
+ERROR:  value too long for type character(10)
+SELECT CAST(f1 AS char(20)) AS "char(text)" FROM TEXT_TBL;
+      char(text)      
+----------------------
+ doh!                
+ hi de ho neighbor   
 (2 rows)
 
 SELECT CAST(f1 AS char(10)) AS "char(varchar)" FROM VARCHAR_TBL;
@@ -479,10 +481,10 @@ SELECT text 'text' || ' and unknown' AS "Concat text to unknown type";
  text and unknown
 (1 row)
 
-SELECT text 'text' || char(10) ' and characters' AS "Concat text to char";
+SELECT text 'text' || char(20) ' and characters' AS "Concat text to char";
  Concat text to char 
 ---------------------
- text and chara
+ text and characters
 (1 row)
 
 SELECT text 'text' || varchar ' and varchar' AS "Concat text to varchar";
index 5f4c0f1f56f3b56cad70030f4bc46d8113652546..e33782eed74a818666bcc93591cd3d6fafeb9df5 100644 (file)
@@ -12,6 +12,8 @@ INSERT INTO VARCHAR_TBL (f1) VALUES ('3');
 INSERT INTO VARCHAR_TBL (f1) VALUES ('');
 -- try varchar's of greater than 1 length 
 INSERT INTO VARCHAR_TBL (f1) VALUES ('cd');
+ERROR:  value too long for type character varying(1)
+INSERT INTO VARCHAR_TBL (f1) VALUES ('c     ');
 SELECT '' AS seven, VARCHAR_TBL.*;
  seven | f1 
 -------+----
@@ -96,6 +98,8 @@ INSERT INTO VARCHAR_TBL (f1) VALUES ('a');
 INSERT INTO VARCHAR_TBL (f1) VALUES ('ab');
 INSERT INTO VARCHAR_TBL (f1) VALUES ('abcd');
 INSERT INTO VARCHAR_TBL (f1) VALUES ('abcde');
+ERROR:  value too long for type character varying(4)
+INSERT INTO VARCHAR_TBL (f1) VALUES ('abcd    ');
 SELECT '' AS four, VARCHAR_TBL.*;
  four |  f1  
 ------+------
index 3b02acf6427252a14e57a2aca414fbc28e9a8ad7..a3300eae129d2fea48c7961bf8b5fec5b9cc1ffb 100644 (file)
@@ -2,6 +2,40 @@
 -- ARRAYS
 --
 
+CREATE TABLE arrtest (
+   a           int2[],
+   b           int4[][][],
+   c           name[],
+   d           text[][], 
+   e           float8[],
+   f           char(5)[],
+   g           varchar(5)[]
+);
+
+--
+-- only this array as a 0-based 'e', the others are 1-based.
+-- 'e' is also a large object.
+--
+
+INSERT INTO arrtest (a[5], b[2][1][2], c, d, f, g)
+   VALUES ('{1,2,3,4,5}', '{{{},{1,2}}}', '{}', '{}', '{}', '{}');
+
+UPDATE arrtest SET e[0] = '1.1';
+
+UPDATE arrtest SET e[1] = '2.2';
+
+INSERT INTO arrtest (f)
+   VALUES ('{"too long"}');
+
+INSERT INTO arrtest (a, b[2][2][1], c, d, e, f, g)
+   VALUES ('{11,12,23}', '{{3,4},{4,5}}', '{"foobar"}', 
+           '{{"elt1", "elt2"}}', '{"3.4", "6.7"}',
+           '{"abc","abcde"}', '{"abc","abcde"}');
+
+INSERT INTO arrtest (a, b[1][2][2], c, d[2][1])
+   VALUES ('{}', '{3,4}', '{foo,bar}', '{bar,foo}');
+
+
 SELECT * FROM arrtest;
 
 SELECT arrtest.a[1],
index ba7167fc659b167c63154c3a06a267f7a079ef70..049f22fad39e5cbbdc7203db59932981d61c6203 100644 (file)
@@ -1,6 +1,5 @@
 --
 -- CHAR
--- all inputs are SILENTLY truncated at 1 character
 --
 
 -- fixed-length by value
@@ -30,6 +29,7 @@ INSERT INTO CHAR_TBL (f1) VALUES ('');
 
 -- try char's of greater than 1 length 
 INSERT INTO CHAR_TBL (f1) VALUES ('cd');
+INSERT INTO CHAR_TBL (f1) VALUES ('c     ');
 
 
 SELECT '' AS seven, CHAR_TBL.*;
@@ -70,6 +70,6 @@ INSERT INTO CHAR_TBL (f1) VALUES ('a');
 INSERT INTO CHAR_TBL (f1) VALUES ('ab');
 INSERT INTO CHAR_TBL (f1) VALUES ('abcd');
 INSERT INTO CHAR_TBL (f1) VALUES ('abcde');
+INSERT INTO CHAR_TBL (f1) VALUES ('abcd    ');
 
 SELECT '' AS four, CHAR_TBL.*;
-
index cd73f64060513bb34dc15c48ec4b09cc506bfced..078450a754416d6fa421bebc42080f260b66f05f 100644 (file)
@@ -188,30 +188,6 @@ INSERT INTO f_star (class, f)
 
 INSERT INTO f_star (class) VALUES ('f');
 
---
--- ARRAYS
---
-
---
--- only this array as a 0-based 'e', the others are 1-based.
--- 'e' is also a large object.
---
-
-INSERT INTO arrtest (a[5], b[2][1][2], c, d, f, g)
-   VALUES ('{1,2,3,4,5}', '{{{},{1,2}}}', '{}', '{}', '{}', '{}');
-
-UPDATE arrtest SET e[0] = '1.1';
-
-UPDATE arrtest SET e[1] = '2.2';
-
-INSERT INTO arrtest (a, b[2][2][1], c, d, e, f, g)
-   VALUES ('{11,12,23}', '{{3,4},{4,5}}', '{"foobar"}', 
-           '{{"elt1", "elt2"}}', '{"3.4", "6.7"}',
-           '{"abc","abcdefgh"}', '{"abc","abcdefgh"}');
-
-INSERT INTO arrtest (a, b[1][2][2], c, d[2][1])
-   VALUES ('{}', '{3,4}', '{foo,bar}', '{bar,foo}');
-
 
 --
 -- for internal portal (cursor) tests
index fe5470894483fa7cfadcb5293966f8342bfb5023..b6a0a8fe603d37d6b071657a9a4238c8799ddcca 100644 (file)
@@ -172,16 +172,6 @@ CREATE TABLE aggtest (
    b           float4
 );
 
-CREATE TABLE arrtest (
-   a           int2[],
-   b           int4[][][],
-   c           name[],
-   d           text[][], 
-   e           float8[],
-   f           char(5)[],
-   g           varchar(5)[]
-);
-
 CREATE TABLE hash_i4_heap (
    seqno       int4,
    random      int4
index f1c7d5f298911bd586f0bbb835030cc5acdc9578..56510f83dddc9eee78dadaae42adfbc6340d8933 100644 (file)
@@ -25,7 +25,9 @@ SELECT CAST(f1 AS text) AS "text(varchar)" FROM VARCHAR_TBL;
 
 SELECT CAST(name 'namefield' AS text) AS "text(name)";
 
-SELECT CAST(f1 AS char(10)) AS "char(text)" FROM TEXT_TBL;
+SELECT CAST(f1 AS char(10)) AS "char(text)" FROM TEXT_TBL; -- fail
+
+SELECT CAST(f1 AS char(20)) AS "char(text)" FROM TEXT_TBL;
 
 SELECT CAST(f1 AS char(10)) AS "char(varchar)" FROM VARCHAR_TBL;
 
@@ -158,7 +160,7 @@ SELECT 'unknown' || ' and unknown' AS "Concat unknown types";
 
 SELECT text 'text' || ' and unknown' AS "Concat text to unknown type";
 
-SELECT text 'text' || char(10) ' and characters' AS "Concat text to char";
+SELECT text 'text' || char(20) ' and characters' AS "Concat text to char";
 
 SELECT text 'text' || varchar ' and varchar' AS "Concat text to varchar";
 
index e28c8f9b932bc8e52f1fbbb82b8f591b53e79f94..70fa8afb4b3754bc06240f419f67363a9ec56f4b 100644 (file)
@@ -20,6 +20,7 @@ INSERT INTO VARCHAR_TBL (f1) VALUES ('');
 
 -- try varchar's of greater than 1 length 
 INSERT INTO VARCHAR_TBL (f1) VALUES ('cd');
+INSERT INTO VARCHAR_TBL (f1) VALUES ('c     ');
 
 
 SELECT '' AS seven, VARCHAR_TBL.*;
@@ -60,6 +61,6 @@ INSERT INTO VARCHAR_TBL (f1) VALUES ('a');
 INSERT INTO VARCHAR_TBL (f1) VALUES ('ab');
 INSERT INTO VARCHAR_TBL (f1) VALUES ('abcd');
 INSERT INTO VARCHAR_TBL (f1) VALUES ('abcde');
+INSERT INTO VARCHAR_TBL (f1) VALUES ('abcd    ');
 
 SELECT '' AS four, VARCHAR_TBL.*;
-