示例#1
0
文件: worker.c 项目: RingsC/postgres
/*
 * Executes default values for columns for which we can't map to remote
 * relation columns.
 *
 * This allows us to support tables which have more columns on the downstream
 * than on the upstream.
 */
static void
slot_fill_defaults(LogicalRepRelMapEntry *rel, EState *estate,
				   TupleTableSlot *slot)
{
	TupleDesc	desc = RelationGetDescr(rel->localrel);
	int			num_phys_attrs = desc->natts;
	int			i;
	int			attnum,
				num_defaults = 0;
	int		   *defmap;
	ExprState **defexprs;
	ExprContext *econtext;

	econtext = GetPerTupleExprContext(estate);

	/* We got all the data via replication, no need to evaluate anything. */
	if (num_phys_attrs == rel->remoterel.natts)
		return;

	defmap = (int *) palloc(num_phys_attrs * sizeof(int));
	defexprs = (ExprState **) palloc(num_phys_attrs * sizeof(ExprState *));

	for (attnum = 0; attnum < num_phys_attrs; attnum++)
	{
		Expr	   *defexpr;

		if (TupleDescAttr(desc, attnum)->attisdropped)
			continue;

		if (rel->attrmap[attnum] >= 0)
			continue;

		defexpr = (Expr *) build_column_default(rel->localrel, attnum + 1);

		if (defexpr != NULL)
		{
			/* Run the expression through planner */
			defexpr = expression_planner(defexpr);

			/* Initialize executable expression in copycontext */
			defexprs[num_defaults] = ExecInitExpr(defexpr, NULL);
			defmap[num_defaults] = attnum;
			num_defaults++;
		}

	}

	for (i = 0; i < num_defaults; i++)
		slot->tts_values[defmap[i]] =
			ExecEvalExpr(defexprs[i], econtext, &slot->tts_isnull[defmap[i]]);
}
示例#2
0
/*
 * Copied from src/backend/commands/indexcmds.c, not exported.
 * CheckMutability
 *		Test whether given expression is mutable
 */
bool
CheckMutability(Expr *expr)
{
	/*
	 * First run the expression through the planner.  This has a couple of
	 * important consequences.  First, function default arguments will get
	 * inserted, which may affect volatility (consider "default now()").
	 * Second, inline-able functions will get inlined, which may allow us to
	 * conclude that the function is really less volatile than it's marked. As
	 * an example, polymorphic functions must be marked with the most volatile
	 * behavior that they have for any input type, but once we inline the
	 * function we may be able to conclude that it's not so volatile for the
	 * particular input type we're dealing with.
	 *
	 * We assume here that expression_planner() won't scribble on its input.
	 */
	expr = expression_planner(expr);

	/* Now we can search for non-immutable functions */
	return contain_mutable_functions((Node *) expr);
}
示例#3
0
/*
 * 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);
}