Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Greenplum
Gpdb
提交
247b3f90
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,发现更多精彩内容 >>
提交
247b3f90
编写于
1月 25, 1999
作者:
V
Vadim B. Mikheev
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
SELECT FOR UPDATE is implemented...
上级
443e24be
变更
7
展开全部
隐藏空白更改
内联
并排
Showing
7 changed file
with
715 addition
and
581 deletion
+715
-581
src/backend/executor/execMain.c
src/backend/executor/execMain.c
+105
-4
src/backend/optimizer/plan/planner.c
src/backend/optimizer/plan/planner.c
+43
-7
src/backend/parser/analyze.c
src/backend/parser/analyze.c
+18
-2
src/backend/parser/gram.c
src/backend/parser/gram.c
+541
-552
src/backend/parser/gram.y
src/backend/parser/gram.y
+3
-14
src/backend/rewrite/rewriteHandler.c
src/backend/rewrite/rewriteHandler.c
+3
-1
src/include/nodes/execnodes.h
src/include/nodes/execnodes.h
+2
-1
未找到文件。
src/backend/executor/execMain.c
浏览文件 @
247b3f90
...
...
@@ -26,7 +26,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.6
2 1998/12/18 09:10:21
vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.6
3 1999/01/25 12:01:03
vadim Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -363,6 +363,32 @@ ExecCheckPerms(CmdType operation,
}
if
(
!
ok
)
elog
(
ERROR
,
"%s: %s"
,
rname
.
data
,
aclcheck_error_strings
[
aclcheck_result
]);
if
(
parseTree
->
rowMark
!=
NULL
)
{
foreach
(
lp
,
parseTree
->
rowMark
)
{
RowMark
*
rm
=
lfirst
(
lp
);
if
(
!
(
rm
->
info
&
ROW_ACL_FOR_UPDATE
))
continue
;
relid
=
((
RangeTblEntry
*
)
nth
(
rm
->
rti
-
1
,
rangeTable
))
->
relid
;
htup
=
SearchSysCacheTuple
(
RELOID
,
ObjectIdGetDatum
(
relid
),
0
,
0
,
0
);
if
(
!
HeapTupleIsValid
(
htup
))
elog
(
ERROR
,
"ExecCheckPerms: bogus RT relid: %d"
,
relid
);
StrNCpy
(
rname
.
data
,
((
Form_pg_class
)
GETSTRUCT
(
htup
))
->
relname
.
data
,
NAMEDATALEN
);
ok
=
((
aclcheck_result
=
CHECK
(
ACL_WR
))
==
ACLCHECK_OK
);
opstr
=
"write"
;
if
(
!
ok
)
elog
(
ERROR
,
"%s: %s"
,
rname
.
data
,
aclcheck_error_strings
[
aclcheck_result
]);
}
}
}
/* ===============================================================
...
...
@@ -372,6 +398,11 @@ ExecCheckPerms(CmdType operation,
* ===============================================================
*/
typedef
struct
execRowMark
{
Relation
relation
;
char
resname
[
32
];
}
execRowMark
;
/* ----------------------------------------------------------------
* InitPlan
...
...
@@ -398,6 +429,10 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
rangeTable
=
parseTree
->
rtable
;
resultRelation
=
parseTree
->
resultRelation
;
#ifndef NO_SECURITY
ExecCheckPerms
(
operation
,
resultRelation
,
rangeTable
,
parseTree
);
#endif
/******************
* initialize the node's execution state
******************
...
...
@@ -468,9 +503,32 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
estate
->
es_result_relation_info
=
NULL
;
}
#ifndef NO_SECURITY
ExecCheckPerms
(
operation
,
resultRelation
,
rangeTable
,
parseTree
);
#endif
/*
* Have to lock relations selected for update
*/
estate
->
es_rowMark
=
NULL
;
if
(
parseTree
->
rowMark
!=
NULL
)
{
Relation
relation
;
Oid
relid
;
RowMark
*
rm
;
List
*
l
;
execRowMark
*
erm
;
foreach
(
l
,
parseTree
->
rowMark
)
{
rm
=
lfirst
(
l
);
relid
=
((
RangeTblEntry
*
)
nth
(
rm
->
rti
-
1
,
rangeTable
))
->
relid
;
relation
=
heap_open
(
relid
);
LockRelation
(
relation
,
RowShareLock
);
if
(
!
(
rm
->
info
&
ROW_MARK_FOR_UPDATE
))
continue
;
erm
=
(
execRowMark
*
)
palloc
(
sizeof
(
execRowMark
));
erm
->
relation
=
relation
;
sprintf
(
erm
->
resname
,
"ctid%u"
,
rm
->
rti
);
estate
->
es_rowMark
=
lappend
(
estate
->
es_rowMark
,
erm
);
}
}
/******************
* initialize the executor "tuple" table.
...
...
@@ -777,6 +835,49 @@ ExecutePlan(EState *estate,
* ctid!! */
tupleid
=
&
tuple_ctid
;
}
else
if
(
estate
->
es_rowMark
!=
NULL
)
{
List
*
l
;
execRowMark
*
erm
;
Buffer
buffer
;
HeapTupleData
tuple
;
int
test
;
foreach
(
l
,
estate
->
es_rowMark
)
{
erm
=
lfirst
(
l
);
if
(
!
ExecGetJunkAttribute
(
junkfilter
,
slot
,
erm
->
resname
,
&
datum
,
&
isNull
))
elog
(
ERROR
,
"ExecutePlan: NO (junk) `%s' was found!"
,
erm
->
resname
);
if
(
isNull
)
elog
(
ERROR
,
"ExecutePlan: (junk) `%s' is NULL!"
,
erm
->
resname
);
tuple
.
t_self
=
*
((
ItemPointer
)
DatumGetPointer
(
datum
));
test
=
heap_mark4update
(
erm
->
relation
,
&
tuple
,
&
buffer
);
ReleaseBuffer
(
buffer
);
switch
(
test
)
{
case
HeapTupleSelfUpdated
:
case
HeapTupleMayBeUpdated
:
break
;
case
HeapTupleUpdated
:
if
(
XactIsoLevel
==
XACT_SERIALIZABLE
)
elog
(
ERROR
,
"Can't serialize access due to concurrent update"
);
else
elog
(
ERROR
,
"Isolation level %u is not supported"
,
XactIsoLevel
);
return
(
NULL
);
default:
elog
(
ERROR
,
"Unknown status %u from heap_mark4update"
,
test
);
return
(
NULL
);
}
}
}
/******************
* Finally create a new "clean" tuple with all junk attributes
...
...
src/backend/optimizer/plan/planner.c
浏览文件 @
247b3f90
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.3
6 1999/01/18 00:09:47 momjian
Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.3
7 1999/01/25 12:01:04 vadim
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -20,6 +20,8 @@
#include "nodes/plannodes.h"
#include "nodes/parsenodes.h"
#include "nodes/relation.h"
#include "nodes/makefuncs.h"
#include "catalog/pg_type.h"
#include "parser/parse_expr.h"
#include "utils/elog.h"
...
...
@@ -119,6 +121,8 @@ union_planner(Query *parse)
else
if
((
rt_index
=
first_inherit_rt_entry
(
rangetable
))
!=
-
1
)
{
if
(
parse
->
rowMark
!=
NULL
)
elog
(
ERROR
,
"SELECT FOR UPDATE is not supported for inherit queries"
);
result_plan
=
(
Plan
*
)
plan_inherit_queries
(
parse
,
rt_index
);
/* XXX do we need to do this? bjm 12/19/97 */
tlist
=
preprocess_targetlist
(
tlist
,
...
...
@@ -148,17 +152,49 @@ union_planner(Query *parse)
* a new entry and attaches it to the list 'new_tlist' (consisting of the
* VAR node and the RESDOM node as usual with tlists :-) ) */
if
(
parse
->
hasAggs
)
{
{
if
(
parse
->
havingQual
!=
NULL
)
{
new_tlist
=
check_having_qual_for_vars
(
parse
->
havingQual
,
new_tlist
);
}
}
{
new_tlist
=
check_having_qual_for_vars
(
parse
->
havingQual
,
new_tlist
);
}
}
new_tlist
=
preprocess_targetlist
(
new_tlist
,
parse
->
commandType
,
parse
->
resultRelation
,
parse
->
rtable
);
/* FOR UPDATE ... */
if
(
parse
->
rowMark
!=
NULL
)
{
List
*
l
;
TargetEntry
*
ctid
;
Resdom
*
resdom
;
Var
*
var
;
char
*
resname
;
foreach
(
l
,
parse
->
rowMark
)
{
if
(
!
(((
RowMark
*
)
lfirst
(
l
))
->
info
&
ROW_MARK_FOR_UPDATE
))
continue
;
resname
=
(
char
*
)
palloc
(
32
);
sprintf
(
resname
,
"ctid%u"
,
((
RowMark
*
)
lfirst
(
l
))
->
rti
);
resdom
=
makeResdom
(
length
(
new_tlist
)
+
1
,
TIDOID
,
-
1
,
resname
,
0
,
0
,
1
);
var
=
makeVar
(((
RowMark
*
)
lfirst
(
l
))
->
rti
,
-
1
,
TIDOID
,
-
1
,
0
,
((
RowMark
*
)
lfirst
(
l
))
->
rti
,
-
1
);
ctid
=
makeTargetEntry
(
resdom
,
(
Node
*
)
var
);
new_tlist
=
lappend
(
new_tlist
,
ctid
);
}
}
/* Here starts the original (pre having) code */
tlist
=
preprocess_targetlist
(
tlist
,
...
...
@@ -290,7 +326,7 @@ union_planner(Query *parse)
pfree
(
vpm
);
}
}
/*
* For now, before we hand back the plan, check to see if there is a
* user-specified sort that needs to be done. Eventually, this will
...
...
src/backend/parser/analyze.c
浏览文件 @
247b3f90
...
...
@@ -5,7 +5,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: analyze.c,v 1.9
4 1999/01/21 22:48:07 momjian
Exp $
* $Id: analyze.c,v 1.9
5 1999/01/25 12:01:05 vadim
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -45,7 +45,8 @@ static Query *transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt);
static
Query
*
transformCursorStmt
(
ParseState
*
pstate
,
SelectStmt
*
stmt
);
static
Query
*
transformCreateStmt
(
ParseState
*
pstate
,
CreateStmt
*
stmt
);
static
void
transformForUpdate
(
Query
*
qry
,
List
*
forUpdate
);
static
void
transformForUpdate
(
Query
*
qry
,
List
*
forUpdate
);
void
CheckSelectForUpdate
(
Query
*
qry
);
List
*
extras_before
=
NIL
;
List
*
extras_after
=
NIL
;
...
...
@@ -1134,6 +1135,19 @@ Node *A_Expr_to_Expr(Node *ptr, bool *intersect_present)
return
result
;
}
void
CheckSelectForUpdate
(
Query
*
qry
)
{
if
(
qry
->
unionClause
!=
NULL
)
elog
(
ERROR
,
"SELECT FOR UPDATE is not allowed with UNION/INTERSECT/EXCEPT clause"
);
if
(
qry
->
uniqueFlag
!=
NULL
)
elog
(
ERROR
,
"SELECT FOR UPDATE is not allowed with DISTINCT clause"
);
if
(
qry
->
groupClause
!=
NULL
)
elog
(
ERROR
,
"SELECT FOR UPDATE is not allowed with GROUP BY clause"
);
if
(
qry
->
hasAggs
)
elog
(
ERROR
,
"SELECT FOR UPDATE is not allowed with AGGREGATE"
);
}
static
void
transformForUpdate
(
Query
*
qry
,
List
*
forUpdate
)
{
...
...
@@ -1142,6 +1156,8 @@ transformForUpdate(Query *qry, List *forUpdate)
List
*
l
;
Index
i
;
CheckSelectForUpdate
(
qry
);
if
(
lfirst
(
forUpdate
)
==
NULL
)
/* all tables */
{
i
=
1
;
...
...
src/backend/parser/gram.c
浏览文件 @
247b3f90
此差异已折叠。
点击以展开。
src/backend/parser/gram.y
浏览文件 @
247b3f90
...
...
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.4
8 1999/01/22 19:35:54 momjian
Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.4
9 1999/01/25 12:01:13 vadim
Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
...
...
@@ -2798,19 +2798,8 @@ SelectStmt: select_w_o_sort sort_clause for_update_clause
first_select->forUpdate = $3;
$$ = (Node *)first_select;
}
if (((SelectStmt *)$$)->forUpdate != NULL)
{
SelectStmt *n = (SelectStmt *)$$;
if (n->unionClause != NULL)
elog(ERROR, "SELECT FOR UPDATE is not allowed with UNION/INTERSECT/EXCEPT clause");
if (n->unique != NULL)
elog(ERROR, "SELECT FOR UPDATE is not allowed with DISTINCT clause");
if (n->groupClause != NULL)
elog(ERROR, "SELECT FOR UPDATE is not allowed with GROUP BY clause");
if (n->havingClause != NULL)
elog(ERROR, "SELECT FOR UPDATE is not allowed with HAVING clause");
}
if (((SelectStmt *)$$)->forUpdate != NULL && QueryIsRule)
elog(ERROR, "SELECT FOR UPDATE is not allowed in RULES");
}
;
...
...
src/backend/rewrite/rewriteHandler.c
浏览文件 @
247b3f90
...
...
@@ -6,7 +6,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.3
0 1999/01/24 00:28:30 momjian
Exp $
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.3
1 1999/01/25 12:01:14 vadim
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -1787,6 +1787,7 @@ apply_RIR_view(Node **nodePtr, int rt_index, RangeTblEntry *rte, List *tlist, in
}
}
extern
void
CheckSelectForUpdate
(
Query
*
rule_action
);
/* in analyze.c */
static
void
ApplyRetrieveRule
(
Query
*
parsetree
,
...
...
@@ -1847,6 +1848,7 @@ ApplyRetrieveRule(Query *parsetree,
Index
rti
=
1
;
List
*
l2
;
CheckSelectForUpdate
(
rule_action
);
/*
* We believe that rt_index is VIEW - nothing should be
* marked for VIEW, but ACL check must be done.
...
...
src/include/nodes/execnodes.h
浏览文件 @
247b3f90
...
...
@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: execnodes.h,v 1.2
0 1998/12/14 05:19:16 scrappy
Exp $
* $Id: execnodes.h,v 1.2
1 1999/01/25 12:01:19 vadim
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -208,6 +208,7 @@ typedef struct EState
int
*
es_refcount
;
uint32
es_processed
;
/* # of tuples processed */
Oid
es_lastoid
;
/* last oid processed (by INSERT) */
List
*
es_rowMark
;
/* not good place, but there is no other */
}
EState
;
/* ----------------
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录