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

Commit653aa60

Browse files
committed
Provide an error cursor for "can't subscript" error messages.
Commitc7aba7c didn't add this, but after more fooling with thefeature I feel that it'd be useful. To make this possible, refactorgetSubscriptingRoutines() so that the caller is responsible forthrowing any error. (In clauses.c, I just chose to make themost conservative assumption rather than throwing an error. We don'texpect failures there anyway really, so the code space for an errormessage would be a poor investment.)
1 parentd2a2808 commit653aa60

File tree

5 files changed

+21
-7
lines changed

5 files changed

+21
-7
lines changed

‎src/backend/executor/execExpr.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2536,6 +2536,14 @@ ExecInitSubscriptingRef(ExprEvalStep *scratch, SubscriptingRef *sbsref,
25362536

25372537
/* Look up the subscripting support methods */
25382538
sbsroutines=getSubscriptingRoutines(sbsref->refcontainertype,NULL);
2539+
if (!sbsroutines)
2540+
ereport(ERROR,
2541+
(errcode(ERRCODE_DATATYPE_MISMATCH),
2542+
errmsg("cannot subscript type %s because it does not support subscripting",
2543+
format_type_be(sbsref->refcontainertype)),
2544+
state->parent ?
2545+
executor_errposition(state->parent->state,
2546+
exprLocation((Node*)sbsref)) :0));
25392547

25402548
/* Allocate sbsrefstate, with enough space for per-subscript arrays too */
25412549
sbsrefstate=palloc0(MAXALIGN(sizeof(SubscriptingRefState))+

‎src/backend/optimizer/util/clauses.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -848,7 +848,7 @@ contain_nonstrict_functions_walker(Node *node, void *context)
848848
return true;
849849
/* Otherwise we must look up the subscripting support methods */
850850
sbsroutines=getSubscriptingRoutines(sbsref->refcontainertype,NULL);
851-
if (!sbsroutines->fetch_strict)
851+
if (!(sbsroutines&&sbsroutines->fetch_strict))
852852
return true;
853853
/* else fall through to check args */
854854
}
@@ -1144,7 +1144,8 @@ contain_leaked_vars_walker(Node *node, void *context)
11441144
/* Consult the subscripting support method info */
11451145
sbsroutines=getSubscriptingRoutines(sbsref->refcontainertype,
11461146
NULL);
1147-
if (!(sbsref->refassgnexpr!=NULL ?
1147+
if (!sbsroutines||
1148+
!(sbsref->refassgnexpr!=NULL ?
11481149
sbsroutines->store_leakproof :
11491150
sbsroutines->fetch_leakproof))
11501151
{

‎src/backend/parser/parse_node.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,12 @@ transformContainerSubscripts(ParseState *pstate,
271271
* functions and typelem.
272272
*/
273273
sbsroutines=getSubscriptingRoutines(containerType,&elementType);
274+
if (!sbsroutines)
275+
ereport(ERROR,
276+
(errcode(ERRCODE_DATATYPE_MISMATCH),
277+
errmsg("cannot subscript type %s because it does not support subscripting",
278+
format_type_be(containerType)),
279+
parser_errposition(pstate,exprLocation(containerBase))));
274280

275281
/*
276282
* Detect whether any of the indirection items are slice specifiers.

‎src/backend/utils/cache/lsyscache.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3031,7 +3031,7 @@ get_typsubscript(Oid typid, Oid *typelemp)
30313031
* getSubscriptingRoutines
30323032
*
30333033
*Given the type OID, fetch the type's subscripting methods struct.
3034-
*Fail if type is not subscriptable.
3034+
*Return NULL if type is not subscriptable.
30353035
*
30363036
* If typelemp isn't NULL, we also store the type's typelem value there.
30373037
* This saves some callers an extra catalog lookup.
@@ -3042,10 +3042,7 @@ getSubscriptingRoutines(Oid typid, Oid *typelemp)
30423042
RegProceduretypsubscript=get_typsubscript(typid,typelemp);
30433043

30443044
if (!OidIsValid(typsubscript))
3045-
ereport(ERROR,
3046-
(errcode(ERRCODE_DATATYPE_MISMATCH),
3047-
errmsg("cannot subscript type %s because it does not support subscripting",
3048-
format_type_be(typid))));
3045+
returnNULL;
30493046

30503047
return (conststructSubscriptRoutines*)
30513048
DatumGetPointer(OidFunctionCall0(typsubscript));

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,8 @@ ERROR: array subscript in assignment must not be null
238238
-- Un-subscriptable type
239239
SELECT (now())[1];
240240
ERROR: cannot subscript type timestamp with time zone because it does not support subscripting
241+
LINE 1: SELECT (now())[1];
242+
^
241243
-- test slices with empty lower and/or upper index
242244
CREATE TEMP TABLE arrtest_s (
243245
a int2[],

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp