Provide an error cursor for "can't subscript" error messages.
Commit c7aba7c14
didn't add this, but after more fooling with the
feature I feel that it'd be useful. To make this possible, refactor
getSubscriptingRoutines() so that the caller is responsible for
throwing any error. (In clauses.c, I just chose to make the
most conservative assumption rather than throwing an error. We don't
expect failures there anyway really, so the code space for an error
message would be a poor investment.)
This commit is contained in:
parent
d2a2808eb4
commit
653aa603f5
|
@ -2536,6 +2536,14 @@ ExecInitSubscriptingRef(ExprEvalStep *scratch, SubscriptingRef *sbsref,
|
|||
|
||||
/* Look up the subscripting support methods */
|
||||
sbsroutines = getSubscriptingRoutines(sbsref->refcontainertype, NULL);
|
||||
if (!sbsroutines)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_DATATYPE_MISMATCH),
|
||||
errmsg("cannot subscript type %s because it does not support subscripting",
|
||||
format_type_be(sbsref->refcontainertype)),
|
||||
state->parent ?
|
||||
executor_errposition(state->parent->state,
|
||||
exprLocation((Node *) sbsref)) : 0));
|
||||
|
||||
/* Allocate sbsrefstate, with enough space for per-subscript arrays too */
|
||||
sbsrefstate = palloc0(MAXALIGN(sizeof(SubscriptingRefState)) +
|
||||
|
|
|
@ -848,7 +848,7 @@ contain_nonstrict_functions_walker(Node *node, void *context)
|
|||
return true;
|
||||
/* Otherwise we must look up the subscripting support methods */
|
||||
sbsroutines = getSubscriptingRoutines(sbsref->refcontainertype, NULL);
|
||||
if (!sbsroutines->fetch_strict)
|
||||
if (!(sbsroutines && sbsroutines->fetch_strict))
|
||||
return true;
|
||||
/* else fall through to check args */
|
||||
}
|
||||
|
@ -1144,7 +1144,8 @@ contain_leaked_vars_walker(Node *node, void *context)
|
|||
/* Consult the subscripting support method info */
|
||||
sbsroutines = getSubscriptingRoutines(sbsref->refcontainertype,
|
||||
NULL);
|
||||
if (!(sbsref->refassgnexpr != NULL ?
|
||||
if (!sbsroutines ||
|
||||
!(sbsref->refassgnexpr != NULL ?
|
||||
sbsroutines->store_leakproof :
|
||||
sbsroutines->fetch_leakproof))
|
||||
{
|
||||
|
|
|
@ -271,6 +271,12 @@ transformContainerSubscripts(ParseState *pstate,
|
|||
* functions and typelem.
|
||||
*/
|
||||
sbsroutines = getSubscriptingRoutines(containerType, &elementType);
|
||||
if (!sbsroutines)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_DATATYPE_MISMATCH),
|
||||
errmsg("cannot subscript type %s because it does not support subscripting",
|
||||
format_type_be(containerType)),
|
||||
parser_errposition(pstate, exprLocation(containerBase))));
|
||||
|
||||
/*
|
||||
* Detect whether any of the indirection items are slice specifiers.
|
||||
|
|
|
@ -3031,7 +3031,7 @@ get_typsubscript(Oid typid, Oid *typelemp)
|
|||
* getSubscriptingRoutines
|
||||
*
|
||||
* Given the type OID, fetch the type's subscripting methods struct.
|
||||
* Fail if type is not subscriptable.
|
||||
* Return NULL if type is not subscriptable.
|
||||
*
|
||||
* If typelemp isn't NULL, we also store the type's typelem value there.
|
||||
* This saves some callers an extra catalog lookup.
|
||||
|
@ -3042,10 +3042,7 @@ getSubscriptingRoutines(Oid typid, Oid *typelemp)
|
|||
RegProcedure typsubscript = get_typsubscript(typid, typelemp);
|
||||
|
||||
if (!OidIsValid(typsubscript))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_DATATYPE_MISMATCH),
|
||||
errmsg("cannot subscript type %s because it does not support subscripting",
|
||||
format_type_be(typid))));
|
||||
return NULL;
|
||||
|
||||
return (const struct SubscriptRoutines *)
|
||||
DatumGetPointer(OidFunctionCall0(typsubscript));
|
||||
|
|
|
@ -238,6 +238,8 @@ ERROR: array subscript in assignment must not be null
|
|||
-- Un-subscriptable type
|
||||
SELECT (now())[1];
|
||||
ERROR: cannot subscript type timestamp with time zone because it does not support subscripting
|
||||
LINE 1: SELECT (now())[1];
|
||||
^
|
||||
-- test slices with empty lower and/or upper index
|
||||
CREATE TEMP TABLE arrtest_s (
|
||||
a int2[],
|
||||
|
|
Loading…
Reference in New Issue