Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
0b8b1fe3
Commit
0b8b1fe3
authored
May 17, 1999
by
Tom Lane
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Tighten coding in new_join_pathkey, which seems to be a hotspot
for GEQO ...
parent
1332c1e1
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
53 additions
and
96 deletions
+53
-96
src/backend/optimizer/path/pathkeys.c
src/backend/optimizer/path/pathkeys.c
+53
-96
No files found.
src/backend/optimizer/path/pathkeys.c
View file @
0b8b1fe3
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/pathkeys.c,v 1.
8 1999/04/30 03:59:06
tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/pathkeys.c,v 1.
9 1999/05/17 00:26:33
tgl Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -29,30 +29,34 @@ static int match_pathkey_joinkeys(List *pathkey, List *joinkeys,
...
@@ -29,30 +29,34 @@ static int match_pathkey_joinkeys(List *pathkey, List *joinkeys,
int
outer_or_inner
);
int
outer_or_inner
);
static
List
*
new_join_pathkey
(
List
*
pathkeys
,
List
*
join_rel_tlist
,
static
List
*
new_join_pathkey
(
List
*
pathkeys
,
List
*
join_rel_tlist
,
List
*
joinclauses
);
List
*
joinclauses
);
static
List
*
get_joinvars_for_var
(
Var
*
pathkey
,
List
**
considered_pathkeys
,
List
*
join_rel_tlist
,
List
*
joinclauses
);
/*
/*
--------------------
* Explanation of Path.pathkeys
* Explanation of Path.pathkeys
*
*
* Path.pathkeys is a List of List of Var nodes that represent the sort
* Path.pathkeys is a List of List of Var nodes that represent the sort
* order of the result generated by the Path.
* order of the result generated by the Path.
*
*
* In single/base relation RelOptInfo's, the Path's represent various ways
* In single/base relation RelOptInfo's, the Path's represent various ways
* of generate the relation. Sequential scan Paths have a NIL pathkeys.
* of generating the relation and the resulting ordering of the tuples.
* Index scans have Path.pathkeys that represent the chosen index. A
* Sequential scan Paths have NIL pathkeys, indicating no known ordering.
* single-key index pathkeys would be { {tab1_indexkey1} }. The pathkeys
* Index scans have Path.pathkeys that represent the chosen index.
* entry for a multi-key index would be { {tab1_indexkey1}, {tab1_indexkey2} }.
* A single-key index pathkeys would be { {tab1_indexkey1} }. For a
* multi-key index pathkeys would be { {tab1_indexkey1}, {tab1_indexkey2} },
* indicating major sort by indexkey1 and minor sort by indexkey2.
*
*
* Multi-relation RelOptInfo Path's are more complicated. Mergejoins are
* Multi-relation RelOptInfo Path's are more complicated. Mergejoins are
* only performed with equ
ajoins
("="). Because of this, the multi-relation
* only performed with equ
ijoins
("="). Because of this, the multi-relation
* path actually has more than one primary Var key. For example, a
* path actually has more than one primary Var key. For example, a
* mergejoin Path of "tab1.col1 = tab2.col1" would generate a pathkeys of
* mergejoin Path of "tab1.col1 = tab2.col1" would generate a pathkeys of
* { {tab1.col1, tab2.col1} }. This allows future joins to use either Var
* { {tab1.col1, tab2.col1} }, indicating that the major sort order of the
* as a pre-sorted key to prevent Mergejoins from having to re-sort the Path.
* Path can be taken to be *either* tab1.col1 or tab2.col1.
* They are equal, so they are both primary sort keys. This is why pathkeys
* They are equal, so they are both primary sort keys. This allows future
* is a List of Lists.
* joins to use either Var as a pre-sorted key to prevent upper Mergejoins
* from having to re-sort the Path. This is why pathkeys is a List of Lists.
*
* Note that while the order of the top list is meaningful (primary vs.
* secondary sort key), the order of each sublist is arbitrary.
*
*
* For multi-key sorts, if the outer is sorted by a multi-key index, the
* For multi-key sorts, if the outer is sorted by a multi-key index, the
* multi-key index remains after the join. If the inner has a multi-key
* multi-key index remains after the join. If the inner has a multi-key
...
@@ -60,11 +64,16 @@ static List *get_joinvars_for_var(Var *pathkey, List **considered_pathkeys,
...
@@ -60,11 +64,16 @@ static List *get_joinvars_for_var(Var *pathkey, List **considered_pathkeys,
* Mergejoins only join on the primary key. Currently, non-primary keys
* Mergejoins only join on the primary key. Currently, non-primary keys
* in the pathkeys List are of limited value.
* in the pathkeys List are of limited value.
*
*
* HashJoin has similar functionality. NestJoin does not perform sorting,
* Although Hashjoins also work only with equijoin operators, it is *not*
* and allows non-equajoins, so it does not allow useful pathkeys.
* safe to consider the output of a Hashjoin to be sorted in any particular
* order --- not even the outer path's order. This is true because the
* executor might have to split the join into multiple batches.
*
*
* -- bjm
* NestJoin does not perform sorting, and allows non-equijoins, so it does
* not allow useful pathkeys. (But couldn't we use the outer path's order?)
*
*
* -- bjm
*--------------------
*/
*/
/****************************************************************************
/****************************************************************************
...
@@ -228,7 +237,7 @@ get_cheapest_path_for_joinkeys(List *joinkeys,
...
@@ -228,7 +237,7 @@ get_cheapest_path_for_joinkeys(List *joinkeys,
int
outer_or_inner
)
int
outer_or_inner
)
{
{
Path
*
matched_path
=
NULL
;
Path
*
matched_path
=
NULL
;
List
*
i
=
NIL
;
List
*
i
;
foreach
(
i
,
paths
)
foreach
(
i
,
paths
)
{
{
...
@@ -337,14 +346,14 @@ new_join_pathkeys(List *outer_pathkeys,
...
@@ -337,14 +346,14 @@ new_join_pathkeys(List *outer_pathkeys,
List
*
join_rel_tlist
,
List
*
join_rel_tlist
,
List
*
joinclauses
)
List
*
joinclauses
)
{
{
List
*
outer_pathkey
=
NIL
;
List
*
final_pathkeys
=
NIL
;
List
*
final_pathkeys
=
NIL
;
List
*
new_pathkey
;
List
*
i
;
List
*
i
=
NIL
;
foreach
(
i
,
outer_pathkeys
)
foreach
(
i
,
outer_pathkeys
)
{
{
outer_pathkey
=
lfirst
(
i
);
List
*
outer_pathkey
=
lfirst
(
i
);
List
*
new_pathkey
;
new_pathkey
=
new_join_pathkey
(
outer_pathkey
,
join_rel_tlist
,
new_pathkey
=
new_join_pathkey
(
outer_pathkey
,
join_rel_tlist
,
joinclauses
);
joinclauses
);
if
(
new_pathkey
!=
NIL
)
if
(
new_pathkey
!=
NIL
)
...
@@ -355,19 +364,18 @@ new_join_pathkeys(List *outer_pathkeys,
...
@@ -355,19 +364,18 @@ new_join_pathkeys(List *outer_pathkeys,
/*
/*
* new_join_pathkey
* new_join_pathkey
* Finds new vars that become pathkeys due to qualification clauses that
* Generate an individual pathkey sublist, consisting of the outer vars
* contain any previously considered pathkeys. These new pathkeys plus the
* already mentioned in 'pathkey' plus any inner vars that are joined to
* pathkeys from 'pathkeys' form a new pathkey for the join relation.
* them (and thus can now also be considered path keys, per discussion
* at the top of this file).
*
*
* Note that each returned pathkey is the var node found in
* Note that each returned pathkey is the var node found in
* 'join_rel_tlist' rather than the joinclause var node.
* 'join_rel_tlist' rather than the joinclause var node.
* (Is this important?) Also, we return a fully copied list
* that does not share any subnodes with existing data structures.
* (Is that important, either?)
*
*
* 'pathkeys' is a list of pathkeys for which matching pathkeys are to be
* Returns a new pathkey (list of pathkey variables).
* found
* 'considered_pathkeys' is the current list of all pathkeys corresponding
* to a given pathkey
*
* Returns a new pathkey(list of pathkeys).
*
*
*/
*/
static
List
*
static
List
*
...
@@ -375,84 +383,33 @@ new_join_pathkey(List *pathkey,
...
@@ -375,84 +383,33 @@ new_join_pathkey(List *pathkey,
List
*
join_rel_tlist
,
List
*
join_rel_tlist
,
List
*
joinclauses
)
List
*
joinclauses
)
{
{
List
*
final
_pathkey
=
NIL
;
List
*
new
_pathkey
=
NIL
;
List
*
i
=
NIL
;
List
*
i
,
List
*
considered_pathkeys
=
NIL
;
*
j
;
foreach
(
i
,
pathkey
)
foreach
(
i
,
pathkey
)
{
{
Var
*
key
=
(
Var
*
)
lfirst
(
i
);
Var
*
key
=
(
Var
*
)
lfirst
(
i
);
List
*
joined_keys
;
Expr
*
tlist_key
;
Expr
*
tlist_key
;
Assert
(
key
);
Assert
(
key
);
joined_keys
=
get_joinvars_for_var
(
key
,
&
considered_pathkeys
,
join_rel_tlist
,
joinclauses
);
if
(
joined_keys
)
{
considered_pathkeys
=
nconc
(
considered_pathkeys
,
joined_keys
);
final_pathkey
=
nconc
(
final_pathkey
,
joined_keys
);
}
tlist_key
=
matching_tlist_var
(
key
,
join_rel_tlist
);
tlist_key
=
matching_tlist_var
(
key
,
join_rel_tlist
);
if
(
tlist_key
&&
!
member
(
tlist_key
,
considered_pathkeys
))
if
(
tlist_key
&&
!
member
(
tlist_key
,
new_pathkey
))
{
new_pathkey
=
lcons
(
copyObject
(
tlist_key
),
new_pathkey
);
/*
* If pathkey is in the target list, and not considered,
* add it
*/
considered_pathkeys
=
lcons
(
tlist_key
,
considered_pathkeys
);
final_pathkey
=
lcons
(
tlist_key
,
final_pathkey
);
}
}
return
copyObject
(
final_pathkey
);
}
/*
foreach
(
j
,
joinclauses
)
* get_joinvars_for_var
* Returns a list of new pathkeys:
* (1) which are not listed in 'considered_pathkeys'
* (2) for which the "other" variable in some clause in 'joinclauses' is
* 'pathkey'
* (3) which are mentioned in 'join_rel_tlist'
*
* Note that each returned pathkey is the var node found in
* 'join_rel_tlist' rather than the joinclause var node.
*
* 'pathkey' is the var node for which we are trying to find matching
* clauses
*
* Returns a list of new pathkeys.
*
*/
static
List
*
get_joinvars_for_var
(
Var
*
key
,
List
**
considered_pathkeys
,
List
*
join_rel_tlist
,
List
*
joinclauses
)
{
List
*
final_pathkey
=
NIL
;
Expr
*
joinclause
;
List
*
i
;
Expr
*
tlist_other_var
;
foreach
(
i
,
joinclauses
)
{
{
joinclause
=
lfirst
(
i
);
Expr
*
joinclause
=
lfirst
(
j
);
Expr
*
tlist_other_var
;
tlist_other_var
=
matching_tlist_var
(
tlist_other_var
=
matching_tlist_var
(
other_join_clause_var
(
key
,
joinclause
),
other_join_clause_var
(
key
,
joinclause
),
join_rel_tlist
);
join_rel_tlist
);
if
(
tlist_other_var
&&
if
(
tlist_other_var
&&
!
member
(
tlist_other_var
,
new_pathkey
))
!
member
(
tlist_other_var
,
*
considered_pathkeys
))
new_pathkey
=
lcons
(
copyObject
(
tlist_other_var
),
new_pathkey
);
{
/*
* The key has a join variable that is in the target list,
* and has not been considered.
*/
*
considered_pathkeys
=
lcons
(
tlist_other_var
,
*
considered_pathkeys
);
final_pathkey
=
lcons
(
tlist_other_var
,
final_pathkey
);
}
}
}
}
return
final_pathkey
;
return
new_pathkey
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment