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
*: remove resolver.go #4988
Conversation
Conflicts: executor/prepared.go executor/prepared_test.go plan/physical_plan_test.go
/run-all-test |
} | ||
|
||
var resolverTests = []resolverTestCase{ | ||
{"select c1 from t1", true, ""}, |
There was a problem hiding this comment.
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
plan/preprocess.go
Outdated
} | ||
|
||
func (p *preprocessor) handleUnionSelectList(u *ast.UnionSelectList) { | ||
firstSelFields := u.Selects[0].GetResultFields() |
There was a problem hiding this comment.
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.
plan/preprocess.go
Outdated
@@ -499,6 +523,19 @@ func (p *preprocessor) handleTableName(tn *ast.TableName) { | |||
// Skip resolving the table to avoid error. | |||
return | |||
} | |||
if p.inDeleteTableList { |
There was a problem hiding this comment.
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 ?
Conflicts: plan/resolver.go
CI failed since #4613 relies on GetResultField of *ast.Join .... |
/run-all-tests |
new_session_test.go
Outdated
c.Assert(err, IsNil) | ||
c.Assert(fields, HasLen, 1) | ||
// We do not create ResultFields anymore when preprocessing. |
There was a problem hiding this comment.
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 ?
plan/dag_plan_test.go
Outdated
@@ -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", |
There was a problem hiding this comment.
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 ?
There was a problem hiding this comment.
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.
plan/logical_plan_builder.go
Outdated
@@ -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 |
There was a problem hiding this comment.
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 ?
There was a problem hiding this comment.
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?
plan/optimizer.go
Outdated
@@ -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 { |
There was a problem hiding this comment.
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 ??
There was a problem hiding this comment.
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 ?
PTAL @hanfei1991 |
/run-all-tests |
CI failed since some error messages changed. |
plan/expression_rewriter.go
Outdated
@@ -28,6 +28,7 @@ import ( | |||
"github.com/pingcap/tidb/sessionctx/variable" | |||
"github.com/pingcap/tidb/sessionctx/varsutil" | |||
"github.com/pingcap/tidb/types" | |||
"strconv" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move this line up.
plan/logical_plan_builder.go
Outdated
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()) |
There was a problem hiding this comment.
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.
plan/logical_plan_builder.go
Outdated
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 |
There was a problem hiding this comment.
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
plan/logical_plan_builder.go
Outdated
foundMatch := false | ||
for _, v := range tableList { | ||
if dn := v.Schema.L; dn != "" { | ||
dbName = dn |
There was a problem hiding this comment.
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?
plan/preprocess.go
Outdated
p.tables = append(p.tables, ts) | ||
} | ||
|
||
func getInnerFromParentheses(expr ast.ExprNode) ast.ExprNode { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we use it?
plan/preprocess.go
Outdated
name := f.ColumnAsName.L | ||
if name == "" { | ||
name = f.Column.Name.L | ||
} |
There was a problem hiding this comment.
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.
plan/logical_plan_builder.go
Outdated
@@ -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 { |
There was a problem hiding this comment.
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.
plan/logical_plan_builder.go
Outdated
@@ -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 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto.
plan/logical_plan_builder.go
Outdated
@@ -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. |
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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;
plan/preprocess.go
Outdated
@@ -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) |
There was a problem hiding this comment.
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 ?
/run-common-test tidb-test=pr4988 |
/run-all-tests tidb-test=pr/398 |
executor/prepared_test.go
Outdated
@@ -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) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
check the error message ?
plan/optimizer.go
Outdated
CodeNoDB terror.ErrCode = mysql.ErrNoDB | ||
CodeUnknownExplainFormat terror.ErrCode = mysql.ErrUnknownExplainFormat | ||
CodeWrongGroupField = mysql.ErrWrongGroupField |
There was a problem hiding this comment.
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 ?
plan/optimizer.go
Outdated
@@ -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 { |
There was a problem hiding this comment.
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 ?
plan/planbuilder.go
Outdated
type clauseCode int | ||
|
||
const ( | ||
unknowClause clauseCode = 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unknowClause clauseCode = iota
- how about let all clause code have a common prefix, like "clauseCodeXXX" ?
There was a problem hiding this comment.
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.
plan/preprocess.go
Outdated
@@ -561,3 +571,38 @@ func (p *preprocessor) resolveAlterTableStmt(node *ast.AlterTableStmt) { | |||
} | |||
} | |||
} | |||
|
|||
// handleTableSource checks name duplication |
There was a problem hiding this comment.
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 ...
?
plan/preprocess.go
Outdated
@@ -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 |
There was a problem hiding this comment.
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{}
?
There was a problem hiding this comment.
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.
plan/typeinfer_test.go
Outdated
err = plan.ResolveName(stmt, is, ctx) | ||
c.Assert(err, IsNil, comment) | ||
err = plan.Preprocess(ctx, stmt, is, false) | ||
c.Assert(err, IsNil) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add comment
back ?
LGTM |
executor/prepared_test.go
Outdated
@@ -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) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why change this
new_session_test.go
Outdated
@@ -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") |
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why remove the comments ?
plan/logical_plan_builder.go
Outdated
@@ -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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
duplicate -> Duplicate
plan/logical_plan_builder.go
Outdated
colName := &ast.ColumnNameExpr{ | ||
Name: &ast.ColumnName{ | ||
Schema: col.DBName, | ||
Table: col.TblName, | ||
Name: col.ColName, | ||
}} | ||
ast.SetFlag(colName) |
There was a problem hiding this comment.
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
plan/preprocess.go
Outdated
name = p.tableUniqueName(tableName.Schema, tableName.Name) | ||
} | ||
if _, ok := p.tableMap[name]; ok { | ||
p.err = errors.Errorf("duplicated table/alias name %s", name) |
There was a problem hiding this comment.
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 ?
PTAL @hanfei1991 |
/run-all-tests tidb-test=pr/398 |
/run-common-test tidb-test=pr/398 |
LGTM |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
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: