github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/parser/parse.go (about)

     1  // Copyright 2012, Google Inc. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in licenses/BSD-vitess.txt.
     4  
     5  // Portions of this file are additionally subject to the following
     6  // license and copyright.
     7  //
     8  // Copyright 2015 The Cockroach Authors.
     9  //
    10  // Use of this software is governed by the Business Source License
    11  // included in the file licenses/BSL.txt.
    12  //
    13  // As of the Change Date specified in that file, in accordance with
    14  // the Business Source License, use of this software will be governed
    15  // by the Apache License, Version 2.0, included in the file
    16  // licenses/APL.txt.
    17  
    18  // This code was derived from https://github.com/youtube/vitess.
    19  
    20  package parser
    21  
    22  import (
    23  	"fmt"
    24  	"strings"
    25  
    26  	"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode"
    27  	"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror"
    28  	"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
    29  	"github.com/cockroachdb/cockroach/pkg/sql/types"
    30  	"github.com/cockroachdb/errors"
    31  )
    32  
    33  // Statement is the result of parsing a single statement. It contains the AST
    34  // node along with other information.
    35  type Statement struct {
    36  	// AST is the root of the AST tree for the parsed statement.
    37  	AST tree.Statement
    38  
    39  	// SQL is the original SQL from which the statement was parsed. Note that this
    40  	// is not appropriate for use in logging, as it may contain passwords and
    41  	// other sensitive data.
    42  	SQL string
    43  
    44  	// NumPlaceholders indicates the number of arguments to the statement (which
    45  	// are referenced through placeholders). This corresponds to the highest
    46  	// argument position (i.e. the x in "$x") that appears in the query.
    47  	//
    48  	// Note: where there are "gaps" in the placeholder positions, this number is
    49  	// based on the highest position encountered. For example, for `SELECT $3`,
    50  	// NumPlaceholders is 3. These cases are malformed and will result in a
    51  	// type-check error.
    52  	NumPlaceholders int
    53  
    54  	// NumAnnotations indicates the number of annotations in the tree. It is equal
    55  	// to the maximum annotation index.
    56  	NumAnnotations tree.AnnotationIdx
    57  }
    58  
    59  // Statements is a list of parsed statements.
    60  type Statements []Statement
    61  
    62  // String returns the AST formatted as a string.
    63  func (stmts Statements) String() string {
    64  	return stmts.StringWithFlags(tree.FmtSimple)
    65  }
    66  
    67  // StringWithFlags returns the AST formatted as a string (with the given flags).
    68  func (stmts Statements) StringWithFlags(flags tree.FmtFlags) string {
    69  	ctx := tree.NewFmtCtx(flags)
    70  	for i, s := range stmts {
    71  		if i > 0 {
    72  			ctx.WriteString("; ")
    73  		}
    74  		ctx.FormatNode(s.AST)
    75  	}
    76  	return ctx.CloseAndGetString()
    77  }
    78  
    79  // Parser wraps a scanner, parser and other utilities present in the parser
    80  // package.
    81  type Parser struct {
    82  	scanner    scanner
    83  	lexer      lexer
    84  	parserImpl sqlParserImpl
    85  	tokBuf     [8]sqlSymType
    86  	stmtBuf    [1]Statement
    87  }
    88  
    89  // INT8 is the historical interpretation of INT. This should be left
    90  // alone in the future, since there are many sql fragments stored
    91  // in various descriptors.  Any user input that was created after
    92  // INT := INT4 will simply use INT4 in any resulting code.
    93  var defaultNakedIntType = types.Int
    94  
    95  // Parse parses the sql and returns a list of statements.
    96  func (p *Parser) Parse(sql string) (Statements, error) {
    97  	return p.parseWithDepth(1, sql, defaultNakedIntType)
    98  }
    99  
   100  // ParseWithInt parses a sql statement string and returns a list of
   101  // Statements. The INT token will result in the specified TInt type.
   102  func (p *Parser) ParseWithInt(sql string, nakedIntType *types.T) (Statements, error) {
   103  	return p.parseWithDepth(1, sql, nakedIntType)
   104  }
   105  
   106  func (p *Parser) parseOneWithDepth(depth int, sql string) (Statement, error) {
   107  	stmts, err := p.parseWithDepth(1, sql, defaultNakedIntType)
   108  	if err != nil {
   109  		return Statement{}, err
   110  	}
   111  	if len(stmts) != 1 {
   112  		return Statement{}, errors.AssertionFailedf("expected 1 statement, but found %d", len(stmts))
   113  	}
   114  	return stmts[0], nil
   115  }
   116  
   117  func (p *Parser) scanOneStmt() (sql string, tokens []sqlSymType, done bool) {
   118  	var lval sqlSymType
   119  	tokens = p.tokBuf[:0]
   120  
   121  	// Scan the first token.
   122  	for {
   123  		p.scanner.scan(&lval)
   124  		if lval.id == 0 {
   125  			return "", nil, true
   126  		}
   127  		if lval.id != ';' {
   128  			break
   129  		}
   130  	}
   131  
   132  	startPos := lval.pos
   133  	// We make the resulting token positions match the returned string.
   134  	lval.pos = 0
   135  	tokens = append(tokens, lval)
   136  	for {
   137  		if lval.id == ERROR {
   138  			return p.scanner.in[startPos:], tokens, true
   139  		}
   140  		posBeforeScan := p.scanner.pos
   141  		p.scanner.scan(&lval)
   142  		if lval.id == 0 || lval.id == ';' {
   143  			return p.scanner.in[startPos:posBeforeScan], tokens, (lval.id == 0)
   144  		}
   145  		lval.pos -= startPos
   146  		tokens = append(tokens, lval)
   147  	}
   148  }
   149  
   150  func (p *Parser) parseWithDepth(depth int, sql string, nakedIntType *types.T) (Statements, error) {
   151  	stmts := Statements(p.stmtBuf[:0])
   152  	p.scanner.init(sql)
   153  	defer p.scanner.cleanup()
   154  	for {
   155  		sql, tokens, done := p.scanOneStmt()
   156  		stmt, err := p.parse(depth+1, sql, tokens, nakedIntType)
   157  		if err != nil {
   158  			return nil, err
   159  		}
   160  		if stmt.AST != nil {
   161  			stmts = append(stmts, stmt)
   162  		}
   163  		if done {
   164  			break
   165  		}
   166  	}
   167  	return stmts, nil
   168  }
   169  
   170  // parse parses a statement from the given scanned tokens.
   171  func (p *Parser) parse(
   172  	depth int, sql string, tokens []sqlSymType, nakedIntType *types.T,
   173  ) (Statement, error) {
   174  	p.lexer.init(sql, tokens, nakedIntType)
   175  	defer p.lexer.cleanup()
   176  	if p.parserImpl.Parse(&p.lexer) != 0 {
   177  		if p.lexer.lastError == nil {
   178  			// This should never happen -- there should be an error object
   179  			// every time Parse() returns nonzero. We're just playing safe
   180  			// here.
   181  			p.lexer.Error("syntax error")
   182  		}
   183  		err := p.lexer.lastError
   184  
   185  		// Compatibility with 19.1 telemetry: prefix the telemetry keys
   186  		// with the "syntax." prefix.
   187  		// TODO(knz): move the auto-prefixing of feature names to a
   188  		// higher level in the call stack.
   189  		tkeys := errors.GetTelemetryKeys(err)
   190  		if len(tkeys) > 0 {
   191  			for i := range tkeys {
   192  				tkeys[i] = "syntax." + tkeys[i]
   193  			}
   194  			err = errors.WithTelemetry(err, tkeys...)
   195  		}
   196  
   197  		return Statement{}, err
   198  	}
   199  	return Statement{
   200  		AST:             p.lexer.stmt,
   201  		SQL:             sql,
   202  		NumPlaceholders: p.lexer.numPlaceholders,
   203  		NumAnnotations:  p.lexer.numAnnotations,
   204  	}, nil
   205  }
   206  
   207  // unaryNegation constructs an AST node for a negation. This attempts
   208  // to preserve constant NumVals and embed the negative sign inside
   209  // them instead of wrapping in an UnaryExpr. This in turn ensures
   210  // that negative numbers get considered as a single constant
   211  // for the purpose of formatting and scrubbing.
   212  func unaryNegation(e tree.Expr) tree.Expr {
   213  	if cst, ok := e.(*tree.NumVal); ok {
   214  		cst.Negate()
   215  		return cst
   216  	}
   217  
   218  	// Common case.
   219  	return &tree.UnaryExpr{Operator: tree.UnaryMinus, Expr: e}
   220  }
   221  
   222  // Parse parses a sql statement string and returns a list of Statements.
   223  func Parse(sql string) (Statements, error) {
   224  	var p Parser
   225  	return p.parseWithDepth(1, sql, defaultNakedIntType)
   226  }
   227  
   228  // ParseOne parses a sql statement string, ensuring that it contains only a
   229  // single statement, and returns that Statement. ParseOne will always
   230  // interpret the INT and SERIAL types as 64-bit types, since this is
   231  // used in various internal-execution paths where we might receive
   232  // bits of SQL from other nodes. In general, we expect that all
   233  // user-generated SQL has been run through the ParseWithInt() function.
   234  func ParseOne(sql string) (Statement, error) {
   235  	var p Parser
   236  	return p.parseOneWithDepth(1, sql)
   237  }
   238  
   239  // ParseQualifiedTableName parses a SQL string of the form
   240  // `[ database_name . ] [ schema_name . ] table_name`.
   241  func ParseQualifiedTableName(sql string) (*tree.TableName, error) {
   242  	name, err := ParseTableName(sql)
   243  	if err != nil {
   244  		return nil, err
   245  	}
   246  	tn := name.ToTableName()
   247  	return &tn, nil
   248  }
   249  
   250  // ParseTableName parses a table name.
   251  func ParseTableName(sql string) (*tree.UnresolvedObjectName, error) {
   252  	// We wrap the name we want to parse into a dummy statement since our parser
   253  	// can only parse full statements.
   254  	stmt, err := ParseOne(fmt.Sprintf("ALTER TABLE %s RENAME TO x", sql))
   255  	if err != nil {
   256  		return nil, err
   257  	}
   258  	rename, ok := stmt.AST.(*tree.RenameTable)
   259  	if !ok {
   260  		return nil, errors.AssertionFailedf("expected an ALTER TABLE statement, but found %T", stmt)
   261  	}
   262  	return rename.Name, nil
   263  }
   264  
   265  // parseExprs parses one or more sql expressions.
   266  func parseExprs(exprs []string) (tree.Exprs, error) {
   267  	stmt, err := ParseOne(fmt.Sprintf("SET ROW (%s)", strings.Join(exprs, ",")))
   268  	if err != nil {
   269  		return nil, err
   270  	}
   271  	set, ok := stmt.AST.(*tree.SetVar)
   272  	if !ok {
   273  		return nil, errors.AssertionFailedf("expected a SET statement, but found %T", stmt)
   274  	}
   275  	return set.Values, nil
   276  }
   277  
   278  // ParseExprs is a short-hand for parseExprs(sql)
   279  func ParseExprs(sql []string) (tree.Exprs, error) {
   280  	if len(sql) == 0 {
   281  		return tree.Exprs{}, nil
   282  	}
   283  	return parseExprs(sql)
   284  }
   285  
   286  // ParseExpr is a short-hand for parseExprs([]string{sql})
   287  func ParseExpr(sql string) (tree.Expr, error) {
   288  	exprs, err := parseExprs([]string{sql})
   289  	if err != nil {
   290  		return nil, err
   291  	}
   292  	if len(exprs) != 1 {
   293  		return nil, errors.AssertionFailedf("expected 1 expression, found %d", len(exprs))
   294  	}
   295  	return exprs[0], nil
   296  }
   297  
   298  // ParseType parses a column type.
   299  func ParseType(sql string) (tree.ResolvableTypeReference, error) {
   300  	expr, err := ParseExpr(fmt.Sprintf("1::%s", sql))
   301  	if err != nil {
   302  		return nil, err
   303  	}
   304  
   305  	cast, ok := expr.(*tree.CastExpr)
   306  	if !ok {
   307  		return nil, errors.AssertionFailedf("expected a tree.CastExpr, but found %T", expr)
   308  	}
   309  
   310  	return cast.Type, nil
   311  }
   312  
   313  var errBitLengthNotPositive = pgerror.WithCandidateCode(
   314  	errors.New("length for type bit must be at least 1"), pgcode.InvalidParameterValue)
   315  
   316  // newBitType creates a new BIT type with the given bit width.
   317  func newBitType(width int32, varying bool) (*types.T, error) {
   318  	if width < 1 {
   319  		return nil, errBitLengthNotPositive
   320  	}
   321  	if varying {
   322  		return types.MakeVarBit(width), nil
   323  	}
   324  	return types.MakeBit(width), nil
   325  }
   326  
   327  var errFloatPrecAtLeast1 = pgerror.WithCandidateCode(
   328  	errors.New("precision for type float must be at least 1 bit"), pgcode.InvalidParameterValue)
   329  var errFloatPrecMax54 = pgerror.WithCandidateCode(
   330  	errors.New("precision for type float must be less than 54 bits"), pgcode.InvalidParameterValue)
   331  
   332  // newFloat creates a type for FLOAT with the given precision.
   333  func newFloat(prec int64) (*types.T, error) {
   334  	if prec < 1 {
   335  		return nil, errFloatPrecAtLeast1
   336  	}
   337  	if prec <= 24 {
   338  		return types.Float4, nil
   339  	}
   340  	if prec <= 54 {
   341  		return types.Float, nil
   342  	}
   343  	return nil, errFloatPrecMax54
   344  }
   345  
   346  // newDecimal creates a type for DECIMAL with the given precision and scale.
   347  func newDecimal(prec, scale int32) (*types.T, error) {
   348  	if scale > prec {
   349  		err := pgerror.WithCandidateCode(
   350  			errors.Newf("scale (%d) must be between 0 and precision (%d)", scale, prec),
   351  			pgcode.InvalidParameterValue)
   352  		return nil, err
   353  	}
   354  	return types.MakeDecimal(prec, scale), nil
   355  }
   356  
   357  // arrayOf creates a type alias for an array of the given element type and fixed
   358  // bounds. The bounds are currently ignored.
   359  func arrayOf(
   360  	ref tree.ResolvableTypeReference, bounds []int32,
   361  ) (tree.ResolvableTypeReference, error) {
   362  	// If the reference is a statically known type, then return an array type,
   363  	// rather than an array type reference.
   364  	if typ, ok := tree.GetStaticallyKnownType(ref); ok {
   365  		if err := types.CheckArrayElementType(typ); err != nil {
   366  			return nil, err
   367  		}
   368  		return types.MakeArray(typ), nil
   369  	}
   370  	return &tree.ArrayTypeReference{ElementType: ref}, nil
   371  }