On 29/04/2016 18:05, Tom Lane wrote:
> Julien Rouhaud <[email protected]> writes:
>> The segfault is caused by quals_match_foreign_key() calling get_leftop()
>> and get_rightop() on a ScalarArrayOpExpr node.
>
>> Reordering the common fields of OpExpr and ScalarArrayOpExpr at the
>> beginning of the struct so the get_*op() work with either (as in
>> attached patch) fixes the issue.
>
>> I'm not sure that assuming this compatibility is the right way to fix
>> this though.
>
> It certainly isn't.
>
Agreed. New attached patch handles explicitly each node tag.
--
Julien Rouhaud
http://dalibo.com - http://dalibo.org
diff --git a/src/backend/optimizer/util/clauses.c
b/src/backend/optimizer/util/clauses.c
index 759566a..3b9715b 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -100,6 +100,7 @@ typedef struct
bool allow_restricted;
} has_parallel_hazard_arg;
+static List *get_opargs(const Expr *clause);
static bool aggregates_allow_partial_walker(Node *node,
partial_agg_context *context);
static bool contain_agg_clause_walker(Node *node, void *context);
@@ -197,6 +198,19 @@ make_opclause(Oid opno, Oid opresulttype, bool opretset,
return (Expr *) expr;
}
+static List *
+get_opargs(const Expr *clause)
+{
+ if (IsA(clause, OpExpr))
+ return ((OpExpr *) clause)->args;
+
+ if (IsA(clause, ScalarArrayOpExpr))
+ return ((ScalarArrayOpExpr *) clause)->args;
+
+ elog(ERROR, "unrecognized node type: %d",
+ (int) nodeTag(clause));
+}
+
/*
* get_leftop
*
@@ -206,10 +220,10 @@ make_opclause(Oid opno, Oid opresulttype, bool opretset,
Node *
get_leftop(const Expr *clause)
{
- const OpExpr *expr = (const OpExpr *) clause;
+ const List *args = get_opargs(clause);
- if (expr->args != NIL)
- return linitial(expr->args);
+ if (args != NIL)
+ return linitial(args);
else
return NULL;
}
@@ -223,10 +237,10 @@ get_leftop(const Expr *clause)
Node *
get_rightop(const Expr *clause)
{
- const OpExpr *expr = (const OpExpr *) clause;
+ const List *args = get_opargs(clause);
- if (list_length(expr->args) >= 2)
- return lsecond(expr->args);
+ if (list_length(args) >= 2)
+ return lsecond(args);
else
return NULL;
}
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers