1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283 |
- // 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 (
- "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 (
- _ DMLNode = &DeleteStmt{}
- _ DMLNode = &InsertStmt{}
- _ DMLNode = &SetOprStmt{}
- _ DMLNode = &UpdateStmt{}
- _ DMLNode = &SelectStmt{}
- _ DMLNode = &CallStmt{}
- _ DMLNode = &ShowStmt{}
- _ DMLNode = &LoadDataStmt{}
- _ DMLNode = &SplitRegionStmt{}
- _ Node = &Assignment{}
- _ Node = &ByItem{}
- _ Node = &FieldList{}
- _ Node = &GroupByClause{}
- _ Node = &HavingClause{}
- _ Node = &Join{}
- _ Node = &Limit{}
- _ Node = &OnCondition{}
- _ Node = &OrderByClause{}
- _ Node = &SelectField{}
- _ Node = &TableName{}
- _ Node = &TableRefsClause{}
- _ Node = &TableSource{}
- _ Node = &SetOprSelectList{}
- _ Node = &WildCardField{}
- _ Node = &WindowSpec{}
- _ Node = &PartitionByClause{}
- _ Node = &FrameClause{}
- _ Node = &FrameBound{}
- )
- // JoinType is join type, including cross/left/right/full.
- type JoinType int
- const (
- // CrossJoin is cross join type.
- CrossJoin JoinType = iota + 1
- // LeftJoin is left Join type.
- LeftJoin
- // RightJoin is right Join type.
- RightJoin
- )
- // Join represents table join.
- type Join struct {
- node
- // Left table can be TableSource or JoinNode.
- Left ResultSetNode
- // Right table can be TableSource or JoinNode or nil.
- Right ResultSetNode
- // Tp represents join type.
- Tp JoinType
- // On represents join on condition.
- On *OnCondition
- // Using represents join using clause.
- Using []*ColumnName
- // NaturalJoin represents join is natural join.
- NaturalJoin bool
- // StraightJoin represents a straight join.
- StraightJoin bool
- ExplicitParens bool
- }
- // NewCrossJoin builds a cross join without `on` or `using` clause.
- // If the right child is a join tree, we need to handle it differently to make the precedence get right.
- // Here is the example: t1 join t2 join t3
- // JOIN ON t2.a = t3.a
- // t1 join / \
- // t2 t3
- // (left) (right)
- //
- // We can not build it directly to:
- // JOIN
- // / \
- // t1 JOIN ON t2.a = t3.a
- // / \
- // t2 t3
- // The precedence would be t1 join (t2 join t3 on t2.a=t3.a), not (t1 join t2) join t3 on t2.a=t3.a
- // We need to find the left-most child of the right child, and build a cross join of the left-hand side
- // of the left child(t1), and the right hand side with the original left-most child of the right child(t2).
- // JOIN t2.a = t3.a
- // / \
- // JOIN t3
- // / \
- // t1 t2
- // Besides, if the right handle side join tree's join type is right join and has explicit parentheses, we need to rewrite it to left join.
- // So t1 join t2 right join t3 would be rewrite to t1 join t3 left join t2.
- // If not, t1 join (t2 right join t3) would be (t1 join t2) right join t3. After rewrite the right join to left join.
- // We get (t1 join t3) left join t2, the semantics is correct.
- func NewCrossJoin(left, right ResultSetNode) (n *Join) {
- rj, ok := right.(*Join)
- if !ok || rj.Right == nil {
- return &Join{Left: left, Right: right, Tp: CrossJoin}
- }
- var leftMostLeafFatherOfRight = rj
- // Walk down the right hand side.
- for {
- if leftMostLeafFatherOfRight.Tp == RightJoin && leftMostLeafFatherOfRight.ExplicitParens {
- // Rewrite right join to left join.
- tmpChild := leftMostLeafFatherOfRight.Right
- leftMostLeafFatherOfRight.Right = leftMostLeafFatherOfRight.Left
- leftMostLeafFatherOfRight.Left = tmpChild
- leftMostLeafFatherOfRight.Tp = LeftJoin
- }
- leftChild := leftMostLeafFatherOfRight.Left
- if join, ok := leftChild.(*Join); ok && join.Right != nil {
- leftMostLeafFatherOfRight = join
- } else {
- break
- }
- }
- newCrossJoin := &Join{Left: left, Right: leftMostLeafFatherOfRight.Left, Tp: CrossJoin}
- leftMostLeafFatherOfRight.Left = newCrossJoin
- return rj
- }
- // Restore implements Node interface.
- func (n *Join) Restore(ctx *format.RestoreCtx) error {
- useCommaJoin := false
- _, leftIsJoin := n.Left.(*Join)
- if leftIsJoin && n.Left.(*Join).Right == nil {
- if ts, ok := n.Left.(*Join).Left.(*TableSource); ok {
- switch ts.Source.(type) {
- case *SelectStmt, *SetOprStmt:
- useCommaJoin = true
- }
- }
- }
- if leftIsJoin && !useCommaJoin {
- ctx.WritePlain("(")
- }
- if err := n.Left.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore Join.Left")
- }
- if leftIsJoin && !useCommaJoin {
- ctx.WritePlain(")")
- }
- if n.Right == nil {
- return nil
- }
- if n.NaturalJoin {
- ctx.WriteKeyWord(" NATURAL")
- }
- switch n.Tp {
- case LeftJoin:
- ctx.WriteKeyWord(" LEFT")
- case RightJoin:
- ctx.WriteKeyWord(" RIGHT")
- }
- if n.StraightJoin {
- ctx.WriteKeyWord(" STRAIGHT_JOIN ")
- } else {
- if useCommaJoin {
- ctx.WritePlain(", ")
- } else {
- ctx.WriteKeyWord(" JOIN ")
- }
- }
- _, rightIsJoin := n.Right.(*Join)
- if rightIsJoin {
- ctx.WritePlain("(")
- }
- if err := n.Right.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore Join.Right")
- }
- if rightIsJoin {
- ctx.WritePlain(")")
- }
- if n.On != nil {
- ctx.WritePlain(" ")
- if err := n.On.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore Join.On")
- }
- }
- if len(n.Using) != 0 {
- ctx.WriteKeyWord(" USING ")
- ctx.WritePlain("(")
- for i, v := range n.Using {
- if i != 0 {
- ctx.WritePlain(",")
- }
- if err := v.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore Join.Using")
- }
- }
- ctx.WritePlain(")")
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *Join) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*Join)
- node, ok := n.Left.Accept(v)
- if !ok {
- return n, false
- }
- n.Left = node.(ResultSetNode)
- if n.Right != nil {
- node, ok = n.Right.Accept(v)
- if !ok {
- return n, false
- }
- n.Right = node.(ResultSetNode)
- }
- if n.On != nil {
- node, ok = n.On.Accept(v)
- if !ok {
- return n, false
- }
- n.On = node.(*OnCondition)
- }
- return v.Leave(n)
- }
- // TableName represents a table name.
- type TableName struct {
- node
- Schema model.CIStr
- Name model.CIStr
- DBInfo *model.DBInfo
- TableInfo *model.TableInfo
- IndexHints []*IndexHint
- PartitionNames []model.CIStr
- TableSample *TableSample
- }
- // Restore implements Node interface.
- func (n *TableName) restoreName(ctx *format.RestoreCtx) {
- if n.Schema.String() != "" {
- ctx.WriteName(n.Schema.String())
- ctx.WritePlain(".")
- } else if ctx.DefaultDB != "" {
- ctx.WriteName(ctx.DefaultDB)
- ctx.WritePlain(".")
- }
- ctx.WriteName(n.Name.String())
- }
- func (n *TableName) restorePartitions(ctx *format.RestoreCtx) {
- if len(n.PartitionNames) > 0 {
- ctx.WriteKeyWord(" PARTITION")
- ctx.WritePlain("(")
- for i, v := range n.PartitionNames {
- if i != 0 {
- ctx.WritePlain(", ")
- }
- ctx.WriteName(v.String())
- }
- ctx.WritePlain(")")
- }
- }
- func (n *TableName) restoreIndexHints(ctx *format.RestoreCtx) error {
- for _, value := range n.IndexHints {
- ctx.WritePlain(" ")
- if err := value.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while splicing IndexHints")
- }
- }
- return nil
- }
- func (n *TableName) Restore(ctx *format.RestoreCtx) error {
- n.restoreName(ctx)
- n.restorePartitions(ctx)
- if err := n.restoreIndexHints(ctx); err != nil {
- return err
- }
- if n.TableSample != nil {
- ctx.WritePlain(" ")
- if err := n.TableSample.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while splicing TableName.TableSample")
- }
- }
- return nil
- }
- // IndexHintType is the type for index hint use, ignore or force.
- type IndexHintType int
- // IndexHintUseType values.
- const (
- HintUse IndexHintType = iota + 1
- HintIgnore
- HintForce
- )
- // IndexHintScope is the type for index hint for join, order by or group by.
- type IndexHintScope int
- // Index hint scopes.
- const (
- HintForScan IndexHintScope = iota + 1
- HintForJoin
- HintForOrderBy
- HintForGroupBy
- )
- // IndexHint represents a hint for optimizer to use/ignore/force for join/order by/group by.
- type IndexHint struct {
- IndexNames []model.CIStr
- HintType IndexHintType
- HintScope IndexHintScope
- }
- // IndexHint Restore (The const field uses switch to facilitate understanding)
- func (n *IndexHint) Restore(ctx *format.RestoreCtx) error {
- indexHintType := ""
- switch n.HintType {
- case HintUse:
- indexHintType = "USE INDEX"
- case HintIgnore:
- indexHintType = "IGNORE INDEX"
- case HintForce:
- indexHintType = "FORCE INDEX"
- default: // Prevent accidents
- return errors.New("IndexHintType has an error while matching")
- }
- indexHintScope := ""
- switch n.HintScope {
- case HintForScan:
- indexHintScope = ""
- case HintForJoin:
- indexHintScope = " FOR JOIN"
- case HintForOrderBy:
- indexHintScope = " FOR ORDER BY"
- case HintForGroupBy:
- indexHintScope = " FOR GROUP BY"
- default: // Prevent accidents
- return errors.New("IndexHintScope has an error while matching")
- }
- ctx.WriteKeyWord(indexHintType)
- ctx.WriteKeyWord(indexHintScope)
- ctx.WritePlain(" (")
- for i, value := range n.IndexNames {
- if i > 0 {
- ctx.WritePlain(", ")
- }
- ctx.WriteName(value.O)
- }
- ctx.WritePlain(")")
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *TableName) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*TableName)
- if n.TableSample != nil {
- newTs, ok := n.TableSample.Accept(v)
- if !ok {
- return n, false
- }
- n.TableSample = newTs.(*TableSample)
- }
- return v.Leave(n)
- }
- // DeleteTableList is the tablelist used in delete statement multi-table mode.
- type DeleteTableList struct {
- node
- Tables []*TableName
- }
- // Restore implements Node interface.
- func (n *DeleteTableList) Restore(ctx *format.RestoreCtx) error {
- for i, t := range n.Tables {
- if i != 0 {
- ctx.WritePlain(",")
- }
- if err := t.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore DeleteTableList.Tables[%v]", i)
- }
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *DeleteTableList) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*DeleteTableList)
- if n != nil {
- for i, t := range n.Tables {
- node, ok := t.Accept(v)
- if !ok {
- return n, false
- }
- n.Tables[i] = node.(*TableName)
- }
- }
- return v.Leave(n)
- }
- // OnCondition represents JOIN on condition.
- type OnCondition struct {
- node
- Expr ExprNode
- }
- // Restore implements Node interface.
- func (n *OnCondition) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("ON ")
- if err := n.Expr.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore OnCondition.Expr")
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *OnCondition) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*OnCondition)
- node, ok := n.Expr.Accept(v)
- if !ok {
- return n, false
- }
- n.Expr = node.(ExprNode)
- return v.Leave(n)
- }
- // TableSource represents table source with a name.
- type TableSource struct {
- node
- // Source is the source of the data, can be a TableName,
- // a SelectStmt, a SetOprStmt, or a JoinNode.
- Source ResultSetNode
- // AsName is the alias name of the table source.
- AsName model.CIStr
- }
- // Restore implements Node interface.
- func (n *TableSource) Restore(ctx *format.RestoreCtx) error {
- needParen := false
- switch n.Source.(type) {
- case *SelectStmt, *SetOprStmt:
- needParen = true
- }
- if tn, tnCase := n.Source.(*TableName); tnCase {
- if needParen {
- ctx.WritePlain("(")
- }
- tn.restoreName(ctx)
- tn.restorePartitions(ctx)
- if asName := n.AsName.String(); asName != "" {
- ctx.WriteKeyWord(" AS ")
- ctx.WriteName(asName)
- }
- if err := tn.restoreIndexHints(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore TableSource.Source.(*TableName).IndexHints")
- }
- if tn.TableSample != nil {
- ctx.WritePlain(" ")
- if err := tn.TableSample.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while splicing TableName.TableSample")
- }
- }
- if needParen {
- ctx.WritePlain(")")
- }
- } else {
- if needParen {
- ctx.WritePlain("(")
- }
- if err := n.Source.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore TableSource.Source")
- }
- if needParen {
- ctx.WritePlain(")")
- }
- if asName := n.AsName.String(); asName != "" {
- ctx.WriteKeyWord(" AS ")
- ctx.WriteName(asName)
- }
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *TableSource) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*TableSource)
- node, ok := n.Source.Accept(v)
- if !ok {
- return n, false
- }
- n.Source = node.(ResultSetNode)
- return v.Leave(n)
- }
- // SelectLockType is the lock type for SelectStmt.
- type SelectLockType int
- // Select lock types.
- const (
- SelectLockNone SelectLockType = iota
- SelectLockForUpdate
- SelectLockForShare
- SelectLockForUpdateNoWait
- SelectLockForUpdateWaitN
- SelectLockForShareNoWait
- SelectLockForUpdateSkipLocked
- SelectLockForShareSkipLocked
- )
- type SelectLockInfo struct {
- LockType SelectLockType
- WaitSec uint64
- }
- // String implements fmt.Stringer.
- func (n SelectLockType) String() string {
- switch n {
- case SelectLockNone:
- return "none"
- case SelectLockForUpdate:
- return "for update"
- case SelectLockForShare:
- return "for share"
- case SelectLockForUpdateNoWait:
- return "for update nowait"
- case SelectLockForUpdateWaitN:
- return "for update wait"
- case SelectLockForShareNoWait:
- return "for share nowait"
- case SelectLockForUpdateSkipLocked:
- return "for update skip locked"
- case SelectLockForShareSkipLocked:
- return "for share skip locked"
- }
- return "unsupported select lock type"
- }
- // WildCardField is a special type of select field content.
- type WildCardField struct {
- node
- Table model.CIStr
- Schema model.CIStr
- }
- // Restore implements Node interface.
- func (n *WildCardField) Restore(ctx *format.RestoreCtx) error {
- if schema := n.Schema.String(); schema != "" {
- ctx.WriteName(schema)
- ctx.WritePlain(".")
- }
- if table := n.Table.String(); table != "" {
- ctx.WriteName(table)
- ctx.WritePlain(".")
- }
- ctx.WritePlain("*")
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *WildCardField) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*WildCardField)
- return v.Leave(n)
- }
- // SelectField represents fields in select statement.
- // There are two type of select field: wildcard
- // and expression with optional alias name.
- type SelectField struct {
- node
- // Offset is used to get original text.
- Offset int
- // WildCard is not nil, Expr will be nil.
- WildCard *WildCardField
- // Expr is not nil, WildCard will be nil.
- Expr ExprNode
- // AsName is alias name for Expr.
- AsName model.CIStr
- // Auxiliary stands for if this field is auxiliary.
- // When we add a Field into SelectField list which is used for having/orderby clause but the field is not in select clause,
- // we should set its Auxiliary to true. Then the TrimExec will trim the field.
- Auxiliary bool
- }
- // Restore implements Node interface.
- func (n *SelectField) Restore(ctx *format.RestoreCtx) error {
- if n.WildCard != nil {
- if err := n.WildCard.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore SelectField.WildCard")
- }
- }
- if n.Expr != nil {
- if err := n.Expr.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore SelectField.Expr")
- }
- }
- if asName := n.AsName.String(); asName != "" {
- ctx.WriteKeyWord(" AS ")
- ctx.WriteName(asName)
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *SelectField) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*SelectField)
- if n.Expr != nil {
- node, ok := n.Expr.Accept(v)
- if !ok {
- return n, false
- }
- n.Expr = node.(ExprNode)
- }
- return v.Leave(n)
- }
- // FieldList represents field list in select statement.
- type FieldList struct {
- node
- Fields []*SelectField
- }
- // Restore implements Node interface.
- func (n *FieldList) Restore(ctx *format.RestoreCtx) error {
- for i, v := range n.Fields {
- if i != 0 {
- ctx.WritePlain(", ")
- }
- if err := v.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore FieldList.Fields[%d]", i)
- }
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *FieldList) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*FieldList)
- for i, val := range n.Fields {
- node, ok := val.Accept(v)
- if !ok {
- return n, false
- }
- n.Fields[i] = node.(*SelectField)
- }
- return v.Leave(n)
- }
- // TableRefsClause represents table references clause in dml statement.
- type TableRefsClause struct {
- node
- TableRefs *Join
- }
- // Restore implements Node interface.
- func (n *TableRefsClause) Restore(ctx *format.RestoreCtx) error {
- if err := n.TableRefs.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore TableRefsClause.TableRefs")
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *TableRefsClause) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*TableRefsClause)
- node, ok := n.TableRefs.Accept(v)
- if !ok {
- return n, false
- }
- n.TableRefs = node.(*Join)
- return v.Leave(n)
- }
- // ByItem represents an item in order by or group by.
- type ByItem struct {
- node
- Expr ExprNode
- Desc bool
- NullOrder bool
- }
- // Restore implements Node interface.
- func (n *ByItem) Restore(ctx *format.RestoreCtx) error {
- if err := n.Expr.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore ByItem.Expr")
- }
- if n.Desc {
- ctx.WriteKeyWord(" DESC")
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *ByItem) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*ByItem)
- node, ok := n.Expr.Accept(v)
- if !ok {
- return n, false
- }
- n.Expr = node.(ExprNode)
- return v.Leave(n)
- }
- // GroupByClause represents group by clause.
- type GroupByClause struct {
- node
- Items []*ByItem
- }
- // Restore implements Node interface.
- func (n *GroupByClause) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("GROUP BY ")
- for i, v := range n.Items {
- if i != 0 {
- ctx.WritePlain(",")
- }
- if err := v.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore GroupByClause.Items[%d]", i)
- }
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *GroupByClause) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*GroupByClause)
- for i, val := range n.Items {
- node, ok := val.Accept(v)
- if !ok {
- return n, false
- }
- n.Items[i] = node.(*ByItem)
- }
- return v.Leave(n)
- }
- // HavingClause represents having clause.
- type HavingClause struct {
- node
- Expr ExprNode
- }
- // Restore implements Node interface.
- func (n *HavingClause) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("HAVING ")
- if err := n.Expr.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore HavingClause.Expr")
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *HavingClause) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*HavingClause)
- node, ok := n.Expr.Accept(v)
- if !ok {
- return n, false
- }
- n.Expr = node.(ExprNode)
- return v.Leave(n)
- }
- // OrderByClause represents order by clause.
- type OrderByClause struct {
- node
- Items []*ByItem
- ForUnion bool
- }
- // Restore implements Node interface.
- func (n *OrderByClause) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("ORDER BY ")
- for i, item := range n.Items {
- if i != 0 {
- ctx.WritePlain(",")
- }
- if err := item.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore OrderByClause.Items[%d]", i)
- }
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *OrderByClause) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*OrderByClause)
- for i, val := range n.Items {
- node, ok := val.Accept(v)
- if !ok {
- return n, false
- }
- n.Items[i] = node.(*ByItem)
- }
- return v.Leave(n)
- }
- type SampleMethodType int8
- const (
- SampleMethodTypeNone SampleMethodType = iota
- SampleMethodTypeSystem
- SampleMethodTypeBernoulli
- SampleMethodTypeTiDBRegion
- )
- type SampleClauseUnitType int8
- const (
- SampleClauseUnitTypeDefault SampleClauseUnitType = iota
- SampleClauseUnitTypeRow
- SampleClauseUnitTypePercent
- )
- type TableSample struct {
- node
- SampleMethod SampleMethodType
- Expr ExprNode
- SampleClauseUnit SampleClauseUnitType
- RepeatableSeed ExprNode
- }
- func (s *TableSample) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("TABLESAMPLE ")
- switch s.SampleMethod {
- case SampleMethodTypeBernoulli:
- ctx.WriteKeyWord("BERNOULLI ")
- case SampleMethodTypeSystem:
- ctx.WriteKeyWord("SYSTEM ")
- case SampleMethodTypeTiDBRegion:
- ctx.WriteKeyWord("REGION ")
- }
- ctx.WritePlain("(")
- if s.Expr != nil {
- if err := s.Expr.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore TableSample.Expr")
- }
- }
- switch s.SampleClauseUnit {
- case SampleClauseUnitTypeDefault:
- case SampleClauseUnitTypePercent:
- ctx.WriteKeyWord(" PERCENT")
- case SampleClauseUnitTypeRow:
- ctx.WriteKeyWord(" ROWS")
- }
- ctx.WritePlain(")")
- if s.RepeatableSeed != nil {
- ctx.WriteKeyWord(" REPEATABLE")
- ctx.WritePlain("(")
- if err := s.RepeatableSeed.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore TableSample.Expr")
- }
- ctx.WritePlain(")")
- }
- return nil
- }
- func (s *TableSample) Accept(v Visitor) (node Node, ok bool) {
- newNode, skipChildren := v.Enter(s)
- if skipChildren {
- return v.Leave(newNode)
- }
- s = newNode.(*TableSample)
- if s.Expr != nil {
- node, ok = s.Expr.Accept(v)
- if !ok {
- return s, false
- }
- s.Expr = node.(ExprNode)
- }
- if s.RepeatableSeed != nil {
- node, ok = s.RepeatableSeed.Accept(v)
- if !ok {
- return s, false
- }
- s.RepeatableSeed = node.(ExprNode)
- }
- return v.Leave(s)
- }
- type SelectStmtKind uint8
- const (
- SelectStmtKindSelect SelectStmtKind = iota
- SelectStmtKindTable
- SelectStmtKindValues
- )
- func (s *SelectStmtKind) String() string {
- switch *s {
- case SelectStmtKindSelect:
- return "SELECT"
- case SelectStmtKindTable:
- return "TABLE"
- case SelectStmtKindValues:
- return "VALUES"
- }
- return ""
- }
- type CommonTableExpression struct {
- node
- Name model.CIStr
- Query *SubqueryExpr
- ColNameList []model.CIStr
- }
- type WithClause struct {
- node
- IsRecursive bool
- CTEs []*CommonTableExpression
- }
- // SelectStmt represents the select query node.
- // See https://dev.mysql.com/doc/refman/5.7/en/select.html
- type SelectStmt struct {
- dmlNode
- // SelectStmtOpts wraps around select hints and switches.
- *SelectStmtOpts
- // Distinct represents whether the select has distinct option.
- Distinct bool
- // From is the from clause of the query.
- From *TableRefsClause
- // Where is the where clause in select statement.
- Where ExprNode
- // Fields is the select expression list.
- Fields *FieldList
- // GroupBy is the group by expression list.
- GroupBy *GroupByClause
- // Having is the having condition.
- Having *HavingClause
- // WindowSpecs is the window specification list.
- WindowSpecs []WindowSpec
- // OrderBy is the ordering expression list.
- OrderBy *OrderByClause
- // Limit is the limit clause.
- Limit *Limit
- // LockInfo is the lock type
- LockInfo *SelectLockInfo
- // TableHints represents the table level Optimizer Hint for join type
- TableHints []*TableOptimizerHint
- // IsInBraces indicates whether it's a stmt in brace.
- IsInBraces bool
- // QueryBlockOffset indicates the order of this SelectStmt if counted from left to right in the sql text.
- QueryBlockOffset int
- // SelectIntoOpt is the select-into option.
- SelectIntoOpt *SelectIntoOption
- // AfterSetOperator indicates the SelectStmt after which type of set operator
- AfterSetOperator *SetOprType
- // Kind refer to three kind of statement: SelectStmt, TableStmt and ValuesStmt
- Kind SelectStmtKind
- // Lists is filled only when Kind == SelectStmtKindValues
- Lists []*RowExpr
- With *WithClause
- }
- func (n *WithClause) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("WITH ")
- if n.IsRecursive {
- ctx.WriteKeyWord("RECURSIVE ")
- }
- for i, cte := range n.CTEs {
- if i != 0 {
- ctx.WritePlain(", ")
- }
- ctx.WriteName(cte.Name.String())
- if len(cte.ColNameList) > 0 {
- ctx.WritePlain(" (")
- for j, name := range cte.ColNameList {
- if j != 0 {
- ctx.WritePlain(", ")
- }
- ctx.WriteName(name.String())
- }
- ctx.WritePlain(")")
- }
- ctx.WriteKeyWord(" AS ")
- err := cte.Query.Restore(ctx)
- if err != nil {
- return err
- }
- }
- ctx.WritePlain(" ")
- return nil
- }
- func (n *WithClause) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- for _, cte := range n.CTEs {
- node, ok := cte.Query.Accept(v)
- if !ok {
- return n, false
- }
- cte.Query = node.(*SubqueryExpr)
- }
- return v.Leave(n)
- }
- // Restore implements Node interface.
- func (n *SelectStmt) Restore(ctx *format.RestoreCtx) error {
- if n.IsInBraces {
- ctx.WritePlain("(")
- defer func() {
- ctx.WritePlain(")")
- }()
- }
- if n.With != nil {
- err := n.With.Restore(ctx)
- if err != nil {
- return err
- }
- }
- ctx.WriteKeyWord(n.Kind.String())
- ctx.WritePlain(" ")
- switch n.Kind {
- case SelectStmtKindSelect:
- if n.SelectStmtOpts.Priority > 0 {
- ctx.WriteKeyWord(mysql.Priority2Str[n.SelectStmtOpts.Priority])
- ctx.WritePlain(" ")
- }
- if n.SelectStmtOpts.SQLSmallResult {
- ctx.WriteKeyWord("SQL_SMALL_RESULT ")
- }
- if n.SelectStmtOpts.SQLBigResult {
- ctx.WriteKeyWord("SQL_BIG_RESULT ")
- }
- if n.SelectStmtOpts.SQLBufferResult {
- ctx.WriteKeyWord("SQL_BUFFER_RESULT ")
- }
- if !n.SelectStmtOpts.SQLCache {
- ctx.WriteKeyWord("SQL_NO_CACHE ")
- }
- if n.SelectStmtOpts.CalcFoundRows {
- ctx.WriteKeyWord("SQL_CALC_FOUND_ROWS ")
- }
- if n.TableHints != nil && len(n.TableHints) != 0 {
- ctx.WritePlain("/*+ ")
- for i, tableHint := range n.TableHints {
- if i != 0 {
- ctx.WritePlain(" ")
- }
- if err := tableHint.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore SelectStmt.TableHints[%d]", i)
- }
- }
- ctx.WritePlain("*/ ")
- }
- if n.Distinct {
- ctx.WriteKeyWord("DISTINCT ")
- } else if n.SelectStmtOpts.ExplicitAll {
- ctx.WriteKeyWord("ALL ")
- }
- if n.SelectStmtOpts.StraightJoin {
- ctx.WriteKeyWord("STRAIGHT_JOIN ")
- }
- if n.Fields != nil {
- for i, field := range n.Fields.Fields {
- if i != 0 {
- ctx.WritePlain(",")
- }
- if err := field.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore SelectStmt.Fields[%d]", i)
- }
- }
- }
- if n.From != nil {
- ctx.WriteKeyWord(" FROM ")
- if err := n.From.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore SelectStmt.From")
- }
- }
- if n.From == nil && n.Where != nil {
- ctx.WriteKeyWord(" FROM DUAL")
- }
- if n.Where != nil {
- ctx.WriteKeyWord(" WHERE ")
- if err := n.Where.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore SelectStmt.Where")
- }
- }
- if n.GroupBy != nil {
- ctx.WritePlain(" ")
- if err := n.GroupBy.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore SelectStmt.GroupBy")
- }
- }
- if n.Having != nil {
- ctx.WritePlain(" ")
- if err := n.Having.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore SelectStmt.Having")
- }
- }
- if n.WindowSpecs != nil {
- ctx.WriteKeyWord(" WINDOW ")
- for i, windowsSpec := range n.WindowSpecs {
- if i != 0 {
- ctx.WritePlain(",")
- }
- if err := windowsSpec.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore SelectStmt.WindowSpec[%d]", i)
- }
- }
- }
- case SelectStmtKindTable:
- if err := n.From.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore SelectStmt.From")
- }
- case SelectStmtKindValues:
- for i, v := range n.Lists {
- if err := v.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore SelectStmt.Lists[%d]", i)
- }
- if i != len(n.Lists)-1 {
- ctx.WritePlain(", ")
- }
- }
- }
- if n.OrderBy != nil {
- ctx.WritePlain(" ")
- if err := n.OrderBy.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore SelectStmt.OrderBy")
- }
- }
- if n.Limit != nil {
- ctx.WritePlain(" ")
- if err := n.Limit.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore SelectStmt.Limit")
- }
- }
- if n.LockInfo != nil {
- ctx.WritePlain(" ")
- switch n.LockInfo.LockType {
- case SelectLockNone:
- case SelectLockForUpdateWaitN:
- ctx.WriteKeyWord(n.LockInfo.LockType.String())
- ctx.WritePlainf(" %d", n.LockInfo.WaitSec)
- default:
- ctx.WriteKeyWord(n.LockInfo.LockType.String())
- }
- }
- if n.SelectIntoOpt != nil {
- ctx.WritePlain(" ")
- if err := n.SelectIntoOpt.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore SelectStmt.SelectIntoOpt")
- }
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *SelectStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*SelectStmt)
- if n.With != nil {
- node, ok := n.With.Accept(v)
- if !ok {
- return n, false
- }
- n.With = node.(*WithClause)
- }
- if n.TableHints != nil && len(n.TableHints) != 0 {
- newHints := make([]*TableOptimizerHint, len(n.TableHints))
- for i, hint := range n.TableHints {
- node, ok := hint.Accept(v)
- if !ok {
- return n, false
- }
- newHints[i] = node.(*TableOptimizerHint)
- }
- n.TableHints = newHints
- }
- if n.Fields != nil {
- node, ok := n.Fields.Accept(v)
- if !ok {
- return n, false
- }
- n.Fields = node.(*FieldList)
- }
- if n.From != nil {
- node, ok := n.From.Accept(v)
- if !ok {
- return n, false
- }
- n.From = node.(*TableRefsClause)
- }
- if n.Where != nil {
- node, ok := n.Where.Accept(v)
- if !ok {
- return n, false
- }
- n.Where = node.(ExprNode)
- }
- if n.GroupBy != nil {
- node, ok := n.GroupBy.Accept(v)
- if !ok {
- return n, false
- }
- n.GroupBy = node.(*GroupByClause)
- }
- if n.Having != nil {
- node, ok := n.Having.Accept(v)
- if !ok {
- return n, false
- }
- n.Having = node.(*HavingClause)
- }
- for i, list := range n.Lists {
- node, ok := list.Accept(v)
- if !ok {
- return n, false
- }
- n.Lists[i] = node.(*RowExpr)
- }
- for i, spec := range n.WindowSpecs {
- node, ok := spec.Accept(v)
- if !ok {
- return n, false
- }
- n.WindowSpecs[i] = *node.(*WindowSpec)
- }
- if n.OrderBy != nil {
- node, ok := n.OrderBy.Accept(v)
- if !ok {
- return n, false
- }
- n.OrderBy = node.(*OrderByClause)
- }
- if n.Limit != nil {
- node, ok := n.Limit.Accept(v)
- if !ok {
- return n, false
- }
- n.Limit = node.(*Limit)
- }
- return v.Leave(n)
- }
- // SetOprSelectList represents the SelectStmt/TableStmt/ValuesStmt list in a union statement.
- type SetOprSelectList struct {
- node
- AfterSetOperator *SetOprType
- Selects []Node
- }
- // Restore implements Node interface.
- func (n *SetOprSelectList) Restore(ctx *format.RestoreCtx) error {
- for i, stmt := range n.Selects {
- switch selectStmt := stmt.(type) {
- case *SelectStmt:
- if i != 0 {
- ctx.WriteKeyWord(" " + selectStmt.AfterSetOperator.String() + " ")
- }
- if err := selectStmt.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore SetOprSelectList.SelectStmt")
- }
- case *SetOprSelectList:
- if i != 0 {
- ctx.WriteKeyWord(" " + selectStmt.AfterSetOperator.String() + " ")
- }
- ctx.WritePlain("(")
- err := selectStmt.Restore(ctx)
- if err != nil {
- return err
- }
- ctx.WritePlain(")")
- }
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *SetOprSelectList) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*SetOprSelectList)
- for i, sel := range n.Selects {
- node, ok := sel.Accept(v)
- if !ok {
- return n, false
- }
- n.Selects[i] = node
- }
- return v.Leave(n)
- }
- type SetOprType uint8
- const (
- Union SetOprType = iota
- UnionAll
- Except
- ExceptAll
- Intersect
- IntersectAll
- )
- func (s *SetOprType) String() string {
- switch *s {
- case Union:
- return "UNION"
- case UnionAll:
- return "UNION ALL"
- case Except:
- return "EXCEPT"
- case ExceptAll:
- return "EXCEPT ALL"
- case Intersect:
- return "INTERSECT"
- case IntersectAll:
- return "INTERSECT ALL"
- }
- return ""
- }
- // SetOprStmt represents "union/except/intersect statement"
- // See https://dev.mysql.com/doc/refman/5.7/en/union.html
- // See https://mariadb.com/kb/en/intersect/
- // See https://mariadb.com/kb/en/except/
- type SetOprStmt struct {
- dmlNode
- SelectList *SetOprSelectList
- OrderBy *OrderByClause
- Limit *Limit
- With *WithClause
- }
- // Restore implements Node interface.
- func (n *SetOprStmt) Restore(ctx *format.RestoreCtx) error {
- if n.With != nil {
- if err := n.With.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore UnionStmt.With")
- }
- }
- if err := n.SelectList.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore SetOprStmt.SelectList")
- }
- if n.OrderBy != nil {
- ctx.WritePlain(" ")
- if err := n.OrderBy.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore SetOprStmt.OrderBy")
- }
- }
- if n.Limit != nil {
- ctx.WritePlain(" ")
- if err := n.Limit.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore SetOprStmt.Limit")
- }
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *SetOprStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- if n.With != nil {
- node, ok := n.With.Accept(v)
- if !ok {
- return n, false
- }
- n.With = node.(*WithClause)
- }
- if n.SelectList != nil {
- node, ok := n.SelectList.Accept(v)
- if !ok {
- return n, false
- }
- n.SelectList = node.(*SetOprSelectList)
- }
- if n.OrderBy != nil {
- node, ok := n.OrderBy.Accept(v)
- if !ok {
- return n, false
- }
- n.OrderBy = node.(*OrderByClause)
- }
- if n.Limit != nil {
- node, ok := n.Limit.Accept(v)
- if !ok {
- return n, false
- }
- n.Limit = node.(*Limit)
- }
- return v.Leave(n)
- }
- // Assignment is the expression for assignment, like a = 1.
- type Assignment struct {
- node
- // Column is the column name to be assigned.
- Column *ColumnName
- // Expr is the expression assigning to ColName.
- Expr ExprNode
- }
- // Restore implements Node interface.
- func (n *Assignment) Restore(ctx *format.RestoreCtx) error {
- if err := n.Column.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore Assignment.Column")
- }
- ctx.WritePlain("=")
- if err := n.Expr.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore Assignment.Expr")
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *Assignment) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*Assignment)
- node, ok := n.Column.Accept(v)
- if !ok {
- return n, false
- }
- n.Column = node.(*ColumnName)
- node, ok = n.Expr.Accept(v)
- if !ok {
- return n, false
- }
- n.Expr = node.(ExprNode)
- return v.Leave(n)
- }
- type ColumnNameOrUserVar struct {
- node
- ColumnName *ColumnName
- UserVar *VariableExpr
- }
- func (n *ColumnNameOrUserVar) Restore(ctx *format.RestoreCtx) error {
- if n.ColumnName != nil {
- if err := n.ColumnName.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore ColumnNameOrUserVar.ColumnName")
- }
- }
- if n.UserVar != nil {
- if err := n.UserVar.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore ColumnNameOrUserVar.UserVar")
- }
- }
- return nil
- }
- func (n *ColumnNameOrUserVar) Accept(v Visitor) (node Node, ok bool) {
- newNode, skipChild := v.Enter(n)
- if skipChild {
- return v.Leave(newNode)
- }
- n = newNode.(*ColumnNameOrUserVar)
- if n.ColumnName != nil {
- node, ok = n.ColumnName.Accept(v)
- if !ok {
- return node, false
- }
- n.ColumnName = node.(*ColumnName)
- }
- if n.UserVar != nil {
- node, ok = n.UserVar.Accept(v)
- if !ok {
- return node, false
- }
- n.UserVar = node.(*VariableExpr)
- }
- return v.Leave(n)
- }
- // LoadDataStmt is a statement to load data from a specified file, then insert this rows into an existing table.
- // See https://dev.mysql.com/doc/refman/5.7/en/load-data.html
- type LoadDataStmt struct {
- dmlNode
- IsLocal bool
- Path string
- OnDuplicate OnDuplicateKeyHandlingType
- Table *TableName
- Columns []*ColumnName
- FieldsInfo *FieldsClause
- LinesInfo *LinesClause
- IgnoreLines uint64
- ColumnAssignments []*Assignment
- ColumnsAndUserVars []*ColumnNameOrUserVar
- }
- // Restore implements Node interface.
- func (n *LoadDataStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("LOAD DATA ")
- if n.IsLocal {
- ctx.WriteKeyWord("LOCAL ")
- }
- ctx.WriteKeyWord("INFILE ")
- ctx.WriteString(n.Path)
- if n.OnDuplicate == OnDuplicateKeyHandlingReplace {
- ctx.WriteKeyWord(" REPLACE")
- } else if n.OnDuplicate == OnDuplicateKeyHandlingIgnore {
- ctx.WriteKeyWord(" IGNORE")
- }
- ctx.WriteKeyWord(" INTO TABLE ")
- if err := n.Table.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore LoadDataStmt.Table")
- }
- n.FieldsInfo.Restore(ctx)
- n.LinesInfo.Restore(ctx)
- if n.IgnoreLines != 0 {
- ctx.WriteKeyWord(" IGNORE ")
- ctx.WritePlainf("%d", n.IgnoreLines)
- ctx.WriteKeyWord(" LINES")
- }
- if len(n.ColumnsAndUserVars) != 0 {
- ctx.WritePlain(" (")
- for i, c := range n.ColumnsAndUserVars {
- if i != 0 {
- ctx.WritePlain(",")
- }
- if err := c.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore LoadDataStmt.ColumnsAndUserVars")
- }
- }
- ctx.WritePlain(")")
- }
- if n.ColumnAssignments != nil {
- ctx.WriteKeyWord(" SET")
- for i, assign := range n.ColumnAssignments {
- if i != 0 {
- ctx.WritePlain(",")
- }
- ctx.WritePlain(" ")
- if err := assign.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore LoadDataStmt.ColumnAssignments")
- }
- }
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *LoadDataStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*LoadDataStmt)
- if n.Table != nil {
- node, ok := n.Table.Accept(v)
- if !ok {
- return n, false
- }
- n.Table = node.(*TableName)
- }
- for i, val := range n.Columns {
- node, ok := val.Accept(v)
- if !ok {
- return n, false
- }
- n.Columns[i] = node.(*ColumnName)
- }
- for i, assignment := range n.ColumnAssignments {
- node, ok := assignment.Accept(v)
- if !ok {
- return n, false
- }
- n.ColumnAssignments[i] = node.(*Assignment)
- }
- for i, cuVars := range n.ColumnsAndUserVars {
- node, ok := cuVars.Accept(v)
- if !ok {
- return n, false
- }
- n.ColumnsAndUserVars[i] = node.(*ColumnNameOrUserVar)
- }
- return v.Leave(n)
- }
- const (
- Terminated = iota
- Enclosed
- Escaped
- )
- type FieldItem struct {
- Type int
- Value string
- OptEnclosed bool
- }
- // FieldsClause represents fields references clause in load data statement.
- type FieldsClause struct {
- Terminated string
- Enclosed byte
- Escaped byte
- OptEnclosed bool
- }
- // Restore for FieldsClause
- func (n *FieldsClause) Restore(ctx *format.RestoreCtx) error {
- if n.Terminated != "\t" || n.Escaped != '\\' {
- ctx.WriteKeyWord(" FIELDS")
- if n.Terminated != "\t" {
- ctx.WriteKeyWord(" TERMINATED BY ")
- ctx.WriteString(n.Terminated)
- }
- if n.Enclosed != 0 {
- if n.OptEnclosed {
- ctx.WriteKeyWord(" OPTIONALLY")
- }
- ctx.WriteKeyWord(" ENCLOSED BY ")
- ctx.WriteString(string(n.Enclosed))
- }
- if n.Escaped != '\\' {
- ctx.WriteKeyWord(" ESCAPED BY ")
- if n.Escaped == 0 {
- ctx.WritePlain("''")
- } else {
- ctx.WriteString(string(n.Escaped))
- }
- }
- }
- return nil
- }
- // LinesClause represents lines references clause in load data statement.
- type LinesClause struct {
- Starting string
- Terminated string
- }
- // Restore for LinesClause
- func (n *LinesClause) Restore(ctx *format.RestoreCtx) error {
- if n.Starting != "" || n.Terminated != "\n" {
- ctx.WriteKeyWord(" LINES")
- if n.Starting != "" {
- ctx.WriteKeyWord(" STARTING BY ")
- ctx.WriteString(n.Starting)
- }
- if n.Terminated != "\n" {
- ctx.WriteKeyWord(" TERMINATED BY ")
- ctx.WriteString(n.Terminated)
- }
- }
- return nil
- }
- // CallStmt represents a call procedure query node.
- // See https://dev.mysql.com/doc/refman/5.7/en/call.html
- type CallStmt struct {
- dmlNode
- Procedure *FuncCallExpr
- }
- // Restore implements Node interface.
- func (n *CallStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("CALL ")
- if err := n.Procedure.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore CallStmt.Procedure")
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *CallStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*CallStmt)
- if n.Procedure != nil {
- node, ok := n.Procedure.Accept(v)
- if !ok {
- return n, false
- }
- n.Procedure = node.(*FuncCallExpr)
- }
- return v.Leave(n)
- }
- // InsertStmt is a statement to insert new rows into an existing table.
- // See https://dev.mysql.com/doc/refman/5.7/en/insert.html
- type InsertStmt struct {
- dmlNode
- IsReplace bool
- IgnoreErr bool
- Table *TableRefsClause
- Columns []*ColumnName
- Lists [][]ExprNode
- Setlist []*Assignment
- Priority mysql.PriorityEnum
- OnDuplicate []*Assignment
- Select ResultSetNode
- // TableHints represents the table level Optimizer Hint for join type.
- TableHints []*TableOptimizerHint
- PartitionNames []model.CIStr
- }
- // Restore implements Node interface.
- func (n *InsertStmt) Restore(ctx *format.RestoreCtx) error {
- if n.IsReplace {
- ctx.WriteKeyWord("REPLACE ")
- } else {
- ctx.WriteKeyWord("INSERT ")
- }
- if n.TableHints != nil && len(n.TableHints) != 0 {
- ctx.WritePlain("/*+ ")
- for i, tableHint := range n.TableHints {
- if i != 0 {
- ctx.WritePlain(" ")
- }
- if err := tableHint.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore InsertStmt.TableHints[%d]", i)
- }
- }
- ctx.WritePlain("*/ ")
- }
- if err := n.Priority.Restore(ctx); err != nil {
- return errors.Trace(err)
- }
- if n.Priority != mysql.NoPriority {
- ctx.WritePlain(" ")
- }
- if n.IgnoreErr {
- ctx.WriteKeyWord("IGNORE ")
- }
- ctx.WriteKeyWord("INTO ")
- if err := n.Table.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore InsertStmt.Table")
- }
- if len(n.PartitionNames) != 0 {
- ctx.WriteKeyWord(" PARTITION")
- ctx.WritePlain("(")
- for i := 0; i < len(n.PartitionNames); i++ {
- if i != 0 {
- ctx.WritePlain(", ")
- }
- ctx.WriteName(n.PartitionNames[i].String())
- }
- ctx.WritePlain(")")
- }
- if n.Columns != nil {
- ctx.WritePlain(" (")
- for i, v := range n.Columns {
- if i != 0 {
- ctx.WritePlain(",")
- }
- if err := v.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore InsertStmt.Columns[%d]", i)
- }
- }
- ctx.WritePlain(")")
- }
- if n.Lists != nil {
- ctx.WriteKeyWord(" VALUES ")
- for i, row := range n.Lists {
- if i != 0 {
- ctx.WritePlain(",")
- }
- ctx.WritePlain("(")
- for j, v := range row {
- if j != 0 {
- ctx.WritePlain(",")
- }
- if err := v.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore InsertStmt.Lists[%d][%d]", i, j)
- }
- }
- ctx.WritePlain(")")
- }
- }
- if n.Select != nil {
- ctx.WritePlain(" ")
- switch v := n.Select.(type) {
- case *SelectStmt, *SetOprStmt:
- if err := v.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore InsertStmt.Select")
- }
- default:
- return errors.Errorf("Incorrect type for InsertStmt.Select: %T", v)
- }
- }
- if n.Setlist != nil {
- ctx.WriteKeyWord(" SET ")
- for i, v := range n.Setlist {
- if i != 0 {
- ctx.WritePlain(",")
- }
- if err := v.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore InsertStmt.Setlist[%d]", i)
- }
- }
- }
- if n.OnDuplicate != nil {
- ctx.WriteKeyWord(" ON DUPLICATE KEY UPDATE ")
- for i, v := range n.OnDuplicate {
- if i != 0 {
- ctx.WritePlain(",")
- }
- if err := v.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore InsertStmt.OnDuplicate[%d]", i)
- }
- }
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *InsertStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*InsertStmt)
- if n.Select != nil {
- node, ok := n.Select.Accept(v)
- if !ok {
- return n, false
- }
- n.Select = node.(ResultSetNode)
- }
- node, ok := n.Table.Accept(v)
- if !ok {
- return n, false
- }
- n.Table = node.(*TableRefsClause)
- for i, val := range n.Columns {
- node, ok := val.Accept(v)
- if !ok {
- return n, false
- }
- n.Columns[i] = node.(*ColumnName)
- }
- for i, list := range n.Lists {
- for j, val := range list {
- node, ok := val.Accept(v)
- if !ok {
- return n, false
- }
- n.Lists[i][j] = node.(ExprNode)
- }
- }
- for i, val := range n.Setlist {
- node, ok := val.Accept(v)
- if !ok {
- return n, false
- }
- n.Setlist[i] = node.(*Assignment)
- }
- for i, val := range n.OnDuplicate {
- node, ok := val.Accept(v)
- if !ok {
- return n, false
- }
- n.OnDuplicate[i] = node.(*Assignment)
- }
- return v.Leave(n)
- }
- // DeleteStmt is a statement to delete rows from table.
- // See https://dev.mysql.com/doc/refman/5.7/en/delete.html
- type DeleteStmt struct {
- dmlNode
- // TableRefs is used in both single table and multiple table delete statement.
- TableRefs *TableRefsClause
- // Tables is only used in multiple table delete statement.
- Tables *DeleteTableList
- Where ExprNode
- Order *OrderByClause
- Limit *Limit
- Priority mysql.PriorityEnum
- IgnoreErr bool
- Quick bool
- IsMultiTable bool
- BeforeFrom bool
- // TableHints represents the table level Optimizer Hint for join type.
- TableHints []*TableOptimizerHint
- With *WithClause
- }
- // Restore implements Node interface.
- func (n *DeleteStmt) Restore(ctx *format.RestoreCtx) error {
- if n.With != nil {
- err := n.With.Restore(ctx)
- if err != nil {
- return err
- }
- }
- ctx.WriteKeyWord("DELETE ")
- if n.TableHints != nil && len(n.TableHints) != 0 {
- ctx.WritePlain("/*+ ")
- for i, tableHint := range n.TableHints {
- if i != 0 {
- ctx.WritePlain(" ")
- }
- if err := tableHint.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore UpdateStmt.TableHints[%d]", i)
- }
- }
- ctx.WritePlain("*/ ")
- }
- if err := n.Priority.Restore(ctx); err != nil {
- return errors.Trace(err)
- }
- if n.Priority != mysql.NoPriority {
- ctx.WritePlain(" ")
- }
- if n.Quick {
- ctx.WriteKeyWord("QUICK ")
- }
- if n.IgnoreErr {
- ctx.WriteKeyWord("IGNORE ")
- }
- if n.IsMultiTable { // Multiple-Table Syntax
- if n.BeforeFrom {
- if err := n.Tables.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore DeleteStmt.Tables")
- }
- ctx.WriteKeyWord(" FROM ")
- if err := n.TableRefs.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore DeleteStmt.TableRefs")
- }
- } else {
- ctx.WriteKeyWord("FROM ")
- if err := n.Tables.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore DeleteStmt.Tables")
- }
- ctx.WriteKeyWord(" USING ")
- if err := n.TableRefs.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore DeleteStmt.TableRefs")
- }
- }
- } else { // Single-Table Syntax
- ctx.WriteKeyWord("FROM ")
- if err := n.TableRefs.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore DeleteStmt.TableRefs")
- }
- }
- if n.Where != nil {
- ctx.WriteKeyWord(" WHERE ")
- if err := n.Where.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore DeleteStmt.Where")
- }
- }
- if n.Order != nil {
- ctx.WritePlain(" ")
- if err := n.Order.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore DeleteStmt.Order")
- }
- }
- if n.Limit != nil {
- ctx.WritePlain(" ")
- if err := n.Limit.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore DeleteStmt.Limit")
- }
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *DeleteStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*DeleteStmt)
- if n.With != nil {
- node, ok := n.With.Accept(v)
- if !ok {
- return n, false
- }
- n.With = node.(*WithClause)
- }
- node, ok := n.TableRefs.Accept(v)
- if !ok {
- return n, false
- }
- n.TableRefs = node.(*TableRefsClause)
- if n.Tables != nil {
- node, ok = n.Tables.Accept(v)
- if !ok {
- return n, false
- }
- n.Tables = node.(*DeleteTableList)
- }
- if n.Where != nil {
- node, ok = n.Where.Accept(v)
- if !ok {
- return n, false
- }
- n.Where = node.(ExprNode)
- }
- if n.Order != nil {
- node, ok = n.Order.Accept(v)
- if !ok {
- return n, false
- }
- n.Order = node.(*OrderByClause)
- }
- if n.Limit != nil {
- node, ok = n.Limit.Accept(v)
- if !ok {
- return n, false
- }
- n.Limit = node.(*Limit)
- }
- return v.Leave(n)
- }
- // UpdateStmt is a statement to update columns of existing rows in tables with new values.
- // See https://dev.mysql.com/doc/refman/5.7/en/update.html
- type UpdateStmt struct {
- dmlNode
- TableRefs *TableRefsClause
- List []*Assignment
- Where ExprNode
- Order *OrderByClause
- Limit *Limit
- Priority mysql.PriorityEnum
- IgnoreErr bool
- MultipleTable bool
- TableHints []*TableOptimizerHint
- With *WithClause
- }
- // Restore implements Node interface.
- func (n *UpdateStmt) Restore(ctx *format.RestoreCtx) error {
- if n.With != nil {
- err := n.With.Restore(ctx)
- if err != nil {
- return err
- }
- }
- ctx.WriteKeyWord("UPDATE ")
- if n.TableHints != nil && len(n.TableHints) != 0 {
- ctx.WritePlain("/*+ ")
- for i, tableHint := range n.TableHints {
- if i != 0 {
- ctx.WritePlain(" ")
- }
- if err := tableHint.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore UpdateStmt.TableHints[%d]", i)
- }
- }
- ctx.WritePlain("*/ ")
- }
- if err := n.Priority.Restore(ctx); err != nil {
- return errors.Trace(err)
- }
- if n.Priority != mysql.NoPriority {
- ctx.WritePlain(" ")
- }
- if n.IgnoreErr {
- ctx.WriteKeyWord("IGNORE ")
- }
- if err := n.TableRefs.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occur while restore UpdateStmt.TableRefs")
- }
- ctx.WriteKeyWord(" SET ")
- for i, assignment := range n.List {
- if i != 0 {
- ctx.WritePlain(", ")
- }
- if err := assignment.Column.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occur while restore UpdateStmt.List[%d].Column", i)
- }
- ctx.WritePlain("=")
- if err := assignment.Expr.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occur while restore UpdateStmt.List[%d].Expr", i)
- }
- }
- if n.Where != nil {
- ctx.WriteKeyWord(" WHERE ")
- if err := n.Where.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occur while restore UpdateStmt.Where")
- }
- }
- if n.Order != nil {
- ctx.WritePlain(" ")
- if err := n.Order.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occur while restore UpdateStmt.Order")
- }
- }
- if n.Limit != nil {
- ctx.WritePlain(" ")
- if err := n.Limit.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occur while restore UpdateStmt.Limit")
- }
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *UpdateStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*UpdateStmt)
- if n.With != nil {
- node, ok := n.With.Accept(v)
- if !ok {
- return n, false
- }
- n.With = node.(*WithClause)
- }
- node, ok := n.TableRefs.Accept(v)
- if !ok {
- return n, false
- }
- n.TableRefs = node.(*TableRefsClause)
- for i, val := range n.List {
- node, ok = val.Accept(v)
- if !ok {
- return n, false
- }
- n.List[i] = node.(*Assignment)
- }
- if n.Where != nil {
- node, ok = n.Where.Accept(v)
- if !ok {
- return n, false
- }
- n.Where = node.(ExprNode)
- }
- if n.Order != nil {
- node, ok = n.Order.Accept(v)
- if !ok {
- return n, false
- }
- n.Order = node.(*OrderByClause)
- }
- if n.Limit != nil {
- node, ok = n.Limit.Accept(v)
- if !ok {
- return n, false
- }
- n.Limit = node.(*Limit)
- }
- return v.Leave(n)
- }
- // Limit is the limit clause.
- type Limit struct {
- node
- Count ExprNode
- Offset ExprNode
- }
- // Restore implements Node interface.
- func (n *Limit) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("LIMIT ")
- if n.Offset != nil {
- if err := n.Offset.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore Limit.Offset")
- }
- ctx.WritePlain(",")
- }
- if err := n.Count.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore Limit.Count")
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *Limit) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- if n.Count != nil {
- node, ok := n.Count.Accept(v)
- if !ok {
- return n, false
- }
- n.Count = node.(ExprNode)
- }
- if n.Offset != nil {
- node, ok := n.Offset.Accept(v)
- if !ok {
- return n, false
- }
- n.Offset = node.(ExprNode)
- }
- n = newNode.(*Limit)
- return v.Leave(n)
- }
- // ShowStmtType is the type for SHOW statement.
- type ShowStmtType int
- // Show statement types.
- const (
- ShowNone = iota
- ShowEngines
- ShowDatabases
- ShowTables
- ShowTableStatus
- ShowColumns
- ShowWarnings
- ShowCharset
- ShowVariables
- ShowStatus
- ShowCollation
- ShowCreateTable
- ShowCreateView
- ShowCreateUser
- ShowCreateSequence
- ShowGrants
- ShowTriggers
- ShowProcedureStatus
- ShowIndex
- ShowProcessList
- ShowCreateDatabase
- ShowConfig
- ShowEvents
- ShowStatsExtended
- ShowStatsMeta
- ShowStatsHistograms
- ShowStatsTopN
- ShowStatsBuckets
- ShowStatsHealthy
- ShowPlugins
- ShowProfile
- ShowProfiles
- ShowMasterStatus
- ShowPrivileges
- ShowErrors
- ShowBindings
- ShowPumpStatus
- ShowDrainerStatus
- ShowOpenTables
- ShowAnalyzeStatus
- ShowRegions
- ShowBuiltins
- ShowTableNextRowId
- ShowBackups
- ShowRestores
- ShowImports
- ShowCreateImport
- )
- const (
- ProfileTypeInvalid = iota
- ProfileTypeCPU
- ProfileTypeMemory
- ProfileTypeBlockIo
- ProfileTypeContextSwitch
- ProfileTypePageFaults
- ProfileTypeIpc
- ProfileTypeSwaps
- ProfileTypeSource
- ProfileTypeAll
- )
- // ShowStmt is a statement to provide information about databases, tables, columns and so on.
- // See https://dev.mysql.com/doc/refman/5.7/en/show.html
- type ShowStmt struct {
- dmlNode
- Tp ShowStmtType // Databases/Tables/Columns/....
- DBName string
- Table *TableName // Used for showing columns.
- Column *ColumnName // Used for `desc table column`.
- IndexName model.CIStr
- Flag int // Some flag parsed from sql, such as FULL.
- Full bool
- User *auth.UserIdentity // Used for show grants/create user.
- Roles []*auth.RoleIdentity // Used for show grants .. using
- IfNotExists bool // Used for `show create database if not exists`
- Extended bool // Used for `show extended columns from ...`
- // GlobalScope is used by `show variables` and `show bindings`
- GlobalScope bool
- Pattern *PatternLikeExpr
- Where ExprNode
- ShowProfileTypes []int // Used for `SHOW PROFILE` syntax
- ShowProfileArgs *int64 // Used for `SHOW PROFILE` syntax
- ShowProfileLimit *Limit // Used for `SHOW PROFILE` syntax
- }
- // Restore implements Node interface.
- func (n *ShowStmt) Restore(ctx *format.RestoreCtx) error {
- restoreOptFull := func() {
- if n.Full {
- ctx.WriteKeyWord("FULL ")
- }
- }
- restoreShowDatabaseNameOpt := func() {
- if n.DBName != "" {
- // FROM OR IN
- ctx.WriteKeyWord(" IN ")
- ctx.WriteName(n.DBName)
- }
- }
- restoreGlobalScope := func() {
- if n.GlobalScope {
- ctx.WriteKeyWord("GLOBAL ")
- } else {
- ctx.WriteKeyWord("SESSION ")
- }
- }
- restoreShowLikeOrWhereOpt := func() error {
- if n.Pattern != nil && n.Pattern.Pattern != nil {
- ctx.WriteKeyWord(" LIKE ")
- if err := n.Pattern.Pattern.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore ShowStmt.Pattern")
- }
- } else 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")
- }
- }
- return nil
- }
- ctx.WriteKeyWord("SHOW ")
- switch n.Tp {
- case ShowCreateTable:
- ctx.WriteKeyWord("CREATE TABLE ")
- if err := n.Table.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore ShowStmt.Table")
- }
- case ShowCreateView:
- ctx.WriteKeyWord("CREATE VIEW ")
- if err := n.Table.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore ShowStmt.VIEW")
- }
- case ShowCreateDatabase:
- ctx.WriteKeyWord("CREATE DATABASE ")
- if n.IfNotExists {
- ctx.WriteKeyWord("IF NOT EXISTS ")
- }
- ctx.WriteName(n.DBName)
- case ShowCreateSequence:
- ctx.WriteKeyWord("CREATE SEQUENCE ")
- if err := n.Table.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore ShowStmt.SEQUENCE")
- }
- case ShowCreateUser:
- ctx.WriteKeyWord("CREATE USER ")
- if err := n.User.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore ShowStmt.User")
- }
- case ShowGrants:
- ctx.WriteKeyWord("GRANTS")
- if n.User != nil {
- ctx.WriteKeyWord(" FOR ")
- if err := n.User.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore ShowStmt.User")
- }
- }
- if n.Roles != nil {
- ctx.WriteKeyWord(" USING ")
- for i, r := range n.Roles {
- if err := r.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore ShowStmt.User")
- }
- if i != len(n.Roles)-1 {
- ctx.WritePlain(", ")
- }
- }
- }
- case ShowMasterStatus:
- ctx.WriteKeyWord("MASTER STATUS")
- case ShowProcessList:
- restoreOptFull()
- ctx.WriteKeyWord("PROCESSLIST")
- case ShowStatsExtended:
- ctx.WriteKeyWord("STATS_EXTENDED")
- if err := restoreShowLikeOrWhereOpt(); err != nil {
- return err
- }
- case ShowStatsMeta:
- ctx.WriteKeyWord("STATS_META")
- if err := restoreShowLikeOrWhereOpt(); err != nil {
- return err
- }
- case ShowStatsHistograms:
- ctx.WriteKeyWord("STATS_HISTOGRAMS")
- if err := restoreShowLikeOrWhereOpt(); err != nil {
- return err
- }
- case ShowStatsTopN:
- ctx.WriteKeyWord("STATS_TOPN")
- if err := restoreShowLikeOrWhereOpt(); err != nil {
- return err
- }
- case ShowStatsBuckets:
- ctx.WriteKeyWord("STATS_BUCKETS")
- if err := restoreShowLikeOrWhereOpt(); err != nil {
- return err
- }
- case ShowStatsHealthy:
- ctx.WriteKeyWord("STATS_HEALTHY")
- if err := restoreShowLikeOrWhereOpt(); err != nil {
- return err
- }
- case ShowProfiles:
- ctx.WriteKeyWord("PROFILES")
- case ShowProfile:
- ctx.WriteKeyWord("PROFILE")
- if len(n.ShowProfileTypes) > 0 {
- for i, tp := range n.ShowProfileTypes {
- if i != 0 {
- ctx.WritePlain(",")
- }
- ctx.WritePlain(" ")
- switch tp {
- case ProfileTypeCPU:
- ctx.WriteKeyWord("CPU")
- case ProfileTypeMemory:
- ctx.WriteKeyWord("MEMORY")
- case ProfileTypeBlockIo:
- ctx.WriteKeyWord("BLOCK IO")
- case ProfileTypeContextSwitch:
- ctx.WriteKeyWord("CONTEXT SWITCHES")
- case ProfileTypeIpc:
- ctx.WriteKeyWord("IPC")
- case ProfileTypePageFaults:
- ctx.WriteKeyWord("PAGE FAULTS")
- case ProfileTypeSource:
- ctx.WriteKeyWord("SOURCE")
- case ProfileTypeSwaps:
- ctx.WriteKeyWord("SWAPS")
- case ProfileTypeAll:
- ctx.WriteKeyWord("ALL")
- }
- }
- }
- if n.ShowProfileArgs != nil {
- ctx.WriteKeyWord(" FOR QUERY ")
- ctx.WritePlainf("%d", *n.ShowProfileArgs)
- }
- if n.ShowProfileLimit != nil {
- ctx.WritePlain(" ")
- if err := n.ShowProfileLimit.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore ShowStmt.WritePlain")
- }
- }
- case ShowPrivileges:
- ctx.WriteKeyWord("PRIVILEGES")
- case ShowBuiltins:
- ctx.WriteKeyWord("BUILTINS")
- case ShowCreateImport:
- ctx.WriteKeyWord("CREATE IMPORT ")
- ctx.WriteName(n.DBName)
- // ShowTargetFilterable
- default:
- switch n.Tp {
- case ShowEngines:
- ctx.WriteKeyWord("ENGINES")
- case ShowConfig:
- ctx.WriteKeyWord("CONFIG")
- case ShowDatabases:
- ctx.WriteKeyWord("DATABASES")
- case ShowCharset:
- ctx.WriteKeyWord("CHARSET")
- case ShowTables:
- restoreOptFull()
- ctx.WriteKeyWord("TABLES")
- restoreShowDatabaseNameOpt()
- case ShowOpenTables:
- ctx.WriteKeyWord("OPEN TABLES")
- restoreShowDatabaseNameOpt()
- case ShowTableStatus:
- ctx.WriteKeyWord("TABLE STATUS")
- restoreShowDatabaseNameOpt()
- case ShowIndex:
- // here can be INDEX INDEXES KEYS
- // FROM or IN
- ctx.WriteKeyWord("INDEX IN ")
- if err := n.Table.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while resotre ShowStmt.Table")
- } // TODO: remember to check this case
- case ShowColumns: // equivalent to SHOW FIELDS
- if n.Extended {
- ctx.WriteKeyWord("EXTENDED ")
- }
- restoreOptFull()
- ctx.WriteKeyWord("COLUMNS")
- if n.Table != nil {
- // FROM or IN
- ctx.WriteKeyWord(" IN ")
- if err := n.Table.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while resotre ShowStmt.Table")
- }
- }
- restoreShowDatabaseNameOpt()
- case ShowWarnings:
- ctx.WriteKeyWord("WARNINGS")
- case ShowErrors:
- ctx.WriteKeyWord("ERRORS")
- case ShowVariables:
- restoreGlobalScope()
- ctx.WriteKeyWord("VARIABLES")
- case ShowStatus:
- restoreGlobalScope()
- ctx.WriteKeyWord("STATUS")
- case ShowCollation:
- ctx.WriteKeyWord("COLLATION")
- case ShowTriggers:
- ctx.WriteKeyWord("TRIGGERS")
- restoreShowDatabaseNameOpt()
- case ShowProcedureStatus:
- ctx.WriteKeyWord("PROCEDURE STATUS")
- case ShowEvents:
- ctx.WriteKeyWord("EVENTS")
- restoreShowDatabaseNameOpt()
- case ShowPlugins:
- ctx.WriteKeyWord("PLUGINS")
- case ShowBindings:
- if n.GlobalScope {
- ctx.WriteKeyWord("GLOBAL ")
- } else {
- ctx.WriteKeyWord("SESSION ")
- }
- ctx.WriteKeyWord("BINDINGS")
- case ShowPumpStatus:
- ctx.WriteKeyWord("PUMP STATUS")
- case ShowDrainerStatus:
- ctx.WriteKeyWord("DRAINER STATUS")
- case ShowAnalyzeStatus:
- ctx.WriteKeyWord("ANALYZE STATUS")
- case ShowRegions:
- ctx.WriteKeyWord("TABLE ")
- if err := n.Table.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore SplitIndexRegionStmt.Table")
- }
- if len(n.IndexName.L) > 0 {
- ctx.WriteKeyWord(" INDEX ")
- ctx.WriteName(n.IndexName.String())
- }
- ctx.WriteKeyWord(" REGIONS")
- if err := restoreShowLikeOrWhereOpt(); err != nil {
- return err
- }
- return nil
- case ShowTableNextRowId:
- ctx.WriteKeyWord("TABLE ")
- if err := n.Table.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore SplitIndexRegionStmt.Table")
- }
- ctx.WriteKeyWord(" NEXT_ROW_ID")
- return nil
- case ShowBackups:
- ctx.WriteKeyWord("BACKUPS")
- case ShowRestores:
- ctx.WriteKeyWord("RESTORES")
- case ShowImports:
- ctx.WriteKeyWord("IMPORTS")
- default:
- return errors.New("Unknown ShowStmt type")
- }
- restoreShowLikeOrWhereOpt()
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *ShowStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*ShowStmt)
- if n.Table != nil {
- node, ok := n.Table.Accept(v)
- if !ok {
- return n, false
- }
- n.Table = node.(*TableName)
- }
- if n.Column != nil {
- node, ok := n.Column.Accept(v)
- if !ok {
- return n, false
- }
- n.Column = node.(*ColumnName)
- }
- if n.Pattern != nil {
- node, ok := n.Pattern.Accept(v)
- if !ok {
- return n, false
- }
- n.Pattern = node.(*PatternLikeExpr)
- }
- if n.Where != nil {
- node, ok := n.Where.Accept(v)
- if !ok {
- return n, false
- }
- n.Where = node.(ExprNode)
- }
- return v.Leave(n)
- }
- // WindowSpec is the specification of a window.
- type WindowSpec struct {
- node
- Name model.CIStr
- // Ref is the reference window of this specification. For example, in `w2 as (w1 order by a)`,
- // the definition of `w2` references `w1`.
- Ref model.CIStr
- PartitionBy *PartitionByClause
- OrderBy *OrderByClause
- Frame *FrameClause
- // OnlyAlias will set to true of the first following case.
- // To make compatible with MySQL, we need to distinguish `select func over w` from `select func over (w)`.
- OnlyAlias bool
- }
- // Restore implements Node interface.
- func (n *WindowSpec) Restore(ctx *format.RestoreCtx) error {
- if name := n.Name.String(); name != "" {
- ctx.WriteName(name)
- if n.OnlyAlias {
- return nil
- }
- ctx.WriteKeyWord(" AS ")
- }
- ctx.WritePlain("(")
- sep := ""
- if refName := n.Ref.String(); refName != "" {
- ctx.WriteName(refName)
- sep = " "
- }
- if n.PartitionBy != nil {
- ctx.WritePlain(sep)
- if err := n.PartitionBy.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore WindowSpec.PartitionBy")
- }
- sep = " "
- }
- if n.OrderBy != nil {
- ctx.WritePlain(sep)
- if err := n.OrderBy.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore WindowSpec.OrderBy")
- }
- sep = " "
- }
- if n.Frame != nil {
- ctx.WritePlain(sep)
- if err := n.Frame.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore WindowSpec.Frame")
- }
- }
- ctx.WritePlain(")")
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *WindowSpec) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*WindowSpec)
- if n.PartitionBy != nil {
- node, ok := n.PartitionBy.Accept(v)
- if !ok {
- return n, false
- }
- n.PartitionBy = node.(*PartitionByClause)
- }
- if n.OrderBy != nil {
- node, ok := n.OrderBy.Accept(v)
- if !ok {
- return n, false
- }
- n.OrderBy = node.(*OrderByClause)
- }
- if n.Frame != nil {
- node, ok := n.Frame.Accept(v)
- if !ok {
- return n, false
- }
- n.Frame = node.(*FrameClause)
- }
- return v.Leave(n)
- }
- type SelectIntoType int
- const (
- SelectIntoOutfile SelectIntoType = iota + 1
- SelectIntoDumpfile
- SelectIntoVars
- )
- type SelectIntoOption struct {
- node
- Tp SelectIntoType
- FileName string
- FieldsInfo *FieldsClause
- LinesInfo *LinesClause
- }
- // Restore implements Node interface.
- func (n *SelectIntoOption) Restore(ctx *format.RestoreCtx) error {
- if n.Tp != SelectIntoOutfile {
- // only support SELECT/TABLE/VALUES ... INTO OUTFILE statement now
- return errors.New("Unsupported SelectionInto type")
- }
- ctx.WriteKeyWord("INTO OUTFILE ")
- ctx.WriteString(n.FileName)
- if n.FieldsInfo != nil {
- if err := n.FieldsInfo.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore SelectInto.FieldsInfo")
- }
- }
- if n.LinesInfo != nil {
- if err := n.LinesInfo.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore SelectInto.LinesInfo")
- }
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *SelectIntoOption) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- return v.Leave(n)
- }
- // PartitionByClause represents partition by clause.
- type PartitionByClause struct {
- node
- Items []*ByItem
- }
- // Restore implements Node interface.
- func (n *PartitionByClause) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("PARTITION BY ")
- for i, v := range n.Items {
- if i != 0 {
- ctx.WritePlain(", ")
- }
- if err := v.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore PartitionByClause.Items[%d]", i)
- }
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *PartitionByClause) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*PartitionByClause)
- for i, val := range n.Items {
- node, ok := val.Accept(v)
- if !ok {
- return n, false
- }
- n.Items[i] = node.(*ByItem)
- }
- return v.Leave(n)
- }
- // FrameType is the type of window function frame.
- type FrameType int
- // Window function frame types.
- // MySQL only supports `ROWS` and `RANGES`.
- const (
- Rows = iota
- Ranges
- Groups
- )
- // FrameClause represents frame clause.
- type FrameClause struct {
- node
- Type FrameType
- Extent FrameExtent
- }
- // Restore implements Node interface.
- func (n *FrameClause) Restore(ctx *format.RestoreCtx) error {
- switch n.Type {
- case Rows:
- ctx.WriteKeyWord("ROWS")
- case Ranges:
- ctx.WriteKeyWord("RANGE")
- default:
- return errors.New("Unsupported window function frame type")
- }
- ctx.WriteKeyWord(" BETWEEN ")
- if err := n.Extent.Start.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore FrameClause.Extent.Start")
- }
- ctx.WriteKeyWord(" AND ")
- if err := n.Extent.End.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore FrameClause.Extent.End")
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *FrameClause) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*FrameClause)
- node, ok := n.Extent.Start.Accept(v)
- if !ok {
- return n, false
- }
- n.Extent.Start = *node.(*FrameBound)
- node, ok = n.Extent.End.Accept(v)
- if !ok {
- return n, false
- }
- n.Extent.End = *node.(*FrameBound)
- return v.Leave(n)
- }
- // FrameExtent represents frame extent.
- type FrameExtent struct {
- Start FrameBound
- End FrameBound
- }
- // FrameType is the type of window function frame bound.
- type BoundType int
- // Frame bound types.
- const (
- Following = iota
- Preceding
- CurrentRow
- )
- // FrameBound represents frame bound.
- type FrameBound struct {
- node
- Type BoundType
- UnBounded bool
- Expr ExprNode
- // `Unit` is used to indicate the units in which the `Expr` should be interpreted.
- // For example: '2:30' MINUTE_SECOND.
- Unit TimeUnitType
- }
- // Restore implements Node interface.
- func (n *FrameBound) Restore(ctx *format.RestoreCtx) error {
- if n.UnBounded {
- ctx.WriteKeyWord("UNBOUNDED")
- }
- switch n.Type {
- case CurrentRow:
- ctx.WriteKeyWord("CURRENT ROW")
- case Preceding, Following:
- if n.Unit != TimeUnitInvalid {
- ctx.WriteKeyWord("INTERVAL ")
- }
- if n.Expr != nil {
- if err := n.Expr.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore FrameBound.Expr")
- }
- }
- if n.Unit != TimeUnitInvalid {
- ctx.WritePlain(" ")
- ctx.WriteKeyWord(n.Unit.String())
- }
- if n.Type == Preceding {
- ctx.WriteKeyWord(" PRECEDING")
- } else {
- ctx.WriteKeyWord(" FOLLOWING")
- }
- }
- return nil
- }
- // Accept implements Node Accept interface.
- func (n *FrameBound) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*FrameBound)
- if n.Expr != nil {
- node, ok := n.Expr.Accept(v)
- if !ok {
- return n, false
- }
- n.Expr = node.(ExprNode)
- }
- return v.Leave(n)
- }
- type SplitRegionStmt struct {
- dmlNode
- Table *TableName
- IndexName model.CIStr
- PartitionNames []model.CIStr
- SplitSyntaxOpt *SplitSyntaxOption
- SplitOpt *SplitOption
- }
- type SplitOption struct {
- Lower []ExprNode
- Upper []ExprNode
- Num int64
- ValueLists [][]ExprNode
- }
- type SplitSyntaxOption struct {
- HasRegionFor bool
- HasPartition bool
- }
- func (n *SplitRegionStmt) Restore(ctx *format.RestoreCtx) error {
- ctx.WriteKeyWord("SPLIT ")
- if n.SplitSyntaxOpt != nil {
- if n.SplitSyntaxOpt.HasRegionFor {
- ctx.WriteKeyWord("REGION FOR ")
- }
- if n.SplitSyntaxOpt.HasPartition {
- ctx.WriteKeyWord("PARTITION ")
- }
- }
- ctx.WriteKeyWord("TABLE ")
- if err := n.Table.Restore(ctx); err != nil {
- return errors.Annotate(err, "An error occurred while restore SplitIndexRegionStmt.Table")
- }
- if len(n.PartitionNames) > 0 {
- ctx.WriteKeyWord(" PARTITION")
- ctx.WritePlain("(")
- for i, v := range n.PartitionNames {
- if i != 0 {
- ctx.WritePlain(", ")
- }
- ctx.WriteName(v.String())
- }
- ctx.WritePlain(")")
- }
- if len(n.IndexName.L) > 0 {
- ctx.WriteKeyWord(" INDEX ")
- ctx.WriteName(n.IndexName.String())
- }
- ctx.WritePlain(" ")
- err := n.SplitOpt.Restore(ctx)
- return err
- }
- func (n *SplitRegionStmt) Accept(v Visitor) (Node, bool) {
- newNode, skipChildren := v.Enter(n)
- if skipChildren {
- return v.Leave(newNode)
- }
- n = newNode.(*SplitRegionStmt)
- node, ok := n.Table.Accept(v)
- if !ok {
- return n, false
- }
- n.Table = node.(*TableName)
- for i, val := range n.SplitOpt.Lower {
- node, ok := val.Accept(v)
- if !ok {
- return n, false
- }
- n.SplitOpt.Lower[i] = node.(ExprNode)
- }
- for i, val := range n.SplitOpt.Upper {
- node, ok := val.Accept(v)
- if !ok {
- return n, false
- }
- n.SplitOpt.Upper[i] = node.(ExprNode)
- }
- for i, list := range n.SplitOpt.ValueLists {
- for j, val := range list {
- node, ok := val.Accept(v)
- if !ok {
- return n, false
- }
- n.SplitOpt.ValueLists[i][j] = node.(ExprNode)
- }
- }
- return v.Leave(n)
- }
- func (n *SplitOption) Restore(ctx *format.RestoreCtx) error {
- if len(n.ValueLists) == 0 {
- ctx.WriteKeyWord("BETWEEN ")
- ctx.WritePlain("(")
- for j, v := range n.Lower {
- if j != 0 {
- ctx.WritePlain(",")
- }
- if err := v.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore SplitOption Lower")
- }
- }
- ctx.WritePlain(")")
- ctx.WriteKeyWord(" AND ")
- ctx.WritePlain("(")
- for j, v := range n.Upper {
- if j != 0 {
- ctx.WritePlain(",")
- }
- if err := v.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore SplitOption Upper")
- }
- }
- ctx.WritePlain(")")
- ctx.WriteKeyWord(" REGIONS")
- ctx.WritePlainf(" %d", n.Num)
- return nil
- }
- ctx.WriteKeyWord("BY ")
- for i, row := range n.ValueLists {
- if i != 0 {
- ctx.WritePlain(",")
- }
- ctx.WritePlain("(")
- for j, v := range row {
- if j != 0 {
- ctx.WritePlain(",")
- }
- if err := v.Restore(ctx); err != nil {
- return errors.Annotatef(err, "An error occurred while restore SplitOption.ValueLists[%d][%d]", i, j)
- }
- }
- ctx.WritePlain(")")
- }
- return nil
- }
- type FulltextSearchModifier int
- const (
- FulltextSearchModifierNaturalLanguageMode = 0
- FulltextSearchModifierBooleanMode = 1
- FulltextSearchModifierModeMask = 0xF
- FulltextSearchModifierWithQueryExpansion = 1 << 4
- )
- func (m FulltextSearchModifier) IsBooleanMode() bool {
- return m&FulltextSearchModifierModeMask == FulltextSearchModifierBooleanMode
- }
- func (m FulltextSearchModifier) IsNaturalLanguageMode() bool {
- return m&FulltextSearchModifierModeMask == FulltextSearchModifierNaturalLanguageMode
- }
- func (m FulltextSearchModifier) WithQueryExpansion() bool {
- return m&FulltextSearchModifierWithQueryExpansion == FulltextSearchModifierWithQueryExpansion
- }
- type TimestampBound struct {
- Mode TimestampBoundMode
- Timestamp ExprNode
- }
- type TimestampBoundMode int
- const (
- TimestampBoundStrong TimestampBoundMode = iota
- TimestampBoundMaxStaleness
- TimestampBoundExactStaleness
- TimestampBoundReadTimestamp
- TimestampBoundMinReadTimestamp
- )
|