mirror of
https://github.com/postgres/postgres.git
synced 2025-06-19 04:21:08 +03:00
Add a parse location field to struct FunctionParameter.
This allows an error cursor to be supplied for a bunch of bad-function-definition errors that previously lacked one, or that cheated a bit by pointing at the contained type name when the error isn't really about that. Bump catversion from an abundance of caution --- I don't think this node type can actually appear in stored views/rules, but better 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
This commit is contained in:
@ -232,7 +232,7 @@ interpret_function_parameter_list(ParseState *pstate,
|
|||||||
if (fpmode == FUNC_PARAM_DEFAULT)
|
if (fpmode == FUNC_PARAM_DEFAULT)
|
||||||
fpmode = FUNC_PARAM_IN;
|
fpmode = FUNC_PARAM_IN;
|
||||||
|
|
||||||
typtup = LookupTypeName(NULL, t, NULL, false);
|
typtup = LookupTypeName(pstate, t, NULL, false);
|
||||||
if (typtup)
|
if (typtup)
|
||||||
{
|
{
|
||||||
if (!((Form_pg_type) GETSTRUCT(typtup))->typisdefined)
|
if (!((Form_pg_type) GETSTRUCT(typtup))->typisdefined)
|
||||||
@ -242,18 +242,21 @@ interpret_function_parameter_list(ParseState *pstate,
|
|||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
|
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
|
||||||
errmsg("SQL function cannot accept shell type %s",
|
errmsg("SQL function cannot accept shell type %s",
|
||||||
TypeNameToString(t))));
|
TypeNameToString(t)),
|
||||||
|
parser_errposition(pstate, t->location)));
|
||||||
/* We don't allow creating aggregates on shell types either */
|
/* We don't allow creating aggregates on shell types either */
|
||||||
else if (objtype == OBJECT_AGGREGATE)
|
else if (objtype == OBJECT_AGGREGATE)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
|
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
|
||||||
errmsg("aggregate cannot accept shell type %s",
|
errmsg("aggregate cannot accept shell type %s",
|
||||||
TypeNameToString(t))));
|
TypeNameToString(t)),
|
||||||
|
parser_errposition(pstate, t->location)));
|
||||||
else
|
else
|
||||||
ereport(NOTICE,
|
ereport(NOTICE,
|
||||||
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
|
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
|
||||||
errmsg("argument type %s is only a shell",
|
errmsg("argument type %s is only a shell",
|
||||||
TypeNameToString(t))));
|
TypeNameToString(t)),
|
||||||
|
parser_errposition(pstate, t->location)));
|
||||||
}
|
}
|
||||||
toid = typeTypeId(typtup);
|
toid = typeTypeId(typtup);
|
||||||
ReleaseSysCache(typtup);
|
ReleaseSysCache(typtup);
|
||||||
@ -263,7 +266,8 @@ interpret_function_parameter_list(ParseState *pstate,
|
|||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||||
errmsg("type %s does not exist",
|
errmsg("type %s does not exist",
|
||||||
TypeNameToString(t))));
|
TypeNameToString(t)),
|
||||||
|
parser_errposition(pstate, t->location)));
|
||||||
toid = InvalidOid; /* keep compiler quiet */
|
toid = InvalidOid; /* keep compiler quiet */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,15 +280,18 @@ interpret_function_parameter_list(ParseState *pstate,
|
|||||||
if (objtype == OBJECT_AGGREGATE)
|
if (objtype == OBJECT_AGGREGATE)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
|
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
|
||||||
errmsg("aggregates cannot accept set arguments")));
|
errmsg("aggregates cannot accept set arguments"),
|
||||||
|
parser_errposition(pstate, fp->location)));
|
||||||
else if (objtype == OBJECT_PROCEDURE)
|
else if (objtype == OBJECT_PROCEDURE)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
|
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
|
||||||
errmsg("procedures cannot accept set arguments")));
|
errmsg("procedures cannot accept set arguments"),
|
||||||
|
parser_errposition(pstate, fp->location)));
|
||||||
else
|
else
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
|
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
|
||||||
errmsg("functions cannot accept set arguments")));
|
errmsg("functions cannot accept set arguments"),
|
||||||
|
parser_errposition(pstate, fp->location)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* handle input parameters */
|
/* handle input parameters */
|
||||||
@ -294,7 +301,8 @@ interpret_function_parameter_list(ParseState *pstate,
|
|||||||
if (varCount > 0)
|
if (varCount > 0)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
|
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
|
||||||
errmsg("VARIADIC parameter must be the last input parameter")));
|
errmsg("VARIADIC parameter must be the last input parameter"),
|
||||||
|
parser_errposition(pstate, fp->location)));
|
||||||
inTypes[inCount++] = toid;
|
inTypes[inCount++] = toid;
|
||||||
isinput = true;
|
isinput = true;
|
||||||
if (parameterTypes_list)
|
if (parameterTypes_list)
|
||||||
@ -314,7 +322,8 @@ interpret_function_parameter_list(ParseState *pstate,
|
|||||||
if (varCount > 0)
|
if (varCount > 0)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
|
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
|
||||||
errmsg("VARIADIC parameter must be the last parameter")));
|
errmsg("VARIADIC parameter must be the last parameter"),
|
||||||
|
parser_errposition(pstate, fp->location)));
|
||||||
/* Procedures with output parameters always return RECORD */
|
/* Procedures with output parameters always return RECORD */
|
||||||
*requiredResultType = RECORDOID;
|
*requiredResultType = RECORDOID;
|
||||||
}
|
}
|
||||||
@ -339,7 +348,8 @@ interpret_function_parameter_list(ParseState *pstate,
|
|||||||
if (!OidIsValid(get_element_type(toid)))
|
if (!OidIsValid(get_element_type(toid)))
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
|
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
|
||||||
errmsg("VARIADIC parameter must be an array")));
|
errmsg("VARIADIC parameter must be an array"),
|
||||||
|
parser_errposition(pstate, fp->location)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -385,7 +395,8 @@ interpret_function_parameter_list(ParseState *pstate,
|
|||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
|
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
|
||||||
errmsg("parameter name \"%s\" used more than once",
|
errmsg("parameter name \"%s\" used more than once",
|
||||||
fp->name)));
|
fp->name),
|
||||||
|
parser_errposition(pstate, fp->location)));
|
||||||
}
|
}
|
||||||
|
|
||||||
paramNames[i] = CStringGetTextDatum(fp->name);
|
paramNames[i] = CStringGetTextDatum(fp->name);
|
||||||
@ -402,7 +413,8 @@ interpret_function_parameter_list(ParseState *pstate,
|
|||||||
if (!isinput)
|
if (!isinput)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
|
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
|
||||||
errmsg("only input parameters can have default values")));
|
errmsg("only input parameters can have default values"),
|
||||||
|
parser_errposition(pstate, fp->location)));
|
||||||
|
|
||||||
def = transformExpr(pstate, fp->defexpr,
|
def = transformExpr(pstate, fp->defexpr,
|
||||||
EXPR_KIND_FUNCTION_DEFAULT);
|
EXPR_KIND_FUNCTION_DEFAULT);
|
||||||
@ -417,7 +429,8 @@ interpret_function_parameter_list(ParseState *pstate,
|
|||||||
contain_var_clause(def))
|
contain_var_clause(def))
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
|
(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
|
||||||
errmsg("cannot use table references in parameter default value")));
|
errmsg("cannot use table references in parameter default value"),
|
||||||
|
parser_errposition(pstate, fp->location)));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* transformExpr() should have already rejected subqueries,
|
* transformExpr() should have already rejected subqueries,
|
||||||
@ -441,7 +454,8 @@ interpret_function_parameter_list(ParseState *pstate,
|
|||||||
if (isinput && have_defaults)
|
if (isinput && have_defaults)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
|
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
|
||||||
errmsg("input parameters after one with a default value must also have defaults")));
|
errmsg("input parameters after one with a default value must also have defaults"),
|
||||||
|
parser_errposition(pstate, fp->location)));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For procedures, we also can't allow OUT parameters after one
|
* For procedures, we also can't allow OUT parameters after one
|
||||||
@ -451,7 +465,8 @@ interpret_function_parameter_list(ParseState *pstate,
|
|||||||
if (objtype == OBJECT_PROCEDURE && have_defaults)
|
if (objtype == OBJECT_PROCEDURE && have_defaults)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
|
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
|
||||||
errmsg("procedure OUT parameters cannot appear after one with a default value")));
|
errmsg("procedure OUT parameters cannot appear after one with a default value"),
|
||||||
|
parser_errposition(pstate, fp->location)));
|
||||||
}
|
}
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
|
@ -1723,8 +1723,7 @@ exprLocation(const Node *expr)
|
|||||||
loc = ((const Constraint *) expr)->location;
|
loc = ((const Constraint *) expr)->location;
|
||||||
break;
|
break;
|
||||||
case T_FunctionParameter:
|
case T_FunctionParameter:
|
||||||
/* just use typename's location */
|
loc = ((const FunctionParameter *) expr)->location;
|
||||||
loc = exprLocation((Node *) ((const FunctionParameter *) expr)->argType);
|
|
||||||
break;
|
break;
|
||||||
case T_XmlSerialize:
|
case T_XmlSerialize:
|
||||||
/* XMLSERIALIZE keyword should always be the first thing */
|
/* XMLSERIALIZE keyword should always be the first thing */
|
||||||
|
@ -184,7 +184,7 @@ static Node *makeSQLValueFunction(SQLValueFunctionOp op, int32 typmod,
|
|||||||
int location);
|
int location);
|
||||||
static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args,
|
static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args,
|
||||||
List *args, int location);
|
List *args, int location);
|
||||||
static List *mergeTableFuncParameters(List *func_args, List *columns);
|
static List *mergeTableFuncParameters(List *func_args, List *columns, core_yyscan_t yyscanner);
|
||||||
static TypeName *TableFuncTypeName(List *columns);
|
static TypeName *TableFuncTypeName(List *columns);
|
||||||
static RangeVar *makeRangeVarFromAnyName(List *names, int position, core_yyscan_t yyscanner);
|
static RangeVar *makeRangeVarFromAnyName(List *names, int position, core_yyscan_t yyscanner);
|
||||||
static RangeVar *makeRangeVarFromQualifiedName(char *name, List *namelist, int location,
|
static RangeVar *makeRangeVarFromQualifiedName(char *name, List *namelist, int location,
|
||||||
@ -8290,7 +8290,7 @@ CreateFunctionStmt:
|
|||||||
n->is_procedure = false;
|
n->is_procedure = false;
|
||||||
n->replace = $2;
|
n->replace = $2;
|
||||||
n->funcname = $4;
|
n->funcname = $4;
|
||||||
n->parameters = mergeTableFuncParameters($5, $9);
|
n->parameters = mergeTableFuncParameters($5, $9, yyscanner);
|
||||||
n->returnType = TableFuncTypeName($9);
|
n->returnType = TableFuncTypeName($9);
|
||||||
n->returnType->location = @7;
|
n->returnType->location = @7;
|
||||||
n->options = $11;
|
n->options = $11;
|
||||||
@ -8423,6 +8423,7 @@ func_arg:
|
|||||||
n->argType = $3;
|
n->argType = $3;
|
||||||
n->mode = $1;
|
n->mode = $1;
|
||||||
n->defexpr = NULL;
|
n->defexpr = NULL;
|
||||||
|
n->location = @1;
|
||||||
$$ = n;
|
$$ = n;
|
||||||
}
|
}
|
||||||
| param_name arg_class func_type
|
| param_name arg_class func_type
|
||||||
@ -8433,6 +8434,7 @@ func_arg:
|
|||||||
n->argType = $3;
|
n->argType = $3;
|
||||||
n->mode = $2;
|
n->mode = $2;
|
||||||
n->defexpr = NULL;
|
n->defexpr = NULL;
|
||||||
|
n->location = @1;
|
||||||
$$ = n;
|
$$ = n;
|
||||||
}
|
}
|
||||||
| param_name func_type
|
| param_name func_type
|
||||||
@ -8443,6 +8445,7 @@ func_arg:
|
|||||||
n->argType = $2;
|
n->argType = $2;
|
||||||
n->mode = FUNC_PARAM_DEFAULT;
|
n->mode = FUNC_PARAM_DEFAULT;
|
||||||
n->defexpr = NULL;
|
n->defexpr = NULL;
|
||||||
|
n->location = @1;
|
||||||
$$ = n;
|
$$ = n;
|
||||||
}
|
}
|
||||||
| arg_class func_type
|
| arg_class func_type
|
||||||
@ -8453,6 +8456,7 @@ func_arg:
|
|||||||
n->argType = $2;
|
n->argType = $2;
|
||||||
n->mode = $1;
|
n->mode = $1;
|
||||||
n->defexpr = NULL;
|
n->defexpr = NULL;
|
||||||
|
n->location = @1;
|
||||||
$$ = n;
|
$$ = n;
|
||||||
}
|
}
|
||||||
| func_type
|
| func_type
|
||||||
@ -8463,6 +8467,7 @@ func_arg:
|
|||||||
n->argType = $1;
|
n->argType = $1;
|
||||||
n->mode = FUNC_PARAM_DEFAULT;
|
n->mode = FUNC_PARAM_DEFAULT;
|
||||||
n->defexpr = NULL;
|
n->defexpr = NULL;
|
||||||
|
n->location = @1;
|
||||||
$$ = n;
|
$$ = n;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@ -8799,6 +8804,7 @@ table_func_column: param_name func_type
|
|||||||
n->argType = $2;
|
n->argType = $2;
|
||||||
n->mode = FUNC_PARAM_TABLE;
|
n->mode = FUNC_PARAM_TABLE;
|
||||||
n->defexpr = NULL;
|
n->defexpr = NULL;
|
||||||
|
n->location = @1;
|
||||||
$$ = n;
|
$$ = n;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@ -18908,7 +18914,7 @@ makeOrderedSetArgs(List *directargs, List *orderedargs,
|
|||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||||
errmsg("an ordered-set aggregate with a VARIADIC direct argument must have one VARIADIC aggregated argument of the same data type"),
|
errmsg("an ordered-set aggregate with a VARIADIC direct argument must have one VARIADIC aggregated argument of the same data type"),
|
||||||
parser_errposition(exprLocation((Node *) firsto))));
|
parser_errposition(firsto->location)));
|
||||||
|
|
||||||
/* OK, drop the duplicate VARIADIC argument from the internal form */
|
/* OK, drop the duplicate VARIADIC argument from the internal form */
|
||||||
orderedargs = NIL;
|
orderedargs = NIL;
|
||||||
@ -19183,7 +19189,7 @@ makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args,
|
|||||||
* Merge the input and output parameters of a table function.
|
* Merge the input and output parameters of a table function.
|
||||||
*/
|
*/
|
||||||
static List *
|
static List *
|
||||||
mergeTableFuncParameters(List *func_args, List *columns)
|
mergeTableFuncParameters(List *func_args, List *columns, core_yyscan_t yyscanner)
|
||||||
{
|
{
|
||||||
ListCell *lc;
|
ListCell *lc;
|
||||||
|
|
||||||
@ -19197,7 +19203,8 @@ mergeTableFuncParameters(List *func_args, List *columns)
|
|||||||
p->mode != FUNC_PARAM_VARIADIC)
|
p->mode != FUNC_PARAM_VARIADIC)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_SYNTAX_ERROR),
|
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||||
errmsg("OUT and INOUT arguments aren't allowed in TABLE functions")));
|
errmsg("OUT and INOUT arguments aren't allowed in TABLE functions"),
|
||||||
|
parser_errposition(p->location)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return list_concat(func_args, columns);
|
return list_concat(func_args, columns);
|
||||||
|
@ -57,6 +57,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* yyyymmddN */
|
/* yyyymmddN */
|
||||||
#define CATALOG_VERSION_NO 202410242
|
#define CATALOG_VERSION_NO 202410311
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -3482,6 +3482,7 @@ typedef struct FunctionParameter
|
|||||||
TypeName *argType; /* TypeName for parameter type */
|
TypeName *argType; /* TypeName for parameter type */
|
||||||
FunctionParameterMode mode; /* IN/OUT/etc */
|
FunctionParameterMode mode; /* IN/OUT/etc */
|
||||||
Node *defexpr; /* raw default expr, or NULL if not given */
|
Node *defexpr; /* raw default expr, or NULL if not given */
|
||||||
|
ParseLoc location; /* token location, or -1 if unknown */
|
||||||
} FunctionParameter;
|
} FunctionParameter;
|
||||||
|
|
||||||
typedef struct AlterFunctionStmt
|
typedef struct AlterFunctionStmt
|
||||||
|
@ -13,6 +13,8 @@ CREATE FUNCTION text_w_default_out(text_w_default)
|
|||||||
AS 'textout'
|
AS 'textout'
|
||||||
LANGUAGE internal STABLE STRICT ;
|
LANGUAGE internal STABLE STRICT ;
|
||||||
NOTICE: argument type text_w_default is only a shell
|
NOTICE: argument type text_w_default is only a shell
|
||||||
|
LINE 1: CREATE FUNCTION text_w_default_out(text_w_default)
|
||||||
|
^
|
||||||
NOTICE: DDL test: type simple, tag CREATE FUNCTION
|
NOTICE: DDL test: type simple, tag CREATE FUNCTION
|
||||||
CREATE TYPE employee_type AS (name TEXT, salary NUMERIC);
|
CREATE TYPE employee_type AS (name TEXT, salary NUMERIC);
|
||||||
NOTICE: DDL test: type simple, tag CREATE TYPE
|
NOTICE: DDL test: type simple, tag CREATE TYPE
|
||||||
|
@ -8,6 +8,8 @@ NOTICE: DDL test: type simple, tag CREATE FUNCTION
|
|||||||
create function int8alias1out(int8alias1) returns cstring
|
create function int8alias1out(int8alias1) returns cstring
|
||||||
strict immutable language internal as 'int8out';
|
strict immutable language internal as 'int8out';
|
||||||
NOTICE: argument type int8alias1 is only a shell
|
NOTICE: argument type int8alias1 is only a shell
|
||||||
|
LINE 1: create function int8alias1out(int8alias1) returns cstring
|
||||||
|
^
|
||||||
NOTICE: DDL test: type simple, tag CREATE FUNCTION
|
NOTICE: DDL test: type simple, tag CREATE FUNCTION
|
||||||
create type int8alias1 (
|
create type int8alias1 (
|
||||||
input = int8alias1in,
|
input = int8alias1in,
|
||||||
@ -24,6 +26,8 @@ NOTICE: DDL test: type simple, tag CREATE FUNCTION
|
|||||||
create function int8alias2out(int8alias2) returns cstring
|
create function int8alias2out(int8alias2) returns cstring
|
||||||
strict immutable language internal as 'int8out';
|
strict immutable language internal as 'int8out';
|
||||||
NOTICE: argument type int8alias2 is only a shell
|
NOTICE: argument type int8alias2 is only a shell
|
||||||
|
LINE 1: create function int8alias2out(int8alias2) returns cstring
|
||||||
|
^
|
||||||
NOTICE: DDL test: type simple, tag CREATE FUNCTION
|
NOTICE: DDL test: type simple, tag CREATE FUNCTION
|
||||||
create type int8alias2 (
|
create type int8alias2 (
|
||||||
input = int8alias2in,
|
input = int8alias2in,
|
||||||
|
@ -36,6 +36,8 @@ CREATE FUNCTION casttesttype_out(casttesttype)
|
|||||||
AS 'textout'
|
AS 'textout'
|
||||||
LANGUAGE internal STRICT IMMUTABLE;
|
LANGUAGE internal STRICT IMMUTABLE;
|
||||||
NOTICE: argument type casttesttype is only a shell
|
NOTICE: argument type casttesttype is only a shell
|
||||||
|
LINE 1: CREATE FUNCTION casttesttype_out(casttesttype)
|
||||||
|
^
|
||||||
CREATE TYPE casttesttype (
|
CREATE TYPE casttesttype (
|
||||||
internallength = variable,
|
internallength = variable,
|
||||||
input = casttesttype_in,
|
input = casttesttype_in,
|
||||||
|
@ -13,6 +13,8 @@ CREATE FUNCTION casttesttype_out(casttesttype)
|
|||||||
AS 'textout'
|
AS 'textout'
|
||||||
LANGUAGE internal STRICT IMMUTABLE;
|
LANGUAGE internal STRICT IMMUTABLE;
|
||||||
NOTICE: argument type casttesttype is only a shell
|
NOTICE: argument type casttesttype is only a shell
|
||||||
|
LINE 1: CREATE FUNCTION casttesttype_out(casttesttype)
|
||||||
|
^
|
||||||
CREATE TYPE casttesttype (
|
CREATE TYPE casttesttype (
|
||||||
internallength = variable,
|
internallength = variable,
|
||||||
input = casttesttype_in,
|
input = casttesttype_in,
|
||||||
|
@ -401,9 +401,13 @@ LINE 1: CREATE PROCEDURE ptestx() LANGUAGE SQL STRICT AS $$ INSERT I...
|
|||||||
CREATE PROCEDURE ptestx(a VARIADIC int[], b OUT int) LANGUAGE SQL
|
CREATE PROCEDURE ptestx(a VARIADIC int[], b OUT int) LANGUAGE SQL
|
||||||
AS $$ SELECT a[1] $$;
|
AS $$ SELECT a[1] $$;
|
||||||
ERROR: VARIADIC parameter must be the last parameter
|
ERROR: VARIADIC parameter must be the last parameter
|
||||||
|
LINE 1: CREATE PROCEDURE ptestx(a VARIADIC int[], b OUT int) LANGUAG...
|
||||||
|
^
|
||||||
CREATE PROCEDURE ptestx(a int DEFAULT 42, b OUT int) LANGUAGE SQL
|
CREATE PROCEDURE ptestx(a int DEFAULT 42, b OUT int) LANGUAGE SQL
|
||||||
AS $$ SELECT a $$;
|
AS $$ SELECT a $$;
|
||||||
ERROR: procedure OUT parameters cannot appear after one with a default value
|
ERROR: procedure OUT parameters cannot appear after one with a default value
|
||||||
|
LINE 1: CREATE PROCEDURE ptestx(a int DEFAULT 42, b OUT int) LANGUAG...
|
||||||
|
^
|
||||||
ALTER PROCEDURE ptest1(text) STRICT;
|
ALTER PROCEDURE ptest1(text) STRICT;
|
||||||
ERROR: invalid attribute in procedure definition
|
ERROR: invalid attribute in procedure definition
|
||||||
LINE 1: ALTER PROCEDURE ptest1(text) STRICT;
|
LINE 1: ALTER PROCEDURE ptest1(text) STRICT;
|
||||||
|
@ -20,6 +20,8 @@ CREATE FUNCTION widget_out(widget)
|
|||||||
AS :'regresslib'
|
AS :'regresslib'
|
||||||
LANGUAGE C STRICT IMMUTABLE;
|
LANGUAGE C STRICT IMMUTABLE;
|
||||||
NOTICE: argument type widget is only a shell
|
NOTICE: argument type widget is only a shell
|
||||||
|
LINE 1: CREATE FUNCTION widget_out(widget)
|
||||||
|
^
|
||||||
CREATE FUNCTION int44in(cstring)
|
CREATE FUNCTION int44in(cstring)
|
||||||
RETURNS city_budget
|
RETURNS city_budget
|
||||||
AS :'regresslib'
|
AS :'regresslib'
|
||||||
@ -31,6 +33,8 @@ CREATE FUNCTION int44out(city_budget)
|
|||||||
AS :'regresslib'
|
AS :'regresslib'
|
||||||
LANGUAGE C STRICT IMMUTABLE;
|
LANGUAGE C STRICT IMMUTABLE;
|
||||||
NOTICE: argument type city_budget is only a shell
|
NOTICE: argument type city_budget is only a shell
|
||||||
|
LINE 1: CREATE FUNCTION int44out(city_budget)
|
||||||
|
^
|
||||||
CREATE TYPE widget (
|
CREATE TYPE widget (
|
||||||
internallength = 24,
|
internallength = 24,
|
||||||
input = widget_in,
|
input = widget_in,
|
||||||
@ -75,6 +79,8 @@ CREATE FUNCTION int42_out(int42)
|
|||||||
AS 'int4out'
|
AS 'int4out'
|
||||||
LANGUAGE internal STRICT IMMUTABLE;
|
LANGUAGE internal STRICT IMMUTABLE;
|
||||||
NOTICE: argument type int42 is only a shell
|
NOTICE: argument type int42 is only a shell
|
||||||
|
LINE 1: CREATE FUNCTION int42_out(int42)
|
||||||
|
^
|
||||||
CREATE FUNCTION text_w_default_in(cstring)
|
CREATE FUNCTION text_w_default_in(cstring)
|
||||||
RETURNS text_w_default
|
RETURNS text_w_default
|
||||||
AS 'textin'
|
AS 'textin'
|
||||||
@ -85,6 +91,8 @@ CREATE FUNCTION text_w_default_out(text_w_default)
|
|||||||
AS 'textout'
|
AS 'textout'
|
||||||
LANGUAGE internal STRICT IMMUTABLE;
|
LANGUAGE internal STRICT IMMUTABLE;
|
||||||
NOTICE: argument type text_w_default is only a shell
|
NOTICE: argument type text_w_default is only a shell
|
||||||
|
LINE 1: CREATE FUNCTION text_w_default_out(text_w_default)
|
||||||
|
^
|
||||||
CREATE TYPE int42 (
|
CREATE TYPE int42 (
|
||||||
internallength = 4,
|
internallength = 4,
|
||||||
input = int42_in,
|
input = int42_in,
|
||||||
@ -186,6 +194,8 @@ NOTICE: return type base_type is only a shell
|
|||||||
CREATE FUNCTION base_fn_out(base_type) RETURNS cstring AS 'boolout'
|
CREATE FUNCTION base_fn_out(base_type) RETURNS cstring AS 'boolout'
|
||||||
LANGUAGE internal IMMUTABLE STRICT;
|
LANGUAGE internal IMMUTABLE STRICT;
|
||||||
NOTICE: argument type base_type is only a shell
|
NOTICE: argument type base_type is only a shell
|
||||||
|
LINE 1: CREATE FUNCTION base_fn_out(base_type) RETURNS cstring AS 'b...
|
||||||
|
^
|
||||||
CREATE TYPE base_type(INPUT = base_fn_in, OUTPUT = base_fn_out);
|
CREATE TYPE base_type(INPUT = base_fn_in, OUTPUT = base_fn_out);
|
||||||
DROP FUNCTION base_fn_in(cstring); -- error
|
DROP FUNCTION base_fn_in(cstring); -- error
|
||||||
ERROR: cannot drop function base_fn_in(cstring) because other objects depend on it
|
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
|
|||||||
CREATE FUNCTION myvarcharout(myvarchar) RETURNS cstring
|
CREATE FUNCTION myvarcharout(myvarchar) RETURNS cstring
|
||||||
LANGUAGE internal IMMUTABLE PARALLEL SAFE STRICT AS 'varcharout';
|
LANGUAGE internal IMMUTABLE PARALLEL SAFE STRICT AS 'varcharout';
|
||||||
NOTICE: argument type myvarchar is only a shell
|
NOTICE: argument type myvarchar is only a shell
|
||||||
|
LINE 1: CREATE FUNCTION myvarcharout(myvarchar) RETURNS cstring
|
||||||
|
^
|
||||||
CREATE FUNCTION myvarcharsend(myvarchar) RETURNS bytea
|
CREATE FUNCTION myvarcharsend(myvarchar) RETURNS bytea
|
||||||
LANGUAGE internal STABLE PARALLEL SAFE STRICT AS 'varcharsend';
|
LANGUAGE internal STABLE PARALLEL SAFE STRICT AS 'varcharsend';
|
||||||
NOTICE: argument type myvarchar is only a shell
|
NOTICE: argument type myvarchar is only a shell
|
||||||
|
LINE 1: CREATE FUNCTION myvarcharsend(myvarchar) RETURNS bytea
|
||||||
|
^
|
||||||
CREATE FUNCTION myvarcharrecv(internal, oid, integer) RETURNS myvarchar
|
CREATE FUNCTION myvarcharrecv(internal, oid, integer) RETURNS myvarchar
|
||||||
LANGUAGE internal STABLE PARALLEL SAFE STRICT AS 'varcharrecv';
|
LANGUAGE internal STABLE PARALLEL SAFE STRICT AS 'varcharrecv';
|
||||||
NOTICE: return type myvarchar is only a shell
|
NOTICE: return type myvarchar is only a shell
|
||||||
|
@ -16,6 +16,8 @@ NOTICE: return type int8alias1 is only a shell
|
|||||||
create function int8alias1out(int8alias1) returns cstring
|
create function int8alias1out(int8alias1) returns cstring
|
||||||
strict immutable language internal as 'int8out';
|
strict immutable language internal as 'int8out';
|
||||||
NOTICE: argument type int8alias1 is only a shell
|
NOTICE: argument type int8alias1 is only a shell
|
||||||
|
LINE 1: create function int8alias1out(int8alias1) returns cstring
|
||||||
|
^
|
||||||
create type int8alias1 (
|
create type int8alias1 (
|
||||||
input = int8alias1in,
|
input = int8alias1in,
|
||||||
output = int8alias1out,
|
output = int8alias1out,
|
||||||
@ -28,6 +30,8 @@ NOTICE: return type int8alias2 is only a shell
|
|||||||
create function int8alias2out(int8alias2) returns cstring
|
create function int8alias2out(int8alias2) returns cstring
|
||||||
strict immutable language internal as 'int8out';
|
strict immutable language internal as 'int8out';
|
||||||
NOTICE: argument type int8alias2 is only a shell
|
NOTICE: argument type int8alias2 is only a shell
|
||||||
|
LINE 1: create function int8alias2out(int8alias2) returns cstring
|
||||||
|
^
|
||||||
create type int8alias2 (
|
create type int8alias2 (
|
||||||
input = int8alias2in,
|
input = int8alias2in,
|
||||||
output = int8alias2out,
|
output = int8alias2out,
|
||||||
|
@ -337,9 +337,13 @@ NOTICE: return type myint is only a shell
|
|||||||
create function myintout(myint) returns cstring strict immutable language
|
create function myintout(myint) returns cstring strict immutable language
|
||||||
internal as 'int4out';
|
internal as 'int4out';
|
||||||
NOTICE: argument type myint is only a shell
|
NOTICE: argument type myint is only a shell
|
||||||
|
LINE 1: create function myintout(myint) returns cstring strict immut...
|
||||||
|
^
|
||||||
create function myinthash(myint) returns integer strict immutable language
|
create function myinthash(myint) returns integer strict immutable language
|
||||||
internal as 'hashint4';
|
internal as 'hashint4';
|
||||||
NOTICE: argument type myint is only a shell
|
NOTICE: argument type myint is only a shell
|
||||||
|
LINE 1: create function myinthash(myint) returns integer strict immu...
|
||||||
|
^
|
||||||
create type myint (input = myintin, output = myintout, like = int4);
|
create type myint (input = myintin, output = myintout, like = int4);
|
||||||
create cast (int4 as myint) without function;
|
create cast (int4 as myint) without function;
|
||||||
create cast (myint as int4) without function;
|
create cast (myint as int4) without function;
|
||||||
|
@ -490,6 +490,8 @@ NOTICE: return type xfloat4 is only a shell
|
|||||||
create function xfloat4out(xfloat4) returns cstring immutable strict
|
create function xfloat4out(xfloat4) returns cstring immutable strict
|
||||||
language internal as 'int4out';
|
language internal as 'int4out';
|
||||||
NOTICE: argument type xfloat4 is only a shell
|
NOTICE: argument type xfloat4 is only a shell
|
||||||
|
LINE 1: create function xfloat4out(xfloat4) returns cstring immutabl...
|
||||||
|
^
|
||||||
create type xfloat4 (input = xfloat4in, output = xfloat4out, like = float4);
|
create type xfloat4 (input = xfloat4in, output = xfloat4out, like = float4);
|
||||||
create cast (xfloat4 as float4) without function;
|
create cast (xfloat4 as float4) without function;
|
||||||
create cast (float4 as xfloat4) without function;
|
create cast (float4 as xfloat4) without function;
|
||||||
|
@ -490,6 +490,8 @@ NOTICE: return type xfloat4 is only a shell
|
|||||||
create function xfloat4out(xfloat4) returns cstring immutable strict
|
create function xfloat4out(xfloat4) returns cstring immutable strict
|
||||||
language internal as 'int4out';
|
language internal as 'int4out';
|
||||||
NOTICE: argument type xfloat4 is only a shell
|
NOTICE: argument type xfloat4 is only a shell
|
||||||
|
LINE 1: create function xfloat4out(xfloat4) returns cstring immutabl...
|
||||||
|
^
|
||||||
create type xfloat4 (input = xfloat4in, output = xfloat4out, like = float4);
|
create type xfloat4 (input = xfloat4in, output = xfloat4out, like = float4);
|
||||||
create cast (xfloat4 as float4) without function;
|
create cast (xfloat4 as float4) without function;
|
||||||
create cast (float4 as xfloat4) without function;
|
create cast (float4 as xfloat4) without function;
|
||||||
|
@ -1022,6 +1022,8 @@ NOTICE: return type xfloat8 is only a shell
|
|||||||
create function xfloat8out(xfloat8) returns cstring immutable strict
|
create function xfloat8out(xfloat8) returns cstring immutable strict
|
||||||
language internal as 'int8out';
|
language internal as 'int8out';
|
||||||
NOTICE: argument type xfloat8 is only a shell
|
NOTICE: argument type xfloat8 is only a shell
|
||||||
|
LINE 1: create function xfloat8out(xfloat8) returns cstring immutabl...
|
||||||
|
^
|
||||||
create type xfloat8 (input = xfloat8in, output = xfloat8out, like = float8);
|
create type xfloat8 (input = xfloat8in, output = xfloat8out, like = float8);
|
||||||
create cast (xfloat8 as float8) without function;
|
create cast (xfloat8 as float8) without function;
|
||||||
create cast (float8 as xfloat8) without function;
|
create cast (float8 as xfloat8) without function;
|
||||||
|
@ -1165,6 +1165,8 @@ create function dfunc(a int = 1, b int) returns int as $$
|
|||||||
select $1 + $2;
|
select $1 + $2;
|
||||||
$$ language sql;
|
$$ language sql;
|
||||||
ERROR: input parameters after one with a default value must also have defaults
|
ERROR: input parameters after one with a default value must also have defaults
|
||||||
|
LINE 1: create function dfunc(a int = 1, b int) returns int as $$
|
||||||
|
^
|
||||||
-- however, this should work:
|
-- however, this should work:
|
||||||
create function dfunc(a int = 1, out sum int, b int = 2) as $$
|
create function dfunc(a int = 1, out sum int, b int = 2) as $$
|
||||||
select $1 + $2;
|
select $1 + $2;
|
||||||
@ -1270,6 +1272,8 @@ create function dfunc(out int = 20) returns int as $$
|
|||||||
select 1;
|
select 1;
|
||||||
$$ language sql;
|
$$ language sql;
|
||||||
ERROR: only input parameters can have default values
|
ERROR: only input parameters can have default values
|
||||||
|
LINE 1: create function dfunc(out int = 20) returns int as $$
|
||||||
|
^
|
||||||
-- polymorphic parameter test
|
-- polymorphic parameter test
|
||||||
create function dfunc(anyelement = 'World'::text) returns text as $$
|
create function dfunc(anyelement = 'World'::text) returns text as $$
|
||||||
select 'Hello, ' || $1::text;
|
select 'Hello, ' || $1::text;
|
||||||
@ -1567,12 +1571,20 @@ drop function dfunc(varchar, numeric);
|
|||||||
--fail, named parameters are not unique
|
--fail, named parameters are not unique
|
||||||
create function testpolym(a int, a int) returns int as $$ select 1;$$ language sql;
|
create function testpolym(a int, a int) returns int as $$ select 1;$$ language sql;
|
||||||
ERROR: parameter name "a" used more than once
|
ERROR: parameter name "a" used more than once
|
||||||
|
LINE 1: create function testpolym(a int, a int) returns int as $$ se...
|
||||||
|
^
|
||||||
create function testpolym(int, out a int, out a int) returns int as $$ select 1;$$ language sql;
|
create function testpolym(int, out a int, out a int) returns int as $$ select 1;$$ language sql;
|
||||||
ERROR: parameter name "a" used more than once
|
ERROR: parameter name "a" used more than once
|
||||||
|
LINE 1: create function testpolym(int, out a int, out a int) returns...
|
||||||
|
^
|
||||||
create function testpolym(out a int, inout a int) returns int as $$ select 1;$$ language sql;
|
create function testpolym(out a int, inout a int) returns int as $$ select 1;$$ language sql;
|
||||||
ERROR: parameter name "a" used more than once
|
ERROR: parameter name "a" used more than once
|
||||||
|
LINE 1: create function testpolym(out a int, inout a int) returns in...
|
||||||
|
^
|
||||||
create function testpolym(a int, inout a int) returns int as $$ select 1;$$ language sql;
|
create function testpolym(a int, inout a int) returns int as $$ select 1;$$ language sql;
|
||||||
ERROR: parameter name "a" used more than once
|
ERROR: parameter name "a" used more than once
|
||||||
|
LINE 1: create function testpolym(a int, inout a int) returns int as...
|
||||||
|
^
|
||||||
-- valid
|
-- valid
|
||||||
create function testpolym(a int, out a int) returns int as $$ select $1;$$ language sql;
|
create function testpolym(a int, out a int) returns int as $$ select $1;$$ language sql;
|
||||||
select testpolym(37);
|
select testpolym(37);
|
||||||
|
Reference in New Issue
Block a user