@@ -176,7 +176,7 @@ static void processCASbits(int cas_bits, int location, const char *constrType,
176
176
bool *deferrable, bool *initdeferred, bool *not_valid,
177
177
bool *no_inherit, core_yyscan_t yyscanner);
178
178
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,
180
180
const char *aliasname, Node *clause, int location);
181
181
182
182
%}
@@ -12064,21 +12064,13 @@ c_expr: columnref { $$ = $1; }
12064
12064
{
12065
12065
SubLink *n = makeNode(SubLink);
12066
12066
12067
- n->subLinkType = EXISTS_SUBLINK ;
12067
+ n->subLinkType = EXPR_SUBLINK ;
12068
12068
n->subLinkId = 0 ;
12069
12069
n->testexpr = NULL ;
12070
12070
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 );
12077
12072
n->location = @1 ;
12078
- if ($1 == EACH)
12079
- $$ = makeNotExpr((Node *)n, @1 );
12080
- else
12081
- $$ = (Node *)n;
12073
+ $$ = (Node *)n;
12082
12074
}
12083
12075
;
12084
12076
@@ -14873,43 +14865,90 @@ makeRecursiveViewSelect(char *relname, List *aliases, Node *query)
14873
14865
}
14874
14866
14875
14867
static SelectStmt *
14876
- makeElementSubselect(int kind, bool recursive, Node *of,
14868
+ makeElementSubselect(int any_or_each, int kind, bool recursive, Node *of,
14877
14869
const char *aliasname, Node *clause, int location)
14878
14870
{
14879
14871
ResTarget *target = makeNode(ResTarget);
14880
- FuncCall *func_call ;
14872
+ FuncCall *unnest_call, *agg_call, *count_call ;
14881
14873
RangeFunction *table_ref = makeNode(RangeFunction);
14882
14874
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 */
14884
14883
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;
14886
14927
target->location = location;
14928
+ subselect->targetList = list_make1(target);
14887
14929
14888
14930
switch(kind)
14889
14931
{
14890
14932
case ELEMENT:
14891
- funcname = "unnest_element";
14933
+ unnest_name = "unnest_element";
14892
14934
break;
14893
14935
case KEY:
14894
- funcname = "unnest_key";
14936
+ unnest_name = "unnest_key";
14895
14937
break;
14896
14938
case VALUE_P:
14897
- funcname = "unnest_value";
14939
+ unnest_name = "unnest_value";
14898
14940
break;
14899
14941
default :
14900
14942
elog (ERROR , " unkown ANY_EL" );
14901
14943
}
14902
14944
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);
14906
14948
14907
- table_ref->functions = list_make1(list_make2(func_call , NIL));
14949
+ table_ref->functions = list_make1(list_make2(unnest_call , NIL));
14908
14950
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);
14913
14952
14914
14953
return subselect;
14915
14954
}
0 commit comments