hawq-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From zhangjackey <...@git.apache.org>
Subject [GitHub] incubator-hawq pull request #1348: HAWQ-1593. Vectorized execution condition...
Date Wed, 21 Mar 2018 06:34:37 GMT
Github user zhangjackey commented on a diff in the pull request:

    https://github.com/apache/incubator-hawq/pull/1348#discussion_r175992596
  
    --- Diff: contrib/vexecutor/vcheck.c ---
    @@ -54,7 +61,274 @@ typedef struct VecFuncHashEntry
         vFuncMap *vFunc;
     } VecFuncHashEntry;
     
    +typedef struct VecTypeHashEntry
    +{
    +	Oid src;
    +	Oid dest;
    +}VecTypeHashEntry;
    +
    +/* Map between the vectorized types and non-vectorized types */
    +static HTAB *hashMapN2V = NULL;
    +
    +/*
    + * We check the expressions tree recursively becuase the args can be a sub expression,
    + * we must check the return type of sub expression to fit the parent expressions.
    + * so the retType in Vectorized is a temporary values, after we check on expression,
    + * we set the retType of this expression, and transfer this value to his parent.
    + */
    +typedef struct VectorizedContext
    +{
    +	plan_tree_base_prefix base; /* Required prefix for plan_tree_walker/mutator */
    +	Oid retType;
    +	bool	 replace;
    +}VectorizedContext;
    +
    +/*
    + * Check all the expressions if they can be vectorized
    + * NOTE: if an expressions is vectorized, we return false...,because we should check
    + * all the expressions in the Plan node, if we return true, then the walker will be
    + * over...
    + */
    +static bool
    +CheckVectorizedExpression(Node *node, VectorizedContext *ctx)
    +{
    +    if(NULL == node)
    +        return false;
    +
    +    if(is_plan_node(node))
    +        return false;
    +
    +    //check the type of Var if it can be vectorized
    +    if(IsA(node, Var))
    +    {
    +        Var *var = (Var*)node;
    +        Oid vtype = GetVtype(var->vartype);
    +        if(InvalidOid == vtype)
    +        	    return true;
    +        ctx->retType = vtype;
    +        if(ctx->replace)
    +        	    var->vartype = vtype;
    +        return false;
    +    }
    +
    +    //Const treat as can be vectorzied, its return type is non-vectorized type
    +    //because we support the function like this: vtype op(vtype, const);
    +    if(IsA(node, Const))
    +    {
    +    	    Const *c = (Const*)node;
    +    	    ctx->retType = c->consttype;
    +    	    return false;
    +    }
    +
    +    //OpExpr:args, return types should can be vectorized,
    +    //and there must exists an vectorized function to implement the operator
    +    if(IsA(node, OpExpr))
    +    {
    +        OpExpr *op = (OpExpr*)node;
    +        Node *argnode = NULL;
    +        Oid ltype, rtype, rettype;
    +        Form_pg_operator voper;
    +        HeapTuple tuple;
    +
    +        //OpExpr mostly have two args, check the first one
    +        argnode = linitial(op->args);
    +        if(CheckVectorizedExpression(argnode, ctx))
    +        	    return true;
    +
    +        ltype = ctx->retType;
    +
    +        //check the second one
    +        argnode = lsecond(op->args);
    +        if(CheckVectorizedExpression(argnode, ctx))
    +        	    return true;
    +
    +        rtype = ctx->retType;
    +
    +        //check the return type
    +        rettype = GetVtype(op->opresulttype);
    +        if(InvalidOid == rettype)
    +        	    return true;
    +
    +
    +        //get the vectorized operator functions
    +        //NOTE:we have no ParseState now, Give the NULL value is OK but not good...
    +        tuple = oper(NULL, list_make1(makeString(get_opname(op->opno))),
    +        				ltype, rtype, false, -1);
    +        if(NULL == tuple)
    +        	    return true;
    +
    +        voper = (Form_pg_operator)GETSTRUCT(tuple);
    +        if(voper->oprresult != rettype)
    +        	    return true;
    +
    +        if(ctx->replace)
    +        {
    +        	    op->opresulttype = rettype;
    +        	    op->opfuncid = voper->oprcode;
    +        }
    +
    +        ctx->retType = rettype;
    +        return false;
    +    }
    +
    +    //now, other nodes treat as can not be vectorized
    +    return plan_tree_walker(node, CheckVectorizedExpression, ctx);;
    +}
    +
    +/*
    + * check an plan node, all the expressions in it should be checked
    + * set the flag if an plan node can be vectorized
    + */
    +static bool
    +CheckPlanNodeWalker(PlannerInfo *root, Plan *plan)
    +{
    +	VectorizedContext ctx;
    +
    +    if(plan->vectorized)
    +    	    return true;
    +
    +    ctx.replace =false;
    +
    +    ctx.retType = InvalidOid;
    +    plan->vectorized = !plan_tree_walker((Node*)plan,
    +    							 CheckVectorizedExpression,
    +							 &ctx);
    +
    +
    +    return false;
    +}
    +
    +/*
    + * check the plan tree
    + */
    +static Plan*
    +CheckPlanVectorzied(PlannerInfo *root, Plan *plan)
    +{
    +    if(NULL == plan)
    +        return plan;
    +
    +    CheckPlanVectorzied(root, plan->lefttree);
    +    CheckPlanVectorzied(root, plan->righttree);
    +    CheckPlanNodeWalker(root, plan);
    +
    +    return plan;
    +}
    +
    +/*
    + * Replace the non-vectorirzed type to vectorized type
    + */
    +static bool
    +ReplacePlanNodeWalker(PlannerInfo *root, Plan *plan)
    +{
    +	VectorizedContext ctx;
    +
    +    if(!plan->vectorized)
    +    		return false;
    +
    +    if(!HasVecExecOprator(nodeTag(plan)))
    +    {
    +    		plan->vectorized = false;
    +    		return false;
    +    }
    +
    +    ctx.replace =true;
    +
    +    ctx.retType = InvalidOid;
    +    plan_tree_walker((Node*)plan,
    +    					CheckVectorizedExpression,
    +					&ctx);
    +
     
    +    return false;
    +}
    +
    +/*
    + * check the plan tree
    + */
    +static Plan*
    +ReplacePlanVectorzied(PlannerInfo *root, Plan *plan)
    +{
    +    if(NULL == plan)
    +        return plan;
    +
    +    ReplacePlanVectorzied(root, plan->lefttree);
    +    ReplacePlanVectorzied(root, plan->righttree);
    +    ReplacePlanNodeWalker(root, plan);
    +
    +    return plan;
    +}
    +
    +Plan*
    +CheckAndReplacePlanVectorized(PlannerInfo *root, Plan *plan)
    --- End diff --
    
    So far it is not supported, but it does not seem to affect the normal running.


---

Mime
View raw message