Ah. Finally after trying to stare down the code for some more time the issue 
is pretty simple.

index_getprocinfo did this:

        /* Initialize the lookup info if first time through */
        if (locinfo->fn_oid == InvalidOid)
        {
...
                fmgr_info_cxt(procId, locinfo, irel->rd_indexcxt);
                
fmgr_info_collation(irel->rd_index->indcollation.values[attnum-1],
                                                        locinfo);
        }

which is not a good idea because irel->rd_index->indcollation is  field after 
the variable lenght indkey field.
Indkey is of int2vector type which is important because it means that there is 
enough space for a second key without making direct access to indcollation 
wrong (which is 4byte alligned). That explains why the issue could only be 
triggered by a composite index covering at least 3 columns...

RelationInitIndexAccessInfo already fills the more convenient 
Relation.rd_indcollation which makes the fix trivial.

It was a good bug though, because now I understand the relcache to some degree 
which I formerly definitely did not ;-)


On Saturday 05 March 2011 18:37:30 Andres Freund wrote:
> test=# CREATE TABLE foo(a int, b text, c int);
> CREATE TABLE
> Time: 65.535 ms
> 
> test=# INSERT INTO foo VALUES (1, '1', 2);
> INSERT 0 1
> Time: 66.777 ms
> 
> test=# INSERT INTO foo VALUES (1, '2', 2);
> INSERT 0 1
> Time: 40.687 ms

> test=# CREATE INDEX foo_abc ON foo (a, b,c);
> ERROR:  locale operation to be invoked, but no collation was derived

Fixed after applying the patch.

Andres
From 91cf261c2af263e0965f5b302129730a7530ff38 Mon Sep 17 00:00:00 2001
From: Andres Freund <and...@anarazel.de>
Date: Sat, 5 Mar 2011 23:45:22 +0100
Subject: [PATCH] Fix one more 'locale operation to be invoked, but no collation was derived' error

The error was caused by directly accessing Relation.rd_index.indcollation.
The latter is positioned after a variable length field and thus cannot be
accessed directly. Instead use Relation.indcollation which is provided for
that purpose.
---
 src/backend/access/index/indexam.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c
index 6e6af18..f489400 100644
--- a/src/backend/access/index/indexam.c
+++ b/src/backend/access/index/indexam.c
@@ -872,7 +872,7 @@ index_getprocinfo(Relation irel,
 				 procnum, attnum, RelationGetRelationName(irel));
 
 		fmgr_info_cxt(procId, locinfo, irel->rd_indexcxt);
-		fmgr_info_collation(irel->rd_index->indcollation.values[attnum-1],
+		fmgr_info_collation(irel->rd_indcollation[attnum-1],
 							locinfo);
 	}
 
-- 
1.7.1

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to