diff options
Diffstat (limited to 'src/backend/optimizer')
| -rw-r--r-- | src/backend/optimizer/path/clausesel.c | 8 | ||||
| -rw-r--r-- | src/backend/optimizer/path/costsize.c | 7 | ||||
| -rw-r--r-- | src/backend/optimizer/plan/setrefs.c | 37 | ||||
| -rw-r--r-- | src/backend/optimizer/util/clauses.c | 46 |
4 files changed, 91 insertions, 7 deletions
diff --git a/src/backend/optimizer/path/clausesel.c b/src/backend/optimizer/path/clausesel.c index 846d52140c..67900d9e40 100644 --- a/src/backend/optimizer/path/clausesel.c +++ b/src/backend/optimizer/path/clausesel.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/path/clausesel.c,v 1.58 2003/05/27 17:49:46 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/path/clausesel.c,v 1.59 2003/06/29 00:33:43 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -515,6 +515,12 @@ clause_selectivity(Query *root, */ s1 = (Selectivity) 0.5; } + else if (IsA(clause, DistinctExpr) || + IsA(clause, ScalarArrayOpExpr)) + { + /* can we do better? */ + s1 = (Selectivity) 0.5; + } else if (IsA(clause, NullTest)) { /* Use node specific selectivity calculation function */ diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c index 21bc152ce6..283987b63d 100644 --- a/src/backend/optimizer/path/costsize.c +++ b/src/backend/optimizer/path/costsize.c @@ -49,7 +49,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.107 2003/02/16 02:30:38 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.108 2003/06/29 00:33:43 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1473,6 +1473,11 @@ cost_qual_eval_walker(Node *node, QualCost *total) { total->per_tuple += cpu_operator_cost; } + else if (IsA(node, ScalarArrayOpExpr)) + { + /* should charge more than 1 op cost, but how many? */ + total->per_tuple += cpu_operator_cost * 10; + } else if (IsA(node, SubLink)) { /* This routine should not be applied to un-planned expressions */ diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c index 4e17a85eb4..1da186e0aa 100644 --- a/src/backend/optimizer/plan/setrefs.c +++ b/src/backend/optimizer/plan/setrefs.c @@ -9,20 +9,19 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.92 2003/02/16 02:30:38 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.93 2003/06/29 00:33:43 tgl Exp $ * *------------------------------------------------------------------------- */ #include "postgres.h" - #include "nodes/makefuncs.h" -#include "nodes/nodeFuncs.h" #include "optimizer/clauses.h" #include "optimizer/planmain.h" #include "optimizer/tlist.h" #include "optimizer/var.h" #include "parser/parsetree.h" +#include "utils/lsyscache.h" typedef struct @@ -61,6 +60,8 @@ static Node *replace_vars_with_subplan_refs(Node *node, static Node *replace_vars_with_subplan_refs_mutator(Node *node, replace_vars_with_subplan_refs_context *context); static bool fix_opfuncids_walker(Node *node, void *context); +static void set_sa_opfuncid(ScalarArrayOpExpr *opexpr); + /***************************************************************************** * @@ -284,6 +285,8 @@ fix_expr_references_walker(Node *node, void *context) set_opfuncid((OpExpr *) node); else if (IsA(node, DistinctExpr)) set_opfuncid((OpExpr *) node); /* rely on struct equivalence */ + else if (IsA(node, ScalarArrayOpExpr)) + set_sa_opfuncid((ScalarArrayOpExpr *) node); else if (IsA(node, NullIfExpr)) set_opfuncid((OpExpr *) node); /* rely on struct equivalence */ else if (IsA(node, SubPlan)) @@ -738,7 +741,35 @@ fix_opfuncids_walker(Node *node, void *context) set_opfuncid((OpExpr *) node); else if (IsA(node, DistinctExpr)) set_opfuncid((OpExpr *) node); /* rely on struct equivalence */ + else if (IsA(node, ScalarArrayOpExpr)) + set_sa_opfuncid((ScalarArrayOpExpr *) node); else if (IsA(node, NullIfExpr)) set_opfuncid((OpExpr *) node); /* rely on struct equivalence */ return expression_tree_walker(node, fix_opfuncids_walker, context); } + +/* + * set_opfuncid + * Set the opfuncid (procedure OID) in an OpExpr node, + * if it hasn't been set already. + * + * Because of struct equivalence, this can also be used for + * DistinctExpr and NullIfExpr nodes. + */ +void +set_opfuncid(OpExpr *opexpr) +{ + if (opexpr->opfuncid == InvalidOid) + opexpr->opfuncid = get_opcode(opexpr->opno); +} + +/* + * set_sa_opfuncid + * As above, for ScalarArrayOpExpr nodes. + */ +static void +set_sa_opfuncid(ScalarArrayOpExpr *opexpr) +{ + if (opexpr->opfuncid == InvalidOid) + opexpr->opfuncid = get_opcode(opexpr->opno); +} diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c index 8b04066133..54f2d7bd69 100644 --- a/src/backend/optimizer/util/clauses.c +++ b/src/backend/optimizer/util/clauses.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.141 2003/06/25 21:30:30 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.142 2003/06/29 00:33:43 tgl Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -25,8 +25,8 @@ #include "executor/executor.h" #include "miscadmin.h" #include "nodes/makefuncs.h" -#include "nodes/nodeFuncs.h" #include "optimizer/clauses.h" +#include "optimizer/planmain.h" #include "optimizer/var.h" #include "parser/analyze.h" #include "parser/parse_clause.h" @@ -461,6 +461,8 @@ expression_returns_set_walker(Node *node, void *context) return false; if (IsA(node, DistinctExpr)) return false; + if (IsA(node, ScalarArrayOpExpr)) + return false; if (IsA(node, BoolExpr)) return false; if (IsA(node, SubLink)) @@ -563,6 +565,14 @@ contain_mutable_functions_walker(Node *node, void *context) return true; /* else fall through to check args */ } + if (IsA(node, ScalarArrayOpExpr)) + { + ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node; + + if (op_volatile(expr->opno) != PROVOLATILE_IMMUTABLE) + return true; + /* else fall through to check args */ + } if (IsA(node, NullIfExpr)) { NullIfExpr *expr = (NullIfExpr *) node; @@ -638,6 +648,14 @@ contain_volatile_functions_walker(Node *node, void *context) return true; /* else fall through to check args */ } + if (IsA(node, ScalarArrayOpExpr)) + { + ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node; + + if (op_volatile(expr->opno) == PROVOLATILE_VOLATILE) + return true; + /* else fall through to check args */ + } if (IsA(node, NullIfExpr)) { NullIfExpr *expr = (NullIfExpr *) node; @@ -711,6 +729,11 @@ contain_nonstrict_functions_walker(Node *node, void *context) /* IS DISTINCT FROM is inherently non-strict */ return true; } + if (IsA(node, ScalarArrayOpExpr)) + { + /* inherently non-strict, consider null scalar and empty array */ + return true; + } if (IsA(node, BoolExpr)) { BoolExpr *expr = (BoolExpr *) node; @@ -2152,6 +2175,15 @@ expression_tree_walker(Node *node, return true; } break; + case T_ScalarArrayOpExpr: + { + ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node; + + if (expression_tree_walker((Node *) expr->args, + walker, context)) + return true; + } + break; case T_BoolExpr: { BoolExpr *expr = (BoolExpr *) node; @@ -2510,6 +2542,16 @@ expression_tree_mutator(Node *node, return (Node *) newnode; } break; + case T_ScalarArrayOpExpr: + { + ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node; + ScalarArrayOpExpr *newnode; + + FLATCOPY(newnode, expr, ScalarArrayOpExpr); + MUTATE(newnode->args, expr->args, List *); + return (Node *) newnode; + } + break; case T_BoolExpr: { BoolExpr *expr = (BoolExpr *) node; |
