github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/pingcap/tidb/optimizer/resolver_test.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_test
    15  
    16  import (
    17  	"testing"
    18  
    19  	. "github.com/insionng/yougam/libraries/pingcap/check"
    20  	"github.com/insionng/yougam/libraries/pingcap/tidb"
    21  	"github.com/insionng/yougam/libraries/pingcap/tidb/ast"
    22  	"github.com/insionng/yougam/libraries/pingcap/tidb/context"
    23  	"github.com/insionng/yougam/libraries/pingcap/tidb/optimizer"
    24  	"github.com/insionng/yougam/libraries/pingcap/tidb/parser"
    25  	"github.com/insionng/yougam/libraries/pingcap/tidb/sessionctx"
    26  	"github.com/insionng/yougam/libraries/pingcap/tidb/sessionctx/db"
    27  	"github.com/insionng/yougam/libraries/pingcap/tidb/util/testkit"
    28  )
    29  
    30  func TestT(t *testing.T) {
    31  	TestingT(t)
    32  }
    33  
    34  var _ = Suite(&testNameResolverSuite{})
    35  
    36  type testNameResolverSuite struct {
    37  }
    38  
    39  type resolverVerifier struct {
    40  	src string
    41  	c   *C
    42  }
    43  
    44  func (rv *resolverVerifier) Enter(node ast.Node) (ast.Node, bool) {
    45  	return node, false
    46  }
    47  
    48  func (rv *resolverVerifier) Leave(in ast.Node) (out ast.Node, ok bool) {
    49  	switch v := in.(type) {
    50  	case *ast.ColumnNameExpr:
    51  		rv.c.Assert(v.Refer, NotNil, Commentf("%s", rv.src))
    52  	case *ast.TableName:
    53  		rv.c.Assert(v.TableInfo, NotNil, Commentf("%s", rv.src))
    54  	}
    55  	return in, true
    56  }
    57  
    58  type resolverTestCase struct {
    59  	src   string
    60  	valid bool
    61  }
    62  
    63  var resolverTestCases = []resolverTestCase{
    64  	{"select c1 from t1", true},
    65  	{"select c3 from t1", false},
    66  	{"select c1 from t4", false},
    67  	{"select c1 from t1, t2", false},
    68  	{"select * from t1", true},
    69  	{"select t1.* from t1", true},
    70  	{"select t2.* from t1", false},
    71  	{"select c1 as a, c2 as a from t1 group by a", false},
    72  	{"select c1 as a, c1 as a from t1 group by a", true},
    73  	{"select 1 as a, c1 as a, c2 as a from t1 group by a", true},
    74  	{"select c1, c2 as c1 from t1 group by c1", false},
    75  	{"select c1, c2 as c1 from t1 group by c1+1", true},
    76  	{"select c1, c2 as c1 from t1 order by c1", false},
    77  	{"select c1, c2 as c1 from t1 order by c1+1", true},
    78  	{"select * from t1, t2 join t3 on t1.c1 = t2.c1", false},
    79  	{"select * from t1, t2 join t3 on t2.c1 = t3.c1", true},
    80  	{"select c1 from t1 group by c1 having c1 = 3", true},
    81  	{"select c1 from t1 group by c1 having c2 = 3", false},
    82  	{"select c1 from t1 where exists (select c2)", true},
    83  }
    84  
    85  func (ts *testNameResolverSuite) TestNameResolver(c *C) {
    86  	store, err := tidb.NewStore(tidb.EngineGoLevelDBMemory)
    87  	c.Assert(err, IsNil)
    88  	defer store.Close()
    89  	testKit := testkit.NewTestKit(c, store)
    90  	testKit.MustExec("use test")
    91  	testKit.MustExec("create table t1 (c1 int, c2 int)")
    92  	testKit.MustExec("create table t2 (c1 int, c2 int)")
    93  	testKit.MustExec("create table t3 (c1 int, c2 int)")
    94  	ctx := testKit.Se.(context.Context)
    95  	domain := sessionctx.GetDomain(ctx)
    96  	db.BindCurrentSchema(ctx, "test")
    97  	for _, tc := range resolverTestCases {
    98  		node, err := parser.ParseOneStmt(tc.src, "", "")
    99  		c.Assert(err, IsNil)
   100  		resolveErr := optimizer.ResolveName(node, domain.InfoSchema(), ctx)
   101  		if tc.valid {
   102  			c.Assert(resolveErr, IsNil)
   103  			verifier := &resolverVerifier{c: c, src: tc.src}
   104  			node.Accept(verifier)
   105  		} else {
   106  			c.Assert(resolveErr, NotNil, Commentf("%s", tc.src))
   107  		}
   108  	}
   109  }