Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit3a0a16c

Browse files
committed
Allow row comparisons to be used as indexscan qualifications.
This completes the project to upgrade our handling of row comparisons.
1 parent06d45e4 commit3a0a16c

File tree

11 files changed

+996
-142
lines changed

11 files changed

+996
-142
lines changed

‎src/backend/access/nbtree/nbtsearch.c

Lines changed: 85 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.101 2006/01/23 22:31:40 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.102 2006/01/25 20:29:23 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -551,6 +551,10 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
551551
* one we use --- by definition, they are either redundant or
552552
* contradictory.
553553
*
554+
* In this loop, row-comparison keys are treated the same as keys on their
555+
* first (leftmost) columns. We'll add on lower-order columns of the row
556+
* comparison below, if possible.
557+
*
554558
* The selected scan keys (at most one per index column) are remembered by
555559
* storing their addresses into the local startKeys[] array.
556560
*----------
@@ -657,44 +661,91 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
657661
{
658662
ScanKeycur=startKeys[i];
659663

660-
/*
661-
* _bt_preprocess_keys disallows it, but it's place to add some code
662-
* later
663-
*/
664-
if (cur->sk_flags&SK_ISNULL)
665-
elog(ERROR,"btree doesn't support is(not)null, yet");
664+
Assert(cur->sk_attno==i+1);
666665

667-
/*
668-
* If scankey operator is of default subtype, we can use the cached
669-
* comparison procedure; otherwise gotta look it up in the catalogs.
670-
*/
671-
if (cur->sk_subtype==InvalidOid)
666+
if (cur->sk_flags&SK_ROW_HEADER)
672667
{
673-
FmgrInfo*procinfo;
674-
675-
procinfo=index_getprocinfo(rel,i+1,BTORDER_PROC);
676-
ScanKeyEntryInitializeWithInfo(scankeys+i,
677-
cur->sk_flags,
678-
i+1,
679-
InvalidStrategy,
680-
InvalidOid,
681-
procinfo,
682-
cur->sk_argument);
668+
/*
669+
* Row comparison header: look to the first row member instead.
670+
*
671+
* The member scankeys are already in insertion format (ie, they
672+
* have sk_func = 3-way-comparison function), but we have to
673+
* watch out for nulls, which _bt_preprocess_keys didn't check.
674+
* A null in the first row member makes the condition unmatchable,
675+
* just like qual_ok = false.
676+
*/
677+
cur= (ScanKey)DatumGetPointer(cur->sk_argument);
678+
Assert(cur->sk_flags&SK_ROW_MEMBER);
679+
if (cur->sk_flags&SK_ISNULL)
680+
return false;
681+
memcpy(scankeys+i,cur,sizeof(ScanKeyData));
682+
/*
683+
* If the row comparison is the last positioning key we accepted,
684+
* try to add additional keys from the lower-order row members.
685+
* (If we accepted independent conditions on additional index
686+
* columns, we use those instead --- doesn't seem worth trying to
687+
* determine which is more restrictive.) Note that this is OK
688+
* even if the row comparison is of ">" or "<" type, because the
689+
* condition applied to all but the last row member is effectively
690+
* ">=" or "<=", and so the extra keys don't break the positioning
691+
* scheme.
692+
*/
693+
if (i==keysCount-1)
694+
{
695+
while (!(cur->sk_flags&SK_ROW_END))
696+
{
697+
cur++;
698+
Assert(cur->sk_flags&SK_ROW_MEMBER);
699+
if (cur->sk_attno!=keysCount+1)
700+
break;/* out-of-sequence, can't use it */
701+
if (cur->sk_flags&SK_ISNULL)
702+
break;/* can't use null keys */
703+
Assert(keysCount<INDEX_MAX_KEYS);
704+
memcpy(scankeys+keysCount,cur,sizeof(ScanKeyData));
705+
keysCount++;
706+
}
707+
break;/* done with outer loop */
708+
}
683709
}
684710
else
685711
{
686-
RegProcedurecmp_proc;
687-
688-
cmp_proc=get_opclass_proc(rel->rd_indclass->values[i],
689-
cur->sk_subtype,
690-
BTORDER_PROC);
691-
ScanKeyEntryInitialize(scankeys+i,
692-
cur->sk_flags,
693-
i+1,
694-
InvalidStrategy,
695-
cur->sk_subtype,
696-
cmp_proc,
697-
cur->sk_argument);
712+
/*
713+
* Ordinary comparison key. Transform the search-style scan key
714+
* to an insertion scan key by replacing the sk_func with the
715+
* appropriate btree comparison function.
716+
*
717+
* If scankey operator is of default subtype, we can use the
718+
* cached comparison function; otherwise gotta look it up in the
719+
* catalogs.
720+
*/
721+
if (cur->sk_subtype==InvalidOid)
722+
{
723+
FmgrInfo*procinfo;
724+
725+
procinfo=index_getprocinfo(rel,cur->sk_attno,BTORDER_PROC);
726+
ScanKeyEntryInitializeWithInfo(scankeys+i,
727+
cur->sk_flags,
728+
cur->sk_attno,
729+
InvalidStrategy,
730+
InvalidOid,
731+
procinfo,
732+
cur->sk_argument);
733+
}
734+
else
735+
{
736+
RegProcedurecmp_proc;
737+
738+
cmp_proc=get_opclass_proc(rel->rd_indclass->values[i],
739+
cur->sk_subtype,
740+
BTORDER_PROC);
741+
ScanKeyEntryInitialize(scankeys+i,
742+
cur->sk_flags,
743+
cur->sk_attno,
744+
InvalidStrategy,
745+
cur->sk_subtype,
746+
cmp_proc,
747+
cur->sk_argument);
748+
}
698749
}
699750
}
700751

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp