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  }