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  }