123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273 |
- // 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 (
- "bytes"
- "fmt"
- "net/url"
- "strconv"
- "strings"
- "github.com/pingcap/errors"
- "github.com/pingcap/parser/auth"
- "github.com/pingcap/parser/format"
- "github.com/pingcap/parser/model"
- "github.com/pingcap/parser/mysql"
- )
- var (
- _ StmtNode = &AdminStmt{}
- _ StmtNode = &AlterUserStmt{}
- _ StmtNode = &BeginStmt{}
- _ StmtNode = &BinlogStmt{}
- _ StmtNode = &CommitStmt{}
- _ StmtNode = &CreateUserStmt{}
- _ StmtNode = &DeallocateStmt{}
- _ StmtNode = &DoStmt{}
- _ StmtNode = &ExecuteStmt{}
- _ StmtNode = &ExplainStmt{}
- _ StmtNode = &GrantStmt{}
- _ StmtNode = &PrepareStmt{}
- _ StmtNode = &RollbackStmt{}
- _ StmtNode = &SetPwdStmt{}
- _ StmtNode = &SetRoleStmt{}
- _ StmtNode = &SetDefaultRoleStmt{}
- _ StmtNode = &SetStmt{}
- _ StmtNode = &UseStmt{}
- _ StmtNode = &FlushStmt{}
- _ StmtNode = &KillStmt{}
- _ StmtNode = &CreateBindingStmt{}
- _ StmtNode = &DropBindingStmt{}
- _ StmtNode = &ShutdownStmt{}
- _ StmtNode = &RenameUserStmt{}
- _ Node = &PrivElem{}
- _ Node = &VariableAssignment{}
- )
- // Isolation level constants.
- const (
- ReadCommitted = "READ-COMMITTED"
- ReadUncommitted = "READ-UNCOMMITTED"
- Serializable = "SERIALIZABLE"
- RepeatableRead = "REPEATABLE-READ"
- // Valid formats for explain statement.
- ExplainFormatROW = "row"
- ExplainFormatDOT = "dot"
- ExplainFormatJSON = "json"
- ExplainFormatHint = "hint"
- ExplainFormatVerbose = "verbose"
- ExplainFormatBrief = "brief"
- PumpType = "PUMP"
- DrainerType = "DRAINER"
- )
- // Transaction mode constants.
- const (
- Optimistic = "OPTIMISTIC"
- Pessimistic = "PESSIMISTIC"
- )
- var (
- // ExplainFormats stores the valid formats for explain statement, used by validator.
- ExplainFormats = []string{
- ExplainFormatROW,
- ExplainFormatDOT,
- ExplainFormatJSON,
- ExplainFormatHint,
- ExplainFormatVerbose,
- ExplainFormatBrief,
- }
- )
- // TypeOpt is used for parsing data type option from SQL.
- type TypeOpt struct {
- IsUnsigned bool
- IsZerofill bool
- }
- // FloatOpt is used for parsing floating-point type option from SQL.
- // See http://dev.mysql.com/doc/refman/5.7/en/floating-point-types.html
- type FloatOpt struct {
- Flen int
- Decimal int
- }
- // AuthOption is used for parsing create use statement.
- type AuthOption struct {
- // ByAuthString set as true, if AuthString is used for authorization. Otherwise, authorization is done by HashString.
- ByAuthString bool
- AuthString string
- HashString string
- // TODO: support auth_plugin
- }
- // Restore implements Node interface.
- func (n *AuthOption) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("IDENTIFIED BY ")
- if n.ByAuthString {
- ctx.WriteString(n.AuthString)
- } else {
- ctx.WriteKeyWord("PASSWORD ")
- ctx.WriteString(n.HashString)
- }
- return nil
- }
- // TraceStmt is a statement to trace what sql actually does at background.
- type TraceStmt struct {
- stmtNode
- Stmt StmtNode
- Format string
- }
- // Restore implements Node interface.
- func (n *TraceStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("TRACE ")
- if n.Format != "row" {
- ctx.WriteKeyWord("FORMAT")
- ctx.WritePlain(" = ")
- ctx.WriteString(n.Format)
- ctx.WritePlain(" ")
- }
- if err := n.Stmt.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore TraceStmt.Stmt")
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *TraceStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*TraceStmt)
- node, ok := n.Stmt.Accept(v)
- if !ok {
- return n, false
- }
- n.Stmt = node.(StmtNode)
- return v.Leave(n)
- }
- // ExplainForStmt is a statement to provite information about how is SQL statement executeing
- // in connection #ConnectionID
- // See https://dev.mysql.com/doc/refman/5.7/en/explain.html
- type ExplainForStmt struct {
- stmtNode
- Format string
- ConnectionID uint64
- }
- // Restore implements Node interface.
- func (n *ExplainForStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("EXPLAIN ")
- ctx.WriteKeyWord("FORMAT ")
- ctx.WritePlain("= ")
- ctx.WriteString(n.Format)
- ctx.WritePlain(" ")
- ctx.WriteKeyWord("FOR ")
- ctx.WriteKeyWord("CONNECTION ")
- ctx.WritePlain(strconv.FormatUint(n.ConnectionID, 10))
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *ExplainForStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*ExplainForStmt)
- return v.Leave(n)
- }
- // ExplainStmt is a statement to provide information about how is SQL statement executed
- // or get columns information in a table.
- // See https://dev.mysql.com/doc/refman/5.7/en/explain.html
- type ExplainStmt struct {
- stmtNode
- Stmt StmtNode
- Format string
- Analyze bool
- }
- // Restore implements Node interface.
- func (n *ExplainStmt) Restore(ctx *format.RestoreCtx) error {
- if showStmt, ok := n.Stmt.(*ShowStmt); ok {
- ctx.WriteKeyWord("DESC ")
- if err := showStmt.Table.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore ExplainStmt.ShowStmt.Table")
- }
- if showStmt.Column != nil {
- ctx.WritePlain(" ")
- if err := showStmt.Column.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore ExplainStmt.ShowStmt.Column")
- }
- }
- return nil
- }
- ctx.WriteKeyWord("EXPLAIN ")
- if n.Analyze {
- ctx.WriteKeyWord("ANALYZE ")
- } else {
- ctx.WriteKeyWord("FORMAT ")
- ctx.WritePlain("= ")
- ctx.WriteString(n.Format)
- ctx.WritePlain(" ")
- }
- if err := n.Stmt.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore ExplainStmt.Stmt")
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *ExplainStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*ExplainStmt)
- node, ok := n.Stmt.Accept(v)
- if !ok {
- return n, false
- }
- n.Stmt = node.(StmtNode)
- return v.Leave(n)
- }
- // PrepareStmt is a statement to prepares a SQL statement which contains placeholders,
- // and it is executed with ExecuteStmt and released with DeallocateStmt.
- // See https://dev.mysql.com/doc/refman/5.7/en/prepare.html
- type PrepareStmt struct {
- stmtNode
- Name string
- SQLText string
- SQLVar *VariableExpr
- }
- // Restore implements Node interface.
- func (n *PrepareStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("PREPARE ")
- ctx.WriteName(n.Name)
- ctx.WriteKeyWord(" FROM ")
- if n.SQLText != "" {
- ctx.WriteString(n.SQLText)
- return nil
- }
- if n.SQLVar != nil {
- if err := n.SQLVar.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore PrepareStmt.SQLVar")
- }
- return nil
- }
- return errors.New("An error occurred while restore PrepareStmt")
- }
- // Accept implements Node Accept interface.
- func (n *PrepareStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*PrepareStmt)
- if n.SQLVar != nil {
- node, ok := n.SQLVar.Accept(v)
- if !ok {
- return n, false
- }
- n.SQLVar = node.(*VariableExpr)
- }
- return v.Leave(n)
- }
- // DeallocateStmt is a statement to release PreparedStmt.
- // See https://dev.mysql.com/doc/refman/5.7/en/deallocate-prepare.html
- type DeallocateStmt struct {
- stmtNode
- Name string
- }
- // Restore implements Node interface.
- func (n *DeallocateStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("DEALLOCATE PREPARE ")
- ctx.WriteName(n.Name)
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *DeallocateStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*DeallocateStmt)
- return v.Leave(n)
- }
- // Prepared represents a prepared statement.
- type Prepared struct {
- Stmt StmtNode
- StmtType string
- Params []ParamMarkerExpr
- SchemaVersion int64
- UseCache bool
- CachedPlan interface{}
- CachedNames interface{}
- }
- // ExecuteStmt is a statement to execute PreparedStmt.
- // See https://dev.mysql.com/doc/refman/5.7/en/execute.html
- type ExecuteStmt struct {
- stmtNode
- Name string
- UsingVars []ExprNode
- BinaryArgs interface{}
- ExecID uint32
- IdxInMulti int
- }
- // Restore implements Node interface.
- func (n *ExecuteStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("EXECUTE ")
- ctx.WriteName(n.Name)
- if len(n.UsingVars) > 0 {
- ctx.WriteKeyWord(" USING ")
- for i, val := range n.UsingVars {
- if i != 0 {
- ctx.WritePlain(",")
- }
- if err := val.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore ExecuteStmt.UsingVars index %d", i)
- }
- }
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *ExecuteStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*ExecuteStmt)
- for i, val := range n.UsingVars {
- node, ok := val.Accept(v)
- if !ok {
- return n, false
- }
- n.UsingVars[i] = node.(ExprNode)
- }
- return v.Leave(n)
- }
- // BeginStmt is a statement to start a new transaction.
- // See https://dev.mysql.com/doc/refman/5.7/en/commit.html
- type BeginStmt struct {
- stmtNode
- Mode string
- ReadOnly bool
- Bound *TimestampBound
- CausalConsistencyOnly bool
- }
- // Restore implements Node interface.
- func (n *BeginStmt) Restore(ctx *format.RestoreCtx) error {
- if n.Mode == "" {
- if n.ReadOnly {
- ctx.WriteKeyWord("START TRANSACTION READ ONLY")
- if n.Bound != nil {
- switch n.Bound.Mode {
- case TimestampBoundStrong:
- ctx.WriteKeyWord(" WITH TIMESTAMP BOUND STRONG")
- case TimestampBoundMaxStaleness:
- ctx.WriteKeyWord(" WITH TIMESTAMP BOUND MAX STALENESS ")
- return n.Bound.Timestamp.Restore(ctx)
- case TimestampBoundExactStaleness:
- ctx.WriteKeyWord(" WITH TIMESTAMP BOUND EXACT STALENESS ")
- return n.Bound.Timestamp.Restore(ctx)
- case TimestampBoundReadTimestamp:
- ctx.WriteKeyWord(" WITH TIMESTAMP BOUND READ TIMESTAMP ")
- return n.Bound.Timestamp.Restore(ctx)
- case TimestampBoundMinReadTimestamp:
- ctx.WriteKeyWord(" WITH TIMESTAMP BOUND MIN READ TIMESTAMP ")
- return n.Bound.Timestamp.Restore(ctx)
- }
- }
- } else if n.CausalConsistencyOnly {
- ctx.WriteKeyWord("START TRANSACTION WITH CAUSAL CONSISTENCY ONLY")
- } else {
- ctx.WriteKeyWord("START TRANSACTION")
- }
- } else {
- ctx.WriteKeyWord("BEGIN ")
- ctx.WriteKeyWord(n.Mode)
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *BeginStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*BeginStmt)
- if n.Bound != nil && n.Bound.Timestamp != nil {
- newTimestamp, ok := n.Bound.Timestamp.Accept(v)
- if !ok {
- return n, false
- }
- n.Bound.Timestamp = newTimestamp.(ExprNode)
- }
- return v.Leave(n)
- }
- // BinlogStmt is an internal-use statement.
- // We just parse and ignore it.
- // See http://dev.mysql.com/doc/refman/5.7/en/binlog.html
- type BinlogStmt struct {
- stmtNode
- Str string
- }
- // Restore implements Node interface.
- func (n *BinlogStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("BINLOG ")
- ctx.WriteString(n.Str)
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *BinlogStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*BinlogStmt)
- return v.Leave(n)
- }
- // CompletionType defines completion_type used in COMMIT and ROLLBACK statements
- type CompletionType int8
- const (
- // CompletionTypeDefault refers to NO_CHAIN
- CompletionTypeDefault CompletionType = iota
- CompletionTypeChain
- CompletionTypeRelease
- )
- func (n CompletionType) Restore(ctx *format.RestoreCtx) error {
- switch n {
- case CompletionTypeDefault:
- break
- case CompletionTypeChain:
- ctx.WriteKeyWord(" AND CHAIN")
- case CompletionTypeRelease:
- ctx.WriteKeyWord(" RELEASE")
- }
- return nil
- }
- // CommitStmt is a statement to commit the current transaction.
- // See https://dev.mysql.com/doc/refman/5.7/en/commit.html
- type CommitStmt struct {
- stmtNode
- // CompletionType overwrites system variable `completion_type` within transaction
- CompletionType CompletionType
- }
- // Restore implements Node interface.
- func (n *CommitStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("COMMIT")
- if err := n.CompletionType.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore CommitStmt.CompletionType")
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *CommitStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*CommitStmt)
- return v.Leave(n)
- }
- // RollbackStmt is a statement to roll back the current transaction.
- // See https://dev.mysql.com/doc/refman/5.7/en/commit.html
- type RollbackStmt struct {
- stmtNode
- // CompletionType overwrites system variable `completion_type` within transaction
- CompletionType CompletionType
- }
- // Restore implements Node interface.
- func (n *RollbackStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("ROLLBACK")
- if err := n.CompletionType.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore RollbackStmt.CompletionType")
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *RollbackStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*RollbackStmt)
- return v.Leave(n)
- }
- // UseStmt is a statement to use the DBName database as the current database.
- // See https://dev.mysql.com/doc/refman/5.7/en/use.html
- type UseStmt struct {
- stmtNode
- DBName string
- }
- // Restore implements Node interface.
- func (n *UseStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("USE ")
- ctx.WriteName(n.DBName)
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *UseStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*UseStmt)
- return v.Leave(n)
- }
- const (
- // SetNames is the const for set names stmt.
- // If VariableAssignment.Name == Names, it should be set names stmt.
- SetNames = "SetNAMES"
- // SetCharset is the const for set charset stmt.
- SetCharset = "SetCharset"
- )
- // VariableAssignment is a variable assignment struct.
- type VariableAssignment struct {
- node
- Name string
- Value ExprNode
- IsGlobal bool
- IsSystem bool
- // ExtendValue is a way to store extended info.
- // VariableAssignment should be able to store information for SetCharset/SetPWD Stmt.
- // For SetCharsetStmt, Value is charset, ExtendValue is collation.
- // TODO: Use SetStmt to implement set password statement.
- ExtendValue ValueExpr
- }
- // Restore implements Node interface.
- func (n *VariableAssignment) Restore(ctx *format.RestoreCtx) error {
- if n.IsSystem {
- ctx.WritePlain("@@")
- if n.IsGlobal {
- ctx.WriteKeyWord("GLOBAL")
- } else {
- ctx.WriteKeyWord("SESSION")
- }
- ctx.WritePlain(".")
- } else if n.Name != SetNames && n.Name != SetCharset {
- ctx.WriteKeyWord("@")
- }
- if n.Name == SetNames {
- ctx.WriteKeyWord("NAMES ")
- } else if n.Name == SetCharset {
- ctx.WriteKeyWord("CHARSET ")
- } else {
- ctx.WriteName(n.Name)
- ctx.WritePlain("=")
- }
- if err := n.Value.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore VariableAssignment.Value")
- }
- if n.ExtendValue != nil {
- ctx.WriteKeyWord(" COLLATE ")
- if err := n.ExtendValue.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore VariableAssignment.ExtendValue")
- }
- }
- return nil
- }
- // Accept implements Node interface.
- func (n *VariableAssignment) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*VariableAssignment)
- node, ok := n.Value.Accept(v)
- if !ok {
- return n, false
- }
- n.Value = node.(ExprNode)
- return v.Leave(n)
- }
- // FlushStmtType is the type for FLUSH statement.
- type FlushStmtType int
- // Flush statement types.
- const (
- FlushNone FlushStmtType = iota
- FlushTables
- FlushPrivileges
- FlushStatus
- FlushTiDBPlugin
- FlushHosts
- FlushLogs
- FlushClientErrorsSummary
- )
- // LogType is the log type used in FLUSH statement.
- type LogType int8
- const (
- LogTypeDefault LogType = iota
- LogTypeBinary
- LogTypeEngine
- LogTypeError
- LogTypeGeneral
- LogTypeSlow
- )
- // FlushStmt is a statement to flush tables/privileges/optimizer costs and so on.
- type FlushStmt struct {
- stmtNode
- Tp FlushStmtType // Privileges/Tables/...
- NoWriteToBinLog bool
- LogType LogType
- Tables []*TableName // For FlushTableStmt, if Tables is empty, it means flush all tables.
- ReadLock bool
- Plugins []string
- }
- // Restore implements Node interface.
- func (n *FlushStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("FLUSH ")
- if n.NoWriteToBinLog {
- ctx.WriteKeyWord("NO_WRITE_TO_BINLOG ")
- }
- switch n.Tp {
- case FlushTables:
- ctx.WriteKeyWord("TABLES")
- for i, v := range n.Tables {
- if i == 0 {
- ctx.WritePlain(" ")
- } else {
- ctx.WritePlain(", ")
- }
- if err := v.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore FlushStmt.Tables[%d]", i)
- }
- }
- if n.ReadLock {
- ctx.WriteKeyWord(" WITH READ LOCK")
- }
- case FlushPrivileges:
- ctx.WriteKeyWord("PRIVILEGES")
- case FlushStatus:
- ctx.WriteKeyWord("STATUS")
- case FlushTiDBPlugin:
- ctx.WriteKeyWord("TIDB PLUGINS")
- for i, v := range n.Plugins {
- if i == 0 {
- ctx.WritePlain(" ")
- } else {
- ctx.WritePlain(", ")
- }
- ctx.WritePlain(v)
- }
- case FlushHosts:
- ctx.WriteKeyWord("HOSTS")
- case FlushLogs:
- var logType string
- switch n.LogType {
- case LogTypeDefault:
- logType = "LOGS"
- case LogTypeBinary:
- logType = "BINARY LOGS"
- case LogTypeEngine:
- logType = "ENGINE LOGS"
- case LogTypeError:
- logType = "ERROR LOGS"
- case LogTypeGeneral:
- logType = "GENERAL LOGS"
- case LogTypeSlow:
- logType = "SLOW LOGS"
- }
- ctx.WriteKeyWord(logType)
- case FlushClientErrorsSummary:
- ctx.WriteKeyWord("CLIENT_ERRORS_SUMMARY")
- default:
- return errors.New("Unsupported type of FlushStmt")
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *FlushStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*FlushStmt)
- return v.Leave(n)
- }
- // KillStmt is a statement to kill a query or connection.
- type KillStmt struct {
- stmtNode
- // Query indicates whether terminate a single query on this connection or the whole connection.
- // If Query is true, terminates the statement the connection is currently executing, but leaves the connection itself intact.
- // If Query is false, terminates the connection associated with the given ConnectionID, after terminating any statement the connection is executing.
- Query bool
- ConnectionID uint64
- // TiDBExtension is used to indicate whether the user knows he is sending kill statement to the right tidb-server.
- // When the SQL grammar is "KILL TIDB [CONNECTION | QUERY] connectionID", TiDBExtension will be set.
- // It's a special grammar extension in TiDB. This extension exists because, when the connection is:
- // client -> LVS proxy -> TiDB, and type Ctrl+C in client, the following action will be executed:
- // new a connection; kill xxx;
- // kill command may send to the wrong TiDB, because the exists of LVS proxy, and kill the wrong session.
- // So, "KILL TIDB" grammar is introduced, and it REQUIRES DIRECT client -> TiDB TOPOLOGY.
- // TODO: The standard KILL grammar will be supported once we have global connectionID.
- TiDBExtension bool
- }
- // Restore implements Node interface.
- func (n *KillStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("KILL")
- if n.TiDBExtension {
- ctx.WriteKeyWord(" TIDB")
- }
- if n.Query {
- ctx.WriteKeyWord(" QUERY")
- }
- ctx.WritePlainf(" %d", n.ConnectionID)
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *KillStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*KillStmt)
- return v.Leave(n)
- }
- // SetStmt is the statement to set variables.
- type SetStmt struct {
- stmtNode
- // Variables is the list of variable assignment.
- Variables []*VariableAssignment
- }
- // Restore implements Node interface.
- func (n *SetStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("SET ")
- for i, v := range n.Variables {
- if i != 0 {
- ctx.WritePlain(", ")
- }
- if err := v.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore SetStmt.Variables[%d]", i)
- }
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *SetStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*SetStmt)
- for i, val := range n.Variables {
- node, ok := val.Accept(v)
- if !ok {
- return n, false
- }
- n.Variables[i] = node.(*VariableAssignment)
- }
- return v.Leave(n)
- }
- // SetConfigStmt is the statement to set cluster configs.
- type SetConfigStmt struct {
- stmtNode
- Type string // TiDB, TiKV, PD
- Instance string // '127.0.0.1:3306'
- Name string // the variable name
- Value ExprNode
- }
- func (n *SetConfigStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("SET CONFIG ")
- if n.Type != "" {
- ctx.WriteKeyWord(n.Type)
- } else {
- ctx.WriteString(n.Instance)
- }
- ctx.WritePlain(" ")
- ctx.WriteKeyWord(n.Name)
- ctx.WritePlain(" = ")
- return n.Value.Restore(ctx)
- }
- func (n *SetConfigStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*SetConfigStmt)
- if node, ok := n.Value.Accept(v); !ok {
- return n, false
- } else {
- n.Value = node.(ExprNode)
- }
- return v.Leave(n)
- }
- /*
- // SetCharsetStmt is a statement to assign values to character and collation variables.
- // See https://dev.mysql.com/doc/refman/5.7/en/set-statement.html
- type SetCharsetStmt struct {
- stmtNode
- Charset string
- Collate string
- }
- // Accept implements Node Accept interface.
- func (n *SetCharsetStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*SetCharsetStmt)
- return v.Leave(n)
- }
- */
- // SetPwdStmt is a statement to assign a password to user account.
- // See https://dev.mysql.com/doc/refman/5.7/en/set-password.html
- type SetPwdStmt struct {
- stmtNode
- User *auth.UserIdentity
- Password string
- }
- // Restore implements Node interface.
- func (n *SetPwdStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("SET PASSWORD")
- if n.User != nil {
- ctx.WriteKeyWord(" FOR ")
- if err := n.User.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore SetPwdStmt.User")
- }
- }
- ctx.WritePlain("=")
- ctx.WriteString(n.Password)
- return nil
- }
- // SecureText implements SensitiveStatement interface.
- func (n *SetPwdStmt) SecureText() string {
- return fmt.Sprintf("set password for user %s", n.User)
- }
- // Accept implements Node Accept interface.
- func (n *SetPwdStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*SetPwdStmt)
- return v.Leave(n)
- }
- type ChangeStmt struct {
- stmtNode
- NodeType string
- State string
- NodeID string
- }
- // Restore implements Node interface.
- func (n *ChangeStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("CHANGE ")
- ctx.WriteKeyWord(n.NodeType)
- ctx.WriteKeyWord(" TO NODE_STATE ")
- ctx.WritePlain("=")
- ctx.WriteString(n.State)
- ctx.WriteKeyWord(" FOR NODE_ID ")
- ctx.WriteString(n.NodeID)
- return nil
- }
- // SecureText implements SensitiveStatement interface.
- func (n *ChangeStmt) SecureText() string {
- return fmt.Sprintf("change %s to node_state='%s' for node_id '%s'", strings.ToLower(n.NodeType), n.State, n.NodeID)
- }
- // Accept implements Node Accept interface.
- func (n *ChangeStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*ChangeStmt)
- return v.Leave(n)
- }
- // SetRoleStmtType is the type for FLUSH statement.
- type SetRoleStmtType int
- // SetRole statement types.
- const (
- SetRoleDefault SetRoleStmtType = iota
- SetRoleNone
- SetRoleAll
- SetRoleAllExcept
- SetRoleRegular
- )
- type SetRoleStmt struct {
- stmtNode
- SetRoleOpt SetRoleStmtType
- RoleList []*auth.RoleIdentity
- }
- func (n *SetRoleStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("SET ROLE")
- switch n.SetRoleOpt {
- case SetRoleDefault:
- ctx.WriteKeyWord(" DEFAULT")
- case SetRoleNone:
- ctx.WriteKeyWord(" NONE")
- case SetRoleAll:
- ctx.WriteKeyWord(" ALL")
- case SetRoleAllExcept:
- ctx.WriteKeyWord(" ALL EXCEPT")
- }
- for i, role := range n.RoleList {
- ctx.WritePlain(" ")
- err := role.Restore(ctx)
- if err != nil {
- return errors.Annotate(err, "An error occurred while restore SetRoleStmt.RoleList")
- }
- if i != len(n.RoleList)-1 {
- ctx.WritePlain(",")
- }
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *SetRoleStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*SetRoleStmt)
- return v.Leave(n)
- }
- type SetDefaultRoleStmt struct {
- stmtNode
- SetRoleOpt SetRoleStmtType
- RoleList []*auth.RoleIdentity
- UserList []*auth.UserIdentity
- }
- func (n *SetDefaultRoleStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("SET DEFAULT ROLE")
- switch n.SetRoleOpt {
- case SetRoleNone:
- ctx.WriteKeyWord(" NONE")
- case SetRoleAll:
- ctx.WriteKeyWord(" ALL")
- default:
- }
- for i, role := range n.RoleList {
- ctx.WritePlain(" ")
- err := role.Restore(ctx)
- if err != nil {
- return errors.Annotate(err, "An error occurred while restore SetDefaultRoleStmt.RoleList")
- }
- if i != len(n.RoleList)-1 {
- ctx.WritePlain(",")
- }
- }
- ctx.WritePlain(" TO")
- for i, user := range n.UserList {
- ctx.WritePlain(" ")
- err := user.Restore(ctx)
- if err != nil {
- return errors.Annotate(err, "An error occurred while restore SetDefaultRoleStmt.UserList")
- }
- if i != len(n.UserList)-1 {
- ctx.WritePlain(",")
- }
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *SetDefaultRoleStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*SetDefaultRoleStmt)
- return v.Leave(n)
- }
- // UserSpec is used for parsing create user statement.
- type UserSpec struct {
- User *auth.UserIdentity
- AuthOpt *AuthOption
- IsRole bool
- }
- // Restore implements Node interface.
- func (n *UserSpec) Restore(ctx *format.RestoreCtx) error {
- if err := n.User.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore UserSpec.User")
- }
- if n.AuthOpt != nil {
- ctx.WritePlain(" ")
- if err := n.AuthOpt.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore UserSpec.AuthOpt")
- }
- }
- return nil
- }
- // SecurityString formats the UserSpec without password information.
- func (n *UserSpec) SecurityString() string {
- withPassword := false
- if opt := n.AuthOpt; opt != nil {
- if len(opt.AuthString) > 0 || len(opt.HashString) > 0 {
- withPassword = true
- }
- }
- if withPassword {
- return fmt.Sprintf("{%s password = ***}", n.User)
- }
- return n.User.String()
- }
- // EncodedPassword returns the encoded password (which is the real data mysql.user).
- // The boolean value indicates input's password format is legal or not.
- func (n *UserSpec) EncodedPassword() (string, bool) {
- if n.AuthOpt == nil {
- return "", true
- }
- opt := n.AuthOpt
- if opt.ByAuthString {
- return auth.EncodePassword(opt.AuthString), true
- }
- // Not a legal password string.
- if len(opt.HashString) != 41 || !strings.HasPrefix(opt.HashString, "*") {
- return "", false
- }
- return opt.HashString, true
- }
- const (
- TslNone = iota
- Ssl
- X509
- Cipher
- Issuer
- Subject
- SAN
- )
- type TLSOption struct {
- Type int
- Value string
- }
- func (t *TLSOption) Restore(ctx *format.RestoreCtx) error {
- switch t.Type {
- case TslNone:
- ctx.WriteKeyWord("NONE")
- case Ssl:
- ctx.WriteKeyWord("SSL")
- case X509:
- ctx.WriteKeyWord("X509")
- case Cipher:
- ctx.WriteKeyWord("CIPHER ")
- ctx.WriteString(t.Value)
- case Issuer:
- ctx.WriteKeyWord("ISSUER ")
- ctx.WriteString(t.Value)
- case Subject:
- ctx.WriteKeyWord("SUBJECT ")
- ctx.WriteString(t.Value)
- case SAN:
- ctx.WriteKeyWord("SAN ")
- ctx.WriteString(t.Value)
- default:
- return errors.Errorf("Unsupported TLSOption.Type %d", t.Type)
- }
- return nil
- }
- const (
- MaxQueriesPerHour = iota + 1
- MaxUpdatesPerHour
- MaxConnectionsPerHour
- MaxUserConnections
- )
- type ResourceOption struct {
- Type int
- Count int64
- }
- func (r *ResourceOption) Restore(ctx *format.RestoreCtx) error {
- switch r.Type {
- case MaxQueriesPerHour:
- ctx.WriteKeyWord("MAX_QUERIES_PER_HOUR ")
- case MaxUpdatesPerHour:
- ctx.WriteKeyWord("MAX_UPDATES_PER_HOUR ")
- case MaxConnectionsPerHour:
- ctx.WriteKeyWord("MAX_CONNECTIONS_PER_HOUR ")
- case MaxUserConnections:
- ctx.WriteKeyWord("MAX_USER_CONNECTIONS ")
- default:
- return errors.Errorf("Unsupported ResourceOption.Type %d", r.Type)
- }
- ctx.WritePlainf("%d", r.Count)
- return nil
- }
- const (
- PasswordExpire = iota + 1
- PasswordExpireDefault
- PasswordExpireNever
- PasswordExpireInterval
- Lock
- Unlock
- )
- type PasswordOrLockOption struct {
- Type int
- Count int64
- }
- func (p *PasswordOrLockOption) Restore(ctx *format.RestoreCtx) error {
- switch p.Type {
- case PasswordExpire:
- ctx.WriteKeyWord("PASSWORD EXPIRE")
- case PasswordExpireDefault:
- ctx.WriteKeyWord("PASSWORD EXPIRE DEFAULT")
- case PasswordExpireNever:
- ctx.WriteKeyWord("PASSWORD EXPIRE NEVER")
- case PasswordExpireInterval:
- ctx.WriteKeyWord("PASSWORD EXPIRE INTERVAL")
- ctx.WritePlainf(" %d", p.Count)
- ctx.WriteKeyWord(" DAY")
- case Lock:
- ctx.WriteKeyWord("ACCOUNT LOCK")
- case Unlock:
- ctx.WriteKeyWord("ACCOUNT UNLOCK")
- default:
- return errors.Errorf("Unsupported PasswordOrLockOption.Type %d", p.Type)
- }
- return nil
- }
- // CreateUserStmt creates user account.
- // See https://dev.mysql.com/doc/refman/5.7/en/create-user.html
- type CreateUserStmt struct {
- stmtNode
- IsCreateRole bool
- IfNotExists bool
- Specs []*UserSpec
- TLSOptions []*TLSOption
- ResourceOptions []*ResourceOption
- PasswordOrLockOptions []*PasswordOrLockOption
- }
- // Restore implements Node interface.
- func (n *CreateUserStmt) Restore(ctx *format.RestoreCtx) error {
- if n.IsCreateRole {
- ctx.WriteKeyWord("CREATE ROLE ")
- } else {
- ctx.WriteKeyWord("CREATE USER ")
- }
- if n.IfNotExists {
- ctx.WriteKeyWord("IF NOT EXISTS ")
- }
- for i, v := range n.Specs {
- if i != 0 {
- ctx.WritePlain(", ")
- }
- if err := v.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore CreateUserStmt.Specs[%d]", i)
- }
- }
- if len(n.TLSOptions) != 0 {
- ctx.WriteKeyWord(" REQUIRE ")
- }
- for i, option := range n.TLSOptions {
- if i != 0 {
- ctx.WriteKeyWord(" AND ")
- }
- if err := option.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore CreateUserStmt.TLSOptions[%d]", i)
- }
- }
- if len(n.ResourceOptions) != 0 {
- ctx.WriteKeyWord(" WITH")
- }
- for i, v := range n.ResourceOptions {
- ctx.WritePlain(" ")
- if err := v.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore CreateUserStmt.ResourceOptions[%d]", i)
- }
- }
- for i, v := range n.PasswordOrLockOptions {
- ctx.WritePlain(" ")
- if err := v.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore CreateUserStmt.PasswordOrLockOptions[%d]", i)
- }
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *CreateUserStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*CreateUserStmt)
- return v.Leave(n)
- }
- // SecureText implements SensitiveStatement interface.
- func (n *CreateUserStmt) SecureText() string {
- var buf bytes.Buffer
- buf.WriteString("create user")
- for _, user := range n.Specs {
- buf.WriteString(" ")
- buf.WriteString(user.SecurityString())
- }
- return buf.String()
- }
- // AlterUserStmt modifies user account.
- // See https://dev.mysql.com/doc/refman/5.7/en/alter-user.html
- type AlterUserStmt struct {
- stmtNode
- IfExists bool
- CurrentAuth *AuthOption
- Specs []*UserSpec
- TLSOptions []*TLSOption
- ResourceOptions []*ResourceOption
- PasswordOrLockOptions []*PasswordOrLockOption
- }
- // Restore implements Node interface.
- func (n *AlterUserStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("ALTER USER ")
- if n.IfExists {
- ctx.WriteKeyWord("IF EXISTS ")
- }
- if n.CurrentAuth != nil {
- ctx.WriteKeyWord("USER")
- ctx.WritePlain("() ")
- if err := n.CurrentAuth.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore AlterUserStmt.CurrentAuth")
- }
- }
- for i, v := range n.Specs {
- if i != 0 {
- ctx.WritePlain(", ")
- }
- if err := v.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore AlterUserStmt.Specs[%d]", i)
- }
- }
- if len(n.TLSOptions) != 0 {
- ctx.WriteKeyWord(" REQUIRE ")
- }
- for i, option := range n.TLSOptions {
- if i != 0 {
- ctx.WriteKeyWord(" AND ")
- }
- if err := option.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore AlterUserStmt.TLSOptions[%d]", i)
- }
- }
- if len(n.ResourceOptions) != 0 {
- ctx.WriteKeyWord(" WITH")
- }
- for i, v := range n.ResourceOptions {
- ctx.WritePlain(" ")
- if err := v.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore AlterUserStmt.ResourceOptions[%d]", i)
- }
- }
- for i, v := range n.PasswordOrLockOptions {
- ctx.WritePlain(" ")
- if err := v.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore AlterUserStmt.PasswordOrLockOptions[%d]", i)
- }
- }
- return nil
- }
- // SecureText implements SensitiveStatement interface.
- func (n *AlterUserStmt) SecureText() string {
- var buf bytes.Buffer
- buf.WriteString("alter user")
- for _, user := range n.Specs {
- buf.WriteString(" ")
- buf.WriteString(user.SecurityString())
- }
- return buf.String()
- }
- // Accept implements Node Accept interface.
- func (n *AlterUserStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*AlterUserStmt)
- return v.Leave(n)
- }
- // AlterInstanceStmt modifies instance.
- // See https://dev.mysql.com/doc/refman/8.0/en/alter-instance.html
- type AlterInstanceStmt struct {
- stmtNode
- ReloadTLS bool
- NoRollbackOnError bool
- }
- // Restore implements Node interface.
- func (n *AlterInstanceStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("ALTER INSTANCE")
- if n.ReloadTLS {
- ctx.WriteKeyWord(" RELOAD TLS")
- }
- if n.NoRollbackOnError {
- ctx.WriteKeyWord(" NO ROLLBACK ON ERROR")
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *AlterInstanceStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*AlterInstanceStmt)
- return v.Leave(n)
- }
- // DropUserStmt creates user account.
- // See http://dev.mysql.com/doc/refman/5.7/en/drop-user.html
- type DropUserStmt struct {
- stmtNode
- IfExists bool
- IsDropRole bool
- UserList []*auth.UserIdentity
- }
- // Restore implements Node interface.
- func (n *DropUserStmt) Restore(ctx *format.RestoreCtx) error {
- if n.IsDropRole {
- ctx.WriteKeyWord("DROP ROLE ")
- } else {
- ctx.WriteKeyWord("DROP USER ")
- }
- if n.IfExists {
- ctx.WriteKeyWord("IF EXISTS ")
- }
- for i, v := range n.UserList {
- if i != 0 {
- ctx.WritePlain(", ")
- }
- if err := v.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore DropUserStmt.UserList[%d]", i)
- }
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *DropUserStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*DropUserStmt)
- return v.Leave(n)
- }
- // CreateBindingStmt creates sql binding hint.
- type CreateBindingStmt struct {
- stmtNode
- GlobalScope bool
- OriginNode StmtNode
- HintedNode StmtNode
- }
- func (n *CreateBindingStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("CREATE ")
- if n.GlobalScope {
- ctx.WriteKeyWord("GLOBAL ")
- } else {
- ctx.WriteKeyWord("SESSION ")
- }
- ctx.WriteKeyWord("BINDING FOR ")
- if err := n.OriginNode.Restore(ctx); err != nil {
- return errors.Trace(err)
- }
- ctx.WriteKeyWord(" USING ")
- if err := n.HintedNode.Restore(ctx); err != nil {
- return errors.Trace(err)
- }
- return nil
- }
- func (n *CreateBindingStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*CreateBindingStmt)
- origNode, ok := n.OriginNode.Accept(v)
- if !ok {
- return n, false
- }
- n.OriginNode = origNode.(StmtNode)
- hintedNode, ok := n.HintedNode.Accept(v)
- if !ok {
- return n, false
- }
- n.HintedNode = hintedNode.(StmtNode)
- return v.Leave(n)
- }
- // DropBindingStmt deletes sql binding hint.
- type DropBindingStmt struct {
- stmtNode
- GlobalScope bool
- OriginNode StmtNode
- HintedNode StmtNode
- }
- func (n *DropBindingStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("DROP ")
- if n.GlobalScope {
- ctx.WriteKeyWord("GLOBAL ")
- } else {
- ctx.WriteKeyWord("SESSION ")
- }
- ctx.WriteKeyWord("BINDING FOR ")
- if err := n.OriginNode.Restore(ctx); err != nil {
- return errors.Trace(err)
- }
- if n.HintedNode != nil {
- ctx.WriteKeyWord(" USING ")
- if err := n.HintedNode.Restore(ctx); err != nil {
- return errors.Trace(err)
- }
- }
- return nil
- }
- func (n *DropBindingStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*DropBindingStmt)
- origNode, ok := n.OriginNode.Accept(v)
- if !ok {
- return n, false
- }
- n.OriginNode = origNode.(StmtNode)
- if n.HintedNode != nil {
- hintedNode, ok := n.HintedNode.Accept(v)
- if !ok {
- return n, false
- }
- n.HintedNode = hintedNode.(StmtNode)
- }
- return v.Leave(n)
- }
- // Extended statistics types.
- const (
- StatsTypeCardinality uint8 = iota
- StatsTypeDependency
- StatsTypeCorrelation
- )
- // StatisticsSpec is the specification for ADD /DROP STATISTICS.
- type StatisticsSpec struct {
- StatsName string
- StatsType uint8
- Columns []*ColumnName
- }
- // CreateStatisticsStmt is a statement to create extended statistics.
- // Examples:
- // CREATE STATISTICS stats1 (cardinality) ON t(a, b, c);
- // CREATE STATISTICS stats2 (dependency) ON t(a, b);
- // CREATE STATISTICS stats3 (correlation) ON t(a, b);
- type CreateStatisticsStmt struct {
- stmtNode
- IfNotExists bool
- StatsName string
- StatsType uint8
- Table *TableName
- Columns []*ColumnName
- }
- // Restore implements Node interface.
- func (n *CreateStatisticsStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("CREATE STATISTICS ")
- if n.IfNotExists {
- ctx.WriteKeyWord("IF NOT EXISTS ")
- }
- ctx.WriteName(n.StatsName)
- switch n.StatsType {
- case StatsTypeCardinality:
- ctx.WriteKeyWord(" (cardinality) ")
- case StatsTypeDependency:
- ctx.WriteKeyWord(" (dependency) ")
- case StatsTypeCorrelation:
- ctx.WriteKeyWord(" (correlation) ")
- }
- ctx.WriteKeyWord("ON ")
- if err := n.Table.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore CreateStatisticsStmt.Table")
- }
- ctx.WritePlain("(")
- for i, col := range n.Columns {
- if i != 0 {
- ctx.WritePlain(", ")
- }
- if err := col.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore CreateStatisticsStmt.Columns: [%v]", i)
- }
- }
- ctx.WritePlain(")")
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *CreateStatisticsStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*CreateStatisticsStmt)
- node, ok := n.Table.Accept(v)
- if !ok {
- return n, false
- }
- n.Table = node.(*TableName)
- for i, col := range n.Columns {
- node, ok = col.Accept(v)
- if !ok {
- return n, false
- }
- n.Columns[i] = node.(*ColumnName)
- }
- return v.Leave(n)
- }
- // DropStatisticsStmt is a statement to drop extended statistics.
- // Examples:
- // DROP STATISTICS stats1;
- type DropStatisticsStmt struct {
- stmtNode
- StatsName string
- }
- // Restore implements Node interface.
- func (n *DropStatisticsStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("DROP STATISTICS ")
- ctx.WriteName(n.StatsName)
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *DropStatisticsStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*DropStatisticsStmt)
- return v.Leave(n)
- }
- // DoStmt is the struct for DO statement.
- type DoStmt struct {
- stmtNode
- Exprs []ExprNode
- }
- // Restore implements Node interface.
- func (n *DoStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("DO ")
- for i, v := range n.Exprs {
- if i != 0 {
- ctx.WritePlain(", ")
- }
- if err := v.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore DoStmt.Exprs[%d]", i)
- }
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *DoStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*DoStmt)
- for i, val := range n.Exprs {
- node, ok := val.Accept(v)
- if !ok {
- return n, false
- }
- n.Exprs[i] = node.(ExprNode)
- }
- return v.Leave(n)
- }
- // AdminStmtType is the type for admin statement.
- type AdminStmtType int
- // Admin statement types.
- const (
- AdminShowDDL = iota + 1
- AdminCheckTable
- AdminShowDDLJobs
- AdminCancelDDLJobs
- AdminCheckIndex
- AdminRecoverIndex
- AdminCleanupIndex
- AdminCheckIndexRange
- AdminShowDDLJobQueries
- AdminChecksumTable
- AdminShowSlow
- AdminShowNextRowID
- AdminReloadExprPushdownBlacklist
- AdminReloadOptRuleBlacklist
- AdminPluginDisable
- AdminPluginEnable
- AdminFlushBindings
- AdminCaptureBindings
- AdminEvolveBindings
- AdminReloadBindings
- AdminShowTelemetry
- AdminResetTelemetryID
- AdminReloadStatistics
- )
- // HandleRange represents a range where handle value >= Begin and < End.
- type HandleRange struct {
- Begin int64
- End int64
- }
- // ShowSlowType defines the type for SlowSlow statement.
- type ShowSlowType int
- const (
- // ShowSlowTop is a ShowSlowType constant.
- ShowSlowTop ShowSlowType = iota
- // ShowSlowRecent is a ShowSlowType constant.
- ShowSlowRecent
- )
- // ShowSlowKind defines the kind for SlowSlow statement when the type is ShowSlowTop.
- type ShowSlowKind int
- const (
- // ShowSlowKindDefault is a ShowSlowKind constant.
- ShowSlowKindDefault ShowSlowKind = iota
- // ShowSlowKindInternal is a ShowSlowKind constant.
- ShowSlowKindInternal
- // ShowSlowKindAll is a ShowSlowKind constant.
- ShowSlowKindAll
- )
- // ShowSlow is used for the following command:
- // admin show slow top [ internal | all] N
- // admin show slow recent N
- type ShowSlow struct {
- Tp ShowSlowType
- Count uint64
- Kind ShowSlowKind
- }
- // Restore implements Node interface.
- func (n *ShowSlow) Restore(ctx *format.RestoreCtx) error {
- switch n.Tp {
- case ShowSlowRecent:
- ctx.WriteKeyWord("RECENT ")
- case ShowSlowTop:
- ctx.WriteKeyWord("TOP ")
- switch n.Kind {
- case ShowSlowKindDefault:
- // do nothing
- case ShowSlowKindInternal:
- ctx.WriteKeyWord("INTERNAL ")
- case ShowSlowKindAll:
- ctx.WriteKeyWord("ALL ")
- default:
- return errors.New("Unsupported kind of ShowSlowTop")
- }
- default:
- return errors.New("Unsupported type of ShowSlow")
- }
- ctx.WritePlainf("%d", n.Count)
- return nil
- }
- // AdminStmt is the struct for Admin statement.
- type AdminStmt struct {
- stmtNode
- Tp AdminStmtType
- Index string
- Tables []*TableName
- JobIDs []int64
- JobNumber int64
- HandleRanges []HandleRange
- ShowSlow *ShowSlow
- Plugins []string
- Where ExprNode
- }
- // Restore implements Node interface.
- func (n *AdminStmt) Restore(ctx *format.RestoreCtx) error {
- restoreTables := func() error {
- for i, v := range n.Tables {
- if i != 0 {
- ctx.WritePlain(", ")
- }
- if err := v.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore AdminStmt.Tables[%d]", i)
- }
- }
- return nil
- }
- restoreJobIDs := func() {
- for i, v := range n.JobIDs {
- if i != 0 {
- ctx.WritePlain(", ")
- }
- ctx.WritePlainf("%d", v)
- }
- }
- ctx.WriteKeyWord("ADMIN ")
- switch n.Tp {
- case AdminShowDDL:
- ctx.WriteKeyWord("SHOW DDL")
- case AdminShowDDLJobs:
- ctx.WriteKeyWord("SHOW DDL JOBS")
- if n.JobNumber != 0 {
- ctx.WritePlainf(" %d", n.JobNumber)
- }
- if n.Where != nil {
- ctx.WriteKeyWord(" WHERE ")
- if err := n.Where.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore ShowStmt.Where")
- }
- }
- case AdminShowNextRowID:
- ctx.WriteKeyWord("SHOW ")
- if err := restoreTables(); err != nil {
- return err
- }
- ctx.WriteKeyWord(" NEXT_ROW_ID")
- case AdminCheckTable:
- ctx.WriteKeyWord("CHECK TABLE ")
- if err := restoreTables(); err != nil {
- return err
- }
- case AdminCheckIndex:
- ctx.WriteKeyWord("CHECK INDEX ")
- if err := restoreTables(); err != nil {
- return err
- }
- ctx.WritePlainf(" %s", n.Index)
- case AdminRecoverIndex:
- ctx.WriteKeyWord("RECOVER INDEX ")
- if err := restoreTables(); err != nil {
- return err
- }
- ctx.WritePlainf(" %s", n.Index)
- case AdminCleanupIndex:
- ctx.WriteKeyWord("CLEANUP INDEX ")
- if err := restoreTables(); err != nil {
- return err
- }
- ctx.WritePlainf(" %s", n.Index)
- case AdminCheckIndexRange:
- ctx.WriteKeyWord("CHECK INDEX ")
- if err := restoreTables(); err != nil {
- return err
- }
- ctx.WritePlainf(" %s", n.Index)
- if n.HandleRanges != nil {
- ctx.WritePlain(" ")
- for i, v := range n.HandleRanges {
- if i != 0 {
- ctx.WritePlain(", ")
- }
- ctx.WritePlainf("(%d,%d)", v.Begin, v.End)
- }
- }
- case AdminChecksumTable:
- ctx.WriteKeyWord("CHECKSUM TABLE ")
- if err := restoreTables(); err != nil {
- return err
- }
- case AdminCancelDDLJobs:
- ctx.WriteKeyWord("CANCEL DDL JOBS ")
- restoreJobIDs()
- case AdminShowDDLJobQueries:
- ctx.WriteKeyWord("SHOW DDL JOB QUERIES ")
- restoreJobIDs()
- case AdminShowSlow:
- ctx.WriteKeyWord("SHOW SLOW ")
- if err := n.ShowSlow.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore AdminStmt.ShowSlow")
- }
- case AdminReloadExprPushdownBlacklist:
- ctx.WriteKeyWord("RELOAD EXPR_PUSHDOWN_BLACKLIST")
- case AdminReloadOptRuleBlacklist:
- ctx.WriteKeyWord("RELOAD OPT_RULE_BLACKLIST")
- case AdminPluginEnable:
- ctx.WriteKeyWord("PLUGINS ENABLE")
- for i, v := range n.Plugins {
- if i == 0 {
- ctx.WritePlain(" ")
- } else {
- ctx.WritePlain(", ")
- }
- ctx.WritePlain(v)
- }
- case AdminPluginDisable:
- ctx.WriteKeyWord("PLUGINS DISABLE")
- for i, v := range n.Plugins {
- if i == 0 {
- ctx.WritePlain(" ")
- } else {
- ctx.WritePlain(", ")
- }
- ctx.WritePlain(v)
- }
- case AdminFlushBindings:
- ctx.WriteKeyWord("FLUSH BINDINGS")
- case AdminCaptureBindings:
- ctx.WriteKeyWord("CAPTURE BINDINGS")
- case AdminEvolveBindings:
- ctx.WriteKeyWord("EVOLVE BINDINGS")
- case AdminReloadBindings:
- ctx.WriteKeyWord("RELOAD BINDINGS")
- case AdminShowTelemetry:
- ctx.WriteKeyWord("SHOW TELEMETRY")
- case AdminResetTelemetryID:
- ctx.WriteKeyWord("RESET TELEMETRY_ID")
- case AdminReloadStatistics:
- ctx.WriteKeyWord("RELOAD STATS_EXTENDED")
- default:
- return errors.New("Unsupported AdminStmt type")
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *AdminStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*AdminStmt)
- for i, val := range n.Tables {
- node, ok := val.Accept(v)
- if !ok {
- return n, false
- }
- n.Tables[i] = node.(*TableName)
- }
- if n.Where != nil {
- node, ok := n.Where.Accept(v)
- if !ok {
- return n, false
- }
- n.Where = node.(ExprNode)
- }
- return v.Leave(n)
- }
- // RoleOrPriv is a temporary structure to be further processed into auth.RoleIdentity or PrivElem
- type RoleOrPriv struct {
- Symbols string // hold undecided symbols
- Node interface{} // hold auth.RoleIdentity or PrivElem that can be sure when parsing
- }
- func (n *RoleOrPriv) ToRole() (*auth.RoleIdentity, error) {
- if n.Node != nil {
- if r, ok := n.Node.(*auth.RoleIdentity); ok {
- return r, nil
- }
- return nil, errors.Errorf("can't convert to RoleIdentity, type %T", n.Node)
- }
- return &auth.RoleIdentity{Username: n.Symbols, Hostname: "%"}, nil
- }
- func (n *RoleOrPriv) ToPriv() (*PrivElem, error) {
- if n.Node != nil {
- if p, ok := n.Node.(*PrivElem); ok {
- return p, nil
- }
- return nil, errors.Errorf("can't convert to PrivElem, type %T", n.Node)
- }
- if len(n.Symbols) == 0 {
- return nil, errors.New("symbols should not be length 0")
- }
- return &PrivElem{Priv: mysql.ExtendedPriv, Name: n.Symbols}, nil
- }
- // PrivElem is the privilege type and optional column list.
- type PrivElem struct {
- node
- Priv mysql.PrivilegeType
- Cols []*ColumnName
- Name string
- }
- // Restore implements Node interface.
- func (n *PrivElem) Restore(ctx *format.RestoreCtx) error {
- if n.Priv == mysql.AllPriv {
- ctx.WriteKeyWord("ALL")
- } else if n.Priv == mysql.ExtendedPriv {
- ctx.WriteKeyWord(n.Name)
- } else {
- str, ok := mysql.Priv2Str[n.Priv]
- if ok {
- ctx.WriteKeyWord(str)
- } else {
- return errors.New("Undefined privilege type")
- }
- }
- if n.Cols != nil {
- ctx.WritePlain(" (")
- for i, v := range n.Cols {
- if i != 0 {
- ctx.WritePlain(",")
- }
- if err := v.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore PrivElem.Cols[%d]", i)
- }
- }
- ctx.WritePlain(")")
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *PrivElem) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*PrivElem)
- for i, val := range n.Cols {
- node, ok := val.Accept(v)
- if !ok {
- return n, false
- }
- n.Cols[i] = node.(*ColumnName)
- }
- return v.Leave(n)
- }
- // ObjectTypeType is the type for object type.
- type ObjectTypeType int
- const (
- // ObjectTypeNone is for empty object type.
- ObjectTypeNone ObjectTypeType = iota + 1
- // ObjectTypeTable means the following object is a table.
- ObjectTypeTable
- // ObjectTypeFunction means the following object is a stored function.
- ObjectTypeFunction
- // ObjectTypeProcedure means the following object is a stored procedure.
- ObjectTypeProcedure
- )
- // Restore implements Node interface.
- func (n ObjectTypeType) Restore(ctx *format.RestoreCtx) error {
- switch n {
- case ObjectTypeNone:
- // do nothing
- case ObjectTypeTable:
- ctx.WriteKeyWord("TABLE")
- case ObjectTypeFunction:
- ctx.WriteKeyWord("FUNCTION")
- case ObjectTypeProcedure:
- ctx.WriteKeyWord("PROCEDURE")
- default:
- return errors.New("Unsupported object type")
- }
- return nil
- }
- // GrantLevelType is the type for grant level.
- type GrantLevelType int
- const (
- // GrantLevelNone is the dummy const for default value.
- GrantLevelNone GrantLevelType = iota + 1
- // GrantLevelGlobal means the privileges are administrative or apply to all databases on a given server.
- GrantLevelGlobal
- // GrantLevelDB means the privileges apply to all objects in a given database.
- GrantLevelDB
- // GrantLevelTable means the privileges apply to all columns in a given table.
- GrantLevelTable
- )
- // GrantLevel is used for store the privilege scope.
- type GrantLevel struct {
- Level GrantLevelType
- DBName string
- TableName string
- }
- // Restore implements Node interface.
- func (n *GrantLevel) Restore(ctx *format.RestoreCtx) error {
- switch n.Level {
- case GrantLevelDB:
- if n.DBName == "" {
- ctx.WritePlain("*")
- } else {
- ctx.WriteName(n.DBName)
- ctx.WritePlain(".*")
- }
- case GrantLevelGlobal:
- ctx.WritePlain("*.*")
- case GrantLevelTable:
- if n.DBName != "" {
- ctx.WriteName(n.DBName)
- ctx.WritePlain(".")
- }
- ctx.WriteName(n.TableName)
- }
- return nil
- }
- // RevokeStmt is the struct for REVOKE statement.
- type RevokeStmt struct {
- stmtNode
- Privs []*PrivElem
- ObjectType ObjectTypeType
- Level *GrantLevel
- Users []*UserSpec
- }
- // Restore implements Node interface.
- func (n *RevokeStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("REVOKE ")
- for i, v := range n.Privs {
- if i != 0 {
- ctx.WritePlain(", ")
- }
- if err := v.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore RevokeStmt.Privs[%d]", i)
- }
- }
- ctx.WriteKeyWord(" ON ")
- if n.ObjectType != ObjectTypeNone {
- if err := n.ObjectType.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore RevokeStmt.ObjectType")
- }
- ctx.WritePlain(" ")
- }
- if err := n.Level.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore RevokeStmt.Level")
- }
- ctx.WriteKeyWord(" FROM ")
- for i, v := range n.Users {
- if i != 0 {
- ctx.WritePlain(", ")
- }
- if err := v.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore RevokeStmt.Users[%d]", i)
- }
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *RevokeStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*RevokeStmt)
- for i, val := range n.Privs {
- node, ok := val.Accept(v)
- if !ok {
- return n, false
- }
- n.Privs[i] = node.(*PrivElem)
- }
- return v.Leave(n)
- }
- // RevokeStmt is the struct for REVOKE statement.
- type RevokeRoleStmt struct {
- stmtNode
- Roles []*auth.RoleIdentity
- Users []*auth.UserIdentity
- }
- // Restore implements Node interface.
- func (n *RevokeRoleStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("REVOKE ")
- for i, role := range n.Roles {
- if i != 0 {
- ctx.WritePlain(", ")
- }
- if err := role.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore RevokeRoleStmt.Roles[%d]", i)
- }
- }
- ctx.WriteKeyWord(" FROM ")
- for i, v := range n.Users {
- if i != 0 {
- ctx.WritePlain(", ")
- }
- if err := v.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore RevokeRoleStmt.Users[%d]", i)
- }
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *RevokeRoleStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*RevokeRoleStmt)
- return v.Leave(n)
- }
- // GrantStmt is the struct for GRANT statement.
- type GrantStmt struct {
- stmtNode
- Privs []*PrivElem
- ObjectType ObjectTypeType
- Level *GrantLevel
- Users []*UserSpec
- TLSOptions []*TLSOption
- WithGrant bool
- }
- // Restore implements Node interface.
- func (n *GrantStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("GRANT ")
- for i, v := range n.Privs {
- if i != 0 && v.Priv != 0 {
- ctx.WritePlain(", ")
- } else if v.Priv == 0 {
- ctx.WritePlain(" ")
- }
- if err := v.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore GrantStmt.Privs[%d]", i)
- }
- }
- ctx.WriteKeyWord(" ON ")
- if n.ObjectType != ObjectTypeNone {
- if err := n.ObjectType.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore GrantStmt.ObjectType")
- }
- ctx.WritePlain(" ")
- }
- if err := n.Level.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore GrantStmt.Level")
- }
- ctx.WriteKeyWord(" TO ")
- for i, v := range n.Users {
- if i != 0 {
- ctx.WritePlain(", ")
- }
- if err := v.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore GrantStmt.Users[%d]", i)
- }
- }
- if n.TLSOptions != nil {
- if len(n.TLSOptions) != 0 {
- ctx.WriteKeyWord(" REQUIRE ")
- }
- for i, option := range n.TLSOptions {
- if i != 0 {
- ctx.WriteKeyWord(" AND ")
- }
- if err := option.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore GrantStmt.TLSOptions[%d]", i)
- }
- }
- }
- if n.WithGrant {
- ctx.WriteKeyWord(" WITH GRANT OPTION")
- }
- return nil
- }
- // SecureText implements SensitiveStatement interface.
- func (n *GrantStmt) SecureText() string {
- text := n.text
- // Filter "identified by xxx" because it would expose password information.
- idx := strings.Index(strings.ToLower(text), "identified")
- if idx > 0 {
- text = text[:idx]
- }
- return text
- }
- // Accept implements Node Accept interface.
- func (n *GrantStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*GrantStmt)
- for i, val := range n.Privs {
- node, ok := val.Accept(v)
- if !ok {
- return n, false
- }
- n.Privs[i] = node.(*PrivElem)
- }
- return v.Leave(n)
- }
- // GrantProxyStmt is the struct for GRANT PROXY statement.
- type GrantProxyStmt struct {
- stmtNode
- LocalUser *auth.UserIdentity
- ExternalUsers []*auth.UserIdentity
- WithGrant bool
- }
- // Accept implements Node Accept interface.
- func (n *GrantProxyStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*GrantProxyStmt)
- return v.Leave(n)
- }
- // Restore implements Node interface.
- func (n *GrantProxyStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("GRANT PROXY ON ")
- if err := n.LocalUser.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore GrantProxyStmt.LocalUser")
- }
- ctx.WriteKeyWord(" TO ")
- for i, v := range n.ExternalUsers {
- if i != 0 {
- ctx.WritePlain(", ")
- }
- if err := v.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore GrantProxyStmt.ExternalUsers[%d]", i)
- }
- }
- if n.WithGrant {
- ctx.WriteKeyWord(" WITH GRANT OPTION")
- }
- return nil
- }
- // GrantRoleStmt is the struct for GRANT TO statement.
- type GrantRoleStmt struct {
- stmtNode
- Roles []*auth.RoleIdentity
- Users []*auth.UserIdentity
- }
- // Accept implements Node Accept interface.
- func (n *GrantRoleStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*GrantRoleStmt)
- return v.Leave(n)
- }
- // Restore implements Node interface.
- func (n *GrantRoleStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("GRANT ")
- if len(n.Roles) > 0 {
- for i, role := range n.Roles {
- if i != 0 {
- ctx.WritePlain(", ")
- }
- if err := role.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore GrantRoleStmt.Roles[%d]", i)
- }
- }
- }
- ctx.WriteKeyWord(" TO ")
- for i, v := range n.Users {
- if i != 0 {
- ctx.WritePlain(", ")
- }
- if err := v.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore GrantStmt.Users[%d]", i)
- }
- }
- return nil
- }
- // SecureText implements SensitiveStatement interface.
- func (n *GrantRoleStmt) SecureText() string {
- text := n.text
- // Filter "identified by xxx" because it would expose password information.
- idx := strings.Index(strings.ToLower(text), "identified")
- if idx > 0 {
- text = text[:idx]
- }
- return text
- }
- // ShutdownStmt is a statement to stop the TiDB server.
- // See https://dev.mysql.com/doc/refman/5.7/en/shutdown.html
- type ShutdownStmt struct {
- stmtNode
- }
- // Restore implements Node interface.
- func (n *ShutdownStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("SHUTDOWN")
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *ShutdownStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*ShutdownStmt)
- return v.Leave(n)
- }
- // RenameUserStmt is a statement to rename a user.
- // See http://dev.mysql.com/doc/refman/5.7/en/rename-user.html
- type RenameUserStmt struct {
- stmtNode
- UserToUsers []*UserToUser
- }
- // Restore implements Node interface.
- func (n *RenameUserStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("RENAME USER ")
- for index, user2user := range n.UserToUsers {
- if index != 0 {
- ctx.WritePlain(", ")
- }
- if err := user2user.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore RenameUserStmt.UserToUsers")
- }
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *RenameUserStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*RenameUserStmt)
- for i, t := range n.UserToUsers {
- node, ok := t.Accept(v)
- if !ok {
- return n, false
- }
- n.UserToUsers[i] = node.(*UserToUser)
- }
- return v.Leave(n)
- }
- // UserToUser represents renaming old user to new user used in RenameUserStmt.
- type UserToUser struct {
- node
- OldUser *auth.UserIdentity
- NewUser *auth.UserIdentity
- }
- // Restore implements Node interface.
- func (n *UserToUser) Restore(ctx *format.RestoreCtx) error {
- if err := n.OldUser.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore UserToUser.OldUser")
- }
- ctx.WriteKeyWord(" TO ")
- if err := n.NewUser.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore UserToUser.NewUser")
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *UserToUser) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*UserToUser)
- return v.Leave(n)
- }
- type BRIEKind uint8
- type BRIEOptionType uint16
- const (
- BRIEKindBackup BRIEKind = iota
- BRIEKindRestore
- // common BRIE options
- BRIEOptionRateLimit BRIEOptionType = iota + 1
- BRIEOptionConcurrency
- BRIEOptionChecksum
- BRIEOptionSendCreds
- BRIEOptionCheckpoint
- // backup options
- BRIEOptionBackupTimeAgo
- BRIEOptionBackupTS
- BRIEOptionBackupTSO
- BRIEOptionLastBackupTS
- BRIEOptionLastBackupTSO
- // restore options
- BRIEOptionOnline
- // import options
- BRIEOptionAnalyze
- BRIEOptionBackend
- BRIEOptionOnDuplicate
- BRIEOptionSkipSchemaFiles
- BRIEOptionStrictFormat
- BRIEOptionTiKVImporter
- BRIEOptionResume
- // CSV options
- BRIEOptionCSVBackslashEscape
- BRIEOptionCSVDelimiter
- BRIEOptionCSVHeader
- BRIEOptionCSVNotNull
- BRIEOptionCSVNull
- BRIEOptionCSVSeparator
- BRIEOptionCSVTrimLastSeparators
- BRIECSVHeaderIsColumns = ^uint64(0)
- )
- type BRIEOptionLevel uint64
- const (
- BRIEOptionLevelOff BRIEOptionLevel = iota // equals FALSE
- BRIEOptionLevelRequired // equals TRUE
- BRIEOptionLevelOptional
- )
- func (kind BRIEKind) String() string {
- switch kind {
- case BRIEKindBackup:
- return "BACKUP"
- case BRIEKindRestore:
- return "RESTORE"
- default:
- return ""
- }
- }
- func (kind BRIEOptionType) String() string {
- switch kind {
- case BRIEOptionRateLimit:
- return "RATE_LIMIT"
- case BRIEOptionConcurrency:
- return "CONCURRENCY"
- case BRIEOptionChecksum:
- return "CHECKSUM"
- case BRIEOptionSendCreds:
- return "SEND_CREDENTIALS_TO_TIKV"
- case BRIEOptionBackupTimeAgo, BRIEOptionBackupTS, BRIEOptionBackupTSO:
- return "SNAPSHOT"
- case BRIEOptionLastBackupTS, BRIEOptionLastBackupTSO:
- return "LAST_BACKUP"
- case BRIEOptionOnline:
- return "ONLINE"
- case BRIEOptionCheckpoint:
- return "CHECKPOINT"
- case BRIEOptionAnalyze:
- return "ANALYZE"
- case BRIEOptionBackend:
- return "BACKEND"
- case BRIEOptionOnDuplicate:
- return "ON_DUPLICATE"
- case BRIEOptionSkipSchemaFiles:
- return "SKIP_SCHEMA_FILES"
- case BRIEOptionStrictFormat:
- return "STRICT_FORMAT"
- case BRIEOptionTiKVImporter:
- return "TIKV_IMPORTER"
- case BRIEOptionResume:
- return "RESUME"
- case BRIEOptionCSVBackslashEscape:
- return "CSV_BACKSLASH_ESCAPE"
- case BRIEOptionCSVDelimiter:
- return "CSV_DELIMITER"
- case BRIEOptionCSVHeader:
- return "CSV_HEADER"
- case BRIEOptionCSVNotNull:
- return "CSV_NOT_NULL"
- case BRIEOptionCSVNull:
- return "CSV_NULL"
- case BRIEOptionCSVSeparator:
- return "CSV_SEPARATOR"
- case BRIEOptionCSVTrimLastSeparators:
- return "CSV_TRIM_LAST_SEPARATORS"
- default:
- return ""
- }
- }
- func (level BRIEOptionLevel) String() string {
- switch level {
- case BRIEOptionLevelOff:
- return "OFF"
- case BRIEOptionLevelOptional:
- return "OPTIONAL"
- case BRIEOptionLevelRequired:
- return "REQUIRED"
- default:
- return ""
- }
- }
- type BRIEOption struct {
- Tp BRIEOptionType
- StrValue string
- UintValue uint64
- }
- func (opt *BRIEOption) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord(opt.Tp.String())
- ctx.WritePlain(" = ")
- switch opt.Tp {
- case BRIEOptionBackupTS, BRIEOptionLastBackupTS, BRIEOptionBackend, BRIEOptionOnDuplicate, BRIEOptionTiKVImporter, BRIEOptionCSVDelimiter, BRIEOptionCSVNull, BRIEOptionCSVSeparator:
- ctx.WriteString(opt.StrValue)
- case BRIEOptionBackupTimeAgo:
- ctx.WritePlainf("%d ", opt.UintValue/1000)
- ctx.WriteKeyWord("MICROSECOND AGO")
- case BRIEOptionRateLimit:
- ctx.WritePlainf("%d ", opt.UintValue/1048576)
- ctx.WriteKeyWord("MB")
- ctx.WritePlain("/")
- ctx.WriteKeyWord("SECOND")
- case BRIEOptionCSVHeader:
- if opt.UintValue == BRIECSVHeaderIsColumns {
- ctx.WriteKeyWord("COLUMNS")
- } else {
- ctx.WritePlainf("%d", opt.UintValue)
- }
- case BRIEOptionChecksum, BRIEOptionAnalyze:
- // BACKUP/RESTORE doesn't support OPTIONAL value for now, should warn at executor
- ctx.WriteKeyWord(BRIEOptionLevel(opt.UintValue).String())
- default:
- ctx.WritePlainf("%d", opt.UintValue)
- }
- return nil
- }
- // BRIEStmt is a statement for backup, restore, import and export.
- type BRIEStmt struct {
- stmtNode
- Kind BRIEKind
- Schemas []string
- Tables []*TableName
- Storage string
- Options []*BRIEOption
- }
- func (n *BRIEStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*BRIEStmt)
- for i, val := range n.Tables {
- node, ok := val.Accept(v)
- if !ok {
- return n, false
- }
- n.Tables[i] = node.(*TableName)
- }
- return v.Leave(n)
- }
- func (n *BRIEStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord(n.Kind.String())
- switch {
- case len(n.Tables) != 0:
- ctx.WriteKeyWord(" TABLE ")
- for index, table := range n.Tables {
- if index != 0 {
- ctx.WritePlain(", ")
- }
- if err := table.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore BRIEStmt.Tables[%d]", index)
- }
- }
- case len(n.Schemas) != 0:
- ctx.WriteKeyWord(" DATABASE ")
- for index, schema := range n.Schemas {
- if index != 0 {
- ctx.WritePlain(", ")
- }
- ctx.WriteName(schema)
- }
- default:
- ctx.WriteKeyWord(" DATABASE")
- ctx.WritePlain(" *")
- }
- switch n.Kind {
- case BRIEKindBackup:
- ctx.WriteKeyWord(" TO ")
- case BRIEKindRestore:
- ctx.WriteKeyWord(" FROM ")
- }
- ctx.WriteString(n.Storage)
- for _, opt := range n.Options {
- ctx.WritePlain(" ")
- if err := opt.Restore(ctx); err != nil {
- return err
- }
- }
- return nil
- }
- // SecureText implements SensitiveStmtNode
- func (n *BRIEStmt) SecureText() string {
- // FIXME: this solution is not scalable, and duplicates some logic from BR.
- redactedStorage := n.Storage
- u, err := url.Parse(n.Storage)
- if err == nil {
- if u.Scheme == "s3" {
- query := u.Query()
- for key := range query {
- switch strings.ToLower(strings.ReplaceAll(key, "_", "-")) {
- case "access-key", "secret-access-key":
- query[key] = []string{"xxxxxx"}
- }
- }
- u.RawQuery = query.Encode()
- redactedStorage = u.String()
- }
- }
- redactedStmt := &BRIEStmt{
- Kind: n.Kind,
- Schemas: n.Schemas,
- Tables: n.Tables,
- Storage: redactedStorage,
- Options: n.Options,
- }
- var sb strings.Builder
- _ = redactedStmt.Restore(format.NewRestoreCtx(format.DefaultRestoreFlags, &sb))
- return sb.String()
- }
- type PurgeImportStmt struct {
- stmtNode
- TaskID uint64
- }
- func (n *PurgeImportStmt) Accept(v Visitor) (Node, bool) {
- newNode, _ := v.Enter(n)
- n = newNode.(*PurgeImportStmt)
- return v.Leave(n)
- }
- func (n *PurgeImportStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WritePlainf("PURGE IMPORT %d", n.TaskID)
- return nil
- }
- // ErrorHandlingOption is used in async IMPORT related stmt
- type ErrorHandlingOption uint64
- const (
- ErrorHandleError ErrorHandlingOption = iota
- ErrorHandleReplace
- ErrorHandleSkipAll
- ErrorHandleSkipConstraint
- ErrorHandleSkipDuplicate
- ErrorHandleSkipStrict
- )
- func (o ErrorHandlingOption) String() string {
- switch o {
- case ErrorHandleError:
- return ""
- case ErrorHandleReplace:
- return "REPLACE"
- case ErrorHandleSkipAll:
- return "SKIP ALL"
- case ErrorHandleSkipConstraint:
- return "SKIP CONSTRAINT"
- case ErrorHandleSkipDuplicate:
- return "SKIP DUPLICATE"
- case ErrorHandleSkipStrict:
- return "SKIP STRICT"
- default:
- return ""
- }
- }
- type CreateImportStmt struct {
- stmtNode
- IfNotExists bool
- Name string
- Storage string
- ErrorHandling ErrorHandlingOption
- Options []*BRIEOption
- }
- func (n *CreateImportStmt) Accept(v Visitor) (Node, bool) {
- newNode, _ := v.Enter(n)
- n = newNode.(*CreateImportStmt)
- return v.Leave(n)
- }
- func (n *CreateImportStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("CREATE IMPORT ")
- if n.IfNotExists {
- ctx.WriteKeyWord("IF NOT EXISTS ")
- }
- ctx.WriteName(n.Name)
- ctx.WriteKeyWord(" FROM ")
- ctx.WriteString(n.Storage)
- if n.ErrorHandling != ErrorHandleError {
- ctx.WritePlain(" ")
- ctx.WriteKeyWord(n.ErrorHandling.String())
- }
- for _, opt := range n.Options {
- ctx.WritePlain(" ")
- if err := opt.Restore(ctx); err != nil {
- return err
- }
- }
- return nil
- }
- // SecureText implements SensitiveStmtNode
- func (n *CreateImportStmt) SecureText() string {
- // FIXME: this solution is not scalable, and duplicates some logic from BR.
- redactedStorage := n.Storage
- u, err := url.Parse(n.Storage)
- if err == nil {
- if u.Scheme == "s3" {
- query := u.Query()
- for key := range query {
- switch strings.ToLower(strings.ReplaceAll(key, "_", "-")) {
- case "access-key", "secret-access-key":
- query[key] = []string{"xxxxxx"}
- }
- }
- u.RawQuery = query.Encode()
- redactedStorage = u.String()
- }
- }
- redactedStmt := &CreateImportStmt{
- IfNotExists: n.IfNotExists,
- Name: n.Name,
- Storage: redactedStorage,
- ErrorHandling: n.ErrorHandling,
- Options: n.Options,
- }
- var sb strings.Builder
- _ = redactedStmt.Restore(format.NewRestoreCtx(format.DefaultRestoreFlags, &sb))
- return sb.String()
- }
- type StopImportStmt struct {
- stmtNode
- IfRunning bool
- Name string
- }
- func (n *StopImportStmt) Accept(v Visitor) (Node, bool) {
- newNode, _ := v.Enter(n)
- n = newNode.(*StopImportStmt)
- return v.Leave(n)
- }
- func (n *StopImportStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("STOP IMPORT ")
- if n.IfRunning {
- ctx.WriteKeyWord("IF RUNNING ")
- }
- ctx.WriteName(n.Name)
- return nil
- }
- type ResumeImportStmt struct {
- stmtNode
- IfNotRunning bool
- Name string
- }
- func (n *ResumeImportStmt) Accept(v Visitor) (Node, bool) {
- newNode, _ := v.Enter(n)
- n = newNode.(*ResumeImportStmt)
- return v.Leave(n)
- }
- func (n *ResumeImportStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("RESUME IMPORT ")
- if n.IfNotRunning {
- ctx.WriteKeyWord("IF NOT RUNNING ")
- }
- ctx.WriteName(n.Name)
- return nil
- }
- type ImportTruncate struct {
- IsErrorsOnly bool
- TableNames []*TableName
- }
- type AlterImportStmt struct {
- stmtNode
- Name string
- ErrorHandling ErrorHandlingOption
- Options []*BRIEOption
- Truncate *ImportTruncate
- }
- func (n *AlterImportStmt) Accept(v Visitor) (Node, bool) {
- newNode, _ := v.Enter(n)
- n = newNode.(*AlterImportStmt)
- return v.Leave(n)
- }
- func (n *AlterImportStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("ALTER IMPORT ")
- ctx.WriteName(n.Name)
- if n.ErrorHandling != ErrorHandleError {
- ctx.WritePlain(" ")
- ctx.WriteKeyWord(n.ErrorHandling.String())
- }
- for _, opt := range n.Options {
- ctx.WritePlain(" ")
- if err := opt.Restore(ctx); err != nil {
- return err
- }
- }
- if n.Truncate != nil {
- if n.Truncate.IsErrorsOnly {
- ctx.WriteKeyWord(" TRUNCATE ERRORS")
- } else {
- ctx.WriteKeyWord(" TRUNCATE ALL")
- }
- if len(n.Truncate.TableNames) != 0 {
- ctx.WriteKeyWord(" TABLE")
- }
- for i := range n.Truncate.TableNames {
- if i == 0 {
- ctx.WritePlain(" ")
- } else {
- ctx.WritePlain(", ")
- }
- if err := n.Truncate.TableNames[i].Restore(ctx); err != nil {
- return err
- }
- }
- }
- return nil
- }
- type DropImportStmt struct {
- stmtNode
- IfExists bool
- Name string
- }
- func (n *DropImportStmt) Accept(v Visitor) (Node, bool) {
- newNode, _ := v.Enter(n)
- n = newNode.(*DropImportStmt)
- return v.Leave(n)
- }
- func (n *DropImportStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("DROP IMPORT ")
- if n.IfExists {
- ctx.WriteKeyWord("IF EXISTS ")
- }
- ctx.WriteName(n.Name)
- return nil
- }
- type ShowImportStmt struct {
- stmtNode
- Name string
- ErrorsOnly bool
- TableNames []*TableName
- }
- func (n *ShowImportStmt) Accept(v Visitor) (Node, bool) {
- newNode, _ := v.Enter(n)
- n = newNode.(*ShowImportStmt)
- return v.Leave(n)
- }
- func (n *ShowImportStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("SHOW IMPORT ")
- ctx.WriteName(n.Name)
- if n.ErrorsOnly {
- ctx.WriteKeyWord(" ERRORS")
- }
- if len(n.TableNames) != 0 {
- ctx.WriteKeyWord(" TABLE")
- }
- for i := range n.TableNames {
- if i == 0 {
- ctx.WritePlain(" ")
- } else {
- ctx.WritePlain(", ")
- }
- if err := n.TableNames[i].Restore(ctx); err != nil {
- return err
- }
- }
- return nil
- }
- // Ident is the table identifier composed of schema name and table name.
- type Ident struct {
- Schema model.CIStr
- Name model.CIStr
- }
- // String implements fmt.Stringer interface.
- func (i Ident) String() string {
- if i.Schema.O == "" {
- return i.Name.O
- }
- return fmt.Sprintf("%s.%s", i.Schema, i.Name)
- }
- // SelectStmtOpts wrap around select hints and switches
- type SelectStmtOpts struct {
- Distinct bool
- SQLBigResult bool
- SQLBufferResult bool
- SQLCache bool
- SQLSmallResult bool
- CalcFoundRows bool
- StraightJoin bool
- Priority mysql.PriorityEnum
- TableHints []*TableOptimizerHint
- ExplicitAll bool
- }
- // TableOptimizerHint is Table level optimizer hint
- type TableOptimizerHint struct {
- node
- // HintName is the name or alias of the table(s) which the hint will affect.
- // Table hints has no schema info
- // It allows only table name or alias (if table has an alias)
- HintName model.CIStr
- // HintData is the payload of the hint. The actual type of this field
- // is defined differently as according `HintName`. Define as following:
- //
- // Statement Execution Time Optimizer Hints
- // See https://dev.mysql.com/doc/refman/5.7/en/optimizer-hints.html#optimizer-hints-execution-time
- // - MAX_EXECUTION_TIME => uint64
- // - MEMORY_QUOTA => int64
- // - QUERY_TYPE => model.CIStr
- //
- // Time Range is used to hint the time range of inspection tables
- // e.g: select /*+ time_range('','') */ * from information_schema.inspection_result.
- // - TIME_RANGE => ast.HintTimeRange
- // - READ_FROM_STORAGE => model.CIStr
- // - USE_TOJA => bool
- // - NTH_PLAN => int64
- HintData interface{}
- // QBName is the default effective query block of this hint.
- QBName model.CIStr
- Tables []HintTable
- Indexes []model.CIStr
- }
- // HintTimeRange is the payload of `TIME_RANGE` hint
- type HintTimeRange struct {
- From string
- To string
- }
- // HintSetVar is the payload of `SET_VAR` hint
- type HintSetVar struct {
- VarName string
- Value string
- }
- // HintTable is table in the hint. It may have query block info.
- type HintTable struct {
- DBName model.CIStr
- TableName model.CIStr
- QBName model.CIStr
- PartitionList []model.CIStr
- }
- func (ht *HintTable) Restore(ctx *format.RestoreCtx) {
- if ht.DBName.L != "" {
- ctx.WriteName(ht.DBName.String())
- ctx.WriteKeyWord(".")
- }
- ctx.WriteName(ht.TableName.String())
- if ht.QBName.L != "" {
- ctx.WriteKeyWord("@")
- ctx.WriteName(ht.QBName.String())
- }
- if len(ht.PartitionList) > 0 {
- ctx.WriteKeyWord(" PARTITION")
- ctx.WritePlain("(")
- for i, p := range ht.PartitionList {
- if i > 0 {
- ctx.WritePlain(", ")
- }
- ctx.WriteName(p.String())
- }
- ctx.WritePlain(")")
- }
- }
- // Restore implements Node interface.
- func (n *TableOptimizerHint) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord(n.HintName.String())
- ctx.WritePlain("(")
- if n.QBName.L != "" {
- if n.HintName.L != "qb_name" {
- ctx.WriteKeyWord("@")
- }
- ctx.WriteName(n.QBName.String())
- }
- // Hints without args except query block.
- switch n.HintName.L {
- case "hash_agg", "stream_agg", "agg_to_cop", "read_consistent_replica", "no_index_merge", "qb_name", "ignore_plan_cache", "limit_to_cop":
- ctx.WritePlain(")")
- return nil
- }
- if n.QBName.L != "" {
- ctx.WritePlain(" ")
- }
- // Hints with args except query block.
- switch n.HintName.L {
- case "max_execution_time":
- ctx.WritePlainf("%d", n.HintData.(uint64))
- case "nth_plan":
- ctx.WritePlainf("%d", n.HintData.(int64))
- case "tidb_hj", "tidb_smj", "tidb_inlj", "hash_join", "merge_join", "inl_join", "broadcast_join", "broadcast_join_local", "inl_hash_join", "inl_merge_join":
- for i, table := range n.Tables {
- if i != 0 {
- ctx.WritePlain(", ")
- }
- table.Restore(ctx)
- }
- case "use_index", "ignore_index", "use_index_merge", "force_index":
- n.Tables[0].Restore(ctx)
- ctx.WritePlain(" ")
- for i, index := range n.Indexes {
- if i != 0 {
- ctx.WritePlain(", ")
- }
- ctx.WriteName(index.String())
- }
- case "use_toja", "use_cascades":
- if n.HintData.(bool) {
- ctx.WritePlain("TRUE")
- } else {
- ctx.WritePlain("FALSE")
- }
- case "query_type":
- ctx.WriteKeyWord(n.HintData.(model.CIStr).String())
- case "memory_quota":
- ctx.WritePlainf("%d MB", n.HintData.(int64)/1024/1024)
- case "read_from_storage":
- ctx.WriteKeyWord(n.HintData.(model.CIStr).String())
- for i, table := range n.Tables {
- if i == 0 {
- ctx.WritePlain("[")
- }
- table.Restore(ctx)
- if i == len(n.Tables)-1 {
- ctx.WritePlain("]")
- } else {
- ctx.WritePlain(", ")
- }
- }
- case "time_range":
- hintData := n.HintData.(HintTimeRange)
- ctx.WriteString(hintData.From)
- ctx.WritePlain(", ")
- ctx.WriteString(hintData.To)
- case "set_var":
- hintData := n.HintData.(HintSetVar)
- ctx.WriteString(hintData.VarName)
- ctx.WritePlain(", ")
- ctx.WriteString(hintData.Value)
- }
- ctx.WritePlain(")")
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *TableOptimizerHint) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*TableOptimizerHint)
- return v.Leave(n)
- }
- type BinaryLiteral interface {
- ToString() string
- }
- // NewDecimal creates a types.Decimal value, it's provided by parser driver.
- var NewDecimal func(string) (interface{}, error)
- // NewHexLiteral creates a types.HexLiteral value, it's provided by parser driver.
- var NewHexLiteral func(string) (interface{}, error)
- // NewBitLiteral creates a types.BitLiteral value, it's provided by parser driver.
- var NewBitLiteral func(string) (interface{}, error)
|