public inbox for [email protected]
help / color / mirror / Atom feedFrom: Boguk, Maksym <[email protected]>
To: [email protected]
Subject: UTF8 national character data type support WIP patch and list of open issues.
Date: Tue, 3 Sep 2013 12:28:45 +1000
Message-ID: <[email protected]> (raw)
List-Unsubscribe: <mailto:[email protected]?body=unsub%20pgsql-hackers>
Hi,
As part of my job I started developing in-core support for the UTF8
National Character types (national character/national character
variable).
I attached current WIP patch (against HEAD) to community review.
Target usage: ability to store UTF8 national characters in some
selected fields inside a single-byte encoded database.
For sample if I have a ru-RU.koi8r encoded database with mostly Russian
text inside, it would be nice to be able store an Japanese text in one
field without converting the whole database to UTF8 (convert such
database to UTF8 easily could almost double the database size even if
only one field in whole database will use any symbols outside of
ru-RU.koi8r encoding).
What has been done:
1)Addition of new string data types NATIONAL CHARACTER and NATIONAL
CHARACTER VARIABLE.
These types differ from the char/varchar data types in one important
respect: NATIONAL string types are always have UTF8 encoding even
(independent from used database encoding).
Of course that lead to encoding conversion overhead when comparing
NATIONAL string types with common string types (that is expected and
unavoidable).
2)Some ECPG support for these types
3)Some documentation patch (not finished)
What need to be done:
1)Full set of string functions and operators for NATIONAL types (we
could not use generic text functions because they assume that the stings
will have database encoding).
Now only basic set implemented.
2)Need implement some way to define default collation for a NATIONAL
types.
3)Need implement some way to input UTF8 characters into NATIONAL types
via SQL (there are serious open problem... it will be defined later in
the text).
Most serious open problem that the patch in current state doesn't allow
input/output UTF8 symbols which could not be represented in used
database encoding into NATIONAL fields.
It happen because encoding conversion from the client_encoding to the
database encoding happens before syntax analyze/parse stage and throw an
error for symbols which could not be represented.
I don't see any good solution to this problem except made whole codebase
use an UTF8 encoding for the all internal operations with huge
performance hit.
May be someone have good idea how to deal with this issue.
That is really WIP patch (with lots things on todo list/required
polish).
Kindly please tell me what you think about this idea/patch in general.
PS: It is my first patch to PostgreSQL so there are a lot of space to
improvement/style for sure.
Kind Regards,
Maksym
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Attachments:
[application/octet-stream] pgHEAD_UTF8NCHAR.patch (210.6K, ../[email protected]/2-pgHEAD_UTF8NCHAR.patch)
download | inline diff:
diff -U 5 -N -r -w ../orig.HEAD/doc/src/sgml/datatype.sgml ./doc/src/sgml/datatype.sgml
--- ../orig.HEAD/doc/src/sgml/datatype.sgml 2013-08-19 20:22:06.000000000 -0400
+++ ./doc/src/sgml/datatype.sgml 2013-08-19 20:54:00.000000000 -0400
@@ -159,10 +159,22 @@
<entry></entry>
<entry>currency amount</entry>
</row>
<row>
+ <entry><type>national character varying [ (<replaceable>n</replaceable>) ]</type></entry>
+ <entry><type>nvarchar [ (<replaceable>n</replaceable>) ]</type></entry>
+ <entry>variable-length national character string</entry>
+ </row>
+
+ <row>
+ <entry><type>national character [ (<replaceable>n</replaceable>) ]</type></entry>
+ <entry><type>nchar [ (<replaceable>n</replaceable>) ]</type></entry>
+ <entry>fixed-length national character string</entry>
+ </row>
+
+ <row>
<entry><type>numeric [ (<replaceable>p</replaceable>,
<replaceable>s</replaceable>) ]</type></entry>
<entry><type>decimal [ (<replaceable>p</replaceable>,
<replaceable>s</replaceable>) ]</type></entry>
<entry>exact numeric of selectable precision</entry>
@@ -4661,6 +4673,195 @@
<type>internal</> argument.
</para>
</sect1>
+ <sect1 id="datatype-national-character">
+ <title>National Character Types</title>
+
+ <indexterm zone="datatype-national-character">
+ <primary>national character string</primary>
+ <secondary>data types</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>string</primary>
+ <see>national character string</see>
+ </indexterm>
+
+ <indexterm zone="datatype-national-character">
+ <primary>national character</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-national-character">
+ <primary>national character varying</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-national-character">
+ <primary>nchar</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-national-character">
+ <primary>nvarchar</primary>
+ </indexterm>
+
+ <table id="datatype-national-character-table">
+ <title>National Character Types</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><type>national character varying(<replaceable>n</>)</type>, <type>nvarchar(<replaceable>n</>)</type></entry>
+ <entry>variable-length with limit</entry>
+ </row>
+ <row>
+ <entry><type>national character(<replaceable>n</>)</type>, <type>nchar(<replaceable>n</>)</type></entry>
+ <entry>fixed-length, blank padded</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ <xref linkend="datatype-national-character-table"> shows the
+ general-purpose national character types available in
+ <productname>PostgreSQL</productname>.
+ </para>
+
+ <para>
+ <acronym>SQL</acronym> defines two primary national character types:
+ <type>national character varying(<replaceable>n</>)</type> and
+ <type>national character(<replaceable>n</>)</type>, where <replaceable>n</>
+ is a positive integer. Both of these types can store strings up to
+ <replaceable>n</> national characters (not bytes) 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.
+ If the string to be stored is shorter than the declared
+ length, values of type <type>national character</type> will be space-padded;
+ values of type <type>national character varying</type> will simply store the
+ shorter
+ string.
+ </para>
+
+ <para>
+ If one explicitly casts a value to <type>national character
+ varying(<replaceable>n</>)</type> or
+ <type>national character(<replaceable>n</>)</type>, then an over-length
+ value will be truncated to <replaceable>n</> characters without
+ raising an error. (This too is required by the
+ <acronym>SQL</acronym> standard.)
+ </para>
+
+ <para>
+ The notations <type>nvarchar(<replaceable>n</>)</type> and
+ <type>nchar(<replaceable>n</>)</type> are aliases for <type>national character
+ varying(<replaceable>n</>)</type> and
+ <type>national character(<replaceable>n</>)</type>, respectively.
+ <type>national character</type> without length specifier is equivalent to
+ <type>national character(1)</type>. If <type>national character varying</type> is used
+ without length specifier, the type accepts strings of any size. The
+ latter is a <productname>PostgreSQL</> extension.
+ </para>
+
+ <para>
+ Values of type <type>national character</type> are physically padded
+ with spaces to the specified width <replaceable>n</>, and are
+ stored and displayed that way. However, the padding spaces are
+ treated as semantically insignificant. Trailing spaces are
+ disregarded when comparing two values of type <type>national character</type>,
+ and they will be removed when converting a <type>national character</type> value
+ to one of the other string types. Note that trailing spaces
+ <emphasis>are</> semantically significant in
+ <type>national character varying</type> values, and
+ when using pattern matching, e.g. <literal>LIKE</>,
+ regular expressions.
+ </para>
+
+ <para>
+ The storage requirement for a short string (up to 126 bytes) is 1 byte
+ plus the actual string, which includes the space padding in the case of
+ <type>national character</type>. Longer strings have 4 bytes of overhead instead
+ of 1. Long strings are compressed by the system automatically, so
+ the physical requirement on disk might be less. Very long values are also
+ stored in background tables so that they do not interfere with rapid
+ access to shorter column values. In any case, the longest
+ possible character string that can be stored is about 1 GB. (The
+ maximum value that will be allowed for <replaceable>n</> in the data
+ type declaration is less than that. It wouldn't be useful to
+ change this because with multibyte character encodings the number of
+ characters and bytes can be quite different. If you desire to
+ store long strings with no specific upper limit, use
+ <type>text</type> or <type>national character varying</type> without a length
+ specifier, rather than making up an arbitrary length limit.)
+ </para>
+
+ <tip>
+ <para>
+ There is no performance difference among these two types,
+ apart from increased storage space when using the blank-padded
+ type, and a few extra CPU cycles to check the length when storing into
+ a length-constrained column. While
+ <type>national character(<replaceable>n</>)</type> has performance
+ advantages in some other database systems, there is no such advantage in
+ <productname>PostgreSQL</productname>; in fact
+ <type>national character(<replaceable>n</>)</type> is usually the slowest of
+ the three because of its additional storage costs. In most situations
+ <type>text</type> or <type>national character varying</type> should be used
+ instead.
+ </para>
+ </tip>
+
+ <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. The
+ database character set determines the character set used to store
+ textual values. The <type>national character varying</type> or <type>national character</type> types are supported only when the database encoding is UTF-8; for more information on character set support,
+ refer to <xref linkend="multibyte">.
+ </para>
+
+ <example>
+ <title>Using the National Character Types</title>
+
+<programlisting>
+CREATE TABLE test1 (a national character(4));
+INSERT INTO test1 VALUES (N'ok');
+SELECT a, char_length(a) FROM test1; -- <co id="co.datatype-nchar">
+<computeroutput>
+ a | char_length
+------+-------------
+ ok | 2
+</computeroutput>
+
+CREATE TABLE test2 (b nvarchar(5));
+INSERT INTO test2 VALUES (N'ok');
+INSERT INTO test2 VALUES (N'good ');
+INSERT INTO test2 VALUES (N'too long');
+<computeroutput>ERROR: value too long for type national character varying(5)</computeroutput>
+INSERT INTO test2 VALUES ('too long'::nvarchar(5)); -- explicit truncation
+SELECT b, char_length(b) FROM test2;
+<computeroutput>
+ b | char_length
+-------+-------------
+ ok | 2
+ good | 5
+ too l | 5
+</computeroutput>
+</programlisting>
+ <calloutlist>
+ <callout arearefs="co.datatype-nchar">
+ <para>
+ The <function>char_length</function> function is discussed in
+ <xref linkend="functions-string">.
+ </para>
+ </callout>
+ </calloutlist>
+ </example>
+
+ </sect1>
</chapter>
diff -U 5 -N -r -w ../orig.HEAD/doc/src/sgml/ecpg.sgml ./doc/src/sgml/ecpg.sgml
--- ../orig.HEAD/doc/src/sgml/ecpg.sgml 2013-08-19 20:22:06.000000000 -0400
+++ ./doc/src/sgml/ecpg.sgml 2013-08-19 20:54:00.000000000 -0400
@@ -888,10 +888,20 @@
<row>
<entry><type>boolean</type></entry>
<entry><type>bool</type><footnote><para>declared in <filename>ecpglib.h</filename> if not native</para></footnote></entry>
</row>
+
+ <row>
+ <entry><type>national character(<replaceable>n</>)</type>, <type>nvarchar(<replaceable>n</>)</type></entry>
+ <entry><type>NCHAR[<replaceable>n</>+1]</type>, <type>NVARCHAR[<replaceable>n</>+1]</type></entry>
+ </row>
+
+ <row>
+ <entry><type>national character(<replaceable>n</>)</type>, <type>nvarchar(<replaceable>n</>)</type>, <type>character(<replaceable>n</>)</type>, <type>varchar(<replaceable>n</>)</type>, <type>text</type></entry>
+ <entry><type>UVARCHAR[<replaceable>2*n</>]</type></entry>
+ </row>
</tbody>
</tgroup>
</table>
<sect3 id="ecpg-char">
@@ -966,10 +976,197 @@
also hold values of other SQL types, which will be stored in
their string forms.
</para>
</sect3>
+ <sect3 id="ecpg-nchar">
+ <title>Handling National Character Strings</title>
+
+ <para>
+ To handle SQL national character string data types, such
+ as <type>nvarchar</type> and <type>nchar</type>, there are two
+ possible ways to declare the host variables.
+ </para>
+
+ <para>
+ One way is using <type>NCHAR[]</type>, an array
+ of <type>NCHAR</type>, internally which is mapped to an array of <type>char</type> which is the most common way to handle
+ character data in C.
+<programlisting>
+EXEC SQL BEGIN DECLARE SECTION;
+ NCHAR str[50];
+EXEC SQL END DECLARE SECTION;
+</programlisting>
+ Note that you have to take care of the length yourself. If you
+ use this host variable as the target variable of a query which
+ returns a string with more than 49 characters, a buffer overflow
+ occurs.
+ </para>
+
+ <para>
+ The other way is using the <type>NVARCHAR</type> type, which is a
+ special type provided by ECPG. The definition on an array of
+ type <type>NVARCHAR</type> is converted into a
+ named <type>struct</> for every variable. A declaration like:
+<programlisting>
+NVARCHAR var[180];
+</programlisting>
+ is converted into:
+<programlisting>
+struct varchar_var { int len; char arr[180]; } var;
+</programlisting>
+ The member <structfield>arr</structfield> hosts the string
+ including a terminating zero byte. Thus, to store a string in
+ a <type>NVARCHAR</type> host variable, the host variable has to be
+ declared with the length including the zero byte terminator. The
+ member <structfield>len</structfield> holds the length of the
+ string stored in the <structfield>arr</structfield> without the
+ terminating zero byte. When a host variable is used as input for
+ a query, if <literal>strlen(arr)</literal>
+ and <structfield>len</structfield> are different, the shorter one
+ is used.
+ </para>
+
+ <para>
+ Two or more <type>NVARCHAR</type> host variables cannot be defined
+ in single line statement. The following code will confuse
+ the <command>ecpg</command> preprocessor:
+<programlisting>
+NVARCHAR v1[128], v2[128]; /* WRONG */
+</programlisting>
+ Two variables should be defined in separate statements like this:
+<programlisting>
+NVARCHAR v1[128];
+NVARCHAR v2[128];
+</programlisting>
+ </para>
+
+ <para>
+ <type>NVARCHAR</type> and <type>NCHAR</type> can be written in upper or lower case, but
+ not in mixed case.
+ </para>
+
+ <para>
+ <type>NCHAR</type> and <type>NVARCHAR</type> host variables can
+ also hold values of other SQL types, which will be stored in
+ their string forms. NVARCHAR type is pretty similar to VARCHAR type
+ and added mainly for SQL standard compatibility.
+ </para>
+ </sect3>
+
+ <sect3 id="ecpg-uvarchar">
+ <title>Handling Strings with UVARCHAR type</title>
+
+ <para>
+ ECPG contains a special type <type>UVARCHAR</type> for defining host variables to store
+ character string and national character string values from respective SQL types.
+
+ This type is preprocessed into a structure with length and buffer fields.
+
+ <programlisting>
+ struct uvarchar_var { int len; char arr[180]; } uvc;
+ </programlisting>
+
+ The data stored by <type>UVARCHAR</type> type structure is always in UTF-16 encoding. There is an implicit conversion from UTF-8 to UTF-16 when UVARCHAR type is created.
+ </para>
+
+ <para>
+ The sample usage of UVARCHAR to handle string data
+
+ <programlisting>
+ #include <stdio.h>
+
+ EXEC SQL INCLUDE sqlca;
+ EXEC SQL WHENEVER SQLERROR SQLPRINT;
+
+ int main( int argc, char * argv[] )
+ {
+ EXEC SQL BEGIN DECLARE SECTION;
+ UVARCHAR uv[100];
+ EXEC SQL END DECLARE SECTION;
+
+ EXEC SQL CONNECT TO postgres;
+ EXEC SQL CREATE TABLE test (a nvarchar);
+ EXEC SQL INSERT INTO test (a) values ('ok'),
+ ...
+ EXEC SQL SELECT a INTO :uv FROM test;
+ printf("value=%s length=%d\n", uv.arr, uv.len);
+ ...
+ ...
+ }
+ </programlisting>
+
+ The member <structfield>arr</structfield> hosts the string
+ without a terminating zero byte. As the default encoding for
+ <type>UVARCHAR</type> is UTF-16, to store a string in a
+ <type>UVARCHAR</type> host variable, the host variable has to be
+ declared with the minimum length of 2*n. The member <structfield>len</structfield>
+ holds the length of the string stored in the <structfield>arr</structfield>.
+ When a host variable is used as input for a query,
+ if <literal>strlen(arr)</literal> and <structfield>len</structfield>
+ are different, the shorter one is used.
+
+ </para>
+
+ </sect3>
+
+ <sect3 id="ecpg-datatype-comparison">
+ <title>Comparison between VARCHAR, NVARCHAR and UVARCHAR Types</title>
+ <para>
+ The host data types used for handling string values, differ in few aspects like memory usage, encoding, performance etc.
+ <xref linkend="ecpg-datatype-comaprison-table"> shows the comparison of
+ host data types.
+
+ </para>
+ <table id="ecpg-datatype-comaprison-table">
+ <title>Comparison between VARCHAR, NVARCHAR and UVARCHAR Types</title>
+
+ <tgroup cols="4">
+ <thead>
+ <row>
+ <entry></entry>
+ <entry>VARCHAR</entry>
+ <entry>NVARCHAR</entry>
+ <entry>UVARCHAR</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><type>Maximum Size for 'n' characters</type></entry>
+ <entry><type>4*n + 1</type></entry>
+ <entry><type>4*n + 1</type></entry>
+ <entry><type>4*n</type></entry>
+ </row>
+ <row>
+ <entry><type>Minimum Size for 'n' characters</type></entry>
+ <entry><type>n + 1</type></entry>
+ <entry><type>n + 1</type></entry>
+ <entry><type>2*n</type></entry>
+ </row>
+ <row>
+ <entry><type>Encoding Used</type></entry>
+ <entry><type>client encoding</type></entry>
+ <entry><type>client encoding</type></entry>
+ <entry><type>UTF-16</type></entry>
+ </row>
+ <row>
+ <entry><type>Zero Terminated</type></entry>
+ <entry><type>Yes</type></entry>
+ <entry><type>Yes</type></entry>
+ <entry><type>No</type></entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Please note that the data conversion from UTF-8 encoding to UTF-16 encoding will incur a negligible performance overhead in case of UVARCHAR Type.
+ </para>
+ </sect3>
+
<sect3 id="ecpg-special-types">
<title>Accessing Special Data Types</title>
<para>
ECPG contains some special types that help you to interact easily
diff -U 5 -N -r -w ../orig.HEAD/doc/src/sgml/syntax.sgml ./doc/src/sgml/syntax.sgml
--- ../orig.HEAD/doc/src/sgml/syntax.sgml 2013-08-19 20:22:06.000000000 -0400
+++ ./doc/src/sgml/syntax.sgml 2013-08-19 20:54:00.000000000 -0400
@@ -551,10 +551,37 @@
To include the escape character in the string literally, write it
twice.
</para>
</sect3>
+ <sect3 id="sql-syntax-strings-N">
+ <title>String Constants with prefix N</title>
+
+ <indexterm zone="sql-syntax-strings-N">
+ <primary>Prefix N</primary>
+ <secondary>in string constants</secondary>
+ </indexterm>
+
+ <para>
+ The standard syntax for specifying national character type string constants
+ is to add a prefix 'N' to the string constant. This string constant syntax
+ is supported only when the database encoding is UTF-8.
+
+ The following trivial example shows how to pass a national character type
+ string constant with prefix 'N'
+
+ <programlisting>
+ INSERT INTO test VALUES (N'ok');
+ </programlisting>
+
+ </para>
+ <para>
+ Please note that this syntax is optional and national character type string constants can also be specified bounded by single quotes (<literal>'</literal>), for example
+ <literal>'ok'</literal>.
+ </para>
+ </sect3>
+
<sect3 id="sql-syntax-dollar-quoting">
<title>Dollar-quoted String Constants</title>
<indexterm>
<primary>dollar quoting</primary>
diff -U 5 -N -r -w ../orig.HEAD/src/backend/catalog/information_schema.sql ./src/backend/catalog/information_schema.sql
--- ../orig.HEAD/src/backend/catalog/information_schema.sql 2013-08-19 20:22:07.000000000 -0400
+++ ./src/backend/catalog/information_schema.sql 2013-08-19 20:54:00.000000000 -0400
@@ -77,11 +77,11 @@
RETURNS NULL ON NULL INPUT
AS
$$SELECT
CASE WHEN $2 = -1 /* default typmod */
THEN null
- WHEN $1 IN (1042, 1043) /* char, varchar */
+ WHEN $1 IN (1042, 1043, 5001, 6001) /* char, varchar, nchar, nvarchar */
THEN $2 - 4
WHEN $1 IN (1560, 1562) /* bit, varbit */
THEN $2
ELSE null
END$$;
@@ -90,11 +90,11 @@
LANGUAGE sql
IMMUTABLE
RETURNS NULL ON NULL INPUT
AS
$$SELECT
- CASE WHEN $1 IN (25, 1042, 1043) /* text, char, varchar */
+ CASE WHEN $1 IN (25, 1042, 1043, 5001, 6001) /* text, char, varchar, nchar, nvarchar */
THEN CASE WHEN $2 = -1 /* default typmod */
THEN CAST(2^30 AS integer)
ELSE information_schema._pg_char_max_length($1, $2) *
pg_catalog.pg_encoding_max_length((SELECT encoding FROM pg_catalog.pg_database WHERE datname = pg_catalog.current_database()))
END
diff -U 5 -N -r -w ../orig.HEAD/src/backend/parser/gram.y ./src/backend/parser/gram.y
--- ../orig.HEAD/src/backend/parser/gram.y 2013-08-19 20:22:08.000000000 -0400
+++ ./src/backend/parser/gram.y 2013-08-19 21:42:23.000000000 -0400
@@ -439,13 +439,15 @@
%type <typnam> Typename SimpleTypename ConstTypename
GenericType Numeric opt_float
Character ConstCharacter
CharacterWithLength CharacterWithoutLength
+ NCharacterWithLength NCharacterWithoutLength
ConstDatetime ConstInterval
Bit ConstBit BitWithLength BitWithoutLength
%type <str> character
+%type <str> ncharacter
%type <str> extract_arg
%type <str> opt_charset
%type <boolean> opt_varying opt_timezone opt_no_inherit
%type <ival> Iconst SignedIconst
@@ -562,10 +564,11 @@
MAPPING MATCH MATERIALIZED MAXVALUE MINUTE_P MINVALUE MODE MONTH_P MOVE
NAME_P NAMES NATIONAL NATURAL NCHAR NEXT NO NONE
NOT NOTHING NOTIFY NOTNULL NOWAIT NULL_P NULLIF
NULLS_P NUMERIC
+ NVARCHAR
OBJECT_P OF OFF OFFSET OIDS ON ONLY OPERATOR OPTION OPTIONS OR
ORDER ORDINALITY OUT_P OUTER_P OVER OVERLAPS OVERLAY OWNED OWNER
PARSER PARTIAL PARTITION PASSING PASSWORD PLACING PLANS POSITION
@@ -10277,13 +10280,22 @@
}
| CharacterWithoutLength
{
$$ = $1;
}
+ | NCharacterWithLength
+ {
+ $$ = $1;
+ }
+ | NCharacterWithoutLength
+ {
+ $$ = $1;
+ }
;
-ConstCharacter: CharacterWithLength
+ConstCharacter:
+ CharacterWithLength
{
$$ = $1;
}
| CharacterWithoutLength
{
@@ -10294,13 +10306,79 @@
* was not specified.
*/
$$ = $1;
$$->typmods = NIL;
}
+ | NCharacterWithLength
+ {
+ $$ = $1;
+ }
+ | NCharacterWithoutLength
+ {
+ /* Length was not specified so allow to be unrestricted.
+ * This handles problems with fixed-length (bpchar) strings
+ * which in column definitions must default to a length
+ * of one, but should not be constrained if the length
+ * was not specified.
+ */
+ $$ = $1;
+ $$->typmods = NIL;
+ }
;
-CharacterWithLength: character '(' Iconst ')' opt_charset
+NCharacterWithLength:
+ NATIONAL ncharacter '(' Iconst ')' opt_charset
+ {
+ if (($6 != NULL) && (strcmp($6, "sql_text") != 0))
+ {
+ char *type;
+
+ type = palloc(strlen($2) + 1 + strlen($2) + 1);
+ strcpy(type, $2);
+ strcat(type, "_");
+ strcat(type, $6);
+ $1 = type;
+ }
+ $$ = SystemTypeName($2);
+ $$->typmods = list_make1(makeIntConst($4, @4));
+ $$->location = @1;
+ }
+ ;
+
+NCharacterWithoutLength:
+ NATIONAL ncharacter opt_charset
+ {
+ if (($3 != NULL) && (strcmp($3, "sql_text") != 0))
+ {
+ char *type;
+
+ type = palloc(strlen($2) + 1 + strlen($3) + 1);
+ strcpy(type, $2);
+ strcat(type, "_");
+ strcat(type, $3);
+ $2 = type;
+ }
+ $$ = SystemTypeName($2);
+ /* nchar defaults to char(1), varchar to no limit */
+ if (strcmp($2, "nbpchar") == 0)
+ $$->typmods = list_make1(makeIntConst(1, -1));
+
+ $$->location = @1;
+ }
+ ;
+
+ncharacter:
+ CHARACTER opt_varying
+ { $$ = $2 ? "nvarchar": "nbpchar"; }
+ | CHAR_P opt_varying
+ { $$ = $2 ? "nvarchar": "nbpchar"; }
+ | VARCHAR
+ { $$ = "nvarchar"; }
+ ;
+
+CharacterWithLength:
+ character '(' Iconst ')' opt_charset
{
if (($5 != NULL) && (strcmp($5, "sql_text") != 0))
{
char *type;
@@ -10315,11 +10393,12 @@
$$->typmods = list_make1(makeIntConst($3, @3));
$$->location = @1;
}
;
-CharacterWithoutLength: character opt_charset
+CharacterWithoutLength:
+ character opt_charset
{
if (($2 != NULL) && (strcmp($2, "sql_text") != 0))
{
char *type;
@@ -10330,30 +10409,29 @@
$1 = type;
}
$$ = SystemTypeName($1);
- /* char defaults to char(1), varchar to no limit */
- if (strcmp($1, "bpchar") == 0)
+ /* [n]char defaults to [national ]char(1), varchar to no limit */
+ if ((strcmp($1, "bpchar") == 0) || (strcmp($1, "nbpchar") == 0))
$$->typmods = list_make1(makeIntConst(1, -1));
$$->location = @1;
}
;
-character: CHARACTER opt_varying
+character:
+ CHARACTER opt_varying
{ $$ = $2 ? "varchar": "bpchar"; }
| CHAR_P opt_varying
{ $$ = $2 ? "varchar": "bpchar"; }
| VARCHAR
{ $$ = "varchar"; }
- | NATIONAL CHARACTER opt_varying
- { $$ = $3 ? "varchar": "bpchar"; }
- | NATIONAL CHAR_P opt_varying
- { $$ = $3 ? "varchar": "bpchar"; }
| NCHAR opt_varying
- { $$ = $2 ? "varchar": "bpchar"; }
+ { $$ = $2 ? "nvarchar": "nbpchar"; }
+ | NVARCHAR
+ { $$ = "nvarchar"; }
;
opt_varying:
VARYING { $$ = TRUE; }
| /*EMPTY*/ { $$ = FALSE; }
@@ -12739,10 +12817,11 @@
| NATIONAL
| NCHAR
| NONE
| NULLIF
| NUMERIC
+ | NVARCHAR
| OUT_P
| OVERLAY
| POSITION
| PRECISION
| REAL
diff -U 5 -N -r -w ../orig.HEAD/src/backend/parser/scan.l ./src/backend/parser/scan.l
--- ../orig.HEAD/src/backend/parser/scan.l 2013-08-19 20:22:08.000000000 -0400
+++ ./src/backend/parser/scan.l 2013-08-19 22:27:02.000000000 -0400
@@ -480,11 +480,11 @@
const ScanKeyword *keyword;
SET_YYLLOC();
yyless(1); /* eat only 'n' this time */
- keyword = ScanKeywordLookup("nchar",
+ keyword = ScanKeywordLookup("nvarchar",
yyextra->keywords,
yyextra->num_keywords);
if (keyword != NULL)
{
yylval->keyword = keyword->name;
diff -U 5 -N -r -w ../orig.HEAD/src/backend/utils/adt/format_type.c ./src/backend/utils/adt/format_type.c
--- ../orig.HEAD/src/backend/utils/adt/format_type.c 2013-08-19 20:22:09.000000000 -0400
+++ ./src/backend/utils/adt/format_type.c 2013-08-19 20:54:00.000000000 -0400
@@ -216,10 +216,25 @@
}
else
buf = pstrdup("character");
break;
+ case NBPCHAROID:
+ if (with_typemod)
+ buf = printTypmod("national character", typemod, typeform->typmodout);
+ else if (typemod_given)
+ {
+ /*
+ * bpchar with typmod -1 is not the same as CHARACTER, which
+ * means CHARACTER(1) per SQL spec. Report it as bpchar so
+ * that parser will not assign a bogus typmod.
+ */
+ }
+ else
+ buf = pstrdup("national character");
+ break;
+
case FLOAT4OID:
buf = pstrdup("real");
break;
case FLOAT8OID:
@@ -291,10 +306,17 @@
if (with_typemod)
buf = printTypmod("character varying", typemod, typeform->typmodout);
else
buf = pstrdup("character varying");
break;
+
+ case NVARCHAROID:
+ if (with_typemod)
+ buf = printTypmod("national character varying", typemod, typeform->typmodout);
+ else
+ buf = pstrdup("national character varying");
+ break;
}
if (buf == NULL)
{
/*
@@ -381,11 +403,13 @@
return -1;
switch (type_oid)
{
case BPCHAROID:
+ case NBPCHAROID:
case VARCHAROID:
+ case NVARCHAROID:
/* typemod includes varlena header */
/* typemod is in characters not bytes */
return (typemod - VARHDRSZ) *
pg_encoding_max_length(GetDatabaseEncoding())
diff -U 5 -N -r -w ../orig.HEAD/src/backend/utils/adt/Makefile ./src/backend/utils/adt/Makefile
--- ../orig.HEAD/src/backend/utils/adt/Makefile 2013-08-19 20:22:09.000000000 -0400
+++ ./src/backend/utils/adt/Makefile 2013-08-20 04:53:45.000000000 -0400
@@ -18,11 +18,11 @@
OBJS = acl.o arrayfuncs.o array_selfuncs.o array_typanalyze.o \
array_userfuncs.o arrayutils.o bool.o \
cash.o char.o date.o datetime.o datum.o domains.o \
enum.o float.o format_type.o \
geo_ops.o geo_selfuncs.o int.o int8.o json.o jsonfuncs.o like.o \
- lockfuncs.o misc.o nabstime.o name.o numeric.o numutils.o \
+ lockfuncs.o misc.o nabstime.o name.o numeric.o numutils.o nvarchar.o \
oid.o oracle_compat.o pseudotypes.o rangetypes.o rangetypes_gist.o \
rowtypes.o regexp.o regproc.o ruleutils.o selfuncs.o \
tid.o timestamp.o varbit.o varchar.o varlena.o version.o xid.o \
network.o mac.o inet_cidr_ntop.o inet_net_pton.o \
ri_triggers.o pg_lzcompress.o pg_locale.o formatting.o \
diff -U 5 -N -r -w ../orig.HEAD/src/backend/utils/adt/nvarchar.c ./src/backend/utils/adt/nvarchar.c
--- ../orig.HEAD/src/backend/utils/adt/nvarchar.c 1969-12-31 19:00:00.000000000 -0500
+++ ./src/backend/utils/adt/nvarchar.c 2013-08-20 04:54:06.000000000 -0400
@@ -0,0 +1,421 @@
+/*-------------------------------------------------------------------------
+ *
+ * nvarchar.c
+ * Functions for the built-in types nchar(n) and nvarchar(n).
+ *
+ * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ * src/backend/utils/adt/nvarchar.c
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres.h"
+
+
+#include "access/hash.h"
+#include "access/tuptoaster.h"
+#include "libpq/pqformat.h"
+#include "nodes/nodeFuncs.h"
+#include "utils/array.h"
+#include "utils/builtins.h"
+#include "mb/pg_wchar.h"
+#include "utils/formatting.h"
+#include "catalog/namespace.h"
+#include "catalog/pg_collation.h"
+
+/*
+ * ====================
+ * FORWARD DECLARATIONS
+ * ====================
+ */
+static int32 ntextcmp(text *left, text *right, Oid collid);
+
+// being really dumb for ntext collation initially
+static const char *ntext_collation = "C.UTF-8";
+
+/*
+ * ===================
+ * TYPE CAST FUNCTIONS
+ * ===================
+ */
+
+/*
+ * convert text to ntext (the database encoding to UTF8)
+ */
+Datum
+text2nvarchar(PG_FUNCTION_ARGS)
+{
+ text *in_val = PG_GETARG_TEXT_PP(0);
+ char *in_string;
+ text *out_val;
+
+ in_string = text_to_cstring(in_val);
+ out_val = cstring_to_text(pg_server_to_any(in_string, strlen(in_string), PG_UTF8));
+
+ PG_RETURN_TEXT_P(out_val);
+}
+
+/*
+ * convert ntext to text (UTF8 to the database encoding)
+ */
+Datum
+nvarchar2text(PG_FUNCTION_ARGS)
+{
+ text *in_val = PG_GETARG_TEXT_PP(0);
+ char *in_string;
+ text *out_val;
+
+ in_string = text_to_cstring(in_val);
+ out_val = cstring_to_text(pg_any_to_server(in_string, strlen(in_string), PG_UTF8));
+
+ PG_RETURN_TEXT_P(out_val);
+}
+
+/*
+ * convert rtrimmed text to ntext (the database encoding to UTF8)
+ * used for conversion from char type to nvarchar type
+ */
+Datum
+rtrimtext2nvarchar(PG_FUNCTION_ARGS)
+{
+ text *in_val = PG_GETARG_TEXT_PP(0);
+ char *in_string;
+ text *out_val;
+ text *trimmed_val;
+
+ trimmed_val = dotrim(VARDATA_ANY(in_val), VARSIZE_ANY_EXHDR(in_val),
+ " ", 1,
+ false, true);
+ in_string = text_to_cstring(trimmed_val);
+ out_val = cstring_to_text(pg_server_to_any(in_string, strlen(in_string), PG_UTF8));
+
+ PG_RETURN_TEXT_P(out_val);
+}
+
+/*
+ * convert ntext to rtrimmed text (UTF8 to the database encoding)
+ * used for conversion from nchar types to varchar/text types
+ */
+Datum
+nvarchar2rtrimtext(PG_FUNCTION_ARGS)
+{
+ text *in_val = PG_GETARG_TEXT_PP(0);
+ char *in_string;
+ text *out_val;
+ text *trimmed_val;
+
+ in_string = text_to_cstring(in_val);
+ out_val = cstring_to_text(pg_any_to_server(in_string, strlen(in_string), PG_UTF8));
+ trimmed_val = dotrim(VARDATA_ANY(out_val), VARSIZE_ANY_EXHDR(out_val),
+ " ", 1,
+ false, true);
+ PG_RETURN_TEXT_P(trimmed_val);
+}
+
+
+
+/*
+ * =================
+ * UTILITY FUNCTIONS
+ * =================
+ */
+
+/*
+ * ntextin - converts "..." (assume that "..." using db encoding we need decode it to UTF8) to internal representation
+ */
+
+Datum
+ntextin(PG_FUNCTION_ARGS)
+{
+ char *in_val = PG_GETARG_CSTRING(0);
+
+ PG_RETURN_TEXT_P(cstring_to_text(pg_server_to_any(in_val, strlen(in_val), PG_UTF8)));
+}
+
+/*
+ * ntextout - converts internal representation to "..." (assume that "..." using db encoding we need decode it from UTF8)
+ */
+
+Datum
+ntextout(PG_FUNCTION_ARGS)
+{
+ text *in_val = PG_GETARG_TEXT_PP(0);
+ char *in_string;
+
+ in_string = text_to_cstring(in_val);
+ PG_RETURN_CSTRING(pg_any_to_server(in_string, strlen(in_string), PG_UTF8));
+}
+
+
+/*
+ * Convert a C string to VARCHAR internal representation. atttypmod
+ * is the declared length of the type plus VARHDRSZ.
+ */
+Datum
+nvarcharin(PG_FUNCTION_ARGS)
+{
+ char *s = PG_GETARG_CSTRING(0);
+#ifdef NOT_USED
+ Oid typelem = PG_GETARG_OID(1);
+#endif
+ int32 atttypmod = PG_GETARG_INT32(2);
+ VarChar *result;
+
+// result = varchar_input(s, strlen(s), atttypmod);
+// PG_RETURN_VARCHAR_P(result);
+ PG_RETURN_VARCHAR_P(cstring_to_text(pg_server_to_any(s, strlen(s), PG_UTF8)));
+}
+
+
+/*
+ * Convert a VARCHAR value to a C string.
+ *
+ * Uses the text to C string conversion function, which is only appropriate
+ * if VarChar and text are equivalent types.
+ */
+Datum
+nvarcharout(PG_FUNCTION_ARGS)
+{
+ Datum txt = PG_GETARG_DATUM(0);
+ char *in_string;
+
+ in_string = text_to_cstring(txt);
+ PG_RETURN_CSTRING(pg_any_to_server(in_string, strlen(txt), PG_UTF8));
+}
+
+
+Datum
+ntextlower(PG_FUNCTION_ARGS)
+{
+ text *in_string = PG_GETARG_TEXT_PP(0);
+ char *out_string;
+ text *result;
+
+ out_string = str_tolower(VARDATA_ANY(in_string),
+ VARSIZE_ANY_EXHDR(in_string),
+ CollationGetCollid(ntext_collation));
+ result = cstring_to_text(out_string);
+ pfree(out_string);
+
+ PG_RETURN_TEXT_P(result);
+}
+
+Datum
+ntextupper(PG_FUNCTION_ARGS)
+{
+ text *in_string = PG_GETARG_TEXT_PP(0);
+ char *out_string;
+ text *result;
+
+ out_string = str_toupper(VARDATA_ANY(in_string),
+ VARSIZE_ANY_EXHDR(in_string),
+ CollationGetCollid(ntext_collation));
+ result = cstring_to_text(out_string);
+ pfree(out_string);
+
+ PG_RETURN_TEXT_P(result);
+}
+
+
+/*
+ * actual octet length of an utf8 text
+ */
+Datum
+ntextoctetlen(PG_FUNCTION_ARGS)
+{
+// Datum arg = PG_GETARG_DATUM(0);
+// /* We need not detoast the input at all */
+// PG_RETURN_INT32(toast_raw_datum_size(arg) - VARHDRSZ);
+ text *in_val = PG_GETARG_TEXT_PP(0);
+ char *in_string;
+ int len;
+
+ in_string = text_to_cstring(in_val);
+ len = strlen(in_string);
+
+ PG_RETURN_INT32(len);
+}
+
+/*
+ * ntextcmp()
+ * Internal comparison function for ntext strings.
+ * Returns int32 negative, zero, or positive.
+ */
+static int32
+ntextcmp(text *left, text *right, Oid collid)
+{
+ return varstr_cmp(VARDATA_ANY(left), VARSIZE_ANY_EXHDR(left),
+ VARDATA_ANY(right), VARSIZE_ANY_EXHDR(right),
+ collid);
+}
+
+/*
+ * ==================
+ * INDEXING FUNCTIONS
+ * ==================
+ */
+Datum
+ntext_cmp(PG_FUNCTION_ARGS)
+{
+ text *left = PG_GETARG_TEXT_PP(0);
+ text *right = PG_GETARG_TEXT_PP(1);
+ int32 result;
+
+ result = ntextcmp(left, right, CollationGetCollid(ntext_collation));
+
+ PG_FREE_IF_COPY(left, 0);
+ PG_FREE_IF_COPY(right, 1);
+
+ PG_RETURN_INT32(result);
+}
+
+PG_FUNCTION_INFO_V1(ntext_hash);
+
+Datum
+ntext_hash(PG_FUNCTION_ARGS)
+{
+ text *txt = PG_GETARG_TEXT_PP(0);
+ Datum result;
+
+ result = hash_any((unsigned char *) VARDATA_ANY(txt), VARSIZE_ANY_EXHDR(txt));
+
+ /* Avoid leaking memory for toasted inputs */
+ PG_FREE_IF_COPY(txt, 0);
+
+ PG_RETURN_DATUM(result);
+}
+
+/*
+ * ==================
+ * OPERATOR FUNCTIONS
+ * ==================
+ */
+Datum
+ntext_eq(PG_FUNCTION_ARGS)
+{
+ text *left = PG_GETARG_TEXT_PP(0);
+ text *right = PG_GETARG_TEXT_PP(1);
+ bool result;
+
+ /*
+ * Since we only care about equality or not-equality, we can avoid all the
+ * expense of strcoll() here, and just do bitwise comparison.
+ */
+ result = (strcmp(text_to_cstring(left), text_to_cstring(right)) == 0);
+
+ PG_FREE_IF_COPY(left, 0);
+ PG_FREE_IF_COPY(right, 1);
+
+ PG_RETURN_BOOL(result);
+}
+
+Datum
+ntext_ne(PG_FUNCTION_ARGS)
+{
+ text *left = PG_GETARG_TEXT_PP(0);
+ text *right = PG_GETARG_TEXT_PP(1);
+ bool result;
+
+ /*
+ * Since we only care about equality or not-equality, we can avoid all the
+ * expense of strcoll() here, and just do bitwise comparison.
+ */
+ result = (strcmp(text_to_cstring(left), text_to_cstring(right)) != 0);
+
+ PG_FREE_IF_COPY(left, 0);
+ PG_FREE_IF_COPY(right, 1);
+
+ PG_RETURN_BOOL(result);
+}
+
+Datum
+ntext_lt(PG_FUNCTION_ARGS)
+{
+ text *left = PG_GETARG_TEXT_PP(0);
+ text *right = PG_GETARG_TEXT_PP(1);
+ bool result;
+
+ result = ntextcmp(left, right, CollationGetCollid(ntext_collation)) < 0;
+
+ PG_FREE_IF_COPY(left, 0);
+ PG_FREE_IF_COPY(right, 1);
+
+ PG_RETURN_BOOL(result);
+}
+
+Datum
+ntext_le(PG_FUNCTION_ARGS)
+{
+ text *left = PG_GETARG_TEXT_PP(0);
+ text *right = PG_GETARG_TEXT_PP(1);
+ bool result;
+
+ result = ntextcmp(left, right, CollationGetCollid(ntext_collation)) <= 0;
+
+ PG_FREE_IF_COPY(left, 0);
+ PG_FREE_IF_COPY(right, 1);
+
+ PG_RETURN_BOOL(result);
+}
+
+Datum
+ntext_gt(PG_FUNCTION_ARGS)
+{
+ text *left = PG_GETARG_TEXT_PP(0);
+ text *right = PG_GETARG_TEXT_PP(1);
+ bool result;
+
+ result = ntextcmp(left, right, CollationGetCollid(ntext_collation)) > 0;
+
+ PG_FREE_IF_COPY(left, 0);
+ PG_FREE_IF_COPY(right, 1);
+
+ PG_RETURN_BOOL(result);
+}
+
+Datum
+ntext_ge(PG_FUNCTION_ARGS)
+{
+ text *left = PG_GETARG_TEXT_PP(0);
+ text *right = PG_GETARG_TEXT_PP(1);
+ bool result;
+
+ result = ntextcmp(left, right, CollationGetCollid(ntext_collation)) >= 0;
+
+ PG_FREE_IF_COPY(left, 0);
+ PG_FREE_IF_COPY(right, 1);
+
+ PG_RETURN_BOOL(result);
+}
+
+/*
+ * ===================
+ * AGGREGATE FUNCTIONS
+ * ===================
+ */
+Datum
+ntext_smaller(PG_FUNCTION_ARGS)
+{
+ text *left = PG_GETARG_TEXT_PP(0);
+ text *right = PG_GETARG_TEXT_PP(1);
+ text *result;
+
+ result = ntextcmp(left, right, CollationGetCollid(ntext_collation)) < 0 ? left : right;
+ PG_RETURN_TEXT_P(result);
+}
+
+Datum
+ntext_larger(PG_FUNCTION_ARGS)
+{
+ text *left = PG_GETARG_TEXT_PP(0);
+ text *right = PG_GETARG_TEXT_PP(1);
+ text *result;
+
+ result = ntextcmp(left, right, CollationGetCollid(ntext_collation)) > 0 ? left : right;
+ PG_RETURN_TEXT_P(result);
+}
+
+
diff -U 5 -N -r -w ../orig.HEAD/src/backend/utils/adt/oracle_compat.c ./src/backend/utils/adt/oracle_compat.c
--- ../orig.HEAD/src/backend/utils/adt/oracle_compat.c 2013-08-19 20:22:09.000000000 -0400
+++ ./src/backend/utils/adt/oracle_compat.c 2013-08-19 20:54:00.000000000 -0400
@@ -18,15 +18,10 @@
#include "utils/builtins.h"
#include "utils/formatting.h"
#include "mb/pg_wchar.h"
-static text *dotrim(const char *string, int stringlen,
- const char *set, int setlen,
- bool doltrim, bool dortrim);
-
-
/********************************************************************
*
* lower
*
* Syntax:
@@ -365,11 +360,11 @@
}
/*
* Common implementation for btrim, ltrim, rtrim
*/
-static text *
+text *
dotrim(const char *string, int stringlen,
const char *set, int setlen,
bool doltrim, bool dortrim)
{
int i;
diff -U 5 -N -r -w ../orig.HEAD/src/backend/utils/adt/selfuncs.c ./src/backend/utils/adt/selfuncs.c
--- ../orig.HEAD/src/backend/utils/adt/selfuncs.c 2013-08-19 20:22:09.000000000 -0400
+++ ./src/backend/utils/adt/selfuncs.c 2013-08-19 20:54:00.000000000 -0400
@@ -3624,11 +3624,13 @@
/*
* Built-in string types
*/
case CHAROID:
case BPCHAROID:
+ case NBPCHAROID:
case VARCHAROID:
+ case NVARCHAROID:
case TEXTOID:
case NAMEOID:
{
char *valstr = convert_string_datum(value, valuetypid);
char *lostr = convert_string_datum(lobound, boundstypid);
@@ -3886,11 +3888,13 @@
val = (char *) palloc(2);
val[0] = DatumGetChar(value);
val[1] = '\0';
break;
case BPCHAROID:
+ case NBPCHAROID:
case VARCHAROID:
+ case NVARCHAROID:
case TEXTOID:
val = TextDatumGetCString(value);
break;
case NAMEOID:
{
@@ -5873,11 +5877,13 @@
*/
switch (datatype)
{
case TEXTOID:
case VARCHAROID:
+ case NVARCHAROID:
case BPCHAROID:
+ case NBPCHAROID:
collation = DEFAULT_COLLATION_OID;
constlen = -1;
break;
case NAMEOID:
diff -U 5 -N -r -w ../orig.HEAD/src/include/catalog/pg_amop.h ./src/include/catalog/pg_amop.h
--- ../orig.HEAD/src/include/catalog/pg_amop.h 2013-08-19 20:22:12.000000000 -0400
+++ ./src/include/catalog/pg_amop.h 2013-08-19 20:54:00.000000000 -0400
@@ -251,10 +251,17 @@
DATA(insert ( 426 1042 1042 2 s 1059 403 0 ));
DATA(insert ( 426 1042 1042 3 s 1054 403 0 ));
DATA(insert ( 426 1042 1042 4 s 1061 403 0 ));
DATA(insert ( 426 1042 1042 5 s 1060 403 0 ));
+DATA(insert ( 426 5001 5001 1 s 5058 403 0 ));
+DATA(insert ( 426 5001 5001 2 s 5059 403 0 ));
+DATA(insert ( 426 5001 5001 3 s 5054 403 0 ));
+DATA(insert ( 426 5001 5001 4 s 5061 403 0 ));
+DATA(insert ( 426 5001 5001 5 s 5060 403 0 ));
+
+
/*
* btree bytea_ops
*/
DATA(insert ( 428 17 17 1 s 1957 403 0 ));
@@ -506,10 +513,14 @@
* hash index _ops
*/
/* bpchar_ops */
DATA(insert ( 427 1042 1042 1 s 1054 405 0 ));
+
+/* nbpchar_ops */
+DATA(insert ( 427 5001 5001 1 s 5054 405 0 ));
+
/* char_ops */
DATA(insert ( 431 18 18 1 s 92 405 0 ));
/* date_ops */
DATA(insert ( 435 1082 1082 1 s 1093 405 0 ));
/* float_ops */
diff -U 5 -N -r -w ../orig.HEAD/src/include/catalog/pg_amproc.h ./src/include/catalog/pg_amproc.h
--- ../orig.HEAD/src/include/catalog/pg_amproc.h 2013-08-19 20:22:12.000000000 -0400
+++ ./src/include/catalog/pg_amproc.h 2013-08-19 20:54:00.000000000 -0400
@@ -78,10 +78,11 @@
DATA(insert ( 397 2277 2277 1 382 ));
DATA(insert ( 421 702 702 1 357 ));
DATA(insert ( 423 1560 1560 1 1596 ));
DATA(insert ( 424 16 16 1 1693 ));
DATA(insert ( 426 1042 1042 1 1078 ));
+DATA(insert ( 426 5001 5001 1 1078 ));
DATA(insert ( 428 17 17 1 1954 ));
DATA(insert ( 429 18 18 1 358 ));
DATA(insert ( 434 1082 1082 1 1092 ));
DATA(insert ( 434 1082 1082 2 3136 ));
DATA(insert ( 434 1082 1114 1 2344 ));
@@ -126,20 +127,22 @@
DATA(insert ( 1996 1083 1083 1 1107 ));
DATA(insert ( 2000 1266 1266 1 1358 ));
DATA(insert ( 2002 1562 1562 1 1672 ));
DATA(insert ( 2095 25 25 1 2166 ));
DATA(insert ( 2097 1042 1042 1 2180 ));
+DATA(insert ( 2097 5001 5001 1 2180 ));
DATA(insert ( 2099 790 790 1 377 ));
DATA(insert ( 2233 703 703 1 380 ));
DATA(insert ( 2234 704 704 1 381 ));
DATA(insert ( 2789 27 27 1 2794 ));
DATA(insert ( 2968 2950 2950 1 2960 ));
DATA(insert ( 3522 3500 3500 1 3514 ));
/* hash */
DATA(insert ( 427 1042 1042 1 1080 ));
+DATA(insert ( 427 5001 5001 1 1080 ));
DATA(insert ( 431 18 18 1 454 ));
DATA(insert ( 435 1082 1082 1 450 ));
DATA(insert ( 627 2277 2277 1 626 ));
DATA(insert ( 1971 700 700 1 451 ));
DATA(insert ( 1971 701 701 1 452 ));
@@ -165,10 +168,11 @@
DATA(insert ( 2226 29 29 1 450 ));
DATA(insert ( 2227 702 702 1 450 ));
DATA(insert ( 2228 703 703 1 450 ));
DATA(insert ( 2229 25 25 1 400 ));
DATA(insert ( 2231 1042 1042 1 1080 ));
+DATA(insert ( 2231 5001 5001 1 1080 ));
DATA(insert ( 2235 1033 1033 1 329 ));
DATA(insert ( 2969 2950 2950 1 2963 ));
DATA(insert ( 3523 3500 3500 1 3515 ));
diff -U 5 -N -r -w ../orig.HEAD/src/include/catalog/pg_cast.h ./src/include/catalog/pg_cast.h
--- ../orig.HEAD/src/include/catalog/pg_cast.h 2013-08-19 20:22:12.000000000 -0400
+++ ./src/include/catalog/pg_cast.h 2013-08-19 20:54:00.000000000 -0400
@@ -212,16 +212,77 @@
DATA(insert ( 1043 2205 1079 i f ));
/*
* String category
*/
-DATA(insert ( 25 1042 0 i b ));
-DATA(insert ( 25 1043 0 i b ));
+/*
+ * 501 UTF8 conversion to database encoding
+ * 502 database encoding to UTF8
+ * 401 rtrim
+ * 503 conversion from UTF8 + rtrim
+ * 504 rtrim + conversion to UTF8
+ * national -> common is always 'a' = assigment autocasts (and they could fail if encoding error happen)
+ * common -> nactional is always 'i' = implicit (because they should work always)
+ * temporary assume rtrim not depend on actual encoding (which is definitely wrong assumption)
+*/
+
+/*
+ * char -> text
+ * char -> varchar
+ * char -> nchar
+ * char -> nvarchar
+*/
DATA(insert ( 1042 25 401 i f ));
DATA(insert ( 1042 1043 401 i f ));
+DATA(insert ( 1042 5001 502 i f ));
+DATA(insert ( 1042 6001 504 i f ));
+
+/*
+ * varchar -> text
+ * varchar -> char
+ * varchar -> nvarchar
+ * varchar -> nchar
+*/
DATA(insert ( 1043 25 0 i b ));
DATA(insert ( 1043 1042 0 i b ));
+DATA(insert ( 1043 6001 502 i f ));
+DATA(insert ( 1043 5001 502 i f ));
+
+/*
+ * text -> varchar
+ * text -> char
+ * text -> nchar
+ * text -> nvarchar
+*/
+DATA(insert ( 25 1043 0 i b ));
+DATA(insert ( 25 1042 0 i b ));
+DATA(insert ( 25 5001 502 i f ));
+DATA(insert ( 25 6001 502 i f ));
+
+/*
+ * nvarchar -> text
+ * nvarchar -> varchar
+ * nvarchar -> char
+ * nvarchar -> nchar
+*/
+DATA(insert ( 6001 25 501 a f ));
+DATA(insert ( 6001 1043 501 a f ));
+DATA(insert ( 6001 1042 501 a f ));
+DATA(insert ( 6001 5001 0 i f ));
+
+/*
+ * nchar -> text
+ * nchar -> varchar
+ * nchar -> char
+ * nchar -> nvarchar
+*/
+DATA(insert ( 5001 25 503 a f ));
+DATA(insert ( 5001 1042 503 a f ));
+DATA(insert ( 5001 1043 501 a f ));
+DATA(insert ( 5001 6001 401 i f ));
+
+
DATA(insert ( 18 25 946 i f ));
DATA(insert ( 18 1042 860 a f ));
DATA(insert ( 18 1043 946 a f ));
DATA(insert ( 19 25 406 i f ));
DATA(insert ( 19 1042 408 a f ));
@@ -347,11 +408,13 @@
/*
* Length-coercion functions
*/
DATA(insert ( 1042 1042 668 i f ));
+DATA(insert ( 5001 5001 5668 i f ));
DATA(insert ( 1043 1043 669 i f ));
+DATA(insert ( 6001 6001 5669 i f ));
DATA(insert ( 1083 1083 1968 i f ));
DATA(insert ( 1114 1114 1961 i f ));
DATA(insert ( 1184 1184 1967 i f ));
DATA(insert ( 1186 1186 1200 i f ));
DATA(insert ( 1266 1266 1969 i f ));
diff -U 5 -N -r -w ../orig.HEAD/src/include/catalog/pg_opclass.h ./src/include/catalog/pg_opclass.h
--- ../orig.HEAD/src/include/catalog/pg_opclass.h 2013-08-19 20:22:12.000000000 -0400
+++ ./src/include/catalog/pg_opclass.h 2013-08-19 20:54:00.000000000 -0400
@@ -95,10 +95,12 @@
DATA(insert ( 405 array_ops PGNSP PGUID 627 2277 t 0 ));
DATA(insert ( 403 bit_ops PGNSP PGUID 423 1560 t 0 ));
DATA(insert ( 403 bool_ops PGNSP PGUID 424 16 t 0 ));
DATA(insert ( 403 bpchar_ops PGNSP PGUID 426 1042 t 0 ));
DATA(insert ( 405 bpchar_ops PGNSP PGUID 427 1042 t 0 ));
+DATA(insert ( 403 nbpchar_ops PGNSP PGUID 426 5001 t 0 ));
+DATA(insert ( 405 nbpchar_ops PGNSP PGUID 427 5001 t 0 ));
DATA(insert ( 403 bytea_ops PGNSP PGUID 428 17 t 0 ));
DATA(insert ( 403 char_ops PGNSP PGUID 429 18 t 0 ));
DATA(insert ( 405 char_ops PGNSP PGUID 431 18 t 0 ));
DATA(insert ( 403 cidr_ops PGNSP PGUID 1974 869 f 0 ));
DATA(insert ( 405 cidr_ops PGNSP PGUID 1975 869 f 0 ));
@@ -154,10 +156,12 @@
DATA(insert ( 403 timetz_ops PGNSP PGUID 2000 1266 t 0 ));
DATA(insert ( 405 timetz_ops PGNSP PGUID 2001 1266 t 0 ));
DATA(insert ( 403 varbit_ops PGNSP PGUID 2002 1562 t 0 ));
DATA(insert ( 403 varchar_ops PGNSP PGUID 1994 25 f 0 ));
DATA(insert ( 405 varchar_ops PGNSP PGUID 1995 25 f 0 ));
+DATA(insert ( 403 nvarchar_ops PGNSP PGUID 1994 25 f 0 ));
+DATA(insert ( 405 nvarchar_ops PGNSP PGUID 1995 25 f 0 ));
DATA(insert OID = 3128 ( 403 timestamp_ops PGNSP PGUID 434 1114 t 0 ));
#define TIMESTAMP_BTREE_OPS_OID 3128
DATA(insert ( 405 timestamp_ops PGNSP PGUID 2040 1114 t 0 ));
DATA(insert ( 403 text_pattern_ops PGNSP PGUID 2095 25 f 0 ));
DATA(insert ( 403 varchar_pattern_ops PGNSP PGUID 2095 25 f 0 ));
@@ -185,10 +189,11 @@
DATA(insert ( 2742 _text_ops PGNSP PGUID 2745 1009 t 25 ));
DATA(insert ( 2742 _abstime_ops PGNSP PGUID 2745 1023 t 702 ));
DATA(insert ( 2742 _bit_ops PGNSP PGUID 2745 1561 t 1560 ));
DATA(insert ( 2742 _bool_ops PGNSP PGUID 2745 1000 t 16 ));
DATA(insert ( 2742 _bpchar_ops PGNSP PGUID 2745 1014 t 1042 ));
+DATA(insert ( 2742 _nbpchar_ops PGNSP PGUID 2745 5014 t 5001 ));
DATA(insert ( 2742 _bytea_ops PGNSP PGUID 2745 1001 t 17 ));
DATA(insert ( 2742 _char_ops PGNSP PGUID 2745 1002 t 18 ));
DATA(insert ( 2742 _cidr_ops PGNSP PGUID 2745 651 t 650 ));
DATA(insert ( 2742 _date_ops PGNSP PGUID 2745 1182 t 1082 ));
DATA(insert ( 2742 _float4_ops PGNSP PGUID 2745 1021 t 700 ));
@@ -205,10 +210,11 @@
DATA(insert ( 2742 _time_ops PGNSP PGUID 2745 1183 t 1083 ));
DATA(insert ( 2742 _timestamptz_ops PGNSP PGUID 2745 1185 t 1184 ));
DATA(insert ( 2742 _timetz_ops PGNSP PGUID 2745 1270 t 1266 ));
DATA(insert ( 2742 _varbit_ops PGNSP PGUID 2745 1563 t 1562 ));
DATA(insert ( 2742 _varchar_ops PGNSP PGUID 2745 1015 t 1043 ));
+DATA(insert ( 2742 _nvarchar_ops PGNSP PGUID 2745 5015 t 6001 ));
DATA(insert ( 2742 _timestamp_ops PGNSP PGUID 2745 1115 t 1114 ));
DATA(insert ( 2742 _money_ops PGNSP PGUID 2745 791 t 790 ));
DATA(insert ( 2742 _reltime_ops PGNSP PGUID 2745 1024 t 703 ));
DATA(insert ( 2742 _tinterval_ops PGNSP PGUID 2745 1025 t 704 ));
DATA(insert ( 403 uuid_ops PGNSP PGUID 2968 2950 t 0 ));
diff -U 5 -N -r -w ../orig.HEAD/src/include/catalog/pg_operator.h ./src/include/catalog/pg_operator.h
--- ../orig.HEAD/src/include/catalog/pg_operator.h 2013-08-19 20:22:12.000000000 -0400
+++ ./src/include/catalog/pg_operator.h 2013-08-19 20:54:00.000000000 -0400
@@ -741,26 +741,50 @@
DATA(insert OID = 971 ( "@@" PGNSP PGUID l f f 0 604 600 0 0 poly_center - - ));
DESCR("center of");
DATA(insert OID = 1054 ( "=" PGNSP PGUID b t t 1042 1042 16 1054 1057 bpchareq eqsel eqjoinsel ));
DESCR("equal");
+DATA(insert OID = 5054 ( "=" PGNSP PGUID b t t 5001 5001 16 5054 5057 nbpchareq eqsel eqjoinsel ));
+DESCR("equal");
DATA(insert OID = 1055 ( "~" PGNSP PGUID b f f 1042 25 16 0 1056 bpcharregexeq regexeqsel regexeqjoinsel ));
DESCR("matches regular expression, case-sensitive");
+DATA(insert OID = 5055 ( "~" PGNSP PGUID b f f 5001 25 16 0 5056 nbpcharregexeq regexeqsel regexeqjoinsel ));
+DESCR("matches regular expression, case-sensitive");
+
#define OID_BPCHAR_REGEXEQ_OP 1055
DATA(insert OID = 1056 ( "!~" PGNSP PGUID b f f 1042 25 16 0 1055 bpcharregexne regexnesel regexnejoinsel ));
DESCR("does not match regular expression, case-sensitive");
+DATA(insert OID = 5056 ( "!~" PGNSP PGUID b f f 5001 25 16 0 5055 nbpcharregexne regexnesel regexnejoinsel ));
+DESCR("does not match regular expression, case-sensitive");
+
DATA(insert OID = 1057 ( "<>" PGNSP PGUID b f f 1042 1042 16 1057 1054 bpcharne neqsel neqjoinsel ));
DESCR("not equal");
+DATA(insert OID = 5057 ( "<>" PGNSP PGUID b f f 5001 5001 16 5057 5054 nbpcharne neqsel neqjoinsel ));
+DESCR("not equal");
+
DATA(insert OID = 1058 ( "<" PGNSP PGUID b f f 1042 1042 16 1060 1061 bpcharlt scalarltsel scalarltjoinsel ));
DESCR("less than");
+DATA(insert OID = 5058 ( "<" PGNSP PGUID b f f 5001 5001 16 5060 5061 nbpcharlt scalarltsel scalarltjoinsel ));
+DESCR("less than");
+
DATA(insert OID = 1059 ( "<=" PGNSP PGUID b f f 1042 1042 16 1061 1060 bpcharle scalarltsel scalarltjoinsel ));
DESCR("less than or equal");
+DATA(insert OID = 5059 ( "<=" PGNSP PGUID b f f 5001 5001 16 5061 5060 nbpcharle scalarltsel scalarltjoinsel ));
+DESCR("less than or equal");
+
DATA(insert OID = 1060 ( ">" PGNSP PGUID b f f 1042 1042 16 1058 1059 bpchargt scalargtsel scalargtjoinsel ));
DESCR("greater than");
+DATA(insert OID = 5060 ( ">" PGNSP PGUID b f f 5001 5001 16 5058 5059 nbpchargt scalargtsel scalargtjoinsel ));
+DESCR("greater than");
+
+
DATA(insert OID = 1061 ( ">=" PGNSP PGUID b f f 1042 1042 16 1059 1058 bpcharge scalargtsel scalargtjoinsel ));
DESCR("greater than or equal");
+DATA(insert OID = 5061 ( ">=" PGNSP PGUID b f f 5001 5001 16 5059 5058 nbpcharge scalargtsel scalargtjoinsel ));
+DESCR("greater than or equal");
+
/* generic array comparison operators */
DATA(insert OID = 1070 ( "=" PGNSP PGUID b t t 2277 2277 16 1070 1071 array_eq eqsel eqjoinsel ));
DESCR("equal");
#define ARRAY_EQ_OP 1070
@@ -885,13 +909,18 @@
#define OID_TEXT_LIKE_OP 1209
DATA(insert OID = 1210 ( "!~~" PGNSP PGUID b f f 25 25 16 0 1209 textnlike nlikesel nlikejoinsel ));
DESCR("does not match LIKE expression");
DATA(insert OID = 1211 ( "~~" PGNSP PGUID b f f 1042 25 16 0 1212 bpcharlike likesel likejoinsel ));
DESCR("matches LIKE expression");
+DATA(insert OID = 5211 ( "~~" PGNSP PGUID b f f 5001 25 16 0 5212 nbpcharlike likesel likejoinsel ));
+DESCR("matches LIKE expression");
+
#define OID_BPCHAR_LIKE_OP 1211
DATA(insert OID = 1212 ( "!~~" PGNSP PGUID b f f 1042 25 16 0 1211 bpcharnlike nlikesel nlikejoinsel ));
DESCR("does not match LIKE expression");
+DATA(insert OID = 5212 ( "!~~" PGNSP PGUID b f f 5001 25 16 0 5211 nbpcharnlike nlikesel nlikejoinsel ));
+DESCR("does not match LIKE expression");
/* case-insensitive regex hacks */
DATA(insert OID = 1226 ( "~*" PGNSP PGUID b f f 19 25 16 0 1227 nameicregexeq icregexeqsel icregexeqjoinsel ));
DESCR("matches regular expression, case-insensitive");
#define OID_NAME_ICREGEXEQ_OP 1226
@@ -902,13 +931,18 @@
#define OID_TEXT_ICREGEXEQ_OP 1228
DATA(insert OID = 1229 ( "!~*" PGNSP PGUID b f f 25 25 16 0 1228 texticregexne icregexnesel icregexnejoinsel ));
DESCR("does not match regular expression, case-insensitive");
DATA(insert OID = 1234 ( "~*" PGNSP PGUID b f f 1042 25 16 0 1235 bpcharicregexeq icregexeqsel icregexeqjoinsel ));
DESCR("matches regular expression, case-insensitive");
+DATA(insert OID = 5234 ( "~*" PGNSP PGUID b f f 5001 25 16 0 5235 nbpcharicregexeq icregexeqsel icregexeqjoinsel ));
+DESCR("matches regular expression, case-insensitive");
+
#define OID_BPCHAR_ICREGEXEQ_OP 1234
DATA(insert OID = 1235 ( "!~*" PGNSP PGUID b f f 1042 25 16 0 1234 bpcharicregexne icregexnesel icregexnejoinsel ));
DESCR("does not match regular expression, case-insensitive");
+DATA(insert OID = 5235 ( "!~*" PGNSP PGUID b f f 5001 25 16 0 5234 nbpcharicregexne icregexnesel icregexnejoinsel ));
+DESCR("does not match regular expression, case-insensitive");
/* timestamptz operators */
DATA(insert OID = 1320 ( "=" PGNSP PGUID b t t 1184 1184 16 1320 1321 timestamptz_eq eqsel eqjoinsel ));
DESCR("equal");
DATA(insert OID = 1321 ( "<>" PGNSP PGUID b f f 1184 1184 16 1321 1320 timestamptz_ne neqsel neqjoinsel ));
@@ -1176,13 +1210,18 @@
#define OID_TEXT_ICLIKE_OP 1627
DATA(insert OID = 1628 ( "!~~*" PGNSP PGUID b f f 25 25 16 0 1627 texticnlike icnlikesel icnlikejoinsel ));
DESCR("does not match LIKE expression, case-insensitive");
DATA(insert OID = 1629 ( "~~*" PGNSP PGUID b f f 1042 25 16 0 1630 bpchariclike iclikesel iclikejoinsel ));
DESCR("matches LIKE expression, case-insensitive");
+DATA(insert OID = 5629 ( "~~*" PGNSP PGUID b f f 5001 25 16 0 5630 nbpchariclike iclikesel iclikejoinsel ));
+DESCR("matches LIKE expression, case-insensitive");
#define OID_BPCHAR_ICLIKE_OP 1629
DATA(insert OID = 1630 ( "!~~*" PGNSP PGUID b f f 1042 25 16 0 1629 bpcharicnlike icnlikesel icnlikejoinsel ));
DESCR("does not match LIKE expression, case-insensitive");
+DATA(insert OID = 5630 ( "!~~*" PGNSP PGUID b f f 5001 25 16 0 5629 nbpcharicnlike icnlikesel icnlikejoinsel ));
+DESCR("does not match LIKE expression, case-insensitive");
+
/* NUMERIC type - OID's 1700-1799 */
DATA(insert OID = 1751 ( "-" PGNSP PGUID l f f 0 1700 1700 0 0 numeric_uminus - - ));
DESCR("negate");
DATA(insert OID = 1752 ( "=" PGNSP PGUID b t t 1700 1700 16 1752 1753 numeric_eq eqsel eqjoinsel ));
@@ -1395,16 +1434,27 @@
DATA(insert OID = 2318 ( "~>~" PGNSP PGUID b f f 25 25 16 2314 2315 text_pattern_gt scalargtsel scalargtjoinsel ));
DESCR("greater than");
DATA(insert OID = 2326 ( "~<~" PGNSP PGUID b f f 1042 1042 16 2330 2329 bpchar_pattern_lt scalarltsel scalarltjoinsel ));
DESCR("less than");
+DATA(insert OID = 5326 ( "~<~" PGNSP PGUID b f f 5001 5001 16 5330 5329 nbpchar_pattern_lt scalarltsel scalarltjoinsel ));
+DESCR("less than");
+
DATA(insert OID = 2327 ( "~<=~" PGNSP PGUID b f f 1042 1042 16 2329 2330 bpchar_pattern_le scalarltsel scalarltjoinsel ));
DESCR("less than or equal");
+DATA(insert OID = 5327 ( "~<=~" PGNSP PGUID b f f 5001 5001 16 5329 5330 nbpchar_pattern_le scalarltsel scalarltjoinsel ));
+DESCR("less than or equal");
+
DATA(insert OID = 2329 ( "~>=~" PGNSP PGUID b f f 1042 1042 16 2327 2326 bpchar_pattern_ge scalargtsel scalargtjoinsel ));
DESCR("greater than or equal");
+DATA(insert OID = 5329 ( "~>=~" PGNSP PGUID b f f 5001 5001 16 5327 5326 nbpchar_pattern_ge scalargtsel scalargtjoinsel ));
+DESCR("greater than or equal");
+
DATA(insert OID = 2330 ( "~>~" PGNSP PGUID b f f 1042 1042 16 2326 2327 bpchar_pattern_gt scalargtsel scalargtjoinsel ));
DESCR("greater than");
+DATA(insert OID = 5330 ( "~>~" PGNSP PGUID b f f 5001 5001 16 5326 5327 nbpchar_pattern_gt scalargtsel scalargtjoinsel ));
+DESCR("greater than");
/* crosstype operations for date vs. timestamp and timestamptz */
DATA(insert OID = 2345 ( "<" PGNSP PGUID b f f 1082 1114 16 2375 2348 date_lt_timestamp scalarltsel scalarltjoinsel ));
DESCR("less than");
diff -U 5 -N -r -w ../orig.HEAD/src/include/catalog/pg_proc.h ./src/include/catalog/pg_proc.h
--- ../orig.HEAD/src/include/catalog/pg_proc.h 2013-08-19 20:22:12.000000000 -0400
+++ ./src/include/catalog/pg_proc.h 2013-08-19 20:54:00.000000000 -0400
@@ -743,10 +743,19 @@
DESCR("convert int8 to float8");
DATA(insert OID = 483 ( int8 PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 20 "701" _null_ _null_ _null_ _null_ dtoi8 _null_ _null_ _null_ ));
DESCR("convert float8 to int8");
/* OIDS 500 - 599 */
+/* national characters support functions */
+DATA(insert OID = 501 ( text PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 25 "6001" _null_ _null_ _null_ _null_ nvarchar2text _null_ _null_ _null_ ));
+DESCR("convert nvarchar to text");
+DATA(insert OID = 502 ( nvarchar PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 6001 "25" _null_ _null_ _null_ _null_ text2nvarchar _null_ _null_ _null_ ));
+DESCR("convert text to nvarchar");
+DATA(insert OID = 503 ( text PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 25 "5001" _null_ _null_ _null_ _null_ nvarchar2rtrimtext _null_ _null_ _null_ ));
+DESCR("convert nbpvarchar to rtrimmed text");
+DATA(insert OID = 504 ( nvarchar PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 6001 "1042" _null_ _null_ _null_ _null_ rtrimtext2nvarchar _null_ _null_ _null_ ));
+DESCR("convert trimmed text (bpchar) to nvarchar");
/* OIDS 600 - 699 */
DATA(insert OID = 626 ( hash_array PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 23 "2277" _null_ _null_ _null_ _null_ hash_array _null_ _null_ _null_ ));
DESCR("hash");
@@ -767,14 +776,23 @@
DATA(insert OID = 658 ( namege PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 16 "19 19" _null_ _null_ _null_ _null_ namege _null_ _null_ _null_ ));
DATA(insert OID = 659 ( namene PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 16 "19 19" _null_ _null_ _null_ _null_ namene _null_ _null_ _null_ ));
DATA(insert OID = 668 ( bpchar PGNSP PGUID 12 1 0 0 0 f f f f t f i 3 0 1042 "1042 23 16" _null_ _null_ _null_ _null_ bpchar _null_ _null_ _null_ ));
DESCR("adjust char() to typmod length");
+DATA(insert OID = 5668 ( nbpchar PGNSP PGUID 12 1 0 0 0 f f f f t f i 3 0 5001 "5001 23 16" _null_ _null_ _null_ _null_ bpchar _null_ _null_ _null_ ));
+DESCR("adjust char() to typmod length");
+
DATA(insert OID = 3097 ( varchar_transform PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2281 "2281" _null_ _null_ _null_ _null_ varchar_transform _null_ _null_ _null_ ));
DESCR("transform a varchar length coercion");
+DATA(insert OID = 5097 ( nvarchar_transform PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2281 "2281" _null_ _null_ _null_ _null_ varchar_transform _null_ _null_ _null_ ));
+DESCR("transform a nvarchar length coercion");
+
DATA(insert OID = 669 ( varchar PGNSP PGUID 12 1 0 0 varchar_transform f f f f t f i 3 0 1043 "1043 23 16" _null_ _null_ _null_ _null_ varchar _null_ _null_ _null_ ));
DESCR("adjust varchar() to typmod length");
+DATA(insert OID = 5669 ( nvarchar PGNSP PGUID 12 1 0 0 nvarchar_transform f f f f t f i 3 0 6001 "6001 23 16" _null_ _null_ _null_ _null_ varchar _null_ _null_ _null_ ));
+DESCR("adjust nvarchar() to typmod length");
+
DATA(insert OID = 676 ( mktinterval PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 704 "702 702" _null_ _null_ _null_ _null_ mktinterval _null_ _null_ _null_ ));
DATA(insert OID = 619 ( oidvectorne PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "30 30" _null_ _null_ _null_ _null_ oidvectorne _null_ _null_ _null_ ));
DATA(insert OID = 677 ( oidvectorlt PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "30 30" _null_ _null_ _null_ _null_ oidvectorlt _null_ _null_ _null_ ));
@@ -1118,38 +1136,79 @@
DESCR("make ACL item");
DATA(insert OID = 3943 ( acldefault PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1034 "18 26" _null_ _null_ _null_ _null_ acldefault_sql _null_ _null_ _null_ ));
DESCR("TODO");
DATA(insert OID = 1689 ( aclexplode PGNSP PGUID 12 1 10 0 0 f f f f t t s 1 0 2249 "1034" "{1034,26,26,25,16}" "{i,o,o,o,o}" "{acl,grantor,grantee,privilege_type,is_grantable}" _null_ aclexplode _null_ _null_ _null_ ));
DESCR("convert ACL item array to table, for use by information schema");
-DATA(insert OID = 1044 ( bpcharin PGNSP PGUID 12 1 0 0 0 f f f f t f i 3 0 1042 "2275 26 23" _null_ _null_ _null_ _null_ bpcharin _null_ _null_ _null_ ));
+
+DATA(insert OID = 1043 ( bpcharin PGNSP PGUID 12 1 0 0 0 f f f f t f i 3 0 1042 "2275 26 23" _null_ _null_ _null_ _null_ bpcharin _null_ _null_ _null_ ));
DESCR("I/O");
DATA(insert OID = 1045 ( bpcharout PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2275 "1042" _null_ _null_ _null_ _null_ bpcharout _null_ _null_ _null_ ));
DESCR("I/O");
+
+DATA(insert OID = 5101 ( nbpcharin PGNSP PGUID 12 1 0 0 0 f f f f t f i 3 0 5001 "2275 26 23" _null_ _null_ _null_ _null_ bpcharin _null_ _null_ _null_ ));
+DESCR("I/O");
+DATA(insert OID = 5045 ( nbpcharout PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2275 "5001" _null_ _null_ _null_ _null_ bpcharout _null_ _null_ _null_ ));
+DESCR("I/O");
+
DATA(insert OID = 2913 ( bpchartypmodin PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 23 "1263" _null_ _null_ _null_ _null_ bpchartypmodin _null_ _null_ _null_ ));
DESCR("I/O typmod");
DATA(insert OID = 2914 ( bpchartypmodout PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2275 "23" _null_ _null_ _null_ _null_ bpchartypmodout _null_ _null_ _null_ ));
DESCR("I/O typmod");
+
+DATA(insert OID = 5913 ( nbpchartypmodin PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 23 "1263" _null_ _null_ _null_ _null_ bpchartypmodin _null_ _null_ _null_ ));
+DESCR("I/O typmod");
+DATA(insert OID = 5914 ( nbpchartypmodout PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2275 "23" _null_ _null_ _null_ _null_ bpchartypmodout _null_ _null_ _null_ ));
+DESCR("I/O typmod");
+
DATA(insert OID = 1046 ( varcharin PGNSP PGUID 12 1 0 0 0 f f f f t f i 3 0 1043 "2275 26 23" _null_ _null_ _null_ _null_ varcharin _null_ _null_ _null_ ));
DESCR("I/O");
DATA(insert OID = 1047 ( varcharout PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2275 "1043" _null_ _null_ _null_ _null_ varcharout _null_ _null_ _null_ ));
DESCR("I/O");
+
+DATA(insert OID = 5046 ( nvarcharin PGNSP PGUID 12 1 0 0 0 f f f f t f i 3 0 6001 "2275 26 23" _null_ _null_ _null_ _null_ nvarcharin _null_ _null_ _null_ ));
+DESCR("I/O");
+DATA(insert OID = 5047 ( nvarcharout PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2275 "6001" _null_ _null_ _null_ _null_ nvarcharout _null_ _null_ _null_ ));
+DESCR("I/O");
+
DATA(insert OID = 2915 ( varchartypmodin PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 23 "1263" _null_ _null_ _null_ _null_ varchartypmodin _null_ _null_ _null_ ));
DESCR("I/O typmod");
DATA(insert OID = 2916 ( varchartypmodout PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2275 "23" _null_ _null_ _null_ _null_ varchartypmodout _null_ _null_ _null_ ));
DESCR("I/O typmod");
+
+DATA(insert OID = 5915 ( nvarchartypmodin PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 23 "1263" _null_ _null_ _null_ _null_ varchartypmodin _null_ _null_ _null_ ));
+DESCR("I/O typmod");
+DATA(insert OID = 5916 ( nvarchartypmodout PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2275 "23" _null_ _null_ _null_ _null_ varchartypmodout _null_ _null_ _null_ ));
+DESCR("I/O typmod");
+
DATA(insert OID = 1048 ( bpchareq PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 16 "1042 1042" _null_ _null_ _null_ _null_ bpchareq _null_ _null_ _null_ ));
DATA(insert OID = 1049 ( bpcharlt PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "1042 1042" _null_ _null_ _null_ _null_ bpcharlt _null_ _null_ _null_ ));
DATA(insert OID = 1050 ( bpcharle PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "1042 1042" _null_ _null_ _null_ _null_ bpcharle _null_ _null_ _null_ ));
DATA(insert OID = 1051 ( bpchargt PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "1042 1042" _null_ _null_ _null_ _null_ bpchargt _null_ _null_ _null_ ));
DATA(insert OID = 1052 ( bpcharge PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "1042 1042" _null_ _null_ _null_ _null_ bpcharge _null_ _null_ _null_ ));
DATA(insert OID = 1053 ( bpcharne PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 16 "1042 1042" _null_ _null_ _null_ _null_ bpcharne _null_ _null_ _null_ ));
+
+DATA(insert OID = 5048 ( nbpchareq PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 16 "5001 5001" _null_ _null_ _null_ _null_ bpchareq _null_ _null_ _null_ ));
+DATA(insert OID = 5049 ( nbpcharlt PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "5001 5001" _null_ _null_ _null_ _null_ bpcharlt _null_ _null_ _null_ ));
+DATA(insert OID = 5050 ( nbpcharle PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "5001 5001" _null_ _null_ _null_ _null_ bpcharle _null_ _null_ _null_ ));
+DATA(insert OID = 5051 ( nbpchargt PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "5001 5001" _null_ _null_ _null_ _null_ bpchargt _null_ _null_ _null_ ));
+DATA(insert OID = 5052 ( nbpcharge PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "5001 5001" _null_ _null_ _null_ _null_ bpcharge _null_ _null_ _null_ ));
+DATA(insert OID = 5053 ( nbpcharne PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 16 "5001 5001" _null_ _null_ _null_ _null_ bpcharne _null_ _null_ _null_ ));
+
DATA(insert OID = 1063 ( bpchar_larger PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1042 "1042 1042" _null_ _null_ _null_ _null_ bpchar_larger _null_ _null_ _null_ ));
DESCR("larger of two");
DATA(insert OID = 1064 ( bpchar_smaller PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1042 "1042 1042" _null_ _null_ _null_ _null_ bpchar_smaller _null_ _null_ _null_ ));
DESCR("smaller of two");
DATA(insert OID = 1078 ( bpcharcmp PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 23 "1042 1042" _null_ _null_ _null_ _null_ bpcharcmp _null_ _null_ _null_ ));
DESCR("less-equal-greater");
+
+DATA(insert OID = 5063 ( nbpchar_larger PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 5001 "5001 5001" _null_ _null_ _null_ _null_ bpchar_larger _null_ _null_ _null_ ));
+DESCR("larger of two");
+DATA(insert OID = 5064 ( nbpchar_smaller PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 5001 "5001 5001" _null_ _null_ _null_ _null_ bpchar_smaller _null_ _null_ _null_ ));
+DESCR("smaller of two");
+DATA(insert OID = 5078 ( nbpcharcmp PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 23 "5001 5001" _null_ _null_ _null_ _null_ bpcharcmp _null_ _null_ _null_ ));
+DESCR("less-equal-greater");
+
DATA(insert OID = 1080 ( hashbpchar PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 23 "1042" _null_ _null_ _null_ _null_ hashbpchar _null_ _null_ _null_ ));
DESCR("hash");
DATA(insert OID = 1081 ( format_type PGNSP PGUID 12 1 0 0 0 f f f f f f s 2 0 25 "26 23" _null_ _null_ _null_ _null_ format_type _null_ _null_ _null_ ));
DESCR("format a type oid and atttypmod to canonical SQL");
DATA(insert OID = 1084 ( date_in PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 1082 "2275" _null_ _null_ _null_ _null_ date_in _null_ _null_ _null_ ));
@@ -1492,10 +1551,14 @@
DESCR("character length");
DATA(insert OID = 1374 ( octet_length PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 23 "25" _null_ _null_ _null_ _null_ textoctetlen _null_ _null_ _null_ ));
DESCR("octet length");
DATA(insert OID = 1375 ( octet_length PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 23 "1042" _null_ _null_ _null_ _null_ bpcharoctetlen _null_ _null_ _null_ ));
DESCR("octet length");
+DATA(insert OID = 5374 ( octet_length PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 23 "5001" _null_ _null_ _null_ _null_ bpcharoctetlen _null_ _null_ _null_ ));
+DESCR("octet length");
+DATA(insert OID = 5375 ( octet_length PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 23 "6001" _null_ _null_ _null_ _null_ textoctetlen _null_ _null_ _null_ ));
+DESCR("octet length");
DATA(insert OID = 1377 ( time_larger PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1083 "1083 1083" _null_ _null_ _null_ _null_ time_larger _null_ _null_ _null_ ));
DESCR("larger of two");
DATA(insert OID = 1378 ( time_smaller PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1083 "1083 1083" _null_ _null_ _null_ _null_ time_smaller _null_ _null_ _null_ ));
DESCR("smaller of two");
@@ -1547,10 +1610,15 @@
DATA(insert OID = 1400 ( name PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 19 "1043" _null_ _null_ _null_ _null_ text_name _null_ _null_ _null_ ));
DESCR("convert varchar to name");
DATA(insert OID = 1401 ( varchar PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 1043 "19" _null_ _null_ _null_ _null_ name_text _null_ _null_ _null_ ));
DESCR("convert name to varchar");
+DATA(insert OID = 5400 ( name PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 19 "6001" _null_ _null_ _null_ _null_ text_name _null_ _null_ _null_ ));
+DESCR("convert nvarchar to name");
+DATA(insert OID = 5401 ( nvarchar PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 6001 "19" _null_ _null_ _null_ _null_ name_text _null_ _null_ _null_ ));
+DESCR("convert name to nvarchar");
+
DATA(insert OID = 1402 ( current_schema PGNSP PGUID 12 1 0 0 0 f f f f t f s 0 0 19 "" _null_ _null_ _null_ _null_ current_schema _null_ _null_ _null_ ));
DESCR("current schema name");
DATA(insert OID = 1403 ( current_schemas PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 1003 "16" _null_ _null_ _null_ _null_ current_schemas _null_ _null_ _null_ ));
DESCR("current schema search list");
@@ -1821,10 +1889,13 @@
DATA(insert OID = 1624 ( mul_d_interval PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1186 "701 1186" _null_ _null_ _null_ _null_ mul_d_interval _null_ _null_ _null_ ));
DATA(insert OID = 1631 ( bpcharlike PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "1042 25" _null_ _null_ _null_ _null_ textlike _null_ _null_ _null_ ));
DATA(insert OID = 1632 ( bpcharnlike PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "1042 25" _null_ _null_ _null_ _null_ textnlike _null_ _null_ _null_ ));
+DATA(insert OID = 5631 ( nbpcharlike PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "5001 25" _null_ _null_ _null_ _null_ textlike _null_ _null_ _null_ ));
+DATA(insert OID = 5632 ( nbpcharnlike PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "5001 25" _null_ _null_ _null_ _null_ textnlike _null_ _null_ _null_ ));
+
DATA(insert OID = 1633 ( texticlike PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "25 25" _null_ _null_ _null_ _null_ texticlike _null_ _null_ _null_ ));
DATA(insert OID = 1634 ( texticnlike PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "25 25" _null_ _null_ _null_ _null_ texticnlike _null_ _null_ _null_ ));
DATA(insert OID = 1635 ( nameiclike PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "19 25" _null_ _null_ _null_ _null_ nameiclike _null_ _null_ _null_ ));
DATA(insert OID = 1636 ( nameicnlike PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "19 25" _null_ _null_ _null_ _null_ nameicnlike _null_ _null_ _null_ ));
@@ -1836,10 +1907,18 @@
DATA(insert OID = 1658 ( bpcharregexeq PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "1042 25" _null_ _null_ _null_ _null_ textregexeq _null_ _null_ _null_ ));
DATA(insert OID = 1659 ( bpcharregexne PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "1042 25" _null_ _null_ _null_ _null_ textregexne _null_ _null_ _null_ ));
DATA(insert OID = 1660 ( bpchariclike PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "1042 25" _null_ _null_ _null_ _null_ texticlike _null_ _null_ _null_ ));
DATA(insert OID = 1661 ( bpcharicnlike PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "1042 25" _null_ _null_ _null_ _null_ texticnlike _null_ _null_ _null_ ));
+DATA(insert OID = 5656 ( nbpcharicregexeq PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "5001 25" _null_ _null_ _null_ _null_ texticregexeq _null_ _null_ _null_ ));
+DATA(insert OID = 5657 ( nbpcharicregexne PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "5001 25" _null_ _null_ _null_ _null_ texticregexne _null_ _null_ _null_ ));
+DATA(insert OID = 5658 ( nbpcharregexeq PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "5001 25" _null_ _null_ _null_ _null_ textregexeq _null_ _null_ _null_ ));
+DATA(insert OID = 5659 ( nbpcharregexne PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "5001 25" _null_ _null_ _null_ _null_ textregexne _null_ _null_ _null_ ));
+DATA(insert OID = 5660 ( nbpchariclike PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "5001 25" _null_ _null_ _null_ _null_ texticlike _null_ _null_ _null_ ));
+DATA(insert OID = 5661 ( nbpcharicnlike PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "5001 25" _null_ _null_ _null_ _null_ texticnlike _null_ _null_ _null_ ));
+
+
/* Oracle Compatibility Related Functions - By Edmund Mergl <[email protected]> */
DATA(insert OID = 868 ( strpos PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 23 "25 25" _null_ _null_ _null_ _null_ textpos _null_ _null_ _null_ ));
DESCR("position of substring");
DATA(insert OID = 870 ( lower PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 25 "25" _null_ _null_ _null_ _null_ lower _null_ _null_ _null_ ));
DESCR("lowercase");
@@ -3256,10 +3335,18 @@
DATA(insert OID = 2177 ( bpchar_pattern_ge PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "1042 1042" _null_ _null_ _null_ _null_ bpchar_pattern_ge _null_ _null_ _null_ ));
DATA(insert OID = 2178 ( bpchar_pattern_gt PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "1042 1042" _null_ _null_ _null_ _null_ bpchar_pattern_gt _null_ _null_ _null_ ));
DATA(insert OID = 2180 ( btbpchar_pattern_cmp PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 23 "1042 1042" _null_ _null_ _null_ _null_ btbpchar_pattern_cmp _null_ _null_ _null_ ));
DESCR("less-equal-greater");
+DATA(insert OID = 5174 ( nbpchar_pattern_lt PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "5001 5001" _null_ _null_ _null_ _null_ bpchar_pattern_lt _null_ _null_ _null_ ));
+DATA(insert OID = 5175 ( nbpchar_pattern_le PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "5001 5001" _null_ _null_ _null_ _null_ bpchar_pattern_le _null_ _null_ _null_ ));
+DATA(insert OID = 5177 ( nbpchar_pattern_ge PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "5001 5001" _null_ _null_ _null_ _null_ bpchar_pattern_ge _null_ _null_ _null_ ));
+DATA(insert OID = 5178 ( nbpchar_pattern_gt PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "5001 5001" _null_ _null_ _null_ _null_ bpchar_pattern_gt _null_ _null_ _null_ ));
+DATA(insert OID = 5180 ( nbtbpchar_pattern_cmp PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 23 "5001 5001" _null_ _null_ _null_ _null_ btbpchar_pattern_cmp _null_ _null_ _null_ ));
+DESCR("less-equal-greater");
+
+
DATA(insert OID = 2188 ( btint48cmp PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 23 "23 20" _null_ _null_ _null_ _null_ btint48cmp _null_ _null_ _null_ ));
DESCR("less-equal-greater");
DATA(insert OID = 2189 ( btint84cmp PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 23 "20 23" _null_ _null_ _null_ _null_ btint84cmp _null_ _null_ _null_ ));
DESCR("less-equal-greater");
DATA(insert OID = 2190 ( btint24cmp PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 23 "21 23" _null_ _null_ _null_ _null_ btint24cmp _null_ _null_ _null_ ));
@@ -3643,14 +3730,22 @@
DESCR("I/O");
DATA(insert OID = 2430 ( bpcharrecv PGNSP PGUID 12 1 0 0 0 f f f f t f s 3 0 1042 "2281 26 23" _null_ _null_ _null_ _null_ bpcharrecv _null_ _null_ _null_ ));
DESCR("I/O");
DATA(insert OID = 2431 ( bpcharsend PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 17 "1042" _null_ _null_ _null_ _null_ bpcharsend _null_ _null_ _null_ ));
DESCR("I/O");
+DATA(insert OID = 5430 ( nbpcharrecv PGNSP PGUID 12 1 0 0 0 f f f f t f s 3 0 5001 "2281 26 23" _null_ _null_ _null_ _null_ bpcharrecv _null_ _null_ _null_ ));
+DESCR("I/O");
+DATA(insert OID = 5431 ( nbpcharsend PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 17 "5001" _null_ _null_ _null_ _null_ bpcharsend _null_ _null_ _null_ ));
+DESCR("I/O");
DATA(insert OID = 2432 ( varcharrecv PGNSP PGUID 12 1 0 0 0 f f f f t f s 3 0 1043 "2281 26 23" _null_ _null_ _null_ _null_ varcharrecv _null_ _null_ _null_ ));
DESCR("I/O");
DATA(insert OID = 2433 ( varcharsend PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 17 "1043" _null_ _null_ _null_ _null_ varcharsend _null_ _null_ _null_ ));
DESCR("I/O");
+DATA(insert OID = 5432 ( nvarcharrecv PGNSP PGUID 12 1 0 0 0 f f f f t f s 3 0 6001 "2281 26 23" _null_ _null_ _null_ _null_ varcharrecv _null_ _null_ _null_ ));
+DESCR("I/O");
+DATA(insert OID = 5433 ( nvarcharsend PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 17 "6001" _null_ _null_ _null_ _null_ varcharsend _null_ _null_ _null_ ));
+DESCR("I/O");
DATA(insert OID = 2434 ( charrecv PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 18 "2281" _null_ _null_ _null_ _null_ charrecv _null_ _null_ _null_ ));
DESCR("I/O");
DATA(insert OID = 2435 ( charsend PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 17 "18" _null_ _null_ _null_ _null_ charsend _null_ _null_ _null_ ));
DESCR("I/O");
DATA(insert OID = 2436 ( boolrecv PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 16 "2281" _null_ _null_ _null_ _null_ boolrecv _null_ _null_ _null_ ));
diff -U 5 -N -r -w ../orig.HEAD/src/include/catalog/pg_type.h ./src/include/catalog/pg_type.h
--- ../orig.HEAD/src/include/catalog/pg_type.h 2013-08-19 20:22:12.000000000 -0400
+++ ./src/include/catalog/pg_type.h 2013-08-19 20:54:00.000000000 -0400
@@ -457,11 +457,13 @@
DATA(insert OID = 1010 ( _tid PGNSP PGUID -1 f b A f t \054 0 27 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ ));
DATA(insert OID = 1011 ( _xid PGNSP PGUID -1 f b A f t \054 0 28 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ ));
DATA(insert OID = 1012 ( _cid PGNSP PGUID -1 f b A f t \054 0 29 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ ));
DATA(insert OID = 1013 ( _oidvector PGNSP PGUID -1 f b A f t \054 0 30 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ ));
DATA(insert OID = 1014 ( _bpchar PGNSP PGUID -1 f b A f t \054 0 1042 0 array_in array_out array_recv array_send bpchartypmodin bpchartypmodout array_typanalyze i x f 0 -1 0 100 _null_ _null_ _null_ ));
+DATA(insert OID = 5014 ( _nbpchar PGNSP PGUID -1 f b A f t \054 0 5001 0 array_in array_out array_recv array_send nbpchartypmodin nbpchartypmodout array_typanalyze i x f 0 -1 0 100 _null_ _null_ _null_ ));
DATA(insert OID = 1015 ( _varchar PGNSP PGUID -1 f b A f t \054 0 1043 0 array_in array_out array_recv array_send varchartypmodin varchartypmodout array_typanalyze i x f 0 -1 0 100 _null_ _null_ _null_ ));
+DATA(insert OID = 5015 ( _nvarchar PGNSP PGUID -1 f b A f t \054 0 6001 0 array_in array_out array_recv array_send nvarchartypmodin nvarchartypmodout array_typanalyze i x f 0 -1 0 100 _null_ _null_ _null_ ));
DATA(insert OID = 1016 ( _int8 PGNSP PGUID -1 f b A f t \054 0 20 0 array_in array_out array_recv array_send - - array_typanalyze d x f 0 -1 0 0 _null_ _null_ _null_ ));
DATA(insert OID = 1017 ( _point PGNSP PGUID -1 f b A f t \054 0 600 0 array_in array_out array_recv array_send - - array_typanalyze d x f 0 -1 0 0 _null_ _null_ _null_ ));
DATA(insert OID = 1018 ( _lseg PGNSP PGUID -1 f b A f t \054 0 601 0 array_in array_out array_recv array_send - - array_typanalyze d x f 0 -1 0 0 _null_ _null_ _null_ ));
DATA(insert OID = 1019 ( _path PGNSP PGUID -1 f b A f t \054 0 602 0 array_in array_out array_recv array_send - - array_typanalyze d x f 0 -1 0 0 _null_ _null_ _null_ ));
DATA(insert OID = 1020 ( _box PGNSP PGUID -1 f b A f t \073 0 603 0 array_in array_out array_recv array_send - - array_typanalyze d x f 0 -1 0 0 _null_ _null_ _null_ ));
@@ -483,14 +485,23 @@
#define CSTRINGARRAYOID 1263
DATA(insert OID = 1042 ( bpchar PGNSP PGUID -1 f b S f t \054 0 0 1014 bpcharin bpcharout bpcharrecv bpcharsend bpchartypmodin bpchartypmodout - i x f 0 -1 0 100 _null_ _null_ _null_ ));
DESCR("char(length), blank-padded string, fixed storage length");
#define BPCHAROID 1042
+
+DATA(insert OID = 5001 ( nbpchar PGNSP PGUID -1 f b S f t \054 0 0 5014 nbpcharin nbpcharout nbpcharrecv nbpcharsend nbpchartypmodin nbpchartypmodout - i x f 0 -1 0 100 _null_ _null_ _null_ ));
+DESCR("nchar(length), blank-padded national string, fixed storage length");
+#define NBPCHAROID 5001
+
DATA(insert OID = 1043 ( varchar PGNSP PGUID -1 f b S f t \054 0 0 1015 varcharin varcharout varcharrecv varcharsend varchartypmodin varchartypmodout - i x f 0 -1 0 100 _null_ _null_ _null_ ));
DESCR("varchar(length), non-blank-padded string, variable storage length");
#define VARCHAROID 1043
+DATA(insert OID = 6001 ( nvarchar PGNSP PGUID -1 f b S f t \054 0 0 5015 nvarcharin nvarcharout nvarcharrecv nvarcharsend nvarchartypmodin nvarchartypmodout - i x f 0 -1 0 100 _null_ _null_ _null_ ));
+DESCR("nvarchar(length), non-blank-padded national string, variable storage length");
+#define NVARCHAROID 6001
+
DATA(insert OID = 1082 ( date PGNSP PGUID 4 t b D f t \054 0 0 1182 date_in date_out date_recv date_send - - - i p f 0 -1 0 0 _null_ _null_ _null_ ));
DESCR("date");
#define DATEOID 1082
DATA(insert OID = 1083 ( time PGNSP PGUID 8 FLOAT8PASSBYVAL b D f t \054 0 0 1183 time_in time_out time_recv time_send timetypmodin timetypmodout - d p f 0 -1 0 0 _null_ _null_ _null_ ));
DESCR("time of day");
diff -U 5 -N -r -w ../orig.HEAD/src/include/parser/kwlist.h ./src/include/parser/kwlist.h
--- ../orig.HEAD/src/include/parser/kwlist.h 2013-08-19 20:22:12.000000000 -0400
+++ ./src/include/parser/kwlist.h 2013-08-19 20:54:00.000000000 -0400
@@ -255,10 +255,11 @@
PG_KEYWORD("nowait", NOWAIT, UNRESERVED_KEYWORD)
PG_KEYWORD("null", NULL_P, RESERVED_KEYWORD)
PG_KEYWORD("nullif", NULLIF, COL_NAME_KEYWORD)
PG_KEYWORD("nulls", NULLS_P, UNRESERVED_KEYWORD)
PG_KEYWORD("numeric", NUMERIC, COL_NAME_KEYWORD)
+PG_KEYWORD("nvarchar", NVARCHAR, COL_NAME_KEYWORD)
PG_KEYWORD("object", OBJECT_P, UNRESERVED_KEYWORD)
PG_KEYWORD("of", OF, UNRESERVED_KEYWORD)
PG_KEYWORD("off", OFF, UNRESERVED_KEYWORD)
PG_KEYWORD("offset", OFFSET, RESERVED_KEYWORD)
PG_KEYWORD("oids", OIDS, UNRESERVED_KEYWORD)
diff -U 5 -N -r -w ../orig.HEAD/src/include/utils/builtins.h ./src/include/utils/builtins.h
--- ../orig.HEAD/src/include/utils/builtins.h 2013-08-19 20:22:13.000000000 -0400
+++ ./src/include/utils/builtins.h 2013-08-19 20:54:00.000000000 -0400
@@ -324,10 +324,33 @@
extern Datum btfloat4sortsupport(PG_FUNCTION_ARGS);
extern Datum btfloat8sortsupport(PG_FUNCTION_ARGS);
extern Datum btoidsortsupport(PG_FUNCTION_ARGS);
extern Datum btnamesortsupport(PG_FUNCTION_ARGS);
+/* nvarchar.c */
+extern Datum ntextin(PG_FUNCTION_ARGS);
+extern Datum ntextout(PG_FUNCTION_ARGS);
+extern Datum nvarcharin(PG_FUNCTION_ARGS);
+extern Datum nvarcharout(PG_FUNCTION_ARGS);
+extern Datum ntextlower(PG_FUNCTION_ARGS);
+extern Datum ntextupper(PG_FUNCTION_ARGS);
+extern Datum ntextoctetlen(PG_FUNCTION_ARGS);
+extern Datum nvarchar2text(PG_FUNCTION_ARGS);
+extern Datum text2nvarchar(PG_FUNCTION_ARGS);
+extern Datum nvarchar2rtrimtext(PG_FUNCTION_ARGS);
+extern Datum rtrimtext2nvarchar(PG_FUNCTION_ARGS);
+extern Datum ntext_cmp(PG_FUNCTION_ARGS);
+extern Datum ntext_hash(PG_FUNCTION_ARGS);
+extern Datum ntext_eq(PG_FUNCTION_ARGS);
+extern Datum ntext_ne(PG_FUNCTION_ARGS);
+extern Datum ntext_gt(PG_FUNCTION_ARGS);
+extern Datum ntext_ge(PG_FUNCTION_ARGS);
+extern Datum ntext_lt(PG_FUNCTION_ARGS);
+extern Datum ntext_le(PG_FUNCTION_ARGS);
+extern Datum ntext_smaller(PG_FUNCTION_ARGS);
+extern Datum ntext_larger(PG_FUNCTION_ARGS);
+
/* float.c */
extern PGDLLIMPORT int extra_float_digits;
extern double get_float8_infinity(void);
extern float get_float4_infinity(void);
@@ -831,10 +854,13 @@
extern Datum byteanlike(PG_FUNCTION_ARGS);
extern Datum like_escape(PG_FUNCTION_ARGS);
extern Datum like_escape_bytea(PG_FUNCTION_ARGS);
/* oracle_compat.c */
+extern text *dotrim(const char *string, int stringlen,
+ const char *set, int setlen,
+ bool doltrim, bool dortrim);
extern Datum lower(PG_FUNCTION_ARGS);
extern Datum upper(PG_FUNCTION_ARGS);
extern Datum initcap(PG_FUNCTION_ARGS);
extern Datum lpad(PG_FUNCTION_ARGS);
extern Datum rpad(PG_FUNCTION_ARGS);
diff -U 5 -N -r -w ../orig.HEAD/src/interfaces/ecpg/ecpglib/data.c ./src/interfaces/ecpg/ecpglib/data.c
--- ../orig.HEAD/src/interfaces/ecpg/ecpglib/data.c 2013-08-19 20:22:13.000000000 -0400
+++ ./src/interfaces/ecpg/ecpglib/data.c 2013-08-20 05:02:12.000000000 -0400
@@ -225,12 +225,14 @@
}
switch (type)
{
case ECPGt_char:
+ case ECPGt_nchar:
case ECPGt_unsigned_char:
case ECPGt_varchar:
+ case ECPGt_nvarchar:
case ECPGt_string:
break;
default:
pval++;
@@ -448,10 +450,11 @@
ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
return (false);
break;
case ECPGt_char:
+ case ECPGt_nchar:
case ECPGt_unsigned_char:
case ECPGt_string:
{
char *str = (char *) (var + offset * act_tuple);
@@ -506,10 +509,11 @@
pval += size;
}
break;
case ECPGt_varchar:
+ case ECPGt_nvarchar:
{
struct ECPGgeneric_varchar *variable =
(struct ECPGgeneric_varchar *) (var + offset * act_tuple);
variable->len = size;
@@ -545,17 +549,20 @@
default:
break;
}
sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';
+ /*
+ * it will be not too good result if it
+ * truncate in middle of utf byte-sequence
+ */
variable->len = varcharsize;
}
}
pval += size;
}
break;
-
case ECPGt_decimal:
case ECPGt_numeric:
if (isarray && *pval == '"')
nres = PGTYPESnumeric_from_asc(pval + 1, &scan_length);
else
diff -U 5 -N -r -w ../orig.HEAD/src/interfaces/ecpg/ecpglib/descriptor.c ./src/interfaces/ecpg/ecpglib/descriptor.c
--- ../orig.HEAD/src/interfaces/ecpg/ecpglib/descriptor.c 2013-08-19 20:22:13.000000000 -0400
+++ ./src/interfaces/ecpg/ecpglib/descriptor.c 2013-08-20 05:00:38.000000000 -0400
@@ -198,15 +198,17 @@
get_char_item(int lineno, void *var, enum ECPGttype vartype, char *value, int varcharsize)
{
switch (vartype)
{
case ECPGt_char:
+ case ECPGt_nchar:
case ECPGt_unsigned_char:
case ECPGt_string:
strncpy((char *) var, value, varcharsize);
break;
case ECPGt_varchar:
+ case ECPGt_nvarchar:
{
struct ECPGgeneric_varchar *variable =
(struct ECPGgeneric_varchar *) var;
if (varcharsize == 0)
diff -U 5 -N -r -w ../orig.HEAD/src/interfaces/ecpg/ecpglib/error.c ./src/interfaces/ecpg/ecpglib/error.c
--- ../orig.HEAD/src/interfaces/ecpg/ecpglib/error.c 2013-08-19 20:22:13.000000000 -0400
+++ ./src/interfaces/ecpg/ecpglib/error.c 2013-08-19 20:54:00.000000000 -0400
@@ -37,10 +37,20 @@
* expanded.
*/
ecpg_gettext("out of memory on line %d"), line);
break;
+ case ECPG_ENCODING_ERROR:
+ snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
+
+ /*
+ * translator: this string will be truncated at 149 characters
+ * expanded.
+ */
+ ecpg_gettext("encoding conversion error on line %d"), line);
+ break;
+
case ECPG_UNSUPPORTED:
snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
/*
* translator: this string will be truncated at 149 characters
diff -U 5 -N -r -w ../orig.HEAD/src/interfaces/ecpg/ecpglib/execute.c ./src/interfaces/ecpg/ecpglib/execute.c
--- ../orig.HEAD/src/interfaces/ecpg/ecpglib/execute.c 2013-08-19 20:22:13.000000000 -0400
+++ ./src/interfaces/ecpg/ecpglib/execute.c 2013-08-20 05:05:56.000000000 -0400
@@ -244,12 +244,16 @@
return (ECPG_ARRAY_ERROR);
if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), CIDROID, ECPG_ARRAY_NONE, stmt->lineno))
return (ECPG_ARRAY_ERROR);
if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), BPCHAROID, ECPG_ARRAY_NONE, stmt->lineno))
return (ECPG_ARRAY_ERROR);
+ if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), NBPCHAROID, ECPG_ARRAY_NONE, stmt->lineno))
+ return (ECPG_ARRAY_ERROR);
if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), VARCHAROID, ECPG_ARRAY_NONE, stmt->lineno))
return (ECPG_ARRAY_ERROR);
+ if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), NVARCHAROID, ECPG_ARRAY_NONE, stmt->lineno))
+ return (ECPG_ARRAY_ERROR);
if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), DATEOID, ECPG_ARRAY_NONE, stmt->lineno))
return (ECPG_ARRAY_ERROR);
if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), TIMEOID, ECPG_ARRAY_NONE, stmt->lineno))
return (ECPG_ARRAY_ERROR);
if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), TIMESTAMPOID, ECPG_ARRAY_NONE, stmt->lineno))
@@ -360,10 +364,11 @@
if (!PQfformat(results, act_field))
{
switch (var->type)
{
case ECPGt_char:
+ case ECPGt_nchar:
case ECPGt_unsigned_char:
case ECPGt_string:
if (!var->varcharsize && !var->arrsize)
{
/* special mode for handling char**foo=0 */
@@ -385,10 +390,11 @@
}
var->offset *= var->varcharsize;
len = var->offset * ntuples;
}
break;
+ case ECPGt_nvarchar:
case ECPGt_varchar:
len = ntuples * (var->varcharsize + sizeof(int));
break;
default:
len = var->offset * ntuples;
@@ -421,11 +427,11 @@
ecpg_add_mem(var->ind_value, stmt->lineno);
}
/* fill the variable with the tuple(s) */
if (!var->varcharsize && !var->arrsize &&
- (var->type == ECPGt_char || var->type == ECPGt_unsigned_char || var->type == ECPGt_string))
+ (var->type == ECPGt_char || var->type == ECPGt_unsigned_char || var->type == ECPGt_string || var->type == ECPGt_nchar))
{
/* special mode for handling char**foo=0 */
/* filling the array of (char*)s */
char **current_string = (char **) var->value;
@@ -791,10 +797,11 @@
*tobeinserted_p = mallocedval;
break;
case ECPGt_char:
+ case ECPGt_nchar:
case ECPGt_unsigned_char:
case ECPGt_string:
{
/* set slen to string length if type is char * */
int slen = (var->varcharsize == 0) ? strlen((char *) var->value) : (unsigned int) var->varcharsize;
@@ -825,10 +832,11 @@
*tobeinserted_p = mallocedval;
}
break;
case ECPGt_varchar:
+ case ECPGt_nvarchar:
{
struct ECPGgeneric_varchar *variable =
(struct ECPGgeneric_varchar *) (var->value);
if (!(newcopy = (char *) ecpg_alloc(variable->len + 1, lineno)))
@@ -842,11 +850,10 @@
return false;
*tobeinserted_p = mallocedval;
}
break;
-
case ECPGt_decimal:
case ECPGt_numeric:
{
char *str = NULL;
int slen;
@@ -1229,10 +1236,12 @@
desc_inlist.value = sqlda->sqlvar[i].sqldata;
desc_inlist.pointer = &(sqlda->sqlvar[i].sqldata);
switch (desc_inlist.type)
{
case ECPGt_char:
+ case ECPGt_nchar:
+ case ECPGt_nvarchar:
case ECPGt_varchar:
desc_inlist.varcharsize = strlen(sqlda->sqlvar[i].sqldata);
break;
default:
desc_inlist.varcharsize = 0;
@@ -1284,10 +1293,12 @@
desc_inlist.value = sqlda->sqlvar[i].sqldata;
desc_inlist.pointer = &(sqlda->sqlvar[i].sqldata);
switch (desc_inlist.type)
{
case ECPGt_char:
+ case ECPGt_nchar:
+ case ECPGt_nvarchar:
case ECPGt_varchar:
desc_inlist.varcharsize = strlen(sqlda->sqlvar[i].sqldata);
break;
default:
desc_inlist.varcharsize = 0;
diff -U 5 -N -r -w ../orig.HEAD/src/interfaces/ecpg/ecpglib/extern.h ./src/interfaces/ecpg/ecpglib/extern.h
--- ../orig.HEAD/src/interfaces/ecpg/ecpglib/extern.h 2013-08-19 20:22:13.000000000 -0400
+++ ./src/interfaces/ecpg/ecpglib/extern.h 2013-08-19 20:54:00.000000000 -0400
@@ -202,7 +202,8 @@
#define ECPG_SQLSTATE_DUPLICATE_CURSOR "42P03"
/* implementation-defined internal errors of ecpg */
#define ECPG_SQLSTATE_ECPG_INTERNAL_ERROR "YE000"
#define ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY "YE001"
+#define ECPG_SQLSTATE_ECPG_ENCODING_ERROR "YE002"
#endif /* _ECPG_LIB_EXTERN_H */
diff -U 5 -N -r -w ../orig.HEAD/src/interfaces/ecpg/ecpglib/misc.c ./src/interfaces/ecpg/ecpglib/misc.c
--- ../orig.HEAD/src/interfaces/ecpg/ecpglib/misc.c 2013-08-19 20:22:13.000000000 -0400
+++ ./src/interfaces/ecpg/ecpglib/misc.c 2013-08-20 05:04:28.000000000 -0400
@@ -303,10 +303,11 @@
ECPGset_noind_null(enum ECPGttype type, void *ptr)
{
switch (type)
{
case ECPGt_char:
+ case ECPGt_nchar:
case ECPGt_unsigned_char:
case ECPGt_string:
*((char *) ptr) = '\0';
break;
case ECPGt_short:
@@ -332,10 +333,11 @@
memset((char *) ptr, 0xff, sizeof(float));
break;
case ECPGt_double:
memset((char *) ptr, 0xff, sizeof(double));
break;
+ case ECPGt_nvarchar:
case ECPGt_varchar:
*(((struct ECPGgeneric_varchar *) ptr)->arr) = 0x00;
((struct ECPGgeneric_varchar *) ptr)->len = 0;
break;
case ECPGt_decimal:
@@ -405,10 +407,11 @@
return (_check(ptr, sizeof(float)));
break;
case ECPGt_double:
return (_check(ptr, sizeof(double)));
break;
+ case ECPGt_nvarchar:
case ECPGt_varchar:
if (*(((struct ECPGgeneric_varchar *) ptr)->arr) == 0x00)
return true;
break;
case ECPGt_decimal:
@@ -546,5 +549,6 @@
struct var_list *ptr;
for (ptr = ivlist; ptr != NULL && ptr->number != number; ptr = ptr->next);
return (ptr) ? ptr->pointer : NULL;
}
+
diff -U 5 -N -r -w ../orig.HEAD/src/interfaces/ecpg/ecpglib/pg_type.h ./src/interfaces/ecpg/ecpglib/pg_type.h
--- ../orig.HEAD/src/interfaces/ecpg/ecpglib/pg_type.h 2013-08-19 20:22:13.000000000 -0400
+++ ./src/interfaces/ecpg/ecpglib/pg_type.h 2013-08-19 20:54:00.000000000 -0400
@@ -46,10 +46,12 @@
#define CASHOID 790
#define INETOID 869
#define CIDROID 650
#define BPCHAROID 1042
#define VARCHAROID 1043
+#define NBPCHAROID 5001
+#define NVARCHAROID 6001
#define DATEOID 1082
#define TIMEOID 1083
#define TIMESTAMPOID 1114
#define TIMESTAMPTZOID 1184
#define INTERVALOID 1186
diff -U 5 -N -r -w ../orig.HEAD/src/interfaces/ecpg/ecpglib/sqlda.c ./src/interfaces/ecpg/ecpglib/sqlda.c
--- ../orig.HEAD/src/interfaces/ecpg/ecpglib/sqlda.c 2013-08-19 20:22:13.000000000 -0400
+++ ./src/interfaces/ecpg/ecpglib/sqlda.c 2013-08-19 20:54:00.000000000 -0400
@@ -132,10 +132,11 @@
break;
case ECPGt_interval:
ecpg_sqlda_align_add_size(offset, sizeof(int64), sizeof(interval), &offset, &next_offset);
break;
case ECPGt_char:
+ case ECPGt_nchar:
case ECPGt_unsigned_char:
case ECPGt_string:
default:
{
long datalen = strlen(PQgetvalue(res, row, i)) + 1;
@@ -371,10 +372,11 @@
ecpg_sqlda_align_add_size(offset, sizeof(int64), sizeof(interval), &offset, &next_offset);
sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
sqlda->sqlvar[i].sqllen = sizeof(interval);
break;
case ECPGt_char:
+ case ECPGt_nchar:
case ECPGt_unsigned_char:
case ECPGt_string:
default:
datalen = strlen(PQgetvalue(res, row, i)) + 1;
ecpg_sqlda_align_add_size(offset, sizeof(int), datalen, &offset, &next_offset);
@@ -560,10 +562,11 @@
ecpg_sqlda_align_add_size(offset, sizeof(int64), sizeof(interval), &offset, &next_offset);
sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
sqlda->sqlvar[i].sqllen = sizeof(interval);
break;
case ECPGt_char:
+ case ECPGt_nchar:
case ECPGt_unsigned_char:
case ECPGt_string:
default:
datalen = strlen(PQgetvalue(res, row, i)) + 1;
ecpg_sqlda_align_add_size(offset, sizeof(int), datalen, &offset, &next_offset);
diff -U 5 -N -r -w ../orig.HEAD/src/interfaces/ecpg/ecpglib/typename.c ./src/interfaces/ecpg/ecpglib/typename.c
--- ../orig.HEAD/src/interfaces/ecpg/ecpglib/typename.c 2013-08-19 20:22:13.000000000 -0400
+++ ./src/interfaces/ecpg/ecpglib/typename.c 2013-08-20 05:02:32.000000000 -0400
@@ -20,10 +20,12 @@
switch (typ)
{
case ECPGt_char:
case ECPGt_string:
return "char";
+ case ECPGt_nchar:
+ return "national char";
case ECPGt_unsigned_char:
return "unsigned char";
case ECPGt_short:
return "short";
case ECPGt_unsigned_short:
@@ -46,10 +48,12 @@
return "double";
case ECPGt_bool:
return "bool";
case ECPGt_varchar:
return "varchar";
+ case ECPGt_nvarchar:
+ return "nvarchar";
case ECPGt_char_variable:
return "char";
case ECPGt_decimal:
return "decimal";
case ECPGt_numeric:
@@ -85,12 +89,16 @@
return SQL3_REAL; /* float4 */
case FLOAT8OID:
return SQL3_DOUBLE_PRECISION; /* float8 */
case BPCHAROID:
return SQL3_CHARACTER; /* bpchar */
+ case NBPCHAROID:
+ return SQL3_CHARACTER; /* bpchar */
case VARCHAROID:
return SQL3_CHARACTER_VARYING; /* varchar */
+ case NVARCHAROID:
+ return SQL3_CHARACTER_VARYING; /* nvarchar */
case DATEOID:
return SQL3_DATE_TIME_TIMESTAMP; /* date */
case TIMEOID:
return SQL3_DATE_TIME_TIMESTAMP; /* time */
case TIMESTAMPOID:
@@ -107,11 +115,13 @@
{
switch (type)
{
case CHAROID:
case VARCHAROID:
+ case NVARCHAROID:
case BPCHAROID:
+ case NBPCHAROID:
case TEXTOID:
return ECPGt_char;
case INT2OID:
return ECPGt_short;
case INT4OID:
diff -U 5 -N -r -w ../orig.HEAD/src/interfaces/ecpg/include/ecpgerrno.h ./src/interfaces/ecpg/include/ecpgerrno.h
--- ../orig.HEAD/src/interfaces/ecpg/include/ecpgerrno.h 2013-08-19 20:22:13.000000000 -0400
+++ ./src/interfaces/ecpg/include/ecpgerrno.h 2013-08-19 20:54:00.000000000 -0400
@@ -43,10 +43,13 @@
#define ECPG_INVALID_DESCRIPTOR_INDEX -241
#define ECPG_UNKNOWN_DESCRIPTOR_ITEM -242
#define ECPG_VAR_NOT_NUMERIC -243
#define ECPG_VAR_NOT_CHAR -244
+/*encoding conversion errors */
+#define ECPG_ENCODING_ERROR -250
+
/* finally the backend error messages, they start at 400 */
#define ECPG_PGSQL -400
#define ECPG_TRANS -401
#define ECPG_CONNECT -402
#define ECPG_DUPLICATE_KEY -403
diff -U 5 -N -r -w ../orig.HEAD/src/interfaces/ecpg/include/ecpgtype.h ./src/interfaces/ecpg/include/ecpgtype.h
--- ../orig.HEAD/src/interfaces/ecpg/include/ecpgtype.h 2013-08-19 20:22:13.000000000 -0400
+++ ./src/interfaces/ecpg/include/ecpgtype.h 2013-08-20 05:02:01.000000000 -0400
@@ -44,10 +44,12 @@
ECPGt_int, ECPGt_unsigned_int, ECPGt_long, ECPGt_unsigned_long,
ECPGt_long_long, ECPGt_unsigned_long_long,
ECPGt_bool,
ECPGt_float, ECPGt_double,
ECPGt_varchar, ECPGt_varchar2,
+ ECPGt_nvarchar, /* the same as ECPGt_varchar actually */
+ ECPGt_nchar, /* converted to char *arr[N] */
ECPGt_numeric, /* this is a decimal that stores its digits in
* a malloced array */
ECPGt_decimal, /* this is a decimal that stores its digits in
* a fixed array */
ECPGt_date,
@@ -102,5 +104,6 @@
#ifdef __cplusplus
}
#endif
#endif /* _ECPGTYPE_H */
+
diff -U 5 -N -r -w ../orig.HEAD/src/interfaces/ecpg/include/sqltypes.h ./src/interfaces/ecpg/include/sqltypes.h
--- ../orig.HEAD/src/interfaces/ecpg/include/sqltypes.h 2013-08-19 20:22:13.000000000 -0400
+++ ./src/interfaces/ecpg/include/sqltypes.h 2013-08-19 20:54:00.000000000 -0400
@@ -44,10 +44,11 @@
#define SQLTEXT ECPGt_char
#define SQLVCHAR ECPGt_char
#define SQLINTERVAL ECPGt_interval
#define SQLNCHAR ECPGt_char
#define SQLNVCHAR ECPGt_char
+#define SQLNVARCHAR ECPGt_char
#ifdef HAVE_LONG_LONG_INT_64
#define SQLINT8 ECPGt_long_long
#define SQLSERIAL8 ECPGt_long_long
#else
#define SQLINT8 ECPGt_long
diff -U 5 -N -r -w ../orig.HEAD/src/interfaces/ecpg/preproc/c_keywords.c ./src/interfaces/ecpg/preproc/c_keywords.c
--- ../orig.HEAD/src/interfaces/ecpg/preproc/c_keywords.c 2013-08-19 20:22:13.000000000 -0400
+++ ./src/interfaces/ecpg/preproc/c_keywords.c 2013-08-20 05:09:08.000000000 -0400
@@ -25,10 +25,12 @@
/*
* category is not needed in ecpg, it is only here so we can share the
* data structure with the backend
*/
+ {"NCHAR", NCHAR, 0},
+ {"NVARCHAR", NVARCHAR, 0},
{"VARCHAR", VARCHAR, 0},
{"auto", S_AUTO, 0},
{"bool", SQL_BOOL, 0},
{"char", CHAR_P, 0},
{"const", S_CONST, 0},
@@ -38,10 +40,12 @@
{"hour", HOUR_P, 0},
{"int", INT_P, 0},
{"long", SQL_LONG, 0},
{"minute", MINUTE_P, 0},
{"month", MONTH_P, 0},
+ {"nchar", NCHAR, 0},
+ {"nvarchar", NVARCHAR, 0},
{"register", S_REGISTER, 0},
{"second", SECOND_P, 0},
{"short", SQL_SHORT, 0},
{"signed", SQL_SIGNED, 0},
{"static", S_STATIC, 0},
diff -U 5 -N -r -w ../orig.HEAD/src/interfaces/ecpg/preproc/ecpg.header ./src/interfaces/ecpg/preproc/ecpg.header
--- ../orig.HEAD/src/interfaces/ecpg/preproc/ecpg.header 2013-08-19 20:22:13.000000000 -0400
+++ ./src/interfaces/ecpg/preproc/ecpg.header 2013-08-20 05:08:24.000000000 -0400
@@ -267,11 +267,13 @@
{
newvar = ptr->variable;
skip_set_var = true;
}
else if ((ptr->variable->type->type != ECPGt_varchar
+ && ptr->variable->type->type != ECPGt_nvarchar
&& ptr->variable->type->type != ECPGt_char
+ && ptr->variable->type->type != ECPGt_nchar
&& ptr->variable->type->type != ECPGt_unsigned_char
&& ptr->variable->type->type != ECPGt_string)
&& atoi(ptr->variable->type->size) > 1)
{
newvar = new_variable(cat_str(4, mm_strdup("("),
@@ -283,11 +285,13 @@
ptr->variable->type->u.element->counter),
ptr->variable->type->size),
0);
}
else if ((ptr->variable->type->type == ECPGt_varchar
+ || ptr->variable->type->type == ECPGt_nvarchar
|| ptr->variable->type->type == ECPGt_char
+ || ptr->variable->type->type == ECPGt_nchar
|| ptr->variable->type->type == ECPGt_unsigned_char
|| ptr->variable->type->type == ECPGt_string)
&& atoi(ptr->variable->type->size) > 1)
{
newvar = new_variable(cat_str(4, mm_strdup("("),
@@ -296,11 +300,11 @@
mm_strdup(var_text)),
ECPGmake_simple_type(ptr->variable->type->type,
ptr->variable->type->size,
ptr->variable->type->counter),
0);
- if (ptr->variable->type->type == ECPGt_varchar)
+ if (ptr->variable->type->type == ECPGt_varchar || ptr->variable->type->type == ECPGt_nvarchar)
var_ptr = true;
}
else if (ptr->variable->type->type == ECPGt_struct
|| ptr->variable->type->type == ECPGt_union)
{
@@ -543,10 +547,11 @@
this->type->type_sizeof = ECPGstruct_sizeof;
this->struct_member_list = (type_enum == ECPGt_struct || type_enum == ECPGt_union) ?
ECPGstruct_member_dup(struct_member_list[struct_level]) : NULL;
if (type_enum != ECPGt_varchar &&
+ type_enum != ECPGt_nvarchar &&
type_enum != ECPGt_char &&
type_enum != ECPGt_unsigned_char &&
type_enum != ECPGt_string &&
atoi(this->type->type_index) >= 0)
mmerror(PARSE_ERROR, ET_ERROR, "multidimensional arrays for simple data types are not supported");
diff -U 5 -N -r -w ../orig.HEAD/src/interfaces/ecpg/preproc/ecpg.tokens ./src/interfaces/ecpg/preproc/ecpg.tokens
--- ../orig.HEAD/src/interfaces/ecpg/preproc/ecpg.tokens 2013-08-19 20:22:13.000000000 -0400
+++ ./src/interfaces/ecpg/preproc/ecpg.tokens 2013-08-20 05:07:52.000000000 -0400
@@ -14,14 +14,16 @@
SQL_RETURNED_LENGTH SQL_RETURNED_OCTET_LENGTH SQL_SCALE
SQL_SECTION SQL_SHORT SQL_SIGNED SQL_SQL SQL_SQLERROR
SQL_SQLPRINT SQL_SQLWARNING SQL_START SQL_STOP
SQL_STRUCT SQL_UNSIGNED SQL_VAR SQL_WHENEVER
+
/* C tokens */
%token S_ADD S_AND S_ANYTHING S_AUTO S_CONST S_DEC S_DIV
S_DOTPOINT S_EQUAL S_EXTERN S_INC S_LSHIFT S_MEMPOINT
S_MEMBER S_MOD S_MUL S_NEQUAL S_OR S_REGISTER S_RSHIFT
S_STATIC S_SUB S_VOLATILE
S_TYPEDEF
%token CSTRING CVARIABLE CPP_LINE IP
%token DOLCONST ECONST NCONST UCONST UIDENT
+
diff -U 5 -N -r -w ../orig.HEAD/src/interfaces/ecpg/preproc/ecpg.trailer ./src/interfaces/ecpg/preproc/ecpg.trailer
--- ../orig.HEAD/src/interfaces/ecpg/preproc/ecpg.trailer 2013-08-19 20:22:13.000000000 -0400
+++ ./src/interfaces/ecpg/preproc/ecpg.trailer 2013-08-20 05:07:32.000000000 -0400
@@ -184,11 +184,11 @@
/* if array see what's inside */
if (type == ECPGt_array)
type = argsinsert->variable->type->u.element->type;
/* handle varchars */
- if (type == ECPGt_varchar)
+ if (type == ECPGt_varchar || type == ECPGt_nvarchar)
$$ = make2_str(mm_strdup(argsinsert->variable->name), mm_strdup(".arr"));
else
$$ = mm_strdup(argsinsert->variable->name);
}
;
@@ -209,15 +209,17 @@
type = p->type->u.element->type;
switch (type)
{
case ECPGt_char:
+ case ECPGt_nchar:
case ECPGt_unsigned_char:
case ECPGt_string:
$$ = $1;
break;
case ECPGt_varchar:
+ case ECPGt_nvarchar:
$$ = make2_str($1, mm_strdup(".arr"));
break;
default:
mmerror(PARSE_ERROR, ET_ERROR, "invalid data type");
$$ = $1;
@@ -548,10 +550,26 @@
$$.type_str = EMPTY; /*mm_strdup("varchar");*/
$$.type_dimension = mm_strdup("-1");
$$.type_index = mm_strdup("-1");
$$.type_sizeof = NULL;
}
+ else if (strcmp($1, "nvarchar") == 0)
+ {
+ $$.type_enum = ECPGt_nvarchar;
+ $$.type_str = EMPTY; /*mm_strdup("nvarchar");*/
+ $$.type_dimension = mm_strdup("-1");
+ $$.type_index = mm_strdup("-1");
+ $$.type_sizeof = NULL;
+ }
+ else if (strcmp($1, "nchar") == 0)
+ {
+ $$.type_enum = ECPGt_nchar;
+ $$.type_str = EMPTY; /*mm_strdup("nchar");*/
+ $$.type_dimension = mm_strdup("-1");
+ $$.type_index = mm_strdup("-1");
+ $$.type_sizeof = NULL;
+ }
else if (strcmp($1, "float") == 0)
{
$$.type_enum = ECPGt_float;
$$.type_str = mm_strdup("float");
$$.type_dimension = mm_strdup("-1");
@@ -625,11 +643,11 @@
else
{
/* this is for typedef'ed types */
struct typedefs *this = get_typedef($1);
- $$.type_str = (this->type->type_enum == ECPGt_varchar) ? EMPTY : mm_strdup(this->name);
+ $$.type_str = (this->type->type_enum == ECPGt_varchar || this->type->type_enum == ECPGt_nvarchar) ? EMPTY : mm_strdup(this->name);
$$.type_enum = this->type->type_enum;
$$.type_dimension = this->type->type_dimension;
$$.type_index = this->type->type_index;
if (this->type->type_sizeof && strlen(this->type->type_sizeof) != 0)
$$.type_sizeof = this->type->type_sizeof;
@@ -860,10 +878,11 @@
type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum, actual_type[struct_level].type_str, actual_type[struct_level].type_sizeof), dimension);
$$ = cat_str(5, $1, mm_strdup($2), $3.str, $4, $5);
break;
+ case ECPGt_nvarchar:
case ECPGt_varchar:
if (atoi(dimension) < 0)
type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length, varchar_counter);
else
type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length, varchar_counter), dimension);
@@ -884,10 +903,29 @@
else
$$ = cat_str(8, make2_str(mm_strdup(" struct varchar_"), vcn), mm_strdup(" { int len; char arr["), mm_strdup(length), mm_strdup("]; } "), mm_strdup($2), dim_str, $4, $5);
varchar_counter++;
break;
+ case ECPGt_nchar:
+ if (atoi(dimension) == -1)
+ {
+ int i = strlen($5);
+
+ if (atoi(length) == -1 && i > 0) /* char <var>[] = "string" */
+ {
+ /* if we have an initializer but no string size set, let's use the initializer's length */
+ free(length);
+ length = mm_alloc(i+sizeof("sizeof()"));
+ sprintf(length, "sizeof(%s)", $5+2);
+ }
+ type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length, 0);
+ }
+ else
+ type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length, 0), dimension);
+
+ $$ = cat_str(6, mm_strdup("char"), $1, mm_strdup($2), $3.str, $4, $5);
+ break;
case ECPGt_char:
case ECPGt_unsigned_char:
case ECPGt_string:
if (atoi(dimension) == -1)
{
@@ -1346,18 +1384,20 @@
type = ECPGmake_struct_type(struct_member_list[struct_level], $5.type_enum, $5.type_str, $5.type_sizeof);
else
type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], $5.type_enum, $5.type_str, $5.type_sizeof), dimension);
break;
+ case ECPGt_nvarchar:
case ECPGt_varchar:
if (atoi(dimension) == -1)
type = ECPGmake_simple_type($5.type_enum, length, 0);
else
type = ECPGmake_array_type(ECPGmake_simple_type($5.type_enum, length, 0), dimension);
break;
case ECPGt_char:
+ case ECPGt_nchar:
case ECPGt_unsigned_char:
case ECPGt_string:
if (atoi(dimension) == -1)
type = ECPGmake_simple_type($5.type_enum, length, 0);
else
@@ -1842,10 +1882,12 @@
| CHAR_P { $$ = mm_strdup("char"); }
| FLOAT_P { $$ = mm_strdup("float"); }
| TO { $$ = mm_strdup("to"); }
| UNION { $$ = mm_strdup("union"); }
| VARCHAR { $$ = mm_strdup("varchar"); }
+ | NVARCHAR { $$ = mm_strdup("nvarchar"); }
+ | NCHAR { $$ = mm_strdup("nchar"); }
| '[' { $$ = mm_strdup("["); }
| ']' { $$ = mm_strdup("]"); }
| '=' { $$ = mm_strdup("="); }
| ':' { $$ = mm_strdup(":"); }
;
diff -U 5 -N -r -w ../orig.HEAD/src/interfaces/ecpg/preproc/type.c ./src/interfaces/ecpg/preproc/type.c
--- ../orig.HEAD/src/interfaces/ecpg/preproc/type.c 2013-08-19 20:22:13.000000000 -0400
+++ ./src/interfaces/ecpg/preproc/type.c 2013-08-20 05:08:51.000000000 -0400
@@ -135,10 +135,13 @@
switch (type)
{
case ECPGt_char:
return ("ECPGt_char");
break;
+ case ECPGt_nchar:
+ return ("ECPGt_nchar");
+ break;
case ECPGt_unsigned_char:
return ("ECPGt_unsigned_char");
break;
case ECPGt_short:
return ("ECPGt_short");
@@ -173,10 +176,14 @@
case ECPGt_bool:
return ("ECPGt_bool");
break;
case ECPGt_varchar:
return ("ECPGt_varchar");
+ break;
+ case ECPGt_nvarchar:
+ return ("ECPGt_nvarchar");
+ break;
case ECPGt_NO_INDICATOR: /* no indicator */
return ("ECPGt_NO_INDICATOR");
break;
case ECPGt_char_variable: /* string that should not be quoted */
return ("ECPGt_char_variable");
@@ -381,12 +388,12 @@
/*
* we have to use the & operator except for arrays and
* pointers
*/
+ case ECPGt_nvarchar:
case ECPGt_varchar:
-
/*
* we have to use the pointer except for arrays with given
* bounds
*/
if (((atoi(arrsize) > 0) ||
@@ -404,10 +411,11 @@
sprintf(offset, "sizeof(struct varchar_%d)", counter);
else
sprintf(offset, "sizeof(struct varchar)");
break;
case ECPGt_char:
+ case ECPGt_nchar:
case ECPGt_unsigned_char:
case ECPGt_char_variable:
case ECPGt_string:
/*
diff -U 5 -N -r -w ../orig.HEAD/src/interfaces/ecpg/preproc/variable.c ./src/interfaces/ecpg/preproc/variable.c
--- ../orig.HEAD/src/interfaces/ecpg/preproc/variable.c 2013-08-19 20:22:13.000000000 -0400
+++ ./src/interfaces/ecpg/preproc/variable.c 2013-08-20 05:04:08.000000000 -0400
@@ -527,11 +527,11 @@
if (pointer_len > 2)
mmerror(PARSE_ERROR, ET_FATAL, ngettext("multilevel pointers (more than 2 levels) are not supported; found %d level",
"multilevel pointers (more than 2 levels) are not supported; found %d levels", pointer_len),
pointer_len);
- if (pointer_len > 1 && type_enum != ECPGt_char && type_enum != ECPGt_unsigned_char && type_enum != ECPGt_string)
+ if (pointer_len > 1 && type_enum != ECPGt_char && type_enum != ECPGt_nchar && type_enum != ECPGt_unsigned_char && type_enum != ECPGt_string)
mmerror(PARSE_ERROR, ET_FATAL, "pointer to pointer is not supported for this data type");
if (pointer_len > 1 && (atoi(*length) >= 0 || atoi(*dimension) >= 0))
mmerror(PARSE_ERROR, ET_FATAL, "multidimensional arrays are not supported");
@@ -552,10 +552,11 @@
if (atoi(*length) >= 0)
mmerror(PARSE_ERROR, ET_FATAL, "multidimensional arrays for structures are not supported");
break;
case ECPGt_varchar:
+ case ECPGt_nvarchar:
/* pointer has to get dimension 0 */
if (pointer_len)
*dimension = mm_strdup("0");
/* one index is the string length */
@@ -565,10 +566,11 @@
*dimension = mm_strdup("-1");
}
break;
case ECPGt_char:
+ case ECPGt_nchar:
case ECPGt_unsigned_char:
case ECPGt_string:
/* char ** */
if (pointer_len == 2)
{
diff -U 5 -N -r -w ../orig.HEAD/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c ./src/interfaces/ecpg/test/expected/compat_informix-sqlda.c
--- ../orig.HEAD/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c 2013-08-19 20:22:13.000000000 -0400
+++ ./src/interfaces/ecpg/test/expected/compat_informix-sqlda.c 2013-08-19 20:54:00.000000000 -0400
@@ -95,10 +95,11 @@
#define SQLTEXT ECPGt_char
#define SQLVCHAR ECPGt_char
#define SQLINTERVAL ECPGt_interval
#define SQLNCHAR ECPGt_char
#define SQLNVCHAR ECPGt_char
+#define SQLNVARCHAR ECPGt_char
#ifdef HAVE_LONG_LONG_INT_64
#define SQLINT8 ECPGt_long_long
#define SQLSERIAL8 ECPGt_long_long
#else
#define SQLINT8 ECPGt_long
diff -U 5 -N -r -w ../orig.HEAD/src/interfaces/ecpg/test/expected/preproc-type.c ./src/interfaces/ecpg/test/expected/preproc-type.c
--- ../orig.HEAD/src/interfaces/ecpg/test/expected/preproc-type.c 2013-08-19 20:22:13.000000000 -0400
+++ ./src/interfaces/ecpg/test/expected/preproc-type.c 2013-08-19 20:54:00.000000000 -0400
@@ -81,10 +81,21 @@
+
+
+
+
+
+
+
+
+
+
+
#line 29 "type.pgc"
struct TBempl empl ;
#line 30 "type.pgc"
string str ;
@@ -98,48 +109,72 @@
int len ;
#line 35 "type.pgc"
char text [ 10 ] ;
} vc ;
+
+#line 41 "type.pgc"
+ struct nvarchar {
+#line 39 "type.pgc"
+ int len ;
+
+#line 40 "type.pgc"
+ char text [ 10 ] ;
+ } nvc ;
+
+#line 46 "type.pgc"
+ struct uvarchar {
+#line 44 "type.pgc"
+ int len ;
+
+#line 45 "type.pgc"
+ char text [ 20 ] ;
+ } uvc ;
/* exec sql end declare section */
-#line 37 "type.pgc"
+#line 48 "type.pgc"
/* exec sql var vc is [ 10 ] */
-#line 39 "type.pgc"
+#line 50 "type.pgc"
+
+ /* exec sql var nvc is [ 10 ] */
+#line 51 "type.pgc"
+
+ /* exec sql var uvc is [ 20 ] */
+#line 52 "type.pgc"
ECPGdebug (1, stderr);
empl.idnum = 1;
{ ECPGconnect(__LINE__, 0, "regress1" , NULL, NULL , NULL, 0); }
-#line 43 "type.pgc"
+#line 56 "type.pgc"
if (sqlca.sqlcode)
{
printf ("connect error = %ld\n", sqlca.sqlcode);
exit (sqlca.sqlcode);
}
- { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table empl ( idnum integer , name char ( 20 ) , accs smallint , string1 char ( 10 ) , string2 char ( 10 ) , string3 char ( 10 ) )", ECPGt_EOIT, ECPGt_EORT);}
-#line 51 "type.pgc"
+ { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table empl ( idnum integer , name char ( 20 ) , accs smallint , string1 char ( 10 ) , string2 char ( 10 ) , string3 char ( 10 ) , string4 char ( 10 ) , string5 char ( 10 ) )", ECPGt_EOIT, ECPGt_EORT);}
+#line 64 "type.pgc"
if (sqlca.sqlcode)
{
printf ("create error = %ld\n", sqlca.sqlcode);
exit (sqlca.sqlcode);
}
- { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into empl values ( 1 , 'user name' , 320 , 'first str' , 'second str' , 'third str' )", ECPGt_EOIT, ECPGt_EORT);}
-#line 58 "type.pgc"
+ { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into empl values ( 1 , 'user name' , 320 , 'first str' , 'second str' , 'third str' , 'fourth str' , 'fifth str' )", ECPGt_EOIT, ECPGt_EORT);}
+#line 71 "type.pgc"
if (sqlca.sqlcode)
{
printf ("insert error = %ld\n", sqlca.sqlcode);
exit (sqlca.sqlcode);
}
- { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select idnum , name , accs , string1 , string2 , string3 from empl where idnum = $1 ",
+ { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select idnum , name , accs , string1 , string2 , string3 , string4 , string5 from empl where idnum = $1 ",
ECPGt_long,&(empl.idnum),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
ECPGt_long,&(empl.idnum),(long)1,(long)1,sizeof(long),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,&(empl.name),(long)21,(long)1,(21)*sizeof(char),
@@ -149,22 +184,27 @@
ECPGt_char,(str),(long)11,(long)1,(11)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,&(ptr),(long)0,(long)1,(1)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_varchar,&(vc),(long)10,(long)1,sizeof(struct varchar),
+ ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
+ ECPGt_nvarchar,&(nvc),(long)10,(long)1,sizeof(struct varchar),
+ ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
+ ECPGt_uvarchar,&(uvc),(long)20,(long)1,sizeof(struct varchar),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
-#line 68 "type.pgc"
+#line 81 "type.pgc"
if (sqlca.sqlcode)
{
printf ("select error = %ld\n", sqlca.sqlcode);
exit (sqlca.sqlcode);
}
- printf ("id=%ld name='%s' accs=%d str='%s' ptr='%s' vc='%10.10s'\n", empl.idnum, empl.name, empl.accs, str, ptr, vc.text);
+ printf ("id=%ld name='%s' accs=%d str='%s' ptr='%s' vc='%10.10s' vc.len='%d' nvc='%10.10s' nvc.len='%d' uvc='%20.20s' uvc.len='%d'\n", empl.idnum, empl.name, empl.accs, str, ptr, vc.text, vc.len, nvc.text, nvc.len, uvc.text, uvc.len);
{ ECPGdisconnect(__LINE__, "CURRENT");}
-#line 76 "type.pgc"
+#line 89 "type.pgc"
free(ptr);
exit (0);
}
+
diff -U 5 -N -r -w ../orig.HEAD/src/interfaces/ecpg/test/expected/preproc-type.stderr ./src/interfaces/ecpg/test/expected/preproc-type.stderr
--- ../orig.HEAD/src/interfaces/ecpg/test/expected/preproc-type.stderr 2013-08-19 20:22:13.000000000 -0400
+++ ./src/interfaces/ecpg/test/expected/preproc-type.stderr 2013-08-19 20:54:00.000000000 -0400
@@ -1,40 +1,44 @@
[NO_PID]: ECPGdebug: set to 1
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ECPGconnect: opening database regress1 on <DEFAULT> port <DEFAULT>
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 50: query: create table empl ( idnum integer , name char ( 20 ) , accs smallint , string1 char ( 10 ) , string2 char ( 10 ) , string3 char ( 10 ) ); with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 63: query: create table empl ( idnum integer , name char ( 20 ) , accs smallint , string1 char ( 10 ) , string2 char ( 10 ) , string3 char ( 10 ) , string4 char ( 10 ) , string5 char ( 10 ) ); with 0 parameter(s) on connection regress1
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 50: using PQexec
+[NO_PID]: ecpg_execute on line 63: using PQexec
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 50: OK: CREATE TABLE
+[NO_PID]: ecpg_execute on line 63: OK: CREATE TABLE
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 58: query: insert into empl values ( 1 , 'user name' , 320 , 'first str' , 'second str' , 'third str' ); with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 71: query: insert into empl values ( 1 , 'user name' , 320 , 'first str' , 'second str' , 'third str' , 'fourth str' , 'fifth str' ); with 0 parameter(s) on connection regress1
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 58: using PQexec
+[NO_PID]: ecpg_execute on line 71: using PQexec
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 58: OK: INSERT 0 1
+[NO_PID]: ecpg_execute on line 71: OK: INSERT 0 1
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 65: query: select idnum , name , accs , string1 , string2 , string3 from empl where idnum = $1 ; with 1 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 78: query: select idnum , name , accs , string1 , string2 , string3 , string4 , string5 from empl where idnum = $1 ; with 1 parameter(s) on connection regress1
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 65: using PQexecParams
+[NO_PID]: ecpg_execute on line 78: using PQexecParams
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 65: parameter 1 = 1
+[NO_PID]: free_params on line 78: parameter 1 = 1
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 65: correctly got 1 tuples with 6 fields
+[NO_PID]: ecpg_execute on line 78: correctly got 1 tuples with 8 fields
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 65: RESULT: 1 offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 78: RESULT: 1 offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 65: RESULT: user name offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 78: RESULT: user name offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 65: RESULT: 320 offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 78: RESULT: 320 offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 65: RESULT: first str offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 78: RESULT: first str offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_store_result on line 65: allocating memory for 1 tuples
+[NO_PID]: ecpg_store_result on line 78: allocating memory for 1 tuples
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 65: RESULT: second str offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 78: RESULT: second str offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 65: RESULT: third str offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 78: RESULT: third str offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 78: RESULT: fourth str offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 78: RESULT: fifth str offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_finish: connection regress1 closed
[NO_PID]: sqlca: code: 0, state: 00000
diff -U 5 -N -r -w ../orig.HEAD/src/interfaces/ecpg/test/expected/preproc-type.stdout ./src/interfaces/ecpg/test/expected/preproc-type.stdout
--- ../orig.HEAD/src/interfaces/ecpg/test/expected/preproc-type.stdout 2013-08-19 20:22:13.000000000 -0400
+++ ./src/interfaces/ecpg/test/expected/preproc-type.stdout 2013-08-19 20:54:00.000000000 -0400
@@ -1 +1 @@
-id=1 name='user name ' accs=320 str='first str ' ptr='second str' vc='third str '
+id=1 name='user name ' accs=320 str='first str ' ptr='second str' vc='third str ' vc.len='10' nvc='fourth str' nvc.len='10' uvc=' f' uvc.len='20'
diff -U 5 -N -r -w ../orig.HEAD/src/interfaces/ecpg/test/expected/sql-fetch.c ./src/interfaces/ecpg/test/expected/sql-fetch.c
--- ../orig.HEAD/src/interfaces/ecpg/test/expected/sql-fetch.c 2013-08-19 20:22:13.000000000 -0400
+++ ./src/interfaces/ecpg/test/expected/sql-fetch.c 2013-08-19 20:54:00.000000000 -0400
@@ -25,210 +25,250 @@
int main() {
/* exec sql begin declare section */
+
+
+
+
#line 9 "fetch.pgc"
char str [ 25 ] ;
#line 10 "fetch.pgc"
int i , count = 1 ;
-/* exec sql end declare section */
+
#line 11 "fetch.pgc"
+ char nstr [ 25 ] ;
+
+#line 12 "fetch.pgc"
+ struct varchar_1 { int len; char arr[ 25 ]; } _varchar ;
+
+#line 13 "fetch.pgc"
+ struct varchar_2 { int len; char arr[ 25 ]; } _nvarchar ;
+
+#line 14 "fetch.pgc"
+ struct varchar_3 { int len; char arr[ 25 ]; } _uvarchar ;
+/* exec sql end declare section */
+#line 15 "fetch.pgc"
ECPGdebug(1, stderr);
{ ECPGconnect(__LINE__, 0, "regress1" , NULL, NULL , NULL, 0); }
-#line 14 "fetch.pgc"
+#line 18 "fetch.pgc"
/* exec sql whenever sql_warning sqlprint ; */
-#line 16 "fetch.pgc"
+#line 20 "fetch.pgc"
/* exec sql whenever sqlerror sqlprint ; */
-#line 17 "fetch.pgc"
+#line 21 "fetch.pgc"
- { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table My_Table ( Item1 int , Item2 text )", ECPGt_EOIT, ECPGt_EORT);
-#line 19 "fetch.pgc"
+ { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table My_Table ( Item1 int , Item2 text , Item3 text , Item4 varchar , Item5 varchar , Item6 varchar )", ECPGt_EOIT, ECPGt_EORT);
+#line 23 "fetch.pgc"
if (sqlca.sqlwarn[0] == 'W') sqlprint();
-#line 19 "fetch.pgc"
+#line 23 "fetch.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
-#line 19 "fetch.pgc"
+#line 23 "fetch.pgc"
- { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into My_Table values ( 1 , 'text1' )", ECPGt_EOIT, ECPGt_EORT);
-#line 21 "fetch.pgc"
+ { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into My_Table values ( 1 , 'text1' , 'text1' , 'text1' , 'text1' , 'text1' )", ECPGt_EOIT, ECPGt_EORT);
+#line 25 "fetch.pgc"
if (sqlca.sqlwarn[0] == 'W') sqlprint();
-#line 21 "fetch.pgc"
+#line 25 "fetch.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
-#line 21 "fetch.pgc"
+#line 25 "fetch.pgc"
- { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into My_Table values ( 2 , 'text2' )", ECPGt_EOIT, ECPGt_EORT);
-#line 22 "fetch.pgc"
+ { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into My_Table values ( 2 , 'text2' , 'text2' , 'text2' , 'text2' , 'text2' )", ECPGt_EOIT, ECPGt_EORT);
+#line 26 "fetch.pgc"
if (sqlca.sqlwarn[0] == 'W') sqlprint();
-#line 22 "fetch.pgc"
+#line 26 "fetch.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
-#line 22 "fetch.pgc"
+#line 26 "fetch.pgc"
- { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into My_Table values ( 3 , 'text3' )", ECPGt_EOIT, ECPGt_EORT);
-#line 23 "fetch.pgc"
+ { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into My_Table values ( 3 , 'text3' , 'text3' , 'text3' , 'text3' , 'text3' )", ECPGt_EOIT, ECPGt_EORT);
+#line 27 "fetch.pgc"
if (sqlca.sqlwarn[0] == 'W') sqlprint();
-#line 23 "fetch.pgc"
+#line 27 "fetch.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
-#line 23 "fetch.pgc"
+#line 27 "fetch.pgc"
- { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into My_Table values ( 4 , 'text4' )", ECPGt_EOIT, ECPGt_EORT);
-#line 24 "fetch.pgc"
+ { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into My_Table values ( 4 , 'text4' , 'text4' , 'text4' , 'text4' , 'text4' )", ECPGt_EOIT, ECPGt_EORT);
+#line 28 "fetch.pgc"
if (sqlca.sqlwarn[0] == 'W') sqlprint();
-#line 24 "fetch.pgc"
+#line 28 "fetch.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
-#line 24 "fetch.pgc"
+#line 28 "fetch.pgc"
/* declare C cursor for select * from My_Table */
-#line 26 "fetch.pgc"
+#line 30 "fetch.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare C cursor for select * from My_Table", ECPGt_EOIT, ECPGt_EORT);
-#line 28 "fetch.pgc"
+#line 32 "fetch.pgc"
if (sqlca.sqlwarn[0] == 'W') sqlprint();
-#line 28 "fetch.pgc"
+#line 32 "fetch.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
-#line 28 "fetch.pgc"
+#line 32 "fetch.pgc"
/* exec sql whenever not found break ; */
-#line 30 "fetch.pgc"
+#line 34 "fetch.pgc"
while (1) {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch 1 in C", ECPGt_EOIT,
ECPGt_int,&(i),(long)1,(long)1,sizeof(int),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(str),(long)25,(long)1,(25)*sizeof(char),
+ ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
+ ECPGt_nchar,(nstr),(long)25,(long)1,(25)*sizeof(char),
+ ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
+ ECPGt_varchar,&(_varchar),(long)25,(long)1,sizeof(struct varchar_1),
+ ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
+ ECPGt_nvarchar,&(_nvarchar),(long)25,(long)1,sizeof(struct varchar_2),
+ ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
+ ECPGt_uvarchar,&(_uvarchar),(long)25,(long)1,sizeof(struct varchar_3),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
-#line 32 "fetch.pgc"
+#line 36 "fetch.pgc"
if (sqlca.sqlcode == ECPG_NOT_FOUND) break;
-#line 32 "fetch.pgc"
+#line 36 "fetch.pgc"
if (sqlca.sqlwarn[0] == 'W') sqlprint();
-#line 32 "fetch.pgc"
+#line 36 "fetch.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
-#line 32 "fetch.pgc"
+#line 36 "fetch.pgc"
- printf("%d: %s\n", i, str);
+ printf("%d: %s, %s, %s, %s\n", i, str, nstr, _varchar.arr, _nvarchar.arr);
}
/* exec sql whenever not found continue ; */
-#line 36 "fetch.pgc"
+#line 40 "fetch.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "move backward 2 in C", ECPGt_EOIT, ECPGt_EORT);
-#line 37 "fetch.pgc"
+#line 41 "fetch.pgc"
if (sqlca.sqlwarn[0] == 'W') sqlprint();
-#line 37 "fetch.pgc"
+#line 41 "fetch.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
-#line 37 "fetch.pgc"
+#line 41 "fetch.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch $0 in C",
ECPGt_int,&(count),(long)1,(long)1,sizeof(int),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
ECPGt_int,&(i),(long)1,(long)1,sizeof(int),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(str),(long)25,(long)1,(25)*sizeof(char),
+ ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
+ ECPGt_nchar,(nstr),(long)25,(long)1,(25)*sizeof(char),
+ ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
+ ECPGt_varchar,&(_varchar),(long)25,(long)1,sizeof(struct varchar_1),
+ ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
+ ECPGt_nvarchar,&(_nvarchar),(long)25,(long)1,sizeof(struct varchar_2),
+ ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
+ ECPGt_uvarchar,&(_uvarchar),(long)25,(long)1,sizeof(struct varchar_3),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
-#line 39 "fetch.pgc"
+#line 43 "fetch.pgc"
if (sqlca.sqlwarn[0] == 'W') sqlprint();
-#line 39 "fetch.pgc"
+#line 43 "fetch.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
-#line 39 "fetch.pgc"
+#line 43 "fetch.pgc"
- printf("%d: %s\n", i, str);
+ printf("%d: %s, %s, %s, %s\n", i, str, nstr, _varchar.arr, _nvarchar.arr);
/* declare D cursor for select * from My_Table where Item1 = $1 */
-#line 42 "fetch.pgc"
+#line 46 "fetch.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare D cursor for select * from My_Table where Item1 = $1",
ECPGt_const,"1",(long)1,(long)1,strlen("1"),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
-#line 44 "fetch.pgc"
+#line 48 "fetch.pgc"
if (sqlca.sqlwarn[0] == 'W') sqlprint();
-#line 44 "fetch.pgc"
+#line 48 "fetch.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
-#line 44 "fetch.pgc"
+#line 48 "fetch.pgc"
/* exec sql whenever not found break ; */
-#line 46 "fetch.pgc"
+#line 50 "fetch.pgc"
while (1) {
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch 1 in D", ECPGt_EOIT,
ECPGt_int,&(i),(long)1,(long)1,sizeof(int),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_char,(str),(long)25,(long)1,(25)*sizeof(char),
+ ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
+ ECPGt_nchar,(nstr),(long)25,(long)1,(25)*sizeof(char),
+ ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
+ ECPGt_varchar,&(_varchar),(long)25,(long)1,sizeof(struct varchar_1),
+ ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
+ ECPGt_nvarchar,&(_nvarchar),(long)25,(long)1,sizeof(struct varchar_2),
+ ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
+ ECPGt_uvarchar,&(_uvarchar),(long)25,(long)1,sizeof(struct varchar_3),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
-#line 48 "fetch.pgc"
+#line 52 "fetch.pgc"
if (sqlca.sqlcode == ECPG_NOT_FOUND) break;
-#line 48 "fetch.pgc"
+#line 52 "fetch.pgc"
if (sqlca.sqlwarn[0] == 'W') sqlprint();
-#line 48 "fetch.pgc"
+#line 52 "fetch.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
-#line 48 "fetch.pgc"
+#line 52 "fetch.pgc"
- printf("%d: %s\n", i, str);
+ printf("%d: %s, %s, %s, %s\n", i, str, nstr, _varchar.arr, _nvarchar.arr);
}
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close D", ECPGt_EOIT, ECPGt_EORT);
-#line 51 "fetch.pgc"
+#line 55 "fetch.pgc"
if (sqlca.sqlwarn[0] == 'W') sqlprint();
-#line 51 "fetch.pgc"
+#line 55 "fetch.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
-#line 51 "fetch.pgc"
+#line 55 "fetch.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table My_Table", ECPGt_EOIT, ECPGt_EORT);
-#line 53 "fetch.pgc"
+#line 57 "fetch.pgc"
if (sqlca.sqlwarn[0] == 'W') sqlprint();
-#line 53 "fetch.pgc"
+#line 57 "fetch.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
-#line 53 "fetch.pgc"
+#line 57 "fetch.pgc"
{ ECPGdisconnect(__LINE__, "ALL");
-#line 55 "fetch.pgc"
+#line 59 "fetch.pgc"
if (sqlca.sqlwarn[0] == 'W') sqlprint();
-#line 55 "fetch.pgc"
+#line 59 "fetch.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
-#line 55 "fetch.pgc"
+#line 59 "fetch.pgc"
return 0;
}
diff -U 5 -N -r -w ../orig.HEAD/src/interfaces/ecpg/test/expected/sql-fetch.stderr ./src/interfaces/ecpg/test/expected/sql-fetch.stderr
--- ../orig.HEAD/src/interfaces/ecpg/test/expected/sql-fetch.stderr 2013-08-19 20:22:13.000000000 -0400
+++ ./src/interfaces/ecpg/test/expected/sql-fetch.stderr 2013-08-19 20:54:00.000000000 -0400
@@ -1,147 +1,195 @@
[NO_PID]: ECPGdebug: set to 1
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ECPGconnect: opening database regress1 on <DEFAULT> port <DEFAULT>
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 19: query: create table My_Table ( Item1 int , Item2 text ); with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 23: query: create table My_Table ( Item1 int , Item2 text , Item3 text , Item4 varchar , Item5 varchar , Item6 varchar ); with 0 parameter(s) on connection regress1
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 19: using PQexec
+[NO_PID]: ecpg_execute on line 23: using PQexec
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 19: OK: CREATE TABLE
+[NO_PID]: ecpg_execute on line 23: OK: CREATE TABLE
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 21: query: insert into My_Table values ( 1 , 'text1' ); with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 25: query: insert into My_Table values ( 1 , 'text1' , 'text1' , 'text1' , 'text1' , 'text1' ); with 0 parameter(s) on connection regress1
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 21: using PQexec
+[NO_PID]: ecpg_execute on line 25: using PQexec
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 21: OK: INSERT 0 1
+[NO_PID]: ecpg_execute on line 25: OK: INSERT 0 1
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 22: query: insert into My_Table values ( 2 , 'text2' ); with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 26: query: insert into My_Table values ( 2 , 'text2' , 'text2' , 'text2' , 'text2' , 'text2' ); with 0 parameter(s) on connection regress1
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 22: using PQexec
+[NO_PID]: ecpg_execute on line 26: using PQexec
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 22: OK: INSERT 0 1
+[NO_PID]: ecpg_execute on line 26: OK: INSERT 0 1
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 23: query: insert into My_Table values ( 3 , 'text3' ); with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 27: query: insert into My_Table values ( 3 , 'text3' , 'text3' , 'text3' , 'text3' , 'text3' ); with 0 parameter(s) on connection regress1
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 23: using PQexec
+[NO_PID]: ecpg_execute on line 27: using PQexec
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 23: OK: INSERT 0 1
+[NO_PID]: ecpg_execute on line 27: OK: INSERT 0 1
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 24: query: insert into My_Table values ( 4 , 'text4' ); with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 28: query: insert into My_Table values ( 4 , 'text4' , 'text4' , 'text4' , 'text4' , 'text4' ); with 0 parameter(s) on connection regress1
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 24: using PQexec
+[NO_PID]: ecpg_execute on line 28: using PQexec
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 24: OK: INSERT 0 1
+[NO_PID]: ecpg_execute on line 28: OK: INSERT 0 1
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 28: query: declare C cursor for select * from My_Table; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 32: query: declare C cursor for select * from My_Table; with 0 parameter(s) on connection regress1
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 28: using PQexec
+[NO_PID]: ecpg_execute on line 32: using PQexec
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 28: OK: DECLARE CURSOR
+[NO_PID]: ecpg_execute on line 32: OK: DECLARE CURSOR
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 32: query: fetch 1 in C; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 36: query: fetch 1 in C; with 0 parameter(s) on connection regress1
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 32: using PQexec
+[NO_PID]: ecpg_execute on line 36: using PQexec
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 32: correctly got 1 tuples with 2 fields
+[NO_PID]: ecpg_execute on line 36: correctly got 1 tuples with 6 fields
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 32: RESULT: 1 offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 36: RESULT: 1 offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 32: RESULT: text1 offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 36: RESULT: text1 offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 32: query: fetch 1 in C; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_get_data on line 36: RESULT: text1 offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 32: using PQexec
+[NO_PID]: ecpg_get_data on line 36: RESULT: text1 offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 32: correctly got 1 tuples with 2 fields
+[NO_PID]: ecpg_get_data on line 36: RESULT: text1 offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 32: RESULT: 2 offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 36: RESULT: text1 offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 32: RESULT: text2 offset: -1; array: no
+[NO_PID]: ecpg_execute on line 36: query: fetch 1 in C; with 0 parameter(s) on connection regress1
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 32: query: fetch 1 in C; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 36: using PQexec
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 32: using PQexec
+[NO_PID]: ecpg_execute on line 36: correctly got 1 tuples with 6 fields
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 32: correctly got 1 tuples with 2 fields
+[NO_PID]: ecpg_get_data on line 36: RESULT: 2 offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 32: RESULT: 3 offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 36: RESULT: text2 offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 32: RESULT: text3 offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 36: RESULT: text2 offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 32: query: fetch 1 in C; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_get_data on line 36: RESULT: text2 offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 32: using PQexec
+[NO_PID]: ecpg_get_data on line 36: RESULT: text2 offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 32: correctly got 1 tuples with 2 fields
+[NO_PID]: ecpg_get_data on line 36: RESULT: text2 offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 32: RESULT: 4 offset: -1; array: no
+[NO_PID]: ecpg_execute on line 36: query: fetch 1 in C; with 0 parameter(s) on connection regress1
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 32: RESULT: text4 offset: -1; array: no
+[NO_PID]: ecpg_execute on line 36: using PQexec
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 32: query: fetch 1 in C; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 36: correctly got 1 tuples with 6 fields
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 32: using PQexec
+[NO_PID]: ecpg_get_data on line 36: RESULT: 3 offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 36: RESULT: text3 offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 36: RESULT: text3 offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 36: RESULT: text3 offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 36: RESULT: text3 offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 36: RESULT: text3 offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 36: query: fetch 1 in C; with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 36: using PQexec
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 32: correctly got 0 tuples with 2 fields
+[NO_PID]: ecpg_execute on line 36: correctly got 1 tuples with 6 fields
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: raising sqlcode 100 on line 32: no data found on line 32
+[NO_PID]: ecpg_get_data on line 36: RESULT: 4 offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 36: RESULT: text4 offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 36: RESULT: text4 offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 36: RESULT: text4 offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 36: RESULT: text4 offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 36: RESULT: text4 offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 36: query: fetch 1 in C; with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 36: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 36: correctly got 0 tuples with 6 fields
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: raising sqlcode 100 on line 36: no data found on line 36
[NO_PID]: sqlca: code: 100, state: 02000
-[NO_PID]: ecpg_execute on line 37: query: move backward 2 in C; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 41: query: move backward 2 in C; with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 41: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 41: OK: MOVE 2
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 43: query: fetch 1 in C; with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 43: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 43: correctly got 1 tuples with 6 fields
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 43: RESULT: 4 offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 43: RESULT: text4 offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 43: RESULT: text4 offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 37: using PQexec
+[NO_PID]: ecpg_get_data on line 43: RESULT: text4 offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 37: OK: MOVE 2
+[NO_PID]: ecpg_get_data on line 43: RESULT: text4 offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 39: query: fetch 1 in C; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_get_data on line 43: RESULT: text4 offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 39: using PQexec
+[NO_PID]: ecpg_execute on line 48: query: declare D cursor for select * from My_Table where Item1 = $1; with 1 parameter(s) on connection regress1
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 39: correctly got 1 tuples with 2 fields
+[NO_PID]: ecpg_execute on line 48: using PQexecParams
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 39: RESULT: 4 offset: -1; array: no
+[NO_PID]: free_params on line 48: parameter 1 = 1
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 39: RESULT: text4 offset: -1; array: no
+[NO_PID]: ecpg_execute on line 48: OK: DECLARE CURSOR
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 44: query: declare D cursor for select * from My_Table where Item1 = $1; with 1 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 52: query: fetch 1 in D; with 0 parameter(s) on connection regress1
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 44: using PQexecParams
+[NO_PID]: ecpg_execute on line 52: using PQexec
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 44: parameter 1 = 1
+[NO_PID]: ecpg_execute on line 52: correctly got 1 tuples with 6 fields
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 44: OK: DECLARE CURSOR
+[NO_PID]: ecpg_get_data on line 52: RESULT: 1 offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 48: query: fetch 1 in D; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_get_data on line 52: RESULT: text1 offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 48: using PQexec
+[NO_PID]: ecpg_get_data on line 52: RESULT: text1 offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 48: correctly got 1 tuples with 2 fields
+[NO_PID]: ecpg_get_data on line 52: RESULT: text1 offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 48: RESULT: 1 offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 52: RESULT: text1 offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 48: RESULT: text1 offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 52: RESULT: text1 offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 48: query: fetch 1 in D; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 52: query: fetch 1 in D; with 0 parameter(s) on connection regress1
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 48: using PQexec
+[NO_PID]: ecpg_execute on line 52: using PQexec
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 48: correctly got 0 tuples with 2 fields
+[NO_PID]: ecpg_execute on line 52: correctly got 0 tuples with 6 fields
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: raising sqlcode 100 on line 48: no data found on line 48
+[NO_PID]: raising sqlcode 100 on line 52: no data found on line 52
[NO_PID]: sqlca: code: 100, state: 02000
-[NO_PID]: ecpg_execute on line 51: query: close D; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 55: query: close D; with 0 parameter(s) on connection regress1
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 51: using PQexec
+[NO_PID]: ecpg_execute on line 55: using PQexec
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 51: OK: CLOSE CURSOR
+[NO_PID]: ecpg_execute on line 55: OK: CLOSE CURSOR
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 53: query: drop table My_Table; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 57: query: drop table My_Table; with 0 parameter(s) on connection regress1
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 53: using PQexec
+[NO_PID]: ecpg_execute on line 57: using PQexec
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_check_PQresult on line 53: bad response - ERROR: cannot DROP TABLE "my_table" because it is being used by active queries in this session
+[NO_PID]: ecpg_check_PQresult on line 57: bad response - ERROR: cannot DROP TABLE "my_table" because it is being used by active queries in this session
[NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: raising sqlstate 55006 (sqlcode -400): cannot DROP TABLE "my_table" because it is being used by active queries in this session on line 53
+[NO_PID]: raising sqlstate 55006 (sqlcode -400): cannot DROP TABLE "my_table" because it is being used by active queries in this session on line 57
[NO_PID]: sqlca: code: -400, state: 55006
-SQL error: cannot DROP TABLE "my_table" because it is being used by active queries in this session on line 53
+SQL error: cannot DROP TABLE "my_table" because it is being used by active queries in this session on line 57
[NO_PID]: ecpg_finish: connection regress1 closed
[NO_PID]: sqlca: code: 0, state: 00000
diff -U 5 -N -r -w ../orig.HEAD/src/interfaces/ecpg/test/expected/sql-fetch.stdout ./src/interfaces/ecpg/test/expected/sql-fetch.stdout
--- ../orig.HEAD/src/interfaces/ecpg/test/expected/sql-fetch.stdout 2013-08-19 20:22:13.000000000 -0400
+++ ./src/interfaces/ecpg/test/expected/sql-fetch.stdout 2013-08-19 20:54:00.000000000 -0400
@@ -1,6 +1,6 @@
-1: text1
-2: text2
-3: text3
-4: text4
-4: text4
-1: text1
+1: text1, text1, text1, text1
+2: text2, text2, text2, text2
+3: text3, text3, text3, text3
+4: text4, text4, text4, text4
+4: text4, text4, text4, text4
+1: text1, text1, text1, text1
diff -U 5 -N -r -w ../orig.HEAD/src/interfaces/ecpg/test/preproc/type.pgc ./src/interfaces/ecpg/test/preproc/type.pgc
--- ../orig.HEAD/src/interfaces/ecpg/test/preproc/type.pgc 2013-08-19 20:22:13.000000000 -0400
+++ ./src/interfaces/ecpg/test/preproc/type.pgc 2013-08-19 20:54:00.000000000 -0400
@@ -32,13 +32,26 @@
struct varchar
{
int len;
char text[10];
} vc;
+ struct nvarchar
+ {
+ int len;
+ char text[10];
+ } nvc;
+ struct uvarchar
+ {
+ int len;
+ char text[20];
+ } uvc;
+
EXEC SQL END DECLARE SECTION;
EXEC SQL var vc is varchar[10];
+ EXEC SQL var nvc is nvarchar[10];
+ EXEC SQL var uvc is uvarchar[20];
ECPGdebug (1, stderr);
empl.idnum = 1;
EXEC SQL connect to REGRESSDB1;
if (sqlca.sqlcode)
@@ -46,35 +59,36 @@
printf ("connect error = %ld\n", sqlca.sqlcode);
exit (sqlca.sqlcode);
}
EXEC SQL create table empl
- (idnum integer, name char(20), accs smallint, string1 char(10), string2 char(10), string3 char(10));
+ (idnum integer, name char(20), accs smallint, string1 char(10), string2 char(10), string3 char(10), string4 char(10), string5 char(10));
if (sqlca.sqlcode)
{
printf ("create error = %ld\n", sqlca.sqlcode);
exit (sqlca.sqlcode);
}
- EXEC SQL insert into empl values (1, 'user name', 320, 'first str', 'second str', 'third str');
+ EXEC SQL insert into empl values (1, 'user name', 320, 'first str', 'second str', 'third str', 'fourth str', 'fifth str');
if (sqlca.sqlcode)
{
printf ("insert error = %ld\n", sqlca.sqlcode);
exit (sqlca.sqlcode);
}
- EXEC SQL select idnum, name, accs, string1, string2, string3
- into :empl, :str, :ptr, :vc
+ EXEC SQL select idnum, name, accs, string1, string2, string3, string4, string5
+ into :empl, :str, :ptr, :vc, :nvc, :uvc
from empl
where idnum =:empl.idnum;
if (sqlca.sqlcode)
{
printf ("select error = %ld\n", sqlca.sqlcode);
exit (sqlca.sqlcode);
}
- printf ("id=%ld name='%s' accs=%d str='%s' ptr='%s' vc='%10.10s'\n", empl.idnum, empl.name, empl.accs, str, ptr, vc.text);
+ printf ("id=%ld name='%s' accs=%d str='%s' ptr='%s' vc='%10.10s' vc.len='%d' nvc='%10.10s' nvc.len='%d' uvc='%20.20s' uvc.len='%d'\n", empl.idnum, empl.name, empl.accs, str, ptr, vc.text, vc.len, nvc.text, nvc.len, uvc.text, uvc.len);
EXEC SQL disconnect;
free(ptr);
exit (0);
}
+
diff -U 5 -N -r -w ../orig.HEAD/src/interfaces/ecpg/test/sql/fetch.pgc ./src/interfaces/ecpg/test/sql/fetch.pgc
--- ../orig.HEAD/src/interfaces/ecpg/test/sql/fetch.pgc 2013-08-19 20:22:13.000000000 -0400
+++ ./src/interfaces/ecpg/test/sql/fetch.pgc 2013-08-19 20:54:00.000000000 -0400
@@ -6,49 +6,53 @@
int main() {
EXEC SQL BEGIN DECLARE SECTION;
char str[25];
int i, count=1;
+ NCHAR nstr[25];
+ VARCHAR _varchar[25];
+ NVARCHAR _nvarchar[25];
+ UVARCHAR _uvarchar[25];
EXEC SQL END DECLARE SECTION;
ECPGdebug(1, stderr);
EXEC SQL CONNECT TO REGRESSDB1;
EXEC SQL WHENEVER SQLWARNING SQLPRINT;
EXEC SQL WHENEVER SQLERROR SQLPRINT;
- EXEC SQL CREATE TABLE My_Table ( Item1 int, Item2 text );
+ EXEC SQL CREATE TABLE My_Table ( Item1 int, Item2 text, Item3 text, Item4 varchar, Item5 varchar, Item6 varchar );
- EXEC SQL INSERT INTO My_Table VALUES ( 1, 'text1');
- EXEC SQL INSERT INTO My_Table VALUES ( 2, 'text2');
- EXEC SQL INSERT INTO My_Table VALUES ( 3, 'text3');
- EXEC SQL INSERT INTO My_Table VALUES ( 4, 'text4');
+ EXEC SQL INSERT INTO My_Table VALUES ( 1, 'text1', 'text1', 'text1', 'text1', 'text1');
+ EXEC SQL INSERT INTO My_Table VALUES ( 2, 'text2', 'text2', 'text2', 'text2', 'text2');
+ EXEC SQL INSERT INTO My_Table VALUES ( 3, 'text3', 'text3', 'text3', 'text3', 'text3');
+ EXEC SQL INSERT INTO My_Table VALUES ( 4, 'text4', 'text4', 'text4', 'text4', 'text4');
EXEC SQL DECLARE C CURSOR FOR SELECT * FROM My_Table;
EXEC SQL OPEN C;
EXEC SQL WHENEVER NOT FOUND DO BREAK;
while (1) {
- EXEC SQL FETCH 1 IN C INTO :i, :str;
- printf("%d: %s\n", i, str);
+ EXEC SQL FETCH 1 IN C INTO :i, :str, :nstr, :_varchar, :_nvarchar, :_uvarchar;
+ printf("%d: %s, %s, %s, %s\n", i, str, nstr, _varchar.arr, _nvarchar.arr);
}
EXEC SQL WHENEVER NOT FOUND CONTINUE;
EXEC SQL MOVE BACKWARD 2 IN C;
- EXEC SQL FETCH :count IN C INTO :i, :str;
- printf("%d: %s\n", i, str);
+ EXEC SQL FETCH :count IN C INTO :i, :str, :nstr, :_varchar, :_nvarchar, :_uvarchar;
+ printf("%d: %s, %s, %s, %s\n", i, str, nstr, _varchar.arr, _nvarchar.arr);
EXEC SQL DECLARE D CURSOR FOR SELECT * FROM My_Table WHERE Item1 = $1;
EXEC SQL OPEN D using 1;
EXEC SQL WHENEVER NOT FOUND DO BREAK;
while (1) {
- EXEC SQL FETCH 1 IN D INTO :i, :str;
- printf("%d: %s\n", i, str);
+ EXEC SQL FETCH 1 IN D INTO :i, :str, :nstr, :_varchar, :_nvarchar, :_uvarchar;
+ printf("%d: %s, %s, %s, %s\n", i, str, nstr, _varchar.arr, _nvarchar.arr);
}
EXEC SQL CLOSE D;
EXEC SQL DROP TABLE My_Table;
diff -U 5 -N -r -w ../orig.HEAD/src/test/regress/expected/create_function_3.out ./src/test/regress/expected/create_function_3.out
--- ../orig.HEAD/src/test/regress/expected/create_function_3.out 2013-08-19 20:22:14.000000000 -0400
+++ ./src/test/regress/expected/create_function_3.out 2013-08-19 20:54:00.000000000 -0400
@@ -306,10 +306,12 @@
namege | boolean | [0:1]={name,name}
namegt | boolean | [0:1]={name,name}
namele | boolean | [0:1]={name,name}
namelt | boolean | [0:1]={name,name}
namene | boolean | [0:1]={name,name}
+ nbpchareq | boolean | [0:1]={"national character","national character"}
+ nbpcharne | boolean | [0:1]={"national character","national character"}
network_eq | boolean | [0:1]={inet,inet}
network_ge | boolean | [0:1]={inet,inet}
network_gt | boolean | [0:1]={inet,inet}
network_le | boolean | [0:1]={inet,inet}
network_lt | boolean | [0:1]={inet,inet}
@@ -381,11 +383,11 @@
varbitgt | boolean | [0:1]={"bit varying","bit varying"}
varbitle | boolean | [0:1]={"bit varying","bit varying"}
varbitlt | boolean | [0:1]={"bit varying","bit varying"}
varbitne | boolean | [0:1]={"bit varying","bit varying"}
xideq | boolean | [0:1]={xid,xid}
-(228 rows)
+(230 rows)
--
-- CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT
--
CREATE FUNCTION functext_F_1(int) RETURNS bool LANGUAGE 'sql'
diff -U 5 -N -r -w ../orig.HEAD/src/test/regress/expected/nchar.out ./src/test/regress/expected/nchar.out
--- ../orig.HEAD/src/test/regress/expected/nchar.out 1969-12-31 19:00:00.000000000 -0500
+++ ./src/test/regress/expected/nchar.out 2013-08-19 23:31:45.000000000 -0400
@@ -0,0 +1,122 @@
+--
+-- NCHAR
+--
+-- fixed-length by value
+-- internally passed by value if <= 4 bytes in storage
+SELECT nchar 'c' = nchar 'c' AS true;
+ true
+------
+ t
+(1 row)
+
+--
+-- Build a table for testing
+--
+CREATE TABLE NCHAR_TBL(f1 nchar);
+INSERT INTO NCHAR_TBL (f1) VALUES ('a');
+INSERT INTO NCHAR_TBL (f1) VALUES ('A');
+-- any of the following three input formats are acceptable
+INSERT INTO NCHAR_TBL (f1) VALUES ('1');
+INSERT INTO NCHAR_TBL (f1) VALUES (2);
+INSERT INTO NCHAR_TBL (f1) VALUES ('3');
+-- zero-length nchar
+INSERT INTO NCHAR_TBL (f1) VALUES ('');
+-- try nchar's of greater than 1 length
+INSERT INTO NCHAR_TBL (f1) VALUES ('cd');
+ERROR: value too long for type character(1)
+INSERT INTO NCHAR_TBL (f1) VALUES ('c ');
+SELECT '' AS seven, * FROM NCHAR_TBL;
+ seven | f1
+-------+----
+ | a
+ | A
+ | 1
+ | 2
+ | 3
+ |
+ | c
+(7 rows)
+
+SELECT '' AS six, c.*
+ FROM NCHAR_TBL c
+ WHERE c.f1 <> 'a';
+ six | f1
+-----+----
+ | A
+ | 1
+ | 2
+ | 3
+ |
+ | c
+(6 rows)
+
+SELECT '' AS one, c.*
+ FROM NCHAR_TBL c
+ WHERE c.f1 = 'a';
+ one | f1
+-----+----
+ | a
+(1 row)
+
+SELECT '' AS five, c.*
+ FROM NCHAR_TBL c
+ WHERE c.f1 < 'a';
+ five | f1
+------+----
+ | A
+ | 1
+ | 2
+ | 3
+ |
+(5 rows)
+
+SELECT '' AS six, c.*
+ FROM NCHAR_TBL c
+ WHERE c.f1 <= 'a';
+ six | f1
+-----+----
+ | a
+ | A
+ | 1
+ | 2
+ | 3
+ |
+(6 rows)
+
+SELECT '' AS one, c.*
+ FROM NCHAR_TBL c
+ WHERE c.f1 > 'a';
+ one | f1
+-----+----
+ | c
+(1 row)
+
+SELECT '' AS two, c.*
+ FROM NCHAR_TBL c
+ WHERE c.f1 >= 'a';
+ two | f1
+-----+----
+ | a
+ | c
+(2 rows)
+
+DROP TABLE NCHAR_TBL;
+--
+-- Now test longer arrays of nchar
+--
+CREATE TABLE NCHAR_TBL(f1 nchar(4));
+INSERT INTO NCHAR_TBL (f1) VALUES ('a');
+INSERT INTO NCHAR_TBL (f1) VALUES ('ab');
+INSERT INTO NCHAR_TBL (f1) VALUES ('abcd');
+INSERT INTO NCHAR_TBL (f1) VALUES ('abcde');
+ERROR: value too long for type character(4)
+INSERT INTO NCHAR_TBL (f1) VALUES ('abcd ');
+SELECT '' AS four, * FROM NCHAR_TBL;
+ four | f1
+------+------
+ | a
+ | ab
+ | abcd
+ | abcd
+(4 rows)
+
diff -U 5 -N -r -w ../orig.HEAD/src/test/regress/expected/nvarchar_1.out ./src/test/regress/expected/nvarchar_1.out
--- ../orig.HEAD/src/test/regress/expected/nvarchar_1.out 1969-12-31 19:00:00.000000000 -0500
+++ ./src/test/regress/expected/nvarchar_1.out 2013-08-19 23:31:50.000000000 -0400
@@ -0,0 +1,111 @@
+--
+-- NVARCHAR
+--
+CREATE TABLE NVARCHAR_TBL(f1 nvarchar(1));
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('a');
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('A');
+-- any of the following three input formats are acceptable
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('1');
+INSERT INTO NVARCHAR_TBL (f1) VALUES (2);
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('3');
+-- zero-length nchar
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('');
+-- try nvarchar's of greater than 1 length
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('cd');
+ERROR: value too long for type character varying(1)
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('c ');
+SELECT '' AS seven, * FROM NVARCHAR_TBL;
+ seven | f1
+-------+----
+ | a
+ | A
+ | 1
+ | 2
+ | 3
+ |
+ | c
+(7 rows)
+
+SELECT '' AS six, c.*
+ FROM NVARCHAR_TBL c
+ WHERE c.f1 <> 'a';
+ six | f1
+-----+----
+ | A
+ | 1
+ | 2
+ | 3
+ |
+ | c
+(6 rows)
+
+SELECT '' AS one, c.*
+ FROM NVARCHAR_TBL c
+ WHERE c.f1 = 'a';
+ one | f1
+-----+----
+ | a
+(1 row)
+
+SELECT '' AS five, c.*
+ FROM NVARCHAR_TBL c
+ WHERE c.f1 < 'a';
+ five | f1
+------+----
+ | 1
+ | 2
+ | 3
+ |
+(4 rows)
+
+SELECT '' AS six, c.*
+ FROM NVARCHAR_TBL c
+ WHERE c.f1 <= 'a';
+ six | f1
+-----+----
+ | a
+ | 1
+ | 2
+ | 3
+ |
+(5 rows)
+
+SELECT '' AS one, c.*
+ FROM NVARCHAR_TBL c
+ WHERE c.f1 > 'a';
+ one | f1
+-----+----
+ | A
+ | c
+(2 rows)
+
+SELECT '' AS two, c.*
+ FROM NVARCHAR_TBL c
+ WHERE c.f1 >= 'a';
+ two | f1
+-----+----
+ | a
+ | A
+ | c
+(3 rows)
+
+DROP TABLE NVARCHAR_TBL;
+--
+-- Now test longer arrays of nchar
+--
+CREATE TABLE NVARCHAR_TBL(f1 nvarchar(4));
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('a');
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('ab');
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('abcd');
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('abcde');
+ERROR: value too long for type character varying(4)
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('abcd ');
+SELECT '' AS four, * FROM NVARCHAR_TBL;
+ four | f1
+------+------
+ | a
+ | ab
+ | abcd
+ | abcd
+(4 rows)
+
diff -U 5 -N -r -w ../orig.HEAD/src/test/regress/expected/nvarchar_2.out ./src/test/regress/expected/nvarchar_2.out
--- ../orig.HEAD/src/test/regress/expected/nvarchar_2.out 1969-12-31 19:00:00.000000000 -0500
+++ ./src/test/regress/expected/nvarchar_2.out 2013-08-19 23:31:50.000000000 -0400
@@ -0,0 +1,111 @@
+--
+-- NVARCHAR
+--
+CREATE TABLE NVARCHAR_TBL(f1 nvarchar(1));
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('a');
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('A');
+-- any of the following three input formats are acceptable
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('1');
+INSERT INTO NVARCHAR_TBL (f1) VALUES (2);
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('3');
+-- zero-length nchar
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('');
+-- try nvarchar's of greater than 1 length
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('cd');
+ERROR: value too long for type character varying(1)
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('c ');
+SELECT '' AS seven, * FROM NVARCHAR_TBL;
+ seven | f1
+-------+----
+ | a
+ | A
+ | 1
+ | 2
+ | 3
+ |
+ | c
+(7 rows)
+
+SELECT '' AS six, c.*
+ FROM NVARCHAR_TBL c
+ WHERE c.f1 <> 'a';
+ six | f1
+-----+----
+ | A
+ | 1
+ | 2
+ | 3
+ |
+ | c
+(6 rows)
+
+SELECT '' AS one, c.*
+ FROM NVARCHAR_TBL c
+ WHERE c.f1 = 'a';
+ one | f1
+-----+----
+ | a
+(1 row)
+
+SELECT '' AS five, c.*
+ FROM NVARCHAR_TBL c
+ WHERE c.f1 < 'a';
+ five | f1
+------+----
+ |
+(1 row)
+
+SELECT '' AS six, c.*
+ FROM NVARCHAR_TBL c
+ WHERE c.f1 <= 'a';
+ six | f1
+-----+----
+ | a
+ |
+(2 rows)
+
+SELECT '' AS one, c.*
+ FROM NVARCHAR_TBL c
+ WHERE c.f1 > 'a';
+ one | f1
+-----+----
+ | A
+ | 1
+ | 2
+ | 3
+ | c
+(5 rows)
+
+SELECT '' AS two, c.*
+ FROM NVARCHAR_TBL c
+ WHERE c.f1 >= 'a';
+ two | f1
+-----+----
+ | a
+ | A
+ | 1
+ | 2
+ | 3
+ | c
+(6 rows)
+
+DROP TABLE NVARCHAR_TBL;
+--
+-- Now test longer arrays of nchar
+--
+CREATE TABLE NVARCHAR_TBL(f1 nvarchar(4));
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('a');
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('ab');
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('abcd');
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('abcde');
+ERROR: value too long for type character varying(4)
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('abcd ');
+SELECT '' AS four, * FROM NVARCHAR_TBL;
+ four | f1
+------+------
+ | a
+ | ab
+ | abcd
+ | abcd
+(4 rows)
+
diff -U 5 -N -r -w ../orig.HEAD/src/test/regress/expected/nvarchar_alter.out ./src/test/regress/expected/nvarchar_alter.out
--- ../orig.HEAD/src/test/regress/expected/nvarchar_alter.out 1969-12-31 19:00:00.000000000 -0500
+++ ./src/test/regress/expected/nvarchar_alter.out 2013-08-19 23:31:50.000000000 -0400
@@ -0,0 +1,138 @@
+--create table
+create table nchar_test (f1 nchar(10) default N'a', f2 nvarchar(10) default N'b');
+--values
+values (N'abc各国語');
+ column1
+-----------
+ abc各国語
+(1 row)
+
+--analyze
+analyze nchar_test(f1);
+analyze nchar_test(f2);
+--vacuum analyze
+vacuum analyze nchar_test(f1);
+vacuum analyze nchar_test(f2);
+--broken
+--set application_name to N'abc各国語';
+--select
+select f1,f2,N'abc各国語' from nchar_test;
+ f1 | f2 | nvarchar
+----+----+----------
+(0 rows)
+
+--select into
+select f1,f2,N'abc各国語' into nchar_test1 from nchar_test;
+--revoke per column not supported
+--grant per column not supported
+--insert into/returning
+insert into nchar_test1 select f1,f2,N'abc各国語' from nchar_test returning f1,f2,nvarchar,N'abc各国語';
+ f1 | f2 | nvarchar | nvarchar
+----+----+----------+----------
+(0 rows)
+
+--explain
+explain select f1,f2,N'abc各国語' from nchar_test;
+ QUERY PLAN
+--------------------------------------------------------------
+ Seq Scan on nchar_test (cost=0.00..17.70 rows=770 width=76)
+(1 row)
+
+--do
+do $$begin perform f1,f2,N'abc各国語' from nchar_test; end $$;
+--delete
+delete from nchar_test where f1=N'abc各国語' and f2=N'abc各国語';
+--create view
+create view v as select f1,f2,N'abc各国語' from nchar_test;
+--create index
+create index i2 on nchar_test(f2);
+create index i3 on nchar_test((f1||'abc各国語'));
+create index i1 on nchar_test(f1);
+--comment
+comment on COLUMN nchar_test.f1 is 'f1';
+comment on COLUMN nchar_test.f2 is 'f2';
+comment on type nvarchar is 'nvarchar';
+--analyze
+analyze nchar_test(f1);
+--copy
+copy nchar_test(f1, f2) to stdout;
+--alter view
+alter view v alter column f1 set default N'abc各国語';
+alter view v alter column f2 set default N'abc各国語';
+--alter table
+alter table nchar_test1 rename f1 to f3;
+alter table nchar_test1 rename f2 to f4;
+alter table nchar_test1 alter f3 type nchar(10);
+alter table nchar_test1 alter f4 type nvarchar;
+alter table nchar_test1 alter f3 set default N'abc各国語';
+alter table nchar_test1 alter f4 set default N'abc各国語';
+--declare cursor
+begin;declare qqq cursor for select f1,f2,N'abc各国語' from nchar_test;commit;
+--create trigger
+create trigger tr before update on nchar_test for each row when (OLD.f1=N'abc各国語') EXECUTE PROCEDURE suppress_redundant_updates_trigger();
+--foreign key
+alter table nchar_test1 add CONSTRAINT nchar_test1_pk primary key(f3);
+NOTICE: ALTER TABLE / ADD PRIMARY KEY will create implicit index "nchar_test1_pk" for table "nchar_test1"
+alter table nchar_test add CONSTRAINT qqqq FOREIGN KEY (f1) references nchar_test1(f3);
+--update
+update nchar_test set f1=N'abc各国語', f2='abc各国語';
+select * from nchar_test1;
+ f3 | f4 | nvarchar
+----+----+----------
+(0 rows)
+
+create domain test_nchar_domain as nchar(10) default (N'a') CHECK (value <> N'b');
+create domain test_nvarchar_domain as nvarchar(10) default (N'a') CHECK (value <> N'b');
+alter domain test_nchar_domain set default (N'b');
+alter domain test_nvarchar_domain set default (N'b');
+DROP DOMAIN test_nchar_domain;
+DROP DOMAIN test_nvarchar_domain;
+CREATE AGGREGATE test_nvarchar_agg (nvarchar) ( sfunc = array_append, stype = nvarchar[], initcond = '{}');
+CREATE AGGREGATE test_nchar_agg (nchar(10)) ( sfunc = array_append, stype = nchar(10)[], initcond = '{}');
+alter aggregate test_nvarchar_agg(nvarchar) rename to test_nvarchar_aggregate;
+alter aggregate test_nchar_agg (nchar(10)) rename to test_nchar_aggregate;
+drop aggregate test_nvarchar_aggregate(nvarchar);
+drop aggregate test_nchar_aggregate(nchar(10));
+CREATE TYPE test_nchar_type AS (f1 nchar(10));
+CREATE TYPE test_nvarchar_type AS (f1 nvarchar);
+drop type test_nchar_type;
+drop type test_nvarchar_type;
+drop view v;
+drop table nchar_test;
+drop table nchar_test1;
+create table nchar_test (f1 nchar(10), f2 nvarchar(10));
+select f1, f2, N'a' from nchar_test where f1=N'a' and f2=N'b';
+ f1 | f2 | nvarchar
+----+----+----------
+(0 rows)
+
+insert into nchar_test values (N'a', N'b') returning (f1, f2, N'c');
+ row
+--------------------
+ ("a ",b,c)
+(1 row)
+
+select f1, f2, N'a' into nchar_test1 from nchar_test;
+select * from nchar_test1;
+ f1 | f2 | nvarchar
+------------+----+----------
+ a | b | a
+(1 row)
+
+prepare qqq(nchar(10), nvarchar(10)) AS select f1, f2, N'a' from nchar_test where f1=N'a' and f2=N'b';
+execute qqq(N'a', N'b');
+ f1 | f2 | nvarchar
+------------+----+----------
+ a | b | a
+(1 row)
+
+explain select f1, f2, N'a' from nchar_test where f1=N'a' and f2=N'b';
+ QUERY PLAN
+--------------------------------------------------------------
+ Seq Scan on nchar_test (cost=0.00..21.55 rows=1 width=76)
+ Filter: ((f1 = 'a'::nbpchar) AND ((f2)::text = 'b'::text))
+(2 rows)
+
+delete from nchar_test1 where f1=N'a' and f2=N'b';
+drop table nchar_test;
+drop table nchar_test1;
diff -U 5 -N -r -w ../orig.HEAD/src/test/regress/expected/nvarchar_func.out ./src/test/regress/expected/nvarchar_func.out
--- ../orig.HEAD/src/test/regress/expected/nvarchar_func.out 1969-12-31 19:00:00.000000000 -0500
+++ ./src/test/regress/expected/nvarchar_func.out 2013-08-19 23:31:50.000000000 -0400
@@ -0,0 +1,258 @@
+SELECT N'各国' || N'文字';
+ ?column?
+----------
+ 各国文字
+(1 row)
+
+SELECT N'各国' || 42;
+ ?column?
+----------
+ 各国42
+(1 row)
+
+SELECT bit_length(N'各国');
+ bit_length
+------------
+ 48
+(1 row)
+
+SELECT char_length(N'各国');
+ char_length
+-------------
+ 2
+(1 row)
+
+SELECT lower(N'各国TOM');
+ lower
+---------
+ 各国tom
+(1 row)
+
+SELECT octet_length(N'各国');
+ octet_length
+--------------
+ 6
+(1 row)
+
+SELECT overlay(N'各XX' placing N'文字' from 2 for 3);
+ overlay
+---------
+ 各文字
+(1 row)
+
+SELECT position(N'文' in N'各国文字');
+ position
+----------
+ 3
+(1 row)
+
+SELECT substring(N'各国文字' from 3 for 3);
+ substring
+-----------
+ 文字
+(1 row)
+
+SELECT substring(N'各国文字列' from N'...$');
+ substring
+-----------
+ 文字列
+(1 row)
+
+SELECT substring(N'各国文字列国' from '%#"文_列#"_' for '#');
+ substring
+-----------
+ 文字列
+(1 row)
+
+SELECT trim(both N'X' from N'X各国文字XX');
+ btrim
+----------
+ 各国文字
+(1 row)
+
+SELECT upper(N'各国tom');
+ upper
+---------
+ 各国TOM
+(1 row)
+
+SELECT ascii(N'数');
+ ascii
+-------
+ 25968
+(1 row)
+
+SELECT btrim(N'XY各国X', N'XY');
+ btrim
+-------
+ 各国
+(1 row)
+
+SELECT chr(25968);
+ chr
+-----
+ 数
+(1 row)
+
+SELECT concat(N'各', N'国', NULL, N'語');
+ concat
+--------
+ 各国語
+(1 row)
+
+SELECT concat_ws(N'_', N'各国', NULL, N'文字');
+ concat_ws
+------------
+ 各国_文字
+(1 row)
+
+-- convert_to(N'各国', 'SJIS') = '\x8a658d91'
+-- convert_to(N'各国', 'UTF8') = '\xe59084e59bbd'
+SELECT convert('\x8a658d91'::bytea, 'SJIS', 'UTF8');
+ convert
+----------------
+ \xe59084e59bbd
+(1 row)
+
+-- N'各国'::bytea = '\xe59084e59bbd'
+SELECT convert_from('\xe59084e59bbd'::bytea, 'UTF8');
+ convert_from
+--------------
+ 各国
+(1 row)
+
+-- '\xe59084e59bbd'::bytea = N'各国'
+SELECT convert_to(N'各国', 'UTF8');
+ convert_to
+----------------
+ \xe59084e59bbd
+(1 row)
+
+SELECT format('各国 %s, %1$s', N'文字');
+ format
+-----------------
+ 各国 文字, 文字
+(1 row)
+
+SELECT initcap(N'hi 各国');
+ initcap
+---------
+ Hi 各国
+(1 row)
+
+SELECT left(N'各国文字', 2);
+ left
+------
+ 各国
+(1 row)
+
+SELECT length(N'各国文字');
+ length
+--------
+ 4
+(1 row)
+
+-- N'各国文字'::bytea = '\xe59084e59bbde69687e5ad97'
+SELECT length('\xe59084e59bbde69687e5ad97'::bytea , 'UTF8');
+ length
+--------
+ 4
+(1 row)
+
+SELECT lpad(N'文字', 3, N'各国');
+ lpad
+--------
+ 各文字
+(1 row)
+
+SELECT ltrim(N'◯×各国', N'◯×');
+ ltrim
+-------
+ 各国
+(1 row)
+
+SELECT regexp_matches(N'各国文字データ', N'(文字)(データ)');
+ regexp_matches
+----------------
+ {文字,データ}
+(1 row)
+
+SELECT regexp_replace(N'各国x文字', '.[a-z]文.', N'語');
+ regexp_replace
+----------------
+ 各語
+(1 row)
+
+SELECT regexp_split_to_array(N'各国 文字列', E'\\s+');
+ regexp_split_to_array
+-----------------------
+ {各国,文字列}
+(1 row)
+
+SELECT regexp_split_to_table(N'各国 文字列', E'\\s+');
+ regexp_split_to_table
+-----------------------
+ 各国
+ 文字列
+(2 rows)
+
+SELECT repeat(N'文字', 4);
+ repeat
+------------------
+ 文字文字文字文字
+(1 row)
+
+SELECT replace(N'各国文字国', N'国', N'語');
+ replace
+------------
+ 各語文字語
+(1 row)
+
+SELECT reverse(N'各国語');
+ reverse
+---------
+ 語国各
+(1 row)
+
+SELECT right(N'各国語', 2);
+ right
+-------
+ 国語
+(1 row)
+
+SELECT rpad(N'各国', 3, N'語');
+ rpad
+--------
+ 各国語
+(1 row)
+
+SELECT rtrim(N'◯各国◯◯', N'◯');
+ rtrim
+-------
+ ◯各国
+(1 row)
+
+SELECT split_part(N'各国◯語◯文字', N'◯', 3);
+ split_part
+------------
+ 文字
+(1 row)
+
+SELECT strpos(N'各国語', N'語');
+ strpos
+--------
+ 3
+(1 row)
+
+SELECT substr(N'各国語', 3, 3);
+ substr
+--------
+ 語
+(1 row)
+
+SELECT translate(N'各国文字', N'各字', N'◯×');
+ translate
+-----------
+ ◯国文×
+(1 row)
+
diff -U 5 -N -r -w ../orig.HEAD/src/test/regress/expected/nvarchar_misc.out ./src/test/regress/expected/nvarchar_misc.out
--- ../orig.HEAD/src/test/regress/expected/nvarchar_misc.out 1969-12-31 19:00:00.000000000 -0500
+++ ./src/test/regress/expected/nvarchar_misc.out 2013-08-19 23:31:50.000000000 -0400
@@ -0,0 +1,126 @@
+select N'a '=N'a';
+ ?column?
+----------
+ f
+(1 row)
+
+select N'a '='a';
+ ?column?
+----------
+ f
+(1 row)
+
+select N'a'='a';
+ ?column?
+----------
+ t
+(1 row)
+
+select N'a '='a'::char(1);
+ ?column?
+----------
+ t
+(1 row)
+
+select N'a '='a'::nchar(1);
+ ?column?
+----------
+ t
+(1 row)
+
+select N'a '='a'::varchar(1);
+ ?column?
+----------
+ f
+(1 row)
+
+select N'a '='a'::nvarchar(1);
+ ?column?
+----------
+ f
+(1 row)
+
+select N'a'='a'::nvarchar(1);
+ ?column?
+----------
+ t
+(1 row)
+
+select N'a'='a'::varchar(1);
+ ?column?
+----------
+ t
+(1 row)
+
+select N'a'='a'::char(1);
+ ?column?
+----------
+ t
+(1 row)
+
+select N'a'='a'::nchar(1);
+ ?column?
+----------
+ t
+(1 row)
+
+select 'a'::nchar(10)='a'::char(1);
+ ?column?
+----------
+ t
+(1 row)
+
+select 'a'::nchar(10)='a'::nchar(1);
+ ?column?
+----------
+ t
+(1 row)
+
+select 'a'::nchar(10)='a'::varchar(1);
+ ?column?
+----------
+ t
+(1 row)
+
+select 'a'::nchar(10)='a'::nvarchar(1);
+ ?column?
+----------
+ t
+(1 row)
+
+select 'a'::nvarchar(10)='a'::varchar(1);
+ ?column?
+----------
+ t
+(1 row)
+
+select 'a'::nvarchar(10)='a'::varchar(10);
+ ?column?
+----------
+ t
+(1 row)
+
+select 'a'::nvarchar(10)='a '::varchar(10);
+ ?column?
+----------
+ f
+(1 row)
+
+select 'a'::nvarchar(10)='a '::char(10);
+ ?column?
+----------
+ t
+(1 row)
+
+select 'a '::nchar(10)='a '::nchar(5);
+ ?column?
+----------
+ t
+(1 row)
+
+select 'a '::nchar(10)='a '::char(5);
+ ?column?
+----------
+ t
+(1 row)
+
diff -U 5 -N -r -w ../orig.HEAD/src/test/regress/expected/nvarchar.out ./src/test/regress/expected/nvarchar.out
--- ../orig.HEAD/src/test/regress/expected/nvarchar.out 1969-12-31 19:00:00.000000000 -0500
+++ ./src/test/regress/expected/nvarchar.out 2013-08-19 23:31:50.000000000 -0400
@@ -0,0 +1,111 @@
+--
+-- NVARCHAR
+--
+CREATE TABLE NVARCHAR_TBL(f1 nvarchar(1));
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('a');
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('A');
+-- any of the following three input formats are acceptable
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('1');
+INSERT INTO NVARCHAR_TBL (f1) VALUES (2);
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('3');
+-- zero-length char
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('');
+-- try nvarchar's of greater than 1 length
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('cd');
+ERROR: value too long for type character varying(1)
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('c ');
+SELECT '' AS seven, * FROM NVARCHAR_TBL;
+ seven | f1
+-------+----
+ | a
+ | A
+ | 1
+ | 2
+ | 3
+ |
+ | c
+(7 rows)
+
+SELECT '' AS six, c.*
+ FROM NVARCHAR_TBL c
+ WHERE c.f1 <> 'a';
+ six | f1
+-----+----
+ | A
+ | 1
+ | 2
+ | 3
+ |
+ | c
+(6 rows)
+
+SELECT '' AS one, c.*
+ FROM NVARCHAR_TBL c
+ WHERE c.f1 = 'a';
+ one | f1
+-----+----
+ | a
+(1 row)
+
+SELECT '' AS five, c.*
+ FROM NVARCHAR_TBL c
+ WHERE c.f1 < 'a';
+ five | f1
+------+----
+ | A
+ | 1
+ | 2
+ | 3
+ |
+(5 rows)
+
+SELECT '' AS six, c.*
+ FROM NVARCHAR_TBL c
+ WHERE c.f1 <= 'a';
+ six | f1
+-----+----
+ | a
+ | A
+ | 1
+ | 2
+ | 3
+ |
+(6 rows)
+
+SELECT '' AS one, c.*
+ FROM NVARCHAR_TBL c
+ WHERE c.f1 > 'a';
+ one | f1
+-----+----
+ | c
+(1 row)
+
+SELECT '' AS two, c.*
+ FROM NVARCHAR_TBL c
+ WHERE c.f1 >= 'a';
+ two | f1
+-----+----
+ | a
+ | c
+(2 rows)
+
+DROP TABLE NVARCHAR_TBL;
+--
+-- Now test longer arrays of char
+--
+CREATE TABLE NVARCHAR_TBL(f1 nvarchar(4));
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('a');
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('ab');
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('abcd');
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('abcde');
+ERROR: value too long for type character varying(4)
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('abcd ');
+SELECT '' AS four, * FROM NVARCHAR_TBL;
+ four | f1
+------+------
+ | a
+ | ab
+ | abcd
+ | abcd
+(4 rows)
+
diff -U 5 -N -r -w ../orig.HEAD/src/test/regress/expected/opr_sanity.out ./src/test/regress/expected/opr_sanity.out
--- ../orig.HEAD/src/test/regress/expected/opr_sanity.out 2013-08-19 20:22:14.000000000 -0400
+++ ./src/test/regress/expected/opr_sanity.out 2013-08-19 20:54:00.000000000 -0400
@@ -152,12 +152,15 @@
(p1.prorettype < p2.prorettype)
ORDER BY 1, 2;
prorettype | prorettype
------------+------------
25 | 1043
+ 25 | 6001
+ 1042 | 5001
+ 1043 | 6001
1114 | 1184
-(2 rows)
+(5 rows)
SELECT DISTINCT p1.proargtypes[0], p2.proargtypes[0]
FROM pg_proc AS p1, pg_proc AS p2
WHERE p1.oid != p2.oid AND
p1.prosrc = p2.prosrc AND
@@ -169,14 +172,18 @@
ORDER BY 1, 2;
proargtypes | proargtypes
-------------+-------------
25 | 1042
25 | 1043
+ 25 | 5001
+ 25 | 6001
+ 1042 | 5001
+ 1043 | 6001
1114 | 1184
1560 | 1562
2277 | 2283
-(5 rows)
+(9 rows)
SELECT DISTINCT p1.proargtypes[1], p2.proargtypes[1]
FROM pg_proc AS p1, pg_proc AS p2
WHERE p1.oid != p2.oid AND
p1.prosrc = p2.prosrc AND
@@ -187,14 +194,15 @@
(p1.proargtypes[1] < p2.proargtypes[1])
ORDER BY 1, 2;
proargtypes | proargtypes
-------------+-------------
23 | 28
+ 1042 | 5001
1114 | 1184
1560 | 1562
2277 | 2283
-(4 rows)
+(5 rows)
SELECT DISTINCT p1.proargtypes[2], p2.proargtypes[2]
FROM pg_proc AS p1, pg_proc AS p2
WHERE p1.oid != p2.oid AND
p1.prosrc = p2.prosrc AND
@@ -433,19 +441,23 @@
NOT EXISTS (SELECT 1 FROM pg_cast k
WHERE k.castmethod = 'b' AND
k.castsource = c.casttarget AND
k.casttarget = c.castsource);
castsource | casttarget | castfunc | castcontext
--------------------+-------------------+----------+-------------
- text | character | 0 | i
+----------------------------+--------------------+----------+-------------
+ national character varying | character | 0 | i
+ national character varying | national character | 0 | i
character varying | character | 0 | i
+ character varying | national character | 0 | i
+ text | character | 0 | i
+ text | national character | 0 | i
pg_node_tree | text | 0 | i
cidr | inet | 0 | i
xml | text | 0 | a
xml | character varying | 0 | a
xml | character | 0 | a
-(7 rows)
+(11 rows)
-- **************** pg_operator ****************
-- Look for illegal values in pg_operator fields.
SELECT p1.oid, p1.oprname
FROM pg_operator as p1
@@ -1211,11 +1223,13 @@
p3.amoplefttype = p1.amoplefttype AND
p3.amoprighttype = p2.amoplefttype AND
p3.amopstrategy = 1);
amoplefttype | amoplefttype
--------------+--------------
-(0 rows)
+ 1042 | 5001
+ 5001 | 1042
+(2 rows)
-- **************** pg_amproc ****************
-- Look for illegal values in pg_amproc fields
SELECT p1.amprocfamily, p1.amprocnum
FROM pg_amproc as p1
@@ -1273,12 +1287,14 @@
WHERE am.amname = 'btree' OR am.amname = 'gist' OR am.amname = 'gin'
GROUP BY amname, amsupport, opcname, amprocfamily
HAVING (count(*) != amsupport AND count(*) != amsupport - 1)
OR amprocfamily IS NULL;
amname | opcname | count
---------+---------+-------
-(0 rows)
+--------+---------------+-------
+ gin | _nbpchar_ops | 1
+ gin | _nvarchar_ops | 1
+(2 rows)
-- Unfortunately, we can't check the amproc link very well because the
-- signature of the function may be different for different support routines
-- or different base data types.
-- We can check that all the referenced instances of the same support
@@ -1316,12 +1332,14 @@
WHEN amprocnum = 2
THEN prorettype != 'void'::regtype OR proretset OR pronargs != 1
OR proargtypes[0] != 'internal'::regtype
ELSE true END);
amprocfamily | amprocnum | oid | proname | opfname
---------------+-----------+-----+---------+---------
-(0 rows)
+--------------+-----------+------+----------------------+--------------------
+ 426 | 1 | 1078 | bpcharcmp | bpchar_ops
+ 2097 | 1 | 2180 | btbpchar_pattern_cmp | bpchar_pattern_ops
+(2 rows)
-- For hash we can also do a little better: the support routines must be
-- of the form hash(lefttype) returns int4. There are several cases where
-- we cheat and use a hash function that is physically compatible with the
-- datatype even though there's no cast, so this check does find a small
diff -U 5 -N -r -w ../orig.HEAD/src/test/regress/expected/sanity_check.out ./src/test/regress/expected/sanity_check.out
--- ../orig.HEAD/src/test/regress/expected/sanity_check.out 2013-08-19 20:22:15.000000000 -0400
+++ ./src/test/regress/expected/sanity_check.out 2013-08-19 20:54:00.000000000 -0400
@@ -66,10 +66,11 @@
kd_point_tbl | t
log_table | f
lseg_tbl | f
main_table | f
money_data | f
+ nchar_tbl | f
num_data | f
num_exp_add | t
num_exp_div | t
num_exp_ln | t
num_exp_log10 | t
@@ -77,10 +78,11 @@
num_exp_power_10_ln | t
num_exp_sqrt | t
num_exp_sub | t
num_input_test | f
num_result | f
+ nvarchar_tbl | f
onek | t
onek2 | t
path_tbl | f
person | f
pg_aggregate | t
diff -U 5 -N -r -w ../orig.HEAD/src/test/regress/expected/strings.out ./src/test/regress/expected/strings.out
--- ../orig.HEAD/src/test/regress/expected/strings.out 2013-08-19 20:22:15.000000000 -0400
+++ ./src/test/regress/expected/strings.out 2013-08-19 20:54:00.000000000 -0400
@@ -201,19 +201,37 @@
ab
abcd
abcd
(4 rows)
+SELECT CAST(f1 AS text) AS "text(nchar)" FROM NCHAR_TBL;
+ text(nchar)
+-------------
+ a
+ ab
+ abcd
+ abcd
+(4 rows)
+
SELECT CAST(f1 AS text) AS "text(varchar)" FROM VARCHAR_TBL;
text(varchar)
---------------
a
ab
abcd
abcd
(4 rows)
+SELECT CAST(f1 AS text) AS "text(nvarchar)" FROM NVARCHAR_TBL;
+ text(nvarchar)
+----------------
+ a
+ ab
+ abcd
+ abcd
+(4 rows)
+
SELECT CAST(name 'namefield' AS text) AS "text(name)";
text(name)
------------
namefield
(1 row)
@@ -225,54 +243,106 @@
doh!
hi de ho n
(2 rows)
-- note: implicit-cast case is tested in char.sql
+SELECT CAST(f1 AS nchar(10)) AS "nchar(text)" FROM TEXT_TBL;
+ nchar(text)
+-------------
+ doh!
+ hi de ho n
+(2 rows)
+
+-- note: implicit-cast case is tested in nchar.sql
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 nchar(20)) AS "nchar(text)" FROM TEXT_TBL;
+ nchar(text)
+----------------------
+ doh!
+ hi de ho neighbor
+(2 rows)
+
SELECT CAST(f1 AS char(10)) AS "char(varchar)" FROM VARCHAR_TBL;
char(varchar)
---------------
a
ab
abcd
abcd
(4 rows)
+SELECT CAST(f1 AS nchar(10)) AS "nchar(nvarchar)" FROM NVARCHAR_TBL;
+ nchar(nvarchar)
+-----------------
+ a
+ ab
+ abcd
+ abcd
+(4 rows)
+
SELECT CAST(name 'namefield' AS char(10)) AS "char(name)";
char(name)
------------
namefield
(1 row)
+SELECT CAST(name 'namefield' AS nchar(10)) AS "nchar(name)";
+ nchar(name)
+-------------
+ namefield
+(1 row)
+
SELECT CAST(f1 AS varchar) AS "varchar(text)" FROM TEXT_TBL;
varchar(text)
-------------------
doh!
hi de ho neighbor
(2 rows)
+SELECT CAST(f1 AS nvarchar) AS "nvarchar(text)" FROM TEXT_TBL;
+ nvarchar(text)
+-------------------
+ doh!
+ hi de ho neighbor
+(2 rows)
+
SELECT CAST(f1 AS varchar) AS "varchar(char)" FROM CHAR_TBL;
varchar(char)
---------------
a
ab
abcd
abcd
(4 rows)
+SELECT CAST(f1 AS nvarchar) AS "nvarchar(nchar)" FROM NCHAR_TBL;
+ nvarchar(nchar)
+-----------------
+ a
+ ab
+ abcd
+ abcd
+(4 rows)
+
SELECT CAST(name 'namefield' AS varchar) AS "varchar(name)";
varchar(name)
---------------
namefield
(1 row)
+SELECT CAST(name 'namefield' AS nvarchar) AS "nvarchar(name)";
+ nvarchar(name)
+----------------
+ namefield
+(1 row)
+
--
-- test SQL string functions
-- E### and T### are feature reference numbers from SQL99
--
-- E021-09 trim function
@@ -1103,22 +1173,40 @@
Concat char to unknown type
-----------------------------
characters and text
(1 row)
+SELECT nchar(20) 'ncharacters' || ' and text' AS "Concat nchar to unknown type";
+ Concat nchar to unknown type
+------------------------------
+ ncharacters and text
+(1 row)
+
SELECT text 'text' || char(20) ' and characters' AS "Concat text to char";
Concat text to char
---------------------
text and characters
(1 row)
+SELECT text 'text' || nchar(20) ' and ncharacters' AS "Concat text to nchar";
+ Concat text to nchar
+----------------------
+ text and ncharacters
+(1 row)
+
SELECT text 'text' || varchar ' and varchar' AS "Concat text to varchar";
Concat text to varchar
------------------------
text and varchar
(1 row)
+SELECT text 'text' || nvarchar ' and nvarchar' AS "Concat text to nvarchar";
+ Concat text to nvarchar
+-------------------------
+ text and nvarchar
+(1 row)
+
--
-- test substr with toasted text values
--
CREATE TABLE toasttest(f1 text);
insert into toasttest values(repeat('1234567890',10000));
diff -U 5 -N -r -w ../orig.HEAD/src/test/regress/expected/union.out ./src/test/regress/expected/union.out
--- ../orig.HEAD/src/test/regress/expected/union.out 2013-08-19 20:22:15.000000000 -0400
+++ ./src/test/regress/expected/union.out 2013-08-19 20:54:00.000000000 -0400
@@ -255,10 +255,52 @@
abcd
doh!
hi de ho neighbor
(5 rows)
+--NVARCHAR specific
+SELECT f1 AS three FROM NVARCHAR_TBL
+UNION
+SELECT CAST(f1 AS nvarchar) FROM NCHAR_TBL
+ORDER BY 1;
+ three
+-------
+ a
+ ab
+ abcd
+(3 rows)
+
+SELECT f1 AS eight FROM NVARCHAR_TBL
+UNION ALL
+SELECT f1 FROM NCHAR_TBL;
+ eight
+-------
+ a
+ ab
+ abcd
+ abcd
+ a
+ ab
+ abcd
+ abcd
+(8 rows)
+
+SELECT f1 AS five FROM TEXT_TBL
+UNION
+SELECT f1 FROM NVARCHAR_TBL
+UNION
+SELECT TRIM(TRAILING FROM f1) FROM NCHAR_TBL
+ORDER BY 1;
+ five
+-------------------
+ a
+ ab
+ abcd
+ doh!
+ hi de ho neighbor
+(5 rows)
+
--
-- INTERSECT and EXCEPT
--
SELECT q2 FROM int8_tbl INTERSECT SELECT q1 FROM int8_tbl;
q2
diff -U 5 -N -r -w ../orig.HEAD/src/test/regress/expected/update.out ./src/test/regress/expected/update.out
--- ../orig.HEAD/src/test/regress/expected/update.out 2013-08-19 20:22:15.000000000 -0400
+++ ./src/test/regress/expected/update.out 2013-08-19 20:54:00.000000000 -0400
@@ -2,75 +2,101 @@
-- UPDATE syntax tests
--
CREATE TABLE update_test (
a INT DEFAULT 10,
b INT,
- c TEXT
+ c TEXT,
+ d nchar(10),
+ e nvarchar
);
-INSERT INTO update_test VALUES (5, 10, 'foo');
+INSERT INTO update_test VALUES (5, 10, 'foo', 'a', 'a');
INSERT INTO update_test(b, a) VALUES (15, 10);
SELECT * FROM update_test;
- a | b | c
-----+----+-----
- 5 | 10 | foo
- 10 | 15 |
+ a | b | c | d | e
+----+----+-----+------------+---
+ 5 | 10 | foo | a | a
+ 10 | 15 | | |
+(2 rows)
+
+UPDATE update_test SET d='b', e='b';
+SELECT * FROM update_test;
+ a | b | c | d | e
+----+----+-----+------------+---
+ 5 | 10 | foo | b | b
+ 10 | 15 | | b | b
+(2 rows)
+
+UPDATE update_test SET d='c' where e='b';
+SELECT * FROM update_test;
+ a | b | c | d | e
+----+----+-----+------------+---
+ 5 | 10 | foo | c | b
+ 10 | 15 | | c | b
+(2 rows)
+
+UPDATE update_test SET d=N'e' where e=N'b';
+SELECT * FROM update_test;
+ a | b | c | d | e
+----+----+-----+------------+---
+ 5 | 10 | foo | e | b
+ 10 | 15 | | e | b
(2 rows)
UPDATE update_test SET a = DEFAULT, b = DEFAULT;
SELECT * FROM update_test;
- a | b | c
-----+---+-----
- 10 | | foo
- 10 | |
+ a | b | c | d | e
+----+---+-----+------------+---
+ 10 | | foo | e | b
+ 10 | | | e | b
(2 rows)
-- aliases for the UPDATE target table
UPDATE update_test AS t SET b = 10 WHERE t.a = 10;
SELECT * FROM update_test;
- a | b | c
-----+----+-----
- 10 | 10 | foo
- 10 | 10 |
+ a | b | c | d | e
+----+----+-----+------------+---
+ 10 | 10 | foo | e | b
+ 10 | 10 | | e | b
(2 rows)
UPDATE update_test t SET b = t.b + 10 WHERE t.a = 10;
SELECT * FROM update_test;
- a | b | c
-----+----+-----
- 10 | 20 | foo
- 10 | 20 |
+ a | b | c | d | e
+----+----+-----+------------+---
+ 10 | 20 | foo | e | b
+ 10 | 20 | | e | b
(2 rows)
--
-- Test VALUES in FROM
--
UPDATE update_test SET a=v.i FROM (VALUES(100, 20)) AS v(i, j)
WHERE update_test.b = v.j;
SELECT * FROM update_test;
- a | b | c
------+----+-----
- 100 | 20 | foo
- 100 | 20 |
+ a | b | c | d | e
+-----+----+-----+------------+---
+ 100 | 20 | foo | e | b
+ 100 | 20 | | e | b
(2 rows)
--
-- Test multiple-set-clause syntax
--
UPDATE update_test SET (c,b,a) = ('bugle', b+11, DEFAULT) WHERE c = 'foo';
SELECT * FROM update_test;
- a | b | c
------+----+-------
- 100 | 20 |
- 10 | 31 | bugle
+ a | b | c | d | e
+-----+----+-------+------------+---
+ 100 | 20 | | e | b
+ 10 | 31 | bugle | e | b
(2 rows)
UPDATE update_test SET (c,b) = ('car', a+b), a = a + 1 WHERE a = 10;
SELECT * FROM update_test;
- a | b | c
------+----+-----
- 100 | 20 |
- 11 | 41 | car
+ a | b | c | d | e
+-----+----+-----+------------+---
+ 100 | 20 | | e | b
+ 11 | 41 | car | e | b
(2 rows)
-- fail, multi assignment to same column:
UPDATE update_test SET (c,b) = ('car', a+b), b = a + 1 WHERE a = 10;
ERROR: multiple assignments to same column "b"
diff -U 5 -N -r -w ../orig.HEAD/src/test/regress/output/misc.source ./src/test/regress/output/misc.source
--- ../orig.HEAD/src/test/regress/output/misc.source 2013-08-19 20:22:15.000000000 -0400
+++ ./src/test/regress/output/misc.source 2013-08-19 20:54:00.000000000 -0400
@@ -39,32 +39,32 @@
-- SET age = age + 3
-- WHERE name = 'linda';
--
-- copy
--
-COPY onek TO '@abs_builddir@/results/onek.data';
+COPY onek TO '/home/mboguk/postgres/build_test/src/test/regress/results/onek.data';
DELETE FROM onek;
-COPY onek FROM '@abs_builddir@/results/onek.data';
+COPY onek FROM '/home/mboguk/postgres/build_test/src/test/regress/results/onek.data';
SELECT unique1 FROM onek WHERE unique1 < 2 ORDER BY unique1;
unique1
---------
0
1
(2 rows)
DELETE FROM onek2;
-COPY onek2 FROM '@abs_builddir@/results/onek.data';
+COPY onek2 FROM '/home/mboguk/postgres/build_test/src/test/regress/results/onek.data';
SELECT unique1 FROM onek2 WHERE unique1 < 2 ORDER BY unique1;
unique1
---------
0
1
(2 rows)
-COPY BINARY stud_emp TO '@abs_builddir@/results/stud_emp.data';
+COPY BINARY stud_emp TO '/home/mboguk/postgres/build_test/src/test/regress/results/stud_emp.data';
DELETE FROM stud_emp;
-COPY BINARY stud_emp FROM '@abs_builddir@/results/stud_emp.data';
+COPY BINARY stud_emp FROM '/home/mboguk/postgres/build_test/src/test/regress/results/stud_emp.data';
SELECT * FROM stud_emp;
name | age | location | salary | manager | gpa | percent
-------+-----+------------+--------+---------+-----+---------
jeff | 23 | (8,7.7) | 600 | sharon | 3.5 |
cim | 30 | (10.5,4.7) | 400 | | 3.4 |
@@ -640,10 +640,11 @@
kd_point_tbl
log_table
lseg_tbl
main_table
money_data
+ nchar_tbl
num_data
num_exp_add
num_exp_div
num_exp_ln
num_exp_log10
@@ -651,10 +652,11 @@
num_exp_power_10_ln
num_exp_sqrt
num_exp_sub
num_input_test
num_result
+ nvarchar_tbl
onek
onek2
path_tbl
person
point_tbl
diff -U 5 -N -r -w ../orig.HEAD/src/test/regress/parallel_schedule ./src/test/regress/parallel_schedule
--- ../orig.HEAD/src/test/regress/parallel_schedule 2013-08-19 20:22:15.000000000 -0400
+++ ./src/test/regress/parallel_schedule 2013-08-19 20:54:00.000000000 -0400
@@ -11,11 +11,11 @@
test: tablespace
# ----------
# The first group of parallel tests
# ----------
-test: boolean char name varchar text int2 int4 int8 oid float4 float8 bit numeric txid uuid enum money rangetypes
+test: boolean char name varchar nchar nvarchar text int2 int4 int8 oid float4 float8 bit numeric txid uuid enum money rangetypes nvarchar_func nvarchar_alter nvarchar_misc
# Depends on things setup during char, varchar and text
test: strings
# Depends on int2, int4, int8, float4, float8
test: numerology
diff -U 5 -N -r -w ../orig.HEAD/src/test/regress/serial_schedule ./src/test/regress/serial_schedule
--- ../orig.HEAD/src/test/regress/serial_schedule 2013-08-19 20:22:15.000000000 -0400
+++ ./src/test/regress/serial_schedule 2013-08-19 20:54:00.000000000 -0400
@@ -3,10 +3,15 @@
test: tablespace
test: boolean
test: char
test: name
test: varchar
+test: nvarchar
+test: nvarchar_alter
+test: nvarchar_func
+test: nvarchar_misc
+test: nchar
test: text
test: int2
test: int4
test: int8
test: oid
diff -U 5 -N -r -w ../orig.HEAD/src/test/regress/sql/nchar.sql ./src/test/regress/sql/nchar.sql
--- ../orig.HEAD/src/test/regress/sql/nchar.sql 1969-12-31 19:00:00.000000000 -0500
+++ ./src/test/regress/sql/nchar.sql 2013-08-19 23:31:21.000000000 -0400
@@ -0,0 +1,75 @@
+--
+-- NCHAR
+--
+
+-- fixed-length by value
+-- internally passed by value if <= 4 bytes in storage
+
+SELECT nchar 'c' = nchar 'c' AS true;
+
+--
+-- Build a table for testing
+--
+
+CREATE TABLE NCHAR_TBL(f1 nchar);
+
+INSERT INTO NCHAR_TBL (f1) VALUES ('a');
+
+INSERT INTO NCHAR_TBL (f1) VALUES ('A');
+
+-- any of the following three input formats are acceptable
+INSERT INTO NCHAR_TBL (f1) VALUES ('1');
+
+INSERT INTO NCHAR_TBL (f1) VALUES (2);
+
+INSERT INTO NCHAR_TBL (f1) VALUES ('3');
+
+-- zero-length nchar
+INSERT INTO NCHAR_TBL (f1) VALUES ('');
+
+-- try nchar's of greater than 1 length
+INSERT INTO NCHAR_TBL (f1) VALUES ('cd');
+INSERT INTO NCHAR_TBL (f1) VALUES ('c ');
+
+
+SELECT '' AS seven, * FROM NCHAR_TBL;
+
+SELECT '' AS six, c.*
+ FROM NCHAR_TBL c
+ WHERE c.f1 <> 'a';
+
+SELECT '' AS one, c.*
+ FROM NCHAR_TBL c
+ WHERE c.f1 = 'a';
+
+SELECT '' AS five, c.*
+ FROM NCHAR_TBL c
+ WHERE c.f1 < 'a';
+
+SELECT '' AS six, c.*
+ FROM NCHAR_TBL c
+ WHERE c.f1 <= 'a';
+
+SELECT '' AS one, c.*
+ FROM NCHAR_TBL c
+ WHERE c.f1 > 'a';
+
+SELECT '' AS two, c.*
+ FROM NCHAR_TBL c
+ WHERE c.f1 >= 'a';
+
+DROP TABLE NCHAR_TBL;
+
+--
+-- Now test longer arrays of nchar
+--
+
+CREATE TABLE NCHAR_TBL(f1 nchar(4));
+
+INSERT INTO NCHAR_TBL (f1) VALUES ('a');
+INSERT INTO NCHAR_TBL (f1) VALUES ('ab');
+INSERT INTO NCHAR_TBL (f1) VALUES ('abcd');
+INSERT INTO NCHAR_TBL (f1) VALUES ('abcde');
+INSERT INTO NCHAR_TBL (f1) VALUES ('abcd ');
+
+SELECT '' AS four, * FROM NCHAR_TBL;
diff -U 5 -N -r -w ../orig.HEAD/src/test/regress/sql/nvarchar_alter.sql ./src/test/regress/sql/nvarchar_alter.sql
--- ../orig.HEAD/src/test/regress/sql/nvarchar_alter.sql 1969-12-31 19:00:00.000000000 -0500
+++ ./src/test/regress/sql/nvarchar_alter.sql 2013-08-19 23:31:15.000000000 -0400
@@ -0,0 +1,126 @@
+--create table
+create table nchar_test (f1 nchar(10) default N'a', f2 nvarchar(10) default N'b');
+
+--values
+values (N'abc各国語');
+
+--analyze
+analyze nchar_test(f1);
+analyze nchar_test(f2);
+
+--vacuum analyze
+vacuum analyze nchar_test(f1);
+vacuum analyze nchar_test(f2);
+
+--broken
+--set application_name to N'abc各国語';
+
+--select
+select f1,f2,N'abc各国語' from nchar_test;
+
+--select into
+select f1,f2,N'abc各国語' into nchar_test1 from nchar_test;
+
+--revoke per column not supported
+
+--grant per column not supported
+
+--insert into/returning
+insert into nchar_test1 select f1,f2,N'abc各国語' from nchar_test returning f1,f2,nvarchar,N'abc各国語';
+
+--explain
+explain select f1,f2,N'abc各国語' from nchar_test;
+
+--do
+do $$begin perform f1,f2,N'abc各国語' from nchar_test; end $$;
+
+--delete
+delete from nchar_test where f1=N'abc各国語' and f2=N'abc各国語';
+
+--create view
+create view v as select f1,f2,N'abc各国語' from nchar_test;
+
+--create index
+create index i2 on nchar_test(f2);
+create index i3 on nchar_test((f1||'abc各国語'));
+create index i1 on nchar_test(f1);
+
+--comment
+comment on COLUMN nchar_test.f1 is 'f1';
+comment on COLUMN nchar_test.f2 is 'f2';
+comment on type nvarchar is 'nvarchar';
+
+
+--analyze
+analyze nchar_test(f1);
+
+--copy
+copy nchar_test(f1, f2) to stdout;
+
+--alter view
+alter view v alter column f1 set default N'abc各国語';
+alter view v alter column f2 set default N'abc各国語';
+
+--alter table
+alter table nchar_test1 rename f1 to f3;
+alter table nchar_test1 rename f2 to f4;
+alter table nchar_test1 alter f3 type nchar(10);
+alter table nchar_test1 alter f4 type nvarchar;
+alter table nchar_test1 alter f3 set default N'abc各国語';
+alter table nchar_test1 alter f4 set default N'abc各国語';
+
+--declare cursor
+begin;declare qqq cursor for select f1,f2,N'abc各国語' from nchar_test;commit;
+
+--create trigger
+create trigger tr before update on nchar_test for each row when (OLD.f1=N'abc各国語') EXECUTE PROCEDURE suppress_redundant_updates_trigger();
+
+--foreign key
+alter table nchar_test1 add CONSTRAINT nchar_test1_pk primary key(f3);
+alter table nchar_test add CONSTRAINT qqqq FOREIGN KEY (f1) references nchar_test1(f3);
+
+--update
+update nchar_test set f1=N'abc各国語', f2='abc各国語';
+
+select * from nchar_test1;
+
+create domain test_nchar_domain as nchar(10) default (N'a') CHECK (value <> N'b');
+create domain test_nvarchar_domain as nvarchar(10) default (N'a') CHECK (value <> N'b');
+alter domain test_nchar_domain set default (N'b');
+alter domain test_nvarchar_domain set default (N'b');
+DROP DOMAIN test_nchar_domain;
+DROP DOMAIN test_nvarchar_domain;
+
+CREATE AGGREGATE test_nvarchar_agg (nvarchar) ( sfunc = array_append, stype = nvarchar[], initcond = '{}');
+CREATE AGGREGATE test_nchar_agg (nchar(10)) ( sfunc = array_append, stype = nchar(10)[], initcond = '{}');
+alter aggregate test_nvarchar_agg(nvarchar) rename to test_nvarchar_aggregate;
+alter aggregate test_nchar_agg (nchar(10)) rename to test_nchar_aggregate;
+drop aggregate test_nvarchar_aggregate(nvarchar);
+drop aggregate test_nchar_aggregate(nchar(10));
+
+CREATE TYPE test_nchar_type AS (f1 nchar(10));
+CREATE TYPE test_nvarchar_type AS (f1 nvarchar);
+drop type test_nchar_type;
+drop type test_nvarchar_type;
+
+
+drop view v;
+drop table nchar_test;
+drop table nchar_test1;
+
+create table nchar_test (f1 nchar(10), f2 nvarchar(10));
+select f1, f2, N'a' from nchar_test where f1=N'a' and f2=N'b';
+insert into nchar_test values (N'a', N'b') returning (f1, f2, N'c');
+select f1, f2, N'a' into nchar_test1 from nchar_test;
+select * from nchar_test1;
+
+prepare qqq(nchar(10), nvarchar(10)) AS select f1, f2, N'a' from nchar_test where f1=N'a' and f2=N'b';
+execute qqq(N'a', N'b');
+
+explain select f1, f2, N'a' from nchar_test where f1=N'a' and f2=N'b';
+
+delete from nchar_test1 where f1=N'a' and f2=N'b';
+
+drop table nchar_test;
+drop table nchar_test1;
+
diff -U 5 -N -r -w ../orig.HEAD/src/test/regress/sql/nvarchar_func.sql ./src/test/regress/sql/nvarchar_func.sql
--- ../orig.HEAD/src/test/regress/sql/nvarchar_func.sql 1969-12-31 19:00:00.000000000 -0500
+++ ./src/test/regress/sql/nvarchar_func.sql 2013-08-19 23:31:15.000000000 -0400
@@ -0,0 +1,90 @@
+
+SELECT N'各国' || N'文字';
+
+SELECT N'各国' || 42;
+
+SELECT bit_length(N'各国');
+
+SELECT char_length(N'各国');
+
+SELECT lower(N'各国TOM');
+
+SELECT octet_length(N'各国');
+
+SELECT overlay(N'各XX' placing N'文字' from 2 for 3);
+
+SELECT position(N'文' in N'各国文字');
+
+SELECT substring(N'各国文字' from 3 for 3);
+
+SELECT substring(N'各国文字列' from N'...$');
+
+SELECT substring(N'各国文字列国' from '%#"文_列#"_' for '#');
+
+SELECT trim(both N'X' from N'X各国文字XX');
+
+SELECT upper(N'各国tom');
+
+SELECT ascii(N'数');
+
+SELECT btrim(N'XY各国X', N'XY');
+
+SELECT chr(25968);
+
+SELECT concat(N'各', N'国', NULL, N'語');
+
+SELECT concat_ws(N'_', N'各国', NULL, N'文字');
+
+-- convert_to(N'各国', 'SJIS') = '\x8a658d91'
+-- convert_to(N'各国', 'UTF8') = '\xe59084e59bbd'
+SELECT convert('\x8a658d91'::bytea, 'SJIS', 'UTF8');
+
+-- N'各国'::bytea = '\xe59084e59bbd'
+SELECT convert_from('\xe59084e59bbd'::bytea, 'UTF8');
+
+-- '\xe59084e59bbd'::bytea = N'各国'
+SELECT convert_to(N'各国', 'UTF8');
+
+SELECT format('各国 %s, %1$s', N'文字');
+
+SELECT initcap(N'hi 各国');
+
+SELECT left(N'各国文字', 2);
+
+SELECT length(N'各国文字');
+
+-- N'各国文字'::bytea = '\xe59084e59bbde69687e5ad97'
+SELECT length('\xe59084e59bbde69687e5ad97'::bytea , 'UTF8');
+
+SELECT lpad(N'文字', 3, N'各国');
+
+SELECT ltrim(N'◯×各国', N'◯×');
+
+SELECT regexp_matches(N'各国文字データ', N'(文字)(データ)');
+
+SELECT regexp_replace(N'各国x文字', '.[a-z]文.', N'語');
+
+SELECT regexp_split_to_array(N'各国 文字列', E'\\s+');
+
+SELECT regexp_split_to_table(N'各国 文字列', E'\\s+');
+
+SELECT repeat(N'文字', 4);
+
+SELECT replace(N'各国文字国', N'国', N'語');
+
+SELECT reverse(N'各国語');
+
+SELECT right(N'各国語', 2);
+
+SELECT rpad(N'各国', 3, N'語');
+
+SELECT rtrim(N'◯各国◯◯', N'◯');
+
+SELECT split_part(N'各国◯語◯文字', N'◯', 3);
+
+SELECT strpos(N'各国語', N'語');
+
+SELECT substr(N'各国語', 3, 3);
+
+SELECT translate(N'各国文字', N'各字', N'◯×');
+
diff -U 5 -N -r -w ../orig.HEAD/src/test/regress/sql/nvarchar_misc.sql ./src/test/regress/sql/nvarchar_misc.sql
--- ../orig.HEAD/src/test/regress/sql/nvarchar_misc.sql 1969-12-31 19:00:00.000000000 -0500
+++ ./src/test/regress/sql/nvarchar_misc.sql 2013-08-19 23:31:15.000000000 -0400
@@ -0,0 +1,22 @@
+select N'a '=N'a';
+select N'a '='a';
+select N'a'='a';
+select N'a '='a'::char(1);
+select N'a '='a'::nchar(1);
+select N'a '='a'::varchar(1);
+select N'a '='a'::nvarchar(1);
+select N'a'='a'::nvarchar(1);
+select N'a'='a'::varchar(1);
+select N'a'='a'::char(1);
+select N'a'='a'::nchar(1);
+select 'a'::nchar(10)='a'::char(1);
+select 'a'::nchar(10)='a'::nchar(1);
+select 'a'::nchar(10)='a'::varchar(1);
+select 'a'::nchar(10)='a'::nvarchar(1);
+select 'a'::nvarchar(10)='a'::varchar(1);
+select 'a'::nvarchar(10)='a'::varchar(10);
+select 'a'::nvarchar(10)='a '::varchar(10);
+select 'a'::nvarchar(10)='a '::char(10);
+select 'a '::nchar(10)='a '::nchar(5);
+select 'a '::nchar(10)='a '::char(5);
+
diff -U 5 -N -r -w ../orig.HEAD/src/test/regress/sql/nvarchar.sql ./src/test/regress/sql/nvarchar.sql
--- ../orig.HEAD/src/test/regress/sql/nvarchar.sql 1969-12-31 19:00:00.000000000 -0500
+++ ./src/test/regress/sql/nvarchar.sql 2013-08-19 23:31:15.000000000 -0400
@@ -0,0 +1,66 @@
+--
+-- NVARCHAR
+--
+
+CREATE TABLE NVARCHAR_TBL(f1 nvarchar(1));
+
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('a');
+
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('A');
+
+-- any of the following three input formats are acceptable
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('1');
+
+INSERT INTO NVARCHAR_TBL (f1) VALUES (2);
+
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('3');
+
+-- zero-length nchar
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('');
+
+-- try nvarchar's of greater than 1 length
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('cd');
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('c ');
+
+
+SELECT '' AS seven, * FROM NVARCHAR_TBL;
+
+SELECT '' AS six, c.*
+ FROM NVARCHAR_TBL c
+ WHERE c.f1 <> 'a';
+
+SELECT '' AS one, c.*
+ FROM NVARCHAR_TBL c
+ WHERE c.f1 = 'a';
+
+SELECT '' AS five, c.*
+ FROM NVARCHAR_TBL c
+ WHERE c.f1 < 'a';
+
+SELECT '' AS six, c.*
+ FROM NVARCHAR_TBL c
+ WHERE c.f1 <= 'a';
+
+SELECT '' AS one, c.*
+ FROM NVARCHAR_TBL c
+ WHERE c.f1 > 'a';
+
+SELECT '' AS two, c.*
+ FROM NVARCHAR_TBL c
+ WHERE c.f1 >= 'a';
+
+DROP TABLE NVARCHAR_TBL;
+
+--
+-- Now test longer arrays of nchar
+--
+
+CREATE TABLE NVARCHAR_TBL(f1 nvarchar(4));
+
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('a');
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('ab');
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('abcd');
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('abcde');
+INSERT INTO NVARCHAR_TBL (f1) VALUES ('abcd ');
+
+SELECT '' AS four, * FROM NVARCHAR_TBL;
diff -U 5 -N -r -w ../orig.HEAD/src/test/regress/sql/strings.sql ./src/test/regress/sql/strings.sql
--- ../orig.HEAD/src/test/regress/sql/strings.sql 2013-08-19 20:22:15.000000000 -0400
+++ ./src/test/regress/sql/strings.sql 2013-08-19 20:54:00.000000000 -0400
@@ -68,30 +68,41 @@
-- test conversions between various string types
-- E021-10 implicit casting among the character data types
--
SELECT CAST(f1 AS text) AS "text(char)" FROM CHAR_TBL;
+SELECT CAST(f1 AS text) AS "text(nchar)" FROM NCHAR_TBL;
SELECT CAST(f1 AS text) AS "text(varchar)" FROM VARCHAR_TBL;
+SELECT CAST(f1 AS text) AS "text(nvarchar)" FROM NVARCHAR_TBL;
SELECT CAST(name 'namefield' AS text) AS "text(name)";
-- since this is an explicit cast, it should truncate w/o error:
SELECT CAST(f1 AS char(10)) AS "char(text)" FROM TEXT_TBL;
-- note: implicit-cast case is tested in char.sql
+SELECT CAST(f1 AS nchar(10)) AS "nchar(text)" FROM TEXT_TBL;
+-- note: implicit-cast case is tested in nchar.sql
SELECT CAST(f1 AS char(20)) AS "char(text)" FROM TEXT_TBL;
+SELECT CAST(f1 AS nchar(20)) AS "nchar(text)" FROM TEXT_TBL;
SELECT CAST(f1 AS char(10)) AS "char(varchar)" FROM VARCHAR_TBL;
+SELECT CAST(f1 AS nchar(10)) AS "nchar(nvarchar)" FROM NVARCHAR_TBL;
+
SELECT CAST(name 'namefield' AS char(10)) AS "char(name)";
+SELECT CAST(name 'namefield' AS nchar(10)) AS "nchar(name)";
SELECT CAST(f1 AS varchar) AS "varchar(text)" FROM TEXT_TBL;
+SELECT CAST(f1 AS nvarchar) AS "nvarchar(text)" FROM TEXT_TBL;
SELECT CAST(f1 AS varchar) AS "varchar(char)" FROM CHAR_TBL;
+SELECT CAST(f1 AS nvarchar) AS "nvarchar(nchar)" FROM NCHAR_TBL;
SELECT CAST(name 'namefield' AS varchar) AS "varchar(name)";
+SELECT CAST(name 'namefield' AS nvarchar) AS "nvarchar(name)";
--
-- test SQL string functions
-- E### and T### are feature reference numbers from SQL99
--
@@ -328,14 +339,17 @@
SELECT 'unknown' || ' and unknown' AS "Concat unknown types";
SELECT text 'text' || ' and unknown' AS "Concat text to unknown type";
SELECT char(20) 'characters' || ' and text' AS "Concat char to unknown type";
+SELECT nchar(20) 'ncharacters' || ' and text' AS "Concat nchar to unknown type";
SELECT text 'text' || char(20) ' and characters' AS "Concat text to char";
+SELECT text 'text' || nchar(20) ' and ncharacters' AS "Concat text to nchar";
SELECT text 'text' || varchar ' and varchar' AS "Concat text to varchar";
+SELECT text 'text' || nvarchar ' and nvarchar' AS "Concat text to nvarchar";
--
-- test substr with toasted text values
--
CREATE TABLE toasttest(f1 text);
diff -U 5 -N -r -w ../orig.HEAD/src/test/regress/sql/union.sql ./src/test/regress/sql/union.sql
--- ../orig.HEAD/src/test/regress/sql/union.sql 2013-08-19 20:22:15.000000000 -0400
+++ ./src/test/regress/sql/union.sql 2013-08-19 20:54:00.000000000 -0400
@@ -87,10 +87,27 @@
SELECT f1 FROM VARCHAR_TBL
UNION
SELECT TRIM(TRAILING FROM f1) FROM CHAR_TBL
ORDER BY 1;
+--NVARCHAR specific
+SELECT f1 AS three FROM NVARCHAR_TBL
+UNION
+SELECT CAST(f1 AS nvarchar) FROM NCHAR_TBL
+ORDER BY 1;
+
+SELECT f1 AS eight FROM NVARCHAR_TBL
+UNION ALL
+SELECT f1 FROM NCHAR_TBL;
+
+SELECT f1 AS five FROM TEXT_TBL
+UNION
+SELECT f1 FROM NVARCHAR_TBL
+UNION
+SELECT TRIM(TRAILING FROM f1) FROM NCHAR_TBL
+ORDER BY 1;
+
--
-- INTERSECT and EXCEPT
--
SELECT q2 FROM int8_tbl INTERSECT SELECT q1 FROM int8_tbl;
diff -U 5 -N -r -w ../orig.HEAD/src/test/regress/sql/update.sql ./src/test/regress/sql/update.sql
--- ../orig.HEAD/src/test/regress/sql/update.sql 2013-08-19 20:22:15.000000000 -0400
+++ ./src/test/regress/sql/update.sql 2013-08-19 20:54:00.000000000 -0400
@@ -3,18 +3,32 @@
--
CREATE TABLE update_test (
a INT DEFAULT 10,
b INT,
- c TEXT
+ c TEXT,
+ d nchar(10),
+ e nvarchar
);
-INSERT INTO update_test VALUES (5, 10, 'foo');
+INSERT INTO update_test VALUES (5, 10, 'foo', 'a', 'a');
INSERT INTO update_test(b, a) VALUES (15, 10);
SELECT * FROM update_test;
+UPDATE update_test SET d='b', e='b';
+
+SELECT * FROM update_test;
+
+UPDATE update_test SET d='c' where e='b';
+
+SELECT * FROM update_test;
+
+UPDATE update_test SET d=N'e' where e=N'b';
+
+SELECT * FROM update_test;
+
UPDATE update_test SET a = DEFAULT, b = DEFAULT;
SELECT * FROM update_test;
-- aliases for the UPDATE target table
view thread (62+ messages) latest in thread
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected]
Subject: Re: UTF8 national character data type support WIP patch and list of open issues.
In-Reply-To: <[email protected]>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox