diff options
Diffstat (limited to 'src/backend/access/gist')
-rw-r--r-- | src/backend/access/gist/gist.c | 24 | ||||
-rw-r--r-- | src/backend/access/gist/gistget.c | 4 | ||||
-rw-r--r-- | src/backend/access/gist/gistutil.c | 42 | ||||
-rw-r--r-- | src/backend/access/gist/gistvalidate.c | 3 |
4 files changed, 61 insertions, 12 deletions
diff --git a/src/backend/access/gist/gist.c b/src/backend/access/gist/gist.c index 565525bbdfc..aec174cd006 100644 --- a/src/backend/access/gist/gist.c +++ b/src/backend/access/gist/gist.c @@ -1453,12 +1453,23 @@ initGISTstate(Relation index) fmgr_info_copy(&(giststate->unionFn[i]), index_getprocinfo(index, i + 1, GIST_UNION_PROC), scanCxt); - fmgr_info_copy(&(giststate->compressFn[i]), - index_getprocinfo(index, i + 1, GIST_COMPRESS_PROC), - scanCxt); - fmgr_info_copy(&(giststate->decompressFn[i]), - index_getprocinfo(index, i + 1, GIST_DECOMPRESS_PROC), - scanCxt); + + /* opclasses are not required to provide a Compress method */ + if (OidIsValid(index_getprocid(index, i + 1, GIST_COMPRESS_PROC))) + fmgr_info_copy(&(giststate->compressFn[i]), + index_getprocinfo(index, i + 1, GIST_COMPRESS_PROC), + scanCxt); + else + giststate->compressFn[i].fn_oid = InvalidOid; + + /* opclasses are not required to provide a Decompress method */ + if (OidIsValid(index_getprocid(index, i + 1, GIST_DECOMPRESS_PROC))) + fmgr_info_copy(&(giststate->decompressFn[i]), + index_getprocinfo(index, i + 1, GIST_DECOMPRESS_PROC), + scanCxt); + else + giststate->decompressFn[i].fn_oid = InvalidOid; + fmgr_info_copy(&(giststate->penaltyFn[i]), index_getprocinfo(index, i + 1, GIST_PENALTY_PROC), scanCxt); @@ -1468,6 +1479,7 @@ initGISTstate(Relation index) fmgr_info_copy(&(giststate->equalFn[i]), index_getprocinfo(index, i + 1, GIST_EQUAL_PROC), scanCxt); + /* opclasses are not required to provide a Distance method */ if (OidIsValid(index_getprocid(index, i + 1, GIST_DISTANCE_PROC))) fmgr_info_copy(&(giststate->distanceFn[i]), diff --git a/src/backend/access/gist/gistget.c b/src/backend/access/gist/gistget.c index 760ea0c997e..06dac0bb53d 100644 --- a/src/backend/access/gist/gistget.c +++ b/src/backend/access/gist/gistget.c @@ -801,11 +801,13 @@ gistgetbitmap(IndexScanDesc scan, TIDBitmap *tbm) * Can we do index-only scans on the given index column? * * Opclasses that implement a fetch function support index-only scans. + * Opclasses without compression functions also support index-only scans. */ bool gistcanreturn(Relation index, int attno) { - if (OidIsValid(index_getprocid(index, attno, GIST_FETCH_PROC))) + if (OidIsValid(index_getprocid(index, attno, GIST_FETCH_PROC)) || + !OidIsValid(index_getprocid(index, attno, GIST_COMPRESS_PROC))) return true; else return false; diff --git a/src/backend/access/gist/gistutil.c b/src/backend/access/gist/gistutil.c index b6ccc1a66a1..26d89f79ae6 100644 --- a/src/backend/access/gist/gistutil.c +++ b/src/backend/access/gist/gistutil.c @@ -550,6 +550,11 @@ gistdentryinit(GISTSTATE *giststate, int nkey, GISTENTRY *e, GISTENTRY *dep; gistentryinit(*e, k, r, pg, o, l); + + /* there may not be a decompress function in opclass */ + if (!OidIsValid(giststate->decompressFn[nkey].fn_oid)) + return; + dep = (GISTENTRY *) DatumGetPointer(FunctionCall1Coll(&giststate->decompressFn[nkey], giststate->supportCollation[nkey], @@ -585,10 +590,14 @@ gistFormTuple(GISTSTATE *giststate, Relation r, gistentryinit(centry, attdata[i], r, NULL, (OffsetNumber) 0, isleaf); - cep = (GISTENTRY *) - DatumGetPointer(FunctionCall1Coll(&giststate->compressFn[i], - giststate->supportCollation[i], - PointerGetDatum(¢ry))); + /* there may not be a compress function in opclass */ + if (OidIsValid(giststate->compressFn[i].fn_oid)) + cep = (GISTENTRY *) + DatumGetPointer(FunctionCall1Coll(&giststate->compressFn[i], + giststate->supportCollation[i], + PointerGetDatum(¢ry))); + else + cep = ¢ry; compatt[i] = cep->key; } } @@ -648,6 +657,17 @@ gistFetchTuple(GISTSTATE *giststate, Relation r, IndexTuple tuple) else fetchatt[i] = (Datum) 0; } + else if (giststate->compressFn[i].fn_oid == InvalidOid) + { + /* + * If opclass does not provide compress method that could change + * original value, att is necessarily stored in original form. + */ + if (!isnull[i]) + fetchatt[i] = datum; + else + fetchatt[i] = (Datum) 0; + } else { /* @@ -934,6 +954,20 @@ gistproperty(Oid index_oid, int attno, ObjectIdGetDatum(opcintype), ObjectIdGetDatum(opcintype), Int16GetDatum(procno)); + + /* + * Special case: even without a fetch function, AMPROP_RETURNABLE is true + * if the opclass has no compress function. + */ + if (prop == AMPROP_RETURNABLE && !*res) + { + *res = !SearchSysCacheExists4(AMPROCNUM, + ObjectIdGetDatum(opfamily), + ObjectIdGetDatum(opcintype), + ObjectIdGetDatum(opcintype), + Int16GetDatum(GIST_COMPRESS_PROC)); + } + return true; } diff --git a/src/backend/access/gist/gistvalidate.c b/src/backend/access/gist/gistvalidate.c index 42254c5f153..42f91ac0c96 100644 --- a/src/backend/access/gist/gistvalidate.c +++ b/src/backend/access/gist/gistvalidate.c @@ -258,7 +258,8 @@ gistvalidate(Oid opclassoid) if (opclassgroup && (opclassgroup->functionset & (((uint64) 1) << i)) != 0) continue; /* got it */ - if (i == GIST_DISTANCE_PROC || i == GIST_FETCH_PROC) + if (i == GIST_DISTANCE_PROC || i == GIST_FETCH_PROC || + i == GIST_COMPRESS_PROC || i == GIST_DECOMPRESS_PROC) continue; /* optional methods */ ereport(INFO, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), |