setting up scan keys - Mailing list pgsql-hackers

From Markus Wanner
Subject setting up scan keys
Date
Msg-id 20090825120818.34597m7kez6fs3ki@mail.bluegap.ch
Whole thread Raw
Responses Re: setting up scan keys  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-hackers
Hi,

I'm currently having difficulties understanding how to setup scan keys
for simple index scans. What I want to achieve is scanning a primary
key index (thus unique constraint - and as far as I know only nbtree
can handle these, right?).

Up until now I've used something along the following lines to setup
the scan keys for a BTGreaterStrategy scan:
        procinfo = index_getprocinfo(index_rel, i + 1, BTORDER_PROC);        ScanKeyEntryInitializeWithInfo(&skeys[i],
                                    SK_ROW_MEMBER,                                       (AttrNumber) (i + 1),
                            strategy,                                       InvalidOid,
     procinfo,                                       value); 

That seems to work for that strategy. However, when using the same for
BTEqualStrategy, the scan doesn't return any tuple (although I'm
pretty sure it should return exactly one).

Reading src/backend/access/nbtree/README and various code in the same
directory, I've learned that these scan keys are used in two different
ways: "search" and "insertion" scan keys. AFAIU, I'm setting up an
insertion scan key, due to using the BTORDER_PROC directly (in my case
that's mostly btint4cmp). But it also looks like that's just an
(nbtree-)internal representation. I don't see
ScanKeyEntryInitializeWithInfo used anywhere outside of that code.

Now I'm trying with something more like:
        get_sort_group_operators(tdesc->attrs[attnum-1]->atttypid,                                 false, true, true,
                             NULL, &eq_func, >_func); 
        if (strategy == BTEqualStrategyNumber)            regproc = get_opcode(eq_func);        else if (strategy ==
BTGreaterStrategyNumber)           regproc = get_opcode(gt_func);        else            Assert(false); 
        ScanKeyEntryInitialize(&skeys[i],                               SK_ROW_MEMBER,
(AttrNumber)(i + 1),                               strategy,                               InvalidOid,
            regproc,                               value); 

That still triggers an assertion for me, not quite sure why. But is
this the preferred way? Or am I better off fiddling with the first
variant and get that to run?

I'm using the scan keys later on with simple index_beginscan(),
index_rescan() and index_getnext(). My goal is to support any kind of
UNIQUE INDEX, always with all attributes of the index.

Any enlightening comments on this duplicate use of ScanKeyData?

Help is greatly appreciated.

Regards

Markus Wanner



pgsql-hackers by date:

Previous
From: Jean-Michel Pouré
Date:
Subject: Re: DELETE syntax on JOINS
Next
From: Paul Matthews
Date:
Subject: Re: Slaying the HYPOTamus