github.com/cockroachdb/cockroachdb-parser@v0.23.3-0.20240213214944-911057d40c9a/pkg/sql/sem/tree/prepare.go (about) 1 // Copyright 2016 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 tree 12 13 import "github.com/cockroachdb/cockroachdb-parser/pkg/sql/lexbase" 14 15 // Prepare represents a PREPARE statement. 16 type Prepare struct { 17 Name Name 18 Types []ResolvableTypeReference 19 Statement Statement 20 } 21 22 // Format implements the NodeFormatter interface. 23 func (node *Prepare) Format(ctx *FmtCtx) { 24 ctx.WriteString("PREPARE ") 25 ctx.FormatNode(&node.Name) 26 if len(node.Types) > 0 { 27 ctx.WriteString(" (") 28 for i, t := range node.Types { 29 if i > 0 { 30 ctx.WriteString(", ") 31 } 32 ctx.FormatTypeReference(t) 33 } 34 ctx.WriteRune(')') 35 } 36 ctx.WriteString(" AS ") 37 ctx.FormatNode(node.Statement) 38 } 39 40 // CannedOptPlan is used as the AST for a PREPARE .. AS OPT PLAN statement. 41 // This is a testing facility that allows execution (and benchmarking) of 42 // specific plans. See exprgen package for more information on the syntax. 43 type CannedOptPlan struct { 44 Plan string 45 } 46 47 // Format implements the NodeFormatter interface. 48 func (node *CannedOptPlan) Format(ctx *FmtCtx) { 49 // This node can only be used as the AST for a Prepare statement of the form: 50 // PREPARE name AS OPT PLAN '...'). 51 ctx.WriteString("OPT PLAN ") 52 ctx.WriteString(lexbase.EscapeSQLString(node.Plan)) 53 } 54 55 // Execute represents an EXECUTE statement. 56 type Execute struct { 57 Name Name 58 Params Exprs 59 // DiscardRows is set when we want to throw away all the rows rather than 60 // returning for client (used for testing and benchmarking). 61 DiscardRows bool 62 } 63 64 // Format implements the NodeFormatter interface. 65 func (node *Execute) Format(ctx *FmtCtx) { 66 ctx.WriteString("EXECUTE ") 67 ctx.FormatNode(&node.Name) 68 if len(node.Params) > 0 { 69 ctx.WriteString(" (") 70 ctx.FormatNode(&node.Params) 71 ctx.WriteByte(')') 72 } 73 if node.DiscardRows { 74 ctx.WriteString(" DISCARD ROWS") 75 } 76 } 77 78 // Deallocate represents a DEALLOCATE statement. 79 type Deallocate struct { 80 Name Name // empty for ALL 81 } 82 83 // Format implements the NodeFormatter interface. 84 func (node *Deallocate) Format(ctx *FmtCtx) { 85 ctx.WriteString("DEALLOCATE ") 86 if node.Name == "" { 87 ctx.WriteString("ALL") 88 } else { 89 // Special case for names in DEALLOCATE: the names are redacted in 90 // FmtHideConstants mode so that DEALLOCATE statements all show up together 91 // in the statement stats UI. The reason is that unlike other statements 92 // where the name being referenced is useful for observability, the name of 93 // a prepared statement doesn't matter that much. Also, it's extremely cheap 94 // to run DEALLOCATE, which can lead to thousands or more DEALLOCATE 95 // statements appearing in the UI; other statements that refer to things by 96 // name are too expensive for that to be a real problem. 97 if ctx.HasFlags(FmtHideConstants) { 98 ctx.WriteByte('_') 99 } else { 100 ctx.FormatNode(&node.Name) 101 } 102 } 103 }