// Parse parses a query string to raw ast.StmtNode. func Parse(ctx context.Context, src string) ([]ast.StmtNode, error) { charset, collation := getCtxCharsetInfo(ctx) stmts, err := parser.Parse(src, charset, collation) if err != nil { log.Warnf("compiling %s, error: %v", src, err) return nil, errors.Trace(err) } return stmts, nil }
// DoPrepare prepares the statement, it can be called multiple times without // side effect. func (e *PrepareExec) DoPrepare() { vars := variable.GetSessionVars(e.Ctx) if e.ID != 0 { // Must be the case when we retry a prepare. // Make sure it is idempotent. _, ok := vars.PreparedStmts[e.ID] if ok { return } } charset, collation := variable.GetCharsetInfo(e.Ctx) stmts, err := parser.Parse(e.SQLText, charset, collation) if err != nil { e.Err = errors.Trace(err) return } if len(stmts) != 1 { e.Err = ErrPrepareMulti return } stmt := stmts[0] var extractor paramMarkerExtractor stmt.Accept(&extractor) // The parameter markers are appended in visiting order, which may not // be the same as the position order in the query string. We need to // sort it by position. sorter := ¶mMarkerSorter{markers: extractor.markers} sort.Sort(sorter) e.ParamCount = len(sorter.markers) prepared := &Prepared{ Stmt: stmt, Params: sorter.markers, SchemaVersion: e.IS.SchemaMetaVersion(), } if optimizer.IsSupported(stmt) { err := optimizer.Prepare(e.IS, e.Ctx, stmt) if err != nil { e.Err = errors.Trace(err) return } if resultSetNode, ok := stmt.(ast.ResultSetNode); ok { e.ResultFields = convertResultFields(resultSetNode.GetResultFields()) } } if e.ID == 0 { e.ID = vars.GetNextPreparedStmtID() } if e.Name != "" { vars.PreparedStmtNameToID[e.Name] = e.ID } vars.PreparedStmts[e.ID] = prepared }
func (ts *testMiscSuite) TestDMLVistorCover(c *C) { sql := `delete from somelog where user = '******' order by timestamp_column limit 1; delete t1, t2 from t1 inner join t2 inner join t3 where t1.id=t2.id and t2.id=t3.id; select * from t where exists(select * from t k where t.c = k.c having sum(c) = 1); insert into t_copy select * from t where t.x > 5; (select a from t1 where a=10 and b=1) union (select a from t2 where a=11 and b=2) order by a limit 10; update t1 set col1 = col1 + 1, col2 = col1; show create table t; load data infile '/tmp/t.csv' into table t fields terminated by 'ab' enclosed by 'b';` parser := parser.New() stmts, err := parser.Parse(sql, "", "") c.Assert(err, IsNil) for _, stmt := range stmts { stmt.Accept(visitor{}) stmt.Accept(visitor1{}) } }
func (ts *testMiscSuite) TestDDLVisitorCover(c *C) { sql := ` create table t (c1 smallint unsigned, c2 int unsigned); alter table t add column a smallint unsigned after b; create index t_i on t (id); create database test character set utf8; drop database test; drop index t_i on t; drop table t; truncate t; create table t ( jobAbbr char(4) not null, constraint foreign key (jobabbr) references ffxi_jobtype (jobabbr) on delete cascade on update cascade ); ` parser := parser.New() stmts, err := parser.Parse(sql, "", "") c.Assert(err, IsNil) for _, stmt := range stmts { stmt.Accept(visitor{}) stmt.Accept(visitor1{}) } }
func (s *testPlanSuite) TestRangeBuilder(c *C) { rb := &rangeBuilder{} cases := []struct { exprStr string resultStr string }{ { exprStr: "a = 1", resultStr: "[[1 1]]", }, { exprStr: "1 = a", resultStr: "[[1 1]]", }, { exprStr: "a != 1", resultStr: "[[-inf 1) (1 +inf]]", }, { exprStr: "1 != a", resultStr: "[[-inf 1) (1 +inf]]", }, { exprStr: "a > 1", resultStr: "[(1 +inf]]", }, { exprStr: "1 < a", resultStr: "[(1 +inf]]", }, { exprStr: "a >= 1", resultStr: "[[1 +inf]]", }, { exprStr: "1 <= a", resultStr: "[[1 +inf]]", }, { exprStr: "a < 1", resultStr: "[[-inf 1)]", }, { exprStr: "1 > a", resultStr: "[[-inf 1)]", }, { exprStr: "a <= 1", resultStr: "[[-inf 1]]", }, { exprStr: "1 >= a", resultStr: "[[-inf 1]]", }, { exprStr: "(a)", resultStr: "[[-inf 0) (0 +inf]]", }, { exprStr: "a in (1, 3, NULL, 2)", resultStr: "[[<nil> <nil>] [1 1] [2 2] [3 3]]", }, { exprStr: "a between 1 and 2", resultStr: "[[1 2]]", }, { exprStr: "a not between 1 and 2", resultStr: "[[-inf 1) (2 +inf]]", }, { exprStr: "a not between null and 0", resultStr: "[(0 +inf]]", }, { exprStr: "a between 2 and 1", resultStr: "[]", }, { exprStr: "a not between 2 and 1", resultStr: "[[-inf +inf]]", }, { exprStr: "a IS NULL", resultStr: "[[<nil> <nil>]]", }, { exprStr: "a IS NOT NULL", resultStr: "[[-inf +inf]]", }, { exprStr: "a IS TRUE", resultStr: "[[-inf 0) (0 +inf]]", }, { exprStr: "a IS NOT TRUE", resultStr: "[[<nil> <nil>] [0 0]]", }, { exprStr: "a IS FALSE", resultStr: "[[0 0]]", }, { exprStr: "a IS NOT FALSE", resultStr: "[[<nil> 0) (0 +inf]]", }, { exprStr: "a LIKE 'abc%'", resultStr: "[[abc abd)]", }, { exprStr: "a LIKE 'abc_'", resultStr: "[(abc abd)]", }, { exprStr: "a LIKE '%'", resultStr: "[[-inf +inf]]", }, { exprStr: `a LIKE '\%a'`, resultStr: `[[%a %b)]`, }, { exprStr: `a LIKE "\\"`, resultStr: `[[\ ])]`, }, { exprStr: `a LIKE "\\\\a%"`, resultStr: `[[\a \b)]`, }, { exprStr: `a > 0 AND a < 1`, resultStr: `[(0 1)]`, }, { exprStr: `a > 1 AND a < 0`, resultStr: `[]`, }, { exprStr: `a > 1 OR a < 0`, resultStr: `[[-inf 0) (1 +inf]]`, }, { exprStr: `(a > 1 AND a < 2) OR (a > 3 AND a < 4)`, resultStr: `[(1 2) (3 4)]`, }, { exprStr: `(a < 0 OR a > 3) AND (a < 1 OR a > 4)`, resultStr: `[[-inf 0) (4 +inf]]`, }, } for _, ca := range cases { sql := "select 1 from dual where " + ca.exprStr stmts, err := parser.Parse(sql, "", "") c.Assert(err, IsNil, Commentf("error %v, for expr %s", err, ca.exprStr)) stmt := stmts[0].(*ast.SelectStmt) result := rb.build(stmt.Where) c.Assert(rb.err, IsNil) got := fmt.Sprintf("%v", result) c.Assert(got, Equals, ca.resultStr, Commentf("differen for expr %s", ca.exprStr)) } }
func (s *testPlanSuite) TestNewRangeBuilder(c *C) { UseNewPlanner = true defer testleak.AfterTest(c)() rb := &rangeBuilder{} cases := []struct { exprStr string resultStr string }{ { exprStr: "a = 1", resultStr: "[[1 1]]", }, { exprStr: "1 = a", resultStr: "[[1 1]]", }, { exprStr: "a != 1", resultStr: "[[-inf 1) (1 +inf]]", }, { exprStr: "1 != a", resultStr: "[[-inf 1) (1 +inf]]", }, { exprStr: "a > 1", resultStr: "[(1 +inf]]", }, { exprStr: "1 < a", resultStr: "[(1 +inf]]", }, { exprStr: "a >= 1", resultStr: "[[1 +inf]]", }, { exprStr: "1 <= a", resultStr: "[[1 +inf]]", }, { exprStr: "a < 1", resultStr: "[[-inf 1)]", }, { exprStr: "1 > a", resultStr: "[[-inf 1)]", }, { exprStr: "a <= 1", resultStr: "[[-inf 1]]", }, { exprStr: "1 >= a", resultStr: "[[-inf 1]]", }, { exprStr: "(a)", resultStr: "[[-inf 0) (0 +inf]]", }, { exprStr: `0.4`, resultStr: `[]`, }, { exprStr: `a > NULL`, resultStr: `[]`, }, } for _, ca := range cases { sql := "select 1 from t where " + ca.exprStr stmts, err := parser.Parse(sql, "", "") c.Assert(err, IsNil, Commentf("error %v, for expr %s", err, ca.exprStr)) stmt := stmts[0].(*ast.SelectStmt) err = newMockResolve(stmt) c.Assert(err, IsNil) p, err := BuildPlan(stmt, nil) c.Assert(err, IsNil, Commentf("error %v, for build plan, expr %s", err, ca.exprStr)) var selection *Selection for _, child := range p.GetChildren() { plan, ok := child.(*Selection) if ok { selection = plan break } } c.Assert(selection, NotNil, Commentf("expr:%v", ca.exprStr)) c.Assert(selection.Conditions, HasLen, 1, Commentf("conditions:%v, expr:%v", selection.Conditions, ca.exprStr)) result := rb.newBuild(selection.Conditions[0]) c.Assert(rb.err, IsNil) got := fmt.Sprintf("%v", result) c.Assert(got, Equals, ca.resultStr, Commentf("differen for expr %s", ca.exprStr)) } UseNewPlanner = false }
func (s *testPlanSuite) TestNewRangeBuilder(c *C) { UseNewPlanner = true defer testleak.AfterTest(c)() rb := &rangeBuilder{} cases := []struct { exprStr string resultStr string }{ { exprStr: "a = 1", resultStr: "[[1 1]]", }, { exprStr: "1 = a", resultStr: "[[1 1]]", }, { exprStr: "a != 1", resultStr: "[[-inf 1) (1 +inf]]", }, { exprStr: "1 != a", resultStr: "[[-inf 1) (1 +inf]]", }, { exprStr: "a > 1", resultStr: "[(1 +inf]]", }, { exprStr: "1 < a", resultStr: "[(1 +inf]]", }, { exprStr: "a >= 1", resultStr: "[[1 +inf]]", }, { exprStr: "1 <= a", resultStr: "[[1 +inf]]", }, { exprStr: "a < 1", resultStr: "[[-inf 1)]", }, { exprStr: "1 > a", resultStr: "[[-inf 1)]", }, { exprStr: "a <= 1", resultStr: "[[-inf 1]]", }, { exprStr: "1 >= a", resultStr: "[[-inf 1]]", }, { exprStr: "(a)", resultStr: "[[-inf 0) (0 +inf]]", }, { exprStr: "a in (1, 3, NULL, 2)", resultStr: "[[<nil> <nil>] [1 1] [2 2] [3 3]]", }, { exprStr: `a IN (8,8,81,45)`, resultStr: `[[8 8] [45 45] [81 81]]`, }, { exprStr: "a between 1 and 2", resultStr: "[[1 2]]", }, { exprStr: "a not between 1 and 2", resultStr: "[[-inf 1) (2 +inf]]", }, { exprStr: "a not between null and 0", resultStr: "[(0 +inf]]", }, { exprStr: "a between 2 and 1", resultStr: "[]", }, { exprStr: "a not between 2 and 1", resultStr: "[[-inf +inf]]", }, { exprStr: "a IS NULL", resultStr: "[[<nil> <nil>]]", }, { exprStr: "a IS NOT NULL", resultStr: "[[-inf +inf]]", }, { exprStr: "a IS TRUE", resultStr: "[[-inf 0) (0 +inf]]", }, { exprStr: "a IS NOT TRUE", resultStr: "[[<nil> <nil>] [0 0]]", }, { exprStr: "a IS FALSE", resultStr: "[[0 0]]", }, { exprStr: "a IS NOT FALSE", resultStr: "[[<nil> 0) (0 +inf]]", }, { exprStr: "a LIKE 'abc%'", resultStr: "[[abc abd)]", }, { exprStr: "a LIKE 'abc_'", resultStr: "[(abc abd)]", }, { exprStr: "a LIKE 'abc'", resultStr: "[[abc abc]]", }, { exprStr: `a LIKE "ab\_c"`, resultStr: "[[ab_c ab_c]]", }, { exprStr: "a LIKE '%'", resultStr: "[[-inf +inf]]", }, { exprStr: `a LIKE '\%a'`, resultStr: `[[%a %a]]`, }, { exprStr: `a LIKE "\\"`, resultStr: `[[\ \]]`, }, { exprStr: `a LIKE "\\\\a%"`, resultStr: `[[\a \b)]`, }, { exprStr: `0.4`, resultStr: `[]`, }, { exprStr: `a > NULL`, resultStr: `[]`, }, } for _, ca := range cases { sql := "select 1 from t where " + ca.exprStr stmts, err := parser.Parse(sql, "", "") c.Assert(err, IsNil, Commentf("error %v, for expr %s", err, ca.exprStr)) stmt := stmts[0].(*ast.SelectStmt) err = newMockResolve(stmt) c.Assert(err, IsNil) p, err := BuildPlan(stmt, nil) c.Assert(err, IsNil, Commentf("error %v, for build plan, expr %s", err, ca.exprStr)) var selection *Selection for _, child := range p.GetChildren() { plan, ok := child.(*Selection) if ok { selection = plan break } } c.Assert(selection, NotNil, Commentf("expr:%v", ca.exprStr)) c.Assert(selection.Conditions, HasLen, 1, Commentf("conditions:%v, expr:%v", selection.Conditions, ca.exprStr)) result := rb.newBuild(selection.Conditions[0]) c.Assert(rb.err, IsNil) got := fmt.Sprintf("%v", result) c.Assert(got, Equals, ca.resultStr, Commentf("differen for expr %s", ca.exprStr)) } UseNewPlanner = false }