From 33d836cd6fb29e5a8beb8b6bb19ee9d8b37d2e4c Mon Sep 17 00:00:00 2001
From: Alvaro Herrera <alvherre@alvh.no-ip.org>
Date: Tue, 26 Nov 2019 11:39:22 -0300
Subject: [PATCH v14 2/2] grammar tweaks

---
 src/backend/parser/gram.y | 100 ++++++++++++++------------------------
 1 file changed, 36 insertions(+), 64 deletions(-)

diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index e776215155..1dc45eec62 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -135,13 +135,6 @@ typedef struct SelectLimit
 	LimitOption limitOption;
 } SelectLimit;
 
-/* Private struct for the result of limit_clause production */
-typedef struct LimitClause
-{
-	Node *limitCount;
-	LimitOption limitOption;
-} LimitClause;
-
 /* ConstraintAttributeSpec yields an integer bitmask of these flags: */
 #define CAS_NOT_DEFERRABLE			0x01
 #define CAS_DEFERRABLE				0x02
@@ -179,8 +172,7 @@ static List *makeOrderedSetArgs(List *directargs, List *orderedargs,
 								core_yyscan_t yyscanner);
 static void insertSelectOptions(SelectStmt *stmt,
 								List *sortClause, List *lockingClause,
-								Node *limitOffset, Node *limitCount,
-								LimitOption limitOption,
+								SelectLimit *limitClause,
 								WithClause *withClause,
 								core_yyscan_t yyscanner);
 static Node *makeSetOp(SetOperation op, bool all, Node *larg, Node *rarg);
@@ -258,8 +250,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
 	PartitionSpec		*partspec;
 	PartitionBoundSpec	*partboundspec;
 	RoleSpec			*rolespec;
-	struct SelectLimit	*SelectLimit;
-	struct LimitClause	*LimitClause;
+	struct SelectLimit	*selectlimit;
 }
 
 %type <node>	stmt schema_stmt
@@ -392,8 +383,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
 %type <ival>	import_qualification_type
 %type <importqual> import_qualification
 %type <node>	vacuum_relation
-%type <SelectLimit> opt_select_limit select_limit
-%type <LimitClause> limit_clause
+%type <selectlimit> opt_select_limit select_limit limit_clause
 
 %type <list>	stmtblock stmtmulti
 				OptTableElementList TableElementList OptInherit definition
@@ -11336,15 +11326,14 @@ select_no_parens:
 			| select_clause sort_clause
 				{
 					insertSelectOptions((SelectStmt *) $1, $2, NIL,
-										NULL, NULL, LIMIT_OPTION_DEFAULT, NULL,
+										NULL, NULL,
 										yyscanner);
 					$$ = $1;
 				}
 			| select_clause opt_sort_clause for_locking_clause opt_select_limit
 				{
 					insertSelectOptions((SelectStmt *) $1, $2, $3,
-										($4)->limitOffset, ($4)->limitCount,
-										($4)->limitOption,
+										$4,
 										NULL,
 										yyscanner);
 					$$ = $1;
@@ -11352,8 +11341,7 @@ select_no_parens:
 			| select_clause opt_sort_clause select_limit opt_for_locking_clause
 				{
 					insertSelectOptions((SelectStmt *) $1, $2, $4,
-										($3)->limitOffset, ($3)->limitCount,
-										($3)->limitOption,
+										$3,
 										NULL,
 										yyscanner);
 					$$ = $1;
@@ -11361,24 +11349,23 @@ select_no_parens:
 			| with_clause select_clause
 				{
 					insertSelectOptions((SelectStmt *) $2, NULL, NIL,
-										NULL, NULL,
-										LIMIT_OPTION_DEFAULT,$1,
+										NULL,
+										$1,
 										yyscanner);
 					$$ = $2;
 				}
 			| with_clause select_clause sort_clause
 				{
 					insertSelectOptions((SelectStmt *) $2, $3, NIL,
-										NULL, NULL,
-										LIMIT_OPTION_DEFAULT,$1,
+										NULL,
+										$1,
 										yyscanner);
 					$$ = $2;
 				}
 			| with_clause select_clause opt_sort_clause for_locking_clause opt_select_limit
 				{
 					insertSelectOptions((SelectStmt *) $2, $3, $4,
-										($5)->limitOffset, ($5)->limitCount,
-										($5)->limitOption,
+										$5,
 										$1,
 										yyscanner);
 					$$ = $2;
@@ -11386,8 +11373,7 @@ select_no_parens:
 			| with_clause select_clause opt_sort_clause select_limit opt_for_locking_clause
 				{
 					insertSelectOptions((SelectStmt *) $2, $3, $5,
-										($4)->limitOffset, ($4)->limitCount,
-										($4)->limitOption,
+										$4,
 										$1,
 										yyscanner);
 					$$ = $2;
@@ -11683,27 +11669,17 @@ sortby:		a_expr USING qual_all_Op opt_nulls_order
 select_limit:
 			limit_clause offset_clause
 				{
-					SelectLimit *n = (SelectLimit *) palloc(sizeof(SelectLimit));
-					n->limitOffset = $2;
-					n->limitCount = ($1)->limitCount;
-					n->limitOption = ($1)->limitOption;
-					$$ = n;
+					$$ = $1;
+					($$)->limitOffset = $2;
 				}
 			| offset_clause limit_clause
 				{
-					SelectLimit *n = (SelectLimit *) palloc(sizeof(SelectLimit));
-					n->limitOffset = $1;
-					n->limitCount = ($2)->limitCount;
-					n->limitOption = ($2)->limitOption;
-					$$ = n;
+					$$ = $2;
+					($$)->limitOffset = $1;
 				}
 			| limit_clause
 				{
-					SelectLimit *n = (SelectLimit *) palloc(sizeof(SelectLimit));
-					n->limitOffset = NULL;
-					n->limitCount = ($1)->limitCount;
-					n->limitOption = ($1)->limitOption;
-					$$ = n;
+					$$ = $1;
 				}
 			| offset_clause
 				{
@@ -11717,20 +11693,14 @@ select_limit:
 
 opt_select_limit:
 			select_limit						{ $$ = $1; }
-			| /* EMPTY */
-				{
-					SelectLimit *n = (SelectLimit *) palloc(sizeof(SelectLimit));
-					n->limitOffset = NULL;
-					n->limitCount = NULL;
-					n->limitOption = LIMIT_OPTION_DEFAULT;
-					$$ = n;
-				}
+			| /* EMPTY */						{ $$ = NULL; }
 		;
 
 limit_clause:
 			LIMIT select_limit_value
 				{
-					LimitClause *n = (LimitClause *) palloc(sizeof(LimitClause));
+					SelectLimit *n = (SelectLimit *) palloc(sizeof(SelectLimit));
+					n->limitOffset = NULL;
 					n->limitCount = $2;
 					n->limitOption = LIMIT_OPTION_COUNT;
 					$$ = n;
@@ -11753,21 +11723,24 @@ limit_clause:
 			 */
 			| FETCH first_or_next select_fetch_first_value row_or_rows ONLY
 				{
-					LimitClause *n = (LimitClause *) palloc(sizeof(LimitClause));
+					SelectLimit *n = (SelectLimit *) palloc(sizeof(SelectLimit));
+					n->limitOffset = NULL;
 					n->limitCount = $3;
 					n->limitOption = LIMIT_OPTION_COUNT;
 					$$ = n;
 				}
 			| FETCH first_or_next select_fetch_first_value row_or_rows WITH TIES
 				{
-					LimitClause *n = (LimitClause *) palloc(sizeof(LimitClause));
+					SelectLimit *n = (SelectLimit *) palloc(sizeof(SelectLimit));
+					n->limitOffset = NULL;
 					n->limitCount = $3;
 					n->limitOption = LIMIT_OPTION_WITH_TIES;
 					$$ = n;
 				}
 			| FETCH first_or_next row_or_rows ONLY
 				{
-					LimitClause *n = (LimitClause *) palloc(sizeof(LimitClause));
+					SelectLimit *n = (SelectLimit *) palloc(sizeof(SelectLimit));
+					n->limitOffset = NULL;
 					n->limitCount = makeIntConst(1, -1);
 					n->limitOption = LIMIT_OPTION_COUNT;
 					$$ = n;
@@ -16027,8 +16000,7 @@ makeOrderedSetArgs(List *directargs, List *orderedargs,
 static void
 insertSelectOptions(SelectStmt *stmt,
 					List *sortClause, List *lockingClause,
-					Node *limitOffset, Node *limitCount,
-					LimitOption limitOption,
+					SelectLimit *limitClause,
 					WithClause *withClause,
 					core_yyscan_t yyscanner)
 {
@@ -16049,35 +16021,35 @@ insertSelectOptions(SelectStmt *stmt,
 	}
 	/* We can handle multiple locking clauses, though */
 	stmt->lockingClause = list_concat(stmt->lockingClause, lockingClause);
-	if (limitOffset)
+	if (limitClause && limitClause->limitOffset)
 	{
 		if (stmt->limitOffset)
 			ereport(ERROR,
 					(errcode(ERRCODE_SYNTAX_ERROR),
 					 errmsg("multiple OFFSET clauses not allowed"),
-					 parser_errposition(exprLocation(limitOffset))));
-		stmt->limitOffset = limitOffset;
+					 parser_errposition(exprLocation(limitClause->limitOffset))));
+		stmt->limitOffset = limitClause->limitOffset;
 	}
-	if (limitCount)
+	if (limitClause && limitClause->limitCount)
 	{
 		if (stmt->limitCount)
 			ereport(ERROR,
 					(errcode(ERRCODE_SYNTAX_ERROR),
 					 errmsg("multiple LIMIT clauses not allowed"),
-					 parser_errposition(exprLocation(limitCount))));
-		stmt->limitCount = limitCount;
+					 parser_errposition(exprLocation(limitClause->limitCount))));
+		stmt->limitCount = limitClause->limitCount;
 	}
-	if (limitOption && limitOption != LIMIT_OPTION_DEFAULT)
+	if (limitClause && limitClause->limitOption != LIMIT_OPTION_DEFAULT)
 	{
 		if (stmt->limitOption)
 			ereport(ERROR,
 					(errcode(ERRCODE_SYNTAX_ERROR),
 					 errmsg("multiple limit options not allowed")));
-		if (!stmt->sortClause && limitOption == LIMIT_OPTION_WITH_TIES)
+		if (!stmt->sortClause && limitClause->limitOption == LIMIT_OPTION_WITH_TIES)
 			ereport(ERROR,
 					(errcode(ERRCODE_SYNTAX_ERROR),
 					 errmsg("WITH TIES options can not be specified without ORDER BY clause")));
-		stmt->limitOption = limitOption;
+		stmt->limitOption = limitClause->limitOption;
 	}
 	if (withClause)
 	{
-- 
2.20.1

