Clean up prepkeyset.c - Mailing list pgsql-hackers
From | David Hartwig |
---|---|
Subject | Clean up prepkeyset.c |
Date | |
Msg-id | 35EF3CCE.30456BE5@bellatlantic.net Whole thread Raw |
List | pgsql-hackers |
I put some extra checks to make sure a query was a good candidate for rewrite into a UNION. Besides the existing checks: 1. Make sure the AND/OR tree was rectangular. ( i.e. 3 X 4 or 10 X 3) 2. Only one table. 3. Must have an AND dimension. 4. At least 9 OP expressions total Also cleaned up and commented. *** ./backend/optimizer/prep/prepkeyset.c.orig Thu Sep 3 16:17:56 1998 --- ./backend/optimizer/prep/prepkeyset.c Thu Sep 3 20:17:05 1998 *************** *** 11,45 **** #include <string.h> #include "postgres.h" - #include "nodes/pg_list.h" - #include "nodes/parsenodes.h" - #include "utils/elog.h" - - #include "nodes/nodes.h" - #include "nodes/execnodes.h" - #include "nodes/plannodes.h" - #include "nodes/primnodes.h" - #include "nodes/relation.h" - - #include "catalog/pg_type.h" - #include "lib/stringinfo.h" #include "optimizer/planmain.h" /* * Node_Copy-- * a macro to simplify calling of copyObject on the specified field */ #define Node_Copy(from, newnode, field) newnode->field = copyObject(from->field) - /***** DEBUG stuff - #define TABS {int i; printf("\n"); for (i = 0; i<level; i++) printf("\t"); } - static int level = 0; - ******/ - bool _use_keyset_query_optimizer = FALSE; static int inspectOpNode(Expr *expr); static int inspectAndNode(Expr *expr); static int inspectOrNode(Expr *expr); /********************************************************************** * This routine transforms query trees with the following form: --- 11,30 ---- #include <string.h> #include "postgres.h" #include "optimizer/planmain.h" + /* * Node_Copy-- * a macro to simplify calling of copyObject on the specified field */ #define Node_Copy(from, newnode, field) newnode->field = copyObject(from->field) bool _use_keyset_query_optimizer = FALSE; static int inspectOpNode(Expr *expr); static int inspectAndNode(Expr *expr); static int inspectOrNode(Expr *expr); + static int TotalExpr; /********************************************************************** * This routine transforms query trees with the following form: *************** *** 73,80 **** * * daveh@insightdist.com 1998-08-31 * ! * Needs to better identify the signeture WHERE clause. ! * May want to also prune out duplicate where clauses. **********************************************************************/ void transformKeySetQuery(Query *origNode) --- 58,64 ---- * * daveh@insightdist.com 1998-08-31 * ! * May want to also prune out duplicate terms. **********************************************************************/ void transformKeySetQuery(Query *origNode) *************** *** 92,109 **** return; /* Qualify single table query */ /* Qualify where clause */ ! if ( ! inspectOrNode((Expr*)origNode->qual)) { return; - } /* Copy essential elements into a union node */ - /* - elog(NOTICE, "OR_EXPR=%d, OP_EXPR=%d, AND_EXPR=%d", OR_EXPR, OP_EXPR, AND_EXPR); - elog(NOTICE, "T_List=%d, T_Expr=%d, T_Var=%d, T_Const=%d", T_List, T_Expr, T_Var, T_Const); - elog(NOTICE, "opType=%d", ((Expr*)origNode->qual)->opType); - */ while (((Expr*)origNode->qual)->opType == OR_EXPR) { Query *unionNode = makeNode(Query); --- 76,95 ---- return; /* Qualify single table query */ + if (length(origNode->rtable) != 1) + return; + /* Sorry about the global, not worth passing around */ + /* 9 expressions seems like a good number. More than 9 */ + /* and it starts to slow down quite a bit */ + TotalExpr = 0; + /*************************/ /* Qualify where clause */ ! /*************************/ ! if ( ! inspectOrNode((Expr*)origNode->qual) || TotalExpr < 9) return; /* Copy essential elements into a union node */ while (((Expr*)origNode->qual)->opType == OR_EXPR) { Query *unionNode = makeNode(Query); *************** *** 113,123 **** /* Pull up balance of tree */ origNode->qual = lfirst(((Expr*)origNode->qual)->args); - /* - elog(NOTICE, "origNode: opType=%d, nodeTag=%d", ((Expr*)origNode->qual)->opType, nodeTag(origNode->qual)); - elog(NOTICE, "unionNode: opType=%d, nodeTag=%d", ((Expr*)unionNode->qual)->opType, nodeTag(unionNode->qual)); - */ - unionNode->commandType = origNode->commandType; unionNode->resultRelation = origNode->resultRelation; unionNode->isPortal = origNode->isPortal; --- 99,104 ---- *************** *** 139,147 **** static int inspectOrNode(Expr *expr) { ! int fr = 0, sr = 0; Expr *firstExpr, *secondExpr; if ( ! (expr && nodeTag(expr) == T_Expr && expr->opType == OR_EXPR)) --- 120,133 ---- static int + /********************************************************************** + * Checks for 1 or more OR terms w/ 1 or more AND terms. + * AND terms must be equal in size. + * Returns the number of each AND term. + **********************************************************************/ inspectOrNode(Expr *expr) { ! int rc; Expr *firstExpr, *secondExpr; if ( ! (expr && nodeTag(expr) == T_Expr && expr->opType == OR_EXPR)) *************** *** 152,178 **** if (nodeTag(firstExpr) != T_Expr || nodeTag(secondExpr) != T_Expr) return 0; ! if (firstExpr->opType == OR_EXPR) ! fr = inspectOrNode(firstExpr); ! else if (firstExpr->opType == OP_EXPR) /* Need to make sure it is last */ ! fr = inspectOpNode(firstExpr); ! else if (firstExpr->opType == AND_EXPR) /* Need to make sure it is last */ ! fr = inspectAndNode(firstExpr); ! ! if (secondExpr->opType == AND_EXPR) ! sr = inspectAndNode(secondExpr); ! else if (secondExpr->opType == OP_EXPR) ! sr = inspectOpNode(secondExpr); ! return (fr && sr); } static int inspectAndNode(Expr *expr) { ! int fr = 0, sr = 0; Expr *firstExpr, *secondExpr; if ( ! (expr && nodeTag(expr) == T_Expr && expr->opType == AND_EXPR)) --- 138,172 ---- if (nodeTag(firstExpr) != T_Expr || nodeTag(secondExpr) != T_Expr) return 0; ! if (firstExpr->opType == OR_EXPR && secondExpr->opType == AND_EXPR) ! { ! if ((rc = inspectOrNode(firstExpr)) == 0) ! return 0; ! return (rc == inspectAndNode(secondExpr)) ? rc : 0; ! } ! else if (firstExpr->opType == AND_EXPR && secondExpr->opType == AND_EXPR) ! { ! if ((rc = inspectAndNode(firstExpr)) == 0) ! return 0; ! ! return (rc == inspectAndNode(secondExpr)) ? rc : 0; ! } ! ! return 0; } static int + /********************************************************************** + * Check for one or more AND terms. Each sub-term must be a T_Const + * T_Var expression. + * Returns the number of AND terms. + **********************************************************************/ inspectAndNode(Expr *expr) { ! int rc; Expr *firstExpr, *secondExpr; if ( ! (expr && nodeTag(expr) == T_Expr && expr->opType == AND_EXPR)) *************** *** 183,197 **** if (nodeTag(firstExpr) != T_Expr || nodeTag(secondExpr) != T_Expr) return 0; ! if (firstExpr->opType == AND_EXPR) ! fr = inspectAndNode(firstExpr); ! else if (firstExpr->opType == OP_EXPR) ! fr = inspectOpNode(firstExpr); ! if (secondExpr->opType == OP_EXPR) ! sr = inspectOpNode(secondExpr); ! ! return (fr && sr); } --- 177,195 ---- if (nodeTag(firstExpr) != T_Expr || nodeTag(secondExpr) != T_Expr) return 0; ! if (firstExpr->opType == AND_EXPR && ! secondExpr->opType == OP_EXPR && inspectOpNode(secondExpr)) ! { ! rc = inspectAndNode(firstExpr); ! return ((rc) ? (rc + 1) : 0); /* Add up the AND nodes */ ! } ! else if (firstExpr->opType == OP_EXPR && inspectOpNode(firstExpr) && ! secondExpr->opType == OP_EXPR && inspectOpNode(secondExpr)) ! { ! return 1; ! } ! return 0; } *************** *** 205,211 **** Expr *firstExpr, *secondExpr; if (nodeTag(expr) != T_Expr || expr->opType != OP_EXPR) ! return 0; firstExpr = lfirst(expr->args); secondExpr = lsecond(expr->args); --- 203,211 ---- Expr *firstExpr, *secondExpr; if (nodeTag(expr) != T_Expr || expr->opType != OP_EXPR) ! return FALSE; ! ! TotalExpr++; firstExpr = lfirst(expr->args); secondExpr = lsecond(expr->args);
pgsql-hackers by date: