mirror of
https://github.com/dolthub/dolt.git
synced 2026-02-09 10:38:10 -06:00
160 lines
4.4 KiB
Go
160 lines
4.4 KiB
Go
// Copyright 2019 Dolthub, Inc.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package schema
|
|
|
|
import (
|
|
"errors"
|
|
"math"
|
|
"strings"
|
|
|
|
"github.com/dolthub/dolt/go/libraries/doltcore/schema/typeinfo"
|
|
"github.com/dolthub/dolt/go/store/types"
|
|
)
|
|
|
|
// InvalidTag is used as an invalid tag
|
|
const InvalidTag uint64 = math.MaxUint64
|
|
|
|
var (
|
|
// KindToLwrStr maps a noms kind to the kinds lowercased name
|
|
KindToLwrStr = make(map[types.NomsKind]string)
|
|
|
|
// LwrStrToKind maps a lowercase string to the noms kind it is referring to
|
|
LwrStrToKind = make(map[string]types.NomsKind)
|
|
)
|
|
|
|
var (
|
|
// InvalidCol is a Column instance that is returned when there is nothing to return and can be tested against.
|
|
InvalidCol = Column{
|
|
"invalid",
|
|
InvalidTag,
|
|
types.NullKind,
|
|
false,
|
|
typeinfo.UnknownType,
|
|
"",
|
|
false,
|
|
"",
|
|
nil,
|
|
}
|
|
)
|
|
|
|
func init() {
|
|
for t, s := range types.KindToString {
|
|
KindToLwrStr[t] = strings.ToLower(s)
|
|
LwrStrToKind[strings.ToLower(s)] = t
|
|
}
|
|
}
|
|
|
|
// Column is a structure containing information about a column in a row in a table.
|
|
type Column struct {
|
|
// Name is the name of the column
|
|
Name string
|
|
|
|
// Tag should be unique per versioned schema and allows
|
|
Tag uint64
|
|
|
|
// Kind is the types.NomsKind that values of this column will be
|
|
Kind types.NomsKind
|
|
|
|
// IsPartOfPK says whether this column is part of the primary key
|
|
IsPartOfPK bool
|
|
|
|
// TypeInfo states the type of this column.
|
|
TypeInfo typeinfo.TypeInfo
|
|
|
|
// Default is the default value of this column. This is the string representation of a sql.Expression.
|
|
Default string
|
|
|
|
// AutoIncrement says whether this column auto increments.
|
|
AutoIncrement bool
|
|
|
|
// Comment is the comment for this column.
|
|
Comment string
|
|
|
|
// Constraints are rules that can be checked on each column to say if the columns value is valid
|
|
Constraints []ColConstraint
|
|
}
|
|
|
|
// NewColumn creates a Column instance with the default type info for the NomsKind
|
|
func NewColumn(name string, tag uint64, kind types.NomsKind, partOfPK bool, constraints ...ColConstraint) Column {
|
|
typeInfo := typeinfo.FromKind(kind)
|
|
col, err := NewColumnWithTypeInfo(name, tag, typeInfo, partOfPK, "", false, "", constraints...)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return col
|
|
}
|
|
|
|
// NewColumnWithTypeInfo creates a Column instance with the given type info.
|
|
func NewColumnWithTypeInfo(name string, tag uint64, typeInfo typeinfo.TypeInfo, partOfPK bool, defaultVal string, autoIncrement bool, comment string, constraints ...ColConstraint) (Column, error) {
|
|
for _, c := range constraints {
|
|
if c == nil {
|
|
return Column{}, errors.New("nil passed as a constraint")
|
|
}
|
|
}
|
|
|
|
if typeInfo == nil {
|
|
return Column{}, errors.New("cannot instantiate column with nil type info")
|
|
}
|
|
|
|
return Column{
|
|
name,
|
|
tag,
|
|
typeInfo.NomsKind(),
|
|
partOfPK,
|
|
typeInfo,
|
|
defaultVal,
|
|
autoIncrement,
|
|
comment,
|
|
constraints,
|
|
}, nil
|
|
}
|
|
|
|
// IsNullable returns whether the column can be set to a null value.
|
|
func (c Column) IsNullable() bool {
|
|
if c.IsPartOfPK {
|
|
return false
|
|
}
|
|
for _, cnst := range c.Constraints {
|
|
if cnst.GetConstraintType() == NotNullConstraintType {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
// Equals tests equality between two columns.
|
|
func (c Column) Equals(other Column) bool {
|
|
return c.Name == other.Name &&
|
|
c.Tag == other.Tag &&
|
|
c.Kind == other.Kind &&
|
|
c.IsPartOfPK == other.IsPartOfPK &&
|
|
c.TypeInfo.Equals(other.TypeInfo) &&
|
|
c.Default == other.Default &&
|
|
ColConstraintsAreEqual(c.Constraints, other.Constraints)
|
|
}
|
|
|
|
// Compatible tests compatibility between two columns. Compatible columns have the same tag and can store the same
|
|
// kinds of values at the storage layer, but may have different constraints or type parameters.
|
|
func (c Column) Compatible(other Column) bool {
|
|
return c.Tag == other.Tag &&
|
|
c.Kind == other.Kind &&
|
|
c.IsPartOfPK == other.IsPartOfPK
|
|
}
|
|
|
|
// KindString returns the string representation of the NomsKind stored in the column.
|
|
func (c Column) KindString() string {
|
|
return KindToLwrStr[c.Kind]
|
|
}
|