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

Optimize large case-when in simple form to constant lookup #14317

Open
TennyZhuang opened this issue Jan 3, 2024 · 4 comments
Open

Optimize large case-when in simple form to constant lookup #14317

TennyZhuang opened this issue Jan 3, 2024 · 4 comments

Comments

@TennyZhuang
Copy link
Contributor

TennyZhuang commented Jan 3, 2024

PostgreSQL supports a simple-form case-when expression:

create table test (a int);
insert into test values (1),(2),(3),(5);
SELECT a,
       CASE a WHEN 1 THEN 'one'
              WHEN 2 THEN 'two'
              ELSE 'other'
       END
    FROM test;

In such case, if there is a large number of arms (e.g. 500+), it's better to optimize it to a constant lookup.

struct LookupExpression<S: Scalar> {
    arms: HashMap<Option<S>, BoxedExpression>,
    fallback: BoxedExpression,
}

In addition, if users write a case-when expression that can be converted to the simple form, we can also normalize it in optimizer easily:

SELECT a,
       CASE WHEN a=1 THEN 'one'
            WHEN a=2 THEN 'two'
            ELSE 'other'
       END
    FROM test;

Note: the corner cases should be covered:

SELECT 
       CASE a
              WHEN 1 THEN 'one'
              WHEN 1 THEN 'oneone'
              ELSE 'other',
       CASE a::decimal 
              WHEN 1.0 THEN 'one'
              WHEN 1 THEN 'oneone'
              ELSE 'other'
       END
    FROM test;
@github-actions github-actions bot added this to the release-1.6 milestone Jan 3, 2024
@TennyZhuang TennyZhuang added the good first issue Good for newcomers label Jan 3, 2024
@chenzl25
Copy link
Contributor

chenzl25 commented Jan 5, 2024

I suggest performing this optimization in the binder phase because it is more straightforward and easier to implement.

pub(super) fn bind_case(

Copy link
Contributor

github-actions bot commented Mar 6, 2024

This issue has been open for 60 days with no activity. Could you please update the status? Feel free to continue discussion or close as not planned.

@xzhseh
Copy link
Contributor

xzhseh commented Mar 6, 2024

Some future to-dos:

  1. refactor the current bind_case, some branches are pretty similar and could be potentially combined together.
  2. regarding corner case, e.g., the one mentioned in above description
  3. CBO for constant lookup, and we can get rid of a preset limit for number of arms (i.e., 30 at present)

@xzhseh xzhseh removed this from the release-1.6 milestone Mar 6, 2024
Copy link
Contributor

This issue has been open for 60 days with no activity. Could you please update the status? Feel free to continue discussion or close as not planned.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants