From a191a169d6d0b9558da4519e66510c4540204a51 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Wed, 10 Jan 2007 18:06:05 +0000 Subject: Change the planner-to-executor API so that the planner tells the executor which comparison operators to use for plan nodes involving tuple comparison (Agg, Group, Unique, SetOp). Formerly the executor looked up the default equality operator for the datatype, which was really pretty shaky, since it's possible that the data being fed to the node is sorted according to some nondefault operator class that could have an incompatible idea of equality. The planner knows what it has sorted by and therefore can provide the right equality operator to use. Also, this change moves a couple of catalog lookups out of the executor and into the planner, which should help startup time for pre-planned queries by some small amount. Modify the planner to remove some other cavalier assumptions about always being able to use the default operators. Also add "nulls first/last" info to the Plan node for a mergejoin --- neither the executor nor the planner can cope yet, but at least the API is in place. --- src/include/nodes/plannodes.h | 25 +++++++++++++++++++------ src/include/nodes/relation.h | 25 ++++++++++++++----------- 2 files changed, 33 insertions(+), 17 deletions(-) (limited to 'src/include/nodes') diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h index 44002a9d45..c9aa190b33 100644 --- a/src/include/nodes/plannodes.h +++ b/src/include/nodes/plannodes.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/nodes/plannodes.h,v 1.88 2007/01/09 02:14:15 tgl Exp $ + * $PostgreSQL: pgsql/src/include/nodes/plannodes.h,v 1.89 2007/01/10 18:06:04 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -346,14 +346,23 @@ typedef struct NestLoop /* ---------------- * merge join node + * + * The expected ordering of each mergeable column is described by a btree + * opfamily OID, a direction (BTLessStrategyNumber or BTGreaterStrategyNumber) + * and a nulls-first flag. Note that the two sides of each mergeclause may + * be of different datatypes, but they are ordered the same way according to + * the common opfamily. The operator in each mergeclause must be an equality + * operator of the indicated opfamily. * ---------------- */ typedef struct MergeJoin { Join join; List *mergeclauses; /* mergeclauses as expression trees */ - List *mergefamilies; /* OID list of btree opfamilies */ - List *mergestrategies; /* integer list of btree strategies */ + /* these are arrays, but have the same length as the mergeclauses list: */ + Oid *mergeFamilies; /* per-clause OIDs of btree opfamilies */ + int *mergeStrategies; /* per-clause ordering (ASC or DESC) */ + bool *mergeNullsFirst; /* per-clause nulls ordering */ } MergeJoin; /* ---------------- @@ -399,6 +408,7 @@ typedef struct Group Plan plan; int numCols; /* number of grouping columns */ AttrNumber *grpColIdx; /* their indexes in the target list */ + Oid *grpOperators; /* equality operators to compare with */ } Group; /* --------------- @@ -428,6 +438,7 @@ typedef struct Agg AggStrategy aggstrategy; int numCols; /* number of grouping columns */ AttrNumber *grpColIdx; /* their indexes in the target list */ + Oid *grpOperators; /* equality operators to compare with */ long numGroups; /* estimated number of groups in input */ } Agg; @@ -439,7 +450,8 @@ typedef struct Unique { Plan plan; int numCols; /* number of columns to check for uniqueness */ - AttrNumber *uniqColIdx; /* indexes into the target list */ + AttrNumber *uniqColIdx; /* their indexes in the target list */ + Oid *uniqOperators; /* equality operators to compare with */ } Unique; /* ---------------- @@ -470,8 +482,9 @@ typedef struct SetOp SetOpCmd cmd; /* what to do */ int numCols; /* number of columns to check for * duplicate-ness */ - AttrNumber *dupColIdx; /* indexes into the target list */ - AttrNumber flagColIdx; + AttrNumber *dupColIdx; /* their indexes in the target list */ + Oid *dupOperators; /* equality operators to compare with */ + AttrNumber flagColIdx; /* where is the flag column, if any */ } SetOp; /* ---------------- diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h index 4e285a765a..f790037739 100644 --- a/src/include/nodes/relation.h +++ b/src/include/nodes/relation.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.131 2007/01/09 02:14:15 tgl Exp $ + * $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.132 2007/01/10 18:06:04 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -618,9 +618,11 @@ typedef JoinPath NestPath; * A mergejoin path has these fields. * * path_mergeclauses lists the clauses (in the form of RestrictInfos) - * that will be used in the merge. The parallel lists path_mergefamilies - * and path_mergestrategies specify the merge semantics for each clause - * (in effect, defining the relevant sort ordering for each clause). + * that will be used in the merge. The parallel arrays path_mergeFamilies, + * path_mergeStrategies, and path_mergeNullsFirst specify the merge semantics + * for each clause (i.e., define the relevant sort ordering for each clause). + * (XXX is this the most reasonable path-time representation? It's at least + * partially redundant with the pathkeys of the input paths.) * * Note that the mergeclauses are a subset of the parent relation's * restriction-clause list. Any join clauses that are not mergejoinable @@ -637,8 +639,10 @@ typedef struct MergePath { JoinPath jpath; List *path_mergeclauses; /* join clauses to be used for merge */ - List *path_mergefamilies; /* OID list of btree opfamilies */ - List *path_mergestrategies; /* integer list of btree strategies */ + /* these are arrays, but have the same length as the mergeclauses list: */ + Oid *path_mergeFamilies; /* per-clause OIDs of opfamilies */ + int *path_mergeStrategies; /* per-clause ordering (ASC or DESC) */ + bool *path_mergeNullsFirst; /* per-clause nulls ordering */ List *outersortkeys; /* keys for explicit sort, if any */ List *innersortkeys; /* keys for explicit sort, if any */ } MergePath; @@ -885,6 +889,9 @@ typedef struct OuterJoinInfo * the order of joining and use special join methods at some join points. * We record information about each such IN clause in an InClauseInfo struct. * These structs are kept in the PlannerInfo node's in_info_list. + * + * Note: sub_targetlist is just a list of Vars or expressions; it does not + * contain TargetEntry nodes. */ typedef struct InClauseInfo @@ -893,11 +900,7 @@ typedef struct InClauseInfo Relids lefthand; /* base relids in lefthand expressions */ Relids righthand; /* base relids coming from the subselect */ List *sub_targetlist; /* targetlist of original RHS subquery */ - - /* - * Note: sub_targetlist is just a list of Vars or expressions; it does not - * contain TargetEntry nodes. - */ + List *in_operators; /* OIDs of the IN's equality operator(s) */ } InClauseInfo; /* -- cgit v1.2.1