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
e3a1ab76
Commit
e3a1ab76
authored
Jan 29, 1999
by
Vadim B. Mikheev
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
READ COMMITTED isolevel is implemented and is default now.
parent
3e2f87f3
Changes
12
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
499 additions
and
128 deletions
+499
-128
src/backend/access/heap/heapam.c
src/backend/access/heap/heapam.c
+2
-1
src/backend/access/nbtree/nbtinsert.c
src/backend/access/nbtree/nbtinsert.c
+2
-1
src/backend/access/transam/xact.c
src/backend/access/transam/xact.c
+2
-2
src/backend/commands/trigger.c
src/backend/commands/trigger.c
+21
-2
src/backend/executor/execMain.c
src/backend/executor/execMain.c
+356
-56
src/backend/executor/nodeIndexscan.c
src/backend/executor/nodeIndexscan.c
+43
-1
src/backend/executor/nodeSeqscan.c
src/backend/executor/nodeSeqscan.c
+37
-4
src/backend/nodes/copyfuncs.c
src/backend/nodes/copyfuncs.c
+4
-39
src/backend/parser/gram.c
src/backend/parser/gram.c
+4
-4
src/backend/utils/time/tqual.c
src/backend/utils/time/tqual.c
+4
-1
src/include/nodes/execnodes.h
src/include/nodes/execnodes.h
+22
-16
src/include/utils/tqual.h
src/include/utils/tqual.h
+2
-1
No files found.
src/backend/access/heap/heapam.c
View file @
e3a1ab76
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.
39 1998/12/15 12:45:13
vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.
40 1999/01/29 09:22:51
vadim Exp $
*
*
*
*
* INTERFACE ROUTINES
* INTERFACE ROUTINES
...
@@ -1373,6 +1373,7 @@ l3:
...
@@ -1373,6 +1373,7 @@ l3:
if
(
result
!=
HeapTupleMayBeUpdated
)
if
(
result
!=
HeapTupleMayBeUpdated
)
{
{
Assert
(
result
==
HeapTupleSelfUpdated
||
result
==
HeapTupleUpdated
);
Assert
(
result
==
HeapTupleSelfUpdated
||
result
==
HeapTupleUpdated
);
tuple
->
t_self
=
tuple
->
t_data
->
t_ctid
;
LockBuffer
(
*
buffer
,
BUFFER_LOCK_UNLOCK
);
LockBuffer
(
*
buffer
,
BUFFER_LOCK_UNLOCK
);
return
result
;
return
result
;
}
}
...
...
src/backend/access/nbtree/nbtinsert.c
View file @
e3a1ab76
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.3
2 1998/12/15 12:45:20
vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.3
3 1999/01/29 09:22:52
vadim Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -134,6 +134,7 @@ l1:
...
@@ -134,6 +134,7 @@ l1:
* If this tuple is being updated by other transaction
* If this tuple is being updated by other transaction
* then we have to wait for its commit/abort.
* then we have to wait for its commit/abort.
*/
*/
ReleaseBuffer
(
buffer
);
if
(
TransactionIdIsValid
(
xwait
))
if
(
TransactionIdIsValid
(
xwait
))
{
{
if
(
nbuf
!=
InvalidBuffer
)
if
(
nbuf
!=
InvalidBuffer
)
...
...
src/backend/access/transam/xact.c
View file @
e3a1ab76
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.2
8 1998/12/18 09:10:18
vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.2
9 1999/01/29 09:22:53
vadim Exp $
*
*
* NOTES
* NOTES
* Transaction aborts can now occur two ways:
* Transaction aborts can now occur two ways:
...
@@ -194,7 +194,7 @@ TransactionStateData CurrentTransactionStateData = {
...
@@ -194,7 +194,7 @@ TransactionStateData CurrentTransactionStateData = {
TransactionState
CurrentTransactionState
=
TransactionState
CurrentTransactionState
=
&
CurrentTransactionStateData
;
&
CurrentTransactionStateData
;
int
DefaultXactIsoLevel
=
XACT_
SERIALIZABLE
;
int
DefaultXactIsoLevel
=
XACT_
READ_COMMITTED
;
int
XactIsoLevel
;
int
XactIsoLevel
;
/* ----------------
/* ----------------
...
...
src/backend/commands/trigger.c
View file @
e3a1ab76
...
@@ -28,6 +28,7 @@
...
@@ -28,6 +28,7 @@
#include "utils/inval.h"
#include "utils/inval.h"
#include "utils/builtins.h"
#include "utils/builtins.h"
#include "utils/syscache.h"
#include "utils/syscache.h"
#include "executor/executor.h"
#ifndef NO_SECURITY
#ifndef NO_SECURITY
#include "miscadmin.h"
#include "miscadmin.h"
...
@@ -790,6 +791,8 @@ ExecARUpdateTriggers(EState *estate, ItemPointer tupleid, HeapTuple newtuple)
...
@@ -790,6 +791,8 @@ ExecARUpdateTriggers(EState *estate, ItemPointer tupleid, HeapTuple newtuple)
return
;
return
;
}
}
extern
TupleTableSlot
*
EvalPlanQual
(
EState
*
estate
,
Index
rti
,
ItemPointer
tid
);
static
HeapTuple
static
HeapTuple
GetTupleForTrigger
(
EState
*
estate
,
ItemPointer
tid
,
bool
before
)
GetTupleForTrigger
(
EState
*
estate
,
ItemPointer
tid
,
bool
before
)
{
{
...
@@ -806,6 +809,7 @@ GetTupleForTrigger(EState *estate, ItemPointer tid, bool before)
...
@@ -806,6 +809,7 @@ GetTupleForTrigger(EState *estate, ItemPointer tid, bool before)
* mark tuple for update
* mark tuple for update
*/
*/
tuple
.
t_self
=
*
tid
;
tuple
.
t_self
=
*
tid
;
ltrmark:
;
test
=
heap_mark4update
(
relation
,
&
tuple
,
&
buffer
);
test
=
heap_mark4update
(
relation
,
&
tuple
,
&
buffer
);
switch
(
test
)
switch
(
test
)
{
{
...
@@ -820,8 +824,23 @@ GetTupleForTrigger(EState *estate, ItemPointer tid, bool before)
...
@@ -820,8 +824,23 @@ GetTupleForTrigger(EState *estate, ItemPointer tid, bool before)
ReleaseBuffer
(
buffer
);
ReleaseBuffer
(
buffer
);
if
(
XactIsoLevel
==
XACT_SERIALIZABLE
)
if
(
XactIsoLevel
==
XACT_SERIALIZABLE
)
elog
(
ERROR
,
"Can't serialize access due to concurrent update"
);
elog
(
ERROR
,
"Can't serialize access due to concurrent update"
);
else
else
if
(
!
(
ItemPointerEquals
(
&
(
tuple
.
t_self
),
tid
)))
elog
(
ERROR
,
"Isolation level %u is not supported"
,
XactIsoLevel
);
{
TupleTableSlot
*
slot
=
EvalPlanQual
(
estate
,
estate
->
es_result_relation_info
->
ri_RangeTableIndex
,
&
(
tuple
.
t_self
));
if
(
!
(
TupIsNull
(
slot
)))
{
*
tid
=
tuple
.
t_self
;
goto
ltrmark
;
}
}
/*
* if tuple was deleted or PlanQual failed
* for updated tuple - we have not process
* this tuple!
*/
return
(
NULL
);
return
(
NULL
);
default:
default:
...
...
src/backend/executor/execMain.c
View file @
e3a1ab76
...
@@ -26,7 +26,7 @@
...
@@ -26,7 +26,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.6
5 1999/01/27 16:48:20 tgl
Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.6
6 1999/01/29 09:22:57 vadim
Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -64,9 +64,8 @@ static TupleDesc InitPlan(CmdType operation, Query *parseTree,
...
@@ -64,9 +64,8 @@ static TupleDesc InitPlan(CmdType operation, Query *parseTree,
Plan
*
plan
,
EState
*
estate
);
Plan
*
plan
,
EState
*
estate
);
static
void
EndPlan
(
Plan
*
plan
,
EState
*
estate
);
static
void
EndPlan
(
Plan
*
plan
,
EState
*
estate
);
static
TupleTableSlot
*
ExecutePlan
(
EState
*
estate
,
Plan
*
plan
,
static
TupleTableSlot
*
ExecutePlan
(
EState
*
estate
,
Plan
*
plan
,
Query
*
parseTree
,
CmdType
operation
,
CmdType
operation
,
int
numberTuples
,
ScanDirection
direction
,
int
numberTuples
,
ScanDirection
direction
,
void
(
*
printfunc
)
());
DestReceiver
*
destfunc
);
static
void
ExecRetrieve
(
TupleTableSlot
*
slot
,
static
void
ExecRetrieve
(
TupleTableSlot
*
slot
,
DestReceiver
*
destfunc
,
DestReceiver
*
destfunc
,
EState
*
estate
);
EState
*
estate
);
...
@@ -75,7 +74,11 @@ static void ExecAppend(TupleTableSlot *slot, ItemPointer tupleid,
...
@@ -75,7 +74,11 @@ static void ExecAppend(TupleTableSlot *slot, ItemPointer tupleid,
static
void
ExecDelete
(
TupleTableSlot
*
slot
,
ItemPointer
tupleid
,
static
void
ExecDelete
(
TupleTableSlot
*
slot
,
ItemPointer
tupleid
,
EState
*
estate
);
EState
*
estate
);
static
void
ExecReplace
(
TupleTableSlot
*
slot
,
ItemPointer
tupleid
,
static
void
ExecReplace
(
TupleTableSlot
*
slot
,
ItemPointer
tupleid
,
EState
*
estate
,
Query
*
parseTree
);
EState
*
estate
);
TupleTableSlot
*
EvalPlanQual
(
EState
*
estate
,
Index
rti
,
ItemPointer
tid
);
static
TupleTableSlot
*
EvalPlanQualNext
(
EState
*
estate
);
/* end of local decls */
/* end of local decls */
...
@@ -168,11 +171,10 @@ TupleTableSlot *
...
@@ -168,11 +171,10 @@ TupleTableSlot *
ExecutorRun
(
QueryDesc
*
queryDesc
,
EState
*
estate
,
int
feature
,
int
count
)
ExecutorRun
(
QueryDesc
*
queryDesc
,
EState
*
estate
,
int
feature
,
int
count
)
{
{
CmdType
operation
;
CmdType
operation
;
Query
*
parseTree
;
Plan
*
plan
;
Plan
*
plan
;
TupleTableSlot
*
result
;
TupleTableSlot
*
result
;
CommandDest
dest
;
CommandDest
dest
;
DestReceiver
*
destfunc
;
void
(
*
destination
)
()
;
/******************
/******************
* sanity checks
* sanity checks
...
@@ -186,42 +188,30 @@ ExecutorRun(QueryDesc *queryDesc, EState *estate, int feature, int count)
...
@@ -186,42 +188,30 @@ ExecutorRun(QueryDesc *queryDesc, EState *estate, int feature, int count)
******************
******************
*/
*/
operation
=
queryDesc
->
operation
;
operation
=
queryDesc
->
operation
;
parseTree
=
queryDesc
->
parsetree
;
plan
=
queryDesc
->
plantree
;
plan
=
queryDesc
->
plantree
;
dest
=
queryDesc
->
dest
;
dest
=
queryDesc
->
dest
;
dest
func
=
DestToFunction
(
dest
);
dest
ination
=
(
void
(
*
)
())
DestToFunction
(
dest
);
estate
->
es_processed
=
0
;
estate
->
es_processed
=
0
;
estate
->
es_lastoid
=
InvalidOid
;
estate
->
es_lastoid
=
InvalidOid
;
/******************
* FIXME: the dest setup function ought to be handed the tuple desc
* for the tuples to be output, but I'm not quite sure how to get that
* info at this point. For now, passing NULL is OK because no existing
* dest setup function actually uses the pointer.
******************
*/
(
*
destfunc
->
setup
)
(
destfunc
,
(
TupleDesc
)
NULL
);
switch
(
feature
)
switch
(
feature
)
{
{
case
EXEC_RUN
:
case
EXEC_RUN
:
result
=
ExecutePlan
(
estate
,
result
=
ExecutePlan
(
estate
,
plan
,
plan
,
parseTree
,
operation
,
operation
,
ALL_TUPLES
,
ALL_TUPLES
,
ForwardScanDirection
,
ForwardScanDirection
,
dest
func
);
dest
ination
);
break
;
break
;
case
EXEC_FOR
:
case
EXEC_FOR
:
result
=
ExecutePlan
(
estate
,
result
=
ExecutePlan
(
estate
,
plan
,
plan
,
parseTree
,
operation
,
operation
,
count
,
count
,
ForwardScanDirection
,
ForwardScanDirection
,
dest
func
);
dest
ination
);
break
;
break
;
/******************
/******************
...
@@ -231,11 +221,10 @@ ExecutorRun(QueryDesc *queryDesc, EState *estate, int feature, int count)
...
@@ -231,11 +221,10 @@ ExecutorRun(QueryDesc *queryDesc, EState *estate, int feature, int count)
case
EXEC_BACK
:
case
EXEC_BACK
:
result
=
ExecutePlan
(
estate
,
result
=
ExecutePlan
(
estate
,
plan
,
plan
,
parseTree
,
operation
,
operation
,
count
,
count
,
BackwardScanDirection
,
BackwardScanDirection
,
dest
func
);
dest
ination
);
break
;
break
;
/******************
/******************
...
@@ -246,11 +235,10 @@ ExecutorRun(QueryDesc *queryDesc, EState *estate, int feature, int count)
...
@@ -246,11 +235,10 @@ ExecutorRun(QueryDesc *queryDesc, EState *estate, int feature, int count)
case
EXEC_RETONE
:
case
EXEC_RETONE
:
result
=
ExecutePlan
(
estate
,
result
=
ExecutePlan
(
estate
,
plan
,
plan
,
parseTree
,
operation
,
operation
,
ONE_TUPLE
,
ONE_TUPLE
,
ForwardScanDirection
,
ForwardScanDirection
,
dest
func
);
dest
ination
);
break
;
break
;
default:
default:
result
=
NULL
;
result
=
NULL
;
...
@@ -258,8 +246,6 @@ ExecutorRun(QueryDesc *queryDesc, EState *estate, int feature, int count)
...
@@ -258,8 +246,6 @@ ExecutorRun(QueryDesc *queryDesc, EState *estate, int feature, int count)
break
;
break
;
}
}
(
*
destfunc
->
cleanup
)
(
destfunc
);
return
result
;
return
result
;
}
}
...
@@ -413,9 +399,18 @@ ExecCheckPerms(CmdType operation,
...
@@ -413,9 +399,18 @@ ExecCheckPerms(CmdType operation,
typedef
struct
execRowMark
typedef
struct
execRowMark
{
{
Relation
relation
;
Relation
relation
;
Index
rti
;
char
resname
[
32
];
char
resname
[
32
];
}
execRowMark
;
}
execRowMark
;
typedef
struct
evalPlanQual
{
Plan
*
plan
;
Index
rti
;
EState
estate
;
struct
evalPlanQual
*
free
;
}
evalPlanQual
;
/* ----------------------------------------------------------------
/* ----------------------------------------------------------------
* InitPlan
* InitPlan
*
*
...
@@ -429,7 +424,6 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
...
@@ -429,7 +424,6 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
List
*
rangeTable
;
List
*
rangeTable
;
int
resultRelation
;
int
resultRelation
;
Relation
intoRelationDesc
;
Relation
intoRelationDesc
;
TupleDesc
tupType
;
TupleDesc
tupType
;
List
*
targetList
;
List
*
targetList
;
int
len
;
int
len
;
...
@@ -537,6 +531,7 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
...
@@ -537,6 +531,7 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
continue
;
continue
;
erm
=
(
execRowMark
*
)
palloc
(
sizeof
(
execRowMark
));
erm
=
(
execRowMark
*
)
palloc
(
sizeof
(
execRowMark
));
erm
->
relation
=
relation
;
erm
->
relation
=
relation
;
erm
->
rti
=
rm
->
rti
;
sprintf
(
erm
->
resname
,
"ctid%u"
,
rm
->
rti
);
sprintf
(
erm
->
resname
,
"ctid%u"
,
rm
->
rti
);
estate
->
es_rowMark
=
lappend
(
estate
->
es_rowMark
,
erm
);
estate
->
es_rowMark
=
lappend
(
estate
->
es_rowMark
,
erm
);
}
}
...
@@ -669,6 +664,11 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
...
@@ -669,6 +664,11 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
estate
->
es_into_relation_descriptor
=
intoRelationDesc
;
estate
->
es_into_relation_descriptor
=
intoRelationDesc
;
estate
->
es_origPlan
=
plan
;
estate
->
es_evalPlanQual
=
NULL
;
estate
->
es_evTuple
=
NULL
;
estate
->
es_useEvalPlan
=
false
;
return
tupType
;
return
tupType
;
}
}
...
@@ -753,11 +753,10 @@ EndPlan(Plan *plan, EState *estate)
...
@@ -753,11 +753,10 @@ EndPlan(Plan *plan, EState *estate)
static
TupleTableSlot
*
static
TupleTableSlot
*
ExecutePlan
(
EState
*
estate
,
ExecutePlan
(
EState
*
estate
,
Plan
*
plan
,
Plan
*
plan
,
Query
*
parseTree
,
CmdType
operation
,
CmdType
operation
,
int
numberTuples
,
int
numberTuples
,
ScanDirection
direction
,
ScanDirection
direction
,
DestReceiver
*
destfunc
)
void
(
*
printfunc
)
()
)
{
{
JunkFilter
*
junkfilter
;
JunkFilter
*
junkfilter
;
...
@@ -794,6 +793,14 @@ ExecutePlan(EState *estate,
...
@@ -794,6 +793,14 @@ ExecutePlan(EState *estate,
******************
******************
*/
*/
/* at the top level, the parent of a plan (2nd arg) is itself */
/* at the top level, the parent of a plan (2nd arg) is itself */
lnext:
;
if
(
estate
->
es_useEvalPlan
)
{
slot
=
EvalPlanQualNext
(
estate
);
if
(
TupIsNull
(
slot
))
slot
=
ExecProcNode
(
plan
,
plan
);
}
else
slot
=
ExecProcNode
(
plan
,
plan
);
slot
=
ExecProcNode
(
plan
,
plan
);
/******************
/******************
...
@@ -821,8 +828,6 @@ ExecutePlan(EState *estate,
...
@@ -821,8 +828,6 @@ ExecutePlan(EState *estate,
if
((
junkfilter
=
estate
->
es_junkFilter
)
!=
(
JunkFilter
*
)
NULL
)
if
((
junkfilter
=
estate
->
es_junkFilter
)
!=
(
JunkFilter
*
)
NULL
)
{
{
Datum
datum
;
Datum
datum
;
/* NameData attrName; */
HeapTuple
newTuple
;
HeapTuple
newTuple
;
bool
isNull
;
bool
isNull
;
...
@@ -853,8 +858,10 @@ ExecutePlan(EState *estate,
...
@@ -853,8 +858,10 @@ ExecutePlan(EState *estate,
execRowMark
*
erm
;
execRowMark
*
erm
;
Buffer
buffer
;
Buffer
buffer
;
HeapTupleData
tuple
;
HeapTupleData
tuple
;
TupleTableSlot
*
newSlot
;
int
test
;
int
test
;
lmark:
;
foreach
(
l
,
estate
->
es_rowMark
)
foreach
(
l
,
estate
->
es_rowMark
)
{
{
erm
=
lfirst
(
l
);
erm
=
lfirst
(
l
);
...
@@ -879,10 +886,27 @@ ExecutePlan(EState *estate,
...
@@ -879,10 +886,27 @@ ExecutePlan(EState *estate,
case
HeapTupleUpdated
:
case
HeapTupleUpdated
:
if
(
XactIsoLevel
==
XACT_SERIALIZABLE
)
if
(
XactIsoLevel
==
XACT_SERIALIZABLE
)
{
elog
(
ERROR
,
"Can't serialize access due to concurrent update"
);
elog
(
ERROR
,
"Can't serialize access due to concurrent update"
);
else
elog
(
ERROR
,
"Isolation level %u is not supported"
,
XactIsoLevel
);
return
(
NULL
);
return
(
NULL
);
}
else
if
(
!
(
ItemPointerEquals
(
&
(
tuple
.
t_self
),
(
ItemPointer
)
DatumGetPointer
(
datum
))))
{
newSlot
=
EvalPlanQual
(
estate
,
erm
->
rti
,
&
(
tuple
.
t_self
));
if
(
!
(
TupIsNull
(
newSlot
)))
{
slot
=
newSlot
;
estate
->
es_useEvalPlan
=
true
;
goto
lmark
;
}
}
/*
* if tuple was deleted or PlanQual failed
* for updated tuple - we have not return
* this tuple!
*/
goto
lnext
;
default:
default:
elog
(
ERROR
,
"Unknown status %u from heap_mark4update"
,
test
);
elog
(
ERROR
,
"Unknown status %u from heap_mark4update"
,
test
);
...
@@ -917,7 +941,7 @@ ExecutePlan(EState *estate,
...
@@ -917,7 +941,7 @@ ExecutePlan(EState *estate,
{
{
case
CMD_SELECT
:
case
CMD_SELECT
:
ExecRetrieve
(
slot
,
/* slot containing tuple */
ExecRetrieve
(
slot
,
/* slot containing tuple */
destfunc
,
/* destination's tuple-receiver obj
*/
printfunc
,
/* print function
*/
estate
);
/* */
estate
);
/* */
result
=
slot
;
result
=
slot
;
break
;
break
;
...
@@ -933,7 +957,7 @@ ExecutePlan(EState *estate,
...
@@ -933,7 +957,7 @@ ExecutePlan(EState *estate,
break
;
break
;
case
CMD_UPDATE
:
case
CMD_UPDATE
:
ExecReplace
(
slot
,
tupleid
,
estate
,
parseTree
);
ExecReplace
(
slot
,
tupleid
,
estate
);
result
=
NULL
;
result
=
NULL
;
break
;
break
;
...
@@ -973,7 +997,7 @@ ExecutePlan(EState *estate,
...
@@ -973,7 +997,7 @@ ExecutePlan(EState *estate,
*/
*/
static
void
static
void
ExecRetrieve
(
TupleTableSlot
*
slot
,
ExecRetrieve
(
TupleTableSlot
*
slot
,
DestReceiver
*
destfunc
,
void
(
*
printfunc
)
()
,
EState
*
estate
)
EState
*
estate
)
{
{
HeapTuple
tuple
;
HeapTuple
tuple
;
...
@@ -1000,7 +1024,7 @@ ExecRetrieve(TupleTableSlot *slot,
...
@@ -1000,7 +1024,7 @@ ExecRetrieve(TupleTableSlot *slot,
* send the tuple to the front end (or the screen)
* send the tuple to the front end (or the screen)
******************
******************
*/
*/
(
*
destfunc
->
receiveTuple
)
(
tuple
,
attrtype
,
destfunc
);
(
*
printfunc
)
(
tuple
,
attrtype
);
IncrRetrieved
();
IncrRetrieved
();
(
estate
->
es_processed
)
++
;
(
estate
->
es_processed
)
++
;
}
}
...
@@ -1115,7 +1139,8 @@ ExecDelete(TupleTableSlot *slot,
...
@@ -1115,7 +1139,8 @@ ExecDelete(TupleTableSlot *slot,
{
{
RelationInfo
*
resultRelationInfo
;
RelationInfo
*
resultRelationInfo
;
Relation
resultRelationDesc
;
Relation
resultRelationDesc
;
ItemPointerData
ctid
;
ItemPointerData
ctid
,
oldtid
;
int
result
;
int
result
;
/******************
/******************
...
@@ -1140,6 +1165,7 @@ ExecDelete(TupleTableSlot *slot,
...
@@ -1140,6 +1165,7 @@ ExecDelete(TupleTableSlot *slot,
/*
/*
* delete the tuple
* delete the tuple
*/
*/
ldelete:
;
result
=
heap_delete
(
resultRelationDesc
,
tupleid
,
&
ctid
);
result
=
heap_delete
(
resultRelationDesc
,
tupleid
,
&
ctid
);
switch
(
result
)
switch
(
result
)
{
{
...
@@ -1152,8 +1178,18 @@ ExecDelete(TupleTableSlot *slot,
...
@@ -1152,8 +1178,18 @@ ExecDelete(TupleTableSlot *slot,
case
HeapTupleUpdated
:
case
HeapTupleUpdated
:
if
(
XactIsoLevel
==
XACT_SERIALIZABLE
)
if
(
XactIsoLevel
==
XACT_SERIALIZABLE
)
elog
(
ERROR
,
"Can't serialize access due to concurrent update"
);
elog
(
ERROR
,
"Can't serialize access due to concurrent update"
);
else
else
if
(
!
(
ItemPointerEquals
(
tupleid
,
&
ctid
)))
elog
(
ERROR
,
"Isolation level %u is not supported"
,
XactIsoLevel
);
{
TupleTableSlot
*
slot
=
EvalPlanQual
(
estate
,
resultRelationInfo
->
ri_RangeTableIndex
,
&
ctid
);
if
(
!
TupIsNull
(
slot
))
{
tupleid
=
&
oldtid
;
*
tupleid
=
ctid
;
goto
ldelete
;
}
}
return
;
return
;
default:
default:
...
@@ -1197,13 +1233,13 @@ ExecDelete(TupleTableSlot *slot,
...
@@ -1197,13 +1233,13 @@ ExecDelete(TupleTableSlot *slot,
static
void
static
void
ExecReplace
(
TupleTableSlot
*
slot
,
ExecReplace
(
TupleTableSlot
*
slot
,
ItemPointer
tupleid
,
ItemPointer
tupleid
,
EState
*
estate
,
EState
*
estate
)
Query
*
parseTree
)
{
{
HeapTuple
tuple
;
HeapTuple
tuple
;
RelationInfo
*
resultRelationInfo
;
RelationInfo
*
resultRelationInfo
;
Relation
resultRelationDesc
;
Relation
resultRelationDesc
;
ItemPointerData
ctid
;
ItemPointerData
ctid
,
oldtid
;
int
result
;
int
result
;
int
numIndices
;
int
numIndices
;
...
@@ -1270,6 +1306,7 @@ ExecReplace(TupleTableSlot *slot,
...
@@ -1270,6 +1306,7 @@ ExecReplace(TupleTableSlot *slot,
/*
/*
* replace the heap tuple
* replace the heap tuple
*/
*/
lreplace:
;
result
=
heap_replace
(
resultRelationDesc
,
tupleid
,
tuple
,
&
ctid
);
result
=
heap_replace
(
resultRelationDesc
,
tupleid
,
tuple
,
&
ctid
);
switch
(
result
)
switch
(
result
)
{
{
...
@@ -1282,8 +1319,18 @@ ExecReplace(TupleTableSlot *slot,
...
@@ -1282,8 +1319,18 @@ ExecReplace(TupleTableSlot *slot,
case
HeapTupleUpdated
:
case
HeapTupleUpdated
:
if
(
XactIsoLevel
==
XACT_SERIALIZABLE
)
if
(
XactIsoLevel
==
XACT_SERIALIZABLE
)
elog
(
ERROR
,
"Can't serialize access due to concurrent update"
);
elog
(
ERROR
,
"Can't serialize access due to concurrent update"
);
else
else
if
(
!
(
ItemPointerEquals
(
tupleid
,
&
ctid
)))
elog
(
ERROR
,
"Isolation level %u is not supported"
,
XactIsoLevel
);
{
TupleTableSlot
*
slot
=
EvalPlanQual
(
estate
,
resultRelationInfo
->
ri_RangeTableIndex
,
&
ctid
);
if
(
!
TupIsNull
(
slot
))
{
tupleid
=
&
oldtid
;
*
tupleid
=
ctid
;
goto
lreplace
;
}
}
return
;
return
;
default:
default:
...
@@ -1480,3 +1527,256 @@ ExecConstraints(char *caller, Relation rel, HeapTuple tuple)
...
@@ -1480,3 +1527,256 @@ ExecConstraints(char *caller, Relation rel, HeapTuple tuple)
return
;
return
;
}
}
TupleTableSlot
*
EvalPlanQual
(
EState
*
estate
,
Index
rti
,
ItemPointer
tid
)
{
evalPlanQual
*
epq
=
(
evalPlanQual
*
)
estate
->
es_evalPlanQual
;
evalPlanQual
*
oldepq
;
EState
*
epqstate
=
NULL
;
Relation
relation
;
Buffer
buffer
;
HeapTupleData
tuple
;
bool
endNode
=
true
;
Assert
(
rti
!=
0
);
if
(
epq
!=
NULL
&&
epq
->
rti
==
0
)
{
Assert
(
!
(
estate
->
es_useEvalPlan
)
&&
epq
->
estate
.
es_evalPlanQual
==
NULL
);
epq
->
rti
=
rti
;
endNode
=
false
;
}
/*
* If this is request for another RTE - Ra, - then we have to check
* wasn't PlanQual requested for Ra already and if so then Ra' row
* was updated again and we have to re-start old execution for Ra
* and forget all what we done after Ra was suspended. Cool? -:))
*/
if
(
epq
!=
NULL
&&
epq
->
rti
!=
rti
&&
epq
->
estate
.
es_evTuple
[
rti
-
1
]
!=
NULL
)
{
do
{
/* pop previous PlanQual from the stack */
epqstate
=
&
(
epq
->
estate
);
oldepq
=
(
evalPlanQual
*
)
epqstate
->
es_evalPlanQual
;
Assert
(
oldepq
->
rti
!=
0
);
/* stop execution */
ExecEndNode
(
epq
->
plan
,
epq
->
plan
);
pfree
(
epqstate
->
es_evTuple
[
epq
->
rti
-
1
]);
epqstate
->
es_evTuple
[
epq
->
rti
-
1
]
=
NULL
;
/* push current PQ to freePQ stack */
oldepq
->
free
=
epq
;
epq
=
oldepq
;
}
while
(
epq
->
rti
!=
rti
);
estate
->
es_evalPlanQual
=
(
Pointer
)
epq
;
}
/*
* If we are requested for another RTE then we have to suspend
* execution of current PlanQual and start execution for new one.
*/
if
(
epq
==
NULL
||
epq
->
rti
!=
rti
)
{
/* try to reuse plan used previously */
evalPlanQual
*
newepq
=
(
epq
!=
NULL
)
?
epq
->
free
:
NULL
;
if
(
newepq
==
NULL
)
{
newepq
=
(
evalPlanQual
*
)
palloc
(
sizeof
(
evalPlanQual
));
/* Init EState */
epqstate
=
&
(
newepq
->
estate
);
memset
(
epqstate
,
0
,
sizeof
(
EState
));
epqstate
->
type
=
T_EState
;
epqstate
->
es_direction
=
ForwardScanDirection
;
epqstate
->
es_snapshot
=
estate
->
es_snapshot
;
epqstate
->
es_range_table
=
estate
->
es_range_table
;
epqstate
->
es_param_list_info
=
estate
->
es_param_list_info
;
if
(
estate
->
es_origPlan
->
nParamExec
>
0
)
epqstate
->
es_param_exec_vals
=
(
ParamExecData
*
)
palloc
(
estate
->
es_origPlan
->
nParamExec
*
sizeof
(
ParamExecData
));
epqstate
->
es_tupleTable
=
ExecCreateTupleTable
(
estate
->
es_tupleTable
->
size
);
epqstate
->
es_refcount
=
estate
->
es_refcount
;
/* ... rest */
newepq
->
plan
=
copyObject
(
estate
->
es_origPlan
);
newepq
->
free
=
NULL
;
if
(
epq
==
NULL
)
{
epqstate
->
es_evTuple
=
(
HeapTuple
*
)
palloc
(
length
(
estate
->
es_range_table
)
*
sizeof
(
HeapTuple
));
memset
(
epqstate
->
es_evTuple
,
0
,
length
(
estate
->
es_range_table
)
*
sizeof
(
HeapTuple
));
epqstate
->
es_evTupleNull
=
(
bool
*
)
palloc
(
length
(
estate
->
es_range_table
)
*
sizeof
(
bool
));
memset
(
epqstate
->
es_evTupleNull
,
false
,
length
(
estate
->
es_range_table
)
*
sizeof
(
bool
));
}
else
{
epqstate
->
es_evTuple
=
epq
->
estate
.
es_evTuple
;
epqstate
->
es_evTupleNull
=
epq
->
estate
.
es_evTupleNull
;
}
}
else
{
epqstate
=
&
(
newepq
->
estate
);
}
/* push current PQ to the stack */
epqstate
->
es_evalPlanQual
=
(
Pointer
)
epq
;
estate
->
es_evalPlanQual
=
(
Pointer
)
epq
=
newepq
;
epq
->
rti
=
rti
;
endNode
=
false
;
}
epqstate
=
&
(
epq
->
estate
);
/*
* Ok - we're requested for the same RTE (-:)).
* I'm not sure about ability to use ExecReScan instead of
* ExecInitNode, so...
*/
if
(
endNode
)
ExecEndNode
(
epq
->
plan
,
epq
->
plan
);
/* free old RTE' tuple */
if
(
epqstate
->
es_evTuple
[
epq
->
rti
-
1
]
!=
NULL
)
{
pfree
(
epqstate
->
es_evTuple
[
epq
->
rti
-
1
]);
epqstate
->
es_evTuple
[
epq
->
rti
-
1
]
=
NULL
;
}
/* ** fetch tid tuple ** */
if
(
estate
->
es_result_relation_info
!=
NULL
&&
estate
->
es_result_relation_info
->
ri_RangeTableIndex
==
rti
)
relation
=
estate
->
es_result_relation_info
->
ri_RelationDesc
;
else
{
List
*
l
;
foreach
(
l
,
estate
->
es_rowMark
)
{
if
(((
execRowMark
*
)
lfirst
(
l
))
->
rti
==
rti
)
break
;
}
relation
=
((
execRowMark
*
)
lfirst
(
l
))
->
relation
;
}
tuple
.
t_self
=
*
tid
;
for
(
;
;
)
{
heap_fetch
(
relation
,
SnapshotDirty
,
&
tuple
,
&
buffer
);
if
(
tuple
.
t_data
!=
NULL
)
{
TransactionId
xwait
=
SnapshotDirty
->
xmax
;
if
(
TransactionIdIsValid
(
SnapshotDirty
->
xmin
))
elog
(
ERROR
,
"EvalPlanQual: t_xmin is uncommitted ?!"
);
/*
* If tuple is being updated by other transaction then
* we have to wait for its commit/abort.
*/
if
(
TransactionIdIsValid
(
xwait
))
{
ReleaseBuffer
(
buffer
);
XactLockTableWait
(
xwait
);
continue
;
}
/*
* Nice! We got tuple - now copy it.
*/
epqstate
->
es_evTuple
[
epq
->
rti
-
1
]
=
heap_copytuple
(
&
tuple
);
epqstate
->
es_evTupleNull
[
epq
->
rti
-
1
]
=
false
;
ReleaseBuffer
(
buffer
);
break
;
}
/*
* Ops! Invalid tuple. Have to check is it updated or deleted.
* Note that it's possible to get invalid SnapshotDirty->tid
* if tuple updated by this transaction. Have we to check this ?
*/
if
(
ItemPointerIsValid
(
&
(
SnapshotDirty
->
tid
))
&&
!
(
ItemPointerEquals
(
&
(
tuple
.
t_self
),
&
(
SnapshotDirty
->
tid
))))
{
tuple
.
t_self
=
SnapshotDirty
->
tid
;
/* updated ... */
continue
;
}
/*
* Deleted or updated by this transaction. Do not
* (re-)start execution of this PQ. Continue previous PQ.
*/
oldepq
=
(
evalPlanQual
*
)
epqstate
->
es_evalPlanQual
;
if
(
oldepq
!=
NULL
)
{
Assert
(
oldepq
->
rti
!=
0
);
/* push current PQ to freePQ stack */
oldepq
->
free
=
epq
;
epq
=
oldepq
;
epqstate
=
&
(
epq
->
estate
);
estate
->
es_evalPlanQual
=
(
Pointer
)
epq
;
}
else
{
/* this is the first (oldest) PQ
epq->rti = 0; * - mark as free and
estate->es_useEvalPlan = false; * continue Query execution
return (NULL); */
}
}
if
(
estate
->
es_origPlan
->
nParamExec
>
0
)
memset
(
epqstate
->
es_param_exec_vals
,
0
,
estate
->
es_origPlan
->
nParamExec
*
sizeof
(
ParamExecData
));
ExecInitNode
(
epq
->
plan
,
epqstate
,
NULL
);
/*
* For UPDATE/DELETE we have to return tid of actual row
* we're executing PQ for.
*/
*
tid
=
tuple
.
t_self
;
return
(
EvalPlanQualNext
(
estate
));
}
static
TupleTableSlot
*
EvalPlanQualNext
(
EState
*
estate
)
{
evalPlanQual
*
epq
=
(
evalPlanQual
*
)
estate
->
es_evalPlanQual
;
EState
*
epqstate
=
&
(
epq
->
estate
);
evalPlanQual
*
oldepq
;
TupleTableSlot
*
slot
;
Assert
(
epq
->
rti
!=
0
);
lpqnext:
;
slot
=
ExecProcNode
(
epq
->
plan
,
epq
->
plan
);
/*
* No more tuples for this PQ. Continue previous one.
*/
if
(
TupIsNull
(
slot
))
{
ExecEndNode
(
epq
->
plan
,
epq
->
plan
);
pfree
(
epqstate
->
es_evTuple
[
epq
->
rti
-
1
]);
epqstate
->
es_evTuple
[
epq
->
rti
-
1
]
=
NULL
;
/* pop old PQ from the stack */
oldepq
=
(
evalPlanQual
*
)
epqstate
->
es_evalPlanQual
;
if
(
oldepq
==
(
evalPlanQual
*
)
NULL
)
{
/* this is the first (oldest) */
epq
->
rti
=
0
;
/* PQ - mark as free and */
estate
->
es_useEvalPlan
=
false
;
/* continue Query execution */
return
(
NULL
);
}
Assert
(
oldepq
->
rti
!=
0
);
/* push current PQ to freePQ stack */
oldepq
->
free
=
epq
;
epq
=
oldepq
;
epqstate
=
&
(
epq
->
estate
);
estate
->
es_evalPlanQual
=
(
Pointer
)
epq
;
goto
lpqnext
;
}
return
(
slot
);
}
src/backend/executor/nodeIndexscan.c
View file @
e3a1ab76
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.
29 1998/11/27 19:52:03
vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.
30 1999/01/29 09:22:58
vadim Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -109,6 +109,40 @@ IndexNext(IndexScan *node)
...
@@ -109,6 +109,40 @@ IndexNext(IndexScan *node)
heapRelation
=
scanstate
->
css_currentRelation
;
heapRelation
=
scanstate
->
css_currentRelation
;
numIndices
=
indexstate
->
iss_NumIndices
;
numIndices
=
indexstate
->
iss_NumIndices
;
slot
=
scanstate
->
css_ScanTupleSlot
;
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
* IndexScan --> NewNode switching in Init/ReScan plan...
*/
if
(
estate
->
es_evTuple
!=
NULL
&&
estate
->
es_evTuple
[
node
->
scan
.
scanrelid
-
1
]
!=
NULL
)
{
int
iptr
;
slot
->
ttc_buffer
=
InvalidBuffer
;
slot
->
ttc_shouldFree
=
false
;
if
(
estate
->
es_evTupleNull
[
node
->
scan
.
scanrelid
-
1
])
{
slot
->
val
=
NULL
;
/* must not free tuple! */
return
(
slot
);
}
slot
->
val
=
estate
->
es_evTuple
[
node
->
scan
.
scanrelid
-
1
];
for
(
iptr
=
0
;
iptr
<
numIndices
;
iptr
++
)
{
scanstate
->
cstate
.
cs_ExprContext
->
ecxt_scantuple
=
slot
;
if
(
ExecQual
(
nth
(
iptr
,
node
->
indxqualorig
),
scanstate
->
cstate
.
cs_ExprContext
))
break
;
}
if
(
iptr
==
numIndices
)
/* would not be returned by indices */
slot
->
val
=
NULL
;
/* Flag for the next call that no more tuples */
estate
->
es_evTupleNull
[
node
->
scan
.
scanrelid
-
1
]
=
true
;
return
(
slot
);
}
tuple
=
&
(
indexstate
->
iss_htup
);
tuple
=
&
(
indexstate
->
iss_htup
);
/* ----------------
/* ----------------
...
@@ -262,6 +296,14 @@ ExecIndexReScan(IndexScan *node, ExprContext *exprCtxt, Plan *parent)
...
@@ -262,6 +296,14 @@ ExecIndexReScan(IndexScan *node, ExprContext *exprCtxt, Plan *parent)
numScanKeys
=
indexstate
->
iss_NumScanKeys
;
numScanKeys
=
indexstate
->
iss_NumScanKeys
;
indexstate
->
iss_IndexPtr
=
0
;
indexstate
->
iss_IndexPtr
=
0
;
/* 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 */
/* it's possible in subselects */
if
(
exprCtxt
==
NULL
)
if
(
exprCtxt
==
NULL
)
exprCtxt
=
node
->
scan
.
scanstate
->
cstate
.
cs_ExprContext
;
exprCtxt
=
node
->
scan
.
scanstate
->
cstate
.
cs_ExprContext
;
...
...
src/backend/executor/nodeSeqscan.c
View file @
e3a1ab76
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/nodeSeqscan.c,v 1.1
5 1998/09/25 13:38:32 thomas
Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/nodeSeqscan.c,v 1.1
6 1999/01/29 09:22:58 vadim
Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -64,6 +64,34 @@ SeqNext(SeqScan *node)
...
@@ -64,6 +64,34 @@ SeqNext(SeqScan *node)
scanstate
=
node
->
scanstate
;
scanstate
=
node
->
scanstate
;
scandesc
=
scanstate
->
css_currentScanDesc
;
scandesc
=
scanstate
->
css_currentScanDesc
;
direction
=
estate
->
es_direction
;
direction
=
estate
->
es_direction
;
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
* SeqScan --> NewNode switching in Init/ReScan plan...
*/
if
(
estate
->
es_evTuple
!=
NULL
&&
estate
->
es_evTuple
[
node
->
scanrelid
-
1
]
!=
NULL
)
{
slot
->
ttc_buffer
=
InvalidBuffer
;
slot
->
ttc_shouldFree
=
false
;
if
(
estate
->
es_evTupleNull
[
node
->
scanrelid
-
1
])
{
slot
->
val
=
NULL
;
/* must not free tuple! */
return
(
slot
);
}
slot
->
val
=
estate
->
es_evTuple
[
node
->
scanrelid
-
1
];
/*
* Note that unlike IndexScan, SeqScan never use keys
* in heap_beginscan (and this is very bad) - so, here
* we have not check are keys ok or not.
*/
/* Flag for the next call that no more tuples */
estate
->
es_evTupleNull
[
node
->
scanrelid
-
1
]
=
true
;
return
(
slot
);
}
/* ----------------
/* ----------------
* get the next tuple from the access methods
* get the next tuple from the access methods
...
@@ -79,7 +107,6 @@ SeqNext(SeqScan *node)
...
@@ -79,7 +107,6 @@ SeqNext(SeqScan *node)
* be pfree()'d.
* be pfree()'d.
* ----------------
* ----------------
*/
*/
slot
=
scanstate
->
css_ScanTupleSlot
;
slot
=
ExecStoreTuple
(
tuple
,
/* tuple to store */
slot
=
ExecStoreTuple
(
tuple
,
/* tuple to store */
slot
,
/* slot to store in */
slot
,
/* slot to store in */
...
@@ -374,9 +401,15 @@ ExecSeqReScan(SeqScan *node, ExprContext *exprCtxt, Plan *parent)
...
@@ -374,9 +401,15 @@ ExecSeqReScan(SeqScan *node, ExprContext *exprCtxt, Plan *parent)
outerPlan
=
outerPlan
((
Plan
*
)
node
);
outerPlan
=
outerPlan
((
Plan
*
)
node
);
ExecReScan
(
outerPlan
,
exprCtxt
,
parent
);
ExecReScan
(
outerPlan
,
exprCtxt
,
parent
);
}
}
else
else
/* otherwise, we are scanning a relation */
{
{
/* otherwise, we are scanning a relation */
/* If this is re-scanning of PlanQual ... */
if
(
estate
->
es_evTuple
!=
NULL
&&
estate
->
es_evTuple
[
node
->
scanrelid
-
1
]
!=
NULL
)
{
estate
->
es_evTupleNull
[
node
->
scanrelid
-
1
]
=
false
;
return
;
}
rel
=
scanstate
->
css_currentRelation
;
rel
=
scanstate
->
css_currentRelation
;
scan
=
scanstate
->
css_currentScanDesc
;
scan
=
scanstate
->
css_currentScanDesc
;
direction
=
estate
->
es_direction
;
direction
=
estate
->
es_direction
;
...
...
src/backend/nodes/copyfuncs.c
View file @
e3a1ab76
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.5
5 1999/01/25 18:02:14 momjian
Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.5
6 1999/01/29 09:22:59 vadim
Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -83,7 +83,6 @@ CopyPlanFields(Plan *from, Plan *newnode)
...
@@ -83,7 +83,6 @@ CopyPlanFields(Plan *from, Plan *newnode)
newnode
->
plan_size
=
from
->
plan_size
;
newnode
->
plan_size
=
from
->
plan_size
;
newnode
->
plan_width
=
from
->
plan_width
;
newnode
->
plan_width
=
from
->
plan_width
;
newnode
->
plan_tupperpage
=
from
->
plan_tupperpage
;
newnode
->
plan_tupperpage
=
from
->
plan_tupperpage
;
newnode
->
state
=
from
->
state
;
newnode
->
targetlist
=
copyObject
(
from
->
targetlist
);
newnode
->
targetlist
=
copyObject
(
from
->
targetlist
);
newnode
->
qual
=
copyObject
(
from
->
qual
);
newnode
->
qual
=
copyObject
(
from
->
qual
);
newnode
->
lefttree
=
copyObject
(
from
->
lefttree
);
newnode
->
lefttree
=
copyObject
(
from
->
lefttree
);
...
@@ -138,7 +137,6 @@ _copyResult(Result *from)
...
@@ -138,7 +137,6 @@ _copyResult(Result *from)
* ----------------
* ----------------
*/
*/
Node_Copy
(
from
,
newnode
,
resconstantqual
);
Node_Copy
(
from
,
newnode
,
resconstantqual
);
Node_Copy
(
from
,
newnode
,
resstate
);
return
newnode
;
return
newnode
;
}
}
...
@@ -166,7 +164,6 @@ _copyAppend(Append *from)
...
@@ -166,7 +164,6 @@ _copyAppend(Append *from)
Node_Copy
(
from
,
newnode
,
unionrtables
);
Node_Copy
(
from
,
newnode
,
unionrtables
);
newnode
->
inheritrelid
=
from
->
inheritrelid
;
newnode
->
inheritrelid
=
from
->
inheritrelid
;
Node_Copy
(
from
,
newnode
,
inheritrtable
);
Node_Copy
(
from
,
newnode
,
inheritrtable
);
Node_Copy
(
from
,
newnode
,
appendstate
);
return
newnode
;
return
newnode
;
}
}
...
@@ -183,7 +180,6 @@ static void
...
@@ -183,7 +180,6 @@ static void
CopyScanFields
(
Scan
*
from
,
Scan
*
newnode
)
CopyScanFields
(
Scan
*
from
,
Scan
*
newnode
)
{
{
newnode
->
scanrelid
=
from
->
scanrelid
;
newnode
->
scanrelid
=
from
->
scanrelid
;
Node_Copy
(
from
,
newnode
,
scanstate
);
return
;
return
;
}
}
...
@@ -248,7 +244,6 @@ _copyIndexScan(IndexScan *from)
...
@@ -248,7 +244,6 @@ _copyIndexScan(IndexScan *from)
newnode
->
indxid
=
listCopy
(
from
->
indxid
);
newnode
->
indxid
=
listCopy
(
from
->
indxid
);
Node_Copy
(
from
,
newnode
,
indxqual
);
Node_Copy
(
from
,
newnode
,
indxqual
);
Node_Copy
(
from
,
newnode
,
indxqualorig
);
Node_Copy
(
from
,
newnode
,
indxqualorig
);
Node_Copy
(
from
,
newnode
,
indxstate
);
return
newnode
;
return
newnode
;
}
}
...
@@ -304,12 +299,6 @@ _copyNestLoop(NestLoop *from)
...
@@ -304,12 +299,6 @@ _copyNestLoop(NestLoop *from)
CopyPlanFields
((
Plan
*
)
from
,
(
Plan
*
)
newnode
);
CopyPlanFields
((
Plan
*
)
from
,
(
Plan
*
)
newnode
);
CopyJoinFields
((
Join
*
)
from
,
(
Join
*
)
newnode
);
CopyJoinFields
((
Join
*
)
from
,
(
Join
*
)
newnode
);
/* ----------------
* copy remainder of node
* ----------------
*/
Node_Copy
(
from
,
newnode
,
nlstate
);
return
newnode
;
return
newnode
;
}
}
...
@@ -346,8 +335,6 @@ _copyMergeJoin(MergeJoin *from)
...
@@ -346,8 +335,6 @@ _copyMergeJoin(MergeJoin *from)
newnode
->
mergeleftorder
[
0
]
=
from
->
mergeleftorder
[
0
];
newnode
->
mergeleftorder
[
0
]
=
from
->
mergeleftorder
[
0
];
newnode
->
mergeleftorder
[
1
]
=
0
;
newnode
->
mergeleftorder
[
1
]
=
0
;
Node_Copy
(
from
,
newnode
,
mergestate
);
return
newnode
;
return
newnode
;
}
}
...
@@ -375,12 +362,9 @@ _copyHashJoin(HashJoin *from)
...
@@ -375,12 +362,9 @@ _copyHashJoin(HashJoin *from)
newnode
->
hashjoinop
=
from
->
hashjoinop
;
newnode
->
hashjoinop
=
from
->
hashjoinop
;
Node_Copy
(
from
,
newnode
,
hashjoinstate
);
/* both are unused !.. */
newnode
->
hashjointable
=
from
->
hashjointable
;
newnode
->
hashjointablekey
=
from
->
hashjointablekey
;
newnode
->
hashjointablekey
=
from
->
hashjointablekey
;
newnode
->
hashjointablesize
=
from
->
hashjointablesize
;
newnode
->
hashjointablesize
=
from
->
hashjointablesize
;
newnode
->
hashdone
=
from
->
hashdone
;
return
newnode
;
return
newnode
;
}
}
...
@@ -437,12 +421,6 @@ _copyMaterial(Material *from)
...
@@ -437,12 +421,6 @@ _copyMaterial(Material *from)
CopyPlanFields
((
Plan
*
)
from
,
(
Plan
*
)
newnode
);
CopyPlanFields
((
Plan
*
)
from
,
(
Plan
*
)
newnode
);
CopyTempFields
((
Temp
*
)
from
,
(
Temp
*
)
newnode
);
CopyTempFields
((
Temp
*
)
from
,
(
Temp
*
)
newnode
);
/* ----------------
* copy remainder of node
* ----------------
*/
Node_Copy
(
from
,
newnode
,
matstate
);
return
newnode
;
return
newnode
;
}
}
...
@@ -463,14 +441,6 @@ _copySort(Sort *from)
...
@@ -463,14 +441,6 @@ _copySort(Sort *from)
CopyPlanFields
((
Plan
*
)
from
,
(
Plan
*
)
newnode
);
CopyPlanFields
((
Plan
*
)
from
,
(
Plan
*
)
newnode
);
CopyTempFields
((
Temp
*
)
from
,
(
Temp
*
)
newnode
);
CopyTempFields
((
Temp
*
)
from
,
(
Temp
*
)
newnode
);
/* ----------------
* copy remainder of node
* ----------------
*/
Node_Copy
(
from
,
newnode
,
sortstate
);
Node_Copy
(
from
,
newnode
,
psortstate
);
newnode
->
cleaned
=
from
->
cleaned
;
return
newnode
;
return
newnode
;
}
}
...
@@ -490,7 +460,6 @@ _copyGroup(Group *from)
...
@@ -490,7 +460,6 @@ _copyGroup(Group *from)
newnode
->
numCols
=
from
->
numCols
;
newnode
->
numCols
=
from
->
numCols
;
newnode
->
grpColIdx
=
palloc
(
from
->
numCols
*
sizeof
(
AttrNumber
));
newnode
->
grpColIdx
=
palloc
(
from
->
numCols
*
sizeof
(
AttrNumber
));
memcpy
(
newnode
->
grpColIdx
,
from
->
grpColIdx
,
from
->
numCols
*
sizeof
(
AttrNumber
));
memcpy
(
newnode
->
grpColIdx
,
from
->
grpColIdx
,
from
->
numCols
*
sizeof
(
AttrNumber
));
Node_Copy
(
from
,
newnode
,
grpstate
);
return
newnode
;
return
newnode
;
}
}
...
@@ -507,7 +476,6 @@ _copyAgg(Agg *from)
...
@@ -507,7 +476,6 @@ _copyAgg(Agg *from)
CopyPlanFields
((
Plan
*
)
from
,
(
Plan
*
)
newnode
);
CopyPlanFields
((
Plan
*
)
from
,
(
Plan
*
)
newnode
);
newnode
->
aggs
=
get_agg_tlist_references
(
newnode
);
newnode
->
aggs
=
get_agg_tlist_references
(
newnode
);
Node_Copy
(
from
,
newnode
,
aggstate
);
return
newnode
;
return
newnode
;
}
}
...
@@ -553,7 +521,6 @@ _copyUnique(Unique *from)
...
@@ -553,7 +521,6 @@ _copyUnique(Unique *from)
else
else
newnode
->
uniqueAttr
=
NULL
;
newnode
->
uniqueAttr
=
NULL
;
newnode
->
uniqueAttrNum
=
from
->
uniqueAttrNum
;
newnode
->
uniqueAttrNum
=
from
->
uniqueAttrNum
;
Node_Copy
(
from
,
newnode
,
uniquestate
);
return
newnode
;
return
newnode
;
}
}
...
@@ -579,9 +546,8 @@ _copyHash(Hash *from)
...
@@ -579,9 +546,8 @@ _copyHash(Hash *from)
* ----------------
* ----------------
*/
*/
Node_Copy
(
from
,
newnode
,
hashkey
);
Node_Copy
(
from
,
newnode
,
hashkey
);
Node_Copy
(
from
,
newnode
,
hashstate
);
newnode
->
hashtable
=
from
->
hashtable
;
/* both are unused !.. */
newnode
->
hashtablekey
=
from
->
hashtablekey
;
newnode
->
hashtablekey
=
from
->
hashtablekey
;
newnode
->
hashtablesize
=
from
->
hashtablesize
;
newnode
->
hashtablesize
=
from
->
hashtablesize
;
...
@@ -599,7 +565,6 @@ _copySubPlan(SubPlan *from)
...
@@ -599,7 +565,6 @@ _copySubPlan(SubPlan *from)
newnode
->
setParam
=
listCopy
(
from
->
setParam
);
newnode
->
setParam
=
listCopy
(
from
->
setParam
);
newnode
->
parParam
=
listCopy
(
from
->
parParam
);
newnode
->
parParam
=
listCopy
(
from
->
parParam
);
Node_Copy
(
from
,
newnode
,
sublink
);
Node_Copy
(
from
,
newnode
,
sublink
);
newnode
->
shutdown
=
from
->
shutdown
;
return
newnode
;
return
newnode
;
}
}
...
@@ -1901,7 +1866,7 @@ copyObject(void *from)
...
@@ -1901,7 +1866,7 @@ copyObject(void *from)
}
}
break
;
break
;
default:
default:
elog
(
NOTICE
,
"copyObject: don't know how to copy %d"
,
nodeTag
(
from
));
elog
(
ERROR
,
"copyObject: don't know how to copy %d"
,
nodeTag
(
from
));
retval
=
from
;
retval
=
from
;
break
;
break
;
}
}
...
...
src/backend/parser/gram.c
View file @
e3a1ab76
...
@@ -239,7 +239,7 @@
...
@@ -239,7 +239,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/Attic/gram.c,v 2.6
4 1999/01/26 23:32:04 momjian
Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/Attic/gram.c,v 2.6
5 1999/01/29 09:23:02 vadim
Exp $
*
*
* HISTORY
* HISTORY
* AUTHOR DATE MAJOR EVENT
* AUTHOR DATE MAJOR EVENT
...
@@ -4791,7 +4791,7 @@ static const short yycheck[] = { 3,
...
@@ -4791,7 +4791,7 @@ static const short yycheck[] = { 3,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
214
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
214
};
};
/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
#line 3 "/usr/
local/bison
/bison.simple"
#line 3 "/usr/
share/misc
/bison.simple"
/* Skeleton output parser for bison,
/* Skeleton output parser for bison,
Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
...
@@ -4984,7 +4984,7 @@ __yy_memcpy (char *to, char *from, int count)
...
@@ -4984,7 +4984,7 @@ __yy_memcpy (char *to, char *from, int count)
#endif
#endif
#endif
#endif
#line 196 "/usr/
local/bison
/bison.simple"
#line 196 "/usr/
share/misc
/bison.simple"
/* The user can define YYPARSE_PARAM as the name of an argument to be passed
/* The user can define YYPARSE_PARAM as the name of an argument to be passed
into yyparse. The argument should have type void *.
into yyparse. The argument should have type void *.
...
@@ -11088,7 +11088,7 @@ case 960:
...
@@ -11088,7 +11088,7 @@ case 960:
break
;}
break
;}
}
}
/* the action file gets copied in in place of this dollarsign */
/* the action file gets copied in in place of this dollarsign */
#line 498 "/usr/
local/bison
/bison.simple"
#line 498 "/usr/
share/misc
/bison.simple"
yyvsp
-=
yylen
;
yyvsp
-=
yylen
;
yyssp
-=
yylen
;
yyssp
-=
yylen
;
...
...
src/backend/utils/time/tqual.c
View file @
e3a1ab76
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/time/tqual.c,v 1.2
3 1998/12/18 09:10:39
vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/time/tqual.c,v 1.2
4 1999/01/29 09:23:12
vadim Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -368,6 +368,7 @@ bool
...
@@ -368,6 +368,7 @@ bool
HeapTupleSatisfiesDirty
(
HeapTupleHeader
tuple
)
HeapTupleSatisfiesDirty
(
HeapTupleHeader
tuple
)
{
{
SnapshotDirty
->
xmin
=
SnapshotDirty
->
xmax
=
InvalidTransactionId
;
SnapshotDirty
->
xmin
=
SnapshotDirty
->
xmax
=
InvalidTransactionId
;
ItemPointerSetInvalid
(
&
(
SnapshotDirty
->
tid
));
if
(
AMI_OVERRIDE
)
if
(
AMI_OVERRIDE
)
return
true
;
return
true
;
...
@@ -413,6 +414,7 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple)
...
@@ -413,6 +414,7 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple)
{
{
if
(
tuple
->
t_infomask
&
HEAP_MARKED_FOR_UPDATE
)
if
(
tuple
->
t_infomask
&
HEAP_MARKED_FOR_UPDATE
)
return
true
;
return
true
;
SnapshotDirty
->
tid
=
tuple
->
t_ctid
;
return
false
;
/* updated by other */
return
false
;
/* updated by other */
}
}
...
@@ -437,6 +439,7 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple)
...
@@ -437,6 +439,7 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple)
if
(
tuple
->
t_infomask
&
HEAP_MARKED_FOR_UPDATE
)
if
(
tuple
->
t_infomask
&
HEAP_MARKED_FOR_UPDATE
)
return
true
;
return
true
;
SnapshotDirty
->
tid
=
tuple
->
t_ctid
;
return
false
;
/* updated by other */
return
false
;
/* updated by other */
}
}
...
...
src/include/nodes/execnodes.h
View file @
e3a1ab76
...
@@ -6,7 +6,7 @@
...
@@ -6,7 +6,7 @@
*
*
* Copyright (c) 1994, Regents of the University of California
* Copyright (c) 1994, Regents of the University of California
*
*
* $Id: execnodes.h,v 1.2
1 1999/01/25 12:01:19
vadim Exp $
* $Id: execnodes.h,v 1.2
2 1999/01/29 09:23:13
vadim Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -209,6 +209,12 @@ typedef struct EState
...
@@ -209,6 +209,12 @@ typedef struct EState
uint32
es_processed
;
/* # of tuples processed */
uint32
es_processed
;
/* # of tuples processed */
Oid
es_lastoid
;
/* last oid processed (by INSERT) */
Oid
es_lastoid
;
/* last oid processed (by INSERT) */
List
*
es_rowMark
;
/* not good place, but there is no other */
List
*
es_rowMark
;
/* not good place, but there is no other */
/* Below is to re-evaluate plan qual in READ COMMITTED mode */
struct
Plan
*
es_origPlan
;
Pointer
es_evalPlanQual
;
bool
*
es_evTupleNull
;
HeapTuple
*
es_evTuple
;
bool
es_useEvalPlan
;
}
EState
;
}
EState
;
/* ----------------
/* ----------------
...
...
src/include/utils/tqual.h
View file @
e3a1ab76
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
*
*
* Copyright (c) 1994, Regents of the University of California
* Copyright (c) 1994, Regents of the University of California
*
*
* $Id: tqual.h,v 1.1
8 1998/12/18 09:09:55
vadim Exp $
* $Id: tqual.h,v 1.1
9 1999/01/29 09:23:17
vadim Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -22,6 +22,7 @@ typedef struct SnapshotData
...
@@ -22,6 +22,7 @@ typedef struct SnapshotData
TransactionId
xmax
;
/* XID >= xmax are invisible to me */
TransactionId
xmax
;
/* XID >= xmax are invisible to me */
uint32
xcnt
;
/* # of xact below */
uint32
xcnt
;
/* # of xact below */
TransactionId
*
xip
;
/* array of xacts in progress */
TransactionId
*
xip
;
/* array of xacts in progress */
ItemPointerData
tid
;
/* required for Dirty snapshot -:( */
}
SnapshotData
;
}
SnapshotData
;
typedef
SnapshotData
*
Snapshot
;
typedef
SnapshotData
*
Snapshot
;
...
...
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