On tor, 2012-01-12 at 21:25 -0800, probabble wrote: > Compiling on Ubuntu 10.04 LTS AMD64 on a GoGrid virtual machine from > 2012-01-12 checkout. > > Bison upgraded to v2.5, and downgraded to v2.4.1 > > Make process for both versions resulted in the following errors: > > make[3]: Leaving directory `/usr/local/src/pgbuild/src/backend/catalog' > make -C parser gram.h > make[3]: Entering directory `/usr/local/src/pgbuild/src/backend/parser' > /usr/local/bin/bison -d -o gram.c gram.y > gram.y: conflicts: 370 reduce/reduce > gram.y: expected 0 reduce/reduce conflicts > gram.y:10482.27-10494.33: warning: rule useless in parser due to conflicts: > func_expr: COLLATION FOR '(' a_expr ')' > make[3]: *** [gram.c] Error 1
I can't reproduce that. In the meantime, attached is a re-merged version of the patch; the old version doesn't apply cleanly anymore.
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index ff9b8b0..4d77024 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -13637,6 +13637,10 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); <primary>pg_typeof</primary> </indexterm> + <indexterm> + <primary>collation for</primary> + </indexterm> + <para> <xref linkend="functions-info-catalog-table"> lists functions that extract information from the system catalogs. @@ -13790,6 +13794,11 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); <entry><type>regtype</type></entry> <entry>get the data type of any value</entry> </row> + <row> + <entry><literal><function>collation for (<parameter>any</parameter>)</function></literal></entry> + <entry><type>text</type></entry> + <entry>get the collation of the argument</entry> + </row> </tbody> </tgroup> </table> @@ -13916,6 +13925,27 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); </programlisting> </para> + <para> + The expression <literal>collation for</literal> returns the collation of the + value that is passed to it. Example: +<programlisting> +SELECT collation for (description) FROM pg_description LIMIT 1; + pg_collation_for +------------------ + "default" +(1 row) + +SELECT collation for ('foo' COLLATE "de_DE"); + pg_collation_for +------------------ + "de_DE" +(1 row) +</programlisting> + The value might be quoted and schema-qualified. If no collation is derived + for the argument expression, then a null value is returned. If the argument + is not of a collatable data type, then an error is raised. + </para> + <indexterm> <primary>col_description</primary> </indexterm> diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 0ec039b..dd0e2e8 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -10466,6 +10466,19 @@ func_expr: func_name '(' ')' over_clause n->location = @1; $$ = (Node *)n; } + | COLLATION FOR '(' a_expr ')' + { + FuncCall *n = makeNode(FuncCall); + n->funcname = SystemFuncName("pg_collation_for"); + n->args = list_make1($4); + n->agg_order = NIL; + n->agg_star = FALSE; + n->agg_distinct = FALSE; + n->func_variadic = FALSE; + n->over = NULL; + n->location = @1; + $$ = (Node *)n; + } | CURRENT_DATE { /* @@ -11917,7 +11930,6 @@ unreserved_keyword: | CLASS | CLOSE | CLUSTER - | COLLATION | COMMENT | COMMENTS | COMMIT @@ -12253,6 +12265,7 @@ reserved_keyword: | CAST | CHECK | COLLATE + | COLLATION | COLUMN | CONSTRAINT | CREATE diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c index 3de6a5c..84dad33 100644 --- a/src/backend/utils/adt/misc.c +++ b/src/backend/utils/adt/misc.c @@ -26,12 +26,14 @@ #include "commands/dbcommands.h" #include "funcapi.h" #include "miscadmin.h" +#include "nodes/nodeFuncs.h" #include "parser/keywords.h" #include "postmaster/syslogger.h" #include "storage/fd.h" #include "storage/pmsignal.h" #include "storage/proc.h" #include "storage/procarray.h" +#include "utils/lsyscache.h" #include "tcop/tcopprot.h" #include "utils/builtins.h" #include "utils/timestamp.h" @@ -492,3 +494,29 @@ pg_typeof(PG_FUNCTION_ARGS) { PG_RETURN_OID(get_fn_expr_argtype(fcinfo->flinfo, 0)); } + + +/* + * Implementation of the COLLATE FOR expression; returns the collation + * of the argument. + */ +Datum +pg_collation_for(PG_FUNCTION_ARGS) +{ + Oid typeid; + Oid collid; + + typeid = get_fn_expr_argtype(fcinfo->flinfo, 0); + if (!typeid) + PG_RETURN_NULL(); + if (!type_is_collatable(typeid) && typeid != UNKNOWNOID) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("collations are not supported by type %s", + format_type_be(typeid)))); + + collid = PG_GET_COLLATION(); + if (!collid) + PG_RETURN_NULL(); + PG_RETURN_TEXT_P(cstring_to_text(generate_collation_name(collid))); +} diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index 9994468..e4ea0d5 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -1945,6 +1945,8 @@ DESCR("convert generic options array to name/value table"); DATA(insert OID = 1619 ( pg_typeof PGNSP PGUID 12 1 0 0 0 f f f f f s 1 0 2206 "2276" _null_ _null_ _null_ _null_ pg_typeof _null_ _null_ _null_ )); DESCR("type of the argument"); +DATA(insert OID = 3163 ( pg_collation_for PGNSP PGUID 12 1 0 0 0 f f f f f s 1 0 25 "2276" _null_ _null_ _null_ _null_ pg_collation_for _null_ _null_ _null_ )); +DESCR("collation of the argument; implementation of the COLLATION FOR expression"); /* Deferrable unique constraint trigger */ DATA(insert OID = 1250 ( unique_key_recheck PGNSP PGUID 12 1 0 0 0 f f f t f v 0 0 2279 "" _null_ _null_ _null_ _null_ unique_key_recheck _null_ _null_ _null_ )); diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h index 3d7de06..43933e9 100644 --- a/src/include/parser/kwlist.h +++ b/src/include/parser/kwlist.h @@ -79,7 +79,7 @@ PG_KEYWORD("close", CLOSE, UNRESERVED_KEYWORD) PG_KEYWORD("cluster", CLUSTER, UNRESERVED_KEYWORD) PG_KEYWORD("coalesce", COALESCE, COL_NAME_KEYWORD) PG_KEYWORD("collate", COLLATE, RESERVED_KEYWORD) -PG_KEYWORD("collation", COLLATION, UNRESERVED_KEYWORD) +PG_KEYWORD("collation", COLLATION, RESERVED_KEYWORD) PG_KEYWORD("column", COLUMN, RESERVED_KEYWORD) PG_KEYWORD("comment", COMMENT, UNRESERVED_KEYWORD) PG_KEYWORD("comments", COMMENTS, UNRESERVED_KEYWORD) diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h index 46b2f3b..25b5e72 100644 --- a/src/include/utils/builtins.h +++ b/src/include/utils/builtins.h @@ -480,6 +480,7 @@ extern Datum pg_rotate_logfile(PG_FUNCTION_ARGS); extern Datum pg_sleep(PG_FUNCTION_ARGS); extern Datum pg_get_keywords(PG_FUNCTION_ARGS); extern Datum pg_typeof(PG_FUNCTION_ARGS); +extern Datum pg_collation_for(PG_FUNCTION_ARGS); /* oid.c */ extern Datum oidin(PG_FUNCTION_ARGS); diff --git a/src/test/regress/expected/collate.out b/src/test/regress/expected/collate.out index a15e691..81ac6de 100644 --- a/src/test/regress/expected/collate.out +++ b/src/test/regress/expected/collate.out @@ -577,6 +577,26 @@ RESET enable_nestloop; -- 9.1 bug with useless COLLATE in an expression subject to length coercion CREATE TEMP TABLE vctable (f1 varchar(25)); INSERT INTO vctable VALUES ('foo' COLLATE "C"); +SELECT collation for ('foo'); -- unknown type - null + pg_collation_for +------------------ + +(1 row) + +SELECT collation for ('foo'::text); + pg_collation_for +------------------ + "default" +(1 row) + +SELECT collation for ((SELECT a FROM collate_test1 LIMIT 1)); -- non-collatable type - error +ERROR: collations are not supported by type integer +SELECT collation for ((SELECT b FROM collate_test1 LIMIT 1)); + pg_collation_for +------------------ + "C" +(1 row) + -- -- Clean up. Many of these table names will be re-used if the user is -- trying to run any platform-specific collation tests later, so we diff --git a/src/test/regress/sql/collate.sql b/src/test/regress/sql/collate.sql index f72f3ed..3c960e7 100644 --- a/src/test/regress/sql/collate.sql +++ b/src/test/regress/sql/collate.sql @@ -219,6 +219,13 @@ RESET enable_nestloop; CREATE TEMP TABLE vctable (f1 varchar(25)); INSERT INTO vctable VALUES ('foo' COLLATE "C"); + +SELECT collation for ('foo'); -- unknown type - null +SELECT collation for ('foo'::text); +SELECT collation for ((SELECT a FROM collate_test1 LIMIT 1)); -- non-collatable type - error +SELECT collation for ((SELECT b FROM collate_test1 LIMIT 1)); + + -- -- Clean up. Many of these table names will be re-used if the user is -- trying to run any platform-specific collation tests later, so we
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers