diff --git a/core/id/cache.go b/core/id/cache.go index 1fdd204089..e88eb4a390 100644 --- a/core/id/cache.go +++ b/core/id/cache.go @@ -16,7 +16,6 @@ package id import ( "hash/crc32" - "strconv" "sync" ) @@ -59,8 +58,7 @@ func (cache *cacheStruct) ToOID(id Internal) uint32 { } cache.mutex.RUnlock() if id.Section() == Section_OID { - oid, _ := strconv.ParseUint(id.Segment(0), 10, 32) - return uint32(oid) + return InternalOID(id).OID() } cache.mutex.Lock() defer cache.mutex.Unlock() diff --git a/core/id/internal_id.go b/core/id/internal_id.go index 660cf5a9df..3db487bf9b 100644 --- a/core/id/internal_id.go +++ b/core/id/internal_id.go @@ -47,6 +47,34 @@ const ( formatMask = uint8(0x80) // Null is an empty, invalid ID. Null Internal = "" + // NullAccessMethod is an empty, invalid ID. This is exactly equivalent to Null. + NullAccessMethod InternalAccessMethod = "" + // NullCheck is an empty, invalid ID. This is exactly equivalent to Null. + NullCheck InternalCheck = "" + // NullCollation is an empty, invalid ID. This is exactly equivalent to Null. + NullCollation InternalCollation = "" + // NullColumnDefault is an empty, invalid ID. This is exactly equivalent to Null. + NullColumnDefault InternalColumnDefault = "" + // NullDatabase is an empty, invalid ID. This is exactly equivalent to Null. + NullDatabase InternalDatabase = "" + // NullEnumLabel is an empty, invalid ID. This is exactly equivalent to Null. + NullEnumLabel InternalEnumLabel = "" + // NullForeignKey is an empty, invalid ID. This is exactly equivalent to Null. + NullForeignKey InternalForeignKey = "" + // NullFunction is an empty, invalid ID. This is exactly equivalent to Null. + NullFunction InternalFunction = "" + // NullIndex is an empty, invalid ID. This is exactly equivalent to Null. + NullIndex InternalIndex = "" + // NullNamespace is an empty, invalid ID. This is exactly equivalent to Null. + NullNamespace InternalNamespace = "" + // NullSequence is an empty, invalid ID. This is exactly equivalent to Null. + NullSequence InternalSequence = "" + // NullTable is an empty, invalid ID. This is exactly equivalent to Null. + NullTable InternalTable = "" + // NullType is an empty, invalid ID. This is exactly equivalent to Null. + NullType InternalType = "" + // NullView is an empty, invalid ID. This is exactly equivalent to Null. + NullView InternalView = "" ) // Internal is an ID that is used within Doltgres. This ID is never exposed to clients through any normal means, and diff --git a/core/id/internal_id_wrappers.go b/core/id/internal_id_wrappers.go new file mode 100644 index 0000000000..008e84cc3c --- /dev/null +++ b/core/id/internal_id_wrappers.go @@ -0,0 +1,441 @@ +// Copyright 2025 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 id + +import "strconv" + +// InternalAccessMethod is an Internal wrapper for access methods. This wrapper must not be returned to the client. +type InternalAccessMethod Internal + +// InternalCheck is an Internal wrapper for checks. This wrapper must not be returned to the client. +type InternalCheck Internal + +// InternalCollation is an Internal wrapper for collations. This wrapper must not be returned to the client. +type InternalCollation Internal + +// InternalColumnDefault is an Internal wrapper for column defaults. This wrapper must not be returned to the client. +type InternalColumnDefault Internal + +// InternalDatabase is an Internal wrapper for databases. This wrapper must not be returned to the client. +type InternalDatabase Internal + +// InternalEnumLabel is an Internal wrapper for enum labels. This wrapper must not be returned to the client. +type InternalEnumLabel Internal + +// InternalForeignKey is an Internal wrapper for foreign keys. This wrapper must not be returned to the client. +type InternalForeignKey Internal + +// InternalFunction is an Internal wrapper for functions. This wrapper must not be returned to the client. +type InternalFunction Internal + +// InternalIndex is an Internal wrapper for indexes. This wrapper must not be returned to the client. +type InternalIndex Internal + +// InternalNamespace is an Internal wrapper for schemas/namespaces. This wrapper must not be returned to the client. +type InternalNamespace Internal + +// InternalOID is an Internal wrapper for OIDs. This wrapper must not be returned to the client. +type InternalOID Internal + +// InternalSequence is an Internal wrapper for sequences. This wrapper must not be returned to the client. +type InternalSequence Internal + +// InternalTable is an Internal wrapper for tables. This wrapper must not be returned to the client. +type InternalTable Internal + +// InternalType is an Internal wrapper for types. This wrapper must not be returned to the client. +type InternalType Internal + +// InternalView is an Internal wrapper for views. This wrapper must not be returned to the client. +type InternalView Internal + +// NewInternalAccessMethod returns a new InternalAccessMethod. This wrapper must not be returned to the client. +func NewInternalAccessMethod(methodName string) InternalAccessMethod { + if len(methodName) == 0 { + return NullAccessMethod + } + return InternalAccessMethod(NewInternal(Section_AccessMethod, methodName)) +} + +// NewInternalCheck returns a new InternalCheck. This wrapper must not be returned to the client. +func NewInternalCheck(schemaName string, tableName string, checkName string) InternalCheck { + if len(schemaName) == 0 && len(tableName) == 0 && len(checkName) == 0 { + return NullCheck + } + return InternalCheck(NewInternal(Section_Check, schemaName, tableName, checkName)) +} + +// NewInternalCollation returns a new InternalCollation. This wrapper must not be returned to the client. +func NewInternalCollation(schemaName string, collationName string) InternalCollation { + if len(schemaName) == 0 && len(collationName) == 0 { + return NullCollation + } + return InternalCollation(NewInternal(Section_Collation, schemaName, collationName)) +} + +// NewInternalColumnDefault returns a new InternalColumnDefault. This wrapper must not be returned to the client. +func NewInternalColumnDefault(schemaName string, tableName string, columnName string) InternalColumnDefault { + if len(schemaName) == 0 && len(tableName) == 0 && len(columnName) == 0 { + return NullColumnDefault + } + return InternalColumnDefault(NewInternal(Section_ColumnDefault, schemaName, tableName, columnName)) +} + +// NewInternalDatabase returns a new InternalDatabase. This wrapper must not be returned to the client. +func NewInternalDatabase(dbName string) InternalDatabase { + if len(dbName) == 0 { + return NullDatabase + } + return InternalDatabase(NewInternal(Section_Database, dbName)) +} + +// NewInternalEnumLabel returns a new InternalEnumLabel. This wrapper must not be returned to the client. +func NewInternalEnumLabel(parent InternalType, label string) InternalEnumLabel { + if len(parent) == 0 && len(label) == 0 { + return NullEnumLabel + } + return InternalEnumLabel(NewInternal(Section_EnumLabel, string(parent), label)) +} + +// NewInternalForeignKey returns a new InternalForeignKey. This wrapper must not be returned to the client. +func NewInternalForeignKey(schemaName string, tableName string, fkName string) InternalForeignKey { + if len(schemaName) == 0 && len(tableName) == 0 && len(fkName) == 0 { + return NullForeignKey + } + return InternalForeignKey(NewInternal(Section_ForeignKey, schemaName, tableName, fkName)) +} + +// NewInternalFunction returns a new InternalFunction. This wrapper must not be returned to the client. +func NewInternalFunction(schemaName string, funcName string, params ...InternalType) InternalFunction { + if len(schemaName) == 0 && len(funcName) == 0 && len(params) == 0 { + return NullFunction + } + data := make([]string, len(params)+2) + data[0] = schemaName + data[1] = funcName + for i := range params { + data[2+i] = string(params[i]) + } + return InternalFunction(NewInternal(Section_Function, data...)) +} + +// NewInternalIndex returns a new InternalIndex. This wrapper must not be returned to the client. +func NewInternalIndex(schemaName string, tableName string, indexName string) InternalIndex { + if len(schemaName) == 0 && len(tableName) == 0 && len(indexName) == 0 { + return NullIndex + } + return InternalIndex(NewInternal(Section_Index, schemaName, tableName, indexName)) +} + +// NewInternalNamespace returns a new InternalNamespace. This wrapper must not be returned to the client. +func NewInternalNamespace(schemaName string) InternalNamespace { + if len(schemaName) == 0 { + return NullNamespace + } + return InternalNamespace(NewInternal(Section_Namespace, schemaName)) +} + +// NewInternalOID returns a new InternalOID. This wrapper must not be returned to the client. +func NewInternalOID(val uint32) InternalOID { + return InternalOID(NewInternal(Section_OID, strconv.FormatUint(uint64(val), 10))) +} + +// NewInternalSequence returns a new InternalSequence. This wrapper must not be returned to the client. +func NewInternalSequence(schemaName string, sequenceName string) InternalSequence { + if len(schemaName) == 0 && len(sequenceName) == 0 { + return NullSequence + } + return InternalSequence(NewInternal(Section_Sequence, schemaName, sequenceName)) +} + +// NewInternalTable returns a new InternalTable. This wrapper must not be returned to the client. +func NewInternalTable(schemaName string, tableName string) InternalTable { + if len(schemaName) == 0 && len(tableName) == 0 { + return NullTable + } + return InternalTable(NewInternal(Section_Table, schemaName, tableName)) +} + +// NewInternalType returns a new InternalType. This wrapper must not be returned to the client. +func NewInternalType(schemaName string, typeName string) InternalType { + if len(schemaName) == 0 && len(typeName) == 0 { + return NullType + } + return InternalType(NewInternal(Section_Type, schemaName, typeName)) +} + +// NewInternalView returns a new InternalView. This wrapper must not be returned to the client. +func NewInternalView(schemaName string, viewName string) InternalView { + if len(schemaName) == 0 && len(viewName) == 0 { + return NullView + } + return InternalView(NewInternal(Section_View, schemaName, viewName)) +} + +// MethodName returns the method's name. +func (id InternalAccessMethod) MethodName() string { + return Internal(id).Segment(0) +} + +// CheckName returns the check's name. +func (id InternalCheck) CheckName() string { + return Internal(id).Segment(2) +} + +// SchemaName returns the schema name of the check. +func (id InternalCheck) SchemaName() string { + return Internal(id).Segment(0) +} + +// TableName returns the name of the table that the check belongs to. +func (id InternalCheck) TableName() string { + return Internal(id).Segment(1) +} + +// CollationName returns the collation's name. +func (id InternalCollation) CollationName() string { + return Internal(id).Segment(1) +} + +// SchemaName returns the schema name of the collation. +func (id InternalCollation) SchemaName() string { + return Internal(id).Segment(0) +} + +// ColumnName returns the column's name that the default belongs to. +func (id InternalColumnDefault) ColumnName() string { + return Internal(id).Segment(2) +} + +// SchemaName returns the schema name of the column default. +func (id InternalColumnDefault) SchemaName() string { + return Internal(id).Segment(0) +} + +// TableName returns the name of the table that the column belongs to. +func (id InternalColumnDefault) TableName() string { + return Internal(id).Segment(1) +} + +// DatabaseName returns the database's name. +func (id InternalDatabase) DatabaseName() string { + return Internal(id).Segment(0) +} + +// Parent returns the parent ENUM for the label. +func (id InternalEnumLabel) Parent() InternalType { + return InternalType(Internal(id).Segment(0)) +} + +// Label returns the name of the label. +func (id InternalEnumLabel) Label() string { + return Internal(id).Segment(1) +} + +// ForeignKeyName returns the foreign key's name. +func (id InternalForeignKey) ForeignKeyName() string { + return Internal(id).Segment(2) +} + +// SchemaName returns the schema name of the foreign key. +func (id InternalForeignKey) SchemaName() string { + return Internal(id).Segment(0) +} + +// TableName returns the name of the table that the foreign key belongs to. +func (id InternalForeignKey) TableName() string { + return Internal(id).Segment(1) +} + +// FunctionName returns the function's name. +func (id InternalFunction) FunctionName() string { + return Internal(id).Segment(1) +} + +// Parameters returns the function's name. +func (id InternalFunction) Parameters() []InternalType { + data := Internal(id).Data()[2:] + params := make([]InternalType, len(data)) + for i := range data { + params[i] = InternalType(data[i]) + } + return params +} + +// ParameterCount returns the function's name. +func (id InternalFunction) ParameterCount() int { + return Internal(id).SegmentCount() - 2 +} + +// SchemaName returns the schema name of the function. +func (id InternalFunction) SchemaName() string { + return Internal(id).Segment(0) +} + +// IndexName returns the index's name. +func (id InternalIndex) IndexName() string { + return Internal(id).Segment(2) +} + +// SchemaName returns the schema name of the index. +func (id InternalIndex) SchemaName() string { + return Internal(id).Segment(0) +} + +// TableName returns the name of the table that the index belongs to. +func (id InternalIndex) TableName() string { + return Internal(id).Segment(1) +} + +// SchemaName returns the schema name. +func (id InternalNamespace) SchemaName() string { + return Internal(id).Segment(0) +} + +// OID returns the contained uint32 value. +func (id InternalOID) OID() uint32 { + val, _ := strconv.ParseUint(Internal(id).Segment(0), 10, 32) + return uint32(val) +} + +// SchemaName returns the schema name of the sequence. +func (id InternalSequence) SchemaName() string { + return Internal(id).Segment(0) +} + +// SequenceName returns the name of the sequence. +func (id InternalSequence) SequenceName() string { + return Internal(id).Segment(1) +} + +// SchemaName returns the schema name of the table. +func (id InternalTable) SchemaName() string { + return Internal(id).Segment(0) +} + +// TableName returns the table's name. +func (id InternalTable) TableName() string { + return Internal(id).Segment(1) +} + +// SchemaName returns the schema name of the type. +func (id InternalType) SchemaName() string { + return Internal(id).Segment(0) +} + +// TypeName returns the type's name. +func (id InternalType) TypeName() string { + return Internal(id).Segment(1) +} + +// SchemaName returns the schema name of the view. +func (id InternalView) SchemaName() string { + return Internal(id).Segment(0) +} + +// ViewName returns the view's name. +func (id InternalView) ViewName() string { + return Internal(id).Segment(1) +} + +// IsValid returns whether the ID is valid. +func (id InternalAccessMethod) IsValid() bool { return Internal(id).IsValid() } + +// IsValid returns whether the ID is valid. +func (id InternalCheck) IsValid() bool { return Internal(id).IsValid() } + +// IsValid returns whether the ID is valid. +func (id InternalCollation) IsValid() bool { return Internal(id).IsValid() } + +// IsValid returns whether the ID is valid. +func (id InternalColumnDefault) IsValid() bool { return Internal(id).IsValid() } + +// IsValid returns whether the ID is valid. +func (id InternalDatabase) IsValid() bool { return Internal(id).IsValid() } + +// IsValid returns whether the ID is valid. +func (id InternalEnumLabel) IsValid() bool { return Internal(id).IsValid() } + +// IsValid returns whether the ID is valid. +func (id InternalForeignKey) IsValid() bool { return Internal(id).IsValid() } + +// IsValid returns whether the ID is valid. +func (id InternalFunction) IsValid() bool { return Internal(id).IsValid() } + +// IsValid returns whether the ID is valid. +func (id InternalIndex) IsValid() bool { return Internal(id).IsValid() } + +// IsValid returns whether the ID is valid. +func (id InternalNamespace) IsValid() bool { return Internal(id).IsValid() } + +// IsValid returns whether the ID is valid. +func (id InternalOID) IsValid() bool { return Internal(id).IsValid() } + +// IsValid returns whether the ID is valid. +func (id InternalSequence) IsValid() bool { return Internal(id).IsValid() } + +// IsValid returns whether the ID is valid. +func (id InternalTable) IsValid() bool { return Internal(id).IsValid() } + +// IsValid returns whether the ID is valid. +func (id InternalType) IsValid() bool { return Internal(id).IsValid() } + +// IsValid returns whether the ID is valid. +func (id InternalView) IsValid() bool { return Internal(id).IsValid() } + +// Internal returns the unwrapped ID. +func (id InternalAccessMethod) Internal() Internal { return Internal(id) } + +// Internal returns the unwrapped ID. +func (id InternalCheck) Internal() Internal { return Internal(id) } + +// Internal returns the unwrapped ID. +func (id InternalCollation) Internal() Internal { return Internal(id) } + +// Internal returns the unwrapped ID. +func (id InternalColumnDefault) Internal() Internal { return Internal(id) } + +// Internal returns the unwrapped ID. +func (id InternalDatabase) Internal() Internal { return Internal(id) } + +// Internal returns the unwrapped ID. +func (id InternalEnumLabel) Internal() Internal { return Internal(id) } + +// Internal returns the unwrapped ID. +func (id InternalForeignKey) Internal() Internal { return Internal(id) } + +// Internal returns the unwrapped ID. +func (id InternalFunction) Internal() Internal { return Internal(id) } + +// Internal returns the unwrapped ID. +func (id InternalIndex) Internal() Internal { return Internal(id) } + +// Internal returns the unwrapped ID. +func (id InternalNamespace) Internal() Internal { return Internal(id) } + +// Internal returns the unwrapped ID. +func (id InternalOID) Internal() Internal { return Internal(id) } + +// Internal returns the unwrapped ID. +func (id InternalSequence) Internal() Internal { return Internal(id) } + +// Internal returns the unwrapped ID. +func (id InternalTable) Internal() Internal { return Internal(id) } + +// Internal returns the unwrapped ID. +func (id InternalType) Internal() Internal { return Internal(id) } + +// Internal returns the unwrapped ID. +func (id InternalView) Internal() Internal { return Internal(id) } diff --git a/core/id/registry.go b/core/id/registry.go new file mode 100644 index 0000000000..9119f20680 --- /dev/null +++ b/core/id/registry.go @@ -0,0 +1,115 @@ +// Copyright 2025 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 id + +import "github.com/dolthub/go-mysql-server/sql" + +// Operation represents an operation that is being performed or validated. +type Operation uint8 + +const ( + Operation_Rename Operation = iota + Operation_Delete + Operation_Delete_Cascade +) + +// registry is the implementation of the global registry. This holds all functions that operate or validate a change on +// an ID. +type registry struct { + performers [][]InternalPerformer + validators [][]InternalValidator +} + +// globalRegistry is the variable that is referenced for the registry. +var globalRegistry = ®istry{ + performers: make([][]InternalPerformer, section_count), + validators: make([][]InternalValidator, section_count), +} + +// InternalPerformer is a function that performs the given operation on the original ID. Some operations, such as +// renames, will use the new ID. +type InternalPerformer func(ctx *sql.Context, operation Operation, originalID Internal, newID Internal) error + +// InternalValidator is a function that validates the given operation on the original ID. Some operations, such as +// renames, will use the new ID. A validator is not required, and is intended for operations that may be relatively +// expensive to perform, but able to check quickly for failures. In addition, validators should not perform any +// modifications. +type InternalValidator func(ctx *sql.Context, operation Operation, originalID Internal, newID Internal) error + +// RegisterPerformer registers the given performer for the given sections. +// +// For example, sequences are related to tables. Whenever a table operation is performed that changes its ID, sequences +// will also need to update their IDs that reference the table. This is accomplished by registering a performer that +// accepts a table section, where the performer modifies sequences as needed. +// +// Performers should not register sections that are directly related to themselves. For example, a sequence performer +// should not register itself under the sequence section, as it will be the one broadcasting that section, and therefore +// could cause a loop. +func RegisterPerformer(performer InternalPerformer, sections ...Section) { + for _, section := range sections { + if section == Section_Null { + continue + } + globalRegistry.performers[section] = append(globalRegistry.performers[section], performer) + } +} + +// RegisterValidator registers the given validator for the given sections. Please reference both InternalValidator and +// RegisterPerformer for context. +func RegisterValidator(validator InternalValidator, sections ...Section) { + for _, section := range sections { + if section == Section_Null { + continue + } + globalRegistry.validators[section] = append(globalRegistry.validators[section], validator) + } +} + +// PerformOperation calls all registered performers that are associated with the given section. This does not call any +// validators, which should be done using ValidateOperation. This returns the first error that is encountered. +func PerformOperation(ctx *sql.Context, targetSection Section, operation Operation, originalID Internal, newID Internal) error { + for _, performer := range globalRegistry.performers[targetSection] { + if err := performer(ctx, operation, originalID, newID); err != nil { + return err + } + } + // TODO: need to look for tables that store OIDs in their columns and UPDATE them to the new value + // it will be relatively slow, but that's the price a user pays to store OIDs in their tables + return nil +} + +// ValidateOperation calls all registered validators that are associated with the given section. +func ValidateOperation(ctx *sql.Context, targetSection Section, operation Operation, originalID Internal, newID Internal) error { + for _, validator := range globalRegistry.validators[targetSection] { + if err := validator(ctx, operation, originalID, newID); err != nil { + return err + } + } + return nil +} + +// String returns the name of the operation. +func (op Operation) String() string { + switch op { + case Operation_Rename: + return "Rename" + case Operation_Delete: + return "Delete" + case Operation_Delete_Cascade: + return "DeleteCascade" + default: + return "UNKNOWN_OPERATION" + } +} diff --git a/core/id/section.go b/core/id/section.go index f508694734..e994075f08 100644 --- a/core/id/section.go +++ b/core/id/section.go @@ -59,8 +59,10 @@ const ( Section_Trigger Section = 34 // Refers to triggers on tables and views Section_Type Section = 35 // Refers to types Section_UniqueKey Section = 36 // Refers to unique keys on tables - Section_User Section = 37 // Refers to user + Section_User Section = 37 // Refers to users Section_View Section = 38 // Refers to views + + section_count uint8 = 39 // This is the number of sections, and should ALWAYS be kept up-to-date ) // String returns the name of the Section. diff --git a/core/init.go b/core/init.go index 0a61006595..6c309becec 100644 --- a/core/init.go +++ b/core/init.go @@ -17,6 +17,8 @@ package core import ( "github.com/dolthub/dolt/go/libraries/doltcore/doltdb" "github.com/dolthub/dolt/go/store/types" + + "github.com/dolthub/doltgresql/core/id" ) // Init initializes this package. @@ -25,4 +27,6 @@ func Init() { doltdb.NewRootValue = newRootValue types.DoltgresRootValueHumanReadableStringAtIndentationLevel = rootValueHumanReadableStringAtIndentationLevel types.DoltgresRootValueWalkAddrs = rootValueWalkAddrs + id.RegisterPerformer(sequenceIDPerformer, id.Section_Table) + id.RegisterValidator(sequenceIDValidator, id.Section_Table) } diff --git a/core/relations.go b/core/relations.go index 1269efdd3f..7941d5839f 100644 --- a/core/relations.go +++ b/core/relations.go @@ -18,9 +18,10 @@ import ( "fmt" "github.com/dolthub/dolt/go/libraries/doltcore/doltdb" - "github.com/dolthub/dolt/go/libraries/doltcore/sqle/dsess" "github.com/dolthub/go-mysql-server/sql" + + "github.com/dolthub/doltgresql/core/id" ) // RelationType states the type of the relation. @@ -72,7 +73,7 @@ func GetRelationTypeFromRoot(ctx *sql.Context, schema string, relation string, r if err != nil { return RelationType_DoesNotExist, err } - if collection.HasSequence(doltdb.TableName{Name: relation, Schema: schema}) { + if collection.HasSequence(id.NewInternalSequence(schema, relation)) { return RelationType_Sequence, nil } // TODO: the rest of the relations diff --git a/core/rootvalue.go b/core/rootvalue.go index c860b18e7c..751a36f022 100644 --- a/core/rootvalue.go +++ b/core/rootvalue.go @@ -30,6 +30,7 @@ import ( "github.com/dolthub/dolt/go/store/prolly/tree" "github.com/dolthub/dolt/go/store/types" + "github.com/dolthub/doltgresql/core/id" "github.com/dolthub/doltgresql/core/sequences" "github.com/dolthub/doltgresql/core/typecollection" ) @@ -552,7 +553,7 @@ func (root *RootValue) RemoveTables( } for _, tableName := range tables { for _, seq := range collection.GetSequencesWithTable(tableName) { - if err = collection.DropSequence(doltdb.TableName{Name: seq.Name, Schema: tableName.Schema}); err != nil { + if err = collection.DropSequence(seq.Name); err != nil { return nil, err } } @@ -594,7 +595,7 @@ func (root *RootValue) RenameTable(ctx context.Context, oldName, newName doltdb. return nil, err } for _, seq := range collection.GetSequencesWithTable(oldName) { - seq.OwnerTable = newName.Name + seq.OwnerTable = id.NewInternalTable(seq.OwnerTable.SchemaName(), newName.Name) } newRoot, err = newRoot.PutSequences(ctx, collection) if err != nil { diff --git a/core/sequence_id.go b/core/sequence_id.go new file mode 100644 index 0000000000..1c2b4cdad4 --- /dev/null +++ b/core/sequence_id.go @@ -0,0 +1,100 @@ +// Copyright 2025 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 core + +import ( + "fmt" + + "github.com/dolthub/dolt/go/libraries/doltcore/doltdb" + "github.com/dolthub/go-mysql-server/sql" + + "github.com/dolthub/doltgresql/core/id" +) + +// sequenceIDValidator is the internal ID validator for sequences. +func sequenceIDValidator(ctx *sql.Context, operation id.Operation, originalID id.Internal, newID id.Internal) error { + switch originalID.Section() { + case id.Section_ColumnDefault, id.Section_Table: + switch operation { + case id.Operation_Rename, id.Operation_Delete, id.Operation_Delete_Cascade: + return nil + default: + return fmt.Errorf("sequence performer received unexpected operation `%s`", operation.String()) + } + default: + return fmt.Errorf("sequence performer received unexpected section `%s`", originalID.Section().String()) + } +} + +// sequenceIDValidator is the internal ID performer for sequences, which modifies the sequence collection in response to +// the given operation and section of the original ID. +func sequenceIDPerformer(ctx *sql.Context, operation id.Operation, originalID id.Internal, newID id.Internal) error { + switch originalID.Section() { + case id.Section_ColumnDefault: + originalIDCol := id.InternalColumnDefault(originalID) + switch operation { + case id.Operation_Rename: + return nil + case id.Operation_Delete, id.Operation_Delete_Cascade: + collection, err := GetSequencesCollectionFromContext(ctx) + if err != nil { + return err + } + sequences := collection.GetSequencesWithTable(doltdb.TableName{ + Name: originalIDCol.TableName(), + Schema: originalIDCol.SchemaName(), + }) + for _, sequence := range sequences { + if sequence.OwnerColumn == originalIDCol.ColumnName() { + if err = collection.DropSequence(sequence.Name); err != nil { + return err + } + } + } + return nil + default: + return fmt.Errorf("sequence performer received unexpected operation `%s`", operation.String()) + } + case id.Section_Table: + originalIDTable := id.InternalTable(originalID) + switch operation { + case id.Operation_Rename, id.Operation_Delete, id.Operation_Delete_Cascade: + collection, err := GetSequencesCollectionFromContext(ctx) + if err != nil { + return err + } + sequences := collection.GetSequencesWithTable(doltdb.TableName{ + Name: originalIDTable.TableName(), + Schema: originalIDTable.SchemaName(), + }) + for _, sequence := range sequences { + if err = collection.DropSequence(sequence.Name); err != nil { + return err + } + if operation == id.Operation_Rename { + sequence.OwnerTable = id.InternalTable(newID) + if err = collection.CreateSequence(sequence.Name.SchemaName(), sequence); err != nil { + return err + } + } + } + return nil + default: + return fmt.Errorf("sequence performer received unexpected operation `%s`", operation.String()) + } + default: + return fmt.Errorf("sequence performer received unexpected section `%s`", originalID.Section().String()) + } +} diff --git a/core/sequences/merge.go b/core/sequences/merge.go index d17a162aa2..f518f4bac7 100644 --- a/core/sequences/merge.go +++ b/core/sequences/merge.go @@ -17,8 +17,6 @@ package sequences import ( "context" - "github.com/dolthub/dolt/go/libraries/doltcore/doltdb" - pgtypes "github.com/dolthub/doltgresql/server/types" "github.com/dolthub/doltgresql/utils" ) @@ -26,14 +24,14 @@ import ( // Merge handles merging sequences on our root and their root. func Merge(ctx context.Context, ourCollection, theirCollection, ancCollection *Collection) (*Collection, error) { mergedCollection := ourCollection.Clone() - err := theirCollection.IterateSequences(func(schema string, theirSeq *Sequence) error { + err := theirCollection.IterateSequences(func(theirSeq *Sequence) error { // If we don't have the sequence, then we simply add it - if !mergedCollection.HasSequence(doltdb.TableName{Name: theirSeq.Name, Schema: schema}) { + if !mergedCollection.HasSequence(theirSeq.Name) { newSeq := *theirSeq - return mergedCollection.CreateSequence(schema, &newSeq) + return mergedCollection.CreateSequence(theirSeq.Name.SchemaName(), &newSeq) } // Take the min/max of fields that aren't dependent on the increment direction - mergedSeq := mergedCollection.GetSequence(doltdb.TableName{Name: theirSeq.Name, Schema: schema}) + mergedSeq := mergedCollection.GetSequence(theirSeq.Name) mergedSeq.Minimum = utils.Min(mergedSeq.Minimum, theirSeq.Minimum) mergedSeq.Maximum = utils.Max(mergedSeq.Maximum, theirSeq.Maximum) mergedSeq.Cache = utils.Min(mergedSeq.Cache, theirSeq.Cache) diff --git a/core/sequences/sequence.go b/core/sequences/sequence.go index c419fb8de3..f3c0c65123 100644 --- a/core/sequences/sequence.go +++ b/core/sequences/sequence.go @@ -42,8 +42,8 @@ const ( // Sequence represents a single sequence within the pg_sequence table. type Sequence struct { - Name string - DataTypeID id.Internal + Name id.InternalSequence + DataTypeID id.InternalType Persistence Persistence Start int64 Current int64 @@ -53,17 +53,17 @@ type Sequence struct { Cache int64 Cycle bool IsAtEnd bool - OwnerTable string + OwnerTable id.InternalTable OwnerColumn string } // GetSequence returns the sequence with the given schema and name. Returns nil if the sequence cannot be found. -func (pgs *Collection) GetSequence(name doltdb.TableName) *Sequence { +func (pgs *Collection) GetSequence(name id.InternalSequence) *Sequence { pgs.mutex.Lock() defer pgs.mutex.Unlock() - if nameMap, ok := pgs.schemaMap[name.Schema]; ok { - if seq, ok := nameMap[name.Name]; ok { + if nameMap, ok := pgs.schemaMap[name.SchemaName()]; ok { + if seq, ok := nameMap[name.SequenceName()]; ok { return seq } } @@ -78,7 +78,7 @@ func (pgs *Collection) GetSequencesWithTable(name doltdb.TableName) []*Sequence if nameMap, ok := pgs.schemaMap[name.Schema]; ok { var seqs []*Sequence for _, seq := range nameMap { - if seq.OwnerTable == name.Name { + if seq.OwnerTable.TableName() == name.Name { seqs = append(seqs, seq) } } @@ -110,7 +110,7 @@ func (pgs *Collection) GetAllSequences() (sequences map[string][]*Sequence, sche } // HasSequence returns whether the sequence is present. -func (pgs *Collection) HasSequence(name doltdb.TableName) bool { +func (pgs *Collection) HasSequence(name id.InternalSequence) bool { return pgs.GetSequence(name) != nil } @@ -124,21 +124,21 @@ func (pgs *Collection) CreateSequence(schema string, seq *Sequence) error { nameMap = make(map[string]*Sequence) pgs.schemaMap[schema] = nameMap } - if _, ok = nameMap[seq.Name]; ok { + if _, ok = nameMap[seq.Name.SequenceName()]; ok { return fmt.Errorf(`relation "%s" already exists`, seq.Name) } - nameMap[seq.Name] = seq + nameMap[seq.Name.SequenceName()] = seq return nil } // DropSequence drops an existing sequence. -func (pgs *Collection) DropSequence(name doltdb.TableName) error { +func (pgs *Collection) DropSequence(name id.InternalSequence) error { pgs.mutex.Lock() defer pgs.mutex.Unlock() - if nameMap, ok := pgs.schemaMap[name.Schema]; ok { - if _, ok = nameMap[name.Name]; ok { - delete(nameMap, name.Name) + if nameMap, ok := pgs.schemaMap[name.SchemaName()]; ok { + if _, ok = nameMap[name.SequenceName()]; ok { + delete(nameMap, name.SequenceName()) return nil } } @@ -146,13 +146,13 @@ func (pgs *Collection) DropSequence(name doltdb.TableName) error { } // IterateSequences iterates over all sequences in the collection. -func (pgs *Collection) IterateSequences(f func(schema string, seq *Sequence) error) error { +func (pgs *Collection) IterateSequences(f func(seq *Sequence) error) error { pgs.mutex.Lock() defer pgs.mutex.Unlock() - for schema, nameMap := range pgs.schemaMap { + for _, nameMap := range pgs.schemaMap { for _, seq := range nameMap { - if err := f(schema, seq); err != nil { + if err := f(seq); err != nil { return err } } diff --git a/core/sequences/serialization.go b/core/sequences/serialization.go index 30a58cc44c..ca0bb589ea 100644 --- a/core/sequences/serialization.go +++ b/core/sequences/serialization.go @@ -19,6 +19,7 @@ import ( "fmt" "sync" + "github.com/dolthub/doltgresql/core/id" "github.com/dolthub/doltgresql/utils" ) @@ -42,8 +43,8 @@ func (pgs *Collection) Serialize(ctx context.Context) ([]byte, error) { writer.VariableUint(uint64(len(nameMapKeys))) for _, nameMapKey := range nameMapKeys { sequence := nameMap[nameMapKey] - writer.String(sequence.Name) - writer.Internal(sequence.DataTypeID) + writer.Internal(sequence.Name.Internal()) + writer.Internal(sequence.DataTypeID.Internal()) writer.Uint8(uint8(sequence.Persistence)) writer.Int64(sequence.Start) writer.Int64(sequence.Current) @@ -53,7 +54,7 @@ func (pgs *Collection) Serialize(ctx context.Context) ([]byte, error) { writer.Int64(sequence.Cache) writer.Bool(sequence.Cycle) writer.Bool(sequence.IsAtEnd) - writer.String(sequence.OwnerTable) + writer.Internal(sequence.OwnerTable.Internal()) writer.String(sequence.OwnerColumn) } } @@ -85,8 +86,8 @@ func Deserialize(ctx context.Context, data []byte) (*Collection, error) { nameMap := make(map[string]*Sequence) for j := uint64(0); j < numOfSequences; j++ { sequence := &Sequence{} - sequence.Name = reader.String() - sequence.DataTypeID = reader.Internal() + sequence.Name = id.InternalSequence(reader.Internal()) + sequence.DataTypeID = id.InternalType(reader.Internal()) sequence.Persistence = Persistence(reader.Uint8()) sequence.Start = reader.Int64() sequence.Current = reader.Int64() @@ -96,9 +97,9 @@ func Deserialize(ctx context.Context, data []byte) (*Collection, error) { sequence.Cache = reader.Int64() sequence.Cycle = reader.Bool() sequence.IsAtEnd = reader.Bool() - sequence.OwnerTable = reader.String() + sequence.OwnerTable = id.InternalTable(reader.Internal()) sequence.OwnerColumn = reader.String() - nameMap[sequence.Name] = sequence + nameMap[sequence.Name.SequenceName()] = sequence } schemaMap[schemaName] = nameMap } diff --git a/core/typecollection/typecollection.go b/core/typecollection/typecollection.go index 7fb1fc001c..0b89d29f51 100644 --- a/core/typecollection/typecollection.go +++ b/core/typecollection/typecollection.go @@ -149,7 +149,7 @@ func (pgs *TypeCollection) GetTypeByID(internalID id.Internal) (*types.DoltgresT pgs.addSupportedBuiltInTypes() for _, nameMap := range pgs.schemaMap { for _, typ := range nameMap { - if typ.ID == internalID { + if typ.ID.Internal() == internalID { return typ, true } } diff --git a/server/analyzer/init.go b/server/analyzer/init.go index 7cc492c04a..a7161c89ca 100644 --- a/server/analyzer/init.go +++ b/server/analyzer/init.go @@ -24,18 +24,19 @@ import ( // Comments are to match the Stringer formatting rules in the original rule definition file, but we can't generate // human-readable strings for these extended types because they are in another package. const ( - ruleId_TypeSanitizer analyzer.RuleId = iota + 1000 // typeSanitizer - ruleId_AddDomainConstraints // addDomainConstraints - ruleId_AddDomainConstraintsToCasts - ruleId_AssignInsertCasts // assignInsertCasts - ruleId_AssignUpdateCasts // assignUpdateCasts - ruleId_ReplaceIndexedTables // replaceIndexedTables - ruleId_ReplaceSerial // replaceSerial - ruleId_AddImplicitPrefixLengths // addImplicitPrefixLengths - ruleId_InsertContextRootFinalizer // insertContextRootFinalizer - ruleId_ResolveType // resolveType - ruleId_ReplaceArithmeticExpressions // replaceArithmeticExpressions - ruleId_OptimizeFunctions // optimizeFunctions + ruleId_TypeSanitizer analyzer.RuleId = iota + 1000 // typeSanitizer + ruleId_AddDomainConstraints // addDomainConstraints + ruleId_AddDomainConstraintsToCasts // addDomainConstraintsToCasts + ruleId_AssignInsertCasts // assignInsertCasts + ruleId_AssignUpdateCasts // assignUpdateCasts + ruleId_ReplaceIndexedTables // replaceIndexedTables + ruleId_ReplaceNode // replaceNode + ruleId_ReplaceSerial // replaceSerial + ruleId_AddImplicitPrefixLengths // addImplicitPrefixLengths + ruleId_InsertContextRootFinalizer // insertContextRootFinalizer + ruleId_ResolveType // resolveType + ruleId_ReplaceArithmeticExpressions // replaceArithmeticExpressions + ruleId_OptimizeFunctions // optimizeFunctions ) // Init adds additional rules to the analyzer to handle Doltgres-specific functionality. @@ -71,6 +72,7 @@ func Init() { analyzer.Rule{Id: ruleId_OptimizeFunctions, Apply: OptimizeFunctions}, // AddDomainConstraintsToCasts needs to run after 'assignExecIndexes' rule in GMS. analyzer.Rule{Id: ruleId_AddDomainConstraintsToCasts, Apply: AddDomainConstraintsToCasts}, + analyzer.Rule{Id: ruleId_ReplaceNode, Apply: ReplaceNode}, analyzer.Rule{Id: ruleId_InsertContextRootFinalizer, Apply: InsertContextRootFinalizer}) } diff --git a/server/analyzer/replace_node.go b/server/analyzer/replace_node.go new file mode 100644 index 0000000000..438d223e00 --- /dev/null +++ b/server/analyzer/replace_node.go @@ -0,0 +1,36 @@ +// Copyright 2025 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 analyzer + +import ( + "github.com/dolthub/go-mysql-server/sql" + "github.com/dolthub/go-mysql-server/sql/analyzer" + "github.com/dolthub/go-mysql-server/sql/plan" + "github.com/dolthub/go-mysql-server/sql/transform" + + pgnodes "github.com/dolthub/doltgresql/server/node" +) + +// ReplaceNode is used to replace generic top-level nodes with Doltgres versions that wrap them, without performing any +// additional analysis. This is used to handle relatively straightforward tasks, like delete cascading, etc. +func ReplaceNode(ctx *sql.Context, a *analyzer.Analyzer, node sql.Node, scope *plan.Scope, selector analyzer.RuleSelector, qFlags *sql.QueryFlags) (sql.Node, transform.TreeIdentity, error) { + // TODO: need to add the majority of other DDL operations here + switch node := node.(type) { + case *plan.DropTable: + return pgnodes.NewDropTable(node), transform.NewTree, nil + default: + return node, transform.SameTree, nil + } +} diff --git a/server/analyzer/serial.go b/server/analyzer/serial.go index 9f83e69cd2..e4e0a25e04 100644 --- a/server/analyzer/serial.go +++ b/server/analyzer/serial.go @@ -24,6 +24,7 @@ import ( "github.com/dolthub/go-mysql-server/sql/transform" "github.com/dolthub/doltgresql/core" + "github.com/dolthub/doltgresql/core/id" "github.com/dolthub/doltgresql/core/sequences" pgexprs "github.com/dolthub/doltgresql/server/expression" "github.com/dolthub/doltgresql/server/functions/framework" @@ -100,7 +101,7 @@ func ReplaceSerial(ctx *sql.Context, a *analyzer.Analyzer, node sql.Node, scope Parenthesized: false, } ctSequences = append(ctSequences, pgnodes.NewCreateSequence(false, "", &sequences.Sequence{ - Name: sequenceName, + Name: id.NewInternalSequence("", sequenceName), DataTypeID: col.Type.(*pgtypes.DoltgresType).ID, Persistence: sequences.Persistence_Permanent, Start: 1, @@ -111,7 +112,7 @@ func ReplaceSerial(ctx *sql.Context, a *analyzer.Analyzer, node sql.Node, scope Cache: 1, Cycle: false, IsAtEnd: false, - OwnerTable: createTable.Name(), + OwnerTable: id.NewInternalTable("", createTable.Name()), OwnerColumn: col.Name, })) } diff --git a/server/ast/create_sequence.go b/server/ast/create_sequence.go index f4f30ec6a0..ed4196740b 100644 --- a/server/ast/create_sequence.go +++ b/server/ast/create_sequence.go @@ -20,6 +20,7 @@ import ( vitess "github.com/dolthub/vitess/go/vt/sqlparser" + "github.com/dolthub/doltgresql/core/id" "github.com/dolthub/doltgresql/core/sequences" "github.com/dolthub/doltgresql/postgres/parser/sem/tree" pgnodes "github.com/dolthub/doltgresql/server/node" @@ -178,7 +179,7 @@ func nodeCreateSequence(ctx *Context, node *tree.CreateSequence) (vitess.Stateme // Returns the stored procedure call with all options return vitess.InjectedStatement{ Statement: pgnodes.NewCreateSequence(node.IfNotExists, name.SchemaQualifier.String(), &sequences.Sequence{ - Name: name.Name.String(), + Name: id.NewInternalSequence("", name.Name.String()), DataTypeID: dataType.ID, Persistence: sequences.Persistence_Permanent, Start: start, @@ -189,7 +190,7 @@ func nodeCreateSequence(ctx *Context, node *tree.CreateSequence) (vitess.Stateme Cache: 1, Cycle: cycle, IsAtEnd: false, - OwnerTable: ownerTableName, + OwnerTable: id.NewInternalTable("", ownerTableName), OwnerColumn: ownerColumnName, }), Children: nil, diff --git a/server/ast/expr.go b/server/ast/expr.go index db8778d5c7..a5c86b551f 100644 --- a/server/ast/expr.go +++ b/server/ast/expr.go @@ -18,7 +18,6 @@ import ( "context" "fmt" "go/constant" - "strconv" "strings" "github.com/dolthub/go-mysql-server/sql/expression" @@ -506,7 +505,7 @@ func nodeExpr(ctx *Context, node tree.Expr) (vitess.Expr, error) { case *tree.DOid: internalID := id.Cache().ToInternal(uint32(node.DInt)) if !internalID.IsValid() { - internalID = id.NewInternal(id.Section_OID, strconv.FormatUint(uint64(node.DInt), 10)) + internalID = id.NewInternalOID(uint32(node.DInt)).Internal() } return vitess.InjectedExpr{ Expression: pgexprs.NewRawLiteralOid(internalID), diff --git a/server/auth/role.go b/server/auth/role.go index d5254f1f2a..7161036f44 100644 --- a/server/auth/role.go +++ b/server/auth/role.go @@ -40,6 +40,7 @@ type Role struct { // process. IDs are useful for referencing a specific role without using their name, since names can change. This is // basically a special OID specific to roles. Eventually, we'll have a proper OID system, but this is a placeholder for // now. +// TODO: need to replace with id.InternalUser type RoleID uint64 // CreateDefaultRole creates the given role object with all default values set. diff --git a/server/cast/int16.go b/server/cast/int16.go index 3e7f444621..b1ed82e0e5 100644 --- a/server/cast/int16.go +++ b/server/cast/int16.go @@ -15,8 +15,6 @@ package cast import ( - "strconv" - "github.com/dolthub/go-mysql-server/sql" "github.com/shopspring/decimal" @@ -74,7 +72,7 @@ func int16Implicit() { if internalID := id.Cache().ToInternal(uint32(val.(int16))); internalID.IsValid() { return internalID, nil } - return id.NewInternal(id.Section_OID, strconv.FormatUint(uint64(val.(int16)), 10)), nil + return id.NewInternalOID(uint32(val.(int16))).Internal(), nil }, }) framework.MustAddImplicitTypeCast(framework.TypeCast{ @@ -84,7 +82,7 @@ func int16Implicit() { if internalID := id.Cache().ToInternal(uint32(val.(int16))); internalID.IsValid() { return internalID, nil } - return id.NewInternal(id.Section_OID, strconv.FormatUint(uint64(val.(int16)), 10)), nil + return id.NewInternalOID(uint32(val.(int16))).Internal(), nil }, }) framework.MustAddImplicitTypeCast(framework.TypeCast{ @@ -94,7 +92,7 @@ func int16Implicit() { if internalID := id.Cache().ToInternal(uint32(val.(int16))); internalID.IsValid() { return internalID, nil } - return id.NewInternal(id.Section_OID, strconv.FormatUint(uint64(val.(int16)), 10)), nil + return id.NewInternalOID(uint32(val.(int16))).Internal(), nil }, }) framework.MustAddImplicitTypeCast(framework.TypeCast{ @@ -104,7 +102,7 @@ func int16Implicit() { if internalID := id.Cache().ToInternal(uint32(val.(int16))); internalID.IsValid() { return internalID, nil } - return id.NewInternal(id.Section_OID, strconv.FormatUint(uint64(val.(int16)), 10)), nil + return id.NewInternalOID(uint32(val.(int16))).Internal(), nil }, }) } diff --git a/server/cast/int32.go b/server/cast/int32.go index 091c30b76b..732c985800 100644 --- a/server/cast/int32.go +++ b/server/cast/int32.go @@ -16,7 +16,6 @@ package cast import ( "fmt" - "strconv" "github.com/dolthub/go-mysql-server/sql" "github.com/shopspring/decimal" @@ -95,7 +94,7 @@ func int32Implicit() { if internalID := id.Cache().ToInternal(uint32(val.(int32))); internalID.IsValid() { return internalID, nil } - return id.NewInternal(id.Section_OID, strconv.FormatUint(uint64(val.(int32)), 10)), nil + return id.NewInternalOID(uint32(val.(int32))).Internal(), nil }, }) framework.MustAddImplicitTypeCast(framework.TypeCast{ @@ -105,7 +104,7 @@ func int32Implicit() { if internalID := id.Cache().ToInternal(uint32(val.(int32))); internalID.IsValid() { return internalID, nil } - return id.NewInternal(id.Section_OID, strconv.FormatUint(uint64(val.(int32)), 10)), nil + return id.NewInternalOID(uint32(val.(int32))).Internal(), nil }, }) framework.MustAddImplicitTypeCast(framework.TypeCast{ @@ -115,7 +114,7 @@ func int32Implicit() { if internalID := id.Cache().ToInternal(uint32(val.(int32))); internalID.IsValid() { return internalID, nil } - return id.NewInternal(id.Section_OID, strconv.FormatUint(uint64(val.(int32)), 10)), nil + return id.NewInternalOID(uint32(val.(int32))).Internal(), nil }, }) framework.MustAddImplicitTypeCast(framework.TypeCast{ @@ -125,7 +124,7 @@ func int32Implicit() { if internalID := id.Cache().ToInternal(uint32(val.(int32))); internalID.IsValid() { return internalID, nil } - return id.NewInternal(id.Section_OID, strconv.FormatUint(uint64(val.(int32)), 10)), nil + return id.NewInternalOID(uint32(val.(int32))).Internal(), nil }, }) } diff --git a/server/cast/int64.go b/server/cast/int64.go index ef35aa9b8a..d881fc4820 100644 --- a/server/cast/int64.go +++ b/server/cast/int64.go @@ -16,7 +16,6 @@ package cast import ( "fmt" - "strconv" "github.com/dolthub/go-mysql-server/sql" "github.com/shopspring/decimal" @@ -89,7 +88,7 @@ func int64Implicit() { if internalID := id.Cache().ToInternal(uint32(val.(int64))); internalID.IsValid() { return internalID, nil } - return id.NewInternal(id.Section_OID, strconv.FormatUint(uint64(val.(int64)), 10)), nil + return id.NewInternalOID(uint32(val.(int64))).Internal(), nil }, }) framework.MustAddImplicitTypeCast(framework.TypeCast{ @@ -102,7 +101,7 @@ func int64Implicit() { if internalID := id.Cache().ToInternal(uint32(val.(int64))); internalID.IsValid() { return internalID, nil } - return id.NewInternal(id.Section_OID, strconv.FormatUint(uint64(val.(int64)), 10)), nil + return id.NewInternalOID(uint32(val.(int64))).Internal(), nil }, }) framework.MustAddImplicitTypeCast(framework.TypeCast{ @@ -115,7 +114,7 @@ func int64Implicit() { if internalID := id.Cache().ToInternal(uint32(val.(int64))); internalID.IsValid() { return internalID, nil } - return id.NewInternal(id.Section_OID, strconv.FormatUint(uint64(val.(int64)), 10)), nil + return id.NewInternalOID(uint32(val.(int64))).Internal(), nil }, }) framework.MustAddImplicitTypeCast(framework.TypeCast{ @@ -128,7 +127,7 @@ func int64Implicit() { if internalID := id.Cache().ToInternal(uint32(val.(int64))); internalID.IsValid() { return internalID, nil } - return id.NewInternal(id.Section_OID, strconv.FormatUint(uint64(val.(int64)), 10)), nil + return id.NewInternalOID(uint32(val.(int64))).Internal(), nil }, }) } diff --git a/server/connection_data.go b/server/connection_data.go index fc840da827..aec4866d7d 100644 --- a/server/connection_data.go +++ b/server/connection_data.go @@ -121,7 +121,7 @@ func extractBindVarTypes(queryPlan sql.Node) ([]uint32, error) { case *expression.BindVar: var typOid uint32 if doltgresType, ok := e.Type().(*pgtypes.DoltgresType); ok { - typOid = id.Cache().ToOID(doltgresType.ID) + typOid = id.Cache().ToOID(doltgresType.ID.Internal()) } else { // TODO: should remove usage non doltgres type typOid, err = VitessTypeToObjectID(e.Type().Type()) @@ -135,7 +135,7 @@ func extractBindVarTypes(queryPlan sql.Node) ([]uint32, error) { if bindVar, ok := e.Child().(*expression.BindVar); ok { var typOid uint32 if doltgresType, ok := bindVar.Type().(*pgtypes.DoltgresType); ok { - typOid = id.Cache().ToOID(doltgresType.ID) + typOid = id.Cache().ToOID(doltgresType.ID.Internal()) } else { typOid, err = VitessTypeToObjectID(e.Type().Type()) if err != nil { diff --git a/server/doltgres_handler.go b/server/doltgres_handler.go index cd015c45a4..5415f06923 100644 --- a/server/doltgres_handler.go +++ b/server/doltgres_handler.go @@ -162,7 +162,7 @@ func (h *DoltgresHandler) ComPrepareParsed(ctx context.Context, c *mysql.Conn, q fields = []pgproto3.FieldDescription{ { Name: []byte("Rows"), - DataTypeOID: id.Cache().ToOID(pgtypes.Int32.ID), + DataTypeOID: id.Cache().ToOID(pgtypes.Int32.ID.Internal()), DataTypeSize: int16(pgtypes.Int32.MaxTextResponseByteLength(nil)), }, } @@ -256,7 +256,7 @@ func (h *DoltgresHandler) convertBindParameters(ctx *sql.Context, types []uint32 return nil, err } - pgTyp, ok := pgtypes.InternalToBuiltInDoltgresType[id.Cache().ToInternal(typ)] + pgTyp, ok := pgtypes.InternalToBuiltInDoltgresType[id.InternalType(id.Cache().ToInternal(typ))] if !ok { return nil, fmt.Errorf("unhandled oid type: %v", typ) } @@ -398,9 +398,9 @@ func schemaToFieldDescriptions(ctx *sql.Context, s sql.Schema) []pgproto3.FieldD var err error if doltgresType, ok := c.Type.(*pgtypes.DoltgresType); ok { if doltgresType.TypType == pgtypes.TypeType_Domain { - oid = id.Cache().ToOID(doltgresType.BaseTypeID) + oid = id.Cache().ToOID(doltgresType.BaseTypeID.Internal()) } else { - oid = id.Cache().ToOID(doltgresType.ID) + oid = id.Cache().ToOID(doltgresType.ID.Internal()) } typmod = doltgresType.GetAttTypMod() // pg_attribute.atttypmod } else { diff --git a/server/functions/array.go b/server/functions/array.go index 14455057b3..6684a128d6 100644 --- a/server/functions/array.go +++ b/server/functions/array.go @@ -47,7 +47,7 @@ var array_in = framework.Function3{ Callable: func(ctx *sql.Context, _ [4]*pgtypes.DoltgresType, val1, val2, val3 any) (any, error) { input := val1.(string) baseTypeOid := val2.(id.Internal) - baseType := pgtypes.InternalToBuiltInDoltgresType[baseTypeOid] + baseType := pgtypes.InternalToBuiltInDoltgresType[id.InternalType(baseTypeOid)] typmod := val3.(int32) baseType = baseType.WithAttTypMod(typmod) if len(input) < 2 || input[0] != '{' || input[len(input)-1] != '}' { @@ -166,7 +166,7 @@ var array_recv = framework.Function3{ Callable: func(ctx *sql.Context, _ [4]*pgtypes.DoltgresType, val1, val2, val3 any) (any, error) { data := val1.([]byte) baseTypeOid := val2.(id.Internal) - baseType := pgtypes.InternalToBuiltInDoltgresType[baseTypeOid] + baseType := pgtypes.InternalToBuiltInDoltgresType[id.InternalType(baseTypeOid)] typmod := val3.(int32) baseType = baseType.WithAttTypMod(typmod) // Check for the nil value, then ensure the minimum length of the slice diff --git a/server/functions/domain.go b/server/functions/domain.go index 2c25cf3ff0..e401d99408 100644 --- a/server/functions/domain.go +++ b/server/functions/domain.go @@ -37,7 +37,7 @@ var domain_in = framework.Function3{ Callable: func(ctx *sql.Context, _ [4]*pgtypes.DoltgresType, val1, val2, val3 any) (any, error) { str := val1.(string) baseTypeOid := val2.(id.Internal) - t := pgtypes.InternalToBuiltInDoltgresType[baseTypeOid] + t := pgtypes.InternalToBuiltInDoltgresType[id.InternalType(baseTypeOid)] typmod := val3.(int32) t = t.WithAttTypMod(typmod) return t.IoInput(ctx, str) @@ -52,7 +52,7 @@ var domain_recv = framework.Function3{ Callable: func(ctx *sql.Context, _ [4]*pgtypes.DoltgresType, val1, val2, val3 any) (any, error) { data := val1.([]byte) baseTypeOid := val2.(id.Internal) - t := pgtypes.InternalToBuiltInDoltgresType[baseTypeOid] + t := pgtypes.InternalToBuiltInDoltgresType[id.InternalType(baseTypeOid)] typmod := val3.(int32) t = t.WithAttTypMod(typmod) return t.DeserializeValue(data) diff --git a/server/functions/framework/cast.go b/server/functions/framework/cast.go index a6853d1561..65bbf8f10b 100644 --- a/server/functions/framework/cast.go +++ b/server/functions/framework/cast.go @@ -45,28 +45,28 @@ type TypeCast struct { var explicitTypeCastMutex = &sync.RWMutex{} // explicitTypeCastsMap is a map that maps: from -> to -> function. -var explicitTypeCastsMap = map[id.Internal]map[id.Internal]TypeCastFunction{} +var explicitTypeCastsMap = map[id.InternalType]map[id.InternalType]TypeCastFunction{} // explicitTypeCastsArray is a slice that holds all registered explicit casts from the given type. -var explicitTypeCastsArray = map[id.Internal][]*pgtypes.DoltgresType{} +var explicitTypeCastsArray = map[id.InternalType][]*pgtypes.DoltgresType{} // assignmentTypeCastMutex is used to lock the assignment type cast map and array when writing. var assignmentTypeCastMutex = &sync.RWMutex{} // assignmentTypeCastsMap is a map that maps: from -> to -> function. -var assignmentTypeCastsMap = map[id.Internal]map[id.Internal]TypeCastFunction{} +var assignmentTypeCastsMap = map[id.InternalType]map[id.InternalType]TypeCastFunction{} // assignmentTypeCastsArray is a slice that holds all registered assignment casts from the given type. -var assignmentTypeCastsArray = map[id.Internal][]*pgtypes.DoltgresType{} +var assignmentTypeCastsArray = map[id.InternalType][]*pgtypes.DoltgresType{} // implicitTypeCastMutex is used to lock the implicit type cast map and array when writing. var implicitTypeCastMutex = &sync.RWMutex{} // implicitTypeCastsMap is a map that maps: from -> to -> function. -var implicitTypeCastsMap = map[id.Internal]map[id.Internal]TypeCastFunction{} +var implicitTypeCastsMap = map[id.InternalType]map[id.InternalType]TypeCastFunction{} // implicitTypeCastsArray is a slice that holds all registered implicit casts from the given type. -var implicitTypeCastsArray = map[id.Internal][]*pgtypes.DoltgresType{} +var implicitTypeCastsArray = map[id.InternalType][]*pgtypes.DoltgresType{} // AddExplicitTypeCast registers the given explicit type cast. func AddExplicitTypeCast(cast TypeCast) error { @@ -105,12 +105,12 @@ func MustAddImplicitTypeCast(cast TypeCast) { } // GetPotentialExplicitCasts returns all registered explicit type casts from the given type. -func GetPotentialExplicitCasts(fromType id.Internal) []*pgtypes.DoltgresType { +func GetPotentialExplicitCasts(fromType id.InternalType) []*pgtypes.DoltgresType { return getPotentialCasts(explicitTypeCastMutex, explicitTypeCastsArray, fromType) } // GetPotentialAssignmentCasts returns all registered assignment and implicit type casts from the given type. -func GetPotentialAssignmentCasts(fromType id.Internal) []*pgtypes.DoltgresType { +func GetPotentialAssignmentCasts(fromType id.InternalType) []*pgtypes.DoltgresType { assignment := getPotentialCasts(assignmentTypeCastMutex, assignmentTypeCastsArray, fromType) implicit := GetPotentialImplicitCasts(fromType) both := make([]*pgtypes.DoltgresType, len(assignment)+len(implicit)) @@ -120,7 +120,7 @@ func GetPotentialAssignmentCasts(fromType id.Internal) []*pgtypes.DoltgresType { } // GetPotentialImplicitCasts returns all registered implicit type casts from the given type. -func GetPotentialImplicitCasts(fromType id.Internal) []*pgtypes.DoltgresType { +func GetPotentialImplicitCasts(fromType id.InternalType) []*pgtypes.DoltgresType { return getPotentialCasts(implicitTypeCastMutex, implicitTypeCastsArray, fromType) } @@ -213,14 +213,14 @@ func GetImplicitCast(fromType *pgtypes.DoltgresType, toType *pgtypes.DoltgresTyp // addTypeCast registers the given type cast. func addTypeCast(mutex *sync.RWMutex, - castMap map[id.Internal]map[id.Internal]TypeCastFunction, - castArray map[id.Internal][]*pgtypes.DoltgresType, cast TypeCast) error { + castMap map[id.InternalType]map[id.InternalType]TypeCastFunction, + castArray map[id.InternalType][]*pgtypes.DoltgresType, cast TypeCast) error { mutex.Lock() defer mutex.Unlock() toMap, ok := castMap[cast.FromType.ID] if !ok { - toMap = map[id.Internal]TypeCastFunction{} + toMap = map[id.InternalType]TypeCastFunction{} castMap[cast.FromType.ID] = toMap castArray[cast.FromType.ID] = nil } @@ -234,7 +234,7 @@ func addTypeCast(mutex *sync.RWMutex, } // getPotentialCasts returns all registered type casts from the given type. -func getPotentialCasts(mutex *sync.RWMutex, castArray map[id.Internal][]*pgtypes.DoltgresType, fromType id.Internal) []*pgtypes.DoltgresType { +func getPotentialCasts(mutex *sync.RWMutex, castArray map[id.InternalType][]*pgtypes.DoltgresType, fromType id.InternalType) []*pgtypes.DoltgresType { mutex.RLock() defer mutex.RUnlock() @@ -244,7 +244,7 @@ func getPotentialCasts(mutex *sync.RWMutex, castArray map[id.Internal][]*pgtypes // getCast returns the type cast function that will cast the "from" type to the "to" type. Returns nil if such a cast is // not valid. func getCast(mutex *sync.RWMutex, - castMap map[id.Internal]map[id.Internal]TypeCastFunction, + castMap map[id.InternalType]map[id.InternalType]TypeCastFunction, fromType *pgtypes.DoltgresType, toType *pgtypes.DoltgresType, outerFunc getCastFunction) TypeCastFunction { mutex.RLock() defer mutex.RUnlock() diff --git a/server/functions/framework/functions.go b/server/functions/framework/functions.go index 5fdc9851bd..a3ad55218b 100644 --- a/server/functions/framework/functions.go +++ b/server/functions/framework/functions.go @@ -135,7 +135,7 @@ func (f Function0) IsStrict() bool { return f.Strict } // InternalID implements the FunctionInterface interface. func (f Function0) InternalID() id.Internal { - return id.NewInternal(id.Section_Function, "pg_catalog", f.Name) + return id.NewInternalFunction("pg_catalog", f.Name).Internal() } // enforceInterfaceInheritance implements the FunctionInterface interface. @@ -170,7 +170,7 @@ func (f Function1) IsStrict() bool { return f.Strict } // InternalID implements the FunctionInterface interface. func (f Function1) InternalID() id.Internal { - return id.NewInternal(id.Section_Function, "pg_catalog", f.Name, string(f.Parameters[0].ID)) + return id.NewInternalFunction("pg_catalog", f.Name, f.Parameters[0].ID).Internal() } // enforceInterfaceInheritance implements the FunctionInterface interface. @@ -205,7 +205,7 @@ func (f Function2) IsStrict() bool { return f.Strict } // InternalID implements the FunctionInterface interface. func (f Function2) InternalID() id.Internal { - return id.NewInternal(id.Section_Function, "pg_catalog", f.Name, string(f.Parameters[0].ID), string(f.Parameters[1].ID)) + return id.NewInternalFunction("pg_catalog", f.Name, f.Parameters[0].ID, f.Parameters[1].ID).Internal() } // enforceInterfaceInheritance implements the FunctionInterface interface. @@ -240,7 +240,7 @@ func (f Function3) IsStrict() bool { return f.Strict } // InternalID implements the FunctionInterface interface. func (f Function3) InternalID() id.Internal { - return id.NewInternal(id.Section_Function, "pg_catalog", f.Name, string(f.Parameters[0].ID), string(f.Parameters[1].ID), string(f.Parameters[2].ID)) + return id.NewInternalFunction("pg_catalog", f.Name, f.Parameters[0].ID, f.Parameters[1].ID, f.Parameters[2].ID).Internal() } // enforceInterfaceInheritance implements the FunctionInterface interface. @@ -275,7 +275,7 @@ func (f Function4) IsStrict() bool { return f.Strict } // InternalID implements the FunctionInterface interface. func (f Function4) InternalID() id.Internal { - return id.NewInternal(id.Section_Function, "pg_catalog", f.Name, string(f.Parameters[0].ID), string(f.Parameters[1].ID), string(f.Parameters[2].ID), string(f.Parameters[3].ID)) + return id.NewInternalFunction("pg_catalog", f.Name, f.Parameters[0].ID, f.Parameters[1].ID, f.Parameters[2].ID, f.Parameters[3].ID).Internal() } // enforceInterfaceInheritance implements the FunctionInterface interface. diff --git a/server/functions/framework/operators.go b/server/functions/framework/operators.go index 86a7671b3e..b8fd1872cd 100644 --- a/server/functions/framework/operators.go +++ b/server/functions/framework/operators.go @@ -57,14 +57,14 @@ const ( // unaryFunction represents the signature for a unary function. type unaryFunction struct { Operator Operator - TypeID id.Internal + TypeID id.InternalType } // binaryFunction represents the signature for a binary function. type binaryFunction struct { Operator Operator - Left id.Internal - Right id.Internal + Left id.InternalType + Right id.InternalType } var ( diff --git a/server/functions/iterate.go b/server/functions/iterate.go index 31fff65445..c8657c672c 100644 --- a/server/functions/iterate.go +++ b/server/functions/iterate.go @@ -54,7 +54,7 @@ type Callbacks struct { // ItemCheck contains the relevant information to pass to the Check callback. type ItemCheck struct { - OID id.Internal + OID id.InternalCheck Item sql.CheckDefinition } @@ -66,25 +66,25 @@ type ColumnWithIndex struct { // ItemColumnDefault contains the relevant information to pass to the ColumnDefault callback. type ItemColumnDefault struct { - OID id.Internal + OID id.InternalColumnDefault Item ColumnWithIndex } // ItemForeignKey contains the relevant information to pass to the ForeignKey callback. type ItemForeignKey struct { - OID id.Internal + OID id.InternalForeignKey Item sql.ForeignKeyConstraint } // ItemIndex contains the relevant information to pass to the Index callback. type ItemIndex struct { - OID id.Internal + OID id.InternalIndex Item sql.Index } // ItemSchema contains the relevant information to pass to the Schema callback. type ItemSchema struct { - OID id.Internal + OID id.InternalNamespace Item sql.DatabaseSchema } @@ -94,19 +94,19 @@ func (is ItemSchema) IsSystemSchema() bool { // ItemSequence contains the relevant information to pass to the Sequence callback. type ItemSequence struct { - OID id.Internal + OID id.InternalSequence Item *sequences.Sequence } // ItemTable contains the relevant information to pass to the Table callback. type ItemTable struct { - OID id.Internal + OID id.InternalTable Item sql.Table } // ItemView contains the relevant information to pass to the View callback. type ItemView struct { - OID id.Internal + OID id.InternalView Item sql.ViewDefinition } @@ -161,7 +161,7 @@ func iterateSchemas(ctx *sql.Context, callbacks Callbacks, sortedSchemas []sql.D for _, schemaIndex := range callbacks.schemaIterationOrder(sortedSchemas) { schema := sortedSchemas[schemaIndex] itemSchema := ItemSchema{ - OID: id.NewInternal(id.Section_Namespace, schema.SchemaName()), + OID: id.NewInternalNamespace(schema.SchemaName()), Item: schema, } // Check for a schema callback @@ -181,7 +181,7 @@ func iterateSchemas(ctx *sql.Context, callbacks Callbacks, sortedSchemas []sql.D // Iterate over sequences. The map will only be populated if the sequence callback exists. for _, sequence := range sequenceMap[schema.SchemaName()] { itemSequence := ItemSequence{ - OID: id.NewInternal(id.Section_Sequence, schema.SchemaName(), sequence.OwnerTable, sequence.Name), + OID: sequence.Name, Item: sequence, } if cont, err := callbacks.Sequence(ctx, itemSchema, itemSequence); err != nil { @@ -219,7 +219,7 @@ func iterateViews(ctx *sql.Context, callbacks Callbacks, itemSchema ItemSchema) }) for _, view := range views { itemView := ItemView{ - OID: id.NewInternal(id.Section_View, itemSchema.Item.SchemaName(), view.Name), + OID: id.NewInternalView(itemSchema.Item.SchemaName(), view.Name), Item: view, } if cont, err := callbacks.View(ctx, itemSchema, itemView); err != nil { @@ -249,7 +249,7 @@ func iterateTables(ctx *sql.Context, callbacks Callbacks, itemSchema ItemSchema, return sql.ErrTableNotFound.New(tableName) } itemTable := ItemTable{ - OID: id.NewInternal(id.Section_Table, itemSchema.Item.SchemaName(), table.Name()), + OID: id.NewInternalTable(itemSchema.Item.SchemaName(), table.Name()), Item: table, } @@ -310,7 +310,7 @@ func iterateChecks(ctx *sql.Context, callbacks Callbacks, itemSchema ItemSchema, for _, check := range checks { *checkCount++ itemCheck := ItemCheck{ - OID: id.NewInternal(id.Section_Check, itemSchema.Item.SchemaName(), itemTable.Item.Name(), check.Name), + OID: id.NewInternalCheck(itemSchema.Item.SchemaName(), itemTable.Item.Name(), check.Name), Item: check, } if cont, err := callbacks.Check(ctx, itemSchema, itemTable, itemCheck); err != nil { @@ -330,7 +330,7 @@ func iterateColumnDefaults(ctx *sql.Context, callbacks Callbacks, itemSchema Ite if col.Default != nil { *columnDefaultCount++ itemColDefault := ItemColumnDefault{ - OID: id.NewInternal(id.Section_ColumnDefault, itemSchema.Item.SchemaName(), itemTable.Item.Name(), col.Name), + OID: id.NewInternalColumnDefault(itemSchema.Item.SchemaName(), itemTable.Item.Name(), col.Name), Item: ColumnWithIndex{col, i}, } if cont, err := callbacks.ColumnDefault(ctx, itemSchema, itemTable, itemColDefault); err != nil { @@ -341,7 +341,6 @@ func iterateColumnDefaults(ctx *sql.Context, callbacks Callbacks, itemSchema Ite } } return nil - } // iterateForeignKeys is called by iterateTables to handle foreign keys. @@ -357,7 +356,7 @@ func iterateForeignKeys(ctx *sql.Context, callbacks Callbacks, itemSchema ItemSc for _, foreignKey := range foreignKeys { *foreignKeyCount++ itemForeignKey := ItemForeignKey{ - OID: id.NewInternal(id.Section_ForeignKey, itemSchema.Item.SchemaName(), itemTable.Item.Name(), foreignKey.Name), + OID: id.NewInternalForeignKey(itemSchema.Item.SchemaName(), itemTable.Item.Name(), foreignKey.Name), Item: foreignKey, } if cont, err := callbacks.ForeignKey(ctx, itemSchema, itemTable, itemForeignKey); err != nil { @@ -383,7 +382,7 @@ func iterateIndexes(ctx *sql.Context, callbacks Callbacks, itemSchema ItemSchema for _, index := range indexes { *indexCount++ itemIndex := ItemIndex{ - OID: id.NewInternal(id.Section_Index, itemSchema.Item.SchemaName(), itemTable.Item.Name(), index.ID()), + OID: id.NewInternalIndex(itemSchema.Item.SchemaName(), itemTable.Item.Name(), index.ID()), Item: index, } if cont, err := callbacks.Index(ctx, itemSchema, itemTable, itemIndex); err != nil { @@ -426,7 +425,7 @@ func RunCallback(ctx *sql.Context, internalID id.Internal, callbacks Callbacks) for _, schema := range schemas { if schema.SchemaName() == internalID.Segment(0) { itemSchema = ItemSchema{ - OID: id.NewInternal(id.Section_Namespace, schema.SchemaName()), + OID: id.NewInternalNamespace(schema.SchemaName()), Item: schema, } } @@ -464,7 +463,7 @@ func RunCallback(ctx *sql.Context, internalID id.Internal, callbacks Callbacks) return sql.ErrTableNotFound.New(tableName) } itemTable := ItemTable{ - OID: id.NewInternal(id.Section_Table, itemSchema.Item.SchemaName(), table.Name()), + OID: id.NewInternalTable(itemSchema.Item.SchemaName(), table.Name()), Item: table, } switch internalID.Section() { @@ -517,7 +516,7 @@ func runCheck(ctx *sql.Context, internalID id.Internal, callbacks Callbacks, ite for _, check := range checks { if check.Name == internalID.Segment(2) { itemCheck := ItemCheck{ - OID: internalID, + OID: id.InternalCheck(internalID), Item: check, } _, err = callbacks.Check(ctx, itemSchema, itemTable, itemCheck) @@ -528,7 +527,7 @@ func runCheck(ctx *sql.Context, internalID id.Internal, callbacks Callbacks, ite return true, nil } -// runColumnDefault is called by RunCallback to handle Section_ColumnDefault. +// runColumnDefault is called by RunCallback to handle Section_Column. func runColumnDefault(ctx *sql.Context, internalID id.Internal, callbacks Callbacks, itemSchema ItemSchema, itemTable ItemTable, countedIndex *int) (cont bool, err error) { if itemSchema.Item.SchemaName() != internalID.Segment(0) && itemTable.Item.Name() != internalID.Segment(1) { return true, nil @@ -543,7 +542,7 @@ func runColumnDefault(ctx *sql.Context, internalID id.Internal, callbacks Callba for _, col := range colDefaults { if col.Column.Name == internalID.Segment(2) { itemColDefault := ItemColumnDefault{ - OID: internalID, + OID: id.InternalColumnDefault(internalID), Item: col, } _, err = callbacks.ColumnDefault(ctx, itemSchema, itemTable, itemColDefault) @@ -565,7 +564,7 @@ func runForeignKey(ctx *sql.Context, internalID id.Internal, callbacks Callbacks for _, foreignKey := range foreignKeys { if foreignKey.Name == internalID.Segment(2) { itemForeignKey := ItemForeignKey{ - OID: internalID, + OID: id.InternalForeignKey(internalID), Item: foreignKey, } _, err = callbacks.ForeignKey(ctx, itemSchema, itemTable, itemForeignKey) @@ -586,7 +585,7 @@ func runIndex(ctx *sql.Context, internalID id.Internal, callbacks Callbacks, ite for _, index := range indexes { if index.ID() == internalID.Segment(2) && itemTable.Item.Name() == index.Table() { _, err = callbacks.Index(ctx, itemSchema, itemTable, ItemIndex{ - OID: internalID, + OID: id.InternalIndex(internalID), Item: index, }) return false, err @@ -602,7 +601,7 @@ func runNamespace(ctx *sql.Context, internalID id.Internal, callbacks Callbacks, for _, schema := range sortedSchemas { if schema.SchemaName() == internalID.Segment(0) { itemSchema := ItemSchema{ - OID: internalID, + OID: id.InternalNamespace(internalID), Item: schema, } _, err := callbacks.Schema(ctx, itemSchema) @@ -624,9 +623,9 @@ func runSequence(ctx *sql.Context, internalID id.Internal, callbacks Callbacks, return nil } for _, seq := range sequencesInSchema { - if seq.Name == internalID.Segment(2) { + if id.Internal(seq.Name) == internalID { _, err = callbacks.Sequence(ctx, itemSchema, ItemSequence{ - OID: internalID, + OID: id.InternalSequence(internalID), Item: seq, }) return err @@ -644,7 +643,7 @@ func runTable(ctx *sql.Context, internalID id.Internal, callbacks Callbacks, ite return sql.ErrTableNotFound.New(internalID.Segment(1)) } itemTable := ItemTable{ - OID: internalID, + OID: id.InternalTable(internalID), Item: table, } _, err = callbacks.Table(ctx, itemSchema, itemTable) @@ -661,7 +660,7 @@ func runView(ctx *sql.Context, internalID id.Internal, callbacks Callbacks, item for _, view := range views { if view.Name == internalID.Segment(1) { _, err = callbacks.View(ctx, itemSchema, ItemView{ - OID: internalID, + OID: id.InternalView(internalID), Item: view, }) return err diff --git a/server/functions/oid.go b/server/functions/oid.go index 3334f6abdc..348c1aeeb4 100644 --- a/server/functions/oid.go +++ b/server/functions/oid.go @@ -56,7 +56,7 @@ var oidin = framework.Function1{ if internalID := id.Cache().ToInternal(uVal); internalID.IsValid() { return internalID, nil } - return id.NewInternal(id.Section_OID, strconv.FormatUint(uint64(uVal), 10)), nil + return id.NewInternalOID(uVal).Internal(), nil }, } diff --git a/server/functions/pg_get_serial_sequence.go b/server/functions/pg_get_serial_sequence.go index 10958284cf..709196b7f2 100644 --- a/server/functions/pg_get_serial_sequence.go +++ b/server/functions/pg_get_serial_sequence.go @@ -108,7 +108,7 @@ var pg_get_serial_sequence_text_text = framework.Function2{ for _, sequence := range sequences { if sequence.OwnerColumn == column.Name { // pg_get_serial_sequence() always includes the schema name in its output - return schemaName + "." + sequence.Name, nil + return schemaName + "." + sequence.Name.SequenceName(), nil } } diff --git a/server/functions/regclass.go b/server/functions/regclass.go index 06a82d439c..511a3c259e 100644 --- a/server/functions/regclass.go +++ b/server/functions/regclass.go @@ -48,7 +48,7 @@ var regclassin = framework.Function1{ if internalID := id.Cache().ToInternal(uint32(parsedOid)); internalID.IsValid() { return internalID, nil } - return id.NewInternal(id.Section_OID, strconv.FormatUint(parsedOid, 10)), nil + return id.NewInternalOID(uint32(parsedOid)).Internal(), nil } sections, err := ioInputSections(input) if err != nil { @@ -93,28 +93,28 @@ var regclassin = framework.Function1{ idxName = fmt.Sprintf("%s_pkey", index.Item.Table()) } if relationName == idxName { - resultOid = index.OID + resultOid = index.OID.Internal() return false, nil } return true, nil }, Sequence: func(ctx *sql.Context, schema ItemSchema, sequence ItemSequence) (cont bool, err error) { - if sequence.Item.Name == relationName { - resultOid = sequence.OID + if sequence.Item.Name.SequenceName() == relationName { + resultOid = sequence.OID.Internal() return false, nil } return true, nil }, Table: func(ctx *sql.Context, schema ItemSchema, table ItemTable) (cont bool, err error) { if table.Item.Name() == relationName { - resultOid = table.OID + resultOid = table.OID.Internal() return false, nil } return true, nil }, View: func(ctx *sql.Context, schema ItemSchema, view ItemView) (cont bool, err error) { if view.Item.Name == relationName { - resultOid = view.OID + resultOid = view.OID.Internal() return false, nil } return true, nil @@ -167,9 +167,9 @@ var regclassout = framework.Function1{ Sequence: func(ctx *sql.Context, schema ItemSchema, sequence ItemSequence) (cont bool, err error) { schemaName := schema.Item.SchemaName() if _, ok := schemasMap[schemaName]; ok { - output = sequence.Item.Name + output = sequence.Item.Name.SequenceName() } else { - output = fmt.Sprintf("%s.%s", schemaName, sequence.Item.Name) + output = fmt.Sprintf("%s.%s", schemaName, sequence.Item.Name.SequenceName()) } return false, nil }, diff --git a/server/functions/regproc.go b/server/functions/regproc.go index 9d70439e89..2e69d375c9 100644 --- a/server/functions/regproc.go +++ b/server/functions/regproc.go @@ -46,7 +46,7 @@ var regprocin = framework.Function1{ if internalID := id.Cache().ToInternal(uint32(parsedOid)); internalID.IsValid() { return internalID, nil } - return id.NewInternal(id.Section_OID, strconv.FormatUint(parsedOid, 10)), nil + return id.NewInternalOID(uint32(parsedOid)).Internal(), nil } sections, err := ioInputSections(input) if err != nil { diff --git a/server/functions/regtype.go b/server/functions/regtype.go index 25a485c7d2..cd626df02d 100644 --- a/server/functions/regtype.go +++ b/server/functions/regtype.go @@ -49,7 +49,7 @@ var regtypein = framework.Function1{ if internalID := id.Cache().ToInternal(uint32(parsedOid)); internalID.IsValid() { return internalID, nil } - return id.NewInternal(id.Section_OID, strconv.FormatUint(parsedOid, 10)), nil + return id.NewInternalOID(uint32(parsedOid)).Internal(), nil } sections, err := ioInputSections(input) if err != nil { @@ -78,10 +78,10 @@ var regtypein = framework.Function1{ typeName = strings.Split(typeName, "(")[0] if typeName == "char" && schema == "" { - return id.NewInternal(id.Section_Type, "pg_catalog", "bpchar"), nil + return id.NewInternalType("pg_catalog", "bpchar").Internal(), nil } - if internalID, ok := pgtypes.NameToInternalID[typeName]; ok && (internalID.Segment(0) == schema || schema == "") { - return internalID, nil + if internalID, ok := pgtypes.NameToInternalID[typeName]; ok && (internalID.SchemaName() == schema || schema == "") { + return internalID.Internal(), nil } return id.Null, pgtypes.ErrTypeDoesNotExist.New(input) }, diff --git a/server/node/create_domain.go b/server/node/create_domain.go index f518c4dd50..f4c78b11f9 100644 --- a/server/node/create_domain.go +++ b/server/node/create_domain.go @@ -72,8 +72,8 @@ func (c *CreateDomain) RowIter(ctx *sql.Context, r sql.Row) (sql.RowIter, error) return nil, types.ErrTypeAlreadyExists.New(c.Name) } - internalID := id.NewInternal(id.Section_Type, c.SchemaName, c.Name) - arrayID := id.NewInternal(id.Section_Type, c.SchemaName, "_"+c.Name) + internalID := id.NewInternalType(c.SchemaName, c.Name) + arrayID := id.NewInternalType(c.SchemaName, "_"+c.Name) var defExpr string if c.DefaultExpr != nil { diff --git a/server/node/create_sequence.go b/server/node/create_sequence.go index 6a51e47ddd..678edb9ed2 100644 --- a/server/node/create_sequence.go +++ b/server/node/create_sequence.go @@ -24,6 +24,7 @@ import ( vitess "github.com/dolthub/vitess/go/vt/sqlparser" "github.com/dolthub/doltgresql/core" + "github.com/dolthub/doltgresql/core/id" "github.com/dolthub/doltgresql/core/sequences" ) @@ -63,16 +64,18 @@ func (c *CreateSequence) Resolved() bool { // RowIter implements the interface sql.ExecSourceRel. func (c *CreateSequence) RowIter(ctx *sql.Context, r sql.Row) (sql.RowIter, error) { - if strings.HasPrefix(strings.ToLower(c.sequence.Name), "dolt") { + if strings.HasPrefix(strings.ToLower(c.sequence.Name.SequenceName()), "dolt") { return nil, fmt.Errorf("sequences cannot be prefixed with 'dolt'") } schema, err := core.GetSchemaName(ctx, nil, c.schema) if err != nil { return nil, err } + // The sequence won't have the schema filled in, so we have to do that now + c.sequence.Name = id.NewInternalSequence(schema, c.sequence.Name.SequenceName()) // Check that the sequence name is free - relationType, err := core.GetRelationType(ctx, schema, c.sequence.Name) + relationType, err := core.GetRelationType(ctx, schema, c.sequence.Name.SequenceName()) if err != nil { return nil, err } @@ -84,23 +87,25 @@ func (c *CreateSequence) RowIter(ctx *sql.Context, r sql.Row) (sql.RowIter, erro return nil, fmt.Errorf(`relation "%s" already exists`, c.sequence.Name) } // Check that the OWNED BY is valid, if it exists - if len(c.sequence.OwnerTable) > 0 { - relationType, err = core.GetRelationType(ctx, schema, c.sequence.OwnerTable) + if c.sequence.OwnerTable.IsValid() { + // The table will only have its name set, so we need to fill in the schema as well + c.sequence.OwnerTable = id.NewInternalTable(schema, c.sequence.OwnerTable.TableName()) + relationType, err = core.GetRelationType(ctx, schema, c.sequence.OwnerTable.TableName()) if err != nil { return nil, err } if relationType == core.RelationType_DoesNotExist { - return nil, fmt.Errorf(`relation "%s" does not exist`, c.sequence.OwnerTable) + return nil, fmt.Errorf(`relation "%s" does not exist`, c.sequence.OwnerTable.TableName()) } else if relationType != core.RelationType_Table { - return nil, fmt.Errorf(`sequence cannot be owned by relation "%s"`, c.sequence.OwnerTable) + return nil, fmt.Errorf(`sequence cannot be owned by relation "%s"`, c.sequence.OwnerTable.TableName()) } - table, err := core.GetDoltTableFromContext(ctx, doltdb.TableName{Name: c.sequence.OwnerTable, Schema: schema}) + table, err := core.GetDoltTableFromContext(ctx, doltdb.TableName{Name: c.sequence.OwnerTable.TableName(), Schema: schema}) if err != nil { return nil, err } if table == nil { - return nil, fmt.Errorf(`table "%s" cannot be found but says it exists`, c.sequence.OwnerTable) + return nil, fmt.Errorf(`table "%s" cannot be found but says it exists`, c.sequence.OwnerTable.TableName()) } tableSch, err := table.GetSchema(ctx) if err != nil { @@ -114,7 +119,8 @@ func (c *CreateSequence) RowIter(ctx *sql.Context, r sql.Row) (sql.RowIter, erro } } if !colFound { - return nil, fmt.Errorf(`column "%s" of relation "%s" does not exist`, c.sequence.OwnerColumn, c.sequence.OwnerTable) + return nil, fmt.Errorf(`column "%s" of relation "%s" does not exist`, + c.sequence.OwnerColumn, c.sequence.OwnerTable.TableName()) } } // Create the sequence since we know it's completely valid diff --git a/server/node/create_type.go b/server/node/create_type.go index bf6fa19011..7ce3b762de 100644 --- a/server/node/create_type.go +++ b/server/node/create_type.go @@ -110,25 +110,25 @@ func (c *CreateType) RowIter(ctx *sql.Context, r sql.Row) (sql.RowIter, error) { var newType *types.DoltgresType switch c.typType { case types.TypeType_Pseudo: - newType = types.NewShellType(ctx, id.NewInternal(id.Section_Type, c.SchemaName, c.Name)) + newType = types.NewShellType(ctx, id.NewInternalType(c.SchemaName, c.Name)) case types.TypeType_Enum: - typeID := id.NewInternal(id.Section_Type, c.SchemaName, c.Name) - arrayID := id.NewInternal(id.Section_Type, c.SchemaName, "_"+c.Name) + typeID := id.NewInternalType(c.SchemaName, c.Name) + arrayID := id.NewInternalType(c.SchemaName, "_"+c.Name) enumLabelMap := make(map[string]types.EnumLabel) for i, l := range c.Labels { if _, ok := enumLabelMap[l]; ok { // DETAIL: Key (enumtypid, enumlabel)=(16702, ok) already exists. return nil, fmt.Errorf(`duplicate key value violates unique constraint "pg_enum_typid_label_index"`) } - labelID := id.NewInternal(id.Section_EnumLabel, string(typeID), l) + labelID := id.NewInternalEnumLabel(typeID, l) el := types.NewEnumLabel(ctx, labelID, float32(i+1)) enumLabelMap[l] = el } newType = types.NewEnumType(ctx, arrayID, typeID, enumLabelMap) // TODO: store labels somewhere case types.TypeType_Composite: - typeID := id.NewInternal(id.Section_Type, c.SchemaName, c.Name) - arrayID := id.NewInternal(id.Section_Type, c.SchemaName, "_"+c.Name) + typeID := id.NewInternalType(c.SchemaName, c.Name) + arrayID := id.NewInternalType(c.SchemaName, "_"+c.Name) relID := id.Null // TODO: create relation with c.AsTypes attrs := make([]types.CompositeAttribute, len(c.AsTypes)) diff --git a/server/node/drop_sequence.go b/server/node/drop_sequence.go index 759c3194a4..06ca18c9db 100644 --- a/server/node/drop_sequence.go +++ b/server/node/drop_sequence.go @@ -17,12 +17,12 @@ package node import ( "fmt" - "github.com/dolthub/dolt/go/libraries/doltcore/doltdb" "github.com/dolthub/go-mysql-server/sql" "github.com/dolthub/go-mysql-server/sql/plan" vitess "github.com/dolthub/vitess/go/vt/sqlparser" "github.com/dolthub/doltgresql/core" + "github.com/dolthub/doltgresql/core/id" ) // DropSequence handles the DROP SEQUENCE statement. @@ -82,15 +82,17 @@ func (c *DropSequence) RowIter(ctx *sql.Context, r sql.Row) (sql.RowIter, error) if err != nil { return nil, err } - if sequence := collection.GetSequence(doltdb.TableName{Name: c.sequence, Schema: schema}); len(sequence.OwnerTable) > 0 { + sequenceID := id.NewInternalSequence(schema, c.sequence) + if sequence := collection.GetSequence(sequenceID); sequence.OwnerTable.IsValid() { if c.cascade { - // TODO: handle cascade + // TODO: if the sequence is referenced by the column's default value, then we also need to delete the default return nil, fmt.Errorf(`cascading sequence drops are not yet supported`) } else { + // TODO: this error is only true if the sequence is referenced by the column's default value return nil, fmt.Errorf(`cannot drop sequence %s because other objects depend on it`, c.sequence) } } - if err = collection.DropSequence(doltdb.TableName{Name: c.sequence, Schema: schema}); err != nil { + if err = collection.DropSequence(sequenceID); err != nil { return nil, err } return sql.RowsToRowIter(), nil diff --git a/server/node/drop_table.go b/server/node/drop_table.go new file mode 100644 index 0000000000..df598848d5 --- /dev/null +++ b/server/node/drop_table.go @@ -0,0 +1,108 @@ +// Copyright 2024 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 node + +import ( + "fmt" + + "github.com/dolthub/go-mysql-server/sql" + "github.com/dolthub/go-mysql-server/sql/plan" + "github.com/dolthub/go-mysql-server/sql/rowexec" + + "github.com/dolthub/doltgresql/core" + "github.com/dolthub/doltgresql/core/id" +) + +// DropTable is a node that implements functionality specifically relevant to Doltgres' table dropping needs. +type DropTable struct { + gmsDropTable *plan.DropTable +} + +var _ sql.ExecSourceRel = (*DropTable)(nil) + +// NewDropTable returns a new *DropTable. +func NewDropTable(dropTable *plan.DropTable) *DropTable { + return &DropTable{ + gmsDropTable: dropTable, + } +} + +// Children implements the interface sql.ExecSourceRel. +func (c *DropTable) Children() []sql.Node { + return c.gmsDropTable.Children() +} + +// IsReadOnly implements the interface sql.ExecSourceRel. +func (c *DropTable) IsReadOnly() bool { + return false +} + +// Resolved implements the interface sql.ExecSourceRel. +func (c *DropTable) Resolved() bool { + return c.gmsDropTable != nil && c.gmsDropTable.Resolved() +} + +// RowIter implements the interface sql.ExecSourceRel. +func (c *DropTable) RowIter(ctx *sql.Context, r sql.Row) (sql.RowIter, error) { + dropTableIter, err := rowexec.DefaultBuilder.Build(ctx, c.gmsDropTable, r) + if err != nil { + return nil, err + } + + for _, table := range c.gmsDropTable.Tables { + var schemaName string + var tableName string + switch table := table.(type) { + case *plan.ResolvedTable: + schemaName, err = core.GetSchemaName(ctx, table.Database(), "") + if err != nil { + return nil, err + } + tableName = table.Name() + default: + return nil, fmt.Errorf("encountered unexpected table type `%T` during DROP TABLE", table) + } + + tableID := id.NewInternalTable(schemaName, tableName).Internal() + if err = id.ValidateOperation(ctx, id.Section_Table, id.Operation_Delete, tableID, id.Null); err != nil { + return nil, err + } + if err = id.PerformOperation(ctx, id.Section_Table, id.Operation_Delete, tableID, id.Null); err != nil { + return nil, err + } + } + return dropTableIter, err +} + +// Schema implements the interface sql.ExecSourceRel. +func (c *DropTable) Schema() sql.Schema { + return c.gmsDropTable.Schema() +} + +// String implements the interface sql.ExecSourceRel. +func (c *DropTable) String() string { + return c.gmsDropTable.String() +} + +// WithChildren implements the interface sql.ExecSourceRel. +func (c *DropTable) WithChildren(children ...sql.Node) (sql.Node, error) { + gmsDropTable, err := c.gmsDropTable.WithChildren(children...) + if err != nil { + return nil, err + } + return &DropTable{ + gmsDropTable: gmsDropTable.(*plan.DropTable), + }, nil +} diff --git a/server/tables/information_schema/columns_table.go b/server/tables/information_schema/columns_table.go index 73d2bf998b..98fa381f30 100644 --- a/server/tables/information_schema/columns_table.go +++ b/server/tables/information_schema/columns_table.go @@ -304,7 +304,7 @@ func getDataAndUdtType(colType sql.Type, colName string) (string, string) { dgType, ok := colType.(*pgtypes.DoltgresType) if ok { udtName = dgType.Name() - if t, ok := partypes.OidToType[oid.Oid(id.Cache().ToOID(dgType.ID))]; ok { + if t, ok := partypes.OidToType[oid.Oid(id.Cache().ToOID(dgType.ID.Internal()))]; ok { dataType = t.SQLStandardName() } } else { diff --git a/server/tables/pgcatalog/pg_am.go b/server/tables/pgcatalog/pg_am.go index 4fd6a3e69d..9f680d1a44 100644 --- a/server/tables/pgcatalog/pg_am.go +++ b/server/tables/pgcatalog/pg_am.go @@ -104,11 +104,11 @@ type accessMethod struct { // defaultPostgresAms is the list of default access methods available in Postgres. var defaultPostgresAms = []accessMethod{ - {oid: id.NewInternal(id.Section_AccessMethod, "heap"), name: "heap", handler: "heap_tableam_handler", typ: "t"}, - {oid: id.NewInternal(id.Section_AccessMethod, "btree"), name: "btree", handler: "bthandler", typ: "i"}, - {oid: id.NewInternal(id.Section_AccessMethod, "hash"), name: "hash", handler: "hashhandler", typ: "i"}, - {oid: id.NewInternal(id.Section_AccessMethod, "gist"), name: "gist", handler: "gisthandler", typ: "i"}, - {oid: id.NewInternal(id.Section_AccessMethod, "gin"), name: "gin", handler: "ginhandler", typ: "i"}, - {oid: id.NewInternal(id.Section_AccessMethod, "spgist"), name: "spgist", handler: "spghandler", typ: "i"}, - {oid: id.NewInternal(id.Section_AccessMethod, "brin"), name: "brin", handler: "brinhandler", typ: "i"}, + {oid: id.NewInternalAccessMethod("heap").Internal(), name: "heap", handler: "heap_tableam_handler", typ: "t"}, + {oid: id.NewInternalAccessMethod("btree").Internal(), name: "btree", handler: "bthandler", typ: "i"}, + {oid: id.NewInternalAccessMethod("hash").Internal(), name: "hash", handler: "hashhandler", typ: "i"}, + {oid: id.NewInternalAccessMethod("gist").Internal(), name: "gist", handler: "gisthandler", typ: "i"}, + {oid: id.NewInternalAccessMethod("gin").Internal(), name: "gin", handler: "ginhandler", typ: "i"}, + {oid: id.NewInternalAccessMethod("spgist").Internal(), name: "spgist", handler: "spghandler", typ: "i"}, + {oid: id.NewInternalAccessMethod("brin").Internal(), name: "brin", handler: "brinhandler", typ: "i"}, } diff --git a/server/tables/pgcatalog/pg_attrdef.go b/server/tables/pgcatalog/pg_attrdef.go index 5595b4701e..fa6df36f77 100644 --- a/server/tables/pgcatalog/pg_attrdef.go +++ b/server/tables/pgcatalog/pg_attrdef.go @@ -57,7 +57,7 @@ func (p PgAttrdefHandler) RowIter(ctx *sql.Context) (sql.RowIter, error) { err := functions.IterateCurrentDatabase(ctx, functions.Callbacks{ ColumnDefault: func(ctx *sql.Context, _ functions.ItemSchema, table functions.ItemTable, col functions.ItemColumnDefault) (cont bool, err error) { attrdefCols = append(attrdefCols, col) - attrdefTableOIDs = append(attrdefTableOIDs, table.OID) + attrdefTableOIDs = append(attrdefTableOIDs, table.OID.Internal()) return true, nil }, }) @@ -111,7 +111,7 @@ func (iter *pgAttrdefRowIter) Next(ctx *sql.Context) (sql.Row, error) { // TODO: Implement adbin when pg_node_tree exists return sql.Row{ - col.OID, // oid + col.OID.Internal(), // oid tableOid, // adrelid int16(col.Item.ColumnIndex + 1), // adnum nil, // adbin diff --git a/server/tables/pgcatalog/pg_attribute.go b/server/tables/pgcatalog/pg_attribute.go index 6d882e2110..230870cbc3 100644 --- a/server/tables/pgcatalog/pg_attribute.go +++ b/server/tables/pgcatalog/pg_attribute.go @@ -61,7 +61,7 @@ func (p PgAttributeHandler) RowIter(ctx *sql.Context) (sql.RowIter, error) { for i, col := range table.Item.Schema() { cols = append(cols, col) colIdxs = append(colIdxs, i) - tableOIDs = append(tableOIDs, table.OID) + tableOIDs = append(tableOIDs, table.OID.Internal()) } return true, nil }, @@ -154,11 +154,11 @@ func (iter *pgAttributeRowIter) Next(ctx *sql.Context) (sql.Row, error) { typeOid := id.Null if doltgresType, ok := col.Type.(*pgtypes.DoltgresType); ok { - typeOid = doltgresType.ID + typeOid = doltgresType.ID.Internal() } else { // TODO: Remove once all information_schema tables are converted to use DoltgresType dt := pgtypes.FromGmsType(col.Type) - typeOid = dt.ID + typeOid = dt.ID.Internal() } // TODO: Fill in the rest of the pg_attribute columns diff --git a/server/tables/pgcatalog/pg_class.go b/server/tables/pgcatalog/pg_class.go index ad2b9720d5..660aca7716 100644 --- a/server/tables/pgcatalog/pg_class.go +++ b/server/tables/pgcatalog/pg_class.go @@ -58,44 +58,44 @@ func (p PgClassHandler) RowIter(ctx *sql.Context) (sql.RowIter, error) { err := functions.IterateCurrentDatabase(ctx, functions.Callbacks{ Index: func(ctx *sql.Context, schema functions.ItemSchema, table functions.ItemTable, index functions.ItemIndex) (cont bool, err error) { - tableHasIndexes[id.Cache().ToOID(table.OID)] = struct{}{} + tableHasIndexes[id.Cache().ToOID(table.OID.Internal())] = struct{}{} classes = append(classes, pgClass{ - oid: index.OID, + oid: index.OID.Internal(), name: getIndexName(index.Item), hasIndexes: false, kind: "i", - schemaOid: schema.OID, + schemaOid: schema.OID.Internal(), }) return true, nil }, Table: func(ctx *sql.Context, schema functions.ItemSchema, table functions.ItemTable) (cont bool, err error) { - _, hasIndexes := tableHasIndexes[id.Cache().ToOID(table.OID)] + _, hasIndexes := tableHasIndexes[id.Cache().ToOID(table.OID.Internal())] classes = append(classes, pgClass{ - oid: table.OID, + oid: table.OID.Internal(), name: table.Item.Name(), hasIndexes: hasIndexes, kind: "r", - schemaOid: schema.OID, + schemaOid: schema.OID.Internal(), }) return true, nil }, View: func(ctx *sql.Context, schema functions.ItemSchema, view functions.ItemView) (cont bool, err error) { classes = append(classes, pgClass{ - oid: view.OID, + oid: view.OID.Internal(), name: view.Item.Name, hasIndexes: false, kind: "v", - schemaOid: schema.OID, + schemaOid: schema.OID.Internal(), }) return true, nil }, Sequence: func(ctx *sql.Context, schema functions.ItemSchema, sequence functions.ItemSequence) (cont bool, err error) { classes = append(classes, pgClass{ - oid: sequence.OID, - name: sequence.Item.Name, + oid: sequence.OID.Internal(), + name: sequence.Item.Name.SequenceName(), hasIndexes: false, kind: "S", - schemaOid: schema.OID, + schemaOid: schema.OID.Internal(), }) return true, nil }, @@ -195,9 +195,9 @@ func (iter *pgClassRowIter) Next(ctx *sql.Context) (sql.Row, error) { // TODO: this is temporary definition of 'relam' field var relam = id.Null if class.kind == "i" { - relam = id.NewInternal(id.Section_AccessMethod, "btree") + relam = id.NewInternalAccessMethod("btree").Internal() } else if class.kind == "r" || class.kind == "t" { - relam = id.NewInternal(id.Section_AccessMethod, "heap") + relam = id.NewInternalAccessMethod("heap").Internal() } // TODO: Fill in the rest of the pg_class columns diff --git a/server/tables/pgcatalog/pg_constraint.go b/server/tables/pgcatalog/pg_constraint.go index c92438b5e4..44308e49ac 100644 --- a/server/tables/pgcatalog/pg_constraint.go +++ b/server/tables/pgcatalog/pg_constraint.go @@ -60,12 +60,12 @@ func (p PgConstraintHandler) RowIter(ctx *sql.Context) (sql.RowIter, error) { // We iterate over all tables first to obtain their OIDs, which we'll need to reference for foreign keys err := functions.IterateCurrentDatabase(ctx, functions.Callbacks{ Table: func(ctx *sql.Context, schema functions.ItemSchema, table functions.ItemTable) (cont bool, err error) { - inner, ok := tableOIDs[schema.OID] + inner, ok := tableOIDs[schema.OID.Internal()] if !ok { inner = make(map[string]id.Internal) - tableOIDs[schema.OID] = inner + tableOIDs[schema.OID.Internal()] = inner } - inner[table.Item.Name()] = table.OID + inner[table.Item.Name()] = table.OID.Internal() for i, col := range table.Item.Schema() { tableColToIdxMap[fmt.Sprintf("%s.%s", table.Item.Name(), col.Name)] = int16(i + 1) @@ -81,11 +81,11 @@ func (p PgConstraintHandler) RowIter(ctx *sql.Context) (sql.RowIter, error) { err = functions.IterateCurrentDatabase(ctx, functions.Callbacks{ Check: func(ctx *sql.Context, schema functions.ItemSchema, table functions.ItemTable, check functions.ItemCheck) (cont bool, err error) { constraints = append(constraints, pgConstraint{ - oid: check.OID, + oid: check.OID.Internal(), name: check.Item.Name, - schemaOid: schema.OID, + schemaOid: schema.OID.Internal(), conType: "c", - tableOid: table.OID, + tableOid: table.OID.Internal(), idxOid: id.Null, tableRefOid: id.Null, }) @@ -113,13 +113,13 @@ func (p PgConstraintHandler) RowIter(ctx *sql.Context) (sql.RowIter, error) { } constraints = append(constraints, pgConstraint{ - oid: foreignKey.OID, + oid: foreignKey.OID.Internal(), name: foreignKey.Item.Name, - schemaOid: schema.OID, + schemaOid: schema.OID.Internal(), conType: "f", - tableOid: tableOIDs[schema.OID][foreignKey.Item.Table], - idxOid: foreignKey.OID, - tableRefOid: tableOIDs[schema.OID][foreignKey.Item.ParentTable], + tableOid: tableOIDs[schema.OID.Internal()][foreignKey.Item.Table], + idxOid: foreignKey.OID.Internal(), + tableRefOid: tableOIDs[schema.OID.Internal()][foreignKey.Item.ParentTable], fkUpdateType: getFKAction(foreignKey.Item.OnUpdate), fkDeleteType: getFKAction(foreignKey.Item.OnDelete), fkMatchType: "s", @@ -144,12 +144,12 @@ func (p PgConstraintHandler) RowIter(ctx *sql.Context) (sql.RowIter, error) { } constraints = append(constraints, pgConstraint{ - oid: index.OID, + oid: index.OID.Internal(), name: getIndexName(index.Item), - schemaOid: schema.OID, + schemaOid: schema.OID.Internal(), conType: conType, - tableOid: table.OID, - idxOid: index.OID, + tableOid: table.OID.Internal(), + idxOid: index.OID.Internal(), tableRefOid: id.Null, conKey: conKey, conFkey: nil, diff --git a/server/tables/pgcatalog/pg_database.go b/server/tables/pgcatalog/pg_database.go index 45058000dd..9d98514824 100644 --- a/server/tables/pgcatalog/pg_database.go +++ b/server/tables/pgcatalog/pg_database.go @@ -114,7 +114,7 @@ func (iter *pgDatabaseRowIter) Next(ctx *sql.Context) (sql.Row, error) { } iter.idx++ db := iter.dbs[iter.idx-1] - dbOid := id.NewInternal(id.Section_Database, db.Name()) + dbOid := id.NewInternalDatabase(db.Name()).Internal() // TODO: Add the rest of the pg_database columns return sql.Row{ diff --git a/server/tables/pgcatalog/pg_index.go b/server/tables/pgcatalog/pg_index.go index d49a4e3572..db691fea98 100644 --- a/server/tables/pgcatalog/pg_index.go +++ b/server/tables/pgcatalog/pg_index.go @@ -163,8 +163,8 @@ func cacheIndexMetadata(ctx *sql.Context, cache *pgCatalogCache) error { Index: func(ctx *sql.Context, schema functions.ItemSchema, table functions.ItemTable, index functions.ItemIndex) (cont bool, err error) { indexes = append(indexes, index.Item) indexSchemas = append(indexSchemas, schema.Item.SchemaName()) - indexOIDs = append(indexOIDs, index.OID) - tableOIDs = append(tableOIDs, table.OID) + indexOIDs = append(indexOIDs, index.OID.Internal()) + tableOIDs = append(tableOIDs, table.OID.Internal()) return true, nil }, }) diff --git a/server/tables/pgcatalog/pg_namespace.go b/server/tables/pgcatalog/pg_namespace.go index ebe50db20f..e53907d4cb 100644 --- a/server/tables/pgcatalog/pg_namespace.go +++ b/server/tables/pgcatalog/pg_namespace.go @@ -57,7 +57,7 @@ func (p PgNamespaceHandler) RowIter(ctx *sql.Context) (sql.RowIter, error) { err := functions.IterateCurrentDatabase(ctx, functions.Callbacks{ Schema: func(ctx *sql.Context, schema functions.ItemSchema) (cont bool, err error) { schemaNames = append(schemaNames, schema.Item.SchemaName()) - schemaOids = append(schemaOids, schema.OID) + schemaOids = append(schemaOids, schema.OID.Internal()) return true, nil }, }) diff --git a/server/tables/pgcatalog/pg_sequence.go b/server/tables/pgcatalog/pg_sequence.go index 15bdb7a1e3..1d8ca32534 100644 --- a/server/tables/pgcatalog/pg_sequence.go +++ b/server/tables/pgcatalog/pg_sequence.go @@ -58,7 +58,7 @@ func (p PgSequenceHandler) RowIter(ctx *sql.Context) (sql.RowIter, error) { err := functions.IterateCurrentDatabase(ctx, functions.Callbacks{ Sequence: func(ctx *sql.Context, _ functions.ItemSchema, sequence functions.ItemSequence) (cont bool, err error) { sequences = append(sequences, sequence.Item) - sequenceOids = append(sequenceOids, sequence.OID) + sequenceOids = append(sequenceOids, sequence.OID.Internal()) return true, nil }, }) @@ -114,14 +114,14 @@ func (iter *pgSequenceRowIter) Next(ctx *sql.Context) (sql.Row, error) { sequence := iter.sequences[iter.idx-1] oid := iter.oids[iter.idx-1] return sql.Row{ - oid, // seqrelid - sequence.DataTypeID, // seqtypid - int64(sequence.Start), // seqstart - int64(sequence.Increment), // seqincrement - int64(sequence.Maximum), // seqmax - int64(sequence.Minimum), // seqmin - int64(sequence.Cache), // seqcache - bool(sequence.Cycle), // seqcycle + oid, // seqrelid + sequence.DataTypeID.Internal(), // seqtypid + int64(sequence.Start), // seqstart + int64(sequence.Increment), // seqincrement + int64(sequence.Maximum), // seqmax + int64(sequence.Minimum), // seqmin + int64(sequence.Cache), // seqcache + bool(sequence.Cycle), // seqcycle }, nil } diff --git a/server/tables/pgcatalog/pg_type.go b/server/tables/pgcatalog/pg_type.go index b3c10c27b9..a2f19d82b2 100644 --- a/server/tables/pgcatalog/pg_type.go +++ b/server/tables/pgcatalog/pg_type.go @@ -56,7 +56,7 @@ func (p PgTypeHandler) RowIter(ctx *sql.Context) (sql.RowIter, error) { err := functions.IterateCurrentDatabase(ctx, functions.Callbacks{ Schema: func(ctx *sql.Context, schema functions.ItemSchema) (cont bool, err error) { if schema.Item.SchemaName() == PgCatalogName { - pgCatalogOid = schema.OID + pgCatalogOid = schema.OID.Internal() return false, nil } return true, nil @@ -142,38 +142,38 @@ func (iter *pgTypeRowIter) Next(ctx *sql.Context) (sql.Row, error) { typAcl := []any(nil) return sql.Row{ - typ.ID, //oid - typ.Name(), //typname - iter.pgCatalogOid, //typnamespace - id.Null, //typowner - typ.TypLength, //typlen - typ.PassedByVal, //typbyval - string(typ.TypType), //typtype - string(typ.TypCategory), //typcategory - typ.IsPreferred, //typispreferred - typ.IsDefined, //typisdefined - typ.Delimiter, //typdelim - typ.RelID, //typrelid - typ.SubscriptFuncName(), //typsubscript - typ.Elem, //typelem - typ.Array, //typarray - typ.InputFuncName(), //typinput - typ.OutputFuncName(), //typoutput - typ.ReceiveFuncName(), //typreceive - typ.SendFuncName(), //typsend - typ.ModInFuncName(), //typmodin - typ.ModOutFuncName(), //typmodout - typ.AnalyzeFuncName(), //typanalyze - string(typ.Align), //typalign - string(typ.Storage), //typstorage - typ.NotNull, //typnotnull - typ.BaseTypeID, //typbasetype - typ.TypMod, //typtypmod - typ.NDims, //typndims - typ.TypCollation, //typcollation - typ.DefaulBin, //typdefaultbin - typ.Default, //typdefault - typAcl, //typacl + typ.ID.Internal(), //oid + typ.Name(), //typname + iter.pgCatalogOid, //typnamespace + id.Null, //typowner + typ.TypLength, //typlen + typ.PassedByVal, //typbyval + string(typ.TypType), //typtype + string(typ.TypCategory), //typcategory + typ.IsPreferred, //typispreferred + typ.IsDefined, //typisdefined + typ.Delimiter, //typdelim + typ.RelID, //typrelid + typ.SubscriptFuncName(), //typsubscript + typ.Elem.Internal(), //typelem + typ.Array.Internal(), //typarray + typ.InputFuncName(), //typinput + typ.OutputFuncName(), //typoutput + typ.ReceiveFuncName(), //typreceive + typ.SendFuncName(), //typsend + typ.ModInFuncName(), //typmodin + typ.ModOutFuncName(), //typmodout + typ.AnalyzeFuncName(), //typanalyze + string(typ.Align), //typalign + string(typ.Storage), //typstorage + typ.NotNull, //typnotnull + typ.BaseTypeID.Internal(), //typbasetype + typ.TypMod, //typtypmod + typ.NDims, //typndims + typ.TypCollation.Internal(), //typcollation + typ.DefaulBin, //typdefaultbin + typ.Default, //typdefault + typAcl, //typacl }, nil } diff --git a/server/types/any.go b/server/types/any.go index 20b81d7036..ed1fd05afb 100644 --- a/server/types/any.go +++ b/server/types/any.go @@ -30,8 +30,8 @@ var Any = &DoltgresType{ Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("-"), - Elem: id.Null, - Array: id.Null, + Elem: id.NullType, + Array: id.NullType, InputFunc: toFuncID("any_in", toInternal("cstring")), OutputFunc: toFuncID("any_out", toInternal("any")), ReceiveFunc: toFuncID("-"), @@ -42,10 +42,10 @@ var Any = &DoltgresType{ Align: TypeAlignment_Int, Storage: TypeStorage_Plain, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.Null, + TypCollation: id.NullCollation, DefaulBin: "", Default: "", Acl: nil, diff --git a/server/types/any_array.go b/server/types/any_array.go index 0d13743f77..1389dec2d1 100644 --- a/server/types/any_array.go +++ b/server/types/any_array.go @@ -31,8 +31,8 @@ var AnyArray = &DoltgresType{ Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("-"), - Elem: id.Null, - Array: id.Null, + Elem: id.NullType, + Array: id.NullType, InputFunc: toFuncID("anyarray_in", toInternal("cstring")), OutputFunc: toFuncID("anyarray_out", toInternal("anyarray")), ReceiveFunc: toFuncID("anyarray_recv", toInternal("internal")), @@ -43,10 +43,10 @@ var AnyArray = &DoltgresType{ Align: TypeAlignment_Double, Storage: TypeStorage_Extended, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.Null, + TypCollation: id.NullCollation, DefaulBin: "", Default: "", Acl: nil, diff --git a/server/types/any_element.go b/server/types/any_element.go index f4cfd365a1..5a45ae2fe9 100644 --- a/server/types/any_element.go +++ b/server/types/any_element.go @@ -30,8 +30,8 @@ var AnyElement = &DoltgresType{ Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("-"), - Elem: id.Null, - Array: id.Null, + Elem: id.NullType, + Array: id.NullType, InputFunc: toFuncID("anyelement_in", toInternal("cstring")), OutputFunc: toFuncID("anyelement_out", toInternal("anyelement")), ReceiveFunc: toFuncID("-"), @@ -42,10 +42,10 @@ var AnyElement = &DoltgresType{ Align: TypeAlignment_Int, Storage: TypeStorage_Plain, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.Null, + TypCollation: id.NullCollation, DefaulBin: "", Default: "", Acl: nil, diff --git a/server/types/any_enum.go b/server/types/any_enum.go index fb7455a6ad..a001a3fdd9 100644 --- a/server/types/any_enum.go +++ b/server/types/any_enum.go @@ -30,8 +30,8 @@ var AnyEnum = &DoltgresType{ Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("-"), - Elem: id.Null, - Array: id.Null, + Elem: id.NullType, + Array: id.NullType, InputFunc: toFuncID("anyenum_in", toInternal("cstring")), OutputFunc: toFuncID("anyenum_out", toInternal("anyenum")), ReceiveFunc: toFuncID("-"), @@ -42,10 +42,10 @@ var AnyEnum = &DoltgresType{ Align: TypeAlignment_Int, Storage: TypeStorage_Plain, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.Null, + TypCollation: id.NullCollation, DefaulBin: "", Default: "", Acl: nil, diff --git a/server/types/any_nonarray.go b/server/types/any_nonarray.go index 9cf2f0526b..d780abd738 100644 --- a/server/types/any_nonarray.go +++ b/server/types/any_nonarray.go @@ -30,8 +30,8 @@ var AnyNonArray = &DoltgresType{ Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("-"), - Elem: id.Null, - Array: id.Null, + Elem: id.NullType, + Array: id.NullType, InputFunc: toFuncID("anynonarray_in", toInternal("cstring")), OutputFunc: toFuncID("anynonarray_out", toInternal("anynonarray")), ReceiveFunc: toFuncID("-"), @@ -42,10 +42,10 @@ var AnyNonArray = &DoltgresType{ Align: TypeAlignment_Int, Storage: TypeStorage_Plain, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.Null, + TypCollation: id.NullCollation, DefaulBin: "", Default: "", Acl: nil, diff --git a/server/types/array.go b/server/types/array.go index 3ce173dd35..3fa64fb4f9 100644 --- a/server/types/array.go +++ b/server/types/array.go @@ -38,7 +38,7 @@ func CreateArrayTypeFromBaseType(baseType *DoltgresType) *DoltgresType { RelID: id.Null, SubscriptFunc: toFuncID("array_subscript_handler", toInternal("internal")), Elem: baseType.ID, - Array: id.Null, + Array: id.NullType, InputFunc: toFuncID("array_in", toInternal("cstring"), toInternal("oid"), toInternal("int4")), OutputFunc: toFuncID("array_out", toInternal("anyarray")), ReceiveFunc: toFuncID("array_recv", toInternal("internal"), toInternal("oid"), toInternal("int4")), @@ -49,7 +49,7 @@ func CreateArrayTypeFromBaseType(baseType *DoltgresType) *DoltgresType { Align: align, Storage: TypeStorage_Extended, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, TypCollation: baseType.TypCollation, diff --git a/server/types/bool.go b/server/types/bool.go index 16bdf39c0e..16b680b45a 100644 --- a/server/types/bool.go +++ b/server/types/bool.go @@ -30,7 +30,7 @@ var Bool = &DoltgresType{ Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("-"), - Elem: id.Null, + Elem: id.NullType, Array: toInternal("_bool"), InputFunc: toFuncID("boolin", toInternal("cstring")), OutputFunc: toFuncID("boolout", toInternal("bool")), @@ -42,10 +42,10 @@ var Bool = &DoltgresType{ Align: TypeAlignment_Char, Storage: TypeStorage_Plain, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.Null, + TypCollation: id.NullCollation, DefaulBin: "", Default: "", Acl: nil, diff --git a/server/types/bytea.go b/server/types/bytea.go index a753491f9f..1c3e604ce0 100644 --- a/server/types/bytea.go +++ b/server/types/bytea.go @@ -30,7 +30,7 @@ var Bytea = &DoltgresType{ Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("-"), - Elem: id.Null, + Elem: id.NullType, Array: toInternal("_bytea"), InputFunc: toFuncID("byteain", toInternal("cstring")), OutputFunc: toFuncID("byteaout", toInternal("bytea")), @@ -42,10 +42,10 @@ var Bytea = &DoltgresType{ Align: TypeAlignment_Int, Storage: TypeStorage_Extended, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.Null, + TypCollation: id.NullCollation, DefaulBin: "", Default: "", Acl: nil, diff --git a/server/types/char.go b/server/types/char.go index a9c591256c..a81e1e0ebe 100644 --- a/server/types/char.go +++ b/server/types/char.go @@ -30,7 +30,7 @@ var BpChar = &DoltgresType{ Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("-"), - Elem: id.Null, + Elem: id.NullType, Array: toInternal("_bpchar"), InputFunc: toFuncID("bpcharin", toInternal("cstring"), toInternal("oid"), toInternal("int4")), OutputFunc: toFuncID("bpcharout", toInternal("bpchar")), @@ -42,10 +42,10 @@ var BpChar = &DoltgresType{ Align: TypeAlignment_Int, Storage: TypeStorage_Extended, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.NewInternal(id.Section_Collation, "pg_catalog", "default"), + TypCollation: id.NewInternalCollation("pg_catalog", "default"), DefaulBin: "", Default: "", Acl: nil, diff --git a/server/types/composite.go b/server/types/composite.go index 84b6d4b23e..aefb17fa28 100644 --- a/server/types/composite.go +++ b/server/types/composite.go @@ -21,7 +21,7 @@ import ( ) // NewCompositeType creates new instance of composite DoltgresType. -func NewCompositeType(ctx *sql.Context, relID, arrayID, typeID id.Internal, attrs []CompositeAttribute) *DoltgresType { +func NewCompositeType(ctx *sql.Context, relID id.Internal, arrayID, typeID id.InternalType, attrs []CompositeAttribute) *DoltgresType { return &DoltgresType{ ID: typeID, TypLength: -1, @@ -33,7 +33,7 @@ func NewCompositeType(ctx *sql.Context, relID, arrayID, typeID id.Internal, attr Delimiter: ",", RelID: relID, SubscriptFunc: toFuncID("-"), - Elem: id.Null, + Elem: id.NullType, Array: arrayID, InputFunc: toFuncID("record_in", toInternal("cstring"), toInternal("oid"), toInternal("int4")), OutputFunc: toFuncID("record_out", toInternal("record")), @@ -45,10 +45,10 @@ func NewCompositeType(ctx *sql.Context, relID, arrayID, typeID id.Internal, attr Align: TypeAlignment_Double, Storage: TypeStorage_Extended, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.Null, + TypCollation: id.NullCollation, DefaulBin: "", Default: "", Acl: nil, @@ -64,13 +64,13 @@ func NewCompositeType(ctx *sql.Context, relID, arrayID, typeID id.Internal, attr type CompositeAttribute struct { relID id.Internal // ID of the relation it belongs to name string - typeID id.Internal // ID of DoltgresType - num int16 // number of the column in relation + typeID id.InternalType // ID of DoltgresType + num int16 // number of the column in relation collation string } // NewCompositeAttribute creates new instance of composite type attribute. -func NewCompositeAttribute(ctx *sql.Context, relID id.Internal, name string, typeID id.Internal, num int16, collation string) CompositeAttribute { +func NewCompositeAttribute(ctx *sql.Context, relID id.Internal, name string, typeID id.InternalType, num int16, collation string) CompositeAttribute { return CompositeAttribute{ relID: relID, name: name, diff --git a/server/types/cstring.go b/server/types/cstring.go index 41f69d57d4..630192e2d5 100644 --- a/server/types/cstring.go +++ b/server/types/cstring.go @@ -30,7 +30,7 @@ var Cstring = &DoltgresType{ Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("-"), - Elem: id.Null, + Elem: id.NullType, Array: toInternal("_cstring"), InputFunc: toFuncID("cstring_in", toInternal("cstring")), OutputFunc: toFuncID("cstring_out", toInternal("cstring")), @@ -42,10 +42,10 @@ var Cstring = &DoltgresType{ Align: TypeAlignment_Char, Storage: TypeStorage_Plain, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.Null, + TypCollation: id.NullCollation, DefaulBin: "", Default: "", Acl: nil, diff --git a/server/types/date.go b/server/types/date.go index 61c1b09046..7a56632787 100644 --- a/server/types/date.go +++ b/server/types/date.go @@ -30,7 +30,7 @@ var Date = &DoltgresType{ Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("-"), - Elem: id.Null, + Elem: id.NullType, Array: toInternal("_date"), InputFunc: toFuncID("date_in", toInternal("cstring")), OutputFunc: toFuncID("date_out", toInternal("date")), @@ -42,10 +42,10 @@ var Date = &DoltgresType{ Align: TypeAlignment_Int, Storage: TypeStorage_Plain, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.Null, + TypCollation: id.NullCollation, DefaulBin: "", Default: "", Acl: nil, diff --git a/server/types/domain.go b/server/types/domain.go index 4981ce6793..e23fa1ebb8 100644 --- a/server/types/domain.go +++ b/server/types/domain.go @@ -35,7 +35,7 @@ func NewDomainType( defaultExpr string, notNull bool, checks []*sql.CheckDefinition, - arrayID, internalID id.Internal, + arrayID, internalID id.InternalType, ) *DoltgresType { return &DoltgresType{ ID: internalID, @@ -48,7 +48,7 @@ func NewDomainType( Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("-"), - Elem: id.Null, + Elem: id.NullType, Array: arrayID, InputFunc: toFuncID("domain_in", toInternal("cstring"), toInternal("oid"), toInternal("int4")), OutputFunc: asType.OutputFunc, @@ -63,7 +63,7 @@ func NewDomainType( BaseTypeID: asType.ID, TypMod: -1, NDims: 0, - TypCollation: id.Null, + TypCollation: id.NullCollation, DefaulBin: "", Default: defaultExpr, Acl: nil, diff --git a/server/types/enum.go b/server/types/enum.go index ceff8d20c1..7d36ca0527 100644 --- a/server/types/enum.go +++ b/server/types/enum.go @@ -25,7 +25,7 @@ import ( var ErrInvalidInputValueForEnum = errors.NewKind(`invalid input value for enum %s: "%s"`) // NewEnumType creates new instance of enum DoltgresType. -func NewEnumType(ctx *sql.Context, arrayID, typeID id.Internal, labels map[string]EnumLabel) *DoltgresType { +func NewEnumType(ctx *sql.Context, arrayID, typeID id.InternalType, labels map[string]EnumLabel) *DoltgresType { return &DoltgresType{ ID: typeID, TypLength: 4, @@ -37,7 +37,7 @@ func NewEnumType(ctx *sql.Context, arrayID, typeID id.Internal, labels map[strin Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("-"), - Elem: id.Null, + Elem: id.NullType, Array: arrayID, InputFunc: toFuncID("enum_in", toInternal("cstring"), toInternal("oid")), OutputFunc: toFuncID("enum_out", toInternal("anyenum")), @@ -49,10 +49,10 @@ func NewEnumType(ctx *sql.Context, arrayID, typeID id.Internal, labels map[strin Align: TypeAlignment_Int, Storage: TypeStorage_Plain, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.Null, + TypCollation: id.NullCollation, DefaulBin: "", Default: "", Acl: nil, @@ -66,14 +66,14 @@ func NewEnumType(ctx *sql.Context, arrayID, typeID id.Internal, labels map[strin // EnumLabel represents an enum type label. // This is a pg_enum row entry. type EnumLabel struct { - ID id.Internal // First segment is the ENUM parent's Internal ID, second segment is the label + ID id.InternalEnumLabel SortOrder float32 } // NewEnumLabel creates new instance of enum type label. -func NewEnumLabel(ctx *sql.Context, typeID id.Internal, so float32) EnumLabel { +func NewEnumLabel(ctx *sql.Context, labelID id.InternalEnumLabel, so float32) EnumLabel { return EnumLabel{ - ID: typeID, + ID: labelID, SortOrder: so, } } diff --git a/server/types/float32.go b/server/types/float32.go index a23731be20..a5de29ef34 100644 --- a/server/types/float32.go +++ b/server/types/float32.go @@ -30,7 +30,7 @@ var Float32 = &DoltgresType{ Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("-"), - Elem: id.Null, + Elem: id.NullType, Array: toInternal("_float4"), InputFunc: toFuncID("float4in", toInternal("cstring")), OutputFunc: toFuncID("float4out", toInternal("float4")), @@ -42,10 +42,10 @@ var Float32 = &DoltgresType{ Align: TypeAlignment_Int, Storage: TypeStorage_Plain, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.Null, + TypCollation: id.NullCollation, DefaulBin: "", Default: "", Acl: nil, diff --git a/server/types/float64.go b/server/types/float64.go index 37a38896b6..e45e5f9e43 100644 --- a/server/types/float64.go +++ b/server/types/float64.go @@ -30,7 +30,7 @@ var Float64 = &DoltgresType{ Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("-"), - Elem: id.Null, + Elem: id.NullType, Array: toInternal("_float8"), InputFunc: toFuncID("float8in", toInternal("cstring")), OutputFunc: toFuncID("float8out", toInternal("float8")), @@ -42,10 +42,10 @@ var Float64 = &DoltgresType{ Align: TypeAlignment_Double, Storage: TypeStorage_Plain, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.Null, + TypCollation: id.NullCollation, DefaulBin: "", Default: "", Acl: nil, diff --git a/server/types/function_registry.go b/server/types/function_registry.go index 7c0625c5bb..73aa0cece7 100644 --- a/server/types/function_registry.go +++ b/server/types/function_registry.go @@ -44,8 +44,8 @@ var LoadFunctionFromCatalog func(funcName string, parameterTypes []*DoltgresType type functionRegistry struct { mutex *sync.Mutex counter uint32 - mapping map[id.Internal]uint32 - revMapping map[uint32]id.Internal + mapping map[id.InternalFunction]uint32 + revMapping map[uint32]id.InternalFunction functions [256]QuickFunction // Arbitrary number, big enough for now to fit every function in it } @@ -54,12 +54,12 @@ type functionRegistry struct { var globalFunctionRegistry = functionRegistry{ mutex: &sync.Mutex{}, counter: 1, - mapping: map[id.Internal]uint32{id.Null: 0}, - revMapping: map[uint32]id.Internal{0: id.Null}, + mapping: map[id.InternalFunction]uint32{id.NullFunction: 0}, + revMapping: map[uint32]id.InternalFunction{0: id.NullFunction}, } // InternalToRegistryID returns an ID for the given Internal ID. -func (r *functionRegistry) InternalToRegistryID(functionID id.Internal) uint32 { +func (r *functionRegistry) InternalToRegistryID(functionID id.InternalFunction) uint32 { r.mutex.Lock() defer r.mutex.Unlock() if registryID, ok := r.mapping[functionID]; ok { @@ -94,7 +94,7 @@ func (r *functionRegistry) GetFunction(id uint32) QuickFunction { } // GetInternalID returns the function's Internal ID associated with the given registry ID. -func (r *functionRegistry) GetInternalID(registryID uint32) id.Internal { +func (r *functionRegistry) GetInternalID(registryID uint32) id.InternalFunction { r.mutex.Lock() defer r.mutex.Unlock() return r.revMapping[registryID] @@ -133,36 +133,29 @@ func (r *functionRegistry) loadFunction(id uint32) QuickFunction { } // nameWithoutParams returns the name only from the given function string. -func (*functionRegistry) nameWithoutParams(functionID id.Internal) string { +func (*functionRegistry) nameWithoutParams(functionID id.InternalFunction) string { if !functionID.IsValid() { return "-" } - return functionID.Segment(1) + return functionID.FunctionName() } // toFuncSignature returns a function signature for the given Internal ID. -func (*functionRegistry) toFuncSignature(functionID id.Internal) (string, []*DoltgresType) { - data := functionID.Data() - params := make([]*DoltgresType, len(data)-2) - for i := 2; i < len(data); i++ { - typeID := id.Internal(data[i]) - params[i-2] = InternalToBuiltInDoltgresType[typeID] +func (*functionRegistry) toFuncSignature(functionID id.InternalFunction) (string, []*DoltgresType) { + internalParams := functionID.Parameters() + params := make([]*DoltgresType, len(internalParams)) + for i, internalParam := range internalParams { + params[i] = InternalToBuiltInDoltgresType[internalParam] } - return data[1], params + return functionID.FunctionName(), params } // toFuncID creates a valid function string for the given name and parameters, then registers the name with the // global functionRegistry. The ID from the registry is returned. -func toFuncID(functionName string, params ...id.Internal) uint32 { +func toFuncID(functionName string, params ...id.InternalType) uint32 { if functionName == "-" || len(functionName) == 0 { return 0 } - data := make([]string, len(params)+2) - data[0] = "pg_catalog" - data[1] = functionName - for i := range params { - data[2+i] = string(params[i]) - } - functionID := id.NewInternal(id.Section_Function, data...) + functionID := id.NewInternalFunction("pg_catalog", functionName, params...) return globalFunctionRegistry.InternalToRegistryID(functionID) } diff --git a/server/types/globals.go b/server/types/globals.go index 27844e3e27..d4e5d39d85 100644 --- a/server/types/globals.go +++ b/server/types/globals.go @@ -82,7 +82,7 @@ const ( // GetTypeByID returns the DoltgresType matching the given Internal ID. // If the Internal ID does not match a type, then nil is returned. -func GetTypeByID(internalID id.Internal) *DoltgresType { +func GetTypeByID(internalID id.InternalType) *DoltgresType { t, ok := InternalToBuiltInDoltgresType[internalID] if !ok { // TODO: return UNKNOWN? @@ -96,7 +96,7 @@ func GetTypeByID(internalID id.Internal) *DoltgresType { func GetAllBuitInTypes() []*DoltgresType { pgTypes := make([]*DoltgresType, 0, len(InternalToBuiltInDoltgresType)) for internalID, typ := range InternalToBuiltInDoltgresType { - if typ.ID == Unknown.ID && internalID.Segment(1) != "unknown" { + if typ.ID == Unknown.ID && internalID.TypeName() != "unknown" { continue } pgTypes = append(pgTypes, typ) @@ -108,7 +108,7 @@ func GetAllBuitInTypes() []*DoltgresType { } // InternalToBuiltInDoltgresType is a map of id.Internal to Doltgres' built-in type. -var InternalToBuiltInDoltgresType = map[id.Internal]*DoltgresType{ +var InternalToBuiltInDoltgresType = map[id.InternalType]*DoltgresType{ toInternal("_abstime"): Unknown, toInternal("_aclitem"): Unknown, toInternal("_bit"): Unknown, @@ -279,14 +279,14 @@ var InternalToBuiltInDoltgresType = map[id.Internal]*DoltgresType{ } // NameToInternalID is a mapping from a given name to its respective Internal ID. -var NameToInternalID = map[string]id.Internal{} +var NameToInternalID = map[string]id.InternalType{} // init, for now, fills the contents of NameToInternalID, so that we may search for types using regtype. This should be // replaced with a better abstraction at some point. func init() { for _, t := range GetAllBuitInTypes() { NameToInternalID[t.Name()] = t.ID - pt, ok := types.OidToType[oid.Oid(id.Cache().ToOID(t.ID))] + pt, ok := types.OidToType[oid.Oid(id.Cache().ToOID(t.ID.Internal()))] if ok { NameToInternalID[pt.SQLStandardName()] = t.ID } diff --git a/server/types/int16.go b/server/types/int16.go index a7afd6836e..d65f925c94 100644 --- a/server/types/int16.go +++ b/server/types/int16.go @@ -30,7 +30,7 @@ var Int16 = &DoltgresType{ Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("-"), - Elem: id.Null, + Elem: id.NullType, Array: toInternal("_int2"), InputFunc: toFuncID("int2in", toInternal("cstring")), OutputFunc: toFuncID("int2out", toInternal("int2")), @@ -42,10 +42,10 @@ var Int16 = &DoltgresType{ Align: TypeAlignment_Short, Storage: TypeStorage_Plain, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.Null, + TypCollation: id.NullCollation, DefaulBin: "", Default: "", Acl: nil, diff --git a/server/types/int16_serial.go b/server/types/int16_serial.go index 8ce3f0aa66..60b4eaf4eb 100644 --- a/server/types/int16_serial.go +++ b/server/types/int16_serial.go @@ -28,7 +28,7 @@ var Int16Serial = &DoltgresType{ Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("-"), - Elem: id.Null, + Elem: id.NullType, Array: toInternal("_int2"), InputFunc: toFuncID("int2in", toInternal("cstring")), OutputFunc: toFuncID("int2out", toInternal("int2")), @@ -40,10 +40,10 @@ var Int16Serial = &DoltgresType{ Align: TypeAlignment_Short, Storage: TypeStorage_Plain, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.Null, + TypCollation: id.NullCollation, DefaulBin: "", Default: "", Acl: nil, diff --git a/server/types/int32.go b/server/types/int32.go index b243e866ae..d67ed622a4 100644 --- a/server/types/int32.go +++ b/server/types/int32.go @@ -30,7 +30,7 @@ var Int32 = &DoltgresType{ Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("-"), - Elem: id.Null, + Elem: id.NullType, Array: toInternal("_int4"), InputFunc: toFuncID("int4in", toInternal("cstring")), OutputFunc: toFuncID("int4out", toInternal("int4")), @@ -42,10 +42,10 @@ var Int32 = &DoltgresType{ Align: TypeAlignment_Int, Storage: TypeStorage_Plain, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.Null, + TypCollation: id.NullCollation, DefaulBin: "", Default: "", Acl: nil, diff --git a/server/types/int32_serial.go b/server/types/int32_serial.go index 42442a9a84..a99b6bb29d 100644 --- a/server/types/int32_serial.go +++ b/server/types/int32_serial.go @@ -28,7 +28,7 @@ var Int32Serial = &DoltgresType{ Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("-"), - Elem: id.Null, + Elem: id.NullType, Array: toInternal("_int4"), InputFunc: toFuncID("int4in", toInternal("cstring")), OutputFunc: toFuncID("int4out", toInternal("int4")), @@ -40,10 +40,10 @@ var Int32Serial = &DoltgresType{ Align: TypeAlignment_Int, Storage: TypeStorage_Plain, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.Null, + TypCollation: id.NullCollation, DefaulBin: "", Default: "", Acl: nil, diff --git a/server/types/int64.go b/server/types/int64.go index 65d18f8a13..cc9ec13793 100644 --- a/server/types/int64.go +++ b/server/types/int64.go @@ -30,7 +30,7 @@ var Int64 = &DoltgresType{ Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("-"), - Elem: id.Null, + Elem: id.NullType, Array: toInternal("_int8"), InputFunc: toFuncID("int8in", toInternal("cstring")), OutputFunc: toFuncID("int8out", toInternal("int8")), @@ -42,10 +42,10 @@ var Int64 = &DoltgresType{ Align: TypeAlignment_Double, Storage: TypeStorage_Plain, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.Null, + TypCollation: id.NullCollation, DefaulBin: "", Default: "", Acl: nil, diff --git a/server/types/int64_serial.go b/server/types/int64_serial.go index c4671c2849..174d8f8f03 100644 --- a/server/types/int64_serial.go +++ b/server/types/int64_serial.go @@ -28,7 +28,7 @@ var Int64Serial = &DoltgresType{ Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("-"), - Elem: id.Null, + Elem: id.NullType, Array: toInternal("_int8"), InputFunc: toFuncID("int8in", toInternal("cstring")), OutputFunc: toFuncID("int8out", toInternal("int8")), @@ -40,10 +40,10 @@ var Int64Serial = &DoltgresType{ Align: TypeAlignment_Double, Storage: TypeStorage_Plain, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.Null, + TypCollation: id.NullCollation, DefaulBin: "", Default: "", Acl: nil, diff --git a/server/types/internal.go b/server/types/internal.go index 69a79fbe03..57ba5c34f1 100644 --- a/server/types/internal.go +++ b/server/types/internal.go @@ -28,8 +28,8 @@ var Internal = &DoltgresType{ Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("-"), - Elem: id.Null, - Array: id.Null, + Elem: id.NullType, + Array: id.NullType, InputFunc: toFuncID("internal_in", toInternal("cstring")), OutputFunc: toFuncID("internal_out", toInternal("internal")), ReceiveFunc: toFuncID("-"), @@ -40,10 +40,10 @@ var Internal = &DoltgresType{ Align: TypeAlignment_Double, Storage: TypeStorage_Plain, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.Null, + TypCollation: id.NullCollation, DefaulBin: "", Default: "", Acl: nil, @@ -54,7 +54,7 @@ var Internal = &DoltgresType{ // NewInternalTypeWithBaseType returns Internal type with // internal base type set with given type. -func NewInternalTypeWithBaseType(internalID id.Internal) *DoltgresType { +func NewInternalTypeWithBaseType(internalID id.InternalType) *DoltgresType { it := Internal it.BaseTypeForInternal = internalID return it diff --git a/server/types/internal_char.go b/server/types/internal_char.go index 116cce611e..61cf44ab4b 100644 --- a/server/types/internal_char.go +++ b/server/types/internal_char.go @@ -33,7 +33,7 @@ var InternalChar = &DoltgresType{ Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("-"), - Elem: id.Null, + Elem: id.NullType, Array: toInternal("_char"), InputFunc: toFuncID("charin", toInternal("cstring")), OutputFunc: toFuncID("charout", toInternal("char")), @@ -45,10 +45,10 @@ var InternalChar = &DoltgresType{ Align: TypeAlignment_Char, Storage: TypeStorage_Plain, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.Null, + TypCollation: id.NullCollation, DefaulBin: "", Default: "", Acl: nil, diff --git a/server/types/interval.go b/server/types/interval.go index 7cb405e315..96b243c999 100644 --- a/server/types/interval.go +++ b/server/types/interval.go @@ -30,7 +30,7 @@ var Interval = &DoltgresType{ Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("-"), - Elem: id.Null, + Elem: id.NullType, Array: toInternal("_interval"), InputFunc: toFuncID("interval_in", toInternal("cstring"), toInternal("oid"), toInternal("int4")), OutputFunc: toFuncID("interval_out", toInternal("interval")), @@ -42,10 +42,10 @@ var Interval = &DoltgresType{ Align: TypeAlignment_Double, Storage: TypeStorage_Plain, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.Null, + TypCollation: id.NullCollation, DefaulBin: "", Default: "", Acl: nil, diff --git a/server/types/json.go b/server/types/json.go index c91af1a376..01779fa051 100644 --- a/server/types/json.go +++ b/server/types/json.go @@ -30,7 +30,7 @@ var Json = &DoltgresType{ Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("-"), - Elem: id.Null, + Elem: id.NullType, Array: toInternal("_json"), InputFunc: toFuncID("json_in", toInternal("cstring")), OutputFunc: toFuncID("json_out", toInternal("json")), @@ -42,10 +42,10 @@ var Json = &DoltgresType{ Align: TypeAlignment_Int, Storage: TypeStorage_Extended, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.Null, + TypCollation: id.NullCollation, DefaulBin: "", Default: "", Acl: nil, diff --git a/server/types/jsonb.go b/server/types/jsonb.go index e34e586ed1..4a41f08199 100644 --- a/server/types/jsonb.go +++ b/server/types/jsonb.go @@ -30,7 +30,7 @@ var JsonB = &DoltgresType{ Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("jsonb_subscript_handler", toInternal("internal")), - Elem: id.Null, + Elem: id.NullType, Array: toInternal("_jsonb"), InputFunc: toFuncID("jsonb_in", toInternal("cstring")), OutputFunc: toFuncID("jsonb_out", toInternal("jsonb")), @@ -42,10 +42,10 @@ var JsonB = &DoltgresType{ Align: TypeAlignment_Int, Storage: TypeStorage_Extended, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.Null, + TypCollation: id.NullCollation, DefaulBin: "", Default: "", Acl: nil, diff --git a/server/types/name.go b/server/types/name.go index 98901da554..833c8a9e57 100644 --- a/server/types/name.go +++ b/server/types/name.go @@ -45,10 +45,10 @@ var Name = &DoltgresType{ Align: TypeAlignment_Char, Storage: TypeStorage_Plain, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.NewInternal(id.Section_Collation, "pg_catalog", "C"), + TypCollation: id.NewInternalCollation("pg_catalog", "C"), DefaulBin: "", Default: "", Acl: nil, diff --git a/server/types/numeric.go b/server/types/numeric.go index dbabd9c244..6f87d9fd1b 100644 --- a/server/types/numeric.go +++ b/server/types/numeric.go @@ -50,7 +50,7 @@ var Numeric = &DoltgresType{ Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("-"), - Elem: id.Null, + Elem: id.NullType, Array: toInternal("_numeric"), InputFunc: toFuncID("numeric_in", toInternal("cstring"), toInternal("oid"), toInternal("int4")), OutputFunc: toFuncID("numeric_out", toInternal("numeric")), @@ -62,10 +62,10 @@ var Numeric = &DoltgresType{ Align: TypeAlignment_Int, Storage: TypeStorage_Main, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.Null, + TypCollation: id.NullCollation, DefaulBin: "", Default: "", Acl: nil, diff --git a/server/types/oid.go b/server/types/oid.go index 70ac958770..28171913a6 100644 --- a/server/types/oid.go +++ b/server/types/oid.go @@ -30,7 +30,7 @@ var Oid = &DoltgresType{ Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("-"), - Elem: id.Null, + Elem: id.NullType, Array: toInternal("_oid"), InputFunc: toFuncID("oidin", toInternal("cstring")), OutputFunc: toFuncID("oidout", toInternal("oid")), @@ -42,10 +42,10 @@ var Oid = &DoltgresType{ Align: TypeAlignment_Int, Storage: TypeStorage_Plain, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.Null, + TypCollation: id.NullCollation, DefaulBin: "", Default: "", Acl: nil, diff --git a/server/types/record.go b/server/types/record.go index 4c7b7ba17f..7d310c9ce1 100644 --- a/server/types/record.go +++ b/server/types/record.go @@ -30,7 +30,7 @@ var Record = &DoltgresType{ Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("-"), - Elem: id.Null, + Elem: id.NullType, Array: toInternal("_record"), InputFunc: toFuncID("record_in", toInternal("cstring"), toInternal("oid"), toInternal("int4")), OutputFunc: toFuncID("record_out", toInternal("record")), @@ -42,10 +42,10 @@ var Record = &DoltgresType{ Align: TypeAlignment_Double, Storage: TypeStorage_Extended, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.Null, + TypCollation: id.NullCollation, DefaulBin: "", Default: "", Acl: nil, diff --git a/server/types/regclass.go b/server/types/regclass.go index 092e391e98..a05c014aa8 100644 --- a/server/types/regclass.go +++ b/server/types/regclass.go @@ -30,7 +30,7 @@ var Regclass = &DoltgresType{ Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("-"), - Elem: id.Null, + Elem: id.NullType, Array: toInternal("_regclass"), InputFunc: toFuncID("regclassin", toInternal("cstring")), OutputFunc: toFuncID("regclassout", toInternal("regclass")), @@ -42,10 +42,10 @@ var Regclass = &DoltgresType{ Align: TypeAlignment_Int, Storage: TypeStorage_Plain, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.Null, + TypCollation: id.NullCollation, DefaulBin: "", Default: "", Acl: nil, diff --git a/server/types/regproc.go b/server/types/regproc.go index 580383d269..fdbcab0768 100644 --- a/server/types/regproc.go +++ b/server/types/regproc.go @@ -30,7 +30,7 @@ var Regproc = &DoltgresType{ Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("-"), - Elem: id.Null, + Elem: id.NullType, Array: toInternal("_regproc"), InputFunc: toFuncID("regprocin", toInternal("cstring")), OutputFunc: toFuncID("regprocout", toInternal("regproc")), @@ -42,10 +42,10 @@ var Regproc = &DoltgresType{ Align: TypeAlignment_Int, Storage: TypeStorage_Plain, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.Null, + TypCollation: id.NullCollation, DefaulBin: "", Default: "", Acl: nil, diff --git a/server/types/regtype.go b/server/types/regtype.go index 3560689971..898a2e91bc 100644 --- a/server/types/regtype.go +++ b/server/types/regtype.go @@ -30,7 +30,7 @@ var Regtype = &DoltgresType{ Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("-"), - Elem: id.Null, + Elem: id.NullType, Array: toInternal("_regtype"), InputFunc: toFuncID("regtypein", toInternal("cstring")), OutputFunc: toFuncID("regtypeout", toInternal("regtype")), @@ -42,10 +42,10 @@ var Regtype = &DoltgresType{ Align: TypeAlignment_Int, Storage: TypeStorage_Plain, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.Null, + TypCollation: id.NullCollation, DefaulBin: "", Default: "", Acl: nil, diff --git a/server/types/serialization.go b/server/types/serialization.go index 58e8c7c064..5a2e95a0fd 100644 --- a/server/types/serialization.go +++ b/server/types/serialization.go @@ -23,6 +23,7 @@ import ( "github.com/dolthub/go-mysql-server/sql" "github.com/dolthub/go-mysql-server/sql/types" + "github.com/dolthub/doltgresql/core/id" "github.com/dolthub/doltgresql/utils" ) @@ -54,7 +55,7 @@ func DeserializeType(serializedType []byte) (types.ExtendedType, error) { return nil, fmt.Errorf("version %d of types is not supported, please upgrade the server", version) } - typ.ID = reader.Internal() + typ.ID = id.InternalType(reader.Internal()) typ.TypLength = reader.Int16() typ.PassedByVal = reader.Bool() typ.TypType = TypeType(reader.String()) @@ -63,23 +64,23 @@ func DeserializeType(serializedType []byte) (types.ExtendedType, error) { typ.IsDefined = reader.Bool() typ.Delimiter = reader.String() typ.RelID = reader.Internal() - typ.SubscriptFunc = globalFunctionRegistry.InternalToRegistryID(reader.Internal()) - typ.Elem = reader.Internal() - typ.Array = reader.Internal() - typ.InputFunc = globalFunctionRegistry.InternalToRegistryID(reader.Internal()) - typ.OutputFunc = globalFunctionRegistry.InternalToRegistryID(reader.Internal()) - typ.ReceiveFunc = globalFunctionRegistry.InternalToRegistryID(reader.Internal()) - typ.SendFunc = globalFunctionRegistry.InternalToRegistryID(reader.Internal()) - typ.ModInFunc = globalFunctionRegistry.InternalToRegistryID(reader.Internal()) - typ.ModOutFunc = globalFunctionRegistry.InternalToRegistryID(reader.Internal()) - typ.AnalyzeFunc = globalFunctionRegistry.InternalToRegistryID(reader.Internal()) + typ.SubscriptFunc = globalFunctionRegistry.InternalToRegistryID(id.InternalFunction(reader.Internal())) + typ.Elem = id.InternalType(reader.Internal()) + typ.Array = id.InternalType(reader.Internal()) + typ.InputFunc = globalFunctionRegistry.InternalToRegistryID(id.InternalFunction(reader.Internal())) + typ.OutputFunc = globalFunctionRegistry.InternalToRegistryID(id.InternalFunction(reader.Internal())) + typ.ReceiveFunc = globalFunctionRegistry.InternalToRegistryID(id.InternalFunction(reader.Internal())) + typ.SendFunc = globalFunctionRegistry.InternalToRegistryID(id.InternalFunction(reader.Internal())) + typ.ModInFunc = globalFunctionRegistry.InternalToRegistryID(id.InternalFunction(reader.Internal())) + typ.ModOutFunc = globalFunctionRegistry.InternalToRegistryID(id.InternalFunction(reader.Internal())) + typ.AnalyzeFunc = globalFunctionRegistry.InternalToRegistryID(id.InternalFunction(reader.Internal())) typ.Align = TypeAlignment(reader.String()) typ.Storage = TypeStorage(reader.String()) typ.NotNull = reader.Bool() - typ.BaseTypeID = reader.Internal() + typ.BaseTypeID = id.InternalType(reader.Internal()) typ.TypMod = reader.Int32() typ.NDims = reader.Int32() - typ.TypCollation = reader.Internal() + typ.TypCollation = id.InternalCollation(reader.Internal()) typ.DefaulBin = reader.String() typ.Default = reader.String() numOfAcl := reader.VariableUint() @@ -98,7 +99,7 @@ func DeserializeType(serializedType []byte) (types.ExtendedType, error) { }) } typ.attTypMod = reader.Int32() - typ.CompareFunc = globalFunctionRegistry.InternalToRegistryID(reader.Internal()) + typ.CompareFunc = globalFunctionRegistry.InternalToRegistryID(id.InternalFunction(reader.Internal())) numOfEnumLabels := reader.VariableUint() if numOfEnumLabels > 0 { typ.EnumLabels = make(map[string]EnumLabel) @@ -106,7 +107,7 @@ func DeserializeType(serializedType []byte) (types.ExtendedType, error) { typeID := reader.Internal() sortOrder := reader.Float32() typ.EnumLabels[typeID.Segment(1)] = EnumLabel{ - ID: typeID, + ID: id.InternalEnumLabel(typeID), SortOrder: sortOrder, } } @@ -123,7 +124,7 @@ func DeserializeType(serializedType []byte) (types.ExtendedType, error) { typ.CompositeAttrs[k] = CompositeAttribute{ relID: relID, name: name, - typeID: typeID, + typeID: id.InternalType(typeID), num: num, collation: collation, } @@ -143,7 +144,7 @@ func (t *DoltgresType) Serialize() []byte { writer := utils.NewWriter(256) writer.VariableUint(0) // Version // Write the type to the writer - writer.Internal(t.ID) + writer.Internal(t.ID.Internal()) writer.Int16(t.TypLength) writer.Bool(t.PassedByVal) writer.String(string(t.TypType)) @@ -152,23 +153,23 @@ func (t *DoltgresType) Serialize() []byte { writer.Bool(t.IsDefined) writer.String(t.Delimiter) writer.Internal(t.RelID) - writer.Internal(globalFunctionRegistry.GetInternalID(t.SubscriptFunc)) - writer.Internal(t.Elem) - writer.Internal(t.Array) - writer.Internal(globalFunctionRegistry.GetInternalID(t.InputFunc)) - writer.Internal(globalFunctionRegistry.GetInternalID(t.OutputFunc)) - writer.Internal(globalFunctionRegistry.GetInternalID(t.ReceiveFunc)) - writer.Internal(globalFunctionRegistry.GetInternalID(t.SendFunc)) - writer.Internal(globalFunctionRegistry.GetInternalID(t.ModInFunc)) - writer.Internal(globalFunctionRegistry.GetInternalID(t.ModOutFunc)) - writer.Internal(globalFunctionRegistry.GetInternalID(t.AnalyzeFunc)) + writer.Internal(globalFunctionRegistry.GetInternalID(t.SubscriptFunc).Internal()) + writer.Internal(t.Elem.Internal()) + writer.Internal(t.Array.Internal()) + writer.Internal(globalFunctionRegistry.GetInternalID(t.InputFunc).Internal()) + writer.Internal(globalFunctionRegistry.GetInternalID(t.OutputFunc).Internal()) + writer.Internal(globalFunctionRegistry.GetInternalID(t.ReceiveFunc).Internal()) + writer.Internal(globalFunctionRegistry.GetInternalID(t.SendFunc).Internal()) + writer.Internal(globalFunctionRegistry.GetInternalID(t.ModInFunc).Internal()) + writer.Internal(globalFunctionRegistry.GetInternalID(t.ModOutFunc).Internal()) + writer.Internal(globalFunctionRegistry.GetInternalID(t.AnalyzeFunc).Internal()) writer.String(string(t.Align)) writer.String(string(t.Storage)) writer.Bool(t.NotNull) - writer.Internal(t.BaseTypeID) + writer.Internal(t.BaseTypeID.Internal()) writer.Int32(t.TypMod) writer.Int32(t.NDims) - writer.Internal(t.TypCollation) + writer.Internal(t.TypCollation.Internal()) writer.String(t.DefaulBin) writer.String(t.Default) writer.VariableUint(uint64(len(t.Acl))) @@ -181,14 +182,14 @@ func (t *DoltgresType) Serialize() []byte { writer.String(check.CheckExpression) } writer.Int32(t.attTypMod) - writer.Internal(globalFunctionRegistry.GetInternalID(t.CompareFunc)) + writer.Internal(globalFunctionRegistry.GetInternalID(t.CompareFunc).Internal()) writer.VariableUint(uint64(len(t.EnumLabels))) if len(t.EnumLabels) > 0 { labels := slices.SortedFunc(maps.Values(t.EnumLabels), func(v1 EnumLabel, v2 EnumLabel) int { return cmp.Compare(v1.ID, v2.ID) }) for _, l := range labels { - writer.Internal(l.ID) + writer.Internal(l.ID.Internal()) writer.Float32(l.SortOrder) } } @@ -197,7 +198,7 @@ func (t *DoltgresType) Serialize() []byte { for _, l := range t.CompositeAttrs { writer.Internal(l.relID) writer.String(l.name) - writer.Internal(l.typeID) + writer.Internal(l.typeID.Internal()) writer.Int16(l.num) writer.String(l.collation) } diff --git a/server/types/shell.go b/server/types/shell.go index 67e96ee3a2..4a5ab3d109 100644 --- a/server/types/shell.go +++ b/server/types/shell.go @@ -25,7 +25,7 @@ import ( var ErrTypeIsOnlyAShell = errors.NewKind(`type "%s" is only a shell`) // NewShellType creates new instance of shell DoltgresType. -func NewShellType(ctx *sql.Context, internalID id.Internal) *DoltgresType { +func NewShellType(ctx *sql.Context, internalID id.InternalType) *DoltgresType { return &DoltgresType{ ID: internalID, TypLength: 4, @@ -37,8 +37,8 @@ func NewShellType(ctx *sql.Context, internalID id.Internal) *DoltgresType { Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("-"), - Elem: id.Null, - Array: id.Null, + Elem: id.NullType, + Array: id.NullType, InputFunc: toFuncID("shell_in", toInternal("cstring")), OutputFunc: toFuncID("shell_out", toInternal("void")), ReceiveFunc: toFuncID("-"), @@ -49,10 +49,10 @@ func NewShellType(ctx *sql.Context, internalID id.Internal) *DoltgresType { Align: TypeAlignment_Int, Storage: TypeStorage_Plain, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.Null, + TypCollation: id.NullCollation, DefaulBin: "", Default: "", Acl: nil, diff --git a/server/types/text.go b/server/types/text.go index 90545c0080..d41dc01925 100644 --- a/server/types/text.go +++ b/server/types/text.go @@ -30,7 +30,7 @@ var Text = &DoltgresType{ Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("-"), - Elem: id.Null, + Elem: id.NullType, Array: toInternal("_text"), InputFunc: toFuncID("textin", toInternal("cstring")), OutputFunc: toFuncID("textout", toInternal("text")), @@ -42,10 +42,10 @@ var Text = &DoltgresType{ Align: TypeAlignment_Int, Storage: TypeStorage_Extended, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.NewInternal(id.Section_Collation, "pg_catalog", "default"), + TypCollation: id.NewInternalCollation("pg_catalog", "default"), DefaulBin: "", Default: "", Acl: nil, diff --git a/server/types/time.go b/server/types/time.go index 86b40a12e6..1091f94e5f 100644 --- a/server/types/time.go +++ b/server/types/time.go @@ -32,7 +32,7 @@ var Time = &DoltgresType{ Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("-"), - Elem: id.Null, + Elem: id.NullType, Array: toInternal("_time"), InputFunc: toFuncID("time_in", toInternal("cstring"), toInternal("oid"), toInternal("int4")), OutputFunc: toFuncID("time_out", toInternal("time")), @@ -44,10 +44,10 @@ var Time = &DoltgresType{ Align: TypeAlignment_Double, Storage: TypeStorage_Plain, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.Null, + TypCollation: id.NullCollation, DefaulBin: "", Default: "", Acl: nil, diff --git a/server/types/timestamp.go b/server/types/timestamp.go index 78ab8f2079..6125e9178e 100644 --- a/server/types/timestamp.go +++ b/server/types/timestamp.go @@ -30,7 +30,7 @@ var Timestamp = &DoltgresType{ Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("-"), - Elem: id.Null, + Elem: id.NullType, Array: toInternal("_timestamp"), InputFunc: toFuncID("timestamp_in", toInternal("cstring"), toInternal("oid"), toInternal("int4")), OutputFunc: toFuncID("timestamp_out", toInternal("timestamp")), @@ -42,10 +42,10 @@ var Timestamp = &DoltgresType{ Align: TypeAlignment_Double, Storage: TypeStorage_Plain, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.Null, + TypCollation: id.NullCollation, DefaulBin: "", Default: "", Acl: nil, diff --git a/server/types/timestamptz.go b/server/types/timestamptz.go index fdf33a9356..bfa6d1b123 100644 --- a/server/types/timestamptz.go +++ b/server/types/timestamptz.go @@ -30,7 +30,7 @@ var TimestampTZ = &DoltgresType{ Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("-"), - Elem: id.Null, + Elem: id.NullType, Array: toInternal("_timestamptz"), InputFunc: toFuncID("timestamptz_in", toInternal("cstring"), toInternal("oid"), toInternal("int4")), OutputFunc: toFuncID("timestamptz_out", toInternal("timestamptz")), @@ -42,10 +42,10 @@ var TimestampTZ = &DoltgresType{ Align: TypeAlignment_Double, Storage: TypeStorage_Plain, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.Null, + TypCollation: id.NullCollation, DefaulBin: "", Default: "", Acl: nil, diff --git a/server/types/timetz.go b/server/types/timetz.go index 6ba4bee3e5..cb49e70e18 100644 --- a/server/types/timetz.go +++ b/server/types/timetz.go @@ -30,7 +30,7 @@ var TimeTZ = &DoltgresType{ Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("-"), - Elem: id.Null, + Elem: id.NullType, Array: toInternal("_timetz"), InputFunc: toFuncID("timetz_in", toInternal("cstring"), toInternal("oid"), toInternal("int4")), OutputFunc: toFuncID("timetz_out", toInternal("timetz")), @@ -42,10 +42,10 @@ var TimeTZ = &DoltgresType{ Align: TypeAlignment_Double, Storage: TypeStorage_Plain, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.Null, + TypCollation: id.NullCollation, DefaulBin: "", Default: "", Acl: nil, diff --git a/server/types/type.go b/server/types/type.go index b49fb3821f..e21e31ec29 100644 --- a/server/types/type.go +++ b/server/types/type.go @@ -36,7 +36,7 @@ import ( // DoltgresType represents a single type. type DoltgresType struct { - ID id.Internal + ID id.InternalType TypLength int16 PassedByVal bool TypType TypeType @@ -46,8 +46,8 @@ type DoltgresType struct { Delimiter string RelID id.Internal // for Composite types SubscriptFunc uint32 - Elem id.Internal - Array id.Internal + Elem id.InternalType + Array id.InternalType InputFunc uint32 OutputFunc uint32 ReceiveFunc uint32 @@ -57,11 +57,11 @@ type DoltgresType struct { AnalyzeFunc uint32 Align TypeAlignment Storage TypeStorage - NotNull bool // for Domain types - BaseTypeID id.Internal // for Domain types - TypMod int32 // for Domain types - NDims int32 // for Domain types - TypCollation id.Internal + NotNull bool // for Domain types + BaseTypeID id.InternalType // for Domain types + TypMod int32 // for Domain types + NDims int32 // for Domain types + TypCollation id.InternalCollation DefaulBin string // for Domain types Default string Acl []string // TODO: list of privileges @@ -75,9 +75,9 @@ type DoltgresType struct { CompositeAttrs []CompositeAttribute // TODO: should be in `pg_attribute` // Below are not stored - IsSerial bool // used for serial types only (e.g.: smallserial) - IsUnresolved bool // used internally to know if a type has been resolved - BaseTypeForInternal id.Internal // used for INTERNAL type only + IsSerial bool // used for serial types only (e.g.: smallserial) + IsUnresolved bool // used internally to know if a type has been resolved + BaseTypeForInternal id.InternalType // used for INTERNAL type only } var _ types.ExtendedType = &DoltgresType{} @@ -86,7 +86,7 @@ var _ types.ExtendedType = &DoltgresType{} // The type will have the schema and name defined with given values, with IsUnresolved == true. func NewUnresolvedDoltgresType(sch, name string) *DoltgresType { return &DoltgresType{ - ID: id.NewInternal(id.Section_Type, sch, name), + ID: id.NewInternalType(sch, name), IsUnresolved: true, } } @@ -112,7 +112,7 @@ func (t *DoltgresType) ArrayBaseType() *DoltgresType { // CharacterSet implements the sql.StringType interface. func (t *DoltgresType) CharacterSet() sql.CharacterSetID { - switch t.ID.Segment(1) { + switch t.ID.TypeName() { case "varchar", "text", "name": return sql.CharacterSet_binary default: @@ -122,7 +122,7 @@ func (t *DoltgresType) CharacterSet() sql.CharacterSetID { // Collation implements the sql.StringType interface. func (t *DoltgresType) Collation() sql.CollationID { - switch t.ID.Segment(1) { + switch t.ID.TypeName() { case "varchar", "text", "name": return sql.Collation_Default default: @@ -283,7 +283,7 @@ func (t *DoltgresType) Convert(v interface{}) (interface{}, sql.ConvertInRange, if v == nil { return nil, sql.InRange, nil } - switch t.ID.Segment(1) { + switch t.ID.TypeName() { case "bool": if _, ok := v.(bool); ok { return v, sql.InRange, nil @@ -352,7 +352,7 @@ func (t *DoltgresType) DomainUnderlyingBaseType() *DoltgresType { // TODO: handle user-defined type bt, ok := InternalToBuiltInDoltgresType[t.BaseTypeID] if !ok { - panic(fmt.Sprintf("unable to get DoltgresType from ID: %s", t.BaseTypeID.String())) + panic(fmt.Sprintf("unable to get DoltgresType from ID: %s", t.BaseTypeID.Internal().String())) } if bt.TypType == TypeType_Domain { return bt.DomainUnderlyingBaseType() @@ -391,15 +391,15 @@ func (t *DoltgresType) InputFuncName() string { // IoInput converts input string value to given type value. func (t *DoltgresType) IoInput(ctx *sql.Context, input string) (any, error) { if t.TypType == TypeType_Domain { - return globalFunctionRegistry.GetFunction(t.InputFunc).CallVariadic(ctx, input, t.BaseTypeID, t.attTypMod) + return globalFunctionRegistry.GetFunction(t.InputFunc).CallVariadic(ctx, input, t.BaseTypeID.Internal(), t.attTypMod) } else if t.ModInFunc != 0 || t.IsArrayType() { - if t.Elem != id.Null { - return globalFunctionRegistry.GetFunction(t.InputFunc).CallVariadic(ctx, input, t.Elem, t.attTypMod) + if t.Elem != id.NullType { + return globalFunctionRegistry.GetFunction(t.InputFunc).CallVariadic(ctx, input, t.Elem.Internal(), t.attTypMod) } else { - return globalFunctionRegistry.GetFunction(t.InputFunc).CallVariadic(ctx, input, t.ID, t.attTypMod) + return globalFunctionRegistry.GetFunction(t.InputFunc).CallVariadic(ctx, input, t.ID.Internal(), t.attTypMod) } } else if t.TypType == TypeType_Enum { - return globalFunctionRegistry.GetFunction(t.InputFunc).CallVariadic(ctx, input, t.ID) + return globalFunctionRegistry.GetFunction(t.InputFunc).CallVariadic(ctx, input, t.ID.Internal()) } else { return globalFunctionRegistry.GetFunction(t.InputFunc).CallVariadic(ctx, input) } @@ -425,7 +425,7 @@ func (t *DoltgresType) IoOutput(ctx *sql.Context, val any) (string, error) { // IsArrayType returns true if the type is of 'array' category func (t *DoltgresType) IsArrayType() bool { - return t.TypCategory == TypeCategory_ArrayTypes && t.Elem != id.Null + return t.TypCategory == TypeCategory_ArrayTypes && t.Elem != id.NullType } // IsEmptyType returns true if the type is not valid. @@ -439,7 +439,7 @@ func (t *DoltgresType) IsEmptyType() bool { // All polymorphic types have "any" as a prefix. // The exception is the "any" type, which is not a polymorphic type. func (t *DoltgresType) IsPolymorphicType() bool { - switch t.ID.Segment(1) { + switch t.ID.TypeName() { case "anyelement", "anyarray", "anynonarray", "anyenum", "anyrange": // TODO: add other polymorphic types // https://www.postgresql.org/docs/15/extend-type-system.html#EXTEND-TYPES-POLYMORPHIC-TABLE @@ -457,7 +457,7 @@ func (t *DoltgresType) IsResolvedType() bool { // IsValidForPolymorphicType returns whether the given type is valid for the calling polymorphic type. func (t *DoltgresType) IsValidForPolymorphicType(target *DoltgresType) bool { - switch t.ID.Segment(1) { + switch t.ID.TypeName() { case "anyelement": return true case "anyarray": @@ -477,7 +477,7 @@ func (t *DoltgresType) IsValidForPolymorphicType(target *DoltgresType) bool { // Length implements the sql.StringType interface. func (t *DoltgresType) Length() int64 { - switch t.ID.Segment(1) { + switch t.ID.TypeName() { case "varchar": if t.attTypMod == -1 { return StringUnbounded @@ -575,7 +575,7 @@ func (t *DoltgresType) ModOutFuncName() string { // Name returns the name of the type. func (t *DoltgresType) Name() string { - return t.ID.Segment(1) + return t.ID.TypeName() } // OutputFuncName returns the name that would be displayed in pg_type for the `typoutput` field. @@ -595,7 +595,7 @@ func (t *DoltgresType) ReceiveFuncName() string { // Schema returns the schema that the type is contained in. func (t *DoltgresType) Schema() string { - return t.ID.Segment(0) + return t.ID.SchemaName() } // SendFuncName returns the name that would be displayed in pg_type for the `typsend` field. @@ -681,7 +681,7 @@ func (t *DoltgresType) Type() query.Type { TypeCategory_InternalUseTypes: return sqltypes.Text case TypeCategory_DateTimeTypes: - switch t.ID.Segment(1) { + switch t.ID.TypeName() { case "date": return sqltypes.Date case "time": @@ -690,7 +690,7 @@ func (t *DoltgresType) Type() query.Type { return sqltypes.Timestamp } case TypeCategory_NumericTypes: - switch t.ID.Segment(1) { + switch t.ID.TypeName() { case "float4": return sqltypes.Float32 case "float8": @@ -712,7 +712,7 @@ func (t *DoltgresType) Type() query.Type { return sqltypes.Int64 } case TypeCategory_StringTypes, TypeCategory_UnknownTypes: - if t.ID.Segment(1) == "varchar" { + if t.ID.TypeName() == "varchar" { return sqltypes.VarChar } return sqltypes.Text @@ -786,7 +786,7 @@ func (t *DoltgresType) Zero() interface{} { case TypeCategory_DateTimeTypes: return time.Time{} case TypeCategory_NumericTypes: - switch t.ID.Segment(1) { + switch t.ID.TypeName() { case "float4": return float32(0) case "float8": @@ -842,15 +842,15 @@ func (t *DoltgresType) DeserializeValue(val []byte) (any, error) { return nil, nil } if t.TypType == TypeType_Domain { - return globalFunctionRegistry.GetFunction(t.ReceiveFunc).CallVariadic(nil, val, t.BaseTypeID, t.attTypMod) + return globalFunctionRegistry.GetFunction(t.ReceiveFunc).CallVariadic(nil, val, t.BaseTypeID.Internal(), t.attTypMod) } else if t.ModInFunc != 0 || t.IsArrayType() { - if t.Elem != id.Null { - return globalFunctionRegistry.GetFunction(t.ReceiveFunc).CallVariadic(nil, val, t.Elem, t.attTypMod) + if t.Elem != id.NullType { + return globalFunctionRegistry.GetFunction(t.ReceiveFunc).CallVariadic(nil, val, t.Elem.Internal(), t.attTypMod) } else { - return globalFunctionRegistry.GetFunction(t.ReceiveFunc).CallVariadic(nil, val, t.ID, t.attTypMod) + return globalFunctionRegistry.GetFunction(t.ReceiveFunc).CallVariadic(nil, val, t.ID.Internal(), t.attTypMod) } } else if t.TypType == TypeType_Enum { - return globalFunctionRegistry.GetFunction(t.ReceiveFunc).CallVariadic(nil, val, t.ID) + return globalFunctionRegistry.GetFunction(t.ReceiveFunc).CallVariadic(nil, val, t.ID.Internal()) } else { return globalFunctionRegistry.GetFunction(t.ReceiveFunc).CallVariadic(nil, val) } diff --git a/server/types/unknown.go b/server/types/unknown.go index 8dabe33db0..c4bff6eb58 100644 --- a/server/types/unknown.go +++ b/server/types/unknown.go @@ -30,8 +30,8 @@ var Unknown = &DoltgresType{ Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("-"), - Elem: id.Null, - Array: id.Null, + Elem: id.NullType, + Array: id.NullType, InputFunc: toFuncID("unknownin", toInternal("cstring")), OutputFunc: toFuncID("unknownout", toInternal("unknown")), ReceiveFunc: toFuncID("unknownrecv", toInternal("internal")), @@ -42,10 +42,10 @@ var Unknown = &DoltgresType{ Align: TypeAlignment_Char, Storage: TypeStorage_Plain, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.Null, + TypCollation: id.NullCollation, DefaulBin: "", Default: "", Acl: nil, diff --git a/server/types/utils.go b/server/types/utils.go index 1b16fee3da..df5b36cb12 100644 --- a/server/types/utils.go +++ b/server/types/utils.go @@ -173,6 +173,6 @@ func ArrToString(ctx *sql.Context, arr []any, baseType *DoltgresType, trimBool b // toInternal returns an Internal ID for the given type. This is only used for the built-in types, since they all share // the same schema (pg_catalog). -func toInternal(typeName string) id.Internal { - return id.NewInternal(id.Section_Type, "pg_catalog", typeName) +func toInternal(typeName string) id.InternalType { + return id.NewInternalType("pg_catalog", typeName) } diff --git a/server/types/uuid.go b/server/types/uuid.go index 0addc63d53..68dc6d5e7e 100644 --- a/server/types/uuid.go +++ b/server/types/uuid.go @@ -30,7 +30,7 @@ var Uuid = &DoltgresType{ Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("-"), - Elem: id.Null, + Elem: id.NullType, Array: toInternal("_uuid"), InputFunc: toFuncID("uuid_in", toInternal("cstring")), OutputFunc: toFuncID("uuid_out", toInternal("uuid")), @@ -42,10 +42,10 @@ var Uuid = &DoltgresType{ Align: TypeAlignment_Char, Storage: TypeStorage_Plain, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.Null, + TypCollation: id.NullCollation, DefaulBin: "", Default: "", Acl: nil, diff --git a/server/types/varchar.go b/server/types/varchar.go index fe1600c029..e707de9ffc 100644 --- a/server/types/varchar.go +++ b/server/types/varchar.go @@ -48,7 +48,7 @@ var VarChar = &DoltgresType{ Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("-"), - Elem: id.Null, + Elem: id.NullType, Array: toInternal("_varchar"), InputFunc: toFuncID("varcharin", toInternal("cstring"), toInternal("oid"), toInternal("int4")), OutputFunc: toFuncID("varcharout", toInternal("varchar")), @@ -60,10 +60,10 @@ var VarChar = &DoltgresType{ Align: TypeAlignment_Int, Storage: TypeStorage_Extended, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.NewInternal(id.Section_Collation, "pg_catalog", "default"), + TypCollation: id.NewInternalCollation("pg_catalog", "default"), DefaulBin: "", Default: "", Acl: nil, diff --git a/server/types/void.go b/server/types/void.go index 629beb6654..45f8cfd45b 100644 --- a/server/types/void.go +++ b/server/types/void.go @@ -30,8 +30,8 @@ var Void = &DoltgresType{ Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("-"), - Elem: id.Null, - Array: id.Null, + Elem: id.NullType, + Array: id.NullType, InputFunc: toFuncID("void_in", toInternal("cstring"), toInternal("oid")), OutputFunc: toFuncID("void_out", toInternal("void")), ReceiveFunc: toFuncID("void_recv", toInternal("internal"), toInternal("oid")), @@ -42,10 +42,10 @@ var Void = &DoltgresType{ Align: TypeAlignment_Int, Storage: TypeStorage_Plain, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.Null, + TypCollation: id.NullCollation, DefaulBin: "", Default: "", Acl: nil, diff --git a/server/types/xid.go b/server/types/xid.go index 1a8494d622..9d231fa366 100644 --- a/server/types/xid.go +++ b/server/types/xid.go @@ -30,7 +30,7 @@ var Xid = &DoltgresType{ Delimiter: ",", RelID: id.Null, SubscriptFunc: toFuncID("-"), - Elem: id.Null, + Elem: id.NullType, Array: toInternal("_xid"), InputFunc: toFuncID("xidin", toInternal("cstring")), OutputFunc: toFuncID("xidout", toInternal("xid")), @@ -42,10 +42,10 @@ var Xid = &DoltgresType{ Align: TypeAlignment_Int, Storage: TypeStorage_Plain, NotNull: false, - BaseTypeID: id.Null, + BaseTypeID: id.NullType, TypMod: -1, NDims: 0, - TypCollation: id.Null, + TypCollation: id.NullCollation, DefaulBin: "", Default: "", Acl: nil, diff --git a/testing/generation/function_coverage/generators.go b/testing/generation/function_coverage/generators.go index 9de2385652..891cd4e889 100644 --- a/testing/generation/function_coverage/generators.go +++ b/testing/generation/function_coverage/generators.go @@ -167,7 +167,7 @@ var uuidValueGenerators = utils.Or( ) // valueMappings contains the value generators for the given type. -var valueMappings = map[id.Internal]utils.StatementGenerator{ +var valueMappings = map[id.InternalType]utils.StatementGenerator{ pgtypes.Bool.ID: booleanValueGenerators, pgtypes.Float32.ID: float32ValueGenerators, pgtypes.Float64.ID: float64ValueGenerators, diff --git a/testing/go/framework.go b/testing/go/framework.go index a31c2728f3..a1ac15ddab 100644 --- a/testing/go/framework.go +++ b/testing/go/framework.go @@ -24,7 +24,6 @@ import ( "net" "os" "path/filepath" - "strconv" "testing" "time" @@ -379,7 +378,7 @@ func NormalizeRow(fds []pgconn.FieldDescription, row sql.Row, normalize bool) sq } newRow := make(sql.Row, len(row)) for i := range row { - dt, ok := types.InternalToBuiltInDoltgresType[id.Cache().ToInternal(fds[i].DataTypeOID)] + dt, ok := types.InternalToBuiltInDoltgresType[id.InternalType(id.Cache().ToInternal(fds[i].DataTypeOID))] if !ok { // try using text type dt = types.Text @@ -404,7 +403,7 @@ func NormalizeExpectedRow(fds []pgconn.FieldDescription, rows []sql.Row) []sql.R } else { newRow := make(sql.Row, len(row)) for i := range row { - dt, ok := types.InternalToBuiltInDoltgresType[id.Cache().ToInternal(fds[i].DataTypeOID)] + dt, ok := types.InternalToBuiltInDoltgresType[id.InternalType(id.Cache().ToInternal(fds[i].DataTypeOID))] if !ok { // try using text type dt = types.Text @@ -590,7 +589,7 @@ func NormalizeVal(dt *types.DoltgresType, v any) any { if internalID := id.Cache().ToInternal(uval); internalID.IsValid() { return internalID } - return id.NewInternal(id.Section_OID, strconv.FormatUint(uint64(uval), 10)) + return id.NewInternalOID(uval).Internal() } } diff --git a/testing/go/sequences_test.go b/testing/go/sequences_test.go index 6d390073ee..0c9101f185 100644 --- a/testing/go/sequences_test.go +++ b/testing/go/sequences_test.go @@ -780,27 +780,27 @@ func TestSequences(t *testing.T) { { Query: "SELECT * FROM pg_catalog.pg_sequence ORDER BY seqrelid;", Expected: []sql.Row{ - {1417287970, 20, 1, 1, 9223372036854775807, 1, 1, "f"}, - {2181375797, 20, 1, 3, 9223372036854775807, 1, 1, "t"}, + {2795592127, 20, 1, 1, 9223372036854775807, 1, 1, "f"}, + {3473123643, 20, 1, 3, 9223372036854775807, 1, 1, "t"}, }, }, { // Different cases but non-quoted, so it works Query: "SELECT * FROM PG_catalog.pg_SEQUENCE ORDER BY seqrelid;", Expected: []sql.Row{ - {1417287970, 20, 1, 1, 9223372036854775807, 1, 1, "f"}, - {2181375797, 20, 1, 3, 9223372036854775807, 1, 1, "t"}, + {2795592127, 20, 1, 1, 9223372036854775807, 1, 1, "f"}, + {3473123643, 20, 1, 3, 9223372036854775807, 1, 1, "t"}, }, }, { Query: "SELECT * FROM pg_catalog.pg_sequence WHERE seqrelid = 'some_sequence'::regclass;", Expected: []sql.Row{ - {1417287970, 20, 1, 1, 9223372036854775807, 1, 1, "f"}, + {2795592127, 20, 1, 1, 9223372036854775807, 1, 1, "f"}, }, }, { Query: "SELECT * FROM pg_catalog.pg_sequence WHERE seqrelid = 'another_sequence'::regclass;", Expected: []sql.Row{ - {2181375797, 20, 1, 3, 9223372036854775807, 1, 1, "t"}, + {3473123643, 20, 1, 3, 9223372036854775807, 1, 1, "t"}, }, }, { @@ -817,5 +817,38 @@ func TestSequences(t *testing.T) { }, }, }, + { + Name: "DROP TABLE", + SetUpScript: []string{ + "CREATE TABLE test (pk SERIAL PRIMARY KEY, v1 INTEGER);", + "INSERT INTO test (v1) VALUES (2), (3), (5), (7), (11);", + }, + Assertions: []ScriptTestAssertion{ + { + Query: "SELECT * FROM test;", + Expected: []sql.Row{ + {1, 2}, + {2, 3}, + {3, 5}, + {4, 7}, + {5, 11}, + }, + }, + { + Query: "SELECT * FROM pg_catalog.pg_sequence;", + Expected: []sql.Row{ + {3822699147, 23, 1, 1, 2147483647, 1, 1, "f"}, + }, + }, + { + Query: "DROP TABLE test;", + Expected: []sql.Row{}, + }, + { + Query: "SELECT * FROM pg_catalog.pg_sequence;", + Expected: []sql.Row{}, + }, + }, + }, }) }