diff options
author | Teodor Sigaev <teodor@sigaev.ru> | 2015-12-18 15:18:58 +0300 |
---|---|---|
committer | Teodor Sigaev <teodor@sigaev.ru> | 2015-12-18 15:18:58 +0300 |
commit | 9246af6799819847faa33baf441251003acbb8fe (patch) | |
tree | 4ec56f3add9dc6e3bb583a9c3d617385390109fe /src/backend/executor | |
parent | 33bd250f6c4cc309f4eeb657da80f1e7743b3e5c (diff) | |
download | postgresql-9246af6799819847faa33baf441251003acbb8fe.tar.gz postgresql-9246af6799819847faa33baf441251003acbb8fe.zip |
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
Diffstat (limited to 'src/backend/executor')
-rw-r--r-- | src/backend/executor/execQual.c | 44 |
1 files changed, 35 insertions, 9 deletions
diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c index 29f058ce5cb..d9bf9773fe8 100644 --- a/src/backend/executor/execQual.c +++ b/src/backend/executor/execQual.c @@ -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) { |