Skip to content

Commit c359a1b

Browse files
committed
Tweak FOR UPDATE/SHARE error message wording (again)
In commit 0ac5ad5 I changed some error messages from "FOR UPDATE/SHARE" to a rather long gobbledygook which nobody liked. Then, in commit cb9b66d I changed them again, but the alternative chosen there was deemed suboptimal by Peter Eisentraut, who in message 1373937980.20441.8.camel@vanquo.pezone.net proposed an alternative involving a dynamically-constructed string based on the actual locking strength specified in the SQL command. This patch implements that suggestion.
1 parent 765ad89 commit c359a1b

File tree

4 files changed

+118
-22
lines changed

4 files changed

+118
-22
lines changed

src/backend/optimizer/plan/initsplan.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "optimizer/prep.h"
2727
#include "optimizer/restrictinfo.h"
2828
#include "optimizer/var.h"
29+
#include "parser/analyze.h"
2930
#include "rewrite/rewriteManip.h"
3031
#include "utils/lsyscache.h"
3132

@@ -883,7 +884,10 @@ make_outerjoininfo(PlannerInfo *root,
883884
(jointype == JOIN_FULL && bms_is_member(rc->rti, left_rels)))
884885
ereport(ERROR,
885886
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
886-
errmsg("row-level locks cannot be applied to the nullable side of an outer join")));
887+
/*------
888+
translator: %s is a SQL row locking clause such as FOR UPDATE */
889+
errmsg("%s cannot be applied to the nullable side of an outer join",
890+
LCS_asString(rc->strength))));
887891
}
888892

889893
sjinfo->syn_lefthand = left_rels;

src/backend/optimizer/plan/planner.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1107,7 +1107,11 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
11071107
if (parse->rowMarks)
11081108
ereport(ERROR,
11091109
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1110-
errmsg("row-level locks are not allowed with UNION/INTERSECT/EXCEPT")));
1110+
/*------
1111+
translator: %s is a SQL row locking clause such as FOR UPDATE */
1112+
errmsg("%s is not allowed with UNION/INTERSECT/EXCEPT",
1113+
LCS_asString(((RowMarkClause *)
1114+
linitial(parse->rowMarks))->strength))));
11111115

11121116
/*
11131117
* Calculate pathkeys that represent result ordering requirements

src/backend/parser/analyze.c

Lines changed: 107 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1221,7 +1221,11 @@ transformValuesClause(ParseState *pstate, SelectStmt *stmt)
12211221
if (stmt->lockingClause)
12221222
ereport(ERROR,
12231223
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1224-
errmsg("SELECT FOR UPDATE/SHARE cannot be applied to VALUES")));
1224+
/*------
1225+
translator: %s is a SQL row locking clause such as FOR UPDATE */
1226+
errmsg("%s cannot be applied to VALUES",
1227+
LCS_asString(((LockingClause *)
1228+
linitial(stmt->lockingClause))->strength))));
12251229

12261230
qry->rtable = pstate->p_rtable;
12271231
qry->jointree = makeFromExpr(pstate->p_joinlist, NULL);
@@ -1312,7 +1316,11 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
13121316
if (lockingClause)
13131317
ereport(ERROR,
13141318
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1315-
errmsg("SELECT FOR UPDATE/SHARE is not allowed with UNION/INTERSECT/EXCEPT")));
1319+
/*------
1320+
translator: %s is a SQL row locking clause such as FOR UPDATE */
1321+
errmsg("%s is not allowed with UNION/INTERSECT/EXCEPT",
1322+
LCS_asString(((LockingClause *)
1323+
linitial(lockingClause))->strength))));
13161324

13171325
/* Process the WITH clause independently of all else */
13181326
if (withClause)
@@ -1506,7 +1514,11 @@ transformSetOperationTree(ParseState *pstate, SelectStmt *stmt,
15061514
if (stmt->lockingClause)
15071515
ereport(ERROR,
15081516
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1509-
errmsg("SELECT FOR UPDATE/SHARE is not allowed with UNION/INTERSECT/EXCEPT")));
1517+
/*------
1518+
translator: %s is a SQL row locking clause such as FOR UPDATE */
1519+
errmsg("%s is not allowed with UNION/INTERSECT/EXCEPT",
1520+
LCS_asString(((LockingClause *)
1521+
linitial(stmt->lockingClause))->strength))));
15101522

15111523
/*
15121524
* If an internal node of a set-op tree has ORDER BY, LIMIT, FOR UPDATE,
@@ -2063,21 +2075,33 @@ transformDeclareCursorStmt(ParseState *pstate, DeclareCursorStmt *stmt)
20632075
if (result->rowMarks != NIL && (stmt->options & CURSOR_OPT_HOLD))
20642076
ereport(ERROR,
20652077
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2066-
errmsg("DECLARE CURSOR WITH HOLD ... FOR UPDATE/SHARE is not supported"),
2078+
/*------
2079+
translator: %s is a SQL row locking clause such as FOR UPDATE */
2080+
errmsg("DECLARE CURSOR WITH HOLD ... %s is not supported",
2081+
LCS_asString(((RowMarkClause *)
2082+
linitial(result->rowMarks))->strength)),
20672083
errdetail("Holdable cursors must be READ ONLY.")));
20682084

20692085
/* FOR UPDATE and SCROLL are not compatible */
20702086
if (result->rowMarks != NIL && (stmt->options & CURSOR_OPT_SCROLL))
20712087
ereport(ERROR,
20722088
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2073-
errmsg("DECLARE SCROLL CURSOR ... FOR UPDATE/SHARE is not supported"),
2089+
/*------
2090+
translator: %s is a SQL row locking clause such as FOR UPDATE */
2091+
errmsg("DECLARE SCROLL CURSOR ... %s is not supported",
2092+
LCS_asString(((RowMarkClause *)
2093+
linitial(result->rowMarks))->strength)),
20742094
errdetail("Scrollable cursors must be READ ONLY.")));
20752095

20762096
/* FOR UPDATE and INSENSITIVE are not compatible */
20772097
if (result->rowMarks != NIL && (stmt->options & CURSOR_OPT_INSENSITIVE))
20782098
ereport(ERROR,
20792099
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2080-
errmsg("DECLARE INSENSITIVE CURSOR ... FOR UPDATE/SHARE is not supported"),
2100+
/*------
2101+
translator: %s is a SQL row locking clause such as FOR UPDATE */
2102+
errmsg("DECLARE INSENSITIVE CURSOR ... %s is not supported",
2103+
LCS_asString(((RowMarkClause *)
2104+
linitial(result->rowMarks))->strength)),
20812105
errdetail("Insensitive cursors must be READ ONLY.")));
20822106

20832107
/* We won't need the raw querytree any more */
@@ -2196,6 +2220,23 @@ transformCreateTableAsStmt(ParseState *pstate, CreateTableAsStmt *stmt)
21962220
}
21972221

21982222

2223+
char *
2224+
LCS_asString(LockClauseStrength strength)
2225+
{
2226+
switch (strength)
2227+
{
2228+
case LCS_FORKEYSHARE:
2229+
return "FOR KEY SHARE";
2230+
case LCS_FORSHARE:
2231+
return "FOR SHARE";
2232+
case LCS_FORNOKEYUPDATE:
2233+
return "FOR NO KEY UPDATE";
2234+
case LCS_FORUPDATE:
2235+
return "FOR UPDATE";
2236+
}
2237+
return "FOR some"; /* shouldn't happen */
2238+
}
2239+
21992240
/*
22002241
* Check for features that are not supported with FOR [KEY] UPDATE/SHARE.
22012242
*
@@ -2207,31 +2248,59 @@ CheckSelectLocking(Query *qry)
22072248
if (qry->setOperations)
22082249
ereport(ERROR,
22092250
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2210-
errmsg("row-level locks are not allowed with UNION/INTERSECT/EXCEPT")));
2251+
/*------
2252+
translator: %s is a SQL row locking clause such as FOR UPDATE */
2253+
errmsg("%s is not allowed with UNION/INTERSECT/EXCEPT",
2254+
LCS_asString(((RowMarkClause *)
2255+
linitial(qry->rowMarks))->strength))));
22112256
if (qry->distinctClause != NIL)
22122257
ereport(ERROR,
22132258
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2214-
errmsg("row-level locks are not allowed with DISTINCT clause")));
2259+
/*------
2260+
translator: %s is a SQL row locking clause such as FOR UPDATE */
2261+
errmsg("%s is not allowed with DISTINCT clause",
2262+
LCS_asString(((RowMarkClause *)
2263+
linitial(qry->rowMarks))->strength))));
22152264
if (qry->groupClause != NIL)
22162265
ereport(ERROR,
22172266
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2218-
errmsg("row-level locks are not allowed with GROUP BY clause")));
2267+
/*------
2268+
translator: %s is a SQL row locking clause such as FOR UPDATE */
2269+
errmsg("%s is not allowed with GROUP BY clause",
2270+
LCS_asString(((RowMarkClause *)
2271+
linitial(qry->rowMarks))->strength))));
22192272
if (qry->havingQual != NULL)
22202273
ereport(ERROR,
22212274
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2222-
errmsg("row-level locks are not allowed with HAVING clause")));
2275+
/*------
2276+
translator: %s is a SQL row locking clause such as FOR UPDATE */
2277+
errmsg("%s is not allowed with HAVING clause",
2278+
LCS_asString(((RowMarkClause *)
2279+
linitial(qry->rowMarks))->strength))));
22232280
if (qry->hasAggs)
22242281
ereport(ERROR,
22252282
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2226-
errmsg("row-level locks are not allowed with aggregate functions")));
2283+
/*------
2284+
translator: %s is a SQL row locking clause such as FOR UPDATE */
2285+
errmsg("%s is not allowed with aggregate functions",
2286+
LCS_asString(((RowMarkClause *)
2287+
linitial(qry->rowMarks))->strength))));
22272288
if (qry->hasWindowFuncs)
22282289
ereport(ERROR,
22292290
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2230-
errmsg("row-level locks are not allowed with window functions")));
2291+
/*------
2292+
translator: %s is a SQL row locking clause such as FOR UPDATE */
2293+
errmsg("%s is not allowed with window functions",
2294+
LCS_asString(((RowMarkClause *)
2295+
linitial(qry->rowMarks))->strength))));
22312296
if (expression_returns_set((Node *) qry->targetList))
22322297
ereport(ERROR,
22332298
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2234-
errmsg("row-level locks are not allowed with set-returning functions in the target list")));
2299+
/*------
2300+
translator: %s is a SQL row locking clause such as FOR UPDATE */
2301+
errmsg("%s is not allowed with set-returning functions in the target list",
2302+
LCS_asString(((RowMarkClause *)
2303+
linitial(qry->rowMarks))->strength))));
22352304
}
22362305

22372306
/*
@@ -2307,7 +2376,10 @@ transformLockingClause(ParseState *pstate, Query *qry, LockingClause *lc,
23072376
if (thisrel->catalogname || thisrel->schemaname)
23082377
ereport(ERROR,
23092378
(errcode(ERRCODE_SYNTAX_ERROR),
2310-
errmsg("row-level locks must specify unqualified relation names"),
2379+
/*------
2380+
translator: %s is a SQL row locking clause such as FOR UPDATE */
2381+
errmsg("%s must specify unqualified relation names",
2382+
LCS_asString(lc->strength)),
23112383
parser_errposition(pstate, thisrel->location)));
23122384

23132385
i = 0;
@@ -2337,25 +2409,37 @@ transformLockingClause(ParseState *pstate, Query *qry, LockingClause *lc,
23372409
case RTE_JOIN:
23382410
ereport(ERROR,
23392411
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2340-
errmsg("row-level locks cannot be applied to a join"),
2412+
/*------
2413+
translator: %s is a SQL row locking clause such as FOR UPDATE */
2414+
errmsg("%s cannot be applied to a join",
2415+
LCS_asString(lc->strength)),
23412416
parser_errposition(pstate, thisrel->location)));
23422417
break;
23432418
case RTE_FUNCTION:
23442419
ereport(ERROR,
23452420
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2346-
errmsg("row-level locks cannot be applied to a function"),
2421+
/*------
2422+
translator: %s is a SQL row locking clause such as FOR UPDATE */
2423+
errmsg("%s cannot be applied to a function",
2424+
LCS_asString(lc->strength)),
23472425
parser_errposition(pstate, thisrel->location)));
23482426
break;
23492427
case RTE_VALUES:
23502428
ereport(ERROR,
23512429
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2352-
errmsg("row-level locks cannot be applied to VALUES"),
2430+
/*------
2431+
translator: %s is a SQL row locking clause such as FOR UPDATE */
2432+
errmsg("%s cannot be applied to VALUES",
2433+
LCS_asString(lc->strength)),
23532434
parser_errposition(pstate, thisrel->location)));
23542435
break;
23552436
case RTE_CTE:
23562437
ereport(ERROR,
23572438
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2358-
errmsg("row-level locks cannot be applied to a WITH query"),
2439+
/*------
2440+
translator: %s is a SQL row locking clause such as FOR UPDATE */
2441+
errmsg("%s cannot be applied to a WITH query",
2442+
LCS_asString(lc->strength)),
23592443
parser_errposition(pstate, thisrel->location)));
23602444
break;
23612445
default:
@@ -2369,8 +2453,11 @@ transformLockingClause(ParseState *pstate, Query *qry, LockingClause *lc,
23692453
if (rt == NULL)
23702454
ereport(ERROR,
23712455
(errcode(ERRCODE_UNDEFINED_TABLE),
2372-
errmsg("relation \"%s\" in row-level lock clause not found in FROM clause",
2373-
thisrel->relname),
2456+
/*------
2457+
translator: %s is a SQL row locking clause such as FOR UPDATE */
2458+
errmsg("relation \"%s\" in %s clause not found in FROM clause",
2459+
thisrel->relname,
2460+
LCS_asString(lc->strength)),
23742461
parser_errposition(pstate, thisrel->location)));
23752462
}
23762463
}

src/include/parser/analyze.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ extern Query *transformStmt(ParseState *pstate, Node *parseTree);
3636

3737
extern bool analyze_requires_snapshot(Node *parseTree);
3838

39+
extern char *LCS_asString(LockClauseStrength strength);
3940
extern void CheckSelectLocking(Query *qry);
4041
extern void applyLockingClause(Query *qry, Index rtindex,
4142
LockClauseStrength strength, bool noWait, bool pushedDown);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy