Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BugFix] fix invalid expression usage #56064

Merged
merged 2 commits into from
Feb 28, 2025

Conversation

xhumanoid
Copy link
Contributor

@xhumanoid xhumanoid commented Feb 19, 2025

regression introduced in
#44588

expr_context(...)

        // Copy expr to prevent two ExprContexts from owning the same Expr, which will cause the same Expr to be
        // closed twice.
        // - The ExprContext in the `original _opts.conjunct_ctxs_ptr` will own an Expr and all its children.
        // - The newly created ExprContext here will also own this Expr.
        auto* new_expr = Expr::copy(obj_pool, root_expr);
        new_expr_ctx = obj_pool->add(new ExprContext(new_expr));
        RETURN_IF_ERROR(new_expr_ctx->prepare(state));
        RETURN_IF_ERROR(new_expr_ctx->open(state));

create copy of root_expr as new_expr and new ExprContext pupulate ExprContext._fn_contexts and update VectorizedFunctionCallExpr._fn_context_index inside new_expr

after return from function we do call of get_predicate_value with new_expr_ctx + root_expr inside root_expr we can have incorrect VectorizedFunctionCallExpr._fn_context_index, because indexes apply for another context

as result later we have errors

    @         0x16c18359 google::LogMessageFatal::~LogMessageFatal()
    @         0x104f7c96 starrocks::ExprContext::fn_context(int)
    @         0x105b4c11 starrocks::VectorizedFunctionCallExpr::evaluate_checked(starrocks::ExprContext*, starrocks::Chunk*)
    @         0x103a737a starrocks::VectorizedCastToStringExpr<(starrocks::LogicalType)51, false>::evaluate_checked(starrocks::ExprContext*, starrocks::Chunk*)
    FunctionContext* fn_context(int i) {
        DCHECK_GE(i, 0);
        DCHECK_LT(i, _fn_contexts.size());
        return _fn_contexts[i];
    }

for our case _fn_context_index = 3 and _fn_contexts.size() = 2

after fix we will use proper updated expressions with correct expression context

Why I'm doing:

What I'm doing:

Fixes #issue

What type of PR is this:

  • BugFix
  • Feature
  • Enhancement
  • Refactor
  • UT
  • Doc
  • Tool

Does this PR entail a change in behavior?

  • Yes, this PR will result in a change in behavior.
  • No, this PR will not result in a change in behavior.

If yes, please specify the type of change:

  • Interface/UI changes: syntax, type conversion, expression evaluation, display information
  • Parameter changes: default values, similar parameters but with different default values
  • Policy changes: use new policy to replace old one, functionality automatically enabled
  • Feature removed
  • Miscellaneous: upgrade & downgrade compatibility, etc.

Checklist:

  • I have added test cases for my bug fix or my new feature
  • This pr needs user documentation (for new or modified features or behaviors)
    • I have added documentation for my new feature or new function
  • This is a backport pr

Bugfix cherry-pick branch check:

The feature introduced only from 3.4 version and unavailable in previous releases

  • I have checked the version labels which the pr will be auto-backported to the target branch
    • 3.4
    • 3.3
    • 3.2
    • 3.1
    • 3.0

@xhumanoid xhumanoid requested a review from a team as a code owner February 19, 2025 15:10
@CLAassistant
Copy link

CLAassistant commented Feb 19, 2025

CLA assistant check
All committers have signed the CLA.

@xhumanoid
Copy link
Contributor Author

@ZiheLiu could you please review
you introduced initial feature

regression introduced in
StarRocks#44588

expr_context(...)
```
        // Copy expr to prevent two ExprContexts from owning the same Expr, which will cause the same Expr to be
        // closed twice.
        // - The ExprContext in the `original _opts.conjunct_ctxs_ptr` will own an Expr and all its children.
        // - The newly created ExprContext here will also own this Expr.
        auto* new_expr = Expr::copy(obj_pool, root_expr);
        new_expr_ctx = obj_pool->add(new ExprContext(new_expr));
        RETURN_IF_ERROR(new_expr_ctx->prepare(state));
        RETURN_IF_ERROR(new_expr_ctx->open(state));
```

create copy of root_expr as new_expr and new ExprContext
pupulate ExprContext._fn_contexts and update VectorizedFunctionCallExpr._fn_context_index inside new_expr

after return from function we do call of get_predicate_value with new_expr_ctx + root_expr
inside root_expr we can have incorrect VectorizedFunctionCallExpr._fn_context_index, because indexes apply for another context

as result later we have errors

    @         0x16c18359 google::LogMessageFatal::~LogMessageFatal()
    @         0x104f7c96 starrocks::ExprContext::fn_context(int)
    @         0x105b4c11 starrocks::VectorizedFunctionCallExpr::evaluate_checked(starrocks::ExprContext*, starrocks::Chunk*)
    @         0x103a737a starrocks::VectorizedCastToStringExpr<(starrocks::LogicalType)51, false>::evaluate_checked(starrocks::ExprContext*, starrocks::Chunk*)

```
    FunctionContext* fn_context(int i) {
        DCHECK_GE(i, 0);
        DCHECK_LT(i, _fn_contexts.size());
        return _fn_contexts[i];
    }
```

for our case _fn_context_index = 3 and _fn_contexts.size() = 2

after fix we will use proper updated expressions with correct expression context

Signed-off-by: Aliaksei Dziomin <[email protected]>
@xhumanoid xhumanoid force-pushed the fix-incorrect-expression branch from 9852011 to 0b14ed1 Compare February 19, 2025 15:30
@@ -424,7 +424,7 @@ requires(!lt_is_date<SlotType>) Status ChunkPredicateBuilder<E, Type>::normalize
ValueType value;
ASSIGN_OR_RETURN(auto* expr_context, _exprs[i].expr_context(_opts.obj_pool, _opts.runtime_state));
bool ok =
get_predicate_value<Negative>(_opts.obj_pool, slot, root_expr, expr_context, &value, &op, &status);
get_predicate_value<Negative>(_opts.obj_pool, slot, expr_context->root(), expr_context, &value, &op, &status);
Copy link
Contributor

@ZiheLiu ZiheLiu Feb 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great! Thanks a lot for your contribution.

Should use get_root_expr(expr_context->root()) instead of expr_context->root().

Maybe it's better to modify BoxedExpr::root() as follows and call _exprs[i].root() instead of expr_context->root().

Expr* BoxedExpr::root() const {
    if (new_expr_ctx == nullptr) {
        return get_root_expr(root_expr);
    } else {
        return get_root_expr(new_expr_ctx);
    }
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should use get_root_expr(expr_context->root()) instead of expr_context->root().

ok, will update

Maybe it's better to modify BoxedExpr::root() as follows and call _exprs[i].root() instead of expr_context->root().

i think it will be more error prone, because need to keep in mind about side effects of expr_context
and root() will return different results before and after expr_context()

Copy link
Contributor

@ZiheLiu ZiheLiu Feb 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think it will be more error prone, because need to keep in mind about side effects of expr_context
and root() will return different results before and after expr_context()

Make sense. How about making expr_context() return std::pair<ExprContext*, Expr*> [ctx, root] instead of ExprContext*? Then we can use this new root and ctx, which gives a better way to avoid using the new ctx with the old root.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i see at least one place where we need just context, without second part
so as fix i think it have to be enough, but for future refactoring can discuss

@github-actions github-actions bot added 3.3 and removed 3.3 labels Feb 26, 2025
Signed-off-by: Aliaksei Dziomin <[email protected]>
@xhumanoid xhumanoid force-pushed the fix-incorrect-expression branch from a678ab6 to 5795a73 Compare February 27, 2025 13:23
Copy link

[Java-Extensions Incremental Coverage Report]

pass : 0 / 0 (0%)

Copy link

[FE Incremental Coverage Report]

pass : 0 / 0 (0%)

Copy link

[BE Incremental Coverage Report]

fail : 3 / 4 (75.00%)

file detail

path covered_line new_line coverage not_covered_line_detail
🔵 be/src/exec/olap_scan_prepare.cpp 3 4 75.00% [539]

@kangkaisen kangkaisen merged commit 0fc6efc into StarRocks:main Feb 28, 2025
48 of 49 checks passed
Copy link

@Mergifyio backport branch-3.4

@github-actions github-actions bot removed the 3.4 label Feb 28, 2025
Copy link
Contributor

mergify bot commented Feb 28, 2025

backport branch-3.4

✅ Backports have been created

mergify bot pushed a commit that referenced this pull request Feb 28, 2025
Signed-off-by: Aliaksei Dziomin <[email protected]>
(cherry picked from commit 0fc6efc)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants