github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/pingcap/tidb/optimizer/resolver.go (about)

     1  // Copyright 2015 PingCAP, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package optimizer
    15  
    16  import (
    17  	"fmt"
    18  
    19  	"github.com/insionng/yougam/libraries/juju/errors"
    20  	"github.com/insionng/yougam/libraries/pingcap/tidb/ast"
    21  	"github.com/insionng/yougam/libraries/pingcap/tidb/column"
    22  	"github.com/insionng/yougam/libraries/pingcap/tidb/context"
    23  	"github.com/insionng/yougam/libraries/pingcap/tidb/infoschema"
    24  	"github.com/insionng/yougam/libraries/pingcap/tidb/model"
    25  	"github.com/insionng/yougam/libraries/pingcap/tidb/mysql"
    26  	"github.com/insionng/yougam/libraries/pingcap/tidb/sessionctx/db"
    27  	"github.com/insionng/yougam/libraries/pingcap/tidb/util/types"
    28  )
    29  
    30  // ResolveName resolves table name and column name.
    31  // It generates ResultFields for ResultSetNode and resolves ColumnNameExpr to a ResultField.
    32  func ResolveName(node ast.Node, info infoschema.InfoSchema, ctx context.Context) error {
    33  	defaultSchema := db.GetCurrentSchema(ctx)
    34  	resolver := nameResolver{Info: info, Ctx: ctx, DefaultSchema: model.NewCIStr(defaultSchema)}
    35  	node.Accept(&resolver)
    36  	return errors.Trace(resolver.Err)
    37  }
    38  
    39  // MockResolveName only serves for test.
    40  func MockResolveName(node ast.Node, info infoschema.InfoSchema, defaultSchema string) error {
    41  	resolver := nameResolver{Info: info, Ctx: nil, DefaultSchema: model.NewCIStr(defaultSchema)}
    42  	node.Accept(&resolver)
    43  	return resolver.Err
    44  }
    45  
    46  // nameResolver is the visitor to resolve table name and column name.
    47  // In general, a reference can only refer to information that are available for it.
    48  // So children elements are visited in the order that previous elements make information
    49  // available for following elements.
    50  //
    51  // During visiting, information are collected and stored in resolverContext.
    52  // When we enter a subquery, a new resolverContext is pushed to the contextStack, so subquery
    53  // information can overwrite outer query information. When we look up for a column reference,
    54  // we look up from top to bottom in the contextStack.
    55  type nameResolver struct {
    56  	Info            infoschema.InfoSchema
    57  	Ctx             context.Context
    58  	DefaultSchema   model.CIStr
    59  	Err             error
    60  	useOuterContext bool
    61  
    62  	contextStack []*resolverContext
    63  }
    64  
    65  // resolverContext stores information in a single level of select statement
    66  // that table name and column name can be resolved.
    67  type resolverContext struct {
    68  	/* For Select Statement. */
    69  	// table map to lookup and check table name conflict.
    70  	tableMap map[string]int
    71  	// table map to lookup and check derived-table(subselect) name conflict.
    72  	derivedTableMap map[string]int
    73  	// tableSources collected in from clause.
    74  	tables []*ast.TableSource
    75  	// result fields collected in select field list.
    76  	fieldList []*ast.ResultField
    77  	// result fields collected in group by clause.
    78  	groupBy []*ast.ResultField
    79  
    80  	// The join node stack is used by on condition to find out
    81  	// available tables to reference. On condition can only
    82  	// refer to tables involved in current join.
    83  	joinNodeStack []*ast.Join
    84  
    85  	// When visiting TableRefs, tables in this context are not available
    86  	// because it is being collected.
    87  	inTableRefs bool
    88  	// When visiting on condition only tables in current join node are available.
    89  	inOnCondition bool
    90  	// When visiting field list, fieldList in this context are not available.
    91  	inFieldList bool
    92  	// When visiting group by, groupBy fields are not available.
    93  	inGroupBy bool
    94  	// When visiting having, only fieldList and groupBy fields are available.
    95  	inHaving bool
    96  	// When visiting having, checks if the expr is an aggregate function expr.
    97  	inHavingAgg bool
    98  	// OrderBy clause has different resolving rule than group by.
    99  	inOrderBy bool
   100  	// When visiting column name in ByItem, we should know if the column name is in an expression.
   101  	inByItemExpression bool
   102  	// If subquery use outer context.
   103  	useOuterContext bool
   104  	// When visiting multi-table delete stmt table list.
   105  	inDeleteTableList bool
   106  	// When visiting create/drop table statement.
   107  	inCreateOrDropTable bool
   108  	// When visiting show statement.
   109  	inShow bool
   110  }
   111  
   112  // currentContext gets the current resolverContext.
   113  func (nr *nameResolver) currentContext() *resolverContext {
   114  	stackLen := len(nr.contextStack)
   115  	if stackLen == 0 {
   116  		return nil
   117  	}
   118  	return nr.contextStack[stackLen-1]
   119  }
   120  
   121  // pushContext is called when we enter a statement.
   122  func (nr *nameResolver) pushContext() {
   123  	nr.contextStack = append(nr.contextStack, &resolverContext{
   124  		tableMap:        map[string]int{},
   125  		derivedTableMap: map[string]int{},
   126  	})
   127  }
   128  
   129  // popContext is called when we leave a statement.
   130  func (nr *nameResolver) popContext() {
   131  	nr.contextStack = nr.contextStack[:len(nr.contextStack)-1]
   132  }
   133  
   134  // pushJoin is called when we enter a join node.
   135  func (nr *nameResolver) pushJoin(j *ast.Join) {
   136  	ctx := nr.currentContext()
   137  	ctx.joinNodeStack = append(ctx.joinNodeStack, j)
   138  }
   139  
   140  // popJoin is called when we leave a join node.
   141  func (nr *nameResolver) popJoin() {
   142  	ctx := nr.currentContext()
   143  	ctx.joinNodeStack = ctx.joinNodeStack[:len(ctx.joinNodeStack)-1]
   144  }
   145  
   146  // Enter implements ast.Visitor interface.
   147  func (nr *nameResolver) Enter(inNode ast.Node) (outNode ast.Node, skipChildren bool) {
   148  	switch v := inNode.(type) {
   149  	case *ast.AdminStmt:
   150  		nr.pushContext()
   151  	case *ast.AggregateFuncExpr:
   152  		ctx := nr.currentContext()
   153  		if ctx.inHaving {
   154  			ctx.inHavingAgg = true
   155  		}
   156  	case *ast.AlterTableStmt:
   157  		nr.pushContext()
   158  	case *ast.ByItem:
   159  		if _, ok := v.Expr.(*ast.ColumnNameExpr); !ok {
   160  			// If ByItem is not a single column name expression,
   161  			// the resolving rule is different from order by clause.
   162  			nr.currentContext().inByItemExpression = true
   163  		}
   164  		if nr.currentContext().inGroupBy {
   165  			// make sure item is not aggregate function
   166  			if ast.HasAggFlag(v.Expr) {
   167  				nr.Err = ErrInvalidGroupFuncUse
   168  				return inNode, true
   169  			}
   170  		}
   171  	case *ast.CreateIndexStmt:
   172  		nr.pushContext()
   173  	case *ast.CreateTableStmt:
   174  		nr.pushContext()
   175  		nr.currentContext().inCreateOrDropTable = true
   176  	case *ast.DeleteStmt:
   177  		nr.pushContext()
   178  	case *ast.DeleteTableList:
   179  		nr.currentContext().inDeleteTableList = true
   180  	case *ast.DoStmt:
   181  		nr.pushContext()
   182  	case *ast.DropTableStmt:
   183  		nr.pushContext()
   184  		nr.currentContext().inCreateOrDropTable = true
   185  	case *ast.DropIndexStmt:
   186  		nr.pushContext()
   187  	case *ast.FieldList:
   188  		nr.currentContext().inFieldList = true
   189  	case *ast.GroupByClause:
   190  		nr.currentContext().inGroupBy = true
   191  	case *ast.HavingClause:
   192  		nr.currentContext().inHaving = true
   193  	case *ast.InsertStmt:
   194  		nr.pushContext()
   195  	case *ast.Join:
   196  		nr.pushJoin(v)
   197  	case *ast.OnCondition:
   198  		nr.currentContext().inOnCondition = true
   199  	case *ast.OrderByClause:
   200  		nr.currentContext().inOrderBy = true
   201  	case *ast.SelectStmt:
   202  		nr.pushContext()
   203  	case *ast.SetStmt:
   204  		for _, assign := range v.Variables {
   205  			if cn, ok := assign.Value.(*ast.ColumnNameExpr); ok && cn.Name.Table.L == "" {
   206  				// Convert column name expression to string value expression.
   207  				assign.Value = ast.NewValueExpr(cn.Name.Name.O)
   208  			}
   209  		}
   210  		nr.pushContext()
   211  	case *ast.ShowStmt:
   212  		nr.pushContext()
   213  		nr.currentContext().inShow = true
   214  		nr.fillShowFields(v)
   215  	case *ast.TableRefsClause:
   216  		nr.currentContext().inTableRefs = true
   217  	case *ast.TruncateTableStmt:
   218  		nr.pushContext()
   219  	case *ast.UnionStmt:
   220  		nr.pushContext()
   221  	case *ast.UpdateStmt:
   222  		nr.pushContext()
   223  	}
   224  	return inNode, false
   225  }
   226  
   227  // Leave implements ast.Visitor interface.
   228  func (nr *nameResolver) Leave(inNode ast.Node) (node ast.Node, ok bool) {
   229  	switch v := inNode.(type) {
   230  	case *ast.AdminStmt:
   231  		nr.popContext()
   232  	case *ast.AggregateFuncExpr:
   233  		ctx := nr.currentContext()
   234  		if ctx.inHaving {
   235  			ctx.inHavingAgg = false
   236  		}
   237  	case *ast.AlterTableStmt:
   238  		nr.popContext()
   239  	case *ast.TableName:
   240  		nr.handleTableName(v)
   241  	case *ast.ColumnNameExpr:
   242  		nr.handleColumnName(v)
   243  	case *ast.CreateIndexStmt:
   244  		nr.popContext()
   245  	case *ast.CreateTableStmt:
   246  		nr.popContext()
   247  	case *ast.DeleteTableList:
   248  		nr.currentContext().inDeleteTableList = false
   249  	case *ast.DoStmt:
   250  		nr.popContext()
   251  	case *ast.DropIndexStmt:
   252  		nr.popContext()
   253  	case *ast.DropTableStmt:
   254  		nr.popContext()
   255  	case *ast.TableSource:
   256  		nr.handleTableSource(v)
   257  	case *ast.OnCondition:
   258  		nr.currentContext().inOnCondition = false
   259  	case *ast.Join:
   260  		nr.handleJoin(v)
   261  		nr.popJoin()
   262  	case *ast.TableRefsClause:
   263  		nr.currentContext().inTableRefs = false
   264  	case *ast.FieldList:
   265  		nr.handleFieldList(v)
   266  		nr.currentContext().inFieldList = false
   267  	case *ast.GroupByClause:
   268  		ctx := nr.currentContext()
   269  		ctx.inGroupBy = false
   270  		for _, item := range v.Items {
   271  			switch x := item.Expr.(type) {
   272  			case *ast.ColumnNameExpr:
   273  				ctx.groupBy = append(ctx.groupBy, x.Refer)
   274  			}
   275  		}
   276  	case *ast.HavingClause:
   277  		nr.currentContext().inHaving = false
   278  	case *ast.OrderByClause:
   279  		nr.currentContext().inOrderBy = false
   280  	case *ast.ByItem:
   281  		nr.currentContext().inByItemExpression = false
   282  	case *ast.PositionExpr:
   283  		nr.handlePosition(v)
   284  	case *ast.SelectStmt:
   285  		ctx := nr.currentContext()
   286  		v.SetResultFields(ctx.fieldList)
   287  		if ctx.useOuterContext {
   288  			nr.useOuterContext = true
   289  		}
   290  		nr.popContext()
   291  	case *ast.SetStmt:
   292  		nr.popContext()
   293  	case *ast.ShowStmt:
   294  		nr.popContext()
   295  	case *ast.SubqueryExpr:
   296  		if nr.useOuterContext {
   297  			// TODO: check this
   298  			// If there is a deep nest of subquery, there may be something wrong.
   299  			v.Correlated = true
   300  			nr.useOuterContext = false
   301  		}
   302  	case *ast.TruncateTableStmt:
   303  		nr.popContext()
   304  	case *ast.UnionStmt:
   305  		ctx := nr.currentContext()
   306  		v.SetResultFields(ctx.fieldList)
   307  		if ctx.useOuterContext {
   308  			nr.useOuterContext = true
   309  		}
   310  		nr.popContext()
   311  	case *ast.UnionSelectList:
   312  		nr.handleUnionSelectList(v)
   313  	case *ast.InsertStmt:
   314  		nr.popContext()
   315  	case *ast.DeleteStmt:
   316  		nr.popContext()
   317  	case *ast.UpdateStmt:
   318  		nr.popContext()
   319  	}
   320  	return inNode, nr.Err == nil
   321  }
   322  
   323  // handleTableName looks up and sets the schema information and result fields for table name.
   324  func (nr *nameResolver) handleTableName(tn *ast.TableName) {
   325  	if tn.Schema.L == "" {
   326  		tn.Schema = nr.DefaultSchema
   327  	}
   328  	ctx := nr.currentContext()
   329  	if ctx.inCreateOrDropTable {
   330  		// The table may not exist in create table or drop table statement.
   331  		// Skip resolving the table to avoid error.
   332  		return
   333  	}
   334  	if ctx.inDeleteTableList {
   335  		idx, ok := ctx.tableMap[nr.tableUniqueName(tn.Schema, tn.Name)]
   336  		if !ok {
   337  			nr.Err = errors.Errorf("Unknown table %s", tn.Name.O)
   338  			return
   339  		}
   340  		ts := ctx.tables[idx]
   341  		tableName := ts.Source.(*ast.TableName)
   342  		tn.DBInfo = tableName.DBInfo
   343  		tn.TableInfo = tableName.TableInfo
   344  		tn.SetResultFields(tableName.GetResultFields())
   345  		return
   346  	}
   347  	table, err := nr.Info.TableByName(tn.Schema, tn.Name)
   348  	if err != nil {
   349  		nr.Err = errors.Trace(err)
   350  		return
   351  	}
   352  	tn.TableInfo = table.Meta()
   353  	dbInfo, _ := nr.Info.SchemaByName(tn.Schema)
   354  	tn.DBInfo = dbInfo
   355  
   356  	rfs := make([]*ast.ResultField, 0, len(tn.TableInfo.Columns))
   357  	for _, v := range tn.TableInfo.Columns {
   358  		if v.State != model.StatePublic {
   359  			continue
   360  		}
   361  		expr := &ast.ValueExpr{}
   362  		expr.SetType(&v.FieldType)
   363  		rf := &ast.ResultField{
   364  			Column:    v,
   365  			Table:     tn.TableInfo,
   366  			DBName:    tn.Schema,
   367  			Expr:      expr,
   368  			TableName: tn,
   369  		}
   370  		rfs = append(rfs, rf)
   371  	}
   372  	tn.SetResultFields(rfs)
   373  	return
   374  }
   375  
   376  // handleTableSources checks name duplication
   377  // and puts the table source in current resolverContext.
   378  // Note:
   379  // "select * from t as a join (select 1) as a;" is not duplicate.
   380  // "select * from t as a join t as a;" is duplicate.
   381  // "select * from (select 1) as a join (select 1) as a;" is duplicate.
   382  func (nr *nameResolver) handleTableSource(ts *ast.TableSource) {
   383  	for _, v := range ts.GetResultFields() {
   384  		v.TableAsName = ts.AsName
   385  	}
   386  	ctx := nr.currentContext()
   387  	switch ts.Source.(type) {
   388  	case *ast.TableName:
   389  		var name string
   390  		if ts.AsName.L != "" {
   391  			name = ts.AsName.L
   392  		} else {
   393  			tableName := ts.Source.(*ast.TableName)
   394  			name = nr.tableUniqueName(tableName.Schema, tableName.Name)
   395  		}
   396  		if _, ok := ctx.tableMap[name]; ok {
   397  			nr.Err = errors.Errorf("duplicated table/alias name %s", name)
   398  			return
   399  		}
   400  		ctx.tableMap[name] = len(ctx.tables)
   401  	case *ast.SelectStmt:
   402  		name := ts.AsName.L
   403  		if _, ok := ctx.derivedTableMap[name]; ok {
   404  			nr.Err = errors.Errorf("duplicated table/alias name %s", name)
   405  			return
   406  		}
   407  		ctx.derivedTableMap[name] = len(ctx.tables)
   408  	}
   409  	dupNames := make(map[string]struct{}, len(ts.GetResultFields()))
   410  	for _, f := range ts.GetResultFields() {
   411  		// duplicate column name in one table is not allowed.
   412  		// "select * from (select 1, 1) as a;" is duplicate.
   413  		name := f.ColumnAsName.L
   414  		if name == "" {
   415  			name = f.Column.Name.L
   416  		}
   417  		if _, ok := dupNames[name]; ok {
   418  			nr.Err = errors.Errorf("Duplicate column name '%s'", name)
   419  			return
   420  		}
   421  		dupNames[name] = struct{}{}
   422  	}
   423  	ctx.tables = append(ctx.tables, ts)
   424  	return
   425  }
   426  
   427  // handleJoin sets result fields for join.
   428  func (nr *nameResolver) handleJoin(j *ast.Join) {
   429  	if j.Right == nil {
   430  		j.SetResultFields(j.Left.GetResultFields())
   431  		return
   432  	}
   433  	leftLen := len(j.Left.GetResultFields())
   434  	rightLen := len(j.Right.GetResultFields())
   435  	rfs := make([]*ast.ResultField, leftLen+rightLen)
   436  	copy(rfs, j.Left.GetResultFields())
   437  	copy(rfs[leftLen:], j.Right.GetResultFields())
   438  	j.SetResultFields(rfs)
   439  }
   440  
   441  // handleColumnName looks up and sets ResultField for
   442  // the column name.
   443  func (nr *nameResolver) handleColumnName(cn *ast.ColumnNameExpr) {
   444  	ctx := nr.currentContext()
   445  	if ctx.inOnCondition {
   446  		// In on condition, only tables within current join is available.
   447  		nr.resolveColumnNameInOnCondition(cn)
   448  		return
   449  	}
   450  
   451  	// Try to resolve the column name form top to bottom in the context stack.
   452  	for i := len(nr.contextStack) - 1; i >= 0; i-- {
   453  		if nr.resolveColumnNameInContext(nr.contextStack[i], cn) {
   454  			// Column is already resolved or encountered an error.
   455  			if i < len(nr.contextStack)-1 {
   456  				// If in subselect, the query use outer query.
   457  				nr.currentContext().useOuterContext = true
   458  			}
   459  			return
   460  		}
   461  	}
   462  	nr.Err = errors.Errorf("unknown column %s", cn.Name.Name.L)
   463  }
   464  
   465  // resolveColumnNameInContext looks up and sets ResultField for a column with the ctx.
   466  func (nr *nameResolver) resolveColumnNameInContext(ctx *resolverContext, cn *ast.ColumnNameExpr) bool {
   467  	if ctx.inTableRefs {
   468  		// In TableRefsClause, column reference only in join on condition which is handled before.
   469  		return false
   470  	}
   471  	if ctx.inFieldList {
   472  		// only resolve column using tables.
   473  		return nr.resolveColumnInTableSources(cn, ctx.tables)
   474  	}
   475  	if ctx.inGroupBy {
   476  		// From tables first, then field list.
   477  		// If ctx.InByItemExpression is true, the item is not an identifier.
   478  		// Otherwise it is an identifier.
   479  		if ctx.inByItemExpression {
   480  			// From table first, then field list.
   481  			if nr.resolveColumnInTableSources(cn, ctx.tables) {
   482  				return true
   483  			}
   484  			found := nr.resolveColumnInResultFields(ctx, cn, ctx.fieldList)
   485  			if nr.Err == nil && found {
   486  				// Check if resolved refer is an aggregate function expr.
   487  				if _, ok := cn.Refer.Expr.(*ast.AggregateFuncExpr); ok {
   488  					nr.Err = ErrIllegalReference.Gen("Reference '%s' not supported (reference to group function)", cn.Name.Name.O)
   489  				}
   490  			}
   491  			return found
   492  		}
   493  		// Resolve from table first, then from select list.
   494  		found := nr.resolveColumnInTableSources(cn, ctx.tables)
   495  		if nr.Err != nil {
   496  			return found
   497  		}
   498  		// We should copy the refer here.
   499  		// Because if the ByItem is an identifier, we should check if it
   500  		// is ambiguous even it is already resolved from table source.
   501  		// If the ByItem is not an identifier, we do not need the second check.
   502  		r := cn.Refer
   503  		if nr.resolveColumnInResultFields(ctx, cn, ctx.fieldList) {
   504  			if nr.Err != nil {
   505  				return true
   506  			}
   507  			if r != nil {
   508  				// It is not ambiguous and already resolved from table source.
   509  				// We should restore its Refer.
   510  				cn.Refer = r
   511  			}
   512  			if _, ok := cn.Refer.Expr.(*ast.AggregateFuncExpr); ok {
   513  				nr.Err = ErrIllegalReference.Gen("Reference '%s' not supported (reference to group function)", cn.Name.Name.O)
   514  			}
   515  			return true
   516  		}
   517  		return found
   518  	}
   519  	if ctx.inHaving {
   520  		// First group by, then field list.
   521  		if nr.resolveColumnInResultFields(ctx, cn, ctx.groupBy) {
   522  			return true
   523  		}
   524  		if ctx.inHavingAgg {
   525  			// If cn is in an aggregate function in having clause, check tablesource first.
   526  			if nr.resolveColumnInTableSources(cn, ctx.tables) {
   527  				return true
   528  			}
   529  		}
   530  		return nr.resolveColumnInResultFields(ctx, cn, ctx.fieldList)
   531  	}
   532  	if ctx.inOrderBy {
   533  		if nr.resolveColumnInResultFields(ctx, cn, ctx.groupBy) {
   534  			return true
   535  		}
   536  		if ctx.inByItemExpression {
   537  			// From table first, then field list.
   538  			if nr.resolveColumnInTableSources(cn, ctx.tables) {
   539  				return true
   540  			}
   541  			return nr.resolveColumnInResultFields(ctx, cn, ctx.fieldList)
   542  		}
   543  		// Field list first, then from table.
   544  		if nr.resolveColumnInResultFields(ctx, cn, ctx.fieldList) {
   545  			return true
   546  		}
   547  		return nr.resolveColumnInTableSources(cn, ctx.tables)
   548  	}
   549  	if ctx.inShow {
   550  		return nr.resolveColumnInResultFields(ctx, cn, ctx.fieldList)
   551  	}
   552  	// In where clause.
   553  	return nr.resolveColumnInTableSources(cn, ctx.tables)
   554  }
   555  
   556  // resolveColumnNameInOnCondition resolves the column name in current join.
   557  func (nr *nameResolver) resolveColumnNameInOnCondition(cn *ast.ColumnNameExpr) {
   558  	ctx := nr.currentContext()
   559  	join := ctx.joinNodeStack[len(ctx.joinNodeStack)-1]
   560  	tableSources := appendTableSources(nil, join)
   561  	if !nr.resolveColumnInTableSources(cn, tableSources) {
   562  		nr.Err = errors.Errorf("unkown column name %s", cn.Name.Name.O)
   563  	}
   564  }
   565  
   566  func (nr *nameResolver) resolveColumnInTableSources(cn *ast.ColumnNameExpr, tableSources []*ast.TableSource) (done bool) {
   567  	var matchedResultField *ast.ResultField
   568  	tableNameL := cn.Name.Table.L
   569  	columnNameL := cn.Name.Name.L
   570  	if tableNameL != "" {
   571  		var matchedTable ast.ResultSetNode
   572  		for _, ts := range tableSources {
   573  			if tableNameL == ts.AsName.L {
   574  				// different table name.
   575  				matchedTable = ts
   576  				break
   577  			} else if ts.AsName.L != "" {
   578  				// Table as name shadows table real name.
   579  				continue
   580  			}
   581  			if tn, ok := ts.Source.(*ast.TableName); ok {
   582  				if cn.Name.Schema.L != "" && cn.Name.Schema.L != tn.Schema.L {
   583  					continue
   584  				}
   585  				if tableNameL == tn.Name.L {
   586  					matchedTable = ts
   587  				}
   588  			}
   589  		}
   590  		if matchedTable != nil {
   591  			resultFields := matchedTable.GetResultFields()
   592  			for _, rf := range resultFields {
   593  				if rf.ColumnAsName.L == columnNameL || rf.Column.Name.L == columnNameL {
   594  					// resolve column.
   595  					matchedResultField = rf
   596  					break
   597  				}
   598  			}
   599  		}
   600  	} else {
   601  		for _, ts := range tableSources {
   602  			rfs := ts.GetResultFields()
   603  			for _, rf := range rfs {
   604  				matchAsName := rf.ColumnAsName.L != "" && rf.ColumnAsName.L == columnNameL
   605  				matchColumnName := rf.ColumnAsName.L == "" && rf.Column.Name.L == columnNameL
   606  				if matchAsName || matchColumnName {
   607  					if matchedResultField != nil {
   608  						nr.Err = errors.Errorf("column %s is ambiguous.", cn.Name.Name.O)
   609  						return true
   610  					}
   611  					matchedResultField = rf
   612  				}
   613  			}
   614  		}
   615  	}
   616  	if matchedResultField != nil {
   617  		// Bind column.
   618  		cn.Refer = matchedResultField
   619  		matchedResultField.Referenced = true
   620  		return true
   621  	}
   622  	return false
   623  }
   624  
   625  func (nr *nameResolver) resolveColumnInResultFields(ctx *resolverContext, cn *ast.ColumnNameExpr, rfs []*ast.ResultField) bool {
   626  	var matched *ast.ResultField
   627  	for _, rf := range rfs {
   628  		if cn.Name.Table.L != "" {
   629  			// Check table name
   630  			if rf.TableAsName.L != "" {
   631  				if cn.Name.Table.L != rf.TableAsName.L {
   632  					continue
   633  				}
   634  			} else if cn.Name.Table.L != rf.Table.Name.L {
   635  				continue
   636  			}
   637  		}
   638  		matchAsName := cn.Name.Name.L == rf.ColumnAsName.L
   639  		var matchColumnName bool
   640  		if ctx.inHaving {
   641  			matchColumnName = cn.Name.Name.L == rf.Column.Name.L
   642  		} else {
   643  			matchColumnName = rf.ColumnAsName.L == "" && cn.Name.Name.L == rf.Column.Name.L
   644  		}
   645  		if matchAsName || matchColumnName {
   646  			if rf.Column.Name.L == "" {
   647  				// This is not a real table column, resolve it directly.
   648  				cn.Refer = rf
   649  				rf.Referenced = true
   650  				return true
   651  			}
   652  			if matched == nil {
   653  				matched = rf
   654  			} else {
   655  				sameColumn := matched.TableName == rf.TableName && matched.Column.Name.L == rf.Column.Name.L
   656  				if !sameColumn {
   657  					nr.Err = errors.Errorf("column %s is ambiguous.", cn.Name.Name.O)
   658  					return true
   659  				}
   660  			}
   661  		}
   662  	}
   663  	if matched != nil {
   664  		// If in GroupBy, we clone the ResultField
   665  		if ctx.inGroupBy || ctx.inHaving || ctx.inOrderBy {
   666  			nf := *matched
   667  			expr := matched.Expr
   668  			if cexpr, ok := expr.(*ast.ColumnNameExpr); ok {
   669  				expr = cexpr.Refer.Expr
   670  			}
   671  			nf.Expr = expr
   672  			matched = &nf
   673  		}
   674  		// Bind column.
   675  		cn.Refer = matched
   676  		matched.Referenced = true
   677  		return true
   678  	}
   679  	return false
   680  }
   681  
   682  // handleFieldList expands wild card field and sets fieldList in current context.
   683  func (nr *nameResolver) handleFieldList(fieldList *ast.FieldList) {
   684  	var resultFields []*ast.ResultField
   685  	for _, v := range fieldList.Fields {
   686  		resultFields = append(resultFields, nr.createResultFields(v)...)
   687  	}
   688  	nr.currentContext().fieldList = resultFields
   689  }
   690  
   691  func getInnerFromParentheses(expr ast.ExprNode) ast.ExprNode {
   692  	if pexpr, ok := expr.(*ast.ParenthesesExpr); ok {
   693  		return getInnerFromParentheses(pexpr.Expr)
   694  	}
   695  	return expr
   696  }
   697  
   698  // createResultFields creates result field list for a single select field.
   699  func (nr *nameResolver) createResultFields(field *ast.SelectField) (rfs []*ast.ResultField) {
   700  	ctx := nr.currentContext()
   701  	if field.WildCard != nil {
   702  		if len(ctx.tables) == 0 {
   703  			nr.Err = errors.New("No table used.")
   704  			return
   705  		}
   706  		tableRfs := []*ast.ResultField{}
   707  		if field.WildCard.Table.L == "" {
   708  			for _, v := range ctx.tables {
   709  				tableRfs = append(tableRfs, v.GetResultFields()...)
   710  			}
   711  		} else {
   712  			name := nr.tableUniqueName(field.WildCard.Schema, field.WildCard.Table)
   713  			tableIdx, ok1 := ctx.tableMap[name]
   714  			derivedTableIdx, ok2 := ctx.derivedTableMap[name]
   715  			if !ok1 && !ok2 {
   716  				nr.Err = errors.Errorf("unknown table %s.", field.WildCard.Table.O)
   717  			}
   718  			if ok1 {
   719  				tableRfs = ctx.tables[tableIdx].GetResultFields()
   720  			}
   721  			if ok2 {
   722  				tableRfs = append(tableRfs, ctx.tables[derivedTableIdx].GetResultFields()...)
   723  			}
   724  
   725  		}
   726  		for _, trf := range tableRfs {
   727  			trf.Referenced = true
   728  			// Convert it to ColumnNameExpr
   729  			cn := &ast.ColumnName{
   730  				Schema: trf.DBName,
   731  				Table:  trf.Table.Name,
   732  				Name:   trf.ColumnAsName,
   733  			}
   734  			cnExpr := &ast.ColumnNameExpr{
   735  				Name:  cn,
   736  				Refer: trf,
   737  			}
   738  			ast.SetFlag(cnExpr)
   739  			cnExpr.SetType(trf.Expr.GetType())
   740  			rf := *trf
   741  			rf.Expr = cnExpr
   742  			rfs = append(rfs, &rf)
   743  		}
   744  		return
   745  	}
   746  	// The column is visited before so it must has been resolved already.
   747  	rf := &ast.ResultField{ColumnAsName: field.AsName}
   748  	innerExpr := getInnerFromParentheses(field.Expr)
   749  	switch v := innerExpr.(type) {
   750  	case *ast.ColumnNameExpr:
   751  		rf.Column = v.Refer.Column
   752  		rf.Table = v.Refer.Table
   753  		rf.DBName = v.Refer.DBName
   754  		rf.TableName = v.Refer.TableName
   755  		rf.Expr = v
   756  	default:
   757  		rf.Column = &model.ColumnInfo{} // Empty column info.
   758  		rf.Table = &model.TableInfo{}   // Empty table info.
   759  		rf.Expr = v
   760  	}
   761  	if field.AsName.L == "" {
   762  		switch x := innerExpr.(type) {
   763  		case *ast.ColumnNameExpr:
   764  			rf.ColumnAsName = model.NewCIStr(x.Name.Name.O)
   765  		case *ast.ValueExpr:
   766  			if innerExpr.Text() != "" {
   767  				rf.ColumnAsName = model.NewCIStr(innerExpr.Text())
   768  			} else {
   769  				rf.ColumnAsName = model.NewCIStr(field.Text())
   770  			}
   771  		default:
   772  			rf.ColumnAsName = model.NewCIStr(field.Text())
   773  		}
   774  	}
   775  	rfs = append(rfs, rf)
   776  	return
   777  }
   778  
   779  func appendTableSources(in []*ast.TableSource, resultSetNode ast.ResultSetNode) (out []*ast.TableSource) {
   780  	switch v := resultSetNode.(type) {
   781  	case *ast.TableSource:
   782  		out = append(in, v)
   783  	case *ast.Join:
   784  		out = appendTableSources(in, v.Left)
   785  		if v.Right != nil {
   786  			out = appendTableSources(out, v.Right)
   787  		}
   788  	}
   789  	return
   790  }
   791  
   792  func (nr *nameResolver) tableUniqueName(schema, table model.CIStr) string {
   793  	if schema.L != "" && schema.L != nr.DefaultSchema.L {
   794  		return schema.L + "." + table.L
   795  	}
   796  	return table.L
   797  }
   798  
   799  func (nr *nameResolver) handlePosition(pos *ast.PositionExpr) {
   800  	ctx := nr.currentContext()
   801  	if pos.N < 1 || pos.N > len(ctx.fieldList) {
   802  		nr.Err = errors.Errorf("Unknown column '%d'", pos.N)
   803  		return
   804  	}
   805  	matched := ctx.fieldList[pos.N-1]
   806  	nf := *matched
   807  	expr := matched.Expr
   808  	if cexpr, ok := expr.(*ast.ColumnNameExpr); ok {
   809  		expr = cexpr.Refer.Expr
   810  	}
   811  	nf.Expr = expr
   812  	pos.Refer = &nf
   813  	pos.Refer.Referenced = true
   814  	if nr.currentContext().inGroupBy {
   815  		// make sure item is not aggregate function
   816  		if ast.HasAggFlag(pos.Refer.Expr) {
   817  			nr.Err = errors.New("group by cannot contain aggregate function")
   818  		}
   819  	}
   820  }
   821  
   822  func (nr *nameResolver) handleUnionSelectList(u *ast.UnionSelectList) {
   823  	firstSelFields := u.Selects[0].GetResultFields()
   824  	unionFields := make([]*ast.ResultField, len(firstSelFields))
   825  	// Copy first result fields, because we may change the result field type.
   826  	for i, v := range firstSelFields {
   827  		rf := *v
   828  		col := *v.Column
   829  		rf.Column = &col
   830  		if rf.Column.Flen == 0 {
   831  			rf.Column.Flen = types.UnspecifiedLength
   832  		}
   833  		rf.Expr = &ast.ValueExpr{}
   834  		unionFields[i] = &rf
   835  	}
   836  	nr.currentContext().fieldList = unionFields
   837  }
   838  
   839  func (nr *nameResolver) fillShowFields(s *ast.ShowStmt) {
   840  	if s.DBName == "" {
   841  		if s.Table != nil && s.Table.Schema.L != "" {
   842  			s.DBName = s.Table.Schema.O
   843  		} else {
   844  			s.DBName = nr.DefaultSchema.O
   845  		}
   846  	} else if s.Table != nil && s.Table.Schema.L == "" {
   847  		s.Table.Schema = model.NewCIStr(s.DBName)
   848  	}
   849  	var fields []*ast.ResultField
   850  	var (
   851  		names  []string
   852  		ftypes []byte
   853  	)
   854  	switch s.Tp {
   855  	case ast.ShowEngines:
   856  		names = []string{"Engine", "Support", "Comment", "Transactions", "XA", "Savepoints"}
   857  	case ast.ShowDatabases:
   858  		names = []string{"Database"}
   859  	case ast.ShowTables:
   860  		names = []string{fmt.Sprintf("Tables_in_%s", s.DBName)}
   861  		if s.Full {
   862  			names = append(names, "Table_type")
   863  		}
   864  	case ast.ShowTableStatus:
   865  		names = []string{"Name", "Engine", "Version", "Row_format", "Rows", "Avg_row_length",
   866  			"Data_length", "Max_data_length", "Index_length", "Data_free", "Auto_increment",
   867  			"Create_time", "Update_time", "Check_time", "Collation", "Checksum",
   868  			"Create_options", "Comment"}
   869  		ftypes = []byte{mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeLonglong, mysql.TypeVarchar, mysql.TypeLonglong, mysql.TypeLonglong,
   870  			mysql.TypeLonglong, mysql.TypeLonglong, mysql.TypeLonglong, mysql.TypeLonglong, mysql.TypeLonglong,
   871  			mysql.TypeDatetime, mysql.TypeDatetime, mysql.TypeDatetime, mysql.TypeVarchar, mysql.TypeVarchar,
   872  			mysql.TypeVarchar, mysql.TypeVarchar}
   873  	case ast.ShowColumns:
   874  		names = column.ColDescFieldNames(s.Full)
   875  	case ast.ShowWarnings:
   876  		names = []string{"Level", "Code", "Message"}
   877  		ftypes = []byte{mysql.TypeVarchar, mysql.TypeLong, mysql.TypeVarchar}
   878  	case ast.ShowCharset:
   879  		names = []string{"Charset", "Description", "Default collation", "Maxlen"}
   880  		ftypes = []byte{mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeLonglong}
   881  	case ast.ShowVariables:
   882  		names = []string{"Variable_name", "Value"}
   883  	case ast.ShowStatus:
   884  		names = []string{"Variable_name", "Value"}
   885  	case ast.ShowCollation:
   886  		names = []string{"Collation", "Charset", "Id", "Default", "Compiled", "Sortlen"}
   887  		ftypes = []byte{mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeLonglong,
   888  			mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeLonglong}
   889  	case ast.ShowCreateTable:
   890  		names = []string{"Table", "Create Table"}
   891  	case ast.ShowGrants:
   892  		names = []string{fmt.Sprintf("Grants for %s", s.User)}
   893  	case ast.ShowTriggers:
   894  		names = []string{"Trigger", "Event", "Table", "Statement", "Timing", "Created",
   895  			"sql_mode", "Definer", "character_set_client", "collation_connection", "Database Collation"}
   896  		ftypes = []byte{mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeVarchar,
   897  			mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeVarchar}
   898  	case ast.ShowProcedureStatus:
   899  		names = []string{}
   900  		ftypes = []byte{}
   901  	case ast.ShowIndex:
   902  		names = []string{"Table", "Non_unique", "Key_name", "Seq_in_index",
   903  			"Column_name", "Collation", "Cardinality", "Sub_part", "Packed",
   904  			"Null", "Index_type", "Comment", "Index_comment"}
   905  		ftypes = []byte{mysql.TypeVarchar, mysql.TypeLonglong, mysql.TypeVarchar, mysql.TypeLonglong,
   906  			mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeLonglong, mysql.TypeLonglong,
   907  			mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeVarchar}
   908  	}
   909  	for i, name := range names {
   910  		f := &ast.ResultField{
   911  			ColumnAsName: model.NewCIStr(name),
   912  			Column:       &model.ColumnInfo{}, // Empty column info.
   913  			Table:        &model.TableInfo{},  // Empty table info.
   914  		}
   915  		if ftypes == nil || ftypes[i] == 0 {
   916  			// use varchar as the default return column type
   917  			f.Column.Tp = mysql.TypeVarchar
   918  		} else {
   919  			f.Column.Tp = ftypes[i]
   920  		}
   921  		f.Column.Charset, f.Column.Collate = types.DefaultCharsetForType(f.Column.Tp)
   922  		f.Expr = &ast.ValueExpr{}
   923  		f.Expr.SetType(&f.Column.FieldType)
   924  		fields = append(fields, f)
   925  	}
   926  
   927  	if s.Pattern != nil && s.Pattern.Expr == nil {
   928  		rf := fields[0]
   929  		s.Pattern.Expr = &ast.ColumnNameExpr{
   930  			Name: &ast.ColumnName{Name: rf.ColumnAsName},
   931  		}
   932  		ast.SetFlag(s.Pattern)
   933  	}
   934  	s.SetResultFields(fields)
   935  	nr.currentContext().fieldList = fields
   936  }