github.com/dolthub/go-mysql-server@v0.18.0/sql/plan/values.go (about) 1 // Copyright 2020-2021 Dolthub, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package plan 16 17 import ( 18 "strings" 19 20 "github.com/dolthub/go-mysql-server/sql" 21 "github.com/dolthub/go-mysql-server/sql/expression" 22 ) 23 24 // Values represents a set of tuples of expressions. 25 type Values struct { 26 ExpressionTuples [][]sql.Expression 27 } 28 29 var _ sql.Node = (*Values)(nil) 30 var _ sql.CollationCoercible = (*Values)(nil) 31 32 // NewValues creates a Values node with the given tuples. 33 func NewValues(tuples [][]sql.Expression) *Values { 34 return &Values{tuples} 35 } 36 37 // Schema implements the Node interface. 38 func (p *Values) Schema() sql.Schema { 39 if len(p.ExpressionTuples) == 0 { 40 return nil 41 } 42 43 exprs := p.ExpressionTuples[0] 44 s := make(sql.Schema, len(exprs)) 45 for i, e := range exprs { 46 var name string 47 if n, ok := e.(sql.Nameable); ok { 48 name = n.Name() 49 } else { 50 name = e.String() 51 } 52 s[i] = &sql.Column{ 53 Name: name, 54 Type: e.Type(), 55 Nullable: e.IsNullable(), 56 } 57 } 58 59 return s 60 } 61 62 // Children implements the Node interface. 63 func (p *Values) Children() []sql.Node { 64 return nil 65 } 66 67 // Resolved implements the Resolvable interface. 68 func (p *Values) Resolved() bool { 69 for _, et := range p.ExpressionTuples { 70 if !expression.ExpressionsResolved(et...) { 71 return false 72 } 73 } 74 75 return true 76 } 77 78 func (p *Values) IsReadOnly() bool { 79 return true 80 } 81 82 // RowIter implements the Node interface. 83 func (p *Values) RowIter(ctx *sql.Context, row sql.Row) (sql.RowIter, error) { 84 rows := make([]sql.Row, len(p.ExpressionTuples)) 85 for i, et := range p.ExpressionTuples { 86 vals := make([]interface{}, len(et)) 87 for j, e := range et { 88 var err error 89 vals[j], err = e.Eval(ctx, row) 90 if err != nil { 91 return nil, err 92 } 93 } 94 95 rows[i] = sql.NewRow(vals...) 96 } 97 98 return sql.RowsToRowIter(rows...), nil 99 } 100 101 func (p *Values) String() string { 102 var sb strings.Builder 103 sb.WriteString("Values(") 104 for i, tuple := range p.ExpressionTuples { 105 if i > 0 { 106 sb.WriteString(",\n") 107 } 108 for j, e := range tuple { 109 if j > 0 { 110 sb.WriteString(",") 111 } 112 sb.WriteString(e.String()) 113 } 114 } 115 116 sb.WriteString(")") 117 return sb.String() 118 } 119 120 func (p *Values) DebugString() string { 121 var sb strings.Builder 122 sb.WriteString("Values(") 123 for i, tuple := range p.ExpressionTuples { 124 if i > 0 { 125 sb.WriteString(",\n") 126 } 127 sb.WriteRune('[') 128 for j, e := range tuple { 129 if j > 0 { 130 sb.WriteString(",") 131 } 132 sb.WriteString(sql.DebugString(e)) 133 } 134 sb.WriteRune(']') 135 } 136 137 sb.WriteString(")") 138 return sb.String() 139 } 140 141 // Expressions implements the Expressioner interface. 142 func (p *Values) Expressions() []sql.Expression { 143 var exprs []sql.Expression 144 for _, tuple := range p.ExpressionTuples { 145 exprs = append(exprs, tuple...) 146 } 147 return exprs 148 } 149 150 // WithChildren implements the Node interface. 151 func (p *Values) WithChildren(children ...sql.Node) (sql.Node, error) { 152 if len(children) != 0 { 153 return nil, sql.ErrInvalidChildrenNumber.New(p, len(children), 0) 154 } 155 156 return p, nil 157 } 158 159 // CheckPrivileges implements the interface sql.Node. 160 func (p *Values) CheckPrivileges(ctx *sql.Context, opChecker sql.PrivilegedOperationChecker) bool { 161 return true 162 } 163 164 // CollationCoercibility implements the interface sql.CollationCoercible. 165 func (*Values) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 166 return sql.Collation_binary, 7 167 } 168 169 // WithExpressions implements the Expressioner interface. 170 func (p *Values) WithExpressions(exprs ...sql.Expression) (sql.Node, error) { 171 var expected int 172 for _, t := range p.ExpressionTuples { 173 expected += len(t) 174 } 175 176 if len(exprs) != expected { 177 return nil, sql.ErrInvalidChildrenNumber.New(p, len(exprs), expected) 178 } 179 180 var offset int 181 var tuples = make([][]sql.Expression, len(p.ExpressionTuples)) 182 for i, t := range p.ExpressionTuples { 183 for range t { 184 tuples[i] = append(tuples[i], exprs[offset]) 185 offset++ 186 } 187 } 188 189 return NewValues(tuples), nil 190 }