HAWQ-1048. Changed logic to support more than one logical operator in list.
Project: http://git-wip-us.apache.org/repos/asf/incubator-hawq/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-hawq/commit/d563ab5b Tree: http://git-wip-us.apache.org/repos/asf/incubator-hawq/tree/d563ab5b Diff: http://git-wip-us.apache.org/repos/asf/incubator-hawq/diff/d563ab5b Branch: refs/heads/HAWQ-964 Commit: d563ab5b184b07b86406659ebe0abec7e4915d81 Parents: 9225016 Author: Oleksandr Diachenko <[email protected]> Authored: Fri Sep 23 18:35:41 2016 -0700 Committer: Oleksandr Diachenko <[email protected]> Committed: Fri Sep 23 18:35:41 2016 -0700 ---------------------------------------------------------------------- src/backend/access/external/pxffilters.c | 64 ++++++++++++++++++++++++--- src/include/access/pxffilters.h | 8 ++++ 2 files changed, 65 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/d563ab5b/src/backend/access/external/pxffilters.c ---------------------------------------------------------------------- diff --git a/src/backend/access/external/pxffilters.c b/src/backend/access/external/pxffilters.c index e945062..af6d2ea 100644 --- a/src/backend/access/external/pxffilters.c +++ b/src/backend/access/external/pxffilters.c @@ -31,7 +31,7 @@ #include "utils/guc.h" #include "utils/lsyscache.h" -static List* pxf_make_expression_items_list(List *quals); +static List* pxf_make_expression_items_list(List *quals, Node *parent); static void pxf_free_filter(PxfFilterDesc* filter); static char* pxf_serialize_filter_list(List *filters); static bool opexpr_to_pxffilter(OpExpr *expr, PxfFilterDesc *filter); @@ -180,6 +180,28 @@ Oid pxf_supported_types[] = TIMESTAMPOID }; +static void +pxf_free_filter_list(List *expressionItems) +{ + ListCell *lc = NULL; + ExpressionItem *expressionItem = NULL; + int previousLength; + + while (list_length(expressionItems) > 0) + { + expressionItem = (ExpressionItem *) lfirst(list_head(expressionItems)); + pfree(expressionItem); + + /* to avoid freeing already freed items - delete all occurrences of current expression*/ + previousLength = expressionItems->length + 1; + while (expressionItems != NULL && previousLength > expressionItems->length) + { + previousLength = expressionItems->length; + expressionItems = list_delete_ptr(expressionItems, expressionItem); + } + } +} + /* * pxf_make_expression_items_list * @@ -189,12 +211,15 @@ Oid pxf_supported_types[] = * * Basically this function just transforms expression tree to Reversed Polish Notation list. * + * */ static List * -pxf_make_expression_items_list(List *quals) +pxf_make_expression_items_list(List *quals, Node *parent) { + ExpressionItem *expressionItem = NULL; List *result = NIL; ListCell *lc = NULL; + ListCell *ilc = NULL; if (list_length(quals) == 0) return NIL; @@ -203,20 +228,41 @@ pxf_make_expression_items_list(List *quals) { Node *node = (Node *) lfirst(lc); NodeTag tag = nodeTag(node); + expressionItem = (ExpressionItem *) palloc0(sizeof(ExpressionItem)); + expressionItem->node = node; + expressionItem->parent = parent; + expressionItem->processed = false; switch (tag) { case T_OpExpr: { - result = lappend(result, node); + result = lappend(result, expressionItem); break; } case T_BoolExpr: { BoolExpr *expr = (BoolExpr *) node; - List *inner_result = pxf_make_expression_items_list(expr->args); + List *inner_result = pxf_make_expression_items_list(expr->args, node); result = list_concat(result, inner_result); - result = lappend(result, node); + + int childNodesNum = 0; + + /* Find number of child nodes on first level*/ + foreach (ilc, inner_result) + { + ExpressionItem *ei = (ExpressionItem *) lfirst(ilc); + if (!ei->processed && ei->parent == node) + { + ei->processed = true; + childNodesNum++; + } + } + + for (int i = 0; i < childNodesNum - 1; i++) + { + result = lappend(result, expressionItem); + } break; } default: @@ -289,7 +335,8 @@ pxf_serialize_filter_list(List *expressionItems) */ foreach (lc, expressionItems) { - Node *node = (Node *) lfirst(lc); + ExpressionItem *expressionItem = (ExpressionItem *) lfirst(lc); + Node *node = expressionItem->node; NodeTag tag = nodeTag(node); switch (tag) @@ -621,9 +668,12 @@ char *serializePxfFilterQuals(List *quals) if (pxf_enable_filter_pushdown) { - List *expressionItems = pxf_make_expression_items_list(quals); + List *expressionItems = pxf_make_expression_items_list(quals, NULL); result = pxf_serialize_filter_list(expressionItems); + pxf_free_filter_list(expressionItems); } + + elog(DEBUG2, "serializePxfFilterQuals: filter result: %s", (result == NULL) ? "null" : result); return result; http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/d563ab5b/src/include/access/pxffilters.h ---------------------------------------------------------------------- diff --git a/src/include/access/pxffilters.h b/src/include/access/pxffilters.h index a1cd661..894337b 100644 --- a/src/include/access/pxffilters.h +++ b/src/include/access/pxffilters.h @@ -92,6 +92,14 @@ typedef struct dbop_pxfop_map } dbop_pxfop_map; + +typedef struct ExpressionItem +{ + Node *node; + Node *parent; + bool processed; +} ExpressionItem; + static inline bool pxfoperand_is_attr(PxfOperand x) { return (x.opcode == PXF_ATTR_CODE);
