Skip to content

Commit 3dc8c2d

Browse files
committed
This should fix CORE-6440: expression indices with COALESCE cannot be matched
1 parent c4b6e75 commit 3dc8c2d

2 files changed

Lines changed: 39 additions & 0 deletions

File tree

src/dsql/ExprNodes.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,27 @@ using namespace Jrd;
6767

6868
namespace
6969
{
70+
bool sameNodes(const ValueIfNode* node1, const CoalesceNode* node2, bool ignoreStreams)
71+
{
72+
// dimitr: COALESCE could be represented as ValueIfNode in older databases,
73+
// so compare them for actually being the same thing:
74+
// COALESCE(A, B) == VALUE_IF(A IS NULL, B, A)
75+
76+
if (node1 && node2)
77+
{
78+
const MissingBoolNode* const missing = node1->condition->as<MissingBoolNode>();
79+
if (missing && missing->arg->sameAs(node1->falseValue, false) &&
80+
node2->args->items.getCount() == 2 &&
81+
node2->args->items[0]->sameAs(node1->falseValue, ignoreStreams) &&
82+
node2->args->items[1]->sameAs(node1->trueValue, ignoreStreams))
83+
{
84+
return true;
85+
}
86+
}
87+
88+
return false;
89+
}
90+
7091
// Expand DBKEY for view
7192
void expandViewNodes(thread_db* tdbb, CompilerScratch* csb, StreamType stream,
7293
ValueExprNodeStack& stack, UCHAR blrOp)
@@ -2988,6 +3009,14 @@ ValueExprNode* CoalesceNode::copy(thread_db* tdbb, NodeCopier& copier) const
29883009
return node;
29893010
}
29903011

3012+
bool CoalesceNode::sameAs(const ExprNode* other, bool ignoreStreams) const
3013+
{
3014+
if (ExprNode::sameAs(other, ignoreStreams))
3015+
return true;
3016+
3017+
return sameNodes(other->as<ValueIfNode>(), this, ignoreStreams);
3018+
}
3019+
29913020
ValueExprNode* CoalesceNode::pass2(thread_db* tdbb, CompilerScratch* csb)
29923021
{
29933022
ValueExprNode::pass2(tdbb, csb);
@@ -11738,6 +11767,14 @@ ValueExprNode* ValueIfNode::copy(thread_db* tdbb, NodeCopier& copier) const
1173811767
return node;
1173911768
}
1174011769

11770+
bool ValueIfNode::sameAs(const ExprNode* other, bool ignoreStreams) const
11771+
{
11772+
if (ExprNode::sameAs(other, ignoreStreams))
11773+
return true;
11774+
11775+
return sameNodes(this, other->as<CoalesceNode>(), ignoreStreams);
11776+
}
11777+
1174111778
ValueExprNode* ValueIfNode::pass2(thread_db* tdbb, CompilerScratch* csb)
1174211779
{
1174311780
ValueExprNode::pass2(tdbb, csb);

src/dsql/ExprNodes.h

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

221221
virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc);
222222
virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
223+
virtual bool sameAs(const ExprNode* other, bool ignoreStreams) const;
223224
virtual ValueExprNode* pass2(thread_db* tdbb, CompilerScratch* csb);
224225
virtual dsc* execute(thread_db* tdbb, jrd_req* request) const;
225226

@@ -1554,6 +1555,7 @@ class ValueIfNode : public TypedNode<ValueExprNode, ExprNode::TYPE_VALUE_IF>
15541555

15551556
virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc);
15561557
virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
1558+
virtual bool sameAs(const ExprNode* other, bool ignoreStreams) const;
15571559
virtual ValueExprNode* pass2(thread_db* tdbb, CompilerScratch* csb);
15581560
virtual dsc* execute(thread_db* tdbb, jrd_req* request) const;
15591561

0 commit comments

Comments
 (0)