From 6451bd93eaaaec0db466d311ccd2c7addb01e87a Mon Sep 17 00:00:00 2001 From: haplone Date: Tue, 18 Dec 2018 15:19:12 +0800 Subject: [PATCH] [parser] parser: implement Restore for BinaryOperation, WhenClause, CaseExpr and ParenthesesExpr (#81) --- parser/ast/expressions.go | 52 ++++++++++++++++++++++++++++++--- parser/ast/expressions_test.go | 53 ++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 4 deletions(-) diff --git a/parser/ast/expressions.go b/parser/ast/expressions.go index dd0302a18e..18040403eb 100644 --- a/parser/ast/expressions.go +++ b/parser/ast/expressions.go @@ -154,7 +154,17 @@ type BinaryOperationExpr struct { // Restore implements Node interface. func (n *BinaryOperationExpr) Restore(ctx *RestoreCtx) error { - return errors.New("Not implemented") + if err := n.L.Restore(ctx); err != nil { + return errors.Annotate(err, "An error occurred when restore BinaryOperationExpr.L") + } + if err := n.Op.Restore(ctx.In); err != nil { + return errors.Annotate(err, "An error occurred when restore BinaryOperationExpr.Op") + } + if err := n.R.Restore(ctx); err != nil { + return errors.Annotate(err, "An error occurred when restore BinaryOperationExpr.R") + } + + return nil } // Format the ExprNode into a Writer. @@ -200,7 +210,15 @@ type WhenClause struct { // Restore implements Node interface. func (n *WhenClause) Restore(ctx *RestoreCtx) error { - return errors.New("Not implemented") + ctx.WriteKeyWord("WHEN ") + if err := n.Expr.Restore(ctx); err != nil { + return errors.Annotate(err, "An error occurred while restore WhenClauses.Expr") + } + ctx.WriteKeyWord(" THEN ") + if err := n.Result.Restore(ctx); err != nil { + return errors.Annotate(err, "An error occurred while restore WhenClauses.Result") + } + return nil } // Accept implements Node Accept interface. @@ -238,7 +256,28 @@ type CaseExpr struct { // Restore implements Node interface. func (n *CaseExpr) Restore(ctx *RestoreCtx) error { - return errors.New("Not implemented") + ctx.WriteKeyWord("CASE") + if n.Value != nil { + ctx.WritePlain(" ") + if err := n.Value.Restore(ctx); err != nil { + return errors.Annotate(err, "An error occurred while restore CaseExpr.Value") + } + } + for _, clause := range n.WhenClauses { + ctx.WritePlain(" ") + if err := clause.Restore(ctx); err != nil { + return errors.Annotate(err, "An error occurred while restore CaseExpr.WhenClauses") + } + } + if n.ElseClause != nil { + ctx.WriteKeyWord(" ELSE ") + if err := n.ElseClause.Restore(ctx); err != nil { + return errors.Annotate(err, "An error occurred while restore CaseExpr.ElseClause") + } + } + ctx.WriteKeyWord(" END") + + return nil } // Format the ExprNode into a Writer. @@ -777,7 +816,12 @@ type ParenthesesExpr struct { // Restore implements Node interface. func (n *ParenthesesExpr) Restore(ctx *RestoreCtx) error { - return errors.New("Not implemented") + ctx.WritePlain("(") + if err := n.Expr.Restore(ctx); err != nil { + return errors.Annotate(err, "An error occurred when restore ParenthesesExpr.Expr") + } + ctx.WritePlain(")") + return nil } // Format the ExprNode into a Writer. diff --git a/parser/ast/expressions_test.go b/parser/ast/expressions_test.go index 0fb60b5db0..697d29191c 100644 --- a/parser/ast/expressions_test.go +++ b/parser/ast/expressions_test.go @@ -155,3 +155,56 @@ func (tc *testExpressionsSuite) TestBetweenExprRestore(c *C) { } RunNodeRestoreTest(c, testCases, "select %s", extractNodeFunc) } + +func (tc *testExpressionsSuite) TestCaseExpr(c *C) { + testCases := []NodeRestoreTestCase{ + {"case when 1 then 2 end", "CASE WHEN 1 THEN 2 END"}, + {"case when 1 then 'a' when 2 then 'b' end", "CASE WHEN 1 THEN 'a' WHEN 2 THEN 'b' END"}, + {"case when 1 then 'a' when 2 then 'b' else 'c' end", "CASE WHEN 1 THEN 'a' WHEN 2 THEN 'b' ELSE 'c' END"}, + {"case when 'a'!=1 then true else false end", "CASE WHEN 'a'!=1 THEN TRUE ELSE FALSE END"}, + {"case a when 'a' then true else false end", "CASE `a` WHEN 'a' THEN TRUE ELSE FALSE END"}, + } + extractNodeFunc := func(node Node) Node { + return node.(*SelectStmt).Fields.Fields[0].Expr + } + RunNodeRestoreTest(c, testCases, "select %s", extractNodeFunc) +} + +func (tc *testExpressionsSuite) TestBinaryOperationExpr(c *C) { + testCases := []NodeRestoreTestCase{ + {"'a'!=1", "'a'!=1"}, + {"a!=1", "`a`!=1"}, + {"3<5", "3<5"}, + {"10>5", "10>5"}, + {"3+5", "3+5"}, + {"3-5", "3-5"}, + {"a<>5", "`a`!=5"}, + } + extractNodeFunc := func(node Node) Node { + return node.(*SelectStmt).Fields.Fields[0].Expr + } + RunNodeRestoreTest(c, testCases, "select %s", extractNodeFunc) +} + +func (tc *testExpressionsSuite) TestParenthesesExpr(c *C) { + testCases := []NodeRestoreTestCase{ + {"(1+2)*3", "(1+2)*3"}, + {"1+2*3", "1+2*3"}, + } + extractNodeFunc := func(node Node) Node { + return node.(*SelectStmt).Fields.Fields[0].Expr + } + RunNodeRestoreTest(c, testCases, "select %s", extractNodeFunc) +} + +func (tc *testExpressionsSuite) TestWhenClause(c *C) { + testCases := []NodeRestoreTestCase{ + {"when 1 then 2", "WHEN 1 THEN 2"}, + {"when 1 then 'a'", "WHEN 1 THEN 'a'"}, + {"when 'a'!=1 then true", "WHEN 'a'!=1 THEN TRUE"}, + } + extractNodeFunc := func(node Node) Node { + return node.(*SelectStmt).Fields.Fields[0].Expr.(*CaseExpr).WhenClauses[0] + } + RunNodeRestoreTest(c, testCases, "select case %s end", extractNodeFunc) +}