github.com/matrixorigin/matrixone@v1.2.0/pkg/sql/parsers/tree/constant.go (about)

     1  // Copyright 2021 Matrix Origin
     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  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package tree
    16  
    17  import (
    18  	"go/constant"
    19  	"strings"
    20  )
    21  
    22  // the AST for literals like string,numeric,bool and etc.
    23  type Constant interface {
    24  	Expr
    25  }
    26  
    27  type P_TYPE uint8
    28  
    29  const (
    30  	P_any P_TYPE = iota
    31  	P_hexnum
    32  	P_null
    33  	P_bool
    34  	P_int64
    35  	P_uint64
    36  	P_float64
    37  	P_char
    38  	P_decimal
    39  	P_bit
    40  	P_ScoreBinary
    41  	P_nulltext
    42  )
    43  
    44  // the AST for the constant numeric value.
    45  type NumVal struct {
    46  	Constant
    47  	Value constant.Value
    48  
    49  	// negative is the sign label
    50  	negative bool
    51  
    52  	// origString is the "original" string literals that should remain sign-less.
    53  	origString string
    54  
    55  	//converted result
    56  	resInt   int64
    57  	resFloat float64
    58  	ValType  P_TYPE
    59  }
    60  
    61  func (n *NumVal) OrigString() string {
    62  	return n.origString
    63  }
    64  
    65  func (n *NumVal) Format(ctx *FmtCtx) {
    66  	if n.origString != "" {
    67  		ctx.WriteValue(n.ValType, FormatString(n.origString))
    68  		return
    69  	}
    70  	switch n.Value.Kind() {
    71  	case constant.String:
    72  		ctx.WriteValue(n.ValType, n.origString)
    73  	case constant.Bool:
    74  		ctx.WriteString(strings.ToLower(n.Value.String()))
    75  	case constant.Unknown:
    76  		ctx.WriteString("null")
    77  	}
    78  }
    79  
    80  // Accept implements NodeChecker Accept interface.
    81  func (n *NumVal) Accept(v Visitor) (Expr, bool) {
    82  	newNode, skipChildren := v.Enter(n)
    83  	if skipChildren {
    84  		return v.Exit(newNode)
    85  	}
    86  	return v.Exit(n)
    87  }
    88  
    89  func FormatString(str string) string {
    90  	var buffer strings.Builder
    91  	for i, ch := range str {
    92  		if ch == '\n' {
    93  			buffer.WriteString("\\n")
    94  		} else if ch == '\x00' {
    95  			buffer.WriteString("\\0")
    96  		} else if ch == '\r' {
    97  			buffer.WriteString("\\r")
    98  		} else if ch == '\\' {
    99  			if (i + 1) < len(str) {
   100  				if str[i+1] == '_' || str[i+1] == '%' {
   101  					buffer.WriteByte('\\')
   102  					continue
   103  				}
   104  			}
   105  			buffer.WriteString("\\\\")
   106  		} else if ch == 8 {
   107  			buffer.WriteString("\\b")
   108  		} else if ch == 26 {
   109  			buffer.WriteString("\\Z")
   110  		} else if ch == '\t' {
   111  			buffer.WriteString("\\t")
   112  		} else {
   113  			// buffer.WriteByte(byte(ch))
   114  			buffer.WriteRune(ch)
   115  		}
   116  	}
   117  	res := buffer.String()
   118  	return res
   119  }
   120  
   121  func (n *NumVal) String() string {
   122  	return n.origString
   123  }
   124  
   125  func (n *NumVal) Negative() bool {
   126  	return n.negative
   127  }
   128  
   129  func NewNumVal(value constant.Value, origString string, negative bool) *NumVal {
   130  	return &NumVal{
   131  		Value:      value,
   132  		origString: origString,
   133  		negative:   negative,
   134  	}
   135  }
   136  
   137  func NewNumValWithType(value constant.Value, origString string, negative bool, typ P_TYPE) *NumVal {
   138  	numVal := &NumVal{
   139  		Value:      value,
   140  		origString: origString,
   141  		negative:   negative,
   142  		ValType:    typ,
   143  	}
   144  	return numVal
   145  }
   146  
   147  func NewNumValWithResInt(value constant.Value, origString string, negative bool, resInt int64) *NumVal {
   148  	return &NumVal{
   149  		Value:      value,
   150  		origString: origString,
   151  		negative:   negative,
   152  		resInt:     resInt,
   153  	}
   154  }
   155  
   156  func NewNumValWithResFoalt(value constant.Value, origString string, negative bool, resFloat float64) *NumVal {
   157  	return &NumVal{
   158  		Value:      value,
   159  		origString: origString,
   160  		negative:   negative,
   161  		resFloat:   resFloat,
   162  	}
   163  }
   164  
   165  // StrVal represents a constant string value.
   166  type StrVal struct {
   167  	Constant
   168  	str string
   169  }
   170  
   171  func (node *StrVal) Format(ctx *FmtCtx) {
   172  	ctx.WriteString(node.str)
   173  }
   174  
   175  // Accept implements NodeChecker Accept interface.
   176  func (node *StrVal) Accept(v Visitor) (Expr, bool) {
   177  	panic("unimplement StrVal Accept")
   178  }
   179  
   180  func NewStrVal(s string) *StrVal {
   181  	return &StrVal{str: s}
   182  }