]> granicus.if.org Git - postgresql/commitdiff
Improve reporting of run-time-detected indeterminate-collation errors.
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 22 Mar 2011 20:55:32 +0000 (16:55 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 22 Mar 2011 20:55:32 +0000 (16:55 -0400)
pg_newlocale_from_collation does not have enough context to give an error
message that's even a little bit useful, so move the responsibility for
complaining up to its callers.  Also, reword ERRCODE_INDETERMINATE_COLLATION
error messages in a less jargony, more message-style-guide-compliant
fashion.

src/backend/commands/collationcmds.c
src/backend/commands/indexcmds.c
src/backend/commands/view.c
src/backend/utils/adt/formatting.c
src/backend/utils/adt/pg_locale.c
src/backend/utils/adt/varlena.c
src/test/regress/expected/collate.linux.utf8.out
src/test/regress/expected/collate.out

index 6dafb7223c42d4867a0526e72c5b02225bf42f8a..2a6938fd04bcd1f757e4d6562fc3389093155022 100644 (file)
@@ -141,7 +141,7 @@ DefineCollation(List *names, List *parameters)
 
        /* check that the locales can be loaded */
        CommandCounterIncrement();
-       pg_newlocale_from_collation(newoid);
+       (void) pg_newlocale_from_collation(newoid);
 }
 
 /*
index 163980bbfa342df1b5f267c98ede1ea54f32b6f8..dafa6d5efc16e424d4ee5de030899f6fb6cc682a 100644 (file)
@@ -899,7 +899,7 @@ ComputeIndexAttrs(IndexInfo *indexInfo,
                        if (!OidIsValid(attcollation))
                                ereport(ERROR,
                                                (errcode(ERRCODE_INDETERMINATE_COLLATION),
-                                                errmsg("no collation was derived for the index expression"),
+                                                errmsg("could not determine which collation to use for index expression"),
                                                 errhint("Use the COLLATE clause to set the collation explicitly.")));
                }
                else
index 250d02605cf4f46ff20d4fe9e59e6438dc4feda7..508fb23c9ac14a40daa58d39cabc9eeef10a858c 100644 (file)
@@ -139,7 +139,7 @@ DefineVirtualRelation(const RangeVar *relation, List *tlist, bool replace)
                                if (!OidIsValid(def->collOid))
                                        ereport(ERROR,
                                                        (errcode(ERRCODE_INDETERMINATE_COLLATION),
-                                                        errmsg("no collation was derived for view column \"%s\"",
+                                                        errmsg("could not determine which collation to use for view column \"%s\"",
                                                                        def->colname),
                                                         errhint("Use the COLLATE clause to set the collation explicitly.")));
                        }
index 54783103a2c59e6e8fc3822332213c7acc408d5d..45e36f92e5013a0ff745688d60dd48ffc917dac0 100644 (file)
@@ -1503,7 +1503,20 @@ str_tolower(const char *buff, size_t nbytes, Oid collid)
                size_t          result_size;
 
                if (collid != DEFAULT_COLLATION_OID)
+               {
+                       if (!OidIsValid(collid))
+                       {
+                               /*
+                                * This typically means that the parser could not resolve a
+                                * conflict of implicit collations, so report it that way.
+                                */
+                               ereport(ERROR,
+                                               (errcode(ERRCODE_INDETERMINATE_COLLATION),
+                                                errmsg("could not determine which collation to use for lower() function"),
+                                                errhint("Use the COLLATE clause to set the collation explicitly.")));
+                       }
                        mylocale = pg_newlocale_from_collation(collid);
+               }
 
                /* Overflow paranoia */
                if ((nbytes + 1) > (INT_MAX / sizeof(wchar_t)))
@@ -1540,7 +1553,20 @@ str_tolower(const char *buff, size_t nbytes, Oid collid)
                char       *p;
 
                if (collid != DEFAULT_COLLATION_OID)
+               {
+                       if (!OidIsValid(collid))
+                       {
+                               /*
+                                * This typically means that the parser could not resolve a
+                                * conflict of implicit collations, so report it that way.
+                                */
+                               ereport(ERROR,
+                                               (errcode(ERRCODE_INDETERMINATE_COLLATION),
+                                                errmsg("could not determine which collation to use for lower() function"),
+                                                errhint("Use the COLLATE clause to set the collation explicitly.")));
+                       }
                        mylocale = pg_newlocale_from_collation(collid);
+               }
 
                result = pnstrdup(buff, nbytes);
 
@@ -1598,7 +1624,20 @@ str_toupper(const char *buff, size_t nbytes, Oid collid)
                size_t          result_size;
 
                if (collid != DEFAULT_COLLATION_OID)
+               {
+                       if (!OidIsValid(collid))
+                       {
+                               /*
+                                * This typically means that the parser could not resolve a
+                                * conflict of implicit collations, so report it that way.
+                                */
+                               ereport(ERROR,
+                                               (errcode(ERRCODE_INDETERMINATE_COLLATION),
+                                                errmsg("could not determine which collation to use for upper() function"),
+                                                errhint("Use the COLLATE clause to set the collation explicitly.")));
+                       }
                        mylocale = pg_newlocale_from_collation(collid);
+               }
 
                /* Overflow paranoia */
                if ((nbytes + 1) > (INT_MAX / sizeof(wchar_t)))
@@ -1635,7 +1674,20 @@ str_toupper(const char *buff, size_t nbytes, Oid collid)
                char       *p;
 
                if (collid != DEFAULT_COLLATION_OID)
+               {
+                       if (!OidIsValid(collid))
+                       {
+                               /*
+                                * This typically means that the parser could not resolve a
+                                * conflict of implicit collations, so report it that way.
+                                */
+                               ereport(ERROR,
+                                               (errcode(ERRCODE_INDETERMINATE_COLLATION),
+                                                errmsg("could not determine which collation to use for upper() function"),
+                                                errhint("Use the COLLATE clause to set the collation explicitly.")));
+                       }
                        mylocale = pg_newlocale_from_collation(collid);
+               }
 
                result = pnstrdup(buff, nbytes);
 
@@ -1705,7 +1757,20 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
                size_t          result_size;
 
                if (collid != DEFAULT_COLLATION_OID)
+               {
+                       if (!OidIsValid(collid))
+                       {
+                               /*
+                                * This typically means that the parser could not resolve a
+                                * conflict of implicit collations, so report it that way.
+                                */
+                               ereport(ERROR,
+                                               (errcode(ERRCODE_INDETERMINATE_COLLATION),
+                                                errmsg("could not determine which collation to use for initcap() function"),
+                                                errhint("Use the COLLATE clause to set the collation explicitly.")));
+                       }
                        mylocale = pg_newlocale_from_collation(collid);
+               }
 
                /* Overflow paranoia */
                if ((nbytes + 1) > (INT_MAX / sizeof(wchar_t)))
@@ -1754,7 +1819,20 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
                char       *p;
 
                if (collid != DEFAULT_COLLATION_OID)
+               {
+                       if (!OidIsValid(collid))
+                       {
+                               /*
+                                * This typically means that the parser could not resolve a
+                                * conflict of implicit collations, so report it that way.
+                                */
+                               ereport(ERROR,
+                                               (errcode(ERRCODE_INDETERMINATE_COLLATION),
+                                                errmsg("could not determine which collation to use for initcap() function"),
+                                                errhint("Use the COLLATE clause to set the collation explicitly.")));
+                       }
                        mylocale = pg_newlocale_from_collation(collid);
+               }
 
                result = pnstrdup(buff, nbytes);
 
index 15d347c4f89ed671ff64ada48d2f2dff2fd263be..163856d5b18d24ce2a6e5667bd75a71d2c153a39 100644 (file)
@@ -932,21 +932,13 @@ pg_newlocale_from_collation(Oid collid)
 {
        collation_cache_entry *cache_entry;
 
+       /* Callers must pass a valid OID */
+       Assert(OidIsValid(collid));
+
        /* Return 0 for "default" collation, just in case caller forgets */
        if (collid == DEFAULT_COLLATION_OID)
                return (pg_locale_t) 0;
 
-       /*
-        * This is where we'll fail if a collation-aware function is invoked
-        * and no collation OID is passed.  This typically means that the
-        * parser could not resolve a conflict of implicit collations, so
-        * report it that way.
-        */
-       if (!OidIsValid(collid))
-               ereport(ERROR,
-                               (errcode(ERRCODE_INDETERMINATE_COLLATION),
-                                errmsg("locale operation to be invoked, but no collation was derived")));
-
        cache_entry = lookup_collation_cache(collid, false);
 
        if (cache_entry->locale == 0)
index 8a7a3cf45bfa79b9f19668711a43fbd8378fa286..3587fe4595189c242dec29e28a3ada55f16e53ec 100644 (file)
@@ -1302,7 +1302,20 @@ varstr_cmp(char *arg1, int len1, char *arg2, int len2, Oid collid)
                pg_locale_t     mylocale = 0;
 
                if (collid != DEFAULT_COLLATION_OID)
+               {
+                       if (!OidIsValid(collid))
+                       {
+                               /*
+                                * This typically means that the parser could not resolve a
+                                * conflict of implicit collations, so report it that way.
+                                */
+                               ereport(ERROR,
+                                               (errcode(ERRCODE_INDETERMINATE_COLLATION),
+                                                errmsg("could not determine which collation to use for string comparison"),
+                                                errhint("Use the COLLATE clause to set the collation explicitly.")));
+                       }
                        mylocale = pg_newlocale_from_collation(collid);
+               }
 
 #ifdef WIN32
                /* Win32 does not have UTF-8, so we need to map to UTF-16 */
index 0ed0b36da793f08aafb5efe5b53be19cff005bee..b03395b35a9a7f6e76ec4504f5c8de2335749068 100644 (file)
@@ -586,7 +586,8 @@ SELECT a, b FROM collate_test3 EXCEPT SELECT a, b FROM collate_test3 WHERE a < 2
 (3 rows)
 
 SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test3 ORDER BY 2; -- fail
-ERROR:  locale operation to be invoked, but no collation was derived
+ERROR:  could not determine which collation to use for string comparison
+HINT:  Use the COLLATE clause to set the collation explicitly.
 SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test3; -- ok
  a |  b  
 ---+-----
@@ -629,7 +630,8 @@ ERROR:  no collation was derived for column "b" with collatable type text
 HINT:  Use the COLLATE clause to set the collation explicitly.
 -- ideally this would be a parse-time error, but for now it must be run-time:
 select x < y from collate_test10; -- fail
-ERROR:  locale operation to be invoked, but no collation was derived
+ERROR:  could not determine which collation to use for string comparison
+HINT:  Use the COLLATE clause to set the collation explicitly.
 select x || y from collate_test10; -- ok, because || is not collation aware
  ?column? 
 ----------
index 4536cf21015946855512647389641833b9d17563..0ed9601bf2147448b365d0c2249fc68989c77198 100644 (file)
@@ -392,7 +392,8 @@ SELECT a, b FROM collate_test2 EXCEPT SELECT a, b FROM collate_test2 WHERE a < 2
 (3 rows)
 
 SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test2 ORDER BY 2; -- fail
-ERROR:  locale operation to be invoked, but no collation was derived
+ERROR:  could not determine which collation to use for string comparison
+HINT:  Use the COLLATE clause to set the collation explicitly.
 SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test2; -- ok
  a |  b  
 ---+-----
@@ -435,7 +436,8 @@ ERROR:  no collation was derived for column "b" with collatable type text
 HINT:  Use the COLLATE clause to set the collation explicitly.
 -- ideally this would be a parse-time error, but for now it must be run-time:
 select x < y from collate_test10; -- fail
-ERROR:  locale operation to be invoked, but no collation was derived
+ERROR:  could not determine which collation to use for string comparison
+HINT:  Use the COLLATE clause to set the collation explicitly.
 select x || y from collate_test10; -- ok, because || is not collation aware
  ?column? 
 ----------