summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/access/gist/gistutil.c35
-rw-r--r--src/backend/access/gist/gistvalidate.c2
-rw-r--r--src/backend/catalog/pg_constraint.c20
-rw-r--r--src/backend/commands/indexcmds.c50
-rw-r--r--src/backend/commands/tablecmds.c10
-rw-r--r--src/backend/executor/execReplication.c2
-rw-r--r--src/include/access/gist.h3
-rw-r--r--src/include/catalog/pg_amproc.dat12
-rw-r--r--src/include/catalog/pg_proc.dat6
-rw-r--r--src/include/commands/defrem.h4
-rw-r--r--src/include/nodes/primnodes.h4
-rw-r--r--src/test/regress/expected/misc_functions.out16
-rw-r--r--src/test/regress/sql/misc_functions.sql4
13 files changed, 93 insertions, 75 deletions
diff --git a/src/backend/access/gist/gistutil.c b/src/backend/access/gist/gistutil.c
index a2fcfbe4807..48db718b904 100644
--- a/src/backend/access/gist/gistutil.c
+++ b/src/backend/access/gist/gistutil.c
@@ -1058,27 +1058,44 @@ gistGetFakeLSN(Relation rel)
}
/*
- * Returns the same number that was received.
- *
- * This is for GiST opclasses that use the RT*StrategyNumber constants.
+ * This is a stratnum support function for GiST opclasses that use the
+ * RT*StrategyNumber constants.
*/
Datum
-gist_stratnum_identity(PG_FUNCTION_ARGS)
+gist_stratnum_common(PG_FUNCTION_ARGS)
{
- StrategyNumber strat = PG_GETARG_UINT16(0);
+ CompareType cmptype = PG_GETARG_INT32(0);
- PG_RETURN_UINT16(strat);
+ switch (cmptype)
+ {
+ case COMPARE_EQ:
+ PG_RETURN_UINT16(RTEqualStrategyNumber);
+ case COMPARE_LT:
+ PG_RETURN_UINT16(RTLessStrategyNumber);
+ case COMPARE_LE:
+ PG_RETURN_UINT16(RTLessEqualStrategyNumber);
+ case COMPARE_GT:
+ PG_RETURN_UINT16(RTGreaterStrategyNumber);
+ case COMPARE_GE:
+ PG_RETURN_UINT16(RTGreaterEqualStrategyNumber);
+ case COMPARE_OVERLAP:
+ PG_RETURN_UINT16(RTOverlapStrategyNumber);
+ case COMPARE_CONTAINED_BY:
+ PG_RETURN_UINT16(RTContainedByStrategyNumber);
+ default:
+ PG_RETURN_UINT16(InvalidStrategy);
+ }
}
/*
- * Returns the opclass's private stratnum used for the given strategy.
+ * Returns the opclass's private stratnum used for the given compare type.
*
* Calls the opclass's GIST_STRATNUM_PROC support function, if any,
* and returns the result.
* Returns InvalidStrategy if the function is not defined.
*/
StrategyNumber
-GistTranslateStratnum(Oid opclass, StrategyNumber strat)
+GistTranslateStratnum(Oid opclass, CompareType cmptype)
{
Oid opfamily;
Oid opcintype;
@@ -1095,6 +1112,6 @@ GistTranslateStratnum(Oid opclass, StrategyNumber strat)
return InvalidStrategy;
/* Ask the translation function */
- result = OidFunctionCall1Coll(funcid, InvalidOid, UInt16GetDatum(strat));
+ result = OidFunctionCall1Coll(funcid, InvalidOid, Int32GetDatum(cmptype));
return DatumGetUInt16(result);
}
diff --git a/src/backend/access/gist/gistvalidate.c b/src/backend/access/gist/gistvalidate.c
index 499ed8c8748..bb86b559486 100644
--- a/src/backend/access/gist/gistvalidate.c
+++ b/src/backend/access/gist/gistvalidate.c
@@ -148,7 +148,7 @@ gistvalidate(Oid opclassoid)
break;
case GIST_STRATNUM_PROC:
ok = check_amproc_signature(procform->amproc, INT2OID, true,
- 1, 1, INT2OID);
+ 1, 1, INT4OID);
break;
default:
ereport(INFO,
diff --git a/src/backend/catalog/pg_constraint.c b/src/backend/catalog/pg_constraint.c
index 8693ec3c884..bbf4742e18c 100644
--- a/src/backend/catalog/pg_constraint.c
+++ b/src/backend/catalog/pg_constraint.c
@@ -1647,22 +1647,22 @@ FindFKPeriodOpers(Oid opclass,
* of the old value, then we can treat the attribute as if it didn't
* change, and skip the RI check.
*/
- strat = RTContainedByStrategyNumber;
- GetOperatorFromWellKnownStrategy(opclass,
- InvalidOid,
- containedbyoperoid,
- &strat);
+ GetOperatorFromCompareType(opclass,
+ InvalidOid,
+ COMPARE_CONTAINED_BY,
+ containedbyoperoid,
+ &strat);
/*
* Now look up the ContainedBy operator. Its left arg must be the type of
* the column (or rather of the opclass). Its right arg must match the
* return type of the support proc.
*/
- strat = RTContainedByStrategyNumber;
- GetOperatorFromWellKnownStrategy(opclass,
- ANYMULTIRANGEOID,
- aggedcontainedbyoperoid,
- &strat);
+ GetOperatorFromCompareType(opclass,
+ ANYMULTIRANGEOID,
+ COMPARE_CONTAINED_BY,
+ aggedcontainedbyoperoid,
+ &strat);
}
/*
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index d6e23caef17..59c836fc24d 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -2178,15 +2178,15 @@ ComputeIndexAttrs(IndexInfo *indexInfo,
}
else if (iswithoutoverlaps)
{
+ CompareType cmptype;
StrategyNumber strat;
Oid opid;
if (attn == nkeycols - 1)
- strat = RTOverlapStrategyNumber;
+ cmptype = COMPARE_OVERLAP;
else
- strat = RTEqualStrategyNumber;
- GetOperatorFromWellKnownStrategy(opclassOids[attn], InvalidOid,
- &opid, &strat);
+ cmptype = COMPARE_EQ;
+ GetOperatorFromCompareType(opclassOids[attn], InvalidOid, cmptype, &opid, &strat);
indexInfo->ii_ExclusionOps[attn] = opid;
indexInfo->ii_ExclusionProcs[attn] = get_opcode(opid);
indexInfo->ii_ExclusionStrats[attn] = strat;
@@ -2422,30 +2422,28 @@ GetDefaultOpClass(Oid type_id, Oid am_id)
}
/*
- * GetOperatorFromWellKnownStrategy
+ * GetOperatorFromCompareType
*
* opclass - the opclass to use
* rhstype - the type for the right-hand side, or InvalidOid to use the type of the given opclass.
+ * cmptype - kind of operator to find
* opid - holds the operator we found
- * strat - holds the input and output strategy number
+ * strat - holds the output strategy number
*
- * Finds an operator from a "well-known" strategy number. This is used for
- * temporal index constraints (and other temporal features) to look up
- * equality and overlaps operators, since the strategy numbers for non-btree
- * indexams need not follow any fixed scheme. We ask an opclass support
- * function to translate from the well-known number to the internal value. If
- * the function isn't defined or it gives no result, we return
- * InvalidStrategy.
+ * Finds an operator from a CompareType. This is used for temporal index
+ * constraints (and other temporal features) to look up equality and overlaps
+ * operators. We ask an opclass support function to translate from the
+ * compare type to the internal strategy numbers. If the function isn't
+ * defined or it gives no result, we set *strat to InvalidStrategy.
*/
void
-GetOperatorFromWellKnownStrategy(Oid opclass, Oid rhstype,
- Oid *opid, StrategyNumber *strat)
+GetOperatorFromCompareType(Oid opclass, Oid rhstype, CompareType cmptype,
+ Oid *opid, StrategyNumber *strat)
{
Oid opfamily;
Oid opcintype;
- StrategyNumber instrat = *strat;
- Assert(instrat == RTEqualStrategyNumber || instrat == RTOverlapStrategyNumber || instrat == RTContainedByStrategyNumber);
+ Assert(cmptype == COMPARE_EQ || cmptype == COMPARE_OVERLAP || cmptype == COMPARE_CONTAINED_BY);
*opid = InvalidOid;
@@ -2457,7 +2455,7 @@ GetOperatorFromWellKnownStrategy(Oid opclass, Oid rhstype,
* For now we only need GiST support, but this could support other
* indexams if we wanted.
*/
- *strat = GistTranslateStratnum(opclass, instrat);
+ *strat = GistTranslateStratnum(opclass, cmptype);
if (*strat == InvalidStrategy)
{
HeapTuple tuple;
@@ -2468,11 +2466,11 @@ GetOperatorFromWellKnownStrategy(Oid opclass, Oid rhstype,
ereport(ERROR,
errcode(ERRCODE_UNDEFINED_OBJECT),
- instrat == RTEqualStrategyNumber ? errmsg("could not identify an equality operator for type %s", format_type_be(opcintype)) :
- instrat == RTOverlapStrategyNumber ? errmsg("could not identify an overlaps operator for type %s", format_type_be(opcintype)) :
- instrat == RTContainedByStrategyNumber ? errmsg("could not identify a contained-by operator for type %s", format_type_be(opcintype)) : 0,
- errdetail("Could not translate strategy number %d for operator class \"%s\" for access method \"%s\".",
- instrat, NameStr(((Form_pg_opclass) GETSTRUCT(tuple))->opcname), "gist"));
+ cmptype = COMPARE_EQ ? errmsg("could not identify an equality operator for type %s", format_type_be(opcintype)) :
+ cmptype == COMPARE_OVERLAP ? errmsg("could not identify an overlaps operator for type %s", format_type_be(opcintype)) :
+ cmptype == COMPARE_CONTAINED_BY ? errmsg("could not identify a contained-by operator for type %s", format_type_be(opcintype)) : 0,
+ errdetail("Could not translate compare type %d for operator class \"%s\" for access method \"%s\".",
+ cmptype, NameStr(((Form_pg_opclass) GETSTRUCT(tuple))->opcname), "gist"));
}
/*
@@ -2495,9 +2493,9 @@ GetOperatorFromWellKnownStrategy(Oid opclass, Oid rhstype,
ereport(ERROR,
errcode(ERRCODE_UNDEFINED_OBJECT),
- instrat == RTEqualStrategyNumber ? errmsg("could not identify an equality operator for type %s", format_type_be(opcintype)) :
- instrat == RTOverlapStrategyNumber ? errmsg("could not identify an overlaps operator for type %s", format_type_be(opcintype)) :
- instrat == RTContainedByStrategyNumber ? errmsg("could not identify a contained-by operator for type %s", format_type_be(opcintype)) : 0,
+ cmptype == COMPARE_EQ ? errmsg("could not identify an equality operator for type %s", format_type_be(opcintype)) :
+ cmptype == COMPARE_OVERLAP ? errmsg("could not identify an overlaps operator for type %s", format_type_be(opcintype)) :
+ cmptype == COMPARE_CONTAINED_BY ? errmsg("could not identify a contained-by operator for type %s", format_type_be(opcintype)) : 0,
errdetail("There is no suitable operator in operator family \"%s\" for access method \"%s\".",
NameStr(((Form_pg_opfamily) GETSTRUCT(tuple))->opfname), "gist"));
}
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 4fc54bd6eba..d02d564883a 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -9997,7 +9997,7 @@ ATAddForeignKeyConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
if (with_period)
{
- StrategyNumber rtstrategy;
+ CompareType cmptype;
bool for_overlaps = with_period && i == numpks - 1;
/*
@@ -10007,14 +10007,14 @@ ATAddForeignKeyConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
if (amid != GIST_AM_OID)
elog(ERROR, "only GiST indexes are supported for temporal foreign keys");
- rtstrategy = for_overlaps ? RTOverlapStrategyNumber : RTEqualStrategyNumber;
+ cmptype = for_overlaps ? COMPARE_OVERLAP : COMPARE_EQ;
/*
* An opclass can use whatever strategy numbers it wants, so we
* ask the opclass what number it actually uses instead of our RT*
* constants.
*/
- eqstrategy = GistTranslateStratnum(opclasses[i], rtstrategy);
+ eqstrategy = GistTranslateStratnum(opclasses[i], cmptype);
if (eqstrategy == InvalidStrategy)
{
HeapTuple tuple;
@@ -10028,8 +10028,8 @@ ATAddForeignKeyConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
for_overlaps
? errmsg("could not identify an overlaps operator for foreign key")
: errmsg("could not identify an equality operator for foreign key"),
- errdetail("Could not translate strategy number %d for operator class \"%s\" for access method \"%s\".",
- rtstrategy, NameStr(((Form_pg_opclass) GETSTRUCT(tuple))->opcname), "gist"));
+ errdetail("Could not translate compare type %d for operator class \"%s\" for access method \"%s\".",
+ cmptype, NameStr(((Form_pg_opclass) GETSTRUCT(tuple))->opcname), "gist"));
}
}
else
diff --git a/src/backend/executor/execReplication.c b/src/backend/executor/execReplication.c
index e3e4e41ac38..3985e84d3a6 100644
--- a/src/backend/executor/execReplication.c
+++ b/src/backend/executor/execReplication.c
@@ -57,7 +57,7 @@ get_equal_strategy_number(Oid opclass)
ret = HTEqualStrategyNumber;
break;
case GIST_AM_OID:
- ret = GistTranslateStratnum(opclass, RTEqualStrategyNumber);
+ ret = GistTranslateStratnum(opclass, COMPARE_EQ);
break;
default:
ret = InvalidStrategy;
diff --git a/src/include/access/gist.h b/src/include/access/gist.h
index 8ccaecfa1f4..446871263f6 100644
--- a/src/include/access/gist.h
+++ b/src/include/access/gist.h
@@ -247,6 +247,7 @@ typedef struct
do { (e).key = (k); (e).rel = (r); (e).page = (pg); \
(e).offset = (o); (e).leafkey = (l); } while (0)
-extern StrategyNumber GistTranslateStratnum(Oid opclass, StrategyNumber strat);
+enum CompareType;
+extern StrategyNumber GistTranslateStratnum(Oid opclass, enum CompareType cmp);
#endif /* GIST_H */
diff --git a/src/include/catalog/pg_amproc.dat b/src/include/catalog/pg_amproc.dat
index b334a5fb882..508f48d345c 100644
--- a/src/include/catalog/pg_amproc.dat
+++ b/src/include/catalog/pg_amproc.dat
@@ -508,7 +508,7 @@
amprocrighttype => 'box', amprocnum => '8', amproc => 'gist_box_distance' },
{ amprocfamily => 'gist/box_ops', amproclefttype => 'box',
amprocrighttype => 'box', amprocnum => '12',
- amproc => 'gist_stratnum_identity' },
+ amproc => 'gist_stratnum_common' },
{ amprocfamily => 'gist/poly_ops', amproclefttype => 'polygon',
amprocrighttype => 'polygon', amprocnum => '1',
amproc => 'gist_poly_consistent' },
@@ -530,7 +530,7 @@
amproc => 'gist_poly_distance' },
{ amprocfamily => 'gist/poly_ops', amproclefttype => 'polygon',
amprocrighttype => 'polygon', amprocnum => '12',
- amproc => 'gist_stratnum_identity' },
+ amproc => 'gist_stratnum_common' },
{ amprocfamily => 'gist/circle_ops', amproclefttype => 'circle',
amprocrighttype => 'circle', amprocnum => '1',
amproc => 'gist_circle_consistent' },
@@ -551,7 +551,7 @@
amproc => 'gist_circle_distance' },
{ amprocfamily => 'gist/circle_ops', amproclefttype => 'circle',
amprocrighttype => 'circle', amprocnum => '12',
- amproc => 'gist_stratnum_identity' },
+ amproc => 'gist_stratnum_common' },
{ amprocfamily => 'gist/tsvector_ops', amproclefttype => 'tsvector',
amprocrighttype => 'tsvector', amprocnum => '1',
amproc => 'gtsvector_consistent(internal,tsvector,int2,oid,internal)' },
@@ -608,7 +608,7 @@
amproc => 'range_gist_same' },
{ amprocfamily => 'gist/range_ops', amproclefttype => 'anyrange',
amprocrighttype => 'anyrange', amprocnum => '12',
- amproc => 'gist_stratnum_identity' },
+ amproc => 'gist_stratnum_common' },
{ amprocfamily => 'gist/network_ops', amproclefttype => 'inet',
amprocrighttype => 'inet', amprocnum => '1',
amproc => 'inet_gist_consistent' },
@@ -627,7 +627,7 @@
amprocrighttype => 'inet', amprocnum => '9', amproc => 'inet_gist_fetch' },
{ amprocfamily => 'gist/network_ops', amproclefttype => 'inet',
amprocrighttype => 'inet', amprocnum => '12',
- amproc => 'gist_stratnum_identity' },
+ amproc => 'gist_stratnum_common' },
{ amprocfamily => 'gist/multirange_ops', amproclefttype => 'anymultirange',
amprocrighttype => 'anymultirange', amprocnum => '1',
amproc => 'multirange_gist_consistent' },
@@ -648,7 +648,7 @@
amproc => 'range_gist_same' },
{ amprocfamily => 'gist/multirange_ops', amproclefttype => 'anymultirange',
amprocrighttype => 'anymultirange', amprocnum => '12',
- amproc => 'gist_stratnum_identity' },
+ amproc => 'gist_stratnum_common' },
# gin
{ amprocfamily => 'gin/array_ops', amproclefttype => 'anyarray',
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 872cd6e01a3..ba02ba53b29 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -12425,8 +12425,8 @@
# GiST stratnum implementations
{ oid => '8047', descr => 'GiST support',
- proname => 'gist_stratnum_identity', prorettype => 'int2',
- proargtypes => 'int2',
- prosrc => 'gist_stratnum_identity' },
+ proname => 'gist_stratnum_common', prorettype => 'int2',
+ proargtypes => 'int4',
+ prosrc => 'gist_stratnum_common' },
]
diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h
index adf6c634670..6d9348bac80 100644
--- a/src/include/commands/defrem.h
+++ b/src/include/commands/defrem.h
@@ -50,8 +50,8 @@ extern bool CheckIndexCompatible(Oid oldId,
extern Oid GetDefaultOpClass(Oid type_id, Oid am_id);
extern Oid ResolveOpClass(const List *opclass, Oid attrType,
const char *accessMethodName, Oid accessMethodId);
-extern void GetOperatorFromWellKnownStrategy(Oid opclass, Oid rhstype,
- Oid *opid, StrategyNumber *strat);
+extern void GetOperatorFromCompareType(Oid opclass, Oid rhstype, CompareType cmptype,
+ Oid *opid, StrategyNumber *strat);
/* commands/functioncmds.c */
extern ObjectAddress CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt);
diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h
index 2893dba31c3..cb09df9e745 100644
--- a/src/include/nodes/primnodes.h
+++ b/src/include/nodes/primnodes.h
@@ -1446,7 +1446,7 @@ typedef struct RowExpr
* (some of) the operators without needing hardcoded knowledge of index AM's
* strategy numbering.
*
- * XXX Currently, this mapping is not fully developed and the values are
+ * XXX Currently, this mapping is not fully developed and most values are
* chosen to match btree strategy numbers, which is not going to work very
* well for other access methods.
*/
@@ -1458,6 +1458,8 @@ typedef enum CompareType
COMPARE_GE = 4, /* BTGreaterEqualStrategyNumber */
COMPARE_GT = 5, /* BTGreaterStrategyNumber */
COMPARE_NE = 6, /* no such btree strategy */
+ COMPARE_OVERLAP,
+ COMPARE_CONTAINED_BY,
} CompareType;
/*
diff --git a/src/test/regress/expected/misc_functions.out b/src/test/regress/expected/misc_functions.out
index 384e751663a..106dedb519a 100644
--- a/src/test/regress/expected/misc_functions.out
+++ b/src/test/regress/expected/misc_functions.out
@@ -891,15 +891,15 @@ SELECT pg_column_toast_chunk_id(a) IS NULL,
DROP TABLE test_chunk_id;
DROP FUNCTION explain_mask_costs(text, bool, bool, bool, bool);
-- test stratnum support functions
-SELECT gist_stratnum_identity(3::smallint);
- gist_stratnum_identity
-------------------------
- 3
+SELECT gist_stratnum_common(7);
+ gist_stratnum_common
+----------------------
+ 3
(1 row)
-SELECT gist_stratnum_identity(18::smallint);
- gist_stratnum_identity
-------------------------
- 18
+SELECT gist_stratnum_common(3);
+ gist_stratnum_common
+----------------------
+ 18
(1 row)
diff --git a/src/test/regress/sql/misc_functions.sql b/src/test/regress/sql/misc_functions.sql
index ac792abedf2..753a0f41c03 100644
--- a/src/test/regress/sql/misc_functions.sql
+++ b/src/test/regress/sql/misc_functions.sql
@@ -401,5 +401,5 @@ DROP TABLE test_chunk_id;
DROP FUNCTION explain_mask_costs(text, bool, bool, bool, bool);
-- test stratnum support functions
-SELECT gist_stratnum_identity(3::smallint);
-SELECT gist_stratnum_identity(18::smallint);
+SELECT gist_stratnum_common(7);
+SELECT gist_stratnum_common(3);