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
fe35ffe7
Commit
fe35ffe7
authored
Feb 09, 1999
by
Bruce Momjian
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Major optimizer improvement for joining a large number of tables.
parent
be948af2
Changes
21
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
277 additions
and
139 deletions
+277
-139
src/backend/nodes/copyfuncs.c
src/backend/nodes/copyfuncs.c
+9
-8
src/backend/nodes/equalfuncs.c
src/backend/nodes/equalfuncs.c
+13
-13
src/backend/nodes/freefuncs.c
src/backend/nodes/freefuncs.c
+8
-6
src/backend/nodes/list.c
src/backend/nodes/list.c
+3
-3
src/backend/nodes/outfuncs.c
src/backend/nodes/outfuncs.c
+49
-2
src/backend/nodes/readfuncs.c
src/backend/nodes/readfuncs.c
+54
-13
src/backend/optimizer/README
src/backend/optimizer/README
+47
-23
src/backend/optimizer/geqo/geqo_paths.c
src/backend/optimizer/geqo/geqo_paths.c
+2
-2
src/backend/optimizer/path/indxpath.c
src/backend/optimizer/path/indxpath.c
+4
-3
src/backend/optimizer/path/joinpath.c
src/backend/optimizer/path/joinpath.c
+5
-5
src/backend/optimizer/path/joinutils.c
src/backend/optimizer/path/joinutils.c
+2
-3
src/backend/optimizer/path/mergeutils.c
src/backend/optimizer/path/mergeutils.c
+7
-6
src/backend/optimizer/path/orindxpath.c
src/backend/optimizer/path/orindxpath.c
+4
-3
src/backend/optimizer/path/prune.c
src/backend/optimizer/path/prune.c
+2
-2
src/backend/optimizer/plan/createplan.c
src/backend/optimizer/plan/createplan.c
+4
-5
src/backend/optimizer/util/keys.c
src/backend/optimizer/util/keys.c
+2
-2
src/backend/optimizer/util/pathnode.c
src/backend/optimizer/util/pathnode.c
+47
-24
src/backend/parser/gram.c
src/backend/parser/gram.c
+6
-10
src/backend/parser/scan.c
src/backend/parser/scan.c
+2
-2
src/include/nodes/nodes.h
src/include/nodes/nodes.h
+2
-1
src/include/nodes/relation.h
src/include/nodes/relation.h
+5
-3
No files found.
src/backend/nodes/copyfuncs.c
View file @
fe35ffe7
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.6
3 1999/02/08 04:29:03
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.6
4 1999/02/09 03:51:12
momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -1093,25 +1093,26 @@ CopyPathFields(Path *from, Path *newnode)
newnode
->
path_cost
=
from
->
path_cost
;
newnode
->
path_order
.
ordtype
=
from
->
path_order
.
ordtype
;
if
(
from
->
path_order
.
ordtype
==
SORTOP_ORDER
)
newnode
->
path_order
=
makeNode
(
PathOrder
);
newnode
->
path_order
->
ordtype
=
from
->
path_order
->
ordtype
;
if
(
from
->
path_order
->
ordtype
==
SORTOP_ORDER
)
{
int
len
,
i
;
Oid
*
ordering
=
from
->
path_order
.
ord
.
sortop
;
Oid
*
ordering
=
from
->
path_order
->
ord
.
sortop
;
if
(
ordering
)
{
for
(
len
=
0
;
ordering
[
len
]
!=
0
;
len
++
)
;
newnode
->
path_order
.
ord
.
sortop
=
(
Oid
*
)
palloc
(
sizeof
(
Oid
)
*
(
len
+
1
));
newnode
->
path_order
->
ord
.
sortop
=
(
Oid
*
)
palloc
(
sizeof
(
Oid
)
*
(
len
+
1
));
for
(
i
=
0
;
i
<
len
;
i
++
)
newnode
->
path_order
.
ord
.
sortop
[
i
]
=
ordering
[
i
];
newnode
->
path_order
.
ord
.
sortop
[
len
]
=
0
;
newnode
->
path_order
->
ord
.
sortop
[
i
]
=
ordering
[
i
];
newnode
->
path_order
->
ord
.
sortop
[
len
]
=
0
;
}
}
else
Node_Copy
(
from
,
newnode
,
path_order
.
ord
.
merge
);
Node_Copy
(
from
,
newnode
,
path_order
->
ord
.
merge
);
Node_Copy
(
from
,
newnode
,
keys
);
...
...
src/backend/nodes/equalfuncs.c
View file @
fe35ffe7
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.2
6 1999/02/08 04:29:04
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.2
7 1999/02/09 03:51:12
momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -337,33 +337,33 @@ _equalPath(Path *a, Path *b)
/*
* if (a->path_cost != b->path_cost) return(false);
*/
if
(
a
->
path_order
.
ordtype
==
SORTOP_ORDER
)
if
(
a
->
path_order
->
ordtype
==
SORTOP_ORDER
)
{
int
i
=
0
;
if
(
a
->
path_order
.
ord
.
sortop
==
NULL
||
b
->
path_order
.
ord
.
sortop
==
NULL
)
if
(
a
->
path_order
->
ord
.
sortop
==
NULL
||
b
->
path_order
->
ord
.
sortop
==
NULL
)
{
if
(
a
->
path_order
.
ord
.
sortop
!=
b
->
path_order
.
ord
.
sortop
)
if
(
a
->
path_order
->
ord
.
sortop
!=
b
->
path_order
->
ord
.
sortop
)
return
false
;
}
else
{
while
(
a
->
path_order
.
ord
.
sortop
[
i
]
!=
0
&&
b
->
path_order
.
ord
.
sortop
[
i
]
!=
0
)
while
(
a
->
path_order
->
ord
.
sortop
[
i
]
!=
0
&&
b
->
path_order
->
ord
.
sortop
[
i
]
!=
0
)
{
if
(
a
->
path_order
.
ord
.
sortop
[
i
]
!=
b
->
path_order
.
ord
.
sortop
[
i
])
if
(
a
->
path_order
->
ord
.
sortop
[
i
]
!=
b
->
path_order
->
ord
.
sortop
[
i
])
return
false
;
i
++
;
}
if
(
a
->
path_order
.
ord
.
sortop
[
i
]
!=
0
||
b
->
path_order
.
ord
.
sortop
[
i
]
!=
0
)
if
(
a
->
path_order
->
ord
.
sortop
[
i
]
!=
0
||
b
->
path_order
->
ord
.
sortop
[
i
]
!=
0
)
return
false
;
}
}
else
{
if
(
!
equal
(
a
->
path_order
.
ord
.
merge
,
b
->
path_order
.
ord
.
merge
))
if
(
!
equal
(
a
->
path_order
->
ord
.
merge
,
b
->
path_order
->
ord
.
merge
))
return
false
;
}
if
(
!
equal
(
a
->
keys
,
b
->
keys
))
...
...
@@ -433,9 +433,9 @@ _equalHashPath(HashPath *a, HashPath *b)
return
false
;
if
(
!
equal
((
a
->
path_hashclauses
),
(
b
->
path_hashclauses
)))
return
false
;
if
(
!
equal
(
(
a
->
outerhashkeys
),
(
b
->
outerhashkeys
)
))
if
(
!
equal
(
a
->
outerhashkeys
,
b
->
outerhashkeys
))
return
false
;
if
(
!
equal
(
(
a
->
innerhashkeys
),
(
b
->
innerhashkeys
)
))
if
(
!
equal
(
a
->
innerhashkeys
,
b
->
innerhashkeys
))
return
false
;
return
true
;
}
...
...
src/backend/nodes/freefuncs.c
View file @
fe35ffe7
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/Attic/freefuncs.c,v 1.
2 1999/02/08 04:29:04
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/Attic/freefuncs.c,v 1.
3 1999/02/09 03:51:12
momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -756,13 +756,16 @@ _freeRelOptInfo(RelOptInfo * node)
static
void
FreePathFields
(
Path
*
node
)
{
if
(
node
->
path_order
.
ordtype
==
SORTOP_ORDER
)
if
(
node
->
path_order
->
ordtype
==
SORTOP_ORDER
)
{
if
(
node
->
path_order
.
ord
.
sortop
)
pfree
(
node
->
path_order
.
ord
.
sortop
);
if
(
node
->
path_order
->
ord
.
sortop
)
pfree
(
node
->
path_order
->
ord
.
sortop
);
}
else
freeObject
(
node
->
path_order
.
ord
.
merge
);
freeObject
(
node
->
path_order
->
ord
.
merge
);
pfree
(
node
->
path_order
);
/* is it an object, but we don't have
separate free for it */
freeObject
(
node
->
keys
);
...
...
@@ -1171,7 +1174,6 @@ freeObject(void *node)
switch
(
nodeTag
(
node
))
{
/*
* PLAN NODES
*/
...
...
src/backend/nodes/list.c
View file @
fe35ffe7
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/list.c,v 1.1
5 1998/09/01 04:29:05
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/list.c,v 1.1
6 1999/02/09 03:51:13
momjian Exp $
*
* NOTES
* XXX a few of the following functions are duplicated to handle
...
...
@@ -368,8 +368,8 @@ member(void *l1, List *l2)
List
*
i
;
foreach
(
i
,
l2
)
if
(
equal
((
Node
*
)
(
lfirst
(
i
)),
(
Node
*
)
l1
))
return
true
;
if
(
equal
((
Node
*
)
l1
,
(
Node
*
)
lfirst
(
i
)
))
return
true
;
return
false
;
}
...
...
src/backend/nodes/outfuncs.c
View file @
fe35ffe7
...
...
@@ -5,7 +5,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: outfuncs.c,v 1.6
5 1999/02/05 19:59:25
momjian Exp $
* $Id: outfuncs.c,v 1.6
6 1999/02/09 03:51:13
momjian Exp $
*
* NOTES
* Every (plan) node in POSTGRES has an associated "out" routine which
...
...
@@ -855,7 +855,7 @@ _outEState(StringInfo str, EState *node)
* Stuff from relation.h
*/
static
void
_outRelOptInfo
(
StringInfo
str
,
RelOptInfo
*
node
)
_outRelOptInfo
(
StringInfo
str
,
RelOptInfo
*
node
)
{
appendStringInfo
(
str
,
" RELOPTINFO :relids "
);
_outIntList
(
str
,
node
->
relids
);
...
...
@@ -924,6 +924,35 @@ _outRowMark(StringInfo str, RowMark *node)
appendStringInfo
(
str
,
" ROWMARK :rti %u :info %u"
,
node
->
rti
,
node
->
info
);
}
/*
* Path is a subclass of Node.
*/
static
void
_outPathOrder
(
StringInfo
str
,
PathOrder
*
node
)
{
appendStringInfo
(
str
,
" PATHORDER :ordtype %d "
,
node
->
ordtype
);
if
(
node
->
ordtype
==
SORTOP_ORDER
)
{
int
i
;
appendStringInfo
(
str
,
" :sortop "
);
if
(
node
->
ord
.
sortop
==
NULL
)
appendStringInfo
(
str
,
"<>"
);
else
{
for
(
i
=
0
;
node
->
ord
.
sortop
[
i
]
!=
0
;
i
++
)
appendStringInfo
(
str
,
" %d "
,
node
->
ord
.
sortop
[
i
]);
appendStringInfo
(
str
,
" %d "
,
0
);
}
}
else
{
appendStringInfo
(
str
,
" :merge "
);
_outNode
(
str
,
node
->
ord
.
merge
);
}
}
/*
* Path is a subclass of Node.
*/
...
...
@@ -934,6 +963,9 @@ _outPath(StringInfo str, Path *node)
node
->
pathtype
,
node
->
path_cost
);
_outNode
(
str
,
node
->
keys
);
appendStringInfo
(
str
,
" :path_order "
);
_outNode
(
str
,
node
->
path_order
);
}
/*
...
...
@@ -948,6 +980,9 @@ _outIndexPath(StringInfo str, IndexPath *node)
node
->
path
.
path_cost
);
_outNode
(
str
,
node
->
path
.
keys
);
appendStringInfo
(
str
,
" :path_order "
);
_outNode
(
str
,
node
->
path
.
path_order
);
appendStringInfo
(
str
,
" :indexid "
);
_outIntList
(
str
,
node
->
indexid
);
...
...
@@ -967,6 +1002,9 @@ _outJoinPath(StringInfo str, JoinPath *node)
node
->
path
.
path_cost
);
_outNode
(
str
,
node
->
path
.
keys
);
appendStringInfo
(
str
,
" :path_order "
);
_outNode
(
str
,
node
->
path
.
path_order
);
appendStringInfo
(
str
,
" :pathinfo "
);
_outNode
(
str
,
node
->
pathinfo
);
...
...
@@ -995,6 +1033,9 @@ _outMergePath(StringInfo str, MergePath *node)
node
->
jpath
.
path
.
path_cost
);
_outNode
(
str
,
node
->
jpath
.
path
.
keys
);
appendStringInfo
(
str
,
" :path_order "
);
_outNode
(
str
,
node
->
jpath
.
path
.
path_order
);
appendStringInfo
(
str
,
" :pathinfo "
);
_outNode
(
str
,
node
->
jpath
.
pathinfo
);
...
...
@@ -1032,6 +1073,9 @@ _outHashPath(StringInfo str, HashPath *node)
node
->
jpath
.
path
.
path_cost
);
_outNode
(
str
,
node
->
jpath
.
path
.
keys
);
appendStringInfo
(
str
,
" :path_order "
);
_outNode
(
str
,
node
->
jpath
.
path
.
path_order
);
appendStringInfo
(
str
,
" :pathinfo "
);
_outNode
(
str
,
node
->
jpath
.
pathinfo
);
...
...
@@ -1548,6 +1592,9 @@ _outNode(StringInfo str, void *obj)
case
T_RowMark
:
_outRowMark
(
str
,
obj
);
break
;
case
T_PathOrder
:
_outPathOrder
(
str
,
obj
);
break
;
case
T_Path
:
_outPath
(
str
,
obj
);
break
;
...
...
src/backend/nodes/readfuncs.c
View file @
fe35ffe7
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.5
0 1999/02/08 04:29:04
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.5
1 1999/02/09 03:51:13
momjian Exp $
*
* NOTES
* Most of the read functions for plan nodes are tested. (In fact, they
...
...
@@ -37,6 +37,7 @@
#include "utils/lsyscache.h"
#include "utils/syscache.h"
#include "catalog/pg_index.h"
#include "catalog/pg_type.h"
#include "nodes/primnodes.h"
...
...
@@ -1450,6 +1451,54 @@ _readRowMark()
return
local_node
;
}
/* ----------------
* _readPathOrder
*
* PathOrder is part of Path and it's subclasses.
* ----------------
*/
static
PathOrder
*
_readPathOrder
()
{
PathOrder
*
local_node
;
char
*
token
;
int
length
;
local_node
=
makeNode
(
PathOrder
);
token
=
lsptok
(
NULL
,
&
length
);
/* get :ordtype */
token
=
lsptok
(
NULL
,
&
length
);
/* now read it */
local_node
->
ordtype
=
atol
(
token
);
if
(
local_node
->
ordtype
==
SORTOP_ORDER
)
{
token
=
lsptok
(
NULL
,
&
length
);
/* get :sortop */
if
(
length
==
0
)
local_node
->
ord
.
sortop
=
NULL
;
else
{
int
i
=
-
1
;
local_node
->
ord
.
sortop
=
palloc
(
sizeof
(
Oid
)
*
(
INDEX_MAX_KEYS
+
1
));
do
{
i
++
;
Assert
(
i
<=
INDEX_MAX_KEYS
);
token
=
lsptok
(
NULL
,
&
length
);
/* now read it */
local_node
->
ord
.
sortop
[
i
]
=
strtoul
(
token
,
NULL
,
10
);
}
while
(
local_node
->
ord
.
sortop
[
i
]
!=
0
);
}
}
else
{
token
=
lsptok
(
NULL
,
&
length
);
/* get :merge */
local_node
->
ord
.
merge
=
nodeRead
(
true
);
/* now read it */
}
return
local_node
;
}
/* ----------------
* _readPath
*
...
...
@@ -1473,10 +1522,8 @@ _readPath()
token
=
lsptok
(
NULL
,
&
length
);
/* now read it */
local_node
->
path_cost
=
(
Cost
)
atof
(
token
);
#if 0
token
=
lsptok
(
NULL
,
&
length
);
/* get :path_order */
local_node->path_order = nodeRead(true); /* now read it */
#endif
local_node
->
path_order
=
nodeRead
(
true
);
/* now read it */
token
=
lsptok
(
NULL
,
&
length
);
/* get :keys */
local_node
->
keys
=
nodeRead
(
true
);
/* now read it */
...
...
@@ -1507,10 +1554,8 @@ _readIndexPath()
token
=
lsptok
(
NULL
,
&
length
);
/* now read it */
local_node
->
path
.
path_cost
=
(
Cost
)
atof
(
token
);
#if 0
token
=
lsptok
(
NULL
,
&
length
);
/* get :path_order */
local_node->path.path_order = nodeRead(true); /* now read it */
#endif
local_node
->
path
.
path_order
=
nodeRead
(
true
);
/* now read it */
token
=
lsptok
(
NULL
,
&
length
);
/* get :keys */
local_node
->
path
.
keys
=
nodeRead
(
true
);
/* now read it */
...
...
@@ -1548,10 +1593,8 @@ _readJoinPath()
token
=
lsptok
(
NULL
,
&
length
);
/* now read it */
local_node
->
path
.
path_cost
=
(
Cost
)
atof
(
token
);
#if 0
token
=
lsptok
(
NULL
,
&
length
);
/* get :path_order */
local_node
->
path
.
path_order
=
nodeRead
(
true
);
/* now read it */
#endif
token
=
lsptok
(
NULL
,
&
length
);
/* get :keys */
local_node
->
path
.
keys
=
nodeRead
(
true
);
/* now read it */
...
...
@@ -1615,10 +1658,8 @@ _readMergePath()
local_node
->
jpath
.
path
.
path_cost
=
(
Cost
)
atof
(
token
);
#if 0
token
=
lsptok
(
NULL
,
&
length
);
/* get :path_order */
local_node
->
jpath
.
path
.
path_order
=
nodeRead
(
true
);
/* now read it */
#endif
token
=
lsptok
(
NULL
,
&
length
);
/* get :keys */
local_node
->
jpath
.
path
.
keys
=
nodeRead
(
true
);
/* now read it */
...
...
@@ -1691,10 +1732,8 @@ _readHashPath()
local_node
->
jpath
.
path
.
path_cost
=
(
Cost
)
atof
(
token
);
#if 0
token
=
lsptok
(
NULL
,
&
length
);
/* get :path_order */
local_node
->
jpath
.
path
.
path_order
=
nodeRead
(
true
);
/* now read it */
#endif
token
=
lsptok
(
NULL
,
&
length
);
/* get :keys */
local_node
->
jpath
.
path
.
keys
=
nodeRead
(
true
);
/* now read it */
...
...
@@ -2071,6 +2110,8 @@ parsePlanString(void)
return_value
=
_readTargetEntry
();
else
if
(
!
strncmp
(
token
,
"RTE"
,
length
))
return_value
=
_readRangeTblEntry
();
else
if
(
!
strncmp
(
token
,
"PATHORDER"
,
length
))
return_value
=
_readPathOrder
();
else
if
(
!
strncmp
(
token
,
"PATH"
,
length
))
return_value
=
_readPath
();
else
if
(
!
strncmp
(
token
,
"INDEXPATH"
,
length
))
...
...
src/backend/optimizer/README
View file @
fe35ffe7
Summary
-------
The optimizer generates optimial query plans by doing several steps:
Take each relation in a query, and make a RelOptInfo structure for it.
1)
Take each relation in a query, and make a RelOptInfo structure for it.
Find each way of accessing the relation, called a Path, including
sequential and index scans, and add it to the RelOptInfo.path_order
list.
2) Join each RelOptInfo to each other RelOptInfo as specified in the
WHERE clause. At this point each RelOptInfo is a single relation, so
you are joining every relation to every relation it is joined to in the
WHERE clause.
Joins occur using two RelOptInfos. One is outer, the other inner.
Outers drive lookups of values in the inner. In a nested loop, lookups
of values in the inner occur by scanning to find each matching inner
row. In a mergejoin, inner rows are ordered, and are accessed in order,
so only one scan of inner is required to perform the entire join. In a
hashjoin, inner rows are hashed for lookups.
Each unique join combination becomes a new RelOptInfo. The RelOptInfo
is now the joining of two relations. RelOptInfo.path_order are various
paths to create the joined result, having different orderings depending
on the join method used.
3) At this point, every RelOptInfo is joined to each other again, with
a new relation added to each RelOptInfo. This continues until all
relations have been joined into one RelOptInfo, and the cheapest Path is
chosen.
SELECT *
FROM tab1, tab2, tab3, tab4
WHERE tab1.col = tab2.col AND
tab2.col = tab3.col AND
tab3.col = tab4.col
Tables 1, 2, 3, and 4 are joined as:
{1 2},{2 3},{3 4}
{1 2 3},{2 3 4}
{1 2 3 4}
SELECT *
FROM tab1, tab2, tab3, tab4
WHERE tab1.col = tab2.col AND
tab1.col = tab3.col AND
tab1.col = tab4.col
Tables 1, 2, 3, and 4 are joined as:
{1 2},{1 3},{1 4}
{1 2 3},{1 3 4},{1,2,4}
{1 2 3 4}
Optimizer Functions
-------------------
...
...
@@ -56,28 +102,6 @@ planner()
one relation, return
find selectivity of columns used in joins
-----find_join_paths()
Summary: With OPTIMIZER_DEBUG defined, you see:
Tables 1, 2, 3, and 4 are joined as:
{1 2},{1 3},{1 4},{2 3},{2 4}
{1 2 3},{1 2 4},{2 3 4}
{1 2 3 4}
Actual output tests show combinations:
{4 2},{3 2},{1 4},{1 3},{1 2}
{4 2 3},{1 4 2},{1 3 2}
{4 2 3 1}
Cheapest join order shows:
{4 2},{3 2},{1 4},{1 3},{1 2}
{3 2 4},{1 4 2},{1 3 2}
{1 4 2 3}
It first finds the best way to join each table to every other
table. It then takes those joined table combinations, and joins
them to the other joined table combinations, until all tables are
joined.
jump to geqo if needed
again:
find_join_rels():
...
...
src/backend/optimizer/geqo/geqo_paths.c
View file @
fe35ffe7
...
...
@@ -5,7 +5,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: geqo_paths.c,v 1.1
3 1999/02/08 04:29:06
momjian Exp $
* $Id: geqo_paths.c,v 1.1
4 1999/02/09 03:51:15
momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -113,7 +113,7 @@ geqo_rel_paths(RelOptInfo * rel)
{
path
=
(
Path
*
)
lfirst
(
y
);
if
(
!
path
->
path_order
.
ord
.
sortop
)
if
(
!
path
->
path_order
->
ord
.
sortop
)
break
;
}
...
...
src/backend/optimizer/path/indxpath.c
View file @
fe35ffe7
...
...
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.
39 1999/02/08 04:29:08
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.
40 1999/02/09 03:51:17
momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -1290,8 +1290,9 @@ index_innerjoin(Query *root, RelOptInfo * rel, List *clausegroup_list,
pathnode
->
path
.
pathtype
=
T_IndexScan
;
pathnode
->
path
.
parent
=
rel
;
pathnode
->
path
.
path_order
.
ordtype
=
SORTOP_ORDER
;
pathnode
->
path
.
path_order
.
ord
.
sortop
=
index
->
ordering
;
pathnode
->
path
.
path_order
=
makeNode
(
PathOrder
);
pathnode
->
path
.
path_order
->
ordtype
=
SORTOP_ORDER
;
pathnode
->
path
.
path_order
->
ord
.
sortop
=
index
->
ordering
;
pathnode
->
path
.
keys
=
NIL
;
/* not sure about this, bjm 1998/09/21 */
pathnode
->
indexid
=
index
->
relids
;
...
...
src/backend/optimizer/path/joinpath.c
View file @
fe35ffe7
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinpath.c,v 1.1
5 1999/02/08 04:29:11
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinpath.c,v 1.1
6 1999/02/09 03:51:19
momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -324,11 +324,11 @@ match_unsorted_outer(RelOptInfo * joinrel,
List
*
clauses
=
NIL
;
List
*
matchedJoinKeys
=
NIL
;
List
*
matchedJoinClauses
=
NIL
;
MergeInfo
*
xmergeinfo
=
(
MergeInfo
*
)
NULL
;
MergeInfo
*
xmergeinfo
=
(
MergeInfo
*
)
NULL
;
outerpath
=
(
Path
*
)
lfirst
(
i
);
outerpath_ordering
=
&
outerpath
->
path_order
;
outerpath_ordering
=
outerpath
->
path_order
;
if
(
outerpath_ordering
)
{
...
...
@@ -464,14 +464,14 @@ match_unsorted_inner(RelOptInfo * joinrel,
foreach
(
i
,
innerpath_list
)
{
MergeInfo
*
xmergeinfo
=
(
MergeInfo
*
)
NULL
;
MergeInfo
*
xmergeinfo
=
(
MergeInfo
*
)
NULL
;
List
*
clauses
=
NIL
;
List
*
matchedJoinKeys
=
NIL
;
List
*
matchedJoinClauses
=
NIL
;
innerpath
=
(
Path
*
)
lfirst
(
i
);
innerpath_ordering
=
&
innerpath
->
path_order
;
innerpath_ordering
=
innerpath
->
path_order
;
if
(
innerpath_ordering
)
{
...
...
src/backend/optimizer/path/joinutils.c
View file @
fe35ffe7
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/Attic/joinutils.c,v 1.1
1 1999/02/08 04:29:12
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/Attic/joinutils.c,v 1.1
2 1999/02/09 03:51:20
momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -218,8 +218,7 @@ match_paths_joinkeys(List *joinkeys,
key_match
=
every_func
(
joinkeys
,
path
->
keys
,
which_subkey
);
if
(
equal_path_ordering
(
ordering
,
&
path
->
path_order
)
&&
if
(
equal_path_ordering
(
ordering
,
path
->
path_order
)
&&
length
(
joinkeys
)
==
length
(
path
->
keys
)
&&
key_match
)
{
...
...
src/backend/optimizer/path/mergeutils.c
View file @
fe35ffe7
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/Attic/mergeutils.c,v 1.1
4 1999/02/08 04:29:12
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/Attic/mergeutils.c,v 1.1
5 1999/02/09 03:51:20
momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -52,16 +52,17 @@ group_clauses_by_order(List *restrictinfo_list,
* Create a new mergeinfo node and add it to 'mergeinfo-list'
* if one does not yet exist for this merge ordering.
*/
PathOrder
path_order
;
MergeInfo
*
xmergeinfo
;
PathOrder
*
path_order
;
MergeInfo
*
xmergeinfo
;
Expr
*
clause
=
restrictinfo
->
clause
;
Var
*
leftop
=
get_leftop
(
clause
);
Var
*
rightop
=
get_rightop
(
clause
);
JoinKey
*
keys
;
path_order
.
ordtype
=
MERGE_ORDER
;
path_order
.
ord
.
merge
=
merge_ordering
;
xmergeinfo
=
match_order_mergeinfo
(
&
path_order
,
mergeinfo_list
);
path_order
=
makeNode
(
PathOrder
);
path_order
->
ordtype
=
MERGE_ORDER
;
path_order
->
ord
.
merge
=
merge_ordering
;
xmergeinfo
=
match_order_mergeinfo
(
path_order
,
mergeinfo_list
);
if
(
inner_relid
==
leftop
->
varno
)
{
keys
=
makeNode
(
JoinKey
);
...
...
src/backend/optimizer/path/orindxpath.c
View file @
fe35ffe7
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/orindxpath.c,v 1.1
5 1999/02/08 04:29:12
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/orindxpath.c,v 1.1
6 1999/02/09 03:51:20
momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -104,13 +104,14 @@ create_or_index_paths(Query *root,
pathnode
->
path
.
pathtype
=
T_IndexScan
;
pathnode
->
path
.
parent
=
rel
;
pathnode
->
path
.
path_order
.
ordtype
=
SORTOP_ORDER
;
pathnode
->
path
.
path_order
=
makeNode
(
PathOrder
);
pathnode
->
path
.
path_order
->
ordtype
=
SORTOP_ORDER
;
/*
* This is an IndexScan, but it does index lookups based
* on the order of the fields specified in the WHERE clause,
* not in any order, so the sortop is NULL.
*/
pathnode
->
path
.
path_order
.
ord
.
sortop
=
NULL
;
pathnode
->
path
.
path_order
->
ord
.
sortop
=
NULL
;
pathnode
->
path
.
keys
=
NIL
;
/* not sure about this, bjm 1998/09/21 */
pathnode
->
indexqual
=
lcons
(
clausenode
,
NIL
);
...
...
src/backend/optimizer/path/prune.c
View file @
fe35ffe7
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/Attic/prune.c,v 1.2
4 1999/02/08 04:29:12
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/Attic/prune.c,v 1.2
5 1999/02/09 03:51:21
momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -109,7 +109,7 @@ prune_rel_paths(List *rel_list)
{
path
=
(
Path
*
)
lfirst
(
y
);
if
(
!
path
->
path_order
.
ord
.
sortop
)
if
(
!
path
->
path_order
->
ord
.
sortop
)
break
;
}
cheapest
=
(
JoinPath
*
)
prune_rel_path
(
rel
,
path
);
...
...
src/backend/optimizer/plan/createplan.c
View file @
fe35ffe7
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.3
8 1999/02/08 04:29:17
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.3
9 1999/02/09 03:51:21
momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -529,14 +529,14 @@ create_mergejoin_node(MergePath *best_path,
outer_tlist
,
inner_tlist
));
opcode
=
get_opcode
((
best_path
->
jpath
.
path
.
path_order
.
ord
.
merge
)
->
join_operator
);
opcode
=
get_opcode
((
best_path
->
jpath
.
path
.
path_order
->
ord
.
merge
)
->
join_operator
);
outer_order
=
(
Oid
*
)
palloc
(
sizeof
(
Oid
)
*
2
);
outer_order
[
0
]
=
(
best_path
->
jpath
.
path
.
path_order
.
ord
.
merge
)
->
left_operator
;
outer_order
[
0
]
=
(
best_path
->
jpath
.
path
.
path_order
->
ord
.
merge
)
->
left_operator
;
outer_order
[
1
]
=
0
;
inner_order
=
(
Oid
*
)
palloc
(
sizeof
(
Oid
)
*
2
);
inner_order
[
0
]
=
(
best_path
->
jpath
.
path
.
path_order
.
ord
.
merge
)
->
right_operator
;
inner_order
[
0
]
=
(
best_path
->
jpath
.
path
.
path_order
->
ord
.
merge
)
->
right_operator
;
inner_order
[
1
]
=
0
;
/*
...
...
@@ -825,7 +825,6 @@ set_temp_tlist_operators(List *tlist, List *pathkeys, Oid *operators)
resdom
=
tlist_member
((
Var
*
)
keys
,
tlist
);
if
(
resdom
)
{
/*
* Order the resdom keys and replace the operator OID for each
* key with the regproc OID.
...
...
src/backend/optimizer/util/keys.c
View file @
fe35ffe7
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/Attic/keys.c,v 1.1
0 1999/02/01 04:20:50 tgl
Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/Attic/keys.c,v 1.1
1 1999/02/09 03:51:26 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -125,7 +125,7 @@ samekeys(List *keys1, List *keys2)
for
(
key1
=
keys1
,
key2
=
keys2
;
key1
!=
NIL
&&
key2
!=
NIL
;
key1
=
lnext
(
key1
),
key2
=
lnext
(
key2
))
if
(
!
member
(
lfirst
(
key1
),
lfirst
(
key2
)))
if
(
!
member
(
lfirst
(
(
List
*
)
lfirst
(
key1
)
),
lfirst
(
key2
)))
return
false
;
/* Now the result should be true if list keys2 has at least as many
...
...
src/backend/optimizer/util/pathnode.c
View file @
fe35ffe7
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/pathnode.c,v 1.2
0 1999/02/08 04:29:21
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/pathnode.c,v 1.2
1 1999/02/09 03:51:27
momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -164,9 +164,31 @@ better_path(Path *new_path, List *unique_paths, bool *noOther)
{
path
=
(
Path
*
)
lfirst
(
temp
);
#ifdef OPTDUP_DEBUG
if
(
!
samekeys
(
path
->
keys
,
new_path
->
keys
))
{
printf
(
"oldpath
\n
"
);
pprint
(
path
->
keys
);
printf
(
"newpath
\n
"
);
pprint
(
new_path
->
keys
);
if
(
path
->
keys
&&
new_path
->
keys
&&
length
(
lfirst
(
path
->
keys
))
>=
2
&&
length
(
lfirst
(
path
->
keys
))
<
length
(
lfirst
(
new_path
->
keys
)))
sleep
(
0
);
/* set breakpoint here */
}
if
(
!
equal_path_ordering
(
path
->
path_order
,
new_path
->
path_order
))
{
printf
(
"oldord
\n
"
);
pprint
(
path
->
path_order
);
printf
(
"neword
\n
"
);
pprint
(
new_path
->
path_order
);
}
#endif
if
(
samekeys
(
path
->
keys
,
new_path
->
keys
)
&&
equal_path_ordering
(
&
path
->
path_order
,
&
new_path
->
path_order
))
equal_path_ordering
(
path
->
path_order
,
new_path
->
path_order
))
{
old_path
=
path
;
break
;
...
...
@@ -207,8 +229,9 @@ create_seqscan_path(RelOptInfo * rel)
pathnode
->
pathtype
=
T_SeqScan
;
pathnode
->
parent
=
rel
;
pathnode
->
path_cost
=
0
.
0
;
pathnode
->
path_order
.
ordtype
=
SORTOP_ORDER
;
pathnode
->
path_order
.
ord
.
sortop
=
NULL
;
pathnode
->
path_order
=
makeNode
(
PathOrder
);
pathnode
->
path_order
->
ordtype
=
SORTOP_ORDER
;
pathnode
->
path_order
->
ord
.
sortop
=
NULL
;
pathnode
->
keys
=
NIL
;
/*
...
...
@@ -256,8 +279,9 @@ create_index_path(Query *root,
pathnode
->
path
.
pathtype
=
T_IndexScan
;
pathnode
->
path
.
parent
=
rel
;
pathnode
->
path
.
path_order
.
ordtype
=
SORTOP_ORDER
;
pathnode
->
path
.
path_order
.
ord
.
sortop
=
index
->
ordering
;
pathnode
->
path
.
path_order
=
makeNode
(
PathOrder
);
pathnode
->
path
.
path_order
->
ordtype
=
SORTOP_ORDER
;
pathnode
->
path
.
path_order
->
ord
.
sortop
=
index
->
ordering
;
pathnode
->
indexid
=
index
->
relids
;
pathnode
->
indexkeys
=
index
->
indexkeys
;
...
...
@@ -274,7 +298,7 @@ create_index_path(Query *root,
* The index must have an ordering for the path to have (ordering)
* keys, and vice versa.
*/
if
(
pathnode
->
path
.
path_order
.
ord
.
sortop
)
if
(
pathnode
->
path
.
path_order
->
ord
.
sortop
)
{
pathnode
->
path
.
keys
=
collect_index_pathkeys
(
index
->
indexkeys
,
rel
->
targetlist
);
...
...
@@ -286,7 +310,7 @@ create_index_path(Query *root,
* if no index keys were found, we can't order the path).
*/
if
(
pathnode
->
path
.
keys
==
NULL
)
pathnode
->
path
.
path_order
.
ord
.
sortop
=
NULL
;
pathnode
->
path
.
path_order
->
ord
.
sortop
=
NULL
;
}
else
pathnode
->
path
.
keys
=
NULL
;
...
...
@@ -412,23 +436,20 @@ create_nestloop_path(RelOptInfo * joinrel,
pathnode
->
path
.
joinid
=
NIL
;
pathnode
->
path
.
outerjoincost
=
(
Cost
)
0
.
0
;
pathnode
->
path
.
loc_restrictinfo
=
NIL
;
pathnode
->
path
.
path_order
=
makeNode
(
PathOrder
);
if
(
keys
)
{
pathnode
->
path
.
path_order
.
ordtype
=
outer_path
->
path_order
.
ordtype
;
if
(
outer_path
->
path_order
.
ordtype
==
SORTOP_ORDER
)
{
pathnode
->
path
.
path_order
.
ord
.
sortop
=
outer_path
->
path_order
.
ord
.
sortop
;
}
pathnode
->
path
.
path_order
->
ordtype
=
outer_path
->
path_order
->
ordtype
;
if
(
outer_path
->
path_order
->
ordtype
==
SORTOP_ORDER
)
pathnode
->
path
.
path_order
->
ord
.
sortop
=
outer_path
->
path_order
->
ord
.
sortop
;
else
{
pathnode
->
path
.
path_order
.
ord
.
merge
=
outer_path
->
path_order
.
ord
.
merge
;
}
pathnode
->
path
.
path_order
->
ord
.
merge
=
outer_path
->
path_order
->
ord
.
merge
;
}
else
{
pathnode
->
path
.
path_order
.
ordtype
=
SORTOP_ORDER
;
pathnode
->
path
.
path_order
.
ord
.
sortop
=
NULL
;
pathnode
->
path
.
path_order
->
ordtype
=
SORTOP_ORDER
;
pathnode
->
path
.
path_order
->
ord
.
sortop
=
NULL
;
}
pathnode
->
path
.
path_cost
=
cost_nestloop
(
outer_path
->
path_cost
,
...
...
@@ -487,8 +508,9 @@ create_mergejoin_path(RelOptInfo * joinrel,
pathnode
->
jpath
.
innerjoinpath
=
inner_path
;
pathnode
->
jpath
.
pathinfo
=
joinrel
->
restrictinfo
;
pathnode
->
jpath
.
path
.
keys
=
keys
;
pathnode
->
jpath
.
path
.
path_order
.
ordtype
=
MERGE_ORDER
;
pathnode
->
jpath
.
path
.
path_order
.
ord
.
merge
=
order
;
pathnode
->
jpath
.
path
.
path_order
=
makeNode
(
PathOrder
);
pathnode
->
jpath
.
path
.
path_order
->
ordtype
=
MERGE_ORDER
;
pathnode
->
jpath
.
path
.
path_order
->
ord
.
merge
=
order
;
pathnode
->
path_mergeclauses
=
mergeclauses
;
pathnode
->
jpath
.
path
.
loc_restrictinfo
=
NIL
;
pathnode
->
outersortkeys
=
outersortkeys
;
...
...
@@ -552,8 +574,9 @@ create_hashjoin_path(RelOptInfo * joinrel,
pathnode
->
jpath
.
pathinfo
=
joinrel
->
restrictinfo
;
pathnode
->
jpath
.
path
.
loc_restrictinfo
=
NIL
;
pathnode
->
jpath
.
path
.
keys
=
keys
;
pathnode
->
jpath
.
path
.
path_order
.
ordtype
=
SORTOP_ORDER
;
pathnode
->
jpath
.
path
.
path_order
.
ord
.
sortop
=
NULL
;
pathnode
->
jpath
.
path
.
path_order
=
makeNode
(
PathOrder
);
pathnode
->
jpath
.
path
.
path_order
->
ordtype
=
SORTOP_ORDER
;
pathnode
->
jpath
.
path
.
path_order
->
ord
.
sortop
=
NULL
;
pathnode
->
jpath
.
path
.
outerjoincost
=
(
Cost
)
0
.
0
;
pathnode
->
jpath
.
path
.
joinid
=
(
Relid
)
NULL
;
/* pathnode->hashjoinoperator = operator; */
...
...
src/backend/parser/gram.c
View file @
fe35ffe7
...
...
@@ -240,7 +240,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/Attic/gram.c,v 2.
69 1999/02/07 19:04:59 wieck
Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/Attic/gram.c,v 2.
70 1999/02/09 03:51:30 momjian
Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
...
...
@@ -4802,7 +4802,7 @@ static const short yycheck[] = { 3,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
215
};
/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
#line 3 "/usr/
share
/bison.simple"
#line 3 "/usr/
local/bison
/bison.simple"
/* Skeleton output parser for bison,
Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
...
...
@@ -4951,13 +4951,9 @@ int yydebug; /* nonzero means print parse trace */
#define YYMAXDEPTH 10000
#endif
#ifndef YYPARSE_RETURN_TYPE
#define YYPARSE_RETURN_TYPE int
#endif
/* Prevent warning if -Wstrict-prototypes. */
#ifdef __GNUC__
YYPARSE_RETURN_TYPE
yyparse
(
void
);
int
yyparse
(
void
);
#endif
#if __GNUC__ > 1
/* GNU C and GNU C++ define this. */
...
...
@@ -4999,7 +4995,7 @@ __yy_memcpy (char *to, char *from, int count)
#endif
#endif
#line 196 "/usr/
share
/bison.simple"
#line 196 "/usr/
local/bison
/bison.simple"
/* The user can define YYPARSE_PARAM as the name of an argument to be passed
into yyparse. The argument should have type void *.
...
...
@@ -5020,7 +5016,7 @@ __yy_memcpy (char *to, char *from, int count)
#define YYPARSE_PARAM_DECL
#endif
/* not YYPARSE_PARAM */
YYPARSE_RETURN_TYPE
int
yyparse
(
YYPARSE_PARAM_ARG
)
YYPARSE_PARAM_DECL
{
...
...
@@ -11126,7 +11122,7 @@ case 969:
break
;}
}
/* the action file gets copied in in place of this dollarsign */
#line 498 "/usr/
share
/bison.simple"
#line 498 "/usr/
local/bison
/bison.simple"
yyvsp
-=
yylen
;
yyssp
-=
yylen
;
...
...
src/backend/parser/scan.c
View file @
fe35ffe7
/* A lexical scanner generated by flex */
/* Scanner skeleton version:
*
$Header: /cvsroot/pgsql/src/backend/parser/Attic/scan.c,v 1.33 1999/02/07 23:58:52 tgl Exp $
*
/master/usr.bin/lex/skel.c,v 1.3 1997/09/25 00:10:23 jch Exp
*/
#define FLEX_SCANNER
...
...
@@ -556,7 +556,7 @@ char *yytext;
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/Attic/scan.c,v 1.3
3 1999/02/07 23:58:52 tgl
Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/Attic/scan.c,v 1.3
4 1999/02/09 03:51:39 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
src/include/nodes/nodes.h
View file @
fe35ffe7
...
...
@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: nodes.h,v 1.
39 1999/02/06 16:50:31 wieck
Exp $
* $Id: nodes.h,v 1.
40 1999/02/09 03:51:41 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -71,6 +71,7 @@ typedef enum NodeTag
*---------------------
*/
T_RelOptInfo
=
200
,
T_PathOrder
,
T_Path
,
T_IndexPath
,
T_JoinPath
,
...
...
src/include/nodes/relation.h
View file @
fe35ffe7
...
...
@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: relation.h,v 1.1
6 1999/02/08 04:29:25
momjian Exp $
* $Id: relation.h,v 1.1
7 1999/02/09 03:51:42
momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -127,6 +127,8 @@ typedef enum OrderType
typedef
struct
PathOrder
{
NodeTag
type
;
OrderType
ordtype
;
union
{
...
...
@@ -144,9 +146,9 @@ typedef struct Path
NodeTag
pathtype
;
PathOrder
path_order
;
PathOrder
*
path_order
;
List
*
keys
;
List
*
keys
;
/* this is a List of List of keys */
Cost
outerjoincost
;
Relid
joinid
;
List
*
loc_restrictinfo
;
...
...
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