github.com/pingcap/tidb/parser@v0.0.0-20231013125129-93a834a6bf8d/test_driver/test_driver.go (about) 1 // Copyright 2019 PingCAP, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 //go:build !codes 15 // +build !codes 16 17 package test_driver 18 19 import ( 20 "fmt" 21 "io" 22 "strconv" 23 24 "github.com/pingcap/tidb/parser/ast" 25 "github.com/pingcap/tidb/parser/charset" 26 "github.com/pingcap/tidb/parser/format" 27 "github.com/pingcap/tidb/parser/mysql" 28 ) 29 30 func init() { 31 ast.NewValueExpr = newValueExpr 32 ast.NewParamMarkerExpr = newParamMarkerExpr 33 ast.NewDecimal = func(str string) (interface{}, error) { 34 dec := new(MyDecimal) 35 err := dec.FromString([]byte(str)) 36 return dec, err 37 } 38 ast.NewHexLiteral = func(str string) (interface{}, error) { 39 h, err := NewHexLiteral(str) 40 return h, err 41 } 42 ast.NewBitLiteral = func(str string) (interface{}, error) { 43 b, err := NewBitLiteral(str) 44 return b, err 45 } 46 } 47 48 var ( 49 _ ast.ParamMarkerExpr = &ParamMarkerExpr{} 50 _ ast.ValueExpr = &ValueExpr{} 51 ) 52 53 // ValueExpr is the simple value expression. 54 type ValueExpr struct { 55 ast.TexprNode 56 Datum 57 projectionOffset int 58 } 59 60 // Restore implements Node interface. 61 func (n *ValueExpr) Restore(ctx *format.RestoreCtx) error { 62 switch n.Kind() { 63 case KindNull: 64 ctx.WriteKeyWord("NULL") 65 case KindInt64: 66 if n.Type.GetFlag()&mysql.IsBooleanFlag != 0 { 67 if n.GetInt64() > 0 { 68 ctx.WriteKeyWord("TRUE") 69 } else { 70 ctx.WriteKeyWord("FALSE") 71 } 72 } else { 73 ctx.WritePlain(strconv.FormatInt(n.GetInt64(), 10)) 74 } 75 case KindUint64: 76 ctx.WritePlain(strconv.FormatUint(n.GetUint64(), 10)) 77 case KindFloat32: 78 ctx.WritePlain(strconv.FormatFloat(n.GetFloat64(), 'e', -1, 32)) 79 case KindFloat64: 80 ctx.WritePlain(strconv.FormatFloat(n.GetFloat64(), 'e', -1, 64)) 81 case KindString: 82 if n.Type.GetCharset() != "" && 83 !ctx.Flags.HasStringWithoutCharset() && 84 (!ctx.Flags.HasStringWithoutDefaultCharset() || n.Type.GetCharset() != mysql.DefaultCharset) { 85 ctx.WritePlain("_") 86 ctx.WriteKeyWord(n.Type.GetCharset()) 87 } 88 ctx.WriteString(n.GetString()) 89 case KindBytes: 90 ctx.WriteString(n.GetString()) 91 case KindMysqlDecimal: 92 ctx.WritePlain(n.GetMysqlDecimal().String()) 93 case KindBinaryLiteral: 94 if n.Type.GetCharset() != "" && n.Type.GetCharset() != mysql.DefaultCharset && 95 !ctx.Flags.HasStringWithoutCharset() && 96 n.Type.GetCharset() != charset.CharsetBin { 97 ctx.WritePlain("_") 98 ctx.WriteKeyWord(n.Type.GetCharset() + " ") 99 } 100 if n.Type.GetFlag()&mysql.UnsignedFlag != 0 { 101 ctx.WritePlainf("x'%x'", n.GetBytes()) 102 } else { 103 ctx.WritePlain(n.GetBinaryLiteral().ToBitLiteralString(true)) 104 } 105 case KindMysqlDuration, KindMysqlEnum, 106 KindMysqlBit, KindMysqlSet, KindMysqlTime, 107 KindInterface, KindMinNotNull, KindMaxValue, 108 KindRaw, KindMysqlJSON: 109 // TODO implement Restore function 110 return fmt.Errorf("not implemented") 111 default: 112 return fmt.Errorf("can't format to string") 113 } 114 return nil 115 } 116 117 // GetDatumString implements the ValueExpr interface. 118 func (n *ValueExpr) GetDatumString() string { 119 return n.GetString() 120 } 121 122 // Format the ExprNode into a Writer. 123 func (n *ValueExpr) Format(w io.Writer) { 124 var s string 125 switch n.Kind() { 126 case KindNull: 127 s = "NULL" 128 case KindInt64: 129 if n.Type.GetFlag()&mysql.IsBooleanFlag != 0 { 130 if n.GetInt64() > 0 { 131 s = "TRUE" 132 } else { 133 s = "FALSE" 134 } 135 } else { 136 s = strconv.FormatInt(n.GetInt64(), 10) 137 } 138 case KindUint64: 139 s = strconv.FormatUint(n.GetUint64(), 10) 140 case KindFloat32: 141 s = strconv.FormatFloat(n.GetFloat64(), 'e', -1, 32) 142 case KindFloat64: 143 s = strconv.FormatFloat(n.GetFloat64(), 'e', -1, 64) 144 case KindString, KindBytes: 145 s = strconv.Quote(n.GetString()) 146 case KindMysqlDecimal: 147 s = n.GetMysqlDecimal().String() 148 case KindBinaryLiteral: 149 if n.Type.GetFlag()&mysql.UnsignedFlag != 0 { 150 s = fmt.Sprintf("x'%x'", n.GetBytes()) 151 } else { 152 s = n.GetBinaryLiteral().ToBitLiteralString(true) 153 } 154 default: 155 panic("Can't format to string") 156 } 157 _, _ = fmt.Fprint(w, s) 158 } 159 160 // newValueExpr creates a ValueExpr with value, and sets default field type. 161 func newValueExpr(value interface{}, charset string, collate string) ast.ValueExpr { 162 if ve, ok := value.(*ValueExpr); ok { 163 return ve 164 } 165 ve := &ValueExpr{} 166 ve.SetValue(value) 167 DefaultTypeForValue(value, &ve.Type, charset, collate) 168 ve.projectionOffset = -1 169 return ve 170 } 171 172 // SetProjectionOffset sets ValueExpr.projectionOffset for logical plan builder. 173 func (n *ValueExpr) SetProjectionOffset(offset int) { 174 n.projectionOffset = offset 175 } 176 177 // GetProjectionOffset returns ValueExpr.projectionOffset. 178 func (n *ValueExpr) GetProjectionOffset() int { 179 return n.projectionOffset 180 } 181 182 // Accept implements Node interface. 183 func (n *ValueExpr) Accept(v ast.Visitor) (ast.Node, bool) { 184 newNode, skipChildren := v.Enter(n) 185 if skipChildren { 186 return v.Leave(newNode) 187 } 188 n = newNode.(*ValueExpr) 189 return v.Leave(n) 190 } 191 192 // ParamMarkerExpr expression holds a place for another expression. 193 // Used in parsing prepare statement. 194 type ParamMarkerExpr struct { 195 ValueExpr 196 Offset int 197 Order int 198 InExecute bool 199 } 200 201 // Restore implements Node interface. 202 func (n *ParamMarkerExpr) Restore(ctx *format.RestoreCtx) error { 203 ctx.WritePlain("?") 204 return nil 205 } 206 207 func newParamMarkerExpr(offset int) ast.ParamMarkerExpr { 208 return &ParamMarkerExpr{ 209 Offset: offset, 210 } 211 } 212 213 // Format the ExprNode into a Writer. 214 func (n *ParamMarkerExpr) Format(w io.Writer) { 215 panic("Not implemented") 216 } 217 218 // Accept implements Node Accept interface. 219 func (n *ParamMarkerExpr) Accept(v ast.Visitor) (ast.Node, bool) { 220 newNode, skipChildren := v.Enter(n) 221 if skipChildren { 222 return v.Leave(newNode) 223 } 224 n = newNode.(*ParamMarkerExpr) 225 return v.Leave(n) 226 } 227 228 // SetOrder implements the ParamMarkerExpr interface. 229 func (n *ParamMarkerExpr) SetOrder(order int) { 230 n.Order = order 231 }