Skip to content

Commit e61df54

Browse files
committed
Implement #7865: Consider the return value of deterministic functions to be invariant if all its arguments are invariant
1 parent 82c4a08 commit e61df54

File tree

2 files changed

+28
-4
lines changed

2 files changed

+28
-4
lines changed

src/dsql/ExprNodes.cpp

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13429,12 +13429,28 @@ ValueExprNode* UdfCallNode::pass1(thread_db* tdbb, CompilerScratch* csb)
1342913429

1343013430
ValueExprNode* UdfCallNode::pass2(thread_db* tdbb, CompilerScratch* csb)
1343113431
{
13432-
if (function->fun_deterministic && !function->fun_inputs)
13432+
if (function->fun_deterministic)
1343313433
{
1343413434
// Deterministic function without input arguments is expected to be
13435-
// always returning the same result, so it can be marked as invariant
13436-
nodFlags |= FLAG_INVARIANT;
13437-
csb->csb_invariants.push(&impureOffset);
13435+
// always returning the same result, so it can be marked as invariant.
13436+
// Ditto if all its input arguments are deterministic expressions
13437+
// that do not reference any stream.
13438+
13439+
bool invariant = true;
13440+
for (const auto& arg : args->items)
13441+
{
13442+
if (!arg->deterministic() || arg->containsAnyStream())
13443+
{
13444+
invariant = false;
13445+
break;
13446+
}
13447+
}
13448+
13449+
if (invariant)
13450+
{
13451+
nodFlags |= FLAG_INVARIANT;
13452+
csb->csb_invariants.push(&impureOffset);
13453+
}
1343813454
}
1343913455

1344013456
ValueExprNode::pass2(tdbb, csb);

src/dsql/Nodes.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,14 @@ class ExprNode : public DmlNode
698698
return false;
699699
}
700700

701+
bool containsAnyStream() const
702+
{
703+
SortedStreamList nodeStreams;
704+
collectStreams(nodeStreams);
705+
706+
return nodeStreams.hasData();
707+
}
708+
701709
virtual bool dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const;
702710

703711
virtual ExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch)

0 commit comments

Comments
 (0)