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);
pg_typeof
+
+collation for
+
+
lists functions that
extract information from the system catalogs.
@@ -13790,6 +13794,11 @@ SELECT pg_type_is_visible('myschema.widget'::regtype);
regtype
get the data type of any value
+
+ collation for (any)
+ text
+ get the collation of the argument
+
@@ -13916,6 +13925,27 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33);
+
+ The expression collation for returns the collation of the
+ value that is passed to it. Example:
+
+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)
+
+ 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.
+
+
col_description
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_typeofPGNSP 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 "2