@@ -105,12 +105,15 @@ typedef struct ImportQual
105
105
List *table_names;
106
106
} ImportQual;
107
107
108
- /* Private struct for the result of opt_select_limit production */
108
+ /* Private struct for the result of select_limit & limit_clause productions */
109
109
typedef struct SelectLimit
110
110
{
111
111
Node *limitOffset;
112
112
Node *limitCount;
113
- LimitOption limitOption;
113
+ LimitOption limitOption; /* indicates presence of WITH TIES */
114
+ ParseLoc offsetLoc; /* location of OFFSET token, if present */
115
+ ParseLoc countLoc; /* location of LIMIT/FETCH token, if present */
116
+ ParseLoc optionLoc; /* location of WITH TIES, if present */
114
117
} SelectLimit;
115
118
116
119
/* Private struct for the result of group_clause production */
@@ -195,7 +198,8 @@ static void SplitColQualList(List *qualList,
195
198
static void processCASbits (int cas_bits, int location, const char *constrType,
196
199
bool *deferrable, bool *initdeferred, bool *not_valid,
197
200
bool *no_inherit, core_yyscan_t yyscanner);
198
- static PartitionStrategy parsePartitionStrategy (char *strategy);
201
+ static PartitionStrategy parsePartitionStrategy (char *strategy, int location,
202
+ core_yyscan_t yyscanner);
199
203
static void preprocess_pubobj_list (List *pubobjspec_list,
200
204
core_yyscan_t yyscanner);
201
205
static Node *makeRecursiveViewSelect (char *relname, List *aliases, Node *query);
@@ -3145,11 +3149,13 @@ PartitionBoundSpec:
3145
3149
if (n->modulus == -1 )
3146
3150
ereport (ERROR,
3147
3151
(errcode(ERRCODE_SYNTAX_ERROR),
3148
- errmsg(" modulus for hash partition must be specified" )));
3152
+ errmsg(" modulus for hash partition must be specified" ),
3153
+ parser_errposition(@3 )));
3149
3154
if (n->remainder == -1 )
3150
3155
ereport (ERROR,
3151
3156
(errcode(ERRCODE_SYNTAX_ERROR),
3152
- errmsg(" remainder for hash partition must be specified" )));
3157
+ errmsg(" remainder for hash partition must be specified" ),
3158
+ parser_errposition(@3 )));
3153
3159
3154
3160
n->location = @3 ;
3155
3161
@@ -4528,7 +4534,7 @@ PartitionSpec: PARTITION BY ColId '(' part_params ')'
4528
4534
{
4529
4535
PartitionSpec *n = makeNode(PartitionSpec);
4530
4536
4531
- n->strategy = parsePartitionStrategy($3 );
4537
+ n->strategy = parsePartitionStrategy($3 , @3 , yyscanner );
4532
4538
n->partParams = $5 ;
4533
4539
n->location = @1 ;
4534
4540
@@ -5962,7 +5968,8 @@ CreateTrigStmt:
5962
5968
if (n->replace) /* not supported, see CreateTrigger */
5963
5969
ereport (ERROR,
5964
5970
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5965
- errmsg(" CREATE OR REPLACE CONSTRAINT TRIGGER is not supported" )));
5971
+ errmsg(" CREATE OR REPLACE CONSTRAINT TRIGGER is not supported" ),
5972
+ parser_errposition(@1 )));
5966
5973
n->isconstraint = true ;
5967
5974
n->trigname = $5 ;
5968
5975
n->relation = $9 ;
@@ -6247,7 +6254,8 @@ CreateAssertionStmt:
6247
6254
{
6248
6255
ereport (ERROR,
6249
6256
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
6250
- errmsg(" CREATE ASSERTION is not yet implemented" )));
6257
+ errmsg(" CREATE ASSERTION is not yet implemented" ),
6258
+ parser_errposition(@1 )));
6251
6259
6252
6260
$$ = NULL ;
6253
6261
}
@@ -13156,11 +13164,13 @@ select_limit:
13156
13164
{
13157
13165
$$ = $1 ;
13158
13166
($$ )->limitOffset = $2 ;
13167
+ ($$ )->offsetLoc = @2 ;
13159
13168
}
13160
13169
| offset_clause limit_clause
13161
13170
{
13162
13171
$$ = $2 ;
13163
13172
($$ )->limitOffset = $1 ;
13173
+ ($$ )->offsetLoc = @1 ;
13164
13174
}
13165
13175
| limit_clause
13166
13176
{
@@ -13173,6 +13183,9 @@ select_limit:
13173
13183
n->limitOffset = $1 ;
13174
13184
n->limitCount = NULL ;
13175
13185
n->limitOption = LIMIT_OPTION_COUNT;
13186
+ n->offsetLoc = @1 ;
13187
+ n->countLoc = -1 ;
13188
+ n->optionLoc = -1 ;
13176
13189
$$ = n;
13177
13190
}
13178
13191
;
@@ -13190,6 +13203,9 @@ limit_clause:
13190
13203
n->limitOffset = NULL ;
13191
13204
n->limitCount = $2 ;
13192
13205
n->limitOption = LIMIT_OPTION_COUNT;
13206
+ n->offsetLoc = -1 ;
13207
+ n->countLoc = @1 ;
13208
+ n->optionLoc = -1 ;
13193
13209
$$ = n;
13194
13210
}
13195
13211
| LIMIT select_limit_value ' ,' select_offset_value
@@ -13215,6 +13231,9 @@ limit_clause:
13215
13231
n->limitOffset = NULL ;
13216
13232
n->limitCount = $3 ;
13217
13233
n->limitOption = LIMIT_OPTION_COUNT;
13234
+ n->offsetLoc = -1 ;
13235
+ n->countLoc = @1 ;
13236
+ n->optionLoc = -1 ;
13218
13237
$$ = n;
13219
13238
}
13220
13239
| FETCH first_or_next select_fetch_first_value row_or_rows WITH TIES
@@ -13224,6 +13243,9 @@ limit_clause:
13224
13243
n->limitOffset = NULL ;
13225
13244
n->limitCount = $3 ;
13226
13245
n->limitOption = LIMIT_OPTION_WITH_TIES;
13246
+ n->offsetLoc = -1 ;
13247
+ n->countLoc = @1 ;
13248
+ n->optionLoc = @5 ;
13227
13249
$$ = n;
13228
13250
}
13229
13251
| FETCH first_or_next row_or_rows ONLY
@@ -13233,6 +13255,9 @@ limit_clause:
13233
13255
n->limitOffset = NULL ;
13234
13256
n->limitCount = makeIntConst(1 , -1 );
13235
13257
n->limitOption = LIMIT_OPTION_COUNT;
13258
+ n->offsetLoc = -1 ;
13259
+ n->countLoc = @1 ;
13260
+ n->optionLoc = -1 ;
13236
13261
$$ = n;
13237
13262
}
13238
13263
| FETCH first_or_next row_or_rows WITH TIES
@@ -13242,6 +13267,9 @@ limit_clause:
13242
13267
n->limitOffset = NULL ;
13243
13268
n->limitCount = makeIntConst(1 , -1 );
13244
13269
n->limitOption = LIMIT_OPTION_WITH_TIES;
13270
+ n->offsetLoc = -1 ;
13271
+ n->countLoc = @1 ;
13272
+ n->optionLoc = @4 ;
13245
13273
$$ = n;
13246
13274
}
13247
13275
;
@@ -16954,8 +16982,9 @@ json_format_clause:
16954
16982
encoding = JS_ENC_UTF32;
16955
16983
else
16956
16984
ereport (ERROR,
16957
- errcode (ERRCODE_INVALID_PARAMETER_VALUE),
16958
- errmsg (" unrecognized JSON encoding: %s" , $4 ));
16985
+ (errcode (ERRCODE_INVALID_PARAMETER_VALUE),
16986
+ errmsg (" unrecognized JSON encoding: %s" , $4 ),
16987
+ parser_errposition (@4 )));
16959
16988
16960
16989
$$ = (Node *) makeJsonFormat (JS_FORMAT_JSON, encoding, @1 );
16961
16990
}
@@ -17457,7 +17486,8 @@ PLpgSQL_Expr: opt_distinct_clause opt_target_list
17457
17486
$9 ->limitOption == LIMIT_OPTION_WITH_TIES)
17458
17487
ereport (ERROR,
17459
17488
(errcode (ERRCODE_SYNTAX_ERROR),
17460
- errmsg (" WITH TIES cannot be specified without ORDER BY clause" )));
17489
+ errmsg (" WITH TIES cannot be specified without ORDER BY clause" ),
17490
+ parser_errposition ($9 ->optionLoc )));
17461
17491
n->limitOption = $9 ->limitOption ;
17462
17492
}
17463
17493
n->lockingClause = $10 ;
@@ -18962,7 +18992,7 @@ insertSelectOptions(SelectStmt *stmt,
18962
18992
ereport(ERROR,
18963
18993
(errcode(ERRCODE_SYNTAX_ERROR),
18964
18994
errmsg("multiple OFFSET clauses not allowed"),
18965
- parser_errposition(exprLocation( limitClause->limitOffset) )));
18995
+ parser_errposition(limitClause->offsetLoc )));
18966
18996
stmt->limitOffset = limitClause->limitOffset;
18967
18997
}
18968
18998
if (limitClause && limitClause->limitCount)
@@ -18971,19 +19001,18 @@ insertSelectOptions(SelectStmt *stmt,
18971
19001
ereport(ERROR,
18972
19002
(errcode(ERRCODE_SYNTAX_ERROR),
18973
19003
errmsg("multiple LIMIT clauses not allowed"),
18974
- parser_errposition(exprLocation( limitClause->limitCount) )));
19004
+ parser_errposition(limitClause->countLoc )));
18975
19005
stmt->limitCount = limitClause->limitCount;
18976
19006
}
18977
19007
if (limitClause)
18978
19008
{
18979
- if (stmt->limitOption)
18980
- ereport(ERROR,
18981
- (errcode(ERRCODE_SYNTAX_ERROR),
18982
- errmsg("multiple limit options not allowed")));
19009
+ /* If there was a conflict, we must have detected it above */
19010
+ Assert(!stmt->limitOption);
18983
19011
if (!stmt->sortClause && limitClause->limitOption == LIMIT_OPTION_WITH_TIES)
18984
19012
ereport(ERROR,
18985
19013
(errcode(ERRCODE_SYNTAX_ERROR),
18986
- errmsg("WITH TIES cannot be specified without ORDER BY clause")));
19014
+ errmsg("WITH TIES cannot be specified without ORDER BY clause"),
19015
+ parser_errposition(limitClause->optionLoc)));
18987
19016
if (limitClause->limitOption == LIMIT_OPTION_WITH_TIES && stmt->lockingClause)
18988
19017
{
18989
19018
ListCell *lc;
@@ -18996,7 +19025,8 @@ insertSelectOptions(SelectStmt *stmt,
18996
19025
ereport(ERROR,
18997
19026
(errcode(ERRCODE_SYNTAX_ERROR),
18998
19027
errmsg("%s and %s options cannot be used together",
18999
- "SKIP LOCKED", "WITH TIES")));
19028
+ "SKIP LOCKED", "WITH TIES"),
19029
+ parser_errposition(limitClause->optionLoc)));
19000
19030
}
19001
19031
}
19002
19032
stmt->limitOption = limitClause->limitOption;
@@ -19425,7 +19455,7 @@ processCASbits(int cas_bits, int location, const char *constrType,
19425
19455
* PartitionStrategy representation, or die trying.
19426
19456
*/
19427
19457
static PartitionStrategy
19428
- parsePartitionStrategy(char *strategy)
19458
+ parsePartitionStrategy(char *strategy, int location, core_yyscan_t yyscanner )
19429
19459
{
19430
19460
if (pg_strcasecmp(strategy, "list") == 0)
19431
19461
return PARTITION_STRATEGY_LIST;
@@ -19436,8 +19466,8 @@ parsePartitionStrategy(char *strategy)
19436
19466
19437
19467
ereport(ERROR,
19438
19468
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
19439
- errmsg("unrecognized partitioning strategy \"%s\"",
19440
- strategy )));
19469
+ errmsg("unrecognized partitioning strategy \"%s\"", strategy),
19470
+ parser_errposition(location )));
19441
19471
return PARTITION_STRATEGY_LIST; /* keep compiler quiet */
19442
19472
19443
19473
}
0 commit comments