github.com/dolthub/dolt/go@v0.40.5-0.20240520175717-68db7794bea6/libraries/doltcore/sqle/schema_util_test.go (about)

     1  // Copyright 2020 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 sqle
    16  
    17  import (
    18  	"fmt"
    19  	"strconv"
    20  
    21  	"github.com/dolthub/dolt/go/libraries/doltcore/row"
    22  	"github.com/dolthub/dolt/go/libraries/doltcore/schema"
    23  	"github.com/dolthub/dolt/go/store/types"
    24  )
    25  
    26  // Creates a new schema for a result set specified by the given pairs of column names and types. Column names are
    27  // strings, types are NomsKinds.
    28  func NewResultSetSchema(colNamesAndTypes ...interface{}) schema.Schema {
    29  	if len(colNamesAndTypes)%2 != 0 {
    30  		panic("Non-even number of inputs passed to NewResultSetSchema")
    31  	}
    32  
    33  	cols := make([]schema.Column, len(colNamesAndTypes)/2)
    34  	for i := 0; i < len(colNamesAndTypes); i += 2 {
    35  		name := colNamesAndTypes[i].(string)
    36  		nomsKind := colNamesAndTypes[i+1].(types.NomsKind)
    37  		cols[i/2] = schema.NewColumn(name, uint64(i/2), nomsKind, false)
    38  	}
    39  
    40  	collection := schema.NewColCollection(cols...)
    41  	return schema.UnkeyedSchemaFromCols(collection)
    42  }
    43  
    44  // Creates a new row for a result set specified by the given values
    45  func NewResultSetRow(colVals ...types.Value) row.Row {
    46  	taggedVals := make(row.TaggedValues)
    47  	cols := make([]schema.Column, len(colVals))
    48  	for i := 0; i < len(colVals); i++ {
    49  		taggedVals[uint64(i)] = colVals[i]
    50  		nomsKind := colVals[i].Kind()
    51  		cols[i] = schema.NewColumn(fmt.Sprintf("%v", i), uint64(i), nomsKind, false)
    52  	}
    53  
    54  	collection := schema.NewColCollection(cols...)
    55  	sch := schema.UnkeyedSchemaFromCols(collection)
    56  
    57  	r, err := row.New(types.Format_Default, sch, taggedVals)
    58  
    59  	if err != nil {
    60  		panic(err)
    61  	}
    62  
    63  	return r
    64  }
    65  
    66  // NewRow creates a new row with the values given, using ascending tag numbers starting at 0.
    67  // Uses the first value as the primary key.
    68  func NewRow(colVals ...types.Value) row.Row {
    69  	return NewRowWithPks(colVals[0:1], colVals[1:]...)
    70  }
    71  
    72  // NewRowWithPks creates a new row with the values given, using ascending tag numbers starting at 0.
    73  func NewRowWithPks(pkColVals []types.Value, nonPkVals ...types.Value) row.Row {
    74  	var cols []schema.Column
    75  	taggedVals := make(row.TaggedValues)
    76  	var tag int64
    77  
    78  	for _, val := range pkColVals {
    79  		var constraints []schema.ColConstraint
    80  		constraints = append(constraints, schema.NotNullConstraint{})
    81  		cols = append(cols, schema.NewColumn(strconv.FormatInt(tag, 10), uint64(tag), val.Kind(), true, constraints...))
    82  		taggedVals[uint64(tag)] = val
    83  		tag++
    84  	}
    85  
    86  	for _, val := range nonPkVals {
    87  		cols = append(cols, schema.NewColumn(strconv.FormatInt(tag, 10), uint64(tag), val.Kind(), false))
    88  		taggedVals[uint64(tag)] = val
    89  		tag++
    90  	}
    91  
    92  	colColl := schema.NewColCollection(cols...)
    93  	sch := schema.MustSchemaFromCols(colColl)
    94  
    95  	r, err := row.New(types.Format_Default, sch, taggedVals)
    96  
    97  	if err != nil {
    98  		panic(err)
    99  	}
   100  
   101  	return r
   102  }
   103  
   104  // NewRowWithSchema creates a new row with the using the provided schema.
   105  func NewRowWithSchema(sch schema.Schema, vals ...types.Value) row.Row {
   106  	tv := make(row.TaggedValues)
   107  	var i int
   108  	sch.GetAllCols().Iter(func(tag uint64, col schema.Column) (stop bool, err error) {
   109  		tv[tag] = vals[i]
   110  		i++
   111  		return false, nil
   112  	})
   113  
   114  	r, err := row.New(types.Format_Default, sch, tv)
   115  	if err != nil {
   116  		panic(err)
   117  	}
   118  
   119  	return r
   120  }
   121  
   122  // NewSchema creates a new schema with the pairs of column names and types given.
   123  // Uses the first column as the primary key.
   124  func NewSchema(colNamesAndTypes ...interface{}) schema.Schema {
   125  	return NewSchemaForTable("", colNamesAndTypes...)
   126  }
   127  
   128  // NewSchemaForTable creates a new schema for the table with the name given with the pairs of column names and types
   129  // given. Uses the first column as the primary key.
   130  func NewSchemaForTable(tableName string, colNamesAndTypes ...interface{}) schema.Schema {
   131  	if len(colNamesAndTypes)%2 != 0 {
   132  		panic("Non-even number of inputs passed to NewSchema")
   133  	}
   134  
   135  	// existingTags *set.Uint64Set, tableName string, existingColKinds []types.NomsKind, newColName string, newColKind types.NomsKind
   136  	nomsKinds := make([]types.NomsKind, 0)
   137  	tags := make(schema.TagMapping)
   138  
   139  	cols := make([]schema.Column, len(colNamesAndTypes)/2)
   140  	for i := 0; i < len(colNamesAndTypes); i += 2 {
   141  		name := colNamesAndTypes[i].(string)
   142  		nomsKind := colNamesAndTypes[i+1].(types.NomsKind)
   143  
   144  		tag := schema.AutoGenerateTag(tags, tableName, nomsKinds, name, nomsKind)
   145  		tags.Add(tag, tableName)
   146  		nomsKinds = append(nomsKinds, nomsKind)
   147  
   148  		isPk := i/2 == 0
   149  		var constraints []schema.ColConstraint
   150  		if isPk {
   151  			constraints = append(constraints, schema.NotNullConstraint{})
   152  		}
   153  		cols[i/2] = schema.NewColumn(name, tag, nomsKind, isPk, constraints...)
   154  	}
   155  
   156  	colColl := schema.NewColCollection(cols...)
   157  	return schema.MustSchemaFromCols(colColl)
   158  }
   159  
   160  // Returns the logical concatenation of the schemas and rows given, rewriting all tag numbers to begin at zero. The row
   161  // returned will have a new schema identical to the result of compressSchema.
   162  func ConcatRows(schemasAndRows ...interface{}) row.Row {
   163  	if len(schemasAndRows)%2 != 0 {
   164  		panic("Non-even number of inputs passed to concatRows")
   165  	}
   166  
   167  	taggedVals := make(row.TaggedValues)
   168  	cols := make([]schema.Column, 0)
   169  	var itag uint64
   170  	for i := 0; i < len(schemasAndRows); i += 2 {
   171  		sch := schemasAndRows[i].(schema.Schema)
   172  		r := schemasAndRows[i+1].(row.Row)
   173  		sch.GetAllCols().IterInSortedOrder(func(tag uint64, col schema.Column) (stop bool) {
   174  			val, ok := r.GetColVal(tag)
   175  			if ok {
   176  				taggedVals[itag] = val
   177  			}
   178  
   179  			col.Tag = itag
   180  			cols = append(cols, col)
   181  			itag++
   182  
   183  			return false
   184  		})
   185  	}
   186  
   187  	colCol := schema.NewColCollection(cols...)
   188  	r, err := row.New(types.Format_Default, schema.UnkeyedSchemaFromCols(colCol), taggedVals)
   189  
   190  	if err != nil {
   191  		panic(err)
   192  	}
   193  
   194  	return r
   195  }