Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit88c5566

Browse files
committed
Fix crash in error report of invalid tuple lock
My tweak of these error messages in commitc359a1b contained thethinko that a query would always have rowMarks set for a querycontaining a locking clause. Not so: when declaring a cursor, forinstance, rowMarks isn't set at the point we're checking, so we'd bedereferencing a NULL pointer.The fix is to pass the lock strength to the function raising the error,instead of trying to reverse-engineer it. The result not only is morerobust, but it also seems cleaner overall.Per report from Robert Haas.
1 parent05ee328 commit88c5566

File tree

9 files changed

+29
-18
lines changed

9 files changed

+29
-18
lines changed

‎src/backend/optimizer/plan/planner.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1962,7 +1962,8 @@ preprocess_rowmarks(PlannerInfo *root)
19621962
* CTIDs invalid. This is also checked at parse time, but that's
19631963
* insufficient because of rule substitution, query pullup, etc.
19641964
*/
1965-
CheckSelectLocking(parse);
1965+
CheckSelectLocking(parse, ((RowMarkClause*)
1966+
linitial(parse->rowMarks))->strength);
19661967
}
19671968
else
19681969
{

‎src/backend/parser/analyze.c

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2243,64 +2243,57 @@ LCS_asString(LockClauseStrength strength)
22432243
* exported so planner can check again after rewriting, query pullup, etc
22442244
*/
22452245
void
2246-
CheckSelectLocking(Query*qry)
2246+
CheckSelectLocking(Query*qry,LockClauseStrengthstrength)
22472247
{
22482248
if (qry->setOperations)
22492249
ereport(ERROR,
22502250
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
22512251
/*------
22522252
translator: %s is a SQL row locking clause such as FOR UPDATE */
22532253
errmsg("%s is not allowed with UNION/INTERSECT/EXCEPT",
2254-
LCS_asString(((RowMarkClause*)
2255-
linitial(qry->rowMarks))->strength))));
2254+
LCS_asString(strength))));
22562255
if (qry->distinctClause!=NIL)
22572256
ereport(ERROR,
22582257
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
22592258
/*------
22602259
translator: %s is a SQL row locking clause such as FOR UPDATE */
22612260
errmsg("%s is not allowed with DISTINCT clause",
2262-
LCS_asString(((RowMarkClause*)
2263-
linitial(qry->rowMarks))->strength))));
2261+
LCS_asString(strength))));
22642262
if (qry->groupClause!=NIL)
22652263
ereport(ERROR,
22662264
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
22672265
/*------
22682266
translator: %s is a SQL row locking clause such as FOR UPDATE */
22692267
errmsg("%s is not allowed with GROUP BY clause",
2270-
LCS_asString(((RowMarkClause*)
2271-
linitial(qry->rowMarks))->strength))));
2268+
LCS_asString(strength))));
22722269
if (qry->havingQual!=NULL)
22732270
ereport(ERROR,
22742271
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
22752272
/*------
22762273
translator: %s is a SQL row locking clause such as FOR UPDATE */
22772274
errmsg("%s is not allowed with HAVING clause",
2278-
LCS_asString(((RowMarkClause*)
2279-
linitial(qry->rowMarks))->strength))));
2275+
LCS_asString(strength))));
22802276
if (qry->hasAggs)
22812277
ereport(ERROR,
22822278
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
22832279
/*------
22842280
translator: %s is a SQL row locking clause such as FOR UPDATE */
22852281
errmsg("%s is not allowed with aggregate functions",
2286-
LCS_asString(((RowMarkClause*)
2287-
linitial(qry->rowMarks))->strength))));
2282+
LCS_asString(strength))));
22882283
if (qry->hasWindowFuncs)
22892284
ereport(ERROR,
22902285
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
22912286
/*------
22922287
translator: %s is a SQL row locking clause such as FOR UPDATE */
22932288
errmsg("%s is not allowed with window functions",
2294-
LCS_asString(((RowMarkClause*)
2295-
linitial(qry->rowMarks))->strength))));
2289+
LCS_asString(strength))));
22962290
if (expression_returns_set((Node*)qry->targetList))
22972291
ereport(ERROR,
22982292
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
22992293
/*------
23002294
translator: %s is a SQL row locking clause such as FOR UPDATE */
23012295
errmsg("%s is not allowed with set-returning functions in the target list",
2302-
LCS_asString(((RowMarkClause*)
2303-
linitial(qry->rowMarks))->strength))));
2296+
LCS_asString(strength))));
23042297
}
23052298

23062299
/*
@@ -2321,7 +2314,7 @@ transformLockingClause(ParseState *pstate, Query *qry, LockingClause *lc,
23212314
Indexi;
23222315
LockingClause*allrels;
23232316

2324-
CheckSelectLocking(qry);
2317+
CheckSelectLocking(qry,lc->strength);
23252318

23262319
/* make a clause we can pass down to subqueries to select all rels */
23272320
allrels=makeNode(LockingClause);

‎src/include/parser/analyze.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ extern Query *transformStmt(ParseState *pstate, Node *parseTree);
3737
externboolanalyze_requires_snapshot(Node*parseTree);
3838

3939
externchar*LCS_asString(LockClauseStrengthstrength);
40-
externvoidCheckSelectLocking(Query*qry);
40+
externvoidCheckSelectLocking(Query*qry,LockClauseStrengthstrength);
4141
externvoidapplyLockingClause(Query*qry,Indexrtindex,
4242
LockClauseStrengthstrength,boolnoWait,boolpushedDown);
4343

‎src/test/regress/expected/matview.out

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,9 @@ NOTICE: materialized view "no_such_mv" does not exist, skipping
292292
-- make sure invalid comination of options is prohibited
293293
REFRESH MATERIALIZED VIEW CONCURRENTLY tvmm WITH NO DATA;
294294
ERROR: CONCURRENTLY and WITH NO DATA options cannot be used together
295+
-- no tuple locks on materialized views
296+
SELECT * FROM tvvm FOR SHARE;
297+
ERROR: cannot lock rows in materialized view "tvvm"
295298
-- test join of mv and view
296299
SELECT type, m.totamt AS mtot, v.totamt AS vtot FROM tm m LEFT JOIN tv v USING (type) ORDER BY type;
297300
type | mtot | vtot

‎src/test/regress/expected/portals.out

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,6 +1226,10 @@ DECLARE c1 CURSOR FOR SELECT * FROM uctest;
12261226
DELETE FROM uctest WHERE CURRENT OF c1; -- fail, no current row
12271227
ERROR: cursor "c1" is not positioned on a row
12281228
ROLLBACK;
1229+
BEGIN;
1230+
DECLARE c1 CURSOR FOR SELECT MIN(f1) FROM uctest FOR UPDATE;
1231+
ERROR: FOR UPDATE is not allowed with aggregate functions
1232+
ROLLBACK;
12291233
-- WHERE CURRENT OF may someday work with views, but today is not that day.
12301234
-- For now, just make sure it errors out cleanly.
12311235
CREATE TEMP VIEW ucview AS SELECT * FROM uctest;

‎src/test/regress/expected/union.out

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,8 @@ SELECT q1 FROM int8_tbl EXCEPT ALL SELECT DISTINCT q2 FROM int8_tbl;
317317
123
318318
(3 rows)
319319

320+
SELECT q1 FROM int8_tbl EXCEPT ALL SELECT q1 FROM int8_tbl FOR NO KEY UPDATE;
321+
ERROR: FOR NO KEY UPDATE is not allowed with UNION/INTERSECT/EXCEPT
320322
--
321323
-- Mixed types
322324
--

‎src/test/regress/sql/matview.sql

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,9 @@ DROP MATERIALIZED VIEW IF EXISTS no_such_mv;
9595
-- make sure invalid comination of options is prohibited
9696
REFRESH MATERIALIZED VIEW CONCURRENTLY tvmm WITH NO DATA;
9797

98+
-- no tuple locks on materialized views
99+
SELECT*FROM tvvm FOR SHARE;
100+
98101
-- test join of mv and view
99102
SELECT type,m.totamtAS mtot,v.totamtAS vtotFROM tm mLEFT JOIN tv v USING (type)ORDER BY type;
100103

‎src/test/regress/sql/portals.sql

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,9 @@ BEGIN;
447447
DECLARE c1 CURSOR FORSELECT*FROM uctest;
448448
DELETEFROM uctestWHERE CURRENT OF c1;-- fail, no current row
449449
ROLLBACK;
450+
BEGIN;
451+
DECLARE c1 CURSOR FORSELECTMIN(f1)FROM uctest FORUPDATE;
452+
ROLLBACK;
450453

451454
-- WHERE CURRENT OF may someday work with views, but today is not that day.
452455
-- For now, just make sure it errors out cleanly.

‎src/test/regress/sql/union.sql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ SELECT q1 FROM int8_tbl EXCEPT ALL SELECT q2 FROM int8_tbl;
109109

110110
SELECT q1FROM int8_tbl EXCEPT ALLSELECT DISTINCT q2FROM int8_tbl;
111111

112+
SELECT q1FROM int8_tbl EXCEPT ALLSELECT q1FROM int8_tbl FOR NO KEYUPDATE;
113+
112114
--
113115
-- Mixed types
114116
--

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp