aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/src/sgml/datatype.sgml124
-rw-r--r--src/backend/utils/adt/varchar.c247
-rw-r--r--src/test/regress/expected/arrays.out30
-rw-r--r--src/test/regress/expected/char.out5
-rw-r--r--src/test/regress/expected/create_misc.out17
-rw-r--r--src/test/regress/expected/create_table.out9
-rw-r--r--src/test/regress/expected/strings.out16
-rw-r--r--src/test/regress/expected/varchar.out4
-rw-r--r--src/test/regress/sql/arrays.sql34
-rw-r--r--src/test/regress/sql/char.sql4
-rw-r--r--src/test/regress/sql/create_misc.sql24
-rw-r--r--src/test/regress/sql/create_table.sql10
-rw-r--r--src/test/regress/sql/strings.sql6
-rw-r--r--src/test/regress/sql/varchar.sql3
14 files changed, 324 insertions, 209 deletions
diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml
index 93f733e50fd..bbbc85197bb 100644
--- a/doc/src/sgml/datatype.sgml
+++ b/doc/src/sgml/datatype.sgml
@@ -1,5 +1,5 @@
<!--
-$Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.53 2001/05/12 22:51:34 petere Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.54 2001/05/21 16:54:45 petere Exp $
-->
<chapter id="datatype">
@@ -550,31 +550,13 @@ CREATE TABLE <replaceable class="parameter">tablename</replaceable> (<replaceabl
<see>character strings</see>
</indexterm>
- <para>
- <acronym>SQL</acronym> defines two primary character types:
- <type>character</type> and <type>character varying</type>.
- <productname>Postgres</productname> supports these types, in
- addition to the more general <type>text</type> type,
- which unlike <type>character varying</type>
- does not require an explicit declared upper
- limit on the size of the field.
- </para>
-
- <para>
- Refer to <xref linkend="sql-syntax-strings"> for information about
- the syntax of string literals, and to <xref linkend="functions">
- for information about available operators and functions.
- </para>
-
- <para>
<table tocentry="1">
<title>Character Types</title>
- <tgroup cols="4">
+ <tgroup cols="3">
<thead>
<row>
<entry>Type Name</entry>
<entry>Storage</entry>
- <entry>Recommendation</entry>
<entry>Description</entry>
</row>
</thead>
@@ -582,34 +564,116 @@ CREATE TABLE <replaceable class="parameter">tablename</replaceable> (<replaceabl
<row>
<entry>character(n), char(n)</entry>
<entry>(4+n) bytes</entry>
- <entry><acronym>SQL</acronym>-compatible</entry>
<entry>Fixed-length blank padded</entry>
</row>
<row>
<entry>character varying(n), varchar(n)</entry>
<entry>(4+n) bytes</entry>
- <entry><acronym>SQL</acronym>-compatible</entry>
<entry>Variable-length with limit</entry>
</row>
<row>
<entry>text</entry>
<entry>(4+n) bytes</entry>
- <entry>Most flexible</entry>
<entry>Variable unlimited length</entry>
</row>
</tbody>
</tgroup>
</table>
- <note>
- <para>
- Although the type <type>text</type> is not SQL-compliant, many
- other RDBMS packages have it as well.
- </para>
- </note>
+ <para>
+ <acronym>SQL</acronym> defines two primary character types:
+ <type>character(<replaceable>n</>)</type> and <type>character
+ varying(<replaceable>n</>)</type>, where <replaceable>n</> is a
+ positive integer. Both of these types can store strings up to
+ <replaceable>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 <type>character</type> will be space-padded; values
+ of type <type>character varying</type> will simply store the
+ shorter string.
+ </para>
+
+ <note>
+ <para>
+ Prior to PostgreSQL 7.2, strings that were too long were silently
+ truncated, no error was raised.
+ </para>
+ </note>
+
+ <para>
+ The notations <type>char(<replaceable>n</>)</type> and
+ <type>varchar(<replaceable>n</>)</type> are aliases for
+ <type>character(<replaceable>n</>)</type> and <type>character
+ varying(<replaceable>n</>)</type>,
+ respectively. <type>character</type> without length specifier is
+ equivalent to <type>character(1)</type>; if <type>character
+ varying</type> is used without length specifier, the type accepts
+ strings of any size. The latter is a PostgreSQL extension.
</para>
<para>
+ In addition, <productname>PostgreSQL</productname> supports the
+ more general <type>text</type> type, which stores strings of any
+ length. Unlike <type>character varying</type>, <type>text</type>
+ does not require an explicit declared upper limit on the size of
+ the string. Although the type <type>text</type> is not in the SQL
+ standard, many other RDBMS packages have it as well.
+ </para>
+
+ <para>
+ Refer to <xref linkend="sql-syntax-strings"> for information about
+ the syntax of string literals, and to <xref linkend="functions">
+ for information about available operators and functions.
+ </para>
+
+ <tip>
+ <para>
+ There are no performance differences between these three types,
+ apart from the increased storage size when using the blank-padded
+ type.
+ </para>
+ </tip>
+
+ <example>
+ <title>Using the character types</title>
+
+<programlisting>
+CREATE TABLE test1 (a character(4));
+INSERT INTO test1 VALUES ('ok');
+SELECT a, char_length(a) FROM test1; -- <co id="co.datatype-char">
+<computeroutput>
+ a | char_length
+------+-------------
+ ok | 4
+</computeroutput>
+
+CREATE TABLE test2 (b varchar(5));
+INSERT INTO test2 VALUES ('ok');
+INSERT INTO test2 VALUES ('good ');
+INSERT INTO test2 VALUES ('too long');
+<computeroutput>ERROR: value too long for type character varying(5)</computeroutput>
+SELECT b, char_length(b) FROM test2;
+<computeroutput>
+ b | char_length
+-------+-------------
+ ok | 2
+ good | 5
+</computeroutput>
+</programlisting>
+ <calloutlist>
+ <callout arearefs="co.datatype-char">
+ <para>
+ The <function>char_length</function> function is discussed in
+ <xref linkend="functions-string">.
+ </para>
+ </callout>
+ </calloutlist>
+ </example>
+
+ <para>
There are two other fixed-length character types in
<productname>Postgres</productname>. The <type>name</type> type
exists <emphasis>only</emphasis> for storage of internal catalog
@@ -625,7 +689,6 @@ CREATE TABLE <replaceable class="parameter">tablename</replaceable> (<replaceabl
enumeration type.
</para>
- <para>
<table tocentry="1">
<title>Specialty Character Type</title>
<tgroup cols="3">
@@ -650,7 +713,6 @@ CREATE TABLE <replaceable class="parameter">tablename</replaceable> (<replaceabl
</tbody>
</tgroup>
</table>
- </para>
</sect1>
diff --git a/src/backend/utils/adt/varchar.c b/src/backend/utils/adt/varchar.c
index 588c735ca10..467a5cf7de3 100644
--- a/src/backend/utils/adt/varchar.c
+++ b/src/backend/utils/adt/varchar.c
@@ -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 $
*
*-------------------------------------------------------------------------
*/
@@ -55,9 +55,11 @@
*****************************************************************************/
/*
- * 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)
diff --git a/src/test/regress/expected/arrays.out b/src/test/regress/expected/arrays.out
index b6878380640..74c1008d907 100644
--- a/src/test/regress/expected/arrays.out
+++ b/src/test/regress/expected/arrays.out
@@ -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)
diff --git a/src/test/regress/expected/char.out b/src/test/regress/expected/char.out
index 63606fba2d2..0c46e079762 100644
--- a/src/test/regress/expected/char.out
+++ b/src/test/regress/expected/char.out
@@ -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
------+------
diff --git a/src/test/regress/expected/create_misc.out b/src/test/regress/expected/create_misc.out
index add55bc767a..c7600fd13ff 100644
--- a/src/test/regress/expected/create_misc.out
+++ b/src/test/regress/expected/create_misc.out
@@ -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 (
diff --git a/src/test/regress/expected/create_table.out b/src/test/regress/expected/create_table.out
index a0ddd5ef609..3734960691d 100644
--- a/src/test/regress/expected/create_table.out
+++ b/src/test/regress/expected/create_table.out
@@ -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
diff --git a/src/test/regress/expected/strings.out b/src/test/regress/expected/strings.out
index e59ba8e1df5..7562a25fdca 100644
--- a/src/test/regress/expected/strings.out
+++ b/src/test/regress/expected/strings.out
@@ -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";
diff --git a/src/test/regress/expected/varchar.out b/src/test/regress/expected/varchar.out
index 5f4c0f1f56f..e33782eed74 100644
--- a/src/test/regress/expected/varchar.out
+++ b/src/test/regress/expected/varchar.out
@@ -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
------+------
diff --git a/src/test/regress/sql/arrays.sql b/src/test/regress/sql/arrays.sql
index 3b02acf6427..a3300eae129 100644
--- a/src/test/regress/sql/arrays.sql
+++ b/src/test/regress/sql/arrays.sql
@@ -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],
diff --git a/src/test/regress/sql/char.sql b/src/test/regress/sql/char.sql
index ba7167fc659..049f22fad39 100644
--- a/src/test/regress/sql/char.sql
+++ b/src/test/regress/sql/char.sql
@@ -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.*;
-
diff --git a/src/test/regress/sql/create_misc.sql b/src/test/regress/sql/create_misc.sql
index cd73f640605..078450a7544 100644
--- a/src/test/regress/sql/create_misc.sql
+++ b/src/test/regress/sql/create_misc.sql
@@ -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
diff --git a/src/test/regress/sql/create_table.sql b/src/test/regress/sql/create_table.sql
index fe547089448..b6a0a8fe603 100644
--- a/src/test/regress/sql/create_table.sql
+++ b/src/test/regress/sql/create_table.sql
@@ -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
diff --git a/src/test/regress/sql/strings.sql b/src/test/regress/sql/strings.sql
index f1c7d5f2989..56510f83ddd 100644
--- a/src/test/regress/sql/strings.sql
+++ b/src/test/regress/sql/strings.sql
@@ -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";
diff --git a/src/test/regress/sql/varchar.sql b/src/test/regress/sql/varchar.sql
index e28c8f9b932..70fa8afb4b3 100644
--- a/src/test/regress/sql/varchar.sql
+++ b/src/test/regress/sql/varchar.sql
@@ -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.*;
-