1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- package dolphin
- import (
- "errors"
- "io"
- "regexp"
- "strconv"
- "strings"
- "github.com/pingcap/parser"
- _ "github.com/pingcap/parser/test_driver"
- "github.com/kyleconroy/sqlc/internal/metadata"
- "github.com/kyleconroy/sqlc/internal/sql/ast"
- "github.com/kyleconroy/sqlc/internal/sql/sqlerr"
- )
- func NewParser() *Parser {
- return &Parser{parser.New()}
- }
- type Parser struct {
- pingcap *parser.Parser
- }
- var lineColumn = regexp.MustCompile(`^line (\d+) column (\d+) (.*)`)
- func normalizeErr(err error) error {
- if err == nil {
- return err
- }
- parts := strings.Split(err.Error(), "\n")
- msg := strings.TrimSpace(parts[0] + "\"")
- out := lineColumn.FindStringSubmatch(msg)
- if len(out) == 4 {
- line, lineErr := strconv.Atoi(out[1])
- col, colErr := strconv.Atoi(out[2])
- if lineErr != nil || colErr != nil {
- return errors.New(msg)
- }
- return &sqlerr.Error{
- Message: "syntax error",
- Err: errors.New(out[3]),
- Line: line,
- Column: col,
- }
- }
- return errors.New(msg)
- }
- func (p *Parser) Parse(r io.Reader) ([]ast.Statement, error) {
- blob, err := io.ReadAll(r)
- if err != nil {
- return nil, err
- }
- stmtNodes, _, err := p.pingcap.Parse(string(blob), "", "")
- if err != nil {
- return nil, normalizeErr(err)
- }
- var stmts []ast.Statement
- for i := range stmtNodes {
- converter := &cc{}
- out := converter.convert(stmtNodes[i])
- if _, ok := out.(*ast.TODO); ok {
- continue
- }
- // TODO: Attach the text directly to the ast.Statement node
- text := stmtNodes[i].Text()
- loc := strings.Index(string(blob), text)
- stmtLen := len(text)
- if text[stmtLen-1] == ';' {
- stmtLen -= 1 // Subtract one to remove semicolon
- }
- stmts = append(stmts, ast.Statement{
- Raw: &ast.RawStmt{
- Stmt: out,
- StmtLocation: loc,
- StmtLen: stmtLen,
- },
- })
- }
- return stmts, nil
- }
- // https://dev.mysql.com/doc/refman/8.0/en/comments.html
- func (p *Parser) CommentSyntax() metadata.CommentSyntax {
- return metadata.CommentSyntax{
- Dash: true,
- SlashStar: true,
- Hash: true,
- }
- }
|