tgl-support-fixes.patch
text/x-diff
Filename: tgl-support-fixes.patch
Type: text/x-diff
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
| File | + | − |
|---|---|---|
| postgis/gserialized_supportfn.c | 57 | 34 |
diff --git a/postgis/gserialized_supportfn.c b/postgis/gserialized_supportfn.c
index 90c61f3..66b699b 100644
--- a/postgis/gserialized_supportfn.c
+++ b/postgis/gserialized_supportfn.c
@@ -60,7 +60,7 @@ Datum postgis_index_supportfn(PG_FUNCTION_ARGS);
*/
typedef struct
{
- char *fn_name;
+ const char *fn_name;
int strategy_number; /* Index strategy to add */
int nargs; /* Expected number of function arguments */
int expand_arg; /* Radius argument for "within distance" search */
@@ -230,22 +230,42 @@ Datum postgis_index_supportfn(PG_FUNCTION_ARGS)
}
/*
- * Somehow an indexed third argument has slipped in. That
- * should not happen.
+ * We can only do something with index matches on the first or
+ * second argument.
*/
if (req->indexarg > 1)
PG_RETURN_POINTER((Node *)NULL);
/*
- * Need the argument types (which should always be geometry or geography
- * since this function is only bound to those functions)
- * to use in the operator function lookup
+ * Make sure we have enough arguments (just paranoia really).
*/
- if (nargs < 2)
+ if (nargs < 2 || nargs < idxfn.expand_arg)
elog(ERROR, "%s: associated with function with %d arguments", __func__, nargs);
- leftarg = linitial(clause->args);
- rightarg = lsecond(clause->args);
+ /*
+ * Extract "leftarg" as the arg matching the index, and
+ * "rightarg" as the other one, even if they were in the
+ * opposite order in the call. NOTE: the functions we deal
+ * with here treat their first two arguments symmetrically
+ * enough that we needn't distinguish the two cases beyond
+ * this. This might need more work later.
+ */
+ if (req->indexarg == 0)
+ {
+ leftarg = linitial(clause->args);
+ rightarg = lsecond(clause->args);
+ }
+ else
+ {
+ rightarg = linitial(clause->args);
+ leftarg = lsecond(clause->args);
+ }
+
+ /*
+ * Need the argument types (which should always be geometry or geography
+ * since this function is only bound to those functions)
+ * to use in the operator function lookup.
+ */
leftdatatype = exprType(leftarg);
rightdatatype = exprType(rightarg);
@@ -267,20 +287,27 @@ Datum postgis_index_supportfn(PG_FUNCTION_ARGS)
*/
if (idxfn.expand_arg)
{
- Node *indexarg = req->indexarg ? rightarg : leftarg;
- Node *otherarg = req->indexarg ? leftarg : rightarg;
Node *radiusarg = (Node *) list_nth(clause->args, idxfn.expand_arg-1);
- // Oid indexdatatype = exprType(indexarg);
- Oid otherdatatype = exprType(otherarg);
- Oid expandfn_oid = expandFunctionOid(otherdatatype);
+ Oid expandfn_oid = expandFunctionOid(rightdatatype);
+
+ FuncExpr *expandexpr = makeFuncExpr(expandfn_oid, rightdatatype,
+ list_make2(rightarg, radiusarg),
+ InvalidOid, InvalidOid, COERCE_EXPLICIT_CALL);
- FuncExpr *expandexpr = makeFuncExpr(expandfn_oid, otherdatatype,
- list_make2(otherarg, radiusarg),
- InvalidOid, req->indexcollation, COERCE_EXPLICIT_CALL);
+ /*
+ * The comparison expression has to be a pseudoconstant,
+ * ie not volatile nor dependent on the target index's
+ * table. (Including the expandfn itself in this test is
+ * probably unnecessary, but let's be paranoid.)
+ */
+ if (!is_pseudo_constant_for_index((Node *) expandexpr,
+ req->index))
+ PG_RETURN_POINTER((Node *)NULL);
+ /* OK, we can make the index condition */
Expr *expr = make_opclause(oproid, BOOLOID, false,
- (Expr *) indexarg, (Expr *) expandexpr,
- InvalidOid, req->indexcollation);
+ (Expr *) leftarg, (Expr *) expandexpr,
+ InvalidOid, InvalidOid);
ret = (Node *)(list_make1(expr));
}
@@ -289,28 +316,24 @@ Datum postgis_index_supportfn(PG_FUNCTION_ARGS)
* an index OpExpr with the original arguments on each
* side.
* st_intersects(g1, g2) yields: g1 && g2
+ * if g1 is the indexable expression (otherwise g2 && g1)
*/
else
{
- Expr *expr;
/*
- * PgSQL wants the left-hand side to be the non-const
- * term, so if we have a const left we swap with
- * the right
+ * The comparison expression has to be a pseudoconstant,
+ * ie not volatile nor dependent on the target index's
+ * table.
*/
- if (IsA(leftarg, Const))
- {
- Node *tmp;
- oproid = get_commutator(oproid);
- if (!OidIsValid(oproid))
- PG_RETURN_POINTER((Node *)NULL);
- tmp = leftarg;
- leftarg = rightarg;
- rightarg = tmp;
- }
- expr = make_opclause(oproid, BOOLOID, false,
+ if (!is_pseudo_constant_for_index(rightarg,
+ req->index))
+ PG_RETURN_POINTER((Node *)NULL);
+
+ /* OK, we can make the index condition */
+ Expr *expr = make_opclause(oproid, BOOLOID, false,
(Expr *) leftarg, (Expr *) rightarg,
InvalidOid, InvalidOid);
+
ret = (Node *)(list_make1(expr));
}