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

Commit66e6916

Browse files
committed
Fix grammar for subscripting or field selection from a sub-SELECT result.
Such cases should work, but the grammar failed to accept them because ofour ancient precedence hacks to convince bison that extra parenthesesaround a sub-SELECT in an expression are unambiguous. (Formally, they*are* ambiguous, but we don't especially care whether they're treated aspart of the sub-SELECT or part of the expression. Bison cares, though.)Fix by adding a redundant-looking production for this case.This is a fine example of why fixing shift/reduce conflicts viaprecedence declarations is more dangerous than it looks: you can easilycause the parser to reject cases that should work.This has been wrong since commit3db4056or maybe before, and apparently some people have been working around itby inserting no-op casts. That method introduces a dump/reload hazard,as illustrated in bug #7838 from Jan Mate. Hence, back-patch to allactive branches.
1 parent85abf1d commit66e6916

File tree

3 files changed

+92
-0
lines changed

3 files changed

+92
-0
lines changed

‎src/backend/parser/gram.y

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7786,6 +7786,28 @@ c_expr:columnref{ $$ = $1; }
77867786
n->subselect =$1;
77877787
$$ = (Node *)n;
77887788
}
7789+
| select_with_parens indirection
7790+
{
7791+
/*
7792+
* Because the select_with_parens nonterminal is designed
7793+
* to "eat" as many levels of parens as possible, the
7794+
* '(' a_expr ')' opt_indirection production above will
7795+
* fail to match a sub-SELECT with indirection decoration;
7796+
* the sub-SELECT won't be regarded as an a_expr as long
7797+
* as there are parens around it. To support applying
7798+
* subscripting or field selection to a sub-SELECT result,
7799+
* we need this redundant-looking production.
7800+
*/
7801+
SubLink *n = makeNode(SubLink);
7802+
A_Indirection *a = makeNode(A_Indirection);
7803+
n->subLinkType = EXPR_SUBLINK;
7804+
n->testexpr =NULL;
7805+
n->operName = NIL;
7806+
n->subselect =$1;
7807+
a->arg = (Node *)n;
7808+
a->indirection =$2;
7809+
$$ = (Node *)a;
7810+
}
77897811
| EXISTS select_with_parens
77907812
{
77917813
SubLink *n = makeNode(SubLink);

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

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,61 @@ SELECT 1 AS zero WHERE 1 IN (SELECT 2);
1717
------
1818
(0 rows)
1919

20+
-- Check grammar's handling of extra parens in assorted contexts
21+
SELECT * FROM (SELECT 1 AS x) ss;
22+
x
23+
---
24+
1
25+
(1 row)
26+
27+
SELECT * FROM ((SELECT 1 AS x)) ss;
28+
x
29+
---
30+
1
31+
(1 row)
32+
33+
(SELECT 2) UNION SELECT 2;
34+
?column?
35+
----------
36+
2
37+
(1 row)
38+
39+
((SELECT 2)) UNION SELECT 2;
40+
?column?
41+
----------
42+
2
43+
(1 row)
44+
45+
SELECT ((SELECT 2) UNION SELECT 2);
46+
?column?
47+
----------
48+
2
49+
(1 row)
50+
51+
SELECT (((SELECT 2)) UNION SELECT 2);
52+
?column?
53+
----------
54+
2
55+
(1 row)
56+
57+
SELECT (SELECT ARRAY[1,2,3])[1];
58+
?column?
59+
----------
60+
1
61+
(1 row)
62+
63+
SELECT ((SELECT ARRAY[1,2,3]))[2];
64+
?column?
65+
----------
66+
2
67+
(1 row)
68+
69+
SELECT (((SELECT ARRAY[1,2,3])))[3];
70+
?column?
71+
----------
72+
3
73+
(1 row)
74+
2075
-- Set up some simple test tables
2176
CREATE TABLE SUBSELECT_TBL (
2277
f1 integer,

‎src/test/regress/sql/subselect.sql

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,21 @@ SELECT 1 AS zero WHERE 1 NOT IN (SELECT 1);
88

99
SELECT1AS zeroWHERE1IN (SELECT2);
1010

11+
-- Check grammar's handling of extra parens in assorted contexts
12+
13+
SELECT*FROM (SELECT1AS x) ss;
14+
SELECT*FROM ((SELECT1AS x)) ss;
15+
16+
(SELECT2)UNIONSELECT2;
17+
((SELECT2))UNIONSELECT2;
18+
19+
SELECT ((SELECT2)UNIONSELECT2);
20+
SELECT (((SELECT2))UNIONSELECT2);
21+
22+
SELECT (SELECT ARRAY[1,2,3])[1];
23+
SELECT ((SELECT ARRAY[1,2,3]))[2];
24+
SELECT (((SELECT ARRAY[1,2,3])))[3];
25+
1126
-- Set up some simple test tables
1227

1328
CREATETABLESUBSELECT_TBL (

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp