github.com/cockroachdb/cockroachdb-parser@v0.23.3-0.20240213214944-911057d40c9a/pkg/sql/sem/tree/insert.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 tree 21 22 // Insert represents an INSERT statement. 23 type Insert struct { 24 With *With 25 Table TableExpr 26 Columns NameList 27 Rows *Select 28 OnConflict *OnConflict 29 Returning ReturningClause 30 } 31 32 // Format implements the NodeFormatter interface. 33 func (node *Insert) Format(ctx *FmtCtx) { 34 ctx.FormatNode(node.With) 35 if node.OnConflict.IsUpsertAlias() { 36 ctx.WriteString("UPSERT") 37 } else { 38 ctx.WriteString("INSERT") 39 } 40 ctx.WriteString(" INTO ") 41 ctx.FormatNode(node.Table) 42 if node.Columns != nil { 43 ctx.WriteByte('(') 44 ctx.FormatNode(&node.Columns) 45 ctx.WriteByte(')') 46 } 47 if node.DefaultValues() { 48 ctx.WriteString(" DEFAULT VALUES") 49 } else { 50 ctx.WriteByte(' ') 51 ctx.FormatNode(node.Rows) 52 } 53 if node.OnConflict != nil && !node.OnConflict.IsUpsertAlias() { 54 ctx.WriteString(" ON CONFLICT") 55 if node.OnConflict.Constraint != "" { 56 ctx.WriteString(" ON CONSTRAINT ") 57 ctx.FormatNode(&node.OnConflict.Constraint) 58 } 59 if len(node.OnConflict.Columns) > 0 { 60 ctx.WriteString(" (") 61 ctx.FormatNode(&node.OnConflict.Columns) 62 ctx.WriteString(")") 63 } 64 if node.OnConflict.ArbiterPredicate != nil { 65 ctx.WriteString(" WHERE ") 66 ctx.FormatNode(node.OnConflict.ArbiterPredicate) 67 } 68 if node.OnConflict.DoNothing { 69 ctx.WriteString(" DO NOTHING") 70 } else { 71 ctx.WriteString(" DO UPDATE SET ") 72 ctx.FormatNode(&node.OnConflict.Exprs) 73 if node.OnConflict.Where != nil { 74 ctx.WriteByte(' ') 75 ctx.FormatNode(node.OnConflict.Where) 76 } 77 } 78 } 79 if HasReturningClause(node.Returning) { 80 ctx.WriteByte(' ') 81 ctx.FormatNode(node.Returning) 82 } 83 } 84 85 // DefaultValues returns true iff only default values are being inserted. 86 func (node *Insert) DefaultValues() bool { 87 return node.Rows.Select == nil 88 } 89 90 // OnConflict represents an `ON CONFLICT (columns) WHERE arbiter DO UPDATE SET 91 // exprs WHERE where` clause. 92 // 93 // The zero value for OnConflict is used to signal the UPSERT short form, which 94 // uses the primary key for as the conflict index and the values being inserted 95 // for Exprs. 96 type OnConflict struct { 97 // At most one of Columns and Constraint will be set at once. 98 // Columns is the list of arbiter columns, if set, that the user specified 99 // in the ON CONFLICT (columns) list. 100 Columns NameList 101 // Constraint is the name of a table constraint that the user specified to 102 // get the list of arbiter columns from, in the ON CONFLICT ON CONSTRAINT 103 // form. 104 Constraint Name 105 ArbiterPredicate Expr 106 Exprs UpdateExprs 107 Where *Where 108 DoNothing bool 109 } 110 111 // IsUpsertAlias returns true if the UPSERT syntactic sugar was used. 112 func (oc *OnConflict) IsUpsertAlias() bool { 113 return oc != nil && oc.Columns == nil && oc.Constraint == "" && 114 oc.ArbiterPredicate == nil && oc.Exprs == nil && oc.Where == nil && !oc.DoNothing 115 }