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{}