github.com/cockroachdb/cockroachdb-parser@v0.23.3-0.20240213214944-911057d40c9a/pkg/sql/parser/statements/statement.go (about)

     1  // Copyright 2023 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  package statements
    12  
    13  import (
    14  	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/sem/plpgsqltree"
    15  	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/sem/tree"
    16  )
    17  
    18  type AST interface {
    19  }
    20  
    21  // Statement is the result of parsing a single statement. It contains the AST
    22  // node along with other information.
    23  type Statement[T any] struct {
    24  	// AST is the root of the AST tree for the parsed statement.
    25  	// Note that it is NOT SAFE to access this currently with statement execution,
    26  	// as unfortunately the AST is not immutable.
    27  	// See issue https://github.com/cockroachdb/cockroachdb-parser/issues/22847 for more
    28  	// details on this problem.
    29  	AST T
    30  
    31  	// Comments is the list of parsed SQL comments.
    32  	Comments []string
    33  
    34  	// SQL is the original SQL from which the statement was parsed. Note that this
    35  	// is not appropriate for use in logging, as it may contain passwords and
    36  	// other sensitive data.
    37  	SQL string
    38  
    39  	// NumPlaceholders indicates the number of arguments to the statement (which
    40  	// are referenced through placeholders). This corresponds to the highest
    41  	// argument position (i.e. the x in "$x") that appears in the query.
    42  	//
    43  	// Note: where there are "gaps" in the placeholder positions, this number is
    44  	// based on the highest position encountered. For example, for `SELECT $3`,
    45  	// NumPlaceholders is 3. These cases are malformed and will result in a
    46  	// type-check error.
    47  	NumPlaceholders int
    48  
    49  	// NumAnnotations indicates the number of annotations in the tree. It is equal
    50  	// to the maximum annotation index.
    51  	NumAnnotations tree.AnnotationIdx
    52  }
    53  
    54  // IsANSIDML returns true if the AST is one of the 4 DML statements,
    55  // SELECT, UPDATE, INSERT, DELETE, or an EXPLAIN of one of these statements.
    56  func IsANSIDML(stmt tree.Statement) bool {
    57  	switch t := stmt.(type) {
    58  	case *tree.Select, *tree.ParenSelect, *tree.Delete, *tree.Insert, *tree.Update:
    59  		return true
    60  	case *tree.Explain:
    61  		return IsANSIDML(t.Statement)
    62  	}
    63  	return false
    64  }
    65  
    66  // Statements is a list of parsed statements.
    67  type Statements []Statement[tree.Statement]
    68  
    69  type PLpgStatement Statement[*plpgsqltree.Block]
    70  
    71  // String returns the AST formatted as a string.
    72  func (stmts Statements) String() string {
    73  	return stmts.StringWithFlags(tree.FmtSimple)
    74  }
    75  
    76  // StringWithFlags returns the AST formatted as a string (with the given flags).
    77  func (stmts Statements) StringWithFlags(flags tree.FmtFlags) string {
    78  	ctx := tree.NewFmtCtx(flags)
    79  	for i, s := range stmts {
    80  		if i > 0 {
    81  			ctx.WriteString("; ")
    82  		}
    83  		ctx.FormatNode(s.AST)
    84  	}
    85  	return ctx.CloseAndGetString()
    86  }
    87  
    88  func (stmt PLpgStatement) String() string {
    89  	return stmt.StringWithFlags(tree.FmtSimple)
    90  }
    91  
    92  // StringWithFlags returns the AST formatted as a string (with the given flags).
    93  func (stmt PLpgStatement) StringWithFlags(flags tree.FmtFlags) string {
    94  	ctx := tree.NewFmtCtx(flags)
    95  	stmt.AST.Format(ctx)
    96  	return ctx.CloseAndGetString()
    97  }
    98  
    99  type ParsedStmts interface {
   100  	String() string
   101  	StringWithFlags(flags tree.FmtFlags) string
   102  }
   103  
   104  var _ ParsedStmts = Statements{}
   105  var _ ParsedStmts = PLpgStatement{}