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  }