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

*: remove resolver.go #4988

Merged
merged 29 commits into from Nov 10, 2017
Merged

*: remove resolver.go #4988

merged 29 commits into from Nov 10, 2017

Conversation

XuHuaiyu
Copy link
Contributor

@XuHuaiyu XuHuaiyu commented Nov 2, 2017

refer to #4787
should be merged with https://github.com/pingcap/tidb-test/pull/398
This commit removes resolver.go completely.
Now TiDB resolves table name in preprocessor.go, and resolves column names when building logical plan.

Resolving col name when building logical plan will raise a problem like:

create table t(a int);
prepare stmt from 'select b from t'; // This sql should have caused an error, I'll fix it in next PR.

Conflicts:
	executor/prepared.go
	executor/prepared_test.go
	plan/physical_plan_test.go
@XuHuaiyu
Copy link
Contributor Author

XuHuaiyu commented Nov 2, 2017

/run-all-test

}

var resolverTests = []resolverTestCase{
{"select c1 from t1", true, ""},
Copy link
Member

Choose a reason for hiding this comment

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

Some cases need to move to logicalPlanBuilder TestPlanBuilder

}

func (p *preprocessor) handleUnionSelectList(u *ast.UnionSelectList) {
firstSelFields := u.Selects[0].GetResultFields()
Copy link
Member

Choose a reason for hiding this comment

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

Why do we need to change result fields. It seems we don't depend on it any more.

@@ -499,6 +523,19 @@ func (p *preprocessor) handleTableName(tn *ast.TableName) {
// Skip resolving the table to avoid error.
return
}
if p.inDeleteTableList {
Copy link
Member

Choose a reason for hiding this comment

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

it is only for delete statement. can we move this to buildDelete function ?

@XuHuaiyu
Copy link
Contributor Author

XuHuaiyu commented Nov 6, 2017

CI failed since #4613 relies on GetResultField of *ast.Join ....
I'll fix it soon.

@XuHuaiyu
Copy link
Contributor Author

XuHuaiyu commented Nov 7, 2017

/run-all-tests

c.Assert(err, IsNil)
c.Assert(fields, HasLen, 1)
// We do not create ResultFields anymore when preprocessing.
Copy link
Member

Choose a reason for hiding this comment

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

So can we remove this assert ?

@@ -1040,16 +1048,17 @@ func (s *testPlanSuite) TestRefine(c *C) {
},
{
sql: `select a from t where c = 'hanfei'`,
best: "TableReader(Table(t))->Sel([eq(cast(test.t.c), cast(hanfei))])->Projection",
best: "IndexReader(Index(t.c_d_e)[[0,0]])->Projection",
Copy link
Member

Choose a reason for hiding this comment

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

Why is this test changed ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

use test set sc.IgnoreTruncate to true,
SelectStmt reset this when executing, we only compile statement and reuse the sc.IgnoreTruncate set be UseStmt here, so this case changed.

@@ -902,7 +909,11 @@ func (a *havingAndOrderbyExprResolver) Leave(n ast.Node) (node ast.Node, ok bool
return n, true
}
}
a.err = errors.Errorf("Unknown Column %s", v.Name.Name.L)
cn := v.Name.Name.L
Copy link
Member

Choose a reason for hiding this comment

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

It seems this logic will be used in many places. Can we make it a function ?

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 didn't really find another place use this logic totally the same.
May keep it?

@@ -173,13 +173,7 @@ func existsCartesianProduct(p LogicalPlan) bool {
// The statement must be prepared before it can be passed to optimize function.
// We pass InfoSchema instead of getting from Context in case it is changed after resolving name.
func PrepareStmt(is infoschema.InfoSchema, ctx context.Context, node ast.Node) error {
Copy link
Member

Choose a reason for hiding this comment

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

Do we still need this function ??

Copy link
Member

Choose a reason for hiding this comment

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

@XuHuaiyu how about removing it ?

@XuHuaiyu
Copy link
Contributor Author

XuHuaiyu commented Nov 7, 2017

PTAL @hanfei1991

@XuHuaiyu
Copy link
Contributor Author

XuHuaiyu commented Nov 7, 2017

/run-all-tests

@XuHuaiyu XuHuaiyu added this to the 1.1 milestone Nov 7, 2017
@XuHuaiyu
Copy link
Contributor Author

XuHuaiyu commented Nov 7, 2017

CI failed since some error messages changed.
I'll try to fix them soon.

@@ -28,6 +28,7 @@ import (
"github.com/pingcap/tidb/sessionctx/variable"
"github.com/pingcap/tidb/sessionctx/varsutil"
"github.com/pingcap/tidb/types"
"strconv"
Copy link
Contributor

Choose a reason for hiding this comment

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

Move this line up.

return g.fields[index].Expr, true
ret := g.fields[index].Expr
if _, ok := ret.(*ast.AggregateFuncExpr); ok {
err = ErrIllegalReference.Gen("Reference '%s' not supported (reference to group function)", v.Name.OrigColName())
Copy link
Contributor

Choose a reason for hiding this comment

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

I think you can update the content of ErrIllegalReference directly.

if _, ok := ret.(*ast.AggregateFuncExpr); ok {
err = ErrIllegalReference.Gen("Reference '%s' not supported (reference to group function)", v.Name.OrigColName())
} else {
return g.fields[index].Expr, true
Copy link
Contributor

Choose a reason for hiding this comment

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

s/g.fields[index].Expr/ret

foundMatch := false
for _, v := range tableList {
if dn := v.Schema.L; dn != "" {
dbName = dn
Copy link
Contributor

Choose a reason for hiding this comment

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

If the first database name isn't empty and isn't the current database, and the next database name is empty, then the next database isn't the current database. Is there something wrong?

p.tables = append(p.tables, ts)
}

func getInnerFromParentheses(expr ast.ExprNode) ast.ExprNode {
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we use it?

name := f.ColumnAsName.L
if name == "" {
name = f.Column.Name.L
}
Copy link
Contributor

Choose a reason for hiding this comment

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

This name doesn't use. These codes are duplicated with follows.

@@ -1004,7 +1013,12 @@ func (g *gbyResolver) Leave(inNode ast.Node) (ast.Node, bool) {
return inNode, true
}
if index != -1 {
return g.fields[index].Expr, true
ret := g.fields[index].Expr
if _, ok := ret.(*ast.AggregateFuncExpr); ok {
Copy link
Member

Choose a reason for hiding this comment

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

It maybe an expression that contains a aggregate function.

@@ -1014,24 +1028,28 @@ func (g *gbyResolver) Leave(inNode ast.Node) (ast.Node, bool) {
g.err = errors.Errorf("Unknown column '%d' in 'group statement'", v.N)
return inNode, false
}
return g.fields[v.N-1].Expr, true
ret := g.fields[v.N-1].Expr
if _, ok := ret.(*ast.AggregateFuncExpr); ok {
Copy link
Member

Choose a reason for hiding this comment

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

ditto.

@@ -1416,6 +1440,17 @@ func (b *planBuilder) buildSelect(sel *ast.SelectStmt) LogicalPlan {
)
if sel.From != nil {
p = b.buildResultSetNode(sel.From.TableRefs)
// duplicate column name in one table is not allowed.
Copy link
Member

Choose a reason for hiding this comment

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

We should do this check in buildResultSetNode.

break
}
}
if !foundMatch {
Copy link
Member

Choose a reason for hiding this comment

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

What's the behaviour of delete a from (select * from t)a, t;

@@ -105,8 +116,17 @@ func (p *preprocessor) Leave(in ast.Node) (out ast.Node, ok bool) {
if !valid {
p.err = ErrUnknownExplainFormat.GenByArgs(x.Format)
}
case *ast.SelectStmt:
x.SetResultFields(p.fieldList)
Copy link
Member

Choose a reason for hiding this comment

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

Why do we still hold result fields ? can we remove this ?

@XuHuaiyu
Copy link
Contributor Author

XuHuaiyu commented Nov 8, 2017

/run-common-test tidb-test=pr4988
/run-integration-common-tests tidb-test=pr4988

@XuHuaiyu
Copy link
Contributor Author

XuHuaiyu commented Nov 8, 2017

/run-all-tests tidb-test=pr/398

@XuHuaiyu
Copy link
Contributor Author

XuHuaiyu commented Nov 8, 2017

PTAL @hanfei1991 @zimulala @zz-jason

@@ -89,7 +89,7 @@ func (s *testSuite) TestPrepared(c *C) {

// There should be schema changed error.
_, err = tk.Se.ExecutePreparedStmt(stmtId, 1)
c.Assert(plan.ErrSchemaChanged.Equal(err), IsTrue)
c.Assert(err, NotNil)
Copy link
Member

Choose a reason for hiding this comment

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

check the error message ?

CodeNoDB terror.ErrCode = mysql.ErrNoDB
CodeUnknownExplainFormat terror.ErrCode = mysql.ErrUnknownExplainFormat
CodeWrongGroupField = mysql.ErrWrongGroupField
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 add terror.ErrCode to be compatible with other error code definitions ?

@@ -173,13 +173,7 @@ func existsCartesianProduct(p LogicalPlan) bool {
// The statement must be prepared before it can be passed to optimize function.
// We pass InfoSchema instead of getting from Context in case it is changed after resolving name.
func PrepareStmt(is infoschema.InfoSchema, ctx context.Context, node ast.Node) error {
Copy link
Member

Choose a reason for hiding this comment

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

@XuHuaiyu how about removing it ?

type clauseCode int

const (
unknowClause clauseCode = 0
Copy link
Member

Choose a reason for hiding this comment

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

  1. unknowClause clauseCode = iota
  2. how about let all clause code have a common prefix, like "clauseCodeXXX" ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For my part, the current variable names may be better.

@@ -561,3 +571,38 @@ func (p *preprocessor) resolveAlterTableStmt(node *ast.AlterTableStmt) {
}
}
}

// handleTableSource checks name duplication
Copy link
Member

Choose a reason for hiding this comment

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

... checks origin table source duplication ... ?

@@ -48,6 +48,8 @@ type preprocessor struct {
/* For Select Statement. */
// table map to lookup and check table name conflict.
tableMap map[string]int
// table map to lookup and check derived-table(subselect) name conflict.
derivedTableMap map[string]int
Copy link
Member

@zz-jason zz-jason Nov 8, 2017

Choose a reason for hiding this comment

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

Is the int map values meaningless ? If so, how about derivedTableSet map[string]struct{} ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The int value is useful.

err = plan.ResolveName(stmt, is, ctx)
c.Assert(err, IsNil, comment)
err = plan.Preprocess(ctx, stmt, is, false)
c.Assert(err, IsNil)
Copy link
Member

Choose a reason for hiding this comment

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

add comment back ?

@zimulala
Copy link
Contributor

zimulala commented Nov 9, 2017

LGTM

@zimulala zimulala added the status/LGT1 Indicates that a PR has LGTM 1. label Nov 9, 2017
@@ -89,7 +89,7 @@ func (s *testSuite) TestPrepared(c *C) {

// There should be schema changed error.
_, err = tk.Se.ExecutePreparedStmt(stmtId, 1)
c.Assert(plan.ErrSchemaChanged.Equal(err), IsTrue)
c.Assert(err, NotNil)
Copy link
Member

Choose a reason for hiding this comment

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

Why change this

@@ -1119,6 +1118,11 @@ func (s *testSessionSuite) TestDelete(c *C) {
tk.MustExec("insert into t (F1) values ('1'), ('2');")
tk.MustExec("delete test1.t from test1.t inner join test.t where test1.t.F1 > test.t.F1")
tk1.MustQuery("select * from t;").Check(testkit.Rows("1"))

_, err := tk.Exec("delete a from (select * from t ) as a, t")
Copy link
Member

Choose a reason for hiding this comment

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

This test should be moved to logical plan test.

@@ -119,9 +119,7 @@ func (e *Execute) optimizePreparedPlan(ctx context.Context, is infoschema.InfoSc
vars.PreparedParams[i] = val
}
if prepared.SchemaVersion != is.SchemaMetaVersion() {
// If the schema version has changed we need to prepare it again,
Copy link
Member

Choose a reason for hiding this comment

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

Why remove the comments ?

@@ -151,6 +151,17 @@ func (b *planBuilder) buildResultSetNode(node ast.ResultSetNode) LogicalPlan {
col.DBName = model.NewCIStr("")
}
}
// duplicate column name in one table is not allowed.
Copy link
Member

Choose a reason for hiding this comment

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

duplicate -> Duplicate

colName := &ast.ColumnNameExpr{
Name: &ast.ColumnName{
Schema: col.DBName,
Table: col.TblName,
Name: col.ColName,
}}
ast.SetFlag(colName)
Copy link
Member

Choose a reason for hiding this comment

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

Why do we need to set flag for column name ? I grep the whole code. It seems there is the only place that sets flag

name = p.tableUniqueName(tableName.Schema, tableName.Name)
}
if _, ok := p.tableMap[name]; ok {
p.err = errors.Errorf("duplicated table/alias name %s", name)
Copy link
Member

Choose a reason for hiding this comment

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

Duplicated table name would be checked in logical plan builder ?

@XuHuaiyu
Copy link
Contributor Author

XuHuaiyu commented Nov 9, 2017

PTAL @hanfei1991

@XuHuaiyu
Copy link
Contributor Author

XuHuaiyu commented Nov 9, 2017

/run-all-tests tidb-test=pr/398

@XuHuaiyu
Copy link
Contributor Author

XuHuaiyu commented Nov 9, 2017

/run-common-test tidb-test=pr/398
/run-integration-common-tests tidb-test=pr/398

@hanfei1991
Copy link
Member

LGTM

@hanfei1991 hanfei1991 added status/LGT2 Indicates that a PR has LGTM 2. and removed status/LGT1 Indicates that a PR has LGTM 1. labels Nov 10, 2017
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

@coocood coocood merged commit 1521258 into pingcap:master Nov 10, 2017
@XuHuaiyu XuHuaiyu deleted the resolver branch November 10, 2017 07:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status/LGT2 Indicates that a PR has LGTM 2.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants