mirror of
https://github.com/postgres/postgres.git
synced 2025-07-21 16:02:15 +03:00
Make char(n) and varchar(n) types raise an error if the inserted string is
too long. While I was adjusting the regression tests I moved the array things all into array.sql, to make things more manageable.
This commit is contained in:
@ -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">
|
<chapter id="datatype">
|
||||||
@ -550,14 +550,77 @@ CREATE TABLE <replaceable class="parameter">tablename</replaceable> (<replaceabl
|
|||||||
<see>character strings</see>
|
<see>character strings</see>
|
||||||
</indexterm>
|
</indexterm>
|
||||||
|
|
||||||
|
<table tocentry="1">
|
||||||
|
<title>Character Types</title>
|
||||||
|
<tgroup cols="3">
|
||||||
|
<thead>
|
||||||
|
<row>
|
||||||
|
<entry>Type Name</entry>
|
||||||
|
<entry>Storage</entry>
|
||||||
|
<entry>Description</entry>
|
||||||
|
</row>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<row>
|
||||||
|
<entry>character(n), char(n)</entry>
|
||||||
|
<entry>(4+n) bytes</entry>
|
||||||
|
<entry>Fixed-length blank padded</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry>character varying(n), varchar(n)</entry>
|
||||||
|
<entry>(4+n) bytes</entry>
|
||||||
|
<entry>Variable-length with limit</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry>text</entry>
|
||||||
|
<entry>(4+n) bytes</entry>
|
||||||
|
<entry>Variable unlimited length</entry>
|
||||||
|
</row>
|
||||||
|
</tbody>
|
||||||
|
</tgroup>
|
||||||
|
</table>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
<acronym>SQL</acronym> defines two primary character types:
|
<acronym>SQL</acronym> defines two primary character types:
|
||||||
<type>character</type> and <type>character varying</type>.
|
<type>character(<replaceable>n</>)</type> and <type>character
|
||||||
<productname>Postgres</productname> supports these types, in
|
varying(<replaceable>n</>)</type>, where <replaceable>n</> is a
|
||||||
addition to the more general <type>text</type> type,
|
positive integer. Both of these types can store strings up to
|
||||||
which unlike <type>character varying</type>
|
<replaceable>n</> characters in length. An attempt to store a
|
||||||
does not require an explicit declared upper
|
longer string into a column of these types will result in an
|
||||||
limit on the size of the field.
|
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>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@ -566,48 +629,49 @@ CREATE TABLE <replaceable class="parameter">tablename</replaceable> (<replaceabl
|
|||||||
for information about available operators and functions.
|
for information about available operators and functions.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<tip>
|
||||||
<table tocentry="1">
|
<para>
|
||||||
<title>Character Types</title>
|
There are no performance differences between these three types,
|
||||||
<tgroup cols="4">
|
apart from the increased storage size when using the blank-padded
|
||||||
<thead>
|
type.
|
||||||
<row>
|
</para>
|
||||||
<entry>Type Name</entry>
|
</tip>
|
||||||
<entry>Storage</entry>
|
|
||||||
<entry>Recommendation</entry>
|
|
||||||
<entry>Description</entry>
|
|
||||||
</row>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<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>
|
<example>
|
||||||
<para>
|
<title>Using the character types</title>
|
||||||
Although the type <type>text</type> is not SQL-compliant, many
|
|
||||||
other RDBMS packages have it as well.
|
<programlisting>
|
||||||
</para>
|
CREATE TABLE test1 (a character(4));
|
||||||
</note>
|
INSERT INTO test1 VALUES ('ok');
|
||||||
</para>
|
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>
|
<para>
|
||||||
There are two other fixed-length character types in
|
There are two other fixed-length character types in
|
||||||
@ -625,7 +689,6 @@ CREATE TABLE <replaceable class="parameter">tablename</replaceable> (<replaceabl
|
|||||||
enumeration type.
|
enumeration type.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
|
||||||
<table tocentry="1">
|
<table tocentry="1">
|
||||||
<title>Specialty Character Type</title>
|
<title>Specialty Character Type</title>
|
||||||
<tgroup cols="3">
|
<tgroup cols="3">
|
||||||
@ -650,7 +713,6 @@ CREATE TABLE <replaceable class="parameter">tablename</replaceable> (<replaceabl
|
|||||||
</tbody>
|
</tbody>
|
||||||
</tgroup>
|
</tgroup>
|
||||||
</table>
|
</table>
|
||||||
</para>
|
|
||||||
|
|
||||||
</sect1>
|
</sect1>
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 -
|
* Convert a C string to CHARACTER internal representation. atttypmod
|
||||||
* converts a string of char() type to the internal representation.
|
* is the declared length of the type plus VARHDRSZ.
|
||||||
* len is the length specified in () plus VARHDRSZ bytes.
|
*
|
||||||
|
* 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
|
Datum
|
||||||
bpcharin(PG_FUNCTION_ARGS)
|
bpcharin(PG_FUNCTION_ARGS)
|
||||||
@ -71,30 +73,33 @@ bpcharin(PG_FUNCTION_ARGS)
|
|||||||
int32 atttypmod = PG_GETARG_INT32(2);
|
int32 atttypmod = PG_GETARG_INT32(2);
|
||||||
BpChar *result;
|
BpChar *result;
|
||||||
char *r;
|
char *r;
|
||||||
int len;
|
size_t len, maxlen;
|
||||||
int i;
|
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 */
|
#ifdef MULTIBYTE
|
||||||
len = strlen(s);
|
size_t mbmaxlen = pg_mbcliplen(s, len, maxlen);
|
||||||
atttypmod = len + VARHDRSZ;
|
|
||||||
|
if (strspn(s + mbmaxlen, " ") == len - mbmaxlen)
|
||||||
|
len = mbmaxlen;
|
||||||
|
#else
|
||||||
|
if (strspn(s + maxlen, " ") == len - maxlen)
|
||||||
|
/* clip extra spaces */
|
||||||
|
len = maxlen;
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
elog(ERROR, "value too long for type character(%d)", maxlen);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#ifdef MULTIBYTE
|
/* If typmod is -1 (or invalid), use the actual string length */
|
||||||
{
|
maxlen = len;
|
||||||
|
|
||||||
/*
|
result = palloc(maxlen + VARHDRSZ);
|
||||||
* truncate multi-byte string preserving multi-byte boundary
|
VARATT_SIZEP(result) = maxlen + VARHDRSZ;
|
||||||
*/
|
|
||||||
len = pg_mbcliplen(s, atttypmod - VARHDRSZ, atttypmod - VARHDRSZ);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
len = atttypmod - VARHDRSZ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
result = (BpChar *) palloc(atttypmod);
|
|
||||||
VARATT_SIZEP(result) = atttypmod;
|
|
||||||
r = VARDATA(result);
|
r = VARDATA(result);
|
||||||
for (i = 0; i < len; i++, r++, s++)
|
for (i = 0; i < len; i++, r++, s++)
|
||||||
{
|
{
|
||||||
@ -108,16 +113,16 @@ bpcharin(PG_FUNCTION_ARGS)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* blank pad the string if necessary */
|
/* blank pad the string if necessary */
|
||||||
#ifdef MULTIBYTE
|
for (; i < maxlen; i++)
|
||||||
for (; i < atttypmod - VARHDRSZ; i++)
|
|
||||||
#else
|
|
||||||
for (; i < len; i++)
|
|
||||||
#endif
|
|
||||||
*r++ = ' ';
|
*r++ = ' ';
|
||||||
|
|
||||||
PG_RETURN_BPCHAR_P(result);
|
PG_RETURN_BPCHAR_P(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert a CHARACTER value to a C string.
|
||||||
|
*/
|
||||||
Datum
|
Datum
|
||||||
bpcharout(PG_FUNCTION_ARGS)
|
bpcharout(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
@ -138,75 +143,70 @@ bpcharout(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_CSTRING(result);
|
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
|
Datum
|
||||||
bpchar(PG_FUNCTION_ARGS)
|
bpchar(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
BpChar *str = PG_GETARG_BPCHAR_P(0);
|
BpChar *source = PG_GETARG_BPCHAR_P(0);
|
||||||
int32 len = PG_GETARG_INT32(1);
|
int32 maxlen = PG_GETARG_INT32(1);
|
||||||
BpChar *result;
|
BpChar *result;
|
||||||
char *r,
|
int32 len;
|
||||||
*s;
|
char *r;
|
||||||
int rlen,
|
char *s;
|
||||||
slen;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
len = VARSIZE(source);
|
||||||
/* No work if typmod is invalid or supplied data matches it already */
|
/* No work if typmod is invalid or supplied data matches it already */
|
||||||
if (len < (int32) VARHDRSZ || len == VARSIZE(str))
|
if (len < (int32) VARHDRSZ || len == maxlen)
|
||||||
PG_RETURN_BPCHAR_P(str);
|
PG_RETURN_BPCHAR_P(source);
|
||||||
|
|
||||||
rlen = len - VARHDRSZ;
|
if (len > maxlen)
|
||||||
|
|
||||||
#ifdef STRINGDEBUG
|
|
||||||
printf("bpchar- convert string length %d (%d) ->%d (%d)\n",
|
|
||||||
VARSIZE(str) - VARHDRSZ, VARSIZE(str), rlen, len);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
result = (BpChar *) palloc(len);
|
|
||||||
VARATT_SIZEP(result) = len;
|
|
||||||
r = VARDATA(result);
|
|
||||||
|
|
||||||
#ifdef MULTIBYTE
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
#else
|
|
||||||
slen = VARSIZE(str) - VARHDRSZ;
|
|
||||||
#endif
|
|
||||||
s = VARDATA(str);
|
|
||||||
|
|
||||||
#ifdef STRINGDEBUG
|
|
||||||
printf("bpchar- string is '");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (i = 0; (i < rlen) && (i < slen); i++)
|
|
||||||
{
|
{
|
||||||
#ifdef STRINGDEBUG
|
#ifdef MULTIBYTE
|
||||||
printf("%c", *s);
|
size_t maxmblen;
|
||||||
|
|
||||||
|
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(%d)",
|
||||||
|
maxlen - VARHDRSZ);
|
||||||
|
|
||||||
|
len = maxmblen;
|
||||||
|
#else
|
||||||
|
for (i = maxlen - VARHDRSZ; i < len - VARHDRSZ; i++)
|
||||||
|
if (*(VARDATA(source) + i) != ' ')
|
||||||
|
elog(ERROR, "value too long for type character(%d)",
|
||||||
|
maxlen - VARHDRSZ);
|
||||||
|
|
||||||
|
/* clip extra spaces */
|
||||||
|
len = maxlen;
|
||||||
#endif
|
#endif
|
||||||
*r++ = *s++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef STRINGDEBUG
|
s = VARDATA(source);
|
||||||
printf("'\n");
|
|
||||||
#endif
|
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 */
|
/* blank pad the string if necessary */
|
||||||
for (; i < rlen; i++)
|
for (; i < maxlen - VARHDRSZ; i++)
|
||||||
*r++ = ' ';
|
*r++ = ' ';
|
||||||
|
|
||||||
PG_RETURN_BPCHAR_P(result);
|
PG_RETURN_BPCHAR_P(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* _bpchar()
|
/* _bpchar()
|
||||||
* Converts an array of char() elements to a specific internal length.
|
* Converts an array of char() elements to a specific internal length.
|
||||||
* len is the length specified in () plus VARHDRSZ bytes.
|
* len is the length specified in () plus VARHDRSZ bytes.
|
||||||
@ -330,9 +330,11 @@ name_bpchar(PG_FUNCTION_ARGS)
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* varcharin -
|
* Convert a C string to VARCHAR internal representation. atttypmod
|
||||||
* converts a string of varchar() type to the internal representation.
|
* is the declared length of the type plus VARHDRSZ.
|
||||||
* len is the length specified in () plus VARHDRSZ bytes.
|
*
|
||||||
|
* 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
|
Datum
|
||||||
varcharin(PG_FUNCTION_ARGS)
|
varcharin(PG_FUNCTION_ARGS)
|
||||||
@ -345,37 +347,52 @@ varcharin(PG_FUNCTION_ARGS)
|
|||||||
#endif
|
#endif
|
||||||
int32 atttypmod = PG_GETARG_INT32(2);
|
int32 atttypmod = PG_GETARG_INT32(2);
|
||||||
VarChar *result;
|
VarChar *result;
|
||||||
int len;
|
size_t len, maxlen;
|
||||||
|
|
||||||
len = strlen(s) + VARHDRSZ;
|
len = strlen(s);
|
||||||
if (atttypmod >= (int32) VARHDRSZ && len > atttypmod)
|
maxlen = atttypmod - VARHDRSZ;
|
||||||
|
|
||||||
|
if (atttypmod >= (int32) VARHDRSZ && len > maxlen)
|
||||||
|
{
|
||||||
#ifdef MULTIBYTE
|
#ifdef MULTIBYTE
|
||||||
len = pg_mbcliplen(s, len - VARHDRSZ, atttypmod - VARHDRSZ) + VARHDRSZ;
|
size_t mbmaxlen = pg_mbcliplen(s, len, maxlen);
|
||||||
#else
|
|
||||||
len = atttypmod; /* clip the string at max length */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
result = (VarChar *) palloc(len);
|
if (strspn(s + mbmaxlen, " ") == len - mbmaxlen)
|
||||||
VARATT_SIZEP(result) = len;
|
len = mbmaxlen;
|
||||||
memcpy(VARDATA(result), s, len - VARHDRSZ);
|
#else
|
||||||
|
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 = palloc(len + VARHDRSZ);
|
||||||
|
VARATT_SIZEP(result) = len + VARHDRSZ;
|
||||||
|
memcpy(VARDATA(result), s, len);
|
||||||
|
|
||||||
#ifdef CYR_RECODE
|
#ifdef CYR_RECODE
|
||||||
convertstr(VARDATA(result), len - VARHDRSZ, 0);
|
convertstr(VARDATA(result), len, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
PG_RETURN_VARCHAR_P(result);
|
PG_RETURN_VARCHAR_P(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert a VARCHAR value to a C string.
|
||||||
|
*/
|
||||||
Datum
|
Datum
|
||||||
varcharout(PG_FUNCTION_ARGS)
|
varcharout(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
VarChar *s = PG_GETARG_VARCHAR_P(0);
|
VarChar *s = PG_GETARG_VARCHAR_P(0);
|
||||||
char *result;
|
char *result;
|
||||||
int len;
|
int32 len;
|
||||||
|
|
||||||
/* copy and add null term */
|
/* copy and add null term */
|
||||||
len = VARSIZE(s) - VARHDRSZ;
|
len = VARSIZE(s) - VARHDRSZ;
|
||||||
result = (char *) palloc(len + 1);
|
result = palloc(len + 1);
|
||||||
memcpy(result, VARDATA(s), len);
|
memcpy(result, VARDATA(s), len);
|
||||||
result[len] = '\0';
|
result[len] = '\0';
|
||||||
|
|
||||||
@ -386,42 +403,60 @@ varcharout(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_CSTRING(result);
|
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
|
Datum
|
||||||
varchar(PG_FUNCTION_ARGS)
|
varchar(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
VarChar *s = PG_GETARG_VARCHAR_P(0);
|
VarChar *source = PG_GETARG_VARCHAR_P(0);
|
||||||
int32 slen = PG_GETARG_INT32(1);
|
int32 maxlen = PG_GETARG_INT32(1);
|
||||||
VarChar *result;
|
VarChar *result;
|
||||||
int len;
|
int32 len;
|
||||||
|
int i;
|
||||||
|
|
||||||
len = VARSIZE(s);
|
len = VARSIZE(source);
|
||||||
if (slen < (int32) VARHDRSZ || len <= slen)
|
if (maxlen < (int32) VARHDRSZ || len <= maxlen)
|
||||||
PG_RETURN_VARCHAR_P(s);
|
PG_RETURN_VARCHAR_P(source);
|
||||||
|
|
||||||
/* only reach here if we need to truncate string... */
|
/* only reach here if string is too long... */
|
||||||
|
|
||||||
#ifdef MULTIBYTE
|
#ifdef MULTIBYTE
|
||||||
|
{
|
||||||
|
size_t maxmblen;
|
||||||
|
|
||||||
/*
|
/* truncate multi-byte string preserving multi-byte boundary */
|
||||||
* truncate multi-byte string preserving multi-byte boundary
|
maxmblen = pg_mbcliplen(VARDATA(source), len - VARHDRSZ,
|
||||||
*/
|
maxlen - VARHDRSZ) + VARHDRSZ;
|
||||||
len = pg_mbcliplen(VARDATA(s), slen - VARHDRSZ, slen - VARHDRSZ);
|
|
||||||
slen = len + 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
|
#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
|
#endif
|
||||||
|
|
||||||
result = (VarChar *) palloc(slen);
|
result = palloc(len);
|
||||||
VARATT_SIZEP(result) = slen;
|
VARATT_SIZEP(result) = len;
|
||||||
memcpy(VARDATA(result), VARDATA(s), len);
|
memcpy(VARDATA(result), VARDATA(source), len - VARHDRSZ);
|
||||||
|
|
||||||
PG_RETURN_VARCHAR_P(result);
|
PG_RETURN_VARCHAR_P(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* _varchar()
|
/* _varchar()
|
||||||
* Converts an array of varchar() elements to the specified size.
|
* Converts an array of varchar() elements to the specified size.
|
||||||
* len is the length specified in () plus VARHDRSZ bytes.
|
* len is the length specified in () plus VARHDRSZ bytes.
|
||||||
@ -452,6 +487,12 @@ _varchar(PG_FUNCTION_ARGS)
|
|||||||
return array_map(&locfcinfo, VARCHAROID, VARCHAROID);
|
return array_map(&locfcinfo, VARCHAROID, VARCHAROID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* Exported functions
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
/* "True" length (not counting trailing blanks) of a BpChar */
|
/* "True" length (not counting trailing blanks) of a BpChar */
|
||||||
static int
|
static int
|
||||||
bcTruelen(BpChar *arg)
|
bcTruelen(BpChar *arg)
|
||||||
|
@ -1,6 +1,32 @@
|
|||||||
--
|
--
|
||||||
-- ARRAYS
|
-- 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;
|
SELECT * FROM arrtest;
|
||||||
a | b | c | d | e | f | g
|
a | b | c | d | e | f | g
|
||||||
-------------+-----------------+---------------+-------------------+---------------+-------------------+-----------------
|
-------------+-----------------+---------------+-------------------+---------------+-------------------+-----------------
|
||||||
@ -75,8 +101,8 @@ SELECT a,b,c FROM arrtest;
|
|||||||
a | b | c
|
a | b | c
|
||||||
---------------+-----------------------+-----------------------
|
---------------+-----------------------+-----------------------
|
||||||
{16,25,3,4,5} | {{{113,142},{1,147}}} | {}
|
{16,25,3,4,5} | {{{113,142},{1,147}}} | {}
|
||||||
{16,25,23} | {{3,4},{4,5}} | {"foobar","new_word"}
|
|
||||||
{} | {3,4} | {"foo","new_word"}
|
{} | {3,4} | {"foo","new_word"}
|
||||||
|
{16,25,23} | {{3,4},{4,5}} | {"foobar","new_word"}
|
||||||
(3 rows)
|
(3 rows)
|
||||||
|
|
||||||
SELECT a[1:3],
|
SELECT a[1:3],
|
||||||
@ -87,7 +113,7 @@ SELECT a[1:3],
|
|||||||
a | b | c | d
|
a | b | c | d
|
||||||
------------+-----------------------+-----------------------+------------
|
------------+-----------------------+-----------------------+------------
|
||||||
{16,25,3} | {{{113,142},{1,147}}} | |
|
{16,25,3} | {{{113,142},{1,147}}} | |
|
||||||
{16,25,23} | | {"foobar","new_word"} | {{"elt2"}}
|
|
||||||
| | {"foo","new_word"} |
|
| | {"foo","new_word"} |
|
||||||
|
{16,25,23} | | {"foobar","new_word"} | {{"elt2"}}
|
||||||
(3 rows)
|
(3 rows)
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
--
|
--
|
||||||
-- CHAR
|
-- CHAR
|
||||||
-- all inputs are SILENTLY truncated at 1 character
|
|
||||||
--
|
--
|
||||||
-- fixed-length by value
|
-- fixed-length by value
|
||||||
-- internally passed by value if <= 4 bytes in storage
|
-- 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 ('');
|
INSERT INTO CHAR_TBL (f1) VALUES ('');
|
||||||
-- try char's of greater than 1 length
|
-- try char's of greater than 1 length
|
||||||
INSERT INTO CHAR_TBL (f1) VALUES ('cd');
|
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.*;
|
SELECT '' AS seven, CHAR_TBL.*;
|
||||||
seven | f1
|
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 ('ab');
|
||||||
INSERT INTO CHAR_TBL (f1) VALUES ('abcd');
|
INSERT INTO CHAR_TBL (f1) VALUES ('abcd');
|
||||||
INSERT INTO CHAR_TBL (f1) VALUES ('abcde');
|
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.*;
|
SELECT '' AS four, CHAR_TBL.*;
|
||||||
four | f1
|
four | f1
|
||||||
------+------
|
------+------
|
||||||
|
@ -121,23 +121,6 @@ INSERT INTO f_star (class, f)
|
|||||||
VALUES ('f', '(11111111,33333333),(22222222,44444444)'::polygon);
|
VALUES ('f', '(11111111,33333333),(22222222,44444444)'::polygon);
|
||||||
INSERT INTO f_star (class) VALUES ('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
|
-- for internal portal (cursor) tests
|
||||||
--
|
--
|
||||||
CREATE TABLE iportaltest (
|
CREATE TABLE iportaltest (
|
||||||
|
@ -147,15 +147,6 @@ CREATE TABLE aggtest (
|
|||||||
a int2,
|
a int2,
|
||||||
b float4
|
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 (
|
CREATE TABLE hash_i4_heap (
|
||||||
seqno int4,
|
seqno int4,
|
||||||
random int4
|
random int4
|
||||||
|
@ -45,11 +45,13 @@ SELECT CAST(name 'namefield' AS text) AS "text(name)";
|
|||||||
namefield
|
namefield
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
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
|
||||||
char(text)
|
ERROR: value too long for type character(10)
|
||||||
------------
|
SELECT CAST(f1 AS char(20)) AS "char(text)" FROM TEXT_TBL;
|
||||||
|
char(text)
|
||||||
|
----------------------
|
||||||
doh!
|
doh!
|
||||||
hi de ho n
|
hi de ho neighbor
|
||||||
(2 rows)
|
(2 rows)
|
||||||
|
|
||||||
SELECT CAST(f1 AS char(10)) AS "char(varchar)" FROM VARCHAR_TBL;
|
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
|
text and unknown
|
||||||
(1 row)
|
(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
|
Concat text to char
|
||||||
---------------------
|
---------------------
|
||||||
text and chara
|
text and characters
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT text 'text' || varchar ' and varchar' AS "Concat text to varchar";
|
SELECT text 'text' || varchar ' and varchar' AS "Concat text to varchar";
|
||||||
|
@ -12,6 +12,8 @@ INSERT INTO VARCHAR_TBL (f1) VALUES ('3');
|
|||||||
INSERT INTO VARCHAR_TBL (f1) VALUES ('');
|
INSERT INTO VARCHAR_TBL (f1) VALUES ('');
|
||||||
-- try varchar's of greater than 1 length
|
-- try varchar's of greater than 1 length
|
||||||
INSERT INTO VARCHAR_TBL (f1) VALUES ('cd');
|
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.*;
|
SELECT '' AS seven, VARCHAR_TBL.*;
|
||||||
seven | f1
|
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 ('ab');
|
||||||
INSERT INTO VARCHAR_TBL (f1) VALUES ('abcd');
|
INSERT INTO VARCHAR_TBL (f1) VALUES ('abcd');
|
||||||
INSERT INTO VARCHAR_TBL (f1) VALUES ('abcde');
|
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.*;
|
SELECT '' AS four, VARCHAR_TBL.*;
|
||||||
four | f1
|
four | f1
|
||||||
------+------
|
------+------
|
||||||
|
@ -2,6 +2,40 @@
|
|||||||
-- ARRAYS
|
-- 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 * FROM arrtest;
|
||||||
|
|
||||||
SELECT arrtest.a[1],
|
SELECT arrtest.a[1],
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
--
|
--
|
||||||
-- CHAR
|
-- CHAR
|
||||||
-- all inputs are SILENTLY truncated at 1 character
|
|
||||||
--
|
--
|
||||||
|
|
||||||
-- fixed-length by value
|
-- fixed-length by value
|
||||||
@ -30,6 +29,7 @@ INSERT INTO CHAR_TBL (f1) VALUES ('');
|
|||||||
|
|
||||||
-- try char's of greater than 1 length
|
-- try char's of greater than 1 length
|
||||||
INSERT INTO CHAR_TBL (f1) VALUES ('cd');
|
INSERT INTO CHAR_TBL (f1) VALUES ('cd');
|
||||||
|
INSERT INTO CHAR_TBL (f1) VALUES ('c ');
|
||||||
|
|
||||||
|
|
||||||
SELECT '' AS seven, CHAR_TBL.*;
|
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 ('ab');
|
||||||
INSERT INTO CHAR_TBL (f1) VALUES ('abcd');
|
INSERT INTO CHAR_TBL (f1) VALUES ('abcd');
|
||||||
INSERT INTO CHAR_TBL (f1) VALUES ('abcde');
|
INSERT INTO CHAR_TBL (f1) VALUES ('abcde');
|
||||||
|
INSERT INTO CHAR_TBL (f1) VALUES ('abcd ');
|
||||||
|
|
||||||
SELECT '' AS four, CHAR_TBL.*;
|
SELECT '' AS four, CHAR_TBL.*;
|
||||||
|
|
||||||
|
@ -188,30 +188,6 @@ INSERT INTO f_star (class, f)
|
|||||||
|
|
||||||
INSERT INTO f_star (class) VALUES ('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
|
-- for internal portal (cursor) tests
|
||||||
|
@ -172,16 +172,6 @@ CREATE TABLE aggtest (
|
|||||||
b float4
|
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 (
|
CREATE TABLE hash_i4_heap (
|
||||||
seqno int4,
|
seqno int4,
|
||||||
random int4
|
random int4
|
||||||
|
@ -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(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;
|
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' || ' 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";
|
SELECT text 'text' || varchar ' and varchar' AS "Concat text to varchar";
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ INSERT INTO VARCHAR_TBL (f1) VALUES ('');
|
|||||||
|
|
||||||
-- try varchar's of greater than 1 length
|
-- try varchar's of greater than 1 length
|
||||||
INSERT INTO VARCHAR_TBL (f1) VALUES ('cd');
|
INSERT INTO VARCHAR_TBL (f1) VALUES ('cd');
|
||||||
|
INSERT INTO VARCHAR_TBL (f1) VALUES ('c ');
|
||||||
|
|
||||||
|
|
||||||
SELECT '' AS seven, VARCHAR_TBL.*;
|
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 ('ab');
|
||||||
INSERT INTO VARCHAR_TBL (f1) VALUES ('abcd');
|
INSERT INTO VARCHAR_TBL (f1) VALUES ('abcd');
|
||||||
INSERT INTO VARCHAR_TBL (f1) VALUES ('abcde');
|
INSERT INTO VARCHAR_TBL (f1) VALUES ('abcde');
|
||||||
|
INSERT INTO VARCHAR_TBL (f1) VALUES ('abcd ');
|
||||||
|
|
||||||
SELECT '' AS four, VARCHAR_TBL.*;
|
SELECT '' AS four, VARCHAR_TBL.*;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user