diff -uNr postgresql-head-20131017/doc/src/sgml/datatype.sgml postgresql-head-20131017-nchar/doc/src/sgml/datatype.sgml --- postgresql-head-20131017/doc/src/sgml/datatype.sgml 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/doc/src/sgml/datatype.sgml 2013-10-22 16:12:19.000000000 +1100 @@ -161,6 +161,18 @@ + national character varying [ (n) ] + nvarchar [ (n) ] + variable-length national character string + + + + national character [ (n) ] + nchar [ (n) ] + fixed-length national character string + + + numeric [ (p, s) ] decimal [ (p, @@ -1014,6 +1026,14 @@ text variable unlimited length + + national character varying(n), nvarchar(n) + variable-length national character string + + + national character(n), nchar(n) + fixed-length national character string + @@ -1040,7 +1060,15 @@ shorter string. - + + The data types national character(n) and + national character varying(n) can be + used to store data in a specific encoding. Currently the encoding for + national character and national character varying + data types are limited to the database encoding. As a result, declaring a + column as national character is equivalent to declaring + the column as character. + If one explicitly casts a value to character varying(n) or @@ -1060,6 +1088,15 @@ without length specifier, the type accepts strings of any size. The latter is a PostgreSQL extension. + + The notations nvarchar(n) and + nchar(n) are aliases + for national character varying(n) and + national character(n), respectively. + national character without length specifier is equivalent to + national character(1). If national character varying + is used without length specifier, the type accepts strings of any size. + In addition, PostgreSQL provides the @@ -1070,50 +1107,53 @@ - Values of type character are physically padded - with spaces to the specified width n, and are - stored and displayed that way. However, the padding spaces are + Values of types character and national character + are physically padded with spaces to the specified width 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 character, - and they will be removed when converting a character value + disregarded when comparing two values of type character or + national character, and they will be removed when converting + a character or national character value to one of the other string types. Note that trailing spaces are semantically significant in - character varying and text values, and - when using pattern matching, e.g. LIKE, + character varying,national character varying + and text values, and when using pattern matching, e.g. LIKE, regular expressions. 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 - character. 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 + character or national character. 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 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 - text or character varying without a length + text or character varying or + national character varying without a length specifier, rather than making up an arbitrary length limit.) - There is no performance difference among these three types, + There is no performance difference among these five 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 - character(n) has performance - advantages in some other database systems, there is no such advantage in - PostgreSQL; in fact - character(n) is usually the slowest of - the three because of its additional storage costs. In most situations - text or character varying should be used - instead. + character(n) and national character + (n) has performance advantages in some other database + systems, there is no such advantage in PostgreSQL; + in fact character(n) and national character + (n) are usually the slowest of + the five because of its additional storage costs. In most situations + text or character varying or + national character varying should be used instead. @@ -1153,6 +1193,31 @@ good | 5 too l | 5 + +CREATE TABLE test3 (a national character(4)); +INSERT INTO test3 VALUES (N'ok'); +SELECT a, char_length(a) FROM test3; + + a | char_length +------+------------- + ok | 2 + + +CREATE TABLE test4 (b nvarchar(5)); +INSERT INTO test4 VALUES (N'ok'); +INSERT INTO test4 VALUES (N'good '); +INSERT INTO test4 VALUES (N'too long'); +ERROR: value too long for type character varying(5) +INSERT INTO test4 VALUES ('too long'::nvarchar(5)); -- explicit truncation +SELECT b, char_length(b) FROM test4; + + b | char_length +-------+------------- + ok | 2 + good | 5 + too l | 5 + + @@ -4692,5 +4757,4 @@ - diff -uNr postgresql-head-20131017/doc/src/sgml/ecpg.sgml postgresql-head-20131017-nchar/doc/src/sgml/ecpg.sgml --- postgresql-head-20131017/doc/src/sgml/ecpg.sgml 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/doc/src/sgml/ecpg.sgml 2013-10-22 16:03:40.000000000 +1100 @@ -890,6 +890,12 @@ boolean booldeclared in ecpglib.h if not native + + + national character(n), nvarchar(n) + NCHAR[n+1], NVARCHAR[n+1] + + @@ -968,6 +974,81 @@ + + Handling National Character Strings + + + To handle SQL national character string data types, such + as nvarchar and nchar, there are two + possible ways to declare the host variables. + + + + One way is using NCHAR[], an array + of NCHAR, internally which is mapped to an array of char which is the most common way to handle + character data in C. + +EXEC SQL BEGIN DECLARE SECTION; + NCHAR str[50]; +EXEC SQL END DECLARE SECTION; + + 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. + + + + The other way is using the NVARCHAR type, which is a + special type provided by ECPG. The definition on an array of + type NVARCHAR is converted into a + named struct for every variable. A declaration like: + +NVARCHAR var[180]; + + is converted into: + +struct varchar_var { int len; char arr[180]; } var; + + The member arr hosts the string + including a terminating zero byte. Thus, to store a string in + a NVARCHAR host variable, the host variable has to be + declared with the length including the zero byte terminator. The + member len holds the length of the + string stored in the arr without the + terminating zero byte. When a host variable is used as input for + a query, if strlen(arr) + and len are different, the shorter one + is used. + + + + Two or more NVARCHAR host variables cannot be defined + in single line statement. The following code will confuse + the ecpg preprocessor: + +NVARCHAR v1[128], v2[128]; /* WRONG */ + + Two variables should be defined in separate statements like this: + +NVARCHAR v1[128]; +NVARCHAR v2[128]; + + + + + NVARCHAR and NCHAR can be written in upper or lower case, but + not in mixed case. + + + + NCHAR and NVARCHAR host variables can + also hold values of other SQL types, which will be stored in + their string forms. NVARCHAR type is similar to VARCHAR type + and added mainly for SQL standard compatibility. + + + Accessing Special Data Types diff -uNr postgresql-head-20131017/doc/src/sgml/syntax.sgml postgresql-head-20131017-nchar/doc/src/sgml/syntax.sgml --- postgresql-head-20131017/doc/src/sgml/syntax.sgml 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/doc/src/sgml/syntax.sgml 2013-10-22 15:53:09.000000000 +1100 @@ -553,6 +553,32 @@ + + String Constants with prefix N + + + Prefix N + in string constants + + + + The standard syntax for specifying national character type string constants + is to add a prefix 'N' to the string constant. + + The following trivial example shows how to pass a national character type + string constant with prefix 'N' + + + INSERT INTO test VALUES (N'ok'); + + + + + Please note that this syntax is optional and national character type string constants can also be specified bounded by single quotes ('), for example + 'ok'. + + + Dollar-quoted String Constants diff -uNr postgresql-head-20131017/src/backend/catalog/information_schema.sql postgresql-head-20131017-nchar/src/backend/catalog/information_schema.sql --- postgresql-head-20131017/src/backend/catalog/information_schema.sql 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/backend/catalog/information_schema.sql 2013-10-17 11:56:22.000000000 +1100 @@ -79,7 +79,7 @@ $$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 @@ -92,7 +92,7 @@ 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) * diff -uNr postgresql-head-20131017/src/backend/optimizer/path/indxpath.c postgresql-head-20131017-nchar/src/backend/optimizer/path/indxpath.c --- postgresql-head-20131017/src/backend/optimizer/path/indxpath.c 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/backend/optimizer/path/indxpath.c 2013-10-31 10:58:24.000000000 +1100 @@ -4003,6 +4003,8 @@ case TEXTOID: case VARCHAROID: case BPCHAROID: + case NVARCHAROID: + case NBPCHAROID: collation = DEFAULT_COLLATION_OID; constlen = -1; break; diff -uNr postgresql-head-20131017/src/backend/parser/gram.y postgresql-head-20131017-nchar/src/backend/parser/gram.y --- postgresql-head-20131017/src/backend/parser/gram.y 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/backend/parser/gram.y 2013-11-04 10:57:47.000000000 +1100 @@ -63,6 +63,7 @@ #include "utils/datetime.h" #include "utils/numeric.h" #include "utils/xml.h" +#include "mb/pg_wchar.h" /* @@ -442,9 +443,11 @@ GenericType Numeric opt_float Character ConstCharacter CharacterWithLength CharacterWithoutLength + NCharacterWithLength NCharacterWithoutLength ConstDatetime ConstInterval Bit ConstBit BitWithLength BitWithoutLength %type character +%type ncharacter %type extract_arg %type opt_charset %type opt_varying opt_timezone opt_no_inherit @@ -564,7 +567,7 @@ NAME_P NAMES NATIONAL NATURAL NCHAR NEXT NO NONE NOT NOTHING NOTIFY NOTNULL NOWAIT NULL_P NULLIF - NULLS_P NUMERIC + 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 @@ -10302,6 +10305,14 @@ { $$ = $1; } + | NCharacterWithLength + { + $$ = $1; + } + | NCharacterWithoutLength + { + $$ = $1; + } ; ConstCharacter: CharacterWithLength @@ -10319,6 +10330,68 @@ $$ = $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; + } + ; + +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 @@ -10339,8 +10412,8 @@ $$ = 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; @@ -10353,12 +10426,10 @@ { $$ = $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: @@ -12748,6 +12819,7 @@ | NONE | NULLIF | NUMERIC + | NVARCHAR | OUT_P | OVERLAY | POSITION diff -uNr postgresql-head-20131017/src/backend/parser/scan.l postgresql-head-20131017-nchar/src/backend/parser/scan.l --- postgresql-head-20131017/src/backend/parser/scan.l 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/backend/parser/scan.l 2013-10-17 11:56:22.000000000 +1100 @@ -482,7 +482,7 @@ SET_YYLLOC(); yyless(1); /* eat only 'n' this time */ - keyword = ScanKeywordLookup("nchar", + keyword = ScanKeywordLookup("nvarchar", yyextra->keywords, yyextra->num_keywords); if (keyword != NULL) diff -uNr postgresql-head-20131017/src/backend/utils/adt/Makefile postgresql-head-20131017-nchar/src/backend/utils/adt/Makefile --- postgresql-head-20131017/src/backend/utils/adt/Makefile 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/backend/utils/adt/Makefile 2013-10-25 14:53:38.000000000 +1100 @@ -20,7 +20,7 @@ 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 \ diff -uNr postgresql-head-20131017/src/backend/utils/adt/format_type.c postgresql-head-20131017-nchar/src/backend/utils/adt/format_type.c --- postgresql-head-20131017/src/backend/utils/adt/format_type.c 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/backend/utils/adt/format_type.c 2013-10-31 11:01:17.000000000 +1100 @@ -218,6 +218,17 @@ buf = pstrdup("character"); break; + case NBPCHAROID: + if (with_typemod) + buf = printTypmod("national character", typemod, typeform->typmodout); + else if (typemod_given) + { + /* See the comment for BPCHAR above */ + } + else + buf = pstrdup("national character"); + break; + case FLOAT4OID: buf = pstrdup("real"); break; @@ -293,6 +304,13 @@ 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) @@ -384,6 +402,8 @@ { case BPCHAROID: case VARCHAROID: + case NBPCHAROID: + case NVARCHAROID: /* typemod includes varlena header */ /* typemod is in characters not bytes */ diff -uNr postgresql-head-20131017/src/backend/utils/adt/nvarchar.c postgresql-head-20131017-nchar/src/backend/utils/adt/nvarchar.c --- postgresql-head-20131017/src/backend/utils/adt/nvarchar.c 1970-01-01 10:00:00.000000000 +1000 +++ postgresql-head-20131017-nchar/src/backend/utils/adt/nvarchar.c 2013-10-30 14:32:02.000000000 +1100 @@ -0,0 +1,48 @@ +/*------------------------------------------------------------------------- + * + * varchar.c + * Functions for the built-in types nchar(n) and nvarchar(n). + * + * Portions Copyright (c) 1996-2013, 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" + + +/* + * actually just UTF8 stubs copied form char/varchar + */ + +Datum +nbpcharoctetlen(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); +} + +Datum +nvarcharoctetlen(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); +} + diff -uNr postgresql-head-20131017/src/backend/utils/adt/selfuncs.c postgresql-head-20131017-nchar/src/backend/utils/adt/selfuncs.c --- postgresql-head-20131017/src/backend/utils/adt/selfuncs.c 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/backend/utils/adt/selfuncs.c 2013-10-17 11:56:22.000000000 +1100 @@ -3626,7 +3626,9 @@ */ case CHAROID: case BPCHAROID: + case NBPCHAROID: case VARCHAROID: + case NVARCHAROID: case TEXTOID: case NAMEOID: { @@ -3888,7 +3890,9 @@ val[1] = '\0'; break; case BPCHAROID: + case NBPCHAROID: case VARCHAROID: + case NVARCHAROID: case TEXTOID: val = TextDatumGetCString(value); break; @@ -5875,7 +5879,9 @@ { case TEXTOID: case VARCHAROID: + case NVARCHAROID: case BPCHAROID: + case NBPCHAROID: collation = DEFAULT_COLLATION_OID; constlen = -1; break; diff -uNr postgresql-head-20131017/src/include/catalog/pg_amop.h postgresql-head-20131017-nchar/src/include/catalog/pg_amop.h --- postgresql-head-20131017/src/include/catalog/pg_amop.h 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/include/catalog/pg_amop.h 2013-10-30 14:44:44.000000000 +1100 @@ -253,6 +253,12 @@ 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 */ @@ -518,6 +524,10 @@ /* 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 */ diff -uNr postgresql-head-20131017/src/include/catalog/pg_amproc.h postgresql-head-20131017-nchar/src/include/catalog/pg_amproc.h --- postgresql-head-20131017/src/include/catalog/pg_amproc.h 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/include/catalog/pg_amproc.h 2013-10-30 14:43:25.000000000 +1100 @@ -80,6 +80,7 @@ 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 )); @@ -129,6 +130,7 @@ 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 )); @@ -139,6 +141,7 @@ /* 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 )); @@ -168,6 +171,7 @@ 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 -uNr postgresql-head-20131017/src/include/catalog/pg_cast.h postgresql-head-20131017-nchar/src/include/catalog/pg_cast.h --- postgresql-head-20131017/src/include/catalog/pg_cast.h 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/include/catalog/pg_cast.h 2013-10-30 15:14:09.000000000 +1100 @@ -220,6 +220,20 @@ DATA(insert ( 1042 1043 401 i f )); DATA(insert ( 1043 25 0 i b )); DATA(insert ( 1043 1042 0 i b )); +DATA(insert ( 25 5001 0 i b )); +DATA(insert ( 25 6001 0 i b )); +DATA(insert ( 5001 25 401 i f )); +DATA(insert ( 6001 25 0 i b )); +DATA(insert ( 1042 5001 0 a b )); +DATA(insert ( 1042 6001 401 i f )); +DATA(insert ( 5001 1042 0 i b )); +DATA(insert ( 6001 1042 0 i b )); +DATA(insert ( 1043 5001 0 i b )); +DATA(insert ( 1043 6001 0 i b )); +DATA(insert ( 5001 1043 401 i f )); +DATA(insert ( 6001 1043 0 i b )); +DATA(insert ( 5001 6001 401 i f )); +DATA(insert ( 6001 5001 0 i b )); DATA(insert ( 18 25 946 i f )); DATA(insert ( 18 1042 860 a f )); DATA(insert ( 18 1043 946 a f )); @@ -358,5 +372,7 @@ DATA(insert ( 1560 1560 1685 i f )); DATA(insert ( 1562 1562 1687 i f )); DATA(insert ( 1700 1700 1703 i f )); +DATA(insert ( 5001 5001 5668 i f )); +DATA(insert ( 6001 6001 5669 i f )); #endif /* PG_CAST_H */ diff -uNr postgresql-head-20131017/src/include/catalog/pg_opclass.h postgresql-head-20131017-nchar/src/include/catalog/pg_opclass.h --- postgresql-head-20131017/src/include/catalog/pg_opclass.h 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/include/catalog/pg_opclass.h 2013-10-17 11:56:22.000000000 +1100 @@ -97,6 +97,8 @@ 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 )); @@ -157,6 +159,8 @@ 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 )); @@ -188,6 +192,7 @@ 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 )); @@ -208,6 +213,7 @@ 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 )); diff -uNr postgresql-head-20131017/src/include/catalog/pg_operator.h postgresql-head-20131017-nchar/src/include/catalog/pg_operator.h --- postgresql-head-20131017/src/include/catalog/pg_operator.h 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/include/catalog/pg_operator.h 2013-10-31 11:11:29.000000000 +1100 @@ -1751,7 +1751,46 @@ DATA(insert OID = 3967 ( "#>>" PGNSP PGUID b f f 114 1009 25 0 0 json_extract_path_text_op - - )); DESCR("get value from json as text with path elements"); +DATA(insert OID = 5054 ( "=" PGNSP PGUID b t t 5001 5001 16 5054 5057 nbpchareq eqsel eqjoinsel )); +DESCR("equal"); +DATA(insert OID = 5055 ( "~" PGNSP PGUID b f f 5001 25 16 0 5056 nbpcharregexeq regexeqsel regexeqjoinsel )); +DESCR("matches 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 = 5057 ( "<>" PGNSP PGUID b f f 5001 5001 16 5057 5054 nbpcharne neqsel neqjoinsel )); +DESCR("not equal"); +DATA(insert OID = 5058 ( "<" PGNSP PGUID b f f 5001 5001 16 5060 5061 nbpcharlt scalarltsel scalarltjoinsel )); +DESCR("less than"); +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 = 5060 ( ">" PGNSP PGUID b f f 5001 5001 16 5058 5059 nbpchargt scalargtsel scalargtjoinsel )); +DESCR("greater than"); +DATA(insert OID = 5061 ( ">=" PGNSP PGUID b f f 5001 5001 16 5059 5058 nbpcharge scalargtsel scalargtjoinsel )); +DESCR("greater than or equal"); +DATA(insert OID = 5211 ( "~~" PGNSP PGUID b f f 5001 25 16 0 5212 nbpcharlike likesel likejoinsel )); +DESCR("matches 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"); + +DATA(insert OID = 5234 ( "~*" PGNSP PGUID b f f 5001 25 16 0 5235 nbpcharicregexeq icregexeqsel icregexeqjoinsel )); +DESCR("matches 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"); + +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 = 5327 ( "~<=~" PGNSP PGUID b f f 5001 5001 16 5329 5330 nbpchar_pattern_le scalarltsel scalarltjoinsel )); +DESCR("less 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 = 5330 ( "~>~" PGNSP PGUID b f f 5001 5001 16 5326 5327 nbpchar_pattern_gt scalargtsel scalargtjoinsel )); +DESCR("greater than"); + +DATA(insert OID = 5629 ( "~~*" PGNSP PGUID b f f 5001 25 16 0 5630 nbpchariclike iclikesel iclikejoinsel )); +DESCR("matches 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"); /* * function prototypes diff -uNr postgresql-head-20131017/src/include/catalog/pg_proc.h postgresql-head-20131017-nchar/src/include/catalog/pg_proc.h --- postgresql-head-20131017/src/include/catalog/pg_proc.h 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/include/catalog/pg_proc.h 2013-10-31 11:57:16.000000000 +1100 @@ -4741,6 +4741,82 @@ /* event triggers */ DATA(insert OID = 3566 ( pg_event_trigger_dropped_objects PGNSP PGUID 12 10 100 0 0 f f f f t t s 0 0 2249 "" "{26,26,23,25,25,25,25}" "{o,o,o,o,o,o,o}" "{classid, objid, objsubid, object_type, schema_name, object_name, object_identity}" _null_ pg_event_trigger_dropped_objects _null_ _null_ _null_ )); DESCR("list objects dropped by the current command"); + +DATA(insert OID = 5044 ( 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 = 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_ varcharin _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_ varcharout _null_ _null_ _null_ )); +DESCR("I/O"); +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 = 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 = 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 = 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 = 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_ nbpcharoctetlen _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_ nvarcharoctetlen _null_ _null_ _null_ )); +DESCR("octet length"); + +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 = 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 = 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 = 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 = 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_ )); + +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 = 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 = 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 = 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"); + /* * Symbolic values for provolatile column: these indicate whether the result * of a function is dependent *only* on the values of its explicit arguments, diff -uNr postgresql-head-20131017/src/include/catalog/pg_type.h postgresql-head-20131017-nchar/src/include/catalog/pg_type.h --- postgresql-head-20131017/src/include/catalog/pg_type.h 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/include/catalog/pg_type.h 2013-10-30 16:07:44.000000000 +1100 @@ -669,6 +669,16 @@ DATA(insert OID = 3831 ( anyrange PGNSP PGUID -1 f p P f t \054 0 0 0 anyrange_in anyrange_out - - - - - d x f 0 -1 0 0 _null_ _null_ _null_ )); #define ANYRANGEOID 3831 +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 = 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_ )); + +/* national character types */ +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 = 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 /* * macros diff -uNr postgresql-head-20131017/src/include/parser/kwlist.h postgresql-head-20131017-nchar/src/include/parser/kwlist.h --- postgresql-head-20131017/src/include/parser/kwlist.h 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/include/parser/kwlist.h 2013-10-17 11:56:22.000000000 +1100 @@ -257,6 +257,7 @@ 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) diff -uNr postgresql-head-20131017/src/include/utils/builtins.h postgresql-head-20131017-nchar/src/include/utils/builtins.h --- postgresql-head-20131017/src/include/utils/builtins.h 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/include/utils/builtins.h 2013-10-17 11:56:22.000000000 +1100 @@ -326,6 +326,10 @@ extern Datum btoidsortsupport(PG_FUNCTION_ARGS); extern Datum btnamesortsupport(PG_FUNCTION_ARGS); +/* nvarchar.c */ +extern Datum nbpcharoctetlen(PG_FUNCTION_ARGS); +extern Datum nvarcharoctetlen(PG_FUNCTION_ARGS); + /* float.c */ extern PGDLLIMPORT int extra_float_digits; diff -uNr postgresql-head-20131017/src/interfaces/ecpg/ecpglib/data.c postgresql-head-20131017-nchar/src/interfaces/ecpg/ecpglib/data.c --- postgresql-head-20131017/src/interfaces/ecpg/ecpglib/data.c 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/interfaces/ecpg/ecpglib/data.c 2013-10-17 11:56:22.000000000 +1100 @@ -227,8 +227,10 @@ switch (type) { case ECPGt_char: + case ECPGt_nchar: case ECPGt_unsigned_char: case ECPGt_varchar: + case ECPGt_nvarchar: case ECPGt_string: break; @@ -450,6 +452,7 @@ break; case ECPGt_char: + case ECPGt_nchar: case ECPGt_unsigned_char: case ECPGt_string: { @@ -508,6 +511,7 @@ break; case ECPGt_varchar: + case ECPGt_nvarchar: { struct ECPGgeneric_varchar *variable = (struct ECPGgeneric_varchar *) (var + offset * act_tuple); diff -uNr postgresql-head-20131017/src/interfaces/ecpg/ecpglib/descriptor.c postgresql-head-20131017-nchar/src/interfaces/ecpg/ecpglib/descriptor.c --- postgresql-head-20131017/src/interfaces/ecpg/ecpglib/descriptor.c 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/interfaces/ecpg/ecpglib/descriptor.c 2013-10-17 11:56:22.000000000 +1100 @@ -200,11 +200,13 @@ 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; diff -uNr postgresql-head-20131017/src/interfaces/ecpg/ecpglib/execute.c postgresql-head-20131017-nchar/src/interfaces/ecpg/ecpglib/execute.c --- postgresql-head-20131017/src/interfaces/ecpg/ecpglib/execute.c 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/interfaces/ecpg/ecpglib/execute.c 2013-10-31 10:35:42.000000000 +1100 @@ -248,6 +248,10 @@ 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), NBPCHAROID, 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)) @@ -362,6 +366,7 @@ switch (var->type) { case ECPGt_char: + case ECPGt_nchar: case ECPGt_unsigned_char: case ECPGt_string: if (!var->varcharsize && !var->arrsize) @@ -388,6 +393,7 @@ } break; case ECPGt_varchar: + case ECPGt_nvarchar: len = ntuples * (var->varcharsize + sizeof(int)); break; default: @@ -423,7 +429,7 @@ /* 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 */ @@ -793,6 +799,7 @@ break; case ECPGt_char: + case ECPGt_nchar: case ECPGt_unsigned_char: case ECPGt_string: { @@ -827,6 +834,7 @@ } break; case ECPGt_varchar: + case ECPGt_nvarchar: { struct ECPGgeneric_varchar *variable = (struct ECPGgeneric_varchar *) (var->value); @@ -1232,6 +1240,8 @@ { case ECPGt_char: case ECPGt_varchar: + case ECPGt_nchar: + case ECPGt_nvarchar: desc_inlist.varcharsize = strlen(sqlda->sqlvar[i].sqldata); break; default: @@ -1287,6 +1297,8 @@ { case ECPGt_char: case ECPGt_varchar: + case ECPGt_nchar: + case ECPGt_nvarchar: desc_inlist.varcharsize = strlen(sqlda->sqlvar[i].sqldata); break; default: diff -uNr postgresql-head-20131017/src/interfaces/ecpg/ecpglib/misc.c postgresql-head-20131017-nchar/src/interfaces/ecpg/ecpglib/misc.c --- postgresql-head-20131017/src/interfaces/ecpg/ecpglib/misc.c 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/interfaces/ecpg/ecpglib/misc.c 2013-10-31 10:33:33.000000000 +1100 @@ -305,6 +305,7 @@ switch (type) { case ECPGt_char: + case ECPGt_nchar: case ECPGt_unsigned_char: case ECPGt_string: *((char *) ptr) = '\0'; @@ -335,6 +336,7 @@ memset((char *) ptr, 0xff, sizeof(double)); break; case ECPGt_varchar: + case ECPGt_nvarchar: *(((struct ECPGgeneric_varchar *) ptr)->arr) = 0x00; ((struct ECPGgeneric_varchar *) ptr)->len = 0; break; @@ -408,6 +410,7 @@ return (_check(ptr, sizeof(double))); break; case ECPGt_varchar: + case ECPGt_nvarchar: if (*(((struct ECPGgeneric_varchar *) ptr)->arr) == 0x00) return true; break; diff -uNr postgresql-head-20131017/src/interfaces/ecpg/ecpglib/pg_type.h postgresql-head-20131017-nchar/src/interfaces/ecpg/ecpglib/pg_type.h --- postgresql-head-20131017/src/interfaces/ecpg/ecpglib/pg_type.h 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/interfaces/ecpg/ecpglib/pg_type.h 2013-10-25 15:06:05.000000000 +1100 @@ -57,5 +57,7 @@ #define ZPBITOID 1560 #define VARBITOID 1562 #define NUMERICOID 1700 +#define NBPCHAROID 5001 +#define NVARCHAROID 6001 #endif /* PG_TYPE_H */ diff -uNr postgresql-head-20131017/src/interfaces/ecpg/ecpglib/sqlda.c postgresql-head-20131017-nchar/src/interfaces/ecpg/ecpglib/sqlda.c --- postgresql-head-20131017/src/interfaces/ecpg/ecpglib/sqlda.c 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/interfaces/ecpg/ecpglib/sqlda.c 2013-10-17 11:56:22.000000000 +1100 @@ -134,6 +134,7 @@ 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: @@ -373,6 +374,7 @@ sqlda->sqlvar[i].sqllen = sizeof(interval); break; case ECPGt_char: + case ECPGt_nchar: case ECPGt_unsigned_char: case ECPGt_string: default: @@ -562,6 +564,7 @@ sqlda->sqlvar[i].sqllen = sizeof(interval); break; case ECPGt_char: + case ECPGt_nchar: case ECPGt_unsigned_char: case ECPGt_string: default: diff -uNr postgresql-head-20131017/src/interfaces/ecpg/ecpglib/typename.c postgresql-head-20131017-nchar/src/interfaces/ecpg/ecpglib/typename.c --- postgresql-head-20131017/src/interfaces/ecpg/ecpglib/typename.c 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/interfaces/ecpg/ecpglib/typename.c 2013-10-31 10:39:30.000000000 +1100 @@ -62,6 +62,10 @@ return "interval"; case ECPGt_const: return "Const"; + case ECPGt_nchar: + return "national char"; + case ECPGt_nvarchar: + return "nvarchar"; default: abort(); } @@ -89,6 +93,10 @@ return SQL3_CHARACTER; /* bpchar */ case VARCHAROID: return SQL3_CHARACTER_VARYING; /* varchar */ + case NBPCHAROID: + return SQL3_CHARACTER; /* bpchar */ + case NVARCHAROID: + return SQL3_CHARACTER_VARYING; /* nvarchar */ case DATEOID: return SQL3_DATE_TIME_TIMESTAMP; /* date */ case TIMEOID: @@ -110,6 +118,8 @@ case CHAROID: case VARCHAROID: case BPCHAROID: + case NVARCHAROID: + case NBPCHAROID: case TEXTOID: return ECPGt_char; case INT2OID: diff -uNr postgresql-head-20131017/src/interfaces/ecpg/include/ecpgtype.h postgresql-head-20131017-nchar/src/interfaces/ecpg/include/ecpgtype.h --- postgresql-head-20131017/src/interfaces/ecpg/include/ecpgtype.h 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/interfaces/ecpg/include/ecpgtype.h 2013-10-31 10:40:06.000000000 +1100 @@ -63,7 +63,9 @@ ECPGt_EORT, /* End of result types. */ ECPGt_NO_INDICATOR, /* no indicator */ ECPGt_string, /* trimmed (char *) type */ - ECPGt_sqlda /* C struct descriptor */ + ECPGt_sqlda, /* C struct descriptor */ + ECPGt_nvarchar, /* the same as ECPGt_varchar actually */ + ECPGt_nchar /* converted to char *arr[N] */ }; /* descriptor items */ @@ -88,7 +90,7 @@ ECPGd_cardinality }; -#define IS_SIMPLE_TYPE(type) (((type) >= ECPGt_char && (type) <= ECPGt_interval) || ((type) == ECPGt_string)) +#define IS_SIMPLE_TYPE(type) (((type) >= ECPGt_char && (type) <= ECPGt_interval) || ((type) == ECPGt_string) || ((type) == ECPGt_nvarchar) || ((type) == ECPGt_nchar)) /* we also have to handle different statement types */ enum ECPG_statement_type diff -uNr postgresql-head-20131017/src/interfaces/ecpg/include/sqltypes.h postgresql-head-20131017-nchar/src/interfaces/ecpg/include/sqltypes.h --- postgresql-head-20131017/src/interfaces/ecpg/include/sqltypes.h 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/interfaces/ecpg/include/sqltypes.h 2013-10-17 11:56:22.000000000 +1100 @@ -46,6 +46,7 @@ #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 diff -uNr postgresql-head-20131017/src/interfaces/ecpg/preproc/c_keywords.c postgresql-head-20131017-nchar/src/interfaces/ecpg/preproc/c_keywords.c --- postgresql-head-20131017/src/interfaces/ecpg/preproc/c_keywords.c 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/interfaces/ecpg/preproc/c_keywords.c 2013-10-17 11:56:22.000000000 +1100 @@ -27,6 +27,8 @@ * 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}, @@ -40,6 +42,8 @@ {"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}, diff -uNr postgresql-head-20131017/src/interfaces/ecpg/preproc/ecpg.header postgresql-head-20131017-nchar/src/interfaces/ecpg/preproc/ecpg.header --- postgresql-head-20131017/src/interfaces/ecpg/preproc/ecpg.header 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/interfaces/ecpg/preproc/ecpg.header 2013-10-31 10:42:27.000000000 +1100 @@ -270,9 +270,11 @@ } else if ((ptr->variable->type->type != ECPGt_varchar && ptr->variable->type->type != ECPGt_char + && ptr->variable->type->type != ECPGt_nvarchar + && 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) + && atoi(ptr->variable->type->size) > 1) { newvar = new_variable(cat_str(4, mm_strdup("("), mm_strdup(ecpg_type_name(ptr->variable->type->u.element->type)), @@ -286,6 +288,8 @@ } else if ((ptr->variable->type->type == ECPGt_varchar || ptr->variable->type->type == ECPGt_char + || ptr->variable->type->type == ECPGt_nvarchar + || 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) @@ -298,7 +302,7 @@ 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 @@ -545,6 +549,7 @@ 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 && diff -uNr postgresql-head-20131017/src/interfaces/ecpg/preproc/ecpg.trailer postgresql-head-20131017-nchar/src/interfaces/ecpg/preproc/ecpg.trailer --- postgresql-head-20131017/src/interfaces/ecpg/preproc/ecpg.trailer 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/interfaces/ecpg/preproc/ecpg.trailer 2013-10-31 10:47:10.000000000 +1100 @@ -186,7 +186,7 @@ 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); @@ -211,11 +211,13 @@ 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: @@ -550,6 +552,22 @@ $$.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; @@ -627,7 +645,7 @@ /* 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; @@ -862,6 +880,7 @@ $$ = 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); @@ -886,6 +905,25 @@ varchar_counter++; break; + case ECPGt_nchar: + if (atoi(dimension) == -1) + { + int i = strlen($5); + + if (atoi(length) == -1 && i > 0) /* char [] = "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: @@ -1348,6 +1386,7 @@ 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); @@ -1356,6 +1395,7 @@ break; case ECPGt_char: + case ECPGt_nchar: case ECPGt_unsigned_char: case ECPGt_string: if (atoi(dimension) == -1) @@ -1844,6 +1884,8 @@ | 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("="); } diff -uNr postgresql-head-20131017/src/interfaces/ecpg/preproc/type.c postgresql-head-20131017-nchar/src/interfaces/ecpg/preproc/type.c --- postgresql-head-20131017/src/interfaces/ecpg/preproc/type.c 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/interfaces/ecpg/preproc/type.c 2013-10-17 11:56:22.000000000 +1100 @@ -137,6 +137,9 @@ case ECPGt_char: return ("ECPGt_char"); break; + case ECPGt_nchar: + return ("ECPGt_nchar"); + break; case ECPGt_unsigned_char: return ("ECPGt_unsigned_char"); break; @@ -175,6 +178,8 @@ break; case ECPGt_varchar: return ("ECPGt_varchar"); + case ECPGt_nvarchar: + return ("ECPGt_nvarchar"); case ECPGt_NO_INDICATOR: /* no indicator */ return ("ECPGt_NO_INDICATOR"); break; @@ -383,6 +388,7 @@ * pointers */ + case ECPGt_nvarchar: case ECPGt_varchar: /* @@ -406,6 +412,7 @@ sprintf(offset, "sizeof(struct varchar)"); break; case ECPGt_char: + case ECPGt_nchar: case ECPGt_unsigned_char: case ECPGt_char_variable: case ECPGt_string: diff -uNr postgresql-head-20131017/src/interfaces/ecpg/preproc/variable.c postgresql-head-20131017-nchar/src/interfaces/ecpg/preproc/variable.c --- postgresql-head-20131017/src/interfaces/ecpg/preproc/variable.c 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/interfaces/ecpg/preproc/variable.c 2013-10-17 11:56:22.000000000 +1100 @@ -529,7 +529,7 @@ "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)) @@ -554,6 +554,7 @@ break; case ECPGt_varchar: + case ECPGt_nvarchar: /* pointer has to get dimension 0 */ if (pointer_len) *dimension = mm_strdup("0"); @@ -567,6 +568,7 @@ break; case ECPGt_char: + case ECPGt_nchar: case ECPGt_unsigned_char: case ECPGt_string: /* char ** */ diff -uNr postgresql-head-20131017/src/interfaces/ecpg/test/ecpg_schedule postgresql-head-20131017-nchar/src/interfaces/ecpg/test/ecpg_schedule --- postgresql-head-20131017/src/interfaces/ecpg/test/ecpg_schedule 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/interfaces/ecpg/test/ecpg_schedule 2013-10-17 11:56:22.000000000 +1100 @@ -47,8 +47,11 @@ test: sql/show test: sql/insupd test: sql/parser +test: sql/nchar +test: sql/nvarchar test: thread/thread test: thread/thread_implicit test: thread/prep test: thread/alloc test: thread/descriptor + diff -uNr postgresql-head-20131017/src/interfaces/ecpg/test/ecpg_schedule_tcp postgresql-head-20131017-nchar/src/interfaces/ecpg/test/ecpg_schedule_tcp --- postgresql-head-20131017/src/interfaces/ecpg/test/ecpg_schedule_tcp 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/interfaces/ecpg/test/ecpg_schedule_tcp 2013-10-17 11:56:22.000000000 +1100 @@ -47,6 +47,8 @@ test: sql/show test: sql/insupd test: sql/parser +test: sql/nchar +test: sql/nvarchar test: thread/thread test: thread/thread_implicit test: thread/prep diff -uNr postgresql-head-20131017/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c postgresql-head-20131017-nchar/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c --- postgresql-head-20131017/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c 2013-10-17 11:56:22.000000000 +1100 @@ -97,6 +97,7 @@ #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 diff -uNr postgresql-head-20131017/src/interfaces/ecpg/test/expected/preproc-type.c postgresql-head-20131017-nchar/src/interfaces/ecpg/test/expected/preproc-type.c --- postgresql-head-20131017/src/interfaces/ecpg/test/expected/preproc-type.c 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/interfaces/ecpg/test/expected/preproc-type.c 2013-10-31 14:18:52.000000000 +1100 @@ -82,6 +82,12 @@ + + + + + + #line 29 "type.pgc" struct TBempl empl ; @@ -100,18 +106,30 @@ #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 ; /* exec sql end declare section */ -#line 37 "type.pgc" +#line 43 "type.pgc" /* exec sql var vc is [ 10 ] */ -#line 39 "type.pgc" +#line 45 "type.pgc" + + /* exec sql var nvc is [ 10 ] */ +#line 46 "type.pgc" ECPGdebug (1, stderr); empl.idnum = 1; { ECPGconnect(__LINE__, 0, "regress1" , NULL, NULL , NULL, 0); } -#line 43 "type.pgc" +#line 50 "type.pgc" if (sqlca.sqlcode) { @@ -119,8 +137,8 @@ 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 ) )", ECPGt_EOIT, ECPGt_EORT);} +#line 58 "type.pgc" if (sqlca.sqlcode) { @@ -128,8 +146,8 @@ 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' )", ECPGt_EOIT, ECPGt_EORT);} +#line 65 "type.pgc" if (sqlca.sqlcode) { @@ -137,7 +155,7 @@ 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 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), @@ -151,18 +169,20 @@ 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_EORT);} -#line 68 "type.pgc" +#line 75 "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'\n", empl.idnum, empl.name, empl.accs, str, ptr, vc.text, vc.len, nvc.text, nvc.len); { ECPGdisconnect(__LINE__, "CURRENT");} -#line 76 "type.pgc" +#line 83 "type.pgc" free(ptr); diff -uNr postgresql-head-20131017/src/interfaces/ecpg/test/expected/preproc-type.stderr postgresql-head-20131017-nchar/src/interfaces/ecpg/test/expected/preproc-type.stderr --- postgresql-head-20131017/src/interfaces/ecpg/test/expected/preproc-type.stderr 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/interfaces/ecpg/test/expected/preproc-type.stderr 2013-10-17 11:56:22.000000000 +1100 @@ -2,39 +2,41 @@ [NO_PID]: sqlca: code: 0, state: 00000 [NO_PID]: ECPGconnect: opening database regress1 on port [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 57: query: create table empl ( idnum integer , name char ( 20 ) , accs smallint , string1 char ( 10 ) , string2 char ( 10 ) , string3 char ( 10 ) , string4 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 57: 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 57: 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 65: query: insert into empl values ( 1 , 'user name' , 320 , 'first str' , 'second str' , 'third str' , 'fourth 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 65: 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 65: 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 72: query: select idnum , name , accs , string1 , string2 , string3 , string4 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 72: 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 72: 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 72: correctly got 1 tuples with 7 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 72: 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 72: 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 72: 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 72: 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 72: 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 72: 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 72: RESULT: third str offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 72: RESULT: fourth 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 -uNr postgresql-head-20131017/src/interfaces/ecpg/test/expected/preproc-type.stdout postgresql-head-20131017-nchar/src/interfaces/ecpg/test/expected/preproc-type.stdout --- postgresql-head-20131017/src/interfaces/ecpg/test/expected/preproc-type.stdout 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/interfaces/ecpg/test/expected/preproc-type.stdout 2013-10-17 11:56:22.000000000 +1100 @@ -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' diff -uNr postgresql-head-20131017/src/interfaces/ecpg/test/expected/sql-nchar.c postgresql-head-20131017-nchar/src/interfaces/ecpg/test/expected/sql-nchar.c --- postgresql-head-20131017/src/interfaces/ecpg/test/expected/sql-nchar.c 1970-01-01 10:00:00.000000000 +1000 +++ postgresql-head-20131017-nchar/src/interfaces/ecpg/test/expected/sql-nchar.c 2013-10-31 15:08:18.000000000 +1100 @@ -0,0 +1,417 @@ +/* Processed by ecpg (regression mode) */ +/* These include files are added by the preprocessor */ +#include +#include +#include +/* End of automatic include section */ +#define ECPGdebug(X,Y) ECPGdebug((X)+100,(Y)) + +#line 1 "nchar.pgc" +#include +#include +#include + + +#line 1 "regression.h" + + + + + + +#line 5 "nchar.pgc" + + +int main() { + /* exec sql begin declare section */ + + + +#line 9 "nchar.pgc" + char nchar_var [ 40 ] ; + +#line 10 "nchar.pgc" + char count [ 10 ] ; +/* exec sql end declare section */ +#line 11 "nchar.pgc" + + + ECPGdebug(1, stderr); + { ECPGconnect(__LINE__, 0, "regress1" , NULL, NULL , NULL, 0); } +#line 14 "nchar.pgc" + + + { ECPGsetcommit(__LINE__, "on", NULL);} +#line 16 "nchar.pgc" + + /* exec sql whenever sql_warning sqlprint ; */ +#line 17 "nchar.pgc" + + /* exec sql whenever sqlerror sqlprint ; */ +#line 18 "nchar.pgc" + + + /*initialization of test table*/ + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table My_Table ( Item varchar , count integer )", ECPGt_EOIT, ECPGt_EORT); +#line 21 "nchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 21 "nchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 21 "nchar.pgc" + + + /*reinitalization*/ + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "truncate My_Table", ECPGt_EOIT, ECPGt_EORT); +#line 24 "nchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 24 "nchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 24 "nchar.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into My_Table values ( 'foo_item' , 1 )", ECPGt_EOIT, ECPGt_EORT); +#line 25 "nchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 25 "nchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 25 "nchar.pgc" + + /*simple select into NCHAR*/ + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select Item from My_Table limit 1", ECPGt_EOIT, + ECPGt_nchar,(nchar_var),(long)40,(long)1,(40)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); +#line 27 "nchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 27 "nchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 27 "nchar.pgc" + + printf ("Item='%s'\n", nchar_var); + /*simple select using NCHAR*/ + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select count from My_Table where Item = $1 ", + ECPGt_nchar,(nchar_var),(long)40,(long)1,(40)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, + ECPGt_char,(count),(long)10,(long)1,(10)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); +#line 30 "nchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 30 "nchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 30 "nchar.pgc" + + printf ("count=%s for Item='%s'\n", count, nchar_var); + /*simple update using NCHAR*/ + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "update My_Table set count = count + 1 where Item = $1 ", + ECPGt_nchar,(nchar_var),(long)40,(long)1,(40)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); +#line 33 "nchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 33 "nchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 33 "nchar.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select count from My_Table where Item = 'foo_item'", ECPGt_EOIT, + ECPGt_char,(count),(long)10,(long)1,(10)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); +#line 34 "nchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 34 "nchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 34 "nchar.pgc" + + printf ("count=%s for Item='foo_item'\n", count); + /*simple delete using NCHAR*/ + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "delete from My_Table where Item = $1 ", + ECPGt_nchar,(nchar_var),(long)40,(long)1,(40)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); +#line 37 "nchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 37 "nchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 37 "nchar.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select count ( * ) from My_Table where Item = 'foo_item'", ECPGt_EOIT, + ECPGt_char,(count),(long)10,(long)1,(10)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); +#line 38 "nchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 38 "nchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 38 "nchar.pgc" + + printf ("found %s rows for Item='foo_item'\n", count); + /*simple insert using NCHAR*/ + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into My_Table values ( $1 , 3 )", + ECPGt_nchar,(nchar_var),(long)40,(long)1,(40)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); +#line 41 "nchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 41 "nchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 41 "nchar.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select count from My_Table where Item = 'foo_item'", ECPGt_EOIT, + ECPGt_char,(count),(long)10,(long)1,(10)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); +#line 42 "nchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 42 "nchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 42 "nchar.pgc" + + printf ("count='%s' for Item='foo_item'\n", count); + + /*prepared tests*/ + /*reinitalization*/ + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "truncate My_Table", ECPGt_EOIT, ECPGt_EORT); +#line 47 "nchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 47 "nchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 47 "nchar.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into My_Table values ( 'foo_item' , 1 )", ECPGt_EOIT, ECPGt_EORT); +#line 48 "nchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 48 "nchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 48 "nchar.pgc" + + /*prepared select into NCHAR*/ + { ECPGprepare(__LINE__, NULL, 0, "stmt", "SELECT Item FROM My_Table LIMIT 1"); +#line 50 "nchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 50 "nchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 50 "nchar.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_execute, "stmt", ECPGt_EOIT, + ECPGt_nchar,(nchar_var),(long)40,(long)1,(40)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); +#line 51 "nchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 51 "nchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 51 "nchar.pgc" + + printf ("Item='%s'\n", nchar_var); + { ECPGdeallocate(__LINE__, 0, NULL, "stmt"); +#line 53 "nchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 53 "nchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 53 "nchar.pgc" + + /*prepared select using NCHAR*/ + { ECPGprepare(__LINE__, NULL, 0, "stmt", "SELECT Count FROM My_Table WHERE Item=?"); +#line 55 "nchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 55 "nchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 55 "nchar.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_execute, "stmt", + ECPGt_nchar,(nchar_var),(long)40,(long)1,(40)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, + ECPGt_char,(count),(long)10,(long)1,(10)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); +#line 56 "nchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 56 "nchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 56 "nchar.pgc" + + printf ("count=%s for Item='foo_item'\n", count); + { ECPGdeallocate(__LINE__, 0, NULL, "stmt"); +#line 58 "nchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 58 "nchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 58 "nchar.pgc" + + /*prepared update using NCHAR*/ + { ECPGprepare(__LINE__, NULL, 0, "stmt", "UPDATE My_Table SET Count=Count+1 WHERE Item=?"); +#line 60 "nchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 60 "nchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 60 "nchar.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_execute, "stmt", + ECPGt_nchar,(nchar_var),(long)40,(long)1,(40)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); +#line 61 "nchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 61 "nchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 61 "nchar.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select count from My_Table where Item = 'foo_item'", ECPGt_EOIT, + ECPGt_char,(count),(long)10,(long)1,(10)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); +#line 62 "nchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 62 "nchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 62 "nchar.pgc" + + printf ("count=%s for Item='foo_item'\n", count); + { ECPGdeallocate(__LINE__, 0, NULL, "stmt"); +#line 64 "nchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 64 "nchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 64 "nchar.pgc" + + /*prepared delete using NCHAR*/ + { ECPGprepare(__LINE__, NULL, 0, "stmt", "DELETE FROM My_Table WHERE Item=?"); +#line 66 "nchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 66 "nchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 66 "nchar.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_execute, "stmt", + ECPGt_nchar,(nchar_var),(long)40,(long)1,(40)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); +#line 67 "nchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 67 "nchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 67 "nchar.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select count ( * ) from My_Table where Item = 'foo_item'", ECPGt_EOIT, + ECPGt_char,(count),(long)10,(long)1,(10)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); +#line 68 "nchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 68 "nchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 68 "nchar.pgc" + + printf ("found %s rows for Item='foo_item'\n", count); + { ECPGdeallocate(__LINE__, 0, NULL, "stmt"); +#line 70 "nchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 70 "nchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 70 "nchar.pgc" + + /*prepared insert using NCHAR*/ + { ECPGprepare(__LINE__, NULL, 0, "stmt", "INSERT INTO My_Table values (?, 3)"); +#line 72 "nchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 72 "nchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 72 "nchar.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_execute, "stmt", + ECPGt_nchar,(nchar_var),(long)40,(long)1,(40)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); +#line 73 "nchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 73 "nchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 73 "nchar.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select count from My_Table where Item = 'foo_item'", ECPGt_EOIT, + ECPGt_char,(count),(long)10,(long)1,(10)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); +#line 74 "nchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 74 "nchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 74 "nchar.pgc" + + printf ("count='%s' for Item='foo_item'\n", count); + { ECPGdeallocate(__LINE__, 0, NULL, "stmt"); +#line 76 "nchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 76 "nchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 76 "nchar.pgc" + + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table My_Table", ECPGt_EOIT, ECPGt_EORT); +#line 78 "nchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 78 "nchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 78 "nchar.pgc" + + { ECPGdisconnect(__LINE__, "ALL"); +#line 79 "nchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 79 "nchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 79 "nchar.pgc" + + + return 0; +} + diff -uNr postgresql-head-20131017/src/interfaces/ecpg/test/expected/sql-nchar.stderr postgresql-head-20131017-nchar/src/interfaces/ecpg/test/expected/sql-nchar.stderr --- postgresql-head-20131017/src/interfaces/ecpg/test/expected/sql-nchar.stderr 1970-01-01 10:00:00.000000000 +1000 +++ postgresql-head-20131017-nchar/src/interfaces/ecpg/test/expected/sql-nchar.stderr 2013-10-31 15:08:18.000000000 +1100 @@ -0,0 +1,196 @@ +[NO_PID]: ECPGdebug: set to 1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ECPGconnect: opening database regress1 on port +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ECPGsetcommit on line 16: action "on"; connection "regress1" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 21: query: create table My_Table ( Item varchar , count integer ); 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]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 21: OK: CREATE TABLE +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 24: query: truncate My_Table; 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]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 24: OK: TRUNCATE TABLE +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 25: query: insert into My_Table values ( 'foo_item' , 1 ); with 0 parameter(s) on connection regress1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 25: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 25: OK: INSERT 0 1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 27: query: select Item from My_Table limit 1; with 0 parameter(s) on connection regress1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 27: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 27: correctly got 1 tuples with 1 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 27: RESULT: foo_item offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 30: query: select count from My_Table where Item = $1 ; with 1 parameter(s) on connection regress1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 30: using PQexecParams +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: free_params on line 30: parameter 1 = foo_item +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 30: correctly got 1 tuples with 1 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 30: RESULT: 1 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 33: query: update My_Table set count = count + 1 where Item = $1 ; with 1 parameter(s) on connection regress1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 33: using PQexecParams +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: free_params on line 33: parameter 1 = foo_item +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 33: OK: UPDATE 1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 34: query: select count from My_Table where Item = 'foo_item'; with 0 parameter(s) on connection regress1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 34: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 34: correctly got 1 tuples with 1 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 34: RESULT: 2 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 37: query: delete from My_Table where Item = $1 ; with 1 parameter(s) on connection regress1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 37: using PQexecParams +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: free_params on line 37: parameter 1 = foo_item +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 37: OK: DELETE 1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 38: query: select count ( * ) from My_Table where Item = 'foo_item'; with 0 parameter(s) on connection regress1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 38: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 38: correctly got 1 tuples with 1 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 38: RESULT: 0 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 41: query: insert into My_Table values ( $1 , 3 ); with 1 parameter(s) on connection regress1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 41: using PQexecParams +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: free_params on line 41: parameter 1 = foo_item +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 41: OK: INSERT 0 1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 42: query: select count from My_Table where Item = 'foo_item'; with 0 parameter(s) on connection regress1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 42: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 42: correctly got 1 tuples with 1 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 42: RESULT: 3 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 47: query: truncate My_Table; with 0 parameter(s) on connection regress1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 47: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 47: OK: TRUNCATE TABLE +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 48: query: insert into My_Table values ( 'foo_item' , 1 ); 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]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 48: OK: INSERT 0 1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: prepare_common on line 50: name stmt; query: "SELECT Item FROM My_Table LIMIT 1" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 51: query: SELECT Item FROM My_Table LIMIT 1; with 0 parameter(s) on connection regress1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 51: using PQexecPrepared for "SELECT Item FROM My_Table LIMIT 1" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 51: correctly got 1 tuples with 1 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 51: RESULT: foo_item offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: deallocate_one on line 53: name stmt +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: prepare_common on line 55: name stmt; query: "SELECT Count FROM My_Table WHERE Item=$1" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 56: query: SELECT Count FROM My_Table WHERE Item=$1; with 1 parameter(s) on connection regress1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 56: using PQexecPrepared for "SELECT Count FROM My_Table WHERE Item=$1" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: free_params on line 56: parameter 1 = foo_item +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 56: correctly got 1 tuples with 1 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 56: RESULT: 1 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: deallocate_one on line 58: name stmt +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: prepare_common on line 60: name stmt; query: "UPDATE My_Table SET Count=Count+1 WHERE Item=$1" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 61: query: UPDATE My_Table SET Count=Count+1 WHERE Item=$1; with 1 parameter(s) on connection regress1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 61: using PQexecPrepared for "UPDATE My_Table SET Count=Count+1 WHERE Item=$1" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: free_params on line 61: parameter 1 = foo_item +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 61: OK: UPDATE 1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 62: query: select count from My_Table where Item = 'foo_item'; with 0 parameter(s) on connection regress1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 62: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 62: correctly got 1 tuples with 1 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 62: RESULT: 2 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: deallocate_one on line 64: name stmt +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: prepare_common on line 66: name stmt; query: "DELETE FROM My_Table WHERE Item=$1" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 67: query: DELETE FROM My_Table WHERE Item=$1; with 1 parameter(s) on connection regress1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 67: using PQexecPrepared for "DELETE FROM My_Table WHERE Item=$1" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: free_params on line 67: parameter 1 = foo_item +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 67: OK: DELETE 1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 68: query: select count ( * ) from My_Table where Item = 'foo_item'; with 0 parameter(s) on connection regress1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 68: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 68: correctly got 1 tuples with 1 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 68: RESULT: 0 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: deallocate_one on line 70: name stmt +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: prepare_common on line 72: name stmt; query: "INSERT INTO My_Table values ($1, 3)" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 73: query: INSERT INTO My_Table values ($1, 3); with 1 parameter(s) on connection regress1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 73: using PQexecPrepared for "INSERT INTO My_Table values ($1, 3)" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: free_params on line 73: parameter 1 = foo_item +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 73: OK: INSERT 0 1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 74: query: select count from My_Table where Item = 'foo_item'; with 0 parameter(s) on connection regress1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 74: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 74: correctly got 1 tuples with 1 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 74: RESULT: 3 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: deallocate_one on line 76: name stmt +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 78: 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 78: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 78: OK: DROP TABLE +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_finish: connection regress1 closed +[NO_PID]: sqlca: code: 0, state: 00000 diff -uNr postgresql-head-20131017/src/interfaces/ecpg/test/expected/sql-nchar.stdout postgresql-head-20131017-nchar/src/interfaces/ecpg/test/expected/sql-nchar.stdout --- postgresql-head-20131017/src/interfaces/ecpg/test/expected/sql-nchar.stdout 1970-01-01 10:00:00.000000000 +1000 +++ postgresql-head-20131017-nchar/src/interfaces/ecpg/test/expected/sql-nchar.stdout 2013-10-17 11:56:22.000000000 +1100 @@ -0,0 +1,10 @@ +Item='foo_item' +count=1 for Item='foo_item' +count=2 for Item='foo_item' +found 0 rows for Item='foo_item' +count='3' for Item='foo_item' +Item='foo_item' +count=1 for Item='foo_item' +count=2 for Item='foo_item' +found 0 rows for Item='foo_item' +count='3' for Item='foo_item' diff -uNr postgresql-head-20131017/src/interfaces/ecpg/test/expected/sql-nvarchar.c postgresql-head-20131017-nchar/src/interfaces/ecpg/test/expected/sql-nvarchar.c --- postgresql-head-20131017/src/interfaces/ecpg/test/expected/sql-nvarchar.c 1970-01-01 10:00:00.000000000 +1000 +++ postgresql-head-20131017-nchar/src/interfaces/ecpg/test/expected/sql-nvarchar.c 2013-10-31 15:08:18.000000000 +1100 @@ -0,0 +1,418 @@ +/* Processed by ecpg (regression mode) */ +/* These include files are added by the preprocessor */ +#include +#include +#include +/* End of automatic include section */ +#define ECPGdebug(X,Y) ECPGdebug((X)+100,(Y)) + +#line 1 "nvarchar.pgc" +#include +#include +#include + + +#line 1 "regression.h" + + + + + + +#line 5 "nvarchar.pgc" + + +int main() { + /* exec sql begin declare section */ + + + +#line 9 "nvarchar.pgc" + struct varchar_1 { int len; char arr[ 40 ]; } nvarchar_var ; + +#line 10 "nvarchar.pgc" + char count [ 10 ] ; +/* exec sql end declare section */ +#line 11 "nvarchar.pgc" + + + ECPGdebug(1, stderr); + { ECPGconnect(__LINE__, 0, "regress1" , NULL, NULL , NULL, 0); } +#line 14 "nvarchar.pgc" + + + { ECPGsetcommit(__LINE__, "on", NULL);} +#line 16 "nvarchar.pgc" + + /* exec sql whenever sql_warning sqlprint ; */ +#line 17 "nvarchar.pgc" + + /* exec sql whenever sqlerror sqlprint ; */ +#line 18 "nvarchar.pgc" + + + /*initialization of test table*/ + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table My_Table ( Item varchar , count integer )", ECPGt_EOIT, ECPGt_EORT); +#line 21 "nvarchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 21 "nvarchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 21 "nvarchar.pgc" + + + /*simple tests*/ + /*reinitalization*/ + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "truncate My_Table", ECPGt_EOIT, ECPGt_EORT); +#line 25 "nvarchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 25 "nvarchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 25 "nvarchar.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into My_Table values ( 'foo_item' , 1 )", ECPGt_EOIT, ECPGt_EORT); +#line 26 "nvarchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 26 "nvarchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 26 "nvarchar.pgc" + + /*simple select into NVARCHAR*/ + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select Item from My_Table limit 1", ECPGt_EOIT, + ECPGt_nvarchar,&(nvarchar_var),(long)40,(long)1,sizeof(struct varchar_1), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); +#line 28 "nvarchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 28 "nvarchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 28 "nvarchar.pgc" + + printf ("Item='%s'\n", nvarchar_var.arr); + /*simple select using NVARCHAR*/ + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select count from My_Table where Item = $1 ", + ECPGt_nvarchar,&(nvarchar_var),(long)40,(long)1,sizeof(struct varchar_1), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, + ECPGt_char,(count),(long)10,(long)1,(10)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); +#line 31 "nvarchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 31 "nvarchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 31 "nvarchar.pgc" + + printf ("count=%s for Item='%s'\n", count, nvarchar_var.arr); + /*simple update using NVARCHAR*/ + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "update My_Table set count = count + 1 where Item = $1 ", + ECPGt_nvarchar,&(nvarchar_var),(long)40,(long)1,sizeof(struct varchar_1), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); +#line 34 "nvarchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 34 "nvarchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 34 "nvarchar.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select count from My_Table where Item = 'foo_item'", ECPGt_EOIT, + ECPGt_char,(count),(long)10,(long)1,(10)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); +#line 35 "nvarchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 35 "nvarchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 35 "nvarchar.pgc" + + printf ("count=%s for Item='foo_item'\n", count); + /*simple delete using NVARCHAR*/ + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "delete from My_Table where Item = $1 ", + ECPGt_nvarchar,&(nvarchar_var),(long)40,(long)1,sizeof(struct varchar_1), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); +#line 38 "nvarchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 38 "nvarchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 38 "nvarchar.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select count ( * ) from My_Table where Item = 'foo_item'", ECPGt_EOIT, + ECPGt_char,(count),(long)10,(long)1,(10)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); +#line 39 "nvarchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 39 "nvarchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 39 "nvarchar.pgc" + + printf ("found %s rows for Item='foo_item'\n", count); + /*simple insert using NVARCHAR*/ + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into My_Table values ( $1 , 3 )", + ECPGt_nvarchar,&(nvarchar_var),(long)40,(long)1,sizeof(struct varchar_1), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); +#line 42 "nvarchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 42 "nvarchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 42 "nvarchar.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select count from My_Table where Item = 'foo_item'", ECPGt_EOIT, + ECPGt_char,(count),(long)10,(long)1,(10)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); +#line 43 "nvarchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 43 "nvarchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 43 "nvarchar.pgc" + + printf ("count='%s' for Item='foo_item'\n", count); + + /*prepared tests*/ + /*reinitalization*/ + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "truncate My_Table", ECPGt_EOIT, ECPGt_EORT); +#line 48 "nvarchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 48 "nvarchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 48 "nvarchar.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into My_Table values ( 'foo_item' , 1 )", ECPGt_EOIT, ECPGt_EORT); +#line 49 "nvarchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 49 "nvarchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 49 "nvarchar.pgc" + + /*prepared select into NVARCHAR*/ + { ECPGprepare(__LINE__, NULL, 0, "stmt", "SELECT Item FROM My_Table LIMIT 1"); +#line 51 "nvarchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 51 "nvarchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 51 "nvarchar.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_execute, "stmt", ECPGt_EOIT, + ECPGt_nvarchar,&(nvarchar_var),(long)40,(long)1,sizeof(struct varchar_1), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); +#line 52 "nvarchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 52 "nvarchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 52 "nvarchar.pgc" + + printf ("Item='%s'\n", nvarchar_var.arr); + { ECPGdeallocate(__LINE__, 0, NULL, "stmt"); +#line 54 "nvarchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 54 "nvarchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 54 "nvarchar.pgc" + + /*prepared select using NVARCHAR*/ + { ECPGprepare(__LINE__, NULL, 0, "stmt", "SELECT Count FROM My_Table WHERE Item=?"); +#line 56 "nvarchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 56 "nvarchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 56 "nvarchar.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_execute, "stmt", + ECPGt_nvarchar,&(nvarchar_var),(long)40,(long)1,sizeof(struct varchar_1), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, + ECPGt_char,(count),(long)10,(long)1,(10)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); +#line 57 "nvarchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 57 "nvarchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 57 "nvarchar.pgc" + + printf ("count=%s for Item='foo_item'\n", count); + { ECPGdeallocate(__LINE__, 0, NULL, "stmt"); +#line 59 "nvarchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 59 "nvarchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 59 "nvarchar.pgc" + + /*prepared update using NVARCHAR*/ + { ECPGprepare(__LINE__, NULL, 0, "stmt", "UPDATE My_Table SET Count=Count+1 WHERE Item=?"); +#line 61 "nvarchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 61 "nvarchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 61 "nvarchar.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_execute, "stmt", + ECPGt_nvarchar,&(nvarchar_var),(long)40,(long)1,sizeof(struct varchar_1), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); +#line 62 "nvarchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 62 "nvarchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 62 "nvarchar.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select count from My_Table where Item = 'foo_item'", ECPGt_EOIT, + ECPGt_char,(count),(long)10,(long)1,(10)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); +#line 63 "nvarchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 63 "nvarchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 63 "nvarchar.pgc" + + printf ("count=%s for Item='foo_item'\n", count); + { ECPGdeallocate(__LINE__, 0, NULL, "stmt"); +#line 65 "nvarchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 65 "nvarchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 65 "nvarchar.pgc" + + /*prepared delete using NVARCHAR*/ + { ECPGprepare(__LINE__, NULL, 0, "stmt", "DELETE FROM My_Table WHERE Item=?"); +#line 67 "nvarchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 67 "nvarchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 67 "nvarchar.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_execute, "stmt", + ECPGt_nvarchar,&(nvarchar_var),(long)40,(long)1,sizeof(struct varchar_1), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); +#line 68 "nvarchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 68 "nvarchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 68 "nvarchar.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select count ( * ) from My_Table where Item = 'foo_item'", ECPGt_EOIT, + ECPGt_char,(count),(long)10,(long)1,(10)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); +#line 69 "nvarchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 69 "nvarchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 69 "nvarchar.pgc" + + printf ("found %s rows for Item='foo_item'\n", count); + { ECPGdeallocate(__LINE__, 0, NULL, "stmt"); +#line 71 "nvarchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 71 "nvarchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 71 "nvarchar.pgc" + + /*prepared insert using NVARCHAR*/ + { ECPGprepare(__LINE__, NULL, 0, "stmt", "INSERT INTO My_Table values (?, 3)"); +#line 73 "nvarchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 73 "nvarchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 73 "nvarchar.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_execute, "stmt", + ECPGt_nvarchar,&(nvarchar_var),(long)40,(long)1,sizeof(struct varchar_1), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); +#line 74 "nvarchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 74 "nvarchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 74 "nvarchar.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select count from My_Table where Item = 'foo_item'", ECPGt_EOIT, + ECPGt_char,(count),(long)10,(long)1,(10)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); +#line 75 "nvarchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 75 "nvarchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 75 "nvarchar.pgc" + + printf ("count='%s' for Item='foo_item'\n", count); + { ECPGdeallocate(__LINE__, 0, NULL, "stmt"); +#line 77 "nvarchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 77 "nvarchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 77 "nvarchar.pgc" + + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table My_Table", ECPGt_EOIT, ECPGt_EORT); +#line 79 "nvarchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 79 "nvarchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 79 "nvarchar.pgc" + + { ECPGdisconnect(__LINE__, "ALL"); +#line 80 "nvarchar.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 80 "nvarchar.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 80 "nvarchar.pgc" + + + return 0; +} + diff -uNr postgresql-head-20131017/src/interfaces/ecpg/test/expected/sql-nvarchar.stderr postgresql-head-20131017-nchar/src/interfaces/ecpg/test/expected/sql-nvarchar.stderr --- postgresql-head-20131017/src/interfaces/ecpg/test/expected/sql-nvarchar.stderr 1970-01-01 10:00:00.000000000 +1000 +++ postgresql-head-20131017-nchar/src/interfaces/ecpg/test/expected/sql-nvarchar.stderr 2013-10-17 11:56:22.000000000 +1100 @@ -0,0 +1,196 @@ +[NO_PID]: ECPGdebug: set to 1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ECPGconnect: opening database regress1 on port +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ECPGsetcommit on line 16: action "on"; connection "regress1" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 21: query: create table My_Table ( Item varchar , count integer ); 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]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 21: OK: CREATE TABLE +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 25: query: truncate My_Table; with 0 parameter(s) on connection regress1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 25: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 25: OK: TRUNCATE TABLE +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 26: query: insert into My_Table values ( 'foo_item' , 1 ); with 0 parameter(s) on connection regress1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 26: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 26: OK: INSERT 0 1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 28: query: select Item from My_Table limit 1; 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]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 28: correctly got 1 tuples with 1 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 28: RESULT: foo_item offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 31: query: select count from My_Table where Item = $1 ; with 1 parameter(s) on connection regress1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 31: using PQexecParams +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: free_params on line 31: parameter 1 = foo_item +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 31: correctly got 1 tuples with 1 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 31: RESULT: 1 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 34: query: update My_Table set count = count + 1 where Item = $1 ; with 1 parameter(s) on connection regress1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 34: using PQexecParams +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: free_params on line 34: parameter 1 = foo_item +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 34: OK: UPDATE 1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 35: query: select count from My_Table where Item = 'foo_item'; with 0 parameter(s) on connection regress1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 35: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 35: correctly got 1 tuples with 1 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 35: RESULT: 2 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 38: query: delete from My_Table where Item = $1 ; with 1 parameter(s) on connection regress1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 38: using PQexecParams +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: free_params on line 38: parameter 1 = foo_item +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 38: OK: DELETE 1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 39: query: select count ( * ) from My_Table where Item = 'foo_item'; with 0 parameter(s) on connection regress1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 39: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 39: correctly got 1 tuples with 1 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 39: RESULT: 0 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 42: query: insert into My_Table values ( $1 , 3 ); with 1 parameter(s) on connection regress1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 42: using PQexecParams +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: free_params on line 42: parameter 1 = foo_item +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 42: OK: INSERT 0 1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 43: query: select count from My_Table where Item = 'foo_item'; 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 1 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 43: RESULT: 3 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 48: query: truncate My_Table; 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]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 48: OK: TRUNCATE TABLE +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 49: query: insert into My_Table values ( 'foo_item' , 1 ); with 0 parameter(s) on connection regress1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 49: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 49: OK: INSERT 0 1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: prepare_common on line 51: name stmt; query: "SELECT Item FROM My_Table LIMIT 1" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 52: query: SELECT Item FROM My_Table LIMIT 1; with 0 parameter(s) on connection regress1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 52: using PQexecPrepared for "SELECT Item FROM My_Table LIMIT 1" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 52: correctly got 1 tuples with 1 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 52: RESULT: foo_item offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: deallocate_one on line 54: name stmt +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: prepare_common on line 56: name stmt; query: "SELECT Count FROM My_Table WHERE Item=$1" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 57: query: SELECT Count FROM My_Table WHERE Item=$1; with 1 parameter(s) on connection regress1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 57: using PQexecPrepared for "SELECT Count FROM My_Table WHERE Item=$1" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: free_params on line 57: parameter 1 = foo_item +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 57: correctly got 1 tuples with 1 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 57: RESULT: 1 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: deallocate_one on line 59: name stmt +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: prepare_common on line 61: name stmt; query: "UPDATE My_Table SET Count=Count+1 WHERE Item=$1" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 62: query: UPDATE My_Table SET Count=Count+1 WHERE Item=$1; with 1 parameter(s) on connection regress1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 62: using PQexecPrepared for "UPDATE My_Table SET Count=Count+1 WHERE Item=$1" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: free_params on line 62: parameter 1 = foo_item +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 62: OK: UPDATE 1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 63: query: select count from My_Table where Item = 'foo_item'; with 0 parameter(s) on connection regress1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 63: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 63: correctly got 1 tuples with 1 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 63: RESULT: 2 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: deallocate_one on line 65: name stmt +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: prepare_common on line 67: name stmt; query: "DELETE FROM My_Table WHERE Item=$1" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 68: query: DELETE FROM My_Table WHERE Item=$1; with 1 parameter(s) on connection regress1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 68: using PQexecPrepared for "DELETE FROM My_Table WHERE Item=$1" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: free_params on line 68: parameter 1 = foo_item +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 68: OK: DELETE 1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 69: query: select count ( * ) from My_Table where Item = 'foo_item'; with 0 parameter(s) on connection regress1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 69: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 69: correctly got 1 tuples with 1 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 69: RESULT: 0 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: deallocate_one on line 71: name stmt +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: prepare_common on line 73: name stmt; query: "INSERT INTO My_Table values ($1, 3)" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 74: query: INSERT INTO My_Table values ($1, 3); with 1 parameter(s) on connection regress1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 74: using PQexecPrepared for "INSERT INTO My_Table values ($1, 3)" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: free_params on line 74: parameter 1 = foo_item +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 74: OK: INSERT 0 1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 75: query: select count from My_Table where Item = 'foo_item'; with 0 parameter(s) on connection regress1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 75: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 75: correctly got 1 tuples with 1 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 75: RESULT: 3 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: deallocate_one on line 77: name stmt +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 79: 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 79: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 79: OK: DROP TABLE +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_finish: connection regress1 closed +[NO_PID]: sqlca: code: 0, state: 00000 diff -uNr postgresql-head-20131017/src/interfaces/ecpg/test/expected/sql-nvarchar.stdout postgresql-head-20131017-nchar/src/interfaces/ecpg/test/expected/sql-nvarchar.stdout --- postgresql-head-20131017/src/interfaces/ecpg/test/expected/sql-nvarchar.stdout 1970-01-01 10:00:00.000000000 +1000 +++ postgresql-head-20131017-nchar/src/interfaces/ecpg/test/expected/sql-nvarchar.stdout 2013-10-17 11:56:22.000000000 +1100 @@ -0,0 +1,10 @@ +Item='foo_item' +count=1 for Item='foo_item' +count=2 for Item='foo_item' +found 0 rows for Item='foo_item' +count='3' for Item='foo_item' +Item='foo_item' +count=1 for Item='foo_item' +count=2 for Item='foo_item' +found 0 rows for Item='foo_item' +count='3' for Item='foo_item' diff -uNr postgresql-head-20131017/src/interfaces/ecpg/test/preproc/type.pgc postgresql-head-20131017-nchar/src/interfaces/ecpg/test/preproc/type.pgc --- postgresql-head-20131017/src/interfaces/ecpg/test/preproc/type.pgc 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/interfaces/ecpg/test/preproc/type.pgc 2013-10-31 11:24:42.000000000 +1100 @@ -34,9 +34,16 @@ int len; char text[10]; } vc; + struct nvarchar + { + int len; + char text[10]; + } nvc; + EXEC SQL END DECLARE SECTION; EXEC SQL var vc is varchar[10]; + EXEC SQL var nvc is nvarchar[10]; ECPGdebug (1, stderr); empl.idnum = 1; @@ -48,22 +55,22 @@ } 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)); 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'); 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 + into :empl, :str, :ptr, :vc, :nvc from empl where idnum =:empl.idnum; if (sqlca.sqlcode) @@ -71,7 +78,7 @@ 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'\n", empl.idnum, empl.name, empl.accs, str, ptr, vc.text, vc.len, nvc.text, nvc.len); EXEC SQL disconnect; diff -uNr postgresql-head-20131017/src/interfaces/ecpg/test/sql/Makefile postgresql-head-20131017-nchar/src/interfaces/ecpg/test/sql/Makefile --- postgresql-head-20131017/src/interfaces/ecpg/test/sql/Makefile 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/interfaces/ecpg/test/sql/Makefile 2013-10-17 11:56:22.000000000 +1100 @@ -22,7 +22,9 @@ parser parser.c \ quote quote.c \ show show.c \ - insupd insupd.c + insupd insupd.c \ + nchar nchar.c \ + nvarchar nvarchar.c all: $(TESTS) diff -uNr postgresql-head-20131017/src/interfaces/ecpg/test/sql/nchar.pgc postgresql-head-20131017-nchar/src/interfaces/ecpg/test/sql/nchar.pgc --- postgresql-head-20131017/src/interfaces/ecpg/test/sql/nchar.pgc 1970-01-01 10:00:00.000000000 +1000 +++ postgresql-head-20131017-nchar/src/interfaces/ecpg/test/sql/nchar.pgc 2013-10-31 14:49:22.000000000 +1100 @@ -0,0 +1,83 @@ +#include +#include +#include + +EXEC SQL INCLUDE ../regression; + +int main() { + EXEC SQL BEGIN DECLARE SECTION; + NCHAR nchar_var[40]; + char count[10]; + EXEC SQL END DECLARE SECTION; + + ECPGdebug(1, stderr); + EXEC SQL CONNECT TO REGRESSDB1; + + EXEC SQL SET AUTOCOMMIT TO ON; + EXEC SQL WHENEVER SQLWARNING SQLPRINT; + EXEC SQL WHENEVER SQLERROR SQLPRINT; + + /*initialization of test table*/ + EXEC SQL CREATE TABLE My_Table (Item varchar, Count integer); + + /*reinitalization*/ + EXEC SQL TRUNCATE My_Table; + EXEC SQL INSERT INTO My_Table VALUES ('foo_item', 1); + /*simple select into NCHAR*/ + EXEC SQL SELECT Item INTO :nchar_var FROM My_Table LIMIT 1; + printf ("Item='%s'\n", nchar_var); + /*simple select using NCHAR*/ + EXEC SQL SELECT Count INTO :count FROM My_Table WHERE Item=:nchar_var; + printf ("count=%s for Item='%s'\n", count, nchar_var); + /*simple update using NCHAR*/ + EXEC SQL UPDATE My_Table SET Count=Count+1 WHERE Item=:nchar_var; + EXEC SQL SELECT Count INTO :count FROM My_Table WHERE Item='foo_item'; + printf ("count=%s for Item='foo_item'\n", count); + /*simple delete using NCHAR*/ + EXEC SQL DELETE FROM My_Table WHERE Item=:nchar_var; + EXEC SQL SELECT count(*) INTO :count FROM My_Table WHERE Item='foo_item'; + printf ("found %s rows for Item='foo_item'\n", count); + /*simple insert using NCHAR*/ + EXEC SQL INSERT INTO My_Table values (:nchar_var, 3); + EXEC SQL SELECT Count INTO :count FROM My_Table WHERE Item='foo_item'; + printf ("count='%s' for Item='foo_item'\n", count); + + /*prepared tests*/ + /*reinitalization*/ + EXEC SQL TRUNCATE My_Table; + EXEC SQL INSERT INTO My_Table VALUES ('foo_item', 1); + /*prepared select into NCHAR*/ + EXEC SQL PREPARE stmt FROM "SELECT Item FROM My_Table LIMIT 1"; + EXEC SQL EXECUTE stmt INTO :nchar_var; + printf ("Item='%s'\n", nchar_var); + EXEC SQL DEALLOCATE PREPARE stmt; + /*prepared select using NCHAR*/ + EXEC SQL PREPARE stmt FROM "SELECT Count FROM My_Table WHERE Item=?"; + EXEC SQL EXECUTE stmt INTO :count USING :nchar_var; + printf ("count=%s for Item='foo_item'\n", count); + EXEC SQL DEALLOCATE PREPARE stmt; + /*prepared update using NCHAR*/ + EXEC SQL PREPARE stmt FROM "UPDATE My_Table SET Count=Count+1 WHERE Item=?"; + EXEC SQL EXECUTE stmt USING :nchar_var; + EXEC SQL SELECT Count INTO :count FROM My_Table WHERE Item='foo_item'; + printf ("count=%s for Item='foo_item'\n", count); + EXEC SQL DEALLOCATE PREPARE stmt; + /*prepared delete using NCHAR*/ + EXEC SQL PREPARE stmt FROM "DELETE FROM My_Table WHERE Item=?"; + EXEC SQL EXECUTE stmt USING :nchar_var; + EXEC SQL SELECT count(*) INTO :count FROM My_Table WHERE Item='foo_item'; + printf ("found %s rows for Item='foo_item'\n", count); + EXEC SQL DEALLOCATE PREPARE stmt; + /*prepared insert using NCHAR*/ + EXEC SQL PREPARE stmt FROM "INSERT INTO My_Table values (?, 3)"; + EXEC SQL EXECUTE stmt USING :nchar_var; + EXEC SQL SELECT Count INTO :count FROM My_Table WHERE Item='foo_item'; + printf ("count='%s' for Item='foo_item'\n", count); + EXEC SQL DEALLOCATE PREPARE stmt; + + EXEC SQL DROP TABLE My_Table; + EXEC SQL DISCONNECT ALL; + + return 0; +} + diff -uNr postgresql-head-20131017/src/interfaces/ecpg/test/sql/nvarchar.pgc postgresql-head-20131017-nchar/src/interfaces/ecpg/test/sql/nvarchar.pgc --- postgresql-head-20131017/src/interfaces/ecpg/test/sql/nvarchar.pgc 1970-01-01 10:00:00.000000000 +1000 +++ postgresql-head-20131017-nchar/src/interfaces/ecpg/test/sql/nvarchar.pgc 2013-10-31 14:50:53.000000000 +1100 @@ -0,0 +1,84 @@ +#include +#include +#include + +EXEC SQL INCLUDE ../regression; + +int main() { + EXEC SQL BEGIN DECLARE SECTION; + NVARCHAR nvarchar_var[40]; + char count[10]; + EXEC SQL END DECLARE SECTION; + + ECPGdebug(1, stderr); + EXEC SQL CONNECT TO REGRESSDB1; + + EXEC SQL SET AUTOCOMMIT TO ON; + EXEC SQL WHENEVER SQLWARNING SQLPRINT; + EXEC SQL WHENEVER SQLERROR SQLPRINT; + + /*initialization of test table*/ + EXEC SQL CREATE TABLE My_Table (Item varchar, Count integer); + + /*simple tests*/ + /*reinitalization*/ + EXEC SQL TRUNCATE My_Table; + EXEC SQL INSERT INTO My_Table VALUES ('foo_item', 1); + /*simple select into NVARCHAR*/ + EXEC SQL SELECT Item INTO :nvarchar_var FROM My_Table LIMIT 1; + printf ("Item='%s'\n", nvarchar_var.arr); + /*simple select using NVARCHAR*/ + EXEC SQL SELECT Count INTO :count FROM My_Table WHERE Item=:nvarchar_var; + printf ("count=%s for Item='%s'\n", count, nvarchar_var.arr); + /*simple update using NVARCHAR*/ + EXEC SQL UPDATE My_Table SET Count=Count+1 WHERE Item=:nvarchar_var; + EXEC SQL SELECT Count INTO :count FROM My_Table WHERE Item='foo_item'; + printf ("count=%s for Item='foo_item'\n", count); + /*simple delete using NVARCHAR*/ + EXEC SQL DELETE FROM My_Table WHERE Item=:nvarchar_var; + EXEC SQL SELECT count(*) INTO :count FROM My_Table WHERE Item='foo_item'; + printf ("found %s rows for Item='foo_item'\n", count); + /*simple insert using NVARCHAR*/ + EXEC SQL INSERT INTO My_Table values (:nvarchar_var, 3); + EXEC SQL SELECT Count INTO :count FROM My_Table WHERE Item='foo_item'; + printf ("count='%s' for Item='foo_item'\n", count); + + /*prepared tests*/ + /*reinitalization*/ + EXEC SQL TRUNCATE My_Table; + EXEC SQL INSERT INTO My_Table VALUES ('foo_item', 1); + /*prepared select into NVARCHAR*/ + EXEC SQL PREPARE stmt FROM "SELECT Item FROM My_Table LIMIT 1"; + EXEC SQL EXECUTE stmt INTO :nvarchar_var; + printf ("Item='%s'\n", nvarchar_var.arr); + EXEC SQL DEALLOCATE PREPARE stmt; + /*prepared select using NVARCHAR*/ + EXEC SQL PREPARE stmt FROM "SELECT Count FROM My_Table WHERE Item=?"; + EXEC SQL EXECUTE stmt INTO :count USING :nvarchar_var; + printf ("count=%s for Item='foo_item'\n", count); + EXEC SQL DEALLOCATE PREPARE stmt; + /*prepared update using NVARCHAR*/ + EXEC SQL PREPARE stmt FROM "UPDATE My_Table SET Count=Count+1 WHERE Item=?"; + EXEC SQL EXECUTE stmt USING :nvarchar_var; + EXEC SQL SELECT Count INTO :count FROM My_Table WHERE Item='foo_item'; + printf ("count=%s for Item='foo_item'\n", count); + EXEC SQL DEALLOCATE PREPARE stmt; + /*prepared delete using NVARCHAR*/ + EXEC SQL PREPARE stmt FROM "DELETE FROM My_Table WHERE Item=?"; + EXEC SQL EXECUTE stmt USING :nvarchar_var; + EXEC SQL SELECT count(*) INTO :count FROM My_Table WHERE Item='foo_item'; + printf ("found %s rows for Item='foo_item'\n", count); + EXEC SQL DEALLOCATE PREPARE stmt; + /*prepared insert using NVARCHAR*/ + EXEC SQL PREPARE stmt FROM "INSERT INTO My_Table values (?, 3)"; + EXEC SQL EXECUTE stmt USING :nvarchar_var; + EXEC SQL SELECT Count INTO :count FROM My_Table WHERE Item='foo_item'; + printf ("count='%s' for Item='foo_item'\n", count); + EXEC SQL DEALLOCATE PREPARE stmt; + + EXEC SQL DROP TABLE My_Table; + EXEC SQL DISCONNECT ALL; + + return 0; +} + diff -uNr postgresql-head-20131017/src/test/regress/expected/create_function_3.out postgresql-head-20131017-nchar/src/test/regress/expected/create_function_3.out --- postgresql-head-20131017/src/test/regress/expected/create_function_3.out 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/test/regress/expected/create_function_3.out 2013-10-17 11:56:22.000000000 +1100 @@ -308,6 +308,8 @@ 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} @@ -383,7 +385,7 @@ 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 diff -uNr postgresql-head-20131017/src/test/regress/expected/n_test.out postgresql-head-20131017-nchar/src/test/regress/expected/n_test.out --- postgresql-head-20131017/src/test/regress/expected/n_test.out 1970-01-01 10:00:00.000000000 +1000 +++ postgresql-head-20131017-nchar/src/test/regress/expected/n_test.out 2013-10-17 11:56:22.000000000 +1100 @@ -0,0 +1,81 @@ +create domain test1_n_domain as varchar default (N'a'); +create domain test2_n_domain as varchar CHECK (value <> N'b'); +alter domain test1_n_domain set default (N'b'); +values (N'a'); + column1 +--------- + a +(1 row) + +create table n_test (f varchar default N'a', val varchar); +insert into n_test values (N'a', 'test_val') returning f; + f +--- + a +(1 row) + +SELECT f from n_test; + f +--- + a +(1 row) + +select N'a' as f into n_test1 from n_test; +select * from n_test1; + f +--- + a +(1 row) + +select N'a' as f from n_test; + f +--- + a +(1 row) + +select val from n_test where f=N'a'; + val +---------- + test_val +(1 row) + +copy (select N'a' from n_test) to stdout; +a +alter table n_test alter f set default N'a'; +prepare stmt AS select N'a' as f from n_test; +deallocate stmt; +create index i on n_test((f||N'a')); +create trigger tr before update on n_test for each row when (OLD.f=N'a') EXECUTE PROCEDURE suppress_redundant_updates_trigger(); +do $$begin perform N'a' from n_test; end $$; +create view v as select N'a' as f from n_test; +select * from v; + f +--- + a +(1 row) + +alter view v alter column f set default N'a'; +begin;declare c cursor for select N'a' as f from n_test;commit; +prepare stmt(varchar) AS select val from n_test where f=$1; +execute stmt(N'a'); + val +---------- + test_val +(1 row) + +deallocate stmt; +UPDATE n_test SET f=N'b'; +SELECT * from n_test; + f | val +---+---------- + b | test_val +(1 row) + +delete from n_test where f=N'b'; +CREATE FUNCTION foo(f varchar default N'a') returns setof varchar as $$SELECT N'a' from n_test;$$ LANGUAGE SQL; +drop view v; +drop table n_test; +drop table n_test1; +drop function foo(varchar); +drop domain test1_n_domain; +drop domain test2_n_domain; diff -uNr postgresql-head-20131017/src/test/regress/expected/nchar.out postgresql-head-20131017-nchar/src/test/regress/expected/nchar.out --- postgresql-head-20131017/src/test/regress/expected/nchar.out 1970-01-01 10:00:00.000000000 +1000 +++ postgresql-head-20131017-nchar/src/test/regress/expected/nchar.out 2013-10-17 11:56:22.000000000 +1100 @@ -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 -uNr postgresql-head-20131017/src/test/regress/expected/nchar_1.out postgresql-head-20131017-nchar/src/test/regress/expected/nchar_1.out --- postgresql-head-20131017/src/test/regress/expected/nchar_1.out 1970-01-01 10:00:00.000000000 +1000 +++ postgresql-head-20131017-nchar/src/test/regress/expected/nchar_1.out 2013-10-17 11:56:22.000000000 +1100 @@ -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 +------+---- + | 1 + | 2 + | 3 + | +(4 rows) + +SELECT '' AS six, c.* + FROM NCHAR_TBL c + WHERE c.f1 <= 'a'; + six | f1 +-----+---- + | a + | 1 + | 2 + | 3 + | +(5 rows) + +SELECT '' AS one, c.* + FROM NCHAR_TBL c + WHERE c.f1 > 'a'; + one | f1 +-----+---- + | A + | c +(2 rows) + +SELECT '' AS two, c.* + FROM NCHAR_TBL c + WHERE c.f1 >= 'a'; + two | f1 +-----+---- + | a + | A + | c +(3 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 -uNr postgresql-head-20131017/src/test/regress/expected/nchar_2.out postgresql-head-20131017-nchar/src/test/regress/expected/nchar_2.out --- postgresql-head-20131017/src/test/regress/expected/nchar_2.out 1970-01-01 10:00:00.000000000 +1000 +++ postgresql-head-20131017-nchar/src/test/regress/expected/nchar_2.out 2013-10-17 11:56:22.000000000 +1100 @@ -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 +------+---- + | +(1 row) + +SELECT '' AS six, c.* + FROM NCHAR_TBL c + WHERE c.f1 <= 'a'; + six | f1 +-----+---- + | a + | +(2 rows) + +SELECT '' AS one, c.* + FROM NCHAR_TBL c + WHERE c.f1 > 'a'; + one | f1 +-----+---- + | A + | 1 + | 2 + | 3 + | c +(5 rows) + +SELECT '' AS two, c.* + FROM NCHAR_TBL c + WHERE c.f1 >= 'a'; + two | f1 +-----+---- + | a + | A + | 1 + | 2 + | 3 + | c +(6 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 -uNr postgresql-head-20131017/src/test/regress/expected/nchar_test.out postgresql-head-20131017-nchar/src/test/regress/expected/nchar_test.out --- postgresql-head-20131017/src/test/regress/expected/nchar_test.out 1970-01-01 10:00:00.000000000 +1000 +++ postgresql-head-20131017-nchar/src/test/regress/expected/nchar_test.out 2013-10-17 11:56:22.000000000 +1100 @@ -0,0 +1,101 @@ +CREATE AGGREGATE test_nchar_agg (nchar(10)) ( sfunc = array_append, stype = nchar(10)[], initcond = '{}'); +alter aggregate test_nchar_agg (nchar(10)) rename to test_nchar_aggregate; +drop aggregate test_nchar_aggregate(nchar(10)); +create domain test_nchar_domain as nchar(10); +drop domain test_nchar_domain; +create table nchar_test (f nchar(10), val varchar); +create index i on nchar_test(f); +vacuum analyze nchar_test(f); +insert into nchar_test values ('a', 'test_val') returning (f); + f +------------ + a +(1 row) + +SELECT f from nchar_test; + f +------------ + a +(1 row) + +select f into nchar_test1 from nchar_test; +select * from nchar_test1; + f +------------ + a +(1 row) + +drop table nchar_test1; +select f from nchar_test; + f +------------ + a +(1 row) + +select val from nchar_test where f='a'; + val +---------- + test_val +(1 row) + +prepare stmt AS select f from nchar_test; +prepare stmt1(nchar(10)) AS select val from nchar_test where f=$1; +deallocate stmt; +deallocate stmt1; +prepare stmt(varchar) AS select val from nchar_test where f=$1; +execute stmt('a'); + val +---------- + test_val +(1 row) + +deallocate stmt; +begin;declare c cursor for select f from nchar_test;commit; +create view v as select f from nchar_test; +select * from v; + f +------------ + a +(1 row) + +alter view v alter column f set default 'a'; +drop view v; +do $$begin perform f from nchar_test; end $$; +CREATE TYPE test_nchar_type AS (f nchar(10)); +comment on type test_nchar_type is 'comment'; +drop type test_nchar_type; +create trigger tr before update on nchar_test for each row when (OLD.f='a') EXECUTE PROCEDURE suppress_redundant_updates_trigger(); +copy nchar_test(f) to stdout; +a +comment on COLUMN nchar_test.f is 'comment'; +analyze nchar_test(f); +alter table nchar_test rename f to f_renamed; +alter table nchar_test rename f_renamed to f; +alter table nchar_test alter val type nchar(10); +UPDATE nchar_test SET f='b'; +SELECT * from nchar_test; + f | val +------------+------------ + b | test_val +(1 row) + +delete from nchar_test where f='b'; +CREATE FUNCTION foo(f nchar(10)) returns setof nchar(10) as $$SELECT f from nchar_test;$$ LANGUAGE SQL; +alter function foo(nchar(10)) reset all; +drop function foo(nchar(10)); +drop table nchar_test; +create function dummy_eq (nchar, nchar) returns boolean as 'SELECT $1=$2;' LANGUAGE SQL; +CREATE OPERATOR === (LEFTARG = nchar, RIGHTARG = nchar, PROCEDURE = dummy_eq); +alter operator === (nchar,nchar) set schema pg_catalog; +DROP OPERATOR === (nchar,nchar); +drop function dummy_eq (nchar, nchar); +create cast (nchar as bytea) with FUNCTION nbpcharsend(nchar); +drop cast (nchar as bytea); +create foreign data wrapper dummy; +CREATE SERVER foo FOREIGN DATA WRAPPER "dummy"; +create foreign table ft_nchar (f nchar(10), var varchar) server foo; +alter foreign table ft_nchar alter var type nchar(10); +alter foreign table ft_nchar rename column f to f_new; +drop foreign table ft_nchar; +drop SERVER foo; +drop foreign data wrapper dummy; diff -uNr postgresql-head-20131017/src/test/regress/expected/nvarchar.out postgresql-head-20131017-nchar/src/test/regress/expected/nvarchar.out --- postgresql-head-20131017/src/test/regress/expected/nvarchar.out 1970-01-01 10:00:00.000000000 +1000 +++ postgresql-head-20131017-nchar/src/test/regress/expected/nvarchar.out 2013-10-17 11:56:22.000000000 +1100 @@ -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 nvarchar +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 nvarchar +-- +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 -uNr postgresql-head-20131017/src/test/regress/expected/nvarchar_1.out postgresql-head-20131017-nchar/src/test/regress/expected/nvarchar_1.out --- postgresql-head-20131017/src/test/regress/expected/nvarchar_1.out 1970-01-01 10:00:00.000000000 +1000 +++ postgresql-head-20131017-nchar/src/test/regress/expected/nvarchar_1.out 2013-10-17 11:56:22.000000000 +1100 @@ -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 nvarchar +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 nvarchar +-- +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 -uNr postgresql-head-20131017/src/test/regress/expected/nvarchar_2.out postgresql-head-20131017-nchar/src/test/regress/expected/nvarchar_2.out --- postgresql-head-20131017/src/test/regress/expected/nvarchar_2.out 1970-01-01 10:00:00.000000000 +1000 +++ postgresql-head-20131017-nchar/src/test/regress/expected/nvarchar_2.out 2013-10-17 11:56:22.000000000 +1100 @@ -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 nvarchar +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 nvarchar +-- +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 -uNr postgresql-head-20131017/src/test/regress/expected/nvarchar_misc.out postgresql-head-20131017-nchar/src/test/regress/expected/nvarchar_misc.out --- postgresql-head-20131017/src/test/regress/expected/nvarchar_misc.out 1970-01-01 10:00:00.000000000 +1000 +++ postgresql-head-20131017-nchar/src/test/regress/expected/nvarchar_misc.out 2013-10-17 11:56:22.000000000 +1100 @@ -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 -uNr postgresql-head-20131017/src/test/regress/expected/nvarchar_test.out postgresql-head-20131017-nchar/src/test/regress/expected/nvarchar_test.out --- postgresql-head-20131017/src/test/regress/expected/nvarchar_test.out 1970-01-01 10:00:00.000000000 +1000 +++ postgresql-head-20131017-nchar/src/test/regress/expected/nvarchar_test.out 2013-10-17 11:56:22.000000000 +1100 @@ -0,0 +1,101 @@ +CREATE AGGREGATE test_nvarchar_agg (nvarchar) ( sfunc = array_append, stype = nvarchar[], initcond = '{}'); +alter aggregate test_nvarchar_agg (nvarchar) rename to test_nvarchar_aggregate; +drop aggregate test_nvarchar_aggregate(nvarchar); +create domain test_nvarchar_domain as nvarchar; +drop domain test_nvarchar_domain; +create table nvarchar_test (f nvarchar, val varchar); +create index i on nvarchar_test(f); +vacuum analyze nvarchar_test(f); +insert into nvarchar_test values ('a', 'test_val') returning (f); + f +--- + a +(1 row) + +SELECT f from nvarchar_test; + f +--- + a +(1 row) + +select f into nvarchar_test1 from nvarchar_test; +select * from nvarchar_test1; + f +--- + a +(1 row) + +drop table nvarchar_test1; +select f from nvarchar_test; + f +--- + a +(1 row) + +select val from nvarchar_test where f='a'; + val +---------- + test_val +(1 row) + +prepare stmt AS select f from nvarchar_test; +prepare stmt1(nvarchar) AS select val from nvarchar_test where f=$1; +deallocate stmt; +deallocate stmt1; +prepare stmt(varchar) AS select val from nvarchar_test where f=$1; +execute stmt('a'); + val +---------- + test_val +(1 row) + +deallocate stmt; +begin;declare c cursor for select f from nvarchar_test;commit; +create view v as select f from nvarchar_test; +select * from v; + f +--- + a +(1 row) + +alter view v alter column f set default 'a'; +drop view v; +do $$begin perform f from nvarchar_test; end $$; +CREATE TYPE test_nvarchar_type AS (f nvarchar); +comment on type test_nvarchar_type is 'comment'; +drop type test_nvarchar_type; +create trigger tr before update on nvarchar_test for each row when (OLD.f='a') EXECUTE PROCEDURE suppress_redundant_updates_trigger(); +copy nvarchar_test(f) to stdout; +a +comment on COLUMN nvarchar_test.f is 'comment'; +analyze nvarchar_test(f); +alter table nvarchar_test rename f to f_renamed; +alter table nvarchar_test rename f_renamed to f; +alter table nvarchar_test alter val type nvarchar; +UPDATE nvarchar_test SET f='b'; +SELECT * from nvarchar_test; + f | val +---+---------- + b | test_val +(1 row) + +delete from nvarchar_test where f='b'; +CREATE FUNCTION foo(f nvarchar) returns setof nvarchar as $$SELECT f from nvarchar_test;$$ LANGUAGE SQL; +alter function foo(nvarchar) reset all; +drop function foo(nvarchar); +drop table nvarchar_test; +create function dummy_eq (nvarchar, nvarchar) returns boolean as 'SELECT $1=$2;' LANGUAGE SQL; +CREATE OPERATOR === (LEFTARG = nvarchar, RIGHTARG = nvarchar, PROCEDURE = dummy_eq); +alter operator === (nvarchar,nvarchar) set schema pg_catalog; +DROP OPERATOR === (nvarchar,nvarchar); +drop function dummy_eq (nvarchar, nvarchar); +create cast (name as nvarchar) with FUNCTION "nvarchar"(name); +drop cast (name as nvarchar); +create foreign data wrapper dummy; +CREATE SERVER foo FOREIGN DATA WRAPPER "dummy"; +create foreign table ft_nvarchar (f nvarchar, var varchar) server foo; +alter foreign table ft_nvarchar alter var type nvarchar; +alter foreign table ft_nvarchar rename column f to f_new; +drop foreign table ft_nvarchar; +drop SERVER foo; +drop foreign data wrapper dummy; diff -uNr postgresql-head-20131017/src/test/regress/expected/opr_sanity.out postgresql-head-20131017-nchar/src/test/regress/expected/opr_sanity.out --- postgresql-head-20131017/src/test/regress/expected/opr_sanity.out 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/test/regress/expected/opr_sanity.out 2013-10-31 13:47:56.000000000 +1100 @@ -154,8 +154,11 @@ 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 @@ -171,10 +174,14 @@ -------------+------------- 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 @@ -189,10 +196,11 @@ 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 @@ -434,16 +442,20 @@ WHERE k.castmethod = 'b' AND k.castsource = c.casttarget AND k.casttarget = c.castsource); - castsource | casttarget | castfunc | castcontext --------------------+-------------------+----------+------------- - text | character | 0 | i - character varying | 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) + castsource | casttarget | castfunc | castcontext +----------------------------+--------------------+----------+------------- + text | character | 0 | i + character varying | character | 0 | i + text | national character | 0 | i + national character varying | character | 0 | i + character varying | national character | 0 | i + national character varying | 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 +(11 rows) -- **************** pg_operator **************** -- Look for illegal values in pg_operator fields. @@ -1228,7 +1240,9 @@ p3.amopstrategy = 1); amoplefttype | amoplefttype --------------+-------------- -(0 rows) + 1042 | 5001 + 5001 | 1042 +(2 rows) -- **************** pg_amproc **************** -- Look for illegal values in pg_amproc fields @@ -1289,9 +1303,11 @@ GROUP BY amname, amsupport, opcname, amprocfamily HAVING (count(*) != amsupport AND count(*) != amsupport - 1) OR amprocfamily IS NULL; - amname | opcname | count ---------+---------+------- -(0 rows) + amname | opcname | count +--------+---------------+------- + 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 @@ -1332,9 +1348,11 @@ THEN prorettype != 'void'::regtype OR proretset OR pronargs != 1 OR proargtypes[0] != 'internal'::regtype ELSE true END); - amprocfamily | amprocnum | oid | proname | opfname ---------------+-----------+-----+---------+--------- -(0 rows) + amprocfamily | amprocnum | oid | proname | opfname +--------------+-----------+------+----------------------+-------------------- + 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 diff -uNr postgresql-head-20131017/src/test/regress/expected/sanity_check.out postgresql-head-20131017-nchar/src/test/regress/expected/sanity_check.out --- postgresql-head-20131017/src/test/regress/expected/sanity_check.out 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/test/regress/expected/sanity_check.out 2013-10-17 14:05:30.000000000 +1100 @@ -69,6 +69,7 @@ lseg_tbl | f main_table | f money_data | f + nchar_tbl | f num_data | f num_exp_add | t num_exp_div | t @@ -80,6 +81,7 @@ num_exp_sub | t num_input_test | f num_result | f + nvarchar_tbl | f onek | t onek2 | t path_tbl | f @@ -167,7 +169,7 @@ timetz_tbl | f tinterval_tbl | f varchar_tbl | f -(156 rows) +(158 rows) -- -- another sanity check: every system catalog that has OIDs should have diff -uNr postgresql-head-20131017/src/test/regress/expected/strings.out postgresql-head-20131017-nchar/src/test/regress/expected/strings.out --- postgresql-head-20131017/src/test/regress/expected/strings.out 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/test/regress/expected/strings.out 2013-10-17 11:56:22.000000000 +1100 @@ -203,6 +203,15 @@ 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) --------------- @@ -212,6 +221,15 @@ 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) ------------ @@ -227,6 +245,14 @@ (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) ---------------------- @@ -234,6 +260,13 @@ 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) --------------- @@ -243,12 +276,27 @@ 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) ------------------- @@ -256,6 +304,13 @@ 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) --------------- @@ -265,12 +320,27 @@ 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 @@ -1105,18 +1175,36 @@ 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 -- diff -uNr postgresql-head-20131017/src/test/regress/expected/union.out postgresql-head-20131017-nchar/src/test/regress/expected/union.out --- postgresql-head-20131017/src/test/regress/expected/union.out 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/test/regress/expected/union.out 2013-10-17 11:56:22.000000000 +1100 @@ -257,6 +257,48 @@ 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 -- diff -uNr postgresql-head-20131017/src/test/regress/expected/update.out postgresql-head-20131017-nchar/src/test/regress/expected/update.out --- postgresql-head-20131017/src/test/regress/expected/update.out 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/test/regress/expected/update.out 2013-10-17 11:56:22.000000000 +1100 @@ -4,40 +4,66 @@ 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) -- @@ -46,10 +72,10 @@ 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) -- @@ -57,18 +83,18 @@ -- 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: diff -uNr postgresql-head-20131017/src/test/regress/output/misc.source postgresql-head-20131017-nchar/src/test/regress/output/misc.source --- postgresql-head-20131017/src/test/regress/output/misc.source 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/test/regress/output/misc.source 2013-10-17 14:06:41.000000000 +1100 @@ -643,6 +643,7 @@ lseg_tbl main_table money_data + nchar_tbl num_data num_exp_add num_exp_div @@ -654,6 +655,7 @@ num_exp_sub num_input_test num_result + nvarchar_tbl onek onek2 path_tbl @@ -697,7 +699,7 @@ tvvmv varchar_tbl xacttest -(119 rows) +(121 rows) SELECT name(equipment(hobby_construct(text 'skywalking', text 'mer'))); name diff -uNr postgresql-head-20131017/src/test/regress/parallel_schedule postgresql-head-20131017-nchar/src/test/regress/parallel_schedule --- postgresql-head-20131017/src/test/regress/parallel_schedule 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/test/regress/parallel_schedule 2013-10-22 15:16:06.000000000 +1100 @@ -13,7 +13,7 @@ # ---------- # 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_misc # Depends on things setup during char, varchar and text test: strings @@ -109,3 +109,8 @@ # run stats by itself because its delay may be insufficient under heavy load test: stats + +test: n_test +test: nchar_test +test: nvarchar_test + diff -uNr postgresql-head-20131017/src/test/regress/serial_schedule postgresql-head-20131017-nchar/src/test/regress/serial_schedule --- postgresql-head-20131017/src/test/regress/serial_schedule 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/test/regress/serial_schedule 2013-10-22 14:38:27.000000000 +1100 @@ -5,6 +5,9 @@ test: char test: name test: varchar +test: nvarchar +test: nvarchar_misc +test: nchar test: text test: int2 test: int4 @@ -141,3 +144,7 @@ test: with test: xml test: stats +test: n_test +test: nchar_test +test: nvarchar_test + diff -uNr postgresql-head-20131017/src/test/regress/sql/n_test.sql postgresql-head-20131017-nchar/src/test/regress/sql/n_test.sql --- postgresql-head-20131017/src/test/regress/sql/n_test.sql 1970-01-01 10:00:00.000000000 +1000 +++ postgresql-head-20131017-nchar/src/test/regress/sql/n_test.sql 2013-10-17 11:56:22.000000000 +1100 @@ -0,0 +1,57 @@ + +create domain test1_n_domain as varchar default (N'a'); +create domain test2_n_domain as varchar CHECK (value <> N'b'); + +alter domain test1_n_domain set default (N'b'); + +values (N'a'); + +create table n_test (f varchar default N'a', val varchar); + +insert into n_test values (N'a', 'test_val') returning f; +SELECT f from n_test; + +select N'a' as f into n_test1 from n_test; +select * from n_test1; + +select N'a' as f from n_test; +select val from n_test where f=N'a'; + +copy (select N'a' from n_test) to stdout; + +alter table n_test alter f set default N'a'; + +prepare stmt AS select N'a' as f from n_test; +deallocate stmt; + +create index i on n_test((f||N'a')); + +create trigger tr before update on n_test for each row when (OLD.f=N'a') EXECUTE PROCEDURE suppress_redundant_updates_trigger(); + +do $$begin perform N'a' from n_test; end $$; + +create view v as select N'a' as f from n_test; +select * from v; + +alter view v alter column f set default N'a'; + +begin;declare c cursor for select N'a' as f from n_test;commit; + +prepare stmt(varchar) AS select val from n_test where f=$1; +execute stmt(N'a'); +deallocate stmt; + +UPDATE n_test SET f=N'b'; +SELECT * from n_test; + +delete from n_test where f=N'b'; + +CREATE FUNCTION foo(f varchar default N'a') returns setof varchar as $$SELECT N'a' from n_test;$$ LANGUAGE SQL; + +drop view v; +drop table n_test; +drop table n_test1; +drop function foo(varchar); +drop domain test1_n_domain; +drop domain test2_n_domain; + diff -uNr postgresql-head-20131017/src/test/regress/sql/nchar.sql postgresql-head-20131017-nchar/src/test/regress/sql/nchar.sql --- postgresql-head-20131017/src/test/regress/sql/nchar.sql 1970-01-01 10:00:00.000000000 +1000 +++ postgresql-head-20131017-nchar/src/test/regress/sql/nchar.sql 2013-10-17 11:56:22.000000000 +1100 @@ -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 -uNr postgresql-head-20131017/src/test/regress/sql/nchar_test.sql postgresql-head-20131017-nchar/src/test/regress/sql/nchar_test.sql --- postgresql-head-20131017/src/test/regress/sql/nchar_test.sql 1970-01-01 10:00:00.000000000 +1000 +++ postgresql-head-20131017-nchar/src/test/regress/sql/nchar_test.sql 2013-10-17 11:56:22.000000000 +1100 @@ -0,0 +1,101 @@ + +CREATE AGGREGATE test_nchar_agg (nchar(10)) ( sfunc = array_append, stype = nchar(10)[], initcond = '{}'); + +alter aggregate test_nchar_agg (nchar(10)) rename to test_nchar_aggregate; + +drop aggregate test_nchar_aggregate(nchar(10)); + +create domain test_nchar_domain as nchar(10); + +drop domain test_nchar_domain; + +create table nchar_test (f nchar(10), val varchar); + +create index i on nchar_test(f); + +vacuum analyze nchar_test(f); + +insert into nchar_test values ('a', 'test_val') returning (f); +SELECT f from nchar_test; + +select f into nchar_test1 from nchar_test; +select * from nchar_test1; + +drop table nchar_test1; + +select f from nchar_test; +select val from nchar_test where f='a'; + +prepare stmt AS select f from nchar_test; +prepare stmt1(nchar(10)) AS select val from nchar_test where f=$1; + +deallocate stmt; +deallocate stmt1; + +prepare stmt(varchar) AS select val from nchar_test where f=$1; +execute stmt('a'); + +deallocate stmt; + +begin;declare c cursor for select f from nchar_test;commit; + +create view v as select f from nchar_test; +select * from v; + +alter view v alter column f set default 'a'; + +drop view v; + +do $$begin perform f from nchar_test; end $$; + +CREATE TYPE test_nchar_type AS (f nchar(10)); + +comment on type test_nchar_type is 'comment'; + +drop type test_nchar_type; + +create trigger tr before update on nchar_test for each row when (OLD.f='a') EXECUTE PROCEDURE suppress_redundant_updates_trigger(); + +copy nchar_test(f) to stdout; + +comment on COLUMN nchar_test.f is 'comment'; + +analyze nchar_test(f); + +alter table nchar_test rename f to f_renamed; +alter table nchar_test rename f_renamed to f; + +alter table nchar_test alter val type nchar(10); + +UPDATE nchar_test SET f='b'; +SELECT * from nchar_test; + +delete from nchar_test where f='b'; + +CREATE FUNCTION foo(f nchar(10)) returns setof nchar(10) as $$SELECT f from nchar_test;$$ LANGUAGE SQL; + +alter function foo(nchar(10)) reset all; + +drop function foo(nchar(10)); + +drop table nchar_test; + +create function dummy_eq (nchar, nchar) returns boolean as 'SELECT $1=$2;' LANGUAGE SQL; +CREATE OPERATOR === (LEFTARG = nchar, RIGHTARG = nchar, PROCEDURE = dummy_eq); +alter operator === (nchar,nchar) set schema pg_catalog; +DROP OPERATOR === (nchar,nchar); +drop function dummy_eq (nchar, nchar); + +create cast (nchar as bytea) with FUNCTION nbpcharsend(nchar); +drop cast (nchar as bytea); + +create foreign data wrapper dummy; +CREATE SERVER foo FOREIGN DATA WRAPPER "dummy"; +create foreign table ft_nchar (f nchar(10), var varchar) server foo; +alter foreign table ft_nchar alter var type nchar(10); +alter foreign table ft_nchar rename column f to f_new; +drop foreign table ft_nchar; +drop SERVER foo; +drop foreign data wrapper dummy; + + diff -uNr postgresql-head-20131017/src/test/regress/sql/nvarchar.sql postgresql-head-20131017-nchar/src/test/regress/sql/nvarchar.sql --- postgresql-head-20131017/src/test/regress/sql/nvarchar.sql 1970-01-01 10:00:00.000000000 +1000 +++ postgresql-head-20131017-nchar/src/test/regress/sql/nvarchar.sql 2013-10-17 11:56:22.000000000 +1100 @@ -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 nvarchar +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 nvarchar +-- + +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 -uNr postgresql-head-20131017/src/test/regress/sql/nvarchar_misc.sql postgresql-head-20131017-nchar/src/test/regress/sql/nvarchar_misc.sql --- postgresql-head-20131017/src/test/regress/sql/nvarchar_misc.sql 1970-01-01 10:00:00.000000000 +1000 +++ postgresql-head-20131017-nchar/src/test/regress/sql/nvarchar_misc.sql 2013-10-17 11:56:22.000000000 +1100 @@ -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 -uNr postgresql-head-20131017/src/test/regress/sql/nvarchar_test.sql postgresql-head-20131017-nchar/src/test/regress/sql/nvarchar_test.sql --- postgresql-head-20131017/src/test/regress/sql/nvarchar_test.sql 1970-01-01 10:00:00.000000000 +1000 +++ postgresql-head-20131017-nchar/src/test/regress/sql/nvarchar_test.sql 2013-10-17 11:56:22.000000000 +1100 @@ -0,0 +1,101 @@ + +CREATE AGGREGATE test_nvarchar_agg (nvarchar) ( sfunc = array_append, stype = nvarchar[], initcond = '{}'); + +alter aggregate test_nvarchar_agg (nvarchar) rename to test_nvarchar_aggregate; + +drop aggregate test_nvarchar_aggregate(nvarchar); + +create domain test_nvarchar_domain as nvarchar; + +drop domain test_nvarchar_domain; + +create table nvarchar_test (f nvarchar, val varchar); + +create index i on nvarchar_test(f); + +vacuum analyze nvarchar_test(f); + +insert into nvarchar_test values ('a', 'test_val') returning (f); +SELECT f from nvarchar_test; + +select f into nvarchar_test1 from nvarchar_test; +select * from nvarchar_test1; + +drop table nvarchar_test1; + +select f from nvarchar_test; +select val from nvarchar_test where f='a'; + +prepare stmt AS select f from nvarchar_test; +prepare stmt1(nvarchar) AS select val from nvarchar_test where f=$1; + +deallocate stmt; +deallocate stmt1; + +prepare stmt(varchar) AS select val from nvarchar_test where f=$1; +execute stmt('a'); + +deallocate stmt; + +begin;declare c cursor for select f from nvarchar_test;commit; + +create view v as select f from nvarchar_test; +select * from v; + +alter view v alter column f set default 'a'; + +drop view v; + +do $$begin perform f from nvarchar_test; end $$; + +CREATE TYPE test_nvarchar_type AS (f nvarchar); + +comment on type test_nvarchar_type is 'comment'; + +drop type test_nvarchar_type; + +create trigger tr before update on nvarchar_test for each row when (OLD.f='a') EXECUTE PROCEDURE suppress_redundant_updates_trigger(); + +copy nvarchar_test(f) to stdout; + +comment on COLUMN nvarchar_test.f is 'comment'; + +analyze nvarchar_test(f); + +alter table nvarchar_test rename f to f_renamed; +alter table nvarchar_test rename f_renamed to f; + +alter table nvarchar_test alter val type nvarchar; + +UPDATE nvarchar_test SET f='b'; +SELECT * from nvarchar_test; + +delete from nvarchar_test where f='b'; + +CREATE FUNCTION foo(f nvarchar) returns setof nvarchar as $$SELECT f from nvarchar_test;$$ LANGUAGE SQL; + +alter function foo(nvarchar) reset all; + +drop function foo(nvarchar); + +drop table nvarchar_test; + +create function dummy_eq (nvarchar, nvarchar) returns boolean as 'SELECT $1=$2;' LANGUAGE SQL; +CREATE OPERATOR === (LEFTARG = nvarchar, RIGHTARG = nvarchar, PROCEDURE = dummy_eq); +alter operator === (nvarchar,nvarchar) set schema pg_catalog; +DROP OPERATOR === (nvarchar,nvarchar); +drop function dummy_eq (nvarchar, nvarchar); + +create cast (name as nvarchar) with FUNCTION "nvarchar"(name); +drop cast (name as nvarchar); + +create foreign data wrapper dummy; +CREATE SERVER foo FOREIGN DATA WRAPPER "dummy"; +create foreign table ft_nvarchar (f nvarchar, var varchar) server foo; +alter foreign table ft_nvarchar alter var type nvarchar; +alter foreign table ft_nvarchar rename column f to f_new; +drop foreign table ft_nvarchar; +drop SERVER foo; +drop foreign data wrapper dummy; + + diff -uNr postgresql-head-20131017/src/test/regress/sql/strings.sql postgresql-head-20131017-nchar/src/test/regress/sql/strings.sql --- postgresql-head-20131017/src/test/regress/sql/strings.sql 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/test/regress/sql/strings.sql 2013-10-31 11:26:49.000000000 +1100 @@ -70,26 +70,36 @@ -- 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 @@ -330,10 +340,13 @@ 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 diff -uNr postgresql-head-20131017/src/test/regress/sql/union.sql postgresql-head-20131017-nchar/src/test/regress/sql/union.sql --- postgresql-head-20131017/src/test/regress/sql/union.sql 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/test/regress/sql/union.sql 2013-10-17 11:56:22.000000000 +1100 @@ -89,6 +89,23 @@ 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 -- diff -uNr postgresql-head-20131017/src/test/regress/sql/update.sql postgresql-head-20131017-nchar/src/test/regress/sql/update.sql --- postgresql-head-20131017/src/test/regress/sql/update.sql 2013-10-17 04:22:55.000000000 +1100 +++ postgresql-head-20131017-nchar/src/test/regress/sql/update.sql 2013-10-17 11:56:22.000000000 +1100 @@ -5,14 +5,28 @@ 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;