324 Node *rawreq = (Node *) PG_GETARG_POINTER(0);
331 postgis_initialize_cache();
333 if (IsA(rawreq, SupportRequestSelectivity))
335 SupportRequestSelectivity *req = (SupportRequestSelectivity *) rawreq;
345 POSTGIS_DEBUGF(2,
"%s: got selectivity %g", __func__, req->selectivity);
346 PG_RETURN_POINTER(req);
353 if (IsA(rawreq, SupportRequestIndexCondition))
355 SupportRequestIndexCondition *req = (SupportRequestIndexCondition *) rawreq;
357 if (is_funcclause(req->node))
359 FuncExpr *clause = (FuncExpr *) req->node;
360 Oid funcid = clause->funcid;
362 Oid opfamilyoid = req->opfamily;
366 int nargs = list_length(clause->args);
367 Node *leftarg, *rightarg;
368 Oid leftdatatype, rightdatatype, oproid;
369 bool swapped =
false;
378 uint8_t opfamilydims;
380 if (opfamilyam != GIST_AM_OID &&
381 opfamilyam != SPGIST_AM_OID &&
382 opfamilyam != BRIN_AM_OID)
384 PG_RETURN_POINTER((Node *)NULL);
391 if (req->indexarg > 1)
392 PG_RETURN_POINTER((Node *)NULL);
399 if (opfamilydims == 3 && idxfn.dims != 3)
400 PG_RETURN_POINTER((Node *)NULL);
405 if (nargs < 2 || nargs < idxfn.expand_arg)
406 elog(ERROR,
"%s: associated with function with %d arguments", __func__, nargs);
418 if (req->indexarg == 0)
420 leftarg = linitial(clause->args);
421 rightarg = lsecond(clause->args);
425 rightarg = linitial(clause->args);
426 leftarg = lsecond(clause->args);
434 leftdatatype = exprType(leftarg);
435 rightdatatype = exprType(rightarg);
442 oproid = get_opfamily_member(opfamilyoid,
446 if (!OidIsValid(oproid))
448 "no spatial operator found for '%s': opfamily %u type %d",
460 if (idxfn.expand_arg)
463 Node *radiusarg = (Node *) list_nth(clause->args, idxfn.expand_arg-1);
466 FuncExpr *expandexpr = makeFuncExpr(expandfn_oid, rightdatatype,
467 list_make2(rightarg, radiusarg),
468 InvalidOid, InvalidOid, COERCE_EXPLICIT_CALL);
474 #if POSTGIS_PGSQL_VERSION >= 140
475 if (!is_pseudo_constant_for_index(req->root, (Node*)expandexpr, req->index))
477 if (!is_pseudo_constant_for_index((Node*)expandexpr, req->index))
479 PG_RETURN_POINTER((Node*)NULL);
482 expr = make_opclause(oproid, BOOLOID,
false,
483 (Expr *) leftarg, (Expr *) expandexpr,
484 InvalidOid, InvalidOid);
486 ret = (Node *)(list_make1(expr));
501 #if POSTGIS_PGSQL_VERSION >= 140
502 if (!is_pseudo_constant_for_index(req->root, rightarg, req->index))
504 if (!is_pseudo_constant_for_index(rightarg, req->index))
506 PG_RETURN_POINTER((Node*)NULL);
515 oproid = get_commutator(oproid);
516 if (!OidIsValid(oproid))
517 PG_RETURN_POINTER((Node *)NULL);
520 expr = make_opclause(oproid, BOOLOID,
false,
521 (Expr *) leftarg, (Expr *) rightarg,
522 InvalidOid, InvalidOid);
524 ret = (Node *)(list_make1(expr));
534 PG_RETURN_POINTER(ret);
538 elog(WARNING,
"support function '%s' called from unsupported spatial function", __func__);
543 PG_RETURN_POINTER(ret);
static bool needsSpatialIndex(Oid funcid, IndexableFunction *idxfn)
static Oid expandFunctionOid(Oid geotype, Oid callingfunc)
static Oid opFamilyAmOid(Oid opfamilyoid, uint8_t *dims)
float8 gserialized_sel_internal(PlannerInfo *root, List *args, int varRelid, int mode)
This function should return an estimation of the number of rows returned by a query involving an over...
float8 gserialized_joinsel_internal(PlannerInfo *root, List *args, JoinType jointype, int mode)
static int16 get_strategy_by_type(Oid first_type, uint16_t index)