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/parser/parse_node.c | |
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/parser/parse_node.c')
-rw-r--r-- | src/backend/parser/parse_node.c | 49 |
1 files changed, 32 insertions, 17 deletions
diff --git a/src/backend/parser/parse_node.c b/src/backend/parser/parse_node.c index 4130cbff5ed..de6e0b89342 100644 --- a/src/backend/parser/parse_node.c +++ b/src/backend/parser/parse_node.c @@ -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); } |