1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480 |
- // Copyright 2015 PingCAP, Inc.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // See the License for the specific language governing permissions and
- // limitations under the License.
- package ast
- import (
- "fmt"
- "io"
- "reflect"
- "regexp"
- "strings"
- "github.com/pingcap/errors"
- "github.com/pingcap/parser/format"
- "github.com/pingcap/parser/model"
- "github.com/pingcap/parser/opcode"
- )
- var (
- _ ExprNode = &BetweenExpr{}
- _ ExprNode = &BinaryOperationExpr{}
- _ ExprNode = &CaseExpr{}
- _ ExprNode = &ColumnNameExpr{}
- _ ExprNode = &TableNameExpr{}
- _ ExprNode = &CompareSubqueryExpr{}
- _ ExprNode = &DefaultExpr{}
- _ ExprNode = &ExistsSubqueryExpr{}
- _ ExprNode = &IsNullExpr{}
- _ ExprNode = &IsTruthExpr{}
- _ ExprNode = &ParenthesesExpr{}
- _ ExprNode = &PatternInExpr{}
- _ ExprNode = &PatternLikeExpr{}
- _ ExprNode = &PatternRegexpExpr{}
- _ ExprNode = &PositionExpr{}
- _ ExprNode = &RowExpr{}
- _ ExprNode = &SubqueryExpr{}
- _ ExprNode = &UnaryOperationExpr{}
- _ ExprNode = &ValuesExpr{}
- _ ExprNode = &VariableExpr{}
- _ ExprNode = &MatchAgainst{}
- _ ExprNode = &SetCollationExpr{}
- _ Node = &ColumnName{}
- _ Node = &WhenClause{}
- )
- // ValueExpr define a interface for ValueExpr.
- type ValueExpr interface {
- ExprNode
- SetValue(val interface{})
- GetValue() interface{}
- GetDatumString() string
- GetString() string
- GetProjectionOffset() int
- SetProjectionOffset(offset int)
- }
- // NewValueExpr creates a ValueExpr with value, and sets default field type.
- var NewValueExpr func(value interface{}, charset string, collate string) ValueExpr
- // NewParamMarkerExpr creates a ParamMarkerExpr.
- var NewParamMarkerExpr func(offset int) ParamMarkerExpr
- // BetweenExpr is for "between and" or "not between and" expression.
- type BetweenExpr struct {
- exprNode
- // Expr is the expression to be checked.
- Expr ExprNode
- // Left is the expression for minimal value in the range.
- Left ExprNode
- // Right is the expression for maximum value in the range.
- Right ExprNode
- // Not is true, the expression is "not between and".
- Not bool
- }
- // Restore implements Node interface.
- func (n *BetweenExpr) Restore(ctx *format.RestoreCtx) error {
- if err := n.Expr.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore BetweenExpr.Expr")
- }
- if n.Not {
- ctx.WriteKeyWord(" NOT BETWEEN ")
- } else {
- ctx.WriteKeyWord(" BETWEEN ")
- }
- if err := n.Left.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore BetweenExpr.Left")
- }
- ctx.WriteKeyWord(" AND ")
- if err := n.Right.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore BetweenExpr.Right ")
- }
- return nil
- }
- // Format the ExprNode into a Writer.
- func (n *BetweenExpr) Format(w io.Writer) {
- n.Expr.Format(w)
- if n.Not {
- fmt.Fprint(w, " NOT BETWEEN ")
- } else {
- fmt.Fprint(w, " BETWEEN ")
- }
- n.Left.Format(w)
- fmt.Fprint(w, " AND ")
- n.Right.Format(w)
- }
- // Accept implements Node interface.
- func (n *BetweenExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*BetweenExpr)
- node, ok := n.Expr.Accept(v)
- if !ok {
- return n, false
- }
- n.Expr = node.(ExprNode)
- node, ok = n.Left.Accept(v)
- if !ok {
- return n, false
- }
- n.Left = node.(ExprNode)
- node, ok = n.Right.Accept(v)
- if !ok {
- return n, false
- }
- n.Right = node.(ExprNode)
- return v.Leave(n)
- }
- // BinaryOperationExpr is for binary operation like `1 + 1`, `1 - 1`, etc.
- type BinaryOperationExpr struct {
- exprNode
- // Op is the operator code for BinaryOperation.
- Op opcode.Op
- // L is the left expression in BinaryOperation.
- L ExprNode
- // R is the right expression in BinaryOperation.
- R ExprNode
- }
- func restoreBinaryOpWithSpacesAround(ctx *format.RestoreCtx, op opcode.Op) error {
- shouldInsertSpace := ctx.Flags.HasSpacesAroundBinaryOperationFlag() || op.IsKeyword()
- if shouldInsertSpace {
- ctx.WritePlain(" ")
- }
- if err := op.Restore(ctx); err != nil {
- return err // no need to annotate, the caller will annotate.
- }
- if shouldInsertSpace {
- ctx.WritePlain(" ")
- }
- return nil
- }
- // Restore implements Node interface.
- func (n *BinaryOperationExpr) Restore(ctx *format.RestoreCtx) error {
- if err := n.L.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred when restore BinaryOperationExpr.L")
- }
- if err := restoreBinaryOpWithSpacesAround(ctx, n.Op); 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.
- func (n *BinaryOperationExpr) Format(w io.Writer) {
- n.L.Format(w)
- fmt.Fprint(w, " ")
- n.Op.Format(w)
- fmt.Fprint(w, " ")
- n.R.Format(w)
- }
- // Accept implements Node interface.
- func (n *BinaryOperationExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*BinaryOperationExpr)
- node, ok := n.L.Accept(v)
- if !ok {
- return n, false
- }
- n.L = node.(ExprNode)
- node, ok = n.R.Accept(v)
- if !ok {
- return n, false
- }
- n.R = node.(ExprNode)
- return v.Leave(n)
- }
- // WhenClause is the when clause in Case expression for "when condition then result".
- type WhenClause struct {
- node
- // Expr is the condition expression in WhenClause.
- Expr ExprNode
- // Result is the result expression in WhenClause.
- Result ExprNode
- }
- // Restore implements Node interface.
- func (n *WhenClause) Restore(ctx *format.RestoreCtx) error {
- 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.
- func (n *WhenClause) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*WhenClause)
- node, ok := n.Expr.Accept(v)
- if !ok {
- return n, false
- }
- n.Expr = node.(ExprNode)
- node, ok = n.Result.Accept(v)
- if !ok {
- return n, false
- }
- n.Result = node.(ExprNode)
- return v.Leave(n)
- }
- // CaseExpr is the case expression.
- type CaseExpr struct {
- exprNode
- // Value is the compare value expression.
- Value ExprNode
- // WhenClauses is the condition check expression.
- WhenClauses []*WhenClause
- // ElseClause is the else result expression.
- ElseClause ExprNode
- }
- // Restore implements Node interface.
- func (n *CaseExpr) Restore(ctx *format.RestoreCtx) error {
- 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.
- func (n *CaseExpr) Format(w io.Writer) {
- fmt.Fprint(w, "CASE")
- // Because the presence of `case when` syntax, `Value` could be nil and we need check this.
- if n.Value != nil {
- fmt.Fprint(w, " ")
- n.Value.Format(w)
- }
- for _, clause := range n.WhenClauses {
- fmt.Fprint(w, " ")
- fmt.Fprint(w, "WHEN ")
- clause.Expr.Format(w)
- fmt.Fprint(w, " THEN ")
- clause.Result.Format(w)
- }
- if n.ElseClause != nil {
- fmt.Fprint(w, " ELSE ")
- n.ElseClause.Format(w)
- }
- fmt.Fprint(w, " END")
- }
- // Accept implements Node Accept interface.
- func (n *CaseExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*CaseExpr)
- if n.Value != nil {
- node, ok := n.Value.Accept(v)
- if !ok {
- return n, false
- }
- n.Value = node.(ExprNode)
- }
- for i, val := range n.WhenClauses {
- node, ok := val.Accept(v)
- if !ok {
- return n, false
- }
- n.WhenClauses[i] = node.(*WhenClause)
- }
- if n.ElseClause != nil {
- node, ok := n.ElseClause.Accept(v)
- if !ok {
- return n, false
- }
- n.ElseClause = node.(ExprNode)
- }
- return v.Leave(n)
- }
- // SubqueryExpr represents a subquery.
- type SubqueryExpr struct {
- exprNode
- // Query is the query SelectNode.
- Query ResultSetNode
- Evaluated bool
- Correlated bool
- MultiRows bool
- Exists bool
- }
- // Restore implements Node interface.
- func (n *SubqueryExpr) Restore(ctx *format.RestoreCtx) error {
- ctx.WritePlain("(")
- if err := n.Query.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore SubqueryExpr.Query")
- }
- ctx.WritePlain(")")
- return nil
- }
- // Format the ExprNode into a Writer.
- func (n *SubqueryExpr) Format(w io.Writer) {
- panic("Not implemented")
- }
- // Accept implements Node Accept interface.
- func (n *SubqueryExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*SubqueryExpr)
- node, ok := n.Query.Accept(v)
- if !ok {
- return n, false
- }
- n.Query = node.(ResultSetNode)
- return v.Leave(n)
- }
- // CompareSubqueryExpr is the expression for "expr cmp (select ...)".
- // See https://dev.mysql.com/doc/refman/5.7/en/comparisons-using-subqueries.html
- // See https://dev.mysql.com/doc/refman/5.7/en/any-in-some-subqueries.html
- // See https://dev.mysql.com/doc/refman/5.7/en/all-subqueries.html
- type CompareSubqueryExpr struct {
- exprNode
- // L is the left expression
- L ExprNode
- // Op is the comparison opcode.
- Op opcode.Op
- // R is the subquery for right expression, may be rewritten to other type of expression.
- R ExprNode
- // All is true, we should compare all records in subquery.
- All bool
- }
- // Restore implements Node interface.
- func (n *CompareSubqueryExpr) Restore(ctx *format.RestoreCtx) error {
- if err := n.L.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore CompareSubqueryExpr.L")
- }
- if err := restoreBinaryOpWithSpacesAround(ctx, n.Op); err != nil {
- return errors.Annotate(err, "An error occurred while restore CompareSubqueryExpr.Op")
- }
- if n.All {
- ctx.WriteKeyWord("ALL ")
- } else {
- ctx.WriteKeyWord("ANY ")
- }
- if err := n.R.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore CompareSubqueryExpr.R")
- }
- return nil
- }
- // Format the ExprNode into a Writer.
- func (n *CompareSubqueryExpr) Format(w io.Writer) {
- panic("Not implemented")
- }
- // Accept implements Node Accept interface.
- func (n *CompareSubqueryExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*CompareSubqueryExpr)
- node, ok := n.L.Accept(v)
- if !ok {
- return n, false
- }
- n.L = node.(ExprNode)
- node, ok = n.R.Accept(v)
- if !ok {
- return n, false
- }
- n.R = node.(ExprNode)
- return v.Leave(n)
- }
- // TableNameExpr represents a table-level object name expression, such as sequence/table/view etc.
- type TableNameExpr struct {
- exprNode
- // Name is the referenced object name expression.
- Name *TableName
- }
- // Restore implements Node interface.
- func (n *TableNameExpr) Restore(ctx *format.RestoreCtx) error {
- if err := n.Name.Restore(ctx); err != nil {
- return errors.Trace(err)
- }
- return nil
- }
- // Format the ExprNode into a Writer.
- func (n *TableNameExpr) Format(w io.Writer) {
- dbName, tbName := n.Name.Schema.L, n.Name.Name.L
- if dbName == "" {
- fmt.Fprintf(w, "`%s`", tbName)
- } else {
- fmt.Fprintf(w, "`%s`.`%s`", dbName, tbName)
- }
- }
- // Accept implements Node Accept interface.
- func (n *TableNameExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*TableNameExpr)
- node, ok := n.Name.Accept(v)
- if !ok {
- return n, false
- }
- n.Name = node.(*TableName)
- return v.Leave(n)
- }
- // ColumnName represents column name.
- type ColumnName struct {
- node
- Schema model.CIStr
- Table model.CIStr
- Name model.CIStr
- }
- // Restore implements Node interface.
- func (n *ColumnName) Restore(ctx *format.RestoreCtx) error {
- if n.Schema.O != "" {
- ctx.WriteName(n.Schema.O)
- ctx.WritePlain(".")
- }
- if n.Table.O != "" {
- ctx.WriteName(n.Table.O)
- ctx.WritePlain(".")
- }
- ctx.WriteName(n.Name.O)
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *ColumnName) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*ColumnName)
- return v.Leave(n)
- }
- // String implements Stringer interface.
- func (n *ColumnName) String() string {
- result := n.Name.L
- if n.Table.L != "" {
- result = n.Table.L + "." + result
- }
- if n.Schema.L != "" {
- result = n.Schema.L + "." + result
- }
- return result
- }
- // OrigColName returns the full original column name.
- func (n *ColumnName) OrigColName() (ret string) {
- ret = n.Name.O
- if n.Table.O == "" {
- return
- }
- ret = n.Table.O + "." + ret
- if n.Schema.O == "" {
- return
- }
- ret = n.Schema.O + "." + ret
- return
- }
- // ColumnNameExpr represents a column name expression.
- type ColumnNameExpr struct {
- exprNode
- // Name is the referenced column name.
- Name *ColumnName
- // Refer is the result field the column name refers to.
- // The value of Refer.Expr is used as the value of the expression.
- Refer *ResultField
- }
- // Restore implements Node interface.
- func (n *ColumnNameExpr) Restore(ctx *format.RestoreCtx) error {
- if err := n.Name.Restore(ctx); err != nil {
- return errors.Trace(err)
- }
- return nil
- }
- // Format the ExprNode into a Writer.
- func (n *ColumnNameExpr) Format(w io.Writer) {
- name := strings.Replace(n.Name.String(), ".", "`.`", -1)
- fmt.Fprintf(w, "`%s`", name)
- }
- // Accept implements Node Accept interface.
- func (n *ColumnNameExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*ColumnNameExpr)
- node, ok := n.Name.Accept(v)
- if !ok {
- return n, false
- }
- n.Name = node.(*ColumnName)
- return v.Leave(n)
- }
- // DefaultExpr is the default expression using default value for a column.
- type DefaultExpr struct {
- exprNode
- // Name is the column name.
- Name *ColumnName
- }
- // Restore implements Node interface.
- func (n *DefaultExpr) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("DEFAULT")
- if n.Name != nil {
- ctx.WritePlain("(")
- if err := n.Name.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore DefaultExpr.Name")
- }
- ctx.WritePlain(")")
- }
- return nil
- }
- // Format the ExprNode into a Writer.
- func (n *DefaultExpr) Format(w io.Writer) {
- panic("Not implemented")
- }
- // Accept implements Node Accept interface.
- func (n *DefaultExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*DefaultExpr)
- return v.Leave(n)
- }
- // ExistsSubqueryExpr is the expression for "exists (select ...)".
- // See https://dev.mysql.com/doc/refman/5.7/en/exists-and-not-exists-subqueries.html
- type ExistsSubqueryExpr struct {
- exprNode
- // Sel is the subquery, may be rewritten to other type of expression.
- Sel ExprNode
- // Not is true, the expression is "not exists".
- Not bool
- }
- // Restore implements Node interface.
- func (n *ExistsSubqueryExpr) Restore(ctx *format.RestoreCtx) error {
- if n.Not {
- ctx.WriteKeyWord("NOT EXISTS ")
- } else {
- ctx.WriteKeyWord("EXISTS ")
- }
- if err := n.Sel.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore ExistsSubqueryExpr.Sel")
- }
- return nil
- }
- // Format the ExprNode into a Writer.
- func (n *ExistsSubqueryExpr) Format(w io.Writer) {
- panic("Not implemented")
- }
- // Accept implements Node Accept interface.
- func (n *ExistsSubqueryExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*ExistsSubqueryExpr)
- node, ok := n.Sel.Accept(v)
- if !ok {
- return n, false
- }
- n.Sel = node.(ExprNode)
- return v.Leave(n)
- }
- // PatternInExpr is the expression for in operator, like "expr in (1, 2, 3)" or "expr in (select c from t)".
- type PatternInExpr struct {
- exprNode
- // Expr is the value expression to be compared.
- Expr ExprNode
- // List is the list expression in compare list.
- List []ExprNode
- // Not is true, the expression is "not in".
- Not bool
- // Sel is the subquery, may be rewritten to other type of expression.
- Sel ExprNode
- }
- // Restore implements Node interface.
- func (n *PatternInExpr) Restore(ctx *format.RestoreCtx) error {
- if err := n.Expr.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore PatternInExpr.Expr")
- }
- if n.Not {
- ctx.WriteKeyWord(" NOT IN ")
- } else {
- ctx.WriteKeyWord(" IN ")
- }
- if n.Sel != nil {
- if err := n.Sel.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore PatternInExpr.Sel")
- }
- } else {
- ctx.WritePlain("(")
- for i, expr := range n.List {
- if i != 0 {
- ctx.WritePlain(",")
- }
- if err := expr.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore PatternInExpr.List[%d]", i)
- }
- }
- ctx.WritePlain(")")
- }
- return nil
- }
- // Format the ExprNode into a Writer.
- func (n *PatternInExpr) Format(w io.Writer) {
- n.Expr.Format(w)
- if n.Not {
- fmt.Fprint(w, " NOT IN (")
- } else {
- fmt.Fprint(w, " IN (")
- }
- for i, expr := range n.List {
- if i != 0 {
- fmt.Fprint(w, ",")
- }
- expr.Format(w)
- }
- fmt.Fprint(w, ")")
- }
- // Accept implements Node Accept interface.
- func (n *PatternInExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*PatternInExpr)
- node, ok := n.Expr.Accept(v)
- if !ok {
- return n, false
- }
- n.Expr = node.(ExprNode)
- for i, val := range n.List {
- node, ok = val.Accept(v)
- if !ok {
- return n, false
- }
- n.List[i] = node.(ExprNode)
- }
- if n.Sel != nil {
- node, ok = n.Sel.Accept(v)
- if !ok {
- return n, false
- }
- n.Sel = node.(ExprNode)
- }
- return v.Leave(n)
- }
- // IsNullExpr is the expression for null check.
- type IsNullExpr struct {
- exprNode
- // Expr is the expression to be checked.
- Expr ExprNode
- // Not is true, the expression is "is not null".
- Not bool
- }
- // Restore implements Node interface.
- func (n *IsNullExpr) Restore(ctx *format.RestoreCtx) error {
- if err := n.Expr.Restore(ctx); err != nil {
- return errors.Trace(err)
- }
- if n.Not {
- ctx.WriteKeyWord(" IS NOT NULL")
- } else {
- ctx.WriteKeyWord(" IS NULL")
- }
- return nil
- }
- // Format the ExprNode into a Writer.
- func (n *IsNullExpr) Format(w io.Writer) {
- n.Expr.Format(w)
- if n.Not {
- fmt.Fprint(w, " IS NOT NULL")
- return
- }
- fmt.Fprint(w, " IS NULL")
- }
- // Accept implements Node Accept interface.
- func (n *IsNullExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*IsNullExpr)
- node, ok := n.Expr.Accept(v)
- if !ok {
- return n, false
- }
- n.Expr = node.(ExprNode)
- return v.Leave(n)
- }
- // IsTruthExpr is the expression for true/false check.
- type IsTruthExpr struct {
- exprNode
- // Expr is the expression to be checked.
- Expr ExprNode
- // Not is true, the expression is "is not true/false".
- Not bool
- // True indicates checking true or false.
- True int64
- }
- // Restore implements Node interface.
- func (n *IsTruthExpr) Restore(ctx *format.RestoreCtx) error {
- if err := n.Expr.Restore(ctx); err != nil {
- return errors.Trace(err)
- }
- if n.Not {
- ctx.WriteKeyWord(" IS NOT")
- } else {
- ctx.WriteKeyWord(" IS")
- }
- if n.True > 0 {
- ctx.WriteKeyWord(" TRUE")
- } else {
- ctx.WriteKeyWord(" FALSE")
- }
- return nil
- }
- // Format the ExprNode into a Writer.
- func (n *IsTruthExpr) Format(w io.Writer) {
- n.Expr.Format(w)
- if n.Not {
- fmt.Fprint(w, " IS NOT")
- } else {
- fmt.Fprint(w, " IS")
- }
- if n.True > 0 {
- fmt.Fprint(w, " TRUE")
- } else {
- fmt.Fprint(w, " FALSE")
- }
- }
- // Accept implements Node Accept interface.
- func (n *IsTruthExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*IsTruthExpr)
- node, ok := n.Expr.Accept(v)
- if !ok {
- return n, false
- }
- n.Expr = node.(ExprNode)
- return v.Leave(n)
- }
- // PatternLikeExpr is the expression for like operator, e.g, expr like "%123%"
- type PatternLikeExpr struct {
- exprNode
- // Expr is the expression to be checked.
- Expr ExprNode
- // Pattern is the like expression.
- Pattern ExprNode
- // Not is true, the expression is "not like".
- Not bool
- Escape byte
- PatChars []byte
- PatTypes []byte
- }
- // Restore implements Node interface.
- func (n *PatternLikeExpr) Restore(ctx *format.RestoreCtx) error {
- if err := n.Expr.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore PatternLikeExpr.Expr")
- }
- if n.Not {
- ctx.WriteKeyWord(" NOT LIKE ")
- } else {
- ctx.WriteKeyWord(" LIKE ")
- }
- if err := n.Pattern.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore PatternLikeExpr.Pattern")
- }
- escape := string(n.Escape)
- if escape != "\\" {
- ctx.WriteKeyWord(" ESCAPE ")
- ctx.WriteString(escape)
- }
- return nil
- }
- // Format the ExprNode into a Writer.
- func (n *PatternLikeExpr) Format(w io.Writer) {
- n.Expr.Format(w)
- if n.Not {
- fmt.Fprint(w, " NOT LIKE ")
- } else {
- fmt.Fprint(w, " LIKE ")
- }
- n.Pattern.Format(w)
- if n.Escape != '\\' {
- fmt.Fprint(w, " ESCAPE ")
- fmt.Fprintf(w, "'%c'", n.Escape)
- }
- }
- // Accept implements Node Accept interface.
- func (n *PatternLikeExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*PatternLikeExpr)
- if n.Expr != nil {
- node, ok := n.Expr.Accept(v)
- if !ok {
- return n, false
- }
- n.Expr = node.(ExprNode)
- }
- if n.Pattern != nil {
- node, ok := n.Pattern.Accept(v)
- if !ok {
- return n, false
- }
- n.Pattern = node.(ExprNode)
- }
- return v.Leave(n)
- }
- // ParamMarkerExpr expression holds a place for another expression.
- // Used in parsing prepare statement.
- type ParamMarkerExpr interface {
- ValueExpr
- SetOrder(int)
- }
- // ParenthesesExpr is the parentheses expression.
- type ParenthesesExpr struct {
- exprNode
- // Expr is the expression in parentheses.
- Expr ExprNode
- }
- // Restore implements Node interface.
- func (n *ParenthesesExpr) Restore(ctx *format.RestoreCtx) error {
- 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.
- func (n *ParenthesesExpr) Format(w io.Writer) {
- fmt.Fprint(w, "(")
- n.Expr.Format(w)
- fmt.Fprint(w, ")")
- }
- // Accept implements Node Accept interface.
- func (n *ParenthesesExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*ParenthesesExpr)
- if n.Expr != nil {
- node, ok := n.Expr.Accept(v)
- if !ok {
- return n, false
- }
- n.Expr = node.(ExprNode)
- }
- return v.Leave(n)
- }
- // PositionExpr is the expression for order by and group by position.
- // MySQL use position expression started from 1, it looks a little confused inner.
- // maybe later we will use 0 at first.
- type PositionExpr struct {
- exprNode
- // N is the position, started from 1 now.
- N int
- // P is the parameterized position.
- P ExprNode
- // Refer is the result field the position refers to.
- Refer *ResultField
- }
- // Restore implements Node interface.
- func (n *PositionExpr) Restore(ctx *format.RestoreCtx) error {
- ctx.WritePlainf("%d", n.N)
- return nil
- }
- // Format the ExprNode into a Writer.
- func (n *PositionExpr) Format(w io.Writer) {
- panic("Not implemented")
- }
- // Accept implements Node Accept interface.
- func (n *PositionExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*PositionExpr)
- if n.P != nil {
- node, ok := n.P.Accept(v)
- if !ok {
- return n, false
- }
- n.P = node.(ExprNode)
- }
- return v.Leave(n)
- }
- // PatternRegexpExpr is the pattern expression for pattern match.
- type PatternRegexpExpr struct {
- exprNode
- // Expr is the expression to be checked.
- Expr ExprNode
- // Pattern is the expression for pattern.
- Pattern ExprNode
- // Not is true, the expression is "not rlike",
- Not bool
- // Re is the compiled regexp.
- Re *regexp.Regexp
- // Sexpr is the string for Expr expression.
- Sexpr *string
- }
- // Restore implements Node interface.
- func (n *PatternRegexpExpr) Restore(ctx *format.RestoreCtx) error {
- if err := n.Expr.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore PatternRegexpExpr.Expr")
- }
- if n.Not {
- ctx.WriteKeyWord(" NOT REGEXP ")
- } else {
- ctx.WriteKeyWord(" REGEXP ")
- }
- if err := n.Pattern.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore PatternRegexpExpr.Pattern")
- }
- return nil
- }
- // Format the ExprNode into a Writer.
- func (n *PatternRegexpExpr) Format(w io.Writer) {
- n.Expr.Format(w)
- if n.Not {
- fmt.Fprint(w, " NOT REGEXP ")
- } else {
- fmt.Fprint(w, " REGEXP ")
- }
- n.Pattern.Format(w)
- }
- // Accept implements Node Accept interface.
- func (n *PatternRegexpExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*PatternRegexpExpr)
- node, ok := n.Expr.Accept(v)
- if !ok {
- return n, false
- }
- n.Expr = node.(ExprNode)
- node, ok = n.Pattern.Accept(v)
- if !ok {
- return n, false
- }
- n.Pattern = node.(ExprNode)
- return v.Leave(n)
- }
- // RowExpr is the expression for row constructor.
- // See https://dev.mysql.com/doc/refman/5.7/en/row-subqueries.html
- type RowExpr struct {
- exprNode
- Values []ExprNode
- }
- // Restore implements Node interface.
- func (n *RowExpr) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("ROW")
- ctx.WritePlain("(")
- for i, v := range n.Values {
- if i != 0 {
- ctx.WritePlain(",")
- }
- if err := v.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred when restore RowExpr.Values[%v]", i)
- }
- }
- ctx.WritePlain(")")
- return nil
- }
- // Format the ExprNode into a Writer.
- func (n *RowExpr) Format(w io.Writer) {
- panic("Not implemented")
- }
- // Accept implements Node Accept interface.
- func (n *RowExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*RowExpr)
- for i, val := range n.Values {
- node, ok := val.Accept(v)
- if !ok {
- return n, false
- }
- n.Values[i] = node.(ExprNode)
- }
- return v.Leave(n)
- }
- // UnaryOperationExpr is the expression for unary operator.
- type UnaryOperationExpr struct {
- exprNode
- // Op is the operator opcode.
- Op opcode.Op
- // V is the unary expression.
- V ExprNode
- }
- // Restore implements Node interface.
- func (n *UnaryOperationExpr) Restore(ctx *format.RestoreCtx) error {
- if err := n.Op.Restore(ctx); err != nil {
- return errors.Trace(err)
- }
- if err := n.V.Restore(ctx); err != nil {
- return errors.Trace(err)
- }
- return nil
- }
- // Format the ExprNode into a Writer.
- func (n *UnaryOperationExpr) Format(w io.Writer) {
- n.Op.Format(w)
- n.V.Format(w)
- }
- // Accept implements Node Accept interface.
- func (n *UnaryOperationExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*UnaryOperationExpr)
- node, ok := n.V.Accept(v)
- if !ok {
- return n, false
- }
- n.V = node.(ExprNode)
- return v.Leave(n)
- }
- // ValuesExpr is the expression used in INSERT VALUES.
- type ValuesExpr struct {
- exprNode
- // Column is column name.
- Column *ColumnNameExpr
- }
- // Restore implements Node interface.
- func (n *ValuesExpr) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("VALUES")
- ctx.WritePlain("(")
- if err := n.Column.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore ValuesExpr.Column")
- }
- ctx.WritePlain(")")
- return nil
- }
- // Format the ExprNode into a Writer.
- func (n *ValuesExpr) Format(w io.Writer) {
- panic("Not implemented")
- }
- // Accept implements Node Accept interface.
- func (n *ValuesExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*ValuesExpr)
- node, ok := n.Column.Accept(v)
- if !ok {
- return n, false
- }
- if col, ok := node.(*ColumnNameExpr); ok {
- // `node` may be *ast.ValueExpr
- n.Column = col
- }
- return v.Leave(n)
- }
- // VariableExpr is the expression for variable.
- type VariableExpr struct {
- exprNode
- // Name is the variable name.
- Name string
- // IsGlobal indicates whether this variable is global.
- IsGlobal bool
- // IsSystem indicates whether this variable is a system variable in current session.
- IsSystem bool
- // ExplicitScope indicates whether this variable scope is set explicitly.
- ExplicitScope bool
- // Value is the variable value.
- Value ExprNode
- }
- // Restore implements Node interface.
- func (n *VariableExpr) Restore(ctx *format.RestoreCtx) error {
- if n.IsSystem {
- ctx.WritePlain("@@")
- if n.ExplicitScope {
- if n.IsGlobal {
- ctx.WriteKeyWord("GLOBAL")
- } else {
- ctx.WriteKeyWord("SESSION")
- }
- ctx.WritePlain(".")
- }
- } else {
- ctx.WritePlain("@")
- }
- ctx.WriteName(n.Name)
- if n.Value != nil {
- ctx.WritePlain(":=")
- if err := n.Value.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore VariableExpr.Value")
- }
- }
- return nil
- }
- // Format the ExprNode into a Writer.
- func (n *VariableExpr) Format(w io.Writer) {
- panic("Not implemented")
- }
- // Accept implements Node Accept interface.
- func (n *VariableExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*VariableExpr)
- if n.Value == nil {
- return v.Leave(n)
- }
- node, ok := n.Value.Accept(v)
- if !ok {
- return n, false
- }
- n.Value = node.(ExprNode)
- return v.Leave(n)
- }
- // MaxValueExpr is the expression for "maxvalue" used in partition.
- type MaxValueExpr struct {
- exprNode
- }
- // Restore implements Node interface.
- func (n *MaxValueExpr) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("MAXVALUE")
- return nil
- }
- // Format the ExprNode into a Writer.
- func (n *MaxValueExpr) Format(w io.Writer) {
- fmt.Fprint(w, "MAXVALUE")
- }
- // Accept implements Node Accept interface.
- func (n *MaxValueExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- return v.Leave(n)
- }
- // MatchAgainst is the expression for matching against fulltext index.
- type MatchAgainst struct {
- exprNode
- // ColumnNames are the columns to match.
- ColumnNames []*ColumnName
- // Against
- Against ExprNode
- // Modifier
- Modifier FulltextSearchModifier
- }
- func (n *MatchAgainst) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("MATCH")
- ctx.WritePlain(" (")
- for i, v := range n.ColumnNames {
- if i != 0 {
- ctx.WritePlain(",")
- }
- if err := v.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore MatchAgainst.ColumnNames[%d]", i)
- }
- }
- ctx.WritePlain(") ")
- ctx.WriteKeyWord("AGAINST")
- ctx.WritePlain(" (")
- if err := n.Against.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore MatchAgainst.Against")
- }
- if n.Modifier.IsBooleanMode() {
- ctx.WritePlain(" IN BOOLEAN MODE")
- if n.Modifier.WithQueryExpansion() {
- return errors.New("BOOLEAN MODE doesn't support QUERY EXPANSION")
- }
- } else if n.Modifier.WithQueryExpansion() {
- ctx.WritePlain(" WITH QUERY EXPANSION")
- }
- ctx.WritePlain(")")
- return nil
- }
- func (n *MatchAgainst) Format(w io.Writer) {
- fmt.Fprint(w, "MATCH(")
- for i, v := range n.ColumnNames {
- if i != 0 {
- fmt.Fprintf(w, ",%s", v.String())
- } else {
- fmt.Fprint(w, v.String())
- }
- }
- fmt.Fprint(w, ") AGAINST(")
- n.Against.Format(w)
- if n.Modifier.IsBooleanMode() {
- fmt.Fprint(w, " IN BOOLEAN MODE")
- } else if n.Modifier.WithQueryExpansion() {
- fmt.Fprint(w, " WITH QUERY EXPANSION")
- }
- fmt.Fprint(w, ")")
- }
- func (n *MatchAgainst) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*MatchAgainst)
- for i, colName := range n.ColumnNames {
- newColName, ok := colName.Accept(v)
- if !ok {
- return n, false
- }
- n.ColumnNames[i] = newColName.(*ColumnName)
- }
- newAgainst, ok := n.Against.Accept(v)
- if !ok {
- return n, false
- }
- n.Against = newAgainst.(ExprNode)
- return v.Leave(n)
- }
- // SetCollationExpr is the expression for the `COLLATE collation_name` clause.
- type SetCollationExpr struct {
- exprNode
- // Expr is the expression to be set.
- Expr ExprNode
- // Collate is the name of collation to set.
- Collate string
- }
- // Restore implements Node interface.
- func (n *SetCollationExpr) Restore(ctx *format.RestoreCtx) error {
- if err := n.Expr.Restore(ctx); err != nil {
- return errors.Trace(err)
- }
- ctx.WriteKeyWord(" COLLATE ")
- ctx.WritePlain(n.Collate)
- return nil
- }
- // Format the ExprNode into a Writer.
- func (n *SetCollationExpr) Format(w io.Writer) {
- n.Expr.Format(w)
- fmt.Fprintf(w, " COLLATE %s", n.Collate)
- }
- // Accept implements Node Accept interface.
- func (n *SetCollationExpr) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*SetCollationExpr)
- node, ok := n.Expr.Accept(v)
- if !ok {
- return n, false
- }
- n.Expr = node.(ExprNode)
- return v.Leave(n)
- }
- type exprTextPositionCleaner struct {
- oldTextPos []int
- restore bool
- }
- func (e *exprTextPositionCleaner) BeginRestore() {
- e.restore = true
- }
- func (e *exprTextPositionCleaner) Enter(n Node) (node Node, skipChildren bool) {
- if e.restore {
- n.SetOriginTextPosition(e.oldTextPos[0])
- e.oldTextPos = e.oldTextPos[1:]
- return n, false
- }
- e.oldTextPos = append(e.oldTextPos, n.OriginTextPosition())
- n.SetOriginTextPosition(0)
- return n, false
- }
- func (e *exprTextPositionCleaner) Leave(n Node) (node Node, ok bool) {
- return n, true
- }
- // ExpressionDeepEqual compares the equivalence of two expressions.
- func ExpressionDeepEqual(a ExprNode, b ExprNode) bool {
- cleanerA := &exprTextPositionCleaner{}
- cleanerB := &exprTextPositionCleaner{}
- a.Accept(cleanerA)
- b.Accept(cleanerB)
- result := reflect.DeepEqual(a, b)
- cleanerA.BeginRestore()
- cleanerB.BeginRestore()
- a.Accept(cleanerA)
- b.Accept(cleanerB)
- return result
- }
|