canon-pathkeys-as-rbtree-3-ctxdiff.patch
application/octet-stream
Filename: canon-pathkeys-as-rbtree-3-ctxdiff.patch
Type: application/octet-stream
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: context
| File | + | − |
|---|---|---|
| src/backend/nodes/Makefile | 1 | 1 |
| src/backend/nodes/outfuncs.c | 21 | 1 |
| src/backend/nodes/tree.c | 65 | 0 |
| src/backend/optimizer/path/pathkeys.c | 73 | 14 |
| src/backend/optimizer/plan/planmain.c | 4 | 2 |
| src/backend/optimizer/plan/planner.c | 1 | 0 |
| src/include/nodes/nodes.h | 5 | 0 |
| src/include/nodes/pg_tree.h | 50 | 0 |
| src/include/nodes/primnodes.h | 1 | 0 |
| src/include/nodes/relation.h | 1 | 1 |
| src/include/optimizer/paths.h | 4 | 0 |
diff -dcrpN postgresql-9.0rc1.orig/src/backend/nodes/Makefile postgresql-9.0rc1/src/backend/nodes/Makefile
*** postgresql-9.0rc1.orig/src/backend/nodes/Makefile 2008-02-19 11:30:07.000000000 +0100
--- postgresql-9.0rc1/src/backend/nodes/Makefile 2010-09-07 10:20:24.000000000 +0200
*************** subdir = src/backend/nodes
*** 12,18 ****
top_builddir = ../../..
include $(top_builddir)/src/Makefile.global
! OBJS = nodeFuncs.o nodes.o list.o bitmapset.o tidbitmap.o \
copyfuncs.o equalfuncs.o makefuncs.o \
outfuncs.o readfuncs.o print.o read.o params.o value.o
--- 12,18 ----
top_builddir = ../../..
include $(top_builddir)/src/Makefile.global
! OBJS = nodeFuncs.o nodes.o list.o tree.o bitmapset.o tidbitmap.o \
copyfuncs.o equalfuncs.o makefuncs.o \
outfuncs.o readfuncs.o print.o read.o params.o value.o
diff -dcrpN postgresql-9.0rc1.orig/src/backend/nodes/outfuncs.c postgresql-9.0rc1/src/backend/nodes/outfuncs.c
*** postgresql-9.0rc1.orig/src/backend/nodes/outfuncs.c 2010-08-18 17:22:00.000000000 +0200
--- postgresql-9.0rc1/src/backend/nodes/outfuncs.c 2010-09-07 10:18:00.000000000 +0200
*************** _outList(StringInfo str, List *node)
*** 175,180 ****
--- 175,198 ----
appendStringInfoChar(str, ')');
}
+ static void
+ _outTree(StringInfo str, Tree *node)
+ {
+ TreeCell *element;
+
+ appendStringInfoChar(str, '(');
+
+ rb_begin_iterate(node->tree, LeftRightWalk);
+ element = (TreeCell *)rb_iterate(node->tree);
+ while (element)
+ {
+ _outNode(str, element->node);
+ element = (TreeCell *)rb_iterate(node->tree);
+ }
+
+ appendStringInfoChar(str, ')');
+ }
+
/*
* _outBitmapset -
* converts a bitmap set of integers
*************** _outPlannerInfo(StringInfo str, PlannerI
*** 1545,1551 ****
WRITE_NODE_FIELD(init_plans);
WRITE_NODE_FIELD(cte_plan_ids);
WRITE_NODE_FIELD(eq_classes);
! WRITE_NODE_FIELD(canon_pathkeys);
WRITE_NODE_FIELD(left_join_clauses);
WRITE_NODE_FIELD(right_join_clauses);
WRITE_NODE_FIELD(full_join_clauses);
--- 1563,1569 ----
WRITE_NODE_FIELD(init_plans);
WRITE_NODE_FIELD(cte_plan_ids);
WRITE_NODE_FIELD(eq_classes);
! WRITE_NODE_FIELD(rb_canon_pathkeys);
WRITE_NODE_FIELD(left_join_clauses);
WRITE_NODE_FIELD(right_join_clauses);
WRITE_NODE_FIELD(full_join_clauses);
*************** _outNode(StringInfo str, void *obj)
*** 2451,2456 ****
--- 2469,2476 ----
appendStringInfo(str, "<>");
else if (IsA(obj, List) ||IsA(obj, IntList) || IsA(obj, OidList))
_outList(str, obj);
+ else if (IsA(obj, Tree))
+ _outTree(str, obj);
else if (IsA(obj, Integer) ||
IsA(obj, Float) ||
IsA(obj, String) ||
diff -dcrpN postgresql-9.0rc1.orig/src/backend/nodes/tree.c postgresql-9.0rc1/src/backend/nodes/tree.c
*** postgresql-9.0rc1.orig/src/backend/nodes/tree.c 1970-01-01 01:00:00.000000000 +0100
--- postgresql-9.0rc1/src/backend/nodes/tree.c 2010-09-07 14:06:42.000000000 +0200
***************
*** 0 ****
--- 1,65 ----
+ /*-------------------------------------------------------------------------
+ *
+ * tree.c
+ * implementation for PostgreSQL generic rbtree package
+ *
+ *
+ * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ * $PostgreSQL: pgsql/src/backend/nodes/list.c,v 1.74 2010/02/13 02:34:11 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+ #include "postgres.h"
+
+ #include "nodes/pg_tree.h"
+ #include "utils/rbtree.h"
+
+ RBNode *tree_allocfunc(void *arg)
+ {
+ return (RBNode *)palloc(sizeof(TreeCell));
+ }
+
+ /*
+ * Return a freshly allocated Tree.
+ */
+ Tree *
+ new_tree(rb_comparator comparator, rb_allocfunc allocfunc, void *arg)
+ {
+ Tree *tree = makeNode(Tree);
+
+ tree->tree = rb_create(sizeof(TreeCell), comparator, NULL, allocfunc, NULL, arg);
+
+ return tree;
+ }
+
+ Node *
+ tree_find(Tree *tree, Node *node)
+ {
+ TreeCell *cell = palloc(sizeof(TreeCell));
+ TreeCell *result;
+
+ cell->node = node;
+
+ result = (TreeCell *)rb_find(tree->tree, (RBNode *)cell);
+
+ pfree(cell);
+
+ if (result == NULL)
+ return NULL;
+
+ return result->node;
+ }
+
+ void
+ tree_add(Tree *tree, Node *node)
+ {
+ TreeCell *rbnode = palloc(sizeof(TreeCell));
+ bool isNew;
+
+ rbnode->node = node;
+ rb_insert(tree->tree, (RBNode *)rbnode, &isNew);
+ }
diff -dcrpN postgresql-9.0rc1.orig/src/backend/optimizer/path/pathkeys.c postgresql-9.0rc1/src/backend/optimizer/path/pathkeys.c
*** postgresql-9.0rc1.orig/src/backend/optimizer/path/pathkeys.c 2010-02-26 03:00:45.000000000 +0100
--- postgresql-9.0rc1/src/backend/optimizer/path/pathkeys.c 2010-09-07 15:41:49.000000000 +0200
*************** makePathKey(EquivalenceClass *eclass, Oi
*** 71,76 ****
--- 71,137 ----
return pk;
}
+ RBNode *
+ pathkeys_allocfunc(void *arg)
+ {
+ PlannerInfo *root = arg;
+ MemoryContext oldcontext;
+ RBNode *node;
+
+ oldcontext = MemoryContextSwitchTo(root->planner_cxt);
+
+ node = palloc(sizeof(TreeCell));
+
+ MemoryContextSwitchTo(oldcontext);
+
+ return node;
+ }
+
+ int
+ pathkeys_comparator(const RBNode *a, const RBNode *b, void *arg)
+ {
+ TreeCell *left = (TreeCell *)a;
+ TreeCell *right = (TreeCell *)b;
+ PathKey *pk_left = (PathKey *)left->node;
+ PathKey *pk_right = (PathKey *)right->node;
+ long val1, val2;
+
+ Assert((pk_left != NULL));
+ Assert((pk_right != NULL));
+
+ val1 = (long)pk_left->pk_eclass;
+ val2 = (long)pk_right->pk_eclass;
+
+ if (val1 < val2)
+ return -1;
+ else if (val1 > val2)
+ return 1;
+
+ if (pk_left->pk_opfamily < pk_right->pk_opfamily)
+ return -1;
+ else if (pk_left->pk_opfamily > pk_right->pk_opfamily)
+ return 1;
+
+ if (pk_left->pk_strategy < pk_right->pk_strategy)
+ return -1;
+ else if (pk_left->pk_strategy > pk_right->pk_strategy)
+ return 1;
+
+ if (pk_left->pk_nulls_first < pk_right->pk_nulls_first)
+ return -1;
+ else if (pk_left->pk_nulls_first > pk_right->pk_nulls_first)
+ return 1;
+
+ if (pk_left == NULL)
+ elog(ERROR, "pk_left NULL");
+ if (pk_right == NULL)
+ elog(ERROR, "pk_right NULL");
+
+ return 0;
+ }
+
+
+
/*
* make_canonical_pathkey
* Given the parameters for a PathKey, find any pre-existing matching
*************** make_canonical_pathkey(PlannerInfo *root
*** 85,119 ****
EquivalenceClass *eclass, Oid opfamily,
int strategy, bool nulls_first)
{
! PathKey *pk;
! ListCell *lc;
MemoryContext oldcontext;
/* The passed eclass might be non-canonical, so chase up to the top */
while (eclass->ec_merged)
eclass = eclass->ec_merged;
- foreach(lc, root->canon_pathkeys)
- {
- pk = (PathKey *) lfirst(lc);
- if (eclass == pk->pk_eclass &&
- opfamily == pk->pk_opfamily &&
- strategy == pk->pk_strategy &&
- nulls_first == pk->pk_nulls_first)
- return pk;
- }
-
/*
* Be sure canonical pathkeys are allocated in the main planning context.
* Not an issue in normal planning, but it is for GEQO.
*/
oldcontext = MemoryContextSwitchTo(root->planner_cxt);
! pk = makePathKey(eclass, opfamily, strategy, nulls_first);
! root->canon_pathkeys = lappend(root->canon_pathkeys, pk);
MemoryContextSwitchTo(oldcontext);
return pk;
}
--- 146,178 ----
EquivalenceClass *eclass, Oid opfamily,
int strategy, bool nulls_first)
{
! PathKey *pk, *pk_new;
MemoryContext oldcontext;
/* The passed eclass might be non-canonical, so chase up to the top */
while (eclass->ec_merged)
eclass = eclass->ec_merged;
/*
* Be sure canonical pathkeys are allocated in the main planning context.
* Not an issue in normal planning, but it is for GEQO.
*/
oldcontext = MemoryContextSwitchTo(root->planner_cxt);
! pk_new = makePathKey(eclass, opfamily, strategy, nulls_first);
MemoryContextSwitchTo(oldcontext);
+ pk = (PathKey *) tree_find(root->rb_canon_pathkeys, (Node *)pk_new);
+
+ if (pk)
+ pfree(pk_new);
+ else
+ {
+ tree_add(root->rb_canon_pathkeys, (Node *)pk_new);
+ pk = pk_new;
+ }
+
return pk;
}
diff -dcrpN postgresql-9.0rc1.orig/src/backend/optimizer/plan/planmain.c postgresql-9.0rc1/src/backend/optimizer/plan/planmain.c
*** postgresql-9.0rc1.orig/src/backend/optimizer/plan/planmain.c 2010-07-06 21:18:56.000000000 +0200
--- postgresql-9.0rc1/src/backend/optimizer/plan/planmain.c 2010-09-07 14:29:40.000000000 +0200
***************
*** 20,31 ****
--- 20,33 ----
*/
#include "postgres.h"
+ #include "nodes/pg_tree.h"
#include "optimizer/cost.h"
#include "optimizer/pathnode.h"
#include "optimizer/paths.h"
#include "optimizer/placeholder.h"
#include "optimizer/planmain.h"
#include "optimizer/tlist.h"
+ #include "utils/rbtree.h"
#include "utils/selfuncs.h"
*************** query_planner(PlannerInfo *root, List *t
*** 116,122 ****
* We still are required to canonicalize any pathkeys, in case it's
* something like "SELECT 2+2 ORDER BY 1".
*/
! root->canon_pathkeys = NIL;
root->query_pathkeys = canonicalize_pathkeys(root,
root->query_pathkeys);
root->group_pathkeys = canonicalize_pathkeys(root,
--- 118,124 ----
* We still are required to canonicalize any pathkeys, in case it's
* something like "SELECT 2+2 ORDER BY 1".
*/
! root->rb_canon_pathkeys = new_tree(pathkeys_comparator, pathkeys_allocfunc, root);
root->query_pathkeys = canonicalize_pathkeys(root,
root->query_pathkeys);
root->group_pathkeys = canonicalize_pathkeys(root,
*************** query_planner(PlannerInfo *root, List *t
*** 144,150 ****
root->join_rel_hash = NULL;
root->join_rel_level = NULL;
root->join_cur_level = 0;
! root->canon_pathkeys = NIL;
root->left_join_clauses = NIL;
root->right_join_clauses = NIL;
root->full_join_clauses = NIL;
--- 146,152 ----
root->join_rel_hash = NULL;
root->join_rel_level = NULL;
root->join_cur_level = 0;
! root->rb_canon_pathkeys = new_tree(pathkeys_comparator, pathkeys_allocfunc, root);
root->left_join_clauses = NIL;
root->right_join_clauses = NIL;
root->full_join_clauses = NIL;
diff -dcrpN postgresql-9.0rc1.orig/src/backend/optimizer/plan/planner.c postgresql-9.0rc1/src/backend/optimizer/plan/planner.c
*** postgresql-9.0rc1.orig/src/backend/optimizer/plan/planner.c 2010-03-30 23:58:10.000000000 +0200
--- postgresql-9.0rc1/src/backend/optimizer/plan/planner.c 2010-09-07 14:12:39.000000000 +0200
*************** subquery_planner(PlannerGlobal *glob, Qu
*** 305,310 ****
--- 305,311 ----
root->init_plans = NIL;
root->cte_plan_ids = NIL;
root->eq_classes = NIL;
+ root->rb_canon_pathkeys = new_tree(pathkeys_comparator, pathkeys_allocfunc, root);
root->append_rel_list = NIL;
root->rowMarks = NIL;
root->hasInheritedTarget = false;
diff -dcrpN postgresql-9.0rc1.orig/src/include/nodes/nodes.h postgresql-9.0rc1/src/include/nodes/nodes.h
*** postgresql-9.0rc1.orig/src/include/nodes/nodes.h 2010-03-29 00:59:33.000000000 +0200
--- postgresql-9.0rc1/src/include/nodes/nodes.h 2010-09-06 13:11:47.000000000 +0200
*************** typedef enum NodeTag
*** 252,257 ****
--- 252,262 ----
T_OidList,
/*
+ * TAGS FOR TREE NODES (pg_tree.h)
+ */
+ T_Tree,
+
+ /*
* TAGS FOR STATEMENT NODES (mostly in parsenodes.h)
*/
T_Query = 700,
diff -dcrpN postgresql-9.0rc1.orig/src/include/nodes/pg_tree.h postgresql-9.0rc1/src/include/nodes/pg_tree.h
*** postgresql-9.0rc1.orig/src/include/nodes/pg_tree.h 1970-01-01 01:00:00.000000000 +0100
--- postgresql-9.0rc1/src/include/nodes/pg_tree.h 2010-09-07 14:06:09.000000000 +0200
***************
*** 0 ****
--- 1,50 ----
+ /*-------------------------------------------------------------------------
+ *
+ * pg_tree.h
+ * interface for PostgreSQL generic rbtree package
+ *
+ * This package implements rbtree of Node * elements of the same type.
+ * It is a replacement of List for dealing with O(n^2) behaviour
+ * found with long lists.
+ *
+ * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * $PostgreSQL$
+ *
+ *-------------------------------------------------------------------------
+ */
+ #ifndef PG_TREE_H
+ #define PG_TREE_H
+
+ #include "nodes/nodes.h"
+ #include "utils/rbtree.h"
+
+ typedef struct TreeCell
+ {
+ RBNode treenode;
+ Node *node;
+ } TreeCell;
+
+
+ typedef struct Tree
+ {
+ NodeTag type; /* T_Tree */
+ RBTree *tree;
+ } Tree;
+
+ extern RBNode *tree_allocfunc(void *arg);
+
+ extern Tree *new_tree(rb_comparator comparator, rb_allocfunc allocfunc, void *arg);
+ extern Node *tree_find(Tree *tree, Node *node);
+ extern void tree_add(Tree *tree, Node *node);
+
+ /*
+ * tforeach -
+ * a convenience macro which loops through the tree elements
+ * in "inorder" walk to make it look like a list
+ */
+ #define tforeach(cell, t) \
+ for (rb_begin_iterate(t, LeftRightWalk) , (cell) = (TreeCell *)rb_iterate(t); (cell) != NULL; (cell) = (TreeCell *)rb_iterate(t))
+
+ #endif /* PG_TREE_H */
diff -dcrpN postgresql-9.0rc1.orig/src/include/nodes/primnodes.h postgresql-9.0rc1/src/include/nodes/primnodes.h
*** postgresql-9.0rc1.orig/src/include/nodes/primnodes.h 2010-02-26 03:01:25.000000000 +0100
--- postgresql-9.0rc1/src/include/nodes/primnodes.h 2010-09-07 10:16:45.000000000 +0200
***************
*** 19,24 ****
--- 19,25 ----
#include "access/attnum.h"
#include "nodes/pg_list.h"
+ #include "nodes/pg_tree.h"
/* ----------------------------------------------------------------
diff -dcrpN postgresql-9.0rc1.orig/src/include/nodes/relation.h postgresql-9.0rc1/src/include/nodes/relation.h
*** postgresql-9.0rc1.orig/src/include/nodes/relation.h 2010-07-06 21:19:00.000000000 +0200
--- postgresql-9.0rc1/src/include/nodes/relation.h 2010-09-07 14:31:16.000000000 +0200
*************** typedef struct PlannerInfo
*** 160,166 ****
List *eq_classes; /* list of active EquivalenceClasses */
! List *canon_pathkeys; /* list of "canonical" PathKeys */
List *left_join_clauses; /* list of RestrictInfos for
* mergejoinable outer join clauses
--- 160,166 ----
List *eq_classes; /* list of active EquivalenceClasses */
! Tree *rb_canon_pathkeys; /* tree of "canonical" PathKeys */
List *left_join_clauses; /* list of RestrictInfos for
* mergejoinable outer join clauses
diff -dcrpN postgresql-9.0rc1.orig/src/include/optimizer/paths.h postgresql-9.0rc1/src/include/optimizer/paths.h
*** postgresql-9.0rc1.orig/src/include/optimizer/paths.h 2010-01-02 17:58:07.000000000 +0100
--- postgresql-9.0rc1/src/include/optimizer/paths.h 2010-09-07 14:11:28.000000000 +0200
***************
*** 15,20 ****
--- 15,21 ----
#define PATHS_H
#include "nodes/relation.h"
+ #include "utils/rbtree.h"
/*
*************** typedef enum
*** 152,157 ****
--- 153,161 ----
PATHKEYS_DIFFERENT /* neither pathkey includes the other */
} PathKeysComparison;
+ extern RBNode *pathkeys_allocfunc(void *arg);
+ extern int pathkeys_comparator(const RBNode *a, const RBNode *b, void *arg);
+
extern List *canonicalize_pathkeys(PlannerInfo *root, List *pathkeys);
extern PathKeysComparison compare_pathkeys(List *keys1, List *keys2);
extern bool pathkeys_contained_in(List *keys1, List *keys2);
Binary files postgresql-9.0rc1.orig/src/timezone/gmon.out and postgresql-9.0rc1/src/timezone/gmon.out differ