/* * GetStreamPaths */ void GetStreamPaths(PlannerInfo *root, RelOptInfo *baserel, Oid relid) { ForeignPath *path; Cost startup_cost; Cost total_cost; double rows; if (!IsContQueryProcess()) { PlannerInfo *parent = root; /* If the root query is continuous, we can read from streams */ while (parent->parent_root != NULL) parent = parent->parent_root; if (!parent->parse->isContinuous) { ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("\"%s\" is a stream", get_rel_name(relid)), errhint("Streams can only be read by a continuous view's FROM clause."))); } } rows = Min(100, continuous_query_batch_size * 0.25); startup_cost = baserel->baserestrictcost.startup; total_cost = startup_cost + (cpu_tuple_cost * rows); path = create_foreignscan_path(root, baserel, rows, startup_cost, total_cost, NIL, NULL, NULL, NIL); add_path(baserel, (Path *) path); }
/* * pglogGetForeignPaths * Create possible access paths for a scan on the foreign table * * Currently we don't support any push-down feature, so there is only one * possible access path, which simply returns all records in the order in * the data file. */ static void pglogGetForeignPaths(PlannerInfo *root, RelOptInfo *baserel, Oid foreigntableid) { PgLogPlanState *fdw_private = (PgLogPlanState *) baserel->fdw_private; Cost startup_cost; Cost total_cost; List *columns; List *coptions = NIL; elog(DEBUG1,"Entering function %s",__func__); /* Decide whether to selectively perform binary conversion */ if (check_selective_binary_conversion(baserel, foreigntableid, &columns)) coptions = list_make1(makeDefElem("convert_selectively", (Node *) columns)); /* Estimate costs */ estimate_costs(root, baserel, fdw_private, &startup_cost, &total_cost); /* * Create a ForeignPath node and add it as only possible path. We use the * fdw_private list of the path to carry the convert_selectively option; * it will be propagated into the fdw_private list of the Plan node. */ add_path(baserel, (Path *) create_foreignscan_path(root, baserel, baserel->rows, startup_cost, total_cost, NIL, /* no pathkeys */ NULL, /* no outer rel either */ coptions)); /* * If data file was sorted, and we knew it somehow, we could insert * appropriate pathkeys into the ForeignPath node to tell the planner * that. */ }
static void cassandraGetForeignPaths(PlannerInfo *root, RelOptInfo *baserel, Oid foreigntableid) { /* * Create possible access paths for a scan on a foreign table. This is * called during query planning. The parameters are the same as for * GetForeignRelSize, which has already been called. * * This function must generate at least one access path (ForeignPath node) * for a scan on the foreign table and must call add_path to add each such * path to baserel->pathlist. It's recommended to use * create_foreignscan_path to build the ForeignPath nodes. The function * can generate multiple access paths, e.g., a path which has valid * pathkeys to represent a pre-sorted result. Each access path must * contain cost estimates, and can contain any FDW-private information * that is needed to identify the specific scan method intended. */ /* * CassandraFdwPlanState *fdw_private = baserel->fdw_private; */ Cost startup_cost, total_cost; elog(DEBUG1,"entering function %s",__func__); startup_cost = 0; total_cost = startup_cost + baserel->rows; /* Create a ForeignPath node and add it as only possible path */ add_path(baserel, (Path *) create_foreignscan_path(root, baserel, baserel->rows, startup_cost, total_cost, NIL, /* no pathkeys */ NULL, /* no outer rel either */ NIL)); /* no fdw_private data */ }