/* Order according to distance comparison */ for (i = 0; i < scan->numberOfOrderBys; i++)
{ if (sa->distances[i].isnull)
{ if (!sb->distances[i].isnull) return -1;
} elseif (sb->distances[i].isnull)
{ return1;
} else
{ int cmp = -float8_cmp_internal(sa->distances[i].value,
sb->distances[i].value);
if (cmp != 0) return cmp;
}
}
/* Heap items go before inner pages, to ensure a depth-first search */ if (GISTSearchItemIsHeap(*sa) && !GISTSearchItemIsHeap(*sb)) return1; if (!GISTSearchItemIsHeap(*sa) && GISTSearchItemIsHeap(*sb)) return -1;
return0;
}
/* *IndexAMAPIfunctionsforscanningGiSTindexes
*/
IndexScanDesc
gistbeginscan(Relation r, int nkeys, int norderbys)
{
IndexScanDesc scan;
GISTSTATE *giststate;
GISTScanOpaque so;
MemoryContext oldCxt;
scan = RelationGetIndexScan(r, nkeys, norderbys);
/* First, set up a GISTSTATE with a scan-lifespan memory context */
giststate = initGISTstate(scan->indexRelation);
void
gistrescan(IndexScanDesc scan, ScanKey key, int nkeys,
ScanKey orderbys, int norderbys)
{ /* nkeys and norderbys arguments are ignored */
GISTScanOpaque so = (GISTScanOpaque) scan->opaque; bool first_time; int i;
MemoryContext oldCxt;
/* rescan an existing indexscan --- reset state */
/* *Thefirsttimethrough,wecreatethesearchqueueinthescanCxt. *Subsequenttimesthrough,wecreatethequeueinaseparatequeueCxt, *whichiscreatedonthesecondcallandresetonlatercalls.Thus,in *thecommoncasewhereascanisonlyrescan'donce,wejustputthe *queueinscanCxtanddon'tpaytheoverheadofmakingasecondmemory *context.Ifwedorescanmorethanonce,thefirstqueueisjustleft *fordeaduntilendofscan;thissmallwastageseemsworththesavings *inthecommoncase.
*/ if (so->queue == NULL)
{ /* first time through */
Assert(so->queueCxt == so->giststate->scanCxt);
first_time = true;
} elseif (so->queueCxt == so->giststate->scanCxt)
{ /* second time through */
so->queueCxt = AllocSetContextCreate(so->giststate->scanCxt, "GiST queue context",
ALLOCSET_DEFAULT_SIZES);
first_time = false;
} else
{ /* third or later time through */
MemoryContextReset(so->queueCxt);
first_time = false;
}
/* *Ifwe'redoinganindex-onlyscan,onthefirstcall,alsoinitializea *tupledescriptortorepresentthereturnedindextuplesandcreatea *memorycontexttoholdthemduringthescan.
*/ if (scan->xs_want_itup && !scan->xs_hitupdesc)
{ int natts; int nkeyatts; int attno;
/* Also create a memory context that will hold the returned tuples */
so->pageDataCxt = AllocSetContextCreate(so->giststate->scanCxt, "GiST page data context",
ALLOCSET_DEFAULT_SIZES);
}
/* Restore prior fn_extra pointers, if not first time */ if (!first_time)
skey->sk_func.fn_extra = fn_extras[i];
if (skey->sk_flags & SK_ISNULL)
{ if (!(skey->sk_flags & (SK_SEARCHNULL | SK_SEARCHNOTNULL)))
so->qual_ok = false;
}
}
if (!first_time)
pfree(fn_extras);
}
/* Update order-by key, if a new one is given */ if (orderbys && scan->numberOfOrderBys > 0)
{ void **fn_extras = NULL;
/* As above, preserve fn_extra if not first time through */ if (!first_time)
{
fn_extras = (void **) palloc(scan->numberOfOrderBys * sizeof(void *)); for (i = 0; i < scan->numberOfOrderBys; i++)
fn_extras[i] = scan->orderByData[i].sk_func.fn_extra;
}
/* *Modifytheorder-bykeysothattheDistancemethodiscalledfor *allcomparisons.TheoriginaloperatorispassedtotheDistance *functionintheformofitsstrategynumber,whichisavailable *fromthesk_strategyfield,anditssubtypefromthesk_subtype *field.
*/ for (i = 0; i < scan->numberOfOrderBys; i++)
{
ScanKey skey = scan->orderByData + i;
FmgrInfo *finfo = &(so->giststate->distanceFn[skey->sk_attno - 1]);
/* Check we actually have a distance function ... */ if (!OidIsValid(finfo->fn_oid))
elog(ERROR, "missing support function %d for attribute %d of index \"%s\"",
GIST_DISTANCE_PROC, skey->sk_attno,
RelationGetRelationName(scan->indexRelation));
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.