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

planner: eliminate if null on non null column #7924

Merged

Conversation

zhexuany
Copy link
Contributor

@zhexuany zhexuany commented Oct 16, 2018

What problem does this PR solve?

This PR resolves #7918.

What is changed and how it works?

When buildProjection(), we filter ast.SelectField using certain rules. For these fields which does not pass the rules entering original logic.

details will be provided later.

Check List

Tests

the test case will be added later.

Code changes

Side effects

  • Possible performance regression

Related changes

@zhexuany zhexuany force-pushed the eliminate_if_null_on_non_null_column branch from c501899 to 293d420 Compare October 16, 2018 19:45
@zhexuany zhexuany added sig/planner SIG: Planner type/enhancement The issue or PR belongs to an enhancement. status/WIP labels Oct 16, 2018
@zz-jason
Copy link
Member

zz-jason commented Oct 17, 2018

@zhexuany please fix ci && add tests

@XuHuaiyu XuHuaiyu changed the title eliminate if null on non null column planner: eliminate if null on non null column Oct 17, 2018
@zhexuany zhexuany force-pushed the eliminate_if_null_on_non_null_column branch from 293d420 to 3a3c360 Compare October 17, 2018 02:55
@winoros
Copy link
Member

winoros commented Oct 17, 2018

This can only partially solve it.
ifnull is not only generated during plan building, but also generated by some optimization rule.
This can be done once we know its arg is not null. So it should actually be part of this method

func ifNullFoldHandler(expr *ScalarFunction) (Expression, bool) {

But we cannot integrate it since we don't maintain the column's NULL or NOT NULL information.

var remainingFields []*ast.SelectField
fieldSet := make([]bool, len(fields))
for idx, field := range fields {
if strings.Contains(field.Text(), ast.Ifnull) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we use if !bool to reduce the layers?

schema := expression.NewSchema(make([]*expression.Column, 0, len(remainingFields))...)
oldLen := 0
for _, field := range remainingFields {
newExpr, np, err := b.rewrite(field.Expr, p, mapper, true)
Copy link
Member

Choose a reason for hiding this comment

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

Do the optimization here may be a better idea.

@zhexuany zhexuany force-pushed the eliminate_if_null_on_non_null_column branch from 3a3c360 to 31c13ff Compare October 17, 2018 04:02
var colFound *model.ColumnInfo
if ds, ok := p.(*DataSource); ok {
colFound = model.FindColumnInfo(ds.Columns, cnExpr.Name.Name.L)
if mysql.HasNotNullFlag(colFound.Flag) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we extract these judgement to a function? So that it has strong scalability.

@zhexuany zhexuany force-pushed the eliminate_if_null_on_non_null_column branch from 31c13ff to 4ff9256 Compare October 17, 2018 04:51
@zhexuany
Copy link
Contributor Author

@winoros @lzmhhh123 PTAL

@zhexuany
Copy link
Contributor Author

/run-all-tests

@lzmhhh123
Copy link
Contributor

LGTM.

@lzmhhh123 lzmhhh123 added the status/LGT1 Indicates that a PR has LGTM 1. label Oct 17, 2018
Copy link
Member

@winoros winoros left a comment

Choose a reason for hiding this comment

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

code changes lgtm

@@ -576,6 +576,23 @@ func (b *PlanBuilder) buildProjectionField(id, position int, field *ast.SelectFi
}
}

func eliminateIfNullOnNonNullColumn(p LogicalPlan, expr expression.Expression) expression.Expression {
Copy link
Member

Choose a reason for hiding this comment

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

We usually use NotNull instead of NonNull.

Copy link
Member

Choose a reason for hiding this comment

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

s/NonNullColumn/NotNullCol/

@@ -585,6 +602,7 @@ func (b *PlanBuilder) buildProjection(p LogicalPlan, fields []*ast.SelectField,
oldLen := 0
for _, field := range fields {
newExpr, np, err := b.rewrite(field.Expr, p, mapper, true)
newExpr = eliminateIfNullOnNonNullColumn(p, newExpr)
Copy link
Member

Choose a reason for hiding this comment

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

We can add a TODO here: Do this optimization automatically when creating new scalar function.

@@ -576,6 +576,23 @@ func (b *PlanBuilder) buildProjectionField(id, position int, field *ast.SelectFi
}
}

func eliminateIfNullOnNonNullColumn(p LogicalPlan, expr expression.Expression) expression.Expression {
Copy link
Member

Choose a reason for hiding this comment

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

s/NonNullColumn/NotNullCol/

planner/core/logical_plan_builder.go Outdated Show resolved Hide resolved
@zhexuany zhexuany force-pushed the eliminate_if_null_on_non_null_column branch from 3d1496f to 3614eb7 Compare October 17, 2018 10:16
@zhexuany zhexuany force-pushed the eliminate_if_null_on_non_null_column branch from 3614eb7 to 7000f42 Compare October 17, 2018 10:18

return colRef
}
scalarExpr.SetArgs(exprChildren)
Copy link
Member

Choose a reason for hiding this comment

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

this can be removed.

exprChildren[i] = eliminateIfNullOnNotNullCol(p, exprChildren[i])
}

if scalarExpr.FuncName.L == ast.Ifnull {
Copy link
Member

Choose a reason for hiding this comment

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

how about:

if scalarExpr.FuncName.L != ast.Ifnull {
	return expr
}

@zhexuany
Copy link
Contributor Author

@zz-jason @winkyao PTAL

Copy link
Member

@zz-jason zz-jason left a comment

Choose a reason for hiding this comment

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

LGTM

@zz-jason zz-jason added status/LGT2 Indicates that a PR has LGTM 2. and removed status/LGT1 Indicates that a PR has LGTM 1. labels Oct 17, 2018
@zz-jason
Copy link
Member

/run-all-tests

@zhexuany zhexuany merged commit 6e525f9 into pingcap:master Oct 17, 2018
@zhexuany zhexuany deleted the eliminate_if_null_on_non_null_column branch October 17, 2018 14:20
iamzhoug37 pushed a commit to iamzhoug37/tidb that referenced this pull request Oct 25, 2018
bugfix fixed pingcap#7518

expression: MySQL compatible current_user function (pingcap#7801)

plan: propagate constant over outer join (pingcap#7794)

- extract `outerCol = const` from join conditions and filter conditions,
  substitute `outerCol` in join conditions with `const`;
- extract `outerCol = innerCol` from join conditions, derive new join
  conditions based on this column equal condition and `outerCol` related
  expressions in join conditions and filter conditions;

util/timeutil: fix data race caused by forgetting set stats lease to 0 (pingcap#7901)

stats: handle ddl event for partition table (pingcap#7903)

plan: implement Operand and Pattern of cascades planner. (pingcap#7910)

planner: not convert to TableDual if empty range is derived from deferred constants (pingcap#7808)

plan: move projEliminate behind aggEliminate (pingcap#7909)

admin: fix admin check table bug of byte compare (pingcap#7887)

* admin: remove reflect deepEqual

stats: fix panic caused by empty histogram (pingcap#7912)

plan: fix panic caused by empty schema of LogicalTableDual (pingcap#7906)

* fix drop view if exist error (pingcap#7833)

executor: refine `explain analyze` (pingcap#7888)

executor: add an variable to compatible with MySQL insert for OGG (pingcap#7863)

expression: maintain `DeferredExpr` in aggressive constant folding. (pingcap#7915)

stats: fix histogram boundaries overflow error (pingcap#7883)

ddl:support the definition of `null` change to `not null` using `alter table` (pingcap#7771)

* ddl:support the definition of null change to not null using alter table

ddl: add check when create table with foreign key. (pingcap#7885)

* ddl: add check when create table with foreign key

planner: eliminate if null on non null column (pingcap#7924)

executor: fix a bug in point get (pingcap#7934)

planner, executor: refine ColumnPrune for LogicalUnionAll (pingcap#7930)

executor: fix panic when limit is too large (pingcap#7936)

ddl: add TiDB version to metrics (pingcap#7902)

stats: limit the length of sample values (pingcap#7931)

vendor: update tipb (pingcap#7893)

planner: support the Group and GroupExpr for the cascades planner (pingcap#7917)

store/tikv: log more information when other err occurs (pingcap#7948)

types: fix date time parse (pingcap#7933)

ddl: just print error message when ddl job is normal to calcel, to eliminate noisy log (pingcap#7875)

stats: update delta info for partition table (pingcap#7947)

explaintest: add explain test for partition pruning (pingcap#7505)

util: move disjoint set to util package (pingcap#7950)

util: add PreAlloc4Row and Insert for Chunk and List (pingcap#7916)

executor: add the slow log for commit (pingcap#7951)

expression: add builtin json_keys (pingcap#7776)

privilege: add USAGE in `show grants` for mysql compatibility (pingcap#7955)

ddl: fix invailid ddl job panic (pingcap#7940)

*: move ast.NewValueExpr to standalone parser_driver package (pingcap#7952)

Make the ast package get rid of the dependency of types.Datum

server: allow cors http request (pingcap#7939)

*: move `Statement` and `RecordSet` from ast to sqlexec package (pingcap#7970)

pr suggestion update

executor/aggfuncs: split unit tests to corresponding file (pingcap#7993)

store/tikv: fix typo (pingcap#7990)

executor, planner: clone proj schema for different children in buildProj4Union (pingcap#7999)

executor: let information_schema be the first database in ShowDatabases (pingcap#7938)

stats: use local feedback for partition table (pingcap#7963)

executor: add unit test for aggfuncs (pingcap#7966)

server: add log for binary execute statement (pingcap#7987)

admin: refine admin check decoder (pingcap#7862)

executor: improve wide table insert & update performance (pingcap#7935)

ddl: fix reassigned partition id in `truncate table` does not take effect (pingcap#7919)

fix reassigned partition id in truncate table does not take effect

add changelog for 2.1.0 rc4 (pingcap#8020)

*: make parser package dependency as small as possible (pingcap#7989)

parser: support `:=` in the `set` syntax (pingcap#8018)

According to MySQL document, `set` use the = assignment operator,
but the := assignment operator is also permitted

stats: garbage collect stats for partition table (pingcap#7962)

docs: add the proposal for the column pool (pingcap#7988)

expression: refine built-in func truncate to support uint arg (pingcap#8000)

stats: support show stats for partition table (pingcap#8023)

stats: update error rate for partition table (pingcap#8022)

stats: fix estimation for out of range point queries (pingcap#8015)

*: move parser to a separate repository (pingcap#8036)

executor: fix wrong result when index join on union scan. (pingcap#8031)

Do not modify Plan of dataReaderBuilder directly, because it would
impact next batch of outer rows, as well as other concurrent inner
workers. Instead, build a local child builder to store the child plan.

planner: fix a panic of a cached prepared statement with IndexScan (pingcap#8017)

*: fix the issue of executing DDL after executing SQL failure in txn (pingcap#8044)

* ddl, executor: fix the issue of executing DDL after executing SQL failure in txn

add unit test

remove debug info

add like evaluator case sensitive test

ddl, domain: make schema correct after canceling jobs (pingcap#7997)

unit test fix

code format

proposal: maintaining histograms in plan. (pingcap#7605)

support _tidb_rowid for table scan range (pingcap#8047)

var rename fix
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
sig/planner SIG: Planner status/LGT2 Indicates that a PR has LGTM 2. type/enhancement The issue or PR belongs to an enhancement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

eliminate ifnull projection on not null column
5 participants