Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit c9aa996

Browse files
committed
correctly implement any/each element feature
1 parent 5061792 commit c9aa996

File tree

6 files changed

+134
-48
lines changed

6 files changed

+134
-48
lines changed

contrib/pageinspect/rawpage.c

+1-5
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,6 @@
2828

2929
PG_MODULE_MAGIC;
3030

31-
static bytea *get_raw_page_internal(text *relname, ForkNumber forknum,
32-
BlockNumber blkno);
33-
34-
3531
/*
3632
* get_raw_page
3733
*
@@ -87,7 +83,7 @@ get_raw_page_fork(PG_FUNCTION_ARGS)
8783
/*
8884
* workhorse
8985
*/
90-
static bytea *
86+
bytea *
9187
get_raw_page_internal(text *relname, ForkNumber forknum, BlockNumber blkno)
9288
{
9389
bytea *raw_page;

src/backend/parser/gram.y

+66-27
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ static void processCASbits(int cas_bits, int location, const char *constrType,
176176
bool *deferrable, bool *initdeferred, bool *not_valid,
177177
bool *no_inherit, core_yyscan_t yyscanner);
178178
static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
179-
static SelectStmt * makeElementSubselect(int kind, bool recursive, Node *of,
179+
static SelectStmt * makeElementSubselect(int any_or_each, int kind, bool recursive, Node *of,
180180
const char *aliasname, Node *clause, int location);
181181

182182
%}
@@ -12064,21 +12064,13 @@ c_expr: columnref { $$ = $1; }
1206412064
{
1206512065
SubLink *n = makeNode(SubLink);
1206612066

12067-
n->subLinkType = EXISTS_SUBLINK;
12067+
n->subLinkType = EXPR_SUBLINK;
1206812068
n->subLinkId = 0;
1206912069
n->testexpr = NULL;
1207012070
n->operName = NIL;
12071-
n->subselect = (Node*)makeElementSubselect(
12072-
$2, $3,
12073-
$5, $7,
12074-
($1 == EACH) ? makeNotExpr($10, @1) : $10,
12075-
@1
12076-
);
12071+
n->subselect = (Node*)makeElementSubselect($1, $2, $3, $5, $7, $10, @1);
1207712072
n->location = @1;
12078-
if ($1 == EACH)
12079-
$$ = makeNotExpr((Node *)n, @1);
12080-
else
12081-
$$ = (Node *)n;
12073+
$$ = (Node *)n;
1208212074
}
1208312075
;
1208412076

@@ -14873,43 +14865,90 @@ makeRecursiveViewSelect(char *relname, List *aliases, Node *query)
1487314865
}
1487414866

1487514867
static SelectStmt *
14876-
makeElementSubselect(int kind, bool recursive, Node *of,
14868+
makeElementSubselect(int any_or_each, int kind, bool recursive, Node *of,
1487714869
const char *aliasname, Node *clause, int location)
1487814870
{
1487914871
ResTarget *target = makeNode(ResTarget);
14880-
FuncCall *func_call;
14872+
FuncCall *unnest_call, *agg_call, *count_call;
1488114873
RangeFunction *table_ref = makeNode(RangeFunction);
1488214874
SelectStmt *subselect = makeNode(SelectStmt);
14883-
char *funcname;
14875+
char *unnest_name, *agg_name;
14876+
CaseExpr *c = makeNode(CaseExpr);
14877+
CaseWhen *w = makeNode(CaseWhen);
14878+
NullTest *n = makeNode(NullTest);;
14879+
14880+
/* SELECT (CASE
14881+
* WHEN (COUNT(*) = 0 AND of IS NOT NULL) THEN '?'::bool
14882+
* ELSE BOOL_OR_AND(clause) END ) FROM unnest_*(of) AS aliasname */
1488414883

14885-
target->val = (Node*)makeIntConst(1, location);
14884+
switch(any_or_each)
14885+
{
14886+
case ANY_EL:
14887+
agg_name = "bool_or_not_null";
14888+
break;
14889+
case EACH:
14890+
agg_name = "bool_and_not_null";
14891+
break;
14892+
default:
14893+
elog(ERROR, "unkown ANY or ALL");
14894+
}
14895+
14896+
agg_call = makeFuncCall(SystemFuncName(agg_name),
14897+
list_make1(clause), location);
14898+
14899+
count_call = makeFuncCall(SystemFuncName("count"), NIL, location);
14900+
count_call->agg_star = true;
14901+
14902+
n->arg = (Expr *) of;
14903+
n->nulltesttype = IS_NOT_NULL;
14904+
n->location = location;
14905+
14906+
w->expr = (Expr *)makeAndExpr(
14907+
(Node*)makeSimpleA_Expr(AEXPR_OP, "=",
14908+
(Node*)count_call,
14909+
(Node*)makeIntConst(0, location),
14910+
location
14911+
),
14912+
(Node*)n,
14913+
location
14914+
);
14915+
w->result = (Expr *) makeBoolAConst((any_or_each == EACH) ? true : false, location);
14916+
w->location = location;
14917+
14918+
14919+
c->casetype = InvalidOid;
14920+
c->arg = NULL;
14921+
c->args = list_make1(w);
14922+
c->defresult = (Expr*)agg_call;
14923+
c->location = location;
14924+
14925+
14926+
target->val = (Node*)c;
1488614927
target->location = location;
14928+
subselect->targetList = list_make1(target);
1488714929

1488814930
switch(kind)
1488914931
{
1489014932
case ELEMENT:
14891-
funcname = "unnest_element";
14933+
unnest_name = "unnest_element";
1489214934
break;
1489314935
case KEY:
14894-
funcname = "unnest_key";
14936+
unnest_name = "unnest_key";
1489514937
break;
1489614938
case VALUE_P:
14897-
funcname = "unnest_value";
14939+
unnest_name = "unnest_value";
1489814940
break;
1489914941
default:
1490014942
elog(ERROR, "unkown ANY_EL");
1490114943
}
1490214944

14903-
func_call = makeFuncCall(SystemFuncName(funcname),
14904-
list_make2(of, makeBoolAConst(recursive, location)),
14905-
location);
14945+
unnest_call = makeFuncCall(SystemFuncName(unnest_name),
14946+
list_make2(of, makeBoolAConst(recursive, location)),
14947+
location);
1490614948

14907-
table_ref->functions = list_make1(list_make2(func_call, NIL));
14949+
table_ref->functions = list_make1(list_make2(unnest_call, NIL));
1490814950
table_ref->alias = makeAlias(aliasname, NIL);
14909-
14910-
subselect->targetList = list_make1(target);
14911-
subselect->fromClause = list_make1(table_ref); /* unnest(of) as aliasname */
14912-
subselect->whereClause = clause;
14951+
subselect->fromClause = list_make1(table_ref);
1491314952

1491414953
return subselect;
1491514954
}

src/include/catalog/pg_aggregate.h

+5-5
Original file line numberDiff line numberDiff line change
@@ -257,11 +257,11 @@ DATA(insert ( 2828 n 0 float8_regr_accum float8_covar_samp - - - f f 0
257257
DATA(insert ( 2829 n 0 float8_regr_accum float8_corr - - - f f 0 1022 0 0 0 "{0,0,0,0,0,0}" _null_ ));
258258

259259
/* boolean-and and boolean-or */
260-
DATA(insert ( 2517 n 0 booland_statefunc - bool_accum bool_accum_inv bool_alltrue f f 58 16 0 2281 16 _null_ _null_ ));
261-
DATA(insert ( 2518 n 0 boolor_statefunc - bool_accum bool_accum_inv bool_anytrue f f 59 16 0 2281 16 _null_ _null_ ));
262-
DATA(insert ( 2519 n 0 booland_statefunc - bool_accum bool_accum_inv bool_alltrue f f 58 16 0 2281 16 _null_ _null_ ));
263-
DATA(insert ( 7650 n 0 bool_accum bool_alltrue_notnull bool_accum bool_accum_inv bool_alltrue_notnull f f 58 2281 16 2281 16 _null_ _null_ ));
264-
DATA(insert ( 7651 n 0 bool_accum bool_anytrue_notnull bool_accum bool_accum_inv bool_anytrue_notnull f f 59 2281 16 2281 16 _null_ _null_ ));
260+
DATA(insert ( 2517 n 0 booland_statefunc - bool_accum bool_accum_inv bool_alltrue f f 58 16 0 2281 24 _null_ _null_ ));
261+
DATA(insert ( 2518 n 0 boolor_statefunc - bool_accum bool_accum_inv bool_anytrue f f 59 16 0 2281 24 _null_ _null_ ));
262+
DATA(insert ( 2519 n 0 booland_statefunc - bool_accum bool_accum_inv bool_alltrue f f 58 16 0 2281 24 _null_ _null_ ));
263+
DATA(insert ( 7650 n 0 bool_accum bool_alltrue_notnull bool_accum bool_accum_inv bool_alltrue_notnull f f 58 2281 24 2281 24 _null_ _null_ ));
264+
DATA(insert ( 7651 n 0 bool_accum bool_anytrue_notnull bool_accum bool_accum_inv bool_anytrue_notnull f f 59 2281 24 2281 24 _null_ _null_ ));
265265

266266
/* bitwise integer */
267267
DATA(insert ( 2236 n 0 int2and - - - - f f 0 21 0 0 0 _null_ _null_ ));

src/test/regress/expected/arrays.out

+43-10
Original file line numberDiff line numberDiff line change
@@ -971,18 +971,14 @@ SELECT * FROM array_op_test WHERE EACH ELEMENT OF t AS e SATISFIES (e = 'AAAAAA6
971971
-------+---------------+---------------
972972
16 | {14,63,85,11} | {AAAAAA66777}
973973
101 | {} | {}
974-
102 | {NULL} | {NULL}
975-
103 | |
976-
(4 rows)
974+
(2 rows)
977975

978976
SELECT * FROM array_op_test WHERE EACH ELEMENT OF i AS e SATISFIES (e = 11) ORDER BY seqno;
979-
seqno | i | t
980-
-------+--------+-----------------------------------------------------------------------------------------------------------------------------------------------------------
981-
93 | {11} | {AAAAAAAAAAA176,AAAAAAAAAAAAAA8666,AAAAAAAAAAAAAAA453,AAAAAAAAAAAAA85723,A68938,AAAAAAAAAAAAA9821,AAAAAAA48038,AAAAAAAAAAAAAAAAA59387,AA99927,AAAAA17383}
982-
101 | {} | {}
983-
102 | {NULL} | {NULL}
984-
103 | |
985-
(4 rows)
977+
seqno | i | t
978+
-------+------+-----------------------------------------------------------------------------------------------------------------------------------------------------------
979+
93 | {11} | {AAAAAAAAAAA176,AAAAAAAAAAAAAA8666,AAAAAAAAAAAAAAA453,AAAAAAAAAAAAA85723,A68938,AAAAAAAAAAAAA9821,AAAAAAA48038,AAAAAAAAAAAAAAAAA59387,AA99927,AAAAA17383}
980+
101 | {} | {}
981+
(2 rows)
986982

987983
-- array casts
988984
SELECT ARRAY[1,2,3]::text[]::int[]::float8[] AS "{1,2,3}";
@@ -2051,3 +2047,40 @@ SELECT width_bucket(5, ARRAY[3, 4, NULL]);
20512047
ERROR: thresholds array must not contain NULLs
20522048
SELECT width_bucket(5, ARRAY[ARRAY[1, 2], ARRAY[3, 4]]);
20532049
ERROR: thresholds must be one-dimensional array
2050+
--anytest
2051+
create table anytest(a int[]);
2052+
insert into anytest values
2053+
(NULL),
2054+
('{}'),
2055+
('{NULL}'),
2056+
('{1}'),
2057+
('{1,NULL}'),
2058+
('{2,NULL}'),
2059+
('{NULL,1}'),
2060+
('{NULL,2}');
2061+
SELECT a, (1 = ANY(a)), ANY ELEMENT OF a AS v SATISFIES (v = 1) FROM anytest;
2062+
a | ?column? | bool_or_not_null
2063+
----------+----------+------------------
2064+
| |
2065+
{} | f | f
2066+
{NULL} | |
2067+
{1} | t | t
2068+
{1,NULL} | t | t
2069+
{2,NULL} | |
2070+
{NULL,1} | t | t
2071+
{NULL,2} | |
2072+
(8 rows)
2073+
2074+
SELECT a, (1 = ALL(a)), EACH ELEMENT OF a AS v SATISFIES (v = 1) FROM anytest;
2075+
a | ?column? | bool_and_not_null
2076+
----------+----------+-------------------
2077+
| |
2078+
{} | t | t
2079+
{NULL} | |
2080+
{1} | t | t
2081+
{1,NULL} | |
2082+
{2,NULL} | f | f
2083+
{NULL,1} | |
2084+
{NULL,2} | f | f
2085+
(8 rows)
2086+

src/test/regress/output/misc.source

+2-1
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,7 @@ SELECT user_relns() AS user_relns
583583
abstime_tbl
584584
aggtest
585585
aggtype
586+
anytest
586587
array_index_op_test
587588
array_op_test
588589
arrtest
@@ -705,7 +706,7 @@ SELECT user_relns() AS user_relns
705706
tvvmv
706707
varchar_tbl
707708
xacttest
708-
(127 rows)
709+
(128 rows)
709710

710711
SELECT name(equipment(hobby_construct(text 'skywalking', text 'mer')));
711712
name

src/test/regress/sql/arrays.sql

+17
Original file line numberDiff line numberDiff line change
@@ -602,3 +602,20 @@ SELECT width_bucket(5, '{}');
602602
SELECT width_bucket('5'::text, ARRAY[3, 4]::integer[]);
603603
SELECT width_bucket(5, ARRAY[3, 4, NULL]);
604604
SELECT width_bucket(5, ARRAY[ARRAY[1, 2], ARRAY[3, 4]]);
605+
606+
607+
--anytest
608+
609+
create table anytest(a int[]);
610+
insert into anytest values
611+
(NULL),
612+
('{}'),
613+
('{NULL}'),
614+
('{1}'),
615+
('{1,NULL}'),
616+
('{2,NULL}'),
617+
('{NULL,1}'),
618+
('{NULL,2}');
619+
620+
SELECT a, (1 = ANY(a)), ANY ELEMENT OF a AS v SATISFIES (v = 1) FROM anytest;
621+
SELECT a, (1 = ALL(a)), EACH ELEMENT OF a AS v SATISFIES (v = 1) FROM anytest;

0 commit comments

Comments
 (0)