Skip to content

Commit 350aa6f

Browse files
committed
This should fix CORE-6440: expression indices with COALESCE cannot be matched
1 parent b4386db commit 350aa6f

2 files changed

Lines changed: 40 additions & 0 deletions

File tree

src/dsql/ExprNodes.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,28 @@ using namespace Jrd;
7070

7171
namespace
7272
{
73+
bool sameNodes(CompilerScratch* csb, const ValueIfNode* node1,
74+
const CoalesceNode* node2, bool ignoreStreams)
75+
{
76+
// dimitr: COALESCE could be represented as ValueIfNode in older databases,
77+
// so compare them for actually being the same thing:
78+
// COALESCE(A, B) == VALUE_IF(A IS NULL, B, A)
79+
80+
if (node1 && node2)
81+
{
82+
const auto missing = nodeAs<MissingBoolNode>(node1->condition);
83+
if (missing && missing->arg->sameAs(csb, node1->falseValue, false) &&
84+
node2->args->items.getCount() == 2 &&
85+
node2->args->items[0]->sameAs(csb, node1->falseValue, ignoreStreams) &&
86+
node2->args->items[1]->sameAs(csb, node1->trueValue, ignoreStreams))
87+
{
88+
return true;
89+
}
90+
}
91+
92+
return false;
93+
}
94+
7395
// Try to expand the given stream. If it's a view reference, collect its base streams
7496
// (the ones directly residing in the FROM clause) and recurse.
7597
void expandViewStreams(CompilerScratch* csb, StreamType baseStream, SortedStreamList& streams)
@@ -3692,6 +3714,14 @@ ValueExprNode* CoalesceNode::copy(thread_db* tdbb, NodeCopier& copier) const
36923714
return node;
36933715
}
36943716

3717+
bool CoalesceNode::sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const
3718+
{
3719+
if (ExprNode::sameAs(csb, other, ignoreStreams))
3720+
return true;
3721+
3722+
return sameNodes(csb, nodeAs<ValueIfNode>(other), this, ignoreStreams);
3723+
}
3724+
36953725
ValueExprNode* CoalesceNode::pass2(thread_db* tdbb, CompilerScratch* csb)
36963726
{
36973727
ValueExprNode::pass2(tdbb, csb);
@@ -13373,6 +13403,14 @@ ValueExprNode* ValueIfNode::copy(thread_db* tdbb, NodeCopier& copier) const
1337313403
return node;
1337413404
}
1337513405

13406+
bool ValueIfNode::sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const
13407+
{
13408+
if (ExprNode::sameAs(csb, other, ignoreStreams))
13409+
return true;
13410+
13411+
return sameNodes(csb, this, nodeAs<CoalesceNode>(other), ignoreStreams);
13412+
}
13413+
1337613414
ValueExprNode* ValueIfNode::pass2(thread_db* tdbb, CompilerScratch* csb)
1337713415
{
1337813416
ValueExprNode::pass2(tdbb, csb);

src/dsql/ExprNodes.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,7 @@ class CoalesceNode : public TypedNode<ValueExprNode, ExprNode::TYPE_COALESCE>
308308

309309
virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc);
310310
virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
311+
virtual bool sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const;
311312
virtual ValueExprNode* pass2(thread_db* tdbb, CompilerScratch* csb);
312313
virtual dsc* execute(thread_db* tdbb, jrd_req* request) const;
313314

@@ -2150,6 +2151,7 @@ class ValueIfNode : public TypedNode<ValueExprNode, ExprNode::TYPE_VALUE_IF>
21502151

21512152
virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc);
21522153
virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
2154+
virtual bool sameAs(CompilerScratch* csb, const ExprNode* other, bool ignoreStreams) const;
21532155
virtual ValueExprNode* pass2(thread_db* tdbb, CompilerScratch* csb);
21542156
virtual dsc* execute(thread_db* tdbb, jrd_req* request) const;
21552157

0 commit comments

Comments
 (0)