Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Greenplum
Gpdb
提交
f5f366e1
G
Gpdb
项目概览
Greenplum
/
Gpdb
通知
7
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
G
Gpdb
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
f5f366e1
编写于
8月 06, 1997
作者:
B
Bruce Momjian
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Allow internal sorts to be stored in memory rather than in files.
上级
3bea7b13
变更
11
展开全部
隐藏空白更改
内联
并排
Showing
11 changed file
with
630 addition
and
513 deletion
+630
-513
src/backend/executor/nodeMergejoin.c
src/backend/executor/nodeMergejoin.c
+15
-1
src/backend/executor/nodeSort.c
src/backend/executor/nodeSort.c
+70
-191
src/backend/tcop/postgres.c
src/backend/tcop/postgres.c
+15
-3
src/backend/utils/sort/lselect.c
src/backend/utils/sort/lselect.c
+46
-89
src/backend/utils/sort/psort.c
src/backend/utils/sort/psort.c
+398
-183
src/include/nodes/execnodes.h
src/include/nodes/execnodes.h
+2
-2
src/include/nodes/plannodes.h
src/include/nodes/plannodes.h
+3
-1
src/include/utils/lselect.h
src/include/utils/lselect.h
+20
-11
src/include/utils/psort.h
src/include/utils/psort.h
+49
-16
src/man/postgres.1
src/man/postgres.1
+10
-14
src/man/postmaster.1
src/man/postmaster.1
+2
-2
未找到文件。
src/backend/executor/nodeMergejoin.c
浏览文件 @
f5f366e1
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/nodeMergejoin.c,v 1.
5 1996/11/10 02:59:54
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/nodeMergejoin.c,v 1.
6 1997/08/06 03:41:29
momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -374,6 +374,18 @@ ExecMergeTupleDump(ExprContext *econtext, MergeJoinState *mergestate)
printf
(
"********
\n
"
);
}
static
void
CleanUpSort
(
Plan
*
plan
)
{
if
(
plan
==
NULL
)
return
;
if
(
plan
->
type
==
T_Sort
)
{
Sort
*
sort
=
(
Sort
*
)
plan
;
psort_end
(
sort
);
}
}
/* ----------------------------------------------------------------
* ExecMergeJoin
*
...
...
@@ -676,6 +688,8 @@ ExecMergeJoin(MergeJoin *node)
*/
if
(
TupIsNull
(
outerTupleSlot
))
{
MJ_printf
(
"ExecMergeJoin: **** outer tuple is nil ****
\n
"
);
CleanUpSort
(
node
->
join
.
lefttree
->
lefttree
);
CleanUpSort
(
node
->
join
.
righttree
->
lefttree
);
return
NULL
;
}
...
...
src/backend/executor/nodeSort.c
浏览文件 @
f5f366e1
/*-------------------------------------------------------------------------
*
* nodeSort.c--
* Routines to handle sorting of relations
into temporaries
.
* Routines to handle sorting of relations.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/nodeSort.c,v 1.
4 1996/11/08 05:56:17
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/nodeSort.c,v 1.
5 1997/08/06 03:41:31
momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -86,10 +86,9 @@ FormSortKeys(Sort *sortnode)
* ExecSort
*
* old comments
* Retrieves tuples fron the outer subtree and insert them into a
* temporary relation. The temporary relation is then sorted and
* the sorted relation is stored in the relation whose ID is indicated
* in the 'tempid' field of this node.
* Sorts tuples from the outer subtree of the node in psort,
* which saves the results in a temporary file or memory. After the
* initial call, returns a tuple from the file with each call.
* Assumes that heap access method is used.
*
* Conditions:
...
...
@@ -108,13 +107,8 @@ ExecSort(Sort *node)
ScanDirection
dir
;
int
keycount
;
ScanKey
sortkeys
;
Relation
tempRelation
;
Relation
currentRelation
;
HeapScanDesc
currentScanDesc
;
HeapTuple
heapTuple
;
TupleTableSlot
*
slot
;
Buffer
buffer
;
int
tupCount
=
0
;
/* ----------------
* get state info from node
...
...
@@ -128,10 +122,8 @@ ExecSort(Sort *node)
dir
=
estate
->
es_direction
;
/* ----------------
* the first time we call this, we retrieve all tuples
* from the subplan into a temporary relation and then
* we sort the relation. Subsequent calls return tuples
* from the temporary relation.
* the first time we call this, psort sorts this into a file.
* Subsequent calls return tuples from psort.
* ----------------
*/
...
...
@@ -144,78 +136,23 @@ ExecSort(Sort *node)
* ----------------
*/
estate
->
es_direction
=
ForwardScanDirection
;
/* ----------------
* if we couldn't create the temp or current relations then
* we print a warning and return NULL.
* ----------------
*/
tempRelation
=
sortstate
->
sort_TempRelation
;
if
(
tempRelation
==
NULL
)
{
elog
(
DEBUG
,
"ExecSort: temp relation is NULL! aborting..."
);
return
NULL
;
}
currentRelation
=
sortstate
->
csstate
.
css_currentRelation
;
if
(
currentRelation
==
NULL
)
{
elog
(
DEBUG
,
"ExecSort: current relation is NULL! aborting..."
);
return
NULL
;
}
/* ----------------
* retrieve tuples from the subplan and
* insert them in the temporary relation
* prepare information for psort_begin()
* ----------------
*/
outerNode
=
outerPlan
((
Plan
*
)
node
);
SO1_printf
(
"ExecSort: %s
\n
"
,
"inserting tuples into tempRelation"
);
for
(;;)
{
slot
=
ExecProcNode
(
outerNode
,
(
Plan
*
)
node
);
if
(
TupIsNull
(
slot
))
break
;
tupCount
++
;
heapTuple
=
slot
->
val
;
heap_insert
(
tempRelation
,
/* relation desc */
heapTuple
);
/* heap tuple to insert */
ExecClearTuple
(
slot
);
}
/* ----------------
* now sort the tuples in our temporary relation
* into a new sorted relation using psort()
*
* psort() seems to require that the relations
* are created and opened in advance.
* -cim 1/25/90
* ----------------
*/
keycount
=
node
->
keycount
;
sortkeys
=
(
ScanKey
)
sortstate
->
sort_Keys
;
SO1_printf
(
"ExecSort: %s
\n
"
,
"calling psort"
);
/*
* If no tuples were fetched from the proc node return NULL now
* psort dumps it if 0 tuples are in the relation and I don't want
* to try to debug *that* routine!!
*/
if
(
tupCount
==
0
)
return
NULL
;
psort
(
tempRelation
,
/* old relation */
currentRelation
,
/* new relation */
keycount
,
/* number keys */
sortkeys
);
/* keys */
if
(
currentRelation
==
NULL
)
{
elog
(
DEBUG
,
"ExecSort: sorted relation is NULL! aborting..."
);
"calling psort_begin"
);
if
(
!
psort_begin
(
node
,
/* this node */
keycount
,
/* number keys */
sortkeys
))
/* keys */
{
/* Psort says, there are no tuples to be sorted */
return
NULL
;
}
...
...
@@ -225,67 +162,56 @@ ExecSort(Sort *node)
*/
estate
->
es_direction
=
dir
;
/* ----------------
* now initialize the scan descriptor to scan the
* sorted relation and update the sortstate information
* ----------------
*/
currentScanDesc
=
heap_beginscan
(
currentRelation
,
/* relation */
ScanDirectionIsBackward
(
dir
),
/* bkwd flag */
NowTimeQual
,
/* time qual */
0
,
/* num scan keys */
NULL
);
/* scan keys */
sortstate
->
csstate
.
css_currentRelation
=
currentRelation
;
sortstate
->
csstate
.
css_currentScanDesc
=
currentScanDesc
;
/* ----------------
* make sure the tuple descriptor is up to date
* ----------------
*/
slot
=
sortstate
->
csstate
.
css_ScanTupleSlot
;
slot
->
ttc_tupleDescriptor
=
RelationGetTupleDescriptor
(
currentRelation
);
slot
=
(
TupleTableSlot
*
)
sortstate
->
csstate
.
cstate
.
cs_ResultTupleSlot
;
/* *** get_cs_ResultTupleSlot((CommonState) sortstate); */
slot
->
ttc_tupleDescriptor
=
ExecGetTupType
(
outerNode
);
#ifdef 0
slot
->
ttc_execTupDescriptor
=
ExecGetExecTupDesc
(
outerNode
);
#endif
/* ----------------
* finally set the sorted flag to true
* ----------------
*/
sortstate
->
sort_Flag
=
true
;
SO1_printf
(
stderr
,
"ExecSort: sorting done.
\n
"
);
}
else
{
slot
=
sortstate
->
csstate
.
css_ScanTupleSlot
;
slot
=
(
TupleTableSlot
*
)
sortstate
->
csstate
.
cstate
.
cs_ResultTupleSlot
;
/* *** get_cs_ResultTupleSlot((CommonState) sortstate); */
/* slot = sortstate->csstate.css_ScanTupleSlot; orig */
}
SO1_printf
(
"ExecSort: %s
\n
"
,
"retriev
e
ing tuple from sorted relation"
);
"retrieving tuple from sorted relation"
);
/* ----------------
* at this point we know we have a sorted relation so
* we preform a simple scan on it with amgetnext()..
* at this point we grab a tuple from psort
* ----------------
*/
currentScanDesc
=
sortstate
->
csstate
.
css_currentScanDesc
;
heapTuple
=
heap_getnext
(
currentScanDesc
,
/* scan desc */
ScanDirectionIsBackward
(
dir
),
/* bkwd flag */
&
buffer
);
/* return: buffer */
/* Increase the pin count on the buffer page, because the tuple stored in
the slot also points to it (as well as the scan descriptor). If we
don't, ExecStoreTuple will decrease the pin count on the next iteration.
- 01/09/93
*/
if
(
buffer
!=
InvalidBuffer
)
IncrBufferRefCount
(
buffer
);
return
ExecStoreTuple
(
heapTuple
,
/* tuple to store
*/
slot
,
/* slot to store in
*/
buffer
,
/* this tuple's buffer
*/
false
);
/* don't free stuff from amgetnext */
heapTuple
=
psort_grabtuple
(
node
)
;
if
(
heapTuple
==
NULL
)
{
/* psort_end(node); */
return
(
ExecClearTuple
(
slot
));
}
ExecStoreTuple
(
heapTuple
,
/* tuple to store */
slot
,
/* slot to store in */
InvalidBuffer
,
/* no buffer */
true
);
/* free the palloc'd tuple
*/
/* printf("ExecSort: (%x)",node);print_slot(slot);printf("\n");*/
return
slot
;
#if 0
return ExecStoreTuple(heapTuple, /* tuple to store */
slot, /* slot to store in
*/
InvalidBuffer, /* no buffer
*/
true); /* free the palloc'd tuple
*/
#endif
}
/* ----------------------------------------------------------------
...
...
@@ -302,11 +228,6 @@ ExecInitSort(Sort *node, EState *estate, Plan *parent)
SortState
*
sortstate
;
Plan
*
outerPlan
;
ScanKey
sortkeys
;
TupleDesc
tupType
;
Oid
tempOid
;
Oid
sortOid
;
Relation
tempDesc
;
Relation
sortedDesc
;
SO1_printf
(
"ExecInitSort: %s
\n
"
,
"initializing sort node"
);
...
...
@@ -324,7 +245,7 @@ ExecInitSort(Sort *node, EState *estate, Plan *parent)
sortstate
=
makeNode
(
SortState
);
sortstate
->
sort_Flag
=
0
;
sortstate
->
sort_Keys
=
NULL
;
sortstate
->
sort_TempRelation
=
NULL
;
node
->
cleaned
=
FALSE
;
node
->
sortstate
=
sortstate
;
...
...
@@ -348,8 +269,8 @@ ExecInitSort(Sort *node, EState *estate, Plan *parent)
* relation.
* ----------------
*/
ExecInitScanTupleSlot
(
estate
,
&
sortstate
->
csstate
);
ExecInitResultTupleSlot
(
estate
,
&
sortstate
->
csstate
.
cstate
);
ExecInitResultTupleSlot
(
estate
,
&
sortstate
->
csstate
.
cstate
);
ExecInitScanTupleSlot
(
estate
,
&
sortstate
->
csstate
);
/* ----------------
* initializes child nodes
...
...
@@ -371,41 +292,10 @@ ExecInitSort(Sort *node, EState *estate, Plan *parent)
* info because this node doesn't do projections.
* ----------------
*/
ExecAssignScanTypeFromOuterPlan
((
Plan
*
)
node
,
&
sortstate
->
csstate
);
ExecAssignResultTypeFromOuterPlan
((
Plan
*
)
node
,
&
sortstate
->
csstate
.
cstate
);
ExecAssignScanTypeFromOuterPlan
((
Plan
*
)
node
,
&
sortstate
->
csstate
);
sortstate
->
csstate
.
cstate
.
cs_ProjInfo
=
NULL
;
/* ----------------
* get type information needed for ExecCreatR
* ----------------
*/
tupType
=
ExecGetScanType
(
&
sortstate
->
csstate
);
/* ----------------
* ExecCreatR wants its second argument to be an object id of
* a relation in the range table or _TEMP_RELATION_ID_
* indicating that the relation is not in the range table.
*
* In the second case ExecCreatR creates a temp relation.
* (currently this is the only case we support -cim 10/16/89)
* ----------------
*/
tempOid
=
node
->
tempid
;
sortOid
=
_TEMP_RELATION_ID_
;
/* ----------------
* create the temporary relations
* ----------------
*/
/* len = ExecTargetListLength(node->plan.targetlist); */
tempDesc
=
ExecCreatR
(
tupType
,
tempOid
);
sortedDesc
=
ExecCreatR
(
tupType
,
sortOid
);
/* ----------------
* save the relation descriptor in the sortstate
* ----------------
*/
sortstate
->
sort_TempRelation
=
tempDesc
;
sortstate
->
csstate
.
css_currentRelation
=
sortedDesc
;
SO1_printf
(
"ExecInitSort: %s
\n
"
,
"sort node initialized"
);
...
...
@@ -429,15 +319,12 @@ ExecCountSlotsSort(Sort *node)
* ExecEndSort(node)
*
* old comments
* destroys the temporary relation.
* ----------------------------------------------------------------
*/
void
ExecEndSort
(
Sort
*
node
)
{
SortState
*
sortstate
;
Relation
tempRelation
;
Relation
sortedRelation
;
Plan
*
outerPlan
;
/* ----------------
...
...
@@ -448,18 +335,6 @@ ExecEndSort(Sort *node)
"shutting down sort node"
);
sortstate
=
node
->
sortstate
;
tempRelation
=
sortstate
->
sort_TempRelation
;
sortedRelation
=
sortstate
->
csstate
.
css_currentRelation
;
heap_destroyr
(
tempRelation
);
heap_destroyr
(
sortedRelation
);
/* ----------------
* close the sorted relation and shut down the scan.
* ----------------
*/
ExecCloseR
((
Plan
*
)
node
);
/* ----------------
* shut down the subplan
...
...
@@ -473,6 +348,9 @@ ExecEndSort(Sort *node)
* ----------------
*/
ExecClearTuple
(
sortstate
->
csstate
.
css_ScanTupleSlot
);
/* Clean up after psort */
psort_end
(
node
);
SO1_printf
(
"ExecEndSort: %s
\n
"
,
"sort node shutdown"
);
...
...
@@ -480,37 +358,39 @@ ExecEndSort(Sort *node)
/* ----------------------------------------------------------------
* ExecSortMarkPos
*
* Calls psort to save the current position in the sorted file.
* ----------------------------------------------------------------
*/
void
ExecSortMarkPos
(
Sort
*
node
)
{
SortState
*
sortstate
;
HeapScanDesc
sdesc
;
SortState
*
sortstate
;
/* ----------------
*
if we haven't sorted yet, just return
*
if we haven't sorted yet, just return
* ----------------
*/
sortstate
=
node
->
sortstate
;
if
(
sortstate
->
sort_Flag
==
false
)
return
;
sdesc
=
sortstate
->
csstate
.
css_currentScanDesc
;
heap_markpos
(
sdesc
);
psort_markpos
(
node
)
;
return
;
}
/* ----------------------------------------------------------------
* ExecSortRestrPos
*
* Calls psort to restore the last saved sort file position.
* ----------------------------------------------------------------
*/
void
ExecSortRestrPos
(
Sort
*
node
)
{
SortState
*
sortstate
;
HeapScanDesc
sdesc
;
SortState
*
sortstate
;
/* ----------------
* if we haven't sorted yet, just return.
* ----------------
...
...
@@ -520,9 +400,8 @@ ExecSortRestrPos(Sort *node)
return
;
/* ----------------
*
restore the scan to the previously marked position
*
restore the scan to the previously marked position
* ----------------
*/
sdesc
=
sortstate
->
csstate
.
css_currentScanDesc
;
heap_restrpos
(
sdesc
);
psort_restorepos
(
node
);
}
src/backend/tcop/postgres.c
浏览文件 @
f5f366e1
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.3
6 1997/07/29 16:14:40 thomas
Exp $
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.3
7 1997/08/06 03:41:41 momjian
Exp $
*
* NOTES
* this is the "main" module of the postgres backend and
...
...
@@ -108,6 +108,7 @@ extern int lockingOff;
extern
int
NBuffers
;
int
fsyncOff
=
0
;
int
SortMem
=
512
;
int
dontExecute
=
0
;
static
int
ShowStats
;
...
...
@@ -1038,7 +1039,16 @@ PostgresMain(int argc, char *argv[])
*/
flagQ
=
1
;
break
;
case
'S'
:
/* ----------------
* S - amount of sort memory to use in 1k bytes
* ----------------
*/
SortMem
=
atoi
(
optarg
);
break
;
#ifdef NOT_USED
case
'S'
:
/* ----------------
* S - assume stable main memory
...
...
@@ -1048,6 +1058,7 @@ PostgresMain(int argc, char *argv[])
flagS
=
1
;
SetTransactionFlushEnabled
(
false
);
break
;
#endif
case
's'
:
/* ----------------
...
...
@@ -1173,6 +1184,7 @@ PostgresMain(int argc, char *argv[])
printf
(
"
\t
timings = %c
\n
"
,
ShowStats
?
't'
:
'f'
);
printf
(
"
\t
dates = %s
\n
"
,
EuroDates
?
"European"
:
"Normal"
);
printf
(
"
\t
bufsize = %d
\n
"
,
NBuffers
);
printf
(
"
\t
sortmem = %d
\n
"
,
SortMem
);
printf
(
"
\t
query echo = %c
\n
"
,
EchoQuery
?
't'
:
'f'
);
printf
(
"
\t
multiplexed backend? = %c
\n
"
,
multiplexedBackend
?
't'
:
'f'
);
...
...
@@ -1280,7 +1292,7 @@ PostgresMain(int argc, char *argv[])
*/
if
(
IsUnderPostmaster
==
false
)
{
puts
(
"
\n
POSTGRES backend interactive interface"
);
puts
(
"$Revision: 1.3
6 $ $Date: 1997/07/29 16:14:40
$"
);
puts
(
"$Revision: 1.3
7 $ $Date: 1997/08/06 03:41:41
$"
);
}
/* ----------------
...
...
src/backend/utils/sort/lselect.c
浏览文件 @
f5f366e1
...
...
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/sort/Attic/lselect.c,v 1.
3 1997/05/20 11:35:48 vadim
Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/sort/Attic/lselect.c,v 1.
4 1997/08/06 03:41:47 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -26,37 +26,14 @@
#include "utils/psort.h"
#include "utils/lselect.h"
extern
Relation
SortRdesc
;
/* later static */
/*
* PUTTUP - writes the next tuple
* ENDRUN - mark end of run
* GETLEN - reads the length of the next tuple
* ALLOCTUP - returns space for the new tuple
* SETTUPLEN - stores the length into the tuple
* GETTUP - reads the tuple
*
* Note:
* LEN field must be a short; FP is a stream
*/
#define PUTTUP(TUP, FP) fwrite((char *)TUP, (TUP)->t_len, 1, FP)
#define ENDRUN(FP) fwrite((char *)&shortzero, sizeof (shortzero), 1, FP)
#define GETLEN(LEN, FP) fread(&(LEN), sizeof (shortzero), 1, FP)
#define ALLOCTUP(LEN) ((HeapTuple)palloc((unsigned)LEN))
#define GETTUP(TUP, LEN, FP)\
fread((char *)(TUP) + sizeof (shortzero), 1, (LEN) - sizeof (shortzero), FP)
#define SETTUPLEN(TUP, LEN) (TUP)->t_len = LEN
/*
* USEMEM - record use of memory
* FREEMEM - record freeing of memory
* FULLMEM - 1 iff a tuple will fit
*/
#define USEMEM(AMT) SortMemory -= (AMT)
#define FREEMEM(AMT) SortMemory += (AMT)
#define LACKMEM() (SortMemory <= BLCKSZ)
/* not accurate */
#define USEMEM(context,AMT) context->sortMem -= (AMT)
#define FREEMEM(context,AMT) context->sortMem += (AMT)
/*
* lmerge - merges two leftist trees into one
...
...
@@ -67,12 +44,12 @@ extern Relation SortRdesc; /* later static */
* speed up code significantly.
*/
struct
leftist
*
lmerge
(
struct
leftist
*
pt
,
struct
leftist
*
qt
)
lmerge
(
struct
leftist
*
pt
,
struct
leftist
*
qt
,
LeftistContext
context
)
{
register
struct
leftist
*
root
,
*
majorLeftist
,
*
minorLeftist
;
int
dist
;
if
(
tuplecmp
(
pt
->
lt_tuple
,
qt
->
lt_tuple
))
{
if
(
tuplecmp
(
pt
->
lt_tuple
,
qt
->
lt_tuple
,
context
))
{
root
=
pt
;
majorLeftist
=
qt
;
}
else
{
...
...
@@ -83,7 +60,7 @@ lmerge(struct leftist *pt, struct leftist *qt)
root
->
lt_left
=
majorLeftist
;
else
{
if
((
minorLeftist
=
root
->
lt_right
)
!=
NULL
)
majorLeftist
=
lmerge
(
majorLeftist
,
minorLeftist
);
majorLeftist
=
lmerge
(
majorLeftist
,
minorLeftist
,
context
);
if
((
dist
=
root
->
lt_left
->
lt_dist
)
<
majorLeftist
->
lt_dist
)
{
root
->
lt_dist
=
1
+
dist
;
root
->
lt_right
=
root
->
lt_left
;
...
...
@@ -97,11 +74,11 @@ lmerge(struct leftist *pt, struct leftist *qt)
}
static
struct
leftist
*
linsert
(
struct
leftist
*
root
,
struct
leftist
*
new1
)
linsert
(
struct
leftist
*
root
,
struct
leftist
*
new1
,
LeftistContext
context
)
{
register
struct
leftist
*
left
,
*
right
;
if
(
!
tuplecmp
(
root
->
lt_tuple
,
new1
->
lt_tuple
))
{
if
(
!
tuplecmp
(
root
->
lt_tuple
,
new1
->
lt_tuple
,
context
))
{
new1
->
lt_left
=
root
;
return
(
new1
);
}
...
...
@@ -116,7 +93,7 @@ linsert(struct leftist *root, struct leftist *new1)
}
return
(
root
);
}
right
=
linsert
(
right
,
new1
);
right
=
linsert
(
right
,
new1
,
context
);
if
(
right
->
lt_dist
<
left
->
lt_dist
)
{
root
->
lt_dist
=
1
+
left
->
lt_dist
;
root
->
lt_left
=
right
;
...
...
@@ -142,7 +119,8 @@ linsert(struct leftist *root, struct leftist *new1)
*/
HeapTuple
gettuple
(
struct
leftist
**
treep
,
short
*
devnum
)
/* device from which tuple came */
short
*
devnum
,
/* device from which tuple came */
LeftistContext
context
)
{
register
struct
leftist
*
tp
;
HeapTuple
tup
;
...
...
@@ -153,9 +131,9 @@ gettuple(struct leftist **treep,
if
(
tp
->
lt_dist
==
1
)
/* lt_left == NULL */
*
treep
=
tp
->
lt_left
;
else
*
treep
=
lmerge
(
tp
->
lt_left
,
tp
->
lt_right
);
*
treep
=
lmerge
(
tp
->
lt_left
,
tp
->
lt_right
,
context
);
FREEMEM
(
sizeof
(
struct
leftist
));
FREEMEM
(
context
,
sizeof
(
struct
leftist
));
FREE
(
tp
);
return
(
tup
);
}
...
...
@@ -169,14 +147,17 @@ gettuple(struct leftist **treep,
* Note:
* Currently never returns NULL BUG
*/
int
puttuple
(
struct
leftist
**
treep
,
HeapTuple
newtuple
,
int
devnum
)
void
puttuple
(
struct
leftist
**
treep
,
HeapTuple
newtuple
,
short
devnum
,
LeftistContext
context
)
{
register
struct
leftist
*
new1
;
register
struct
leftist
*
tp
;
new1
=
(
struct
leftist
*
)
palloc
((
unsigned
)
sizeof
(
struct
leftist
));
USEMEM
(
sizeof
(
struct
leftist
));
USEMEM
(
context
,
sizeof
(
struct
leftist
));
new1
->
lt_dist
=
1
;
new1
->
lt_devnum
=
devnum
;
new1
->
lt_tuple
=
newtuple
;
...
...
@@ -185,38 +166,11 @@ puttuple(struct leftist **treep, HeapTuple newtuple, int devnum)
if
((
tp
=
*
treep
)
==
NULL
)
*
treep
=
new1
;
else
*
treep
=
linsert
(
tp
,
new1
);
return
(
1
)
;
*
treep
=
linsert
(
tp
,
new1
,
context
);
return
;
}
/*
* dumptuples - stores all the tuples in tree into file
*/
void
dumptuples
(
FILE
*
file
)
{
register
struct
leftist
*
tp
;
register
struct
leftist
*
newp
;
HeapTuple
tup
;
tp
=
Tuples
;
while
(
tp
!=
NULL
)
{
tup
=
tp
->
lt_tuple
;
if
(
tp
->
lt_dist
==
1
)
/* lt_right == NULL */
newp
=
tp
->
lt_left
;
else
newp
=
lmerge
(
tp
->
lt_left
,
tp
->
lt_right
);
FREEMEM
(
sizeof
(
struct
leftist
));
FREE
(
tp
);
PUTTUP
(
tup
,
file
);
FREEMEM
(
tup
->
t_len
);
FREE
(
tup
);
tp
=
newp
;
}
Tuples
=
NULL
;
}
/*
* tuplecmp - Compares two tuples with respect CmpList
*
...
...
@@ -225,7 +179,7 @@ dumptuples(FILE *file)
* Assumtions:
*/
int
tuplecmp
(
HeapTuple
ltup
,
HeapTuple
rtup
)
tuplecmp
(
HeapTuple
ltup
,
HeapTuple
rtup
,
LeftistContext
context
)
{
register
char
*
lattr
,
*
rattr
;
int
nkey
=
0
;
...
...
@@ -238,24 +192,27 @@ tuplecmp(HeapTuple ltup, HeapTuple rtup)
return
(
0
);
if
(
rtup
==
(
HeapTuple
)
NULL
)
return
(
1
);
while
(
nkey
<
Nk
eys
&&
!
result
)
{
while
(
nkey
<
context
->
nK
eys
&&
!
result
)
{
lattr
=
heap_getattr
(
ltup
,
InvalidBuffer
,
Key
[
nkey
].
sk_attno
,
RelationGetTupleDescriptor
(
SortRdesc
),
&
isnull
);
context
->
scanKeys
[
nkey
].
sk_attno
,
context
->
tupDesc
,
&
isnull
);
if
(
isnull
)
return
(
0
);
rattr
=
heap_getattr
(
rtup
,
InvalidBuffer
,
Key
[
nkey
].
sk_attno
,
RelationGetTupleDescriptor
(
SortRdesc
)
,
context
->
scanKeys
[
nkey
].
sk_attno
,
context
->
tupDesc
,
&
isnull
);
if
(
isnull
)
return
(
1
);
if
(
Key
[
nkey
].
sk_flags
&
SK_COMMUTE
)
{
if
(
!
(
result
=
(
long
)
(
*
Key
[
nkey
].
sk_func
)
(
rattr
,
lattr
)))
result
=
-
(
long
)
(
*
Key
[
nkey
].
sk_func
)
(
lattr
,
rattr
);
}
else
if
(
!
(
result
=
(
long
)
(
*
Key
[
nkey
].
sk_func
)
(
lattr
,
rattr
)))
result
=
-
(
long
)
(
*
Key
[
nkey
].
sk_func
)
(
rattr
,
lattr
);
if
(
context
->
scanKeys
[
nkey
].
sk_flags
&
SK_COMMUTE
)
{
if
(
!
(
result
=
(
long
)
(
*
context
->
scanKeys
[
nkey
].
sk_func
)
(
rattr
,
lattr
)))
result
=
-
(
long
)
(
*
context
->
scanKeys
[
nkey
].
sk_func
)
(
lattr
,
rattr
);
}
else
if
(
!
(
result
=
(
long
)
(
*
context
->
scanKeys
[
nkey
].
sk_func
)
(
lattr
,
rattr
)))
result
=
-
(
long
)
(
*
context
->
scanKeys
[
nkey
].
sk_func
)
(
rattr
,
lattr
);
nkey
++
;
}
return
(
result
==
1
);
...
...
@@ -263,7 +220,7 @@ tuplecmp(HeapTuple ltup, HeapTuple rtup)
#ifdef EBUG
void
checktree
(
struct
leftist
*
tree
)
checktree
(
struct
leftist
*
tree
,
LeftistContext
context
)
{
int
lnodes
;
int
rnodes
;
...
...
@@ -272,8 +229,8 @@ checktree(struct leftist *tree)
puts
(
"Null tree."
);
return
;
}
lnodes
=
checktreer
(
tree
->
lt_left
,
1
);
rnodes
=
checktreer
(
tree
->
lt_right
,
1
);
lnodes
=
checktreer
(
tree
->
lt_left
,
1
,
context
);
rnodes
=
checktreer
(
tree
->
lt_right
,
1
,
context
);
if
(
lnodes
<
0
)
{
lnodes
=
-
lnodes
;
puts
(
"0:
\t
Bad left side."
);
...
...
@@ -297,24 +254,24 @@ checktree(struct leftist *tree)
}
else
if
(
tree
->
lt_dist
!=
1
+
tree
->
lt_right
->
lt_dist
)
puts
(
"0:
\t
Distance incorrect."
);
if
(
lnodes
>
0
)
if
(
tuplecmp
(
tree
->
lt_left
->
lt_tuple
,
tree
->
lt_tuple
))
if
(
tuplecmp
(
tree
->
lt_left
->
lt_tuple
,
tree
->
lt_tuple
,
context
))
printf
(
"%d:
\t
Left child < parent.
\n
"
);
if
(
rnodes
>
0
)
if
(
tuplecmp
(
tree
->
lt_right
->
lt_tuple
,
tree
->
lt_tuple
))
if
(
tuplecmp
(
tree
->
lt_right
->
lt_tuple
,
tree
->
lt_tuple
,
context
))
printf
(
"%d:
\t
Right child < parent.
\n
"
);
printf
(
"Tree has %d nodes
\n
"
,
1
+
lnodes
+
rnodes
);
}
int
checktreer
(
struct
leftist
*
tree
,
int
level
)
checktreer
(
struct
leftist
*
tree
,
int
level
,
LeftistContext
context
)
{
int
lnodes
,
rnodes
;
int
error
=
0
;
if
(
tree
==
NULL
)
return
(
0
);
lnodes
=
checktreer
(
tree
->
lt_left
,
level
+
1
);
rnodes
=
checktreer
(
tree
->
lt_right
,
level
+
1
);
lnodes
=
checktreer
(
tree
->
lt_left
,
level
+
1
,
context
);
rnodes
=
checktreer
(
tree
->
lt_right
,
level
+
1
,
context
);
if
(
lnodes
<
0
)
{
error
=
1
;
lnodes
=
-
lnodes
;
...
...
@@ -349,12 +306,12 @@ checktreer(struct leftist *tree, int level)
printf
(
"%d:
\t
Distance incorrect.
\n
"
,
level
);
}
if
(
lnodes
>
0
)
if
(
tuplecmp
(
tree
->
lt_left
->
lt_tuple
,
tree
->
lt_tuple
))
{
if
(
tuplecmp
(
tree
->
lt_left
->
lt_tuple
,
tree
->
lt_tuple
,
context
))
{
error
=
1
;
printf
(
"%d:
\t
Left child < parent.
\n
"
);
}
if
(
rnodes
>
0
)
if
(
tuplecmp
(
tree
->
lt_right
->
lt_tuple
,
tree
->
lt_tuple
))
{
if
(
tuplecmp
(
tree
->
lt_right
->
lt_tuple
,
tree
->
lt_tuple
,
context
))
{
error
=
1
;
printf
(
"%d:
\t
Right child < parent.
\n
"
);
}
...
...
src/backend/utils/sort/psort.c
浏览文件 @
f5f366e1
此差异已折叠。
点击以展开。
src/include/nodes/execnodes.h
浏览文件 @
f5f366e1
...
...
@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: execnodes.h,v 1.
6 1996/11/04 08:52:54 scrappy
Exp $
* $Id: execnodes.h,v 1.
7 1997/08/06 03:42:02 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -605,7 +605,7 @@ typedef struct SortState {
CommonScanState
csstate
;
/* its first field is NodeTag */
bool
sort_Flag
;
ScanKey
sort_Keys
;
Relation
sort_TempRelation
;
bool
cleaned
;
}
SortState
;
/* ----------------
...
...
src/include/nodes/plannodes.h
浏览文件 @
f5f366e1
...
...
@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: plannodes.h,v 1.
5 1996/11/05 08:18:44 scrappy
Exp $
* $Id: plannodes.h,v 1.
6 1997/08/06 03:42:04 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -265,6 +265,8 @@ typedef struct Sort {
Oid
tempid
;
int
keycount
;
SortState
*
sortstate
;
void
*
psortstate
;
bool
cleaned
;
}
Sort
;
/* ----------------
...
...
src/include/utils/lselect.h
浏览文件 @
f5f366e1
...
...
@@ -6,15 +6,15 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: lselect.h,v 1.
3 1996/11/04 11:51:19 scrappy
Exp $
*
* $Id: lselect.h,v 1.
4 1997/08/06 03:42:07 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef LSELECT_H
#define LSELECT_H
#include <stdio.h>
#include
<access/htup.h>
#include
"access/htup.h"
struct
leftist
{
short
lt_dist
;
/* distance to leaf/empty node */
...
...
@@ -24,17 +24,26 @@ struct leftist {
struct
leftist
*
lt_right
;
};
extern
struct
leftist
*
Tuples
;
/* replaces global variables in lselect.c to make it reentrant */
typedef
struct
{
TupleDesc
tupDesc
;
int
nKeys
;
ScanKey
scanKeys
;
int
sortMem
;
/* needed for psort */
}
LeftistContextData
;
typedef
LeftistContextData
*
LeftistContext
;
extern
struct
leftist
*
lmerge
(
struct
leftist
*
pt
,
struct
leftist
*
qt
);
extern
HeapTuple
gettuple
(
struct
leftist
**
treep
,
short
*
devnum
);
extern
int
puttuple
(
struct
leftist
**
treep
,
HeapTuple
newtuple
,
int
devnum
);
extern
void
dumptuples
(
FILE
*
file
);
extern
int
tuplecmp
(
HeapTuple
ltup
,
HeapTuple
rtup
);
extern
struct
leftist
*
lmerge
(
struct
leftist
*
pt
,
struct
leftist
*
qt
,
LeftistContext
context
);
extern
HeapTuple
gettuple
(
struct
leftist
**
treep
,
short
*
devnum
,
LeftistContext
context
);
extern
void
puttuple
(
struct
leftist
**
treep
,
HeapTuple
newtuple
,
short
devnum
,
LeftistContext
context
);
extern
int
tuplecmp
(
HeapTuple
ltup
,
HeapTuple
rtup
,
LeftistContext
context
);
#ifdef EBUG
extern
void
checktree
(
struct
leftist
*
tree
);
extern
int
checktreer
(
struct
leftist
*
tree
,
int
level
);
extern
void
checktree
(
struct
leftist
*
tree
,
LeftistContext
context
);
extern
int
checktreer
(
struct
leftist
*
tree
,
int
level
,
LeftistContext
context
);
#endif
/* EBUG */
#endif
/* LSELECT_H */
src/include/utils/psort.h
浏览文件 @
f5f366e1
...
...
@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: psort.h,v 1.
3 1997/05/20 11:37:33 vadim
Exp $
* $Id: psort.h,v 1.
4 1997/08/06 03:42:13 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -14,11 +14,13 @@
#define PSORT_H
#include <stdio.h>
#include <access/relscan.h>
#include "access/relscan.h"
#include "utils/lselect.h"
#include "nodes/plannodes.h"
#define SORTMEM (1 << 18)
/* 1/4 M - any static memory */
#define MAXTAPES 7
/* 7--See Fig. 70, p273 */
#define TAPEEXT
"pg_psort.XXXXXX"
/* TEMPDIR/TAPEEXT */
#define TAPEEXT
LEN strlen("pg_psort.xxxxx.xxx")
/* TEMPDIR/TAPEEXT */
#define FREE(x) pfree((char *) x)
struct
tape
{
...
...
@@ -35,13 +37,38 @@ struct cmplist {
struct
cmplist
*
cp_next
;
/* next in chain */
};
extern
int
Nkeys
;
extern
ScanKey
key
;
extern
int
SortMemory
;
/* free memory */
extern
Relation
SortRdesc
;
extern
struct
leftist
*
Tuples
;
/* This structure preserves the state of psort between calls from different
* nodes to its interface functions. Basically, it includes all of the global
* variables in psort. In case you were wondering, pointers to these structures
* are included in Sort node structures. -Rex 2.6.1995
*/
typedef
struct
Psortstate
{
LeftistContextData
treeContext
;
int
TapeRange
;
int
Level
;
int
TotalDummy
;
struct
tape
Tape
[
MAXTAPES
];
int
BytesRead
;
int
BytesWritten
;
int
tupcount
;
struct
leftist
*
Tuples
;
FILE
*
psort_grab_file
;
long
psort_current
;
/* could be file offset, or array index */
long
psort_saved
;
/* could be file offset, or array index */
bool
using_tape_files
;
HeapTuple
*
memtuples
;
}
Psortstate
;
#ifdef EBUG
#include <stdio.h>
#include "utils/elog.h"
#include "storage/buf.h"
#include "storage/bufmgr.h"
#define PDEBUG(PROC, S1)\
elog(DEBUG, "%s:%d>> PROC: %s.", __FILE__, __LINE__, S1)
...
...
@@ -69,15 +96,21 @@ if (1) CODE; else
#endif
/* psort.c */
extern
void
psort
(
Relation
oldrel
,
Relation
newrel
,
int
nkeys
,
ScanKey
key
);
extern
void
init
psort
(
void
);
extern
bool
psort_begin
(
Sort
*
node
,
int
nkeys
,
ScanKey
key
);
extern
void
init
tapes
(
Sort
*
node
);
extern
void
resetpsort
(
void
);
extern
void
initialrun
(
Relation
rdesc
);
extern
bool
createrun
(
HeapScanDesc
sdesc
,
FILE
*
file
);
extern
HeapTuple
tuplecopy
(
HeapTuple
tup
,
Relation
rdesc
,
Buffer
b
);
extern
FILE
*
mergeruns
(
void
);
extern
void
merge
(
struct
tape
*
dest
);
extern
void
endpsort
(
Relation
rdesc
,
FILE
*
file
);
extern
void
initialrun
(
Sort
*
node
,
bool
*
empty
);
extern
bool
createrun
(
Sort
*
node
,
FILE
*
file
,
bool
*
empty
);
extern
HeapTuple
tuplecopy
(
HeapTuple
tup
);
extern
FILE
*
mergeruns
(
Sort
*
node
);
extern
void
merge
(
Sort
*
node
,
struct
tape
*
dest
);
extern
void
dumptuples
(
Sort
*
node
);
extern
HeapTuple
psort_grabtuple
(
Sort
*
node
);
extern
void
psort_markpos
(
Sort
*
node
);
extern
void
psort_restorepos
(
Sort
*
node
);
extern
void
psort_end
(
Sort
*
node
);
extern
FILE
*
gettape
(
void
);
extern
void
resettape
(
FILE
*
file
);
extern
void
destroytape
(
FILE
*
file
);
...
...
src/man/postgres.1
浏览文件 @
f5f366e1
.\" This is -*-nroff-*-
.\" XXX standard disclaimer belongs here....
.\" $Header: /cvsroot/pgsql/src/man/Attic/postgres.1,v 1.
5 1997/01/26 15:32:20 scrappy
Exp $
.\" $Header: /cvsroot/pgsql/src/man/Attic/postgres.1,v 1.
6 1997/08/06 03:42:18 momjian
Exp $
.TH POSTGRES95 UNIX 12/08/96 Postgres95 Postgres95
.SH NAME
postgres \(em the Postgres backend server
...
...
@@ -79,7 +79,10 @@ is the number of shared-memory buffers that the
.IR "postmaster"
has allocated for the backend server processes that it starts. If the
backend is running standalone, this specifies the number of buffers to
allocate. This value defaults to 64.
allocate. This value defaults to 64, and each buffer is 8k bytes.
.TP
.BR "-E"
Echo all queries.
.TP
.BR "-F"
Disable automatic fsync() call after each transaction.
...
...
@@ -89,15 +92,17 @@ while a transaction is in progress will probably cause data loss.
.BR "-P" " filedes"
.IR "filedes"
specifies the file descriptor that corresponds to the socket (port) on
which to communicate to the frontend process. This option is
which to communicate to the frontend process. This option is
.BR not
useful for interactive use.
.TP
.BR "-Q"
Specifies \*(lqquiet\*(rq mode.
.TP
.BR "-E"
Echo all queries.
.BR "-S"
Specifies the amount of memory to be used by internal sorts before using
disk files for sorting. This value is specified in 1k bytes, and
defaults to 512.
.TP
.BR "-e"
The
...
...
@@ -154,15 +159,6 @@ Turns off the locking system.
.BR "-N"
Disables use of newline as a query delimiter.
.TP
.BR "-S"
Indicates that the transaction system can run with the assumption of
stable main memory, thereby avoiding the necessary flushing of data
and log pages to disk at the end of each transaction system. This is
only used for performance comparisons for stable vs. non-stable
storage. Do not use this in other cases, as recovery after a system
crash may be impossible when this option is specified in the absence
of stable main memory.
.TP
.BR "-b"
Enables generation of bushy query plan trees (as opposed to left-deep
query plans trees). These query plans are not intended for actual
...
...
src/man/postmaster.1
浏览文件 @
f5f366e1
.\" This is -*-nroff-*-
.\" XXX standard disclaimer belongs here....
.\" $Header: /cvsroot/pgsql/src/man/Attic/postmaster.1,v 1.
5 1997/02/19 01:31:30
momjian Exp $
.\" $Header: /cvsroot/pgsql/src/man/Attic/postmaster.1,v 1.
6 1997/08/06 03:42:21
momjian Exp $
.TH POSTMASTER UNIX 11/05/95 PostgreSQL PostgreSQL
.SH "NAME"
postmaster \(em run the Postgres postmaster
...
...
@@ -60,7 +60,7 @@ understands the following command-line options:
is the number of shared-memory buffers for the
.IR "postmaster"
to allocate and manage for the backend server processes that it
starts. This value defaults to 64.
starts. This value defaults to 64
, and each buffer is 8k bytes
.
.TP
.BR "-D" " data_dir"
Specifies the directory to use as the root of the tree of database
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录