/* * pglogGetForeignPlan * Create a ForeignScan plan node for scanning the foreign table */ static ForeignScan * pglogGetForeignPlan(PlannerInfo *root, RelOptInfo *baserel, Oid foreigntableid, ForeignPath *best_path, List *tlist, List *scan_clauses) { Index scan_relid = baserel->relid; elog(DEBUG1,"Entering function %s",__func__); /* * We have no native ability to evaluate restriction clauses, so we just * put all the scan_clauses into the plan node's qual list for the * executor to check. So all we have to do here is strip RestrictInfo * nodes from the clauses and ignore pseudoconstants (which will be * handled elsewhere). */ scan_clauses = extract_actual_clauses(scan_clauses, false); /* Create the ForeignScan node */ return make_foreignscan(tlist, scan_clauses, scan_relid, NIL, /* no expressions to evaluate */ best_path->fdw_private); }
static ForeignScan * cassandraGetForeignPlan(PlannerInfo *root, RelOptInfo *baserel, Oid foreigntableid, ForeignPath *best_path, List *tlist, List *scan_clauses) { /* * Create a ForeignScan plan node from the selected foreign access path. * This is called at the end of query planning. The parameters are as for * GetForeignRelSize, plus the selected ForeignPath (previously produced * by GetForeignPaths), the target list to be emitted by the plan node, * and the restriction clauses to be enforced by the plan node. * * This function must create and return a ForeignScan plan node; it's * recommended to use make_foreignscan to build the ForeignScan node. * */ Index scan_relid = baserel->relid; /* * We have no native ability to evaluate restriction clauses, so we just * put all the scan_clauses into the plan node's qual list for the * executor to check. So all we have to do here is strip RestrictInfo * nodes from the clauses and ignore pseudoconstants (which will be * handled elsewhere). */ elog(DEBUG1,"entering function %s",__func__); scan_clauses = extract_actual_clauses(scan_clauses, false); /* Create the ForeignScan node */ return make_foreignscan(tlist, scan_clauses, scan_relid, NIL, /* no expressions to evaluate */ NIL); /* no private state either */ }
/* * GetStreamScanPlan */ ForeignScan * GetStreamScanPlan(PlannerInfo *root, RelOptInfo *baserel, Oid relid, ForeignPath *best_path, List *tlist, List *scan_clauses, Plan *outer_plan) { StreamFdwInfo *sinfo = (StreamFdwInfo *) baserel->fdw_private; List *physical_tlist = build_physical_tlist(root, baserel); RangeTblEntry *rte = NULL; int i; TableSampleClause *sample; Value *sample_cutoff = NULL; /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */ scan_clauses = extract_actual_clauses(scan_clauses, false); for (i = 1; i <= root->simple_rel_array_size; i++) { rte = root->simple_rte_array[i]; if (rte && rte->relid == relid) break; } if (!rte || rte->relid != relid) elog(ERROR, "stream RTE missing"); sample = rte->tablesample; if (sample) { double dcutoff; Datum d; ExprContext *econtext; bool isnull; Node *node; Expr *expr; ExprState *estate; ParseState *ps = make_parsestate(NULL); float4 percent; if (sample->tsmhandler != BERNOULLI_OID) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("tablesample method %s is not supported by streams", get_func_name(sample->tsmhandler)), errhint("Only bernoulli tablesample method can be used with streams."))); if (sample->repeatable) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("streams don't support the REPEATABLE clause for tablesample"))); econtext = CreateStandaloneExprContext(); ps = make_parsestate(NULL); node = (Node *) linitial(sample->args); node = transformExpr(ps, node, EXPR_KIND_OTHER); expr = expression_planner((Expr *) node); estate = ExecInitExpr(expr, NULL); d = ExecEvalExpr(estate, econtext, &isnull, NULL); free_parsestate(ps); FreeExprContext(econtext, false); percent = DatumGetFloat4(d); if (percent < 0 || percent > 100 || isnan(percent)) ereport(ERROR, (errcode(ERRCODE_INVALID_TABLESAMPLE_ARGUMENT), errmsg("sample percentage must be between 0 and 100"))); dcutoff = rint(((double) RAND_MAX + 1) * percent / 100); sample_cutoff = makeInteger((int) dcutoff); } return make_foreignscan(tlist, scan_clauses, baserel->relid, NIL, list_make3(sinfo->colnames, physical_tlist, sample_cutoff), NIL, NIL, outer_plan); }