mirror of
https://github.com/postgres/postgres.git
synced 2025-04-27 22:56:53 +03:00
Revert 9246af6799819847faa33baf441251003acbb8fe because
I miss too much. Patch is returned to commitfest process.
This commit is contained in:
parent
3c7042a7d7
commit
bbbd807097
@ -255,26 +255,6 @@ SELECT schedule[1:2][1:1] FROM sal_emp WHERE name = 'Bill';
|
|||||||
------------------------
|
------------------------
|
||||||
{{meeting},{training}}
|
{{meeting},{training}}
|
||||||
(1 row)
|
(1 row)
|
||||||
</programlisting>
|
|
||||||
|
|
||||||
Possible to skip the <literal><replaceable>lower-bound</replaceable></literal> or
|
|
||||||
<literal><replaceable>upper-bound</replaceable></literal>
|
|
||||||
for get first or last element in slice.
|
|
||||||
|
|
||||||
<programlisting>
|
|
||||||
SELECT schedule[:][:] FROM sal_emp WHERE name = 'Bill';
|
|
||||||
|
|
||||||
schedule
|
|
||||||
------------------------
|
|
||||||
{{meeting,lunch},{training,presentation}}
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
SELECT schedule[:2][2:] FROM sal_emp WHERE name = 'Bill';
|
|
||||||
|
|
||||||
schedule
|
|
||||||
------------------------
|
|
||||||
{{lunch},{presentation}}
|
|
||||||
(1 row)
|
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
If any dimension is written as a slice, i.e., contains a colon, then all
|
If any dimension is written as a slice, i.e., contains a colon, then all
|
||||||
|
@ -268,12 +268,10 @@ ExecEvalArrayRef(ArrayRefExprState *astate,
|
|||||||
bool eisnull;
|
bool eisnull;
|
||||||
ListCell *l;
|
ListCell *l;
|
||||||
int i = 0,
|
int i = 0,
|
||||||
j = 0,
|
j = 0;
|
||||||
indexexpr;
|
|
||||||
IntArray upper,
|
IntArray upper,
|
||||||
lower;
|
lower;
|
||||||
int *lIndex;
|
int *lIndex;
|
||||||
AnyArrayType *arrays;
|
|
||||||
|
|
||||||
array_source = ExecEvalExpr(astate->refexpr,
|
array_source = ExecEvalExpr(astate->refexpr,
|
||||||
econtext,
|
econtext,
|
||||||
@ -295,7 +293,6 @@ ExecEvalArrayRef(ArrayRefExprState *astate,
|
|||||||
foreach(l, astate->refupperindexpr)
|
foreach(l, astate->refupperindexpr)
|
||||||
{
|
{
|
||||||
ExprState *eltstate = (ExprState *) lfirst(l);
|
ExprState *eltstate = (ExprState *) lfirst(l);
|
||||||
eisnull = false;
|
|
||||||
|
|
||||||
if (i >= MAXDIM)
|
if (i >= MAXDIM)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
@ -303,23 +300,10 @@ ExecEvalArrayRef(ArrayRefExprState *astate,
|
|||||||
errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
|
errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
|
||||||
i + 1, MAXDIM)));
|
i + 1, MAXDIM)));
|
||||||
|
|
||||||
if (eltstate == NULL && astate->refattrlength <= 0)
|
upper.indx[i++] = DatumGetInt32(ExecEvalExpr(eltstate,
|
||||||
{
|
econtext,
|
||||||
if (isAssignment)
|
&eisnull,
|
||||||
ereport(ERROR,
|
NULL));
|
||||||
(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 any index expr yields NULL, result is NULL or error */
|
||||||
if (eisnull)
|
if (eisnull)
|
||||||
{
|
{
|
||||||
@ -337,7 +321,6 @@ ExecEvalArrayRef(ArrayRefExprState *astate,
|
|||||||
foreach(l, astate->reflowerindexpr)
|
foreach(l, astate->reflowerindexpr)
|
||||||
{
|
{
|
||||||
ExprState *eltstate = (ExprState *) lfirst(l);
|
ExprState *eltstate = (ExprState *) lfirst(l);
|
||||||
eisnull = false;
|
|
||||||
|
|
||||||
if (j >= MAXDIM)
|
if (j >= MAXDIM)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
@ -345,19 +328,10 @@ ExecEvalArrayRef(ArrayRefExprState *astate,
|
|||||||
errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
|
errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
|
||||||
j + 1, MAXDIM)));
|
j + 1, MAXDIM)));
|
||||||
|
|
||||||
if (eltstate == NULL)
|
lower.indx[j++] = DatumGetInt32(ExecEvalExpr(eltstate,
|
||||||
{
|
econtext,
|
||||||
arrays = (AnyArrayType *)DatumGetArrayTypeP(array_source);
|
&eisnull,
|
||||||
indexexpr = AARR_LBOUND(arrays)[j];
|
NULL));
|
||||||
}
|
|
||||||
else
|
|
||||||
indexexpr = DatumGetInt32(ExecEvalExpr(eltstate,
|
|
||||||
econtext,
|
|
||||||
&eisnull,
|
|
||||||
NULL));
|
|
||||||
|
|
||||||
lower.indx[j++] = indexexpr;
|
|
||||||
|
|
||||||
/* If any index expr yields NULL, result is NULL or error */
|
/* If any index expr yields NULL, result is NULL or error */
|
||||||
if (eisnull)
|
if (eisnull)
|
||||||
{
|
{
|
||||||
|
@ -2403,8 +2403,6 @@ _copyAIndices(const A_Indices *from)
|
|||||||
|
|
||||||
COPY_NODE_FIELD(lidx);
|
COPY_NODE_FIELD(lidx);
|
||||||
COPY_NODE_FIELD(uidx);
|
COPY_NODE_FIELD(uidx);
|
||||||
COPY_SCALAR_FIELD(lidx_default);
|
|
||||||
COPY_SCALAR_FIELD(uidx_default);
|
|
||||||
|
|
||||||
return newnode;
|
return newnode;
|
||||||
}
|
}
|
||||||
|
@ -2153,8 +2153,6 @@ _equalAIndices(const A_Indices *a, const A_Indices *b)
|
|||||||
{
|
{
|
||||||
COMPARE_NODE_FIELD(lidx);
|
COMPARE_NODE_FIELD(lidx);
|
||||||
COMPARE_NODE_FIELD(uidx);
|
COMPARE_NODE_FIELD(uidx);
|
||||||
COMPARE_SCALAR_FIELD(lidx_default);
|
|
||||||
COMPARE_SCALAR_FIELD(uidx_default);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -2765,8 +2765,6 @@ _outA_Indices(StringInfo str, const A_Indices *node)
|
|||||||
|
|
||||||
WRITE_NODE_FIELD(lidx);
|
WRITE_NODE_FIELD(lidx);
|
||||||
WRITE_NODE_FIELD(uidx);
|
WRITE_NODE_FIELD(uidx);
|
||||||
WRITE_BOOL_FIELD(lidx_default);
|
|
||||||
WRITE_BOOL_FIELD(uidx_default);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -13193,35 +13193,6 @@ indirection_el:
|
|||||||
A_Indices *ai = makeNode(A_Indices);
|
A_Indices *ai = makeNode(A_Indices);
|
||||||
ai->lidx = NULL;
|
ai->lidx = NULL;
|
||||||
ai->uidx = $2;
|
ai->uidx = $2;
|
||||||
ai->lidx_default = false;
|
|
||||||
ai->uidx_default = false;
|
|
||||||
$$ = (Node *) ai;
|
|
||||||
}
|
|
||||||
| '[' ':' ']'
|
|
||||||
{
|
|
||||||
A_Indices *ai = makeNode(A_Indices);
|
|
||||||
ai->lidx = NULL;
|
|
||||||
ai->uidx = NULL;
|
|
||||||
ai->lidx_default = true;
|
|
||||||
ai->uidx_default = true;
|
|
||||||
$$ = (Node *) ai;
|
|
||||||
}
|
|
||||||
| '[' ':' a_expr ']'
|
|
||||||
{
|
|
||||||
A_Indices *ai = makeNode(A_Indices);
|
|
||||||
ai->lidx = NULL;
|
|
||||||
ai->uidx = $3;
|
|
||||||
ai->lidx_default = true;
|
|
||||||
ai->uidx_default = false;
|
|
||||||
$$ = (Node *) ai;
|
|
||||||
}
|
|
||||||
| '[' a_expr ':' ']'
|
|
||||||
{
|
|
||||||
A_Indices *ai = makeNode(A_Indices);
|
|
||||||
ai->lidx = $2;
|
|
||||||
ai->uidx = NULL;
|
|
||||||
ai->lidx_default = false;
|
|
||||||
ai->uidx_default = true;
|
|
||||||
$$ = (Node *) ai;
|
$$ = (Node *) ai;
|
||||||
}
|
}
|
||||||
| '[' a_expr ':' a_expr ']'
|
| '[' a_expr ':' a_expr ']'
|
||||||
@ -13229,8 +13200,6 @@ indirection_el:
|
|||||||
A_Indices *ai = makeNode(A_Indices);
|
A_Indices *ai = makeNode(A_Indices);
|
||||||
ai->lidx = $2;
|
ai->lidx = $2;
|
||||||
ai->uidx = $4;
|
ai->uidx = $4;
|
||||||
ai->lidx_default = false;
|
|
||||||
ai->uidx_default = false;
|
|
||||||
$$ = (Node *) ai;
|
$$ = (Node *) ai;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
@ -311,7 +311,7 @@ transformArraySubscripts(ParseState *pstate,
|
|||||||
elementType = transformArrayType(&arrayType, &arrayTypMod);
|
elementType = transformArrayType(&arrayType, &arrayTypMod);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A list containing only single subscripts (uidx) refers to a single array
|
* A list containing only single subscripts refers to a single array
|
||||||
* element. If any of the items are double subscripts (lower:upper), then
|
* element. If any of the items are double subscripts (lower:upper), then
|
||||||
* the subscript expression means an array slice operation. In this case,
|
* 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
|
* 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);
|
A_Indices *ai = (A_Indices *) lfirst(idx);
|
||||||
|
|
||||||
if (ai->lidx != NULL || ai->lidx_default)
|
if (ai->lidx != NULL)
|
||||||
{
|
{
|
||||||
isSlice = true;
|
isSlice = true;
|
||||||
break;
|
break;
|
||||||
@ -335,17 +335,9 @@ transformArraySubscripts(ParseState *pstate,
|
|||||||
foreach(idx, indirection)
|
foreach(idx, indirection)
|
||||||
{
|
{
|
||||||
A_Indices *ai = (A_Indices *) lfirst(idx);
|
A_Indices *ai = (A_Indices *) lfirst(idx);
|
||||||
Node *subexpr = NULL;
|
Node *subexpr;
|
||||||
|
|
||||||
Assert(IsA(ai, A_Indices));
|
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 (isSlice)
|
||||||
{
|
{
|
||||||
if (ai->lidx)
|
if (ai->lidx)
|
||||||
@ -364,7 +356,7 @@ transformArraySubscripts(ParseState *pstate,
|
|||||||
errmsg("array subscript must have type integer"),
|
errmsg("array subscript must have type integer"),
|
||||||
parser_errposition(pstate, exprLocation(ai->lidx))));
|
parser_errposition(pstate, exprLocation(ai->lidx))));
|
||||||
}
|
}
|
||||||
else if (ai->lidx_default == false)
|
else
|
||||||
{
|
{
|
||||||
/* Make a constant 1 */
|
/* Make a constant 1 */
|
||||||
subexpr = (Node *) makeConst(INT4OID,
|
subexpr = (Node *) makeConst(INT4OID,
|
||||||
@ -377,26 +369,19 @@ transformArraySubscripts(ParseState *pstate,
|
|||||||
}
|
}
|
||||||
lowerIndexpr = lappend(lowerIndexpr, subexpr);
|
lowerIndexpr = lappend(lowerIndexpr, subexpr);
|
||||||
}
|
}
|
||||||
|
subexpr = transformExpr(pstate, ai->uidx, pstate->p_expr_kind);
|
||||||
if (ai->uidx_default == false)
|
/* If it's not int4 already, try to coerce */
|
||||||
{
|
subexpr = coerce_to_target_type(pstate,
|
||||||
subexpr = transformExpr(pstate, ai->uidx, pstate->p_expr_kind);
|
subexpr, exprType(subexpr),
|
||||||
/* If it's not int4 already, try to coerce */
|
INT4OID, -1,
|
||||||
subexpr = coerce_to_target_type(pstate,
|
COERCION_ASSIGNMENT,
|
||||||
subexpr, exprType(subexpr),
|
COERCE_IMPLICIT_CAST,
|
||||||
INT4OID, -1,
|
-1);
|
||||||
COERCION_ASSIGNMENT,
|
if (subexpr == NULL)
|
||||||
COERCE_IMPLICIT_CAST,
|
ereport(ERROR,
|
||||||
-1);
|
(errcode(ERRCODE_DATATYPE_MISMATCH),
|
||||||
if (subexpr == NULL)
|
errmsg("array subscript must have type integer"),
|
||||||
ereport(ERROR,
|
parser_errposition(pstate, exprLocation(ai->uidx))));
|
||||||
(errcode(ERRCODE_DATATYPE_MISMATCH),
|
|
||||||
errmsg("array subscript must have type integer"),
|
|
||||||
parser_errposition(pstate, exprLocation(ai->uidx))));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
subexpr = NULL;
|
|
||||||
|
|
||||||
upperIndexpr = lappend(upperIndexpr, subexpr);
|
upperIndexpr = lappend(upperIndexpr, subexpr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -650,7 +650,7 @@ transformAssignmentIndirection(ParseState *pstate,
|
|||||||
if (IsA(n, A_Indices))
|
if (IsA(n, A_Indices))
|
||||||
{
|
{
|
||||||
subscripts = lappend(subscripts, n);
|
subscripts = lappend(subscripts, n);
|
||||||
if (((A_Indices *) n)->lidx != NULL || ((A_Indices *) n)->lidx_default)
|
if (((A_Indices *) n)->lidx != NULL)
|
||||||
isSlice = true;
|
isSlice = true;
|
||||||
}
|
}
|
||||||
else if (IsA(n, A_Star))
|
else if (IsA(n, A_Star))
|
||||||
|
@ -358,8 +358,6 @@ typedef struct A_Indices
|
|||||||
NodeTag type;
|
NodeTag type;
|
||||||
Node *lidx; /* NULL if it's a single subscript */
|
Node *lidx; /* NULL if it's a single subscript */
|
||||||
Node *uidx;
|
Node *uidx;
|
||||||
bool lidx_default;
|
|
||||||
bool uidx_default;
|
|
||||||
} A_Indices;
|
} A_Indices;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2031,43 +2031,3 @@ SELECT width_bucket(5, ARRAY[3, 4, NULL]);
|
|||||||
ERROR: thresholds array must not contain NULLs
|
ERROR: thresholds array must not contain NULLs
|
||||||
SELECT width_bucket(5, ARRAY[ARRAY[1, 2], ARRAY[3, 4]]);
|
SELECT width_bucket(5, ARRAY[ARRAY[1, 2], ARRAY[3, 4]]);
|
||||||
ERROR: thresholds must be one-dimensional array
|
ERROR: thresholds must be one-dimensional array
|
||||||
-- slices with empty lower and/or upper index
|
|
||||||
CREATE TABLE arrtest_s (
|
|
||||||
a int2[],
|
|
||||||
b int2[][]
|
|
||||||
);
|
|
||||||
INSERT INTO arrtest_s VALUES ('{1,2,3,4,5}', '{{1,2,3}, {4,5,6}, {7,8,9}}');
|
|
||||||
SELECT a[:3], b[:2][:2] FROM arrtest_s;
|
|
||||||
a | b
|
|
||||||
---------+---------------
|
|
||||||
{1,2,3} | {{1,2},{4,5}}
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
SELECT a[2:], b[2:][2:] FROM arrtest_s;
|
|
||||||
a | b
|
|
||||||
-----------+---------------
|
|
||||||
{2,3,4,5} | {{5,6},{8,9}}
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
SELECT a[:], b[:] FROM arrtest_s;
|
|
||||||
a | b
|
|
||||||
-------------+---------------------------
|
|
||||||
{1,2,3,4,5} | {{1,2,3},{4,5,6},{7,8,9}}
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
-- errors
|
|
||||||
UPDATE arrtest_s SET a[:3] = '{11, 12, 13}', b[:2][:2] = '{{11,12}, {14, 15}}';
|
|
||||||
ERROR: array subscript must have both boundaries
|
|
||||||
LINE 1: UPDATE arrtest_s SET a[:3] = '{11, 12, 13}', b[:2][:2] = '{{...
|
|
||||||
^
|
|
||||||
HINT: You can't omit the upper or lower boundaries when updating or inserting
|
|
||||||
UPDATE arrtest_s SET a[3:] = '{23, 24, 25}', b[2:][2:] = '{{25,26}, {28, 29}}';
|
|
||||||
ERROR: array subscript must have both boundaries
|
|
||||||
LINE 1: UPDATE arrtest_s SET a[3:] = '{23, 24, 25}', b[2:][2:] = '{{...
|
|
||||||
^
|
|
||||||
HINT: You can't omit the upper or lower boundaries when updating or inserting
|
|
||||||
UPDATE arrtest_s SET a[:] = '{23, 24, 25}';
|
|
||||||
ERROR: array subscript must have both boundaries
|
|
||||||
LINE 1: UPDATE arrtest_s SET a[:] = '{23, 24, 25}';
|
|
||||||
^
|
|
||||||
HINT: You can't omit the upper or lower boundaries when updating or inserting
|
|
||||||
|
@ -586,7 +586,6 @@ SELECT user_relns() AS user_relns
|
|||||||
array_index_op_test
|
array_index_op_test
|
||||||
array_op_test
|
array_op_test
|
||||||
arrtest
|
arrtest
|
||||||
arrtest_s
|
|
||||||
b
|
b
|
||||||
b_star
|
b_star
|
||||||
bb
|
bb
|
||||||
@ -711,7 +710,7 @@ SELECT user_relns() AS user_relns
|
|||||||
tvvmv
|
tvvmv
|
||||||
varchar_tbl
|
varchar_tbl
|
||||||
xacttest
|
xacttest
|
||||||
(133 rows)
|
(132 rows)
|
||||||
|
|
||||||
SELECT name(equipment(hobby_construct(text 'skywalking', text 'mer')));
|
SELECT name(equipment(hobby_construct(text 'skywalking', text 'mer')));
|
||||||
name
|
name
|
||||||
|
@ -609,18 +609,3 @@ SELECT width_bucket(5, '{}');
|
|||||||
SELECT width_bucket('5'::text, ARRAY[3, 4]::integer[]);
|
SELECT width_bucket('5'::text, ARRAY[3, 4]::integer[]);
|
||||||
SELECT width_bucket(5, ARRAY[3, 4, NULL]);
|
SELECT width_bucket(5, ARRAY[3, 4, NULL]);
|
||||||
SELECT width_bucket(5, ARRAY[ARRAY[1, 2], ARRAY[3, 4]]);
|
SELECT width_bucket(5, ARRAY[ARRAY[1, 2], ARRAY[3, 4]]);
|
||||||
|
|
||||||
-- slices with empty lower and/or upper index
|
|
||||||
CREATE TABLE arrtest_s (
|
|
||||||
a int2[],
|
|
||||||
b int2[][]
|
|
||||||
);
|
|
||||||
INSERT INTO arrtest_s VALUES ('{1,2,3,4,5}', '{{1,2,3}, {4,5,6}, {7,8,9}}');
|
|
||||||
SELECT a[:3], b[:2][:2] FROM arrtest_s;
|
|
||||||
SELECT a[2:], b[2:][2:] FROM arrtest_s;
|
|
||||||
SELECT a[:], b[:] FROM arrtest_s;
|
|
||||||
|
|
||||||
-- errors
|
|
||||||
UPDATE arrtest_s SET a[:3] = '{11, 12, 13}', b[:2][:2] = '{{11,12}, {14, 15}}';
|
|
||||||
UPDATE arrtest_s SET a[3:] = '{23, 24, 25}', b[2:][2:] = '{{25,26}, {28, 29}}';
|
|
||||||
UPDATE arrtest_s SET a[:] = '{23, 24, 25}';
|
|
Loading…
x
Reference in New Issue
Block a user