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

Commit89e51ab

Browse files
committed
Add a parse location field to struct FunctionParameter.
This allows an error cursor to be supplied for a bunch ofbad-function-definition errors that previously lacked one,or that cheated a bit by pointing at the contained type namewhen the error isn't really about that.Bump catversion from an abundance of caution --- I don't thinkthis node type can actually appear in stored views/rules, butbetter safe than sorry.Jian He and Tom Lane (extracted from a larger patch by Jian,with some additional work by me)Discussion:https://postgr.es/m/CACJufxEmONE3P2En=jopZy1m=cCCUs65M4+1o52MW5og9oaUPA@mail.gmail.com
1 parentb82c877 commit89e51ab

File tree

17 files changed

+100
-24
lines changed

17 files changed

+100
-24
lines changed

‎src/backend/commands/functioncmds.c

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ interpret_function_parameter_list(ParseState *pstate,
232232
if (fpmode==FUNC_PARAM_DEFAULT)
233233
fpmode=FUNC_PARAM_IN;
234234

235-
typtup=LookupTypeName(NULL,t,NULL, false);
235+
typtup=LookupTypeName(pstate,t,NULL, false);
236236
if (typtup)
237237
{
238238
if (!((Form_pg_type)GETSTRUCT(typtup))->typisdefined)
@@ -242,18 +242,21 @@ interpret_function_parameter_list(ParseState *pstate,
242242
ereport(ERROR,
243243
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
244244
errmsg("SQL function cannot accept shell type %s",
245-
TypeNameToString(t))));
245+
TypeNameToString(t)),
246+
parser_errposition(pstate,t->location)));
246247
/* We don't allow creating aggregates on shell types either */
247248
elseif (objtype==OBJECT_AGGREGATE)
248249
ereport(ERROR,
249250
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
250251
errmsg("aggregate cannot accept shell type %s",
251-
TypeNameToString(t))));
252+
TypeNameToString(t)),
253+
parser_errposition(pstate,t->location)));
252254
else
253255
ereport(NOTICE,
254256
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
255257
errmsg("argument type %s is only a shell",
256-
TypeNameToString(t))));
258+
TypeNameToString(t)),
259+
parser_errposition(pstate,t->location)));
257260
}
258261
toid=typeTypeId(typtup);
259262
ReleaseSysCache(typtup);
@@ -263,7 +266,8 @@ interpret_function_parameter_list(ParseState *pstate,
263266
ereport(ERROR,
264267
(errcode(ERRCODE_UNDEFINED_OBJECT),
265268
errmsg("type %s does not exist",
266-
TypeNameToString(t))));
269+
TypeNameToString(t)),
270+
parser_errposition(pstate,t->location)));
267271
toid=InvalidOid;/* keep compiler quiet */
268272
}
269273

@@ -276,15 +280,18 @@ interpret_function_parameter_list(ParseState *pstate,
276280
if (objtype==OBJECT_AGGREGATE)
277281
ereport(ERROR,
278282
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
279-
errmsg("aggregates cannot accept set arguments")));
283+
errmsg("aggregates cannot accept set arguments"),
284+
parser_errposition(pstate,fp->location)));
280285
elseif (objtype==OBJECT_PROCEDURE)
281286
ereport(ERROR,
282287
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
283-
errmsg("procedures cannot accept set arguments")));
288+
errmsg("procedures cannot accept set arguments"),
289+
parser_errposition(pstate,fp->location)));
284290
else
285291
ereport(ERROR,
286292
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
287-
errmsg("functions cannot accept set arguments")));
293+
errmsg("functions cannot accept set arguments"),
294+
parser_errposition(pstate,fp->location)));
288295
}
289296

290297
/* handle input parameters */
@@ -294,7 +301,8 @@ interpret_function_parameter_list(ParseState *pstate,
294301
if (varCount>0)
295302
ereport(ERROR,
296303
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
297-
errmsg("VARIADIC parameter must be the last input parameter")));
304+
errmsg("VARIADIC parameter must be the last input parameter"),
305+
parser_errposition(pstate,fp->location)));
298306
inTypes[inCount++]=toid;
299307
isinput= true;
300308
if (parameterTypes_list)
@@ -314,7 +322,8 @@ interpret_function_parameter_list(ParseState *pstate,
314322
if (varCount>0)
315323
ereport(ERROR,
316324
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
317-
errmsg("VARIADIC parameter must be the last parameter")));
325+
errmsg("VARIADIC parameter must be the last parameter"),
326+
parser_errposition(pstate,fp->location)));
318327
/* Procedures with output parameters always return RECORD */
319328
*requiredResultType=RECORDOID;
320329
}
@@ -339,7 +348,8 @@ interpret_function_parameter_list(ParseState *pstate,
339348
if (!OidIsValid(get_element_type(toid)))
340349
ereport(ERROR,
341350
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
342-
errmsg("VARIADIC parameter must be an array")));
351+
errmsg("VARIADIC parameter must be an array"),
352+
parser_errposition(pstate,fp->location)));
343353
break;
344354
}
345355
}
@@ -385,7 +395,8 @@ interpret_function_parameter_list(ParseState *pstate,
385395
ereport(ERROR,
386396
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
387397
errmsg("parameter name \"%s\" used more than once",
388-
fp->name)));
398+
fp->name),
399+
parser_errposition(pstate,fp->location)));
389400
}
390401

391402
paramNames[i]=CStringGetTextDatum(fp->name);
@@ -402,7 +413,8 @@ interpret_function_parameter_list(ParseState *pstate,
402413
if (!isinput)
403414
ereport(ERROR,
404415
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
405-
errmsg("only input parameters can have default values")));
416+
errmsg("only input parameters can have default values"),
417+
parser_errposition(pstate,fp->location)));
406418

407419
def=transformExpr(pstate,fp->defexpr,
408420
EXPR_KIND_FUNCTION_DEFAULT);
@@ -417,7 +429,8 @@ interpret_function_parameter_list(ParseState *pstate,
417429
contain_var_clause(def))
418430
ereport(ERROR,
419431
(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
420-
errmsg("cannot use table references in parameter default value")));
432+
errmsg("cannot use table references in parameter default value"),
433+
parser_errposition(pstate,fp->location)));
421434

422435
/*
423436
* transformExpr() should have already rejected subqueries,
@@ -441,7 +454,8 @@ interpret_function_parameter_list(ParseState *pstate,
441454
if (isinput&&have_defaults)
442455
ereport(ERROR,
443456
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
444-
errmsg("input parameters after one with a default value must also have defaults")));
457+
errmsg("input parameters after one with a default value must also have defaults"),
458+
parser_errposition(pstate,fp->location)));
445459

446460
/*
447461
* For procedures, we also can't allow OUT parameters after one
@@ -451,7 +465,8 @@ interpret_function_parameter_list(ParseState *pstate,
451465
if (objtype==OBJECT_PROCEDURE&&have_defaults)
452466
ereport(ERROR,
453467
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
454-
errmsg("procedure OUT parameters cannot appear after one with a default value")));
468+
errmsg("procedure OUT parameters cannot appear after one with a default value"),
469+
parser_errposition(pstate,fp->location)));
455470
}
456471

457472
i++;

‎src/backend/nodes/nodeFuncs.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1723,8 +1723,7 @@ exprLocation(const Node *expr)
17231723
loc= ((constConstraint*)expr)->location;
17241724
break;
17251725
caseT_FunctionParameter:
1726-
/* just use typename's location */
1727-
loc=exprLocation((Node*) ((constFunctionParameter*)expr)->argType);
1726+
loc= ((constFunctionParameter*)expr)->location;
17281727
break;
17291728
caseT_XmlSerialize:
17301729
/* XMLSERIALIZE keyword should always be the first thing */

‎src/backend/parser/gram.y

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ static Node *makeSQLValueFunction(SQLValueFunctionOp op, int32 typmod,
184184
int location);
185185
static Node *makeXmlExpr(XmlExprOp op,char *name, List *named_args,
186186
List *args,int location);
187-
static List *mergeTableFuncParameters(List *func_args, List *columns);
187+
static List *mergeTableFuncParameters(List *func_args, List *columns,core_yyscan_t yyscanner);
188188
static TypeName *TableFuncTypeName(List *columns);
189189
static RangeVar *makeRangeVarFromAnyName(List *names,int position,core_yyscan_t yyscanner);
190190
static RangeVar *makeRangeVarFromQualifiedName(char *name, List *namelist,int location,
@@ -8290,7 +8290,7 @@ CreateFunctionStmt:
82908290
n->is_procedure =false;
82918291
n->replace =$2;
82928292
n->funcname =$4;
8293-
n->parameters = mergeTableFuncParameters($5,$9);
8293+
n->parameters = mergeTableFuncParameters($5,$9, yyscanner);
82948294
n->returnType = TableFuncTypeName($9);
82958295
n->returnType->location =@7;
82968296
n->options =$11;
@@ -8423,6 +8423,7 @@ func_arg:
84238423
n->argType =$3;
84248424
n->mode =$1;
84258425
n->defexpr =NULL;
8426+
n->location =@1;
84268427
$$ = n;
84278428
}
84288429
|param_namearg_classfunc_type
@@ -8433,6 +8434,7 @@ func_arg:
84338434
n->argType =$3;
84348435
n->mode =$2;
84358436
n->defexpr =NULL;
8437+
n->location =@1;
84368438
$$ = n;
84378439
}
84388440
|param_namefunc_type
@@ -8443,6 +8445,7 @@ func_arg:
84438445
n->argType =$2;
84448446
n->mode = FUNC_PARAM_DEFAULT;
84458447
n->defexpr =NULL;
8448+
n->location =@1;
84468449
$$ = n;
84478450
}
84488451
|arg_classfunc_type
@@ -8453,6 +8456,7 @@ func_arg:
84538456
n->argType =$2;
84548457
n->mode =$1;
84558458
n->defexpr =NULL;
8459+
n->location =@1;
84568460
$$ = n;
84578461
}
84588462
|func_type
@@ -8463,6 +8467,7 @@ func_arg:
84638467
n->argType =$1;
84648468
n->mode = FUNC_PARAM_DEFAULT;
84658469
n->defexpr =NULL;
8470+
n->location =@1;
84668471
$$ = n;
84678472
}
84688473
;
@@ -8799,6 +8804,7 @@ table_func_column:param_name func_type
87998804
n->argType =$2;
88008805
n->mode = FUNC_PARAM_TABLE;
88018806
n->defexpr =NULL;
8807+
n->location =@1;
88028808
$$ = n;
88038809
}
88048810
;
@@ -18908,7 +18914,7 @@ makeOrderedSetArgs(List *directargs, List *orderedargs,
1890818914
ereport(ERROR,
1890918915
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1891018916
errmsg("an ordered-set aggregate with a VARIADIC direct argument must have one VARIADIC aggregated argument of the same data type"),
18911-
parser_errposition(exprLocation((Node *)firsto))));
18917+
parser_errposition(firsto->location)));
1891218918

1891318919
/* OK, drop the duplicate VARIADIC argument from the internal form*/
1891418920
orderedargs = NIL;
@@ -19183,7 +19189,7 @@ makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args,
1918319189
* Merge the input and output parameters of a table function.
1918419190
*/
1918519191
static List *
19186-
mergeTableFuncParameters(List *func_args, List *columns)
19192+
mergeTableFuncParameters(List *func_args, List *columns, core_yyscan_t yyscanner)
1918719193
{
1918819194
ListCell *lc;
1918919195

@@ -19197,7 +19203,8 @@ mergeTableFuncParameters(List *func_args, List *columns)
1919719203
p->mode != FUNC_PARAM_VARIADIC)
1919819204
ereport(ERROR,
1919919205
(errcode(ERRCODE_SYNTAX_ERROR),
19200-
errmsg("OUT and INOUT arguments aren't allowed in TABLE functions")));
19206+
errmsg("OUT and INOUT arguments aren't allowed in TABLE functions"),
19207+
parser_errposition(p->location)));
1920119208
}
1920219209

1920319210
return list_concat(func_args, columns);

‎src/include/catalog/catversion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,6 @@
5757
*/
5858

5959
/*yyyymmddN */
60-
#defineCATALOG_VERSION_NO202410242
60+
#defineCATALOG_VERSION_NO202410311
6161

6262
#endif

‎src/include/nodes/parsenodes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3482,6 +3482,7 @@ typedef struct FunctionParameter
34823482
TypeName*argType;/* TypeName for parameter type */
34833483
FunctionParameterModemode;/* IN/OUT/etc */
34843484
Node*defexpr;/* raw default expr, or NULL if not given */
3485+
ParseLoclocation;/* token location, or -1 if unknown */
34853486
}FunctionParameter;
34863487

34873488
typedefstructAlterFunctionStmt

‎src/test/modules/test_ddl_deparse/expected/create_type.out

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ CREATE FUNCTION text_w_default_out(text_w_default)
1313
AS 'textout'
1414
LANGUAGE internal STABLE STRICT ;
1515
NOTICE: argument type text_w_default is only a shell
16+
LINE 1: CREATE FUNCTION text_w_default_out(text_w_default)
17+
^
1618
NOTICE: DDL test: type simple, tag CREATE FUNCTION
1719
CREATE TYPE employee_type AS (name TEXT, salary NUMERIC);
1820
NOTICE: DDL test: type simple, tag CREATE TYPE

‎src/test/modules/test_ddl_deparse/expected/opfamily.out

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ NOTICE: DDL test: type simple, tag CREATE FUNCTION
88
create function int8alias1out(int8alias1) returns cstring
99
strict immutable language internal as 'int8out';
1010
NOTICE: argument type int8alias1 is only a shell
11+
LINE 1: create function int8alias1out(int8alias1) returns cstring
12+
^
1113
NOTICE: DDL test: type simple, tag CREATE FUNCTION
1214
create type int8alias1 (
1315
input = int8alias1in,
@@ -24,6 +26,8 @@ NOTICE: DDL test: type simple, tag CREATE FUNCTION
2426
create function int8alias2out(int8alias2) returns cstring
2527
strict immutable language internal as 'int8out';
2628
NOTICE: argument type int8alias2 is only a shell
29+
LINE 1: create function int8alias2out(int8alias2) returns cstring
30+
^
2731
NOTICE: DDL test: type simple, tag CREATE FUNCTION
2832
create type int8alias2 (
2933
input = int8alias2in,

‎src/test/modules/test_pg_dump/expected/test_pg_dump.out

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ CREATE FUNCTION casttesttype_out(casttesttype)
3636
AS 'textout'
3737
LANGUAGE internal STRICT IMMUTABLE;
3838
NOTICE: argument type casttesttype is only a shell
39+
LINE 1: CREATE FUNCTION casttesttype_out(casttesttype)
40+
^
3941
CREATE TYPE casttesttype (
4042
internallength = variable,
4143
input = casttesttype_in,

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ CREATE FUNCTION casttesttype_out(casttesttype)
1313
AS 'textout'
1414
LANGUAGE internal STRICT IMMUTABLE;
1515
NOTICE: argument type casttesttype is only a shell
16+
LINE 1: CREATE FUNCTION casttesttype_out(casttesttype)
17+
^
1618
CREATE TYPE casttesttype (
1719
internallength = variable,
1820
input = casttesttype_in,

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,9 +401,13 @@ LINE 1: CREATE PROCEDURE ptestx() LANGUAGE SQL STRICT AS $$ INSERT I...
401401
CREATE PROCEDURE ptestx(a VARIADIC int[], b OUT int) LANGUAGE SQL
402402
AS $$ SELECT a[1] $$;
403403
ERROR: VARIADIC parameter must be the last parameter
404+
LINE 1: CREATE PROCEDURE ptestx(a VARIADIC int[], b OUT int) LANGUAG...
405+
^
404406
CREATE PROCEDURE ptestx(a int DEFAULT 42, b OUT int) LANGUAGE SQL
405407
AS $$ SELECT a $$;
406408
ERROR: procedure OUT parameters cannot appear after one with a default value
409+
LINE 1: CREATE PROCEDURE ptestx(a int DEFAULT 42, b OUT int) LANGUAG...
410+
^
407411
ALTER PROCEDURE ptest1(text) STRICT;
408412
ERROR: invalid attribute in procedure definition
409413
LINE 1: ALTER PROCEDURE ptest1(text) STRICT;

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ CREATE FUNCTION widget_out(widget)
2020
AS :'regresslib'
2121
LANGUAGE C STRICT IMMUTABLE;
2222
NOTICE: argument type widget is only a shell
23+
LINE 1: CREATE FUNCTION widget_out(widget)
24+
^
2325
CREATE FUNCTION int44in(cstring)
2426
RETURNS city_budget
2527
AS :'regresslib'
@@ -31,6 +33,8 @@ CREATE FUNCTION int44out(city_budget)
3133
AS :'regresslib'
3234
LANGUAGE C STRICT IMMUTABLE;
3335
NOTICE: argument type city_budget is only a shell
36+
LINE 1: CREATE FUNCTION int44out(city_budget)
37+
^
3438
CREATE TYPE widget (
3539
internallength = 24,
3640
input = widget_in,
@@ -75,6 +79,8 @@ CREATE FUNCTION int42_out(int42)
7579
AS 'int4out'
7680
LANGUAGE internal STRICT IMMUTABLE;
7781
NOTICE: argument type int42 is only a shell
82+
LINE 1: CREATE FUNCTION int42_out(int42)
83+
^
7884
CREATE FUNCTION text_w_default_in(cstring)
7985
RETURNS text_w_default
8086
AS 'textin'
@@ -85,6 +91,8 @@ CREATE FUNCTION text_w_default_out(text_w_default)
8591
AS 'textout'
8692
LANGUAGE internal STRICT IMMUTABLE;
8793
NOTICE: argument type text_w_default is only a shell
94+
LINE 1: CREATE FUNCTION text_w_default_out(text_w_default)
95+
^
8896
CREATE TYPE int42 (
8997
internallength = 4,
9098
input = int42_in,
@@ -186,6 +194,8 @@ NOTICE: return type base_type is only a shell
186194
CREATE FUNCTION base_fn_out(base_type) RETURNS cstring AS 'boolout'
187195
LANGUAGE internal IMMUTABLE STRICT;
188196
NOTICE: argument type base_type is only a shell
197+
LINE 1: CREATE FUNCTION base_fn_out(base_type) RETURNS cstring AS 'b...
198+
^
189199
CREATE TYPE base_type(INPUT = base_fn_in, OUTPUT = base_fn_out);
190200
DROP FUNCTION base_fn_in(cstring); -- error
191201
ERROR: cannot drop function base_fn_in(cstring) because other objects depend on it
@@ -320,9 +330,13 @@ NOTICE: return type myvarchar is only a shell
320330
CREATE FUNCTION myvarcharout(myvarchar) RETURNS cstring
321331
LANGUAGE internal IMMUTABLE PARALLEL SAFE STRICT AS 'varcharout';
322332
NOTICE: argument type myvarchar is only a shell
333+
LINE 1: CREATE FUNCTION myvarcharout(myvarchar) RETURNS cstring
334+
^
323335
CREATE FUNCTION myvarcharsend(myvarchar) RETURNS bytea
324336
LANGUAGE internal STABLE PARALLEL SAFE STRICT AS 'varcharsend';
325337
NOTICE: argument type myvarchar is only a shell
338+
LINE 1: CREATE FUNCTION myvarcharsend(myvarchar) RETURNS bytea
339+
^
326340
CREATE FUNCTION myvarcharrecv(internal, oid, integer) RETURNS myvarchar
327341
LANGUAGE internal STABLE PARALLEL SAFE STRICT AS 'varcharrecv';
328342
NOTICE: return type myvarchar is only a shell

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp