1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-26 12:21:12 +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

@ -268,10 +268,12 @@ ExecEvalArrayRef(ArrayRefExprState *astate,
bool eisnull;
ListCell *l;
int i = 0,
j = 0;
j = 0,
indexexpr;
IntArray upper,
lower;
int *lIndex;
AnyArrayType *arrays;
array_source = ExecEvalExpr(astate->refexpr,
econtext,
@ -293,6 +295,7 @@ ExecEvalArrayRef(ArrayRefExprState *astate,
foreach(l, astate->refupperindexpr)
{
ExprState *eltstate = (ExprState *) lfirst(l);
eisnull = false;
if (i >= MAXDIM)
ereport(ERROR,
@ -300,10 +303,23 @@ ExecEvalArrayRef(ArrayRefExprState *astate,
errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
i + 1, MAXDIM)));
upper.indx[i++] = DatumGetInt32(ExecEvalExpr(eltstate,
econtext,
&eisnull,
NULL));
if (eltstate == NULL && astate->refattrlength <= 0)
{
if (isAssignment)
ereport(ERROR,
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
errmsg("cannot determine upper index for empty array")));
arrays = (AnyArrayType *)DatumGetArrayTypeP(array_source);
indexexpr = AARR_LBOUND(arrays)[i] + AARR_DIMS(arrays)[i] - 1;
}
else
indexexpr = DatumGetInt32(ExecEvalExpr(eltstate,
econtext,
&eisnull,
NULL));
upper.indx[i++] = indexexpr;
/* If any index expr yields NULL, result is NULL or error */
if (eisnull)
{
@ -321,6 +337,7 @@ ExecEvalArrayRef(ArrayRefExprState *astate,
foreach(l, astate->reflowerindexpr)
{
ExprState *eltstate = (ExprState *) lfirst(l);
eisnull = false;
if (j >= MAXDIM)
ereport(ERROR,
@ -328,10 +345,19 @@ ExecEvalArrayRef(ArrayRefExprState *astate,
errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
j + 1, MAXDIM)));
lower.indx[j++] = DatumGetInt32(ExecEvalExpr(eltstate,
econtext,
&eisnull,
NULL));
if (eltstate == NULL)
{
arrays = (AnyArrayType *)DatumGetArrayTypeP(array_source);
indexexpr = AARR_LBOUND(arrays)[j];
}
else
indexexpr = DatumGetInt32(ExecEvalExpr(eltstate,
econtext,
&eisnull,
NULL));
lower.indx[j++] = indexexpr;
/* If any index expr yields NULL, result is NULL or error */
if (eisnull)
{