Пример #1
0
    public: Val Unparse()
    {
        Val ty = nil;
        if (nil != m_rest)
        {
            ty = list(QArest, m_rest);
        }

        if (nil != m_opts)
        {
            ty = nconc(cons(QAoptional, nreverse_list(m_opts)), m_rest);
        }

        ty = nconc(nreverse_list(m_reqs), ty);
        if (nil != ty && nil == cdr(ty))
        {
            return first(ty);
        }
        else
        {
            return cons(Qvalues, ty);
        }
    } // Unparse
Пример #2
0
/*
 * Generate plan for a UNION or UNION ALL node
 */
static Plan *
generate_union_plan(SetOperationStmt *op, Query *parse,
                    List *refnames_tlist)
{
    List	   *planlist;
    List	   *tlist;
    Plan	   *plan;

    /*
     * If any of my children are identical UNION nodes (same op, all-flag,
     * and colTypes) then they can be merged into this node so that we
     * generate only one Append and Sort for the lot.  Recurse to find
     * such nodes and compute their children's plans.
     */
    planlist = nconc(recurse_union_children(op->larg, parse,
                                            op, refnames_tlist),
                     recurse_union_children(op->rarg, parse,
                                            op, refnames_tlist));

    /*
     * Generate tlist for Append plan node.
     *
     * The tlist for an Append plan isn't important as far as the Append is
     * concerned, but we must make it look real anyway for the benefit of
     * the next plan level up.
     */
    tlist = generate_append_tlist(op->colTypes, false,
                                  planlist, refnames_tlist);

    /*
     * Append the child results together.
     */
    plan = (Plan *) make_append(planlist, false, tlist);

    /*
     * For UNION ALL, we just need the Append plan.  For UNION, need to
     * add Sort and Unique nodes to produce unique output.
     */
    if (!op->all)
    {
        List	   *sortList;

        tlist = copyObject(tlist);
        sortList = addAllTargetsToSortList(NULL, NIL, tlist, false);
        plan = (Plan *) make_sort_from_sortclauses(parse, tlist,
                plan, sortList);
        plan = (Plan *) make_unique(tlist, plan, sortList);
    }
    return plan;
}
Пример #3
0
static void coerce_arg(rtype type, rtype ftype, int l, string code,
		       string *buf, int *i, int *lbuf,
		       int int_allowed, frame name)
{
    frame f = make_frame(type, NULL, l, code, "");

    if ((type == T_INTNUM || type == T_INTLNG) && !int_allowed)
	f = coerce_frame(f, T_NUMBER);

    f = coerce_frame(f, ftype);
    if (f->decls)
	name->decls = nconc(name->decls, copy_list(f->decls, 0));

    NORET(f->code);
    *buf = copy_into_buf(*buf, f->code, i, lbuf, strlen(f->code));

    mcfree(f->code);
    mcfree(f);
}
Пример #4
0
/*
 * Pull up children of a UNION node that are identically-propertied UNIONs.
 *
 * NOTE: we can also pull a UNION ALL up into a UNION, since the distinct
 * output rows will be lost anyway.
 */
static List *
recurse_union_children(Node *setOp, Query *parse,
                       SetOperationStmt *top_union,
                       List *refnames_tlist)
{
    if (IsA(setOp, SetOperationStmt))
    {
        SetOperationStmt *op = (SetOperationStmt *) setOp;

        if (op->op == top_union->op &&
                (op->all == top_union->all || op->all) &&
                equalo(op->colTypes, top_union->colTypes))
        {
            /* Same UNION, so fold children into parent's subplan list */
            return nconc(recurse_union_children(op->larg, parse,
                                                top_union,
                                                refnames_tlist),
                         recurse_union_children(op->rarg, parse,
                                                top_union,
                                                refnames_tlist));
        }
    }

    /*
     * Not same, so plan this child separately.
     *
     * Note we disallow any resjunk columns in child results.  This is
     * necessary since the Append node that implements the union won't do
     * any projection, and upper levels will get confused if some of our
     * output tuples have junk and some don't.  This case only arises when
     * we have an EXCEPT or INTERSECT as child, else there won't be
     * resjunk anyway.
     */
    return makeList1(recurse_set_operations(setOp, parse,
                                            top_union->colTypes, false,
                                            -1, refnames_tlist));
}