Skip to content

Commit

Permalink
[parser] *: move github.com/pingcap/tidb/parser here (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
tiancaiamao authored and ti-chi-bot committed Oct 9, 2021
1 parent c3e896b commit c270f55
Show file tree
Hide file tree
Showing 59 changed files with 37,724 additions and 0 deletions.
25 changes: 25 additions & 0 deletions parser/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
.PHONEY: all parser goyacc

all: parser.go

parser.go: parser.y
make parser

parser: goyacc
bin/goyacc -o /dev/null parser.y
bin/goyacc -o parser.go parser.y 2>&1 | egrep "(shift|reduce)/reduce" | awk '{print} END {if (NR > 0) {print "Find conflict in parser.y. Please check y.output for more information."; exit 1;}}'
rm -f y.output

@if [ $(ARCH) = $(LINUX) ]; \
then \
sed -i -e 's|//line.*||' -e 's/yyEofCode/yyEOFCode/' parser.go; \
elif [ $(ARCH) = $(MAC) ]; \
then \
/usr/bin/sed -i "" 's|//line.*||' parser.go; \
/usr/bin/sed -i "" 's/yyEofCode/yyEOFCode/' parser.go; \
fi

@awk 'BEGIN{print "// Code generated by goyacc"} {print $0}' parser.go > tmp_parser.go && mv tmp_parser.go parser.go;

goyacc:
go build -o bin/goyacc goyacc/main.go
156 changes: 156 additions & 0 deletions parser/ast/ast.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
// Copyright 2015 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

// Package ast is the abstract syntax tree parsed from a SQL statement by parser.
// It can be analysed and transformed by optimizer.
package ast

import (
"io"

"github.com/pingcap/parser/model"
"github.com/pingcap/parser/types"
)

// Node is the basic element of the AST.
// Interfaces embed Node should have 'Node' name suffix.
type Node interface {
// Accept accepts Visitor to visit itself.
// The returned node should replace original node.
// ok returns false to stop visiting.
//
// Implementation of this method should first call visitor.Enter,
// assign the returned node to its method receiver, if skipChildren returns true,
// children should be skipped. Otherwise, call its children in particular order that
// later elements depends on former elements. Finally, return visitor.Leave.
Accept(v Visitor) (node Node, ok bool)
// Text returns the original text of the element.
Text() string
// SetText sets original text to the Node.
SetText(text string)
}

// Flags indicates whether an expression contains certain types of expression.
const (
FlagConstant uint64 = 0
FlagHasParamMarker uint64 = 1 << iota
FlagHasFunc
FlagHasReference
FlagHasAggregateFunc
FlagHasSubquery
FlagHasVariable
FlagHasDefault
FlagPreEvaluated
)

// ExprNode is a node that can be evaluated.
// Name of implementations should have 'Expr' suffix.
type ExprNode interface {
// Node is embedded in ExprNode.
Node
// SetType sets evaluation type to the expression.
SetType(tp *types.FieldType)
// GetType gets the evaluation type of the expression.
GetType() *types.FieldType
// SetFlag sets flag to the expression.
// Flag indicates whether the expression contains
// parameter marker, reference, aggregate function...
SetFlag(flag uint64)
// GetFlag returns the flag of the expression.
GetFlag() uint64

// Format formats the AST into a writer.
Format(w io.Writer)
}

// OptBinary is used for parser.
type OptBinary struct {
IsBinary bool
Charset string
}

// FuncNode represents function call expression node.
type FuncNode interface {
ExprNode
functionExpression()
}

// StmtNode represents statement node.
// Name of implementations should have 'Stmt' suffix.
type StmtNode interface {
Node
statement()
}

// DDLNode represents DDL statement node.
type DDLNode interface {
StmtNode
ddlStatement()
}

// DMLNode represents DML statement node.
type DMLNode interface {
StmtNode
dmlStatement()
}

// ResultField represents a result field which can be a column from a table,
// or an expression in select field. It is a generated property during
// binding process. ResultField is the key element to evaluate a ColumnNameExpr.
// After resolving process, every ColumnNameExpr will be resolved to a ResultField.
// During execution, every row retrieved from table will set the row value to
// ResultFields of that table, so ColumnNameExpr resolved to that ResultField can be
// easily evaluated.
type ResultField struct {
Column *model.ColumnInfo
ColumnAsName model.CIStr
Table *model.TableInfo
TableAsName model.CIStr
DBName model.CIStr

// Expr represents the expression for the result field. If it is generated from a select field, it would
// be the expression of that select field, otherwise the type would be ValueExpr and value
// will be set for every retrieved row.
Expr ExprNode
TableName *TableName
// Referenced indicates the result field has been referenced or not.
// If not, we don't need to get the values.
Referenced bool
}

// ResultSetNode interface has a ResultFields property, represents a Node that returns result set.
// Implementations include SelectStmt, SubqueryExpr, TableSource, TableName and Join.
type ResultSetNode interface {
Node
}

// SensitiveStmtNode overloads StmtNode and provides a SecureText method.
type SensitiveStmtNode interface {
StmtNode
// SecureText is different from Text that it hide password information.
SecureText() string
}

// Visitor visits a Node.
type Visitor interface {
// Enter is called before children nodes are visited.
// The returned node must be the same type as the input node n.
// skipChildren returns true means children nodes should be skipped,
// this is useful when work is done in Enter and there is no need to visit children.
Enter(n Node) (node Node, skipChildren bool)
// Leave is called after children nodes have been visited.
// The returned node's type can be different from the input node if it is a ExprNode,
// Non-expression node must be the same type as the input node n.
// ok returns false to stop visiting.
Leave(n Node) (node Node, ok bool)
}
101 changes: 101 additions & 0 deletions parser/ast/base.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// Copyright 2015 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

package ast

import "github.com/pingcap/parser/types"

// node is the struct implements node interface except for Accept method.
// Node implementations should embed it in.
type node struct {
text string
}

// SetText implements Node interface.
func (n *node) SetText(text string) {
n.text = text
}

// Text implements Node interface.
func (n *node) Text() string {
return n.text
}

// stmtNode implements StmtNode interface.
// Statement implementations should embed it in.
type stmtNode struct {
node
}

// statement implements StmtNode interface.
func (sn *stmtNode) statement() {}

// ddlNode implements DDLNode interface.
// DDL implementations should embed it in.
type ddlNode struct {
stmtNode
}

// ddlStatement implements DDLNode interface.
func (dn *ddlNode) ddlStatement() {}

// dmlNode is the struct implements DMLNode interface.
// DML implementations should embed it in.
type dmlNode struct {
stmtNode
}

// dmlStatement implements DMLNode interface.
func (dn *dmlNode) dmlStatement() {}

// exprNode is the struct implements Expression interface.
// Expression implementations should embed it in.
type exprNode struct {
node
Type types.FieldType
flag uint64
}

// TexprNode is exported for parser driver.
type TexprNode = exprNode

// SetType implements ExprNode interface.
func (en *exprNode) SetType(tp *types.FieldType) {
en.Type = *tp
}

// GetType implements ExprNode interface.
func (en *exprNode) GetType() *types.FieldType {
return &en.Type
}

// SetFlag implements ExprNode interface.
func (en *exprNode) SetFlag(flag uint64) {
en.flag = flag
}

// GetFlag implements ExprNode interface.
func (en *exprNode) GetFlag() uint64 {
return en.flag
}

type funcNode struct {
exprNode
}

// functionExpression implements FunctionNode interface.
func (fn *funcNode) functionExpression() {}

type resultSetNode struct {
resultFields []*ResultField
}
Loading

0 comments on commit c270f55

Please sign in to comment.