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
6f9ff92c
Commit
6f9ff92c
authored
Nov 23, 1999
by
Bruce Momjian
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Tid access method feature from Hiroshi Inoue, Inoue@tpf.co.jp
parent
54ffd467
Changes
28
Show whitespace changes
Inline
Side-by-side
Showing
28 changed files
with
1396 additions
and
32 deletions
+1396
-32
src/backend/access/heap/heapam.c
src/backend/access/heap/heapam.c
+8
-2
src/backend/commands/explain.c
src/backend/commands/explain.c
+18
-1
src/backend/executor/Makefile
src/backend/executor/Makefile
+3
-2
src/backend/executor/execAmi.c
src/backend/executor/execAmi.c
+15
-2
src/backend/executor/execProcnode.c
src/backend/executor/execProcnode.c
+17
-1
src/backend/executor/execTuples.c
src/backend/executor/execTuples.c
+8
-1
src/backend/executor/nodeTidscan.c
src/backend/executor/nodeTidscan.c
+550
-0
src/backend/nodes/copyfuncs.c
src/backend/nodes/copyfuncs.c
+57
-1
src/backend/nodes/equalfuncs.c
src/backend/nodes/equalfuncs.c
+41
-1
src/backend/nodes/freefuncs.c
src/backend/nodes/freefuncs.c
+53
-1
src/backend/nodes/outfuncs.c
src/backend/nodes/outfuncs.c
+43
-1
src/backend/nodes/print.c
src/backend/nodes/print.c
+4
-1
src/backend/nodes/readfuncs.c
src/backend/nodes/readfuncs.c
+67
-1
src/backend/optimizer/path/Makefile
src/backend/optimizer/path/Makefile
+3
-2
src/backend/optimizer/path/allpaths.c
src/backend/optimizer/path/allpaths.c
+7
-2
src/backend/optimizer/path/costsize.c
src/backend/optimizer/path/costsize.c
+25
-1
src/backend/optimizer/path/tidpath.c
src/backend/optimizer/path/tidpath.c
+296
-0
src/backend/optimizer/plan/createplan.c
src/backend/optimizer/plan/createplan.c
+74
-1
src/backend/optimizer/plan/setrefs.c
src/backend/optimizer/plan/setrefs.c
+4
-1
src/backend/optimizer/plan/subselect.c
src/backend/optimizer/plan/subselect.c
+6
-1
src/backend/optimizer/util/pathnode.c
src/backend/optimizer/util/pathnode.c
+27
-1
src/include/nodes/execnodes.h
src/include/nodes/execnodes.h
+32
-1
src/include/nodes/nodes.h
src/include/nodes/nodes.h
+4
-1
src/include/nodes/plannodes.h
src/include/nodes/plannodes.h
+14
-2
src/include/nodes/relation.h
src/include/nodes/relation.h
+8
-1
src/include/optimizer/cost.h
src/include/optimizer/cost.h
+3
-1
src/include/optimizer/pathnode.h
src/include/optimizer/pathnode.h
+2
-1
src/include/optimizer/paths.h
src/include/optimizer/paths.h
+7
-1
No files found.
src/backend/access/heap/heapam.c
View file @
6f9ff92c
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.5
8 1999/11/07 23:07:52
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.5
9 1999/11/23 20:06:47
momjian Exp $
*
*
* INTERFACE ROUTINES
...
...
@@ -1062,7 +1062,13 @@ heap_fetch(Relation relation,
* ----------------
*/
Assert
(
ItemIdIsUsed
(
lp
));
if
(
!
ItemIdIsUsed
(
lp
))
{
ReleaseBuffer
(
buffer
);
*
userbuf
=
InvalidBuffer
;
tuple
->
t_data
=
NULL
;
return
;
}
tuple
->
t_data
=
(
HeapTupleHeader
)
PageGetItem
((
Page
)
dp
,
lp
);
tuple
->
t_len
=
ItemIdGetLength
(
lp
);
...
...
src/backend/commands/explain.c
View file @
6f9ff92c
...
...
@@ -4,7 +4,7 @@
*
* Copyright (c) 1994-5, Regents of the University of California
*
* $Id: explain.c,v 1.
49 1999/11/07 23:08:02
momjian Exp $
* $Id: explain.c,v 1.
50 1999/11/23 20:06:48
momjian Exp $
*
*/
...
...
@@ -196,6 +196,9 @@ explain_outNode(StringInfo str, Plan *plan, int indent, ExplainState *es)
case
T_Hash
:
pname
=
"Hash"
;
break
;
case
T_TidScan
:
pname
=
"Tid Scan"
;
break
;
default:
pname
=
"???"
;
break
;
...
...
@@ -234,6 +237,20 @@ explain_outNode(StringInfo str, Plan *plan, int indent, ExplainState *es)
appendStringInfo
(
str
,
stringStringInfo
(
rte
->
refname
));
}
break
;
case
T_TidScan
:
if
(((
TidScan
*
)
plan
)
->
scan
.
scanrelid
>
0
)
{
RangeTblEntry
*
rte
=
nth
(((
TidScan
*
)
plan
)
->
scan
.
scanrelid
-
1
,
es
->
rtable
);
appendStringInfo
(
str
,
" on "
);
if
(
strcmp
(
rte
->
refname
,
rte
->
relname
)
!=
0
)
{
appendStringInfo
(
str
,
"%s "
,
stringStringInfo
(
rte
->
relname
));
}
appendStringInfo
(
str
,
stringStringInfo
(
rte
->
refname
));
}
break
;
default:
break
;
}
...
...
src/backend/executor/Makefile
View file @
6f9ff92c
...
...
@@ -4,7 +4,7 @@
# Makefile for executor
#
# IDENTIFICATION
# $Header: /cvsroot/pgsql/src/backend/executor/Makefile,v 1.
8 1999/03/23 16:50:46
momjian Exp $
# $Header: /cvsroot/pgsql/src/backend/executor/Makefile,v 1.
9 1999/11/23 20:06:49
momjian Exp $
#
#-------------------------------------------------------------------------
...
...
@@ -18,7 +18,8 @@ OBJS = execAmi.o execFlatten.o execJunk.o execMain.o \
execUtils.o functions.o nodeAppend.o nodeAgg.o nodeHash.o
\
nodeHashjoin.o nodeIndexscan.o nodeMaterial.o nodeMergejoin.o
\
nodeNestloop.o nodeResult.o nodeSeqscan.o nodeSort.o
\
nodeUnique.o nodeGroup.o spi.o nodeSubplan.o
nodeUnique.o nodeGroup.o spi.o nodeSubplan.o
\
nodeTidscan.o
all
:
SUBSYS.o
...
...
src/backend/executor/execAmi.c
View file @
6f9ff92c
...
...
@@ -5,7 +5,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: execAmi.c,v 1.4
3 1999/11/04 08:00:57 inoue
Exp $
* $Id: execAmi.c,v 1.4
4 1999/11/23 20:06:50 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -40,6 +40,7 @@
#include "executor/nodeHash.h"
#include "executor/nodeHashjoin.h"
#include "executor/nodeIndexscan.h"
#include "executor/nodeTidscan.h"
#include "executor/nodeMaterial.h"
#include "executor/nodeMergejoin.h"
#include "executor/nodeNestloop.h"
...
...
@@ -217,6 +218,10 @@ ExecCloseR(Plan *node)
state
=
&
(((
Agg
*
)
node
)
->
aggstate
->
csstate
);
break
;
case
T_TidScan
:
state
=
((
TidScan
*
)
node
)
->
scan
.
scanstate
;
break
;
default:
elog
(
DEBUG
,
"ExecCloseR: not a scan, material, or sort node!"
);
return
;
...
...
@@ -367,6 +372,10 @@ ExecReScan(Plan *node, ExprContext *exprCtxt, Plan *parent)
ExecReScanAppend
((
Append
*
)
node
,
exprCtxt
,
parent
);
break
;
case
T_TidScan
:
ExecTidReScan
((
TidScan
*
)
node
,
exprCtxt
,
parent
);
break
;
default:
elog
(
ERROR
,
"ExecReScan: node type %u not supported"
,
nodeTag
(
node
));
return
;
...
...
@@ -425,6 +434,10 @@ ExecMarkPos(Plan *node)
ExecSortMarkPos
((
Sort
*
)
node
);
break
;
case
T_TidScan
:
ExecTidMarkPos
((
TidScan
*
)
node
);
break
;
default:
elog
(
DEBUG
,
"ExecMarkPos: node type %u not supported"
,
nodeTag
(
node
));
break
;
...
...
src/backend/executor/execProcnode.c
View file @
6f9ff92c
...
...
@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/execProcnode.c,v 1.1
5 1999/07/16 04:58:46
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/execProcnode.c,v 1.1
6 1999/11/23 20:06:51
momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -81,6 +81,7 @@
#include "executor/nodeHash.h"
#include "executor/nodeHashjoin.h"
#include "executor/nodeIndexscan.h"
#include "executor/nodeTidscan.h"
#include "executor/nodeMaterial.h"
#include "executor/nodeMergejoin.h"
#include "executor/nodeNestloop.h"
...
...
@@ -195,6 +196,10 @@ ExecInitNode(Plan *node, EState *estate, Plan *parent)
result
=
ExecInitHashJoin
((
HashJoin
*
)
node
,
estate
,
parent
);
break
;
case
T_TidScan
:
result
=
ExecInitTidScan
((
TidScan
*
)
node
,
estate
,
parent
);
break
;
default:
elog
(
ERROR
,
"ExecInitNode: node %d unsupported"
,
nodeTag
(
node
));
result
=
FALSE
;
...
...
@@ -310,6 +315,10 @@ ExecProcNode(Plan *node, Plan *parent)
result
=
ExecHashJoin
((
HashJoin
*
)
node
);
break
;
case
T_TidScan
:
result
=
ExecTidScan
((
TidScan
*
)
node
);
break
;
default:
elog
(
ERROR
,
"ExecProcNode: node %d unsupported"
,
nodeTag
(
node
));
result
=
NULL
;
...
...
@@ -381,6 +390,9 @@ ExecCountSlotsNode(Plan *node)
case
T_HashJoin
:
return
ExecCountSlotsHashJoin
((
HashJoin
*
)
node
);
case
T_TidScan
:
return
ExecCountSlotsTidScan
((
TidScan
*
)
node
);
default:
elog
(
ERROR
,
"ExecCountSlotsNode: node not yet supported: %d"
,
nodeTag
(
node
));
...
...
@@ -497,6 +509,10 @@ ExecEndNode(Plan *node, Plan *parent)
ExecEndHashJoin
((
HashJoin
*
)
node
);
break
;
case
T_TidScan
:
ExecEndTidScan
((
TidScan
*
)
node
);
break
;
default:
elog
(
ERROR
,
"ExecEndNode: node %d unsupported"
,
nodeTag
(
node
));
break
;
...
...
src/backend/executor/execTuples.c
View file @
6f9ff92c
...
...
@@ -14,7 +14,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/execTuples.c,v 1.3
1 1999/11/07 23:08:06
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/execTuples.c,v 1.3
2 1999/11/23 20:06:51
momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -771,6 +771,13 @@ NodeGetResultTupleSlot(Plan *node)
}
break
;
case
T_TidScan
:
{
CommonScanState
*
scanstate
=
((
IndexScan
*
)
node
)
->
scan
.
scanstate
;
slot
=
scanstate
->
cstate
.
cs_ResultTupleSlot
;
}
break
;
default:
/* ----------------
* should never get here
...
...
src/backend/executor/nodeTidscan.c
0 → 100644
View file @
6f9ff92c
/*-------------------------------------------------------------------------
*
* nodeTidscan.c
* Routines to support direct tid scans of relations
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/nodeTidscan.c,v 1.1 1999/11/23 20:06:51 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
* INTERFACE ROUTINES
*
* ExecTidScan scans a relation using tids
* ExecInitTidScan creates and initializes state info.
* ExecTidReScan rescans the tid relation.
* ExecEndTidScan releases all storage.
* ExecTidMarkPos marks scan position.
* ExecTidRestrPos restores scan position.
*
*/
#include "postgres.h"
#include "executor/executor.h"
#include "executor/execdebug.h"
#include "executor/nodeTidscan.h"
#include "optimizer/clauses.h"
/* for get_op, get_leftop, get_rightop */
#include "access/heapam.h"
#include "parser/parsetree.h"
static
int
TidListCreate
(
List
*
,
ExprContext
*
,
ItemPointer
*
);
static
TupleTableSlot
*
TidNext
(
TidScan
*
node
);
static
int
TidListCreate
(
List
*
evalList
,
ExprContext
*
econtext
,
ItemPointer
*
tidList
)
{
List
*
lst
;
ItemPointer
itemptr
;
bool
isNull
;
int
numTids
=
0
;
foreach
(
lst
,
evalList
)
{
itemptr
=
(
ItemPointer
)
ExecEvalExpr
(
lfirst
(
lst
),
econtext
,
&
isNull
,
(
bool
*
)
0
);
if
(
itemptr
&&
ItemPointerIsValid
(
itemptr
))
{
tidList
[
numTids
]
=
itemptr
;
numTids
++
;
}
}
return
numTids
;
}
/* ----------------------------------------------------------------
* TidNext
*
* Retrieve a tuple from the TidScan node's currentRelation
* using the tids in the TidScanState information.
*
* ----------------------------------------------------------------
*/
static
TupleTableSlot
*
TidNext
(
TidScan
*
node
)
{
EState
*
estate
;
CommonScanState
*
scanstate
;
TidScanState
*
tidstate
;
ScanDirection
direction
;
Snapshot
snapshot
;
Relation
heapRelation
;
HeapTuple
tuple
;
TupleTableSlot
*
slot
;
Buffer
buffer
=
InvalidBuffer
;
int
numTids
;
bool
bBackward
;
int
tidNumber
;
ItemPointer
*
tidList
,
itemptr
;
/* ----------------
* extract necessary information from tid scan node
* ----------------
*/
estate
=
node
->
scan
.
plan
.
state
;
direction
=
estate
->
es_direction
;
snapshot
=
estate
->
es_snapshot
;
scanstate
=
node
->
scan
.
scanstate
;
tidstate
=
node
->
tidstate
;
heapRelation
=
scanstate
->
css_currentRelation
;
numTids
=
tidstate
->
tss_NumTids
;
tidList
=
tidstate
->
tss_TidList
;
slot
=
scanstate
->
css_ScanTupleSlot
;
/*
* Check if we are evaluating PlanQual for tuple of this relation.
* Additional checking is not good, but no other way for now. We could
* introduce new nodes for this case and handle TidScan --> NewNode
* switching in Init/ReScan plan...
*/
if
(
estate
->
es_evTuple
!=
NULL
&&
estate
->
es_evTuple
[
node
->
scan
.
scanrelid
-
1
]
!=
NULL
)
{
int
iptr
,
numQuals
;
ExecClearTuple
(
slot
);
if
(
estate
->
es_evTupleNull
[
node
->
scan
.
scanrelid
-
1
])
return
slot
;
/* return empty slot */
slot
->
val
=
estate
->
es_evTuple
[
node
->
scan
.
scanrelid
-
1
];
slot
->
ttc_shouldFree
=
false
;
/* Flag for the next call that no more tuples */
estate
->
es_evTupleNull
[
node
->
scan
.
scanrelid
-
1
]
=
true
;
return
(
slot
);
}
tuple
=
&
(
tidstate
->
tss_htup
);
/* ----------------
* ok, now that we have what we need, fetch an tid tuple.
* if scanning this tid succeeded then return the
* appropriate heap tuple.. else return NULL.
* ----------------
*/
bBackward
=
ScanDirectionIsBackward
(
direction
);
if
(
bBackward
)
{
tidNumber
=
numTids
-
tidstate
->
tss_TidPtr
-
1
;
if
(
tidNumber
<
0
)
{
tidNumber
=
0
;
tidstate
->
tss_TidPtr
=
numTids
-
1
;
}
}
else
{
if
((
tidNumber
=
tidstate
->
tss_TidPtr
)
<
0
)
{
tidNumber
=
0
;
tidstate
->
tss_TidPtr
=
0
;
}
}
while
(
tidNumber
<
numTids
)
{
bool
slot_is_valid
=
false
;
itemptr
=
tidList
[
tidstate
->
tss_TidPtr
];
tuple
->
t_data
=
NULL
;
if
(
itemptr
)
{
tuple
->
t_self
=
*
(
itemptr
);
heap_fetch
(
heapRelation
,
snapshot
,
tuple
,
&
buffer
);
}
if
(
tuple
->
t_data
!=
NULL
)
{
bool
prev_matches
=
false
;
int
prev_tid
;
/* ----------------
* store the scanned tuple in the scan tuple slot of
* the scan state. Eventually we will only do this and not
* return a tuple. Note: we pass 'false' because tuples
* returned by amgetnext are pointers onto disk pages and
* were not created with palloc() and so should not be pfree()'d.
* ----------------
*/
ExecStoreTuple
(
tuple
,
/* tuple to store */
slot
,
/* slot to store in */
buffer
,
/* buffer associated with tuple */
false
);
/* don't pfree */
/*
* At this point we have an extra pin on the buffer,
* because ExecStoreTuple incremented the pin count.
* Drop our local pin.
*/
ReleaseBuffer
(
buffer
);
/*
* We must check to see if the current tuple would have
* been matched by an earlier tid, so we don't double
* report it. We do this by passing the tuple through
* ExecQual and look for failure with all previous
* qualifications.
*/
for
(
prev_tid
=
0
;
prev_tid
<
tidstate
->
tss_TidPtr
;
prev_tid
++
)
{
if
(
ItemPointerEquals
(
tidList
[
prev_tid
],
&
tuple
->
t_self
))
{
prev_matches
=
true
;
break
;
}
}
if
(
!
prev_matches
)
slot_is_valid
=
true
;
else
ExecClearTuple
(
slot
);
}
else
if
(
BufferIsValid
(
buffer
))
ReleaseBuffer
(
buffer
);
tidNumber
++
;
if
(
bBackward
)
tidstate
->
tss_TidPtr
--
;
else
tidstate
->
tss_TidPtr
++
;
if
(
slot_is_valid
)
return
slot
;
}
/* ----------------
* if we get here it means the tid scan failed so we
* are at the end of the scan..
* ----------------
*/
return
ExecClearTuple
(
slot
);
}
/* ----------------------------------------------------------------
* ExecTidScan(node)
*
* Scans the relation using tids and returns
* the next qualifying tuple in the direction specified.
* It calls ExecScan() and passes it the access methods which returns
* the next tuple using the tids.
*
* Conditions:
* -- the "cursor" maintained by the AMI is positioned at the tuple
* returned previously.
*
* Initial States:
* -- the relation indicated is opened for scanning so that the
* "cursor" is positioned before the first qualifying tuple.
* -- tidPtr points to the first tid.
* -- state variable ruleFlag = nil.
* ----------------------------------------------------------------
*/
TupleTableSlot
*
ExecTidScan
(
TidScan
*
node
)
{
/* ----------------
* use TidNext as access method
* ----------------
*/
return
ExecScan
(
&
node
->
scan
,
TidNext
);
}
/* ----------------------------------------------------------------
* ExecTidReScan(node)
* ----------------------------------------------------------------
*/
void
ExecTidReScan
(
TidScan
*
node
,
ExprContext
*
exprCtxt
,
Plan
*
parent
)
{
EState
*
estate
;
TidScanState
*
tidstate
;
Plan
*
outerPlan
;
ItemPointer
*
tidList
;
tidstate
=
node
->
tidstate
;
estate
=
node
->
scan
.
plan
.
state
;
tidstate
->
tss_TidPtr
=
-
1
;
tidList
=
tidstate
->
tss_TidList
;
if
((
outerPlan
=
outerPlan
((
Plan
*
)
node
))
!=
NULL
)
{
/* we are scanning a subplan */
outerPlan
=
outerPlan
((
Plan
*
)
node
);
ExecReScan
(
outerPlan
,
exprCtxt
,
parent
);
}
else
/* otherwise, we are scanning a relation */
{
/* If this is re-scanning of PlanQual ... */
if
(
estate
->
es_evTuple
!=
NULL
&&
estate
->
es_evTuple
[
node
->
scan
.
scanrelid
-
1
]
!=
NULL
)
{
estate
->
es_evTupleNull
[
node
->
scan
.
scanrelid
-
1
]
=
false
;
return
;
}
/* it's possible in subselects */
if
(
exprCtxt
==
NULL
)
exprCtxt
=
node
->
scan
.
scanstate
->
cstate
.
cs_ExprContext
;
node
->
scan
.
scanstate
->
cstate
.
cs_ExprContext
->
ecxt_outertuple
=
exprCtxt
->
ecxt_outertuple
;
tidstate
->
tss_NumTids
=
TidListCreate
(
node
->
tideval
,
exprCtxt
,
tidList
);
}
/* ----------------
* perhaps return something meaningful
* ----------------
*/
return
;
}
/* ----------------------------------------------------------------
* ExecEndTidScan
*
* Releases any storage allocated through C routines.
* Returns nothing.
* ----------------------------------------------------------------
*/
void
ExecEndTidScan
(
TidScan
*
node
)
{
CommonScanState
*
scanstate
;
TidScanState
*
tidstate
;
scanstate
=
node
->
scan
.
scanstate
;
tidstate
=
node
->
tidstate
;
if
(
tidstate
&&
tidstate
->
tss_TidList
)
pfree
(
tidstate
->
tss_TidList
);
/* ----------------
* extract information from the node
* ----------------
*/
/* ----------------
* Free the projection info and the scan attribute info
*
* Note: we don't ExecFreeResultType(scanstate)
* because the rule manager depends on the tupType
* returned by ExecMain(). So for now, this
* is freed at end-transaction time. -cim 6/2/91
* ----------------
*/
ExecFreeProjectionInfo
(
&
scanstate
->
cstate
);
/* ----------------
* close the heap and tid relations
* ----------------
*/
ExecCloseR
((
Plan
*
)
node
);
/* ----------------
* clear out tuple table slots
* ----------------
*/
ExecClearTuple
(
scanstate
->
cstate
.
cs_ResultTupleSlot
);
ExecClearTuple
(
scanstate
->
css_ScanTupleSlot
);
/* ExecClearTuple(scanstate->css_RawTupleSlot); */
}
/* ----------------------------------------------------------------
* ExecTidMarkPos
*
* Marks scan position by marking the current tid.
* Returns nothing.
* ----------------------------------------------------------------
*/
void
ExecTidMarkPos
(
TidScan
*
node
)
{
TidScanState
*
tidstate
;
tidstate
=
node
->
tidstate
;
tidstate
->
tss_MarkTidPtr
=
tidstate
->
tss_TidPtr
;
}
/* ----------------------------------------------------------------
* ExecTidRestrPos
*
* Restores scan position by restoring the current tid.
* Returns nothing.
*
* XXX Assumes previously marked scan position belongs to current tid
* ----------------------------------------------------------------
*/
void
ExecTidRestrPos
(
TidScan
*
node
)
{
TidScanState
*
tidstate
;
tidstate
=
node
->
tidstate
;
tidstate
->
tss_TidPtr
=
tidstate
->
tss_MarkTidPtr
;
}
/* ----------------------------------------------------------------
* ExecInitTidScan
*
* Initializes the tid scan's state information, creates
* scan keys, and opens the base and tid relations.
*
* Parameters:
* node: TidNode node produced by the planner.
* estate: the execution state initialized in InitPlan.
* ----------------------------------------------------------------
*/
bool
ExecInitTidScan
(
TidScan
*
node
,
EState
*
estate
,
Plan
*
parent
)
{
TidScanState
*
tidstate
;
CommonScanState
*
scanstate
;
ItemPointer
*
tidList
;
int
numTids
;
int
tidPtr
;
List
*
rangeTable
;
RangeTblEntry
*
rtentry
;
Oid
relid
;
Oid
reloid
;
Relation
currentRelation
;
int
baseid
;
List
*
execParam
=
NULL
;
/* ----------------
* assign execution state to node
* ----------------
*/
node
->
scan
.
plan
.
state
=
estate
;
/* --------------------------------
* Part 1) initialize scan state
*
* create new CommonScanState for node
* --------------------------------
*/
scanstate
=
makeNode
(
CommonScanState
);
/*
scanstate->ss_ProcOuterFlag = false;
scanstate->ss_OldRelId = 0;
*/
node
->
scan
.
scanstate
=
scanstate
;
/* ----------------
* assign node's base_id .. we don't use AssignNodeBaseid() because
* the increment is done later on after we assign the tid scan's
* scanstate. see below.
* ----------------
*/
baseid
=
estate
->
es_BaseId
;
/* scanstate->csstate.cstate.bnode.base_id = baseid; */
scanstate
->
cstate
.
cs_base_id
=
baseid
;
/* ----------------
* create expression context for node
* ----------------
*/
ExecAssignExprContext
(
estate
,
&
scanstate
->
cstate
);
#define TIDSCAN_NSLOTS 3
/* ----------------
* tuple table initialization
* ----------------
*/
ExecInitResultTupleSlot
(
estate
,
&
scanstate
->
cstate
);
ExecInitScanTupleSlot
(
estate
,
scanstate
);
/* ExecInitRawTupleSlot(estate, scanstate); */
/* ----------------
* initialize projection info. result type comes from scan desc
* below..
* ----------------
*/
ExecAssignProjectionInfo
((
Plan
*
)
node
,
&
scanstate
->
cstate
);
/* --------------------------------
* Part 2) initialize tid scan state
*
* create new TidScanState for node
* --------------------------------
*/
tidstate
=
makeNode
(
TidScanState
);
node
->
tidstate
=
tidstate
;
/* ----------------
* assign base id to tid scan state also
* ----------------
*/
tidstate
->
cstate
.
cs_base_id
=
baseid
;
baseid
++
;
estate
->
es_BaseId
=
baseid
;
/* ----------------
* get the tid node information
* ----------------
*/
tidList
=
(
ItemPointer
*
)
palloc
(
length
(
node
->
tideval
)
*
sizeof
(
ItemPointer
));
numTids
=
0
;
if
(
!
node
->
needRescan
)
numTids
=
TidListCreate
(
node
->
tideval
,
scanstate
->
cstate
.
cs_ExprContext
,
tidList
);
tidPtr
=
-
1
;
CXT1_printf
(
"ExecInitTidScan: context is %d
\n
"
,
CurrentMemoryContext
);
tidstate
->
tss_NumTids
=
numTids
;
tidstate
->
tss_TidPtr
=
tidPtr
;
tidstate
->
tss_TidList
=
tidList
;
/* ----------------
* get the range table and direction information
* from the execution state (these are needed to
* open the relations).
* ----------------
*/
rangeTable
=
estate
->
es_range_table
;
/* ----------------
* open the base relation
* ----------------
*/
relid
=
node
->
scan
.
scanrelid
;
rtentry
=
rt_fetch
(
relid
,
rangeTable
);
reloid
=
rtentry
->
relid
;
currentRelation
=
heap_open
(
reloid
,
AccessShareLock
);
if
(
currentRelation
==
NULL
)
elog
(
ERROR
,
"ExecInitTidScan heap_open failed."
);
scanstate
->
css_currentRelation
=
currentRelation
;
scanstate
->
css_currentScanDesc
=
0
;
/* ----------------
* get the scan type from the relation descriptor.
* ----------------
*/
ExecAssignScanType
(
scanstate
,
RelationGetDescr
(
currentRelation
));
ExecAssignResultTypeFromTL
((
Plan
*
)
node
,
&
scanstate
->
cstate
);
/* ----------------
* tid scans don't have subtrees..
* ----------------
*/
/* scanstate->ss_ProcOuterFlag = false; */
tidstate
->
cstate
.
cs_TupFromTlist
=
false
;
/*
* if there are some PARAM_EXEC in skankeys then force tid rescan on
* first scan.
*/
((
Plan
*
)
node
)
->
chgParam
=
execParam
;
/* ----------------
* all done.
* ----------------
*/
return
TRUE
;
}
int
ExecCountSlotsTidScan
(
TidScan
*
node
)
{
return
ExecCountSlotsNode
(
outerPlan
((
Plan
*
)
node
))
+
ExecCountSlotsNode
(
innerPlan
((
Plan
*
)
node
))
+
TIDSCAN_NSLOTS
;
}
src/backend/nodes/copyfuncs.c
View file @
6f9ff92c
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.9
6 1999/11/15 03:28:06 tgl
Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.9
7 1999/11/23 20:06:52 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -253,6 +253,32 @@ _copyIndexScan(IndexScan *from)
return
newnode
;
}
/* ----------------
* _copyTidScan
* ----------------
*/
static
TidScan
*
_copyTidScan
(
TidScan
*
from
)
{
TidScan
*
newnode
=
makeNode
(
TidScan
);
/* ----------------
* copy node superclass fields
* ----------------
*/
CopyPlanFields
((
Plan
*
)
from
,
(
Plan
*
)
newnode
);
CopyScanFields
((
Scan
*
)
from
,
(
Scan
*
)
newnode
);
/* ----------------
* copy remainder of node
* ----------------
*/
newnode
->
needRescan
=
from
->
needRescan
;
Node_Copy
(
from
,
newnode
,
tideval
);
return
newnode
;
}
/* ----------------
* CopyJoinFields
*
...
...
@@ -1058,6 +1084,30 @@ _copyIndexPath(IndexPath *from)
return
newnode
;
}
/* ----------------
* _copyTidPath
* ----------------
*/
static
TidPath
*
_copyTidPath
(
TidPath
*
from
)
{
TidPath
*
newnode
=
makeNode
(
TidPath
);
/* ----------------
* copy the node superclass fields
* ----------------
*/
CopyPathFields
((
Path
*
)
from
,
(
Path
*
)
newnode
);
/* ----------------
* copy remainder of node
* ----------------
*/
Node_Copy
(
from
,
newnode
,
tideval
);
newnode
->
unjoined_relids
=
listCopy
(
from
->
unjoined_relids
);
return
newnode
;
}
/* ----------------
* CopyJoinPathFields
*
...
...
@@ -1437,6 +1487,9 @@ copyObject(void *from)
case
T_IndexScan
:
retval
=
_copyIndexScan
(
from
);
break
;
case
T_TidScan
:
retval
=
_copyTidScan
(
from
);
break
;
case
T_Join
:
retval
=
_copyJoin
(
from
);
break
;
...
...
@@ -1535,6 +1588,9 @@ copyObject(void *from)
case
T_IndexPath
:
retval
=
_copyIndexPath
(
from
);
break
;
case
T_TidPath
:
retval
=
_copyTidPath
(
from
);
break
;
case
T_NestPath
:
retval
=
_copyNestPath
(
from
);
break
;
...
...
src/backend/nodes/equalfuncs.c
View file @
6f9ff92c
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.5
1 1999/11/15 03:28:06 tgl
Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.5
2 1999/11/23 20:06:52 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -330,6 +330,18 @@ _equalIndexPath(IndexPath *a, IndexPath *b)
return
true
;
}
static
bool
_equalTidPath
(
TidPath
*
a
,
TidPath
*
b
)
{
if
(
!
_equalPath
((
Path
*
)
a
,
(
Path
*
)
b
))
return
false
;
if
(
!
equal
(
a
->
tideval
,
b
->
tideval
))
return
false
;
if
(
!
equali
(
a
->
unjoined_relids
,
b
->
unjoined_relids
))
return
false
;
return
true
;
}
static
bool
_equalJoinPath
(
JoinPath
*
a
,
JoinPath
*
b
)
{
...
...
@@ -403,6 +415,28 @@ _equalIndexScan(IndexScan *a, IndexScan *b)
return
true
;
}
static
bool
_equalTidScan
(
TidScan
*
a
,
TidScan
*
b
)
{
Assert
(
IsA
(
a
,
TidScan
));
Assert
(
IsA
(
b
,
TidScan
));
/*
* if(a->scan.plan.cost != b->scan.plan.cost) return(false);
*/
if
(
a
->
needRescan
!=
b
->
needRescan
)
return
false
;
if
(
!
equal
(
a
->
tideval
,
b
->
tideval
))
return
false
;
if
(
a
->
scan
.
scanrelid
!=
b
->
scan
.
scanrelid
)
return
false
;
return
true
;
}
static
bool
_equalSubPlan
(
SubPlan
*
a
,
SubPlan
*
b
)
{
...
...
@@ -756,6 +790,9 @@ equal(void *a, void *b)
case
T_IndexPath
:
retval
=
_equalIndexPath
(
a
,
b
);
break
;
case
T_TidPath
:
retval
=
_equalTidPath
(
a
,
b
);
break
;
case
T_NestPath
:
retval
=
_equalNestPath
(
a
,
b
);
break
;
...
...
@@ -768,6 +805,9 @@ equal(void *a, void *b)
case
T_IndexScan
:
retval
=
_equalIndexScan
(
a
,
b
);
break
;
case
T_TidScan
:
retval
=
_equalTidScan
(
a
,
b
);
break
;
case
T_SubPlan
:
retval
=
_equalSubPlan
(
a
,
b
);
break
;
...
...
src/backend/nodes/freefuncs.c
View file @
6f9ff92c
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/Attic/freefuncs.c,v 1.2
7 1999/11/15 03:28:07 tgl
Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/Attic/freefuncs.c,v 1.2
8 1999/11/23 20:06:53 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -183,6 +183,29 @@ _freeIndexScan(IndexScan *node)
pfree
(
node
);
}
/* ----------------
* _freeTidScan
* ----------------
*/
static
void
_freeTidScan
(
TidScan
*
node
)
{
/* ----------------
* free node superclass fields
* ----------------
*/
FreePlanFields
((
Plan
*
)
node
);
FreeScanFields
((
Scan
*
)
node
);
/* ----------------
* free remainder of node
* ----------------
*/
freeObject
(
node
->
tideval
);
pfree
(
node
);
}
/* ----------------
* FreeJoinFields
*
...
...
@@ -781,6 +804,29 @@ _freeIndexPath(IndexPath *node)
pfree
(
node
);
}
/* ----------------
* _freeTidPath
* ----------------
*/
static
void
_freeTidPath
(
TidPath
*
node
)
{
/* ----------------
* free the node superclass fields
* ----------------
*/
FreePathFields
((
Path
*
)
node
);
/* ----------------
* free remainder of node
* ----------------
*/
freeObject
(
node
->
tideval
);
freeList
(
node
->
unjoined_relids
);
pfree
(
node
);
}
/* ----------------
* FreeJoinPathFields
*
...
...
@@ -1079,6 +1125,9 @@ freeObject(void *node)
case
T_IndexScan
:
_freeIndexScan
(
node
);
break
;
case
T_TidScan
:
_freeTidScan
(
node
);
break
;
case
T_Join
:
_freeJoin
(
node
);
break
;
...
...
@@ -1177,6 +1226,9 @@ freeObject(void *node)
case
T_IndexPath
:
_freeIndexPath
(
node
);
break
;
case
T_TidPath
:
_freeTidPath
(
node
);
break
;
case
T_NestPath
:
_freeNestPath
(
node
);
break
;
...
...
src/backend/nodes/outfuncs.c
View file @
6f9ff92c
...
...
@@ -5,7 +5,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: outfuncs.c,v 1.9
7 1999/10/07 04:23:04 tgl
Exp $
* $Id: outfuncs.c,v 1.9
8 1999/11/23 20:06:53 momjian
Exp $
*
* NOTES
* Every (plan) node in POSTGRES has an associated "out" routine which
...
...
@@ -451,6 +451,23 @@ _outIndexScan(StringInfo str, IndexScan *node)
appendStringInfo
(
str
,
" :indxorderdir %d "
,
node
->
indxorderdir
);
}
/*
* TidScan is a subclass of Scan
*/
static
void
_outTidScan
(
StringInfo
str
,
TidScan
*
node
)
{
appendStringInfo
(
str
,
" TIDSCAN "
);
_outPlanInfo
(
str
,
(
Plan
*
)
node
);
appendStringInfo
(
str
,
" :scanrelid %u "
,
node
->
scan
.
scanrelid
);
appendStringInfo
(
str
,
" :needrescan %d "
,
node
->
needRescan
);
appendStringInfo
(
str
,
" :tideval "
);
_outNode
(
str
,
node
->
tideval
);
}
/*
* Noname is a subclass of Plan
*/
...
...
@@ -914,6 +931,25 @@ _outIndexPath(StringInfo str, IndexPath *node)
_outIntList
(
str
,
node
->
joinrelids
);
}
/*
* TidPath is a subclass of Path.
*/
static
void
_outTidPath
(
StringInfo
str
,
TidPath
*
node
)
{
appendStringInfo
(
str
,
" TIDPATH :pathtype %d :cost %f :pathkeys "
,
node
->
path
.
pathtype
,
node
->
path
.
path_cost
);
_outNode
(
str
,
node
->
path
.
pathkeys
);
appendStringInfo
(
str
,
" :tideval "
);
_outNode
(
str
,
node
->
tideval
);
appendStringInfo
(
str
,
" :un joined_relids "
);
_outIntList
(
str
,
node
->
unjoined_relids
);
}
/*
* NestPath is a subclass of Path
*/
...
...
@@ -1357,6 +1393,9 @@ _outNode(StringInfo str, void *obj)
case
T_IndexScan
:
_outIndexScan
(
str
,
obj
);
break
;
case
T_TidScan
:
_outTidScan
(
str
,
obj
);
break
;
case
T_Noname
:
_outNoname
(
str
,
obj
);
break
;
...
...
@@ -1435,6 +1474,9 @@ _outNode(StringInfo str, void *obj)
case
T_IndexPath
:
_outIndexPath
(
str
,
obj
);
break
;
case
T_TidPath
:
_outTidPath
(
str
,
obj
);
break
;
case
T_NestPath
:
_outNestPath
(
str
,
obj
);
break
;
...
...
src/backend/nodes/print.c
View file @
6f9ff92c
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/print.c,v 1.3
2 1999/08/16 02:17:43 tgl
Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/print.c,v 1.3
3 1999/11/23 20:06:53 momjian
Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
...
...
@@ -338,6 +338,9 @@ plannode_type(Plan *p)
case
T_Group
:
return
"GROUP"
;
break
;
case
T_TidScan
:
return
"TIDSCAN"
;
break
;
default:
return
"UNKNOWN"
;
break
;
...
...
src/backend/nodes/readfuncs.c
View file @
6f9ff92c
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.7
4 1999/10/07 04:23:04 tgl
Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.7
5 1999/11/23 20:06:53 momjian
Exp $
*
* NOTES
* Most of the read functions for plan nodes are tested. (In fact, they
...
...
@@ -541,6 +541,33 @@ _readIndexScan()
return
local_node
;
}
/* ----------------
* _readTidScan
*
* TidScan is a subclass of Scan
* ----------------
*/
static
TidScan
*
_readTidScan
()
{
TidScan
*
local_node
;
char
*
token
;
int
length
;
local_node
=
makeNode
(
TidScan
);
_getScan
((
Scan
*
)
local_node
);
token
=
lsptok
(
NULL
,
&
length
);
/* eat :needrescan */
token
=
lsptok
(
NULL
,
&
length
);
/* get needrescan */
local_node
->
needRescan
=
atoi
(
token
);
token
=
lsptok
(
NULL
,
&
length
);
/* eat :tideval */
local_node
->
tideval
=
nodeRead
(
true
);
/* now read it */
return
local_node
;
}
/* ----------------
* _readNoname
*
...
...
@@ -1476,6 +1503,41 @@ _readIndexPath()
return
local_node
;
}
/* ----------------
* _readTidPath
*
* TidPath is a subclass of Path.
* ----------------
*/
static
TidPath
*
_readTidPath
()
{
TidPath
*
local_node
;
char
*
token
;
int
length
;
local_node
=
makeNode
(
TidPath
);
token
=
lsptok
(
NULL
,
&
length
);
/* get :pathtype */
token
=
lsptok
(
NULL
,
&
length
);
/* now read it */
local_node
->
path
.
pathtype
=
atol
(
token
);
token
=
lsptok
(
NULL
,
&
length
);
/* get :cost */
token
=
lsptok
(
NULL
,
&
length
);
/* now read it */
local_node
->
path
.
path_cost
=
(
Cost
)
atof
(
token
);
token
=
lsptok
(
NULL
,
&
length
);
/* get :pathkeys */
local_node
->
path
.
pathkeys
=
nodeRead
(
true
);
/* now read it */
token
=
lsptok
(
NULL
,
&
length
);
/* get :tideval */
local_node
->
tideval
=
nodeRead
(
true
);
/* now read it */
token
=
lsptok
(
NULL
,
&
length
);
/* get :unjoined_relids */
local_node
->
unjoined_relids
=
toIntList
(
nodeRead
(
true
));
return
local_node
;
}
/* ----------------
* _readNestPath
*
...
...
@@ -1801,6 +1863,8 @@ parsePlanString(void)
return_value
=
_readSeqScan
();
else
if
(
!
strncmp
(
token
,
"INDEXSCAN"
,
length
))
return_value
=
_readIndexScan
();
else
if
(
!
strncmp
(
token
,
"TIDSCAN"
,
length
))
return_value
=
_readTidScan
();
else
if
(
!
strncmp
(
token
,
"NONAME"
,
length
))
return_value
=
_readNoname
();
else
if
(
!
strncmp
(
token
,
"SORT"
,
length
))
...
...
@@ -1845,6 +1909,8 @@ parsePlanString(void)
return_value
=
_readPath
();
else
if
(
!
strncmp
(
token
,
"INDEXPATH"
,
length
))
return_value
=
_readIndexPath
();
else
if
(
!
strncmp
(
token
,
"TIDPATH"
,
length
))
return_value
=
_readTidPath
();
else
if
(
!
strncmp
(
token
,
"NESTPATH"
,
length
))
return_value
=
_readNestPath
();
else
if
(
!
strncmp
(
token
,
"MERGEPATH"
,
length
))
...
...
src/backend/optimizer/path/Makefile
View file @
6f9ff92c
...
...
@@ -4,7 +4,7 @@
# Makefile for optimizer/path
#
# IDENTIFICATION
# $Header: /cvsroot/pgsql/src/backend/optimizer/path/Makefile,v 1.
9 1999/08/16 02:17:50 tgl
Exp $
# $Header: /cvsroot/pgsql/src/backend/optimizer/path/Makefile,v 1.
10 1999/11/23 20:06:54 momjian
Exp $
#
#-------------------------------------------------------------------------
...
...
@@ -14,7 +14,8 @@ include ../../../Makefile.global
CFLAGS
+=
-I
../..
OBJS
=
allpaths.o clausesel.o costsize.o indxpath.o
\
joinpath.o joinrels.o orindxpath.o pathkeys.o prune.o
joinpath.o joinrels.o orindxpath.o pathkeys.o prune.o
\
tidpath.o
all
:
SUBSYS.o
...
...
src/backend/optimizer/path/allpaths.c
View file @
6f9ff92c
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/allpaths.c,v 1.5
3 1999/08/16 02:17:50 tgl
Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/allpaths.c,v 1.5
4 1999/11/23 20:06:54 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -108,9 +108,14 @@ set_base_rel_pathlist(Query *root, List *rels)
List
*
sequential_scan_list
;
List
*
rel_index_scan_list
;
List
*
or_index_scan_list
;
List
*
tidscan_pathlist
;
sequential_scan_list
=
lcons
(
create_seqscan_path
(
rel
),
NIL
);
/* Tid Scan Pathlist add */
tidscan_pathlist
=
create_tidscan_paths
(
root
,
rel
);
if
(
tidscan_pathlist
)
sequential_scan_list
=
nconc
(
sequential_scan_list
,
tidscan_pathlist
);
rel_index_scan_list
=
create_index_paths
(
root
,
rel
,
indices
,
...
...
src/backend/optimizer/path/costsize.c
View file @
6f9ff92c
...
...
@@ -18,7 +18,7 @@
* Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.4
5 1999/08/22 20:14:41 tgl
Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.4
6 1999/11/23 20:06:54 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -59,6 +59,7 @@ bool _enable_sort_ = true;
bool
_enable_nestloop_
=
true
;
bool
_enable_mergejoin_
=
true
;
bool
_enable_hashjoin_
=
true
;
bool
_enable_tidscan_
=
true
;
Cost
_cpu_page_weight_
=
_CPU_PAGE_WEIGHT_
;
Cost
_cpu_index_page_weight_
=
_CPU_INDEX_PAGE_WEIGHT_
;
...
...
@@ -174,6 +175,29 @@ cost_index(Oid indexid,
return
temp
;
}
/*
* cost_tidscan
* Determines and returns the cost of scanning a relation using tid-s.
*
* disk = number of tids
* cpu = *CPU-PAGE-WEIGHT* * number_of_tids
*
* Returns a flonum.
*
*/
Cost
cost_tidscan
(
List
*
tideval
)
{
Cost
temp
=
0
;
if
(
!
_enable_tidscan_
)
temp
+=
_disable_cost_
;
temp
+=
(
1
.
0
+
_cpu_page_weight_
)
*
length
(
tideval
);
return
temp
;
}
/*
* cost_sort
* Determines and returns the cost of sorting a relation by considering
...
...
src/backend/optimizer/path/tidpath.c
0 → 100644
View file @
6f9ff92c
/*-------------------------------------------------------------------------
*
* tidpath.c
* Routines to determine which tids are usable for scanning a
* given relation, and create TidPaths accordingly.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/tidpath.c,v 1.1 1999/11/23 20:06:55 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#include <math.h>
#include "postgres.h"
#include "access/heapam.h"
#include "catalog/catname.h"
#include "catalog/pg_amop.h"
#include "catalog/pg_operator.h"
#include "executor/executor.h"
#include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h"
#include "optimizer/clauses.h"
#include "optimizer/cost.h"
#include "optimizer/pathnode.h"
#include "optimizer/paths.h"
#include "optimizer/plancat.h"
#include "optimizer/restrictinfo.h"
#include "parser/parse_coerce.h"
#include "parser/parse_expr.h"
#include "parser/parse_oper.h"
#include "parser/parsetree.h"
#include "utils/lsyscache.h"
static
List
*
create_tidscan_joinpaths
(
RelOptInfo
*
);
static
List
*
TidqualFromRestrictinfo
(
List
*
relids
,
List
*
restrictinfo
);
static
bool
isEvaluable
(
int
varno
,
Node
*
node
);
static
Node
*
TidequalClause
(
int
varno
,
Expr
*
node
);
static
List
*
TidqualFromExpr
(
int
varno
,
Expr
*
expr
);
static
bool
isEvaluable
(
int
varno
,
Node
*
node
)
{
List
*
lst
;
Expr
*
expr
;
if
(
IsA
(
node
,
Const
))
return
true
;
if
(
IsA
(
node
,
Param
))
return
true
;
if
(
IsA
(
node
,
Var
))
{
Var
*
var
=
(
Var
*
)
node
;
if
(
var
->
varno
==
varno
)
return
false
;
return
true
;
}
if
(
!
is_funcclause
(
node
))
return
false
;
expr
=
(
Expr
*
)
node
;
foreach
(
lst
,
expr
->
args
)
{
if
(
!
isEvaluable
(
varno
,
lfirst
(
lst
)))
return
false
;
}
return
true
;
}
/*
* The 2nd parameter should be an opclause
* Extract the right node if the opclause is CTID= ....
* or the left node if the opclause is ....=CTID
*/
static
Node
*
TidequalClause
(
int
varno
,
Expr
*
node
)
{
Node
*
rnode
=
0
,
*
arg1
,
*
arg2
,
*
arg
;
Oper
*
oper
;
Var
*
var
;
Const
*
aconst
;
Param
*
param
;
Expr
*
expr
;
if
(
!
node
->
oper
)
return
rnode
;
if
(
!
node
->
args
)
return
rnode
;
if
(
length
(
node
->
args
)
!=
2
)
return
rnode
;
oper
=
(
Oper
*
)
node
->
oper
;
if
(
oper
->
opno
!=
TIDEqualOperator
)
return
rnode
;
arg1
=
lfirst
(
node
->
args
);
arg2
=
lsecond
(
node
->
args
);
arg
=
(
Node
*
)
0
;
if
(
IsA
(
arg1
,
Var
))
{
var
=
(
Var
*
)
arg1
;
if
(
var
->
varno
==
varno
&&
var
->
varattno
==
SelfItemPointerAttributeNumber
&&
var
->
vartype
==
TIDOID
)
arg
=
arg2
;
else
if
(
var
->
varnoold
==
varno
&&
var
->
varoattno
==
SelfItemPointerAttributeNumber
&&
var
->
vartype
==
TIDOID
)
arg
=
arg2
;
}
if
((
!
arg
)
&&
IsA
(
arg2
,
Var
))
{
var
=
(
Var
*
)
arg2
;
if
(
var
->
varno
==
varno
&&
var
->
varattno
==
SelfItemPointerAttributeNumber
&&
var
->
vartype
==
TIDOID
)
arg
=
arg1
;
}
if
(
!
arg
)
return
rnode
;
switch
(
nodeTag
(
arg
))
{
case
T_Const
:
aconst
=
(
Const
*
)
arg
;
if
(
aconst
->
consttype
!=
TIDOID
)
return
rnode
;
if
(
aconst
->
constbyval
)
return
rnode
;
rnode
=
arg
;
break
;
case
T_Param
:
param
=
(
Param
*
)
arg
;
if
(
param
->
paramtype
!=
TIDOID
)
return
rnode
;
rnode
=
arg
;
break
;
case
T_Var
:
var
=
(
Var
*
)
arg
;
if
(
var
->
varno
==
varno
||
var
->
vartype
!=
TIDOID
)
return
rnode
;
rnode
=
arg
;
break
;
case
T_Expr
:
expr
=
(
Expr
*
)
arg
;
if
(
expr
->
typeOid
!=
TIDOID
)
return
rnode
;
if
(
expr
->
opType
!=
FUNC_EXPR
)
return
rnode
;
if
(
isEvaluable
(
varno
,
(
Node
*
)
expr
))
rnode
=
arg
;
break
;
default:
break
;
}
return
rnode
;
}
/*
* Extract the list of CTID values from a specified expr node.
* When the expr node is an or_clause,we try to extract CTID
* values from all member nodes. However we would discard them
* all if we couldn't extract CTID values from a member node.
* When the expr node is an and_clause,we return the list of
* CTID values if we could extract the CTID values from a member
* node.
*/
static
List
*
TidqualFromExpr
(
int
varno
,
Expr
*
expr
)
{
List
*
rlst
=
NIL
,
*
lst
,
*
frtn
;
Node
*
node
=
(
Node
*
)
expr
,
*
rnode
;
if
(
is_opclause
(
node
))
{
rnode
=
TidequalClause
(
varno
,
expr
);
if
(
rnode
)
{
rlst
=
lcons
(
rnode
,
rlst
);
}
}
else
if
(
and_clause
(
node
))
{
foreach
(
lst
,
expr
->
args
)
{
node
=
lfirst
(
lst
);
if
(
!
IsA
(
node
,
Expr
))
continue
;
rlst
=
TidqualFromExpr
(
varno
,
(
Expr
*
)
node
);
if
(
rlst
)
break
;
}
}
else
if
(
or_clause
(
node
))
{
foreach
(
lst
,
expr
->
args
)
{
node
=
lfirst
(
lst
);
if
(
IsA
(
node
,
Expr
)
&&
(
frtn
=
TidqualFromExpr
(
varno
,
(
Expr
*
)
node
))
)
{
rlst
=
nconc
(
rlst
,
frtn
);
}
else
{
if
(
rlst
)
freeList
(
rlst
);
rlst
=
NIL
;
break
;
}
}
}
return
rlst
;
}
static
List
*
TidqualFromRestrictinfo
(
List
*
relids
,
List
*
restrictinfo
)
{
List
*
lst
,
*
rlst
=
NIL
;
int
varno
;
Node
*
node
;
Expr
*
expr
;
if
(
length
(
relids
)
>
1
)
return
NIL
;
varno
=
(
int
)
lfirst
(
relids
);
foreach
(
lst
,
restrictinfo
)
{
node
=
lfirst
(
lst
);
if
(
!
IsA
(
node
,
RestrictInfo
))
continue
;
expr
=
((
RestrictInfo
*
)
node
)
->
clause
;
rlst
=
TidqualFromExpr
(
varno
,
expr
);
if
(
rlst
)
{
break
;
}
}
return
rlst
;
}
/*
* create_tidscan_joinpaths
* Creates a path corresponding to a tid_direct scan, returning the
* pathnode.
*
*/
List
*
create_tidscan_joinpaths
(
RelOptInfo
*
rel
)
{
List
*
rlst
=
NIL
,
*
lst
;
TidPath
*
pathnode
=
(
TidPath
*
)
0
;
List
*
restinfo
,
*
tideval
;
foreach
(
lst
,
rel
->
joininfo
)
{
JoinInfo
*
joininfo
=
(
JoinInfo
*
)
lfirst
(
lst
);
restinfo
=
joininfo
->
jinfo_restrictinfo
;
tideval
=
TidqualFromRestrictinfo
(
rel
->
relids
,
restinfo
);
if
(
tideval
&&
length
(
tideval
)
==
1
)
{
pathnode
=
makeNode
(
TidPath
);
pathnode
->
path
.
pathtype
=
T_TidScan
;
pathnode
->
path
.
parent
=
rel
;
pathnode
->
path
.
path_cost
=
0
.
0
;
pathnode
->
path
.
pathkeys
=
NIL
;
pathnode
->
path
.
path_cost
=
cost_tidscan
(
tideval
);
pathnode
->
tideval
=
tideval
;
/*
pathnode->tideval = copyObject(tideval);
freeList(tideval);
*/
pathnode
->
unjoined_relids
=
joininfo
->
unjoined_relids
;
rlst
=
lappend
(
rlst
,
pathnode
);
}
}
rel
->
innerjoin
=
nconc
(
rel
->
innerjoin
,
rlst
);
return
rlst
;
}
/*
* create_tidscan_paths
* Creates a path corresponding to a tid direct scan, returning the
* pathnode List.
*
*/
List
*
create_tidscan_paths
(
Query
*
root
,
RelOptInfo
*
rel
)
{
List
*
rlst
=
NIL
;
TidPath
*
pathnode
=
(
TidPath
*
)
0
;
List
*
tideval
=
TidqualFromRestrictinfo
(
rel
->
relids
,
rel
->
restrictinfo
);
if
(
tideval
)
pathnode
=
create_tidscan_path
(
rel
,
tideval
);
if
(
pathnode
)
rlst
=
lcons
(
pathnode
,
rlst
);
create_tidscan_joinpaths
(
rel
);
return
rlst
;
}
src/backend/optimizer/plan/createplan.c
View file @
6f9ff92c
...
...
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.7
6 1999/08/22 23:56:44 tgl
Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.7
7 1999/11/23 20:06:57 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -37,6 +37,8 @@ static SeqScan *create_seqscan_node(Path *best_path, List *tlist,
List
*
scan_clauses
);
static
IndexScan
*
create_indexscan_node
(
IndexPath
*
best_path
,
List
*
tlist
,
List
*
scan_clauses
);
static
TidScan
*
create_tidscan_node
(
TidPath
*
best_path
,
List
*
tlist
,
List
*
scan_clauses
);
static
NestLoop
*
create_nestloop_node
(
NestPath
*
best_path
,
List
*
tlist
,
List
*
clauses
,
Plan
*
outer_node
,
List
*
outer_tlist
,
Plan
*
inner_node
,
List
*
inner_tlist
);
...
...
@@ -53,6 +55,8 @@ static Node *fix_indxqual_operand(Node *node, IndexPath *index_path,
Form_pg_index
index
);
static
IndexScan
*
make_indexscan
(
List
*
qptlist
,
List
*
qpqual
,
Index
scanrelid
,
List
*
indxid
,
List
*
indxqual
,
List
*
indxqualorig
);
static
TidScan
*
make_tidscan
(
List
*
qptlist
,
List
*
qpqual
,
Index
scanrelid
,
List
*
tideval
);
static
NestLoop
*
make_nestloop
(
List
*
qptlist
,
List
*
qpqual
,
Plan
*
lefttree
,
Plan
*
righttree
);
static
HashJoin
*
make_hashjoin
(
List
*
tlist
,
List
*
qpqual
,
...
...
@@ -101,6 +105,7 @@ create_plan(Path *best_path)
{
case
T_IndexScan
:
case
T_SeqScan
:
case
T_TidScan
:
plan_node
=
(
Plan
*
)
create_scan_node
(
best_path
,
tlist
);
break
;
case
T_HashJoin
:
...
...
@@ -168,6 +173,12 @@ create_scan_node(Path *best_path, List *tlist)
scan_clauses
);
break
;
case
T_TidScan
:
node
=
(
Scan
*
)
create_tidscan_node
((
TidPath
*
)
best_path
,
tlist
,
scan_clauses
);
break
;
default:
elog
(
ERROR
,
"create_scan_node: unknown node type"
,
best_path
->
pathtype
);
...
...
@@ -399,6 +410,62 @@ create_indexscan_node(IndexPath *best_path,
return
scan_node
;
}
static
TidScan
*
make_tidscan
(
List
*
qptlist
,
List
*
qpqual
,
Index
scanrelid
,
List
*
tideval
)
{
TidScan
*
node
=
makeNode
(
TidScan
);
Plan
*
plan
=
&
node
->
scan
.
plan
;
plan
->
cost
=
0
;
plan
->
plan_size
=
0
;
plan
->
plan_width
=
0
;
plan
->
state
=
(
EState
*
)
NULL
;
plan
->
targetlist
=
qptlist
;
plan
->
qual
=
qpqual
;
plan
->
lefttree
=
NULL
;
plan
->
righttree
=
NULL
;
node
->
scan
.
scanrelid
=
scanrelid
;
node
->
tideval
=
copyObject
(
tideval
);
node
->
needRescan
=
false
;
node
->
scan
.
scanstate
=
(
CommonScanState
*
)
NULL
;
return
node
;
}
/*
* create_tidscan_node
* Returns a tidscan node for the base relation scanned by 'best_path'
* with restriction clauses 'scan_clauses' and targetlist 'tlist'.
*/
static
TidScan
*
create_tidscan_node
(
TidPath
*
best_path
,
List
*
tlist
,
List
*
scan_clauses
)
{
TidScan
*
scan_node
=
(
TidScan
*
)
NULL
;
Index
scan_relid
=
-
1
;
List
*
temp
;
temp
=
best_path
->
path
.
parent
->
relids
;
if
(
temp
==
NULL
)
elog
(
ERROR
,
"scanrelid is empty"
);
else
if
(
length
(
temp
)
!=
1
)
return
scan_node
;
else
scan_relid
=
(
Index
)
lfirsti
(
temp
);
scan_node
=
make_tidscan
(
tlist
,
scan_clauses
,
scan_relid
,
best_path
->
tideval
);
if
(
best_path
->
unjoined_relids
)
scan_node
->
needRescan
=
true
;
scan_node
->
scan
.
plan
.
cost
=
best_path
->
path
.
path_cost
;
return
scan_node
;
}
/*****************************************************************************
*
* JOIN METHODS
...
...
@@ -487,6 +554,12 @@ create_nestloop_node(NestPath *best_path,
innerrel
);
}
}
else
if
(
IsA
(
inner_node
,
TidScan
))
{
List
*
inner_tideval
=
((
TidScan
*
)
inner_node
)
->
tideval
;
TidScan
*
innerscan
=
(
TidScan
*
)
inner_node
;
((
TidScan
*
)
inner_node
)
->
tideval
=
join_references
(
inner_tideval
,
outer_tlist
,
inner_tlist
,
innerscan
->
scan
.
scanrelid
);
}
else
if
(
IsA_Join
(
inner_node
))
{
/*
...
...
src/backend/optimizer/plan/setrefs.c
View file @
6f9ff92c
...
...
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.5
8 1999/10/30 23:07:55 tgl
Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.5
9 1999/11/23 20:06:57 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -125,6 +125,9 @@ set_plan_references(Plan *plan)
set_plan_references
((
Plan
*
)
lfirst
(
pl
));
}
break
;
case
T_TidScan
:
/* nothing special */
break
;
default:
elog
(
ERROR
,
"set_plan_references: unknown plan type %d"
,
nodeTag
(
plan
));
...
...
src/backend/optimizer/plan/subselect.c
View file @
6f9ff92c
...
...
@@ -6,7 +6,7 @@
* Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.2
5 1999/11/15 02:00:08 tgl
Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.2
6 1999/11/23 20:06:57 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -534,6 +534,11 @@ SS_finalize_plan(Plan *plan)
&
results
);
break
;
case
T_TidScan
:
finalize_primnode
((
Node
*
)
((
TidScan
*
)
plan
)
->
tideval
,
&
results
);
break
;
case
T_Agg
:
case
T_SeqScan
:
case
T_NestLoop
:
...
...
src/backend/optimizer/util/pathnode.c
View file @
6f9ff92c
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/pathnode.c,v 1.5
4 1999/08/16 02:17:58 tgl
Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/pathnode.c,v 1.5
5 1999/11/23 20:07:00 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -318,6 +318,32 @@ create_index_path(Query *root,
return
pathnode
;
}
/*
* create_tidscan_path
* Creates a path corresponding to a tid_direct scan, returning the
* pathnode.
*
*/
TidPath
*
create_tidscan_path
(
RelOptInfo
*
rel
,
List
*
tideval
)
{
TidPath
*
pathnode
=
makeNode
(
TidPath
);
pathnode
->
path
.
pathtype
=
T_TidScan
;
pathnode
->
path
.
parent
=
rel
;
pathnode
->
path
.
path_cost
=
0
.
0
;
pathnode
->
path
.
pathkeys
=
NIL
;
pathnode
->
path
.
path_cost
=
cost_tidscan
(
tideval
);
/* divide selectivity for each clause to get an equal selectivity
* as IndexScan does OK ?
*/
pathnode
->
tideval
=
copyObject
(
tideval
);
pathnode
->
unjoined_relids
=
NIL
;
return
pathnode
;
}
/*
* create_nestloop_path
* Creates a pathnode corresponding to a nestloop join between two
...
...
src/include/nodes/execnodes.h
View file @
6f9ff92c
...
...
@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: execnodes.h,v 1.3
7 1999/10/17 22:15:07 tgl
Exp $
* $Id: execnodes.h,v 1.3
8 1999/11/23 20:07:02 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -414,6 +414,37 @@ typedef struct IndexScanState
HeapTupleData
iss_htup
;
}
IndexScanState
;
/* ----------------
* TidScanState information
*
*| tid scans don't use CommonScanState because
*| the underlying AM abstractions for heap scans and
*| tid scans are too different.. It would be nice
*| if the current abstraction was more useful but ... -cim 10/15/89
*
* TidPtr current tid in use
* NumTids number of tids in this scan
* tidList evaluated item pointers
*
* CommonState information
*
* OuterTupleSlot pointer to slot containing current "outer" tuple
* ResultTupleSlot pointer to slot in tuple table for projected tuple
* ExprContext node's current expression context
* ProjInfo info this node uses to form tuple projections
* NumScanAttributes size of ScanAttributes array
* ScanAttributes attribute numbers of interest in this tuple
* ----------------
*/
typedef
struct
TidScanState
{
CommonState
cstate
;
/* its first field is NodeTag */
int
tss_NumTids
;
int
tss_TidPtr
;
int
tss_MarkTidPtr
;
ItemPointer
*
tss_TidList
;
HeapTupleData
tss_htup
;
}
TidScanState
;
/* ----------------------------------------------------------------
* Join State Information
...
...
src/include/nodes/nodes.h
View file @
6f9ff92c
...
...
@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: nodes.h,v 1.5
5 1999/10/15 01:49:47
momjian Exp $
* $Id: nodes.h,v 1.5
6 1999/11/23 20:07:02
momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -47,6 +47,7 @@ typedef enum NodeTag
T_Choose
,
T_Group
,
T_SubPlan
,
T_TidScan
,
/*---------------------
* TAGS FOR PRIMITIVE NODES (primnodes.h)
...
...
@@ -80,6 +81,7 @@ typedef enum NodeTag
T_RestrictInfo
,
T_JoinInfo
,
T_Stream
,
T_TidPath
,
/*---------------------
* TAGS FOR EXECUTOR NODES (execnodes.h)
...
...
@@ -110,6 +112,7 @@ typedef enum NodeTag
T_SortState
,
T_UniqueState
,
T_HashState
,
T_TidScanState
,
/*---------------------
* TAGS FOR MEMORY NODES (memnodes.h)
...
...
src/include/nodes/plannodes.h
View file @
6f9ff92c
...
...
@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: plannodes.h,v 1.3
3 1999/11/15 03:28:06 tgl
Exp $
* $Id: plannodes.h,v 1.3
4 1999/11/23 20:07:02 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -179,6 +179,18 @@ typedef struct IndexScan
IndexScanState
*
indxstate
;
}
IndexScan
;
/* ----------------
* tid scan node
* ----------------
*/
typedef
struct
TidScan
{
Scan
scan
;
bool
needRescan
;
List
*
tideval
;
TidScanState
*
tidstate
;
}
TidScan
;
/*
* ==========
* Join nodes
...
...
src/include/nodes/relation.h
View file @
6f9ff92c
...
...
@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: relation.h,v 1.3
8 1999/08/16 02:17:40 tgl
Exp $
* $Id: relation.h,v 1.3
9 1999/11/23 20:07:02 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -193,6 +193,13 @@ typedef struct IndexPath
Relids
joinrelids
;
/* other rels mentioned in indexqual */
}
IndexPath
;
typedef
struct
TidPath
{
Path
path
;
List
*
tideval
;
Relids
unjoined_relids
;
/* some rels not yet part of my Path */
}
TidPath
;
/*
* All join-type paths share these fields.
*/
...
...
src/include/optimizer/cost.h
View file @
6f9ff92c
...
...
@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: cost.h,v 1.2
3 1999/08/06 04:00:13 tgl
Exp $
* $Id: cost.h,v 1.2
4 1999/11/23 20:07:05 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -31,11 +31,13 @@ extern bool _enable_sort_;
extern
bool
_enable_nestloop_
;
extern
bool
_enable_mergejoin_
;
extern
bool
_enable_hashjoin_
;
extern
bool
_enable_tidscan_
;
extern
Cost
cost_seqscan
(
int
relid
,
int
relpages
,
int
reltuples
);
extern
Cost
cost_index
(
Oid
indexid
,
int
expected_indexpages
,
Cost
selec
,
int
relpages
,
int
reltuples
,
int
indexpages
,
int
indextuples
,
bool
is_injoin
);
extern
Cost
cost_tidscan
(
List
*
evallist
);
extern
Cost
cost_sort
(
List
*
pathkeys
,
int
tuples
,
int
width
);
extern
Cost
cost_nestloop
(
Cost
outercost
,
Cost
innercost
,
int
outertuples
,
int
innertuples
,
int
outerpages
,
bool
is_indexjoin
);
...
...
src/include/optimizer/pathnode.h
View file @
6f9ff92c
...
...
@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: pathnode.h,v 1.2
1 1999/08/16 02:17:45 tgl
Exp $
* $Id: pathnode.h,v 1.2
2 1999/11/23 20:07:06 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -27,6 +27,7 @@ extern Path *create_seqscan_path(RelOptInfo *rel);
extern
IndexPath
*
create_index_path
(
Query
*
root
,
RelOptInfo
*
rel
,
RelOptInfo
*
index
,
List
*
restriction_clauses
);
extern
TidPath
*
create_tidscan_path
(
RelOptInfo
*
rel
,
List
*
tideval
);
extern
NestPath
*
create_nestloop_path
(
RelOptInfo
*
joinrel
,
RelOptInfo
*
outer_rel
,
Path
*
outer_path
,
Path
*
inner_path
,
...
...
src/include/optimizer/paths.h
View file @
6f9ff92c
...
...
@@ -7,7 +7,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: paths.h,v 1.3
5 1999/08/21 03:49:15 tgl
Exp $
* $Id: paths.h,v 1.3
6 1999/11/23 20:07:06 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -30,6 +30,12 @@ extern List *create_index_paths(Query *root, RelOptInfo *rel, List *indices,
List
*
joininfo_list
);
extern
List
*
expand_indexqual_conditions
(
List
*
indexquals
);
/*
* tidpath.h
* routines to generate tid paths
*/
extern
List
*
create_tidscan_paths
(
Query
*
root
,
RelOptInfo
*
rel
);
/*
* joinpath.c
* routines to create join paths
...
...
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