Github user zhangjackey commented on a diff in the pull request:
https://github.com/apache/incubator-hawq/pull/1348#discussion_r175992712
--- 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;
+ }
--- End diff --
Yes, we will support more expression nodes step by step.
---