github.com/matrixorigin/matrixone@v0.7.0/pkg/sql/parsers/dialect/mysql/mysql_lexer.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 mysql
    16  
    17  import (
    18  	"context"
    19  	"fmt"
    20  	"math"
    21  	"strconv"
    22  
    23  	"github.com/matrixorigin/matrixone/pkg/common/moerr"
    24  	"github.com/matrixorigin/matrixone/pkg/sql/parsers/dialect"
    25  	"github.com/matrixorigin/matrixone/pkg/sql/parsers/tree"
    26  )
    27  
    28  func Parse(ctx context.Context, sql string) ([]tree.Statement, error) {
    29  	lexer := NewLexer(dialect.MYSQL, sql)
    30  	if yyParse(lexer) != 0 {
    31  		return nil, lexer.scanner.LastError
    32  	}
    33  	if len(lexer.stmts) == 0 {
    34  		return nil, moerr.NewParseError(ctx, "Query was empty")
    35  	}
    36  	return lexer.stmts, nil
    37  }
    38  
    39  func ParseOne(ctx context.Context, sql string) (tree.Statement, error) {
    40  	lexer := NewLexer(dialect.MYSQL, sql)
    41  	if yyParse(lexer) != 0 {
    42  		return nil, lexer.scanner.LastError
    43  	}
    44  	if len(lexer.stmts) != 1 {
    45  		return nil, moerr.NewParseError(ctx, "syntax error, or too many sql to parse")
    46  	}
    47  	return lexer.stmts[0], nil
    48  }
    49  
    50  type Lexer struct {
    51  	scanner    *Scanner
    52  	stmts      []tree.Statement
    53  	paramIndex int
    54  }
    55  
    56  func NewLexer(dialectType dialect.DialectType, sql string) *Lexer {
    57  	return &Lexer{
    58  		scanner:    NewScanner(dialectType, sql),
    59  		paramIndex: 0,
    60  	}
    61  }
    62  
    63  func (l *Lexer) GetParamIndex() int {
    64  	l.paramIndex = l.paramIndex + 1
    65  	return l.paramIndex
    66  }
    67  
    68  func (l *Lexer) Lex(lval *yySymType) int {
    69  	typ, str := l.scanner.Scan()
    70  	l.scanner.LastToken = str
    71  
    72  	switch typ {
    73  	case INTEGRAL:
    74  		return l.toInt(lval, str)
    75  	case FLOAT:
    76  		return l.toFloat(lval, str)
    77  	case HEX:
    78  		return l.toHex(lval, str)
    79  	case HEXNUM:
    80  		return l.toHexNum(lval, str)
    81  	case BIT_LITERAL:
    82  		return l.toBit(lval, str)
    83  	}
    84  
    85  	lval.str = str
    86  	return typ
    87  }
    88  
    89  func (l *Lexer) Error(err string) {
    90  	errMsg := fmt.Sprintf("You have an error in your SQL syntax; check the manual that corresponds to your MatrixOne server version for the right syntax to use. %s", err)
    91  	near := l.scanner.buf[l.scanner.PrePos:]
    92  	var lenStr string
    93  	if len(near) > 1024 {
    94  		lenStr = " (total length " + strconv.Itoa(len(lenStr)) + ")"
    95  		near = near[:1024]
    96  	}
    97  	l.scanner.LastError = PositionedErr{Err: errMsg, Line: l.scanner.Line, Col: l.scanner.Col, Near: near, LenStr: lenStr}
    98  }
    99  
   100  func (l *Lexer) AppendStmt(stmt tree.Statement) {
   101  	l.stmts = append(l.stmts, stmt)
   102  }
   103  
   104  func (l *Lexer) toInt(lval *yySymType, str string) int {
   105  	ival, err := strconv.ParseUint(str, 10, 64)
   106  	if err != nil {
   107  		// TODO: toDecimal()
   108  		// l.scanner.LastError = err
   109  		lval.str = str
   110  		return DECIMAL_VALUE
   111  	}
   112  	switch {
   113  	case ival <= math.MaxInt64:
   114  		lval.item = int64(ival)
   115  	default:
   116  		lval.item = ival
   117  	}
   118  	lval.str = str
   119  	return INTEGRAL
   120  }
   121  
   122  func (l *Lexer) toFloat(lval *yySymType, str string) int {
   123  	fval, err := strconv.ParseFloat(str, 64)
   124  	if err != nil {
   125  		l.scanner.LastError = err
   126  		return LEX_ERROR
   127  	}
   128  	lval.item = fval
   129  	return FLOAT
   130  }
   131  
   132  func (l *Lexer) toHex(lval *yySymType, str string) int {
   133  	return HEX
   134  }
   135  
   136  // don't transfer 0xXXX to int,uint, all string([]byte),for example
   137  // 0x0616161 will be ' aaa'
   138  func (l *Lexer) toHexNum(lval *yySymType, str string) int {
   139  	// it won't be err, no need to process
   140  	// ival, err := strconv.ParseUint(str[2:], 16, 64)
   141  	// if err != nil {
   142  	// 	// TODO: toDecimal()
   143  	// 	//l.scanner.LastError = err
   144  	// 	lval.item = str
   145  	// 	return HEXNUM
   146  	// }
   147  	// switch {
   148  	// case ival <= math.MaxInt64:
   149  	// 	lval.item = int64(ival)
   150  	// default:
   151  	// 	lval.item = ival
   152  	// }
   153  	// lval.str = str
   154  	lval.str = str
   155  	return HEXNUM
   156  }
   157  
   158  func (l *Lexer) toBit(lval *yySymType, str string) int {
   159  	var (
   160  		ival uint64
   161  		err  error
   162  	)
   163  	if len(str) < 2 {
   164  		ival, err = strconv.ParseUint(str, 2, 64)
   165  	} else if str[1] == 'b' {
   166  		ival, err = strconv.ParseUint(str[2:], 2, 64)
   167  	} else {
   168  		ival, err = strconv.ParseUint(str, 2, 64)
   169  	}
   170  
   171  	if err != nil {
   172  		// TODO: toDecimal()
   173  		//l.scanner.LastError = err
   174  		lval.item = str
   175  		return BIT_LITERAL
   176  	}
   177  	switch {
   178  	case ival <= math.MaxInt64:
   179  		lval.item = int64(ival)
   180  	default:
   181  		lval.item = ival
   182  	}
   183  	lval.str = str
   184  	return BIT_LITERAL
   185  }