1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-29 10:41:53 +03:00

Allow to omit boundaries in array subscript

Allow to omiy lower or upper or both boundaries in array subscript
for selecting slice of array.

Author: YUriy Zhuravlev
This commit is contained in:
Teodor Sigaev
2015-12-18 15:18:58 +03:00
parent 33bd250f6c
commit 9246af6799
12 changed files with 184 additions and 28 deletions

View File

@ -311,7 +311,7 @@ transformArraySubscripts(ParseState *pstate,
elementType = transformArrayType(&arrayType, &arrayTypMod);
/*
* A list containing only single subscripts refers to a single array
* A list containing only single subscripts (uidx) refers to a single array
* element. If any of the items are double subscripts (lower:upper), then
* the subscript expression means an array slice operation. In this case,
* we supply a default lower bound of 1 for any items that contain only a
@ -322,7 +322,7 @@ transformArraySubscripts(ParseState *pstate,
{
A_Indices *ai = (A_Indices *) lfirst(idx);
if (ai->lidx != NULL)
if (ai->lidx != NULL || ai->lidx_default)
{
isSlice = true;
break;
@ -335,9 +335,17 @@ transformArraySubscripts(ParseState *pstate,
foreach(idx, indirection)
{
A_Indices *ai = (A_Indices *) lfirst(idx);
Node *subexpr;
Node *subexpr = NULL;
Assert(IsA(ai, A_Indices));
if ((ai->uidx_default || ai->lidx_default) && assignFrom != NULL)
ereport(ERROR,
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
errmsg("array subscript must have both boundaries"),
errhint("You can't omit the upper or lower"
" boundaries when updating or inserting"),
parser_errposition(pstate, exprLocation(arrayBase))));
if (isSlice)
{
if (ai->lidx)
@ -356,7 +364,7 @@ transformArraySubscripts(ParseState *pstate,
errmsg("array subscript must have type integer"),
parser_errposition(pstate, exprLocation(ai->lidx))));
}
else
else if (ai->lidx_default == false)
{
/* Make a constant 1 */
subexpr = (Node *) makeConst(INT4OID,
@ -369,19 +377,26 @@ transformArraySubscripts(ParseState *pstate,
}
lowerIndexpr = lappend(lowerIndexpr, subexpr);
}
subexpr = transformExpr(pstate, ai->uidx, pstate->p_expr_kind);
/* If it's not int4 already, try to coerce */
subexpr = coerce_to_target_type(pstate,
subexpr, exprType(subexpr),
INT4OID, -1,
COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST,
-1);
if (subexpr == NULL)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("array subscript must have type integer"),
parser_errposition(pstate, exprLocation(ai->uidx))));
if (ai->uidx_default == false)
{
subexpr = transformExpr(pstate, ai->uidx, pstate->p_expr_kind);
/* If it's not int4 already, try to coerce */
subexpr = coerce_to_target_type(pstate,
subexpr, exprType(subexpr),
INT4OID, -1,
COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST,
-1);
if (subexpr == NULL)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("array subscript must have type integer"),
parser_errposition(pstate, exprLocation(ai->uidx))));
}
else
subexpr = NULL;
upperIndexpr = lappend(upperIndexpr, subexpr);
}